1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
---
arch/arm/mach-ixp4xx/ixdp425-setup.c | 173 ++++++++++++++++++++++++++++++++---
1 file changed, 163 insertions(+), 10 deletions(-)
--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/ixdp425-setup.c 2006-03-27 03:08:59.000000000 +0200
+++ linux-ixp4xx/arch/arm/mach-ixp4xx/ixdp425-setup.c 2006-03-27 03:40:03.000000000 +0200
@@ -11,20 +11,26 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
#include <linux/serial_8250.h>
-#include <linux/slab.h>
-
-#include <asm/types.h>
+#include <linux/i2c.h>
+#include <linux/eeprom.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
-#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
+#ifdef CONFIG_LEDS_CLASS
+#include <linux/leds.h>
+#endif
+
+#ifdef CONFIG_MACLIST
+#include <net/maclist.h>
+#endif
+
static struct flash_platform_data ixdp425_flash_data = {
.map_name = "cfi_probe",
.width = 2,
@@ -176,22 +182,169 @@ MACHINE_START(AVILA, "Gateworks Avila Ne
MACHINE_END
#endif
+#ifdef CONFIG_MACH_LOFT
+#ifdef CONFIG_LEDS_CLASS
+static struct resource loft_led_resources[] = {
+ {
+ .name = "ready", /* green led, also J8 pin 7 */
+ .start = 3, /* FIXME use #define */
+ .end = 3,
+ .flags = IXP4XX_GPIO_LOW,
+ },
+};
+
+static struct platform_device loft_leds = {
+ .name = "IXP4XX-GPIO-LED",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(loft_led_resources),
+ .resource = loft_led_resources,
+};
+#endif
+
/*
* Loft is functionally equivalent to Avila except that it has a
* different number for the maximum PCI devices. The MACHINE
- * structure below is identical to Avila except for the comment.
+ * structure below is derived from the Avila one (and may, in
+ * fact, be useful on Avila in general).
+ *
+ * The loft init registers a notifier on the on-board EEPROM to
+ * detect the MAC addresses.
+ * NOTE: this probably works for all Gateworks Avila boards and
+ * maybe the ixdp425 too.
+ *
+ * When the EEPROM is added the MAC address are read from it.
*/
-#ifdef CONFIG_MACH_LOFT
+
+#if defined(CONFIG_SENSORS_EEPROM)
+static unsigned char loft_macs[12];
+
+static int loft_eeprom_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct eeprom_data *data = ptr;
+
+ /* The MACs are the first 12 bytes in the eeprom at address 0x51 */
+ if (event == EEPROM_REGISTER && data->client.addr == 0x51)
+ data->attr->read(&data->client.dev.kobj, loft_macs, 0, 12);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block loft_eeprom_notifier = {
+ .notifier_call = loft_eeprom_event,
+};
+
+static int loft_netdev_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = ptr;
+ unsigned char *hwaddr = NULL;
+
+ /* identify the ixp4xx eth */
+ if (dev->dev_addr[1] != 0x02 || dev->dev_addr[2] != 0xB3)
+ return NOTIFY_DONE;
+
+ if (event != NETDEV_REGISTER)
+ return NOTIFY_DONE;
+
+ /* identify the port */
+ if (dev->dev_addr[5] == 0x01)
+ hwaddr = &loft_macs[0];
+ else if (dev->dev_addr[5] == 0x02)
+ hwaddr = &loft_macs[6];
+
+ if (hwaddr && is_valid_ether_addr(hwaddr)) {
+ struct sockaddr addr;
+ addr.sa_family = dev->type;
+ memcpy(addr.sa_data, hwaddr, ETH_ALEN);
+ dev_set_mac_address(dev, &addr);
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block loft_netdev_notifier = {
+ .notifier_call = loft_netdev_event,
+};
+#endif
+
+static void __init loft_init(void)
+{
+ ixdp425_init();
+
+#ifdef CONFIG_LEDS_CLASS
+ /* We don't care if this fails. */
+ (void)platform_device_register(&loft_leds);
+#endif
+ /* The EEPROM has two ethernet MACs embedded in it which we need,
+ * that is all this notifier does.
+ */
+#ifdef CONFIG_SENSORS_EEPROM
+ register_eeprom_notifier(&loft_eeprom_notifier);
+ register_netdevice_notifier(&loft_netdev_notifier);
+#endif
+}
+
+/*
+ * Loft bootstrap may pass in parameters, if these contain an
+ * ATAG_MEM and it appears valid (not the 16MByte one in the
+ * setup/kernel.c default) we use it, otherwise a 64MByte
+ * setting is forced here, this may be overridden on the
+ * command line.
+ */
+static void __init loft_fixup(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ /* Put Loft specific known-required-for-certain stuff here, leave
+ * a trailing space!
+ */
+ static char loft_command_line[] =
+ "root=/dev/mtdblock2 rw rootfstype=jffs2 init=/linuxrc "
+ "rtc-ds1672.probe=0,0x68 "
+ CONFIG_CMDLINE;
+
+ int memtag = 0;
+
+ /* The Loft typically has one bank of 64MByte memory.
+ * NOTE: setting nr_banks != 0 causes kernel/setup.c to remove
+ * the mem tags from the tag list, so if there is an entry
+ * there don't remove it!
+ */
+ if (tags->hdr.tag == ATAG_CORE) do {
+ tags = tag_next(tags);
+ printk(KERN_NOTICE "ATAG[0x%x] size %d\n", tags->hdr.tag, tags->hdr.size);
+ if (tags->hdr.tag == ATAG_MEM && tags->hdr.size == tag_size(tag_mem32) &&
+ (tags->u.mem.start != 0 || tags->u.mem.size != (16*1024*1024))) {
+ memtag = 1;
+ printk(KERN_NOTICE " ATAG_MEM base %x, size %dMB\n",
+ tags->u.mem.start,
+ tags->u.mem.size / (1024*1024));
+ }
+ } while (tags->hdr.size);
+
+ if (!memtag) {
+ mi->nr_banks = 1;
+ mi->bank[0].start = 0;
+ mi->bank[0].size = (64*1024*1024);
+ mi->bank[0].node = PHYS_TO_NID(0);
+ }
+
+ /* A command line in the ATAG list will override this one,
+ * as is intended.
+ */
+ strlcpy(*cmdline, loft_command_line, COMMAND_LINE_SIZE);
+}
+
MACHINE_START(LOFT, "Giant Shoulder Inc Loft board")
/* Maintainer: Tom Billman <kernel@giantshoulderinc.com> */
.phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+ .fixup = loft_fixup,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
.boot_params = 0x0100,
- .init_machine = ixdp425_init,
+ .init_machine = loft_init,
MACHINE_END
#endif
-
|