summaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/Makefile35
-rw-r--r--arch/sh/kernel/cf-enabler.c24
-rw-r--r--arch/sh/kernel/entry.S15
-rw-r--r--arch/sh/kernel/io.c202
-rw-r--r--arch/sh/kernel/io_generic.c119
-rw-r--r--arch/sh/kernel/io_hd64461.c59
-rw-r--r--arch/sh/kernel/io_se.c62
-rw-r--r--arch/sh/kernel/io_unknown.c47
-rw-r--r--arch/sh/kernel/irq.c29
-rw-r--r--arch/sh/kernel/irq_imask.c5
-rw-r--r--arch/sh/kernel/irq_ipr.c75
-rw-r--r--arch/sh/kernel/led_se.c67
-rw-r--r--arch/sh/kernel/mach_hp600.c63
-rw-r--r--arch/sh/kernel/mach_se.c80
-rw-r--r--arch/sh/kernel/mach_unknown.c68
-rw-r--r--arch/sh/kernel/pci-sh.c19
-rw-r--r--arch/sh/kernel/semaphore.c2
-rw-r--r--arch/sh/kernel/setup.c134
-rw-r--r--arch/sh/kernel/setup_cqreek.c224
-rw-r--r--arch/sh/kernel/setup_hd64461.c19
-rw-r--r--arch/sh/kernel/setup_se.c51
-rw-r--r--arch/sh/kernel/sh_bios.c2
-rw-r--r--arch/sh/kernel/signal.c7
-rw-r--r--arch/sh/kernel/time.c16
24 files changed, 1252 insertions, 172 deletions
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 7b3852295..c9de70daf 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -11,8 +11,8 @@
O_TARGET := kernel.o
O_OBJS := process.o signal.o entry.o traps.o irq.o irq_ipr.o \
- ptrace.o setup.o time.o sys_sh.o semaphore.o pci-sh.o \
- irq_imask.o
+ ptrace.o setup.o time.o sys_sh.o semaphore.o \
+ irq_imask.o io.o
OX_OBJS := sh_ksyms.o
MX_OBJS :=
@@ -21,26 +21,45 @@ O_OBJS += cf-enabler.o
endif
ifdef CONFIG_SH_GENERIC
+
+O_OBJS += mach_se.o setup_se.o setup_cqreek.o io_se.o led_se.o \
+ mach_hp600.o io_hd64461.o \
+ mach_unknown.o io_unknown.o \
+ io_generic.o
+
+else
+
+ifdef CONFIG_SH_HP600
+O_OBJS += mach_hp600.o io_hd64461.o io_generic.o
+endif
+
+ifdef CONFIG_SH_OVERDRIVE
O_OBJS += io_generic.o
endif
ifdef CONFIG_SH_SOLUTION_ENGINE
-O_OBJS += setup_se.o io_se.o
+O_OBJS += mach_se.o setup_se.o io_se.o io_generic.o led_se.o
endif
-ifdef CONFIG_SH_OVERDRIVE
-O_OBJS += setup_od.o io_generic.o
+ifdef CONFIG_SH_CQREEK
+O_OBJS += setup_cqreek.o
+endif
+
+ifdef CONFIG_SH_UNKNOWN
+O_OBJS += mach_unknown.o io_unknown.o io_generic.o
endif
-ifdef CONFIG_SH_HP600
-O_OBJS += io_hd64461.o
endif
ifdef CONFIG_CPU_SH4
O_OBJS += fpu.o
endif
-ifdef CONFIG_HD64461
+ifdef CONFIG_PCI
+O_OBJS += pci-sh.o
+endif
+
+ifneq ($(CONFIG_SH_GENERIC)$(CONFIG_HD64461),)
O_OBJS += setup_hd64461.o
endif
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
index 3727c7264..c446a1151 100644
--- a/arch/sh/kernel/cf-enabler.c
+++ b/arch/sh/kernel/cf-enabler.c
@@ -14,15 +14,18 @@
#include <asm/io.h>
#include <asm/irq.h>
-#ifdef CONFIG_SH_SOLUTION_ENGINE
#include <asm/hitachi_se.h>
+
+
/*
+ * SolutionEngine
+ *
* 0xB8400000 : Common Memory
* 0xB8500000 : Attribute
* 0xB8600000 : I/O
*/
-int __init cf_init(void)
+static int __init cf_init_se(void)
{
if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0)
return 0; /* Not detected */
@@ -68,11 +71,15 @@ int __init cf_init(void)
ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200);
return 0;
}
-#else /* then generic system type */
+
#define CF_CIS_BASE 0xb8000000
/*
* You can connect Compact Flash directly to the bus of SuperH.
* This is the enabler for that.
+ *
+ * SIM: How generic is this really? It looks pretty board, or at
+ * least SH sub-type, specific to me.
+ * I know it doesn't work on the Overdrive!
*/
/*
@@ -81,7 +88,7 @@ int __init cf_init(void)
* 0xBA000000 : I/O
*/
-int __init cf_init(void)
+static int __init cf_init_default(void)
{
/* Enable the card, and set the level interrupt */
ctrl_outw(0x0042, CF_CIS_BASE+0x0200);
@@ -89,6 +96,13 @@ int __init cf_init(void)
disable_irq(14);
return 0;
}
-#endif
+
+int __init cf_init(void)
+{
+ if (MACH_SE) {
+ return cf_init_se();
+ }
+ return cf_init_default();
+}
__initcall (cf_init);
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index 450d49824..4e57175e7 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -62,7 +62,7 @@ ENOSYS = 38
#if defined(__sh3__)
TRA = 0xffffffd0
EXPEVT = 0xffffffd4
-#ifdef CONFIG_CPU_SUBTYPE_SH7709
+#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
INTEVT = 0xa4000000 ! INTEVTE2(0xa4000000)
#else
INTEVT = 0xffffffd8
@@ -182,7 +182,7 @@ tlb_protection_violation_store:
1: .long SYMBOL_NAME(do_page_fault)
2: .long MMU_TEA
-#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
.align 2
/* Unwind the stack and jmp to the debug entry */
debug_kernel:
@@ -219,12 +219,12 @@ debug_kernel:
ldc $k1, $ssr
.align 2
1: .long 0x300000f0
-2: .long 0xa0000100
+2: .long CONFIG_GDB_STUB_VBR + 0x100
#endif
.align 2
debug_trap:
-#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
mov #SR, $r0
mov.l @($r0,$r15), $r0 ! get status register
shll $r0
@@ -829,7 +829,7 @@ ENTRY(interrupt_table)
.long SYMBOL_NAME(do_IRQ) ! rovi
.long SYMBOL_NAME(do_IRQ)
.long SYMBOL_NAME(do_IRQ)
-#if defined(CONFIG_CPU_SUBTYPE_SH7709)
+#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
.long SYMBOL_NAME(do_IRQ) ! 32 IRQ irq0
.long SYMBOL_NAME(do_IRQ) ! 33 irq1
.long SYMBOL_NAME(do_IRQ) ! 34 irq2
@@ -859,6 +859,11 @@ ENTRY(interrupt_table)
.long SYMBOL_NAME(do_IRQ) ! 58 bri2
.long SYMBOL_NAME(do_IRQ) ! 59 txi2
.long SYMBOL_NAME(do_IRQ) ! 60 ADC adi
+#if defined(CONFIG_CPU_SUBTYPE_SH7707)
+ .long SYMBOL_NAME(do_IRQ) ! 61 LCDC lcdi
+ .long SYMBOL_NAME(do_IRQ) ! 62 PCC pcc0i
+ .long SYMBOL_NAME(do_IRQ) ! 63 pcc1i
+#endif
#elif defined(__SH4__)
.long SYMBOL_NAME(do_IRQ) ! Hitachi UDI
.long SYMBOL_NAME(do_IRQ) ! GPIO
diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c
new file mode 100644
index 000000000..27f250f9f
--- /dev/null
+++ b/arch/sh/kernel/io.c
@@ -0,0 +1,202 @@
+/*
+ * linux/arch/sh/kernel/io_generic.c
+ *
+ * Copyright (C) 2000 Stuart Menefy
+ *
+ * Provide real functions which expand to whatever the header file defined.
+ * Also definitions of machine independant IO functions.
+ */
+
+#include <linux/config.h>
+#include <asm/io.h>
+
+unsigned int _inb(unsigned long port)
+{
+ return __inb(port);
+}
+
+unsigned int _inw(unsigned long port)
+{
+ return __inw(port);
+}
+
+unsigned int _inl(unsigned long port)
+{
+ return __inl(port);
+}
+
+void _outb(unsigned char b, unsigned long port)
+{
+ __outb(b, port);
+}
+
+void _outw(unsigned short b, unsigned long port)
+{
+ __outw(b, port);
+}
+
+void _outl(unsigned int b, unsigned long port)
+{
+ __outl(b, port);
+}
+
+unsigned int _inb_p(unsigned long port)
+{
+ return __inb_p(port);
+}
+
+unsigned int _inw_p(unsigned long port)
+{
+ return __inw_p(port);
+}
+
+void _outb_p(unsigned char b, unsigned long port)
+{
+ __outb_p(b, port);
+}
+
+void _outw_p(unsigned short b, unsigned long port)
+{
+ __outw_p(b, port);
+}
+
+void _insb(unsigned long port, void *buffer, unsigned long count)
+{
+ return __insb(port, buffer, count);
+}
+
+void _insw(unsigned long port, void *buffer, unsigned long count)
+{
+ __insw(port, buffer, count);
+}
+
+void _insl(unsigned long port, void *buffer, unsigned long count)
+{
+ __insl(port, buffer, count);
+}
+
+void _outsb(unsigned long port, const void *buffer, unsigned long count)
+{
+ __outsb(port, buffer, count);
+}
+
+void _outsw(unsigned long port, const void *buffer, unsigned long count)
+{
+ __outsw(port, buffer, count);
+}
+
+void _outsl(unsigned long port, const void *buffer, unsigned long count)
+{
+ __outsl(port, buffer, count);
+
+}
+
+unsigned long ___raw_readb(unsigned long addr)
+{
+ return __readb(addr);
+}
+
+unsigned long ___raw_readw(unsigned long addr)
+{
+ return __readw(addr);
+}
+
+unsigned long ___raw_readl(unsigned long addr)
+{
+ return __readl(addr);
+}
+
+unsigned long _readb(unsigned long addr)
+{
+ unsigned long r = __readb(addr);
+ mb();
+ return r;
+}
+
+unsigned long _readw(unsigned long addr)
+{
+ unsigned long r = __readw(addr);
+ mb();
+ return r;
+}
+
+unsigned long _readl(unsigned long addr)
+{
+ unsigned long r = __readl(addr);
+ mb();
+ return r;
+}
+
+void ___raw_writeb(unsigned char b, unsigned long addr)
+{
+ __writeb(b, addr);
+}
+
+void ___raw_writew(unsigned short b, unsigned long addr)
+{
+ __writew(b, addr);
+}
+
+void ___raw_writel(unsigned int b, unsigned long addr)
+{
+ __writel(b, addr);
+}
+
+void _writeb(unsigned char b, unsigned long addr)
+{
+ __writeb(b, addr);
+ mb();
+}
+
+void _writew(unsigned short b, unsigned long addr)
+{
+ __writew(b, addr);
+ mb();
+}
+
+void _writel(unsigned int b, unsigned long addr)
+{
+ __writel(b, addr);
+ mb();
+}
+
+/*
+ * Copy data from IO memory space to "real" memory space.
+ * This needs to be optimized.
+ */
+void memcpy_fromio(void * to, unsigned long from, unsigned long count)
+{
+ while (count) {
+ count--;
+ *(char *) to = readb(from);
+ ((char *) to)++;
+ from++;
+ }
+}
+
+/*
+ * Copy data from "real" memory space to IO memory space.
+ * This needs to be optimized.
+ */
+void memcpy_toio(unsigned long to, const void * from, unsigned long count)
+{
+ while (count) {
+ count--;
+ writeb(*(char *) from, to);
+ ((char *) from)++;
+ to++;
+ }
+}
+
+/*
+ * "memset" on IO memory space.
+ * This needs to be optimized.
+ */
+void memset_io(unsigned long dst, int c, unsigned long count)
+{
+ while (count) {
+ count--;
+ writeb(c, dst);
+ dst++;
+ }
+}
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index 1faa01ce3..9e5793450 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -4,7 +4,8 @@
*
* Copyright (C) 2000 Niibe Yutaka
*
- * Generic I/O routine.
+ * Generic I/O routine. These can be used where a machine specific version
+ * is not required.
*
* 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
@@ -14,6 +15,7 @@
#include <linux/config.h>
#include <asm/io.h>
+#include <asm/machvec.h>
#if defined(__sh3__)
/* I'm not sure SH7709 has this kind of bug */
@@ -21,19 +23,31 @@
#define DUMMY_READ_AREA6 0xba000000
#endif
-#define PORT2ADDR(x) (CONFIG_IOPORT_START+(x))
+#define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
+
+unsigned long generic_io_base;
static inline void delay(void)
{
ctrl_inw(0xa0000000);
}
-unsigned long inb(unsigned int port)
+unsigned long generic_inb(unsigned int port)
{
return *(volatile unsigned char*)PORT2ADDR(port);
}
-unsigned long inb_p(unsigned int port)
+unsigned long generic_inw(unsigned int port)
+{
+ return *(volatile unsigned short*)PORT2ADDR(port);
+}
+
+unsigned long generic_inl(unsigned int port)
+{
+ return *(volatile unsigned long*)PORT2ADDR(port);
+}
+
+unsigned long generic_inb_p(unsigned int port)
{
unsigned long v = *(volatile unsigned char*)PORT2ADDR(port);
@@ -41,23 +55,29 @@ unsigned long inb_p(unsigned int port)
return v;
}
-unsigned long inw(unsigned int port)
+unsigned long generic_inw_p(unsigned int port)
{
- return *(volatile unsigned short*)PORT2ADDR(port);
+ unsigned long v = *(volatile unsigned short*)PORT2ADDR(port);
+
+ delay();
+ return v;
}
-unsigned long inl(unsigned int port)
+unsigned long generic_inl_p(unsigned int port)
{
- return *(volatile unsigned long*)PORT2ADDR(port);
+ unsigned long v = *(volatile unsigned long*)PORT2ADDR(port);
+
+ delay();
+ return v;
}
-void insb(unsigned int port, void *buffer, unsigned long count)
+void generic_insb(unsigned int port, void *buffer, unsigned long count)
{
unsigned char *buf=buffer;
while(count--) *buf++=inb(port);
}
-void insw(unsigned int port, void *buffer, unsigned long count)
+void generic_insw(unsigned int port, void *buffer, unsigned long count)
{
unsigned short *buf=buffer;
while(count--) *buf++=inw(port);
@@ -66,7 +86,7 @@ void insw(unsigned int port, void *buffer, unsigned long count)
#endif
}
-void insl(unsigned int port, void *buffer, unsigned long count)
+void generic_insl(unsigned int port, void *buffer, unsigned long count)
{
unsigned long *buf=buffer;
while(count--) *buf++=inl(port);
@@ -75,34 +95,46 @@ void insl(unsigned int port, void *buffer, unsigned long count)
#endif
}
-void outb(unsigned long b, unsigned int port)
+void generic_outb(unsigned long b, unsigned int port)
{
*(volatile unsigned char*)PORT2ADDR(port) = b;
}
-void outb_p(unsigned long b, unsigned int port)
+void generic_outw(unsigned long b, unsigned int port)
+{
+ *(volatile unsigned short*)PORT2ADDR(port) = b;
+}
+
+void generic_outl(unsigned long b, unsigned int port)
+{
+ *(volatile unsigned long*)PORT2ADDR(port) = b;
+}
+
+void generic_outb_p(unsigned long b, unsigned int port)
{
*(volatile unsigned char*)PORT2ADDR(port) = b;
delay();
}
-void outw(unsigned long b, unsigned int port)
+void generic_outw_p(unsigned long b, unsigned int port)
{
*(volatile unsigned short*)PORT2ADDR(port) = b;
+ delay();
}
-void outl(unsigned long b, unsigned int port)
+void generic_outl_p(unsigned long b, unsigned int port)
{
- *(volatile unsigned long*)PORT2ADDR(port) = b;
+ *(volatile unsigned long*)PORT2ADDR(port) = b;
+ delay();
}
-void outsb(unsigned int port, const void *buffer, unsigned long count)
+void generic_outsb(unsigned int port, const void *buffer, unsigned long count)
{
const unsigned char *buf=buffer;
while(count--) outb(*buf++, port);
}
-void outsw(unsigned int port, const void *buffer, unsigned long count)
+void generic_outsw(unsigned int port, const void *buffer, unsigned long count)
{
const unsigned short *buf=buffer;
while(count--) outw(*buf++, port);
@@ -111,7 +143,7 @@ void outsw(unsigned int port, const void *buffer, unsigned long count)
#endif
}
-void outsl(unsigned int port, const void *buffer, unsigned long count)
+void generic_outsl(unsigned int port, const void *buffer, unsigned long count)
{
const unsigned long *buf=buffer;
while(count--) outl(*buf++, port);
@@ -119,3 +151,52 @@ void outsl(unsigned int port, const void *buffer, unsigned long count)
ctrl_inb (DUMMY_READ_AREA6);
#endif
}
+
+unsigned long generic_readb(unsigned long addr)
+{
+ return *(volatile unsigned char*)addr;
+}
+
+unsigned long generic_readw(unsigned long addr)
+{
+ return *(volatile unsigned short*)addr;
+}
+
+unsigned long generic_readl(unsigned long addr)
+{
+ return *(volatile unsigned long*)addr;
+}
+
+void generic_writeb(unsigned char b, unsigned long addr)
+{
+ *(volatile unsigned char*)addr = b;
+}
+
+void generic_writew(unsigned short b, unsigned long addr)
+{
+ *(volatile unsigned short*)addr = b;
+}
+
+void generic_writel(unsigned int b, unsigned long addr)
+{
+ *(volatile unsigned long*)addr = b;
+}
+
+void * generic_ioremap(unsigned long offset, unsigned long size)
+{
+ return (void *) P2SEGADDR(offset);
+}
+
+void * generic_ioremap_nocache (unsigned long offset, unsigned long size)
+{
+ return (void *) P2SEGADDR(offset);
+}
+
+void generic_iounmap(void *addr)
+{
+}
+
+unsigned long generic_isa_port2addr(unsigned long offset)
+{
+ return offset + generic_io_base;
+}
diff --git a/arch/sh/kernel/io_hd64461.c b/arch/sh/kernel/io_hd64461.c
index 7c655942b..3fbe6f2d0 100644
--- a/arch/sh/kernel/io_hd64461.c
+++ b/arch/sh/kernel/io_hd64461.c
@@ -10,15 +10,36 @@
static __inline__ unsigned long PORT2ADDR(unsigned long port)
{
+ /* 16550A: HD64461 internal */
+ if (0x3f8<=port && port<=0x3ff)
+ return CONFIG_HD64461_IOBASE + 0x8000 + ((port-0x3f8)<<1);
+ if (0x2f8<=port && port<=0x2ff)
+ return CONFIG_HD64461_IOBASE + 0x7000 + ((port-0x2f8)<<1);
+
+#ifdef CONFIG_HD64461_ENABLER
+ /* NE2000: HD64461 PCMCIA channel 0 (I/O) */
+ if (0x300<=port && port<=0x31f)
+ return 0xba000000 + port;
+
+ /* ide0: HD64461 PCMCIA channel 1 (memory) */
+ /* On HP690, CF in slot 1 is configured as a memory card
+ device. See CF+ and CompactFlash Specification for the
+ detail of CF's memory mapped addressing. */
+ if (0x1f0<=port && port<=0x1f7) return 0xb5000000 + port;
+ if (port == 0x3f6) return 0xb50001fe;
+#endif
+
+ /* ??? */
+ if (port < 0x10000) return 0xa0000000 + port;
+
/* HD64461 internal devices (0xb0000000) */
- if (port < 0x10000) return CONFIG_HD64461_IOBASE + port;
+ if (port < 0x20000) return CONFIG_HD64461_IOBASE + port - 0x10000;
/* PCMCIA channel 0, I/O (0xba000000) */
- if (port < 0x20000) return 0xba000000 + port - 0x10000;
+ if (port < 0x30000) return 0xba000000 + port - 0x20000;
- /* PCMCIA channel 1, memory (0xb5000000)
- SH7709 cannot support I/O card attached to Area 5 */
- if (port < 0x30000) return 0xb5000000 + port - 0x20000;
+ /* PCMCIA channel 1, memory (0xb5000000) */
+ if (port < 0x40000) return 0xb5000000 + port - 0x30000;
/* Whole physical address space (0xa0000000) */
return 0xa0000000 + (port & 0x1fffffff);
@@ -29,80 +50,80 @@ static inline void delay(void)
ctrl_inw(0xa0000000);
}
-unsigned long inb(unsigned int port)
+unsigned long hd64461_inb(unsigned int port)
{
return *(volatile unsigned char*)PORT2ADDR(port);
}
-unsigned long inb_p(unsigned int port)
+unsigned long hd64461_inb_p(unsigned int port)
{
unsigned long v = *(volatile unsigned char*)PORT2ADDR(port);
delay();
return v;
}
-unsigned long inw(unsigned int port)
+unsigned long hd64461_inw(unsigned int port)
{
return *(volatile unsigned short*)PORT2ADDR(port);
}
-unsigned long inl(unsigned int port)
+unsigned long hd64461_inl(unsigned int port)
{
return *(volatile unsigned long*)PORT2ADDR(port);
}
-void insb(unsigned int port, void *buffer, unsigned long count)
+void hd64461_insb(unsigned int port, void *buffer, unsigned long count)
{
unsigned char *buf=buffer;
while(count--) *buf++=inb(port);
}
-void insw(unsigned int port, void *buffer, unsigned long count)
+void hd64461_insw(unsigned int port, void *buffer, unsigned long count)
{
unsigned short *buf=buffer;
while(count--) *buf++=inw(port);
}
-void insl(unsigned int port, void *buffer, unsigned long count)
+void hd64461_insl(unsigned int port, void *buffer, unsigned long count)
{
unsigned long *buf=buffer;
while(count--) *buf++=inl(port);
}
-void outb(unsigned long b, unsigned int port)
+void hd64461_outb(unsigned long b, unsigned int port)
{
*(volatile unsigned char*)PORT2ADDR(port) = b;
}
-void outb_p(unsigned long b, unsigned int port)
+void hd64461_outb_p(unsigned long b, unsigned int port)
{
*(volatile unsigned char*)PORT2ADDR(port) = b;
delay();
}
-void outw(unsigned long b, unsigned int port)
+void hd64461_outw(unsigned long b, unsigned int port)
{
*(volatile unsigned short*)PORT2ADDR(port) = b;
}
-void outl(unsigned long b, unsigned int port)
+void hd64461_outl(unsigned long b, unsigned int port)
{
*(volatile unsigned long*)PORT2ADDR(port) = b;
}
-void outsb(unsigned int port, const void *buffer, unsigned long count)
+void hd64461_outsb(unsigned int port, const void *buffer, unsigned long count)
{
const unsigned char *buf=buffer;
while(count--) outb(*buf++, port);
}
-void outsw(unsigned int port, const void *buffer, unsigned long count)
+void hd64461_outsw(unsigned int port, const void *buffer, unsigned long count)
{
const unsigned short *buf=buffer;
while(count--) outw(*buf++, port);
}
-void outsl(unsigned int port, const void *buffer, unsigned long count)
+void hd64461_outsl(unsigned int port, const void *buffer, unsigned long count)
{
const unsigned long *buf=buffer;
while(count--) outl(*buf++, port);
diff --git a/arch/sh/kernel/io_se.c b/arch/sh/kernel/io_se.c
index a16c4738d..4d9eeca3b 100644
--- a/arch/sh/kernel/io_se.c
+++ b/arch/sh/kernel/io_se.c
@@ -56,7 +56,7 @@ shifted_port(unsigned int port)
printk("bad PC-like io %s for port 0x%x at 0x%08x\n", \
#name, (port), (__u32) __builtin_return_address(0))
-unsigned long inb(unsigned int port)
+unsigned long se_inb(unsigned int port)
{
if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
return *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port);
@@ -66,7 +66,7 @@ unsigned long inb(unsigned int port)
return (*port2adr(port))&0xff;
}
-unsigned long inb_p(unsigned int port)
+unsigned long se_inb_p(unsigned int port)
{
unsigned long v;
@@ -80,7 +80,7 @@ unsigned long inb_p(unsigned int port)
return v;
}
-unsigned long inw(unsigned int port)
+unsigned long se_inw(unsigned int port)
{
if (port >= 0x2000 ||
(sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
@@ -90,13 +90,13 @@ unsigned long inw(unsigned int port)
return 0;
}
-unsigned long inl(unsigned int port)
+unsigned long se_inl(unsigned int port)
{
maybebadio(inl, port);
return 0;
}
-void outb(unsigned long value, unsigned int port)
+void se_outb(unsigned long value, unsigned int port)
{
if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
*(__u8 *)(sh_pcic_io_wbase + port) = value;
@@ -106,7 +106,7 @@ void outb(unsigned long value, unsigned int port)
*(port2adr(port)) = value;
}
-void outb_p(unsigned long value, unsigned int port)
+void se_outb_p(unsigned long value, unsigned int port)
{
if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
*(__u8 *)(sh_pcic_io_wbase + port) = value;
@@ -117,7 +117,7 @@ void outb_p(unsigned long value, unsigned int port)
delay();
}
-void outw(unsigned long value, unsigned int port)
+void se_outw(unsigned long value, unsigned int port)
{
if (port >= 0x2000 ||
(sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
@@ -126,12 +126,12 @@ void outw(unsigned long value, unsigned int port)
maybebadio(outw, port);
}
-void outl(unsigned long value, unsigned int port)
+void se_outl(unsigned long value, unsigned int port)
{
maybebadio(outl, port);
}
-void insb(unsigned int port, void *addr, unsigned long count)
+void se_insb(unsigned int port, void *addr, unsigned long count)
{
volatile __u16 *p = port2adr(port);
@@ -148,19 +148,19 @@ void insb(unsigned int port, void *addr, unsigned long count)
}
}
-void insw(unsigned int port, void *addr, unsigned long count)
+void se_insw(unsigned int port, void *addr, unsigned long count)
{
volatile __u16 *p = port2adr(port);
while (count--)
*((__u16 *) addr)++ = *p;
}
-void insl(unsigned int port, void *addr, unsigned long count)
+void se_insl(unsigned int port, void *addr, unsigned long count)
{
maybebadio(insl, port);
}
-void outsb(unsigned int port, const void *addr, unsigned long count)
+void se_outsb(unsigned int port, const void *addr, unsigned long count)
{
volatile __u16 *p = port2adr(port);
@@ -177,24 +177,54 @@ void outsb(unsigned int port, const void *addr, unsigned long count)
}
}
-void outsw(unsigned int port, const void *addr, unsigned long count)
+void se_outsw(unsigned int port, const void *addr, unsigned long count)
{
volatile __u16 *p = port2adr(port);
while (count--)
*p = *((__u16 *) addr)++;
}
-void outsl(unsigned int port, const void *addr, unsigned long count)
+void se_outsl(unsigned int port, const void *addr, unsigned long count)
{
maybebadio(outsw, port);
}
+
+unsigned long se_readb(unsigned long addr)
+{
+ return *(volatile unsigned char*)addr;
+}
+
+unsigned long se_readw(unsigned long addr)
+{
+ return *(volatile unsigned short*)addr;
+}
+
+unsigned long se_readl(unsigned long addr)
+{
+ return *(volatile unsigned long*)addr;
+}
+
+void se_writeb(unsigned char b, unsigned long addr)
+{
+ *(volatile unsigned char*)addr = b;
+}
+
+void se_writew(unsigned short b, unsigned long addr)
+{
+ *(volatile unsigned short*)addr = b;
+}
+
+void se_writel(unsigned int b, unsigned long addr)
+{
+ *(volatile unsigned long*)addr = b;
+}
/* Map ISA bus address to the real address. Only for PCMCIA. */
/* ISA page descriptor. */
static __u32 sh_isa_memmap[256];
-int
+static int
sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
{
int idx;
@@ -212,7 +242,7 @@ sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
}
unsigned long
-sh_isa_slot(unsigned long offset)
+se_isa_port2addr(unsigned long offset)
{
int idx;
diff --git a/arch/sh/kernel/io_unknown.c b/arch/sh/kernel/io_unknown.c
new file mode 100644
index 000000000..a0407cade
--- /dev/null
+++ b/arch/sh/kernel/io_unknown.c
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/sh/kernel/io_unknown.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * I/O routine for unknown hardware.
+ */
+
+static unsigned int unknown_handler(void)
+{
+ return 0;
+}
+
+#define UNKNOWN_ALIAS(fn) \
+ void unknown_##fn(void) __attribute__ ((alias ("unknown_handler")));
+
+UNKNOWN_ALIAS(inb)
+UNKNOWN_ALIAS(inw)
+UNKNOWN_ALIAS(inl)
+UNKNOWN_ALIAS(outb)
+UNKNOWN_ALIAS(outw)
+UNKNOWN_ALIAS(outl)
+UNKNOWN_ALIAS(inb_p)
+UNKNOWN_ALIAS(inw_p)
+UNKNOWN_ALIAS(inl_p)
+UNKNOWN_ALIAS(outb_p)
+UNKNOWN_ALIAS(outw_p)
+UNKNOWN_ALIAS(outl_p)
+UNKNOWN_ALIAS(insb)
+UNKNOWN_ALIAS(insw)
+UNKNOWN_ALIAS(insl)
+UNKNOWN_ALIAS(outsb)
+UNKNOWN_ALIAS(outsw)
+UNKNOWN_ALIAS(outsl)
+UNKNOWN_ALIAS(readb)
+UNKNOWN_ALIAS(readw)
+UNKNOWN_ALIAS(readl)
+UNKNOWN_ALIAS(writeb)
+UNKNOWN_ALIAS(writew)
+UNKNOWN_ALIAS(writel)
+UNKNOWN_ALIAS(isa_port2addr)
+UNKNOWN_ALIAS(ioremap)
+UNKNOWN_ALIAS(ioremap_nocache)
+UNKNOWN_ALIAS(iounmap)
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index a353b0995..6451c4c9e 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -37,10 +37,6 @@
#include <asm/irq.h>
#include <linux/irq.h>
-#ifdef CONFIG_HD64461
-#include <asm/hd64461.h>
-#endif
-
/*
* Micro-access to controllers is serialized over the whole
* system. We never hold this lock when we call the actual
@@ -94,6 +90,7 @@ struct hw_interrupt_type no_irq_type = {
* Generic, controller-independent functions:
*/
+#if defined(CONFIG_PROC_FS)
int get_irq_list(char *buf)
{
int i, j;
@@ -105,7 +102,7 @@ int get_irq_list(char *buf)
p += sprintf(p, "CPU%d ",j);
*p++ = '\n';
- for (i = 0 ; i < NR_IRQS ; i++) {
+ for (i = 0 ; i < ACTUAL_NR_IRQS ; i++) {
action = irq_desc[i].action;
if (!action)
continue;
@@ -120,6 +117,7 @@ int get_irq_list(char *buf)
}
return p - buf;
}
+#endif
/*
* This should really return information about whether
@@ -243,18 +241,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
"shlr %0\n\t"
"add #-16, %0\n\t"
:"=z" (irq));
-#if defined(CONFIG_HD64461)
- if (irq == CONFIG_HD64461_IRQ) {
- unsigned short bit;
- unsigned short nirr = inw(HD64461_NIRR);
- unsigned short nimr = inw(HD64461_NIMR);
- nirr &= ~nimr;
- for (bit = 1, irq = 0; irq < 16; bit <<= 1, irq++)
- if (nirr & bit) break;
- if (irq == 16) irq = CONFIG_HD64461_IRQ;
- else irq += HD64461_IRQBASE;
- }
-#endif
+ irq = irq_demux(irq);
kstat.irqs[cpu][irq]++;
desc = irq_desc + irq;
@@ -330,7 +317,7 @@ int request_irq(unsigned int irq,
int retval;
struct irqaction * action;
- if (irq >= NR_IRQS)
+ if (irq >= ACTUAL_NR_IRQS)
return -EINVAL;
if (!handler)
return -EINVAL;
@@ -358,7 +345,7 @@ void free_irq(unsigned int irq, void *dev_id)
struct irqaction **p;
unsigned long flags;
- if (irq >= NR_IRQS)
+ if (irq >= ACTUAL_NR_IRQS)
return;
spin_lock_irqsave(&irq_controller_lock,flags);
@@ -408,7 +395,7 @@ unsigned long probe_irq_on(void)
for (i = NR_IRQS-1; i > 0; i--) {
if (!irq_desc[i].action) {
irq_desc[i].status |= IRQ_AUTODETECT | IRQ_WAITING;
- if(irq_desc[i].handler->startup(i))
+ if (irq_desc[i].handler->startup(i))
irq_desc[i].status |= IRQ_PENDING;
}
}
@@ -430,7 +417,7 @@ unsigned long probe_irq_on(void)
if (!(status & IRQ_AUTODETECT))
continue;
-
+
/* It triggered already - consider it spurious. */
if (!(status & IRQ_WAITING)) {
irq_desc[i].status = status & ~IRQ_AUTODETECT;
diff --git a/arch/sh/kernel/irq_imask.c b/arch/sh/kernel/irq_imask.c
index 7237ba3b5..8ac95823b 100644
--- a/arch/sh/kernel/irq_imask.c
+++ b/arch/sh/kernel/irq_imask.c
@@ -8,6 +8,9 @@
*
*/
+/* NOTE: Will not work on level 15 */
+
+
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/kernel_stat.h>
@@ -71,7 +74,7 @@ void static inline set_interrupt_registers(int ip)
: "r" (~0xf0), "r" (ip << 4));
}
-void disable_imask_irq(unsigned int irq)
+static void disable_imask_irq(unsigned int irq)
{
clear_bit(irq, &imask_mask);
if (interrupt_priority < IMASK_PRIORITY - irq)
diff --git a/arch/sh/kernel/irq_ipr.c b/arch/sh/kernel/irq_ipr.c
index 8b6b0f5ee..f229e8a12 100644
--- a/arch/sh/kernel/irq_ipr.c
+++ b/arch/sh/kernel/irq_ipr.c
@@ -21,6 +21,7 @@
#include <asm/system.h>
#include <asm/io.h>
+#include <asm/machvec.h>
struct ipr_data {
unsigned int addr; /* Address of Interrupt Priority Register */
@@ -29,15 +30,8 @@ struct ipr_data {
};
static struct ipr_data ipr_data[NR_IRQS];
-void set_ipr_data(unsigned int irq, unsigned int addr, int pos, int priority)
-{
- ipr_data[irq].addr = addr;
- ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */
- ipr_data[irq].priority = priority;
-}
-
static void enable_ipr_irq(unsigned int irq);
-void disable_ipr_irq(unsigned int irq);
+static void disable_ipr_irq(unsigned int irq);
/* shutdown is same as "disable" */
#define shutdown_ipr_irq disable_ipr_irq
@@ -61,7 +55,7 @@ static struct hw_interrupt_type ipr_irq_type = {
end_ipr_irq
};
-void disable_ipr_irq(unsigned int irq)
+static void disable_ipr_irq(unsigned int irq)
{
unsigned long val, flags;
unsigned int addr = ipr_data[irq].addr;
@@ -90,18 +84,11 @@ static void enable_ipr_irq(unsigned int irq)
restore_flags(flags);
}
-void make_ipr_irq(unsigned int irq)
-{
- disable_irq_nosync(irq);
- irq_desc[irq].handler = &ipr_irq_type;
- disable_ipr_irq(irq);
-}
-
static void mask_and_ack_ipr(unsigned int irq)
{
disable_ipr_irq(irq);
-#ifdef CONFIG_CPU_SUBTYPE_SH7709
+#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
/* This is needed when we use edge triggered setting */
/* XXX: Is it really needed? */
if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) {
@@ -118,18 +105,39 @@ static void end_ipr_irq(unsigned int irq)
enable_ipr_irq(irq);
}
+void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)
+{
+ disable_irq_nosync(irq);
+ ipr_data[irq].addr = addr;
+ ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */
+ ipr_data[irq].priority = priority;
+
+ irq_desc[irq].handler = &ipr_irq_type;
+ disable_ipr_irq(irq);
+}
+
void __init init_IRQ(void)
{
- int i;
+ make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
+ make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
- for (i = TIMER_IRQ; i < NR_IRQS; i++) {
- irq_desc[i].handler = &ipr_irq_type;
- }
+ make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
+ make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
+ make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
+
+#ifdef SCIF_ERI_IRQ
+ make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
+ make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
+ make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
+#endif
- set_ipr_data(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
- set_ipr_data(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
+#ifdef IRDA_ERI_IRQ
+ make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
+ make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
+ make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
+#endif
-#ifdef CONFIG_CPU_SUBTYPE_SH7709
+#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
/*
* Initialize the Interrupt Controller (INTC)
* registers to their power on values
@@ -161,11 +169,16 @@ void __init init_IRQ(void)
* You should set corresponding bits of PFC to "00"
* to enable these interrupts.
*/
- set_ipr_data(IRQ0_IRQ, IRQ0_IRP_ADDR, IRQ0_IRP_POS, IRQ0_PRIORITY);
- set_ipr_data(IRQ1_IRQ, IRQ1_IRP_ADDR, IRQ1_IRP_POS, IRQ1_PRIORITY);
- set_ipr_data(IRQ2_IRQ, IRQ2_IRP_ADDR, IRQ2_IRP_POS, IRQ2_PRIORITY);
- set_ipr_data(IRQ3_IRQ, IRQ3_IRP_ADDR, IRQ3_IRP_POS, IRQ3_PRIORITY);
- set_ipr_data(IRQ4_IRQ, IRQ4_IRP_ADDR, IRQ4_IRP_POS, IRQ4_PRIORITY);
- set_ipr_data(IRQ5_IRQ, IRQ5_IRP_ADDR, IRQ5_IRP_POS, IRQ5_PRIORITY);
-#endif /* CONFIG_CPU_SUBTYPE_SH7709 */
+ make_ipr_irq(IRQ0_IRQ, IRQ0_IRP_ADDR, IRQ0_IRP_POS, IRQ0_PRIORITY);
+ make_ipr_irq(IRQ1_IRQ, IRQ1_IRP_ADDR, IRQ1_IRP_POS, IRQ1_PRIORITY);
+ make_ipr_irq(IRQ2_IRQ, IRQ2_IRP_ADDR, IRQ2_IRP_POS, IRQ2_PRIORITY);
+ make_ipr_irq(IRQ3_IRQ, IRQ3_IRP_ADDR, IRQ3_IRP_POS, IRQ3_PRIORITY);
+ make_ipr_irq(IRQ4_IRQ, IRQ4_IRP_ADDR, IRQ4_IRP_POS, IRQ4_PRIORITY);
+ make_ipr_irq(IRQ5_IRQ, IRQ5_IRP_ADDR, IRQ5_IRP_POS, IRQ5_PRIORITY);
+#endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 */
+
+ /* Perform the machine specific initialisation */
+ if (sh_mv.mv_init_irq != NULL) {
+ sh_mv.mv_init_irq();
+ }
}
diff --git a/arch/sh/kernel/led_se.c b/arch/sh/kernel/led_se.c
new file mode 100644
index 000000000..0476f1bd8
--- /dev/null
+++ b/arch/sh/kernel/led_se.c
@@ -0,0 +1,67 @@
+/*
+ * linux/arch/sh/kernel/led_se.c
+ *
+ * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * This file contains Solution Engine specific LED code.
+ */
+
+#include <linux/config.h>
+
+static void mach_led(int position, int value)
+{
+ volatile unsigned short* p = (volatile unsigned short*)0xb0c00000;
+
+ if (value) {
+ *p |= (1<<8);
+ } else {
+ *p &= ~(1<<8);
+ }
+}
+
+#ifdef CONFIG_HEARTBEAT
+
+#include <linux/sched.h>
+
+/* Cycle the LED's in the clasic Knightrider/Sun pattern */
+void heartbeat_se(void)
+{
+ static unsigned int cnt = 0, period = 0;
+ volatile unsigned short* p = (volatile unsigned short*)0xb0c00000;
+ static unsigned bit = 0, up = 1;
+
+ cnt += 1;
+ if (cnt < period) {
+ return;
+ }
+
+ cnt = 0;
+
+ /* Go through the points (roughly!):
+ * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
+ */
+ period = 110 - ( (300<<FSHIFT)/
+ ((avenrun[0]/5) + (3<<FSHIFT)) );
+
+ if (up) {
+ if (bit == 7) {
+ bit--;
+ up=0;
+ } else {
+ bit ++;
+ }
+ } else {
+ if (bit == 0) {
+ bit++;
+ up=1;
+ } else {
+ bit--;
+ }
+ }
+ *p = 1<<(bit+8);
+
+}
+#endif /* CONFIG_HEARTBEAT */
diff --git a/arch/sh/kernel/mach_hp600.c b/arch/sh/kernel/mach_hp600.c
new file mode 100644
index 000000000..6f68d1af7
--- /dev/null
+++ b/arch/sh/kernel/mach_hp600.c
@@ -0,0 +1,63 @@
+/*
+ * linux/arch/sh/kernel/mach_hp600.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine vector for the HP600
+ */
+
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io_hd64461.h>
+#include <asm/io_generic.h>
+#include <asm/irq.h>
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_hp600 __initmv = {
+ mv_name: "HP600",
+
+ mv_nr_irqs: 80, /* HD64461_IRQBASE+16, see hd64461.h */
+
+ mv_inb: hd64461_inb,
+ mv_inw: hd64461_inw,
+ mv_inl: hd64461_inl,
+ mv_outb: hd64461_outb,
+ mv_outw: hd64461_outw,
+ mv_outl: hd64461_outl,
+
+ mv_inb_p: hd64461_inb_p,
+ mv_inw_p: hd64461_inw,
+ mv_inl_p: hd64461_inl,
+ mv_outb_p: hd64461_outb_p,
+ mv_outw_p: hd64461_outw,
+ mv_outl_p: hd64461_outl,
+
+ mv_insb: hd64461_insb,
+ mv_insw: hd64461_insw,
+ mv_insl: hd64461_insl,
+ mv_outsb: hd64461_outsb,
+ mv_outsw: hd64461_outsw,
+ mv_outsl: hd64461_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_irq_demux: hd64461_irq_demux,
+
+ mv_hw_hp600: 1,
+ mv_hw_hd64461: 1,
+};
+ALIAS_MV(hp600)
diff --git a/arch/sh/kernel/mach_se.c b/arch/sh/kernel/mach_se.c
new file mode 100644
index 000000000..ce142a399
--- /dev/null
+++ b/arch/sh/kernel/mach_se.c
@@ -0,0 +1,80 @@
+/*
+ * linux/arch/sh/kernel/mach_se.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine vector for the Hitachi SolutionEngine
+ */
+
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io_se.h>
+
+void heartbeat_se(void);
+void setup_se(void);
+void init_se_IRQ(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_se __initmv = {
+ mv_name: "SolutionEngine",
+
+#if defined(__SH4__)
+ mv_nr_irqs: 48,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
+ mv_nr_irqs: 32,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
+ mv_nr_irqs: 61,
+#endif
+
+ mv_inb: se_inb,
+ mv_inw: se_inw,
+ mv_inl: se_inl,
+ mv_outb: se_outb,
+ mv_outw: se_outw,
+ mv_outl: se_outl,
+
+ mv_inb_p: se_inb_p,
+ mv_inw_p: se_inw,
+ mv_inl_p: se_inl,
+ mv_outb_p: se_outb_p,
+ mv_outw_p: se_outw,
+ mv_outl_p: se_outl,
+
+ mv_insb: se_insb,
+ mv_insw: se_insw,
+ mv_insl: se_insl,
+ mv_outsb: se_outsb,
+ mv_outsw: se_outsw,
+ mv_outsl: se_outsl,
+
+ mv_readb: se_readb,
+ mv_readw: se_readw,
+ mv_readl: se_readl,
+ mv_writeb: se_writeb,
+ mv_writew: se_writew,
+ mv_writel: se_writel,
+
+ mv_ioremap: generic_ioremap,
+ mv_ioremap_nocache: generic_ioremap_nocache,
+ mv_iounmap: generic_iounmap,
+
+ mv_isa_port2addr: se_isa_port2addr,
+
+ mv_init_arch: setup_se,
+ mv_init_irq: init_se_IRQ,
+#ifdef CONFIG_HEARTBEAT
+ mv_heartbeat: heartbeat_se,
+#endif
+
+ mv_hw_se: 1,
+};
+ALIAS_MV(se)
diff --git a/arch/sh/kernel/mach_unknown.c b/arch/sh/kernel/mach_unknown.c
new file mode 100644
index 000000000..895a65c1d
--- /dev/null
+++ b/arch/sh/kernel/mach_unknown.c
@@ -0,0 +1,68 @@
+/*
+ * linux/arch/sh/kernel/mach_unknown.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine specific code for an unknown machine (internal peripherials only)
+ */
+
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io_unknown.h>
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_unknown __initmv = {
+ mv_name: "Unknown",
+
+#if defined(__SH4__)
+ mv_nr_irqs: 48,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
+ mv_nr_irqs: 32,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
+ mv_nr_irqs: 61,
+#endif
+
+ mv_inb: unknown_inb,
+ mv_inw: unknown_inw,
+ mv_inl: unknown_inl,
+ mv_outb: unknown_outb,
+ mv_outw: unknown_outw,
+ mv_outl: unknown_outl,
+
+ mv_inb_p: unknown_inb_p,
+ mv_inw_p: unknown_inw_p,
+ mv_inl_p: unknown_inl_p,
+ mv_outb_p: unknown_outb_p,
+ mv_outw_p: unknown_outw_p,
+ mv_outl_p: unknown_outl_p,
+
+ mv_insb: unknown_insb,
+ mv_insw: unknown_insw,
+ mv_insl: unknown_insl,
+ mv_outsb: unknown_outsb,
+ mv_outsw: unknown_outsw,
+ mv_outsl: unknown_outsl,
+
+ mv_readb: unknown_readb,
+ mv_readw: unknown_readw,
+ mv_readl: unknown_readl,
+ mv_writeb: unknown_writeb,
+ mv_writew: unknown_writew,
+ mv_writel: unknown_writel,
+
+ mv_ioremap: unknown_ioremap,
+ mv_ioremap_nocache: unknown_ioremap_nocache,
+ mv_iounmap: unknown_iounmap,
+
+ mv_isa_port2addr: unknown_isa_port2addr,
+};
+ALIAS_MV(unknown)
diff --git a/arch/sh/kernel/pci-sh.c b/arch/sh/kernel/pci-sh.c
index 3613596f7..a4a6c6918 100644
--- a/arch/sh/kernel/pci-sh.c
+++ b/arch/sh/kernel/pci-sh.c
@@ -4,9 +4,22 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/errno.h>
+#include <asm/machvec.h>
-unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
- unsigned long start, unsigned long size)
+void __init pcibios_init(void)
{
- return start;
+ if (sh_mv.mv_init_pci != NULL) {
+ sh_mv.mv_init_pci();
+ }
}
+
+/* Haven't done anything here as yet */
+char * __init pcibios_setup(char *str)
+{
+ return str;
+}
+
+/* We don't have anything here to fixup */
+struct pci_fixup pcibios_fixups[] = {
+ {0, 0, 0, NULL}
+};
diff --git a/arch/sh/kernel/semaphore.c b/arch/sh/kernel/semaphore.c
index c958745b5..f733501c1 100644
--- a/arch/sh/kernel/semaphore.c
+++ b/arch/sh/kernel/semaphore.c
@@ -12,6 +12,8 @@
#include <asm/semaphore.h>
#include <asm/semaphore-helper.h>
+spinlock_t semaphore_wake_lock;
+
/*
* Semaphores are implemented using a two-way counter:
* The "count" variable is decremented for each process
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index be56f8570..aaea2e6df 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -30,13 +30,16 @@
#endif
#include <linux/bootmem.h>
#include <linux/console.h>
+#include <linux/ctype.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
+#include <asm/io_generic.h>
#include <asm/smp.h>
+#include <asm/machvec.h>
#ifdef CONFIG_SH_EARLY_PRINTK
#include <asm/sh_bios.h>
#endif
@@ -53,10 +56,18 @@ extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
extern int rd_image_start; /* starting block # of image */
#endif
+#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_UNKNOWN)
+struct sh_machine_vector sh_mv;
+#endif
+
extern void fpu_init(void);
extern int root_mountflags;
extern int _text, _etext, _edata, _end;
+#define MV_NAME_SIZE 32
+
+static struct sh_machine_vector* __init get_mv_byname(const char* name);
+
/*
* This is set up by the setup-routine at boot-time
*/
@@ -180,8 +191,10 @@ void sh_console_unregister(void)
#endif
-
-static inline void parse_mem_cmdline (char ** cmdline_p)
+static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE],
+ struct sh_machine_vector** mvp,
+ unsigned long *mv_io_base,
+ int *mv_mmio_enable)
{
char c = ' ', *to = command_line, *from = COMMAND_LINE;
int len = 0;
@@ -208,6 +221,35 @@ static inline void parse_mem_cmdline (char ** cmdline_p)
memory_end = memory_start + mem_size;
}
}
+ if (c == ' ' && !memcmp(from, "sh_mv=", 6)) {
+ char* mv_end;
+ char* mv_comma;
+ int mv_len;
+ if (to != command_line)
+ to--;
+ from += 6;
+ mv_end = strchr(from, ' ');
+ if (mv_end == NULL)
+ mv_end = from + strlen(from);
+
+ mv_comma = strchr(from, ',');
+ if ((mv_comma != NULL) && (mv_comma < mv_end)) {
+ int ints[3];
+ get_options(mv_comma+1, ARRAY_SIZE(ints), ints);
+ *mv_io_base = ints[1];
+ *mv_mmio_enable = ints[2];
+ mv_len = mv_comma - from;
+ } else {
+ mv_len = mv_end - from;
+ }
+ if (mv_len > (MV_NAME_SIZE-1))
+ mv_len = MV_NAME_SIZE-1;
+ memcpy(mv_name, from, mv_len);
+ mv_name[mv_len] = '\0';
+ from = mv_end;
+
+ *mvp = get_mv_byname(mv_name);
+ }
c = *(from++);
if (!c)
break;
@@ -221,6 +263,10 @@ static inline void parse_mem_cmdline (char ** cmdline_p)
void __init setup_arch(char **cmdline_p)
{
+ struct sh_machine_vector *mv = NULL;
+ char mv_name[MV_NAME_SIZE] = "";
+ unsigned long mv_io_base = 0;
+ int mv_mmio_enable = 0;
unsigned long bootmap_size;
unsigned long start_pfn, max_pfn, max_low_pfn;
@@ -248,7 +294,58 @@ void __init setup_arch(char **cmdline_p)
data_resource.start = virt_to_bus(&_etext);
data_resource.end = virt_to_bus(&_edata)-1;
- parse_mem_cmdline(cmdline_p);
+ parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable);
+
+#ifdef CONFIG_SH_GENERIC
+ if (mv == NULL) {
+ extern struct sh_machine_vector mv_unknown;
+ mv = &mv_unknown;
+ if (*mv_name != '\0') {
+ printk("Warning: Unsupported machine %s, using unknown\n",
+ mv_name);
+ }
+ }
+ sh_mv = *mv;
+#endif
+#ifdef CONFIG_SH_UNKNOWN
+ sh_mv = mv_unknown;
+#endif
+
+#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_UNKNOWN)
+ if (mv_io_base != 0) {
+ sh_mv.mv_inb = generic_inb;
+ sh_mv.mv_inw = generic_inw;
+ sh_mv.mv_inl = generic_inl;
+ sh_mv.mv_outb = generic_outb;
+ sh_mv.mv_outw = generic_outw;
+ sh_mv.mv_outl = generic_outl;
+
+ sh_mv.mv_inb_p = generic_inb_p;
+ sh_mv.mv_inw_p = generic_inw_p;
+ sh_mv.mv_inl_p = generic_inl_p;
+ sh_mv.mv_outb_p = generic_outb_p;
+ sh_mv.mv_outw_p = generic_outw_p;
+ sh_mv.mv_outl_p = generic_outl_p;
+
+ sh_mv.mv_insb = generic_insb;
+ sh_mv.mv_insw = generic_insw;
+ sh_mv.mv_insl = generic_insl;
+ sh_mv.mv_outsb = generic_outsb;
+ sh_mv.mv_outsw = generic_outsw;
+ sh_mv.mv_outsl = generic_outsl;
+
+ sh_mv.mv_isa_port2addr = generic_isa_port2addr;
+ generic_io_base = mv_io_base;
+ }
+ if (mv_mmio_enable != 0) {
+ sh_mv.mv_readb = generic_readb;
+ sh_mv.mv_readw = generic_readw;
+ sh_mv.mv_readl = generic_readl;
+ sh_mv.mv_writeb = generic_writeb;
+ sh_mv.mv_writew = generic_writew;
+ sh_mv.mv_writel = generic_writel;
+ }
+#endif
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
@@ -358,6 +455,11 @@ void __init setup_arch(char **cmdline_p)
#endif
#endif
+ /* Perform the machine specific initialisation */
+ if (sh_mv.mv_init_arch != NULL) {
+ sh_mv.mv_init_arch();
+ }
+
#if defined(__SH4__)
/* We already grab/initialized FPU in head.S. Make it consisitent. */
init_task.used_math = 1;
@@ -366,10 +468,32 @@ void __init setup_arch(char **cmdline_p)
paging_init();
}
+struct sh_machine_vector* __init get_mv_byname(const char* name)
+{
+ extern int strcasecmp(const char *, const char *);
+ extern long __machvec_start, __machvec_end;
+ struct sh_machine_vector *all_vecs =
+ (struct sh_machine_vector *)&__machvec_start;
+
+ int i, n = ((unsigned long)&__machvec_end
+ - (unsigned long)&__machvec_start)/
+ sizeof(struct sh_machine_vector);
+
+ for (i = 0; i < n; ++i) {
+ struct sh_machine_vector *mv = &all_vecs[i];
+ if (mv == NULL)
+ continue;
+ if (strcasecmp(name, mv->mv_name) == 0) {
+ return mv;
+ }
+ }
+ return NULL;
+}
+
/*
* Get CPU information for use by the procfs.
*/
-
+#ifdef CONFIG_PROC_FS
int get_cpuinfo(char *buffer)
{
char *p = buffer;
@@ -384,6 +508,7 @@ int get_cpuinfo(char *buffer)
p += sprintf(p, "bogomips\t: %lu.%02lu\n\n",
(loops_per_sec+2500)/500000,
((loops_per_sec+2500)/5000) % 100);
+ p += sprintf(p, "Machine: %s\n", sh_mv.mv_name);
#define PRINT_CLOCK(name, value) \
p += sprintf(p, name " clock: %d.%02dMHz\n", \
@@ -395,3 +520,4 @@ int get_cpuinfo(char *buffer)
return p - buffer;
}
+#endif
diff --git a/arch/sh/kernel/setup_cqreek.c b/arch/sh/kernel/setup_cqreek.c
new file mode 100644
index 000000000..3e0422154
--- /dev/null
+++ b/arch/sh/kernel/setup_cqreek.c
@@ -0,0 +1,224 @@
+/* $Id: setup_cqreek.c,v 1.1 2000/08/05 06:25:23 gniibe Exp $
+ *
+ * arch/sh/kernel/setup_cqreek.c
+ *
+ * Copyright (C) 2000 Niibe Yutaka
+ *
+ * CqREEK IDE/ISA Bridge Support.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/io_generic.h>
+#include <asm/irq.h>
+#include <asm/machvec.h>
+#include <asm/machvec_init.h>
+
+#define BRIDGE_FEATURE 0x0002
+
+#define BRIDGE_IDE_CTRL 0x0018
+#define BRIDGE_IDE_INTR_LVL 0x001A
+#define BRIDGE_IDE_INTR_MASK 0x001C
+#define BRIDGE_IDE_INTR_STAT 0x001E
+
+#define BRIDGE_ISA_CTRL 0x0028
+#define BRIDGE_ISA_INTR_LVL 0x002A
+#define BRIDGE_ISA_INTR_MASK 0x002C
+#define BRIDGE_ISA_INTR_STAT 0x002E
+
+#define IDE_OFFSET 0xA4000000UL
+#define ISA_OFFSET 0xA4A00000UL
+
+static unsigned long cqreek_port2addr(unsigned long port)
+{
+ if (0x0000<=port && port<=0x0040)
+ return IDE_OFFSET + port;
+ if ((0x01f0<=port && port<=0x01f7) || port == 0x03f6)
+ return IDE_OFFSET + port;
+
+ return ISA_OFFSET + port;
+}
+
+static void disable_cqreek_irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned short mask;
+
+ save_and_cli(flags);
+ /* Disable IRQ */
+ mask = inw(BRIDGE_ISA_INTR_MASK) & ~(1 << irq);
+ outw_p(mask, BRIDGE_ISA_INTR_MASK);
+ restore_flags(flags);
+}
+
+static void enable_cqreek_irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned short mask;
+
+ save_and_cli(flags);
+ /* Enable IRQ */
+ mask = inw(BRIDGE_ISA_INTR_MASK) | (1 << irq);
+ outw_p(mask, BRIDGE_ISA_INTR_MASK);
+ restore_flags(flags);
+}
+
+#define CLEAR_AT_ACCEPT
+
+static void mask_and_ack_cqreek(unsigned int irq)
+{
+ inw(BRIDGE_ISA_INTR_STAT);
+ disable_cqreek_irq(irq);
+#ifdef CLEAR_AT_ACCEPT
+ /* Clear IRQ (it might be edge IRQ) */
+ outw_p((1<<irq), BRIDGE_ISA_INTR_STAT);
+#endif
+}
+
+static void end_cqreek_irq(unsigned int irq)
+{
+#ifndef CLEAR_AT_ACCEPT
+ /* Clear IRQ (it might be edge IRQ) */
+ outw_p((1<<irq), BRIDGE_ISA_INTR_STAT);
+#endif
+ enable_cqreek_irq(irq);
+}
+
+static unsigned int startup_cqreek_irq(unsigned int irq)
+{
+ enable_cqreek_irq(irq);
+ return 0;
+}
+
+static void shutdown_cqreek_irq(unsigned int irq)
+{
+ disable_cqreek_irq(irq);
+}
+
+static struct hw_interrupt_type cqreek_irq_type = {
+ "CQREEK-IRQ",
+ startup_cqreek_irq,
+ shutdown_cqreek_irq,
+ enable_cqreek_irq,
+ disable_cqreek_irq,
+ mask_and_ack_cqreek,
+ end_cqreek_irq
+};
+
+static int has_ide, has_isa;
+
+/* XXX: This is just for test for my NE2000 ISA board
+ What we really need is virtualized IRQ and demultiplexer like HP600 port */
+void __init init_cqreek_IRQ(void)
+{
+ if (has_ide)
+ make_ipr_irq(14, IDE_OFFSET+BRIDGE_IDE_INTR_LVL, 0, 0x0f-14);
+
+ if (has_isa) {
+ /* XXX: Err... we may need demultiplexer for ISA irq... */
+ irq_desc[10].handler = &cqreek_irq_type;
+ irq_desc[10].status = IRQ_DISABLED;
+ irq_desc[10].action = 0;
+ irq_desc[10].depth = 1;
+
+ disable_cqreek_irq(10);
+ }
+}
+
+/*
+ * Initialize the board
+ */
+void __init setup_cqreek(void)
+{
+ int i;
+/* udelay is not available at setup time yet... */
+#define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0)
+
+ if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */
+ outw_p(0, BRIDGE_IDE_INTR_LVL);
+ outw_p(0, BRIDGE_IDE_INTR_MASK);
+
+ outw_p(0, BRIDGE_IDE_CTRL);
+ DELAY();
+
+ outw_p(0x8000, BRIDGE_IDE_CTRL);
+ DELAY();
+
+ outw_p(0xffff, BRIDGE_IDE_INTR_STAT); /* Clear interrupt status */
+ outw_p(0x0f-14, BRIDGE_IDE_INTR_LVL); /* Use 14 IPR */
+ outw_p(1, BRIDGE_IDE_INTR_MASK); /* Enable interrupt */
+ has_ide=1;
+ }
+
+ if ((inw (BRIDGE_FEATURE) & 2)) { /* We have ISA interface */
+ outw_p(0, BRIDGE_ISA_INTR_LVL);
+ outw_p(0, BRIDGE_ISA_INTR_MASK);
+
+ outw_p(0, BRIDGE_ISA_CTRL);
+ DELAY();
+ outw_p(0x8000, BRIDGE_ISA_CTRL);
+ DELAY();
+
+ outw_p(0xffff, BRIDGE_ISA_INTR_STAT); /* Clear interrupt status */
+ outw_p(0x0f-10, BRIDGE_ISA_INTR_LVL); /* Use 10 IPR */
+ outw_p(0xfff8, BRIDGE_ISA_INTR_MASK); /* Enable interrupt */
+ has_isa=1;
+ }
+
+ printk(KERN_INFO "CqREEK Setup (IDE=%d, ISA=%d)...done\n", has_ide, has_isa);
+}
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_cqreek __initmv = {
+ mv_name: "CqREEK",
+
+#if defined(__SH4__)
+ mv_nr_irqs: 48,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
+ mv_nr_irqs: 32,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
+ mv_nr_irqs: 61,
+#endif
+
+ mv_inb: generic_inb,
+ mv_inw: generic_inw,
+ mv_inl: generic_inl,
+ mv_outb: generic_outb,
+ mv_outw: generic_outw,
+ mv_outl: generic_outl,
+
+ mv_inb_p: generic_inb_p,
+ mv_inw_p: generic_inw_p,
+ mv_inl_p: generic_inl_p,
+ mv_outb_p: generic_outb_p,
+ mv_outw_p: generic_outw_p,
+ mv_outl_p: generic_outl_p,
+
+ mv_insb: generic_insb,
+ mv_insw: generic_insw,
+ mv_insl: generic_insl,
+ mv_outsb: generic_outsb,
+ mv_outsw: generic_outsw,
+ mv_outsl: generic_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_init_arch: setup_cqreek,
+ mv_init_irq: init_cqreek_IRQ,
+
+ mv_port2addr: cqreek_port2addr,
+ mv_isa_port2addr: cqreek_port2addr,
+};
+ALIAS_MV(cqreek)
diff --git a/arch/sh/kernel/setup_hd64461.c b/arch/sh/kernel/setup_hd64461.c
index 0ee07e887..6132e420d 100644
--- a/arch/sh/kernel/setup_hd64461.c
+++ b/arch/sh/kernel/setup_hd64461.c
@@ -92,6 +92,20 @@ static void hd64461_interrupt(int irq, void *dev_id, struct pt_regs *regs)
inw(HD64461_NIRR), inw(HD64461_NIMR));
}
+int hd64461_irq_demux(int irq)
+{
+ if (irq == CONFIG_HD64461_IRQ) {
+ unsigned short bit;
+ unsigned short nirr = inw(HD64461_NIRR);
+ unsigned short nimr = inw(HD64461_NIMR);
+ nirr &= ~nimr;
+ for (bit = 1, irq = 0; irq < 16; bit <<= 1, irq++)
+ if (nirr & bit) break;
+ if (irq == 16) irq = CONFIG_HD64461_IRQ;
+ else irq += HD64461_IRQBASE;
+ }
+ return irq;
+}
static struct irqaction irq0 = { hd64461_interrupt, SA_INTERRUPT, 0, "HD64461", NULL, NULL};
@@ -100,10 +114,13 @@ int __init setup_hd64461(void)
{
int i;
+ if (!MACH_HD64461)
+ return 0;
+
printk(KERN_INFO "HD64461 configured at 0x%x on irq %d(mapped into %d to %d)\n",
CONFIG_HD64461_IOBASE, CONFIG_HD64461_IRQ,
HD64461_IRQBASE, HD64461_IRQBASE+15);
-#if 1
+#ifdef CONFIG_CPU_SUBTYPE_SH7709
/* IRQ line for HD64461 should be set level trigger mode("10"). */
/* And this should be done earlier than the kernel starts. */
ctrl_outw(0x0200, INTC_ICR1); /* when connected to IRQ4. */
diff --git a/arch/sh/kernel/setup_se.c b/arch/sh/kernel/setup_se.c
index cd9436fff..8b2f59972 100644
--- a/arch/sh/kernel/setup_se.c
+++ b/arch/sh/kernel/setup_se.c
@@ -73,10 +73,8 @@ static void __init init_smsc(void)
/*
* Initialize IRQ setting
*/
-static void __init init_se_IRQ(void)
+void __init init_se_IRQ(void)
{
- int i;
-
/*
* Super I/O (Just mimic PC):
* 1: keyboard
@@ -88,43 +86,34 @@ static void __init init_se_IRQ(void)
* 12: mouse
* 14: ide0
*/
- set_ipr_data(14, BCR_ILCRA, 2, 0x0f-14);
- set_ipr_data(12, BCR_ILCRA, 1, 0x0f-12);
- set_ipr_data( 8, BCR_ILCRB, 1, 0x0f- 8);
- set_ipr_data( 6, BCR_ILCRC, 3, 0x0f- 6);
- set_ipr_data( 5, BCR_ILCRC, 2, 0x0f- 5);
- set_ipr_data( 4, BCR_ILCRC, 1, 0x0f- 4);
- set_ipr_data( 3, BCR_ILCRC, 0, 0x0f- 3);
- set_ipr_data( 1, BCR_ILCRD, 3, 0x0f- 1);
-
- set_ipr_data(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
-
- set_ipr_data( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
- set_ipr_data(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
- set_ipr_data( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
- set_ipr_data( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
+ make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
+ make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12);
+ make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8);
+ make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
+ make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
+ make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
+ make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
+ make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
+
+ make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
+
+ make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
+ make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
+ make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
+ make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
/* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
/* NOTE: #2 and #13 are not used on PC */
- set_ipr_data(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
- set_ipr_data( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
-
- for (i = 0; i < 15; i++) {
- make_ipr_irq(i);
- }
+ make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
+ make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
}
+
/*
* Initialize the board
*/
-int __init setup_se(void)
+void __init setup_se(void)
{
- init_se_IRQ();
init_smsc();
/* XXX: RTC setting comes here */
-
- printk(KERN_INFO "Hitach SolutionEngine Setup...done\n");
- return 0;
}
-
-module_init(setup_se);
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c
index a24b4a842..12f716249 100644
--- a/arch/sh/kernel/sh_bios.c
+++ b/arch/sh/kernel/sh_bios.c
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: sh_bios.c,v 1.2 2000/07/26 04:37:32 gniibe Exp $
*
* linux/arch/sh/kernel/sh_bios.c
* C interface for trapping into the standard LinuxSH BIOS.
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 221af3022..9bdddc9d9 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -198,13 +198,16 @@ static inline int save_sigcontext_fpu(struct sigcontext *sc)
{
struct task_struct *tsk = current;
unsigned long flags;
+ int val;
if (!tsk->used_math) {
- __copy_to_user(&sc->sc_ownedfp, 0, sizeof(int));
+ val = 0;
+ __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int));
return 0;
}
- __copy_to_user(&sc->sc_ownedfp, 1, sizeof(int));
+ val = 1;
+ __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int));
/* This will cause a "finit" to be triggered by the next
attempted FPU operation by the 'current' process.
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 2c73255f4..f1e8d28bf 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -26,6 +26,7 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/delay.h>
+#include <asm/machvec.h>
#include <linux/timex.h>
#include <linux/irq.h>
@@ -226,6 +227,11 @@ static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *reg
sh_do_profile(regs->pc);
#endif
+#ifdef CONFIG_HEARTBEAT
+ if (sh_mv.mv_heartbeat != NULL)
+ sh_mv.mv_heartbeat();
+#endif
+
/*
* If we have an externally synchronized Linux clock, then update
* RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
@@ -441,11 +447,11 @@ void __init time_init(void)
tmp = (frqcr & 0x2000) >> 11;
tmp |= frqcr & 0x0003;
pfc = pfc_table[tmp];
-#ifdef CONFIG_SH_HP600
- master_clock = cpu_clock/6;
-#else
- master_clock = cpu_clock;
-#endif
+ if (MACH_HP600) {
+ master_clock = cpu_clock/6;
+ } else {
+ master_clock = cpu_clock;
+ }
bus_clock = master_clock/pfc;
}
#elif defined(__SH4__)