Re: [PATCH 01/12] gpio: mmio: use new GPIO line value setter callbacks
From: Klara Modin <hidden>
Date: 2025-06-18 11:59:50
Also in:
linux-gpio, linux-omap, linux-riscv, lkml, openbmc
Subsystem:
gpio subsystem, the rest · Maintainers:
Linus Walleij, Bartosz Golaszewski, Linus Torvalds
Hi, On 2025-06-10 14:33:11 +0200, Bartosz Golaszewski wrote:
quoted hunk ↗ jump to hunk
From: Bartosz Golaszewski <redacted> struct gpio_chip now has callbacks for setting line values that return an integer, allowing to indicate failures. Convert the driver to using them. Signed-off-by: Bartosz Golaszewski <redacted> --- drivers/gpio/gpio-mmio.c | 53 ++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 20 deletions(-)diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c index 4841e4ebe7a67d0f954e9a6f995ec5758f124edd..9169eccadb238efe944d494054b1e009f16eee7f 100644 --- a/drivers/gpio/gpio-mmio.c +++ b/drivers/gpio/gpio-mmio.c@@ -211,11 +211,12 @@ static int bgpio_get_multiple_be(struct gpio_chip *gc, unsigned long *mask, return 0; } -static void bgpio_set_none(struct gpio_chip *gc, unsigned int gpio, int val) +static int bgpio_set_none(struct gpio_chip *gc, unsigned int gpio, int val) { + return 0; } -static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +static int bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) { unsigned long mask = bgpio_line2mask(gc, gpio); unsigned long flags;@@ -230,10 +231,12 @@ static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) gc->write_reg(gc->reg_dat, gc->bgpio_data); raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags); + + return 0; } -static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio, - int val) +static int bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio, + int val) { unsigned long mask = bgpio_line2mask(gc, gpio);@@ -241,9 +244,11 @@ static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio, gc->write_reg(gc->reg_set, mask); else gc->write_reg(gc->reg_clr, mask); + + return 0; } -static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val) +static int bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val) { unsigned long mask = bgpio_line2mask(gc, gpio); unsigned long flags;@@ -258,6 +263,8 @@ static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val) gc->write_reg(gc->reg_set, gc->bgpio_data); raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags); + + return 0; } static void bgpio_multiple_get_masks(struct gpio_chip *gc,@@ -298,21 +305,25 @@ static void bgpio_set_multiple_single_reg(struct gpio_chip *gc, raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags); } -static void bgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, +static int bgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { bgpio_set_multiple_single_reg(gc, mask, bits, gc->reg_dat); + + return 0; } -static void bgpio_set_multiple_set(struct gpio_chip *gc, unsigned long *mask, - unsigned long *bits) +static int bgpio_set_multiple_set(struct gpio_chip *gc, unsigned long *mask, + unsigned long *bits) { bgpio_set_multiple_single_reg(gc, mask, bits, gc->reg_set); + + return 0; } -static void bgpio_set_multiple_with_clear(struct gpio_chip *gc, - unsigned long *mask, - unsigned long *bits) +static int bgpio_set_multiple_with_clear(struct gpio_chip *gc, + unsigned long *mask, + unsigned long *bits) { unsigned long set_mask, clear_mask;@@ -322,6 +333,8 @@ static void bgpio_set_multiple_with_clear(struct gpio_chip *gc, gc->write_reg(gc->reg_set, set_mask); if (clear_mask) gc->write_reg(gc->reg_clr, clear_mask); + + return 0; } static int bgpio_dir_return(struct gpio_chip *gc, unsigned int gpio, bool dir_out)@@ -510,18 +523,18 @@ static int bgpio_setup_io(struct gpio_chip *gc, if (set && clr) { gc->reg_set = set; gc->reg_clr = clr; - gc->set = bgpio_set_with_clear; - gc->set_multiple = bgpio_set_multiple_with_clear; + gc->set_rv = bgpio_set_with_clear; + gc->set_multiple_rv = bgpio_set_multiple_with_clear; } else if (set && !clr) { gc->reg_set = set; - gc->set = bgpio_set_set; - gc->set_multiple = bgpio_set_multiple_set; + gc->set_rv = bgpio_set_set; + gc->set_multiple_rv = bgpio_set_multiple_set; } else if (flags & BGPIOF_NO_OUTPUT) { - gc->set = bgpio_set_none; - gc->set_multiple = NULL; + gc->set_rv = bgpio_set_none; + gc->set_multiple_rv = NULL; } else { - gc->set = bgpio_set; - gc->set_multiple = bgpio_set_multiple; + gc->set_rv = bgpio_set; + gc->set_multiple_rv = bgpio_set_multiple; } if (!(flags & BGPIOF_UNREADABLE_REG_SET) &&@@ -654,7 +667,7 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev, } gc->bgpio_data = gc->read_reg(gc->reg_dat); - if (gc->set == bgpio_set_set && + if (gc->set_rv == bgpio_set_set && !(flags & BGPIOF_UNREADABLE_REG_SET)) gc->bgpio_data = gc->read_reg(gc->reg_set);-- 2.48.1
Isn't this missing to convert gc->set() to gc-set_rv() in several places? Without the attached diff I get a null pointer reference on e.g. the spacemit k1 driver. Regards, Klara Modin --
diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c
index 9169eccadb23..57622f45d33e 100644
--- a/drivers/gpio/gpio-mmio.c
+++ b/drivers/gpio/gpio-mmio.c@@ -362,7 +362,7 @@ static int bgpio_dir_out_err(struct gpio_chip *gc, unsigned int gpio, static int bgpio_simple_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) { - gc->set(gc, gpio, val); + gc->set_rv(gc, gpio, val); return bgpio_dir_return(gc, gpio, true); }
@@ -427,14 +427,14 @@ static int bgpio_dir_out_dir_first(struct gpio_chip *gc, unsigned int gpio, int val) { bgpio_dir_out(gc, gpio, val); - gc->set(gc, gpio, val); + gc->set_rv(gc, gpio, val); return bgpio_dir_return(gc, gpio, true); } static int bgpio_dir_out_val_first(struct gpio_chip *gc, unsigned int gpio, int val) { - gc->set(gc, gpio, val); + gc->set_rv(gc, gpio, val); bgpio_dir_out(gc, gpio, val); return bgpio_dir_return(gc, gpio, true); }