mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6: (43 commits) sh: sh775x/titan fixes for irq header changes. sh: update r7780rp defconfig. sh: compile fixes for header cleanup. sh: Fixup pte_mkhuge() build failure. sh: set KBUILD_IMAGE to something sensible. sh: show held locks in stack trace with lockdep. sh: platform_pata support for R7780RP sh: stacktrace/lockdep/irqflags tracing support. sh: Fixup movli.l/movco.l atomic ops for gcc4. sh: dyntick infrastructure. sh: Clock framework tidying. sh: Turn off IRQs around get_timer_offset() calls. sh: Get the PGD right in oops case with 64-bit PTEs. sh: Fix store queue bitmap end. sh: More flexible + SH7780 earlyprintk SCIF support. sh: Fixup various PAGE_SIZE == 4096 assumptions. sh: Fixup 4K irq stacks. sh: dma-api channel capability extensions. sh: Drop name overload in dma-sh. sh: Make dma-isa depend on ISA_DMA_API. ...
This commit is contained in:
commit
dd6a7c19e4
100
arch/sh/Kconfig
100
arch/sh/Kconfig
@ -51,6 +51,14 @@ config GENERIC_TIME
|
||||
config ARCH_MAY_HAVE_PC_FDC
|
||||
bool
|
||||
|
||||
config STACKTRACE_SUPPORT
|
||||
bool
|
||||
default y
|
||||
|
||||
config LOCKDEP_SUPPORT
|
||||
bool
|
||||
default y
|
||||
|
||||
source "init/Kconfig"
|
||||
|
||||
menu "System type"
|
||||
@ -219,6 +227,20 @@ config SH_SHMIN
|
||||
help
|
||||
Select SHMIN if configuring for the SHMIN board.
|
||||
|
||||
config SH_7206_SOLUTION_ENGINE
|
||||
bool "SolutionEngine7206"
|
||||
select CPU_SUBTYPE_SH7206
|
||||
help
|
||||
Select 7206 SolutionEngine if configuring for a Hitachi SH7206
|
||||
evaluation board.
|
||||
|
||||
config SH_7619_SOLUTION_ENGINE
|
||||
bool "SolutionEngine7619"
|
||||
select CPU_SUBTYPE_SH7619
|
||||
help
|
||||
Select 7619 SolutionEngine if configuring for a Hitachi SH7619
|
||||
evaluation board.
|
||||
|
||||
config SH_UNKNOWN
|
||||
bool "BareCPU"
|
||||
help
|
||||
@ -280,12 +302,20 @@ config CF_BASE_ADDR
|
||||
|
||||
menu "Processor features"
|
||||
|
||||
config CPU_LITTLE_ENDIAN
|
||||
bool "Little Endian"
|
||||
choice
|
||||
prompt "Endianess selection"
|
||||
default CPU_LITTLE_ENDIAN
|
||||
help
|
||||
Some SuperH machines can be configured for either little or big
|
||||
endian byte order. These modes require different kernels. Say Y if
|
||||
your machine is little endian, N if it's a big endian machine.
|
||||
endian byte order. These modes require different kernels.
|
||||
|
||||
config CPU_LITTLE_ENDIAN
|
||||
bool "Little Endian"
|
||||
|
||||
config CPU_BIG_ENDIAN
|
||||
bool "Big Endian"
|
||||
|
||||
endchoice
|
||||
|
||||
config SH_FPU
|
||||
bool "FPU support"
|
||||
@ -345,6 +375,9 @@ config CPU_HAS_MASKREG_IRQ
|
||||
config CPU_HAS_INTC2_IRQ
|
||||
bool
|
||||
|
||||
config CPU_HAS_IPR_IRQ
|
||||
bool
|
||||
|
||||
config CPU_HAS_SR_RB
|
||||
bool "CPU has SR.RB"
|
||||
depends on CPU_SH3 || CPU_SH4
|
||||
@ -357,6 +390,9 @@ config CPU_HAS_SR_RB
|
||||
See <file:Documentation/sh/register-banks.txt> for further
|
||||
information on SR.RB and register banking in the kernel in general.
|
||||
|
||||
config CPU_HAS_PTEA
|
||||
bool
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Timer support"
|
||||
@ -364,10 +400,25 @@ depends on !GENERIC_TIME
|
||||
|
||||
config SH_TMU
|
||||
bool "TMU timer support"
|
||||
depends on CPU_SH3 || CPU_SH4
|
||||
default y
|
||||
help
|
||||
This enables the use of the TMU as the system timer.
|
||||
|
||||
config SH_CMT
|
||||
bool "CMT timer support"
|
||||
depends on CPU_SH2
|
||||
default y
|
||||
help
|
||||
This enables the use of the CMT as the system timer.
|
||||
|
||||
config SH_MTU2
|
||||
bool "MTU2 timer support"
|
||||
depends on CPU_SH2A
|
||||
default n
|
||||
help
|
||||
This enables the use of the MTU2 as the system timer.
|
||||
|
||||
endmenu
|
||||
|
||||
source "arch/sh/boards/renesas/hs7751rvoip/Kconfig"
|
||||
@ -376,19 +427,52 @@ source "arch/sh/boards/renesas/rts7751r2d/Kconfig"
|
||||
|
||||
source "arch/sh/boards/renesas/r7780rp/Kconfig"
|
||||
|
||||
config SH_TIMER_IRQ
|
||||
int
|
||||
default "28" if CPU_SUBTYPE_SH7780
|
||||
default "86" if CPU_SUBTYPE_SH7619
|
||||
default "140" if CPU_SUBTYPE_SH7206
|
||||
default "16"
|
||||
|
||||
config NO_IDLE_HZ
|
||||
bool "Dynamic tick timer"
|
||||
help
|
||||
Select this option if you want to disable continuous timer ticks
|
||||
and have them programmed to occur as required. This option saves
|
||||
power as the system can remain in idle state for longer.
|
||||
|
||||
By default dynamic tick is disabled during the boot, and can be
|
||||
manually enabled with:
|
||||
|
||||
echo 1 > /sys/devices/system/timer/timer0/dyn_tick
|
||||
|
||||
Alternatively, if you want dynamic tick automatically enabled
|
||||
during boot, pass "dyntick=enable" via the kernel command string.
|
||||
|
||||
Please note that dynamic tick may affect the accuracy of
|
||||
timekeeping on some platforms depending on the implementation.
|
||||
|
||||
config SH_PCLK_FREQ
|
||||
int "Peripheral clock frequency (in Hz)"
|
||||
default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343
|
||||
default "31250000" if CPU_SUBTYPE_SH7619
|
||||
default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \
|
||||
CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \
|
||||
CPU_SUBTYPE_SH7206
|
||||
default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780
|
||||
default "60000000" if CPU_SUBTYPE_SH7751
|
||||
default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \
|
||||
CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705
|
||||
default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343
|
||||
default "66000000" if CPU_SUBTYPE_SH4_202
|
||||
help
|
||||
This option is used to specify the peripheral clock frequency.
|
||||
This is necessary for determining the reference clock value on
|
||||
platforms lacking an RTC.
|
||||
|
||||
config SH_CLK_MD
|
||||
int "CPU Mode Pin Setting"
|
||||
depends on CPU_SUBTYPE_SH7619 || CPU_SUBTYPE_SH7206
|
||||
help
|
||||
MD2 - MD0 Setting.
|
||||
|
||||
menu "CPU Frequency scaling"
|
||||
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
@ -421,6 +505,8 @@ config HEARTBEAT
|
||||
behavior is platform-dependent, but normally the flash frequency is
|
||||
a hyperbolic function of the 5-minute load average.
|
||||
|
||||
source "arch/sh/drivers/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
config ISA_DMA_API
|
||||
|
@ -1,5 +1,9 @@
|
||||
menu "Kernel hacking"
|
||||
|
||||
config TRACE_IRQFLAGS_SUPPORT
|
||||
bool
|
||||
default y
|
||||
|
||||
source "lib/Kconfig.debug"
|
||||
|
||||
config SH_STANDARD_BIOS
|
||||
@ -17,7 +21,18 @@ config SH_STANDARD_BIOS
|
||||
|
||||
config EARLY_SCIF_CONSOLE
|
||||
bool "Use early SCIF console"
|
||||
depends on CPU_SH4 || CPU_SH2A && !SH_STANDARD_BIOS
|
||||
help
|
||||
This enables an early console using a fixed SCIF port. This can
|
||||
be used by platforms that are either not running the SH
|
||||
standard BIOS, or do not wish to use the BIOS callbacks for the
|
||||
serial I/O.
|
||||
|
||||
config EARLY_SCIF_CONSOLE_PORT
|
||||
hex "SCIF port for early console"
|
||||
depends on EARLY_SCIF_CONSOLE
|
||||
default "0xffe00000" if CPU_SUBTYPE_SH7780
|
||||
default "0xfffe9800" if CPU_SUBTYPE_SH72060
|
||||
default "0xffe80000" if CPU_SH4
|
||||
|
||||
config EARLY_PRINTK
|
||||
bool "Early printk support"
|
||||
@ -30,6 +45,11 @@ config EARLY_PRINTK
|
||||
when the kernel may crash or hang before the serial console is
|
||||
initialised. If unsure, say N.
|
||||
|
||||
On devices that are running SH-IPL and want to keep the port
|
||||
initialization consistent while not using the BIOS callbacks,
|
||||
select both the EARLY_SCIF_CONSOLE and SH_STANDARD_BIOS, using
|
||||
the kernel command line option to toggle back and forth.
|
||||
|
||||
config DEBUG_STACKOVERFLOW
|
||||
bool "Check for stack overflows"
|
||||
depends on DEBUG_KERNEL
|
||||
|
@ -13,10 +13,6 @@
|
||||
# for "archclean" and "archdep" for cleaning up and making dependencies for
|
||||
# this architecture
|
||||
#
|
||||
|
||||
cflags-y := -mb
|
||||
cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml
|
||||
|
||||
isa-y := any
|
||||
isa-$(CONFIG_SH_DSP) := sh
|
||||
isa-$(CONFIG_CPU_SH2) := sh2
|
||||
@ -38,13 +34,16 @@ isa-y := $(isa-y)-nofpu
|
||||
endif
|
||||
endif
|
||||
|
||||
cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),)
|
||||
|
||||
cflags-$(CONFIG_CPU_SH2) += -m2
|
||||
cflags-$(CONFIG_CPU_SH3) += -m3
|
||||
cflags-$(CONFIG_CPU_SH4) += -m4 \
|
||||
cflags-$(CONFIG_CPU_SH2) := -m2
|
||||
cflags-$(CONFIG_CPU_SH3) := -m3
|
||||
cflags-$(CONFIG_CPU_SH4) := -m4 \
|
||||
$(call cc-option,-mno-implicit-fp,-m4-nofpu)
|
||||
cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a-nofpu,)
|
||||
cflags-$(CONFIG_CPU_SH4A) := -m4a $(call cc-option,-m4a-nofpu,)
|
||||
|
||||
cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb
|
||||
cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml
|
||||
|
||||
cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding
|
||||
|
||||
cflags-$(CONFIG_SH_DSP) += -Wa,-dsp
|
||||
cflags-$(CONFIG_SH_KGDB) += -g
|
||||
@ -59,7 +58,9 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -R .stab -R .stabstr -S
|
||||
# never be used by anyone. Use a board-specific defconfig that has a
|
||||
# reasonable chance of being current instead.
|
||||
#
|
||||
KBUILD_DEFCONFIG := rts7751r2d_defconfig
|
||||
KBUILD_DEFCONFIG := r7780rp_defconfig
|
||||
|
||||
KBUILD_IMAGE := arch/sh/boot/zImage
|
||||
|
||||
#
|
||||
# Choosing incompatible machines durings configuration will result in
|
||||
@ -109,6 +110,8 @@ machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev
|
||||
machdir-$(CONFIG_SH_LANDISK) := landisk
|
||||
machdir-$(CONFIG_SH_TITAN) := titan
|
||||
machdir-$(CONFIG_SH_SHMIN) := shmin
|
||||
machdir-$(CONFIG_SH_7206_SOLUTION_ENGINE) := se/7206
|
||||
machdir-$(CONFIG_SH_7619_SOLUTION_ENGINE) := se/7619
|
||||
machdir-$(CONFIG_SH_UNKNOWN) := unknown
|
||||
|
||||
incdir-y := $(notdir $(machdir-y))
|
||||
@ -124,6 +127,7 @@ core-$(CONFIG_HD64465) += arch/sh/cchips/hd6446x/hd64465/
|
||||
core-$(CONFIG_VOYAGERGX) += arch/sh/cchips/voyagergx/
|
||||
|
||||
cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2
|
||||
cpuincdir-$(CONFIG_CPU_SH2A) := cpu-sh2a
|
||||
cpuincdir-$(CONFIG_CPU_SH3) := cpu-sh3
|
||||
cpuincdir-$(CONFIG_CPU_SH4) := cpu-sh4
|
||||
|
||||
|
@ -3,4 +3,6 @@
|
||||
#
|
||||
|
||||
obj-y := setup.o io.o irq.o
|
||||
obj-$(CONFIG_HEARTBEAT) += led.o
|
||||
|
||||
obj-$(CONFIG_HEARTBEAT) += led.o
|
||||
obj-$(CONFIG_PUSH_SWITCH) += psw.o
|
||||
|
@ -10,6 +10,7 @@
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/r7780rp.h>
|
||||
|
||||
|
122
arch/sh/boards/renesas/r7780rp/psw.c
Normal file
122
arch/sh/boards/renesas/r7780rp/psw.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* arch/sh/boards/renesas/r7780rp/psw.c
|
||||
*
|
||||
* push switch support for RDBRP-1/RDBREVRP-1 debug boards.
|
||||
*
|
||||
* Copyright (C) 2006 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/io.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/mach/r7780rp.h>
|
||||
#include <asm/push-switch.h>
|
||||
|
||||
static irqreturn_t psw_irq_handler(int irq, void *arg)
|
||||
{
|
||||
struct platform_device *pdev = arg;
|
||||
struct push_switch *psw = platform_get_drvdata(pdev);
|
||||
struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
|
||||
unsigned int l, mask;
|
||||
int ret = 0;
|
||||
|
||||
l = ctrl_inw(PA_DBSW);
|
||||
|
||||
/* Nothing to do if there's no state change */
|
||||
if (psw->state) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mask = l & 0x70;
|
||||
/* Figure out who raised it */
|
||||
if (mask & (1 << psw_info->bit)) {
|
||||
psw->state = !!(mask & (1 << psw_info->bit));
|
||||
if (psw->state) /* debounce */
|
||||
mod_timer(&psw->debounce, jiffies + 50);
|
||||
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
out:
|
||||
/* Clear the switch IRQs */
|
||||
l |= (0x7 << 12);
|
||||
ctrl_outw(l, PA_DBSW);
|
||||
|
||||
return IRQ_RETVAL(ret);
|
||||
}
|
||||
|
||||
static struct resource psw_resources[] = {
|
||||
[0] = {
|
||||
.start = IRQ_PSW,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct push_switch_platform_info s2_platform_data = {
|
||||
.name = "s2",
|
||||
.bit = 6,
|
||||
.irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
|
||||
IRQF_SHARED,
|
||||
.irq_handler = psw_irq_handler,
|
||||
};
|
||||
|
||||
static struct platform_device s2_switch_device = {
|
||||
.name = "push-switch",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(psw_resources),
|
||||
.resource = psw_resources,
|
||||
.dev = {
|
||||
.platform_data = &s2_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct push_switch_platform_info s3_platform_data = {
|
||||
.name = "s3",
|
||||
.bit = 5,
|
||||
.irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
|
||||
IRQF_SHARED,
|
||||
.irq_handler = psw_irq_handler,
|
||||
};
|
||||
|
||||
static struct platform_device s3_switch_device = {
|
||||
.name = "push-switch",
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(psw_resources),
|
||||
.resource = psw_resources,
|
||||
.dev = {
|
||||
.platform_data = &s3_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct push_switch_platform_info s4_platform_data = {
|
||||
.name = "s4",
|
||||
.bit = 4,
|
||||
.irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
|
||||
IRQF_SHARED,
|
||||
.irq_handler = psw_irq_handler,
|
||||
};
|
||||
|
||||
static struct platform_device s4_switch_device = {
|
||||
.name = "push-switch",
|
||||
.id = 2,
|
||||
.num_resources = ARRAY_SIZE(psw_resources),
|
||||
.resource = psw_resources,
|
||||
.dev = {
|
||||
.platform_data = &s4_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *psw_devices[] = {
|
||||
&s2_switch_device, &s3_switch_device, &s4_switch_device,
|
||||
};
|
||||
|
||||
static int __init psw_init(void)
|
||||
{
|
||||
return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
|
||||
}
|
||||
module_init(psw_init);
|
@ -44,8 +44,37 @@ static struct platform_device m66596_usb_host_device = {
|
||||
.resource = m66596_usb_host_resources,
|
||||
};
|
||||
|
||||
static struct resource cf_ide_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x1f0,
|
||||
.end = 0x1f0 + 8,
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
[1] = {
|
||||
.start = 0x1f0 + 0x206,
|
||||
.end = 0x1f0 + 8 + 0x206 + 8,
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
[2] = {
|
||||
#ifdef CONFIG_SH_R7780MP
|
||||
.start = 1,
|
||||
#else
|
||||
.start = 4,
|
||||
#endif
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device cf_ide_device = {
|
||||
.name = "pata_platform",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(cf_ide_resources),
|
||||
.resource = cf_ide_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *r7780rp_devices[] __initdata = {
|
||||
&m66596_usb_host_device,
|
||||
&cf_ide_device,
|
||||
};
|
||||
|
||||
static int __init r7780rp_devices_setup(void)
|
||||
|
7
arch/sh/boards/se/7206/Makefile
Normal file
7
arch/sh/boards/se/7206/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
#
|
||||
# Makefile for the 7206 SolutionEngine specific parts of the kernel
|
||||
#
|
||||
|
||||
obj-y := setup.o io.o irq.o
|
||||
obj-$(CONFIG_HEARTBEAT) += led.o
|
||||
|
123
arch/sh/boards/se/7206/io.c
Normal file
123
arch/sh/boards/se/7206/io.c
Normal file
@ -0,0 +1,123 @@
|
||||
/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $
|
||||
*
|
||||
* linux/arch/sh/boards/se/7206/io.c
|
||||
*
|
||||
* Copyright (C) 2006 Yoshinori Sato
|
||||
*
|
||||
* I/O routine for Hitachi 7206 SolutionEngine.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/se7206.h>
|
||||
|
||||
|
||||
static inline void delay(void)
|
||||
{
|
||||
ctrl_inw(0x20000000); /* P2 ROM Area */
|
||||
}
|
||||
|
||||
/* MS7750 requires special versions of in*, out* routines, since
|
||||
PC-like io ports are located at upper half byte of 16-bit word which
|
||||
can be accessed only with 16-bit wide. */
|
||||
|
||||
static inline volatile __u16 *
|
||||
port2adr(unsigned int port)
|
||||
{
|
||||
if (port >= 0x2000)
|
||||
return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
|
||||
else if (port >= 0x300 || port < 0x310)
|
||||
return (volatile __u16 *) (PA_SMSC + (port - 0x300));
|
||||
}
|
||||
|
||||
unsigned char se7206_inb(unsigned long port)
|
||||
{
|
||||
return (*port2adr(port))&0xff;
|
||||
}
|
||||
|
||||
unsigned char se7206_inb_p(unsigned long port)
|
||||
{
|
||||
unsigned long v;
|
||||
|
||||
v = (*port2adr(port))&0xff;
|
||||
delay();
|
||||
return v;
|
||||
}
|
||||
|
||||
unsigned short se7206_inw(unsigned long port)
|
||||
{
|
||||
return *port2adr(port);;
|
||||
}
|
||||
|
||||
unsigned int se7206_inl(unsigned long port)
|
||||
{
|
||||
maybebadio(port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void se7206_outb(unsigned char value, unsigned long port)
|
||||
{
|
||||
*(port2adr(port)) = value;
|
||||
}
|
||||
|
||||
void se7206_outb_p(unsigned char value, unsigned long port)
|
||||
{
|
||||
*(port2adr(port)) = value;
|
||||
delay();
|
||||
}
|
||||
|
||||
void se7206_outw(unsigned short value, unsigned long port)
|
||||
{
|
||||
*port2adr(port) = value;
|
||||
}
|
||||
|
||||
void se7206_outl(unsigned int value, unsigned long port)
|
||||
{
|
||||
maybebadio(port);
|
||||
}
|
||||
|
||||
void se7206_insb(unsigned long port, void *addr, unsigned long count)
|
||||
{
|
||||
volatile __u16 *p = port2adr(port);
|
||||
__u8 *ap = addr;
|
||||
|
||||
while (count--)
|
||||
*ap++ = *p;
|
||||
}
|
||||
|
||||
void se7206_insw(unsigned long port, void *addr, unsigned long count)
|
||||
{
|
||||
volatile __u16 *p = port2adr(port);
|
||||
__u16 *ap = addr;
|
||||
while (count--)
|
||||
*ap++ = *p;
|
||||
}
|
||||
|
||||
void se7206_insl(unsigned long port, void *addr, unsigned long count)
|
||||
{
|
||||
maybebadio(port);
|
||||
}
|
||||
|
||||
void se7206_outsb(unsigned long port, const void *addr, unsigned long count)
|
||||
{
|
||||
volatile __u16 *p = port2adr(port);
|
||||
const __u8 *ap = addr;
|
||||
|
||||
while (count--)
|
||||
*p = *ap++;
|
||||
}
|
||||
|
||||
void se7206_outsw(unsigned long port, const void *addr, unsigned long count)
|
||||
{
|
||||
volatile __u16 *p = port2adr(port);
|
||||
const __u16 *ap = addr;
|
||||
while (count--)
|
||||
*p = *ap++;
|
||||
}
|
||||
|
||||
void se7206_outsl(unsigned long port, const void *addr, unsigned long count)
|
||||
{
|
||||
maybebadio(port);
|
||||
}
|
139
arch/sh/boards/se/7206/irq.c
Normal file
139
arch/sh/boards/se/7206/irq.c
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* linux/arch/sh/boards/se/7206/irq.c
|
||||
*
|
||||
* Copyright (C) 2005,2006 Yoshinori Sato
|
||||
*
|
||||
* Hitachi SolutionEngine Support.
|
||||
*
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <asm/se7206.h>
|
||||
|
||||
#define INTSTS0 0x31800000
|
||||
#define INTSTS1 0x31800002
|
||||
#define INTMSK0 0x31800004
|
||||
#define INTMSK1 0x31800006
|
||||
#define INTSEL 0x31800008
|
||||
|
||||
static void disable_se7206_irq(unsigned int irq)
|
||||
{
|
||||
unsigned short val;
|
||||
unsigned short mask = 0xffff ^ (0x0f << 4 * (3 - (IRQ0_IRQ - irq)));
|
||||
unsigned short msk0,msk1;
|
||||
|
||||
/* Set the priority in IPR to 0 */
|
||||
val = ctrl_inw(INTC_IPR01);
|
||||
val &= mask;
|
||||
ctrl_outw(val, INTC_IPR01);
|
||||
/* FPGA mask set */
|
||||
msk0 = ctrl_inw(INTMSK0);
|
||||
msk1 = ctrl_inw(INTMSK1);
|
||||
|
||||
switch (irq) {
|
||||
case IRQ0_IRQ:
|
||||
msk0 |= 0x0010;
|
||||
break;
|
||||
case IRQ1_IRQ:
|
||||
msk0 |= 0x000f;
|
||||
break;
|
||||
case IRQ2_IRQ:
|
||||
msk0 |= 0x0f00;
|
||||
msk1 |= 0x00ff;
|
||||
break;
|
||||
}
|
||||
ctrl_outw(msk0, INTMSK0);
|
||||
ctrl_outw(msk1, INTMSK1);
|
||||
}
|
||||
|
||||
static void enable_se7206_irq(unsigned int irq)
|
||||
{
|
||||
unsigned short val;
|
||||
unsigned short value = (0x0001 << 4 * (3 - (IRQ0_IRQ - irq)));
|
||||
unsigned short msk0,msk1;
|
||||
|
||||
/* Set priority in IPR back to original value */
|
||||
val = ctrl_inw(INTC_IPR01);
|
||||
val |= value;
|
||||
ctrl_outw(val, INTC_IPR01);
|
||||
|
||||
/* FPGA mask reset */
|
||||
msk0 = ctrl_inw(INTMSK0);
|
||||
msk1 = ctrl_inw(INTMSK1);
|
||||
|
||||
switch (irq) {
|
||||
case IRQ0_IRQ:
|
||||
msk0 &= ~0x0010;
|
||||
break;
|
||||
case IRQ1_IRQ:
|
||||
msk0 &= ~0x000f;
|
||||
break;
|
||||
case IRQ2_IRQ:
|
||||
msk0 &= ~0x0f00;
|
||||
msk1 &= ~0x00ff;
|
||||
break;
|
||||
}
|
||||
ctrl_outw(msk0, INTMSK0);
|
||||
ctrl_outw(msk1, INTMSK1);
|
||||
}
|
||||
|
||||
static void eoi_se7206_irq(unsigned int irq)
|
||||
{
|
||||
unsigned short sts0,sts1;
|
||||
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
||||
enable_se7206_irq(irq);
|
||||
/* FPGA isr clear */
|
||||
sts0 = ctrl_inw(INTSTS0);
|
||||
sts1 = ctrl_inw(INTSTS1);
|
||||
|
||||
switch (irq) {
|
||||
case IRQ0_IRQ:
|
||||
sts0 &= ~0x0010;
|
||||
break;
|
||||
case IRQ1_IRQ:
|
||||
sts0 &= ~0x000f;
|
||||
break;
|
||||
case IRQ2_IRQ:
|
||||
sts0 &= ~0x0f00;
|
||||
sts1 &= ~0x00ff;
|
||||
break;
|
||||
}
|
||||
ctrl_outw(sts0, INTSTS0);
|
||||
ctrl_outw(sts1, INTSTS1);
|
||||
}
|
||||
|
||||
static struct irq_chip se7206_irq_chip __read_mostly = {
|
||||
.name = "SE7206-FPGA-IRQ",
|
||||
.mask = disable_se7206_irq,
|
||||
.unmask = enable_se7206_irq,
|
||||
.mask_ack = disable_se7206_irq,
|
||||
.eoi = eoi_se7206_irq,
|
||||
};
|
||||
|
||||
static void make_se7206_irq(unsigned int irq)
|
||||
{
|
||||
disable_irq_nosync(irq);
|
||||
set_irq_chip_and_handler_name(irq, &se7206_irq_chip,
|
||||
handle_level_irq, "level");
|
||||
disable_se7206_irq(irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize IRQ setting
|
||||
*/
|
||||
void __init init_se7206_IRQ(void)
|
||||
{
|
||||
make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */
|
||||
make_se7206_irq(IRQ1_IRQ); /* ATA */
|
||||
make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */
|
||||
ctrl_outw(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */
|
||||
|
||||
/* FPGA System register setup*/
|
||||
ctrl_outw(0x0000,INTSTS0); /* Clear INTSTS0 */
|
||||
ctrl_outw(0x0000,INTSTS1); /* Clear INTSTS1 */
|
||||
/* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */
|
||||
ctrl_outw(0x0001,INTSEL);
|
||||
}
|
57
arch/sh/boards/se/7206/led.c
Normal file
57
arch/sh/boards/se/7206/led.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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>
|
||||
#include <asm/se7206.h>
|
||||
|
||||
#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*)PA_LED;
|
||||
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 */
|
79
arch/sh/boards/se/7206/setup.c
Normal file
79
arch/sh/boards/se/7206/setup.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
*
|
||||
* linux/arch/sh/boards/se/7206/setup.c
|
||||
*
|
||||
* Copyright (C) 2006 Yoshinori Sato
|
||||
*
|
||||
* Hitachi 7206 SolutionEngine Support.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/se7206.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/machvec.h>
|
||||
|
||||
static struct resource smc91x_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x300,
|
||||
.end = 0x300 + 0x020 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = 64,
|
||||
.end = 64,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device smc91x_device = {
|
||||
.name = "smc91x",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(smc91x_resources),
|
||||
.resource = smc91x_resources,
|
||||
};
|
||||
|
||||
static int __init se7206_devices_setup(void)
|
||||
{
|
||||
return platform_device_register(&smc91x_device);
|
||||
}
|
||||
|
||||
__initcall(se7206_devices_setup);
|
||||
|
||||
void heartbeat_se(void);
|
||||
|
||||
/*
|
||||
* The Machine Vector
|
||||
*/
|
||||
|
||||
struct sh_machine_vector mv_se __initmv = {
|
||||
.mv_name = "SolutionEngine",
|
||||
.mv_nr_irqs = 256,
|
||||
.mv_inb = se7206_inb,
|
||||
.mv_inw = se7206_inw,
|
||||
.mv_inl = se7206_inl,
|
||||
.mv_outb = se7206_outb,
|
||||
.mv_outw = se7206_outw,
|
||||
.mv_outl = se7206_outl,
|
||||
|
||||
.mv_inb_p = se7206_inb_p,
|
||||
.mv_inw_p = se7206_inw,
|
||||
.mv_inl_p = se7206_inl,
|
||||
.mv_outb_p = se7206_outb_p,
|
||||
.mv_outw_p = se7206_outw,
|
||||
.mv_outl_p = se7206_outl,
|
||||
|
||||
.mv_insb = se7206_insb,
|
||||
.mv_insw = se7206_insw,
|
||||
.mv_insl = se7206_insl,
|
||||
.mv_outsb = se7206_outsb,
|
||||
.mv_outsw = se7206_outsw,
|
||||
.mv_outsl = se7206_outsl,
|
||||
|
||||
.mv_init_irq = init_se7206_IRQ,
|
||||
#ifdef CONFIG_HEARTBEAT
|
||||
.mv_heartbeat = heartbeat_se,
|
||||
#endif
|
||||
};
|
||||
ALIAS_MV(se)
|
5
arch/sh/boards/se/7619/Makefile
Normal file
5
arch/sh/boards/se/7619/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# Makefile for the 7619 SolutionEngine specific parts of the kernel
|
||||
#
|
||||
|
||||
obj-y := setup.o io.o
|
102
arch/sh/boards/se/7619/io.c
Normal file
102
arch/sh/boards/se/7619/io.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
*
|
||||
* linux/arch/sh/boards/se/7619/io.c
|
||||
*
|
||||
* Copyright (C) 2006 Yoshinori Sato
|
||||
*
|
||||
* I/O routine for Hitachi 7619 SolutionEngine.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/se7619.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
/* FIXME: M3A-ZAB7 Compact Flash Slot support */
|
||||
|
||||
static inline void delay(void)
|
||||
{
|
||||
ctrl_inw(0xa0000000); /* Uncached ROM area (P2) */
|
||||
}
|
||||
|
||||
#define badio(name,port) \
|
||||
printk("bad I/O operation (%s) for port 0x%lx at 0x%08x\n", \
|
||||
#name, (port), (__u32) __builtin_return_address(0))
|
||||
|
||||
unsigned char se7619___inb(unsigned long port)
|
||||
{
|
||||
badio(inb, port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char se7619___inb_p(unsigned long port)
|
||||
{
|
||||
badio(inb_p, port);
|
||||
delay();
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned short se7619___inw(unsigned long port)
|
||||
{
|
||||
badio(inw, port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int se7619___inl(unsigned long port)
|
||||
{
|
||||
badio(inl, port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void se7619___outb(unsigned char value, unsigned long port)
|
||||
{
|
||||
badio(outb, port);
|
||||
}
|
||||
|
||||
void se7619___outb_p(unsigned char value, unsigned long port)
|
||||
{
|
||||
badio(outb_p, port);
|
||||
delay();
|
||||
}
|
||||
|
||||
void se7619___outw(unsigned short value, unsigned long port)
|
||||
{
|
||||
badio(outw, port);
|
||||
}
|
||||
|
||||
void se7619___outl(unsigned int value, unsigned long port)
|
||||
{
|
||||
badio(outl, port);
|
||||
}
|
||||
|
||||
void se7619___insb(unsigned long port, void *addr, unsigned long count)
|
||||
{
|
||||
badio(inw, port);
|
||||
}
|
||||
|
||||
void se7619___insw(unsigned long port, void *addr, unsigned long count)
|
||||
{
|
||||
badio(inw, port);
|
||||
}
|
||||
|
||||
void se7619___insl(unsigned long port, void *addr, unsigned long count)
|
||||
{
|
||||
badio(insl, port);
|
||||
}
|
||||
|
||||
void se7619___outsb(unsigned long port, const void *addr, unsigned long count)
|
||||
{
|
||||
badio(insl, port);
|
||||
}
|
||||
|
||||
void se7619___outsw(unsigned long port, const void *addr, unsigned long count)
|
||||
{
|
||||
badio(insl, port);
|
||||
}
|
||||
|
||||
void se7619___outsl(unsigned long port, const void *addr, unsigned long count)
|
||||
{
|
||||
badio(outsw, port);
|
||||
}
|
43
arch/sh/boards/se/7619/setup.c
Normal file
43
arch/sh/boards/se/7619/setup.c
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* arch/sh/boards/se/7619/setup.c
|
||||
*
|
||||
* Copyright (C) 2006 Yoshinori Sato
|
||||
*
|
||||
* Hitachi SH7619 SolutionEngine Support.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/se7619.h>
|
||||
#include <asm/machvec.h>
|
||||
|
||||
/*
|
||||
* The Machine Vector
|
||||
*/
|
||||
|
||||
struct sh_machine_vector mv_se __initmv = {
|
||||
.mv_name = "SolutionEngine",
|
||||
.mv_nr_irqs = 108,
|
||||
.mv_inb = se7619___inb,
|
||||
.mv_inw = se7619___inw,
|
||||
.mv_inl = se7619___inl,
|
||||
.mv_outb = se7619___outb,
|
||||
.mv_outw = se7619___outw,
|
||||
.mv_outl = se7619___outl,
|
||||
|
||||
.mv_inb_p = se7619___inb_p,
|
||||
.mv_inw_p = se7619___inw,
|
||||
.mv_inl_p = se7619___inl,
|
||||
.mv_outb_p = se7619___outb_p,
|
||||
.mv_outw_p = se7619___outw,
|
||||
.mv_outl_p = se7619___outl,
|
||||
|
||||
.mv_insb = se7619___insb,
|
||||
.mv_insw = se7619___insw,
|
||||
.mv_insl = se7619___insl,
|
||||
.mv_outsb = se7619___outsb,
|
||||
.mv_outsw = se7619___outsw,
|
||||
.mv_outsl = se7619___outsl,
|
||||
};
|
||||
ALIAS_MV(se)
|
@ -1,26 +1,30 @@
|
||||
/*
|
||||
* Setup for Titan
|
||||
* arch/sh/boards/titan/setup.c - Setup for Titan
|
||||
*
|
||||
* Copyright (C) 2006 Jamie Lenehan
|
||||
*
|
||||
* 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 <asm/irq.h>
|
||||
#include <linux/irq.h>
|
||||
#include <asm/titan.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
extern void __init pcibios_init_platform(void);
|
||||
|
||||
static struct ipr_data titan_ipr_map[] = {
|
||||
{ TITAN_IRQ_WAN, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY },
|
||||
{ TITAN_IRQ_LAN, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY },
|
||||
{ TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY },
|
||||
{ TITAN_IRQ_USB, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY },
|
||||
/* IRQ, IPR idx, shift, prio */
|
||||
{ TITAN_IRQ_WAN, 3, 12, 8 }, /* eth0 (WAN) */
|
||||
{ TITAN_IRQ_LAN, 3, 8, 8 }, /* eth1 (LAN) */
|
||||
{ TITAN_IRQ_MPCIA, 3, 4, 8 }, /* mPCI A (top) */
|
||||
{ TITAN_IRQ_USB, 3, 0, 8 }, /* mPCI B (bottom), USB */
|
||||
};
|
||||
|
||||
static void __init init_titan_irq(void)
|
||||
{
|
||||
/* enable individual interrupt mode for externals */
|
||||
ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
|
||||
|
||||
ipr_irq_enable_irlm();
|
||||
/* register ipr irqs */
|
||||
make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map));
|
||||
}
|
||||
|
||||
@ -47,6 +51,5 @@ struct sh_machine_vector mv_titan __initmv = {
|
||||
.mv_ioport_map = titan_ioport_map,
|
||||
|
||||
.mv_init_irq = init_titan_irq,
|
||||
.mv_init_pci = pcibios_init_platform,
|
||||
};
|
||||
ALIAS_MV(titan)
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/addrspace.h>
|
||||
#ifdef CONFIG_SH_STANDARD_BIOS
|
||||
#include <asm/sh_bios.h>
|
||||
#endif
|
||||
@ -228,7 +229,7 @@ long* stack_start = &user_stack[STACK_SIZE];
|
||||
void decompress_kernel(void)
|
||||
{
|
||||
output_data = 0;
|
||||
output_ptr = (unsigned long)&_text+0x20001000;
|
||||
output_ptr = P2SEGADDR((unsigned long)&_text+0x1000);
|
||||
free_mem_ptr = (unsigned long)&_end;
|
||||
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.19-rc3
|
||||
# Tue Oct 31 12:32:06 2006
|
||||
# Linux kernel version: 2.6.19
|
||||
# Wed Dec 6 11:59:38 2006
|
||||
#
|
||||
CONFIG_SUPERH=y
|
||||
CONFIG_RWSEM_GENERIC_SPINLOCK=y
|
||||
@ -11,6 +11,8 @@ CONFIG_GENERIC_HARDIRQS=y
|
||||
CONFIG_GENERIC_IRQ_PROBE=y
|
||||
CONFIG_GENERIC_CALIBRATE_DELAY=y
|
||||
# CONFIG_GENERIC_TIME is not set
|
||||
CONFIG_STACKTRACE_SUPPORT=y
|
||||
CONFIG_LOCKDEP_SUPPORT=y
|
||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||
|
||||
#
|
||||
@ -37,6 +39,7 @@ CONFIG_BSD_PROCESS_ACCT=y
|
||||
# CONFIG_AUDIT is not set
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
# CONFIG_SYSFS_DEPRECATED is not set
|
||||
# CONFIG_RELAY is not set
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
@ -118,6 +121,8 @@ CONFIG_SH_R7780RP=y
|
||||
# CONFIG_SH_LANDISK is not set
|
||||
# CONFIG_SH_TITAN is not set
|
||||
# CONFIG_SH_SHMIN is not set
|
||||
# CONFIG_SH_7206_SOLUTION_ENGINE is not set
|
||||
# CONFIG_SH_7619_SOLUTION_ENGINE is not set
|
||||
# CONFIG_SH_UNKNOWN is not set
|
||||
|
||||
#
|
||||
@ -130,6 +135,12 @@ CONFIG_CPU_SH4A=y
|
||||
# SH-2 Processor Support
|
||||
#
|
||||
# CONFIG_CPU_SUBTYPE_SH7604 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7619 is not set
|
||||
|
||||
#
|
||||
# SH-2A Processor Support
|
||||
#
|
||||
# CONFIG_CPU_SUBTYPE_SH7206 is not set
|
||||
|
||||
#
|
||||
# SH-3 Processor Support
|
||||
@ -165,6 +176,7 @@ CONFIG_CPU_SH4A=y
|
||||
#
|
||||
# CONFIG_CPU_SUBTYPE_SH7770 is not set
|
||||
CONFIG_CPU_SUBTYPE_SH7780=y
|
||||
# CONFIG_CPU_SUBTYPE_SH7785 is not set
|
||||
|
||||
#
|
||||
# SH4AL-DSP Processor Support
|
||||
@ -181,8 +193,14 @@ CONFIG_MEMORY_START=0x08000000
|
||||
CONFIG_MEMORY_SIZE=0x08000000
|
||||
# CONFIG_32BIT is not set
|
||||
CONFIG_VSYSCALL=y
|
||||
CONFIG_PAGE_SIZE_4KB=y
|
||||
# CONFIG_PAGE_SIZE_8KB is not set
|
||||
# CONFIG_PAGE_SIZE_64KB is not set
|
||||
CONFIG_HUGETLB_PAGE_SIZE_64K=y
|
||||
# CONFIG_HUGETLB_PAGE_SIZE_256K is not set
|
||||
# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
|
||||
# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
|
||||
# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
|
||||
CONFIG_SELECT_MEMORY_MODEL=y
|
||||
CONFIG_FLATMEM_MANUAL=y
|
||||
# CONFIG_DISCONTIGMEM_MANUAL is not set
|
||||
@ -204,12 +222,14 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
|
||||
# Processor features
|
||||
#
|
||||
CONFIG_CPU_LITTLE_ENDIAN=y
|
||||
# CONFIG_CPU_BIG_ENDIAN is not set
|
||||
CONFIG_SH_FPU=y
|
||||
# CONFIG_SH_DSP is not set
|
||||
CONFIG_SH_STORE_QUEUES=y
|
||||
CONFIG_CPU_HAS_INTEVT=y
|
||||
CONFIG_CPU_HAS_INTC2_IRQ=y
|
||||
CONFIG_CPU_HAS_SR_RB=y
|
||||
CONFIG_CPU_HAS_PTEA=y
|
||||
|
||||
#
|
||||
# Timer support
|
||||
@ -220,6 +240,8 @@ CONFIG_SH_TMU=y
|
||||
# R7780RP options
|
||||
#
|
||||
CONFIG_SH_R7780MP=y
|
||||
CONFIG_SH_TIMER_IRQ=28
|
||||
CONFIG_NO_IDLE_HZ=y
|
||||
CONFIG_SH_PCLK_FREQ=32000000
|
||||
|
||||
#
|
||||
@ -237,6 +259,11 @@ CONFIG_SH_PCLK_FREQ=32000000
|
||||
#
|
||||
# CONFIG_HD6446X_SERIES is not set
|
||||
|
||||
#
|
||||
# Additional SuperH Device Drivers
|
||||
#
|
||||
CONFIG_PUSH_SWITCH=y
|
||||
|
||||
#
|
||||
# Kernel features
|
||||
#
|
||||
@ -244,7 +271,7 @@ CONFIG_SH_PCLK_FREQ=32000000
|
||||
CONFIG_HZ_250=y
|
||||
# CONFIG_HZ_1000 is not set
|
||||
CONFIG_HZ=250
|
||||
# CONFIG_KEXEC is not set
|
||||
CONFIG_KEXEC=y
|
||||
# CONFIG_SMP is not set
|
||||
# CONFIG_PREEMPT_NONE is not set
|
||||
# CONFIG_PREEMPT_VOLUNTARY is not set
|
||||
@ -278,10 +305,7 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
|
||||
#
|
||||
# PCI Hotplug Support
|
||||
#
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
# CONFIG_HOTPLUG_PCI_FAKE is not set
|
||||
# CONFIG_HOTPLUG_PCI_CPCI is not set
|
||||
# CONFIG_HOTPLUG_PCI_SHPC is not set
|
||||
# CONFIG_HOTPLUG_PCI is not set
|
||||
|
||||
#
|
||||
# Executable file formats
|
||||
@ -341,6 +365,7 @@ CONFIG_INET_TCP_DIAG=y
|
||||
# CONFIG_TCP_CONG_ADVANCED is not set
|
||||
CONFIG_TCP_CONG_CUBIC=y
|
||||
CONFIG_DEFAULT_TCP_CONG="cubic"
|
||||
# CONFIG_TCP_MD5SIG is not set
|
||||
# CONFIG_IPV6 is not set
|
||||
# CONFIG_INET6_XFRM_TUNNEL is not set
|
||||
# CONFIG_INET6_TUNNEL is not set
|
||||
@ -556,6 +581,7 @@ CONFIG_SATA_SIL=y
|
||||
# CONFIG_PATA_IT821X is not set
|
||||
# CONFIG_PATA_JMICRON is not set
|
||||
# CONFIG_PATA_TRIFLEX is not set
|
||||
# CONFIG_PATA_MARVELL is not set
|
||||
# CONFIG_PATA_MPIIX is not set
|
||||
# CONFIG_PATA_OLDPIIX is not set
|
||||
# CONFIG_PATA_NETCELL is not set
|
||||
@ -572,6 +598,7 @@ CONFIG_SATA_SIL=y
|
||||
# CONFIG_PATA_SIS is not set
|
||||
# CONFIG_PATA_VIA is not set
|
||||
# CONFIG_PATA_WINBOND is not set
|
||||
CONFIG_PATA_PLATFORM=y
|
||||
|
||||
#
|
||||
# Multi-device support (RAID and LVM)
|
||||
@ -688,6 +715,7 @@ CONFIG_R8169=y
|
||||
# CONFIG_IXGB is not set
|
||||
# CONFIG_S2IO is not set
|
||||
# CONFIG_MYRI10GE is not set
|
||||
# CONFIG_NETXEN_NIC is not set
|
||||
|
||||
#
|
||||
# Token Ring devices
|
||||
@ -830,10 +858,6 @@ CONFIG_HW_RANDOM=y
|
||||
# CONFIG_DTLK is not set
|
||||
# CONFIG_R3964 is not set
|
||||
# CONFIG_APPLICOM is not set
|
||||
|
||||
#
|
||||
# Ftape, the floppy tape device driver
|
||||
#
|
||||
# CONFIG_DRM is not set
|
||||
# CONFIG_RAW_DRIVER is not set
|
||||
|
||||
@ -1020,7 +1044,7 @@ CONFIG_INOTIFY_USER=y
|
||||
CONFIG_DNOTIFY=y
|
||||
# CONFIG_AUTOFS_FS is not set
|
||||
# CONFIG_AUTOFS4_FS is not set
|
||||
# CONFIG_FUSE_FS is not set
|
||||
CONFIG_FUSE_FS=m
|
||||
|
||||
#
|
||||
# CD-ROM/DVD Filesystems
|
||||
@ -1052,7 +1076,7 @@ CONFIG_TMPFS=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_HUGETLB_PAGE=y
|
||||
CONFIG_RAMFS=y
|
||||
# CONFIG_CONFIGFS_FS is not set
|
||||
CONFIG_CONFIGFS_FS=m
|
||||
|
||||
#
|
||||
# Miscellaneous filesystems
|
||||
@ -1153,28 +1177,33 @@ CONFIG_NLS_ISO8859_1=y
|
||||
#
|
||||
# Profiling support
|
||||
#
|
||||
# CONFIG_PROFILING is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_OPROFILE=m
|
||||
|
||||
#
|
||||
# Kernel hacking
|
||||
#
|
||||
# CONFIG_PRINTK_TIME is not set
|
||||
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_ENABLE_MUST_CHECK=y
|
||||
# CONFIG_MAGIC_SYSRQ is not set
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
# CONFIG_UNUSED_SYMBOLS is not set
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
CONFIG_DETECT_SOFTLOCKUP=y
|
||||
# CONFIG_SCHEDSTATS is not set
|
||||
# CONFIG_DEBUG_SLAB is not set
|
||||
CONFIG_DEBUG_SPINLOCK=y
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
# CONFIG_DEBUG_SPINLOCK is not set
|
||||
# CONFIG_DEBUG_MUTEXES is not set
|
||||
# CONFIG_DEBUG_RWSEMS is not set
|
||||
# CONFIG_DEBUG_LOCK_ALLOC is not set
|
||||
# CONFIG_PROVE_LOCKING is not set
|
||||
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
|
||||
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
|
||||
# CONFIG_DEBUG_KOBJECT is not set
|
||||
# CONFIG_DEBUG_BUGVERBOSE is not set
|
||||
# CONFIG_DEBUG_INFO is not set
|
||||
CONFIG_DEBUG_BUGVERBOSE=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
# CONFIG_DEBUG_VM is not set
|
||||
# CONFIG_DEBUG_LIST is not set
|
||||
@ -1184,7 +1213,7 @@ CONFIG_FORCED_INLINING=y
|
||||
# CONFIG_RCU_TORTURE_TEST is not set
|
||||
# CONFIG_SH_STANDARD_BIOS is not set
|
||||
# CONFIG_EARLY_SCIF_CONSOLE is not set
|
||||
# CONFIG_DEBUG_STACKOVERFLOW is not set
|
||||
CONFIG_DEBUG_STACKOVERFLOW=y
|
||||
# CONFIG_DEBUG_STACK_USAGE is not set
|
||||
# CONFIG_4KSTACKS is not set
|
||||
# CONFIG_KGDB is not set
|
||||
|
826
arch/sh/configs/se7206_defconfig
Normal file
826
arch/sh/configs/se7206_defconfig
Normal file
@ -0,0 +1,826 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.19-rc4
|
||||
# Sun Nov 5 16:20:10 2006
|
||||
#
|
||||
CONFIG_SUPERH=y
|
||||
CONFIG_RWSEM_GENERIC_SPINLOCK=y
|
||||
CONFIG_GENERIC_FIND_NEXT_BIT=y
|
||||
CONFIG_GENERIC_HWEIGHT=y
|
||||
CONFIG_GENERIC_HARDIRQS=y
|
||||
CONFIG_GENERIC_IRQ_PROBE=y
|
||||
CONFIG_GENERIC_CALIBRATE_DELAY=y
|
||||
# CONFIG_GENERIC_TIME is not set
|
||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||
|
||||
#
|
||||
# Code maturity level options
|
||||
#
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
CONFIG_BROKEN_ON_SMP=y
|
||||
CONFIG_INIT_ENV_ARG_LIMIT=32
|
||||
|
||||
#
|
||||
# General setup
|
||||
#
|
||||
CONFIG_LOCALVERSION=""
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
# CONFIG_SYSVIPC is not set
|
||||
# CONFIG_POSIX_MQUEUE is not set
|
||||
# CONFIG_BSD_PROCESS_ACCT is not set
|
||||
# CONFIG_TASKSTATS is not set
|
||||
# CONFIG_UTS_NS is not set
|
||||
# CONFIG_AUDIT is not set
|
||||
# CONFIG_IKCONFIG is not set
|
||||
# CONFIG_RELAY is not set
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||
CONFIG_SYSCTL=y
|
||||
CONFIG_EMBEDDED=y
|
||||
CONFIG_UID16=y
|
||||
# CONFIG_SYSCTL_SYSCALL is not set
|
||||
CONFIG_KALLSYMS=y
|
||||
# CONFIG_KALLSYMS_EXTRA_PASS is not set
|
||||
# CONFIG_HOTPLUG is not set
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_BUG=y
|
||||
CONFIG_ELF_CORE=y
|
||||
CONFIG_BASE_FULL=y
|
||||
# CONFIG_FUTEX is not set
|
||||
# CONFIG_EPOLL is not set
|
||||
CONFIG_SLAB=y
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
CONFIG_TINY_SHMEM=y
|
||||
CONFIG_BASE_SMALL=0
|
||||
# CONFIG_SLOB is not set
|
||||
|
||||
#
|
||||
# Loadable module support
|
||||
#
|
||||
# CONFIG_MODULES is not set
|
||||
|
||||
#
|
||||
# Block layer
|
||||
#
|
||||
CONFIG_BLOCK=y
|
||||
# CONFIG_LBD is not set
|
||||
# CONFIG_LSF is not set
|
||||
|
||||
#
|
||||
# IO Schedulers
|
||||
#
|
||||
CONFIG_IOSCHED_NOOP=y
|
||||
# CONFIG_IOSCHED_AS is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
# CONFIG_DEFAULT_AS is not set
|
||||
# CONFIG_DEFAULT_DEADLINE is not set
|
||||
# CONFIG_DEFAULT_CFQ is not set
|
||||
CONFIG_DEFAULT_NOOP=y
|
||||
CONFIG_DEFAULT_IOSCHED="noop"
|
||||
|
||||
#
|
||||
# System type
|
||||
#
|
||||
# CONFIG_SH_SOLUTION_ENGINE is not set
|
||||
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
|
||||
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
|
||||
# CONFIG_SH_7343_SOLUTION_ENGINE is not set
|
||||
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
|
||||
# CONFIG_SH_7751_SYSTEMH is not set
|
||||
# CONFIG_SH_HP6XX is not set
|
||||
# CONFIG_SH_EC3104 is not set
|
||||
# CONFIG_SH_SATURN is not set
|
||||
# CONFIG_SH_DREAMCAST is not set
|
||||
# CONFIG_SH_BIGSUR is not set
|
||||
# CONFIG_SH_MPC1211 is not set
|
||||
# CONFIG_SH_SH03 is not set
|
||||
# CONFIG_SH_SECUREEDGE5410 is not set
|
||||
# CONFIG_SH_HS7751RVOIP is not set
|
||||
# CONFIG_SH_7710VOIPGW is not set
|
||||
# CONFIG_SH_RTS7751R2D is not set
|
||||
# CONFIG_SH_R7780RP is not set
|
||||
# CONFIG_SH_EDOSK7705 is not set
|
||||
# CONFIG_SH_SH4202_MICRODEV is not set
|
||||
# CONFIG_SH_LANDISK is not set
|
||||
# CONFIG_SH_TITAN is not set
|
||||
# CONFIG_SH_SHMIN is not set
|
||||
CONFIG_SH_7206_SOLUTION_ENGINE=y
|
||||
# CONFIG_SH_7619_SOLUTION_ENGINE is not set
|
||||
# CONFIG_SH_UNKNOWN is not set
|
||||
|
||||
#
|
||||
# Processor selection
|
||||
#
|
||||
CONFIG_CPU_SH2=y
|
||||
CONFIG_CPU_SH2A=y
|
||||
|
||||
#
|
||||
# SH-2 Processor Support
|
||||
#
|
||||
# CONFIG_CPU_SUBTYPE_SH7604 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7619 is not set
|
||||
|
||||
#
|
||||
# SH-2A Processor Support
|
||||
#
|
||||
CONFIG_CPU_SUBTYPE_SH7206=y
|
||||
|
||||
#
|
||||
# SH-3 Processor Support
|
||||
#
|
||||
# CONFIG_CPU_SUBTYPE_SH7300 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7705 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7706 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7707 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7708 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7709 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7710 is not set
|
||||
|
||||
#
|
||||
# SH-4 Processor Support
|
||||
#
|
||||
# CONFIG_CPU_SUBTYPE_SH7750 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7091 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7750R is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7750S is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7751 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7751R is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7760 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
|
||||
|
||||
#
|
||||
# ST40 Processor Support
|
||||
#
|
||||
# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
|
||||
# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
|
||||
|
||||
#
|
||||
# SH-4A Processor Support
|
||||
#
|
||||
# CONFIG_CPU_SUBTYPE_SH7770 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7780 is not set
|
||||
|
||||
#
|
||||
# SH4AL-DSP Processor Support
|
||||
#
|
||||
# CONFIG_CPU_SUBTYPE_SH73180 is not set
|
||||
# CONFIG_CPU_SUBTYPE_SH7343 is not set
|
||||
|
||||
#
|
||||
# Memory management options
|
||||
#
|
||||
CONFIG_PAGE_OFFSET=0x00000000
|
||||
CONFIG_MEMORY_START=0x0c000000
|
||||
CONFIG_MEMORY_SIZE=0x02000000
|
||||
CONFIG_SELECT_MEMORY_MODEL=y
|
||||
CONFIG_FLATMEM_MANUAL=y
|
||||
# CONFIG_DISCONTIGMEM_MANUAL is not set
|
||||
# CONFIG_SPARSEMEM_MANUAL is not set
|
||||
CONFIG_FLATMEM=y
|
||||
CONFIG_FLAT_NODE_MEM_MAP=y
|
||||
# CONFIG_SPARSEMEM_STATIC is not set
|
||||
CONFIG_SPLIT_PTLOCK_CPUS=4
|
||||
# CONFIG_RESOURCES_64BIT is not set
|
||||
|
||||
#
|
||||
# Cache configuration
|
||||
#
|
||||
# CONFIG_SH_DIRECT_MAPPED is not set
|
||||
# CONFIG_SH_WRITETHROUGH is not set
|
||||
# CONFIG_SH_OCRAM is not set
|
||||
|
||||
#
|
||||
# Processor features
|
||||
#
|
||||
# CONFIG_CPU_LITTLE_ENDIAN is not set
|
||||
# CONFIG_SH_FPU is not set
|
||||
# CONFIG_SH_FPU_EMU is not set
|
||||
# CONFIG_SH_DSP is not set
|
||||
|
||||
#
|
||||
# Timer support
|
||||
#
|
||||
CONFIG_SH_CMT=y
|
||||
# CONFIG_SH_MTU2 is not set
|
||||
CONFIG_SH_PCLK_FREQ=33333333
|
||||
CONFIG_SH_CLK_MD=6
|
||||
|
||||
#
|
||||
# CPU Frequency scaling
|
||||
#
|
||||
# CONFIG_CPU_FREQ is not set
|
||||
|
||||
#
|
||||
# DMA support
|
||||
#
|
||||
# CONFIG_SH_DMA is not set
|
||||
|
||||
#
|
||||
# Companion Chips
|
||||
#
|
||||
# CONFIG_HD6446X_SERIES is not set
|
||||
|
||||
#
|
||||
# Kernel features
|
||||
#
|
||||
CONFIG_HZ_100=y
|
||||
# CONFIG_HZ_250 is not set
|
||||
# CONFIG_HZ_1000 is not set
|
||||
CONFIG_HZ=100
|
||||
# CONFIG_KEXEC is not set
|
||||
# CONFIG_SMP is not set
|
||||
CONFIG_PREEMPT_NONE=y
|
||||
# CONFIG_PREEMPT_VOLUNTARY is not set
|
||||
# CONFIG_PREEMPT is not set
|
||||
|
||||
#
|
||||
# Boot options
|
||||
#
|
||||
CONFIG_ZERO_PAGE_OFFSET=0x00001000
|
||||
CONFIG_BOOT_LINK_OFFSET=0x00800000
|
||||
# CONFIG_UBC_WAKEUP is not set
|
||||
# CONFIG_CMDLINE_BOOL is not set
|
||||
|
||||
#
|
||||
# Bus options
|
||||
#
|
||||
# CONFIG_PCI is not set
|
||||
|
||||
#
|
||||
# PCCARD (PCMCIA/CardBus) support
|
||||
#
|
||||
|
||||
#
|
||||
# PCI Hotplug Support
|
||||
#
|
||||
|
||||
#
|
||||
# Executable file formats
|
||||
#
|
||||
CONFIG_BINFMT_FLAT=y
|
||||
CONFIG_BINFMT_ZFLAT=y
|
||||
# CONFIG_BINFMT_SHARED_FLAT is not set
|
||||
# CONFIG_BINFMT_MISC is not set
|
||||
|
||||
#
|
||||
# Power management options (EXPERIMENTAL)
|
||||
#
|
||||
# CONFIG_PM is not set
|
||||
|
||||
#
|
||||
# Networking
|
||||
#
|
||||
CONFIG_NET=y
|
||||
|
||||
#
|
||||
# Networking options
|
||||
#
|
||||
# CONFIG_NETDEBUG is not set
|
||||
# CONFIG_PACKET is not set
|
||||
# CONFIG_UNIX is not set
|
||||
CONFIG_XFRM=y
|
||||
# CONFIG_XFRM_USER is not set
|
||||
# CONFIG_XFRM_SUB_POLICY is not set
|
||||
# CONFIG_NET_KEY is not set
|
||||
CONFIG_INET=y
|
||||
# CONFIG_IP_MULTICAST is not set
|
||||
# CONFIG_IP_ADVANCED_ROUTER is not set
|
||||
CONFIG_IP_FIB_HASH=y
|
||||
# CONFIG_IP_PNP is not set
|
||||
# CONFIG_NET_IPIP is not set
|
||||
# CONFIG_NET_IPGRE is not set
|
||||
# CONFIG_ARPD is not set
|
||||
# CONFIG_SYN_COOKIES is not set
|
||||
# CONFIG_INET_AH is not set
|
||||
# CONFIG_INET_ESP is not set
|
||||
# CONFIG_INET_IPCOMP is not set
|
||||
# CONFIG_INET_XFRM_TUNNEL is not set
|
||||
# CONFIG_INET_TUNNEL is not set
|
||||
CONFIG_INET_XFRM_MODE_TRANSPORT=y
|
||||
CONFIG_INET_XFRM_MODE_TUNNEL=y
|
||||
CONFIG_INET_XFRM_MODE_BEET=y
|
||||
# CONFIG_INET_DIAG is not set
|
||||
# CONFIG_TCP_CONG_ADVANCED is not set
|
||||
CONFIG_TCP_CONG_CUBIC=y
|
||||
CONFIG_DEFAULT_TCP_CONG="cubic"
|
||||
# CONFIG_IPV6 is not set
|
||||
# CONFIG_INET6_XFRM_TUNNEL is not set
|
||||
# CONFIG_INET6_TUNNEL is not set
|
||||
# CONFIG_NETWORK_SECMARK is not set
|
||||
# CONFIG_NETFILTER is not set
|
||||
|
||||
#
|
||||
# DCCP Configuration (EXPERIMENTAL)
|
||||
#
|
||||
# CONFIG_IP_DCCP is not set
|
||||
|
||||
#
|
||||
# SCTP Configuration (EXPERIMENTAL)
|
||||
#
|
||||
# CONFIG_IP_SCTP is not set
|
||||
|
||||
#
|
||||
# TIPC Configuration (EXPERIMENTAL)
|
||||
#
|
||||
# CONFIG_TIPC is not set
|
||||
# CONFIG_ATM is not set
|
||||
# CONFIG_BRIDGE is not set
|
||||
# CONFIG_VLAN_8021Q is not set
|
||||
# CONFIG_DECNET is not set
|
||||
# CONFIG_LLC2 is not set
|
||||
# CONFIG_IPX is not set
|
||||
# CONFIG_ATALK is not set
|
||||
# CONFIG_X25 is not set
|
||||
# CONFIG_LAPB is not set
|
||||
# CONFIG_ECONET is not set
|
||||
# CONFIG_WAN_ROUTER is not set
|
||||
|
||||
#
|
||||
# QoS and/or fair queueing
|
||||
#
|
||||
# CONFIG_NET_SCHED is not set
|
||||
|
||||
#
|
||||
# Network testing
|
||||
#
|
||||
# CONFIG_NET_PKTGEN is not set
|
||||
# CONFIG_HAMRADIO is not set
|
||||
# CONFIG_IRDA is not set
|
||||
# CONFIG_BT is not set
|
||||
# CONFIG_IEEE80211 is not set
|
||||
|
||||
#
|
||||
# Device Drivers
|
||||
#
|
||||
|
||||
#
|
||||
# Generic Driver Options
|
||||
#
|
||||
# CONFIG_STANDALONE is not set
|
||||
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||
# CONFIG_SYS_HYPERVISOR is not set
|
||||
|
||||
#
|
||||
# Connector - unified userspace <-> kernelspace linker
|
||||
#
|
||||
# CONFIG_CONNECTOR is not set
|
||||
|
||||
#
|
||||
# Memory Technology Devices (MTD)
|
||||
#
|
||||
CONFIG_MTD=y
|
||||
# CONFIG_MTD_DEBUG is not set
|
||||
# CONFIG_MTD_CONCAT is not set
|
||||
CONFIG_MTD_PARTITIONS=y
|
||||
CONFIG_MTD_REDBOOT_PARTS=y
|
||||
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
|
||||
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
|
||||
# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
|
||||
# CONFIG_MTD_CMDLINE_PARTS is not set
|
||||
|
||||
#
|
||||
# User Modules And Translation Layers
|
||||
#
|
||||
CONFIG_MTD_CHAR=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
# CONFIG_FTL is not set
|
||||
# CONFIG_NFTL is not set
|
||||
# CONFIG_INFTL is not set
|
||||
# CONFIG_RFD_FTL is not set
|
||||
# CONFIG_SSFDC is not set
|
||||
|
||||
#
|
||||
# RAM/ROM/Flash chip drivers
|
||||
#
|
||||
CONFIG_MTD_CFI=y
|
||||
# CONFIG_MTD_JEDECPROBE is not set
|
||||
CONFIG_MTD_GEN_PROBE=y
|
||||
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_1=y
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_2=y
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_4=y
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
|
||||
CONFIG_MTD_CFI_I1=y
|
||||
CONFIG_MTD_CFI_I2=y
|
||||
# CONFIG_MTD_CFI_I4 is not set
|
||||
# CONFIG_MTD_CFI_I8 is not set
|
||||
# CONFIG_MTD_CFI_INTELEXT is not set
|
||||
CONFIG_MTD_CFI_AMDSTD=y
|
||||
# CONFIG_MTD_CFI_STAA is not set
|
||||
CONFIG_MTD_CFI_UTIL=y
|
||||
# CONFIG_MTD_RAM is not set
|
||||
# CONFIG_MTD_ROM is not set
|
||||
# CONFIG_MTD_ABSENT is not set
|
||||
# CONFIG_MTD_OBSOLETE_CHIPS is not set
|
||||
|
||||
#
|
||||
# Mapping drivers for chip access
|
||||
#
|
||||
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
|
||||
CONFIG_MTD_PHYSMAP=y
|
||||
CONFIG_MTD_PHYSMAP_START=0x20000000
|
||||
CONFIG_MTD_PHYSMAP_LEN=0x1000000
|
||||
CONFIG_MTD_PHYSMAP_BANKWIDTH=4
|
||||
# CONFIG_MTD_SOLUTIONENGINE is not set
|
||||
# CONFIG_MTD_UCLINUX is not set
|
||||
# CONFIG_MTD_PLATRAM is not set
|
||||
|
||||
#
|
||||
# Self-contained MTD device drivers
|
||||
#
|
||||
# CONFIG_MTD_SLRAM is not set
|
||||
# CONFIG_MTD_PHRAM is not set
|
||||
# CONFIG_MTD_MTDRAM is not set
|
||||
# CONFIG_MTD_BLOCK2MTD is not set
|
||||
|
||||
#
|
||||
# Disk-On-Chip Device Drivers
|
||||
#
|
||||
# CONFIG_MTD_DOC2000 is not set
|
||||
# CONFIG_MTD_DOC2001 is not set
|
||||
# CONFIG_MTD_DOC2001PLUS is not set
|
||||
|
||||
#
|
||||
# NAND Flash Device Drivers
|
||||
#
|
||||
# CONFIG_MTD_NAND is not set
|
||||
|
||||
#
|
||||
# OneNAND Flash Device Drivers
|
||||
#
|
||||
# CONFIG_MTD_ONENAND is not set
|
||||
|
||||
#
|
||||
# Parallel port support
|
||||
#
|
||||
# CONFIG_PARPORT is not set
|
||||
|
||||
#
|
||||
# Plug and Play support
|
||||
#
|
||||
|
||||
#
|
||||
# Block devices
|
||||
#
|
||||
# CONFIG_BLK_DEV_COW_COMMON is not set
|
||||
# CONFIG_BLK_DEV_LOOP is not set
|
||||
# CONFIG_BLK_DEV_NBD is not set
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=16
|
||||
CONFIG_BLK_DEV_RAM_SIZE=4096
|
||||
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
|
||||
# CONFIG_BLK_DEV_INITRD is not set
|
||||
# CONFIG_CDROM_PKTCDVD is not set
|
||||
# CONFIG_ATA_OVER_ETH is not set
|
||||
|
||||
#
|
||||
# Misc devices
|
||||
#
|
||||
# CONFIG_TIFM_CORE is not set
|
||||
|
||||
#
|
||||
# ATA/ATAPI/MFM/RLL support
|
||||
#
|
||||
# CONFIG_IDE is not set
|
||||
|
||||
#
|
||||
# SCSI device support
|
||||
#
|
||||
# CONFIG_RAID_ATTRS is not set
|
||||
# CONFIG_SCSI is not set
|
||||
# CONFIG_SCSI_NETLINK is not set
|
||||
|
||||
#
|
||||
# Serial ATA (prod) and Parallel ATA (experimental) drivers
|
||||
#
|
||||
# CONFIG_ATA is not set
|
||||
|
||||
#
|
||||
# Multi-device support (RAID and LVM)
|
||||
#
|
||||
# CONFIG_MD is not set
|
||||
|
||||
#
|
||||
# Fusion MPT device support
|
||||
#
|
||||
# CONFIG_FUSION is not set
|
||||
|
||||
#
|
||||
# IEEE 1394 (FireWire) support
|
||||
#
|
||||
|
||||
#
|
||||
# I2O device support
|
||||
#
|
||||
|
||||
#
|
||||
# Network device support
|
||||
#
|
||||
# CONFIG_NETDEVICES is not set
|
||||
# CONFIG_NETPOLL is not set
|
||||
# CONFIG_NET_POLL_CONTROLLER is not set
|
||||
|
||||
#
|
||||
# ISDN subsystem
|
||||
#
|
||||
# CONFIG_ISDN is not set
|
||||
|
||||
#
|
||||
# Telephony Support
|
||||
#
|
||||
# CONFIG_PHONE is not set
|
||||
|
||||
#
|
||||
# Input device support
|
||||
#
|
||||
# CONFIG_INPUT is not set
|
||||
|
||||
#
|
||||
# Hardware I/O ports
|
||||
#
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_GAMEPORT is not set
|
||||
|
||||
#
|
||||
# Character devices
|
||||
#
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
#
|
||||
# CONFIG_SERIAL_8250 is not set
|
||||
|
||||
#
|
||||
# Non-8250 serial port support
|
||||
#
|
||||
CONFIG_SERIAL_SH_SCI=y
|
||||
CONFIG_SERIAL_SH_SCI_NR_UARTS=4
|
||||
CONFIG_SERIAL_SH_SCI_CONSOLE=y
|
||||
CONFIG_SERIAL_CORE=y
|
||||
CONFIG_SERIAL_CORE_CONSOLE=y
|
||||
# CONFIG_UNIX98_PTYS is not set
|
||||
CONFIG_LEGACY_PTYS=y
|
||||
CONFIG_LEGACY_PTY_COUNT=256
|
||||
|
||||
#
|
||||
# IPMI
|
||||
#
|
||||
# CONFIG_IPMI_HANDLER is not set
|
||||
|
||||
#
|
||||
# Watchdog Cards
|
||||
#
|
||||
# CONFIG_WATCHDOG is not set
|
||||
CONFIG_HW_RANDOM=y
|
||||
# CONFIG_GEN_RTC is not set
|
||||
# CONFIG_DTLK is not set
|
||||
# CONFIG_R3964 is not set
|
||||
|
||||
#
|
||||
# Ftape, the floppy tape device driver
|
||||
#
|
||||
# CONFIG_RAW_DRIVER is not set
|
||||
|
||||
#
|
||||
# TPM devices
|
||||
#
|
||||
# CONFIG_TCG_TPM is not set
|
||||
|
||||
#
|
||||
# I2C support
|
||||
#
|
||||
# CONFIG_I2C is not set
|
||||
|
||||
#
|
||||
# SPI support
|
||||
#
|
||||
# CONFIG_SPI is not set
|
||||
# CONFIG_SPI_MASTER is not set
|
||||
|
||||
#
|
||||
# Dallas's 1-wire bus
|
||||
#
|
||||
# CONFIG_W1 is not set
|
||||
|
||||
#
|
||||
# Hardware Monitoring support
|
||||
#
|
||||
CONFIG_HWMON=y
|
||||
# CONFIG_HWMON_VID is not set
|
||||
# CONFIG_SENSORS_ABITUGURU is not set
|
||||
# CONFIG_SENSORS_F71805F is not set
|
||||
# CONFIG_SENSORS_VT1211 is not set
|
||||
# CONFIG_HWMON_DEBUG_CHIP is not set
|
||||
|
||||
#
|
||||
# Multimedia devices
|
||||
#
|
||||
# CONFIG_VIDEO_DEV is not set
|
||||
|
||||
#
|
||||
# Digital Video Broadcasting Devices
|
||||
#
|
||||
# CONFIG_DVB is not set
|
||||
|
||||
#
|
||||
# Graphics support
|
||||
#
|
||||
CONFIG_FIRMWARE_EDID=y
|
||||
# CONFIG_FB is not set
|
||||
|
||||
#
|
||||
# Sound
|
||||
#
|
||||
# CONFIG_SOUND is not set
|
||||
|
||||
#
|
||||
# USB support
|
||||
#
|
||||
# CONFIG_USB_ARCH_HAS_HCD is not set
|
||||
# CONFIG_USB_ARCH_HAS_OHCI is not set
|
||||
# CONFIG_USB_ARCH_HAS_EHCI is not set
|
||||
|
||||
#
|
||||
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
|
||||
#
|
||||
|
||||
#
|
||||
# USB Gadget Support
|
||||
#
|
||||
# CONFIG_USB_GADGET is not set
|
||||
|
||||
#
|
||||
# MMC/SD Card support
|
||||
#
|
||||
# CONFIG_MMC is not set
|
||||
|
||||
#
|
||||
# LED devices
|
||||
#
|
||||
# CONFIG_NEW_LEDS is not set
|
||||
|
||||
#
|
||||
# LED drivers
|
||||
#
|
||||
|
||||
#
|
||||
# LED Triggers
|
||||
#
|
||||
|
||||
#
|
||||
# InfiniBand support
|
||||
#
|
||||
|
||||
#
|
||||
# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
|
||||
#
|
||||
|
||||
#
|
||||
# Real Time Clock
|
||||
#
|
||||
# CONFIG_RTC_CLASS is not set
|
||||
|
||||
#
|
||||
# DMA Engine support
|
||||
#
|
||||
# CONFIG_DMA_ENGINE is not set
|
||||
|
||||
#
|
||||
# DMA Clients
|
||||
#
|
||||
|
||||
#
|
||||
# DMA Devices
|
||||
#
|
||||
|
||||
#
|
||||
# File systems
|
||||
#
|
||||
CONFIG_EXT2_FS=y
|
||||
# CONFIG_EXT2_FS_XATTR is not set
|
||||
# CONFIG_EXT3_FS is not set
|
||||
# CONFIG_EXT4DEV_FS is not set
|
||||
# CONFIG_REISERFS_FS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
# CONFIG_FS_POSIX_ACL is not set
|
||||
# CONFIG_XFS_FS is not set
|
||||
# CONFIG_GFS2_FS is not set
|
||||
# CONFIG_MINIX_FS is not set
|
||||
CONFIG_ROMFS_FS=y
|
||||
# CONFIG_INOTIFY is not set
|
||||
# CONFIG_QUOTA is not set
|
||||
# CONFIG_DNOTIFY is not set
|
||||
# CONFIG_AUTOFS_FS is not set
|
||||
# CONFIG_AUTOFS4_FS is not set
|
||||
# CONFIG_FUSE_FS is not set
|
||||
|
||||
#
|
||||
# CD-ROM/DVD Filesystems
|
||||
#
|
||||
# CONFIG_ISO9660_FS is not set
|
||||
# CONFIG_UDF_FS is not set
|
||||
|
||||
#
|
||||
# DOS/FAT/NT Filesystems
|
||||
#
|
||||
# CONFIG_MSDOS_FS is not set
|
||||
# CONFIG_VFAT_FS is not set
|
||||
# CONFIG_NTFS_FS is not set
|
||||
|
||||
#
|
||||
# Pseudo filesystems
|
||||
#
|
||||
CONFIG_PROC_FS=y
|
||||
CONFIG_PROC_SYSCTL=y
|
||||
# CONFIG_SYSFS is not set
|
||||
# CONFIG_TMPFS is not set
|
||||
# CONFIG_HUGETLBFS is not set
|
||||
# CONFIG_HUGETLB_PAGE is not set
|
||||
CONFIG_RAMFS=y
|
||||
|
||||
#
|
||||
# Miscellaneous filesystems
|
||||
#
|
||||
# CONFIG_ADFS_FS is not set
|
||||
# CONFIG_AFFS_FS is not set
|
||||
# CONFIG_HFS_FS is not set
|
||||
# CONFIG_HFSPLUS_FS is not set
|
||||
# CONFIG_BEFS_FS is not set
|
||||
# CONFIG_BFS_FS is not set
|
||||
# CONFIG_EFS_FS is not set
|
||||
# CONFIG_JFFS_FS is not set
|
||||
# CONFIG_JFFS2_FS is not set
|
||||
CONFIG_CRAMFS=y
|
||||
# CONFIG_VXFS_FS is not set
|
||||
# CONFIG_HPFS_FS is not set
|
||||
# CONFIG_QNX4FS_FS is not set
|
||||
# CONFIG_SYSV_FS is not set
|
||||
# CONFIG_UFS_FS is not set
|
||||
|
||||
#
|
||||
# Network File Systems
|
||||
#
|
||||
# CONFIG_NFS_FS is not set
|
||||
# CONFIG_NFSD is not set
|
||||
# CONFIG_SMB_FS is not set
|
||||
# CONFIG_CIFS is not set
|
||||
# CONFIG_NCP_FS is not set
|
||||
# CONFIG_CODA_FS is not set
|
||||
# CONFIG_AFS_FS is not set
|
||||
# CONFIG_9P_FS is not set
|
||||
|
||||
#
|
||||
# Partition Types
|
||||
#
|
||||
# CONFIG_PARTITION_ADVANCED is not set
|
||||
CONFIG_MSDOS_PARTITION=y
|
||||
|
||||
#
|
||||
# Native Language Support
|
||||
#
|
||||
# CONFIG_NLS is not set
|
||||
|
||||
#
|
||||
# Profiling support
|
||||
#
|
||||
# CONFIG_PROFILING is not set
|
||||
|
||||
#
|
||||
# Kernel hacking
|
||||
#
|
||||
# CONFIG_PRINTK_TIME is not set
|
||||
CONFIG_ENABLE_MUST_CHECK=y
|
||||
# CONFIG_MAGIC_SYSRQ is not set
|
||||
# CONFIG_UNUSED_SYMBOLS is not set
|
||||
# CONFIG_DEBUG_KERNEL is not set
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
# CONFIG_DEBUG_BUGVERBOSE is not set
|
||||
# CONFIG_UNWIND_INFO is not set
|
||||
# CONFIG_HEADERS_CHECK is not set
|
||||
# CONFIG_SH_STANDARD_BIOS is not set
|
||||
# CONFIG_EARLY_SCIF_CONSOLE is not set
|
||||
# CONFIG_KGDB is not set
|
||||
|
||||
#
|
||||
# Security options
|
||||
#
|
||||
# CONFIG_KEYS is not set
|
||||
|
||||
#
|
||||
# Cryptographic options
|
||||
#
|
||||
# CONFIG_CRYPTO is not set
|
||||
|
||||
#
|
||||
# Library routines
|
||||
#
|
||||
CONFIG_CRC_CCITT=y
|
||||
# CONFIG_CRC16 is not set
|
||||
CONFIG_CRC32=y
|
||||
# CONFIG_LIBCRC32C is not set
|
||||
CONFIG_ZLIB_INFLATE=y
|
9
arch/sh/drivers/Kconfig
Normal file
9
arch/sh/drivers/Kconfig
Normal file
@ -0,0 +1,9 @@
|
||||
menu "Additional SuperH Device Drivers"
|
||||
|
||||
config PUSH_SWITCH
|
||||
tristate "Push switch support"
|
||||
help
|
||||
This enables support for the push switch framework, a simple
|
||||
framework that allows for sysfs driven switch status reporting.
|
||||
|
||||
endmenu
|
@ -5,4 +5,4 @@
|
||||
obj-$(CONFIG_PCI) += pci/
|
||||
obj-$(CONFIG_SH_DMA) += dma/
|
||||
obj-$(CONFIG_SUPERHYWAY) += superhyway/
|
||||
|
||||
obj-$(CONFIG_PUSH_SWITCH) += push-switch.o
|
||||
|
@ -2,8 +2,8 @@
|
||||
# Makefile for the SuperH DMA specific kernel interface routines under Linux.
|
||||
#
|
||||
|
||||
obj-y += dma-api.o dma-isa.o
|
||||
obj-y += dma-api.o
|
||||
obj-$(CONFIG_ISA_DMA_API) += dma-isa.o
|
||||
obj-$(CONFIG_SYSFS) += dma-sysfs.o
|
||||
obj-$(CONFIG_SH_DMA) += dma-sh.o
|
||||
obj-$(CONFIG_SH_DREAMCAST) += dma-pvr2.o dma-g2.o
|
||||
|
||||
|
@ -11,61 +11,27 @@
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/dma.h>
|
||||
|
||||
DEFINE_SPINLOCK(dma_spin_lock);
|
||||
static LIST_HEAD(registered_dmac_list);
|
||||
|
||||
/*
|
||||
* A brief note about the reasons for this API as it stands.
|
||||
*
|
||||
* For starters, the old ISA DMA API didn't work for us for a number of
|
||||
* reasons, for one, the vast majority of channels on the SH DMAC are
|
||||
* dual-address mode only, and both the new and the old DMA APIs are after the
|
||||
* concept of managing a DMA buffer, which doesn't overly fit this model very
|
||||
* well. In addition to which, the new API is largely geared at IOMMUs and
|
||||
* GARTs, and doesn't even support the channel notion very well.
|
||||
*
|
||||
* The other thing that's a marginal issue, is the sheer number of random DMA
|
||||
* engines that are present (ie, in boards like the Dreamcast), some of which
|
||||
* cascade off of the SH DMAC, and others do not. As such, there was a real
|
||||
* need for a scalable subsystem that could deal with both single and
|
||||
* dual-address mode usage, in addition to interoperating with cascaded DMACs.
|
||||
*
|
||||
* There really isn't any reason why this needs to be SH specific, though I'm
|
||||
* not aware of too many other processors (with the exception of some MIPS)
|
||||
* that have the same concept of a dual address mode, or any real desire to
|
||||
* actually make use of the DMAC even if such a subsystem were exposed
|
||||
* elsewhere.
|
||||
*
|
||||
* The idea for this was derived from the ARM port, which acted as an excellent
|
||||
* reference when trying to address these issues.
|
||||
*
|
||||
* It should also be noted that the decision to add Yet Another DMA API(tm) to
|
||||
* the kernel wasn't made easily, and was only decided upon after conferring
|
||||
* with jejb with regards to the state of the old and new APIs as they applied
|
||||
* to these circumstances. Philip Blundell was also a great help in figuring
|
||||
* out some single-address mode DMA semantics that were otherwise rather
|
||||
* confusing.
|
||||
*/
|
||||
|
||||
struct dma_info *get_dma_info(unsigned int chan)
|
||||
{
|
||||
struct dma_info *info;
|
||||
unsigned int total = 0;
|
||||
|
||||
/*
|
||||
* Look for each DMAC's range to determine who the owner of
|
||||
* the channel is.
|
||||
*/
|
||||
list_for_each_entry(info, ®istered_dmac_list, list) {
|
||||
total += info->nr_channels;
|
||||
if (chan > total)
|
||||
if ((chan < info->first_channel_nr) ||
|
||||
(chan >= info->first_channel_nr + info->nr_channels))
|
||||
continue;
|
||||
|
||||
return info;
|
||||
@ -73,6 +39,22 @@ struct dma_info *get_dma_info(unsigned int chan)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(get_dma_info);
|
||||
|
||||
struct dma_info *get_dma_info_by_name(const char *dmac_name)
|
||||
{
|
||||
struct dma_info *info;
|
||||
|
||||
list_for_each_entry(info, ®istered_dmac_list, list) {
|
||||
if (dmac_name && (strcmp(dmac_name, info->name) != 0))
|
||||
continue;
|
||||
else
|
||||
return info;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(get_dma_info_by_name);
|
||||
|
||||
static unsigned int get_nr_channels(void)
|
||||
{
|
||||
@ -91,63 +73,161 @@ static unsigned int get_nr_channels(void)
|
||||
struct dma_channel *get_dma_channel(unsigned int chan)
|
||||
{
|
||||
struct dma_info *info = get_dma_info(chan);
|
||||
struct dma_channel *channel;
|
||||
int i;
|
||||
|
||||
if (!info)
|
||||
if (unlikely(!info))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
return info->channels + chan;
|
||||
for (i = 0; i < info->nr_channels; i++) {
|
||||
channel = &info->channels[i];
|
||||
if (channel->chan == chan)
|
||||
return channel;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(get_dma_channel);
|
||||
|
||||
int get_dma_residue(unsigned int chan)
|
||||
{
|
||||
struct dma_info *info = get_dma_info(chan);
|
||||
struct dma_channel *channel = &info->channels[chan];
|
||||
struct dma_channel *channel = get_dma_channel(chan);
|
||||
|
||||
if (info->ops->get_residue)
|
||||
return info->ops->get_residue(channel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(get_dma_residue);
|
||||
|
||||
int request_dma(unsigned int chan, const char *dev_id)
|
||||
static int search_cap(const char **haystack, const char *needle)
|
||||
{
|
||||
struct dma_info *info = get_dma_info(chan);
|
||||
struct dma_channel *channel = &info->channels[chan];
|
||||
const char **p;
|
||||
|
||||
down(&channel->sem);
|
||||
|
||||
if (!info->ops || chan >= MAX_DMA_CHANNELS) {
|
||||
up(&channel->sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
atomic_set(&channel->busy, 1);
|
||||
|
||||
strlcpy(channel->dev_id, dev_id, sizeof(channel->dev_id));
|
||||
|
||||
up(&channel->sem);
|
||||
|
||||
if (info->ops->request)
|
||||
return info->ops->request(channel);
|
||||
for (p = haystack; *p; p++)
|
||||
if (strcmp(*p, needle) == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* request_dma_bycap - Allocate a DMA channel based on its capabilities
|
||||
* @dmac: List of DMA controllers to search
|
||||
* @caps: List of capabilites
|
||||
*
|
||||
* Search all channels of all DMA controllers to find a channel which
|
||||
* matches the requested capabilities. The result is the channel
|
||||
* number if a match is found, or %-ENODEV if no match is found.
|
||||
*
|
||||
* Note that not all DMA controllers export capabilities, in which
|
||||
* case they can never be allocated using this API, and so
|
||||
* request_dma() must be used specifying the channel number.
|
||||
*/
|
||||
int request_dma_bycap(const char **dmac, const char **caps, const char *dev_id)
|
||||
{
|
||||
unsigned int found = 0;
|
||||
struct dma_info *info;
|
||||
const char **p;
|
||||
int i;
|
||||
|
||||
BUG_ON(!dmac || !caps);
|
||||
|
||||
list_for_each_entry(info, ®istered_dmac_list, list)
|
||||
if (strcmp(*dmac, info->name) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < info->nr_channels; i++) {
|
||||
struct dma_channel *channel = &info->channels[i];
|
||||
|
||||
if (unlikely(!channel->caps))
|
||||
continue;
|
||||
|
||||
for (p = caps; *p; p++) {
|
||||
if (!search_cap(channel->caps, *p))
|
||||
break;
|
||||
if (request_dma(channel->chan, dev_id) == 0)
|
||||
return channel->chan;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL(request_dma_bycap);
|
||||
|
||||
int dmac_search_free_channel(const char *dev_id)
|
||||
{
|
||||
struct dma_channel *channel = { 0 };
|
||||
struct dma_info *info = get_dma_info(0);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < info->nr_channels; i++) {
|
||||
channel = &info->channels[i];
|
||||
if (unlikely(!channel))
|
||||
return -ENODEV;
|
||||
|
||||
if (atomic_read(&channel->busy) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (info->ops->request) {
|
||||
int result = info->ops->request(channel);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
atomic_set(&channel->busy, 1);
|
||||
return channel->chan;
|
||||
}
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int request_dma(unsigned int chan, const char *dev_id)
|
||||
{
|
||||
struct dma_channel *channel = { 0 };
|
||||
struct dma_info *info = get_dma_info(chan);
|
||||
int result;
|
||||
|
||||
channel = get_dma_channel(chan);
|
||||
if (atomic_xchg(&channel->busy, 1))
|
||||
return -EBUSY;
|
||||
|
||||
strlcpy(channel->dev_id, dev_id, sizeof(channel->dev_id));
|
||||
|
||||
if (info->ops->request) {
|
||||
result = info->ops->request(channel);
|
||||
if (result)
|
||||
atomic_set(&channel->busy, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(request_dma);
|
||||
|
||||
void free_dma(unsigned int chan)
|
||||
{
|
||||
struct dma_info *info = get_dma_info(chan);
|
||||
struct dma_channel *channel = &info->channels[chan];
|
||||
struct dma_channel *channel = get_dma_channel(chan);
|
||||
|
||||
if (info->ops->free)
|
||||
info->ops->free(channel);
|
||||
|
||||
atomic_set(&channel->busy, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(free_dma);
|
||||
|
||||
void dma_wait_for_completion(unsigned int chan)
|
||||
{
|
||||
struct dma_info *info = get_dma_info(chan);
|
||||
struct dma_channel *channel = &info->channels[chan];
|
||||
struct dma_channel *channel = get_dma_channel(chan);
|
||||
|
||||
if (channel->flags & DMA_TEI_CAPABLE) {
|
||||
wait_event(channel->wait_queue,
|
||||
@ -158,21 +238,52 @@ void dma_wait_for_completion(unsigned int chan)
|
||||
while (info->ops->get_residue(channel))
|
||||
cpu_relax();
|
||||
}
|
||||
EXPORT_SYMBOL(dma_wait_for_completion);
|
||||
|
||||
int register_chan_caps(const char *dmac, struct dma_chan_caps *caps)
|
||||
{
|
||||
struct dma_info *info;
|
||||
unsigned int found = 0;
|
||||
int i;
|
||||
|
||||
list_for_each_entry(info, ®istered_dmac_list, list)
|
||||
if (strcmp(dmac, info->name) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlikely(!found))
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < info->nr_channels; i++, caps++) {
|
||||
struct dma_channel *channel;
|
||||
|
||||
if ((info->first_channel_nr + i) != caps->ch_num)
|
||||
return -EINVAL;
|
||||
|
||||
channel = &info->channels[i];
|
||||
channel->caps = caps->caplist;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(register_chan_caps);
|
||||
|
||||
void dma_configure_channel(unsigned int chan, unsigned long flags)
|
||||
{
|
||||
struct dma_info *info = get_dma_info(chan);
|
||||
struct dma_channel *channel = &info->channels[chan];
|
||||
struct dma_channel *channel = get_dma_channel(chan);
|
||||
|
||||
if (info->ops->configure)
|
||||
info->ops->configure(channel, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_configure_channel);
|
||||
|
||||
int dma_xfer(unsigned int chan, unsigned long from,
|
||||
unsigned long to, size_t size, unsigned int mode)
|
||||
{
|
||||
struct dma_info *info = get_dma_info(chan);
|
||||
struct dma_channel *channel = &info->channels[chan];
|
||||
struct dma_channel *channel = get_dma_channel(chan);
|
||||
|
||||
channel->sar = from;
|
||||
channel->dar = to;
|
||||
@ -181,8 +292,20 @@ int dma_xfer(unsigned int chan, unsigned long from,
|
||||
|
||||
return info->ops->xfer(channel);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_xfer);
|
||||
|
||||
int dma_extend(unsigned int chan, unsigned long op, void *param)
|
||||
{
|
||||
struct dma_info *info = get_dma_info(chan);
|
||||
struct dma_channel *channel = get_dma_channel(chan);
|
||||
|
||||
if (info->ops->extend)
|
||||
return info->ops->extend(channel, op, param);
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_extend);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static int dma_read_proc(char *buf, char **start, off_t off,
|
||||
int len, int *eof, void *data)
|
||||
{
|
||||
@ -214,8 +337,6 @@ static int dma_read_proc(char *buf, char **start, off_t off,
|
||||
|
||||
return p - buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int register_dmac(struct dma_info *info)
|
||||
{
|
||||
@ -224,8 +345,7 @@ int register_dmac(struct dma_info *info)
|
||||
INIT_LIST_HEAD(&info->list);
|
||||
|
||||
printk(KERN_INFO "DMA: Registering %s handler (%d channel%s).\n",
|
||||
info->name, info->nr_channels,
|
||||
info->nr_channels > 1 ? "s" : "");
|
||||
info->name, info->nr_channels, info->nr_channels > 1 ? "s" : "");
|
||||
|
||||
BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels);
|
||||
|
||||
@ -242,28 +362,26 @@ int register_dmac(struct dma_info *info)
|
||||
|
||||
size = sizeof(struct dma_channel) * info->nr_channels;
|
||||
|
||||
info->channels = kmalloc(size, GFP_KERNEL);
|
||||
info->channels = kzalloc(size, GFP_KERNEL);
|
||||
if (!info->channels)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(info->channels, 0, size);
|
||||
}
|
||||
|
||||
total_channels = get_nr_channels();
|
||||
for (i = 0; i < info->nr_channels; i++) {
|
||||
struct dma_channel *chan = info->channels + i;
|
||||
struct dma_channel *chan = &info->channels[i];
|
||||
|
||||
chan->chan = i;
|
||||
chan->vchan = i + total_channels;
|
||||
atomic_set(&chan->busy, 0);
|
||||
|
||||
chan->chan = info->first_channel_nr + i;
|
||||
chan->vchan = info->first_channel_nr + i + total_channels;
|
||||
|
||||
memcpy(chan->dev_id, "Unused", 7);
|
||||
|
||||
if (info->flags & DMAC_CHANNELS_TEI_CAPABLE)
|
||||
chan->flags |= DMA_TEI_CAPABLE;
|
||||
|
||||
init_MUTEX(&chan->sem);
|
||||
init_waitqueue_head(&chan->wait_queue);
|
||||
|
||||
dma_create_sysfs_files(chan, info);
|
||||
}
|
||||
|
||||
@ -271,6 +389,7 @@ int register_dmac(struct dma_info *info)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(register_dmac);
|
||||
|
||||
void unregister_dmac(struct dma_info *info)
|
||||
{
|
||||
@ -285,31 +404,16 @@ void unregister_dmac(struct dma_info *info)
|
||||
list_del(&info->list);
|
||||
platform_device_unregister(info->pdev);
|
||||
}
|
||||
EXPORT_SYMBOL(unregister_dmac);
|
||||
|
||||
static int __init dma_api_init(void)
|
||||
{
|
||||
printk("DMA: Registering DMA API.\n");
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
printk(KERN_NOTICE "DMA: Registering DMA API.\n");
|
||||
create_proc_read_entry("dma", 0, 0, dma_read_proc, 0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(dma_api_init);
|
||||
|
||||
MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
|
||||
MODULE_DESCRIPTION("DMA API for SuperH");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
EXPORT_SYMBOL(request_dma);
|
||||
EXPORT_SYMBOL(free_dma);
|
||||
EXPORT_SYMBOL(register_dmac);
|
||||
EXPORT_SYMBOL(get_dma_residue);
|
||||
EXPORT_SYMBOL(get_dma_info);
|
||||
EXPORT_SYMBOL(get_dma_channel);
|
||||
EXPORT_SYMBOL(dma_xfer);
|
||||
EXPORT_SYMBOL(dma_wait_for_completion);
|
||||
EXPORT_SYMBOL(dma_configure_channel);
|
||||
|
||||
|
@ -94,20 +94,13 @@ static int sh_dmac_request_dma(struct dma_channel *chan)
|
||||
if (unlikely(!chan->flags & DMA_TEI_CAPABLE))
|
||||
return 0;
|
||||
|
||||
chan->name = kzalloc(32, GFP_KERNEL);
|
||||
if (unlikely(chan->name == NULL))
|
||||
return -ENOMEM;
|
||||
snprintf(chan->name, 32, "DMAC Transfer End (Channel %d)",
|
||||
chan->chan);
|
||||
|
||||
return request_irq(get_dmte_irq(chan->chan), dma_tei,
|
||||
IRQF_DISABLED, chan->name, chan);
|
||||
IRQF_DISABLED, chan->dev_id, chan);
|
||||
}
|
||||
|
||||
static void sh_dmac_free_dma(struct dma_channel *chan)
|
||||
{
|
||||
free_irq(get_dmte_irq(chan->chan), chan);
|
||||
kfree(chan->name);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* sysfs interface for SH DMA API
|
||||
*
|
||||
* Copyright (C) 2004, 2005 Paul Mundt
|
||||
* Copyright (C) 2004 - 2006 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
|
||||
@ -21,7 +21,6 @@
|
||||
static struct sysdev_class dma_sysclass = {
|
||||
set_kset_name("dma"),
|
||||
};
|
||||
|
||||
EXPORT_SYMBOL(dma_sysclass);
|
||||
|
||||
static ssize_t dma_show_devices(struct sys_device *dev, char *buf)
|
||||
@ -31,7 +30,10 @@ static ssize_t dma_show_devices(struct sys_device *dev, char *buf)
|
||||
|
||||
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
|
||||
struct dma_info *info = get_dma_info(i);
|
||||
struct dma_channel *channel = &info->channels[i];
|
||||
struct dma_channel *channel = get_dma_channel(i);
|
||||
|
||||
if (unlikely(!info) || !channel)
|
||||
continue;
|
||||
|
||||
len += sprintf(buf + len, "%2d: %14s %s\n",
|
||||
channel->chan, info->name,
|
||||
@ -125,11 +127,16 @@ int dma_create_sysfs_files(struct dma_channel *chan, struct dma_info *info)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
sysdev_create_file(dev, &attr_dev_id);
|
||||
sysdev_create_file(dev, &attr_count);
|
||||
sysdev_create_file(dev, &attr_mode);
|
||||
sysdev_create_file(dev, &attr_flags);
|
||||
sysdev_create_file(dev, &attr_config);
|
||||
ret |= sysdev_create_file(dev, &attr_dev_id);
|
||||
ret |= sysdev_create_file(dev, &attr_count);
|
||||
ret |= sysdev_create_file(dev, &attr_mode);
|
||||
ret |= sysdev_create_file(dev, &attr_flags);
|
||||
ret |= sysdev_create_file(dev, &attr_config);
|
||||
|
||||
if (unlikely(ret)) {
|
||||
dev_err(&info->pdev->dev, "Failed creating attrs\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "dma%d", chan->chan);
|
||||
return sysfs_create_link(&info->pdev->dev.kobj, &dev->kobj, name);
|
||||
|
@ -15,25 +15,21 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/titan.h>
|
||||
#include "pci-sh4.h"
|
||||
|
||||
static char titan_irq_tab[] __initdata = {
|
||||
TITAN_IRQ_WAN,
|
||||
TITAN_IRQ_LAN,
|
||||
TITAN_IRQ_MPCIA,
|
||||
TITAN_IRQ_MPCIB,
|
||||
TITAN_IRQ_USB,
|
||||
};
|
||||
|
||||
int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
|
||||
{
|
||||
int irq = -1;
|
||||
|
||||
switch (slot) {
|
||||
case 0: irq = TITAN_IRQ_WAN; break; /* eth0 (WAN) */
|
||||
case 1: irq = TITAN_IRQ_LAN; break; /* eth1 (LAN) */
|
||||
case 2: irq = TITAN_IRQ_MPCIA; break; /* mPCI A */
|
||||
case 3: irq = TITAN_IRQ_MPCIB; break; /* mPCI B */
|
||||
case 4: irq = TITAN_IRQ_USB; break; /* USB */
|
||||
default:
|
||||
printk(KERN_INFO "PCI: Bad IRQ mapping "
|
||||
"request for slot %d\n", slot);
|
||||
return -1;
|
||||
}
|
||||
int irq = titan_irq_tab[slot];
|
||||
|
||||
printk("PCI: Mapping TITAN IRQ for slot %d, pin %c to irq %d\n",
|
||||
slot, pin - 1 + 'A', irq);
|
||||
|
@ -22,6 +22,20 @@
|
||||
#include <linux/delay.h>
|
||||
#include "pci-sh4.h"
|
||||
|
||||
#define INTC_BASE 0xffd00000
|
||||
#define INTC_ICR0 (INTC_BASE+0x0)
|
||||
#define INTC_ICR1 (INTC_BASE+0x1c)
|
||||
#define INTC_INTPRI (INTC_BASE+0x10)
|
||||
#define INTC_INTREQ (INTC_BASE+0x24)
|
||||
#define INTC_INTMSK0 (INTC_BASE+0x44)
|
||||
#define INTC_INTMSK1 (INTC_BASE+0x48)
|
||||
#define INTC_INTMSK2 (INTC_BASE+0x40080)
|
||||
#define INTC_INTMSKCLR0 (INTC_BASE+0x64)
|
||||
#define INTC_INTMSKCLR1 (INTC_BASE+0x68)
|
||||
#define INTC_INTMSKCLR2 (INTC_BASE+0x40084)
|
||||
#define INTC_INT2MSKR (INTC_BASE+0x40038)
|
||||
#define INTC_INT2MSKCR (INTC_BASE+0x4003c)
|
||||
|
||||
/*
|
||||
* Initialization. Try all known PCI access methods. Note that we support
|
||||
* using both PCI BIOS and direct access: in such cases, we use I/O ports
|
||||
|
138
arch/sh/drivers/push-switch.c
Normal file
138
arch/sh/drivers/push-switch.c
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Generic push-switch framework
|
||||
*
|
||||
* Copyright (C) 2006 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/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/push-switch.h>
|
||||
|
||||
#define DRV_NAME "push-switch"
|
||||
#define DRV_VERSION "0.1.0"
|
||||
|
||||
static ssize_t switch_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct push_switch_platform_info *psw_info = dev->platform_data;
|
||||
return sprintf(buf, "%s\n", psw_info->name);
|
||||
}
|
||||
static DEVICE_ATTR(switch, S_IRUGO, switch_show, NULL);
|
||||
|
||||
static void switch_timer(unsigned long data)
|
||||
{
|
||||
struct push_switch *psw = (struct push_switch *)data;
|
||||
|
||||
schedule_work(&psw->work);
|
||||
}
|
||||
|
||||
static void switch_work_handler(void *data)
|
||||
{
|
||||
struct platform_device *pdev = data;
|
||||
struct push_switch *psw = platform_get_drvdata(pdev);
|
||||
|
||||
psw->state = 0;
|
||||
|
||||
kobject_uevent(&pdev->dev.kobj, KOBJ_CHANGE);
|
||||
}
|
||||
|
||||
static int switch_drv_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct push_switch_platform_info *psw_info;
|
||||
struct push_switch *psw;
|
||||
int ret, irq;
|
||||
|
||||
psw = kzalloc(sizeof(struct push_switch), GFP_KERNEL);
|
||||
if (unlikely(!psw))
|
||||
return -ENOMEM;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (unlikely(irq < 0)) {
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
psw_info = pdev->dev.platform_data;
|
||||
BUG_ON(!psw_info);
|
||||
|
||||
ret = request_irq(irq, psw_info->irq_handler,
|
||||
IRQF_DISABLED | psw_info->irq_flags,
|
||||
psw_info->name ? psw_info->name : DRV_NAME, pdev);
|
||||
if (unlikely(ret < 0))
|
||||
goto err;
|
||||
|
||||
if (psw_info->name) {
|
||||
ret = device_create_file(&pdev->dev, &dev_attr_switch);
|
||||
if (unlikely(ret)) {
|
||||
dev_err(&pdev->dev, "Failed creating device attrs\n");
|
||||
ret = -EINVAL;
|
||||
goto err_irq;
|
||||
}
|
||||
}
|
||||
|
||||
INIT_WORK(&psw->work, switch_work_handler, pdev);
|
||||
init_timer(&psw->debounce);
|
||||
|
||||
psw->debounce.function = switch_timer;
|
||||
psw->debounce.data = (unsigned long)psw;
|
||||
|
||||
platform_set_drvdata(pdev, psw);
|
||||
|
||||
return 0;
|
||||
|
||||
err_irq:
|
||||
free_irq(irq, pdev);
|
||||
err:
|
||||
kfree(psw);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int switch_drv_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct push_switch *psw = platform_get_drvdata(pdev);
|
||||
struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
|
||||
int irq = platform_get_irq(pdev, 0);
|
||||
|
||||
if (psw_info->name)
|
||||
device_remove_file(&pdev->dev, &dev_attr_switch);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
flush_scheduled_work();
|
||||
del_timer_sync(&psw->debounce);
|
||||
free_irq(irq, pdev);
|
||||
|
||||
kfree(psw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver switch_driver = {
|
||||
.probe = switch_drv_probe,
|
||||
.remove = switch_drv_remove,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init switch_init(void)
|
||||
{
|
||||
printk(KERN_NOTICE DRV_NAME ": version %s loaded\n", DRV_VERSION);
|
||||
return platform_driver_register(&switch_driver);
|
||||
}
|
||||
|
||||
static void __exit switch_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&switch_driver);
|
||||
}
|
||||
module_init(switch_init);
|
||||
module_exit(switch_exit);
|
||||
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_AUTHOR("Paul Mundt");
|
||||
MODULE_LICENSE("GPLv2");
|
@ -4,7 +4,7 @@
|
||||
|
||||
extra-y := head.o init_task.o vmlinux.lds
|
||||
|
||||
obj-y := process.o signal.o entry.o traps.o irq.o \
|
||||
obj-y := process.o signal.o traps.o irq.o \
|
||||
ptrace.o setup.o time.o sys_sh.o semaphore.o \
|
||||
io.o io_generic.o sh_ksyms.o syscalls.o
|
||||
|
||||
@ -21,3 +21,4 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
|
||||
obj-$(CONFIG_APM) += apm.o
|
||||
obj-$(CONFIG_PM) += pm.o
|
||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||
|
@ -2,11 +2,12 @@
|
||||
# Makefile for the Linux/SuperH CPU-specifc backends.
|
||||
#
|
||||
|
||||
obj-y += irq/ init.o clock.o
|
||||
|
||||
obj-$(CONFIG_CPU_SH2) += sh2/
|
||||
obj-$(CONFIG_CPU_SH3) += sh3/
|
||||
obj-$(CONFIG_CPU_SH4) += sh4/
|
||||
obj-$(CONFIG_CPU_SH2) = sh2/
|
||||
obj-$(CONFIG_CPU_SH2A) = sh2a/
|
||||
obj-$(CONFIG_CPU_SH3) = sh3/
|
||||
obj-$(CONFIG_CPU_SH4) = sh4/
|
||||
|
||||
obj-$(CONFIG_UBC_WAKEUP) += ubc.o
|
||||
obj-$(CONFIG_SH_ADC) += adc.o
|
||||
|
||||
obj-y += irq/ init.o clock.o
|
||||
|
@ -5,9 +5,11 @@
|
||||
*
|
||||
* This clock framework is derived from the OMAP version by:
|
||||
*
|
||||
* Copyright (C) 2004 Nokia Corporation
|
||||
* Copyright (C) 2004 - 2005 Nokia Corporation
|
||||
* Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
|
||||
*
|
||||
* Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
|
||||
*
|
||||
* 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.
|
||||
@ -20,6 +22,7 @@
|
||||
#include <linux/kref.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/clock.h>
|
||||
#include <asm/timer.h>
|
||||
|
||||
@ -195,17 +198,37 @@ void clk_recalc_rate(struct clk *clk)
|
||||
propagate_rate(clk);
|
||||
}
|
||||
|
||||
struct clk *clk_get(const char *id)
|
||||
/*
|
||||
* Returns a clock. Note that we first try to use device id on the bus
|
||||
* and clock name. If this fails, we try to use clock name only.
|
||||
*/
|
||||
struct clk *clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
struct clk *p, *clk = ERR_PTR(-ENOENT);
|
||||
int idno;
|
||||
|
||||
if (dev == NULL || dev->bus != &platform_bus_type)
|
||||
idno = -1;
|
||||
else
|
||||
idno = to_platform_device(dev)->id;
|
||||
|
||||
mutex_lock(&clock_list_sem);
|
||||
list_for_each_entry(p, &clock_list, node) {
|
||||
if (p->id == idno &&
|
||||
strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
|
||||
clk = p;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(p, &clock_list, node) {
|
||||
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
|
||||
clk = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
found:
|
||||
mutex_unlock(&clock_list_sem);
|
||||
|
||||
return clk;
|
||||
|
@ -68,12 +68,14 @@ static void __init cache_init(void)
|
||||
|
||||
waysize = cpu_data->dcache.sets;
|
||||
|
||||
#ifdef CCR_CACHE_ORA
|
||||
/*
|
||||
* If the OC is already in RAM mode, we only have
|
||||
* half of the entries to flush..
|
||||
*/
|
||||
if (ccr & CCR_CACHE_ORA)
|
||||
waysize >>= 1;
|
||||
#endif
|
||||
|
||||
waysize <<= cpu_data->dcache.entry_shift;
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
#
|
||||
# Makefile for the Linux/SuperH CPU-specifc IRQ handlers.
|
||||
#
|
||||
obj-y += ipr.o imask.o
|
||||
obj-y += imask.o
|
||||
|
||||
obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o
|
||||
obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o
|
||||
obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o
|
||||
obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o
|
||||
|
@ -53,7 +53,10 @@ void static inline set_interrupt_registers(int ip)
|
||||
{
|
||||
unsigned long __dummy;
|
||||
|
||||
asm volatile("ldc %2, r6_bank\n\t"
|
||||
asm volatile(
|
||||
#ifdef CONFIG_CPU_HAS_SR_RB
|
||||
"ldc %2, r6_bank\n\t"
|
||||
#endif
|
||||
"stc sr, %0\n\t"
|
||||
"and #0xf0, %0\n\t"
|
||||
"shlr2 %0\n\t"
|
||||
|
@ -11,22 +11,29 @@
|
||||
* Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7760)
|
||||
#define INTC2_BASE 0xfe080000
|
||||
#define INTC2_INTMSK (INTC2_BASE + 0x40)
|
||||
#define INTC2_INTMSKCLR (INTC2_BASE + 0x60)
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
|
||||
#define INTC2_BASE 0xffd40000
|
||||
#define INTC2_INTMSK (INTC2_BASE + 0x38)
|
||||
#define INTC2_INTMSKCLR (INTC2_BASE + 0x3c)
|
||||
#endif
|
||||
|
||||
static void disable_intc2_irq(unsigned int irq)
|
||||
{
|
||||
struct intc2_data *p = get_irq_chip_data(irq);
|
||||
ctrl_outl(1 << p->msk_shift,
|
||||
INTC2_BASE + INTC2_INTMSK_OFFSET + p->msk_offset);
|
||||
ctrl_outl(1 << p->msk_shift, INTC2_INTMSK + p->msk_offset);
|
||||
}
|
||||
|
||||
static void enable_intc2_irq(unsigned int irq)
|
||||
{
|
||||
struct intc2_data *p = get_irq_chip_data(irq);
|
||||
ctrl_outl(1 << p->msk_shift,
|
||||
INTC2_BASE + INTC2_INTMSKCLR_OFFSET + p->msk_offset);
|
||||
ctrl_outl(1 << p->msk_shift, INTC2_INTMSKCLR + p->msk_offset);
|
||||
}
|
||||
|
||||
static struct irq_chip intc2_irq_chip = {
|
||||
@ -61,12 +68,10 @@ void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs)
|
||||
/* Set the priority level */
|
||||
local_irq_save(flags);
|
||||
|
||||
ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET +
|
||||
p->ipr_offset);
|
||||
ipr = ctrl_inl(INTC2_BASE + p->ipr_offset);
|
||||
ipr &= ~(0xf << p->ipr_shift);
|
||||
ipr |= p->priority << p->ipr_shift;
|
||||
ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET +
|
||||
p->ipr_offset);
|
||||
ctrl_outl(ipr, INTC2_BASE + p->ipr_offset);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
|
@ -19,25 +19,21 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/machvec.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
static void disable_ipr_irq(unsigned int irq)
|
||||
{
|
||||
struct ipr_data *p = get_irq_chip_data(irq);
|
||||
int shift = p->shift*4;
|
||||
/* Set the priority in IPR to 0 */
|
||||
ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << shift)), p->addr);
|
||||
ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr);
|
||||
}
|
||||
|
||||
static void enable_ipr_irq(unsigned int irq)
|
||||
{
|
||||
struct ipr_data *p = get_irq_chip_data(irq);
|
||||
int shift = p->shift*4;
|
||||
/* Set priority in IPR back to original value */
|
||||
ctrl_outw(ctrl_inw(p->addr) | (p->priority << shift), p->addr);
|
||||
ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr);
|
||||
}
|
||||
|
||||
static struct irq_chip ipr_irq_chip = {
|
||||
@ -53,6 +49,10 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs)
|
||||
|
||||
for (i = 0; i < nr_irqs; i++) {
|
||||
unsigned int irq = table[i].irq;
|
||||
table[i].addr = map_ipridx_to_addr(table[i].ipr_idx);
|
||||
/* could the IPR index be mapped, if not we ignore this */
|
||||
if (table[i].addr == 0)
|
||||
continue;
|
||||
disable_irq_nosync(irq);
|
||||
set_irq_chip_and_handler_name(irq, &ipr_irq_chip,
|
||||
handle_level_irq, "level");
|
||||
@ -62,83 +62,6 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs)
|
||||
}
|
||||
EXPORT_SYMBOL(make_ipr_irq);
|
||||
|
||||
static struct ipr_data sys_ipr_map[] = {
|
||||
#ifndef CONFIG_CPU_SUBTYPE_SH7780
|
||||
{ TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY },
|
||||
{ TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY },
|
||||
#ifdef RTC_IRQ
|
||||
{ RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY },
|
||||
#endif
|
||||
#ifdef SCI_ERI_IRQ
|
||||
{ SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
|
||||
{ SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
|
||||
{ SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
|
||||
#endif
|
||||
#ifdef SCIF1_ERI_IRQ
|
||||
{ SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
|
||||
{ SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
|
||||
{ SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
|
||||
{ SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7300)
|
||||
{ SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
|
||||
{ DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
|
||||
{ DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
|
||||
{ VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
|
||||
#endif
|
||||
#ifdef SCIF_ERI_IRQ
|
||||
{ SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
|
||||
{ SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
|
||||
{ SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
|
||||
{ SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
|
||||
#endif
|
||||
#ifdef IRDA_ERI_IRQ
|
||||
{ IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
|
||||
{ IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
|
||||
{ IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
|
||||
{ IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7706) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
|
||||
/*
|
||||
* Initialize the Interrupt Controller (INTC)
|
||||
* registers to their power on values
|
||||
*/
|
||||
|
||||
/*
|
||||
* Enable external irq (INTC IRQ mode).
|
||||
* You should set corresponding bits of PFC to "00"
|
||||
* to enable these interrupts.
|
||||
*/
|
||||
{ IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY },
|
||||
{ IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY },
|
||||
{ IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY },
|
||||
{ IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY },
|
||||
{ IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY },
|
||||
{ IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY },
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
make_ipr_irq(sys_ipr_map, ARRAY_SIZE(sys_ipr_map));
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_PINT_IRQ
|
||||
init_IRQ_pint();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_INTC2_IRQ
|
||||
init_IRQ_intc2();
|
||||
#endif
|
||||
/* Perform the machine specific initialisation */
|
||||
if (sh_mv.mv_init_irq != NULL)
|
||||
sh_mv.mv_init_irq();
|
||||
|
||||
irq_ctx_init(smp_processor_id());
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_CPU_HAS_PINT_IRQ)
|
||||
int ipr_irq_demux(int irq)
|
||||
{
|
||||
|
@ -2,5 +2,6 @@
|
||||
# Makefile for the Linux/SuperH SH-2 backends.
|
||||
#
|
||||
|
||||
obj-y := probe.o
|
||||
obj-y := ex.o probe.o entry.o
|
||||
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7619) += setup-sh7619.o clock-sh7619.o
|
||||
|
81
arch/sh/kernel/cpu/sh2/clock-sh7619.c
Normal file
81
arch/sh/kernel/cpu/sh2/clock-sh7619.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* arch/sh/kernel/cpu/sh2/clock-sh7619.c
|
||||
*
|
||||
* SH7619 support for the clock framework
|
||||
*
|
||||
* Copyright (C) 2006 Yoshinori Sato
|
||||
*
|
||||
* Based on clock-sh4.c
|
||||
* Copyright (C) 2005 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/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/clock.h>
|
||||
#include <asm/freq.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
const static int pll1rate[]={1,2};
|
||||
const static int pfc_divisors[]={1,2,0,4};
|
||||
|
||||
#if (CONFIG_SH_CLK_MD == 1) || (CONFIG_SH_CLK_MD == 2)
|
||||
#define PLL2 (4)
|
||||
#elif (CONFIG_SH_CLK_MD == 5) || (CONFIG_SH_CLK_MD == 6)
|
||||
#define PLL2 (2)
|
||||
#else
|
||||
#error "Illigal Clock Mode!"
|
||||
#endif
|
||||
|
||||
static void master_clk_init(struct clk *clk)
|
||||
{
|
||||
clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 7];
|
||||
}
|
||||
|
||||
static struct clk_ops sh7619_master_clk_ops = {
|
||||
.init = master_clk_init,
|
||||
};
|
||||
|
||||
static void module_clk_recalc(struct clk *clk)
|
||||
{
|
||||
int idx = (ctrl_inw(FREQCR) & 0x0007);
|
||||
clk->rate = clk->parent->rate / pfc_divisors[idx];
|
||||
}
|
||||
|
||||
static struct clk_ops sh7619_module_clk_ops = {
|
||||
.recalc = module_clk_recalc,
|
||||
};
|
||||
|
||||
static void bus_clk_recalc(struct clk *clk)
|
||||
{
|
||||
clk->rate = clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 7];
|
||||
}
|
||||
|
||||
static struct clk_ops sh7619_bus_clk_ops = {
|
||||
.recalc = bus_clk_recalc,
|
||||
};
|
||||
|
||||
static void cpu_clk_recalc(struct clk *clk)
|
||||
{
|
||||
clk->rate = clk->parent->rate;
|
||||
}
|
||||
|
||||
static struct clk_ops sh7619_cpu_clk_ops = {
|
||||
.recalc = cpu_clk_recalc,
|
||||
};
|
||||
|
||||
static struct clk_ops *sh7619_clk_ops[] = {
|
||||
&sh7619_master_clk_ops,
|
||||
&sh7619_module_clk_ops,
|
||||
&sh7619_bus_clk_ops,
|
||||
&sh7619_cpu_clk_ops,
|
||||
};
|
||||
|
||||
void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
|
||||
{
|
||||
if (idx < ARRAY_SIZE(sh7619_clk_ops))
|
||||
*ops = sh7619_clk_ops[idx];
|
||||
}
|
||||
|
341
arch/sh/kernel/cpu/sh2/entry.S
Normal file
341
arch/sh/kernel/cpu/sh2/entry.S
Normal file
@ -0,0 +1,341 @@
|
||||
/*
|
||||
* arch/sh/kernel/cpu/sh2/entry.S
|
||||
*
|
||||
* The SH-2 exception entry
|
||||
*
|
||||
* Copyright (C) 2005,2006 Yoshinori Sato
|
||||
* Copyright (C) 2005 AXE,Inc.
|
||||
*
|
||||
* 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/linkage.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/cpu/mmu_context.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
/* Offsets to the stack */
|
||||
OFF_R0 = 0 /* Return value. New ABI also arg4 */
|
||||
OFF_R1 = 4 /* New ABI: arg5 */
|
||||
OFF_R2 = 8 /* New ABI: arg6 */
|
||||
OFF_R3 = 12 /* New ABI: syscall_nr */
|
||||
OFF_R4 = 16 /* New ABI: arg0 */
|
||||
OFF_R5 = 20 /* New ABI: arg1 */
|
||||
OFF_R6 = 24 /* New ABI: arg2 */
|
||||
OFF_R7 = 28 /* New ABI: arg3 */
|
||||
OFF_SP = (15*4)
|
||||
OFF_PC = (16*4)
|
||||
OFF_SR = (16*4+2*4)
|
||||
OFF_TRA = (16*4+6*4)
|
||||
|
||||
#include <asm/entry-macros.S>
|
||||
|
||||
ENTRY(exception_handler)
|
||||
! already saved r0/r1
|
||||
mov.l r2,@-sp
|
||||
mov.l r3,@-sp
|
||||
mov r0,r1
|
||||
cli
|
||||
mov.l $cpu_mode,r2
|
||||
mov.l @r2,r0
|
||||
mov.l @(5*4,r15),r3 ! previous SR
|
||||
shll2 r3 ! set "S" flag
|
||||
rotl r0 ! T <- "S" flag
|
||||
rotl r0 ! "S" flag is LSB
|
||||
rotcr r3 ! T -> r3:b30
|
||||
shlr r3
|
||||
shlr r0
|
||||
bt/s 1f
|
||||
mov.l r3,@(5*4,r15) ! copy cpu mode to SR
|
||||
! switch to kernel mode
|
||||
mov #1,r0
|
||||
rotr r0
|
||||
rotr r0
|
||||
mov.l r0,@r2 ! enter kernel mode
|
||||
mov.l $current_thread_info,r2
|
||||
mov.l @r2,r2
|
||||
mov #0x20,r0
|
||||
shll8 r0
|
||||
add r2,r0
|
||||
mov r15,r2 ! r2 = user stack top
|
||||
mov r0,r15 ! switch kernel stack
|
||||
add #-4,r15 ! dummy
|
||||
mov.l r1,@-r15 ! TRA
|
||||
sts.l macl, @-r15
|
||||
sts.l mach, @-r15
|
||||
stc.l gbr, @-r15
|
||||
mov.l @(4*4,r2),r0
|
||||
mov.l @(5*4,r2),r1
|
||||
mov.l r1,@-r15 ! original SR
|
||||
sts.l pr,@-r15
|
||||
mov.l r0,@-r15 ! original PC
|
||||
mov r2,r3
|
||||
add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame
|
||||
mov.l r3,@-r15 ! original SP
|
||||
mov.l r14,@-r15
|
||||
mov.l r13,@-r15
|
||||
mov.l r12,@-r15
|
||||
mov.l r11,@-r15
|
||||
mov.l r10,@-r15
|
||||
mov.l r9,@-r15
|
||||
mov.l r8,@-r15
|
||||
mov.l r7,@-r15
|
||||
mov.l r6,@-r15
|
||||
mov.l r5,@-r15
|
||||
mov.l r4,@-r15
|
||||
mov r2,r8 ! copy user -> kernel stack
|
||||
mov.l @r8+,r3
|
||||
mov.l r3,@-r15
|
||||
mov.l @r8+,r2
|
||||
mov.l r2,@-r15
|
||||
mov.l @r8+,r1
|
||||
mov.l r1,@-r15
|
||||
mov.l @r8+,r0
|
||||
bra 2f
|
||||
mov.l r0,@-r15
|
||||
1:
|
||||
! in kernel exception
|
||||
mov #(22-4-4-1)*4+4,r0
|
||||
mov r15,r2
|
||||
sub r0,r15
|
||||
mov.l @r2+,r0 ! old R3
|
||||
mov.l r0,@-r15
|
||||
mov.l @r2+,r0 ! old R2
|
||||
mov.l r0,@-r15
|
||||
mov.l @r2+,r0 ! old R1
|
||||
mov.l r0,@-r15
|
||||
mov.l @r2+,r0 ! old R0
|
||||
mov.l r0,@-r15
|
||||
mov.l @r2+,r3 ! old PC
|
||||
mov.l @r2+,r0 ! old SR
|
||||
add #-4,r2 ! exception frame stub (sr)
|
||||
mov.l r1,@-r2 ! TRA
|
||||
sts.l macl, @-r2
|
||||
sts.l mach, @-r2
|
||||
stc.l gbr, @-r2
|
||||
mov.l r0,@-r2 ! save old SR
|
||||
sts.l pr,@-r2
|
||||
mov.l r3,@-r2 ! save old PC
|
||||
mov r2,r0
|
||||
add #8*4,r0
|
||||
mov.l r0,@-r2 ! save old SP
|
||||
mov.l r14,@-r2
|
||||
mov.l r13,@-r2
|
||||
mov.l r12,@-r2
|
||||
mov.l r11,@-r2
|
||||
mov.l r10,@-r2
|
||||
mov.l r9,@-r2
|
||||
mov.l r8,@-r2
|
||||
mov.l r7,@-r2
|
||||
mov.l r6,@-r2
|
||||
mov.l r5,@-r2
|
||||
mov.l r4,@-r2
|
||||
mov.l @(OFF_R0,r15),r0
|
||||
mov.l @(OFF_R1,r15),r1
|
||||
mov.l @(OFF_R2,r15),r2
|
||||
mov.l @(OFF_R3,r15),r3
|
||||
2:
|
||||
mov #OFF_TRA,r8
|
||||
add r15,r8
|
||||
mov.l @r8,r9
|
||||
mov #64,r8
|
||||
cmp/hs r8,r9
|
||||
bt interrupt_entry ! vec >= 64 is interrupt
|
||||
mov #32,r8
|
||||
cmp/hs r8,r9
|
||||
bt trap_entry ! 64 > vec >= 32 is trap
|
||||
mov.l 4f,r8
|
||||
mov r9,r4
|
||||
shll2 r9
|
||||
add r9,r8
|
||||
mov.l @r8,r8
|
||||
mov #0,r9
|
||||
cmp/eq r9,r8
|
||||
bf 3f
|
||||
mov.l 8f,r8 ! unhandled exception
|
||||
3:
|
||||
mov.l 5f,r10
|
||||
jmp @r8
|
||||
lds r10,pr
|
||||
|
||||
interrupt_entry:
|
||||
mov r9,r4
|
||||
mov.l 6f,r9
|
||||
mov.l 7f,r8
|
||||
jmp @r8
|
||||
lds r9,pr
|
||||
|
||||
.align 2
|
||||
4: .long exception_handling_table
|
||||
5: .long ret_from_exception
|
||||
6: .long ret_from_irq
|
||||
7: .long do_IRQ
|
||||
8: .long do_exception_error
|
||||
|
||||
trap_entry:
|
||||
add #-0x10,r9
|
||||
shll2 r9 ! TRA
|
||||
mov #OFF_TRA,r8
|
||||
add r15,r8
|
||||
mov.l r9,@r8
|
||||
mov r9,r8
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
mov.l 5f, r9
|
||||
jsr @r9
|
||||
nop
|
||||
#endif
|
||||
sti
|
||||
bra system_call
|
||||
nop
|
||||
|
||||
.align 2
|
||||
1: .long syscall_exit
|
||||
2: .long break_point_trap_software
|
||||
3: .long NR_syscalls
|
||||
4: .long sys_call_table
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
5: .long trace_hardirqs_on
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SH_STANDARD_BIOS)
|
||||
/* Unwind the stack and jmp to the debug entry */
|
||||
debug_kernel_fw:
|
||||
mov r15,r0
|
||||
add #(22-4)*4-4,r0
|
||||
ldc.l @r0+,gbr
|
||||
lds.l @r0+,mach
|
||||
lds.l @r0+,macl
|
||||
mov r15,r0
|
||||
mov.l @(OFF_SP,r0),r1
|
||||
mov #OFF_SR,r2
|
||||
mov.l @(r0,r2),r3
|
||||
mov.l r3,@-r1
|
||||
mov #OFF_SP,r2
|
||||
mov.l @(r0,r2),r3
|
||||
mov.l r3,@-r1
|
||||
mov r15,r0
|
||||
add #(22-4)*4-8,r0
|
||||
mov.l 1f,r2
|
||||
mov.l @r2,r2
|
||||
stc sr,r3
|
||||
mov.l r2,@r0
|
||||
mov.l r3,@r0
|
||||
mov.l r1,@(8,r0)
|
||||
mov.l @r15+, r0
|
||||
mov.l @r15+, r1
|
||||
mov.l @r15+, r2
|
||||
mov.l @r15+, r3
|
||||
mov.l @r15+, r4
|
||||
mov.l @r15+, r5
|
||||
mov.l @r15+, r6
|
||||
mov.l @r15+, r7
|
||||
mov.l @r15+, r8
|
||||
mov.l @r15+, r9
|
||||
mov.l @r15+, r10
|
||||
mov.l @r15+, r11
|
||||
mov.l @r15+, r12
|
||||
mov.l @r15+, r13
|
||||
mov.l @r15+, r14
|
||||
add #8,r15
|
||||
lds.l @r15+, pr
|
||||
rte
|
||||
mov.l @r15+,r15
|
||||
.align 2
|
||||
1: .long gdb_vbr_vector
|
||||
#endif /* CONFIG_SH_STANDARD_BIOS */
|
||||
|
||||
ENTRY(address_error_handler)
|
||||
mov r15,r4 ! regs
|
||||
add #4,r4
|
||||
mov #OFF_PC,r0
|
||||
mov.l @(r0,r15),r6 ! pc
|
||||
mov.l 1f,r0
|
||||
jmp @r0
|
||||
mov #0,r5 ! writeaccess is unknown
|
||||
.align 2
|
||||
|
||||
1: .long do_address_error
|
||||
|
||||
restore_all:
|
||||
cli
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
mov.l 3f, r0
|
||||
jsr @r0
|
||||
nop
|
||||
#endif
|
||||
mov r15,r0
|
||||
mov.l $cpu_mode,r2
|
||||
mov #OFF_SR,r3
|
||||
mov.l @(r0,r3),r1
|
||||
mov.l r1,@r2
|
||||
shll2 r1 ! clear MD bit
|
||||
shlr2 r1
|
||||
mov.l @(OFF_SP,r0),r2
|
||||
add #-8,r2
|
||||
mov.l r2,@(OFF_SP,r0) ! point exception frame top
|
||||
mov.l r1,@(4,r2) ! set sr
|
||||
mov #OFF_PC,r3
|
||||
mov.l @(r0,r3),r1
|
||||
mov.l r1,@r2 ! set pc
|
||||
add #4*16+4,r0
|
||||
lds.l @r0+,pr
|
||||
add #4,r0 ! skip sr
|
||||
ldc.l @r0+,gbr
|
||||
lds.l @r0+,mach
|
||||
lds.l @r0+,macl
|
||||
get_current_thread_info r0, r1
|
||||
mov.l $current_thread_info,r1
|
||||
mov.l r0,@r1
|
||||
mov.l @r15+,r0
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r2
|
||||
mov.l @r15+,r3
|
||||
mov.l @r15+,r4
|
||||
mov.l @r15+,r5
|
||||
mov.l @r15+,r6
|
||||
mov.l @r15+,r7
|
||||
mov.l @r15+,r8
|
||||
mov.l @r15+,r9
|
||||
mov.l @r15+,r10
|
||||
mov.l @r15+,r11
|
||||
mov.l @r15+,r12
|
||||
mov.l @r15+,r13
|
||||
mov.l @r15+,r14
|
||||
mov.l @r15,r15
|
||||
rte
|
||||
nop
|
||||
2:
|
||||
mov.l 1f,r8
|
||||
mov.l 2f,r9
|
||||
jmp @r9
|
||||
lds r8,pr
|
||||
|
||||
.align 2
|
||||
$current_thread_info:
|
||||
.long __current_thread_info
|
||||
$cpu_mode:
|
||||
.long __cpu_mode
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
3: .long trace_hardirqs_off
|
||||
#endif
|
||||
|
||||
! common exception handler
|
||||
#include "../../entry-common.S"
|
||||
|
||||
.data
|
||||
! cpu operation mode
|
||||
! bit30 = MD (compatible SH3/4)
|
||||
__cpu_mode:
|
||||
.long 0x40000000
|
||||
|
||||
.section .bss
|
||||
__current_thread_info:
|
||||
.long 0
|
||||
|
||||
ENTRY(exception_handling_table)
|
||||
.space 4*32
|
46
arch/sh/kernel/cpu/sh2/ex.S
Normal file
46
arch/sh/kernel/cpu/sh2/ex.S
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* arch/sh/kernel/cpu/sh2/ex.S
|
||||
*
|
||||
* The SH-2 exception vector table
|
||||
*
|
||||
* Copyright (C) 2005 Yoshinori Sato
|
||||
*
|
||||
* 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/linkage.h>
|
||||
|
||||
!
|
||||
! convert Exception Vector to Exception Number
|
||||
!
|
||||
exception_entry:
|
||||
no = 0
|
||||
.rept 256
|
||||
mov.l r0,@-sp
|
||||
mov #no,r0
|
||||
bra exception_trampoline
|
||||
and #0xff,r0
|
||||
no = no + 1
|
||||
.endr
|
||||
exception_trampoline:
|
||||
mov.l r1,@-sp
|
||||
mov.l $exception_handler,r1
|
||||
jmp @r1
|
||||
|
||||
.align 2
|
||||
$exception_entry:
|
||||
.long exception_entry
|
||||
$exception_handler:
|
||||
.long exception_handler
|
||||
!
|
||||
! Exception Vector Base
|
||||
!
|
||||
.align 2
|
||||
ENTRY(vbr_base)
|
||||
vector = 0
|
||||
.rept 256
|
||||
.long exception_entry + vector * 8
|
||||
vector = vector + 1
|
||||
.endr
|
@ -17,17 +17,23 @@
|
||||
|
||||
int __init detect_cpu_and_cache_system(void)
|
||||
{
|
||||
/*
|
||||
* For now, assume SH7604 .. fix this later.
|
||||
*/
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7604)
|
||||
cpu_data->type = CPU_SH7604;
|
||||
cpu_data->dcache.ways = 4;
|
||||
cpu_data->dcache.way_shift = 6;
|
||||
cpu_data->dcache.way_incr = (1<<10);
|
||||
cpu_data->dcache.sets = 64;
|
||||
cpu_data->dcache.entry_shift = 4;
|
||||
cpu_data->dcache.linesz = L1_CACHE_BYTES;
|
||||
cpu_data->dcache.flags = 0;
|
||||
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
|
||||
cpu_data->type = CPU_SH7619;
|
||||
cpu_data->dcache.ways = 4;
|
||||
cpu_data->dcache.way_incr = (1<<12);
|
||||
cpu_data->dcache.sets = 256;
|
||||
cpu_data->dcache.entry_shift = 4;
|
||||
cpu_data->dcache.linesz = L1_CACHE_BYTES;
|
||||
cpu_data->dcache.flags = 0;
|
||||
#endif
|
||||
/*
|
||||
* SH-2 doesn't have separate caches
|
||||
*/
|
||||
|
53
arch/sh/kernel/cpu/sh2/setup-sh7619.c
Normal file
53
arch/sh/kernel/cpu/sh2/setup-sh7619.c
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* SH7619 Setup
|
||||
*
|
||||
* Copyright (C) 2006 Yoshinori Sato
|
||||
*
|
||||
* 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 <asm/sci.h>
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
{
|
||||
.mapbase = 0xf8400000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 88, 89, 91, 90},
|
||||
}, {
|
||||
.mapbase = 0xf8410000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 92, 93, 95, 94},
|
||||
}, {
|
||||
.mapbase = 0xf8420000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 96, 97, 99, 98},
|
||||
}, {
|
||||
.flags = 0,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device sci_device = {
|
||||
.name = "sh-sci",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = sci_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *sh7619_devices[] __initdata = {
|
||||
&sci_device,
|
||||
};
|
||||
|
||||
static int __init sh7619_devices_setup(void)
|
||||
{
|
||||
return platform_add_devices(sh7619_devices,
|
||||
ARRAY_SIZE(sh7619_devices));
|
||||
}
|
||||
__initcall(sh7619_devices_setup);
|
10
arch/sh/kernel/cpu/sh2a/Makefile
Normal file
10
arch/sh/kernel/cpu/sh2a/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
#
|
||||
# Makefile for the Linux/SuperH SH-2A backends.
|
||||
#
|
||||
|
||||
obj-y := common.o probe.o
|
||||
|
||||
common-y += $(addprefix ../sh2/, ex.o)
|
||||
common-y += $(addprefix ../sh2/, entry.o)
|
||||
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o
|
85
arch/sh/kernel/cpu/sh2a/clock-sh7206.c
Normal file
85
arch/sh/kernel/cpu/sh2a/clock-sh7206.c
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* arch/sh/kernel/cpu/sh2a/clock-sh7206.c
|
||||
*
|
||||
* SH7206 support for the clock framework
|
||||
*
|
||||
* Copyright (C) 2006 Yoshinori Sato
|
||||
*
|
||||
* Based on clock-sh4.c
|
||||
* Copyright (C) 2005 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/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/clock.h>
|
||||
#include <asm/freq.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
const static int pll1rate[]={1,2,3,4,6,8};
|
||||
const static int pfc_divisors[]={1,2,3,4,6,8,12};
|
||||
#define ifc_divisors pfc_divisors
|
||||
|
||||
#if (CONFIG_SH_CLK_MD == 2)
|
||||
#define PLL2 (4)
|
||||
#elif (CONFIG_SH_CLK_MD == 6)
|
||||
#define PLL2 (2)
|
||||
#elif (CONFIG_SH_CLK_MD == 7)
|
||||
#define PLL2 (1)
|
||||
#else
|
||||
#error "Illigal Clock Mode!"
|
||||
#endif
|
||||
|
||||
static void master_clk_init(struct clk *clk)
|
||||
{
|
||||
clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
|
||||
}
|
||||
|
||||
static struct clk_ops sh7206_master_clk_ops = {
|
||||
.init = master_clk_init,
|
||||
};
|
||||
|
||||
static void module_clk_recalc(struct clk *clk)
|
||||
{
|
||||
int idx = (ctrl_inw(FREQCR) & 0x0007);
|
||||
clk->rate = clk->parent->rate / pfc_divisors[idx];
|
||||
}
|
||||
|
||||
static struct clk_ops sh7206_module_clk_ops = {
|
||||
.recalc = module_clk_recalc,
|
||||
};
|
||||
|
||||
static void bus_clk_recalc(struct clk *clk)
|
||||
{
|
||||
clk->rate = clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
|
||||
}
|
||||
|
||||
static struct clk_ops sh7206_bus_clk_ops = {
|
||||
.recalc = bus_clk_recalc,
|
||||
};
|
||||
|
||||
static void cpu_clk_recalc(struct clk *clk)
|
||||
{
|
||||
int idx = (ctrl_inw(FREQCR) & 0x0007);
|
||||
clk->rate = clk->parent->rate / ifc_divisors[idx];
|
||||
}
|
||||
|
||||
static struct clk_ops sh7206_cpu_clk_ops = {
|
||||
.recalc = cpu_clk_recalc,
|
||||
};
|
||||
|
||||
static struct clk_ops *sh7206_clk_ops[] = {
|
||||
&sh7206_master_clk_ops,
|
||||
&sh7206_module_clk_ops,
|
||||
&sh7206_bus_clk_ops,
|
||||
&sh7206_cpu_clk_ops,
|
||||
};
|
||||
|
||||
void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
|
||||
{
|
||||
if (idx < ARRAY_SIZE(sh7206_clk_ops))
|
||||
*ops = sh7206_clk_ops[idx];
|
||||
}
|
||||
|
39
arch/sh/kernel/cpu/sh2a/probe.c
Normal file
39
arch/sh/kernel/cpu/sh2a/probe.c
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* arch/sh/kernel/cpu/sh2a/probe.c
|
||||
*
|
||||
* CPU Subtype Probing for SH-2A.
|
||||
*
|
||||
* Copyright (C) 2004, 2005 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/init.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
int __init detect_cpu_and_cache_system(void)
|
||||
{
|
||||
/* Just SH7206 for now .. */
|
||||
cpu_data->type = CPU_SH7206;
|
||||
|
||||
cpu_data->dcache.ways = 4;
|
||||
cpu_data->dcache.way_incr = (1 << 11);
|
||||
cpu_data->dcache.sets = 128;
|
||||
cpu_data->dcache.entry_shift = 4;
|
||||
cpu_data->dcache.linesz = L1_CACHE_BYTES;
|
||||
cpu_data->dcache.flags = 0;
|
||||
|
||||
/*
|
||||
* The icache is the same as the dcache as far as this setup is
|
||||
* concerned. The only real difference in hardware is that the icache
|
||||
* lacks the U bit that the dcache has, none of this has any bearing
|
||||
* on the cache info.
|
||||
*/
|
||||
cpu_data->icache = cpu_data->dcache;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
58
arch/sh/kernel/cpu/sh2a/setup-sh7206.c
Normal file
58
arch/sh/kernel/cpu/sh2a/setup-sh7206.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* SH7206 Setup
|
||||
*
|
||||
* Copyright (C) 2006 Yoshinori Sato
|
||||
*
|
||||
* 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 <asm/sci.h>
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
{
|
||||
.mapbase = 0xfffe8000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 240, 241, 242, 243},
|
||||
}, {
|
||||
.mapbase = 0xfffe8800,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 244, 245, 246, 247},
|
||||
}, {
|
||||
.mapbase = 0xfffe9000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 248, 249, 250, 251},
|
||||
}, {
|
||||
.mapbase = 0xfffe9800,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 252, 253, 254, 255},
|
||||
}, {
|
||||
.flags = 0,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device sci_device = {
|
||||
.name = "sh-sci",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = sci_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *sh7206_devices[] __initdata = {
|
||||
&sci_device,
|
||||
};
|
||||
|
||||
static int __init sh7206_devices_setup(void)
|
||||
{
|
||||
return platform_add_devices(sh7206_devices,
|
||||
ARRAY_SIZE(sh7206_devices));
|
||||
}
|
||||
__initcall(sh7206_devices_setup);
|
@ -2,7 +2,7 @@
|
||||
# Makefile for the Linux/SuperH SH-3 backends.
|
||||
#
|
||||
|
||||
obj-y := ex.o probe.o
|
||||
obj-y := ex.o probe.o entry.o
|
||||
|
||||
# CPU subtype setup
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o
|
||||
|
@ -24,7 +24,7 @@ static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 };
|
||||
|
||||
static void set_bus_parent(struct clk *clk)
|
||||
{
|
||||
struct clk *bus_clk = clk_get("bus_clk");
|
||||
struct clk *bus_clk = clk_get(NULL, "bus_clk");
|
||||
clk->parent = bus_clk;
|
||||
clk_put(bus_clk);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* linux/arch/sh/entry.S
|
||||
* arch/sh/kernel/entry.S
|
||||
*
|
||||
* Copyright (C) 1999, 2000, 2002 Niibe Yutaka
|
||||
* Copyright (C) 2003 - 2006 Paul Mundt
|
||||
@ -7,15 +7,16 @@
|
||||
* 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/sys.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/cpu/mmu_context.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/cpu/mmu_context.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
! NOTE:
|
||||
! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
|
||||
@ -81,6 +82,8 @@ OFF_TRA = (16*4+6*4)
|
||||
#define k_g_imask r6_bank /* r6_bank1 */
|
||||
#define current r7 /* r7_bank1 */
|
||||
|
||||
#include <asm/entry-macros.S>
|
||||
|
||||
/*
|
||||
* Kernel mode register usage:
|
||||
* k0 scratch
|
||||
@ -107,26 +110,6 @@ OFF_TRA = (16*4+6*4)
|
||||
! this first version depends *much* on C implementation.
|
||||
!
|
||||
|
||||
#define CLI() \
|
||||
stc sr, r0; \
|
||||
or #0xf0, r0; \
|
||||
ldc r0, sr
|
||||
|
||||
#define STI() \
|
||||
mov.l __INV_IMASK, r11; \
|
||||
stc sr, r10; \
|
||||
and r11, r10; \
|
||||
stc k_g_imask, r11; \
|
||||
or r11, r10; \
|
||||
ldc r10, sr
|
||||
|
||||
#if defined(CONFIG_PREEMPT)
|
||||
# define preempt_stop() CLI()
|
||||
#else
|
||||
# define preempt_stop()
|
||||
# define resume_kernel restore_all
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MMU)
|
||||
.align 2
|
||||
ENTRY(tlb_miss_load)
|
||||
@ -155,29 +138,14 @@ ENTRY(tlb_protection_violation_store)
|
||||
|
||||
call_dpf:
|
||||
mov.l 1f, r0
|
||||
mov r5, r8
|
||||
mov.l @r0, r6
|
||||
mov r6, r9
|
||||
mov.l 2f, r0
|
||||
sts pr, r10
|
||||
jsr @r0
|
||||
mov r15, r4
|
||||
!
|
||||
tst r0, r0
|
||||
bf/s 0f
|
||||
lds r10, pr
|
||||
rts
|
||||
nop
|
||||
0: STI()
|
||||
mov.l @r0, r6 ! address
|
||||
mov.l 3f, r0
|
||||
mov r9, r6
|
||||
mov r8, r5
|
||||
|
||||
jmp @r0
|
||||
mov r15, r4
|
||||
mov r15, r4 ! regs
|
||||
|
||||
.align 2
|
||||
1: .long MMU_TEA
|
||||
2: .long __do_page_fault
|
||||
3: .long do_page_fault
|
||||
|
||||
.align 2
|
||||
@ -203,32 +171,6 @@ call_dae:
|
||||
2: .long do_address_error
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
|
||||
! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present.
|
||||
! If both are configured, handle the debug traps (breakpoints) in SW,
|
||||
! but still allow BIOS traps to FW.
|
||||
|
||||
.align 2
|
||||
debug_kernel:
|
||||
#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB)
|
||||
/* Force BIOS call to FW (debug_trap put TRA in r8) */
|
||||
mov r8,r0
|
||||
shlr2 r0
|
||||
cmp/eq #0x3f,r0
|
||||
bt debug_kernel_fw
|
||||
#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */
|
||||
|
||||
debug_enter:
|
||||
#if defined(CONFIG_SH_KGDB)
|
||||
/* Jump to kgdb, pass stacked regs as arg */
|
||||
debug_kernel_sw:
|
||||
mov.l 3f, r0
|
||||
jmp @r0
|
||||
mov r15, r4
|
||||
.align 2
|
||||
3: .long kgdb_handle_exception
|
||||
#endif /* CONFIG_SH_KGDB */
|
||||
|
||||
#if defined(CONFIG_SH_STANDARD_BIOS)
|
||||
/* Unwind the stack and jmp to the debug entry */
|
||||
debug_kernel_fw:
|
||||
@ -269,276 +211,6 @@ debug_kernel_fw:
|
||||
2: .long gdb_vbr_vector
|
||||
#endif /* CONFIG_SH_STANDARD_BIOS */
|
||||
|
||||
#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
|
||||
|
||||
|
||||
.align 2
|
||||
debug_trap:
|
||||
#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
|
||||
mov #OFF_SR, r0
|
||||
mov.l @(r0,r15), r0 ! get status register
|
||||
shll r0
|
||||
shll r0 ! kernel space?
|
||||
bt/s debug_kernel
|
||||
#endif
|
||||
mov.l @r15, r0 ! Restore R0 value
|
||||
mov.l 1f, r8
|
||||
jmp @r8
|
||||
nop
|
||||
|
||||
.align 2
|
||||
ENTRY(exception_error)
|
||||
!
|
||||
STI()
|
||||
mov.l 2f, r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
!
|
||||
.align 2
|
||||
1: .long break_point_trap_software
|
||||
2: .long do_exception_error
|
||||
|
||||
.align 2
|
||||
ret_from_exception:
|
||||
preempt_stop()
|
||||
ENTRY(ret_from_irq)
|
||||
!
|
||||
mov #OFF_SR, r0
|
||||
mov.l @(r0,r15), r0 ! get status register
|
||||
shll r0
|
||||
shll r0 ! kernel space?
|
||||
bt/s resume_kernel ! Yes, it's from kernel, go back soon
|
||||
GET_THREAD_INFO(r8)
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
bra resume_userspace
|
||||
nop
|
||||
ENTRY(resume_kernel)
|
||||
mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count
|
||||
tst r0, r0
|
||||
bf noresched
|
||||
need_resched:
|
||||
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
|
||||
tst #_TIF_NEED_RESCHED, r0 ! need_resched set?
|
||||
bt noresched
|
||||
|
||||
mov #OFF_SR, r0
|
||||
mov.l @(r0,r15), r0 ! get status register
|
||||
and #0xf0, r0 ! interrupts off (exception path)?
|
||||
cmp/eq #0xf0, r0
|
||||
bt noresched
|
||||
|
||||
mov.l 1f, r0
|
||||
mov.l r0, @(TI_PRE_COUNT,r8)
|
||||
|
||||
STI()
|
||||
mov.l 2f, r0
|
||||
jsr @r0
|
||||
nop
|
||||
mov #0, r0
|
||||
mov.l r0, @(TI_PRE_COUNT,r8)
|
||||
CLI()
|
||||
|
||||
bra need_resched
|
||||
nop
|
||||
noresched:
|
||||
bra restore_all
|
||||
nop
|
||||
|
||||
.align 2
|
||||
1: .long PREEMPT_ACTIVE
|
||||
2: .long schedule
|
||||
#endif
|
||||
|
||||
ENTRY(resume_userspace)
|
||||
! r8: current_thread_info
|
||||
CLI()
|
||||
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
|
||||
tst #_TIF_WORK_MASK, r0
|
||||
bt/s restore_all
|
||||
tst #_TIF_NEED_RESCHED, r0
|
||||
|
||||
.align 2
|
||||
work_pending:
|
||||
! r0: current_thread_info->flags
|
||||
! r8: current_thread_info
|
||||
! t: result of "tst #_TIF_NEED_RESCHED, r0"
|
||||
bf/s work_resched
|
||||
tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0
|
||||
work_notifysig:
|
||||
bt/s restore_all
|
||||
mov r15, r4
|
||||
mov r12, r5 ! set arg1(save_r0)
|
||||
mov r0, r6
|
||||
mov.l 2f, r1
|
||||
mova restore_all, r0
|
||||
jmp @r1
|
||||
lds r0, pr
|
||||
work_resched:
|
||||
#ifndef CONFIG_PREEMPT
|
||||
! gUSA handling
|
||||
mov.l @(OFF_SP,r15), r0 ! get user space stack pointer
|
||||
mov r0, r1
|
||||
shll r0
|
||||
bf/s 1f
|
||||
shll r0
|
||||
bf/s 1f
|
||||
mov #OFF_PC, r0
|
||||
! SP >= 0xc0000000 : gUSA mark
|
||||
mov.l @(r0,r15), r2 ! get user space PC (program counter)
|
||||
mov.l @(OFF_R0,r15), r3 ! end point
|
||||
cmp/hs r3, r2 ! r2 >= r3?
|
||||
bt 1f
|
||||
add r3, r1 ! rewind point #2
|
||||
mov.l r1, @(r0,r15) ! reset PC to rewind point #2
|
||||
!
|
||||
1:
|
||||
#endif
|
||||
mov.l 1f, r1
|
||||
jsr @r1 ! schedule
|
||||
nop
|
||||
CLI()
|
||||
!
|
||||
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
|
||||
tst #_TIF_WORK_MASK, r0
|
||||
bt restore_all
|
||||
bra work_pending
|
||||
tst #_TIF_NEED_RESCHED, r0
|
||||
|
||||
.align 2
|
||||
1: .long schedule
|
||||
2: .long do_notify_resume
|
||||
|
||||
.align 2
|
||||
syscall_exit_work:
|
||||
! r0: current_thread_info->flags
|
||||
! r8: current_thread_info
|
||||
tst #_TIF_SYSCALL_TRACE, r0
|
||||
bt/s work_pending
|
||||
tst #_TIF_NEED_RESCHED, r0
|
||||
STI()
|
||||
! XXX setup arguments...
|
||||
mov.l 4f, r0 ! do_syscall_trace
|
||||
jsr @r0
|
||||
nop
|
||||
bra resume_userspace
|
||||
nop
|
||||
|
||||
.align 2
|
||||
syscall_trace_entry:
|
||||
! Yes it is traced.
|
||||
! XXX setup arguments...
|
||||
mov.l 4f, r11 ! Call do_syscall_trace which notifies
|
||||
jsr @r11 ! superior (will chomp R[0-7])
|
||||
nop
|
||||
! Reload R0-R4 from kernel stack, where the
|
||||
! parent may have modified them using
|
||||
! ptrace(POKEUSR). (Note that R0-R2 are
|
||||
! used by the system call handler directly
|
||||
! from the kernel stack anyway, so don't need
|
||||
! to be reloaded here.) This allows the parent
|
||||
! to rewrite system calls and args on the fly.
|
||||
mov.l @(OFF_R4,r15), r4 ! arg0
|
||||
mov.l @(OFF_R5,r15), r5
|
||||
mov.l @(OFF_R6,r15), r6
|
||||
mov.l @(OFF_R7,r15), r7 ! arg3
|
||||
mov.l @(OFF_R3,r15), r3 ! syscall_nr
|
||||
! Arrange for do_syscall_trace to be called
|
||||
! again as the system call returns.
|
||||
mov.l 2f, r10 ! Number of syscalls
|
||||
cmp/hs r10, r3
|
||||
bf syscall_call
|
||||
mov #-ENOSYS, r0
|
||||
bra syscall_exit
|
||||
mov.l r0, @(OFF_R0,r15) ! Return value
|
||||
|
||||
/*
|
||||
* Syscall interface:
|
||||
*
|
||||
* Syscall #: R3
|
||||
* Arguments #0 to #3: R4--R7
|
||||
* Arguments #4 to #6: R0, R1, R2
|
||||
* TRA: (number of arguments + 0x10) x 4
|
||||
*
|
||||
* This code also handles delegating other traps to the BIOS/gdb stub
|
||||
* according to:
|
||||
*
|
||||
* Trap number
|
||||
* (TRA>>2) Purpose
|
||||
* -------- -------
|
||||
* 0x0-0xf old syscall ABI
|
||||
* 0x10-0x1f new syscall ABI
|
||||
* 0x20-0xff delegated through debug_trap to BIOS/gdb stub.
|
||||
*
|
||||
* Note: When we're first called, the TRA value must be shifted
|
||||
* right 2 bits in order to get the value that was used as the "trapa"
|
||||
* argument.
|
||||
*/
|
||||
|
||||
.align 2
|
||||
.globl ret_from_fork
|
||||
ret_from_fork:
|
||||
mov.l 1f, r8
|
||||
jsr @r8
|
||||
mov r0, r4
|
||||
bra syscall_exit
|
||||
nop
|
||||
.align 2
|
||||
1: .long schedule_tail
|
||||
!
|
||||
ENTRY(system_call)
|
||||
mov.l 1f, r9
|
||||
mov.l @r9, r8 ! Read from TRA (Trap Address) Register
|
||||
!
|
||||
! Is the trap argument >= 0x20? (TRA will be >= 0x80)
|
||||
mov #0x7f, r9
|
||||
cmp/hi r9, r8
|
||||
bt/s 0f
|
||||
mov #OFF_TRA, r9
|
||||
add r15, r9
|
||||
!
|
||||
mov.l r8, @r9 ! set TRA value to tra
|
||||
STI()
|
||||
! Call the system call handler through the table.
|
||||
! First check for bad syscall number
|
||||
mov r3, r9
|
||||
mov.l 2f, r8 ! Number of syscalls
|
||||
cmp/hs r8, r9
|
||||
bf/s good_system_call
|
||||
GET_THREAD_INFO(r8)
|
||||
syscall_badsys: ! Bad syscall number
|
||||
mov #-ENOSYS, r0
|
||||
bra resume_userspace
|
||||
mov.l r0, @(OFF_R0,r15) ! Return value
|
||||
!
|
||||
0:
|
||||
bra debug_trap
|
||||
nop
|
||||
!
|
||||
good_system_call: ! Good syscall number
|
||||
mov.l @(TI_FLAGS,r8), r8
|
||||
mov #_TIF_SYSCALL_TRACE, r10
|
||||
tst r10, r8
|
||||
bf syscall_trace_entry
|
||||
!
|
||||
syscall_call:
|
||||
shll2 r9 ! x4
|
||||
mov.l 3f, r8 ! Load the address of sys_call_table
|
||||
add r8, r9
|
||||
mov.l @r9, r8
|
||||
jsr @r8 ! jump to specific syscall handler
|
||||
nop
|
||||
mov.l @(OFF_R0,r15), r12 ! save r0
|
||||
mov.l r0, @(OFF_R0,r15) ! save the return value
|
||||
!
|
||||
syscall_exit:
|
||||
CLI()
|
||||
!
|
||||
GET_THREAD_INFO(r8)
|
||||
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
|
||||
tst #_TIF_ALLWORK_MASK, r0
|
||||
bf syscall_exit_work
|
||||
restore_all:
|
||||
mov.l @r15+, r0
|
||||
mov.l @r15+, r1
|
||||
@ -606,7 +278,9 @@ skip_restore:
|
||||
!
|
||||
! Calculate new SR value
|
||||
mov k3, k2 ! original SR value
|
||||
mov.l 9f, k1
|
||||
mov #0xf0, k1
|
||||
extu.b k1, k1
|
||||
not k1, k1
|
||||
and k1, k2 ! Mask orignal SR value
|
||||
!
|
||||
mov k3, k0 ! Calculate IMASK-bits
|
||||
@ -632,16 +306,12 @@ skip_restore:
|
||||
nop
|
||||
|
||||
.align 2
|
||||
1: .long TRA
|
||||
2: .long NR_syscalls
|
||||
3: .long sys_call_table
|
||||
4: .long do_syscall_trace
|
||||
5: .long 0x00001000 ! DSP
|
||||
7: .long 0x30000000
|
||||
9:
|
||||
__INV_IMASK:
|
||||
.long 0xffffff0f ! ~(IMASK)
|
||||
|
||||
! common exception handler
|
||||
#include "../../entry-common.S"
|
||||
|
||||
! Exception Vector Base
|
||||
!
|
||||
! Should be aligned page boundary.
|
||||
@ -661,9 +331,176 @@ general_exception:
|
||||
2: .long ret_from_exception
|
||||
!
|
||||
!
|
||||
|
||||
/* This code makes some assumptions to improve performance.
|
||||
* Make sure they are stil true. */
|
||||
#if PTRS_PER_PGD != PTRS_PER_PTE
|
||||
#error PGD and PTE sizes don't match
|
||||
#endif
|
||||
|
||||
/* gas doesn't flag impossible values for mov #immediate as an error */
|
||||
#if (_PAGE_PRESENT >> 2) > 0x7f
|
||||
#error cannot load PAGE_PRESENT as an immediate
|
||||
#endif
|
||||
#if _PAGE_DIRTY > 0x7f
|
||||
#error cannot load PAGE_DIRTY as an immediate
|
||||
#endif
|
||||
#if (_PAGE_PRESENT << 2) != _PAGE_ACCESSED
|
||||
#error cannot derive PAGE_ACCESSED from PAGE_PRESENT
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CPU_SH4)
|
||||
#define ldmmupteh(r) mov.l 8f, r
|
||||
#else
|
||||
#define ldmmupteh(r) mov #MMU_PTEH, r
|
||||
#endif
|
||||
|
||||
.balign 1024,0,1024
|
||||
tlb_miss:
|
||||
mov.l 1f, k2
|
||||
#ifdef COUNT_EXCEPTIONS
|
||||
! Increment the counts
|
||||
mov.l 9f, k1
|
||||
mov.l @k1, k2
|
||||
add #1, k2
|
||||
mov.l k2, @k1
|
||||
#endif
|
||||
|
||||
! k0 scratch
|
||||
! k1 pgd and pte pointers
|
||||
! k2 faulting address
|
||||
! k3 pgd and pte index masks
|
||||
! k4 shift
|
||||
|
||||
! Load up the pgd entry (k1)
|
||||
|
||||
ldmmupteh(k0) ! 9 LS (latency=2) MMU_PTEH
|
||||
|
||||
mov.w 4f, k3 ! 8 LS (latency=2) (PTRS_PER_PGD-1) << 2
|
||||
mov #-(PGDIR_SHIFT-2), k4 ! 6 EX
|
||||
|
||||
mov.l @(MMU_TEA-MMU_PTEH,k0), k2 ! 18 LS (latency=2)
|
||||
|
||||
mov.l @(MMU_TTB-MMU_PTEH,k0), k1 ! 18 LS (latency=2)
|
||||
|
||||
mov k2, k0 ! 5 MT (latency=0)
|
||||
shld k4, k0 ! 99 EX
|
||||
|
||||
and k3, k0 ! 78 EX
|
||||
|
||||
mov.l @(k0, k1), k1 ! 21 LS (latency=2)
|
||||
mov #-(PAGE_SHIFT-2), k4 ! 6 EX
|
||||
|
||||
! Load up the pte entry (k2)
|
||||
|
||||
mov k2, k0 ! 5 MT (latency=0)
|
||||
shld k4, k0 ! 99 EX
|
||||
|
||||
tst k1, k1 ! 86 MT
|
||||
|
||||
bt 20f ! 110 BR
|
||||
|
||||
and k3, k0 ! 78 EX
|
||||
mov.w 5f, k4 ! 8 LS (latency=2) _PAGE_PRESENT
|
||||
|
||||
mov.l @(k0, k1), k2 ! 21 LS (latency=2)
|
||||
add k0, k1 ! 49 EX
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_PTEA
|
||||
! Test the entry for present and _PAGE_ACCESSED
|
||||
|
||||
mov #-28, k3 ! 6 EX
|
||||
mov k2, k0 ! 5 MT (latency=0)
|
||||
|
||||
tst k4, k2 ! 68 MT
|
||||
shld k3, k0 ! 99 EX
|
||||
|
||||
bt 20f ! 110 BR
|
||||
|
||||
! Set PTEA register
|
||||
! MMU_PTEA = ((pteval >> 28) & 0xe) | (pteval & 0x1)
|
||||
!
|
||||
! k0=pte>>28, k1=pte*, k2=pte, k3=<unused>, k4=_PAGE_PRESENT
|
||||
|
||||
and #0xe, k0 ! 79 EX
|
||||
|
||||
mov k0, k3 ! 5 MT (latency=0)
|
||||
mov k2, k0 ! 5 MT (latency=0)
|
||||
|
||||
and #1, k0 ! 79 EX
|
||||
|
||||
or k0, k3 ! 82 EX
|
||||
|
||||
ldmmupteh(k0) ! 9 LS (latency=2)
|
||||
shll2 k4 ! 101 EX _PAGE_ACCESSED
|
||||
|
||||
tst k4, k2 ! 68 MT
|
||||
|
||||
mov.l k3, @(MMU_PTEA-MMU_PTEH,k0) ! 27 LS
|
||||
|
||||
mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK
|
||||
|
||||
! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED
|
||||
#else
|
||||
|
||||
! Test the entry for present and _PAGE_ACCESSED
|
||||
|
||||
mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK
|
||||
tst k4, k2 ! 68 MT
|
||||
|
||||
shll2 k4 ! 101 EX _PAGE_ACCESSED
|
||||
ldmmupteh(k0) ! 9 LS (latency=2)
|
||||
|
||||
bt 20f ! 110 BR
|
||||
tst k4, k2 ! 68 MT
|
||||
|
||||
! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED
|
||||
|
||||
#endif
|
||||
|
||||
! Set up the entry
|
||||
|
||||
and k2, k3 ! 78 EX
|
||||
bt/s 10f ! 108 BR
|
||||
|
||||
mov.l k3, @(MMU_PTEL-MMU_PTEH,k0) ! 27 LS
|
||||
|
||||
ldtlb ! 128 CO
|
||||
|
||||
! At least one instruction between ldtlb and rte
|
||||
nop ! 119 NOP
|
||||
|
||||
rte ! 126 CO
|
||||
|
||||
nop ! 119 NOP
|
||||
|
||||
|
||||
10: or k4, k2 ! 82 EX
|
||||
|
||||
ldtlb ! 128 CO
|
||||
|
||||
! At least one instruction between ldtlb and rte
|
||||
mov.l k2, @k1 ! 27 LS
|
||||
|
||||
rte ! 126 CO
|
||||
|
||||
! Note we cannot execute mov here, because it is executed after
|
||||
! restoring SSR, so would be executed in user space.
|
||||
nop ! 119 NOP
|
||||
|
||||
|
||||
.align 5
|
||||
! Once cache line if possible...
|
||||
1: .long swapper_pg_dir
|
||||
4: .short (PTRS_PER_PGD-1) << 2
|
||||
5: .short _PAGE_PRESENT
|
||||
7: .long _PAGE_FLAGS_HARDWARE_MASK
|
||||
8: .long MMU_PTEH
|
||||
#ifdef COUNT_EXCEPTIONS
|
||||
9: .long exception_count_miss
|
||||
#endif
|
||||
|
||||
! Either pgd or pte not present
|
||||
20: mov.l 1f, k2
|
||||
mov.l 4f, k3
|
||||
bra handle_exception
|
||||
mov.l @k2, k2
|
||||
@ -710,8 +547,9 @@ ENTRY(handle_exception)
|
||||
bt/s 1f ! It's a kernel to kernel transition.
|
||||
mov r15, k0 ! save original stack to k0
|
||||
/* User space to kernel */
|
||||
mov #(THREAD_SIZE >> 8), k1
|
||||
mov #(THREAD_SIZE >> 10), k1
|
||||
shll8 k1 ! k1 := THREAD_SIZE
|
||||
shll2 k1
|
||||
add current, k1
|
||||
mov k1, r15 ! change to kernel stack
|
||||
!
|
||||
@ -761,7 +599,7 @@ skip_save:
|
||||
! Save the user registers on the stack.
|
||||
mov.l k2, @-r15 ! EXPEVT
|
||||
|
||||
mov #-1, k4
|
||||
mov #-1, k4
|
||||
mov.l k4, @-r15 ! set TRA (default: -1)
|
||||
!
|
||||
sts.l macl, @-r15
|
||||
@ -813,6 +651,15 @@ skip_save:
|
||||
bf interrupt_exception
|
||||
shlr2 r8
|
||||
shlr r8
|
||||
|
||||
#ifdef COUNT_EXCEPTIONS
|
||||
mov.l 5f, r9
|
||||
add r8, r9
|
||||
mov.l @r9, r10
|
||||
add #1, r10
|
||||
mov.l r10, @r9
|
||||
#endif
|
||||
|
||||
mov.l 4f, r9
|
||||
add r8, r9
|
||||
mov.l @r9, r9
|
||||
@ -826,6 +673,9 @@ skip_save:
|
||||
2: .long 0x000080f0 ! FD=1, IMASK=15
|
||||
3: .long 0xcfffffff ! RB=0, BL=0
|
||||
4: .long exception_handling_table
|
||||
#ifdef COUNT_EXCEPTIONS
|
||||
5: .long exception_count_table
|
||||
#endif
|
||||
|
||||
interrupt_exception:
|
||||
mov.l 1f, r9
|
@ -2,7 +2,8 @@
|
||||
# Makefile for the Linux/SuperH SH-4 backends.
|
||||
#
|
||||
|
||||
obj-y := ex.o probe.o
|
||||
obj-y := ex.o probe.o common.o
|
||||
common-y += $(addprefix ../sh3/, entry.o)
|
||||
|
||||
obj-$(CONFIG_SH_FPU) += fpu.o
|
||||
obj-$(CONFIG_SH_STORE_QUEUES) += sq.o
|
||||
|
@ -97,7 +97,7 @@ static void shoc_clk_recalc(struct clk *clk)
|
||||
|
||||
static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
struct clk *bclk = clk_get("bus_clk");
|
||||
struct clk *bclk = clk_get(NULL, "bus_clk");
|
||||
unsigned long bclk_rate = clk_get_rate(bclk);
|
||||
|
||||
clk_put(bclk);
|
||||
@ -151,7 +151,7 @@ static struct clk *sh4202_onchip_clocks[] = {
|
||||
|
||||
static int __init sh4202_clk_init(void)
|
||||
{
|
||||
struct clk *clk = clk_get("master_clk");
|
||||
struct clk *clk = clk_get(NULL, "master_clk");
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) {
|
||||
|
@ -98,7 +98,7 @@ static struct clk *sh7780_onchip_clocks[] = {
|
||||
|
||||
static int __init sh7780_clk_init(void)
|
||||
{
|
||||
struct clk *clk = clk_get("master_clk");
|
||||
struct clk *clk = clk_get(NULL, "master_clk");
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) {
|
||||
|
@ -282,11 +282,8 @@ ieee_fpe_handler (struct pt_regs *regs)
|
||||
grab_fpu(regs);
|
||||
restore_fpu(tsk);
|
||||
set_tsk_thread_flag(tsk, TIF_USEDFPU);
|
||||
} else {
|
||||
tsk->thread.trap_no = 11;
|
||||
tsk->thread.error_code = 0;
|
||||
} else
|
||||
force_sig(SIGFPE, tsk);
|
||||
}
|
||||
|
||||
regs->pc = nextpc;
|
||||
return 1;
|
||||
@ -296,29 +293,29 @@ ieee_fpe_handler (struct pt_regs *regs)
|
||||
}
|
||||
|
||||
asmlinkage void
|
||||
do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6,
|
||||
unsigned long r7, struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
struct task_struct *tsk = current;
|
||||
|
||||
if (ieee_fpe_handler (®s))
|
||||
if (ieee_fpe_handler(regs))
|
||||
return;
|
||||
|
||||
regs.pc += 2;
|
||||
save_fpu(tsk, ®s);
|
||||
tsk->thread.trap_no = 11;
|
||||
tsk->thread.error_code = 0;
|
||||
regs->pc += 2;
|
||||
save_fpu(tsk, regs);
|
||||
force_sig(SIGFPE, tsk);
|
||||
}
|
||||
|
||||
asmlinkage void
|
||||
do_fpu_state_restore(unsigned long r4, unsigned long r5, unsigned long r6,
|
||||
unsigned long r7, struct pt_regs regs)
|
||||
unsigned long r7, struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
struct task_struct *tsk = current;
|
||||
|
||||
grab_fpu(®s);
|
||||
if (!user_mode(®s)) {
|
||||
grab_fpu(regs);
|
||||
if (!user_mode(regs)) {
|
||||
printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
|
||||
return;
|
||||
}
|
||||
|
@ -79,16 +79,16 @@ int __init detect_cpu_and_cache_system(void)
|
||||
case 0x205:
|
||||
cpu_data->type = CPU_SH7750;
|
||||
cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
|
||||
CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA;
|
||||
CPU_HAS_PERF_COUNTER;
|
||||
break;
|
||||
case 0x206:
|
||||
cpu_data->type = CPU_SH7750S;
|
||||
cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
|
||||
CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA;
|
||||
CPU_HAS_PERF_COUNTER;
|
||||
break;
|
||||
case 0x1100:
|
||||
cpu_data->type = CPU_SH7751;
|
||||
cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
|
||||
cpu_data->flags |= CPU_HAS_FPU;
|
||||
break;
|
||||
case 0x2000:
|
||||
cpu_data->type = CPU_SH73180;
|
||||
@ -126,23 +126,22 @@ int __init detect_cpu_and_cache_system(void)
|
||||
break;
|
||||
case 0x8000:
|
||||
cpu_data->type = CPU_ST40RA;
|
||||
cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
|
||||
cpu_data->flags |= CPU_HAS_FPU;
|
||||
break;
|
||||
case 0x8100:
|
||||
cpu_data->type = CPU_ST40GX1;
|
||||
cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
|
||||
cpu_data->flags |= CPU_HAS_FPU;
|
||||
break;
|
||||
case 0x700:
|
||||
cpu_data->type = CPU_SH4_501;
|
||||
cpu_data->icache.ways = 2;
|
||||
cpu_data->dcache.ways = 2;
|
||||
cpu_data->flags |= CPU_HAS_PTEA;
|
||||
break;
|
||||
case 0x600:
|
||||
cpu_data->type = CPU_SH4_202;
|
||||
cpu_data->icache.ways = 2;
|
||||
cpu_data->dcache.ways = 2;
|
||||
cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
|
||||
cpu_data->flags |= CPU_HAS_FPU;
|
||||
break;
|
||||
case 0x500 ... 0x501:
|
||||
switch (prr) {
|
||||
@ -160,7 +159,7 @@ int __init detect_cpu_and_cache_system(void)
|
||||
cpu_data->icache.ways = 2;
|
||||
cpu_data->dcache.ways = 2;
|
||||
|
||||
cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
|
||||
cpu_data->flags |= CPU_HAS_FPU;
|
||||
|
||||
break;
|
||||
default:
|
||||
@ -173,6 +172,10 @@ int __init detect_cpu_and_cache_system(void)
|
||||
cpu_data->dcache.ways = 1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_PTEA
|
||||
cpu_data->flags |= CPU_HAS_PTEA;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On anything that's not a direct-mapped cache, look to the CVR
|
||||
* for I/D-cache specifics.
|
||||
|
@ -2,6 +2,7 @@
|
||||
* SH7750/SH7751 Setup
|
||||
*
|
||||
* Copyright (C) 2006 Paul Mundt
|
||||
* Copyright (C) 2006 Jamie Lenehan
|
||||
*
|
||||
* 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
|
||||
@ -10,6 +11,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/sci.h>
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
@ -46,3 +48,71 @@ static int __init sh7750_devices_setup(void)
|
||||
ARRAY_SIZE(sh7750_devices));
|
||||
}
|
||||
__initcall(sh7750_devices_setup);
|
||||
|
||||
static struct ipr_data sh7750_ipr_map[] = {
|
||||
/* IRQ, IPR-idx, shift, priority */
|
||||
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/
|
||||
{ 17, 0, 12, 2 }, /* TMU1 TUNI */
|
||||
{ 18, 0, 4, 2 }, /* TMU2 TUNI */
|
||||
{ 19, 0, 4, 2 }, /* TMU2 TIPCI */
|
||||
{ 27, 1, 12, 2 }, /* WDT ITI */
|
||||
{ 20, 0, 0, 2 }, /* RTC ATI (alarm) */
|
||||
{ 21, 0, 0, 2 }, /* RTC PRI (period) */
|
||||
{ 22, 0, 0, 2 }, /* RTC CUI (carry) */
|
||||
{ 23, 1, 4, 3 }, /* SCI ERI */
|
||||
{ 24, 1, 4, 3 }, /* SCI RXI */
|
||||
{ 25, 1, 4, 3 }, /* SCI TXI */
|
||||
{ 40, 2, 4, 3 }, /* SCIF ERI */
|
||||
{ 41, 2, 4, 3 }, /* SCIF RXI */
|
||||
{ 42, 2, 4, 3 }, /* SCIF BRI */
|
||||
{ 43, 2, 4, 3 }, /* SCIF TXI */
|
||||
{ 34, 2, 8, 7 }, /* DMAC DMTE0 */
|
||||
{ 35, 2, 8, 7 }, /* DMAC DMTE1 */
|
||||
{ 36, 2, 8, 7 }, /* DMAC DMTE2 */
|
||||
{ 37, 2, 8, 7 }, /* DMAC DMTE3 */
|
||||
{ 28, 2, 8, 7 }, /* DMAC DMAE */
|
||||
};
|
||||
|
||||
static struct ipr_data sh7751_ipr_map[] = {
|
||||
{ 44, 2, 8, 7 }, /* DMAC DMTE4 */
|
||||
{ 45, 2, 8, 7 }, /* DMAC DMTE5 */
|
||||
{ 46, 2, 8, 7 }, /* DMAC DMTE6 */
|
||||
{ 47, 2, 8, 7 }, /* DMAC DMTE7 */
|
||||
/* The following use INTC_INPRI00 for masking, which is a 32-bit
|
||||
register, not a 16-bit register like the IPRx registers, so it
|
||||
would need special support */
|
||||
/*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */
|
||||
/*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */
|
||||
};
|
||||
|
||||
static unsigned long ipr_offsets[] = {
|
||||
0xffd00004UL, /* 0: IPRA */
|
||||
0xffd00008UL, /* 1: IPRB */
|
||||
0xffd0000cUL, /* 2: IPRC */
|
||||
0xffd00010UL, /* 3: IPRD */
|
||||
};
|
||||
|
||||
/* given the IPR index return the address of the IPR register */
|
||||
unsigned int map_ipridx_to_addr(int idx)
|
||||
{
|
||||
if (idx >= ARRAY_SIZE(ipr_offsets))
|
||||
return 0;
|
||||
return ipr_offsets[idx];
|
||||
}
|
||||
|
||||
#define INTC_ICR 0xffd00000UL
|
||||
#define INTC_ICR_IRLM (1<<7)
|
||||
|
||||
/* enable individual interrupt mode for external interupts */
|
||||
void ipr_irq_enable_irlm(void)
|
||||
{
|
||||
ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
|
||||
}
|
||||
|
||||
void __init init_IRQ_ipr()
|
||||
{
|
||||
make_ipr_irq(sh7750_ipr_map, ARRAY_SIZE(sh7750_ipr_map));
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7751
|
||||
make_ipr_irq(sh7751_ipr_map, ARRAY_SIZE(sh7751_ipr_map));
|
||||
#endif
|
||||
}
|
||||
|
@ -79,25 +79,27 @@ static int __init sh7780_devices_setup(void)
|
||||
__initcall(sh7780_devices_setup);
|
||||
|
||||
static struct intc2_data intc2_irq_table[] = {
|
||||
{ TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2 },
|
||||
{ 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY },
|
||||
{ 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY },
|
||||
{ 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY },
|
||||
{ SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
|
||||
{ SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
|
||||
{ SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
|
||||
{ SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
|
||||
{ 28, 0, 24, 0, 0, 2 }, /* TMU0 */
|
||||
|
||||
{ SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
|
||||
{ SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
|
||||
{ SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
|
||||
{ SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
|
||||
{ 21, 1, 0, 0, 2, 2 },
|
||||
{ 22, 1, 1, 0, 2, 2 },
|
||||
{ 23, 1, 2, 0, 2, 2 },
|
||||
|
||||
{ PCIC0_IRQ, 0x10, 8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY },
|
||||
{ PCIC1_IRQ, 0x10, 0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY },
|
||||
{ PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY },
|
||||
{ PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY },
|
||||
{ PCIC4_IRQ, 0x14, 8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY },
|
||||
{ 40, 8, 24, 0, 3, 3 }, /* SCIF0 ERI */
|
||||
{ 41, 8, 24, 0, 3, 3 }, /* SCIF0 RXI */
|
||||
{ 42, 8, 24, 0, 3, 3 }, /* SCIF0 BRI */
|
||||
{ 43, 8, 24, 0, 3, 3 }, /* SCIF0 TXI */
|
||||
|
||||
{ 76, 8, 16, 0, 4, 3 }, /* SCIF1 ERI */
|
||||
{ 77, 8, 16, 0, 4, 3 }, /* SCIF1 RXI */
|
||||
{ 78, 8, 16, 0, 4, 3 }, /* SCIF1 BRI */
|
||||
{ 79, 8, 16, 0, 4, 3 }, /* SCIF1 TXI */
|
||||
|
||||
{ 64, 0x10, 8, 0, 14, 2 }, /* PCIC0 */
|
||||
{ 65, 0x10, 0, 0, 15, 2 }, /* PCIC1 */
|
||||
{ 66, 0x14, 24, 0, 16, 2 }, /* PCIC2 */
|
||||
{ 67, 0x14, 16, 0, 17, 2 }, /* PCIC3 */
|
||||
{ 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */
|
||||
};
|
||||
|
||||
void __init init_IRQ_intc2(void)
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/cpu/sq.h>
|
||||
@ -67,6 +67,7 @@ void sq_flush_range(unsigned long start, unsigned int len)
|
||||
/* Wait for completion */
|
||||
store_queue_barrier();
|
||||
}
|
||||
EXPORT_SYMBOL(sq_flush_range);
|
||||
|
||||
static inline void sq_mapping_list_add(struct sq_mapping *map)
|
||||
{
|
||||
@ -166,7 +167,7 @@ unsigned long sq_remap(unsigned long phys, unsigned int size,
|
||||
map->size = size;
|
||||
map->name = name;
|
||||
|
||||
page = bitmap_find_free_region(sq_bitmap, 0x04000000,
|
||||
page = bitmap_find_free_region(sq_bitmap, 0x04000000 >> PAGE_SHIFT,
|
||||
get_order(map->size));
|
||||
if (unlikely(page < 0)) {
|
||||
ret = -ENOSPC;
|
||||
@ -193,6 +194,7 @@ out:
|
||||
kmem_cache_free(sq_cache, map);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(sq_remap);
|
||||
|
||||
/**
|
||||
* sq_unmap - Unmap a Store Queue allocation
|
||||
@ -234,6 +236,7 @@ void sq_unmap(unsigned long vaddr)
|
||||
|
||||
kmem_cache_free(sq_cache, map);
|
||||
}
|
||||
EXPORT_SYMBOL(sq_unmap);
|
||||
|
||||
/*
|
||||
* Needlessly complex sysfs interface. Unfortunately it doesn't seem like
|
||||
@ -402,7 +405,3 @@ module_exit(sq_api_exit);
|
||||
MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, M. R. Brown <mrbrown@0xd6.org>");
|
||||
MODULE_DESCRIPTION("Simple API for SH-4 integrated Store Queues");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
EXPORT_SYMBOL(sq_remap);
|
||||
EXPORT_SYMBOL(sq_unmap);
|
||||
EXPORT_SYMBOL(sq_flush_range);
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <linux/console.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#ifdef CONFIG_SH_STANDARD_BIOS
|
||||
#include <asm/sh_bios.h>
|
||||
@ -62,17 +62,9 @@ static struct console bios_console = {
|
||||
#include <linux/serial_core.h>
|
||||
#include "../../../drivers/serial/sh-sci.h"
|
||||
|
||||
#ifdef CONFIG_CPU_SH4
|
||||
#define SCIF_REG 0xffe80000
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH72060)
|
||||
#define SCIF_REG 0xfffe9800
|
||||
#else
|
||||
#error "Undefined SCIF for this subtype"
|
||||
#endif
|
||||
|
||||
static struct uart_port scif_port = {
|
||||
.mapbase = SCIF_REG,
|
||||
.membase = (char __iomem *)SCIF_REG,
|
||||
.mapbase = CONFIG_EARLY_SCIF_CONSOLE_PORT,
|
||||
.membase = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT,
|
||||
};
|
||||
|
||||
static void scif_sercon_putc(int c)
|
||||
@ -113,23 +105,29 @@ static struct console scif_console = {
|
||||
.index = -1,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS)
|
||||
/*
|
||||
* Simple SCIF init, primarily aimed at SH7750 and other similar SH-4
|
||||
* devices that aren't using sh-ipl+g.
|
||||
*/
|
||||
static void scif_sercon_init(int baud)
|
||||
{
|
||||
ctrl_outw(0, SCIF_REG + 8);
|
||||
ctrl_outw(0, SCIF_REG);
|
||||
ctrl_outw(0, scif_port.mapbase + 8);
|
||||
ctrl_outw(0, scif_port.mapbase);
|
||||
|
||||
/* Set baud rate */
|
||||
ctrl_outb((CONFIG_SH_PCLK_FREQ + 16 * baud) /
|
||||
(32 * baud) - 1, SCIF_REG + 4);
|
||||
(32 * baud) - 1, scif_port.mapbase + 4);
|
||||
|
||||
ctrl_outw(12, SCIF_REG + 24);
|
||||
ctrl_outw(8, SCIF_REG + 24);
|
||||
ctrl_outw(0, SCIF_REG + 32);
|
||||
ctrl_outw(0x60, SCIF_REG + 16);
|
||||
ctrl_outw(0, SCIF_REG + 36);
|
||||
ctrl_outw(0x30, SCIF_REG + 8);
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_CPU_SH4 && !CONFIG_SH_STANDARD_BIOS */
|
||||
#endif /* CONFIG_EARLY_SCIF_CONSOLE */
|
||||
|
||||
/*
|
||||
* Setup a default console, if more than one is compiled in, rely on the
|
||||
@ -168,7 +166,7 @@ int __init setup_early_printk(char *opt)
|
||||
if (!strncmp(buf, "serial", 6)) {
|
||||
early_console = &scif_console;
|
||||
|
||||
#ifdef CONFIG_CPU_SH4
|
||||
#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS)
|
||||
scif_sercon_init(115200);
|
||||
#endif
|
||||
}
|
||||
|
433
arch/sh/kernel/entry-common.S
Normal file
433
arch/sh/kernel/entry-common.S
Normal file
@ -0,0 +1,433 @@
|
||||
/* $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
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
! NOTE:
|
||||
! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
|
||||
! to be jumped is too far, but it causes illegal slot exception.
|
||||
|
||||
/*
|
||||
* entry.S contains the system-call and fault low-level handling routines.
|
||||
* This also contains the timer-interrupt handler, as well as all interrupts
|
||||
* and faults that can result in a task-switch.
|
||||
*
|
||||
* NOTE: This code handles signal-recognition, which happens every time
|
||||
* after a timer-interrupt and after each system call.
|
||||
*
|
||||
* NOTE: This code uses a convention that instructions in the delay slot
|
||||
* of a transfer-control instruction are indented by an extra space, thus:
|
||||
*
|
||||
* jmp @k0 ! control-transfer instruction
|
||||
* ldc k1, ssr ! delay slot
|
||||
*
|
||||
* Stack layout in 'ret_from_syscall':
|
||||
* ptrace needs to have all regs on the stack.
|
||||
* if the order here is changed, it needs to be
|
||||
* updated in ptrace.c and ptrace.h
|
||||
*
|
||||
* r0
|
||||
* ...
|
||||
* r15 = stack pointer
|
||||
* spc
|
||||
* pr
|
||||
* ssr
|
||||
* gbr
|
||||
* mach
|
||||
* macl
|
||||
* syscall #
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_PREEMPT)
|
||||
# define preempt_stop() cli
|
||||
#else
|
||||
# define preempt_stop()
|
||||
# define resume_kernel __restore_all
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
|
||||
! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present.
|
||||
! If both are configured, handle the debug traps (breakpoints) in SW,
|
||||
! but still allow BIOS traps to FW.
|
||||
|
||||
.align 2
|
||||
debug_kernel:
|
||||
#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB)
|
||||
/* Force BIOS call to FW (debug_trap put TRA in r8) */
|
||||
mov r8,r0
|
||||
shlr2 r0
|
||||
cmp/eq #0x3f,r0
|
||||
bt debug_kernel_fw
|
||||
#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */
|
||||
|
||||
debug_enter:
|
||||
#if defined(CONFIG_SH_KGDB)
|
||||
/* Jump to kgdb, pass stacked regs as arg */
|
||||
debug_kernel_sw:
|
||||
mov.l 3f, r0
|
||||
jmp @r0
|
||||
mov r15, r4
|
||||
.align 2
|
||||
3: .long kgdb_handle_exception
|
||||
#endif /* CONFIG_SH_KGDB */
|
||||
|
||||
#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
|
||||
|
||||
|
||||
.align 2
|
||||
debug_trap:
|
||||
#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
|
||||
mov #OFF_SR, r0
|
||||
mov.l @(r0,r15), r0 ! get status register
|
||||
shll r0
|
||||
shll r0 ! kernel space?
|
||||
bt/s debug_kernel
|
||||
#endif
|
||||
mov.l @r15, r0 ! Restore R0 value
|
||||
mov.l 1f, r8
|
||||
jmp @r8
|
||||
nop
|
||||
|
||||
.align 2
|
||||
ENTRY(exception_error)
|
||||
!
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
mov.l 3f, r0
|
||||
jsr @r0
|
||||
nop
|
||||
#endif
|
||||
sti
|
||||
mov.l 2f, r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
!
|
||||
.align 2
|
||||
1: .long break_point_trap_software
|
||||
2: .long do_exception_error
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
3: .long trace_hardirqs_on
|
||||
#endif
|
||||
|
||||
.align 2
|
||||
ret_from_exception:
|
||||
preempt_stop()
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
mov.l 4f, r0
|
||||
jsr @r0
|
||||
nop
|
||||
#endif
|
||||
ENTRY(ret_from_irq)
|
||||
!
|
||||
mov #OFF_SR, r0
|
||||
mov.l @(r0,r15), r0 ! get status register
|
||||
shll r0
|
||||
shll r0 ! kernel space?
|
||||
get_current_thread_info r8, r0
|
||||
bt resume_kernel ! Yes, it's from kernel, go back soon
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
bra resume_userspace
|
||||
nop
|
||||
ENTRY(resume_kernel)
|
||||
mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count
|
||||
tst r0, r0
|
||||
bf noresched
|
||||
need_resched:
|
||||
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
|
||||
tst #_TIF_NEED_RESCHED, r0 ! need_resched set?
|
||||
bt noresched
|
||||
|
||||
mov #OFF_SR, r0
|
||||
mov.l @(r0,r15), r0 ! get status register
|
||||
and #0xf0, r0 ! interrupts off (exception path)?
|
||||
cmp/eq #0xf0, r0
|
||||
bt noresched
|
||||
|
||||
mov.l 1f, r0
|
||||
mov.l r0, @(TI_PRE_COUNT,r8)
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
mov.l 3f, r0
|
||||
jsr @r0
|
||||
nop
|
||||
#endif
|
||||
sti
|
||||
mov.l 2f, r0
|
||||
jsr @r0
|
||||
nop
|
||||
mov #0, r0
|
||||
mov.l r0, @(TI_PRE_COUNT,r8)
|
||||
cli
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
mov.l 4f, r0
|
||||
jsr @r0
|
||||
nop
|
||||
#endif
|
||||
|
||||
bra need_resched
|
||||
nop
|
||||
|
||||
noresched:
|
||||
bra __restore_all
|
||||
nop
|
||||
|
||||
.align 2
|
||||
1: .long PREEMPT_ACTIVE
|
||||
2: .long schedule
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
3: .long trace_hardirqs_on
|
||||
4: .long trace_hardirqs_off
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ENTRY(resume_userspace)
|
||||
! r8: current_thread_info
|
||||
cli
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
mov.l 5f, r0
|
||||
jsr @r0
|
||||
nop
|
||||
#endif
|
||||
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
|
||||
tst #_TIF_WORK_MASK, r0
|
||||
bt/s __restore_all
|
||||
tst #_TIF_NEED_RESCHED, r0
|
||||
|
||||
.align 2
|
||||
work_pending:
|
||||
! r0: current_thread_info->flags
|
||||
! r8: current_thread_info
|
||||
! t: result of "tst #_TIF_NEED_RESCHED, r0"
|
||||
bf/s work_resched
|
||||
tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0
|
||||
work_notifysig:
|
||||
bt/s __restore_all
|
||||
mov r15, r4
|
||||
mov r12, r5 ! set arg1(save_r0)
|
||||
mov r0, r6
|
||||
mov.l 2f, r1
|
||||
mov.l 3f, r0
|
||||
jmp @r1
|
||||
lds r0, pr
|
||||
work_resched:
|
||||
#ifndef CONFIG_PREEMPT
|
||||
! gUSA handling
|
||||
mov.l @(OFF_SP,r15), r0 ! get user space stack pointer
|
||||
mov r0, r1
|
||||
shll r0
|
||||
bf/s 1f
|
||||
shll r0
|
||||
bf/s 1f
|
||||
mov #OFF_PC, r0
|
||||
! SP >= 0xc0000000 : gUSA mark
|
||||
mov.l @(r0,r15), r2 ! get user space PC (program counter)
|
||||
mov.l @(OFF_R0,r15), r3 ! end point
|
||||
cmp/hs r3, r2 ! r2 >= r3?
|
||||
bt 1f
|
||||
add r3, r1 ! rewind point #2
|
||||
mov.l r1, @(r0,r15) ! reset PC to rewind point #2
|
||||
!
|
||||
1:
|
||||
#endif
|
||||
mov.l 1f, r1
|
||||
jsr @r1 ! schedule
|
||||
nop
|
||||
cli
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
mov.l 5f, r0
|
||||
jsr @r0
|
||||
nop
|
||||
#endif
|
||||
!
|
||||
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
|
||||
tst #_TIF_WORK_MASK, r0
|
||||
bt __restore_all
|
||||
bra work_pending
|
||||
tst #_TIF_NEED_RESCHED, r0
|
||||
|
||||
.align 2
|
||||
1: .long schedule
|
||||
2: .long do_notify_resume
|
||||
3: .long restore_all
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
4: .long trace_hardirqs_on
|
||||
5: .long trace_hardirqs_off
|
||||
#endif
|
||||
|
||||
.align 2
|
||||
syscall_exit_work:
|
||||
! r0: current_thread_info->flags
|
||||
! r8: current_thread_info
|
||||
tst #_TIF_SYSCALL_TRACE, r0
|
||||
bt/s work_pending
|
||||
tst #_TIF_NEED_RESCHED, r0
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
mov.l 5f, r0
|
||||
jsr @r0
|
||||
nop
|
||||
#endif
|
||||
sti
|
||||
! XXX setup arguments...
|
||||
mov.l 4f, r0 ! do_syscall_trace
|
||||
jsr @r0
|
||||
nop
|
||||
bra resume_userspace
|
||||
nop
|
||||
|
||||
.align 2
|
||||
syscall_trace_entry:
|
||||
! Yes it is traced.
|
||||
! XXX setup arguments...
|
||||
mov.l 4f, r11 ! Call do_syscall_trace which notifies
|
||||
jsr @r11 ! superior (will chomp R[0-7])
|
||||
nop
|
||||
! Reload R0-R4 from kernel stack, where the
|
||||
! parent may have modified them using
|
||||
! ptrace(POKEUSR). (Note that R0-R2 are
|
||||
! used by the system call handler directly
|
||||
! from the kernel stack anyway, so don't need
|
||||
! to be reloaded here.) This allows the parent
|
||||
! to rewrite system calls and args on the fly.
|
||||
mov.l @(OFF_R4,r15), r4 ! arg0
|
||||
mov.l @(OFF_R5,r15), r5
|
||||
mov.l @(OFF_R6,r15), r6
|
||||
mov.l @(OFF_R7,r15), r7 ! arg3
|
||||
mov.l @(OFF_R3,r15), r3 ! syscall_nr
|
||||
!
|
||||
mov.l 2f, r10 ! Number of syscalls
|
||||
cmp/hs r10, r3
|
||||
bf syscall_call
|
||||
mov #-ENOSYS, r0
|
||||
bra syscall_exit
|
||||
mov.l r0, @(OFF_R0,r15) ! Return value
|
||||
|
||||
__restore_all:
|
||||
mov.l 1f, r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
1: .long restore_all
|
||||
|
||||
.align 2
|
||||
not_syscall_tra:
|
||||
bra debug_trap
|
||||
nop
|
||||
|
||||
.align 2
|
||||
syscall_badsys: ! Bad syscall number
|
||||
mov #-ENOSYS, r0
|
||||
bra resume_userspace
|
||||
mov.l r0, @(OFF_R0,r15) ! Return value
|
||||
|
||||
|
||||
/*
|
||||
* Syscall interface:
|
||||
*
|
||||
* Syscall #: R3
|
||||
* Arguments #0 to #3: R4--R7
|
||||
* Arguments #4 to #6: R0, R1, R2
|
||||
* TRA: (number of arguments + 0x10) x 4
|
||||
*
|
||||
* This code also handles delegating other traps to the BIOS/gdb stub
|
||||
* according to:
|
||||
*
|
||||
* Trap number
|
||||
* (TRA>>2) Purpose
|
||||
* -------- -------
|
||||
* 0x0-0xf old syscall ABI
|
||||
* 0x10-0x1f new syscall ABI
|
||||
* 0x20-0xff delegated through debug_trap to BIOS/gdb stub.
|
||||
*
|
||||
* Note: When we're first called, the TRA value must be shifted
|
||||
* right 2 bits in order to get the value that was used as the "trapa"
|
||||
* argument.
|
||||
*/
|
||||
|
||||
.align 2
|
||||
.globl ret_from_fork
|
||||
ret_from_fork:
|
||||
mov.l 1f, r8
|
||||
jsr @r8
|
||||
mov r0, r4
|
||||
bra syscall_exit
|
||||
nop
|
||||
.align 2
|
||||
1: .long schedule_tail
|
||||
!
|
||||
ENTRY(system_call)
|
||||
#if !defined(CONFIG_CPU_SH2)
|
||||
mov.l 1f, r9
|
||||
mov.l @r9, r8 ! Read from TRA (Trap Address) Register
|
||||
#endif
|
||||
!
|
||||
! Is the trap argument >= 0x20? (TRA will be >= 0x80)
|
||||
mov #0x7f, r9
|
||||
cmp/hi r9, r8
|
||||
bt/s not_syscall_tra
|
||||
mov #OFF_TRA, r9
|
||||
add r15, r9
|
||||
mov.l r8, @r9 ! set TRA value to tra
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
mov.l 5f, r10
|
||||
jsr @r10
|
||||
nop
|
||||
#endif
|
||||
sti
|
||||
|
||||
!
|
||||
get_current_thread_info r8, r10
|
||||
mov.l @(TI_FLAGS,r8), r8
|
||||
mov #_TIF_SYSCALL_TRACE, r10
|
||||
tst r10, r8
|
||||
bf syscall_trace_entry
|
||||
!
|
||||
mov.l 2f, r8 ! Number of syscalls
|
||||
cmp/hs r8, r3
|
||||
bt syscall_badsys
|
||||
!
|
||||
syscall_call:
|
||||
shll2 r3 ! x4
|
||||
mov.l 3f, r8 ! Load the address of sys_call_table
|
||||
add r8, r3
|
||||
mov.l @r3, r8
|
||||
jsr @r8 ! jump to specific syscall handler
|
||||
nop
|
||||
mov.l @(OFF_R0,r15), r12 ! save r0
|
||||
mov.l r0, @(OFF_R0,r15) ! save the return value
|
||||
!
|
||||
syscall_exit:
|
||||
cli
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
mov.l 6f, r0
|
||||
jsr @r0
|
||||
nop
|
||||
#endif
|
||||
!
|
||||
get_current_thread_info r8, r0
|
||||
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
|
||||
tst #_TIF_ALLWORK_MASK, r0
|
||||
bf syscall_exit_work
|
||||
bra __restore_all
|
||||
nop
|
||||
.align 2
|
||||
#if !defined(CONFIG_CPU_SH2)
|
||||
1: .long TRA
|
||||
#endif
|
||||
2: .long NR_syscalls
|
||||
3: .long sys_call_table
|
||||
4: .long do_syscall_trace
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
5: .long trace_hardirqs_on
|
||||
6: .long trace_hardirqs_off
|
||||
#endif
|
@ -33,7 +33,7 @@ ENTRY(empty_zero_page)
|
||||
.long 0x00360000 /* INITRD_START */
|
||||
.long 0x000a0000 /* INITRD_SIZE */
|
||||
.long 0
|
||||
.balign 4096,0,4096
|
||||
.balign PAGE_SIZE,0,PAGE_SIZE
|
||||
|
||||
.text
|
||||
/*
|
||||
@ -53,8 +53,10 @@ ENTRY(_stext)
|
||||
ldc r0, sr
|
||||
! Initialize global interrupt mask
|
||||
mov #0, r0
|
||||
#ifdef CONFIG_CPU_HAS_SR_RB
|
||||
ldc r0, r6_bank
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prefetch if possible to reduce cache miss penalty.
|
||||
*
|
||||
@ -68,11 +70,14 @@ ENTRY(_stext)
|
||||
!
|
||||
mov.l 2f, r0
|
||||
mov r0, r15 ! Set initial r15 (stack pointer)
|
||||
mov #(THREAD_SIZE >> 8), r1
|
||||
mov #(THREAD_SIZE >> 10), r1
|
||||
shll8 r1 ! r1 = THREAD_SIZE
|
||||
shll2 r1
|
||||
sub r1, r0 !
|
||||
#ifdef CONFIG_CPU_HAS_SR_RB
|
||||
ldc r0, r7_bank ! ... and initial thread_info
|
||||
|
||||
#endif
|
||||
|
||||
! Clear BSS area
|
||||
mov.l 3f, r1
|
||||
add #4, r1
|
||||
@ -95,7 +100,11 @@ ENTRY(_stext)
|
||||
nop
|
||||
|
||||
.balign 4
|
||||
#if defined(CONFIG_CPU_SH2)
|
||||
1: .long 0x000000F0 ! IMASK=0xF
|
||||
#else
|
||||
1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
|
||||
#endif
|
||||
2: .long init_thread_union+THREAD_SIZE
|
||||
3: .long __bss_start
|
||||
4: .long _end
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/irq.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/thread_info.h>
|
||||
@ -78,15 +78,16 @@ union irq_ctx {
|
||||
u32 stack[THREAD_SIZE/sizeof(u32)];
|
||||
};
|
||||
|
||||
static union irq_ctx *hardirq_ctx[NR_CPUS];
|
||||
static union irq_ctx *softirq_ctx[NR_CPUS];
|
||||
static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
|
||||
static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
|
||||
#endif
|
||||
|
||||
asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *old_regs = set_irq_regs(®s);
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
int irq;
|
||||
#ifdef CONFIG_4KSTACKS
|
||||
union irq_ctx *curctx, *irqctx;
|
||||
@ -111,7 +112,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_INTEVT
|
||||
irq = (ctrl_inl(INTEVT) >> 5) - 16;
|
||||
irq = evt2irq(ctrl_inl(INTEVT));
|
||||
#else
|
||||
irq = r4;
|
||||
#endif
|
||||
@ -135,17 +136,24 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
|
||||
irqctx->tinfo.task = curctx->tinfo.task;
|
||||
irqctx->tinfo.previous_sp = current_stack_pointer;
|
||||
|
||||
/*
|
||||
* Copy the softirq bits in preempt_count so that the
|
||||
* softirq checks work in the hardirq context.
|
||||
*/
|
||||
irqctx->tinfo.preempt_count =
|
||||
(irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) |
|
||||
(curctx->tinfo.preempt_count & SOFTIRQ_MASK);
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"mov %0, r4 \n"
|
||||
"mov r15, r9 \n"
|
||||
"mov r15, r8 \n"
|
||||
"jsr @%1 \n"
|
||||
/* swith to the irq stack */
|
||||
" mov %2, r15 \n"
|
||||
/* restore the stack (ring zero) */
|
||||
"mov r9, r15 \n"
|
||||
"mov r8, r15 \n"
|
||||
: /* no outputs */
|
||||
: "r" (irq), "r" (generic_handle_irq), "r" (isp)
|
||||
/* XXX: A somewhat excessive clobber list? -PFM */
|
||||
: "memory", "r0", "r1", "r2", "r3", "r4",
|
||||
"r5", "r6", "r7", "r8", "t", "pr"
|
||||
);
|
||||
@ -193,7 +201,7 @@ void irq_ctx_init(int cpu)
|
||||
irqctx->tinfo.task = NULL;
|
||||
irqctx->tinfo.exec_domain = NULL;
|
||||
irqctx->tinfo.cpu = cpu;
|
||||
irqctx->tinfo.preempt_count = SOFTIRQ_OFFSET;
|
||||
irqctx->tinfo.preempt_count = 0;
|
||||
irqctx->tinfo.addr_limit = MAKE_MM_SEG(0);
|
||||
|
||||
softirq_ctx[cpu] = irqctx;
|
||||
@ -239,13 +247,38 @@ asmlinkage void do_softirq(void)
|
||||
"mov r9, r15 \n"
|
||||
: /* no outputs */
|
||||
: "r" (__do_softirq), "r" (isp)
|
||||
/* XXX: A somewhat excessive clobber list? -PFM */
|
||||
: "memory", "r0", "r1", "r2", "r3", "r4",
|
||||
"r5", "r6", "r7", "r8", "r9", "r15", "t", "pr"
|
||||
);
|
||||
|
||||
/*
|
||||
* Shouldnt happen, we returned above if in_interrupt():
|
||||
*/
|
||||
WARN_ON_ONCE(softirq_count());
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
EXPORT_SYMBOL(do_softirq);
|
||||
#endif
|
||||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
#ifdef CONFIG_CPU_HAS_PINT_IRQ
|
||||
init_IRQ_pint();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_INTC2_IRQ
|
||||
init_IRQ_intc2();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_IPR_IRQ
|
||||
init_IRQ_ipr();
|
||||
#endif
|
||||
|
||||
/* Perform the machine specific initialisation */
|
||||
if (sh_mv.mv_init_irq)
|
||||
sh_mv.mv_init_irq();
|
||||
|
||||
irq_ctx_init(smp_processor_id());
|
||||
}
|
||||
|
@ -385,10 +385,11 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne
|
||||
|
||||
asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
#ifdef CONFIG_MMU
|
||||
return do_fork(SIGCHLD, regs.regs[15], ®s, 0, NULL, NULL);
|
||||
return do_fork(SIGCHLD, regs->regs[15], regs, 0, NULL, NULL);
|
||||
#else
|
||||
/* fork almost works, enough to trick you into looking elsewhere :-( */
|
||||
return -EINVAL;
|
||||
@ -398,11 +399,12 @@ asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
|
||||
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
|
||||
unsigned long parent_tidptr,
|
||||
unsigned long child_tidptr,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
if (!newsp)
|
||||
newsp = regs.regs[15];
|
||||
return do_fork(clone_flags, newsp, ®s, 0,
|
||||
newsp = regs->regs[15];
|
||||
return do_fork(clone_flags, newsp, regs, 0,
|
||||
(int __user *)parent_tidptr, (int __user *)child_tidptr);
|
||||
}
|
||||
|
||||
@ -418,9 +420,10 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
|
||||
*/
|
||||
asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], ®s,
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->regs[15], regs,
|
||||
0, NULL, NULL);
|
||||
}
|
||||
|
||||
@ -429,8 +432,9 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
|
||||
*/
|
||||
asmlinkage int sys_execve(char *ufilename, char **uargv,
|
||||
char **uenvp, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
int error;
|
||||
char *filename;
|
||||
|
||||
@ -442,7 +446,7 @@ asmlinkage int sys_execve(char *ufilename, char **uargv,
|
||||
error = do_execve(filename,
|
||||
(char __user * __user *)uargv,
|
||||
(char __user * __user *)uenvp,
|
||||
®s);
|
||||
regs);
|
||||
if (error == 0) {
|
||||
task_lock(current);
|
||||
current->ptrace &= ~PT_DTRACE;
|
||||
@ -472,9 +476,7 @@ unsigned long get_wchan(struct task_struct *p)
|
||||
return pc;
|
||||
}
|
||||
|
||||
asmlinkage void break_point_trap(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
asmlinkage void break_point_trap(void)
|
||||
{
|
||||
/* Clear tracing. */
|
||||
#if defined(CONFIG_CPU_SH4A)
|
||||
@ -492,8 +494,10 @@ asmlinkage void break_point_trap(unsigned long r4, unsigned long r5,
|
||||
|
||||
asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
regs.pc -= 2;
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
|
||||
regs->pc -= 2;
|
||||
force_sig(SIGTRAP, current);
|
||||
}
|
||||
|
@ -7,11 +7,9 @@
|
||||
* This source code is licensed under the GNU General Public License,
|
||||
* Version 2. See the file COPYING for more details.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#define PAGE_SIZE 4096 /* must be same value as in <asm/page.h> */
|
||||
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
.globl relocate_new_kernel
|
||||
relocate_new_kernel:
|
||||
@ -20,8 +18,8 @@ relocate_new_kernel:
|
||||
/* r6 = start_address */
|
||||
/* r7 = vbr_reg */
|
||||
|
||||
mov.l 10f,r8 /* 4096 */
|
||||
mov.l 11f,r9 /* 0xa0000000 */
|
||||
mov.l 10f,r8 /* PAGE_SIZE */
|
||||
mov.l 11f,r9 /* P2SEG */
|
||||
|
||||
/* stack setting */
|
||||
add r8,r5
|
||||
@ -32,7 +30,7 @@ relocate_new_kernel:
|
||||
0:
|
||||
mov.l @r4+,r0 /* cmd = *ind++ */
|
||||
|
||||
1: /* addr = (cmd | 0xa0000000) & 0xfffffff0 */
|
||||
1: /* addr = (cmd | P2SEG) & 0xfffffff0 */
|
||||
mov r0,r2
|
||||
or r9,r2
|
||||
mov #-16,r1
|
||||
@ -92,7 +90,7 @@ relocate_new_kernel:
|
||||
10:
|
||||
.long PAGE_SIZE
|
||||
11:
|
||||
.long 0xa0000000
|
||||
.long P2SEG
|
||||
|
||||
relocate_new_kernel_end:
|
||||
|
||||
|
@ -392,6 +392,7 @@ static int __init topology_init(void)
|
||||
subsys_initcall(topology_init);
|
||||
|
||||
static const char *cpu_name[] = {
|
||||
[CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619",
|
||||
[CPU_SH7604] = "SH7604", [CPU_SH7300] = "SH7300",
|
||||
[CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
|
||||
[CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
|
||||
@ -404,6 +405,7 @@ static const char *cpu_name[] = {
|
||||
[CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501",
|
||||
[CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780",
|
||||
[CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343",
|
||||
[CPU_SH7785] = "SH7785",
|
||||
[CPU_SH_NONE] = "Unknown"
|
||||
};
|
||||
|
||||
|
@ -73,8 +73,6 @@ DECLARE_EXPORT(__lshrdi3);
|
||||
DECLARE_EXPORT(__movstr);
|
||||
DECLARE_EXPORT(__movstrSI16);
|
||||
|
||||
EXPORT_SYMBOL(strcpy);
|
||||
|
||||
#ifdef CONFIG_CPU_SH4
|
||||
DECLARE_EXPORT(__movstr_i4_even);
|
||||
DECLARE_EXPORT(__movstr_i4_odd);
|
||||
|
@ -37,7 +37,7 @@
|
||||
asmlinkage int
|
||||
sys_sigsuspend(old_sigset_t mask,
|
||||
unsigned long r5, unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
mask &= _BLOCKABLE;
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
@ -52,7 +52,7 @@ sys_sigsuspend(old_sigset_t mask,
|
||||
return -ERESTARTNOHAND;
|
||||
}
|
||||
|
||||
asmlinkage int
|
||||
asmlinkage int
|
||||
sys_sigaction(int sig, const struct old_sigaction __user *act,
|
||||
struct old_sigaction __user *oact)
|
||||
{
|
||||
@ -87,9 +87,11 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
|
||||
asmlinkage int
|
||||
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
return do_sigaltstack(uss, uoss, regs.regs[15]);
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
|
||||
return do_sigaltstack(uss, uoss, regs->regs[15]);
|
||||
}
|
||||
|
||||
|
||||
@ -98,7 +100,11 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
|
||||
*/
|
||||
|
||||
#define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
|
||||
#define TRAP16 0xc310 /* Syscall w/no args (NR in R3) */
|
||||
#if defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH2A)
|
||||
#define TRAP_NOARG 0xc320 /* Syscall w/no args (NR in R3) */
|
||||
#else
|
||||
#define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) */
|
||||
#endif
|
||||
#define OR_R0_R0 0x200b /* or r0,r0 (insert to avoid hardware bug) */
|
||||
|
||||
struct sigframe
|
||||
@ -194,9 +200,10 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p
|
||||
|
||||
asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct sigframe __user *frame = (struct sigframe __user *)regs.regs[15];
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
struct sigframe __user *frame = (struct sigframe __user *)regs->regs[15];
|
||||
sigset_t set;
|
||||
int r0;
|
||||
|
||||
@ -216,7 +223,7 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
if (restore_sigcontext(®s, &frame->sc, &r0))
|
||||
if (restore_sigcontext(regs, &frame->sc, &r0))
|
||||
goto badframe;
|
||||
return r0;
|
||||
|
||||
@ -227,9 +234,10 @@ badframe:
|
||||
|
||||
asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs.regs[15];
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs->regs[15];
|
||||
sigset_t set;
|
||||
stack_t st;
|
||||
int r0;
|
||||
@ -246,14 +254,14 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
if (restore_sigcontext(®s, &frame->uc.uc_mcontext, &r0))
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
|
||||
goto badframe;
|
||||
|
||||
if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
|
||||
goto badframe;
|
||||
/* It is more difficult to avoid calling this function than to
|
||||
call it and ignore errors. */
|
||||
do_sigaltstack(&st, NULL, regs.regs[15]);
|
||||
do_sigaltstack(&st, NULL, regs->regs[15]);
|
||||
|
||||
return r0;
|
||||
|
||||
@ -350,7 +358,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
|
||||
} else {
|
||||
/* Generate return code (system call to sigreturn) */
|
||||
err |= __put_user(MOVW(7), &frame->retcode[0]);
|
||||
err |= __put_user(TRAP16, &frame->retcode[1]);
|
||||
err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
|
||||
err |= __put_user(OR_R0_R0, &frame->retcode[2]);
|
||||
err |= __put_user(OR_R0_R0, &frame->retcode[3]);
|
||||
err |= __put_user(OR_R0_R0, &frame->retcode[4]);
|
||||
@ -430,7 +438,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
} else {
|
||||
/* Generate return code (system call to rt_sigreturn) */
|
||||
err |= __put_user(MOVW(7), &frame->retcode[0]);
|
||||
err |= __put_user(TRAP16, &frame->retcode[1]);
|
||||
err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
|
||||
err |= __put_user(OR_R0_R0, &frame->retcode[2]);
|
||||
err |= __put_user(OR_R0_R0, &frame->retcode[3]);
|
||||
err |= __put_user(OR_R0_R0, &frame->retcode[4]);
|
||||
|
43
arch/sh/kernel/stacktrace.c
Normal file
43
arch/sh/kernel/stacktrace.c
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* arch/sh/kernel/stacktrace.c
|
||||
*
|
||||
* Stack trace management functions
|
||||
*
|
||||
* Copyright (C) 2006 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/sched.h>
|
||||
#include <linux/stacktrace.h>
|
||||
#include <linux/thread_info.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
/*
|
||||
* Save stack-backtrace addresses into a stack_trace buffer.
|
||||
*/
|
||||
void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
|
||||
{
|
||||
unsigned long *sp;
|
||||
|
||||
if (!task)
|
||||
task = current;
|
||||
if (task == current)
|
||||
sp = (unsigned long *)current_stack_pointer;
|
||||
else
|
||||
sp = (unsigned long *)task->thread.sp;
|
||||
|
||||
while (!kstack_end(sp)) {
|
||||
unsigned long addr = *sp++;
|
||||
|
||||
if (__kernel_text_address(addr)) {
|
||||
if (trace->skip > 0)
|
||||
trace->skip--;
|
||||
else
|
||||
trace->entries[trace->nr_entries++] = addr;
|
||||
if (trace->nr_entries >= trace->max_entries)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -33,14 +33,15 @@
|
||||
*/
|
||||
asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
int fd[2];
|
||||
int error;
|
||||
|
||||
error = do_pipe(fd);
|
||||
if (!error) {
|
||||
regs.regs[1] = fd[1];
|
||||
regs->regs[1] = fd[1];
|
||||
return fd[0];
|
||||
}
|
||||
return error;
|
||||
@ -50,6 +51,7 @@ unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
|
||||
|
||||
EXPORT_SYMBOL(shm_align_mask);
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
/*
|
||||
* To avoid cache aliases, we map the shared page with same color.
|
||||
*/
|
||||
@ -135,6 +137,7 @@ full_search:
|
||||
addr = COLOUR_ALIGN(addr, pgoff);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
static inline long
|
||||
do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/profile.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/sched.h>
|
||||
#include <asm/clock.h>
|
||||
#include <asm/rtc.h>
|
||||
#include <asm/timer.h>
|
||||
@ -50,15 +52,20 @@ unsigned long long __attribute__ ((weak)) sched_clock(void)
|
||||
#ifndef CONFIG_GENERIC_TIME
|
||||
void do_gettimeofday(struct timeval *tv)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long seq;
|
||||
unsigned long usec, sec;
|
||||
|
||||
do {
|
||||
seq = read_seqbegin(&xtime_lock);
|
||||
/*
|
||||
* Turn off IRQs when grabbing xtime_lock, so that
|
||||
* the sys_timer get_offset code doesn't have to handle it.
|
||||
*/
|
||||
seq = read_seqbegin_irqsave(&xtime_lock, flags);
|
||||
usec = get_timer_offset();
|
||||
sec = xtime.tv_sec;
|
||||
usec += xtime.tv_nsec / 1000;
|
||||
} while (read_seqretry(&xtime_lock, seq));
|
||||
usec += xtime.tv_nsec / NSEC_PER_USEC;
|
||||
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
|
||||
|
||||
while (usec >= 1000000) {
|
||||
usec -= 1000000;
|
||||
@ -85,7 +92,7 @@ int do_settimeofday(struct timespec *tv)
|
||||
* wall time. Discover what correction gettimeofday() would have
|
||||
* made, and then undo it!
|
||||
*/
|
||||
nsec -= 1000 * get_timer_offset();
|
||||
nsec -= get_timer_offset() * NSEC_PER_USEC;
|
||||
|
||||
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
|
||||
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
|
||||
@ -169,6 +176,108 @@ static struct sysdev_class timer_sysclass = {
|
||||
.resume = timer_resume,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
static int timer_dyn_tick_enable(void)
|
||||
{
|
||||
struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick;
|
||||
unsigned long flags;
|
||||
int ret = -ENODEV;
|
||||
|
||||
if (dyn_tick) {
|
||||
spin_lock_irqsave(&dyn_tick->lock, flags);
|
||||
ret = 0;
|
||||
if (!(dyn_tick->state & DYN_TICK_ENABLED)) {
|
||||
ret = dyn_tick->enable();
|
||||
|
||||
if (ret == 0)
|
||||
dyn_tick->state |= DYN_TICK_ENABLED;
|
||||
}
|
||||
spin_unlock_irqrestore(&dyn_tick->lock, flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int timer_dyn_tick_disable(void)
|
||||
{
|
||||
struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick;
|
||||
unsigned long flags;
|
||||
int ret = -ENODEV;
|
||||
|
||||
if (dyn_tick) {
|
||||
spin_lock_irqsave(&dyn_tick->lock, flags);
|
||||
ret = 0;
|
||||
if (dyn_tick->state & DYN_TICK_ENABLED) {
|
||||
ret = dyn_tick->disable();
|
||||
|
||||
if (ret == 0)
|
||||
dyn_tick->state &= ~DYN_TICK_ENABLED;
|
||||
}
|
||||
spin_unlock_irqrestore(&dyn_tick->lock, flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reprogram the system timer for at least the calculated time interval.
|
||||
* This function should be called from the idle thread with IRQs disabled,
|
||||
* immediately before sleeping.
|
||||
*/
|
||||
void timer_dyn_reprogram(void)
|
||||
{
|
||||
struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick;
|
||||
unsigned long next, seq, flags;
|
||||
|
||||
if (!dyn_tick)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&dyn_tick->lock, flags);
|
||||
if (dyn_tick->state & DYN_TICK_ENABLED) {
|
||||
next = next_timer_interrupt();
|
||||
do {
|
||||
seq = read_seqbegin(&xtime_lock);
|
||||
dyn_tick->reprogram(next - jiffies);
|
||||
} while (read_seqretry(&xtime_lock, seq));
|
||||
}
|
||||
spin_unlock_irqrestore(&dyn_tick->lock, flags);
|
||||
}
|
||||
|
||||
static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%i\n",
|
||||
(sys_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1);
|
||||
}
|
||||
|
||||
static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
unsigned int enable = simple_strtoul(buf, NULL, 2);
|
||||
|
||||
if (enable)
|
||||
timer_dyn_tick_enable();
|
||||
else
|
||||
timer_dyn_tick_disable();
|
||||
|
||||
return count;
|
||||
}
|
||||
static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick);
|
||||
|
||||
/*
|
||||
* dyntick=enable|disable
|
||||
*/
|
||||
static char dyntick_str[4] __initdata = "";
|
||||
|
||||
static int __init dyntick_setup(char *str)
|
||||
{
|
||||
if (str)
|
||||
strlcpy(dyntick_str, str, sizeof(dyntick_str));
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("dyntick=", dyntick_setup);
|
||||
#endif
|
||||
|
||||
static int __init timer_init_sysfs(void)
|
||||
{
|
||||
int ret = sysdev_class_register(&timer_sysclass);
|
||||
@ -176,7 +285,22 @@ static int __init timer_init_sysfs(void)
|
||||
return ret;
|
||||
|
||||
sys_timer->dev.cls = &timer_sysclass;
|
||||
return sysdev_register(&sys_timer->dev);
|
||||
ret = sysdev_register(&sys_timer->dev);
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
if (ret == 0 && sys_timer->dyn_tick) {
|
||||
ret = sysdev_create_file(&sys_timer->dev, &attr_dyn_tick);
|
||||
|
||||
/*
|
||||
* Turn on dynamic tick after calibrate delay
|
||||
* for correct bogomips
|
||||
*/
|
||||
if (ret == 0 && dyntick_str[0] == 'e')
|
||||
ret = timer_dyn_tick_enable();
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
device_initcall(timer_init_sysfs);
|
||||
|
||||
@ -200,6 +324,11 @@ void __init time_init(void)
|
||||
sys_timer = get_sys_timer();
|
||||
printk(KERN_INFO "Using %s for system timer\n", sys_timer->name);
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
if (sys_timer->dyn_tick)
|
||||
spin_lock_init(&sys_timer->dyn_tick->lock);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SH_KGDB)
|
||||
/*
|
||||
* Set up kgdb as requested. We do it here because the serial
|
||||
|
@ -5,4 +5,6 @@
|
||||
obj-y := timer.o
|
||||
|
||||
obj-$(CONFIG_SH_TMU) += timer-tmu.o
|
||||
obj-$(CONFIG_SH_MTU2) += timer-mtu2.o
|
||||
obj-$(CONFIG_SH_CMT) += timer-cmt.o
|
||||
|
||||
|
196
arch/sh/kernel/timers/timer-cmt.c
Normal file
196
arch/sh/kernel/timers/timer-cmt.c
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* arch/sh/kernel/timers/timer-cmt.c - CMT Timer Support
|
||||
*
|
||||
* Copyright (C) 2005 Yoshinori Sato
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/seqlock.h>
|
||||
#include <asm/timer.h>
|
||||
#include <asm/rtc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/clock.h>
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7619)
|
||||
#define CMT_CMSTR 0xf84a0070
|
||||
#define CMT_CMCSR_0 0xf84a0072
|
||||
#define CMT_CMCNT_0 0xf84a0074
|
||||
#define CMT_CMCOR_0 0xf84a0076
|
||||
#define CMT_CMCSR_1 0xf84a0078
|
||||
#define CMT_CMCNT_1 0xf84a007a
|
||||
#define CMT_CMCOR_1 0xf84a007c
|
||||
|
||||
#define STBCR3 0xf80a0000
|
||||
#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR3) & ~0x10, STBCR3); } while(0)
|
||||
#define CMT_CMCSR_INIT 0x0040
|
||||
#define CMT_CMCSR_CALIB 0x0000
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7206)
|
||||
#define CMT_CMSTR 0xfffec000
|
||||
#define CMT_CMCSR_0 0xfffec002
|
||||
#define CMT_CMCNT_0 0xfffec004
|
||||
#define CMT_CMCOR_0 0xfffec006
|
||||
|
||||
#define STBCR4 0xfffe040c
|
||||
#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR4) & ~0x04, STBCR4); } while(0)
|
||||
#define CMT_CMCSR_INIT 0x0040
|
||||
#define CMT_CMCSR_CALIB 0x0000
|
||||
#else
|
||||
#error "Unknown CPU SUBTYPE"
|
||||
#endif
|
||||
|
||||
static unsigned long cmt_timer_get_offset(void)
|
||||
{
|
||||
int count;
|
||||
static unsigned short count_p = 0xffff; /* for the first call after boot */
|
||||
static unsigned long jiffies_p = 0;
|
||||
|
||||
/*
|
||||
* cache volatile jiffies temporarily; we have IRQs turned off.
|
||||
*/
|
||||
unsigned long jiffies_t;
|
||||
|
||||
/* timer count may underflow right here */
|
||||
count = ctrl_inw(CMT_CMCOR_0);
|
||||
count -= ctrl_inw(CMT_CMCNT_0);
|
||||
|
||||
jiffies_t = jiffies;
|
||||
|
||||
/*
|
||||
* avoiding timer inconsistencies (they are rare, but they happen)...
|
||||
* there is one kind of problem that must be avoided here:
|
||||
* 1. the timer counter underflows
|
||||
*/
|
||||
|
||||
if (jiffies_t == jiffies_p) {
|
||||
if (count > count_p) {
|
||||
/* the nutcase */
|
||||
if (ctrl_inw(CMT_CMCSR_0) & 0x80) { /* Check CMF bit */
|
||||
count -= LATCH;
|
||||
} else {
|
||||
printk("%s (): hardware timer problem?\n",
|
||||
__FUNCTION__);
|
||||
}
|
||||
}
|
||||
} else
|
||||
jiffies_p = jiffies_t;
|
||||
|
||||
count_p = count;
|
||||
|
||||
count = ((LATCH-1) - count) * TICK_SIZE;
|
||||
count = (count + LATCH/2) / LATCH;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
unsigned long timer_status;
|
||||
|
||||
/* Clear CMF bit */
|
||||
timer_status = ctrl_inw(CMT_CMCSR_0);
|
||||
timer_status &= ~0x80;
|
||||
ctrl_outw(timer_status, CMT_CMCSR_0);
|
||||
|
||||
/*
|
||||
* Here we are in the timer irq handler. We just have irqs locally
|
||||
* disabled but we don't know if the timer_bh is running on the other
|
||||
* CPU. We need to avoid to SMP race with it. NOTE: we don' t need
|
||||
* the irq version of write_lock because as just said we have irq
|
||||
* locally disabled. -arca
|
||||
*/
|
||||
write_seqlock(&xtime_lock);
|
||||
handle_timer_tick();
|
||||
write_sequnlock(&xtime_lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction cmt_irq = {
|
||||
.name = "timer",
|
||||
.handler = cmt_timer_interrupt,
|
||||
.flags = IRQF_DISABLED | IRQF_TIMER,
|
||||
.mask = CPU_MASK_NONE,
|
||||
};
|
||||
|
||||
static void cmt_clk_init(struct clk *clk)
|
||||
{
|
||||
u8 divisor = CMT_CMCSR_INIT & 0x3;
|
||||
ctrl_inw(CMT_CMCSR_0);
|
||||
ctrl_outw(CMT_CMCSR_INIT, CMT_CMCSR_0);
|
||||
clk->parent = clk_get(NULL, "module_clk");
|
||||
clk->rate = clk->parent->rate / (8 << (divisor << 1));
|
||||
}
|
||||
|
||||
static void cmt_clk_recalc(struct clk *clk)
|
||||
{
|
||||
u8 divisor = ctrl_inw(CMT_CMCSR_0) & 0x3;
|
||||
clk->rate = clk->parent->rate / (8 << (divisor << 1));
|
||||
}
|
||||
|
||||
static struct clk_ops cmt_clk_ops = {
|
||||
.init = cmt_clk_init,
|
||||
.recalc = cmt_clk_recalc,
|
||||
};
|
||||
|
||||
static struct clk cmt0_clk = {
|
||||
.name = "cmt0_clk",
|
||||
.ops = &cmt_clk_ops,
|
||||
};
|
||||
|
||||
static int cmt_timer_start(void)
|
||||
{
|
||||
ctrl_outw(ctrl_inw(CMT_CMSTR) | 0x01, CMT_CMSTR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmt_timer_stop(void)
|
||||
{
|
||||
ctrl_outw(ctrl_inw(CMT_CMSTR) & ~0x01, CMT_CMSTR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmt_timer_init(void)
|
||||
{
|
||||
unsigned long interval;
|
||||
|
||||
cmt_clock_enable();
|
||||
|
||||
setup_irq(CONFIG_SH_TIMER_IRQ, &cmt_irq);
|
||||
|
||||
cmt0_clk.parent = clk_get(NULL, "module_clk");
|
||||
|
||||
cmt_timer_stop();
|
||||
|
||||
interval = cmt0_clk.parent->rate / 8 / HZ;
|
||||
printk(KERN_INFO "Interval = %ld\n", interval);
|
||||
|
||||
ctrl_outw(interval, CMT_CMCOR_0);
|
||||
|
||||
clk_register(&cmt0_clk);
|
||||
clk_enable(&cmt0_clk);
|
||||
|
||||
cmt_timer_start();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sys_timer_ops cmt_timer_ops = {
|
||||
.init = cmt_timer_init,
|
||||
.start = cmt_timer_start,
|
||||
.stop = cmt_timer_stop,
|
||||
#ifndef CONFIG_GENERIC_TIME
|
||||
.get_offset = cmt_timer_get_offset,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct sys_timer cmt_timer = {
|
||||
.name = "cmt",
|
||||
.ops = &cmt_timer_ops,
|
||||
};
|
200
arch/sh/kernel/timers/timer-mtu2.c
Normal file
200
arch/sh/kernel/timers/timer-mtu2.c
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* arch/sh/kernel/timers/timer-mtu2.c - MTU2 Timer Support
|
||||
*
|
||||
* Copyright (C) 2005 Paul Mundt
|
||||
*
|
||||
* Based off of arch/sh/kernel/timers/timer-tmu.c
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/seqlock.h>
|
||||
#include <asm/timer.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/clock.h>
|
||||
|
||||
/*
|
||||
* We use channel 1 for our lowly system timer. Channel 2 would be the other
|
||||
* likely candidate, but we leave it alone as it has higher divisors that
|
||||
* would be of more use to other more interesting applications.
|
||||
*
|
||||
* TODO: Presently we only implement a 16-bit single-channel system timer.
|
||||
* However, we can implement channel cascade if we go the overflow route and
|
||||
* get away with using 2 MTU2 channels as a 32-bit timer.
|
||||
*/
|
||||
#define MTU2_TSTR 0xfffe4280
|
||||
#define MTU2_TCR_1 0xfffe4380
|
||||
#define MTU2_TMDR_1 0xfffe4381
|
||||
#define MTU2_TIOR_1 0xfffe4382
|
||||
#define MTU2_TIER_1 0xfffe4384
|
||||
#define MTU2_TSR_1 0xfffe4385
|
||||
#define MTU2_TCNT_1 0xfffe4386 /* 16-bit counter */
|
||||
#define MTU2_TGRA_1 0xfffe438a
|
||||
|
||||
#define STBCR3 0xfffe0408
|
||||
|
||||
#define MTU2_TSTR_CST1 (1 << 1) /* Counter Start 1 */
|
||||
|
||||
#define MTU2_TSR_TGFA (1 << 0) /* GRA compare match */
|
||||
|
||||
#define MTU2_TIER_TGIEA (1 << 0) /* GRA compare match interrupt enable */
|
||||
|
||||
#define MTU2_TCR_INIT 0x22
|
||||
|
||||
#define MTU2_TCR_CALIB 0x00
|
||||
|
||||
static unsigned long mtu2_timer_get_offset(void)
|
||||
{
|
||||
int count;
|
||||
static int count_p = 0x7fff; /* for the first call after boot */
|
||||
static unsigned long jiffies_p = 0;
|
||||
|
||||
/*
|
||||
* cache volatile jiffies temporarily; we have IRQs turned off.
|
||||
*/
|
||||
unsigned long jiffies_t;
|
||||
|
||||
/* timer count may underflow right here */
|
||||
count = ctrl_inw(MTU2_TCNT_1); /* read the latched count */
|
||||
|
||||
jiffies_t = jiffies;
|
||||
|
||||
/*
|
||||
* avoiding timer inconsistencies (they are rare, but they happen)...
|
||||
* there is one kind of problem that must be avoided here:
|
||||
* 1. the timer counter underflows
|
||||
*/
|
||||
|
||||
if (jiffies_t == jiffies_p) {
|
||||
if (count > count_p) {
|
||||
if (ctrl_inb(MTU2_TSR_1) & MTU2_TSR_TGFA) {
|
||||
count -= LATCH;
|
||||
} else {
|
||||
printk("%s (): hardware timer problem?\n",
|
||||
__FUNCTION__);
|
||||
}
|
||||
}
|
||||
} else
|
||||
jiffies_p = jiffies_t;
|
||||
|
||||
count_p = count;
|
||||
|
||||
count = ((LATCH-1) - count) * TICK_SIZE;
|
||||
count = (count + LATCH/2) / LATCH;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
unsigned long timer_status;
|
||||
|
||||
/* Clear TGFA bit */
|
||||
timer_status = ctrl_inb(MTU2_TSR_1);
|
||||
timer_status &= ~MTU2_TSR_TGFA;
|
||||
ctrl_outb(timer_status, MTU2_TSR_1);
|
||||
|
||||
/* Do timer tick */
|
||||
write_seqlock(&xtime_lock);
|
||||
handle_timer_tick();
|
||||
write_sequnlock(&xtime_lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction mtu2_irq = {
|
||||
.name = "timer",
|
||||
.handler = mtu2_timer_interrupt,
|
||||
.flags = IRQF_DISABLED | IRQF_TIMER,
|
||||
.mask = CPU_MASK_NONE,
|
||||
};
|
||||
|
||||
static unsigned int divisors[] = { 1, 4, 16, 64, 1, 1, 256 };
|
||||
|
||||
static void mtu2_clk_init(struct clk *clk)
|
||||
{
|
||||
u8 idx = MTU2_TCR_INIT & 0x7;
|
||||
|
||||
clk->rate = clk->parent->rate / divisors[idx];
|
||||
/* Start TCNT counting */
|
||||
ctrl_outb(ctrl_inb(MTU2_TSTR) | MTU2_TSTR_CST1, MTU2_TSTR);
|
||||
|
||||
}
|
||||
|
||||
static void mtu2_clk_recalc(struct clk *clk)
|
||||
{
|
||||
u8 idx = ctrl_inb(MTU2_TCR_1) & 0x7;
|
||||
clk->rate = clk->parent->rate / divisors[idx];
|
||||
}
|
||||
|
||||
static struct clk_ops mtu2_clk_ops = {
|
||||
.init = mtu2_clk_init,
|
||||
.recalc = mtu2_clk_recalc,
|
||||
};
|
||||
|
||||
static struct clk mtu2_clk1 = {
|
||||
.name = "mtu2_clk1",
|
||||
.ops = &mtu2_clk_ops,
|
||||
};
|
||||
|
||||
static int mtu2_timer_start(void)
|
||||
{
|
||||
ctrl_outb(ctrl_inb(MTU2_TSTR) | MTU2_TSTR_CST1, MTU2_TSTR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtu2_timer_stop(void)
|
||||
{
|
||||
ctrl_outb(ctrl_inb(MTU2_TSTR) & ~MTU2_TSTR_CST1, MTU2_TSTR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtu2_timer_init(void)
|
||||
{
|
||||
u8 tmp;
|
||||
unsigned long interval;
|
||||
|
||||
setup_irq(CONFIG_SH_TIMER_IRQ, &mtu2_irq);
|
||||
|
||||
mtu2_clk1.parent = clk_get(NULL, "module_clk");
|
||||
|
||||
ctrl_outb(ctrl_inb(STBCR3) & (~0x20), STBCR3);
|
||||
|
||||
/* Normal operation */
|
||||
ctrl_outb(0, MTU2_TMDR_1);
|
||||
ctrl_outb(MTU2_TCR_INIT, MTU2_TCR_1);
|
||||
ctrl_outb(0x01, MTU2_TIOR_1);
|
||||
|
||||
/* Enable underflow interrupt */
|
||||
ctrl_outb(ctrl_inb(MTU2_TIER_1) | MTU2_TIER_TGIEA, MTU2_TIER_1);
|
||||
|
||||
interval = CONFIG_SH_PCLK_FREQ / 16 / HZ;
|
||||
printk(KERN_INFO "Interval = %ld\n", interval);
|
||||
|
||||
ctrl_outw(interval, MTU2_TGRA_1);
|
||||
ctrl_outw(0, MTU2_TCNT_1);
|
||||
|
||||
clk_register(&mtu2_clk1);
|
||||
clk_enable(&mtu2_clk1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sys_timer_ops mtu2_timer_ops = {
|
||||
.init = mtu2_timer_init,
|
||||
.start = mtu2_timer_start,
|
||||
.stop = mtu2_timer_stop,
|
||||
#ifndef CONFIG_GENERIC_TIME
|
||||
.get_offset = mtu2_timer_get_offset,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct sys_timer mtu2_timer = {
|
||||
.name = "mtu2",
|
||||
.ops = &mtu2_timer_ops,
|
||||
};
|
@ -17,7 +17,6 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/seqlock.h>
|
||||
#include <asm/timer.h>
|
||||
#include <asm/rtc.h>
|
||||
@ -31,13 +30,9 @@
|
||||
|
||||
#define TMU0_TCR_CALIB 0x0000
|
||||
|
||||
static DEFINE_SPINLOCK(tmu0_lock);
|
||||
|
||||
static unsigned long tmu_timer_get_offset(void)
|
||||
{
|
||||
int count;
|
||||
unsigned long flags;
|
||||
|
||||
static int count_p = 0x7fffffff; /* for the first call after boot */
|
||||
static unsigned long jiffies_p = 0;
|
||||
|
||||
@ -46,7 +41,6 @@ static unsigned long tmu_timer_get_offset(void)
|
||||
*/
|
||||
unsigned long jiffies_t;
|
||||
|
||||
spin_lock_irqsave(&tmu0_lock, flags);
|
||||
/* timer count may underflow right here */
|
||||
count = ctrl_inl(TMU0_TCNT); /* read the latched count */
|
||||
|
||||
@ -72,7 +66,6 @@ static unsigned long tmu_timer_get_offset(void)
|
||||
jiffies_p = jiffies_t;
|
||||
|
||||
count_p = count;
|
||||
spin_unlock_irqrestore(&tmu0_lock, flags);
|
||||
|
||||
count = ((LATCH-1) - count) * TICK_SIZE;
|
||||
count = (count + LATCH/2) / LATCH;
|
||||
@ -106,7 +99,7 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dummy)
|
||||
static struct irqaction tmu_irq = {
|
||||
.name = "timer",
|
||||
.handler = tmu_timer_interrupt,
|
||||
.flags = IRQF_DISABLED,
|
||||
.flags = IRQF_DISABLED | IRQF_TIMER,
|
||||
.mask = CPU_MASK_NONE,
|
||||
};
|
||||
|
||||
@ -149,9 +142,9 @@ static int tmu_timer_init(void)
|
||||
{
|
||||
unsigned long interval;
|
||||
|
||||
setup_irq(TIMER_IRQ, &tmu_irq);
|
||||
setup_irq(CONFIG_SH_TIMER_IRQ, &tmu_irq);
|
||||
|
||||
tmu0_clk.parent = clk_get("module_clk");
|
||||
tmu0_clk.parent = clk_get(NULL, "module_clk");
|
||||
|
||||
/* Start TMU0 */
|
||||
tmu_timer_stop();
|
||||
|
@ -16,6 +16,12 @@
|
||||
static struct sys_timer *sys_timers[] __initdata = {
|
||||
#ifdef CONFIG_SH_TMU
|
||||
&tmu_timer,
|
||||
#endif
|
||||
#ifdef CONFIG_SH_MTU2
|
||||
&mtu2_timer,
|
||||
#endif
|
||||
#ifdef CONFIG_SH_CMT
|
||||
&cmt_timer,
|
||||
#endif
|
||||
NULL,
|
||||
};
|
||||
|
@ -18,13 +18,14 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/debug_locks.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#ifdef CONFIG_SH_KGDB
|
||||
#include <asm/kgdb.h>
|
||||
#define CHK_REMOTE_DEBUG(regs) \
|
||||
{ \
|
||||
#define CHK_REMOTE_DEBUG(regs) \
|
||||
{ \
|
||||
if (kgdb_debug_hook && !user_mode(regs))\
|
||||
(*kgdb_debug_hook)(regs); \
|
||||
}
|
||||
@ -33,8 +34,13 @@
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_SH2
|
||||
#define TRAP_RESERVED_INST 4
|
||||
#define TRAP_ILLEGAL_SLOT_INST 6
|
||||
# define TRAP_RESERVED_INST 4
|
||||
# define TRAP_ILLEGAL_SLOT_INST 6
|
||||
# define TRAP_ADDRESS_ERROR 9
|
||||
# ifdef CONFIG_CPU_SH2A
|
||||
# define TRAP_DIVZERO_ERROR 17
|
||||
# define TRAP_DIVOVF_ERROR 18
|
||||
# endif
|
||||
#else
|
||||
#define TRAP_RESERVED_INST 12
|
||||
#define TRAP_ILLEGAL_SLOT_INST 13
|
||||
@ -88,7 +94,7 @@ void die(const char * str, struct pt_regs * regs, long err)
|
||||
|
||||
if (!user_mode(regs) || in_interrupt())
|
||||
dump_mem("Stack: ", regs->regs[15], THREAD_SIZE +
|
||||
(unsigned long)task_stack_page(current));
|
||||
(unsigned long)task_stack_page(current));
|
||||
|
||||
bust_spinlocks(0);
|
||||
spin_unlock_irq(&die_lock);
|
||||
@ -102,8 +108,6 @@ static inline void die_if_kernel(const char *str, struct pt_regs *regs,
|
||||
die(str, regs, err);
|
||||
}
|
||||
|
||||
static int handle_unaligned_notify_count = 10;
|
||||
|
||||
/*
|
||||
* try and fix up kernelspace address errors
|
||||
* - userspace errors just cause EFAULT to be returned, resulting in SEGV
|
||||
@ -198,7 +202,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs)
|
||||
if (copy_to_user(dst,src,4))
|
||||
goto fetch_fault;
|
||||
ret = 0;
|
||||
break;
|
||||
break;
|
||||
|
||||
case 2: /* mov.[bwl] to memory, possibly with pre-decrement */
|
||||
if (instruction & 4)
|
||||
@ -222,7 +226,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs)
|
||||
if (copy_from_user(dst,src,4))
|
||||
goto fetch_fault;
|
||||
ret = 0;
|
||||
break;
|
||||
break;
|
||||
|
||||
case 6: /* mov.[bwl] from memory, possibly with post-increment */
|
||||
src = (unsigned char*) *rm;
|
||||
@ -230,7 +234,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs)
|
||||
*rm += count;
|
||||
dst = (unsigned char*) rn;
|
||||
*(unsigned long*)dst = 0;
|
||||
|
||||
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
if (copy_from_user(dst, src, count))
|
||||
goto fetch_fault;
|
||||
@ -241,7 +245,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs)
|
||||
}
|
||||
#else
|
||||
dst += 4-count;
|
||||
|
||||
|
||||
if (copy_from_user(dst, src, count))
|
||||
goto fetch_fault;
|
||||
|
||||
@ -320,7 +324,8 @@ static inline int handle_unaligned_delayslot(struct pt_regs *regs)
|
||||
return -EFAULT;
|
||||
|
||||
/* kernel */
|
||||
die("delay-slot-insn faulting in handle_unaligned_delayslot", regs, 0);
|
||||
die("delay-slot-insn faulting in handle_unaligned_delayslot",
|
||||
regs, 0);
|
||||
}
|
||||
|
||||
return handle_unaligned_ins(instruction,regs);
|
||||
@ -342,6 +347,13 @@ static inline int handle_unaligned_delayslot(struct pt_regs *regs)
|
||||
#define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4)
|
||||
#define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4)
|
||||
|
||||
/*
|
||||
* XXX: SH-2A needs this too, but it needs an overhaul thanks to mixed 32-bit
|
||||
* opcodes..
|
||||
*/
|
||||
#ifndef CONFIG_CPU_SH2A
|
||||
static int handle_unaligned_notify_count = 10;
|
||||
|
||||
static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
|
||||
{
|
||||
u_int rm;
|
||||
@ -354,7 +366,8 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
|
||||
if (user_mode(regs) && handle_unaligned_notify_count>0) {
|
||||
handle_unaligned_notify_count--;
|
||||
|
||||
printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
|
||||
printk(KERN_NOTICE "Fixing up unaligned userspace access "
|
||||
"in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
|
||||
current->comm,current->pid,(u16*)regs->pc,instruction);
|
||||
}
|
||||
|
||||
@ -478,32 +491,58 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
|
||||
regs->pc += 2;
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_CPU_SH2A */
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_SR_RB
|
||||
#define lookup_exception_vector(x) \
|
||||
__asm__ __volatile__ ("stc r2_bank, %0\n\t" : "=r" ((x)))
|
||||
#else
|
||||
#define lookup_exception_vector(x) \
|
||||
__asm__ __volatile__ ("mov r4, %0\n\t" : "=r" ((x)))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Handle various address error exceptions
|
||||
* Handle various address error exceptions:
|
||||
* - instruction address error:
|
||||
* misaligned PC
|
||||
* PC >= 0x80000000 in user mode
|
||||
* - data address error (read and write)
|
||||
* misaligned data access
|
||||
* access to >= 0x80000000 is user mode
|
||||
* Unfortuntaly we can't distinguish between instruction address error
|
||||
* and data address errors caused by read acceses.
|
||||
*/
|
||||
asmlinkage void do_address_error(struct pt_regs *regs,
|
||||
asmlinkage void do_address_error(struct pt_regs *regs,
|
||||
unsigned long writeaccess,
|
||||
unsigned long address)
|
||||
{
|
||||
unsigned long error_code;
|
||||
unsigned long error_code = 0;
|
||||
mm_segment_t oldfs;
|
||||
siginfo_t info;
|
||||
#ifndef CONFIG_CPU_SH2A
|
||||
u16 instruction;
|
||||
int tmp;
|
||||
#endif
|
||||
|
||||
asm volatile("stc r2_bank,%0": "=r" (error_code));
|
||||
/* Intentional ifdef */
|
||||
#ifdef CONFIG_CPU_HAS_SR_RB
|
||||
lookup_exception_vector(error_code);
|
||||
#endif
|
||||
|
||||
oldfs = get_fs();
|
||||
|
||||
if (user_mode(regs)) {
|
||||
int si_code = BUS_ADRERR;
|
||||
|
||||
local_irq_enable();
|
||||
current->thread.error_code = error_code;
|
||||
current->thread.trap_no = (writeaccess) ? 8 : 7;
|
||||
|
||||
/* bad PC is not something we can fix */
|
||||
if (regs->pc & 1)
|
||||
if (regs->pc & 1) {
|
||||
si_code = BUS_ADRALN;
|
||||
goto uspace_segv;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_CPU_SH2A
|
||||
set_fs(USER_DS);
|
||||
if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) {
|
||||
/* Argh. Fault on the instruction itself.
|
||||
@ -518,14 +557,23 @@ asmlinkage void do_address_error(struct pt_regs *regs,
|
||||
|
||||
if (tmp==0)
|
||||
return; /* sorted */
|
||||
#endif
|
||||
|
||||
uspace_segv:
|
||||
printk(KERN_NOTICE "Killing process \"%s\" due to unaligned access\n", current->comm);
|
||||
force_sig(SIGSEGV, current);
|
||||
uspace_segv:
|
||||
printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned "
|
||||
"access (PC %lx PR %lx)\n", current->comm, regs->pc,
|
||||
regs->pr);
|
||||
|
||||
info.si_signo = SIGBUS;
|
||||
info.si_errno = 0;
|
||||
info.si_code = si_code;
|
||||
info.si_addr = (void *) address;
|
||||
force_sig_info(SIGBUS, &info, current);
|
||||
} else {
|
||||
if (regs->pc & 1)
|
||||
die("unaligned program counter", regs, error_code);
|
||||
|
||||
#ifndef CONFIG_CPU_SH2A
|
||||
set_fs(KERNEL_DS);
|
||||
if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) {
|
||||
/* Argh. Fault on the instruction itself.
|
||||
@ -537,6 +585,12 @@ asmlinkage void do_address_error(struct pt_regs *regs,
|
||||
|
||||
handle_unaligned_access(instruction, regs);
|
||||
set_fs(oldfs);
|
||||
#else
|
||||
printk(KERN_NOTICE "Killing process \"%s\" due to unaligned "
|
||||
"access\n", current->comm);
|
||||
|
||||
force_sig(SIGSEGV, current);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -548,7 +602,7 @@ int is_dsp_inst(struct pt_regs *regs)
|
||||
{
|
||||
unsigned short inst;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Safe guard if DSP mode is already enabled or we're lacking
|
||||
* the DSP altogether.
|
||||
*/
|
||||
@ -569,27 +623,49 @@ int is_dsp_inst(struct pt_regs *regs)
|
||||
#define is_dsp_inst(regs) (0)
|
||||
#endif /* CONFIG_SH_DSP */
|
||||
|
||||
#ifdef CONFIG_CPU_SH2A
|
||||
asmlinkage void do_divide_error(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
siginfo_t info;
|
||||
|
||||
switch (r4) {
|
||||
case TRAP_DIVZERO_ERROR:
|
||||
info.si_code = FPE_INTDIV;
|
||||
break;
|
||||
case TRAP_DIVOVF_ERROR:
|
||||
info.si_code = FPE_INTOVF;
|
||||
break;
|
||||
}
|
||||
|
||||
force_sig_info(SIGFPE, &info, current);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* arch/sh/kernel/cpu/sh4/fpu.c */
|
||||
extern int do_fpu_inst(unsigned short, struct pt_regs *);
|
||||
extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7, struct pt_regs regs);
|
||||
unsigned long r6, unsigned long r7, struct pt_regs __regs);
|
||||
|
||||
asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
unsigned long error_code;
|
||||
struct task_struct *tsk = current;
|
||||
|
||||
#ifdef CONFIG_SH_FPU_EMU
|
||||
unsigned short inst;
|
||||
unsigned short inst = 0;
|
||||
int err;
|
||||
|
||||
get_user(inst, (unsigned short*)regs.pc);
|
||||
get_user(inst, (unsigned short*)regs->pc);
|
||||
|
||||
err = do_fpu_inst(inst, ®s);
|
||||
err = do_fpu_inst(inst, regs);
|
||||
if (!err) {
|
||||
regs.pc += 2;
|
||||
regs->pc += 2;
|
||||
return;
|
||||
}
|
||||
/* not a FPU inst. */
|
||||
@ -597,20 +673,19 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
|
||||
|
||||
#ifdef CONFIG_SH_DSP
|
||||
/* Check if it's a DSP instruction */
|
||||
if (is_dsp_inst(®s)) {
|
||||
if (is_dsp_inst(regs)) {
|
||||
/* Enable DSP mode, and restart instruction. */
|
||||
regs.sr |= SR_DSP;
|
||||
regs->sr |= SR_DSP;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
asm volatile("stc r2_bank, %0": "=r" (error_code));
|
||||
lookup_exception_vector(error_code);
|
||||
|
||||
local_irq_enable();
|
||||
tsk->thread.error_code = error_code;
|
||||
tsk->thread.trap_no = TRAP_RESERVED_INST;
|
||||
CHK_REMOTE_DEBUG(®s);
|
||||
CHK_REMOTE_DEBUG(regs);
|
||||
force_sig(SIGILL, tsk);
|
||||
die_if_no_fixup("reserved instruction", ®s, error_code);
|
||||
die_if_no_fixup("reserved instruction", regs, error_code);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SH_FPU_EMU
|
||||
@ -658,39 +733,41 @@ static int emulate_branch(unsigned short inst, struct pt_regs* regs)
|
||||
|
||||
asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
unsigned long error_code;
|
||||
struct task_struct *tsk = current;
|
||||
#ifdef CONFIG_SH_FPU_EMU
|
||||
unsigned short inst;
|
||||
unsigned short inst = 0;
|
||||
|
||||
get_user(inst, (unsigned short *)regs.pc + 1);
|
||||
if (!do_fpu_inst(inst, ®s)) {
|
||||
get_user(inst, (unsigned short *)regs.pc);
|
||||
if (!emulate_branch(inst, ®s))
|
||||
get_user(inst, (unsigned short *)regs->pc + 1);
|
||||
if (!do_fpu_inst(inst, regs)) {
|
||||
get_user(inst, (unsigned short *)regs->pc);
|
||||
if (!emulate_branch(inst, regs))
|
||||
return;
|
||||
/* fault in branch.*/
|
||||
}
|
||||
/* not a FPU inst. */
|
||||
#endif
|
||||
|
||||
asm volatile("stc r2_bank, %0": "=r" (error_code));
|
||||
lookup_exception_vector(error_code);
|
||||
|
||||
local_irq_enable();
|
||||
tsk->thread.error_code = error_code;
|
||||
tsk->thread.trap_no = TRAP_RESERVED_INST;
|
||||
CHK_REMOTE_DEBUG(®s);
|
||||
CHK_REMOTE_DEBUG(regs);
|
||||
force_sig(SIGILL, tsk);
|
||||
die_if_no_fixup("illegal slot instruction", ®s, error_code);
|
||||
die_if_no_fixup("illegal slot instruction", regs, error_code);
|
||||
}
|
||||
|
||||
asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs regs)
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
long ex;
|
||||
asm volatile("stc r2_bank, %0" : "=r" (ex));
|
||||
die_if_kernel("exception", ®s, ex);
|
||||
|
||||
lookup_exception_vector(ex);
|
||||
die_if_kernel("exception", regs, ex);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SH_STANDARD_BIOS)
|
||||
@ -735,12 +812,16 @@ void *set_exception_table_vec(unsigned int vec, void *handler)
|
||||
{
|
||||
extern void *exception_handling_table[];
|
||||
void *old_handler;
|
||||
|
||||
|
||||
old_handler = exception_handling_table[vec];
|
||||
exception_handling_table[vec] = handler;
|
||||
return old_handler;
|
||||
}
|
||||
|
||||
extern asmlinkage void address_error_handler(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs __regs);
|
||||
|
||||
void __init trap_init(void)
|
||||
{
|
||||
set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst);
|
||||
@ -759,7 +840,15 @@ void __init trap_init(void)
|
||||
set_exception_table_evt(0x800, do_fpu_state_restore);
|
||||
set_exception_table_evt(0x820, do_fpu_state_restore);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_CPU_SH2
|
||||
set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_handler);
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_SH2A
|
||||
set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error);
|
||||
set_exception_table_vec(TRAP_DIVOVF_ERROR, do_divide_error);
|
||||
#endif
|
||||
|
||||
/* Setup VBR for boot cpu */
|
||||
per_cpu_trap_init();
|
||||
}
|
||||
@ -784,6 +873,11 @@ void show_trace(struct task_struct *tsk, unsigned long *sp,
|
||||
}
|
||||
|
||||
printk("\n");
|
||||
|
||||
if (!tsk)
|
||||
tsk = current;
|
||||
|
||||
debug_show_held_locks(tsk);
|
||||
}
|
||||
|
||||
void show_stack(struct task_struct *tsk, unsigned long *sp)
|
||||
|
@ -4,8 +4,12 @@ menu "Processor selection"
|
||||
# Processor families
|
||||
#
|
||||
config CPU_SH2
|
||||
select SH_WRITETHROUGH if !CPU_SH2A
|
||||
bool
|
||||
select SH_WRITETHROUGH
|
||||
|
||||
config CPU_SH2A
|
||||
bool
|
||||
select CPU_SH2
|
||||
|
||||
config CPU_SH3
|
||||
bool
|
||||
@ -16,6 +20,7 @@ config CPU_SH4
|
||||
bool
|
||||
select CPU_HAS_INTEVT
|
||||
select CPU_HAS_SR_RB
|
||||
select CPU_HAS_PTEA if !CPU_SUBTYPE_ST40
|
||||
|
||||
config CPU_SH4A
|
||||
bool
|
||||
@ -40,6 +45,16 @@ config CPU_SUBTYPE_SH7604
|
||||
bool "Support SH7604 processor"
|
||||
select CPU_SH2
|
||||
|
||||
config CPU_SUBTYPE_SH7619
|
||||
bool "Support SH7619 processor"
|
||||
select CPU_SH2
|
||||
|
||||
comment "SH-2A Processor Support"
|
||||
|
||||
config CPU_SUBTYPE_SH7206
|
||||
bool "Support SH7206 processor"
|
||||
select CPU_SH2A
|
||||
|
||||
comment "SH-3 Processor Support"
|
||||
|
||||
config CPU_SUBTYPE_SH7300
|
||||
@ -89,6 +104,7 @@ comment "SH-4 Processor Support"
|
||||
config CPU_SUBTYPE_SH7750
|
||||
bool "Support SH7750 processor"
|
||||
select CPU_SH4
|
||||
select CPU_HAS_IPR_IRQ
|
||||
help
|
||||
Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU.
|
||||
|
||||
@ -104,15 +120,18 @@ config CPU_SUBTYPE_SH7750R
|
||||
bool "Support SH7750R processor"
|
||||
select CPU_SH4
|
||||
select CPU_SUBTYPE_SH7750
|
||||
select CPU_HAS_IPR_IRQ
|
||||
|
||||
config CPU_SUBTYPE_SH7750S
|
||||
bool "Support SH7750S processor"
|
||||
select CPU_SH4
|
||||
select CPU_SUBTYPE_SH7750
|
||||
select CPU_HAS_IPR_IRQ
|
||||
|
||||
config CPU_SUBTYPE_SH7751
|
||||
bool "Support SH7751 processor"
|
||||
select CPU_SH4
|
||||
select CPU_HAS_IPR_IRQ
|
||||
help
|
||||
Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU,
|
||||
or if you have a HD6417751R CPU.
|
||||
@ -121,6 +140,7 @@ config CPU_SUBTYPE_SH7751R
|
||||
bool "Support SH7751R processor"
|
||||
select CPU_SH4
|
||||
select CPU_SUBTYPE_SH7751
|
||||
select CPU_HAS_IPR_IRQ
|
||||
|
||||
config CPU_SUBTYPE_SH7760
|
||||
bool "Support SH7760 processor"
|
||||
@ -157,6 +177,11 @@ config CPU_SUBTYPE_SH7780
|
||||
select CPU_SH4A
|
||||
select CPU_HAS_INTC2_IRQ
|
||||
|
||||
config CPU_SUBTYPE_SH7785
|
||||
bool "Support SH7785 processor"
|
||||
select CPU_SH4A
|
||||
select CPU_HAS_INTC2_IRQ
|
||||
|
||||
comment "SH4AL-DSP Processor Support"
|
||||
|
||||
config CPU_SUBTYPE_SH73180
|
||||
@ -216,13 +241,22 @@ config MEMORY_SIZE
|
||||
|
||||
config 32BIT
|
||||
bool "Support 32-bit physical addressing through PMB"
|
||||
depends on CPU_SH4A && MMU
|
||||
depends on CPU_SH4A && MMU && (!X2TLB || BROKEN)
|
||||
default y
|
||||
help
|
||||
If you say Y here, physical addressing will be extended to
|
||||
32-bits through the SH-4A PMB. If this is not set, legacy
|
||||
29-bit physical addressing will be used.
|
||||
|
||||
config X2TLB
|
||||
bool "Enable extended TLB mode"
|
||||
depends on CPU_SUBTYPE_SH7785 && MMU && EXPERIMENTAL
|
||||
help
|
||||
Selecting this option will enable the extended mode of the SH-X2
|
||||
TLB. For legacy SH-X behaviour and interoperability, say N. For
|
||||
all of the fun new features and a willingless to submit bug reports,
|
||||
say Y.
|
||||
|
||||
config VSYSCALL
|
||||
bool "Support vsyscall page"
|
||||
depends on MMU
|
||||
@ -236,17 +270,53 @@ config VSYSCALL
|
||||
For systems with an MMU that can afford to give up a page,
|
||||
(the default value) say Y.
|
||||
|
||||
choice
|
||||
prompt "Kernel page size"
|
||||
default PAGE_SIZE_4KB
|
||||
|
||||
config PAGE_SIZE_4KB
|
||||
bool "4kB"
|
||||
help
|
||||
This is the default page size used by all SuperH CPUs.
|
||||
|
||||
config PAGE_SIZE_8KB
|
||||
bool "8kB"
|
||||
depends on EXPERIMENTAL && X2TLB
|
||||
help
|
||||
This enables 8kB pages as supported by SH-X2 and later MMUs.
|
||||
|
||||
config PAGE_SIZE_64KB
|
||||
bool "64kB"
|
||||
depends on EXPERIMENTAL && CPU_SH4
|
||||
help
|
||||
This enables support for 64kB pages, possible on all SH-4
|
||||
CPUs and later. Highly experimental, not recommended.
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "HugeTLB page size"
|
||||
depends on HUGETLB_PAGE && CPU_SH4 && MMU
|
||||
default HUGETLB_PAGE_SIZE_64K
|
||||
|
||||
config HUGETLB_PAGE_SIZE_64K
|
||||
bool "64K"
|
||||
bool "64kB"
|
||||
|
||||
config HUGETLB_PAGE_SIZE_256K
|
||||
bool "256kB"
|
||||
depends on X2TLB
|
||||
|
||||
config HUGETLB_PAGE_SIZE_1MB
|
||||
bool "1MB"
|
||||
|
||||
config HUGETLB_PAGE_SIZE_4MB
|
||||
bool "4MB"
|
||||
depends on X2TLB
|
||||
|
||||
config HUGETLB_PAGE_SIZE_64MB
|
||||
bool "64MB"
|
||||
depends on X2TLB
|
||||
|
||||
endchoice
|
||||
|
||||
source "mm/Kconfig"
|
||||
@ -274,7 +344,6 @@ config SH_DIRECT_MAPPED
|
||||
|
||||
config SH_WRITETHROUGH
|
||||
bool "Use write-through caching"
|
||||
default y if CPU_SH2
|
||||
help
|
||||
Selecting this option will configure the caches in write-through
|
||||
mode, as opposed to the default write-back configuration.
|
||||
|
@ -5,6 +5,7 @@
|
||||
*
|
||||
* Released under the terms of the GNU GPL v2.0.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
@ -14,37 +15,43 @@
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/*
|
||||
* Calculate the OC address and set the way bit on the SH-2.
|
||||
*
|
||||
* We must have already jump_to_P2()'ed prior to calling this
|
||||
* function, since we rely on CCR manipulation to do the
|
||||
* Right Thing(tm).
|
||||
*/
|
||||
unsigned long __get_oc_addr(unsigned long set, unsigned long way)
|
||||
void __flush_wback_region(void *start, int size)
|
||||
{
|
||||
unsigned long ccr;
|
||||
unsigned long v;
|
||||
unsigned long begin, end;
|
||||
|
||||
/*
|
||||
* On SH-2 the way bit isn't tracked in the address field
|
||||
* if we're doing address array access .. instead, we need
|
||||
* to manually switch out the way in the CCR.
|
||||
*/
|
||||
ccr = ctrl_inl(CCR);
|
||||
ccr &= ~0x00c0;
|
||||
ccr |= way << cpu_data->dcache.way_shift;
|
||||
|
||||
/*
|
||||
* Despite the number of sets being halved, we end up losing
|
||||
* the first 2 ways to OCRAM instead of the last 2 (if we're
|
||||
* 4-way). As a result, forcibly setting the W1 bit handily
|
||||
* bumps us up 2 ways.
|
||||
*/
|
||||
if (ccr & CCR_CACHE_ORA)
|
||||
ccr |= 1 << (cpu_data->dcache.way_shift + 1);
|
||||
|
||||
ctrl_outl(ccr, CCR);
|
||||
|
||||
return CACHE_OC_ADDRESS_ARRAY | (set << cpu_data->dcache.entry_shift);
|
||||
begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
|
||||
end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
|
||||
& ~(L1_CACHE_BYTES-1);
|
||||
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
|
||||
/* FIXME cache purge */
|
||||
ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008);
|
||||
}
|
||||
}
|
||||
|
||||
void __flush_purge_region(void *start, int size)
|
||||
{
|
||||
unsigned long v;
|
||||
unsigned long begin, end;
|
||||
|
||||
begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
|
||||
end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
|
||||
& ~(L1_CACHE_BYTES-1);
|
||||
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
|
||||
ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008);
|
||||
}
|
||||
}
|
||||
|
||||
void __flush_invalidate_region(void *start, int size)
|
||||
{
|
||||
unsigned long v;
|
||||
unsigned long begin, end;
|
||||
|
||||
begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
|
||||
end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
|
||||
& ~(L1_CACHE_BYTES-1);
|
||||
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
|
||||
ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,12 +11,8 @@
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
@ -83,9 +79,9 @@ static void __init emit_cache_params(void)
|
||||
*/
|
||||
|
||||
/* Worst case assumed to be 64k cache, direct-mapped i.e. 4 synonym bits. */
|
||||
#define MAX_P3_SEMAPHORES 16
|
||||
#define MAX_P3_MUTEXES 16
|
||||
|
||||
struct semaphore p3map_sem[MAX_P3_SEMAPHORES];
|
||||
struct mutex p3map_mutex[MAX_P3_MUTEXES];
|
||||
|
||||
void __init p3_cache_init(void)
|
||||
{
|
||||
@ -115,7 +111,7 @@ void __init p3_cache_init(void)
|
||||
panic("%s failed.", __FUNCTION__);
|
||||
|
||||
for (i = 0; i < cpu_data->dcache.n_aliases; i++)
|
||||
sema_init(&p3map_sem[i], 1);
|
||||
mutex_init(&p3map_mutex[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -229,7 +225,7 @@ static inline void flush_cache_4096(unsigned long start,
|
||||
*/
|
||||
if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) ||
|
||||
(start < CACHE_OC_ADDRESS_ARRAY))
|
||||
exec_offset = 0x20000000;
|
||||
exec_offset = 0x20000000;
|
||||
|
||||
local_irq_save(flags);
|
||||
__flush_cache_4096(start | SH_CACHE_ASSOC,
|
||||
@ -250,7 +246,7 @@ void flush_dcache_page(struct page *page)
|
||||
|
||||
/* Loop all the D-cache */
|
||||
n = cpu_data->dcache.n_aliases;
|
||||
for (i = 0; i < n; i++, addr += PAGE_SIZE)
|
||||
for (i = 0; i < n; i++, addr += 4096)
|
||||
flush_cache_4096(addr, phys);
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
/* $Id: clear_page.S,v 1.13 2003/08/25 17:03:10 lethal Exp $
|
||||
*
|
||||
/*
|
||||
* __clear_user_page, __clear_user, clear_page implementation of SuperH
|
||||
*
|
||||
* Copyright (C) 2001 Kaz Kojima
|
||||
* Copyright (C) 2001, 2002 Niibe Yutaka
|
||||
*
|
||||
* Copyright (C) 2006 Paul Mundt
|
||||
*/
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
/*
|
||||
* clear_page_slow
|
||||
@ -18,11 +18,11 @@
|
||||
/*
|
||||
* r0 --- scratch
|
||||
* r4 --- to
|
||||
* r5 --- to + 4096
|
||||
* r5 --- to + PAGE_SIZE
|
||||
*/
|
||||
ENTRY(clear_page_slow)
|
||||
mov r4,r5
|
||||
mov.w .Llimit,r0
|
||||
mov.l .Llimit,r0
|
||||
add r0,r5
|
||||
mov #0,r0
|
||||
!
|
||||
@ -50,7 +50,7 @@ ENTRY(clear_page_slow)
|
||||
!
|
||||
rts
|
||||
nop
|
||||
.Llimit: .word (4096-28)
|
||||
.Llimit: .long (PAGE_SIZE-28)
|
||||
|
||||
ENTRY(__clear_user)
|
||||
!
|
||||
@ -164,10 +164,10 @@ ENTRY(__clear_user)
|
||||
* r0 --- scratch
|
||||
* r4 --- to
|
||||
* r5 --- orig_to
|
||||
* r6 --- to + 4096
|
||||
* r6 --- to + PAGE_SIZE
|
||||
*/
|
||||
ENTRY(__clear_user_page)
|
||||
mov.w .L4096,r0
|
||||
mov.l .Lpsz,r0
|
||||
mov r4,r6
|
||||
add r0,r6
|
||||
mov #0,r0
|
||||
@ -191,7 +191,7 @@ ENTRY(__clear_user_page)
|
||||
!
|
||||
rts
|
||||
nop
|
||||
.L4096: .word 4096
|
||||
.Lpsz: .long PAGE_SIZE
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
/* $Id: copy_page.S,v 1.8 2003/08/25 17:03:10 lethal Exp $
|
||||
*
|
||||
/*
|
||||
* copy_page, __copy_user_page, __copy_user implementation of SuperH
|
||||
*
|
||||
* Copyright (C) 2001 Niibe Yutaka & Kaz Kojima
|
||||
* Copyright (C) 2002 Toshinobu Sugioka
|
||||
*
|
||||
* Copyright (C) 2006 Paul Mundt
|
||||
*/
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
/*
|
||||
* copy_page_slow
|
||||
@ -18,7 +18,7 @@
|
||||
|
||||
/*
|
||||
* r0, r1, r2, r3, r4, r5, r6, r7 --- scratch
|
||||
* r8 --- from + 4096
|
||||
* r8 --- from + PAGE_SIZE
|
||||
* r9 --- not used
|
||||
* r10 --- to
|
||||
* r11 --- from
|
||||
@ -30,7 +30,7 @@ ENTRY(copy_page_slow)
|
||||
mov r4,r10
|
||||
mov r5,r11
|
||||
mov r5,r8
|
||||
mov.w .L4096,r0
|
||||
mov.l .Lpsz,r0
|
||||
add r0,r8
|
||||
!
|
||||
1: mov.l @r11+,r0
|
||||
@ -80,7 +80,7 @@ ENTRY(copy_page_slow)
|
||||
|
||||
/*
|
||||
* r0, r1, r2, r3, r4, r5, r6, r7 --- scratch
|
||||
* r8 --- from + 4096
|
||||
* r8 --- from + PAGE_SIZE
|
||||
* r9 --- orig_to
|
||||
* r10 --- to
|
||||
* r11 --- from
|
||||
@ -94,7 +94,7 @@ ENTRY(__copy_user_page)
|
||||
mov r5,r11
|
||||
mov r6,r9
|
||||
mov r5,r8
|
||||
mov.w .L4096,r0
|
||||
mov.l .Lpsz,r0
|
||||
add r0,r8
|
||||
!
|
||||
1: ocbi @r9
|
||||
@ -129,7 +129,7 @@ ENTRY(__copy_user_page)
|
||||
rts
|
||||
nop
|
||||
#endif
|
||||
.L4096: .word 4096
|
||||
.Lpsz: .long PAGE_SIZE
|
||||
/*
|
||||
* __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
|
||||
* Return the number of bytes NOT copied
|
||||
|
@ -26,13 +26,19 @@ extern void die(const char *,struct pt_regs *,long);
|
||||
* and the problem, and then passes it off to one of the appropriate
|
||||
* routines.
|
||||
*/
|
||||
asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
|
||||
unsigned long address)
|
||||
asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
|
||||
unsigned long writeaccess,
|
||||
unsigned long address)
|
||||
{
|
||||
struct task_struct *tsk;
|
||||
struct mm_struct *mm;
|
||||
struct vm_area_struct * vma;
|
||||
unsigned long page;
|
||||
int si_code;
|
||||
siginfo_t info;
|
||||
|
||||
trace_hardirqs_on();
|
||||
local_irq_enable();
|
||||
|
||||
#ifdef CONFIG_SH_KGDB
|
||||
if (kgdb_nofault && kgdb_bus_err_hook)
|
||||
@ -41,6 +47,46 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
|
||||
|
||||
tsk = current;
|
||||
mm = tsk->mm;
|
||||
si_code = SEGV_MAPERR;
|
||||
|
||||
if (unlikely(address >= TASK_SIZE)) {
|
||||
/*
|
||||
* Synchronize this task's top level page-table
|
||||
* with the 'reference' page table.
|
||||
*
|
||||
* Do _not_ use "tsk" here. We might be inside
|
||||
* an interrupt in the middle of a task switch..
|
||||
*/
|
||||
int offset = pgd_index(address);
|
||||
pgd_t *pgd, *pgd_k;
|
||||
pud_t *pud, *pud_k;
|
||||
pmd_t *pmd, *pmd_k;
|
||||
|
||||
pgd = get_TTB() + offset;
|
||||
pgd_k = swapper_pg_dir + offset;
|
||||
|
||||
/* This will never happen with the folded page table. */
|
||||
if (!pgd_present(*pgd)) {
|
||||
if (!pgd_present(*pgd_k))
|
||||
goto bad_area_nosemaphore;
|
||||
set_pgd(pgd, *pgd_k);
|
||||
return;
|
||||
}
|
||||
|
||||
pud = pud_offset(pgd, address);
|
||||
pud_k = pud_offset(pgd_k, address);
|
||||
if (pud_present(*pud) || !pud_present(*pud_k))
|
||||
goto bad_area_nosemaphore;
|
||||
set_pud(pud, *pud_k);
|
||||
|
||||
pmd = pmd_offset(pud, address);
|
||||
pmd_k = pmd_offset(pud_k, address);
|
||||
if (pmd_present(*pmd) || !pmd_present(*pmd_k))
|
||||
goto bad_area_nosemaphore;
|
||||
set_pmd(pmd, *pmd_k);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're in an interrupt or have no user
|
||||
@ -65,6 +111,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
|
||||
* we can handle it..
|
||||
*/
|
||||
good_area:
|
||||
si_code = SEGV_ACCERR;
|
||||
if (writeaccess) {
|
||||
if (!(vma->vm_flags & VM_WRITE))
|
||||
goto bad_area;
|
||||
@ -104,10 +151,13 @@ survive:
|
||||
bad_area:
|
||||
up_read(&mm->mmap_sem);
|
||||
|
||||
bad_area_nosemaphore:
|
||||
if (user_mode(regs)) {
|
||||
tsk->thread.address = address;
|
||||
tsk->thread.error_code = writeaccess;
|
||||
force_sig(SIGSEGV, tsk);
|
||||
info.si_signo = SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
info.si_code = si_code;
|
||||
info.si_addr = (void *) address;
|
||||
force_sig_info(SIGSEGV, &info, tsk);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -127,11 +177,9 @@ no_context:
|
||||
printk(KERN_ALERT "Unable to handle kernel paging request");
|
||||
printk(" at virtual address %08lx\n", address);
|
||||
printk(KERN_ALERT "pc = %08lx\n", regs->pc);
|
||||
asm volatile("mov.l %1, %0"
|
||||
: "=r" (page)
|
||||
: "m" (__m(MMU_TTB)));
|
||||
page = (unsigned long)get_TTB();
|
||||
if (page) {
|
||||
page = ((unsigned long *) page)[address >> 22];
|
||||
page = ((unsigned long *) page)[address >> PGDIR_SHIFT];
|
||||
printk(KERN_ALERT "*pde = %08lx\n", page);
|
||||
if (page & _PAGE_PRESENT) {
|
||||
page &= PAGE_MASK;
|
||||
@ -166,98 +214,13 @@ do_sigbus:
|
||||
* Send a sigbus, regardless of whether we were in kernel
|
||||
* or user mode.
|
||||
*/
|
||||
tsk->thread.address = address;
|
||||
tsk->thread.error_code = writeaccess;
|
||||
tsk->thread.trap_no = 14;
|
||||
force_sig(SIGBUS, tsk);
|
||||
info.si_signo = SIGBUS;
|
||||
info.si_errno = 0;
|
||||
info.si_code = BUS_ADRERR;
|
||||
info.si_addr = (void *)address;
|
||||
force_sig_info(SIGBUS, &info, tsk);
|
||||
|
||||
/* Kernel mode? Handle exceptions or die */
|
||||
if (!user_mode(regs))
|
||||
goto no_context;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SH_STORE_QUEUES
|
||||
/*
|
||||
* This is a special case for the SH-4 store queues, as pages for this
|
||||
* space still need to be faulted in before it's possible to flush the
|
||||
* store queue cache for writeout to the remapped region.
|
||||
*/
|
||||
#define P3_ADDR_MAX (P4SEG_STORE_QUE + 0x04000000)
|
||||
#else
|
||||
#define P3_ADDR_MAX P4SEG
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Called with interrupts disabled.
|
||||
*/
|
||||
asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
|
||||
unsigned long writeaccess,
|
||||
unsigned long address)
|
||||
{
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
pte_t entry;
|
||||
struct mm_struct *mm = current->mm;
|
||||
spinlock_t *ptl;
|
||||
int ret = 1;
|
||||
|
||||
#ifdef CONFIG_SH_KGDB
|
||||
if (kgdb_nofault && kgdb_bus_err_hook)
|
||||
kgdb_bus_err_hook();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We don't take page faults for P1, P2, and parts of P4, these
|
||||
* are always mapped, whether it be due to legacy behaviour in
|
||||
* 29-bit mode, or due to PMB configuration in 32-bit mode.
|
||||
*/
|
||||
if (address >= P3SEG && address < P3_ADDR_MAX) {
|
||||
pgd = pgd_offset_k(address);
|
||||
mm = NULL;
|
||||
} else {
|
||||
if (unlikely(address >= TASK_SIZE || !mm))
|
||||
return 1;
|
||||
|
||||
pgd = pgd_offset(mm, address);
|
||||
}
|
||||
|
||||
pud = pud_offset(pgd, address);
|
||||
if (pud_none_or_clear_bad(pud))
|
||||
return 1;
|
||||
pmd = pmd_offset(pud, address);
|
||||
if (pmd_none_or_clear_bad(pmd))
|
||||
return 1;
|
||||
|
||||
if (mm)
|
||||
pte = pte_offset_map_lock(mm, pmd, address, &ptl);
|
||||
else
|
||||
pte = pte_offset_kernel(pmd, address);
|
||||
|
||||
entry = *pte;
|
||||
if (unlikely(pte_none(entry) || pte_not_present(entry)))
|
||||
goto unlock;
|
||||
if (unlikely(writeaccess && !pte_write(entry)))
|
||||
goto unlock;
|
||||
|
||||
if (writeaccess)
|
||||
entry = pte_mkdirty(entry);
|
||||
entry = pte_mkyoung(entry);
|
||||
|
||||
#ifdef CONFIG_CPU_SH4
|
||||
/*
|
||||
* ITLB is not affected by "ldtlb" instruction.
|
||||
* So, we need to flush the entry by ourselves.
|
||||
*/
|
||||
__flush_tlb_page(get_asid(), address & PAGE_MASK);
|
||||
#endif
|
||||
|
||||
set_pte(pte, entry);
|
||||
update_mmu_cache(NULL, address, entry);
|
||||
ret = 0;
|
||||
unlock:
|
||||
if (mm)
|
||||
pte_unmap_unlock(pte, ptl);
|
||||
return ret;
|
||||
}
|
||||
|
@ -84,30 +84,22 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
|
||||
pgd = swapper_pg_dir + pgd_index(addr);
|
||||
pgd = pgd_offset_k(addr);
|
||||
if (pgd_none(*pgd)) {
|
||||
pgd_ERROR(*pgd);
|
||||
return;
|
||||
}
|
||||
|
||||
pud = pud_offset(pgd, addr);
|
||||
if (pud_none(*pud)) {
|
||||
pmd = (pmd_t *)get_zeroed_page(GFP_ATOMIC);
|
||||
set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
|
||||
if (pmd != pmd_offset(pud, 0)) {
|
||||
pud_ERROR(*pud);
|
||||
return;
|
||||
}
|
||||
pud = pud_alloc(NULL, pgd, addr);
|
||||
if (unlikely(!pud)) {
|
||||
pud_ERROR(*pud);
|
||||
return;
|
||||
}
|
||||
|
||||
pmd = pmd_offset(pud, addr);
|
||||
if (pmd_none(*pmd)) {
|
||||
pte = (pte_t *)get_zeroed_page(GFP_ATOMIC);
|
||||
set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
|
||||
if (pte != pte_offset_kernel(pmd, 0)) {
|
||||
pmd_ERROR(*pmd);
|
||||
return;
|
||||
}
|
||||
pmd = pmd_alloc(NULL, pud, addr);
|
||||
if (unlikely(!pmd)) {
|
||||
pmd_ERROR(*pmd);
|
||||
return;
|
||||
}
|
||||
|
||||
pte = pte_offset_kernel(pmd, addr);
|
||||
@ -155,9 +147,6 @@ extern char __init_begin, __init_end;
|
||||
|
||||
/*
|
||||
* paging_init() sets up the page tables
|
||||
*
|
||||
* This routines also unmaps the page at virtual kernel address 0, so
|
||||
* that we can trap those pesky NULL-reference errors in the kernel.
|
||||
*/
|
||||
void __init paging_init(void)
|
||||
{
|
||||
@ -180,14 +169,11 @@ void __init paging_init(void)
|
||||
*/
|
||||
{
|
||||
unsigned long max_dma, low, start_pfn;
|
||||
pgd_t *pg_dir;
|
||||
int i;
|
||||
|
||||
/* We don't need kernel mapping as hardware support that. */
|
||||
pg_dir = swapper_pg_dir;
|
||||
|
||||
for (i = 0; i < PTRS_PER_PGD; i++)
|
||||
pgd_val(pg_dir[i]) = 0;
|
||||
/* We don't need to map the kernel through the TLB, as
|
||||
* it is permanatly mapped using P1. So clear the
|
||||
* entire pgd. */
|
||||
memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir));
|
||||
|
||||
/* Turn on the MMU */
|
||||
enable_mmu();
|
||||
@ -206,6 +192,10 @@ void __init paging_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Set an initial value for the MMU.TTB so we don't have to
|
||||
* check for a null value. */
|
||||
set_TTB(swapper_pg_dir);
|
||||
|
||||
#elif defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4)
|
||||
/*
|
||||
* If we don't have CONFIG_MMU set and the processor in question
|
||||
@ -227,7 +217,6 @@ static struct kcore_list kcore_mem, kcore_vmalloc;
|
||||
|
||||
void __init mem_init(void)
|
||||
{
|
||||
extern unsigned long empty_zero_page[1024];
|
||||
int codesize, reservedpages, datasize, initsize;
|
||||
int tmp;
|
||||
extern unsigned long memory_start;
|
||||
|
@ -28,9 +28,7 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address,
|
||||
{
|
||||
unsigned long end;
|
||||
unsigned long pfn;
|
||||
pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW |
|
||||
_PAGE_DIRTY | _PAGE_ACCESSED |
|
||||
_PAGE_HW_SHARED | _PAGE_FLAGS_HARD | flags);
|
||||
pgprot_t pgprot = __pgprot(pgprot_val(PAGE_KERNEL_NOCACHE) | flags);
|
||||
|
||||
address &= ~PMD_MASK;
|
||||
end = address + size;
|
||||
|
@ -39,8 +39,6 @@ static void copy_page_dma(void *to, void *from)
|
||||
|
||||
static void clear_page_dma(void *to)
|
||||
{
|
||||
extern unsigned long empty_zero_page[1024];
|
||||
|
||||
/*
|
||||
* We get invoked quite early on, if the DMAC hasn't been initialized
|
||||
* yet, fall back on the slow manual implementation.
|
||||
|
@ -6,22 +6,12 @@
|
||||
*
|
||||
* Released under the terms of the GNU GPL v2.0.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/threads.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
extern struct semaphore p3map_sem[];
|
||||
extern struct mutex p3map_mutex[];
|
||||
|
||||
#define CACHE_ALIAS (cpu_data->dcache.alias_mask)
|
||||
|
||||
@ -37,10 +27,6 @@ void clear_user_page(void *to, unsigned long address, struct page *page)
|
||||
if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
|
||||
clear_page(to);
|
||||
else {
|
||||
pgprot_t pgprot = __pgprot(_PAGE_PRESENT |
|
||||
_PAGE_RW | _PAGE_CACHABLE |
|
||||
_PAGE_DIRTY | _PAGE_ACCESSED |
|
||||
_PAGE_HW_SHARED | _PAGE_FLAGS_HARD);
|
||||
unsigned long phys_addr = PHYSADDR(to);
|
||||
unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS);
|
||||
pgd_t *pgd = pgd_offset_k(p3_addr);
|
||||
@ -50,8 +36,8 @@ void clear_user_page(void *to, unsigned long address, struct page *page)
|
||||
pte_t entry;
|
||||
unsigned long flags;
|
||||
|
||||
entry = pfn_pte(phys_addr >> PAGE_SHIFT, pgprot);
|
||||
down(&p3map_sem[(address & CACHE_ALIAS)>>12]);
|
||||
entry = pfn_pte(phys_addr >> PAGE_SHIFT, PAGE_KERNEL);
|
||||
mutex_lock(&p3map_mutex[(address & CACHE_ALIAS)>>12]);
|
||||
set_pte(pte, entry);
|
||||
local_irq_save(flags);
|
||||
__flush_tlb_page(get_asid(), p3_addr);
|
||||
@ -59,7 +45,7 @@ void clear_user_page(void *to, unsigned long address, struct page *page)
|
||||
update_mmu_cache(NULL, p3_addr, entry);
|
||||
__clear_user_page((void *)p3_addr, to);
|
||||
pte_clear(&init_mm, p3_addr, pte);
|
||||
up(&p3map_sem[(address & CACHE_ALIAS)>>12]);
|
||||
mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,10 +63,6 @@ void copy_user_page(void *to, void *from, unsigned long address,
|
||||
if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
|
||||
copy_page(to, from);
|
||||
else {
|
||||
pgprot_t pgprot = __pgprot(_PAGE_PRESENT |
|
||||
_PAGE_RW | _PAGE_CACHABLE |
|
||||
_PAGE_DIRTY | _PAGE_ACCESSED |
|
||||
_PAGE_HW_SHARED | _PAGE_FLAGS_HARD);
|
||||
unsigned long phys_addr = PHYSADDR(to);
|
||||
unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS);
|
||||
pgd_t *pgd = pgd_offset_k(p3_addr);
|
||||
@ -90,8 +72,8 @@ void copy_user_page(void *to, void *from, unsigned long address,
|
||||
pte_t entry;
|
||||
unsigned long flags;
|
||||
|
||||
entry = pfn_pte(phys_addr >> PAGE_SHIFT, pgprot);
|
||||
down(&p3map_sem[(address & CACHE_ALIAS)>>12]);
|
||||
entry = pfn_pte(phys_addr >> PAGE_SHIFT, PAGE_KERNEL);
|
||||
mutex_lock(&p3map_mutex[(address & CACHE_ALIAS)>>12]);
|
||||
set_pte(pte, entry);
|
||||
local_irq_save(flags);
|
||||
__flush_tlb_page(get_asid(), p3_addr);
|
||||
@ -99,7 +81,7 @@ void copy_user_page(void *to, void *from, unsigned long address,
|
||||
update_mmu_cache(NULL, p3_addr, entry);
|
||||
__copy_user_page((void *)p3_addr, from, to);
|
||||
pte_clear(&init_mm, p3_addr, pte);
|
||||
up(&p3map_sem[(address & CACHE_ALIAS)>>12]);
|
||||
mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,4 +104,3 @@ inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t
|
||||
}
|
||||
return pte;
|
||||
}
|
||||
|
||||
|
@ -30,3 +30,5 @@ R7780MP SH_R7780MP
|
||||
TITAN SH_TITAN
|
||||
SHMIN SH_SHMIN
|
||||
7710VOIPGW SH_7710VOIPGW
|
||||
7206SE SH_7206_SOLUTION_ENGINE
|
||||
7619SE SH_7619_SOLUTION_ENGINE
|
||||
|
@ -775,7 +775,7 @@ static int sci_notifier(struct notifier_block *self,
|
||||
*
|
||||
* Clean this up later..
|
||||
*/
|
||||
clk = clk_get("module_clk");
|
||||
clk = clk_get(NULL, "module_clk");
|
||||
port->uartclk = clk_get_rate(clk) * 16;
|
||||
clk_put(clk);
|
||||
}
|
||||
@ -960,7 +960,7 @@ static void sci_set_termios(struct uart_port *port, struct termios *termios,
|
||||
default:
|
||||
{
|
||||
#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
|
||||
struct clk *clk = clk_get("module_clk");
|
||||
struct clk *clk = clk_get(NULL, "module_clk");
|
||||
t = SCBRR_VALUE(baud, clk_get_rate(clk));
|
||||
clk_put(clk);
|
||||
#else
|
||||
@ -1128,7 +1128,7 @@ static void __init sci_init_ports(void)
|
||||
* XXX: We should use a proper SCI/SCIF clock
|
||||
*/
|
||||
{
|
||||
struct clk *clk = clk_get("module_clk");
|
||||
struct clk *clk = clk_get(NULL, "module_clk");
|
||||
sci_ports[i].port.uartclk = clk_get_rate(clk) * 16;
|
||||
clk_put(clk);
|
||||
}
|
||||
|
@ -133,6 +133,20 @@
|
||||
# define SCIF_ORER 0x0001 /* Overrun error bit */
|
||||
# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
|
||||
# define SCIF_ONLY
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7206)
|
||||
# define SCSPTR0 0xfffe8020 /* 16 bit SCIF */
|
||||
# define SCSPTR1 0xfffe8820 /* 16 bit SCIF */
|
||||
# define SCSPTR2 0xfffe9020 /* 16 bit SCIF */
|
||||
# define SCSPTR3 0xfffe9820 /* 16 bit SCIF */
|
||||
# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
|
||||
# define SCIF_ONLY
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
|
||||
# define SCSPTR0 0xf8400020 /* 16 bit SCIF */
|
||||
# define SCSPTR1 0xf8410020 /* 16 bit SCIF */
|
||||
# define SCSPTR2 0xf8420020 /* 16 bit SCIF */
|
||||
# define SCIF_ORER 0x0001 /* overrun error bit */
|
||||
# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
|
||||
# define SCIF_ONLY
|
||||
#else
|
||||
# error CPU subtype not defined
|
||||
#endif
|
||||
@ -365,6 +379,7 @@ SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8)
|
||||
SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8)
|
||||
SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780)
|
||||
SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
|
||||
SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
|
||||
SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
|
||||
SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
|
||||
@ -544,6 +559,28 @@ static inline int sci_rxd_in(struct uart_port *port)
|
||||
if (port->mapbase == 0xffe10000)
|
||||
return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
|
||||
}
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7206)
|
||||
static inline int sci_rxd_in(struct uart_port *port)
|
||||
{
|
||||
if (port->mapbase == 0xfffe8000)
|
||||
return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
|
||||
if (port->mapbase == 0xfffe8800)
|
||||
return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
|
||||
if (port->mapbase == 0xfffe9000)
|
||||
return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
|
||||
if (port->mapbase == 0xfffe9800)
|
||||
return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
|
||||
}
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
|
||||
static inline int sci_rxd_in(struct uart_port *port)
|
||||
{
|
||||
if (port->mapbase == 0xf8400000)
|
||||
return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
|
||||
if (port->mapbase == 0xf8410000)
|
||||
return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
|
||||
if (port->mapbase == 0xf8420000)
|
||||
return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -28,11 +28,11 @@ static inline void atomic_add(int i, atomic_t *v)
|
||||
unsigned long tmp;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"1: movli.l @%3, %0 ! atomic_add \n"
|
||||
" add %2, %0 \n"
|
||||
" movco.l %0, @%3 \n"
|
||||
"1: movli.l @%2, %0 ! atomic_add \n"
|
||||
" add %1, %0 \n"
|
||||
" movco.l %0, @%2 \n"
|
||||
" bf 1b \n"
|
||||
: "=&z" (tmp), "=r" (&v->counter)
|
||||
: "=&z" (tmp)
|
||||
: "r" (i), "r" (&v->counter)
|
||||
: "t");
|
||||
#else
|
||||
@ -50,11 +50,11 @@ static inline void atomic_sub(int i, atomic_t *v)
|
||||
unsigned long tmp;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"1: movli.l @%3, %0 ! atomic_sub \n"
|
||||
" sub %2, %0 \n"
|
||||
" movco.l %0, @%3 \n"
|
||||
"1: movli.l @%2, %0 ! atomic_sub \n"
|
||||
" sub %1, %0 \n"
|
||||
" movco.l %0, @%2 \n"
|
||||
" bf 1b \n"
|
||||
: "=&z" (tmp), "=r" (&v->counter)
|
||||
: "=&z" (tmp)
|
||||
: "r" (i), "r" (&v->counter)
|
||||
: "t");
|
||||
#else
|
||||
@ -80,12 +80,12 @@ static inline int atomic_add_return(int i, atomic_t *v)
|
||||
|
||||
#ifdef CONFIG_CPU_SH4A
|
||||
__asm__ __volatile__ (
|
||||
"1: movli.l @%3, %0 ! atomic_add_return \n"
|
||||
" add %2, %0 \n"
|
||||
" movco.l %0, @%3 \n"
|
||||
"1: movli.l @%2, %0 ! atomic_add_return \n"
|
||||
" add %1, %0 \n"
|
||||
" movco.l %0, @%2 \n"
|
||||
" bf 1b \n"
|
||||
" synco \n"
|
||||
: "=&z" (temp), "=r" (&v->counter)
|
||||
: "=&z" (temp)
|
||||
: "r" (i), "r" (&v->counter)
|
||||
: "t");
|
||||
#else
|
||||
@ -109,12 +109,12 @@ static inline int atomic_sub_return(int i, atomic_t *v)
|
||||
|
||||
#ifdef CONFIG_CPU_SH4A
|
||||
__asm__ __volatile__ (
|
||||
"1: movli.l @%3, %0 ! atomic_sub_return \n"
|
||||
" sub %2, %0 \n"
|
||||
" movco.l %0, @%3 \n"
|
||||
"1: movli.l @%2, %0 ! atomic_sub_return \n"
|
||||
" sub %1, %0 \n"
|
||||
" movco.l %0, @%2 \n"
|
||||
" bf 1b \n"
|
||||
" synco \n"
|
||||
: "=&z" (temp), "=r" (&v->counter)
|
||||
: "=&z" (temp)
|
||||
: "r" (i), "r" (&v->counter)
|
||||
: "t");
|
||||
#else
|
||||
@ -186,11 +186,11 @@ static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
|
||||
unsigned long tmp;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"1: movli.l @%3, %0 ! atomic_clear_mask \n"
|
||||
" and %2, %0 \n"
|
||||
" movco.l %0, @%3 \n"
|
||||
"1: movli.l @%2, %0 ! atomic_clear_mask \n"
|
||||
" and %1, %0 \n"
|
||||
" movco.l %0, @%2 \n"
|
||||
" bf 1b \n"
|
||||
: "=&z" (tmp), "=r" (&v->counter)
|
||||
: "=&z" (tmp)
|
||||
: "r" (~mask), "r" (&v->counter)
|
||||
: "t");
|
||||
#else
|
||||
@ -208,11 +208,11 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
|
||||
unsigned long tmp;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"1: movli.l @%3, %0 ! atomic_set_mask \n"
|
||||
" or %2, %0 \n"
|
||||
" movco.l %0, @%3 \n"
|
||||
"1: movli.l @%2, %0 ! atomic_set_mask \n"
|
||||
" or %1, %0 \n"
|
||||
" movco.l %0, @%2 \n"
|
||||
" bf 1b \n"
|
||||
: "=&z" (tmp), "=r" (&v->counter)
|
||||
: "=&z" (tmp)
|
||||
: "r" (mask), "r" (&v->counter)
|
||||
: "t");
|
||||
#else
|
||||
|
@ -23,16 +23,20 @@ static void __init check_bugs(void)
|
||||
cpu_data->loops_per_jiffy = loops_per_jiffy;
|
||||
|
||||
switch (cpu_data->type) {
|
||||
case CPU_SH7604:
|
||||
case CPU_SH7604 ... CPU_SH7619:
|
||||
*p++ = '2';
|
||||
break;
|
||||
case CPU_SH7206:
|
||||
*p++ = '2';
|
||||
*p++ = 'a';
|
||||
break;
|
||||
case CPU_SH7705 ... CPU_SH7300:
|
||||
*p++ = '3';
|
||||
break;
|
||||
case CPU_SH7750 ... CPU_SH4_501:
|
||||
*p++ = '4';
|
||||
break;
|
||||
case CPU_SH7770 ... CPU_SH7781:
|
||||
case CPU_SH7770 ... CPU_SH7785:
|
||||
*p++ = '4';
|
||||
*p++ = 'a';
|
||||
break;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <linux/kref.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
struct clk;
|
||||
|
||||
@ -18,7 +19,7 @@ struct clk_ops {
|
||||
struct clk {
|
||||
struct list_head node;
|
||||
const char *name;
|
||||
|
||||
int id;
|
||||
struct module *owner;
|
||||
|
||||
struct clk *parent;
|
||||
@ -40,22 +41,13 @@ void arch_init_clk_ops(struct clk_ops **, int type);
|
||||
int clk_init(void);
|
||||
|
||||
int __clk_enable(struct clk *);
|
||||
int clk_enable(struct clk *);
|
||||
|
||||
void __clk_disable(struct clk *);
|
||||
void clk_disable(struct clk *);
|
||||
|
||||
int clk_set_rate(struct clk *, unsigned long rate);
|
||||
unsigned long clk_get_rate(struct clk *);
|
||||
void clk_recalc_rate(struct clk *);
|
||||
|
||||
struct clk *clk_get(const char *id);
|
||||
void clk_put(struct clk *);
|
||||
|
||||
int clk_register(struct clk *);
|
||||
void clk_unregister(struct clk *);
|
||||
|
||||
int show_clocks(struct seq_file *m);
|
||||
|
||||
#endif /* __ASM_SH_CLOCK_H */
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#define L1_CACHE_SHIFT 4
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7604)
|
||||
#define CCR 0xfffffe92 /* Address of Cache Control Register */
|
||||
|
||||
#define CCR_CACHE_CE 0x01 /* Cache enable */
|
||||
@ -27,5 +28,26 @@
|
||||
#define CCR_CACHE_ORA CCR_CACHE_TW
|
||||
#define CCR_CACHE_WT 0x00 /* SH-2 is _always_ write-through */
|
||||
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
|
||||
#define CCR1 0xffffffec
|
||||
#define CCR CCR1
|
||||
|
||||
#define CCR_CACHE_CE 0x01 /* Cache enable */
|
||||
#define CCR_CACHE_WT 0x06 /* CCR[bit1=1,bit2=1] */
|
||||
/* 0x00000000-0x7fffffff: Write-through */
|
||||
/* 0x80000000-0x9fffffff: Write-back */
|
||||
/* 0xc0000000-0xdfffffff: Write-through */
|
||||
#define CCR_CACHE_CB 0x00 /* CCR[bit1=0,bit2=0] */
|
||||
/* 0x00000000-0x7fffffff: Write-back */
|
||||
/* 0x80000000-0x9fffffff: Write-through */
|
||||
/* 0xc0000000-0xdfffffff: Write-back */
|
||||
#define CCR_CACHE_CF 0x08 /* Cache invalidate */
|
||||
|
||||
#define CACHE_OC_ADDRESS_ARRAY 0xf0000000
|
||||
#define CACHE_OC_DATA_ARRAY 0xf1000000
|
||||
|
||||
#define CCR_CACHE_ENABLE CCR_CACHE_CE
|
||||
#define CCR_CACHE_INVALIDATE CCR_CACHE_CF
|
||||
#endif
|
||||
#endif /* __ASM_CPU_SH2_CACHE_H */
|
||||
|
||||
|
18
include/asm-sh/cpu-sh2/freq.h
Normal file
18
include/asm-sh/cpu-sh2/freq.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* include/asm-sh/cpu-sh2/freq.h
|
||||
*
|
||||
* Copyright (C) 2006 Yoshinori Sato
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __ASM_CPU_SH2_FREQ_H
|
||||
#define __ASM_CPU_SH2_FREQ_H
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7619)
|
||||
#define FREQCR 0xf815ff80
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_CPU_SH2_FREQ_H */
|
||||
|
16
include/asm-sh/cpu-sh2/mmu_context.h
Normal file
16
include/asm-sh/cpu-sh2/mmu_context.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* include/asm-sh/cpu-sh2/mmu_context.h
|
||||
*
|
||||
* Copyright (C) 2003 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.
|
||||
*/
|
||||
#ifndef __ASM_CPU_SH2_MMU_CONTEXT_H
|
||||
#define __ASM_CPU_SH2_MMU_CONTEXT_H
|
||||
|
||||
/* No MMU */
|
||||
|
||||
#endif /* __ASM_CPU_SH2_MMU_CONTEXT_H */
|
||||
|
6
include/asm-sh/cpu-sh2/timer.h
Normal file
6
include/asm-sh/cpu-sh2/timer.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __ASM_CPU_SH2_TIMER_H
|
||||
#define __ASM_CPU_SH2_TIMER_H
|
||||
|
||||
/* Nothing needed yet */
|
||||
|
||||
#endif /* __ASM_CPU_SH2_TIMER_H */
|
1
include/asm-sh/cpu-sh2a/addrspace.h
Normal file
1
include/asm-sh/cpu-sh2a/addrspace.h
Normal file
@ -0,0 +1 @@
|
||||
#include <asm/cpu-sh2/addrspace.h>
|
39
include/asm-sh/cpu-sh2a/cache.h
Normal file
39
include/asm-sh/cpu-sh2a/cache.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* include/asm-sh/cpu-sh2a/cache.h
|
||||
*
|
||||
* Copyright (C) 2004 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.
|
||||
*/
|
||||
#ifndef __ASM_CPU_SH2A_CACHE_H
|
||||
#define __ASM_CPU_SH2A_CACHE_H
|
||||
|
||||
#define L1_CACHE_SHIFT 4
|
||||
|
||||
#define CCR1 0xfffc1000
|
||||
#define CCR2 0xfffc1004
|
||||
|
||||
/* CCR1 behaves more like the traditional CCR */
|
||||
#define CCR CCR1
|
||||
|
||||
/*
|
||||
* Most of the SH-2A CCR1 definitions resemble the SH-4 ones. All others not
|
||||
* listed here are reserved.
|
||||
*/
|
||||
#define CCR_CACHE_CB 0x0000 /* Hack */
|
||||
#define CCR_CACHE_OCE 0x0001
|
||||
#define CCR_CACHE_WT 0x0002
|
||||
#define CCR_CACHE_OCI 0x0008 /* OCF */
|
||||
#define CCR_CACHE_ICE 0x0100
|
||||
#define CCR_CACHE_ICI 0x0800 /* ICF */
|
||||
|
||||
#define CACHE_IC_ADDRESS_ARRAY 0xf0000000
|
||||
#define CACHE_OC_ADDRESS_ARRAY 0xf0800000
|
||||
|
||||
#define CCR_CACHE_ENABLE (CCR_CACHE_OCE | CCR_CACHE_ICE)
|
||||
#define CCR_CACHE_INVALIDATE (CCR_CACHE_OCI | CCR_CACHE_ICI)
|
||||
|
||||
#endif /* __ASM_CPU_SH2A_CACHE_H */
|
||||
|
1
include/asm-sh/cpu-sh2a/cacheflush.h
Normal file
1
include/asm-sh/cpu-sh2a/cacheflush.h
Normal file
@ -0,0 +1 @@
|
||||
#include <asm/cpu-sh2/cacheflush.h>
|
1
include/asm-sh/cpu-sh2a/dma.h
Normal file
1
include/asm-sh/cpu-sh2a/dma.h
Normal file
@ -0,0 +1 @@
|
||||
#include <asm/cpu-sh2/dma.h>
|
18
include/asm-sh/cpu-sh2a/freq.h
Normal file
18
include/asm-sh/cpu-sh2a/freq.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* include/asm-sh/cpu-sh2a/freq.h
|
||||
*
|
||||
* Copyright (C) 2006 Yoshinori Sato
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __ASM_CPU_SH2A_FREQ_H
|
||||
#define __ASM_CPU_SH2A_FREQ_H
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7206)
|
||||
#define FREQCR 0xfffe0010
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_CPU_SH2A_FREQ_H */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user