diff options
author | Gabor Juhos <juhosg@openwrt.org> | 2010-11-23 10:06:25 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2011-01-18 13:30:21 -0500 |
commit | 487d70d0b8bd1c70d099a7526077ffefee412050 (patch) | |
tree | e8ea4a5830fa88dca0a903b6bdf1f14e3ee119eb /arch/mips/kernel/mips_machine.c | |
parent | 0bec405e8ee390067e63265b3002aaac49d4eea8 (diff) |
MIPS: Add generic support for multiple machines within a single kernel
This patch adds a generic solution to support multiple machines based on
a given SoC within a single kernel image. It is implemented already for
several other architectures but MIPS has no generic support for that yet.
[Ralf: This competes with DT but DT is a much more complex solution and this
code has been used by OpenWRT for a long time so for now DT is a bad reason
to stop the merge but longer term this should be migrated to DT.]
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Cc: linux-mips@linux-mips.org
Cc: kaloz@openwrt.org
Cc: Luis R. Rodriguez <lrodriguez@atheros.com>
Cc: Cliff Holden <Cliff.Holden@Atheros.com>
Patchwork: https://patchwork.linux-mips.org/patch/1814/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/mips_machine.c')
-rw-r--r-- | arch/mips/kernel/mips_machine.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/arch/mips/kernel/mips_machine.c b/arch/mips/kernel/mips_machine.c new file mode 100644 index 000000000000..411a058d2c53 --- /dev/null +++ b/arch/mips/kernel/mips_machine.c | |||
@@ -0,0 +1,86 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License version 2 as published | ||
6 | * by the Free Software Foundation. | ||
7 | * | ||
8 | */ | ||
9 | #include <linux/mm.h> | ||
10 | #include <linux/string.h> | ||
11 | #include <linux/slab.h> | ||
12 | |||
13 | #include <asm/mips_machine.h> | ||
14 | |||
15 | static struct mips_machine *mips_machine __initdata; | ||
16 | static char *mips_machine_name = "Unknown"; | ||
17 | |||
18 | #define for_each_machine(mach) \ | ||
19 | for ((mach) = (struct mips_machine *)&__mips_machines_start; \ | ||
20 | (mach) && \ | ||
21 | (unsigned long)(mach) < (unsigned long)&__mips_machines_end; \ | ||
22 | (mach)++) | ||
23 | |||
24 | __init void mips_set_machine_name(const char *name) | ||
25 | { | ||
26 | char *p; | ||
27 | |||
28 | if (name == NULL) | ||
29 | return; | ||
30 | |||
31 | p = kstrdup(name, GFP_KERNEL); | ||
32 | if (!p) | ||
33 | pr_err("MIPS: no memory for machine_name\n"); | ||
34 | |||
35 | mips_machine_name = p; | ||
36 | } | ||
37 | |||
38 | char *mips_get_machine_name(void) | ||
39 | { | ||
40 | return mips_machine_name; | ||
41 | } | ||
42 | |||
43 | __init int mips_machtype_setup(char *id) | ||
44 | { | ||
45 | struct mips_machine *mach; | ||
46 | |||
47 | for_each_machine(mach) { | ||
48 | if (mach->mach_id == NULL) | ||
49 | continue; | ||
50 | |||
51 | if (strcmp(mach->mach_id, id) == 0) { | ||
52 | mips_machtype = mach->mach_type; | ||
53 | return 0; | ||
54 | } | ||
55 | } | ||
56 | |||
57 | pr_err("MIPS: no machine found for id '%s', supported machines:\n", id); | ||
58 | pr_err("%-24s %s\n", "id", "name"); | ||
59 | for_each_machine(mach) | ||
60 | pr_err("%-24s %s\n", mach->mach_id, mach->mach_name); | ||
61 | |||
62 | return 1; | ||
63 | } | ||
64 | |||
65 | __setup("machtype=", mips_machtype_setup); | ||
66 | |||
67 | __init void mips_machine_setup(void) | ||
68 | { | ||
69 | struct mips_machine *mach; | ||
70 | |||
71 | for_each_machine(mach) { | ||
72 | if (mips_machtype == mach->mach_type) { | ||
73 | mips_machine = mach; | ||
74 | break; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | if (!mips_machine) | ||
79 | return; | ||
80 | |||
81 | mips_set_machine_name(mips_machine->mach_name); | ||
82 | pr_info("MIPS: machine is %s\n", mips_machine_name); | ||
83 | |||
84 | if (mips_machine->mach_setup) | ||
85 | mips_machine->mach_setup(); | ||
86 | } | ||