ar71xx: move gpio-buttons support into a spearate file
[librecmc/librecmc.git] / target / linux / ar71xx / files / arch / mips / ar71xx / devices.c
1 /*
2  *  Atheros AR71xx SoC platform devices
3  *
4  *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
5  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6  *
7  *  Parts of this file are based on Atheros' 2.6.15 BSP
8  *
9  *  This program is free software; you can redistribute it and/or modify it
10  *  under the terms of the GNU General Public License version 2 as published
11  *  by the Free Software Foundation.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/delay.h>
17 #include <linux/dma-mapping.h>
18 #include <linux/etherdevice.h>
19 #include <linux/platform_device.h>
20 #include <linux/serial_8250.h>
21
22 #include <asm/mach-ar71xx/ar71xx.h>
23
24 #include "devices.h"
25
26 static u8 ar71xx_mac_base[ETH_ALEN] __initdata;
27
28 /*
29  * OHCI (USB full speed host controller)
30  */
31 static struct resource ar71xx_ohci_resources[] = {
32         [0] = {
33                 .start  = AR71XX_OHCI_BASE,
34                 .end    = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1,
35                 .flags  = IORESOURCE_MEM,
36         },
37         [1] = {
38                 .start  = AR71XX_MISC_IRQ_OHCI,
39                 .end    = AR71XX_MISC_IRQ_OHCI,
40                 .flags  = IORESOURCE_IRQ,
41         },
42 };
43
44 static struct resource ar7240_ohci_resources[] = {
45         [0] = {
46                 .start  = AR7240_OHCI_BASE,
47                 .end    = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1,
48                 .flags  = IORESOURCE_MEM,
49         },
50         [1] = {
51                 .start  = AR71XX_CPU_IRQ_USB,
52                 .end    = AR71XX_CPU_IRQ_USB,
53                 .flags  = IORESOURCE_IRQ,
54         },
55 };
56
57 static u64 ar71xx_ohci_dmamask = DMA_BIT_MASK(32);
58 static struct platform_device ar71xx_ohci_device = {
59         .name           = "ar71xx-ohci",
60         .id             = -1,
61         .resource       = ar71xx_ohci_resources,
62         .num_resources  = ARRAY_SIZE(ar71xx_ohci_resources),
63         .dev = {
64                 .dma_mask               = &ar71xx_ohci_dmamask,
65                 .coherent_dma_mask      = DMA_BIT_MASK(32),
66         },
67 };
68
69 /*
70  * EHCI (USB full speed host controller)
71  */
72 static struct resource ar71xx_ehci_resources[] = {
73         [0] = {
74                 .start  = AR71XX_EHCI_BASE,
75                 .end    = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1,
76                 .flags  = IORESOURCE_MEM,
77         },
78         [1] = {
79                 .start  = AR71XX_CPU_IRQ_USB,
80                 .end    = AR71XX_CPU_IRQ_USB,
81                 .flags  = IORESOURCE_IRQ,
82         },
83 };
84
85
86 static u64 ar71xx_ehci_dmamask = DMA_BIT_MASK(32);
87 static struct ar71xx_ehci_platform_data ar71xx_ehci_data;
88
89 static struct platform_device ar71xx_ehci_device = {
90         .name           = "ar71xx-ehci",
91         .id             = -1,
92         .resource       = ar71xx_ehci_resources,
93         .num_resources  = ARRAY_SIZE(ar71xx_ehci_resources),
94         .dev = {
95                 .dma_mask               = &ar71xx_ehci_dmamask,
96                 .coherent_dma_mask      = DMA_BIT_MASK(32),
97                 .platform_data          = &ar71xx_ehci_data,
98         },
99 };
100
101 #define AR71XX_USB_RESET_MASK \
102         (RESET_MODULE_USB_HOST | RESET_MODULE_USB_PHY \
103         | RESET_MODULE_USB_OHCI_DLL)
104
105 #define AR7240_USB_RESET_MASK \
106         (RESET_MODULE_USB_HOST | RESET_MODULE_USB_OHCI_DLL_7240)
107
108 static void __init ar71xx_usb_setup(void)
109 {
110         ar71xx_device_stop(AR71XX_USB_RESET_MASK);
111         mdelay(1000);
112         ar71xx_device_start(AR71XX_USB_RESET_MASK);
113
114         /* Turning on the Buff and Desc swap bits */
115         ar71xx_usb_ctrl_wr(USB_CTRL_REG_CONFIG, 0xf0000);
116
117         /* WAR for HW bug. Here it adjusts the duration between two SOFS */
118         ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x20c00);
119
120         mdelay(900);
121 }
122
123 static void __init ar7240_usb_setup(void)
124 {
125         ar71xx_ohci_device.resource = ar7240_ohci_resources;
126
127         ar71xx_device_stop(AR7240_USB_RESET_MASK);
128         mdelay(1000);
129         ar71xx_device_start(AR7240_USB_RESET_MASK);
130
131         /* WAR for HW bug. Here it adjusts the duration between two SOFS */
132         ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x3);
133 }
134
135 static void __init ar91xx_usb_setup(void)
136 {
137         ar71xx_device_stop(RESET_MODULE_USBSUS_OVERRIDE);
138         mdelay(10);
139
140         ar71xx_device_start(RESET_MODULE_USB_HOST);
141         mdelay(10);
142
143         ar71xx_device_start(RESET_MODULE_USB_PHY);
144         mdelay(10);
145 }
146
147 void __init ar71xx_add_device_usb(void)
148 {
149         switch (ar71xx_soc) {
150         case AR71XX_SOC_AR7240:
151                 ar7240_usb_setup();
152                 platform_device_register(&ar71xx_ohci_device);
153                 break;
154
155         case AR71XX_SOC_AR7130:
156         case AR71XX_SOC_AR7141:
157         case AR71XX_SOC_AR7161:
158                 ar71xx_usb_setup();
159                 platform_device_register(&ar71xx_ohci_device);
160                 platform_device_register(&ar71xx_ehci_device);
161                 break;
162
163         case AR71XX_SOC_AR9130:
164         case AR71XX_SOC_AR9132:
165                 ar91xx_usb_setup();
166                 ar71xx_ehci_data.is_ar91xx = 1;
167                 platform_device_register(&ar71xx_ehci_device);
168                 break;
169
170         default:
171                 BUG();
172         }
173 }
174
175 static struct resource ar71xx_uart_resources[] = {
176         {
177                 .start  = AR71XX_UART_BASE,
178                 .end    = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
179                 .flags  = IORESOURCE_MEM,
180         },
181 };
182
183 #define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
184 static struct plat_serial8250_port ar71xx_uart_data[] = {
185         {
186                 .mapbase        = AR71XX_UART_BASE,
187                 .irq            = AR71XX_MISC_IRQ_UART,
188                 .flags          = AR71XX_UART_FLAGS,
189                 .iotype         = UPIO_MEM32,
190                 .regshift       = 2,
191         }, {
192                 /* terminating entry */
193         }
194 };
195
196 static struct platform_device ar71xx_uart_device = {
197         .name           = "serial8250",
198         .id             = PLAT8250_DEV_PLATFORM,
199         .resource       = ar71xx_uart_resources,
200         .num_resources  = ARRAY_SIZE(ar71xx_uart_resources),
201         .dev = {
202                 .platform_data  = ar71xx_uart_data
203         },
204 };
205
206 void __init ar71xx_add_device_uart(void)
207 {
208         ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq;
209         platform_device_register(&ar71xx_uart_device);
210 }
211
212 static struct resource ar71xx_mdio_resources[] = {
213         {
214                 .name   = "mdio_base",
215                 .flags  = IORESOURCE_MEM,
216                 .start  = AR71XX_GE0_BASE,
217                 .end    = AR71XX_GE0_BASE + 0x200 - 1,
218         }
219 };
220
221 static struct ag71xx_mdio_platform_data ar71xx_mdio_data;
222
223 static struct platform_device ar71xx_mdio_device = {
224         .name           = "ag71xx-mdio",
225         .id             = -1,
226         .resource       = ar71xx_mdio_resources,
227         .num_resources  = ARRAY_SIZE(ar71xx_mdio_resources),
228         .dev = {
229                 .platform_data = &ar71xx_mdio_data,
230         },
231 };
232
233 void __init ar71xx_add_device_mdio(u32 phy_mask)
234 {
235         if (ar71xx_soc == AR71XX_SOC_AR7240)
236                 ar71xx_mdio_data.is_ar7240 = 1;
237
238         ar71xx_mdio_data.phy_mask = phy_mask;
239
240         platform_device_register(&ar71xx_mdio_device);
241 }
242
243 static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift)
244 {
245         void __iomem *base;
246         u32 t;
247
248         base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
249
250         t = __raw_readl(base + cfg_reg);
251         t &= ~(3 << shift);
252         t |=  (2 << shift);
253         __raw_writel(t, base + cfg_reg);
254         udelay(100);
255
256         __raw_writel(pll_val, base + pll_reg);
257
258         t |= (3 << shift);
259         __raw_writel(t, base + cfg_reg);
260         udelay(100);
261
262         t &= ~(3 << shift);
263         __raw_writel(t, base + cfg_reg);
264         udelay(100);
265
266         printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n",
267                 (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg));
268
269         iounmap(base);
270 }
271
272 struct ar71xx_eth_pll_data ar71xx_eth0_pll_data;
273 struct ar71xx_eth_pll_data ar71xx_eth1_pll_data;
274
275 static u32 ar71xx_get_eth_pll(unsigned int mac, int speed)
276 {
277         struct ar71xx_eth_pll_data *pll_data;
278         u32 pll_val;
279
280         switch (mac) {
281         case 0:
282                 pll_data = &ar71xx_eth0_pll_data;
283                 break;
284         case 1:
285                 pll_data = &ar71xx_eth1_pll_data;
286                 break;
287         default:
288                 BUG();
289         }
290
291         switch (speed) {
292         case SPEED_10:
293                 pll_val = pll_data->pll_10;
294                 break;
295         case SPEED_100:
296                 pll_val = pll_data->pll_100;
297                 break;
298         case SPEED_1000:
299                 pll_val = pll_data->pll_1000;
300                 break;
301         default:
302                 BUG();
303         }
304
305         return pll_val;
306 }
307
308 static void ar71xx_set_pll_ge0(int speed)
309 {
310         u32 val = ar71xx_get_eth_pll(0, speed);
311
312         ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK,
313                         val, AR71XX_ETH0_PLL_SHIFT);
314 }
315
316 static void ar71xx_set_pll_ge1(int speed)
317 {
318         u32 val = ar71xx_get_eth_pll(1, speed);
319
320         ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK,
321                          val, AR71XX_ETH1_PLL_SHIFT);
322 }
323
324 static void ar724x_set_pll_ge0(int speed)
325 {
326         /* TODO */
327 }
328
329 static void ar724x_set_pll_ge1(int speed)
330 {
331         /* TODO */
332 }
333
334 static void ar91xx_set_pll_ge0(int speed)
335 {
336         u32 val = ar71xx_get_eth_pll(0, speed);
337
338         ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK,
339                          val, AR91XX_ETH0_PLL_SHIFT);
340 }
341
342 static void ar91xx_set_pll_ge1(int speed)
343 {
344         u32 val = ar71xx_get_eth_pll(1, speed);
345
346         ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK,
347                          val, AR91XX_ETH1_PLL_SHIFT);
348 }
349
350 static void ar71xx_ddr_flush_ge0(void)
351 {
352         ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0);
353 }
354
355 static void ar71xx_ddr_flush_ge1(void)
356 {
357         ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1);
358 }
359
360 static void ar724x_ddr_flush_ge0(void)
361 {
362         ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE0);
363 }
364
365 static void ar724x_ddr_flush_ge1(void)
366 {
367         ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE1);
368 }
369
370 static void ar91xx_ddr_flush_ge0(void)
371 {
372         ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0);
373 }
374
375 static void ar91xx_ddr_flush_ge1(void)
376 {
377         ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1);
378 }
379
380 static struct resource ar71xx_eth0_resources[] = {
381         {
382                 .name   = "mac_base",
383                 .flags  = IORESOURCE_MEM,
384                 .start  = AR71XX_GE0_BASE,
385                 .end    = AR71XX_GE0_BASE + 0x200 - 1,
386         }, {
387                 .name   = "mii_ctrl",
388                 .flags  = IORESOURCE_MEM,
389                 .start  = AR71XX_MII_BASE + MII_REG_MII0_CTRL,
390                 .end    = AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3,
391         }, {
392                 .name   = "mac_irq",
393                 .flags  = IORESOURCE_IRQ,
394                 .start  = AR71XX_CPU_IRQ_GE0,
395                 .end    = AR71XX_CPU_IRQ_GE0,
396         },
397 };
398
399 struct ag71xx_platform_data ar71xx_eth0_data = {
400         .reset_bit      = RESET_MODULE_GE0_MAC,
401 };
402
403 static struct platform_device ar71xx_eth0_device = {
404         .name           = "ag71xx",
405         .id             = 0,
406         .resource       = ar71xx_eth0_resources,
407         .num_resources  = ARRAY_SIZE(ar71xx_eth0_resources),
408         .dev = {
409                 .platform_data = &ar71xx_eth0_data,
410         },
411 };
412
413 static struct resource ar71xx_eth1_resources[] = {
414         {
415                 .name   = "mac_base",
416                 .flags  = IORESOURCE_MEM,
417                 .start  = AR71XX_GE1_BASE,
418                 .end    = AR71XX_GE1_BASE + 0x200 - 1,
419         }, {
420                 .name   = "mii_ctrl",
421                 .flags  = IORESOURCE_MEM,
422                 .start  = AR71XX_MII_BASE + MII_REG_MII1_CTRL,
423                 .end    = AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3,
424         }, {
425                 .name   = "mac_irq",
426                 .flags  = IORESOURCE_IRQ,
427                 .start  = AR71XX_CPU_IRQ_GE1,
428                 .end    = AR71XX_CPU_IRQ_GE1,
429         },
430 };
431
432 struct ag71xx_platform_data ar71xx_eth1_data = {
433         .reset_bit      = RESET_MODULE_GE1_MAC,
434 };
435
436 static struct platform_device ar71xx_eth1_device = {
437         .name           = "ag71xx",
438         .id             = 1,
439         .resource       = ar71xx_eth1_resources,
440         .num_resources  = ARRAY_SIZE(ar71xx_eth1_resources),
441         .dev = {
442                 .platform_data = &ar71xx_eth1_data,
443         },
444 };
445
446 #define AR71XX_PLL_VAL_1000     0x00110000
447 #define AR71XX_PLL_VAL_100      0x00001099
448 #define AR71XX_PLL_VAL_10       0x00991099
449
450 #define AR724X_PLL_VAL_1000     0x00110000
451 #define AR724X_PLL_VAL_100      0x00001099
452 #define AR724X_PLL_VAL_10       0x00991099
453
454 #define AR91XX_PLL_VAL_1000     0x1a000000
455 #define AR91XX_PLL_VAL_100      0x13000a44
456 #define AR91XX_PLL_VAL_10       0x00441099
457
458 static void __init ar71xx_init_eth_pll_data(unsigned int id)
459 {
460         struct ar71xx_eth_pll_data *pll_data;
461         u32 pll_10, pll_100, pll_1000;
462
463         switch (id) {
464         case 0:
465                 pll_data = &ar71xx_eth0_pll_data;
466                 break;
467         case 1:
468                 pll_data = &ar71xx_eth1_pll_data;
469                 break;
470         default:
471                 BUG();
472         }
473
474         switch (ar71xx_soc) {
475         case AR71XX_SOC_AR7130:
476         case AR71XX_SOC_AR7141:
477         case AR71XX_SOC_AR7161:
478                 pll_10 = AR71XX_PLL_VAL_10;
479                 pll_100 = AR71XX_PLL_VAL_100;
480                 pll_1000 = AR71XX_PLL_VAL_1000;
481                 break;
482
483         case AR71XX_SOC_AR7240:
484                 pll_10 = AR724X_PLL_VAL_10;
485                 pll_100 = AR724X_PLL_VAL_100;
486                 pll_1000 = AR724X_PLL_VAL_1000;
487                 break;
488
489         case AR71XX_SOC_AR9130:
490         case AR71XX_SOC_AR9132:
491                 pll_10 = AR91XX_PLL_VAL_10;
492                 pll_100 = AR91XX_PLL_VAL_100;
493                 pll_1000 = AR91XX_PLL_VAL_1000;
494                 break;
495         default:
496                 BUG();
497         }
498
499         if (!pll_data->pll_10)
500                 pll_data->pll_10 = pll_10;
501
502         if (!pll_data->pll_100)
503                 pll_data->pll_100 = pll_100;
504
505         if (!pll_data->pll_1000)
506                 pll_data->pll_1000 = pll_1000;
507 }
508
509 static int ar71xx_eth_instance __initdata;
510 void __init ar71xx_add_device_eth(unsigned int id)
511 {
512         struct platform_device *pdev;
513         struct ag71xx_platform_data *pdata;
514
515         ar71xx_init_eth_pll_data(id);
516
517         switch (id) {
518         case 0:
519                 switch (ar71xx_eth0_data.phy_if_mode) {
520                 case PHY_INTERFACE_MODE_MII:
521                         ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII;
522                         break;
523                 case PHY_INTERFACE_MODE_GMII:
524                         ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII;
525                         break;
526                 case PHY_INTERFACE_MODE_RGMII:
527                         ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII;
528                         break;
529                 case PHY_INTERFACE_MODE_RMII:
530                         ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII;
531                         break;
532                 default:
533                         printk(KERN_ERR "ar71xx: invalid PHY interface mode "
534                                         "for eth0\n");
535                         return;
536                 }
537                 pdev = &ar71xx_eth0_device;
538                 break;
539         case 1:
540                 switch (ar71xx_eth1_data.phy_if_mode) {
541                 case PHY_INTERFACE_MODE_RMII:
542                         ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII;
543                         break;
544                 case PHY_INTERFACE_MODE_RGMII:
545                         ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII;
546                         break;
547                 default:
548                         printk(KERN_ERR "ar71xx: invalid PHY interface mode "
549                                         "for eth1\n");
550                         return;
551                 }
552                 pdev = &ar71xx_eth1_device;
553                 break;
554         default:
555                 printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id);
556                 return;
557         }
558
559         pdata = pdev->dev.platform_data;
560
561         switch (ar71xx_soc) {
562         case AR71XX_SOC_AR7130:
563                 pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
564                                       : ar71xx_ddr_flush_ge0;
565                 pdata->set_pll =  id ? ar71xx_set_pll_ge1
566                                      : ar71xx_set_pll_ge0;
567                 break;
568
569         case AR71XX_SOC_AR7141:
570         case AR71XX_SOC_AR7161:
571                 pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
572                                       : ar71xx_ddr_flush_ge0;
573                 pdata->set_pll =  id ? ar71xx_set_pll_ge1
574                                      : ar71xx_set_pll_ge0;
575                 pdata->has_gbit = 1;
576                 break;
577
578         case AR71XX_SOC_AR7240:
579                 pdata->ddr_flush = id ? ar724x_ddr_flush_ge1
580                                       : ar724x_ddr_flush_ge0;
581                 pdata->set_pll =  id ? ar724x_set_pll_ge1
582                                      : ar724x_set_pll_ge0;
583                 pdata->is_ar724x = 1;
584                 break;
585
586         case AR71XX_SOC_AR9130:
587                 pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
588                                       : ar91xx_ddr_flush_ge0;
589                 pdata->set_pll =  id ? ar91xx_set_pll_ge1
590                                      : ar91xx_set_pll_ge0;
591                 pdata->is_ar91xx = 1;
592                 break;
593
594         case AR71XX_SOC_AR9132:
595                 pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
596                                       : ar91xx_ddr_flush_ge0;
597                 pdata->set_pll =  id ? ar91xx_set_pll_ge1
598                                       : ar91xx_set_pll_ge0;
599                 pdata->is_ar91xx = 1;
600                 pdata->has_gbit = 1;
601                 break;
602
603         default:
604                 BUG();
605         }
606
607         switch (pdata->phy_if_mode) {
608         case PHY_INTERFACE_MODE_GMII:
609         case PHY_INTERFACE_MODE_RGMII:
610                 if (!pdata->has_gbit) {
611                         printk(KERN_ERR "ar71xx: no gbit available on eth%d\n",
612                                         id);
613                         return;
614                 }
615                 /* fallthrough */
616         default:
617                 break;
618         }
619
620         if (is_valid_ether_addr(ar71xx_mac_base)) {
621                 memcpy(pdata->mac_addr, ar71xx_mac_base, ETH_ALEN);
622                 pdata->mac_addr[5] += ar71xx_eth_instance;
623         } else {
624                 random_ether_addr(pdata->mac_addr);
625                 printk(KERN_DEBUG
626                         "ar71xx: using random MAC address for eth%d\n",
627                         ar71xx_eth_instance);
628         }
629
630         if (pdata->mii_bus_dev == NULL)
631                 pdata->mii_bus_dev = &ar71xx_mdio_device.dev;
632
633         /* Reset the device */
634         ar71xx_device_stop(pdata->reset_bit);
635         mdelay(100);
636
637         ar71xx_device_start(pdata->reset_bit);
638         mdelay(100);
639
640         platform_device_register(pdev);
641         ar71xx_eth_instance++;
642 }
643
644 static struct resource ar71xx_spi_resources[] = {
645         [0] = {
646                 .start  = AR71XX_SPI_BASE,
647                 .end    = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
648                 .flags  = IORESOURCE_MEM,
649         },
650 };
651
652 static struct platform_device ar71xx_spi_device = {
653         .name           = "ar71xx-spi",
654         .id             = -1,
655         .resource       = ar71xx_spi_resources,
656         .num_resources  = ARRAY_SIZE(ar71xx_spi_resources),
657 };
658
659 void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
660                                 struct spi_board_info const *info,
661                                 unsigned n)
662 {
663         spi_register_board_info(info, n);
664         ar71xx_spi_device.dev.platform_data = pdata;
665         platform_device_register(&ar71xx_spi_device);
666 }
667
668 void __init ar71xx_add_device_wdt(void)
669 {
670         platform_device_register_simple("ar71xx-wdt", -1, NULL, 0);
671 }
672
673 void __init ar71xx_set_mac_base(unsigned char *mac)
674 {
675         memcpy(ar71xx_mac_base, mac, ETH_ALEN);
676 }
677
678 void __init ar71xx_parse_mac_addr(char *mac_str)
679 {
680         u8 tmp[ETH_ALEN];
681         int t;
682
683         t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
684                         &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
685
686         if (t != ETH_ALEN)
687                 t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx",
688                         &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
689
690         if (t == ETH_ALEN)
691                 ar71xx_set_mac_base(tmp);
692         else
693                 printk(KERN_DEBUG "ar71xx: failed to parse mac address "
694                                 "\"%s\"\n", mac_str);
695 }
696
697 static struct platform_device ar71xx_dsa_switch_device = {
698         .name           = "dsa",
699         .id             = 0,
700 };
701
702 void __init ar71xx_add_device_dsa(unsigned int id,
703                                   struct dsa_platform_data *d)
704 {
705         int i;
706
707         switch (id) {
708         case 0:
709                 d->netdev = &ar71xx_eth0_device.dev;
710                 break;
711         case 1:
712                 d->netdev = &ar71xx_eth1_device.dev;
713                 break;
714         default:
715                 printk(KERN_ERR
716                         "ar71xx: invalid ethernet id %d for DSA switch\n",
717                         id);
718                 return;
719         }
720
721         for (i = 0; i < d->nr_chips; i++)
722                 d->chip[i].mii_bus = &ar71xx_mdio_device.dev;
723
724         ar71xx_dsa_switch_device.dev.platform_data = d;
725
726         platform_device_register(&ar71xx_dsa_switch_device);
727 }