Index: linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c =================================================================== --- linux-2.6.24.2.orig/arch/arm/mach-ixp4xx/avila-setup.c +++ linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c @@ -14,10 +14,18 @@ #include #include #include +#include +#include +#include #include #include #include #include +#ifdef CONFIG_SENSORS_EEPROM +# include +# include +#endif + #include #include @@ -177,6 +185,118 @@ static struct platform_device *avila_eth &avila_eth[1] }; +#ifdef CONFIG_SENSORS_EEPROM +struct avila_board_info { + unsigned char *model; + int npes_used; + int npeb_phy; + int npec_phy; +}; + +static struct avila_board_info avila_boards[] = { + { + .model = "GW2342", + .npes_used = 2, + .npeb_phy = 0, + .npec_phy = 1, + }, { + .model = "GW2347", + .npes_used = 1, + .npeb_phy = 1, + }, { + .model = "GW2348-2", + .npes_used = 2, + .npeb_phy = 0, + .npec_phy = 1, + }, { + .model = "GW2348-4", + .npes_used = 2, + .npeb_phy = 0, + .npec_phy = 1, + }, { + .model = "GW2353", + .npes_used = 1, + .npeb_phy = 1, + }, { + .model = "GW2355", + .npes_used = 2, + .npeb_phy = -1, + .npec_phy = 1, + }, { + .model = "GW2357", + .npes_used = 1, + .npeb_phy = 1, + } +}; + +static struct avila_board_info *avila_find_board_info(char *model) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(avila_boards); i++) { + struct avila_board_info *info = &avila_boards[i]; + if (strncmp(info->model, model, strlen(info->model)) == 0) + return info; + } + + return NULL; +} + +struct avila_eeprom_header { + unsigned char mac0[ETH_ALEN]; + unsigned char mac1[ETH_ALEN]; + unsigned char res0[4]; + unsigned char magic[2]; + unsigned char config[14]; + unsigned char model[16]; +}; + +static int avila_eeprom_notify(struct notifier_block *self, + unsigned long event, void *t) +{ + struct eeprom_data *ee = t; + struct avila_board_info *info = NULL; + struct avila_eeprom_header hdr; + + /* The eeprom is at address 0x51 */ + if (event != EEPROM_REGISTER || ee->client.addr != 0x51) + return NOTIFY_DONE; + + ee->attr->read(&ee->client.dev.kobj, ee->attr, (char *)&hdr, + 0, sizeof(hdr)); + + if (hdr.magic[0] != 'G' || hdr.magic[1] != 'W') + return NOTIFY_DONE; + + memcpy(&avila_plat_eth[0].hwaddr, hdr.mac0, ETH_ALEN); + memcpy(&avila_plat_eth[1].hwaddr, hdr.mac1, ETH_ALEN); + + info = avila_find_board_info(hdr.model); + + if (info) { + printk(KERN_DEBUG "Running on Gateworks Avila %s\n", + info->model); + avila_plat_eth[0].phy = info->npeb_phy; + avila_plat_eth[1].phy = info->npec_phy; + platform_add_devices(avila_eth_devices, + info->npes_used); + } else { + printk(KERN_INFO "Unknown/missing Avila model number" + " -- defaults will be used\n"); + platform_add_devices(avila_eth_devices, + ARRAY_SIZE(avila_eth_devices)); + } + + unregister_eeprom_notifier(self); + + return NOTIFY_OK; +} + +static struct notifier_block avila_eeprom_notifier = { + .notifier_call = avila_eeprom_notify +}; +#endif + static void __init avila_init(void) { ixp4xx_sys_init(); @@ -201,7 +321,11 @@ static void __init avila_init(void) platform_device_register(&avila_pata); +#ifdef CONFIG_SENSORS_EEPROM + register_eeprom_notifier(&avila_eeprom_notifier); +#else platform_add_devices(avila_eth_devices, ARRAY_SIZE(avila_eth_devices)); +#endif } MACHINE_START(AVILA, "Gateworks Avila Network Platform")