K2.6 patches and update.
[tomato.git] / release / src-rt / linux / linux-2.6 / arch / mips / brcm-boards / bcm947xx / setup.c
blobfe7f72e83f0a2b4ada3247f7281b3d3f2fe41322
1 /*
2 * HND MIPS boards setup routines
4 * Copyright (C) 2009, Broadcom Corporation
5 * All Rights Reserved.
6 *
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.
12 * $Id: setup.c,v 1.14 2010/02/26 04:43:25 Exp $
15 #include <linux/types.h>
16 #include <linux/config.h>
17 #include <linux/init.h>
18 #include <linux/kernel.h>
19 #include <linux/serial.h>
20 #include <linux/serialP.h>
21 #include <linux/serial_core.h>
22 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
23 #include <linux/blkdev.h>
24 #include <linux/ide.h>
25 #endif
26 #include <asm/bootinfo.h>
27 #include <asm/cpu.h>
28 #include <asm/time.h>
29 #include <asm/reboot.h>
31 #ifdef CONFIG_MTD_PARTITIONS
32 #include <linux/mtd/mtd.h>
33 #include <linux/mtd/partitions.h>
34 #include <linux/romfs_fs.h>
35 #include <linux/cramfs_fs.h>
36 #include <linux/squashfs_fs.h>
37 #endif
39 #include <typedefs.h>
40 #include <osl.h>
41 #include <bcmutils.h>
42 #include <bcmnvram.h>
43 #include <siutils.h>
44 #include <hndsoc.h>
45 #include <hndcpu.h>
46 #include <mips33_core.h>
47 #include <mips74k_core.h>
48 #include <sbchipc.h>
49 #include <hndchipc.h>
50 #include <trxhdr.h>
51 #ifdef HNDCTF
52 #include <ctf/hndctf.h>
53 #endif /* HNDCTF */
54 #include "bcm947xx.h"
55 #ifdef NFLASH_SUPPORT
56 #include "nflash.h"
57 #endif
59 extern void bcm947xx_time_init(void);
60 extern void bcm947xx_timer_setup(struct irqaction *irq);
62 #ifdef CONFIG_KGDB
63 extern void set_debug_traps(void);
64 extern void rs_kgdb_hook(struct uart_port *);
65 extern void breakpoint(void);
66 #endif
68 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
69 extern struct ide_ops std_ide_ops;
70 #endif
72 /* Global SB handle */
73 si_t *bcm947xx_sih = NULL;
74 spinlock_t bcm947xx_sih_lock = SPIN_LOCK_UNLOCKED;
75 EXPORT_SYMBOL(bcm947xx_sih);
76 EXPORT_SYMBOL(bcm947xx_sih_lock);
78 /* CPU freq Tomato RAF features */
79 int bcm947xx_cpu_clk;
80 EXPORT_SYMBOL(bcm947xx_cpu_clk);
82 /* Convenience */
83 #define sih bcm947xx_sih
84 #define sih_lock bcm947xx_sih_lock
86 #ifdef HNDCTF
87 ctf_t *kcih = NULL;
88 EXPORT_SYMBOL(kcih);
89 ctf_attach_t ctf_attach_fn = NULL;
90 EXPORT_SYMBOL(ctf_attach_fn);
91 #endif /* HNDCTF */
93 /* Kernel command line */
94 extern char arcs_cmdline[CL_SIZE];
95 static int lanports_enable = 0;
96 static int wombo_reset = GPIO_PIN_NOTDEFINED;
98 static void
99 bcm947xx_reboot_handler(void)
101 if (lanports_enable) {
102 uint lp = 1 << lanports_enable;
103 si_gpioout(sih, lp, 0, GPIO_DRV_PRIORITY);
104 si_gpioouten(sih, lp, lp, GPIO_DRV_PRIORITY);
105 bcm_mdelay(1);
108 /* gpio 0 is also valid wombo_reset */
109 if (wombo_reset != GPIO_PIN_NOTDEFINED) {
110 int reset = 1 << wombo_reset;
112 si_gpioout(sih, reset, 0, GPIO_DRV_PRIORITY);
113 si_gpioouten(sih, reset, reset, GPIO_DRV_PRIORITY);
114 bcm_mdelay(10);
118 void
119 bcm947xx_machine_restart(char *command)
121 printk("Please stand by while rebooting the system...\n");
123 /* Set the watchdog timer to reset immediately */
124 local_irq_disable();
125 bcm947xx_reboot_handler();
126 hnd_cpu_reset(sih);
129 void
130 bcm947xx_machine_halt(void)
132 printk("System halted\n");
134 /* Disable interrupts and watchdog and spin forever */
135 local_irq_disable();
136 bcm947xx_reboot_handler();
137 si_watchdog(sih, 0);
138 while (1);
141 #ifdef CONFIG_SERIAL_CORE
143 static int num_ports = 0;
145 static void __init
146 serial_add(void *regs, uint irq, uint baud_base, uint reg_shift)
148 struct uart_port rs;
150 memset(&rs, 0, sizeof(rs));
151 rs.line = num_ports++;
152 rs.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
153 rs.iotype = UPIO_MEM;
155 rs.mapbase = (unsigned int) regs;
156 rs.membase = regs;
157 rs.irq = irq + 2;
158 rs.uartclk = baud_base;
159 rs.regshift = reg_shift;
161 if (early_serial_setup(&rs) != 0) {
162 printk(KERN_ERR "Serial setup failed!\n");
166 static void __init
167 serial_setup(si_t *sih)
169 si_serial_init(sih, serial_add);
171 #ifdef CONFIG_KGDB
172 /* Use the last port for kernel debugging */
173 if (rs.membase)
174 rs_kgdb_hook(&rs);
175 #endif
178 #endif /* CONFIG_SERIAL_CORE */
180 void __init
181 brcm_setup(void)
183 char *value;
185 /* Get global SB handle */
186 sih = si_kattach(SI_OSH);
188 /* Initialize clocks and interrupts */
189 si_mips_init(sih, SBMIPS_VIRTIRQ_BASE);
191 if (BCM330X(current_cpu_data.processor_id) &&
192 (read_c0_diag() & BRCM_PFC_AVAIL)) {
194 * Now that the sih is inited set the proper PFC value
196 printk("Setting the PFC to its default value\n");
197 enable_pfc(PFC_AUTO);
201 #ifdef CONFIG_SERIAL_CORE
202 /* Initialize UARTs */
203 serial_setup(sih);
204 #endif /* CONFIG_SERIAL_CORE */
206 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
207 ide_ops = &std_ide_ops;
208 #endif
210 #ifdef NFLASH_SUPPORT
211 if ((sih->ccrev >= 38) && ((sih->chipst & (1 << 4)) != 0)) {
212 if (strncmp(arcs_cmdline, "root=/dev/mtdblock", strlen("root=/dev/mtdblock")) == 0)
213 strcpy(arcs_cmdline, "root=/dev/mtdblock15 console=ttyS0,115200");
215 #endif
216 /* Override default command line arguments */
217 value = nvram_get("kernel_args");
218 if (value && strlen(value) && strncmp(value, "empty", 5))
219 strncpy(arcs_cmdline, value, sizeof(arcs_cmdline));
221 if ((lanports_enable = getgpiopin(NULL, "lanports_enable", GPIO_PIN_NOTDEFINED)) ==
222 GPIO_PIN_NOTDEFINED)
223 lanports_enable = 0;
225 /* wombo reset */
226 if ((wombo_reset = getgpiopin(NULL, "wombo_reset", GPIO_PIN_NOTDEFINED)) !=
227 GPIO_PIN_NOTDEFINED) {
228 int reset = 1 << wombo_reset;
230 printk("wombo_reset set to gpio %d\n", wombo_reset);
232 si_gpioout(sih, reset, 0, GPIO_DRV_PRIORITY);
233 si_gpioouten(sih, reset, reset, GPIO_DRV_PRIORITY);
234 bcm_mdelay(10);
236 si_gpioout(sih, reset, reset, GPIO_DRV_PRIORITY);
237 bcm_mdelay(20);
240 /* Generic setup */
241 _machine_restart = bcm947xx_machine_restart;
242 _machine_halt = bcm947xx_machine_halt;
243 pm_power_off = bcm947xx_machine_halt;
245 board_time_init = bcm947xx_time_init;
248 const char *
249 get_system_type(void)
251 static char s[32];
252 char cn[8];
254 if (bcm947xx_sih) {
255 bcm_chipname(bcm947xx_sih->chip, cn, 8);
256 sprintf(s, "Broadcom BCM%s chip rev %d pkg %d", cn,
257 bcm947xx_sih->chiprev, bcm947xx_sih->chippkg);
258 return s;
260 else
261 return "Broadcom BCM947XX";
264 void __init
265 bus_error_init(void)
269 void __init
270 plat_mem_setup(void)
272 brcm_setup();
273 return;
276 #ifdef CONFIG_MTD_PARTITIONS
278 enum {
279 RT_UNKNOWN,
280 RT_DIR320, // D-Link DIR-320
281 RT_WNR3500L, // Netgear WNR3500v2/U/L
282 RT_WNR2000V2, // Netgear WNR2000v2
283 RT_BELKIN_F7D // Belkin F7D3301, F7D3302, F7D4302, F7D8235V3
286 static int get_router(void)
288 uint boardnum = bcm_strtoul(nvram_safe_get("boardnum"), NULL, 0);
289 uint boardrev = bcm_strtoul(nvram_safe_get("boardrev"), NULL, 0);
290 uint boardtype = bcm_strtoul(nvram_safe_get("boardtype"), NULL, 0);
292 if ((boardnum == 1 || boardnum == 3500) && boardtype == 0x4CF && (boardrev == 0x1213 || boardrev == 2)) {
293 return RT_WNR3500L;
295 else if (boardnum == 1 && boardtype == 0xE4CD && boardrev == 0x1700) {
296 return RT_WNR2000V2;
298 #ifdef DIR320_BOARD
299 else if (boardnum == 0 && boardtype == 0x48E && boardrev == 0x35) {
300 return RT_DIR320;
302 #endif
303 else if (boardtype == 0xA4CF && (boardrev == 0x1102 || boardrev == 0x1100)) {
304 return RT_BELKIN_F7D;
306 return RT_UNKNOWN;
309 #ifdef DIR320_BOARD
310 static size_t get_erasesize(struct mtd_info *mtd, size_t offset, size_t size)
312 int i;
313 struct mtd_erase_region_info *regions;
314 size_t erasesize = 0;
316 if (mtd->numeraseregions > 1) {
317 regions = mtd->eraseregions;
319 // Find the first erase regions which is part of this partition
320 for (i = 0; i < mtd->numeraseregions && offset >= regions[i].offset; i++);
322 for (i--; i < mtd->numeraseregions && offset + size > regions[i].offset; i++) {
323 if (erasesize < regions[i].erasesize)
324 erasesize = regions[i].erasesize;
327 else {
328 erasesize = mtd->erasesize;
331 return erasesize;
333 #endif
336 new layout -- zzz 04/2006
338 +--------------+
339 | boot |
340 +---+----------+ < search for HDR0
341 | | |
342 | | (kernel) |
343 | l | |
344 | i +----------+ < + trx->offset[1]
345 | n | |
346 | u | rootfs |
347 | x | |
348 + +----------+ < + trx->len
349 | | jffs2 |
350 +---+----------+ < size - NVRAM_SPACE - board_data_size()
351 | board_data |
352 +--------------+ < size - NVRAM_SPACE
353 | nvram |
354 +--------------+ < size
357 static struct mtd_partition bcm947xx_parts[] = {
358 { name: "pmon", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, },
359 { name: "linux", offset: 0, size: 0, },
360 { name: "rootfs", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, },
361 { name: "jffs2", offset: 0, size: 0, },
362 { name: "nvram", offset: 0, size: 0, },
363 { name: "board_data", offset: 0, size: 0, },
364 { name: NULL, },
367 #define PART_BOOT 0
368 #define PART_LINUX 1
369 #define PART_ROOTFS 2
370 #define PART_JFFS2 3
371 #define PART_NVRAM 4
372 #define PART_BOARD 5
374 struct mtd_partition *
375 init_mtd_partitions(struct mtd_info *mtd, size_t size)
377 int router;
378 struct trx_header *trx;
379 unsigned char buf[512];
380 size_t off, trxoff, boardoff;
381 size_t crclen;
382 size_t len;
383 size_t trxsize;
385 crclen = 0;
387 /* Find and size nvram */
388 bcm947xx_parts[PART_NVRAM].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
389 bcm947xx_parts[PART_NVRAM].offset = size - bcm947xx_parts[PART_NVRAM].size;
391 /* Size board_data */
392 boardoff = bcm947xx_parts[PART_NVRAM].offset;
393 router = get_router();
394 switch (router) {
395 #ifdef DIR320_BOARD
396 case RT_DIR320:
397 if (get_erasesize(mtd, bcm947xx_parts[PART_NVRAM].offset, bcm947xx_parts[PART_NVRAM].size) == 0x2000) {
398 bcm947xx_parts[PART_NVRAM].size = ROUNDUP(NVRAM_SPACE, 0x2000);
399 bcm947xx_parts[PART_NVRAM].offset = size - bcm947xx_parts[PART_NVRAM].size;
400 bcm947xx_parts[PART_BOARD].size = 0x2000; // 8 KB
401 bcm947xx_parts[PART_BOARD].offset = bcm947xx_parts[PART_NVRAM].offset - bcm947xx_parts[PART_BOARD].size;
403 else bcm947xx_parts[PART_BOARD].name = NULL;
404 break;
405 #endif
406 case RT_WNR3500L:
407 case RT_WNR2000V2:
408 bcm947xx_parts[PART_BOARD].size = mtd->erasesize;
409 boardoff -= bcm947xx_parts[PART_BOARD].size;
410 bcm947xx_parts[PART_BOARD].offset = boardoff;
411 boardoff -= 5 * mtd->erasesize;
412 if (size <= 4 * 1024 * 1024) {
413 // 4MB flash
414 bcm947xx_parts[PART_JFFS2].offset = boardoff;
415 bcm947xx_parts[PART_JFFS2].size = bcm947xx_parts[PART_BOARD].offset - bcm947xx_parts[PART_JFFS2].offset;
417 else {
418 // 8MB or larger flash, exclude 1 block for Netgear CRC
419 crclen = mtd->erasesize;
421 break;
422 default:
423 bcm947xx_parts[PART_BOARD].name = NULL;
424 break;
427 trxsize = 0;
428 trx = (struct trx_header *) buf;
429 for (off = 0; off < size; off += mtd->erasesize) {
431 * Read block 0 to test for rootfs
433 if ((mtd->read(mtd, off, sizeof(buf), &len, buf)) || (len != sizeof(buf)))
434 continue;
436 /* Try looking at TRX header for rootfs offset */
437 switch (le32_to_cpu(trx->magic)) {
438 case TRX_MAGIC_F7D3301:
439 case TRX_MAGIC_F7D3302:
440 case TRX_MAGIC_F7D4302:
441 case TRX_MAGIC_F5D8235V3:
442 case TRX_MAGIC_QA:
443 if (router != RT_BELKIN_F7D)
444 continue;
445 // fall through
446 case TRX_MAGIC:
447 trxsize = ROUNDUP(le32_to_cpu(trx->len), mtd->erasesize); // kernel + rootfs
448 break;
451 if (trxsize) {
452 /* Size pmon */
453 bcm947xx_parts[PART_BOOT].size = off;
455 /* Size linux (kernel and rootfs) */
456 bcm947xx_parts[PART_LINUX].offset = off;
457 bcm947xx_parts[PART_LINUX].size = boardoff - off;
459 /* Find and size rootfs */
460 trxoff = (le32_to_cpu(trx->offsets[2]) > off) ? trx->offsets[2] : trx->offsets[1];
461 bcm947xx_parts[PART_ROOTFS].offset = trxoff + off;
462 bcm947xx_parts[PART_ROOTFS].size = trxsize - trxoff;
464 /* Find and size jffs2 */
465 if (bcm947xx_parts[PART_JFFS2].size == 0) {
466 bcm947xx_parts[PART_JFFS2].offset = off + trxsize;
467 if ((boardoff - crclen) > bcm947xx_parts[PART_JFFS2].offset) {
468 bcm947xx_parts[PART_JFFS2].size = boardoff - crclen - bcm947xx_parts[PART_JFFS2].offset;
472 break;
476 if (trxsize == 0) {
477 // uh, now what...
478 printk(KERN_NOTICE "%s: Unable to find a valid linux partition\n", mtd->name);
481 #if 0
482 int i;
483 for (i = 0; bcm947xx_parts[i].name; ++i) {
484 printk(KERN_NOTICE "%8x %8x (%8x) %s\n",
485 bcm947xx_parts[i].offset,
486 (bcm947xx_parts[i].offset + bcm947xx_parts[i].size) - 1,
487 bcm947xx_parts[i].size,
488 bcm947xx_parts[i].name);
490 #endif
492 return bcm947xx_parts;
495 EXPORT_SYMBOL(init_mtd_partitions);
497 #ifdef NFLASH_SUPPORT
498 static struct mtd_partition bcm947xx_nflash_parts[] =
501 .name = "boot",
502 .size = 0,
503 .offset = 0,
504 .mask_flags = MTD_WRITEABLE
507 .name = "nvram",
508 .size = 0,
509 .offset = 0
511 #if 1
513 .name = "board_data",
514 .offset = 0,
515 .size = 0,
518 .name = "POT1",
519 .offset = 0,
520 .size = 0,
523 .name = "POT2",
524 .offset = 0,
525 .size = 0,
528 .name = "T_Meter1",
529 .offset = 0,
530 .size = 0,
533 .name = "T_Meter2",
534 .offset = 0,
535 .size = 0,
538 .name = "ML1",
539 .offset = 0,
540 .size = 0,
543 .name = "ML2",
544 .offset = 0,
545 .size = 0,
548 .name = "ML3",
549 .offset = 0,
550 .size = 0,
553 .name = "ML4",
554 .offset = 0,
555 .size = 0,
558 .name = "ML5",
559 .offset = 0,
560 .size = 0,
563 .name = "ML6",
564 .offset = 0,
565 .size = 0,
568 .name = "ML7",
569 .offset = 0,
570 .size = 0,
572 #endif
574 .name = "linux",
575 .size = 0,
576 .offset = 0
579 .name = "rootfs",
580 .size = 0,
581 .offset = 0,
582 .mask_flags = MTD_WRITEABLE
585 .name = 0,
586 .size = 0,
587 .offset = 0
591 struct mtd_partition * init_nflash_mtd_partitions(struct mtd_info *mtd, size_t size)
593 struct romfs_super_block *romfsb;
594 struct cramfs_super *cramfsb;
595 struct squashfs_super_block *squashfsb;
596 struct trx_header *trx;
597 unsigned char buf[NFL_SECTOR_SIZE];
598 uint blocksize, mask, blk_offset, off, shift = 0;
599 chipcregs_t *cc;
600 uint32 bootsz, *bisz;
601 int ret, i;
602 uint32 top;
603 int idx;
605 romfsb = (struct romfs_super_block *) buf;
606 cramfsb = (struct cramfs_super *) buf;
607 squashfsb = (struct squashfs_super_block *) buf;
608 trx = (struct trx_header *) buf;
610 if ((cc = (chipcregs_t *)si_setcoreidx(sih, SI_CC_IDX)) == NULL)
611 return NULL;
613 /* Look at every block boundary till 16MB; higher space is reserved for application data. */
614 blocksize = mtd->erasesize;
615 for (off = NFL_BOOT_SIZE; off < NFL_BOOT_OS_SIZE; off += blocksize) {
616 mask = blocksize - 1;
617 blk_offset = off & ~mask;
618 if (nflash_checkbadb(sih, cc, blk_offset) != 0)
619 continue;
620 memset(buf, 0xe5, sizeof(buf));
621 if ((ret = nflash_read(sih, cc, off, sizeof(buf), buf)) != sizeof(buf)) {
622 printk(KERN_NOTICE
623 "%s: nflash_read return %d\n", mtd->name, ret);
624 continue;
627 /* Try looking at TRX header for rootfs offset */
628 if (le32_to_cpu(trx->magic) == TRX_MAGIC && off >= 0x500000) {
629 mask = NFL_SECTOR_SIZE - 1;
630 off = off + (le32_to_cpu(trx->offsets[1]) & ~mask) - blocksize;
631 shift = (le32_to_cpu(trx->offsets[1]) & mask);
632 romfsb = (unsigned char *)romfsb + shift;
633 cramfsb = (unsigned char *)cramfsb + shift;
634 squashfsb = (unsigned char *)squashfsb + shift;
635 continue;
638 /* romfs is at block zero too */
639 if (romfsb->word0 == ROMSB_WORD0 &&
640 romfsb->word1 == ROMSB_WORD1) {
641 printk(KERN_NOTICE
642 "%s: romfs filesystem found at block %d\n",
643 mtd->name, off / BLOCK_SIZE);
644 goto done;
647 /* so is cramfs */
648 if (cramfsb->magic == CRAMFS_MAGIC) {
649 printk(KERN_NOTICE
650 "%s: cramfs filesystem found at block %d\n",
651 mtd->name, off / BLOCK_SIZE);
652 goto done;
655 if (squashfsb->s_magic == SQUASHFS_MAGIC) {
656 printk(KERN_NOTICE
657 "%s: squash filesystem with lzma found at block %d\n",
658 mtd->name, off / BLOCK_SIZE);
659 goto done;
663 printk(KERN_NOTICE
664 "%s: Couldn't find valid ROM disk image\n",
665 mtd->name);
667 done:
669 /* Default is 256K boot partition */
670 bootsz = 256 * 1024;
672 /* Do we have a self-describing binary image? */
673 bisz = (uint32 *)KSEG1ADDR(SI_FLASH1 + BISZ_OFFSET);
674 if (bisz[BISZ_MAGIC_IDX] == BISZ_MAGIC) {
675 int isz = bisz[BISZ_DATAEND_IDX] - bisz[BISZ_TXTST_IDX];
677 if (isz > (1024 * 1024))
678 bootsz = 2048 * 1024;
679 else if (isz > (512 * 1024))
680 bootsz = 1024 * 1024;
681 else if (isz > (256 * 1024))
682 bootsz = 512 * 1024;
683 else if (isz <= (128 * 1024))
684 bootsz = 128 * 1024;
686 if (bootsz > mtd->erasesize) {
687 /* Prepare double space in case of bad blocks */
688 bootsz = (bootsz << 1);
689 } else {
690 /* CFE occupies at least one block */
691 bootsz = mtd->erasesize;
694 printf("Boot partition size = %d(0x%x)\n", bootsz, bootsz);
696 /* Size pmon */
697 bcm947xx_nflash_parts[0].size = bootsz;
699 /* Setup NVRAM MTD partition */
700 bcm947xx_nflash_parts[1].offset = bootsz;
701 bcm947xx_nflash_parts[1].size = NFL_BOOT_SIZE - bootsz;
703 i = (sizeof(bcm947xx_nflash_parts)/sizeof(struct mtd_partition)) - 2;
704 top = NFL_BOOT_OS_SIZE;
706 #if 1
707 for (idx = 2; idx <= i - 2; idx++)
709 if (strncmp(bcm947xx_nflash_parts[idx].name, "board_data", 10) == 0)
710 bcm947xx_nflash_parts[idx].size = 0x40000; /* 256K */
711 else if (strncmp(bcm947xx_nflash_parts[idx].name, "POT", 3) == 0)
712 bcm947xx_nflash_parts[idx].size = 0x40000; /* 256K */
713 else if (strncmp(bcm947xx_nflash_parts[idx].name, "T_Meter", 7) == 0)
714 bcm947xx_nflash_parts[idx].size = 0x40000; /* 256K */
715 else if (strncmp(bcm947xx_nflash_parts[idx].name, "ML", 2) == 0)
716 bcm947xx_nflash_parts[idx].size = 0x40000; /* 256K */
717 else if (strncmp(bcm947xx_nflash_parts[idx].name, "linux", 5) == 0)
718 break;
719 else if (strncmp(bcm947xx_nflash_parts[idx].name, "rootfs", 6) == 0)
720 break;
721 else
723 printk(KERN_ERR "%s: Unknow MTD name %s\n",
724 __FUNCTION__, bcm947xx_nflash_parts[idx].name);
725 break;
728 bcm947xx_nflash_parts[idx].offset = bcm947xx_nflash_parts[idx - 1].offset
729 + bcm947xx_nflash_parts[idx - 1].size;
731 #endif
733 /* Find and size rootfs */
734 if (off < size) {
735 bcm947xx_nflash_parts[i].offset = off + shift;
736 bcm947xx_nflash_parts[i].size =
737 top - bcm947xx_nflash_parts[i].offset;
740 /* Size linux (kernel and rootfs) */
741 bcm947xx_nflash_parts[i - 1].offset =
742 bcm947xx_nflash_parts[i - 2].offset + bcm947xx_nflash_parts[i - 2].size;
743 bcm947xx_nflash_parts[i - 1].size =
744 top - bcm947xx_nflash_parts[i - 1].offset;
746 return bcm947xx_nflash_parts;
749 EXPORT_SYMBOL(init_nflash_mtd_partitions);
750 #endif /* NFLASH_SUPPORT */
753 #endif