diff options
| author | Linus Torvalds <[email protected]> | 2020-12-17 18:07:20 -0800 |
|---|---|---|
| committer | Linus Torvalds <[email protected]> | 2020-12-17 18:07:20 -0800 |
| commit | a409ed156a90093a03fe6a93721ddf4c591eac87 (patch) | |
| tree | 2a3c6f6f81c8b233627cf14da7149c7f312b475e /drivers/gpio/gpio-xilinx.c | |
| parent | 345b17acb1aa7a443741d9220f66b30d5ddd7c39 (diff) | |
| parent | 7ac554888233468a9fd7c4f28721396952dd9959 (diff) | |
Merge tag 'gpio-v5.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
Pull GPIO updates from Linus Walleij:
"This is the bulk of the GPIO changes for the v5.11 kernel cycle:
Core changes:
- Retired the old set-up function for GPIO IRQ chips. All chips now
use the template struct gpio_irq_chip and pass that to the core to
be set up alongside the gpio_chip. We can finally get rid of the
old cruft.
- Some refactoring and clean up of the core code.
- Support edge event timestamps to be stamped using REALTIME (wall
clock) timestamps. We have found solid use cases for this, so we
support it.
New drivers:
- MStar MSC313 GPIO driver.
- HiSilicon GPIO driver.
Driver improvements:
- The PCA953x driver now also supports the NXP PCAL9554B/C chips.
- The mockup driver can now be probed from the device tree which is
pretty useful for virtual prototyping of devices.
- The Rcar driver now supports .get_multiple()
- The MXC driver dropped some legacy and became a pure device tree
client.
- The Exar driver was moved over to the IDA interface for
enumerating, and also switched over to using regmap for register
access"
* tag 'gpio-v5.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (87 commits)
MAINTAINERS: Remove reference to non-existing file
gpio: hisi: Do not require ACPI for COMPILE_TEST
MAINTAINERS: Add maintainer for HiSilicon GPIO driver
gpio: gpio-hisi: Add HiSilicon GPIO support
gpio: cs5535: Simplify the return expression of cs5535_gpio_probe()
gpiolib: irq hooks: fix recursion in gpiochip_irq_unmask
dt-bindings: mt7621-gpio: convert bindings to YAML format
gpiolib: cdev: Flag invalid GPIOs as used
gpio: put virtual gpio device into their own submenu
drivers: gpio: amd8111: use SPDX-License-Identifier
drivers: gpio: amd8111: prefer dev_err()/dev_info() over raw printk
drivers: gpio: bt8xx: prefer dev_err()/dev_warn() over of raw printk
gpio: Add TODO item for debugfs interface
gpio: just plain warning when nonexisting gpio requested
tools: gpio: add option to report wall-clock time to gpio-event-mon
tools: gpio: add support for reporting realtime event clock to lsgpio
gpiolib: cdev: allow edge event timestamps to be configured as REALTIME
gpio: msc313: MStar MSC313 GPIO driver
dt-bindings: gpio: Binding for MStar MSC313 GPIO controller
dt-bindings: gpio: Add a binding header for the MSC313 GPIO driver
...
Diffstat (limited to 'drivers/gpio/gpio-xilinx.c')
| -rw-r--r-- | drivers/gpio/gpio-xilinx.c | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c index 67f9f82e0db0..be539381fd82 100644 --- a/drivers/gpio/gpio-xilinx.c +++ b/drivers/gpio/gpio-xilinx.c @@ -6,13 +6,14 @@ */ #include <linux/bitops.h> -#include <linux/init.h> +#include <linux/clk.h> #include <linux/errno.h> +#include <linux/gpio/driver.h> +#include <linux/init.h> +#include <linux/io.h> #include <linux/module.h> #include <linux/of_device.h> #include <linux/of_platform.h> -#include <linux/io.h> -#include <linux/gpio/driver.h> #include <linux/slab.h> /* Register Offset Definitions */ @@ -38,6 +39,7 @@ * @gpio_state: GPIO state shadow register * @gpio_dir: GPIO direction shadow register * @gpio_lock: Lock used for synchronization + * @clk: clock resource for this driver */ struct xgpio_instance { struct gpio_chip gc; @@ -46,6 +48,7 @@ struct xgpio_instance { u32 gpio_state[2]; u32 gpio_dir[2]; spinlock_t gpio_lock[2]; + struct clk *clk; }; static inline int xgpio_index(struct xgpio_instance *chip, int gpio) @@ -257,6 +260,23 @@ static void xgpio_save_regs(struct xgpio_instance *chip) } /** + * xgpio_remove - Remove method for the GPIO device. + * @pdev: pointer to the platform device + * + * This function remove gpiochips and frees all the allocated resources. + * + * Return: 0 always + */ +static int xgpio_remove(struct platform_device *pdev) +{ + struct xgpio_instance *gpio = platform_get_drvdata(pdev); + + clk_disable_unprepare(gpio->clk); + + return 0; +} + +/** * xgpio_of_probe - Probe method for the GPIO device. * @pdev: pointer to the platform device * @@ -278,7 +298,8 @@ static int xgpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, chip); /* Update GPIO state shadow register with default value */ - of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state[0]); + if (of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state[0])) + chip->gpio_state[0] = 0x0; /* Update GPIO direction shadow register with default value */ if (of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir[0])) @@ -298,8 +319,9 @@ static int xgpio_probe(struct platform_device *pdev) if (is_dual) { /* Update GPIO state shadow register with default value */ - of_property_read_u32(np, "xlnx,dout-default-2", - &chip->gpio_state[1]); + if (of_property_read_u32(np, "xlnx,dout-default-2", + &chip->gpio_state[1])) + chip->gpio_state[1] = 0x0; /* Update GPIO direction shadow register with default value */ if (of_property_read_u32(np, "xlnx,tri-default-2", @@ -334,11 +356,25 @@ static int xgpio_probe(struct platform_device *pdev) return PTR_ERR(chip->regs); } + chip->clk = devm_clk_get_optional(&pdev->dev, NULL); + if (IS_ERR(chip->clk)) { + if (PTR_ERR(chip->clk) != -EPROBE_DEFER) + dev_dbg(&pdev->dev, "Input clock not found\n"); + return PTR_ERR(chip->clk); + } + + status = clk_prepare_enable(chip->clk); + if (status < 0) { + dev_err(&pdev->dev, "Failed to prepare clk\n"); + return status; + } + xgpio_save_regs(chip); status = devm_gpiochip_add_data(&pdev->dev, &chip->gc, chip); if (status) { dev_err(&pdev->dev, "failed to add GPIO chip\n"); + clk_disable_unprepare(chip->clk); return status; } @@ -354,6 +390,7 @@ MODULE_DEVICE_TABLE(of, xgpio_of_match); static struct platform_driver xgpio_plat_driver = { .probe = xgpio_probe, + .remove = xgpio_remove, .driver = { .name = "gpio-xilinx", .of_match_table = xgpio_of_match, |