aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/machvec.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-05-14 02:59:09 -0400
committerPaul Mundt <lethal@hera.kernel.org>2007-06-07 22:43:37 -0400
commit9655ad03af2d232c3b26e7562ab4f8c29b107e49 (patch)
tree6a76057e969ca072e7ca9bdf253219e759054d3f /arch/sh/kernel/machvec.c
parente08f457c7c0cc7720f28349f8780ea752c063441 (diff)
sh: Fixup machvec support.
This fixes up much of the machvec handling, allowing for it to be overloaded on boot. Making practical use of this still requires some Kconfig munging, however. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/machvec.c')
-rw-r--r--arch/sh/kernel/machvec.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
new file mode 100644
index 000000000000..1e78191154e3
--- /dev/null
+++ b/arch/sh/kernel/machvec.c
@@ -0,0 +1,105 @@
1/*
2 * arch/sh/kernel/machvec.c
3 *
4 * The SuperH machine vector setup handlers, yanked from setup.c
5 *
6 * Copyright (C) 1999 Niibe Yutaka
7 * Copyright (C) 2002 - 2007 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/init.h>
14#include <linux/string.h>
15#include <asm/machvec.h>
16#include <asm/sections.h>
17#include <asm/io.h>
18#include <asm/irq.h>
19
20#define MV_NAME_SIZE 32
21
22#define for_each_mv(mv) \
23 for ((mv) = (struct sh_machine_vector *)&__machvec_start; \
24 (mv) && (unsigned long)(mv) < (unsigned long)&__machvec_end; \
25 (mv)++)
26
27static struct sh_machine_vector * __init get_mv_byname(const char *name)
28{
29 struct sh_machine_vector *mv;
30
31 for_each_mv(mv)
32 if (strcasecmp(name, get_system_type()) == 0)
33 return mv;
34
35 return NULL;
36}
37
38static int __init early_parse_mv(char *from)
39{
40 char mv_name[MV_NAME_SIZE] = "";
41 char *mv_end;
42 char *mv_comma;
43 int mv_len;
44 struct sh_machine_vector *mvp;
45
46 mv_end = strchr(from, ' ');
47 if (mv_end == NULL)
48 mv_end = from + strlen(from);
49
50 mv_comma = strchr(from, ',');
51 mv_len = mv_end - from;
52 if (mv_len > (MV_NAME_SIZE-1))
53 mv_len = MV_NAME_SIZE-1;
54 memcpy(mv_name, from, mv_len);
55 mv_name[mv_len] = '\0';
56 from = mv_end;
57
58 if (strcmp(sh_mv.mv_name, mv_name) != 0) {
59 mvp = get_mv_byname(mv_name);
60 if (unlikely(!mvp)) {
61 printk("Available vectors:\n\n\t");
62 for_each_mv(mvp)
63 printk("'%s', ", mvp->mv_name);
64 printk("\n\n");
65 panic("Failed to select machvec '%s' -- halting.\n",
66 mv_name);
67 } else
68 sh_mv = *mvp;
69 }
70
71 printk(KERN_NOTICE "Booting machvec: %s\n", sh_mv.mv_name);
72 return 0;
73}
74early_param("sh_mv", early_parse_mv);
75
76void __init sh_mv_setup(void)
77{
78 /*
79 * Manually walk the vec, fill in anything that the board hasn't yet
80 * by hand, wrapping to the generic implementation.
81 */
82#define mv_set(elem) do { \
83 if (!sh_mv.mv_##elem) \
84 sh_mv.mv_##elem = generic_##elem; \
85} while (0)
86
87 mv_set(inb); mv_set(inw); mv_set(inl);
88 mv_set(outb); mv_set(outw); mv_set(outl);
89
90 mv_set(inb_p); mv_set(inw_p); mv_set(inl_p);
91 mv_set(outb_p); mv_set(outw_p); mv_set(outl_p);
92
93 mv_set(insb); mv_set(insw); mv_set(insl);
94 mv_set(outsb); mv_set(outsw); mv_set(outsl);
95
96 mv_set(readb); mv_set(readw); mv_set(readl);
97 mv_set(writeb); mv_set(writew); mv_set(writel);
98
99 mv_set(ioport_map);
100 mv_set(ioport_unmap);
101 mv_set(irq_demux);
102
103 if (!sh_mv.mv_nr_irqs)
104 sh_mv.mv_nr_irqs = NR_IRQS;
105}