Skip to content

Commit

Permalink
gpio: mockup: use the generic 'gpio-line-names' property
Browse files Browse the repository at this point in the history
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 <bgolaszewski@baylibre.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  • Loading branch information
brgl committed Sep 30, 2020
1 parent 148c256 commit 582be05
Showing 1 changed file with 38 additions and 32 deletions.
70 changes: 38 additions & 32 deletions drivers/gpio/gpio-mockup.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,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"
Expand Down Expand Up @@ -374,29 +375,6 @@ static void gpio_mockup_debugfs_setup(struct device *dev,
}
}

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;
Expand Down Expand Up @@ -464,12 +442,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))
Expand Down Expand Up @@ -510,13 +482,35 @@ static void gpio_mockup_unregister_pdevs(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];
int i, prop, num_chips, err = 0, base;
struct platform_device_info pdevinfo;
struct platform_device *pdev;
char chip_label[32];
char **line_names;
u16 ngpio;

if ((gpio_mockup_num_ranges < 2) ||
Expand Down Expand Up @@ -549,6 +543,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');
Expand All @@ -564,15 +559,26 @@ 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) {
platform_driver_unregister(&gpio_mockup_driver);
gpio_mockup_unregister_pdevs();
return -ENOMEM;
}

properties[prop++] = PROPERTY_ENTRY_STRING_ARRAY_LEN(
"gpio-line-names",
line_names, ngpio);
}

pdevinfo.name = "gpio-mockup";
pdevinfo.id = i;
pdevinfo.properties = properties;

pdev = platform_device_register_full(&pdevinfo);
kfree_strarray(line_names, ngpio);
if (IS_ERR(pdev)) {
pr_err("error registering device");
platform_driver_unregister(&gpio_mockup_driver);
Expand Down

0 comments on commit 582be05

Please sign in to comment.