aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/gpio/board.txt11
-rw-r--r--drivers/gpio/Kconfig4
-rw-r--r--drivers/gpio/gpio-moxart.c3
-rw-r--r--drivers/gpio/gpio-pisosr.c4
-rw-r--r--drivers/gpio/gpiolib-sysfs.c12
-rw-r--r--drivers/gpio/gpiolib.c73
-rw-r--r--include/uapi/linux/gpio.h22
-rw-r--r--tools/gpio/lsgpio.c6
8 files changed, 64 insertions, 71 deletions
diff --git a/Documentation/gpio/board.txt b/Documentation/gpio/board.txt
index 3092178628c4..86d3fa95fd12 100644
--- a/Documentation/gpio/board.txt
+++ b/Documentation/gpio/board.txt
@@ -111,16 +111,13 @@ files that desire to do so need to include the following header:
GPIOs are mapped by the means of tables of lookups, containing instances of the
gpiod_lookup structure. Two macros are defined to help declaring such mappings:
- GPIO_LOOKUP(chip_label, chip_hwnum, dev_id, con_id, flags)
- GPIO_LOOKUP_IDX(chip_label, chip_hwnum, dev_id, con_id, idx, flags)
+ GPIO_LOOKUP(chip_label, chip_hwnum, con_id, flags)
+ GPIO_LOOKUP_IDX(chip_label, chip_hwnum, con_id, idx, flags)
where
- chip_label is the label of the gpiod_chip instance providing the GPIO
- chip_hwnum is the hardware number of the GPIO within the chip
- - dev_id is the identifier of the device that will make use of this GPIO. It
- can be NULL, in which case it will be matched for calls to gpiod_get()
- with a NULL device.
- con_id is the name of the GPIO function from the device point of view. It
can be NULL, in which case it will match any function.
- idx is the index of the GPIO within the function.
@@ -134,7 +131,9 @@ In the future, these flags might be extended to support more properties.
Note that GPIO_LOOKUP() is just a shortcut to GPIO_LOOKUP_IDX() where idx = 0.
A lookup table can then be defined as follows, with an empty entry defining its
-end:
+end. The 'dev_id' field of the table is the identifier of the device that will
+make use of these GPIOs. It can be NULL, in which case it will be matched for
+calls to gpiod_get() with a NULL device.
struct gpiod_lookup_table gpios_table = {
.dev_id = "foo.0",
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 5584ba457161..96ad29de3a3e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -266,7 +266,7 @@ config GPIO_LYNXPOINT
config GPIO_MB86S7X
bool "GPIO support for Fujitsu MB86S7x Platforms"
- depends on ARCH_MB86S7X
+ depends on ARCH_MB86S7X || COMPILE_TEST
help
Say yes here to support the GPIO controller in Fujitsu MB86S70 SoCs.
@@ -280,7 +280,7 @@ config GPIO_MM_LANTIQ
config GPIO_MOXART
bool "MOXART GPIO support"
- depends on ARCH_MOXART
+ depends on ARCH_MOXART || COMPILE_TEST
select GPIO_GENERIC
help
Select this option to enable GPIO driver for
diff --git a/drivers/gpio/gpio-moxart.c b/drivers/gpio/gpio-moxart.c
index 869002b7a571..f02d0b490978 100644
--- a/drivers/gpio/gpio-moxart.c
+++ b/drivers/gpio/gpio-moxart.c
@@ -57,10 +57,7 @@ static int moxart_gpio_probe(struct platform_device *pdev)
gc->label = "moxart-gpio";
gc->request = gpiochip_generic_request;
gc->free = gpiochip_generic_free;
- gc->bgpio_data = gc->read_reg(gc->reg_set);
gc->base = 0;
- gc->ngpio = 32;
- gc->parent = dev;
gc->owner = THIS_MODULE;
ret = devm_gpiochip_add_data(dev, gc, NULL);
diff --git a/drivers/gpio/gpio-pisosr.c b/drivers/gpio/gpio-pisosr.c
index 8b8bf8f9de6a..cb14b8d1d512 100644
--- a/drivers/gpio/gpio-pisosr.c
+++ b/drivers/gpio/gpio-pisosr.c
@@ -46,9 +46,9 @@ static int pisosr_gpio_refresh(struct pisosr_gpio *gpio)
mutex_lock(&gpio->lock);
if (gpio->load_gpio) {
- gpiod_set_value(gpio->load_gpio, 1);
+ gpiod_set_value_cansleep(gpio->load_gpio, 1);
udelay(1); /* registers load time (~10ns) */
- gpiod_set_value(gpio->load_gpio, 0);
+ gpiod_set_value_cansleep(gpio->load_gpio, 0);
udelay(1); /* registers recovery time (~5ns) */
}
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index c56309491e8b..932e510aec50 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -721,6 +721,7 @@ EXPORT_SYMBOL_GPL(gpiod_unexport);
int gpiochip_sysfs_register(struct gpio_device *gdev)
{
struct device *dev;
+ struct device *parent;
struct gpio_chip *chip = gdev->chip;
/*
@@ -732,8 +733,17 @@ int gpiochip_sysfs_register(struct gpio_device *gdev)
if (!gpio_class.p)
return 0;
+ /*
+ * For sysfs backward compatibility we need to preserve this
+ * preferred parenting to the gpio_chip parent field, if set.
+ */
+ if (chip->parent)
+ parent = chip->parent;
+ else
+ parent = &gdev->dev;
+
/* use chip->base for the ID; it's already known to be unique */
- dev = device_create_with_groups(&gpio_class, &gdev->dev,
+ dev = device_create_with_groups(&gpio_class, parent,
MKDEV(0, 0),
chip, gpiochip_groups,
"gpiochip%d", chip->base);
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index e31d0a1e6f7c..1741ef4d2aaa 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -206,58 +206,43 @@ EXPORT_SYMBOL_GPL(gpiod_get_direction);
*/
static int gpiodev_add_to_list(struct gpio_device *gdev)
{
- struct gpio_device *iterator;
- struct gpio_device *previous = NULL;
-
- if (!gdev->chip)
- return -EINVAL;
+ struct gpio_device *prev, *next;
if (list_empty(&gpio_devices)) {
+ /* initial entry in list */
list_add_tail(&gdev->list, &gpio_devices);
return 0;
}
- list_for_each_entry(iterator, &gpio_devices, list) {
- if (iterator->base >= gdev->base + gdev->ngpio) {
- /*
- * Iterator is the first GPIO chip so there is no
- * previous one
- */
- if (!previous) {
- goto found;
- } else {
- /*
- * We found a valid range(means
- * [base, base + ngpio - 1]) between previous
- * and iterator chip.
- */
- if (previous->base + previous->ngpio
- <= gdev->base)
- goto found;
- }
- }
- previous = iterator;
+ next = list_entry(gpio_devices.next, struct gpio_device, list);
+ if (gdev->base + gdev->ngpio <= next->base) {
+ /* add before first entry */
+ list_add(&gdev->list, &gpio_devices);
+ return 0;
}
- /*
- * We are beyond the last chip in the list and iterator now
- * points to the head.
- * Let iterator point to the last chip in the list.
- */
-
- iterator = list_last_entry(&gpio_devices, struct gpio_device, list);
- if (iterator->base + iterator->ngpio <= gdev->base) {
- list_add(&gdev->list, &iterator->list);
+ prev = list_entry(gpio_devices.prev, struct gpio_device, list);
+ if (prev->base + prev->ngpio <= gdev->base) {
+ /* add behind last entry */
+ list_add_tail(&gdev->list, &gpio_devices);
return 0;
}
- dev_err(&gdev->dev,
- "GPIO integer space overlap, cannot add chip\n");
- return -EBUSY;
+ list_for_each_entry_safe(prev, next, &gpio_devices, list) {
+ /* at the end of the list */
+ if (&next->list == &gpio_devices)
+ break;
-found:
- list_add_tail(&gdev->list, &iterator->list);
- return 0;
+ /* add between prev and next */
+ if (prev->base + prev->ngpio <= gdev->base
+ && gdev->base + gdev->ngpio <= next->base) {
+ list_add(&gdev->list, &prev->list);
+ return 0;
+ }
+ }
+
+ dev_err(&gdev->dev, "GPIO integer space overlap, cannot add chip\n");
+ return -EBUSY;
}
/**
@@ -368,11 +353,11 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
lineinfo.name[0] = '\0';
}
if (desc->label) {
- strncpy(lineinfo.label, desc->label,
- sizeof(lineinfo.label));
- lineinfo.label[sizeof(lineinfo.label)-1] = '\0';
+ strncpy(lineinfo.consumer, desc->label,
+ sizeof(lineinfo.consumer));
+ lineinfo.consumer[sizeof(lineinfo.consumer)-1] = '\0';
} else {
- lineinfo.label[0] = '\0';
+ lineinfo.consumer[0] = '\0';
}
/*
diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h
index 416ce47f2291..dfe8ade2742d 100644
--- a/include/uapi/linux/gpio.h
+++ b/include/uapi/linux/gpio.h
@@ -15,8 +15,9 @@
/**
* struct gpiochip_info - Information about a certain GPIO chip
- * @name: the name of this GPIO chip
- * @label: a functional name for this GPIO chip
+ * @name: the Linux kernel name of this GPIO chip
+ * @label: a functional name for this GPIO chip, such as a product
+ * number, may be NULL
* @lines: number of GPIO lines on this chip
*/
struct gpiochip_info {
@@ -34,20 +35,21 @@ struct gpiochip_info {
/**
* struct gpioline_info - Information about a certain GPIO line
- * @line_offset: the local offset on this GPIO device, fill in when
- * requesting information from the kernel
+ * @line_offset: the local offset on this GPIO device, fill this in when
+ * requesting the line information from the kernel
* @flags: various flags for this line
- * @name: the name of this GPIO line
- * @label: a functional name for this GPIO line
- * @kernel: this GPIO is in use by the kernel
- * @out: this GPIO is an output line (false means it is an input)
- * @active_low: this GPIO is active low
+ * @name: the name of this GPIO line, such as the output pin of the line on the
+ * chip, a rail or a pin header name on a board, as specified by the gpio
+ * chip, may be NULL
+ * @consumer: a functional name for the consumer of this GPIO line as set by
+ * whatever is using it, will be NULL if there is no current user but may
+ * also be NULL if the consumer doesn't set this up
*/
struct gpioline_info {
__u32 line_offset;
__u32 flags;
char name[32];
- char label[32];
+ char consumer[32];
};
#define GPIO_GET_CHIPINFO_IOCTL _IOR('o', 0x01, struct gpiochip_info)
diff --git a/tools/gpio/lsgpio.c b/tools/gpio/lsgpio.c
index 6af118cc7efb..1124da375942 100644
--- a/tools/gpio/lsgpio.c
+++ b/tools/gpio/lsgpio.c
@@ -116,10 +116,10 @@ int list_device(const char *device_name)
fprintf(stdout, " \"%s\"", linfo.name);
else
fprintf(stdout, " unnamed");
- if (linfo.label[0])
- fprintf(stdout, " \"%s\"", linfo.label);
+ if (linfo.consumer[0])
+ fprintf(stdout, " \"%s\"", linfo.consumer);
else
- fprintf(stdout, " unlabeled");
+ fprintf(stdout, " unused");
if (linfo.flags) {
fprintf(stdout, " [");
print_flags(linfo.flags);