diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-28 16:09:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-28 16:09:47 -0400 |
commit | 84860bf0644d7c45afe7ddbd30731c3e3c371fae (patch) | |
tree | d6c4b98a9c3fd9981e7fcc5d7729c9e01e327767 /drivers/input/keyboard/atkbd.c | |
parent | 8caf89157d64f1eedba37113afb4b303b2b3e301 (diff) | |
parent | 6fbfddcb52d8d9fa2cd209f5ac2a1c87497d55b5 (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.c | 188 |
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 | ||
186 | struct atkbd { | 186 | struct 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 | ||
738 | static void atkbd_set_device_attrs(struct atkbd *atkbd) | 737 | static 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) | |||
796 | static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | 800 | static 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 | ||
1009 | static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count) | 1006 | static 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 | ||
1037 | static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count) | 1042 | static 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 | ||
1062 | static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) | 1070 | static 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 | ||
1091 | static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count) | 1102 | static 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 | ||
1122 | static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count) | 1135 | static 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 | } |