diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-06 16:34:45 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-06 16:34:45 -0500 |
commit | 9858a38ea3a940762ae3028cce88f686d0e0c28b (patch) | |
tree | f34a3ba1eba9be58cdd906e33280ce5b35d31b06 /arch/sh/kernel/cpu | |
parent | abb359450f20c32ae03039d8736f12b1d561caf5 (diff) | |
parent | f862f904d357dc0d3612347a8dbabe6fae037fbb (diff) |
Merge branch 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6:
sh: include Migo-R TS driver in Migo-R defconfig
sh: correct definitions to access stack pointers
sh: Tidy up SH-4A unaligned load support.
dma: shdma: NMI support.
sh: mach-sdk7786: Handle baseboard NMI source selection.
sh: mach-rsk: Add polled GPIO buttons support for RSK+7203.
sh: Break out cpuinfo_op procfs bits.
sh: Enable optional gpiolib for all CPUs with pinmux tables.
sh: migrate SH_CLK_MD to mode pin API.
sh: machvec IO death.
Diffstat (limited to 'arch/sh/kernel/cpu')
-rw-r--r-- | arch/sh/kernel/cpu/Makefile | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/proc.c | 148 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh2/clock-sh7619.c | 22 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh2a/clock-sh7201.c | 20 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh2a/clock-sh7203.c | 21 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh2a/clock-sh7206.c | 20 |
6 files changed, 189 insertions, 44 deletions
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index 4edcb60a1355..d49c2135fd48 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile | |||
@@ -20,4 +20,4 @@ obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o | |||
20 | obj-$(CONFIG_SH_FPU) += fpu.o | 20 | obj-$(CONFIG_SH_FPU) += fpu.o |
21 | obj-$(CONFIG_SH_FPU_EMU) += fpu.o | 21 | obj-$(CONFIG_SH_FPU_EMU) += fpu.o |
22 | 22 | ||
23 | obj-y += irq/ init.o clock.o hwblk.o | 23 | obj-y += irq/ init.o clock.o hwblk.o proc.o |
diff --git a/arch/sh/kernel/cpu/proc.c b/arch/sh/kernel/cpu/proc.c new file mode 100644 index 000000000000..e80a936f409a --- /dev/null +++ b/arch/sh/kernel/cpu/proc.c | |||
@@ -0,0 +1,148 @@ | |||
1 | #include <linux/seq_file.h> | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/module.h> | ||
4 | #include <asm/machvec.h> | ||
5 | #include <asm/processor.h> | ||
6 | |||
7 | static const char *cpu_name[] = { | ||
8 | [CPU_SH7201] = "SH7201", | ||
9 | [CPU_SH7203] = "SH7203", [CPU_SH7263] = "SH7263", | ||
10 | [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619", | ||
11 | [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", | ||
12 | [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708", | ||
13 | [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710", | ||
14 | [CPU_SH7712] = "SH7712", [CPU_SH7720] = "SH7720", | ||
15 | [CPU_SH7721] = "SH7721", [CPU_SH7729] = "SH7729", | ||
16 | [CPU_SH7750] = "SH7750", [CPU_SH7750S] = "SH7750S", | ||
17 | [CPU_SH7750R] = "SH7750R", [CPU_SH7751] = "SH7751", | ||
18 | [CPU_SH7751R] = "SH7751R", [CPU_SH7760] = "SH7760", | ||
19 | [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501", | ||
20 | [CPU_SH7763] = "SH7763", [CPU_SH7770] = "SH7770", | ||
21 | [CPU_SH7780] = "SH7780", [CPU_SH7781] = "SH7781", | ||
22 | [CPU_SH7343] = "SH7343", [CPU_SH7785] = "SH7785", | ||
23 | [CPU_SH7786] = "SH7786", [CPU_SH7757] = "SH7757", | ||
24 | [CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3", | ||
25 | [CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103", | ||
26 | [CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723", | ||
27 | [CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724", | ||
28 | [CPU_SH_NONE] = "Unknown" | ||
29 | }; | ||
30 | |||
31 | const char *get_cpu_subtype(struct sh_cpuinfo *c) | ||
32 | { | ||
33 | return cpu_name[c->type]; | ||
34 | } | ||
35 | EXPORT_SYMBOL(get_cpu_subtype); | ||
36 | |||
37 | #ifdef CONFIG_PROC_FS | ||
38 | /* Symbolic CPU flags, keep in sync with asm/cpu-features.h */ | ||
39 | static const char *cpu_flags[] = { | ||
40 | "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr", | ||
41 | "ptea", "llsc", "l2", "op32", "pteaex", NULL | ||
42 | }; | ||
43 | |||
44 | static void show_cpuflags(struct seq_file *m, struct sh_cpuinfo *c) | ||
45 | { | ||
46 | unsigned long i; | ||
47 | |||
48 | seq_printf(m, "cpu flags\t:"); | ||
49 | |||
50 | if (!c->flags) { | ||
51 | seq_printf(m, " %s\n", cpu_flags[0]); | ||
52 | return; | ||
53 | } | ||
54 | |||
55 | for (i = 0; cpu_flags[i]; i++) | ||
56 | if ((c->flags & (1 << i))) | ||
57 | seq_printf(m, " %s", cpu_flags[i+1]); | ||
58 | |||
59 | seq_printf(m, "\n"); | ||
60 | } | ||
61 | |||
62 | static void show_cacheinfo(struct seq_file *m, const char *type, | ||
63 | struct cache_info info) | ||
64 | { | ||
65 | unsigned int cache_size; | ||
66 | |||
67 | cache_size = info.ways * info.sets * info.linesz; | ||
68 | |||
69 | seq_printf(m, "%s size\t: %2dKiB (%d-way)\n", | ||
70 | type, cache_size >> 10, info.ways); | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * Get CPU information for use by the procfs. | ||
75 | */ | ||
76 | static int show_cpuinfo(struct seq_file *m, void *v) | ||
77 | { | ||
78 | struct sh_cpuinfo *c = v; | ||
79 | unsigned int cpu = c - cpu_data; | ||
80 | |||
81 | if (!cpu_online(cpu)) | ||
82 | return 0; | ||
83 | |||
84 | if (cpu == 0) | ||
85 | seq_printf(m, "machine\t\t: %s\n", get_system_type()); | ||
86 | else | ||
87 | seq_printf(m, "\n"); | ||
88 | |||
89 | seq_printf(m, "processor\t: %d\n", cpu); | ||
90 | seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine); | ||
91 | seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype(c)); | ||
92 | if (c->cut_major == -1) | ||
93 | seq_printf(m, "cut\t\t: unknown\n"); | ||
94 | else if (c->cut_minor == -1) | ||
95 | seq_printf(m, "cut\t\t: %d.x\n", c->cut_major); | ||
96 | else | ||
97 | seq_printf(m, "cut\t\t: %d.%d\n", c->cut_major, c->cut_minor); | ||
98 | |||
99 | show_cpuflags(m, c); | ||
100 | |||
101 | seq_printf(m, "cache type\t: "); | ||
102 | |||
103 | /* | ||
104 | * Check for what type of cache we have, we support both the | ||
105 | * unified cache on the SH-2 and SH-3, as well as the harvard | ||
106 | * style cache on the SH-4. | ||
107 | */ | ||
108 | if (c->icache.flags & SH_CACHE_COMBINED) { | ||
109 | seq_printf(m, "unified\n"); | ||
110 | show_cacheinfo(m, "cache", c->icache); | ||
111 | } else { | ||
112 | seq_printf(m, "split (harvard)\n"); | ||
113 | show_cacheinfo(m, "icache", c->icache); | ||
114 | show_cacheinfo(m, "dcache", c->dcache); | ||
115 | } | ||
116 | |||
117 | /* Optional secondary cache */ | ||
118 | if (c->flags & CPU_HAS_L2_CACHE) | ||
119 | show_cacheinfo(m, "scache", c->scache); | ||
120 | |||
121 | seq_printf(m, "address sizes\t: %u bits physical\n", c->phys_bits); | ||
122 | |||
123 | seq_printf(m, "bogomips\t: %lu.%02lu\n", | ||
124 | c->loops_per_jiffy/(500000/HZ), | ||
125 | (c->loops_per_jiffy/(5000/HZ)) % 100); | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static void *c_start(struct seq_file *m, loff_t *pos) | ||
131 | { | ||
132 | return *pos < NR_CPUS ? cpu_data + *pos : NULL; | ||
133 | } | ||
134 | static void *c_next(struct seq_file *m, void *v, loff_t *pos) | ||
135 | { | ||
136 | ++*pos; | ||
137 | return c_start(m, pos); | ||
138 | } | ||
139 | static void c_stop(struct seq_file *m, void *v) | ||
140 | { | ||
141 | } | ||
142 | const struct seq_operations cpuinfo_op = { | ||
143 | .start = c_start, | ||
144 | .next = c_next, | ||
145 | .stop = c_stop, | ||
146 | .show = show_cpuinfo, | ||
147 | }; | ||
148 | #endif /* CONFIG_PROC_FS */ | ||
diff --git a/arch/sh/kernel/cpu/sh2/clock-sh7619.c b/arch/sh/kernel/cpu/sh2/clock-sh7619.c index 0c9f24d7a02f..5b7f12e58a8d 100644 --- a/arch/sh/kernel/cpu/sh2/clock-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/clock-sh7619.c | |||
@@ -14,24 +14,18 @@ | |||
14 | */ | 14 | */ |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/io.h> | ||
17 | #include <asm/clock.h> | 18 | #include <asm/clock.h> |
18 | #include <asm/freq.h> | 19 | #include <asm/freq.h> |
19 | #include <asm/io.h> | 20 | #include <asm/processor.h> |
20 | 21 | ||
21 | static const int pll1rate[] = {1,2}; | 22 | static const int pll1rate[] = {1,2}; |
22 | static const int pfc_divisors[] = {1,2,0,4}; | 23 | static const int pfc_divisors[] = {1,2,0,4}; |
23 | 24 | static unsigned int pll2_mult; | |
24 | #if (CONFIG_SH_CLK_MD == 1) || (CONFIG_SH_CLK_MD == 2) | ||
25 | #define PLL2 (4) | ||
26 | #elif (CONFIG_SH_CLK_MD == 5) || (CONFIG_SH_CLK_MD == 6) | ||
27 | #define PLL2 (2) | ||
28 | #else | ||
29 | #error "Illigal Clock Mode!" | ||
30 | #endif | ||
31 | 25 | ||
32 | static void master_clk_init(struct clk *clk) | 26 | static void master_clk_init(struct clk *clk) |
33 | { | 27 | { |
34 | clk->rate *= PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 7]; | 28 | clk->rate *= pll2_mult * pll1rate[(__raw_readw(FREQCR) >> 8) & 7]; |
35 | } | 29 | } |
36 | 30 | ||
37 | static struct clk_ops sh7619_master_clk_ops = { | 31 | static struct clk_ops sh7619_master_clk_ops = { |
@@ -70,6 +64,14 @@ static struct clk_ops *sh7619_clk_ops[] = { | |||
70 | 64 | ||
71 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | 65 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) |
72 | { | 66 | { |
67 | if (test_mode_pin(MODE_PIN2 | MODE_PIN0) || | ||
68 | test_mode_pin(MODE_PIN2 | MODE_PIN1)) | ||
69 | pll2_mult = 2; | ||
70 | else if (test_mode_pin(MODE_PIN0) || test_mode_pin(MODE_PIN1)) | ||
71 | pll2_mult = 4; | ||
72 | |||
73 | BUG_ON(!pll2_mult); | ||
74 | |||
73 | if (idx < ARRAY_SIZE(sh7619_clk_ops)) | 75 | if (idx < ARRAY_SIZE(sh7619_clk_ops)) |
74 | *ops = sh7619_clk_ops[idx]; | 76 | *ops = sh7619_clk_ops[idx]; |
75 | } | 77 | } |
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c index c509c40cba4b..1174e2d96c03 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c | |||
@@ -22,19 +22,12 @@ static const int pll1rate[]={1,2,3,4,6,8}; | |||
22 | static const int pfc_divisors[]={1,2,3,4,6,8,12}; | 22 | static const int pfc_divisors[]={1,2,3,4,6,8,12}; |
23 | #define ifc_divisors pfc_divisors | 23 | #define ifc_divisors pfc_divisors |
24 | 24 | ||
25 | #if (CONFIG_SH_CLK_MD == 0) | 25 | static unsigned int pll2_mult; |
26 | #define PLL2 (4) | ||
27 | #elif (CONFIG_SH_CLK_MD == 2) | ||
28 | #define PLL2 (2) | ||
29 | #elif (CONFIG_SH_CLK_MD == 3) | ||
30 | #define PLL2 (1) | ||
31 | #else | ||
32 | #error "Illegal Clock Mode!" | ||
33 | #endif | ||
34 | 26 | ||
35 | static void master_clk_init(struct clk *clk) | 27 | static void master_clk_init(struct clk *clk) |
36 | { | 28 | { |
37 | clk->rate = 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; | 29 | clk->rate = 10000000 * pll2_mult * |
30 | pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; | ||
38 | } | 31 | } |
39 | 32 | ||
40 | static struct clk_ops sh7201_master_clk_ops = { | 33 | static struct clk_ops sh7201_master_clk_ops = { |
@@ -80,6 +73,13 @@ static struct clk_ops *sh7201_clk_ops[] = { | |||
80 | 73 | ||
81 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | 74 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) |
82 | { | 75 | { |
76 | if (test_mode_pin(MODE_PIN1 | MODE_PIN0)) | ||
77 | pll2_mult = 1; | ||
78 | else if (test_mode_pin(MODE_PIN1)) | ||
79 | pll2_mult = 2; | ||
80 | else | ||
81 | pll2_mult = 4; | ||
82 | |||
83 | if (idx < ARRAY_SIZE(sh7201_clk_ops)) | 83 | if (idx < ARRAY_SIZE(sh7201_clk_ops)) |
84 | *ops = sh7201_clk_ops[idx]; | 84 | *ops = sh7201_clk_ops[idx]; |
85 | } | 85 | } |
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c index 7e75d8f79502..95a008e8b735 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c | |||
@@ -25,21 +25,11 @@ static const int pll1rate[]={8,12,16,0}; | |||
25 | static const int pfc_divisors[]={1,2,3,4,6,8,12}; | 25 | static const int pfc_divisors[]={1,2,3,4,6,8,12}; |
26 | #define ifc_divisors pfc_divisors | 26 | #define ifc_divisors pfc_divisors |
27 | 27 | ||
28 | #if (CONFIG_SH_CLK_MD == 0) | 28 | static unsigned int pll2_mult; |
29 | #define PLL2 (1) | ||
30 | #elif (CONFIG_SH_CLK_MD == 1) | ||
31 | #define PLL2 (2) | ||
32 | #elif (CONFIG_SH_CLK_MD == 2) | ||
33 | #define PLL2 (4) | ||
34 | #elif (CONFIG_SH_CLK_MD == 3) | ||
35 | #define PLL2 (4) | ||
36 | #else | ||
37 | #error "Illegal Clock Mode!" | ||
38 | #endif | ||
39 | 29 | ||
40 | static void master_clk_init(struct clk *clk) | 30 | static void master_clk_init(struct clk *clk) |
41 | { | 31 | { |
42 | clk->rate *= pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0003] * PLL2 ; | 32 | clk->rate *= pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0003] * pll2_mult; |
43 | } | 33 | } |
44 | 34 | ||
45 | static struct clk_ops sh7203_master_clk_ops = { | 35 | static struct clk_ops sh7203_master_clk_ops = { |
@@ -79,6 +69,13 @@ static struct clk_ops *sh7203_clk_ops[] = { | |||
79 | 69 | ||
80 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | 70 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) |
81 | { | 71 | { |
72 | if (test_mode_pin(MODE_PIN1)) | ||
73 | pll2_mult = 4; | ||
74 | else if (test_mode_pin(MODE_PIN0)) | ||
75 | pll2_mult = 2; | ||
76 | else | ||
77 | pll2_mult = 1; | ||
78 | |||
82 | if (idx < ARRAY_SIZE(sh7203_clk_ops)) | 79 | if (idx < ARRAY_SIZE(sh7203_clk_ops)) |
83 | *ops = sh7203_clk_ops[idx]; | 80 | *ops = sh7203_clk_ops[idx]; |
84 | } | 81 | } |
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c index b27a5e2687ab..3c314d7cd6e6 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c | |||
@@ -22,19 +22,11 @@ static const int pll1rate[]={1,2,3,4,6,8}; | |||
22 | static const int pfc_divisors[]={1,2,3,4,6,8,12}; | 22 | static const int pfc_divisors[]={1,2,3,4,6,8,12}; |
23 | #define ifc_divisors pfc_divisors | 23 | #define ifc_divisors pfc_divisors |
24 | 24 | ||
25 | #if (CONFIG_SH_CLK_MD == 2) | 25 | static unsigned int pll2_mult; |
26 | #define PLL2 (4) | ||
27 | #elif (CONFIG_SH_CLK_MD == 6) | ||
28 | #define PLL2 (2) | ||
29 | #elif (CONFIG_SH_CLK_MD == 7) | ||
30 | #define PLL2 (1) | ||
31 | #else | ||
32 | #error "Illigal Clock Mode!" | ||
33 | #endif | ||
34 | 26 | ||
35 | static void master_clk_init(struct clk *clk) | 27 | static void master_clk_init(struct clk *clk) |
36 | { | 28 | { |
37 | clk->rate *= PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; | 29 | clk->rate *= pll2_mult * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; |
38 | } | 30 | } |
39 | 31 | ||
40 | static struct clk_ops sh7206_master_clk_ops = { | 32 | static struct clk_ops sh7206_master_clk_ops = { |
@@ -79,7 +71,13 @@ static struct clk_ops *sh7206_clk_ops[] = { | |||
79 | 71 | ||
80 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | 72 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) |
81 | { | 73 | { |
74 | if (test_mode_pin(MODE_PIN2 | MODE_PIN1 | MODE_PIN0)) | ||
75 | pll2_mult = 1; | ||
76 | else if (test_mode_pin(MODE_PIN2 | MODE_PIN1)) | ||
77 | pll2_mult = 2; | ||
78 | else if (test_mode_pin(MODE_PIN1)) | ||
79 | pll2_mult = 4; | ||
80 | |||
82 | if (idx < ARRAY_SIZE(sh7206_clk_ops)) | 81 | if (idx < ARRAY_SIZE(sh7206_clk_ops)) |
83 | *ops = sh7206_clk_ops[idx]; | 82 | *ops = sh7206_clk_ops[idx]; |
84 | } | 83 | } |
85 | |||