diff options
Diffstat (limited to 'drivers/input/serio')
-rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 7 | ||||
-rw-r--r-- | drivers/input/serio/rpckbd.c | 44 | ||||
-rw-r--r-- | drivers/input/serio/sa1111ps2.c | 59 | ||||
-rw-r--r-- | drivers/input/serio/serio_raw.c | 15 |
4 files changed, 95 insertions, 30 deletions
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index b4cfc6c8be89..5ec774d6c82b 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -512,6 +512,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { | |||
512 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"), | 512 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"), |
513 | }, | 513 | }, |
514 | }, | 514 | }, |
515 | { | ||
516 | /* Lenovo Ideapad U455 */ | ||
517 | .matches = { | ||
518 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
519 | DMI_MATCH(DMI_PRODUCT_NAME, "20046"), | ||
520 | }, | ||
521 | }, | ||
515 | { } | 522 | { } |
516 | }; | 523 | }; |
517 | 524 | ||
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 | ||
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c index 44fc8b4bcd81..5ebabe3fc845 100644 --- a/drivers/input/serio/sa1111ps2.c +++ b/drivers/input/serio/sa1111ps2.c | |||
@@ -24,6 +24,26 @@ | |||
24 | 24 | ||
25 | #include <asm/hardware/sa1111.h> | 25 | #include <asm/hardware/sa1111.h> |
26 | 26 | ||
27 | #define PS2CR 0x0000 | ||
28 | #define PS2STAT 0x0004 | ||
29 | #define PS2DATA 0x0008 | ||
30 | #define PS2CLKDIV 0x000c | ||
31 | #define PS2PRECNT 0x0010 | ||
32 | |||
33 | #define PS2CR_ENA 0x08 | ||
34 | #define PS2CR_FKD 0x02 | ||
35 | #define PS2CR_FKC 0x01 | ||
36 | |||
37 | #define PS2STAT_STP 0x0100 | ||
38 | #define PS2STAT_TXE 0x0080 | ||
39 | #define PS2STAT_TXB 0x0040 | ||
40 | #define PS2STAT_RXF 0x0020 | ||
41 | #define PS2STAT_RXB 0x0010 | ||
42 | #define PS2STAT_ENA 0x0008 | ||
43 | #define PS2STAT_RXP 0x0004 | ||
44 | #define PS2STAT_KBD 0x0002 | ||
45 | #define PS2STAT_KBC 0x0001 | ||
46 | |||
27 | struct ps2if { | 47 | struct ps2if { |
28 | struct serio *io; | 48 | struct serio *io; |
29 | struct sa1111_dev *dev; | 49 | struct sa1111_dev *dev; |
@@ -45,22 +65,22 @@ static irqreturn_t ps2_rxint(int irq, void *dev_id) | |||
45 | struct ps2if *ps2if = dev_id; | 65 | struct ps2if *ps2if = dev_id; |
46 | unsigned int scancode, flag, status; | 66 | unsigned int scancode, flag, status; |
47 | 67 | ||
48 | status = sa1111_readl(ps2if->base + SA1111_PS2STAT); | 68 | status = sa1111_readl(ps2if->base + PS2STAT); |
49 | while (status & PS2STAT_RXF) { | 69 | while (status & PS2STAT_RXF) { |
50 | if (status & PS2STAT_STP) | 70 | if (status & PS2STAT_STP) |
51 | sa1111_writel(PS2STAT_STP, ps2if->base + SA1111_PS2STAT); | 71 | sa1111_writel(PS2STAT_STP, ps2if->base + PS2STAT); |
52 | 72 | ||
53 | flag = (status & PS2STAT_STP ? SERIO_FRAME : 0) | | 73 | flag = (status & PS2STAT_STP ? SERIO_FRAME : 0) | |
54 | (status & PS2STAT_RXP ? 0 : SERIO_PARITY); | 74 | (status & PS2STAT_RXP ? 0 : SERIO_PARITY); |
55 | 75 | ||
56 | scancode = sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff; | 76 | scancode = sa1111_readl(ps2if->base + PS2DATA) & 0xff; |
57 | 77 | ||
58 | if (hweight8(scancode) & 1) | 78 | if (hweight8(scancode) & 1) |
59 | flag ^= SERIO_PARITY; | 79 | flag ^= SERIO_PARITY; |
60 | 80 | ||
61 | serio_interrupt(ps2if->io, scancode, flag); | 81 | serio_interrupt(ps2if->io, scancode, flag); |
62 | 82 | ||
63 | status = sa1111_readl(ps2if->base + SA1111_PS2STAT); | 83 | status = sa1111_readl(ps2if->base + PS2STAT); |
64 | } | 84 | } |
65 | 85 | ||
66 | return IRQ_HANDLED; | 86 | return IRQ_HANDLED; |
@@ -75,12 +95,12 @@ static irqreturn_t ps2_txint(int irq, void *dev_id) | |||
75 | unsigned int status; | 95 | unsigned int status; |
76 | 96 | ||
77 | spin_lock(&ps2if->lock); | 97 | spin_lock(&ps2if->lock); |
78 | status = sa1111_readl(ps2if->base + SA1111_PS2STAT); | 98 | status = sa1111_readl(ps2if->base + PS2STAT); |
79 | if (ps2if->head == ps2if->tail) { | 99 | if (ps2if->head == ps2if->tail) { |
80 | disable_irq_nosync(irq); | 100 | disable_irq_nosync(irq); |
81 | /* done */ | 101 | /* done */ |
82 | } else if (status & PS2STAT_TXE) { | 102 | } else if (status & PS2STAT_TXE) { |
83 | sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + SA1111_PS2DATA); | 103 | sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + PS2DATA); |
84 | ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1); | 104 | ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1); |
85 | } | 105 | } |
86 | spin_unlock(&ps2if->lock); | 106 | spin_unlock(&ps2if->lock); |
@@ -103,8 +123,8 @@ static int ps2_write(struct serio *io, unsigned char val) | |||
103 | /* | 123 | /* |
104 | * If the TX register is empty, we can go straight out. | 124 | * If the TX register is empty, we can go straight out. |
105 | */ | 125 | */ |
106 | if (sa1111_readl(ps2if->base + SA1111_PS2STAT) & PS2STAT_TXE) { | 126 | if (sa1111_readl(ps2if->base + PS2STAT) & PS2STAT_TXE) { |
107 | sa1111_writel(val, ps2if->base + SA1111_PS2DATA); | 127 | sa1111_writel(val, ps2if->base + PS2DATA); |
108 | } else { | 128 | } else { |
109 | if (ps2if->head == ps2if->tail) | 129 | if (ps2if->head == ps2if->tail) |
110 | enable_irq(ps2if->dev->irq[1]); | 130 | enable_irq(ps2if->dev->irq[1]); |
@@ -124,13 +144,16 @@ static int ps2_open(struct serio *io) | |||
124 | struct ps2if *ps2if = io->port_data; | 144 | struct ps2if *ps2if = io->port_data; |
125 | int ret; | 145 | int ret; |
126 | 146 | ||
127 | sa1111_enable_device(ps2if->dev); | 147 | ret = sa1111_enable_device(ps2if->dev); |
148 | if (ret) | ||
149 | return ret; | ||
128 | 150 | ||
129 | ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0, | 151 | ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0, |
130 | SA1111_DRIVER_NAME(ps2if->dev), ps2if); | 152 | SA1111_DRIVER_NAME(ps2if->dev), ps2if); |
131 | if (ret) { | 153 | if (ret) { |
132 | printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", | 154 | printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", |
133 | ps2if->dev->irq[0], ret); | 155 | ps2if->dev->irq[0], ret); |
156 | sa1111_disable_device(ps2if->dev); | ||
134 | return ret; | 157 | return ret; |
135 | } | 158 | } |
136 | 159 | ||
@@ -140,6 +163,7 @@ static int ps2_open(struct serio *io) | |||
140 | printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", | 163 | printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", |
141 | ps2if->dev->irq[1], ret); | 164 | ps2if->dev->irq[1], ret); |
142 | free_irq(ps2if->dev->irq[0], ps2if); | 165 | free_irq(ps2if->dev->irq[0], ps2if); |
166 | sa1111_disable_device(ps2if->dev); | ||
143 | return ret; | 167 | return ret; |
144 | } | 168 | } |
145 | 169 | ||
@@ -147,7 +171,7 @@ static int ps2_open(struct serio *io) | |||
147 | 171 | ||
148 | enable_irq_wake(ps2if->dev->irq[0]); | 172 | enable_irq_wake(ps2if->dev->irq[0]); |
149 | 173 | ||
150 | sa1111_writel(PS2CR_ENA, ps2if->base + SA1111_PS2CR); | 174 | sa1111_writel(PS2CR_ENA, ps2if->base + PS2CR); |
151 | return 0; | 175 | return 0; |
152 | } | 176 | } |
153 | 177 | ||
@@ -155,7 +179,7 @@ static void ps2_close(struct serio *io) | |||
155 | { | 179 | { |
156 | struct ps2if *ps2if = io->port_data; | 180 | struct ps2if *ps2if = io->port_data; |
157 | 181 | ||
158 | sa1111_writel(0, ps2if->base + SA1111_PS2CR); | 182 | sa1111_writel(0, ps2if->base + PS2CR); |
159 | 183 | ||
160 | disable_irq_wake(ps2if->dev->irq[0]); | 184 | disable_irq_wake(ps2if->dev->irq[0]); |
161 | 185 | ||
@@ -175,7 +199,7 @@ static void __devinit ps2_clear_input(struct ps2if *ps2if) | |||
175 | int maxread = 100; | 199 | int maxread = 100; |
176 | 200 | ||
177 | while (maxread--) { | 201 | while (maxread--) { |
178 | if ((sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff) == 0xff) | 202 | if ((sa1111_readl(ps2if->base + PS2DATA) & 0xff) == 0xff) |
179 | break; | 203 | break; |
180 | } | 204 | } |
181 | } | 205 | } |
@@ -185,11 +209,11 @@ static unsigned int __devinit ps2_test_one(struct ps2if *ps2if, | |||
185 | { | 209 | { |
186 | unsigned int val; | 210 | unsigned int val; |
187 | 211 | ||
188 | sa1111_writel(PS2CR_ENA | mask, ps2if->base + SA1111_PS2CR); | 212 | sa1111_writel(PS2CR_ENA | mask, ps2if->base + PS2CR); |
189 | 213 | ||
190 | udelay(2); | 214 | udelay(2); |
191 | 215 | ||
192 | val = sa1111_readl(ps2if->base + SA1111_PS2STAT); | 216 | val = sa1111_readl(ps2if->base + PS2STAT); |
193 | return val & (PS2STAT_KBC | PS2STAT_KBD); | 217 | return val & (PS2STAT_KBC | PS2STAT_KBD); |
194 | } | 218 | } |
195 | 219 | ||
@@ -220,7 +244,7 @@ static int __devinit ps2_test(struct ps2if *ps2if) | |||
220 | ret = -ENODEV; | 244 | ret = -ENODEV; |
221 | } | 245 | } |
222 | 246 | ||
223 | sa1111_writel(0, ps2if->base + SA1111_PS2CR); | 247 | sa1111_writel(0, ps2if->base + PS2CR); |
224 | 248 | ||
225 | return ret; | 249 | return ret; |
226 | } | 250 | } |
@@ -274,8 +298,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev) | |||
274 | sa1111_enable_device(ps2if->dev); | 298 | sa1111_enable_device(ps2if->dev); |
275 | 299 | ||
276 | /* Incoming clock is 8MHz */ | 300 | /* Incoming clock is 8MHz */ |
277 | sa1111_writel(0, ps2if->base + SA1111_PS2CLKDIV); | 301 | sa1111_writel(0, ps2if->base + PS2CLKDIV); |
278 | sa1111_writel(127, ps2if->base + SA1111_PS2PRECNT); | 302 | sa1111_writel(127, ps2if->base + PS2PRECNT); |
279 | 303 | ||
280 | /* | 304 | /* |
281 | * Flush any pending input. | 305 | * Flush any pending input. |
@@ -330,6 +354,7 @@ static int __devexit ps2_remove(struct sa1111_dev *dev) | |||
330 | static struct sa1111_driver ps2_driver = { | 354 | static struct sa1111_driver ps2_driver = { |
331 | .drv = { | 355 | .drv = { |
332 | .name = "sa1111-ps2", | 356 | .name = "sa1111-ps2", |
357 | .owner = THIS_MODULE, | ||
333 | }, | 358 | }, |
334 | .devid = SA1111_DEVID_PS2, | 359 | .devid = SA1111_DEVID_PS2, |
335 | .probe = ps2_probe, | 360 | .probe = ps2_probe, |
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 8250299fd64f..4494233d331a 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -164,7 +164,8 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, | |||
164 | struct serio_raw_client *client = file->private_data; | 164 | struct serio_raw_client *client = file->private_data; |
165 | struct serio_raw *serio_raw = client->serio_raw; | 165 | struct serio_raw *serio_raw = client->serio_raw; |
166 | char uninitialized_var(c); | 166 | char uninitialized_var(c); |
167 | ssize_t retval = 0; | 167 | ssize_t read = 0; |
168 | int retval; | ||
168 | 169 | ||
169 | if (serio_raw->dead) | 170 | if (serio_raw->dead) |
170 | return -ENODEV; | 171 | return -ENODEV; |
@@ -180,13 +181,15 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, | |||
180 | if (serio_raw->dead) | 181 | if (serio_raw->dead) |
181 | return -ENODEV; | 182 | return -ENODEV; |
182 | 183 | ||
183 | while (retval < count && serio_raw_fetch_byte(serio_raw, &c)) { | 184 | while (read < count && serio_raw_fetch_byte(serio_raw, &c)) { |
184 | if (put_user(c, buffer++)) | 185 | if (put_user(c, buffer++)) { |
185 | return -EFAULT; | 186 | retval = -EFAULT; |
186 | retval++; | 187 | break; |
188 | } | ||
189 | read++; | ||
187 | } | 190 | } |
188 | 191 | ||
189 | return retval; | 192 | return read ?: retval; |
190 | } | 193 | } |
191 | 194 | ||
192 | static ssize_t serio_raw_write(struct file *file, const char __user *buffer, | 195 | static ssize_t serio_raw_write(struct file *file, const char __user *buffer, |