From: Asmaa Mnebhi <asmaa@nvidia.com>
To: <andy.shevchenko@gmail.com>, <linus.walleij@linaro.org>,
<linux-gpio@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Cc: Asmaa Mnebhi <asmaa@nvidia.com>
Subject: [PATCH v3] gpio: mmio: handle "ngpios" properly in bgpio_init()
Date: Fri, 3 Mar 2023 16:58:14 -0500 [thread overview]
Message-ID: <20230303215814.24783-1-asmaa@nvidia.com> (raw)
bgpio_init() uses "sz" argument to populate ngpio, which is not
accurate. Instead, read the "ngpios" property from the DT and if it
doesn't exist, use the "sz" argument. With this change, drivers no
longer need to overwrite the ngpio variable after calling bgpio_init.
Signed-off-by: Asmaa Mnebhi <asmaa@nvidia.com>
---
drivers/gpio/gpio-mmio.c | 7 ++++-
drivers/gpio/gpiolib.c | 58 ++++++++++++++++++----------------------
drivers/gpio/gpiolib.h | 1 +
3 files changed, 33 insertions(+), 33 deletions(-)
diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c
index d9dff3dc92ae..c9f9f4e36c89 100644
--- a/drivers/gpio/gpio-mmio.c
+++ b/drivers/gpio/gpio-mmio.c
@@ -60,6 +60,8 @@ o ` ~~~~\___/~~~~ ` controller in FPGA is ,.`
#include <linux/of.h>
#include <linux/of_device.h>
+#include "gpiolib.h"
+
static void bgpio_write8(void __iomem *reg, unsigned long data)
{
writeb(data, reg);
@@ -614,10 +616,13 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev,
gc->parent = dev;
gc->label = dev_name(dev);
gc->base = -1;
- gc->ngpio = gc->bgpio_bits;
gc->request = bgpio_request;
gc->be_bits = !!(flags & BGPIOF_BIG_ENDIAN);
+ ret = gpiochip_get_ngpios(gc, dev);
+ if (ret)
+ gc->ngpio = gc->bgpio_bits;
+
ret = bgpio_setup_io(gc, dat, set, clr, flags);
if (ret)
return ret;
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 939c776b9488..17b63f52fda7 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -647,6 +647,28 @@ static void gpiochip_setup_devs(void)
}
}
+int gpiochip_get_ngpios(struct gpio_chip *gc, struct device *dev)
+{
+ u32 ngpios = gc->ngpio;
+ int ret;
+
+ if (ngpios == 0) {
+ ret = device_property_read_u32(dev, "ngpios", &ngpios);
+ if (ret) {
+ chip_err(gc, "Failed to get ngpios property\n");
+ return -EINVAL;
+ }
+
+ gc->ngpio = ngpios;
+ }
+
+ if (gc->ngpio > FASTPATH_NGPIO)
+ chip_warn(gc, "line cnt %u is greater than fast path cnt %u\n",
+ gc->ngpio, FASTPATH_NGPIO);
+
+ return 0;
+}
+
int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
struct lock_class_key *lock_key,
struct lock_class_key *request_key)
@@ -655,7 +677,6 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
struct gpio_device *gdev;
unsigned long flags;
unsigned int i;
- u32 ngpios = 0;
int base = 0;
int ret = 0;
@@ -704,36 +725,9 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
else
gdev->owner = THIS_MODULE;
- /*
- * Try the device properties if the driver didn't supply the number
- * of GPIO lines.
- */
- ngpios = gc->ngpio;
- if (ngpios == 0) {
- ret = device_property_read_u32(&gdev->dev, "ngpios", &ngpios);
- if (ret == -ENODATA)
- /*
- * -ENODATA means that there is no property found and
- * we want to issue the error message to the user.
- * Besides that, we want to return different error code
- * to state that supplied value is not valid.
- */
- ngpios = 0;
- else if (ret)
- goto err_free_dev_name;
-
- gc->ngpio = ngpios;
- }
-
- if (gc->ngpio == 0) {
- chip_err(gc, "tried to insert a GPIO chip with zero lines\n");
- ret = -EINVAL;
- goto err_free_dev_name;
- }
-
- if (gc->ngpio > FASTPATH_NGPIO)
- chip_warn(gc, "line cnt %u is greater than fast path cnt %u\n",
- gc->ngpio, FASTPATH_NGPIO);
+ ret = gpiochip_get_ngpios(gc, &gdev->dev);
+ if (ret)
+ return ret;
gdev->descs = kcalloc(gc->ngpio, sizeof(*gdev->descs), GFP_KERNEL);
if (!gdev->descs) {
@@ -903,7 +897,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
/* failures here can mean systems won't boot... */
if (ret != -EPROBE_DEFER) {
pr_err("%s: GPIOs %d..%d (%s) failed to register, %d\n", __func__,
- base, base + (int)ngpios - 1,
+ base, base + (int)gc->ngpio - 1,
gc->label ? : "generic", ret);
}
return ret;
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index b3c2db6eba80..c38cbf1b753b 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -207,6 +207,7 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce);
int gpiod_hog(struct gpio_desc *desc, const char *name,
unsigned long lflags, enum gpiod_flags dflags);
+int gpiochip_get_ngpios(struct gpio_chip *gc, struct device *dev);
/*
* Return the GPIO number of the passed descriptor relative to its chip
--
2.30.1
next reply other threads:[~2023-03-03 22:16 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-03 21:58 Asmaa Mnebhi [this message]
2023-03-03 22:35 ` Andy Shevchenko
2023-03-06 18:47 ` Asmaa Mnebhi
2023-03-06 20:16 ` Andy Shevchenko
2023-03-04 19:51 ` kernel test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230303215814.24783-1-asmaa@nvidia.com \
--to=asmaa@nvidia.com \
--cc=andy.shevchenko@gmail.com \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®