ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / mtd / maps / h720x-flash.c
1 /*
2  * Flash memory access on Hynix GMS30C7201/HMS30C7202 based 
3  * evaluation boards
4  * 
5  * (C) 2002 Jungjun Kim <jungjun.kim@hynix.com>
6  *     2003 Thomas Gleixner <tglx@linutronix.de>        
7 */
8
9 #include <linux/config.h>
10 #include <linux/module.h>
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/errno.h>
15 #include <linux/slab.h>
16
17 #include <linux/mtd/mtd.h>
18 #include <linux/mtd/map.h>
19 #include <linux/mtd/partitions.h>
20 #include <asm/hardware.h>
21 #include <asm/io.h>
22
23 static struct mtd_info *mymtd;
24
25 static struct map_info h720x_map = {
26         .name =         "H720X",
27         .buswidth =     4,
28         .size =         FLASH_SIZE,
29         .phys =         FLASH_PHYS,
30 };
31
32 static struct mtd_partition h720x_partitions[] = {
33         {
34                 .name = "ArMon",
35                 .size = 0x00080000,
36                 .offset = 0,
37                 .mask_flags = MTD_WRITEABLE
38         },{
39                 .name = "Env",
40                 .size = 0x00040000,
41                 .offset = 0x00080000,
42                 .mask_flags = MTD_WRITEABLE
43         },{
44                 .name = "Kernel",
45                 .size = 0x00180000,
46                 .offset = 0x000c0000,
47                 .mask_flags = MTD_WRITEABLE
48         },{
49                 .name = "Ramdisk",
50                 .size = 0x00400000,
51                 .offset = 0x00240000,
52                 .mask_flags = MTD_WRITEABLE
53         },{
54                 .name = "jffs2",
55                 .size = MTDPART_SIZ_FULL,
56                 .offset = MTDPART_OFS_APPEND
57         }
58 };
59
60 #define NUM_PARTITIONS  (sizeof(h720x_partitions)/sizeof(h720x_partitions[0]))
61
62 static int                   nr_mtd_parts;
63 static struct mtd_partition *mtd_parts;
64 static const char *probes[] = { "cmdlinepart", NULL };
65
66 /*
67  * Initialize FLASH support
68  */
69 int __init h720x_mtd_init(void)
70 {
71
72         char    *part_type = NULL;
73         
74         h720x_map.virt = (unsigned long)ioremap(FLASH_PHYS, FLASH_SIZE);
75
76         if (!h720x_map.virt) {
77                 printk(KERN_ERR "H720x-MTD: ioremap failed\n");
78                 return -EIO;
79         }
80
81         simple_map_init(&h720x_map);
82
83         // Probe for flash buswidth 4
84         printk (KERN_INFO "H720x-MTD probing 32bit FLASH\n");
85         mymtd = do_map_probe("cfi_probe", &h720x_map);
86         if (!mymtd) {
87                 printk (KERN_INFO "H720x-MTD probing 16bit FLASH\n");
88             // Probe for buswidth 2
89             h720x_map.buswidth = 2;
90             mymtd = do_map_probe("cfi_probe", &h720x_map);
91         }
92             
93         if (mymtd) {
94                 mymtd->owner = THIS_MODULE;
95
96 #ifdef CONFIG_MTD_PARTITIONS
97                 nr_mtd_parts = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0);
98                 if (nr_mtd_parts > 0)
99                         part_type = "command line";
100 #endif
101                 if (nr_mtd_parts <= 0) {
102                         mtd_parts = h720x_partitions;
103                         nr_mtd_parts = NUM_PARTITIONS;
104                         part_type = "builtin";
105                 }
106                 printk(KERN_INFO "Using %s partition table\n", part_type);
107                 add_mtd_partitions(mymtd, mtd_parts, nr_mtd_parts);
108                 return 0;
109         }
110
111         iounmap((void *)h720x_map.virt);
112         return -ENXIO;
113 }
114
115 /*
116  * Cleanup
117  */
118 static void __exit h720x_mtd_cleanup(void)
119 {
120
121         if (mymtd) {
122                 del_mtd_partitions(mymtd);
123                 map_destroy(mymtd);
124         }
125         
126         /* Free partition info, if commandline partition was used */
127         if (mtd_parts && (mtd_parts != h720x_partitions))
128                 kfree (mtd_parts);
129         
130         if (h720x_map.virt) {
131                 iounmap((void *)h720x_map.virt);
132                 h720x_map.virt = 0;
133         }
134 }
135
136
137 module_init(h720x_mtd_init);
138 module_exit(h720x_mtd_cleanup);
139
140 MODULE_LICENSE("GPL");
141 MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
142 MODULE_DESCRIPTION("MTD map driver for Hynix evaluation boards");