gpio: aggregator: Fix calling into sleeping GPIO controllers
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2071835
Tested: This is one of a series of patch sets to enable Arm SystemReady IR
support in the kernel for NXP i.MX8 platforms. This set updates GPIO
support. It has been tested via simple boot tests and by using the
kernel GPIO tools to verify pins are being identified and can be used.
commit 2cba05451a6d0c703bb74f1a250691404f27c4f1
Author: Geert Uytterhoeven <geert+renesas@glider.be>
Date: Mon Jan 31 11:35:53 2022 +0100
gpio: aggregator: Fix calling into sleeping GPIO controllers
If the parent GPIO controller is a sleeping controller (e.g. a GPIO
controller connected to I2C), getting or setting a GPIO triggers a
might_sleep() warning. This happens because the GPIO Aggregator takes
the can_sleep flag into account only for its internal locking, not for
calling into the parent GPIO controller.
Fix this by using the gpiod_[gs]et*_cansleep() APIs when calling into a
sleeping GPIO controller.
Reported-by: Mikko Salomäki <ms@datarespons.se>
Fixes: 828546e242
("gpio: Add GPIO Aggregator")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
(cherry picked from commit 2cba05451a6d0c703bb74f1a250691404f27c4f1)
Signed-off-by: Al Stone <ahs3@redhat.com>
This commit is contained in:
parent
456898eea2
commit
6d5ce6b1f3
|
@ -278,7 +278,8 @@ static int gpio_fwd_get(struct gpio_chip *chip, unsigned int offset)
|
|||
{
|
||||
struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
|
||||
|
||||
return gpiod_get_value(fwd->descs[offset]);
|
||||
return chip->can_sleep ? gpiod_get_value_cansleep(fwd->descs[offset])
|
||||
: gpiod_get_value(fwd->descs[offset]);
|
||||
}
|
||||
|
||||
static int gpio_fwd_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
|
||||
|
@ -293,7 +294,10 @@ static int gpio_fwd_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
|
|||
for_each_set_bit(i, mask, fwd->chip.ngpio)
|
||||
descs[j++] = fwd->descs[i];
|
||||
|
||||
error = gpiod_get_array_value(j, descs, NULL, values);
|
||||
if (fwd->chip.can_sleep)
|
||||
error = gpiod_get_array_value_cansleep(j, descs, NULL, values);
|
||||
else
|
||||
error = gpiod_get_array_value(j, descs, NULL, values);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -328,7 +332,10 @@ static void gpio_fwd_set(struct gpio_chip *chip, unsigned int offset, int value)
|
|||
{
|
||||
struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
|
||||
|
||||
gpiod_set_value(fwd->descs[offset], value);
|
||||
if (chip->can_sleep)
|
||||
gpiod_set_value_cansleep(fwd->descs[offset], value);
|
||||
else
|
||||
gpiod_set_value(fwd->descs[offset], value);
|
||||
}
|
||||
|
||||
static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
|
||||
|
@ -343,7 +350,10 @@ static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
|
|||
descs[j++] = fwd->descs[i];
|
||||
}
|
||||
|
||||
gpiod_set_array_value(j, descs, NULL, values);
|
||||
if (fwd->chip.can_sleep)
|
||||
gpiod_set_array_value_cansleep(j, descs, NULL, values);
|
||||
else
|
||||
gpiod_set_array_value(j, descs, NULL, values);
|
||||
}
|
||||
|
||||
static void gpio_fwd_set_multiple_locked(struct gpio_chip *chip,
|
||||
|
|
Loading…
Reference in New Issue