Thread (74 messages) 74 messages, 7 authors, 2020-09-11

Re: [PATCH 14/23] gpio: mockup: use the generic 'gpio-line-names' property

From: Bartosz Golaszewski <hidden>
Date: 2020-09-07 11:11:24
Also in: linux-acpi, linux-gpio, lkml

On Fri, Sep 4, 2020 at 6:46 PM Andy Shevchenko
[off-list ref] wrote:
On Fri, Sep 04, 2020 at 05:45:38PM +0200, Bartosz Golaszewski wrote:
quoted
From: Bartosz Golaszewski <redacted>

GPIO line names are currently created by the driver from the chip label.
We'll want to support custom formats for line names (for instance: to
name all lines the same) for user-space tests so create them in the
module init function and pass them to the driver using the standard
'gpio-line-names' property.

Signed-off-by: Bartosz Golaszewski <redacted>
---
 drivers/gpio/gpio-mockup.c | 70 +++++++++++++++++++++-----------------
 1 file changed, 38 insertions(+), 32 deletions(-)
diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c
index ce83f1df1933..96976ba66598 100644
--- a/drivers/gpio/gpio-mockup.c
+++ b/drivers/gpio/gpio-mockup.c
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/property.h>
 #include <linux/slab.h>
+#include <linux/string_helpers.h>
 #include <linux/uaccess.h>

 #include "gpiolib.h"
@@ -378,29 +379,6 @@ static void gpio_mockup_debugfs_setup(struct device *dev,
      return;
 }

-static int gpio_mockup_name_lines(struct device *dev,
-                               struct gpio_mockup_chip *chip)
-{
-     struct gpio_chip *gc = &chip->gc;
-     char **names;
-     int i;
-
-     names = devm_kcalloc(dev, gc->ngpio, sizeof(char *), GFP_KERNEL);
-     if (!names)
-             return -ENOMEM;
-
-     for (i = 0; i < gc->ngpio; i++) {
-             names[i] = devm_kasprintf(dev, GFP_KERNEL,
-                                       "%s-%d", gc->label, i);
-             if (!names[i])
-                     return -ENOMEM;
-     }
-
-     gc->names = (const char *const *)names;
-
-     return 0;
-}
-
 static void gpio_mockup_dispose_mappings(void *data)
 {
      struct gpio_mockup_chip *chip = data;
@@ -468,12 +446,6 @@ static int gpio_mockup_probe(struct platform_device *pdev)
      for (i = 0; i < gc->ngpio; i++)
              chip->lines[i].dir = GPIO_LINE_DIRECTION_IN;

-     if (device_property_read_bool(dev, "named-gpio-lines")) {
-             rv = gpio_mockup_name_lines(dev, chip);
-             if (rv)
-                     return rv;
-     }
-
      chip->irq_sim_domain = devm_irq_domain_create_sim(dev, NULL,
                                                        gc->ngpio);
      if (IS_ERR(chip->irq_sim_domain))
@@ -524,6 +496,27 @@ static void gpio_mockup_unregister_devices(void)
      }
 }

+static __init char **gpio_mockup_make_line_names(const char *label,
+                                              unsigned int num_lines)
+{
+     unsigned int i;
+     char **names;
+
+     names = kcalloc(num_lines + 1, sizeof(char *), GFP_KERNEL);
+     if (!names)
+             return NULL;
+
+     for (i = 0; i < num_lines; i++) {
+             names[i] = kasprintf(GFP_KERNEL, "%s-%u", label, i);
+             if (!names[i]) {
+                     kfree_strarray(names, i);
+                     return NULL;
+             }
+     }
+
+     return names;
+}
+
 static int __init gpio_mockup_init(void)
 {
      struct property_entry properties[GPIO_MOCKUP_MAX_PROP];
@@ -531,6 +524,7 @@ static int __init gpio_mockup_init(void)
      struct gpio_mockup_device *mockup_dev;
      int i, prop, num_chips, err = 0, base;
      struct platform_device_info pdevinfo;
+     char **line_names;
      u16 ngpio;

      if ((gpio_mockup_num_ranges < 2) ||
@@ -563,6 +557,7 @@ static int __init gpio_mockup_init(void)
              memset(properties, 0, sizeof(properties));
              memset(&pdevinfo, 0, sizeof(pdevinfo));
              prop = 0;
+             line_names = NULL;

              snprintf(chip_label, sizeof(chip_label),
                       "gpio-mockup-%c", i + 'A');
@@ -578,9 +573,18 @@ static int __init gpio_mockup_init(void)
                               : gpio_mockup_range_ngpio(i) - base;
              properties[prop++] = PROPERTY_ENTRY_U16("nr-gpios", ngpio);

-             if (gpio_mockup_named_lines)
-                     properties[prop++] = PROPERTY_ENTRY_BOOL(
-                                             "named-gpio-lines");
+             if (gpio_mockup_named_lines) {
+                     line_names = gpio_mockup_make_line_names(chip_label,
+                                                              ngpio);
+                     if (!line_names) {
+                             err = -ENOMEM;
+                             goto err_out;
+                     }
+
+                     properties[prop++] = PROPERTY_ENTRY_STRING_ARRAY_LEN(
+                                             "gpio-line-names",
+                                             line_names, ngpio);
+             }
Indentation here looks quite deep. Maybe introduce a helper in between where
you assign properties?
No need for that - this gets flattened later on in the series.

Bart
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help