aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/gpio/sodaville.txt48
-rw-r--r--arch/x86/platform/ce4100/falconfalls.dts7
-rw-r--r--drivers/gpio/Kconfig14
-rw-r--r--drivers/gpio/Makefile2
-rw-r--r--drivers/gpio/gpio-mc9s08dz60.c161
-rw-r--r--drivers/gpio/gpio-pl061.c7
-rw-r--r--drivers/gpio/gpio-sodaville.c302
-rw-r--r--drivers/gpio/gpio-tps65910.c20
-rw-r--r--drivers/gpio/gpiolib.c8
-rw-r--r--drivers/of/gpio.c9
-rw-r--r--include/linux/mfd/tps65910.h8
-rw-r--r--include/linux/of_gpio.h27
12 files changed, 599 insertions, 14 deletions
diff --git a/Documentation/devicetree/bindings/gpio/sodaville.txt b/Documentation/devicetree/bindings/gpio/sodaville.txt
new file mode 100644
index 000000000000..563eff22b975
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/sodaville.txt
@@ -0,0 +1,48 @@
1GPIO controller on CE4100 / Sodaville SoCs
2==========================================
3
4The bindings for CE4100's GPIO controller match the generic description
5which is covered by the gpio.txt file in this folder.
6
7The only additional property is the intel,muxctl property which holds the
8value which is written into the MUXCNTL register.
9
10There is no compatible property for now because the driver is probed via
11PCI id (vendor 0x8086 device 0x2e67).
12
13The interrupt specifier consists of two cells encoded as follows:
14 - <1st cell>: The interrupt-number that identifies the interrupt source.
15 - <2nd cell>: The level-sense information, encoded as follows:
16 4 - active high level-sensitive
17 8 - active low level-sensitive
18
19Example of the GPIO device and one user:
20
21 pcigpio: gpio@b,1 {
22 /* two cells for GPIO and interrupt */
23 #gpio-cells = <2>;
24 #interrupt-cells = <2>;
25 compatible = "pci8086,2e67.2",
26 "pci8086,2e67",
27 "pciclassff0000",
28 "pciclassff00";
29
30 reg = <0x15900 0x0 0x0 0x0 0x0>;
31 /* Interrupt line of the gpio device */
32 interrupts = <15 1>;
33 /* It is an interrupt and GPIO controller itself */
34 interrupt-controller;
35 gpio-controller;
36 intel,muxctl = <0>;
37 };
38
39 testuser@20 {
40 compatible = "example,testuser";
41 /* User the 11th GPIO line as an active high triggered
42 * level interrupt
43 */
44 interrupts = <11 8>;
45 interrupt-parent = <&pcigpio>;
46 /* Use this GPIO also with the gpio functions */
47 gpios = <&pcigpio 11 0>;
48 };
diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
index e70be38ce039..ce874f872cc6 100644
--- a/arch/x86/platform/ce4100/falconfalls.dts
+++ b/arch/x86/platform/ce4100/falconfalls.dts
@@ -208,16 +208,19 @@
208 interrupts = <14 1>; 208 interrupts = <14 1>;
209 }; 209 };
210 210
211 gpio@b,1 { 211 pcigpio: gpio@b,1 {
212 #gpio-cells = <2>;
213 #interrupt-cells = <2>;
212 compatible = "pci8086,2e67.2", 214 compatible = "pci8086,2e67.2",
213 "pci8086,2e67", 215 "pci8086,2e67",
214 "pciclassff0000", 216 "pciclassff0000",
215 "pciclassff00"; 217 "pciclassff00";
216 218
217 #gpio-cells = <2>;
218 reg = <0x15900 0x0 0x0 0x0 0x0>; 219 reg = <0x15900 0x0 0x0 0x0 0x0>;
219 interrupts = <15 1>; 220 interrupts = <15 1>;
221 interrupt-controller;
220 gpio-controller; 222 gpio-controller;
223 intel,muxctl = <0>;
221 }; 224 };
222 225
223 i2c-controller@b,2 { 226 i2c-controller@b,2 {
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index d0c41188d4e5..dbb1909ca0a2 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -225,6 +225,12 @@ config GPIO_MAX732X_IRQ
225 Say yes here to enable the max732x to be used as an interrupt 225 Say yes here to enable the max732x to be used as an interrupt
226 controller. It requires the driver to be built in the kernel. 226 controller. It requires the driver to be built in the kernel.
227 227
228config GPIO_MC9S08DZ60
229 bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions"
230 depends on I2C && MACH_MX35_3DS
231 help
232 Select this to enable the MC9S08DZ60 GPIO driver
233
228config GPIO_PCA953X 234config GPIO_PCA953X
229 tristate "PCA953x, PCA955x, TCA64xx, and MAX7310 I/O ports" 235 tristate "PCA953x, PCA955x, TCA64xx, and MAX7310 I/O ports"
230 depends on I2C 236 depends on I2C
@@ -411,6 +417,14 @@ config GPIO_ML_IOH
411 Hub) which is for IVI(In-Vehicle Infotainment) use. 417 Hub) which is for IVI(In-Vehicle Infotainment) use.
412 This driver can access the IOH's GPIO device. 418 This driver can access the IOH's GPIO device.
413 419
420config GPIO_SODAVILLE
421 bool "Intel Sodaville GPIO support"
422 depends on X86 && PCI && OF
423 select GPIO_GENERIC
424 select GENERIC_IRQ_CHIP
425 help
426 Say Y here to support Intel Sodaville GPIO.
427
414config GPIO_TIMBERDALE 428config GPIO_TIMBERDALE
415 bool "Support for timberdale GPIO IP" 429 bool "Support for timberdale GPIO IP"
416 depends on MFD_TIMBERDALE && HAS_IOMEM 430 depends on MFD_TIMBERDALE && HAS_IOMEM
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index fa10df604c01..593bdcd1976e 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o
26obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o 26obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o
27obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o 27obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o
28obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o 28obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
29obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
29obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o 30obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o
30obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o 31obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o
31obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o 32obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
@@ -45,6 +46,7 @@ obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
45obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o 46obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o
46obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o 47obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
47obj-$(CONFIG_GPIO_SCH) += gpio-sch.o 48obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
49obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o
48obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o 50obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
49obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o 51obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o
50obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o 52obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o
diff --git a/drivers/gpio/gpio-mc9s08dz60.c b/drivers/gpio/gpio-mc9s08dz60.c
new file mode 100644
index 000000000000..2738cc44d636
--- /dev/null
+++ b/drivers/gpio/gpio-mc9s08dz60.c
@@ -0,0 +1,161 @@
1/*
2 * Copyright 2009-2012 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * Author: Wu Guoxing <b39297@freescale.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/slab.h>
20#include <linux/i2c.h>
21#include <linux/gpio.h>
22
23#define GPIO_GROUP_NUM 2
24#define GPIO_NUM_PER_GROUP 8
25#define GPIO_NUM (GPIO_GROUP_NUM*GPIO_NUM_PER_GROUP)
26
27struct mc9s08dz60 {
28 struct i2c_client *client;
29 struct gpio_chip chip;
30};
31
32static inline struct mc9s08dz60 *to_mc9s08dz60(struct gpio_chip *gc)
33{
34 return container_of(gc, struct mc9s08dz60, chip);
35}
36
37
38static void mc9s_gpio_to_reg_and_bit(int offset, u8 *reg, u8 *bit)
39{
40 *reg = 0x20 + offset / GPIO_NUM_PER_GROUP;
41 *bit = offset % GPIO_NUM_PER_GROUP;
42}
43
44static int mc9s08dz60_get_value(struct gpio_chip *gc, unsigned offset)
45{
46 u8 reg, bit;
47 s32 value;
48 struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc);
49
50 mc9s_gpio_to_reg_and_bit(offset, &reg, &bit);
51 value = i2c_smbus_read_byte_data(mc9s->client, reg);
52
53 return (value >= 0) ? (value >> bit) & 0x1 : 0;
54}
55
56static int mc9s08dz60_set(struct mc9s08dz60 *mc9s, unsigned offset, int val)
57{
58 u8 reg, bit;
59 s32 value;
60
61 mc9s_gpio_to_reg_and_bit(offset, &reg, &bit);
62 value = i2c_smbus_read_byte_data(mc9s->client, reg);
63 if (value >= 0) {
64 if (val)
65 value |= 1 << bit;
66 else
67 value &= ~(1 << bit);
68
69 return i2c_smbus_write_byte_data(mc9s->client, reg, value);
70 } else
71 return value;
72
73}
74
75
76static void mc9s08dz60_set_value(struct gpio_chip *gc, unsigned offset, int val)
77{
78 struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc);
79
80 mc9s08dz60_set(mc9s, offset, val);
81}
82
83static int mc9s08dz60_direction_output(struct gpio_chip *gc,
84 unsigned offset, int val)
85{
86 struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc);
87
88 return mc9s08dz60_set(mc9s, offset, val);
89}
90
91static int mc9s08dz60_probe(struct i2c_client *client,
92 const struct i2c_device_id *id)
93{
94 int ret = 0;
95 struct mc9s08dz60 *mc9s;
96
97 mc9s = kzalloc(sizeof(*mc9s), GFP_KERNEL);
98 if (!mc9s)
99 return -ENOMEM;
100
101 mc9s->chip.label = client->name;
102 mc9s->chip.base = -1;
103 mc9s->chip.dev = &client->dev;
104 mc9s->chip.owner = THIS_MODULE;
105 mc9s->chip.ngpio = GPIO_NUM;
106 mc9s->chip.can_sleep = 1;
107 mc9s->chip.get = mc9s08dz60_get_value;
108 mc9s->chip.set = mc9s08dz60_set_value;
109 mc9s->chip.direction_output = mc9s08dz60_direction_output;
110 mc9s->client = client;
111 i2c_set_clientdata(client, mc9s);
112
113 ret = gpiochip_add(&mc9s->chip);
114 if (ret)
115 goto error;
116
117 return 0;
118
119 error:
120 kfree(mc9s);
121 return ret;
122}
123
124static int mc9s08dz60_remove(struct i2c_client *client)
125{
126 struct mc9s08dz60 *mc9s;
127 int ret;
128
129 mc9s = i2c_get_clientdata(client);
130
131 ret = gpiochip_remove(&mc9s->chip);
132 if (!ret)
133 kfree(mc9s);
134
135 return ret;
136
137}
138
139static const struct i2c_device_id mc9s08dz60_id[] = {
140 {"mc9s08dz60", 0},
141 {},
142};
143
144MODULE_DEVICE_TABLE(i2c, mc9s08dz60_id);
145
146static struct i2c_driver mc9s08dz60_i2c_driver = {
147 .driver = {
148 .owner = THIS_MODULE,
149 .name = "mc9s08dz60",
150 },
151 .probe = mc9s08dz60_probe,
152 .remove = mc9s08dz60_remove,
153 .id_table = mc9s08dz60_id,
154};
155
156module_i2c_driver(mc9s08dz60_i2c_driver);
157
158MODULE_AUTHOR("Freescale Semiconductor, Inc. "
159 "Wu Guoxing <b39297@freescale.com>");
160MODULE_DESCRIPTION("mc9s08dz60 gpio function on mx35 3ds board");
161MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index 77c9cc70fa77..b4b5da4fd2cc 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -352,7 +352,12 @@ static int pl061_resume(struct device *dev)
352 return 0; 352 return 0;
353} 353}
354 354
355static SIMPLE_DEV_PM_OPS(pl061_dev_pm_ops, pl061_suspend, pl061_resume); 355static const struct dev_pm_ops pl061_dev_pm_ops = {
356 .suspend = pl061_suspend,
357 .resume = pl061_resume,
358 .freeze = pl061_suspend,
359 .restore = pl061_resume,
360};
356#endif 361#endif
357 362
358static struct amba_id pl061_ids[] = { 363static struct amba_id pl061_ids[] = {
diff --git a/drivers/gpio/gpio-sodaville.c b/drivers/gpio/gpio-sodaville.c
new file mode 100644
index 000000000000..9ba15d31d242
--- /dev/null
+++ b/drivers/gpio/gpio-sodaville.c
@@ -0,0 +1,302 @@
1/*
2 * GPIO interface for Intel Sodaville SoCs.
3 *
4 * Copyright (c) 2010, 2011 Intel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License 2 as published
8 * by the Free Software Foundation.
9 *
10 */
11
12#include <linux/errno.h>
13#include <linux/gpio.h>
14#include <linux/init.h>
15#include <linux/io.h>
16#include <linux/irq.h>
17#include <linux/interrupt.h>
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/pci.h>
21#include <linux/platform_device.h>
22#include <linux/of_irq.h>
23#include <linux/basic_mmio_gpio.h>
24
25#define DRV_NAME "sdv_gpio"
26#define SDV_NUM_PUB_GPIOS 12
27#define PCI_DEVICE_ID_SDV_GPIO 0x2e67
28#define GPIO_BAR 0
29
30#define GPOUTR 0x00
31#define GPOER 0x04
32#define GPINR 0x08
33
34#define GPSTR 0x0c
35#define GPIT1R0 0x10
36#define GPIO_INT 0x14
37#define GPIT1R1 0x18
38
39#define GPMUXCTL 0x1c
40
41struct sdv_gpio_chip_data {
42 int irq_base;
43 void __iomem *gpio_pub_base;
44 struct irq_domain id;
45 struct irq_chip_generic *gc;
46 struct bgpio_chip bgpio;
47};
48
49static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type)
50{
51 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
52 struct sdv_gpio_chip_data *sd = gc->private;
53 void __iomem *type_reg;
54 u32 irq_offs = d->irq - sd->irq_base;
55 u32 reg;
56
57 if (irq_offs < 8)
58 type_reg = sd->gpio_pub_base + GPIT1R0;
59 else
60 type_reg = sd->gpio_pub_base + GPIT1R1;
61
62 reg = readl(type_reg);
63
64 switch (type) {
65 case IRQ_TYPE_LEVEL_HIGH:
66 reg &= ~BIT(4 * (irq_offs % 8));
67 break;
68
69 case IRQ_TYPE_LEVEL_LOW:
70 reg |= BIT(4 * (irq_offs % 8));
71 break;
72
73 default:
74 return -EINVAL;
75 }
76
77 writel(reg, type_reg);
78 return 0;
79}
80
81static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data)
82{
83 struct sdv_gpio_chip_data *sd = data;
84 u32 irq_stat = readl(sd->gpio_pub_base + GPSTR);
85
86 irq_stat &= readl(sd->gpio_pub_base + GPIO_INT);
87 if (!irq_stat)
88 return IRQ_NONE;
89
90 while (irq_stat) {
91 u32 irq_bit = __fls(irq_stat);
92
93 irq_stat &= ~BIT(irq_bit);
94 generic_handle_irq(sd->irq_base + irq_bit);
95 }
96
97 return IRQ_HANDLED;
98}
99
100static int sdv_xlate(struct irq_domain *h, struct device_node *node,
101 const u32 *intspec, u32 intsize, irq_hw_number_t *out_hwirq,
102 u32 *out_type)
103{
104 u32 line, type;
105
106 if (node != h->of_node)
107 return -EINVAL;
108
109 if (intsize < 2)
110 return -EINVAL;
111
112 line = *intspec;
113 *out_hwirq = line;
114
115 intspec++;
116 type = *intspec;
117
118 switch (type) {
119 case IRQ_TYPE_LEVEL_LOW:
120 case IRQ_TYPE_LEVEL_HIGH:
121 *out_type = type;
122 break;
123 default:
124 return -EINVAL;
125 }
126 return 0;
127}
128
129static struct irq_domain_ops irq_domain_sdv_ops = {
130 .dt_translate = sdv_xlate,
131};
132
133static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd,
134 struct pci_dev *pdev)
135{
136 struct irq_chip_type *ct;
137 int ret;
138
139 sd->irq_base = irq_alloc_descs(-1, 0, SDV_NUM_PUB_GPIOS, -1);
140 if (sd->irq_base < 0)
141 return sd->irq_base;
142
143 /* mask + ACK all interrupt sources */
144 writel(0, sd->gpio_pub_base + GPIO_INT);
145 writel((1 << 11) - 1, sd->gpio_pub_base + GPSTR);
146
147 ret = request_irq(pdev->irq, sdv_gpio_pub_irq_handler, IRQF_SHARED,
148 "sdv_gpio", sd);
149 if (ret)
150 goto out_free_desc;
151
152 sd->id.irq_base = sd->irq_base;
153 sd->id.of_node = of_node_get(pdev->dev.of_node);
154 sd->id.ops = &irq_domain_sdv_ops;
155
156 /*
157 * This gpio irq controller latches level irqs. Testing shows that if
158 * we unmask & ACK the IRQ before the source of the interrupt is gone
159 * then the interrupt is active again.
160 */
161 sd->gc = irq_alloc_generic_chip("sdv-gpio", 1, sd->irq_base,
162 sd->gpio_pub_base, handle_fasteoi_irq);
163 if (!sd->gc) {
164 ret = -ENOMEM;
165 goto out_free_irq;
166 }
167
168 sd->gc->private = sd;
169 ct = sd->gc->chip_types;
170 ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW;
171 ct->regs.eoi = GPSTR;
172 ct->regs.mask = GPIO_INT;
173 ct->chip.irq_mask = irq_gc_mask_clr_bit;
174 ct->chip.irq_unmask = irq_gc_mask_set_bit;
175 ct->chip.irq_eoi = irq_gc_eoi;
176 ct->chip.irq_set_type = sdv_gpio_pub_set_type;
177
178 irq_setup_generic_chip(sd->gc, IRQ_MSK(SDV_NUM_PUB_GPIOS),
179 IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST,
180 IRQ_LEVEL | IRQ_NOPROBE);
181
182 irq_domain_add(&sd->id);
183 return 0;
184out_free_irq:
185 free_irq(pdev->irq, sd);
186out_free_desc:
187 irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS);
188 return ret;
189}
190
191static int __devinit sdv_gpio_probe(struct pci_dev *pdev,
192 const struct pci_device_id *pci_id)
193{
194 struct sdv_gpio_chip_data *sd;
195 unsigned long addr;
196 const void *prop;
197 int len;
198 int ret;
199 u32 mux_val;
200
201 sd = kzalloc(sizeof(struct sdv_gpio_chip_data), GFP_KERNEL);
202 if (!sd)
203 return -ENOMEM;
204 ret = pci_enable_device(pdev);
205 if (ret) {
206 dev_err(&pdev->dev, "can't enable device.\n");
207 goto done;
208 }
209
210 ret = pci_request_region(pdev, GPIO_BAR, DRV_NAME);
211 if (ret) {
212 dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR);
213 goto disable_pci;
214 }
215
216 addr = pci_resource_start(pdev, GPIO_BAR);
217 if (!addr)
218 goto release_reg;
219 sd->gpio_pub_base = ioremap(addr, pci_resource_len(pdev, GPIO_BAR));
220
221 prop = of_get_property(pdev->dev.of_node, "intel,muxctl", &len);
222 if (prop && len == 4) {
223 mux_val = of_read_number(prop, 1);
224 writel(mux_val, sd->gpio_pub_base + GPMUXCTL);
225 }
226
227 ret = bgpio_init(&sd->bgpio, &pdev->dev, 4,
228 sd->gpio_pub_base + GPINR, sd->gpio_pub_base + GPOUTR,
229 NULL, sd->gpio_pub_base + GPOER, NULL, false);
230 if (ret)
231 goto unmap;
232 sd->bgpio.gc.ngpio = SDV_NUM_PUB_GPIOS;
233
234 ret = gpiochip_add(&sd->bgpio.gc);
235 if (ret < 0) {
236 dev_err(&pdev->dev, "gpiochip_add() failed.\n");
237 goto unmap;
238 }
239
240 ret = sdv_register_irqsupport(sd, pdev);
241 if (ret)
242 goto unmap;
243
244 pci_set_drvdata(pdev, sd);
245 dev_info(&pdev->dev, "Sodaville GPIO driver registered.\n");
246 return 0;
247
248unmap:
249 iounmap(sd->gpio_pub_base);
250release_reg:
251 pci_release_region(pdev, GPIO_BAR);
252disable_pci:
253 pci_disable_device(pdev);
254done:
255 kfree(sd);
256 return ret;
257}
258
259static void sdv_gpio_remove(struct pci_dev *pdev)
260{
261 struct sdv_gpio_chip_data *sd = pci_get_drvdata(pdev);
262
263 irq_domain_del(&sd->id);
264 free_irq(pdev->irq, sd);
265 irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS);
266
267 if (gpiochip_remove(&sd->bgpio.gc))
268 dev_err(&pdev->dev, "gpiochip_remove() failed.\n");
269
270 pci_release_region(pdev, GPIO_BAR);
271 iounmap(sd->gpio_pub_base);
272 pci_disable_device(pdev);
273 kfree(sd);
274}
275
276static struct pci_device_id sdv_gpio_pci_ids[] __devinitdata = {
277 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_SDV_GPIO) },
278 { 0, },
279};
280
281static struct pci_driver sdv_gpio_driver = {
282 .name = DRV_NAME,
283 .id_table = sdv_gpio_pci_ids,
284 .probe = sdv_gpio_probe,
285 .remove = sdv_gpio_remove,
286};
287
288static int __init sdv_gpio_init(void)
289{
290 return pci_register_driver(&sdv_gpio_driver);
291}
292module_init(sdv_gpio_init);
293
294static void __exit sdv_gpio_exit(void)
295{
296 pci_unregister_driver(&sdv_gpio_driver);
297}
298module_exit(sdv_gpio_exit);
299
300MODULE_AUTHOR("Hans J. Koch <hjk@linutronix.de>");
301MODULE_DESCRIPTION("GPIO interface for Intel Sodaville SoCs");
302MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c
index 91f45b965d1e..7eef648a3351 100644
--- a/drivers/gpio/gpio-tps65910.c
+++ b/drivers/gpio/gpio-tps65910.c
@@ -69,6 +69,7 @@ static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset)
69void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base) 69void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base)
70{ 70{
71 int ret; 71 int ret;
72 struct tps65910_board *board_data;
72 73
73 if (!gpio_base) 74 if (!gpio_base)
74 return; 75 return;
@@ -80,10 +81,10 @@ void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base)
80 81
81 switch(tps65910_chip_id(tps65910)) { 82 switch(tps65910_chip_id(tps65910)) {
82 case TPS65910: 83 case TPS65910:
83 tps65910->gpio.ngpio = 6; 84 tps65910->gpio.ngpio = TPS65910_NUM_GPIO;
84 break; 85 break;
85 case TPS65911: 86 case TPS65911:
86 tps65910->gpio.ngpio = 9; 87 tps65910->gpio.ngpio = TPS65911_NUM_GPIO;
87 break; 88 break;
88 default: 89 default:
89 return; 90 return;
@@ -95,6 +96,21 @@ void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base)
95 tps65910->gpio.set = tps65910_gpio_set; 96 tps65910->gpio.set = tps65910_gpio_set;
96 tps65910->gpio.get = tps65910_gpio_get; 97 tps65910->gpio.get = tps65910_gpio_get;
97 98
99 /* Configure sleep control for gpios */
100 board_data = dev_get_platdata(tps65910->dev);
101 if (board_data) {
102 int i;
103 for (i = 0; i < tps65910->gpio.ngpio; ++i) {
104 if (board_data->en_gpio_sleep[i]) {
105 ret = tps65910_set_bits(tps65910,
106 TPS65910_GPIO0 + i, GPIO_SLEEP_MASK);
107 if (ret < 0)
108 dev_warn(tps65910->dev,
109 "GPIO Sleep setting failed\n");
110 }
111 }
112 }
113
98 ret = gpiochip_add(&tps65910->gpio); 114 ret = gpiochip_add(&tps65910->gpio);
99 115
100 if (ret) 116 if (ret)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 17fdf4b6af93..d77354068b90 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -873,6 +873,7 @@ void gpio_unexport(unsigned gpio)
873{ 873{
874 struct gpio_desc *desc; 874 struct gpio_desc *desc;
875 int status = 0; 875 int status = 0;
876 struct device *dev = NULL;
876 877
877 if (!gpio_is_valid(gpio)) { 878 if (!gpio_is_valid(gpio)) {
878 status = -EINVAL; 879 status = -EINVAL;
@@ -884,19 +885,20 @@ void gpio_unexport(unsigned gpio)
884 desc = &gpio_desc[gpio]; 885 desc = &gpio_desc[gpio];
885 886
886 if (test_bit(FLAG_EXPORT, &desc->flags)) { 887 if (test_bit(FLAG_EXPORT, &desc->flags)) {
887 struct device *dev = NULL;
888 888
889 dev = class_find_device(&gpio_class, NULL, desc, match_export); 889 dev = class_find_device(&gpio_class, NULL, desc, match_export);
890 if (dev) { 890 if (dev) {
891 gpio_setup_irq(desc, dev, 0); 891 gpio_setup_irq(desc, dev, 0);
892 clear_bit(FLAG_EXPORT, &desc->flags); 892 clear_bit(FLAG_EXPORT, &desc->flags);
893 put_device(dev);
894 device_unregister(dev);
895 } else 893 } else
896 status = -ENODEV; 894 status = -ENODEV;
897 } 895 }
898 896
899 mutex_unlock(&sysfs_lock); 897 mutex_unlock(&sysfs_lock);
898 if (dev) {
899 device_unregister(dev);
900 put_device(dev);
901 }
900done: 902done:
901 if (status) 903 if (status)
902 pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); 904 pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
index 7e62d15d60f6..e034b38590a8 100644
--- a/drivers/of/gpio.c
+++ b/drivers/of/gpio.c
@@ -78,8 +78,9 @@ err0:
78EXPORT_SYMBOL(of_get_named_gpio_flags); 78EXPORT_SYMBOL(of_get_named_gpio_flags);
79 79
80/** 80/**
81 * of_gpio_count - Count GPIOs for a device 81 * of_gpio_named_count - Count GPIOs for a device
82 * @np: device node to count GPIOs for 82 * @np: device node to count GPIOs for
83 * @propname: property name containing gpio specifier(s)
83 * 84 *
84 * The function returns the count of GPIOs specified for a node. 85 * The function returns the count of GPIOs specified for a node.
85 * 86 *
@@ -93,14 +94,14 @@ EXPORT_SYMBOL(of_get_named_gpio_flags);
93 * defines four GPIOs (so this function will return 4), two of which 94 * defines four GPIOs (so this function will return 4), two of which
94 * are not specified. 95 * are not specified.
95 */ 96 */
96unsigned int of_gpio_count(struct device_node *np) 97unsigned int of_gpio_named_count(struct device_node *np, const char* propname)
97{ 98{
98 unsigned int cnt = 0; 99 unsigned int cnt = 0;
99 100
100 do { 101 do {
101 int ret; 102 int ret;
102 103
103 ret = of_parse_phandle_with_args(np, "gpios", "#gpio-cells", 104 ret = of_parse_phandle_with_args(np, propname, "#gpio-cells",
104 cnt, NULL); 105 cnt, NULL);
105 /* A hole in the gpios = <> counts anyway. */ 106 /* A hole in the gpios = <> counts anyway. */
106 if (ret < 0 && ret != -EEXIST) 107 if (ret < 0 && ret != -EEXIST)
@@ -109,7 +110,7 @@ unsigned int of_gpio_count(struct device_node *np)
109 110
110 return cnt; 111 return cnt;
111} 112}
112EXPORT_SYMBOL(of_gpio_count); 113EXPORT_SYMBOL(of_gpio_named_count);
113 114
114/** 115/**
115 * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags 116 * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags
diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h
index d0cb12eba402..9071902bd222 100644
--- a/include/linux/mfd/tps65910.h
+++ b/include/linux/mfd/tps65910.h
@@ -657,6 +657,8 @@
657 657
658 658
659/*Register GPIO (0x80) register.RegisterDescription */ 659/*Register GPIO (0x80) register.RegisterDescription */
660#define GPIO_SLEEP_MASK 0x80
661#define GPIO_SLEEP_SHIFT 7
660#define GPIO_DEB_MASK 0x10 662#define GPIO_DEB_MASK 0x10
661#define GPIO_DEB_SHIFT 4 663#define GPIO_DEB_SHIFT 4
662#define GPIO_PUEN_MASK 0x08 664#define GPIO_PUEN_MASK 0x08
@@ -740,6 +742,11 @@
740#define TPS65910_GPIO_STS BIT(1) 742#define TPS65910_GPIO_STS BIT(1)
741#define TPS65910_GPIO_SET BIT(0) 743#define TPS65910_GPIO_SET BIT(0)
742 744
745/* Max number of TPS65910/11 GPIOs */
746#define TPS65910_NUM_GPIO 6
747#define TPS65911_NUM_GPIO 9
748#define TPS6591X_MAX_NUM_GPIO 9
749
743/* Regulator Index Definitions */ 750/* Regulator Index Definitions */
744#define TPS65910_REG_VRTC 0 751#define TPS65910_REG_VRTC 0
745#define TPS65910_REG_VIO 1 752#define TPS65910_REG_VIO 1
@@ -779,6 +786,7 @@ struct tps65910_board {
779 int irq_base; 786 int irq_base;
780 int vmbch_threshold; 787 int vmbch_threshold;
781 int vmbch2_threshold; 788 int vmbch2_threshold;
789 bool en_gpio_sleep[TPS6591X_MAX_NUM_GPIO];
782 struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS]; 790 struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS];
783}; 791};
784 792
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
index b254052a49d7..81733d12cbea 100644
--- a/include/linux/of_gpio.h
+++ b/include/linux/of_gpio.h
@@ -50,7 +50,8 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc)
50extern int of_get_named_gpio_flags(struct device_node *np, 50extern int of_get_named_gpio_flags(struct device_node *np,
51 const char *list_name, int index, enum of_gpio_flags *flags); 51 const char *list_name, int index, enum of_gpio_flags *flags);
52 52
53extern unsigned int of_gpio_count(struct device_node *np); 53extern unsigned int of_gpio_named_count(struct device_node *np,
54 const char* propname);
54 55
55extern int of_mm_gpiochip_add(struct device_node *np, 56extern int of_mm_gpiochip_add(struct device_node *np,
56 struct of_mm_gpio_chip *mm_gc); 57 struct of_mm_gpio_chip *mm_gc);
@@ -71,7 +72,8 @@ static inline int of_get_named_gpio_flags(struct device_node *np,
71 return -ENOSYS; 72 return -ENOSYS;
72} 73}
73 74
74static inline unsigned int of_gpio_count(struct device_node *np) 75static inline unsigned int of_gpio_named_count(struct device_node *np,
76 const char* propname)
75{ 77{
76 return 0; 78 return 0;
77} 79}
@@ -89,6 +91,27 @@ static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
89#endif /* CONFIG_OF_GPIO */ 91#endif /* CONFIG_OF_GPIO */
90 92
91/** 93/**
94 * of_gpio_count - Count GPIOs for a device
95 * @np: device node to count GPIOs for
96 *
97 * The function returns the count of GPIOs specified for a node.
98 *
99 * Note that the empty GPIO specifiers counts too. For example,
100 *
101 * gpios = <0
102 * &pio1 1 2
103 * 0
104 * &pio2 3 4>;
105 *
106 * defines four GPIOs (so this function will return 4), two of which
107 * are not specified.
108 */
109static inline unsigned int of_gpio_count(struct device_node *np)
110{
111 return of_gpio_named_count(np, "gpios");
112}
113
114/**
92 * of_get_gpio_flags() - Get a GPIO number and flags to use with GPIO API 115 * of_get_gpio_flags() - Get a GPIO number and flags to use with GPIO API
93 * @np: device node to get GPIO from 116 * @np: device node to get GPIO from
94 * @index: index of the GPIO 117 * @index: index of the GPIO