diff options
-rw-r--r-- | arch/arm/mach-rpc/riscpc.c | 7 | ||||
-rw-r--r-- | drivers/input/serio/rpckbd.c | 44 |
2 files changed, 44 insertions, 7 deletions
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index 3d44a59fc0df..30baaa8b8a2f 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c | |||
@@ -134,12 +134,19 @@ static struct platform_device iomd_device = { | |||
134 | .resource = iomd_resources, | 134 | .resource = iomd_resources, |
135 | }; | 135 | }; |
136 | 136 | ||
137 | static struct resource iomd_kart_resources[] = { | ||
138 | DEFINE_RES_IRQ(IRQ_KEYBOARDRX), | ||
139 | DEFINE_RES_IRQ(IRQ_KEYBOARDTX), | ||
140 | }; | ||
141 | |||
137 | static struct platform_device kbd_device = { | 142 | static struct platform_device kbd_device = { |
138 | .name = "kart", | 143 | .name = "kart", |
139 | .id = -1, | 144 | .id = -1, |
140 | .dev = { | 145 | .dev = { |
141 | .parent = &iomd_device.dev, | 146 | .parent = &iomd_device.dev, |
142 | }, | 147 | }, |
148 | .num_resources = ARRAY_SIZE(iomd_kart_resources), | ||
149 | .resource = iomd_kart_resources, | ||
143 | }; | 150 | }; |
144 | 151 | ||
145 | static struct plat_serial8250_port serial_platform_data[] = { | 152 | static struct plat_serial8250_port serial_platform_data[] = { |
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 8b44ddc8041c..58b224498b35 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c | |||
@@ -36,7 +36,6 @@ | |||
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> | 41 | #include <asm/system.h> |
@@ -46,6 +45,11 @@ MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver"); | |||
46 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
47 | MODULE_ALIAS("platform:kart"); | 46 | MODULE_ALIAS("platform:kart"); |
48 | 47 | ||
48 | struct rpckbd_data { | ||
49 | int tx_irq; | ||
50 | int rx_irq; | ||
51 | }; | ||
52 | |||
49 | static int rpckbd_write(struct serio *port, unsigned char val) | 53 | static int rpckbd_write(struct serio *port, unsigned char val) |
50 | { | 54 | { |
51 | while (!(iomd_readb(IOMD_KCTRL) & (1 << 7))) | 55 | while (!(iomd_readb(IOMD_KCTRL) & (1 << 7))) |
@@ -78,19 +82,21 @@ static irqreturn_t rpckbd_tx(int irq, void *dev_id) | |||
78 | 82 | ||
79 | static int rpckbd_open(struct serio *port) | 83 | static int rpckbd_open(struct serio *port) |
80 | { | 84 | { |
85 | struct rpckbd_data *rpckbd = port->port_data; | ||
86 | |||
81 | /* Reset the keyboard state machine. */ | 87 | /* Reset the keyboard state machine. */ |
82 | iomd_writeb(0, IOMD_KCTRL); | 88 | iomd_writeb(0, IOMD_KCTRL); |
83 | iomd_writeb(8, IOMD_KCTRL); | 89 | iomd_writeb(8, IOMD_KCTRL); |
84 | iomd_readb(IOMD_KARTRX); | 90 | iomd_readb(IOMD_KARTRX); |
85 | 91 | ||
86 | if (request_irq(IRQ_KEYBOARDRX, rpckbd_rx, 0, "rpckbd", port) != 0) { | 92 | 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"); | 93 | printk(KERN_ERR "rpckbd.c: Could not allocate keyboard receive IRQ\n"); |
88 | return -EBUSY; | 94 | return -EBUSY; |
89 | } | 95 | } |
90 | 96 | ||
91 | if (request_irq(IRQ_KEYBOARDTX, rpckbd_tx, 0, "rpckbd", port) != 0) { | 97 | 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"); | 98 | printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n"); |
93 | free_irq(IRQ_KEYBOARDRX, port); | 99 | free_irq(rpckbd->rx_irq, port); |
94 | return -EBUSY; | 100 | return -EBUSY; |
95 | } | 101 | } |
96 | 102 | ||
@@ -99,8 +105,10 @@ static int rpckbd_open(struct serio *port) | |||
99 | 105 | ||
100 | static void rpckbd_close(struct serio *port) | 106 | static void rpckbd_close(struct serio *port) |
101 | { | 107 | { |
102 | free_irq(IRQ_KEYBOARDRX, port); | 108 | struct rpckbd_data *rpckbd = port->port_data; |
103 | free_irq(IRQ_KEYBOARDTX, port); | 109 | |
110 | free_irq(rpckbd->rx_irq, port); | ||
111 | free_irq(rpckbd->tx_irq, port); | ||
104 | } | 112 | } |
105 | 113 | ||
106 | /* | 114 | /* |
@@ -109,17 +117,35 @@ static void rpckbd_close(struct serio *port) | |||
109 | */ | 117 | */ |
110 | static int __devinit rpckbd_probe(struct platform_device *dev) | 118 | static int __devinit rpckbd_probe(struct platform_device *dev) |
111 | { | 119 | { |
120 | struct rpckbd_data *rpckbd; | ||
112 | struct serio *serio; | 121 | struct serio *serio; |
122 | int tx_irq, rx_irq; | ||
123 | |||
124 | rx_irq = platform_get_irq(dev, 0); | ||
125 | if (rx_irq <= 0) | ||
126 | return rx_irq < 0 ? rx_irq : -ENXIO; | ||
127 | |||
128 | tx_irq = platform_get_irq(dev, 1); | ||
129 | if (tx_irq <= 0) | ||
130 | return tx_irq < 0 ? tx_irq : -ENXIO; | ||
113 | 131 | ||
114 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); | 132 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); |
115 | if (!serio) | 133 | rpckbd = kzalloc(sizeof(*rpckbd), GFP_KERNEL); |
134 | if (!serio || !rpckbd) { | ||
135 | kfree(rpckbd); | ||
136 | kfree(serio); | ||
116 | return -ENOMEM; | 137 | return -ENOMEM; |
138 | } | ||
139 | |||
140 | rpckbd->rx_irq = rx_irq; | ||
141 | rpckbd->tx_irq = tx_irq; | ||
117 | 142 | ||
118 | serio->id.type = SERIO_8042; | 143 | serio->id.type = SERIO_8042; |
119 | serio->write = rpckbd_write; | 144 | serio->write = rpckbd_write; |
120 | serio->open = rpckbd_open; | 145 | serio->open = rpckbd_open; |
121 | serio->close = rpckbd_close; | 146 | serio->close = rpckbd_close; |
122 | serio->dev.parent = &dev->dev; | 147 | serio->dev.parent = &dev->dev; |
148 | serio->port_data = rpckbd; | ||
123 | strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name)); | 149 | strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name)); |
124 | strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys)); | 150 | strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys)); |
125 | 151 | ||
@@ -131,7 +157,11 @@ static int __devinit rpckbd_probe(struct platform_device *dev) | |||
131 | static int __devexit rpckbd_remove(struct platform_device *dev) | 157 | static int __devexit rpckbd_remove(struct platform_device *dev) |
132 | { | 158 | { |
133 | struct serio *serio = platform_get_drvdata(dev); | 159 | struct serio *serio = platform_get_drvdata(dev); |
160 | struct rpckbd_data *rpckbd = serio->port_data; | ||
161 | |||
134 | serio_unregister_port(serio); | 162 | serio_unregister_port(serio); |
163 | kfree(rpckbd); | ||
164 | |||
135 | return 0; | 165 | return 0; |
136 | } | 166 | } |
137 | 167 | ||