2 * Generic setup routines for Broadcom MIPS boards
4 * Copyright 2004, Broadcom Corporation
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
15 #include <linux/config.h>
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <linux/serialP.h>
19 #include <linux/ide.h>
20 #include <asm/bootinfo.h>
22 #include <asm/reboot.h>
24 #ifdef CONFIG_MTD_PARTITIONS
25 #include <linux/mtd/mtd.h>
26 #include <linux/mtd/partitions.h>
36 extern void bcm947xx_time_init(void);
37 extern void bcm947xx_timer_setup(struct irqaction
*irq
);
39 #ifdef CONFIG_REMOTE_DEBUG
40 extern void set_debug_traps(void);
41 extern void rs_kgdb_hook(struct serial_state
*);
42 extern void breakpoint(void);
45 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
46 extern struct ide_ops std_ide_ops
;
49 /* Global SB handle */
50 void *bcm947xx_sbh
= NULL
;
51 spinlock_t bcm947xx_sbh_lock
= SPIN_LOCK_UNLOCKED
;
52 EXPORT_SYMBOL(bcm947xx_sbh
);
53 EXPORT_SYMBOL(bcm947xx_sbh_lock
);
56 #define sbh bcm947xx_sbh
57 #define sbh_lock bcm947xx_sbh_lock
59 /* Kernel command line */
60 char arcs_cmdline
[CL_SIZE
] __initdata
= CONFIG_CMDLINE
;
63 bcm947xx_machine_restart(char *command
)
65 printk("Please stand by while rebooting the system...\n");
67 /* Set the watchdog timer to reset immediately */
74 bcm947xx_machine_halt(void)
76 printk("System halted\n");
78 /* Disable interrupts and watchdog and spin forever */
86 static struct serial_struct rs
= {
88 flags
: ASYNC_BOOT_AUTOCONF
,
89 io_type
: SERIAL_IO_MEM
,
93 serial_add(void *regs
, uint irq
, uint baud_base
, uint reg_shift
)
97 rs
.baud_base
= baud_base
/ 16;
98 rs
.iomem_reg_shift
= reg_shift
;
100 early_serial_setup(&rs
);
106 serial_setup(void *sbh
)
108 sb_serial_init(sbh
, serial_add
);
110 #ifdef CONFIG_REMOTE_DEBUG
111 /* Use the last port for kernel debugging */
117 #endif /* CONFIG_SERIAL */
124 /* Get global SB handle */
127 /* Initialize clocks and interrupts */
131 /* Initialize UARTs */
135 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
136 ide_ops
= &std_ide_ops
;
139 /* Override default command line arguments */
140 value
= nvram_get("kernel_args");
141 if (value
&& strlen(value
) && strncmp(value
, "empty", 5))
142 strncpy(arcs_cmdline
, value
, sizeof(arcs_cmdline
));
146 _machine_restart
= bcm947xx_machine_restart
;
147 _machine_halt
= bcm947xx_machine_halt
;
148 _machine_power_off
= bcm947xx_machine_halt
;
150 board_time_init
= bcm947xx_time_init
;
151 board_timer_setup
= bcm947xx_timer_setup
;
155 get_system_type(void)
157 return "Broadcom BCM947XX";
165 #ifdef CONFIG_MTD_PARTITIONS
167 static struct mtd_partition bcm947xx_parts
[] = {
168 { name
: "pmon", offset
: 0, size
: 0, mask_flags
: MTD_WRITEABLE
, },
169 { name
: "linux", offset
: 0, size
: 0, },
170 { name
: "rootfs", offset
: 0, size
: 0, },
171 { name
: "nvram", offset
: 0, size
: 0, },
172 { name
: "OpenWrt", offset
: 0, size
: 0, },
177 find_root(struct mtd_info
*mtd
, size_t size
, struct mtd_partition
*part
)
179 struct trx_header
*trx
;
180 unsigned char buf
[512];
184 trx
= (struct trx_header
*) buf
;
186 for (off
= (256*1024); off
< size
; off
+= mtd
->erasesize
) {
187 memset(buf
, 0xe5, sizeof(buf
));
192 if (MTD_READ(mtd
, off
, sizeof(buf
), &len
, buf
) ||
196 /* found a TRX header */
197 if (le32_to_cpu(trx
->magic
) == TRX_MAGIC
) {
198 part
->offset
= le32_to_cpu(trx
->offsets
[2]) ? :
199 le32_to_cpu(trx
->offsets
[1]);
200 part
->size
= le32_to_cpu(trx
->len
);
202 part
->size
-= part
->offset
;
210 "%s: Couldn't find root filesystem\n",
218 struct mtd_partition
* __init
219 init_mtd_partitions(struct mtd_info
*mtd
, size_t size
)
223 bcm947xx_parts
[0].offset
=0;
224 bcm947xx_parts
[0].size
=256*1024;
227 bcm947xx_parts
[3].offset
= size
- ROUNDUP(NVRAM_SPACE
, mtd
->erasesize
);
228 bcm947xx_parts
[3].size
= size
- bcm947xx_parts
[3].offset
;
230 /* Size linux (kernel and rootfs) */
231 bcm947xx_parts
[1].offset
= bcm947xx_parts
[0].size
;
232 bcm947xx_parts
[1].size
= bcm947xx_parts
[3].offset
- bcm947xx_parts
[1].offset
;
234 /* Find and size rootfs */
235 if (find_root(mtd
,size
,&bcm947xx_parts
[2])==0) {
237 bcm947xx_parts
[2].size
= bcm947xx_parts
[3].offset
- bcm947xx_parts
[2].offset
;
238 bcm947xx_parts
[4].name
= NULL
;
241 /* calculate leftover flash, and assign it to the jffs2 partition */
242 bcm947xx_parts
[4].offset
= bcm947xx_parts
[2].offset
+ bcm947xx_parts
[2].size
;
243 bcm947xx_parts
[4].offset
= ROUNDUP(bcm947xx_parts
[4].offset
, mtd
->erasesize
);
244 bcm947xx_parts
[4].size
= bcm947xx_parts
[3].offset
- bcm947xx_parts
[4].offset
;
247 return bcm947xx_parts
;
250 EXPORT_SYMBOL(init_mtd_partitions
);