From 19c26d90ff4ca08ef2a2fef23cc9c13cfbfd891e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 17 Apr 2020 11:21:57 +0200 Subject: gpio: mvebu: Fix probing for chips without PWM The PWM iomem resource is optional and its presence indicates whether the GPIO chip has a PWM or not, which is why mvebu_pwm_probe() returned successfully when the PWM resource was not present. With f51b18d92b66 the driver switched to devm_platform_ioremap_resource_byname() and its error return is propagated to the caller, so now a missing PWM resource leads to a probe error in the driver. To fix this explicitly test for the presence of the PWM resource and return successfully when it's not there. Do this check before the check for the clock is done (which GPIO chips without a PWM do not have). Also move the existing comment why the PWM resource is optional up to the actual check. Fixes: f51b18d92b66 ("gpio: mvebu: use devm_platform_ioremap_resource_byname()") Signed-off-by: Sascha Hauer Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-mvebu.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 3c9f4fb3d5a2..bd65114eb170 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -782,6 +782,15 @@ static int mvebu_pwm_probe(struct platform_device *pdev, "marvell,armada-370-gpio")) return 0; + /* + * There are only two sets of PWM configuration registers for + * all the GPIO lines on those SoCs which this driver reserves + * for the first two GPIO chips. So if the resource is missing + * we can't treat it as an error. + */ + if (!platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm")) + return 0; + if (IS_ERR(mvchip->clk)) return PTR_ERR(mvchip->clk); @@ -804,12 +813,6 @@ static int mvebu_pwm_probe(struct platform_device *pdev, mvchip->mvpwm = mvpwm; mvpwm->mvchip = mvchip; - /* - * There are only two sets of PWM configuration registers for - * all the GPIO lines on those SoCs which this driver reserves - * for the first two GPIO chips. So if the resource is missing - * we can't treat it as an error. - */ mvpwm->membase = devm_platform_ioremap_resource_byname(pdev, "pwm"); if (IS_ERR(mvpwm->membase)) return PTR_ERR(mvpwm->membase); -- cgit v1.2.3 From 333830aa149a87cabeb5d30fbcf12eecc8040d2c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 29 Apr 2020 15:56:54 +0200 Subject: gpio: exar: Fix bad handling for ida_simple_get error path The commit 7ecced0934e5 ("gpio: exar: add a check for the return value of ida_simple_get fails") added a goto jump to the common error handler for ida_simple_get() error, but this is wrong in two ways: it doesn't set the proper return code and, more badly, it invokes ida_simple_remove() with a negative index that shall lead to a kernel panic via BUG_ON(). This patch addresses those two issues. Fixes: 7ecced0934e5 ("gpio: exar: add a check for the return value of ida_simple_get fails") Cc: Signed-off-by: Takashi Iwai Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-exar.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-exar.c b/drivers/gpio/gpio-exar.c index da1ef0b1c291..b1accfba017d 100644 --- a/drivers/gpio/gpio-exar.c +++ b/drivers/gpio/gpio-exar.c @@ -148,8 +148,10 @@ static int gpio_exar_probe(struct platform_device *pdev) mutex_init(&exar_gpio->lock); index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL); - if (index < 0) - goto err_destroy; + if (index < 0) { + ret = index; + goto err_mutex_destroy; + } sprintf(exar_gpio->name, "exar_gpio%d", index); exar_gpio->gpio_chip.label = exar_gpio->name; @@ -176,6 +178,7 @@ static int gpio_exar_probe(struct platform_device *pdev) err_destroy: ida_simple_remove(&ida_index, index); +err_mutex_destroy: mutex_destroy(&exar_gpio->lock); return ret; } -- cgit v1.2.3 From 9fefca775c8ddbbbcd97f2860218188b8641819d Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Sat, 9 May 2020 16:08:13 +0200 Subject: gpiolib: notify user-space about line status changes after flags are set Currently we emit the REQUESTED line state event after the line is requested but before the flags are configured. This is obviously wrong as we want to pass the updated lineinfo to user-space together with the event. Since the flags can be configured in different ways depending on how the line is being requested - we need to call the notifier chain in different places separately. Fixes: 51c1064e82e7 ("gpiolib: add new ioctl() for monitoring changes in line info") Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index bf9732ab7f91..66cb3ca40184 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -729,6 +729,10 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) if (ret) goto out_free_descs; } + + atomic_notifier_call_chain(&desc->gdev->notifier, + GPIOLINE_CHANGED_REQUESTED, desc); + dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", offset); } @@ -1083,6 +1087,9 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) if (ret) goto out_free_desc; + atomic_notifier_call_chain(&desc->gdev->notifier, + GPIOLINE_CHANGED_REQUESTED, desc); + le->irq = gpiod_to_irq(desc); if (le->irq <= 0) { ret = -ENODEV; @@ -2998,8 +3005,6 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label) } done: spin_unlock_irqrestore(&gpio_lock, flags); - atomic_notifier_call_chain(&desc->gdev->notifier, - GPIOLINE_CHANGED_REQUESTED, desc); return ret; } @@ -4961,6 +4966,9 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, return ERR_PTR(ret); } + atomic_notifier_call_chain(&desc->gdev->notifier, + GPIOLINE_CHANGED_REQUESTED, desc); + return desc; } EXPORT_SYMBOL_GPL(gpiod_get_index); @@ -5026,6 +5034,9 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, return ERR_PTR(ret); } + atomic_notifier_call_chain(&desc->gdev->notifier, + GPIOLINE_CHANGED_REQUESTED, desc); + return desc; } EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod); -- cgit v1.2.3