diff options
Diffstat (limited to 'arch/mips/ar7/platform.c')
-rw-r--r-- | arch/mips/ar7/platform.c | 713 |
1 files changed, 381 insertions, 332 deletions
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 85169c08d8dc..246df7aca2e7 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c | |||
@@ -34,45 +34,50 @@ | |||
34 | #include <linux/etherdevice.h> | 34 | #include <linux/etherdevice.h> |
35 | #include <linux/phy.h> | 35 | #include <linux/phy.h> |
36 | #include <linux/phy_fixed.h> | 36 | #include <linux/phy_fixed.h> |
37 | #include <linux/gpio.h> | ||
38 | #include <linux/clk.h> | ||
37 | 39 | ||
38 | #include <asm/addrspace.h> | 40 | #include <asm/addrspace.h> |
39 | #include <asm/mach-ar7/ar7.h> | 41 | #include <asm/mach-ar7/ar7.h> |
40 | #include <asm/mach-ar7/gpio.h> | 42 | #include <asm/mach-ar7/gpio.h> |
41 | #include <asm/mach-ar7/prom.h> | 43 | #include <asm/mach-ar7/prom.h> |
42 | 44 | ||
45 | /***************************************************************************** | ||
46 | * VLYNQ Bus | ||
47 | ****************************************************************************/ | ||
43 | struct plat_vlynq_data { | 48 | struct plat_vlynq_data { |
44 | struct plat_vlynq_ops ops; | 49 | struct plat_vlynq_ops ops; |
45 | int gpio_bit; | 50 | int gpio_bit; |
46 | int reset_bit; | 51 | int reset_bit; |
47 | }; | 52 | }; |
48 | 53 | ||
49 | |||
50 | static int vlynq_on(struct vlynq_device *dev) | 54 | static int vlynq_on(struct vlynq_device *dev) |
51 | { | 55 | { |
52 | int result; | 56 | int ret; |
53 | struct plat_vlynq_data *pdata = dev->dev.platform_data; | 57 | struct plat_vlynq_data *pdata = dev->dev.platform_data; |
54 | 58 | ||
55 | result = gpio_request(pdata->gpio_bit, "vlynq"); | 59 | ret = gpio_request(pdata->gpio_bit, "vlynq"); |
56 | if (result) | 60 | if (ret) |
57 | goto out; | 61 | goto out; |
58 | 62 | ||
59 | ar7_device_reset(pdata->reset_bit); | 63 | ar7_device_reset(pdata->reset_bit); |
60 | 64 | ||
61 | result = ar7_gpio_disable(pdata->gpio_bit); | 65 | ret = ar7_gpio_disable(pdata->gpio_bit); |
62 | if (result) | 66 | if (ret) |
63 | goto out_enabled; | 67 | goto out_enabled; |
64 | 68 | ||
65 | result = ar7_gpio_enable(pdata->gpio_bit); | 69 | ret = ar7_gpio_enable(pdata->gpio_bit); |
66 | if (result) | 70 | if (ret) |
67 | goto out_enabled; | 71 | goto out_enabled; |
68 | 72 | ||
69 | result = gpio_direction_output(pdata->gpio_bit, 0); | 73 | ret = gpio_direction_output(pdata->gpio_bit, 0); |
70 | if (result) | 74 | if (ret) |
71 | goto out_gpio_enabled; | 75 | goto out_gpio_enabled; |
72 | 76 | ||
73 | msleep(50); | 77 | msleep(50); |
74 | 78 | ||
75 | gpio_set_value(pdata->gpio_bit, 1); | 79 | gpio_set_value(pdata->gpio_bit, 1); |
80 | |||
76 | msleep(50); | 81 | msleep(50); |
77 | 82 | ||
78 | return 0; | 83 | return 0; |
@@ -83,320 +88,384 @@ out_enabled: | |||
83 | ar7_device_disable(pdata->reset_bit); | 88 | ar7_device_disable(pdata->reset_bit); |
84 | gpio_free(pdata->gpio_bit); | 89 | gpio_free(pdata->gpio_bit); |
85 | out: | 90 | out: |
86 | return result; | 91 | return ret; |
87 | } | 92 | } |
88 | 93 | ||
89 | static void vlynq_off(struct vlynq_device *dev) | 94 | static void vlynq_off(struct vlynq_device *dev) |
90 | { | 95 | { |
91 | struct plat_vlynq_data *pdata = dev->dev.platform_data; | 96 | struct plat_vlynq_data *pdata = dev->dev.platform_data; |
97 | |||
92 | ar7_gpio_disable(pdata->gpio_bit); | 98 | ar7_gpio_disable(pdata->gpio_bit); |
93 | gpio_free(pdata->gpio_bit); | 99 | gpio_free(pdata->gpio_bit); |
94 | ar7_device_disable(pdata->reset_bit); | 100 | ar7_device_disable(pdata->reset_bit); |
95 | } | 101 | } |
96 | 102 | ||
97 | static struct resource physmap_flash_resource = { | 103 | static struct resource vlynq_low_res[] = { |
98 | .name = "mem", | ||
99 | .flags = IORESOURCE_MEM, | ||
100 | .start = 0x10000000, | ||
101 | .end = 0x107fffff, | ||
102 | }; | ||
103 | |||
104 | static struct resource cpmac_low_res[] = { | ||
105 | { | 104 | { |
106 | .name = "regs", | 105 | .name = "regs", |
107 | .flags = IORESOURCE_MEM, | 106 | .flags = IORESOURCE_MEM, |
108 | .start = AR7_REGS_MAC0, | 107 | .start = AR7_REGS_VLYNQ0, |
109 | .end = AR7_REGS_MAC0 + 0x7ff, | 108 | .end = AR7_REGS_VLYNQ0 + 0xff, |
110 | }, | 109 | }, |
111 | { | 110 | { |
112 | .name = "irq", | 111 | .name = "irq", |
113 | .flags = IORESOURCE_IRQ, | 112 | .flags = IORESOURCE_IRQ, |
114 | .start = 27, | 113 | .start = 29, |
115 | .end = 27, | 114 | .end = 29, |
116 | }, | 115 | }, |
117 | }; | ||
118 | |||
119 | static struct resource cpmac_high_res[] = { | ||
120 | { | 116 | { |
121 | .name = "regs", | 117 | .name = "mem", |
122 | .flags = IORESOURCE_MEM, | 118 | .flags = IORESOURCE_MEM, |
123 | .start = AR7_REGS_MAC1, | 119 | .start = 0x04000000, |
124 | .end = AR7_REGS_MAC1 + 0x7ff, | 120 | .end = 0x04ffffff, |
125 | }, | 121 | }, |
126 | { | 122 | { |
127 | .name = "irq", | 123 | .name = "devirq", |
128 | .flags = IORESOURCE_IRQ, | 124 | .flags = IORESOURCE_IRQ, |
129 | .start = 41, | 125 | .start = 80, |
130 | .end = 41, | 126 | .end = 111, |
131 | }, | 127 | }, |
132 | }; | 128 | }; |
133 | 129 | ||
134 | static struct resource vlynq_low_res[] = { | 130 | static struct resource vlynq_high_res[] = { |
135 | { | 131 | { |
136 | .name = "regs", | 132 | .name = "regs", |
137 | .flags = IORESOURCE_MEM, | 133 | .flags = IORESOURCE_MEM, |
138 | .start = AR7_REGS_VLYNQ0, | 134 | .start = AR7_REGS_VLYNQ1, |
139 | .end = AR7_REGS_VLYNQ0 + 0xff, | 135 | .end = AR7_REGS_VLYNQ1 + 0xff, |
140 | }, | 136 | }, |
141 | { | 137 | { |
142 | .name = "irq", | 138 | .name = "irq", |
143 | .flags = IORESOURCE_IRQ, | 139 | .flags = IORESOURCE_IRQ, |
144 | .start = 29, | 140 | .start = 33, |
145 | .end = 29, | 141 | .end = 33, |
146 | }, | 142 | }, |
147 | { | 143 | { |
148 | .name = "mem", | 144 | .name = "mem", |
149 | .flags = IORESOURCE_MEM, | 145 | .flags = IORESOURCE_MEM, |
150 | .start = 0x04000000, | 146 | .start = 0x0c000000, |
151 | .end = 0x04ffffff, | 147 | .end = 0x0cffffff, |
152 | }, | 148 | }, |
153 | { | 149 | { |
154 | .name = "devirq", | 150 | .name = "devirq", |
155 | .flags = IORESOURCE_IRQ, | 151 | .flags = IORESOURCE_IRQ, |
156 | .start = 80, | 152 | .start = 112, |
157 | .end = 111, | 153 | .end = 143, |
158 | }, | 154 | }, |
159 | }; | 155 | }; |
160 | 156 | ||
161 | static struct resource vlynq_high_res[] = { | 157 | static struct plat_vlynq_data vlynq_low_data = { |
162 | { | 158 | .ops = { |
163 | .name = "regs", | 159 | .on = vlynq_on, |
164 | .flags = IORESOURCE_MEM, | 160 | .off = vlynq_off, |
165 | .start = AR7_REGS_VLYNQ1, | ||
166 | .end = AR7_REGS_VLYNQ1 + 0xff, | ||
167 | }, | 161 | }, |
168 | { | 162 | .reset_bit = 20, |
169 | .name = "irq", | 163 | .gpio_bit = 18, |
170 | .flags = IORESOURCE_IRQ, | 164 | }; |
171 | .start = 33, | 165 | |
172 | .end = 33, | 166 | static struct plat_vlynq_data vlynq_high_data = { |
167 | .ops = { | ||
168 | .on = vlynq_on, | ||
169 | .off = vlynq_off, | ||
173 | }, | 170 | }, |
174 | { | 171 | .reset_bit = 26, |
175 | .name = "mem", | 172 | .gpio_bit = 19, |
176 | .flags = IORESOURCE_MEM, | 173 | }; |
177 | .start = 0x0c000000, | 174 | |
178 | .end = 0x0cffffff, | 175 | static struct platform_device vlynq_low = { |
176 | .id = 0, | ||
177 | .name = "vlynq", | ||
178 | .dev = { | ||
179 | .platform_data = &vlynq_low_data, | ||
179 | }, | 180 | }, |
180 | { | 181 | .resource = vlynq_low_res, |
181 | .name = "devirq", | 182 | .num_resources = ARRAY_SIZE(vlynq_low_res), |
182 | .flags = IORESOURCE_IRQ, | 183 | }; |
183 | .start = 112, | 184 | |
184 | .end = 143, | 185 | static struct platform_device vlynq_high = { |
186 | .id = 1, | ||
187 | .name = "vlynq", | ||
188 | .dev = { | ||
189 | .platform_data = &vlynq_high_data, | ||
185 | }, | 190 | }, |
191 | .resource = vlynq_high_res, | ||
192 | .num_resources = ARRAY_SIZE(vlynq_high_res), | ||
186 | }; | 193 | }; |
187 | 194 | ||
188 | static struct resource usb_res[] = { | 195 | /***************************************************************************** |
189 | { | 196 | * Flash |
190 | .name = "regs", | 197 | ****************************************************************************/ |
191 | .flags = IORESOURCE_MEM, | 198 | static struct resource physmap_flash_resource = { |
192 | .start = AR7_REGS_USB, | 199 | .name = "mem", |
193 | .end = AR7_REGS_USB + 0xff, | 200 | .flags = IORESOURCE_MEM, |
201 | .start = 0x10000000, | ||
202 | .end = 0x107fffff, | ||
203 | }; | ||
204 | |||
205 | static struct physmap_flash_data physmap_flash_data = { | ||
206 | .width = 2, | ||
207 | }; | ||
208 | |||
209 | static struct platform_device physmap_flash = { | ||
210 | .name = "physmap-flash", | ||
211 | .dev = { | ||
212 | .platform_data = &physmap_flash_data, | ||
194 | }, | 213 | }, |
214 | .resource = &physmap_flash_resource, | ||
215 | .num_resources = 1, | ||
216 | }; | ||
217 | |||
218 | /***************************************************************************** | ||
219 | * Ethernet | ||
220 | ****************************************************************************/ | ||
221 | static struct resource cpmac_low_res[] = { | ||
195 | { | 222 | { |
196 | .name = "irq", | 223 | .name = "regs", |
197 | .flags = IORESOURCE_IRQ, | 224 | .flags = IORESOURCE_MEM, |
198 | .start = 32, | 225 | .start = AR7_REGS_MAC0, |
199 | .end = 32, | 226 | .end = AR7_REGS_MAC0 + 0x7ff, |
200 | }, | 227 | }, |
201 | { | 228 | { |
202 | .name = "mem", | 229 | .name = "irq", |
203 | .flags = IORESOURCE_MEM, | 230 | .flags = IORESOURCE_IRQ, |
204 | .start = 0x03400000, | 231 | .start = 27, |
205 | .end = 0x034001fff, | 232 | .end = 27, |
206 | }, | 233 | }, |
207 | }; | 234 | }; |
208 | 235 | ||
209 | static struct physmap_flash_data physmap_flash_data = { | 236 | static struct resource cpmac_high_res[] = { |
210 | .width = 2, | 237 | { |
238 | .name = "regs", | ||
239 | .flags = IORESOURCE_MEM, | ||
240 | .start = AR7_REGS_MAC1, | ||
241 | .end = AR7_REGS_MAC1 + 0x7ff, | ||
242 | }, | ||
243 | { | ||
244 | .name = "irq", | ||
245 | .flags = IORESOURCE_IRQ, | ||
246 | .start = 41, | ||
247 | .end = 41, | ||
248 | }, | ||
211 | }; | 249 | }; |
212 | 250 | ||
213 | static struct fixed_phy_status fixed_phy_status __initdata = { | 251 | static struct fixed_phy_status fixed_phy_status __initdata = { |
214 | .link = 1, | 252 | .link = 1, |
215 | .speed = 100, | 253 | .speed = 100, |
216 | .duplex = 1, | 254 | .duplex = 1, |
217 | }; | 255 | }; |
218 | 256 | ||
219 | static struct plat_cpmac_data cpmac_low_data = { | 257 | static struct plat_cpmac_data cpmac_low_data = { |
220 | .reset_bit = 17, | 258 | .reset_bit = 17, |
221 | .power_bit = 20, | 259 | .power_bit = 20, |
222 | .phy_mask = 0x80000000, | 260 | .phy_mask = 0x80000000, |
223 | }; | 261 | }; |
224 | 262 | ||
225 | static struct plat_cpmac_data cpmac_high_data = { | 263 | static struct plat_cpmac_data cpmac_high_data = { |
226 | .reset_bit = 21, | 264 | .reset_bit = 21, |
227 | .power_bit = 22, | 265 | .power_bit = 22, |
228 | .phy_mask = 0x7fffffff, | 266 | .phy_mask = 0x7fffffff, |
229 | }; | ||
230 | |||
231 | static struct plat_vlynq_data vlynq_low_data = { | ||
232 | .ops.on = vlynq_on, | ||
233 | .ops.off = vlynq_off, | ||
234 | .reset_bit = 20, | ||
235 | .gpio_bit = 18, | ||
236 | }; | ||
237 | |||
238 | static struct plat_vlynq_data vlynq_high_data = { | ||
239 | .ops.on = vlynq_on, | ||
240 | .ops.off = vlynq_off, | ||
241 | .reset_bit = 16, | ||
242 | .gpio_bit = 19, | ||
243 | }; | ||
244 | |||
245 | static struct platform_device physmap_flash = { | ||
246 | .id = 0, | ||
247 | .name = "physmap-flash", | ||
248 | .dev.platform_data = &physmap_flash_data, | ||
249 | .resource = &physmap_flash_resource, | ||
250 | .num_resources = 1, | ||
251 | }; | 267 | }; |
252 | 268 | ||
253 | static u64 cpmac_dma_mask = DMA_BIT_MASK(32); | 269 | static u64 cpmac_dma_mask = DMA_BIT_MASK(32); |
270 | |||
254 | static struct platform_device cpmac_low = { | 271 | static struct platform_device cpmac_low = { |
255 | .id = 0, | 272 | .id = 0, |
256 | .name = "cpmac", | 273 | .name = "cpmac", |
257 | .dev = { | 274 | .dev = { |
258 | .dma_mask = &cpmac_dma_mask, | 275 | .dma_mask = &cpmac_dma_mask, |
259 | .coherent_dma_mask = DMA_BIT_MASK(32), | 276 | .coherent_dma_mask = DMA_BIT_MASK(32), |
260 | .platform_data = &cpmac_low_data, | 277 | .platform_data = &cpmac_low_data, |
261 | }, | 278 | }, |
262 | .resource = cpmac_low_res, | 279 | .resource = cpmac_low_res, |
263 | .num_resources = ARRAY_SIZE(cpmac_low_res), | 280 | .num_resources = ARRAY_SIZE(cpmac_low_res), |
264 | }; | 281 | }; |
265 | 282 | ||
266 | static struct platform_device cpmac_high = { | 283 | static struct platform_device cpmac_high = { |
267 | .id = 1, | 284 | .id = 1, |
268 | .name = "cpmac", | 285 | .name = "cpmac", |
269 | .dev = { | 286 | .dev = { |
270 | .dma_mask = &cpmac_dma_mask, | 287 | .dma_mask = &cpmac_dma_mask, |
271 | .coherent_dma_mask = DMA_BIT_MASK(32), | 288 | .coherent_dma_mask = DMA_BIT_MASK(32), |
272 | .platform_data = &cpmac_high_data, | 289 | .platform_data = &cpmac_high_data, |
273 | }, | 290 | }, |
274 | .resource = cpmac_high_res, | 291 | .resource = cpmac_high_res, |
275 | .num_resources = ARRAY_SIZE(cpmac_high_res), | 292 | .num_resources = ARRAY_SIZE(cpmac_high_res), |
276 | }; | 293 | }; |
277 | 294 | ||
278 | static struct platform_device vlynq_low = { | 295 | static inline unsigned char char2hex(char h) |
279 | .id = 0, | 296 | { |
280 | .name = "vlynq", | 297 | switch (h) { |
281 | .dev.platform_data = &vlynq_low_data, | 298 | case '0': case '1': case '2': case '3': case '4': |
282 | .resource = vlynq_low_res, | 299 | case '5': case '6': case '7': case '8': case '9': |
283 | .num_resources = ARRAY_SIZE(vlynq_low_res), | 300 | return h - '0'; |
284 | }; | 301 | case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': |
302 | return h - 'A' + 10; | ||
303 | case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': | ||
304 | return h - 'a' + 10; | ||
305 | default: | ||
306 | return 0; | ||
307 | } | ||
308 | } | ||
285 | 309 | ||
286 | static struct platform_device vlynq_high = { | 310 | static void cpmac_get_mac(int instance, unsigned char *dev_addr) |
287 | .id = 1, | 311 | { |
288 | .name = "vlynq", | 312 | int i; |
289 | .dev.platform_data = &vlynq_high_data, | 313 | char name[5], default_mac[ETH_ALEN], *mac; |
290 | .resource = vlynq_high_res, | 314 | |
291 | .num_resources = ARRAY_SIZE(vlynq_high_res), | 315 | mac = NULL; |
316 | sprintf(name, "mac%c", 'a' + instance); | ||
317 | mac = prom_getenv(name); | ||
318 | if (!mac) { | ||
319 | sprintf(name, "mac%c", 'a'); | ||
320 | mac = prom_getenv(name); | ||
321 | } | ||
322 | if (!mac) { | ||
323 | random_ether_addr(default_mac); | ||
324 | mac = default_mac; | ||
325 | } | ||
326 | for (i = 0; i < 6; i++) | ||
327 | dev_addr[i] = (char2hex(mac[i * 3]) << 4) + | ||
328 | char2hex(mac[i * 3 + 1]); | ||
329 | } | ||
330 | |||
331 | /***************************************************************************** | ||
332 | * USB | ||
333 | ****************************************************************************/ | ||
334 | static struct resource usb_res[] = { | ||
335 | { | ||
336 | .name = "regs", | ||
337 | .flags = IORESOURCE_MEM, | ||
338 | .start = AR7_REGS_USB, | ||
339 | .end = AR7_REGS_USB + 0xff, | ||
340 | }, | ||
341 | { | ||
342 | .name = "irq", | ||
343 | .flags = IORESOURCE_IRQ, | ||
344 | .start = 32, | ||
345 | .end = 32, | ||
346 | }, | ||
347 | { | ||
348 | .name = "mem", | ||
349 | .flags = IORESOURCE_MEM, | ||
350 | .start = 0x03400000, | ||
351 | .end = 0x03401fff, | ||
352 | }, | ||
292 | }; | 353 | }; |
293 | 354 | ||
355 | static struct platform_device ar7_udc = { | ||
356 | .name = "ar7_udc", | ||
357 | .resource = usb_res, | ||
358 | .num_resources = ARRAY_SIZE(usb_res), | ||
359 | }; | ||
294 | 360 | ||
361 | /***************************************************************************** | ||
362 | * LEDs | ||
363 | ****************************************************************************/ | ||
295 | static struct gpio_led default_leds[] = { | 364 | static struct gpio_led default_leds[] = { |
296 | { | 365 | { |
297 | .name = "status", | 366 | .name = "status", |
298 | .gpio = 8, | 367 | .gpio = 8, |
299 | .active_low = 1, | 368 | .active_low = 1, |
300 | }, | 369 | }, |
301 | }; | 370 | }; |
302 | 371 | ||
303 | static struct gpio_led dsl502t_leds[] = { | 372 | static struct gpio_led dsl502t_leds[] = { |
304 | { | 373 | { |
305 | .name = "status", | 374 | .name = "status", |
306 | .gpio = 9, | 375 | .gpio = 9, |
307 | .active_low = 1, | 376 | .active_low = 1, |
308 | }, | 377 | }, |
309 | { | 378 | { |
310 | .name = "ethernet", | 379 | .name = "ethernet", |
311 | .gpio = 7, | 380 | .gpio = 7, |
312 | .active_low = 1, | 381 | .active_low = 1, |
313 | }, | 382 | }, |
314 | { | 383 | { |
315 | .name = "usb", | 384 | .name = "usb", |
316 | .gpio = 12, | 385 | .gpio = 12, |
317 | .active_low = 1, | 386 | .active_low = 1, |
318 | }, | 387 | }, |
319 | }; | 388 | }; |
320 | 389 | ||
321 | static struct gpio_led dg834g_leds[] = { | 390 | static struct gpio_led dg834g_leds[] = { |
322 | { | 391 | { |
323 | .name = "ppp", | 392 | .name = "ppp", |
324 | .gpio = 6, | 393 | .gpio = 6, |
325 | .active_low = 1, | 394 | .active_low = 1, |
326 | }, | 395 | }, |
327 | { | 396 | { |
328 | .name = "status", | 397 | .name = "status", |
329 | .gpio = 7, | 398 | .gpio = 7, |
330 | .active_low = 1, | 399 | .active_low = 1, |
331 | }, | 400 | }, |
332 | { | 401 | { |
333 | .name = "adsl", | 402 | .name = "adsl", |
334 | .gpio = 8, | 403 | .gpio = 8, |
335 | .active_low = 1, | 404 | .active_low = 1, |
336 | }, | 405 | }, |
337 | { | 406 | { |
338 | .name = "wifi", | 407 | .name = "wifi", |
339 | .gpio = 12, | 408 | .gpio = 12, |
340 | .active_low = 1, | 409 | .active_low = 1, |
341 | }, | 410 | }, |
342 | { | 411 | { |
343 | .name = "power", | 412 | .name = "power", |
344 | .gpio = 14, | 413 | .gpio = 14, |
345 | .active_low = 1, | 414 | .active_low = 1, |
346 | .default_trigger = "default-on", | 415 | .default_trigger = "default-on", |
347 | }, | 416 | }, |
348 | }; | 417 | }; |
349 | 418 | ||
350 | static struct gpio_led fb_sl_leds[] = { | 419 | static struct gpio_led fb_sl_leds[] = { |
351 | { | 420 | { |
352 | .name = "1", | 421 | .name = "1", |
353 | .gpio = 7, | 422 | .gpio = 7, |
354 | }, | 423 | }, |
355 | { | 424 | { |
356 | .name = "2", | 425 | .name = "2", |
357 | .gpio = 13, | 426 | .gpio = 13, |
358 | .active_low = 1, | 427 | .active_low = 1, |
359 | }, | 428 | }, |
360 | { | 429 | { |
361 | .name = "3", | 430 | .name = "3", |
362 | .gpio = 10, | 431 | .gpio = 10, |
363 | .active_low = 1, | 432 | .active_low = 1, |
364 | }, | 433 | }, |
365 | { | 434 | { |
366 | .name = "4", | 435 | .name = "4", |
367 | .gpio = 12, | 436 | .gpio = 12, |
368 | .active_low = 1, | 437 | .active_low = 1, |
369 | }, | 438 | }, |
370 | { | 439 | { |
371 | .name = "5", | 440 | .name = "5", |
372 | .gpio = 9, | 441 | .gpio = 9, |
373 | .active_low = 1, | 442 | .active_low = 1, |
374 | }, | 443 | }, |
375 | }; | 444 | }; |
376 | 445 | ||
377 | static struct gpio_led fb_fon_leds[] = { | 446 | static struct gpio_led fb_fon_leds[] = { |
378 | { | 447 | { |
379 | .name = "1", | 448 | .name = "1", |
380 | .gpio = 8, | 449 | .gpio = 8, |
381 | }, | 450 | }, |
382 | { | 451 | { |
383 | .name = "2", | 452 | .name = "2", |
384 | .gpio = 3, | 453 | .gpio = 3, |
385 | .active_low = 1, | 454 | .active_low = 1, |
386 | }, | 455 | }, |
387 | { | 456 | { |
388 | .name = "3", | 457 | .name = "3", |
389 | .gpio = 5, | 458 | .gpio = 5, |
390 | }, | 459 | }, |
391 | { | 460 | { |
392 | .name = "4", | 461 | .name = "4", |
393 | .gpio = 4, | 462 | .gpio = 4, |
394 | .active_low = 1, | 463 | .active_low = 1, |
395 | }, | 464 | }, |
396 | { | 465 | { |
397 | .name = "5", | 466 | .name = "5", |
398 | .gpio = 11, | 467 | .gpio = 11, |
399 | .active_low = 1, | 468 | .active_low = 1, |
400 | }, | 469 | }, |
401 | }; | 470 | }; |
402 | 471 | ||
@@ -404,69 +473,11 @@ static struct gpio_led_platform_data ar7_led_data; | |||
404 | 473 | ||
405 | static struct platform_device ar7_gpio_leds = { | 474 | static struct platform_device ar7_gpio_leds = { |
406 | .name = "leds-gpio", | 475 | .name = "leds-gpio", |
407 | .id = -1, | ||
408 | .dev = { | 476 | .dev = { |
409 | .platform_data = &ar7_led_data, | 477 | .platform_data = &ar7_led_data, |
410 | } | 478 | } |
411 | }; | 479 | }; |
412 | 480 | ||
413 | static struct platform_device ar7_udc = { | ||
414 | .id = -1, | ||
415 | .name = "ar7_udc", | ||
416 | .resource = usb_res, | ||
417 | .num_resources = ARRAY_SIZE(usb_res), | ||
418 | }; | ||
419 | |||
420 | static struct resource ar7_wdt_res = { | ||
421 | .name = "regs", | ||
422 | .start = -1, /* Filled at runtime */ | ||
423 | .end = -1, /* Filled at runtime */ | ||
424 | .flags = IORESOURCE_MEM, | ||
425 | }; | ||
426 | |||
427 | static struct platform_device ar7_wdt = { | ||
428 | .id = -1, | ||
429 | .name = "ar7_wdt", | ||
430 | .resource = &ar7_wdt_res, | ||
431 | .num_resources = 1, | ||
432 | }; | ||
433 | |||
434 | static inline unsigned char char2hex(char h) | ||
435 | { | ||
436 | switch (h) { | ||
437 | case '0': case '1': case '2': case '3': case '4': | ||
438 | case '5': case '6': case '7': case '8': case '9': | ||
439 | return h - '0'; | ||
440 | case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': | ||
441 | return h - 'A' + 10; | ||
442 | case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': | ||
443 | return h - 'a' + 10; | ||
444 | default: | ||
445 | return 0; | ||
446 | } | ||
447 | } | ||
448 | |||
449 | static void cpmac_get_mac(int instance, unsigned char *dev_addr) | ||
450 | { | ||
451 | int i; | ||
452 | char name[5], default_mac[ETH_ALEN], *mac; | ||
453 | |||
454 | mac = NULL; | ||
455 | sprintf(name, "mac%c", 'a' + instance); | ||
456 | mac = prom_getenv(name); | ||
457 | if (!mac) { | ||
458 | sprintf(name, "mac%c", 'a'); | ||
459 | mac = prom_getenv(name); | ||
460 | } | ||
461 | if (!mac) { | ||
462 | random_ether_addr(default_mac); | ||
463 | mac = default_mac; | ||
464 | } | ||
465 | for (i = 0; i < 6; i++) | ||
466 | dev_addr[i] = (char2hex(mac[i * 3]) << 4) + | ||
467 | char2hex(mac[i * 3 + 1]); | ||
468 | } | ||
469 | |||
470 | static void __init detect_leds(void) | 481 | static void __init detect_leds(void) |
471 | { | 482 | { |
472 | char *prid, *usb_prod; | 483 | char *prid, *usb_prod; |
@@ -499,111 +510,149 @@ static void __init detect_leds(void) | |||
499 | } | 510 | } |
500 | } | 511 | } |
501 | 512 | ||
502 | static int __init ar7_register_devices(void) | 513 | /***************************************************************************** |
514 | * Watchdog | ||
515 | ****************************************************************************/ | ||
516 | static struct resource ar7_wdt_res = { | ||
517 | .name = "regs", | ||
518 | .flags = IORESOURCE_MEM, | ||
519 | .start = -1, /* Filled at runtime */ | ||
520 | .end = -1, /* Filled at runtime */ | ||
521 | }; | ||
522 | |||
523 | static struct platform_device ar7_wdt = { | ||
524 | .name = "ar7_wdt", | ||
525 | .resource = &ar7_wdt_res, | ||
526 | .num_resources = 1, | ||
527 | }; | ||
528 | |||
529 | /***************************************************************************** | ||
530 | * Init | ||
531 | ****************************************************************************/ | ||
532 | static int __init ar7_register_uarts(void) | ||
503 | { | 533 | { |
504 | u16 chip_id; | ||
505 | int res; | ||
506 | u32 *bootcr, val; | ||
507 | #ifdef CONFIG_SERIAL_8250 | 534 | #ifdef CONFIG_SERIAL_8250 |
508 | static struct uart_port uart_port[2] __initdata; | 535 | static struct uart_port uart_port __initdata; |
509 | 536 | struct clk *bus_clk; | |
510 | memset(uart_port, 0, sizeof(struct uart_port) * 2); | 537 | int res; |
511 | 538 | ||
512 | uart_port[0].type = PORT_16550A; | 539 | memset(&uart_port, 0, sizeof(struct uart_port)); |
513 | uart_port[0].line = 0; | 540 | |
514 | uart_port[0].irq = AR7_IRQ_UART0; | 541 | bus_clk = clk_get(NULL, "bus"); |
515 | uart_port[0].uartclk = ar7_bus_freq() / 2; | 542 | if (IS_ERR(bus_clk)) |
516 | uart_port[0].iotype = UPIO_MEM32; | 543 | panic("unable to get bus clk\n"); |
517 | uart_port[0].mapbase = AR7_REGS_UART0; | 544 | |
518 | uart_port[0].membase = ioremap(uart_port[0].mapbase, 256); | 545 | uart_port.type = PORT_16550A; |
519 | uart_port[0].regshift = 2; | 546 | uart_port.uartclk = clk_get_rate(bus_clk) / 2; |
520 | res = early_serial_setup(&uart_port[0]); | 547 | uart_port.iotype = UPIO_MEM32; |
548 | uart_port.regshift = 2; | ||
549 | |||
550 | uart_port.line = 0; | ||
551 | uart_port.irq = AR7_IRQ_UART0; | ||
552 | uart_port.mapbase = AR7_REGS_UART0; | ||
553 | uart_port.membase = ioremap(uart_port.mapbase, 256); | ||
554 | |||
555 | res = early_serial_setup(&uart_port); | ||
521 | if (res) | 556 | if (res) |
522 | return res; | 557 | return res; |
523 | 558 | ||
524 | |||
525 | /* Only TNETD73xx have a second serial port */ | 559 | /* Only TNETD73xx have a second serial port */ |
526 | if (ar7_has_second_uart()) { | 560 | if (ar7_has_second_uart()) { |
527 | uart_port[1].type = PORT_16550A; | 561 | uart_port.line = 1; |
528 | uart_port[1].line = 1; | 562 | uart_port.irq = AR7_IRQ_UART1; |
529 | uart_port[1].irq = AR7_IRQ_UART1; | 563 | uart_port.mapbase = UR8_REGS_UART1; |
530 | uart_port[1].uartclk = ar7_bus_freq() / 2; | 564 | uart_port.membase = ioremap(uart_port.mapbase, 256); |
531 | uart_port[1].iotype = UPIO_MEM32; | 565 | |
532 | uart_port[1].mapbase = UR8_REGS_UART1; | 566 | res = early_serial_setup(&uart_port); |
533 | uart_port[1].membase = ioremap(uart_port[1].mapbase, 256); | ||
534 | uart_port[1].regshift = 2; | ||
535 | res = early_serial_setup(&uart_port[1]); | ||
536 | if (res) | 567 | if (res) |
537 | return res; | 568 | return res; |
538 | } | 569 | } |
539 | #endif /* CONFIG_SERIAL_8250 */ | 570 | #endif |
571 | |||
572 | return 0; | ||
573 | } | ||
574 | |||
575 | static int __init ar7_register_devices(void) | ||
576 | { | ||
577 | void __iomem *bootcr; | ||
578 | u32 val; | ||
579 | u16 chip_id; | ||
580 | int res; | ||
581 | |||
582 | res = ar7_register_uarts(); | ||
583 | if (res) | ||
584 | pr_err("unable to setup uart(s): %d\n", res); | ||
585 | |||
540 | res = platform_device_register(&physmap_flash); | 586 | res = platform_device_register(&physmap_flash); |
541 | if (res) | 587 | if (res) |
542 | return res; | 588 | pr_warning("unable to register physmap-flash: %d\n", res); |
543 | 589 | ||
544 | ar7_device_disable(vlynq_low_data.reset_bit); | 590 | ar7_device_disable(vlynq_low_data.reset_bit); |
545 | res = platform_device_register(&vlynq_low); | 591 | res = platform_device_register(&vlynq_low); |
546 | if (res) | 592 | if (res) |
547 | return res; | 593 | pr_warning("unable to register vlynq-low: %d\n", res); |
548 | 594 | ||
549 | if (ar7_has_high_vlynq()) { | 595 | if (ar7_has_high_vlynq()) { |
550 | ar7_device_disable(vlynq_high_data.reset_bit); | 596 | ar7_device_disable(vlynq_high_data.reset_bit); |
551 | res = platform_device_register(&vlynq_high); | 597 | res = platform_device_register(&vlynq_high); |
552 | if (res) | 598 | if (res) |
553 | return res; | 599 | pr_warning("unable to register vlynq-high: %d\n", res); |
554 | } | 600 | } |
555 | 601 | ||
556 | if (ar7_has_high_cpmac()) { | 602 | if (ar7_has_high_cpmac()) { |
557 | res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status); | 603 | if (!res) { |
558 | if (res && res != -ENODEV) | 604 | cpmac_get_mac(1, cpmac_high_data.dev_addr); |
559 | return res; | 605 | |
560 | cpmac_get_mac(1, cpmac_high_data.dev_addr); | 606 | res = platform_device_register(&cpmac_high); |
561 | res = platform_device_register(&cpmac_high); | 607 | if (res) |
562 | if (res) | 608 | pr_warning("unable to register cpmac-high: %d\n", res); |
563 | return res; | 609 | } else |
564 | } else { | 610 | pr_warning("unable to add cpmac-high phy: %d\n", res); |
611 | } else | ||
565 | cpmac_low_data.phy_mask = 0xffffffff; | 612 | cpmac_low_data.phy_mask = 0xffffffff; |
566 | } | ||
567 | 613 | ||
568 | res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status); | 614 | res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status); |
569 | if (res && res != -ENODEV) | 615 | if (!res) { |
570 | return res; | 616 | cpmac_get_mac(0, cpmac_low_data.dev_addr); |
571 | 617 | res = platform_device_register(&cpmac_low); | |
572 | cpmac_get_mac(0, cpmac_low_data.dev_addr); | 618 | if (res) |
573 | res = platform_device_register(&cpmac_low); | 619 | pr_warning("unable to register cpmac-low: %d\n", res); |
574 | if (res) | 620 | } else |
575 | return res; | 621 | pr_warning("unable to add cpmac-low phy: %d\n", res); |
576 | 622 | ||
577 | detect_leds(); | 623 | detect_leds(); |
578 | res = platform_device_register(&ar7_gpio_leds); | 624 | res = platform_device_register(&ar7_gpio_leds); |
579 | if (res) | 625 | if (res) |
580 | return res; | 626 | pr_warning("unable to register leds: %d\n", res); |
581 | 627 | ||
582 | res = platform_device_register(&ar7_udc); | 628 | res = platform_device_register(&ar7_udc); |
583 | 629 | if (res) | |
584 | chip_id = ar7_chip_id(); | 630 | pr_warning("unable to register usb slave: %d\n", res); |
585 | switch (chip_id) { | ||
586 | case AR7_CHIP_7100: | ||
587 | case AR7_CHIP_7200: | ||
588 | ar7_wdt_res.start = AR7_REGS_WDT; | ||
589 | break; | ||
590 | case AR7_CHIP_7300: | ||
591 | ar7_wdt_res.start = UR8_REGS_WDT; | ||
592 | break; | ||
593 | default: | ||
594 | break; | ||
595 | } | ||
596 | |||
597 | ar7_wdt_res.end = ar7_wdt_res.start + 0x20; | ||
598 | |||
599 | bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4); | ||
600 | val = *bootcr; | ||
601 | iounmap(bootcr); | ||
602 | 631 | ||
603 | /* Register watchdog only if enabled in hardware */ | 632 | /* Register watchdog only if enabled in hardware */ |
604 | if (val & AR7_WDT_HW_ENA) | 633 | bootcr = ioremap_nocache(AR7_REGS_DCL, 4); |
634 | val = readl(bootcr); | ||
635 | iounmap(bootcr); | ||
636 | if (val & AR7_WDT_HW_ENA) { | ||
637 | chip_id = ar7_chip_id(); | ||
638 | switch (chip_id) { | ||
639 | case AR7_CHIP_7100: | ||
640 | case AR7_CHIP_7200: | ||
641 | ar7_wdt_res.start = AR7_REGS_WDT; | ||
642 | break; | ||
643 | case AR7_CHIP_7300: | ||
644 | ar7_wdt_res.start = UR8_REGS_WDT; | ||
645 | break; | ||
646 | default: | ||
647 | break; | ||
648 | } | ||
649 | |||
650 | ar7_wdt_res.end = ar7_wdt_res.start + 0x20; | ||
605 | res = platform_device_register(&ar7_wdt); | 651 | res = platform_device_register(&ar7_wdt); |
652 | if (res) | ||
653 | pr_warning("unable to register watchdog: %d\n", res); | ||
654 | } | ||
606 | 655 | ||
607 | return res; | 656 | return 0; |
608 | } | 657 | } |
609 | arch_initcall(ar7_register_devices); | 658 | arch_initcall(ar7_register_devices); |