diff options
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/74x164.c | 27 | ||||
-rw-r--r-- | drivers/gpio/Kconfig | 32 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-ep93xx.c | 410 | ||||
-rw-r--r-- | drivers/gpio/pca953x.c | 1 |
5 files changed, 434 insertions, 37 deletions
diff --git a/drivers/gpio/74x164.c b/drivers/gpio/74x164.c index 84e070219839..7fb60b6bf523 100644 --- a/drivers/gpio/74x164.c +++ b/drivers/gpio/74x164.c | |||
@@ -16,9 +16,6 @@ | |||
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | 18 | ||
19 | #define GEN_74X164_GPIO_COUNT 8 | ||
20 | |||
21 | |||
22 | struct gen_74x164_chip { | 19 | struct gen_74x164_chip { |
23 | struct spi_device *spi; | 20 | struct spi_device *spi; |
24 | struct gpio_chip gpio_chip; | 21 | struct gpio_chip gpio_chip; |
@@ -26,8 +23,6 @@ struct gen_74x164_chip { | |||
26 | u8 port_config; | 23 | u8 port_config; |
27 | }; | 24 | }; |
28 | 25 | ||
29 | static void gen_74x164_set_value(struct gpio_chip *, unsigned, int); | ||
30 | |||
31 | static struct gen_74x164_chip *gpio_to_chip(struct gpio_chip *gc) | 26 | static struct gen_74x164_chip *gpio_to_chip(struct gpio_chip *gc) |
32 | { | 27 | { |
33 | return container_of(gc, struct gen_74x164_chip, gpio_chip); | 28 | return container_of(gc, struct gen_74x164_chip, gpio_chip); |
@@ -39,13 +34,6 @@ static int __gen_74x164_write_config(struct gen_74x164_chip *chip) | |||
39 | &chip->port_config, sizeof(chip->port_config)); | 34 | &chip->port_config, sizeof(chip->port_config)); |
40 | } | 35 | } |
41 | 36 | ||
42 | static int gen_74x164_direction_output(struct gpio_chip *gc, | ||
43 | unsigned offset, int val) | ||
44 | { | ||
45 | gen_74x164_set_value(gc, offset, val); | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset) | 37 | static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset) |
50 | { | 38 | { |
51 | struct gen_74x164_chip *chip = gpio_to_chip(gc); | 39 | struct gen_74x164_chip *chip = gpio_to_chip(gc); |
@@ -73,6 +61,13 @@ static void gen_74x164_set_value(struct gpio_chip *gc, | |||
73 | mutex_unlock(&chip->lock); | 61 | mutex_unlock(&chip->lock); |
74 | } | 62 | } |
75 | 63 | ||
64 | static int gen_74x164_direction_output(struct gpio_chip *gc, | ||
65 | unsigned offset, int val) | ||
66 | { | ||
67 | gen_74x164_set_value(gc, offset, val); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
76 | static int __devinit gen_74x164_probe(struct spi_device *spi) | 71 | static int __devinit gen_74x164_probe(struct spi_device *spi) |
77 | { | 72 | { |
78 | struct gen_74x164_chip *chip; | 73 | struct gen_74x164_chip *chip; |
@@ -104,12 +99,12 @@ static int __devinit gen_74x164_probe(struct spi_device *spi) | |||
104 | 99 | ||
105 | chip->spi = spi; | 100 | chip->spi = spi; |
106 | 101 | ||
107 | chip->gpio_chip.label = GEN_74X164_DRIVER_NAME, | 102 | chip->gpio_chip.label = spi->modalias; |
108 | chip->gpio_chip.direction_output = gen_74x164_direction_output; | 103 | chip->gpio_chip.direction_output = gen_74x164_direction_output; |
109 | chip->gpio_chip.get = gen_74x164_get_value; | 104 | chip->gpio_chip.get = gen_74x164_get_value; |
110 | chip->gpio_chip.set = gen_74x164_set_value; | 105 | chip->gpio_chip.set = gen_74x164_set_value; |
111 | chip->gpio_chip.base = pdata->base; | 106 | chip->gpio_chip.base = pdata->base; |
112 | chip->gpio_chip.ngpio = GEN_74X164_GPIO_COUNT; | 107 | chip->gpio_chip.ngpio = 8; |
113 | chip->gpio_chip.can_sleep = 1; | 108 | chip->gpio_chip.can_sleep = 1; |
114 | chip->gpio_chip.dev = &spi->dev; | 109 | chip->gpio_chip.dev = &spi->dev; |
115 | chip->gpio_chip.owner = THIS_MODULE; | 110 | chip->gpio_chip.owner = THIS_MODULE; |
@@ -157,7 +152,7 @@ static int __devexit gen_74x164_remove(struct spi_device *spi) | |||
157 | 152 | ||
158 | static struct spi_driver gen_74x164_driver = { | 153 | static struct spi_driver gen_74x164_driver = { |
159 | .driver = { | 154 | .driver = { |
160 | .name = GEN_74X164_DRIVER_NAME, | 155 | .name = "74x164", |
161 | .owner = THIS_MODULE, | 156 | .owner = THIS_MODULE, |
162 | }, | 157 | }, |
163 | .probe = gen_74x164_probe, | 158 | .probe = gen_74x164_probe, |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 57d7bc547f4b..f8b6e7d27e4c 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -86,12 +86,13 @@ config GPIO_IT8761E | |||
86 | help | 86 | help |
87 | Say yes here to support GPIO functionality of IT8761E super I/O chip. | 87 | Say yes here to support GPIO functionality of IT8761E super I/O chip. |
88 | 88 | ||
89 | config GPIO_EP93XX | ||
90 | def_bool y | ||
91 | depends on ARCH_EP93XX | ||
92 | |||
89 | config GPIO_EXYNOS4 | 93 | config GPIO_EXYNOS4 |
90 | bool "Samsung Exynos4 GPIO library support" | 94 | def_bool y |
91 | default y if CPU_EXYNOS4210 | 95 | depends on CPU_EXYNOS4210 |
92 | depends on ARM | ||
93 | help | ||
94 | Say yes here to support Samsung Exynos4 series SoCs GPIO library | ||
95 | 96 | ||
96 | config GPIO_MXS | 97 | config GPIO_MXS |
97 | def_bool y | 98 | def_bool y |
@@ -103,25 +104,16 @@ config GPIO_MXC | |||
103 | select GPIO_BASIC_MMIO_CORE | 104 | select GPIO_BASIC_MMIO_CORE |
104 | 105 | ||
105 | config GPIO_PLAT_SAMSUNG | 106 | config GPIO_PLAT_SAMSUNG |
106 | bool "Samsung SoCs GPIO library support" | 107 | def_bool y |
107 | default y if SAMSUNG_GPIOLIB_4BIT | 108 | depends on SAMSUNG_GPIOLIB_4BIT |
108 | depends on ARM | ||
109 | help | ||
110 | Say yes here to support Samsung SoCs GPIO library | ||
111 | 109 | ||
112 | config GPIO_S5PC100 | 110 | config GPIO_S5PC100 |
113 | bool "Samsung S5PC100 GPIO library support" | 111 | def_bool y |
114 | default y if CPU_S5PC100 | 112 | depends on CPU_S5PC100 |
115 | depends on ARM | ||
116 | help | ||
117 | Say yes here to support Samsung S5PC100 SoCs GPIO library | ||
118 | 113 | ||
119 | config GPIO_S5PV210 | 114 | config GPIO_S5PV210 |
120 | bool "Samsung S5PV210/S5PC110 GPIO library support" | 115 | def_bool y |
121 | default y if CPU_S5PV210 | 116 | depends on CPU_S5PV210 |
122 | depends on ARM | ||
123 | help | ||
124 | Say yes here to support Samsung S5PV210/S5PC110 SoCs GPIO library | ||
125 | 117 | ||
126 | config GPIO_PL061 | 118 | config GPIO_PL061 |
127 | bool "PrimeCell PL061 GPIO support" | 119 | bool "PrimeCell PL061 GPIO support" |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 9c37339a57a7..66923cf3ad6a 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o | |||
8 | obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o | 8 | obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o |
9 | obj-$(CONFIG_GPIO_BASIC_MMIO_CORE) += basic_mmio_gpio.o | 9 | obj-$(CONFIG_GPIO_BASIC_MMIO_CORE) += basic_mmio_gpio.o |
10 | obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o | 10 | obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o |
11 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o | ||
11 | obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o | 12 | obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o |
12 | obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o | 13 | obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o |
13 | obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o | 14 | obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o |
diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c new file mode 100644 index 000000000000..415dce37b88c --- /dev/null +++ b/drivers/gpio/gpio-ep93xx.c | |||
@@ -0,0 +1,410 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-ep93xx/gpio.c | ||
3 | * | ||
4 | * Generic EP93xx GPIO handling | ||
5 | * | ||
6 | * Copyright (c) 2008 Ryan Mallon <ryan@bluewatersys.com> | ||
7 | * | ||
8 | * Based on code originally from: | ||
9 | * linux/arch/arm/mach-ep93xx/core.c | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt | ||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/seq_file.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/irq.h> | ||
24 | |||
25 | #include <mach/hardware.h> | ||
26 | |||
27 | /************************************************************************* | ||
28 | * Interrupt handling for EP93xx on-chip GPIOs | ||
29 | *************************************************************************/ | ||
30 | static unsigned char gpio_int_unmasked[3]; | ||
31 | static unsigned char gpio_int_enabled[3]; | ||
32 | static unsigned char gpio_int_type1[3]; | ||
33 | static unsigned char gpio_int_type2[3]; | ||
34 | static unsigned char gpio_int_debounce[3]; | ||
35 | |||
36 | /* Port ordering is: A B F */ | ||
37 | static const u8 int_type1_register_offset[3] = { 0x90, 0xac, 0x4c }; | ||
38 | static const u8 int_type2_register_offset[3] = { 0x94, 0xb0, 0x50 }; | ||
39 | static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 }; | ||
40 | static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 }; | ||
41 | static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 }; | ||
42 | |||
43 | static void ep93xx_gpio_update_int_params(unsigned port) | ||
44 | { | ||
45 | BUG_ON(port > 2); | ||
46 | |||
47 | __raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port])); | ||
48 | |||
49 | __raw_writeb(gpio_int_type2[port], | ||
50 | EP93XX_GPIO_REG(int_type2_register_offset[port])); | ||
51 | |||
52 | __raw_writeb(gpio_int_type1[port], | ||
53 | EP93XX_GPIO_REG(int_type1_register_offset[port])); | ||
54 | |||
55 | __raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port], | ||
56 | EP93XX_GPIO_REG(int_en_register_offset[port])); | ||
57 | } | ||
58 | |||
59 | static inline void ep93xx_gpio_int_mask(unsigned line) | ||
60 | { | ||
61 | gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7)); | ||
62 | } | ||
63 | |||
64 | static void ep93xx_gpio_int_debounce(unsigned int irq, bool enable) | ||
65 | { | ||
66 | int line = irq_to_gpio(irq); | ||
67 | int port = line >> 3; | ||
68 | int port_mask = 1 << (line & 7); | ||
69 | |||
70 | if (enable) | ||
71 | gpio_int_debounce[port] |= port_mask; | ||
72 | else | ||
73 | gpio_int_debounce[port] &= ~port_mask; | ||
74 | |||
75 | __raw_writeb(gpio_int_debounce[port], | ||
76 | EP93XX_GPIO_REG(int_debounce_register_offset[port])); | ||
77 | } | ||
78 | |||
79 | static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
80 | { | ||
81 | unsigned char status; | ||
82 | int i; | ||
83 | |||
84 | status = __raw_readb(EP93XX_GPIO_A_INT_STATUS); | ||
85 | for (i = 0; i < 8; i++) { | ||
86 | if (status & (1 << i)) { | ||
87 | int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i; | ||
88 | generic_handle_irq(gpio_irq); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | status = __raw_readb(EP93XX_GPIO_B_INT_STATUS); | ||
93 | for (i = 0; i < 8; i++) { | ||
94 | if (status & (1 << i)) { | ||
95 | int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i; | ||
96 | generic_handle_irq(gpio_irq); | ||
97 | } | ||
98 | } | ||
99 | } | ||
100 | |||
101 | static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
102 | { | ||
103 | /* | ||
104 | * map discontiguous hw irq range to continuous sw irq range: | ||
105 | * | ||
106 | * IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7}) | ||
107 | */ | ||
108 | int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */ | ||
109 | int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx; | ||
110 | |||
111 | generic_handle_irq(gpio_irq); | ||
112 | } | ||
113 | |||
114 | static void ep93xx_gpio_irq_ack(struct irq_data *d) | ||
115 | { | ||
116 | int line = irq_to_gpio(d->irq); | ||
117 | int port = line >> 3; | ||
118 | int port_mask = 1 << (line & 7); | ||
119 | |||
120 | if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { | ||
121 | gpio_int_type2[port] ^= port_mask; /* switch edge direction */ | ||
122 | ep93xx_gpio_update_int_params(port); | ||
123 | } | ||
124 | |||
125 | __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port])); | ||
126 | } | ||
127 | |||
128 | static void ep93xx_gpio_irq_mask_ack(struct irq_data *d) | ||
129 | { | ||
130 | int line = irq_to_gpio(d->irq); | ||
131 | int port = line >> 3; | ||
132 | int port_mask = 1 << (line & 7); | ||
133 | |||
134 | if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) | ||
135 | gpio_int_type2[port] ^= port_mask; /* switch edge direction */ | ||
136 | |||
137 | gpio_int_unmasked[port] &= ~port_mask; | ||
138 | ep93xx_gpio_update_int_params(port); | ||
139 | |||
140 | __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port])); | ||
141 | } | ||
142 | |||
143 | static void ep93xx_gpio_irq_mask(struct irq_data *d) | ||
144 | { | ||
145 | int line = irq_to_gpio(d->irq); | ||
146 | int port = line >> 3; | ||
147 | |||
148 | gpio_int_unmasked[port] &= ~(1 << (line & 7)); | ||
149 | ep93xx_gpio_update_int_params(port); | ||
150 | } | ||
151 | |||
152 | static void ep93xx_gpio_irq_unmask(struct irq_data *d) | ||
153 | { | ||
154 | int line = irq_to_gpio(d->irq); | ||
155 | int port = line >> 3; | ||
156 | |||
157 | gpio_int_unmasked[port] |= 1 << (line & 7); | ||
158 | ep93xx_gpio_update_int_params(port); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * gpio_int_type1 controls whether the interrupt is level (0) or | ||
163 | * edge (1) triggered, while gpio_int_type2 controls whether it | ||
164 | * triggers on low/falling (0) or high/rising (1). | ||
165 | */ | ||
166 | static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type) | ||
167 | { | ||
168 | const int gpio = irq_to_gpio(d->irq); | ||
169 | const int port = gpio >> 3; | ||
170 | const int port_mask = 1 << (gpio & 7); | ||
171 | irq_flow_handler_t handler; | ||
172 | |||
173 | gpio_direction_input(gpio); | ||
174 | |||
175 | switch (type) { | ||
176 | case IRQ_TYPE_EDGE_RISING: | ||
177 | gpio_int_type1[port] |= port_mask; | ||
178 | gpio_int_type2[port] |= port_mask; | ||
179 | handler = handle_edge_irq; | ||
180 | break; | ||
181 | case IRQ_TYPE_EDGE_FALLING: | ||
182 | gpio_int_type1[port] |= port_mask; | ||
183 | gpio_int_type2[port] &= ~port_mask; | ||
184 | handler = handle_edge_irq; | ||
185 | break; | ||
186 | case IRQ_TYPE_LEVEL_HIGH: | ||
187 | gpio_int_type1[port] &= ~port_mask; | ||
188 | gpio_int_type2[port] |= port_mask; | ||
189 | handler = handle_level_irq; | ||
190 | break; | ||
191 | case IRQ_TYPE_LEVEL_LOW: | ||
192 | gpio_int_type1[port] &= ~port_mask; | ||
193 | gpio_int_type2[port] &= ~port_mask; | ||
194 | handler = handle_level_irq; | ||
195 | break; | ||
196 | case IRQ_TYPE_EDGE_BOTH: | ||
197 | gpio_int_type1[port] |= port_mask; | ||
198 | /* set initial polarity based on current input level */ | ||
199 | if (gpio_get_value(gpio)) | ||
200 | gpio_int_type2[port] &= ~port_mask; /* falling */ | ||
201 | else | ||
202 | gpio_int_type2[port] |= port_mask; /* rising */ | ||
203 | handler = handle_edge_irq; | ||
204 | break; | ||
205 | default: | ||
206 | pr_err("failed to set irq type %d for gpio %d\n", type, gpio); | ||
207 | return -EINVAL; | ||
208 | } | ||
209 | |||
210 | __irq_set_handler_locked(d->irq, handler); | ||
211 | |||
212 | gpio_int_enabled[port] |= port_mask; | ||
213 | |||
214 | ep93xx_gpio_update_int_params(port); | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | static struct irq_chip ep93xx_gpio_irq_chip = { | ||
220 | .name = "GPIO", | ||
221 | .irq_ack = ep93xx_gpio_irq_ack, | ||
222 | .irq_mask_ack = ep93xx_gpio_irq_mask_ack, | ||
223 | .irq_mask = ep93xx_gpio_irq_mask, | ||
224 | .irq_unmask = ep93xx_gpio_irq_unmask, | ||
225 | .irq_set_type = ep93xx_gpio_irq_type, | ||
226 | }; | ||
227 | |||
228 | void __init ep93xx_gpio_init_irq(void) | ||
229 | { | ||
230 | int gpio_irq; | ||
231 | |||
232 | for (gpio_irq = gpio_to_irq(0); | ||
233 | gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) { | ||
234 | irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip, | ||
235 | handle_level_irq); | ||
236 | set_irq_flags(gpio_irq, IRQF_VALID); | ||
237 | } | ||
238 | |||
239 | irq_set_chained_handler(IRQ_EP93XX_GPIO_AB, | ||
240 | ep93xx_gpio_ab_irq_handler); | ||
241 | irq_set_chained_handler(IRQ_EP93XX_GPIO0MUX, | ||
242 | ep93xx_gpio_f_irq_handler); | ||
243 | irq_set_chained_handler(IRQ_EP93XX_GPIO1MUX, | ||
244 | ep93xx_gpio_f_irq_handler); | ||
245 | irq_set_chained_handler(IRQ_EP93XX_GPIO2MUX, | ||
246 | ep93xx_gpio_f_irq_handler); | ||
247 | irq_set_chained_handler(IRQ_EP93XX_GPIO3MUX, | ||
248 | ep93xx_gpio_f_irq_handler); | ||
249 | irq_set_chained_handler(IRQ_EP93XX_GPIO4MUX, | ||
250 | ep93xx_gpio_f_irq_handler); | ||
251 | irq_set_chained_handler(IRQ_EP93XX_GPIO5MUX, | ||
252 | ep93xx_gpio_f_irq_handler); | ||
253 | irq_set_chained_handler(IRQ_EP93XX_GPIO6MUX, | ||
254 | ep93xx_gpio_f_irq_handler); | ||
255 | irq_set_chained_handler(IRQ_EP93XX_GPIO7MUX, | ||
256 | ep93xx_gpio_f_irq_handler); | ||
257 | } | ||
258 | |||
259 | |||
260 | /************************************************************************* | ||
261 | * gpiolib interface for EP93xx on-chip GPIOs | ||
262 | *************************************************************************/ | ||
263 | struct ep93xx_gpio_chip { | ||
264 | struct gpio_chip chip; | ||
265 | |||
266 | void __iomem *data_reg; | ||
267 | void __iomem *data_dir_reg; | ||
268 | }; | ||
269 | |||
270 | #define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip) | ||
271 | |||
272 | static int ep93xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
273 | { | ||
274 | struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); | ||
275 | unsigned long flags; | ||
276 | u8 v; | ||
277 | |||
278 | local_irq_save(flags); | ||
279 | v = __raw_readb(ep93xx_chip->data_dir_reg); | ||
280 | v &= ~(1 << offset); | ||
281 | __raw_writeb(v, ep93xx_chip->data_dir_reg); | ||
282 | local_irq_restore(flags); | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static int ep93xx_gpio_direction_output(struct gpio_chip *chip, | ||
288 | unsigned offset, int val) | ||
289 | { | ||
290 | struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); | ||
291 | unsigned long flags; | ||
292 | int line; | ||
293 | u8 v; | ||
294 | |||
295 | local_irq_save(flags); | ||
296 | |||
297 | /* Set the value */ | ||
298 | v = __raw_readb(ep93xx_chip->data_reg); | ||
299 | if (val) | ||
300 | v |= (1 << offset); | ||
301 | else | ||
302 | v &= ~(1 << offset); | ||
303 | __raw_writeb(v, ep93xx_chip->data_reg); | ||
304 | |||
305 | /* Drive as an output */ | ||
306 | line = chip->base + offset; | ||
307 | if (line <= EP93XX_GPIO_LINE_MAX_IRQ) { | ||
308 | /* Ports A/B/F */ | ||
309 | ep93xx_gpio_int_mask(line); | ||
310 | ep93xx_gpio_update_int_params(line >> 3); | ||
311 | } | ||
312 | |||
313 | v = __raw_readb(ep93xx_chip->data_dir_reg); | ||
314 | v |= (1 << offset); | ||
315 | __raw_writeb(v, ep93xx_chip->data_dir_reg); | ||
316 | |||
317 | local_irq_restore(flags); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static int ep93xx_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
323 | { | ||
324 | struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); | ||
325 | |||
326 | return !!(__raw_readb(ep93xx_chip->data_reg) & (1 << offset)); | ||
327 | } | ||
328 | |||
329 | static void ep93xx_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | ||
330 | { | ||
331 | struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); | ||
332 | unsigned long flags; | ||
333 | u8 v; | ||
334 | |||
335 | local_irq_save(flags); | ||
336 | v = __raw_readb(ep93xx_chip->data_reg); | ||
337 | if (val) | ||
338 | v |= (1 << offset); | ||
339 | else | ||
340 | v &= ~(1 << offset); | ||
341 | __raw_writeb(v, ep93xx_chip->data_reg); | ||
342 | local_irq_restore(flags); | ||
343 | } | ||
344 | |||
345 | static int ep93xx_gpio_set_debounce(struct gpio_chip *chip, | ||
346 | unsigned offset, unsigned debounce) | ||
347 | { | ||
348 | int gpio = chip->base + offset; | ||
349 | int irq = gpio_to_irq(gpio); | ||
350 | |||
351 | if (irq < 0) | ||
352 | return -EINVAL; | ||
353 | |||
354 | ep93xx_gpio_int_debounce(irq, debounce ? true : false); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | #define EP93XX_GPIO_BANK(name, dr, ddr, base_gpio) \ | ||
360 | { \ | ||
361 | .chip = { \ | ||
362 | .label = name, \ | ||
363 | .direction_input = ep93xx_gpio_direction_input, \ | ||
364 | .direction_output = ep93xx_gpio_direction_output, \ | ||
365 | .get = ep93xx_gpio_get, \ | ||
366 | .set = ep93xx_gpio_set, \ | ||
367 | .base = base_gpio, \ | ||
368 | .ngpio = 8, \ | ||
369 | }, \ | ||
370 | .data_reg = EP93XX_GPIO_REG(dr), \ | ||
371 | .data_dir_reg = EP93XX_GPIO_REG(ddr), \ | ||
372 | } | ||
373 | |||
374 | static struct ep93xx_gpio_chip ep93xx_gpio_banks[] = { | ||
375 | EP93XX_GPIO_BANK("A", 0x00, 0x10, 0), | ||
376 | EP93XX_GPIO_BANK("B", 0x04, 0x14, 8), | ||
377 | EP93XX_GPIO_BANK("C", 0x08, 0x18, 40), | ||
378 | EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24), | ||
379 | EP93XX_GPIO_BANK("E", 0x20, 0x24, 32), | ||
380 | EP93XX_GPIO_BANK("F", 0x30, 0x34, 16), | ||
381 | EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48), | ||
382 | EP93XX_GPIO_BANK("H", 0x40, 0x44, 56), | ||
383 | }; | ||
384 | |||
385 | void __init ep93xx_gpio_init(void) | ||
386 | { | ||
387 | int i; | ||
388 | |||
389 | /* Set Ports C, D, E, G, and H for GPIO use */ | ||
390 | ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS | | ||
391 | EP93XX_SYSCON_DEVCFG_GONK | | ||
392 | EP93XX_SYSCON_DEVCFG_EONIDE | | ||
393 | EP93XX_SYSCON_DEVCFG_GONIDE | | ||
394 | EP93XX_SYSCON_DEVCFG_HONIDE); | ||
395 | |||
396 | for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) { | ||
397 | struct gpio_chip *chip = &ep93xx_gpio_banks[i].chip; | ||
398 | |||
399 | /* | ||
400 | * Ports A, B, and F support input debouncing when | ||
401 | * used as interrupts. | ||
402 | */ | ||
403 | if (!strcmp(chip->label, "A") || | ||
404 | !strcmp(chip->label, "B") || | ||
405 | !strcmp(chip->label, "F")) | ||
406 | chip->set_debounce = ep93xx_gpio_set_debounce; | ||
407 | |||
408 | gpiochip_add(chip); | ||
409 | } | ||
410 | } | ||
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 0451d7ac94ac..63022b17014a 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c | |||
@@ -493,7 +493,6 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
493 | ret = request_threaded_irq(client->irq, | 493 | ret = request_threaded_irq(client->irq, |
494 | NULL, | 494 | NULL, |
495 | pca953x_irq_handler, | 495 | pca953x_irq_handler, |
496 | IRQF_TRIGGER_RISING | | ||
497 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 496 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
498 | dev_name(&client->dev), chip); | 497 | dev_name(&client->dev), chip); |
499 | if (ret) { | 498 | if (ret) { |