aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-02-07 17:43:08 -0500
committerPaul Mackerras <paulus@samba.org>2006-02-07 17:43:08 -0500
commit8f75015f33c3005e0bbf83ffc0d5e0b4262cc03d (patch)
treea3c34ad86ccdc904bb43af6cd1cb163231c29276 /arch/sh/kernel
parent076d022c566fddde41fd4a858dd24bacad8304d7 (diff)
parente060e084e7d9e1c62d02cb6b8d3fe07db5317eaa (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/Makefile2
-rw-r--r--arch/sh/kernel/cpu/Makefile2
-rw-r--r--arch/sh/kernel/cpu/bus.c197
-rw-r--r--arch/sh/kernel/cpu/clock.c13
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c59
-rw-r--r--arch/sh/kernel/entry.S18
-rw-r--r--arch/sh/kernel/process.c54
-rw-r--r--arch/sh/kernel/setup.c51
8 files changed, 78 insertions, 318 deletions
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 7a86eeb22655..f05cd96f8867 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -8,7 +8,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \
8 ptrace.o setup.o time.o sys_sh.o semaphore.o \ 8 ptrace.o setup.o time.o sys_sh.o semaphore.o \
9 io.o io_generic.o sh_ksyms.o 9 io.o io_generic.o sh_ksyms.o
10 10
11obj-y += cpu/ 11obj-y += cpu/ timers/
12 12
13obj-$(CONFIG_SMP) += smp.o 13obj-$(CONFIG_SMP) += smp.o
14obj-$(CONFIG_CF_ENABLER) += cf-enabler.o 14obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index 5bfc33bec5d0..59d5b748752f 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the Linux/SuperH CPU-specifc backends. 2# Makefile for the Linux/SuperH CPU-specifc backends.
3# 3#
4 4
5obj-y += irq/ init.o bus.o clock.o 5obj-y += irq/ init.o clock.o
6 6
7obj-$(CONFIG_CPU_SH2) += sh2/ 7obj-$(CONFIG_CPU_SH2) += sh2/
8obj-$(CONFIG_CPU_SH3) += sh3/ 8obj-$(CONFIG_CPU_SH3) += sh3/
diff --git a/arch/sh/kernel/cpu/bus.c b/arch/sh/kernel/cpu/bus.c
deleted file mode 100644
index fc6c4bd40c65..000000000000
--- a/arch/sh/kernel/cpu/bus.c
+++ /dev/null
@@ -1,197 +0,0 @@
1/*
2 * arch/sh/kernel/cpu/bus.c
3 *
4 * Virtual bus for SuperH.
5 *
6 * Copyright (C) 2004 Paul Mundt
7 *
8 * Shamelessly cloned from arch/arm/mach-omap/bus.c, which was written
9 * by:
10 *
11 * Copyright (C) 2003 - 2004 Nokia Corporation
12 * Written by Tony Lindgren <tony@atomide.com>
13 * Portions of code based on sa1111.c.
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 */
20#include <linux/kernel.h>
21#include <linux/device.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <asm/bus-sh.h>
25
26static int sh_bus_match(struct device *dev, struct device_driver *drv)
27{
28 struct sh_driver *shdrv = to_sh_driver(drv);
29 struct sh_dev *shdev = to_sh_dev(dev);
30
31 return shdev->dev_id == shdrv->dev_id;
32}
33
34static int sh_bus_suspend(struct device *dev, pm_message_t state)
35{
36 struct sh_dev *shdev = to_sh_dev(dev);
37 struct sh_driver *shdrv = to_sh_driver(dev->driver);
38
39 if (shdrv && shdrv->suspend)
40 return shdrv->suspend(shdev, state);
41
42 return 0;
43}
44
45static int sh_bus_resume(struct device *dev)
46{
47 struct sh_dev *shdev = to_sh_dev(dev);
48 struct sh_driver *shdrv = to_sh_driver(dev->driver);
49
50 if (shdrv && shdrv->resume)
51 return shdrv->resume(shdev);
52
53 return 0;
54}
55
56static int sh_device_probe(struct device *dev)
57{
58 struct sh_dev *shdev = to_sh_dev(dev);
59 struct sh_driver *shdrv = to_sh_driver(dev->driver);
60
61 if (shdrv && shdrv->probe)
62 return shdrv->probe(shdev);
63
64 return -ENODEV;
65}
66
67static int sh_device_remove(struct device *dev)
68{
69 struct sh_dev *shdev = to_sh_dev(dev);
70 struct sh_driver *shdrv = to_sh_driver(dev->driver);
71
72 if (shdrv && shdrv->remove)
73 return shdrv->remove(shdev);
74
75 return 0;
76}
77
78static struct device sh_bus_devices[SH_NR_BUSES] = {
79 {
80 .bus_id = SH_BUS_NAME_VIRT,
81 },
82};
83
84struct bus_type sh_bus_types[SH_NR_BUSES] = {
85 {
86 .name = SH_BUS_NAME_VIRT,
87 .match = sh_bus_match,
88 .probe = sh_bus_probe,
89 .remove = sh_bus_remove,
90 .suspend = sh_bus_suspend,
91 .resume = sh_bus_resume,
92 },
93};
94
95int sh_device_register(struct sh_dev *dev)
96{
97 if (!dev)
98 return -EINVAL;
99
100 if (dev->bus_id < 0 || dev->bus_id >= SH_NR_BUSES) {
101 printk(KERN_ERR "%s: bus_id invalid: %s bus: %d\n",
102 __FUNCTION__, dev->name, dev->bus_id);
103 return -EINVAL;
104 }
105
106 dev->dev.parent = &sh_bus_devices[dev->bus_id];
107 dev->dev.bus = &sh_bus_types[dev->bus_id];
108
109 /* This is needed for USB OHCI to work */
110 if (dev->dma_mask)
111 dev->dev.dma_mask = dev->dma_mask;
112 if (dev->coherent_dma_mask)
113 dev->dev.coherent_dma_mask = dev->coherent_dma_mask;
114
115 snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%s%u",
116 dev->name, dev->dev_id);
117
118 printk(KERN_INFO "Registering SH device '%s'. Parent at %s\n",
119 dev->dev.bus_id, dev->dev.parent->bus_id);
120
121 return device_register(&dev->dev);
122}
123
124void sh_device_unregister(struct sh_dev *dev)
125{
126 device_unregister(&dev->dev);
127}
128
129int sh_driver_register(struct sh_driver *drv)
130{
131 if (!drv)
132 return -EINVAL;
133
134 if (drv->bus_id < 0 || drv->bus_id >= SH_NR_BUSES) {
135 printk(KERN_ERR "%s: bus_id invalid: bus: %d device %d\n",
136 __FUNCTION__, drv->bus_id, drv->dev_id);
137 return -EINVAL;
138 }
139
140 drv->drv.bus = &sh_bus_types[drv->bus_id];
141
142 return driver_register(&drv->drv);
143}
144
145void sh_driver_unregister(struct sh_driver *drv)
146{
147 driver_unregister(&drv->drv);
148}
149
150static int __init sh_bus_init(void)
151{
152 int i, ret = 0;
153
154 for (i = 0; i < SH_NR_BUSES; i++) {
155 ret = device_register(&sh_bus_devices[i]);
156 if (ret != 0) {
157 printk(KERN_ERR "Unable to register bus device %s\n",
158 sh_bus_devices[i].bus_id);
159 continue;
160 }
161
162 ret = bus_register(&sh_bus_types[i]);
163 if (ret != 0) {
164 printk(KERN_ERR "Unable to register bus %s\n",
165 sh_bus_types[i].name);
166 device_unregister(&sh_bus_devices[i]);
167 }
168 }
169
170 printk(KERN_INFO "SH Virtual Bus initialized\n");
171
172 return ret;
173}
174
175static void __exit sh_bus_exit(void)
176{
177 int i;
178
179 for (i = 0; i < SH_NR_BUSES; i++) {
180 bus_unregister(&sh_bus_types[i]);
181 device_unregister(&sh_bus_devices[i]);
182 }
183}
184
185module_init(sh_bus_init);
186module_exit(sh_bus_exit);
187
188MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
189MODULE_DESCRIPTION("SH Virtual Bus");
190MODULE_LICENSE("GPL");
191
192EXPORT_SYMBOL(sh_bus_types);
193EXPORT_SYMBOL(sh_device_register);
194EXPORT_SYMBOL(sh_device_unregister);
195EXPORT_SYMBOL(sh_driver_register);
196EXPORT_SYMBOL(sh_driver_unregister);
197
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 989e7fdd524d..97fa37f42b84 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -38,9 +38,7 @@ static DECLARE_MUTEX(clock_list_sem);
38static struct clk master_clk = { 38static struct clk master_clk = {
39 .name = "master_clk", 39 .name = "master_clk",
40 .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, 40 .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES,
41#ifdef CONFIG_SH_PCLK_FREQ_BOOL
42 .rate = CONFIG_SH_PCLK_FREQ, 41 .rate = CONFIG_SH_PCLK_FREQ,
43#endif
44}; 42};
45 43
46static struct clk module_clk = { 44static struct clk module_clk = {
@@ -227,16 +225,7 @@ int __init clk_init(void)
227{ 225{
228 int i, ret = 0; 226 int i, ret = 0;
229 227
230 if (unlikely(!master_clk.rate)) 228 BUG_ON(unlikely(!master_clk.rate));
231 /*
232 * NOTE: This will break if the default divisor has been
233 * changed.
234 *
235 * No one should be changing the default on us however,
236 * expect that a sane value for CONFIG_SH_PCLK_FREQ will
237 * be defined in the event of a different divisor.
238 */
239 master_clk.rate = get_timer_frequency() * 4;
240 229
241 for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) { 230 for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) {
242 struct clk *clk = onchip_clocks[i]; 231 struct clk *clk = onchip_clocks[i];
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index fdbd718ae5c6..e55150ed0856 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -108,8 +108,7 @@ static void end_ipr_irq(unsigned int irq)
108 enable_ipr_irq(irq); 108 enable_ipr_irq(irq);
109} 109}
110 110
111void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, 111void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)
112 int priority, int maskpos)
113{ 112{
114 disable_irq_nosync(irq); 113 disable_irq_nosync(irq);
115 ipr_data[irq].addr = addr; 114 ipr_data[irq].addr = addr;
@@ -123,44 +122,44 @@ void make_ipr_irq(unsigned int irq, unsigned int addr, int pos,
123void __init init_IRQ(void) 122void __init init_IRQ(void)
124{ 123{
125#ifndef CONFIG_CPU_SUBTYPE_SH7780 124#ifndef CONFIG_CPU_SUBTYPE_SH7780
126 make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY, 0); 125 make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
127 make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY, 0); 126 make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY);
128#if defined(CONFIG_SH_RTC) 127#if defined(CONFIG_SH_RTC)
129 make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY, 0); 128 make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
130#endif 129#endif
131 130
132#ifdef SCI_ERI_IRQ 131#ifdef SCI_ERI_IRQ
133 make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0); 132 make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
134 make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0); 133 make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
135 make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0); 134 make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
136#endif 135#endif
137 136
138#ifdef SCIF1_ERI_IRQ 137#ifdef SCIF1_ERI_IRQ
139 make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0); 138 make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
140 make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0); 139 make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
141 make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0); 140 make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
142 make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0); 141 make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
143#endif 142#endif
144 143
145#if defined(CONFIG_CPU_SUBTYPE_SH7300) 144#if defined(CONFIG_CPU_SUBTYPE_SH7300)
146 make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY, 0); 145 make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY);
147 make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY, 0); 146 make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
148 make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY, 0); 147 make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
149 make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY, 0); 148 make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
150#endif 149#endif
151 150
152#ifdef SCIF_ERI_IRQ 151#ifdef SCIF_ERI_IRQ
153 make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0); 152 make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
154 make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0); 153 make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
155 make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0); 154 make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
156 make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0); 155 make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
157#endif 156#endif
158 157
159#ifdef IRDA_ERI_IRQ 158#ifdef IRDA_ERI_IRQ
160 make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0); 159 make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
161 make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0); 160 make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
162 make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0); 161 make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
163 make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0); 162 make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
164#endif 163#endif
165 164
166#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ 165#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
@@ -175,12 +174,12 @@ void __init init_IRQ(void)
175 * You should set corresponding bits of PFC to "00" 174 * You should set corresponding bits of PFC to "00"
176 * to enable these interrupts. 175 * to enable these interrupts.
177 */ 176 */
178 make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY, 0); 177 make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY);
179 make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY, 0); 178 make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY);
180 make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY, 0); 179 make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY);
181 make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY, 0); 180 make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY);
182 make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY, 0); 181 make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY);
183 make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY, 0); 182 make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY);
184#endif 183#endif
185#endif 184#endif
186 185
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index fb6368159dd0..a440d36ee618 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -16,6 +16,7 @@
16#include <linux/config.h> 16#include <linux/config.h>
17#include <asm/asm-offsets.h> 17#include <asm/asm-offsets.h>
18#include <asm/thread_info.h> 18#include <asm/thread_info.h>
19#include <asm/cpu/mmu_context.h>
19#include <asm/unistd.h> 20#include <asm/unistd.h>
20 21
21#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE) 22#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE)
@@ -75,23 +76,6 @@
75ENOSYS = 38 76ENOSYS = 38
76EINVAL = 22 77EINVAL = 22
77 78
78#if defined(CONFIG_CPU_SH3)
79TRA = 0xffffffd0
80EXPEVT = 0xffffffd4
81#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
82 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
83INTEVT = 0xa4000000 ! INTEVTE2(0xa4000000)
84#else
85INTEVT = 0xffffffd8
86#endif
87MMU_TEA = 0xfffffffc ! TLB Exception Address Register
88#elif defined(CONFIG_CPU_SH4)
89TRA = 0xff000020
90EXPEVT = 0xff000024
91INTEVT = 0xff000028
92MMU_TEA = 0xff00000c ! TLB Exception Address Register
93#endif
94
95#if defined(CONFIG_KGDB_NMI) 79#if defined(CONFIG_KGDB_NMI)
96NMI_VEC = 0x1c0 ! Must catch early for debounce 80NMI_VEC = 0x1c0 ! Must catch early for debounce
97#endif 81#endif
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index a4dc2b532e10..9fd1723e6219 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -15,21 +15,18 @@
15#include <linux/unistd.h> 15#include <linux/unistd.h>
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/elfcore.h> 17#include <linux/elfcore.h>
18#include <linux/slab.h>
19#include <linux/a.out.h> 18#include <linux/a.out.h>
19#include <linux/slab.h>
20#include <linux/pm.h>
20#include <linux/ptrace.h> 21#include <linux/ptrace.h>
21#include <linux/platform.h> 22#include <linux/platform.h>
22#include <linux/kallsyms.h> 23#include <linux/kallsyms.h>
24#include <linux/kexec.h>
23 25
24#include <asm/io.h> 26#include <asm/io.h>
25#include <asm/uaccess.h> 27#include <asm/uaccess.h>
26#include <asm/mmu_context.h> 28#include <asm/mmu_context.h>
27#include <asm/elf.h> 29#include <asm/elf.h>
28#if defined(CONFIG_SH_HS7751RVOIP)
29#include <asm/hs7751rvoip/hs7751rvoip.h>
30#elif defined(CONFIG_SH_RTS7751R2D)
31#include <asm/rts7751r2d/rts7751r2d.h>
32#endif
33 30
34static int hlt_counter=0; 31static int hlt_counter=0;
35 32
@@ -37,6 +34,11 @@ int ubc_usercnt = 0;
37 34
38#define HARD_IDLE_TIMEOUT (HZ / 3) 35#define HARD_IDLE_TIMEOUT (HZ / 3)
39 36
37void (*pm_idle)(void);
38
39void (*pm_power_off)(void);
40EXPORT_SYMBOL(pm_power_off);
41
40void disable_hlt(void) 42void disable_hlt(void)
41{ 43{
42 hlt_counter++; 44 hlt_counter++;
@@ -51,17 +53,25 @@ void enable_hlt(void)
51 53
52EXPORT_SYMBOL(enable_hlt); 54EXPORT_SYMBOL(enable_hlt);
53 55
56void default_idle(void)
57{
58 if (!hlt_counter)
59 cpu_sleep();
60 else
61 cpu_relax();
62}
63
54void cpu_idle(void) 64void cpu_idle(void)
55{ 65{
56 /* endless idle loop with no priority at all */ 66 /* endless idle loop with no priority at all */
57 while (1) { 67 while (1) {
58 if (hlt_counter) { 68 void (*idle)(void) = pm_idle;
59 while (!need_resched()) 69
60 cpu_relax(); 70 if (!idle)
61 } else { 71 idle = default_idle;
62 while (!need_resched()) 72
63 cpu_sleep(); 73 while (!need_resched())
64 } 74 idle();
65 75
66 preempt_enable_no_resched(); 76 preempt_enable_no_resched();
67 schedule(); 77 schedule();
@@ -88,28 +98,16 @@ void machine_restart(char * __unused)
88 98
89void machine_halt(void) 99void machine_halt(void)
90{ 100{
91#if defined(CONFIG_SH_HS7751RVOIP) 101 local_irq_disable();
92 unsigned short value;
93 102
94 value = ctrl_inw(PA_OUTPORTR);
95 ctrl_outw((value & 0xffdf), PA_OUTPORTR);
96#elif defined(CONFIG_SH_RTS7751R2D)
97 ctrl_outw(0x0001, PA_POWOFF);
98#endif
99 while (1) 103 while (1)
100 cpu_sleep(); 104 cpu_sleep();
101} 105}
102 106
103void machine_power_off(void) 107void machine_power_off(void)
104{ 108{
105#if defined(CONFIG_SH_HS7751RVOIP) 109 if (pm_power_off)
106 unsigned short value; 110 pm_power_off();
107
108 value = ctrl_inw(PA_OUTPORTR);
109 ctrl_outw((value & 0xffdf), PA_OUTPORTR);
110#elif defined(CONFIG_SH_RTS7751R2D)
111 ctrl_outw(0x0001, PA_POWOFF);
112#endif
113} 111}
114 112
115void show_regs(struct pt_regs * regs) 113void show_regs(struct pt_regs * regs)
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 036050b377cd..a067a34e0b64 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -22,10 +22,10 @@
22#include <linux/cpu.h> 22#include <linux/cpu.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <asm/io.h> 24#include <asm/io.h>
25#include <asm/io_generic.h>
26#include <asm/sections.h> 25#include <asm/sections.h>
27#include <asm/irq.h> 26#include <asm/irq.h>
28#include <asm/setup.h> 27#include <asm/setup.h>
28#include <asm/clock.h>
29 29
30#ifdef CONFIG_SH_KGDB 30#ifdef CONFIG_SH_KGDB
31#include <asm/kgdb.h> 31#include <asm/kgdb.h>
@@ -41,7 +41,7 @@ extern void * __rd_start, * __rd_end;
41 * This value will be used at the very early stage of serial setup. 41 * This value will be used at the very early stage of serial setup.
42 * The bigger value means no problem. 42 * The bigger value means no problem.
43 */ 43 */
44struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 0, 10000000, }; 44struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, };
45struct screen_info screen_info; 45struct screen_info screen_info;
46 46
47#if defined(CONFIG_SH_UNKNOWN) 47#if defined(CONFIG_SH_UNKNOWN)
@@ -186,7 +186,7 @@ static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE],
186 186
187static int __init sh_mv_setup(char **cmdline_p) 187static int __init sh_mv_setup(char **cmdline_p)
188{ 188{
189#if defined(CONFIG_SH_UNKNOWN) 189#ifdef CONFIG_SH_UNKNOWN
190 extern struct sh_machine_vector mv_unknown; 190 extern struct sh_machine_vector mv_unknown;
191#endif 191#endif
192 struct sh_machine_vector *mv = NULL; 192 struct sh_machine_vector *mv = NULL;
@@ -196,7 +196,7 @@ static int __init sh_mv_setup(char **cmdline_p)
196 196
197 parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable); 197 parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable);
198 198
199#ifdef CONFIG_SH_GENERIC 199#ifdef CONFIG_SH_UNKNOWN
200 if (mv == NULL) { 200 if (mv == NULL) {
201 mv = &mv_unknown; 201 mv = &mv_unknown;
202 if (*mv_name != '\0') { 202 if (*mv_name != '\0') {
@@ -206,9 +206,6 @@ static int __init sh_mv_setup(char **cmdline_p)
206 } 206 }
207 sh_mv = *mv; 207 sh_mv = *mv;
208#endif 208#endif
209#ifdef CONFIG_SH_UNKNOWN
210 sh_mv = mv_unknown;
211#endif
212 209
213 /* 210 /*
214 * Manually walk the vec, fill in anything that the board hasn't yet 211 * Manually walk the vec, fill in anything that the board hasn't yet
@@ -231,10 +228,8 @@ static int __init sh_mv_setup(char **cmdline_p)
231 mv_set(readb); mv_set(readw); mv_set(readl); 228 mv_set(readb); mv_set(readw); mv_set(readl);
232 mv_set(writeb); mv_set(writew); mv_set(writel); 229 mv_set(writeb); mv_set(writew); mv_set(writel);
233 230
234 mv_set(ioremap); 231 mv_set(ioport_map);
235 mv_set(iounmap); 232 mv_set(ioport_unmap);
236
237 mv_set(isa_port2addr);
238 mv_set(irq_demux); 233 mv_set(irq_demux);
239 234
240#ifdef CONFIG_SH_UNKNOWN 235#ifdef CONFIG_SH_UNKNOWN
@@ -273,10 +268,10 @@ void __init setup_arch(char **cmdline_p)
273 init_mm.end_data = (unsigned long) _edata; 268 init_mm.end_data = (unsigned long) _edata;
274 init_mm.brk = (unsigned long) _end; 269 init_mm.brk = (unsigned long) _end;
275 270
276 code_resource.start = virt_to_bus(_text); 271 code_resource.start = (unsigned long)virt_to_phys(_text);
277 code_resource.end = virt_to_bus(_etext)-1; 272 code_resource.end = (unsigned long)virt_to_phys(_etext)-1;
278 data_resource.start = virt_to_bus(_etext); 273 data_resource.start = (unsigned long)virt_to_phys(_etext);
279 data_resource.end = virt_to_bus(_edata)-1; 274 data_resource.end = (unsigned long)virt_to_phys(_edata)-1;
280 275
281 sh_mv_setup(cmdline_p); 276 sh_mv_setup(cmdline_p);
282 277
@@ -435,6 +430,9 @@ static const char *cpu_name[] = {
435 [CPU_ST40GX1] = "ST40GX1", 430 [CPU_ST40GX1] = "ST40GX1",
436 [CPU_SH4_202] = "SH4-202", 431 [CPU_SH4_202] = "SH4-202",
437 [CPU_SH4_501] = "SH4-501", 432 [CPU_SH4_501] = "SH4-501",
433 [CPU_SH7770] = "SH7770",
434 [CPU_SH7780] = "SH7780",
435 [CPU_SH7781] = "SH7781",
438 [CPU_SH_NONE] = "Unknown" 436 [CPU_SH_NONE] = "Unknown"
439}; 437};
440 438
@@ -445,7 +443,7 @@ const char *get_cpu_subtype(void)
445 443
446#ifdef CONFIG_PROC_FS 444#ifdef CONFIG_PROC_FS
447static const char *cpu_flags[] = { 445static const char *cpu_flags[] = {
448 "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr", 446 "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr", "ptea", NULL
449}; 447};
450 448
451static void show_cpuflags(struct seq_file *m) 449static void show_cpuflags(struct seq_file *m)
@@ -459,7 +457,7 @@ static void show_cpuflags(struct seq_file *m)
459 return; 457 return;
460 } 458 }
461 459
462 for (i = 0; i < cpu_data->flags; i++) 460 for (i = 0; cpu_flags[i]; i++)
463 if ((cpu_data->flags & (1 << i))) 461 if ((cpu_data->flags & (1 << i)))
464 seq_printf(m, " %s", cpu_flags[i+1]); 462 seq_printf(m, " %s", cpu_flags[i+1]);
465 463
@@ -472,7 +470,8 @@ static void show_cacheinfo(struct seq_file *m, const char *type, struct cache_in
472 470
473 cache_size = info.ways * info.sets * info.linesz; 471 cache_size = info.ways * info.sets * info.linesz;
474 472
475 seq_printf(m, "%s size\t: %dKiB\n", type, cache_size >> 10); 473 seq_printf(m, "%s size\t: %2dKiB (%d-way)\n",
474 type, cache_size >> 10, info.ways);
476} 475}
477 476
478/* 477/*
@@ -511,21 +510,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
511 boot_cpu_data.loops_per_jiffy/(500000/HZ), 510 boot_cpu_data.loops_per_jiffy/(500000/HZ),
512 (boot_cpu_data.loops_per_jiffy/(5000/HZ)) % 100); 511 (boot_cpu_data.loops_per_jiffy/(5000/HZ)) % 100);
513 512
514#define PRINT_CLOCK(name, value) \ 513 return show_clocks(m);
515 seq_printf(m, name " clock\t: %d.%02dMHz\n", \
516 ((value) / 1000000), ((value) % 1000000)/10000)
517
518 PRINT_CLOCK("cpu", boot_cpu_data.cpu_clock);
519 PRINT_CLOCK("bus", boot_cpu_data.bus_clock);
520#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
521 PRINT_CLOCK("memory", boot_cpu_data.memory_clock);
522#endif
523 PRINT_CLOCK("module", boot_cpu_data.module_clock);
524
525 return 0;
526} 514}
527 515
528
529static void *c_start(struct seq_file *m, loff_t *pos) 516static void *c_start(struct seq_file *m, loff_t *pos)
530{ 517{
531 return *pos < NR_CPUS ? cpu_data + *pos : NULL; 518 return *pos < NR_CPUS ? cpu_data + *pos : NULL;
@@ -596,7 +583,7 @@ static int __init kgdb_parse_options(char *options)
596 options += map->namelen + 1; 583 options += map->namelen + 1;
597 584
598 options = (*options == ',') ? options+1 : options; 585 options = (*options == ',') ? options+1 : options;
599 586
600 /* Read optional parameters (baud/parity/bits) */ 587 /* Read optional parameters (baud/parity/bits) */
601 baud = simple_strtoul(options, &options, 10); 588 baud = simple_strtoul(options, &options, 10);
602 if (baud != 0) { 589 if (baud != 0) {