summaryrefslogtreecommitdiff
path: root/arch/sh/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/Makefile_322
-rw-r--r--arch/sh/kernel/Makefile_642
-rw-r--r--arch/sh/kernel/asm-offsets.c7
-rw-r--r--arch/sh/kernel/cf-enabler.c15
-rw-r--r--arch/sh/kernel/cpu/irq/intc-sh5.c72
-rw-r--r--arch/sh/kernel/cpu/irq/intc.c93
-rw-r--r--arch/sh/kernel/cpu/sh2a/Makefile7
-rw-r--r--arch/sh/kernel/cpu/sh2a/fpu.c5
-rw-r--r--arch/sh/kernel/cpu/sh2a/probe.c3
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-mxg.c168
-rw-r--r--arch/sh/kernel/cpu/sh3/Makefile2
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh3.c71
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c22
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh770x.c32
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c25
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7720.c35
-rw-r--r--arch/sh/kernel/cpu/sh4/fpu.c1
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c34
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7785.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c26
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7723.c335
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7763.c19
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7770.c37
-rw-r--r--arch/sh/kernel/cpu/sh5/entry.S28
-rw-r--r--arch/sh/kernel/cpu/sh5/fpu.c1
-rw-r--r--arch/sh/kernel/cpu/sh5/probe.c4
-rw-r--r--arch/sh/kernel/dump_task.c1
-rw-r--r--arch/sh/kernel/early_printk.c30
-rw-r--r--arch/sh/kernel/entry-common.S12
-rw-r--r--arch/sh/kernel/head_32.S4
-rw-r--r--arch/sh/kernel/init_task.c1
-rw-r--r--arch/sh/kernel/irq.c2
-rw-r--r--arch/sh/kernel/kgdb_stub.c19
-rw-r--r--arch/sh/kernel/module.c39
-rw-r--r--arch/sh/kernel/process_32.c1
-rw-r--r--arch/sh/kernel/process_64.c1
-rw-r--r--arch/sh/kernel/ptrace_64.c1
-rw-r--r--arch/sh/kernel/semaphore.c139
-rw-r--r--arch/sh/kernel/setup.c72
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c10
-rw-r--r--arch/sh/kernel/sh_ksyms_64.c31
-rw-r--r--arch/sh/kernel/signal_32.c1
-rw-r--r--arch/sh/kernel/signal_64.c1
-rw-r--r--arch/sh/kernel/sys_sh64.c17
-rw-r--r--arch/sh/kernel/time_64.c5
-rw-r--r--arch/sh/kernel/traps.c10
-rw-r--r--arch/sh/kernel/traps_32.c1
-rw-r--r--arch/sh/kernel/traps_64.c1
49 files changed, 1019 insertions, 430 deletions
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
index 62bf373266f7..4bbdce36b92b 100644
--- a/arch/sh/kernel/Makefile_32
+++ b/arch/sh/kernel/Makefile_32
@@ -5,7 +5,7 @@
extra-y := head_32.o init_task.o vmlinux.lds
obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \
- ptrace_32.o semaphore.o setup.o signal_32.o sys_sh.o sys_sh32.o \
+ ptrace_32.o setup.o signal_32.o sys_sh.o sys_sh32.o \
syscalls_32.o time_32.o topology.o traps.o traps_32.o
obj-y += cpu/ timers/
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64
index e01283d49cbf..6edf53b93d94 100644
--- a/arch/sh/kernel/Makefile_64
+++ b/arch/sh/kernel/Makefile_64
@@ -1,7 +1,7 @@
extra-y := head_64.o init_task.o vmlinux.lds
obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_64.o \
- ptrace_64.o semaphore.o setup.o signal_64.o sys_sh.o sys_sh64.o \
+ ptrace_64.o setup.o signal_64.o sys_sh.o sys_sh64.o \
syscalls_64.o time_64.o topology.o traps.o traps_64.o
obj-y += cpu/ timers/
diff --git a/arch/sh/kernel/asm-offsets.c b/arch/sh/kernel/asm-offsets.c
index dc6725c51a89..57cf0e0680f3 100644
--- a/arch/sh/kernel/asm-offsets.c
+++ b/arch/sh/kernel/asm-offsets.c
@@ -11,12 +11,9 @@
#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/mm.h>
-#include <asm/thread_info.h>
-
-#define DEFINE(sym, val) \
- asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+#include <linux/kbuild.h>
-#define BLANK() asm volatile("\n->" : : )
+#include <asm/thread_info.h>
int main(void)
{
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
index 1c3b99642e1c..01ff4d05aab0 100644
--- a/arch/sh/kernel/cf-enabler.c
+++ b/arch/sh/kernel/cf-enabler.c
@@ -83,6 +83,8 @@ static int __init cf_init_default(void)
#include <asm/se.h>
#elif defined(CONFIG_SH_7722_SOLUTION_ENGINE)
#include <asm/se7722.h>
+#elif defined(CONFIG_SH_7721_SOLUTION_ENGINE)
+#include <asm/se7721.h>
#endif
/*
@@ -99,7 +101,9 @@ static int __init cf_init_default(void)
* 0xB0600000 : I/O
*/
-#if defined(CONFIG_SH_SOLUTION_ENGINE) || defined(CONFIG_SH_7722_SOLUTION_ENGINE)
+#if defined(CONFIG_SH_SOLUTION_ENGINE) || \
+ defined(CONFIG_SH_7722_SOLUTION_ENGINE) || \
+ defined(CONFIG_SH_7721_SOLUTION_ENGINE)
static int __init cf_init_se(void)
{
if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0)
@@ -112,7 +116,7 @@ static int __init cf_init_se(void)
}
/*
- * PC-Card window open
+ * PC-Card window open
* flag == COMMON/ATTRIBUTE/IO
*/
/* common window open */
@@ -122,7 +126,7 @@ static int __init cf_init_se(void)
ctrl_outw(0x0b00, MRSHPC_MW0CR2);
else
/* common mode & bus width 16bit SWAP = 0*/
- ctrl_outw(0x0300, MRSHPC_MW0CR2);
+ ctrl_outw(0x0300, MRSHPC_MW0CR2);
/* attribute window open */
ctrl_outw(0x8a85, MRSHPC_MW1CR1);
@@ -155,10 +159,9 @@ static int __init cf_init_se(void)
int __init cf_init(void)
{
- if( mach_is_se() || mach_is_7722se() ){
+ if (mach_is_se() || mach_is_7722se() || mach_is_7721se())
return cf_init_se();
- }
-
+
return cf_init_default();
}
diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c
index d6e0e2bdaad5..79baa47af977 100644
--- a/arch/sh/kernel/cpu/irq/intc-sh5.c
+++ b/arch/sh/kernel/cpu/irq/intc-sh5.c
@@ -184,9 +184,8 @@ int intc_irq_describe(char* p, int irq)
void __init plat_irq_setup(void)
{
- unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
+ unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
unsigned long reg;
- unsigned long data;
int i;
intc_virt = onchip_remap(INTC_BASE, 1024, "INTC");
@@ -196,11 +195,8 @@ void __init plat_irq_setup(void)
/* Set default: per-line enable/disable, priority driven ack/eoi */
- for (i = 0; i < NR_INTC_IRQS; i++) {
- if (platform_int_priority[i] != NO_PRIORITY) {
- irq_desc[i].chip = &intc_irq_type;
- }
- }
+ for (i = 0; i < NR_INTC_IRQS; i++)
+ irq_desc[i].chip = &intc_irq_type;
/* Disable all interrupts and set all priorities to 0 to avoid trouble */
@@ -211,35 +207,43 @@ void __init plat_irq_setup(void)
ctrl_outl( NO_PRIORITY, reg);
- /* Set IRLM */
- /* If all the priorities are set to 'no priority', then
- * assume we are using encoded mode.
- */
- irlm = platform_int_priority[IRQ_IRL0] + platform_int_priority[IRQ_IRL1] + \
- platform_int_priority[IRQ_IRL2] + platform_int_priority[IRQ_IRL3];
-
- if (irlm == NO_PRIORITY) {
- /* IRLM = 0 */
- reg = INTC_ICR_CLEAR;
- i = IRQ_INTA;
- printk("Trying to use encoded IRL0-3. IRLs unsupported.\n");
- } else {
- /* IRLM = 1 */
- reg = INTC_ICR_SET;
- i = IRQ_IRL0;
- }
- ctrl_outl(INTC_ICR_IRLM, reg);
-
- /* Set interrupt priorities according to platform description */
- for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
- data |= platform_int_priority[i] << ((i % INTC_INTPRI_PPREG) * 4);
- if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
- /* Upon the 7th, set Priority Register */
- ctrl_outl(data, reg);
- data = 0;
- reg += 8;
+#ifdef CONFIG_SH_CAYMAN
+ {
+ unsigned long data;
+
+ /* Set IRLM */
+ /* If all the priorities are set to 'no priority', then
+ * assume we are using encoded mode.
+ */
+ irlm = platform_int_priority[IRQ_IRL0] +
+ platform_int_priority[IRQ_IRL1] +
+ platform_int_priority[IRQ_IRL2] +
+ platform_int_priority[IRQ_IRL3];
+ if (irlm == NO_PRIORITY) {
+ /* IRLM = 0 */
+ reg = INTC_ICR_CLEAR;
+ i = IRQ_INTA;
+ printk("Trying to use encoded IRL0-3. IRLs unsupported.\n");
+ } else {
+ /* IRLM = 1 */
+ reg = INTC_ICR_SET;
+ i = IRQ_IRL0;
+ }
+ ctrl_outl(INTC_ICR_IRLM, reg);
+
+ /* Set interrupt priorities according to platform description */
+ for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
+ data |= platform_int_priority[i] <<
+ ((i % INTC_INTPRI_PPREG) * 4);
+ if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
+ /* Upon the 7th, set Priority Register */
+ ctrl_outl(data, reg);
+ data = 0;
+ reg += 8;
+ }
}
}
+#endif
/*
* And now let interrupts come in.
diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c
index 84806b2027f8..da5dae787888 100644
--- a/arch/sh/kernel/cpu/irq/intc.c
+++ b/arch/sh/kernel/cpu/irq/intc.c
@@ -1,7 +1,7 @@
/*
* Shared interrupt handling code for IPR and INTC2 types of IRQs.
*
- * Copyright (C) 2007 Magnus Damm
+ * Copyright (C) 2007, 2008 Magnus Damm
*
* Based on intc2.c and ipr.c
*
@@ -62,6 +62,9 @@ struct intc_desc_int {
#endif
static unsigned int intc_prio_level[NR_IRQS]; /* for now */
+#ifdef CONFIG_CPU_SH3
+static unsigned long ack_handle[NR_IRQS];
+#endif
static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
{
@@ -98,17 +101,26 @@ static void write_32(unsigned long addr, unsigned long h, unsigned long data)
static void modify_8(unsigned long addr, unsigned long h, unsigned long data)
{
+ unsigned long flags;
+ local_irq_save(flags);
ctrl_outb(set_field(ctrl_inb(addr), data, h), addr);
+ local_irq_restore(flags);
}
static void modify_16(unsigned long addr, unsigned long h, unsigned long data)
{
+ unsigned long flags;
+ local_irq_save(flags);
ctrl_outw(set_field(ctrl_inw(addr), data, h), addr);
+ local_irq_restore(flags);
}
static void modify_32(unsigned long addr, unsigned long h, unsigned long data)
{
+ unsigned long flags;
+ local_irq_save(flags);
ctrl_outl(set_field(ctrl_inl(addr), data, h), addr);
+ local_irq_restore(flags);
}
enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 };
@@ -219,6 +231,25 @@ static void intc_disable(unsigned int irq)
}
}
+#ifdef CONFIG_CPU_SH3
+static void intc_mask_ack(unsigned int irq)
+{
+ struct intc_desc_int *d = get_intc_desc(irq);
+ unsigned long handle = ack_handle[irq];
+ unsigned long addr;
+
+ intc_disable(irq);
+
+ /* read register and write zero only to the assocaited bit */
+
+ if (handle) {
+ addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
+ ctrl_inb(addr);
+ ctrl_outb(0x3f ^ set_field(0, 1, handle), addr);
+ }
+}
+#endif
+
static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
unsigned int nr_hp,
unsigned int irq)
@@ -280,7 +311,12 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
[IRQ_TYPE_EDGE_FALLING] = VALID(0),
[IRQ_TYPE_EDGE_RISING] = VALID(1),
[IRQ_TYPE_LEVEL_LOW] = VALID(2),
+ /* SH7706, SH7707 and SH7709 do not support high level triggered */
+#if !defined(CONFIG_CPU_SUBTYPE_SH7706) && \
+ !defined(CONFIG_CPU_SUBTYPE_SH7707) && \
+ !defined(CONFIG_CPU_SUBTYPE_SH7709)
[IRQ_TYPE_LEVEL_HIGH] = VALID(3),
+#endif
};
static int intc_set_sense(unsigned int irq, unsigned int type)
@@ -430,6 +466,40 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc,
return 0;
}
+#ifdef CONFIG_CPU_SH3
+static unsigned int __init intc_ack_data(struct intc_desc *desc,
+ struct intc_desc_int *d,
+ intc_enum enum_id)
+{
+ struct intc_mask_reg *mr = desc->ack_regs;
+ unsigned int i, j, fn, mode;
+ unsigned long reg_e, reg_d;
+
+ for (i = 0; mr && enum_id && i < desc->nr_ack_regs; i++) {
+ mr = desc->ack_regs + i;
+
+ for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
+ if (mr->enum_ids[j] != enum_id)
+ continue;
+
+ fn = REG_FN_MODIFY_BASE;
+ mode = MODE_ENABLE_REG;
+ reg_e = mr->set_reg;
+ reg_d = mr->set_reg;
+
+ fn += (mr->reg_width >> 3) - 1;
+ return _INTC_MK(fn, mode,
+ intc_get_reg(d, reg_e),
+ intc_get_reg(d, reg_d),
+ 1,
+ (mr->reg_width - 1) - j);
+ }
+ }
+
+ return 0;
+}
+#endif
+
static unsigned int __init intc_sense_data(struct intc_desc *desc,
struct intc_desc_int *d,
intc_enum enum_id)
@@ -530,6 +600,11 @@ static void __init intc_register_irq(struct intc_desc *desc,
/* irq should be disabled by default */
d->chip.mask(irq);
+
+#ifdef CONFIG_CPU_SH3
+ if (desc->ack_regs)
+ ack_handle[irq] = intc_ack_data(desc, d, enum_id);
+#endif
}
static unsigned int __init save_reg(struct intc_desc_int *d,
@@ -560,6 +635,9 @@ void __init register_intc_controller(struct intc_desc *desc)
d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
+#ifdef CONFIG_CPU_SH3
+ d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0;
+#endif
d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg));
#ifdef CONFIG_SMP
d->smp = alloc_bootmem(d->nr_reg * sizeof(*d->smp));
@@ -592,14 +670,23 @@ void __init register_intc_controller(struct intc_desc *desc)
}
}
- BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
-
d->chip.name = desc->name;
d->chip.mask = intc_disable;
d->chip.unmask = intc_enable;
d->chip.mask_ack = intc_disable;
d->chip.set_type = intc_set_sense;
+#ifdef CONFIG_CPU_SH3
+ if (desc->ack_regs) {
+ for (i = 0; i < desc->nr_ack_regs; i++)
+ k += save_reg(d, k, desc->ack_regs[i].set_reg, 0);
+
+ d->chip.mask_ack = intc_mask_ack;
+ }
+#endif
+
+ BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
+
for (i = 0; i < desc->nr_vectors; i++) {
struct intc_vect *vect = desc->vectors + i;
diff --git a/arch/sh/kernel/cpu/sh2a/Makefile b/arch/sh/kernel/cpu/sh2a/Makefile
index b279cdc3a233..7e2b90cfa7bf 100644
--- a/arch/sh/kernel/cpu/sh2a/Makefile
+++ b/arch/sh/kernel/cpu/sh2a/Makefile
@@ -8,6 +8,7 @@ common-y += $(addprefix ../sh2/, ex.o entry.o)
obj-$(CONFIG_SH_FPU) += fpu.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7203) += setup-sh7203.o clock-sh7203.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7263) += setup-sh7203.o clock-sh7203.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7203) += setup-sh7203.o clock-sh7203.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7263) += setup-sh7203.o clock-sh7203.o
+obj-$(CONFIG_CPU_SUBTYPE_MXG) += setup-mxg.o clock-sh7206.o
diff --git a/arch/sh/kernel/cpu/sh2a/fpu.c b/arch/sh/kernel/cpu/sh2a/fpu.c
index ff99562456fb..6df2fb98eb30 100644
--- a/arch/sh/kernel/cpu/sh2a/fpu.c
+++ b/arch/sh/kernel/cpu/sh2a/fpu.c
@@ -13,6 +13,7 @@
#include <linux/signal.h>
#include <asm/processor.h>
#include <asm/io.h>
+#include <asm/fpu.h>
/* The PR (precision) bit in the FP Status Register must be clear when
* an frchg instruction is executed, otherwise the instruction is undefined.
@@ -299,7 +300,7 @@ static int denormal_addf(int hx, int hy)
iy = hy & 0x7fffffff;
if (iy < 0x00800000) {
ix = denormal_subf1(ix, iy);
- if (ix < 0) {
+ if ((int) ix < 0) {
ix = -ix;
sign ^= 0x80000000;
}
@@ -384,7 +385,7 @@ static long long denormal_addd(long long hx, long long hy)
iy = hy & 0x7fffffffffffffffLL;
if (iy < 0x0010000000000000LL) {
ix = denormal_subd1(ix, iy);
- if (ix < 0) {
+ if ((int) ix < 0) {
ix = -ix;
sign ^= 0x8000000000000000LL;
}
diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c
index 6910e2664468..6e79132f6f30 100644
--- a/arch/sh/kernel/cpu/sh2a/probe.c
+++ b/arch/sh/kernel/cpu/sh2a/probe.c
@@ -29,6 +29,9 @@ int __init detect_cpu_and_cache_system(void)
boot_cpu_data.type = CPU_SH7206;
/* While SH7206 has a DSP.. */
boot_cpu_data.flags |= CPU_HAS_DSP;
+#elif defined(CONFIG_CPU_SUBTYPE_MXG)
+ boot_cpu_data.type = CPU_MXG;
+ boot_cpu_data.flags |= CPU_HAS_DSP;
#endif
boot_cpu_data.dcache.ways = 4;
diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
new file mode 100644
index 000000000000..e611d79fac4c
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
@@ -0,0 +1,168 @@
+/*
+ * Renesas MX-G (R8A03022BG) Setup
+ *
+ * Copyright (C) 2008 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/serial_sci.h>
+
+enum {
+ UNUSED = 0,
+
+ /* interrupt sources */
+ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
+ IRQ8, IRQ9, IRQ10, IRQ11, IRQ12, IRQ13, IRQ14, IRQ15,
+
+ PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
+
+ SINT8, SINT7, SINT6, SINT5, SINT4, SINT3, SINT2, SINT1,
+
+ SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
+ SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
+
+ MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
+ MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
+ MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
+ MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
+ MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
+ MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
+ MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W,
+
+ /* interrupt groups */
+ PINT, SCIF0, SCIF1,
+ MTU2_GROUP1, MTU2_GROUP2, MTU2_GROUP3, MTU2_GROUP4, MTU2_GROUP5
+};
+
+static struct intc_vect vectors[] __initdata = {
+ INTC_IRQ(IRQ0, 64), INTC_IRQ(IRQ1, 65),
+ INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67),
+ INTC_IRQ(IRQ4, 68), INTC_IRQ(IRQ5, 69),
+ INTC_IRQ(IRQ6, 70), INTC_IRQ(IRQ7, 71),
+ INTC_IRQ(IRQ8, 72), INTC_IRQ(IRQ9, 73),
+ INTC_IRQ(IRQ10, 74), INTC_IRQ(IRQ11, 75),
+ INTC_IRQ(IRQ12, 76), INTC_IRQ(IRQ13, 77),
+ INTC_IRQ(IRQ14, 78), INTC_IRQ(IRQ15, 79),
+
+ INTC_IRQ(PINT0, 80), INTC_IRQ(PINT1, 81),
+ INTC_IRQ(PINT2, 82), INTC_IRQ(PINT3, 83),
+ INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85),
+ INTC_IRQ(PINT6, 86), INTC_IRQ(PINT7, 87),
+
+ INTC_IRQ(SINT8, 94), INTC_IRQ(SINT7, 95),
+ INTC_IRQ(SINT6, 96), INTC_IRQ(SINT5, 97),
+ INTC_IRQ(SINT4, 98), INTC_IRQ(SINT3, 99),
+ INTC_IRQ(SINT2, 100), INTC_IRQ(SINT1, 101),
+
+ INTC_IRQ(SCIF0_RXI, 220), INTC_IRQ(SCIF0_TXI, 221),
+ INTC_IRQ(SCIF0_BRI, 222), INTC_IRQ(SCIF0_ERI, 223),
+ INTC_IRQ(SCIF1_RXI, 224), INTC_IRQ(SCIF1_TXI, 225),
+ INTC_IRQ(SCIF1_BRI, 226), INTC_IRQ(SCIF1_ERI, 227),
+
+ INTC_IRQ(MTU2_TGI0A, 228), INTC_IRQ(MTU2_TGI0B, 229),
+ INTC_IRQ(MTU2_TGI0C, 230), INTC_IRQ(MTU2_TGI0D, 231),
+ INTC_IRQ(MTU2_TCI0V, 232), INTC_IRQ(MTU2_TGI0E, 233),
+
+ INTC_IRQ(MTU2_TGI0F, 234), INTC_IRQ(MTU2_TGI1A, 235),
+ INTC_IRQ(MTU2_TGI1B, 236), INTC_IRQ(MTU2_TCI1V, 237),
+ INTC_IRQ(MTU2_TCI1U, 238), INTC_IRQ(MTU2_TGI2A, 239),
+
+ INTC_IRQ(MTU2_TGI2B, 240), INTC_IRQ(MTU2_TCI2V, 241),
+ INTC_IRQ(MTU2_TCI2U, 242), INTC_IRQ(MTU2_TGI3A, 243),
+
+ INTC_IRQ(MTU2_TGI3B, 244),
+ INTC_IRQ(MTU2_TGI3C, 245),
+
+ INTC_IRQ(MTU2_TGI3D, 246), INTC_IRQ(MTU2_TCI3V, 247),
+ INTC_IRQ(MTU2_TGI4A, 248), INTC_IRQ(MTU2_TGI4B, 249),
+ INTC_IRQ(MTU2_TGI4C, 250), INTC_IRQ(MTU2_TGI4D, 251),
+
+ INTC_IRQ(MTU2_TCI4V, 252), INTC_IRQ(MTU2_TGI5U, 253),
+ INTC_IRQ(MTU2_TGI5V, 254), INTC_IRQ(MTU2_TGI5W, 255),
+};
+
+static struct intc_group groups[] __initdata = {
+ INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
+ PINT4, PINT5, PINT6, PINT7),
+ INTC_GROUP(MTU2_GROUP1, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
+ MTU2_TCI0V, MTU2_TGI0E),
+ INTC_GROUP(MTU2_GROUP2, MTU2_TGI0F, MTU2_TGI1A, MTU2_TGI1B,
+ MTU2_TCI1V, MTU2_TCI1U, MTU2_TGI2A),
+ INTC_GROUP(MTU2_GROUP3, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
+ MTU2_TGI3A),
+ INTC_GROUP(MTU2_GROUP4, MTU2_TGI3D, MTU2_TCI3V, MTU2_TGI4A,
+ MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
+ INTC_GROUP(MTU2_GROUP5, MTU2_TCI4V, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W),
+ INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
+ INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
+};
+
+static struct intc_prio_reg prio_registers[] __initdata = {
+ { 0xfffd9418, 0, 16, 4, /* IPR01 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
+ { 0xfffd941a, 0, 16, 4, /* IPR02 */ { IRQ4, IRQ5, IRQ6, IRQ7 } },
+ { 0xfffd941c, 0, 16, 4, /* IPR03 */ { IRQ8, IRQ9, IRQ10, IRQ11 } },
+ { 0xfffd941e, 0, 16, 4, /* IPR04 */ { IRQ12, IRQ13, IRQ14, IRQ15 } },
+ { 0xfffd9420, 0, 16, 4, /* IPR05 */ { PINT, 0, 0, 0 } },
+ { 0xfffd9800, 0, 16, 4, /* IPR06 */ { } },
+ { 0xfffd9802, 0, 16, 4, /* IPR07 */ { } },
+ { 0xfffd9804, 0, 16, 4, /* IPR08 */ { } },
+ { 0xfffd9806, 0, 16, 4, /* IPR09 */ { } },
+ { 0xfffd9808, 0, 16, 4, /* IPR10 */ { } },
+ { 0xfffd980a, 0, 16, 4, /* IPR11 */ { } },
+ { 0xfffd980c, 0, 16, 4, /* IPR12 */ { } },
+ { 0xfffd980e, 0, 16, 4, /* IPR13 */ { } },
+ { 0xfffd9810, 0, 16, 4, /* IPR14 */ { 0, 0, 0, SCIF0 } },
+ { 0xfffd9812, 0, 16, 4, /* IPR15 */
+ { SCIF1, MTU2_GROUP1, MTU2_GROUP2, MTU2_GROUP3 } },
+ { 0xfffd9814, 0, 16, 4, /* IPR16 */
+ { MTU2_TGI3B, MTU2_TGI3C, MTU2_GROUP4, MTU2_GROUP5 } },
+};
+
+static struct intc_mask_reg mask_registers[] __initdata = {
+ { 0xfffd9408, 0, 16, /* PINTER */
+ { 0, 0, 0, 0, 0, 0, 0, 0,
+ PINT7, PINT6, PINT5, PINT4, PINT3, PINT2, PINT1, PINT0 } },
+};
+
+static DECLARE_INTC_DESC(intc_desc, "mxg", vectors, groups,
+ mask_registers, prio_registers, NULL);
+
+static struct plat_sci_port sci_platform_data[] = {
+ {
+ .mapbase = 0xff804000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 223, 220, 221, 222 },
+ }, {
+ .flags = 0,
+ }
+};
+
+static struct platform_device sci_device = {
+ .name = "sh-sci",
+ .id = -1,
+ .dev = {
+ .platform_data = sci_platform_data,
+ },
+};
+
+static struct platform_device *mxg_devices[] __initdata = {
+ &sci_device,
+};
+
+static int __init mxg_devices_setup(void)
+{
+ return platform_add_devices(mxg_devices,
+ ARRAY_SIZE(mxg_devices));
+}
+__initcall(mxg_devices_setup);
+
+void __init plat_irq_setup(void)
+{
+ register_intc_controller(&intc_desc);
+}
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile
index 3ae4d9111f19..511de55af832 100644
--- a/arch/sh/kernel/cpu/sh3/Makefile
+++ b/arch/sh/kernel/cpu/sh3/Makefile
@@ -2,7 +2,7 @@
# Makefile for the Linux/SuperH SH-3 backends.
#
-obj-y := ex.o probe.o entry.o
+obj-y := ex.o probe.o entry.o setup-sh3.o
# CPU subtype setup
obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh3.c b/arch/sh/kernel/cpu/sh3/setup-sh3.c
new file mode 100644
index 000000000000..c98846857855
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/setup-sh3.c
@@ -0,0 +1,71 @@
+/*
+ * Shared SH3 Setup code
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+/* All SH3 devices are equipped with IRQ0->5 (except sh7708) */
+
+enum {
+ UNUSED = 0,
+
+ /* interrupt sources */
+ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
+};
+
+static struct intc_vect vectors_irq0123[] __initdata = {
+ INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
+ INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
+};
+
+static struct intc_vect vectors_irq45[] __initdata = {
+ INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+};
+
+static struct intc_prio_reg prio_registers[] __initdata = {
+ { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
+ { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } },
+};
+
+static struct intc_mask_reg ack_registers[] __initdata = {
+ { 0xa4000004, 0, 8, /* IRR0 */
+ { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } },
+};
+
+static struct intc_sense_reg sense_registers[] __initdata = {
+ { 0xa4000010, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } },
+};
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh3-irq0123",
+ vectors_irq0123, NULL, NULL,
+ prio_registers, sense_registers, ack_registers);
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq45, "sh3-irq45",
+ vectors_irq45, NULL, NULL,
+ prio_registers, sense_registers, ack_registers);
+
+#define INTC_ICR1 0xa4000010UL
+#define INTC_ICR1_IRQLVL (1<<14)
+
+void __init plat_irq_setup_pins(int mode)
+{
+ if (mode == IRQ_MODE_IRQ) {
+ ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1);
+ register_intc_controller(&intc_desc_irq0123);
+ return;
+ }
+ BUG();
+}
+
+void __init plat_irq_setup_sh3(void)
+{
+ register_intc_controller(&intc_desc_irq45);
+}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index f581534cb732..6468ae86b944 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -37,7 +37,7 @@ enum {
};
static struct intc_vect vectors[] __initdata = {
- INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+ /* IRQ0->5 are handled in setup-sh3.c */
INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720),
INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
@@ -48,7 +48,7 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(ADC_ADI, 0x980),
INTC_VECT(USB_USI0, 0xa20), INTC_VECT(USB_USI1, 0xa40),
INTC_VECT(TPU0, 0xc00), INTC_VECT(TPU1, 0xc20),
- INTC_VECT(TPU3, 0xc80), INTC_VECT(TPU1, 0xca0),
+ INTC_VECT(TPU2, 0xc80), INTC_VECT(TPU3, 0xca0),
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
@@ -81,14 +81,6 @@ static struct intc_prio_reg prio_registers[] __initdata = {
static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups,
NULL, prio_registers, NULL);
-static struct intc_vect vectors_irq[] __initdata = {
- INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
- INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
-};
-
-static DECLARE_INTC_DESC(intc_desc_irq, "sh7705-irq", vectors_irq, NULL,
- NULL, prio_registers, NULL);
-
static struct plat_sci_port sci_platform_data[] = {
{
.mapbase = 0xa4410000,
@@ -159,16 +151,8 @@ static int __init sh7705_devices_setup(void)
}
__initcall(sh7705_devices_setup);
-void __init plat_irq_setup_pins(int mode)
-{
- if (mode == IRQ_MODE_IRQ) {
- register_intc_controller(&intc_desc_irq);
- return;
- }
- BUG();
-}
-
void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
+ plat_irq_setup_sh3();
}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
index d3733b13ea52..93c55e2ed952 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
@@ -52,7 +52,7 @@ static struct intc_vect vectors[] __initdata = {
#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
defined(CONFIG_CPU_SUBTYPE_SH7707) || \
defined(CONFIG_CPU_SUBTYPE_SH7709)
- INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+ /* IRQ0->5 are handled in setup-sh3.c */
INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
INTC_VECT(ADC_ADI, 0x980),
@@ -104,18 +104,6 @@ static struct intc_prio_reg prio_registers[] __initdata = {
static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups,
NULL, prio_registers, NULL);
-#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
- defined(CONFIG_CPU_SUBTYPE_SH7707) || \
- defined(CONFIG_CPU_SUBTYPE_SH7709)
-static struct intc_vect vectors_irq[] __initdata = {
- INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
- INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
-};
-
-static DECLARE_INTC_DESC(intc_desc_irq, "sh770x-irq", vectors_irq, NULL,
- NULL, prio_registers, NULL);
-#endif
-
static struct resource rtc_resources[] = {
[0] = {
.start = 0xfffffec0,
@@ -194,24 +182,12 @@ static int __init sh770x_devices_setup(void)
}
__initcall(sh770x_devices_setup);
-#define INTC_ICR1 0xa4000010UL
-#define INTC_ICR1_IRQLVL (1<<14)
-
-void __init plat_irq_setup_pins(int mode)
+void __init plat_irq_setup(void)
{
- if (mode == IRQ_MODE_IRQ) {
+ register_intc_controller(&intc_desc);
#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
defined(CONFIG_CPU_SUBTYPE_SH7707) || \
defined(CONFIG_CPU_SUBTYPE_SH7709)
- ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1);
- register_intc_controller(&intc_desc_irq);
- return;
+ plat_irq_setup_sh3();
#endif
- }
- BUG();
-}
-
-void __init plat_irq_setup(void)
-{
- register_intc_controller(&intc_desc);
}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 7406c9ad9259..77eee481de47 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -38,7 +38,7 @@ enum {
};
static struct intc_vect vectors[] __initdata = {
- INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+ /* IRQ0->5 are handled in setup-sh3.c */
INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
@@ -79,10 +79,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
{ 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } },
{ 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC1, SCIF0, SCIF1 } },
- { 0xa4080000, 0, 16, 4, /* IPRF */ { 0, DMAC2 } },
-#ifdef CONFIG_CPU_SUBTYPE_SH7710
- { 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC } },
-#endif
+ { 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC, DMAC2 } },
{ 0xa4080002, 0, 16, 4, /* IPRG */ { EDMAC0, EDMAC1, EDMAC2 } },
{ 0xa4080004, 0, 16, 4, /* IPRH */ { 0, 0, 0, SIOF0 } },
{ 0xa4080006, 0, 16, 4, /* IPRI */ { 0, 0, SIOF1 } },
@@ -91,14 +88,6 @@ static struct intc_prio_reg prio_registers[] __initdata = {
static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups,
NULL, prio_registers, NULL);
-static struct intc_vect vectors_irq[] __initdata = {
- INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
- INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
-};
-
-static DECLARE_INTC_DESC(intc_desc_irq, "sh7710-irq", vectors_irq, NULL,
- NULL, prio_registers, NULL);
-
static struct resource rtc_resources[] = {
[0] = {
.start = 0xa413fec0,
@@ -170,16 +159,8 @@ static int __init sh7710_devices_setup(void)
}
__initcall(sh7710_devices_setup);
-void __init plat_irq_setup_pins(int mode)
-{
- if (mode == IRQ_MODE_IRQ) {
- register_intc_controller(&intc_desc_irq);
- return;
- }
- BUG();
-}
-
void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
+ plat_irq_setup_sh3();
}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index 8028082527c5..f807a21b066c 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -19,10 +19,6 @@
#include <linux/serial_sci.h>
#include <asm/rtc.h>
-#define INTC_ICR1 0xA4140010UL
-#define INTC_ICR_IRLM 0x4000
-#define INTC_ICR_IRQ (~INTC_ICR_IRLM)
-
static struct resource rtc_resources[] = {
[0] = {
.start = 0xa413fec0,
@@ -170,6 +166,7 @@ enum {
};
static struct intc_vect vectors[] __initdata = {
+ /* IRQ0->5 are handled in setup-sh3.c */
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
INTC_VECT(TMU2, 0x440), INTC_VECT(RTC_ATI, 0x480),
INTC_VECT(RTC_PRI, 0x4a0), INTC_VECT(RTC_CUI, 0x4c0),
@@ -214,11 +211,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } },
{ 0xA4140016UL, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
{ 0xA4140018UL, 0, 16, 4, /* IPRD */ { USBF_SPD, TMU_SUNI, IRQ5, IRQ4 } },
-#if defined(CONFIG_CPU_SUBTYPE_SH7720)
{ 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, SSL } },
-#else
- { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, 0 } },
-#endif
{ 0xA4080000UL, 0, 16, 4, /* IPRF */ { ADC, DMAC2, USBFI, CMT } },
{ 0xA4080002UL, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, 0, 0 } },
{ 0xA4080004UL, 0, 16, 4, /* IPRH */ { PINT07, PINT815, TPU, IIC } },
@@ -229,32 +222,8 @@ static struct intc_prio_reg prio_registers[] __initdata = {
static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups,
NULL, prio_registers, NULL);
-static struct intc_sense_reg sense_registers[] __initdata = {
- { INTC_ICR1, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } },
-};
-
-static struct intc_vect vectors_irq[] __initdata = {
- INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
- INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
- INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
-};
-
-static DECLARE_INTC_DESC(intc_irq_desc, "sh7720-irq", vectors_irq,
- NULL, NULL, prio_registers, sense_registers);
-
-void __init plat_irq_setup_pins(int mode)
-{
- switch (mode) {
- case IRQ_MODE_IRQ:
- ctrl_outw(ctrl_inw(INTC_ICR1) & INTC_ICR_IRQ, INTC_ICR1);
- register_intc_controller(&intc_irq_desc);
- break;
- default:
- BUG();
- }
-}
-
void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
+ plat_irq_setup_sh3();
}
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
index 817f9939cda6..8020796139f1 100644
--- a/arch/sh/kernel/cpu/sh4/fpu.c
+++ b/arch/sh/kernel/cpu/sh4/fpu.c
@@ -16,6 +16,7 @@
#include <asm/cpu/fpu.h>
#include <asm/processor.h>
#include <asm/system.h>
+#include <asm/fpu.h>
/* The PR (precision) bit in the FP Status Register must be clear when
* an frchg instruction is executed, otherwise the instruction is undefined.
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 9e89984c4f1d..be4926969181 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -53,7 +53,7 @@ int __init detect_cpu_and_cache_system(void)
/*
* Setup some generic flags we can probe on SH-4A parts
*/
- if (((pvr >> 16) & 0xff) == 0x10) {
+ if (((pvr >> 24) & 0xff) == 0x10) {
if ((cvr & 0x10000000) == 0)
boot_cpu_data.flags |= CPU_HAS_DSP;
@@ -126,17 +126,23 @@ int __init detect_cpu_and_cache_system(void)
CPU_HAS_LLSC;
break;
case 0x3008:
- if (prr == 0xa0 || prr == 0xa1) {
- boot_cpu_data.type = CPU_SH7722;
- boot_cpu_data.icache.ways = 4;
- boot_cpu_data.dcache.ways = 4;
- boot_cpu_data.flags |= CPU_HAS_LLSC;
- }
- else if (prr == 0x70) {
+ boot_cpu_data.icache.ways = 4;
+ boot_cpu_data.dcache.ways = 4;
+ boot_cpu_data.flags |= CPU_HAS_LLSC;
+
+ switch (prr) {
+ case 0x50:
+ case 0x51:
+ boot_cpu_data.type = CPU_SH7723;
+ boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_L2_CACHE;
+ break;
+ case 0x70:
boot_cpu_data.type = CPU_SH7366;
- boot_cpu_data.icache.ways = 4;
- boot_cpu_data.dcache.ways = 4;
- boot_cpu_data.flags |= CPU_HAS_LLSC;
+ break;
+ case 0xa0:
+ case 0xa1:
+ boot_cpu_data.type = CPU_SH7722;
+ break;
}
break;
case 0x4000: /* 1st cut */
@@ -215,6 +221,12 @@ int __init detect_cpu_and_cache_system(void)
* SH-4A's have an optional PIPT L2.
*/
if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) {
+ /* Bug if we can't decode the L2 info */
+ BUG_ON(!(cvr & 0xf));
+
+ /* Silicon and specifications have clearly never met.. */
+ cvr ^= 0xf;
+
/*
* Size calculation is much more sensible
* than it is for the L1.
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index 5d890ac8e793..a880e7968750 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o
obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o
obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7723) += setup-sh7723.o
obj-$(CONFIG_CPU_SUBTYPE_SH7366) += setup-sh7366.o
obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o
@@ -22,6 +23,7 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o
clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
index 805535aa505e..27fa81bef6a0 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
@@ -26,7 +26,7 @@ static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18,
static void master_clk_init(struct clk *clk)
{
- clk->rate *= 36;
+ clk->rate *= pfc_divisors[ctrl_inl(FRQMR1) & 0x000f];
}
static struct clk_ops sh7785_master_clk_ops = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index b98b4bc93ec9..62ebccf18b3c 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -17,12 +17,11 @@
static struct resource usbf_resources[] = {
[0] = {
.name = "m66592_udc",
- .start = 0xA4480000,
- .end = 0xA44800FF,
+ .start = 0x04480000,
+ .end = 0x044800FF,
.flags = IORESOURCE_MEM,
},
[1] = {
- .name = "m66592_udc",
.start = 65,
.end = 65,
.flags = IORESOURCE_IRQ,
@@ -40,6 +39,26 @@ static struct platform_device usbf_device = {
.resource = usbf_resources,
};
+static struct resource iic_resources[] = {
+ [0] = {
+ .name = "IIC",
+ .start = 0x04470000,
+ .end = 0x04470017,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 96,
+ .end = 99,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device iic_device = {
+ .name = "i2c-sh_mobile",
+ .num_resources = ARRAY_SIZE(iic_resources),
+ .resource = iic_resources,
+};
+
static struct plat_sci_port sci_platform_data[] = {
{
.mapbase = 0xffe00000,
@@ -74,6 +93,7 @@ static struct platform_device sci_device = {
static struct platform_device *sh7722_devices[] __initdata = {
&usbf_device,
+ &iic_device,
&sci_device,
};
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
new file mode 100644
index 000000000000..a0470f2f5479
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -0,0 +1,335 @@
+/*
+ * SH7723 Setup
+ *
+ * Copyright (C) 2008 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/mm.h>
+#include <linux/serial_sci.h>
+#include <asm/mmzone.h>
+
+static struct plat_sci_port sci_platform_data[] = {
+ {
+ .mapbase = 0xffe00000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 80, 80, 80, 80 },
+ },{
+ .mapbase = 0xffe10000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 81, 81, 81, 81 },
+ },{
+ .mapbase = 0xffe20000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 82, 82, 82, 82 },
+ },{
+ .mapbase = 0xa4e30000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCI,
+ .irqs = { 56, 56, 56, 56 },
+ },{
+ .mapbase = 0xa4e40000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCI,
+ .irqs = { 88, 88, 88, 88 },
+ },{
+ .mapbase = 0xa4e50000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCI,
+ .irqs = { 109, 109, 109, 109 },
+ }, {
+ .flags = 0,
+ }
+};
+
+static struct platform_device sci_device = {
+ .name = "sh-sci",
+ .id = -1,
+ .dev = {
+ .platform_data = sci_platform_data,
+ },
+};
+
+static struct resource rtc_resources[] = {
+ [0] = {
+ .start = 0xa465fec0,
+ .end = 0xa465fec0 + 0x58 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ /* Period IRQ */
+ .start = 69,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* Carry IRQ */
+ .start = 70,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ /* Alarm IRQ */
+ .start = 68,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device rtc_device = {
+ .name = "sh-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
+};
+
+static struct resource sh7723_usb_host_resources[] = {
+ [0] = {
+ .name = "r8a66597_hcd",
+ .start = 0xa4d80000,
+ .end = 0xa4d800ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 65,
+ .end = 65,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sh7723_usb_host_device = {
+ .name = "r8a66597_hcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL, /* not use dma */
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(sh7723_usb_host_resources),
+ .resource = sh7723_usb_host_resources,
+};
+
+static struct platform_device *sh7723_devices[] __initdata = {
+ &sci_device,
+ &rtc_device,
+ &sh7723_usb_host_device,
+};
+
+static int __init sh7723_devices_setup(void)
+{
+ return platform_add_devices(sh7723_devices,
+ ARRAY_SIZE(sh7723_devices));
+}
+__initcall(sh7723_devices_setup);
+
+enum {
+ UNUSED=0,
+
+ /* interrupt sources */
+ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
+ HUDI,
+ DMAC1A_DEI0,DMAC1A_DEI1,DMAC1A_DEI2,DMAC1A_DEI3,
+ _2DG_TRI,_2DG_INI,_2DG_CEI,
+ DMAC0A_DEI0,DMAC0A_DEI1,DMAC0A_DEI2,DMAC0A_DEI3,
+ VIO_CEUI,VIO_BEUI,VIO_VEU2HI,VIO_VOUI,
+ SCIFA_SCIFA0,
+ VPU_VPUI,
+ TPU_TPUI,
+ ADC_ADI,
+ USB_USI0,
+ RTC_ATI,RTC_PRI,RTC_CUI,
+ DMAC1B_DEI4,DMAC1B_DEI5,DMAC1B_DADERR,
+ DMAC0B_DEI4,DMAC0B_DEI5,DMAC0B_DADERR,
+ KEYSC_KEYI,
+ SCIF_SCIF0,SCIF_SCIF1,SCIF_SCIF2,
+ MSIOF_MSIOFI0,MSIOF_MSIOFI1,
+ SCIFA_SCIFA1,
+ FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I,
+ I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI,
+ SDHI0_SDHII0,SDHI0_SDHII1,SDHI0_SDHII2,
+ CMT_CMTI,
+ TSIF_TSIFI,
+ SIU_SIUI,
+ SCIFA_SCIFA2,
+ TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2,
+ IRDA_IRDAI,
+ ATAPI_ATAPII,
+ SDHI1_SDHII0,SDHI1_SDHII1,SDHI1_SDHII2,
+ VEU2H1_VEU2HI,
+ LCDC_LCDCI,
+ TMU1_TUNI0,TMU1_TUNI1,TMU1_TUNI2,
+
+ /* interrupt groups */
+ DMAC1A, DMAC0A, VIO, DMAC0B, FLCTL, I2C, _2DG,
+ SDHI1, RTC, DMAC1B, SDHI0,
+};
+
+static struct intc_vect vectors[] __initdata = {
+ INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
+ INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
+ INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+ INTC_VECT(IRQ6, 0x6c0), INTC_VECT(IRQ7, 0x6e0),
+
+ INTC_VECT(DMAC1A_DEI0,0x700),
+ INTC_VECT(DMAC1A_DEI1,0x720),
+ INTC_VECT(DMAC1A_DEI2,0x740),
+ INTC_VECT(DMAC1A_DEI3,0x760),
+
+ INTC_VECT(_2DG_TRI, 0x780),
+ INTC_VECT(_2DG_INI, 0x7A0),
+ INTC_VECT(_2DG_CEI, 0x7C0),
+
+ INTC_VECT(DMAC0A_DEI0,0x800),
+ INTC_VECT(DMAC0A_DEI1,0x820),
+ INTC_VECT(DMAC0A_DEI2,0x840),
+ INTC_VECT(DMAC0A_DEI3,0x860),
+
+ INTC_VECT(VIO_CEUI,0x880),
+ INTC_VECT(VIO_BEUI,0x8A0),
+ INTC_VECT(VIO_VEU2HI,0x8C0),
+ INTC_VECT(VIO_VOUI,0x8E0),
+
+ INTC_VECT(SCIFA_SCIFA0,0x900),
+ INTC_VECT(VPU_VPUI,0x980),
+ INTC_VECT(TPU_TPUI,0x9A0),
+ INTC_VECT(ADC_ADI,0x9E0),
+ INTC_VECT(USB_USI0,0xA20),
+
+ INTC_VECT(RTC_ATI,0xA80),
+ INTC_VECT(RTC_PRI,0xAA0),
+ INTC_VECT(RTC_CUI,0xAC0),
+
+ INTC_VECT(DMAC1B_DEI4,0xB00),
+ INTC_VECT(DMAC1B_DEI5,0xB20),
+ INTC_VECT(DMAC1B_DADERR,0xB40),
+
+ INTC_VECT(DMAC0B_DEI4,0xB80),
+ INTC_VECT(DMAC0B_DEI5,0xBA0),
+ INTC_VECT(DMAC0B_DADERR,0xBC0),
+
+ INTC_VECT(KEYSC_KEYI,0xBE0),
+ INTC_VECT(SCIF_SCIF0,0xC00),
+ INTC_VECT(SCIF_SCIF1,0xC20),
+ INTC_VECT(SCIF_SCIF2,0xC40),
+ INTC_VECT(MSIOF_MSIOFI0,0xC80),
+ INTC_VECT(MSIOF_MSIOFI1,0xCA0),
+ INTC_VECT(SCIFA_SCIFA1,0xD00),
+
+ INTC_VECT(FLCTL_FLSTEI,0xD80),
+ INTC_VECT(FLCTL_FLTENDI,0xDA0),
+ INTC_VECT(FLCTL_FLTREQ0I,0xDC0),
+ INTC_VECT(FLCTL_FLTREQ1I,0xDE0),
+
+ INTC_VECT(I2C_ALI,0xE00),
+ INTC_VECT(I2C_TACKI,0xE20),
+ INTC_VECT(I2C_WAITI,0xE40),
+ INTC_VECT(I2C_DTEI,0xE60),
+
+ INTC_VECT(SDHI0_SDHII0,0xE80),
+ INTC_VECT(SDHI0_SDHII1,0xEA0),
+ INTC_VECT(SDHI0_SDHII2,0xEC0),
+
+ INTC_VECT(CMT_CMTI,0xF00),
+ INTC_VECT(TSIF_TSIFI,0xF20),
+ INTC_VECT(SIU_SIUI,0xF80),
+ INTC_VECT(SCIFA_SCIFA2,0xFA0),
+
+ INTC_VECT(TMU0_TUNI0,0x400),
+ INTC_VECT(TMU0_TUNI1,0x420),
+ INTC_VECT(TMU0_TUNI2,0x440),
+
+ INTC_VECT(IRDA_IRDAI,0x480),
+ INTC_VECT(ATAPI_ATAPII,0x4A0),
+
+ INTC_VECT(SDHI1_SDHII0,0x4E0),
+ INTC_VECT(SDHI1_SDHII1,0x500),
+ INTC_VECT(SDHI1_SDHII2,0x520),
+
+ INTC_VECT(VEU2H1_VEU2HI,0x560),
+ INTC_VECT(LCDC_LCDCI,0x580),
+
+ INTC_VECT(TMU1_TUNI0,0x920),
+ INTC_VECT(TMU1_TUNI1,0x940),
+ INTC_VECT(TMU1_TUNI2,0x960),
+
+};
+
+static struct intc_group groups[] __initdata = {
+ INTC_GROUP(DMAC1A,DMAC1A_DEI0,DMAC1A_DEI1,DMAC1A_DEI2,DMAC1A_DEI3),
+ INTC_GROUP(DMAC0A,DMAC0A_DEI0,DMAC0A_DEI1,DMAC0A_DEI2,DMAC0A_DEI3),
+ INTC_GROUP(VIO, VIO_CEUI,VIO_BEUI,VIO_VEU2HI,VIO_VOUI),
+ INTC_GROUP(DMAC0B, DMAC0B_DEI4,DMAC0B_DEI5,DMAC0B_DADERR),
+ INTC_GROUP(FLCTL,FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I),
+ INTC_GROUP(I2C,I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI),
+ INTC_GROUP(_2DG, _2DG_TRI,_2DG_INI,_2DG_CEI),
+ INTC_GROUP(SDHI1, SDHI1_SDHII0,SDHI1_SDHII1,SDHI1_SDHII2),
+ INTC_GROUP(RTC, RTC_ATI,RTC_PRI,RTC_CUI),
+ INTC_GROUP(DMAC1B, DMAC1B_DEI4,DMAC1B_DEI5,DMAC1B_DADERR),
+ INTC_GROUP(SDHI0,SDHI0_SDHII0,SDHI0_SDHII1,SDHI0_SDHII2),
+};
+
+static struct intc_mask_reg mask_registers[] __initdata = {
+ { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
+ { 0, TMU1_TUNI2,TMU1_TUNI1,TMU1_TUNI0,0,SDHI1_SDHII2,SDHI1_SDHII1,SDHI1_SDHII0} },
+ { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
+ { VIO_VOUI, VIO_VEU2HI,VIO_BEUI,VIO_CEUI,DMAC0A_DEI3,DMAC0A_DEI2,DMAC0A_DEI1,DMAC0A_DEI0 } },
+ { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */
+ { 0, 0, 0, VPU_VPUI,0,0,0,SCIFA_SCIFA0 } },
+ { 0xa408008c, 0xa40800cc, 8, /* IMR3 / IMCR3 */
+ { DMAC1A_DEI3,DMAC1A_DEI2,DMAC1A_DEI1,DMAC1A_DEI0,0,0,0,IRDA_IRDAI } },
+ { 0xa4080090, 0xa40800d0, 8, /* IMR4 / IMCR4 */
+ { 0,TMU0_TUNI2,TMU0_TUNI1,TMU0_TUNI0,VEU2H1_VEU2HI,0,0,LCDC_LCDCI } },
+ { 0xa4080094, 0xa40800d4, 8, /* IMR5 / IMCR5 */
+ { KEYSC_KEYI,DMAC0B_DADERR,DMAC0B_DEI5,DMAC0B_DEI4,0,SCIF_SCIF2,SCIF_SCIF1,SCIF_SCIF0 } },
+ { 0xa4080098, 0xa40800d8, 8, /* IMR6 / IMCR6 */
+ { 0,0,0,SCIFA_SCIFA1,ADC_ADI,0,MSIOF_MSIOFI1,MSIOF_MSIOFI0 } },
+ { 0xa408009c, 0xa40800dc, 8, /* IMR7 / IMCR7 */
+ { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI,
+ FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
+ { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
+ { 0,SDHI0_SDHII2,SDHI0_SDHII1,SDHI0_SDHII0,0,0,SCIFA_SCIFA2,SIU_SIUI } },
+ { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
+ { 0, 0, 0, CMT_CMTI, 0, 0, USB_USI0,0 } },
+ { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */
+ { 0, DMAC1B_DADERR,DMAC1B_DEI5,DMAC1B_DEI4,0,RTC_ATI,RTC_PRI,RTC_CUI } },
+ { 0xa40800ac, 0xa40800ec, 8, /* IMR11 / IMCR11 */
+ { 0,_2DG_CEI,_2DG_INI,_2DG_TRI,0,TPU_TPUI,0,TSIF_TSIFI } },
+ { 0xa40800b0, 0xa40800f0, 8, /* IMR12 / IMCR12 */
+ { 0,0,0,0,0,0,0,ATAPI_ATAPII } },
+ { 0xa4140044, 0xa4140064, 8, /* INTMSK00 / INTMSKCLR00 */
+ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static struct intc_prio_reg prio_registers[] __initdata = {
+ { 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2, IRDA_IRDAI } },
+ { 0xa4080004, 0, 16, 4, /* IPRB */ { VEU2H1_VEU2HI, LCDC_LCDCI, DMAC1A, 0} },
+ { 0xa4080008, 0, 16, 4, /* IPRC */ { TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2, 0} },
+ { 0xa408000c, 0, 16, 4, /* IPRD */ { } },
+ { 0xa4080010, 0, 16, 4, /* IPRE */ { DMAC0A, VIO, SCIFA_SCIFA0, VPU_VPUI } },
+ { 0xa4080014, 0, 16, 4, /* IPRF */ { KEYSC_KEYI, DMAC0B, USB_USI0, CMT_CMTI } },
+ { 0xa4080018, 0, 16, 4, /* IPRG */ { SCIF_SCIF0, SCIF_SCIF1, SCIF_SCIF2,0 } },
+ { 0xa408001c, 0, 16, 4, /* IPRH */ { MSIOF_MSIOFI0,MSIOF_MSIOFI1, FLCTL, I2C } },
+ { 0xa4080020, 0, 16, 4, /* IPRI */ { SCIFA_SCIFA1,0,TSIF_TSIFI,_2DG } },
+ { 0xa4080024, 0, 16, 4, /* IPRJ */ { ADC_ADI,0,SIU_SIUI,SDHI1 } },
+ { 0xa4080028, 0, 16, 4, /* IPRK */ { RTC,DMAC1B,0,SDHI0 } },
+ { 0xa408002c, 0, 16, 4, /* IPRL */ { SCIFA_SCIFA2,0,TPU_TPUI,ATAPI_ATAPII } },
+ { 0xa4140010, 0, 32, 4, /* INTPRI00 */
+ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static struct intc_sense_reg sense_registers[] __initdata = {
+ { 0xa414001c, 16, 2, /* ICR1 */
+ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static DECLARE_INTC_DESC(intc_desc, "sh7723", vectors, groups,
+ mask_registers, prio_registers, sense_registers);
+
+void __init plat_irq_setup(void)
+{
+ register_intc_controller(&intc_desc);
+}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
index 07c988dc9de6..f189a559462b 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
@@ -231,12 +231,6 @@ static struct intc_group groups[] __initdata = {
INTC_GROUP(GPIO, GPIO_CH0, GPIO_CH1, GPIO_CH2, GPIO_CH3),
};
-static struct intc_prio priorities[] __initdata = {
- INTC_PRIO(SCIF0, 3),
- INTC_PRIO(SCIF1, 3),
- INTC_PRIO(SCIF2, 3),
-};
-
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
{ 0, 0, 0, 0, 0, 0, GPIO, 0,
@@ -270,11 +264,10 @@ static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xffd400b4, 0, 32, 8, /* INT2PRI13 */ { 0, 0, STIF1, STIF0 } },
};
-static DECLARE_INTC_DESC(intc_desc, "sh7763", vectors, groups, priorities,
+static DECLARE_INTC_DESC(intc_desc, "sh7763", vectors, groups,
mask_registers, prio_registers, NULL);
/* Support for external interrupt pins in IRQ mode */
-
static struct intc_vect irq_vectors[] __initdata = {
INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
@@ -298,11 +291,11 @@ static struct intc_sense_reg irq_sense_registers[] __initdata = {
};
static DECLARE_INTC_DESC(intc_irq_desc, "sh7763-irq", irq_vectors,
- NULL, NULL, irq_mask_registers, irq_prio_registers,
- irq_sense_registers);
+ NULL, irq_mask_registers, irq_prio_registers,
+ irq_sense_registers);
-/* External interrupt pins in IRL mode */
+/* External interrupt pins in IRL mode */
static struct intc_vect irl_vectors[] __initdata = {
INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
@@ -332,10 +325,10 @@ static struct intc_mask_reg irl7654_mask_registers[] __initdata = {
};
static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7763-irl7654", irl_vectors,
- NULL, NULL, irl7654_mask_registers, NULL, NULL);
+ NULL, irl7654_mask_registers, NULL, NULL);
static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7763-irl3210", irl_vectors,
- NULL, NULL, irl3210_mask_registers, NULL, NULL);
+ NULL, irl3210_mask_registers, NULL, NULL);
#define INTC_ICR0 0xffd00000
#define INTC_INTMSK0 0xffd00044
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
index b9cec48b1808..b73578ee295d 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
@@ -1,7 +1,7 @@
/*
* SH7770 Setup
*
- * Copyright (C) 2006 Paul Mundt
+ * Copyright (C) 2006 - 2008 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -29,6 +29,41 @@ static struct plat_sci_port sci_platform_data[] = {
.type = PORT_SCIF,
.irqs = { 63, 63, 63, 63 },
}, {
+ .mapbase = 0xff926000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 64, 64, 64, 64 },
+ }, {
+ .mapbase = 0xff927000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 65, 65, 65, 65 },
+ }, {
+ .mapbase = 0xff928000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 66, 66, 66, 66 },
+ }, {
+ .mapbase = 0xff929000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 67, 67, 67, 67 },
+ }, {
+ .mapbase = 0xff92a000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 68, 68, 68, 68 },
+ }, {
+ .mapbase = 0xff92b000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 69, 69, 69, 69 },
+ }, {
+ .mapbase = 0xff92c000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 70, 70, 70, 70 },
+ }, {
.flags = 0,
}
};
diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S
index ba8750176d91..05372ed6c568 100644
--- a/arch/sh/kernel/cpu/sh5/entry.S
+++ b/arch/sh/kernel/cpu/sh5/entry.S
@@ -143,12 +143,22 @@ resvec_save_area:
trap_jtable:
.long do_exception_error /* 0x000 */
.long do_exception_error /* 0x020 */
+#ifdef CONFIG_MMU
.long tlb_miss_load /* 0x040 */
.long tlb_miss_store /* 0x060 */
+#else
+ .long do_exception_error
+ .long do_exception_error
+#endif
! ARTIFICIAL pseudo-EXPEVT setting
.long do_debug_interrupt /* 0x080 */
+#ifdef CONFIG_MMU
.long tlb_miss_load /* 0x0A0 */
.long tlb_miss_store /* 0x0C0 */
+#else
+ .long do_exception_error
+ .long do_exception_error
+#endif
.long do_address_error_load /* 0x0E0 */
.long do_address_error_store /* 0x100 */
#ifdef CONFIG_SH_FPU
@@ -185,10 +195,18 @@ trap_jtable:
.endr
.long do_IRQ /* 0xA00 */
.long do_IRQ /* 0xA20 */
+#ifdef CONFIG_MMU
.long itlb_miss_or_IRQ /* 0xA40 */
+#else
+ .long do_IRQ
+#endif
.long do_IRQ /* 0xA60 */
.long do_IRQ /* 0xA80 */
+#ifdef CONFIG_MMU
.long itlb_miss_or_IRQ /* 0xAA0 */
+#else
+ .long do_IRQ
+#endif
.long do_exception_error /* 0xAC0 */
.long do_address_error_exec /* 0xAE0 */
.rept 8
@@ -274,6 +292,7 @@ not_a_tlb_miss:
* Instead of '.space 1024-TEXT_SIZE' place the RESVEC
* block making sure the final alignment is correct.
*/
+#ifdef CONFIG_MMU
tlb_miss:
synco /* TAKum03020 (but probably a good idea anyway.) */
putcon SP, KCR1
@@ -377,6 +396,9 @@ fixup_to_invoke_general_handler:
getcon KCR1, SP
pta handle_exception, tr0
blink tr0, ZERO
+#else /* CONFIG_MMU */
+ .balign 256
+#endif
/* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE
DOES END UP AT VBR+0x600 */
@@ -1103,6 +1125,7 @@ restore_all:
* fpu_error_or_IRQ? is a helper to deflect to the right cause.
*
*/
+#ifdef CONFIG_MMU
tlb_miss_load:
or SP, ZERO, r2
or ZERO, ZERO, r3 /* Read */
@@ -1132,6 +1155,7 @@ call_do_page_fault:
movi do_page_fault, r6
ptabs r6, tr0
blink tr0, ZERO
+#endif /* CONFIG_MMU */
fpu_error_or_IRQA:
pta its_IRQ, tr0
@@ -1481,6 +1505,7 @@ poke_real_address_q:
ptabs LINK, tr0
blink tr0, r63
+#ifdef CONFIG_MMU
/*
* --- User Access Handling Section
*/
@@ -1604,6 +1629,7 @@ ___clear_user_exit:
ptabs LINK, tr0
blink tr0, ZERO
+#endif /* CONFIG_MMU */
/*
* int __strncpy_from_user(unsigned long __dest, unsigned long __src,
@@ -2014,9 +2040,11 @@ sa_default_restorer:
.global asm_uaccess_start /* Just a marker */
asm_uaccess_start:
+#ifdef CONFIG_MMU
.long ___copy_user1, ___copy_user_exit
.long ___copy_user2, ___copy_user_exit
.long ___clear_user1, ___clear_user_exit
+#endif
.long ___strncpy_from_user1, ___strncpy_from_user_exit
.long ___strnlen_user1, ___strnlen_user_exit
.long ___get_user_asm_b1, ___get_user_asm_b_exit
diff --git a/arch/sh/kernel/cpu/sh5/fpu.c b/arch/sh/kernel/cpu/sh5/fpu.c
index 30b76a94abf2..dd4f51ffb50e 100644
--- a/arch/sh/kernel/cpu/sh5/fpu.c
+++ b/arch/sh/kernel/cpu/sh5/fpu.c
@@ -17,6 +17,7 @@
#include <asm/processor.h>
#include <asm/user.h>
#include <asm/io.h>
+#include <asm/fpu.h>
/*
* Initially load the FPU with signalling NANS. This bit pattern
diff --git a/arch/sh/kernel/cpu/sh5/probe.c b/arch/sh/kernel/cpu/sh5/probe.c
index 31f8cb0f6374..92ad844b5c12 100644
--- a/arch/sh/kernel/cpu/sh5/probe.c
+++ b/arch/sh/kernel/cpu/sh5/probe.c
@@ -15,6 +15,7 @@
#include <linux/string.h>
#include <asm/processor.h>
#include <asm/cache.h>
+#include <asm/tlb.h>
int __init detect_cpu_and_cache_system(void)
{
@@ -67,5 +68,8 @@ int __init detect_cpu_and_cache_system(void)
set_bit(SH_CACHE_MODE_WB, &(boot_cpu_data.dcache.flags));
#endif
+ /* Setup some I/D TLB defaults */
+ sh64_tlb_init();
+
return 0;
}
diff --git a/arch/sh/kernel/dump_task.c b/arch/sh/kernel/dump_task.c
index 4a8a4083ff0b..1db7ce0f25d4 100644
--- a/arch/sh/kernel/dump_task.c
+++ b/arch/sh/kernel/dump_task.c
@@ -1,5 +1,6 @@
#include <linux/elfcore.h>
#include <linux/sched.h>
+#include <asm/fpu.h>
/*
* Capture the user space registers if the task is not running (in user space)
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
index 957f25611543..6b7d166694e2 100644
--- a/arch/sh/kernel/early_printk.c
+++ b/arch/sh/kernel/early_printk.c
@@ -141,7 +141,9 @@ static void scif_sercon_init(char *s)
*/
static void scif_sercon_init(char *s)
{
+ struct uart_port *port = &scif_port;
unsigned baud = DEFAULT_BAUD;
+ unsigned int status;
char *e;
if (*s == ',')
@@ -160,19 +162,25 @@ static void scif_sercon_init(char *s)
baud = DEFAULT_BAUD;
}
- ctrl_outw(0, scif_port.mapbase + 8);
- ctrl_outw(0, scif_port.mapbase);
+ do {
+ status = sci_in(port, SCxSR);
+ } while (!(status & SCxSR_TEND(port)));
+
+ sci_out(port, SCSCR, 0); /* TE=0, RE=0 */
+ sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
+ sci_out(port, SCSMR, 0);
/* Set baud rate */
- ctrl_outb((CONFIG_SH_PCLK_FREQ + 16 * baud) /
- (32 * baud) - 1, scif_port.mapbase + 4);
-
- ctrl_outw(12, scif_port.mapbase + 24);
- ctrl_outw(8, scif_port.mapbase + 24);
- ctrl_outw(0, scif_port.mapbase + 32);
- ctrl_outw(0x60, scif_port.mapbase + 16);
- ctrl_outw(0, scif_port.mapbase + 36);
- ctrl_outw(0x30, scif_port.mapbase + 8);
+ sci_out(port, SCBRR, (CONFIG_SH_PCLK_FREQ + 16 * baud) /
+ (32 * baud) - 1);
+ udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
+
+ sci_out(port, SCSPTR, 0);
+ sci_out(port, SCxSR, 0x60);
+ sci_out(port, SCLSR, 0);
+
+ sci_out(port, SCFCR, 0);
+ sci_out(port, SCSCR, 0x30); /* TE=1, RE=1 */
}
#endif /* defined(CONFIG_CPU_SUBTYPE_SH7720) */
#endif /* !defined(CONFIG_SH_STANDARD_BIOS) */
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 926b2e7b11c1..718bd2356b34 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -1,9 +1,6 @@
-/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $
- *
- * linux/arch/sh/entry.S
- *
+/*
* Copyright (C) 1999, 2000, 2002 Niibe Yutaka
- * Copyright (C) 2003 Paul Mundt
+ * Copyright (C) 2003 - 2008 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -262,6 +259,7 @@ __restore_all:
.align 2
syscall_badsys: ! Bad syscall number
+ get_current_thread_info r8, r0
mov #-ENOSYS, r0
bra resume_userspace
mov.l r0, @(OFF_R0,r15) ! Return value
@@ -281,7 +279,9 @@ debug_trap:
mov.l 1f, r8
add r0, r8
mov.l @r8, r8
- jmp @r8
+ jsr @r8
+ nop
+ bra __restore_all
nop
.align 2
diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index d67d7ed09f22..ae0a382a82eb 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -30,8 +30,8 @@ ENTRY(empty_zero_page)
.long 0 /* RAMDISK_FLAGS */
.long 0x0200 /* ORIG_ROOT_DEV */
.long 1 /* LOADER_TYPE */
- .long 0x00360000 /* INITRD_START */
- .long 0x000a0000 /* INITRD_SIZE */
+ .long 0x00000000 /* INITRD_START */
+ .long 0x00000000 /* INITRD_SIZE */
#ifdef CONFIG_32BIT
.long 0x53453f00 + 32 /* "SE?" = 32 bit */
#else
diff --git a/arch/sh/kernel/init_task.c b/arch/sh/kernel/init_task.c
index f9bcc606127e..b151a25cb14d 100644
--- a/arch/sh/kernel/init_task.c
+++ b/arch/sh/kernel/init_task.c
@@ -8,7 +8,6 @@
#include <asm/pgtable.h>
static struct fs_struct init_fs = INIT_FS;
-static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct pt_regs fake_swapper_regs;
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 9bf19b00696a..a2a99e487e33 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -200,8 +200,6 @@ void irq_ctx_exit(int cpu)
hardirq_ctx[cpu] = NULL;
}
-extern asmlinkage void __do_softirq(void);
-
asmlinkage void do_softirq(void)
{
unsigned long flags;
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
index d453c3a1c79f..bf8ac4c71640 100644
--- a/arch/sh/kernel/kgdb_stub.c
+++ b/arch/sh/kernel/kgdb_stub.c
@@ -274,8 +274,7 @@ static char *mem_to_hex(const char *mem, char *buf, const int count)
}
for (i = 0; i < count; i++) {
ch = *mem++;
- *buf++ = highhex(ch);
- *buf++ = lowhex(ch);
+ buf = pack_hex_byte(buf, ch);
}
*buf = 0;
return (buf);
@@ -330,14 +329,6 @@ static char *ebin_to_mem(const char *buf, char *mem, int count)
return mem;
}
-/* Pack a hex byte */
-static char *pack_hex_byte(char *pkt, int byte)
-{
- *pkt++ = hexchars[(byte >> 4) & 0xf];
- *pkt++ = hexchars[(byte & 0xf)];
- return pkt;
-}
-
/* Scan for the start char '$', read the packet and check the checksum */
static void get_packet(char *buffer, int buflen)
{
@@ -435,8 +426,8 @@ static void put_packet(char *buffer)
/* '#' Separator, put high and low components of checksum */
put_debug_char('#');
- put_debug_char(highhex(checksum));
- put_debug_char(lowhex(checksum));
+ put_debug_char(hex_asc_hi(checksum));
+ put_debug_char(hex_asc_lo(checksum));
}
while ((get_debug_char()) != '+'); /* While no ack */
}
@@ -658,8 +649,8 @@ static void undo_single_step(void)
static void send_signal_msg(const int signum)
{
out_buffer[0] = 'S';
- out_buffer[1] = highhex(signum);
- out_buffer[2] = lowhex(signum);
+ out_buffer[1] = hex_asc_hi(signum);
+ out_buffer[2] = hex_asc_lo(signum);
out_buffer[3] = 0;
put_packet(out_buffer);
}
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c
index b3d0a03b4c76..5482e65375a9 100644
--- a/arch/sh/kernel/module.c
+++ b/arch/sh/kernel/module.c
@@ -30,6 +30,7 @@
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
+#include <asm/unaligned.h>
void *module_alloc(unsigned long size)
{
@@ -56,34 +57,6 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
return 0;
}
-#ifdef CONFIG_SUPERH32
-#define COPY_UNALIGNED_WORD(sw, tw, align) \
-{ \
- void *__s = &(sw), *__t = &(tw); \
- unsigned short *__s2 = __s, *__t2 = __t; \
- unsigned char *__s1 = __s, *__t1 = __t; \
- switch ((align)) \
- { \
- case 0: \
- *(unsigned long *) __t = *(unsigned long *) __s; \
- break; \
- case 2: \
- *__t2++ = *__s2++; \
- *__t2 = *__s2; \
- break; \
- default: \
- *__t1++ = *__s1++; \
- *__t1++ = *__s1++; \
- *__t1++ = *__s1++; \
- *__t1 = *__s1; \
- break; \
- } \
-}
-#else
-/* One thing SHmedia doesn't screw up! */
-#define COPY_UNALIGNED_WORD(sw, tw, align) { (tw) = (sw); }
-#endif
-
int apply_relocate_add(Elf32_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
@@ -96,7 +69,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
Elf32_Addr relocation;
uint32_t *location;
uint32_t value;
- int align;
pr_debug("Applying relocate section %u to %u\n", relsec,
sechdrs[relsec].sh_info);
@@ -109,7 +81,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ ELF32_R_SYM(rel[i].r_info);
relocation = sym->st_value + rel[i].r_addend;
- align = (int)location & 3;
#ifdef CONFIG_SUPERH64
/* For text addresses, bit2 of the st_other field indicates
@@ -122,15 +93,15 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
switch (ELF32_R_TYPE(rel[i].r_info)) {
case R_SH_DIR32:
- COPY_UNALIGNED_WORD (*location, value, align);
+ value = get_unaligned(location);
value += relocation;
- COPY_UNALIGNED_WORD (value, *location, align);
+ put_unaligned(value, location);
break;
case R_SH_REL32:
relocation = (relocation - (Elf32_Addr) location);
- COPY_UNALIGNED_WORD (*location, value, align);
+ value = get_unaligned(location);
value += relocation;
- COPY_UNALIGNED_WORD (value, *location, align);
+ put_unaligned(value, location);
break;
case R_SH_IMM_LOW16:
*location = (*location & ~0x3fffc00) |
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 9ab1926b9d10..b98e37a1f54c 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -25,6 +25,7 @@
#include <asm/pgalloc.h>
#include <asm/system.h>
#include <asm/ubc.h>
+#include <asm/fpu.h>
static int hlt_counter;
int ubc_usercnt = 0;
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index 046999b1d1af..0283d8133075 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -28,6 +28,7 @@
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/mmu_context.h>
+#include <asm/fpu.h>
struct task_struct *last_task_used_math = NULL;
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index f6fbdfa6876d..d453c47dc522 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -33,6 +33,7 @@
#include <asm/system.h>
#include <asm/processor.h>
#include <asm/mmu_context.h>
+#include <asm/fpu.h>
/* This mask defines the bits of the SR which the user is not allowed to
change, which are everything except S, Q, M, PR, SZ, FR. */
diff --git a/arch/sh/kernel/semaphore.c b/arch/sh/kernel/semaphore.c
deleted file mode 100644
index 184119eeae56..000000000000
--- a/arch/sh/kernel/semaphore.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Just taken from alpha implementation.
- * This can't work well, perhaps.
- */
-/*
- * Generic semaphore code. Buyer beware. Do your own
- * specific changes in <asm/semaphore-helper.h>
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/init.h>
-#include <asm/semaphore.h>
-#include <asm/semaphore-helper.h>
-
-DEFINE_SPINLOCK(semaphore_wake_lock);
-
-/*
- * Semaphores are implemented using a two-way counter:
- * The "count" variable is decremented for each process
- * that tries to sleep, while the "waking" variable is
- * incremented when the "up()" code goes to wake up waiting
- * processes.
- *
- * Notably, the inline "up()" and "down()" functions can
- * efficiently test if they need to do any extra work (up
- * needs to do something only if count was negative before
- * the increment operation.
- *
- * waking_non_zero() (from asm/semaphore.h) must execute
- * atomically.
- *
- * When __up() is called, the count was negative before
- * incrementing it, and we need to wake up somebody.
- *
- * This routine adds one to the count of processes that need to
- * wake up and exit. ALL waiting processes actually wake up but
- * only the one that gets to the "waking" field first will gate
- * through and acquire the semaphore. The others will go back
- * to sleep.
- *
- * Note that these functions are only called when there is
- * contention on the lock, and as such all this is the
- * "non-critical" part of the whole semaphore business. The
- * critical part is the inline stuff in <asm/semaphore.h>
- * where we want to avoid any extra jumps and calls.
- */
-void __up(struct semaphore *sem)
-{
- wake_one_more(sem);
- wake_up(&sem->wait);
-}
-
-/*
- * Perform the "down" function. Return zero for semaphore acquired,
- * return negative for signalled out of the function.
- *
- * If called from __down, the return is ignored and the wait loop is
- * not interruptible. This means that a task waiting on a semaphore
- * using "down()" cannot be killed until someone does an "up()" on
- * the semaphore.
- *
- * If called from __down_interruptible, the return value gets checked
- * upon return. If the return value is negative then the task continues
- * with the negative value in the return register (it can be tested by
- * the caller).
- *
- * Either form may be used in conjunction with "up()".
- *
- */
-
-#define DOWN_VAR \
- struct task_struct *tsk = current; \
- wait_queue_t wait; \
- init_waitqueue_entry(&wait, tsk);
-
-#define DOWN_HEAD(task_state) \
- \
- \
- tsk->state = (task_state); \
- add_wait_queue(&sem->wait, &wait); \
- \
- /* \
- * Ok, we're set up. sem->count is known to be less than zero \
- * so we must wait. \
- * \
- * We can let go the lock for purposes of waiting. \
- * We re-acquire it after awaking so as to protect \
- * all semaphore operations. \
- * \
- * If "up()" is called before we call waking_non_zero() then \
- * we will catch it right away. If it is called later then \
- * we will have to go through a wakeup cycle to catch it. \
- * \
- * Multiple waiters contend for the semaphore lock to see \
- * who gets to gate through and who has to wait some more. \
- */ \
- for (;;) {
-
-#define DOWN_TAIL(task_state) \
- tsk->state = (task_state); \
- } \
- tsk->state = TASK_RUNNING; \
- remove_wait_queue(&sem->wait, &wait);
-
-void __sched __down(struct semaphore * sem)
-{
- DOWN_VAR
- DOWN_HEAD(TASK_UNINTERRUPTIBLE)
- if (waking_non_zero(sem))
- break;
- schedule();
- DOWN_TAIL(TASK_UNINTERRUPTIBLE)
-}
-
-int __sched __down_interruptible(struct semaphore * sem)
-{
- int ret = 0;
- DOWN_VAR
- DOWN_HEAD(TASK_INTERRUPTIBLE)
-
- ret = waking_non_zero_interruptible(sem, tsk);
- if (ret)
- {
- if (ret == 1)
- /* ret != 0 only if we get interrupted -arca */
- ret = 0;
- break;
- }
- schedule();
- DOWN_TAIL(TASK_INTERRUPTIBLE)
- return ret;
-}
-
-int __down_trylock(struct semaphore * sem)
-{
- return waking_non_zero_trylock(sem);
-}
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index ff4f54a47c07..bca2bbc575db 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -23,6 +23,8 @@
#include <linux/kexec.h>
#include <linux/module.h>
#include <linux/smp.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/page.h>
@@ -51,6 +53,7 @@ EXPORT_SYMBOL(cpu_data);
* sh_mv= on the command line, prior to .machvec.init teardown.
*/
struct sh_machine_vector sh_mv = { .mv_name = "generic", };
+EXPORT_SYMBOL(sh_mv);
#ifdef CONFIG_VT
struct screen_info screen_info;
@@ -74,11 +77,18 @@ static struct resource data_resource = {
.flags = IORESOURCE_BUSY | IORESOURCE_MEM,
};
+static struct resource bss_resource = {
+ .name = "Kernel bss",
+ .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
+};
+
unsigned long memory_start;
EXPORT_SYMBOL(memory_start);
unsigned long memory_end = 0;
EXPORT_SYMBOL(memory_end);
+static struct resource mem_resources[MAX_NUMNODES];
+
int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
static int __init early_parse_mem(char *p)
@@ -167,6 +177,40 @@ static inline void __init reserve_crashkernel(void)
{}
#endif
+void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
+ unsigned long end_pfn)
+{
+ struct resource *res = &mem_resources[nid];
+
+ WARN_ON(res->name); /* max one active range per node for now */
+
+ res->name = "System RAM";
+ res->start = start_pfn << PAGE_SHIFT;
+ res->end = (end_pfn << PAGE_SHIFT) - 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ if (request_resource(&iomem_resource, res)) {
+ pr_err("unable to request memory_resource 0x%lx 0x%lx\n",
+ start_pfn, end_pfn);
+ return;
+ }
+
+ /*
+ * We don't know which RAM region contains kernel data,
+ * so we try it repeatedly and let the resource manager
+ * test it.
+ */
+ request_resource(res, &code_resource);
+ request_resource(res, &data_resource);
+ request_resource(res, &bss_resource);
+
+#ifdef CONFIG_KEXEC
+ if (crashk_res.start != crashk_res.end)
+ request_resource(res, &crashk_res);
+#endif
+
+ add_active_range(nid, start_pfn, end_pfn);
+}
+
void __init setup_bootmem_allocator(unsigned long free_pfn)
{
unsigned long bootmap_size;
@@ -179,7 +223,7 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
bootmap_size = init_bootmem_node(NODE_DATA(0), free_pfn,
min_low_pfn, max_low_pfn);
- add_active_range(0, min_low_pfn, max_low_pfn);
+ __add_active_range(0, min_low_pfn, max_low_pfn);
register_bootmem_low_pages();
node_set_online(0);
@@ -248,6 +292,17 @@ void __init setup_arch(char **cmdline_p)
ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
+ printk(KERN_NOTICE "Boot params:\n"
+ "... MOUNT_ROOT_RDONLY - %08lx\n"
+ "... RAMDISK_FLAGS - %08lx\n"
+ "... ORIG_ROOT_DEV - %08lx\n"
+ "... LOADER_TYPE - %08lx\n"
+ "... INITRD_START - %08lx\n"
+ "... INITRD_SIZE - %08lx\n",
+ MOUNT_ROOT_RDONLY, RAMDISK_FLAGS,
+ ORIG_ROOT_DEV, LOADER_TYPE,
+ INITRD_START, INITRD_SIZE);
+
#ifdef CONFIG_BLK_DEV_RAM
rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
@@ -265,6 +320,8 @@ void __init setup_arch(char **cmdline_p)
code_resource.end = virt_to_phys(_etext)-1;
data_resource.start = virt_to_phys(_etext);
data_resource.end = virt_to_phys(_edata)-1;
+ bss_resource.start = virt_to_phys(__bss_start);
+ bss_resource.end = virt_to_phys(_ebss)-1;
memory_start = (unsigned long)__va(__MEMORY_START);
if (!memory_end)
@@ -333,6 +390,7 @@ static const char *cpu_name[] = {
[CPU_SH7343] = "SH7343", [CPU_SH7785] = "SH7785",
[CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3",
[CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103",
+ [CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723",
[CPU_SH7366] = "SH7366", [CPU_SH_NONE] = "Unknown"
};
@@ -443,3 +501,15 @@ const struct seq_operations cpuinfo_op = {
.show = show_cpuinfo,
};
#endif /* CONFIG_PROC_FS */
+
+struct dentry *sh_debugfs_root;
+
+static int __init sh_debugfs_init(void)
+{
+ sh_debugfs_root = debugfs_create_dir("sh", NULL);
+ if (IS_ERR(sh_debugfs_root))
+ return PTR_ERR(sh_debugfs_root);
+
+ return 0;
+}
+arch_initcall(sh_debugfs_init);
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index d80de3903271..8f916536719c 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -9,7 +9,6 @@
#include <linux/pci.h>
#include <linux/irq.h>
#include <asm/sections.h>
-#include <asm/semaphore.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/checksum.h>
@@ -21,8 +20,6 @@
extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
extern struct hw_interrupt_type no_irq_type;
-EXPORT_SYMBOL(sh_mv);
-
/* platform dependent support */
EXPORT_SYMBOL(dump_fpu);
EXPORT_SYMBOL(kernel_thread);
@@ -48,12 +45,6 @@ EXPORT_SYMBOL(__copy_user);
EXPORT_SYMBOL(get_vm_area);
#endif
-/* semaphore exports */
-EXPORT_SYMBOL(__up);
-EXPORT_SYMBOL(__down);
-EXPORT_SYMBOL(__down_interruptible);
-EXPORT_SYMBOL(__down_trylock);
-
EXPORT_SYMBOL(__udelay);
EXPORT_SYMBOL(__ndelay);
EXPORT_SYMBOL(__const_udelay);
@@ -149,3 +140,4 @@ EXPORT_SYMBOL(clear_page);
EXPORT_SYMBOL(copy_page);
EXPORT_SYMBOL(__clear_user);
EXPORT_SYMBOL(_ebss);
+EXPORT_SYMBOL(empty_zero_page);
diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c
index dd38a683de65..9324d32adacc 100644
--- a/arch/sh/kernel/sh_ksyms_64.c
+++ b/arch/sh/kernel/sh_ksyms_64.c
@@ -16,7 +16,7 @@
#include <linux/in6.h>
#include <linux/interrupt.h>
#include <linux/screen_info.h>
-#include <asm/semaphore.h>
+#include <asm/cacheflush.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/checksum.h>
@@ -30,27 +30,50 @@ extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
EXPORT_SYMBOL(dump_fpu);
EXPORT_SYMBOL(kernel_thread);
+#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU)
+EXPORT_SYMBOL(clear_user_page);
+#endif
+
+#ifndef CONFIG_CACHE_OFF
+EXPORT_SYMBOL(flush_dcache_page);
+#endif
+
/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial);
EXPORT_SYMBOL(csum_partial_copy_nocheck);
+#ifdef CONFIG_IPV6
+EXPORT_SYMBOL(csum_ipv6_magic);
+#endif
#ifdef CONFIG_VT
EXPORT_SYMBOL(screen_info);
#endif
-EXPORT_SYMBOL(__down);
-EXPORT_SYMBOL(__down_trylock);
-EXPORT_SYMBOL(__up);
+EXPORT_SYMBOL(__put_user_asm_b);
+EXPORT_SYMBOL(__put_user_asm_w);
EXPORT_SYMBOL(__put_user_asm_l);
+EXPORT_SYMBOL(__put_user_asm_q);
+EXPORT_SYMBOL(__get_user_asm_b);
+EXPORT_SYMBOL(__get_user_asm_w);
EXPORT_SYMBOL(__get_user_asm_l);
+EXPORT_SYMBOL(__get_user_asm_q);
+EXPORT_SYMBOL(__strnlen_user);
+EXPORT_SYMBOL(__strncpy_from_user);
+EXPORT_SYMBOL(clear_page);
+EXPORT_SYMBOL(__clear_user);
EXPORT_SYMBOL(copy_page);
EXPORT_SYMBOL(__copy_user);
+EXPORT_SYMBOL(empty_zero_page);
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(__udelay);
EXPORT_SYMBOL(__ndelay);
+EXPORT_SYMBOL(__const_udelay);
/* Ugh. These come in from libgcc.a at link time. */
#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name)
DECLARE_EXPORT(__sdivsi3);
+DECLARE_EXPORT(__sdivsi3_2);
DECLARE_EXPORT(__muldi3);
DECLARE_EXPORT(__udivsi3);
+DECLARE_EXPORT(__div_table);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index f6b5fbfe75c4..f311551d9a05 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -29,6 +29,7 @@
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
+#include <asm/fpu.h>
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 80bde19d445b..552eb810cd85 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -26,6 +26,7 @@
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
+#include <asm/fpu.h>
#define REG_RET 9
#define REG_ARG1 2
diff --git a/arch/sh/kernel/sys_sh64.c b/arch/sh/kernel/sys_sh64.c
index 578004d71e02..91fb8445a5a0 100644
--- a/arch/sh/kernel/sys_sh64.c
+++ b/arch/sh/kernel/sys_sh64.c
@@ -31,23 +31,6 @@
#include <asm/unistd.h>
/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way Unix traditionally does this, though.
- */
-asmlinkage int sys_pipe(unsigned long * fildes)
-{
- int fd[2];
- int error;
-
- error = do_pipe(fd);
- if (!error) {
- if (copy_to_user(fildes, fd, 2*sizeof(int)))
- error = -EFAULT;
- }
- return error;
-}
-
-/*
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
diff --git a/arch/sh/kernel/time_64.c b/arch/sh/kernel/time_64.c
index 898977ee2030..022a55f1c1d4 100644
--- a/arch/sh/kernel/time_64.c
+++ b/arch/sh/kernel/time_64.c
@@ -172,6 +172,7 @@ void do_gettimeofday(struct timeval *tv)
tv->tv_sec = sec;
tv->tv_usec = usec;
}
+EXPORT_SYMBOL(do_gettimeofday);
int do_settimeofday(struct timespec *tv)
{
@@ -240,7 +241,7 @@ static inline void do_timer_interrupt(void)
* the irq version of write_lock because as just said we have irq
* locally disabled. -arca
*/
- write_lock(&xtime_lock);
+ write_seqlock(&xtime_lock);
asm ("getcon cr62, %0" : "=r" (current_ctc));
ctc_last_interrupt = (unsigned long) current_ctc;
@@ -266,7 +267,7 @@ static inline void do_timer_interrupt(void)
/* do it again in 60 s */
last_rtc_update = xtime.tv_sec - 600;
}
- write_unlock(&xtime_lock);
+ write_sequnlock(&xtime_lock);
#ifndef CONFIG_SMP
update_process_times(user_mode(get_irq_regs()));
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index a3bdc68ef02c..438f1ebcc453 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -4,6 +4,7 @@
#include <linux/kdebug.h>
#include <linux/signal.h>
#include <linux/sched.h>
+#include <linux/uaccess.h>
#include <asm/system.h>
#ifdef CONFIG_BUG
@@ -21,7 +22,14 @@ static void handle_BUG(struct pt_regs *regs)
int is_valid_bugaddr(unsigned long addr)
{
- return addr >= PAGE_OFFSET;
+ unsigned short opcode;
+
+ if (addr < PAGE_OFFSET)
+ return 0;
+ if (probe_kernel_address((u16 *)addr, opcode))
+ return 0;
+
+ return opcode == TRAPA_BUG_OPCODE;
}
#endif
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index baa4fa368dce..e08b3bfeb656 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -25,6 +25,7 @@
#include <linux/limits.h>
#include <asm/system.h>
#include <asm/uaccess.h>
+#include <asm/fpu.h>
#ifdef CONFIG_SH_KGDB
#include <asm/kgdb.h>
diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c
index 1b58a7499087..a85831cbf18b 100644
--- a/arch/sh/kernel/traps_64.c
+++ b/arch/sh/kernel/traps_64.c
@@ -30,6 +30,7 @@
#include <asm/atomic.h>
#include <asm/processor.h>
#include <asm/pgtable.h>
+#include <asm/fpu.h>
#undef DEBUG_EXCEPTION
#ifdef DEBUG_EXCEPTION