diff options
author | Andrew Victor <andrew@sanpeople.com> | 2006-11-06 08:56:07 -0500 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2006-12-04 20:12:03 -0500 |
commit | ebe5cfb3b9f0207ea1f4a0c24bf504deb19a37cc (patch) | |
tree | 934a5085479b5f412fb88e745a7a77cbbb1f52e7 /drivers | |
parent | af2b3b503ad1b071b66e1531caae252b4b95c847 (diff) |
[PATCH] pcmcia: at91_cf update
This is an update to the AT91RM9200 CompactFlash driver.
The changes include:
- Use the I/O memory address passed via the platform_device resources
instead of constant global values.
- The IRQ should not be used as a random'ness source.
- Return errors if ioremap() or request_mem_region() fails.
Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pcmcia/at91_cf.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index 3bcb7dc32995..a8fa6c17fcf1 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c | |||
@@ -32,10 +32,11 @@ | |||
32 | * A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW; | 32 | * A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW; |
33 | * some other bit in {A24,A22..A11} is nREG to flag memory access | 33 | * some other bit in {A24,A22..A11} is nREG to flag memory access |
34 | * (vs attributes). So more than 2KB/region would just be waste. | 34 | * (vs attributes). So more than 2KB/region would just be waste. |
35 | * Note: These are offsets from the physical base address. | ||
35 | */ | 36 | */ |
36 | #define CF_ATTR_PHYS (AT91_CF_BASE) | 37 | #define CF_ATTR_PHYS (0) |
37 | #define CF_IO_PHYS (AT91_CF_BASE + (1 << 23)) | 38 | #define CF_IO_PHYS (1 << 23) |
38 | #define CF_MEM_PHYS (AT91_CF_BASE + 0x017ff800) | 39 | #define CF_MEM_PHYS (0x017ff800) |
39 | 40 | ||
40 | /*--------------------------------------------------------------------------*/ | 41 | /*--------------------------------------------------------------------------*/ |
41 | 42 | ||
@@ -48,6 +49,8 @@ struct at91_cf_socket { | |||
48 | 49 | ||
49 | struct platform_device *pdev; | 50 | struct platform_device *pdev; |
50 | struct at91_cf_data *board; | 51 | struct at91_cf_data *board; |
52 | |||
53 | unsigned long phys_baseaddr; | ||
51 | }; | 54 | }; |
52 | 55 | ||
53 | #define SZ_2K (2 * SZ_1K) | 56 | #define SZ_2K (2 * SZ_1K) |
@@ -168,7 +171,7 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) | |||
168 | * some cards only like that way to get at the odd byte, despite | 171 | * some cards only like that way to get at the odd byte, despite |
169 | * CF 3.0 spec table 35 also giving the D8-D15 option. | 172 | * CF 3.0 spec table 35 also giving the D8-D15 option. |
170 | */ | 173 | */ |
171 | if (!(io->flags & (MAP_16BIT|MAP_AUTOSZ))) { | 174 | if (!(io->flags & (MAP_16BIT | MAP_AUTOSZ))) { |
172 | csr |= AT91_SMC_DBW_8; | 175 | csr |= AT91_SMC_DBW_8; |
173 | pr_debug("%s: 8bit i/o bus\n", driver_name); | 176 | pr_debug("%s: 8bit i/o bus\n", driver_name); |
174 | } else { | 177 | } else { |
@@ -194,11 +197,11 @@ at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map) | |||
194 | 197 | ||
195 | cf = container_of(s, struct at91_cf_socket, socket); | 198 | cf = container_of(s, struct at91_cf_socket, socket); |
196 | 199 | ||
197 | map->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT; | 200 | map->flags &= (MAP_ACTIVE | MAP_ATTRIB | MAP_16BIT); |
198 | if (map->flags & MAP_ATTRIB) | 201 | if (map->flags & MAP_ATTRIB) |
199 | map->static_start = CF_ATTR_PHYS; | 202 | map->static_start = cf->phys_baseaddr + CF_ATTR_PHYS; |
200 | else | 203 | else |
201 | map->static_start = CF_MEM_PHYS; | 204 | map->static_start = cf->phys_baseaddr + CF_MEM_PHYS; |
202 | 205 | ||
203 | return 0; | 206 | return 0; |
204 | } | 207 | } |
@@ -235,6 +238,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
235 | 238 | ||
236 | cf->board = board; | 239 | cf->board = board; |
237 | cf->pdev = pdev; | 240 | cf->pdev = pdev; |
241 | cf->phys_baseaddr = io->start; | ||
238 | platform_set_drvdata(pdev, cf); | 242 | platform_set_drvdata(pdev, cf); |
239 | 243 | ||
240 | /* CF takes over CS4, CS5, CS6 */ | 244 | /* CF takes over CS4, CS5, CS6 */ |
@@ -260,8 +264,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
260 | ); | 264 | ); |
261 | 265 | ||
262 | /* must be a GPIO; ergo must trigger on both edges */ | 266 | /* must be a GPIO; ergo must trigger on both edges */ |
263 | status = request_irq(board->det_pin, at91_cf_irq, | 267 | status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf); |
264 | IRQF_SAMPLE_RANDOM, driver_name, cf); | ||
265 | if (status < 0) | 268 | if (status < 0) |
266 | goto fail0; | 269 | goto fail0; |
267 | device_init_wakeup(&pdev->dev, 1); | 270 | device_init_wakeup(&pdev->dev, 1); |
@@ -282,14 +285,18 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
282 | cf->socket.pci_irq = NR_IRQS + 1; | 285 | cf->socket.pci_irq = NR_IRQS + 1; |
283 | 286 | ||
284 | /* pcmcia layer only remaps "real" memory not iospace */ | 287 | /* pcmcia layer only remaps "real" memory not iospace */ |
285 | cf->socket.io_offset = (unsigned long) ioremap(CF_IO_PHYS, SZ_2K); | 288 | cf->socket.io_offset = (unsigned long) ioremap(cf->phys_baseaddr + CF_IO_PHYS, SZ_2K); |
286 | if (!cf->socket.io_offset) | 289 | if (!cf->socket.io_offset) { |
290 | status = -ENXIO; | ||
287 | goto fail1; | 291 | goto fail1; |
292 | } | ||
288 | 293 | ||
289 | /* reserve CS4, CS5, and CS6 regions; but use just CS4 */ | 294 | /* reserve CS4, CS5, and CS6 regions; but use just CS4 */ |
290 | if (!request_mem_region(io->start, io->end + 1 - io->start, | 295 | if (!request_mem_region(io->start, io->end + 1 - io->start, |
291 | driver_name)) | 296 | driver_name)) { |
297 | status = -ENXIO; | ||
292 | goto fail1; | 298 | goto fail1; |
299 | } | ||
293 | 300 | ||
294 | pr_info("%s: irqs det #%d, io #%d\n", driver_name, | 301 | pr_info("%s: irqs det #%d, io #%d\n", driver_name, |
295 | board->det_pin, board->irq_pin); | 302 | board->det_pin, board->irq_pin); |
@@ -319,7 +326,6 @@ fail1: | |||
319 | fail0a: | 326 | fail0a: |
320 | device_init_wakeup(&pdev->dev, 0); | 327 | device_init_wakeup(&pdev->dev, 0); |
321 | free_irq(board->det_pin, cf); | 328 | free_irq(board->det_pin, cf); |
322 | device_init_wakeup(&pdev->dev, 0); | ||
323 | fail0: | 329 | fail0: |
324 | at91_sys_write(AT91_EBI_CSA, csa); | 330 | at91_sys_write(AT91_EBI_CSA, csa); |
325 | kfree(cf); | 331 | kfree(cf); |
@@ -336,8 +342,8 @@ static int __exit at91_cf_remove(struct platform_device *pdev) | |||
336 | pcmcia_unregister_socket(&cf->socket); | 342 | pcmcia_unregister_socket(&cf->socket); |
337 | if (board->irq_pin) | 343 | if (board->irq_pin) |
338 | free_irq(board->irq_pin, cf); | 344 | free_irq(board->irq_pin, cf); |
339 | free_irq(board->det_pin, cf); | ||
340 | device_init_wakeup(&pdev->dev, 0); | 345 | device_init_wakeup(&pdev->dev, 0); |
346 | free_irq(board->det_pin, cf); | ||
341 | iounmap((void __iomem *) cf->socket.io_offset); | 347 | iounmap((void __iomem *) cf->socket.io_offset); |
342 | release_mem_region(io->start, io->end + 1 - io->start); | 348 | release_mem_region(io->start, io->end + 1 - io->start); |
343 | 349 | ||