package/dropbear: fix segfault with remote port forwarding (closes: #10339)
[openwrt.git] / target / linux / lantiq / patches-3.0 / 0012-MIPS-lantiq-adds-GPIO3-support-on-AR9.patch
1 From 6b5e2ee7c8f9722d59213f17d423b3f90d80f822 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 12/24] MIPS: lantiq: adds GPIO3 support 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 | 62 ++++++++++++++++----
17 arch/mips/lantiq/xway/gpio_ebu.c | 3 +-
18 arch/mips/lantiq/xway/gpio_stp.c | 3 +-
19 5 files changed, 57 insertions(+), 16 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 da8ff95..421768e 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 @@ -113,7 +113,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 9bacaa8..b7efac5 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 a321451..2c48c17 100644
58 --- a/arch/mips/lantiq/xway/gpio.c
59 +++ b/arch/mips/lantiq/xway/gpio.c
60 @@ -21,9 +21,15 @@
61 #define LTQ_GPIO_ALTSEL0 0x0C
62 #define LTQ_GPIO_ALTSEL1 0x10
63 #define LTQ_GPIO_OD 0x14
64 +#define LTQ_GPIO3_OD 0x24
65 +#define LTQ_GPIO3_ALTSEL1 0x24
66
67 +/* PORT3 only has 8 pins and its register layout
68 + is slightly different */
69 #define PINS_PER_PORT 16
70 -#define MAX_PORTS 3
71 +#define PINS_PORT3 8
72 +#define MAX_PORTS 4
73 +#define MAX_PIN 56
74
75 #define ltq_gpio_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p)))
76 #define ltq_gpio_setbit(m, r, p) ltq_w32_mask(0, (1 << p), m + r)
77 @@ -53,7 +59,7 @@ int ltq_gpio_request(unsigned int pin, unsigned int alt0,
78 {
79 int id = 0;
80
81 - if (pin >= (MAX_PORTS * PINS_PER_PORT))
82 + if (pin >= MAX_PIN)
83 return -EINVAL;
84 if (gpio_request(pin, name)) {
85 pr_err("failed to setup lantiq gpio: %s\n", name);
86 @@ -73,12 +79,21 @@ int ltq_gpio_request(unsigned int pin, unsigned int alt0,
87 else
88 ltq_gpio_clearbit(ltq_gpio_port[id].membase,
89 LTQ_GPIO_ALTSEL0, pin);
90 - if (alt1)
91 - ltq_gpio_setbit(ltq_gpio_port[id].membase,
92 - LTQ_GPIO_ALTSEL1, pin);
93 - else
94 - ltq_gpio_clearbit(ltq_gpio_port[id].membase,
95 - LTQ_GPIO_ALTSEL1, pin);
96 + if (id == 3) {
97 + if (alt1)
98 + ltq_gpio_setbit(ltq_gpio_port[1].membase,
99 + LTQ_GPIO3_ALTSEL1, pin);
100 + else
101 + ltq_gpio_clearbit(ltq_gpio_port[1].membase,
102 + LTQ_GPIO3_ALTSEL1, pin);
103 + } else {
104 + if (alt1)
105 + ltq_gpio_setbit(ltq_gpio_port[id].membase,
106 + LTQ_GPIO_ALTSEL1, pin);
107 + else
108 + ltq_gpio_clearbit(ltq_gpio_port[id].membase,
109 + LTQ_GPIO_ALTSEL1, pin);
110 + }
111 return 0;
112 }
113 EXPORT_SYMBOL(ltq_gpio_request);
114 @@ -104,7 +119,11 @@ static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
115 {
116 struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
117
118 - ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
119 + if (chip->ngpio == PINS_PORT3)
120 + ltq_gpio_clearbit(ltq_gpio_port[0].membase,
121 + LTQ_GPIO3_OD, offset);
122 + else
123 + ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
124 ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
125
126 return 0;
127 @@ -115,7 +134,10 @@ static int ltq_gpio_direction_output(struct gpio_chip *chip,
128 {
129 struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
130
131 - ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
132 + if (chip->ngpio == PINS_PORT3)
133 + ltq_gpio_setbit(ltq_gpio_port[0].membase, LTQ_GPIO3_OD, offset);
134 + else
135 + ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
136 ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
137 ltq_gpio_set(chip, offset, value);
138
139 @@ -127,7 +149,11 @@ static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset)
140 struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
141
142 ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset);
143 - ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
144 + if (chip->ngpio == PINS_PORT3)
145 + ltq_gpio_clearbit(ltq_gpio_port[1].membase,
146 + LTQ_GPIO3_ALTSEL1, offset);
147 + else
148 + ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
149 return 0;
150 }
151
152 @@ -140,6 +166,15 @@ static int ltq_gpio_probe(struct platform_device *pdev)
153 pdev->id);
154 return -EINVAL;
155 }
156 +
157 + /* dirty hack - The registers of port3 are not mapped linearly.
158 + Port 3 may only load if Port 1/2 are mapped */
159 + if ((pdev->id == 3) && (!ltq_gpio_port[1].membase || !ltq_gpio_port[2].membase)) {
160 + dev_err(&pdev->dev,
161 + "ports 1/2 need to be loaded before port 3 works\n");
162 + return -ENOMEM;
163 + }
164 +
165 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
166 if (!res) {
167 dev_err(&pdev->dev, "failed to get memory for gpio port %d\n",
168 @@ -169,7 +204,10 @@ static int ltq_gpio_probe(struct platform_device *pdev)
169 ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set;
170 ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req;
171 ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id;
172 - ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
173 + if (pdev->id == 3)
174 + ltq_gpio_port[pdev->id].chip.ngpio = PINS_PORT3;
175 + else
176 + ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
177 platform_set_drvdata(pdev, &ltq_gpio_port[pdev->id]);
178 return gpiochip_add(&ltq_gpio_port[pdev->id].chip);
179 }
180 diff --git a/arch/mips/lantiq/xway/gpio_ebu.c b/arch/mips/lantiq/xway/gpio_ebu.c
181 index a479355..729f8e3 100644
182 --- a/arch/mips/lantiq/xway/gpio_ebu.c
183 +++ b/arch/mips/lantiq/xway/gpio_ebu.c
184 @@ -61,9 +61,8 @@ static struct gpio_chip ltq_ebu_chip = {
185 .label = "ltq_ebu",
186 .direction_output = ltq_ebu_direction_output,
187 .set = ltq_ebu_set,
188 - .base = 72,
189 + .base = 100,
190 .ngpio = 16,
191 - .can_sleep = 1,
192 .owner = THIS_MODULE,
193 };
194
195 diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c
196 index 67d59d6..c01294e 100644
197 --- a/arch/mips/lantiq/xway/gpio_stp.c
198 +++ b/arch/mips/lantiq/xway/gpio_stp.c
199 @@ -70,9 +70,8 @@ static struct gpio_chip ltq_stp_chip = {
200 .label = "ltq_stp",
201 .direction_output = ltq_stp_direction_output,
202 .set = ltq_stp_set,
203 - .base = 48,
204 + .base = 200,
205 .ngpio = 24,
206 - .can_sleep = 1,
207 .owner = THIS_MODULE,
208 };
209
210 --
211 1.7.5.4
212
This page took 0.060085 seconds and 5 git commands to generate.