aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod/file2alias.c
diff options
context:
space:
mode:
authorDave Martin <dave.martin@linaro.org>2011-10-05 09:44:57 -0400
committerDave Martin <dave.martin@linaro.org>2011-11-22 05:58:30 -0500
commit523817bd22617cd62199ae4ca2a6f5e1aa250654 (patch)
treecf3d5597fb8be2e8d7da4d76a8824e5267f14c40 /scripts/mod/file2alias.c
parent1e5f9a23430e64fb56d9d5d8e1ca165ba1cfeb75 (diff)
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 <dave.martin@linaro.org> Acked-by: Pawel Moll <pawel.moll@arm.com>
Diffstat (limited to 'scripts/mod/file2alias.c')
-rw-r--r--scripts/mod/file2alias.c72
1 files changed, 72 insertions, 0 deletions
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,
880 return 1; 880 return 1;
881} 881}
882 882
883/*
884 * Append a match expression for a single masked hex digit.
885 * outp points to a pointer to the character at which to append.
886 * *outp is updated on return to point just after the appended text,
887 * to facilitate further appending.
888 */
889static void append_nibble_mask(char **outp,
890 unsigned int nibble, unsigned int mask)
891{
892 char *p = *outp;
893 unsigned int i;
894
895 switch (mask) {
896 case 0:
897 *p++ = '?';
898 break;
899
900 case 0xf:
901 p += sprintf(p, "%X", nibble);
902 break;
903
904 default:
905 /*
906 * Dumbly emit a match pattern for all possible matching
907 * digits. This could be improved in some cases using ranges,
908 * but it has the advantage of being trivially correct, and is
909 * often optimal.
910 */
911 *p++ = '[';
912 for (i = 0; i < 0x10; i++)
913 if ((i & mask) == nibble)
914 p += sprintf(p, "%X", i);
915 *p++ = ']';
916 }
917
918 /* Ensure that the string remains NUL-terminated: */
919 *p = '\0';
920
921 /* Advance the caller's end-of-string pointer: */
922 *outp = p;
923}
924
925/*
926 * looks like: "amba:dN"
927 *
928 * N is exactly 8 digits, where each is an upper-case hex digit, or
929 * a ? or [] pattern matching exactly one digit.
930 */
931static int do_amba_entry(const char *filename,
932 struct amba_id *id, char *alias)
933{
934 unsigned int digit;
935 char *p = alias;
936
937 if ((id->id & id->mask) != id->id)
938 fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: "
939 "id=0x%08X, mask=0x%08X. Please fix this driver.\n",
940 filename, id->id, id->mask);
941
942 p += sprintf(alias, "amba:d");
943 for (digit = 0; digit < 8; digit++)
944 append_nibble_mask(&p,
945 (id->id >> (4 * (7 - digit))) & 0xf,
946 (id->mask >> (4 * (7 - digit))) & 0xf);
947
948 return 1;
949}
950
883/* Ignore any prefix, eg. some architectures prepend _ */ 951/* Ignore any prefix, eg. some architectures prepend _ */
884static inline int sym_is(const char *symbol, const char *name) 952static inline int sym_is(const char *symbol, const char *name)
885{ 953{
@@ -1047,6 +1115,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
1047 do_table(symval, sym->st_size, 1115 do_table(symval, sym->st_size,
1048 sizeof(struct isapnp_device_id), "isa", 1116 sizeof(struct isapnp_device_id), "isa",
1049 do_isapnp_entry, mod); 1117 do_isapnp_entry, mod);
1118 else if (sym_is(symname, "__mod_amba_device_table"))
1119 do_table(symval, sym->st_size,
1120 sizeof(struct amba_id), "amba",
1121 do_amba_entry, mod);
1050 free(zeros); 1122 free(zeros);
1051} 1123}
1052 1124