Commit 30a464a8 authored by Linus Walleij's avatar Linus Walleij

Merge tag 'gpio-updates-for-v5.7-part4' of...

Merge tag 'gpio-updates-for-v5.7-part4' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into devel

gpio updates for v5.7 part 4

- improve comments in the uapi header
- fix documentation issues
- add a warning to gpio-pl061 when the IRQ line is not configured
- allow building gpio-mxc and gpio-mxs with COMPILE_TEST enabled
- don't print an error message when an optional IRQ is missing in gpio-mvebu
- fix a potential segfault in gpio-hammer
- fix a couple typos and coding style issues in gpio tools
- provide a new flag in gpio-mmio and use it in mt7621 to fix an issue with
  the controller ignoring value setting when a GPIO is in input mode
- slightly refactor gpio_name_to_desc()
parents a28e1c05 97551625
...@@ -416,7 +416,7 @@ The preferred way to set up the helpers is to fill in the ...@@ -416,7 +416,7 @@ The preferred way to set up the helpers is to fill in the
struct gpio_irq_chip inside struct gpio_chip before adding the gpio_chip. struct gpio_irq_chip inside struct gpio_chip before adding the gpio_chip.
If you do this, the additional irq_chip will be set up by gpiolib at the If you do this, the additional irq_chip will be set up by gpiolib at the
same time as setting up the rest of the GPIO functionality. The following same time as setting up the rest of the GPIO functionality. The following
is a typical example of a cascaded interrupt handler using gpio_irq_chip:: is a typical example of a cascaded interrupt handler using gpio_irq_chip:
.. code-block:: c .. code-block:: c
...@@ -453,7 +453,7 @@ is a typical example of a cascaded interrupt handler using gpio_irq_chip:: ...@@ -453,7 +453,7 @@ is a typical example of a cascaded interrupt handler using gpio_irq_chip::
return devm_gpiochip_add_data(dev, &g->gc, g); return devm_gpiochip_add_data(dev, &g->gc, g);
The helper support using hierarchical interrupt controllers as well. The helper support using hierarchical interrupt controllers as well.
In this case the typical set-up will look like this:: In this case the typical set-up will look like this:
.. code-block:: c .. code-block:: c
......
...@@ -394,13 +394,13 @@ config GPIO_MVEBU ...@@ -394,13 +394,13 @@ config GPIO_MVEBU
config GPIO_MXC config GPIO_MXC
def_bool y def_bool y
depends on ARCH_MXC depends on ARCH_MXC || COMPILE_TEST
select GPIO_GENERIC select GPIO_GENERIC
select GENERIC_IRQ_CHIP select GENERIC_IRQ_CHIP
config GPIO_MXS config GPIO_MXS
def_bool y def_bool y
depends on ARCH_MXS depends on ARCH_MXS || COMPILE_TEST
select GPIO_GENERIC select GPIO_GENERIC
select GENERIC_IRQ_CHIP select GENERIC_IRQ_CHIP
......
...@@ -389,12 +389,10 @@ static int bgpio_get_dir(struct gpio_chip *gc, unsigned int gpio) ...@@ -389,12 +389,10 @@ static int bgpio_get_dir(struct gpio_chip *gc, unsigned int gpio)
return GPIO_LINE_DIRECTION_IN; return GPIO_LINE_DIRECTION_IN;
} }
static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
{ {
unsigned long flags; unsigned long flags;
gc->set(gc, gpio, val);
spin_lock_irqsave(&gc->bgpio_lock, flags); spin_lock_irqsave(&gc->bgpio_lock, flags);
gc->bgpio_dir |= bgpio_line2mask(gc, gpio); gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
...@@ -405,7 +403,21 @@ static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) ...@@ -405,7 +403,21 @@ static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
gc->write_reg(gc->reg_dir_out, gc->bgpio_dir); gc->write_reg(gc->reg_dir_out, gc->bgpio_dir);
spin_unlock_irqrestore(&gc->bgpio_lock, flags); spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static int bgpio_dir_out_dir_first(struct gpio_chip *gc, unsigned int gpio,
int val)
{
bgpio_dir_out(gc, gpio, val);
gc->set(gc, gpio, val);
return 0;
}
static int bgpio_dir_out_val_first(struct gpio_chip *gc, unsigned int gpio,
int val)
{
gc->set(gc, gpio, val);
bgpio_dir_out(gc, gpio, val);
return 0; return 0;
} }
...@@ -538,7 +550,10 @@ static int bgpio_setup_direction(struct gpio_chip *gc, ...@@ -538,7 +550,10 @@ static int bgpio_setup_direction(struct gpio_chip *gc,
if (dirout || dirin) { if (dirout || dirin) {
gc->reg_dir_out = dirout; gc->reg_dir_out = dirout;
gc->reg_dir_in = dirin; gc->reg_dir_in = dirin;
gc->direction_output = bgpio_dir_out; if (flags & BGPIOF_NO_SET_ON_INPUT)
gc->direction_output = bgpio_dir_out_dir_first;
else
gc->direction_output = bgpio_dir_out_val_first;
gc->direction_input = bgpio_dir_in; gc->direction_input = bgpio_dir_in;
gc->get_direction = bgpio_get_dir; gc->get_direction = bgpio_get_dir;
} else { } else {
......
...@@ -227,8 +227,8 @@ mediatek_gpio_bank_probe(struct device *dev, ...@@ -227,8 +227,8 @@ mediatek_gpio_bank_probe(struct device *dev,
ctrl = mtk->base + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_STRIDE); ctrl = mtk->base + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_STRIDE);
diro = mtk->base + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_STRIDE); diro = mtk->base + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_STRIDE);
ret = bgpio_init(&rg->chip, dev, 4, ret = bgpio_init(&rg->chip, dev, 4, dat, set, ctrl, diro, NULL,
dat, set, ctrl, diro, NULL, 0); BGPIOF_NO_SET_ON_INPUT);
if (ret) { if (ret) {
dev_err(dev, "bgpio_init() failed\n"); dev_err(dev, "bgpio_init() failed\n");
return ret; return ret;
......
...@@ -1247,7 +1247,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) ...@@ -1247,7 +1247,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
* pins. * pins.
*/ */
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
int irq = platform_get_irq(pdev, i); int irq = platform_get_irq_optional(pdev, i);
if (irq < 0) if (irq < 0)
continue; continue;
......
...@@ -326,10 +326,8 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -326,10 +326,8 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
writeb(0, pl061->base + GPIOIE); /* disable irqs */ writeb(0, pl061->base + GPIOIE); /* disable irqs */
irq = adev->irq[0]; irq = adev->irq[0];
if (irq < 0) { if (!irq)
dev_err(&adev->dev, "invalid IRQ\n"); dev_warn(&adev->dev, "IRQ support disabled\n");
return -ENODEV;
}
pl061->parent_irq = irq; pl061->parent_irq = irq;
girq = &pl061->gc.irq; girq = &pl061->gc.irq;
......
...@@ -301,6 +301,9 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name) ...@@ -301,6 +301,9 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name)
struct gpio_device *gdev; struct gpio_device *gdev;
unsigned long flags; unsigned long flags;
if (!name)
return NULL;
spin_lock_irqsave(&gpio_lock, flags); spin_lock_irqsave(&gpio_lock, flags);
list_for_each_entry(gdev, &gpio_devices, list) { list_for_each_entry(gdev, &gpio_devices, list) {
...@@ -309,7 +312,7 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name) ...@@ -309,7 +312,7 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name)
for (i = 0; i != gdev->ngpio; ++i) { for (i = 0; i != gdev->ngpio; ++i) {
struct gpio_desc *desc = &gdev->descs[i]; struct gpio_desc *desc = &gdev->descs[i];
if (!desc->name || !name) if (!desc->name)
continue; continue;
if (!strcmp(desc->name, name)) { if (!strcmp(desc->name, name)) {
......
...@@ -572,6 +572,7 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev, ...@@ -572,6 +572,7 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev,
#define BGPIOF_BIG_ENDIAN_BYTE_ORDER BIT(3) #define BGPIOF_BIG_ENDIAN_BYTE_ORDER BIT(3)
#define BGPIOF_READ_OUTPUT_REG_SET BIT(4) /* reg_set stores output value */ #define BGPIOF_READ_OUTPUT_REG_SET BIT(4) /* reg_set stores output value */
#define BGPIOF_NO_OUTPUT BIT(5) /* only input */ #define BGPIOF_NO_OUTPUT BIT(5) /* only input */
#define BGPIOF_NO_SET_ON_INPUT BIT(6)
int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, int gpiochip_irq_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hwirq); irq_hw_number_t hwirq);
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* struct gpiochip_info - Information about a certain GPIO chip * struct gpiochip_info - Information about a certain GPIO chip
* @name: the Linux kernel name of this GPIO chip * @name: the Linux kernel name of this GPIO chip
* @label: a functional name for this GPIO chip, such as a product * @label: a functional name for this GPIO chip, such as a product
* number, may be NULL * number, may be empty
* @lines: number of GPIO lines on this chip * @lines: number of GPIO lines on this chip
*/ */
struct gpiochip_info { struct gpiochip_info {
...@@ -44,10 +44,10 @@ struct gpiochip_info { ...@@ -44,10 +44,10 @@ struct gpiochip_info {
* @flags: various flags for this line * @flags: various flags for this line
* @name: the name of this GPIO line, such as the output pin of the line on the * @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, a rail or a pin header name on a board, as specified by the gpio
* chip, may be NULL * chip, may be empty
* @consumer: a functional name for the consumer of this GPIO line as set by * @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 * whatever is using it, will be empty if there is no current user but may
* also be NULL if the consumer doesn't set this up * also be empty if the consumer doesn't set this up
*/ */
struct gpioline_info { struct gpioline_info {
__u32 line_offset; __u32 line_offset;
......
...@@ -77,7 +77,7 @@ int hammer_device(const char *device_name, unsigned int *lines, int nlines, ...@@ -77,7 +77,7 @@ int hammer_device(const char *device_name, unsigned int *lines, int nlines,
fprintf(stdout, "[%c] ", swirr[j]); fprintf(stdout, "[%c] ", swirr[j]);
j++; j++;
if (j == sizeof(swirr)-1) if (j == sizeof(swirr) - 1)
j = 0; j = 0;
fprintf(stdout, "["); fprintf(stdout, "[");
...@@ -135,7 +135,14 @@ int main(int argc, char **argv) ...@@ -135,7 +135,14 @@ int main(int argc, char **argv)
device_name = optarg; device_name = optarg;
break; break;
case 'o': case 'o':
lines[i] = strtoul(optarg, NULL, 10); /*
* Avoid overflow. Do not immediately error, we want to
* be able to accurately report on the amount of times
* '-o' was given to give an accurate error message
*/
if (i < GPIOHANDLES_MAX)
lines[i] = strtoul(optarg, NULL, 10);
i++; i++;
break; break;
case '?': case '?':
...@@ -143,6 +150,14 @@ int main(int argc, char **argv) ...@@ -143,6 +150,14 @@ int main(int argc, char **argv)
return -1; return -1;
} }
} }
if (i >= GPIOHANDLES_MAX) {
fprintf(stderr,
"Only %d occurrences of '-o' are allowed, %d were found\n",
GPIOHANDLES_MAX, i + 1);
return -1;
}
nlines = i; nlines = i;
if (!device_name || !nlines) { if (!device_name || !nlines) {
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include "gpio-utils.h" #include "gpio-utils.h"
#define COMSUMER "gpio-utils" #define CONSUMER "gpio-utils"
/** /**
* doc: Operation of gpio * doc: Operation of gpio
...@@ -209,7 +209,7 @@ int gpiotools_gets(const char *device_name, unsigned int *lines, ...@@ -209,7 +209,7 @@ int gpiotools_gets(const char *device_name, unsigned int *lines,
ret = gpiotools_request_linehandle(device_name, lines, nlines, ret = gpiotools_request_linehandle(device_name, lines, nlines,
GPIOHANDLE_REQUEST_INPUT, data, GPIOHANDLE_REQUEST_INPUT, data,
COMSUMER); CONSUMER);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -259,7 +259,7 @@ int gpiotools_sets(const char *device_name, unsigned int *lines, ...@@ -259,7 +259,7 @@ int gpiotools_sets(const char *device_name, unsigned int *lines,
ret = gpiotools_request_linehandle(device_name, lines, nlines, ret = gpiotools_request_linehandle(device_name, lines, nlines,
GPIOHANDLE_REQUEST_OUTPUT, data, GPIOHANDLE_REQUEST_OUTPUT, data,
COMSUMER); CONSUMER);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment