aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Mallon <ryan@bluewatersys.com>2009-02-10 15:02:08 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-02-12 05:45:08 -0500
commitf373e8c0639f1720d2d0fe414990f504e113c2ba (patch)
tree2b903b23117f9f94734f4eeec471139504452cb2
parentb7eb1a5ed50c6f622664bb8a7113313fa8b6dd1e (diff)
[ARM] 5373/2: Add gpiolib support to AT91
Add support for gpiolib, including debugfs output, to the AT91 family. The at91_get/set_gpio_value calls still exist since they are used by the atmel serial driver. Signed-off-by: Ryan Mallon <ryan@bluewatersys.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/mach-at91/generic.h3
-rw-r--r--arch/arm/mach-at91/gpio.c276
-rw-r--r--arch/arm/mach-at91/include/mach/gpio.h28
4 files changed, 161 insertions, 147 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index dbfdf87f993f..5e0c5ab9560d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -241,6 +241,7 @@ config ARCH_VERSATILE
241config ARCH_AT91 241config ARCH_AT91
242 bool "Atmel AT91" 242 bool "Atmel AT91"
243 select GENERIC_GPIO 243 select GENERIC_GPIO
244 select ARCH_REQUIRE_GPIOLIB
244 select HAVE_CLK 245 select HAVE_CLK
245 help 246 help
246 This enables support for systems based on the Atmel AT91RM9200, 247 This enables support for systems based on the Atmel AT91RM9200,
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 7b9ce7a336b0..b5daf7f5e011 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -47,9 +47,6 @@ extern void at91_irq_resume(void);
47#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ 47#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */
48 48
49struct at91_gpio_bank { 49struct at91_gpio_bank {
50 unsigned chipbase; /* bank's first GPIO number */
51 void __iomem *regbase; /* base of register bank */
52 struct at91_gpio_bank *next; /* bank sharing same IRQ/clock/... */
53 unsigned short id; /* peripheral ID */ 50 unsigned short id; /* peripheral ID */
54 unsigned long offset; /* offset from system peripheral base */ 51 unsigned long offset; /* offset from system peripheral base */
55 struct clk *clock; /* associated clock */ 52 struct clk *clock; /* associated clock */
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 9b0447c3d59b..028e4f7a88be 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -24,19 +24,59 @@
24#include <mach/at91_pio.h> 24#include <mach/at91_pio.h>
25#include <mach/gpio.h> 25#include <mach/gpio.h>
26 26
27#include <asm/gpio.h>
28
27#include "generic.h" 29#include "generic.h"
28 30
31struct at91_gpio_chip {
32 struct gpio_chip chip;
33 struct at91_gpio_chip *next; /* Bank sharing same clock */
34 struct at91_gpio_bank *bank; /* Bank definition */
35 void __iomem *regbase; /* Base of register bank */
36};
29 37
30static struct at91_gpio_bank *gpio; 38#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip)
31static int gpio_banks; 39
40static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip);
41static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val);
42static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset);
43static int at91_gpiolib_direction_output(struct gpio_chip *chip,
44 unsigned offset, int val);
45static int at91_gpiolib_direction_input(struct gpio_chip *chip,
46 unsigned offset);
47static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset);
48
49#define AT91_GPIO_CHIP(name, base_gpio, nr_gpio) \
50 { \
51 .chip = { \
52 .label = name, \
53 .request = at91_gpiolib_request, \
54 .direction_input = at91_gpiolib_direction_input, \
55 .direction_output = at91_gpiolib_direction_output, \
56 .get = at91_gpiolib_get, \
57 .set = at91_gpiolib_set, \
58 .dbg_show = at91_gpiolib_dbg_show, \
59 .base = base_gpio, \
60 .ngpio = nr_gpio, \
61 }, \
62 }
32 63
64static struct at91_gpio_chip gpio_chip[] = {
65 AT91_GPIO_CHIP("A", 0x00 + PIN_BASE, 32),
66 AT91_GPIO_CHIP("B", 0x20 + PIN_BASE, 32),
67 AT91_GPIO_CHIP("C", 0x40 + PIN_BASE, 32),
68 AT91_GPIO_CHIP("D", 0x60 + PIN_BASE, 32),
69 AT91_GPIO_CHIP("E", 0x80 + PIN_BASE, 32),
70};
71
72static int gpio_banks;
33 73
34static inline void __iomem *pin_to_controller(unsigned pin) 74static inline void __iomem *pin_to_controller(unsigned pin)
35{ 75{
36 pin -= PIN_BASE; 76 pin -= PIN_BASE;
37 pin /= 32; 77 pin /= 32;
38 if (likely(pin < gpio_banks)) 78 if (likely(pin < gpio_banks))
39 return gpio[pin].regbase; 79 return gpio_chip[pin].regbase;
40 80
41 return NULL; 81 return NULL;
42} 82}
@@ -197,39 +237,6 @@ int __init_or_module at91_set_multi_drive(unsigned pin, int is_on)
197} 237}
198EXPORT_SYMBOL(at91_set_multi_drive); 238EXPORT_SYMBOL(at91_set_multi_drive);
199 239
200/*--------------------------------------------------------------------------*/
201
202/* new-style GPIO calls; these expect at91_set_GPIO_periph to have been
203 * called, and maybe at91_set_multi_drive() for putout pins.
204 */
205
206int gpio_direction_input(unsigned pin)
207{
208 void __iomem *pio = pin_to_controller(pin);
209 unsigned mask = pin_to_mask(pin);
210
211 if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
212 return -EINVAL;
213 __raw_writel(mask, pio + PIO_ODR);
214 return 0;
215}
216EXPORT_SYMBOL(gpio_direction_input);
217
218int gpio_direction_output(unsigned pin, int value)
219{
220 void __iomem *pio = pin_to_controller(pin);
221 unsigned mask = pin_to_mask(pin);
222
223 if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
224 return -EINVAL;
225 __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
226 __raw_writel(mask, pio + PIO_OER);
227 return 0;
228}
229EXPORT_SYMBOL(gpio_direction_output);
230
231/*--------------------------------------------------------------------------*/
232
233/* 240/*
234 * assuming the pin is muxed as a gpio output, set its value. 241 * assuming the pin is muxed as a gpio output, set its value.
235 */ 242 */
@@ -282,7 +289,7 @@ static int gpio_irq_set_wake(unsigned pin, unsigned state)
282 else 289 else
283 wakeups[bank] &= ~mask; 290 wakeups[bank] &= ~mask;
284 291
285 set_irq_wake(gpio[bank].id, state); 292 set_irq_wake(gpio_chip[bank].bank->id, state);
286 293
287 return 0; 294 return 0;
288} 295}
@@ -292,14 +299,14 @@ void at91_gpio_suspend(void)
292 int i; 299 int i;
293 300
294 for (i = 0; i < gpio_banks; i++) { 301 for (i = 0; i < gpio_banks; i++) {
295 void __iomem *pio = gpio[i].regbase; 302 void __iomem *pio = gpio_chip[i].regbase;
296 303
297 backups[i] = __raw_readl(pio + PIO_IMR); 304 backups[i] = __raw_readl(pio + PIO_IMR);
298 __raw_writel(backups[i], pio + PIO_IDR); 305 __raw_writel(backups[i], pio + PIO_IDR);
299 __raw_writel(wakeups[i], pio + PIO_IER); 306 __raw_writel(wakeups[i], pio + PIO_IER);
300 307
301 if (!wakeups[i]) 308 if (!wakeups[i])
302 clk_disable(gpio[i].clock); 309 clk_disable(gpio_chip[i].bank->clock);
303 else { 310 else {
304#ifdef CONFIG_PM_DEBUG 311#ifdef CONFIG_PM_DEBUG
305 printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); 312 printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]);
@@ -313,10 +320,10 @@ void at91_gpio_resume(void)
313 int i; 320 int i;
314 321
315 for (i = 0; i < gpio_banks; i++) { 322 for (i = 0; i < gpio_banks; i++) {
316 void __iomem *pio = gpio[i].regbase; 323 void __iomem *pio = gpio_chip[i].regbase;
317 324
318 if (!wakeups[i]) 325 if (!wakeups[i])
319 clk_enable(gpio[i].clock); 326 clk_enable(gpio_chip[i].bank->clock);
320 327
321 __raw_writel(wakeups[i], pio + PIO_IDR); 328 __raw_writel(wakeups[i], pio + PIO_IDR);
322 __raw_writel(backups[i], pio + PIO_IER); 329 __raw_writel(backups[i], pio + PIO_IER);
@@ -380,12 +387,12 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
380{ 387{
381 unsigned pin; 388 unsigned pin;
382 struct irq_desc *gpio; 389 struct irq_desc *gpio;
383 struct at91_gpio_bank *bank; 390 struct at91_gpio_chip *at91_gpio;
384 void __iomem *pio; 391 void __iomem *pio;
385 u32 isr; 392 u32 isr;
386 393
387 bank = get_irq_chip_data(irq); 394 at91_gpio = get_irq_chip_data(irq);
388 pio = bank->regbase; 395 pio = at91_gpio->regbase;
389 396
390 /* temporarily mask (level sensitive) parent IRQ */ 397 /* temporarily mask (level sensitive) parent IRQ */
391 desc->chip->ack(irq); 398 desc->chip->ack(irq);
@@ -396,14 +403,14 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
396 */ 403 */
397 isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR); 404 isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR);
398 if (!isr) { 405 if (!isr) {
399 if (!bank->next) 406 if (!at91_gpio->next)
400 break; 407 break;
401 bank = bank->next; 408 at91_gpio = at91_gpio->next;
402 pio = bank->regbase; 409 pio = at91_gpio->regbase;
403 continue; 410 continue;
404 } 411 }
405 412
406 pin = bank->chipbase; 413 pin = at91_gpio->chip.base;
407 gpio = &irq_desc[pin]; 414 gpio = &irq_desc[pin];
408 415
409 while (isr) { 416 while (isr) {
@@ -430,66 +437,6 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
430 437
431/*--------------------------------------------------------------------------*/ 438/*--------------------------------------------------------------------------*/
432 439
433#ifdef CONFIG_DEBUG_FS
434
435static int at91_gpio_show(struct seq_file *s, void *unused)
436{
437 int bank, j;
438
439 /* print heading */
440 seq_printf(s, "Pin\t");
441 for (bank = 0; bank < gpio_banks; bank++) {
442 seq_printf(s, "PIO%c\t", 'A' + bank);
443 };
444 seq_printf(s, "\n\n");
445
446 /* print pin status */
447 for (j = 0; j < 32; j++) {
448 seq_printf(s, "%i:\t", j);
449
450 for (bank = 0; bank < gpio_banks; bank++) {
451 unsigned pin = PIN_BASE + (32 * bank) + j;
452 void __iomem *pio = pin_to_controller(pin);
453 unsigned mask = pin_to_mask(pin);
454
455 if (__raw_readl(pio + PIO_PSR) & mask)
456 seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0");
457 else
458 seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A");
459
460 seq_printf(s, "\t");
461 }
462
463 seq_printf(s, "\n");
464 }
465
466 return 0;
467}
468
469static int at91_gpio_open(struct inode *inode, struct file *file)
470{
471 return single_open(file, at91_gpio_show, NULL);
472}
473
474static const struct file_operations at91_gpio_operations = {
475 .open = at91_gpio_open,
476 .read = seq_read,
477 .llseek = seq_lseek,
478 .release = single_release,
479};
480
481static int __init at91_gpio_debugfs_init(void)
482{
483 /* /sys/kernel/debug/at91_gpio */
484 (void) debugfs_create_file("at91_gpio", S_IFREG | S_IRUGO, NULL, NULL, &at91_gpio_operations);
485 return 0;
486}
487postcore_initcall(at91_gpio_debugfs_init);
488
489#endif
490
491/*--------------------------------------------------------------------------*/
492
493/* This lock class tells lockdep that GPIO irqs are in a different 440/* This lock class tells lockdep that GPIO irqs are in a different
494 * category than their parents, so it won't report false recursion. 441 * category than their parents, so it won't report false recursion.
495 */ 442 */
@@ -501,20 +448,20 @@ static struct lock_class_key gpio_lock_class;
501void __init at91_gpio_irq_setup(void) 448void __init at91_gpio_irq_setup(void)
502{ 449{
503 unsigned pioc, pin; 450 unsigned pioc, pin;
504 struct at91_gpio_bank *this, *prev; 451 struct at91_gpio_chip *this, *prev;
505 452
506 for (pioc = 0, pin = PIN_BASE, this = gpio, prev = NULL; 453 for (pioc = 0, pin = PIN_BASE, this = gpio_chip, prev = NULL;
507 pioc++ < gpio_banks; 454 pioc++ < gpio_banks;
508 prev = this, this++) { 455 prev = this, this++) {
509 unsigned id = this->id; 456 unsigned id = this->bank->id;
510 unsigned i; 457 unsigned i;
511 458
512 /* enable PIO controller's clock */ 459 /* enable PIO controller's clock */
513 clk_enable(this->clock); 460 clk_enable(this->bank->clock);
514 461
515 __raw_writel(~0, this->regbase + PIO_IDR); 462 __raw_writel(~0, this->regbase + PIO_IDR);
516 463
517 for (i = 0, pin = this->chipbase; i < 32; i++, pin++) { 464 for (i = 0, pin = this->chip.base; i < 32; i++, pin++) {
518 lockdep_set_class(&irq_desc[pin].lock, &gpio_lock_class); 465 lockdep_set_class(&irq_desc[pin].lock, &gpio_lock_class);
519 466
520 /* 467 /*
@@ -539,25 +486,114 @@ void __init at91_gpio_irq_setup(void)
539 pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); 486 pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks);
540} 487}
541 488
489/* gpiolib support */
490static int at91_gpiolib_direction_input(struct gpio_chip *chip,
491 unsigned offset)
492{
493 struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
494 void __iomem *pio = at91_gpio->regbase;
495 unsigned mask = 1 << offset;
496
497 __raw_writel(mask, pio + PIO_ODR);
498 return 0;
499}
500
501static int at91_gpiolib_direction_output(struct gpio_chip *chip,
502 unsigned offset, int val)
503{
504 struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
505 void __iomem *pio = at91_gpio->regbase;
506 unsigned mask = 1 << offset;
507
508 __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR));
509 __raw_writel(mask, pio + PIO_OER);
510 return 0;
511}
512
513static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset)
514{
515 struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
516 void __iomem *pio = at91_gpio->regbase;
517 unsigned mask = 1 << offset;
518 u32 pdsr;
519
520 pdsr = __raw_readl(pio + PIO_PDSR);
521 return (pdsr & mask) != 0;
522}
523
524static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
525{
526 struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
527 void __iomem *pio = at91_gpio->regbase;
528 unsigned mask = 1 << offset;
529
530 __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR));
531}
532
533static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset)
534{
535 unsigned pin = chip->base + offset;
536 void __iomem *pio = pin_to_controller(pin);
537 unsigned mask = pin_to_mask(pin);
538
539 /* Cannot request GPIOs that are in alternate function mode */
540 if (!(__raw_readl(pio + PIO_PSR) & mask))
541 return -EPERM;
542
543 return 0;
544}
545
546static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
547{
548 int i;
549
550 for (i = 0; i < chip->ngpio; i++) {
551 unsigned pin = chip->base + i;
552 void __iomem *pio = pin_to_controller(pin);
553 unsigned mask = pin_to_mask(pin);
554 const char *gpio_label;
555
556 gpio_label = gpiochip_is_requested(chip, i);
557 if (gpio_label) {
558 seq_printf(s, "[%s] GPIO%s%d: ",
559 gpio_label, chip->label, i);
560 if (__raw_readl(pio + PIO_PSR) & mask)
561 seq_printf(s, "[gpio] %s\n",
562 at91_get_gpio_value(pin) ?
563 "set" : "clear");
564 else
565 seq_printf(s, "[periph %s]\n",
566 __raw_readl(pio + PIO_ABSR) &
567 mask ? "B" : "A");
568 }
569 }
570}
571
542/* 572/*
543 * Called from the processor-specific init to enable GPIO pin support. 573 * Called from the processor-specific init to enable GPIO pin support.
544 */ 574 */
545void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) 575void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
546{ 576{
547 unsigned i; 577 unsigned i;
548 struct at91_gpio_bank *last; 578 struct at91_gpio_chip *at91_gpio, *last = NULL;
549 579
550 BUG_ON(nr_banks > MAX_GPIO_BANKS); 580 BUG_ON(nr_banks > MAX_GPIO_BANKS);
551 581
552 gpio = data;
553 gpio_banks = nr_banks; 582 gpio_banks = nr_banks;
554 583
555 for (i = 0, last = NULL; i < nr_banks; i++, last = data, data++) { 584 for (i = 0; i < nr_banks; i++) {
556 data->chipbase = PIN_BASE + i * 32; 585 at91_gpio = &gpio_chip[i];
557 data->regbase = data->offset + (void __iomem *)AT91_VA_BASE_SYS; 586
587 at91_gpio->bank = &data[i];
588 at91_gpio->chip.base = PIN_BASE + i * 32;
589 at91_gpio->regbase = at91_gpio->bank->offset +
590 (void __iomem *)AT91_VA_BASE_SYS;
558 591
559 /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ 592 /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
560 if (last && last->id == data->id) 593 if (last && last->bank->id == at91_gpio->bank->id)
561 last->next = data; 594 last->next = at91_gpio;
595 last = at91_gpio;
596
597 gpiochip_add(&at91_gpio->chip);
562 } 598 }
563} 599}
diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h
index bffa6741a751..04c91e31c9c5 100644
--- a/arch/arm/mach-at91/include/mach/gpio.h
+++ b/arch/arm/mach-at91/include/mach/gpio.h
@@ -213,32 +213,12 @@ extern void at91_gpio_resume(void);
213 */ 213 */
214 214
215#include <asm/errno.h> 215#include <asm/errno.h>
216
217static inline int gpio_request(unsigned gpio, const char *label)
218{
219 return 0;
220}
221
222static inline void gpio_free(unsigned gpio)
223{
224 might_sleep();
225}
226
227extern int gpio_direction_input(unsigned gpio);
228extern int gpio_direction_output(unsigned gpio, int value);
229
230static inline int gpio_get_value(unsigned gpio)
231{
232 return at91_get_gpio_value(gpio);
233}
234
235static inline void gpio_set_value(unsigned gpio, int value)
236{
237 at91_set_gpio_value(gpio, value);
238}
239
240#include <asm-generic/gpio.h> /* cansleep wrappers */ 216#include <asm-generic/gpio.h> /* cansleep wrappers */
241 217
218#define gpio_get_value __gpio_get_value
219#define gpio_set_value __gpio_set_value
220#define gpio_cansleep __gpio_cansleep
221
242static inline int gpio_to_irq(unsigned gpio) 222static inline int gpio_to_irq(unsigned gpio)
243{ 223{
244 return gpio; 224 return gpio;