diff options
-rw-r--r-- | drivers/base/platform.c | 23 | ||||
-rw-r--r-- | include/linux/mod_devicetable.h | 9 | ||||
-rw-r--r-- | include/linux/platform_device.h | 6 | ||||
-rw-r--r-- | scripts/mod/file2alias.c | 12 |
4 files changed, 49 insertions, 1 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 62a8768d96b3..ec993aa6a2ca 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -584,10 +584,25 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
584 | { | 584 | { |
585 | struct platform_device *pdev = to_platform_device(dev); | 585 | struct platform_device *pdev = to_platform_device(dev); |
586 | 586 | ||
587 | add_uevent_var(env, "MODALIAS=platform:%s", pdev->name); | 587 | add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, |
588 | (pdev->id_entry) ? pdev->id_entry->name : pdev->name); | ||
588 | return 0; | 589 | return 0; |
589 | } | 590 | } |
590 | 591 | ||
592 | static const struct platform_device_id *platform_match_id( | ||
593 | struct platform_device_id *id, | ||
594 | struct platform_device *pdev) | ||
595 | { | ||
596 | while (id->name[0]) { | ||
597 | if (strcmp(pdev->name, id->name) == 0) { | ||
598 | pdev->id_entry = id; | ||
599 | return id; | ||
600 | } | ||
601 | id++; | ||
602 | } | ||
603 | return NULL; | ||
604 | } | ||
605 | |||
591 | /** | 606 | /** |
592 | * platform_match - bind platform device to platform driver. | 607 | * platform_match - bind platform device to platform driver. |
593 | * @dev: device. | 608 | * @dev: device. |
@@ -604,7 +619,13 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
604 | static int platform_match(struct device *dev, struct device_driver *drv) | 619 | static int platform_match(struct device *dev, struct device_driver *drv) |
605 | { | 620 | { |
606 | struct platform_device *pdev = to_platform_device(dev); | 621 | struct platform_device *pdev = to_platform_device(dev); |
622 | struct platform_driver *pdrv = to_platform_driver(drv); | ||
623 | |||
624 | /* match against the id table first */ | ||
625 | if (pdrv->id_table) | ||
626 | return platform_match_id(pdrv->id_table, pdev) != NULL; | ||
607 | 627 | ||
628 | /* fall-back to driver name match */ | ||
608 | return (strcmp(pdev->name, drv->name) == 0); | 629 | return (strcmp(pdev->name, drv->name) == 0); |
609 | } | 630 | } |
610 | 631 | ||
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index fde86671f48f..1bf5900ffe43 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h | |||
@@ -454,4 +454,13 @@ struct dmi_system_id { | |||
454 | 454 | ||
455 | #define DMI_MATCH(a, b) { a, b } | 455 | #define DMI_MATCH(a, b) { a, b } |
456 | 456 | ||
457 | #define PLATFORM_NAME_SIZE 20 | ||
458 | #define PLATFORM_MODULE_PREFIX "platform:" | ||
459 | |||
460 | struct platform_device_id { | ||
461 | char name[PLATFORM_NAME_SIZE]; | ||
462 | kernel_ulong_t driver_data | ||
463 | __attribute__((aligned(sizeof(kernel_ulong_t)))); | ||
464 | }; | ||
465 | |||
457 | #endif /* LINUX_MOD_DEVICETABLE_H */ | 466 | #endif /* LINUX_MOD_DEVICETABLE_H */ |
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 9a342699c607..76aef7be32ab 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #define _PLATFORM_DEVICE_H_ | 12 | #define _PLATFORM_DEVICE_H_ |
13 | 13 | ||
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/mod_devicetable.h> | ||
15 | 16 | ||
16 | struct platform_device { | 17 | struct platform_device { |
17 | const char * name; | 18 | const char * name; |
@@ -19,8 +20,12 @@ struct platform_device { | |||
19 | struct device dev; | 20 | struct device dev; |
20 | u32 num_resources; | 21 | u32 num_resources; |
21 | struct resource * resource; | 22 | struct resource * resource; |
23 | |||
24 | struct platform_device_id *id_entry; | ||
22 | }; | 25 | }; |
23 | 26 | ||
27 | #define platform_get_device_id(pdev) ((pdev)->id_entry) | ||
28 | |||
24 | #define to_platform_device(x) container_of((x), struct platform_device, dev) | 29 | #define to_platform_device(x) container_of((x), struct platform_device, dev) |
25 | 30 | ||
26 | extern int platform_device_register(struct platform_device *); | 31 | extern int platform_device_register(struct platform_device *); |
@@ -56,6 +61,7 @@ struct platform_driver { | |||
56 | int (*resume_early)(struct platform_device *); | 61 | int (*resume_early)(struct platform_device *); |
57 | int (*resume)(struct platform_device *); | 62 | int (*resume)(struct platform_device *); |
58 | struct device_driver driver; | 63 | struct device_driver driver; |
64 | struct platform_device_id *id_table; | ||
59 | }; | 65 | }; |
60 | 66 | ||
61 | extern int platform_driver_register(struct platform_driver *); | 67 | extern int platform_driver_register(struct platform_driver *); |
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 4eea60b1693e..a3344285ccf4 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
@@ -710,6 +710,14 @@ static int do_dmi_entry(const char *filename, struct dmi_system_id *id, | |||
710 | strcat(alias, ":"); | 710 | strcat(alias, ":"); |
711 | return 1; | 711 | return 1; |
712 | } | 712 | } |
713 | |||
714 | static int do_platform_entry(const char *filename, | ||
715 | struct platform_device_id *id, char *alias) | ||
716 | { | ||
717 | sprintf(alias, PLATFORM_MODULE_PREFIX "%s", id->name); | ||
718 | return 1; | ||
719 | } | ||
720 | |||
713 | /* Ignore any prefix, eg. some architectures prepend _ */ | 721 | /* Ignore any prefix, eg. some architectures prepend _ */ |
714 | static inline int sym_is(const char *symbol, const char *name) | 722 | static inline int sym_is(const char *symbol, const char *name) |
715 | { | 723 | { |
@@ -849,6 +857,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
849 | do_table(symval, sym->st_size, | 857 | do_table(symval, sym->st_size, |
850 | sizeof(struct dmi_system_id), "dmi", | 858 | sizeof(struct dmi_system_id), "dmi", |
851 | do_dmi_entry, mod); | 859 | do_dmi_entry, mod); |
860 | else if (sym_is(symname, "__mod_platform_device_table")) | ||
861 | do_table(symval, sym->st_size, | ||
862 | sizeof(struct platform_device_id), "platform", | ||
863 | do_platform_entry, mod); | ||
852 | free(zeros); | 864 | free(zeros); |
853 | } | 865 | } |
854 | 866 | ||