MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / mtd / maps / se4000.c
blob89cf2ea7e682982795e5f946f48ee47abd39919e
1 /****************************************************************************/
3 /*
4 * se4000.c -- MTD map driver for SnapGear SE4000 platform
6 * (C) Copyright 2003, Greg Ungerer <gerg@snapgear.com>
7 */
9 /****************************************************************************/
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include <linux/kernel.h>
14 #include <linux/string.h>
15 #include <linux/notifier.h>
16 #include <linux/init.h>
17 #include <linux/reboot.h>
18 #include <linux/mtd/mtd.h>
19 #include <linux/mtd/map.h>
20 #include <linux/mtd/partitions.h>
21 #include <linux/mtd/cfi.h>
22 #include <linux/ioport.h>
23 #include <asm/io.h>
25 /****************************************************************************/
27 static struct map_info se4000_map = {
28 .name = "SnapGear SE4000 Flash",
29 .buswidth = 2,
30 .phys = 0x50000000,
31 .size = 0x01000000,
34 static struct mtd_partition *parsed_parts;
36 /****************************************************************************/
38 #ifdef CONFIG_MTD_CFI_INTELEXT
40 * Set the Intel flash back to read mode as MTD may leave it in command mode.
43 static int se4000_reboot_notifier(
44 struct notifier_block *nb,
45 unsigned long val,
46 void *v)
48 struct cfi_private *cfi = se4000_map.fldrv_priv;
49 int i;
51 for (i = 0; cfi && i < cfi->numchips; i++)
52 cfi_send_gen_cmd(0xff, 0x55, cfi->chips[i].start, &se4000_map,
53 cfi, cfi->device_type, NULL);
55 return NOTIFY_OK;
58 static struct notifier_block se4000_notifier_block = {
59 se4000_reboot_notifier, NULL, 0
62 #endif
65 /****************************************************************************/
67 static struct mtd_info *se4000_mtd;
68 static const char *probes[] = { "RedBoot", NULL };
70 /****************************************************************************/
72 static void se4000_exit(void)
74 if (se4000_mtd) {
75 del_mtd_partitions(se4000_mtd);
76 map_destroy(se4000_mtd);
78 if (se4000_map.virt)
79 iounmap((void *)se4000_map.virt);
81 if (parsed_parts)
82 kfree(parsed_parts);
84 /* Disable flash write */
85 *IXP425_EXP_CS0 &= ~IXP425_FLASH_WRITABLE;
88 /****************************************************************************/
90 static int __init se4000_init(void)
92 int res, npart;
94 /* Enable flash write */
95 *IXP425_EXP_CS0 |= IXP425_FLASH_WRITABLE;
97 se4000_map.virt = (unsigned long) ioremap(se4000_map.phys, se4000_map.size);
98 if (!se4000_map.virt) {
99 printk(KERN_ERR "SE4000: ioremap(%x) failed\n", (int)se4000_map.phys);
100 res = -EIO;
101 goto Error;
104 /* Probe for the CFI complaint chip */
105 se4000_mtd = do_map_probe("cfi_probe", &se4000_map);
106 if (!se4000_mtd) {
107 res = -ENXIO;
108 goto Error;
110 se4000_mtd->owner = THIS_MODULE;
112 /* Try to parse RedBoot partitions */
113 npart = parse_mtd_partitions(se4000_mtd, probes, &parsed_parts, 0);
114 if (npart > 0) {
115 /* found "npart" RedBoot partitions */
116 res = add_mtd_partitions(se4000_mtd, parsed_parts, npart);
117 } else {
118 res = -EIO;
121 if (res)
122 goto Error;
124 #ifdef CONFIG_MTD_CFI_INTELEXT
125 register_reboot_notifier(&se4000_notifier_block);
126 #endif
128 return res;
129 Error:
130 se4000_exit();
131 return res;
134 /****************************************************************************/
136 module_init(se4000_init);
137 module_exit(se4000_exit);
139 MODULE_DESCRIPTION("MTD map driver for SnapGear SE4000");
141 /****************************************************************************/