From 523817bd22617cd62199ae4ca2a6f5e1aa250654 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Wed, 5 Oct 2011 14:44:57 +0100 Subject: ARM: amba: Auto-generate AMBA driver module aliases during modpost This patch adds the necessary support in file2alias.c to define suitable aliases based on the amba_id table in AMBA driver modules. This should be sufficient to allow such modules to be auto-loaded via udev. The AMBA bus driver's uevent hotplug code is also modified to pass an approriate MODALIAS string in the event. For simplicity, the AMBA ID is treated an an opaque 32-bit numeber. Module alises use patterns as appropriate to describe the value- mask pairs described in the driver's amba_id list. The proposed alias format is (extended regex): ^amba:d(HEX){8}$ Where HEX is a single upper-case HEX digit or a pattern (? or [] expression) matching a single upper-case HEX digit, as expected by udev. "d" is short for "device", following existing alias naming conventions for other device types. This adds some flexibility for unambiguously extending the alias format in the future by adding additional leading and trailing fields, if this turns out to be necessary. Signed-off-by: Dave Martin Acked-by: Pawel Moll --- scripts/mod/file2alias.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'scripts/mod/file2alias.c') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index f936d1fa969d..363ab4666b17 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -880,6 +880,74 @@ static int do_isapnp_entry(const char *filename, return 1; } +/* + * Append a match expression for a single masked hex digit. + * outp points to a pointer to the character at which to append. + * *outp is updated on return to point just after the appended text, + * to facilitate further appending. + */ +static void append_nibble_mask(char **outp, + unsigned int nibble, unsigned int mask) +{ + char *p = *outp; + unsigned int i; + + switch (mask) { + case 0: + *p++ = '?'; + break; + + case 0xf: + p += sprintf(p, "%X", nibble); + break; + + default: + /* + * Dumbly emit a match pattern for all possible matching + * digits. This could be improved in some cases using ranges, + * but it has the advantage of being trivially correct, and is + * often optimal. + */ + *p++ = '['; + for (i = 0; i < 0x10; i++) + if ((i & mask) == nibble) + p += sprintf(p, "%X", i); + *p++ = ']'; + } + + /* Ensure that the string remains NUL-terminated: */ + *p = '\0'; + + /* Advance the caller's end-of-string pointer: */ + *outp = p; +} + +/* + * looks like: "amba:dN" + * + * N is exactly 8 digits, where each is an upper-case hex digit, or + * a ? or [] pattern matching exactly one digit. + */ +static int do_amba_entry(const char *filename, + struct amba_id *id, char *alias) +{ + unsigned int digit; + char *p = alias; + + if ((id->id & id->mask) != id->id) + fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: " + "id=0x%08X, mask=0x%08X. Please fix this driver.\n", + filename, id->id, id->mask); + + p += sprintf(alias, "amba:d"); + for (digit = 0; digit < 8; digit++) + append_nibble_mask(&p, + (id->id >> (4 * (7 - digit))) & 0xf, + (id->mask >> (4 * (7 - digit))) & 0xf); + + return 1; +} + /* Ignore any prefix, eg. some architectures prepend _ */ static inline int sym_is(const char *symbol, const char *name) { @@ -1047,6 +1115,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_table(symval, sym->st_size, sizeof(struct isapnp_device_id), "isa", do_isapnp_entry, mod); + else if (sym_is(symname, "__mod_amba_device_table")) + do_table(symval, sym->st_size, + sizeof(struct amba_id), "amba", + do_amba_entry, mod); free(zeros); } -- cgit v1.2.3 From 5dd7bf59e0e8563265b3e5b33276099ef628fcc7 Mon Sep 17 00:00:00 2001 From: Jochen Friedrich Date: Sun, 27 Nov 2011 22:00:54 +0100 Subject: ARM: sa11x0: Implement autoloading of codec and codec pdata for mcp bus. Signed-off-by: Jochen Friedrich Signed-off-by: Samuel Ortiz --- scripts/mod/file2alias.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'scripts/mod/file2alias.c') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index f936d1fa969d..e8c7eb16c0ea 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -774,6 +774,15 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id, return 1; } +/* Looks like: mcp:S */ +static int do_mcp_entry(const char *filename, struct mcp_device_id *id, + char *alias) +{ + sprintf(alias, MCP_MODULE_PREFIX "%s", id->name); + + return 1; +} + static const struct dmifield { const char *prefix; int field; @@ -1027,6 +1036,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_table(symval, sym->st_size, sizeof(struct spi_device_id), "spi", do_spi_entry, mod); + else if (sym_is(symname, "__mod_mcp_device_table")) + do_table(symval, sym->st_size, + sizeof(struct mcp_device_id), "mcp", + do_mcp_entry, mod); else if (sym_is(symname, "__mod_dmi_device_table")) do_table(symval, sym->st_size, sizeof(struct dmi_system_id), "dmi", -- cgit v1.2.3 From 626596e295d477c0fefa08cd5daa7dd011b1bb2c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 13 Jan 2012 09:32:15 +1030 Subject: modpost: use a table rather than a giant if/else statement. We look for symbols of form __mod__device_table, and for all but three cases we use a standard interation function (do_table) to walk over the contents and dump out the aliases. Alessandro Rubini did this first, I just repainted the bikeshed a bit. Signed-off-by: Rusty Russell Cc: Alessandro Rubini --- scripts/mod/file2alias.c | 192 ++++++++++++++++++----------------------------- 1 file changed, 73 insertions(+), 119 deletions(-) (limited to 'scripts/mod/file2alias.c') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 363ab4666b17..395e7479bcf7 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -28,6 +28,7 @@ typedef Elf64_Addr kernel_ulong_t; #endif #include +#include typedef uint32_t __u32; typedef uint16_t __u16; @@ -948,15 +949,13 @@ static int do_amba_entry(const char *filename, return 1; } -/* Ignore any prefix, eg. some architectures prepend _ */ -static inline int sym_is(const char *symbol, const char *name) +/* Does namelen bytes of name exactly match the symbol? */ +static bool sym_is(const char *name, unsigned namelen, const char *symbol) { - const char *match; + if (namelen != strlen(symbol)) + return false; - match = strstr(symbol, name); - if (!match) - return 0; - return match[strlen(name)] == '\0'; + return memcmp(name, symbol, namelen) == 0; } static void do_table(void *symval, unsigned long size, @@ -981,6 +980,43 @@ static void do_table(void *symval, unsigned long size, } } +/* This array collects all instances that use the generic do_table above */ +struct devtable_switch { + const char *device_id; /* name of table, __mod__device_table. */ + unsigned long id_size; + void *function; +}; + +static const struct devtable_switch devtable_switch[] = { + { "acpi", sizeof(struct acpi_device_id), do_acpi_entry }, + { "amba", sizeof(struct amba_id), do_amba_entry }, + { "ap", sizeof(struct ap_device_id), do_ap_entry }, + { "bcma", sizeof(struct bcma_device_id), do_bcma_entry }, + { "ccw", sizeof(struct ccw_device_id), do_ccw_entry }, + { "css", sizeof(struct css_device_id), do_css_entry }, + { "dmi", sizeof(struct dmi_system_id), do_dmi_entry }, + { "eisa", sizeof(struct eisa_device_id), do_eisa_entry }, + { "hid", sizeof(struct hid_device_id), do_hid_entry }, + { "i2c", sizeof(struct i2c_device_id), do_i2c_entry }, + { "ieee1394", sizeof(struct ieee1394_device_id), do_ieee1394_entry }, + { "input", sizeof(struct input_device_id), do_input_entry }, + { "isa", sizeof(struct isapnp_device_id), do_isapnp_entry }, + { "mdio", sizeof(struct mdio_device_id), do_mdio_entry }, + { "of", sizeof(struct of_device_id), do_of_entry }, + { "parisc", sizeof(struct parisc_device_id), do_parisc_entry }, + { "pci", sizeof(struct pci_device_id), do_pci_entry }, + { "pcmcia", sizeof(struct pcmcia_device_id), do_pcmcia_entry }, + { "platform", sizeof(struct platform_device_id), do_platform_entry }, + { "sdio", sizeof(struct sdio_device_id), do_sdio_entry }, + { "serio", sizeof(struct serio_device_id), do_serio_entry }, + { "spi", sizeof(struct spi_device_id), do_spi_entry }, + { "ssb", sizeof(struct ssb_device_id), do_ssb_entry }, + { "vio", sizeof(struct vio_device_id), do_vio_entry }, + { "virtio", sizeof(struct virtio_device_id), do_virtio_entry }, + { "vmbus", sizeof(struct hv_vmbus_device_id), do_vmbus_entry }, + { "zorro", sizeof(struct zorro_device_id), do_zorro_entry }, +}; + /* Create MODULE_ALIAS() statements. * At this time, we cannot write the actual output C source yet, * so we write into the mod->dev_table_buf buffer. */ @@ -989,11 +1025,25 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, { void *symval; char *zeros = NULL; + const char *name; + unsigned int namelen; /* We're looking for a section relative symbol */ if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) return; + /* All our symbols are of form __mod_XXX_device_table. */ + name = strstr(symname, "__mod_"); + if (!name) + return; + name += strlen("__mod_"); + namelen = strlen(name); + if (namelen < strlen("_device_table")) + return; + if (strcmp(name + namelen - strlen("_device_table"), "_device_table")) + return; + namelen -= strlen("_device_table"); + /* Handle all-NULL symbols allocated into .bss */ if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { zeros = calloc(1, sym->st_size); @@ -1004,121 +1054,25 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, + sym->st_value; } - if (sym_is(symname, "__mod_pci_device_table")) - do_table(symval, sym->st_size, - sizeof(struct pci_device_id), "pci", - do_pci_entry, mod); - else if (sym_is(symname, "__mod_usb_device_table")) - /* special case to handle bcdDevice ranges */ + /* First handle the "special" cases */ + if (sym_is(name, namelen, "usb")) do_usb_table(symval, sym->st_size, mod); - else if (sym_is(symname, "__mod_hid_device_table")) - do_table(symval, sym->st_size, - sizeof(struct hid_device_id), "hid", - do_hid_entry, mod); - else if (sym_is(symname, "__mod_ieee1394_device_table")) - do_table(symval, sym->st_size, - sizeof(struct ieee1394_device_id), "ieee1394", - do_ieee1394_entry, mod); - else if (sym_is(symname, "__mod_ccw_device_table")) - do_table(symval, sym->st_size, - sizeof(struct ccw_device_id), "ccw", - do_ccw_entry, mod); - else if (sym_is(symname, "__mod_ap_device_table")) - do_table(symval, sym->st_size, - sizeof(struct ap_device_id), "ap", - do_ap_entry, mod); - else if (sym_is(symname, "__mod_css_device_table")) - do_table(symval, sym->st_size, - sizeof(struct css_device_id), "css", - do_css_entry, mod); - else if (sym_is(symname, "__mod_serio_device_table")) - do_table(symval, sym->st_size, - sizeof(struct serio_device_id), "serio", - do_serio_entry, mod); - else if (sym_is(symname, "__mod_acpi_device_table")) - do_table(symval, sym->st_size, - sizeof(struct acpi_device_id), "acpi", - do_acpi_entry, mod); - else if (sym_is(symname, "__mod_pnp_device_table")) + else if (sym_is(name, namelen, "pnp")) do_pnp_device_entry(symval, sym->st_size, mod); - else if (sym_is(symname, "__mod_pnp_card_device_table")) + else if (sym_is(name, namelen, "pnp_card")) do_pnp_card_entries(symval, sym->st_size, mod); - else if (sym_is(symname, "__mod_pcmcia_device_table")) - do_table(symval, sym->st_size, - sizeof(struct pcmcia_device_id), "pcmcia", - do_pcmcia_entry, mod); - else if (sym_is(symname, "__mod_of_device_table")) - do_table(symval, sym->st_size, - sizeof(struct of_device_id), "of", - do_of_entry, mod); - else if (sym_is(symname, "__mod_vio_device_table")) - do_table(symval, sym->st_size, - sizeof(struct vio_device_id), "vio", - do_vio_entry, mod); - else if (sym_is(symname, "__mod_input_device_table")) - do_table(symval, sym->st_size, - sizeof(struct input_device_id), "input", - do_input_entry, mod); - else if (sym_is(symname, "__mod_eisa_device_table")) - do_table(symval, sym->st_size, - sizeof(struct eisa_device_id), "eisa", - do_eisa_entry, mod); - else if (sym_is(symname, "__mod_parisc_device_table")) - do_table(symval, sym->st_size, - sizeof(struct parisc_device_id), "parisc", - do_parisc_entry, mod); - else if (sym_is(symname, "__mod_sdio_device_table")) - do_table(symval, sym->st_size, - sizeof(struct sdio_device_id), "sdio", - do_sdio_entry, mod); - else if (sym_is(symname, "__mod_ssb_device_table")) - do_table(symval, sym->st_size, - sizeof(struct ssb_device_id), "ssb", - do_ssb_entry, mod); - else if (sym_is(symname, "__mod_bcma_device_table")) - do_table(symval, sym->st_size, - sizeof(struct bcma_device_id), "bcma", - do_bcma_entry, mod); - else if (sym_is(symname, "__mod_virtio_device_table")) - do_table(symval, sym->st_size, - sizeof(struct virtio_device_id), "virtio", - do_virtio_entry, mod); - else if (sym_is(symname, "__mod_vmbus_device_table")) - do_table(symval, sym->st_size, - sizeof(struct hv_vmbus_device_id), "vmbus", - do_vmbus_entry, mod); - else if (sym_is(symname, "__mod_i2c_device_table")) - do_table(symval, sym->st_size, - sizeof(struct i2c_device_id), "i2c", - do_i2c_entry, mod); - else if (sym_is(symname, "__mod_spi_device_table")) - do_table(symval, sym->st_size, - sizeof(struct spi_device_id), "spi", - do_spi_entry, mod); - else if (sym_is(symname, "__mod_dmi_device_table")) - do_table(symval, sym->st_size, - sizeof(struct dmi_system_id), "dmi", - do_dmi_entry, mod); - else if (sym_is(symname, "__mod_platform_device_table")) - do_table(symval, sym->st_size, - sizeof(struct platform_device_id), "platform", - do_platform_entry, mod); - else if (sym_is(symname, "__mod_mdio_device_table")) - do_table(symval, sym->st_size, - sizeof(struct mdio_device_id), "mdio", - do_mdio_entry, mod); - else if (sym_is(symname, "__mod_zorro_device_table")) - do_table(symval, sym->st_size, - sizeof(struct zorro_device_id), "zorro", - do_zorro_entry, mod); - else if (sym_is(symname, "__mod_isapnp_device_table")) - do_table(symval, sym->st_size, - sizeof(struct isapnp_device_id), "isa", - do_isapnp_entry, mod); - else if (sym_is(symname, "__mod_amba_device_table")) - do_table(symval, sym->st_size, - sizeof(struct amba_id), "amba", - do_amba_entry, mod); + else { + const struct devtable_switch *p = devtable_switch; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(devtable_switch); i++, p++) { + if (sym_is(name, namelen, p->device_id)) { + do_table(symval, sym->st_size, p->id_size, + p->device_id, p->function, mod); + break; + } + } + } free(zeros); } -- cgit v1.2.3 From e49ce14150c64b29a8dd211df785576fa19a9858 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 13 Jan 2012 09:32:16 +1030 Subject: modpost: use linker section to generate table. This means (most) future busses need only have one hunk in their patch. Also took the opportunity to check that function matches the type. Again, inspired by Alessandro's patch series. Signed-off-by: Rusty Russell Cc: Alessandro Rubini --- scripts/mod/file2alias.c | 106 +++++++++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 45 deletions(-) (limited to 'scripts/mod/file2alias.c') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 395e7479bcf7..e8c969577768 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -39,6 +39,35 @@ typedef unsigned char __u8; * we handle those differences explicitly below */ #include "../../include/linux/mod_devicetable.h" +/* This array collects all instances that use the generic do_table */ +struct devtable { + const char *device_id; /* name of table, __mod__device_table. */ + unsigned long id_size; + void *function; +}; + +/* We construct a table of pointers in an ELF section (pointers generally + * go unpadded by gcc). ld creates boundary syms for us. */ +extern struct devtable *__start___devtable[], *__stop___devtable[]; +#define ___cat(a,b) a ## b +#define __cat(a,b) ___cat(a,b) + +#if __GNUC__ == 3 && __GNUC_MINOR__ < 3 +# define __used __attribute__((__unused__)) +#else +# define __used __attribute__((__used__)) +#endif + +/* Add a table entry. We test function type matches while we're here. */ +#define ADD_TO_DEVTABLE(device_id, type, function) \ + static struct devtable __cat(devtable,__LINE__) = { \ + device_id + 0*sizeof((function)((const char *)NULL, \ + (type *)NULL, \ + (char *)NULL)), \ + sizeof(type), (function) }; \ + static struct devtable *__attribute__((section("__devtable"))) \ + __used __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__) + #define ADD(str, sep, cond, field) \ do { \ strcat(str, sep); \ @@ -290,6 +319,7 @@ static int do_hid_entry(const char *filename, return 1; } +ADD_TO_DEVTABLE("hid", struct hid_device_id, do_hid_entry); /* Looks like: ieee1394:venNmoNspNverN */ static int do_ieee1394_entry(const char *filename, @@ -314,6 +344,7 @@ static int do_ieee1394_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("ieee1394", struct ieee1394_device_id, do_ieee1394_entry); /* Looks like: pci:vNdNsvNsdNbcNscNiN. */ static int do_pci_entry(const char *filename, @@ -357,6 +388,7 @@ static int do_pci_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("pci", struct pci_device_id, do_pci_entry); /* looks like: "ccw:tNmNdtNdmN" */ static int do_ccw_entry(const char *filename, @@ -380,6 +412,7 @@ static int do_ccw_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("ccw", struct ccw_device_id, do_ccw_entry); /* looks like: "ap:tN" */ static int do_ap_entry(const char *filename, @@ -388,6 +421,7 @@ static int do_ap_entry(const char *filename, sprintf(alias, "ap:t%02X*", id->dev_type); return 1; } +ADD_TO_DEVTABLE("ap", struct ap_device_id, do_ap_entry); /* looks like: "css:tN" */ static int do_css_entry(const char *filename, @@ -396,6 +430,7 @@ static int do_css_entry(const char *filename, sprintf(alias, "css:t%01X", id->type); return 1; } +ADD_TO_DEVTABLE("css", struct css_device_id, do_css_entry); /* Looks like: "serio:tyNprNidNexN" */ static int do_serio_entry(const char *filename, @@ -415,6 +450,7 @@ static int do_serio_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("serio", struct serio_device_id, do_serio_entry); /* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */ static int do_acpi_entry(const char *filename, @@ -423,6 +459,7 @@ static int do_acpi_entry(const char *filename, sprintf(alias, "acpi*:%s:*", id->id); return 1; } +ADD_TO_DEVTABLE("acpi", struct acpi_device_id, do_acpi_entry); /* looks like: "pnp:dD" */ static void do_pnp_device_entry(void *symval, unsigned long size, @@ -545,8 +582,7 @@ static int do_pcmcia_entry(const char *filename, add_wildcard(alias); return 1; } - - +ADD_TO_DEVTABLE("pcmcia", struct pcmcia_device_id, do_pcmcia_entry); static int do_of_entry (const char *filename, struct of_device_id *of, char *alias) { @@ -569,6 +605,7 @@ static int do_of_entry (const char *filename, struct of_device_id *of, char *ali add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("of", struct of_device_id, do_of_entry); static int do_vio_entry(const char *filename, struct vio_device_id *vio, char *alias) @@ -586,6 +623,7 @@ static int do_vio_entry(const char *filename, struct vio_device_id *vio, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("vio", struct vio_device_id, do_vio_entry); #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -641,6 +679,7 @@ static int do_input_entry(const char *filename, struct input_device_id *id, do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX); return 1; } +ADD_TO_DEVTABLE("input", struct input_device_id, do_input_entry); static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa, char *alias) @@ -651,6 +690,7 @@ static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa, strcat(alias, "*"); return 1; } +ADD_TO_DEVTABLE("eisa", struct eisa_device_id, do_eisa_entry); /* Looks like: parisc:tNhvNrevNsvN */ static int do_parisc_entry(const char *filename, struct parisc_device_id *id, @@ -670,6 +710,7 @@ static int do_parisc_entry(const char *filename, struct parisc_device_id *id, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("parisc", struct parisc_device_id, do_parisc_entry); /* Looks like: sdio:cNvNdN. */ static int do_sdio_entry(const char *filename, @@ -686,6 +727,7 @@ static int do_sdio_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("sdio", struct sdio_device_id, do_sdio_entry); /* Looks like: ssb:vNidNrevN. */ static int do_ssb_entry(const char *filename, @@ -702,6 +744,7 @@ static int do_ssb_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("ssb", struct ssb_device_id, do_ssb_entry); /* Looks like: bcma:mNidNrevNclN. */ static int do_bcma_entry(const char *filename, @@ -720,6 +763,7 @@ static int do_bcma_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("bcma", struct bcma_device_id, do_bcma_entry); /* Looks like: virtio:dNvN */ static int do_virtio_entry(const char *filename, struct virtio_device_id *id, @@ -735,6 +779,7 @@ static int do_virtio_entry(const char *filename, struct virtio_device_id *id, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("virtio", struct virtio_device_id, do_virtio_entry); /* * Looks like: vmbus:guid @@ -756,6 +801,7 @@ static int do_vmbus_entry(const char *filename, struct hv_vmbus_device_id *id, return 1; } +ADD_TO_DEVTABLE("vmbus", struct hv_vmbus_device_id, do_vmbus_entry); /* Looks like: i2c:S */ static int do_i2c_entry(const char *filename, struct i2c_device_id *id, @@ -765,6 +811,7 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *id, return 1; } +ADD_TO_DEVTABLE("i2c", struct i2c_device_id, do_i2c_entry); /* Looks like: spi:S */ static int do_spi_entry(const char *filename, struct spi_device_id *id, @@ -774,6 +821,7 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id, return 1; } +ADD_TO_DEVTABLE("spi", struct spi_device_id, do_spi_entry); static const struct dmifield { const char *prefix; @@ -828,6 +876,7 @@ static int do_dmi_entry(const char *filename, struct dmi_system_id *id, strcat(alias, ":"); return 1; } +ADD_TO_DEVTABLE("dmi", struct dmi_system_id, do_dmi_entry); static int do_platform_entry(const char *filename, struct platform_device_id *id, char *alias) @@ -835,6 +884,7 @@ static int do_platform_entry(const char *filename, sprintf(alias, PLATFORM_MODULE_PREFIX "%s", id->name); return 1; } +ADD_TO_DEVTABLE("platform", struct platform_device_id, do_platform_entry); static int do_mdio_entry(const char *filename, struct mdio_device_id *id, char *alias) @@ -857,6 +907,7 @@ static int do_mdio_entry(const char *filename, return 1; } +ADD_TO_DEVTABLE("mdio", struct mdio_device_id, do_mdio_entry); /* Looks like: zorro:iN. */ static int do_zorro_entry(const char *filename, struct zorro_device_id *id, @@ -867,6 +918,7 @@ static int do_zorro_entry(const char *filename, struct zorro_device_id *id, ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id); return 1; } +ADD_TO_DEVTABLE("zorro", struct zorro_device_id, do_zorro_entry); /* looks like: "pnp:dD" */ static int do_isapnp_entry(const char *filename, @@ -880,6 +932,7 @@ static int do_isapnp_entry(const char *filename, (id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f); return 1; } +ADD_TO_DEVTABLE("isa", struct isapnp_device_id, do_isapnp_entry); /* * Append a match expression for a single masked hex digit. @@ -948,6 +1001,7 @@ static int do_amba_entry(const char *filename, return 1; } +ADD_TO_DEVTABLE("amba", struct amba_id, do_amba_entry); /* Does namelen bytes of name exactly match the symbol? */ static bool sym_is(const char *name, unsigned namelen, const char *symbol) @@ -980,43 +1034,6 @@ static void do_table(void *symval, unsigned long size, } } -/* This array collects all instances that use the generic do_table above */ -struct devtable_switch { - const char *device_id; /* name of table, __mod__device_table. */ - unsigned long id_size; - void *function; -}; - -static const struct devtable_switch devtable_switch[] = { - { "acpi", sizeof(struct acpi_device_id), do_acpi_entry }, - { "amba", sizeof(struct amba_id), do_amba_entry }, - { "ap", sizeof(struct ap_device_id), do_ap_entry }, - { "bcma", sizeof(struct bcma_device_id), do_bcma_entry }, - { "ccw", sizeof(struct ccw_device_id), do_ccw_entry }, - { "css", sizeof(struct css_device_id), do_css_entry }, - { "dmi", sizeof(struct dmi_system_id), do_dmi_entry }, - { "eisa", sizeof(struct eisa_device_id), do_eisa_entry }, - { "hid", sizeof(struct hid_device_id), do_hid_entry }, - { "i2c", sizeof(struct i2c_device_id), do_i2c_entry }, - { "ieee1394", sizeof(struct ieee1394_device_id), do_ieee1394_entry }, - { "input", sizeof(struct input_device_id), do_input_entry }, - { "isa", sizeof(struct isapnp_device_id), do_isapnp_entry }, - { "mdio", sizeof(struct mdio_device_id), do_mdio_entry }, - { "of", sizeof(struct of_device_id), do_of_entry }, - { "parisc", sizeof(struct parisc_device_id), do_parisc_entry }, - { "pci", sizeof(struct pci_device_id), do_pci_entry }, - { "pcmcia", sizeof(struct pcmcia_device_id), do_pcmcia_entry }, - { "platform", sizeof(struct platform_device_id), do_platform_entry }, - { "sdio", sizeof(struct sdio_device_id), do_sdio_entry }, - { "serio", sizeof(struct serio_device_id), do_serio_entry }, - { "spi", sizeof(struct spi_device_id), do_spi_entry }, - { "ssb", sizeof(struct ssb_device_id), do_ssb_entry }, - { "vio", sizeof(struct vio_device_id), do_vio_entry }, - { "virtio", sizeof(struct virtio_device_id), do_virtio_entry }, - { "vmbus", sizeof(struct hv_vmbus_device_id), do_vmbus_entry }, - { "zorro", sizeof(struct zorro_device_id), do_zorro_entry }, -}; - /* Create MODULE_ALIAS() statements. * At this time, we cannot write the actual output C source yet, * so we write into the mod->dev_table_buf buffer. */ @@ -1062,13 +1079,12 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, else if (sym_is(name, namelen, "pnp_card")) do_pnp_card_entries(symval, sym->st_size, mod); else { - const struct devtable_switch *p = devtable_switch; - unsigned int i; + struct devtable **p; - for (i = 0; i < ARRAY_SIZE(devtable_switch); i++, p++) { - if (sym_is(name, namelen, p->device_id)) { - do_table(symval, sym->st_size, p->id_size, - p->device_id, p->function, mod); + for (p = __start___devtable; p < __stop___devtable; p++) { + if (sym_is(name, namelen, (*p)->device_id)) { + do_table(symval, sym->st_size, (*p)->id_size, + (*p)->device_id, (*p)->function, mod); break; } } -- cgit v1.2.3 From 65f2e753f1eb09d3a7e2a0d16408a5433b4097b2 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Jan 2012 17:38:58 +0000 Subject: Revert "ARM: sa11x0: Implement autoloading of codec and codec pdata for mcp bus." This reverts commit 5dd7bf59e0e8563265b3e5b33276099ef628fcc7. Conflicts: scripts/mod/file2alias.c This change is wrong on many levels. First and foremost, it causes a regression. On boot on Assabet, which this patch gives a codec id of 'ucb1x00', it gives: ucb1x00 ID not found: 1005 0x1005 is a valid ID for the UCB1300 device. Secondly, this patch is way over the top in terms of complexity. The only device which has been seen to be connected with this MCP code is the UCB1x00 (UCB1200, UCB1300 etc) devices, and they all use the same driver. Adding a match table, requiring the codec string to match the hardware ID read out of the ID register, etc is completely over the top when we can just read the hardware ID register. --- scripts/mod/file2alias.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'scripts/mod/file2alias.c') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index c0e14b3f2306..e8c969577768 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -823,16 +823,6 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id, } ADD_TO_DEVTABLE("spi", struct spi_device_id, do_spi_entry); -/* Looks like: mcp:S */ -static int do_mcp_entry(const char *filename, struct mcp_device_id *id, - char *alias) -{ - sprintf(alias, MCP_MODULE_PREFIX "%s", id->name); - - return 1; -} -ADD_TO_DEVTABLE("mcp", struct mcp_device_id, do_mcp_entry); - static const struct dmifield { const char *prefix; int field; -- cgit v1.2.3 From 0d86f65ed0b727daa06d3aa176314cd175323db6 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Fri, 10 Feb 2012 20:12:27 +0100 Subject: module: fix broken isapnp handling in file2alias Handling of isapnp module aliases was broken by commit 626596e295d477c0fefa08cd5daa7dd011b1bb2c by changing "isapnp" string to "isa". The code was then modified by commit e49ce14150c64b29a8dd211df785576fa19a9858 but this bug remained. Change the string back to "isapnp". Signed-off-by: Ondrej Zary Signed-off-by: Rusty Russell --- scripts/mod/file2alias.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts/mod/file2alias.c') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index e8c969577768..d0de2a2c3a2d 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -932,7 +932,7 @@ static int do_isapnp_entry(const char *filename, (id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f); return 1; } -ADD_TO_DEVTABLE("isa", struct isapnp_device_id, do_isapnp_entry); +ADD_TO_DEVTABLE("isapnp", struct isapnp_device_id, do_isapnp_entry); /* * Append a match expression for a single masked hex digit. -- cgit v1.2.3 From dd2a3acaecd7abb2d43b09a823cf2e4c967fa2ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Bie=C3=9Fmann?= Date: Fri, 24 Feb 2012 08:23:53 +0100 Subject: mod/file2alias: make modpost compile on darwin again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e49ce14150c64b29a8dd211df785576fa19a9858 breaks cross compiling the linux kernel on darwin hosts. This fix introduce some minimal glue to adopt linker section handling for darwin hosts. Signed-off-by: Andreas Bießmann CC: Rusty Russell CC: Greg Kroah-Hartman CC: Jochen Friedrich CC: Samuel Ortiz CC: "K. Y. Srinivasan" Signed-off-by: Rusty Russell Tested-by: Bernhard Walle --- scripts/mod/file2alias.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'scripts/mod/file2alias.c') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index d0de2a2c3a2d..b89efe6e4c85 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -46,11 +46,37 @@ struct devtable { void *function; }; +#define ___cat(a,b) a ## b +#define __cat(a,b) ___cat(a,b) + +/* we need some special handling for this host tool running eventually on + * Darwin. The Mach-O section handling is a bit different than ELF section + * handling. The differnces in detail are: + * a) we have segments which have sections + * b) we need a API call to get the respective section symbols */ +#if defined(__MACH__) +#include + +#define INIT_SECTION(name) do { \ + unsigned long name ## _len; \ + char *__cat(pstart_,name) = getsectdata("__TEXT", \ + #name, &__cat(name,_len)); \ + char *__cat(pstop_,name) = __cat(pstart_,name) + \ + __cat(name, _len); \ + __cat(__start_,name) = (void *)__cat(pstart_,name); \ + __cat(__stop_,name) = (void *)__cat(pstop_,name); \ + } while (0) +#define SECTION(name) __attribute__((section("__TEXT, " #name))) + +struct devtable **__start___devtable, **__stop___devtable; +#else +#define INIT_SECTION(name) /* no-op for ELF */ +#define SECTION(name) __attribute__((section(#name))) + /* We construct a table of pointers in an ELF section (pointers generally * go unpadded by gcc). ld creates boundary syms for us. */ extern struct devtable *__start___devtable[], *__stop___devtable[]; -#define ___cat(a,b) a ## b -#define __cat(a,b) ___cat(a,b) +#endif /* __MACH__ */ #if __GNUC__ == 3 && __GNUC_MINOR__ < 3 # define __used __attribute__((__unused__)) @@ -65,8 +91,8 @@ extern struct devtable *__start___devtable[], *__stop___devtable[]; (type *)NULL, \ (char *)NULL)), \ sizeof(type), (function) }; \ - static struct devtable *__attribute__((section("__devtable"))) \ - __used __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__) + static struct devtable *SECTION(__devtable) __used \ + __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__) #define ADD(str, sep, cond, field) \ do { \ @@ -1080,6 +1106,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_pnp_card_entries(symval, sym->st_size, mod); else { struct devtable **p; + INIT_SECTION(__devtable); for (p = __start___devtable; p < __stop___devtable; p++) { if (sym_is(name, namelen, (*p)->device_id)) { -- cgit v1.2.3