diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/mtd/maps/wr_sbc82xx_flash.c |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/mtd/maps/wr_sbc82xx_flash.c')
-rw-r--r-- | drivers/mtd/maps/wr_sbc82xx_flash.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/drivers/mtd/maps/wr_sbc82xx_flash.c b/drivers/mtd/maps/wr_sbc82xx_flash.c new file mode 100644 index 000000000000..82b887b05707 --- /dev/null +++ b/drivers/mtd/maps/wr_sbc82xx_flash.c | |||
@@ -0,0 +1,181 @@ | |||
1 | /* | ||
2 | * $Id: wr_sbc82xx_flash.c,v 1.7 2004/11/04 13:24:15 gleixner Exp $ | ||
3 | * | ||
4 | * Map for flash chips on Wind River PowerQUICC II SBC82xx board. | ||
5 | * | ||
6 | * Copyright (C) 2004 Red Hat, Inc. | ||
7 | * | ||
8 | * Author: David Woodhouse <dwmw2@infradead.org> | ||
9 | * | ||
10 | */ | ||
11 | |||
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> | ||
17 | #include <asm/io.h> | ||
18 | #include <linux/mtd/mtd.h> | ||
19 | #include <linux/mtd/map.h> | ||
20 | #include <linux/config.h> | ||
21 | #include <linux/mtd/partitions.h> | ||
22 | |||
23 | #include <asm/immap_cpm2.h> | ||
24 | |||
25 | static struct mtd_info *sbcmtd[3]; | ||
26 | static struct mtd_partition *sbcmtd_parts[3]; | ||
27 | |||
28 | struct map_info sbc82xx_flash_map[3] = { | ||
29 | {.name = "Boot flash"}, | ||
30 | {.name = "Alternate boot flash"}, | ||
31 | {.name = "User flash"} | ||
32 | }; | ||
33 | |||
34 | static struct mtd_partition smallflash_parts[] = { | ||
35 | { | ||
36 | .name = "space", | ||
37 | .size = 0x100000, | ||
38 | .offset = 0, | ||
39 | }, { | ||
40 | .name = "bootloader", | ||
41 | .size = MTDPART_SIZ_FULL, | ||
42 | .offset = MTDPART_OFS_APPEND, | ||
43 | } | ||
44 | }; | ||
45 | |||
46 | static struct mtd_partition bigflash_parts[] = { | ||
47 | { | ||
48 | .name = "bootloader", | ||
49 | .size = 0x00100000, | ||
50 | .offset = 0, | ||
51 | }, { | ||
52 | .name = "file system", | ||
53 | .size = 0x01f00000, | ||
54 | .offset = MTDPART_OFS_APPEND, | ||
55 | }, { | ||
56 | .name = "boot config", | ||
57 | .size = 0x00100000, | ||
58 | .offset = MTDPART_OFS_APPEND, | ||
59 | }, { | ||
60 | .name = "space", | ||
61 | .size = 0x01f00000, | ||
62 | .offset = MTDPART_OFS_APPEND, | ||
63 | } | ||
64 | }; | ||
65 | |||
66 | static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL}; | ||
67 | |||
68 | #define init_sbc82xx_one_flash(map, br, or) \ | ||
69 | do { \ | ||
70 | (map).phys = (br & 1) ? (br & 0xffff8000) : 0; \ | ||
71 | (map).size = (br & 1) ? (~(or & 0xffff8000) + 1) : 0; \ | ||
72 | switch (br & 0x00001800) { \ | ||
73 | case 0x00000000: \ | ||
74 | case 0x00000800: (map).bankwidth = 1; break; \ | ||
75 | case 0x00001000: (map).bankwidth = 2; break; \ | ||
76 | case 0x00001800: (map).bankwidth = 4; break; \ | ||
77 | } \ | ||
78 | } while (0); | ||
79 | |||
80 | int __init init_sbc82xx_flash(void) | ||
81 | { | ||
82 | volatile memctl_cpm2_t *mc = &cpm2_immr->im_memctl; | ||
83 | int bigflash; | ||
84 | int i; | ||
85 | |||
86 | #ifdef CONFIG_SBC8560 | ||
87 | mc = ioremap(0xff700000 + 0x5000, sizeof(memctl_cpm2_t)); | ||
88 | #else | ||
89 | mc = &cpm2_immr->im_memctl; | ||
90 | #endif | ||
91 | |||
92 | bigflash = 1; | ||
93 | if ((mc->memc_br0 & 0x00001800) == 0x00001800) | ||
94 | bigflash = 0; | ||
95 | |||
96 | init_sbc82xx_one_flash(sbc82xx_flash_map[0], mc->memc_br0, mc->memc_or0); | ||
97 | init_sbc82xx_one_flash(sbc82xx_flash_map[1], mc->memc_br6, mc->memc_or6); | ||
98 | init_sbc82xx_one_flash(sbc82xx_flash_map[2], mc->memc_br1, mc->memc_or1); | ||
99 | |||
100 | #ifdef CONFIG_SBC8560 | ||
101 | iounmap((void *) mc); | ||
102 | #endif | ||
103 | |||
104 | for (i=0; i<3; i++) { | ||
105 | int8_t flashcs[3] = { 0, 6, 1 }; | ||
106 | int nr_parts; | ||
107 | |||
108 | printk(KERN_NOTICE "PowerQUICC II %s (%ld MiB on CS%d", | ||
109 | sbc82xx_flash_map[i].name, | ||
110 | (sbc82xx_flash_map[i].size >> 20), | ||
111 | flashcs[i]); | ||
112 | if (!sbc82xx_flash_map[i].phys) { | ||
113 | /* We know it can't be at zero. */ | ||
114 | printk("): disabled by bootloader.\n"); | ||
115 | continue; | ||
116 | } | ||
117 | printk(" at %08lx)\n", sbc82xx_flash_map[i].phys); | ||
118 | |||
119 | sbc82xx_flash_map[i].virt = ioremap(sbc82xx_flash_map[i].phys, sbc82xx_flash_map[i].size); | ||
120 | |||
121 | if (!sbc82xx_flash_map[i].virt) { | ||
122 | printk("Failed to ioremap\n"); | ||
123 | continue; | ||
124 | } | ||
125 | |||
126 | simple_map_init(&sbc82xx_flash_map[i]); | ||
127 | |||
128 | sbcmtd[i] = do_map_probe("cfi_probe", &sbc82xx_flash_map[i]); | ||
129 | |||
130 | if (!sbcmtd[i]) | ||
131 | continue; | ||
132 | |||
133 | sbcmtd[i]->owner = THIS_MODULE; | ||
134 | |||
135 | nr_parts = parse_mtd_partitions(sbcmtd[i], part_probes, | ||
136 | &sbcmtd_parts[i], 0); | ||
137 | if (nr_parts > 0) { | ||
138 | add_mtd_partitions (sbcmtd[i], sbcmtd_parts[i], nr_parts); | ||
139 | continue; | ||
140 | } | ||
141 | |||
142 | /* No partitioning detected. Use default */ | ||
143 | if (i == 2) { | ||
144 | add_mtd_device(sbcmtd[i]); | ||
145 | } else if (i == bigflash) { | ||
146 | add_mtd_partitions (sbcmtd[i], bigflash_parts, ARRAY_SIZE(bigflash_parts)); | ||
147 | } else { | ||
148 | add_mtd_partitions (sbcmtd[i], smallflash_parts, ARRAY_SIZE(smallflash_parts)); | ||
149 | } | ||
150 | } | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static void __exit cleanup_sbc82xx_flash(void) | ||
155 | { | ||
156 | int i; | ||
157 | |||
158 | for (i=0; i<3; i++) { | ||
159 | if (!sbcmtd[i]) | ||
160 | continue; | ||
161 | |||
162 | if (i<2 || sbcmtd_parts[i]) | ||
163 | del_mtd_partitions(sbcmtd[i]); | ||
164 | else | ||
165 | del_mtd_device(sbcmtd[i]); | ||
166 | |||
167 | kfree(sbcmtd_parts[i]); | ||
168 | map_destroy(sbcmtd[i]); | ||
169 | |||
170 | iounmap((void *)sbc82xx_flash_map[i].virt); | ||
171 | sbc82xx_flash_map[i].virt = 0; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | module_init(init_sbc82xx_flash); | ||
176 | module_exit(cleanup_sbc82xx_flash); | ||
177 | |||
178 | |||
179 | MODULE_LICENSE("GPL"); | ||
180 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); | ||
181 | MODULE_DESCRIPTION("Flash map driver for WindRiver PowerQUICC II"); | ||