aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/maps/lantiq-flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/maps/lantiq-flash.c')
-rw-r--r--drivers/mtd/maps/lantiq-flash.c76
1 files changed, 32 insertions, 44 deletions
diff --git a/drivers/mtd/maps/lantiq-flash.c b/drivers/mtd/maps/lantiq-flash.c
index b5401e355745..c03456f17004 100644
--- a/drivers/mtd/maps/lantiq-flash.c
+++ b/drivers/mtd/maps/lantiq-flash.c
@@ -19,9 +19,9 @@
19#include <linux/mtd/cfi.h> 19#include <linux/mtd/cfi.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/mtd/physmap.h> 21#include <linux/mtd/physmap.h>
22#include <linux/of.h>
22 23
23#include <lantiq_soc.h> 24#include <lantiq_soc.h>
24#include <lantiq_platform.h>
25 25
26/* 26/*
27 * The NOR flash is connected to the same external bus unit (EBU) as PCI. 27 * The NOR flash is connected to the same external bus unit (EBU) as PCI.
@@ -44,8 +44,9 @@ struct ltq_mtd {
44 struct map_info *map; 44 struct map_info *map;
45}; 45};
46 46
47static char ltq_map_name[] = "ltq_nor"; 47static const char ltq_map_name[] = "ltq_nor";
48static const char *ltq_probe_types[] __devinitconst = { "cmdlinepart", NULL }; 48static const char *ltq_probe_types[] __devinitconst = {
49 "cmdlinepart", "ofpart", NULL };
49 50
50static map_word 51static map_word
51ltq_read16(struct map_info *map, unsigned long adr) 52ltq_read16(struct map_info *map, unsigned long adr)
@@ -108,42 +109,38 @@ ltq_copy_to(struct map_info *map, unsigned long to,
108 spin_unlock_irqrestore(&ebu_lock, flags); 109 spin_unlock_irqrestore(&ebu_lock, flags);
109} 110}
110 111
111static int __init 112static int __devinit
112ltq_mtd_probe(struct platform_device *pdev) 113ltq_mtd_probe(struct platform_device *pdev)
113{ 114{
114 struct physmap_flash_data *ltq_mtd_data = dev_get_platdata(&pdev->dev); 115 struct mtd_part_parser_data ppdata;
115 struct ltq_mtd *ltq_mtd; 116 struct ltq_mtd *ltq_mtd;
116 struct resource *res;
117 struct cfi_private *cfi; 117 struct cfi_private *cfi;
118 int err; 118 int err;
119 119
120 if (of_machine_is_compatible("lantiq,falcon") &&
121 (ltq_boot_select() != BS_FLASH)) {
122 dev_err(&pdev->dev, "invalid bootstrap options\n");
123 return -ENODEV;
124 }
125
120 ltq_mtd = kzalloc(sizeof(struct ltq_mtd), GFP_KERNEL); 126 ltq_mtd = kzalloc(sizeof(struct ltq_mtd), GFP_KERNEL);
121 platform_set_drvdata(pdev, ltq_mtd); 127 platform_set_drvdata(pdev, ltq_mtd);
122 128
123 ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 129 ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
124 if (!ltq_mtd->res) { 130 if (!ltq_mtd->res) {
125 dev_err(&pdev->dev, "failed to get memory resource"); 131 dev_err(&pdev->dev, "failed to get memory resource\n");
126 err = -ENOENT; 132 err = -ENOENT;
127 goto err_out; 133 goto err_out;
128 } 134 }
129 135
130 res = devm_request_mem_region(&pdev->dev, ltq_mtd->res->start,
131 resource_size(ltq_mtd->res), dev_name(&pdev->dev));
132 if (!ltq_mtd->res) {
133 dev_err(&pdev->dev, "failed to request mem resource");
134 err = -EBUSY;
135 goto err_out;
136 }
137
138 ltq_mtd->map = kzalloc(sizeof(struct map_info), GFP_KERNEL); 136 ltq_mtd->map = kzalloc(sizeof(struct map_info), GFP_KERNEL);
139 ltq_mtd->map->phys = res->start; 137 ltq_mtd->map->phys = ltq_mtd->res->start;
140 ltq_mtd->map->size = resource_size(res); 138 ltq_mtd->map->size = resource_size(ltq_mtd->res);
141 ltq_mtd->map->virt = devm_ioremap_nocache(&pdev->dev, 139 ltq_mtd->map->virt = devm_request_and_ioremap(&pdev->dev, ltq_mtd->res);
142 ltq_mtd->map->phys, ltq_mtd->map->size);
143 if (!ltq_mtd->map->virt) { 140 if (!ltq_mtd->map->virt) {
144 dev_err(&pdev->dev, "failed to ioremap!\n"); 141 dev_err(&pdev->dev, "failed to remap mem resource\n");
145 err = -ENOMEM; 142 err = -EBUSY;
146 goto err_free; 143 goto err_out;
147 } 144 }
148 145
149 ltq_mtd->map->name = ltq_map_name; 146 ltq_mtd->map->name = ltq_map_name;
@@ -169,9 +166,9 @@ ltq_mtd_probe(struct platform_device *pdev)
169 cfi->addr_unlock1 ^= 1; 166 cfi->addr_unlock1 ^= 1;
170 cfi->addr_unlock2 ^= 1; 167 cfi->addr_unlock2 ^= 1;
171 168
172 err = mtd_device_parse_register(ltq_mtd->mtd, ltq_probe_types, NULL, 169 ppdata.of_node = pdev->dev.of_node;
173 ltq_mtd_data->parts, 170 err = mtd_device_parse_register(ltq_mtd->mtd, ltq_probe_types,
174 ltq_mtd_data->nr_parts); 171 &ppdata, NULL, 0);
175 if (err) { 172 if (err) {
176 dev_err(&pdev->dev, "failed to add partitions\n"); 173 dev_err(&pdev->dev, "failed to add partitions\n");
177 goto err_destroy; 174 goto err_destroy;
@@ -204,32 +201,23 @@ ltq_mtd_remove(struct platform_device *pdev)
204 return 0; 201 return 0;
205} 202}
206 203
204static const struct of_device_id ltq_mtd_match[] = {
205 { .compatible = "lantiq,nor" },
206 {},
207};
208MODULE_DEVICE_TABLE(of, ltq_mtd_match);
209
207static struct platform_driver ltq_mtd_driver = { 210static struct platform_driver ltq_mtd_driver = {
211 .probe = ltq_mtd_probe,
208 .remove = __devexit_p(ltq_mtd_remove), 212 .remove = __devexit_p(ltq_mtd_remove),
209 .driver = { 213 .driver = {
210 .name = "ltq_nor", 214 .name = "ltq-nor",
211 .owner = THIS_MODULE, 215 .owner = THIS_MODULE,
216 .of_match_table = ltq_mtd_match,
212 }, 217 },
213}; 218};
214 219
215static int __init 220module_platform_driver(ltq_mtd_driver);
216init_ltq_mtd(void)
217{
218 int ret = platform_driver_probe(&ltq_mtd_driver, ltq_mtd_probe);
219
220 if (ret)
221 pr_err("ltq_nor: error registering platform driver");
222 return ret;
223}
224
225static void __exit
226exit_ltq_mtd(void)
227{
228 platform_driver_unregister(&ltq_mtd_driver);
229}
230
231module_init(init_ltq_mtd);
232module_exit(exit_ltq_mtd);
233 221
234MODULE_LICENSE("GPL"); 222MODULE_LICENSE("GPL");
235MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); 223MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");