diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-15 19:43:53 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-15 19:43:53 -0500 |
commit | 4937e2a6f939a41bf811378e80d71f68aa0950c6 (patch) | |
tree | ed8ac843c96f01cd054542169afc968ec5d96189 /drivers/input/serio | |
parent | db0b2d01163cc3050eb52a979541e0d16553be48 (diff) | |
parent | 42249094f79422fbf5ed4b54eeb48ff096809b8f (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov:
"Updates for the input subsystem. You will get an new drivers for
Hyper-V synthetic keyboard and for Neonode zForce touchscreens, plus a
bunch of driver fixes and cleanups"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (49 commits)
Revert "Input: ALPS - add support for model found on Dell XT2"
arm: dts: am335x sk: add touchscreen support
Input: ti_am335x_tsc - fix spelling mistake in TSC/ADC DT binding
Input: cyttsp4 - replace IS_ERR and PTR_ERR with PTR_ERR_OR_ZERO
Input: mma8450 - add missing i2c_set_clientdata() in mma8450_probe()
Input: mpu3050 - add missing i2c_set_clientdata() in mpu3050_probe()
Input: tnetv107x-keypad - make irqs signed for error handling
Input: add driver for Neonode zForce based touchscreens
Input: sh_keysc - enable the driver on all ARM platforms
Input: remove a redundant max() call
Input: mousedev - allow disabling even without CONFIG_EXPERT
Input: allow deselecting serio drivers even without CONFIG_EXPERT
Input: i8042 - add PNP modaliases
Input: evdev - fall back to vmalloc for client event buffer
Input: cypress_ps2 - do not consider data bad if palm is detected
Input: cypress_ps2 - remove useless cast
Input: fix PWM-related undefined reference errors
Input: ALPS - change secondary device's name
Input: wacom - not all multi-interface devices support touch
Input: nspire-keypad - add missing clk_disable_unprepare() on error path
...
Diffstat (limited to 'drivers/input/serio')
-rw-r--r-- | drivers/input/serio/Kconfig | 16 | ||||
-rw-r--r-- | drivers/input/serio/Makefile | 1 | ||||
-rw-r--r-- | drivers/input/serio/hyperv-keyboard.c | 437 | ||||
-rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 2 |
4 files changed, 453 insertions, 3 deletions
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 1de1e5f8f795..8541f949778d 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -2,7 +2,7 @@ | |||
2 | # Input core configuration | 2 | # Input core configuration |
3 | # | 3 | # |
4 | config SERIO | 4 | config SERIO |
5 | tristate "Serial I/O support" if EXPERT || !X86 | 5 | tristate "Serial I/O support" |
6 | default y | 6 | default y |
7 | help | 7 | help |
8 | Say Yes here if you have any input device that uses serial I/O to | 8 | Say Yes here if you have any input device that uses serial I/O to |
@@ -19,7 +19,7 @@ config SERIO | |||
19 | if SERIO | 19 | if SERIO |
20 | 20 | ||
21 | config SERIO_I8042 | 21 | config SERIO_I8042 |
22 | tristate "i8042 PC Keyboard controller" if EXPERT || !X86 | 22 | tristate "i8042 PC Keyboard controller" |
23 | default y | 23 | default y |
24 | depends on !PARISC && (!ARM || FOOTBRIDGE_HOST) && \ | 24 | depends on !PARISC && (!ARM || FOOTBRIDGE_HOST) && \ |
25 | (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN && !S390 && \ | 25 | (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN && !S390 && \ |
@@ -170,7 +170,7 @@ config SERIO_MACEPS2 | |||
170 | module will be called maceps2. | 170 | module will be called maceps2. |
171 | 171 | ||
172 | config SERIO_LIBPS2 | 172 | config SERIO_LIBPS2 |
173 | tristate "PS/2 driver library" if EXPERT | 173 | tristate "PS/2 driver library" |
174 | depends on SERIO_I8042 || SERIO_I8042=n | 174 | depends on SERIO_I8042 || SERIO_I8042=n |
175 | help | 175 | help |
176 | Say Y here if you are using a driver for device connected | 176 | Say Y here if you are using a driver for device connected |
@@ -266,4 +266,14 @@ config SERIO_OLPC_APSP | |||
266 | To compile this driver as a module, choose M here: the module will | 266 | To compile this driver as a module, choose M here: the module will |
267 | be called olpc_apsp. | 267 | be called olpc_apsp. |
268 | 268 | ||
269 | config HYPERV_KEYBOARD | ||
270 | tristate "Microsoft Synthetic Keyboard driver" | ||
271 | depends on HYPERV | ||
272 | default HYPERV | ||
273 | help | ||
274 | Select this option to enable the Hyper-V Keyboard driver. | ||
275 | |||
276 | To compile this driver as a module, choose M here: the module will | ||
277 | be called hyperv_keyboard. | ||
278 | |||
269 | endif | 279 | endif |
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index 12298b1c0e71..815d874fe724 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile | |||
@@ -28,3 +28,4 @@ obj-$(CONFIG_SERIO_ALTERA_PS2) += altera_ps2.o | |||
28 | obj-$(CONFIG_SERIO_ARC_PS2) += arc_ps2.o | 28 | obj-$(CONFIG_SERIO_ARC_PS2) += arc_ps2.o |
29 | obj-$(CONFIG_SERIO_APBPS2) += apbps2.o | 29 | obj-$(CONFIG_SERIO_APBPS2) += apbps2.o |
30 | obj-$(CONFIG_SERIO_OLPC_APSP) += olpc_apsp.o | 30 | obj-$(CONFIG_SERIO_OLPC_APSP) += olpc_apsp.o |
31 | obj-$(CONFIG_HYPERV_KEYBOARD) += hyperv-keyboard.o | ||
diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c new file mode 100644 index 000000000000..3a83c3c14b23 --- /dev/null +++ b/drivers/input/serio/hyperv-keyboard.c | |||
@@ -0,0 +1,437 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013, Microsoft Corporation. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/init.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/completion.h> | ||
18 | #include <linux/hyperv.h> | ||
19 | #include <linux/serio.h> | ||
20 | #include <linux/slab.h> | ||
21 | |||
22 | /* | ||
23 | * Current version 1.0 | ||
24 | * | ||
25 | */ | ||
26 | #define SYNTH_KBD_VERSION_MAJOR 1 | ||
27 | #define SYNTH_KBD_VERSION_MINOR 0 | ||
28 | #define SYNTH_KBD_VERSION (SYNTH_KBD_VERSION_MINOR | \ | ||
29 | (SYNTH_KBD_VERSION_MAJOR << 16)) | ||
30 | |||
31 | |||
32 | /* | ||
33 | * Message types in the synthetic input protocol | ||
34 | */ | ||
35 | enum synth_kbd_msg_type { | ||
36 | SYNTH_KBD_PROTOCOL_REQUEST = 1, | ||
37 | SYNTH_KBD_PROTOCOL_RESPONSE = 2, | ||
38 | SYNTH_KBD_EVENT = 3, | ||
39 | SYNTH_KBD_LED_INDICATORS = 4, | ||
40 | }; | ||
41 | |||
42 | /* | ||
43 | * Basic message structures. | ||
44 | */ | ||
45 | struct synth_kbd_msg_hdr { | ||
46 | __le32 type; | ||
47 | }; | ||
48 | |||
49 | struct synth_kbd_msg { | ||
50 | struct synth_kbd_msg_hdr header; | ||
51 | char data[]; /* Enclosed message */ | ||
52 | }; | ||
53 | |||
54 | union synth_kbd_version { | ||
55 | __le32 version; | ||
56 | }; | ||
57 | |||
58 | /* | ||
59 | * Protocol messages | ||
60 | */ | ||
61 | struct synth_kbd_protocol_request { | ||
62 | struct synth_kbd_msg_hdr header; | ||
63 | union synth_kbd_version version_requested; | ||
64 | }; | ||
65 | |||
66 | #define PROTOCOL_ACCEPTED BIT(0) | ||
67 | struct synth_kbd_protocol_response { | ||
68 | struct synth_kbd_msg_hdr header; | ||
69 | __le32 proto_status; | ||
70 | }; | ||
71 | |||
72 | #define IS_UNICODE BIT(0) | ||
73 | #define IS_BREAK BIT(1) | ||
74 | #define IS_E0 BIT(2) | ||
75 | #define IS_E1 BIT(3) | ||
76 | struct synth_kbd_keystroke { | ||
77 | struct synth_kbd_msg_hdr header; | ||
78 | __le16 make_code; | ||
79 | __le16 reserved0; | ||
80 | __le32 info; /* Additional information */ | ||
81 | }; | ||
82 | |||
83 | |||
84 | #define HK_MAXIMUM_MESSAGE_SIZE 256 | ||
85 | |||
86 | #define KBD_VSC_SEND_RING_BUFFER_SIZE (10 * PAGE_SIZE) | ||
87 | #define KBD_VSC_RECV_RING_BUFFER_SIZE (10 * PAGE_SIZE) | ||
88 | |||
89 | #define XTKBD_EMUL0 0xe0 | ||
90 | #define XTKBD_EMUL1 0xe1 | ||
91 | #define XTKBD_RELEASE 0x80 | ||
92 | |||
93 | |||
94 | /* | ||
95 | * Represents a keyboard device | ||
96 | */ | ||
97 | struct hv_kbd_dev { | ||
98 | struct hv_device *hv_dev; | ||
99 | struct serio *hv_serio; | ||
100 | struct synth_kbd_protocol_request protocol_req; | ||
101 | struct synth_kbd_protocol_response protocol_resp; | ||
102 | /* Synchronize the request/response if needed */ | ||
103 | struct completion wait_event; | ||
104 | spinlock_t lock; /* protects 'started' field */ | ||
105 | bool started; | ||
106 | }; | ||
107 | |||
108 | static void hv_kbd_on_receive(struct hv_device *hv_dev, | ||
109 | struct synth_kbd_msg *msg, u32 msg_length) | ||
110 | { | ||
111 | struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev); | ||
112 | struct synth_kbd_keystroke *ks_msg; | ||
113 | unsigned long flags; | ||
114 | u32 msg_type = __le32_to_cpu(msg->header.type); | ||
115 | u32 info; | ||
116 | u16 scan_code; | ||
117 | |||
118 | switch (msg_type) { | ||
119 | case SYNTH_KBD_PROTOCOL_RESPONSE: | ||
120 | /* | ||
121 | * Validate the information provided by the host. | ||
122 | * If the host is giving us a bogus packet, | ||
123 | * drop the packet (hoping the problem | ||
124 | * goes away). | ||
125 | */ | ||
126 | if (msg_length < sizeof(struct synth_kbd_protocol_response)) { | ||
127 | dev_err(&hv_dev->device, | ||
128 | "Illegal protocol response packet (len: %d)\n", | ||
129 | msg_length); | ||
130 | break; | ||
131 | } | ||
132 | |||
133 | memcpy(&kbd_dev->protocol_resp, msg, | ||
134 | sizeof(struct synth_kbd_protocol_response)); | ||
135 | complete(&kbd_dev->wait_event); | ||
136 | break; | ||
137 | |||
138 | case SYNTH_KBD_EVENT: | ||
139 | /* | ||
140 | * Validate the information provided by the host. | ||
141 | * If the host is giving us a bogus packet, | ||
142 | * drop the packet (hoping the problem | ||
143 | * goes away). | ||
144 | */ | ||
145 | if (msg_length < sizeof(struct synth_kbd_keystroke)) { | ||
146 | dev_err(&hv_dev->device, | ||
147 | "Illegal keyboard event packet (len: %d)\n", | ||
148 | msg_length); | ||
149 | break; | ||
150 | } | ||
151 | |||
152 | ks_msg = (struct synth_kbd_keystroke *)msg; | ||
153 | info = __le32_to_cpu(ks_msg->info); | ||
154 | |||
155 | /* | ||
156 | * Inject the information through the serio interrupt. | ||
157 | */ | ||
158 | spin_lock_irqsave(&kbd_dev->lock, flags); | ||
159 | if (kbd_dev->started) { | ||
160 | if (info & IS_E0) | ||
161 | serio_interrupt(kbd_dev->hv_serio, | ||
162 | XTKBD_EMUL0, 0); | ||
163 | |||
164 | scan_code = __le16_to_cpu(ks_msg->make_code); | ||
165 | if (info & IS_BREAK) | ||
166 | scan_code |= XTKBD_RELEASE; | ||
167 | |||
168 | serio_interrupt(kbd_dev->hv_serio, scan_code, 0); | ||
169 | } | ||
170 | spin_unlock_irqrestore(&kbd_dev->lock, flags); | ||
171 | break; | ||
172 | |||
173 | default: | ||
174 | dev_err(&hv_dev->device, | ||
175 | "unhandled message type %d\n", msg_type); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | static void hv_kbd_handle_received_packet(struct hv_device *hv_dev, | ||
180 | struct vmpacket_descriptor *desc, | ||
181 | u32 bytes_recvd, | ||
182 | u64 req_id) | ||
183 | { | ||
184 | struct synth_kbd_msg *msg; | ||
185 | u32 msg_sz; | ||
186 | |||
187 | switch (desc->type) { | ||
188 | case VM_PKT_COMP: | ||
189 | break; | ||
190 | |||
191 | case VM_PKT_DATA_INBAND: | ||
192 | /* | ||
193 | * We have a packet that has "inband" data. The API used | ||
194 | * for retrieving the packet guarantees that the complete | ||
195 | * packet is read. So, minimally, we should be able to | ||
196 | * parse the payload header safely (assuming that the host | ||
197 | * can be trusted. Trusting the host seems to be a | ||
198 | * reasonable assumption because in a virtualized | ||
199 | * environment there is not whole lot you can do if you | ||
200 | * don't trust the host. | ||
201 | * | ||
202 | * Nonetheless, let us validate if the host can be trusted | ||
203 | * (in a trivial way). The interesting aspect of this | ||
204 | * validation is how do you recover if we discover that the | ||
205 | * host is not to be trusted? Simply dropping the packet, I | ||
206 | * don't think is an appropriate recovery. In the interest | ||
207 | * of failing fast, it may be better to crash the guest. | ||
208 | * For now, I will just drop the packet! | ||
209 | */ | ||
210 | |||
211 | msg_sz = bytes_recvd - (desc->offset8 << 3); | ||
212 | if (msg_sz <= sizeof(struct synth_kbd_msg_hdr)) { | ||
213 | /* | ||
214 | * Drop the packet and hope | ||
215 | * the problem magically goes away. | ||
216 | */ | ||
217 | dev_err(&hv_dev->device, | ||
218 | "Illegal packet (type: %d, tid: %llx, size: %d)\n", | ||
219 | desc->type, req_id, msg_sz); | ||
220 | break; | ||
221 | } | ||
222 | |||
223 | msg = (void *)desc + (desc->offset8 << 3); | ||
224 | hv_kbd_on_receive(hv_dev, msg, msg_sz); | ||
225 | break; | ||
226 | |||
227 | default: | ||
228 | dev_err(&hv_dev->device, | ||
229 | "unhandled packet type %d, tid %llx len %d\n", | ||
230 | desc->type, req_id, bytes_recvd); | ||
231 | break; | ||
232 | } | ||
233 | } | ||
234 | |||
235 | static void hv_kbd_on_channel_callback(void *context) | ||
236 | { | ||
237 | struct hv_device *hv_dev = context; | ||
238 | void *buffer; | ||
239 | int bufferlen = 0x100; /* Start with sensible size */ | ||
240 | u32 bytes_recvd; | ||
241 | u64 req_id; | ||
242 | int error; | ||
243 | |||
244 | buffer = kmalloc(bufferlen, GFP_ATOMIC); | ||
245 | if (!buffer) | ||
246 | return; | ||
247 | |||
248 | while (1) { | ||
249 | error = vmbus_recvpacket_raw(hv_dev->channel, buffer, bufferlen, | ||
250 | &bytes_recvd, &req_id); | ||
251 | switch (error) { | ||
252 | case 0: | ||
253 | if (bytes_recvd == 0) { | ||
254 | kfree(buffer); | ||
255 | return; | ||
256 | } | ||
257 | |||
258 | hv_kbd_handle_received_packet(hv_dev, buffer, | ||
259 | bytes_recvd, req_id); | ||
260 | break; | ||
261 | |||
262 | case -ENOBUFS: | ||
263 | kfree(buffer); | ||
264 | /* Handle large packet */ | ||
265 | bufferlen = bytes_recvd; | ||
266 | buffer = kmalloc(bytes_recvd, GFP_ATOMIC); | ||
267 | if (!buffer) | ||
268 | return; | ||
269 | break; | ||
270 | } | ||
271 | } | ||
272 | } | ||
273 | |||
274 | static int hv_kbd_connect_to_vsp(struct hv_device *hv_dev) | ||
275 | { | ||
276 | struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev); | ||
277 | struct synth_kbd_protocol_request *request; | ||
278 | struct synth_kbd_protocol_response *response; | ||
279 | u32 proto_status; | ||
280 | int error; | ||
281 | |||
282 | request = &kbd_dev->protocol_req; | ||
283 | memset(request, 0, sizeof(struct synth_kbd_protocol_request)); | ||
284 | request->header.type = __cpu_to_le32(SYNTH_KBD_PROTOCOL_REQUEST); | ||
285 | request->version_requested.version = __cpu_to_le32(SYNTH_KBD_VERSION); | ||
286 | |||
287 | error = vmbus_sendpacket(hv_dev->channel, request, | ||
288 | sizeof(struct synth_kbd_protocol_request), | ||
289 | (unsigned long)request, | ||
290 | VM_PKT_DATA_INBAND, | ||
291 | VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); | ||
292 | if (error) | ||
293 | return error; | ||
294 | |||
295 | if (!wait_for_completion_timeout(&kbd_dev->wait_event, 10 * HZ)) | ||
296 | return -ETIMEDOUT; | ||
297 | |||
298 | response = &kbd_dev->protocol_resp; | ||
299 | proto_status = __le32_to_cpu(response->proto_status); | ||
300 | if (!(proto_status & PROTOCOL_ACCEPTED)) { | ||
301 | dev_err(&hv_dev->device, | ||
302 | "synth_kbd protocol request failed (version %d)\n", | ||
303 | SYNTH_KBD_VERSION); | ||
304 | return -ENODEV; | ||
305 | } | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | static int hv_kbd_start(struct serio *serio) | ||
311 | { | ||
312 | struct hv_kbd_dev *kbd_dev = serio->port_data; | ||
313 | unsigned long flags; | ||
314 | |||
315 | spin_lock_irqsave(&kbd_dev->lock, flags); | ||
316 | kbd_dev->started = true; | ||
317 | spin_unlock_irqrestore(&kbd_dev->lock, flags); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static void hv_kbd_stop(struct serio *serio) | ||
323 | { | ||
324 | struct hv_kbd_dev *kbd_dev = serio->port_data; | ||
325 | unsigned long flags; | ||
326 | |||
327 | spin_lock_irqsave(&kbd_dev->lock, flags); | ||
328 | kbd_dev->started = false; | ||
329 | spin_unlock_irqrestore(&kbd_dev->lock, flags); | ||
330 | } | ||
331 | |||
332 | static int hv_kbd_probe(struct hv_device *hv_dev, | ||
333 | const struct hv_vmbus_device_id *dev_id) | ||
334 | { | ||
335 | struct hv_kbd_dev *kbd_dev; | ||
336 | struct serio *hv_serio; | ||
337 | int error; | ||
338 | |||
339 | kbd_dev = kzalloc(sizeof(struct hv_kbd_dev), GFP_KERNEL); | ||
340 | hv_serio = kzalloc(sizeof(struct serio), GFP_KERNEL); | ||
341 | if (!kbd_dev || !hv_serio) { | ||
342 | error = -ENOMEM; | ||
343 | goto err_free_mem; | ||
344 | } | ||
345 | |||
346 | kbd_dev->hv_dev = hv_dev; | ||
347 | kbd_dev->hv_serio = hv_serio; | ||
348 | spin_lock_init(&kbd_dev->lock); | ||
349 | init_completion(&kbd_dev->wait_event); | ||
350 | hv_set_drvdata(hv_dev, kbd_dev); | ||
351 | |||
352 | hv_serio->dev.parent = &hv_dev->device; | ||
353 | hv_serio->id.type = SERIO_8042_XL; | ||
354 | hv_serio->port_data = kbd_dev; | ||
355 | strlcpy(hv_serio->name, dev_name(&hv_dev->device), | ||
356 | sizeof(hv_serio->name)); | ||
357 | strlcpy(hv_serio->phys, dev_name(&hv_dev->device), | ||
358 | sizeof(hv_serio->phys)); | ||
359 | |||
360 | hv_serio->start = hv_kbd_start; | ||
361 | hv_serio->stop = hv_kbd_stop; | ||
362 | |||
363 | error = vmbus_open(hv_dev->channel, | ||
364 | KBD_VSC_SEND_RING_BUFFER_SIZE, | ||
365 | KBD_VSC_RECV_RING_BUFFER_SIZE, | ||
366 | NULL, 0, | ||
367 | hv_kbd_on_channel_callback, | ||
368 | hv_dev); | ||
369 | if (error) | ||
370 | goto err_free_mem; | ||
371 | |||
372 | error = hv_kbd_connect_to_vsp(hv_dev); | ||
373 | if (error) | ||
374 | goto err_close_vmbus; | ||
375 | |||
376 | serio_register_port(kbd_dev->hv_serio); | ||
377 | return 0; | ||
378 | |||
379 | err_close_vmbus: | ||
380 | vmbus_close(hv_dev->channel); | ||
381 | err_free_mem: | ||
382 | kfree(hv_serio); | ||
383 | kfree(kbd_dev); | ||
384 | return error; | ||
385 | } | ||
386 | |||
387 | static int hv_kbd_remove(struct hv_device *hv_dev) | ||
388 | { | ||
389 | struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev); | ||
390 | |||
391 | serio_unregister_port(kbd_dev->hv_serio); | ||
392 | vmbus_close(hv_dev->channel); | ||
393 | kfree(kbd_dev); | ||
394 | |||
395 | hv_set_drvdata(hv_dev, NULL); | ||
396 | |||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | /* | ||
401 | * Keyboard GUID | ||
402 | * {f912ad6d-2b17-48ea-bd65-f927a61c7684} | ||
403 | */ | ||
404 | #define HV_KBD_GUID \ | ||
405 | .guid = { \ | ||
406 | 0x6d, 0xad, 0x12, 0xf9, 0x17, 0x2b, 0xea, 0x48, \ | ||
407 | 0xbd, 0x65, 0xf9, 0x27, 0xa6, 0x1c, 0x76, 0x84 \ | ||
408 | } | ||
409 | |||
410 | static const struct hv_vmbus_device_id id_table[] = { | ||
411 | /* Keyboard guid */ | ||
412 | { HV_KBD_GUID, }, | ||
413 | { }, | ||
414 | }; | ||
415 | |||
416 | MODULE_DEVICE_TABLE(vmbus, id_table); | ||
417 | |||
418 | static struct hv_driver hv_kbd_drv = { | ||
419 | .name = KBUILD_MODNAME, | ||
420 | .id_table = id_table, | ||
421 | .probe = hv_kbd_probe, | ||
422 | .remove = hv_kbd_remove, | ||
423 | }; | ||
424 | |||
425 | static int __init hv_kbd_init(void) | ||
426 | { | ||
427 | return vmbus_driver_register(&hv_kbd_drv); | ||
428 | } | ||
429 | |||
430 | static void __exit hv_kbd_exit(void) | ||
431 | { | ||
432 | vmbus_driver_unregister(&hv_kbd_drv); | ||
433 | } | ||
434 | |||
435 | MODULE_LICENSE("GPL"); | ||
436 | module_init(hv_kbd_init); | ||
437 | module_exit(hv_kbd_exit); | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 5f306f79da0c..0ec9abbe31fe 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -765,6 +765,7 @@ static struct pnp_device_id pnp_kbd_devids[] = { | |||
765 | { .id = "CPQA0D7", .driver_data = 0 }, | 765 | { .id = "CPQA0D7", .driver_data = 0 }, |
766 | { .id = "", }, | 766 | { .id = "", }, |
767 | }; | 767 | }; |
768 | MODULE_DEVICE_TABLE(pnp, pnp_kbd_devids); | ||
768 | 769 | ||
769 | static struct pnp_driver i8042_pnp_kbd_driver = { | 770 | static struct pnp_driver i8042_pnp_kbd_driver = { |
770 | .name = "i8042 kbd", | 771 | .name = "i8042 kbd", |
@@ -786,6 +787,7 @@ static struct pnp_device_id pnp_aux_devids[] = { | |||
786 | { .id = "SYN0801", .driver_data = 0 }, | 787 | { .id = "SYN0801", .driver_data = 0 }, |
787 | { .id = "", }, | 788 | { .id = "", }, |
788 | }; | 789 | }; |
790 | MODULE_DEVICE_TABLE(pnp, pnp_aux_devids); | ||
789 | 791 | ||
790 | static struct pnp_driver i8042_pnp_aux_driver = { | 792 | static struct pnp_driver i8042_pnp_aux_driver = { |
791 | .name = "i8042 aux", | 793 | .name = "i8042 aux", |