aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/mach-w90x900/Makefile2
-rw-r--r--arch/arm/mach-w90x900/gpio.c154
-rw-r--r--arch/arm/mach-w90x900/include/mach/gpio.h34
4 files changed, 191 insertions, 1 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a930e5c5672c..013993c6ceea 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -488,6 +488,8 @@ config ARCH_NS9XXX
488config ARCH_W90X900 488config ARCH_W90X900
489 bool "Nuvoton W90X900 CPU" 489 bool "Nuvoton W90X900 CPU"
490 select CPU_ARM926T 490 select CPU_ARM926T
491 select ARCH_REQUIRE_GPIOLIB
492 select GENERIC_GPIO
491 help 493 help
492 Support for Nuvoton (Winbond logic dept.) ARM9 processor,You 494 Support for Nuvoton (Winbond logic dept.) ARM9 processor,You
493 can login www.mcuos.com or www.nuvoton.com to know more. 495 can login www.mcuos.com or www.nuvoton.com to know more.
diff --git a/arch/arm/mach-w90x900/Makefile b/arch/arm/mach-w90x900/Makefile
index 947316a0a52f..6287268cde4c 100644
--- a/arch/arm/mach-w90x900/Makefile
+++ b/arch/arm/mach-w90x900/Makefile
@@ -4,7 +4,7 @@
4 4
5# Object file lists. 5# Object file lists.
6 6
7obj-y := irq.o time.o mfp-w90p910.o 7obj-y := irq.o time.o mfp-w90p910.o gpio.o
8 8
9# W90X900 CPU support files 9# W90X900 CPU support files
10 10
diff --git a/arch/arm/mach-w90x900/gpio.c b/arch/arm/mach-w90x900/gpio.c
new file mode 100644
index 000000000000..c72e0dfa1825
--- /dev/null
+++ b/arch/arm/mach-w90x900/gpio.c
@@ -0,0 +1,154 @@
1/*
2 * linux/arch/arm/mach-w90p910/gpio.c
3 *
4 * Generic w90p910 GPIO handling
5 *
6 * Wan ZongShun <mcuos.com@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/errno.h>
15#include <linux/interrupt.h>
16#include <linux/irq.h>
17#include <linux/debugfs.h>
18#include <linux/seq_file.h>
19#include <linux/kernel.h>
20#include <linux/list.h>
21#include <linux/module.h>
22#include <linux/io.h>
23#include <linux/gpio.h>
24
25#include <mach/hardware.h>
26
27#define GPIO_BASE (W90X900_VA_GPIO)
28#define GPIO_DIR (0x04)
29#define GPIO_OUT (0x08)
30#define GPIO_IN (0x0C)
31#define GROUPINERV (0x10)
32#define GPIO_GPIO(Nb) (0x00000001 << (Nb))
33#define to_w90p910_gpio_chip(c) container_of(c, struct w90p910_gpio_chip, chip)
34
35#define W90P910_GPIO_CHIP(name, base_gpio, nr_gpio) \
36 { \
37 .chip = { \
38 .label = name, \
39 .direction_input = w90p910_dir_input, \
40 .direction_output = w90p910_dir_output, \
41 .get = w90p910_gpio_get, \
42 .set = w90p910_gpio_set, \
43 .base = base_gpio, \
44 .ngpio = nr_gpio, \
45 } \
46 }
47
48struct w90p910_gpio_chip {
49 struct gpio_chip chip;
50 void __iomem *regbase; /* Base of group register*/
51 spinlock_t gpio_lock;
52};
53
54static int w90p910_gpio_get(struct gpio_chip *chip, unsigned offset)
55{
56 struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip);
57 void __iomem *pio = w90p910_gpio->regbase + GPIO_IN;
58 unsigned int regval;
59
60 regval = __raw_readl(pio);
61 regval &= GPIO_GPIO(offset);
62
63 return (regval != 0);
64}
65
66static void w90p910_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
67{
68 struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip);
69 void __iomem *pio = w90p910_gpio->regbase + GPIO_OUT;
70 unsigned int regval;
71 unsigned long flags;
72
73 spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags);
74
75 regval = __raw_readl(pio);
76
77 if (val)
78 regval |= GPIO_GPIO(offset);
79 else
80 regval &= ~GPIO_GPIO(offset);
81
82 __raw_writel(regval, pio);
83
84 spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags);
85}
86
87static int w90p910_dir_input(struct gpio_chip *chip, unsigned offset)
88{
89 struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip);
90 void __iomem *pio = w90p910_gpio->regbase + GPIO_DIR;
91 unsigned int regval;
92 unsigned long flags;
93
94 spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags);
95
96 regval = __raw_readl(pio);
97 regval &= ~GPIO_GPIO(offset);
98 __raw_writel(regval, pio);
99
100 spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags);
101
102 return 0;
103}
104
105static int w90p910_dir_output(struct gpio_chip *chip, unsigned offset, int val)
106{
107 struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip);
108 void __iomem *outreg = w90p910_gpio->regbase + GPIO_OUT;
109 void __iomem *pio = w90p910_gpio->regbase + GPIO_DIR;
110 unsigned int regval;
111 unsigned long flags;
112
113 spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags);
114
115 regval = __raw_readl(pio);
116 regval |= GPIO_GPIO(offset);
117 __raw_writel(regval, pio);
118
119 regval = __raw_readl(outreg);
120
121 if (val)
122 regval |= GPIO_GPIO(offset);
123 else
124 regval &= ~GPIO_GPIO(offset);
125
126 __raw_writel(regval, outreg);
127
128 spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags);
129
130 return 0;
131}
132
133static struct w90p910_gpio_chip w90p910_gpio[] = {
134 W90P910_GPIO_CHIP("GROUPC", 0, 16),
135 W90P910_GPIO_CHIP("GROUPD", 16, 10),
136 W90P910_GPIO_CHIP("GROUPE", 26, 14),
137 W90P910_GPIO_CHIP("GROUPF", 40, 10),
138 W90P910_GPIO_CHIP("GROUPG", 50, 17),
139 W90P910_GPIO_CHIP("GROUPH", 67, 8),
140 W90P910_GPIO_CHIP("GROUPI", 75, 17),
141};
142
143void __init w90p910_init_gpio(int nr_group)
144{
145 unsigned i;
146 struct w90p910_gpio_chip *gpio_chip;
147
148 for (i = 0; i < nr_group; i++) {
149 gpio_chip = &w90p910_gpio[i];
150 spin_lock_init(&gpio_chip->gpio_lock);
151 gpio_chip->regbase = GPIO_BASE + i * GROUPINERV;
152 gpiochip_add(&gpio_chip->chip);
153 }
154}
diff --git a/arch/arm/mach-w90x900/include/mach/gpio.h b/arch/arm/mach-w90x900/include/mach/gpio.h
new file mode 100644
index 000000000000..034da3e390c9
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/gpio.h
@@ -0,0 +1,34 @@
1/*
2 * linux/arch/arm/mach-w90p910/include/mach/gpio.h
3 *
4 * Generic w90p910 GPIO handling
5 *
6 * Wan ZongShun <mcuos.com@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __ASM_ARCH_W90P910_GPIO_H
14#define __ASM_ARCH_W90P910_GPIO_H
15
16#include <mach/hardware.h>
17#include <asm/irq.h>
18#include <asm-generic/gpio.h>
19
20#define gpio_get_value __gpio_get_value
21#define gpio_set_value __gpio_set_value
22#define gpio_cansleep __gpio_cansleep
23
24static inline int gpio_to_irq(unsigned gpio)
25{
26 return gpio;
27}
28
29static inline int irq_to_gpio(unsigned irq)
30{
31 return irq;
32}
33
34#endif