summaryrefslogtreecommitdiff
path: root/drivers/gpio
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2011-07-21 21:48:13 -0400
committerNicolas Pitre <nicolas.pitre@linaro.org>2011-07-21 21:48:13 -0400
commitf25718e8cff17b5c64ad11c2a6e9d2ee1b676eef (patch)
treee0368d1f4a4b21cfbc1a04f216580ae6b913d1ea /drivers/gpio
parentc7e0c8535d73f8c5bf760926a2bd71c9840cf2ef (diff)
Revert "Merge remote-tracking branch 'arm-soc/for-next' into linaro-3.0"
This reverts commit c7e0c8535d73f8c5bf760926a2bd71c9840cf2ef, reversing changes made to dfee09c8acf18e84fe197bb5d821d1e4e02d020f. John Stultz reports that Panda doesn't boot anymore and 'git bisect' indicated the merge commit itself as the culprit. The resulting kernel log is: [ 1.734802] OMAP DSS rev 4.0 [ 1.740417] omap_hwmod: dss_core: _wait_target_disable failed [ 1.746429] omap_device: omapdss_dss.-1: new worst case deactivate latency 01 [ 1.755035] omapdss DISPC error: can't get dss_clk [ 1.760101] omapdss_dispc: probe of omapdss_dispc failed with error -2 [ 1.767333] omapdss HDMI error: can't get hdmi_clk [ 1.772399] omapdss_hdmi: probe of omapdss_hdmi failed with error -2 [ 1.780273] ------------[ cut here ]------------ [ 1.785125] WARNING: at drivers/video/omap2/dss/dispc.c:553dispc_runtime_ge) [ 1.793640] Modules linked in: [ 1.796905] ---[ end trace 6fcb132ac310d004 ]--- [ 1.801757] Unable to handle kernel NULL pointer dereference at virtualaddr0 [...] Revert it so a later version of the arm-soc merge result can be used instead.
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/74x164.c (renamed from drivers/gpio/gpio-74x164.c)33
-rw-r--r--drivers/gpio/Kconfig66
-rw-r--r--drivers/gpio/Makefile87
-rw-r--r--drivers/gpio/ab8500-gpio.c (renamed from drivers/gpio/gpio-ab8500.c)0
-rw-r--r--drivers/gpio/adp5520-gpio.c (renamed from drivers/gpio/gpio-adp5520.c)0
-rw-r--r--drivers/gpio/adp5588-gpio.c (renamed from drivers/gpio/gpio-adp5588.c)0
-rw-r--r--drivers/gpio/basic_mmio_gpio.c (renamed from drivers/gpio/gpio-generic.c)6
-rw-r--r--drivers/gpio/bt8xxgpio.c (renamed from drivers/gpio/gpio-bt8xx.c)0
-rw-r--r--drivers/gpio/cs5535-gpio.c (renamed from drivers/gpio/gpio-cs5535.c)0
-rw-r--r--drivers/gpio/gpio-da9052.c277
-rw-r--r--drivers/gpio/gpio-ep93xx.c405
-rw-r--r--drivers/gpio/gpio-exynos4.c5
-rw-r--r--drivers/gpio/gpio-mpc5200.c376
-rw-r--r--drivers/gpio/gpio-mxc.c460
-rw-r--r--drivers/gpio/gpio-mxs.c289
-rw-r--r--drivers/gpio/gpio-omap.c723
-rw-r--r--drivers/gpio/gpio-plat-samsung.c3
-rw-r--r--drivers/gpio/gpio-s5pc100.c5
-rw-r--r--drivers/gpio/gpio-s5pv210.c5
-rw-r--r--drivers/gpio/gpio-tegra.c441
-rw-r--r--drivers/gpio/gpio-u300.c5
-rw-r--r--drivers/gpio/it8761e_gpio.c (renamed from drivers/gpio/gpio-it8761e.c)2
-rw-r--r--drivers/gpio/janz-ttl.c (renamed from drivers/gpio/gpio-janz-ttl.c)0
-rw-r--r--drivers/gpio/langwell_gpio.c (renamed from drivers/gpio/gpio-langwell.c)4
-rw-r--r--drivers/gpio/max7300.c (renamed from drivers/gpio/gpio-max7300.c)2
-rw-r--r--drivers/gpio/max7301.c (renamed from drivers/gpio/gpio-max7301.c)2
-rw-r--r--drivers/gpio/max730x.c (renamed from drivers/gpio/gpio-max730x.c)2
-rw-r--r--drivers/gpio/max732x.c (renamed from drivers/gpio/gpio-max732x.c)2
-rw-r--r--drivers/gpio/mc33880.c (renamed from drivers/gpio/gpio-mc33880.c)2
-rw-r--r--drivers/gpio/mcp23s08.c (renamed from drivers/gpio/gpio-mcp23s08.c)291
-rw-r--r--drivers/gpio/ml_ioh_gpio.c (renamed from drivers/gpio/gpio-ml-ioh.c)2
-rw-r--r--drivers/gpio/pca953x.c (renamed from drivers/gpio/gpio-pca953x.c)105
-rw-r--r--drivers/gpio/pcf857x.c (renamed from drivers/gpio/gpio-pcf857x.c)2
-rw-r--r--drivers/gpio/pch_gpio.c (renamed from drivers/gpio/gpio-pch.c)0
-rw-r--r--drivers/gpio/pl061.c (renamed from drivers/gpio/gpio-pl061.c)4
-rw-r--r--drivers/gpio/rdc321x-gpio.c (renamed from drivers/gpio/gpio-rdc321x.c)0
-rw-r--r--drivers/gpio/sch_gpio.c (renamed from drivers/gpio/gpio-sch.c)2
-rw-r--r--drivers/gpio/stmpe-gpio.c (renamed from drivers/gpio/gpio-stmpe.c)0
-rw-r--r--drivers/gpio/sx150x.c (renamed from drivers/gpio/gpio-sx150x.c)0
-rw-r--r--drivers/gpio/tc3589x-gpio.c (renamed from drivers/gpio/gpio-tc3589x.c)0
-rw-r--r--drivers/gpio/timbgpio.c (renamed from drivers/gpio/gpio-timberdale.c)2
-rw-r--r--drivers/gpio/tps65910-gpio.c (renamed from drivers/gpio/gpio-tps65910.c)2
-rw-r--r--drivers/gpio/twl4030-gpio.c (renamed from drivers/gpio/gpio-twl4030.c)2
-rw-r--r--drivers/gpio/ucb1400_gpio.c (renamed from drivers/gpio/gpio-ucb1400.c)0
-rw-r--r--drivers/gpio/vr41xx_giu.c (renamed from drivers/gpio/gpio-vr41xx.c)2
-rw-r--r--drivers/gpio/vx855_gpio.c (renamed from drivers/gpio/gpio-vx855.c)0
-rw-r--r--drivers/gpio/wm831x-gpio.c (renamed from drivers/gpio/gpio-wm831x.c)2
-rw-r--r--drivers/gpio/wm8350-gpiolib.c (renamed from drivers/gpio/gpio-wm8350.c)2
-rw-r--r--drivers/gpio/wm8994-gpio.c (renamed from drivers/gpio/gpio-wm8994.c)2
-rw-r--r--drivers/gpio/xilinx_gpio.c (renamed from drivers/gpio/gpio-xilinx.c)0
50 files changed, 802 insertions, 2820 deletions
diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/74x164.c
index ff525c0958d..84e07021983 100644
--- a/drivers/gpio/gpio-74x164.c
+++ b/drivers/gpio/74x164.c
@@ -16,6 +16,9 @@
#include <linux/gpio.h>
#include <linux/slab.h>
+#define GEN_74X164_GPIO_COUNT 8
+
+
struct gen_74x164_chip {
struct spi_device *spi;
struct gpio_chip gpio_chip;
@@ -23,7 +26,9 @@ struct gen_74x164_chip {
u8 port_config;
};
-static struct gen_74x164_chip *gpio_to_74x164_chip(struct gpio_chip *gc)
+static void gen_74x164_set_value(struct gpio_chip *, unsigned, int);
+
+static struct gen_74x164_chip *gpio_to_chip(struct gpio_chip *gc)
{
return container_of(gc, struct gen_74x164_chip, gpio_chip);
}
@@ -34,9 +39,16 @@ static int __gen_74x164_write_config(struct gen_74x164_chip *chip)
&chip->port_config, sizeof(chip->port_config));
}
+static int gen_74x164_direction_output(struct gpio_chip *gc,
+ unsigned offset, int val)
+{
+ gen_74x164_set_value(gc, offset, val);
+ return 0;
+}
+
static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset)
{
- struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc);
+ struct gen_74x164_chip *chip = gpio_to_chip(gc);
int ret;
mutex_lock(&chip->lock);
@@ -49,7 +61,7 @@ static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset)
static void gen_74x164_set_value(struct gpio_chip *gc,
unsigned offset, int val)
{
- struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc);
+ struct gen_74x164_chip *chip = gpio_to_chip(gc);
mutex_lock(&chip->lock);
if (val)
@@ -61,13 +73,6 @@ static void gen_74x164_set_value(struct gpio_chip *gc,
mutex_unlock(&chip->lock);
}
-static int gen_74x164_direction_output(struct gpio_chip *gc,
- unsigned offset, int val)
-{
- gen_74x164_set_value(gc, offset, val);
- return 0;
-}
-
static int __devinit gen_74x164_probe(struct spi_device *spi)
{
struct gen_74x164_chip *chip;
@@ -99,12 +104,12 @@ static int __devinit gen_74x164_probe(struct spi_device *spi)
chip->spi = spi;
- chip->gpio_chip.label = spi->modalias;
- chip->gpio_chip.direction_output = gen_74x164_direction_output;
+ chip->gpio_chip.label = GEN_74X164_DRIVER_NAME,
+ chip->gpio_chip.direction_output = gen_74x164_direction_output;
chip->gpio_chip.get = gen_74x164_get_value;
chip->gpio_chip.set = gen_74x164_set_value;
chip->gpio_chip.base = pdata->base;
- chip->gpio_chip.ngpio = 8;
+ chip->gpio_chip.ngpio = GEN_74X164_GPIO_COUNT;
chip->gpio_chip.can_sleep = 1;
chip->gpio_chip.dev = &spi->dev;
chip->gpio_chip.owner = THIS_MODULE;
@@ -152,7 +157,7 @@ static int __devexit gen_74x164_remove(struct spi_device *spi)
static struct spi_driver gen_74x164_driver = {
.driver = {
- .name = "74x164",
+ .name = GEN_74X164_DRIVER_NAME,
.owner = THIS_MODULE,
},
.probe = gen_74x164_probe,
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 363498697c2..2967002a9f8 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -63,58 +63,33 @@ config GPIO_SYSFS
Kernel drivers may also request that a particular GPIO be
exported to userspace; this can be useful when debugging.
-config GPIO_GENERIC
- tristate
-
# put drivers in the right section, in alphabetical order
-config GPIO_DA9052
- tristate "Dialog DA9052 GPIO"
- depends on PMIC_DA9052
- help
- Say yes here to enable the GPIO driver for the DA9052 chip.
-
config GPIO_MAX730X
tristate
comment "Memory mapped GPIO drivers:"
-config GPIO_GENERIC_PLATFORM
- tristate "Generic memory-mapped GPIO controller support (MMIO platform device)"
- select GPIO_GENERIC
+config GPIO_BASIC_MMIO_CORE
+ tristate
+ help
+ Provides core functionality for basic memory-mapped GPIO controllers.
+
+config GPIO_BASIC_MMIO
+ tristate "Basic memory-mapped GPIO controllers support"
+ select GPIO_BASIC_MMIO_CORE
help
- Say yes here to support basic platform_device memory-mapped GPIO controllers.
+ Say yes here to support basic memory-mapped GPIO controllers.
config GPIO_IT8761E
tristate "IT8761E GPIO support"
help
Say yes here to support GPIO functionality of IT8761E super I/O chip.
-config GPIO_EP93XX
- def_bool y
- depends on ARCH_EP93XX
- select GPIO_GENERIC
-
config GPIO_EXYNOS4
def_bool y
depends on CPU_EXYNOS4210
-config GPIO_MPC5200
- def_bool y
- depends on PPC_MPC52xx
-
-config GPIO_MXC
- def_bool y
- depends on ARCH_MXC
- select GPIO_GENERIC
- select GENERIC_IRQ_CHIP
-
-config GPIO_MXS
- def_bool y
- depends on ARCH_MXS
- select GPIO_GENERIC
- select GENERIC_IRQ_CHIP
-
config GPIO_PLAT_SAMSUNG
def_bool y
depends on SAMSUNG_GPIOLIB_4BIT
@@ -162,6 +137,9 @@ config GPIO_SCH
The Intel Tunnel Creek processor has 5 GPIOs powered by the
core power rail and 9 from suspend power supply.
+ This driver can also be built as a module. If so, the module
+ will be called sch-gpio.
+
config GPIO_VX855
tristate "VIA VX855/VX875 GPIO"
depends on MFD_SUPPORT && PCI
@@ -224,6 +202,9 @@ config GPIO_PCA953X
16 bits: pca9535, pca9539, pca9555, tca6416
+ This driver can also be built as a module. If so, the module
+ will be called pca953x.
+
config GPIO_PCA953X_IRQ
bool "Interrupt controller support for PCA953x"
depends on GPIO_PCA953X=y
@@ -315,12 +296,17 @@ config GPIO_ADP5520
This option enables support for on-chip GPIO found
on Analog Devices ADP5520 PMICs.
+ To compile this driver as a module, choose M here: the module will
+ be called adp5520-gpio.
+
config GPIO_ADP5588
tristate "ADP5588 I2C GPIO expander"
depends on I2C
help
This option enables support for 18 GPIOs found
on Analog Devices ADP5588 GPIO Expanders.
+ To compile this driver as a module, choose M here: the module will be
+ called adp5588-gpio.
config GPIO_ADP5588_IRQ
bool "Interrupt controller support for ADP5588"
@@ -412,11 +398,10 @@ config GPIO_MAX7301
GPIO driver for Maxim MAX7301 SPI-based GPIO expander.
config GPIO_MCP23S08
- tristate "Microchip MCP23xxx I/O expander"
- depends on SPI_MASTER || I2C
+ tristate "Microchip MCP23Sxx I/O expander"
+ depends on SPI_MASTER
help
- SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017
- I/O expanders.
+ SPI driver for Microchip MCP23S08/MPC23S17 I/O expanders.
This provides a GPIO interface supporting inputs and outputs.
config GPIO_MC33880
@@ -443,6 +428,9 @@ config GPIO_UCB1400
This enables support for the Philips UCB1400 GPIO pins.
The UCB1400 is an AC97 audio codec.
+ To compile this driver as a module, choose M here: the
+ module will be called ucb1400_gpio.
+
comment "MODULbus GPIO expanders:"
config GPIO_JANZ_TTL
@@ -453,7 +441,7 @@ config GPIO_JANZ_TTL
This driver provides support for driving the pins in output
mode only. Input mode is not supported.
-config GPIO_AB8500
+config AB8500_GPIO
bool "ST-Ericsson AB8500 Mixed Signal Circuit gpio functions"
depends on AB8500_CORE && BROKEN
help
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 72071125139..b605f8ec6fb 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -4,56 +4,47 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
obj-$(CONFIG_GPIOLIB) += gpiolib.o
-# Device drivers. Generally keep list sorted alphabetically
-obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
-
-obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o
-obj-$(CONFIG_GPIO_AB8500) += gpio-ab8500.o
-obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o
-obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o
-obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
-obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
-obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
-obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
+obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o
+obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o
+obj-$(CONFIG_GPIO_BASIC_MMIO_CORE) += basic_mmio_gpio.o
+obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o
obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o
-obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o
-obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
-obj-$(CONFIG_GPIO_LANGWELL) += gpio-langwell.o
-obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o
-obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o
-obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o
-obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o
-obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
-obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o
-obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o
-obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
-obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
-obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
-obj-$(CONFIG_PLAT_NOMADIK) += gpio-nomadik.o
-obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o
-obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o
-obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o
-obj-$(CONFIG_GPIO_PCH) += gpio-pch.o
-obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
-obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
-
obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o
obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o
obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o
-
-obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
-obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
-obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o
-obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o
-obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o
-obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
-obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
-obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
+obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o
+obj-$(CONFIG_GPIO_MAX730X) += max730x.o
+obj-$(CONFIG_GPIO_MAX7300) += max7300.o
+obj-$(CONFIG_GPIO_MAX7301) += max7301.o
+obj-$(CONFIG_GPIO_MAX732X) += max732x.o
+obj-$(CONFIG_GPIO_MC33880) += mc33880.o
+obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o
+obj-$(CONFIG_GPIO_74X164) += 74x164.o
+obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o
+obj-$(CONFIG_GPIO_PCA953X) += pca953x.o
+obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o
+obj-$(CONFIG_GPIO_PCH) += pch_gpio.o
+obj-$(CONFIG_GPIO_PL061) += pl061.o
+obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o
+obj-$(CONFIG_GPIO_TC3589X) += tc3589x-gpio.o
+obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o
+obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o
+obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o
+obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o
+obj-$(CONFIG_GPIO_CS5535) += cs5535-gpio.o
+obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o
+obj-$(CONFIG_GPIO_IT8761E) += it8761e_gpio.o
+obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
+obj-$(CONFIG_GPIO_WM831X) += wm831x-gpio.o
+obj-$(CONFIG_GPIO_WM8350) += wm8350-gpiolib.o
+obj-$(CONFIG_GPIO_WM8994) += wm8994-gpio.o
+obj-$(CONFIG_GPIO_SCH) += sch_gpio.o
obj-$(CONFIG_MACH_U300) += gpio-u300.o
-obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o
-obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o
-obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o
-obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o
-obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o
-obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o
-obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o
+obj-$(CONFIG_PLAT_NOMADIK) += gpio-nomadik.o
+obj-$(CONFIG_GPIO_RDC321X) += rdc321x-gpio.o
+obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o
+obj-$(CONFIG_GPIO_SX150X) += sx150x.o
+obj-$(CONFIG_GPIO_VX855) += vx855_gpio.o
+obj-$(CONFIG_GPIO_ML_IOH) += ml_ioh_gpio.o
+obj-$(CONFIG_AB8500_GPIO) += ab8500-gpio.o
+obj-$(CONFIG_GPIO_TPS65910) += tps65910-gpio.o
diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/ab8500-gpio.c
index 970053c89ff..970053c89ff 100644
--- a/drivers/gpio/gpio-ab8500.c
+++ b/drivers/gpio/ab8500-gpio.c
diff --git a/drivers/gpio/gpio-adp5520.c b/drivers/gpio/adp5520-gpio.c
index 9f278153700..9f278153700 100644
--- a/drivers/gpio/gpio-adp5520.c
+++ b/drivers/gpio/adp5520-gpio.c
diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/adp5588-gpio.c
index 3525ad91877..3525ad91877 100644
--- a/drivers/gpio/gpio-adp5588.c
+++ b/drivers/gpio/adp5588-gpio.c
diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/basic_mmio_gpio.c
index 231714def4d..8152e9f516b 100644
--- a/drivers/gpio/gpio-generic.c
+++ b/drivers/gpio/basic_mmio_gpio.c
@@ -1,5 +1,5 @@
/*
- * Generic driver for memory-mapped GPIO controllers.
+ * Driver for basic memory-mapped GPIO controllers.
*
* Copyright 2008 MontaVista Software, Inc.
* Copyright 2008,2010 Anton Vorontsov <cbouatmailru@gmail.com>
@@ -404,7 +404,7 @@ int __devinit bgpio_init(struct bgpio_chip *bgc,
}
EXPORT_SYMBOL_GPL(bgpio_init);
-#ifdef CONFIG_GPIO_GENERIC_PLATFORM
+#ifdef CONFIG_GPIO_BASIC_MMIO
static void __iomem *bgpio_map(struct platform_device *pdev,
const char *name,
@@ -541,7 +541,7 @@ static void __exit bgpio_platform_exit(void)
}
module_exit(bgpio_platform_exit);
-#endif /* CONFIG_GPIO_GENERIC_PLATFORM */
+#endif /* CONFIG_GPIO_BASIC_MMIO */
MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers");
MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");
diff --git a/drivers/gpio/gpio-bt8xx.c b/drivers/gpio/bt8xxgpio.c
index aa4f09ad3ce..aa4f09ad3ce 100644
--- a/drivers/gpio/gpio-bt8xx.c
+++ b/drivers/gpio/bt8xxgpio.c
diff --git a/drivers/gpio/gpio-cs5535.c b/drivers/gpio/cs5535-gpio.c
index 6e16cba56ad..6e16cba56ad 100644
--- a/drivers/gpio/gpio-cs5535.c
+++ b/drivers/gpio/cs5535-gpio.c
diff --git a/drivers/gpio/gpio-da9052.c b/drivers/gpio/gpio-da9052.c
deleted file mode 100644
index 038f5eb8b13..00000000000
--- a/drivers/gpio/gpio-da9052.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * GPIO Driver for Dialog DA9052 PMICs.
- *
- * Copyright(c) 2011 Dialog Semiconductor Ltd.
- *
- * Author: David Dajun Chen <dchen@diasemi.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/uaccess.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/syscalls.h>
-#include <linux/seq_file.h>
-
-#include <linux/mfd/da9052/da9052.h>
-#include <linux/mfd/da9052/reg.h>
-#include <linux/mfd/da9052/pdata.h>
-#include <linux/mfd/da9052/gpio.h>
-
-#define DA9052_INPUT 1
-#define DA9052_OUTPUT_OPENDRAIN 2
-#define DA9052_OUTPUT_PUSHPULL 3
-
-#define DA9052_SUPPLY_VDD_IO1 0
-
-#define DA9052_DEBOUNCING_OFF 0
-#define DA9052_DEBOUNCING_ON 1
-
-#define DA9052_OUTPUT_LOWLEVEL 0
-
-#define DA9052_ACTIVE_LOW 0
-#define DA9052_ACTIVE_HIGH 1
-
-#define DA9052_GPIO_MAX_PORTS_PER_REGISTER 8
-#define DA9052_GPIO_SHIFT_COUNT(no) (no%8)
-#define DA9052_GPIO_MASK_UPPER_NIBBLE 0xF0
-#define DA9052_GPIO_MASK_LOWER_NIBBLE 0x0F
-#define DA9052_GPIO_NIBBLE_SHIFT 4
-
-struct da9052_gpio {
- struct da9052 *da9052;
- struct gpio_chip gp;
-};
-
-static inline struct da9052_gpio *to_da9052_gpio(struct gpio_chip *chip)
-{
- return container_of(chip, struct da9052_gpio, gp);
-}
-
-static unsigned char da9052_gpio_port_odd(unsigned offset)
-{
- return offset % 2;
-}
-
-static int da9052_gpio_get(struct gpio_chip *gc, unsigned offset)
-{
- struct da9052_gpio *gpio = to_da9052_gpio(gc);
- int da9052_port_direction = 0;
- int ret;
-
- ret = da9052_reg_read(gpio->da9052,
- DA9052_GPIO_0_1_REG + (offset >> 1));
- if (ret < 0)
- return ret;
-
- if (da9052_gpio_port_odd(offset)) {
- da9052_port_direction = ret & DA9052_GPIO_ODD_PORT_PIN;
- da9052_port_direction >>= 4;
- } else {
- da9052_port_direction = ret & DA9052_GPIO_EVEN_PORT_PIN;
- }
-
- switch (da9052_port_direction) {
- case DA9052_INPUT:
- if (offset < DA9052_GPIO_MAX_PORTS_PER_REGISTER)
- ret = da9052_reg_read(gpio->da9052,
- DA9052_STATUS_C_REG);
- else
- ret = da9052_reg_read(gpio->da9052,
- DA9052_STATUS_D_REG);
- if (ret < 0)
- return ret;
- if (ret & (1 << DA9052_GPIO_SHIFT_COUNT(offset)))
- return 1;
- else
- return 0;
- case DA9052_OUTPUT_PUSHPULL:
- if (da9052_gpio_port_odd(offset))
- return ret & DA9052_GPIO_ODD_PORT_MODE;
- else
- return ret & DA9052_GPIO_EVEN_PORT_MODE;
- default:
- return -EINVAL;
- }
-}
-
-static void da9052_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
-{
- struct da9052_gpio *gpio = to_da9052_gpio(gc);
- unsigned char register_value = 0;
- int ret;
-
- if (da9052_gpio_port_odd(offset)) {
- if (value) {
- register_value = DA9052_GPIO_ODD_PORT_MODE;
- ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
- DA9052_GPIO_0_1_REG,
- DA9052_GPIO_ODD_PORT_MODE,
- register_value);
- if (ret != 0)
- dev_err(gpio->da9052->dev,
- "Failed to updated gpio odd reg,%d",
- ret);
- }
- } else {
- if (value) {
- register_value = DA9052_GPIO_EVEN_PORT_MODE;
- ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
- DA9052_GPIO_0_1_REG,
- DA9052_GPIO_EVEN_PORT_MODE,
- register_value);
- if (ret != 0)
- dev_err(gpio->da9052->dev,
- "Failed to updated gpio even reg,%d",
- ret);
- }
- }
-}
-
-static int da9052_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
-{
- struct da9052_gpio *gpio = to_da9052_gpio(gc);
- unsigned char register_value;
- int ret;
-
- /* Format: function - 2 bits type - 1 bit mode - 1 bit */
- register_value = DA9052_INPUT | DA9052_ACTIVE_LOW << 2 |
- DA9052_DEBOUNCING_ON << 3;
-
- if (da9052_gpio_port_odd(offset))
- ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
- DA9052_GPIO_0_1_REG,
- DA9052_GPIO_MASK_UPPER_NIBBLE,
- (register_value <<
- DA9052_GPIO_NIBBLE_SHIFT));
- else
- ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
- DA9052_GPIO_0_1_REG,
- DA9052_GPIO_MASK_LOWER_NIBBLE,
- register_value);
-
- return ret;
-}
-
-static int da9052_gpio_direction_output(struct gpio_chip *gc,
- unsigned offset, int value)
-{
- struct da9052_gpio *gpio = to_da9052_gpio(gc);
- unsigned char register_value;
- int ret;
-
- /* Format: Function - 2 bits Type - 1 bit Mode - 1 bit */
- register_value = DA9052_OUTPUT_PUSHPULL | DA9052_SUPPLY_VDD_IO1 << 2 |
- value << 3;
-
- if (da9052_gpio_port_odd(offset))
- ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
- DA9052_GPIO_0_1_REG,
- DA9052_GPIO_MASK_UPPER_NIBBLE,
- (register_value <<
- DA9052_GPIO_NIBBLE_SHIFT));
- else
- ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
- DA9052_GPIO_0_1_REG,
- DA9052_GPIO_MASK_LOWER_NIBBLE,
- register_value);
-
- return ret;
-}
-
-static int da9052_gpio_to_irq(struct gpio_chip *gc, u32 offset)
-{
- struct da9052_gpio *gpio = to_da9052_gpio(gc);
- struct da9052 *da9052 = gpio->da9052;
-
- return da9052->irq_base + DA9052_IRQ_GPI0 + offset;
-}
-
-static struct gpio_chip reference_gp __devinitdata = {
- .label = "da9052-gpio",
- .owner = THIS_MODULE,
- .get = da9052_gpio_get,
- .set = da9052_gpio_set,
- .direction_input = da9052_gpio_direction_input,
- .direction_output = da9052_gpio_direction_output,
- .to_irq = da9052_gpio_to_irq,
- .can_sleep = 1;
- .ngpio = 16;
- .base = -1;
-};
-
-static int __devinit da9052_gpio_probe(struct platform_device *pdev)
-{
- struct da9052_gpio *gpio;
- struct da9052_pdata *pdata;
- int ret;
-
- gpio = kzalloc(sizeof(*gpio), GFP_KERNEL);
- if (gpio == NULL)
- return -ENOMEM;
-
- gpio->da9052 = dev_get_drvdata(pdev->dev.parent);
- pdata = gpio->da9052->dev->platform_data;
-
- gpio->gp = reference_gp;
- if (pdata && pdata->gpio_base)
- gpio->gp.base = pdata->gpio_base;
-
- ret = gpiochip_add(&gpio->gp);
- if (ret < 0) {
- dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
- goto err_mem;
- }
-
- platform_set_drvdata(pdev, gpio);
-
- return 0;
-
-err_mem:
- kfree(gpio);
- return ret;
-}
-
-static int __devexit da9052_gpio_remove(struct platform_device *pdev)
-{
- struct da9052_gpio *gpio = platform_get_drvdata(pdev);
- int ret;
-
- ret = gpiochip_remove(&gpio->gp);
- if (ret == 0)
- kfree(gpio);
-
- return ret;
-}
-
-static struct platform_driver da9052_gpio_driver = {
- .probe = da9052_gpio_probe,
- .remove = __devexit_p(da9052_gpio_remove),
- .driver = {
- .name = "da9052-gpio",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init da9052_gpio_init(void)
-{
- return platform_driver_register(&da9052_gpio_driver);
-}
-module_init(da9052_gpio_init);
-
-static void __exit da9052_gpio_exit(void)
-{
- return platform_driver_unregister(&da9052_gpio_driver);
-}
-module_exit(da9052_gpio_exit);
-
-MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
-MODULE_DESCRIPTION("DA9052 GPIO Device Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:da9052-gpio");
diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
deleted file mode 100644
index 3bfd3417ab1..00000000000
--- a/drivers/gpio/gpio-ep93xx.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Generic EP93xx GPIO handling
- *
- * Copyright (c) 2008 Ryan Mallon <ryan@bluewatersys.com>
- * Copyright (c) 2011 H Hartley Sweeten <hsweeten@visionengravers.com>
- *
- * Based on code originally from:
- * linux/arch/arm/mach-ep93xx/core.c
- *
- * 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.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/irq.h>
-#include <linux/slab.h>
-#include <linux/basic_mmio_gpio.h>
-
-#include <mach/hardware.h>
-
-struct ep93xx_gpio {
- void __iomem *mmio_base;
- struct bgpio_chip bgc[8];
-};
-
-/*************************************************************************
- * Interrupt handling for EP93xx on-chip GPIOs
- *************************************************************************/
-static unsigned char gpio_int_unmasked[3];
-static unsigned char gpio_int_enabled[3];
-static unsigned char gpio_int_type1[3];
-static unsigned char gpio_int_type2[3];
-static unsigned char gpio_int_debounce[3];
-
-/* Port ordering is: A B F */
-static const u8 int_type1_register_offset[3] = { 0x90, 0xac, 0x4c };
-static const u8 int_type2_register_offset[3] = { 0x94, 0xb0, 0x50 };
-static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 };
-static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 };
-static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 };
-
-static void ep93xx_gpio_update_int_params(unsigned port)
-{
- BUG_ON(port > 2);
-
- __raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
-
- __raw_writeb(gpio_int_type2[port],
- EP93XX_GPIO_REG(int_type2_register_offset[port]));
-
- __raw_writeb(gpio_int_type1[port],
- EP93XX_GPIO_REG(int_type1_register_offset[port]));
-
- __raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
- EP93XX_GPIO_REG(int_en_register_offset[port]));
-}
-
-static inline void ep93xx_gpio_int_mask(unsigned line)
-{
- gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
-}
-
-static void ep93xx_gpio_int_debounce(unsigned int irq, bool enable)
-{
- int line = irq_to_gpio(irq);
- int port = line >> 3;
- int port_mask = 1 << (line & 7);
-
- if (enable)
- gpio_int_debounce[port] |= port_mask;
- else
- gpio_int_debounce[port] &= ~port_mask;
-
- __raw_writeb(gpio_int_debounce[port],
- EP93XX_GPIO_REG(int_debounce_register_offset[port]));
-}
-
-static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
- unsigned char status;
- int i;
-
- status = __raw_readb(EP93XX_GPIO_A_INT_STATUS);
- for (i = 0; i < 8; i++) {
- if (status & (1 << i)) {
- int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
- generic_handle_irq(gpio_irq);
- }
- }
-
- status = __raw_readb(EP93XX_GPIO_B_INT_STATUS);
- for (i = 0; i < 8; i++) {
- if (status & (1 << i)) {
- int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
- generic_handle_irq(gpio_irq);
- }
- }
-}
-
-static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
- /*
- * map discontiguous hw irq range to continuous sw irq range:
- *
- * IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
- */
- int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
- int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
-
- generic_handle_irq(gpio_irq);
-}
-
-static void ep93xx_gpio_irq_ack(struct irq_data *d)
-{
- int line = irq_to_gpio(d->irq);
- int port = line >> 3;
- int port_mask = 1 << (line & 7);
-
- if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) {
- gpio_int_type2[port] ^= port_mask; /* switch edge direction */
- ep93xx_gpio_update_int_params(port);
- }
-
- __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
-}
-
-static void ep93xx_gpio_irq_mask_ack(struct irq_data *d)
-{
- int line = irq_to_gpio(d->irq);
- int port = line >> 3;
- int port_mask = 1 << (line & 7);
-
- if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH)
- gpio_int_type2[port] ^= port_mask; /* switch edge direction */
-
- gpio_int_unmasked[port] &= ~port_mask;
- ep93xx_gpio_update_int_params(port);
-
- __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
-}
-
-static void ep93xx_gpio_irq_mask(struct irq_data *d)
-{
- int line = irq_to_gpio(d->irq);
- int port = line >> 3;
-
- gpio_int_unmasked[port] &= ~(1 << (line & 7));
- ep93xx_gpio_update_int_params(port);
-}
-
-static void ep93xx_gpio_irq_unmask(struct irq_data *d)
-{
- int line = irq_to_gpio(d->irq);
- int port = line >> 3;
-
- gpio_int_unmasked[port] |= 1 << (line & 7);
- ep93xx_gpio_update_int_params(port);
-}
-
-/*
- * gpio_int_type1 controls whether the interrupt is level (0) or
- * edge (1) triggered, while gpio_int_type2 controls whether it
- * triggers on low/falling (0) or high/rising (1).
- */
-static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
-{
- const int gpio = irq_to_gpio(d->irq);
- const int port = gpio >> 3;
- const int port_mask = 1 << (gpio & 7);
- irq_flow_handler_t handler;
-
- gpio_direction_input(gpio);
-
- switch (type) {
- case IRQ_TYPE_EDGE_RISING:
- gpio_int_type1[port] |= port_mask;
- gpio_int_type2[port] |= port_mask;
- handler = handle_edge_irq;
- break;
- case IRQ_TYPE_EDGE_FALLING:
- gpio_int_type1[port] |= port_mask;
- gpio_int_type2[port] &= ~port_mask;
- handler = handle_edge_irq;
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- gpio_int_type1[port] &= ~port_mask;
- gpio_int_type2[port] |= port_mask;
- handler = handle_level_irq;
- break;
- case IRQ_TYPE_LEVEL_LOW:
- gpio_int_type1[port] &= ~port_mask;
- gpio_int_type2[port] &= ~port_mask;
- handler = handle_level_irq;
- break;
- case IRQ_TYPE_EDGE_BOTH:
- gpio_int_type1[port] |= port_mask;
- /* set initial polarity based on current input level */
- if (gpio_get_value(gpio))
- gpio_int_type2[port] &= ~port_mask; /* falling */
- else
- gpio_int_type2[port] |= port_mask; /* rising */
- handler = handle_edge_irq;
- break;
- default:
- pr_err("failed to set irq type %d for gpio %d\n", type, gpio);
- return -EINVAL;
- }
-
- __irq_set_handler_locked(d->irq, handler);
-
- gpio_int_enabled[port] |= port_mask;
-
- ep93xx_gpio_update_int_params(port);
-
- return 0;
-}
-
-static struct irq_chip ep93xx_gpio_irq_chip = {
- .name = "GPIO",
- .irq_ack = ep93xx_gpio_irq_ack,
- .irq_mask_ack = ep93xx_gpio_irq_mask_ack,
- .irq_mask = ep93xx_gpio_irq_mask,
- .irq_unmask = ep93xx_gpio_irq_unmask,
- .irq_set_type = ep93xx_gpio_irq_type,
-};
-
-static void ep93xx_gpio_init_irq(void)
-{
- int gpio_irq;
-
- for (gpio_irq = gpio_to_irq(0);
- gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
- irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
- handle_level_irq);
- set_irq_flags(gpio_irq, IRQF_VALID);
- }
-
- irq_set_chained_handler(IRQ_EP93XX_GPIO_AB,
- ep93xx_gpio_ab_irq_handler);
- irq_set_chained_handler(IRQ_EP93XX_GPIO0MUX,
- ep93xx_gpio_f_irq_handler);
- irq_set_chained_handler(IRQ_EP93XX_GPIO1MUX,
- ep93xx_gpio_f_irq_handler);
- irq_set_chained_handler(IRQ_EP93XX_GPIO2MUX,
- ep93xx_gpio_f_irq_handler);
- irq_set_chained_handler(IRQ_EP93XX_GPIO3MUX,
- ep93xx_gpio_f_irq_handler);
- irq_set_chained_handler(IRQ_EP93XX_GPIO4MUX,
- ep93xx_gpio_f_irq_handler);
- irq_set_chained_handler(IRQ_EP93XX_GPIO5MUX,
- ep93xx_gpio_f_irq_handler);
- irq_set_chained_handler(IRQ_EP93XX_GPIO6MUX,
- ep93xx_gpio_f_irq_handler);
- irq_set_chained_handler(IRQ_EP93XX_GPIO7MUX,
- ep93xx_gpio_f_irq_handler);
-}
-
-
-/*************************************************************************
- * gpiolib interface for EP93xx on-chip GPIOs
- *************************************************************************/
-struct ep93xx_gpio_bank {
- const char *label;
- int data;
- int dir;
- int base;
- bool has_debounce;
-};
-
-#define EP93XX_GPIO_BANK(_label, _data, _dir, _base, _debounce) \
- { \
- .label = _label, \
- .data = _data, \
- .dir = _dir, \
- .base = _base, \
- .has_debounce = _debounce, \
- }
-
-static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = {
- EP93XX_GPIO_BANK("A", 0x00, 0x10, 0, true),
- EP93XX_GPIO_BANK("B", 0x04, 0x14, 8, true),
- EP93XX_GPIO_BANK("C", 0x08, 0x18, 40, false),
- EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24, false),
- EP93XX_GPIO_BANK("E", 0x20, 0x24, 32, false),
- EP93XX_GPIO_BANK("F", 0x30, 0x34, 16, true),
- EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48, false),
- EP93XX_GPIO_BANK("H", 0x40, 0x44, 56, false),
-};
-
-static int ep93xx_gpio_set_debounce(struct gpio_chip *chip,
- unsigned offset, unsigned debounce)
-{
- int gpio = chip->base + offset;
- int irq = gpio_to_irq(gpio);
-
- if (irq < 0)
- return -EINVAL;
-
- ep93xx_gpio_int_debounce(irq, debounce ? true : false);
-
- return 0;
-}
-
-static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev,
- void __iomem *mmio_base, struct ep93xx_gpio_bank *bank)
-{
- void __iomem *data = mmio_base + bank->data;
- void __iomem *dir = mmio_base + bank->dir;
- int err;
-
- err = bgpio_init(bgc, dev, 1, data, NULL, NULL, dir, NULL, false);
- if (err)
- return err;
-
- bgc->gc.label = bank->label;
- bgc->gc.base = bank->base;
-
- if (bank->has_debounce)
- bgc->gc.set_debounce = ep93xx_gpio_set_debounce;
-
- return gpiochip_add(&bgc->gc);
-}
-
-static int __devinit ep93xx_gpio_probe(struct platform_device *pdev)
-{
- struct ep93xx_gpio *ep93xx_gpio;
- struct resource *res;
- void __iomem *mmio;
- int i;
- int ret;
-
- ep93xx_gpio = kzalloc(sizeof(*ep93xx_gpio), GFP_KERNEL);
- if (!ep93xx_gpio)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- ret = -ENXIO;
- goto exit_free;
- }
-
- if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
- ret = -EBUSY;
- goto exit_free;
- }
-
- mmio = ioremap(res->start, resource_size(res));
- if (!mmio) {
- ret = -ENXIO;
- goto exit_release;
- }
- ep93xx_gpio->mmio_base = mmio;
-
- /* Default all ports to GPIO */
- ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
- EP93XX_SYSCON_DEVCFG_GONK |
- EP93XX_SYSCON_DEVCFG_EONIDE |
- EP93XX_SYSCON_DEVCFG_GONIDE |
- EP93XX_SYSCON_DEVCFG_HONIDE);
-
- for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
- struct bgpio_chip *bgc = &ep93xx_gpio->bgc[i];
- struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
-
- if (ep93xx_gpio_add_bank(bgc, &pdev->dev, mmio, bank))
- dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
- bank->label);
- }
-
- ep93xx_gpio_init_irq();
-
- return 0;
-
-exit_release:
- release_mem_region(res->start, resource_size(res));
-exit_free:
- kfree(ep93xx_gpio);
- dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, ret);
- return ret;
-}
-
-static struct platform_driver ep93xx_gpio_driver = {
- .driver = {
- .name = "gpio-ep93xx",
- .owner = THIS_MODULE,
- },
- .probe = ep93xx_gpio_probe,
-};
-
-static int __init ep93xx_gpio_init(void)
-{
- return platform_driver_register(&ep93xx_gpio_driver);
-}
-postcore_initcall(ep93xx_gpio_init);
-
-MODULE_AUTHOR("Ryan Mallon <ryan@bluewatersys.com> "
- "H Hartley Sweeten <hsweeten@visionengravers.com>");
-MODULE_DESCRIPTION("EP93XX GPIO driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-exynos4.c b/drivers/gpio/gpio-exynos4.c
index d24b337cf1a..9029835112e 100644
--- a/drivers/gpio/gpio-exynos4.c
+++ b/drivers/gpio/gpio-exynos4.c
@@ -1,9 +1,10 @@
-/*
- * EXYNOS4 - GPIOlib support
+/* linux/arch/arm/mach-exynos4/gpiolib.c
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
+ * EXYNOS4 - GPIOlib support
+ *
* 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.
diff --git a/drivers/gpio/gpio-mpc5200.c b/drivers/gpio/gpio-mpc5200.c
deleted file mode 100644
index 52d3ed20810..00000000000
--- a/drivers/gpio/gpio-mpc5200.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * MPC52xx gpio driver
- *
- * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- *
- * 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.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/of.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/of_gpio.h>
-#include <linux/io.h>
-#include <linux/of_platform.h>
-
-#include <asm/gpio.h>
-#include <asm/mpc52xx.h>
-#include <sysdev/fsl_soc.h>
-
-static DEFINE_SPINLOCK(gpio_lock);
-
-struct mpc52xx_gpiochip {
- struct of_mm_gpio_chip mmchip;
- unsigned int shadow_dvo;
- unsigned int shadow_gpioe;
- unsigned int shadow_ddr;
-};
-
-/*
- * GPIO LIB API implementation for wakeup GPIOs.
- *
- * There's a maximum of 8 wakeup GPIOs. Which of these are available
- * for use depends on your board setup.
- *
- * 0 -> GPIO_WKUP_7
- * 1 -> GPIO_WKUP_6
- * 2 -> PSC6_1
- * 3 -> PSC6_0
- * 4 -> ETH_17
- * 5 -> PSC3_9
- * 6 -> PSC2_4
- * 7 -> PSC1_4
- *
- */
-static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
- unsigned int ret;
-
- ret = (in_8(&regs->wkup_ival) >> (7 - gpio)) & 1;
-
- pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret);
-
- return ret;
-}
-
-static inline void
-__mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct mpc52xx_gpiochip *chip = container_of(mm_gc,
- struct mpc52xx_gpiochip, mmchip);
- struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
-
- if (val)
- chip->shadow_dvo |= 1 << (7 - gpio);
- else
- chip->shadow_dvo &= ~(1 << (7 - gpio));
-
- out_8(&regs->wkup_dvo, chip->shadow_dvo);
-}
-
-static void
-mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gpio_lock, flags);
-
- __mpc52xx_wkup_gpio_set(gc, gpio, val);
-
- spin_unlock_irqrestore(&gpio_lock, flags);
-
- pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
-}
-
-static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct mpc52xx_gpiochip *chip = container_of(mm_gc,
- struct mpc52xx_gpiochip, mmchip);
- struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
- unsigned long flags;
-
- spin_lock_irqsave(&gpio_lock, flags);
-
- /* set the direction */
- chip->shadow_ddr &= ~(1 << (7 - gpio));
- out_8(&regs->wkup_ddr, chip->shadow_ddr);
-
- /* and enable the pin */
- chip->shadow_gpioe |= 1 << (7 - gpio);
- out_8(&regs->wkup_gpioe, chip->shadow_gpioe);
-
- spin_unlock_irqrestore(&gpio_lock, flags);
-
- return 0;
-}
-
-static int
-mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
- struct mpc52xx_gpiochip *chip = container_of(mm_gc,
- struct mpc52xx_gpiochip, mmchip);
- unsigned long flags;
-
- spin_lock_irqsave(&gpio_lock, flags);
-
- __mpc52xx_wkup_gpio_set(gc, gpio, val);
-
- /* Then set direction */
- chip->shadow_ddr |= 1 << (7 - gpio);
- out_8(&regs->wkup_ddr, chip->shadow_ddr);
-
- /* Finally enable the pin */
- chip->shadow_gpioe |= 1 << (7 - gpio);
- out_8(&regs->wkup_gpioe, chip->shadow_gpioe);
-
- spin_unlock_irqrestore(&gpio_lock, flags);
-
- pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
-
- return 0;
-}
-
-static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev)
-{
- struct mpc52xx_gpiochip *chip;
- struct mpc52xx_gpio_wkup __iomem *regs;
- struct gpio_chip *gc;
- int ret;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
-
- gc = &chip->mmchip.gc;
-
- gc->ngpio = 8;
- gc->direction_input = mpc52xx_wkup_gpio_dir_in;
- gc->direction_output = mpc52xx_wkup_gpio_dir_out;
- gc->get = mpc52xx_wkup_gpio_get;
- gc->set = mpc52xx_wkup_gpio_set;
-
- ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip);
- if (ret)
- return ret;
-
- regs = chip->mmchip.regs;
- chip->shadow_gpioe = in_8(&regs->wkup_gpioe);
- chip->shadow_ddr = in_8(&regs->wkup_ddr);
- chip->shadow_dvo = in_8(&regs->wkup_dvo);
-
- return 0;
-}
-
-static int mpc52xx_gpiochip_remove(struct platform_device *ofdev)
-{
- return -EBUSY;
-}
-
-static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = {
- { .compatible = "fsl,mpc5200-gpio-wkup", },
- {}
-};
-
-static struct platform_driver mpc52xx_wkup_gpiochip_driver = {
- .driver = {
- .name = "mpc5200-gpio-wkup",
- .owner = THIS_MODULE,
- .of_match_table = mpc52xx_wkup_gpiochip_match,
- },
- .probe = mpc52xx_wkup_gpiochip_probe,
- .remove = mpc52xx_gpiochip_remove,
-};
-
-/*
- * GPIO LIB API implementation for simple GPIOs
- *
- * There's a maximum of 32 simple GPIOs. Which of these are available
- * for use depends on your board setup.
- * The numbering reflects the bit numbering in the port registers:
- *
- * 0..1 > reserved
- * 2..3 > IRDA
- * 4..7 > ETHR
- * 8..11 > reserved
- * 12..15 > USB
- * 16..17 > reserved
- * 18..23 > PSC3
- * 24..27 > PSC2
- * 28..31 > PSC1
- */
-static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
- unsigned int ret;
-
- ret = (in_be32(&regs->simple_ival) >> (31 - gpio)) & 1;
-
- return ret;
-}
-
-static inline void
-__mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct mpc52xx_gpiochip *chip = container_of(mm_gc,
- struct mpc52xx_gpiochip, mmchip);
- struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
-
- if (val)
- chip->shadow_dvo |= 1 << (31 - gpio);
- else
- chip->shadow_dvo &= ~(1 << (31 - gpio));
- out_be32(&regs->simple_dvo, chip->shadow_dvo);
-}
-
-static void
-mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gpio_lock, flags);
-
- __mpc52xx_simple_gpio_set(gc, gpio, val);
-
- spin_unlock_irqrestore(&gpio_lock, flags);
-
- pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
-}
-
-static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct mpc52xx_gpiochip *chip = container_of(mm_gc,
- struct mpc52xx_gpiochip, mmchip);
- struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
- unsigned long flags;
-
- spin_lock_irqsave(&gpio_lock, flags);
-
- /* set the direction */
- chip->shadow_ddr &= ~(1 << (31 - gpio));
- out_be32(&regs->simple_ddr, chip->shadow_ddr);
-
- /* and enable the pin */
- chip->shadow_gpioe |= 1 << (31 - gpio);
- out_be32(&regs->simple_gpioe, chip->shadow_gpioe);
-
- spin_unlock_irqrestore(&gpio_lock, flags);
-
- return 0;
-}
-
-static int
-mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct mpc52xx_gpiochip *chip = container_of(mm_gc,
- struct mpc52xx_gpiochip, mmchip);
- struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
- unsigned long flags;
-
- spin_lock_irqsave(&gpio_lock, flags);
-
- /* First set initial value */
- __mpc52xx_simple_gpio_set(gc, gpio, val);
-
- /* Then set direction */
- chip->shadow_ddr |= 1 << (31 - gpio);
- out_be32(&regs->simple_ddr, chip->shadow_ddr);
-
- /* Finally enable the pin */
- chip->shadow_gpioe |= 1 << (31 - gpio);
- out_be32(&regs->simple_gpioe, chip->shadow_gpioe);
-
- spin_unlock_irqrestore(&gpio_lock, flags);
-
- pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
-
- return 0;
-}
-
-static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev)
-{
- struct mpc52xx_gpiochip *chip;
- struct gpio_chip *gc;
- struct mpc52xx_gpio __iomem *regs;
- int ret;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
-
- gc = &chip->mmchip.gc;
-
- gc->ngpio = 32;
- gc->direction_input = mpc52xx_simple_gpio_dir_in;
- gc->direction_output = mpc52xx_simple_gpio_dir_out;
- gc->get = mpc52xx_simple_gpio_get;
- gc->set = mpc52xx_simple_gpio_set;
-
- ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip);
- if (ret)
- return ret;
-
- regs = chip->mmchip.regs;
- chip->shadow_gpioe = in_be32(&regs->simple_gpioe);
- chip->shadow_ddr = in_be32(&regs->simple_ddr);
- chip->shadow_dvo = in_be32(&regs->simple_dvo);
-
- return 0;
-}
-
-static const struct of_device_id mpc52xx_simple_gpiochip_match[] = {
- { .compatible = "fsl,mpc5200-gpio", },
- {}
-};
-
-static struct platform_driver mpc52xx_simple_gpiochip_driver = {
- .driver = {
- .name = "mpc5200-gpio",
- .owner = THIS_MODULE,
- .of_match_table = mpc52xx_simple_gpiochip_match,
- },
- .probe = mpc52xx_simple_gpiochip_probe,
- .remove = mpc52xx_gpiochip_remove,
-};
-
-static int __init mpc52xx_gpio_init(void)
-{
- if (platform_driver_register(&mpc52xx_wkup_gpiochip_driver))
- printk(KERN_ERR "Unable to register wakeup GPIO driver\n");
-
- if (platform_driver_register(&mpc52xx_simple_gpiochip_driver))
- printk(KERN_ERR "Unable to register simple GPIO driver\n");
-
- return 0;
-}
-
-
-/* Make sure we get initialised before anyone else tries to use us */
-subsys_initcall(mpc52xx_gpio_init);
-
-/* No exit call at the moment as we cannot unregister of gpio chips */
-
-MODULE_DESCRIPTION("Freescale MPC52xx gpio driver");
-MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
-MODULE_LICENSE("GPL v2");
-
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
deleted file mode 100644
index 89fda58db90..00000000000
--- a/drivers/gpio/gpio-mxc.c
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- *
- * Based on code from Freescale,
- * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/basic_mmio_gpio.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <asm-generic/bug.h>
-
-enum mxc_gpio_hwtype {
- IMX1_GPIO, /* runs on i.mx1 */
- IMX21_GPIO, /* runs on i.mx21 and i.mx27 */
- IMX31_GPIO, /* runs on all other i.mx */
-};
-
-/* device type dependent stuff */
-struct mxc_gpio_hwdata {
- unsigned dr_reg;
- unsigned gdir_reg;
- unsigned psr_reg;
- unsigned icr1_reg;
- unsigned icr2_reg;
- unsigned imr_reg;
- unsigned isr_reg;
- unsigned low_level;
- unsigned high_level;
- unsigned rise_edge;
- unsigned fall_edge;
-};
-
-struct mxc_gpio_port {
- struct list_head node;
- void __iomem *base;
- int irq;
- int irq_high;
- int virtual_irq_start;
- struct bgpio_chip bgc;
- u32 both_edges;
-};
-
-static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = {
- .dr_reg = 0x1c,
- .gdir_reg = 0x00,
- .psr_reg = 0x24,
- .icr1_reg = 0x28,
- .icr2_reg = 0x2c,
- .imr_reg = 0x30,
- .isr_reg = 0x34,
- .low_level = 0x03,
- .high_level = 0x02,
- .rise_edge = 0x00,
- .fall_edge = 0x01,
-};
-
-static struct mxc_gpio_hwdata imx31_gpio_hwdata = {
- .dr_reg = 0x00,
- .gdir_reg = 0x04,
- .psr_reg = 0x08,
- .icr1_reg = 0x0c,
- .icr2_reg = 0x10,
- .imr_reg = 0x14,
- .isr_reg = 0x18,
- .low_level = 0x00,
- .high_level = 0x01,
- .rise_edge = 0x02,
- .fall_edge = 0x03,
-};
-
-static enum mxc_gpio_hwtype mxc_gpio_hwtype;
-static struct mxc_gpio_hwdata *mxc_gpio_hwdata;
-
-#define GPIO_DR (mxc_gpio_hwdata->dr_reg)
-#define GPIO_GDIR (mxc_gpio_hwdata->gdir_reg)
-#define GPIO_PSR (mxc_gpio_hwdata->psr_reg)
-#define GPIO_ICR1 (mxc_gpio_hwdata->icr1_reg)
-#define GPIO_ICR2 (mxc_gpio_hwdata->icr2_reg)
-#define GPIO_IMR (mxc_gpio_hwdata->imr_reg)
-#define GPIO_ISR (mxc_gpio_hwdata->isr_reg)
-
-#define GPIO_INT_LOW_LEV (mxc_gpio_hwdata->low_level)
-#define GPIO_INT_HIGH_LEV (mxc_gpio_hwdata->high_level)
-#define GPIO_INT_RISE_EDGE (mxc_gpio_hwdata->rise_edge)
-#define GPIO_INT_FALL_EDGE (mxc_gpio_hwdata->fall_edge)
-#define GPIO_INT_NONE 0x4
-
-static struct platform_device_id mxc_gpio_devtype[] = {
- {
- .name = "imx1-gpio",
- .driver_data = IMX1_GPIO,
- }, {
- .name = "imx21-gpio",
- .driver_data = IMX21_GPIO,
- }, {
- .name = "imx31-gpio",
- .driver_data = IMX31_GPIO,
- }, {
- /* sentinel */
- }
-};
-
-static const struct of_device_id mxc_gpio_dt_ids[] = {
- { .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], },
- { .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], },
- { .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], },
- { /* sentinel */ }
-};
-
-/*
- * MX2 has one interrupt *for all* gpio ports. The list is used
- * to save the references to all ports, so that mx2_gpio_irq_handler
- * can walk through all interrupt status registers.
- */
-static LIST_HEAD(mxc_gpio_ports);
-
-/* Note: This driver assumes 32 GPIOs are handled in one register */
-
-static int gpio_set_irq_type(struct irq_data *d, u32 type)
-{
- u32 gpio = irq_to_gpio(d->irq);
- struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- struct mxc_gpio_port *port = gc->private;
- u32 bit, val;
- int edge;
- void __iomem *reg = port->base;
-
- port->both_edges &= ~(1 << (gpio & 31));
- switch (type) {
- case IRQ_TYPE_EDGE_RISING:
- edge = GPIO_INT_RISE_EDGE;
- break;
- case IRQ_TYPE_EDGE_FALLING:
- edge = GPIO_INT_FALL_EDGE;
- break;
- case IRQ_TYPE_EDGE_BOTH:
- val = gpio_get_value(gpio);
- if (val) {
- edge = GPIO_INT_LOW_LEV;
- pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
- } else {
- edge = GPIO_INT_HIGH_LEV;
- pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
- }
- port->both_edges |= 1 << (gpio & 31);
- break;
- case IRQ_TYPE_LEVEL_LOW:
- edge = GPIO_INT_LOW_LEV;
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- edge = GPIO_INT_HIGH_LEV;
- break;
- default:
- return -EINVAL;
- }
-
- reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
- bit = gpio & 0xf;
- val = readl(reg) & ~(0x3 << (bit << 1));
- writel(val | (edge << (bit << 1)), reg);
- writel(1 << (gpio & 0x1f), port->base + GPIO_ISR);
-
- return 0;
-}
-
-static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
-{
- void __iomem *reg = port->base;
- u32 bit, val;
- int edge;
-
- reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
- bit = gpio & 0xf;
- val = readl(reg);
- edge = (val >> (bit << 1)) & 3;
- val &= ~(0x3 << (bit << 1));
- if (edge == GPIO_INT_HIGH_LEV) {
- edge = GPIO_INT_LOW_LEV;
- pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
- } else if (edge == GPIO_INT_LOW_LEV) {
- edge = GPIO_INT_HIGH_LEV;
- pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
- } else {
- pr_err("mxc: invalid configuration for GPIO %d: %x\n",
- gpio, edge);
- return;
- }
- writel(val | (edge << (bit << 1)), reg);
-}
-
-/* handle 32 interrupts in one status register */
-static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
-{
- u32 gpio_irq_no_base = port->virtual_irq_start;
-
- while (irq_stat != 0) {
- int irqoffset = fls(irq_stat) - 1;
-
- if (port->both_edges & (1 << irqoffset))
- mxc_flip_edge(port, irqoffset);
-
- generic_handle_irq(gpio_irq_no_base + irqoffset);
-
- irq_stat &= ~(1 << irqoffset);
- }
-}
-
-/* MX1 and MX3 has one interrupt *per* gpio port */
-static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
-{
- u32 irq_stat;
- struct mxc_gpio_port *port = irq_get_handler_data(irq);
-
- irq_stat = readl(port->base + GPIO_ISR) & readl(port->base + GPIO_IMR);
-
- mxc_gpio_irq_handler(port, irq_stat);
-}
-
-/* MX2 has one interrupt *for all* gpio ports */
-static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
-{
- u32 irq_msk, irq_stat;
- struct mxc_gpio_port *port;
-
- /* walk through all interrupt status registers */
- list_for_each_entry(port, &mxc_gpio_ports, node) {
- irq_msk = readl(port->base + GPIO_IMR);
- if (!irq_msk)
- continue;
-
- irq_stat = readl(port->base + GPIO_ISR) & irq_msk;
- if (irq_stat)
- mxc_gpio_irq_handler(port, irq_stat);
- }
-}
-
-/*
- * Set interrupt number "irq" in the GPIO as a wake-up source.
- * While system is running, all registered GPIO interrupts need to have
- * wake-up enabled. When system is suspended, only selected GPIO interrupts
- * need to have wake-up enabled.
- * @param irq interrupt source number
- * @param enable enable as wake-up if equal to non-zero
- * @return This function returns 0 on success.
- */
-static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
-{
- u32 gpio = irq_to_gpio(d->irq);
- u32 gpio_idx = gpio & 0x1F;
- struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- struct mxc_gpio_port *port = gc->private;
-
- if (enable) {
- if (port->irq_high && (gpio_idx >= 16))
- enable_irq_wake(port->irq_high);
- else
- enable_irq_wake(port->irq);
- } else {
- if (port->irq_high && (gpio_idx >= 16))
- disable_irq_wake(port->irq_high);
- else
- disable_irq_wake(port->irq);
- }
-
- return 0;
-}
-
-static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port)
-{
- struct irq_chip_generic *gc;
- struct irq_chip_type *ct;
-
- gc = irq_alloc_generic_chip("gpio-mxc", 1, port->virtual_irq_start,
- port->base, handle_level_irq);
- gc->private = port;
-
- ct = gc->chip_types;
- ct->chip.irq_ack = irq_gc_ack,
- ct->chip.irq_mask = irq_gc_mask_clr_bit;
- ct->chip.irq_unmask = irq_gc_mask_set_bit;
- ct->chip.irq_set_type = gpio_set_irq_type;
- ct->chip.irq_set_wake = gpio_set_wake_irq,
- ct->regs.ack = GPIO_ISR;
- ct->regs.mask = GPIO_IMR;
-
- irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK,
- IRQ_NOREQUEST, 0);
-}
-
-static void __devinit mxc_gpio_get_hw(struct platform_device *pdev)
-{
- const struct of_device_id *of_id =
- of_match_device(mxc_gpio_dt_ids, &pdev->dev);
- enum mxc_gpio_hwtype hwtype;
-
- if (of_id)
- pdev->id_entry = of_id->data;
- hwtype = pdev->id_entry->driver_data;
-
- if (mxc_gpio_hwtype) {
- /*
- * The driver works with a reasonable presupposition,
- * that is all gpio ports must be the same type when
- * running on one soc.
- */
- BUG_ON(mxc_gpio_hwtype != hwtype);
- return;
- }
-
- if (hwtype == IMX31_GPIO)
- mxc_gpio_hwdata = &imx31_gpio_hwdata;
- else
- mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata;
-
- mxc_gpio_hwtype = hwtype;
-}
-
-static int __devinit mxc_gpio_probe(struct platform_device *pdev)
-{
- struct device_node *np = pdev->dev.of_node;
- struct mxc_gpio_port *port;
- struct resource *iores;
- int err;
-
- mxc_gpio_get_hw(pdev);
-
- port = kzalloc(sizeof(struct mxc_gpio_port), GFP_KERNEL);
- if (!port)
- return -ENOMEM;
-
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iores) {
- err = -ENODEV;
- goto out_kfree;
- }
-
- 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 = platform_get_irq(pdev, 0);
- if (port->irq < 0) {
- err = -EINVAL;
- goto out_iounmap;
- }
-
- /* disable the interrupt and clear the status */
- writel(0, port->base + GPIO_IMR);
- writel(~0, port->base + GPIO_ISR);
-
- if (mxc_gpio_hwtype == IMX21_GPIO) {
- /* setup one handler for all GPIO interrupts */
- if (pdev->id == 0)
- irq_set_chained_handler(port->irq,
- mx2_gpio_irq_handler);
- } else {
- /* setup one handler for each entry */
- irq_set_chained_handler(port->irq, mx3_gpio_irq_handler);
- irq_set_handler_data(port->irq, port);
- if (port->irq_high > 0) {
- /* setup handler for GPIO 16 to 31 */
- irq_set_chained_handler(port->irq_high,
- mx3_gpio_irq_handler);
- irq_set_handler_data(port->irq_high, port);
- }
- }
-
- err = bgpio_init(&port->bgc, &pdev->dev, 4,
- port->base + GPIO_PSR,
- port->base + GPIO_DR, NULL,
- port->base + GPIO_GDIR, NULL, false);
- if (err)
- goto out_iounmap;
-
- port->bgc.gc.base = pdev->id * 32;
- port->bgc.dir = port->bgc.read_reg(port->bgc.reg_dir);
- port->bgc.data = port->bgc.read_reg(port->bgc.reg_set);
-
- err = gpiochip_add(&port->bgc.gc);
- if (err)
- goto out_bgpio_remove;
-
- /*
- * In dt case, we use gpio number range dynamically
- * allocated by gpio core.
- */
- port->virtual_irq_start = MXC_GPIO_IRQ_START + (np ? port->bgc.gc.base :
- pdev->id * 32);
-
- /* gpio-mxc can be a generic irq chip */
- mxc_gpio_init_gc(port);
-
- list_add_tail(&port->node, &mxc_gpio_ports);
-
- return 0;
-
-out_bgpio_remove:
- bgpio_remove(&port->bgc);
-out_iounmap:
- 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);
- return err;
-}
-
-static struct platform_driver mxc_gpio_driver = {
- .driver = {
- .name = "gpio-mxc",
- .owner = THIS_MODULE,
- .of_match_table = mxc_gpio_dt_ids,
- },
- .probe = mxc_gpio_probe,
- .id_table = mxc_gpio_devtype,
-};
-
-static int __init gpio_mxc_init(void)
-{
- return platform_driver_register(&mxc_gpio_driver);
-}
-postcore_initcall(gpio_mxc_init);
-
-MODULE_AUTHOR("Freescale Semiconductor, "
- "Daniel Mack <danielncaiaq.de>, "
- "Juergen Beisert <kernel@pengutronix.de>");
-MODULE_DESCRIPTION("Freescale MXC GPIO");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
deleted file mode 100644
index d8cafba8c82..00000000000
--- a/drivers/gpio/gpio-mxs.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- *
- * Based on code from Freescale,
- * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/basic_mmio_gpio.h>
-#include <mach/mxs.h>
-
-#define MXS_SET 0x4
-#define MXS_CLR 0x8
-
-#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
-#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
-#define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
-#define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
-#define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
-#define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
-#define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
-#define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
-
-#define GPIO_INT_FALL_EDGE 0x0
-#define GPIO_INT_LOW_LEV 0x1
-#define GPIO_INT_RISE_EDGE 0x2
-#define GPIO_INT_HIGH_LEV 0x3
-#define GPIO_INT_LEV_MASK (1 << 0)
-#define GPIO_INT_POL_MASK (1 << 1)
-
-struct mxs_gpio_port {
- void __iomem *base;
- int id;
- int irq;
- int virtual_irq_start;
- struct bgpio_chip bgc;
-};
-
-/* Note: This driver assumes 32 GPIOs are handled in one register */
-
-static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
-{
- u32 gpio = irq_to_gpio(d->irq);
- u32 pin_mask = 1 << (gpio & 31);
- struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- struct mxs_gpio_port *port = gc->private;
- void __iomem *pin_addr;
- int edge;
-
- switch (type) {
- case IRQ_TYPE_EDGE_RISING:
- edge = GPIO_INT_RISE_EDGE;
- break;
- case IRQ_TYPE_EDGE_FALLING:
- edge = GPIO_INT_FALL_EDGE;
- break;
- case IRQ_TYPE_LEVEL_LOW:
- edge = GPIO_INT_LOW_LEV;
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- edge = GPIO_INT_HIGH_LEV;
- break;
- default:
- return -EINVAL;
- }
-
- /* set level or edge */
- pin_addr = port->base + PINCTRL_IRQLEV(port->id);
- if (edge & GPIO_INT_LEV_MASK)
- writel(pin_mask, pin_addr + MXS_SET);
- else
- writel(pin_mask, pin_addr + MXS_CLR);
-
- /* set polarity */
- pin_addr = port->base + PINCTRL_IRQPOL(port->id);
- if (edge & GPIO_INT_POL_MASK)
- writel(pin_mask, pin_addr + MXS_SET);
- else
- writel(pin_mask, pin_addr + MXS_CLR);
-
- writel(1 << (gpio & 0x1f),
- port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR);
-
- return 0;
-}
-
-/* MXS has one interrupt *per* gpio port */
-static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
-{
- u32 irq_stat;
- struct mxs_gpio_port *port = irq_get_handler_data(irq);
- u32 gpio_irq_no_base = port->virtual_irq_start;
-
- desc->irq_data.chip->irq_ack(&desc->irq_data);
-
- irq_stat = readl(port->base + PINCTRL_IRQSTAT(port->id)) &
- readl(port->base + PINCTRL_IRQEN(port->id));
-
- while (irq_stat != 0) {
- int irqoffset = fls(irq_stat) - 1;
- generic_handle_irq(gpio_irq_no_base + irqoffset);
- irq_stat &= ~(1 << irqoffset);
- }
-}
-
-/*
- * Set interrupt number "irq" in the GPIO as a wake-up source.
- * While system is running, all registered GPIO interrupts need to have
- * wake-up enabled. When system is suspended, only selected GPIO interrupts
- * need to have wake-up enabled.
- * @param irq interrupt source number
- * @param enable enable as wake-up if equal to non-zero
- * @return This function returns 0 on success.
- */
-static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
-{
- struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- struct mxs_gpio_port *port = gc->private;
-
- if (enable)
- enable_irq_wake(port->irq);
- else
- disable_irq_wake(port->irq);
-
- return 0;
-}
-
-static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port)
-{
- struct irq_chip_generic *gc;
- struct irq_chip_type *ct;
-
- gc = irq_alloc_generic_chip("gpio-mxs", 1, port->virtual_irq_start,
- port->base, handle_level_irq);
- gc->private = port;
-
- ct = gc->chip_types;
- ct->chip.irq_ack = irq_gc_ack,
- ct->chip.irq_mask = irq_gc_mask_clr_bit;
- ct->chip.irq_unmask = irq_gc_mask_set_bit;
- ct->chip.irq_set_type = mxs_gpio_set_irq_type;
- ct->chip.irq_set_wake = mxs_gpio_set_wake_irq,
- ct->regs.ack = PINCTRL_IRQSTAT(port->id) + MXS_CLR;
- ct->regs.mask = PINCTRL_IRQEN(port->id);
-
- irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0);
-}
-
-static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
-{
- struct bgpio_chip *bgc = to_bgpio_chip(gc);
- struct mxs_gpio_port *port =
- container_of(bgc, struct mxs_gpio_port, bgc);
-
- return port->virtual_irq_start + offset;
-}
-
-static int __devinit mxs_gpio_probe(struct platform_device *pdev)
-{
- static void __iomem *base;
- struct mxs_gpio_port *port;
- struct resource *iores = NULL;
- int err;
-
- port = kzalloc(sizeof(struct mxs_gpio_port), GFP_KERNEL);
- if (!port)
- return -ENOMEM;
-
- port->id = pdev->id;
- port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32;
-
- /*
- * map memory region only once, as all the gpio ports
- * share the same one
- */
- if (!base) {
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iores) {
- err = -ENODEV;
- goto out_kfree;
- }
-
- if (!request_mem_region(iores->start, resource_size(iores),
- pdev->name)) {
- err = -EBUSY;
- goto out_kfree;
- }
-
- base = ioremap(iores->start, resource_size(iores));
- if (!base) {
- err = -ENOMEM;
- goto out_release_mem;
- }
- }
- port->base = base;
-
- port->irq = platform_get_irq(pdev, 0);
- if (port->irq < 0) {
- err = -EINVAL;
- goto out_iounmap;
- }
-
- /*
- * select the pin interrupt functionality but initially
- * disable the interrupts
- */
- writel(~0U, port->base + PINCTRL_PIN2IRQ(port->id));
- writel(0, port->base + PINCTRL_IRQEN(port->id));
-
- /* clear address has to be used to clear IRQSTAT bits */
- writel(~0U, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR);
-
- /* gpio-mxs can be a generic irq chip */
- mxs_gpio_init_gc(port);
-
- /* setup one handler for each entry */
- irq_set_chained_handler(port->irq, mxs_gpio_irq_handler);
- irq_set_handler_data(port->irq, port);
-
- err = bgpio_init(&port->bgc, &pdev->dev, 4,
- port->base + PINCTRL_DIN(port->id),
- port->base + PINCTRL_DOUT(port->id), NULL,
- port->base + PINCTRL_DOE(port->id), NULL, false);
- if (err)
- goto out_iounmap;
-
- port->bgc.gc.to_irq = mxs_gpio_to_irq;
- port->bgc.gc.base = port->id * 32;
-
- err = gpiochip_add(&port->bgc.gc);
- if (err)
- goto out_bgpio_remove;
-
- return 0;
-
-out_bgpio_remove:
- bgpio_remove(&port->bgc);
-out_iounmap:
- if (iores)
- iounmap(port->base);
-out_release_mem:
- if (iores)
- release_mem_region(iores->start, resource_size(iores));
-out_kfree:
- kfree(port);
- dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
- return err;
-}
-
-static struct platform_driver mxs_gpio_driver = {
- .driver = {
- .name = "gpio-mxs",
- .owner = THIS_MODULE,
- },
- .probe = mxs_gpio_probe,
-};
-
-static int __init mxs_gpio_init(void)
-{
- return platform_driver_register(&mxs_gpio_driver);
-}
-postcore_initcall(mxs_gpio_init);
-
-MODULE_AUTHOR("Freescale Semiconductor, "
- "Daniel Mack <danielncaiaq.de>, "
- "Juergen Beisert <kernel@pengutronix.de>");
-MODULE_DESCRIPTION("Freescale MXS GPIO");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 0599854e221..35bebde23e8 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -54,11 +54,6 @@ struct gpio_bank {
struct device *dev;
bool dbck_flag;
int stride;
- u32 width;
-
- void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable);
-
- struct omap_gpio_reg_offs *regs;
};
#ifdef CONFIG_ARCH_OMAP3
@@ -84,18 +79,121 @@ static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
*/
static struct gpio_bank *gpio_bank;
+static int bank_width;
+
/* TODO: Analyze removing gpio_bank_count usage from driver code */
int gpio_bank_count;
-#define GPIO_INDEX(bank, gpio) (gpio % bank->width)
-#define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio))
+static inline struct gpio_bank *get_gpio_bank(int gpio)
+{
+ if (cpu_is_omap15xx()) {
+ if (OMAP_GPIO_IS_MPUIO(gpio))
+ return &gpio_bank[0];
+ return &gpio_bank[1];
+ }
+ if (cpu_is_omap16xx()) {
+ if (OMAP_GPIO_IS_MPUIO(gpio))
+ return &gpio_bank[0];
+ return &gpio_bank[1 + (gpio >> 4)];
+ }
+ if (cpu_is_omap7xx()) {
+ if (OMAP_GPIO_IS_MPUIO(gpio))
+ return &gpio_bank[0];
+ return &gpio_bank[1 + (gpio >> 5)];
+ }
+ if (cpu_is_omap24xx())
+ return &gpio_bank[gpio >> 5];
+ if (cpu_is_omap34xx() || cpu_is_omap44xx())
+ return &gpio_bank[gpio >> 5];
+ BUG();
+ return NULL;
+}
+
+static inline int get_gpio_index(int gpio)
+{
+ if (cpu_is_omap7xx())
+ return gpio & 0x1f;
+ if (cpu_is_omap24xx())
+ return gpio & 0x1f;
+ if (cpu_is_omap34xx() || cpu_is_omap44xx())
+ return gpio & 0x1f;
+ return gpio & 0x0f;
+}
+
+static inline int gpio_valid(int gpio)
+{
+ if (gpio < 0)
+ return -1;
+ if (cpu_class_is_omap1() && OMAP_GPIO_IS_MPUIO(gpio)) {
+ if (gpio >= OMAP_MAX_GPIO_LINES + 16)
+ return -1;
+ return 0;
+ }
+ if (cpu_is_omap15xx() && gpio < 16)
+ return 0;
+ if ((cpu_is_omap16xx()) && gpio < 64)
+ return 0;
+ if (cpu_is_omap7xx() && gpio < 192)
+ return 0;
+ if (cpu_is_omap2420() && gpio < 128)
+ return 0;
+ if (cpu_is_omap2430() && gpio < 160)
+ return 0;
+ if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && gpio < 192)
+ return 0;
+ return -1;
+}
+
+static int check_gpio(int gpio)
+{
+ if (unlikely(gpio_valid(gpio) < 0)) {
+ printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio);
+ dump_stack();
+ return -1;
+ }
+ return 0;
+}
static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
{
void __iomem *reg = bank->base;
u32 l;
- reg += bank->regs->direction;
+ switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+ case METHOD_MPUIO:
+ reg += OMAP_MPUIO_IO_CNTL / bank->stride;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+ case METHOD_GPIO_1510:
+ reg += OMAP1510_GPIO_DIR_CONTROL;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+ case METHOD_GPIO_1610:
+ reg += OMAP1610_GPIO_DIRECTION;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ case METHOD_GPIO_7XX:
+ reg += OMAP7XX_GPIO_DIR_CONTROL;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+ case METHOD_GPIO_24XX:
+ reg += OMAP24XX_GPIO_OE;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP4)
+ case METHOD_GPIO_44XX:
+ reg += OMAP4_GPIO_OE;
+ break;
+#endif
+ default:
+ WARN_ON(1);
+ return;
+ }
l = __raw_readl(reg);
if (is_input)
l |= 1 << gpio;
@@ -104,48 +202,165 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
__raw_writel(l, reg);
}
-
-/* set data out value using dedicate set/clear register */
-static void _set_gpio_dataout_reg(struct gpio_bank *bank, int gpio, int enable)
+static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
{
void __iomem *reg = bank->base;
- u32 l = GPIO_BIT(bank, gpio);
-
- if (enable)
- reg += bank->regs->set_dataout;
- else
- reg += bank->regs->clr_dataout;
-
- __raw_writel(l, reg);
-}
-
-/* set data out value using mask register */
-static void _set_gpio_dataout_mask(struct gpio_bank *bank, int gpio, int enable)
-{
- void __iomem *reg = bank->base + bank->regs->dataout;
- u32 gpio_bit = GPIO_BIT(bank, gpio);
- u32 l;
+ u32 l = 0;
- l = __raw_readl(reg);
- if (enable)
- l |= gpio_bit;
- else
- l &= ~gpio_bit;
+ switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+ case METHOD_MPUIO:
+ reg += OMAP_MPUIO_OUTPUT / bank->stride;
+ l = __raw_readl(reg);
+ if (enable)
+ l |= 1 << gpio;
+ else
+ l &= ~(1 << gpio);
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+ case METHOD_GPIO_1510:
+ reg += OMAP1510_GPIO_DATA_OUTPUT;
+ l = __raw_readl(reg);
+ if (enable)
+ l |= 1 << gpio;
+ else
+ l &= ~(1 << gpio);
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+ case METHOD_GPIO_1610:
+ if (enable)
+ reg += OMAP1610_GPIO_SET_DATAOUT;
+ else
+ reg += OMAP1610_GPIO_CLEAR_DATAOUT;
+ l = 1 << gpio;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ case METHOD_GPIO_7XX:
+ reg += OMAP7XX_GPIO_DATA_OUTPUT;
+ l = __raw_readl(reg);
+ if (enable)
+ l |= 1 << gpio;
+ else
+ l &= ~(1 << gpio);
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+ case METHOD_GPIO_24XX:
+ if (enable)
+ reg += OMAP24XX_GPIO_SETDATAOUT;
+ else
+ reg += OMAP24XX_GPIO_CLEARDATAOUT;
+ l = 1 << gpio;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+ case METHOD_GPIO_44XX:
+ if (enable)
+ reg += OMAP4_GPIO_SETDATAOUT;
+ else
+ reg += OMAP4_GPIO_CLEARDATAOUT;
+ l = 1 << gpio;
+ break;
+#endif
+ default:
+ WARN_ON(1);
+ return;
+ }
__raw_writel(l, reg);
}
static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
{
- void __iomem *reg = bank->base + bank->regs->datain;
+ void __iomem *reg;
- return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0;
+ if (check_gpio(gpio) < 0)
+ return -EINVAL;
+ reg = bank->base;
+ switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+ case METHOD_MPUIO:
+ reg += OMAP_MPUIO_INPUT_LATCH / bank->stride;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+ case METHOD_GPIO_1510:
+ reg += OMAP1510_GPIO_DATA_INPUT;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+ case METHOD_GPIO_1610:
+ reg += OMAP1610_GPIO_DATAIN;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ case METHOD_GPIO_7XX:
+ reg += OMAP7XX_GPIO_DATA_INPUT;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+ case METHOD_GPIO_24XX:
+ reg += OMAP24XX_GPIO_DATAIN;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+ case METHOD_GPIO_44XX:
+ reg += OMAP4_GPIO_DATAIN;
+ break;
+#endif
+ default:
+ return -EINVAL;
+ }
+ return (__raw_readl(reg)
+ & (1 << get_gpio_index(gpio))) != 0;
}
static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
{
- void __iomem *reg = bank->base + bank->regs->dataout;
+ void __iomem *reg;
+
+ if (check_gpio(gpio) < 0)
+ return -EINVAL;
+ reg = bank->base;
+
+ switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+ case METHOD_MPUIO:
+ reg += OMAP_MPUIO_OUTPUT / bank->stride;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+ case METHOD_GPIO_1510:
+ reg += OMAP1510_GPIO_DATA_OUTPUT;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+ case METHOD_GPIO_1610:
+ reg += OMAP1610_GPIO_DATAOUT;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ case METHOD_GPIO_7XX:
+ reg += OMAP7XX_GPIO_DATA_OUTPUT;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+ case METHOD_GPIO_24XX:
+ reg += OMAP24XX_GPIO_DATAOUT;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+ case METHOD_GPIO_44XX:
+ reg += OMAP4_GPIO_DATAOUT;
+ break;
+#endif
+ default:
+ return -EINVAL;
+ }
- return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0;
+ return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
}
#define MOD_REG_BIT(reg, bit_mask, set) \
@@ -168,7 +383,7 @@ do { \
static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
unsigned debounce)
{
- void __iomem *reg;
+ void __iomem *reg = bank->base;
u32 val;
u32 l;
@@ -182,12 +397,21 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
else
debounce = (debounce / 0x1f) - 1;
- l = GPIO_BIT(bank, gpio);
+ l = 1 << get_gpio_index(gpio);
+
+ if (bank->method == METHOD_GPIO_44XX)
+ reg += OMAP4_GPIO_DEBOUNCINGTIME;
+ else
+ reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
- reg = bank->base + bank->regs->debounce;
__raw_writel(debounce, reg);
- reg = bank->base + bank->regs->debounce_en;
+ reg = bank->base;
+ if (bank->method == METHOD_GPIO_44XX)
+ reg += OMAP4_GPIO_DEBOUNCENABLE;
+ else
+ reg += OMAP24XX_GPIO_DEBOUNCE_EN;
+
val = __raw_readl(reg);
if (debounce) {
@@ -405,6 +629,9 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
else
gpio = d->irq - IH_GPIO_BASE;
+ if (check_gpio(gpio) < 0)
+ return -EINVAL;
+
if (type & ~IRQ_TYPE_SENSE_MASK)
return -EINVAL;
@@ -415,7 +642,7 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
bank = irq_data_get_irq_chip_data(d);
spin_lock_irqsave(&bank->lock, flags);
- retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type);
+ retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
spin_unlock_irqrestore(&bank->lock, flags);
if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
@@ -430,81 +657,195 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
{
void __iomem *reg = bank->base;
- reg += bank->regs->irqstatus;
+ switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+ case METHOD_MPUIO:
+ /* MPUIO irqstatus is reset by reading the status register,
+ * so do nothing here */
+ return;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+ case METHOD_GPIO_1510:
+ reg += OMAP1510_GPIO_INT_STATUS;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+ case METHOD_GPIO_1610:
+ reg += OMAP1610_GPIO_IRQSTATUS1;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ case METHOD_GPIO_7XX:
+ reg += OMAP7XX_GPIO_INT_STATUS;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+ case METHOD_GPIO_24XX:
+ reg += OMAP24XX_GPIO_IRQSTATUS1;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP4)
+ case METHOD_GPIO_44XX:
+ reg += OMAP4_GPIO_IRQSTATUS0;
+ break;
+#endif
+ default:
+ WARN_ON(1);
+ return;
+ }
__raw_writel(gpio_mask, reg);
/* Workaround for clearing DSP GPIO interrupts to allow retention */
- if (bank->regs->irqstatus2) {
- reg = bank->base + bank->regs->irqstatus2;
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2;
+ else if (cpu_is_omap44xx())
+ reg = bank->base + OMAP4_GPIO_IRQSTATUS1;
+
+ if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
__raw_writel(gpio_mask, reg);
- }
/* Flush posted write for the irq status to avoid spurious interrupts */
__raw_readl(reg);
+ }
}
static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
{
- _clear_gpio_irqbank(bank, GPIO_BIT(bank, gpio));
+ _clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio));
}
static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
{
void __iomem *reg = bank->base;
+ int inv = 0;
u32 l;
- u32 mask = (1 << bank->width) - 1;
+ u32 mask;
+
+ switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+ case METHOD_MPUIO:
+ reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
+ mask = 0xffff;
+ inv = 1;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+ case METHOD_GPIO_1510:
+ reg += OMAP1510_GPIO_INT_MASK;
+ mask = 0xffff;
+ inv = 1;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+ case METHOD_GPIO_1610:
+ reg += OMAP1610_GPIO_IRQENABLE1;
+ mask = 0xffff;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ case METHOD_GPIO_7XX:
+ reg += OMAP7XX_GPIO_INT_MASK;
+ mask = 0xffffffff;
+ inv = 1;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+ case METHOD_GPIO_24XX:
+ reg += OMAP24XX_GPIO_IRQENABLE1;
+ mask = 0xffffffff;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP4)
+ case METHOD_GPIO_44XX:
+ reg += OMAP4_GPIO_IRQSTATUSSET0;
+ mask = 0xffffffff;
+ break;
+#endif
+ default:
+ WARN_ON(1);
+ return 0;
+ }
- reg += bank->regs->irqenable;
l = __raw_readl(reg);
- if (bank->regs->irqenable_inv)
+ if (inv)
l = ~l;
l &= mask;
return l;
}
-static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
+static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
{
void __iomem *reg = bank->base;
u32 l;
- if (bank->regs->set_irqenable) {
- reg += bank->regs->set_irqenable;
- l = gpio_mask;
- } else {
- reg += bank->regs->irqenable;
+ switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+ case METHOD_MPUIO:
+ reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
l = __raw_readl(reg);
- if (bank->regs->irqenable_inv)
- l &= ~gpio_mask;
+ if (enable)
+ l &= ~(gpio_mask);
else
l |= gpio_mask;
- }
-
- __raw_writel(l, reg);
-}
-
-static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
-{
- void __iomem *reg = bank->base;
- u32 l;
-
- if (bank->regs->clr_irqenable) {
- reg += bank->regs->clr_irqenable;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+ case METHOD_GPIO_1510:
+ reg += OMAP1510_GPIO_INT_MASK;
+ l = __raw_readl(reg);
+ if (enable)
+ l &= ~(gpio_mask);
+ else
+ l |= gpio_mask;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+ case METHOD_GPIO_1610:
+ if (enable)
+ reg += OMAP1610_GPIO_SET_IRQENABLE1;
+ else
+ reg += OMAP1610_GPIO_CLEAR_IRQENABLE1;
l = gpio_mask;
- } else {
- reg += bank->regs->irqenable;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ case METHOD_GPIO_7XX:
+ reg += OMAP7XX_GPIO_INT_MASK;
l = __raw_readl(reg);
- if (bank->regs->irqenable_inv)
+ if (enable)
+ l &= ~(gpio_mask);
+ else
l |= gpio_mask;
+ break;
+#endif
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+ case METHOD_GPIO_24XX:
+ if (enable)
+ reg += OMAP24XX_GPIO_SETIRQENABLE1;
+ else
+ reg += OMAP24XX_GPIO_CLEARIRQENABLE1;
+ l = gpio_mask;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+ case METHOD_GPIO_44XX:
+ if (enable)
+ reg += OMAP4_GPIO_IRQSTATUSSET0;
else
- l &= ~gpio_mask;
+ reg += OMAP4_GPIO_IRQSTATUSCLR0;
+ l = gpio_mask;
+ break;
+#endif
+ default:
+ WARN_ON(1);
+ return;
}
-
__raw_writel(l, reg);
}
static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
{
- _enable_gpio_irqbank(bank, GPIO_BIT(bank, gpio));
+ _enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable);
}
/*
@@ -517,32 +858,50 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena
*/
static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
{
- u32 gpio_bit = GPIO_BIT(bank, gpio);
- unsigned long flags;
+ unsigned long uninitialized_var(flags);
- if (bank->non_wakeup_gpios & gpio_bit) {
- dev_err(bank->dev,
- "Unable to modify wakeup on non-wakeup GPIO%d\n", gpio);
+ switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP16XX
+ case METHOD_MPUIO:
+ case METHOD_GPIO_1610:
+ spin_lock_irqsave(&bank->lock, flags);
+ if (enable)
+ bank->suspend_wakeup |= (1 << gpio);
+ else
+ bank->suspend_wakeup &= ~(1 << gpio);
+ spin_unlock_irqrestore(&bank->lock, flags);
+ return 0;
+#endif
+#ifdef CONFIG_ARCH_OMAP2PLUS
+ case METHOD_GPIO_24XX:
+ case METHOD_GPIO_44XX:
+ if (bank->non_wakeup_gpios & (1 << gpio)) {
+ printk(KERN_ERR "Unable to modify wakeup on "
+ "non-wakeup GPIO%d\n",
+ (bank - gpio_bank) * 32 + gpio);
+ return -EINVAL;
+ }
+ spin_lock_irqsave(&bank->lock, flags);
+ if (enable)
+ bank->suspend_wakeup |= (1 << gpio);
+ else
+ bank->suspend_wakeup &= ~(1 << gpio);
+ spin_unlock_irqrestore(&bank->lock, flags);
+ return 0;
+#endif
+ default:
+ printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n",
+ bank->method);
return -EINVAL;
}
-
- spin_lock_irqsave(&bank->lock, flags);
- if (enable)
- bank->suspend_wakeup |= gpio_bit;
- else
- bank->suspend_wakeup &= ~gpio_bit;
-
- spin_unlock_irqrestore(&bank->lock, flags);
-
- return 0;
}
static void _reset_gpio(struct gpio_bank *bank, int gpio)
{
- _set_gpio_direction(bank, GPIO_INDEX(bank, gpio), 1);
+ _set_gpio_direction(bank, get_gpio_index(gpio), 1);
_set_gpio_irqenable(bank, gpio, 0);
_clear_gpio_irqstatus(bank, gpio);
- _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE);
+ _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
}
/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
@@ -552,8 +911,10 @@ static int gpio_wake_enable(struct irq_data *d, unsigned int enable)
struct gpio_bank *bank;
int retval;
+ if (check_gpio(gpio) < 0)
+ return -ENODEV;
bank = irq_data_get_irq_chip_data(d);
- retval = _set_gpio_wakeup(bank, gpio, enable);
+ retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
return retval;
}
@@ -669,7 +1030,31 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
chained_irq_enter(chip, desc);
bank = irq_get_handler_data(irq);
- isr_reg = bank->base + bank->regs->irqstatus;
+#ifdef CONFIG_ARCH_OMAP1
+ if (bank->method == METHOD_MPUIO)
+ isr_reg = bank->base +
+ OMAP_MPUIO_GPIO_INT / bank->stride;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+ if (bank->method == METHOD_GPIO_1510)
+ isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+ if (bank->method == METHOD_GPIO_1610)
+ isr_reg = bank->base + OMAP1610_GPIO_IRQSTATUS1;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ if (bank->method == METHOD_GPIO_7XX)
+ isr_reg = bank->base + OMAP7XX_GPIO_INT_STATUS;
+#endif
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+ if (bank->method == METHOD_GPIO_24XX)
+ isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
+#endif
+#if defined(CONFIG_ARCH_OMAP4)
+ if (bank->method == METHOD_GPIO_44XX)
+ isr_reg = bank->base + OMAP4_GPIO_IRQSTATUS0;
+#endif
if (WARN_ON(!isr_reg))
goto exit;
@@ -691,9 +1076,9 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
/* clear edge sensitive interrupts before handler(s) are
called so that we don't miss any interrupt occurred while
executing them */
- _disable_gpio_irqbank(bank, isr_saved & ~level_mask);
+ _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0);
_clear_gpio_irqbank(bank, isr_saved & ~level_mask);
- _enable_gpio_irqbank(bank, isr_saved & ~level_mask);
+ _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1);
/* if there is only edge sensitive GPIO pin interrupts
configured, we could unmask GPIO bank interrupt immediately */
@@ -709,7 +1094,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
gpio_irq = bank->virtual_irq_start;
for (; isr != 0; isr >>= 1, gpio_irq++) {
- gpio_index = GPIO_INDEX(bank, irq_to_gpio(gpio_irq));
+ gpio_index = get_gpio_index(irq_to_gpio(gpio_irq));
if (!(isr & 1))
continue;
@@ -765,7 +1150,7 @@ static void gpio_mask_irq(struct irq_data *d)
spin_lock_irqsave(&bank->lock, flags);
_set_gpio_irqenable(bank, gpio, 0);
- _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE);
+ _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
spin_unlock_irqrestore(&bank->lock, flags);
}
@@ -773,13 +1158,13 @@ static void gpio_unmask_irq(struct irq_data *d)
{
unsigned int gpio = d->irq - IH_GPIO_BASE;
struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
- unsigned int irq_mask = GPIO_BIT(bank, gpio);
+ unsigned int irq_mask = 1 << get_gpio_index(gpio);
u32 trigger = irqd_get_trigger_type(d);
unsigned long flags;
spin_lock_irqsave(&bank->lock, flags);
if (trigger)
- _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), trigger);
+ _set_gpio_triggering(bank, get_gpio_index(gpio), trigger);
/* For level-triggered GPIOs, the clearing must be done after
* the HW source is cleared, thus after the handler has run */
@@ -806,8 +1191,45 @@ static struct irq_chip gpio_irq_chip = {
#ifdef CONFIG_ARCH_OMAP1
+/* MPUIO uses the always-on 32k clock */
+
+static void mpuio_ack_irq(struct irq_data *d)
+{
+ /* The ISR is reset automatically, so do nothing here. */
+}
+
+static void mpuio_mask_irq(struct irq_data *d)
+{
+ unsigned int gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE);
+ struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+
+ _set_gpio_irqenable(bank, gpio, 0);
+}
+
+static void mpuio_unmask_irq(struct irq_data *d)
+{
+ unsigned int gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE);
+ struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+
+ _set_gpio_irqenable(bank, gpio, 1);
+}
+
+static struct irq_chip mpuio_irq_chip = {
+ .name = "MPUIO",
+ .irq_ack = mpuio_ack_irq,
+ .irq_mask = mpuio_mask_irq,
+ .irq_unmask = mpuio_unmask_irq,
+ .irq_set_type = gpio_irq_type,
+#ifdef CONFIG_ARCH_OMAP16XX
+ /* REVISIT: assuming only 16xx supports MPUIO wake events */
+ .irq_set_wake = gpio_wake_enable,
+#endif
+};
+
+
#define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO)
+
#ifdef CONFIG_ARCH_OMAP16XX
#include <linux/platform_device.h>
@@ -867,7 +1289,7 @@ static struct platform_device omap_mpuio_device = {
static inline void mpuio_init(void)
{
- struct gpio_bank *bank = &gpio_bank[0];
+ struct gpio_bank *bank = get_gpio_bank(OMAP_MPUIO(0));
platform_set_drvdata(&omap_mpuio_device, bank);
if (platform_driver_register(&omap_mpuio_driver) == 0)
@@ -880,6 +1302,8 @@ static inline void mpuio_init(void) {}
#else
+extern struct irq_chip mpuio_irq_chip;
+
#define bank_is_mpuio(bank) 0
static inline void mpuio_init(void) {}
@@ -905,8 +1329,31 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset)
static int gpio_is_input(struct gpio_bank *bank, int mask)
{
- void __iomem *reg = bank->base + bank->regs->direction;
+ void __iomem *reg = bank->base;
+ switch (bank->method) {
+ case METHOD_MPUIO:
+ reg += OMAP_MPUIO_IO_CNTL / bank->stride;
+ break;
+ case METHOD_GPIO_1510:
+ reg += OMAP1510_GPIO_DIR_CONTROL;
+ break;
+ case METHOD_GPIO_1610:
+ reg += OMAP1610_GPIO_DIRECTION;
+ break;
+ case METHOD_GPIO_7XX:
+ reg += OMAP7XX_GPIO_DIR_CONTROL;
+ break;
+ case METHOD_GPIO_24XX:
+ reg += OMAP24XX_GPIO_OE;
+ break;
+ case METHOD_GPIO_44XX:
+ reg += OMAP4_GPIO_OE;
+ break;
+ default:
+ WARN_ONCE(1, "gpio_is_input: incorrect OMAP GPIO method");
+ return -EINVAL;
+ }
return __raw_readl(reg) & mask;
}
@@ -918,9 +1365,9 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset)
u32 mask;
gpio = chip->base + offset;
- bank = container_of(chip, struct gpio_bank, chip);
+ bank = get_gpio_bank(gpio);
reg = bank->base;
- mask = GPIO_BIT(bank, gpio);
+ mask = 1 << get_gpio_index(gpio);
if (gpio_is_input(bank, mask))
return _get_gpio_datain(bank, gpio);
@@ -935,7 +1382,7 @@ static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)
bank = container_of(chip, struct gpio_bank, chip);
spin_lock_irqsave(&bank->lock, flags);
- bank->set_dataout(bank, offset, value);
+ _set_gpio_dataout(bank, offset, value);
_set_gpio_direction(bank, offset, 0);
spin_unlock_irqrestore(&bank->lock, flags);
return 0;
@@ -969,7 +1416,7 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)
bank = container_of(chip, struct gpio_bank, chip);
spin_lock_irqsave(&bank->lock, flags);
- bank->set_dataout(bank, offset, value);
+ _set_gpio_dataout(bank, offset, value);
spin_unlock_irqrestore(&bank->lock, flags);
}
@@ -985,17 +1432,19 @@ static int gpio_2irq(struct gpio_chip *chip, unsigned offset)
static void __init omap_gpio_show_rev(struct gpio_bank *bank)
{
- static bool called;
u32 rev;
- if (called || bank->regs->revision == USHRT_MAX)
+ if (cpu_is_omap16xx() && !(bank->method != METHOD_MPUIO))
+ rev = __raw_readw(bank->base + OMAP1610_GPIO_REVISION);
+ else if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ rev = __raw_readl(bank->base + OMAP24XX_GPIO_REVISION);
+ else if (cpu_is_omap44xx())
+ rev = __raw_readl(bank->base + OMAP4_GPIO_REVISION);
+ else
return;
- rev = __raw_readw(bank->base + bank->regs->revision);
- pr_info("OMAP GPIO hardware version %d.%d\n",
+ printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n",
(rev >> 4) & 0x0f, rev & 0x0f);
-
- called = true;
}
/* This lock class tells lockdep that GPIO irqs are in a different
@@ -1077,30 +1526,6 @@ static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
}
}
-static __init void
-omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
- unsigned int num)
-{
- struct irq_chip_generic *gc;
- struct irq_chip_type *ct;
-
- gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base,
- handle_simple_irq);
- ct = gc->chip_types;
-
- /* NOTE: No ack required, reading IRQ status clears it. */
- ct->chip.irq_mask = irq_gc_mask_set_bit;
- ct->chip.irq_unmask = irq_gc_mask_clr_bit;
- ct->chip.irq_set_type = gpio_irq_type;
- /* REVISIT: assuming only 16xx supports MPUIO wake events */
- if (cpu_is_omap16xx())
- ct->chip.irq_set_wake = gpio_wake_enable,
-
- ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride;
- irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
- IRQ_NOREQUEST | IRQ_NOPROBE, 0);
-}
-
static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
{
int j;
@@ -1128,23 +1553,22 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
} else {
bank->chip.label = "gpio";
bank->chip.base = gpio;
- gpio += bank->width;
+ gpio += bank_width;
}
- bank->chip.ngpio = bank->width;
+ bank->chip.ngpio = bank_width;
gpiochip_add(&bank->chip);
for (j = bank->virtual_irq_start;
- j < bank->virtual_irq_start + bank->width; j++) {
+ j < bank->virtual_irq_start + bank_width; j++) {
irq_set_lockdep_class(j, &gpio_lock_class);
irq_set_chip_data(j, bank);
- if (bank_is_mpuio(bank)) {
- omap_mpuio_alloc_gc(bank, j, bank->width);
- } else {
+ if (bank_is_mpuio(bank))
+ irq_set_chip(j, &mpuio_irq_chip);
+ else
irq_set_chip(j, &gpio_irq_chip);
- irq_set_handler(j, handle_simple_irq);
- set_irq_flags(j, IRQF_VALID);
- }
+ irq_set_handler(j, handle_simple_irq);
+ set_irq_flags(j, IRQF_VALID);
}
irq_set_chained_handler(bank->irq, gpio_irq_handler);
irq_set_handler_data(bank->irq, bank);
@@ -1186,14 +1610,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
bank->dev = &pdev->dev;
bank->dbck_flag = pdata->dbck_flag;
bank->stride = pdata->bank_stride;
- bank->width = pdata->bank_width;
-
- bank->regs = pdata->regs;
-
- if (bank->regs->set_dataout && bank->regs->clr_dataout)
- bank->set_dataout = _set_gpio_dataout_reg;
- else
- bank->set_dataout = _set_gpio_dataout_mask;
+ bank_width = pdata->bank_width;
spin_lock_init(&bank->lock);
diff --git a/drivers/gpio/gpio-plat-samsung.c b/drivers/gpio/gpio-plat-samsung.c
index ef67f1952a7..ea37c046178 100644
--- a/drivers/gpio/gpio-plat-samsung.c
+++ b/drivers/gpio/gpio-plat-samsung.c
@@ -1,4 +1,5 @@
-/*
+/* arch/arm/plat-samsung/gpiolib.c
+ *
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
diff --git a/drivers/gpio/gpio-s5pc100.c b/drivers/gpio/gpio-s5pc100.c
index 7f87b0c76e0..2842394b28b 100644
--- a/drivers/gpio/gpio-s5pc100.c
+++ b/drivers/gpio/gpio-s5pc100.c
@@ -1,5 +1,4 @@
-/*
- * S5PC100 - GPIOlib support
+/* linux/arch/arm/mach-s5pc100/gpiolib.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -7,6 +6,8 @@
* Copyright 2009 Samsung Electronics Co
* Kyungmin Park <kyungmin.park@samsung.com>
*
+ * S5PC100 - GPIOlib support
+ *
* 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.
diff --git a/drivers/gpio/gpio-s5pv210.c b/drivers/gpio/gpio-s5pv210.c
index eb12f1602de..1ba20a703e0 100644
--- a/drivers/gpio/gpio-s5pv210.c
+++ b/drivers/gpio/gpio-s5pv210.c
@@ -1,9 +1,10 @@
-/*
- * S5PV210 - GPIOlib support
+/* linux/arch/arm/mach-s5pv210/gpiolib.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
+ * S5PV210 - GPIOlib support
+ *
* 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.
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
deleted file mode 100644
index 747eb40e8af..00000000000
--- a/drivers/gpio/gpio-tegra.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * arch/arm/mach-tegra/gpio.c
- *
- * Copyright (c) 2010 Google, Inc
- *
- * Author:
- * Erik Gilling <konkers@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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/irq.h>
-#include <linux/interrupt.h>
-
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/of.h>
-
-#include <asm/mach/irq.h>
-
-#include <mach/iomap.h>
-#include <mach/suspend.h>
-
-#define GPIO_BANK(x) ((x) >> 5)
-#define GPIO_PORT(x) (((x) >> 3) & 0x3)
-#define GPIO_BIT(x) ((x) & 0x7)
-
-#define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \
- GPIO_BANK(x) * 0x80 + \
- GPIO_PORT(x) * 4)
-
-#define GPIO_CNF(x) (GPIO_REG(x) + 0x00)
-#define GPIO_OE(x) (GPIO_REG(x) + 0x10)
-#define GPIO_OUT(x) (GPIO_REG(x) + 0X20)
-#define GPIO_IN(x) (GPIO_REG(x) + 0x30)
-#define GPIO_INT_STA(x) (GPIO_REG(x) + 0x40)
-#define GPIO_INT_ENB(x) (GPIO_REG(x) + 0x50)
-#define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60)
-#define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70)
-
-#define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x800)
-#define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x810)
-#define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0X820)
-#define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0x840)
-#define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0x850)
-#define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0x860)
-
-#define GPIO_INT_LVL_MASK 0x010101
-#define GPIO_INT_LVL_EDGE_RISING 0x000101
-#define GPIO_INT_LVL_EDGE_FALLING 0x000100
-#define GPIO_INT_LVL_EDGE_BOTH 0x010100
-#define GPIO_INT_LVL_LEVEL_HIGH 0x000001
-#define GPIO_INT_LVL_LEVEL_LOW 0x000000
-
-struct tegra_gpio_bank {
- int bank;
- int irq;
- spinlock_t lvl_lock[4];
-#ifdef CONFIG_PM
- u32 cnf[4];
- u32 out[4];
- u32 oe[4];
- u32 int_enb[4];
- u32 int_lvl[4];
-#endif
-};
-
-
-static struct tegra_gpio_bank tegra_gpio_banks[] = {
- {.bank = 0, .irq = INT_GPIO1},
- {.bank = 1, .irq = INT_GPIO2},
- {.bank = 2, .irq = INT_GPIO3},
- {.bank = 3, .irq = INT_GPIO4},
- {.bank = 4, .irq = INT_GPIO5},
- {.bank = 5, .irq = INT_GPIO6},
- {.bank = 6, .irq = INT_GPIO7},
-};
-
-static int tegra_gpio_compose(int bank, int port, int bit)
-{
- return (bank << 5) | ((port & 0x3) << 3) | (bit & 0x7);
-}
-
-static void tegra_gpio_mask_write(u32 reg, int gpio, int value)
-{
- u32 val;
-
- val = 0x100 << GPIO_BIT(gpio);
- if (value)
- val |= 1 << GPIO_BIT(gpio);
- __raw_writel(val, reg);
-}
-
-void tegra_gpio_enable(int gpio)
-{
- tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1);
-}
-
-void tegra_gpio_disable(int gpio)
-{
- tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0);
-}
-
-static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
- tegra_gpio_mask_write(GPIO_MSK_OUT(offset), offset, value);
-}
-
-static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- return (__raw_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1;
-}
-
-static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
- tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 0);
- return 0;
-}
-
-static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
- int value)
-{
- tegra_gpio_set(chip, offset, value);
- tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 1);
- return 0;
-}
-
-
-
-static struct gpio_chip tegra_gpio_chip = {
- .label = "tegra-gpio",
- .direction_input = tegra_gpio_direction_input,
- .get = tegra_gpio_get,
- .direction_output = tegra_gpio_direction_output,
- .set = tegra_gpio_set,
- .base = 0,
- .ngpio = TEGRA_NR_GPIOS,
-};
-
-static void tegra_gpio_irq_ack(struct irq_data *d)
-{
- int gpio = d->irq - INT_GPIO_BASE;
-
- __raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
-}
-
-static void tegra_gpio_irq_mask(struct irq_data *d)
-{
- int gpio = d->irq - INT_GPIO_BASE;
-
- tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0);
-}
-
-static void tegra_gpio_irq_unmask(struct irq_data *d)
-{
- int gpio = d->irq - INT_GPIO_BASE;
-
- tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1);
-}
-
-static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
-{
- int gpio = d->irq - INT_GPIO_BASE;
- struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
- int port = GPIO_PORT(gpio);
- int lvl_type;
- int val;
- unsigned long flags;
-
- switch (type & IRQ_TYPE_SENSE_MASK) {
- case IRQ_TYPE_EDGE_RISING:
- lvl_type = GPIO_INT_LVL_EDGE_RISING;
- break;
-
- case IRQ_TYPE_EDGE_FALLING:
- lvl_type = GPIO_INT_LVL_EDGE_FALLING;
- break;
-
- case IRQ_TYPE_EDGE_BOTH:
- lvl_type = GPIO_INT_LVL_EDGE_BOTH;
- break;
-
- case IRQ_TYPE_LEVEL_HIGH:
- lvl_type = GPIO_INT_LVL_LEVEL_HIGH;
- break;
-
- case IRQ_TYPE_LEVEL_LOW:
- lvl_type = GPIO_INT_LVL_LEVEL_LOW;
- break;
-
- default:
- return -EINVAL;
- }
-
- spin_lock_irqsave(&bank->lvl_lock[port], flags);
-
- val = __raw_readl(GPIO_INT_LVL(gpio));
- val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio));
- val |= lvl_type << GPIO_BIT(gpio);
- __raw_writel(val, GPIO_INT_LVL(gpio));
-
- spin_unlock_irqrestore(&bank->lvl_lock[port], flags);
-
- if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
- __irq_set_handler_locked(d->irq, handle_level_irq);
- else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
- __irq_set_handler_locked(d->irq, handle_edge_irq);
-
- return 0;
-}
-
-static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
- struct tegra_gpio_bank *bank;
- int port;
- int pin;
- int unmasked = 0;
- struct irq_chip *chip = irq_desc_get_chip(desc);
-
- chained_irq_enter(chip, desc);
-
- bank = irq_get_handler_data(irq);
-
- for (port = 0; port < 4; port++) {
- int gpio = tegra_gpio_compose(bank->bank, port, 0);
- unsigned long sta = __raw_readl(GPIO_INT_STA(gpio)) &
- __raw_readl(GPIO_INT_ENB(gpio));
- u32 lvl = __raw_readl(GPIO_INT_LVL(gpio));
-
- for_each_set_bit(pin, &sta, 8) {
- __raw_writel(1 << pin, GPIO_INT_CLR(gpio));
-
- /* if gpio is edge triggered, clear condition
- * before executing the hander so that we don't
- * miss edges
- */
- if (lvl & (0x100 << pin)) {
- unmasked = 1;
- chained_irq_exit(chip, desc);
- }
-
- generic_handle_irq(gpio_to_irq(gpio + pin));
- }
- }
-
- if (!unmasked)
- chained_irq_exit(chip, desc);
-
-}
-
-#ifdef CONFIG_PM
-void tegra_gpio_resume(void)
-{
- unsigned long flags;
- int b;
- int p;
-
- local_irq_save(flags);
-
- for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
- struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
-
- for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
- unsigned int gpio = (b<<5) | (p<<3);
- __raw_writel(bank->cnf[p], GPIO_CNF(gpio));
- __raw_writel(bank->out[p], GPIO_OUT(gpio));
- __raw_writel(bank->oe[p], GPIO_OE(gpio));
- __raw_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio));
- __raw_writel(bank->int_enb[p], GPIO_INT_ENB(gpio));
- }
- }
-
- local_irq_restore(flags);
-}
-
-void tegra_gpio_suspend(void)
-{
- unsigned long flags;
- int b;
- int p;
-
- local_irq_save(flags);
- for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
- struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
-
- for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
- unsigned int gpio = (b<<5) | (p<<3);
- bank->cnf[p] = __raw_readl(GPIO_CNF(gpio));
- bank->out[p] = __raw_readl(GPIO_OUT(gpio));
- bank->oe[p] = __raw_readl(GPIO_OE(gpio));
- bank->int_enb[p] = __raw_readl(GPIO_INT_ENB(gpio));
- bank->int_lvl[p] = __raw_readl(GPIO_INT_LVL(gpio));
- }
- }
- local_irq_restore(flags);
-}
-
-static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable)
-{
- struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
- return irq_set_irq_wake(bank->irq, enable);
-}
-#endif
-
-static struct irq_chip tegra_gpio_irq_chip = {
- .name = "GPIO",
- .irq_ack = tegra_gpio_irq_ack,
- .irq_mask = tegra_gpio_irq_mask,
- .irq_unmask = tegra_gpio_irq_unmask,
- .irq_set_type = tegra_gpio_irq_set_type,
-#ifdef CONFIG_PM
- .irq_set_wake = tegra_gpio_wake_enable,
-#endif
-};
-
-
-/* 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;
-
-static int __init tegra_gpio_init(void)
-{
- struct tegra_gpio_bank *bank;
- int i;
- int j;
-
- for (i = 0; i < 7; i++) {
- for (j = 0; j < 4; j++) {
- int gpio = tegra_gpio_compose(i, j, 0);
- __raw_writel(0x00, GPIO_INT_ENB(gpio));
- }
- }
-
-#ifdef CONFIG_OF_GPIO
- /*
- * This isn't ideal, but it gets things hooked up until this
- * driver is converted into a platform_device
- */
- tegra_gpio_chip.of_node = of_find_compatible_node(NULL, NULL,
- "nvidia,tegra20-gpio");
-#endif /* CONFIG_OF_GPIO */
-
- gpiochip_add(&tegra_gpio_chip);
-
- for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) {
- bank = &tegra_gpio_banks[GPIO_BANK(irq_to_gpio(i))];
-
- irq_set_lockdep_class(i, &gpio_lock_class);
- irq_set_chip_data(i, bank);
- irq_set_chip_and_handler(i, &tegra_gpio_irq_chip,
- handle_simple_irq);
- set_irq_flags(i, IRQF_VALID);
- }
-
- for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
- bank = &tegra_gpio_banks[i];
-
- irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler);
- irq_set_handler_data(bank->irq, bank);
-
- for (j = 0; j < 4; j++)
- spin_lock_init(&bank->lvl_lock[j]);
- }
-
- return 0;
-}
-
-postcore_initcall(tegra_gpio_init);
-
-void __init tegra_gpio_config(struct tegra_gpio_table *table, int num)
-{
- int i;
-
- for (i = 0; i < num; i++) {
- int gpio = table[i].gpio;
-
- if (table[i].enable)
- tegra_gpio_enable(gpio);
- else
- tegra_gpio_disable(gpio);
- }
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
-static int dbg_gpio_show(struct seq_file *s, void *unused)
-{
- int i;
- int j;
-
- for (i = 0; i < 7; i++) {
- for (j = 0; j < 4; j++) {
- int gpio = tegra_gpio_compose(i, j, 0);
- seq_printf(s,
- "%d:%d %02x %02x %02x %02x %02x %02x %06x\n",
- i, j,
- __raw_readl(GPIO_CNF(gpio)),
- __raw_readl(GPIO_OE(gpio)),
- __raw_readl(GPIO_OUT(gpio)),
- __raw_readl(GPIO_IN(gpio)),
- __raw_readl(GPIO_INT_STA(gpio)),
- __raw_readl(GPIO_INT_ENB(gpio)),
- __raw_readl(GPIO_INT_LVL(gpio)));
- }
- }
- return 0;
-}
-
-static int dbg_gpio_open(struct inode *inode, struct file *file)
-{
- return single_open(file, dbg_gpio_show, &inode->i_private);
-}
-
-static const struct file_operations debug_fops = {
- .open = dbg_gpio_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int __init tegra_gpio_debuginit(void)
-{
- (void) debugfs_create_file("tegra_gpio", S_IRUGO,
- NULL, NULL, &debug_fops);
- return 0;
-}
-late_initcall(tegra_gpio_debuginit);
-#endif
diff --git a/drivers/gpio/gpio-u300.c b/drivers/gpio/gpio-u300.c
index fd2dfeeefdf..d92790140fe 100644
--- a/drivers/gpio/gpio-u300.c
+++ b/drivers/gpio/gpio-u300.c
@@ -1,8 +1,11 @@
/*
- * U300 GPIO module.
+ *
+ * arch/arm/mach-u300/gpio.c
+ *
*
* Copyright (C) 2007-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
+ * U300 GPIO module.
* This can driver either of the two basic GPIO cores
* available in the U300 platforms:
* COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0)
diff --git a/drivers/gpio/gpio-it8761e.c b/drivers/gpio/it8761e_gpio.c
index 278b8131701..48fc43c4bdd 100644
--- a/drivers/gpio/gpio-it8761e.c
+++ b/drivers/gpio/it8761e_gpio.c
@@ -1,5 +1,5 @@
/*
- * GPIO interface for IT8761E Super I/O chip
+ * it8761_gpio.c - GPIO interface for IT8761E Super I/O chip
*
* Author: Denis Turischev <denis@compulab.co.il>
*
diff --git a/drivers/gpio/gpio-janz-ttl.c b/drivers/gpio/janz-ttl.c
index 813ac077e5d..813ac077e5d 100644
--- a/drivers/gpio/gpio-janz-ttl.c
+++ b/drivers/gpio/janz-ttl.c
diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/langwell_gpio.c
index d2eb57c60e0..644ba1255d3 100644
--- a/drivers/gpio/gpio-langwell.c
+++ b/drivers/gpio/langwell_gpio.c
@@ -1,6 +1,4 @@
-/*
- * Moorestown platform Langwell chip GPIO driver
- *
+/* langwell_gpio.c Moorestown platform Langwell chip GPIO driver
* Copyright (c) 2008 - 2009, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
diff --git a/drivers/gpio/gpio-max7300.c b/drivers/gpio/max7300.c
index a5ca0ab1b37..962f661c18c 100644
--- a/drivers/gpio/gpio-max7300.c
+++ b/drivers/gpio/max7300.c
@@ -1,4 +1,6 @@
/*
+ * drivers/gpio/max7300.c
+ *
* Copyright (C) 2009 Wolfram Sang, Pengutronix
*
* This program is free software; you can redistribute it and/or modify
diff --git a/drivers/gpio/gpio-max7301.c b/drivers/gpio/max7301.c
index 741acfcbe76..92a100ddef6 100644
--- a/drivers/gpio/gpio-max7301.c
+++ b/drivers/gpio/max7301.c
@@ -1,4 +1,6 @@
/*
+ * drivers/gpio/max7301.c
+ *
* Copyright (C) 2006 Juergen Beisert, Pengutronix
* Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
* Copyright (C) 2009 Wolfram Sang, Pengutronix
diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/max730x.c
index 05e2dac60b3..94ce773f95f 100644
--- a/drivers/gpio/gpio-max730x.c
+++ b/drivers/gpio/max730x.c
@@ -1,4 +1,6 @@
/**
+ * drivers/gpio/max7301.c
+ *
* Copyright (C) 2006 Juergen Beisert, Pengutronix
* Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
* Copyright (C) 2009 Wolfram Sang, Pengutronix
diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/max732x.c
index 9504120812a..ad6951edc16 100644
--- a/drivers/gpio/gpio-max732x.c
+++ b/drivers/gpio/max732x.c
@@ -1,5 +1,5 @@
/*
- * MAX732x I2C Port Expander with 8/16 I/O
+ * max732x.c - I2C Port Expander with 8/16 I/O
*
* Copyright (C) 2007 Marvell International Ltd.
* Copyright (C) 2008 Jack Ren <jack.ren@marvell.com>
diff --git a/drivers/gpio/gpio-mc33880.c b/drivers/gpio/mc33880.c
index b3b4652e89e..4ec797593bd 100644
--- a/drivers/gpio/gpio-mc33880.c
+++ b/drivers/gpio/mc33880.c
@@ -1,5 +1,5 @@
/*
- * MC33880 high-side/low-side switch GPIO driver
+ * mc33880.c MC33880 high-side/low-side switch GPIO driver
* Copyright (c) 2009 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/mcp23s08.c
index 1ef46e6c2a2..40e076083ec 100644
--- a/drivers/gpio/gpio-mcp23s08.c
+++ b/drivers/gpio/mcp23s08.c
@@ -1,12 +1,12 @@
/*
- * MCP23S08 SPI/GPIO gpio expander driver
+ * mcp23s08.c - SPI gpio expander driver
*/
#include <linux/kernel.h>
#include <linux/device.h>
+#include <linux/workqueue.h>
#include <linux/mutex.h>
#include <linux/gpio.h>
-#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/spi/mcp23s08.h>
#include <linux/slab.h>
@@ -17,13 +17,13 @@
*/
#define MCP_TYPE_S08 0
#define MCP_TYPE_S17 1
-#define MCP_TYPE_008 2
-#define MCP_TYPE_017 3
/* Registers are all 8 bits wide.
*
* The mcp23s17 has twice as many bits, and can be configured to work
* with either 16 bit registers or with two adjacent 8 bit banks.
+ *
+ * Also, there are I2C versions of both chips.
*/
#define MCP_IODIR 0x00 /* init/reset: all ones */
#define MCP_IPOL 0x01
@@ -51,6 +51,7 @@ struct mcp23s08_ops {
};
struct mcp23s08 {
+ struct spi_device *spi;
u8 addr;
u16 cache[11];
@@ -59,8 +60,9 @@ struct mcp23s08 {
struct gpio_chip chip;
+ struct work_struct work;
+
const struct mcp23s08_ops *ops;
- void *data; /* ops specific data */
};
/* A given spi_device can represent up to eight mcp23sxx chips
@@ -74,74 +76,6 @@ struct mcp23s08_driver_data {
struct mcp23s08 chip[];
};
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_I2C
-
-static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg)
-{
- return i2c_smbus_read_byte_data(mcp->data, reg);
-}
-
-static int mcp23008_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
-{
- return i2c_smbus_write_byte_data(mcp->data, reg, val);
-}
-
-static int
-mcp23008_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
-{
- while (n--) {
- int ret = mcp23008_read(mcp, reg++);
- if (ret < 0)
- return ret;
- *vals++ = ret;
- }
-
- return 0;
-}
-
-static int mcp23017_read(struct mcp23s08 *mcp, unsigned reg)
-{
- return i2c_smbus_read_word_data(mcp->data, reg << 1);
-}
-
-static int mcp23017_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
-{
- return i2c_smbus_write_word_data(mcp->data, reg << 1, val);
-}
-
-static int
-mcp23017_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
-{
- while (n--) {
- int ret = mcp23017_read(mcp, reg++);
- if (ret < 0)
- return ret;
- *vals++ = ret;
- }
-
- return 0;
-}
-
-static const struct mcp23s08_ops mcp23008_ops = {
- .read = mcp23008_read,
- .write = mcp23008_write,
- .read_regs = mcp23008_read_regs,
-};
-
-static const struct mcp23s08_ops mcp23017_ops = {
- .read = mcp23017_read,
- .write = mcp23017_write,
- .read_regs = mcp23017_read_regs,
-};
-
-#endif /* CONFIG_I2C */
-
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_SPI_MASTER
-
static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg)
{
u8 tx[2], rx[1];
@@ -149,7 +83,7 @@ static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg)
tx[0] = mcp->addr | 0x01;
tx[1] = reg;
- status = spi_write_then_read(mcp->data, tx, sizeof tx, rx, sizeof rx);
+ status = spi_write_then_read(mcp->spi, tx, sizeof tx, rx, sizeof rx);
return (status < 0) ? status : rx[0];
}
@@ -160,7 +94,7 @@ static int mcp23s08_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
tx[0] = mcp->addr;
tx[1] = reg;
tx[2] = val;
- return spi_write_then_read(mcp->data, tx, sizeof tx, NULL, 0);
+ return spi_write_then_read(mcp->spi, tx, sizeof tx, NULL, 0);
}
static int
@@ -175,7 +109,7 @@ mcp23s08_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
tx[1] = reg;
tmp = (u8 *)vals;
- status = spi_write_then_read(mcp->data, tx, sizeof tx, tmp, n);
+ status = spi_write_then_read(mcp->spi, tx, sizeof tx, tmp, n);
if (status >= 0) {
while (n--)
vals[n] = tmp[n]; /* expand to 16bit */
@@ -190,7 +124,7 @@ static int mcp23s17_read(struct mcp23s08 *mcp, unsigned reg)
tx[0] = mcp->addr | 0x01;
tx[1] = reg << 1;
- status = spi_write_then_read(mcp->data, tx, sizeof tx, rx, sizeof rx);
+ status = spi_write_then_read(mcp->spi, tx, sizeof tx, rx, sizeof rx);
return (status < 0) ? status : (rx[0] | (rx[1] << 8));
}
@@ -202,7 +136,7 @@ static int mcp23s17_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
tx[1] = reg << 1;
tx[2] = val;
tx[3] = val >> 8;
- return spi_write_then_read(mcp->data, tx, sizeof tx, NULL, 0);
+ return spi_write_then_read(mcp->spi, tx, sizeof tx, NULL, 0);
}
static int
@@ -216,7 +150,7 @@ mcp23s17_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
tx[0] = mcp->addr | 0x01;
tx[1] = reg << 1;
- status = spi_write_then_read(mcp->data, tx, sizeof tx,
+ status = spi_write_then_read(mcp->spi, tx, sizeof tx,
(u8 *)vals, n * 2);
if (status >= 0) {
while (n--)
@@ -238,7 +172,6 @@ static const struct mcp23s08_ops mcp23s17_ops = {
.read_regs = mcp23s17_read_regs,
};
-#endif /* CONFIG_SPI_MASTER */
/*----------------------------------------------------------------------*/
@@ -366,16 +299,17 @@ done:
/*----------------------------------------------------------------------*/
-static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
- void *data, unsigned addr,
+static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr,
unsigned type, unsigned base, unsigned pullups)
{
- int status;
+ struct mcp23s08_driver_data *data = spi_get_drvdata(spi);
+ struct mcp23s08 *mcp = data->mcp[addr];
+ int status;
mutex_init(&mcp->lock);
- mcp->data = data;
- mcp->addr = addr;
+ mcp->spi = spi;
+ mcp->addr = 0x40 | (addr << 1);
mcp->chip.direction_input = mcp23s08_direction_input;
mcp->chip.get = mcp23s08_get;
@@ -383,43 +317,18 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
mcp->chip.set = mcp23s08_set;
mcp->chip.dbg_show = mcp23s08_dbg_show;
- switch (type) {
-#ifdef CONFIG_SPI_MASTER
- case MCP_TYPE_S08:
- mcp->ops = &mcp23s08_ops;
- mcp->chip.ngpio = 8;
- mcp->chip.label = "mcp23s08";
- break;
-
- case MCP_TYPE_S17:
+ if (type == MCP_TYPE_S17) {
mcp->ops = &mcp23s17_ops;
mcp->chip.ngpio = 16;
mcp->chip.label = "mcp23s17";
- break;
-#endif /* CONFIG_SPI_MASTER */
-
-#ifdef CONFIG_I2C
- case MCP_TYPE_008:
- mcp->ops = &mcp23008_ops;
+ } else {
+ mcp->ops = &mcp23s08_ops;
mcp->chip.ngpio = 8;
- mcp->chip.label = "mcp23008";
- break;
-
- case MCP_TYPE_017:
- mcp->ops = &mcp23017_ops;
- mcp->chip.ngpio = 16;
- mcp->chip.label = "mcp23017";
- break;
-#endif /* CONFIG_I2C */
-
- default:
- dev_err(dev, "invalid device type (%d)\n", type);
- return -EINVAL;
+ mcp->chip.label = "mcp23s08";
}
-
mcp->chip.base = base;
mcp->chip.can_sleep = 1;
- mcp->chip.dev = dev;
+ mcp->chip.dev = &spi->dev;
mcp->chip.owner = THIS_MODULE;
/* verify MCP_IOCON.SEQOP = 0, so sequential reads work,
@@ -465,98 +374,11 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
status = gpiochip_add(&mcp->chip);
fail:
if (status < 0)
- dev_dbg(dev, "can't setup chip %d, --> %d\n",
- addr, status);
+ dev_dbg(&spi->dev, "can't setup chip %d, --> %d\n",
+ addr, status);
return status;
}
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_I2C
-
-static int __devinit mcp230xx_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct mcp23s08_platform_data *pdata;
- struct mcp23s08 *mcp;
- int status;
-
- pdata = client->dev.platform_data;
- if (!pdata || !gpio_is_valid(pdata->base)) {
- dev_dbg(&client->dev, "invalid or missing platform data\n");
- return -EINVAL;
- }
-
- mcp = kzalloc(sizeof *mcp, GFP_KERNEL);
- if (!mcp)
- return -ENOMEM;
-
- status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr,
- id->driver_data, pdata->base,
- pdata->chip[0].pullups);
- if (status)
- goto fail;
-
- i2c_set_clientdata(client, mcp);
-
- return 0;
-
-fail:
- kfree(mcp);
-
- return status;
-}
-
-static int __devexit mcp230xx_remove(struct i2c_client *client)
-{
- struct mcp23s08 *mcp = i2c_get_clientdata(client);
- int status;
-
- status = gpiochip_remove(&mcp->chip);
- if (status == 0)
- kfree(mcp);
-
- return status;
-}
-
-static const struct i2c_device_id mcp230xx_id[] = {
- { "mcp23008", MCP_TYPE_008 },
- { "mcp23017", MCP_TYPE_017 },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, mcp230xx_id);
-
-static struct i2c_driver mcp230xx_driver = {
- .driver = {
- .name = "mcp230xx",
- .owner = THIS_MODULE,
- },
- .probe = mcp230xx_probe,
- .remove = __devexit_p(mcp230xx_remove),
- .id_table = mcp230xx_id,
-};
-
-static int __init mcp23s08_i2c_init(void)
-{
- return i2c_add_driver(&mcp230xx_driver);
-}
-
-static void mcp23s08_i2c_exit(void)
-{
- i2c_del_driver(&mcp230xx_driver);
-}
-
-#else
-
-static int __init mcp23s08_i2c_init(void) { return 0; }
-static void mcp23s08_i2c_exit(void) { }
-
-#endif /* CONFIG_I2C */
-
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_SPI_MASTER
-
static int mcp23s08_probe(struct spi_device *spi)
{
struct mcp23s08_platform_data *pdata;
@@ -599,8 +421,7 @@ static int mcp23s08_probe(struct spi_device *spi)
continue;
chips--;
data->mcp[addr] = &data->chip[chips];
- status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi,
- 0x40 | (addr << 1), type, base,
+ status = mcp23s08_probe_one(spi, addr, type, base,
pdata->chip[addr].pullups);
if (status < 0)
goto fail;
@@ -614,6 +435,14 @@ static int mcp23s08_probe(struct spi_device *spi)
* handled here...
*/
+ if (pdata->setup) {
+ status = pdata->setup(spi,
+ pdata->base, data->ngpio,
+ pdata->context);
+ if (status < 0)
+ dev_dbg(&spi->dev, "setup --> %d\n", status);
+ }
+
return 0;
fail:
@@ -633,9 +462,20 @@ fail:
static int mcp23s08_remove(struct spi_device *spi)
{
struct mcp23s08_driver_data *data = spi_get_drvdata(spi);
+ struct mcp23s08_platform_data *pdata = spi->dev.platform_data;
unsigned addr;
int status = 0;
+ if (pdata->teardown) {
+ status = pdata->teardown(spi,
+ pdata->base, data->ngpio,
+ pdata->context);
+ if (status < 0) {
+ dev_err(&spi->dev, "%s --> %d\n", "teardown", status);
+ return status;
+ }
+ }
+
for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) {
int tmp;
@@ -670,53 +510,20 @@ static struct spi_driver mcp23s08_driver = {
},
};
-static int __init mcp23s08_spi_init(void)
-{
- return spi_register_driver(&mcp23s08_driver);
-}
-
-static void mcp23s08_spi_exit(void)
-{
- spi_unregister_driver(&mcp23s08_driver);
-}
-
-#else
-
-static int __init mcp23s08_spi_init(void) { return 0; }
-static void mcp23s08_spi_exit(void) { }
-
-#endif /* CONFIG_SPI_MASTER */
-
/*----------------------------------------------------------------------*/
static int __init mcp23s08_init(void)
{
- int ret;
-
- ret = mcp23s08_spi_init();
- if (ret)
- goto spi_fail;
-
- ret = mcp23s08_i2c_init();
- if (ret)
- goto i2c_fail;
-
- return 0;
-
- i2c_fail:
- mcp23s08_spi_exit();
- spi_fail:
- return ret;
+ return spi_register_driver(&mcp23s08_driver);
}
-/* register after spi/i2c postcore initcall and before
+/* register after spi postcore initcall and before
* subsys initcalls that may rely on these GPIOs
*/
subsys_initcall(mcp23s08_init);
static void __exit mcp23s08_exit(void)
{
- mcp23s08_spi_exit();
- mcp23s08_i2c_exit();
+ spi_unregister_driver(&mcp23s08_driver);
}
module_exit(mcp23s08_exit);
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/ml_ioh_gpio.c
index a9016f56ed7..1bc621ac353 100644
--- a/drivers/gpio/gpio-ml-ioh.c
+++ b/drivers/gpio/ml_ioh_gpio.c
@@ -233,7 +233,7 @@ static int __devinit ioh_gpio_probe(struct pci_dev *pdev,
return 0;
err_gpiochip_add:
- while (--i >= 0) {
+ for (; i != 0; i--) {
chip--;
ret = gpiochip_remove(&chip->gpio);
if (ret)
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/pca953x.c
index c43b8ff626a..0451d7ac94a 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -1,5 +1,5 @@
/*
- * PCA953x 4/8/16 bit I/O ports
+ * pca953x.c - 4/8/16 bit I/O ports
*
* Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
* Copyright (C) 2007 Marvell International Ltd.
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#ifdef CONFIG_OF_GPIO
#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
#endif
#define PCA953X_INPUT 0
@@ -84,6 +85,7 @@ struct pca953x_chip {
#endif
struct i2c_client *client;
+ struct pca953x_platform_data *dyn_pdata;
struct gpio_chip gpio_chip;
const char *const *names;
int chip_type;
@@ -435,7 +437,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)
do {
level = __ffs(pending);
- handle_nested_irq(level + chip->irq_base);
+ generic_handle_irq(level + chip->irq_base);
pending &= ~(1 << level);
} while (pending);
@@ -444,13 +446,13 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)
}
static int pca953x_irq_setup(struct pca953x_chip *chip,
- const struct i2c_device_id *id,
- int irq_base)
+ const struct i2c_device_id *id)
{
struct i2c_client *client = chip->client;
+ struct pca953x_platform_data *pdata = client->dev.platform_data;
int ret, offset = 0;
- if (irq_base != -1
+ if (pdata->irq_base != -1
&& (id->driver_data & PCA_INT)) {
int lvl;
@@ -472,19 +474,15 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
* this purpose.
*/
chip->irq_stat &= chip->reg_direction;
+ chip->irq_base = pdata->irq_base;
mutex_init(&chip->irq_lock);
- chip->irq_base = irq_alloc_descs(-1, irq_base, chip->gpio_chip.ngpio, -1);
- if (chip->irq_base < 0)
- goto out_failed;
-
for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) {
int irq = lvl + chip->irq_base;
- irq_clear_status_flags(irq, IRQ_NOREQUEST);
irq_set_chip_data(irq, chip);
- irq_set_chip(irq, &pca953x_irq_chip);
- irq_set_nested_thread(irq, true);
+ irq_set_chip_and_handler(irq, &pca953x_irq_chip,
+ handle_simple_irq);
#ifdef CONFIG_ARM
set_irq_flags(irq, IRQF_VALID);
#else
@@ -495,7 +493,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
ret = request_threaded_irq(client->irq,
NULL,
pca953x_irq_handler,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
dev_name(&client->dev), chip);
if (ret) {
dev_err(&client->dev, "failed to request irq %d\n",
@@ -515,19 +514,17 @@ out_failed:
static void pca953x_irq_teardown(struct pca953x_chip *chip)
{
- if (chip->irq_base != -1) {
- irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio);
+ if (chip->irq_base != -1)
free_irq(chip->client->irq, chip);
- }
}
#else /* CONFIG_GPIO_PCA953X_IRQ */
static int pca953x_irq_setup(struct pca953x_chip *chip,
- const struct i2c_device_id *id,
- int irq_base)
+ const struct i2c_device_id *id)
{
struct i2c_client *client = chip->client;
+ struct pca953x_platform_data *pdata = client->dev.platform_data;
- if (irq_base != -1 && (id->driver_data & PCA_INT))
+ if (pdata->irq_base != -1 && (id->driver_data & PCA_INT))
dev_warn(&client->dev, "interrupt support not compiled in\n");
return 0;
@@ -544,39 +541,46 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip)
#ifdef CONFIG_OF_GPIO
/*
* Translate OpenFirmware node properties into platform_data
- * WARNING: This is DEPRECATED and will be removed eventually!
*/
-void
-pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
+static struct pca953x_platform_data *
+pca953x_get_alt_pdata(struct i2c_client *client)
{
+ struct pca953x_platform_data *pdata;
struct device_node *node;
const __be32 *val;
int size;
node = client->dev.of_node;
if (node == NULL)
- return;
+ return NULL;
+
+ pdata = kzalloc(sizeof(struct pca953x_platform_data), GFP_KERNEL);
+ if (pdata == NULL) {
+ dev_err(&client->dev, "Unable to allocate platform_data\n");
+ return NULL;
+ }
- *gpio_base = -1;
+ pdata->gpio_base = -1;
val = of_get_property(node, "linux,gpio-base", &size);
- WARN(val, "%s: device-tree property 'linux,gpio-base' is deprecated!", __func__);
if (val) {
if (size != sizeof(*val))
dev_warn(&client->dev, "%s: wrong linux,gpio-base\n",
node->full_name);
else
- *gpio_base = be32_to_cpup(val);
+ pdata->gpio_base = be32_to_cpup(val);
}
val = of_get_property(node, "polarity", NULL);
- WARN(val, "%s: device-tree property 'polarity' is deprecated!", __func__);
if (val)
- *invert = *val;
+ pdata->invert = *val;
+
+ return pdata;
}
#else
-void
-pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
+static struct pca953x_platform_data *
+pca953x_get_alt_pdata(struct i2c_client *client)
{
+ return NULL;
}
#endif
@@ -638,7 +642,6 @@ static int __devinit pca953x_probe(struct i2c_client *client,
{
struct pca953x_platform_data *pdata;
struct pca953x_chip *chip;
- int irq_base=0, invert=0;
int ret = 0;
chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
@@ -646,22 +649,26 @@ static int __devinit pca953x_probe(struct i2c_client *client,
return -ENOMEM;
pdata = client->dev.platform_data;
- if (pdata) {
- irq_base = pdata->irq_base;
- chip->gpio_start = pdata->gpio_base;
- invert = pdata->invert;
- chip->names = pdata->names;
- } else {
- pca953x_get_alt_pdata(client, &chip->gpio_start, &invert);
-#ifdef CONFIG_OF_GPIO
- /* If I2C node has no interrupts property, disable GPIO interrupts */
- if (of_find_property(client->dev.of_node, "interrupts", NULL) == NULL)
- irq_base = -1;
-#endif
+ if (pdata == NULL) {
+ pdata = pca953x_get_alt_pdata(client);
+ /*
+ * Unlike normal platform_data, this is allocated
+ * dynamically and must be freed in the driver
+ */
+ chip->dyn_pdata = pdata;
+ }
+
+ if (pdata == NULL) {
+ dev_dbg(&client->dev, "no platform data\n");
+ ret = -EINVAL;
+ goto out_failed;
}
chip->client = client;
+ chip->gpio_start = pdata->gpio_base;
+
+ chip->names = pdata->names;
chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE);
mutex_init(&chip->i2c_lock);
@@ -672,13 +679,13 @@ static int __devinit pca953x_probe(struct i2c_client *client,
pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK);
if (chip->chip_type == PCA953X_TYPE)
- device_pca953x_init(chip, invert);
+ device_pca953x_init(chip, pdata->invert);
else if (chip->chip_type == PCA957X_TYPE)
- device_pca957x_init(chip, invert);
+ device_pca957x_init(chip, pdata->invert);
else
goto out_failed;
- ret = pca953x_irq_setup(chip, id, irq_base);
+ ret = pca953x_irq_setup(chip, id);
if (ret)
goto out_failed;
@@ -686,7 +693,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
if (ret)
goto out_failed_irq;
- if (pdata && pdata->setup) {
+ if (pdata->setup) {
ret = pdata->setup(client, chip->gpio_chip.base,
chip->gpio_chip.ngpio, pdata->context);
if (ret < 0)
@@ -699,6 +706,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
out_failed_irq:
pca953x_irq_teardown(chip);
out_failed:
+ kfree(chip->dyn_pdata);
kfree(chip);
return ret;
}
@@ -709,7 +717,7 @@ static int pca953x_remove(struct i2c_client *client)
struct pca953x_chip *chip = i2c_get_clientdata(client);
int ret = 0;
- if (pdata && pdata->teardown) {
+ if (pdata->teardown) {
ret = pdata->teardown(client, chip->gpio_chip.base,
chip->gpio_chip.ngpio, pdata->context);
if (ret < 0) {
@@ -727,6 +735,7 @@ static int pca953x_remove(struct i2c_client *client)
}
pca953x_irq_teardown(chip);
+ kfree(chip->dyn_pdata);
kfree(chip);
return 0;
}
diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/pcf857x.c
index 7369fdda92b..879b473aab5 100644
--- a/drivers/gpio/gpio-pcf857x.c
+++ b/drivers/gpio/pcf857x.c
@@ -1,5 +1,5 @@
/*
- * Driver for pcf857x, pca857x, and pca967x I2C GPIO expanders
+ * pcf857x - driver for pcf857x, pca857x, and pca967x I2C GPIO expanders
*
* Copyright (C) 2007 David Brownell
*
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/pch_gpio.c
index 36919e77c49..36919e77c49 100644
--- a/drivers/gpio/gpio-pch.c
+++ b/drivers/gpio/pch_gpio.c
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/pl061.c
index 2c5a18f32bf..6fcb28cdd86 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/pl061.c
@@ -1,5 +1,7 @@
/*
- * Copyright (C) 2008, 2009 Provigent Ltd.
+ * linux/drivers/gpio/pl061.c
+ *
+ * Copyright (C) 2008, 2009 Provigent 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
diff --git a/drivers/gpio/gpio-rdc321x.c b/drivers/gpio/rdc321x-gpio.c
index 2762698e020..2762698e020 100644
--- a/drivers/gpio/gpio-rdc321x.c
+++ b/drivers/gpio/rdc321x-gpio.c
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/sch_gpio.c
index 16351584549..56060421cdf 100644
--- a/drivers/gpio/gpio-sch.c
+++ b/drivers/gpio/sch_gpio.c
@@ -1,5 +1,5 @@
/*
- * GPIO interface for Intel Poulsbo SCH
+ * sch_gpio.c - GPIO interface for Intel Poulsbo SCH
*
* Copyright (c) 2010 CompuLab Ltd
* Author: Denis Turischev <denis@compulab.co.il>
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/stmpe-gpio.c
index 4c980b57332..4c980b57332 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/stmpe-gpio.c
diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/sx150x.c
index a4f73534394..a4f73534394 100644
--- a/drivers/gpio/gpio-sx150x.c
+++ b/drivers/gpio/sx150x.c
diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/tc3589x-gpio.c
index 2a82e8999a4..2a82e8999a4 100644
--- a/drivers/gpio/gpio-tc3589x.c
+++ b/drivers/gpio/tc3589x-gpio.c
diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/timbgpio.c
index c593bd46bfb..0265872e57d 100644
--- a/drivers/gpio/gpio-timberdale.c
+++ b/drivers/gpio/timbgpio.c
@@ -1,5 +1,5 @@
/*
- * Timberdale FPGA GPIO driver
+ * timbgpio.c timberdale FPGA GPIO driver
* Copyright (c) 2009 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/tps65910-gpio.c
index b9c1c297669..15097ca616d 100644
--- a/drivers/gpio/gpio-tps65910.c
+++ b/drivers/gpio/tps65910-gpio.c
@@ -1,5 +1,5 @@
/*
- * TI TPS6591x GPIO driver
+ * tps65910-gpio.c -- TI TPS6591x
*
* Copyright 2010 Texas Instruments Inc.
*
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/twl4030-gpio.c
index b8b4f228757..57635ac35a7 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/twl4030-gpio.c
@@ -1,5 +1,5 @@
/*
- * Access to GPIOs on TWL4030/TPS659x0 chips
+ * twl4030_gpio.c -- access to GPIOs on TWL4030/TPS659x0 chips
*
* Copyright (C) 2006-2007 Texas Instruments, Inc.
* Copyright (C) 2006 MontaVista Software, Inc.
diff --git a/drivers/gpio/gpio-ucb1400.c b/drivers/gpio/ucb1400_gpio.c
index 50e6bd1392c..50e6bd1392c 100644
--- a/drivers/gpio/gpio-ucb1400.c
+++ b/drivers/gpio/ucb1400_gpio.c
diff --git a/drivers/gpio/gpio-vr41xx.c b/drivers/gpio/vr41xx_giu.c
index 98723cb9ac6..a365be040b3 100644
--- a/drivers/gpio/gpio-vr41xx.c
+++ b/drivers/gpio/vr41xx_giu.c
@@ -518,7 +518,7 @@ static int __devinit giu_probe(struct platform_device *pdev)
if (!res)
return -EBUSY;
- giu_base = ioremap(res->start, resource_size(res));
+ giu_base = ioremap(res->start, res->end - res->start + 1);
if (!giu_base)
return -ENOMEM;
diff --git a/drivers/gpio/gpio-vx855.c b/drivers/gpio/vx855_gpio.c
index ef5aabd8b8b..ef5aabd8b8b 100644
--- a/drivers/gpio/gpio-vx855.c
+++ b/drivers/gpio/vx855_gpio.c
diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/wm831x-gpio.c
index deb949e75ec..2bcfb0be09f 100644
--- a/drivers/gpio/gpio-wm831x.c
+++ b/drivers/gpio/wm831x-gpio.c
@@ -1,5 +1,5 @@
/*
- * gpiolib support for Wolfson WM831x PMICs
+ * wm831x-gpio.c -- gpiolib support for Wolfson WM831x PMICs
*
* Copyright 2009 Wolfson Microelectronics PLC.
*
diff --git a/drivers/gpio/gpio-wm8350.c b/drivers/gpio/wm8350-gpiolib.c
index a06af515483..359999290f5 100644
--- a/drivers/gpio/gpio-wm8350.c
+++ b/drivers/gpio/wm8350-gpiolib.c
@@ -1,5 +1,5 @@
/*
- * gpiolib support for Wolfson WM835x PMICs
+ * wm835x-gpiolib.c -- gpiolib support for Wolfson WM835x PMICs
*
* Copyright 2009 Wolfson Microelectronics PLC.
*
diff --git a/drivers/gpio/gpio-wm8994.c b/drivers/gpio/wm8994-gpio.c
index 96198f3fab7..c822baacd8f 100644
--- a/drivers/gpio/gpio-wm8994.c
+++ b/drivers/gpio/wm8994-gpio.c
@@ -1,5 +1,5 @@
/*
- * gpiolib support for Wolfson WM8994
+ * wm8994-gpio.c -- gpiolib support for Wolfson WM8994
*
* Copyright 2009 Wolfson Microelectronics PLC.
*
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/xilinx_gpio.c
index 846fbd5e31b..846fbd5e31b 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/xilinx_gpio.c