aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard/atkbd.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-10-28 16:09:47 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-28 16:09:47 -0400
commit84860bf0644d7c45afe7ddbd30731c3e3c371fae (patch)
treed6c4b98a9c3fd9981e7fcc5d7729c9e01e327767 /drivers/input/keyboard/atkbd.c
parent8caf89157d64f1eedba37113afb4b303b2b3e301 (diff)
parent6fbfddcb52d8d9fa2cd209f5ac2a1c87497d55b5 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
Diffstat (limited to 'drivers/input/keyboard/atkbd.c')
-rw-r--r--drivers/input/keyboard/atkbd.c188
1 files changed, 102 insertions, 86 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 1ad8c2ee7dbf..820c7fd9a604 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -185,12 +185,12 @@ static struct {
185 185
186struct atkbd { 186struct atkbd {
187 187
188 struct ps2dev ps2dev; 188 struct ps2dev ps2dev;
189 struct input_dev *dev;
189 190
190 /* Written only during init */ 191 /* Written only during init */
191 char name[64]; 192 char name[64];
192 char phys[32]; 193 char phys[32];
193 struct input_dev dev;
194 194
195 unsigned short id; 195 unsigned short id;
196 unsigned char keycode[512]; 196 unsigned char keycode[512];
@@ -290,7 +290,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
290 if (!atkbd->enabled) 290 if (!atkbd->enabled)
291 goto out; 291 goto out;
292 292
293 input_event(&atkbd->dev, EV_MSC, MSC_RAW, code); 293 input_event(atkbd->dev, EV_MSC, MSC_RAW, code);
294 294
295 if (atkbd->translated) { 295 if (atkbd->translated) {
296 296
@@ -326,10 +326,10 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
326 atkbd->release = 1; 326 atkbd->release = 1;
327 goto out; 327 goto out;
328 case ATKBD_RET_HANGUEL: 328 case ATKBD_RET_HANGUEL:
329 atkbd_report_key(&atkbd->dev, regs, KEY_HANGUEL, 3); 329 atkbd_report_key(atkbd->dev, regs, KEY_HANGUEL, 3);
330 goto out; 330 goto out;
331 case ATKBD_RET_HANJA: 331 case ATKBD_RET_HANJA:
332 atkbd_report_key(&atkbd->dev, regs, KEY_HANJA, 3); 332 atkbd_report_key(atkbd->dev, regs, KEY_HANJA, 3);
333 goto out; 333 goto out;
334 case ATKBD_RET_ERR: 334 case ATKBD_RET_ERR:
335 printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); 335 printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
@@ -345,7 +345,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
345 } 345 }
346 346
347 if (atkbd->keycode[code] != ATKBD_KEY_NULL) 347 if (atkbd->keycode[code] != ATKBD_KEY_NULL)
348 input_event(&atkbd->dev, EV_MSC, MSC_SCAN, code); 348 input_event(atkbd->dev, EV_MSC, MSC_SCAN, code);
349 349
350 switch (atkbd->keycode[code]) { 350 switch (atkbd->keycode[code]) {
351 case ATKBD_KEY_NULL: 351 case ATKBD_KEY_NULL:
@@ -365,7 +365,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
365 "to make it known.\n", 365 "to make it known.\n",
366 code & 0x80 ? "e0" : "", code & 0x7f); 366 code & 0x80 ? "e0" : "", code & 0x7f);
367 } 367 }
368 input_sync(&atkbd->dev); 368 input_sync(atkbd->dev);
369 break; 369 break;
370 case ATKBD_SCR_1: 370 case ATKBD_SCR_1:
371 scroll = 1 - atkbd->release * 2; 371 scroll = 1 - atkbd->release * 2;
@@ -390,7 +390,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
390 break; 390 break;
391 default: 391 default:
392 value = atkbd->release ? 0 : 392 value = atkbd->release ? 0 :
393 (1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key))); 393 (1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev->key)));
394 394
395 switch (value) { /* Workaround Toshiba laptop multiple keypress */ 395 switch (value) { /* Workaround Toshiba laptop multiple keypress */
396 case 0: 396 case 0:
@@ -398,7 +398,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
398 break; 398 break;
399 case 1: 399 case 1:
400 atkbd->last = code; 400 atkbd->last = code;
401 atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev.rep[REP_DELAY]) / 2; 401 atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev->rep[REP_DELAY]) / 2;
402 break; 402 break;
403 case 2: 403 case 2:
404 if (!time_after(jiffies, atkbd->time) && atkbd->last == code) 404 if (!time_after(jiffies, atkbd->time) && atkbd->last == code)
@@ -406,16 +406,16 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
406 break; 406 break;
407 } 407 }
408 408
409 atkbd_report_key(&atkbd->dev, regs, atkbd->keycode[code], value); 409 atkbd_report_key(atkbd->dev, regs, atkbd->keycode[code], value);
410 } 410 }
411 411
412 if (atkbd->scroll) { 412 if (atkbd->scroll) {
413 input_regs(&atkbd->dev, regs); 413 input_regs(atkbd->dev, regs);
414 if (click != -1) 414 if (click != -1)
415 input_report_key(&atkbd->dev, BTN_MIDDLE, click); 415 input_report_key(atkbd->dev, BTN_MIDDLE, click);
416 input_report_rel(&atkbd->dev, REL_WHEEL, scroll); 416 input_report_rel(atkbd->dev, REL_WHEEL, scroll);
417 input_report_rel(&atkbd->dev, REL_HWHEEL, hscroll); 417 input_report_rel(atkbd->dev, REL_HWHEEL, hscroll);
418 input_sync(&atkbd->dev); 418 input_sync(atkbd->dev);
419 } 419 }
420 420
421 atkbd->release = 0; 421 atkbd->release = 0;
@@ -463,7 +463,6 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co
463 463
464 return 0; 464 return 0;
465 465
466
467 case EV_REP: 466 case EV_REP:
468 467
469 if (atkbd->softrepeat) return 0; 468 if (atkbd->softrepeat) return 0;
@@ -693,7 +692,7 @@ static void atkbd_disconnect(struct serio *serio)
693 device_remove_file(&serio->dev, &atkbd_attr_softrepeat); 692 device_remove_file(&serio->dev, &atkbd_attr_softrepeat);
694 device_remove_file(&serio->dev, &atkbd_attr_softraw); 693 device_remove_file(&serio->dev, &atkbd_attr_softraw);
695 694
696 input_unregister_device(&atkbd->dev); 695 input_unregister_device(atkbd->dev);
697 serio_close(serio); 696 serio_close(serio);
698 serio_set_drvdata(serio, NULL); 697 serio_set_drvdata(serio, NULL);
699 kfree(atkbd); 698 kfree(atkbd);
@@ -701,7 +700,7 @@ static void atkbd_disconnect(struct serio *serio)
701 700
702 701
703/* 702/*
704 * atkbd_set_device_attrs() initializes keyboard's keycode table 703 * atkbd_set_keycode_table() initializes keyboard's keycode table
705 * according to the selected scancode set 704 * according to the selected scancode set
706 */ 705 */
707 706
@@ -737,53 +736,58 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
737 736
738static void atkbd_set_device_attrs(struct atkbd *atkbd) 737static void atkbd_set_device_attrs(struct atkbd *atkbd)
739{ 738{
739 struct input_dev *input_dev = atkbd->dev;
740 int i; 740 int i;
741 741
742 memset(&atkbd->dev, 0, sizeof(struct input_dev)); 742 if (atkbd->extra)
743 sprintf(atkbd->name, "AT Set 2 Extra keyboard");
744 else
745 sprintf(atkbd->name, "AT %s Set %d keyboard",
746 atkbd->translated ? "Translated" : "Raw", atkbd->set);
743 747
744 init_input_dev(&atkbd->dev); 748 sprintf(atkbd->phys, "%s/input0", atkbd->ps2dev.serio->phys);
745 749
746 atkbd->dev.name = atkbd->name; 750 input_dev->name = atkbd->name;
747 atkbd->dev.phys = atkbd->phys; 751 input_dev->phys = atkbd->phys;
748 atkbd->dev.id.bustype = BUS_I8042; 752 input_dev->id.bustype = BUS_I8042;
749 atkbd->dev.id.vendor = 0x0001; 753 input_dev->id.vendor = 0x0001;
750 atkbd->dev.id.product = atkbd->translated ? 1 : atkbd->set; 754 input_dev->id.product = atkbd->translated ? 1 : atkbd->set;
751 atkbd->dev.id.version = atkbd->id; 755 input_dev->id.version = atkbd->id;
752 atkbd->dev.event = atkbd_event; 756 input_dev->event = atkbd_event;
753 atkbd->dev.private = atkbd; 757 input_dev->private = atkbd;
754 atkbd->dev.dev = &atkbd->ps2dev.serio->dev; 758 input_dev->cdev.dev = &atkbd->ps2dev.serio->dev;
755 759
756 atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC); 760 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
757 761
758 if (atkbd->write) { 762 if (atkbd->write) {
759 atkbd->dev.evbit[0] |= BIT(EV_LED); 763 input_dev->evbit[0] |= BIT(EV_LED);
760 atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); 764 input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
761 } 765 }
762 766
763 if (atkbd->extra) 767 if (atkbd->extra)
764 atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | 768 input_dev->ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) |
765 BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC); 769 BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
766 770
767 if (!atkbd->softrepeat) { 771 if (!atkbd->softrepeat) {
768 atkbd->dev.rep[REP_DELAY] = 250; 772 input_dev->rep[REP_DELAY] = 250;
769 atkbd->dev.rep[REP_PERIOD] = 33; 773 input_dev->rep[REP_PERIOD] = 33;
770 } 774 }
771 775
772 atkbd->dev.mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN); 776 input_dev->mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
773 777
774 if (atkbd->scroll) { 778 if (atkbd->scroll) {
775 atkbd->dev.evbit[0] |= BIT(EV_REL); 779 input_dev->evbit[0] |= BIT(EV_REL);
776 atkbd->dev.relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL); 780 input_dev->relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
777 set_bit(BTN_MIDDLE, atkbd->dev.keybit); 781 set_bit(BTN_MIDDLE, input_dev->keybit);
778 } 782 }
779 783
780 atkbd->dev.keycode = atkbd->keycode; 784 input_dev->keycode = atkbd->keycode;
781 atkbd->dev.keycodesize = sizeof(unsigned char); 785 input_dev->keycodesize = sizeof(unsigned char);
782 atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode); 786 input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
783 787
784 for (i = 0; i < 512; i++) 788 for (i = 0; i < 512; i++)
785 if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) 789 if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
786 set_bit(atkbd->keycode[i], atkbd->dev.keybit); 790 set_bit(atkbd->keycode[i], input_dev->keybit);
787} 791}
788 792
789/* 793/*
@@ -796,13 +800,15 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
796static int atkbd_connect(struct serio *serio, struct serio_driver *drv) 800static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
797{ 801{
798 struct atkbd *atkbd; 802 struct atkbd *atkbd;
799 int err; 803 struct input_dev *dev;
800 804 int err = -ENOMEM;
801 if (!(atkbd = kmalloc(sizeof(struct atkbd), GFP_KERNEL)))
802 return - ENOMEM;
803 805
804 memset(atkbd, 0, sizeof(struct atkbd)); 806 atkbd = kzalloc(sizeof(struct atkbd), GFP_KERNEL);
807 dev = input_allocate_device();
808 if (!atkbd || !dev)
809 goto fail;
805 810
811 atkbd->dev = dev;
806 ps2_init(&atkbd->ps2dev, serio); 812 ps2_init(&atkbd->ps2dev, serio);
807 813
808 switch (serio->id.type) { 814 switch (serio->id.type) {
@@ -828,19 +834,15 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
828 serio_set_drvdata(serio, atkbd); 834 serio_set_drvdata(serio, atkbd);
829 835
830 err = serio_open(serio, drv); 836 err = serio_open(serio, drv);
831 if (err) { 837 if (err)
832 serio_set_drvdata(serio, NULL); 838 goto fail;
833 kfree(atkbd);
834 return err;
835 }
836 839
837 if (atkbd->write) { 840 if (atkbd->write) {
838 841
839 if (atkbd_probe(atkbd)) { 842 if (atkbd_probe(atkbd)) {
840 serio_close(serio); 843 serio_close(serio);
841 serio_set_drvdata(serio, NULL); 844 err = -ENODEV;
842 kfree(atkbd); 845 goto fail;
843 return -ENODEV;
844 } 846 }
845 847
846 atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra); 848 atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
@@ -851,19 +853,9 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
851 atkbd->id = 0xab00; 853 atkbd->id = 0xab00;
852 } 854 }
853 855
854 if (atkbd->extra)
855 sprintf(atkbd->name, "AT Set 2 Extra keyboard");
856 else
857 sprintf(atkbd->name, "AT %s Set %d keyboard",
858 atkbd->translated ? "Translated" : "Raw", atkbd->set);
859
860 sprintf(atkbd->phys, "%s/input0", serio->phys);
861
862 atkbd_set_keycode_table(atkbd); 856 atkbd_set_keycode_table(atkbd);
863 atkbd_set_device_attrs(atkbd); 857 atkbd_set_device_attrs(atkbd);
864 858
865 input_register_device(&atkbd->dev);
866
867 device_create_file(&serio->dev, &atkbd_attr_extra); 859 device_create_file(&serio->dev, &atkbd_attr_extra);
868 device_create_file(&serio->dev, &atkbd_attr_scroll); 860 device_create_file(&serio->dev, &atkbd_attr_scroll);
869 device_create_file(&serio->dev, &atkbd_attr_set); 861 device_create_file(&serio->dev, &atkbd_attr_set);
@@ -872,9 +864,14 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
872 864
873 atkbd_enable(atkbd); 865 atkbd_enable(atkbd);
874 866
875 printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys); 867 input_register_device(atkbd->dev);
876 868
877 return 0; 869 return 0;
870
871 fail: serio_set_drvdata(serio, NULL);
872 input_free_device(dev);
873 kfree(atkbd);
874 return err;
878} 875}
879 876
880/* 877/*
@@ -896,9 +893,9 @@ static int atkbd_reconnect(struct serio *serio)
896 atkbd_disable(atkbd); 893 atkbd_disable(atkbd);
897 894
898 if (atkbd->write) { 895 if (atkbd->write) {
899 param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0) 896 param[0] = (test_bit(LED_SCROLLL, atkbd->dev->led) ? 1 : 0)
900 | (test_bit(LED_NUML, atkbd->dev.led) ? 2 : 0) 897 | (test_bit(LED_NUML, atkbd->dev->led) ? 2 : 0)
901 | (test_bit(LED_CAPSL, atkbd->dev.led) ? 4 : 0); 898 | (test_bit(LED_CAPSL, atkbd->dev->led) ? 4 : 0);
902 899
903 if (atkbd_probe(atkbd)) 900 if (atkbd_probe(atkbd))
904 return -1; 901 return -1;
@@ -1008,6 +1005,7 @@ static ssize_t atkbd_show_extra(struct atkbd *atkbd, char *buf)
1008 1005
1009static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count) 1006static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count)
1010{ 1007{
1008 struct input_dev *new_dev;
1011 unsigned long value; 1009 unsigned long value;
1012 char *rest; 1010 char *rest;
1013 1011
@@ -1019,12 +1017,19 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
1019 return -EINVAL; 1017 return -EINVAL;
1020 1018
1021 if (atkbd->extra != value) { 1019 if (atkbd->extra != value) {
1022 /* unregister device as it's properties will change */ 1020 /*
1023 input_unregister_device(&atkbd->dev); 1021 * Since device's properties will change we need to
1022 * unregister old device. But allocate new one first
1023 * to make sure we have it.
1024 */
1025 if (!(new_dev = input_allocate_device()))
1026 return -ENOMEM;
1027 input_unregister_device(atkbd->dev);
1028 atkbd->dev = new_dev;
1024 atkbd->set = atkbd_select_set(atkbd, atkbd->set, value); 1029 atkbd->set = atkbd_select_set(atkbd, atkbd->set, value);
1025 atkbd_activate(atkbd); 1030 atkbd_activate(atkbd);
1026 atkbd_set_device_attrs(atkbd); 1031 atkbd_set_device_attrs(atkbd);
1027 input_register_device(&atkbd->dev); 1032 input_register_device(atkbd->dev);
1028 } 1033 }
1029 return count; 1034 return count;
1030} 1035}
@@ -1036,6 +1041,7 @@ static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf)
1036 1041
1037static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count) 1042static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count)
1038{ 1043{
1044 struct input_dev *new_dev;
1039 unsigned long value; 1045 unsigned long value;
1040 char *rest; 1046 char *rest;
1041 1047
@@ -1044,12 +1050,14 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou
1044 return -EINVAL; 1050 return -EINVAL;
1045 1051
1046 if (atkbd->scroll != value) { 1052 if (atkbd->scroll != value) {
1047 /* unregister device as it's properties will change */ 1053 if (!(new_dev = input_allocate_device()))
1048 input_unregister_device(&atkbd->dev); 1054 return -ENOMEM;
1055 input_unregister_device(atkbd->dev);
1056 atkbd->dev = new_dev;
1049 atkbd->scroll = value; 1057 atkbd->scroll = value;
1050 atkbd_set_keycode_table(atkbd); 1058 atkbd_set_keycode_table(atkbd);
1051 atkbd_set_device_attrs(atkbd); 1059 atkbd_set_device_attrs(atkbd);
1052 input_register_device(&atkbd->dev); 1060 input_register_device(atkbd->dev);
1053 } 1061 }
1054 return count; 1062 return count;
1055} 1063}
@@ -1061,6 +1069,7 @@ static ssize_t atkbd_show_set(struct atkbd *atkbd, char *buf)
1061 1069
1062static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) 1070static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
1063{ 1071{
1072 struct input_dev *new_dev;
1064 unsigned long value; 1073 unsigned long value;
1065 char *rest; 1074 char *rest;
1066 1075
@@ -1072,13 +1081,15 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
1072 return -EINVAL; 1081 return -EINVAL;
1073 1082
1074 if (atkbd->set != value) { 1083 if (atkbd->set != value) {
1075 /* unregister device as it's properties will change */ 1084 if (!(new_dev = input_allocate_device()))
1076 input_unregister_device(&atkbd->dev); 1085 return -ENOMEM;
1086 input_unregister_device(atkbd->dev);
1087 atkbd->dev = new_dev;
1077 atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra); 1088 atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra);
1078 atkbd_activate(atkbd); 1089 atkbd_activate(atkbd);
1079 atkbd_set_keycode_table(atkbd); 1090 atkbd_set_keycode_table(atkbd);
1080 atkbd_set_device_attrs(atkbd); 1091 atkbd_set_device_attrs(atkbd);
1081 input_register_device(&atkbd->dev); 1092 input_register_device(atkbd->dev);
1082 } 1093 }
1083 return count; 1094 return count;
1084} 1095}
@@ -1090,6 +1101,7 @@ static ssize_t atkbd_show_softrepeat(struct atkbd *atkbd, char *buf)
1090 1101
1091static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count) 1102static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count)
1092{ 1103{
1104 struct input_dev *new_dev;
1093 unsigned long value; 1105 unsigned long value;
1094 char *rest; 1106 char *rest;
1095 1107
@@ -1101,15 +1113,16 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t
1101 return -EINVAL; 1113 return -EINVAL;
1102 1114
1103 if (atkbd->softrepeat != value) { 1115 if (atkbd->softrepeat != value) {
1104 /* unregister device as it's properties will change */ 1116 if (!(new_dev = input_allocate_device()))
1105 input_unregister_device(&atkbd->dev); 1117 return -ENOMEM;
1118 input_unregister_device(atkbd->dev);
1119 atkbd->dev = new_dev;
1106 atkbd->softrepeat = value; 1120 atkbd->softrepeat = value;
1107 if (atkbd->softrepeat) 1121 if (atkbd->softrepeat)
1108 atkbd->softraw = 1; 1122 atkbd->softraw = 1;
1109 atkbd_set_device_attrs(atkbd); 1123 atkbd_set_device_attrs(atkbd);
1110 input_register_device(&atkbd->dev); 1124 input_register_device(atkbd->dev);
1111 } 1125 }
1112
1113 return count; 1126 return count;
1114} 1127}
1115 1128
@@ -1121,6 +1134,7 @@ static ssize_t atkbd_show_softraw(struct atkbd *atkbd, char *buf)
1121 1134
1122static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count) 1135static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count)
1123{ 1136{
1137 struct input_dev *new_dev;
1124 unsigned long value; 1138 unsigned long value;
1125 char *rest; 1139 char *rest;
1126 1140
@@ -1129,11 +1143,13 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co
1129 return -EINVAL; 1143 return -EINVAL;
1130 1144
1131 if (atkbd->softraw != value) { 1145 if (atkbd->softraw != value) {
1132 /* unregister device as it's properties will change */ 1146 if (!(new_dev = input_allocate_device()))
1133 input_unregister_device(&atkbd->dev); 1147 return -ENOMEM;
1148 input_unregister_device(atkbd->dev);
1149 atkbd->dev = new_dev;
1134 atkbd->softraw = value; 1150 atkbd->softraw = value;
1135 atkbd_set_device_attrs(atkbd); 1151 atkbd_set_device_attrs(atkbd);
1136 input_register_device(&atkbd->dev); 1152 input_register_device(atkbd->dev);
1137 } 1153 }
1138 return count; 1154 return count;
1139} 1155}