summaryrefslogtreecommitdiff
path: root/drivers/pcmcia/db1xxx_ss.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/db1xxx_ss.c')
-rw-r--r--drivers/pcmcia/db1xxx_ss.c45
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 = {