aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/maps/ixp4xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/maps/ixp4xx.c')
-rw-r--r--drivers/mtd/maps/ixp4xx.c56
1 files changed, 19 insertions, 37 deletions
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index 733a9297a562..56b3a355bf7b 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ixp4xx.c,v 1.7 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: ixp4xx.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/ixp4xx.c 4 * drivers/mtd/maps/ixp4xx.c
5 * 5 *
@@ -45,7 +45,7 @@
45static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs) 45static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs)
46{ 46{
47 map_word val; 47 map_word val;
48 val.x[0] = *(__u16 *) (map->map_priv_1 + ofs); 48 val.x[0] = le16_to_cpu(readw(map->virt + ofs));
49 return val; 49 return val;
50} 50}
51 51
@@ -59,35 +59,35 @@ static void ixp4xx_copy_from(struct map_info *map, void *to,
59{ 59{
60 int i; 60 int i;
61 u8 *dest = (u8 *) to; 61 u8 *dest = (u8 *) to;
62 u16 *src = (u16 *) (map->map_priv_1 + from); 62 void __iomem *src = map->virt + from;
63 u16 data; 63 u16 data;
64 64
65 for (i = 0; i < (len / 2); i++) { 65 for (i = 0; i < (len / 2); i++) {
66 data = src[i]; 66 data = le16_to_cpu(readw(src + 2*i));
67 dest[i * 2] = BYTE0(data); 67 dest[i * 2] = BYTE0(data);
68 dest[i * 2 + 1] = BYTE1(data); 68 dest[i * 2 + 1] = BYTE1(data);
69 } 69 }
70 70
71 if (len & 1) 71 if (len & 1)
72 dest[len - 1] = BYTE0(src[i]); 72 dest[len - 1] = BYTE0(le16_to_cpu(readw(src + 2*i)));
73} 73}
74 74
75/* 75/*
76 * Unaligned writes are ignored, causing the 8-bit 76 * Unaligned writes are ignored, causing the 8-bit
77 * probe to fail and proceed to the 16-bit probe (which succeeds). 77 * probe to fail and proceed to the 16-bit probe (which succeeds).
78 */ 78 */
79static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr) 79static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr)
80{ 80{
81 if (!(adr & 1)) 81 if (!(adr & 1))
82 *(__u16 *) (map->map_priv_1 + adr) = d.x[0]; 82 writew(cpu_to_le16(d.x[0]), map->virt + adr);
83} 83}
84 84
85/* 85/*
86 * Fast write16 function without the probing check above 86 * Fast write16 function without the probing check above
87 */ 87 */
88static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr) 88static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
89{ 89{
90 *(__u16 *) (map->map_priv_1 + adr) = d.x[0]; 90 writew(cpu_to_le16(d.x[0]), map->virt + adr);
91} 91}
92 92
93struct ixp4xx_flash_info { 93struct ixp4xx_flash_info {
@@ -104,28 +104,20 @@ static int ixp4xx_flash_remove(struct device *_dev)
104 struct platform_device *dev = to_platform_device(_dev); 104 struct platform_device *dev = to_platform_device(_dev);
105 struct flash_platform_data *plat = dev->dev.platform_data; 105 struct flash_platform_data *plat = dev->dev.platform_data;
106 struct ixp4xx_flash_info *info = dev_get_drvdata(&dev->dev); 106 struct ixp4xx_flash_info *info = dev_get_drvdata(&dev->dev);
107 map_word d;
108 107
109 dev_set_drvdata(&dev->dev, NULL); 108 dev_set_drvdata(&dev->dev, NULL);
110 109
111 if(!info) 110 if(!info)
112 return 0; 111 return 0;
113 112
114 /*
115 * This is required for a soft reboot to work.
116 */
117 d.x[0] = 0xff;
118 ixp4xx_write16(&info->map, d, 0x55 * 0x2);
119
120 if (info->mtd) { 113 if (info->mtd) {
121 del_mtd_partitions(info->mtd); 114 del_mtd_partitions(info->mtd);
122 map_destroy(info->mtd); 115 map_destroy(info->mtd);
123 } 116 }
124 if (info->map.map_priv_1) 117 if (info->map.virt)
125 iounmap((void *) info->map.map_priv_1); 118 iounmap(info->map.virt);
126 119
127 if (info->partitions) 120 kfree(info->partitions);
128 kfree(info->partitions);
129 121
130 if (info->res) { 122 if (info->res) {
131 release_resource(info->res); 123 release_resource(info->res);
@@ -135,9 +127,6 @@ static int ixp4xx_flash_remove(struct device *_dev)
135 if (plat->exit) 127 if (plat->exit)
136 plat->exit(); 128 plat->exit();
137 129
138 /* Disable flash write */
139 *IXP4XX_EXP_CS0 &= ~IXP4XX_FLASH_WRITABLE;
140
141 return 0; 130 return 0;
142} 131}
143 132
@@ -161,17 +150,11 @@ static int ixp4xx_flash_probe(struct device *_dev)
161 if(!info) { 150 if(!info) {
162 err = -ENOMEM; 151 err = -ENOMEM;
163 goto Error; 152 goto Error;
164 } 153 }
165 memzero(info, sizeof(struct ixp4xx_flash_info)); 154 memzero(info, sizeof(struct ixp4xx_flash_info));
166 155
167 dev_set_drvdata(&dev->dev, info); 156 dev_set_drvdata(&dev->dev, info);
168 157
169 /*
170 * Enable flash write
171 * TODO: Move this out to board specific code
172 */
173 *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
174
175 /* 158 /*
176 * Tell the MTD layer we're not 1:1 mapped so that it does 159 * Tell the MTD layer we're not 1:1 mapped so that it does
177 * not attempt to do a direct access on us. 160 * not attempt to do a direct access on us.
@@ -190,8 +173,8 @@ static int ixp4xx_flash_probe(struct device *_dev)
190 info->map.write = ixp4xx_probe_write16, 173 info->map.write = ixp4xx_probe_write16,
191 info->map.copy_from = ixp4xx_copy_from, 174 info->map.copy_from = ixp4xx_copy_from,
192 175
193 info->res = request_mem_region(dev->resource->start, 176 info->res = request_mem_region(dev->resource->start,
194 dev->resource->end - dev->resource->start + 1, 177 dev->resource->end - dev->resource->start + 1,
195 "IXP4XXFlash"); 178 "IXP4XXFlash");
196 if (!info->res) { 179 if (!info->res) {
197 printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n"); 180 printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n");
@@ -199,9 +182,9 @@ static int ixp4xx_flash_probe(struct device *_dev)
199 goto Error; 182 goto Error;
200 } 183 }
201 184
202 info->map.map_priv_1 = ioremap(dev->resource->start, 185 info->map.virt = ioremap(dev->resource->start,
203 dev->resource->end - dev->resource->start + 1); 186 dev->resource->end - dev->resource->start + 1);
204 if (!info->map.map_priv_1) { 187 if (!info->map.virt) {
205 printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n"); 188 printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n");
206 err = -EIO; 189 err = -EIO;
207 goto Error; 190 goto Error;
@@ -214,7 +197,7 @@ static int ixp4xx_flash_probe(struct device *_dev)
214 goto Error; 197 goto Error;
215 } 198 }
216 info->mtd->owner = THIS_MODULE; 199 info->mtd->owner = THIS_MODULE;
217 200
218 /* Use the fast version */ 201 /* Use the fast version */
219 info->map.write = ixp4xx_write16, 202 info->map.write = ixp4xx_write16,
220 203
@@ -259,4 +242,3 @@ module_exit(ixp4xx_flash_exit);
259MODULE_LICENSE("GPL"); 242MODULE_LICENSE("GPL");
260MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems"); 243MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems");
261MODULE_AUTHOR("Deepak Saxena"); 244MODULE_AUTHOR("Deepak Saxena");
262