From dc87f6dd058a648cd2a35e4aa04592dccdc9f0c2 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sat, 11 Apr 2020 20:33:52 -0500 Subject: gpio: pca953x: Fix pca953x_gpio_set_config pca953x_gpio_set_config is setup to support pull-up/down bias. Currently the driver uses a variable called 'config' to determine which options to use. Unfortunately, this is incorrect. This patch uses function pinconf_to_config_param(config), which converts this 'config' parameter back to pinconfig to determine which option to use. Fixes: 15add06841a3 ("gpio: pca953x: add ->set_config implementation") Signed-off-by: Adam Ford Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-pca953x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 5638b4e5355f..4269ea9a817e 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -531,7 +531,7 @@ static int pca953x_gpio_set_config(struct gpio_chip *gc, unsigned int offset, { struct pca953x_chip *chip = gpiochip_get_data(gc); - switch (config) { + switch (pinconf_to_config_param(config)) { case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_DOWN: return pca953x_gpio_set_pull_up_down(chip, offset, config); -- cgit v1.2.3 From 4e1541593017d76cfa04bd666de8e4dbcfe3105d Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 15 Apr 2020 10:23:59 +0200 Subject: gpiolib: improve the robustness of watch/unwatch ioctl() This makes the new ioctl() a bit more robust - we now check if a line is already being watched and return -EBUSY if the user-space tries to start watching it again. Same for unwatch - return -EBUSY if user-space tries to unwatch a line that's not being watched. Fixes: 51c1064e82e7 ("gpiolib: add new ioctl() for monitoring changes in line info") Signed-off-by: Bartosz Golaszewski Reviewed-by: Linus Walleij --- drivers/gpio/gpiolib.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 40f2d7f69be2..29f6abe84d2e 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1227,6 +1227,7 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) void __user *ip = (void __user *)arg; struct gpio_desc *desc; __u32 offset; + int hwgpio; /* We fail any subsequent ioctl():s when the chip is gone */ if (!gc) @@ -1259,13 +1260,19 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (IS_ERR(desc)) return PTR_ERR(desc); + hwgpio = gpio_chip_hwgpio(desc); + + if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL && + test_bit(hwgpio, priv->watched_lines)) + return -EBUSY; + gpio_desc_to_lineinfo(desc, &lineinfo); if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) return -EFAULT; if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) - set_bit(gpio_chip_hwgpio(desc), priv->watched_lines); + set_bit(hwgpio, priv->watched_lines); return 0; } else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) { @@ -1280,7 +1287,12 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (IS_ERR(desc)) return PTR_ERR(desc); - clear_bit(gpio_chip_hwgpio(desc), priv->watched_lines); + hwgpio = gpio_chip_hwgpio(desc); + + if (!test_bit(hwgpio, priv->watched_lines)) + return -EBUSY; + + clear_bit(hwgpio, priv->watched_lines); return 0; } return -EINVAL; -- cgit v1.2.3 From 6409d049ce28bef35e13dfb8699fc7ee27469ba1 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Fri, 17 Apr 2020 09:01:51 +0200 Subject: gpiolib: don't call sleeping functions with a spinlock taken We must not call pinctrl_gpio_can_use_line() with the gpio_lock taken as it takes a mutex internally. Let's move the call before taking the spinlock and store the return value. This isn't perfect - there's a moment between calling pinctrl_gpio_can_use_line() and taking the spinlock where the situation can change but it isn't a regression either: previously this part wasn't protected at all and it only affects the information user-space is seeing. Reported-by: Geert Uytterhoeven Fixes: d2ac25798208 ("gpiolib: provide a dedicated function for setting lineinfo") Signed-off-by: Bartosz Golaszewski Acked-by: Linus Walleij --- drivers/gpio/gpiolib.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 29f6abe84d2e..bf9732ab7f91 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1158,8 +1158,19 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, struct gpioline_info *info) { struct gpio_chip *gc = desc->gdev->chip; + bool ok_for_pinctrl; unsigned long flags; + /* + * This function takes a mutex so we must check this before taking + * the spinlock. + * + * FIXME: find a non-racy way to retrieve this information. Maybe a + * lock common to both frameworks? + */ + ok_for_pinctrl = + pinctrl_gpio_can_use_line(gc->base + info->line_offset); + spin_lock_irqsave(&gpio_lock, flags); if (desc->name) { @@ -1186,7 +1197,7 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, test_bit(FLAG_USED_AS_IRQ, &desc->flags) || test_bit(FLAG_EXPORT, &desc->flags) || test_bit(FLAG_SYSFS, &desc->flags) || - !pinctrl_gpio_can_use_line(gc->base + info->line_offset)) + !ok_for_pinctrl) info->flags |= GPIOLINE_FLAG_KERNEL; if (test_bit(FLAG_IS_OUT, &desc->flags)) info->flags |= GPIOLINE_FLAG_IS_OUT; -- cgit v1.2.3 From 8650b6099da5cab203624bf56af200191e260f68 Mon Sep 17 00:00:00 2001 From: David Gow Date: Fri, 24 Apr 2020 21:46:55 -0700 Subject: gpio: of: Build fails if CONFIG_OF_DYNAMIC enabled without CONFIG_OF_GPIO The symbol 'gpio_of_notifier' doesn't exist without both CONFIG_OF_GPIO and CONFIG_OF_DYNAMIC enabled, but is referenced when only CONFIG_OF_DYNAMIC is enabled. This broke building with 'make ARCH=um allyesconfig': --------------- /usr/bin/ld: drivers/gpio/gpiolib.o: in function `gpiolib_dev_init': ./drivers/gpio/gpiolib.c:5293: undefined reference to `gpio_of_notifier' collect2: error: ld returned 1 exit status --------------- Fixes: 63636d956c45 ("gpio: of: Add DT overlay support for GPIO hogs") Signed-off-by: David Gow Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20200425044655.166257-1-davidgow@google.com Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index bf9732ab7f91..182136d98b97 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -5312,8 +5312,9 @@ static int __init gpiolib_dev_init(void) gpiolib_initialized = true; gpiochip_setup_devs(); - if (IS_ENABLED(CONFIG_OF_DYNAMIC)) - WARN_ON(of_reconfig_notifier_register(&gpio_of_notifier)); +#if IS_ENABLED(CONFIG_OF_DYNAMIC) && IS_ENABLED(CONFIG_OF_GPIO) + WARN_ON(of_reconfig_notifier_register(&gpio_of_notifier)); +#endif /* CONFIG_OF_DYNAMIC && CONFIG_OF_GPIO */ return ret; } -- cgit v1.2.3 From 0cf253eed5d2bdf7bb3152457b38f39b012955f7 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 27 Apr 2020 17:26:05 -0600 Subject: gpio: tegra: mask GPIO IRQs during IRQ shutdown The driver currently leaves GPIO IRQs unmasked even when the GPIO IRQ client has released the GPIO IRQ. This allows the HW to raise IRQs, and SW to process them, after shutdown. Fix this by masking the IRQ when it's shut down. This is usually taken care of by the irqchip core, but since this driver has a custom irq_shutdown implementation, it must do this explicitly itself. Signed-off-by: Stephen Warren Link: https://lore.kernel.org/r/20200427232605.11608-1-swarren@wwwdotorg.org Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tegra.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index acb99eff9939..86568154cdb3 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -368,6 +368,7 @@ static void tegra_gpio_irq_shutdown(struct irq_data *d) struct tegra_gpio_info *tgi = bank->tgi; unsigned int gpio = d->hwirq; + tegra_gpio_irq_mask(d); gpiochip_unlock_as_irq(&tgi->gc, gpio); } -- cgit v1.2.3