ar71xx: boost SPI flash read performance
[openwrt.git] / target / linux / lantiq / patches-3.2 / 0056-MIPS-lantiq-make-GPIO3-work-on-AR9.patch
1 From b11a96f2bdf1730fe3fd3be1d0667e20a4eb5bff Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Sat, 13 Aug 2011 13:59:50 +0200
4 Subject: [PATCH 56/70] MIPS: lantiq: make GPIO3 work on AR9
5
6 There are 3 16bit and 1 8bit gpio ports on AR9. The gpio driver needs a hack
7 at 2 places to make the different register layout of the GPIO3 work properly
8 with the driver. Before only GPIO0-2 were supported. As the GPIO number scheme
9 clashes with the new size, we also move the other gpio chips to new offsets.
10
11 Signed-off-by: John Crispin <blogic@openwrt.org>
12 Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
13 ---
14 .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 2 +
15 arch/mips/lantiq/xway/devices.c | 3 +
16 arch/mips/lantiq/xway/gpio.c | 84 ++++++++++++++++----
17 arch/mips/lantiq/xway/gpio_ebu.c | 3 +-
18 arch/mips/lantiq/xway/gpio_stp.c | 3 +-
19 5 files changed, 75 insertions(+), 20 deletions(-)
20
21 diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
22 index d1b8cc8..bfdeb16 100644
23 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
24 +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
25 @@ -126,7 +126,9 @@
26 #define LTQ_GPIO0_BASE_ADDR 0x1E100B10
27 #define LTQ_GPIO1_BASE_ADDR 0x1E100B40
28 #define LTQ_GPIO2_BASE_ADDR 0x1E100B70
29 +#define LTQ_GPIO3_BASE_ADDR 0x1E100BA0
30 #define LTQ_GPIO_SIZE 0x30
31 +#define LTQ_GPIO3_SIZE 0x10
32
33 /* SSC */
34 #define LTQ_SSC_BASE_ADDR 0x1e100800
35 diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
36 index 5efa4f3..e6d45bc 100644
37 --- a/arch/mips/lantiq/xway/devices.c
38 +++ b/arch/mips/lantiq/xway/devices.c
39 @@ -34,6 +34,7 @@ static struct resource ltq_gpio_resource[] = {
40 MEM_RES("gpio0", LTQ_GPIO0_BASE_ADDR, LTQ_GPIO_SIZE),
41 MEM_RES("gpio1", LTQ_GPIO1_BASE_ADDR, LTQ_GPIO_SIZE),
42 MEM_RES("gpio2", LTQ_GPIO2_BASE_ADDR, LTQ_GPIO_SIZE),
43 + MEM_RES("gpio3", LTQ_GPIO3_BASE_ADDR, LTQ_GPIO3_SIZE),
44 };
45
46 void __init ltq_register_gpio(void)
47 @@ -47,6 +48,8 @@ void __init ltq_register_gpio(void)
48 if (ltq_is_ar9() || ltq_is_vr9()) {
49 platform_device_register_simple("ltq_gpio", 2,
50 &ltq_gpio_resource[2], 1);
51 + platform_device_register_simple("ltq_gpio", 3,
52 + &ltq_gpio_resource[3], 1);
53 }
54 }
55
56 diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c
57 index 54ec6c9..375329b 100644
58 --- a/arch/mips/lantiq/xway/gpio.c
59 +++ b/arch/mips/lantiq/xway/gpio.c
60 @@ -23,9 +23,17 @@
61 #define LTQ_GPIO_OD 0x14
62 #define LTQ_GPIO_PUDSEL 0x1C
63 #define LTQ_GPIO_PUDEN 0x20
64 +#define LTQ_GPIO3_OD 0x24
65 +#define LTQ_GPIO3_ALTSEL1 0x24
66 +#define LTQ_GPIO3_PUDSEL 0x28
67 +#define LTQ_GPIO3_PUDEN 0x2C
68
69 +/* PORT3 only has 8 pins and its register layout
70 + is slightly different */
71 #define PINS_PER_PORT 16
72 -#define MAX_PORTS 3
73 +#define PINS_PORT3 8
74 +#define MAX_PORTS 4
75 +#define MAX_PIN 56
76
77 #define ltq_gpio_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p)))
78 #define ltq_gpio_setbit(m, r, p) ltq_w32_mask(0, (1 << p), m + r)
79 @@ -55,7 +63,7 @@ int ltq_gpio_request(struct device *dev, unsigned int pin, unsigned int mux,
80 {
81 int id = 0;
82
83 - if (pin >= (MAX_PORTS * PINS_PER_PORT))
84 + if (pin >= MAX_PIN)
85 return -EINVAL;
86 if (devm_gpio_request(dev, pin, name)) {
87 pr_err("failed to setup lantiq gpio: %s\n", name);
88 @@ -75,12 +83,21 @@ int ltq_gpio_request(struct device *dev, unsigned int pin, unsigned int mux,
89 else
90 ltq_gpio_clearbit(ltq_gpio_port[id].membase,
91 LTQ_GPIO_ALTSEL0, pin);
92 - if (mux & 0x1)
93 - ltq_gpio_setbit(ltq_gpio_port[id].membase,
94 - LTQ_GPIO_ALTSEL1, pin);
95 - else
96 - ltq_gpio_clearbit(ltq_gpio_port[id].membase,
97 - LTQ_GPIO_ALTSEL1, pin);
98 + if (id == 3) {
99 + if (mux & 0x1)
100 + ltq_gpio_setbit(ltq_gpio_port[1].membase,
101 + LTQ_GPIO3_ALTSEL1, pin);
102 + else
103 + ltq_gpio_clearbit(ltq_gpio_port[1].membase,
104 + LTQ_GPIO3_ALTSEL1, pin);
105 + } else {
106 + if (mux & 0x1)
107 + ltq_gpio_setbit(ltq_gpio_port[id].membase,
108 + LTQ_GPIO_ALTSEL1, pin);
109 + else
110 + ltq_gpio_clearbit(ltq_gpio_port[id].membase,
111 + LTQ_GPIO_ALTSEL1, pin);
112 + }
113 return 0;
114 }
115 EXPORT_SYMBOL(ltq_gpio_request);
116 @@ -106,10 +123,19 @@ static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
117 {
118 struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
119
120 - ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
121 + if (chip->ngpio == PINS_PORT3) {
122 + ltq_gpio_clearbit(ltq_gpio_port[0].membase,
123 + LTQ_GPIO3_OD, offset);
124 + ltq_gpio_setbit(ltq_gpio_port[0].membase,
125 + LTQ_GPIO3_PUDSEL, offset);
126 + ltq_gpio_setbit(ltq_gpio_port[0].membase,
127 + LTQ_GPIO3_PUDEN, offset);
128 + } else {
129 + ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
130 + ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
131 + ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
132 + }
133 ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
134 - ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
135 - ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
136
137 return 0;
138 }
139 @@ -119,10 +145,19 @@ static int ltq_gpio_direction_output(struct gpio_chip *chip,
140 {
141 struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
142
143 - ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
144 + if (chip->ngpio == PINS_PORT3) {
145 + ltq_gpio_setbit(ltq_gpio_port[0].membase,
146 + LTQ_GPIO3_OD, offset);
147 + ltq_gpio_clearbit(ltq_gpio_port[0].membase,
148 + LTQ_GPIO3_PUDSEL, offset);
149 + ltq_gpio_clearbit(ltq_gpio_port[0].membase,
150 + LTQ_GPIO3_PUDEN, offset);
151 + } else {
152 + ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
153 + ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
154 + ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
155 + }
156 ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
157 - ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
158 - ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
159 ltq_gpio_set(chip, offset, value);
160
161 return 0;
162 @@ -133,7 +168,11 @@ static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset)
163 struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
164
165 ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset);
166 - ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
167 + if (chip->ngpio == PINS_PORT3)
168 + ltq_gpio_clearbit(ltq_gpio_port[1].membase,
169 + LTQ_GPIO3_ALTSEL1, offset);
170 + else
171 + ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
172 return 0;
173 }
174
175 @@ -146,6 +185,16 @@ static int ltq_gpio_probe(struct platform_device *pdev)
176 pdev->id);
177 return -EINVAL;
178 }
179 +
180 + /* dirty hack - The registers of port3 are not mapped linearly.
181 + Port 3 may only load if Port 1/2 are mapped */
182 + if ((pdev->id == 3) && (!ltq_gpio_port[1].membase
183 + || !ltq_gpio_port[2].membase)) {
184 + dev_err(&pdev->dev,
185 + "ports 1/2 need to be loaded before port 3 works\n");
186 + return -ENOMEM;
187 + }
188 +
189 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
190 if (!res) {
191 dev_err(&pdev->dev, "failed to get memory for gpio port %d\n",
192 @@ -175,7 +224,10 @@ static int ltq_gpio_probe(struct platform_device *pdev)
193 ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set;
194 ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req;
195 ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id;
196 - ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
197 + if (pdev->id == 3)
198 + ltq_gpio_port[pdev->id].chip.ngpio = PINS_PORT3;
199 + else
200 + ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
201 platform_set_drvdata(pdev, &ltq_gpio_port[pdev->id]);
202 return gpiochip_add(&ltq_gpio_port[pdev->id].chip);
203 }
204 diff --git a/arch/mips/lantiq/xway/gpio_ebu.c b/arch/mips/lantiq/xway/gpio_ebu.c
205 index b91c7f1..bc5696b 100644
206 --- a/arch/mips/lantiq/xway/gpio_ebu.c
207 +++ b/arch/mips/lantiq/xway/gpio_ebu.c
208 @@ -61,9 +61,8 @@ static struct gpio_chip ltq_ebu_chip = {
209 .label = "ltq_ebu",
210 .direction_output = ltq_ebu_direction_output,
211 .set = ltq_ebu_set,
212 - .base = 72,
213 + .base = 100,
214 .ngpio = 16,
215 - .can_sleep = 1,
216 .owner = THIS_MODULE,
217 };
218
219 diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c
220 index da91c5e..9610c10 100644
221 --- a/arch/mips/lantiq/xway/gpio_stp.c
222 +++ b/arch/mips/lantiq/xway/gpio_stp.c
223 @@ -74,9 +74,8 @@ static struct gpio_chip ltq_stp_chip = {
224 .label = "ltq_stp",
225 .direction_output = ltq_stp_direction_output,
226 .set = ltq_stp_set,
227 - .base = 48,
228 + .base = 200,
229 .ngpio = 24,
230 - .can_sleep = 1,
231 .owner = THIS_MODULE,
232 };
233
234 --
235 1.7.7.1
236
This page took 0.048352 seconds and 5 git commands to generate.