Commit 27c7651a authored by Linus Torvalds's avatar Linus Torvalds

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

Pull GPIO updates from Linus Walleij:
 "This is the bulk of GPIO changes for the v3.12 series:

   - A new driver for the TZ1090 PDC which is used on the metag
     architecture.

   - A new driver for the Kontron ETX or COMexpress GPIO block.  This is
     found on some ETX x86 devices.

   - A new driver for the Fintek Super-I/O chips, used on some x86
     boards.

   - Added device tree probing on a few select GPIO blocks.

   - Drop the Exynos support from the Samsung GPIO driver.

     The Samsung maintainers have moved over to use the modernized pin
     control driver to provide GPIO for the modern platforms instead.

   - The usual bunch of non-critical fixes and cleanups"

* tag 'gpio-v3.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (36 commits)
  gpio: return -ENOTSUPP if debounce cannot be set
  gpio: improve error path in gpiolib
  gpio: add GPIO support for F71882FG and F71889F
  of: add vendor prefix for Microchip Technology Inc
  gpio: mcp23s08: rename the device tree property
  gpio: samsung: Drop support for Exynos SoCs
  gpio: pcf857x: Remove pdata argument to pcf857x_irq_domain_init()
  gpio: pcf857x: Sort headers alphabetically
  gpio: max7301: Reverting "Do not force SPI speed when using OF Platform"
  gpio: Fix bit masking in Kontron PLD GPIO driver
  gpio: pca953x: fix gpio input on gpio offsets >= 8
  drivers/gpio: simplify use of devm_ioremap_resource
  drivers/gpio/gpio-omap.c: convert comma to semicolon
  gpio-lynxpoint: Fix warning about unbalanced pm_runtime_enable
  gpio: Fix platform driver name in Kontron PLD GPIO driver
  gpio: adnp: Fix segfault if request_threaded_irq fails
  gpio: msm: Staticize local variable 'msm_gpio'
  gpio: gpiolib-of.c: make error message more meaningful by adding the node name and index
  gpio: use dev_get_platdata()
  gpio/mxc: add chained_irq_enter/exit() to mx2_gpio_irq_handler
  ...
parents 8b8a7df9 65d87656
...@@ -3,10 +3,17 @@ Microchip MCP2308/MCP23S08/MCP23017/MCP23S17 driver for ...@@ -3,10 +3,17 @@ Microchip MCP2308/MCP23S08/MCP23017/MCP23S17 driver for
Required properties: Required properties:
- compatible : Should be - compatible : Should be
- "mcp,mcp23s08" for 8 GPIO SPI version - "mcp,mcp23s08" (DEPRECATED) for 8 GPIO SPI version
- "mcp,mcp23s17" for 16 GPIO SPI version - "mcp,mcp23s17" (DEPRECATED) for 16 GPIO SPI version
- "mcp,mcp23008" for 8 GPIO I2C version or - "mcp,mcp23008" (DEPRECATED) for 8 GPIO I2C version or
- "mcp,mcp23017" for 16 GPIO I2C version of the chip - "mcp,mcp23017" (DEPRECATED) for 16 GPIO I2C version of the chip
- "microchip,mcp23s08" for 8 GPIO SPI version
- "microchip,mcp23s17" for 16 GPIO SPI version
- "microchip,mcp23008" for 8 GPIO I2C version or
- "microchip,mcp23017" for 16 GPIO I2C version of the chip
NOTE: Do not use the old mcp prefix any more. It is deprecated and will be
removed.
- #gpio-cells : Should be two. - #gpio-cells : Should be two.
- first cell is the pin number - first cell is the pin number
- second cell is used to specify flags. Flags are currently unused. - second cell is used to specify flags. Flags are currently unused.
...@@ -15,10 +22,11 @@ Required properties: ...@@ -15,10 +22,11 @@ Required properties:
SPI uses this to specify the chipselect line which the chip is SPI uses this to specify the chipselect line which the chip is
connected to. The driver and the SPI variant of the chip support connected to. The driver and the SPI variant of the chip support
multiple chips on the same chipselect. Have a look at multiple chips on the same chipselect. Have a look at
mcp,spi-present-mask below. microchip,spi-present-mask below.
Required device specific properties (only for SPI chips): Required device specific properties (only for SPI chips):
- mcp,spi-present-mask : This is a present flag, that makes only sense for SPI - mcp,spi-present-mask (DEPRECATED)
- microchip,spi-present-mask : This is a present flag, that makes only sense for SPI
chips - as the name suggests. Multiple SPI chips can share the same chips - as the name suggests. Multiple SPI chips can share the same
SPI chipselect. Set a bit in bit0-7 in this mask to 1 if there is a SPI chipselect. Set a bit in bit0-7 in this mask to 1 if there is a
chip connected with the corresponding spi address set. For example if chip connected with the corresponding spi address set. For example if
...@@ -26,11 +34,13 @@ Required device specific properties (only for SPI chips): ...@@ -26,11 +34,13 @@ Required device specific properties (only for SPI chips):
which is 0x08. mcp23s08 chip variant only supports bits 0-3. It is not which is 0x08. mcp23s08 chip variant only supports bits 0-3. It is not
possible to mix mcp23s08 and mcp23s17 on the same chipselect. Set at possible to mix mcp23s08 and mcp23s17 on the same chipselect. Set at
least one bit to 1 for SPI chips. least one bit to 1 for SPI chips.
NOTE: Do not use the old mcp prefix any more. It is deprecated and will be
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: Example I2C:
gpiom1: gpio@20 { gpiom1: gpio@20 {
compatible = "mcp,mcp23017"; compatible = "microchip,mcp23017";
gpio-controller; gpio-controller;
#gpio-cells = <2>; #gpio-cells = <2>;
reg = <0x20>; reg = <0x20>;
...@@ -38,7 +48,7 @@ gpiom1: gpio@20 { ...@@ -38,7 +48,7 @@ gpiom1: gpio@20 {
Example SPI: Example SPI:
gpiom1: gpio@0 { gpiom1: gpio@0 {
compatible = "mcp,mcp23s17"; compatible = "microchip,mcp23s17";
gpio-controller; gpio-controller;
#gpio-cells = <2>; #gpio-cells = <2>;
spi-present-mask = <0x01>; spi-present-mask = <0x01>;
......
Palmas GPIO controller bindings
Required properties:
- compatible:
- "ti,palams-gpio" for palma series of the GPIO controller
- "ti,tps80036-gpio" for Palma series device TPS80036.
- "ti,tps65913-gpio" for palma series device TPS65913.
- "ti,tps65914-gpio" for palma series device TPS65914.
- #gpio-cells : Should be two.
- first cell is the gpio pin number
- second cell is used to specify the gpio polarity:
0 = active high
1 = active low
- gpio-controller : Marks the device node as a GPIO controller.
Note: This gpio node will be sub node of palmas node.
Example:
palmas: tps65913@58 {
:::::::::::
palmas_gpio: palmas_gpio {
compatible = "ti,palmas-gpio";
gpio-controller;
#gpio-cells = <2>;
};
:::::::::::
};
ImgTec TZ1090 PDC GPIO Controller
Required properties:
- compatible: Compatible property value should be "img,tz1090-pdc-gpio".
- reg: Physical base address of the controller and length of memory mapped
region. This starts at and cover the SOC_GPIO_CONTROL registers.
- gpio-controller: Specifies that the node is a gpio controller.
- #gpio-cells: Should be 2. The syntax of the gpio specifier used by client
nodes should have the following values.
<[phandle of the gpio controller node]
[PDC gpio number]
[gpio flags]>
Values for gpio specifier:
- GPIO number: a value in the range 0 to 6.
- GPIO flags: bit field of flags, as defined in <dt-bindings/gpio/gpio.h>.
Only the following flags are supported:
GPIO_ACTIVE_HIGH
GPIO_ACTIVE_LOW
Optional properties:
- gpio-ranges: Mapping to pin controller pins (as described in
Documentation/devicetree/bindings/gpio/gpio.txt)
- interrupts: Individual syswake interrupts (other GPIOs cannot interrupt)
Example:
pdc_gpios: gpio-controller@02006500 {
gpio-controller;
#gpio-cells = <2>;
compatible = "img,tz1090-pdc-gpio";
reg = <0x02006500 0x100>;
interrupt-parent = <&pdc>;
interrupts = <8 IRQ_TYPE_NONE>, /* Syswake 0 */
<9 IRQ_TYPE_NONE>, /* Syswake 1 */
<10 IRQ_TYPE_NONE>; /* Syswake 2 */
gpio-ranges = <&pdc_pinctrl 0 0 7>;
};
ImgTec TZ1090 GPIO Controller
Required properties:
- compatible: Compatible property value should be "img,tz1090-gpio".
- reg: Physical base address of the controller and length of memory mapped
region.
- #address-cells: Should be 1 (for bank subnodes)
- #size-cells: Should be 0 (for bank subnodes)
- Each bank of GPIOs should have a subnode to represent it.
Bank subnode required properties:
- reg: Index of bank in the range 0 to 2.
- gpio-controller: Specifies that the node is a gpio controller.
- #gpio-cells: Should be 2. The syntax of the gpio specifier used by client
nodes should have the following values.
<[phandle of the gpio controller node]
[gpio number within the gpio bank]
[gpio flags]>
Values for gpio specifier:
- GPIO number: a value in the range 0 to 29.
- GPIO flags: bit field of flags, as defined in <dt-bindings/gpio/gpio.h>.
Only the following flags are supported:
GPIO_ACTIVE_HIGH
GPIO_ACTIVE_LOW
Bank subnode optional properties:
- gpio-ranges: Mapping to pin controller pins (as described in
Documentation/devicetree/bindings/gpio/gpio.txt)
- interrupts: Interrupt for the entire bank
- interrupt-controller: Specifies that the node is an interrupt controller
- #interrupt-cells: Should be 2. The syntax of the interrupt specifier used by
client nodes should have the following values.
<[phandle of the interurupt controller]
[gpio number within the gpio bank]
[irq flags]>
Values for irq specifier:
- GPIO number: a value in the range 0 to 29
- IRQ flags: value to describe edge and level triggering, as defined in
<dt-bindings/interrupt-controller/irq.h>. Only the following flags are
supported:
IRQ_TYPE_EDGE_RISING
IRQ_TYPE_EDGE_FALLING
IRQ_TYPE_EDGE_BOTH
IRQ_TYPE_LEVEL_HIGH
IRQ_TYPE_LEVEL_LOW
Example:
gpios: gpio-controller@02005800 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "img,tz1090-gpio";
reg = <0x02005800 0x90>;
/* bank 0 with an interrupt */
gpios0: bank@0 {
#gpio-cells = <2>;
#interrupt-cells = <2>;
reg = <0>;
interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
gpio-ranges = <&pinctrl 0 0 30>;
interrupt-controller;
};
/* bank 2 without interrupt */
gpios2: bank@2 {
#gpio-cells = <2>;
reg = <2>;
gpio-controller;
gpio-ranges = <&pinctrl 0 60 30>;
};
};
...@@ -10,8 +10,9 @@ Required properties: ...@@ -10,8 +10,9 @@ Required properties:
There're three gpio interrupts in arch-pxa, and they're gpio0, There're three gpio interrupts in arch-pxa, and they're gpio0,
gpio1 and gpio_mux. There're only one gpio interrupt in arch-mmp, gpio1 and gpio_mux. There're only one gpio interrupt in arch-mmp,
gpio_mux. gpio_mux.
- interrupt-name : Should be the name of irq resource. Each interrupt - interrupt-names : Should be the names of irq resources. Each interrupt
binds its interrupt-name. uses its own interrupt name, so there should be as many interrupt names
as referenced interrups.
- interrupt-controller : Identifies the node as an interrupt controller. - interrupt-controller : Identifies the node as an interrupt controller.
- #interrupt-cells: Specifies the number of cells needed to encode an - #interrupt-cells: Specifies the number of cells needed to encode an
interrupt source. interrupt source.
...@@ -24,7 +25,7 @@ Example: ...@@ -24,7 +25,7 @@ Example:
compatible = "marvell,mmp-gpio"; compatible = "marvell,mmp-gpio";
reg = <0xd4019000 0x1000>; reg = <0xd4019000 0x1000>;
interrupts = <49>; interrupts = <49>;
interrupt-name = "gpio_mux"; interrupt-names = "gpio_mux";
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <1>;
interrupt-controller; interrupt-controller;
......
...@@ -23,6 +23,10 @@ Required Properties: ...@@ -23,6 +23,10 @@ Required Properties:
Please refer to gpio.txt in this directory for details of gpio-ranges property Please refer to gpio.txt in this directory for details of gpio-ranges property
and the common GPIO bindings used by client devices. and the common GPIO bindings used by client devices.
The GPIO controller also acts as an interrupt controller. It uses the default
two cells specifier as described in Documentation/devicetree/bindings/
interrupt-controller/interrupts.txt.
Example: R8A7779 (R-Car H1) GPIO controller nodes Example: R8A7779 (R-Car H1) GPIO controller nodes
gpio0: gpio@ffc40000 { gpio0: gpio@ffc40000 {
...@@ -33,6 +37,8 @@ Example: R8A7779 (R-Car H1) GPIO controller nodes ...@@ -33,6 +37,8 @@ Example: R8A7779 (R-Car H1) GPIO controller nodes
#gpio-cells = <2>; #gpio-cells = <2>;
gpio-controller; gpio-controller;
gpio-ranges = <&pfc 0 0 32>; gpio-ranges = <&pfc 0 0 32>;
interrupt-controller;
#interrupt-cells = <2>;
}; };
... ...
gpio6: gpio@ffc46000 { gpio6: gpio@ffc46000 {
...@@ -43,4 +49,6 @@ Example: R8A7779 (R-Car H1) GPIO controller nodes ...@@ -43,4 +49,6 @@ Example: R8A7779 (R-Car H1) GPIO controller nodes
#gpio-cells = <2>; #gpio-cells = <2>;
gpio-controller; gpio-controller;
gpio-ranges = <&pfc 0 192 9>; gpio-ranges = <&pfc 0 192 9>;
interrupt-controller;
#interrupt-cells = <2>;
}; };
...@@ -38,6 +38,7 @@ linux Linux-specific binding ...@@ -38,6 +38,7 @@ linux Linux-specific binding
lsi LSI Corp. (LSI Logic) lsi LSI Corp. (LSI Logic)
marvell Marvell Technology Group Ltd. marvell Marvell Technology Group Ltd.
maxim Maxim Integrated Products maxim Maxim Integrated Products
microchip Microchip Technology Inc.
mosaixtech Mosaix Technologies, Inc. mosaixtech Mosaix Technologies, Inc.
national National Semiconductor national National Semiconductor
nintendo Nintendo nintendo Nintendo
......
...@@ -1320,7 +1320,6 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) ...@@ -1320,7 +1320,6 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained S: Maintained
F: arch/arm/mach-vt8500/ F: arch/arm/mach-vt8500/
F: drivers/clocksource/vt8500_timer.c F: drivers/clocksource/vt8500_timer.c
F: drivers/gpio/gpio-vt8500.c
F: drivers/i2c/busses/i2c-wmt.c F: drivers/i2c/busses/i2c-wmt.c
F: drivers/mmc/host/wmt-sdmmc.c F: drivers/mmc/host/wmt-sdmmc.c
F: drivers/pwm/pwm-vt8500.c F: drivers/pwm/pwm-vt8500.c
......
...@@ -146,6 +146,16 @@ config GPIO_MM_LANTIQ ...@@ -146,6 +146,16 @@ config GPIO_MM_LANTIQ
(EBU) found on Lantiq SoCs. The gpios are output only as they are (EBU) found on Lantiq SoCs. The gpios are output only as they are
created by attaching a 16bit latch to the bus. created by attaching a 16bit latch to the bus.
config GPIO_F7188X
tristate "F71882FG and F71889F GPIO support"
depends on X86
help
This option enables support for GPIOs found on Fintek Super-I/O
chips F71882FG and F71889F.
To compile this driver as a module, choose M here: the module will
be called f7188x-gpio.
config GPIO_MPC5200 config GPIO_MPC5200
def_bool y def_bool y
depends on PPC_MPC52xx depends on PPC_MPC52xx
...@@ -242,6 +252,21 @@ config GPIO_TS5500 ...@@ -242,6 +252,21 @@ config GPIO_TS5500
blocks of the TS-5500: DIO1, DIO2 and the LCD port, and the TS-5600 blocks of the TS-5500: DIO1, DIO2 and the LCD port, and the TS-5600
LCD port. LCD port.
config GPIO_TZ1090
bool "Toumaz Xenif TZ1090 GPIO support"
depends on SOC_TZ1090
select GENERIC_IRQ_CHIP
default y
help
Say yes here to support Toumaz Xenif TZ1090 GPIOs.
config GPIO_TZ1090_PDC
bool "Toumaz Xenif TZ1090 PDC GPIO support"
depends on SOC_TZ1090
default y
help
Say yes here to support Toumaz Xenif TZ1090 PDC GPIOs.
config GPIO_XILINX config GPIO_XILINX
bool "Xilinx GPIO support" bool "Xilinx GPIO support"
depends on PPC_OF || MICROBLAZE || ARCH_ZYNQ depends on PPC_OF || MICROBLAZE || ARCH_ZYNQ
...@@ -676,6 +701,18 @@ config GPIO_UCB1400 ...@@ -676,6 +701,18 @@ config GPIO_UCB1400
This enables support for the Philips UCB1400 GPIO pins. This enables support for the Philips UCB1400 GPIO pins.
The UCB1400 is an AC97 audio codec. The UCB1400 is an AC97 audio codec.
comment "LPC GPIO expanders:"
config GPIO_KEMPLD
tristate "Kontron ETX / COMexpress GPIO"
depends on MFD_KEMPLD
help
This enables support for the PLD GPIO interface on some Kontron ETX
and COMexpress (ETXexpress) modules.
This driver can also be built as a module. If so, the module will be
called gpio-kempld.
comment "MODULbus GPIO expanders:" comment "MODULbus GPIO expanders:"
config GPIO_JANZ_TTL config GPIO_JANZ_TTL
......
...@@ -24,11 +24,13 @@ obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o ...@@ -24,11 +24,13 @@ obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o
obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o
obj-$(CONFIG_GPIO_EM) += gpio-em.o obj-$(CONFIG_GPIO_EM) += gpio-em.o
obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o
obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o
obj-$(CONFIG_GPIO_ICH) += gpio-ich.o obj-$(CONFIG_GPIO_ICH) += gpio-ich.o
obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o
obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o
obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o
obj-$(CONFIG_GPIO_LANGWELL) += gpio-langwell.o obj-$(CONFIG_GPIO_LANGWELL) += gpio-langwell.o
obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o
...@@ -79,6 +81,8 @@ obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o ...@@ -79,6 +81,8 @@ obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o
obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o
obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o
obj-$(CONFIG_GPIO_TZ1090) += gpio-tz1090.o
obj-$(CONFIG_GPIO_TZ1090_PDC) += gpio-tz1090-pdc.o
obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o
obj-$(CONFIG_GPIO_VIPERBOARD) += gpio-viperboard.o obj-$(CONFIG_GPIO_VIPERBOARD) += gpio-viperboard.o
obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o
......
...@@ -129,7 +129,7 @@ static int gen_74x164_probe(struct spi_device *spi) ...@@ -129,7 +129,7 @@ static int gen_74x164_probe(struct spi_device *spi)
if (!chip) if (!chip)
return -ENOMEM; return -ENOMEM;
pdata = spi->dev.platform_data; pdata = dev_get_platdata(&spi->dev);
if (pdata && pdata->base) if (pdata && pdata->base)
chip->gpio_chip.base = pdata->base; chip->gpio_chip.base = pdata->base;
else else
......
...@@ -490,15 +490,11 @@ static int adnp_irq_setup(struct adnp *adnp) ...@@ -490,15 +490,11 @@ static int adnp_irq_setup(struct adnp *adnp)
if (err != 0) { if (err != 0) {
dev_err(chip->dev, "can't request IRQ#%d: %d\n", dev_err(chip->dev, "can't request IRQ#%d: %d\n",
adnp->client->irq, err); adnp->client->irq, err);
goto error; return err;
} }
chip->to_irq = adnp_gpio_to_irq; chip->to_irq = adnp_gpio_to_irq;
return 0; return 0;
error:
irq_domain_remove(adnp->domain);
return err;
} }
static void adnp_irq_teardown(struct adnp *adnp) static void adnp_irq_teardown(struct adnp *adnp)
......
...@@ -89,7 +89,7 @@ static int adp5520_gpio_direction_output(struct gpio_chip *chip, ...@@ -89,7 +89,7 @@ static int adp5520_gpio_direction_output(struct gpio_chip *chip,
static int adp5520_gpio_probe(struct platform_device *pdev) static int adp5520_gpio_probe(struct platform_device *pdev)
{ {
struct adp5520_gpio_platform_data *pdata = pdev->dev.platform_data; struct adp5520_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct adp5520_gpio *dev; struct adp5520_gpio *dev;
struct gpio_chip *gc; struct gpio_chip *gc;
int ret, i, gpios; int ret, i, gpios;
......
...@@ -276,7 +276,8 @@ static irqreturn_t adp5588_irq_handler(int irq, void *devid) ...@@ -276,7 +276,8 @@ static irqreturn_t adp5588_irq_handler(int irq, void *devid)
static int adp5588_irq_setup(struct adp5588_gpio *dev) static int adp5588_irq_setup(struct adp5588_gpio *dev)
{ {
struct i2c_client *client = dev->client; struct i2c_client *client = dev->client;
struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; struct adp5588_gpio_platform_data *pdata =
dev_get_platdata(&client->dev);
unsigned gpio; unsigned gpio;
int ret; int ret;
...@@ -349,7 +350,8 @@ static void adp5588_irq_teardown(struct adp5588_gpio *dev) ...@@ -349,7 +350,8 @@ static void adp5588_irq_teardown(struct adp5588_gpio *dev)
static int adp5588_gpio_probe(struct i2c_client *client, static int adp5588_gpio_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; struct adp5588_gpio_platform_data *pdata =
dev_get_platdata(&client->dev);
struct adp5588_gpio *dev; struct adp5588_gpio *dev;
struct gpio_chip *gc; struct gpio_chip *gc;
int ret, i, revid; int ret, i, revid;
...@@ -440,7 +442,8 @@ static int adp5588_gpio_probe(struct i2c_client *client, ...@@ -440,7 +442,8 @@ static int adp5588_gpio_probe(struct i2c_client *client,
static int adp5588_gpio_remove(struct i2c_client *client) static int adp5588_gpio_remove(struct i2c_client *client)
{ {
struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; struct adp5588_gpio_platform_data *pdata =
dev_get_platdata(&client->dev);
struct adp5588_gpio *dev = i2c_get_clientdata(client); struct adp5588_gpio *dev = i2c_get_clientdata(client);
int ret; int ret;
......
...@@ -97,7 +97,7 @@ static struct gpio_chip template_chip = { ...@@ -97,7 +97,7 @@ static struct gpio_chip template_chip = {
static int arizona_gpio_probe(struct platform_device *pdev) static int arizona_gpio_probe(struct platform_device *pdev)
{ {
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
struct arizona_pdata *pdata = arizona->dev->platform_data; struct arizona_pdata *pdata = dev_get_platdata(arizona->dev);
struct arizona_gpio *arizona_gpio; struct arizona_gpio *arizona_gpio;
int ret; int ret;
......
...@@ -216,7 +216,7 @@ static int da9052_gpio_probe(struct platform_device *pdev) ...@@ -216,7 +216,7 @@ static int da9052_gpio_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
gpio->da9052 = dev_get_drvdata(pdev->dev.parent); gpio->da9052 = dev_get_drvdata(pdev->dev.parent);
pdata = gpio->da9052->dev->platform_data; pdata = dev_get_platdata(gpio->da9052->dev);
gpio->gp = reference_gp; gpio->gp = reference_gp;
if (pdata && pdata->gpio_base) if (pdata && pdata->gpio_base)
......
...@@ -150,7 +150,7 @@ static int da9055_gpio_probe(struct platform_device *pdev) ...@@ -150,7 +150,7 @@ static int da9055_gpio_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
gpio->da9055 = dev_get_drvdata(pdev->dev.parent); gpio->da9055 = dev_get_drvdata(pdev->dev.parent);
pdata = gpio->da9055->dev->platform_data; pdata = dev_get_platdata(gpio->da9055->dev);
gpio->gp = reference_gp; gpio->gp = reference_gp;
if (pdata && pdata->gpio_base) if (pdata && pdata->gpio_base)
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_data/gpio-em.h> #include <linux/platform_data/gpio-em.h>
struct em_gio_priv { struct em_gio_priv {
...@@ -216,6 +217,21 @@ static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset) ...@@ -216,6 +217,21 @@ static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset)
return irq_create_mapping(gpio_to_priv(chip)->irq_domain, offset); return irq_create_mapping(gpio_to_priv(chip)->irq_domain, offset);
} }
static int em_gio_request(struct gpio_chip *chip, unsigned offset)
{
return pinctrl_request_gpio(chip->base + offset);
}
static void em_gio_free(struct gpio_chip *chip, unsigned offset)
{
pinctrl_free_gpio(chip->base + offset);
/* Set the GPIO as an input to ensure that the next GPIO request won't
* drive the GPIO pin as an output.
*/
em_gio_direction_input(chip, offset);
}
static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq, static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw) irq_hw_number_t hw)
{ {
...@@ -237,7 +253,7 @@ static struct irq_domain_ops em_gio_irq_domain_ops = { ...@@ -237,7 +253,7 @@ static struct irq_domain_ops em_gio_irq_domain_ops = {
static int em_gio_probe(struct platform_device *pdev) static int em_gio_probe(struct platform_device *pdev)
{ {
struct gpio_em_config pdata_dt; struct gpio_em_config pdata_dt;
struct gpio_em_config *pdata = pdev->dev.platform_data; struct gpio_em_config *pdata = dev_get_platdata(&pdev->dev);
struct em_gio_priv *p; struct em_gio_priv *p;
struct resource *io[2], *irq[2]; struct resource *io[2], *irq[2];
struct gpio_chip *gpio_chip; struct gpio_chip *gpio_chip;
...@@ -308,6 +324,8 @@ static int em_gio_probe(struct platform_device *pdev) ...@@ -308,6 +324,8 @@ static int em_gio_probe(struct platform_device *pdev)
gpio_chip->direction_output = em_gio_direction_output; gpio_chip->direction_output = em_gio_direction_output;
gpio_chip->set = em_gio_set; gpio_chip->set = em_gio_set;
gpio_chip->to_irq = em_gio_to_irq; gpio_chip->to_irq = em_gio_to_irq;
gpio_chip->request = em_gio_request;
gpio_chip->free = em_gio_free;
gpio_chip->label = name; gpio_chip->label = name;
gpio_chip->owner = THIS_MODULE; gpio_chip->owner = THIS_MODULE;
gpio_chip->base = pdata->gpio_base; gpio_chip->base = pdata->gpio_base;
...@@ -351,6 +369,13 @@ static int em_gio_probe(struct platform_device *pdev) ...@@ -351,6 +369,13 @@ static int em_gio_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to add GPIO controller\n"); dev_err(&pdev->dev, "failed to add GPIO controller\n");
goto err1; goto err1;
} }
if (pdata->pctl_name) {
ret = gpiochip_add_pin_range(gpio_chip, pdata->pctl_name, 0,
gpio_chip->base, gpio_chip->ngpio);
if (ret < 0)
dev_warn(&pdev->dev, "failed to add pin range\n");
}
return 0; return 0;
err1: err1:
......
This diff is collapsed.
...@@ -354,7 +354,7 @@ static int ichx_gpio_probe(struct platform_device *pdev) ...@@ -354,7 +354,7 @@ static int ichx_gpio_probe(struct platform_device *pdev)
{ {
struct resource *res_base, *res_pm; struct resource *res_base, *res_pm;
int err; int err;
struct lpc_ich_info *ich_info = pdev->dev.platform_data; struct lpc_ich_info *ich_info = dev_get_platdata(&pdev->dev);
if (!ich_info) if (!ich_info)
return -ENODEV; return -ENODEV;
......
...@@ -149,7 +149,7 @@ static int ttl_probe(struct platform_device *pdev) ...@@ -149,7 +149,7 @@ static int ttl_probe(struct platform_device *pdev)
struct resource *res; struct resource *res;
int ret; int ret;
pdata = pdev->dev.platform_data; pdata = dev_get_platdata(&pdev->dev);
if (!pdata) { if (!pdata) {
dev_err(dev, "no platform data\n"); dev_err(dev, "no platform data\n");
ret = -ENXIO; ret = -ENXIO;
......
/*
* Kontron PLD GPIO driver
*
* Copyright (c) 2010-2013 Kontron Europe GmbH
* Author: Michael Brunner <michael.brunner@kontron.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License 2 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/mfd/kempld.h>
#define KEMPLD_GPIO_MAX_NUM 16
#define KEMPLD_GPIO_MASK(x) (1 << ((x) % 8))
#define KEMPLD_GPIO_DIR_NUM(x) (0x40 + (x) / 8)
#define KEMPLD_GPIO_LVL_NUM(x) (0x42 + (x) / 8)
#define KEMPLD_GPIO_EVT_LVL_EDGE 0x46
#define KEMPLD_GPIO_IEN 0x4A
struct kempld_gpio_data {
struct gpio_chip chip;
struct kempld_device_data *pld;
};
/*
* Set or clear GPIO bit
* kempld_get_mutex must be called prior to calling this function.
*/
static void kempld_gpio_bitop(struct kempld_device_data *pld,
u8 reg, u8 bit, u8 val)
{
u8 status;
status = kempld_read8(pld, reg);
if (val)
status |= KEMPLD_GPIO_MASK(bit);
else
status &= ~KEMPLD_GPIO_MASK(bit);
kempld_write8(pld, reg, status);
}
static int kempld_gpio_get_bit(struct kempld_device_data *pld, u8 reg, u8 bit)
{
u8 status;
kempld_get_mutex(pld);
status = kempld_read8(pld, reg);
kempld_release_mutex(pld);
return !!(status & KEMPLD_GPIO_MASK(bit));
}
static int kempld_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct kempld_gpio_data *gpio
= container_of(chip, struct kempld_gpio_data, chip);
struct kempld_device_data *pld = gpio->pld;
return kempld_gpio_get_bit(pld, KEMPLD_GPIO_LVL_NUM(offset), offset);
}
static void kempld_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct kempld_gpio_data *gpio
= container_of(chip, struct kempld_gpio_data, chip);
struct kempld_device_data *pld = gpio->pld;
kempld_get_mutex(pld);
kempld_gpio_bitop(pld, KEMPLD_GPIO_LVL_NUM(offset), offset, value);
kempld_release_mutex(pld);
}
static int kempld_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
struct kempld_gpio_data *gpio
= container_of(chip, struct kempld_gpio_data, chip);
struct kempld_device_data *pld = gpio->pld;
kempld_get_mutex(pld);
kempld_gpio_bitop(pld, KEMPLD_GPIO_DIR_NUM(offset), offset, 0);
kempld_release_mutex(pld);
return 0;
}
static int kempld_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
int value)
{
struct kempld_gpio_data *gpio
= container_of(chip, struct kempld_gpio_data, chip);
struct kempld_device_data *pld = gpio->pld;
kempld_get_mutex(pld);
kempld_gpio_bitop(pld, KEMPLD_GPIO_LVL_NUM(offset), offset, value);
kempld_gpio_bitop(pld, KEMPLD_GPIO_DIR_NUM(offset), offset, 1);
kempld_release_mutex(pld);
return 0;
}
static int kempld_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
{
struct kempld_gpio_data *gpio
= container_of(chip, struct kempld_gpio_data, chip);
struct kempld_device_data *pld = gpio->pld;
return kempld_gpio_get_bit(pld, KEMPLD_GPIO_DIR_NUM(offset), offset);
}
static int kempld_gpio_pincount(struct kempld_device_data *pld)
{
u16 evt, evt_back;
kempld_get_mutex(pld);
/* Backup event register as it might be already initialized */
evt_back = kempld_read16(pld, KEMPLD_GPIO_EVT_LVL_EDGE);
/* Clear event register */
kempld_write16(pld, KEMPLD_GPIO_EVT_LVL_EDGE, 0x0000);
/* Read back event register */
evt = kempld_read16(pld, KEMPLD_GPIO_EVT_LVL_EDGE);
/* Restore event register */
kempld_write16(pld, KEMPLD_GPIO_EVT_LVL_EDGE, evt_back);
kempld_release_mutex(pld);
return evt ? __ffs(evt) : 16;
}
static int kempld_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct kempld_device_data *pld = dev_get_drvdata(dev->parent);
struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
struct kempld_gpio_data *gpio;
struct gpio_chip *chip;
int ret;
if (pld->info.spec_major < 2) {
dev_err(dev,
"Driver only supports GPIO devices compatible to PLD spec. rev. 2.0 or higher\n");
return -ENODEV;
}
gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
if (gpio == NULL)
return -ENOMEM;
gpio->pld = pld;
platform_set_drvdata(pdev, gpio);
chip = &gpio->chip;
chip->label = "gpio-kempld";
chip->owner = THIS_MODULE;
chip->dev = dev;
chip->can_sleep = 1;
if (pdata && pdata->gpio_base)
chip->base = pdata->gpio_base;
else
chip->base = -1;
chip->direction_input = kempld_gpio_direction_input;
chip->direction_output = kempld_gpio_direction_output;
chip->get_direction = kempld_gpio_get_direction;
chip->get = kempld_gpio_get;
chip->set = kempld_gpio_set;
chip->ngpio = kempld_gpio_pincount(pld);
if (chip->ngpio == 0) {
dev_err(dev, "No GPIO pins detected\n");
return -ENODEV;
}
ret = gpiochip_add(chip);
if (ret) {
dev_err(dev, "Could not register GPIO chip\n");
return ret;
}
dev_info(dev, "GPIO functionality initialized with %d pins\n",
chip->ngpio);
return 0;
}
static int kempld_gpio_remove(struct platform_device *pdev)
{
struct kempld_gpio_data *gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&gpio->chip);
}
static struct platform_driver kempld_gpio_driver = {
.driver = {
.name = "kempld-gpio",
.owner = THIS_MODULE,
},
.probe = kempld_gpio_probe,
.remove = kempld_gpio_remove,
};
module_platform_driver(kempld_gpio_driver);
MODULE_DESCRIPTION("KEM PLD GPIO Driver");
MODULE_AUTHOR("Michael Brunner <michael.brunner@kontron.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:gpio-kempld");
...@@ -444,6 +444,7 @@ static int lp_gpio_remove(struct platform_device *pdev) ...@@ -444,6 +444,7 @@ static int lp_gpio_remove(struct platform_device *pdev)
{ {
struct lp_gpio *lg = platform_get_drvdata(pdev); struct lp_gpio *lg = platform_get_drvdata(pdev);
int err; int err;
pm_runtime_disable(&pdev->dev);
err = gpiochip_remove(&lg->chip); err = gpiochip_remove(&lg->chip);
if (err) if (err)
dev_warn(&pdev->dev, "failed to remove gpio_chip.\n"); dev_warn(&pdev->dev, "failed to remove gpio_chip.\n");
......
...@@ -56,7 +56,6 @@ static int max7301_probe(struct spi_device *spi) ...@@ -56,7 +56,6 @@ static int max7301_probe(struct spi_device *spi)
int ret; int ret;
/* bits_per_word cannot be configured in platform data */ /* bits_per_word cannot be configured in platform data */
if (spi->dev.platform_data)
spi->bits_per_word = 16; spi->bits_per_word = 16;
ret = spi_setup(spi); ret = spi_setup(spi);
if (ret < 0) if (ret < 0)
......
...@@ -166,7 +166,7 @@ int __max730x_probe(struct max7301 *ts) ...@@ -166,7 +166,7 @@ int __max730x_probe(struct max7301 *ts)
struct max7301_platform_data *pdata; struct max7301_platform_data *pdata;
int i, ret; int i, ret;
pdata = dev->platform_data; pdata = dev_get_platdata(dev);
mutex_init(&ts->lock); mutex_init(&ts->lock);
dev_set_drvdata(dev, ts); dev_set_drvdata(dev, ts);
......
...@@ -453,7 +453,7 @@ static int max732x_irq_setup(struct max732x_chip *chip, ...@@ -453,7 +453,7 @@ static int max732x_irq_setup(struct max732x_chip *chip,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct i2c_client *client = chip->client; struct i2c_client *client = chip->client;
struct max732x_platform_data *pdata = client->dev.platform_data; struct max732x_platform_data *pdata = dev_get_platdata(&client->dev);
int has_irq = max732x_features[id->driver_data] >> 32; int has_irq = max732x_features[id->driver_data] >> 32;
int ret; int ret;
...@@ -512,7 +512,7 @@ static int max732x_irq_setup(struct max732x_chip *chip, ...@@ -512,7 +512,7 @@ static int max732x_irq_setup(struct max732x_chip *chip,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct i2c_client *client = chip->client; struct i2c_client *client = chip->client;
struct max732x_platform_data *pdata = client->dev.platform_data; struct max732x_platform_data *pdata = dev_get_platdata(&client->dev);
int has_irq = max732x_features[id->driver_data] >> 32; int has_irq = max732x_features[id->driver_data] >> 32;
if (pdata->irq_base && has_irq != INT_NONE) if (pdata->irq_base && has_irq != INT_NONE)
...@@ -583,7 +583,7 @@ static int max732x_probe(struct i2c_client *client, ...@@ -583,7 +583,7 @@ static int max732x_probe(struct i2c_client *client,
uint16_t addr_a, addr_b; uint16_t addr_a, addr_b;
int ret, nr_port; int ret, nr_port;
pdata = client->dev.platform_data; pdata = dev_get_platdata(&client->dev);
if (pdata == NULL) { if (pdata == NULL) {
dev_dbg(&client->dev, "no platform data\n"); dev_dbg(&client->dev, "no platform data\n");
return -EINVAL; return -EINVAL;
...@@ -653,7 +653,7 @@ static int max732x_probe(struct i2c_client *client, ...@@ -653,7 +653,7 @@ static int max732x_probe(struct i2c_client *client,
static int max732x_remove(struct i2c_client *client) static int max732x_remove(struct i2c_client *client)
{ {
struct max732x_platform_data *pdata = client->dev.platform_data; struct max732x_platform_data *pdata = dev_get_platdata(&client->dev);
struct max732x_chip *chip = i2c_get_clientdata(client); struct max732x_chip *chip = i2c_get_clientdata(client);
int ret; int ret;
......
...@@ -86,7 +86,7 @@ static int mc33880_probe(struct spi_device *spi) ...@@ -86,7 +86,7 @@ static int mc33880_probe(struct spi_device *spi)
struct mc33880_platform_data *pdata; struct mc33880_platform_data *pdata;
int ret; int ret;
pdata = spi->dev.platform_data; pdata = dev_get_platdata(&spi->dev);
if (!pdata || !pdata->base) { if (!pdata || !pdata->base) {
dev_dbg(&spi->dev, "incorrect or missing platform data\n"); dev_dbg(&spi->dev, "incorrect or missing platform data\n");
return -EINVAL; return -EINVAL;
......
...@@ -483,10 +483,21 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, ...@@ -483,10 +483,21 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
#ifdef CONFIG_SPI_MASTER #ifdef CONFIG_SPI_MASTER
static struct of_device_id mcp23s08_spi_of_match[] = { static struct of_device_id mcp23s08_spi_of_match[] = {
{ {
.compatible = "mcp,mcp23s08", .data = (void *) MCP_TYPE_S08, .compatible = "microchip,mcp23s08",
.data = (void *) MCP_TYPE_S08,
}, },
{ {
.compatible = "mcp,mcp23s17", .data = (void *) MCP_TYPE_S17, .compatible = "microchip,mcp23s17",
.data = (void *) MCP_TYPE_S17,
},
/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
{
.compatible = "mcp,mcp23s08",
.data = (void *) MCP_TYPE_S08,
},
{
.compatible = "mcp,mcp23s17",
.data = (void *) MCP_TYPE_S17,
}, },
{ }, { },
}; };
...@@ -496,10 +507,21 @@ MODULE_DEVICE_TABLE(of, mcp23s08_spi_of_match); ...@@ -496,10 +507,21 @@ MODULE_DEVICE_TABLE(of, mcp23s08_spi_of_match);
#if IS_ENABLED(CONFIG_I2C) #if IS_ENABLED(CONFIG_I2C)
static struct of_device_id mcp23s08_i2c_of_match[] = { static struct of_device_id mcp23s08_i2c_of_match[] = {
{ {
.compatible = "mcp,mcp23008", .data = (void *) MCP_TYPE_008, .compatible = "microchip,mcp23008",
.data = (void *) MCP_TYPE_008,
},
{
.compatible = "microchip,mcp23017",
.data = (void *) MCP_TYPE_017,
},
/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
{
.compatible = "mcp,mcp23008",
.data = (void *) MCP_TYPE_008,
}, },
{ {
.compatible = "mcp,mcp23017", .data = (void *) MCP_TYPE_017, .compatible = "mcp,mcp23017",
.data = (void *) MCP_TYPE_017,
}, },
{ }, { },
}; };
...@@ -520,14 +542,13 @@ static int mcp230xx_probe(struct i2c_client *client, ...@@ -520,14 +542,13 @@ static int mcp230xx_probe(struct i2c_client *client,
match = of_match_device(of_match_ptr(mcp23s08_i2c_of_match), match = of_match_device(of_match_ptr(mcp23s08_i2c_of_match),
&client->dev); &client->dev);
if (match) { pdata = dev_get_platdata(&client->dev);
if (match || !pdata) {
base = -1; base = -1;
pullups = 0; pullups = 0;
} else { } else {
pdata = client->dev.platform_data; if (!gpio_is_valid(pdata->base)) {
if (!pdata || !gpio_is_valid(pdata->base)) { dev_dbg(&client->dev, "invalid platform data\n");
dev_dbg(&client->dev,
"invalid or missing platform data\n");
return -EINVAL; return -EINVAL;
} }
base = pdata->base; base = pdata->base;
...@@ -620,12 +641,17 @@ static int mcp23s08_probe(struct spi_device *spi) ...@@ -620,12 +641,17 @@ 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)match->data;
status = of_property_read_u32(spi->dev.of_node,
"microchip,spi-present-mask", &spi_present_mask);
if (status) {
status = of_property_read_u32(spi->dev.of_node, status = of_property_read_u32(spi->dev.of_node,
"mcp,spi-present-mask", &spi_present_mask); "mcp,spi-present-mask", &spi_present_mask);
if (status) { if (status) {
dev_err(&spi->dev, "DT has no spi-present-mask\n"); dev_err(&spi->dev,
"DT has no spi-present-mask\n");
return -ENODEV; return -ENODEV;
} }
}
if ((spi_present_mask <= 0) || (spi_present_mask >= 256)) { if ((spi_present_mask <= 0) || (spi_present_mask >= 256)) {
dev_err(&spi->dev, "invalid spi-present-mask\n"); dev_err(&spi->dev, "invalid spi-present-mask\n");
return -ENODEV; return -ENODEV;
...@@ -635,7 +661,7 @@ static int mcp23s08_probe(struct spi_device *spi) ...@@ -635,7 +661,7 @@ static int mcp23s08_probe(struct spi_device *spi)
pullups[addr] = 0; pullups[addr] = 0;
} else { } else {
type = spi_get_device_id(spi)->driver_data; type = spi_get_device_id(spi)->driver_data;
pdata = spi->dev.platform_data; pdata = dev_get_platdata(&spi->dev);
if (!pdata || !gpio_is_valid(pdata->base)) { if (!pdata || !gpio_is_valid(pdata->base)) {
dev_dbg(&spi->dev, dev_dbg(&spi->dev,
"invalid or missing platform data\n"); "invalid or missing platform data\n");
......
...@@ -259,7 +259,7 @@ static void msic_gpio_irq_handler(unsigned irq, struct irq_desc *desc) ...@@ -259,7 +259,7 @@ static void msic_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
static int platform_msic_gpio_probe(struct platform_device *pdev) static int platform_msic_gpio_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct intel_msic_gpio_pdata *pdata = dev->platform_data; struct intel_msic_gpio_pdata *pdata = dev_get_platdata(dev);
struct msic_gpio *mg; struct msic_gpio *mg;
int irq = platform_get_irq(pdev, 0); int irq = platform_get_irq(pdev, 0);
int retval; int retval;
......
...@@ -106,7 +106,7 @@ struct msm_gpio_dev { ...@@ -106,7 +106,7 @@ struct msm_gpio_dev {
void __iomem *msm_tlmm_base; void __iomem *msm_tlmm_base;
}; };
struct msm_gpio_dev msm_gpio; static struct msm_gpio_dev msm_gpio;
#define GPIO_INTR_CFG_SU(gpio) (msm_gpio.msm_tlmm_base + 0x0400 + \ #define GPIO_INTR_CFG_SU(gpio) (msm_gpio.msm_tlmm_base + 0x0400 + \
(0x04 * (gpio))) (0x04 * (gpio)))
......
...@@ -566,12 +566,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev) ...@@ -566,12 +566,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
else else
soc_variant = MVEBU_GPIO_SOC_VARIANT_ORION; soc_variant = MVEBU_GPIO_SOC_VARIANT_ORION;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "Cannot get memory resource\n");
return -ENODEV;
}
mvchip = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_gpio_chip), GFP_KERNEL); mvchip = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_gpio_chip), GFP_KERNEL);
if (!mvchip) { if (!mvchip) {
dev_err(&pdev->dev, "Cannot allocate memory\n"); dev_err(&pdev->dev, "Cannot allocate memory\n");
...@@ -611,6 +605,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) ...@@ -611,6 +605,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
mvchip->chip.dbg_show = mvebu_gpio_dbg_show; mvchip->chip.dbg_show = mvebu_gpio_dbg_show;
spin_lock_init(&mvchip->lock); spin_lock_init(&mvchip->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mvchip->membase = devm_ioremap_resource(&pdev->dev, res); mvchip->membase = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mvchip->membase)) if (IS_ERR(mvchip->membase))
return PTR_ERR(mvchip->membase); return PTR_ERR(mvchip->membase);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
...@@ -291,6 +292,9 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) ...@@ -291,6 +292,9 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
{ {
u32 irq_msk, irq_stat; u32 irq_msk, irq_stat;
struct mxc_gpio_port *port; struct mxc_gpio_port *port;
struct irq_chip *chip = irq_get_chip(irq);
chained_irq_enter(chip, desc);
/* walk through all interrupt status registers */ /* walk through all interrupt status registers */
list_for_each_entry(port, &mxc_gpio_ports, node) { list_for_each_entry(port, &mxc_gpio_ports, node) {
...@@ -302,6 +306,7 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) ...@@ -302,6 +306,7 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
if (irq_stat) if (irq_stat)
mxc_gpio_irq_handler(port, irq_stat); mxc_gpio_irq_handler(port, irq_stat);
} }
chained_irq_exit(chip, desc);
} }
/* /*
...@@ -405,34 +410,19 @@ static int mxc_gpio_probe(struct platform_device *pdev) ...@@ -405,34 +410,19 @@ static int mxc_gpio_probe(struct platform_device *pdev)
mxc_gpio_get_hw(pdev); mxc_gpio_get_hw(pdev);
port = kzalloc(sizeof(struct mxc_gpio_port), GFP_KERNEL); port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
if (!port) if (!port)
return -ENOMEM; return -ENOMEM;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!iores) { port->base = devm_ioremap_resource(&pdev->dev, iores);
err = -ENODEV; if (IS_ERR(port->base))
goto out_kfree; return PTR_ERR(port->base);
}
if (!request_mem_region(iores->start, resource_size(iores),
pdev->name)) {
err = -EBUSY;
goto out_kfree;
}
port->base = ioremap(iores->start, resource_size(iores));
if (!port->base) {
err = -ENOMEM;
goto out_release_mem;
}
port->irq_high = platform_get_irq(pdev, 1); port->irq_high = platform_get_irq(pdev, 1);
port->irq = platform_get_irq(pdev, 0); port->irq = platform_get_irq(pdev, 0);
if (port->irq < 0) { if (port->irq < 0)
err = -EINVAL; return -EINVAL;
goto out_iounmap;
}
/* disable the interrupt and clear the status */ /* disable the interrupt and clear the status */
writel(0, port->base + GPIO_IMR); writel(0, port->base + GPIO_IMR);
...@@ -462,7 +452,7 @@ static int mxc_gpio_probe(struct platform_device *pdev) ...@@ -462,7 +452,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
port->base + GPIO_DR, NULL, port->base + GPIO_DR, NULL,
port->base + GPIO_GDIR, NULL, 0); port->base + GPIO_GDIR, NULL, 0);
if (err) if (err)
goto out_iounmap; goto out_bgio;
port->bgc.gc.to_irq = mxc_gpio_to_irq; port->bgc.gc.to_irq = mxc_gpio_to_irq;
port->bgc.gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 : port->bgc.gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 :
...@@ -498,12 +488,7 @@ static int mxc_gpio_probe(struct platform_device *pdev) ...@@ -498,12 +488,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
WARN_ON(gpiochip_remove(&port->bgc.gc) < 0); WARN_ON(gpiochip_remove(&port->bgc.gc) < 0);
out_bgpio_remove: out_bgpio_remove:
bgpio_remove(&port->bgc); bgpio_remove(&port->bgc);
out_iounmap: out_bgio:
iounmap(port->base);
out_release_mem:
release_mem_region(iores->start, resource_size(iores));
out_kfree:
kfree(port);
dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err); dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
return err; return err;
} }
......
...@@ -1030,7 +1030,7 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, ...@@ -1030,7 +1030,7 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
ct->chip.irq_set_type = gpio_irq_type; ct->chip.irq_set_type = gpio_irq_type;
if (bank->regs->wkup_en) if (bank->regs->wkup_en)
ct->chip.irq_set_wake = gpio_wake_enable, ct->chip.irq_set_wake = gpio_wake_enable;
ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride; ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride;
irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
...@@ -1100,7 +1100,7 @@ static int omap_gpio_probe(struct platform_device *pdev) ...@@ -1100,7 +1100,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
match = of_match_device(of_match_ptr(omap_gpio_match), dev); match = of_match_device(of_match_ptr(omap_gpio_match), dev);
pdata = match ? match->data : dev->platform_data; pdata = match ? match->data : dev_get_platdata(dev);
if (!pdata) if (!pdata)
return -EINVAL; return -EINVAL;
......
...@@ -43,9 +43,22 @@ static int palmas_gpio_get(struct gpio_chip *gc, unsigned offset) ...@@ -43,9 +43,22 @@ static int palmas_gpio_get(struct gpio_chip *gc, unsigned offset)
unsigned int val; unsigned int val;
int ret; int ret;
ret = palmas_read(palmas, PALMAS_GPIO_BASE, PALMAS_GPIO_DATA_IN, &val); ret = palmas_read(palmas, PALMAS_GPIO_BASE, PALMAS_GPIO_DATA_DIR, &val);
if (ret < 0) { if (ret < 0) {
dev_err(gc->dev, "GPIO_DATA_IN read failed, err = %d\n", ret); dev_err(gc->dev, "GPIO_DATA_DIR read failed, err = %d\n", ret);
return ret;
}
if (val & (1 << offset)) {
ret = palmas_read(palmas, PALMAS_GPIO_BASE,
PALMAS_GPIO_DATA_OUT, &val);
} else {
ret = palmas_read(palmas, PALMAS_GPIO_BASE,
PALMAS_GPIO_DATA_IN, &val);
}
if (ret < 0) {
dev_err(gc->dev, "GPIO_DATA_IN/OUT read failed, err = %d\n",
ret);
return ret; return ret;
} }
return !!(val & BIT(offset)); return !!(val & BIT(offset));
...@@ -134,7 +147,7 @@ static int palmas_gpio_probe(struct platform_device *pdev) ...@@ -134,7 +147,7 @@ static int palmas_gpio_probe(struct platform_device *pdev)
palmas_gpio->gpio_chip.get = palmas_gpio_get; palmas_gpio->gpio_chip.get = palmas_gpio_get;
palmas_gpio->gpio_chip.dev = &pdev->dev; palmas_gpio->gpio_chip.dev = &pdev->dev;
#ifdef CONFIG_OF_GPIO #ifdef CONFIG_OF_GPIO
palmas_gpio->gpio_chip.of_node = palmas->dev->of_node; palmas_gpio->gpio_chip.of_node = pdev->dev.of_node;
#endif #endif
palmas_pdata = dev_get_platdata(palmas->dev); palmas_pdata = dev_get_platdata(palmas->dev);
if (palmas_pdata && palmas_pdata->gpio_base) if (palmas_pdata && palmas_pdata->gpio_base)
...@@ -159,9 +172,19 @@ static int palmas_gpio_remove(struct platform_device *pdev) ...@@ -159,9 +172,19 @@ static int palmas_gpio_remove(struct platform_device *pdev)
return gpiochip_remove(&palmas_gpio->gpio_chip); return gpiochip_remove(&palmas_gpio->gpio_chip);
} }
static struct of_device_id of_palmas_gpio_match[] = {
{ .compatible = "ti,palmas-gpio"},
{ .compatible = "ti,tps65913-gpio"},
{ .compatible = "ti,tps65914-gpio"},
{ .compatible = "ti,tps80036-gpio"},
{ },
};
MODULE_DEVICE_TABLE(of, of_palmas_gpio_match);
static struct platform_driver palmas_gpio_driver = { static struct platform_driver palmas_gpio_driver = {
.driver.name = "palmas-gpio", .driver.name = "palmas-gpio",
.driver.owner = THIS_MODULE, .driver.owner = THIS_MODULE,
.driver.of_match_table = of_palmas_gpio_match,
.probe = palmas_gpio_probe, .probe = palmas_gpio_probe,
.remove = palmas_gpio_remove, .remove = palmas_gpio_remove,
}; };
......
...@@ -308,7 +308,7 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) ...@@ -308,7 +308,7 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
return 0; return 0;
} }
return (reg_val & (1u << off)) ? 1 : 0; return (reg_val & (1u << (off % BANK_SZ))) ? 1 : 0;
} }
static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
...@@ -731,7 +731,7 @@ static int pca953x_probe(struct i2c_client *client, ...@@ -731,7 +731,7 @@ static int pca953x_probe(struct i2c_client *client,
if (chip == NULL) if (chip == NULL)
return -ENOMEM; return -ENOMEM;
pdata = client->dev.platform_data; pdata = dev_get_platdata(&client->dev);
if (pdata) { if (pdata) {
irq_base = pdata->irq_base; irq_base = pdata->irq_base;
chip->gpio_start = pdata->gpio_base; chip->gpio_start = pdata->gpio_base;
...@@ -785,7 +785,7 @@ static int pca953x_probe(struct i2c_client *client, ...@@ -785,7 +785,7 @@ static int pca953x_probe(struct i2c_client *client,
static int pca953x_remove(struct i2c_client *client) static int pca953x_remove(struct i2c_client *client)
{ {
struct pca953x_platform_data *pdata = client->dev.platform_data; struct pca953x_platform_data *pdata = dev_get_platdata(&client->dev);
struct pca953x_chip *chip = i2c_get_clientdata(client); struct pca953x_chip *chip = i2c_get_clientdata(client);
int ret = 0; int ret = 0;
......
...@@ -18,15 +18,15 @@ ...@@ -18,15 +18,15 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c/pcf857x.h> #include <linux/i2c/pcf857x.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
...@@ -223,7 +223,6 @@ static void pcf857x_irq_domain_cleanup(struct pcf857x *gpio) ...@@ -223,7 +223,6 @@ static void pcf857x_irq_domain_cleanup(struct pcf857x *gpio)
} }
static int pcf857x_irq_domain_init(struct pcf857x *gpio, static int pcf857x_irq_domain_init(struct pcf857x *gpio,
struct pcf857x_platform_data *pdata,
struct i2c_client *client) struct i2c_client *client)
{ {
int status; int status;
...@@ -262,7 +261,7 @@ static int pcf857x_probe(struct i2c_client *client, ...@@ -262,7 +261,7 @@ static int pcf857x_probe(struct i2c_client *client,
struct pcf857x *gpio; struct pcf857x *gpio;
int status; int status;
pdata = client->dev.platform_data; pdata = dev_get_platdata(&client->dev);
if (!pdata) { if (!pdata) {
dev_dbg(&client->dev, "no platform data\n"); dev_dbg(&client->dev, "no platform data\n");
} }
...@@ -286,8 +285,8 @@ static int pcf857x_probe(struct i2c_client *client, ...@@ -286,8 +285,8 @@ static int pcf857x_probe(struct i2c_client *client,
gpio->chip.ngpio = id->driver_data; gpio->chip.ngpio = id->driver_data;
/* enable gpio_to_irq() if platform has settings */ /* enable gpio_to_irq() if platform has settings */
if (pdata && client->irq) { if (client->irq) {
status = pcf857x_irq_domain_init(gpio, pdata, client); status = pcf857x_irq_domain_init(gpio, client);
if (status < 0) { if (status < 0) {
dev_err(&client->dev, "irq_domain init failed\n"); dev_err(&client->dev, "irq_domain init failed\n");
goto fail; goto fail;
...@@ -388,7 +387,7 @@ static int pcf857x_probe(struct i2c_client *client, ...@@ -388,7 +387,7 @@ static int pcf857x_probe(struct i2c_client *client,
dev_dbg(&client->dev, "probe error %d for '%s'\n", dev_dbg(&client->dev, "probe error %d for '%s'\n",
status, client->name); status, client->name);
if (pdata && client->irq) if (client->irq)
pcf857x_irq_domain_cleanup(gpio); pcf857x_irq_domain_cleanup(gpio);
return status; return status;
...@@ -396,7 +395,7 @@ static int pcf857x_probe(struct i2c_client *client, ...@@ -396,7 +395,7 @@ static int pcf857x_probe(struct i2c_client *client,
static int pcf857x_remove(struct i2c_client *client) static int pcf857x_remove(struct i2c_client *client)
{ {
struct pcf857x_platform_data *pdata = client->dev.platform_data; struct pcf857x_platform_data *pdata = dev_get_platdata(&client->dev);
struct pcf857x *gpio = i2c_get_clientdata(client); struct pcf857x *gpio = i2c_get_clientdata(client);
int status = 0; int status = 0;
...@@ -411,7 +410,7 @@ static int pcf857x_remove(struct i2c_client *client) ...@@ -411,7 +410,7 @@ static int pcf857x_remove(struct i2c_client *client)
} }
} }
if (pdata && client->irq) if (client->irq)
pcf857x_irq_domain_cleanup(gpio); pcf857x_irq_domain_cleanup(gpio);
status = gpiochip_remove(&gpio->chip); status = gpiochip_remove(&gpio->chip);
......
...@@ -259,7 +259,7 @@ static const struct irq_domain_ops pl061_domain_ops = { ...@@ -259,7 +259,7 @@ static const struct irq_domain_ops pl061_domain_ops = {
static int pl061_probe(struct amba_device *adev, const struct amba_id *id) static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
{ {
struct device *dev = &adev->dev; struct device *dev = &adev->dev;
struct pl061_platform_data *pdata = dev->platform_data; struct pl061_platform_data *pdata = dev_get_platdata(dev);
struct pl061_gpio *chip; struct pl061_gpio *chip;
int ret, irq, i, irq_base; int ret, irq, i, irq_base;
......
...@@ -524,8 +524,8 @@ const struct irq_domain_ops pxa_irq_domain_ops = { ...@@ -524,8 +524,8 @@ const struct irq_domain_ops pxa_irq_domain_ops = {
static int pxa_gpio_probe_dt(struct platform_device *pdev) static int pxa_gpio_probe_dt(struct platform_device *pdev)
{ {
int ret, nr_gpios; int ret = 0, nr_gpios;
struct device_node *prev, *next, *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
const struct of_device_id *of_id = const struct of_device_id *of_id =
of_match_device(pxa_gpio_dt_ids, &pdev->dev); of_match_device(pxa_gpio_dt_ids, &pdev->dev);
const struct pxa_gpio_id *gpio_id; const struct pxa_gpio_id *gpio_id;
...@@ -537,20 +537,13 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev) ...@@ -537,20 +537,13 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
gpio_id = of_id->data; gpio_id = of_id->data;
gpio_type = gpio_id->type; gpio_type = gpio_id->type;
next = of_get_next_child(np, NULL);
prev = next;
if (!next) {
dev_err(&pdev->dev, "Failed to find child gpio node\n");
ret = -EINVAL;
goto err;
}
of_node_put(prev);
nr_gpios = gpio_id->gpio_nums; nr_gpios = gpio_id->gpio_nums;
pxa_last_gpio = nr_gpios - 1; pxa_last_gpio = nr_gpios - 1;
irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0); irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0);
if (irq_base < 0) { if (irq_base < 0) {
dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n"); dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n");
ret = irq_base;
goto err; goto err;
} }
domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0,
......
...@@ -285,7 +285,7 @@ static struct irq_domain_ops gpio_rcar_irq_domain_ops = { ...@@ -285,7 +285,7 @@ static struct irq_domain_ops gpio_rcar_irq_domain_ops = {
static void gpio_rcar_parse_pdata(struct gpio_rcar_priv *p) static void gpio_rcar_parse_pdata(struct gpio_rcar_priv *p)
{ {
struct gpio_rcar_config *pdata = p->pdev->dev.platform_data; struct gpio_rcar_config *pdata = dev_get_platdata(&p->pdev->dev);
struct device_node *np = p->pdev->dev.of_node; struct device_node *np = p->pdev->dev.of_node;
struct of_phandle_args args; struct of_phandle_args args;
int ret; int ret;
......
...@@ -135,7 +135,7 @@ static int rdc321x_gpio_probe(struct platform_device *pdev) ...@@ -135,7 +135,7 @@ static int rdc321x_gpio_probe(struct platform_device *pdev)
struct rdc321x_gpio *rdc321x_gpio_dev; struct rdc321x_gpio *rdc321x_gpio_dev;
struct rdc321x_gpio_pdata *pdata; struct rdc321x_gpio_pdata *pdata;
pdata = pdev->dev.platform_data; pdata = dev_get_platdata(&pdev->dev);
if (!pdata) { if (!pdata) {
dev_err(&pdev->dev, "no platform data supplied\n"); dev_err(&pdev->dev, "no platform data supplied\n");
return -ENODEV; return -ENODEV;
......
This diff is collapsed.
...@@ -128,18 +128,13 @@ static int spics_gpio_probe(struct platform_device *pdev) ...@@ -128,18 +128,13 @@ static int spics_gpio_probe(struct platform_device *pdev)
struct resource *res; struct resource *res;
int ret; int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n");
return -EBUSY;
}
spics = devm_kzalloc(&pdev->dev, sizeof(*spics), GFP_KERNEL); spics = devm_kzalloc(&pdev->dev, sizeof(*spics), GFP_KERNEL);
if (!spics) { if (!spics) {
dev_err(&pdev->dev, "memory allocation fail\n"); dev_err(&pdev->dev, "memory allocation fail\n");
return -ENOMEM; return -ENOMEM;
} }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
spics->base = devm_ioremap_resource(&pdev->dev, res); spics->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(spics->base)) if (IS_ERR(spics->base))
return PTR_ERR(spics->base); return PTR_ERR(spics->base);
......
...@@ -361,7 +361,7 @@ static int gsta_probe(struct platform_device *dev) ...@@ -361,7 +361,7 @@ static int gsta_probe(struct platform_device *dev)
struct gsta_gpio *chip; struct gsta_gpio *chip;
struct resource *res; struct resource *res;
pdev = *(struct pci_dev **)(dev->dev.platform_data); pdev = *(struct pci_dev **)dev_get_platdata(&dev->dev);
gpio_pdata = dev_get_platdata(&pdev->dev); gpio_pdata = dev_get_platdata(&pdev->dev);
if (gpio_pdata == NULL) if (gpio_pdata == NULL)
......
...@@ -583,7 +583,7 @@ static int sx150x_probe(struct i2c_client *client, ...@@ -583,7 +583,7 @@ static int sx150x_probe(struct i2c_client *client,
struct sx150x_chip *chip; struct sx150x_chip *chip;
int rc; int rc;
pdata = client->dev.platform_data; pdata = dev_get_platdata(&client->dev);
if (!pdata) if (!pdata)
return -EINVAL; return -EINVAL;
......
...@@ -227,7 +227,7 @@ static int timbgpio_probe(struct platform_device *pdev) ...@@ -227,7 +227,7 @@ static int timbgpio_probe(struct platform_device *pdev)
struct gpio_chip *gc; struct gpio_chip *gc;
struct timbgpio *tgpio; struct timbgpio *tgpio;
struct resource *iomem; struct resource *iomem;
struct timbgpio_platform_data *pdata = pdev->dev.platform_data; struct timbgpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
int irq = platform_get_irq(pdev, 0); int irq = platform_get_irq(pdev, 0);
if (!pdata || pdata->nr_pins > 32) { if (!pdata || pdata->nr_pins > 32) {
...@@ -318,7 +318,7 @@ static int timbgpio_probe(struct platform_device *pdev) ...@@ -318,7 +318,7 @@ static int timbgpio_probe(struct platform_device *pdev)
static int timbgpio_remove(struct platform_device *pdev) static int timbgpio_remove(struct platform_device *pdev)
{ {
int err; int err;
struct timbgpio_platform_data *pdata = pdev->dev.platform_data; struct timbgpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct timbgpio *tgpio = platform_get_drvdata(pdev); struct timbgpio *tgpio = platform_get_drvdata(pdev);
struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int irq = platform_get_irq(pdev, 0); int irq = platform_get_irq(pdev, 0);
......
...@@ -87,7 +87,7 @@ static struct gpio_chip template_chip = { ...@@ -87,7 +87,7 @@ static struct gpio_chip template_chip = {
static int tps65912_gpio_probe(struct platform_device *pdev) static int tps65912_gpio_probe(struct platform_device *pdev)
{ {
struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent); struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent);
struct tps65912_board *pdata = tps65912->dev->platform_data; struct tps65912_board *pdata = dev_get_platdata(tps65912->dev);
struct tps65912_gpio_data *tps65912_gpio; struct tps65912_gpio_data *tps65912_gpio;
int ret; int ret;
......
...@@ -322,7 +322,7 @@ static void ts5500_disable_irq(struct ts5500_priv *priv) ...@@ -322,7 +322,7 @@ static void ts5500_disable_irq(struct ts5500_priv *priv)
static int ts5500_dio_probe(struct platform_device *pdev) static int ts5500_dio_probe(struct platform_device *pdev)
{ {
enum ts5500_blocks block = platform_get_device_id(pdev)->driver_data; enum ts5500_blocks block = platform_get_device_id(pdev)->driver_data;
struct ts5500_dio_platform_data *pdata = pdev->dev.platform_data; struct ts5500_dio_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
const char *name = dev_name(dev); const char *name = dev_name(dev);
struct ts5500_priv *priv; struct ts5500_priv *priv;
......
...@@ -256,7 +256,7 @@ static int twl_request(struct gpio_chip *chip, unsigned offset) ...@@ -256,7 +256,7 @@ static int twl_request(struct gpio_chip *chip, unsigned offset)
/* optionally have the first two GPIOs switch vMMC1 /* optionally have the first two GPIOs switch vMMC1
* and vMMC2 power supplies based on card presence. * and vMMC2 power supplies based on card presence.
*/ */
pdata = chip->dev->platform_data; pdata = dev_get_platdata(chip->dev);
if (pdata) if (pdata)
value |= pdata->mmc_cd & 0x03; value |= pdata->mmc_cd & 0x03;
...@@ -460,7 +460,7 @@ static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev) ...@@ -460,7 +460,7 @@ static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev)
static int gpio_twl4030_probe(struct platform_device *pdev) static int gpio_twl4030_probe(struct platform_device *pdev)
{ {
struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; struct twl4030_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct device_node *node = pdev->dev.of_node; struct device_node *node = pdev->dev.of_node;
struct gpio_twl4030_priv *priv; struct gpio_twl4030_priv *priv;
int ret, irq_base; int ret, irq_base;
...@@ -556,7 +556,7 @@ static int gpio_twl4030_probe(struct platform_device *pdev) ...@@ -556,7 +556,7 @@ static int gpio_twl4030_probe(struct platform_device *pdev)
/* Cannot use as gpio_twl4030_probe() calls us */ /* Cannot use as gpio_twl4030_probe() calls us */
static int gpio_twl4030_remove(struct platform_device *pdev) static int gpio_twl4030_remove(struct platform_device *pdev)
{ {
struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; struct twl4030_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct gpio_twl4030_priv *priv = platform_get_drvdata(pdev); struct gpio_twl4030_priv *priv = platform_get_drvdata(pdev);
int status; int status;
......
...@@ -84,14 +84,10 @@ static struct gpio_chip twl6040gpo_chip = { ...@@ -84,14 +84,10 @@ static struct gpio_chip twl6040gpo_chip = {
static int gpo_twl6040_probe(struct platform_device *pdev) static int gpo_twl6040_probe(struct platform_device *pdev)
{ {
struct twl6040_gpo_data *pdata = pdev->dev.platform_data;
struct device *twl6040_core_dev = pdev->dev.parent; struct device *twl6040_core_dev = pdev->dev.parent;
struct twl6040 *twl6040 = dev_get_drvdata(twl6040_core_dev); struct twl6040 *twl6040 = dev_get_drvdata(twl6040_core_dev);
int ret; int ret;
if (pdata)
twl6040gpo_chip.base = pdata->gpio_base;
else
twl6040gpo_chip.base = -1; twl6040gpo_chip.base = -1;
if (twl6040_get_revid(twl6040) < TWL6041_REV_ES2_0) if (twl6040_get_revid(twl6040) < TWL6041_REV_ES2_0)
......
/*
* Toumaz Xenif TZ1090 PDC GPIO handling.
*
* Copyright (C) 2012-2013 Imagination Technologies Ltd.
*
* 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.
*/
#include <linux/bitops.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/syscore_ops.h>
#include <asm/global_lock.h>
/* Register offsets from SOC_GPIO_CONTROL0 */
#define REG_SOC_GPIO_CONTROL0 0x00
#define REG_SOC_GPIO_CONTROL1 0x04
#define REG_SOC_GPIO_CONTROL2 0x08
#define REG_SOC_GPIO_CONTROL3 0x0c
#define REG_SOC_GPIO_STATUS 0x80
/* PDC GPIOs go after normal GPIOs */
#define GPIO_PDC_BASE 90
#define GPIO_PDC_NGPIO 7
/* Out of PDC gpios, only syswakes have irqs */
#define GPIO_PDC_IRQ_FIRST 2
#define GPIO_PDC_NIRQ 3
/**
* struct tz1090_pdc_gpio - GPIO bank private data
* @chip: Generic GPIO chip for GPIO bank
* @reg: Base of registers, offset for this GPIO bank
* @irq: IRQ numbers for Syswake GPIOs
*
* This is the main private data for the PDC GPIO driver. It encapsulates a
* gpio_chip, and the callbacks for the gpio_chip can access the private data
* with the to_pdc() macro below.
*/
struct tz1090_pdc_gpio {
struct gpio_chip chip;
void __iomem *reg;
int irq[GPIO_PDC_NIRQ];
};
#define to_pdc(c) container_of(c, struct tz1090_pdc_gpio, chip)
/* Register accesses into the PDC MMIO area */
static inline void pdc_write(struct tz1090_pdc_gpio *priv, unsigned int reg_offs,
unsigned int data)
{
writel(data, priv->reg + reg_offs);
}
static inline unsigned int pdc_read(struct tz1090_pdc_gpio *priv,
unsigned int reg_offs)
{
return readl(priv->reg + reg_offs);
}
/* Generic GPIO interface */
static int tz1090_pdc_gpio_direction_input(struct gpio_chip *chip,
unsigned int offset)
{
struct tz1090_pdc_gpio *priv = to_pdc(chip);
u32 value;
int lstat;
__global_lock2(lstat);
value = pdc_read(priv, REG_SOC_GPIO_CONTROL1);
value |= BIT(offset);
pdc_write(priv, REG_SOC_GPIO_CONTROL1, value);
__global_unlock2(lstat);
return 0;
}
static int tz1090_pdc_gpio_direction_output(struct gpio_chip *chip,
unsigned int offset,
int output_value)
{
struct tz1090_pdc_gpio *priv = to_pdc(chip);
u32 value;
int lstat;
__global_lock2(lstat);
/* EXT_POWER doesn't seem to have an output value bit */
if (offset < 6) {
value = pdc_read(priv, REG_SOC_GPIO_CONTROL0);
if (output_value)
value |= BIT(offset);
else
value &= ~BIT(offset);
pdc_write(priv, REG_SOC_GPIO_CONTROL0, value);
}
value = pdc_read(priv, REG_SOC_GPIO_CONTROL1);
value &= ~BIT(offset);
pdc_write(priv, REG_SOC_GPIO_CONTROL1, value);
__global_unlock2(lstat);
return 0;
}
static int tz1090_pdc_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct tz1090_pdc_gpio *priv = to_pdc(chip);
return pdc_read(priv, REG_SOC_GPIO_STATUS) & BIT(offset);
}
static void tz1090_pdc_gpio_set(struct gpio_chip *chip, unsigned int offset,
int output_value)
{
struct tz1090_pdc_gpio *priv = to_pdc(chip);
u32 value;
int lstat;
/* EXT_POWER doesn't seem to have an output value bit */
if (offset >= 6)
return;
__global_lock2(lstat);
value = pdc_read(priv, REG_SOC_GPIO_CONTROL0);
if (output_value)
value |= BIT(offset);
else
value &= ~BIT(offset);
pdc_write(priv, REG_SOC_GPIO_CONTROL0, value);
__global_unlock2(lstat);
}
static int tz1090_pdc_gpio_request(struct gpio_chip *chip, unsigned int offset)
{
return pinctrl_request_gpio(chip->base + offset);
}
static void tz1090_pdc_gpio_free(struct gpio_chip *chip, unsigned int offset)
{
pinctrl_free_gpio(chip->base + offset);
}
static int tz1090_pdc_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
{
struct tz1090_pdc_gpio *priv = to_pdc(chip);
unsigned int syswake = offset - GPIO_PDC_IRQ_FIRST;
int irq;
/* only syswakes have irqs */
if (syswake >= GPIO_PDC_NIRQ)
return -EINVAL;
irq = priv->irq[syswake];
if (!irq)
return -EINVAL;
return irq;
}
static int tz1090_pdc_gpio_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct resource *res_regs;
struct tz1090_pdc_gpio *priv;
unsigned int i;
if (!np) {
dev_err(&pdev->dev, "must be instantiated via devicetree\n");
return -ENOENT;
}
res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res_regs) {
dev_err(&pdev->dev, "cannot find registers resource\n");
return -ENOENT;
}
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) {
dev_err(&pdev->dev, "unable to allocate driver data\n");
return -ENOMEM;
}
/* Ioremap the registers */
priv->reg = devm_ioremap(&pdev->dev, res_regs->start,
res_regs->end - res_regs->start);
if (!priv->reg) {
dev_err(&pdev->dev, "unable to ioremap registers\n");
return -ENOMEM;
}
/* Set up GPIO chip */
priv->chip.label = "tz1090-pdc-gpio";
priv->chip.dev = &pdev->dev;
priv->chip.direction_input = tz1090_pdc_gpio_direction_input;
priv->chip.direction_output = tz1090_pdc_gpio_direction_output;
priv->chip.get = tz1090_pdc_gpio_get;
priv->chip.set = tz1090_pdc_gpio_set;
priv->chip.free = tz1090_pdc_gpio_free;
priv->chip.request = tz1090_pdc_gpio_request;
priv->chip.to_irq = tz1090_pdc_gpio_to_irq;
priv->chip.of_node = np;
/* GPIO numbering */
priv->chip.base = GPIO_PDC_BASE;
priv->chip.ngpio = GPIO_PDC_NGPIO;
/* Map the syswake irqs */
for (i = 0; i < GPIO_PDC_NIRQ; ++i)
priv->irq[i] = irq_of_parse_and_map(np, i);
/* Add the GPIO bank */
gpiochip_add(&priv->chip);
return 0;
}
static struct of_device_id tz1090_pdc_gpio_of_match[] = {
{ .compatible = "img,tz1090-pdc-gpio" },
{ },
};
static struct platform_driver tz1090_pdc_gpio_driver = {
.driver = {
.name = "tz1090-pdc-gpio",
.owner = THIS_MODULE,
.of_match_table = tz1090_pdc_gpio_of_match,
},
.probe = tz1090_pdc_gpio_probe,
};
static int __init tz1090_pdc_gpio_init(void)
{
return platform_driver_register(&tz1090_pdc_gpio_driver);
}
subsys_initcall(tz1090_pdc_gpio_init);
This diff is collapsed.
...@@ -45,7 +45,7 @@ static void ucb1400_gpio_set(struct gpio_chip *gc, unsigned off, int val) ...@@ -45,7 +45,7 @@ static void ucb1400_gpio_set(struct gpio_chip *gc, unsigned off, int val)
static int ucb1400_gpio_probe(struct platform_device *dev) static int ucb1400_gpio_probe(struct platform_device *dev)
{ {
struct ucb1400_gpio *ucb = dev->dev.platform_data; struct ucb1400_gpio *ucb = dev_get_platdata(&dev->dev);
int err = 0; int err = 0;
if (!(ucb && ucb->gpio_offset)) { if (!(ucb && ucb->gpio_offset)) {
......
...@@ -246,7 +246,7 @@ static struct gpio_chip template_chip = { ...@@ -246,7 +246,7 @@ static struct gpio_chip template_chip = {
static int wm831x_gpio_probe(struct platform_device *pdev) static int wm831x_gpio_probe(struct platform_device *pdev)
{ {
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data; struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev);
struct wm831x_gpio *wm831x_gpio; struct wm831x_gpio *wm831x_gpio;
int ret; int ret;
......
...@@ -112,7 +112,7 @@ static struct gpio_chip template_chip = { ...@@ -112,7 +112,7 @@ static struct gpio_chip template_chip = {
static int wm8350_gpio_probe(struct platform_device *pdev) static int wm8350_gpio_probe(struct platform_device *pdev)
{ {
struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent); struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent);
struct wm8350_platform_data *pdata = wm8350->dev->platform_data; struct wm8350_platform_data *pdata = dev_get_platdata(wm8350->dev);
struct wm8350_gpio_data *wm8350_gpio; struct wm8350_gpio_data *wm8350_gpio;
int ret; int ret;
......
...@@ -248,7 +248,7 @@ static struct gpio_chip template_chip = { ...@@ -248,7 +248,7 @@ static struct gpio_chip template_chip = {
static int wm8994_gpio_probe(struct platform_device *pdev) static int wm8994_gpio_probe(struct platform_device *pdev)
{ {
struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent); struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
struct wm8994_pdata *pdata = wm8994->dev->platform_data; struct wm8994_pdata *pdata = dev_get_platdata(wm8994->dev);
struct wm8994_gpio *wm8994_gpio; struct wm8994_gpio *wm8994_gpio;
int ret; int ret;
......
...@@ -76,7 +76,8 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname, ...@@ -76,7 +76,8 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname,
ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index, ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index,
&gg_data.gpiospec); &gg_data.gpiospec);
if (ret) { if (ret) {
pr_debug("%s: can't parse gpios property\n", __func__); pr_debug("%s: can't parse gpios property of node '%s[%d]'\n",
__func__, np->full_name, index);
return ret; return ret;
} }
......
...@@ -349,7 +349,7 @@ static ssize_t gpio_value_store(struct device *dev, ...@@ -349,7 +349,7 @@ static ssize_t gpio_value_store(struct device *dev,
else { else {
long value; long value;
status = strict_strtol(buf, 0, &value); status = kstrtol(buf, 0, &value);
if (status == 0) { if (status == 0) {
if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
value = !value; value = !value;
...@@ -570,7 +570,7 @@ static ssize_t gpio_active_low_store(struct device *dev, ...@@ -570,7 +570,7 @@ static ssize_t gpio_active_low_store(struct device *dev,
} else { } else {
long value; long value;
status = strict_strtol(buf, 0, &value); status = kstrtol(buf, 0, &value);
if (status == 0) if (status == 0)
status = sysfs_set_active_low(desc, dev, value != 0); status = sysfs_set_active_low(desc, dev, value != 0);
} }
...@@ -652,7 +652,7 @@ static ssize_t export_store(struct class *class, ...@@ -652,7 +652,7 @@ static ssize_t export_store(struct class *class,
struct gpio_desc *desc; struct gpio_desc *desc;
int status; int status;
status = strict_strtol(buf, 0, &gpio); status = kstrtol(buf, 0, &gpio);
if (status < 0) if (status < 0)
goto done; goto done;
...@@ -694,7 +694,7 @@ static ssize_t unexport_store(struct class *class, ...@@ -694,7 +694,7 @@ static ssize_t unexport_store(struct class *class,
struct gpio_desc *desc; struct gpio_desc *desc;
int status; int status;
status = strict_strtol(buf, 0, &gpio); status = kstrtol(buf, 0, &gpio);
if (status < 0) if (status < 0)
goto done; goto done;
...@@ -1398,7 +1398,7 @@ static int gpiod_request(struct gpio_desc *desc, const char *label) ...@@ -1398,7 +1398,7 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
int status = -EPROBE_DEFER; int status = -EPROBE_DEFER;
unsigned long flags; unsigned long flags;
if (!desc) { if (!desc || !desc->chip) {
pr_warn("%s: invalid GPIO\n", __func__); pr_warn("%s: invalid GPIO\n", __func__);
return -EINVAL; return -EINVAL;
} }
...@@ -1406,8 +1406,6 @@ static int gpiod_request(struct gpio_desc *desc, const char *label) ...@@ -1406,8 +1406,6 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
spin_lock_irqsave(&gpio_lock, flags); spin_lock_irqsave(&gpio_lock, flags);
chip = desc->chip; chip = desc->chip;
if (chip == NULL)
goto done;
if (!try_module_get(chip->owner)) if (!try_module_get(chip->owner))
goto done; goto done;
...@@ -1630,16 +1628,20 @@ static int gpiod_direction_input(struct gpio_desc *desc) ...@@ -1630,16 +1628,20 @@ static int gpiod_direction_input(struct gpio_desc *desc)
int status = -EINVAL; int status = -EINVAL;
int offset; int offset;
if (!desc) { if (!desc || !desc->chip) {
pr_warn("%s: invalid GPIO\n", __func__); pr_warn("%s: invalid GPIO\n", __func__);
return -EINVAL; return -EINVAL;
} }
chip = desc->chip;
if (!chip->get || !chip->direction_input) {
pr_warn("%s: missing get() or direction_input() operations\n",
__func__);
return -EIO;
}
spin_lock_irqsave(&gpio_lock, flags); spin_lock_irqsave(&gpio_lock, flags);
chip = desc->chip;
if (!chip || !chip->get || !chip->direction_input)
goto fail;
status = gpio_ensure_requested(desc); status = gpio_ensure_requested(desc);
if (status < 0) if (status < 0)
goto fail; goto fail;
...@@ -1691,7 +1693,7 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value) ...@@ -1691,7 +1693,7 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value)
int status = -EINVAL; int status = -EINVAL;
int offset; int offset;
if (!desc) { if (!desc || !desc->chip) {
pr_warn("%s: invalid GPIO\n", __func__); pr_warn("%s: invalid GPIO\n", __func__);
return -EINVAL; return -EINVAL;
} }
...@@ -1704,11 +1706,15 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value) ...@@ -1704,11 +1706,15 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value)
if (!value && test_bit(FLAG_OPEN_SOURCE, &desc->flags)) if (!value && test_bit(FLAG_OPEN_SOURCE, &desc->flags))
return gpiod_direction_input(desc); return gpiod_direction_input(desc);
chip = desc->chip;
if (!chip->set || !chip->direction_output) {
pr_warn("%s: missing set() or direction_output() operations\n",
__func__);
return -EIO;
}
spin_lock_irqsave(&gpio_lock, flags); spin_lock_irqsave(&gpio_lock, flags);
chip = desc->chip;
if (!chip || !chip->set || !chip->direction_output)
goto fail;
status = gpio_ensure_requested(desc); status = gpio_ensure_requested(desc);
if (status < 0) if (status < 0)
goto fail; goto fail;
...@@ -1757,6 +1763,9 @@ EXPORT_SYMBOL_GPL(gpio_direction_output); ...@@ -1757,6 +1763,9 @@ EXPORT_SYMBOL_GPL(gpio_direction_output);
* gpio_set_debounce - sets @debounce time for a @gpio * gpio_set_debounce - sets @debounce time for a @gpio
* @gpio: the gpio to set debounce time * @gpio: the gpio to set debounce time
* @debounce: debounce time is microseconds * @debounce: debounce time is microseconds
*
* returns -ENOTSUPP if the controller does not support setting
* debounce.
*/ */
static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce) static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
{ {
...@@ -1765,16 +1774,19 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce) ...@@ -1765,16 +1774,19 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
int status = -EINVAL; int status = -EINVAL;
int offset; int offset;
if (!desc) { if (!desc || !desc->chip) {
pr_warn("%s: invalid GPIO\n", __func__); pr_warn("%s: invalid GPIO\n", __func__);
return -EINVAL; return -EINVAL;
} }
spin_lock_irqsave(&gpio_lock, flags);
chip = desc->chip; chip = desc->chip;
if (!chip || !chip->set || !chip->set_debounce) if (!chip->set || !chip->set_debounce) {
goto fail; pr_debug("%s: missing set() or set_debounce() operations\n",
__func__);
return -ENOTSUPP;
}
spin_lock_irqsave(&gpio_lock, flags);
status = gpio_ensure_requested(desc); status = gpio_ensure_requested(desc);
if (status < 0) if (status < 0)
......
...@@ -5,6 +5,7 @@ struct gpio_em_config { ...@@ -5,6 +5,7 @@ struct gpio_em_config {
unsigned int gpio_base; unsigned int gpio_base;
unsigned int irq_base; unsigned int irq_base;
unsigned int number_of_pins; unsigned int number_of_pins;
const char *pctl_name;
}; };
#endif /* __GPIO_EM_H__ */ #endif /* __GPIO_EM_H__ */
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