[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20250623-gpiochip-set-rv-gpio-v3-1-90f0e170a846@linaro.org>
Date: Mon, 23 Jun 2025 09:57:16 +0200
From: Bartosz Golaszewski <brgl@...ev.pl>
To: Russell King <linux@...linux.org.uk>,
Linus Walleij <linus.walleij@...aro.org>, Arnd Bergmann <arnd@...nel.org>,
Bartosz Golaszewski <brgl@...ev.pl>
Cc: linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org,
linux-gpio@...r.kernel.org,
Bartosz Golaszewski <bartosz.golaszewski@...aro.org>
Subject: [PATCH v3] gpio: reg: use new GPIO line value setter callbacks
From: Bartosz Golaszewski <bartosz.golaszewski@...aro.org>
struct gpio_chip now has callbacks for setting line values that return
an integer, allowing to indicate failures. Convert the legacy generic
gpio-reg module to using them. We have to update the two legacy ARM
platforms that use it at the same time as they call the set_multiple()
callbacks directly (they shouldn't but it's old technical debt I
suppose).
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@...aro.org>
---
Commit 98ce1eb1fd87e ("gpiolib: introduce gpio_chip setters that return
values") added new line setter callbacks to struct gpio_chip. They allow
to indicate failures to callers. We're in the process of converting all
GPIO controllers to using them before removing the old ones. This is the
last remaining patch from a bigger series that already went into
linux-next. The idea is for the ARM changes to be Acked by Arnd or
Russell and routed through the GPIO tree.
---
Changes in v3:
- also modify the callbacks used in legacy ARM platforms
- drop applied patches
- Link to v2: https://lore.kernel.org/r/20250619-gpiochip-set-rv-gpio-v2-0-74abf689fbd8@linaro.org
Changes in v2:
- fix a NULL-pointer dereference in gpio-reg: use the correct function
pointer when calling the setter callback directly
- Link to v1: https://lore.kernel.org/r/20250617-gpiochip-set-rv-gpio-v1-0-903703881fa2@linaro.org
---
arch/arm/mach-sa1100/assabet.c | 2 +-
arch/arm/mach-sa1100/neponset.c | 2 +-
drivers/gpio/gpio-reg.c | 16 ++++++++++------
3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 2b833aa0212b294eecd7a8177d58c7cb50fe6c61..bad8aa661e9d0998e8238b6559757ec83bff4cb1 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -80,7 +80,7 @@ void ASSABET_BCR_frob(unsigned int mask, unsigned int val)
{
unsigned long m = mask, v = val;
- assabet_bcr_gc->set_multiple(assabet_bcr_gc, &m, &v);
+ assabet_bcr_gc->set_multiple_rv(assabet_bcr_gc, &m, &v);
}
EXPORT_SYMBOL(ASSABET_BCR_frob);
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 88fe79f0a4ed36a3bcae349fd037b52d0f9964d9..6516598c8a713bc5ca055be0934a03be73c07403 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -126,7 +126,7 @@ void neponset_ncr_frob(unsigned int mask, unsigned int val)
unsigned long m = mask, v = val;
if (nep)
- n->gpio[0]->set_multiple(n->gpio[0], &m, &v);
+ n->gpio[0]->set_multiple_rv(n->gpio[0], &m, &v);
else
WARN(1, "nep unset\n");
}
diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c
index 73c7260d89c083a702b1d914ddca7a573a37de4a..d8da99f973850e5f4afa36d97c685f477837e665 100644
--- a/drivers/gpio/gpio-reg.c
+++ b/drivers/gpio/gpio-reg.c
@@ -46,7 +46,7 @@ static int gpio_reg_direction_output(struct gpio_chip *gc, unsigned offset,
if (r->direction & BIT(offset))
return -ENOTSUPP;
- gc->set(gc, offset, value);
+ gc->set_rv(gc, offset, value);
return 0;
}
@@ -57,7 +57,7 @@ static int gpio_reg_direction_input(struct gpio_chip *gc, unsigned offset)
return r->direction & BIT(offset) ? 0 : -ENOTSUPP;
}
-static void gpio_reg_set(struct gpio_chip *gc, unsigned offset, int value)
+static int gpio_reg_set(struct gpio_chip *gc, unsigned int offset, int value)
{
struct gpio_reg *r = to_gpio_reg(gc);
unsigned long flags;
@@ -72,6 +72,8 @@ static void gpio_reg_set(struct gpio_chip *gc, unsigned offset, int value)
r->out = val;
writel_relaxed(val, r->reg);
spin_unlock_irqrestore(&r->lock, flags);
+
+ return 0;
}
static int gpio_reg_get(struct gpio_chip *gc, unsigned offset)
@@ -92,8 +94,8 @@ static int gpio_reg_get(struct gpio_chip *gc, unsigned offset)
return !!(val & mask);
}
-static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
- unsigned long *bits)
+static int gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
+ unsigned long *bits)
{
struct gpio_reg *r = to_gpio_reg(gc);
unsigned long flags;
@@ -102,6 +104,8 @@ static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
r->out = (r->out & ~*mask) | (*bits & *mask);
writel_relaxed(r->out, r->reg);
spin_unlock_irqrestore(&r->lock, flags);
+
+ return 0;
}
static int gpio_reg_to_irq(struct gpio_chip *gc, unsigned offset)
@@ -157,9 +161,9 @@ struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
r->gc.get_direction = gpio_reg_get_direction;
r->gc.direction_input = gpio_reg_direction_input;
r->gc.direction_output = gpio_reg_direction_output;
- r->gc.set = gpio_reg_set;
+ r->gc.set_rv = gpio_reg_set;
r->gc.get = gpio_reg_get;
- r->gc.set_multiple = gpio_reg_set_multiple;
+ r->gc.set_multiple_rv = gpio_reg_set_multiple;
if (irqs)
r->gc.to_irq = gpio_reg_to_irq;
r->gc.base = base;
---
base-commit: cb908f3699fb137e28017a8fdf506c35762b3eb6
change-id: 20250617-gpiochip-set-rv-gpio-e1e864768942
Best regards,
--
Bartosz Golaszewski <bartosz.golaszewski@...aro.org>
Powered by blists - more mailing lists