diff options
Diffstat (limited to 'drivers/pcmcia/db1xxx_ss.c')
| -rw-r--r-- | drivers/pcmcia/db1xxx_ss.c | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 944674ee3464..85d2616061dd 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * PCMCIA socket code for the Alchemy Db1xxx/Pb1xxx boards. * @@ -131,22 +132,27 @@ static irqreturn_t db1000_pcmcia_stschgirq(int irq, void *data) return IRQ_HANDLED; } +/* Db/Pb1200 have separate per-socket insertion and ejection + * interrupts which stay asserted as long as the card is + * inserted/missing. The one which caused us to be called + * needs to be disabled and the other one enabled. + */ static irqreturn_t db1200_pcmcia_cdirq(int irq, void *data) { + disable_irq_nosync(irq); + return IRQ_WAKE_THREAD; +} + +static irqreturn_t db1200_pcmcia_cdirq_fn(int irq, void *data) +{ struct db1x_pcmcia_sock *sock = data; - /* Db/Pb1200 have separate per-socket insertion and ejection - * interrupts which stay asserted as long as the card is - * inserted/missing. The one which caused us to be called - * needs to be disabled and the other one enabled. - */ - if (irq == sock->insert_irq) { - disable_irq_nosync(sock->insert_irq); + /* Wait a bit for the signals to stop bouncing. */ + msleep(100); + if (irq == sock->insert_irq) enable_irq(sock->eject_irq); - } else { - disable_irq_nosync(sock->eject_irq); + else enable_irq(sock->insert_irq); - } pcmcia_parse_events(&sock->socket, SS_DETECT); @@ -172,13 +178,13 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock) */ if ((sock->board_type == BOARD_TYPE_DB1200) || (sock->board_type == BOARD_TYPE_DB1300)) { - ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq, - 0, "pcmcia_insert", sock); + ret = request_threaded_irq(sock->insert_irq, db1200_pcmcia_cdirq, + db1200_pcmcia_cdirq_fn, 0, "pcmcia_insert", sock); if (ret) goto out1; - ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq, - 0, "pcmcia_eject", sock); + ret = request_threaded_irq(sock->eject_irq, db1200_pcmcia_cdirq, + db1200_pcmcia_cdirq_fn, 0, "pcmcia_eject", sock); if (ret) { free_irq(sock->insert_irq, sock); goto out1; @@ -249,8 +255,10 @@ static int db1x_pcmcia_configure(struct pcmcia_socket *skt, switch (state->Vcc) { case 50: ++v; + fallthrough; case 33: ++v; + fallthrough; case 0: break; default: @@ -261,9 +269,11 @@ static int db1x_pcmcia_configure(struct pcmcia_socket *skt, switch (state->Vpp) { case 12: ++p; + fallthrough; case 33: case 50: ++p; + fallthrough; case 0: break; default: @@ -346,6 +356,7 @@ static int db1x_pcmcia_get_status(struct pcmcia_socket *skt, case 0: case 2: status |= SS_3VCARD; /* 3V card */ + break; case 3: break; /* 5V card: set nothing */ default: @@ -442,7 +453,7 @@ static int db1x_pcmcia_socket_probe(struct platform_device *pdev) printk(KERN_INFO "db1xxx-ss: unknown board %d!\n", bid); ret = -ENODEV; goto out0; - }; + } /* * gather resources necessary and optional nice-to-haves to @@ -566,7 +577,7 @@ out0: return ret; } -static int db1x_pcmcia_socket_remove(struct platform_device *pdev) +static void db1x_pcmcia_socket_remove(struct platform_device *pdev) { struct db1x_pcmcia_sock *sock = platform_get_drvdata(pdev); @@ -574,8 +585,6 @@ static int db1x_pcmcia_socket_remove(struct platform_device *pdev) pcmcia_unregister_socket(&sock->socket); iounmap((void *)(sock->virt_io + (u32)mips_io_port_base)); kfree(sock); - - return 0; } static struct platform_driver db1x_pcmcia_socket_driver = { |
