diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2009-03-04 15:01:34 -0500 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-03-20 14:11:20 -0400 |
commit | 610f75e74b636f933bc3e379a88a10f883b91332 (patch) | |
tree | 16255acdf1aaf3cf3a02363abe24cd872152ac8e | |
parent | 64fb65baffa5b8f6f2eb3f628dec43c22cd1031f (diff) |
[MTD] RBTX4939 map driver
This is a map driver for NOR flash chips on RBTX4939 board.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Cc: Ralf Bächle <ralf@linux-mips.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r-- | drivers/mtd/maps/Kconfig | 6 | ||||
-rw-r--r-- | drivers/mtd/maps/Makefile | 1 | ||||
-rw-r--r-- | drivers/mtd/maps/rbtx4939-flash.c | 208 |
3 files changed, 215 insertions, 0 deletions
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 043d50fb6ef6..a0da8e243cc4 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -542,6 +542,12 @@ config MTD_INTEL_VR_NOR | |||
542 | Map driver for a NOR flash bank located on the Expansion Bus of the | 542 | Map driver for a NOR flash bank located on the Expansion Bus of the |
543 | Intel Vermilion Range chipset. | 543 | Intel Vermilion Range chipset. |
544 | 544 | ||
545 | config MTD_RBTX4939 | ||
546 | tristate "Map driver for RBTX4939 board" | ||
547 | depends on TOSHIBA_RBTX4939 && MTD_CFI && MTD_COMPLEX_MAPPINGS | ||
548 | help | ||
549 | Map driver for NOR flash chips on RBTX4939 board. | ||
550 | |||
545 | config MTD_PLATRAM | 551 | config MTD_PLATRAM |
546 | tristate "Map driver for platform device RAM (mtd-ram)" | 552 | tristate "Map driver for platform device RAM (mtd-ram)" |
547 | select MTD_RAM | 553 | select MTD_RAM |
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 6d9ba35caf11..f53a7dc4a4fb 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile | |||
@@ -61,3 +61,4 @@ obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o | |||
61 | obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o | 61 | obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o |
62 | obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o | 62 | obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o |
63 | obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o | 63 | obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o |
64 | obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o | ||
diff --git a/drivers/mtd/maps/rbtx4939-flash.c b/drivers/mtd/maps/rbtx4939-flash.c new file mode 100644 index 000000000000..d39f0adac846 --- /dev/null +++ b/drivers/mtd/maps/rbtx4939-flash.c | |||
@@ -0,0 +1,208 @@ | |||
1 | /* | ||
2 | * rbtx4939-flash (based on physmap.c) | ||
3 | * | ||
4 | * This is a simplified physmap driver with map_init callback function. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * Copyright (C) 2009 Atsushi Nemoto <anemo@mba.ocn.ne.jp> | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/device.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/mtd/mtd.h> | ||
21 | #include <linux/mtd/map.h> | ||
22 | #include <linux/mtd/partitions.h> | ||
23 | #include <asm/txx9/rbtx4939.h> | ||
24 | |||
25 | struct rbtx4939_flash_info { | ||
26 | struct mtd_info *mtd; | ||
27 | struct map_info map; | ||
28 | #ifdef CONFIG_MTD_PARTITIONS | ||
29 | int nr_parts; | ||
30 | struct mtd_partition *parts; | ||
31 | #endif | ||
32 | }; | ||
33 | |||
34 | static int rbtx4939_flash_remove(struct platform_device *dev) | ||
35 | { | ||
36 | struct rbtx4939_flash_info *info; | ||
37 | |||
38 | info = platform_get_drvdata(dev); | ||
39 | if (!info) | ||
40 | return 0; | ||
41 | platform_set_drvdata(dev, NULL); | ||
42 | |||
43 | if (info->mtd) { | ||
44 | #ifdef CONFIG_MTD_PARTITIONS | ||
45 | struct rbtx4939_flash_data *pdata = dev->dev.platform_data; | ||
46 | |||
47 | if (info->nr_parts) { | ||
48 | del_mtd_partitions(info->mtd); | ||
49 | kfree(info->parts); | ||
50 | } else if (pdata->nr_parts) | ||
51 | del_mtd_partitions(info->mtd); | ||
52 | else | ||
53 | del_mtd_device(info->mtd); | ||
54 | #else | ||
55 | del_mtd_device(info->mtd); | ||
56 | #endif | ||
57 | map_destroy(info->mtd); | ||
58 | } | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; | ||
63 | #ifdef CONFIG_MTD_PARTITIONS | ||
64 | static const char *part_probe_types[] = { "cmdlinepart", NULL }; | ||
65 | #endif | ||
66 | |||
67 | static int rbtx4939_flash_probe(struct platform_device *dev) | ||
68 | { | ||
69 | struct rbtx4939_flash_data *pdata; | ||
70 | struct rbtx4939_flash_info *info; | ||
71 | struct resource *res; | ||
72 | const char **probe_type; | ||
73 | int err = 0; | ||
74 | unsigned long size; | ||
75 | |||
76 | pdata = dev->dev.platform_data; | ||
77 | if (!pdata) | ||
78 | return -ENODEV; | ||
79 | |||
80 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
81 | if (!res) | ||
82 | return -ENODEV; | ||
83 | info = devm_kzalloc(&dev->dev, sizeof(struct rbtx4939_flash_info), | ||
84 | GFP_KERNEL); | ||
85 | if (!info) | ||
86 | return -ENOMEM; | ||
87 | |||
88 | platform_set_drvdata(dev, info); | ||
89 | |||
90 | size = resource_size(res); | ||
91 | pr_notice("rbtx4939 platform flash device: %pR\n", res); | ||
92 | |||
93 | if (!devm_request_mem_region(&dev->dev, res->start, size, | ||
94 | dev_name(&dev->dev))) | ||
95 | return -EBUSY; | ||
96 | |||
97 | info->map.name = dev_name(&dev->dev); | ||
98 | info->map.phys = res->start; | ||
99 | info->map.size = size; | ||
100 | info->map.bankwidth = pdata->width; | ||
101 | |||
102 | info->map.virt = devm_ioremap(&dev->dev, info->map.phys, size); | ||
103 | if (!info->map.virt) | ||
104 | return -EBUSY; | ||
105 | |||
106 | if (pdata->map_init) | ||
107 | (*pdata->map_init)(&info->map); | ||
108 | else | ||
109 | simple_map_init(&info->map); | ||
110 | |||
111 | probe_type = rom_probe_types; | ||
112 | for (; !info->mtd && *probe_type; probe_type++) | ||
113 | info->mtd = do_map_probe(*probe_type, &info->map); | ||
114 | if (!info->mtd) { | ||
115 | dev_err(&dev->dev, "map_probe failed\n"); | ||
116 | err = -ENXIO; | ||
117 | goto err_out; | ||
118 | } | ||
119 | info->mtd->owner = THIS_MODULE; | ||
120 | if (err) | ||
121 | goto err_out; | ||
122 | |||
123 | #ifdef CONFIG_MTD_PARTITIONS | ||
124 | err = parse_mtd_partitions(info->mtd, part_probe_types, | ||
125 | &info->parts, 0); | ||
126 | if (err > 0) { | ||
127 | add_mtd_partitions(info->mtd, info->parts, err); | ||
128 | info->nr_parts = err; | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | if (pdata->nr_parts) { | ||
133 | pr_notice("Using rbtx4939 partition information\n"); | ||
134 | add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); | ||
135 | return 0; | ||
136 | } | ||
137 | #endif | ||
138 | |||
139 | add_mtd_device(info->mtd); | ||
140 | return 0; | ||
141 | |||
142 | err_out: | ||
143 | rbtx4939_flash_remove(dev); | ||
144 | return err; | ||
145 | } | ||
146 | |||
147 | #ifdef CONFIG_PM | ||
148 | static int rbtx4939_flash_suspend(struct platform_device *dev, | ||
149 | pm_message_t state) | ||
150 | { | ||
151 | struct rbtx4939_flash_info *info = platform_get_drvdata(dev); | ||
152 | |||
153 | if (info->mtd->suspend) | ||
154 | return info->mtd->suspend(info->mtd); | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int rbtx4939_flash_resume(struct platform_device *dev) | ||
159 | { | ||
160 | struct rbtx4939_flash_info *info = platform_get_drvdata(dev); | ||
161 | |||
162 | if (info->mtd->resume) | ||
163 | info->mtd->resume(info->mtd); | ||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | static void rbtx4939_flash_shutdown(struct platform_device *dev) | ||
168 | { | ||
169 | struct rbtx4939_flash_info *info = platform_get_drvdata(dev); | ||
170 | |||
171 | if (info->mtd->suspend && info->mtd->resume) | ||
172 | if (info->mtd->suspend(info->mtd) == 0) | ||
173 | info->mtd->resume(info->mtd); | ||
174 | } | ||
175 | #else | ||
176 | #define rbtx4939_flash_suspend NULL | ||
177 | #define rbtx4939_flash_resume NULL | ||
178 | #define rbtx4939_flash_shutdown NULL | ||
179 | #endif | ||
180 | |||
181 | static struct platform_driver rbtx4939_flash_driver = { | ||
182 | .probe = rbtx4939_flash_probe, | ||
183 | .remove = rbtx4939_flash_remove, | ||
184 | .suspend = rbtx4939_flash_suspend, | ||
185 | .resume = rbtx4939_flash_resume, | ||
186 | .shutdown = rbtx4939_flash_shutdown, | ||
187 | .driver = { | ||
188 | .name = "rbtx4939-flash", | ||
189 | .owner = THIS_MODULE, | ||
190 | }, | ||
191 | }; | ||
192 | |||
193 | static int __init rbtx4939_flash_init(void) | ||
194 | { | ||
195 | return platform_driver_register(&rbtx4939_flash_driver); | ||
196 | } | ||
197 | |||
198 | static void __exit rbtx4939_flash_exit(void) | ||
199 | { | ||
200 | platform_driver_unregister(&rbtx4939_flash_driver); | ||
201 | } | ||
202 | |||
203 | module_init(rbtx4939_flash_init); | ||
204 | module_exit(rbtx4939_flash_exit); | ||
205 | |||
206 | MODULE_LICENSE("GPL"); | ||
207 | MODULE_DESCRIPTION("RBTX4939 MTD map driver"); | ||
208 | MODULE_ALIAS("platform:rbtx4939-flash"); | ||