Commit 8e509660 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull GPIO tree bulk changes from Linus Walleij:
 "A big set this merge window, as we have much going on in this
  subsystem.  The changes to other subsystems (notably a slew of ARM
  machines as I am doing away with their custom APIs) have all been
  ACKed to the extent possible.

  Major changes this time:

   - Some core improvements and cleanups to the new GPIO descriptor API.
     This seems to be working now so we can start the exodus to this
     API, moving gradually away from the global GPIO numberspace.

   - Incremental improvements to the ACPI GPIO core, and move the few
     GPIO ACPI clients we have to the GPIO descriptor API right *now*
     before we go any further.  We actually managed to contain this
     *before* we started to litter the kernel with yet another hackish
     global numberspace for the ACPI GPIOs, which is a big win.

   - The RFkill GPIO driver and all platforms using it have been
     migrated to use the GPIO descriptors rather than fixed number
     assignments.  Tegra machine has been migrated as part of this.

   - New drivers for MOXA ART, Xtensa GPIO32 and SMSC SCH311x.  Those
     should be really good examples of how I expect a nice GPIO driver
     to look these days.

   - Do away with custom GPIO implementations on a major part of the ARM
     machines: ks8695, lpc32xx, mv78xx0.  Make a first step towards the
     same in the horribly convoluted Samsung S3C include forest.  We
     expect to continue to clean this up as we move forward.

   - Flag GPIO lines used for IRQ on adnp, bcm-kona, em, intel-mid and
     lynxpoint.

     This makes the GPIOlib core aware that a certain GPIO line is used
     for IRQs and can then enforce some semantics such as disallowing a
     GPIO line marked as in use for IRQ to be switched to output mode.

   - Drop all use of irq_set_chip_and_handler_name().  The name provided
     in these cases were just unhelpful tags like "mux" or "demux".

   - Extend the MCP23s08 driver to handle interrupts.

   - Minor incremental improvements for rcar, lynxpoint, em 74x164 and
     msm drivers.

   - Some non-urgent bug fixes here and there, duplicate #includes and
     that usual kind of cleanups"

Fix up broken Kconfig file manually to make this all compile.

* tag 'gpio-v3.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (71 commits)
  gpio: mcp23s08: fix casting caused build warning
  gpio: mcp23s08: depend on OF_GPIO
  gpio: mcp23s08: Add irq functionality for i2c chips
  ARM: S5P[v210|c100|64x0]: Fix build error
  gpio: pxa: clamp gpio get value to [0,1]
  ARM: s3c24xx: explicit dependency on <plat/gpio-cfg.h>
  ARM: S3C[24|64]xx: move includes back under <mach/> scope
  Documentation / ACPI: update to GPIO descriptor API
  gpio / ACPI: get rid of acpi_gpio.h
  gpio / ACPI: register to ACPI events automatically
  mmc: sdhci-acpi: convert to use GPIO descriptor API
  ARM: s3c24xx: fix build error
  gpio: f7188x: set can_sleep attribute
  gpio: samsung: Update documentation
  gpio: samsung: Remove hardware.h inclusion
  gpio: xtensa: depend on HAVE_XTENSA_GPIO32
  gpio: clps711x: Enable driver compilation with COMPILE_TEST
  gpio: clps711x: Use of_match_ptr()
  net: rfkill: gpio: convert to descriptor-based GPIO interface
  leds: s3c24xx: Fix build failure
  ...
parents 02d0a752 de755c33
...@@ -293,36 +293,13 @@ the device to the driver. For example: ...@@ -293,36 +293,13 @@ the device to the driver. For example:
These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0" These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0"
specifies the path to the controller. In order to use these GPIOs in Linux specifies the path to the controller. In order to use these GPIOs in Linux
we need to translate them to the Linux GPIO numbers. we need to translate them to the corresponding Linux GPIO descriptors.
In a simple case of just getting the Linux GPIO number from device There is a standard GPIO API for that and is documented in
resources one can use acpi_get_gpio_by_index() helper function. It takes Documentation/gpio.txt.
pointer to the device and index of the GpioIo/GpioInt descriptor in the
device resources list. For example:
int gpio_irq, gpio_power; In the above example we can get the corresponding two GPIO descriptors with
int ret; a code like this:
gpio_irq = acpi_get_gpio_by_index(dev, 1, NULL);
if (gpio_irq < 0)
/* handle error */
gpio_power = acpi_get_gpio_by_index(dev, 0, NULL);
if (gpio_power < 0)
/* handle error */
/* Now we can use the GPIO numbers */
Other GpioIo parameters must be converted first by the driver to be
suitable to the gpiolib before passing them.
In case of GpioInt resource an additional call to gpio_to_irq() must be
done before calling request_irq().
Note that the above API is ACPI specific and not recommended for drivers
that need to support non-ACPI systems. The recommended way is to use
the descriptor based GPIO interfaces. The above example looks like this
when converted to the GPIO desc:
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
... ...
...@@ -339,4 +316,5 @@ when converted to the GPIO desc: ...@@ -339,4 +316,5 @@ when converted to the GPIO desc:
/* Now we can use the GPIO descriptors */ /* Now we can use the GPIO descriptors */
See also Documentation/gpio.txt. There are also devm_* versions of these functions which release the
descriptors once the device is released.
...@@ -85,21 +85,10 @@ between the calls. ...@@ -85,21 +85,10 @@ between the calls.
Headers Headers
------- -------
See arch/arm/mach-s3c2410/include/mach/regs-gpio.h for the list See arch/arm/mach-s3c24xx/include/mach/regs-gpio.h for the list
of GPIO pins, and the configuration values for them. This of GPIO pins, and the configuration values for them. This
is included by using #include <mach/regs-gpio.h> is included by using #include <mach/regs-gpio.h>
The GPIO management functions are defined in the hardware
header arch/arm/mach-s3c2410/include/mach/hardware.h which can be
included by #include <mach/hardware.h>
A useful amount of documentation can be found in the hardware
header on how the GPIO functions (and others) work.
Whilst a number of these functions do make some checks on what
is passed to them, for speed of use, they may not always ensure
that the user supplied data to them is correct.
PIN Numbers PIN Numbers
----------- -----------
......
...@@ -38,12 +38,38 @@ Required device specific properties (only for SPI chips): ...@@ -38,12 +38,38 @@ Required device specific properties (only for SPI chips):
removed. removed.
- spi-max-frequency = The maximum frequency this chip is able to handle - spi-max-frequency = The maximum frequency this chip is able to handle
Example I2C: Optional properties:
- #interrupt-cells : Should be two.
- first cell is the pin number
- second cell is used to specify flags.
- interrupt-controller: Marks the device node as a interrupt controller.
NOTE: The interrupt functionality is only supported for i2c versions of the
chips. The spi chips can also do the interrupts, but this is not supported by
the linux driver yet.
Optional device specific properties:
- microchip,irq-mirror: Sets the mirror flag in the IOCON register. Devices
with two interrupt outputs (these are the devices ending with 17 and
those that have 16 IOs) have two IO banks: IO 0-7 form bank 1 and
IO 8-15 are bank 2. These chips have two different interrupt outputs:
One for bank 1 and another for bank 2. If irq-mirror is set, both
interrupts are generated regardless of the bank that an input change
occured on. If it is not set, the interrupt are only generated for the
bank they belong to.
On devices with only one interrupt output this property is useless.
Example I2C (with interrupt):
gpiom1: gpio@20 { gpiom1: gpio@20 {
compatible = "microchip,mcp23017"; compatible = "microchip,mcp23017";
gpio-controller; gpio-controller;
#gpio-cells = <2>; #gpio-cells = <2>;
reg = <0x20>; reg = <0x20>;
interrupt-parent = <&gpio1>;
interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells=<2>;
microchip,irq-mirror;
}; };
Example SPI: Example SPI:
......
MOXA ART GPIO Controller
Required properties:
- #gpio-cells : Should be 2, The first cell is the pin number,
the second cell is used to specify polarity:
0 = active high
1 = active low
- compatible : Must be "moxa,moxart-gpio"
- reg : Should contain registers location and length
Example:
gpio: gpio@98700000 {
gpio-controller;
#gpio-cells = <2>;
compatible = "moxa,moxart-gpio";
reg = <0x98700000 0xC>;
};
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
Required Properties: Required Properties:
- compatible: should be one of the following. - compatible: should contain one of the following.
- "renesas,gpio-r8a7778": for R8A7778 (R-Mobile M1) compatible GPIO controller. - "renesas,gpio-r8a7778": for R8A7778 (R-Mobile M1) compatible GPIO controller.
- "renesas,gpio-r8a7779": for R8A7779 (R-Car H1) compatible GPIO controller. - "renesas,gpio-r8a7779": for R8A7779 (R-Car H1) compatible GPIO controller.
- "renesas,gpio-r8a7790": for R8A7790 (R-Car H2) compatible GPIO controller. - "renesas,gpio-r8a7790": for R8A7790 (R-Car H2) compatible GPIO controller.
- "renesas,gpio-r8a7791": for R8A7791 (R-Car M2) compatible GPIO controller.
- "renesas,gpio-rcar": for generic R-Car GPIO controller. - "renesas,gpio-rcar": for generic R-Car GPIO controller.
- reg: Base address and length of each memory resource used by the GPIO - reg: Base address and length of each memory resource used by the GPIO
......
...@@ -72,10 +72,11 @@ where ...@@ -72,10 +72,11 @@ where
- chip_label is the label of the gpiod_chip instance providing the GPIO - 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 - 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. If - dev_id is the identifier of the device that will make use of this GPIO. It
NULL, the GPIO will be available to all devices. 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 - con_id is the name of the GPIO function from the device point of view. It
can be NULL. can be NULL, in which case it will match any function.
- idx is the index of the GPIO within the function. - idx is the index of the GPIO within the function.
- flags is defined to specify the following properties: - flags is defined to specify the following properties:
* GPIOF_ACTIVE_LOW - to configure the GPIO as active-low * GPIOF_ACTIVE_LOW - to configure the GPIO as active-low
...@@ -86,18 +87,23 @@ In the future, these flags might be extended to support more properties. ...@@ -86,18 +87,23 @@ 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. Note that GPIO_LOOKUP() is just a shortcut to GPIO_LOOKUP_IDX() where idx = 0.
A lookup table can then be defined as follows: A lookup table can then be defined as follows, with an empty entry defining its
end:
struct gpiod_lookup gpios_table[] = { struct gpiod_lookup_table gpios_table = {
GPIO_LOOKUP_IDX("gpio.0", 15, "foo.0", "led", 0, GPIO_ACTIVE_HIGH), .dev_id = "foo.0",
GPIO_LOOKUP_IDX("gpio.0", 16, "foo.0", "led", 1, GPIO_ACTIVE_HIGH), .table = {
GPIO_LOOKUP_IDX("gpio.0", 17, "foo.0", "led", 2, GPIO_ACTIVE_HIGH), GPIO_LOOKUP_IDX("gpio.0", 15, "led", 0, GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("gpio.0", 1, "foo.0", "power", GPIO_ACTIVE_LOW), GPIO_LOOKUP_IDX("gpio.0", 16, "led", 1, GPIO_ACTIVE_HIGH),
}; GPIO_LOOKUP_IDX("gpio.0", 17, "led", 2, GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("gpio.0", 1, "power", GPIO_ACTIVE_LOW),
{ },
},
};
And the table can be added by the board code as follows: And the table can be added by the board code as follows:
gpiod_add_table(gpios_table, ARRAY_SIZE(gpios_table)); gpiod_add_lookup_table(&gpios_table);
The driver controlling "foo.0" will then be able to obtain its GPIOs as follows: The driver controlling "foo.0" will then be able to obtain its GPIOs as follows:
......
...@@ -38,7 +38,11 @@ device that displays digits), an additional index argument can be specified: ...@@ -38,7 +38,11 @@ device that displays digits), an additional index argument can be specified:
const char *con_id, unsigned int idx) const char *con_id, unsigned int idx)
Both functions return either a valid GPIO descriptor, or an error code checkable Both functions return either a valid GPIO descriptor, or an error code checkable
with IS_ERR(). They will never return a NULL pointer. with IS_ERR() (they will never return a NULL pointer). -ENOENT will be returned
if and only if no GPIO has been assigned to the device/function/index triplet,
other error codes are used for cases where a GPIO has been assigned but an error
occured while trying to acquire it. This is useful to discriminate between mere
errors and an absence of GPIO for optional GPIO parameters.
Device-managed variants of these functions are also defined: Device-managed variants of these functions are also defined:
......
...@@ -711,7 +711,6 @@ config ARCH_S3C24XX ...@@ -711,7 +711,6 @@ config ARCH_S3C24XX
select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C2410_WATCHDOG if WATCHDOG
select HAVE_S3C_RTC if RTC_CLASS select HAVE_S3C_RTC if RTC_CLASS
select MULTI_IRQ_HANDLER select MULTI_IRQ_HANDLER
select NEED_MACH_GPIO_H
select NEED_MACH_IO_H select NEED_MACH_IO_H
select SAMSUNG_ATAGS select SAMSUNG_ATAGS
help help
...@@ -734,7 +733,6 @@ config ARCH_S3C64XX ...@@ -734,7 +733,6 @@ config ARCH_S3C64XX
select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_I2C if I2C
select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C2410_WATCHDOG if WATCHDOG
select HAVE_TCM select HAVE_TCM
select NEED_MACH_GPIO_H
select NO_IOPORT select NO_IOPORT
select PLAT_SAMSUNG select PLAT_SAMSUNG
select PM_GENERIC_DOMAINS select PM_GENERIC_DOMAINS
...@@ -1594,7 +1592,7 @@ config ARM_PSCI ...@@ -1594,7 +1592,7 @@ config ARM_PSCI
config ARCH_NR_GPIO config ARCH_NR_GPIO
int int
default 1024 if ARCH_SHMOBILE || ARCH_TEGRA default 1024 if ARCH_SHMOBILE || ARCH_TEGRA
default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || SOC_DRA7XX default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || SOC_DRA7XX || ARCH_S3C24XX || ARCH_S3C64XX
default 392 if ARCH_U8500 default 392 if ARCH_U8500
default 352 if ARCH_VT8500 default 352 if ARCH_VT8500
default 288 if ARCH_SUNXI default 288 if ARCH_SUNXI
......
/*
* arch/arm/mach-ks8695/include/mach/gpio.h
*
* Copyright (C) 2006 Andrew Victor
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_ARCH_GPIO_H_
#define __ASM_ARCH_GPIO_H_
/*
* Map IRQ number to GPIO line.
*/
extern int irq_to_gpio(unsigned int irq);
#endif
#ifndef __MACH_GPIO_H
#define __MACH_GPIO_H
#include "gpio-lpc32xx.h"
#endif /* __MACH_GPIO_H */
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/mtd/lpc32xx_slc.h> #include <linux/mtd/lpc32xx_slc.h>
#include <linux/mtd/lpc32xx_mlc.h> #include <linux/mtd/lpc32xx_mlc.h>
#include <linux/platform_data/gpio-lpc32xx.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -44,7 +45,6 @@ ...@@ -44,7 +45,6 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/platform.h> #include <mach/platform.h>
#include <mach/board.h> #include <mach/board.h>
#include <mach/gpio-lpc32xx.h>
#include "common.h" #include "common.h"
/* /*
......
/*
* arch/asm-arm/mach-mv78xx0/include/mach/gpio.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <plat/gpio.h>
...@@ -180,27 +180,6 @@ config CPU_LLSERIAL_S3C2440 ...@@ -180,27 +180,6 @@ config CPU_LLSERIAL_S3C2440
Selected if there is an S3C2440 (or register compatible) serial Selected if there is an S3C2440 (or register compatible) serial
low-level implementation needed low-level implementation needed
# gpio configurations
config S3C24XX_GPIO_EXTRA
int
default 128 if S3C24XX_GPIO_EXTRA128
default 64 if S3C24XX_GPIO_EXTRA64
default 16 if ARCH_H1940
default 0
config S3C24XX_GPIO_EXTRA64
bool
help
Add an extra 64 gpio numbers to the available GPIO pool. This is
available for boards that need extra gpios for external devices.
config S3C24XX_GPIO_EXTRA128
bool
help
Add an extra 128 gpio numbers to the available GPIO pool. This is
available for boards that need extra gpios for external devices.
config S3C24XX_PLL config S3C24XX_PLL
bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)" bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
depends on ARM_S3C24XX_CPUFREQ depends on ARM_S3C24XX_CPUFREQ
......
...@@ -37,8 +37,8 @@ ...@@ -37,8 +37,8 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <linux/platform_data/leds-s3c24xx.h> #include <linux/platform_data/leds-s3c24xx.h>
#include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/mtd-nand-s3c2410.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
......
...@@ -19,8 +19,10 @@ ...@@ -19,8 +19,10 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/rfkill.h> #include <linux/rfkill.h>
#include <plat/gpio-cfg.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include "h1940.h" #include "h1940.h"
......
...@@ -14,16 +14,8 @@ ...@@ -14,16 +14,8 @@
* devices that need GPIO. * devices that need GPIO.
*/ */
#ifndef __MACH_GPIO_H #ifndef GPIO_SAMSUNG_S3C24XX_H
#define __MACH_GPIO_H __FILE__ #define GPIO_SAMSUNG_S3C24XX_H
#ifdef CONFIG_CPU_S3C244X
#define ARCH_NR_GPIOS (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
#define ARCH_NR_GPIOS (32 * 12 + CONFIG_S3C24XX_GPIO_EXTRA)
#else
#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA)
#endif
/* /*
* GPIO sizes for various SoCs: * GPIO sizes for various SoCs:
...@@ -31,17 +23,17 @@ ...@@ -31,17 +23,17 @@
* 2410 2412 2440 2443 2416 * 2410 2412 2440 2443 2416
* 2442 * 2442
* ---- ---- ---- ---- ---- * ---- ---- ---- ---- ----
* A 23 22 25 16 25 * A 23 22 25 16 27
* B 11 11 11 11 9 * B 11 11 11 11 11
* C 16 15 16 16 16 * C 16 16 16 16 16
* D 16 16 16 16 16 * D 16 16 16 16 16
* E 16 16 16 16 16 * E 16 16 16 16 16
* F 8 8 8 8 8 * F 8 8 8 8 8
* G 16 16 16 16 8 * G 16 16 16 16 8
* H 11 11 9 15 15 * H 11 11 11 15 15
* J -- -- 13 16 -- * J -- -- 13 16 --
* K -- -- -- -- 16 * K -- -- -- -- 16
* L -- -- -- 15 7 * L -- -- -- 15 14
* M -- -- -- 2 2 * M -- -- -- 2 2
*/ */
...@@ -101,8 +93,6 @@ enum s3c_gpio_number { ...@@ -101,8 +93,6 @@ enum s3c_gpio_number {
#define S3C2410_GPL(_nr) (S3C2410_GPIO_L_START + (_nr)) #define S3C2410_GPL(_nr) (S3C2410_GPIO_L_START + (_nr))
#define S3C2410_GPM(_nr) (S3C2410_GPIO_M_START + (_nr)) #define S3C2410_GPM(_nr) (S3C2410_GPIO_M_START + (_nr))
#include <plat/gpio-cfg.h>
#ifdef CONFIG_CPU_S3C244X #ifdef CONFIG_CPU_S3C244X
#define S3C_GPIO_END (S3C2410_GPJ(0) + 32) #define S3C_GPIO_END (S3C2410_GPJ(0) + 32)
#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416) #elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
...@@ -111,4 +101,4 @@ enum s3c_gpio_number { ...@@ -111,4 +101,4 @@ enum s3c_gpio_number {
#define S3C_GPIO_END (S3C2410_GPH(0) + 32) #define S3C_GPIO_END (S3C2410_GPH(0) + 32)
#endif #endif
#endif /* __MACH_GPIO_H */ #endif /* GPIO_SAMSUNG_S3C24XX_H */
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
#include <plat/devs.h> #include <plat/devs.h>
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/gpio-samsung.h>
#include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/mtd-nand-s3c2410.h>
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/gpio-samsung.h>
#include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/mtd-nand-s3c2410.h>
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/gpio-samsung.h>
#include <plat/clock.h> #include <plat/clock.h>
#include <plat/cpu.h> #include <plat/cpu.h>
......
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/regs-irq.h> #include <mach/regs-irq.h>
#include <mach/gpio-samsung.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/devs.h> #include <plat/devs.h>
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include <mach/regs-clock.h> #include <mach/regs-clock.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/gpio-samsung.h>
#include <plat/clock.h> #include <plat/clock.h>
#include <plat/cpu.h> #include <plat/cpu.h>
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/fb.h> #include <mach/fb.h>
#include <mach/gpio-samsung.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <linux/platform_data/leds-s3c24xx.h> #include <linux/platform_data/leds-s3c24xx.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/irqs.h> #include <mach/irqs.h>
#include <mach/gpio-samsung.h>
#include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/mtd-nand-s3c2410.h>
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
#include <linux/platform_data/mmc-s3cmci.h> #include <linux/platform_data/mmc-s3cmci.h>
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/platform_data/leds-s3c24xx.h> #include <linux/platform_data/leds-s3c24xx.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/gpio-samsung.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
//#include <asm/debug-ll.h> //#include <asm/debug-ll.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/i2c/tps65010.h> #include <linux/i2c/tps65010.h>
#include <plat/cpu-freq.h> #include <plat/cpu-freq.h>
#include <mach/gpio-samsung.h>
#define OSIRIS_GPIO_DVS S3C2410_GPB(5) #define OSIRIS_GPIO_DVS S3C2410_GPB(5)
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/gpio-samsung.h>
#include "common.h" #include "common.h"
#include "osiris.h" #include "osiris.h"
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/mtd-nand-s3c2410.h>
#include <linux/platform_data/usb-s3c2410_udc.h> #include <linux/platform_data/usb-s3c2410_udc.h>
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
#include <mach/gpio-samsung.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <plat/devs.h> #include <plat/devs.h>
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include <mach/fb.h> #include <mach/fb.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/gpio-samsung.h>
#include <plat/clock.h> #include <plat/clock.h>
#include <plat/cpu.h> #include <plat/cpu.h>
...@@ -58,6 +59,7 @@ ...@@ -58,6 +59,7 @@
#include <plat/pm.h> #include <plat/pm.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <plat/samsung-time.h> #include <plat/samsung-time.h>
#include <plat/gpio-cfg.h>
#include "common.h" #include "common.h"
#include "h1940.h" #include "h1940.h"
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/gpio-samsung.h>
#include <plat/clock.h> #include <plat/clock.h>
#include <plat/cpu.h> #include <plat/cpu.h>
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/platform_data/usb-s3c2410_udc.h> #include <linux/platform_data/usb-s3c2410_udc.h>
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
#include <mach/gpio-samsung.h>
#include <mach/fb.h> #include <mach/fb.h>
#include <plat/clock.h> #include <plat/clock.h>
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/regs-s3c2443-clock.h> #include <mach/regs-s3c2443-clock.h>
#include <mach/gpio-samsung.h>
#include <linux/platform_data/leds-s3c24xx.h> #include <linux/platform_data/leds-s3c24xx.h>
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/clock.h> #include <plat/clock.h>
#include <plat/cpu.h> #include <plat/cpu.h>
......
...@@ -33,7 +33,9 @@ ...@@ -33,7 +33,9 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/gpio-cfg.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/pm.h> #include <plat/pm.h>
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <mach/regs-clock.h> #include <mach/regs-clock.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/regs-irq.h> #include <mach/regs-irq.h>
#include <mach/gpio-samsung.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/gpio-samsung.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/system_misc.h> #include <asm/system_misc.h>
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/gpio-samsung.h>
#include <asm/proc-fns.h> #include <asm/proc-fns.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/system_misc.h> #include <asm/system_misc.h>
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/gpio-samsung.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <plat/devs.h> #include <plat/devs.h>
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/gpio-samsung.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <asm/irq.h> #include <asm/irq.h>
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/gpio-samsung.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/system_misc.h> #include <asm/system_misc.h>
......
...@@ -19,6 +19,7 @@ struct platform_device; ...@@ -19,6 +19,7 @@ struct platform_device;
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
void s3c_i2c0_cfg_gpio(struct platform_device *dev) void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{ {
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
......
...@@ -15,7 +15,9 @@ ...@@ -15,7 +15,9 @@
struct platform_device; /* don't need the contents */ struct platform_device; /* don't need the contents */
#include <plat/gpio-cfg.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/gpio-samsung.h>
/** /**
* s3c24xx_ts_cfg_gpio - configure gpio for s3c2410 systems * s3c24xx_ts_cfg_gpio - configure gpio for s3c2410 systems
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/gpio-samsung.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <linux/platform_data/usb-ohci-s3c2410.h> #include <linux/platform_data/usb-ohci-s3c2410.h>
......
...@@ -192,7 +192,6 @@ config SMDK6410_WM1190_EV1 ...@@ -192,7 +192,6 @@ config SMDK6410_WM1190_EV1
select MFD_WM8350_I2C select MFD_WM8350_I2C
select REGULATOR select REGULATOR
select REGULATOR_WM8350 select REGULATOR_WM8350
select SAMSUNG_GPIO_EXTRA64
help help
The Wolfson Microelectronics 1190-EV1 is a WM835x based PMIC The Wolfson Microelectronics 1190-EV1 is a WM835x based PMIC
and audio daughtercard for the Samsung SMDK6410 reference and audio daughtercard for the Samsung SMDK6410 reference
...@@ -208,7 +207,6 @@ config SMDK6410_WM1192_EV1 ...@@ -208,7 +207,6 @@ config SMDK6410_WM1192_EV1
select MFD_WM831X_I2C select MFD_WM831X_I2C
select REGULATOR select REGULATOR
select REGULATOR_WM831X select REGULATOR_WM831X
select SAMSUNG_GPIO_EXTRA64
help help
The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC
daughtercard for the Samsung SMDK6410 reference platform. daughtercard for the Samsung SMDK6410 reference platform.
...@@ -294,7 +292,6 @@ config MACH_WLF_CRAGG_6410 ...@@ -294,7 +292,6 @@ config MACH_WLF_CRAGG_6410
select SAMSUNG_DEV_ADC select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_KEYPAD select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM select SAMSUNG_DEV_PWM
select SAMSUNG_GPIO_EXTRA128
help help
Machine support for the Wolfson Cragganmore S3C6410 variant. Machine support for the Wolfson Cragganmore S3C6410 variant.
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <mach/map.h> #include <mach/map.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/devs.h> #include <plat/devs.h>
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#ifndef MACH_CRAG6410_H #ifndef MACH_CRAG6410_H
#define MACH_CRAG6410_H #define MACH_CRAG6410_H
#include <linux/gpio.h> #include <mach/gpio-samsung.h>
#define GLENFARCLAS_PMIC_IRQ_BASE IRQ_BOARD_START #define GLENFARCLAS_PMIC_IRQ_BASE IRQ_BOARD_START
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <plat/devs.h> #include <plat/devs.h>
#include <linux/platform_data/asoc-s3c.h> #include <linux/platform_data/asoc-s3c.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <mach/gpio-samsung.h>
static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev) static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)
{ {
......
/* arch/arm/mach-s3c6400/include/mach/gpio.h /*
*
* Copyright 2008 Openmoko, Inc. * Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics * Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/ * http://armlinux.simtec.co.uk/
...@@ -12,6 +11,9 @@ ...@@ -12,6 +11,9 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#ifndef GPIO_SAMSUNG_S3C64XX_H
#define GPIO_SAMSUNG_S3C64XX_H
/* GPIO bank sizes */ /* GPIO bank sizes */
#define S3C64XX_GPIO_A_NR (8) #define S3C64XX_GPIO_A_NR (8)
#define S3C64XX_GPIO_B_NR (7) #define S3C64XX_GPIO_B_NR (7)
...@@ -88,6 +90,5 @@ enum s3c_gpio_number { ...@@ -88,6 +90,5 @@ enum s3c_gpio_number {
/* define the number of gpios we need to the one after the GPQ() range */ /* define the number of gpios we need to the one after the GPQ() range */
#define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1) #define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
#define BOARD_NR_GPIOS (16 + CONFIG_SAMSUNG_GPIO_EXTRA) #endif /* GPIO_SAMSUNG_S3C64XX_H */
#define ARCH_NR_GPIOS (GPIO_BOARD_START + BOARD_NR_GPIOS)
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include <plat/devs.h> #include <plat/devs.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/samsung-time.h> #include <plat/samsung-time.h>
#include "common.h" #include "common.h"
......
...@@ -48,8 +48,8 @@ ...@@ -48,8 +48,8 @@
#include <video/samsung_fimd.h> #include <video/samsung_fimd.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/map.h> #include <mach/map.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <plat/fb.h> #include <plat/fb.h>
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
#include <mach/gpio-samsung.h>
#include <plat/fb.h> #include <plat/fb.h>
#include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/mtd-nand-s3c2410.h>
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <mach/map.h> #include <mach/map.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/adc.h> #include <plat/adc.h>
#include <plat/cpu.h> #include <plat/cpu.h>
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <mach/map.h> #include <mach/map.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/adc.h> #include <plat/adc.h>
#include <plat/cpu.h> #include <plat/cpu.h>
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <mach/map.h> #include <mach/map.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/clock.h> #include <plat/clock.h>
#include <plat/cpu.h> #include <plat/cpu.h>
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <video/samsung_fimd.h> #include <video/samsung_fimd.h>
#include <mach/map.h> #include <mach/map.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/devs.h> #include <plat/devs.h>
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <video/samsung_fimd.h> #include <video/samsung_fimd.h>
#include <mach/map.h> #include <mach/map.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/devs.h> #include <plat/devs.h>
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <plat/devs.h> #include <plat/devs.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
#include <mach/gpio-samsung.h>
#include <plat/samsung-time.h> #include <plat/samsung-time.h>
#include "common.h" #include "common.h"
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <linux/platform_data/ata-samsung_cf.h> #include <linux/platform_data/ata-samsung_cf.h>
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
#include <plat/fb.h> #include <plat/fb.h>
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/regs-clock.h> #include <mach/regs-clock.h>
#include <mach/gpio-samsung.h>
#include "regs-gpio-memport.h" #include "regs-gpio-memport.h"
#include "regs-modem.h" #include "regs-modem.h"
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <plat/fb.h> #include <plat/fb.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <mach/gpio-samsung.h>
void s3c64xx_fb_gpio_setup_24bpp(void) void s3c64xx_fb_gpio_setup_24bpp(void)
{ {
......
...@@ -20,6 +20,7 @@ struct platform_device; /* don't need the contents */ ...@@ -20,6 +20,7 @@ struct platform_device; /* don't need the contents */
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <mach/gpio-samsung.h>
void s3c_i2c0_cfg_gpio(struct platform_device *dev) void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{ {
......
...@@ -20,6 +20,7 @@ struct platform_device; /* don't need the contents */ ...@@ -20,6 +20,7 @@ struct platform_device; /* don't need the contents */
#include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <mach/gpio-samsung.h>
void s3c_i2c1_cfg_gpio(struct platform_device *dev) void s3c_i2c1_cfg_gpio(struct platform_device *dev)
{ {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <mach/map.h> #include <mach/map.h>
#include <mach/regs-clock.h> #include <mach/regs-clock.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <mach/gpio-samsung.h>
#include <linux/platform_data/ata-samsung_cf.h> #include <linux/platform_data/ata-samsung_cf.h>
void s3c64xx_ide_setup_gpio(void) void s3c64xx_ide_setup_gpio(void)
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <plat/keypad.h> #include <plat/keypad.h>
#include <mach/gpio-samsung.h>
void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
{ {
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <plat/sdhci.h> #include <plat/sdhci.h>
#include <mach/gpio-samsung.h>
void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{ {
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <mach/gpio-samsung.h>
#ifdef CONFIG_S3C64XX_DEV_SPI0 #ifdef CONFIG_S3C64XX_DEV_SPI0
int s3c64xx_spi0_cfg_gpio(void) int s3c64xx_spi0_cfg_gpio(void)
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
*/ */
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/gpio/driver.h>
#include <linux/rfkill-gpio.h> #include <linux/rfkill-gpio.h>
#include "board.h" #include "board.h"
...@@ -36,7 +37,17 @@ static struct platform_device wifi_rfkill_device = { ...@@ -36,7 +37,17 @@ static struct platform_device wifi_rfkill_device = {
}, },
}; };
static struct gpiod_lookup_table wifi_gpio_lookup = {
.dev_id = "rfkill_gpio",
.table = {
GPIO_LOOKUP_IDX("tegra-gpio", 25, NULL, 0, 0),
GPIO_LOOKUP_IDX("tegra-gpio", 85, NULL, 1, 0),
{ },
},
};
void __init tegra_paz00_wifikill_init(void) void __init tegra_paz00_wifikill_init(void)
{ {
gpiod_add_lookup_table(&wifi_gpio_lookup);
platform_device_register(&wifi_rfkill_device); platform_device_register(&wifi_rfkill_device);
} }
...@@ -19,6 +19,10 @@ ...@@ -19,6 +19,10 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
#include <mach/gpio-samsung.h>
#endif
#include <plat/gpio-core.h> #include <plat/gpio-core.h>
#include <plat/pm.h> #include <plat/pm.h>
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <mach/gpio-samsung.h>
/* Number of camera port pins, without FIELD */ /* Number of camera port pins, without FIELD */
#define S3C_CAMIF_NUM_GPIOS 13 #define S3C_CAMIF_NUM_GPIOS 13
......
...@@ -64,6 +64,9 @@ config MMU ...@@ -64,6 +64,9 @@ config MMU
config VARIANT_IRQ_SWITCH config VARIANT_IRQ_SWITCH
def_bool n def_bool n
config HAVE_XTENSA_GPIO32
def_bool n
menu "Processor type and features" menu "Processor type and features"
choice choice
...@@ -73,16 +76,19 @@ choice ...@@ -73,16 +76,19 @@ choice
config XTENSA_VARIANT_FSF config XTENSA_VARIANT_FSF
bool "fsf - default (not generic) configuration" bool "fsf - default (not generic) configuration"
select MMU select MMU
select HAVE_XTENSA_GPIO32
config XTENSA_VARIANT_DC232B config XTENSA_VARIANT_DC232B
bool "dc232b - Diamond 232L Standard Core Rev.B (LE)" bool "dc232b - Diamond 232L Standard Core Rev.B (LE)"
select MMU select MMU
select HAVE_XTENSA_GPIO32
help help
This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE). This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE).
config XTENSA_VARIANT_DC233C config XTENSA_VARIANT_DC233C
bool "dc233c - Diamond 233L Standard Core Rev.C (LE)" bool "dc233c - Diamond 233L Standard Core Rev.C (LE)"
select MMU select MMU
select HAVE_XTENSA_GPIO32
help help
This variant refers to Tensilica's Diamond 233L Standard core Rev.C (LE). This variant refers to Tensilica's Diamond 233L Standard core Rev.C (LE).
......
...@@ -110,7 +110,7 @@ comment "Memory mapped GPIO drivers:" ...@@ -110,7 +110,7 @@ comment "Memory mapped GPIO drivers:"
config GPIO_CLPS711X config GPIO_CLPS711X
tristate "CLPS711X GPIO support" tristate "CLPS711X GPIO support"
depends on ARCH_CLPS711X depends on ARCH_CLPS711X || COMPILE_TEST
select GPIO_GENERIC select GPIO_GENERIC
help help
Say yes here to support GPIO on CLPS711X SoCs. Say yes here to support GPIO on CLPS711X SoCs.
...@@ -156,6 +156,13 @@ config GPIO_F7188X ...@@ -156,6 +156,13 @@ config GPIO_F7188X
To compile this driver as a module, choose M here: the module will To compile this driver as a module, choose M here: the module will
be called f7188x-gpio. be called f7188x-gpio.
config GPIO_MOXART
bool "MOXART GPIO support"
depends on ARCH_MOXART
help
Select this option to enable GPIO driver for
MOXA ART SoC devices.
config GPIO_MPC5200 config GPIO_MPC5200
def_bool y def_bool y
depends on PPC_MPC52xx depends on PPC_MPC52xx
...@@ -237,6 +244,15 @@ config GPIO_SAMSUNG ...@@ -237,6 +244,15 @@ config GPIO_SAMSUNG
Legacy GPIO support. Use only for platforms without support for Legacy GPIO support. Use only for platforms without support for
pinctrl. pinctrl.
config GPIO_SCH311X
tristate "SMSC SCH311x SuperI/O GPIO"
help
Driver to enable the GPIOs found on SMSC SMSC SCH3112, SCH3114 and
SCH3116 "Super I/O" chipsets.
To compile this driver as a module, choose M here: the module will
be called gpio-sch311x.
config GPIO_SPEAR_SPICS config GPIO_SPEAR_SPICS
bool "ST SPEAr13xx SPI Chip Select as GPIO support" bool "ST SPEAr13xx SPI Chip Select as GPIO support"
depends on PLAT_SPEAR depends on PLAT_SPEAR
...@@ -281,6 +297,15 @@ config GPIO_XILINX ...@@ -281,6 +297,15 @@ config GPIO_XILINX
help help
Say yes here to support the Xilinx FPGA GPIO device Say yes here to support the Xilinx FPGA GPIO device
config GPIO_XTENSA
bool "Xtensa GPIO32 support"
depends on XTENSA
depends on HAVE_XTENSA_GPIO32
depends on !SMP
help
Say yes here to support the Xtensa internal GPIO32 IMPWIRE (input)
and EXPSTATE (output) ports
config GPIO_VR41XX config GPIO_VR41XX
tristate "NEC VR4100 series General-purpose I/O Uint support" tristate "NEC VR4100 series General-purpose I/O Uint support"
depends on CPU_VR41XX depends on CPU_VR41XX
...@@ -353,7 +378,7 @@ config GPIO_GE_FPGA ...@@ -353,7 +378,7 @@ config GPIO_GE_FPGA
board computers. board computers.
config GPIO_LYNXPOINT config GPIO_LYNXPOINT
bool "Intel Lynxpoint GPIO support" tristate "Intel Lynxpoint GPIO support"
depends on ACPI && X86 depends on ACPI && X86
select IRQ_DOMAIN select IRQ_DOMAIN
help help
...@@ -692,11 +717,13 @@ config GPIO_MAX7301 ...@@ -692,11 +717,13 @@ config GPIO_MAX7301
config GPIO_MCP23S08 config GPIO_MCP23S08
tristate "Microchip MCP23xxx I/O expander" tristate "Microchip MCP23xxx I/O expander"
depends on OF_GPIO
depends on (SPI_MASTER && !I2C) || I2C depends on (SPI_MASTER && !I2C) || I2C
help help
SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017 SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017
I/O expanders. I/O expanders.
This provides a GPIO interface supporting inputs and outputs. This provides a GPIO interface supporting inputs and outputs.
The I2C versions of the chips can be used as interrupt-controller.
config GPIO_MC33880 config GPIO_MC33880
tristate "Freescale MC33880 high-side/low-side switch" tristate "Freescale MC33880 high-side/low-side switch"
...@@ -707,10 +734,10 @@ config GPIO_MC33880 ...@@ -707,10 +734,10 @@ config GPIO_MC33880
config GPIO_74X164 config GPIO_74X164
tristate "74x164 serial-in/parallel-out 8-bits shift register" tristate "74x164 serial-in/parallel-out 8-bits shift register"
depends on SPI_MASTER depends on SPI_MASTER && OF
help help
Platform driver for 74x164 compatible serial-in/parallel-out Driver for 74x164 compatible serial-in/parallel-out 8-outputs
8-outputs shift registers. This driver can be used to provide access shift registers. This driver can be used to provide access
to more gpio outputs. to more gpio outputs.
comment "AC97 GPIO expanders:" comment "AC97 GPIO expanders:"
......
...@@ -46,6 +46,7 @@ obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o ...@@ -46,6 +46,7 @@ obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o
obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o
obj-$(CONFIG_GPIO_MM_LANTIQ) += gpio-mm-lantiq.o obj-$(CONFIG_GPIO_MM_LANTIQ) += gpio-mm-lantiq.o
obj-$(CONFIG_GPIO_MOXART) += gpio-moxart.o
obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o
...@@ -67,6 +68,7 @@ obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o ...@@ -67,6 +68,7 @@ obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
obj-$(CONFIG_GPIO_SAMSUNG) += gpio-samsung.o obj-$(CONFIG_GPIO_SAMSUNG) += gpio-samsung.o
obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
obj-$(CONFIG_GPIO_SCH) += gpio-sch.o obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o
obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o
obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o
obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o
...@@ -95,3 +97,4 @@ obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o ...@@ -95,3 +97,4 @@ obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o
obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o
obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o
obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o
obj-$(CONFIG_GPIO_XTENSA) += gpio-xtensa.o
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/74x164.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -21,7 +20,6 @@ ...@@ -21,7 +20,6 @@
#define GEN_74X164_NUMBER_GPIOS 8 #define GEN_74X164_NUMBER_GPIOS 8
struct gen_74x164_chip { struct gen_74x164_chip {
struct spi_device *spi;
u8 *buffer; u8 *buffer;
struct gpio_chip gpio_chip; struct gpio_chip gpio_chip;
struct mutex lock; struct mutex lock;
...@@ -35,6 +33,7 @@ static struct gen_74x164_chip *gpio_to_74x164_chip(struct gpio_chip *gc) ...@@ -35,6 +33,7 @@ static struct gen_74x164_chip *gpio_to_74x164_chip(struct gpio_chip *gc)
static int __gen_74x164_write_config(struct gen_74x164_chip *chip) static int __gen_74x164_write_config(struct gen_74x164_chip *chip)
{ {
struct spi_device *spi = to_spi_device(chip->gpio_chip.dev);
struct spi_message message; struct spi_message message;
struct spi_transfer *msg_buf; struct spi_transfer *msg_buf;
int i, ret = 0; int i, ret = 0;
...@@ -55,12 +54,12 @@ static int __gen_74x164_write_config(struct gen_74x164_chip *chip) ...@@ -55,12 +54,12 @@ static int __gen_74x164_write_config(struct gen_74x164_chip *chip)
* byte of the buffer will end up in the last register. * byte of the buffer will end up in the last register.
*/ */
for (i = chip->registers - 1; i >= 0; i--) { for (i = chip->registers - 1; i >= 0; i--) {
msg_buf[i].tx_buf = chip->buffer +i; msg_buf[i].tx_buf = chip->buffer + i;
msg_buf[i].len = sizeof(u8); msg_buf[i].len = sizeof(u8);
spi_message_add_tail(msg_buf + i, &message); spi_message_add_tail(msg_buf + i, &message);
} }
ret = spi_sync(chip->spi, &message); ret = spi_sync(spi, &message);
kfree(msg_buf); kfree(msg_buf);
...@@ -108,14 +107,8 @@ static int gen_74x164_direction_output(struct gpio_chip *gc, ...@@ -108,14 +107,8 @@ static int gen_74x164_direction_output(struct gpio_chip *gc,
static int gen_74x164_probe(struct spi_device *spi) static int gen_74x164_probe(struct spi_device *spi)
{ {
struct gen_74x164_chip *chip; struct gen_74x164_chip *chip;
struct gen_74x164_chip_platform_data *pdata;
int ret; int ret;
if (!spi->dev.of_node) {
dev_err(&spi->dev, "No device tree data available.\n");
return -EINVAL;
}
/* /*
* bits_per_word cannot be configured in platform data * bits_per_word cannot be configured in platform data
*/ */
...@@ -129,40 +122,32 @@ static int gen_74x164_probe(struct spi_device *spi) ...@@ -129,40 +122,32 @@ static int gen_74x164_probe(struct spi_device *spi)
if (!chip) if (!chip)
return -ENOMEM; return -ENOMEM;
pdata = dev_get_platdata(&spi->dev);
if (pdata && pdata->base)
chip->gpio_chip.base = pdata->base;
else
chip->gpio_chip.base = -1;
mutex_init(&chip->lock);
spi_set_drvdata(spi, chip); spi_set_drvdata(spi, chip);
chip->spi = spi;
chip->gpio_chip.label = spi->modalias; chip->gpio_chip.label = spi->modalias;
chip->gpio_chip.direction_output = gen_74x164_direction_output; chip->gpio_chip.direction_output = gen_74x164_direction_output;
chip->gpio_chip.get = gen_74x164_get_value; chip->gpio_chip.get = gen_74x164_get_value;
chip->gpio_chip.set = gen_74x164_set_value; chip->gpio_chip.set = gen_74x164_set_value;
chip->gpio_chip.base = -1;
if (of_property_read_u32(spi->dev.of_node, "registers-number", &chip->registers)) { if (of_property_read_u32(spi->dev.of_node, "registers-number",
dev_err(&spi->dev, "Missing registers-number property in the DT.\n"); &chip->registers)) {
ret = -EINVAL; dev_err(&spi->dev,
goto exit_destroy; "Missing registers-number property in the DT.\n");
return -EINVAL;
} }
chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers; chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers;
chip->buffer = devm_kzalloc(&spi->dev, chip->registers, GFP_KERNEL); chip->buffer = devm_kzalloc(&spi->dev, chip->registers, GFP_KERNEL);
if (!chip->buffer) { if (!chip->buffer)
ret = -ENOMEM; return -ENOMEM;
goto exit_destroy;
}
chip->gpio_chip.can_sleep = 1; chip->gpio_chip.can_sleep = true;
chip->gpio_chip.dev = &spi->dev; chip->gpio_chip.dev = &spi->dev;
chip->gpio_chip.owner = THIS_MODULE; chip->gpio_chip.owner = THIS_MODULE;
mutex_init(&chip->lock);
ret = __gen_74x164_write_config(chip); ret = __gen_74x164_write_config(chip);
if (ret) { if (ret) {
dev_err(&spi->dev, "Failed writing: %d\n", ret); dev_err(&spi->dev, "Failed writing: %d\n", ret);
...@@ -170,31 +155,23 @@ static int gen_74x164_probe(struct spi_device *spi) ...@@ -170,31 +155,23 @@ static int gen_74x164_probe(struct spi_device *spi)
} }
ret = gpiochip_add(&chip->gpio_chip); ret = gpiochip_add(&chip->gpio_chip);
if (ret) if (!ret)
goto exit_destroy; return 0;
return ret;
exit_destroy: exit_destroy:
mutex_destroy(&chip->lock); mutex_destroy(&chip->lock);
return ret; return ret;
} }
static int gen_74x164_remove(struct spi_device *spi) static int gen_74x164_remove(struct spi_device *spi)
{ {
struct gen_74x164_chip *chip; struct gen_74x164_chip *chip = spi_get_drvdata(spi);
int ret; int ret;
chip = spi_get_drvdata(spi);
if (chip == NULL)
return -ENODEV;
ret = gpiochip_remove(&chip->gpio_chip); ret = gpiochip_remove(&chip->gpio_chip);
if (!ret) if (!ret)
mutex_destroy(&chip->lock); mutex_destroy(&chip->lock);
else
dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n",
ret);
return ret; return ret;
} }
......
...@@ -260,7 +260,7 @@ static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios) ...@@ -260,7 +260,7 @@ static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios)
chip->direction_output = adnp_gpio_direction_output; chip->direction_output = adnp_gpio_direction_output;
chip->get = adnp_gpio_get; chip->get = adnp_gpio_get;
chip->set = adnp_gpio_set; chip->set = adnp_gpio_set;
chip->can_sleep = 1; chip->can_sleep = true;
if (IS_ENABLED(CONFIG_DEBUG_FS)) if (IS_ENABLED(CONFIG_DEBUG_FS))
chip->dbg_show = adnp_gpio_dbg_show; chip->dbg_show = adnp_gpio_dbg_show;
...@@ -408,6 +408,27 @@ static void adnp_irq_bus_unlock(struct irq_data *data) ...@@ -408,6 +408,27 @@ static void adnp_irq_bus_unlock(struct irq_data *data)
mutex_unlock(&adnp->irq_lock); mutex_unlock(&adnp->irq_lock);
} }
static unsigned int adnp_irq_startup(struct irq_data *data)
{
struct adnp *adnp = irq_data_get_irq_chip_data(data);
if (gpio_lock_as_irq(&adnp->gpio, data->hwirq))
dev_err(adnp->gpio.dev,
"unable to lock HW IRQ %lu for IRQ\n",
data->hwirq);
/* Satisfy the .enable semantics by unmasking the line */
adnp_irq_unmask(data);
return 0;
}
static void adnp_irq_shutdown(struct irq_data *data)
{
struct adnp *adnp = irq_data_get_irq_chip_data(data);
adnp_irq_mask(data);
gpio_unlock_as_irq(&adnp->gpio, data->hwirq);
}
static struct irq_chip adnp_irq_chip = { static struct irq_chip adnp_irq_chip = {
.name = "gpio-adnp", .name = "gpio-adnp",
.irq_mask = adnp_irq_mask, .irq_mask = adnp_irq_mask,
...@@ -415,6 +436,8 @@ static struct irq_chip adnp_irq_chip = { ...@@ -415,6 +436,8 @@ static struct irq_chip adnp_irq_chip = {
.irq_set_type = adnp_irq_set_type, .irq_set_type = adnp_irq_set_type,
.irq_bus_lock = adnp_irq_bus_lock, .irq_bus_lock = adnp_irq_bus_lock,
.irq_bus_sync_unlock = adnp_irq_bus_unlock, .irq_bus_sync_unlock = adnp_irq_bus_unlock,
.irq_startup = adnp_irq_startup,
.irq_shutdown = adnp_irq_shutdown,
}; };
static int adnp_irq_map(struct irq_domain *domain, unsigned int irq, static int adnp_irq_map(struct irq_domain *domain, unsigned int irq,
......
...@@ -127,7 +127,7 @@ static int adp5520_gpio_probe(struct platform_device *pdev) ...@@ -127,7 +127,7 @@ static int adp5520_gpio_probe(struct platform_device *pdev)
gc->direction_output = adp5520_gpio_direction_output; gc->direction_output = adp5520_gpio_direction_output;
gc->get = adp5520_gpio_get_value; gc->get = adp5520_gpio_get_value;
gc->set = adp5520_gpio_set_value; gc->set = adp5520_gpio_set_value;
gc->can_sleep = 1; gc->can_sleep = true;
gc->base = pdata->gpio_start; gc->base = pdata->gpio_start;
gc->ngpio = gpios; gc->ngpio = gpios;
......
...@@ -380,7 +380,7 @@ static int adp5588_gpio_probe(struct i2c_client *client, ...@@ -380,7 +380,7 @@ static int adp5588_gpio_probe(struct i2c_client *client,
gc->direction_output = adp5588_gpio_direction_output; gc->direction_output = adp5588_gpio_direction_output;
gc->get = adp5588_gpio_get_value; gc->get = adp5588_gpio_get_value;
gc->set = adp5588_gpio_set_value; gc->set = adp5588_gpio_set_value;
gc->can_sleep = 1; gc->can_sleep = true;
gc->base = pdata->gpio_start; gc->base = pdata->gpio_start;
gc->ngpio = ADP5588_MAXGPIO; gc->ngpio = ADP5588_MAXGPIO;
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
* register a pci_driver, because someone else might one day * register a pci_driver, because someone else might one day
* want to register another driver on the same PCI id. * want to register another driver on the same PCI id.
*/ */
static DEFINE_PCI_DEVICE_TABLE(pci_tbl) = { static const struct pci_device_id pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS), 0 }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS), 0 },
{ 0, }, /* terminate list */ { 0, }, /* terminate list */
}; };
......
...@@ -91,7 +91,7 @@ static struct gpio_chip template_chip = { ...@@ -91,7 +91,7 @@ static struct gpio_chip template_chip = {
.get = arizona_gpio_get, .get = arizona_gpio_get,
.direction_output = arizona_gpio_direction_out, .direction_output = arizona_gpio_direction_out,
.set = arizona_gpio_set, .set = arizona_gpio_set,
.can_sleep = 1, .can_sleep = true,
}; };
static int arizona_gpio_probe(struct platform_device *pdev) static int arizona_gpio_probe(struct platform_device *pdev)
......
...@@ -449,12 +449,34 @@ static void bcm_kona_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) ...@@ -449,12 +449,34 @@ static void bcm_kona_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
} }
static unsigned int bcm_kona_gpio_irq_startup(struct irq_data *d)
{
struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d);
if (gpio_lock_as_irq(&kona_gpio->gpio_chip, d->hwirq))
dev_err(kona_gpio->gpio_chip.dev,
"unable to lock HW IRQ %lu for IRQ\n",
d->hwirq);
bcm_kona_gpio_irq_unmask(d);
return 0;
}
static void bcm_kona_gpio_irq_shutdown(struct irq_data *d)
{
struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d);
bcm_kona_gpio_irq_mask(d);
gpio_unlock_as_irq(&kona_gpio->gpio_chip, d->hwirq);
}
static struct irq_chip bcm_gpio_irq_chip = { static struct irq_chip bcm_gpio_irq_chip = {
.name = "bcm-kona-gpio", .name = "bcm-kona-gpio",
.irq_ack = bcm_kona_gpio_irq_ack, .irq_ack = bcm_kona_gpio_irq_ack,
.irq_mask = bcm_kona_gpio_irq_mask, .irq_mask = bcm_kona_gpio_irq_mask,
.irq_unmask = bcm_kona_gpio_irq_unmask, .irq_unmask = bcm_kona_gpio_irq_unmask,
.irq_set_type = bcm_kona_gpio_irq_set_type, .irq_set_type = bcm_kona_gpio_irq_set_type,
.irq_startup = bcm_kona_gpio_irq_startup,
.irq_shutdown = bcm_kona_gpio_irq_shutdown,
}; };
static struct __initconst of_device_id bcm_kona_gpio_of_match[] = { static struct __initconst of_device_id bcm_kona_gpio_of_match[] = {
......
...@@ -169,7 +169,7 @@ static void bt8xxgpio_gpio_setup(struct bt8xxgpio *bg) ...@@ -169,7 +169,7 @@ static void bt8xxgpio_gpio_setup(struct bt8xxgpio *bg)
c->dbg_show = NULL; c->dbg_show = NULL;
c->base = modparam_gpiobase; c->base = modparam_gpiobase;
c->ngpio = BT8XXGPIO_NR_GPIOS; c->ngpio = BT8XXGPIO_NR_GPIOS;
c->can_sleep = 0; c->can_sleep = false;
} }
static int bt8xxgpio_probe(struct pci_dev *dev, static int bt8xxgpio_probe(struct pci_dev *dev,
...@@ -308,7 +308,7 @@ static int bt8xxgpio_resume(struct pci_dev *pdev) ...@@ -308,7 +308,7 @@ static int bt8xxgpio_resume(struct pci_dev *pdev)
#define bt8xxgpio_resume NULL #define bt8xxgpio_resume NULL
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
static DEFINE_PCI_DEVICE_TABLE(bt8xxgpio_pci_tbl) = { static const struct pci_device_id bt8xxgpio_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848) }, { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849) }, { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878) }, { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878) },
......
...@@ -77,7 +77,7 @@ static int clps711x_gpio_remove(struct platform_device *pdev) ...@@ -77,7 +77,7 @@ static int clps711x_gpio_remove(struct platform_device *pdev)
return bgpio_remove(bgc); return bgpio_remove(bgc);
} }
static const struct of_device_id clps711x_gpio_ids[] = { static const struct of_device_id __maybe_unused clps711x_gpio_ids[] = {
{ .compatible = "cirrus,clps711x-gpio" }, { .compatible = "cirrus,clps711x-gpio" },
{ } { }
}; };
...@@ -87,7 +87,7 @@ static struct platform_driver clps711x_gpio_driver = { ...@@ -87,7 +87,7 @@ static struct platform_driver clps711x_gpio_driver = {
.driver = { .driver = {
.name = "clps711x-gpio", .name = "clps711x-gpio",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = clps711x_gpio_ids, .of_match_table = of_match_ptr(clps711x_gpio_ids),
}, },
.probe = clps711x_gpio_probe, .probe = clps711x_gpio_probe,
.remove = clps711x_gpio_remove, .remove = clps711x_gpio_remove,
......
...@@ -200,7 +200,7 @@ static struct gpio_chip reference_gp = { ...@@ -200,7 +200,7 @@ static struct gpio_chip reference_gp = {
.direction_input = da9052_gpio_direction_input, .direction_input = da9052_gpio_direction_input,
.direction_output = da9052_gpio_direction_output, .direction_output = da9052_gpio_direction_output,
.to_irq = da9052_gpio_to_irq, .to_irq = da9052_gpio_to_irq,
.can_sleep = 1, .can_sleep = true,
.ngpio = 16, .ngpio = 16,
.base = -1, .base = -1,
}; };
......
...@@ -134,7 +134,7 @@ static struct gpio_chip reference_gp = { ...@@ -134,7 +134,7 @@ static struct gpio_chip reference_gp = {
.direction_input = da9055_gpio_direction_input, .direction_input = da9055_gpio_direction_input,
.direction_output = da9055_gpio_direction_output, .direction_output = da9055_gpio_direction_output,
.to_irq = da9055_gpio_to_irq, .to_irq = da9055_gpio_to_irq,
.can_sleep = 1, .can_sleep = true,
.ngpio = 3, .ngpio = 3,
.base = -1, .base = -1,
}; };
......
...@@ -99,6 +99,27 @@ static void em_gio_irq_enable(struct irq_data *d) ...@@ -99,6 +99,27 @@ static void em_gio_irq_enable(struct irq_data *d)
em_gio_write(p, GIO_IEN, BIT(irqd_to_hwirq(d))); em_gio_write(p, GIO_IEN, BIT(irqd_to_hwirq(d)));
} }
static unsigned int em_gio_irq_startup(struct irq_data *d)
{
struct em_gio_priv *p = irq_data_get_irq_chip_data(d);
if (gpio_lock_as_irq(&p->gpio_chip, irqd_to_hwirq(d)))
dev_err(p->gpio_chip.dev,
"unable to lock HW IRQ %lu for IRQ\n",
irqd_to_hwirq(d));
em_gio_irq_enable(d);
return 0;
}
static void em_gio_irq_shutdown(struct irq_data *d)
{
struct em_gio_priv *p = irq_data_get_irq_chip_data(d);
em_gio_irq_disable(d);
gpio_unlock_as_irq(&p->gpio_chip, irqd_to_hwirq(d));
}
#define GIO_ASYNC(x) (x + 8) #define GIO_ASYNC(x) (x + 8)
static unsigned char em_gio_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { static unsigned char em_gio_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
...@@ -328,6 +349,7 @@ static int em_gio_probe(struct platform_device *pdev) ...@@ -328,6 +349,7 @@ static int em_gio_probe(struct platform_device *pdev)
gpio_chip->request = em_gio_request; gpio_chip->request = em_gio_request;
gpio_chip->free = em_gio_free; gpio_chip->free = em_gio_free;
gpio_chip->label = name; gpio_chip->label = name;
gpio_chip->dev = &pdev->dev;
gpio_chip->owner = THIS_MODULE; gpio_chip->owner = THIS_MODULE;
gpio_chip->base = pdata->gpio_base; gpio_chip->base = pdata->gpio_base;
gpio_chip->ngpio = pdata->number_of_pins; gpio_chip->ngpio = pdata->number_of_pins;
...@@ -336,10 +358,10 @@ static int em_gio_probe(struct platform_device *pdev) ...@@ -336,10 +358,10 @@ static int em_gio_probe(struct platform_device *pdev)
irq_chip->name = name; irq_chip->name = name;
irq_chip->irq_mask = em_gio_irq_disable; irq_chip->irq_mask = em_gio_irq_disable;
irq_chip->irq_unmask = em_gio_irq_enable; irq_chip->irq_unmask = em_gio_irq_enable;
irq_chip->irq_enable = em_gio_irq_enable;
irq_chip->irq_disable = em_gio_irq_disable;
irq_chip->irq_set_type = em_gio_irq_set_type; irq_chip->irq_set_type = em_gio_irq_set_type;
irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; irq_chip->irq_startup = em_gio_irq_startup;
irq_chip->irq_shutdown = em_gio_irq_shutdown;
irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND;
p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, p->irq_domain = irq_domain_add_simple(pdev->dev.of_node,
pdata->number_of_pins, pdata->number_of_pins,
......
...@@ -135,6 +135,7 @@ static void f7188x_gpio_set(struct gpio_chip *chip, unsigned offset, int value); ...@@ -135,6 +135,7 @@ static void f7188x_gpio_set(struct gpio_chip *chip, unsigned offset, int value);
.set = f7188x_gpio_set, \ .set = f7188x_gpio_set, \
.base = _base, \ .base = _base, \
.ngpio = _ngpio, \ .ngpio = _ngpio, \
.can_sleep = true, \
}, \ }, \
.regbase = _regbase, \ .regbase = _regbase, \
} }
......
...@@ -252,7 +252,7 @@ static void ichx_gpiolib_setup(struct gpio_chip *chip) ...@@ -252,7 +252,7 @@ static void ichx_gpiolib_setup(struct gpio_chip *chip)
chip->direction_output = ichx_gpio_direction_output; chip->direction_output = ichx_gpio_direction_output;
chip->base = modparam_gpiobase; chip->base = modparam_gpiobase;
chip->ngpio = ichx_priv.desc->ngpio; chip->ngpio = ichx_priv.desc->ngpio;
chip->can_sleep = 0; chip->can_sleep = false;
chip->dbg_show = NULL; chip->dbg_show = NULL;
} }
......
...@@ -235,11 +235,33 @@ static void intel_mid_irq_mask(struct irq_data *d) ...@@ -235,11 +235,33 @@ static void intel_mid_irq_mask(struct irq_data *d)
{ {
} }
static unsigned int intel_mid_irq_startup(struct irq_data *d)
{
struct intel_mid_gpio *priv = irq_data_get_irq_chip_data(d);
if (gpio_lock_as_irq(&priv->chip, irqd_to_hwirq(d)))
dev_err(priv->chip.dev,
"unable to lock HW IRQ %lu for IRQ\n",
irqd_to_hwirq(d));
intel_mid_irq_unmask(d);
return 0;
}
static void intel_mid_irq_shutdown(struct irq_data *d)
{
struct intel_mid_gpio *priv = irq_data_get_irq_chip_data(d);
intel_mid_irq_mask(d);
gpio_unlock_as_irq(&priv->chip, irqd_to_hwirq(d));
}
static struct irq_chip intel_mid_irqchip = { static struct irq_chip intel_mid_irqchip = {
.name = "INTEL_MID-GPIO", .name = "INTEL_MID-GPIO",
.irq_mask = intel_mid_irq_mask, .irq_mask = intel_mid_irq_mask,
.irq_unmask = intel_mid_irq_unmask, .irq_unmask = intel_mid_irq_unmask,
.irq_set_type = intel_mid_irq_type, .irq_set_type = intel_mid_irq_type,
.irq_startup = intel_mid_irq_startup,
.irq_shutdown = intel_mid_irq_shutdown,
}; };
static const struct intel_mid_gpio_ddata gpio_lincroft = { static const struct intel_mid_gpio_ddata gpio_lincroft = {
...@@ -275,7 +297,7 @@ static const struct intel_mid_gpio_ddata gpio_tangier = { ...@@ -275,7 +297,7 @@ static const struct intel_mid_gpio_ddata gpio_tangier = {
.chip_irq_type = INTEL_MID_IRQ_TYPE_EDGE, .chip_irq_type = INTEL_MID_IRQ_TYPE_EDGE,
}; };
static DEFINE_PCI_DEVICE_TABLE(intel_gpio_ids) = { static const struct pci_device_id intel_gpio_ids[] = {
{ {
/* Lincroft */ /* Lincroft */
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080f), PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080f),
...@@ -358,8 +380,7 @@ static int intel_gpio_irq_map(struct irq_domain *d, unsigned int irq, ...@@ -358,8 +380,7 @@ static int intel_gpio_irq_map(struct irq_domain *d, unsigned int irq,
{ {
struct intel_mid_gpio *priv = d->host_data; struct intel_mid_gpio *priv = d->host_data;
irq_set_chip_and_handler_name(irq, &intel_mid_irqchip, irq_set_chip_and_handler(irq, &intel_mid_irqchip, handle_simple_irq);
handle_simple_irq, "demux");
irq_set_chip_data(irq, priv); irq_set_chip_data(irq, priv);
irq_set_irq_type(irq, IRQ_TYPE_NONE); irq_set_irq_type(irq, IRQ_TYPE_NONE);
...@@ -418,6 +439,7 @@ static int intel_gpio_probe(struct pci_dev *pdev, ...@@ -418,6 +439,7 @@ static int intel_gpio_probe(struct pci_dev *pdev,
priv->reg_base = pcim_iomap_table(pdev)[0]; priv->reg_base = pcim_iomap_table(pdev)[0];
priv->chip.label = dev_name(&pdev->dev); priv->chip.label = dev_name(&pdev->dev);
priv->chip.dev = &pdev->dev;
priv->chip.request = intel_gpio_request; priv->chip.request = intel_gpio_request;
priv->chip.direction_input = intel_gpio_direction_input; priv->chip.direction_input = intel_gpio_direction_input;
priv->chip.direction_output = intel_gpio_direction_output; priv->chip.direction_output = intel_gpio_direction_output;
...@@ -426,7 +448,7 @@ static int intel_gpio_probe(struct pci_dev *pdev, ...@@ -426,7 +448,7 @@ static int intel_gpio_probe(struct pci_dev *pdev,
priv->chip.to_irq = intel_gpio_to_irq; priv->chip.to_irq = intel_gpio_to_irq;
priv->chip.base = gpio_base; priv->chip.base = gpio_base;
priv->chip.ngpio = ddata->ngpio; priv->chip.ngpio = ddata->ngpio;
priv->chip.can_sleep = 0; priv->chip.can_sleep = false;
priv->pdev = pdev; priv->pdev = pdev;
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
......
...@@ -167,7 +167,7 @@ static int kempld_gpio_probe(struct platform_device *pdev) ...@@ -167,7 +167,7 @@ static int kempld_gpio_probe(struct platform_device *pdev)
chip->label = "gpio-kempld"; chip->label = "gpio-kempld";
chip->owner = THIS_MODULE; chip->owner = THIS_MODULE;
chip->dev = dev; chip->dev = dev;
chip->can_sleep = 1; chip->can_sleep = true;
if (pdata && pdata->gpio_base) if (pdata && pdata->gpio_base)
chip->base = pdata->gpio_base; chip->base = pdata->gpio_base;
else else
......
...@@ -228,7 +228,7 @@ static struct gpio_chip ks8695_gpio_chip = { ...@@ -228,7 +228,7 @@ static struct gpio_chip ks8695_gpio_chip = {
.to_irq = ks8695_gpio_to_irq, .to_irq = ks8695_gpio_to_irq,
.base = 0, .base = 0,
.ngpio = 16, .ngpio = 16,
.can_sleep = 0, .can_sleep = false,
}; };
/* Register the GPIOs */ /* Register the GPIOs */
......
...@@ -25,10 +25,10 @@ ...@@ -25,10 +25,10 @@
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_data/gpio-lpc32xx.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/platform.h> #include <mach/platform.h>
#include <mach/gpio-lpc32xx.h>
#include <mach/irqs.h> #include <mach/irqs.h>
#define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000) #define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000)
...@@ -448,7 +448,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { ...@@ -448,7 +448,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
.base = LPC32XX_GPIO_P0_GRP, .base = LPC32XX_GPIO_P0_GRP,
.ngpio = LPC32XX_GPIO_P0_MAX, .ngpio = LPC32XX_GPIO_P0_MAX,
.names = gpio_p0_names, .names = gpio_p0_names,
.can_sleep = 0, .can_sleep = false,
}, },
.gpio_grp = &gpio_grp_regs_p0, .gpio_grp = &gpio_grp_regs_p0,
}, },
...@@ -464,7 +464,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { ...@@ -464,7 +464,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
.base = LPC32XX_GPIO_P1_GRP, .base = LPC32XX_GPIO_P1_GRP,
.ngpio = LPC32XX_GPIO_P1_MAX, .ngpio = LPC32XX_GPIO_P1_MAX,
.names = gpio_p1_names, .names = gpio_p1_names,
.can_sleep = 0, .can_sleep = false,
}, },
.gpio_grp = &gpio_grp_regs_p1, .gpio_grp = &gpio_grp_regs_p1,
}, },
...@@ -479,7 +479,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { ...@@ -479,7 +479,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
.base = LPC32XX_GPIO_P2_GRP, .base = LPC32XX_GPIO_P2_GRP,
.ngpio = LPC32XX_GPIO_P2_MAX, .ngpio = LPC32XX_GPIO_P2_MAX,
.names = gpio_p2_names, .names = gpio_p2_names,
.can_sleep = 0, .can_sleep = false,
}, },
.gpio_grp = &gpio_grp_regs_p2, .gpio_grp = &gpio_grp_regs_p2,
}, },
...@@ -495,7 +495,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { ...@@ -495,7 +495,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
.base = LPC32XX_GPIO_P3_GRP, .base = LPC32XX_GPIO_P3_GRP,
.ngpio = LPC32XX_GPIO_P3_MAX, .ngpio = LPC32XX_GPIO_P3_MAX,
.names = gpio_p3_names, .names = gpio_p3_names,
.can_sleep = 0, .can_sleep = false,
}, },
.gpio_grp = &gpio_grp_regs_p3, .gpio_grp = &gpio_grp_regs_p3,
}, },
...@@ -509,7 +509,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { ...@@ -509,7 +509,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
.base = LPC32XX_GPI_P3_GRP, .base = LPC32XX_GPI_P3_GRP,
.ngpio = LPC32XX_GPI_P3_MAX, .ngpio = LPC32XX_GPI_P3_MAX,
.names = gpi_p3_names, .names = gpi_p3_names,
.can_sleep = 0, .can_sleep = false,
}, },
.gpio_grp = &gpio_grp_regs_p3, .gpio_grp = &gpio_grp_regs_p3,
}, },
...@@ -523,7 +523,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { ...@@ -523,7 +523,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
.base = LPC32XX_GPO_P3_GRP, .base = LPC32XX_GPO_P3_GRP,
.ngpio = LPC32XX_GPO_P3_MAX, .ngpio = LPC32XX_GPO_P3_MAX,
.names = gpo_p3_names, .names = gpo_p3_names,
.can_sleep = 0, .can_sleep = false,
}, },
.gpio_grp = &gpio_grp_regs_p3, .gpio_grp = &gpio_grp_regs_p3,
}, },
......
...@@ -301,6 +301,26 @@ static void lp_irq_disable(struct irq_data *d) ...@@ -301,6 +301,26 @@ static void lp_irq_disable(struct irq_data *d)
spin_unlock_irqrestore(&lg->lock, flags); spin_unlock_irqrestore(&lg->lock, flags);
} }
static unsigned int lp_irq_startup(struct irq_data *d)
{
struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
if (gpio_lock_as_irq(&lg->chip, irqd_to_hwirq(d)))
dev_err(lg->chip.dev,
"unable to lock HW IRQ %lu for IRQ\n",
irqd_to_hwirq(d));
lp_irq_enable(d);
return 0;
}
static void lp_irq_shutdown(struct irq_data *d)
{
struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
lp_irq_disable(d);
gpio_unlock_as_irq(&lg->chip, irqd_to_hwirq(d));
}
static struct irq_chip lp_irqchip = { static struct irq_chip lp_irqchip = {
.name = "LP-GPIO", .name = "LP-GPIO",
.irq_mask = lp_irq_mask, .irq_mask = lp_irq_mask,
...@@ -308,6 +328,8 @@ static struct irq_chip lp_irqchip = { ...@@ -308,6 +328,8 @@ static struct irq_chip lp_irqchip = {
.irq_enable = lp_irq_enable, .irq_enable = lp_irq_enable,
.irq_disable = lp_irq_disable, .irq_disable = lp_irq_disable,
.irq_set_type = lp_irq_type, .irq_set_type = lp_irq_type,
.irq_startup = lp_irq_startup,
.irq_shutdown = lp_irq_shutdown,
.flags = IRQCHIP_SKIP_SET_WAKE, .flags = IRQCHIP_SKIP_SET_WAKE,
}; };
...@@ -331,8 +353,7 @@ static int lp_gpio_irq_map(struct irq_domain *d, unsigned int irq, ...@@ -331,8 +353,7 @@ static int lp_gpio_irq_map(struct irq_domain *d, unsigned int irq,
{ {
struct lp_gpio *lg = d->host_data; struct lp_gpio *lg = d->host_data;
irq_set_chip_and_handler_name(irq, &lp_irqchip, handle_simple_irq, irq_set_chip_and_handler(irq, &lp_irqchip, handle_simple_irq);
"demux");
irq_set_chip_data(irq, lg); irq_set_chip_data(irq, lg);
irq_set_irq_type(irq, IRQ_TYPE_NONE); irq_set_irq_type(irq, IRQ_TYPE_NONE);
...@@ -392,7 +413,7 @@ static int lp_gpio_probe(struct platform_device *pdev) ...@@ -392,7 +413,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
gc->set = lp_gpio_set; gc->set = lp_gpio_set;
gc->base = -1; gc->base = -1;
gc->ngpio = LP_NUM_GPIO; gc->ngpio = LP_NUM_GPIO;
gc->can_sleep = 0; gc->can_sleep = false;
gc->dev = dev; gc->dev = dev;
/* set up interrupts */ /* set up interrupts */
...@@ -438,6 +459,7 @@ static const struct dev_pm_ops lp_gpio_pm_ops = { ...@@ -438,6 +459,7 @@ static const struct dev_pm_ops lp_gpio_pm_ops = {
static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = { static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = {
{ "INT33C7", 0 }, { "INT33C7", 0 },
{ "INT3437", 0 },
{ } { }
}; };
MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match); MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match);
...@@ -469,4 +491,15 @@ static int __init lp_gpio_init(void) ...@@ -469,4 +491,15 @@ static int __init lp_gpio_init(void)
return platform_driver_register(&lp_gpio_driver); return platform_driver_register(&lp_gpio_driver);
} }
static void __exit lp_gpio_exit(void)
{
platform_driver_unregister(&lp_gpio_driver);
}
subsys_initcall(lp_gpio_init); subsys_initcall(lp_gpio_init);
module_exit(lp_gpio_exit);
MODULE_AUTHOR("Mathias Nyman (Intel)");
MODULE_DESCRIPTION("GPIO interface for Intel Lynxpoint");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:lp_gpio");
...@@ -188,7 +188,7 @@ int __max730x_probe(struct max7301 *ts) ...@@ -188,7 +188,7 @@ int __max730x_probe(struct max7301 *ts)
ts->chip.set = max7301_set; ts->chip.set = max7301_set;
ts->chip.ngpio = PIN_NUMBER; ts->chip.ngpio = PIN_NUMBER;
ts->chip.can_sleep = 1; ts->chip.can_sleep = true;
ts->chip.dev = dev; ts->chip.dev = dev;
ts->chip.owner = THIS_MODULE; ts->chip.owner = THIS_MODULE;
...@@ -220,7 +220,6 @@ int __max730x_probe(struct max7301 *ts) ...@@ -220,7 +220,6 @@ int __max730x_probe(struct max7301 *ts)
return ret; return ret;
exit_destroy: exit_destroy:
dev_set_drvdata(dev, NULL);
mutex_destroy(&ts->lock); mutex_destroy(&ts->lock);
return ret; return ret;
} }
...@@ -234,8 +233,6 @@ int __max730x_remove(struct device *dev) ...@@ -234,8 +233,6 @@ int __max730x_remove(struct device *dev)
if (ts == NULL) if (ts == NULL)
return -ENODEV; return -ENODEV;
dev_set_drvdata(dev, NULL);
/* Power down the chip and disable IRQ output */ /* Power down the chip and disable IRQ output */
ts->write(dev, 0x04, 0x00); ts->write(dev, 0x04, 0x00);
......
...@@ -564,7 +564,7 @@ static int max732x_setup_gpio(struct max732x_chip *chip, ...@@ -564,7 +564,7 @@ static int max732x_setup_gpio(struct max732x_chip *chip,
gc->set = max732x_gpio_set_value; gc->set = max732x_gpio_set_value;
} }
gc->get = max732x_gpio_get_value; gc->get = max732x_gpio_get_value;
gc->can_sleep = 1; gc->can_sleep = true;
gc->base = gpio_start; gc->base = gpio_start;
gc->ngpio = port; gc->ngpio = port;
......
...@@ -115,7 +115,7 @@ static int mc33880_probe(struct spi_device *spi) ...@@ -115,7 +115,7 @@ static int mc33880_probe(struct spi_device *spi)
mc->chip.set = mc33880_set; mc->chip.set = mc33880_set;
mc->chip.base = pdata->base; mc->chip.base = pdata->base;
mc->chip.ngpio = PIN_NUMBER; mc->chip.ngpio = PIN_NUMBER;
mc->chip.can_sleep = 1; mc->chip.can_sleep = true;
mc->chip.dev = &spi->dev; mc->chip.dev = &spi->dev;
mc->chip.owner = THIS_MODULE; mc->chip.owner = THIS_MODULE;
......
...@@ -102,7 +102,7 @@ static int mc9s08dz60_probe(struct i2c_client *client, ...@@ -102,7 +102,7 @@ static int mc9s08dz60_probe(struct i2c_client *client,
mc9s->chip.dev = &client->dev; mc9s->chip.dev = &client->dev;
mc9s->chip.owner = THIS_MODULE; mc9s->chip.owner = THIS_MODULE;
mc9s->chip.ngpio = GPIO_NUM; mc9s->chip.ngpio = GPIO_NUM;
mc9s->chip.can_sleep = 1; mc9s->chip.can_sleep = true;
mc9s->chip.get = mc9s08dz60_get_value; mc9s->chip.get = mc9s08dz60_get_value;
mc9s->chip.set = mc9s08dz60_set_value; mc9s->chip.set = mc9s08dz60_set_value;
mc9s->chip.direction_output = mc9s08dz60_direction_output; mc9s->chip.direction_output = mc9s08dz60_direction_output;
......
/* /*
* MCP23S08 SPI/GPIO gpio expander driver * MCP23S08 SPI/I2C GPIO gpio expander driver
*
* The inputs and outputs of the mcp23s08, mcp23s17, mcp23008 and mcp23017 are
* supported.
* For the I2C versions of the chips (mcp23008 and mcp23017) generation of
* interrupts is also supported.
* The hardware of the SPI versions of the chips (mcp23s08 and mcp23s17) is
* also capable of generating interrupts, but the linux driver does not
* support that yet.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -12,7 +20,8 @@ ...@@ -12,7 +20,8 @@
#include <linux/spi/mcp23s08.h> #include <linux/spi/mcp23s08.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <linux/of.h> #include <linux/interrupt.h>
#include <linux/of_irq.h>
#include <linux/of_device.h> #include <linux/of_device.h>
/** /**
...@@ -34,6 +43,7 @@ ...@@ -34,6 +43,7 @@
#define MCP_DEFVAL 0x03 #define MCP_DEFVAL 0x03
#define MCP_INTCON 0x04 #define MCP_INTCON 0x04
#define MCP_IOCON 0x05 #define MCP_IOCON 0x05
# define IOCON_MIRROR (1 << 6)
# define IOCON_SEQOP (1 << 5) # define IOCON_SEQOP (1 << 5)
# define IOCON_HAEN (1 << 3) # define IOCON_HAEN (1 << 3)
# define IOCON_ODR (1 << 2) # define IOCON_ODR (1 << 2)
...@@ -57,8 +67,14 @@ struct mcp23s08 { ...@@ -57,8 +67,14 @@ struct mcp23s08 {
u8 addr; u8 addr;
u16 cache[11]; u16 cache[11];
u16 irq_rise;
u16 irq_fall;
int irq;
bool irq_controller;
/* lock protects the cached values */ /* lock protects the cached values */
struct mutex lock; struct mutex lock;
struct mutex irq_lock;
struct irq_domain *irq_domain;
struct gpio_chip chip; struct gpio_chip chip;
...@@ -77,6 +93,11 @@ struct mcp23s08_driver_data { ...@@ -77,6 +93,11 @@ struct mcp23s08_driver_data {
struct mcp23s08 chip[]; struct mcp23s08 chip[];
}; };
/* This lock class tells lockdep that GPIO irqs are in a different
* category than their parents, so it won't report false recursion.
*/
static struct lock_class_key gpio_lock_class;
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
#if IS_ENABLED(CONFIG_I2C) #if IS_ENABLED(CONFIG_I2C)
...@@ -315,6 +336,195 @@ mcp23s08_direction_output(struct gpio_chip *chip, unsigned offset, int value) ...@@ -315,6 +336,195 @@ mcp23s08_direction_output(struct gpio_chip *chip, unsigned offset, int value)
return status; return status;
} }
/*----------------------------------------------------------------------*/
static irqreturn_t mcp23s08_irq(int irq, void *data)
{
struct mcp23s08 *mcp = data;
int intcap, intf, i;
unsigned int child_irq;
mutex_lock(&mcp->lock);
intf = mcp->ops->read(mcp, MCP_INTF);
if (intf < 0) {
mutex_unlock(&mcp->lock);
return IRQ_HANDLED;
}
mcp->cache[MCP_INTF] = intf;
intcap = mcp->ops->read(mcp, MCP_INTCAP);
if (intcap < 0) {
mutex_unlock(&mcp->lock);
return IRQ_HANDLED;
}
mcp->cache[MCP_INTCAP] = intcap;
mutex_unlock(&mcp->lock);
for (i = 0; i < mcp->chip.ngpio; i++) {
if ((BIT(i) & mcp->cache[MCP_INTF]) &&
((BIT(i) & intcap & mcp->irq_rise) ||
(mcp->irq_fall & ~intcap & BIT(i)))) {
child_irq = irq_find_mapping(mcp->irq_domain, i);
handle_nested_irq(child_irq);
}
}
return IRQ_HANDLED;
}
static int mcp23s08_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct mcp23s08 *mcp = container_of(chip, struct mcp23s08, chip);
return irq_find_mapping(mcp->irq_domain, offset);
}
static void mcp23s08_irq_mask(struct irq_data *data)
{
struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);
unsigned int pos = data->hwirq;
mcp->cache[MCP_GPINTEN] &= ~BIT(pos);
}
static void mcp23s08_irq_unmask(struct irq_data *data)
{
struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);
unsigned int pos = data->hwirq;
mcp->cache[MCP_GPINTEN] |= BIT(pos);
}
static int mcp23s08_irq_set_type(struct irq_data *data, unsigned int type)
{
struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);
unsigned int pos = data->hwirq;
int status = 0;
if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
mcp->cache[MCP_INTCON] &= ~BIT(pos);
mcp->irq_rise |= BIT(pos);
mcp->irq_fall |= BIT(pos);
} else if (type & IRQ_TYPE_EDGE_RISING) {
mcp->cache[MCP_INTCON] &= ~BIT(pos);
mcp->irq_rise |= BIT(pos);
mcp->irq_fall &= ~BIT(pos);
} else if (type & IRQ_TYPE_EDGE_FALLING) {
mcp->cache[MCP_INTCON] &= ~BIT(pos);
mcp->irq_rise &= ~BIT(pos);
mcp->irq_fall |= BIT(pos);
} else
return -EINVAL;
return status;
}
static void mcp23s08_irq_bus_lock(struct irq_data *data)
{
struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);
mutex_lock(&mcp->irq_lock);
}
static void mcp23s08_irq_bus_unlock(struct irq_data *data)
{
struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);
mutex_lock(&mcp->lock);
mcp->ops->write(mcp, MCP_GPINTEN, mcp->cache[MCP_GPINTEN]);
mcp->ops->write(mcp, MCP_DEFVAL, mcp->cache[MCP_DEFVAL]);
mcp->ops->write(mcp, MCP_INTCON, mcp->cache[MCP_INTCON]);
mutex_unlock(&mcp->lock);
mutex_unlock(&mcp->irq_lock);
}
static unsigned int mcp23s08_irq_startup(struct irq_data *data)
{
struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);
if (gpio_lock_as_irq(&mcp->chip, data->hwirq))
dev_err(mcp->chip.dev,
"unable to lock HW IRQ %lu for IRQ usage\n",
data->hwirq);
mcp23s08_irq_unmask(data);
return 0;
}
static void mcp23s08_irq_shutdown(struct irq_data *data)
{
struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);
mcp23s08_irq_mask(data);
gpio_unlock_as_irq(&mcp->chip, data->hwirq);
}
static struct irq_chip mcp23s08_irq_chip = {
.name = "gpio-mcp23xxx",
.irq_mask = mcp23s08_irq_mask,
.irq_unmask = mcp23s08_irq_unmask,
.irq_set_type = mcp23s08_irq_set_type,
.irq_bus_lock = mcp23s08_irq_bus_lock,
.irq_bus_sync_unlock = mcp23s08_irq_bus_unlock,
.irq_startup = mcp23s08_irq_startup,
.irq_shutdown = mcp23s08_irq_shutdown,
};
static int mcp23s08_irq_setup(struct mcp23s08 *mcp)
{
struct gpio_chip *chip = &mcp->chip;
int err, irq, j;
mutex_init(&mcp->irq_lock);
mcp->irq_domain = irq_domain_add_linear(chip->of_node, chip->ngpio,
&irq_domain_simple_ops, mcp);
if (!mcp->irq_domain)
return -ENODEV;
err = devm_request_threaded_irq(chip->dev, mcp->irq, NULL, mcp23s08_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
dev_name(chip->dev), mcp);
if (err != 0) {
dev_err(chip->dev, "unable to request IRQ#%d: %d\n",
mcp->irq, err);
return err;
}
chip->to_irq = mcp23s08_gpio_to_irq;
for (j = 0; j < mcp->chip.ngpio; j++) {
irq = irq_create_mapping(mcp->irq_domain, j);
irq_set_lockdep_class(irq, &gpio_lock_class);
irq_set_chip_data(irq, mcp);
irq_set_chip(irq, &mcp23s08_irq_chip);
irq_set_nested_thread(irq, true);
#ifdef CONFIG_ARM
set_irq_flags(irq, IRQF_VALID);
#else
irq_set_noprobe(irq);
#endif
}
return 0;
}
static void mcp23s08_irq_teardown(struct mcp23s08 *mcp)
{
unsigned int irq, i;
free_irq(mcp->irq, mcp);
for (i = 0; i < mcp->chip.ngpio; i++) {
irq = irq_find_mapping(mcp->irq_domain, i);
if (irq > 0)
irq_dispose_mapping(irq);
}
irq_domain_remove(mcp->irq_domain);
}
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
...@@ -370,10 +580,11 @@ static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip) ...@@ -370,10 +580,11 @@ static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip)
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
void *data, unsigned addr, void *data, unsigned addr, unsigned type,
unsigned type, unsigned base, unsigned pullups) unsigned base, unsigned pullups)
{ {
int status; int status;
bool mirror = false;
mutex_init(&mcp->lock); mutex_init(&mcp->lock);
...@@ -425,20 +636,32 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, ...@@ -425,20 +636,32 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
} }
mcp->chip.base = base; mcp->chip.base = base;
mcp->chip.can_sleep = 1; mcp->chip.can_sleep = true;
mcp->chip.dev = dev; mcp->chip.dev = dev;
mcp->chip.owner = THIS_MODULE; mcp->chip.owner = THIS_MODULE;
/* verify MCP_IOCON.SEQOP = 0, so sequential reads work, /* verify MCP_IOCON.SEQOP = 0, so sequential reads work,
* and MCP_IOCON.HAEN = 1, so we work with all chips. * and MCP_IOCON.HAEN = 1, so we work with all chips.
*/ */
status = mcp->ops->read(mcp, MCP_IOCON); status = mcp->ops->read(mcp, MCP_IOCON);
if (status < 0) if (status < 0)
goto fail; goto fail;
if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN)) {
mcp->irq_controller = of_property_read_bool(mcp->chip.of_node,
"interrupt-controller");
if (mcp->irq && mcp->irq_controller && (type == MCP_TYPE_017))
mirror = of_property_read_bool(mcp->chip.of_node,
"microchip,irq-mirror");
if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror) {
/* mcp23s17 has IOCON twice, make sure they are in sync */ /* mcp23s17 has IOCON twice, make sure they are in sync */
status &= ~(IOCON_SEQOP | (IOCON_SEQOP << 8)); status &= ~(IOCON_SEQOP | (IOCON_SEQOP << 8));
status |= IOCON_HAEN | (IOCON_HAEN << 8); status |= IOCON_HAEN | (IOCON_HAEN << 8);
status &= ~(IOCON_INTPOL | (IOCON_INTPOL << 8));
if (mirror)
status |= IOCON_MIRROR | (IOCON_MIRROR << 8);
status = mcp->ops->write(mcp, MCP_IOCON, status); status = mcp->ops->write(mcp, MCP_IOCON, status);
if (status < 0) if (status < 0)
goto fail; goto fail;
...@@ -470,6 +693,16 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, ...@@ -470,6 +693,16 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
} }
status = gpiochip_add(&mcp->chip); status = gpiochip_add(&mcp->chip);
if (status < 0)
goto fail;
if (mcp->irq && mcp->irq_controller) {
status = mcp23s08_irq_setup(mcp);
if (status) {
mcp23s08_irq_teardown(mcp);
goto fail;
}
}
fail: fail:
if (status < 0) if (status < 0)
dev_dbg(dev, "can't setup chip %d, --> %d\n", dev_dbg(dev, "can't setup chip %d, --> %d\n",
...@@ -546,6 +779,7 @@ static int mcp230xx_probe(struct i2c_client *client, ...@@ -546,6 +779,7 @@ static int mcp230xx_probe(struct i2c_client *client,
if (match || !pdata) { if (match || !pdata) {
base = -1; base = -1;
pullups = 0; pullups = 0;
client->irq = irq_of_parse_and_map(client->dev.of_node, 0);
} else { } else {
if (!gpio_is_valid(pdata->base)) { if (!gpio_is_valid(pdata->base)) {
dev_dbg(&client->dev, "invalid platform data\n"); dev_dbg(&client->dev, "invalid platform data\n");
...@@ -559,6 +793,7 @@ static int mcp230xx_probe(struct i2c_client *client, ...@@ -559,6 +793,7 @@ static int mcp230xx_probe(struct i2c_client *client,
if (!mcp) if (!mcp)
return -ENOMEM; return -ENOMEM;
mcp->irq = client->irq;
status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr, status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr,
id->driver_data, base, pullups); id->driver_data, base, pullups);
if (status) if (status)
...@@ -579,6 +814,9 @@ static int mcp230xx_remove(struct i2c_client *client) ...@@ -579,6 +814,9 @@ static int mcp230xx_remove(struct i2c_client *client)
struct mcp23s08 *mcp = i2c_get_clientdata(client); struct mcp23s08 *mcp = i2c_get_clientdata(client);
int status; int status;
if (client->irq && mcp->irq_controller)
mcp23s08_irq_teardown(mcp);
status = gpiochip_remove(&mcp->chip); status = gpiochip_remove(&mcp->chip);
if (status == 0) if (status == 0)
kfree(mcp); kfree(mcp);
...@@ -640,7 +878,7 @@ static int mcp23s08_probe(struct spi_device *spi) ...@@ -640,7 +878,7 @@ static int mcp23s08_probe(struct spi_device *spi)
match = of_match_device(of_match_ptr(mcp23s08_spi_of_match), &spi->dev); match = of_match_device(of_match_ptr(mcp23s08_spi_of_match), &spi->dev);
if (match) { if (match) {
type = (int)match->data; type = (int)(uintptr_t)match->data;
status = of_property_read_u32(spi->dev.of_node, status = of_property_read_u32(spi->dev.of_node,
"microchip,spi-present-mask", &spi_present_mask); "microchip,spi-present-mask", &spi_present_mask);
if (status) { if (status) {
......
...@@ -242,7 +242,7 @@ static void ioh_gpio_setup(struct ioh_gpio *chip, int num_port) ...@@ -242,7 +242,7 @@ static void ioh_gpio_setup(struct ioh_gpio *chip, int num_port)
gpio->dbg_show = NULL; gpio->dbg_show = NULL;
gpio->base = -1; gpio->base = -1;
gpio->ngpio = num_port; gpio->ngpio = num_port;
gpio->can_sleep = 0; gpio->can_sleep = false;
gpio->to_irq = ioh_gpio_to_irq; gpio->to_irq = ioh_gpio_to_irq;
} }
...@@ -596,7 +596,7 @@ static int ioh_gpio_resume(struct pci_dev *pdev) ...@@ -596,7 +596,7 @@ static int ioh_gpio_resume(struct pci_dev *pdev)
#define ioh_gpio_resume NULL #define ioh_gpio_resume NULL
#endif #endif
static DEFINE_PCI_DEVICE_TABLE(ioh_gpio_pcidev_id) = { static const struct pci_device_id ioh_gpio_pcidev_id[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x802E) }, { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x802E) },
{ 0, } { 0, }
}; };
......
/*
* MOXA ART SoCs GPIO driver.
*
* Copyright (C) 2013 Jonas Jensen
*
* Jonas Jensen <jonas.jensen@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/err.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/bitops.h>
#define GPIO_DATA_OUT 0x00
#define GPIO_DATA_IN 0x04
#define GPIO_PIN_DIRECTION 0x08
struct moxart_gpio_chip {
struct gpio_chip gpio;
void __iomem *base;
};
static inline struct moxart_gpio_chip *to_moxart_gpio(struct gpio_chip *chip)
{
return container_of(chip, struct moxart_gpio_chip, gpio);
}
static int moxart_gpio_request(struct gpio_chip *chip, unsigned offset)
{
return pinctrl_request_gpio(offset);
}
static void moxart_gpio_free(struct gpio_chip *chip, unsigned offset)
{
pinctrl_free_gpio(offset);
}
static int moxart_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
struct moxart_gpio_chip *gc = to_moxart_gpio(chip);
void __iomem *ioaddr = gc->base + GPIO_PIN_DIRECTION;
writel(readl(ioaddr) & ~BIT(offset), ioaddr);
return 0;
}
static int moxart_gpio_direction_output(struct gpio_chip *chip,
unsigned offset, int value)
{
struct moxart_gpio_chip *gc = to_moxart_gpio(chip);
void __iomem *ioaddr = gc->base + GPIO_PIN_DIRECTION;
writel(readl(ioaddr) | BIT(offset), ioaddr);
return 0;
}
static void moxart_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct moxart_gpio_chip *gc = to_moxart_gpio(chip);
void __iomem *ioaddr = gc->base + GPIO_DATA_OUT;
u32 reg = readl(ioaddr);
if (value)
reg = reg | BIT(offset);
else
reg = reg & ~BIT(offset);
writel(reg, ioaddr);
}
static int moxart_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct moxart_gpio_chip *gc = to_moxart_gpio(chip);
u32 ret = readl(gc->base + GPIO_PIN_DIRECTION);
if (ret & BIT(offset))
return !!(readl(gc->base + GPIO_DATA_OUT) & BIT(offset));
else
return !!(readl(gc->base + GPIO_DATA_IN) & BIT(offset));
}
static struct gpio_chip moxart_template_chip = {
.label = "moxart-gpio",
.request = moxart_gpio_request,
.free = moxart_gpio_free,
.direction_input = moxart_gpio_direction_input,
.direction_output = moxart_gpio_direction_output,
.set = moxart_gpio_set,
.get = moxart_gpio_get,
.ngpio = 32,
.owner = THIS_MODULE,
};
static int moxart_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct resource *res;
struct moxart_gpio_chip *mgc;
int ret;
mgc = devm_kzalloc(dev, sizeof(*mgc), GFP_KERNEL);
if (!mgc) {
dev_err(dev, "can't allocate GPIO chip container\n");
return -ENOMEM;
}
mgc->gpio = moxart_template_chip;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mgc->base = devm_ioremap_resource(dev, res);
if (IS_ERR(mgc->base))
return PTR_ERR(mgc->base);
mgc->gpio.dev = dev;
ret = gpiochip_add(&mgc->gpio);
if (ret) {
dev_err(dev, "%s: gpiochip_add failed\n",
dev->of_node->full_name);
return ret;
}
return 0;
}
static const struct of_device_id moxart_gpio_match[] = {
{ .compatible = "moxa,moxart-gpio" },
{ }
};
static struct platform_driver moxart_gpio_driver = {
.driver = {
.name = "moxart-gpio",
.owner = THIS_MODULE,
.of_match_table = moxart_gpio_match,
},
.probe = moxart_gpio_probe,
};
module_platform_driver(moxart_gpio_driver);
MODULE_DESCRIPTION("MOXART GPIO chip driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jonas Jensen <jonas.jensen@gmail.com>");
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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