Commit bbfe0d6b authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'gpio-v5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio

Pull GPIO updates from Linus Walleij:
 "This is the bulk of changes in the GPIO subsystem for the v5.4 kernel
  cycle.

  Core changes:

   - Support hierarchical GPIO irqchips.

     We now have three consumers that can use this: Intel IXP4xx,
     ThunderX and Qualcomm SPMI GPIO (in the pinctrl subsystem).

     The support code has been long in the making and hashed out so it
     should be easily adaptable for all hierarchical irqchip parents.
     The code only gets compiled in if hierarchical irqchip is used at
     the topmost irq controller at least, as the hierarchical irqchip
     requires strict hierarchy all the way up in the system.

   - Determine the need for a "valid_mask" for GPIO lines on the
     gpio_chip and conversely for the "valid_mask" for the GPIO
     interrupt chip interrupt lines by looking for a .init_valid_mask()
     callback in the main chip or GPIO interrupt chip respectively.
     Allocate it with bitmap_alloc().

   - Isolate the device tree/open firmware GPIO description code out in
     its own file properly.

   - Isolate the ACPI GPIO description code out in its own file
     properly.

   - Drop a whole lot of #ifdef:s in the main includes: it does not hurt
     to keep the include items around, and we get quicker and clearer
     compile failures if the appropriate kernel symbols are not selected
     for drivers.

  New/deleted drivers:

   - New driver for Aspeed SGPIO.

   - The KS8695 driver is deleted as the platform gets deleted from
     arch/arm in this kernel cycle.

   - The Cirrus Logic Madera driver now supports CS47L92 and CS47L15.

   - The Freescale MPC8xxx now supports LS1028A and LS1088A.

  Driver improvements:

   - We pass the GPIO irqchip intialization by directly filling in the
     struct instead of using set-up functions (the new way) for Intel
     MID, Lynxpoint, Merrifield, XLP, HLWD, Aspeed, ZX, VF610, TQMX86,
     MT7621, Zynq and EP93xx.

  Out-of-band changes:

   - Fix a GPIO header inclusion in Unicore - no response from
     maintainer.

   - Drop FMC subsystem from MAINTAINERS - was deleted in the GPIO tree
     last cycle so let's mop up the shards"

* tag 'gpio-v5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (82 commits)
  gpiolib: of: add a fallback for wlf,reset GPIO name
  gpio: htc-egpio: Remove unused exported htc_egpio_get_wakeup_irq()
  gpio: remove explicit comparison with 0
  gpio: creg-snps: use devm_platform_ioremap_resource() to simplify code
  gpio: devres: Switch to EXPORT_SYMBOL_GPL()
  gpio: of: Switch to EXPORT_SYMBOL_GPL()
  gpio: of: Make of_gpio_simple_xlate() private
  gpio: of: Make of_get_named_gpiod_flags() private
  gpio: aspeed: Add in ast2600 details to Aspeed driver
  gpio: aspeed: Use ngpio property from device tree if available
  gpio: aspeed: Setup irqchip dynamically
  gpio/aspeed: Fix incorrect number of banks
  gpio: aspeed: Update documentation with ast2600 controllers
  gpio: Initialize the irqchip valid_mask with a callback
  gpiolib: acpi: make acpi_can_fallback_to_crs() static
  gpio: Fix further merge errors
  gpio: Fix up merge collision in include file
  gpio: of: Normalize return code variable name
  gpio: gpiolib: Normalize return code variable name
  gpio: ep93xx: Pass irqchip when adding gpiochip
  ...
parents 31dda85e 11c43bb0
...@@ -2,7 +2,8 @@ Aspeed GPIO controller Device Tree Bindings ...@@ -2,7 +2,8 @@ Aspeed GPIO controller Device Tree Bindings
------------------------------------------- -------------------------------------------
Required properties: Required properties:
- compatible : Either "aspeed,ast2400-gpio" or "aspeed,ast2500-gpio" - compatible : Either "aspeed,ast2400-gpio", "aspeed,ast2500-gpio",
or "aspeed,ast2600-gpio".
- #gpio-cells : Should be two - #gpio-cells : Should be two
- First cell is the GPIO line number - First cell is the GPIO line number
...@@ -18,6 +19,8 @@ Required properties: ...@@ -18,6 +19,8 @@ Required properties:
Optional properties: Optional properties:
- clocks : A phandle to the clock to use for debounce timings - clocks : A phandle to the clock to use for debounce timings
- ngpios : Number of GPIOs controlled by this controller. Should be set
when there are multiple GPIO controllers on a SoC (ast2600).
The gpio and interrupt properties are further described in their respective The gpio and interrupt properties are further described in their respective
bindings documentation: bindings documentation:
......
...@@ -6,6 +6,7 @@ Required Properties: ...@@ -6,6 +6,7 @@ Required Properties:
66AK2E SoCs 66AK2E SoCs
"ti,k2g-gpio", "ti,keystone-gpio": for 66AK2G "ti,k2g-gpio", "ti,keystone-gpio": for 66AK2G
"ti,am654-gpio", "ti,keystone-gpio": for TI K3 AM654 "ti,am654-gpio", "ti,keystone-gpio": for TI K3 AM654
"ti,j721e-gpio", "ti,keystone-gpio": for J721E SoCs
- reg: Physical base address of the controller and the size of memory mapped - reg: Physical base address of the controller and the size of memory mapped
registers. registers.
......
...@@ -4,7 +4,7 @@ Required properties: ...@@ -4,7 +4,7 @@ Required properties:
- compatible : Should be "fsl,<soc>-gpio" - compatible : Should be "fsl,<soc>-gpio"
The following <soc>s are known to be supported: The following <soc>s are known to be supported:
mpc5121, mpc5125, mpc8349, mpc8572, mpc8610, pq3, qoriq, mpc5121, mpc5125, mpc8349, mpc8572, mpc8610, pq3, qoriq,
ls1021a, ls1043a, ls2080a. ls1021a, ls1043a, ls2080a, ls1028a, ls1088a.
- reg : Address and length of the register set for the device - reg : Address and length of the register set for the device
- interrupts : Should be the port interrupt shared by all 32 pins. - interrupts : Should be the port interrupt shared by all 32 pins.
- #gpio-cells : Should be two. The first cell is the pin number and - #gpio-cells : Should be two. The first cell is the pin number and
...@@ -37,3 +37,17 @@ gpio0: gpio@2300000 { ...@@ -37,3 +37,17 @@ gpio0: gpio@2300000 {
interrupt-controller; interrupt-controller;
#interrupt-cells = <2>; #interrupt-cells = <2>;
}; };
Example of gpio-controller node for a ls1028a/ls1088a SoC:
gpio1: gpio@2300000 {
compatible = "fsl,ls1028a-gpio", "fsl,ls1088a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x2300000 0x0 0x10000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
little-endian;
};
Aspeed SGPIO controller Device Tree Bindings
--------------------------------------------
This SGPIO controller is for ASPEED AST2500 SoC, it supports up to 80 full
featured Serial GPIOs. Each of the Serial GPIO pins can be programmed to
support the following options:
- Support interrupt option for each input port and various interrupt
sensitivity option (level-high, level-low, edge-high, edge-low)
- Support reset tolerance option for each output port
- Directly connected to APB bus and its shift clock is from APB bus clock
divided by a programmable value.
- Co-work with external signal-chained TTL components (74LV165/74LV595)
Required properties:
- compatible : Should be one of
"aspeed,ast2400-sgpio", "aspeed,ast2500-sgpio"
- #gpio-cells : Should be 2, see gpio.txt
- reg : Address and length of the register set for the device
- gpio-controller : Marks the device node as a GPIO controller
- interrupts : Interrupt specifier, see interrupt-controller/interrupts.txt
- interrupt-controller : Mark the GPIO controller as an interrupt-controller
- ngpios : number of GPIO lines, see gpio.txt
(should be multiple of 8, up to 80 pins)
- clocks : A phandle to the APB clock for SGPM clock division
- bus-frequency : SGPM CLK frequency
The sgpio and interrupt properties are further described in their respective
bindings documentation:
- Documentation/devicetree/bindings/gpio/gpio.txt
- Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
Example:
sgpio: sgpio@1e780200 {
#gpio-cells = <2>;
compatible = "aspeed,ast2500-sgpio";
gpio-controller;
interrupts = <40>;
reg = <0x1e780200 0x0100>;
clocks = <&syscon ASPEED_CLK_APB>;
interrupt-controller;
ngpios = <8>;
bus-frequency = <12000000>;
};
...@@ -69,9 +69,9 @@ driver code: ...@@ -69,9 +69,9 @@ driver code:
The code implementing a gpio_chip should support multiple instances of the The code implementing a gpio_chip should support multiple instances of the
controller, preferably using the driver model. That code will configure each controller, preferably using the driver model. That code will configure each
gpio_chip and issue ``gpiochip_add[_data]()`` or ``devm_gpiochip_add_data()``. gpio_chip and issue gpiochip_add(), gpiochip_add_data(), or
Removing a GPIO controller should be rare; use ``[devm_]gpiochip_remove()`` devm_gpiochip_add_data(). Removing a GPIO controller should be rare; use
when it is unavoidable. gpiochip_remove() when it is unavoidable.
Often a gpio_chip is part of an instance-specific structure with states not Often a gpio_chip is part of an instance-specific structure with states not
exposed by the GPIO interfaces, such as addressing, power management, and more. exposed by the GPIO interfaces, such as addressing, power management, and more.
...@@ -259,7 +259,7 @@ most often cascaded off a parent interrupt controller, and in some special ...@@ -259,7 +259,7 @@ most often cascaded off a parent interrupt controller, and in some special
cases the GPIO logic is melded with a SoC's primary interrupt controller. cases the GPIO logic is melded with a SoC's primary interrupt controller.
The IRQ portions of the GPIO block are implemented using an irq_chip, using The IRQ portions of the GPIO block are implemented using an irq_chip, using
the header <linux/irq.h>. So basically such a driver is utilizing two sub- the header <linux/irq.h>. So this combined driver is utilizing two sub-
systems simultaneously: gpio and irq. systems simultaneously: gpio and irq.
It is legal for any IRQ consumer to request an IRQ from any irqchip even if it It is legal for any IRQ consumer to request an IRQ from any irqchip even if it
...@@ -391,25 +391,119 @@ Infrastructure helpers for GPIO irqchips ...@@ -391,25 +391,119 @@ Infrastructure helpers for GPIO irqchips
---------------------------------------- ----------------------------------------
To help out in handling the set-up and management of GPIO irqchips and the To help out in handling the set-up and management of GPIO irqchips and the
associated irqdomain and resource allocation callbacks, the gpiolib has associated irqdomain and resource allocation callbacks. These are activated
some helpers that can be enabled by selecting the GPIOLIB_IRQCHIP Kconfig by selecting the Kconfig symbol GPIOLIB_IRQCHIP. If the symbol
symbol: IRQ_DOMAIN_HIERARCHY is also selected, hierarchical helpers will also be
provided. A big portion of overhead code will be managed by gpiolib,
- gpiochip_irqchip_add(): adds a chained cascaded irqchip to a gpiochip. It under the assumption that your interrupts are 1-to-1-mapped to the
will pass the struct gpio_chip* for the chip to all IRQ callbacks, so the GPIO line index:
callbacks need to embed the gpio_chip in its state container and obtain a
pointer to the container using container_of(). GPIO line offset Hardware IRQ
(See Documentation/driver-api/driver-model/design-patterns.rst) 0 0
1 1
2 2
... ...
ngpio-1 ngpio-1
If some GPIO lines do not have corresponding IRQs, the bitmask valid_mask
and the flag need_valid_mask in gpio_irq_chip can be used to mask off some
lines as invalid for associating with IRQs.
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.
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
is a typical example of a cascaded interrupt handler using gpio_irq_chip:
/* Typical state container with dynamic irqchip */
struct my_gpio {
struct gpio_chip gc;
struct irq_chip irq;
};
int irq; /* from platform etc */
struct my_gpio *g;
struct gpio_irq_chip *girq;
/* Set up the irqchip dynamically */
g->irq.name = "my_gpio_irq";
g->irq.irq_ack = my_gpio_ack_irq;
g->irq.irq_mask = my_gpio_mask_irq;
g->irq.irq_unmask = my_gpio_unmask_irq;
g->irq.irq_set_type = my_gpio_set_irq_type;
/* Get a pointer to the gpio_irq_chip */
girq = &g->gc.irq;
girq->chip = &g->irq;
girq->parent_handler = ftgpio_gpio_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_bad_irq;
girq->parents[0] = irq;
return devm_gpiochip_add_data(dev, &g->gc, g);
The helper support using hierarchical interrupt controllers as well.
In this case the typical set-up will look like this:
/* Typical state container with dynamic irqchip */
struct my_gpio {
struct gpio_chip gc;
struct irq_chip irq;
struct fwnode_handle *fwnode;
};
int irq; /* from platform etc */
struct my_gpio *g;
struct gpio_irq_chip *girq;
/* Set up the irqchip dynamically */
g->irq.name = "my_gpio_irq";
g->irq.irq_ack = my_gpio_ack_irq;
g->irq.irq_mask = my_gpio_mask_irq;
g->irq.irq_unmask = my_gpio_unmask_irq;
g->irq.irq_set_type = my_gpio_set_irq_type;
/* Get a pointer to the gpio_irq_chip */
girq = &g->gc.irq;
girq->chip = &g->irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_bad_irq;
girq->fwnode = g->fwnode;
girq->parent_domain = parent;
girq->child_to_parent_hwirq = my_gpio_child_to_parent_hwirq;
return devm_gpiochip_add_data(dev, &g->gc, g);
As you can see pretty similar, but you do not supply a parent handler for
the IRQ, instead a parent irqdomain, an fwnode for the hardware and
a funcion .child_to_parent_hwirq() that has the purpose of looking up
the parent hardware irq from a child (i.e. this gpio chip) hardware irq.
As always it is good to look at examples in the kernel tree for advice
on how to find the required pieces.
The old way of adding irqchips to gpiochips after registration is also still
available but we try to move away from this:
- DEPRECATED: gpiochip_irqchip_add(): adds a chained cascaded irqchip to a
gpiochip. It will pass the struct gpio_chip* for the chip to all IRQ
callbacks, so the callbacks need to embed the gpio_chip in its state
container and obtain a pointer to the container using container_of().
(See Documentation/driver-model/design-patterns.txt)
- gpiochip_irqchip_add_nested(): adds a nested cascaded irqchip to a gpiochip, - gpiochip_irqchip_add_nested(): adds a nested cascaded irqchip to a gpiochip,
as discussed above regarding different types of cascaded irqchips. The as discussed above regarding different types of cascaded irqchips. The
cascaded irq has to be handled by a threaded interrupt handler. cascaded irq has to be handled by a threaded interrupt handler.
Apart from that it works exactly like the chained irqchip. Apart from that it works exactly like the chained irqchip.
- gpiochip_set_chained_irqchip(): sets up a chained cascaded irq handler for a - DEPRECATED: gpiochip_set_chained_irqchip(): sets up a chained cascaded irq
gpio_chip from a parent IRQ and passes the struct gpio_chip* as handler handler for a gpio_chip from a parent IRQ and passes the struct gpio_chip*
data. Notice that we pass is as the handler data, since the irqchip data is as handler data. Notice that we pass is as the handler data, since the
likely used by the parent irqchip. irqchip data is likely used by the parent irqchip.
- gpiochip_set_nested_irqchip(): sets up a nested cascaded irq handler for a - gpiochip_set_nested_irqchip(): sets up a nested cascaded irq handler for a
gpio_chip from a parent IRQ. As the parent IRQ has usually been gpio_chip from a parent IRQ. As the parent IRQ has usually been
...@@ -418,11 +512,11 @@ symbol: ...@@ -418,11 +512,11 @@ symbol:
If there is a need to exclude certain GPIO lines from the IRQ domain handled by If there is a need to exclude certain GPIO lines from the IRQ domain handled by
these helpers, we can set .irq.need_valid_mask of the gpiochip before these helpers, we can set .irq.need_valid_mask of the gpiochip before
``[devm_]gpiochip_add_data()`` is called. This allocates an .irq.valid_mask with as devm_gpiochip_add_data() or gpiochip_add_data() is called. This allocates an
many bits set as there are GPIO lines in the chip, each bit representing line .irq.valid_mask with as many bits set as there are GPIO lines in the chip, each
0..n-1. Drivers can exclude GPIO lines by clearing bits from this mask. The mask bit representing line 0..n-1. Drivers can exclude GPIO lines by clearing bits
must be filled in before gpiochip_irqchip_add() or gpiochip_irqchip_add_nested() from this mask. The mask must be filled in before gpiochip_irqchip_add() or
is called. gpiochip_irqchip_add_nested() is called.
To use the helpers please keep the following in mind: To use the helpers please keep the following in mind:
......
...@@ -6329,15 +6329,6 @@ S: Odd Fixes ...@@ -6329,15 +6329,6 @@ S: Odd Fixes
L: linux-block@vger.kernel.org L: linux-block@vger.kernel.org
F: drivers/block/floppy.c F: drivers/block/floppy.c
FMC SUBSYSTEM
M: Alessandro Rubini <rubini@gnudd.com>
W: http://www.ohwr.org/projects/fmc-bus
S: Supported
F: drivers/fmc/
F: include/linux/fmc*.h
F: include/linux/ipmi-fru.h
K: fmc_d.*register
FPGA MANAGER FRAMEWORK FPGA MANAGER FRAMEWORK
M: Moritz Fischer <mdf@kernel.org> M: Moritz Fischer <mdf@kernel.org>
L: linux-fpga@vger.kernel.org L: linux-fpga@vger.kernel.org
...@@ -8383,12 +8374,6 @@ F: Documentation/x86/intel_txt.rst ...@@ -8383,12 +8374,6 @@ F: Documentation/x86/intel_txt.rst
F: include/linux/tboot.h F: include/linux/tboot.h
F: arch/x86/kernel/tboot.c F: arch/x86/kernel/tboot.c
INTEL-MID GPIO DRIVER
M: David Cohen <david.a.cohen@linux.intel.com>
L: linux-gpio@vger.kernel.org
S: Maintained
F: drivers/gpio/gpio-intel-mid.c
INTERCONNECT API INTERCONNECT API
M: Georgi Djakov <georgi.djakov@linaro.org> M: Georgi Djakov <georgi.djakov@linaro.org>
L: linux-pm@vger.kernel.org L: linux-pm@vger.kernel.org
......
...@@ -93,6 +93,7 @@ CONFIG_SERIAL_HS_LPC32XX_CONSOLE=y ...@@ -93,6 +93,7 @@ CONFIG_SERIAL_HS_LPC32XX_CONSOLE=y
# CONFIG_HW_RANDOM is not set # CONFIG_HW_RANDOM is not set
CONFIG_I2C_CHARDEV=y CONFIG_I2C_CHARDEV=y
CONFIG_I2C_PNX=y CONFIG_I2C_PNX=y
CONFIG_GPIO_LPC32XX=y
CONFIG_SPI=y CONFIG_SPI=y
CONFIG_SPI_PL022=y CONFIG_SPI_PL022=y
CONFIG_GPIO_SYSFS=y CONFIG_GPIO_SYSFS=y
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <linux/kallsyms.h> #include <linux/kallsyms.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/syscore_ops.h> #include <linux/syscore_ops.h>
#include <linux/gpio.h>
#include <mach/hardware.h> #include <mach/hardware.h>
......
...@@ -288,7 +288,7 @@ config GPIO_IXP4XX ...@@ -288,7 +288,7 @@ config GPIO_IXP4XX
depends on ARM # For <asm/mach-types.h> depends on ARM # For <asm/mach-types.h>
depends on ARCH_IXP4XX depends on ARCH_IXP4XX
select GPIO_GENERIC select GPIO_GENERIC
select IRQ_DOMAIN select GPIOLIB_IRQCHIP
select IRQ_DOMAIN_HIERARCHY select IRQ_DOMAIN_HIERARCHY
help help
Say yes here to support the GPIO functionality of a number of Intel Say yes here to support the GPIO functionality of a number of Intel
...@@ -311,6 +311,13 @@ config GPIO_LPC18XX ...@@ -311,6 +311,13 @@ config GPIO_LPC18XX
Select this option to enable GPIO driver for Select this option to enable GPIO driver for
NXP LPC18XX/43XX devices. NXP LPC18XX/43XX devices.
config GPIO_LPC32XX
tristate "NXP LPC32XX GPIO support"
depends on OF_GPIO && (ARCH_LPC32XX || COMPILE_TEST)
help
Select this option to enable GPIO driver for
NXP LPC32XX devices.
config GPIO_LYNXPOINT config GPIO_LYNXPOINT
tristate "Intel Lynxpoint GPIO support" tristate "Intel Lynxpoint GPIO support"
depends on ACPI && X86 depends on ACPI && X86
...@@ -539,6 +546,7 @@ config GPIO_THUNDERX ...@@ -539,6 +546,7 @@ config GPIO_THUNDERX
tristate "Cavium ThunderX/OCTEON-TX GPIO" tristate "Cavium ThunderX/OCTEON-TX GPIO"
depends on ARCH_THUNDER || (64BIT && COMPILE_TEST) depends on ARCH_THUNDER || (64BIT && COMPILE_TEST)
depends on PCI_MSI depends on PCI_MSI
select GPIOLIB_IRQCHIP
select IRQ_DOMAIN_HIERARCHY select IRQ_DOMAIN_HIERARCHY
select IRQ_FASTEOI_HIERARCHY_HANDLERS select IRQ_FASTEOI_HIERARCHY_HANDLERS
help help
...@@ -1465,7 +1473,6 @@ endmenu ...@@ -1465,7 +1473,6 @@ endmenu
config GPIO_MOCKUP config GPIO_MOCKUP
tristate "GPIO Testing Driver" tristate "GPIO Testing Driver"
depends on GPIOLIB
select IRQ_SIM select IRQ_SIM
help help
This enables GPIO Testing driver, which provides a way to test GPIO This enables GPIO Testing driver, which provides a way to test GPIO
......
...@@ -67,14 +67,13 @@ obj-$(CONFIG_GPIO_IT87) += gpio-it87.o ...@@ -67,14 +67,13 @@ obj-$(CONFIG_GPIO_IT87) += gpio-it87.o
obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o
obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o
obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o
obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o
obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o
obj-$(CONFIG_GPIO_LP3943) += gpio-lp3943.o obj-$(CONFIG_GPIO_LP3943) += gpio-lp3943.o
obj-$(CONFIG_GPIO_LP873X) += gpio-lp873x.o obj-$(CONFIG_GPIO_LP873X) += gpio-lp873x.o
obj-$(CONFIG_GPIO_LP87565) += gpio-lp87565.o obj-$(CONFIG_GPIO_LP87565) += gpio-lp87565.o
obj-$(CONFIG_GPIO_LPC18XX) += gpio-lpc18xx.o obj-$(CONFIG_GPIO_LPC18XX) += gpio-lpc18xx.o
obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o obj-$(CONFIG_GPIO_LPC32XX) += gpio-lpc32xx.o
obj-$(CONFIG_GPIO_LYNXPOINT) += gpio-lynxpoint.o obj-$(CONFIG_GPIO_LYNXPOINT) += gpio-lynxpoint.o
obj-$(CONFIG_GPIO_MADERA) += gpio-madera.o obj-$(CONFIG_GPIO_MADERA) += gpio-madera.o
obj-$(CONFIG_GPIO_MAX3191X) += gpio-max3191x.o obj-$(CONFIG_GPIO_MAX3191X) += gpio-max3191x.o
......
...@@ -142,7 +142,7 @@ static const struct gpio_chip template_chip = { ...@@ -142,7 +142,7 @@ static const struct gpio_chip template_chip = {
static int arizona_gpio_probe(struct platform_device *pdev) static int arizona_gpio_probe(struct platform_device *pdev)
{ {
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
struct arizona_pdata *pdata = dev_get_platdata(arizona->dev); struct arizona_pdata *pdata = &arizona->pdata;
struct arizona_gpio *arizona_gpio; struct arizona_gpio *arizona_gpio;
int ret; int ret;
...@@ -177,7 +177,7 @@ static int arizona_gpio_probe(struct platform_device *pdev) ...@@ -177,7 +177,7 @@ static int arizona_gpio_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
if (pdata && pdata->gpio_base) if (pdata->gpio_base)
arizona_gpio->gpio_chip.base = pdata->gpio_base; arizona_gpio->gpio_chip.base = pdata->gpio_base;
else else
arizona_gpio->gpio_chip.base = -1; arizona_gpio->gpio_chip.base = -1;
......
...@@ -52,6 +52,7 @@ struct aspeed_gpio_config { ...@@ -52,6 +52,7 @@ struct aspeed_gpio_config {
*/ */
struct aspeed_gpio { struct aspeed_gpio {
struct gpio_chip chip; struct gpio_chip chip;
struct irq_chip irqc;
spinlock_t lock; spinlock_t lock;
void __iomem *base; void __iomem *base;
int irq; int irq;
...@@ -661,12 +662,14 @@ static void aspeed_gpio_irq_handler(struct irq_desc *desc) ...@@ -661,12 +662,14 @@ static void aspeed_gpio_irq_handler(struct irq_desc *desc)
struct gpio_chip *gc = irq_desc_get_handler_data(desc); struct gpio_chip *gc = irq_desc_get_handler_data(desc);
struct irq_chip *ic = irq_desc_get_chip(desc); struct irq_chip *ic = irq_desc_get_chip(desc);
struct aspeed_gpio *data = gpiochip_get_data(gc); struct aspeed_gpio *data = gpiochip_get_data(gc);
unsigned int i, p, girq; unsigned int i, p, girq, banks;
unsigned long reg; unsigned long reg;
struct aspeed_gpio *gpio = gpiochip_get_data(gc);
chained_irq_enter(ic, desc); chained_irq_enter(ic, desc);
for (i = 0; i < ARRAY_SIZE(aspeed_gpio_banks); i++) { banks = DIV_ROUND_UP(gpio->chip.ngpio, 32);
for (i = 0; i < banks; i++) {
const struct aspeed_gpio_bank *bank = &aspeed_gpio_banks[i]; const struct aspeed_gpio_bank *bank = &aspeed_gpio_banks[i];
reg = ioread32(bank_reg(data, bank, reg_irq_status)); reg = ioread32(bank_reg(data, bank, reg_irq_status));
...@@ -681,16 +684,11 @@ static void aspeed_gpio_irq_handler(struct irq_desc *desc) ...@@ -681,16 +684,11 @@ static void aspeed_gpio_irq_handler(struct irq_desc *desc)
chained_irq_exit(ic, desc); chained_irq_exit(ic, desc);
} }
static struct irq_chip aspeed_gpio_irqchip = { static void aspeed_init_irq_valid_mask(struct gpio_chip *gc,
.name = "aspeed-gpio", unsigned long *valid_mask,
.irq_ack = aspeed_gpio_irq_ack, unsigned int ngpios)
.irq_mask = aspeed_gpio_irq_mask,
.irq_unmask = aspeed_gpio_irq_unmask,
.irq_set_type = aspeed_gpio_set_type,
};
static void set_irq_valid_mask(struct aspeed_gpio *gpio)
{ {
struct aspeed_gpio *gpio = gpiochip_get_data(gc);
const struct aspeed_bank_props *props = gpio->config->props; const struct aspeed_bank_props *props = gpio->config->props;
while (!is_bank_props_sentinel(props)) { while (!is_bank_props_sentinel(props)) {
...@@ -701,42 +699,16 @@ static void set_irq_valid_mask(struct aspeed_gpio *gpio) ...@@ -701,42 +699,16 @@ static void set_irq_valid_mask(struct aspeed_gpio *gpio)
for_each_clear_bit(offset, &input, 32) { for_each_clear_bit(offset, &input, 32) {
unsigned int i = props->bank * 32 + offset; unsigned int i = props->bank * 32 + offset;
if (i >= gpio->config->nr_gpios) if (i >= gpio->chip.ngpio)
break; break;
clear_bit(i, gpio->chip.irq.valid_mask); clear_bit(i, valid_mask);
} }
props++; props++;
} }
} }
static int aspeed_gpio_setup_irqs(struct aspeed_gpio *gpio,
struct platform_device *pdev)
{
int rc;
rc = platform_get_irq(pdev, 0);
if (rc < 0)
return rc;
gpio->irq = rc;
set_irq_valid_mask(gpio);
rc = gpiochip_irqchip_add(&gpio->chip, &aspeed_gpio_irqchip,
0, handle_bad_irq, IRQ_TYPE_NONE);
if (rc) {
dev_info(&pdev->dev, "Could not add irqchip\n");
return rc;
}
gpiochip_set_chained_irqchip(&gpio->chip, &aspeed_gpio_irqchip,
gpio->irq, aspeed_gpio_irq_handler);
return 0;
}
static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip, static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
unsigned int offset, bool enable) unsigned int offset, bool enable)
{ {
...@@ -1040,10 +1012,10 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc, ...@@ -1040,10 +1012,10 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
unsigned long flags; unsigned long flags;
if (!gpio->cf_copro_bankmap) if (!gpio->cf_copro_bankmap)
gpio->cf_copro_bankmap = kzalloc(gpio->config->nr_gpios >> 3, GFP_KERNEL); gpio->cf_copro_bankmap = kzalloc(gpio->chip.ngpio >> 3, GFP_KERNEL);
if (!gpio->cf_copro_bankmap) if (!gpio->cf_copro_bankmap)
return -ENOMEM; return -ENOMEM;
if (offset < 0 || offset > gpio->config->nr_gpios)