Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 698 lines (620 sloc) 19.144 kB
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
1 /*
c103de2 gpio: reorganize drivers
Grant Likely authored
2 * U300 GPIO module.
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
3 *
4 * Copyright (C) 2007-2009 ST-Ericsson AB
5 * License terms: GNU General Public License (GPL) version 2
6 * This can driver either of the two basic GPIO cores
7 * available in the U300 platforms:
8 * COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0)
9 * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0)
10 * Notice that you also have inline macros in <asm-arch/gpio.h>
11 * Author: Linus Walleij <linus.walleij@stericsson.com>
12 * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
13 *
14 */
15 #include <linux/module.h>
16 #include <linux/interrupt.h>
17 #include <linux/delay.h>
18 #include <linux/errno.h>
19 #include <linux/io.h>
20 #include <linux/clk.h>
21 #include <linux/err.h>
22 #include <linux/platform_device.h>
23 #include <linux/gpio.h>
24
25 /* Reference to GPIO block clock */
26 static struct clk *clk;
27
28 /* Memory resource */
29 static struct resource *memres;
30 static void __iomem *virtbase;
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
31 static struct device *gpiodev;
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
32
33 struct u300_gpio_port {
34 const char *name;
35 int irq;
36 int number;
37 };
38
39
40 static struct u300_gpio_port gpio_ports[] = {
41 {
42 .name = "gpio0",
43 .number = 0,
44 },
45 {
46 .name = "gpio1",
47 .number = 1,
48 },
49 {
50 .name = "gpio2",
51 .number = 2,
52 },
53 #ifdef U300_COH901571_3
54 {
55 .name = "gpio3",
56 .number = 3,
57 },
58 {
59 .name = "gpio4",
60 .number = 4,
61 },
62 #ifdef CONFIG_MACH_U300_BS335
63 {
64 .name = "gpio5",
65 .number = 5,
66 },
67 {
68 .name = "gpio6",
69 .number = 6,
70 },
71 #endif
72 #endif
73
74 };
75
76
77 #ifdef U300_COH901571_3
78
79 /* Default input value */
80 #define DEFAULT_OUTPUT_LOW 0
81 #define DEFAULT_OUTPUT_HIGH 1
82
83 /* GPIO Pull-Up status */
84 #define DISABLE_PULL_UP 0
85 #define ENABLE_PULL_UP 1
86
87 #define GPIO_NOT_USED 0
88 #define GPIO_IN 1
89 #define GPIO_OUT 2
90
91 struct u300_gpio_configuration_data {
92 unsigned char pin_usage;
93 unsigned char default_output_value;
94 unsigned char pull_up;
95 };
96
97 /* Initial configuration */
98 const struct u300_gpio_configuration_data
99 u300_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
100 #ifdef CONFIG_MACH_U300_BS335
101 /* Port 0, pins 0-7 */
102 {
103 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
104 {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
105 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
106 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
107 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
108 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
109 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
110 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
111 },
112 /* Port 1, pins 0-7 */
113 {
114 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
115 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
116 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
117 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
118 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
119 {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
120 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
121 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
122 },
123 /* Port 2, pins 0-7 */
124 {
125 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
126 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
127 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
128 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
129 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
130 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
131 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
132 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
133 },
134 /* Port 3, pins 0-7 */
135 {
136 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
137 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
138 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
139 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
140 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
141 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
142 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
143 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
144 },
145 /* Port 4, pins 0-7 */
146 {
147 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
148 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
149 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
150 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
151 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
152 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
153 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
154 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
155 },
156 /* Port 5, pins 0-7 */
157 {
158 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
159 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
160 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
161 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
162 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
163 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
164 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
165 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
166 },
167 /* Port 6, pind 0-7 */
168 {
169 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
170 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
171 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
172 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
173 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
174 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
175 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
176 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
177 }
178 #endif
179
180 #ifdef CONFIG_MACH_U300_BS365
181 /* Port 0, pins 0-7 */
182 {
183 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
184 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
185 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
186 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
187 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
188 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
189 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
190 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
191 },
192 /* Port 1, pins 0-7 */
193 {
194 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
195 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
196 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
197 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
198 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
199 {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
200 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
201 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
202 },
203 /* Port 2, pins 0-7 */
204 {
205 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
206 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
207 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
208 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
209 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
210 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
211 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
212 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
213 },
214 /* Port 3, pins 0-7 */
215 {
216 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
217 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
218 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
219 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
220 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
221 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
222 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
223 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
224 },
225 /* Port 4, pins 0-7 */
226 {
227 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
228 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
229 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
230 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
231 /* These 4 pins doesn't exist on DB3210 */
232 {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
233 {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
234 {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
235 {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
236 }
237 #endif
238 };
239 #endif
240
241
242 /* No users == we can power down GPIO */
243 static int gpio_users;
244
245 struct gpio_struct {
246 int (*callback)(void *);
247 void *data;
248 int users;
249 };
250
251 static struct gpio_struct gpio_pin[U300_GPIO_MAX];
252
253 /*
254 * Let drivers register callback in order to get notified when there is
255 * an interrupt on the gpio pin
256 */
257 int gpio_register_callback(unsigned gpio, int (*func)(void *arg), void *data)
258 {
259 if (gpio_pin[gpio].callback)
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
260 dev_warn(gpiodev, "%s: WARNING: callback already "
261 "registered for gpio pin#%d\n", __func__, gpio);
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
262 gpio_pin[gpio].callback = func;
263 gpio_pin[gpio].data = data;
264
265 return 0;
266 }
267 EXPORT_SYMBOL(gpio_register_callback);
268
269 int gpio_unregister_callback(unsigned gpio)
270 {
271 if (!gpio_pin[gpio].callback)
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
272 dev_warn(gpiodev, "%s: WARNING: callback already "
273 "unregistered for gpio pin#%d\n", __func__, gpio);
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
274 gpio_pin[gpio].callback = NULL;
275 gpio_pin[gpio].data = NULL;
276
277 return 0;
278 }
279 EXPORT_SYMBOL(gpio_unregister_callback);
280
ee17962 ARM: 5731/2: Fix U300 generic GPIO, remove ifdefs from MMCI v3
Linus Walleij authored
281 /* Non-zero means valid */
282 int gpio_is_valid(int number)
283 {
284 if (number >= 0 &&
285 number < (U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT))
286 return 1;
287 return 0;
288 }
289 EXPORT_SYMBOL(gpio_is_valid);
290
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
291 int gpio_request(unsigned gpio, const char *label)
292 {
293 if (gpio_pin[gpio].users)
294 return -EINVAL;
295 else
296 gpio_pin[gpio].users++;
297
298 gpio_users++;
299
300 return 0;
301 }
302 EXPORT_SYMBOL(gpio_request);
303
304 void gpio_free(unsigned gpio)
305 {
306 gpio_users--;
307 gpio_pin[gpio].users--;
308 if (unlikely(gpio_pin[gpio].users < 0)) {
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
309 dev_warn(gpiodev, "warning: gpio#%d release mismatch\n",
310 gpio);
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
311 gpio_pin[gpio].users = 0;
312 }
313
314 return;
315 }
316 EXPORT_SYMBOL(gpio_free);
317
318 /* This returns zero or nonzero */
319 int gpio_get_value(unsigned gpio)
320 {
321 return readl(virtbase + U300_GPIO_PXPDIR +
322 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) & (1 << (gpio & 0x07));
323 }
324 EXPORT_SYMBOL(gpio_get_value);
325
326 /*
327 * We hope that the compiler will optimize away the unused branch
328 * in case "value" is a constant
329 */
330 void gpio_set_value(unsigned gpio, int value)
331 {
332 u32 val;
333 unsigned long flags;
334
335 local_irq_save(flags);
336 if (value) {
337 /* set */
338 val = readl(virtbase + U300_GPIO_PXPDOR +
339 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
340 & (1 << (gpio & 0x07));
341 writel(val | (1 << (gpio & 0x07)), virtbase +
342 U300_GPIO_PXPDOR +
343 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
344 } else {
345 /* clear */
346 val = readl(virtbase + U300_GPIO_PXPDOR +
347 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
348 & (1 << (gpio & 0x07));
349 writel(val & ~(1 << (gpio & 0x07)), virtbase +
350 U300_GPIO_PXPDOR +
351 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
352 }
353 local_irq_restore(flags);
354 }
355 EXPORT_SYMBOL(gpio_set_value);
356
357 int gpio_direction_input(unsigned gpio)
358 {
359 unsigned long flags;
360 u32 val;
361
362 if (gpio > U300_GPIO_MAX)
363 return -EINVAL;
364
365 local_irq_save(flags);
366 val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
367 U300_GPIO_PORTX_SPACING);
368 /* Mask out this pin*/
369 val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
370 /* This is not needed since it sets the bits to zero.*/
371 /* val |= (U300_GPIO_PXPCR_PIN_MODE_INPUT << (gpio*2)); */
372 writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
373 U300_GPIO_PORTX_SPACING);
374 local_irq_restore(flags);
375 return 0;
376 }
377 EXPORT_SYMBOL(gpio_direction_input);
378
379 int gpio_direction_output(unsigned gpio, int value)
380 {
381 unsigned long flags;
382 u32 val;
383
384 if (gpio > U300_GPIO_MAX)
385 return -EINVAL;
386
387 local_irq_save(flags);
388 val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
389 U300_GPIO_PORTX_SPACING);
390 /* Mask out this pin */
391 val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
392 /*
393 * FIXME: configure for push/pull, open drain or open source per pin
394 * in setup. The current driver will only support push/pull.
395 */
396 val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL
397 << ((gpio & 0x07) << 1));
398 writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
399 U300_GPIO_PORTX_SPACING);
400 gpio_set_value(gpio, value);
401 local_irq_restore(flags);
402 return 0;
403 }
404 EXPORT_SYMBOL(gpio_direction_output);
405
406 /*
407 * Enable an IRQ, edge is rising edge (!= 0) or falling edge (==0).
408 */
409 void enable_irq_on_gpio_pin(unsigned gpio, int edge)
410 {
411 u32 val;
412 unsigned long flags;
413 local_irq_save(flags);
414
415 val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
416 U300_GPIO_PORTX_SPACING);
417 val |= (1 << (gpio & 0x07));
418 writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
419 U300_GPIO_PORTX_SPACING);
420 val = readl(virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
421 U300_GPIO_PORTX_SPACING);
422 if (edge)
423 val |= (1 << (gpio & 0x07));
424 else
425 val &= ~(1 << (gpio & 0x07));
426 writel(val, virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
427 U300_GPIO_PORTX_SPACING);
428 local_irq_restore(flags);
429 }
430 EXPORT_SYMBOL(enable_irq_on_gpio_pin);
431
432 void disable_irq_on_gpio_pin(unsigned gpio)
433 {
434 u32 val;
435 unsigned long flags;
436
437 local_irq_save(flags);
438 val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
439 U300_GPIO_PORTX_SPACING);
440 val &= ~(1 << (gpio & 0x07));
441 writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
442 U300_GPIO_PORTX_SPACING);
443 local_irq_restore(flags);
444 }
445 EXPORT_SYMBOL(disable_irq_on_gpio_pin);
446
447 /* Enable (value == 0) or disable (value == 1) internal pullup */
448 void gpio_pullup(unsigned gpio, int value)
449 {
450 u32 val;
451 unsigned long flags;
452
453 local_irq_save(flags);
454 if (value) {
455 val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
456 U300_GPIO_PORTX_SPACING);
457 writel(val | (1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
458 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
459 } else {
460 val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
461 U300_GPIO_PORTX_SPACING);
462 writel(val & ~(1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
463 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
464 }
465 local_irq_restore(flags);
466 }
467 EXPORT_SYMBOL(gpio_pullup);
468
469 static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
470 {
471 struct u300_gpio_port *port = dev_id;
472 u32 val;
473 int pin;
474
475 /* Read event register */
476 val = readl(virtbase + U300_GPIO_PXIEV + port->number *
477 U300_GPIO_PORTX_SPACING);
478 /* Mask with enable register */
479 val &= readl(virtbase + U300_GPIO_PXIEV + port->number *
480 U300_GPIO_PORTX_SPACING);
481 /* Mask relevant bits */
482 val &= U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK;
483 /* ACK IRQ (clear event) */
484 writel(val, virtbase + U300_GPIO_PXIEV + port->number *
485 U300_GPIO_PORTX_SPACING);
486 /* Print message */
487 while (val != 0) {
488 unsigned gpio;
489
490 pin = __ffs(val);
491 /* mask off this pin */
492 val &= ~(1 << pin);
493 gpio = (port->number << 3) + pin;
494
495 if (gpio_pin[gpio].callback)
496 (void)gpio_pin[gpio].callback(gpio_pin[gpio].data);
497 else
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
498 dev_dbg(gpiodev, "stray GPIO IRQ on line %d\n",
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
499 gpio);
500 }
501 return IRQ_HANDLED;
502 }
503
504 static void gpio_set_initial_values(void)
505 {
506 #ifdef U300_COH901571_3
507 int i, j;
508 unsigned long flags;
509 u32 val;
510
511 /* Write default values to all pins */
512 for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
513 val = 0;
514 for (j = 0; j < 8; j++)
515 val |= (u32) (u300_gpio_config[i][j].default_output_value != DEFAULT_OUTPUT_LOW) << j;
516 local_irq_save(flags);
517 writel(val, virtbase + U300_GPIO_PXPDOR + i * U300_GPIO_PORTX_SPACING);
518 local_irq_restore(flags);
519 }
520
521 /*
522 * Put all pins that are set to either 'GPIO_OUT' or 'GPIO_NOT_USED'
421f91d fix typos concerning "initiali[zs]e"
Uwe Kleine-König authored
523 * to output and 'GPIO_IN' to input for each port. And initialize
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
524 * default value on outputs.
525 */
526 for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
527 for (j = 0; j < U300_GPIO_PINS_PER_PORT; j++) {
528 local_irq_save(flags);
529 val = readl(virtbase + U300_GPIO_PXPCR +
530 i * U300_GPIO_PORTX_SPACING);
531 /* Mask out this pin */
532 val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << (j << 1));
533
534 if (u300_gpio_config[i][j].pin_usage != GPIO_IN)
535 val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL << (j << 1));
536 writel(val, virtbase + U300_GPIO_PXPCR +
537 i * U300_GPIO_PORTX_SPACING);
538 local_irq_restore(flags);
539 }
540 }
541
542 /* Enable or disable the internal pull-ups in the GPIO ASIC block */
543 for (i = 0; i < U300_GPIO_MAX; i++) {
544 val = 0;
545 for (j = 0; j < 8; j++)
fcfadca @RoelKluin ARM: 5956/1: misplaced parentheses
RoelKluin authored
546 val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP) << j);
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
547 local_irq_save(flags);
548 writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING);
549 local_irq_restore(flags);
550 }
551 #endif
552 }
553
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
554 static int __init gpio_probe(struct platform_device *pdev)
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
555 {
556 u32 val;
557 int err = 0;
558 int i;
559 int num_irqs;
560
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
561 gpiodev = &pdev->dev;
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
562 memset(gpio_pin, 0, sizeof(gpio_pin));
563
564 /* Get GPIO clock */
565 clk = clk_get(&pdev->dev, NULL);
566 if (IS_ERR(clk)) {
567 err = PTR_ERR(clk);
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
568 dev_err(gpiodev, "could not get GPIO clock\n");
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
569 goto err_no_clk;
570 }
571 err = clk_enable(clk);
572 if (err) {
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
573 dev_err(gpiodev, "could not enable GPIO clock\n");
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
574 goto err_no_clk_enable;
575 }
576
577 memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
578 if (!memres)
579 goto err_no_resource;
580
28f65c1 @JoePerches treewide: Convert uses of struct resource to resource_size(ptr)
JoePerches authored
581 if (!request_mem_region(memres->start, resource_size(memres),
582 "GPIO Controller")) {
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
583 err = -ENODEV;
584 goto err_no_ioregion;
585 }
586
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
587 virtbase = ioremap(memres->start, resource_size(memres));
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
588 if (!virtbase) {
589 err = -ENOMEM;
590 goto err_no_ioremap;
591 }
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
592 dev_info(gpiodev, "remapped 0x%08x to %p\n",
593 memres->start, virtbase);
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
594
595 #ifdef U300_COH901335
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
596 dev_info(gpiodev, "initializing GPIO Controller COH 901 335\n");
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
597 /* Turn on the GPIO block */
598 writel(U300_GPIO_CR_BLOCK_CLOCK_ENABLE, virtbase + U300_GPIO_CR);
599 #endif
600
601 #ifdef U300_COH901571_3
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
602 dev_info(gpiodev, "initializing GPIO Controller COH 901 571/3\n");
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
603 val = readl(virtbase + U300_GPIO_CR);
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
604 dev_info(gpiodev, "COH901571/3 block version: %d, " \
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
605 "number of cores: %d\n",
606 ((val & 0x0000FE00) >> 9),
607 ((val & 0x000001FC) >> 2));
608 writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, virtbase + U300_GPIO_CR);
609 #endif
610
611 gpio_set_initial_values();
612
613 for (num_irqs = 0 ; num_irqs < U300_GPIO_NUM_PORTS; num_irqs++) {
614
615 gpio_ports[num_irqs].irq =
616 platform_get_irq_byname(pdev,
617 gpio_ports[num_irqs].name);
618
619 err = request_irq(gpio_ports[num_irqs].irq,
620 gpio_irq_handler, IRQF_DISABLED,
621 gpio_ports[num_irqs].name,
622 &gpio_ports[num_irqs]);
623 if (err) {
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
624 dev_err(gpiodev, "cannot allocate IRQ for %s!\n",
625 gpio_ports[num_irqs].name);
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
626 goto err_no_irq;
627 }
628 /* Turns off PortX_irq_force */
629 writel(0x0, virtbase + U300_GPIO_PXIFR +
630 num_irqs * U300_GPIO_PORTX_SPACING);
631 }
632
633 return 0;
634
635 err_no_irq:
636 for (i = 0; i < num_irqs; i++)
637 free_irq(gpio_ports[i].irq, &gpio_ports[i]);
638 iounmap(virtbase);
639 err_no_ioremap:
28f65c1 @JoePerches treewide: Convert uses of struct resource to resource_size(ptr)
JoePerches authored
640 release_mem_region(memres->start, resource_size(memres));
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
641 err_no_ioregion:
642 err_no_resource:
643 clk_disable(clk);
644 err_no_clk_enable:
645 clk_put(clk);
646 err_no_clk:
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
647 dev_info(gpiodev, "module ERROR:%d\n", err);
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
648 return err;
649 }
650
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
651 static int __exit gpio_remove(struct platform_device *pdev)
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
652 {
653 int i;
654
655 /* Turn off the GPIO block */
656 writel(0x00000000U, virtbase + U300_GPIO_CR);
657 for (i = 0 ; i < U300_GPIO_NUM_PORTS; i++)
658 free_irq(gpio_ports[i].irq, &gpio_ports[i]);
659 iounmap(virtbase);
28f65c1 @JoePerches treewide: Convert uses of struct resource to resource_size(ptr)
JoePerches authored
660 release_mem_region(memres->start, resource_size(memres));
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
661 clk_disable(clk);
662 clk_put(clk);
663 return 0;
664 }
665
666 static struct platform_driver gpio_driver = {
667 .driver = {
668 .name = "u300-gpio",
669 },
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
670 .remove = __exit_p(gpio_remove),
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
671 };
672
673
674 static int __init u300_gpio_init(void)
675 {
f7a9a4d [ARM] 5510/1: U300 GPIO debug and init fixes
Linus Walleij authored
676 return platform_driver_probe(&gpio_driver, gpio_probe);
bd41b99 [ARM] 5471/2: U300 GPIO and PADMUX support
Linus Walleij authored
677 }
678
679 static void __exit u300_gpio_exit(void)
680 {
681 platform_driver_unregister(&gpio_driver);
682 }
683
684 arch_initcall(u300_gpio_init);
685 module_exit(u300_gpio_exit);
686
687 MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
688
689 #ifdef U300_COH901571_3
690 MODULE_DESCRIPTION("ST-Ericsson AB COH 901 571/3 GPIO driver");
691 #endif
692
693 #ifdef U300_COH901335
694 MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335 GPIO driver");
695 #endif
696
697 MODULE_LICENSE("GPL");
Something went wrong with that request. Please try again.