aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-01-07 14:29:51 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-07 14:29:51 -0500
commitb9abaa3fb7328851bdeaad19e694048f0ff71d9a (patch)
treede56cda929b837c6b2e421b57c723939ec7df5da /drivers/input
parent8995b161eb142b843094dd614b80e4cce1d66352 (diff)
parent736ce43295682d060f2b93624b4a339f9af6aab1 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/evdev.c493
-rw-r--r--drivers/input/gameport/Kconfig7
-rw-r--r--drivers/input/keyboard/atkbd.c2
-rw-r--r--drivers/input/misc/m68kspkr.c102
-rw-r--r--drivers/input/misc/pcspkr.c86
-rw-r--r--drivers/input/misc/sparcspkr.c162
-rw-r--r--drivers/input/misc/wistron_btns.c133
-rw-r--r--drivers/input/mouse/alps.c1
-rw-r--r--drivers/input/mouse/lifebook.c7
-rw-r--r--drivers/input/mouse/logips2pp.c2
-rw-r--r--drivers/input/mouse/psmouse-base.c15
-rw-r--r--drivers/input/mousedev.c10
-rw-r--r--drivers/input/serio/ct82c710.c89
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h15
-rw-r--r--drivers/input/serio/i8042.c116
-rw-r--r--drivers/input/serio/maceps2.c68
-rw-r--r--drivers/input/serio/q40kbd.c89
17 files changed, 853 insertions, 544 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index a1e660e3531d..f7490a015d18 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -146,6 +146,7 @@ static int evdev_open(struct inode * inode, struct file * file)
146} 146}
147 147
148#ifdef CONFIG_COMPAT 148#ifdef CONFIG_COMPAT
149
149struct input_event_compat { 150struct input_event_compat {
150 struct compat_timeval time; 151 struct compat_timeval time;
151 __u16 type; 152 __u16 type;
@@ -165,98 +166,107 @@ struct input_event_compat {
165# define COMPAT_TEST test_thread_flag(TIF_32BIT) 166# define COMPAT_TEST test_thread_flag(TIF_32BIT)
166#endif 167#endif
167 168
168static ssize_t evdev_write_compat(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) 169static inline size_t evdev_event_size(void)
169{ 170{
170 struct evdev_list *list = file->private_data; 171 return COMPAT_TEST ?
171 struct input_event_compat event; 172 sizeof(struct input_event_compat) : sizeof(struct input_event);
172 int retval = 0; 173}
173 174
174 while (retval < count) { 175static int evdev_event_from_user(const char __user *buffer, struct input_event *event)
175 if (copy_from_user(&event, buffer + retval, sizeof(struct input_event_compat))) 176{
177 if (COMPAT_TEST) {
178 struct input_event_compat compat_event;
179
180 if (copy_from_user(&compat_event, buffer, sizeof(struct input_event_compat)))
181 return -EFAULT;
182
183 event->time.tv_sec = compat_event.time.tv_sec;
184 event->time.tv_usec = compat_event.time.tv_usec;
185 event->type = compat_event.type;
186 event->code = compat_event.code;
187 event->value = compat_event.value;
188
189 } else {
190 if (copy_from_user(event, buffer, sizeof(struct input_event)))
176 return -EFAULT; 191 return -EFAULT;
177 input_event(list->evdev->handle.dev, event.type, event.code, event.value);
178 retval += sizeof(struct input_event_compat);
179 } 192 }
180 193
181 return retval; 194 return 0;
182} 195}
183#endif
184 196
185static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) 197static int evdev_event_to_user(char __user *buffer, const struct input_event *event)
186{ 198{
187 struct evdev_list *list = file->private_data; 199 if (COMPAT_TEST) {
188 struct input_event event; 200 struct input_event_compat compat_event;
189 int retval = 0;
190
191 if (!list->evdev->exist) return -ENODEV;
192 201
193#ifdef CONFIG_COMPAT 202 compat_event.time.tv_sec = event->time.tv_sec;
194 if (COMPAT_TEST) 203 compat_event.time.tv_usec = event->time.tv_usec;
195 return evdev_write_compat(file, buffer, count, ppos); 204 compat_event.type = event->type;
196#endif 205 compat_event.code = event->code;
206 compat_event.value = event->value;
197 207
198 while (retval < count) { 208 if (copy_to_user(buffer, &compat_event, sizeof(struct input_event_compat)))
209 return -EFAULT;
199 210
200 if (copy_from_user(&event, buffer + retval, sizeof(struct input_event))) 211 } else {
212 if (copy_to_user(buffer, event, sizeof(struct input_event)))
201 return -EFAULT; 213 return -EFAULT;
202 input_event(list->evdev->handle.dev, event.type, event.code, event.value);
203 retval += sizeof(struct input_event);
204 } 214 }
205 215
206 return retval; 216 return 0;
207} 217}
208 218
209#ifdef CONFIG_COMPAT 219#else
210static ssize_t evdev_read_compat(struct file * file, char __user * buffer, size_t count, loff_t *ppos) 220
221static inline size_t evdev_event_size(void)
211{ 222{
212 struct evdev_list *list = file->private_data; 223 return sizeof(struct input_event);
213 int retval; 224}
214 225
215 if (count < sizeof(struct input_event_compat)) 226static int evdev_event_from_user(const char __user *buffer, struct input_event *event)
216 return -EINVAL; 227{
228 if (copy_from_user(event, buffer, sizeof(struct input_event)))
229 return -EFAULT;
217 230
218 if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK)) 231 return 0;
219 return -EAGAIN; 232}
220 233
221 retval = wait_event_interruptible(list->evdev->wait, 234static int evdev_event_to_user(char __user *buffer, const struct input_event *event)
222 list->head != list->tail || (!list->evdev->exist)); 235{
236 if (copy_to_user(buffer, event, sizeof(struct input_event)))
237 return -EFAULT;
223 238
224 if (retval) 239 return 0;
225 return retval; 240}
241
242#endif /* CONFIG_COMPAT */
243
244static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
245{
246 struct evdev_list *list = file->private_data;
247 struct input_event event;
248 int retval = 0;
226 249
227 if (!list->evdev->exist) 250 if (!list->evdev->exist)
228 return -ENODEV; 251 return -ENODEV;
229 252
230 while (list->head != list->tail && retval + sizeof(struct input_event_compat) <= count) { 253 while (retval < count) {
231 struct input_event *event = (struct input_event *) list->buffer + list->tail; 254
232 struct input_event_compat event_compat; 255 if (evdev_event_from_user(buffer + retval, &event))
233 event_compat.time.tv_sec = event->time.tv_sec; 256 return -EFAULT;
234 event_compat.time.tv_usec = event->time.tv_usec; 257 input_event(list->evdev->handle.dev, event.type, event.code, event.value);
235 event_compat.type = event->type; 258 retval += evdev_event_size();
236 event_compat.code = event->code;
237 event_compat.value = event->value;
238
239 if (copy_to_user(buffer + retval, &event_compat,
240 sizeof(struct input_event_compat))) return -EFAULT;
241 list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
242 retval += sizeof(struct input_event_compat);
243 } 259 }
244 260
245 return retval; 261 return retval;
246} 262}
247#endif
248 263
249static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) 264static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
250{ 265{
251 struct evdev_list *list = file->private_data; 266 struct evdev_list *list = file->private_data;
252 int retval; 267 int retval;
253 268
254#ifdef CONFIG_COMPAT 269 if (count < evdev_event_size())
255 if (COMPAT_TEST)
256 return evdev_read_compat(file, buffer, count, ppos);
257#endif
258
259 if (count < sizeof(struct input_event))
260 return -EINVAL; 270 return -EINVAL;
261 271
262 if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK)) 272 if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK))
@@ -271,11 +281,15 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count
271 if (!list->evdev->exist) 281 if (!list->evdev->exist)
272 return -ENODEV; 282 return -ENODEV;
273 283
274 while (list->head != list->tail && retval + sizeof(struct input_event) <= count) { 284 while (list->head != list->tail && retval + evdev_event_size() <= count) {
275 if (copy_to_user(buffer + retval, list->buffer + list->tail, 285
276 sizeof(struct input_event))) return -EFAULT; 286 struct input_event *event = (struct input_event *) list->buffer + list->tail;
287
288 if (evdev_event_to_user(buffer + retval, event))
289 return -EFAULT;
290
277 list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1); 291 list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
278 retval += sizeof(struct input_event); 292 retval += evdev_event_size();
279 } 293 }
280 294
281 return retval; 295 return retval;
@@ -290,17 +304,95 @@ static unsigned int evdev_poll(struct file *file, poll_table *wait)
290 (list->evdev->exist ? 0 : (POLLHUP | POLLERR)); 304 (list->evdev->exist ? 0 : (POLLHUP | POLLERR));
291} 305}
292 306
293static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 307#ifdef CONFIG_COMPAT
308
309#define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8)
310#define NBITS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1)
311
312#ifdef __BIG_ENDIAN
313static int bits_to_user(unsigned long *bits, unsigned int maxbit,
314 unsigned int maxlen, void __user *p, int compat)
315{
316 int len, i;
317
318 if (compat) {
319 len = NBITS_COMPAT(maxbit) * sizeof(compat_long_t);
320 if (len < maxlen)
321 len = maxlen;
322
323 for (i = 0; i < len / sizeof(compat_long_t); i++)
324 if (copy_to_user((compat_long_t __user *) p + i,
325 (compat_long_t *) bits +
326 i + 1 - ((i % 2) << 1),
327 sizeof(compat_long_t)))
328 return -EFAULT;
329 } else {
330 len = NBITS(maxbit) * sizeof(long);
331 if (len > maxlen)
332 len = maxlen;
333
334 if (copy_to_user(p, bits, len))
335 return -EFAULT;
336 }
337
338 return len;
339}
340#else
341static int bits_to_user(unsigned long *bits, unsigned int maxbit,
342 unsigned int maxlen, void __user *p, int compat)
343{
344 int len = compat ?
345 NBITS_COMPAT(maxbit) * sizeof(compat_long_t) :
346 NBITS(maxbit) * sizeof(long);
347
348 if (len > maxlen)
349 len = maxlen;
350
351 return copy_to_user(p, bits, len) ? -EFAULT : len;
352}
353#endif /* __BIG_ENDIAN */
354
355#else
356
357static int bits_to_user(unsigned long *bits, unsigned int maxbit,
358 unsigned int maxlen, void __user *p, int compat)
359{
360 int len = NBITS(maxbit) * sizeof(long);
361
362 if (len > maxlen)
363 len = maxlen;
364
365 return copy_to_user(p, bits, len) ? -EFAULT : len;
366}
367
368#endif /* CONFIG_COMPAT */
369
370static int str_to_user(const char *str, unsigned int maxlen, void __user *p)
371{
372 int len;
373
374 if (!str)
375 return -ENOENT;
376
377 len = strlen(str) + 1;
378 if (len > maxlen)
379 len = maxlen;
380
381 return copy_to_user(p, str, len) ? -EFAULT : len;
382}
383
384static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
385 void __user *p, int compat_mode)
294{ 386{
295 struct evdev_list *list = file->private_data; 387 struct evdev_list *list = file->private_data;
296 struct evdev *evdev = list->evdev; 388 struct evdev *evdev = list->evdev;
297 struct input_dev *dev = evdev->handle.dev; 389 struct input_dev *dev = evdev->handle.dev;
298 struct input_absinfo abs; 390 struct input_absinfo abs;
299 void __user *p = (void __user *)arg; 391 int __user *ip = (int __user *)p;
300 int __user *ip = (int __user *)arg;
301 int i, t, u, v; 392 int i, t, u, v;
302 393
303 if (!evdev->exist) return -ENODEV; 394 if (!evdev->exist)
395 return -ENODEV;
304 396
305 switch (cmd) { 397 switch (cmd) {
306 398
@@ -308,26 +400,39 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
308 return put_user(EV_VERSION, ip); 400 return put_user(EV_VERSION, ip);
309 401
310 case EVIOCGID: 402 case EVIOCGID:
311 return copy_to_user(p, &dev->id, sizeof(struct input_id)) ? -EFAULT : 0; 403 if (copy_to_user(p, &dev->id, sizeof(struct input_id)))
404 return -EFAULT;
405
406 return 0;
312 407
313 case EVIOCGKEYCODE: 408 case EVIOCGKEYCODE:
314 if (get_user(t, ip)) return -EFAULT; 409 if (get_user(t, ip))
315 if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL; 410 return -EFAULT;
316 if (put_user(INPUT_KEYCODE(dev, t), ip + 1)) return -EFAULT; 411 if (t < 0 || t >= dev->keycodemax || !dev->keycodesize)
412 return -EINVAL;
413 if (put_user(INPUT_KEYCODE(dev, t), ip + 1))
414 return -EFAULT;
317 return 0; 415 return 0;
318 416
319 case EVIOCSKEYCODE: 417 case EVIOCSKEYCODE:
320 if (get_user(t, ip)) return -EFAULT; 418 if (get_user(t, ip))
321 if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL; 419 return -EFAULT;
322 if (get_user(v, ip + 1)) return -EFAULT; 420 if (t < 0 || t >= dev->keycodemax || !dev->keycodesize)
323 if (v < 0 || v > KEY_MAX) return -EINVAL; 421 return -EINVAL;
324 if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8))) return -EINVAL; 422 if (get_user(v, ip + 1))
423 return -EFAULT;
424 if (v < 0 || v > KEY_MAX)
425 return -EINVAL;
426 if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8)))
427 return -EINVAL;
428
325 u = SET_INPUT_KEYCODE(dev, t, v); 429 u = SET_INPUT_KEYCODE(dev, t, v);
326 clear_bit(u, dev->keybit); 430 clear_bit(u, dev->keybit);
327 set_bit(v, dev->keybit); 431 set_bit(v, dev->keybit);
328 for (i = 0; i < dev->keycodemax; i++) 432 for (i = 0; i < dev->keycodemax; i++)
329 if (INPUT_KEYCODE(dev,i) == u) 433 if (INPUT_KEYCODE(dev, i) == u)
330 set_bit(u, dev->keybit); 434 set_bit(u, dev->keybit);
435
331 return 0; 436 return 0;
332 437
333 case EVIOCSFF: 438 case EVIOCSFF:
@@ -338,17 +443,17 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
338 if (copy_from_user(&effect, p, sizeof(effect))) 443 if (copy_from_user(&effect, p, sizeof(effect)))
339 return -EFAULT; 444 return -EFAULT;
340 err = dev->upload_effect(dev, &effect); 445 err = dev->upload_effect(dev, &effect);
341 if (put_user(effect.id, &(((struct ff_effect __user *)arg)->id))) 446 if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
342 return -EFAULT; 447 return -EFAULT;
343 return err; 448 return err;
344 } 449 } else
345 else return -ENOSYS; 450 return -ENOSYS;
346 451
347 case EVIOCRMFF: 452 case EVIOCRMFF:
348 if (dev->erase_effect) { 453 if (!dev->erase_effect)
349 return dev->erase_effect(dev, (int)arg); 454 return -ENOSYS;
350 } 455
351 else return -ENOSYS; 456 return dev->erase_effect(dev, (int)(unsigned long) p);
352 457
353 case EVIOCGEFFECTS: 458 case EVIOCGEFFECTS:
354 if (put_user(dev->ff_effects_max, ip)) 459 if (put_user(dev->ff_effects_max, ip))
@@ -356,7 +461,7 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
356 return 0; 461 return 0;
357 462
358 case EVIOCGRAB: 463 case EVIOCGRAB:
359 if (arg) { 464 if (p) {
360 if (evdev->grab) 465 if (evdev->grab)
361 return -EBUSY; 466 return -EBUSY;
362 if (input_grab_device(&evdev->handle)) 467 if (input_grab_device(&evdev->handle))
@@ -395,62 +500,33 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
395 case EV_SW: bits = dev->swbit; len = SW_MAX; break; 500 case EV_SW: bits = dev->swbit; len = SW_MAX; break;
396 default: return -EINVAL; 501 default: return -EINVAL;
397 } 502 }
398 len = NBITS(len) * sizeof(long); 503 return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode);
399 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
400 return copy_to_user(p, bits, len) ? -EFAULT : len;
401 } 504 }
402 505
403 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) { 506 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
404 int len; 507 return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd),
405 len = NBITS(KEY_MAX) * sizeof(long); 508 p, compat_mode);
406 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
407 return copy_to_user(p, dev->key, len) ? -EFAULT : len;
408 }
409 509
410 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) { 510 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
411 int len; 511 return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd),
412 len = NBITS(LED_MAX) * sizeof(long); 512 p, compat_mode);
413 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
414 return copy_to_user(p, dev->led, len) ? -EFAULT : len;
415 }
416 513
417 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) { 514 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
418 int len; 515 return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd),
419 len = NBITS(SND_MAX) * sizeof(long); 516 p, compat_mode);
420 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
421 return copy_to_user(p, dev->snd, len) ? -EFAULT : len;
422 }
423 517
424 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) { 518 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
425 int len; 519 return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd),
426 len = NBITS(SW_MAX) * sizeof(long); 520 p, compat_mode);
427 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
428 return copy_to_user(p, dev->sw, len) ? -EFAULT : len;
429 }
430 521
431 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) { 522 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0)))
432 int len; 523 return str_to_user(dev->name, _IOC_SIZE(cmd), p);
433 if (!dev->name) return -ENOENT;
434 len = strlen(dev->name) + 1;
435 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
436 return copy_to_user(p, dev->name, len) ? -EFAULT : len;
437 }
438 524
439 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) { 525 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0)))
440 int len; 526 return str_to_user(dev->phys, _IOC_SIZE(cmd), p);
441 if (!dev->phys) return -ENOENT;
442 len = strlen(dev->phys) + 1;
443 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
444 return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
445 }
446 527
447 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) { 528 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0)))
448 int len; 529 return str_to_user(dev->uniq, _IOC_SIZE(cmd), p);
449 if (!dev->uniq) return -ENOENT;
450 len = strlen(dev->uniq) + 1;
451 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
452 return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
453 }
454 530
455 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { 531 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
456 532
@@ -492,158 +568,15 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
492 return -EINVAL; 568 return -EINVAL;
493} 569}
494 570
495#ifdef CONFIG_COMPAT 571static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
496 572{
497#define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8) 573 return evdev_ioctl_handler(file, cmd, (void __user *)arg, 0);
498#define NBITS_COMPAT(x) ((((x)-1)/BITS_PER_LONG_COMPAT)+1) 574}
499#define OFF_COMPAT(x) ((x)%BITS_PER_LONG_COMPAT)
500#define BIT_COMPAT(x) (1UL<<OFF_COMPAT(x))
501#define LONG_COMPAT(x) ((x)/BITS_PER_LONG_COMPAT)
502#define test_bit_compat(bit, array) ((array[LONG_COMPAT(bit)] >> OFF_COMPAT(bit)) & 1)
503
504#ifdef __BIG_ENDIAN
505#define bit_to_user(bit, max) \
506do { \
507 int i; \
508 int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
509 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
510 for (i = 0; i < len / sizeof(compat_long_t); i++) \
511 if (copy_to_user((compat_long_t __user *) p + i, \
512 (compat_long_t*) (bit) + i + 1 - ((i % 2) << 1), \
513 sizeof(compat_long_t))) \
514 return -EFAULT; \
515 return len; \
516} while (0)
517#else
518#define bit_to_user(bit, max) \
519do { \
520 int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
521 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
522 return copy_to_user(p, (bit), len) ? -EFAULT : len; \
523} while (0)
524#endif
525 575
576#ifdef CONFIG_COMPAT
526static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) 577static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
527{ 578{
528 struct evdev_list *list = file->private_data; 579 return evdev_ioctl_handler(file, cmd, compat_ptr(arg), 1);
529 struct evdev *evdev = list->evdev;
530 struct input_dev *dev = evdev->handle.dev;
531 struct input_absinfo abs;
532 void __user *p = compat_ptr(arg);
533
534 if (!evdev->exist) return -ENODEV;
535
536 switch (cmd) {
537
538 case EVIOCGVERSION:
539 case EVIOCGID:
540 case EVIOCGKEYCODE:
541 case EVIOCSKEYCODE:
542 case EVIOCSFF:
543 case EVIOCRMFF:
544 case EVIOCGEFFECTS:
545 case EVIOCGRAB:
546 return evdev_ioctl(file, cmd, (unsigned long) p);
547
548 default:
549
550 if (_IOC_TYPE(cmd) != 'E')
551 return -EINVAL;
552
553 if (_IOC_DIR(cmd) == _IOC_READ) {
554
555 if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
556 long *bits;
557 int max;
558
559 switch (_IOC_NR(cmd) & EV_MAX) {
560 case 0: bits = dev->evbit; max = EV_MAX; break;
561 case EV_KEY: bits = dev->keybit; max = KEY_MAX; break;
562 case EV_REL: bits = dev->relbit; max = REL_MAX; break;
563 case EV_ABS: bits = dev->absbit; max = ABS_MAX; break;
564 case EV_MSC: bits = dev->mscbit; max = MSC_MAX; break;
565 case EV_LED: bits = dev->ledbit; max = LED_MAX; break;
566 case EV_SND: bits = dev->sndbit; max = SND_MAX; break;
567 case EV_FF: bits = dev->ffbit; max = FF_MAX; break;
568 case EV_SW: bits = dev->swbit; max = SW_MAX; break;
569 default: return -EINVAL;
570 }
571 bit_to_user(bits, max);
572 }
573
574 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
575 bit_to_user(dev->key, KEY_MAX);
576
577 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
578 bit_to_user(dev->led, LED_MAX);
579
580 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
581 bit_to_user(dev->snd, SND_MAX);
582
583 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
584 bit_to_user(dev->sw, SW_MAX);
585
586 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
587 int len;
588 if (!dev->name) return -ENOENT;
589 len = strlen(dev->name) + 1;
590 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
591 return copy_to_user(p, dev->name, len) ? -EFAULT : len;
592 }
593
594 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
595 int len;
596 if (!dev->phys) return -ENOENT;
597 len = strlen(dev->phys) + 1;
598 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
599 return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
600 }
601
602 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
603 int len;
604 if (!dev->uniq) return -ENOENT;
605 len = strlen(dev->uniq) + 1;
606 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
607 return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
608 }
609
610 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
611
612 int t = _IOC_NR(cmd) & ABS_MAX;
613
614 abs.value = dev->abs[t];
615 abs.minimum = dev->absmin[t];
616 abs.maximum = dev->absmax[t];
617 abs.fuzz = dev->absfuzz[t];
618 abs.flat = dev->absflat[t];
619
620 if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
621 return -EFAULT;
622
623 return 0;
624 }
625 }
626
627 if (_IOC_DIR(cmd) == _IOC_WRITE) {
628
629 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
630
631 int t = _IOC_NR(cmd) & ABS_MAX;
632
633 if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
634 return -EFAULT;
635
636 dev->abs[t] = abs.value;
637 dev->absmin[t] = abs.minimum;
638 dev->absmax[t] = abs.maximum;
639 dev->absfuzz[t] = abs.fuzz;
640 dev->absflat[t] = abs.flat;
641
642 return 0;
643 }
644 }
645 }
646 return -EINVAL;
647} 580}
648#endif 581#endif
649 582
diff --git a/drivers/input/gameport/Kconfig b/drivers/input/gameport/Kconfig
index 7524bd7d8b8f..d279454a5c9e 100644
--- a/drivers/input/gameport/Kconfig
+++ b/drivers/input/gameport/Kconfig
@@ -52,5 +52,12 @@ config GAMEPORT_EMU10K1
52config GAMEPORT_FM801 52config GAMEPORT_FM801
53 tristate "ForteMedia FM801 gameport support" 53 tristate "ForteMedia FM801 gameport support"
54 depends on PCI 54 depends on PCI
55 help
56 Say Y here if you have ForteMedia FM801 PCI audio controller
57 (Abit AU10, Genius Sound Maker, HP Workstation zx2000,
58 and others), and want to use its gameport.
59
60 To compile this driver as a module, choose M here: the
61 module will be called fm801-gp.
55 62
56endif 63endif
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index a0256f8de8ef..ffacf6eca5f5 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -321,7 +321,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
321 switch (code) { 321 switch (code) {
322 case ATKBD_RET_BAT: 322 case ATKBD_RET_BAT:
323 atkbd->enabled = 0; 323 atkbd->enabled = 0;
324 serio_rescan(atkbd->ps2dev.serio); 324 serio_reconnect(atkbd->ps2dev.serio);
325 goto out; 325 goto out;
326 case ATKBD_RET_EMUL0: 326 case ATKBD_RET_EMUL0:
327 atkbd->emul = 1; 327 atkbd->emul = 1;
diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c
index 04489ad7702a..8d6c3837badb 100644
--- a/drivers/input/misc/m68kspkr.c
+++ b/drivers/input/misc/m68kspkr.c
@@ -17,6 +17,7 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/input.h> 19#include <linux/input.h>
20#include <linux/platform_device.h>
20#include <asm/machdep.h> 21#include <asm/machdep.h>
21#include <asm/io.h> 22#include <asm/io.h>
22 23
@@ -24,7 +25,7 @@ MODULE_AUTHOR("Richard Zidlicky <rz@linux-m68k.org>");
24MODULE_DESCRIPTION("m68k beeper driver"); 25MODULE_DESCRIPTION("m68k beeper driver");
25MODULE_LICENSE("GPL"); 26MODULE_LICENSE("GPL");
26 27
27static struct input_dev *m68kspkr_dev; 28static struct platform_device *m68kspkr_platform_device;
28 29
29static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 30static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
30{ 31{
@@ -47,36 +48,103 @@ static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int
47 return 0; 48 return 0;
48} 49}
49 50
51static int __devinit m68kspkr_probe(struct platform_device *dev)
52{
53 struct input_dev *input_dev;
54 int err;
55
56 input_dev = input_allocate_device();
57 if (!input_dev)
58 return -ENOMEM;
59
60 input_dev->name = "m68k beeper";
61 input_dev->phys = "m68k/generic";
62 input_dev->id.bustype = BUS_HOST;
63 input_dev->id.vendor = 0x001f;
64 input_dev->id.product = 0x0001;
65 input_dev->id.version = 0x0100;
66 input_dev->cdev.dev = &dev->dev;
67
68 input_dev->evbit[0] = BIT(EV_SND);
69 input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
70 input_dev->event = m68kspkr_event;
71
72 err = input_register_device(input_dev);
73 if (err) {
74 input_free_device(input_dev);
75 return err;
76 }
77
78 platform_set_drvdata(dev, input_dev);
79
80 return 0;
81}
82
83static int __devexit m68kspkr_remove(struct platform_device *dev)
84{
85 struct input_dev *input_dev = platform_get_drvdata(dev);
86
87 input_unregister_device(input_dev);
88 platform_set_drvdata(dev, NULL);
89 /* turn off the speaker */
90 m68kspkr_event(NULL, EV_SND, SND_BELL, 0);
91
92 return 0;
93}
94
95static void m68kspkr_shutdown(struct platform_device *dev)
96{
97 /* turn off the speaker */
98 m68kspkr_event(NULL, EV_SND, SND_BELL, 0);
99}
100
101static struct platform_driver m68kspkr_platform_driver = {
102 .driver = {
103 .name = "m68kspkr",
104 .owner = THIS_MODULE,
105 },
106 .probe = m68kspkr_probe,
107 .remove = __devexit_p(m68kspkr_remove),
108 .shutdown = m68kspkr_shutdown,
109};
110
50static int __init m68kspkr_init(void) 111static int __init m68kspkr_init(void)
51{ 112{
52 if (!mach_beep) { 113 int err;
114
115 if (!mach_beep) {
53 printk(KERN_INFO "m68kspkr: no lowlevel beep support\n"); 116 printk(KERN_INFO "m68kspkr: no lowlevel beep support\n");
54 return -ENODEV; 117 return -ENODEV;
55 } 118 }
56 119
57 m68kspkr_dev = input_allocate_device(); 120 err = platform_driver_register(&m68kspkr_platform_driver);
58 if (!m68kspkr_dev) 121 if (err)
59 return -ENOMEM; 122 return err;
60
61 m68kspkr_dev->name = "m68k beeper";
62 m68kspkr_dev->phys = "m68k/generic";
63 m68kspkr_dev->id.bustype = BUS_HOST;
64 m68kspkr_dev->id.vendor = 0x001f;
65 m68kspkr_dev->id.product = 0x0001;
66 m68kspkr_dev->id.version = 0x0100;
67 123
68 m68kspkr_dev->evbit[0] = BIT(EV_SND); 124 m68kspkr_platform_device = platform_device_alloc("m68kspkr", -1);
69 m68kspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); 125 if (!m68kspkr_platform_device) {
70 m68kspkr_dev->event = m68kspkr_event; 126 err = -ENOMEM;
127 goto err_unregister_driver;
128 }
71 129
72 input_register_device(m68kspkr_dev); 130 err = platform_device_add(m68kspkr_platform_device);
131 if (err)
132 goto err_free_device;
73 133
74 return 0; 134 return 0;
135
136 err_free_device:
137 platform_device_put(m68kspkr_platform_device);
138 err_unregister_driver:
139 platform_driver_unregister(&m68kspkr_platform_driver);
140
141 return err;
75} 142}
76 143
77static void __exit m68kspkr_exit(void) 144static void __exit m68kspkr_exit(void)
78{ 145{
79 input_unregister_device(m68kspkr_dev); 146 platform_device_unregister(m68kspkr_platform_device);
147 platform_driver_unregister(&m68kspkr_platform_driver);
80} 148}
81 149
82module_init(m68kspkr_init); 150module_init(m68kspkr_init);
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
index 68ac97f101b0..1ef477f4469c 100644
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -16,6 +16,7 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/input.h> 18#include <linux/input.h>
19#include <linux/platform_device.h>
19#include <asm/8253pit.h> 20#include <asm/8253pit.h>
20#include <asm/io.h> 21#include <asm/io.h>
21 22
@@ -23,8 +24,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
23MODULE_DESCRIPTION("PC Speaker beeper driver"); 24MODULE_DESCRIPTION("PC Speaker beeper driver");
24MODULE_LICENSE("GPL"); 25MODULE_LICENSE("GPL");
25 26
26static struct input_dev *pcspkr_dev; 27static struct platform_device *pcspkr_platform_device;
27
28static DEFINE_SPINLOCK(i8253_beep_lock); 28static DEFINE_SPINLOCK(i8253_beep_lock);
29 29
30static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 30static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
@@ -64,8 +64,11 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
64 return 0; 64 return 0;
65} 65}
66 66
67static int __init pcspkr_init(void) 67static int __devinit pcspkr_probe(struct platform_device *dev)
68{ 68{
69 struct input_dev *pcspkr_dev;
70 int err;
71
69 pcspkr_dev = input_allocate_device(); 72 pcspkr_dev = input_allocate_device();
70 if (!pcspkr_dev) 73 if (!pcspkr_dev)
71 return -ENOMEM; 74 return -ENOMEM;
@@ -76,22 +79,93 @@ static int __init pcspkr_init(void)
76 pcspkr_dev->id.vendor = 0x001f; 79 pcspkr_dev->id.vendor = 0x001f;
77 pcspkr_dev->id.product = 0x0001; 80 pcspkr_dev->id.product = 0x0001;
78 pcspkr_dev->id.version = 0x0100; 81 pcspkr_dev->id.version = 0x0100;
82 pcspkr_dev->cdev.dev = &dev->dev;
79 83
80 pcspkr_dev->evbit[0] = BIT(EV_SND); 84 pcspkr_dev->evbit[0] = BIT(EV_SND);
81 pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); 85 pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
82 pcspkr_dev->event = pcspkr_event; 86 pcspkr_dev->event = pcspkr_event;
83 87
84 input_register_device(pcspkr_dev); 88 err = input_register_device(pcspkr_dev);
89 if (err) {
90 input_free_device(pcspkr_dev);
91 return err;
92 }
93
94 platform_set_drvdata(dev, pcspkr_dev);
85 95
86 return 0; 96 return 0;
87} 97}
88 98
89static void __exit pcspkr_exit(void) 99static int __devexit pcspkr_remove(struct platform_device *dev)
100{
101 struct input_dev *pcspkr_dev = platform_get_drvdata(dev);
102
103 input_unregister_device(pcspkr_dev);
104 platform_set_drvdata(dev, NULL);
105 /* turn off the speaker */
106 pcspkr_event(NULL, EV_SND, SND_BELL, 0);
107
108 return 0;
109}
110
111static int pcspkr_suspend(struct platform_device *dev, pm_message_t state)
112{
113 pcspkr_event(NULL, EV_SND, SND_BELL, 0);
114
115 return 0;
116}
117
118static void pcspkr_shutdown(struct platform_device *dev)
90{ 119{
91 input_unregister_device(pcspkr_dev);
92 /* turn off the speaker */ 120 /* turn off the speaker */
93 pcspkr_event(NULL, EV_SND, SND_BELL, 0); 121 pcspkr_event(NULL, EV_SND, SND_BELL, 0);
94} 122}
95 123
124static struct platform_driver pcspkr_platform_driver = {
125 .driver = {
126 .name = "pcspkr",
127 .owner = THIS_MODULE,
128 },
129 .probe = pcspkr_probe,
130 .remove = __devexit_p(pcspkr_remove),
131 .suspend = pcspkr_suspend,
132 .shutdown = pcspkr_shutdown,
133};
134
135
136static int __init pcspkr_init(void)
137{
138 int err;
139
140 err = platform_driver_register(&pcspkr_platform_driver);
141 if (err)
142 return err;
143
144 pcspkr_platform_device = platform_device_alloc("pcspkr", -1);
145 if (!pcspkr_platform_device) {
146 err = -ENOMEM;
147 goto err_unregister_driver;
148 }
149
150 err = platform_device_add(pcspkr_platform_device);
151 if (err)
152 goto err_free_device;
153
154 return 0;
155
156 err_free_device:
157 platform_device_put(pcspkr_platform_device);
158 err_unregister_driver:
159 platform_driver_unregister(&pcspkr_platform_driver);
160
161 return err;
162}
163
164static void __exit pcspkr_exit(void)
165{
166 platform_device_unregister(pcspkr_platform_device);
167 platform_driver_unregister(&pcspkr_platform_driver);
168}
169
96module_init(pcspkr_init); 170module_init(pcspkr_init);
97module_exit(pcspkr_exit); 171module_exit(pcspkr_exit);
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index 29d97b12be7a..f0fd2c4740f1 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -9,6 +9,7 @@
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/input.h> 11#include <linux/input.h>
12#include <linux/platform_device.h>
12 13
13#include <asm/io.h> 14#include <asm/io.h>
14#include <asm/ebus.h> 15#include <asm/ebus.h>
@@ -20,22 +21,10 @@ MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
20MODULE_DESCRIPTION("Sparc Speaker beeper driver"); 21MODULE_DESCRIPTION("Sparc Speaker beeper driver");
21MODULE_LICENSE("GPL"); 22MODULE_LICENSE("GPL");
22 23
24const char *beep_name;
23static unsigned long beep_iobase; 25static unsigned long beep_iobase;
24static struct input_dev *sparcspkr_dev; 26static int (*beep_event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
25 27static DEFINE_SPINLOCK(beep_lock);
26DEFINE_SPINLOCK(beep_lock);
27
28static void __init init_sparcspkr_struct(void)
29{
30 sparcspkr_dev->evbit[0] = BIT(EV_SND);
31 sparcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
32
33 sparcspkr_dev->phys = "sparc/input0";
34 sparcspkr_dev->id.bustype = BUS_ISA;
35 sparcspkr_dev->id.vendor = 0x001f;
36 sparcspkr_dev->id.product = 0x0001;
37 sparcspkr_dev->id.version = 0x0100;
38}
39 28
40static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 29static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
41{ 30{
@@ -59,39 +48,16 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in
59 /* EBUS speaker only has on/off state, the frequency does not 48 /* EBUS speaker only has on/off state, the frequency does not
60 * appear to be programmable. 49 * appear to be programmable.
61 */ 50 */
62 if (count) { 51 if (beep_iobase & 0x2UL)
63 if (beep_iobase & 0x2UL) 52 outb(!!count, beep_iobase);
64 outb(1, beep_iobase); 53 else
65 else 54 outl(!!count, beep_iobase);
66 outl(1, beep_iobase);
67 } else {
68 if (beep_iobase & 0x2UL)
69 outb(0, beep_iobase);
70 else
71 outl(0, beep_iobase);
72 }
73 55
74 spin_unlock_irqrestore(&beep_lock, flags); 56 spin_unlock_irqrestore(&beep_lock, flags);
75 57
76 return 0; 58 return 0;
77} 59}
78 60
79static int __init init_ebus_beep(struct linux_ebus_device *edev)
80{
81 beep_iobase = edev->resource[0].start;
82
83 sparcspkr_dev = input_allocate_device();
84 if (!sparcspkr_dev)
85 return -ENOMEM;
86
87 sparcspkr_dev->name = "Sparc EBUS Speaker";
88 sparcspkr_dev->event = ebus_spkr_event;
89
90 input_register_device(sparcspkr_dev);
91
92 return 0;
93}
94
95#ifdef CONFIG_SPARC64 61#ifdef CONFIG_SPARC64
96static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 62static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
97{ 63{
@@ -129,30 +95,103 @@ static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int
129 95
130 return 0; 96 return 0;
131} 97}
98#endif
132 99
133static int __init init_isa_beep(struct sparc_isa_device *isa_dev) 100static int __devinit sparcspkr_probe(struct platform_device *dev)
134{ 101{
135 beep_iobase = isa_dev->resource.start; 102 struct input_dev *input_dev;
103 int error;
136 104
137 sparcspkr_dev = input_allocate_device(); 105 input_dev = input_allocate_device();
138 if (!sparcspkr_dev) 106 if (!input_dev)
139 return -ENOMEM; 107 return -ENOMEM;
140 108
141 init_sparcspkr_struct(); 109 input_dev->name = beep_name;
110 input_dev->phys = "sparc/input0";
111 input_dev->id.bustype = BUS_ISA;
112 input_dev->id.vendor = 0x001f;
113 input_dev->id.product = 0x0001;
114 input_dev->id.version = 0x0100;
115 input_dev->cdev.dev = &dev->dev;
142 116
143 sparcspkr_dev->name = "Sparc ISA Speaker"; 117 input_dev->evbit[0] = BIT(EV_SND);
144 sparcspkr_dev->event = isa_spkr_event; 118 input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
145 119
146 input_register_device(sparcspkr_dev); 120 input_dev->event = beep_event;
121
122 error = input_register_device(input_dev);
123 if (error) {
124 input_free_device(input_dev);
125 return error;
126 }
127
128 platform_set_drvdata(dev, input_dev);
147 129
148 return 0; 130 return 0;
149} 131}
150#endif 132
133static int __devexit sparcspkr_remove(struct platform_device *dev)
134{
135 struct input_dev *input_dev = platform_get_drvdata(dev);
136
137 input_unregister_device(input_dev);
138 platform_set_drvdata(dev, NULL);
139 /* turn off the speaker */
140 beep_event(NULL, EV_SND, SND_BELL, 0);
141
142 return 0;
143}
144
145static void sparcspkr_shutdown(struct platform_device *dev)
146{
147 /* turn off the speaker */
148 beep_event(NULL, EV_SND, SND_BELL, 0);
149}
150
151static struct platform_driver sparcspkr_platform_driver = {
152 .driver = {
153 .name = "sparcspkr",
154 .owner = THIS_MODULE,
155 },
156 .probe = sparcspkr_probe,
157 .remove = __devexit_p(sparcspkr_remove),
158 .shutdown = sparcspkr_shutdown,
159};
160
161static struct platform_device *sparcspkr_platform_device;
162
163static int __init sparcspkr_drv_init(void)
164{
165 int error;
166
167 error = platform_driver_register(&sparcspkr_platform_driver);
168 if (error)
169 return error;
170
171 sparcspkr_platform_device = platform_device_alloc("sparcspkr", -1);
172 if (!sparcspkr_platform_device) {
173 error = -ENOMEM;
174 goto err_unregister_driver;
175 }
176
177 error = platform_device_add(sparcspkr_platform_device);
178 if (error)
179 goto err_free_device;
180
181 return 0;
182
183 err_free_device:
184 platform_device_put(sparcspkr_platform_device);
185 err_unregister_driver:
186 platform_driver_unregister(&sparcspkr_platform_driver);
187
188 return error;
189}
151 190
152static int __init sparcspkr_init(void) 191static int __init sparcspkr_init(void)
153{ 192{
154 struct linux_ebus *ebus; 193 struct linux_ebus *ebus;
155 struct linux_ebus_device *edev = NULL; 194 struct linux_ebus_device *edev;
156#ifdef CONFIG_SPARC64 195#ifdef CONFIG_SPARC64
157 struct sparc_isa_bridge *isa_br; 196 struct sparc_isa_bridge *isa_br;
158 struct sparc_isa_device *isa_dev; 197 struct sparc_isa_device *isa_dev;
@@ -160,8 +199,12 @@ static int __init sparcspkr_init(void)
160 199
161 for_each_ebus(ebus) { 200 for_each_ebus(ebus) {
162 for_each_ebusdev(edev, ebus) { 201 for_each_ebusdev(edev, ebus) {
163 if (!strcmp(edev->prom_name, "beep")) 202 if (!strcmp(edev->prom_name, "beep")) {
164 return init_ebus_beep(edev); 203 beep_name = "Sparc EBUS Speaker";
204 beep_event = ebus_spkr_event;
205 beep_iobase = edev->resource[0].start;
206 return sparcspkr_drv_init();
207 }
165 } 208 }
166 } 209 }
167#ifdef CONFIG_SPARC64 210#ifdef CONFIG_SPARC64
@@ -170,8 +213,12 @@ static int __init sparcspkr_init(void)
170 /* A hack, the beep device's base lives in 213 /* A hack, the beep device's base lives in
171 * the DMA isa node. 214 * the DMA isa node.
172 */ 215 */
173 if (!strcmp(isa_dev->prom_name, "dma")) 216 if (!strcmp(isa_dev->prom_name, "dma")) {
174 return init_isa_beep(isa_dev); 217 beep_name = "Sparc ISA Speaker";
218 beep_event = isa_spkr_event,
219 beep_iobase = isa_dev->resource.start;
220 return sparcspkr_drv_init();
221 }
175 } 222 }
176 } 223 }
177#endif 224#endif
@@ -181,7 +228,8 @@ static int __init sparcspkr_init(void)
181 228
182static void __exit sparcspkr_exit(void) 229static void __exit sparcspkr_exit(void)
183{ 230{
184 input_unregister_device(sparcspkr_dev); 231 platform_device_unregister(sparcspkr_platform_device);
232 platform_driver_unregister(&sparcspkr_platform_driver);
185} 233}
186 234
187module_init(sparcspkr_init); 235module_init(sparcspkr_init);
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index bac3085185fe..a05b8557842f 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -174,7 +174,7 @@ static u16 bios_pop_queue(void)
174 return regs.eax; 174 return regs.eax;
175} 175}
176 176
177static void __init bios_attach(void) 177static void __devinit bios_attach(void)
178{ 178{
179 struct regs regs; 179 struct regs regs;
180 180
@@ -194,7 +194,7 @@ static void bios_detach(void)
194 call_bios(&regs); 194 call_bios(&regs);
195} 195}
196 196
197static u8 __init bios_get_cmos_address(void) 197static u8 __devinit bios_get_cmos_address(void)
198{ 198{
199 struct regs regs; 199 struct regs regs;
200 200
@@ -206,7 +206,7 @@ static u8 __init bios_get_cmos_address(void)
206 return regs.ecx; 206 return regs.ecx;
207} 207}
208 208
209static u16 __init bios_get_default_setting(u8 subsys) 209static u16 __devinit bios_get_default_setting(u8 subsys)
210{ 210{
211 struct regs regs; 211 struct regs regs;
212 212
@@ -296,6 +296,16 @@ static struct key_entry keymap_acer_aspire_1500[] = {
296 { KE_END, 0 } 296 { KE_END, 0 }
297}; 297};
298 298
299static struct key_entry keymap_acer_travelmate_240[] = {
300 { KE_KEY, 0x31, KEY_MAIL },
301 { KE_KEY, 0x36, KEY_WWW },
302 { KE_KEY, 0x11, KEY_PROG1 },
303 { KE_KEY, 0x12, KEY_PROG2 },
304 { KE_BLUETOOTH, 0x44, 0 },
305 { KE_WIFI, 0x30, 0 },
306 { KE_END, 0 }
307};
308
299/* 309/*
300 * If your machine is not here (which is currently rather likely), please send 310 * If your machine is not here (which is currently rather likely), please send
301 * a list of buttons and their key codes (reported when loading this module 311 * a list of buttons and their key codes (reported when loading this module
@@ -320,6 +330,15 @@ static struct dmi_system_id dmi_ids[] = {
320 }, 330 },
321 .driver_data = keymap_acer_aspire_1500 331 .driver_data = keymap_acer_aspire_1500
322 }, 332 },
333 {
334 .callback = dmi_matched,
335 .ident = "Acer TravelMate 240",
336 .matches = {
337 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
338 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"),
339 },
340 .driver_data = keymap_acer_travelmate_240
341 },
323 { NULL, } 342 { NULL, }
324}; 343};
325 344
@@ -348,7 +367,7 @@ static int __init select_keymap(void)
348 367
349static struct input_dev *input_dev; 368static struct input_dev *input_dev;
350 369
351static int __init setup_input_dev(void) 370static int __devinit setup_input_dev(void)
352{ 371{
353 const struct key_entry *key; 372 const struct key_entry *key;
354 int error; 373 int error;
@@ -447,6 +466,52 @@ static void poll_bios(unsigned long discard)
447 mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY); 466 mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY);
448} 467}
449 468
469static int __devinit wistron_probe(struct platform_device *dev)
470{
471 int err = setup_input_dev();
472 if (err)
473 return err;
474
475 bios_attach();
476 cmos_address = bios_get_cmos_address();
477
478 if (have_wifi) {
479 u16 wifi = bios_get_default_setting(WIFI);
480 if (wifi & 1)
481 wifi_enabled = (wifi & 2) ? 1 : 0;
482 else
483 have_wifi = 0;
484
485 if (have_wifi)
486 bios_set_state(WIFI, wifi_enabled);
487 }
488
489 if (have_bluetooth) {
490 u16 bt = bios_get_default_setting(BLUETOOTH);
491 if (bt & 1)
492 bluetooth_enabled = (bt & 2) ? 1 : 0;
493 else
494 have_bluetooth = 0;
495
496 if (have_bluetooth)
497 bios_set_state(BLUETOOTH, bluetooth_enabled);
498 }
499
500 poll_bios(1); /* Flush stale event queue and arm timer */
501
502 return 0;
503}
504
505static int __devexit wistron_remove(struct platform_device *dev)
506{
507 del_timer_sync(&poll_timer);
508 input_unregister_device(input_dev);
509 bios_detach();
510
511 return 0;
512}
513
514#ifdef CONFIG_PM
450static int wistron_suspend(struct platform_device *dev, pm_message_t state) 515static int wistron_suspend(struct platform_device *dev, pm_message_t state)
451{ 516{
452 del_timer_sync(&poll_timer); 517 del_timer_sync(&poll_timer);
@@ -472,13 +537,20 @@ static int wistron_resume(struct platform_device *dev)
472 537
473 return 0; 538 return 0;
474} 539}
540#else
541#define wistron_suspend NULL
542#define wistron_resume NULL
543#endif
475 544
476static struct platform_driver wistron_driver = { 545static struct platform_driver wistron_driver = {
477 .suspend = wistron_suspend,
478 .resume = wistron_resume,
479 .driver = { 546 .driver = {
480 .name = "wistron-bios", 547 .name = "wistron-bios",
548 .owner = THIS_MODULE,
481 }, 549 },
550 .probe = wistron_probe,
551 .remove = __devexit_p(wistron_remove),
552 .suspend = wistron_suspend,
553 .resume = wistron_resume,
482}; 554};
483 555
484static int __init wb_module_init(void) 556static int __init wb_module_init(void)
@@ -493,55 +565,27 @@ static int __init wb_module_init(void)
493 if (err) 565 if (err)
494 return err; 566 return err;
495 567
496 bios_attach();
497 cmos_address = bios_get_cmos_address();
498
499 err = platform_driver_register(&wistron_driver); 568 err = platform_driver_register(&wistron_driver);
500 if (err) 569 if (err)
501 goto err_detach_bios; 570 goto err_unmap_bios;
502 571
503 wistron_device = platform_device_register_simple("wistron-bios", -1, NULL, 0); 572 wistron_device = platform_device_alloc("wistron-bios", -1);
504 if (IS_ERR(wistron_device)) { 573 if (!wistron_device) {
505 err = PTR_ERR(wistron_device); 574 err = -ENOMEM;
506 goto err_unregister_driver; 575 goto err_unregister_driver;
507 } 576 }
508 577
509 if (have_wifi) { 578 err = platform_device_add(wistron_device);
510 u16 wifi = bios_get_default_setting(WIFI);
511 if (wifi & 1)
512 wifi_enabled = (wifi & 2) ? 1 : 0;
513 else
514 have_wifi = 0;
515
516 if (have_wifi)
517 bios_set_state(WIFI, wifi_enabled);
518 }
519
520 if (have_bluetooth) {
521 u16 bt = bios_get_default_setting(BLUETOOTH);
522 if (bt & 1)
523 bluetooth_enabled = (bt & 2) ? 1 : 0;
524 else
525 have_bluetooth = 0;
526
527 if (have_bluetooth)
528 bios_set_state(BLUETOOTH, bluetooth_enabled);
529 }
530
531 err = setup_input_dev();
532 if (err) 579 if (err)
533 goto err_unregister_device; 580 goto err_free_device;
534
535 poll_bios(1); /* Flush stale event queue and arm timer */
536 581
537 return 0; 582 return 0;
538 583
539 err_unregister_device: 584 err_free_device:
540 platform_device_unregister(wistron_device); 585 platform_device_put(wistron_device);
541 err_unregister_driver: 586 err_unregister_driver:
542 platform_driver_unregister(&wistron_driver); 587 platform_driver_unregister(&wistron_driver);
543 err_detach_bios: 588 err_unmap_bios:
544 bios_detach();
545 unmap_bios(); 589 unmap_bios();
546 590
547 return err; 591 return err;
@@ -549,11 +593,8 @@ static int __init wb_module_init(void)
549 593
550static void __exit wb_module_exit(void) 594static void __exit wb_module_exit(void)
551{ 595{
552 del_timer_sync(&poll_timer);
553 input_unregister_device(input_dev);
554 platform_device_unregister(wistron_device); 596 platform_device_unregister(wistron_device);
555 platform_driver_unregister(&wistron_driver); 597 platform_driver_unregister(&wistron_driver);
556 bios_detach();
557 unmap_bios(); 598 unmap_bios();
558} 599}
559 600
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 4f41ec3e4332..24474335dfd1 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -40,6 +40,7 @@ static struct alps_model_info alps_model_data[] = {
40 { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */ 40 { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */
41 { { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, 41 { { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
42 { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, 42 { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
43 { { 0x60, 0x03, 0xc8 }, 0xf8, 0xf8, 0 }, /* HP ze1115 */
43 { { 0x63, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, 44 { { 0x63, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
44 { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, 45 { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
45 { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */ 46 { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 55991424ac91..5ccc3ef3b89e 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -27,6 +27,13 @@ static struct dmi_system_id lifebook_dmi_table[] = {
27 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"), 27 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"),
28 }, 28 },
29 }, 29 },
30 {
31 .ident = "Lifebook B142",
32 .matches = {
33 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
34 },
35
36 },
30 { } 37 { }
31}; 38};
32 39
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 31a59f7abfaf..025a71de5404 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -226,7 +226,9 @@ static struct ps2pp_info *get_model_info(unsigned char model)
226 { 80, PS2PP_KIND_WHEEL, PS2PP_SIDE_BTN | PS2PP_WHEEL }, 226 { 80, PS2PP_KIND_WHEEL, PS2PP_SIDE_BTN | PS2PP_WHEEL },
227 { 81, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, 227 { 81, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
228 { 83, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, 228 { 83, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
229 { 85, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
229 { 86, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, 230 { 86, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
231 { 87, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
230 { 88, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, 232 { 88, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
231 { 96, 0, 0 }, 233 { 96, 0, 0 },
232 { 97, PS2PP_KIND_TP3, PS2PP_WHEEL | PS2PP_HWHEEL }, 234 { 97, PS2PP_KIND_TP3, PS2PP_WHEEL | PS2PP_HWHEEL },
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 6ee9999a2eaa..4d5ecc04c5b6 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -527,11 +527,15 @@ static int psmouse_extensions(struct psmouse *psmouse,
527 if (max_proto > PSMOUSE_IMEX && ps2pp_init(psmouse, set_properties) == 0) 527 if (max_proto > PSMOUSE_IMEX && ps2pp_init(psmouse, set_properties) == 0)
528 return PSMOUSE_PS2PP; 528 return PSMOUSE_PS2PP;
529 529
530 if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0)
531 return PSMOUSE_TRACKPOINT;
532
530/* 533/*
531 * Reset to defaults in case the device got confused by extended 534 * Reset to defaults in case the device got confused by extended
532 * protocol probes. 535 * protocol probes. Note that we do full reset becuase some mice
536 * put themselves to sleep when see PSMOUSE_RESET_DIS.
533 */ 537 */
534 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); 538 psmouse_reset(psmouse);
535 539
536 if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse, set_properties) == 0) 540 if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse, set_properties) == 0)
537 return PSMOUSE_IMEX; 541 return PSMOUSE_IMEX;
@@ -540,12 +544,6 @@ static int psmouse_extensions(struct psmouse *psmouse,
540 return PSMOUSE_IMPS; 544 return PSMOUSE_IMPS;
541 545
542/* 546/*
543 * Try to initialize the IBM TrackPoint
544 */
545 if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0)
546 return PSMOUSE_TRACKPOINT;
547
548/*
549 * Okay, all failed, we have a standard mouse here. The number of the buttons 547 * Okay, all failed, we have a standard mouse here. The number of the buttons
550 * is still a question, though. We assume 3. 548 * is still a question, though. We assume 3.
551 */ 549 */
@@ -559,7 +557,6 @@ static int psmouse_extensions(struct psmouse *psmouse,
559 * extensions. 557 * extensions.
560 */ 558 */
561 psmouse_reset(psmouse); 559 psmouse_reset(psmouse);
562 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
563 } 560 }
564 561
565 return PSMOUSE_PS2; 562 return PSMOUSE_PS2;
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 2d0af44ac4b9..81fd7a97a93d 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -40,15 +40,15 @@ MODULE_LICENSE("GPL");
40#endif 40#endif
41 41
42static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X; 42static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X;
43module_param(xres, uint, 0); 43module_param(xres, uint, 0644);
44MODULE_PARM_DESC(xres, "Horizontal screen resolution"); 44MODULE_PARM_DESC(xres, "Horizontal screen resolution");
45 45
46static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y; 46static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y;
47module_param(yres, uint, 0); 47module_param(yres, uint, 0644);
48MODULE_PARM_DESC(yres, "Vertical screen resolution"); 48MODULE_PARM_DESC(yres, "Vertical screen resolution");
49 49
50static unsigned tap_time = 200; 50static unsigned tap_time = 200;
51module_param(tap_time, uint, 0); 51module_param(tap_time, uint, 0644);
52MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)"); 52MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)");
53 53
54struct mousedev_hw_data { 54struct mousedev_hw_data {
@@ -155,7 +155,7 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
155 switch (code) { 155 switch (code) {
156 case ABS_X: 156 case ABS_X:
157 size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; 157 size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
158 if (size == 0) size = xres; 158 if (size == 0) size = xres ? : 1;
159 if (value > dev->absmax[ABS_X]) value = dev->absmax[ABS_X]; 159 if (value > dev->absmax[ABS_X]) value = dev->absmax[ABS_X];
160 if (value < dev->absmin[ABS_X]) value = dev->absmin[ABS_X]; 160 if (value < dev->absmin[ABS_X]) value = dev->absmin[ABS_X];
161 mousedev->packet.x = ((value - dev->absmin[ABS_X]) * xres) / size; 161 mousedev->packet.x = ((value - dev->absmin[ABS_X]) * xres) / size;
@@ -164,7 +164,7 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
164 164
165 case ABS_Y: 165 case ABS_Y:
166 size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y]; 166 size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
167 if (size == 0) size = yres; 167 if (size == 0) size = yres ? : 1;
168 if (value > dev->absmax[ABS_Y]) value = dev->absmax[ABS_Y]; 168 if (value > dev->absmax[ABS_Y]) value = dev->absmax[ABS_Y];
169 if (value < dev->absmin[ABS_Y]) value = dev->absmin[ABS_Y]; 169 if (value < dev->absmin[ABS_Y]) value = dev->absmin[ABS_Y];
170 mousedev->packet.y = yres - ((value - dev->absmin[ABS_Y]) * yres) / size; 170 mousedev->packet.y = yres - ((value - dev->absmin[ABS_Y]) * yres) / size;
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
index 4da6c86b5d76..096b6a0b5cca 100644
--- a/drivers/input/serio/ct82c710.c
+++ b/drivers/input/serio/ct82c710.c
@@ -154,7 +154,7 @@ static int ct82c710_write(struct serio *port, unsigned char c)
154 * See if we can find a 82C710 device. Read mouse address. 154 * See if we can find a 82C710 device. Read mouse address.
155 */ 155 */
156 156
157static int __init ct82c710_probe(void) 157static int __init ct82c710_detect(void)
158{ 158{
159 outb_p(0x55, 0x2fa); /* Any value except 9, ff or 36 */ 159 outb_p(0x55, 0x2fa); /* Any value except 9, ff or 36 */
160 outb_p(0xaa, 0x3fa); /* Inverse of 55 */ 160 outb_p(0xaa, 0x3fa); /* Inverse of 55 */
@@ -163,7 +163,7 @@ static int __init ct82c710_probe(void)
163 outb_p(0x1b, 0x2fa); /* Inverse of e4 */ 163 outb_p(0x1b, 0x2fa); /* Inverse of e4 */
164 outb_p(0x0f, 0x390); /* Write index */ 164 outb_p(0x0f, 0x390); /* Write index */
165 if (inb_p(0x391) != 0xe4) /* Config address found? */ 165 if (inb_p(0x391) != 0xe4) /* Config address found? */
166 return -1; /* No: no 82C710 here */ 166 return -ENODEV; /* No: no 82C710 here */
167 167
168 outb_p(0x0d, 0x390); /* Write index */ 168 outb_p(0x0d, 0x390); /* Write index */
169 ct82c710_iores.start = inb_p(0x391) << 2; /* Get mouse I/O address */ 169 ct82c710_iores.start = inb_p(0x391) << 2; /* Get mouse I/O address */
@@ -175,51 +175,88 @@ static int __init ct82c710_probe(void)
175 return 0; 175 return 0;
176} 176}
177 177
178static struct serio * __init ct82c710_allocate_port(void) 178static int __devinit ct82c710_probe(struct platform_device *dev)
179{ 179{
180 struct serio *serio; 180 ct82c710_port = kzalloc(sizeof(struct serio), GFP_KERNEL);
181 181 if (!ct82c710_port)
182 serio = kmalloc(sizeof(struct serio), GFP_KERNEL); 182 return -ENOMEM;
183 if (serio) { 183
184 memset(serio, 0, sizeof(struct serio)); 184 ct82c710_port->id.type = SERIO_8042;
185 serio->id.type = SERIO_8042; 185 ct82c710_port->dev.parent = &dev->dev;
186 serio->open = ct82c710_open; 186 ct82c710_port->open = ct82c710_open;
187 serio->close = ct82c710_close; 187 ct82c710_port->close = ct82c710_close;
188 serio->write = ct82c710_write; 188 ct82c710_port->write = ct82c710_write;
189 serio->dev.parent = &ct82c710_device->dev; 189 strlcpy(ct82c710_port->name, "C&T 82c710 mouse port",
190 strlcpy(serio->name, "C&T 82c710 mouse port", sizeof(serio->name)); 190 sizeof(ct82c710_port->name));
191 snprintf(serio->phys, sizeof(serio->phys), "isa%04lx/serio0", CT82C710_DATA); 191 snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys),
192 } 192 "isa%04lx/serio0", CT82C710_DATA);
193
194 serio_register_port(ct82c710_port);
195
196 return 0;
197}
198
199static int __devexit ct82c710_remove(struct platform_device *dev)
200{
201 serio_unregister_port(ct82c710_port);
193 202
194 return serio; 203 return 0;
195} 204}
196 205
206static struct platform_driver ct82c710_driver = {
207 .driver = {
208 .name = "ct82c710",
209 .owner = THIS_MODULE,
210 },
211 .probe = ct82c710_probe,
212 .remove = __devexit_p(ct82c710_remove),
213};
214
215
197static int __init ct82c710_init(void) 216static int __init ct82c710_init(void)
198{ 217{
199 if (ct82c710_probe()) 218 int error;
200 return -ENODEV;
201 219
202 ct82c710_device = platform_device_register_simple("ct82c710", -1, &ct82c710_iores, 1); 220 error = ct82c710_detect();
203 if (IS_ERR(ct82c710_device)) 221 if (error)
204 return PTR_ERR(ct82c710_device); 222 return error;
205 223
206 if (!(ct82c710_port = ct82c710_allocate_port())) { 224 error = platform_driver_register(&ct82c710_driver);
207 platform_device_unregister(ct82c710_device); 225 if (error)
208 return -ENOMEM; 226 return error;
227
228 ct82c710_device = platform_device_alloc("ct82c710", -1);
229 if (!ct82c710_device) {
230 error = -ENOMEM;
231 goto err_unregister_driver;
209 } 232 }
210 233
234 error = platform_device_add_resources(ct82c710_device, &ct82c710_iores, 1);
235 if (error)
236 goto err_free_device;
237
238 error = platform_device_add(ct82c710_device);
239 if (error)
240 goto err_free_device;
241
211 serio_register_port(ct82c710_port); 242 serio_register_port(ct82c710_port);
212 243
213 printk(KERN_INFO "serio: C&T 82c710 mouse port at %#lx irq %d\n", 244 printk(KERN_INFO "serio: C&T 82c710 mouse port at %#lx irq %d\n",
214 CT82C710_DATA, CT82C710_IRQ); 245 CT82C710_DATA, CT82C710_IRQ);
215 246
216 return 0; 247 return 0;
248
249 err_free_device:
250 platform_device_put(ct82c710_device);
251 err_unregister_driver:
252 platform_driver_unregister(&ct82c710_driver);
253 return error;
217} 254}
218 255
219static void __exit ct82c710_exit(void) 256static void __exit ct82c710_exit(void)
220{ 257{
221 serio_unregister_port(ct82c710_port);
222 platform_device_unregister(ct82c710_device); 258 platform_device_unregister(ct82c710_device);
259 platform_driver_unregister(&ct82c710_driver);
223} 260}
224 261
225module_init(ct82c710_init); 262module_init(ct82c710_init);
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 273bb3b08cfa..2d2f9fb3aded 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -84,6 +84,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
84 DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"), 84 DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
85 }, 85 },
86 }, 86 },
87 {
88 .ident = "OQO Model 01",
89 .matches = {
90 DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
91 DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
92 DMI_MATCH(DMI_PRODUCT_VERSION, "00"),
93 },
94 },
87 { } 95 { }
88}; 96};
89 97
@@ -158,6 +166,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
158 DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), 166 DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
159 }, 167 },
160 }, 168 },
169 {
170 .ident = "Sharp Actius MM20",
171 .matches = {
172 DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
173 DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
174 },
175 },
161 { } 176 { }
162}; 177};
163 178
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index ac86c1d1d83e..a7d91d5356a5 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -572,7 +572,7 @@ static int i8042_enable_mux_ports(void)
572 * LCS/Telegraphics. 572 * LCS/Telegraphics.
573 */ 573 */
574 574
575static int __init i8042_check_mux(void) 575static int __devinit i8042_check_mux(void)
576{ 576{
577 unsigned char mux_version; 577 unsigned char mux_version;
578 578
@@ -600,7 +600,7 @@ static int __init i8042_check_mux(void)
600 * the presence of an AUX interface. 600 * the presence of an AUX interface.
601 */ 601 */
602 602
603static int __init i8042_check_aux(void) 603static int __devinit i8042_check_aux(void)
604{ 604{
605 unsigned char param; 605 unsigned char param;
606 static int i8042_check_aux_cookie; 606 static int i8042_check_aux_cookie;
@@ -678,7 +678,7 @@ static int __init i8042_check_aux(void)
678 * registers it, and reports to the user. 678 * registers it, and reports to the user.
679 */ 679 */
680 680
681static int __init i8042_port_register(struct i8042_port *port) 681static int __devinit i8042_port_register(struct i8042_port *port)
682{ 682{
683 i8042_ctr &= ~port->disable; 683 i8042_ctr &= ~port->disable;
684 684
@@ -956,7 +956,6 @@ static int i8042_resume(struct platform_device *dev)
956 panic_blink = i8042_panic_blink; 956 panic_blink = i8042_panic_blink;
957 957
958 return 0; 958 return 0;
959
960} 959}
961 960
962/* 961/*
@@ -969,16 +968,7 @@ static void i8042_shutdown(struct platform_device *dev)
969 i8042_controller_cleanup(); 968 i8042_controller_cleanup();
970} 969}
971 970
972static struct platform_driver i8042_driver = { 971static int __devinit i8042_create_kbd_port(void)
973 .suspend = i8042_suspend,
974 .resume = i8042_resume,
975 .shutdown = i8042_shutdown,
976 .driver = {
977 .name = "i8042",
978 },
979};
980
981static int __init i8042_create_kbd_port(void)
982{ 972{
983 struct serio *serio; 973 struct serio *serio;
984 struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO]; 974 struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
@@ -1003,7 +993,7 @@ static int __init i8042_create_kbd_port(void)
1003 return i8042_port_register(port); 993 return i8042_port_register(port);
1004} 994}
1005 995
1006static int __init i8042_create_aux_port(void) 996static int __devinit i8042_create_aux_port(void)
1007{ 997{
1008 struct serio *serio; 998 struct serio *serio;
1009 struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO]; 999 struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO];
@@ -1028,7 +1018,7 @@ static int __init i8042_create_aux_port(void)
1028 return i8042_port_register(port); 1018 return i8042_port_register(port);
1029} 1019}
1030 1020
1031static int __init i8042_create_mux_port(int index) 1021static int __devinit i8042_create_mux_port(int index)
1032{ 1022{
1033 struct serio *serio; 1023 struct serio *serio;
1034 struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index]; 1024 struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index];
@@ -1057,37 +1047,16 @@ static int __init i8042_create_mux_port(int index)
1057 return i8042_port_register(port); 1047 return i8042_port_register(port);
1058} 1048}
1059 1049
1060static int __init i8042_init(void) 1050static int __devinit i8042_probe(struct platform_device *dev)
1061{ 1051{
1062 int i, have_ports = 0; 1052 int i, have_ports = 0;
1063 int err; 1053 int err;
1064 1054
1065 dbg_init();
1066
1067 init_timer(&i8042_timer); 1055 init_timer(&i8042_timer);
1068 i8042_timer.function = i8042_timer_func; 1056 i8042_timer.function = i8042_timer_func;
1069 1057
1070 err = i8042_platform_init(); 1058 if (i8042_controller_init())
1071 if (err) 1059 return -ENODEV;
1072 return err;
1073
1074 i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ;
1075 i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
1076
1077 if (i8042_controller_init()) {
1078 err = -ENODEV;
1079 goto err_platform_exit;
1080 }
1081
1082 err = platform_driver_register(&i8042_driver);
1083 if (err)
1084 goto err_controller_cleanup;
1085
1086 i8042_platform_device = platform_device_register_simple("i8042", -1, NULL, 0);
1087 if (IS_ERR(i8042_platform_device)) {
1088 err = PTR_ERR(i8042_platform_device);
1089 goto err_unregister_driver;
1090 }
1091 1060
1092 if (!i8042_noaux && !i8042_check_aux()) { 1061 if (!i8042_noaux && !i8042_check_aux()) {
1093 if (!i8042_nomux && !i8042_check_mux()) { 1062 if (!i8042_nomux && !i8042_check_mux()) {
@@ -1113,30 +1082,23 @@ static int __init i8042_init(void)
1113 1082
1114 if (!have_ports) { 1083 if (!have_ports) {
1115 err = -ENODEV; 1084 err = -ENODEV;
1116 goto err_unregister_device; 1085 goto err_controller_cleanup;
1117 } 1086 }
1118 1087
1119 mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD); 1088 mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
1120
1121 return 0; 1089 return 0;
1122 1090
1123 err_unregister_ports: 1091 err_unregister_ports:
1124 for (i = 0; i < I8042_NUM_PORTS; i++) 1092 for (i = 0; i < I8042_NUM_PORTS; i++)
1125 if (i8042_ports[i].serio) 1093 if (i8042_ports[i].serio)
1126 serio_unregister_port(i8042_ports[i].serio); 1094 serio_unregister_port(i8042_ports[i].serio);
1127 err_unregister_device:
1128 platform_device_unregister(i8042_platform_device);
1129 err_unregister_driver:
1130 platform_driver_unregister(&i8042_driver);
1131 err_controller_cleanup: 1095 err_controller_cleanup:
1132 i8042_controller_cleanup(); 1096 i8042_controller_cleanup();
1133 err_platform_exit:
1134 i8042_platform_exit();
1135 1097
1136 return err; 1098 return err;
1137} 1099}
1138 1100
1139static void __exit i8042_exit(void) 1101static int __devexit i8042_remove(struct platform_device *dev)
1140{ 1102{
1141 int i; 1103 int i;
1142 1104
@@ -1148,6 +1110,62 @@ static void __exit i8042_exit(void)
1148 1110
1149 del_timer_sync(&i8042_timer); 1111 del_timer_sync(&i8042_timer);
1150 1112
1113 return 0;
1114}
1115
1116static struct platform_driver i8042_driver = {
1117 .driver = {
1118 .name = "i8042",
1119 .owner = THIS_MODULE,
1120 },
1121 .probe = i8042_probe,
1122 .remove = __devexit_p(i8042_remove),
1123 .suspend = i8042_suspend,
1124 .resume = i8042_resume,
1125 .shutdown = i8042_shutdown,
1126};
1127
1128static int __init i8042_init(void)
1129{
1130 int err;
1131
1132 dbg_init();
1133
1134 err = i8042_platform_init();
1135 if (err)
1136 return err;
1137
1138 i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ;
1139 i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
1140
1141 err = platform_driver_register(&i8042_driver);
1142 if (err)
1143 goto err_platform_exit;
1144
1145 i8042_platform_device = platform_device_alloc("i8042", -1);
1146 if (!i8042_platform_device) {
1147 err = -ENOMEM;
1148 goto err_unregister_driver;
1149 }
1150
1151 err = platform_device_add(i8042_platform_device);
1152 if (err)
1153 goto err_free_device;
1154
1155 return 0;
1156
1157 err_free_device:
1158 platform_device_put(i8042_platform_device);
1159 err_unregister_driver:
1160 platform_driver_unregister(&i8042_driver);
1161 err_platform_exit:
1162 i8042_platform_exit();
1163
1164 return err;
1165}
1166
1167static void __exit i8042_exit(void)
1168{
1151 platform_device_unregister(i8042_platform_device); 1169 platform_device_unregister(i8042_platform_device);
1152 platform_driver_unregister(&i8042_driver); 1170 platform_driver_unregister(&i8042_driver);
1153 1171
diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
index d857f7081adb..f08a5d0cd5fa 100644
--- a/drivers/input/serio/maceps2.c
+++ b/drivers/input/serio/maceps2.c
@@ -118,13 +118,12 @@ static void maceps2_close(struct serio *dev)
118} 118}
119 119
120 120
121static struct serio * __init maceps2_allocate_port(int idx) 121static struct serio * __devinit maceps2_allocate_port(int idx)
122{ 122{
123 struct serio *serio; 123 struct serio *serio;
124 124
125 serio = kmalloc(sizeof(struct serio), GFP_KERNEL); 125 serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
126 if (serio) { 126 if (serio) {
127 memset(serio, 0, sizeof(struct serio));
128 serio->id.type = SERIO_8042; 127 serio->id.type = SERIO_8042;
129 serio->write = maceps2_write; 128 serio->write = maceps2_write;
130 serio->open = maceps2_open; 129 serio->open = maceps2_open;
@@ -138,24 +137,13 @@ static struct serio * __init maceps2_allocate_port(int idx)
138 return serio; 137 return serio;
139} 138}
140 139
141 140static int __devinit maceps2_probe(struct platform_device *dev)
142static int __init maceps2_init(void)
143{ 141{
144 maceps2_device = platform_device_register_simple("maceps2", -1, NULL, 0);
145 if (IS_ERR(maceps2_device))
146 return PTR_ERR(maceps2_device);
147
148 port_data[0].port = &mace->perif.ps2.keyb;
149 port_data[0].irq = MACEISA_KEYB_IRQ;
150 port_data[1].port = &mace->perif.ps2.mouse;
151 port_data[1].irq = MACEISA_MOUSE_IRQ;
152
153 maceps2_port[0] = maceps2_allocate_port(0); 142 maceps2_port[0] = maceps2_allocate_port(0);
154 maceps2_port[1] = maceps2_allocate_port(1); 143 maceps2_port[1] = maceps2_allocate_port(1);
155 if (!maceps2_port[0] || !maceps2_port[1]) { 144 if (!maceps2_port[0] || !maceps2_port[1]) {
156 kfree(maceps2_port[0]); 145 kfree(maceps2_port[0]);
157 kfree(maceps2_port[1]); 146 kfree(maceps2_port[1]);
158 platform_device_unregister(maceps2_device);
159 return -ENOMEM; 147 return -ENOMEM;
160 } 148 }
161 149
@@ -165,11 +153,59 @@ static int __init maceps2_init(void)
165 return 0; 153 return 0;
166} 154}
167 155
168static void __exit maceps2_exit(void) 156static int __devexit maceps2_remove(struct platform_device *dev)
169{ 157{
170 serio_unregister_port(maceps2_port[0]); 158 serio_unregister_port(maceps2_port[0]);
171 serio_unregister_port(maceps2_port[1]); 159 serio_unregister_port(maceps2_port[1]);
160
161 return 0;
162}
163
164static struct platform_driver maceps2_driver = {
165 .driver = {
166 .name = "maceps2",
167 .owner = THIS_MODULE,
168 },
169 .probe = maceps2_probe,
170 .remove = __devexit_p(maceps2_remove),
171};
172
173static int __init maceps2_init(void)
174{
175 int error;
176
177 error = platform_driver_register(&maceps2_driver);
178 if (error)
179 return error;
180
181 maceps2_device = platform_device_alloc("maceps2", -1);
182 if (!maceps2_device) {
183 error = -ENOMEM;
184 goto err_unregister_driver;
185 }
186
187 port_data[0].port = &mace->perif.ps2.keyb;
188 port_data[0].irq = MACEISA_KEYB_IRQ;
189 port_data[1].port = &mace->perif.ps2.mouse;
190 port_data[1].irq = MACEISA_MOUSE_IRQ;
191
192 error = platform_device_add(maceps2_device);
193 if (error)
194 goto err_free_device;
195
196 return 0;
197
198 err_free_device:
199 platform_device_put(maceps2_device);
200 err_unregister_driver:
201 platform_driver_unregister(&maceps2_driver);
202 return error;
203}
204
205static void __exit maceps2_exit(void)
206{
172 platform_device_unregister(maceps2_device); 207 platform_device_unregister(maceps2_device);
208 platform_driver_unregister(&maceps2_driver);
173} 209}
174 210
175module_init(maceps2_init); 211module_init(maceps2_init);
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
index b44d255596c2..d3827c5fe119 100644
--- a/drivers/input/serio/q40kbd.c
+++ b/drivers/input/serio/q40kbd.c
@@ -75,13 +75,13 @@ static irqreturn_t q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
75 75
76static void q40kbd_flush(void) 76static void q40kbd_flush(void)
77{ 77{
78 int maxread = 100; 78 int maxread = 100;
79 unsigned long flags; 79 unsigned long flags;
80 80
81 spin_lock_irqsave(&q40kbd_lock, flags); 81 spin_lock_irqsave(&q40kbd_lock, flags);
82 82
83 while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))) 83 while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
84 master_inb(KEYCODE_REG); 84 master_inb(KEYCODE_REG);
85 85
86 spin_unlock_irqrestore(&q40kbd_lock, flags); 86 spin_unlock_irqrestore(&q40kbd_lock, flags);
87} 87}
@@ -97,14 +97,14 @@ static int q40kbd_open(struct serio *port)
97 97
98 if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) { 98 if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) {
99 printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD); 99 printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD);
100 return -1; 100 return -EBUSY;
101 } 101 }
102 102
103 /* off we go */ 103 /* off we go */
104 master_outb(-1, KEYBOARD_UNLOCK_REG); 104 master_outb(-1, KEYBOARD_UNLOCK_REG);
105 master_outb(1, KEY_IRQ_ENABLE_REG); 105 master_outb(1, KEY_IRQ_ENABLE_REG);
106 106
107 return 0; 107 return 0;
108} 108}
109 109
110static void q40kbd_close(struct serio *port) 110static void q40kbd_close(struct serio *port)
@@ -116,48 +116,73 @@ static void q40kbd_close(struct serio *port)
116 q40kbd_flush(); 116 q40kbd_flush();
117} 117}
118 118
119static struct serio * __init q40kbd_allocate_port(void) 119static int __devinit q40kbd_probe(struct platform_device *dev)
120{ 120{
121 struct serio *serio; 121 q40kbd_port = kzalloc(sizeof(struct serio), GFP_KERNEL);
122 122 if (!q40kbd_port)
123 serio = kmalloc(sizeof(struct serio), GFP_KERNEL); 123 return -ENOMEM;
124 if (serio) { 124
125 memset(serio, 0, sizeof(struct serio)); 125 q40kbd_port->id.type = SERIO_8042;
126 serio->id.type = SERIO_8042; 126 q40kbd_port->open = q40kbd_open;
127 serio->open = q40kbd_open; 127 q40kbd_port->close = q40kbd_close;
128 serio->close = q40kbd_close; 128 q40kbd_port->dev.parent = &dev->dev;
129 serio->dev.parent = &q40kbd_device->dev; 129 strlcpy(q40kbd_port->name, "Q40 Kbd Port", sizeof(q40kbd_port->name));
130 strlcpy(serio->name, "Q40 Kbd Port", sizeof(serio->name)); 130 strlcpy(q40kbd_port->phys, "Q40", sizeof(q40kbd_port->phys));
131 strlcpy(serio->phys, "Q40", sizeof(serio->phys)); 131
132 } 132 serio_register_port(q40kbd_port);
133 printk(KERN_INFO "serio: Q40 kbd registered\n");
133 134
134 return serio; 135 return 0;
135} 136}
136 137
138static int __devexit q40kbd_remove(struct platform_device *dev)
139{
140 serio_unregister_port(q40kbd_port);
141
142 return 0;
143}
144
145static struct platform_driver q40kbd_driver = {
146 .driver = {
147 .name = "q40kbd",
148 .owner = THIS_MODULE,
149 },
150 .probe = q40kbd_probe,
151 .remove = __devexit_p(q40kbd_remove),
152};
153
137static int __init q40kbd_init(void) 154static int __init q40kbd_init(void)
138{ 155{
156 int error;
157
139 if (!MACH_IS_Q40) 158 if (!MACH_IS_Q40)
140 return -EIO; 159 return -EIO;
141 160
142 q40kbd_device = platform_device_register_simple("q40kbd", -1, NULL, 0); 161 error = platform_driver_register(&q40kbd_driver);
143 if (IS_ERR(q40kbd_device)) 162 if (error)
144 return PTR_ERR(q40kbd_device); 163 return error;
145 164
146 if (!(q40kbd_port = q40kbd_allocate_port())) { 165 q40kbd_device = platform_device_alloc("q40kbd", -1);
147 platform_device_unregister(q40kbd_device); 166 if (!q40kbd_device)
148 return -ENOMEM; 167 goto err_unregister_driver;
149 }
150 168
151 serio_register_port(q40kbd_port); 169 error = platform_device_add(q40kbd_device);
152 printk(KERN_INFO "serio: Q40 kbd registered\n"); 170 if (error)
171 goto err_free_device;
153 172
154 return 0; 173 return 0;
174
175 err_free_device:
176 platform_device_put(q40kbd_device);
177 err_unregister_driver:
178 platform_driver_unregister(&q40kbd_driver);
179 return error;
155} 180}
156 181
157static void __exit q40kbd_exit(void) 182static void __exit q40kbd_exit(void)
158{ 183{
159 serio_unregister_port(q40kbd_port);
160 platform_device_unregister(q40kbd_device); 184 platform_device_unregister(q40kbd_device);
185 platform_driver_unregister(&q40kbd_driver);
161} 186}
162 187
163module_init(q40kbd_init); 188module_init(q40kbd_init);