aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/maps
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/maps')
-rw-r--r--drivers/mtd/maps/Kconfig11
-rw-r--r--drivers/mtd/maps/cfi_flagadm.c4
-rw-r--r--drivers/mtd/maps/dbox2-flash.c2
-rw-r--r--drivers/mtd/maps/mtx-1_flash.c2
-rw-r--r--drivers/mtd/maps/nettel.c4
-rw-r--r--drivers/mtd/maps/pcmciamtd.c1
-rw-r--r--drivers/mtd/maps/physmap.c255
-rw-r--r--drivers/mtd/maps/sun_uflash.c195
8 files changed, 294 insertions, 180 deletions
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 97b3e0d20865..83d0b2a52527 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -37,7 +37,7 @@ config MTD_PHYSMAP_START
37config MTD_PHYSMAP_LEN 37config MTD_PHYSMAP_LEN
38 hex "Physical length of flash mapping" 38 hex "Physical length of flash mapping"
39 depends on MTD_PHYSMAP 39 depends on MTD_PHYSMAP
40 default "0x4000000" 40 default "0"
41 help 41 help
42 This is the total length of the mapping of the flash chips on 42 This is the total length of the mapping of the flash chips on
43 your particular board. If there is space, or aliases, in the 43 your particular board. If there is space, or aliases, in the
@@ -78,7 +78,7 @@ config MTD_PNC2000
78 78
79config MTD_SC520CDP 79config MTD_SC520CDP
80 tristate "CFI Flash device mapped on AMD SC520 CDP" 80 tristate "CFI Flash device mapped on AMD SC520 CDP"
81 depends on X86 && MTD_CFI 81 depends on X86 && MTD_CFI && MTD_CONCAT
82 help 82 help
83 The SC520 CDP board has two banks of CFI-compliant chips and one 83 The SC520 CDP board has two banks of CFI-compliant chips and one
84 Dual-in-line JEDEC chip. This 'mapping' driver supports that 84 Dual-in-line JEDEC chip. This 'mapping' driver supports that
@@ -109,7 +109,7 @@ config MTD_TS5500
109 mtd1 allows you to reprogram your BIOS. BE VERY CAREFUL. 109 mtd1 allows you to reprogram your BIOS. BE VERY CAREFUL.
110 110
111 Note that jumper 3 ("Write Enable Drive A") must be set 111 Note that jumper 3 ("Write Enable Drive A") must be set
112 otherwise detection won't succeeed. 112 otherwise detection won't succeed.
113 113
114config MTD_SBC_GXX 114config MTD_SBC_GXX
115 tristate "CFI Flash device mapped on Arcom SBC-GXx boards" 115 tristate "CFI Flash device mapped on Arcom SBC-GXx boards"
@@ -200,8 +200,8 @@ config MTD_TSUNAMI
200 Support for the flash chip on Tsunami TIG bus. 200 Support for the flash chip on Tsunami TIG bus.
201 201
202config MTD_LASAT 202config MTD_LASAT
203 tristate "Flash chips on LASAT board" 203 tristate "LASAT flash device"
204 depends on LASAT 204 depends on LASAT && MTD_CFI
205 help 205 help
206 Support for the flash chips on the Lasat 100 and 200 boards. 206 Support for the flash chips on the Lasat 100 and 200 boards.
207 207
@@ -561,7 +561,6 @@ config MTD_PCMCIA
561config MTD_PCMCIA_ANONYMOUS 561config MTD_PCMCIA_ANONYMOUS
562 bool "Use PCMCIA MTD drivers for anonymous PCMCIA cards" 562 bool "Use PCMCIA MTD drivers for anonymous PCMCIA cards"
563 depends on MTD_PCMCIA 563 depends on MTD_PCMCIA
564 default N
565 help 564 help
566 If this option is enabled, PCMCIA cards which do not report 565 If this option is enabled, PCMCIA cards which do not report
567 anything about themselves are assumed to be MTD cards. 566 anything about themselves are assumed to be MTD cards.
diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c
index fd0f0d3187de..92b5d883d7b0 100644
--- a/drivers/mtd/maps/cfi_flagadm.c
+++ b/drivers/mtd/maps/cfi_flagadm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is> 2 * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is>
3 * 3 *
4 * $Id: cfi_flagadm.c,v 1.15 2005/11/07 11:14:26 gleixner Exp $ 4 * $Id: cfi_flagadm.c,v 1.15 2005/11/07 11:14:26 gleixner Exp $
5 * 5 *
@@ -135,5 +135,5 @@ module_exit(cleanup_flagadm);
135 135
136 136
137MODULE_LICENSE("GPL"); 137MODULE_LICENSE("GPL");
138MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>"); 138MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>");
139MODULE_DESCRIPTION("MTD map driver for Flaga digital module"); 139MODULE_DESCRIPTION("MTD map driver for Flaga digital module");
diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c
index 652813cd6c2d..85c2a9e22b1e 100644
--- a/drivers/mtd/maps/dbox2-flash.c
+++ b/drivers/mtd/maps/dbox2-flash.c
@@ -122,5 +122,5 @@ module_exit(cleanup_dbox2_flash);
122 122
123 123
124MODULE_LICENSE("GPL"); 124MODULE_LICENSE("GPL");
125MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>, Bastian Blank <waldi@tuxbox.org>, Alexander Wild <wild@te-elektronik.com>"); 125MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>, Bastian Blank <waldi@tuxbox.org>, Alexander Wild <wild@te-elektronik.com>");
126MODULE_DESCRIPTION("MTD map driver for D-Box 2 board"); 126MODULE_DESCRIPTION("MTD map driver for D-Box 2 board");
diff --git a/drivers/mtd/maps/mtx-1_flash.c b/drivers/mtd/maps/mtx-1_flash.c
index d1e66e186746..5c25d4e552c6 100644
--- a/drivers/mtd/maps/mtx-1_flash.c
+++ b/drivers/mtd/maps/mtx-1_flash.c
@@ -4,7 +4,7 @@
4 * $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $ 4 * $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $
5 * 5 *
6 * (C) 2005 Bruno Randolf <bruno.randolf@4g-systems.biz> 6 * (C) 2005 Bruno Randolf <bruno.randolf@4g-systems.biz>
7 * (C) 2005 Jörn Engel <joern@wohnheim.fh-wedel.de> 7 * (C) 2005 Jörn Engel <joern@wohnheim.fh-wedel.de>
8 * 8 *
9 */ 9 */
10 10
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index 54a3102ab19a..0994b5b2e331 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -20,6 +20,8 @@
20#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
21#include <linux/mtd/cfi.h> 21#include <linux/mtd/cfi.h>
22#include <linux/reboot.h> 22#include <linux/reboot.h>
23#include <linux/kdev_t.h>
24#include <linux/root_dev.h>
23#include <asm/io.h> 25#include <asm/io.h>
24 26
25/****************************************************************************/ 27/****************************************************************************/
@@ -188,7 +190,7 @@ int nettel_eraseconfig(void)
188 set_current_state(TASK_INTERRUPTIBLE); 190 set_current_state(TASK_INTERRUPTIBLE);
189 add_wait_queue(&wait_q, &wait); 191 add_wait_queue(&wait_q, &wait);
190 192
191 ret = MTD_ERASE(mtd, &nettel_erase); 193 ret = mtd->erase(mtd, &nettel_erase);
192 if (ret) { 194 if (ret) {
193 set_current_state(TASK_RUNNING); 195 set_current_state(TASK_RUNNING);
194 remove_wait_queue(&wait_q, &wait); 196 remove_wait_queue(&wait_q, &wait);
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index d27f4129afd3..c861134cbc48 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -713,6 +713,7 @@ static void pcmciamtd_detach(struct pcmcia_device *link)
713 713
714 if(dev->mtd_info) { 714 if(dev->mtd_info) {
715 del_mtd_device(dev->mtd_info); 715 del_mtd_device(dev->mtd_info);
716 map_destroy(dev->mtd_info);
716 info("mtd%d: Removed", dev->mtd_info->index); 717 info("mtd%d: Removed", dev->mtd_info->index);
717 } 718 }
718 719
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index f49ebc3c4606..433c3cac3ca9 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -14,112 +14,229 @@
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <asm/io.h> 17#include <linux/device.h>
18#include <linux/platform_device.h>
18#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
19#include <linux/mtd/map.h> 20#include <linux/mtd/map.h>
20#include <linux/config.h> 21#include <linux/config.h>
21#include <linux/mtd/partitions.h> 22#include <linux/mtd/partitions.h>
22#include <linux/mtd/physmap.h> 23#include <linux/mtd/physmap.h>
24#include <asm/io.h>
23 25
24static struct mtd_info *mymtd; 26struct physmap_flash_info {
25 27 struct mtd_info *mtd;
26struct map_info physmap_map = { 28 struct map_info map;
27 .name = "phys_mapped_flash", 29 struct resource *res;
28 .phys = CONFIG_MTD_PHYSMAP_START, 30#ifdef CONFIG_MTD_PARTITIONS
29 .size = CONFIG_MTD_PHYSMAP_LEN, 31 int nr_parts;
30 .bankwidth = CONFIG_MTD_PHYSMAP_BANKWIDTH, 32 struct mtd_partition *parts;
33#endif
31}; 34};
32 35
36
37static int physmap_flash_remove(struct platform_device *dev)
38{
39 struct physmap_flash_info *info;
40 struct physmap_flash_data *physmap_data;
41
42 info = platform_get_drvdata(dev);
43 if (info == NULL)
44 return 0;
45 platform_set_drvdata(dev, NULL);
46
47 physmap_data = dev->dev.platform_data;
48
49 if (info->mtd != NULL) {
33#ifdef CONFIG_MTD_PARTITIONS 50#ifdef CONFIG_MTD_PARTITIONS
34static struct mtd_partition *mtd_parts; 51 if (info->nr_parts) {
35static int mtd_parts_nb; 52 del_mtd_partitions(info->mtd);
53 kfree(info->parts);
54 } else if (physmap_data->nr_parts) {
55 del_mtd_partitions(info->mtd);
56 } else {
57 del_mtd_device(info->mtd);
58 }
59#else
60 del_mtd_device(info->mtd);
61#endif
62 map_destroy(info->mtd);
63 }
36 64
37static int num_physmap_partitions; 65 if (info->map.virt != NULL)
38static struct mtd_partition *physmap_partitions; 66 iounmap((void *)info->map.virt);
39 67
40static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL}; 68 if (info->res != NULL) {
69 release_resource(info->res);
70 kfree(info->res);
71 }
41 72
42void physmap_set_partitions(struct mtd_partition *parts, int num_parts) 73 return 0;
43{
44 physmap_partitions=parts;
45 num_physmap_partitions=num_parts;
46} 74}
47#endif /* CONFIG_MTD_PARTITIONS */
48 75
49static int __init init_physmap(void) 76static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL };
77#ifdef CONFIG_MTD_PARTITIONS
78static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
79#endif
80
81static int physmap_flash_probe(struct platform_device *dev)
50{ 82{
51 static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL }; 83 struct physmap_flash_data *physmap_data;
52 const char **type; 84 struct physmap_flash_info *info;
85 const char **probe_type;
86 int err;
87
88 physmap_data = dev->dev.platform_data;
89 if (physmap_data == NULL)
90 return -ENODEV;
91
92 printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n",
93 (unsigned long long)dev->resource->end - dev->resource->start + 1,
94 (unsigned long long)dev->resource->start);
95
96 info = kmalloc(sizeof(struct physmap_flash_info), GFP_KERNEL);
97 if (info == NULL) {
98 err = -ENOMEM;
99 goto err_out;
100 }
101 memset(info, 0, sizeof(*info));
53 102
54 printk(KERN_NOTICE "physmap flash device: %lx at %lx\n", physmap_map.size, physmap_map.phys); 103 platform_set_drvdata(dev, info);
55 physmap_map.virt = ioremap(physmap_map.phys, physmap_map.size);
56 104
57 if (!physmap_map.virt) { 105 info->res = request_mem_region(dev->resource->start,
58 printk("Failed to ioremap\n"); 106 dev->resource->end - dev->resource->start + 1,
59 return -EIO; 107 dev->dev.bus_id);
108 if (info->res == NULL) {
109 dev_err(&dev->dev, "Could not reserve memory region\n");
110 err = -ENOMEM;
111 goto err_out;
60 } 112 }
61 113
62 simple_map_init(&physmap_map); 114 info->map.name = dev->dev.bus_id;
115 info->map.phys = dev->resource->start;
116 info->map.size = dev->resource->end - dev->resource->start + 1;
117 info->map.bankwidth = physmap_data->width;
118 info->map.set_vpp = physmap_data->set_vpp;
119
120 info->map.virt = ioremap(info->map.phys, info->map.size);
121 if (info->map.virt == NULL) {
122 dev_err(&dev->dev, "Failed to ioremap flash region\n");
123 err = EIO;
124 goto err_out;
125 }
63 126
64 mymtd = NULL; 127 simple_map_init(&info->map);
65 type = rom_probe_types; 128
66 for(; !mymtd && *type; type++) { 129 probe_type = rom_probe_types;
67 mymtd = do_map_probe(*type, &physmap_map); 130 for (; info->mtd == NULL && *probe_type != NULL; probe_type++)
131 info->mtd = do_map_probe(*probe_type, &info->map);
132 if (info->mtd == NULL) {
133 dev_err(&dev->dev, "map_probe failed\n");
134 err = -ENXIO;
135 goto err_out;
68 } 136 }
69 if (mymtd) { 137 info->mtd->owner = THIS_MODULE;
70 mymtd->owner = THIS_MODULE;
71 138
72#ifdef CONFIG_MTD_PARTITIONS 139#ifdef CONFIG_MTD_PARTITIONS
73 mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes, 140 err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0);
74 &mtd_parts, 0); 141 if (err > 0) {
142 add_mtd_partitions(info->mtd, info->parts, err);
143 return 0;
144 }
75 145
76 if (mtd_parts_nb > 0) 146 if (physmap_data->nr_parts) {
77 { 147 printk(KERN_NOTICE "Using physmap partition information\n");
78 add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb); 148 add_mtd_partitions(info->mtd, physmap_data->parts,
79 return 0; 149 physmap_data->nr_parts);
80 } 150 return 0;
151 }
152#endif
153
154 add_mtd_device(info->mtd);
155 return 0;
156
157err_out:
158 physmap_flash_remove(dev);
159 return err;
160}
161
162static struct platform_driver physmap_flash_driver = {
163 .probe = physmap_flash_probe,
164 .remove = physmap_flash_remove,
165 .driver = {
166 .name = "physmap-flash",
167 },
168};
81 169
82 if (num_physmap_partitions != 0)
83 {
84 printk(KERN_NOTICE
85 "Using physmap partition definition\n");
86 add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions);
87 return 0;
88 }
89 170
171#ifdef CONFIG_MTD_PHYSMAP_LEN
172#if CONFIG_MTD_PHYSMAP_LEN != 0
173#warning using PHYSMAP compat code
174#define PHYSMAP_COMPAT
175#endif
90#endif 176#endif
91 add_mtd_device(mymtd);
92 177
93 return 0; 178#ifdef PHYSMAP_COMPAT
94 } 179static struct physmap_flash_data physmap_flash_data = {
180 .width = CONFIG_MTD_PHYSMAP_BANKWIDTH,
181};
95 182
96 iounmap(physmap_map.virt); 183static struct resource physmap_flash_resource = {
97 return -ENXIO; 184 .start = CONFIG_MTD_PHYSMAP_START,
98} 185 .end = CONFIG_MTD_PHYSMAP_START + CONFIG_MTD_PHYSMAP_LEN,
186 .flags = IORESOURCE_MEM,
187};
99 188
100static void __exit cleanup_physmap(void) 189static struct platform_device physmap_flash = {
190 .name = "physmap-flash",
191 .id = 0,
192 .dev = {
193 .platform_data = &physmap_flash_data,
194 },
195 .num_resources = 1,
196 .resource = &physmap_flash_resource,
197};
198
199void physmap_configure(unsigned long addr, unsigned long size,
200 int bankwidth, void (*set_vpp)(struct map_info *, int))
101{ 201{
202 physmap_flash_resource.start = addr;
203 physmap_flash_resource.end = addr + size - 1;
204 physmap_flash_data.width = bankwidth;
205 physmap_flash_data.set_vpp = set_vpp;
206}
207
102#ifdef CONFIG_MTD_PARTITIONS 208#ifdef CONFIG_MTD_PARTITIONS
103 if (mtd_parts_nb) { 209void physmap_set_partitions(struct mtd_partition *parts, int num_parts)
104 del_mtd_partitions(mymtd); 210{
105 kfree(mtd_parts); 211 physmap_flash_data.nr_parts = num_parts;
106 } else if (num_physmap_partitions) { 212 physmap_flash_data.parts = parts;
107 del_mtd_partitions(mymtd); 213}
108 } else { 214#endif
109 del_mtd_device(mymtd);
110 }
111#else
112 del_mtd_device(mymtd);
113#endif 215#endif
114 map_destroy(mymtd);
115 216
116 iounmap(physmap_map.virt); 217static int __init physmap_init(void)
117 physmap_map.virt = NULL; 218{
219 int err;
220
221 err = platform_driver_register(&physmap_flash_driver);
222#ifdef PHYSMAP_COMPAT
223 if (err == 0)
224 platform_device_register(&physmap_flash);
225#endif
226
227 return err;
118} 228}
119 229
120module_init(init_physmap); 230static void __exit physmap_exit(void)
121module_exit(cleanup_physmap); 231{
232#ifdef PHYSMAP_COMPAT
233 platform_device_unregister(&physmap_flash);
234#endif
235 platform_driver_unregister(&physmap_flash_driver);
236}
122 237
238module_init(physmap_init);
239module_exit(physmap_exit);
123 240
124MODULE_LICENSE("GPL"); 241MODULE_LICENSE("GPL");
125MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 242MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c
index 0758cb1d0105..24a03152d196 100644
--- a/drivers/mtd/maps/sun_uflash.c
+++ b/drivers/mtd/maps/sun_uflash.c
@@ -18,6 +18,7 @@
18#include <linux/ioport.h> 18#include <linux/ioport.h>
19#include <asm/ebus.h> 19#include <asm/ebus.h>
20#include <asm/oplib.h> 20#include <asm/oplib.h>
21#include <asm/prom.h>
21#include <asm/uaccess.h> 22#include <asm/uaccess.h>
22#include <asm/io.h> 23#include <asm/io.h>
23 24
@@ -30,146 +31,140 @@
30#define UFLASH_WINDOW_SIZE 0x200000 31#define UFLASH_WINDOW_SIZE 0x200000
31#define UFLASH_BUSWIDTH 1 /* EBus is 8-bit */ 32#define UFLASH_BUSWIDTH 1 /* EBus is 8-bit */
32 33
33MODULE_AUTHOR 34MODULE_AUTHOR("Eric Brower <ebrower@usa.net>");
34 ("Eric Brower <ebrower@usa.net>"); 35MODULE_DESCRIPTION("User-programmable flash device on Sun Microsystems boardsets");
35MODULE_DESCRIPTION 36MODULE_SUPPORTED_DEVICE("userflash");
36 ("User-programmable flash device on Sun Microsystems boardsets"); 37MODULE_LICENSE("GPL");
37MODULE_SUPPORTED_DEVICE 38MODULE_VERSION("2.0");
38 ("userflash");
39MODULE_LICENSE
40 ("GPL");
41 39
42static LIST_HEAD(device_list); 40static LIST_HEAD(device_list);
43struct uflash_dev { 41struct uflash_dev {
44 char * name; /* device name */ 42 char *name; /* device name */
45 struct map_info map; /* mtd map info */ 43 struct map_info map; /* mtd map info */
46 struct mtd_info * mtd; /* mtd info */ 44 struct mtd_info *mtd; /* mtd info */
47 struct list_head list;
48}; 45};
49 46
50 47
51struct map_info uflash_map_templ = { 48struct map_info uflash_map_templ = {
52 .name = "SUNW,???-????", 49 .name = "SUNW,???-????",
53 .size = UFLASH_WINDOW_SIZE, 50 .size = UFLASH_WINDOW_SIZE,
54 .bankwidth = UFLASH_BUSWIDTH, 51 .bankwidth = UFLASH_BUSWIDTH,
55}; 52};
56 53
57int uflash_devinit(struct linux_ebus_device* edev) 54int uflash_devinit(struct linux_ebus_device *edev, struct device_node *dp)
58{ 55{
59 int iTmp, nregs; 56 struct uflash_dev *up;
60 struct linux_prom_registers regs[2]; 57 struct resource *res;
61 struct uflash_dev *pdev;
62
63 iTmp = prom_getproperty(
64 edev->prom_node, "reg", (void *)regs, sizeof(regs));
65 if ((iTmp % sizeof(regs[0])) != 0) {
66 printk("%s: Strange reg property size %d\n",
67 UFLASH_DEVNAME, iTmp);
68 return -ENODEV;
69 }
70 58
71 nregs = iTmp / sizeof(regs[0]); 59 res = &edev->resource[0];
72 60
73 if (nregs != 1) { 61 if (edev->num_addrs != 1) {
74 /* Non-CFI userflash device-- once I find one we 62 /* Non-CFI userflash device-- once I find one we
75 * can work on supporting it. 63 * can work on supporting it.
76 */ 64 */
77 printk("%s: unsupported device at 0x%lx (%d regs): " \ 65 printk("%s: unsupported device at 0x%lx (%d regs): " \
78 "email ebrower@usa.net\n", 66 "email ebrower@usa.net\n",
79 UFLASH_DEVNAME, edev->resource[0].start, nregs); 67 dp->full_name, res->start, edev->num_addrs);
68
80 return -ENODEV; 69 return -ENODEV;
81 } 70 }
82 71
83 if(0 == (pdev = kmalloc(sizeof(struct uflash_dev), GFP_KERNEL))) { 72 up = kzalloc(sizeof(struct uflash_dev), GFP_KERNEL);
84 printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME); 73 if (!up)
85 return(-ENOMEM); 74 return -ENOMEM;
86 }
87 75
88 /* copy defaults and tweak parameters */ 76 /* copy defaults and tweak parameters */
89 memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ)); 77 memcpy(&up->map, &uflash_map_templ, sizeof(uflash_map_templ));
90 pdev->map.size = regs[0].reg_size; 78 up->map.size = (res->end - res->start) + 1UL;
91 79
92 iTmp = prom_getproplen(edev->prom_node, "model"); 80 up->name = of_get_property(dp, "model", NULL);
93 pdev->name = kmalloc(iTmp, GFP_KERNEL); 81 if (up->name && 0 < strlen(up->name))
94 prom_getstring(edev->prom_node, "model", pdev->name, iTmp); 82 up->map.name = up->name;
95 if(0 != pdev->name && 0 < strlen(pdev->name)) { 83
96 pdev->map.name = pdev->name; 84 up->map.phys = res->start;
97 } 85
98 pdev->map.phys = edev->resource[0].start; 86 up->map.virt = ioremap_nocache(res->start, up->map.size);
99 pdev->map.virt = ioremap_nocache(edev->resource[0].start, pdev->map.size); 87 if (!up->map.virt) {
100 if(0 == pdev->map.virt) { 88 printk("%s: Failed to map device.\n", dp->full_name);
101 printk("%s: failed to map device\n", __FUNCTION__); 89 kfree(up);
102 kfree(pdev->name); 90
103 kfree(pdev); 91 return -EINVAL;
104 return(-1);
105 } 92 }
106 93
107 simple_map_init(&pdev->map); 94 simple_map_init(&up->map);
108 95
109 /* MTD registration */ 96 /* MTD registration */
110 pdev->mtd = do_map_probe("cfi_probe", &pdev->map); 97 up->mtd = do_map_probe("cfi_probe", &up->map);
111 if(0 == pdev->mtd) { 98 if (!up->mtd) {
112 iounmap(pdev->map.virt); 99 iounmap(up->map.virt);
113 kfree(pdev->name); 100 kfree(up);
114 kfree(pdev); 101
115 return(-ENXIO); 102 return -ENXIO;
116 } 103 }
117 104
118 list_add(&pdev->list, &device_list); 105 up->mtd->owner = THIS_MODULE;
119 106
120 pdev->mtd->owner = THIS_MODULE; 107 add_mtd_device(up->mtd);
121 108
122 add_mtd_device(pdev->mtd); 109 dev_set_drvdata(&edev->ofdev.dev, up);
123 return(0); 110
111 return 0;
124} 112}
125 113
126static int __init uflash_init(void) 114static int __devinit uflash_probe(struct of_device *dev, const struct of_device_id *match)
127{ 115{
128 struct linux_ebus *ebus = NULL; 116 struct linux_ebus_device *edev = to_ebus_device(&dev->dev);
129 struct linux_ebus_device *edev = NULL; 117 struct device_node *dp = dev->node;
130
131 for_each_ebus(ebus) {
132 for_each_ebusdev(edev, ebus) {
133 if (!strcmp(edev->prom_name, UFLASH_OBPNAME)) {
134 if(0 > prom_getproplen(edev->prom_node, "user")) {
135 DEBUG(2, "%s: ignoring device at 0x%lx\n",
136 UFLASH_DEVNAME, edev->resource[0].start);
137 } else {
138 uflash_devinit(edev);
139 }
140 }
141 }
142 }
143 118
144 if(list_empty(&device_list)) { 119 if (of_find_property(dp, "user", NULL))
145 printk("%s: unable to locate device\n", UFLASH_DEVNAME);
146 return -ENODEV; 120 return -ENODEV;
147 } 121
148 return(0); 122 return uflash_devinit(edev, dp);
149} 123}
150 124
151static void __exit uflash_cleanup(void) 125static int __devexit uflash_remove(struct of_device *dev)
152{ 126{
153 struct list_head *udevlist; 127 struct uflash_dev *up = dev_get_drvdata(&dev->dev);
154 struct uflash_dev *udev; 128
155 129 if (up->mtd) {
156 list_for_each(udevlist, &device_list) { 130 del_mtd_device(up->mtd);
157 udev = list_entry(udevlist, struct uflash_dev, list); 131 map_destroy(up->mtd);
158 DEBUG(2, "%s: removing device %s\n",
159 UFLASH_DEVNAME, udev->name);
160
161 if(0 != udev->mtd) {
162 del_mtd_device(udev->mtd);
163 map_destroy(udev->mtd);
164 }
165 if(0 != udev->map.virt) {
166 iounmap(udev->map.virt);
167 udev->map.virt = NULL;
168 }
169 kfree(udev->name);
170 kfree(udev);
171 } 132 }
133 if (up->map.virt) {
134 iounmap(up->map.virt);
135 up->map.virt = NULL;
136 }
137
138 kfree(up);
139
140 return 0;
141}
142
143static struct of_device_id uflash_match[] = {
144 {
145 .name = UFLASH_OBPNAME,
146 },
147 {},
148};
149
150MODULE_DEVICE_TABLE(of, uflash_match);
151
152static struct of_platform_driver uflash_driver = {
153 .name = UFLASH_DEVNAME,
154 .match_table = uflash_match,
155 .probe = uflash_probe,
156 .remove = __devexit_p(uflash_remove),
157};
158
159static int __init uflash_init(void)
160{
161 return of_register_driver(&uflash_driver, &ebus_bus_type);
162}
163
164static void __exit uflash_exit(void)
165{
166 of_unregister_driver(&uflash_driver);
172} 167}
173 168
174module_init(uflash_init); 169module_init(uflash_init);
175module_exit(uflash_cleanup); 170module_exit(uflash_exit);