提交 ebe5cfb3 编写于 作者: A Andrew Victor 提交者: Dominik Brodowski

[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: NAndrew Victor <andrew@sanpeople.com>
Signed-off-by: NDominik Brodowski <linux@dominikbrodowski.net>
上级 af2b3b50
...@@ -32,10 +32,11 @@ ...@@ -32,10 +32,11 @@
* A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW; * A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW;
* some other bit in {A24,A22..A11} is nREG to flag memory access * some other bit in {A24,A22..A11} is nREG to flag memory access
* (vs attributes). So more than 2KB/region would just be waste. * (vs attributes). So more than 2KB/region would just be waste.
* Note: These are offsets from the physical base address.
*/ */
#define CF_ATTR_PHYS (AT91_CF_BASE) #define CF_ATTR_PHYS (0)
#define CF_IO_PHYS (AT91_CF_BASE + (1 << 23)) #define CF_IO_PHYS (1 << 23)
#define CF_MEM_PHYS (AT91_CF_BASE + 0x017ff800) #define CF_MEM_PHYS (0x017ff800)
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
...@@ -48,6 +49,8 @@ struct at91_cf_socket { ...@@ -48,6 +49,8 @@ struct at91_cf_socket {
struct platform_device *pdev; struct platform_device *pdev;
struct at91_cf_data *board; struct at91_cf_data *board;
unsigned long phys_baseaddr;
}; };
#define SZ_2K (2 * SZ_1K) #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,7 +171,7 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
* some cards only like that way to get at the odd byte, despite * some cards only like that way to get at the odd byte, despite
* CF 3.0 spec table 35 also giving the D8-D15 option. * CF 3.0 spec table 35 also giving the D8-D15 option.
*/ */
if (!(io->flags & (MAP_16BIT|MAP_AUTOSZ))) { if (!(io->flags & (MAP_16BIT | MAP_AUTOSZ))) {
csr |= AT91_SMC_DBW_8; csr |= AT91_SMC_DBW_8;
pr_debug("%s: 8bit i/o bus\n", driver_name); pr_debug("%s: 8bit i/o bus\n", driver_name);
} else { } else {
...@@ -194,11 +197,11 @@ at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map) ...@@ -194,11 +197,11 @@ at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map)
cf = container_of(s, struct at91_cf_socket, socket); cf = container_of(s, struct at91_cf_socket, socket);
map->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT; map->flags &= (MAP_ACTIVE | MAP_ATTRIB | MAP_16BIT);
if (map->flags & MAP_ATTRIB) if (map->flags & MAP_ATTRIB)
map->static_start = CF_ATTR_PHYS; map->static_start = cf->phys_baseaddr + CF_ATTR_PHYS;
else else
map->static_start = CF_MEM_PHYS; map->static_start = cf->phys_baseaddr + CF_MEM_PHYS;
return 0; return 0;
} }
...@@ -235,6 +238,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) ...@@ -235,6 +238,7 @@ static int __init at91_cf_probe(struct platform_device *pdev)
cf->board = board; cf->board = board;
cf->pdev = pdev; cf->pdev = pdev;
cf->phys_baseaddr = io->start;
platform_set_drvdata(pdev, cf); platform_set_drvdata(pdev, cf);
/* CF takes over CS4, CS5, CS6 */ /* CF takes over CS4, CS5, CS6 */
...@@ -260,8 +264,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) ...@@ -260,8 +264,7 @@ static int __init at91_cf_probe(struct platform_device *pdev)
); );
/* must be a GPIO; ergo must trigger on both edges */ /* must be a GPIO; ergo must trigger on both edges */
status = request_irq(board->det_pin, at91_cf_irq, status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf);
IRQF_SAMPLE_RANDOM, driver_name, cf);
if (status < 0) if (status < 0)
goto fail0; goto fail0;
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
...@@ -282,14 +285,18 @@ static int __init at91_cf_probe(struct platform_device *pdev) ...@@ -282,14 +285,18 @@ static int __init at91_cf_probe(struct platform_device *pdev)
cf->socket.pci_irq = NR_IRQS + 1; cf->socket.pci_irq = NR_IRQS + 1;
/* pcmcia layer only remaps "real" memory not iospace */ /* pcmcia layer only remaps "real" memory not iospace */
cf->socket.io_offset = (unsigned long) ioremap(CF_IO_PHYS, SZ_2K); cf->socket.io_offset = (unsigned long) ioremap(cf->phys_baseaddr + CF_IO_PHYS, SZ_2K);
if (!cf->socket.io_offset) if (!cf->socket.io_offset) {
status = -ENXIO;
goto fail1; goto fail1;
}
/* reserve CS4, CS5, and CS6 regions; but use just CS4 */ /* reserve CS4, CS5, and CS6 regions; but use just CS4 */
if (!request_mem_region(io->start, io->end + 1 - io->start, if (!request_mem_region(io->start, io->end + 1 - io->start,
driver_name)) driver_name)) {
status = -ENXIO;
goto fail1; goto fail1;
}
pr_info("%s: irqs det #%d, io #%d\n", driver_name, pr_info("%s: irqs det #%d, io #%d\n", driver_name,
board->det_pin, board->irq_pin); board->det_pin, board->irq_pin);
...@@ -319,7 +326,6 @@ static int __init at91_cf_probe(struct platform_device *pdev) ...@@ -319,7 +326,6 @@ static int __init at91_cf_probe(struct platform_device *pdev)
fail0a: fail0a:
device_init_wakeup(&pdev->dev, 0); device_init_wakeup(&pdev->dev, 0);
free_irq(board->det_pin, cf); free_irq(board->det_pin, cf);
device_init_wakeup(&pdev->dev, 0);
fail0: fail0:
at91_sys_write(AT91_EBI_CSA, csa); at91_sys_write(AT91_EBI_CSA, csa);
kfree(cf); kfree(cf);
...@@ -336,8 +342,8 @@ static int __exit at91_cf_remove(struct platform_device *pdev) ...@@ -336,8 +342,8 @@ static int __exit at91_cf_remove(struct platform_device *pdev)
pcmcia_unregister_socket(&cf->socket); pcmcia_unregister_socket(&cf->socket);
if (board->irq_pin) if (board->irq_pin)
free_irq(board->irq_pin, cf); free_irq(board->irq_pin, cf);
free_irq(board->det_pin, cf);
device_init_wakeup(&pdev->dev, 0); device_init_wakeup(&pdev->dev, 0);
free_irq(board->det_pin, cf);
iounmap((void __iomem *) cf->socket.io_offset); iounmap((void __iomem *) cf->socket.io_offset);
release_mem_region(io->start, io->end + 1 - io->start); release_mem_region(io->start, io->end + 1 - io->start);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册