]> Pileus Git - ~andy/linux/blobdiff - drivers/input/serio/rpckbd.c
Merge tag 'nfs-for-3.4-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
[~andy/linux] / drivers / input / serio / rpckbd.c
index 8b44ddc8041ce4c1cf410435585caeb8f379193a..2af5df6a8fba76855f5a354fafaeb958459feecc 100644 (file)
 #include <linux/io.h>
 #include <linux/slab.h>
 
-#include <asm/irq.h>
 #include <mach/hardware.h>
 #include <asm/hardware/iomd.h>
-#include <asm/system.h>
 
 MODULE_AUTHOR("Vojtech Pavlik, Russell King");
 MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:kart");
 
+struct rpckbd_data {
+       int tx_irq;
+       int rx_irq;
+};
+
 static int rpckbd_write(struct serio *port, unsigned char val)
 {
        while (!(iomd_readb(IOMD_KCTRL) & (1 << 7)))
@@ -78,19 +81,21 @@ static irqreturn_t rpckbd_tx(int irq, void *dev_id)
 
 static int rpckbd_open(struct serio *port)
 {
+       struct rpckbd_data *rpckbd = port->port_data;
+
        /* Reset the keyboard state machine. */
        iomd_writeb(0, IOMD_KCTRL);
        iomd_writeb(8, IOMD_KCTRL);
        iomd_readb(IOMD_KARTRX);
 
-       if (request_irq(IRQ_KEYBOARDRX, rpckbd_rx, 0, "rpckbd", port) != 0) {
+       if (request_irq(rpckbd->rx_irq, rpckbd_rx, 0, "rpckbd", port) != 0) {
                printk(KERN_ERR "rpckbd.c: Could not allocate keyboard receive IRQ\n");
                return -EBUSY;
        }
 
-       if (request_irq(IRQ_KEYBOARDTX, rpckbd_tx, 0, "rpckbd", port) != 0) {
+       if (request_irq(rpckbd->tx_irq, rpckbd_tx, 0, "rpckbd", port) != 0) {
                printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n");
-               free_irq(IRQ_KEYBOARDRX, port);
+               free_irq(rpckbd->rx_irq, port);
                return -EBUSY;
        }
 
@@ -99,8 +104,10 @@ static int rpckbd_open(struct serio *port)
 
 static void rpckbd_close(struct serio *port)
 {
-       free_irq(IRQ_KEYBOARDRX, port);
-       free_irq(IRQ_KEYBOARDTX, port);
+       struct rpckbd_data *rpckbd = port->port_data;
+
+       free_irq(rpckbd->rx_irq, port);
+       free_irq(rpckbd->tx_irq, port);
 }
 
 /*
@@ -109,17 +116,35 @@ static void rpckbd_close(struct serio *port)
  */
 static int __devinit rpckbd_probe(struct platform_device *dev)
 {
+       struct rpckbd_data *rpckbd;
        struct serio *serio;
+       int tx_irq, rx_irq;
+
+       rx_irq = platform_get_irq(dev, 0);
+       if (rx_irq <= 0)
+               return rx_irq < 0 ? rx_irq : -ENXIO;
+
+       tx_irq = platform_get_irq(dev, 1);
+       if (tx_irq <= 0)
+               return tx_irq < 0 ? tx_irq : -ENXIO;
 
        serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
-       if (!serio)
+       rpckbd = kzalloc(sizeof(*rpckbd), GFP_KERNEL);
+       if (!serio || !rpckbd) {
+               kfree(rpckbd);
+               kfree(serio);
                return -ENOMEM;
+       }
+
+       rpckbd->rx_irq = rx_irq;
+       rpckbd->tx_irq = tx_irq;
 
        serio->id.type          = SERIO_8042;
        serio->write            = rpckbd_write;
        serio->open             = rpckbd_open;
        serio->close            = rpckbd_close;
        serio->dev.parent       = &dev->dev;
+       serio->port_data        = rpckbd;
        strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
        strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));
 
@@ -131,7 +156,11 @@ static int __devinit rpckbd_probe(struct platform_device *dev)
 static int __devexit rpckbd_remove(struct platform_device *dev)
 {
        struct serio *serio = platform_get_drvdata(dev);
+       struct rpckbd_data *rpckbd = serio->port_data;
+
        serio_unregister_port(serio);
+       kfree(rpckbd);
+
        return 0;
 }