diff options
Diffstat (limited to 'drivers/mtd/maps/ixp4xx.c')
-rw-r--r-- | drivers/mtd/maps/ixp4xx.c | 56 |
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 @@ | |||
45 | static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs) | 45 | static 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 | */ |
79 | static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr) | 79 | static 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 | */ |
88 | static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr) | 88 | static 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 | ||
93 | struct ixp4xx_flash_info { | 93 | struct 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); | |||
259 | MODULE_LICENSE("GPL"); | 242 | MODULE_LICENSE("GPL"); |
260 | MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems"); | 243 | MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems"); |
261 | MODULE_AUTHOR("Deepak Saxena"); | 244 | MODULE_AUTHOR("Deepak Saxena"); |
262 | |||