Root/target/linux/ar71xx/files/arch/mips/ar71xx/devices.c

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

Archive Download this file



interactive