Skip to content

Commit

Permalink
modpost: fix module autoloading for OF devices with generic compatibl…
Browse files Browse the repository at this point in the history
…e property

Since the wildcard at the end of OF module aliases is gone, autoloading
of modules that don't match a device's last (most generic) compatible
value fails.

For example the CODA960 VPU on i.MX6Q has the SoC specific compatible
"fsl,imx6q-vpu" and the generic compatible "cnm,coda960".  Since the
driver currently only works with knowledge about the SoC specific
integration, it doesn't list "cnm,cod960" in the module device table.

This results in the device compatible
"of:NvpuT<NULL>Cfsl,imx6q-vpuCcnm,coda960" not matching the module alias
"of:N*T*Cfsl,imx6q-vpu" anymore, whereas before commit 2f63236
("modpost: don't add a trailing wildcard for OF module aliases") it
matched the module alias "of:N*T*Cfsl,imx6q-vpu*".

This patch adds two module aliases for each compatible, one without the
wildcard and one with "C*" appended.

  $ modinfo coda | grep imx6q
  alias:          of:N*T*Cfsl,imx6q-vpuC*
  alias:          of:N*T*Cfsl,imx6q-vpu

Fixes: 2f63236 ("modpost: don't add a trailing wildcard for OF module aliases")
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Philipp Zabel <[email protected]>
Cc: Javier Martinez Canillas <[email protected]>
Cc: Brian Norris <[email protected]>
Cc: Sjoerd Simons <[email protected]>
Cc: Rusty Russell <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: <[email protected]>	[4.5+]
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
pH5 authored and torvalds committed May 6, 2016
1 parent 8148a73 commit acbef7b
Showing 1 changed file with 45 additions and 24 deletions.
69 changes: 45 additions & 24 deletions scripts/mod/file2alias.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,49 @@ static void do_usb_table(void *symval, unsigned long size,
do_usb_entry_multi(symval + i, mod);
}

static void do_of_entry_multi(void *symval, struct module *mod)
{
char alias[500];
int len;
char *tmp;

DEF_FIELD_ADDR(symval, of_device_id, name);
DEF_FIELD_ADDR(symval, of_device_id, type);
DEF_FIELD_ADDR(symval, of_device_id, compatible);

len = sprintf(alias, "of:N%sT%s", (*name)[0] ? *name : "*",
(*type)[0] ? *type : "*");

if (compatible[0])
sprintf(&alias[len], "%sC%s", (*type)[0] ? "*" : "",
*compatible);

/* Replace all whitespace with underscores */
for (tmp = alias; tmp && *tmp; tmp++)
if (isspace(*tmp))
*tmp = '_';

buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias);
strcat(alias, "C");
add_wildcard(alias);
buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias);
}

static void do_of_table(void *symval, unsigned long size,
struct module *mod)
{
unsigned int i;
const unsigned long id_size = SIZE_of_device_id;

device_id_check(mod->name, "of", size, id_size, symval);

/* Leave last one: it's the terminator. */
size -= id_size;

for (i = 0; i < size; i += id_size)
do_of_entry_multi(symval + i, mod);
}

/* Looks like: hid:bNvNpN */
static int do_hid_entry(const char *filename,
void *symval, char *alias)
Expand Down Expand Up @@ -684,30 +727,6 @@ static int do_pcmcia_entry(const char *filename,
}
ADD_TO_DEVTABLE("pcmcia", pcmcia_device_id, do_pcmcia_entry);

static int do_of_entry (const char *filename, void *symval, char *alias)
{
int len;
char *tmp;
DEF_FIELD_ADDR(symval, of_device_id, name);
DEF_FIELD_ADDR(symval, of_device_id, type);
DEF_FIELD_ADDR(symval, of_device_id, compatible);

len = sprintf(alias, "of:N%sT%s", (*name)[0] ? *name : "*",
(*type)[0] ? *type : "*");

if (compatible[0])
sprintf(&alias[len], "%sC%s", (*type)[0] ? "*" : "",
*compatible);

/* Replace all whitespace with underscores */
for (tmp = alias; tmp && *tmp; tmp++)
if (isspace (*tmp))
*tmp = '_';

return 1;
}
ADD_TO_DEVTABLE("of", of_device_id, do_of_entry);

static int do_vio_entry(const char *filename, void *symval,
char *alias)
{
Expand Down Expand Up @@ -1348,6 +1367,8 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
/* First handle the "special" cases */
if (sym_is(name, namelen, "usb"))
do_usb_table(symval, sym->st_size, mod);
if (sym_is(name, namelen, "of"))
do_of_table(symval, sym->st_size, mod);
else if (sym_is(name, namelen, "pnp"))
do_pnp_device_entry(symval, sym->st_size, mod);
else if (sym_is(name, namelen, "pnp_card"))
Expand Down

0 comments on commit acbef7b

Please sign in to comment.