added mtd driver
[linux-2.4.git] / drivers / mtd / maps / cdb89712.c
1 /*
2  * Flash on Cirrus CDB89712
3  *
4  * $Id: cdb89712.c,v 1.3 2001/10/02 15:14:43 rmk Exp $
5  */
6
7 #include <linux/module.h>
8 #include <linux/types.h>
9 #include <linux/kernel.h>
10 #include <linux/ioport.h>
11 #include <asm/io.h>
12 #include <asm/arch/hardware.h>
13 #include <linux/mtd/mtd.h>
14 #include <linux/mtd/map.h>
15 #include <linux/mtd/partitions.h>
16
17
18
19 __u8 cdb89712_read8(struct map_info *map, unsigned long ofs)
20 {
21         return __raw_readb(map->map_priv_1 + ofs);
22 }
23
24 __u16 cdb89712_read16(struct map_info *map, unsigned long ofs)
25 {
26         return __raw_readw(map->map_priv_1 + ofs);
27 }
28
29 __u32 cdb89712_read32(struct map_info *map, unsigned long ofs)
30 {
31         return __raw_readl(map->map_priv_1 + ofs);
32 }
33
34 void cdb89712_write8(struct map_info *map, __u8 d, unsigned long adr)
35 {
36         __raw_writeb(d, map->map_priv_1 + adr);
37         mb();
38 }
39
40 void cdb89712_write16(struct map_info *map, __u16 d, unsigned long adr)
41 {
42         __raw_writew(d, map->map_priv_1 + adr);
43         mb();
44 }
45
46 void cdb89712_write32(struct map_info *map, __u32 d, unsigned long adr)
47 {
48         __raw_writel(d, map->map_priv_1 + adr);
49         mb();
50 }
51
52 void cdb89712_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
53 {
54         // printk ("cdb89712_copy_from: 0x%x@0x%x -> 0x%x\n", len, from, to);
55         memcpy_fromio(to, map->map_priv_1 + from, len);
56 }
57
58 void cdb89712_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
59 {
60         while(len) {
61                 __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to);
62                 from++;
63                 to++;
64                 len--;
65         }
66 }
67
68
69 static struct mtd_info *flash_mtd;
70
71 struct map_info cdb89712_flash_map = {
72         name: "flash",
73         size: FLASH_SIZE,
74         buswidth: FLASH_WIDTH,
75         read8: cdb89712_read8,
76         read16: cdb89712_read16,
77         read32: cdb89712_read32,
78         copy_from: cdb89712_copy_from,
79         write8: cdb89712_write8,
80         write16: cdb89712_write16,
81         write32: cdb89712_write32,
82         copy_to: cdb89712_copy_to
83 };
84
85 struct resource cdb89712_flash_resource = {
86         name:   "Flash",
87         start:  FLASH_START,
88         end:    FLASH_START + FLASH_SIZE - 1,
89         flags:  IORESOURCE_IO | IORESOURCE_BUSY,
90 };
91
92 static int __init init_cdb89712_flash (void)
93 {
94         int err;
95         
96         if (request_resource (&ioport_resource, &cdb89712_flash_resource)) {
97                 printk(KERN_NOTICE "Failed to reserve Cdb89712 FLASH space\n");
98                 err = -EBUSY;
99                 goto out;
100         }
101         
102         cdb89712_flash_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
103         if (!cdb89712_flash_map.map_priv_1) {
104                 printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n");
105                 err = -EIO;
106                 goto out_resource;
107         }
108
109         flash_mtd = do_map_probe("cfi_probe", &cdb89712_flash_map);
110         if (!flash_mtd) {
111                 flash_mtd = do_map_probe("map_rom", &cdb89712_flash_map);
112                 if (flash_mtd)
113                         flash_mtd->erasesize = 0x10000;
114         }
115         if (!flash_mtd) {
116                 printk("FLASH probe failed\n");
117                 err = -ENXIO;
118                 goto out_ioremap;
119         }
120
121         flash_mtd->module = THIS_MODULE;
122         
123         if (add_mtd_device(flash_mtd)) {
124                 printk("FLASH device addition failed\n");
125                 err = -ENOMEM;
126                 goto out_probe;
127         }
128                 
129         return 0;
130
131 out_probe:
132         map_destroy(flash_mtd);
133         flash_mtd = 0;
134 out_ioremap:
135         iounmap((void *)cdb89712_flash_map.map_priv_1);
136 out_resource:
137         release_resource (&cdb89712_flash_resource);
138 out:
139         return err;
140 }
141
142
143
144
145
146 static struct mtd_info *sram_mtd;
147
148 struct map_info cdb89712_sram_map = {
149         name: "SRAM",
150         size: SRAM_SIZE,
151         buswidth: SRAM_WIDTH,
152         read8: cdb89712_read8,
153         read16: cdb89712_read16,
154         read32: cdb89712_read32,
155         copy_from: cdb89712_copy_from,
156         write8: cdb89712_write8,
157         write16: cdb89712_write16,
158         write32: cdb89712_write32,
159         copy_to: cdb89712_copy_to
160 };
161
162 struct resource cdb89712_sram_resource = {
163         name:   "SRAM",
164         start:  SRAM_START,
165         end:    SRAM_START + SRAM_SIZE - 1,
166         flags:  IORESOURCE_IO | IORESOURCE_BUSY,
167 };
168
169 static int __init init_cdb89712_sram (void)
170 {
171         int err;
172         
173         if (request_resource (&ioport_resource, &cdb89712_sram_resource)) {
174                 printk(KERN_NOTICE "Failed to reserve Cdb89712 SRAM space\n");
175                 err = -EBUSY;
176                 goto out;
177         }
178         
179         cdb89712_sram_map.map_priv_1 = (unsigned long)ioremap(SRAM_START, SRAM_SIZE);
180         if (!cdb89712_sram_map.map_priv_1) {
181                 printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n");
182                 err = -EIO;
183                 goto out_resource;
184         }
185
186         sram_mtd = do_map_probe("map_ram", &cdb89712_sram_map);
187         if (!sram_mtd) {
188                 printk("SRAM probe failed\n");
189                 err = -ENXIO;
190                 goto out_ioremap;
191         }
192
193         sram_mtd->module = THIS_MODULE;
194         sram_mtd->erasesize = 16;
195         
196         if (add_mtd_device(sram_mtd)) {
197                 printk("SRAM device addition failed\n");
198                 err = -ENOMEM;
199                 goto out_probe;
200         }
201                 
202         return 0;
203
204 out_probe:
205         map_destroy(sram_mtd);
206         sram_mtd = 0;
207 out_ioremap:
208         iounmap((void *)cdb89712_sram_map.map_priv_1);
209 out_resource:
210         release_resource (&cdb89712_sram_resource);
211 out:
212         return err;
213 }
214
215
216
217
218
219
220
221 static struct mtd_info *bootrom_mtd;
222
223 struct map_info cdb89712_bootrom_map = {
224         name: "BootROM",
225         size: BOOTROM_SIZE,
226         buswidth: BOOTROM_WIDTH,
227         read8: cdb89712_read8,
228         read16: cdb89712_read16,
229         read32: cdb89712_read32,
230         copy_from: cdb89712_copy_from,
231 };
232
233 struct resource cdb89712_bootrom_resource = {
234         name:   "BootROM",
235         start:  BOOTROM_START,
236         end:    BOOTROM_START + BOOTROM_SIZE - 1,
237         flags:  IORESOURCE_IO | IORESOURCE_BUSY,
238 };
239
240 static int __init init_cdb89712_bootrom (void)
241 {
242         int err;
243         
244         if (request_resource (&ioport_resource, &cdb89712_bootrom_resource)) {
245                 printk(KERN_NOTICE "Failed to reserve Cdb89712 BOOTROM space\n");
246                 err = -EBUSY;
247                 goto out;
248         }
249         
250         cdb89712_bootrom_map.map_priv_1 = (unsigned long)ioremap(BOOTROM_START, BOOTROM_SIZE);
251         if (!cdb89712_bootrom_map.map_priv_1) {
252                 printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n");
253                 err = -EIO;
254                 goto out_resource;
255         }
256
257         bootrom_mtd = do_map_probe("map_rom", &cdb89712_bootrom_map);
258         if (!bootrom_mtd) {
259                 printk("BootROM probe failed\n");
260                 err = -ENXIO;
261                 goto out_ioremap;
262         }
263
264         bootrom_mtd->module = THIS_MODULE;
265         bootrom_mtd->erasesize = 0x10000;
266         
267         if (add_mtd_device(bootrom_mtd)) {
268                 printk("BootROM device addition failed\n");
269                 err = -ENOMEM;
270                 goto out_probe;
271         }
272                 
273         return 0;
274
275 out_probe:
276         map_destroy(bootrom_mtd);
277         bootrom_mtd = 0;
278 out_ioremap:
279         iounmap((void *)cdb89712_bootrom_map.map_priv_1);
280 out_resource:
281         release_resource (&cdb89712_bootrom_resource);
282 out:
283         return err;
284 }
285
286
287
288
289
290 static int __init init_cdb89712_maps(void)
291 {
292
293         printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n  Flash 0x%x at 0x%x\n  SRAM 0x%x at 0x%x\n  BootROM 0x%x at 0x%x\n", 
294                FLASH_SIZE, FLASH_START, SRAM_SIZE, SRAM_START, BOOTROM_SIZE, BOOTROM_START);
295
296         init_cdb89712_flash();
297         init_cdb89712_sram();
298         init_cdb89712_bootrom();
299         
300         return 0;
301 }
302         
303
304 static void __exit cleanup_cdb89712_maps(void)
305 {
306         if (sram_mtd) {
307                 del_mtd_device(sram_mtd);
308                 map_destroy(sram_mtd);
309                 iounmap((void *)cdb89712_sram_map.map_priv_1);
310                 release_resource (&cdb89712_sram_resource);
311         }
312         
313         if (flash_mtd) {
314                 del_mtd_device(flash_mtd);
315                 map_destroy(flash_mtd);
316                 iounmap((void *)cdb89712_flash_map.map_priv_1);
317                 release_resource (&cdb89712_flash_resource);
318         }
319
320         if (bootrom_mtd) {
321                 del_mtd_device(bootrom_mtd);
322                 map_destroy(bootrom_mtd);
323                 iounmap((void *)cdb89712_bootrom_map.map_priv_1);
324                 release_resource (&cdb89712_bootrom_resource);
325         }
326 }
327
328 module_init(init_cdb89712_maps);
329 module_exit(cleanup_cdb89712_maps);
330
331 MODULE_AUTHOR("Ray L");
332 MODULE_DESCRIPTION("ARM CDB89712 map driver");
333 MODULE_LICENSE("GPL");