aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-orion5x
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-03-19 19:10:40 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-03-19 19:10:40 -0400
commit7d83f8fca517b123cf0136503a9e50974f65ec49 (patch)
tree92ed1faaf112e98e29a00efc99e1a4e6c79e6a8e /arch/arm/mach-orion5x
parentbe093beb608edf821b45fe00a8a080fb5c6ed4af (diff)
parent569106c70e49ad67c69fa7d43a2a5218e63a4619 (diff)
Merge branch 'master' of git://git.marvell.com/orion into devel
Conflicts: arch/arm/mach-mx1/devices.c
Diffstat (limited to 'arch/arm/mach-orion5x')
-rw-r--r--arch/arm/mach-orion5x/Kconfig1
-rw-r--r--arch/arm/mach-orion5x/common.c7
-rw-r--r--arch/arm/mach-orion5x/dns323-setup.c4
-rw-r--r--arch/arm/mach-orion5x/ts78xx-fpga.h29
-rw-r--r--arch/arm/mach-orion5x/ts78xx-setup.c441
5 files changed, 370 insertions, 112 deletions
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index f59a8d0e0824..2c7035d8dcbf 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -71,6 +71,7 @@ config MACH_WRT350N_V2
71 71
72config MACH_TS78XX 72config MACH_TS78XX
73 bool "Technologic Systems TS-78xx" 73 bool "Technologic Systems TS-78xx"
74 select PM
74 help 75 help
75 Say 'Y' here if you want your kernel to support the 76 Say 'Y' here if you want your kernel to support the
76 Technologic Systems TS-78xx platform. 77 Technologic Systems TS-78xx platform.
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 0a623379789f..8a0e49d84256 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -431,6 +431,10 @@ void __init orion5x_uart1_init(void)
431/***************************************************************************** 431/*****************************************************************************
432 * XOR engine 432 * XOR engine
433 ****************************************************************************/ 433 ****************************************************************************/
434struct mv_xor_platform_shared_data orion5x_xor_shared_data = {
435 .dram = &orion5x_mbus_dram_info,
436};
437
434static struct resource orion5x_xor_shared_resources[] = { 438static struct resource orion5x_xor_shared_resources[] = {
435 { 439 {
436 .name = "xor low", 440 .name = "xor low",
@@ -448,6 +452,9 @@ static struct resource orion5x_xor_shared_resources[] = {
448static struct platform_device orion5x_xor_shared = { 452static struct platform_device orion5x_xor_shared = {
449 .name = MV_XOR_SHARED_NAME, 453 .name = MV_XOR_SHARED_NAME,
450 .id = 0, 454 .id = 0,
455 .dev = {
456 .platform_data = &orion5x_xor_shared_data,
457 },
451 .num_resources = ARRAY_SIZE(orion5x_xor_shared_resources), 458 .num_resources = ARRAY_SIZE(orion5x_xor_shared_resources),
452 .resource = orion5x_xor_shared_resources, 459 .resource = orion5x_xor_shared_resources,
453}; 460};
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
index 0722d6510df1..b31ca4cef365 100644
--- a/arch/arm/mach-orion5x/dns323-setup.c
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -76,7 +76,7 @@ static int __init dns323_dev_id(void)
76 76
77static int __init dns323_pci_init(void) 77static int __init dns323_pci_init(void)
78{ 78{
79 /* The 5182 doesn't really use it's PCI bus, and initialising PCI 79 /* The 5182 doesn't really use its PCI bus, and initialising PCI
80 * gets in the way of initialising the SATA controller. 80 * gets in the way of initialising the SATA controller.
81 */ 81 */
82 if (machine_is_dns323() && dns323_dev_id() != MV88F5182_DEV_ID) 82 if (machine_is_dns323() && dns323_dev_id() != MV88F5182_DEV_ID)
@@ -418,7 +418,7 @@ static void __init dns323_init(void)
418 orion5x_i2c_init(); 418 orion5x_i2c_init();
419 orion5x_uart0_init(); 419 orion5x_uart0_init();
420 420
421 /* The 5182 has it's SATA controller on-chip, and needs it's own little 421 /* The 5182 has its SATA controller on-chip, and needs its own little
422 * init routine. 422 * init routine.
423 */ 423 */
424 if (dns323_dev_id() == MV88F5182_DEV_ID) 424 if (dns323_dev_id() == MV88F5182_DEV_ID)
diff --git a/arch/arm/mach-orion5x/ts78xx-fpga.h b/arch/arm/mach-orion5x/ts78xx-fpga.h
new file mode 100644
index 000000000000..0a314ddef658
--- /dev/null
+++ b/arch/arm/mach-orion5x/ts78xx-fpga.h
@@ -0,0 +1,29 @@
1#define FPGAID(_magic, _rev) ((_magic << 8) + _rev)
2
3/*
4 * get yer id's from http://ts78xx.digriz.org.uk/
5 * do *not* make up your own or 'borrow' any!
6 */
7enum fpga_ids {
8 /* Technologic Systems */
9 TS7800_REV_B2 = FPGAID(0x00b480, 0x02),
10 TS7800_REV_B3 = FPGAID(0x00b480, 0x03),
11};
12
13struct fpga_device {
14 unsigned present:1;
15 unsigned init:1;
16};
17
18struct fpga_devices {
19 /* Technologic Systems */
20 struct fpga_device ts_rtc;
21 struct fpga_device ts_nand;
22};
23
24struct ts78xx_fpga_data {
25 unsigned int id;
26 int state;
27
28 struct fpga_devices supports;
29};
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c
index 1368e9fd1a06..f5191ddea085 100644
--- a/arch/arm/mach-orion5x/ts78xx-setup.c
+++ b/arch/arm/mach-orion5x/ts78xx-setup.c
@@ -10,17 +10,20 @@
10 10
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/sysfs.h>
13#include <linux/platform_device.h> 14#include <linux/platform_device.h>
14#include <linux/mtd/physmap.h>
15#include <linux/mv643xx_eth.h> 15#include <linux/mv643xx_eth.h>
16#include <linux/ata_platform.h> 16#include <linux/ata_platform.h>
17#include <linux/m48t86.h> 17#include <linux/m48t86.h>
18#include <linux/mtd/nand.h>
19#include <linux/mtd/partitions.h>
18#include <asm/mach-types.h> 20#include <asm/mach-types.h>
19#include <asm/mach/arch.h> 21#include <asm/mach/arch.h>
20#include <asm/mach/map.h> 22#include <asm/mach/map.h>
21#include <mach/orion5x.h> 23#include <mach/orion5x.h>
22#include "common.h" 24#include "common.h"
23#include "mpp.h" 25#include "mpp.h"
26#include "ts78xx-fpga.h"
24 27
25/***************************************************************************** 28/*****************************************************************************
26 * TS-78xx Info 29 * TS-78xx Info
@@ -33,18 +36,11 @@
33#define TS78XX_FPGA_REGS_VIRT_BASE 0xff900000 36#define TS78XX_FPGA_REGS_VIRT_BASE 0xff900000
34#define TS78XX_FPGA_REGS_SIZE SZ_1M 37#define TS78XX_FPGA_REGS_SIZE SZ_1M
35 38
36#define TS78XX_FPGA_REGS_SYSCON_ID (TS78XX_FPGA_REGS_VIRT_BASE | 0x000) 39static struct ts78xx_fpga_data ts78xx_fpga = {
37#define TS78XX_FPGA_REGS_SYSCON_LCDI (TS78XX_FPGA_REGS_VIRT_BASE | 0x004) 40 .id = 0,
38#define TS78XX_FPGA_REGS_SYSCON_LCDO (TS78XX_FPGA_REGS_VIRT_BASE | 0x008) 41 .state = 1,
39 42/* .supports = ... - populated by ts78xx_fpga_supports() */
40#define TS78XX_FPGA_REGS_RTC_CTRL (TS78XX_FPGA_REGS_VIRT_BASE | 0x808) 43};
41#define TS78XX_FPGA_REGS_RTC_DATA (TS78XX_FPGA_REGS_VIRT_BASE | 0x80c)
42
43/*
44 * 512kB NOR flash Device
45 */
46#define TS78XX_NOR_BOOT_BASE 0xff800000
47#define TS78XX_NOR_BOOT_SIZE SZ_512K
48 44
49/***************************************************************************** 45/*****************************************************************************
50 * I/O Address Mapping 46 * I/O Address Mapping
@@ -65,73 +61,47 @@ void __init ts78xx_map_io(void)
65} 61}
66 62
67/***************************************************************************** 63/*****************************************************************************
68 * 512kB NOR Boot Flash - the chip is a M25P40 64 * Ethernet
69 ****************************************************************************/ 65 ****************************************************************************/
70static struct mtd_partition ts78xx_nor_boot_flash_resources[] = { 66static struct mv643xx_eth_platform_data ts78xx_eth_data = {
71 { 67 .phy_addr = MV643XX_ETH_PHY_ADDR(0),
72 .name = "ts-bootrom",
73 .offset = 0,
74 /* only the first 256kB is used */
75 .size = SZ_256K,
76 .mask_flags = MTD_WRITEABLE,
77 },
78};
79
80static struct physmap_flash_data ts78xx_nor_boot_flash_data = {
81 .width = 1,
82 .parts = ts78xx_nor_boot_flash_resources,
83 .nr_parts = ARRAY_SIZE(ts78xx_nor_boot_flash_resources),
84};
85
86static struct resource ts78xx_nor_boot_flash_resource = {
87 .flags = IORESOURCE_MEM,
88 .start = TS78XX_NOR_BOOT_BASE,
89 .end = TS78XX_NOR_BOOT_BASE + TS78XX_NOR_BOOT_SIZE - 1,
90};
91
92static struct platform_device ts78xx_nor_boot_flash = {
93 .name = "physmap-flash",
94 .id = -1,
95 .dev = {
96 .platform_data = &ts78xx_nor_boot_flash_data,
97 },
98 .num_resources = 1,
99 .resource = &ts78xx_nor_boot_flash_resource,
100}; 68};
101 69
102/***************************************************************************** 70/*****************************************************************************
103 * Ethernet 71 * SATA
104 ****************************************************************************/ 72 ****************************************************************************/
105static struct mv643xx_eth_platform_data ts78xx_eth_data = { 73static struct mv_sata_platform_data ts78xx_sata_data = {
106 .phy_addr = MV643XX_ETH_PHY_ADDR(0), 74 .n_ports = 2,
107}; 75};
108 76
109/***************************************************************************** 77/*****************************************************************************
110 * RTC M48T86 - nicked^Wborrowed from arch/arm/mach-ep93xx/ts72xx.c 78 * RTC M48T86 - nicked^Wborrowed from arch/arm/mach-ep93xx/ts72xx.c
111 ****************************************************************************/ 79 ****************************************************************************/
112#ifdef CONFIG_RTC_DRV_M48T86 80#define TS_RTC_CTRL (TS78XX_FPGA_REGS_VIRT_BASE | 0x808)
113static unsigned char ts78xx_rtc_readbyte(unsigned long addr) 81#define TS_RTC_DATA (TS78XX_FPGA_REGS_VIRT_BASE | 0x80c)
82
83static unsigned char ts78xx_ts_rtc_readbyte(unsigned long addr)
114{ 84{
115 writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL); 85 writeb(addr, TS_RTC_CTRL);
116 return readb(TS78XX_FPGA_REGS_RTC_DATA); 86 return readb(TS_RTC_DATA);
117} 87}
118 88
119static void ts78xx_rtc_writebyte(unsigned char value, unsigned long addr) 89static void ts78xx_ts_rtc_writebyte(unsigned char value, unsigned long addr)
120{ 90{
121 writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL); 91 writeb(addr, TS_RTC_CTRL);
122 writeb(value, TS78XX_FPGA_REGS_RTC_DATA); 92 writeb(value, TS_RTC_DATA);
123} 93}
124 94
125static struct m48t86_ops ts78xx_rtc_ops = { 95static struct m48t86_ops ts78xx_ts_rtc_ops = {
126 .readbyte = ts78xx_rtc_readbyte, 96 .readbyte = ts78xx_ts_rtc_readbyte,
127 .writebyte = ts78xx_rtc_writebyte, 97 .writebyte = ts78xx_ts_rtc_writebyte,
128}; 98};
129 99
130static struct platform_device ts78xx_rtc_device = { 100static struct platform_device ts78xx_ts_rtc_device = {
131 .name = "rtc-m48t86", 101 .name = "rtc-m48t86",
132 .id = -1, 102 .id = -1,
133 .dev = { 103 .dev = {
134 .platform_data = &ts78xx_rtc_ops, 104 .platform_data = &ts78xx_ts_rtc_ops,
135 }, 105 },
136 .num_resources = 0, 106 .num_resources = 0,
137}; 107};
@@ -146,59 +116,311 @@ static struct platform_device ts78xx_rtc_device = {
146 * TODO: track down a guinea pig without an RTC to see if we can work out a 116 * TODO: track down a guinea pig without an RTC to see if we can work out a
147 * better RTC detection routine 117 * better RTC detection routine
148 */ 118 */
149static int __init ts78xx_rtc_init(void) 119static int ts78xx_ts_rtc_load(void)
150{ 120{
121 int rc;
151 unsigned char tmp_rtc0, tmp_rtc1; 122 unsigned char tmp_rtc0, tmp_rtc1;
152 123
153 tmp_rtc0 = ts78xx_rtc_readbyte(126); 124 tmp_rtc0 = ts78xx_ts_rtc_readbyte(126);
154 tmp_rtc1 = ts78xx_rtc_readbyte(127); 125 tmp_rtc1 = ts78xx_ts_rtc_readbyte(127);
155 126
156 ts78xx_rtc_writebyte(0x00, 126); 127 ts78xx_ts_rtc_writebyte(0x00, 126);
157 ts78xx_rtc_writebyte(0x55, 127); 128 ts78xx_ts_rtc_writebyte(0x55, 127);
158 if (ts78xx_rtc_readbyte(127) == 0x55) { 129 if (ts78xx_ts_rtc_readbyte(127) == 0x55) {
159 ts78xx_rtc_writebyte(0xaa, 127); 130 ts78xx_ts_rtc_writebyte(0xaa, 127);
160 if (ts78xx_rtc_readbyte(127) == 0xaa 131 if (ts78xx_ts_rtc_readbyte(127) == 0xaa
161 && ts78xx_rtc_readbyte(126) == 0x00) { 132 && ts78xx_ts_rtc_readbyte(126) == 0x00) {
162 ts78xx_rtc_writebyte(tmp_rtc0, 126); 133 ts78xx_ts_rtc_writebyte(tmp_rtc0, 126);
163 ts78xx_rtc_writebyte(tmp_rtc1, 127); 134 ts78xx_ts_rtc_writebyte(tmp_rtc1, 127);
164 platform_device_register(&ts78xx_rtc_device); 135
165 return 1; 136 if (ts78xx_fpga.supports.ts_rtc.init == 0) {
137 rc = platform_device_register(&ts78xx_ts_rtc_device);
138 if (!rc)
139 ts78xx_fpga.supports.ts_rtc.init = 1;
140 } else
141 rc = platform_device_add(&ts78xx_ts_rtc_device);
142
143 return rc;
166 } 144 }
167 } 145 }
168 146
169 return 0; 147 return -ENODEV;
170}; 148};
171#else 149
172static int __init ts78xx_rtc_init(void) 150static void ts78xx_ts_rtc_unload(void)
173{ 151{
174 return 0; 152 platform_device_del(&ts78xx_ts_rtc_device);
175} 153}
176#endif
177 154
178/***************************************************************************** 155/*****************************************************************************
179 * SATA 156 * NAND Flash
180 ****************************************************************************/ 157 ****************************************************************************/
181static struct mv_sata_platform_data ts78xx_sata_data = { 158#define TS_NAND_CTRL (TS78XX_FPGA_REGS_VIRT_BASE | 0x800) /* VIRT */
182 .n_ports = 2, 159#define TS_NAND_DATA (TS78XX_FPGA_REGS_PHYS_BASE | 0x804) /* PHYS */
160
161/*
162 * hardware specific access to control-lines
163 *
164 * ctrl:
165 * NAND_NCE: bit 0 -> bit 2
166 * NAND_CLE: bit 1 -> bit 1
167 * NAND_ALE: bit 2 -> bit 0
168 */
169static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
170 unsigned int ctrl)
171{
172 struct nand_chip *this = mtd->priv;
173
174 if (ctrl & NAND_CTRL_CHANGE) {
175 unsigned char bits;
176
177 bits = (ctrl & NAND_NCE) << 2;
178 bits |= ctrl & NAND_CLE;
179 bits |= (ctrl & NAND_ALE) >> 2;
180
181 writeb((readb(TS_NAND_CTRL) & ~0x7) | bits, TS_NAND_CTRL);
182 }
183
184 if (cmd != NAND_CMD_NONE)
185 writeb(cmd, this->IO_ADDR_W);
186}
187
188static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd)
189{
190 return readb(TS_NAND_CTRL) & 0x20;
191}
192
193const char *ts_nand_part_probes[] = { "cmdlinepart", NULL };
194
195static struct mtd_partition ts78xx_ts_nand_parts[] = {
196 {
197 .name = "mbr",
198 .offset = 0,
199 .size = SZ_128K,
200 .mask_flags = MTD_WRITEABLE,
201 }, {
202 .name = "kernel",
203 .offset = MTDPART_OFS_APPEND,
204 .size = SZ_4M,
205 }, {
206 .name = "initrd",
207 .offset = MTDPART_OFS_APPEND,
208 .size = SZ_4M,
209 }, {
210 .name = "rootfs",
211 .offset = MTDPART_OFS_APPEND,
212 .size = MTDPART_SIZ_FULL,
213 }
183}; 214};
184 215
216static struct platform_nand_data ts78xx_ts_nand_data = {
217 .chip = {
218 .part_probe_types = ts_nand_part_probes,
219 .partitions = ts78xx_ts_nand_parts,
220 .nr_partitions = ARRAY_SIZE(ts78xx_ts_nand_parts),
221 .chip_delay = 15,
222 .options = NAND_USE_FLASH_BBT,
223 },
224 .ctrl = {
225 /*
226 * The HW ECC offloading functions, used to give about a 9%
227 * performance increase for 'dd if=/dev/mtdblockX' and 5% for
228 * nanddump. This all however was changed by git commit
229 * e6cf5df1838c28bb060ac45b5585e48e71bbc740 so now there is
230 * no performance advantage to be had so we no longer bother
231 */
232 .cmd_ctrl = ts78xx_ts_nand_cmd_ctrl,
233 .dev_ready = ts78xx_ts_nand_dev_ready,
234 },
235};
236
237static struct resource ts78xx_ts_nand_resources = {
238 .start = TS_NAND_DATA,
239 .end = TS_NAND_DATA + 4,
240 .flags = IORESOURCE_IO,
241};
242
243static struct platform_device ts78xx_ts_nand_device = {
244 .name = "gen_nand",
245 .id = -1,
246 .dev = {
247 .platform_data = &ts78xx_ts_nand_data,
248 },
249 .resource = &ts78xx_ts_nand_resources,
250 .num_resources = 1,
251};
252
253static int ts78xx_ts_nand_load(void)
254{
255 int rc;
256
257 if (ts78xx_fpga.supports.ts_nand.init == 0) {
258 rc = platform_device_register(&ts78xx_ts_nand_device);
259 if (!rc)
260 ts78xx_fpga.supports.ts_nand.init = 1;
261 } else
262 rc = platform_device_add(&ts78xx_ts_nand_device);
263
264 return rc;
265};
266
267static void ts78xx_ts_nand_unload(void)
268{
269 platform_device_del(&ts78xx_ts_nand_device);
270}
271
185/***************************************************************************** 272/*****************************************************************************
186 * print some information regarding the board 273 * FPGA 'hotplug' support code
187 ****************************************************************************/ 274 ****************************************************************************/
188static void __init ts78xx_print_board_id(void) 275static void ts78xx_fpga_devices_zero_init(void)
189{ 276{
190 unsigned int board_info; 277 ts78xx_fpga.supports.ts_rtc.init = 0;
191 278 ts78xx_fpga.supports.ts_nand.init = 0;
192 board_info = readl(TS78XX_FPGA_REGS_SYSCON_ID); 279}
193 printk(KERN_INFO "TS-78xx Info: FPGA rev=%.2x, Board Magic=%.6x, ", 280
194 board_info & 0xff, 281static void ts78xx_fpga_supports(void)
195 (board_info >> 8) & 0xffffff); 282{
196 board_info = readl(TS78XX_FPGA_REGS_SYSCON_LCDI); 283 /* TODO: put this 'table' into ts78xx-fpga.h */
197 printk("JP1=%d, JP2=%d\n", 284 switch (ts78xx_fpga.id) {
198 (board_info >> 30) & 0x1, 285 case TS7800_REV_B2:
199 (board_info >> 31) & 0x1); 286 case TS7800_REV_B3:
287 ts78xx_fpga.supports.ts_rtc.present = 1;
288 ts78xx_fpga.supports.ts_nand.present = 1;
289 break;
290 default:
291 ts78xx_fpga.supports.ts_rtc.present = 0;
292 ts78xx_fpga.supports.ts_nand.present = 0;
293 }
294}
295
296static int ts78xx_fpga_load_devices(void)
297{
298 int tmp, ret = 0;
299
300 if (ts78xx_fpga.supports.ts_rtc.present == 1) {
301 tmp = ts78xx_ts_rtc_load();
302 if (tmp) {
303 printk(KERN_INFO "TS-78xx: RTC not registered\n");
304 ts78xx_fpga.supports.ts_rtc.present = 0;
305 }
306 ret |= tmp;
307 }
308 if (ts78xx_fpga.supports.ts_nand.present == 1) {
309 tmp = ts78xx_ts_nand_load();
310 if (tmp) {
311 printk(KERN_INFO "TS-78xx: NAND not registered\n");
312 ts78xx_fpga.supports.ts_nand.present = 0;
313 }
314 ret |= tmp;
315 }
316
317 return ret;
318}
319
320static int ts78xx_fpga_unload_devices(void)
321{
322 int ret = 0;
323
324 if (ts78xx_fpga.supports.ts_rtc.present == 1)
325 ts78xx_ts_rtc_unload();
326 if (ts78xx_fpga.supports.ts_nand.present == 1)
327 ts78xx_ts_nand_unload();
328
329 return ret;
330}
331
332static int ts78xx_fpga_load(void)
333{
334 ts78xx_fpga.id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
335
336 printk(KERN_INFO "TS-78xx FPGA: magic=0x%.6x, rev=0x%.2x\n",
337 (ts78xx_fpga.id >> 8) & 0xffffff,
338 ts78xx_fpga.id & 0xff);
339
340 ts78xx_fpga_supports();
341
342 if (ts78xx_fpga_load_devices()) {
343 ts78xx_fpga.state = -1;
344 return -EBUSY;
345 }
346
347 return 0;
200}; 348};
201 349
350static int ts78xx_fpga_unload(void)
351{
352 unsigned int fpga_id;
353
354 fpga_id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
355
356 /*
357 * There does not seem to be a feasible way to block access to the GPIO
358 * pins from userspace (/dev/mem). This if clause should hopefully warn
359 * those foolish enough not to follow 'policy' :)
360 *
361 * UrJTAG SVN since r1381 can be used to reprogram the FPGA
362 */
363 if (ts78xx_fpga.id != fpga_id) {
364 printk(KERN_ERR "TS-78xx FPGA: magic/rev mismatch\n"
365 "TS-78xx FPGA: was 0x%.6x/%.2x but now 0x%.6x/%.2x\n",
366 (ts78xx_fpga.id >> 8) & 0xffffff, ts78xx_fpga.id & 0xff,
367 (fpga_id >> 8) & 0xffffff, fpga_id & 0xff);
368 ts78xx_fpga.state = -1;
369 return -EBUSY;
370 }
371
372 if (ts78xx_fpga_unload_devices()) {
373 ts78xx_fpga.state = -1;
374 return -EBUSY;
375 }
376
377 return 0;
378};
379
380static ssize_t ts78xx_fpga_show(struct kobject *kobj,
381 struct kobj_attribute *attr, char *buf)
382{
383 if (ts78xx_fpga.state < 0)
384 return sprintf(buf, "borked\n");
385
386 return sprintf(buf, "%s\n", (ts78xx_fpga.state) ? "online" : "offline");
387}
388
389static ssize_t ts78xx_fpga_store(struct kobject *kobj,
390 struct kobj_attribute *attr, const char *buf, size_t n)
391{
392 int value, ret;
393
394 if (ts78xx_fpga.state < 0) {
395 printk(KERN_ERR "TS-78xx FPGA: borked, you must powercycle asap\n");
396 return -EBUSY;
397 }
398
399 if (strncmp(buf, "online", sizeof("online") - 1) == 0)
400 value = 1;
401 else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
402 value = 0;
403 else {
404 printk(KERN_ERR "ts78xx_fpga_store: Invalid value\n");
405 return -EINVAL;
406 }
407
408 if (ts78xx_fpga.state == value)
409 return n;
410
411 ret = (ts78xx_fpga.state == 0)
412 ? ts78xx_fpga_load()
413 : ts78xx_fpga_unload();
414
415 if (!(ret < 0))
416 ts78xx_fpga.state = value;
417
418 return n;
419}
420
421static struct kobj_attribute ts78xx_fpga_attr =
422 __ATTR(ts78xx_fpga, 0644, ts78xx_fpga_show, ts78xx_fpga_store);
423
202/***************************************************************************** 424/*****************************************************************************
203 * General Setup 425 * General Setup
204 ****************************************************************************/ 426 ****************************************************************************/
@@ -223,30 +445,29 @@ static struct orion5x_mpp_mode ts78xx_mpp_modes[] __initdata = {
223 { 17, MPP_UART }, 445 { 17, MPP_UART },
224 { 18, MPP_UART }, 446 { 18, MPP_UART },
225 { 19, MPP_UART }, 447 { 19, MPP_UART },
448 /*
449 * MPP[20] PCI Clock Out 1
450 * MPP[21] PCI Clock Out 0
451 * MPP[22] Unused
452 * MPP[23] Unused
453 * MPP[24] Unused
454 * MPP[25] Unused
455 */
226 { -1 }, 456 { -1 },
227}; 457};
228 458
229static void __init ts78xx_init(void) 459static void __init ts78xx_init(void)
230{ 460{
461 int ret;
462
231 /* 463 /*
232 * Setup basic Orion functions. Need to be called early. 464 * Setup basic Orion functions. Need to be called early.
233 */ 465 */
234 orion5x_init(); 466 orion5x_init();
235 467
236 ts78xx_print_board_id();
237
238 orion5x_mpp_conf(ts78xx_mpp_modes); 468 orion5x_mpp_conf(ts78xx_mpp_modes);
239 469
240 /* 470 /*
241 * MPP[20] PCI Clock Out 1
242 * MPP[21] PCI Clock Out 0
243 * MPP[22] Unused
244 * MPP[23] Unused
245 * MPP[24] Unused
246 * MPP[25] Unused
247 */
248
249 /*
250 * Configure peripherals. 471 * Configure peripherals.
251 */ 472 */
252 orion5x_ehci0_init(); 473 orion5x_ehci0_init();
@@ -257,12 +478,12 @@ static void __init ts78xx_init(void)
257 orion5x_uart1_init(); 478 orion5x_uart1_init();
258 orion5x_xor_init(); 479 orion5x_xor_init();
259 480
260 orion5x_setup_dev_boot_win(TS78XX_NOR_BOOT_BASE, 481 /* FPGA init */
261 TS78XX_NOR_BOOT_SIZE); 482 ts78xx_fpga_devices_zero_init();
262 platform_device_register(&ts78xx_nor_boot_flash); 483 ret = ts78xx_fpga_load();
263 484 ret = sysfs_create_file(power_kobj, &ts78xx_fpga_attr.attr);
264 if (!ts78xx_rtc_init()) 485 if (ret)
265 printk(KERN_INFO "TS-78xx RTC not detected or enabled\n"); 486 printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
266} 487}
267 488
268MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC") 489MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")