diff options
Diffstat (limited to 'drivers/pcmcia/at91_cf.c')
-rw-r--r-- | drivers/pcmcia/at91_cf.c | 62 |
1 files changed, 47 insertions, 15 deletions
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index eb6abd3f9221..385e145e1acc 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c | |||
@@ -21,9 +21,9 @@ | |||
21 | #include <asm/hardware.h> | 21 | #include <asm/hardware.h> |
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | #include <asm/sizes.h> | 23 | #include <asm/sizes.h> |
24 | #include <asm/gpio.h> | ||
24 | 25 | ||
25 | #include <asm/arch/board.h> | 26 | #include <asm/arch/board.h> |
26 | #include <asm/arch/gpio.h> | ||
27 | #include <asm/arch/at91rm9200_mc.h> | 27 | #include <asm/arch/at91rm9200_mc.h> |
28 | 28 | ||
29 | 29 | ||
@@ -56,7 +56,7 @@ struct at91_cf_socket { | |||
56 | 56 | ||
57 | static inline int at91_cf_present(struct at91_cf_socket *cf) | 57 | static inline int at91_cf_present(struct at91_cf_socket *cf) |
58 | { | 58 | { |
59 | return !at91_get_gpio_value(cf->board->det_pin); | 59 | return !gpio_get_value(cf->board->det_pin); |
60 | } | 60 | } |
61 | 61 | ||
62 | /*--------------------------------------------------------------------------*/ | 62 | /*--------------------------------------------------------------------------*/ |
@@ -100,9 +100,9 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp) | |||
100 | int vcc = cf->board->vcc_pin; | 100 | int vcc = cf->board->vcc_pin; |
101 | 101 | ||
102 | *sp = SS_DETECT | SS_3VCARD; | 102 | *sp = SS_DETECT | SS_3VCARD; |
103 | if (!rdy || at91_get_gpio_value(rdy)) | 103 | if (!rdy || gpio_get_value(rdy)) |
104 | *sp |= SS_READY; | 104 | *sp |= SS_READY; |
105 | if (!vcc || at91_get_gpio_value(vcc)) | 105 | if (!vcc || gpio_get_value(vcc)) |
106 | *sp |= SS_POWERON; | 106 | *sp |= SS_POWERON; |
107 | } else | 107 | } else |
108 | *sp = 0; | 108 | *sp = 0; |
@@ -121,10 +121,10 @@ at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) | |||
121 | if (cf->board->vcc_pin) { | 121 | if (cf->board->vcc_pin) { |
122 | switch (s->Vcc) { | 122 | switch (s->Vcc) { |
123 | case 0: | 123 | case 0: |
124 | at91_set_gpio_value(cf->board->vcc_pin, 0); | 124 | gpio_set_value(cf->board->vcc_pin, 0); |
125 | break; | 125 | break; |
126 | case 33: | 126 | case 33: |
127 | at91_set_gpio_value(cf->board->vcc_pin, 1); | 127 | gpio_set_value(cf->board->vcc_pin, 1); |
128 | break; | 128 | break; |
129 | default: | 129 | default: |
130 | return -EINVAL; | 130 | return -EINVAL; |
@@ -132,7 +132,7 @@ at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) | |||
132 | } | 132 | } |
133 | 133 | ||
134 | /* toggle reset if needed */ | 134 | /* toggle reset if needed */ |
135 | at91_set_gpio_value(cf->board->rst_pin, s->flags & SS_RESET); | 135 | gpio_set_value(cf->board->rst_pin, s->flags & SS_RESET); |
136 | 136 | ||
137 | pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n", | 137 | pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n", |
138 | driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask); | 138 | driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask); |
@@ -239,11 +239,24 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
239 | platform_set_drvdata(pdev, cf); | 239 | platform_set_drvdata(pdev, cf); |
240 | 240 | ||
241 | /* must be a GPIO; ergo must trigger on both edges */ | 241 | /* must be a GPIO; ergo must trigger on both edges */ |
242 | status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf); | 242 | status = gpio_request(board->det_pin, "cf_det"); |
243 | if (status < 0) | 243 | if (status < 0) |
244 | goto fail0; | 244 | goto fail0; |
245 | status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf); | ||
246 | if (status < 0) | ||
247 | goto fail00; | ||
245 | device_init_wakeup(&pdev->dev, 1); | 248 | device_init_wakeup(&pdev->dev, 1); |
246 | 249 | ||
250 | status = gpio_request(board->rst_pin, "cf_rst"); | ||
251 | if (status < 0) | ||
252 | goto fail0a; | ||
253 | |||
254 | if (board->vcc_pin) { | ||
255 | status = gpio_request(board->vcc_pin, "cf_vcc"); | ||
256 | if (status < 0) | ||
257 | goto fail0b; | ||
258 | } | ||
259 | |||
247 | /* | 260 | /* |
248 | * The card driver will request this irq later as needed. | 261 | * The card driver will request this irq later as needed. |
249 | * but it causes lots of "irqNN: nobody cared" messages | 262 | * but it causes lots of "irqNN: nobody cared" messages |
@@ -251,16 +264,20 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
251 | * (Note: DK board doesn't wire the IRQ pin...) | 264 | * (Note: DK board doesn't wire the IRQ pin...) |
252 | */ | 265 | */ |
253 | if (board->irq_pin) { | 266 | if (board->irq_pin) { |
267 | status = gpio_request(board->irq_pin, "cf_irq"); | ||
268 | if (status < 0) | ||
269 | goto fail0c; | ||
254 | status = request_irq(board->irq_pin, at91_cf_irq, | 270 | status = request_irq(board->irq_pin, at91_cf_irq, |
255 | IRQF_SHARED, driver_name, cf); | 271 | IRQF_SHARED, driver_name, cf); |
256 | if (status < 0) | 272 | if (status < 0) |
257 | goto fail0a; | 273 | goto fail0d; |
258 | cf->socket.pci_irq = board->irq_pin; | 274 | cf->socket.pci_irq = board->irq_pin; |
259 | } else | 275 | } else |
260 | cf->socket.pci_irq = NR_IRQS + 1; | 276 | cf->socket.pci_irq = NR_IRQS + 1; |
261 | 277 | ||
262 | /* pcmcia layer only remaps "real" memory not iospace */ | 278 | /* pcmcia layer only remaps "real" memory not iospace */ |
263 | cf->socket.io_offset = (unsigned long) ioremap(cf->phys_baseaddr + CF_IO_PHYS, SZ_2K); | 279 | cf->socket.io_offset = (unsigned long) |
280 | ioremap(cf->phys_baseaddr + CF_IO_PHYS, SZ_2K); | ||
264 | if (!cf->socket.io_offset) { | 281 | if (!cf->socket.io_offset) { |
265 | status = -ENXIO; | 282 | status = -ENXIO; |
266 | goto fail1; | 283 | goto fail1; |
@@ -296,11 +313,21 @@ fail2: | |||
296 | fail1: | 313 | fail1: |
297 | if (cf->socket.io_offset) | 314 | if (cf->socket.io_offset) |
298 | iounmap((void __iomem *) cf->socket.io_offset); | 315 | iounmap((void __iomem *) cf->socket.io_offset); |
299 | if (board->irq_pin) | 316 | if (board->irq_pin) { |
300 | free_irq(board->irq_pin, cf); | 317 | free_irq(board->irq_pin, cf); |
318 | fail0d: | ||
319 | gpio_free(board->irq_pin); | ||
320 | } | ||
321 | fail0c: | ||
322 | if (board->vcc_pin) | ||
323 | gpio_free(board->vcc_pin); | ||
324 | fail0b: | ||
325 | gpio_free(board->rst_pin); | ||
301 | fail0a: | 326 | fail0a: |
302 | device_init_wakeup(&pdev->dev, 0); | 327 | device_init_wakeup(&pdev->dev, 0); |
303 | free_irq(board->det_pin, cf); | 328 | free_irq(board->det_pin, cf); |
329 | fail00: | ||
330 | gpio_free(board->det_pin); | ||
304 | fail0: | 331 | fail0: |
305 | kfree(cf); | 332 | kfree(cf); |
306 | return status; | 333 | return status; |
@@ -313,13 +340,18 @@ static int __exit at91_cf_remove(struct platform_device *pdev) | |||
313 | struct resource *io = cf->socket.io[0].res; | 340 | struct resource *io = cf->socket.io[0].res; |
314 | 341 | ||
315 | pcmcia_unregister_socket(&cf->socket); | 342 | pcmcia_unregister_socket(&cf->socket); |
316 | if (board->irq_pin) | 343 | release_mem_region(io->start, io->end + 1 - io->start); |
344 | iounmap((void __iomem *) cf->socket.io_offset); | ||
345 | if (board->irq_pin) { | ||
317 | free_irq(board->irq_pin, cf); | 346 | free_irq(board->irq_pin, cf); |
347 | gpio_free(board->irq_pin); | ||
348 | } | ||
349 | if (board->vcc_pin) | ||
350 | gpio_free(board->vcc_pin); | ||
351 | gpio_free(board->rst_pin); | ||
318 | device_init_wakeup(&pdev->dev, 0); | 352 | device_init_wakeup(&pdev->dev, 0); |
319 | free_irq(board->det_pin, cf); | 353 | free_irq(board->det_pin, cf); |
320 | iounmap((void __iomem *) cf->socket.io_offset); | 354 | gpio_free(board->det_pin); |
321 | release_mem_region(io->start, io->end + 1 - io->start); | ||
322 | |||
323 | kfree(cf); | 355 | kfree(cf); |
324 | return 0; | 356 | return 0; |
325 | } | 357 | } |