gpio: of: make it possible to name GPIO lines
Make it possible to name the producer side of a GPIO line using a "gpio-line-names" property array, modeled on the "clock-output-names" property from the clock bindings. This naming is especially useful for: - Debugging: lines are named after function, not just opaque offset numbers. - Exploration: systems where some or all GPIO lines are available to end users, such as prototyping, one-off's "makerspace usecases" users are helped by the names of the GPIO lines when tinkering. This usecase has been surfacing recently. The gpio-line-names attribute is completely optional. Example output from lsgpio on a patched Snowball tree: GPIO chip: gpiochip6, "8000e180.gpio", 32 GPIO lines line 0: unnamed unused line 1: "AP_GPIO161" "extkb3" [kernel] line 2: "AP_GPIO162" "extkb4" [kernel] line 3: "ACCELEROMETER_INT1_RDY" unused [kernel] line 4: "ACCELEROMETER_INT2" unused line 5: "MAG_DRDY" unused [kernel] line 6: "GYRO_DRDY" unused [kernel] line 7: "RSTn_MLC" unused line 8: "RSTn_SLC" unused line 9: "GYRO_INT" unused line 10: "UART_WAKE" unused line 11: "GBF_RESET" unused line 12: unnamed unused Cc: Grant Likely <grant.likely@linaro.org> Cc: Amit Kucheria <amit.kucheria@linaro.org> Cc: David Mandala <david.mandala@linaro.org> Cc: Lee Campbell <leecam@google.com> Cc: devicetree@vger.kernel.org Acked-by: Rob Herring <robh@kernel.org> Reviewed-by: Michael Welling <mwelling@ieee.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>steinar/wifi_calib_4_9_kernel
parent
4c37ce8608
commit
fd9c55315d
|
@ -152,6 +152,21 @@ additional bitmask is needed to specify which GPIOs are actually in use,
|
||||||
and which are dummies. The bindings for this case has not yet been
|
and which are dummies. The bindings for this case has not yet been
|
||||||
specified, but should be specified if/when such hardware appears.
|
specified, but should be specified if/when such hardware appears.
|
||||||
|
|
||||||
|
Optionally, a GPIO controller may have a "gpio-line-names" property. This is
|
||||||
|
an array of strings defining the names of the GPIO lines going out of the
|
||||||
|
GPIO controller. This name should be the most meaningful producer name
|
||||||
|
for the system, such as a rail name indicating the usage. Package names
|
||||||
|
such as pin name are discouraged: such lines have opaque names (since they
|
||||||
|
are by definition generic purpose) and such names are usually not very
|
||||||
|
helpful. For example "MMC-CD", "Red LED Vdd" and "ethernet reset" are
|
||||||
|
reasonable line names as they describe what the line is used for. "GPIO0"
|
||||||
|
is not a good name to give to a GPIO line. Placeholders are discouraged:
|
||||||
|
rather use the "" (blank string) if the use of the GPIO line is undefined
|
||||||
|
in your design. The names are assigned starting from line offset 0 from
|
||||||
|
left to right from the passed array. An incomplete array (where the number
|
||||||
|
of passed named are less than ngpios) will still be used up until the last
|
||||||
|
provided valid line index.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
gpio-controller@00000000 {
|
gpio-controller@00000000 {
|
||||||
|
@ -160,6 +175,10 @@ gpio-controller@00000000 {
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
ngpios = <18>;
|
ngpios = <18>;
|
||||||
|
gpio-line-names = "MMC-CD", "MMC-WP", "VDD eth", "RST eth", "LED R",
|
||||||
|
"LED G", "LED B", "Col A", "Col B", "Col C", "Col D",
|
||||||
|
"Row A", "Row B", "Row C", "Row D", "NMI button",
|
||||||
|
"poweroff", "reset";
|
||||||
}
|
}
|
||||||
|
|
||||||
The GPIO chip may contain GPIO hog definitions. GPIO hogging is a mechanism
|
The GPIO chip may contain GPIO hog definitions. GPIO hogging is a mechanism
|
||||||
|
|
|
@ -195,6 +195,51 @@ static struct gpio_desc *of_parse_own_gpio(struct device_node *np,
|
||||||
return gg_data.out_gpio;
|
return gg_data.out_gpio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* of_gpiochip_set_names() - set up the names of the lines
|
||||||
|
* @chip: GPIO chip whose lines should be named, if possible
|
||||||
|
*/
|
||||||
|
static void of_gpiochip_set_names(struct gpio_chip *gc)
|
||||||
|
{
|
||||||
|
struct gpio_device *gdev = gc->gpiodev;
|
||||||
|
struct device_node *np = gc->of_node;
|
||||||
|
int i;
|
||||||
|
int nstrings;
|
||||||
|
|
||||||
|
nstrings = of_property_count_strings(np, "gpio-line-names");
|
||||||
|
if (nstrings <= 0)
|
||||||
|
/* Lines names not present */
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* This is normally not what you want */
|
||||||
|
if (gdev->ngpio != nstrings)
|
||||||
|
dev_info(&gdev->dev, "gpio-line-names specifies %d line "
|
||||||
|
"names but there are %d lines on the chip\n",
|
||||||
|
nstrings, gdev->ngpio);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure to not index beyond the end of the number of descriptors
|
||||||
|
* of the GPIO device.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < gdev->ngpio; i++) {
|
||||||
|
const char *name;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = of_property_read_string_index(np,
|
||||||
|
"gpio-line-names",
|
||||||
|
i,
|
||||||
|
&name);
|
||||||
|
if (ret) {
|
||||||
|
if (ret != -ENODATA)
|
||||||
|
dev_err(&gdev->dev,
|
||||||
|
"unable to name line %d: %d\n",
|
||||||
|
i, ret);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gdev->descs[i].name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* of_gpiochip_scan_gpios - Scan gpio-controller for gpio definitions
|
* of_gpiochip_scan_gpios - Scan gpio-controller for gpio definitions
|
||||||
* @chip: gpio chip to act on
|
* @chip: gpio chip to act on
|
||||||
|
@ -445,6 +490,10 @@ int of_gpiochip_add(struct gpio_chip *chip)
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
/* If the chip defines names itself, these take precedence */
|
||||||
|
if (!chip->names)
|
||||||
|
of_gpiochip_set_names(chip);
|
||||||
|
|
||||||
of_node_get(chip->of_node);
|
of_node_get(chip->of_node);
|
||||||
|
|
||||||
return of_gpiochip_scan_gpios(chip);
|
return of_gpiochip_scan_gpios(chip);
|
||||||
|
|
Loading…
Reference in New Issue