2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16 * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
19 #include <linux/autoconf.h>
20 #include <linux/init.h>
21 #include <linux/module.h>
22 #include <linux/types.h>
23 #include <linux/string.h>
24 #include <linux/mtd/physmap.h>
25 #include <linux/kernel.h>
26 #include <linux/reboot.h>
27 #include <linux/platform_device.h>
28 #include <asm/bootinfo.h>
29 #include <asm/reboot.h>
33 #include <linux/etherdevice.h>
34 #include <asm/ifxmips/ifxmips.h>
35 #include <linux/leds.h>
37 #define MAX_BOARD_NAME_LEN 32
38 #define MAX_IFXMIPS_DEVS 9
40 #define SYSTEM_DANUBE "Danube"
41 #define SYSTEM_DANUBE_CHIPID1 0x10129083
42 #define SYSTEM_DANUBE_CHIPID2 0x3012B083
44 #define SYSTEM_TWINPASS "Twinpass"
45 #define SYSTEM_TWINPASS_CHIPID 0x3012D083
47 extern int ifxmips_pci_external_clock
;
49 static unsigned int chiprev
;
50 static int cmdline_mac
= 0;
51 char board_name
[MAX_BOARD_NAME_LEN
+ 1] = { 0 };
53 struct ifxmips_board
{
55 unsigned int system_type
;
56 struct platform_device
*devs
[MAX_IFXMIPS_DEVS
];
57 struct resource reset_resource
;
58 struct resource gpiodev_resource
;
59 int pci_external_clock
;
63 spinlock_t ebu_lock
= SPIN_LOCK_UNLOCKED
;
64 EXPORT_SYMBOL_GPL(ebu_lock
);
66 static unsigned char ifxmips_mii_mac
[6];
67 static int ifxmips_brn
= 0;
69 static struct platform_device
73 .name
= "ifxmips_led",
76 static struct platform_device
80 .name
= "ifxmips_gpio",
84 static struct platform_device
88 .name
= "ifxmips_mii0",
90 .platform_data
= ifxmips_mii_mac
,
94 static struct platform_device
98 .name
= "ifxmips_wdt",
101 static struct resource
102 ifxmips_mtd_resource
= {
103 .start
= IFXMIPS_FLASH_START
,
104 .end
= IFXMIPS_FLASH_START
+ IFXMIPS_FLASH_MAX
- 1,
105 .flags
= IORESOURCE_MEM
,
108 static struct platform_device
112 .name
= "ifxmips_mtd",
114 .resource
= &ifxmips_mtd_resource
,
117 static struct platform_device
124 #ifdef CONFIG_LEDS_GPIO
125 static struct gpio_led arv4519_leds
[] = {
126 { .name
= "ifxmips:green:power0", .gpio
= 3, .active_low
= 0, },
127 { .name
= "ifxmips:red:power1", .gpio
= 7, .active_low
= 1, },
128 { .name
= "ifxmips:green:adsl", .gpio
= 4, .active_low
= 1, },
129 { .name
= "ifxmips:green:internet0", .gpio
= 5, .active_low
= 0, },
130 { .name
= "ifxmips:red:internet1", .gpio
= 8, .active_low
= 1, },
131 { .name
= "ifxmips:green:wlan", .gpio
= 6, .active_low
= 1, },
132 { .name
= "ifxmips:green:usb", .gpio
= 19, .active_low
= 1, },
135 static const struct gpio_led_platform_data arv4519_led_data
= {
136 .num_leds
= ARRAY_SIZE(arv4519_leds
),
137 .leds
= (void *) arv4519_leds
,
140 static struct platform_device arv4519_gpio_leds
= {
144 .platform_data
= (void *) &arv4519_led_data
,
150 get_system_type(void)
152 chiprev
= ifxmips_r32(IFXMIPS_MPS_CHIPID
);
155 case SYSTEM_DANUBE_CHIPID1
:
156 case SYSTEM_DANUBE_CHIPID2
:
157 return SYSTEM_DANUBE
;
159 case SYSTEM_TWINPASS_CHIPID
:
160 return SYSTEM_TWINPASS
;
163 return BOARD_SYSTEM_TYPE
;
167 ifxmips_set_board_type(char *str
)
169 str
= strchr(str
, '=');
173 if(strlen(str
) > MAX_BOARD_NAME_LEN
)
175 strncpy(board_name
, str
, MAX_BOARD_NAME_LEN
);
176 printk("bootloader told us, that this is a %s board\n", board_name
);
180 __setup("ifxmips_board", ifxmips_set_board_type
);
183 (((x >='0' && x <= '9') || (x >='a' && x <= 'f') || (x >='A' && x <= 'F'))?(1):(0))
186 ifxmips_set_mii0_mac(char *str
)
189 str
= strchr(str
, '=');
193 if(strlen(str
) != 17)
195 for(i
= 0; i
< 6; i
++)
197 if(!IS_HEX(str
[3 * i
]) || !IS_HEX(str
[(3 * i
) + 1]))
199 if((i
!= 5) && (str
[(3 * i
) + 2] != ':'))
201 ifxmips_mii_mac
[i
] = simple_strtoul(&str
[3 * i
], NULL
, 16);
203 if(is_valid_ether_addr(ifxmips_mii_mac
))
208 __setup("mii0_mac", ifxmips_set_mii0_mac
);
211 static struct ifxmips_board boards
[] =
215 .system_type
= SYSTEM_DANUBE_CHIPID1
,
218 &ifxmips_led
, &ifxmips_gpio
, &ifxmips_mii
,
219 &ifxmips_mtd
, &ifxmips_wdt
, &ifxmips_gpio_dev
,
230 .start
= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) |
231 (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12),
232 .end
= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) |
233 (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12),
238 .system_type
= SYSTEM_TWINPASS_CHIPID
,
241 &ifxmips_led
, &ifxmips_gpio
, &ifxmips_mii
,
242 &ifxmips_mtd
, &ifxmips_wdt
, &ifxmips_gpio_dev
,
253 .start
= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) |
254 (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12),
255 .end
= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) |
256 (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12),
261 .system_type
= SYSTEM_DANUBE_CHIPID2
,
264 &ifxmips_gpio
, &ifxmips_mii
,
265 &ifxmips_mtd
, &ifxmips_wdt
, &ifxmips_gpio_dev
,
266 #ifdef CONFIG_LEDS_GPIO
279 .start
= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) |
280 (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12),
281 .end
= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) |
282 (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12),
284 .pci_external_clock
= 1,
290 ifxmips_find_brn_block(void){
291 unsigned char temp
[8];
292 memcpy_fromio(temp
, (void*)KSEG1ADDR(IFXMIPS_FLASH_START
+ 0x800000 - 0x10000), 8);
293 if(memcmp(temp
, "BRN-BOOT", 8) == 0)
296 memcpy_fromio(ifxmips_mii_mac
, (void*)KSEG1ADDR(IFXMIPS_FLASH_START
+ 0x800000 - 0x10000 + 0x16), 6);
305 ifxmips_has_brn_block(void)
309 EXPORT_SYMBOL(ifxmips_has_brn_block
);
311 struct ifxmips_board
*
312 ifxmips_find_board(void)
317 for(i
= 0; i
< ARRAY_SIZE(boards
); i
++)
318 if((boards
[i
].system_type
== chiprev
) && (!strcmp(boards
[i
].name
, board_name
)))
324 ifxmips_init_devices(void)
326 struct ifxmips_board
*board
= ifxmips_find_board();
328 chiprev
= ifxmips_r32(IFXMIPS_MPS_CHIPID
);
329 ifxmips_brn
= ifxmips_find_brn_block();
332 random_ether_addr(ifxmips_mii_mac
);
338 case SYSTEM_DANUBE_CHIPID1
:
339 case SYSTEM_DANUBE_CHIPID2
:
342 case SYSTEM_TWINPASS_CHIPID
:
347 ifxmips_gpio
.resource
= &board
->reset_resource
;
348 ifxmips_gpio_dev
.resource
= &board
->gpiodev_resource
;
349 if(board
->pci_external_clock
)
350 ifxmips_pci_external_clock
= 1;
351 printk("using board definition %s\n", board
->name
);
352 return platform_add_devices(board
->devs
, board
->num_devs
);
355 arch_initcall(ifxmips_init_devices
);