summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt9
-rw-r--r--drivers/gpio/gpio-dwapb.c46
-rw-r--r--drivers/mfd/intel_quark_i2c_gpio.c3
-rw-r--r--include/linux/platform_data/gpio-dwapb.h3
4 files changed, 48 insertions, 13 deletions
diff --git a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
index 4a75da7051bd..3c1118bc67f5 100644
--- a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
@@ -26,8 +26,13 @@ controller.
the second encodes the triger flags encoded as described in
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
- interrupt-parent : The parent interrupt controller.
-- interrupts : The interrupt to the parent controller raised when GPIOs
- generate the interrupts.
+- interrupts : The interrupts to the parent controller raised when GPIOs
+ generate the interrupts. If the controller provides one combined interrupt
+ for all GPIOs, specify a single interrupt. If the controller provides one
+ interrupt for each GPIO, provide a list of interrupts that correspond to each
+ of the GPIO pins. When specifying multiple interrupts, if any are unconnected,
+ use the interrupts-extended property to specify the interrupts and set the
+ interrupt controller handle for unused interrupts to 0.
- snps,nr-gpios : The number of pins in the port, a single cell.
- resets : Reset line for the controller.
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index 226977f78482..7dcd06b11570 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -441,14 +441,19 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
irq_gc->chip_types[1].handler = handle_edge_irq;
if (!pp->irq_shared) {
- irq_set_chained_handler_and_data(pp->irq, dwapb_irq_handler,
- gpio);
+ int i;
+
+ for (i = 0; i < pp->ngpio; i++) {
+ if (pp->irq[i])
+ irq_set_chained_handler_and_data(pp->irq[i],
+ dwapb_irq_handler, gpio);
+ }
} else {
/*
* Request a shared IRQ since where MFD would have devices
* using the same irq pin
*/
- err = devm_request_irq(gpio->dev, pp->irq,
+ err = devm_request_irq(gpio->dev, pp->irq[0],
dwapb_irq_handler_mfd,
IRQF_SHARED, "gpio-dwapb-mfd", gpio);
if (err) {
@@ -524,7 +529,7 @@ static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
if (pp->idx == 0)
port->gc.set_config = dwapb_gpio_set_config;
- if (pp->irq)
+ if (pp->has_irq)
dwapb_configure_irqs(gpio, port, pp);
err = gpiochip_add_data(&port->gc, port);
@@ -535,7 +540,7 @@ static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
port->is_registered = true;
/* Add GPIO-signaled ACPI event support */
- if (pp->irq)
+ if (pp->has_irq)
acpi_gpiochip_request_interrupts(&port->gc);
return err;
@@ -601,13 +606,36 @@ dwapb_gpio_get_pdata(struct device *dev)
if (dev->of_node && pp->idx == 0 &&
fwnode_property_read_bool(fwnode,
"interrupt-controller")) {
- pp->irq = irq_of_parse_and_map(to_of_node(fwnode), 0);
- if (!pp->irq)
+ struct device_node *np = to_of_node(fwnode);
+ unsigned int j;
+
+ /*
+ * The IP has configuration options to allow a single
+ * combined interrupt or one per gpio. If one per gpio,
+ * some might not be used.
+ */
+ for (j = 0; j < pp->ngpio; j++) {
+ int irq = of_irq_get(np, j);
+ if (irq < 0)
+ continue;
+
+ pp->irq[j] = irq;
+ pp->has_irq = true;
+ }
+
+ if (!pp->has_irq)
dev_warn(dev, "no irq for port%d\n", pp->idx);
}
- if (has_acpi_companion(dev) && pp->idx == 0)
- pp->irq = platform_get_irq(to_platform_device(dev), 0);
+ if (has_acpi_companion(dev) && pp->idx == 0) {
+ unsigned int j;
+
+ for (j = 0; j < pp->ngpio; j++) {
+ pp->irq[j] = platform_get_irq(to_platform_device(dev), j);
+ if (pp->irq[j])
+ pp->has_irq = true;
+ }
+ }
pp->irq_shared = false;
pp->gpio_base = -1;
diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
index 90e35dec8648..5bddb84cfc1f 100644
--- a/drivers/mfd/intel_quark_i2c_gpio.c
+++ b/drivers/mfd/intel_quark_i2c_gpio.c
@@ -233,7 +233,8 @@ static int intel_quark_gpio_setup(struct pci_dev *pdev, struct mfd_cell *cell)
pdata->properties->idx = 0;
pdata->properties->ngpio = INTEL_QUARK_MFD_NGPIO;
pdata->properties->gpio_base = INTEL_QUARK_MFD_GPIO_BASE;
- pdata->properties->irq = pdev->irq;
+ pdata->properties->irq[0] = pdev->irq;
+ pdata->properties->has_irq = true;
pdata->properties->irq_shared = true;
cell->platform_data = pdata;
diff --git a/include/linux/platform_data/gpio-dwapb.h b/include/linux/platform_data/gpio-dwapb.h
index 2dc7f4a8ab09..5a52d69c13f3 100644
--- a/include/linux/platform_data/gpio-dwapb.h
+++ b/include/linux/platform_data/gpio-dwapb.h
@@ -19,7 +19,8 @@ struct dwapb_port_property {
unsigned int idx;
unsigned int ngpio;
unsigned int gpio_base;
- unsigned int irq;
+ unsigned int irq[32];
+ bool has_irq;
bool irq_shared;
};