2 * $Id: wr_sbc82xx_flash.c,v 1.1 2004/06/07 10:21:32 dwmw2 Exp $
4 * Map for flash chips on Wind River PowerQUICC II SBC82xx board.
6 * Copyright (C) 2004 Red Hat, Inc.
8 * Author: David Woodhouse <dwmw2@infradead.org>
12 #include <linux/module.h>
13 #include <linux/types.h>
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/slab.h>
18 #include <linux/mtd/mtd.h>
19 #include <linux/mtd/map.h>
20 #include <linux/config.h>
21 #include <linux/mtd/partitions.h>
23 #include <asm/immap_8260.h>
25 static struct mtd_info *sbcmtd[3];
26 static struct mtd_partition *sbcmtd_parts[3];
28 struct map_info sbc82xx_flash_map[3] = {
29 {.name = "Boot flash"},
30 {.name = "Alternate boot flash"},
31 {.name = "User flash"}
34 static struct mtd_partition smallflash_parts[] = {
41 .size = MTDPART_SIZ_FULL,
42 .offset = MTDPART_OFS_APPEND,
46 static struct mtd_partition bigflash_parts[] = {
52 .name = "file system",
53 .size = MTDPART_SIZ_FULL,
54 .offset = MTDPART_OFS_APPEND,
58 static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL};
60 int __init init_sbc82xx_flash(void)
62 volatile memctl8260_t *mc = &immr->im_memctl;
66 /* First, register the boot flash, whichever we're booting from */
67 if ((mc->memc_br0 & 0x00001800) == 0x00001800) {
69 } else if ((mc->memc_br0 & 0x00001800) == 0x00000800) {
72 printk(KERN_WARNING "Bus Controller register BR0 is %08x. Cannot determine flash configuration\n", mc->memc_br0);
76 /* Set parameters for the big flash chip (CS6 or CS0) */
77 sbc82xx_flash_map[bigflash].buswidth = 4;
78 sbc82xx_flash_map[bigflash].size = 0x4000000;
80 /* Set parameters for the small flash chip (CS0 or CS6) */
81 sbc82xx_flash_map[!bigflash].buswidth = 1;
82 sbc82xx_flash_map[!bigflash].size = 0x200000;
84 /* Set parameters for the user flash chip (CS1) */
85 sbc82xx_flash_map[2].buswidth = 4;
86 sbc82xx_flash_map[2].size = 0x4000000;
88 sbc82xx_flash_map[0].phys = mc->memc_br0 & 0xffff8000;
89 sbc82xx_flash_map[1].phys = mc->memc_br6 & 0xffff8000;
90 sbc82xx_flash_map[2].phys = mc->memc_br1 & 0xffff8000;
93 int8_t flashcs[3] = { 0, 6, 1 };
96 printk(KERN_NOTICE "PowerQUICC II %s (%ld MiB on CS%d",
97 sbc82xx_flash_map[i].name, sbc82xx_flash_map[i].size >> 20, flashcs[i]);
98 if (!sbc82xx_flash_map[i].phys) {
99 /* We know it can't be at zero. */
100 printk("): disabled by bootloader.\n");
103 printk(" at %08lx)\n", sbc82xx_flash_map[i].phys);
105 sbc82xx_flash_map[i].virt = (unsigned long)ioremap(sbc82xx_flash_map[i].phys, sbc82xx_flash_map[i].size);
107 if (!sbc82xx_flash_map[i].virt) {
108 printk("Failed to ioremap\n");
112 simple_map_init(&sbc82xx_flash_map[i]);
114 sbcmtd[i] = do_map_probe("cfi_probe", &sbc82xx_flash_map[i]);
119 sbcmtd[i]->owner = THIS_MODULE;
121 nr_parts = parse_mtd_partitions(sbcmtd[i], part_probes,
122 &sbcmtd_parts[i], 0);
124 add_mtd_partitions (sbcmtd[i], sbcmtd_parts[i], nr_parts);
128 /* No partitioning detected. Use default */
130 add_mtd_device(sbcmtd[i]);
131 } else if (i == bigflash) {
132 add_mtd_partitions (sbcmtd[i], bigflash_parts, ARRAY_SIZE(bigflash_parts));
134 add_mtd_partitions (sbcmtd[i], smallflash_parts, ARRAY_SIZE(smallflash_parts));
140 static void __exit cleanup_sbc82xx_flash(void)
144 for (i=0; i<3; i++) {
148 if (i<2 || sbcmtd_parts[i])
149 del_mtd_partitions(sbcmtd[i]);
151 del_mtd_device(sbcmtd[i]);
153 kfree(sbcmtd_parts[i]);
154 map_destroy(sbcmtd[i]);
156 iounmap((void *)sbc82xx_flash_map[i].virt);
157 sbc82xx_flash_map[i].virt = 0;
161 module_init(init_sbc82xx_flash);
162 module_exit(cleanup_sbc82xx_flash);
165 MODULE_LICENSE("GPL");
166 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
167 MODULE_DESCRIPTION("Flash map driver for WindRiver PowerQUICC II");