summaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2011-03-08 00:55:06 +0100
committerJames Morris <jmorris@namei.org>2011-03-08 00:55:06 +0100
commit1cc26bada9f6807814806db2f0d78792eecdac71 (patch)
tree5509b5139db04af6c13db0a580c84116a4a54039 /drivers/gpio
parentTOMOYO: Fix memory leak upon file open. (diff)
parentMerge branch 'omap-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/ker... (diff)
downloadlinux-1cc26bada9f6807814806db2f0d78792eecdac71.tar.xz
linux-1cc26bada9f6807814806db2f0d78792eecdac71.zip
Merge branch 'master'; commit 'v2.6.38-rc7' into next
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/Kconfig14
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/adp5588-gpio.c39
-rw-r--r--drivers/gpio/cs5535-gpio.c145
-rw-r--r--drivers/gpio/langwell_gpio.c25
-rw-r--r--drivers/gpio/max732x.c38
-rw-r--r--drivers/gpio/ml_ioh_gpio.c352
-rw-r--r--drivers/gpio/pca953x.c66
-rw-r--r--drivers/gpio/pl061.c28
-rw-r--r--drivers/gpio/stmpe-gpio.c36
-rw-r--r--drivers/gpio/sx150x.c46
-rw-r--r--drivers/gpio/tc3589x-gpio.c36
-rw-r--r--drivers/gpio/timbgpio.c26
-rw-r--r--drivers/gpio/vr41xx_giu.c48
-rw-r--r--drivers/gpio/wm8994-gpio.c24
15 files changed, 677 insertions, 247 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 082495bb08a7..664660e56335 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -118,7 +118,7 @@ config GPIO_SCH
config GPIO_VX855
tristate "VIA VX855/VX875 GPIO"
- depends on GPIOLIB
+ depends on GPIOLIB && MFD_SUPPORT && PCI
select MFD_CORE
select MFD_VX855
help
@@ -295,7 +295,7 @@ comment "PCI GPIO expanders:"
config GPIO_CS5535
tristate "AMD CS5535/CS5536 GPIO support"
- depends on PCI && !CS5535_GPIO
+ depends on PCI && X86 && !CS5535_GPIO
help
The AMD CS5535 and CS5536 southbridges support 28 GPIO pins that
can be used for quite a number of things. The CS5535/6 is found on
@@ -333,6 +333,15 @@ config GPIO_PCH
which is an IOH(Input/Output Hub) for x86 embedded processor.
This driver can access PCH GPIO device.
+config GPIO_ML_IOH
+ tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support"
+ depends on PCI
+ help
+ ML7213 is companion chip for Intel Atom E6xx series.
+ This driver can be used for OKI SEMICONDUCTOR ML7213 IOH(Input/Output
+ Hub) which is for IVI(In-Vehicle Infotainment) use.
+ This driver can access the IOH's GPIO device.
+
config GPIO_TIMBERDALE
bool "Support for timberdale GPIO IP"
depends on MFD_TIMBERDALE && GPIOLIB && HAS_IOMEM
@@ -342,6 +351,7 @@ config GPIO_TIMBERDALE
config GPIO_RDC321X
tristate "RDC R-321x GPIO support"
depends on PCI && GPIOLIB
+ select MFD_SUPPORT
select MFD_CORE
select MFD_RDC321X
help
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 39bfd7a37650..3351cf87b0ed 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -41,3 +41,4 @@ 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
diff --git a/drivers/gpio/adp5588-gpio.c b/drivers/gpio/adp5588-gpio.c
index 0871f78af593..33fc685cb385 100644
--- a/drivers/gpio/adp5588-gpio.c
+++ b/drivers/gpio/adp5588-gpio.c
@@ -146,9 +146,10 @@ static int adp5588_gpio_to_irq(struct gpio_chip *chip, unsigned off)
return dev->irq_base + off;
}
-static void adp5588_irq_bus_lock(unsigned int irq)
+static void adp5588_irq_bus_lock(struct irq_data *d)
{
- struct adp5588_gpio *dev = get_irq_chip_data(irq);
+ struct adp5588_gpio *dev = irq_data_get_irq_chip_data(d);
+
mutex_lock(&dev->irq_lock);
}
@@ -160,9 +161,9 @@ static void adp5588_irq_bus_lock(unsigned int irq)
* and unlocks the bus.
*/
-static void adp5588_irq_bus_sync_unlock(unsigned int irq)
+static void adp5588_irq_bus_sync_unlock(struct irq_data *d)
{
- struct adp5588_gpio *dev = get_irq_chip_data(irq);
+ struct adp5588_gpio *dev = irq_data_get_irq_chip_data(d);
int i;
for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++)
@@ -175,31 +176,31 @@ static void adp5588_irq_bus_sync_unlock(unsigned int irq)
mutex_unlock(&dev->irq_lock);
}
-static void adp5588_irq_mask(unsigned int irq)
+static void adp5588_irq_mask(struct irq_data *d)
{
- struct adp5588_gpio *dev = get_irq_chip_data(irq);
- unsigned gpio = irq - dev->irq_base;
+ struct adp5588_gpio *dev = irq_data_get_irq_chip_data(d);
+ unsigned gpio = d->irq - dev->irq_base;
dev->irq_mask[ADP5588_BANK(gpio)] &= ~ADP5588_BIT(gpio);
}
-static void adp5588_irq_unmask(unsigned int irq)
+static void adp5588_irq_unmask(struct irq_data *d)
{
- struct adp5588_gpio *dev = get_irq_chip_data(irq);
- unsigned gpio = irq - dev->irq_base;
+ struct adp5588_gpio *dev = irq_data_get_irq_chip_data(d);
+ unsigned gpio = d->irq - dev->irq_base;
dev->irq_mask[ADP5588_BANK(gpio)] |= ADP5588_BIT(gpio);
}
-static int adp5588_irq_set_type(unsigned int irq, unsigned int type)
+static int adp5588_irq_set_type(struct irq_data *d, unsigned int type)
{
- struct adp5588_gpio *dev = get_irq_chip_data(irq);
- uint16_t gpio = irq - dev->irq_base;
+ struct adp5588_gpio *dev = irq_data_get_irq_chip_data(d);
+ uint16_t gpio = d->irq - dev->irq_base;
unsigned bank, bit;
if ((type & IRQ_TYPE_EDGE_BOTH)) {
dev_err(&dev->client->dev, "irq %d: unsupported type %d\n",
- irq, type);
+ d->irq, type);
return -EINVAL;
}
@@ -222,11 +223,11 @@ static int adp5588_irq_set_type(unsigned int irq, unsigned int type)
static struct irq_chip adp5588_irq_chip = {
.name = "adp5588",
- .mask = adp5588_irq_mask,
- .unmask = adp5588_irq_unmask,
- .bus_lock = adp5588_irq_bus_lock,
- .bus_sync_unlock = adp5588_irq_bus_sync_unlock,
- .set_type = adp5588_irq_set_type,
+ .irq_mask = adp5588_irq_mask,
+ .irq_unmask = adp5588_irq_unmask,
+ .irq_bus_lock = adp5588_irq_bus_lock,
+ .irq_bus_sync_unlock = adp5588_irq_bus_sync_unlock,
+ .irq_set_type = adp5588_irq_set_type,
};
static int adp5588_gpio_read_intstat(struct i2c_client *client, u8 *buf)
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c
index d3e55a0ae92b..0d05ea7d499b 100644
--- a/drivers/gpio/cs5535-gpio.c
+++ b/drivers/gpio/cs5535-gpio.c
@@ -11,13 +11,13 @@
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/module.h>
-#include <linux/pci.h>
+#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/cs5535.h>
+#include <asm/msr.h>
#define DRV_NAME "cs5535-gpio"
-#define GPIO_BAR 1
/*
* Some GPIO pins
@@ -46,7 +46,7 @@ static struct cs5535_gpio_chip {
struct gpio_chip chip;
resource_size_t base;
- struct pci_dev *pdev;
+ struct platform_device *pdev;
spinlock_t lock;
} cs5535_gpio_chip;
@@ -144,6 +144,57 @@ int cs5535_gpio_isset(unsigned offset, unsigned int reg)
}
EXPORT_SYMBOL_GPL(cs5535_gpio_isset);
+int cs5535_gpio_set_irq(unsigned group, unsigned irq)
+{
+ uint32_t lo, hi;
+
+ if (group > 7 || irq > 15)
+ return -EINVAL;
+
+ rdmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
+
+ lo &= ~(0xF << (group * 4));
+ lo |= (irq & 0xF) << (group * 4);
+
+ wrmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cs5535_gpio_set_irq);
+
+void cs5535_gpio_setup_event(unsigned offset, int pair, int pme)
+{
+ struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
+ uint32_t shift = (offset % 8) * 4;
+ unsigned long flags;
+ uint32_t val;
+
+ if (offset >= 24)
+ offset = GPIO_MAP_W;
+ else if (offset >= 16)
+ offset = GPIO_MAP_Z;
+ else if (offset >= 8)
+ offset = GPIO_MAP_Y;
+ else
+ offset = GPIO_MAP_X;
+
+ spin_lock_irqsave(&chip->lock, flags);
+ val = inl(chip->base + offset);
+
+ /* Clear whatever was there before */
+ val &= ~(0xF << shift);
+
+ /* Set the new value */
+ val |= ((pair & 7) << shift);
+
+ /* Set the PME bit if this is a PME event */
+ if (pme)
+ val |= (1 << (shift + 3));
+
+ outl(val, chip->base + offset);
+ spin_unlock_irqrestore(&chip->lock, flags);
+}
+EXPORT_SYMBOL_GPL(cs5535_gpio_setup_event);
+
/*
* Generic gpio_chip API support.
*/
@@ -249,10 +300,10 @@ static struct cs5535_gpio_chip cs5535_gpio_chip = {
},
};
-static int __init cs5535_gpio_probe(struct pci_dev *pdev,
- const struct pci_device_id *pci_id)
+static int __devinit cs5535_gpio_probe(struct platform_device *pdev)
{
- int err;
+ struct resource *res;
+ int err = -EIO;
ulong mask_orig = mask;
/* There are two ways to get the GPIO base address; one is by
@@ -262,25 +313,23 @@ static int __init cs5535_gpio_probe(struct pci_dev *pdev,
* it turns out to be unreliable in the face of crappy BIOSes, we
* can always go back to using MSRs.. */
- err = pci_enable_device_io(pdev);
- if (err) {
- dev_err(&pdev->dev, "can't enable device IO\n");
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "can't fetch device resource info\n");
goto done;
}
- err = pci_request_region(pdev, GPIO_BAR, DRV_NAME);
- if (err) {
- dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR);
+ if (!request_region(res->start, resource_size(res), pdev->name)) {
+ dev_err(&pdev->dev, "can't request region\n");
goto done;
}
/* set up the driver-specific struct */
- cs5535_gpio_chip.base = pci_resource_start(pdev, GPIO_BAR);
+ cs5535_gpio_chip.base = res->start;
cs5535_gpio_chip.pdev = pdev;
spin_lock_init(&cs5535_gpio_chip.lock);
- dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", GPIO_BAR,
- (unsigned long long) cs5535_gpio_chip.base);
+ dev_info(&pdev->dev, "reserved resource region %pR\n", res);
/* mask out reserved pins */
mask &= 0x1F7FFFFF;
@@ -298,78 +347,49 @@ static int __init cs5535_gpio_probe(struct pci_dev *pdev,
if (err)
goto release_region;
- dev_info(&pdev->dev, DRV_NAME ": GPIO support successfully loaded.\n");
+ dev_info(&pdev->dev, "GPIO support successfully loaded.\n");
return 0;
release_region:
- pci_release_region(pdev, GPIO_BAR);
+ release_region(res->start, resource_size(res));
done:
return err;
}
-static void __exit cs5535_gpio_remove(struct pci_dev *pdev)
+static int __devexit cs5535_gpio_remove(struct platform_device *pdev)
{
+ struct resource *r;
int err;
err = gpiochip_remove(&cs5535_gpio_chip.chip);
if (err) {
/* uhh? */
dev_err(&pdev->dev, "unable to remove gpio_chip?\n");
- }
- pci_release_region(pdev, GPIO_BAR);
-}
-
-static struct pci_device_id cs5535_gpio_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
- { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
- { 0, },
-};
-MODULE_DEVICE_TABLE(pci, cs5535_gpio_pci_tbl);
-
-/*
- * We can't use the standard PCI driver registration stuff here, since
- * that allows only one driver to bind to each PCI device (and we want
- * multiple drivers to be able to bind to the device). Instead, manually
- * scan for the PCI device, request a single region, and keep track of the
- * devices that we're using.
- */
-
-static int __init cs5535_gpio_scan_pci(void)
-{
- struct pci_dev *pdev;
- int err = -ENODEV;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(cs5535_gpio_pci_tbl); i++) {
- pdev = pci_get_device(cs5535_gpio_pci_tbl[i].vendor,
- cs5535_gpio_pci_tbl[i].device, NULL);
- if (pdev) {
- err = cs5535_gpio_probe(pdev, &cs5535_gpio_pci_tbl[i]);
- if (err)
- pci_dev_put(pdev);
-
- /* we only support a single CS5535/6 southbridge */
- break;
- }
+ return err;
}
- return err;
+ r = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ release_region(r->start, resource_size(r));
+ return 0;
}
-static void __exit cs5535_gpio_free_pci(void)
-{
- cs5535_gpio_remove(cs5535_gpio_chip.pdev);
- pci_dev_put(cs5535_gpio_chip.pdev);
-}
+static struct platform_driver cs5535_gpio_drv = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = cs5535_gpio_probe,
+ .remove = __devexit_p(cs5535_gpio_remove),
+};
static int __init cs5535_gpio_init(void)
{
- return cs5535_gpio_scan_pci();
+ return platform_driver_register(&cs5535_gpio_drv);
}
static void __exit cs5535_gpio_exit(void)
{
- cs5535_gpio_free_pci();
+ platform_driver_unregister(&cs5535_gpio_drv);
}
module_init(cs5535_gpio_init);
@@ -378,3 +398,4 @@ module_exit(cs5535_gpio_exit);
MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>");
MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c
index 64db9dc3a275..54d70a47afc1 100644
--- a/drivers/gpio/langwell_gpio.c
+++ b/drivers/gpio/langwell_gpio.c
@@ -134,10 +134,10 @@ static int lnw_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
return lnw->irq_base + offset;
}
-static int lnw_irq_type(unsigned irq, unsigned type)
+static int lnw_irq_type(struct irq_data *d, unsigned type)
{
- struct lnw_gpio *lnw = get_irq_chip_data(irq);
- u32 gpio = irq - lnw->irq_base;
+ struct lnw_gpio *lnw = irq_data_get_irq_chip_data(d);
+ u32 gpio = d->irq - lnw->irq_base;
unsigned long flags;
u32 value;
void __iomem *grer = gpio_reg(&lnw->chip, gpio, GRER);
@@ -162,19 +162,19 @@ static int lnw_irq_type(unsigned irq, unsigned type)
return 0;
}
-static void lnw_irq_unmask(unsigned irq)
+static void lnw_irq_unmask(struct irq_data *d)
{
}
-static void lnw_irq_mask(unsigned irq)
+static void lnw_irq_mask(struct irq_data *d)
{
}
static struct irq_chip lnw_irqchip = {
.name = "LNW-GPIO",
- .mask = lnw_irq_mask,
- .unmask = lnw_irq_unmask,
- .set_type = lnw_irq_type,
+ .irq_mask = lnw_irq_mask,
+ .irq_unmask = lnw_irq_unmask,
+ .irq_set_type = lnw_irq_type,
};
static DEFINE_PCI_DEVICE_TABLE(lnw_gpio_ids) = { /* pin number */
@@ -187,7 +187,7 @@ MODULE_DEVICE_TABLE(pci, lnw_gpio_ids);
static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
{
- struct lnw_gpio *lnw = (struct lnw_gpio *)get_irq_data(irq);
+ struct lnw_gpio *lnw = get_irq_data(irq);
u32 base, gpio;
void __iomem *gedr;
u32 gedr_v;
@@ -206,7 +206,12 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
/* clear the edge detect status bit */
writel(gedr_v, gedr);
}
- desc->chip->eoi(irq);
+
+ if (desc->chip->irq_eoi)
+ desc->chip->irq_eoi(irq_get_irq_data(irq));
+ else
+ dev_warn(lnw->chip.dev, "missing EOI handler for irq %d\n", irq);
+
}
static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
diff --git a/drivers/gpio/max732x.c b/drivers/gpio/max732x.c
index 9cad60f9e962..9e1d01f0071a 100644
--- a/drivers/gpio/max732x.c
+++ b/drivers/gpio/max732x.c
@@ -327,40 +327,40 @@ static int max732x_gpio_to_irq(struct gpio_chip *gc, unsigned off)
return chip->irq_base + off;
}
-static void max732x_irq_mask(unsigned int irq)
+static void max732x_irq_mask(struct irq_data *d)
{
- struct max732x_chip *chip = get_irq_chip_data(irq);
+ struct max732x_chip *chip = irq_data_get_irq_chip_data(d);
- chip->irq_mask_cur &= ~(1 << (irq - chip->irq_base));
+ chip->irq_mask_cur &= ~(1 << (d->irq - chip->irq_base));
}
-static void max732x_irq_unmask(unsigned int irq)
+static void max732x_irq_unmask(struct irq_data *d)
{
- struct max732x_chip *chip = get_irq_chip_data(irq);
+ struct max732x_chip *chip = irq_data_get_irq_chip_data(d);
- chip->irq_mask_cur |= 1 << (irq - chip->irq_base);
+ chip->irq_mask_cur |= 1 << (d->irq - chip->irq_base);
}
-static void max732x_irq_bus_lock(unsigned int irq)
+static void max732x_irq_bus_lock(struct irq_data *d)
{
- struct max732x_chip *chip = get_irq_chip_data(irq);
+ struct max732x_chip *chip = irq_data_get_irq_chip_data(d);
mutex_lock(&chip->irq_lock);
chip->irq_mask_cur = chip->irq_mask;
}
-static void max732x_irq_bus_sync_unlock(unsigned int irq)
+static void max732x_irq_bus_sync_unlock(struct irq_data *d)
{
- struct max732x_chip *chip = get_irq_chip_data(irq);
+ struct max732x_chip *chip = irq_data_get_irq_chip_data(d);
max732x_irq_update_mask(chip);
mutex_unlock(&chip->irq_lock);
}
-static int max732x_irq_set_type(unsigned int irq, unsigned int type)
+static int max732x_irq_set_type(struct irq_data *d, unsigned int type)
{
- struct max732x_chip *chip = get_irq_chip_data(irq);
- uint16_t off = irq - chip->irq_base;
+ struct max732x_chip *chip = irq_data_get_irq_chip_data(d);
+ uint16_t off = d->irq - chip->irq_base;
uint16_t mask = 1 << off;
if (!(mask & chip->dir_input)) {
@@ -371,7 +371,7 @@ static int max732x_irq_set_type(unsigned int irq, unsigned int type)
if (!(type & IRQ_TYPE_EDGE_BOTH)) {
dev_err(&chip->client->dev, "irq %d: unsupported type %d\n",
- irq, type);
+ d->irq, type);
return -EINVAL;
}
@@ -390,11 +390,11 @@ static int max732x_irq_set_type(unsigned int irq, unsigned int type)
static struct irq_chip max732x_irq_chip = {
.name = "max732x",
- .mask = max732x_irq_mask,
- .unmask = max732x_irq_unmask,
- .bus_lock = max732x_irq_bus_lock,
- .bus_sync_unlock = max732x_irq_bus_sync_unlock,
- .set_type = max732x_irq_set_type,
+ .irq_mask = max732x_irq_mask,
+ .irq_unmask = max732x_irq_unmask,
+ .irq_bus_lock = max732x_irq_bus_lock,
+ .irq_bus_sync_unlock = max732x_irq_bus_sync_unlock,
+ .irq_set_type = max732x_irq_set_type,
};
static uint8_t max732x_irq_pending(struct max732x_chip *chip)
diff --git a/drivers/gpio/ml_ioh_gpio.c b/drivers/gpio/ml_ioh_gpio.c
new file mode 100644
index 000000000000..cead8e6ff345
--- /dev/null
+++ b/drivers/gpio/ml_ioh_gpio.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * 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; version 2 of the License.
+ *
+ * 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/kernel.h>
+#include <linux/pci.h>
+#include <linux/gpio.h>
+
+#define PCI_VENDOR_ID_ROHM 0x10DB
+
+struct ioh_reg_comn {
+ u32 ien;
+ u32 istatus;
+ u32 idisp;
+ u32 iclr;
+ u32 imask;
+ u32 imaskclr;
+ u32 po;
+ u32 pi;
+ u32 pm;
+ u32 im_0;
+ u32 im_1;
+ u32 reserved;
+};
+
+struct ioh_regs {
+ struct ioh_reg_comn regs[8];
+ u32 reserve1[16];
+ u32 ioh_sel_reg[4];
+ u32 reserve2[11];
+ u32 srst;
+};
+
+/**
+ * struct ioh_gpio_reg_data - The register store data.
+ * @po_reg: To store contents of PO register.
+ * @pm_reg: To store contents of PM register.
+ */
+struct ioh_gpio_reg_data {
+ u32 po_reg;
+ u32 pm_reg;
+};
+
+/**
+ * struct ioh_gpio - GPIO private data structure.
+ * @base: PCI base address of Memory mapped I/O register.
+ * @reg: Memory mapped IOH GPIO register list.
+ * @dev: Pointer to device structure.
+ * @gpio: Data for GPIO infrastructure.
+ * @ioh_gpio_reg: Memory mapped Register data is saved here
+ * when suspend.
+ * @ch: Indicate GPIO channel
+ */
+struct ioh_gpio {
+ void __iomem *base;
+ struct ioh_regs __iomem *reg;
+ struct device *dev;
+ struct gpio_chip gpio;
+ struct ioh_gpio_reg_data ioh_gpio_reg;
+ struct mutex lock;
+ int ch;
+};
+
+static const int num_ports[] = {6, 12, 16, 16, 15, 16, 16, 12};
+
+static void ioh_gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
+{
+ u32 reg_val;
+ struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio);
+
+ mutex_lock(&chip->lock);
+ reg_val = ioread32(&chip->reg->regs[chip->ch].po);
+ if (val)
+ reg_val |= (1 << nr);
+ else
+ reg_val &= ~(1 << nr);
+
+ iowrite32(reg_val, &chip->reg->regs[chip->ch].po);
+ mutex_unlock(&chip->lock);
+}
+
+static int ioh_gpio_get(struct gpio_chip *gpio, unsigned nr)
+{
+ struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio);
+
+ return ioread32(&chip->reg->regs[chip->ch].pi) & (1 << nr);
+}
+
+static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
+ int val)
+{
+ struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio);
+ u32 pm;
+ u32 reg_val;
+
+ mutex_lock(&chip->lock);
+ pm = ioread32(&chip->reg->regs[chip->ch].pm) &
+ ((1 << num_ports[chip->ch]) - 1);
+ pm |= (1 << nr);
+ iowrite32(pm, &chip->reg->regs[chip->ch].pm);
+
+ reg_val = ioread32(&chip->reg->regs[chip->ch].po);
+ if (val)
+ reg_val |= (1 << nr);
+ else
+ reg_val &= ~(1 << nr);
+
+ mutex_unlock(&chip->lock);
+
+ return 0;
+}
+
+static int ioh_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
+{
+ struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio);
+ u32 pm;
+
+ mutex_lock(&chip->lock);
+ pm = ioread32(&chip->reg->regs[chip->ch].pm) &
+ ((1 << num_ports[chip->ch]) - 1);
+ pm &= ~(1 << nr);
+ iowrite32(pm, &chip->reg->regs[chip->ch].pm);
+ mutex_unlock(&chip->lock);
+
+ return 0;
+}
+
+/*
+ * Save register configuration and disable interrupts.
+ */
+static void ioh_gpio_save_reg_conf(struct ioh_gpio *chip)
+{
+ chip->ioh_gpio_reg.po_reg = ioread32(&chip->reg->regs[chip->ch].po);
+ chip->ioh_gpio_reg.pm_reg = ioread32(&chip->reg->regs[chip->ch].pm);
+}
+
+/*
+ * This function restores the register configuration of the GPIO device.
+ */
+static void ioh_gpio_restore_reg_conf(struct ioh_gpio *chip)
+{
+ /* to store contents of PO register */
+ iowrite32(chip->ioh_gpio_reg.po_reg, &chip->reg->regs[chip->ch].po);
+ /* to store contents of PM register */
+ iowrite32(chip->ioh_gpio_reg.pm_reg, &chip->reg->regs[chip->ch].pm);
+}
+
+static void ioh_gpio_setup(struct ioh_gpio *chip, int num_port)
+{
+ struct gpio_chip *gpio = &chip->gpio;
+
+ gpio->label = dev_name(chip->dev);
+ gpio->owner = THIS_MODULE;
+ gpio->direction_input = ioh_gpio_direction_input;
+ gpio->get = ioh_gpio_get;
+ gpio->direction_output = ioh_gpio_direction_output;
+ gpio->set = ioh_gpio_set;
+ gpio->dbg_show = NULL;
+ gpio->base = -1;
+ gpio->ngpio = num_port;
+ gpio->can_sleep = 0;
+}
+
+static int __devinit ioh_gpio_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ int ret;
+ int i;
+ struct ioh_gpio *chip;
+ void __iomem *base;
+ void __iomem *chip_save;
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "%s : pci_enable_device failed", __func__);
+ goto err_pci_enable;
+ }
+
+ ret = pci_request_regions(pdev, KBUILD_MODNAME);
+ if (ret) {
+ dev_err(&pdev->dev, "pci_request_regions failed-%d", ret);
+ goto err_request_regions;
+ }
+
+ base = pci_iomap(pdev, 1, 0);
+ if (base == 0) {
+ dev_err(&pdev->dev, "%s : pci_iomap failed", __func__);
+ ret = -ENOMEM;
+ goto err_iomap;
+ }
+
+ chip_save = kzalloc(sizeof(*chip) * 8, GFP_KERNEL);
+ if (chip_save == NULL) {
+ dev_err(&pdev->dev, "%s : kzalloc failed", __func__);
+ ret = -ENOMEM;
+ goto err_kzalloc;
+ }
+
+ chip = chip_save;
+ for (i = 0; i < 8; i++, chip++) {
+ chip->dev = &pdev->dev;
+ chip->base = base;
+ chip->reg = chip->base;
+ chip->ch = i;
+ mutex_init(&chip->lock);
+ ioh_gpio_setup(chip, num_ports[i]);
+ ret = gpiochip_add(&chip->gpio);
+ if (ret) {
+ dev_err(&pdev->dev, "IOH gpio: Failed to register GPIO\n");
+ goto err_gpiochip_add;
+ }
+ }
+
+ chip = chip_save;
+ pci_set_drvdata(pdev, chip);
+
+ return 0;
+
+err_gpiochip_add:
+ for (; i != 0; i--) {
+ chip--;
+ ret = gpiochip_remove(&chip->gpio);
+ if (ret)
+ dev_err(&pdev->dev, "Failed gpiochip_remove(%d)\n", i);
+ }
+ kfree(chip_save);
+
+err_kzalloc:
+ pci_iounmap(pdev, base);
+
+err_iomap:
+ pci_release_regions(pdev);
+
+err_request_regions:
+ pci_disable_device(pdev);
+
+err_pci_enable:
+
+ dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret);
+ return ret;
+}
+
+static void __devexit ioh_gpio_remove(struct pci_dev *pdev)
+{
+ int err;
+ int i;
+ struct ioh_gpio *chip = pci_get_drvdata(pdev);
+ void __iomem *chip_save;
+
+ chip_save = chip;
+ for (i = 0; i < 8; i++, chip++) {
+ err = gpiochip_remove(&chip->gpio);
+ if (err)
+ dev_err(&pdev->dev, "Failed gpiochip_remove\n");
+ }
+
+ chip = chip_save;
+ pci_iounmap(pdev, chip->base);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ kfree(chip);
+}
+
+#ifdef CONFIG_PM
+static int ioh_gpio_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ s32 ret;
+ struct ioh_gpio *chip = pci_get_drvdata(pdev);
+
+ ioh_gpio_save_reg_conf(chip);
+ ioh_gpio_restore_reg_conf(chip);
+
+ ret = pci_save_state(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "pci_save_state Failed-%d\n", ret);
+ return ret;
+ }
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D0);
+ ret = pci_enable_wake(pdev, PCI_D0, 1);
+ if (ret)
+ dev_err(&pdev->dev, "pci_enable_wake Failed -%d\n", ret);
+
+ return 0;
+}
+
+static int ioh_gpio_resume(struct pci_dev *pdev)
+{
+ s32 ret;
+ struct ioh_gpio *chip = pci_get_drvdata(pdev);
+
+ ret = pci_enable_wake(pdev, PCI_D0, 0);
+
+ pci_set_power_state(pdev, PCI_D0);
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "pci_enable_device Failed-%d ", ret);
+ return ret;
+ }
+ pci_restore_state(pdev);
+
+ iowrite32(0x01, &chip->reg->srst);
+ iowrite32(0x00, &chip->reg->srst);
+ ioh_gpio_restore_reg_conf(chip);
+
+ return 0;
+}
+#else
+#define ioh_gpio_suspend NULL
+#define ioh_gpio_resume NULL
+#endif
+
+static DEFINE_PCI_DEVICE_TABLE(ioh_gpio_pcidev_id) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x802E) },
+ { 0, }
+};
+
+static struct pci_driver ioh_gpio_driver = {
+ .name = "ml_ioh_gpio",
+ .id_table = ioh_gpio_pcidev_id,
+ .probe = ioh_gpio_probe,
+ .remove = __devexit_p(ioh_gpio_remove),
+ .suspend = ioh_gpio_suspend,
+ .resume = ioh_gpio_resume
+};
+
+static int __init ioh_gpio_pci_init(void)
+{
+ return pci_register_driver(&ioh_gpio_driver);
+}
+module_init(ioh_gpio_pci_init);
+
+static void __exit ioh_gpio_pci_exit(void)
+{
+ pci_unregister_driver(&ioh_gpio_driver);
+}
+module_exit(ioh_gpio_pci_exit);
+
+MODULE_DESCRIPTION("OKI SEMICONDUCTOR ML-IOH series GPIO Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index 501866662e05..b473429eee75 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -60,6 +60,7 @@ struct pca953x_chip {
unsigned gpio_start;
uint16_t reg_output;
uint16_t reg_direction;
+ struct mutex i2c_lock;
#ifdef CONFIG_GPIO_PCA953X_IRQ
struct mutex irq_lock;
@@ -119,13 +120,17 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
chip = container_of(gc, struct pca953x_chip, gpio_chip);
+ mutex_lock(&chip->i2c_lock);
reg_val = chip->reg_direction | (1u << off);
ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
if (ret)
- return ret;
+ goto exit;
chip->reg_direction = reg_val;
- return 0;
+ ret = 0;
+exit:
+ mutex_unlock(&chip->i2c_lock);
+ return ret;
}
static int pca953x_gpio_direction_output(struct gpio_chip *gc,
@@ -137,6 +142,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
chip = container_of(gc, struct pca953x_chip, gpio_chip);
+ mutex_lock(&chip->i2c_lock);
/* set output level */
if (val)
reg_val = chip->reg_output | (1u << off);
@@ -145,7 +151,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
if (ret)
- return ret;
+ goto exit;
chip->reg_output = reg_val;
@@ -153,10 +159,13 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
reg_val = chip->reg_direction & ~(1u << off);
ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
if (ret)
- return ret;
+ goto exit;
chip->reg_direction = reg_val;
- return 0;
+ ret = 0;
+exit:
+ mutex_unlock(&chip->i2c_lock);
+ return ret;
}
static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
@@ -167,7 +176,9 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
chip = container_of(gc, struct pca953x_chip, gpio_chip);
+ mutex_lock(&chip->i2c_lock);
ret = pca953x_read_reg(chip, PCA953X_INPUT, &reg_val);
+ mutex_unlock(&chip->i2c_lock);
if (ret < 0) {
/* NOTE: diagnostic already emitted; that's all we should
* do unless gpio_*_value_cansleep() calls become different
@@ -187,6 +198,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
chip = container_of(gc, struct pca953x_chip, gpio_chip);
+ mutex_lock(&chip->i2c_lock);
if (val)
reg_val = chip->reg_output | (1u << off);
else
@@ -194,9 +206,11 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
if (ret)
- return;
+ goto exit;
chip->reg_output = reg_val;
+exit:
+ mutex_unlock(&chip->i2c_lock);
}
static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
@@ -228,30 +242,30 @@ static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off)
return chip->irq_base + off;
}
-static void pca953x_irq_mask(unsigned int irq)
+static void pca953x_irq_mask(struct irq_data *d)
{
- struct pca953x_chip *chip = get_irq_chip_data(irq);
+ struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
- chip->irq_mask &= ~(1 << (irq - chip->irq_base));
+ chip->irq_mask &= ~(1 << (d->irq - chip->irq_base));
}
-static void pca953x_irq_unmask(unsigned int irq)
+static void pca953x_irq_unmask(struct irq_data *d)
{
- struct pca953x_chip *chip = get_irq_chip_data(irq);
+ struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
- chip->irq_mask |= 1 << (irq - chip->irq_base);
+ chip->irq_mask |= 1 << (d->irq - chip->irq_base);
}
-static void pca953x_irq_bus_lock(unsigned int irq)
+static void pca953x_irq_bus_lock(struct irq_data *d)
{
- struct pca953x_chip *chip = get_irq_chip_data(irq);
+ struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
mutex_lock(&chip->irq_lock);
}
-static void pca953x_irq_bus_sync_unlock(unsigned int irq)
+static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
{
- struct pca953x_chip *chip = get_irq_chip_data(irq);
+ struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
uint16_t new_irqs;
uint16_t level;
@@ -268,15 +282,15 @@ static void pca953x_irq_bus_sync_unlock(unsigned int irq)
mutex_unlock(&chip->irq_lock);
}
-static int pca953x_irq_set_type(unsigned int irq, unsigned int type)
+static int pca953x_irq_set_type(struct irq_data *d, unsigned int type)
{
- struct pca953x_chip *chip = get_irq_chip_data(irq);
- uint16_t level = irq - chip->irq_base;
+ struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
+ uint16_t level = d->irq - chip->irq_base;
uint16_t mask = 1 << level;
if (!(type & IRQ_TYPE_EDGE_BOTH)) {
dev_err(&chip->client->dev, "irq %d: unsupported type %d\n",
- irq, type);
+ d->irq, type);
return -EINVAL;
}
@@ -295,11 +309,11 @@ static int pca953x_irq_set_type(unsigned int irq, unsigned int type)
static struct irq_chip pca953x_irq_chip = {
.name = "pca953x",
- .mask = pca953x_irq_mask,
- .unmask = pca953x_irq_unmask,
- .bus_lock = pca953x_irq_bus_lock,
- .bus_sync_unlock = pca953x_irq_bus_sync_unlock,
- .set_type = pca953x_irq_set_type,
+ .irq_mask = pca953x_irq_mask,
+ .irq_unmask = pca953x_irq_unmask,
+ .irq_bus_lock = pca953x_irq_bus_lock,
+ .irq_bus_sync_unlock = pca953x_irq_bus_sync_unlock,
+ .irq_set_type = pca953x_irq_set_type,
};
static uint16_t pca953x_irq_pending(struct pca953x_chip *chip)
@@ -517,6 +531,8 @@ static int __devinit pca953x_probe(struct i2c_client *client,
chip->names = pdata->names;
+ mutex_init(&chip->i2c_lock);
+
/* initialize cached registers from their original values.
* we can't share this chip with another i2c master.
*/
diff --git a/drivers/gpio/pl061.c b/drivers/gpio/pl061.c
index 5005990f751f..2975d22daffe 100644
--- a/drivers/gpio/pl061.c
+++ b/drivers/gpio/pl061.c
@@ -129,10 +129,10 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
/*
* PL061 GPIO IRQ
*/
-static void pl061_irq_disable(unsigned irq)
+static void pl061_irq_disable(struct irq_data *d)
{
- struct pl061_gpio *chip = get_irq_chip_data(irq);
- int offset = irq - chip->irq_base;
+ struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - chip->irq_base;
unsigned long flags;
u8 gpioie;
@@ -143,10 +143,10 @@ static void pl061_irq_disable(unsigned irq)
spin_unlock_irqrestore(&chip->irq_lock, flags);
}
-static void pl061_irq_enable(unsigned irq)
+static void pl061_irq_enable(struct irq_data *d)
{
- struct pl061_gpio *chip = get_irq_chip_data(irq);
- int offset = irq - chip->irq_base;
+ struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - chip->irq_base;
unsigned long flags;
u8 gpioie;
@@ -157,10 +157,10 @@ static void pl061_irq_enable(unsigned irq)
spin_unlock_irqrestore(&chip->irq_lock, flags);
}
-static int pl061_irq_type(unsigned irq, unsigned trigger)
+static int pl061_irq_type(struct irq_data *d, unsigned trigger)
{
- struct pl061_gpio *chip = get_irq_chip_data(irq);
- int offset = irq - chip->irq_base;
+ struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - chip->irq_base;
unsigned long flags;
u8 gpiois, gpioibe, gpioiev;
@@ -203,9 +203,9 @@ static int pl061_irq_type(unsigned irq, unsigned trigger)
static struct irq_chip pl061_irqchip = {
.name = "GPIO",
- .enable = pl061_irq_enable,
- .disable = pl061_irq_disable,
- .set_type = pl061_irq_type,
+ .irq_enable = pl061_irq_enable,
+ .irq_disable = pl061_irq_disable,
+ .irq_set_type = pl061_irq_type,
};
static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
@@ -214,7 +214,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
struct list_head *ptr;
struct pl061_gpio *chip;
- desc->chip->ack(irq);
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
list_for_each(ptr, chip_list) {
unsigned long pending;
int offset;
@@ -229,7 +229,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
for_each_set_bit(offset, &pending, PL061_GPIO_NR)
generic_handle_irq(pl061_to_irq(&chip->gc, offset));
}
- desc->chip->unmask(irq);
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
}
static int pl061_probe(struct amba_device *dev, struct amba_id *id)
diff --git a/drivers/gpio/stmpe-gpio.c b/drivers/gpio/stmpe-gpio.c
index 7c9e6a052c45..eb2901f8ab5e 100644
--- a/drivers/gpio/stmpe-gpio.c
+++ b/drivers/gpio/stmpe-gpio.c
@@ -122,10 +122,10 @@ static struct gpio_chip template_chip = {
.can_sleep = 1,
};
-static int stmpe_gpio_irq_set_type(unsigned int irq, unsigned int type)
+static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
- struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq);
- int offset = irq - stmpe_gpio->irq_base;
+ struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - stmpe_gpio->irq_base;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
@@ -145,16 +145,16 @@ static int stmpe_gpio_irq_set_type(unsigned int irq, unsigned int type)
return 0;
}
-static void stmpe_gpio_irq_lock(unsigned int irq)
+static void stmpe_gpio_irq_lock(struct irq_data *d)
{
- struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq);
+ struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
mutex_lock(&stmpe_gpio->irq_lock);
}
-static void stmpe_gpio_irq_sync_unlock(unsigned int irq)
+static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)
{
- struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq);
+ struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
struct stmpe *stmpe = stmpe_gpio->stmpe;
int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8);
static const u8 regmap[] = {
@@ -180,20 +180,20 @@ static void stmpe_gpio_irq_sync_unlock(unsigned int irq)
mutex_unlock(&stmpe_gpio->irq_lock);
}
-static void stmpe_gpio_irq_mask(unsigned int irq)
+static void stmpe_gpio_irq_mask(struct irq_data *d)
{
- struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq);
- int offset = irq - stmpe_gpio->irq_base;
+ struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - stmpe_gpio->irq_base;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
stmpe_gpio->regs[REG_IE][regoffset] &= ~mask;
}
-static void stmpe_gpio_irq_unmask(unsigned int irq)
+static void stmpe_gpio_irq_unmask(struct irq_data *d)
{
- struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq);
- int offset = irq - stmpe_gpio->irq_base;
+ struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - stmpe_gpio->irq_base;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
@@ -202,11 +202,11 @@ static void stmpe_gpio_irq_unmask(unsigned int irq)
static struct irq_chip stmpe_gpio_irq_chip = {
.name = "stmpe-gpio",
- .bus_lock = stmpe_gpio_irq_lock,
- .bus_sync_unlock = stmpe_gpio_irq_sync_unlock,
- .mask = stmpe_gpio_irq_mask,
- .unmask = stmpe_gpio_irq_unmask,
- .set_type = stmpe_gpio_irq_set_type,
+ .irq_bus_lock = stmpe_gpio_irq_lock,
+ .irq_bus_sync_unlock = stmpe_gpio_irq_sync_unlock,
+ .irq_mask = stmpe_gpio_irq_mask,
+ .irq_unmask = stmpe_gpio_irq_unmask,
+ .irq_set_type = stmpe_gpio_irq_set_type,
};
static irqreturn_t stmpe_gpio_irq(int irq, void *dev)
diff --git a/drivers/gpio/sx150x.c b/drivers/gpio/sx150x.c
index 823559ab0e24..e60be0015c9b 100644
--- a/drivers/gpio/sx150x.c
+++ b/drivers/gpio/sx150x.c
@@ -304,36 +304,36 @@ static int sx150x_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
return chip->irq_base + offset;
}
-static void sx150x_irq_mask(unsigned int irq)
+static void sx150x_irq_mask(struct irq_data *d)
{
- struct irq_chip *ic = get_irq_chip(irq);
+ struct irq_chip *ic = irq_data_get_irq_chip(d);
struct sx150x_chip *chip;
unsigned n;
chip = container_of(ic, struct sx150x_chip, irq_chip);
- n = irq - chip->irq_base;
+ n = d->irq - chip->irq_base;
sx150x_write_cfg(chip, n, 1, chip->dev_cfg->reg_irq_mask, 1);
sx150x_write_cfg(chip, n, 2, chip->dev_cfg->reg_sense, 0);
}
-static void sx150x_irq_unmask(unsigned int irq)
+static void sx150x_irq_unmask(struct irq_data *d)
{
- struct irq_chip *ic = get_irq_chip(irq);
+ struct irq_chip *ic = irq_data_get_irq_chip(d);
struct sx150x_chip *chip;
unsigned n;
chip = container_of(ic, struct sx150x_chip, irq_chip);
- n = irq - chip->irq_base;
+ n = d->irq - chip->irq_base;
sx150x_write_cfg(chip, n, 1, chip->dev_cfg->reg_irq_mask, 0);
sx150x_write_cfg(chip, n, 2, chip->dev_cfg->reg_sense,
chip->irq_sense >> (n * 2));
}
-static int sx150x_irq_set_type(unsigned int irq, unsigned int flow_type)
+static int sx150x_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
- struct irq_chip *ic = get_irq_chip(irq);
+ struct irq_chip *ic = irq_data_get_irq_chip(d);
struct sx150x_chip *chip;
unsigned n, val = 0;
@@ -341,7 +341,7 @@ static int sx150x_irq_set_type(unsigned int irq, unsigned int flow_type)
return -EINVAL;
chip = container_of(ic, struct sx150x_chip, irq_chip);
- n = irq - chip->irq_base;
+ n = d->irq - chip->irq_base;
if (flow_type & IRQ_TYPE_EDGE_RISING)
val |= 0x1;
@@ -386,9 +386,9 @@ static irqreturn_t sx150x_irq_thread_fn(int irq, void *dev_id)
return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
}
-static void sx150x_irq_bus_lock(unsigned int irq)
+static void sx150x_irq_bus_lock(struct irq_data *d)
{
- struct irq_chip *ic = get_irq_chip(irq);
+ struct irq_chip *ic = irq_data_get_irq_chip(d);
struct sx150x_chip *chip;
chip = container_of(ic, struct sx150x_chip, irq_chip);
@@ -396,9 +396,9 @@ static void sx150x_irq_bus_lock(unsigned int irq)
mutex_lock(&chip->lock);
}
-static void sx150x_irq_bus_sync_unlock(unsigned int irq)
+static void sx150x_irq_bus_sync_unlock(struct irq_data *d)
{
- struct irq_chip *ic = get_irq_chip(irq);
+ struct irq_chip *ic = irq_data_get_irq_chip(d);
struct sx150x_chip *chip;
unsigned n;
@@ -437,16 +437,16 @@ static void sx150x_init_chip(struct sx150x_chip *chip,
if (pdata->oscio_is_gpo)
++chip->gpio_chip.ngpio;
- chip->irq_chip.name = client->name;
- chip->irq_chip.mask = sx150x_irq_mask;
- chip->irq_chip.unmask = sx150x_irq_unmask;
- chip->irq_chip.set_type = sx150x_irq_set_type;
- chip->irq_chip.bus_lock = sx150x_irq_bus_lock;
- chip->irq_chip.bus_sync_unlock = sx150x_irq_bus_sync_unlock;
- chip->irq_summary = -1;
- chip->irq_base = -1;
- chip->irq_sense = 0;
- chip->irq_set_type_pending = 0;
+ chip->irq_chip.name = client->name;
+ chip->irq_chip.irq_mask = sx150x_irq_mask;
+ chip->irq_chip.irq_unmask = sx150x_irq_unmask;
+ chip->irq_chip.irq_set_type = sx150x_irq_set_type;
+ chip->irq_chip.irq_bus_lock = sx150x_irq_bus_lock;
+ chip->irq_chip.irq_bus_sync_unlock = sx150x_irq_bus_sync_unlock;
+ chip->irq_summary = -1;
+ chip->irq_base = -1;
+ chip->irq_sense = 0;
+ chip->irq_set_type_pending = 0;
}
static int sx150x_init_io(struct sx150x_chip *chip, u8 base, u16 cfg)
diff --git a/drivers/gpio/tc3589x-gpio.c b/drivers/gpio/tc3589x-gpio.c
index 180d584454fb..27200af1a595 100644
--- a/drivers/gpio/tc3589x-gpio.c
+++ b/drivers/gpio/tc3589x-gpio.c
@@ -110,10 +110,10 @@ static struct gpio_chip template_chip = {
.can_sleep = 1,
};
-static int tc3589x_gpio_irq_set_type(unsigned int irq, unsigned int type)
+static int tc3589x_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
- struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq);
- int offset = irq - tc3589x_gpio->irq_base;
+ struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - tc3589x_gpio->irq_base;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
@@ -137,16 +137,16 @@ static int tc3589x_gpio_irq_set_type(unsigned int irq, unsigned int type)
return 0;
}
-static void tc3589x_gpio_irq_lock(unsigned int irq)
+static void tc3589x_gpio_irq_lock(struct irq_data *d)
{
- struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq);
+ struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d);
mutex_lock(&tc3589x_gpio->irq_lock);
}
-static void tc3589x_gpio_irq_sync_unlock(unsigned int irq)
+static void tc3589x_gpio_irq_sync_unlock(struct irq_data *d)
{
- struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq);
+ struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d);
struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
static const u8 regmap[] = {
[REG_IBE] = TC3589x_GPIOIBE0,
@@ -172,20 +172,20 @@ static void tc3589x_gpio_irq_sync_unlock(unsigned int irq)
mutex_unlock(&tc3589x_gpio->irq_lock);
}
-static void tc3589x_gpio_irq_mask(unsigned int irq)
+static void tc3589x_gpio_irq_mask(struct irq_data *d)
{
- struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq);
- int offset = irq - tc3589x_gpio->irq_base;
+ struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - tc3589x_gpio->irq_base;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
tc3589x_gpio->regs[REG_IE][regoffset] &= ~mask;
}
-static void tc3589x_gpio_irq_unmask(unsigned int irq)
+static void tc3589x_gpio_irq_unmask(struct irq_data *d)
{
- struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq);
- int offset = irq - tc3589x_gpio->irq_base;
+ struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - tc3589x_gpio->irq_base;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
@@ -194,11 +194,11 @@ static void tc3589x_gpio_irq_unmask(unsigned int irq)
static struct irq_chip tc3589x_gpio_irq_chip = {
.name = "tc3589x-gpio",
- .bus_lock = tc3589x_gpio_irq_lock,
- .bus_sync_unlock = tc3589x_gpio_irq_sync_unlock,
- .mask = tc3589x_gpio_irq_mask,
- .unmask = tc3589x_gpio_irq_unmask,
- .set_type = tc3589x_gpio_irq_set_type,
+ .irq_bus_lock = tc3589x_gpio_irq_lock,
+ .irq_bus_sync_unlock = tc3589x_gpio_irq_sync_unlock,
+ .irq_mask = tc3589x_gpio_irq_mask,
+ .irq_unmask = tc3589x_gpio_irq_unmask,
+ .irq_set_type = tc3589x_gpio_irq_set_type,
};
static irqreturn_t tc3589x_gpio_irq(int irq, void *dev)
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c
index 45293662e950..58c8f30352dd 100644
--- a/drivers/gpio/timbgpio.c
+++ b/drivers/gpio/timbgpio.c
@@ -109,10 +109,10 @@ static int timbgpio_to_irq(struct gpio_chip *gpio, unsigned offset)
/*
* GPIO IRQ
*/
-static void timbgpio_irq_disable(unsigned irq)
+static void timbgpio_irq_disable(struct irq_data *d)
{
- struct timbgpio *tgpio = get_irq_chip_data(irq);
- int offset = irq - tgpio->irq_base;
+ struct timbgpio *tgpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - tgpio->irq_base;
unsigned long flags;
spin_lock_irqsave(&tgpio->lock, flags);
@@ -121,10 +121,10 @@ static void timbgpio_irq_disable(unsigned irq)
spin_unlock_irqrestore(&tgpio->lock, flags);
}
-static void timbgpio_irq_enable(unsigned irq)
+static void timbgpio_irq_enable(struct irq_data *d)
{
- struct timbgpio *tgpio = get_irq_chip_data(irq);
- int offset = irq - tgpio->irq_base;
+ struct timbgpio *tgpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - tgpio->irq_base;
unsigned long flags;
spin_lock_irqsave(&tgpio->lock, flags);
@@ -133,10 +133,10 @@ static void timbgpio_irq_enable(unsigned irq)
spin_unlock_irqrestore(&tgpio->lock, flags);
}
-static int timbgpio_irq_type(unsigned irq, unsigned trigger)
+static int timbgpio_irq_type(struct irq_data *d, unsigned trigger)
{
- struct timbgpio *tgpio = get_irq_chip_data(irq);
- int offset = irq - tgpio->irq_base;
+ struct timbgpio *tgpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - tgpio->irq_base;
unsigned long flags;
u32 lvr, flr, bflr = 0;
u32 ver;
@@ -199,7 +199,7 @@ static void timbgpio_irq(unsigned int irq, struct irq_desc *desc)
unsigned long ipr;
int offset;
- desc->chip->ack(irq);
+ desc->irq_data.chip->irq_ack(irq_get_irq_data(irq));
ipr = ioread32(tgpio->membase + TGPIO_IPR);
iowrite32(ipr, tgpio->membase + TGPIO_ICR);
@@ -217,9 +217,9 @@ static void timbgpio_irq(unsigned int irq, struct irq_desc *desc)
static struct irq_chip timbgpio_irqchip = {
.name = "GPIO",
- .enable = timbgpio_irq_enable,
- .disable = timbgpio_irq_disable,
- .set_type = timbgpio_irq_type,
+ .irq_enable = timbgpio_irq_enable,
+ .irq_disable = timbgpio_irq_disable,
+ .irq_set_type = timbgpio_irq_type,
};
static int __devinit timbgpio_probe(struct platform_device *pdev)
diff --git a/drivers/gpio/vr41xx_giu.c b/drivers/gpio/vr41xx_giu.c
index b16c9a8c03f5..cffa3bd7ad3b 100644
--- a/drivers/gpio/vr41xx_giu.c
+++ b/drivers/gpio/vr41xx_giu.c
@@ -111,69 +111,69 @@ static inline u16 giu_clear(u16 offset, u16 clear)
return data;
}
-static void ack_giuint_low(unsigned int irq)
+static void ack_giuint_low(struct irq_data *d)
{
- giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq));
+ giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(d->irq));
}
-static void mask_giuint_low(unsigned int irq)
+static void mask_giuint_low(struct irq_data *d)
{
- giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
+ giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(d->irq));
}
-static void mask_ack_giuint_low(unsigned int irq)
+static void mask_ack_giuint_low(struct irq_data *d)
{
unsigned int pin;
- pin = GPIO_PIN_OF_IRQ(irq);
+ pin = GPIO_PIN_OF_IRQ(d->irq);
giu_clear(GIUINTENL, 1 << pin);
giu_write(GIUINTSTATL, 1 << pin);
}
-static void unmask_giuint_low(unsigned int irq)
+static void unmask_giuint_low(struct irq_data *d)
{
- giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
+ giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(d->irq));
}
static struct irq_chip giuint_low_irq_chip = {
.name = "GIUINTL",
- .ack = ack_giuint_low,
- .mask = mask_giuint_low,
- .mask_ack = mask_ack_giuint_low,
- .unmask = unmask_giuint_low,
+ .irq_ack = ack_giuint_low,
+ .irq_mask = mask_giuint_low,
+ .irq_mask_ack = mask_ack_giuint_low,
+ .irq_unmask = unmask_giuint_low,
};
-static void ack_giuint_high(unsigned int irq)
+static void ack_giuint_high(struct irq_data *d)
{
giu_write(GIUINTSTATH,
- 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
+ 1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET));
}
-static void mask_giuint_high(unsigned int irq)
+static void mask_giuint_high(struct irq_data *d)
{
- giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
+ giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET));
}
-static void mask_ack_giuint_high(unsigned int irq)
+static void mask_ack_giuint_high(struct irq_data *d)
{
unsigned int pin;
- pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET;
+ pin = GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET;
giu_clear(GIUINTENH, 1 << pin);
giu_write(GIUINTSTATH, 1 << pin);
}
-static void unmask_giuint_high(unsigned int irq)
+static void unmask_giuint_high(struct irq_data *d)
{
- giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
+ giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET));
}
static struct irq_chip giuint_high_irq_chip = {
.name = "GIUINTH",
- .ack = ack_giuint_high,
- .mask = mask_giuint_high,
- .mask_ack = mask_ack_giuint_high,
- .unmask = unmask_giuint_high,
+ .irq_ack = ack_giuint_high,
+ .irq_mask = mask_giuint_high,
+ .irq_mask_ack = mask_ack_giuint_high,
+ .irq_unmask = unmask_giuint_high,
};
static int giu_get_irq(unsigned int irq)
diff --git a/drivers/gpio/wm8994-gpio.c b/drivers/gpio/wm8994-gpio.c
index 618398e4ed8e..c822baacd8fc 100644
--- a/drivers/gpio/wm8994-gpio.c
+++ b/drivers/gpio/wm8994-gpio.c
@@ -35,6 +35,29 @@ static inline struct wm8994_gpio *to_wm8994_gpio(struct gpio_chip *chip)
return container_of(chip, struct wm8994_gpio, gpio_chip);
}
+static int wm8994_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
+ struct wm8994 *wm8994 = wm8994_gpio->wm8994;
+
+ switch (wm8994->type) {
+ case WM8958:
+ switch (offset) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 6:
+ return -EINVAL;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static int wm8994_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
{
struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
@@ -136,6 +159,7 @@ static void wm8994_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
static struct gpio_chip template_chip = {
.label = "wm8994",
.owner = THIS_MODULE,
+ .request = wm8994_gpio_request,
.direction_input = wm8994_gpio_direction_in,
.get = wm8994_gpio_get,
.direction_output = wm8994_gpio_direction_out,