aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/serio/rpckbd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/serio/rpckbd.c')
-rw-r--r--drivers/input/serio/rpckbd.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
index 8b44ddc8041c..2af5df6a8fba 100644
--- a/drivers/input/serio/rpckbd.c
+++ b/drivers/input/serio/rpckbd.c
@@ -36,16 +36,19 @@
36#include <linux/io.h> 36#include <linux/io.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38 38
39#include <asm/irq.h>
40#include <mach/hardware.h> 39#include <mach/hardware.h>
41#include <asm/hardware/iomd.h> 40#include <asm/hardware/iomd.h>
42#include <asm/system.h>
43 41
44MODULE_AUTHOR("Vojtech Pavlik, Russell King"); 42MODULE_AUTHOR("Vojtech Pavlik, Russell King");
45MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver"); 43MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver");
46MODULE_LICENSE("GPL"); 44MODULE_LICENSE("GPL");
47MODULE_ALIAS("platform:kart"); 45MODULE_ALIAS("platform:kart");
48 46
47struct rpckbd_data {
48 int tx_irq;
49 int rx_irq;
50};
51
49static int rpckbd_write(struct serio *port, unsigned char val) 52static int rpckbd_write(struct serio *port, unsigned char val)
50{ 53{
51 while (!(iomd_readb(IOMD_KCTRL) & (1 << 7))) 54 while (!(iomd_readb(IOMD_KCTRL) & (1 << 7)))
@@ -78,19 +81,21 @@ static irqreturn_t rpckbd_tx(int irq, void *dev_id)
78 81
79static int rpckbd_open(struct serio *port) 82static int rpckbd_open(struct serio *port)
80{ 83{
84 struct rpckbd_data *rpckbd = port->port_data;
85
81 /* Reset the keyboard state machine. */ 86 /* Reset the keyboard state machine. */
82 iomd_writeb(0, IOMD_KCTRL); 87 iomd_writeb(0, IOMD_KCTRL);
83 iomd_writeb(8, IOMD_KCTRL); 88 iomd_writeb(8, IOMD_KCTRL);
84 iomd_readb(IOMD_KARTRX); 89 iomd_readb(IOMD_KARTRX);
85 90
86 if (request_irq(IRQ_KEYBOARDRX, rpckbd_rx, 0, "rpckbd", port) != 0) { 91 if (request_irq(rpckbd->rx_irq, rpckbd_rx, 0, "rpckbd", port) != 0) {
87 printk(KERN_ERR "rpckbd.c: Could not allocate keyboard receive IRQ\n"); 92 printk(KERN_ERR "rpckbd.c: Could not allocate keyboard receive IRQ\n");
88 return -EBUSY; 93 return -EBUSY;
89 } 94 }
90 95
91 if (request_irq(IRQ_KEYBOARDTX, rpckbd_tx, 0, "rpckbd", port) != 0) { 96 if (request_irq(rpckbd->tx_irq, rpckbd_tx, 0, "rpckbd", port) != 0) {
92 printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n"); 97 printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n");
93 free_irq(IRQ_KEYBOARDRX, port); 98 free_irq(rpckbd->rx_irq, port);
94 return -EBUSY; 99 return -EBUSY;
95 } 100 }
96 101
@@ -99,8 +104,10 @@ static int rpckbd_open(struct serio *port)
99 104
100static void rpckbd_close(struct serio *port) 105static void rpckbd_close(struct serio *port)
101{ 106{
102 free_irq(IRQ_KEYBOARDRX, port); 107 struct rpckbd_data *rpckbd = port->port_data;
103 free_irq(IRQ_KEYBOARDTX, port); 108
109 free_irq(rpckbd->rx_irq, port);
110 free_irq(rpckbd->tx_irq, port);
104} 111}
105 112
106/* 113/*
@@ -109,17 +116,35 @@ static void rpckbd_close(struct serio *port)
109 */ 116 */
110static int __devinit rpckbd_probe(struct platform_device *dev) 117static int __devinit rpckbd_probe(struct platform_device *dev)
111{ 118{
119 struct rpckbd_data *rpckbd;
112 struct serio *serio; 120 struct serio *serio;
121 int tx_irq, rx_irq;
122
123 rx_irq = platform_get_irq(dev, 0);
124 if (rx_irq <= 0)
125 return rx_irq < 0 ? rx_irq : -ENXIO;
126
127 tx_irq = platform_get_irq(dev, 1);
128 if (tx_irq <= 0)
129 return tx_irq < 0 ? tx_irq : -ENXIO;
113 130
114 serio = kzalloc(sizeof(struct serio), GFP_KERNEL); 131 serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
115 if (!serio) 132 rpckbd = kzalloc(sizeof(*rpckbd), GFP_KERNEL);
133 if (!serio || !rpckbd) {
134 kfree(rpckbd);
135 kfree(serio);
116 return -ENOMEM; 136 return -ENOMEM;
137 }
138
139 rpckbd->rx_irq = rx_irq;
140 rpckbd->tx_irq = tx_irq;
117 141
118 serio->id.type = SERIO_8042; 142 serio->id.type = SERIO_8042;
119 serio->write = rpckbd_write; 143 serio->write = rpckbd_write;
120 serio->open = rpckbd_open; 144 serio->open = rpckbd_open;
121 serio->close = rpckbd_close; 145 serio->close = rpckbd_close;
122 serio->dev.parent = &dev->dev; 146 serio->dev.parent = &dev->dev;
147 serio->port_data = rpckbd;
123 strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name)); 148 strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
124 strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys)); 149 strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));
125 150
@@ -131,7 +156,11 @@ static int __devinit rpckbd_probe(struct platform_device *dev)
131static int __devexit rpckbd_remove(struct platform_device *dev) 156static int __devexit rpckbd_remove(struct platform_device *dev)
132{ 157{
133 struct serio *serio = platform_get_drvdata(dev); 158 struct serio *serio = platform_get_drvdata(dev);
159 struct rpckbd_data *rpckbd = serio->port_data;
160
134 serio_unregister_port(serio); 161 serio_unregister_port(serio);
162 kfree(rpckbd);
163
135 return 0; 164 return 0;
136} 165}
137 166