diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2006-11-04 20:18:11 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2006-11-06 15:55:37 -0500 |
commit | 907c51b2d1705b022c3fb65b66cb4e5e09346433 (patch) | |
tree | 0ba2b3bcc9bda29e4d334a894a4e508c6f2a8acc /arch/mips/momentum | |
parent | d6b861c6402307e30c7df24dcda911df64a5f9d6 (diff) |
[MIPS] Ocelot C: Fix MAC address detection after platform_device conversion.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/momentum')
-rw-r--r-- | arch/mips/momentum/ocelot_c/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/momentum/ocelot_c/platform.c | 201 | ||||
-rw-r--r-- | arch/mips/momentum/ocelot_c/prom.c | 58 | ||||
-rw-r--r-- | arch/mips/momentum/ocelot_c/setup.c | 121 |
4 files changed, 202 insertions, 180 deletions
diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile index 94802b4db472..d69161aa1675 100644 --- a/arch/mips/momentum/ocelot_c/Makefile +++ b/arch/mips/momentum/ocelot_c/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for Momentum Computer's Ocelot-C and -CS boards. | 2 | # Makefile for Momentum Computer's Ocelot-C and -CS boards. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += cpci-irq.o irq.o prom.o reset.o \ | 5 | obj-y += cpci-irq.o irq.o platform.o prom.o reset.o \ |
6 | setup.o uart-irq.o | 6 | setup.o uart-irq.o |
7 | 7 | ||
8 | obj-$(CONFIG_KGDB) += dbg_io.o | 8 | obj-$(CONFIG_KGDB) += dbg_io.o |
diff --git a/arch/mips/momentum/ocelot_c/platform.c b/arch/mips/momentum/ocelot_c/platform.c new file mode 100644 index 000000000000..6c495b2f1560 --- /dev/null +++ b/arch/mips/momentum/ocelot_c/platform.c | |||
@@ -0,0 +1,201 @@ | |||
1 | #include <linux/delay.h> | ||
2 | #include <linux/if_ether.h> | ||
3 | #include <linux/ioport.h> | ||
4 | #include <linux/mv643xx.h> | ||
5 | #include <linux/platform_device.h> | ||
6 | |||
7 | #include "ocelot_c_fpga.h" | ||
8 | |||
9 | #if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) | ||
10 | |||
11 | static struct resource mv643xx_eth_shared_resources[] = { | ||
12 | [0] = { | ||
13 | .name = "ethernet shared base", | ||
14 | .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, | ||
15 | .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + | ||
16 | MV643XX_ETH_SHARED_REGS_SIZE - 1, | ||
17 | .flags = IORESOURCE_MEM, | ||
18 | }, | ||
19 | }; | ||
20 | |||
21 | static struct platform_device mv643xx_eth_shared_device = { | ||
22 | .name = MV643XX_ETH_SHARED_NAME, | ||
23 | .id = 0, | ||
24 | .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), | ||
25 | .resource = mv643xx_eth_shared_resources, | ||
26 | }; | ||
27 | |||
28 | #define MV_SRAM_BASE 0xfe000000UL | ||
29 | #define MV_SRAM_SIZE (256 * 1024) | ||
30 | |||
31 | #define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) | ||
32 | #define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) | ||
33 | |||
34 | #define MV_SRAM_BASE_ETH0 MV_SRAM_BASE | ||
35 | #define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) | ||
36 | |||
37 | #define MV64x60_IRQ_ETH_0 48 | ||
38 | #define MV64x60_IRQ_ETH_1 49 | ||
39 | |||
40 | #ifdef CONFIG_MV643XX_ETH_0 | ||
41 | |||
42 | static struct resource mv64x60_eth0_resources[] = { | ||
43 | [0] = { | ||
44 | .name = "eth0 irq", | ||
45 | .start = MV64x60_IRQ_ETH_0, | ||
46 | .end = MV64x60_IRQ_ETH_0, | ||
47 | .flags = IORESOURCE_IRQ, | ||
48 | }, | ||
49 | }; | ||
50 | |||
51 | static char eth0_mac_addr[ETH_ALEN]; | ||
52 | |||
53 | static struct mv643xx_eth_platform_data eth0_pd = { | ||
54 | .mac_addr = eth0_mac_addr, | ||
55 | |||
56 | .tx_sram_addr = MV_SRAM_BASE_ETH0, | ||
57 | .tx_sram_size = MV_SRAM_TXRING_SIZE, | ||
58 | .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, | ||
59 | |||
60 | .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, | ||
61 | .rx_sram_size = MV_SRAM_RXRING_SIZE, | ||
62 | .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, | ||
63 | }; | ||
64 | |||
65 | static struct platform_device eth0_device = { | ||
66 | .name = MV643XX_ETH_NAME, | ||
67 | .id = 0, | ||
68 | .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), | ||
69 | .resource = mv64x60_eth0_resources, | ||
70 | .dev = { | ||
71 | .platform_data = ð0_pd, | ||
72 | }, | ||
73 | }; | ||
74 | #endif /* CONFIG_MV643XX_ETH_0 */ | ||
75 | |||
76 | #ifdef CONFIG_MV643XX_ETH_1 | ||
77 | |||
78 | static struct resource mv64x60_eth1_resources[] = { | ||
79 | [0] = { | ||
80 | .name = "eth1 irq", | ||
81 | .start = MV64x60_IRQ_ETH_1, | ||
82 | .end = MV64x60_IRQ_ETH_1, | ||
83 | .flags = IORESOURCE_IRQ, | ||
84 | }, | ||
85 | }; | ||
86 | |||
87 | static char eth1_mac_addr[ETH_ALEN]; | ||
88 | |||
89 | static struct mv643xx_eth_platform_data eth1_pd = { | ||
90 | .mac_addr = eth1_mac_addr, | ||
91 | |||
92 | .tx_sram_addr = MV_SRAM_BASE_ETH1, | ||
93 | .tx_sram_size = MV_SRAM_TXRING_SIZE, | ||
94 | .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, | ||
95 | |||
96 | .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, | ||
97 | .rx_sram_size = MV_SRAM_RXRING_SIZE, | ||
98 | .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, | ||
99 | }; | ||
100 | |||
101 | static struct platform_device eth1_device = { | ||
102 | .name = MV643XX_ETH_NAME, | ||
103 | .id = 1, | ||
104 | .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), | ||
105 | .resource = mv64x60_eth1_resources, | ||
106 | .dev = { | ||
107 | .platform_data = ð1_pd, | ||
108 | }, | ||
109 | }; | ||
110 | #endif /* CONFIG_MV643XX_ETH_1 */ | ||
111 | |||
112 | static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { | ||
113 | &mv643xx_eth_shared_device, | ||
114 | #ifdef CONFIG_MV643XX_ETH_0 | ||
115 | ð0_device, | ||
116 | #endif | ||
117 | #ifdef CONFIG_MV643XX_ETH_1 | ||
118 | ð1_device, | ||
119 | #endif | ||
120 | /* The third port is not wired up on the Ocelot C */ | ||
121 | }; | ||
122 | |||
123 | static u8 __init exchange_bit(u8 val, u8 cs) | ||
124 | { | ||
125 | /* place the data */ | ||
126 | OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); | ||
127 | udelay(1); | ||
128 | |||
129 | /* turn the clock on */ | ||
130 | OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); | ||
131 | udelay(1); | ||
132 | |||
133 | /* turn the clock off and read-strobe */ | ||
134 | OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); | ||
135 | |||
136 | /* return the data */ | ||
137 | return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1; | ||
138 | } | ||
139 | |||
140 | static void __init get_mac(char dest[6]) | ||
141 | { | ||
142 | u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | ||
143 | int i,j; | ||
144 | |||
145 | for (i = 0; i < 12; i++) | ||
146 | exchange_bit(read_opcode[i], 1); | ||
147 | |||
148 | for (j = 0; j < 6; j++) { | ||
149 | dest[j] = 0; | ||
150 | for (i = 0; i < 8; i++) { | ||
151 | dest[j] <<= 1; | ||
152 | dest[j] |= exchange_bit(0, 1); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | /* turn off CS */ | ||
157 | exchange_bit(0,0); | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Copy and increment ethernet MAC address by a small value. | ||
162 | * | ||
163 | * This is useful for systems where the only one MAC address is stored in | ||
164 | * non-volatile memory for multiple ports. | ||
165 | */ | ||
166 | static inline void eth_mac_add(unsigned char *dst, unsigned char *src, | ||
167 | unsigned int add) | ||
168 | { | ||
169 | int i; | ||
170 | |||
171 | BUG_ON(add >= 256); | ||
172 | |||
173 | for (i = ETH_ALEN; i >= 0; i--) { | ||
174 | dst[i] = src[i] + add; | ||
175 | add = dst[i] < src[i]; /* compute carry */ | ||
176 | } | ||
177 | |||
178 | WARN_ON(add); | ||
179 | } | ||
180 | |||
181 | static int __init mv643xx_eth_add_pds(void) | ||
182 | { | ||
183 | unsigned char mac[ETH_ALEN]; | ||
184 | int ret; | ||
185 | |||
186 | get_mac(mac); | ||
187 | #ifdef CONFIG_MV643XX_ETH_0 | ||
188 | eth_mac_add(eth1_mac_addr, mac, 0); | ||
189 | #endif | ||
190 | #ifdef CONFIG_MV643XX_ETH_1 | ||
191 | eth_mac_add(eth1_mac_addr, mac, 1); | ||
192 | #endif | ||
193 | ret = platform_add_devices(mv643xx_eth_pd_devs, | ||
194 | ARRAY_SIZE(mv643xx_eth_pd_devs)); | ||
195 | |||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | device_initcall(mv643xx_eth_add_pds); | ||
200 | |||
201 | #endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ | ||
diff --git a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c index 1f67728d6a49..d0b77e101d74 100644 --- a/arch/mips/momentum/ocelot_c/prom.c +++ b/arch/mips/momentum/ocelot_c/prom.c | |||
@@ -31,10 +31,6 @@ struct callvectors* debug_vectors; | |||
31 | extern unsigned long marvell_base; | 31 | extern unsigned long marvell_base; |
32 | extern unsigned int cpu_clock; | 32 | extern unsigned int cpu_clock; |
33 | 33 | ||
34 | #ifdef CONFIG_MV643XX_ETH | ||
35 | extern unsigned char prom_mac_addr_base[6]; | ||
36 | #endif | ||
37 | |||
38 | const char *get_system_type(void) | 34 | const char *get_system_type(void) |
39 | { | 35 | { |
40 | #ifdef CONFIG_CPU_SR71000 | 36 | #ifdef CONFIG_CPU_SR71000 |
@@ -44,55 +40,6 @@ const char *get_system_type(void) | |||
44 | #endif | 40 | #endif |
45 | } | 41 | } |
46 | 42 | ||
47 | #ifdef CONFIG_MV643XX_ETH | ||
48 | static void burn_clocks(void) | ||
49 | { | ||
50 | int i; | ||
51 | |||
52 | /* this loop should burn at least 1us -- this should be plenty */ | ||
53 | for (i = 0; i < 0x10000; i++) | ||
54 | ; | ||
55 | } | ||
56 | |||
57 | static u8 exchange_bit(u8 val, u8 cs) | ||
58 | { | ||
59 | /* place the data */ | ||
60 | OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); | ||
61 | burn_clocks(); | ||
62 | |||
63 | /* turn the clock on */ | ||
64 | OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); | ||
65 | burn_clocks(); | ||
66 | |||
67 | /* turn the clock off and read-strobe */ | ||
68 | OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); | ||
69 | |||
70 | /* return the data */ | ||
71 | return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); | ||
72 | } | ||
73 | |||
74 | void get_mac(char dest[6]) | ||
75 | { | ||
76 | u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | ||
77 | int i,j; | ||
78 | |||
79 | for (i = 0; i < 12; i++) | ||
80 | exchange_bit(read_opcode[i], 1); | ||
81 | |||
82 | for (j = 0; j < 6; j++) { | ||
83 | dest[j] = 0; | ||
84 | for (i = 0; i < 8; i++) { | ||
85 | dest[j] <<= 1; | ||
86 | dest[j] |= exchange_bit(0, 1); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | /* turn off CS */ | ||
91 | exchange_bit(0,0); | ||
92 | } | ||
93 | #endif | ||
94 | |||
95 | |||
96 | #ifdef CONFIG_64BIT | 43 | #ifdef CONFIG_64BIT |
97 | 44 | ||
98 | unsigned long signext(unsigned long addr) | 45 | unsigned long signext(unsigned long addr) |
@@ -226,11 +173,6 @@ void __init prom_init(void) | |||
226 | mips_machgroup = MACH_GROUP_MOMENCO; | 173 | mips_machgroup = MACH_GROUP_MOMENCO; |
227 | mips_machtype = MACH_MOMENCO_OCELOT_C; | 174 | mips_machtype = MACH_MOMENCO_OCELOT_C; |
228 | 175 | ||
229 | #ifdef CONFIG_MV643XX_ETH | ||
230 | /* get the base MAC address for on-board ethernet ports */ | ||
231 | get_mac(prom_mac_addr_base); | ||
232 | #endif | ||
233 | |||
234 | #ifndef CONFIG_64BIT | 176 | #ifndef CONFIG_64BIT |
235 | debug_vectors->printf("Booting Linux kernel...\n"); | 177 | debug_vectors->printf("Booting Linux kernel...\n"); |
236 | #endif | 178 | #endif |
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c index b0e82a097f7e..0b6b2338cfb4 100644 --- a/arch/mips/momentum/ocelot_c/setup.c +++ b/arch/mips/momentum/ocelot_c/setup.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <linux/sched.h> | 50 | #include <linux/sched.h> |
51 | #include <linux/interrupt.h> | 51 | #include <linux/interrupt.h> |
52 | #include <linux/pci.h> | 52 | #include <linux/pci.h> |
53 | #include <linux/platform_device.h> | ||
54 | #include <linux/pm.h> | 53 | #include <linux/pm.h> |
55 | #include <linux/timex.h> | 54 | #include <linux/timex.h> |
56 | #include <linux/vmalloc.h> | 55 | #include <linux/vmalloc.h> |
@@ -361,123 +360,3 @@ static int io_base_ioremap(void) | |||
361 | } | 360 | } |
362 | 361 | ||
363 | module_init(io_base_ioremap); | 362 | module_init(io_base_ioremap); |
364 | |||
365 | #if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) | ||
366 | |||
367 | static struct resource mv643xx_eth_shared_resources[] = { | ||
368 | [0] = { | ||
369 | .name = "ethernet shared base", | ||
370 | .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, | ||
371 | .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + | ||
372 | MV643XX_ETH_SHARED_REGS_SIZE - 1, | ||
373 | .flags = IORESOURCE_MEM, | ||
374 | }, | ||
375 | }; | ||
376 | |||
377 | static struct platform_device mv643xx_eth_shared_device = { | ||
378 | .name = MV643XX_ETH_SHARED_NAME, | ||
379 | .id = 0, | ||
380 | .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), | ||
381 | .resource = mv643xx_eth_shared_resources, | ||
382 | }; | ||
383 | |||
384 | #define MV_SRAM_BASE 0xfe000000UL | ||
385 | #define MV_SRAM_SIZE (256 * 1024) | ||
386 | |||
387 | #define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) | ||
388 | #define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) | ||
389 | |||
390 | #define MV_SRAM_BASE_ETH0 MV_SRAM_BASE | ||
391 | #define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) | ||
392 | |||
393 | #define MV64x60_IRQ_ETH_0 48 | ||
394 | #define MV64x60_IRQ_ETH_1 49 | ||
395 | |||
396 | #ifdef CONFIG_MV643XX_ETH_0 | ||
397 | |||
398 | static struct resource mv64x60_eth0_resources[] = { | ||
399 | [0] = { | ||
400 | .name = "eth0 irq", | ||
401 | .start = MV64x60_IRQ_ETH_0, | ||
402 | .end = MV64x60_IRQ_ETH_0, | ||
403 | .flags = IORESOURCE_IRQ, | ||
404 | }, | ||
405 | }; | ||
406 | |||
407 | static struct mv643xx_eth_platform_data eth0_pd = { | ||
408 | .tx_sram_addr = MV_SRAM_BASE_ETH0, | ||
409 | .tx_sram_size = MV_SRAM_TXRING_SIZE, | ||
410 | .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, | ||
411 | |||
412 | .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, | ||
413 | .rx_sram_size = MV_SRAM_RXRING_SIZE, | ||
414 | .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, | ||
415 | }; | ||
416 | |||
417 | static struct platform_device eth0_device = { | ||
418 | .name = MV643XX_ETH_NAME, | ||
419 | .id = 0, | ||
420 | .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), | ||
421 | .resource = mv64x60_eth0_resources, | ||
422 | .dev = { | ||
423 | .platform_data = ð0_pd, | ||
424 | }, | ||
425 | }; | ||
426 | #endif /* CONFIG_MV643XX_ETH_0 */ | ||
427 | |||
428 | #ifdef CONFIG_MV643XX_ETH_1 | ||
429 | |||
430 | static struct resource mv64x60_eth1_resources[] = { | ||
431 | [0] = { | ||
432 | .name = "eth1 irq", | ||
433 | .start = MV64x60_IRQ_ETH_1, | ||
434 | .end = MV64x60_IRQ_ETH_1, | ||
435 | .flags = IORESOURCE_IRQ, | ||
436 | }, | ||
437 | }; | ||
438 | |||
439 | static struct mv643xx_eth_platform_data eth1_pd = { | ||
440 | .tx_sram_addr = MV_SRAM_BASE_ETH1, | ||
441 | .tx_sram_size = MV_SRAM_TXRING_SIZE, | ||
442 | .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, | ||
443 | |||
444 | .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, | ||
445 | .rx_sram_size = MV_SRAM_RXRING_SIZE, | ||
446 | .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, | ||
447 | }; | ||
448 | |||
449 | static struct platform_device eth1_device = { | ||
450 | .name = MV643XX_ETH_NAME, | ||
451 | .id = 1, | ||
452 | .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), | ||
453 | .resource = mv64x60_eth1_resources, | ||
454 | .dev = { | ||
455 | .platform_data = ð1_pd, | ||
456 | }, | ||
457 | }; | ||
458 | #endif /* CONFIG_MV643XX_ETH_1 */ | ||
459 | |||
460 | static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { | ||
461 | &mv643xx_eth_shared_device, | ||
462 | #ifdef CONFIG_MV643XX_ETH_0 | ||
463 | ð0_device, | ||
464 | #endif | ||
465 | #ifdef CONFIG_MV643XX_ETH_1 | ||
466 | ð1_device, | ||
467 | #endif | ||
468 | /* The third port is not wired up on the Ocelot C */ | ||
469 | }; | ||
470 | |||
471 | int mv643xx_eth_add_pds(void) | ||
472 | { | ||
473 | int ret; | ||
474 | |||
475 | ret = platform_add_devices(mv643xx_eth_pd_devs, | ||
476 | ARRAY_SIZE(mv643xx_eth_pd_devs)); | ||
477 | |||
478 | return ret; | ||
479 | } | ||
480 | |||
481 | device_initcall(mv643xx_eth_add_pds); | ||
482 | |||
483 | #endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ | ||