[ixp4xx] avila: add model detection, refresh patches. Kaloz: thank you for the review...
[openwrt.git] / target / linux / ixp4xx / patches-2.6.24 / 300-avila_fetch_mac.patch
1 Index: linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c
2 ===================================================================
3 --- linux-2.6.24.2.orig/arch/arm/mach-ixp4xx/avila-setup.c
4 +++ linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c
5 @@ -14,10 +14,18 @@
6  #include <linux/kernel.h>
7  #include <linux/init.h>
8  #include <linux/device.h>
9 +#include <linux/if_ether.h>
10 +#include <linux/socket.h>
11 +#include <linux/netdevice.h>
12  #include <linux/serial.h>
13  #include <linux/tty.h>
14  #include <linux/serial_8250.h>
15  #include <linux/slab.h>
16 +#ifdef CONFIG_SENSORS_EEPROM
17 +# include <linux/i2c.h>
18 +# include <linux/eeprom.h>
19 +#endif
20 +
21  #include <linux/i2c-gpio.h>
22  
23  #include <asm/types.h>
24 @@ -177,6 +185,118 @@ static struct platform_device *avila_eth
25         &avila_eth[1]
26  };
27  
28 +#ifdef CONFIG_SENSORS_EEPROM
29 +struct avila_board_info {
30 +       unsigned char *model;
31 +       int     npes_used;
32 +       int     npeb_phy;
33 +       int     npec_phy;
34 +};
35 +
36 +static struct avila_board_info avila_boards[] = {
37 +       {
38 +               .model          = "GW2342",
39 +               .npes_used      = 2,
40 +               .npeb_phy       = 0,
41 +               .npec_phy       = 1,
42 +       }, {
43 +               .model          = "GW2345",
44 +               .npes_used      = 2,
45 +               .npeb_phy       = 0,
46 +               .npec_phy       = 1,
47 +       }, {
48 +               .model          = "GW2347",
49 +               .npes_used      = 1,
50 +               .npeb_phy       = 1,
51 +       }, {
52 +               .model          = "GW2348-2",
53 +               .npes_used      = 2,
54 +               .npeb_phy       = 0,
55 +               .npec_phy       = 1,
56 +       }, {
57 +               .model          = "GW2348-4",
58 +               .npes_used      = 2,
59 +               .npeb_phy       = 0,
60 +               .npec_phy       = 1,
61 +       }, {
62 +               .model          = "GW2353",
63 +               .npes_used      = 1,
64 +               .npeb_phy       = 1,
65 +       }, {
66 +               .model          = "GW2357",
67 +               .npes_used      = 1,
68 +               .npeb_phy       = 1,
69 +       }
70 +};
71 +
72 +static struct avila_board_info *avila_find_board_info(char *model)
73 +{
74 +       int i;
75 +
76 +       for (i = 0; i < ARRAY_SIZE(avila_boards); i++) {
77 +               struct avila_board_info *info = &avila_boards[i];
78 +               if (strncmp(info->model, model, strlen(info->model)) == 0)
79 +                       return info;
80 +       }
81 +
82 +       return NULL;
83 +}
84 +
85 +struct avila_eeprom_header {
86 +       unsigned char mac0[ETH_ALEN];
87 +       unsigned char mac1[ETH_ALEN];
88 +       unsigned char res0[4];
89 +       unsigned char magic[2];
90 +       unsigned char config[14];
91 +       unsigned char model[16];
92 +};
93 +
94 +static int avila_eeprom_notify(struct notifier_block *self,
95 +                       unsigned long event, void *t)
96 +{
97 +       struct eeprom_data *ee = t;
98 +       struct avila_board_info *info = NULL;
99 +       struct avila_eeprom_header hdr;
100 +
101 +       /* The eeprom is at address 0x51 */
102 +       if (event != EEPROM_REGISTER || ee->client.addr != 0x51)
103 +               return NOTIFY_DONE;
104 +
105 +       ee->attr->read(&ee->client.dev.kobj, ee->attr, (char *)&hdr,
106 +               0, sizeof(hdr));
107 +
108 +       if (hdr.magic[0] != 'G' || hdr.magic[1] != 'W')
109 +               return NOTIFY_DONE;
110 +
111 +       memcpy(&avila_plat_eth[0].hwaddr, hdr.mac0, ETH_ALEN);
112 +       memcpy(&avila_plat_eth[1].hwaddr, hdr.mac1, ETH_ALEN);
113 +
114 +       info = avila_find_board_info(hdr.model);
115 +
116 +       if (info) {
117 +               printk(KERN_DEBUG "Running on Gateworks Avila %s\n",
118 +                                                       info->model);
119 +               avila_plat_eth[0].phy = info->npeb_phy;
120 +               avila_plat_eth[1].phy = info->npec_phy;
121 +               platform_add_devices(avila_eth_devices,
122 +                       info->npes_used);
123 +       } else {
124 +               printk(KERN_INFO "Unknown/missing Avila model number"
125 +                                       " -- defaults will be used\n");
126 +               platform_add_devices(avila_eth_devices,
127 +                       ARRAY_SIZE(avila_eth_devices));
128 +       }
129 +
130 +       unregister_eeprom_notifier(self);
131 +
132 +       return NOTIFY_OK;
133 +}
134 +
135 +static struct notifier_block avila_eeprom_notifier = {
136 +       .notifier_call = avila_eeprom_notify
137 +};
138 +#endif
139 +
140  static void __init avila_init(void)
141  {
142         ixp4xx_sys_init();
143 @@ -201,7 +321,11 @@ static void __init avila_init(void)
144  
145         platform_device_register(&avila_pata);
146  
147 +#ifdef CONFIG_SENSORS_EEPROM
148 +       register_eeprom_notifier(&avila_eeprom_notifier);
149 +#else
150         platform_add_devices(avila_eth_devices, ARRAY_SIZE(avila_eth_devices));
151 +#endif
152  }
153  
154  MACHINE_START(AVILA, "Gateworks Avila Network Platform")