W1: support for automatic family drivers loading via hotplug: - allow family drivers support list of families; - export supported families through MODULE_DEVICE_TABLE. Signed-off-by: Dmitry Torokhov <dtor at mail.ru> --- drivers/w1/w1.c | 6 ++++-- drivers/w1/w1.h | 3 ++- drivers/w1/w1_sernum.c | 9 ++++++++- drivers/w1/w1_thermal.c | 9 ++++++++- include/linux/mod_devicetable.h | 4 ++++ scripts/mod/file2alias.c | 16 ++++++++++++++++ 6 files changed, 42 insertions(+), 5 deletions(-) Index: dtor/drivers/w1/w1.c =================================================================== --- dtor.orig/drivers/w1/w1.c +++ dtor/drivers/w1/w1.c @@ -58,9 +58,11 @@ static int w1_bus_match(struct device *d */ struct w1_slave *slave = to_w1_slave(dev); struct w1_family *family = to_w1_family(drv); + struct w1_device_id *id; - if (slave->reg_num.family == family->fid) - return 1; + for (id = family->id_table; id->family; id++) + if (slave->reg_num.family == id->family) + return 1; return 0; } Index: dtor/drivers/w1/w1.h =================================================================== --- dtor.orig/drivers/w1/w1.h +++ dtor/drivers/w1/w1.h @@ -41,6 +41,7 @@ struct w1_reg_num #include <linux/completion.h> #include <linux/device.h> +#include <linux/mod_devicetable.h> #include <asm/semaphore.h> @@ -118,7 +119,7 @@ void w1_remove_master_device(struct w1_m struct w1_family { struct device_driver driver; - u8 fid; + struct w1_device_id *id_table; const char *name; int (*join)(struct w1_slave *); Index: dtor/drivers/w1/w1_thermal.c =================================================================== --- dtor.orig/drivers/w1/w1_thermal.c +++ dtor/drivers/w1/w1_thermal.c @@ -50,11 +50,18 @@ static void w1_thermal_leave(struct w1_s device_remove_file(&slave->dev, &w1_thermal_temperature_attr); } +static struct w1_device_id w1_thermal_ids[] = { + { .family = W1_FAMILY_THERMAL, }, + { } +}; + +MODULE_DEVICE_TABLE(w1, w1_thermal_ids); + static struct w1_family w1_thermal_family = { .driver = { .name = "thermal", }, - .fid = W1_FAMILY_THERMAL, + .id_table = w1_thermal_ids, .name = "Digital Thermometer Driver", .join = w1_thermal_join, .leave = w1_thermal_leave, Index: dtor/drivers/w1/w1_sernum.c =================================================================== --- dtor.orig/drivers/w1/w1_sernum.c +++ dtor/drivers/w1/w1_sernum.c @@ -40,11 +40,18 @@ MODULE_DESCRIPTION("1-Wire Silicon Seria * by W1 core. */ +static struct w1_device_id w1_serial_num_ids[] = { + { .family = W1_FAMILY_SERIAL_NUM, }, + { } +}; + +MODULE_DEVICE_TABLE(w1, w1_serial_num_ids); + static struct w1_family w1_serial_num_family = { .driver = { .name = "sernum", }, - .fid = W1_FAMILY_SERIAL_NUM, + .id_table = w1_serial_num_ids, .name = "Serial Number Driver", }; Index: dtor/scripts/mod/file2alias.c =================================================================== --- dtor.orig/scripts/mod/file2alias.c +++ dtor/scripts/mod/file2alias.c @@ -25,6 +25,7 @@ typedef Elf64_Addr kernel_ulong_t; #include <stdint.h> #endif +typedef uint64_t __u64; typedef uint32_t __u32; typedef uint16_t __u16; typedef unsigned char __u8; @@ -199,6 +200,18 @@ static int do_serio_entry(const char *fi return 1; } +/* Looks like: "w1:fidNsnN" */ +static int do_w1_entry(const char *filename, + struct w1_device_id *id, char *alias) +{ + id->family = TO_NATIVE(id->family); + id->serial = TO_NATIVE(id->serial); + + sprintf(alias, "w1:fid%02Xsn%024llX", id->family, id->serial); + + return 1; +} + /* looks like: "pnp:dD" */ static int do_pnp_entry(const char *filename, struct pnp_device_id *id, char *alias) @@ -291,6 +304,9 @@ void handle_moddevtable(struct module *m else if (sym_is(symname, "__mod_serio_device_table")) do_table(symval, sym->st_size, sizeof(struct serio_device_id), do_serio_entry, mod); + else if (sym_is(symname, "__mod_w1_device_table")) + do_table(symval, sym->st_size, sizeof(struct w1_device_id), + do_w1_entry, mod); else if (sym_is(symname, "__mod_pnp_device_table")) do_table(symval, sym->st_size, sizeof(struct pnp_device_id), do_pnp_entry, mod); Index: dtor/include/linux/mod_devicetable.h =================================================================== --- dtor.orig/include/linux/mod_devicetable.h +++ dtor/include/linux/mod_devicetable.h @@ -174,5 +174,9 @@ struct serio_device_id { __u8 proto; }; +struct w1_device_id { + __u8 family; + __u64 serial; +}; #endif /* LINUX_MOD_DEVICETABLE_H */