]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/mtd/maps/integrator-flash.c
MTD/JFFS2: remove CVS keywords
[mirror_ubuntu-artful-kernel.git] / drivers / mtd / maps / integrator-flash.c
CommitLineData
1da177e4
LT
1/*======================================================================
2
3 drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver
69f34c98 4
1da177e4
LT
5 Copyright (C) 2000 ARM Limited
6 Copyright (C) 2003 Deep Blue Solutions Ltd.
69f34c98 7
1da177e4
LT
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
69f34c98 12
1da177e4
LT
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
69f34c98 17
1da177e4
LT
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
69f34c98
TG
21
22 This is access code for flashes using ARM's flash partitioning
1da177e4
LT
23 standards.
24
1da177e4
LT
25======================================================================*/
26
1da177e4
LT
27#include <linux/module.h>
28#include <linux/types.h>
29#include <linux/kernel.h>
30#include <linux/slab.h>
31#include <linux/ioport.h>
d052d1be 32#include <linux/platform_device.h>
1da177e4
LT
33#include <linux/init.h>
34
35#include <linux/mtd/mtd.h>
36#include <linux/mtd/map.h>
37#include <linux/mtd/partitions.h>
38
39#include <asm/mach/flash.h>
40#include <asm/hardware.h>
41#include <asm/io.h>
42#include <asm/system.h>
43
44#ifdef CONFIG_ARCH_P720T
45#define FLASH_BASE (0x04000000)
46#define FLASH_SIZE (64*1024*1024)
47#endif
48
49struct armflash_info {
50 struct flash_platform_data *plat;
51 struct resource *res;
52 struct mtd_partition *parts;
53 struct mtd_info *mtd;
54 struct map_info map;
55};
56
57static void armflash_set_vpp(struct map_info *map, int on)
58{
59 struct armflash_info *info = container_of(map, struct armflash_info, map);
60
61 if (info->plat && info->plat->set_vpp)
62 info->plat->set_vpp(on);
63}
64
65static const char *probes[] = { "cmdlinepart", "RedBoot", "afs", NULL };
66
3ae5eaec 67static int armflash_probe(struct platform_device *dev)
1da177e4 68{
1da177e4
LT
69 struct flash_platform_data *plat = dev->dev.platform_data;
70 struct resource *res = dev->resource;
71 unsigned int size = res->end - res->start + 1;
72 struct armflash_info *info;
73 int err;
74 void __iomem *base;
75
95b93a0c 76 info = kzalloc(sizeof(struct armflash_info), GFP_KERNEL);
1da177e4
LT
77 if (!info) {
78 err = -ENOMEM;
79 goto out;
80 }
81
1da177e4
LT
82 info->plat = plat;
83 if (plat && plat->init) {
84 err = plat->init();
85 if (err)
86 goto no_resource;
87 }
88
89 info->res = request_mem_region(res->start, size, "armflash");
90 if (!info->res) {
91 err = -EBUSY;
92 goto no_resource;
93 }
94
95 base = ioremap(res->start, size);
96 if (!base) {
97 err = -ENOMEM;
98 goto no_mem;
99 }
100
101 /*
102 * look for CFI based flash parts fitted to this board
103 */
104 info->map.size = size;
105 info->map.bankwidth = plat->width;
106 info->map.phys = res->start;
107 info->map.virt = base;
108 info->map.name = dev->dev.bus_id;
109 info->map.set_vpp = armflash_set_vpp;
110
111 simple_map_init(&info->map);
112
113 /*
114 * Also, the CFI layer automatically works out what size
115 * of chips we have, and does the necessary identification
116 * for us automatically.
117 */
118 info->mtd = do_map_probe(plat->map_name, &info->map);
119 if (!info->mtd) {
120 err = -ENXIO;
121 goto no_device;
122 }
123
124 info->mtd->owner = THIS_MODULE;
125
126 err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0);
127 if (err > 0) {
128 err = add_mtd_partitions(info->mtd, info->parts, err);
129 if (err)
130 printk(KERN_ERR
131 "mtd partition registration failed: %d\n", err);
132 }
133
134 if (err == 0)
3ae5eaec 135 platform_set_drvdata(dev, info);
1da177e4
LT
136
137 /*
138 * If we got an error, free all resources.
139 */
140 if (err < 0) {
141 if (info->mtd) {
142 del_mtd_partitions(info->mtd);
143 map_destroy(info->mtd);
144 }
fa671646 145 kfree(info->parts);
1da177e4
LT
146
147 no_device:
148 iounmap(base);
149 no_mem:
150 release_mem_region(res->start, size);
151 no_resource:
152 if (plat && plat->exit)
153 plat->exit();
154 kfree(info);
155 }
156 out:
157 return err;
158}
159
3ae5eaec 160static int armflash_remove(struct platform_device *dev)
1da177e4 161{
3ae5eaec 162 struct armflash_info *info = platform_get_drvdata(dev);
1da177e4 163
3ae5eaec 164 platform_set_drvdata(dev, NULL);
1da177e4
LT
165
166 if (info) {
167 if (info->mtd) {
168 del_mtd_partitions(info->mtd);
169 map_destroy(info->mtd);
170 }
fa671646 171 kfree(info->parts);
1da177e4
LT
172
173 iounmap(info->map.virt);
174 release_resource(info->res);
175 kfree(info->res);
176
177 if (info->plat && info->plat->exit)
178 info->plat->exit();
179
180 kfree(info);
181 }
182
183 return 0;
184}
185
3ae5eaec 186static struct platform_driver armflash_driver = {
1da177e4
LT
187 .probe = armflash_probe,
188 .remove = armflash_remove,
3ae5eaec
RK
189 .driver = {
190 .name = "armflash",
41d867c9 191 .owner = THIS_MODULE,
3ae5eaec 192 },
1da177e4
LT
193};
194
195static int __init armflash_init(void)
196{
3ae5eaec 197 return platform_driver_register(&armflash_driver);
1da177e4
LT
198}
199
200static void __exit armflash_exit(void)
201{
3ae5eaec 202 platform_driver_unregister(&armflash_driver);
1da177e4
LT
203}
204
205module_init(armflash_init);
206module_exit(armflash_exit);
207
208MODULE_AUTHOR("ARM Ltd");
209MODULE_DESCRIPTION("ARM Integrator CFI map driver");
210MODULE_LICENSE("GPL");
41d867c9 211MODULE_ALIAS("platform:armflash");