From e012d15a238f24795081ef1e43ffe2859b6538ed Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 15 Jun 2020 08:46:47 +0200 Subject: [PATCH 01/17] gpio: driver.h: fix kernel-doc markup There is one parameter with a wrong name at kernel-doc macro: ./include/linux/gpio/driver.h:499: warning: Function parameter or member 'gc' not described in 'gpiochip_add_data' ./include/linux/gpio/driver.h:499: warning: Excess function parameter 'chip' description in 'gpiochip_add_data' Fix it. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Bartosz Golaszewski --- include/linux/gpio/driver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index c4f272af7af5..c11261f3c724 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -481,7 +481,7 @@ extern int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, /** * gpiochip_add_data() - register a gpio_chip - * @chip: the chip to register, with chip->base initialized + * @gc: the chip to register, with chip->base initialized * @data: driver-private data associated with this chip * * Context: potentially before irqs will work From 97cd738c44c85680d6c37f8583409ad2ef0ea17b Mon Sep 17 00:00:00 2001 From: Wang Qing Date: Fri, 12 Jun 2020 16:05:45 +0800 Subject: [PATCH 02/17] gpiolib: sysfs: use kobj_to_dev Use kobj_to_dev() API instead of container_of(). Signed-off-by: Wang Qing Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 23e3d335cd54..82371fe2ccc6 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -365,7 +365,7 @@ static DEVICE_ATTR_RW(active_low); static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr, int n) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct gpiod_data *data = dev_get_drvdata(dev); struct gpio_desc *desc = data->desc; umode_t mode = attr->mode; From 3d5bfbd9716318b1ca5c38488aa69f64d38a9aa5 Mon Sep 17 00:00:00 2001 From: Song Hui Date: Thu, 11 Jun 2020 18:28:09 +0800 Subject: [PATCH 03/17] gpio: mpc8xxx: change the gpio interrupt flags. Delete the interrupt IRQF_NO_THREAD flags in order to gpio interrupts can be threaded to allow high-priority processes to preempt. Signed-off-by: Song Hui Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-mpc8xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index 604dfec353a1..1e866524a4bd 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c @@ -417,7 +417,7 @@ static int mpc8xxx_probe(struct platform_device *pdev) ret = devm_request_irq(&pdev->dev, mpc8xxx_gc->irqn, mpc8xxx_gpio_irq_cascade, - IRQF_NO_THREAD | IRQF_SHARED, "gpio-cascade", + IRQF_SHARED, "gpio-cascade", mpc8xxx_gc); if (ret) { dev_err(&pdev->dev, "%s: failed to devm_request_irq(%d), ret = %d\n", From 3abda79aa12aba40964b593459866c312c513c23 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Tue, 9 Jun 2020 13:45:56 +0100 Subject: [PATCH 04/17] drivers: gpio: Fix trivial spelling The word 'descriptor' is misspelled throughout the tree. Fix it up accordingly: decriptors -> descriptors Signed-off-by: Kieran Bingham Signed-off-by: Bartosz Golaszewski --- drivers/gpio/TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/TODO b/drivers/gpio/TODO index b989c9352da2..e560e45e84f8 100644 --- a/drivers/gpio/TODO +++ b/drivers/gpio/TODO @@ -5,7 +5,7 @@ subsystem. GPIO descriptors Starting with commit 79a9becda894 the GPIO subsystem embarked on a journey -to move away from the global GPIO numberspace and toward a decriptor-based +to move away from the global GPIO numberspace and toward a descriptor-based approach. This means that GPIO consumers, drivers and machine descriptions ideally have no use or idea of the global GPIO numberspace that has/was used in the inception of the GPIO subsystem. From ee0f054fb5379e828137e0ff04188477459ce44c Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 15 Jun 2020 15:22:28 +0200 Subject: [PATCH 05/17] dt-bindings: gpio: pca953x: add nxp,pcal9535 The NXP PCAL9535 is an extended variant of the PCA9535. Signed-off-by: Jan Kiszka Reviewed-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- Documentation/devicetree/bindings/gpio/gpio-pca953x.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt b/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt index dab537c20def..3126c3817e2a 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt @@ -19,6 +19,7 @@ Required properties: nxp,pca9698 nxp,pcal6416 nxp,pcal6524 + nxp,pcal9535 nxp,pcal9555a maxim,max7310 maxim,max7312 From 3ba3ff5c0966280bfd1d40b05b1d7c089f45cc9b Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 15 Jun 2020 15:22:29 +0200 Subject: [PATCH 06/17] gpio: pca953x: Add support for the PCAL9535 The PCAL9535 is compatible to the PCA9535. Additionally, it comes with interrupt support and input latching. Other features are not supported by the GPIO subsystem. Datasheet: https://www.nxp.com/docs/en/data-sheet/PCAL9535A.pdf Signed-off-by: Jan Kiszka Reviewed-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-pca953x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 1fca8dd7824f..cd5fb522563e 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -89,6 +89,7 @@ static const struct i2c_device_id pca953x_id[] = { { "pcal6416", 16 | PCA953X_TYPE | PCA_LATCH_INT, }, { "pcal6524", 24 | PCA953X_TYPE | PCA_LATCH_INT, }, + { "pcal9535", 16 | PCA953X_TYPE | PCA_LATCH_INT, }, { "pcal9555a", 16 | PCA953X_TYPE | PCA_LATCH_INT, }, { "max7310", 8 | PCA953X_TYPE, }, @@ -1145,6 +1146,7 @@ static const struct of_device_id pca953x_dt_ids[] = { { .compatible = "nxp,pcal6416", .data = OF_953X(16, PCA_LATCH_INT), }, { .compatible = "nxp,pcal6524", .data = OF_953X(24, PCA_LATCH_INT), }, + { .compatible = "nxp,pcal9535", .data = OF_953X(16, PCA_LATCH_INT), }, { .compatible = "nxp,pcal9555a", .data = OF_953X(16, PCA_LATCH_INT), }, { .compatible = "maxim,max7310", .data = OF_953X( 8, 0), }, From 8346b92ecddfae624b1dd4631e840fb98f5430cd Mon Sep 17 00:00:00 2001 From: Gaurav Singh Date: Sat, 20 Jun 2020 18:40:53 -0400 Subject: [PATCH 07/17] gpio: max732x: remove redundant check from probe() The pdata is already checked for its validity. Remove the redundant check. Signed-off-by: Gaurav Singh Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-max732x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c index 5fb0bcf31142..63472f308857 100644 --- a/drivers/gpio/gpio-max732x.c +++ b/drivers/gpio/gpio-max732x.c @@ -703,7 +703,7 @@ static int max732x_probe(struct i2c_client *client, if (ret) return ret; - if (pdata && pdata->setup) { + if (pdata->setup) { ret = pdata->setup(client, chip->gpio_chip.base, chip->gpio_chip.ngpio, pdata->context); if (ret < 0) From fdcfec11b215b3bbc9c20240739cf76be921cca1 Mon Sep 17 00:00:00 2001 From: Glenn Langedock Date: Wed, 17 Jun 2020 17:07:21 +0530 Subject: [PATCH 08/17] gpio: zynq: protect direction in/out with a spinlock Fix race condition when changing the direction (in/out) of the GPIO pin. The read-modify-write sequence (as coded in the driver) isn't atomic and requires synchronization (spinlock). Signed-off-by: Glenn Langedock Signed-off-by: Michal Simek Signed-off-by: Srinivas Neeli Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-zynq.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index 05ba16fffdad..fb93b35ab19e 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -116,6 +117,7 @@ struct gpio_regs { * @irq: interrupt for the GPIO device * @p_data: pointer to platform data * @context: context registers + * @dirlock: lock used for direction in/out synchronization */ struct zynq_gpio { struct gpio_chip chip; @@ -124,6 +126,7 @@ struct zynq_gpio { int irq; const struct zynq_platform_data *p_data; struct gpio_regs context; + spinlock_t dirlock; /* lock */ }; /** @@ -297,6 +300,7 @@ static int zynq_gpio_dir_in(struct gpio_chip *chip, unsigned int pin) { u32 reg; unsigned int bank_num, bank_pin_num; + unsigned long flags; struct zynq_gpio *gpio = gpiochip_get_data(chip); zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio); @@ -310,9 +314,11 @@ static int zynq_gpio_dir_in(struct gpio_chip *chip, unsigned int pin) return -EINVAL; /* clear the bit in direction mode reg to set the pin as input */ + spin_lock_irqsave(&gpio->dirlock, flags); reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); reg &= ~BIT(bank_pin_num); writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); + spin_unlock_irqrestore(&gpio->dirlock, flags); return 0; } @@ -334,11 +340,13 @@ static int zynq_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, { u32 reg; unsigned int bank_num, bank_pin_num; + unsigned long flags; struct zynq_gpio *gpio = gpiochip_get_data(chip); zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio); /* set the GPIO pin as output */ + spin_lock_irqsave(&gpio->dirlock, flags); reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); reg |= BIT(bank_pin_num); writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); @@ -347,6 +355,7 @@ static int zynq_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_OUTEN_OFFSET(bank_num)); reg |= BIT(bank_pin_num); writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_OUTEN_OFFSET(bank_num)); + spin_unlock_irqrestore(&gpio->dirlock, flags); /* set the state of the pin */ zynq_gpio_set_value(chip, pin, state); @@ -885,6 +894,8 @@ static int zynq_gpio_probe(struct platform_device *pdev) return ret; } + spin_lock_init(&gpio->dirlock); + pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = pm_runtime_get_sync(&pdev->dev); From 3e1ad2b858dd1c1e795e3817aa31f0a301d6aeba Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Wed, 17 Jun 2020 17:07:22 +0530 Subject: [PATCH 09/17] dt-bindings: gpio: Add binding for Versal gpio Add binding for Versal binding. Versal devices are the industry's first adaptive compute acceleration platforms. https://www.xilinx.com/support/documentation/data_sheets/ds950-versal-overview.pdf On the Versal platform, we are using two customized GPIO controllers(IP) which were used in Zynq/ZynqMp platform. One of them present in the Platform Management Controller(PMC) block and other in Processing System(PS) block. In PMC_GPIO only Bank0,1,3 & 4 are enabled and in PS_GPIO only Bank 0 & 3 are enabled. You can find more details of GPIO IP in ZynqMP TRM General Purpose I/O(Chapter-27). https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf Signed-off-by: Shubhrajyoti Datta Signed-off-by: Michal Simek Signed-off-by: Bartosz Golaszewski --- Documentation/devicetree/bindings/gpio/gpio-zynq.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/gpio/gpio-zynq.txt b/Documentation/devicetree/bindings/gpio/gpio-zynq.txt index 4fa4eb5507cd..4806d846c0fc 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-zynq.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-zynq.txt @@ -6,7 +6,8 @@ Required properties: - First cell is the GPIO line number - Second cell is used to specify optional parameters (unused) -- compatible : Should be "xlnx,zynq-gpio-1.0" or "xlnx,zynqmp-gpio-1.0" +- compatible : Should be "xlnx,zynq-gpio-1.0" or + "xlnx,zynqmp-gpio-1.0" or "xlnx,versal-gpio-1.0 - clocks : Clock specifier (see clock bindings for details) - gpio-controller : Marks the device node as a GPIO controller. - interrupts : Interrupt specifier (see interrupt bindings for From c0178b8e24b2b1eed8ebfe5b155a36304d42a137 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Wed, 17 Jun 2020 17:07:23 +0530 Subject: [PATCH 10/17] dt-bindings: gpio: Add pmc gpio node to gpio-zynq Add the pmc gpio node to the device tree. Versal devices are the industry's first adaptive compute acceleration platforms. https://www.xilinx.com/support/documentation/data_sheets/ds950-versal-overview.pdf On the Versal platform, we are using two customized GPIO controllers(IP) which were used in Zynq/ZynqMp platform. One of them present in the Platform Management Controller(PMC) block and other in Processing System(PS) block. In PMC_GPIO only Bank0,1,3 & 4 are enabled and in PS_GPIO only Bank 0 & 3 are enabled. You can find more details of GPIO IP in ZynqMP TRM General Purpose I/O(Chapter-27). https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf Signed-off-by: Shubhrajyoti Datta Signed-off-by: Michal Simek Signed-off-by: Bartosz Golaszewski --- Documentation/devicetree/bindings/gpio/gpio-zynq.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/gpio/gpio-zynq.txt b/Documentation/devicetree/bindings/gpio/gpio-zynq.txt index 4806d846c0fc..f693e82b4c0f 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-zynq.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-zynq.txt @@ -8,6 +8,7 @@ Required properties: parameters (unused) - compatible : Should be "xlnx,zynq-gpio-1.0" or "xlnx,zynqmp-gpio-1.0" or "xlnx,versal-gpio-1.0 + or "xlnx,pmc-gpio-1.0 - clocks : Clock specifier (see clock bindings for details) - gpio-controller : Marks the device node as a GPIO controller. - interrupts : Interrupt specifier (see interrupt bindings for From 675002448eee5a9f96bfeb9b057e12a60a004b6c Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Wed, 17 Jun 2020 17:07:24 +0530 Subject: [PATCH 11/17] gpio: zynq: Add Versal support Add Versal support in gpio. Only bank 0 and 3 are connected to the Multiplexed Input output pins. Bank 0 to mio and bank3 to fabric Multiplexed input output pins. Versal devices are the industry's first adaptive compute acceleration platforms. https://www.xilinx.com/support/documentation/data_sheets/ds950-versal-overview.pdf On the Versal platform, we are using two customized GPIO controllers(IP) which were used in Zynq/ZynqMp platform. One of them present in the Platform Management Controller(PMC) block and other in Processing System(PS) block. In PMC_GPIO only Bank0,1,3 & 4 are enabled and in PS_GPIO only Bank 0 & 3 are enabled. You can find more details of GPIO IP in ZynqMP TRM General Purpose I/O(Chapter-27). https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf Signed-off-by: Shubhrajyoti Datta Signed-off-by: Michal Simek Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-zynq.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index fb93b35ab19e..9ac69144a0eb 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c @@ -22,6 +22,8 @@ /* Maximum banks */ #define ZYNQ_GPIO_MAX_BANK 4 #define ZYNQMP_GPIO_MAX_BANK 6 +#define VERSAL_GPIO_MAX_BANK 4 +#define VERSAL_UNUSED_BANKS 2 #define ZYNQ_GPIO_BANK0_NGPIO 32 #define ZYNQ_GPIO_BANK1_NGPIO 22 @@ -96,6 +98,7 @@ /* set to differentiate zynq from zynqmp, 0=zynqmp, 1=zynq */ #define ZYNQ_GPIO_QUIRK_IS_ZYNQ BIT(0) #define GPIO_QUIRK_DATA_RO_BUG BIT(1) +#define GPIO_QUIRK_VERSAL BIT(2) struct gpio_regs { u32 datamsw[ZYNQMP_GPIO_MAX_BANK]; @@ -199,6 +202,8 @@ static inline void zynq_gpio_get_bank_pin(unsigned int pin_num, gpio->p_data->bank_min[bank]; return; } + if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL) + bank = bank + VERSAL_UNUSED_BANKS; } /* default */ @@ -656,6 +661,8 @@ static void zynq_gpio_irqhandler(struct irq_desc *desc) int_enb = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_INTMASK_OFFSET(bank_num)); zynq_gpio_handle_bank_irq(gpio, bank_num, int_sts & ~int_enb); + if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL) + bank_num = bank_num + VERSAL_UNUSED_BANKS; } chained_irq_exit(irqchip, desc); @@ -685,6 +692,8 @@ static void zynq_gpio_save_context(struct zynq_gpio *gpio) gpio->context.int_any[bank_num] = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_INTANY_OFFSET(bank_num)); + if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL) + bank_num = bank_num + VERSAL_UNUSED_BANKS; } } @@ -716,6 +725,8 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio) writel_relaxed(~(gpio->context.int_en[bank_num]), gpio->base_addr + ZYNQ_GPIO_INTEN_OFFSET(bank_num)); + if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL) + bank_num = bank_num + VERSAL_UNUSED_BANKS; } } @@ -787,6 +798,17 @@ static const struct dev_pm_ops zynq_gpio_dev_pm_ops = { zynq_gpio_runtime_resume, NULL) }; +static const struct zynq_platform_data versal_gpio_def = { + .label = "versal_gpio", + .quirks = GPIO_QUIRK_VERSAL, + .ngpio = 58, + .max_bank = VERSAL_GPIO_MAX_BANK, + .bank_min[0] = 0, + .bank_max[0] = 25, /* 0 to 25 are connected to MIOs (26 pins) */ + .bank_min[3] = 26, + .bank_max[3] = 57, /* Bank 3 is connected to FMIOs (32 pins) */ +}; + static const struct zynq_platform_data zynqmp_gpio_def = { .label = "zynqmp_gpio", .quirks = GPIO_QUIRK_DATA_RO_BUG, @@ -824,6 +846,7 @@ static const struct zynq_platform_data zynq_gpio_def = { static const struct of_device_id zynq_gpio_of_match[] = { { .compatible = "xlnx,zynq-gpio-1.0", .data = &zynq_gpio_def }, { .compatible = "xlnx,zynqmp-gpio-1.0", .data = &zynqmp_gpio_def }, + { .compatible = "xlnx,versal-gpio-1.0", .data = &versal_gpio_def }, { /* end of table */ } }; MODULE_DEVICE_TABLE(of, zynq_gpio_of_match); @@ -903,9 +926,12 @@ static int zynq_gpio_probe(struct platform_device *pdev) goto err_pm_dis; /* disable interrupts for all banks */ - for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) + for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) { writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr + ZYNQ_GPIO_INTDIS_OFFSET(bank_num)); + if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL) + bank_num = bank_num + VERSAL_UNUSED_BANKS; + } /* Set up the GPIO irqchip */ girq = &chip->irq; From 26ebdbf8c2e311759d88c0b0cf26126715e932c6 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Wed, 17 Jun 2020 17:07:25 +0530 Subject: [PATCH 12/17] gpio: zynq: Disable the irq if it is not a wakeup source If gpio is not set to wake disable the interrupt. ATF set all slaves with enabled interrupts as wakeup sources and if gpio is used in r5 then it wakes up linux. Signed-off-by: Shubhrajyoti Datta Signed-off-by: Michal Simek Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-zynq.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index 9ac69144a0eb..b6261a3aec55 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c @@ -735,6 +735,9 @@ static int __maybe_unused zynq_gpio_suspend(struct device *dev) struct zynq_gpio *gpio = dev_get_drvdata(dev); struct irq_data *data = irq_get_irq_data(gpio->irq); + if (!device_may_wakeup(dev)) + disable_irq(gpio->irq); + if (!irqd_is_wakeup_set(data)) { zynq_gpio_save_context(gpio); return pm_runtime_force_suspend(dev); @@ -749,6 +752,9 @@ static int __maybe_unused zynq_gpio_resume(struct device *dev) struct irq_data *data = irq_get_irq_data(gpio->irq); int ret; + if (!device_may_wakeup(dev)) + enable_irq(gpio->irq); + if (!irqd_is_wakeup_set(data)) { ret = pm_runtime_force_resume(dev); zynq_gpio_restore_context(gpio); @@ -956,6 +962,8 @@ static int zynq_gpio_probe(struct platform_device *pdev) goto err_pm_put; } + irq_set_status_flags(gpio->irq, IRQ_DISABLE_UNLAZY); + device_init_wakeup(&pdev->dev, 1); pm_runtime_put(&pdev->dev); return 0; From 73c612fe2a5f819bc54598b5babc630528bf29d1 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Wed, 17 Jun 2020 17:07:26 +0530 Subject: [PATCH 13/17] gpio: zynq: Add pmc gpio support Add PMC gpio support. Only bank 0,1, 3 and 4 are connected to the multiplexed Input output pins. Bank 0 and 1 to mio and bank 3 and 4 to extended multiplexed input output pins. Versal devices are the industry's first adaptive compute acceleration platforms. https://www.xilinx.com/support/documentation/data_sheets/ds950-versal-overview.pdf On the Versal platform, we are using two customized GPIO controllers(IP) which were used in Zynq/ZynqMp platform. One of them present in the Platform Management Controller(PMC) block and other in Processing System(PS) block. In PMC_GPIO only Bank0,1,3 & 4 are enabled and in PS_GPIO only Bank 0 & 3 are enabled. You can find more details of GPIO IP in ZynqMP TRM General Purpose I/O(Chapter-27). https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf Signed-off-by: Shubhrajyoti Datta Signed-off-by: Michal Simek Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-zynq.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index b6261a3aec55..2ddb59b242e7 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c @@ -23,6 +23,7 @@ #define ZYNQ_GPIO_MAX_BANK 4 #define ZYNQMP_GPIO_MAX_BANK 6 #define VERSAL_GPIO_MAX_BANK 4 +#define PMC_GPIO_MAX_BANK 5 #define VERSAL_UNUSED_BANKS 2 #define ZYNQ_GPIO_BANK0_NGPIO 32 @@ -815,6 +816,20 @@ static const struct zynq_platform_data versal_gpio_def = { .bank_max[3] = 57, /* Bank 3 is connected to FMIOs (32 pins) */ }; +static const struct zynq_platform_data pmc_gpio_def = { + .label = "pmc_gpio", + .ngpio = 116, + .max_bank = PMC_GPIO_MAX_BANK, + .bank_min[0] = 0, + .bank_max[0] = 25, /* 0 to 25 are connected to MIOs (26 pins) */ + .bank_min[1] = 26, + .bank_max[1] = 51, /* Bank 1 are connected to MIOs (26 pins) */ + .bank_min[3] = 52, + .bank_max[3] = 83, /* Bank 3 is connected to EMIOs (32 pins) */ + .bank_min[4] = 84, + .bank_max[4] = 115, /* Bank 4 is connected to EMIOs (32 pins) */ +}; + static const struct zynq_platform_data zynqmp_gpio_def = { .label = "zynqmp_gpio", .quirks = GPIO_QUIRK_DATA_RO_BUG, @@ -853,6 +868,7 @@ static const struct of_device_id zynq_gpio_of_match[] = { { .compatible = "xlnx,zynq-gpio-1.0", .data = &zynq_gpio_def }, { .compatible = "xlnx,zynqmp-gpio-1.0", .data = &zynqmp_gpio_def }, { .compatible = "xlnx,versal-gpio-1.0", .data = &versal_gpio_def }, + { .compatible = "xlnx,pmc-gpio-1.0", .data = &pmc_gpio_def }, { /* end of table */ } }; MODULE_DEVICE_TABLE(of, zynq_gpio_of_match); From 0077428118204d934382dcb74569899ac3dd2f58 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Wed, 17 Jun 2020 17:07:27 +0530 Subject: [PATCH 14/17] gpio: zynq: Remove error prints in EPROBE_DEFER In case of probe is deferred do not print the errors. Signed-off-by: Shubhrajyoti Datta Signed-off-by: Michal Simek Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-zynq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index 2ddb59b242e7..53d1387592fd 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c @@ -930,7 +930,8 @@ static int zynq_gpio_probe(struct platform_device *pdev) /* Retrieve GPIO clock */ gpio->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(gpio->clk)) { - dev_err(&pdev->dev, "input clock not found.\n"); + if (PTR_ERR(gpio->clk) != -EPROBE_DEFER) + dev_err(&pdev->dev, "input clock not found.\n"); return PTR_ERR(gpio->clk); } ret = clk_prepare_enable(gpio->clk); From e4c6a52c64607d825b0e81c82e548d4cc8199e53 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 23 Jun 2020 16:40:01 +0200 Subject: [PATCH 15/17] gpio: Drop superfluous dependencies on GPIOLIB All config options for GPIO drivers are inside a big "if GPIOLIB ... endif" block, so there is no reason for individual config options to have expicit dependencies on GPIOLIB. Hence remove them. Signed-off-by: Geert Uytterhoeven Signed-off-by: Bartosz Golaszewski --- drivers/gpio/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c6b5c65c8405..05e0801c6a78 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -410,7 +410,7 @@ config GPIO_MXS config GPIO_OCTEON tristate "Cavium OCTEON GPIO" - depends on GPIOLIB && CAVIUM_OCTEON_SOC + depends on CAVIUM_OCTEON_SOC default y help Say yes here to support the on-chip GPIO lines on the OCTEON @@ -1117,7 +1117,7 @@ config GPIO_DLN2 config HTC_EGPIO bool "HTC EGPIO support" - depends on GPIOLIB && ARM + depends on ARM help This driver supports the CPLD egpio chip present on several HTC phones. It provides basic support for input From f02a03985d06c5a39605a0b8a6206af0f9ec7b03 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 29 Jun 2020 09:41:14 -0700 Subject: [PATCH 16/17] gpio: omap: Add missing PM ops for suspend We've had the legacy platform code take care of suspend for us but this no longer is the case when probed without legacy mode with ti-sysc. We need to configure PM ops like standard Linux device drivers do. As we still have some SoCs booting also the legacy mode, we need to add omap_gpio_suspend() and omap_gpio_resume(), and check for the is_suspended flag to avoid legacy _od_suspend_noirq() calling them on an already suspended GPIO instance. Once we have no SoCs booting in legacy mode, we can just switch to using the standard PM ops with pm_runtime_force_suspend() and pm_runtime_force_resume(). Signed-off-by: Tony Lindgren Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-omap.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index b8e2ecc3eade..b3afe39027bd 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -60,6 +60,7 @@ struct gpio_bank { struct clk *dbck; struct notifier_block nb; unsigned int is_suspended:1; + unsigned int needs_resume:1; u32 mod_usage; u32 irq_usage; u32 dbck_enable_mask; @@ -1504,9 +1505,34 @@ static int __maybe_unused omap_gpio_runtime_resume(struct device *dev) return 0; } +static int omap_gpio_suspend(struct device *dev) +{ + struct gpio_bank *bank = dev_get_drvdata(dev); + + if (bank->is_suspended) + return 0; + + bank->needs_resume = 1; + + return omap_gpio_runtime_suspend(dev); +} + +static int omap_gpio_resume(struct device *dev) +{ + struct gpio_bank *bank = dev_get_drvdata(dev); + + if (!bank->needs_resume) + return 0; + + bank->needs_resume = 0; + + return omap_gpio_runtime_resume(dev); +} + static const struct dev_pm_ops gpio_pm_ops = { SET_RUNTIME_PM_OPS(omap_gpio_runtime_suspend, omap_gpio_runtime_resume, NULL) + SET_LATE_SYSTEM_SLEEP_PM_OPS(omap_gpio_suspend, omap_gpio_resume) }; static struct platform_driver omap_gpio_driver = { From ae66eca000cfef3ef0e31842102e17b1b660b1ce Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 30 Jun 2020 12:21:46 +0300 Subject: [PATCH 17/17] gpiolib: Deduplicate find_first_zero_bit() call bitmap_full() is a shortcut to find_first_zero_bit(). Thus, no need to call it twice. Signed-off-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 4fa075d49fbc..fa01455be4f0 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3705,10 +3705,9 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep, bitmap_xor(value_bitmap, value_bitmap, array_info->invert_mask, array_size); - if (bitmap_full(array_info->get_mask, array_size)) - return 0; - i = find_first_zero_bit(array_info->get_mask, array_size); + if (i == array_size) + return 0; } else { array_info = NULL; } @@ -3989,10 +3988,9 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep, gpio_chip_set_multiple(array_info->chip, array_info->set_mask, value_bitmap); - if (bitmap_full(array_info->set_mask, array_size)) - return 0; - i = find_first_zero_bit(array_info->set_mask, array_size); + if (i == array_size) + return 0; } else { array_info = NULL; }