diff options
| -rw-r--r-- | drivers/input/input.c | 39 | ||||
| -rw-r--r-- | include/linux/input.h | 79 | ||||
| -rw-r--r-- | scripts/mod/file2alias.c | 62 |
3 files changed, 141 insertions, 39 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index 2d37b394e384..ef5824c8846b 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -528,10 +528,49 @@ INPUT_DEV_STRING_ATTR_SHOW(name); | |||
| 528 | INPUT_DEV_STRING_ATTR_SHOW(phys); | 528 | INPUT_DEV_STRING_ATTR_SHOW(phys); |
| 529 | INPUT_DEV_STRING_ATTR_SHOW(uniq); | 529 | INPUT_DEV_STRING_ATTR_SHOW(uniq); |
| 530 | 530 | ||
| 531 | static int print_modalias_bits(char *buf, char prefix, unsigned long *arr, | ||
| 532 | unsigned int min, unsigned int max) | ||
| 533 | { | ||
| 534 | int len, i; | ||
| 535 | |||
| 536 | len = sprintf(buf, "%c", prefix); | ||
| 537 | for (i = min; i < max; i++) | ||
| 538 | if (arr[LONG(i)] & BIT(i)) | ||
| 539 | len += sprintf(buf+len, "%X,", i); | ||
| 540 | return len; | ||
| 541 | } | ||
| 542 | |||
| 543 | static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf) | ||
| 544 | { | ||
| 545 | struct input_dev *id = to_input_dev(dev); | ||
| 546 | ssize_t len = 0; | ||
| 547 | |||
| 548 | len += sprintf(buf+len, "input:b%04Xv%04Xp%04Xe%04X-", | ||
| 549 | id->id.bustype, | ||
| 550 | id->id.vendor, | ||
| 551 | id->id.product, | ||
| 552 | id->id.version); | ||
| 553 | |||
| 554 | len += print_modalias_bits(buf+len, 'e', id->evbit, 0, EV_MAX); | ||
| 555 | len += print_modalias_bits(buf+len, 'k', id->keybit, | ||
| 556 | KEY_MIN_INTERESTING, KEY_MAX); | ||
| 557 | len += print_modalias_bits(buf+len, 'r', id->relbit, 0, REL_MAX); | ||
| 558 | len += print_modalias_bits(buf+len, 'a', id->absbit, 0, ABS_MAX); | ||
| 559 | len += print_modalias_bits(buf+len, 'm', id->mscbit, 0, MSC_MAX); | ||
| 560 | len += print_modalias_bits(buf+len, 'l', id->ledbit, 0, LED_MAX); | ||
| 561 | len += print_modalias_bits(buf+len, 's', id->sndbit, 0, SND_MAX); | ||
| 562 | len += print_modalias_bits(buf+len, 'f', id->ffbit, 0, FF_MAX); | ||
| 563 | len += print_modalias_bits(buf+len, 'w', id->swbit, 0, SW_MAX); | ||
| 564 | len += sprintf(buf+len, "\n"); | ||
| 565 | return len; | ||
| 566 | } | ||
| 567 | static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); | ||
| 568 | |||
| 531 | static struct attribute *input_dev_attrs[] = { | 569 | static struct attribute *input_dev_attrs[] = { |
| 532 | &class_device_attr_name.attr, | 570 | &class_device_attr_name.attr, |
| 533 | &class_device_attr_phys.attr, | 571 | &class_device_attr_phys.attr, |
| 534 | &class_device_attr_uniq.attr, | 572 | &class_device_attr_uniq.attr, |
| 573 | &class_device_attr_modalias.attr, | ||
| 535 | NULL | 574 | NULL |
| 536 | }; | 575 | }; |
| 537 | 576 | ||
diff --git a/include/linux/input.h b/include/linux/input.h index 3c5823368ddb..bef08551a33b 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <sys/ioctl.h> | 18 | #include <sys/ioctl.h> |
| 19 | #include <asm/types.h> | 19 | #include <asm/types.h> |
| 20 | #endif | 20 | #endif |
| 21 | #include <linux/mod_devicetable.h> | ||
| 21 | 22 | ||
| 22 | /* | 23 | /* |
| 23 | * The event structure itself | 24 | * The event structure itself |
| @@ -511,6 +512,8 @@ struct input_absinfo { | |||
| 511 | #define KEY_FN_S 0x1e3 | 512 | #define KEY_FN_S 0x1e3 |
| 512 | #define KEY_FN_B 0x1e4 | 513 | #define KEY_FN_B 0x1e4 |
| 513 | 514 | ||
| 515 | /* We avoid low common keys in module aliases so they don't get huge. */ | ||
| 516 | #define KEY_MIN_INTERESTING KEY_MUTE | ||
| 514 | #define KEY_MAX 0x1ff | 517 | #define KEY_MAX 0x1ff |
| 515 | 518 | ||
| 516 | /* | 519 | /* |
| @@ -793,6 +796,44 @@ struct ff_effect { | |||
| 793 | 796 | ||
| 794 | #define FF_MAX 0x7f | 797 | #define FF_MAX 0x7f |
| 795 | 798 | ||
| 799 | struct input_device_id { | ||
| 800 | |||
| 801 | kernel_ulong_t flags; | ||
| 802 | |||
| 803 | struct input_id id; | ||
| 804 | |||
| 805 | kernel_ulong_t evbit[EV_MAX/BITS_PER_LONG+1]; | ||
| 806 | kernel_ulong_t keybit[KEY_MAX/BITS_PER_LONG+1]; | ||
| 807 | kernel_ulong_t relbit[REL_MAX/BITS_PER_LONG+1]; | ||
| 808 | kernel_ulong_t absbit[ABS_MAX/BITS_PER_LONG+1]; | ||
| 809 | kernel_ulong_t mscbit[MSC_MAX/BITS_PER_LONG+1]; | ||
| 810 | kernel_ulong_t ledbit[LED_MAX/BITS_PER_LONG+1]; | ||
| 811 | kernel_ulong_t sndbit[SND_MAX/BITS_PER_LONG+1]; | ||
| 812 | kernel_ulong_t ffbit[FF_MAX/BITS_PER_LONG+1]; | ||
| 813 | kernel_ulong_t swbit[SW_MAX/BITS_PER_LONG+1]; | ||
| 814 | |||
| 815 | kernel_ulong_t driver_info; | ||
| 816 | }; | ||
| 817 | |||
| 818 | /* | ||
| 819 | * Structure for hotplug & device<->driver matching. | ||
| 820 | */ | ||
| 821 | |||
| 822 | #define INPUT_DEVICE_ID_MATCH_BUS 1 | ||
| 823 | #define INPUT_DEVICE_ID_MATCH_VENDOR 2 | ||
| 824 | #define INPUT_DEVICE_ID_MATCH_PRODUCT 4 | ||
| 825 | #define INPUT_DEVICE_ID_MATCH_VERSION 8 | ||
| 826 | |||
| 827 | #define INPUT_DEVICE_ID_MATCH_EVBIT 0x010 | ||
| 828 | #define INPUT_DEVICE_ID_MATCH_KEYBIT 0x020 | ||
| 829 | #define INPUT_DEVICE_ID_MATCH_RELBIT 0x040 | ||
| 830 | #define INPUT_DEVICE_ID_MATCH_ABSBIT 0x080 | ||
| 831 | #define INPUT_DEVICE_ID_MATCH_MSCIT 0x100 | ||
| 832 | #define INPUT_DEVICE_ID_MATCH_LEDBIT 0x200 | ||
| 833 | #define INPUT_DEVICE_ID_MATCH_SNDBIT 0x400 | ||
| 834 | #define INPUT_DEVICE_ID_MATCH_FFBIT 0x800 | ||
| 835 | #define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000 | ||
| 836 | |||
| 796 | #ifdef __KERNEL__ | 837 | #ifdef __KERNEL__ |
| 797 | 838 | ||
| 798 | /* | 839 | /* |
| @@ -901,49 +942,11 @@ struct input_dev { | |||
| 901 | }; | 942 | }; |
| 902 | #define to_input_dev(d) container_of(d, struct input_dev, cdev) | 943 | #define to_input_dev(d) container_of(d, struct input_dev, cdev) |
| 903 | 944 | ||
| 904 | /* | ||
| 905 | * Structure for hotplug & device<->driver matching. | ||
| 906 | */ | ||
| 907 | |||
| 908 | #define INPUT_DEVICE_ID_MATCH_BUS 1 | ||
| 909 | #define INPUT_DEVICE_ID_MATCH_VENDOR 2 | ||
| 910 | #define INPUT_DEVICE_ID_MATCH_PRODUCT 4 | ||
| 911 | #define INPUT_DEVICE_ID_MATCH_VERSION 8 | ||
| 912 | |||
| 913 | #define INPUT_DEVICE_ID_MATCH_EVBIT 0x010 | ||
| 914 | #define INPUT_DEVICE_ID_MATCH_KEYBIT 0x020 | ||
| 915 | #define INPUT_DEVICE_ID_MATCH_RELBIT 0x040 | ||
| 916 | #define INPUT_DEVICE_ID_MATCH_ABSBIT 0x080 | ||
| 917 | #define INPUT_DEVICE_ID_MATCH_MSCIT 0x100 | ||
| 918 | #define INPUT_DEVICE_ID_MATCH_LEDBIT 0x200 | ||
| 919 | #define INPUT_DEVICE_ID_MATCH_SNDBIT 0x400 | ||
| 920 | #define INPUT_DEVICE_ID_MATCH_FFBIT 0x800 | ||
| 921 | #define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000 | ||
| 922 | |||
| 923 | #define INPUT_DEVICE_ID_MATCH_DEVICE\ | 945 | #define INPUT_DEVICE_ID_MATCH_DEVICE\ |
| 924 | (INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT) | 946 | (INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT) |
| 925 | #define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION\ | 947 | #define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION\ |
| 926 | (INPUT_DEVICE_ID_MATCH_DEVICE | INPUT_DEVICE_ID_MATCH_VERSION) | 948 | (INPUT_DEVICE_ID_MATCH_DEVICE | INPUT_DEVICE_ID_MATCH_VERSION) |
| 927 | 949 | ||
| 928 | struct input_device_id { | ||
| 929 | |||
| 930 | unsigned long flags; | ||
| 931 | |||
| 932 | struct input_id id; | ||
| 933 | |||
| 934 | unsigned long evbit[NBITS(EV_MAX)]; | ||
| 935 | unsigned long keybit[NBITS(KEY_MAX)]; | ||
| 936 | unsigned long relbit[NBITS(REL_MAX)]; | ||
| 937 | unsigned long absbit[NBITS(ABS_MAX)]; | ||
| 938 | unsigned long mscbit[NBITS(MSC_MAX)]; | ||
| 939 | unsigned long ledbit[NBITS(LED_MAX)]; | ||
| 940 | unsigned long sndbit[NBITS(SND_MAX)]; | ||
| 941 | unsigned long ffbit[NBITS(FF_MAX)]; | ||
| 942 | unsigned long swbit[NBITS(SW_MAX)]; | ||
| 943 | |||
| 944 | unsigned long driver_info; | ||
| 945 | }; | ||
| 946 | |||
| 947 | struct input_handle; | 950 | struct input_handle; |
| 948 | 951 | ||
| 949 | struct input_handler { | 952 | struct input_handler { |
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index e3d144a3f10b..e0eedffe565b 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
| @@ -16,8 +16,10 @@ | |||
| 16 | * use either stdint.h or inttypes.h for the rest. */ | 16 | * use either stdint.h or inttypes.h for the rest. */ |
| 17 | #if KERNEL_ELFCLASS == ELFCLASS32 | 17 | #if KERNEL_ELFCLASS == ELFCLASS32 |
| 18 | typedef Elf32_Addr kernel_ulong_t; | 18 | typedef Elf32_Addr kernel_ulong_t; |
| 19 | #define BITS_PER_LONG 32 | ||
| 19 | #else | 20 | #else |
| 20 | typedef Elf64_Addr kernel_ulong_t; | 21 | typedef Elf64_Addr kernel_ulong_t; |
| 22 | #define BITS_PER_LONG 64 | ||
| 21 | #endif | 23 | #endif |
| 22 | #ifdef __sun__ | 24 | #ifdef __sun__ |
| 23 | #include <inttypes.h> | 25 | #include <inttypes.h> |
| @@ -35,6 +37,7 @@ typedef unsigned char __u8; | |||
| 35 | * even potentially has different endianness and word sizes, since | 37 | * even potentially has different endianness and word sizes, since |
| 36 | * we handle those differences explicitly below */ | 38 | * we handle those differences explicitly below */ |
| 37 | #include "../../include/linux/mod_devicetable.h" | 39 | #include "../../include/linux/mod_devicetable.h" |
| 40 | #include "../../include/linux/input.h" | ||
| 38 | 41 | ||
| 39 | #define ADD(str, sep, cond, field) \ | 42 | #define ADD(str, sep, cond, field) \ |
| 40 | do { \ | 43 | do { \ |
| @@ -366,6 +369,61 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *i2c, char *a | |||
| 366 | return 1; | 369 | return 1; |
| 367 | } | 370 | } |
| 368 | 371 | ||
| 372 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
| 373 | |||
| 374 | static void do_input(char *alias, | ||
| 375 | kernel_ulong_t *arr, unsigned int min, unsigned int max) | ||
| 376 | { | ||
| 377 | unsigned int i; | ||
| 378 | for (i = min; i < max; i++) { | ||
| 379 | if (arr[i/BITS_PER_LONG] & (1 << (i%BITS_PER_LONG))) | ||
| 380 | sprintf(alias+strlen(alias), "%X,*", i); | ||
| 381 | } | ||
| 382 | } | ||
| 383 | |||
| 384 | /* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */ | ||
| 385 | static int do_input_entry(const char *filename, struct input_device_id *id, | ||
| 386 | char *alias) | ||
| 387 | { | ||
| 388 | sprintf(alias, "input:"); | ||
| 389 | |||
| 390 | ADD(alias, "b", id->flags&INPUT_DEVICE_ID_MATCH_BUS, id->id.bustype); | ||
| 391 | ADD(alias, "v", id->flags&INPUT_DEVICE_ID_MATCH_VENDOR, id->id.vendor); | ||
| 392 | ADD(alias, "p", id->flags&INPUT_DEVICE_ID_MATCH_PRODUCT, | ||
| 393 | id->id.product); | ||
| 394 | ADD(alias, "e", id->flags&INPUT_DEVICE_ID_MATCH_VERSION, | ||
| 395 | id->id.version); | ||
| 396 | |||
| 397 | sprintf(alias + strlen(alias), "-e*"); | ||
| 398 | if (id->flags&INPUT_DEVICE_ID_MATCH_EVBIT) | ||
| 399 | do_input(alias, id->evbit, 0, EV_MAX); | ||
| 400 | sprintf(alias + strlen(alias), "k*"); | ||
| 401 | if (id->flags&INPUT_DEVICE_ID_MATCH_KEYBIT) | ||
| 402 | do_input(alias, id->keybit, KEY_MIN_INTERESTING, KEY_MAX); | ||
| 403 | sprintf(alias + strlen(alias), "r*"); | ||
| 404 | if (id->flags&INPUT_DEVICE_ID_MATCH_RELBIT) | ||
| 405 | do_input(alias, id->relbit, 0, REL_MAX); | ||
| 406 | sprintf(alias + strlen(alias), "a*"); | ||
| 407 | if (id->flags&INPUT_DEVICE_ID_MATCH_ABSBIT) | ||
| 408 | do_input(alias, id->absbit, 0, ABS_MAX); | ||
| 409 | sprintf(alias + strlen(alias), "m*"); | ||
| 410 | if (id->flags&INPUT_DEVICE_ID_MATCH_MSCIT) | ||
| 411 | do_input(alias, id->mscbit, 0, MSC_MAX); | ||
| 412 | sprintf(alias + strlen(alias), "l*"); | ||
| 413 | if (id->flags&INPUT_DEVICE_ID_MATCH_LEDBIT) | ||
| 414 | do_input(alias, id->ledbit, 0, LED_MAX); | ||
| 415 | sprintf(alias + strlen(alias), "s*"); | ||
| 416 | if (id->flags&INPUT_DEVICE_ID_MATCH_SNDBIT) | ||
| 417 | do_input(alias, id->sndbit, 0, SND_MAX); | ||
| 418 | sprintf(alias + strlen(alias), "f*"); | ||
| 419 | if (id->flags&INPUT_DEVICE_ID_MATCH_FFBIT) | ||
| 420 | do_input(alias, id->ffbit, 0, SND_MAX); | ||
| 421 | sprintf(alias + strlen(alias), "w*"); | ||
| 422 | if (id->flags&INPUT_DEVICE_ID_MATCH_SWBIT) | ||
| 423 | do_input(alias, id->swbit, 0, SW_MAX); | ||
| 424 | return 1; | ||
| 425 | } | ||
| 426 | |||
| 369 | /* Ignore any prefix, eg. v850 prepends _ */ | 427 | /* Ignore any prefix, eg. v850 prepends _ */ |
| 370 | static inline int sym_is(const char *symbol, const char *name) | 428 | static inline int sym_is(const char *symbol, const char *name) |
| 371 | { | 429 | { |
| @@ -453,7 +511,9 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
| 453 | else if (sym_is(symname, "__mod_i2c_device_table")) | 511 | else if (sym_is(symname, "__mod_i2c_device_table")) |
| 454 | do_table(symval, sym->st_size, sizeof(struct i2c_device_id), | 512 | do_table(symval, sym->st_size, sizeof(struct i2c_device_id), |
| 455 | do_i2c_entry, mod); | 513 | do_i2c_entry, mod); |
| 456 | 514 | else if (sym_is(symname, "__mod_input_device_table")) | |
| 515 | do_table(symval, sym->st_size, sizeof(struct input_device_id), | ||
| 516 | do_input_entry, mod); | ||
| 457 | } | 517 | } |
| 458 | 518 | ||
| 459 | /* Now add out buffered information to the generated C source */ | 519 | /* Now add out buffered information to the generated C source */ |
