at91_cf: use generic gpio calls
Update the AT91 CF driver to use the generic GPIO calls instead of the AT91-specific ones; and request exclusive use of those signals. Minor tweaks to cleanup code paths: always in reverse order of how the resources were allocated, with remove() matching the fault paths of probe(). Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
9ab9898e32
Коммит
4c1fc445c2
|
@ -21,9 +21,9 @@
|
|||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/sizes.h>
|
||||
#include <asm/gpio.h>
|
||||
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/at91rm9200_mc.h>
|
||||
|
||||
|
||||
|
@ -56,7 +56,7 @@ struct at91_cf_socket {
|
|||
|
||||
static inline int at91_cf_present(struct at91_cf_socket *cf)
|
||||
{
|
||||
return !at91_get_gpio_value(cf->board->det_pin);
|
||||
return !gpio_get_value(cf->board->det_pin);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
@ -100,9 +100,9 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp)
|
|||
int vcc = cf->board->vcc_pin;
|
||||
|
||||
*sp = SS_DETECT | SS_3VCARD;
|
||||
if (!rdy || at91_get_gpio_value(rdy))
|
||||
if (!rdy || gpio_get_value(rdy))
|
||||
*sp |= SS_READY;
|
||||
if (!vcc || at91_get_gpio_value(vcc))
|
||||
if (!vcc || gpio_get_value(vcc))
|
||||
*sp |= SS_POWERON;
|
||||
} else
|
||||
*sp = 0;
|
||||
|
@ -121,10 +121,10 @@ at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
|
|||
if (cf->board->vcc_pin) {
|
||||
switch (s->Vcc) {
|
||||
case 0:
|
||||
at91_set_gpio_value(cf->board->vcc_pin, 0);
|
||||
gpio_set_value(cf->board->vcc_pin, 0);
|
||||
break;
|
||||
case 33:
|
||||
at91_set_gpio_value(cf->board->vcc_pin, 1);
|
||||
gpio_set_value(cf->board->vcc_pin, 1);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -132,7 +132,7 @@ at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
|
|||
}
|
||||
|
||||
/* toggle reset if needed */
|
||||
at91_set_gpio_value(cf->board->rst_pin, s->flags & SS_RESET);
|
||||
gpio_set_value(cf->board->rst_pin, s->flags & SS_RESET);
|
||||
|
||||
pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n",
|
||||
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)
|
|||
platform_set_drvdata(pdev, cf);
|
||||
|
||||
/* must be a GPIO; ergo must trigger on both edges */
|
||||
status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf);
|
||||
status = gpio_request(board->det_pin, "cf_det");
|
||||
if (status < 0)
|
||||
goto fail0;
|
||||
status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf);
|
||||
if (status < 0)
|
||||
goto fail00;
|
||||
device_init_wakeup(&pdev->dev, 1);
|
||||
|
||||
status = gpio_request(board->rst_pin, "cf_rst");
|
||||
if (status < 0)
|
||||
goto fail0a;
|
||||
|
||||
if (board->vcc_pin) {
|
||||
status = gpio_request(board->vcc_pin, "cf_vcc");
|
||||
if (status < 0)
|
||||
goto fail0b;
|
||||
}
|
||||
|
||||
/*
|
||||
* The card driver will request this irq later as needed.
|
||||
* but it causes lots of "irqNN: nobody cared" messages
|
||||
|
@ -251,16 +264,20 @@ static int __init at91_cf_probe(struct platform_device *pdev)
|
|||
* (Note: DK board doesn't wire the IRQ pin...)
|
||||
*/
|
||||
if (board->irq_pin) {
|
||||
status = gpio_request(board->irq_pin, "cf_irq");
|
||||
if (status < 0)
|
||||
goto fail0c;
|
||||
status = request_irq(board->irq_pin, at91_cf_irq,
|
||||
IRQF_SHARED, driver_name, cf);
|
||||
if (status < 0)
|
||||
goto fail0a;
|
||||
goto fail0d;
|
||||
cf->socket.pci_irq = board->irq_pin;
|
||||
} else
|
||||
cf->socket.pci_irq = NR_IRQS + 1;
|
||||
|
||||
/* pcmcia layer only remaps "real" memory not iospace */
|
||||
cf->socket.io_offset = (unsigned long) ioremap(cf->phys_baseaddr + 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) {
|
||||
status = -ENXIO;
|
||||
goto fail1;
|
||||
|
@ -296,11 +313,21 @@ fail2:
|
|||
fail1:
|
||||
if (cf->socket.io_offset)
|
||||
iounmap((void __iomem *) cf->socket.io_offset);
|
||||
if (board->irq_pin)
|
||||
if (board->irq_pin) {
|
||||
free_irq(board->irq_pin, cf);
|
||||
fail0d:
|
||||
gpio_free(board->irq_pin);
|
||||
}
|
||||
fail0c:
|
||||
if (board->vcc_pin)
|
||||
gpio_free(board->vcc_pin);
|
||||
fail0b:
|
||||
gpio_free(board->rst_pin);
|
||||
fail0a:
|
||||
device_init_wakeup(&pdev->dev, 0);
|
||||
free_irq(board->det_pin, cf);
|
||||
fail00:
|
||||
gpio_free(board->det_pin);
|
||||
fail0:
|
||||
kfree(cf);
|
||||
return status;
|
||||
|
@ -313,13 +340,18 @@ static int __exit at91_cf_remove(struct platform_device *pdev)
|
|||
struct resource *io = cf->socket.io[0].res;
|
||||
|
||||
pcmcia_unregister_socket(&cf->socket);
|
||||
if (board->irq_pin)
|
||||
release_mem_region(io->start, io->end + 1 - io->start);
|
||||
iounmap((void __iomem *) cf->socket.io_offset);
|
||||
if (board->irq_pin) {
|
||||
free_irq(board->irq_pin, cf);
|
||||
gpio_free(board->irq_pin);
|
||||
}
|
||||
if (board->vcc_pin)
|
||||
gpio_free(board->vcc_pin);
|
||||
gpio_free(board->rst_pin);
|
||||
device_init_wakeup(&pdev->dev, 0);
|
||||
free_irq(board->det_pin, cf);
|
||||
iounmap((void __iomem *) cf->socket.io_offset);
|
||||
release_mem_region(io->start, io->end + 1 - io->start);
|
||||
|
||||
gpio_free(board->det_pin);
|
||||
kfree(cf);
|
||||
return 0;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче