aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/Kconfig35
-rw-r--r--drivers/gpio/Makefile4
-rw-r--r--drivers/gpio/adp5520-gpio.c206
-rw-r--r--drivers/gpio/bt8xxgpio.c7
-rw-r--r--drivers/gpio/gpiolib.c253
-rw-r--r--drivers/gpio/langwell_gpio.c297
-rw-r--r--drivers/gpio/max7301.c1
-rw-r--r--drivers/gpio/mc33880.c196
-rw-r--r--drivers/gpio/mcp23s08.c5
-rw-r--r--drivers/gpio/pca953x.c4
-rw-r--r--drivers/gpio/pcf857x.c4
-rw-r--r--drivers/gpio/ucb1400_gpio.c125
12 files changed, 1121 insertions, 16 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 6b4c484a699a..2ad0128c63c6 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -162,6 +162,16 @@ config GPIO_WM831X
162 Say yes here to access the GPIO signals of WM831x power management 162 Say yes here to access the GPIO signals of WM831x power management
163 chips from Wolfson Microelectronics. 163 chips from Wolfson Microelectronics.
164 164
165config GPIO_ADP5520
166 tristate "GPIO Support for ADP5520 PMIC"
167 depends on PMIC_ADP5520
168 help
169 This option enables support for on-chip GPIO found
170 on Analog Devices ADP5520 PMICs.
171
172 To compile this driver as a module, choose M here: the module will
173 be called adp5520-gpio.
174
165comment "PCI GPIO expanders:" 175comment "PCI GPIO expanders:"
166 176
167config GPIO_BT8XX 177config GPIO_BT8XX
@@ -180,6 +190,12 @@ config GPIO_BT8XX
180 190
181 If unsure, say N. 191 If unsure, say N.
182 192
193config GPIO_LANGWELL
194 bool "Intel Moorestown Platform Langwell GPIO support"
195 depends on PCI
196 help
197 Say Y here to support Intel Moorestown platform GPIO.
198
183comment "SPI GPIO expanders:" 199comment "SPI GPIO expanders:"
184 200
185config GPIO_MAX7301 201config GPIO_MAX7301
@@ -195,4 +211,23 @@ config GPIO_MCP23S08
195 SPI driver for Microchip MCP23S08 I/O expander. This provides 211 SPI driver for Microchip MCP23S08 I/O expander. This provides
196 a GPIO interface supporting inputs and outputs. 212 a GPIO interface supporting inputs and outputs.
197 213
214config GPIO_MC33880
215 tristate "Freescale MC33880 high-side/low-side switch"
216 depends on SPI_MASTER
217 help
218 SPI driver for Freescale MC33880 high-side/low-side switch.
219 This provides GPIO interface supporting inputs and outputs.
220
221comment "AC97 GPIO expanders:"
222
223config GPIO_UCB1400
224 bool "Philips UCB1400 GPIO"
225 depends on UCB1400_CORE
226 help
227 This enables support for the Philips UCB1400 GPIO pins.
228 The UCB1400 is an AC97 audio codec.
229
230 To compile this driver as a module, choose M here: the
231 module will be called ucb1400_gpio.
232
198endif 233endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index ea7c745f26a8..00a532c9a1e2 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -4,13 +4,17 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
4 4
5obj-$(CONFIG_GPIOLIB) += gpiolib.o 5obj-$(CONFIG_GPIOLIB) += gpiolib.o
6 6
7obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o
8obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o
7obj-$(CONFIG_GPIO_MAX7301) += max7301.o 9obj-$(CONFIG_GPIO_MAX7301) += max7301.o
8obj-$(CONFIG_GPIO_MAX732X) += max732x.o 10obj-$(CONFIG_GPIO_MAX732X) += max732x.o
11obj-$(CONFIG_GPIO_MC33880) += mc33880.o
9obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o 12obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o
10obj-$(CONFIG_GPIO_PCA953X) += pca953x.o 13obj-$(CONFIG_GPIO_PCA953X) += pca953x.o
11obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o 14obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o
12obj-$(CONFIG_GPIO_PL061) += pl061.o 15obj-$(CONFIG_GPIO_PL061) += pl061.o
13obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o 16obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o
17obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o
14obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o 18obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o
15obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o 19obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o
16obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o 20obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
diff --git a/drivers/gpio/adp5520-gpio.c b/drivers/gpio/adp5520-gpio.c
new file mode 100644
index 000000000000..ad05bbc7ffd5
--- /dev/null
+++ b/drivers/gpio/adp5520-gpio.c
@@ -0,0 +1,206 @@
1/*
2 * GPIO driver for Analog Devices ADP5520 MFD PMICs
3 *
4 * Copyright 2009 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/module.h>
10#include <linux/kernel.h>
11#include <linux/init.h>
12#include <linux/platform_device.h>
13#include <linux/mfd/adp5520.h>
14
15#include <linux/gpio.h>
16
17struct adp5520_gpio {
18 struct device *master;
19 struct gpio_chip gpio_chip;
20 unsigned char lut[ADP5520_MAXGPIOS];
21 unsigned long output;
22};
23
24static int adp5520_gpio_get_value(struct gpio_chip *chip, unsigned off)
25{
26 struct adp5520_gpio *dev;
27 uint8_t reg_val;
28
29 dev = container_of(chip, struct adp5520_gpio, gpio_chip);
30
31 /*
32 * There are dedicated registers for GPIO IN/OUT.
33 * Make sure we return the right value, even when configured as output
34 */
35
36 if (test_bit(off, &dev->output))
37 adp5520_read(dev->master, GPIO_OUT, &reg_val);
38 else
39 adp5520_read(dev->master, GPIO_IN, &reg_val);
40
41 return !!(reg_val & dev->lut[off]);
42}
43
44static void adp5520_gpio_set_value(struct gpio_chip *chip,
45 unsigned off, int val)
46{
47 struct adp5520_gpio *dev;
48 dev = container_of(chip, struct adp5520_gpio, gpio_chip);
49
50 if (val)
51 adp5520_set_bits(dev->master, GPIO_OUT, dev->lut[off]);
52 else
53 adp5520_clr_bits(dev->master, GPIO_OUT, dev->lut[off]);
54}
55
56static int adp5520_gpio_direction_input(struct gpio_chip *chip, unsigned off)
57{
58 struct adp5520_gpio *dev;
59 dev = container_of(chip, struct adp5520_gpio, gpio_chip);
60
61 clear_bit(off, &dev->output);
62
63 return adp5520_clr_bits(dev->master, GPIO_CFG_2, dev->lut[off]);
64}
65
66static int adp5520_gpio_direction_output(struct gpio_chip *chip,
67 unsigned off, int val)
68{
69 struct adp5520_gpio *dev;
70 int ret = 0;
71 dev = container_of(chip, struct adp5520_gpio, gpio_chip);
72
73 set_bit(off, &dev->output);
74
75 if (val)
76 ret |= adp5520_set_bits(dev->master, GPIO_OUT, dev->lut[off]);
77 else
78 ret |= adp5520_clr_bits(dev->master, GPIO_OUT, dev->lut[off]);
79
80 ret |= adp5520_set_bits(dev->master, GPIO_CFG_2, dev->lut[off]);
81
82 return ret;
83}
84
85static int __devinit adp5520_gpio_probe(struct platform_device *pdev)
86{
87 struct adp5520_gpio_platfrom_data *pdata = pdev->dev.platform_data;
88 struct adp5520_gpio *dev;
89 struct gpio_chip *gc;
90 int ret, i, gpios;
91 unsigned char ctl_mask = 0;
92
93 if (pdata == NULL) {
94 dev_err(&pdev->dev, "missing platform data\n");
95 return -ENODEV;
96 }
97
98 if (pdev->id != ID_ADP5520) {
99 dev_err(&pdev->dev, "only ADP5520 supports GPIO\n");
100 return -ENODEV;
101 }
102
103 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
104 if (dev == NULL) {
105 dev_err(&pdev->dev, "failed to alloc memory\n");
106 return -ENOMEM;
107 }
108
109 dev->master = pdev->dev.parent;
110
111 for (gpios = 0, i = 0; i < ADP5520_MAXGPIOS; i++)
112 if (pdata->gpio_en_mask & (1 << i))
113 dev->lut[gpios++] = 1 << i;
114
115 if (gpios < 1) {
116 ret = -EINVAL;
117 goto err;
118 }
119
120 gc = &dev->gpio_chip;
121 gc->direction_input = adp5520_gpio_direction_input;
122 gc->direction_output = adp5520_gpio_direction_output;
123 gc->get = adp5520_gpio_get_value;
124 gc->set = adp5520_gpio_set_value;
125 gc->can_sleep = 1;
126
127 gc->base = pdata->gpio_start;
128 gc->ngpio = gpios;
129 gc->label = pdev->name;
130 gc->owner = THIS_MODULE;
131
132 ret = adp5520_clr_bits(dev->master, GPIO_CFG_1,
133 pdata->gpio_en_mask);
134
135 if (pdata->gpio_en_mask & GPIO_C3)
136 ctl_mask |= C3_MODE;
137
138 if (pdata->gpio_en_mask & GPIO_R3)
139 ctl_mask |= R3_MODE;
140
141 if (ctl_mask)
142 ret = adp5520_set_bits(dev->master, LED_CONTROL,
143 ctl_mask);
144
145 ret |= adp5520_set_bits(dev->master, GPIO_PULLUP,
146 pdata->gpio_pullup_mask);
147
148 if (ret) {
149 dev_err(&pdev->dev, "failed to write\n");
150 goto err;
151 }
152
153 ret = gpiochip_add(&dev->gpio_chip);
154 if (ret)
155 goto err;
156
157 platform_set_drvdata(pdev, dev);
158 return 0;
159
160err:
161 kfree(dev);
162 return ret;
163}
164
165static int __devexit adp5520_gpio_remove(struct platform_device *pdev)
166{
167 struct adp5520_gpio *dev;
168 int ret;
169
170 dev = platform_get_drvdata(pdev);
171 ret = gpiochip_remove(&dev->gpio_chip);
172 if (ret) {
173 dev_err(&pdev->dev, "%s failed, %d\n",
174 "gpiochip_remove()", ret);
175 return ret;
176 }
177
178 kfree(dev);
179 return 0;
180}
181
182static struct platform_driver adp5520_gpio_driver = {
183 .driver = {
184 .name = "adp5520-gpio",
185 .owner = THIS_MODULE,
186 },
187 .probe = adp5520_gpio_probe,
188 .remove = __devexit_p(adp5520_gpio_remove),
189};
190
191static int __init adp5520_gpio_init(void)
192{
193 return platform_driver_register(&adp5520_gpio_driver);
194}
195module_init(adp5520_gpio_init);
196
197static void __exit adp5520_gpio_exit(void)
198{
199 platform_driver_unregister(&adp5520_gpio_driver);
200}
201module_exit(adp5520_gpio_exit);
202
203MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
204MODULE_DESCRIPTION("GPIO ADP5520 Driver");
205MODULE_LICENSE("GPL");
206MODULE_ALIAS("platform:adp5520-gpio");
diff --git a/drivers/gpio/bt8xxgpio.c b/drivers/gpio/bt8xxgpio.c
index 984b587f0f96..2559f2289409 100644
--- a/drivers/gpio/bt8xxgpio.c
+++ b/drivers/gpio/bt8xxgpio.c
@@ -46,8 +46,7 @@
46#include <linux/module.h> 46#include <linux/module.h>
47#include <linux/pci.h> 47#include <linux/pci.h>
48#include <linux/spinlock.h> 48#include <linux/spinlock.h>
49 49#include <linux/gpio.h>
50#include <asm/gpio.h>
51 50
52/* Steal the hardware definitions from the bttv driver. */ 51/* Steal the hardware definitions from the bttv driver. */
53#include "../media/video/bt8xx/bt848.h" 52#include "../media/video/bt8xx/bt848.h"
@@ -331,13 +330,13 @@ static struct pci_driver bt8xxgpio_pci_driver = {
331 .resume = bt8xxgpio_resume, 330 .resume = bt8xxgpio_resume,
332}; 331};
333 332
334static int bt8xxgpio_init(void) 333static int __init bt8xxgpio_init(void)
335{ 334{
336 return pci_register_driver(&bt8xxgpio_pci_driver); 335 return pci_register_driver(&bt8xxgpio_pci_driver);
337} 336}
338module_init(bt8xxgpio_init) 337module_init(bt8xxgpio_init)
339 338
340static void bt8xxgpio_exit(void) 339static void __exit bt8xxgpio_exit(void)
341{ 340{
342 pci_unregister_driver(&bt8xxgpio_pci_driver); 341 pci_unregister_driver(&bt8xxgpio_pci_driver);
343} 342}
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 51a8d4103be5..bb11a429394a 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1,5 +1,6 @@
1#include <linux/kernel.h> 1#include <linux/kernel.h>
2#include <linux/module.h> 2#include <linux/module.h>
3#include <linux/interrupt.h>
3#include <linux/irq.h> 4#include <linux/irq.h>
4#include <linux/spinlock.h> 5#include <linux/spinlock.h>
5#include <linux/device.h> 6#include <linux/device.h>
@@ -7,6 +8,7 @@
7#include <linux/debugfs.h> 8#include <linux/debugfs.h>
8#include <linux/seq_file.h> 9#include <linux/seq_file.h>
9#include <linux/gpio.h> 10#include <linux/gpio.h>
11#include <linux/idr.h>
10 12
11 13
12/* Optional implementation infrastructure for GPIO interfaces. 14/* Optional implementation infrastructure for GPIO interfaces.
@@ -49,6 +51,13 @@ struct gpio_desc {
49#define FLAG_RESERVED 2 51#define FLAG_RESERVED 2
50#define FLAG_EXPORT 3 /* protected by sysfs_lock */ 52#define FLAG_EXPORT 3 /* protected by sysfs_lock */
51#define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control */ 53#define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control */
54#define FLAG_TRIG_FALL 5 /* trigger on falling edge */
55#define FLAG_TRIG_RISE 6 /* trigger on rising edge */
56
57#define PDESC_ID_SHIFT 16 /* add new flags before this one */
58
59#define GPIO_FLAGS_MASK ((1 << PDESC_ID_SHIFT) - 1)
60#define GPIO_TRIGGER_MASK (BIT(FLAG_TRIG_FALL) | BIT(FLAG_TRIG_RISE))
52 61
53#ifdef CONFIG_DEBUG_FS 62#ifdef CONFIG_DEBUG_FS
54 const char *label; 63 const char *label;
@@ -56,6 +65,15 @@ struct gpio_desc {
56}; 65};
57static struct gpio_desc gpio_desc[ARCH_NR_GPIOS]; 66static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];
58 67
68#ifdef CONFIG_GPIO_SYSFS
69struct poll_desc {
70 struct work_struct work;
71 struct sysfs_dirent *value_sd;
72};
73
74static struct idr pdesc_idr;
75#endif
76
59static inline void desc_set_label(struct gpio_desc *d, const char *label) 77static inline void desc_set_label(struct gpio_desc *d, const char *label)
60{ 78{
61#ifdef CONFIG_DEBUG_FS 79#ifdef CONFIG_DEBUG_FS
@@ -188,10 +206,10 @@ static DEFINE_MUTEX(sysfs_lock);
188 * /value 206 * /value
189 * * always readable, subject to hardware behavior 207 * * always readable, subject to hardware behavior
190 * * may be writable, as zero/nonzero 208 * * may be writable, as zero/nonzero
191 * 209 * /edge
192 * REVISIT there will likely be an attribute for configuring async 210 * * configures behavior of poll(2) on /value
193 * notifications, e.g. to specify polling interval or IRQ trigger type 211 * * available only if pin can generate IRQs on input
194 * that would for example trigger a poll() on the "value". 212 * * is read/write as "none", "falling", "rising", or "both"
195 */ 213 */
196 214
197static ssize_t gpio_direction_show(struct device *dev, 215static ssize_t gpio_direction_show(struct device *dev,
@@ -288,6 +306,175 @@ static ssize_t gpio_value_store(struct device *dev,
288static /*const*/ DEVICE_ATTR(value, 0644, 306static /*const*/ DEVICE_ATTR(value, 0644,
289 gpio_value_show, gpio_value_store); 307 gpio_value_show, gpio_value_store);
290 308
309static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
310{
311 struct work_struct *work = priv;
312
313 schedule_work(work);
314 return IRQ_HANDLED;
315}
316
317static void gpio_notify_sysfs(struct work_struct *work)
318{
319 struct poll_desc *pdesc;
320
321 pdesc = container_of(work, struct poll_desc, work);
322 sysfs_notify_dirent(pdesc->value_sd);
323}
324
325static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
326 unsigned long gpio_flags)
327{
328 struct poll_desc *pdesc;
329 unsigned long irq_flags;
330 int ret, irq, id;
331
332 if ((desc->flags & GPIO_TRIGGER_MASK) == gpio_flags)
333 return 0;
334
335 irq = gpio_to_irq(desc - gpio_desc);
336 if (irq < 0)
337 return -EIO;
338
339 id = desc->flags >> PDESC_ID_SHIFT;
340 pdesc = idr_find(&pdesc_idr, id);
341 if (pdesc) {
342 free_irq(irq, &pdesc->work);
343 cancel_work_sync(&pdesc->work);
344 }
345
346 desc->flags &= ~GPIO_TRIGGER_MASK;
347
348 if (!gpio_flags) {
349 ret = 0;
350 goto free_sd;
351 }
352
353 irq_flags = IRQF_SHARED;
354 if (test_bit(FLAG_TRIG_FALL, &gpio_flags))
355 irq_flags |= IRQF_TRIGGER_FALLING;
356 if (test_bit(FLAG_TRIG_RISE, &gpio_flags))
357 irq_flags |= IRQF_TRIGGER_RISING;
358
359 if (!pdesc) {
360 pdesc = kmalloc(sizeof(*pdesc), GFP_KERNEL);
361 if (!pdesc) {
362 ret = -ENOMEM;
363 goto err_out;
364 }
365
366 do {
367 ret = -ENOMEM;
368 if (idr_pre_get(&pdesc_idr, GFP_KERNEL))
369 ret = idr_get_new_above(&pdesc_idr,
370 pdesc, 1, &id);
371 } while (ret == -EAGAIN);
372
373 if (ret)
374 goto free_mem;
375
376 desc->flags &= GPIO_FLAGS_MASK;
377 desc->flags |= (unsigned long)id << PDESC_ID_SHIFT;
378
379 if (desc->flags >> PDESC_ID_SHIFT != id) {
380 ret = -ERANGE;
381 goto free_id;
382 }
383
384 pdesc->value_sd = sysfs_get_dirent(dev->kobj.sd, "value");
385 if (!pdesc->value_sd) {
386 ret = -ENODEV;
387 goto free_id;
388 }
389 INIT_WORK(&pdesc->work, gpio_notify_sysfs);
390 }
391
392 ret = request_irq(irq, gpio_sysfs_irq, irq_flags,
393 "gpiolib", &pdesc->work);
394 if (ret)
395 goto free_sd;
396
397 desc->flags |= gpio_flags;
398 return 0;
399
400free_sd:
401 sysfs_put(pdesc->value_sd);
402free_id:
403 idr_remove(&pdesc_idr, id);
404 desc->flags &= GPIO_FLAGS_MASK;
405free_mem:
406 kfree(pdesc);
407err_out:
408 return ret;
409}
410
411static const struct {
412 const char *name;
413 unsigned long flags;
414} trigger_types[] = {
415 { "none", 0 },
416 { "falling", BIT(FLAG_TRIG_FALL) },
417 { "rising", BIT(FLAG_TRIG_RISE) },
418 { "both", BIT(FLAG_TRIG_FALL) | BIT(FLAG_TRIG_RISE) },
419};
420
421static ssize_t gpio_edge_show(struct device *dev,
422 struct device_attribute *attr, char *buf)
423{
424 const struct gpio_desc *desc = dev_get_drvdata(dev);
425 ssize_t status;
426
427 mutex_lock(&sysfs_lock);
428
429 if (!test_bit(FLAG_EXPORT, &desc->flags))
430 status = -EIO;
431 else {
432 int i;
433
434 status = 0;
435 for (i = 0; i < ARRAY_SIZE(trigger_types); i++)
436 if ((desc->flags & GPIO_TRIGGER_MASK)
437 == trigger_types[i].flags) {
438 status = sprintf(buf, "%s\n",
439 trigger_types[i].name);
440 break;
441 }
442 }
443
444 mutex_unlock(&sysfs_lock);
445 return status;
446}
447
448static ssize_t gpio_edge_store(struct device *dev,
449 struct device_attribute *attr, const char *buf, size_t size)
450{
451 struct gpio_desc *desc = dev_get_drvdata(dev);
452 ssize_t status;
453 int i;
454
455 for (i = 0; i < ARRAY_SIZE(trigger_types); i++)
456 if (sysfs_streq(trigger_types[i].name, buf))
457 goto found;
458 return -EINVAL;
459
460found:
461 mutex_lock(&sysfs_lock);
462
463 if (!test_bit(FLAG_EXPORT, &desc->flags))
464 status = -EIO;
465 else {
466 status = gpio_setup_irq(desc, dev, trigger_types[i].flags);
467 if (!status)
468 status = size;
469 }
470
471 mutex_unlock(&sysfs_lock);
472
473 return status;
474}
475
476static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store);
477
291static const struct attribute *gpio_attrs[] = { 478static const struct attribute *gpio_attrs[] = {
292 &dev_attr_direction.attr, 479 &dev_attr_direction.attr,
293 &dev_attr_value.attr, 480 &dev_attr_value.attr,
@@ -473,7 +660,7 @@ int gpio_export(unsigned gpio, bool direction_may_change)
473 struct device *dev; 660 struct device *dev;
474 661
475 dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), 662 dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
476 desc, ioname ? ioname : "gpio%d", gpio); 663 desc, ioname ? ioname : "gpio%d", gpio);
477 if (dev) { 664 if (dev) {
478 if (direction_may_change) 665 if (direction_may_change)
479 status = sysfs_create_group(&dev->kobj, 666 status = sysfs_create_group(&dev->kobj,
@@ -481,6 +668,14 @@ int gpio_export(unsigned gpio, bool direction_may_change)
481 else 668 else
482 status = device_create_file(dev, 669 status = device_create_file(dev,
483 &dev_attr_value); 670 &dev_attr_value);
671
672 if (!status && gpio_to_irq(gpio) >= 0
673 && (direction_may_change
674 || !test_bit(FLAG_IS_OUT,
675 &desc->flags)))
676 status = device_create_file(dev,
677 &dev_attr_edge);
678
484 if (status != 0) 679 if (status != 0)
485 device_unregister(dev); 680 device_unregister(dev);
486 } else 681 } else
@@ -505,6 +700,51 @@ static int match_export(struct device *dev, void *data)
505} 700}
506 701
507/** 702/**
703 * gpio_export_link - create a sysfs link to an exported GPIO node
704 * @dev: device under which to create symlink
705 * @name: name of the symlink
706 * @gpio: gpio to create symlink to, already exported
707 *
708 * Set up a symlink from /sys/.../dev/name to /sys/class/gpio/gpioN
709 * node. Caller is responsible for unlinking.
710 *
711 * Returns zero on success, else an error.
712 */
713int gpio_export_link(struct device *dev, const char *name, unsigned gpio)
714{
715 struct gpio_desc *desc;
716 int status = -EINVAL;
717
718 if (!gpio_is_valid(gpio))
719 goto done;
720
721 mutex_lock(&sysfs_lock);
722
723 desc = &gpio_desc[gpio];
724
725 if (test_bit(FLAG_EXPORT, &desc->flags)) {
726 struct device *tdev;
727
728 tdev = class_find_device(&gpio_class, NULL, desc, match_export);
729 if (tdev != NULL) {
730 status = sysfs_create_link(&dev->kobj, &tdev->kobj,
731 name);
732 } else {
733 status = -ENODEV;
734 }
735 }
736
737 mutex_unlock(&sysfs_lock);
738
739done:
740 if (status)
741 pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
742
743 return status;
744}
745EXPORT_SYMBOL_GPL(gpio_export_link);
746
747/**
508 * gpio_unexport - reverse effect of gpio_export() 748 * gpio_unexport - reverse effect of gpio_export()
509 * @gpio: gpio to make unavailable 749 * @gpio: gpio to make unavailable
510 * 750 *
@@ -527,6 +767,7 @@ void gpio_unexport(unsigned gpio)
527 767
528 dev = class_find_device(&gpio_class, NULL, desc, match_export); 768 dev = class_find_device(&gpio_class, NULL, desc, match_export);
529 if (dev) { 769 if (dev) {
770 gpio_setup_irq(desc, dev, 0);
530 clear_bit(FLAG_EXPORT, &desc->flags); 771 clear_bit(FLAG_EXPORT, &desc->flags);
531 put_device(dev); 772 put_device(dev);
532 device_unregister(dev); 773 device_unregister(dev);
@@ -611,6 +852,8 @@ static int __init gpiolib_sysfs_init(void)
611 unsigned long flags; 852 unsigned long flags;
612 unsigned gpio; 853 unsigned gpio;
613 854
855 idr_init(&pdesc_idr);
856
614 status = class_register(&gpio_class); 857 status = class_register(&gpio_class);
615 if (status < 0) 858 if (status < 0)
616 return status; 859 return status;
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c
new file mode 100644
index 000000000000..5711ce5353c6
--- /dev/null
+++ b/drivers/gpio/langwell_gpio.c
@@ -0,0 +1,297 @@
1/* langwell_gpio.c Moorestown platform Langwell chip GPIO driver
2 * Copyright (c) 2008 - 2009, Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 */
17
18/* Supports:
19 * Moorestown platform Langwell chip.
20 */
21
22#include <linux/module.h>
23#include <linux/pci.h>
24#include <linux/kernel.h>
25#include <linux/delay.h>
26#include <linux/stddef.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/irq.h>
30#include <linux/io.h>
31#include <linux/gpio.h>
32
33struct lnw_gpio_register {
34 u32 GPLR[2];
35 u32 GPDR[2];
36 u32 GPSR[2];
37 u32 GPCR[2];
38 u32 GRER[2];
39 u32 GFER[2];
40 u32 GEDR[2];
41};
42
43struct lnw_gpio {
44 struct gpio_chip chip;
45 struct lnw_gpio_register *reg_base;
46 spinlock_t lock;
47 unsigned irq_base;
48};
49
50static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset)
51{
52 struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
53 u8 reg = offset / 32;
54 void __iomem *gplr;
55
56 gplr = (void __iomem *)(&lnw->reg_base->GPLR[reg]);
57 return readl(gplr) & BIT(offset % 32);
58}
59
60static void lnw_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
61{
62 struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
63 u8 reg = offset / 32;
64 void __iomem *gpsr, *gpcr;
65
66 if (value) {
67 gpsr = (void __iomem *)(&lnw->reg_base->GPSR[reg]);
68 writel(BIT(offset % 32), gpsr);
69 } else {
70 gpcr = (void __iomem *)(&lnw->reg_base->GPCR[reg]);
71 writel(BIT(offset % 32), gpcr);
72 }
73}
74
75static int lnw_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
76{
77 struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
78 u8 reg = offset / 32;
79 u32 value;
80 unsigned long flags;
81 void __iomem *gpdr;
82
83 gpdr = (void __iomem *)(&lnw->reg_base->GPDR[reg]);
84 spin_lock_irqsave(&lnw->lock, flags);
85 value = readl(gpdr);
86 value &= ~BIT(offset % 32);
87 writel(value, gpdr);
88 spin_unlock_irqrestore(&lnw->lock, flags);
89 return 0;
90}
91
92static int lnw_gpio_direction_output(struct gpio_chip *chip,
93 unsigned offset, int value)
94{
95 struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
96 u8 reg = offset / 32;
97 unsigned long flags;
98 void __iomem *gpdr;
99
100 lnw_gpio_set(chip, offset, value);
101 gpdr = (void __iomem *)(&lnw->reg_base->GPDR[reg]);
102 spin_lock_irqsave(&lnw->lock, flags);
103 value = readl(gpdr);
104 value |= BIT(offset % 32);;
105 writel(value, gpdr);
106 spin_unlock_irqrestore(&lnw->lock, flags);
107 return 0;
108}
109
110static int lnw_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
111{
112 struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
113 return lnw->irq_base + offset;
114}
115
116static int lnw_irq_type(unsigned irq, unsigned type)
117{
118 struct lnw_gpio *lnw = get_irq_chip_data(irq);
119 u32 gpio = irq - lnw->irq_base;
120 u8 reg = gpio / 32;
121 unsigned long flags;
122 u32 value;
123 void __iomem *grer = (void __iomem *)(&lnw->reg_base->GRER[reg]);
124 void __iomem *gfer = (void __iomem *)(&lnw->reg_base->GFER[reg]);
125
126 if (gpio < 0 || gpio > lnw->chip.ngpio)
127 return -EINVAL;
128 spin_lock_irqsave(&lnw->lock, flags);
129 if (type & IRQ_TYPE_EDGE_RISING)
130 value = readl(grer) | BIT(gpio % 32);
131 else
132 value = readl(grer) & (~BIT(gpio % 32));
133 writel(value, grer);
134
135 if (type & IRQ_TYPE_EDGE_FALLING)
136 value = readl(gfer) | BIT(gpio % 32);
137 else
138 value = readl(gfer) & (~BIT(gpio % 32));
139 writel(value, gfer);
140 spin_unlock_irqrestore(&lnw->lock, flags);
141
142 return 0;
143};
144
145static void lnw_irq_unmask(unsigned irq)
146{
147 struct lnw_gpio *lnw = get_irq_chip_data(irq);
148 u32 gpio = irq - lnw->irq_base;
149 u8 reg = gpio / 32;
150 void __iomem *gedr;
151
152 gedr = (void __iomem *)(&lnw->reg_base->GEDR[reg]);
153 writel(BIT(gpio % 32), gedr);
154};
155
156static void lnw_irq_mask(unsigned irq)
157{
158};
159
160static struct irq_chip lnw_irqchip = {
161 .name = "LNW-GPIO",
162 .mask = lnw_irq_mask,
163 .unmask = lnw_irq_unmask,
164 .set_type = lnw_irq_type,
165};
166
167static struct pci_device_id lnw_gpio_ids[] = {
168 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080f) },
169 { 0, }
170};
171MODULE_DEVICE_TABLE(pci, lnw_gpio_ids);
172
173static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
174{
175 struct lnw_gpio *lnw = (struct lnw_gpio *)get_irq_data(irq);
176 u32 reg, gpio;
177 void __iomem *gedr;
178 u32 gedr_v;
179
180 /* check GPIO controller to check which pin triggered the interrupt */
181 for (reg = 0; reg < lnw->chip.ngpio / 32; reg++) {
182 gedr = (void __iomem *)(&lnw->reg_base->GEDR[reg]);
183 gedr_v = readl(gedr);
184 if (!gedr_v)
185 continue;
186 for (gpio = reg*32; gpio < reg*32+32; gpio++) {
187 gedr_v = readl(gedr);
188 if (gedr_v & BIT(gpio % 32)) {
189 pr_debug("pin %d triggered\n", gpio);
190 generic_handle_irq(lnw->irq_base + gpio);
191 }
192 }
193 /* clear the edge detect status bit */
194 writel(gedr_v, gedr);
195 }
196 desc->chip->eoi(irq);
197}
198
199static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
200 const struct pci_device_id *id)
201{
202 void *base;
203 int i;
204 resource_size_t start, len;
205 struct lnw_gpio *lnw;
206 u32 irq_base;
207 u32 gpio_base;
208 int retval = 0;
209
210 retval = pci_enable_device(pdev);
211 if (retval)
212 goto done;
213
214 retval = pci_request_regions(pdev, "langwell_gpio");
215 if (retval) {
216 dev_err(&pdev->dev, "error requesting resources\n");
217 goto err2;
218 }
219 /* get the irq_base from bar1 */
220 start = pci_resource_start(pdev, 1);
221 len = pci_resource_len(pdev, 1);
222 base = ioremap_nocache(start, len);
223 if (!base) {
224 dev_err(&pdev->dev, "error mapping bar1\n");
225 goto err3;
226 }
227 irq_base = *(u32 *)base;
228 gpio_base = *((u32 *)base + 1);
229 /* release the IO mapping, since we already get the info from bar1 */
230 iounmap(base);
231 /* get the register base from bar0 */
232 start = pci_resource_start(pdev, 0);
233 len = pci_resource_len(pdev, 0);
234 base = ioremap_nocache(start, len);
235 if (!base) {
236 dev_err(&pdev->dev, "error mapping bar0\n");
237 retval = -EFAULT;
238 goto err3;
239 }
240
241 lnw = kzalloc(sizeof(struct lnw_gpio), GFP_KERNEL);
242 if (!lnw) {
243 dev_err(&pdev->dev, "can't allocate langwell_gpio chip data\n");
244 retval = -ENOMEM;
245 goto err4;
246 }
247 lnw->reg_base = base;
248 lnw->irq_base = irq_base;
249 lnw->chip.label = dev_name(&pdev->dev);
250 lnw->chip.direction_input = lnw_gpio_direction_input;
251 lnw->chip.direction_output = lnw_gpio_direction_output;
252 lnw->chip.get = lnw_gpio_get;
253 lnw->chip.set = lnw_gpio_set;
254 lnw->chip.to_irq = lnw_gpio_to_irq;
255 lnw->chip.base = gpio_base;
256 lnw->chip.ngpio = 64;
257 lnw->chip.can_sleep = 0;
258 pci_set_drvdata(pdev, lnw);
259 retval = gpiochip_add(&lnw->chip);
260 if (retval) {
261 dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval);
262 goto err5;
263 }
264 set_irq_data(pdev->irq, lnw);
265 set_irq_chained_handler(pdev->irq, lnw_irq_handler);
266 for (i = 0; i < lnw->chip.ngpio; i++) {
267 set_irq_chip_and_handler_name(i + lnw->irq_base, &lnw_irqchip,
268 handle_simple_irq, "demux");
269 set_irq_chip_data(i + lnw->irq_base, lnw);
270 }
271
272 spin_lock_init(&lnw->lock);
273 goto done;
274err5:
275 kfree(lnw);
276err4:
277 iounmap(base);
278err3:
279 pci_release_regions(pdev);
280err2:
281 pci_disable_device(pdev);
282done:
283 return retval;
284}
285
286static struct pci_driver lnw_gpio_driver = {
287 .name = "langwell_gpio",
288 .id_table = lnw_gpio_ids,
289 .probe = lnw_gpio_probe,
290};
291
292static int __init lnw_gpio_init(void)
293{
294 return pci_register_driver(&lnw_gpio_driver);
295}
296
297device_initcall(lnw_gpio_init);
diff --git a/drivers/gpio/max7301.c b/drivers/gpio/max7301.c
index 7b82eaae2621..480956f1ca50 100644
--- a/drivers/gpio/max7301.c
+++ b/drivers/gpio/max7301.c
@@ -339,3 +339,4 @@ module_exit(max7301_exit);
339MODULE_AUTHOR("Juergen Beisert"); 339MODULE_AUTHOR("Juergen Beisert");
340MODULE_LICENSE("GPL v2"); 340MODULE_LICENSE("GPL v2");
341MODULE_DESCRIPTION("MAX7301 SPI based GPIO-Expander"); 341MODULE_DESCRIPTION("MAX7301 SPI based GPIO-Expander");
342MODULE_ALIAS("spi:" DRIVER_NAME);
diff --git a/drivers/gpio/mc33880.c b/drivers/gpio/mc33880.c
new file mode 100644
index 000000000000..e7d01bd8fdb3
--- /dev/null
+++ b/drivers/gpio/mc33880.c
@@ -0,0 +1,196 @@
1/*
2 * mc33880.c MC33880 high-side/low-side switch GPIO driver
3 * Copyright (c) 2009 Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19/* Supports:
20 * Freescale MC33880 high-side/low-side switch
21 */
22
23#include <linux/init.h>
24#include <linux/mutex.h>
25#include <linux/spi/spi.h>
26#include <linux/spi/mc33880.h>
27#include <linux/gpio.h>
28
29#define DRIVER_NAME "mc33880"
30
31/*
32 * Pin configurations, see MAX7301 datasheet page 6
33 */
34#define PIN_CONFIG_MASK 0x03
35#define PIN_CONFIG_IN_PULLUP 0x03
36#define PIN_CONFIG_IN_WO_PULLUP 0x02
37#define PIN_CONFIG_OUT 0x01
38
39#define PIN_NUMBER 8
40
41
42/*
43 * Some registers must be read back to modify.
44 * To save time we cache them here in memory
45 */
46struct mc33880 {
47 struct mutex lock; /* protect from simultanous accesses */
48 u8 port_config;
49 struct gpio_chip chip;
50 struct spi_device *spi;
51};
52
53static int mc33880_write_config(struct mc33880 *mc)
54{
55 return spi_write(mc->spi, &mc->port_config, sizeof(mc->port_config));
56}
57
58
59static int __mc33880_set(struct mc33880 *mc, unsigned offset, int value)
60{
61 if (value)
62 mc->port_config |= 1 << offset;
63 else
64 mc->port_config &= ~(1 << offset);
65
66 return mc33880_write_config(mc);
67}
68
69
70static void mc33880_set(struct gpio_chip *chip, unsigned offset, int value)
71{
72 struct mc33880 *mc = container_of(chip, struct mc33880, chip);
73
74 mutex_lock(&mc->lock);
75
76 __mc33880_set(mc, offset, value);
77
78 mutex_unlock(&mc->lock);
79}
80
81static int __devinit mc33880_probe(struct spi_device *spi)
82{
83 struct mc33880 *mc;
84 struct mc33880_platform_data *pdata;
85 int ret;
86
87 pdata = spi->dev.platform_data;
88 if (!pdata || !pdata->base) {
89 dev_dbg(&spi->dev, "incorrect or missing platform data\n");
90 return -EINVAL;
91 }
92
93 /*
94 * bits_per_word cannot be configured in platform data
95 */
96 spi->bits_per_word = 8;
97
98 ret = spi_setup(spi);
99 if (ret < 0)
100 return ret;
101
102 mc = kzalloc(sizeof(struct mc33880), GFP_KERNEL);
103 if (!mc)
104 return -ENOMEM;
105
106 mutex_init(&mc->lock);
107
108 dev_set_drvdata(&spi->dev, mc);
109
110 mc->spi = spi;
111
112 mc->chip.label = DRIVER_NAME,
113 mc->chip.set = mc33880_set;
114 mc->chip.base = pdata->base;
115 mc->chip.ngpio = PIN_NUMBER;
116 mc->chip.can_sleep = 1;
117 mc->chip.dev = &spi->dev;
118 mc->chip.owner = THIS_MODULE;
119
120 mc->port_config = 0x00;
121 /* write twice, because during initialisation the first setting
122 * is just for testing SPI communication, and the second is the
123 * "real" configuration
124 */
125 ret = mc33880_write_config(mc);
126 mc->port_config = 0x00;
127 if (!ret)
128 ret = mc33880_write_config(mc);
129
130 if (ret) {
131 printk(KERN_ERR "Failed writing to " DRIVER_NAME ": %d\n", ret);
132 goto exit_destroy;
133 }
134
135 ret = gpiochip_add(&mc->chip);
136 if (ret)
137 goto exit_destroy;
138
139 return ret;
140
141exit_destroy:
142 dev_set_drvdata(&spi->dev, NULL);
143 mutex_destroy(&mc->lock);
144 kfree(mc);
145 return ret;
146}
147
148static int mc33880_remove(struct spi_device *spi)
149{
150 struct mc33880 *mc;
151 int ret;
152
153 mc = dev_get_drvdata(&spi->dev);
154 if (mc == NULL)
155 return -ENODEV;
156
157 dev_set_drvdata(&spi->dev, NULL);
158
159 ret = gpiochip_remove(&mc->chip);
160 if (!ret) {
161 mutex_destroy(&mc->lock);
162 kfree(mc);
163 } else
164 dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n",
165 ret);
166
167 return ret;
168}
169
170static struct spi_driver mc33880_driver = {
171 .driver = {
172 .name = DRIVER_NAME,
173 .owner = THIS_MODULE,
174 },
175 .probe = mc33880_probe,
176 .remove = __devexit_p(mc33880_remove),
177};
178
179static int __init mc33880_init(void)
180{
181 return spi_register_driver(&mc33880_driver);
182}
183/* register after spi postcore initcall and before
184 * subsys initcalls that may rely on these GPIOs
185 */
186subsys_initcall(mc33880_init);
187
188static void __exit mc33880_exit(void)
189{
190 spi_unregister_driver(&mc33880_driver);
191}
192module_exit(mc33880_exit);
193
194MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
195MODULE_LICENSE("GPL v2");
196
diff --git a/drivers/gpio/mcp23s08.c b/drivers/gpio/mcp23s08.c
index f6fae0e50e65..cd651ec8d034 100644
--- a/drivers/gpio/mcp23s08.c
+++ b/drivers/gpio/mcp23s08.c
@@ -6,12 +6,10 @@
6#include <linux/device.h> 6#include <linux/device.h>
7#include <linux/workqueue.h> 7#include <linux/workqueue.h>
8#include <linux/mutex.h> 8#include <linux/mutex.h>
9 9#include <linux/gpio.h>
10#include <linux/spi/spi.h> 10#include <linux/spi/spi.h>
11#include <linux/spi/mcp23s08.h> 11#include <linux/spi/mcp23s08.h>
12 12
13#include <asm/gpio.h>
14
15 13
16/* Registers are all 8 bits wide. 14/* Registers are all 8 bits wide.
17 * 15 *
@@ -433,3 +431,4 @@ static void __exit mcp23s08_exit(void)
433module_exit(mcp23s08_exit); 431module_exit(mcp23s08_exit);
434 432
435MODULE_LICENSE("GPL"); 433MODULE_LICENSE("GPL");
434MODULE_ALIAS("spi:mcp23s08");
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index cdb6574d25a6..6a2fb3fbb3d9 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/gpio.h>
16#include <linux/i2c.h> 17#include <linux/i2c.h>
17#include <linux/i2c/pca953x.h> 18#include <linux/i2c/pca953x.h>
18#ifdef CONFIG_OF_GPIO 19#ifdef CONFIG_OF_GPIO
@@ -20,8 +21,6 @@
20#include <linux/of_gpio.h> 21#include <linux/of_gpio.h>
21#endif 22#endif
22 23
23#include <asm/gpio.h>
24
25#define PCA953X_INPUT 0 24#define PCA953X_INPUT 0
26#define PCA953X_OUTPUT 1 25#define PCA953X_OUTPUT 1
27#define PCA953X_INVERT 2 26#define PCA953X_INVERT 2
@@ -40,6 +39,7 @@ static const struct i2c_device_id pca953x_id[] = {
40 { "pca9557", 8, }, 39 { "pca9557", 8, },
41 40
42 { "max7310", 8, }, 41 { "max7310", 8, },
42 { "max7315", 8, },
43 { "pca6107", 8, }, 43 { "pca6107", 8, },
44 { "tca6408", 8, }, 44 { "tca6408", 8, },
45 { "tca6416", 16, }, 45 { "tca6416", 16, },
diff --git a/drivers/gpio/pcf857x.c b/drivers/gpio/pcf857x.c
index 9525724be731..29f19ce3e80f 100644
--- a/drivers/gpio/pcf857x.c
+++ b/drivers/gpio/pcf857x.c
@@ -20,14 +20,14 @@
20 20
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/gpio.h>
23#include <linux/i2c.h> 24#include <linux/i2c.h>
24#include <linux/i2c/pcf857x.h> 25#include <linux/i2c/pcf857x.h>
25 26
26#include <asm/gpio.h>
27
28 27
29static const struct i2c_device_id pcf857x_id[] = { 28static const struct i2c_device_id pcf857x_id[] = {
30 { "pcf8574", 8 }, 29 { "pcf8574", 8 },
30 { "pcf8574a", 8 },
31 { "pca8574", 8 }, 31 { "pca8574", 8 },
32 { "pca9670", 8 }, 32 { "pca9670", 8 },
33 { "pca9672", 8 }, 33 { "pca9672", 8 },
diff --git a/drivers/gpio/ucb1400_gpio.c b/drivers/gpio/ucb1400_gpio.c
new file mode 100644
index 000000000000..50e6bd1392ce
--- /dev/null
+++ b/drivers/gpio/ucb1400_gpio.c
@@ -0,0 +1,125 @@
1/*
2 * Philips UCB1400 GPIO driver
3 *
4 * Author: Marek Vasut <marek.vasut@gmail.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 version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/ucb1400.h>
14
15struct ucb1400_gpio_data *ucbdata;
16
17static int ucb1400_gpio_dir_in(struct gpio_chip *gc, unsigned off)
18{
19 struct ucb1400_gpio *gpio;
20 gpio = container_of(gc, struct ucb1400_gpio, gc);
21 ucb1400_gpio_set_direction(gpio->ac97, off, 0);
22 return 0;
23}
24
25static int ucb1400_gpio_dir_out(struct gpio_chip *gc, unsigned off, int val)
26{
27 struct ucb1400_gpio *gpio;
28 gpio = container_of(gc, struct ucb1400_gpio, gc);
29 ucb1400_gpio_set_direction(gpio->ac97, off, 1);
30 ucb1400_gpio_set_value(gpio->ac97, off, val);
31 return 0;
32}
33
34static int ucb1400_gpio_get(struct gpio_chip *gc, unsigned off)
35{
36 struct ucb1400_gpio *gpio;
37 gpio = container_of(gc, struct ucb1400_gpio, gc);
38 return ucb1400_gpio_get_value(gpio->ac97, off);
39}
40
41static void ucb1400_gpio_set(struct gpio_chip *gc, unsigned off, int val)
42{
43 struct ucb1400_gpio *gpio;
44 gpio = container_of(gc, struct ucb1400_gpio, gc);
45 ucb1400_gpio_set_value(gpio->ac97, off, val);
46}
47
48static int ucb1400_gpio_probe(struct platform_device *dev)
49{
50 struct ucb1400_gpio *ucb = dev->dev.platform_data;
51 int err = 0;
52
53 if (!(ucbdata && ucbdata->gpio_offset)) {
54 err = -EINVAL;
55 goto err;
56 }
57
58 platform_set_drvdata(dev, ucb);
59
60 ucb->gc.label = "ucb1400_gpio";
61 ucb->gc.base = ucbdata->gpio_offset;
62 ucb->gc.ngpio = 10;
63 ucb->gc.owner = THIS_MODULE;
64
65 ucb->gc.direction_input = ucb1400_gpio_dir_in;
66 ucb->gc.direction_output = ucb1400_gpio_dir_out;
67 ucb->gc.get = ucb1400_gpio_get;
68 ucb->gc.set = ucb1400_gpio_set;
69 ucb->gc.can_sleep = 1;
70
71 err = gpiochip_add(&ucb->gc);
72 if (err)
73 goto err;
74
75 if (ucbdata && ucbdata->gpio_setup)
76 err = ucbdata->gpio_setup(&dev->dev, ucb->gc.ngpio);
77
78err:
79 return err;
80
81}
82
83static int ucb1400_gpio_remove(struct platform_device *dev)
84{
85 int err = 0;
86 struct ucb1400_gpio *ucb = platform_get_drvdata(dev);
87
88 if (ucbdata && ucbdata->gpio_teardown) {
89 err = ucbdata->gpio_teardown(&dev->dev, ucb->gc.ngpio);
90 if (err)
91 return err;
92 }
93
94 err = gpiochip_remove(&ucb->gc);
95 return err;
96}
97
98static struct platform_driver ucb1400_gpio_driver = {
99 .probe = ucb1400_gpio_probe,
100 .remove = ucb1400_gpio_remove,
101 .driver = {
102 .name = "ucb1400_gpio"
103 },
104};
105
106static int __init ucb1400_gpio_init(void)
107{
108 return platform_driver_register(&ucb1400_gpio_driver);
109}
110
111static void __exit ucb1400_gpio_exit(void)
112{
113 platform_driver_unregister(&ucb1400_gpio_driver);
114}
115
116void __init ucb1400_gpio_set_data(struct ucb1400_gpio_data *data)
117{
118 ucbdata = data;
119}
120
121module_init(ucb1400_gpio_init);
122module_exit(ucb1400_gpio_exit);
123
124MODULE_DESCRIPTION("Philips UCB1400 GPIO driver");
125MODULE_LICENSE("GPL");