Merge branch 'sh/hwblk' into sh/pm-runtime

This commit is contained in:
Paul Mundt 2009-08-23 18:02:59 +09:00
commit 0858d9c0c5
109 changed files with 6565 additions and 1796 deletions

View File

@ -10,12 +10,16 @@ config SUPERH
select EMBEDDED
select HAVE_CLK
select HAVE_IDE
select HAVE_LMB
select HAVE_OPROFILE
select HAVE_GENERIC_DMA_COHERENT
select HAVE_IOREMAP_PROT if MMU
select HAVE_ARCH_TRACEHOOK
select HAVE_DMA_API_DEBUG
select HAVE_PERF_COUNTERS
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
select RTC_LIB
select GENERIC_ATOMIC64
help
@ -31,6 +35,9 @@ config SUPERH32
select HAVE_FUNCTION_TRACER
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_FTRACE_SYSCALLS
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_ARCH_KGDB
select ARCH_HIBERNATION_POSSIBLE if MMU

View File

@ -38,11 +38,12 @@ config EARLY_SCIF_CONSOLE_PORT
default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \
CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 || \
CPU_SUBTYPE_SH7343
default "0xffea0000" if CPU_SUBTYPE_SH7785
default "0xffeb0000" if CPU_SUBTYPE_SH7785
default "0xffeb0000" if CPU_SUBTYPE_SH7786
default "0xfffe8000" if CPU_SUBTYPE_SH7203
default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263
default "0xffe80000" if CPU_SH4
default "0xa4000150" if CPU_SH3
default "0x00000000"
config EARLY_PRINTK
@ -61,12 +62,14 @@ config EARLY_PRINTK
select both the EARLY_SCIF_CONSOLE and SH_STANDARD_BIOS, using
the kernel command line option to toggle back and forth.
config DEBUG_STACKOVERFLOW
config STACK_DEBUG
bool "Check for stack overflows"
depends on DEBUG_KERNEL && SUPERH32
help
This option will cause messages to be printed if free stack space
drops below a certain limit.
drops below a certain limit. Saying Y here will add overhead to
every function call and will therefore incur a major
performance hit. Most users should say N.
config DEBUG_STACK_USAGE
bool "Stack utilization instrumentation"
@ -107,6 +110,14 @@ config DUMP_CODE
Those looking for more verbose debugging output should say Y.
config DWARF_UNWINDER
bool "Enable the DWARF unwinder for stacktraces"
select FRAME_POINTER
default n
help
Enabling this option will make stacktraces more accurate, at
the cost of an increase in overall kernel size.
config SH_NO_BSS_INIT
bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)"
depends on DEBUG_KERNEL
@ -123,4 +134,9 @@ config SH64_SR_WATCH
bool "Debug: set SR.WATCH to enable hardware watchpoints and trace"
depends on SUPERH64
config MCOUNT
def_bool y
depends on SUPERH32
depends on STACK_DEBUG || FUNCTION_TRACER
endmenu

View File

@ -136,6 +136,7 @@ machdir-$(CONFIG_SH_7751_SYSTEMH) += mach-systemh
machdir-$(CONFIG_SH_EDOSK7705) += mach-edosk7705
machdir-$(CONFIG_SH_HIGHLANDER) += mach-highlander
machdir-$(CONFIG_SH_MIGOR) += mach-migor
machdir-$(CONFIG_SH_KFR2R09) += mach-kfr2r09
machdir-$(CONFIG_SH_SDK7780) += mach-sdk7780
machdir-$(CONFIG_SH_X3PROTO) += mach-x3proto
machdir-$(CONFIG_SH_SH7763RDP) += mach-sh7763rdp
@ -186,17 +187,27 @@ KBUILD_CFLAGS += -pipe $(cflags-y)
KBUILD_CPPFLAGS += $(cflags-y)
KBUILD_AFLAGS += $(cflags-y)
ifeq ($(CONFIG_MCOUNT),y)
KBUILD_CFLAGS += -pg
endif
ifeq ($(CONFIG_DWARF_UNWINDER),y)
KBUILD_CFLAGS += -fasynchronous-unwind-tables
endif
libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y)
PHONY += maketools FORCE
BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec \
zImage vmlinux.srec romImage
PHONY += maketools $(BOOT_TARGETS) FORCE
maketools: include/linux/version.h FORCE
$(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h
all: $(KBUILD_IMAGE)
zImage uImage uImage.srec vmlinux.srec: vmlinux
$(BOOT_TARGETS): vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
compressed: zImage
@ -208,10 +219,14 @@ archclean:
$(Q)$(MAKE) $(clean)=arch/sh/kernel/vsyscall
define archhelp
@echo '* zImage - Compressed kernel image'
@echo ' zImage - Compressed kernel image'
@echo ' romImage - Compressed ROM image, if supported'
@echo ' vmlinux.srec - Create an ELF S-record'
@echo ' uImage - Create a bootable image for U-Boot'
@echo '* uImage - Alias to bootable U-Boot image'
@echo ' uImage.srec - Create an S-record for U-Boot'
@echo '* uImage.gz - Kernel-only image for U-Boot (gzip)'
@echo ' uImage.bz2 - Kernel-only image for U-Boot (bzip2)'
@echo ' uImage.lzma - Kernel-only image for U-Boot (lzma)'
endef
CLEAN_FILES += include/asm-sh/machtypes.h

View File

@ -193,6 +193,13 @@ config SH_AP325RXA
Renesas "AP-325RXA" support.
Compatible with ALGO SYSTEM CO.,LTD. "AP-320A"
config SH_KFR2R09
bool "KFR2R09"
depends on CPU_SUBTYPE_SH7724
select ARCH_REQUIRE_GPIOLIB
help
"Kit For R2R for 2009" support.
config SH_SH7763RDP
bool "SH7763RDP"
depends on CPU_SUBTYPE_SH7763

View File

@ -227,6 +227,9 @@ static struct platform_device lcdc_device = {
.dev = {
.platform_data = &lcdc_info,
},
.archdata = {
.hwblk_id = HWBLK_LCDC,
},
};
static void camera_power(int val)
@ -377,6 +380,9 @@ static struct platform_device ceu_device = {
.dev = {
.platform_data = &sh_mobile_ceu_info,
},
.archdata = {
.hwblk_id = HWBLK_CEU,
},
};
struct spi_gpio_platform_data sdcard_cn3_platform_data = {

View File

@ -22,6 +22,7 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/usb/r8a66597.h>
#include <linux/usb/m66592.h>
#include <net/ax88796.h>
#include <asm/machvec.h>
#include <mach/highlander.h>
@ -60,6 +61,11 @@ static struct platform_device r8a66597_usb_host_device = {
.resource = r8a66597_usb_host_resources,
};
static struct m66592_platdata usbf_platdata = {
.xtal = M66592_PLATDATA_XTAL_24MHZ,
.vif = 1,
};
static struct resource m66592_usb_peripheral_resources[] = {
[0] = {
.name = "m66592_udc",
@ -81,6 +87,7 @@ static struct platform_device m66592_usb_peripheral_device = {
.dev = {
.dma_mask = NULL, /* don't use dma */
.coherent_dma_mask = 0xffffffff,
.platform_data = &usbf_platdata,
},
.num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources),
.resource = m66592_usb_peripheral_resources,

View File

@ -0,0 +1,2 @@
obj-y := setup.o
obj-$(CONFIG_FB_SH_MOBILE_LCDC) += lcd_wqvga.o

View File

@ -0,0 +1,332 @@
/*
* KFR2R09 LCD panel support
*
* Copyright (C) 2009 Magnus Damm
*
* Register settings based on the out-of-tree t33fb.c driver
* Copyright (C) 2008 Lineo Solutions, 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/delay.h>
#include <linux/err.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <video/sh_mobile_lcdc.h>
#include <mach/kfr2r09.h>
#include <cpu/sh7724.h>
/* The on-board LCD module is a Hitachi TX07D34VM0AAA. This module is made
* up of a 240x400 LCD hooked up to a R61517 driver IC. The driver IC is
* communicating with the main port of the LCDC using an 18-bit SYS interface.
*
* The device code for this LCD module is 0x01221517.
*/
static const unsigned char data_frame_if[] = {
0x02, /* WEMODE: 1=cont, 0=one-shot */
0x00, 0x00,
0x00, /* EPF, DFM */
0x02, /* RIM[1] : 1 (18bpp) */
};
static const unsigned char data_panel[] = {
0x0b,
0x63, /* 400 lines */
0x04, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00,
};
static const unsigned char data_timing[] = {
0x00, 0x00, 0x13, 0x08, 0x08,
};
static const unsigned char data_timing_src[] = {
0x11, 0x01, 0x00, 0x01,
};
static const unsigned char data_gamma[] = {
0x01, 0x02, 0x08, 0x23, 0x03, 0x0c, 0x00, 0x06, 0x00, 0x00,
0x01, 0x00, 0x0c, 0x23, 0x03, 0x08, 0x02, 0x06, 0x00, 0x00,
};
static const unsigned char data_power[] = {
0x07, 0xc5, 0xdc, 0x02, 0x33, 0x0a,
};
static unsigned long read_reg(void *sohandle,
struct sh_mobile_lcdc_sys_bus_ops *so)
{
return so->read_data(sohandle);
}
static void write_reg(void *sohandle,
struct sh_mobile_lcdc_sys_bus_ops *so,
int i, unsigned long v)
{
if (i)
so->write_data(sohandle, v); /* PTH4/LCDRS High [param, 17:0] */
else
so->write_index(sohandle, v); /* PTH4/LCDRS Low [cmd, 7:0] */
}
static void write_data(void *sohandle,
struct sh_mobile_lcdc_sys_bus_ops *so,
unsigned char const *data, int no_data)
{
int i;
for (i = 0; i < no_data; i++)
write_reg(sohandle, so, 1, data[i]);
}
static unsigned long read_device_code(void *sohandle,
struct sh_mobile_lcdc_sys_bus_ops *so)
{
unsigned long device_code;
/* access protect OFF */
write_reg(sohandle, so, 0, 0xb0);
write_reg(sohandle, so, 1, 0x00);
/* deep standby OFF */
write_reg(sohandle, so, 0, 0xb1);
write_reg(sohandle, so, 1, 0x00);
/* device code command */
write_reg(sohandle, so, 0, 0xbf);
mdelay(50);
/* dummy read */
read_reg(sohandle, so);
/* read device code */
device_code = ((read_reg(sohandle, so) & 0xff) << 24);
device_code |= ((read_reg(sohandle, so) & 0xff) << 16);
device_code |= ((read_reg(sohandle, so) & 0xff) << 8);
device_code |= (read_reg(sohandle, so) & 0xff);
return device_code;
}
static void write_memory_start(void *sohandle,
struct sh_mobile_lcdc_sys_bus_ops *so)
{
write_reg(sohandle, so, 0, 0x2c);
}
static void clear_memory(void *sohandle,
struct sh_mobile_lcdc_sys_bus_ops *so)
{
int i;
/* write start */
write_memory_start(sohandle, so);
/* paint it black */
for (i = 0; i < (240 * 400); i++)
write_reg(sohandle, so, 1, 0x00);
}
static void display_on(void *sohandle,
struct sh_mobile_lcdc_sys_bus_ops *so)
{
/* access protect off */
write_reg(sohandle, so, 0, 0xb0);
write_reg(sohandle, so, 1, 0x00);
/* exit deep standby mode */
write_reg(sohandle, so, 0, 0xb1);
write_reg(sohandle, so, 1, 0x00);
/* frame memory I/F */
write_reg(sohandle, so, 0, 0xb3);
write_data(sohandle, so, data_frame_if, ARRAY_SIZE(data_frame_if));
/* display mode and frame memory write mode */
write_reg(sohandle, so, 0, 0xb4);
write_reg(sohandle, so, 1, 0x00); /* DBI, internal clock */
/* panel */
write_reg(sohandle, so, 0, 0xc0);
write_data(sohandle, so, data_panel, ARRAY_SIZE(data_panel));
/* timing (normal) */
write_reg(sohandle, so, 0, 0xc1);
write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
/* timing (partial) */
write_reg(sohandle, so, 0, 0xc2);
write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
/* timing (idle) */
write_reg(sohandle, so, 0, 0xc3);
write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
/* timing (source/VCOM/gate driving) */
write_reg(sohandle, so, 0, 0xc4);
write_data(sohandle, so, data_timing_src, ARRAY_SIZE(data_timing_src));
/* gamma (red) */
write_reg(sohandle, so, 0, 0xc8);
write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
/* gamma (green) */
write_reg(sohandle, so, 0, 0xc9);
write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
/* gamma (blue) */
write_reg(sohandle, so, 0, 0xca);
write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
/* power (common) */
write_reg(sohandle, so, 0, 0xd0);
write_data(sohandle, so, data_power, ARRAY_SIZE(data_power));
/* VCOM */
write_reg(sohandle, so, 0, 0xd1);
write_reg(sohandle, so, 1, 0x00);
write_reg(sohandle, so, 1, 0x0f);
write_reg(sohandle, so, 1, 0x02);
/* power (normal) */
write_reg(sohandle, so, 0, 0xd2);
write_reg(sohandle, so, 1, 0x63);
write_reg(sohandle, so, 1, 0x24);
/* power (partial) */
write_reg(sohandle, so, 0, 0xd3);
write_reg(sohandle, so, 1, 0x63);
write_reg(sohandle, so, 1, 0x24);
/* power (idle) */
write_reg(sohandle, so, 0, 0xd4);
write_reg(sohandle, so, 1, 0x63);
write_reg(sohandle, so, 1, 0x24);
write_reg(sohandle, so, 0, 0xd8);
write_reg(sohandle, so, 1, 0x77);
write_reg(sohandle, so, 1, 0x77);
/* TE signal */
write_reg(sohandle, so, 0, 0x35);
write_reg(sohandle, so, 1, 0x00);
/* TE signal line */
write_reg(sohandle, so, 0, 0x44);
write_reg(sohandle, so, 1, 0x00);
write_reg(sohandle, so, 1, 0x00);
/* column address */
write_reg(sohandle, so, 0, 0x2a);
write_reg(sohandle, so, 1, 0x00);
write_reg(sohandle, so, 1, 0x00);
write_reg(sohandle, so, 1, 0x00);
write_reg(sohandle, so, 1, 0xef);
/* page address */
write_reg(sohandle, so, 0, 0x2b);
write_reg(sohandle, so, 1, 0x00);
write_reg(sohandle, so, 1, 0x00);
write_reg(sohandle, so, 1, 0x01);
write_reg(sohandle, so, 1, 0x8f);
/* exit sleep mode */
write_reg(sohandle, so, 0, 0x11);
mdelay(120);
/* clear vram */
clear_memory(sohandle, so);
/* display ON */
write_reg(sohandle, so, 0, 0x29);
mdelay(1);
write_memory_start(sohandle, so);
}
int kfr2r09_lcd_setup(void *board_data, void *sohandle,
struct sh_mobile_lcdc_sys_bus_ops *so)
{
/* power on */
gpio_set_value(GPIO_PTF4, 0); /* PROTECT/ -> L */
gpio_set_value(GPIO_PTE4, 0); /* LCD_RST/ -> L */
gpio_set_value(GPIO_PTF4, 1); /* PROTECT/ -> H */
udelay(1100);
gpio_set_value(GPIO_PTE4, 1); /* LCD_RST/ -> H */
udelay(10);
gpio_set_value(GPIO_PTF4, 0); /* PROTECT/ -> L */
mdelay(20);
if (read_device_code(sohandle, so) != 0x01221517)
return -ENODEV;
pr_info("KFR2R09 WQVGA LCD Module detected.\n");
display_on(sohandle, so);
return 0;
}
#define CTRL_CKSW 0x10
#define CTRL_C10 0x20
#define CTRL_CPSW 0x80
#define MAIN_MLED4 0x40
#define MAIN_MSW 0x80
static int kfr2r09_lcd_backlight(int on)
{
struct i2c_adapter *a;
struct i2c_msg msg;
unsigned char buf[2];
int ret;
a = i2c_get_adapter(0);
if (!a)
return -ENODEV;
buf[0] = 0x00;
if (on)
buf[1] = CTRL_CPSW | CTRL_C10 | CTRL_CKSW;
else
buf[1] = 0;
msg.addr = 0x75;
msg.buf = buf;
msg.len = 2;
msg.flags = 0;
ret = i2c_transfer(a, &msg, 1);
if (ret != 1)
return -ENODEV;
buf[0] = 0x01;
if (on)
buf[1] = MAIN_MSW | MAIN_MLED4 | 0x0c;
else
buf[1] = 0;
msg.addr = 0x75;
msg.buf = buf;
msg.len = 2;
msg.flags = 0;
ret = i2c_transfer(a, &msg, 1);
if (ret != 1)
return -ENODEV;
return 0;
}
void kfr2r09_lcd_on(void *board_data)
{
kfr2r09_lcd_backlight(1);
}
void kfr2r09_lcd_off(void *board_data)
{
kfr2r09_lcd_backlight(0);
}

View File

@ -0,0 +1,276 @@
/*
* KFR2R09 board support code
*
* Copyright (C) 2009 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/onenand.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <video/sh_mobile_lcdc.h>
#include <asm/clock.h>
#include <asm/machvec.h>
#include <asm/io.h>
#include <asm/sh_keysc.h>
#include <cpu/sh7724.h>
#include <mach/kfr2r09.h>
static struct mtd_partition kfr2r09_nor_flash_partitions[] =
{
{
.name = "boot",
.offset = 0,
.size = (4 * 1024 * 1024),
.mask_flags = MTD_WRITEABLE, /* Read-only */
},
{
.name = "other",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
},
};
static struct physmap_flash_data kfr2r09_nor_flash_data = {
.width = 2,
.parts = kfr2r09_nor_flash_partitions,
.nr_parts = ARRAY_SIZE(kfr2r09_nor_flash_partitions),
};
static struct resource kfr2r09_nor_flash_resources[] = {
[0] = {
.name = "NOR Flash",
.start = 0x00000000,
.end = 0x03ffffff,
.flags = IORESOURCE_MEM,
}
};
static struct platform_device kfr2r09_nor_flash_device = {
.name = "physmap-flash",
.resource = kfr2r09_nor_flash_resources,
.num_resources = ARRAY_SIZE(kfr2r09_nor_flash_resources),
.dev = {
.platform_data = &kfr2r09_nor_flash_data,
},
};
static struct resource kfr2r09_nand_flash_resources[] = {
[0] = {
.name = "NAND Flash",
.start = 0x10000000,
.end = 0x1001ffff,
.flags = IORESOURCE_MEM,
}
};
static struct platform_device kfr2r09_nand_flash_device = {
.name = "onenand-flash",
.resource = kfr2r09_nand_flash_resources,
.num_resources = ARRAY_SIZE(kfr2r09_nand_flash_resources),
};
static struct sh_keysc_info kfr2r09_sh_keysc_info = {
.mode = SH_KEYSC_MODE_1, /* KEYOUT0->4, KEYIN0->4 */
.scan_timing = 3,
.delay = 10,
.keycodes = {
KEY_PHONE, KEY_CLEAR, KEY_MAIL, KEY_WWW, KEY_ENTER,
KEY_1, KEY_2, KEY_3, 0, KEY_UP,
KEY_4, KEY_5, KEY_6, 0, KEY_LEFT,
KEY_7, KEY_8, KEY_9, KEY_PROG1, KEY_RIGHT,
KEY_S, KEY_0, KEY_P, KEY_PROG2, KEY_DOWN,
0, 0, 0, 0, 0
},
};
static struct resource kfr2r09_sh_keysc_resources[] = {
[0] = {
.name = "KEYSC",
.start = 0x044b0000,
.end = 0x044b000f,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 79,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device kfr2r09_sh_keysc_device = {
.name = "sh_keysc",
.id = 0, /* "keysc0" clock */
.num_resources = ARRAY_SIZE(kfr2r09_sh_keysc_resources),
.resource = kfr2r09_sh_keysc_resources,
.dev = {
.platform_data = &kfr2r09_sh_keysc_info,
},
.archdata = {
.hwblk_id = HWBLK_KEYSC,
},
};
static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
.clock_source = LCDC_CLK_BUS,
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
.bpp = 16,
.interface_type = SYS18,
.clock_divider = 6,
.flags = LCDC_FLAGS_DWPOL,
.lcd_cfg = {
.name = "TX07D34VM0AAA",
.xres = 240,
.yres = 400,
.left_margin = 0,
.right_margin = 16,
.hsync_len = 8,
.upper_margin = 0,
.lower_margin = 1,
.vsync_len = 1,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
},
.lcd_size_cfg = {
.width = 35,
.height = 58,
},
.board_cfg = {
.setup_sys = kfr2r09_lcd_setup,
.display_on = kfr2r09_lcd_on,
.display_off = kfr2r09_lcd_off,
},
.sys_bus_cfg = {
.ldmt2r = 0x07010904,
.ldmt3r = 0x14012914,
/* set 1s delay to encourage fsync() */
.deferred_io_msec = 1000,
},
}
};
static struct resource kfr2r09_sh_lcdc_resources[] = {
[0] = {
.name = "LCDC",
.start = 0xfe940000, /* P4-only space */
.end = 0xfe941fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 106,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device kfr2r09_sh_lcdc_device = {
.name = "sh_mobile_lcdc_fb",
.num_resources = ARRAY_SIZE(kfr2r09_sh_lcdc_resources),
.resource = kfr2r09_sh_lcdc_resources,
.dev = {
.platform_data = &kfr2r09_sh_lcdc_info,
},
.archdata = {
.hwblk_id = HWBLK_LCDC,
},
};
static struct platform_device *kfr2r09_devices[] __initdata = {
&kfr2r09_nor_flash_device,
&kfr2r09_nand_flash_device,
&kfr2r09_sh_keysc_device,
&kfr2r09_sh_lcdc_device,
};
#define BSC_CS0BCR 0xfec10004
#define BSC_CS0WCR 0xfec10024
#define BSC_CS4BCR 0xfec10010
#define BSC_CS4WCR 0xfec10030
static int __init kfr2r09_devices_setup(void)
{
/* enable SCIF1 serial port for YC401 console support */
gpio_request(GPIO_FN_SCIF1_RXD, NULL);
gpio_request(GPIO_FN_SCIF1_TXD, NULL);
/* setup NOR flash at CS0 */
ctrl_outl(0x36db0400, BSC_CS0BCR);
ctrl_outl(0x00000500, BSC_CS0WCR);
/* setup NAND flash at CS4 */
ctrl_outl(0x36db0400, BSC_CS4BCR);
ctrl_outl(0x00000500, BSC_CS4WCR);
/* setup KEYSC pins */
gpio_request(GPIO_FN_KEYOUT0, NULL);
gpio_request(GPIO_FN_KEYOUT1, NULL);
gpio_request(GPIO_FN_KEYOUT2, NULL);
gpio_request(GPIO_FN_KEYOUT3, NULL);
gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
gpio_request(GPIO_FN_KEYIN0, NULL);
gpio_request(GPIO_FN_KEYIN1, NULL);
gpio_request(GPIO_FN_KEYIN2, NULL);
gpio_request(GPIO_FN_KEYIN3, NULL);
gpio_request(GPIO_FN_KEYIN4, NULL);
gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
/* setup LCDC pins for SYS panel */
gpio_request(GPIO_FN_LCDD17, NULL);
gpio_request(GPIO_FN_LCDD16, NULL);
gpio_request(GPIO_FN_LCDD15, NULL);
gpio_request(GPIO_FN_LCDD14, NULL);
gpio_request(GPIO_FN_LCDD13, NULL);
gpio_request(GPIO_FN_LCDD12, NULL);
gpio_request(GPIO_FN_LCDD11, NULL);
gpio_request(GPIO_FN_LCDD10, NULL);
gpio_request(GPIO_FN_LCDD9, NULL);
gpio_request(GPIO_FN_LCDD8, NULL);
gpio_request(GPIO_FN_LCDD7, NULL);
gpio_request(GPIO_FN_LCDD6, NULL);
gpio_request(GPIO_FN_LCDD5, NULL);
gpio_request(GPIO_FN_LCDD4, NULL);
gpio_request(GPIO_FN_LCDD3, NULL);
gpio_request(GPIO_FN_LCDD2, NULL);
gpio_request(GPIO_FN_LCDD1, NULL);
gpio_request(GPIO_FN_LCDD0, NULL);
gpio_request(GPIO_FN_LCDRS, NULL); /* LCD_RS */
gpio_request(GPIO_FN_LCDCS, NULL); /* LCD_CS/ */
gpio_request(GPIO_FN_LCDRD, NULL); /* LCD_RD/ */
gpio_request(GPIO_FN_LCDWR, NULL); /* LCD_WR/ */
gpio_request(GPIO_FN_LCDVSYN, NULL); /* LCD_VSYNC */
gpio_request(GPIO_PTE4, NULL); /* LCD_RST/ */
gpio_direction_output(GPIO_PTE4, 1);
gpio_request(GPIO_PTF4, NULL); /* PROTECT/ */
gpio_direction_output(GPIO_PTF4, 1);
gpio_request(GPIO_PTU0, NULL); /* LEDSTDBY/ */
gpio_direction_output(GPIO_PTU0, 1);
return platform_add_devices(kfr2r09_devices,
ARRAY_SIZE(kfr2r09_devices));
}
device_initcall(kfr2r09_devices_setup);
/* Return the board specific boot mode pin configuration */
static int kfr2r09_mode_pins(void)
{
/* MD0=1, MD1=1, MD2=0: Clock Mode 3
* MD3=0: 16-bit Area0 Bus Width
* MD5=1: Little Endian
* MD8=1: Test Mode Disabled
*/
return MODE_PIN0 | MODE_PIN1 | MODE_PIN5 | MODE_PIN8;
}
/*
* The Machine Vector
*/
static struct sh_machine_vector mv_kfr2r09 __initmv = {
.mv_name = "kfr2r09",
.mv_mode_pins = kfr2r09_mode_pins,
};

View File

@ -98,6 +98,9 @@ static struct platform_device sh_keysc_device = {
.dev = {
.platform_data = &sh_keysc_info,
},
.archdata = {
.hwblk_id = HWBLK_KEYSC,
},
};
static struct mtd_partition migor_nor_flash_partitions[] =
@ -292,6 +295,9 @@ static struct platform_device migor_lcdc_device = {
.dev = {
.platform_data = &sh_mobile_lcdc_info,
},
.archdata = {
.hwblk_id = HWBLK_LCDC,
},
};
static struct clk *camera_clk;
@ -379,6 +385,9 @@ static struct platform_device migor_ceu_device = {
.dev = {
.platform_data = &sh_mobile_ceu_info,
},
.archdata = {
.hwblk_id = HWBLK_CEU,
},
};
struct spi_gpio_platform_data sdcard_cn9_platform_data = {

View File

@ -22,6 +22,7 @@
#include <asm/io.h>
#include <asm/heartbeat.h>
#include <asm/sh_keysc.h>
#include <cpu/sh7722.h>
/* Heartbeat */
static struct heartbeat_data heartbeat_data = {
@ -137,6 +138,9 @@ static struct platform_device sh_keysc_device = {
.dev = {
.platform_data = &sh_keysc_info,
},
.archdata = {
.hwblk_id = HWBLK_KEYSC,
},
};
static struct platform_device *se7722_devices[] __initdata = {

View File

@ -39,7 +39,15 @@
* SW41 : abxx xxxx -> a = 0 : Analog monitor
* 1 : Digital monitor
* b = 0 : VGA
* 1 : SVGA
* 1 : 720p
*/
/*
* about 720p
*
* When you use 1280 x 720 lcdc output,
* you should change OSC6 lcdc clock from 25.175MHz to 74.25MHz,
* and change SW41 to use 720p
*/
/* Heartbeat */
@ -174,6 +182,9 @@ static struct platform_device lcdc_device = {
.dev = {
.platform_data = &lcdc_info,
},
.archdata = {
.hwblk_id = HWBLK_LCDC,
},
};
/* CEU0 */
@ -205,6 +216,9 @@ static struct platform_device ceu0_device = {
.dev = {
.platform_data = &sh_mobile_ceu0_info,
},
.archdata = {
.hwblk_id = HWBLK_CEU0,
},
};
/* CEU1 */
@ -236,6 +250,9 @@ static struct platform_device ceu1_device = {
.dev = {
.platform_data = &sh_mobile_ceu1_info,
},
.archdata = {
.hwblk_id = HWBLK_CEU1,
},
};
/* KEYSC in SoC (Needs SW33-2 set to ON) */
@ -274,6 +291,9 @@ static struct platform_device keysc_device = {
.dev = {
.platform_data = &keysc_info,
},
.archdata = {
.hwblk_id = HWBLK_KEYSC,
},
};
/* SH Eth */
@ -302,9 +322,13 @@ static struct platform_device sh_eth_device = {
},
.num_resources = ARRAY_SIZE(sh_eth_resources),
.resource = sh_eth_resources,
.archdata = {
.hwblk_id = HWBLK_ETHER,
},
};
static struct r8a66597_platdata sh7724_usb0_host_data = {
.on_chip = 1,
};
static struct resource sh7724_usb0_host_resources[] = {
@ -330,6 +354,9 @@ static struct platform_device sh7724_usb0_host_device = {
},
.num_resources = ARRAY_SIZE(sh7724_usb0_host_resources),
.resource = sh7724_usb0_host_resources,
.archdata = {
.hwblk_id = HWBLK_USB0,
},
};
static struct platform_device *ms7724se_devices[] __initdata = {
@ -421,6 +448,32 @@ static int __init devices_setup(void)
/* turn on USB clocks, use external clock */
ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
#ifdef CONFIG_PM
/* Let LED9 show STATUS2 */
gpio_request(GPIO_FN_STATUS2, NULL);
/* Lit LED10 show STATUS0 */
gpio_request(GPIO_FN_STATUS0, NULL);
/* Lit LED11 show PDSTATUS */
gpio_request(GPIO_FN_PDSTATUS, NULL);
#else
/* Lit LED9 */
gpio_request(GPIO_PTJ6, NULL);
gpio_direction_output(GPIO_PTJ6, 1);
gpio_export(GPIO_PTJ6, 0);
/* Lit LED10 */
gpio_request(GPIO_PTJ5, NULL);
gpio_direction_output(GPIO_PTJ5, 1);
gpio_export(GPIO_PTJ5, 0);
/* Lit LED11 */
gpio_request(GPIO_PTJ7, NULL);
gpio_direction_output(GPIO_PTJ7, 1);
gpio_export(GPIO_PTJ7, 0);
#endif
/* enable USB0 port */
ctrl_outw(0x0600, 0xa40501d4);
@ -546,15 +599,15 @@ static int __init devices_setup(void)
sh_eth_init();
if (sw & SW41_B) {
/* SVGA */
lcdc_info.ch[0].lcd_cfg.xres = 800;
lcdc_info.ch[0].lcd_cfg.yres = 600;
lcdc_info.ch[0].lcd_cfg.left_margin = 142;
lcdc_info.ch[0].lcd_cfg.right_margin = 52;
lcdc_info.ch[0].lcd_cfg.hsync_len = 96;
lcdc_info.ch[0].lcd_cfg.upper_margin = 24;
lcdc_info.ch[0].lcd_cfg.lower_margin = 2;
lcdc_info.ch[0].lcd_cfg.vsync_len = 2;
/* 720p */
lcdc_info.ch[0].lcd_cfg.xres = 1280;
lcdc_info.ch[0].lcd_cfg.yres = 720;
lcdc_info.ch[0].lcd_cfg.left_margin = 220;
lcdc_info.ch[0].lcd_cfg.right_margin = 110;
lcdc_info.ch[0].lcd_cfg.hsync_len = 40;
lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
lcdc_info.ch[0].lcd_cfg.vsync_len = 5;
} else {
/* VGA */
lcdc_info.ch[0].lcd_cfg.xres = 640;

View File

@ -17,6 +17,7 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/usb/r8a66597.h>
#include <linux/usb/m66592.h>
#include <asm/ilsel.h>
static struct resource heartbeat_resources[] = {
@ -89,6 +90,11 @@ static struct platform_device r8a66597_usb_host_device = {
.resource = r8a66597_usb_host_resources,
};
static struct m66592_platdata usbf_platdata = {
.xtal = M66592_PLATDATA_XTAL_24MHZ,
.vif = 1,
};
static struct resource m66592_usb_peripheral_resources[] = {
[0] = {
.name = "m66592_udc",
@ -109,6 +115,7 @@ static struct platform_device m66592_usb_peripheral_device = {
.dev = {
.dma_mask = NULL, /* don't use dma */
.coherent_dma_mask = 0xffffffff,
.platform_data = &usbf_platdata,
},
.num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources),
.resource = m66592_usb_peripheral_resources,

View File

@ -1,4 +1,3 @@
zImage
vmlinux.srec
uImage
uImage.srec
vmlinux*
uImage*

View File

@ -20,8 +20,13 @@ CONFIG_BOOT_LINK_OFFSET ?= 0x00800000
CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000
CONFIG_ENTRY_OFFSET ?= 0x00001000
targets := zImage vmlinux.srec uImage uImage.srec
subdir- := compressed
suffix-$(CONFIG_KERNEL_GZIP) := gz
suffix-$(CONFIG_KERNEL_BZIP2) := bz2
suffix-$(CONFIG_KERNEL_LZMA) := lzma
targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz uImage.bz2 uImage.lzma
extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma
subdir- := compressed romimage
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
@ -30,6 +35,13 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(obj)/compressed/vmlinux: FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
$(obj)/romImage: $(obj)/romimage/vmlinux FORCE
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
$(obj)/romimage/vmlinux: $(obj)/zImage FORCE
$(Q)$(MAKE) $(build)=$(obj)/romimage $@
KERNEL_MEMORY := 0x00000000
ifeq ($(CONFIG_PMB_FIXED),y)
KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
@ -40,9 +52,6 @@ KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
$$[$(CONFIG_MEMORY_START)]')
endif
export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \
CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET KERNEL_MEMORY
KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%08x" \
$$[$(CONFIG_PAGE_OFFSET) + \
$(KERNEL_MEMORY) + \
@ -55,19 +64,30 @@ KERNEL_ENTRY := $(shell /bin/bash -c 'printf "0x%08x" \
quiet_cmd_uimage = UIMAGE $@
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sh -O linux -T kernel \
-C gzip -a $(KERNEL_LOAD) -e $(KERNEL_ENTRY) \
-C $(2) -a $(KERNEL_LOAD) -e $(KERNEL_ENTRY) \
-n 'Linux-$(KERNELRELEASE)' -d $< $@
$(obj)/uImage: $(obj)/vmlinux.bin.gz FORCE
$(call if_changed,uimage)
@echo ' Image $@ is ready'
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)
$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
$(call if_changed,bzip2)
$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
$(call if_changed,lzma)
$(obj)/uImage.bz2: $(obj)/vmlinux.bin.bz2
$(call if_changed,uimage,bzip2)
$(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
$(call if_changed,uimage,gzip)
$(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
$(call if_changed,uimage,lzma)
OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec
$(obj)/vmlinux.srec: $(obj)/compressed/vmlinux
$(call if_changed,objcopy)
@ -76,5 +96,9 @@ OBJCOPYFLAGS_uImage.srec := -I binary -O srec
$(obj)/uImage.srec: $(obj)/uImage
$(call if_changed,objcopy)
clean-files += uImage uImage.srec vmlinux.srec \
vmlinux.bin vmlinux.bin.gz
$(obj)/uImage: $(obj)/uImage.$(suffix-y)
@ln -sf $(notdir $<) $@
@echo ' Image $@ is ready'
export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \
CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET KERNEL_MEMORY suffix-y

1
arch/sh/boot/compressed/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
vmlinux.bin.*

View File

@ -5,9 +5,10 @@
#
targets := vmlinux vmlinux.bin vmlinux.bin.gz \
head_$(BITS).o misc_$(BITS).o piggy.o
vmlinux.bin.bz2 vmlinux.bin.lzma \
head_$(BITS).o misc.o piggy.o
OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc_$(BITS).o $(obj)/cache.o
OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o
ifdef CONFIG_SH_STANDARD_BIOS
OBJECTS += $(obj)/../../kernel/sh_bios.o
@ -23,7 +24,7 @@ IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \
LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
ifeq ($(CONFIG_FUNCTION_TRACER),y)
ifeq ($(CONFIG_MCOUNT),y)
ORIG_CFLAGS := $(KBUILD_CFLAGS)
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
endif
@ -38,10 +39,18 @@ $(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
vmlinux.bin.all-y := $(obj)/vmlinux.bin
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
$(call if_changed,gzip)
$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
$(call if_changed,bzip2)
$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
$(call if_changed,lzma)
OBJCOPYFLAGS += -R .empty_zero_page
$(obj)/piggy.o: $(obj)/piggy.S $(obj)/vmlinux.bin.gz FORCE
$(call if_changed,as_o_S)
LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
$(call if_changed,ld)

View File

@ -0,0 +1,149 @@
/*
* arch/sh/boot/compressed/misc.c
*
* This is a collection of several routines from gzip-1.0.3
* adapted for Linux.
*
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
*
* Adapted for SH by Stuart Menefy, Aug 1999
*
* Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
*/
#include <asm/uaccess.h>
#include <asm/addrspace.h>
#include <asm/page.h>
#include <asm/sh_bios.h>
/*
* gzip declarations
*/
#define STATIC static
#undef memset
#undef memcpy
#define memzero(s, n) memset ((s), 0, (n))
/* cache.c */
#define CACHE_ENABLE 0
#define CACHE_DISABLE 1
int cache_control(unsigned int command);
extern char input_data[];
extern int input_len;
static unsigned char *output;
static void error(char *m);
int puts(const char *);
extern int _text; /* Defined in vmlinux.lds.S */
extern int _end;
static unsigned long free_mem_ptr;
static unsigned long free_mem_end_ptr;
#ifdef CONFIG_HAVE_KERNEL_BZIP2
#define HEAP_SIZE 0x400000
#else
#define HEAP_SIZE 0x10000
#endif
#ifdef CONFIG_KERNEL_GZIP
#include "../../../../lib/decompress_inflate.c"
#endif
#ifdef CONFIG_KERNEL_BZIP2
#include "../../../../lib/decompress_bunzip2.c"
#endif
#ifdef CONFIG_KERNEL_LZMA
#include "../../../../lib/decompress_unlzma.c"
#endif
#ifdef CONFIG_SH_STANDARD_BIOS
size_t strlen(const char *s)
{
int i = 0;
while (*s++)
i++;
return i;
}
int puts(const char *s)
{
int len = strlen(s);
sh_bios_console_write(s, len);
return len;
}
#else
int puts(const char *s)
{
/* This should be updated to use the sh-sci routines */
return 0;
}
#endif
void* memset(void* s, int c, size_t n)
{
int i;
char *ss = (char*)s;
for (i=0;i<n;i++) ss[i] = c;
return s;
}
void* memcpy(void* __dest, __const void* __src,
size_t __n)
{
int i;
char *d = (char *)__dest, *s = (char *)__src;
for (i=0;i<__n;i++) d[i] = s[i];
return __dest;
}
static void error(char *x)
{
puts("\n\n");
puts(x);
puts("\n\n -- System halted");
while(1); /* Halt */
}
#ifdef CONFIG_SUPERH64
#define stackalign 8
#else
#define stackalign 4
#endif
#define STACK_SIZE (4096)
long __attribute__ ((aligned(stackalign))) user_stack[STACK_SIZE];
long *stack_start = &user_stack[STACK_SIZE];
void decompress_kernel(void)
{
unsigned long output_addr;
#ifdef CONFIG_SUPERH64
output_addr = (CONFIG_MEMORY_START + 0x2000);
#else
output_addr = PHYSADDR((unsigned long)&_text+PAGE_SIZE);
#ifdef CONFIG_29BIT
output_addr |= P2SEG;
#endif
#endif
output = (unsigned char *)output_addr;
free_mem_ptr = (unsigned long)&_end;
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
puts("Uncompressing Linux... ");
cache_control(CACHE_ENABLE);
decompress(input_data, input_len, NULL, NULL, output, NULL, error);
cache_control(CACHE_DISABLE);
puts("Ok, booting the kernel.\n");
}

View File

@ -1,206 +0,0 @@
/*
* arch/sh/boot/compressed/misc.c
*
* This is a collection of several routines from gzip-1.0.3
* adapted for Linux.
*
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
*
* Adapted for SH by Stuart Menefy, Aug 1999
*
* Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
*/
#include <asm/uaccess.h>
#include <asm/addrspace.h>
#include <asm/page.h>
#ifdef CONFIG_SH_STANDARD_BIOS
#include <asm/sh_bios.h>
#endif
/*
* gzip declarations
*/
#define OF(args) args
#define STATIC static
#undef memset
#undef memcpy
#define memzero(s, n) memset ((s), 0, (n))
typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;
#define WSIZE 0x8000 /* Window size must be at least 32k, */
/* and a power of two */
static uch *inbuf; /* input buffer */
static uch window[WSIZE]; /* Sliding window buffer */
static unsigned insize = 0; /* valid bytes in inbuf */
static unsigned inptr = 0; /* index of next byte to be processed in inbuf */
static unsigned outcnt = 0; /* bytes in output buffer */
/* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
#define COMMENT 0x10 /* bit 4 set: file comment present */
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
#define RESERVED 0xC0 /* bit 6,7: reserved */
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
/* Diagnostic functions */
#ifdef DEBUG
# define Assert(cond,msg) {if(!(cond)) error(msg);}
# define Trace(x) fprintf x
# define Tracev(x) {if (verbose) fprintf x ;}
# define Tracevv(x) {if (verbose>1) fprintf x ;}
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
#else
# define Assert(cond,msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
# define Tracec(c,x)
# define Tracecv(c,x)
#endif
static int fill_inbuf(void);
static void flush_window(void);
static void error(char *m);
extern char input_data[];
extern int input_len;
static long bytes_out = 0;
static uch *output_data;
static unsigned long output_ptr = 0;
static void error(char *m);
int puts(const char *);
extern int _text; /* Defined in vmlinux.lds.S */
extern int _end;
static unsigned long free_mem_ptr;
static unsigned long free_mem_end_ptr;
#define HEAP_SIZE 0x10000
#include "../../../../lib/inflate.c"
#ifdef CONFIG_SH_STANDARD_BIOS
size_t strlen(const char *s)
{
int i = 0;
while (*s++)
i++;
return i;
}
int puts(const char *s)
{
int len = strlen(s);
sh_bios_console_write(s, len);
return len;
}
#else
int puts(const char *s)
{
/* This should be updated to use the sh-sci routines */
return 0;
}
#endif
void* memset(void* s, int c, size_t n)
{
int i;
char *ss = (char*)s;
for (i=0;i<n;i++) ss[i] = c;
return s;
}
void* memcpy(void* __dest, __const void* __src,
size_t __n)
{
int i;
char *d = (char *)__dest, *s = (char *)__src;
for (i=0;i<__n;i++) d[i] = s[i];
return __dest;
}
/* ===========================================================================
* Fill the input buffer. This is called only when the buffer is empty
* and at least one byte is really needed.
*/
static int fill_inbuf(void)
{
if (insize != 0) {
error("ran out of input data");
}
inbuf = input_data;
insize = input_len;
inptr = 1;
return inbuf[0];
}
/* ===========================================================================
* Write the output window window[0..outcnt-1] and update crc and bytes_out.
* (Used for the decompressed data only.)
*/
static void flush_window(void)
{
ulg c = crc; /* temporary variable */
unsigned n;
uch *in, *out, ch;
in = window;
out = &output_data[output_ptr];
for (n = 0; n < outcnt; n++) {
ch = *out++ = *in++;
c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
}
crc = c;
bytes_out += (ulg)outcnt;
output_ptr += (ulg)outcnt;
outcnt = 0;
}
static void error(char *x)
{
puts("\n\n");
puts(x);
puts("\n\n -- System halted");
while(1); /* Halt */
}
#define STACK_SIZE (4096)
long user_stack [STACK_SIZE];
long* stack_start = &user_stack[STACK_SIZE];
void decompress_kernel(void)
{
output_data = NULL;
output_ptr = PHYSADDR((unsigned long)&_text+PAGE_SIZE);
#ifdef CONFIG_29BIT
output_ptr |= P2SEG;
#endif
free_mem_ptr = (unsigned long)&_end;
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
makecrc();
puts("Uncompressing Linux... ");
gunzip();
puts("Ok, booting the kernel.\n");
}

View File

@ -1,210 +0,0 @@
/*
* arch/sh/boot/compressed/misc_64.c
*
* This is a collection of several routines from gzip-1.0.3
* adapted for Linux.
*
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
*
* Adapted for SHmedia from sh by Stuart Menefy, May 2002
*/
#include <asm/uaccess.h>
/* cache.c */
#define CACHE_ENABLE 0
#define CACHE_DISABLE 1
int cache_control(unsigned int command);
/*
* gzip declarations
*/
#define OF(args) args
#define STATIC static
#undef memset
#undef memcpy
#define memzero(s, n) memset ((s), 0, (n))
typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;
#define WSIZE 0x8000 /* Window size must be at least 32k, */
/* and a power of two */
static uch *inbuf; /* input buffer */
static uch window[WSIZE]; /* Sliding window buffer */
static unsigned insize = 0; /* valid bytes in inbuf */
static unsigned inptr = 0; /* index of next byte to be processed in inbuf */
static unsigned outcnt = 0; /* bytes in output buffer */
/* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
#define COMMENT 0x10 /* bit 4 set: file comment present */
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
#define RESERVED 0xC0 /* bit 6,7: reserved */
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
/* Diagnostic functions */
#ifdef DEBUG
# define Assert(cond,msg) {if(!(cond)) error(msg);}
# define Trace(x) fprintf x
# define Tracev(x) {if (verbose) fprintf x ;}
# define Tracevv(x) {if (verbose>1) fprintf x ;}
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
#else
# define Assert(cond,msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
# define Tracec(c,x)
# define Tracecv(c,x)
#endif
static int fill_inbuf(void);
static void flush_window(void);
static void error(char *m);
extern char input_data[];
extern int input_len;
static long bytes_out = 0;
static uch *output_data;
static unsigned long output_ptr = 0;
static void error(char *m);
static void puts(const char *);
extern int _text; /* Defined in vmlinux.lds.S */
extern int _end;
static unsigned long free_mem_ptr;
static unsigned long free_mem_end_ptr;
#define HEAP_SIZE 0x10000
#include "../../../../lib/inflate.c"
void puts(const char *s)
{
}
void *memset(void *s, int c, size_t n)
{
int i;
char *ss = (char *) s;
for (i = 0; i < n; i++)
ss[i] = c;
return s;
}
void *memcpy(void *__dest, __const void *__src, size_t __n)
{
int i;
char *d = (char *) __dest, *s = (char *) __src;
for (i = 0; i < __n; i++)
d[i] = s[i];
return __dest;
}
/* ===========================================================================
* Fill the input buffer. This is called only when the buffer is empty
* and at least one byte is really needed.
*/
static int fill_inbuf(void)
{
if (insize != 0) {
error("ran out of input data\n");
}
inbuf = input_data;
insize = input_len;
inptr = 1;
return inbuf[0];
}
/* ===========================================================================
* Write the output window window[0..outcnt-1] and update crc and bytes_out.
* (Used for the decompressed data only.)
*/
static void flush_window(void)
{
ulg c = crc; /* temporary variable */
unsigned n;
uch *in, *out, ch;
in = window;
out = &output_data[output_ptr];
for (n = 0; n < outcnt; n++) {
ch = *out++ = *in++;
c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
}
crc = c;
bytes_out += (ulg) outcnt;
output_ptr += (ulg) outcnt;
outcnt = 0;
puts(".");
}
static void error(char *x)
{
puts("\n\n");
puts(x);
puts("\n\n -- System halted");
while (1) ; /* Halt */
}
#define STACK_SIZE (4096)
long __attribute__ ((aligned(8))) user_stack[STACK_SIZE];
long *stack_start = &user_stack[STACK_SIZE];
void decompress_kernel(void)
{
output_data = (uch *) (CONFIG_MEMORY_START + 0x2000);
free_mem_ptr = (unsigned long) &_end;
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
makecrc();
puts("Uncompressing Linux... ");
cache_control(CACHE_ENABLE);
gunzip();
puts("\n");
#if 0
/* When booting from ROM may want to do something like this if the
* boot loader doesn't.
*/
/* Set up the parameters and command line */
{
volatile unsigned int *parambase =
(int *) (CONFIG_MEMORY_START + 0x1000);
parambase[0] = 0x1; /* MOUNT_ROOT_RDONLY */
parambase[1] = 0x0; /* RAMDISK_FLAGS */
parambase[2] = 0x0200; /* ORIG_ROOT_DEV */
parambase[3] = 0x0; /* LOADER_TYPE */
parambase[4] = 0x0; /* INITRD_START */
parambase[5] = 0x0; /* INITRD_SIZE */
parambase[6] = 0;
strcpy((char *) ((int) parambase + 0x100),
"console=ttySC0,38400");
}
#endif
puts("Ok, booting the kernel.\n");
cache_control(CACHE_DISABLE);
}

View File

@ -1,8 +0,0 @@
.global input_len, input_data
.data
input_len:
.long input_data_end - input_data
input_data:
.incbin "arch/sh/boot/compressed/vmlinux.bin.gz"
input_data_end:
.end

View File

@ -0,0 +1,10 @@
SECTIONS
{
.rodata.compressed : {
input_len = .;
LONG(input_data_end - input_data) input_data = .;
*(.data)
output_len = . - 4;
input_data_end = .;
}
}

View File

@ -0,0 +1,19 @@
#
# linux/arch/sh/boot/romimage/Makefile
#
# create an image suitable for burning to flash from zImage
#
targets := vmlinux head.o
OBJECTS = $(obj)/head.o
LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext 0 -e romstart
$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE
$(call if_changed,ld)
@:
LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T
$(obj)/piggy.o: $(obj)/vmlinux.scr arch/sh/boot/zImage FORCE
$(call if_changed,ld)

View File

@ -0,0 +1,10 @@
/*
* linux/arch/sh/boot/romimage/head.S
*
* Board specific setup code, executed before zImage loader
*/
.text
.global romstart
romstart:
#include <mach/romimage.h>

View File

@ -0,0 +1,6 @@
SECTIONS
{
.text : {
*(.data)
}
}

View File

@ -0,0 +1,877 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.31-rc3
# Thu Jul 23 17:45:09 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_IRQ_PER_CPU=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_SYS_SUPPORTS_TMU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
#
# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
#
# RCU Subsystem
#
CONFIG_CLASSIC_RCU=y
# CONFIG_TREE_RCU is not set
# CONFIG_PREEMPT_RCU is not set
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
# CONFIG_KALLSYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_HAVE_PERF_COUNTERS=y
#
# Performance Counters
#
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
#
# CONFIG_GCOV_KERNEL is not set
# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY 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"
# CONFIG_FREEZER is not set
#
# System type
#
CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
CONFIG_CPU_SHX2=y
CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
# CONFIG_CPU_SUBTYPE_SH7206 is not set
# CONFIG_CPU_SUBTYPE_SH7263 is not set
# CONFIG_CPU_SUBTYPE_MXG 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
# CONFIG_CPU_SUBTYPE_SH7712 is not set
# CONFIG_CPU_SUBTYPE_SH7720 is not set
# CONFIG_CPU_SUBTYPE_SH7721 is not set
# 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
# CONFIG_CPU_SUBTYPE_SH7723 is not set
CONFIG_CPU_SUBTYPE_SH7724=y
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
#
# Memory management options
#
CONFIG_QUICKLIST=y
CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_FORCE_MAX_ZONEORDER=11
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
CONFIG_29BIT=y
# CONFIG_X2TLB is not set
CONFIG_VSYSCALL=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
CONFIG_MAX_ACTIVE_REGIONS=1
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
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=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
#
# Cache configuration
#
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
#
# Processor features
#
CONFIG_CPU_LITTLE_ENDIAN=y
# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_SH_FPU=y
# CONFIG_SH_STORE_QUEUES is not set
CONFIG_CPU_HAS_INTEVT=y
CONFIG_CPU_HAS_SR_RB=y
CONFIG_CPU_HAS_FPU=y
#
# Board support
#
# CONFIG_SH_7724_SOLUTION_ENGINE is not set
CONFIG_SH_KFR2R09=y
#
# Timer and clock configuration
#
# CONFIG_SH_TIMER_TMU is not set
CONFIG_SH_TIMER_CMT=y
CONFIG_SH_PCLK_FREQ=33333333
CONFIG_SH_CLK_CPG=y
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set
#
# DMA support
#
# CONFIG_SH_DMA is not set
#
# Companion Chips
#
#
# Additional SuperH Device Drivers
#
# CONFIG_HEARTBEAT is not set
# CONFIG_PUSH_SWITCH is not set
#
# Kernel features
#
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000
# CONFIG_SCHED_HRTICK is not set
CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
# CONFIG_SECCOMP is not set
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
CONFIG_GUSA=y
# CONFIG_SPARSE_IRQ is not set
#
# Boot options
#
CONFIG_ZERO_PAGE_OFFSET=0x00001000
CONFIG_BOOT_LINK_OFFSET=0x00800000
CONFIG_ENTRY_OFFSET=0x00001000
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="console=ttySC1,115200"
#
# Bus options
#
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCCARD is not set
#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
#
# Power management options (EXPERIMENTAL)
#
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
# CONFIG_SUSPEND is not set
# CONFIG_HIBERNATION is not set
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_IDLE_GOV_MENU=y
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
# 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 is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
# 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_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_NET_DSA 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
# CONFIG_PHONET is not set
# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
# CONFIG_WIRELESS is not set
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
#
# Device Drivers
#
#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set
#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLKDEVS=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
# CONFIG_MTD_OOPS 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=y
# CONFIG_MTD_CFI_AMDSTD is not set
# 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
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
# CONFIG_MTD_PHYSMAP_COMPAT 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
# CONFIG_MTD_NAND is not set
# CONFIG_MTD_ONENAND is not set
#
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
#
# UBI - Unsorted block images
#
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI_BEB_RESERVE=1
# CONFIG_MTD_UBI_GLUEBI is not set
#
# UBI debugging options
#
# CONFIG_MTD_UBI_DEBUG is not set
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# 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 is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
# CONFIG_MISC_DEVICES is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
# CONFIG_SCSI_NETLINK is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_NETDEVICES is not set
# CONFIG_ISDN is not set
# CONFIG_PHONE is not set
#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
#
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_ATKBD is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_GPIO is not set
# CONFIG_KEYBOARD_MATRIX is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
CONFIG_KEYBOARD_SH_KEYSC=y
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
#
# Hardware I/O ports
#
# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
#
# Character devices
#
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_DEVKMEM=y
# 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=6
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
# CONFIG_I2C_CHARDEV is not set
CONFIG_I2C_HELPER_AUTO=y
#
# I2C Hardware Bus support
#
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
# CONFIG_I2C_DESIGNWARE is not set
# CONFIG_I2C_GPIO is not set
# CONFIG_I2C_OCORES is not set
CONFIG_I2C_SH_MOBILE=y
# CONFIG_I2C_SIMTEC is not set
#
# External I2C/SMBus adapter drivers
#
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_TAOS_EVM is not set
#
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_PCA_PLATFORM is not set
#
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SPI is not set
#
# PPS support
#
# CONFIG_PPS is not set
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
#
# Memory mapped GPIO expanders:
#
#
# I2C GPIO expanders:
#
# CONFIG_GPIO_MAX732X is not set
# CONFIG_GPIO_PCA953X is not set
# CONFIG_GPIO_PCF857X is not set
#
# PCI GPIO expanders:
#
#
# SPI GPIO expanders:
#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
# CONFIG_SSB is not set
#
# Multifunction device drivers
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_TPS65010 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
#
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
# CONFIG_FB is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set
#
# Console display driver support
#
CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
CONFIG_RTC_LIB=y
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=y
# CONFIG_UIO_PDRV is not set
CONFIG_UIO_PDRV_GENIRQ=y
# CONFIG_UIO_SMX is not set
# CONFIG_UIO_SERCOS3 is not set
#
# TI VLYNQ
#
# CONFIG_STAGING is not set
#
# File systems
#
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
# CONFIG_EXT4_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_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
CONFIG_FILE_LOCKING=y
# CONFIG_FSNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
#
# Caches
#
# CONFIG_FSCACHE 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_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
# CONFIG_MISC_FILESYSTEMS is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
# CONFIG_DLM is not set
#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_WARN_DEPRECATED=y
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FTRACE_SYSCALLS=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
# CONFIG_BINARY_PRINTF is not set
#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_GENERIC_FIND_LAST_BIT=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
CONFIG_CRC7=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_HAVE_LMB=y
CONFIG_NLATTR=y
CONFIG_GENERIC_ATOMIC64=y

View File

@ -3,7 +3,9 @@
*
* This file is released under the GPLv2
*/
#include <asm-generic/device.h>
struct dev_archdata {
};
struct platform_device;
/* allocate contiguous memory chunk and fill in struct resource */
@ -12,3 +14,6 @@ int platform_resource_setup_memory(struct platform_device *pdev,
void plat_early_device_setup(void);
struct pdev_archdata {
int hwblk_id;
};

View File

@ -16,6 +16,7 @@
/* DMAOR contorl: The DMAOR access size is different by CPU.*/
#if defined(CONFIG_CPU_SUBTYPE_SH7723) || \
defined(CONFIG_CPU_SUBTYPE_SH7724) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785)
#define dmaor_read_reg(n) \

402
arch/sh/include/asm/dwarf.h Normal file
View File

@ -0,0 +1,402 @@
/*
* Copyright (C) 2009 Matt Fleming <matt@console-pimps.org>
*
* 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_SH_DWARF_H
#define __ASM_SH_DWARF_H
#ifdef CONFIG_DWARF_UNWINDER
/*
* DWARF expression operations
*/
#define DW_OP_addr 0x03
#define DW_OP_deref 0x06
#define DW_OP_const1u 0x08
#define DW_OP_const1s 0x09
#define DW_OP_const2u 0x0a
#define DW_OP_const2s 0x0b
#define DW_OP_const4u 0x0c
#define DW_OP_const4s 0x0d
#define DW_OP_const8u 0x0e
#define DW_OP_const8s 0x0f
#define DW_OP_constu 0x10
#define DW_OP_consts 0x11
#define DW_OP_dup 0x12
#define DW_OP_drop 0x13
#define DW_OP_over 0x14
#define DW_OP_pick 0x15
#define DW_OP_swap 0x16
#define DW_OP_rot 0x17
#define DW_OP_xderef 0x18
#define DW_OP_abs 0x19
#define DW_OP_and 0x1a
#define DW_OP_div 0x1b
#define DW_OP_minus 0x1c
#define DW_OP_mod 0x1d
#define DW_OP_mul 0x1e
#define DW_OP_neg 0x1f
#define DW_OP_not 0x20
#define DW_OP_or 0x21
#define DW_OP_plus 0x22
#define DW_OP_plus_uconst 0x23
#define DW_OP_shl 0x24
#define DW_OP_shr 0x25
#define DW_OP_shra 0x26
#define DW_OP_xor 0x27
#define DW_OP_skip 0x2f
#define DW_OP_bra 0x28
#define DW_OP_eq 0x29
#define DW_OP_ge 0x2a
#define DW_OP_gt 0x2b
#define DW_OP_le 0x2c
#define DW_OP_lt 0x2d
#define DW_OP_ne 0x2e
#define DW_OP_lit0 0x30
#define DW_OP_lit1 0x31
#define DW_OP_lit2 0x32
#define DW_OP_lit3 0x33
#define DW_OP_lit4 0x34
#define DW_OP_lit5 0x35
#define DW_OP_lit6 0x36
#define DW_OP_lit7 0x37
#define DW_OP_lit8 0x38
#define DW_OP_lit9 0x39
#define DW_OP_lit10 0x3a
#define DW_OP_lit11 0x3b
#define DW_OP_lit12 0x3c
#define DW_OP_lit13 0x3d
#define DW_OP_lit14 0x3e
#define DW_OP_lit15 0x3f
#define DW_OP_lit16 0x40
#define DW_OP_lit17 0x41
#define DW_OP_lit18 0x42
#define DW_OP_lit19 0x43
#define DW_OP_lit20 0x44
#define DW_OP_lit21 0x45
#define DW_OP_lit22 0x46
#define DW_OP_lit23 0x47
#define DW_OP_lit24 0x48
#define DW_OP_lit25 0x49
#define DW_OP_lit26 0x4a
#define DW_OP_lit27 0x4b
#define DW_OP_lit28 0x4c
#define DW_OP_lit29 0x4d
#define DW_OP_lit30 0x4e
#define DW_OP_lit31 0x4f
#define DW_OP_reg0 0x50
#define DW_OP_reg1 0x51
#define DW_OP_reg2 0x52
#define DW_OP_reg3 0x53
#define DW_OP_reg4 0x54
#define DW_OP_reg5 0x55
#define DW_OP_reg6 0x56
#define DW_OP_reg7 0x57
#define DW_OP_reg8 0x58
#define DW_OP_reg9 0x59
#define DW_OP_reg10 0x5a
#define DW_OP_reg11 0x5b
#define DW_OP_reg12 0x5c
#define DW_OP_reg13 0x5d
#define DW_OP_reg14 0x5e
#define DW_OP_reg15 0x5f
#define DW_OP_reg16 0x60
#define DW_OP_reg17 0x61
#define DW_OP_reg18 0x62
#define DW_OP_reg19 0x63
#define DW_OP_reg20 0x64
#define DW_OP_reg21 0x65
#define DW_OP_reg22 0x66
#define DW_OP_reg23 0x67
#define DW_OP_reg24 0x68
#define DW_OP_reg25 0x69
#define DW_OP_reg26 0x6a
#define DW_OP_reg27 0x6b
#define DW_OP_reg28 0x6c
#define DW_OP_reg29 0x6d
#define DW_OP_reg30 0x6e
#define DW_OP_reg31 0x6f
#define DW_OP_breg0 0x70
#define DW_OP_breg1 0x71
#define DW_OP_breg2 0x72
#define DW_OP_breg3 0x73
#define DW_OP_breg4 0x74
#define DW_OP_breg5 0x75
#define DW_OP_breg6 0x76
#define DW_OP_breg7 0x77
#define DW_OP_breg8 0x78
#define DW_OP_breg9 0x79
#define DW_OP_breg10 0x7a
#define DW_OP_breg11 0x7b
#define DW_OP_breg12 0x7c
#define DW_OP_breg13 0x7d
#define DW_OP_breg14 0x7e
#define DW_OP_breg15 0x7f
#define DW_OP_breg16 0x80
#define DW_OP_breg17 0x81
#define DW_OP_breg18 0x82
#define DW_OP_breg19 0x83
#define DW_OP_breg20 0x84
#define DW_OP_breg21 0x85
#define DW_OP_breg22 0x86
#define DW_OP_breg23 0x87
#define DW_OP_breg24 0x88
#define DW_OP_breg25 0x89
#define DW_OP_breg26 0x8a
#define DW_OP_breg27 0x8b
#define DW_OP_breg28 0x8c
#define DW_OP_breg29 0x8d
#define DW_OP_breg30 0x8e
#define DW_OP_breg31 0x8f
#define DW_OP_regx 0x90
#define DW_OP_fbreg 0x91
#define DW_OP_bregx 0x92
#define DW_OP_piece 0x93
#define DW_OP_deref_size 0x94
#define DW_OP_xderef_size 0x95
#define DW_OP_nop 0x96
#define DW_OP_push_object_address 0x97
#define DW_OP_call2 0x98
#define DW_OP_call4 0x99
#define DW_OP_call_ref 0x9a
#define DW_OP_form_tls_address 0x9b
#define DW_OP_call_frame_cfa 0x9c
#define DW_OP_bit_piece 0x9d
#define DW_OP_lo_user 0xe0
#define DW_OP_hi_user 0xff
/*
* Addresses used in FDE entries in the .eh_frame section may be encoded
* using one of the following encodings.
*/
#define DW_EH_PE_absptr 0x00
#define DW_EH_PE_omit 0xff
#define DW_EH_PE_uleb128 0x01
#define DW_EH_PE_udata2 0x02
#define DW_EH_PE_udata4 0x03
#define DW_EH_PE_udata8 0x04
#define DW_EH_PE_sleb128 0x09
#define DW_EH_PE_sdata2 0x0a
#define DW_EH_PE_sdata4 0x0b
#define DW_EH_PE_sdata8 0x0c
#define DW_EH_PE_signed 0x09
#define DW_EH_PE_pcrel 0x10
/*
* The architecture-specific register number that contains the return
* address in the .debug_frame table.
*/
#define DWARF_ARCH_RA_REG 17
#ifndef __ASSEMBLY__
/*
* Read either the frame pointer (r14) or the stack pointer (r15).
* NOTE: this MUST be inlined.
*/
static __always_inline unsigned long dwarf_read_arch_reg(unsigned int reg)
{
unsigned long value;
switch (reg) {
case 14:
__asm__ __volatile__("mov r14, %0\n" : "=r" (value));
break;
case 15:
__asm__ __volatile__("mov r15, %0\n" : "=r" (value));
break;
default:
BUG();
}
return value;
}
/**
* dwarf_cie - Common Information Entry
*/
struct dwarf_cie {
unsigned long length;
unsigned long cie_id;
unsigned char version;
const char *augmentation;
unsigned int code_alignment_factor;
int data_alignment_factor;
/* Which column in the rule table represents return addr of func. */
unsigned int return_address_reg;
unsigned char *initial_instructions;
unsigned char *instructions_end;
unsigned char encoding;
unsigned long cie_pointer;
struct list_head link;
unsigned long flags;
#define DWARF_CIE_Z_AUGMENTATION (1 << 0)
};
/**
* dwarf_fde - Frame Description Entry
*/
struct dwarf_fde {
unsigned long length;
unsigned long cie_pointer;
struct dwarf_cie *cie;
unsigned long initial_location;
unsigned long address_range;
unsigned char *instructions;
unsigned char *end;
struct list_head link;
};
/**
* dwarf_frame - DWARF information for a frame in the call stack
*/
struct dwarf_frame {
struct dwarf_frame *prev, *next;
unsigned long pc;
struct dwarf_reg *regs;
unsigned int num_regs; /* how many regs are allocated? */
unsigned int depth; /* what level are we in the callstack? */
unsigned long cfa;
/* Valid when DW_FRAME_CFA_REG_OFFSET is set in flags */
unsigned int cfa_register;
unsigned int cfa_offset;
/* Valid when DW_FRAME_CFA_REG_EXP is set in flags */
unsigned char *cfa_expr;
unsigned int cfa_expr_len;
unsigned long flags;
#define DWARF_FRAME_CFA_REG_OFFSET (1 << 0)
#define DWARF_FRAME_CFA_REG_EXP (1 << 1)
unsigned long return_addr;
};
/**
* dwarf_reg - DWARF register
* @flags: Describes how to calculate the value of this register
*/
struct dwarf_reg {
unsigned long addr;
unsigned long flags;
#define DWARF_REG_OFFSET (1 << 0)
};
/**
* dwarf_stack - a DWARF stack contains a collection of DWARF frames
* @depth: the number of frames in the stack
* @level: an array of DWARF frames, indexed by stack level
*
*/
struct dwarf_stack {
unsigned int depth;
struct dwarf_frame **level;
};
/*
* Call Frame instruction opcodes.
*/
#define DW_CFA_advance_loc 0x40
#define DW_CFA_offset 0x80
#define DW_CFA_restore 0xc0
#define DW_CFA_nop 0x00
#define DW_CFA_set_loc 0x01
#define DW_CFA_advance_loc1 0x02
#define DW_CFA_advance_loc2 0x03
#define DW_CFA_advance_loc4 0x04
#define DW_CFA_offset_extended 0x05
#define DW_CFA_restore_extended 0x06
#define DW_CFA_undefined 0x07
#define DW_CFA_same_value 0x08
#define DW_CFA_register 0x09
#define DW_CFA_remember_state 0x0a
#define DW_CFA_restore_state 0x0b
#define DW_CFA_def_cfa 0x0c
#define DW_CFA_def_cfa_register 0x0d
#define DW_CFA_def_cfa_offset 0x0e
#define DW_CFA_def_cfa_expression 0x0f
#define DW_CFA_expression 0x10
#define DW_CFA_offset_extended_sf 0x11
#define DW_CFA_def_cfa_sf 0x12
#define DW_CFA_def_cfa_offset_sf 0x13
#define DW_CFA_val_offset 0x14
#define DW_CFA_val_offset_sf 0x15
#define DW_CFA_val_expression 0x16
#define DW_CFA_lo_user 0x1c
#define DW_CFA_hi_user 0x3f
/*
* Some call frame instructions encode their operands in the opcode. We
* need some helper functions to extract both the opcode and operands
* from an instruction.
*/
static inline unsigned int DW_CFA_opcode(unsigned long insn)
{
return (insn & 0xc0);
}
static inline unsigned int DW_CFA_operand(unsigned long insn)
{
return (insn & 0x3f);
}
#define DW_EH_FRAME_CIE 0 /* .eh_frame CIE IDs are 0 */
#define DW_CIE_ID 0xffffffff
#define DW64_CIE_ID 0xffffffffffffffffULL
/*
* DWARF FDE/CIE length field values.
*/
#define DW_EXT_LO 0xfffffff0
#define DW_EXT_HI 0xffffffff
#define DW_EXT_DWARF64 DW_EXT_HI
extern void dwarf_unwinder_init(void);
extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
struct dwarf_frame *);
#endif /* __ASSEMBLY__ */
#define CFI_STARTPROC .cfi_startproc
#define CFI_ENDPROC .cfi_endproc
#define CFI_DEF_CFA .cfi_def_cfa
#define CFI_REGISTER .cfi_register
#define CFI_REL_OFFSET .cfi_rel_offset
#else
/*
* Use the asm comment character to ignore the rest of the line.
*/
#define CFI_IGNORE !
#define CFI_STARTPROC CFI_IGNORE
#define CFI_ENDPROC CFI_IGNORE
#define CFI_DEF_CFA CFI_IGNORE
#define CFI_REGISTER CFI_IGNORE
#define CFI_REL_OFFSET CFI_IGNORE
#ifndef __ASSEMBLY__
static inline void dwarf_unwinder_init(void)
{
}
#endif
#endif /* CONFIG_DWARF_UNWINDER */
#endif /* __ASM_SH_DWARF_H */

View File

@ -31,8 +31,92 @@
#endif
.endm
#ifdef CONFIG_TRACE_IRQFLAGS
.macro TRACE_IRQS_ON
mov.l r0, @-r15
mov.l r1, @-r15
mov.l r2, @-r15
mov.l r3, @-r15
mov.l r4, @-r15
mov.l r5, @-r15
mov.l r6, @-r15
mov.l r7, @-r15
mov.l 7834f, r0
jsr @r0
nop
mov.l @r15+, r7
mov.l @r15+, r6
mov.l @r15+, r5
mov.l @r15+, r4
mov.l @r15+, r3
mov.l @r15+, r2
mov.l @r15+, r1
mov.l @r15+, r0
mov.l 7834f, r0
bra 7835f
nop
.balign 4
7834: .long trace_hardirqs_on
7835:
.endm
.macro TRACE_IRQS_OFF
mov.l r0, @-r15
mov.l r1, @-r15
mov.l r2, @-r15
mov.l r3, @-r15
mov.l r4, @-r15
mov.l r5, @-r15
mov.l r6, @-r15
mov.l r7, @-r15
mov.l 7834f, r0
jsr @r0
nop
mov.l @r15+, r7
mov.l @r15+, r6
mov.l @r15+, r5
mov.l @r15+, r4
mov.l @r15+, r3
mov.l @r15+, r2
mov.l @r15+, r1
mov.l @r15+, r0
mov.l 7834f, r0
bra 7835f
nop
.balign 4
7834: .long trace_hardirqs_off
7835:
.endm
#else
.macro TRACE_IRQS_ON
.endm
.macro TRACE_IRQS_OFF
.endm
#endif
#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
# define PREF(x) pref @x
#else
# define PREF(x) nop
#endif
/*
* Macro for use within assembly. Because the DWARF unwinder
* needs to use the frame register to unwind the stack, we
* need to setup r14 with the value of the stack pointer as
* the return address is usually on the stack somewhere.
*/
.macro setup_frame_reg
#ifdef CONFIG_DWARF_UNWINDER
mov r15, r14
#endif
.endm

View File

@ -11,10 +11,13 @@ extern void mcount(void);
#define MCOUNT_ADDR ((long)(mcount))
#ifdef CONFIG_DYNAMIC_FTRACE
#define CALLER_ADDR ((long)(ftrace_caller))
#define CALL_ADDR ((long)(ftrace_call))
#define STUB_ADDR ((long)(ftrace_stub))
#define GRAPH_ADDR ((long)(ftrace_graph_call))
#define CALLER_ADDR ((long)(ftrace_caller))
#define MCOUNT_INSN_OFFSET ((STUB_ADDR - CALLER_ADDR) >> 1)
#define MCOUNT_INSN_OFFSET ((STUB_ADDR - CALL_ADDR) - 4)
#define GRAPH_INSN_OFFSET ((CALLER_ADDR - GRAPH_ADDR) - 4)
struct dyn_arch_ftrace {
/* No extra data needed on sh */

View File

@ -1,16 +1,9 @@
#ifndef __ASM_SH_HARDIRQ_H
#define __ASM_SH_HARDIRQ_H
#include <linux/threads.h>
#include <linux/irq.h>
/* entry.S is sensitive to the offsets of these fields */
typedef struct {
unsigned int __softirq_pending;
} ____cacheline_aligned irq_cpustat_t;
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
extern void ack_bad_irq(unsigned int irq);
#define ack_bad_irq ack_bad_irq
#include <asm-generic/hardirq.h>
#endif /* __ASM_SH_HARDIRQ_H */

View File

@ -0,0 +1,70 @@
#ifndef __ASM_SH_HWBLK_H
#define __ASM_SH_HWBLK_H
#include <asm/clock.h>
#include <asm/io.h>
#define HWBLK_CNT_USAGE 0
#define HWBLK_CNT_NR 1
#define HWBLK_AREA_FLAG_PARENT (1 << 0) /* valid parent */
#define HWBLK_AREA(_flags, _parent) \
{ \
.flags = _flags, \
.parent = _parent, \
}
struct hwblk_area {
int cnt[HWBLK_CNT_NR];
unsigned char parent;
unsigned char flags;
};
#define HWBLK(_mstp, _bit, _area) \
{ \
.mstp = (void __iomem *)_mstp, \
.bit = _bit, \
.area = _area, \
}
struct hwblk {
void __iomem *mstp;
unsigned char bit;
unsigned char area;
int cnt[HWBLK_CNT_NR];
};
struct hwblk_info {
struct hwblk_area *areas;
int nr_areas;
struct hwblk *hwblks;
int nr_hwblks;
};
/* Should be defined by processor-specific code */
int arch_hwblk_init(void);
int arch_hwblk_sleep_mode(void);
int hwblk_register(struct hwblk_info *info);
int hwblk_init(void);
void hwblk_enable(struct hwblk_info *info, int hwblk);
void hwblk_disable(struct hwblk_info *info, int hwblk);
void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int cnt);
void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int cnt);
/* allow clocks to enable and disable hardware blocks */
#define SH_HWBLK_CLK(_name, _id, _parent, _hwblk, _flags) \
{ \
.name = _name, \
.id = _id, \
.parent = _parent, \
.arch_flags = _hwblk, \
.flags = _flags, \
}
int sh_hwblk_clk_register(struct clk *clks, int nr);
#endif /* __ASM_SH_HWBLK_H */

View File

@ -0,0 +1,6 @@
#ifndef __ASM_SH_LMB_H
#define __ASM_SH_LMB_H
#define LMB_REAL_LIMIT 0
#endif /* __ASM_SH_LMB_H */

View File

@ -20,7 +20,7 @@
* - Bit 9 is reserved by everyone and used by _PAGE_PROTNONE.
*
* - Bits 10 and 11 are low bits of the PPN that are reserved on >= 4K pages.
* Bit 10 is used for _PAGE_ACCESSED, bit 11 remains unused.
* Bit 10 is used for _PAGE_ACCESSED, and bit 11 is used for _PAGE_SPECIAL.
*
* - On 29 bit platforms, bits 31 to 29 are used for the space attributes
* and timing control which (together with bit 0) are moved into the
@ -52,6 +52,7 @@
#define _PAGE_PROTNONE 0x200 /* software: if not present */
#define _PAGE_ACCESSED 0x400 /* software: page referenced */
#define _PAGE_FILE _PAGE_WT /* software: pagecache or swap? */
#define _PAGE_SPECIAL 0x800 /* software: special page */
#define _PAGE_SZ_MASK (_PAGE_SZ0 | _PAGE_SZ1)
#define _PAGE_PR_MASK (_PAGE_RW | _PAGE_USER)
@ -148,8 +149,12 @@
# define _PAGE_SZHUGE (_PAGE_FLAGS_HARD)
#endif
/*
* Mask of bits that are to be preserved accross pgprot changes.
*/
#define _PAGE_CHG_MASK \
(PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | _PAGE_DIRTY)
(PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | \
_PAGE_DIRTY | _PAGE_SPECIAL)
#ifndef __ASSEMBLY__
@ -328,7 +333,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
#define pte_dirty(pte) ((pte).pte_low & _PAGE_DIRTY)
#define pte_young(pte) ((pte).pte_low & _PAGE_ACCESSED)
#define pte_file(pte) ((pte).pte_low & _PAGE_FILE)
#define pte_special(pte) (0)
#define pte_special(pte) ((pte).pte_low & _PAGE_SPECIAL)
#ifdef CONFIG_X2TLB
#define pte_write(pte) ((pte).pte_high & _PAGE_EXT_USER_WRITE)
@ -358,8 +363,9 @@ PTE_BIT_FUNC(low, mkclean, &= ~_PAGE_DIRTY);
PTE_BIT_FUNC(low, mkdirty, |= _PAGE_DIRTY);
PTE_BIT_FUNC(low, mkold, &= ~_PAGE_ACCESSED);
PTE_BIT_FUNC(low, mkyoung, |= _PAGE_ACCESSED);
PTE_BIT_FUNC(low, mkspecial, |= _PAGE_SPECIAL);
static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
#define __HAVE_ARCH_PTE_SPECIAL
/*
* Macro and implementation to make a page protection as uncachable.

View File

@ -7,6 +7,7 @@ extern void __nosave_begin, __nosave_end;
extern long __machvec_start, __machvec_end;
extern char __uncached_start, __uncached_end;
extern char _ebss[];
extern char __start_eh_frame[], __stop_eh_frame[];
#endif /* __ASM_SH_SECTIONS_H */

View File

@ -0,0 +1,25 @@
/*
* Copyright (C) 2009 Matt Fleming
*
* Based on:
* The x86 implementation - arch/x86/include/asm/stacktrace.h
*/
#ifndef _ASM_SH_STACKTRACE_H
#define _ASM_SH_STACKTRACE_H
/* Generic stack tracer with callbacks */
struct stacktrace_ops {
void (*warning)(void *data, char *msg);
/* msg must contain %s for the symbol */
void (*warning_symbol)(void *data, char *msg, unsigned long symbol);
void (*address)(void *data, unsigned long address, int reliable);
/* On negative return stop dumping */
int (*stack)(void *data, char *name);
};
void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
unsigned long *stack,
const struct stacktrace_ops *ops, void *data);
#endif /* _ASM_SH_STACKTRACE_H */

View File

@ -10,6 +10,15 @@ struct swsusp_arch_regs {
struct pt_regs user_regs;
unsigned long bank1_regs[8];
};
void sh_mobile_call_standby(unsigned long mode);
#ifdef CONFIG_CPU_IDLE
void sh_mobile_setup_cpuidle(void);
#else
static inline void sh_mobile_setup_cpuidle(void) {}
#endif
#endif
/* flags passed to assembly suspend code */

View File

@ -65,6 +65,7 @@ static inline void syscall_get_arguments(struct task_struct *task,
case 3: args[2] = regs->regs[6];
case 2: args[1] = regs->regs[5];
case 1: args[0] = regs->regs[4];
case 0:
break;
default:
BUG();

View File

@ -116,6 +116,7 @@ extern void free_thread_info(struct thread_info *ti);
#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
#define TIF_SECCOMP 6 /* secure computing */
#define TIF_NOTIFY_RESUME 7 /* callback before returning to user */
#define TIF_SYSCALL_FTRACE 8 /* for ftrace syscall instrumentation */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 18
@ -129,25 +130,27 @@ extern void free_thread_info(struct thread_info *ti);
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SYSCALL_FTRACE (1 << TIF_SYSCALL_FTRACE)
#define _TIF_USEDFPU (1 << TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_FREEZE (1 << TIF_FREEZE)
/*
* _TIF_ALLWORK_MASK and _TIF_WORK_MASK need to fit within a byte, or we
* _TIF_ALLWORK_MASK and _TIF_WORK_MASK need to fit within 2 bytes, or we
* blow the tst immediate size constraints and need to fix up
* arch/sh/kernel/entry-common.S.
*/
/* work to do in syscall trace */
#define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
_TIF_SYSCALL_AUDIT | _TIF_SECCOMP)
_TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
_TIF_SYSCALL_FTRACE)
/* work to do on any return to u-space */
#define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \
_TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \
_TIF_SINGLESTEP | _TIF_RESTORE_SIGMASK | \
_TIF_NOTIFY_RESUME)
_TIF_NOTIFY_RESUME | _TIF_SYSCALL_FTRACE)
/* work to do on interrupt/exception return */
#define _TIF_WORK_MASK (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \

View File

@ -0,0 +1,25 @@
#ifndef _LINUX_UNWINDER_H
#define _LINUX_UNWINDER_H
#include <asm/stacktrace.h>
struct unwinder {
const char *name;
struct list_head list;
int rating;
void (*dump)(struct task_struct *, struct pt_regs *,
unsigned long *, const struct stacktrace_ops *, void *);
};
extern int unwinder_init(void);
extern int unwinder_register(struct unwinder *);
extern void unwind_stack(struct task_struct *, struct pt_regs *,
unsigned long *, const struct stacktrace_ops *,
void *);
extern void stack_reader_dump(struct task_struct *, struct pt_regs *,
unsigned long *, const struct stacktrace_ops *,
void *);
#endif /* _LINUX_UNWINDER_H */

View File

@ -0,0 +1,17 @@
#ifndef __ASM_SH_VMLINUX_LDS_H
#define __ASM_SH_VMLINUX_LDS_H
#include <asm-generic/vmlinux.lds.h>
#ifdef CONFIG_DWARF_UNWINDER
#define DWARF_EH_FRAME \
.eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start_eh_frame) = .; \
*(.eh_frame) \
VMLINUX_SYMBOL(__stop_eh_frame) = .; \
}
#else
#define DWARF_EH_FRAME
#endif
#endif /* __ASM_SH_VMLINUX_LDS_H */

View File

@ -16,7 +16,8 @@
#define DMAE0_IRQ 38
#define SH_DMAC_BASE0 0xFF608020
#define SH_DMARS_BASE 0xFF609000
#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
#elif defined(CONFIG_CPU_SUBTYPE_SH7723) || \
defined(CONFIG_CPU_SUBTYPE_SH7724)
#define DMTE0_IRQ 48 /* DMAC0A*/
#define DMTE4_IRQ 40 /* DMAC0B */
#define DMTE6_IRQ 42

View File

@ -221,4 +221,18 @@ enum {
GPIO_FN_KEYOUT3, GPIO_FN_KEYOUT4_IN6, GPIO_FN_KEYOUT5_IN5,
};
enum {
HWBLK_UNKNOWN = 0,
HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_URAM, HWBLK_XYMEM,
HWBLK_INTC, HWBLK_DMAC, HWBLK_SHYWAY, HWBLK_HUDI,
HWBLK_UBC, HWBLK_TMU, HWBLK_CMT, HWBLK_RWDT, HWBLK_FLCTL,
HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SIO,
HWBLK_SIOF0, HWBLK_SIOF1, HWBLK_IIC, HWBLK_RTC,
HWBLK_TPU, HWBLK_IRDA, HWBLK_SDHI, HWBLK_SIM, HWBLK_KEYSC,
HWBLK_TSIF, HWBLK_USBF, HWBLK_2DG, HWBLK_SIU, HWBLK_VOU,
HWBLK_JPU, HWBLK_BEU, HWBLK_CEU, HWBLK_VEU, HWBLK_VPU,
HWBLK_LCDC,
HWBLK_NR,
};
#endif /* __ASM_SH7722_H__ */

View File

@ -265,4 +265,21 @@ enum {
GPIO_FN_IDEA1, GPIO_FN_IDEA0,
};
enum {
HWBLK_UNKNOWN = 0,
HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_L2C, HWBLK_ILMEM, HWBLK_FPU,
HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY,
HWBLK_HUDI, HWBLK_DBG, HWBLK_UBC, HWBLK_SUBC,
HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1,
HWBLK_FLCTL,
HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2,
HWBLK_SCIF3, HWBLK_SCIF4, HWBLK_SCIF5,
HWBLK_MSIOF0, HWBLK_MSIOF1, HWBLK_MERAM, HWBLK_IIC, HWBLK_RTC,
HWBLK_ATAPI, HWBLK_ADC, HWBLK_TPU, HWBLK_IRDA, HWBLK_TSIF, HWBLK_ICB,
HWBLK_SDHI0, HWBLK_SDHI1, HWBLK_KEYSC, HWBLK_USB,
HWBLK_2DG, HWBLK_SIU, HWBLK_VEU2H1, HWBLK_VOU, HWBLK_BEU, HWBLK_CEU,
HWBLK_VEU2H0, HWBLK_VPU, HWBLK_LCDC,
HWBLK_NR,
};
#endif /* __ASM_SH7723_H__ */

View File

@ -266,4 +266,21 @@ enum {
GPIO_FN_INTC_IRQ1, GPIO_FN_INTC_IRQ0,
};
enum {
HWBLK_UNKNOWN = 0,
HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_RSMEM, HWBLK_ILMEM, HWBLK_L2C,
HWBLK_FPU, HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY,
HWBLK_HUDI, HWBLK_DBG, HWBLK_UBC,
HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1,
HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SCIF3,
HWBLK_SCIF4, HWBLK_SCIF5, HWBLK_MSIOF0, HWBLK_MSIOF1,
HWBLK_KEYSC, HWBLK_RTC, HWBLK_IIC0, HWBLK_IIC1,
HWBLK_MMC, HWBLK_ETHER, HWBLK_ATAPI, HWBLK_TPU, HWBLK_IRDA,
HWBLK_TSIF, HWBLK_USB1, HWBLK_USB0, HWBLK_2DG,
HWBLK_SDHI0, HWBLK_SDHI1, HWBLK_VEU1, HWBLK_CEU1, HWBLK_BEU1,
HWBLK_2DDMAC, HWBLK_SPU, HWBLK_JPU, HWBLK_VOU,
HWBLK_BEU0, HWBLK_CEU0, HWBLK_VEU0, HWBLK_VPU, HWBLK_LCDC,
HWBLK_NR,
};
#endif /* __ASM_SH7724_H__ */

View File

@ -1,64 +0,0 @@
#ifndef __ASM_SH_MIGOR_H
#define __ASM_SH_MIGOR_H
/*
* linux/include/asm-sh/migor.h
*
* Copyright (C) 2008 Renesas Solutions
*
* Portions Copyright (C) 2007 Nobuhiro Iwamatsu
*
* 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 <asm/addrspace.h>
/* GPIO */
#define PORT_PACR 0xa4050100
#define PORT_PDCR 0xa4050106
#define PORT_PECR 0xa4050108
#define PORT_PHCR 0xa405010e
#define PORT_PJCR 0xa4050110
#define PORT_PKCR 0xa4050112
#define PORT_PLCR 0xa4050114
#define PORT_PMCR 0xa4050116
#define PORT_PRCR 0xa405011c
#define PORT_PTCR 0xa4050140
#define PORT_PUCR 0xa4050142
#define PORT_PVCR 0xa4050144
#define PORT_PWCR 0xa4050146
#define PORT_PXCR 0xa4050148
#define PORT_PYCR 0xa405014a
#define PORT_PZCR 0xa405014c
#define PORT_PADR 0xa4050120
#define PORT_PHDR 0xa405012e
#define PORT_PTDR 0xa4050160
#define PORT_PWDR 0xa4050166
#define PORT_HIZCRA 0xa4050158
#define PORT_HIZCRC 0xa405015c
#define PORT_MSELCRB 0xa4050182
#define PORT_PSELA 0xa405014e
#define PORT_PSELB 0xa4050150
#define PORT_PSELC 0xa4050152
#define PORT_PSELD 0xa4050154
#define PORT_PSELE 0xa4050156
#define PORT_HIZCRA 0xa4050158
#define PORT_HIZCRB 0xa405015a
#define PORT_HIZCRC 0xa405015c
#define BSC_CS4BCR 0xfec10010
#define BSC_CS6ABCR 0xfec1001c
#define BSC_CS4WCR 0xfec10030
#include <video/sh_mobile_lcdc.h>
int migor_lcd_qvga_setup(void *board_data, void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
#endif /* __ASM_SH_MIGOR_H */

View File

@ -0,0 +1 @@
/* do nothing here by default */

View File

@ -0,0 +1,21 @@
#ifndef __ASM_SH_KFR2R09_H
#define __ASM_SH_KFR2R09_H
#include <video/sh_mobile_lcdc.h>
#ifdef CONFIG_FB_SH_MOBILE_LCDC
void kfr2r09_lcd_on(void *board_data);
void kfr2r09_lcd_off(void *board_data);
int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
#else
static inline void kfr2r09_lcd_on(void *board_data) {}
static inline void kfr2r09_lcd_off(void *board_data) {}
static inline int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops)
{
return -ENODEV;
}
#endif
#endif /* __ASM_SH_KFR2R09_H */

View File

@ -0,0 +1,134 @@
LIST "partner-jet-setup.txt - 20090729 Magnus Damm"
LIST "set up enough of the kfr2r09 hardware to boot the kernel"
LIST "zImage (RAM boot)"
LIST "This script can be used to boot the kernel from RAM via JTAG:"
LIST "> < partner-jet-setup.txt"
LIST "> RD zImage, 0xa8800000"
LIST "> G=0xa8800000"
LIST "romImage (Flash boot)"
LIST "Use the following command to burn the zImage to flash via JTAG:"
LIST "> RD romImage, 0"
LIST "--------------------------------"
LIST "disable watchdog"
EW 0xa4520004, 0xa507
LIST "select mode for cs5 + cs6"
ED 0xff800020, 0xa5a50001
ED 0xfec10000, 0x0000001b
LIST "setup clocks"
ED 0xa4150004, 0x00000050
ED 0xa4150000, 0x91053508
WAIT 1
ED 0xa4150024, 0x00005000
LIST "setup pins"
EB 0xa4050120, 0x00
EB 0xa4050122, 0x00
EB 0xa4050124, 0x00
EB 0xa4050126, 0x00
EB 0xa4050128, 0xA0
EB 0xa405012A, 0x10
EB 0xa405012C, 0x00
EB 0xa405012E, 0x00
EB 0xa4050130, 0x00
EB 0xa4050132, 0x00
EB 0xa4050134, 0x01
EB 0xa4050136, 0x40
EB 0xa4050138, 0x00
EB 0xa405013A, 0x00
EB 0xa405013C, 0x00
EB 0xa405013E, 0x20
EB 0xa4050160, 0x00
EB 0xa4050162, 0x40
EB 0xa4050164, 0x03
EB 0xa4050166, 0x00
EB 0xa4050168, 0x00
EB 0xa405016A, 0x00
EB 0xa405016C, 0x00
EW 0xa405014E, 0x5660
EW 0xa4050150, 0x0145
EW 0xa4050152, 0x1550
EW 0xa4050154, 0x0200
EW 0xa4050156, 0x0040
EW 0xa4050158, 0x0000
EW 0xa405015a, 0x0000
EW 0xa405015c, 0x0000
EW 0xa405015e, 0x0000
EW 0xa4050180, 0x0000
EW 0xa4050182, 0x8002
EW 0xa4050184, 0x0000
EW 0xa405018a, 0x9991
EW 0xa405018c, 0x8011
EW 0xa405018e, 0x9550
EW 0xa4050100, 0x0000
EW 0xa4050102, 0x5540
EW 0xa4050104, 0x0000
EW 0xa4050106, 0x0000
EW 0xa4050108, 0x4550
EW 0xa405010a, 0x0130
EW 0xa405010c, 0x0555
EW 0xa405010e, 0x0000
EW 0xa4050110, 0x0000
EW 0xa4050112, 0xAAA8
EW 0xa4050114, 0x8305
EW 0xa4050116, 0x10F0
EW 0xa4050118, 0x0F50
EW 0xa405011a, 0x0000
EW 0xa405011c, 0x0000
EW 0xa405011e, 0x0555
EW 0xa4050140, 0x0000
EW 0xa4050142, 0x5141
EW 0xa4050144, 0x5005
EW 0xa4050146, 0xAAA9
EW 0xa4050148, 0xFAA9
EW 0xa405014a, 0x3000
EW 0xa405014c, 0x0000
LIST "setup sdram"
ED 0xFD000108, 0x40000301
ED 0xFD000020, 0x011B0002
ED 0xFD000030, 0x03060E02
ED 0xFD000034, 0x01020102
ED 0xFD000038, 0x01090406
ED 0xFD000008, 0x00000004
ED 0xFD000040, 0x00000001
ED 0xFD000040, 0x00000000
ED 0xFD000018, 0x00000001
WAIT 1
ED 0xFD000014, 0x00000002
ED 0xFD000060, 0x00000032
ED 0xFD000060, 0x00020000
ED 0xFD000014, 0x00000004
ED 0xFD000014, 0x00000004
ED 0xFD000010, 0x00000001
ED 0xFD000044, 0x000004AF
ED 0xFD000048, 0x20CF0037
LIST "read 16 bytes from sdram"
DD 0xa8000000, 0xa8000000, 1
DD 0xa8000004, 0xa8000004, 1
DD 0xa8000008, 0xa8000008, 1
DD 0xa800000c, 0xa800000c, 1
ED 0xFD000014, 0x00000002
ED 0xFD000014, 0x00000004
ED 0xFD000108, 0x40000300
ED 0xFD000040, 0x00010000
LIST "write to internal ram"
ED 0xfd8007fc, 0
LIST "setup cache"
ED 0xff00001c, 0x0000090b

View File

@ -0,0 +1,75 @@
/* kfr2r09 board specific boot code:
* converts the "partner-jet-script.txt" script into assembly
* the assembly code is the first code to be executed in the romImage
*/
/* The LIST command is used to include comments in the script */
.macro LIST comment
.endm
/* The ED command is used to write a 32-bit word */
.macro ED, addr, data
mov.l 1f ,r1
mov.l 2f ,r0
mov.l r0, @r1
bra 3f
nop
.align 2
1: .long \addr
2: .long \data
3:
.endm
/* The EW command is used to write a 16-bit word */
.macro EW, addr, data
mov.l 1f ,r1
mov.l 2f ,r0
mov.w r0, @r1
bra 3f
nop
.align 2
1: .long \addr
2: .long \data
3:
.endm
/* The EB command is used to write an 8-bit word */
.macro EB, addr, data
mov.l 1f ,r1
mov.l 2f ,r0
mov.b r0, @r1
bra 3f
nop
.align 2
1: .long \addr
2: .long \data
3:
.endm
/* The WAIT command is used to delay the execution */
.macro WAIT, time
mov.l 2f ,r3
1:
nop
tst r3, r3
bf/s 1b
dt r3
bra 3f
nop
.align 2
2: .long \time * 100
3:
.endm
/* The DD command is used to read a 32-bit word */
.macro DD, addr, addr2, nr
mov.l 1f ,r1
mov.l @r1, r0
bra 2f
nop
.align 2
1: .long \addr
2:
.endm
#include "partner-jet-setup.txt"

View File

@ -0,0 +1,14 @@
#ifndef __ASM_SH_MIGOR_H
#define __ASM_SH_MIGOR_H
#define PORT_MSELCRB 0xa4050182
#define BSC_CS4BCR 0xfec10010
#define BSC_CS6ABCR 0xfec1001c
#define BSC_CS4WCR 0xfec10030
#include <video/sh_mobile_lcdc.h>
int migor_lcd_qvga_setup(void *board_data, void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
#endif /* __ASM_SH_MIGOR_H */

View File

@ -9,10 +9,10 @@ ifdef CONFIG_FUNCTION_TRACER
CFLAGS_REMOVE_ftrace.o = -pg
endif
obj-y := debugtraps.o idle.o io.o io_generic.o irq.o \
obj-y := debugtraps.o dumpstack.o idle.o io.o io_generic.o irq.o \
machvec.o process_32.o ptrace_32.o setup.o signal_32.o \
sys_sh.o sys_sh32.o syscalls_32.o time.o topology.o \
traps.o traps_32.o
traps.o traps_32.o unwinder.o
obj-y += cpu/
obj-$(CONFIG_VSYSCALL) += vsyscall/
@ -29,8 +29,11 @@ obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_GENERIC_GPIO) += gpio.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
obj-$(CONFIG_DUMP_CODE) += disassemble.o
obj-$(CONFIG_HIBERNATION) += swsusp.o
obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o

View File

@ -2,7 +2,7 @@ extra-y := head_64.o init_task.o vmlinux.lds
obj-y := debugtraps.o idle.o io.o io_generic.o irq.o machvec.o process_64.o \
ptrace_64.o setup.o signal_64.o sys_sh.o sys_sh64.o \
syscalls_64.o time.o topology.o traps.o traps_64.o
syscalls_64.o time.o topology.o traps.o traps_64.o unwinder.o
obj-y += cpu/
obj-$(CONFIG_SMP) += smp.o
@ -13,6 +13,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
obj-$(CONFIG_GENERIC_GPIO) += gpio.o
obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o

View File

@ -26,6 +26,7 @@ int main(void)
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
DEFINE(TI_RESTART_BLOCK,offsetof(struct thread_info, restart_block));
DEFINE(TI_SIZE, sizeof(struct thread_info));
#ifdef CONFIG_HIBERNATION
DEFINE(PBE_ADDRESS, offsetof(struct pbe, address));

View File

@ -19,4 +19,4 @@ obj-$(CONFIG_UBC_WAKEUP) += ubc.o
obj-$(CONFIG_SH_ADC) += adc.o
obj-$(CONFIG_SH_CLK_CPG) += clock-cpg.o
obj-y += irq/ init.o clock.o
obj-y += irq/ init.o clock.o hwblk.o

155
arch/sh/kernel/cpu/hwblk.c Normal file
View File

@ -0,0 +1,155 @@
#include <linux/clk.h>
#include <linux/compiler.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <asm/suspend.h>
#include <asm/hwblk.h>
#include <asm/clock.h>
static DEFINE_SPINLOCK(hwblk_lock);
static void hwblk_area_mod_cnt(struct hwblk_info *info,
int area, int counter, int value, int goal)
{
struct hwblk_area *hap = info->areas + area;
hap->cnt[counter] += value;
if (hap->cnt[counter] != goal)
return;
if (hap->flags & HWBLK_AREA_FLAG_PARENT)
hwblk_area_mod_cnt(info, hap->parent, counter, value, goal);
}
static int __hwblk_mod_cnt(struct hwblk_info *info, int hwblk,
int counter, int value, int goal)
{
struct hwblk *hp = info->hwblks + hwblk;
hp->cnt[counter] += value;
if (hp->cnt[counter] == goal)
hwblk_area_mod_cnt(info, hp->area, counter, value, goal);
return hp->cnt[counter];
}
static void hwblk_mod_cnt(struct hwblk_info *info, int hwblk,
int counter, int value, int goal)
{
unsigned long flags;
spin_lock_irqsave(&hwblk_lock, flags);
__hwblk_mod_cnt(info, hwblk, counter, value, goal);
spin_unlock_irqrestore(&hwblk_lock, flags);
}
void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int counter)
{
hwblk_mod_cnt(info, hwblk, counter, 1, 1);
}
void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int counter)
{
hwblk_mod_cnt(info, hwblk, counter, -1, 0);
}
void hwblk_enable(struct hwblk_info *info, int hwblk)
{
struct hwblk *hp = info->hwblks + hwblk;
unsigned long tmp;
unsigned long flags;
int ret;
spin_lock_irqsave(&hwblk_lock, flags);
ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, 1, 1);
if (ret == 1) {
tmp = __raw_readl(hp->mstp);
tmp &= ~(1 << hp->bit);
__raw_writel(tmp, hp->mstp);
}
spin_unlock_irqrestore(&hwblk_lock, flags);
}
void hwblk_disable(struct hwblk_info *info, int hwblk)
{
struct hwblk *hp = info->hwblks + hwblk;
unsigned long tmp;
unsigned long flags;
int ret;
spin_lock_irqsave(&hwblk_lock, flags);
ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, -1, 0);
if (ret == 0) {
tmp = __raw_readl(hp->mstp);
tmp |= 1 << hp->bit;
__raw_writel(tmp, hp->mstp);
}
spin_unlock_irqrestore(&hwblk_lock, flags);
}
struct hwblk_info *hwblk_info;
int __init hwblk_register(struct hwblk_info *info)
{
hwblk_info = info;
return 0;
}
int __init __weak arch_hwblk_init(void)
{
return 0;
}
int __weak arch_hwblk_sleep_mode(void)
{
return SUSP_SH_SLEEP;
}
int __init hwblk_init(void)
{
return arch_hwblk_init();
}
/* allow clocks to enable and disable hardware blocks */
static int sh_hwblk_clk_enable(struct clk *clk)
{
if (!hwblk_info)
return -ENOENT;
hwblk_enable(hwblk_info, clk->arch_flags);
return 0;
}
static void sh_hwblk_clk_disable(struct clk *clk)
{
if (hwblk_info)
hwblk_disable(hwblk_info, clk->arch_flags);
}
static struct clk_ops sh_hwblk_clk_ops = {
.enable = sh_hwblk_clk_enable,
.disable = sh_hwblk_clk_disable,
.recalc = followparent_recalc,
};
int __init sh_hwblk_clk_register(struct clk *clks, int nr)
{
struct clk *clkp;
int ret = 0;
int k;
for (k = 0; !ret && (k < nr); k++) {
clkp = clks + k;
clkp->ops = &sh_hwblk_clk_ops;
ret |= clk_register(clkp);
}
return ret;
}

View File

@ -3,7 +3,7 @@
*
* CPU init code
*
* Copyright (C) 2002 - 2007 Paul Mundt
* Copyright (C) 2002 - 2009 Paul Mundt
* Copyright (C) 2003 Richard Curnow
*
* This file is subject to the terms and conditions of the GNU General Public
@ -62,6 +62,37 @@ static void __init speculative_execution_init(void)
#define speculative_execution_init() do { } while (0)
#endif
#ifdef CONFIG_CPU_SH4A
#define EXPMASK 0xff2f0004
#define EXPMASK_RTEDS (1 << 0)
#define EXPMASK_BRDSSLP (1 << 1)
#define EXPMASK_MMCAW (1 << 4)
static void __init expmask_init(void)
{
unsigned long expmask = __raw_readl(EXPMASK);
/*
* Future proofing.
*
* Disable support for slottable sleep instruction
* and non-nop instructions in the rte delay slot.
*/
expmask &= ~(EXPMASK_RTEDS | EXPMASK_BRDSSLP);
/*
* Enable associative writes to the memory-mapped cache array
* until the cache flush ops have been rewritten.
*/
expmask |= EXPMASK_MMCAW;
__raw_writel(expmask, EXPMASK);
ctrl_barrier();
}
#else
#define expmask_init() do { } while (0)
#endif
/* 2nd-level cache init */
void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void)
{
@ -321,4 +352,5 @@ asmlinkage void __init sh_cpu_init(void)
#endif
speculative_execution_init();
expmask_init();
}

View File

@ -227,8 +227,9 @@ ENTRY(sh_bios_handler)
mov.l @r15+, r14
add #8,r15
lds.l @r15+, pr
rte
mov.l @r15+,r15
rte
nop
.align 2
1: .long gdb_vbr_vector
#endif /* CONFIG_SH_STANDARD_BIOS */

View File

@ -176,8 +176,9 @@ ENTRY(sh_bios_handler)
movml.l @r15+,r14
add #8,r15
lds.l @r15+, pr
rte
mov.l @r15+,r15
rte
nop
.align 2
1: .long gdb_vbr_vector
#endif /* CONFIG_SH_STANDARD_BIOS */

View File

@ -137,6 +137,7 @@ ENTRY(tlb_protection_violation_store)
mov #1, r5
call_dpf:
setup_frame_reg
mov.l 1f, r0
mov r5, r8
mov.l @r0, r6

View File

@ -25,9 +25,9 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
clock-$(CONFIG_CPU_SUBTYPE_SH7786) := clock-sh7786.o
clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o
clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7723.o
clock-$(CONFIG_CPU_SUBTYPE_SH7724) := clock-sh7724.o
clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o hwblk-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7723.o hwblk-sh7723.o
clock-$(CONFIG_CPU_SUBTYPE_SH7724) := clock-sh7724.o hwblk-sh7724.o
clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7366.o
clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o

View File

@ -22,6 +22,8 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/clock.h>
#include <asm/hwblk.h>
#include <cpu/sh7722.h>
/* SH7722 registers */
#define FRQCR 0xa4150000
@ -30,9 +32,6 @@
#define SCLKBCR 0xa415000c
#define IRDACLKCR 0xa4150018
#define PLLCR 0xa4150024
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
#define DLLFRQ 0xa4150050
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
@ -140,35 +139,37 @@ struct clk div6_clks[] = {
SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
};
#define MSTP(_str, _parent, _reg, _bit, _flags) \
SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _flags)
#define R_CLK &r_clk
#define P_CLK &div4_clks[DIV4_P]
#define B_CLK &div4_clks[DIV4_B]
#define U_CLK &div4_clks[DIV4_U]
static struct clk mstp_clks[] = {
MSTP("uram0", &div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
MSTP("xymem0", &div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0),
MSTP("cmt0", &r_clk, MSTPCR0, 14, 0),
MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0),
MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0),
MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 7, 0),
MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 6, 0),
MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 5, 0),
SH_HWBLK_CLK("uram0", -1, U_CLK, HWBLK_URAM, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("xymem0", -1, B_CLK, HWBLK_XYMEM, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU, 0),
SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0),
SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0),
MSTP("rtc0", &r_clk, MSTPCR1, 8, 0),
SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0),
SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
MSTP("sdhi0", &div4_clks[DIV4_P], MSTPCR2, 18, 0),
MSTP("keysc0", &r_clk, MSTPCR2, 14, 0),
MSTP("usbf0", &div4_clks[DIV4_P], MSTPCR2, 11, 0),
MSTP("2dg0", &div4_clks[DIV4_B], MSTPCR2, 9, 0),
MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 8, 0),
MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0),
MSTP("jpu0", &div4_clks[DIV4_B], MSTPCR2, 6, CLK_ENABLE_ON_INIT),
MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0),
MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0),
MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT),
MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT),
MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0),
SH_HWBLK_CLK("sdhi0", -1, P_CLK, HWBLK_SDHI, 0),
SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
SH_HWBLK_CLK("usbf0", -1, P_CLK, HWBLK_USBF, 0),
SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0),
SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0),
SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0),
SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("lcdc0", -1, P_CLK, HWBLK_LCDC, 0),
};
int __init arch_clk_init(void)
@ -191,7 +192,7 @@ int __init arch_clk_init(void)
ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
return ret;
}

View File

@ -22,6 +22,8 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/clock.h>
#include <asm/hwblk.h>
#include <cpu/sh7723.h>
/* SH7723 registers */
#define FRQCR 0xa4150000
@ -30,9 +32,6 @@
#define SCLKBCR 0xa415000c
#define IRDACLKCR 0xa4150018
#define PLLCR 0xa4150024
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
#define DLLFRQ 0xa4150050
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
@ -140,60 +139,64 @@ struct clk div6_clks[] = {
SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
};
#define MSTP(_str, _parent, _reg, _bit, _force_on, _need_cpg, _need_ram) \
SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _force_on * CLK_ENABLE_ON_INIT)
#define R_CLK (&r_clk)
#define P_CLK (&div4_clks[DIV4_P])
#define B_CLK (&div4_clks[DIV4_B])
#define U_CLK (&div4_clks[DIV4_U])
#define I_CLK (&div4_clks[DIV4_I])
#define SH_CLK (&div4_clks[DIV4_SH])
static struct clk mstp_clks[] = {
/* See page 60 of Datasheet V1.0: Overview -> Block Diagram */
MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, 1, 1, 0),
MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, 1, 1, 0),
MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, 1, 1, 0),
MSTP("l2c0", &div4_clks[DIV4_SH], MSTPCR0, 28, 1, 1, 0),
MSTP("ilmem0", &div4_clks[DIV4_I], MSTPCR0, 27, 1, 1, 0),
MSTP("fpu0", &div4_clks[DIV4_I], MSTPCR0, 24, 1, 1, 0),
MSTP("intc0", &div4_clks[DIV4_I], MSTPCR0, 22, 1, 1, 0),
MSTP("dmac0", &div4_clks[DIV4_B], MSTPCR0, 21, 0, 1, 1),
MSTP("sh0", &div4_clks[DIV4_SH], MSTPCR0, 20, 0, 1, 0),
MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0, 1, 0),
MSTP("ubc0", &div4_clks[DIV4_I], MSTPCR0, 17, 0, 1, 0),
MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0, 1, 0),
MSTP("cmt0", &r_clk, MSTPCR0, 14, 0, 0, 0),
MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0, 0, 0),
MSTP("dmac1", &div4_clks[DIV4_B], MSTPCR0, 12, 0, 1, 1),
MSTP("tmu1", &div4_clks[DIV4_P], MSTPCR0, 11, 0, 1, 0),
MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0, 1, 0),
MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 9, 0, 1, 0),
MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 8, 0, 1, 0),
MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 7, 0, 1, 0),
MSTP("scif3", &div4_clks[DIV4_B], MSTPCR0, 6, 0, 1, 0),
MSTP("scif4", &div4_clks[DIV4_B], MSTPCR0, 5, 0, 1, 0),
MSTP("scif5", &div4_clks[DIV4_B], MSTPCR0, 4, 0, 1, 0),
MSTP("msiof0", &div4_clks[DIV4_B], MSTPCR0, 2, 0, 1, 0),
MSTP("msiof1", &div4_clks[DIV4_B], MSTPCR0, 1, 0, 1, 0),
MSTP("meram0", &div4_clks[DIV4_SH], MSTPCR0, 0, 1, 1, 0),
SH_HWBLK_CLK("tlb0", -1, I_CLK, HWBLK_TLB, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("ic0", -1, I_CLK, HWBLK_IC, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("oc0", -1, I_CLK, HWBLK_OC, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("l2c0", -1, SH_CLK, HWBLK_L2C, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("ilmem0", -1, I_CLK, HWBLK_ILMEM, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("fpu0", -1, I_CLK, HWBLK_FPU, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("intc0", -1, I_CLK, HWBLK_INTC, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("dmac0", -1, B_CLK, HWBLK_DMAC0, 0),
SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0),
SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0),
SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU0, 0),
SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0),
SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0),
SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0),
SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
SH_HWBLK_CLK("scif3", -1, B_CLK, HWBLK_SCIF3, 0),
SH_HWBLK_CLK("scif4", -1, B_CLK, HWBLK_SCIF4, 0),
SH_HWBLK_CLK("scif5", -1, B_CLK, HWBLK_SCIF5, 0),
SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0),
SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0),
SH_HWBLK_CLK("meram0", -1, SH_CLK, HWBLK_MERAM, 0),
MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0, 1, 0),
MSTP("rtc0", &r_clk, MSTPCR1, 8, 0, 0, 0),
SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0),
SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
MSTP("atapi0", &div4_clks[DIV4_SH], MSTPCR2, 28, 0, 1, 0),
MSTP("adc0", &div4_clks[DIV4_P], MSTPCR2, 27, 0, 1, 0),
MSTP("tpu0", &div4_clks[DIV4_B], MSTPCR2, 25, 0, 1, 0),
MSTP("irda0", &div4_clks[DIV4_P], MSTPCR2, 24, 0, 1, 0),
MSTP("tsif0", &div4_clks[DIV4_B], MSTPCR2, 22, 0, 1, 0),
MSTP("icb0", &div4_clks[DIV4_B], MSTPCR2, 21, 0, 1, 1),
MSTP("sdhi0", &div4_clks[DIV4_B], MSTPCR2, 18, 0, 1, 0),
MSTP("sdhi1", &div4_clks[DIV4_B], MSTPCR2, 17, 0, 1, 0),
MSTP("keysc0", &r_clk, MSTPCR2, 14, 0, 0, 0),
MSTP("usb0", &div4_clks[DIV4_B], MSTPCR2, 11, 0, 1, 0),
MSTP("2dg0", &div4_clks[DIV4_B], MSTPCR2, 10, 0, 1, 1),
MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 8, 0, 1, 0),
MSTP("veu1", &div4_clks[DIV4_B], MSTPCR2, 6, 1, 1, 1),
MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0, 1, 1),
MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0, 1, 1),
MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0, 1, 1),
MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, 1, 1, 1),
MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, 1, 1, 1),
MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0, 1, 1),
SH_HWBLK_CLK("atapi0", -1, SH_CLK, HWBLK_ATAPI, 0),
SH_HWBLK_CLK("adc0", -1, P_CLK, HWBLK_ADC, 0),
SH_HWBLK_CLK("tpu0", -1, B_CLK, HWBLK_TPU, 0),
SH_HWBLK_CLK("irda0", -1, P_CLK, HWBLK_IRDA, 0),
SH_HWBLK_CLK("tsif0", -1, B_CLK, HWBLK_TSIF, 0),
SH_HWBLK_CLK("icb0", -1, B_CLK, HWBLK_ICB, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("sdhi0", -1, B_CLK, HWBLK_SDHI0, 0),
SH_HWBLK_CLK("sdhi1", -1, B_CLK, HWBLK_SDHI1, 0),
SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
SH_HWBLK_CLK("usb0", -1, B_CLK, HWBLK_USB, 0),
SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0),
SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU2H1, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0),
SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0),
SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU2H0, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0),
};
int __init arch_clk_init(void)
@ -216,7 +219,7 @@ int __init arch_clk_init(void)
ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
return ret;
}

View File

@ -22,6 +22,8 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/clock.h>
#include <asm/hwblk.h>
#include <cpu/sh7724.h>
/* SH7724 registers */
#define FRQCRA 0xa4150000
@ -31,9 +33,6 @@
#define FCLKBCR 0xa415000c
#define IRDACLKCR 0xa4150018
#define PLLCR 0xa4150024
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
#define SPUCLKCR 0xa415003c
#define FLLFRQ 0xa4150050
#define LSTATS 0xa4150060
@ -156,64 +155,67 @@ struct clk div6_clks[] = {
SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, 0),
};
#define MSTP(_str, _parent, _reg, _bit, _force_on, _need_cpg, _need_ram) \
SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _force_on * CLK_ENABLE_ON_INIT)
#define R_CLK (&r_clk)
#define P_CLK (&div4_clks[DIV4_P])
#define B_CLK (&div4_clks[DIV4_B])
#define I_CLK (&div4_clks[DIV4_I])
#define SH_CLK (&div4_clks[DIV4_SH])
static struct clk mstp_clks[] = {
MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, 1, 1, 0),
MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, 1, 1, 0),
MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, 1, 1, 0),
MSTP("rs0", &div4_clks[DIV4_B], MSTPCR0, 28, 1, 1, 0),
MSTP("ilmem0", &div4_clks[DIV4_I], MSTPCR0, 27, 1, 1, 0),
MSTP("l2c0", &div4_clks[DIV4_SH], MSTPCR0, 26, 1, 1, 0),
MSTP("fpu0", &div4_clks[DIV4_I], MSTPCR0, 24, 1, 1, 0),
MSTP("intc0", &div4_clks[DIV4_P], MSTPCR0, 22, 1, 1, 0),
MSTP("dmac0", &div4_clks[DIV4_B], MSTPCR0, 21, 0, 1, 1),
MSTP("sh0", &div4_clks[DIV4_SH], MSTPCR0, 20, 0, 1, 0),
MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0, 1, 0),
MSTP("ubc0", &div4_clks[DIV4_I], MSTPCR0, 17, 0, 1, 0),
MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0, 1, 0),
MSTP("cmt0", &r_clk, MSTPCR0, 14, 0, 0, 0),
MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0, 0, 0),
MSTP("dmac1", &div4_clks[DIV4_B], MSTPCR0, 12, 0, 1, 1),
MSTP("tmu1", &div4_clks[DIV4_P], MSTPCR0, 10, 0, 1, 0),
MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 9, 0, 1, 0),
MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 8, 0, 1, 0),
MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 7, 0, 1, 0),
MSTP("scif3", &div4_clks[DIV4_B], MSTPCR0, 6, 0, 1, 0),
MSTP("scif4", &div4_clks[DIV4_B], MSTPCR0, 5, 0, 1, 0),
MSTP("scif5", &div4_clks[DIV4_B], MSTPCR0, 4, 0, 1, 0),
MSTP("msiof0", &div4_clks[DIV4_B], MSTPCR0, 2, 0, 1, 0),
MSTP("msiof1", &div4_clks[DIV4_B], MSTPCR0, 1, 0, 1, 0),
SH_HWBLK_CLK("tlb0", -1, I_CLK, HWBLK_TLB, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("ic0", -1, I_CLK, HWBLK_IC, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("oc0", -1, I_CLK, HWBLK_OC, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("rs0", -1, B_CLK, HWBLK_RSMEM, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("ilmem0", -1, I_CLK, HWBLK_ILMEM, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("l2c0", -1, SH_CLK, HWBLK_L2C, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("fpu0", -1, I_CLK, HWBLK_FPU, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("intc0", -1, P_CLK, HWBLK_INTC, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("dmac0", -1, B_CLK, HWBLK_DMAC0, 0),
SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0),
SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0),
SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU0, 0),
SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0),
SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0),
SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
SH_HWBLK_CLK("scif3", -1, B_CLK, HWBLK_SCIF3, 0),
SH_HWBLK_CLK("scif4", -1, B_CLK, HWBLK_SCIF4, 0),
SH_HWBLK_CLK("scif5", -1, B_CLK, HWBLK_SCIF5, 0),
SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0),
SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0),
MSTP("keysc0", &r_clk, MSTPCR1, 12, 0, 0, 0),
MSTP("rtc0", &r_clk, MSTPCR1, 11, 0, 0, 0),
MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0, 1, 0),
MSTP("i2c1", &div4_clks[DIV4_P], MSTPCR1, 8, 0, 1, 0),
SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC0, 0),
SH_HWBLK_CLK("i2c1", -1, P_CLK, HWBLK_IIC1, 0),
MSTP("mmc0", &div4_clks[DIV4_B], MSTPCR2, 29, 0, 1, 0),
MSTP("eth0", &div4_clks[DIV4_B], MSTPCR2, 28, 0, 1, 0),
MSTP("atapi0", &div4_clks[DIV4_B], MSTPCR2, 26, 0, 1, 0),
MSTP("tpu0", &div4_clks[DIV4_B], MSTPCR2, 25, 0, 1, 0),
MSTP("irda0", &div4_clks[DIV4_P], MSTPCR2, 24, 0, 1, 0),
MSTP("tsif0", &div4_clks[DIV4_B], MSTPCR2, 22, 0, 1, 0),
MSTP("usb1", &div4_clks[DIV4_B], MSTPCR2, 21, 0, 1, 1),
MSTP("usb0", &div4_clks[DIV4_B], MSTPCR2, 20, 0, 1, 1),
MSTP("2dg0", &div4_clks[DIV4_B], MSTPCR2, 19, 0, 1, 1),
MSTP("sdhi0", &div4_clks[DIV4_B], MSTPCR2, 18, 0, 1, 0),
MSTP("sdhi1", &div4_clks[DIV4_B], MSTPCR2, 17, 0, 1, 0),
MSTP("veu1", &div4_clks[DIV4_B], MSTPCR2, 15, 1, 1, 1),
MSTP("ceu1", &div4_clks[DIV4_B], MSTPCR2, 13, 0, 1, 1),
MSTP("beu1", &div4_clks[DIV4_B], MSTPCR2, 12, 0, 1, 1),
MSTP("2ddmac0", &div4_clks[DIV4_SH], MSTPCR2, 10, 0, 1, 1),
MSTP("spu0", &div4_clks[DIV4_B], MSTPCR2, 9, 0, 1, 0),
MSTP("jpu0", &div4_clks[DIV4_B], MSTPCR2, 6, 1, 1, 1),
MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0, 1, 1),
MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0, 1, 1),
MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0, 1, 1),
MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, 1, 1, 1),
MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, 1, 1, 1),
MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0, 1, 1),
SH_HWBLK_CLK("mmc0", -1, B_CLK, HWBLK_MMC, 0),
SH_HWBLK_CLK("eth0", -1, B_CLK, HWBLK_ETHER, 0),
SH_HWBLK_CLK("atapi0", -1, B_CLK, HWBLK_ATAPI, 0),
SH_HWBLK_CLK("tpu0", -1, B_CLK, HWBLK_TPU, 0),
SH_HWBLK_CLK("irda0", -1, P_CLK, HWBLK_IRDA, 0),
SH_HWBLK_CLK("tsif0", -1, B_CLK, HWBLK_TSIF, 0),
SH_HWBLK_CLK("usb1", -1, B_CLK, HWBLK_USB1, 0),
SH_HWBLK_CLK("usb0", -1, B_CLK, HWBLK_USB0, 0),
SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
SH_HWBLK_CLK("sdhi0", -1, B_CLK, HWBLK_SDHI0, 0),
SH_HWBLK_CLK("sdhi1", -1, B_CLK, HWBLK_SDHI1, 0),
SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU1, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("ceu1", -1, B_CLK, HWBLK_CEU1, 0),
SH_HWBLK_CLK("beu1", -1, B_CLK, HWBLK_BEU1, 0),
SH_HWBLK_CLK("2ddmac0", -1, SH_CLK, HWBLK_2DDMAC, 0),
SH_HWBLK_CLK("spu0", -1, B_CLK, HWBLK_SPU, 0),
SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU0, 0),
SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU0, 0),
SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU0, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0),
};
int __init arch_clk_init(void)
@ -236,7 +238,7 @@ int __init arch_clk_init(void)
ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
return ret;
}

View File

@ -0,0 +1,106 @@
/*
* arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c
*
* SH7722 hardware block support
*
* Copyright (C) 2009 Magnus Damm
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/suspend.h>
#include <asm/hwblk.h>
#include <cpu/sh7722.h>
/* SH7722 registers */
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
/* SH7722 Power Domains */
enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
static struct hwblk_area sh7722_hwblk_area[] = {
[CORE_AREA] = HWBLK_AREA(0, 0),
[CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
[SUB_AREA] = HWBLK_AREA(0, 0),
};
/* Table mapping HWBLK to Module Stop Bit and Power Domain */
static struct hwblk sh7722_hwblk[HWBLK_NR] = {
[HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
[HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
[HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
[HWBLK_URAM] = HWBLK(MSTPCR0, 28, CORE_AREA),
[HWBLK_XYMEM] = HWBLK(MSTPCR0, 26, CORE_AREA),
[HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
[HWBLK_DMAC] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
[HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
[HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
[HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
[HWBLK_TMU] = HWBLK(MSTPCR0, 15, CORE_AREA),
[HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
[HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
[HWBLK_FLCTL] = HWBLK(MSTPCR0, 10, CORE_AREA),
[HWBLK_SCIF0] = HWBLK(MSTPCR0, 7, CORE_AREA),
[HWBLK_SCIF1] = HWBLK(MSTPCR0, 6, CORE_AREA),
[HWBLK_SCIF2] = HWBLK(MSTPCR0, 5, CORE_AREA),
[HWBLK_SIO] = HWBLK(MSTPCR0, 3, CORE_AREA),
[HWBLK_SIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
[HWBLK_SIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
[HWBLK_IIC] = HWBLK(MSTPCR1, 9, CORE_AREA),
[HWBLK_RTC] = HWBLK(MSTPCR1, 8, SUB_AREA),
[HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
[HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
[HWBLK_SDHI] = HWBLK(MSTPCR2, 18, CORE_AREA),
[HWBLK_SIM] = HWBLK(MSTPCR2, 16, CORE_AREA),
[HWBLK_KEYSC] = HWBLK(MSTPCR2, 14, SUB_AREA),
[HWBLK_TSIF] = HWBLK(MSTPCR2, 13, SUB_AREA),
[HWBLK_USBF] = HWBLK(MSTPCR2, 11, CORE_AREA),
[HWBLK_2DG] = HWBLK(MSTPCR2, 9, CORE_AREA_BM),
[HWBLK_SIU] = HWBLK(MSTPCR2, 8, CORE_AREA),
[HWBLK_JPU] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
[HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
[HWBLK_BEU] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
[HWBLK_CEU] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
[HWBLK_VEU] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
[HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
[HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
};
static struct hwblk_info sh7722_hwblk_info = {
.areas = sh7722_hwblk_area,
.nr_areas = ARRAY_SIZE(sh7722_hwblk_area),
.hwblks = sh7722_hwblk,
.nr_hwblks = ARRAY_SIZE(sh7722_hwblk),
};
int arch_hwblk_sleep_mode(void)
{
if (!sh7722_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
return SUSP_SH_STANDBY | SUSP_SH_SF;
if (!sh7722_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
return SUSP_SH_SLEEP | SUSP_SH_SF;
return SUSP_SH_SLEEP;
}
int __init arch_hwblk_init(void)
{
return hwblk_register(&sh7722_hwblk_info);
}

View File

@ -0,0 +1,117 @@
/*
* arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c
*
* SH7723 hardware block support
*
* Copyright (C) 2009 Magnus Damm
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/suspend.h>
#include <asm/hwblk.h>
#include <cpu/sh7723.h>
/* SH7723 registers */
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
/* SH7723 Power Domains */
enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
static struct hwblk_area sh7723_hwblk_area[] = {
[CORE_AREA] = HWBLK_AREA(0, 0),
[CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
[SUB_AREA] = HWBLK_AREA(0, 0),
};
/* Table mapping HWBLK to Module Stop Bit and Power Domain */
static struct hwblk sh7723_hwblk[HWBLK_NR] = {
[HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
[HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
[HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
[HWBLK_L2C] = HWBLK(MSTPCR0, 28, CORE_AREA),
[HWBLK_ILMEM] = HWBLK(MSTPCR0, 27, CORE_AREA),
[HWBLK_FPU] = HWBLK(MSTPCR0, 24, CORE_AREA),
[HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
[HWBLK_DMAC0] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
[HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
[HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
[HWBLK_DBG] = HWBLK(MSTPCR0, 18, CORE_AREA),
[HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
[HWBLK_SUBC] = HWBLK(MSTPCR0, 16, CORE_AREA),
[HWBLK_TMU0] = HWBLK(MSTPCR0, 15, CORE_AREA),
[HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
[HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
[HWBLK_DMAC1] = HWBLK(MSTPCR0, 12, CORE_AREA_BM),
[HWBLK_TMU1] = HWBLK(MSTPCR0, 11, CORE_AREA),
[HWBLK_FLCTL] = HWBLK(MSTPCR0, 10, CORE_AREA),
[HWBLK_SCIF0] = HWBLK(MSTPCR0, 9, CORE_AREA),
[HWBLK_SCIF1] = HWBLK(MSTPCR0, 8, CORE_AREA),
[HWBLK_SCIF2] = HWBLK(MSTPCR0, 7, CORE_AREA),
[HWBLK_SCIF3] = HWBLK(MSTPCR0, 6, CORE_AREA),
[HWBLK_SCIF4] = HWBLK(MSTPCR0, 5, CORE_AREA),
[HWBLK_SCIF5] = HWBLK(MSTPCR0, 4, CORE_AREA),
[HWBLK_MSIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
[HWBLK_MSIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
[HWBLK_MERAM] = HWBLK(MSTPCR0, 0, CORE_AREA),
[HWBLK_IIC] = HWBLK(MSTPCR1, 9, CORE_AREA),
[HWBLK_RTC] = HWBLK(MSTPCR1, 8, SUB_AREA),
[HWBLK_ATAPI] = HWBLK(MSTPCR2, 28, CORE_AREA_BM),
[HWBLK_ADC] = HWBLK(MSTPCR2, 27, CORE_AREA),
[HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
[HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
[HWBLK_TSIF] = HWBLK(MSTPCR2, 22, CORE_AREA),
[HWBLK_ICB] = HWBLK(MSTPCR2, 21, CORE_AREA_BM),
[HWBLK_SDHI0] = HWBLK(MSTPCR2, 18, CORE_AREA),
[HWBLK_SDHI1] = HWBLK(MSTPCR2, 17, CORE_AREA),
[HWBLK_KEYSC] = HWBLK(MSTPCR2, 14, SUB_AREA),
[HWBLK_USB] = HWBLK(MSTPCR2, 11, CORE_AREA),
[HWBLK_2DG] = HWBLK(MSTPCR2, 10, CORE_AREA_BM),
[HWBLK_SIU] = HWBLK(MSTPCR2, 8, CORE_AREA),
[HWBLK_VEU2H1] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
[HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
[HWBLK_BEU] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
[HWBLK_CEU] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
[HWBLK_VEU2H0] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
[HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
[HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
};
static struct hwblk_info sh7723_hwblk_info = {
.areas = sh7723_hwblk_area,
.nr_areas = ARRAY_SIZE(sh7723_hwblk_area),
.hwblks = sh7723_hwblk,
.nr_hwblks = ARRAY_SIZE(sh7723_hwblk),
};
int arch_hwblk_sleep_mode(void)
{
if (!sh7723_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
return SUSP_SH_STANDBY | SUSP_SH_SF;
if (!sh7723_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
return SUSP_SH_SLEEP | SUSP_SH_SF;
return SUSP_SH_SLEEP;
}
int __init arch_hwblk_init(void)
{
return hwblk_register(&sh7723_hwblk_info);
}

View File

@ -0,0 +1,121 @@
/*
* arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c
*
* SH7724 hardware block support
*
* Copyright (C) 2009 Magnus Damm
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/suspend.h>
#include <asm/hwblk.h>
#include <cpu/sh7724.h>
/* SH7724 registers */
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
/* SH7724 Power Domains */
enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
static struct hwblk_area sh7724_hwblk_area[] = {
[CORE_AREA] = HWBLK_AREA(0, 0),
[CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
[SUB_AREA] = HWBLK_AREA(0, 0),
};
/* Table mapping HWBLK to Module Stop Bit and Power Domain */
static struct hwblk sh7724_hwblk[HWBLK_NR] = {
[HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
[HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
[HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
[HWBLK_RSMEM] = HWBLK(MSTPCR0, 28, CORE_AREA),
[HWBLK_ILMEM] = HWBLK(MSTPCR0, 27, CORE_AREA),
[HWBLK_L2C] = HWBLK(MSTPCR0, 26, CORE_AREA),
[HWBLK_FPU] = HWBLK(MSTPCR0, 24, CORE_AREA),
[HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
[HWBLK_DMAC0] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
[HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
[HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
[HWBLK_DBG] = HWBLK(MSTPCR0, 18, CORE_AREA),
[HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
[HWBLK_TMU0] = HWBLK(MSTPCR0, 15, CORE_AREA),
[HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
[HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
[HWBLK_DMAC1] = HWBLK(MSTPCR0, 12, CORE_AREA_BM),
[HWBLK_TMU1] = HWBLK(MSTPCR0, 10, CORE_AREA),
[HWBLK_SCIF0] = HWBLK(MSTPCR0, 9, CORE_AREA),
[HWBLK_SCIF1] = HWBLK(MSTPCR0, 8, CORE_AREA),
[HWBLK_SCIF2] = HWBLK(MSTPCR0, 7, CORE_AREA),
[HWBLK_SCIF3] = HWBLK(MSTPCR0, 6, CORE_AREA),
[HWBLK_SCIF4] = HWBLK(MSTPCR0, 5, CORE_AREA),
[HWBLK_SCIF5] = HWBLK(MSTPCR0, 4, CORE_AREA),
[HWBLK_MSIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
[HWBLK_MSIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
[HWBLK_KEYSC] = HWBLK(MSTPCR1, 12, SUB_AREA),
[HWBLK_RTC] = HWBLK(MSTPCR1, 11, SUB_AREA),
[HWBLK_IIC0] = HWBLK(MSTPCR1, 9, CORE_AREA),
[HWBLK_IIC1] = HWBLK(MSTPCR1, 8, CORE_AREA),
[HWBLK_MMC] = HWBLK(MSTPCR2, 29, CORE_AREA),
[HWBLK_ETHER] = HWBLK(MSTPCR2, 28, CORE_AREA_BM),
[HWBLK_ATAPI] = HWBLK(MSTPCR2, 26, CORE_AREA_BM),
[HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
[HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
[HWBLK_TSIF] = HWBLK(MSTPCR2, 22, CORE_AREA),
[HWBLK_USB1] = HWBLK(MSTPCR2, 21, CORE_AREA),
[HWBLK_USB0] = HWBLK(MSTPCR2, 20, CORE_AREA),
[HWBLK_2DG] = HWBLK(MSTPCR2, 19, CORE_AREA_BM),
[HWBLK_SDHI0] = HWBLK(MSTPCR2, 18, CORE_AREA),
[HWBLK_SDHI1] = HWBLK(MSTPCR2, 17, CORE_AREA),
[HWBLK_VEU1] = HWBLK(MSTPCR2, 15, CORE_AREA_BM),
[HWBLK_CEU1] = HWBLK(MSTPCR2, 13, CORE_AREA_BM),
[HWBLK_BEU1] = HWBLK(MSTPCR2, 12, CORE_AREA_BM),
[HWBLK_2DDMAC] = HWBLK(MSTPCR2, 10, CORE_AREA_BM),
[HWBLK_SPU] = HWBLK(MSTPCR2, 9, CORE_AREA_BM),
[HWBLK_JPU] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
[HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
[HWBLK_BEU0] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
[HWBLK_CEU0] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
[HWBLK_VEU0] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
[HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
[HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
};
static struct hwblk_info sh7724_hwblk_info = {
.areas = sh7724_hwblk_area,
.nr_areas = ARRAY_SIZE(sh7724_hwblk_area),
.hwblks = sh7724_hwblk,
.nr_hwblks = ARRAY_SIZE(sh7724_hwblk),
};
int arch_hwblk_sleep_mode(void)
{
if (!sh7724_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
return SUSP_SH_STANDBY | SUSP_SH_SF;
if (!sh7724_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
return SUSP_SH_SLEEP | SUSP_SH_SF;
return SUSP_SH_SLEEP;
}
int __init arch_hwblk_init(void)
{
return hwblk_register(&sh7724_hwblk_info);
}

View File

@ -40,7 +40,7 @@ static struct platform_device iic_device = {
};
static struct r8a66597_platdata r8a66597_data = {
/* This set zero to all members */
.on_chip = 1,
};
static struct resource usb_host_resources[] = {

View File

@ -13,9 +13,11 @@
#include <linux/serial_sci.h>
#include <linux/mm.h>
#include <linux/uio_driver.h>
#include <linux/usb/m66592.h>
#include <linux/sh_timer.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
#include <cpu/sh7722.h>
static struct resource rtc_resources[] = {
[0] = {
@ -45,11 +47,18 @@ static struct platform_device rtc_device = {
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
.archdata = {
.hwblk_id = HWBLK_RTC,
},
};
static struct m66592_platdata usbf_platdata = {
.on_chip = 1,
};
static struct resource usbf_resources[] = {
[0] = {
.name = "m66592_udc",
.name = "USBF",
.start = 0x04480000,
.end = 0x044800FF,
.flags = IORESOURCE_MEM,
@ -67,9 +76,13 @@ static struct platform_device usbf_device = {
.dev = {
.dma_mask = NULL,
.coherent_dma_mask = 0xffffffff,
.platform_data = &usbf_platdata,
},
.num_resources = ARRAY_SIZE(usbf_resources),
.resource = usbf_resources,
.archdata = {
.hwblk_id = HWBLK_USBF,
},
};
static struct resource iic_resources[] = {
@ -91,6 +104,9 @@ static struct platform_device iic_device = {
.id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic_resources),
.resource = iic_resources,
.archdata = {
.hwblk_id = HWBLK_IIC,
},
};
static struct uio_info vpu_platform_data = {
@ -119,6 +135,9 @@ static struct platform_device vpu_device = {
},
.resource = vpu_resources,
.num_resources = ARRAY_SIZE(vpu_resources),
.archdata = {
.hwblk_id = HWBLK_VPU,
},
};
static struct uio_info veu_platform_data = {
@ -147,6 +166,9 @@ static struct platform_device veu_device = {
},
.resource = veu_resources,
.num_resources = ARRAY_SIZE(veu_resources),
.archdata = {
.hwblk_id = HWBLK_VEU,
},
};
static struct uio_info jpu_platform_data = {
@ -175,6 +197,9 @@ static struct platform_device jpu_device = {
},
.resource = jpu_resources,
.num_resources = ARRAY_SIZE(jpu_resources),
.archdata = {
.hwblk_id = HWBLK_JPU,
},
};
static struct sh_timer_config cmt_platform_data = {
@ -207,6 +232,9 @@ static struct platform_device cmt_device = {
},
.resource = cmt_resources,
.num_resources = ARRAY_SIZE(cmt_resources),
.archdata = {
.hwblk_id = HWBLK_CMT,
},
};
static struct sh_timer_config tmu0_platform_data = {
@ -238,6 +266,9 @@ static struct platform_device tmu0_device = {
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
.archdata = {
.hwblk_id = HWBLK_TMU,
},
};
static struct sh_timer_config tmu1_platform_data = {
@ -269,6 +300,9 @@ static struct platform_device tmu1_device = {
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
.archdata = {
.hwblk_id = HWBLK_TMU,
},
};
static struct sh_timer_config tmu2_platform_data = {
@ -299,6 +333,9 @@ static struct platform_device tmu2_device = {
},
.resource = tmu2_resources,
.num_resources = ARRAY_SIZE(tmu2_resources),
.archdata = {
.hwblk_id = HWBLK_TMU,
},
};
static struct plat_sci_port sci_platform_data[] = {

View File

@ -18,6 +18,7 @@
#include <linux/io.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
#include <cpu/sh7723.h>
static struct uio_info vpu_platform_data = {
.name = "VPU5",
@ -45,6 +46,9 @@ static struct platform_device vpu_device = {
},
.resource = vpu_resources,
.num_resources = ARRAY_SIZE(vpu_resources),
.archdata = {
.hwblk_id = HWBLK_VPU,
},
};
static struct uio_info veu0_platform_data = {
@ -73,6 +77,9 @@ static struct platform_device veu0_device = {
},
.resource = veu0_resources,
.num_resources = ARRAY_SIZE(veu0_resources),
.archdata = {
.hwblk_id = HWBLK_VEU2H0,
},
};
static struct uio_info veu1_platform_data = {
@ -101,6 +108,9 @@ static struct platform_device veu1_device = {
},
.resource = veu1_resources,
.num_resources = ARRAY_SIZE(veu1_resources),
.archdata = {
.hwblk_id = HWBLK_VEU2H1,
},
};
static struct sh_timer_config cmt_platform_data = {
@ -133,6 +143,9 @@ static struct platform_device cmt_device = {
},
.resource = cmt_resources,
.num_resources = ARRAY_SIZE(cmt_resources),
.archdata = {
.hwblk_id = HWBLK_CMT,
},
};
static struct sh_timer_config tmu0_platform_data = {
@ -164,6 +177,9 @@ static struct platform_device tmu0_device = {
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
.archdata = {
.hwblk_id = HWBLK_TMU0,
},
};
static struct sh_timer_config tmu1_platform_data = {
@ -195,6 +211,9 @@ static struct platform_device tmu1_device = {
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
.archdata = {
.hwblk_id = HWBLK_TMU0,
},
};
static struct sh_timer_config tmu2_platform_data = {
@ -225,6 +244,9 @@ static struct platform_device tmu2_device = {
},
.resource = tmu2_resources,
.num_resources = ARRAY_SIZE(tmu2_resources),
.archdata = {
.hwblk_id = HWBLK_TMU0,
},
};
static struct sh_timer_config tmu3_platform_data = {
@ -255,6 +277,9 @@ static struct platform_device tmu3_device = {
},
.resource = tmu3_resources,
.num_resources = ARRAY_SIZE(tmu3_resources),
.archdata = {
.hwblk_id = HWBLK_TMU1,
},
};
static struct sh_timer_config tmu4_platform_data = {
@ -285,6 +310,9 @@ static struct platform_device tmu4_device = {
},
.resource = tmu4_resources,
.num_resources = ARRAY_SIZE(tmu4_resources),
.archdata = {
.hwblk_id = HWBLK_TMU1,
},
};
static struct sh_timer_config tmu5_platform_data = {
@ -315,6 +343,9 @@ static struct platform_device tmu5_device = {
},
.resource = tmu5_resources,
.num_resources = ARRAY_SIZE(tmu5_resources),
.archdata = {
.hwblk_id = HWBLK_TMU1,
},
};
static struct plat_sci_port sci_platform_data[] = {
@ -395,10 +426,13 @@ static struct platform_device rtc_device = {
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
.archdata = {
.hwblk_id = HWBLK_RTC,
},
};
static struct r8a66597_platdata r8a66597_data = {
/* This set zero to all members */
.on_chip = 1,
};
static struct resource sh7723_usb_host_resources[] = {
@ -424,6 +458,9 @@ static struct platform_device sh7723_usb_host_device = {
},
.num_resources = ARRAY_SIZE(sh7723_usb_host_resources),
.resource = sh7723_usb_host_resources,
.archdata = {
.hwblk_id = HWBLK_USB,
},
};
static struct resource iic_resources[] = {
@ -445,6 +482,9 @@ static struct platform_device iic_device = {
.id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic_resources),
.resource = iic_resources,
.archdata = {
.hwblk_id = HWBLK_IIC,
},
};
static struct platform_device *sh7723_devices[] __initdata = {

View File

@ -22,6 +22,7 @@
#include <linux/io.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
#include <cpu/sh7724.h>
/* Serial */
static struct plat_sci_port sci_platform_data[] = {
@ -103,6 +104,9 @@ static struct platform_device rtc_device = {
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
.archdata = {
.hwblk_id = HWBLK_RTC,
},
};
/* I2C0 */
@ -125,6 +129,9 @@ static struct platform_device iic0_device = {
.id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic0_resources),
.resource = iic0_resources,
.archdata = {
.hwblk_id = HWBLK_IIC0,
},
};
/* I2C1 */
@ -147,6 +154,9 @@ static struct platform_device iic1_device = {
.id = 1, /* "i2c1" clock */
.num_resources = ARRAY_SIZE(iic1_resources),
.resource = iic1_resources,
.archdata = {
.hwblk_id = HWBLK_IIC1,
},
};
/* VPU */
@ -176,6 +186,9 @@ static struct platform_device vpu_device = {
},
.resource = vpu_resources,
.num_resources = ARRAY_SIZE(vpu_resources),
.archdata = {
.hwblk_id = HWBLK_VPU,
},
};
/* VEU0 */
@ -205,6 +218,9 @@ static struct platform_device veu0_device = {
},
.resource = veu0_resources,
.num_resources = ARRAY_SIZE(veu0_resources),
.archdata = {
.hwblk_id = HWBLK_VEU0,
},
};
/* VEU1 */
@ -234,6 +250,9 @@ static struct platform_device veu1_device = {
},
.resource = veu1_resources,
.num_resources = ARRAY_SIZE(veu1_resources),
.archdata = {
.hwblk_id = HWBLK_VEU1,
},
};
static struct sh_timer_config cmt_platform_data = {
@ -266,6 +285,9 @@ static struct platform_device cmt_device = {
},
.resource = cmt_resources,
.num_resources = ARRAY_SIZE(cmt_resources),
.archdata = {
.hwblk_id = HWBLK_CMT,
},
};
static struct sh_timer_config tmu0_platform_data = {
@ -297,6 +319,9 @@ static struct platform_device tmu0_device = {
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
.archdata = {
.hwblk_id = HWBLK_TMU0,
},
};
static struct sh_timer_config tmu1_platform_data = {
@ -328,6 +353,9 @@ static struct platform_device tmu1_device = {
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
.archdata = {
.hwblk_id = HWBLK_TMU0,
},
};
static struct sh_timer_config tmu2_platform_data = {
@ -358,6 +386,9 @@ static struct platform_device tmu2_device = {
},
.resource = tmu2_resources,
.num_resources = ARRAY_SIZE(tmu2_resources),
.archdata = {
.hwblk_id = HWBLK_TMU0,
},
};
@ -389,6 +420,9 @@ static struct platform_device tmu3_device = {
},
.resource = tmu3_resources,
.num_resources = ARRAY_SIZE(tmu3_resources),
.archdata = {
.hwblk_id = HWBLK_TMU1,
},
};
static struct sh_timer_config tmu4_platform_data = {
@ -419,6 +453,9 @@ static struct platform_device tmu4_device = {
},
.resource = tmu4_resources,
.num_resources = ARRAY_SIZE(tmu4_resources),
.archdata = {
.hwblk_id = HWBLK_TMU1,
},
};
static struct sh_timer_config tmu5_platform_data = {
@ -449,6 +486,9 @@ static struct platform_device tmu5_device = {
},
.resource = tmu5_resources,
.num_resources = ARRAY_SIZE(tmu5_resources),
.archdata = {
.hwblk_id = HWBLK_TMU1,
},
};
/* JPU */
@ -478,6 +518,9 @@ static struct platform_device jpu_device = {
},
.resource = jpu_resources,
.num_resources = ARRAY_SIZE(jpu_resources),
.archdata = {
.hwblk_id = HWBLK_JPU,
},
};
static struct platform_device *sh7724_devices[] __initdata = {

View File

@ -4,3 +4,4 @@
# Power Management & Sleep mode
obj-$(CONFIG_PM) += pm.o sleep.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o

View File

@ -0,0 +1,102 @@
/*
* arch/sh/kernel/cpu/shmobile/cpuidle.c
*
* Cpuidle support code for SuperH Mobile
*
* Copyright (C) 2009 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/suspend.h>
#include <linux/cpuidle.h>
#include <asm/suspend.h>
#include <asm/uaccess.h>
#include <asm/hwblk.h>
static unsigned long cpuidle_mode[] = {
SUSP_SH_SLEEP, /* regular sleep mode */
SUSP_SH_SLEEP | SUSP_SH_SF, /* sleep mode + self refresh */
};
static int cpuidle_sleep_enter(struct cpuidle_device *dev,
struct cpuidle_state *state)
{
unsigned long allowed_mode = arch_hwblk_sleep_mode();
ktime_t before, after;
int requested_state = state - &dev->states[0];
int allowed_state;
int k;
/* convert allowed mode to allowed state */
for (k = ARRAY_SIZE(cpuidle_mode) - 1; k > 0; k--)
if (cpuidle_mode[k] == allowed_mode)
break;
allowed_state = k;
/* take the following into account for sleep mode selection:
* - allowed_state: best mode allowed by hardware (clock deps)
* - requested_state: best mode allowed by software (latencies)
*/
k = min_t(int, allowed_state, requested_state);
dev->last_state = &dev->states[k];
before = ktime_get();
sh_mobile_call_standby(cpuidle_mode[k]);
after = ktime_get();
return ktime_to_ns(ktime_sub(after, before)) >> 10;
}
static struct cpuidle_device cpuidle_dev;
static struct cpuidle_driver cpuidle_driver = {
.name = "sh_idle",
.owner = THIS_MODULE,
};
void sh_mobile_setup_cpuidle(void)
{
struct cpuidle_device *dev = &cpuidle_dev;
struct cpuidle_state *state;
int i;
cpuidle_register_driver(&cpuidle_driver);
for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
dev->states[i].name[0] = '\0';
dev->states[i].desc[0] = '\0';
}
i = CPUIDLE_DRIVER_STATE_START;
state = &dev->states[i++];
snprintf(state->name, CPUIDLE_NAME_LEN, "C0");
strncpy(state->desc, "SuperH Sleep Mode", CPUIDLE_DESC_LEN);
state->exit_latency = 1;
state->target_residency = 1 * 2;
state->power_usage = 3;
state->flags = 0;
state->flags |= CPUIDLE_FLAG_SHALLOW;
state->flags |= CPUIDLE_FLAG_TIME_VALID;
state->enter = cpuidle_sleep_enter;
dev->safe_state = state;
state = &dev->states[i++];
snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
strncpy(state->desc, "SuperH Sleep Mode [SF]", CPUIDLE_DESC_LEN);
state->exit_latency = 100;
state->target_residency = 1 * 2;
state->power_usage = 1;
state->flags = 0;
state->flags |= CPUIDLE_FLAG_TIME_VALID;
state->enter = cpuidle_sleep_enter;
dev->state_count = i;
cpuidle_register_device(dev);
}

View File

@ -1,5 +1,5 @@
/*
* arch/sh/kernel/cpu/sh4a/pm-sh_mobile.c
* arch/sh/kernel/cpu/shmobile/pm.c
*
* Power management support code for SuperH Mobile
*
@ -32,20 +32,17 @@
*
* R-standby mode is unsupported, but will be added in the future
* U-standby mode is low priority since it needs bootloader hacks
*
* All modes should be tied in with cpuidle. But before that can
* happen we need to keep track of enabled hardware blocks so we
* can avoid entering sleep modes that stop clocks to hardware
* blocks that are in use even though the cpu core is idle.
*/
#define ILRAM_BASE 0xe5200000
extern const unsigned char sh_mobile_standby[];
extern const unsigned int sh_mobile_standby_size;
static void sh_mobile_call_standby(unsigned long mode)
void sh_mobile_call_standby(unsigned long mode)
{
extern void *vbr_base;
void *onchip_mem = (void *)0xe5200000; /* ILRAM */
void *onchip_mem = (void *)ILRAM_BASE;
void (*standby_onchip_mem)(unsigned long) = onchip_mem;
/* Note: Wake up from sleep may generate exceptions!
@ -55,11 +52,6 @@ static void sh_mobile_call_standby(unsigned long mode)
if (mode & SUSP_SH_SF)
asm volatile("ldc %0, vbr" : : "r" (onchip_mem) : "memory");
/* Copy the assembly snippet to the otherwise ununsed ILRAM */
memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size);
wmb();
ctrl_barrier();
/* Let assembly snippet in on-chip memory handle the rest */
standby_onchip_mem(mode);
@ -85,7 +77,15 @@ static struct platform_suspend_ops sh_pm_ops = {
static int __init sh_pm_init(void)
{
void *onchip_mem = (void *)ILRAM_BASE;
/* Copy the assembly snippet to the otherwise ununsed ILRAM */
memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size);
wmb();
ctrl_barrier();
suspend_set_ops(&sh_pm_ops);
sh_mobile_setup_cpuidle();
return 0;
}

123
arch/sh/kernel/dumpstack.c Normal file
View File

@ -0,0 +1,123 @@
/*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
* Copyright (C) 2009 Matt Fleming
*/
#include <linux/kallsyms.h>
#include <linux/ftrace.h>
#include <linux/debug_locks.h>
#include <asm/unwinder.h>
#include <asm/stacktrace.h>
void printk_address(unsigned long address, int reliable)
{
printk(" [<%p>] %s%pS\n", (void *) address,
reliable ? "" : "? ", (void *) address);
}
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
static void
print_ftrace_graph_addr(unsigned long addr, void *data,
const struct stacktrace_ops *ops,
struct thread_info *tinfo, int *graph)
{
struct task_struct *task = tinfo->task;
unsigned long ret_addr;
int index = task->curr_ret_stack;
if (addr != (unsigned long)return_to_handler)
return;
if (!task->ret_stack || index < *graph)
return;
index -= *graph;
ret_addr = task->ret_stack[index].ret;
ops->address(data, ret_addr, 1);
(*graph)++;
}
#else
static inline void
print_ftrace_graph_addr(unsigned long addr, void *data,
const struct stacktrace_ops *ops,
struct thread_info *tinfo, int *graph)
{ }
#endif
void
stack_reader_dump(struct task_struct *task, struct pt_regs *regs,
unsigned long *sp, const struct stacktrace_ops *ops,
void *data)
{
struct thread_info *context;
int graph = 0;
context = (struct thread_info *)
((unsigned long)sp & (~(THREAD_SIZE - 1)));
while (!kstack_end(sp)) {
unsigned long addr = *sp++;
if (__kernel_text_address(addr)) {
ops->address(data, addr, 1);
print_ftrace_graph_addr(addr, data, ops,
context, &graph);
}
}
}
static void
print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
{
printk(data);
print_symbol(msg, symbol);
printk("\n");
}
static void print_trace_warning(void *data, char *msg)
{
printk("%s%s\n", (char *)data, msg);
}
static int print_trace_stack(void *data, char *name)
{
printk("%s <%s> ", (char *)data, name);
return 0;
}
/*
* Print one address/symbol entries per line.
*/
static void print_trace_address(void *data, unsigned long addr, int reliable)
{
printk(data);
printk_address(addr, reliable);
}
static const struct stacktrace_ops print_trace_ops = {
.warning = print_trace_warning,
.warning_symbol = print_trace_warning_symbol,
.stack = print_trace_stack,
.address = print_trace_address,
};
void show_trace(struct task_struct *tsk, unsigned long *sp,
struct pt_regs *regs)
{
if (regs && user_mode(regs))
return;
printk("\nCall trace:\n");
unwind_stack(tsk, regs, sp, &print_trace_ops, "");
printk("\n");
if (!tsk)
tsk = current;
debug_show_held_locks(tsk);
}

902
arch/sh/kernel/dwarf.c Normal file
View File

@ -0,0 +1,902 @@
/*
* Copyright (C) 2009 Matt Fleming <matt@console-pimps.org>
*
* 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.
*
* This is an implementation of a DWARF unwinder. Its main purpose is
* for generating stacktrace information. Based on the DWARF 3
* specification from http://www.dwarfstd.org.
*
* TODO:
* - DWARF64 doesn't work.
*/
/* #define DEBUG */
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <asm/dwarf.h>
#include <asm/unwinder.h>
#include <asm/sections.h>
#include <asm/unaligned.h>
#include <asm/dwarf.h>
#include <asm/stacktrace.h>
static LIST_HEAD(dwarf_cie_list);
DEFINE_SPINLOCK(dwarf_cie_lock);
static LIST_HEAD(dwarf_fde_list);
DEFINE_SPINLOCK(dwarf_fde_lock);
static struct dwarf_cie *cached_cie;
/*
* Figure out whether we need to allocate some dwarf registers. If dwarf
* registers have already been allocated then we may need to realloc
* them. "reg" is a register number that we need to be able to access
* after this call.
*
* Register numbers start at zero, therefore we need to allocate space
* for "reg" + 1 registers.
*/
static void dwarf_frame_alloc_regs(struct dwarf_frame *frame,
unsigned int reg)
{
struct dwarf_reg *regs;
unsigned int num_regs = reg + 1;
size_t new_size;
size_t old_size;
new_size = num_regs * sizeof(*regs);
old_size = frame->num_regs * sizeof(*regs);
/* Fast path: don't allocate any regs if we've already got enough. */
if (frame->num_regs >= num_regs)
return;
regs = kzalloc(new_size, GFP_ATOMIC);
if (!regs) {
printk(KERN_WARNING "Unable to allocate DWARF registers\n");
/*
* Let's just bomb hard here, we have no way to
* gracefully recover.
*/
BUG();
}
if (frame->regs) {
memcpy(regs, frame->regs, old_size);
kfree(frame->regs);
}
frame->regs = regs;
frame->num_regs = num_regs;
}
/**
* dwarf_read_addr - read dwarf data
* @src: source address of data
* @dst: destination address to store the data to
*
* Read 'n' bytes from @src, where 'n' is the size of an address on
* the native machine. We return the number of bytes read, which
* should always be 'n'. We also have to be careful when reading
* from @src and writing to @dst, because they can be arbitrarily
* aligned. Return 'n' - the number of bytes read.
*/
static inline int dwarf_read_addr(unsigned long *src, unsigned long *dst)
{
u32 val = get_unaligned(src);
put_unaligned(val, dst);
return sizeof(unsigned long *);
}
/**
* dwarf_read_uleb128 - read unsigned LEB128 data
* @addr: the address where the ULEB128 data is stored
* @ret: address to store the result
*
* Decode an unsigned LEB128 encoded datum. The algorithm is taken
* from Appendix C of the DWARF 3 spec. For information on the
* encodings refer to section "7.6 - Variable Length Data". Return
* the number of bytes read.
*/
static inline unsigned long dwarf_read_uleb128(char *addr, unsigned int *ret)
{
unsigned int result;
unsigned char byte;
int shift, count;
result = 0;
shift = 0;
count = 0;
while (1) {
byte = __raw_readb(addr);
addr++;
count++;
result |= (byte & 0x7f) << shift;
shift += 7;
if (!(byte & 0x80))
break;
}
*ret = result;
return count;
}
/**
* dwarf_read_leb128 - read signed LEB128 data
* @addr: the address of the LEB128 encoded data
* @ret: address to store the result
*
* Decode signed LEB128 data. The algorithm is taken from Appendix
* C of the DWARF 3 spec. Return the number of bytes read.
*/
static inline unsigned long dwarf_read_leb128(char *addr, int *ret)
{
unsigned char byte;
int result, shift;
int num_bits;
int count;
result = 0;
shift = 0;
count = 0;
while (1) {
byte = __raw_readb(addr);
addr++;
result |= (byte & 0x7f) << shift;
shift += 7;
count++;
if (!(byte & 0x80))
break;
}
/* The number of bits in a signed integer. */
num_bits = 8 * sizeof(result);
if ((shift < num_bits) && (byte & 0x40))
result |= (-1 << shift);
*ret = result;
return count;
}
/**
* dwarf_read_encoded_value - return the decoded value at @addr
* @addr: the address of the encoded value
* @val: where to write the decoded value
* @encoding: the encoding with which we can decode @addr
*
* GCC emits encoded address in the .eh_frame FDE entries. Decode
* the value at @addr using @encoding. The decoded value is written
* to @val and the number of bytes read is returned.
*/
static int dwarf_read_encoded_value(char *addr, unsigned long *val,
char encoding)
{
unsigned long decoded_addr = 0;
int count = 0;
switch (encoding & 0x70) {
case DW_EH_PE_absptr:
break;
case DW_EH_PE_pcrel:
decoded_addr = (unsigned long)addr;
break;
default:
pr_debug("encoding=0x%x\n", (encoding & 0x70));
BUG();
}
if ((encoding & 0x07) == 0x00)
encoding |= DW_EH_PE_udata4;
switch (encoding & 0x0f) {
case DW_EH_PE_sdata4:
case DW_EH_PE_udata4:
count += 4;
decoded_addr += get_unaligned((u32 *)addr);
__raw_writel(decoded_addr, val);
break;
default:
pr_debug("encoding=0x%x\n", encoding);
BUG();
}
return count;
}
/**
* dwarf_entry_len - return the length of an FDE or CIE
* @addr: the address of the entry
* @len: the length of the entry
*
* Read the initial_length field of the entry and store the size of
* the entry in @len. We return the number of bytes read. Return a
* count of 0 on error.
*/
static inline int dwarf_entry_len(char *addr, unsigned long *len)
{
u32 initial_len;
int count;
initial_len = get_unaligned((u32 *)addr);
count = 4;
/*
* An initial length field value in the range DW_LEN_EXT_LO -
* DW_LEN_EXT_HI indicates an extension, and should not be
* interpreted as a length. The only extension that we currently
* understand is the use of DWARF64 addresses.
*/
if (initial_len >= DW_EXT_LO && initial_len <= DW_EXT_HI) {
/*
* The 64-bit length field immediately follows the
* compulsory 32-bit length field.
*/
if (initial_len == DW_EXT_DWARF64) {
*len = get_unaligned((u64 *)addr + 4);
count = 12;
} else {
printk(KERN_WARNING "Unknown DWARF extension\n");
count = 0;
}
} else
*len = initial_len;
return count;
}
/**
* dwarf_lookup_cie - locate the cie
* @cie_ptr: pointer to help with lookup
*/
static struct dwarf_cie *dwarf_lookup_cie(unsigned long cie_ptr)
{
struct dwarf_cie *cie, *n;
unsigned long flags;
spin_lock_irqsave(&dwarf_cie_lock, flags);
/*
* We've cached the last CIE we looked up because chances are
* that the FDE wants this CIE.
*/
if (cached_cie && cached_cie->cie_pointer == cie_ptr) {
cie = cached_cie;
goto out;
}
list_for_each_entry_safe(cie, n, &dwarf_cie_list, link) {
if (cie->cie_pointer == cie_ptr) {
cached_cie = cie;
break;
}
}
/* Couldn't find the entry in the list. */
if (&cie->link == &dwarf_cie_list)
cie = NULL;
out:
spin_unlock_irqrestore(&dwarf_cie_lock, flags);
return cie;
}
/**
* dwarf_lookup_fde - locate the FDE that covers pc
* @pc: the program counter
*/
struct dwarf_fde *dwarf_lookup_fde(unsigned long pc)
{
unsigned long flags;
struct dwarf_fde *fde, *n;
spin_lock_irqsave(&dwarf_fde_lock, flags);
list_for_each_entry_safe(fde, n, &dwarf_fde_list, link) {
unsigned long start, end;
start = fde->initial_location;
end = fde->initial_location + fde->address_range;
if (pc >= start && pc < end)
break;
}
/* Couldn't find the entry in the list. */
if (&fde->link == &dwarf_fde_list)
fde = NULL;
spin_unlock_irqrestore(&dwarf_fde_lock, flags);
return fde;
}
/**
* dwarf_cfa_execute_insns - execute instructions to calculate a CFA
* @insn_start: address of the first instruction
* @insn_end: address of the last instruction
* @cie: the CIE for this function
* @fde: the FDE for this function
* @frame: the instructions calculate the CFA for this frame
* @pc: the program counter of the address we're interested in
* @define_ra: keep executing insns until the return addr reg is defined?
*
* Execute the Call Frame instruction sequence starting at
* @insn_start and ending at @insn_end. The instructions describe
* how to calculate the Canonical Frame Address of a stackframe.
* Store the results in @frame.
*/
static int dwarf_cfa_execute_insns(unsigned char *insn_start,
unsigned char *insn_end,
struct dwarf_cie *cie,
struct dwarf_fde *fde,
struct dwarf_frame *frame,
unsigned long pc,
bool define_ra)
{
unsigned char insn;
unsigned char *current_insn;
unsigned int count, delta, reg, expr_len, offset;
bool seen_ra_reg;
current_insn = insn_start;
/*
* If we're executing instructions for the dwarf_unwind_stack()
* FDE we need to keep executing instructions until the value of
* DWARF_ARCH_RA_REG is defined. See the comment in
* dwarf_unwind_stack() for more details.
*/
if (define_ra)
seen_ra_reg = false;
else
seen_ra_reg = true;
while (current_insn < insn_end && (frame->pc <= pc || !seen_ra_reg) ) {
insn = __raw_readb(current_insn++);
if (!seen_ra_reg) {
if (frame->num_regs >= DWARF_ARCH_RA_REG &&
frame->regs[DWARF_ARCH_RA_REG].flags)
seen_ra_reg = true;
}
/*
* Firstly, handle the opcodes that embed their operands
* in the instructions.
*/
switch (DW_CFA_opcode(insn)) {
case DW_CFA_advance_loc:
delta = DW_CFA_operand(insn);
delta *= cie->code_alignment_factor;
frame->pc += delta;
continue;
/* NOTREACHED */
case DW_CFA_offset:
reg = DW_CFA_operand(insn);
count = dwarf_read_uleb128(current_insn, &offset);
current_insn += count;
offset *= cie->data_alignment_factor;
dwarf_frame_alloc_regs(frame, reg);
frame->regs[reg].addr = offset;
frame->regs[reg].flags |= DWARF_REG_OFFSET;
continue;
/* NOTREACHED */
case DW_CFA_restore:
reg = DW_CFA_operand(insn);
continue;
/* NOTREACHED */
}
/*
* Secondly, handle the opcodes that don't embed their
* operands in the instruction.
*/
switch (insn) {
case DW_CFA_nop:
continue;
case DW_CFA_advance_loc1:
delta = *current_insn++;
frame->pc += delta * cie->code_alignment_factor;
break;
case DW_CFA_advance_loc2:
delta = get_unaligned((u16 *)current_insn);
current_insn += 2;
frame->pc += delta * cie->code_alignment_factor;
break;
case DW_CFA_advance_loc4:
delta = get_unaligned((u32 *)current_insn);
current_insn += 4;
frame->pc += delta * cie->code_alignment_factor;
break;
case DW_CFA_offset_extended:
count = dwarf_read_uleb128(current_insn, &reg);
current_insn += count;
count = dwarf_read_uleb128(current_insn, &offset);
current_insn += count;
offset *= cie->data_alignment_factor;
break;
case DW_CFA_restore_extended:
count = dwarf_read_uleb128(current_insn, &reg);
current_insn += count;
break;
case DW_CFA_undefined:
count = dwarf_read_uleb128(current_insn, &reg);
current_insn += count;
break;
case DW_CFA_def_cfa:
count = dwarf_read_uleb128(current_insn,
&frame->cfa_register);
current_insn += count;
count = dwarf_read_uleb128(current_insn,
&frame->cfa_offset);
current_insn += count;
frame->flags |= DWARF_FRAME_CFA_REG_OFFSET;
break;
case DW_CFA_def_cfa_register:
count = dwarf_read_uleb128(current_insn,
&frame->cfa_register);
current_insn += count;
frame->cfa_offset = 0;
frame->flags |= DWARF_FRAME_CFA_REG_OFFSET;
break;
case DW_CFA_def_cfa_offset:
count = dwarf_read_uleb128(current_insn, &offset);
current_insn += count;
frame->cfa_offset = offset;
break;
case DW_CFA_def_cfa_expression:
count = dwarf_read_uleb128(current_insn, &expr_len);
current_insn += count;
frame->cfa_expr = current_insn;
frame->cfa_expr_len = expr_len;
current_insn += expr_len;
frame->flags |= DWARF_FRAME_CFA_REG_EXP;
break;
case DW_CFA_offset_extended_sf:
count = dwarf_read_uleb128(current_insn, &reg);
current_insn += count;
count = dwarf_read_leb128(current_insn, &offset);
current_insn += count;
offset *= cie->data_alignment_factor;
dwarf_frame_alloc_regs(frame, reg);
frame->regs[reg].flags |= DWARF_REG_OFFSET;
frame->regs[reg].addr = offset;
break;
case DW_CFA_val_offset:
count = dwarf_read_uleb128(current_insn, &reg);
current_insn += count;
count = dwarf_read_leb128(current_insn, &offset);
offset *= cie->data_alignment_factor;
frame->regs[reg].flags |= DWARF_REG_OFFSET;
frame->regs[reg].addr = offset;
break;
default:
pr_debug("unhandled DWARF instruction 0x%x\n", insn);
break;
}
}
return 0;
}
/**
* dwarf_unwind_stack - recursively unwind the stack
* @pc: address of the function to unwind
* @prev: struct dwarf_frame of the previous stackframe on the callstack
*
* Return a struct dwarf_frame representing the most recent frame
* on the callstack. Each of the lower (older) stack frames are
* linked via the "prev" member.
*/
struct dwarf_frame *dwarf_unwind_stack(unsigned long pc,
struct dwarf_frame *prev)
{
struct dwarf_frame *frame;
struct dwarf_cie *cie;
struct dwarf_fde *fde;
unsigned long addr;
int i, offset;
bool define_ra = false;
/*
* If this is the first invocation of this recursive function we
* need get the contents of a physical register to get the CFA
* in order to begin the virtual unwinding of the stack.
*
* Setting "define_ra" to true indictates that we want
* dwarf_cfa_execute_insns() to continue executing instructions
* until we know how to calculate the value of DWARF_ARCH_RA_REG
* (which we need in order to kick off the whole unwinding
* process).
*
* NOTE: the return address is guaranteed to be setup by the
* time this function makes its first function call.
*/
if (!pc && !prev) {
pc = (unsigned long)&dwarf_unwind_stack;
define_ra = true;
}
frame = kzalloc(sizeof(*frame), GFP_ATOMIC);
if (!frame)
return NULL;
frame->prev = prev;
fde = dwarf_lookup_fde(pc);
if (!fde) {
/*
* This is our normal exit path - the one that stops the
* recursion. There's two reasons why we might exit
* here,
*
* a) pc has no asscociated DWARF frame info and so
* we don't know how to unwind this frame. This is
* usually the case when we're trying to unwind a
* frame that was called from some assembly code
* that has no DWARF info, e.g. syscalls.
*
* b) the DEBUG info for pc is bogus. There's
* really no way to distinguish this case from the
* case above, which sucks because we could print a
* warning here.
*/
return NULL;
}
cie = dwarf_lookup_cie(fde->cie_pointer);
frame->pc = fde->initial_location;
/* CIE initial instructions */
dwarf_cfa_execute_insns(cie->initial_instructions,
cie->instructions_end, cie, fde,
frame, pc, false);
/* FDE instructions */
dwarf_cfa_execute_insns(fde->instructions, fde->end, cie,
fde, frame, pc, define_ra);
/* Calculate the CFA */
switch (frame->flags) {
case DWARF_FRAME_CFA_REG_OFFSET:
if (prev) {
BUG_ON(!prev->regs[frame->cfa_register].flags);
addr = prev->cfa;
addr += prev->regs[frame->cfa_register].addr;
frame->cfa = __raw_readl(addr);
} else {
/*
* Again, this is the first invocation of this
* recurisve function. We need to physically
* read the contents of a register in order to
* get the Canonical Frame Address for this
* function.
*/
frame->cfa = dwarf_read_arch_reg(frame->cfa_register);
}
frame->cfa += frame->cfa_offset;
break;
default:
BUG();
}
/* If we haven't seen the return address reg, we're screwed. */
BUG_ON(!frame->regs[DWARF_ARCH_RA_REG].flags);
for (i = 0; i <= frame->num_regs; i++) {
struct dwarf_reg *reg = &frame->regs[i];
if (!reg->flags)
continue;
offset = reg->addr;
offset += frame->cfa;
}
addr = frame->cfa + frame->regs[DWARF_ARCH_RA_REG].addr;
frame->return_addr = __raw_readl(addr);
frame->next = dwarf_unwind_stack(frame->return_addr, frame);
return frame;
}
static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
unsigned char *end)
{
struct dwarf_cie *cie;
unsigned long flags;
int count;
cie = kzalloc(sizeof(*cie), GFP_KERNEL);
if (!cie)
return -ENOMEM;
cie->length = len;
/*
* Record the offset into the .eh_frame section
* for this CIE. It allows this CIE to be
* quickly and easily looked up from the
* corresponding FDE.
*/
cie->cie_pointer = (unsigned long)entry;
cie->version = *(char *)p++;
BUG_ON(cie->version != 1);
cie->augmentation = p;
p += strlen(cie->augmentation) + 1;
count = dwarf_read_uleb128(p, &cie->code_alignment_factor);
p += count;
count = dwarf_read_leb128(p, &cie->data_alignment_factor);
p += count;
/*
* Which column in the rule table contains the
* return address?
*/
if (cie->version == 1) {
cie->return_address_reg = __raw_readb(p);
p++;
} else {
count = dwarf_read_uleb128(p, &cie->return_address_reg);
p += count;
}
if (cie->augmentation[0] == 'z') {
unsigned int length, count;
cie->flags |= DWARF_CIE_Z_AUGMENTATION;
count = dwarf_read_uleb128(p, &length);
p += count;
BUG_ON((unsigned char *)p > end);
cie->initial_instructions = p + length;
cie->augmentation++;
}
while (*cie->augmentation) {
/*
* "L" indicates a byte showing how the
* LSDA pointer is encoded. Skip it.
*/
if (*cie->augmentation == 'L') {
p++;
cie->augmentation++;
} else if (*cie->augmentation == 'R') {
/*
* "R" indicates a byte showing
* how FDE addresses are
* encoded.
*/
cie->encoding = *(char *)p++;
cie->augmentation++;
} else if (*cie->augmentation == 'P') {
/*
* "R" indicates a personality
* routine in the CIE
* augmentation.
*/
BUG();
} else if (*cie->augmentation == 'S') {
BUG();
} else {
/*
* Unknown augmentation. Assume
* 'z' augmentation.
*/
p = cie->initial_instructions;
BUG_ON(!p);
break;
}
}
cie->initial_instructions = p;
cie->instructions_end = end;
/* Add to list */
spin_lock_irqsave(&dwarf_cie_lock, flags);
list_add_tail(&cie->link, &dwarf_cie_list);
spin_unlock_irqrestore(&dwarf_cie_lock, flags);
return 0;
}
static int dwarf_parse_fde(void *entry, u32 entry_type,
void *start, unsigned long len)
{
struct dwarf_fde *fde;
struct dwarf_cie *cie;
unsigned long flags;
int count;
void *p = start;
fde = kzalloc(sizeof(*fde), GFP_KERNEL);
if (!fde)
return -ENOMEM;
fde->length = len;
/*
* In a .eh_frame section the CIE pointer is the
* delta between the address within the FDE
*/
fde->cie_pointer = (unsigned long)(p - entry_type - 4);
cie = dwarf_lookup_cie(fde->cie_pointer);
fde->cie = cie;
if (cie->encoding)
count = dwarf_read_encoded_value(p, &fde->initial_location,
cie->encoding);
else
count = dwarf_read_addr(p, &fde->initial_location);
p += count;
if (cie->encoding)
count = dwarf_read_encoded_value(p, &fde->address_range,
cie->encoding & 0x0f);
else
count = dwarf_read_addr(p, &fde->address_range);
p += count;
if (fde->cie->flags & DWARF_CIE_Z_AUGMENTATION) {
unsigned int length;
count = dwarf_read_uleb128(p, &length);
p += count + length;
}
/* Call frame instructions. */
fde->instructions = p;
fde->end = start + len;
/* Add to list. */
spin_lock_irqsave(&dwarf_fde_lock, flags);
list_add_tail(&fde->link, &dwarf_fde_list);
spin_unlock_irqrestore(&dwarf_fde_lock, flags);
return 0;
}
static void dwarf_unwinder_dump(struct task_struct *task, struct pt_regs *regs,
unsigned long *sp,
const struct stacktrace_ops *ops, void *data)
{
struct dwarf_frame *frame;
frame = dwarf_unwind_stack(0, NULL);
while (frame && frame->return_addr) {
ops->address(data, frame->return_addr, 1);
frame = frame->next;
}
}
static struct unwinder dwarf_unwinder = {
.name = "dwarf-unwinder",
.dump = dwarf_unwinder_dump,
.rating = 150,
};
static void dwarf_unwinder_cleanup(void)
{
struct dwarf_cie *cie, *m;
struct dwarf_fde *fde, *n;
unsigned long flags;
/*
* Deallocate all the memory allocated for the DWARF unwinder.
* Traverse all the FDE/CIE lists and remove and free all the
* memory associated with those data structures.
*/
spin_lock_irqsave(&dwarf_cie_lock, flags);
list_for_each_entry_safe(cie, m, &dwarf_cie_list, link)
kfree(cie);
spin_unlock_irqrestore(&dwarf_cie_lock, flags);
spin_lock_irqsave(&dwarf_fde_lock, flags);
list_for_each_entry_safe(fde, n, &dwarf_fde_list, link)
kfree(fde);
spin_unlock_irqrestore(&dwarf_fde_lock, flags);
}
/**
* dwarf_unwinder_init - initialise the dwarf unwinder
*
* Build the data structures describing the .dwarf_frame section to
* make it easier to lookup CIE and FDE entries. Because the
* .eh_frame section is packed as tightly as possible it is not
* easy to lookup the FDE for a given PC, so we build a list of FDE
* and CIE entries that make it easier.
*/
void dwarf_unwinder_init(void)
{
u32 entry_type;
void *p, *entry;
int count, err;
unsigned long len;
unsigned int c_entries, f_entries;
unsigned char *end;
INIT_LIST_HEAD(&dwarf_cie_list);
INIT_LIST_HEAD(&dwarf_fde_list);
c_entries = 0;
f_entries = 0;
entry = &__start_eh_frame;
while ((char *)entry < __stop_eh_frame) {
p = entry;
count = dwarf_entry_len(p, &len);
if (count == 0) {
/*
* We read a bogus length field value. There is
* nothing we can do here apart from disabling
* the DWARF unwinder. We can't even skip this
* entry and move to the next one because 'len'
* tells us where our next entry is.
*/
goto out;
} else
p += count;
/* initial length does not include itself */
end = p + len;
entry_type = get_unaligned((u32 *)p);
p += 4;
if (entry_type == DW_EH_FRAME_CIE) {
err = dwarf_parse_cie(entry, p, len, end);
if (err < 0)
goto out;
else
c_entries++;
} else {
err = dwarf_parse_fde(entry, entry_type, p, len);
if (err < 0)
goto out;
else
f_entries++;
}
entry = (char *)entry + len + 4;
}
printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n",
c_entries, f_entries);
err = unwinder_register(&dwarf_unwinder);
if (err)
goto out;
return;
out:
printk(KERN_ERR "Failed to initialise DWARF unwinder: %d\n", err);
dwarf_unwinder_cleanup();
}

View File

@ -134,7 +134,7 @@ static void scif_sercon_init(char *s)
sci_out(&scif_port, SCFCR, 0x0030); /* TTRG=b'11 */
sci_out(&scif_port, SCSCR, 0x0030); /* TE, RE */
}
#elif defined(CONFIG_CPU_SH4)
#elif defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3)
#define DEFAULT_BAUD 115200
/*
* Simple SCIF init, primarily aimed at SH7750 and other similar SH-4
@ -220,8 +220,7 @@ static int __init setup_early_printk(char *buf)
early_console = &scif_console;
#if !defined(CONFIG_SH_STANDARD_BIOS)
#if defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721)
#if defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3)
scif_sercon_init(buf + 6);
#endif
#endif

View File

@ -43,9 +43,10 @@
* syscall #
*
*/
#include <asm/dwarf.h>
#if defined(CONFIG_PREEMPT)
# define preempt_stop() cli
# define preempt_stop() cli ; TRACE_IRQS_OFF
#else
# define preempt_stop()
# define resume_kernel __restore_all
@ -55,11 +56,7 @@
.align 2
ENTRY(exception_error)
!
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 2f, r0
jsr @r0
nop
#endif
TRACE_IRQS_ON
sti
mov.l 1f, r0
jmp @r0
@ -67,22 +64,28 @@ ENTRY(exception_error)
.align 2
1: .long do_exception_error
#ifdef CONFIG_TRACE_IRQFLAGS
2: .long trace_hardirqs_on
#endif
.align 2
ret_from_exception:
CFI_STARTPROC simple
CFI_DEF_CFA r14, 0
CFI_REL_OFFSET 17, 64
CFI_REL_OFFSET 15, 0
CFI_REL_OFFSET 14, 56
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
shlr2 r0
and #0x3c, r0
cmp/eq #0x3c, r0
bt 9f
TRACE_IRQS_ON
9:
mov #OFF_SR, r0
mov.l @(r0,r15), r0 ! get status register
shll r0
shll r0 ! kernel space?
get_current_thread_info r8, r0
@ -125,13 +128,9 @@ noresched:
ENTRY(resume_userspace)
! r8: current_thread_info
cli
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 5f, r0
jsr @r0
nop
#endif
TRACE_IRQS_OfF
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
tst #_TIF_WORK_MASK, r0
tst #(_TIF_WORK_MASK & 0xff), r0
bt/s __restore_all
tst #_TIF_NEED_RESCHED, r0
@ -156,14 +155,10 @@ work_resched:
jsr @r1 ! schedule
nop
cli
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 5f, r0
jsr @r0
nop
#endif
TRACE_IRQS_OFF
!
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
tst #_TIF_WORK_MASK, r0
tst #(_TIF_WORK_MASK & 0xff), r0
bt __restore_all
bra work_pending
tst #_TIF_NEED_RESCHED, r0
@ -172,23 +167,15 @@ work_resched:
1: .long schedule
2: .long do_notify_resume
3: .long resume_userspace
#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_WORK_SYSCALL_MASK, r0
tst #(_TIF_WORK_SYSCALL_MASK & 0xff), r0
bt/s work_pending
tst #_TIF_NEED_RESCHED, r0
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 5f, r0
jsr @r0
nop
#endif
TRACE_IRQS_ON
sti
mov r15, r4
mov.l 8f, r0 ! do_syscall_trace_leave
@ -259,6 +246,7 @@ debug_trap:
nop
bra __restore_all
nop
CFI_ENDPROC
.align 2
1: .long debug_trap_table
@ -304,6 +292,7 @@ ret_from_fork:
* system calls and debug traps through their respective jump tables.
*/
ENTRY(system_call)
setup_frame_reg
#if !defined(CONFIG_CPU_SH2)
mov.l 1f, r9
mov.l @r9, r8 ! Read from TRA (Trap Address) Register
@ -321,18 +310,18 @@ ENTRY(system_call)
bt/s debug_trap ! it's a debug trap..
nop
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 5f, r10
jsr @r10
nop
#endif
TRACE_IRQS_ON
sti
!
get_current_thread_info r8, r10
mov.l @(TI_FLAGS,r8), r8
mov #_TIF_WORK_SYSCALL_MASK, r10
mov #(_TIF_WORK_SYSCALL_MASK & 0xff), r10
mov #(_TIF_WORK_SYSCALL_MASK >> 8), r9
tst r10, r8
shll8 r9
bf syscall_trace_entry
tst r9, r8
bf syscall_trace_entry
!
mov.l 2f, r8 ! Number of syscalls
@ -351,15 +340,15 @@ syscall_call:
!
syscall_exit:
cli
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 6f, r0
jsr @r0
nop
#endif
TRACE_IRQS_OFF
!
get_current_thread_info r8, r0
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
tst #_TIF_ALLWORK_MASK, r0
tst #(_TIF_ALLWORK_MASK & 0xff), r0
mov #(_TIF_ALLWORK_MASK >> 8), r1
bf syscall_exit_work
shlr8 r0
tst r0, r1
bf syscall_exit_work
bra __restore_all
nop
@ -369,9 +358,5 @@ syscall_exit:
#endif
2: .long NR_syscalls
3: .long sys_call_table
#ifdef CONFIG_TRACE_IRQFLAGS
5: .long trace_hardirqs_on
6: .long trace_hardirqs_off
#endif
7: .long do_syscall_trace_enter
8: .long do_syscall_trace_leave

View File

@ -16,9 +16,13 @@
#include <linux/string.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <asm/ftrace.h>
#include <asm/cacheflush.h>
#include <asm/unistd.h>
#include <trace/syscall.h>
#ifdef CONFIG_DYNAMIC_FTRACE
static unsigned char ftrace_replaced_code[MCOUNT_INSN_SIZE];
static unsigned char ftrace_nop[4];
@ -131,3 +135,189 @@ int __init ftrace_dyn_arch_init(void *data)
return 0;
}
#endif /* CONFIG_DYNAMIC_FTRACE */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
#ifdef CONFIG_DYNAMIC_FTRACE
extern void ftrace_graph_call(void);
static int ftrace_mod(unsigned long ip, unsigned long old_addr,
unsigned long new_addr)
{
unsigned char code[MCOUNT_INSN_SIZE];
if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE))
return -EFAULT;
if (old_addr != __raw_readl((unsigned long *)code))
return -EINVAL;
__raw_writel(new_addr, ip);
return 0;
}
int ftrace_enable_ftrace_graph_caller(void)
{
unsigned long ip, old_addr, new_addr;
ip = (unsigned long)(&ftrace_graph_call) + GRAPH_INSN_OFFSET;
old_addr = (unsigned long)(&skip_trace);
new_addr = (unsigned long)(&ftrace_graph_caller);
return ftrace_mod(ip, old_addr, new_addr);
}
int ftrace_disable_ftrace_graph_caller(void)
{
unsigned long ip, old_addr, new_addr;
ip = (unsigned long)(&ftrace_graph_call) + GRAPH_INSN_OFFSET;
old_addr = (unsigned long)(&ftrace_graph_caller);
new_addr = (unsigned long)(&skip_trace);
return ftrace_mod(ip, old_addr, new_addr);
}
#endif /* CONFIG_DYNAMIC_FTRACE */
/*
* Hook the return address and push it in the stack of return addrs
* in the current thread info.
*
* This is the main routine for the function graph tracer. The function
* graph tracer essentially works like this:
*
* parent is the stack address containing self_addr's return address.
* We pull the real return address out of parent and store it in
* current's ret_stack. Then, we replace the return address on the stack
* with the address of return_to_handler. self_addr is the function that
* called mcount.
*
* When self_addr returns, it will jump to return_to_handler which calls
* ftrace_return_to_handler. ftrace_return_to_handler will pull the real
* return address off of current's ret_stack and jump to it.
*/
void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
{
unsigned long old;
int faulted, err;
struct ftrace_graph_ent trace;
unsigned long return_hooker = (unsigned long)&return_to_handler;
if (unlikely(atomic_read(&current->tracing_graph_pause)))
return;
/*
* Protect against fault, even if it shouldn't
* happen. This tool is too much intrusive to
* ignore such a protection.
*/
__asm__ __volatile__(
"1: \n\t"
"mov.l @%2, %0 \n\t"
"2: \n\t"
"mov.l %3, @%2 \n\t"
"mov #0, %1 \n\t"
"3: \n\t"
".section .fixup, \"ax\" \n\t"
"4: \n\t"
"mov.l 5f, %0 \n\t"
"jmp @%0 \n\t"
" mov #1, %1 \n\t"
".balign 4 \n\t"
"5: .long 3b \n\t"
".previous \n\t"
".section __ex_table,\"a\" \n\t"
".long 1b, 4b \n\t"
".long 2b, 4b \n\t"
".previous \n\t"
: "=&r" (old), "=r" (faulted)
: "r" (parent), "r" (return_hooker)
);
if (unlikely(faulted)) {
ftrace_graph_stop();
WARN_ON(1);
return;
}
err = ftrace_push_return_trace(old, self_addr, &trace.depth, 0);
if (err == -EBUSY) {
__raw_writel(old, parent);
return;
}
trace.func = self_addr;
/* Only trace if the calling function expects to */
if (!ftrace_graph_entry(&trace)) {
current->curr_ret_stack--;
__raw_writel(old, parent);
}
}
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
#ifdef CONFIG_FTRACE_SYSCALLS
extern unsigned long __start_syscalls_metadata[];
extern unsigned long __stop_syscalls_metadata[];
extern unsigned long *sys_call_table;
static struct syscall_metadata **syscalls_metadata;
static struct syscall_metadata *find_syscall_meta(unsigned long *syscall)
{
struct syscall_metadata *start;
struct syscall_metadata *stop;
char str[KSYM_SYMBOL_LEN];
start = (struct syscall_metadata *)__start_syscalls_metadata;
stop = (struct syscall_metadata *)__stop_syscalls_metadata;
kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str);
for ( ; start < stop; start++) {
if (start->name && !strcmp(start->name, str))
return start;
}
return NULL;
}
#define FTRACE_SYSCALL_MAX (NR_syscalls - 1)
struct syscall_metadata *syscall_nr_to_meta(int nr)
{
if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0)
return NULL;
return syscalls_metadata[nr];
}
void arch_init_ftrace_syscalls(void)
{
int i;
struct syscall_metadata *meta;
unsigned long **psys_syscall_table = &sys_call_table;
static atomic_t refs;
if (atomic_inc_return(&refs) != 1)
goto end;
syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
FTRACE_SYSCALL_MAX, GFP_KERNEL);
if (!syscalls_metadata) {
WARN_ON(1);
return;
}
for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
meta = find_syscall_meta(psys_syscall_table[i]);
syscalls_metadata[i] = meta;
}
return;
/* Paranoid: avoid overflow */
end:
atomic_dec(&refs);
}
#endif /* CONFIG_FTRACE_SYSCALLS */

View File

@ -112,14 +112,15 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
struct trapped_io *tiop;
struct resource *res;
int k, len;
unsigned long flags;
spin_lock_irq(&trapped_lock);
spin_lock_irqsave(&trapped_lock, flags);
list_for_each_entry(tiop, list, list) {
voffs = 0;
for (k = 0; k < tiop->num_resources; k++) {
res = tiop->resource + k;
if (res->start == offset) {
spin_unlock_irq(&trapped_lock);
spin_unlock_irqrestore(&trapped_lock, flags);
return tiop->virt_base + voffs;
}
@ -127,7 +128,7 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
voffs += roundup(len, PAGE_SIZE);
}
}
spin_unlock_irq(&trapped_lock);
spin_unlock_irqrestore(&trapped_lock, flags);
return NULL;
}
EXPORT_SYMBOL_GPL(match_trapped_io_handler);

View File

@ -14,6 +14,7 @@
#include <asm/processor.h>
#include <asm/machvec.h>
#include <asm/uaccess.h>
#include <asm/dwarf.h>
#include <asm/thread_info.h>
#include <cpu/mmu_context.h>
@ -114,23 +115,6 @@ asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs)
#endif
irq_enter();
#ifdef CONFIG_DEBUG_STACKOVERFLOW
/* Debugging check for stack overflow: is there less than 1KB free? */
{
long sp;
__asm__ __volatile__ ("and r15, %0" :
"=r" (sp) : "0" (THREAD_SIZE - 1));
if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
printk("do_IRQ: stack overflow: %ld\n",
sp - sizeof(struct thread_info));
dump_stack();
}
}
#endif
irq = irq_demux(intc_evt2irq(irq));
#ifdef CONFIG_IRQSTACKS
@ -278,6 +262,9 @@ void __init init_IRQ(void)
sh_mv.mv_init_irq();
irq_ctx_init(smp_processor_id());
/* This needs to be early, but not too early.. */
dwarf_unwinder_init();
}
#ifdef CONFIG_SPARSE_IRQ

View File

@ -23,6 +23,7 @@
#include <linux/tick.h>
#include <linux/reboot.h>
#include <linux/fs.h>
#include <linux/ftrace.h>
#include <linux/preempt.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
@ -264,8 +265,8 @@ static void ubc_set_tracing(int asid, unsigned long pc)
* switch_to(x,y) should switch tasks from x to y.
*
*/
struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *next)
__notrace_funcgraph struct task_struct *
__switch_to(struct task_struct *prev, struct task_struct *next)
{
#if defined(CONFIG_SH_FPU)
unlazy_fpu(prev, task_pt_regs(prev));

View File

@ -34,6 +34,8 @@
#include <asm/syscalls.h>
#include <asm/fpu.h>
#include <trace/syscall.h>
/*
* This routine will get a word off of the process kernel stack.
*/
@ -459,6 +461,9 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
*/
ret = -1L;
if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
ftrace_syscall_enter(regs);
if (unlikely(current->audit_context))
audit_syscall_entry(audit_arch(), regs->regs[3],
regs->regs[4], regs->regs[5],
@ -475,6 +480,9 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]),
regs->regs[0]);
if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
ftrace_syscall_exit(regs);
step = test_thread_flag(TIF_SINGLESTEP);
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, step);

View File

@ -30,6 +30,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/lmb.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/page.h>
@ -233,39 +234,45 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
void __init setup_bootmem_allocator(unsigned long free_pfn)
{
unsigned long bootmap_size;
unsigned long bootmap_pages, bootmem_paddr;
u64 total_pages = (lmb_end_of_DRAM() - __MEMORY_START) >> PAGE_SHIFT;
int i;
bootmap_pages = bootmem_bootmap_pages(total_pages);
bootmem_paddr = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
/*
* Find a proper area for the bootmem bitmap. After this
* bootstrap step all allocations (until the page allocator
* is intact) must be done via bootmem_alloc().
*/
bootmap_size = init_bootmem_node(NODE_DATA(0), free_pfn,
bootmap_size = init_bootmem_node(NODE_DATA(0),
bootmem_paddr >> PAGE_SHIFT,
min_low_pfn, max_low_pfn);
__add_active_range(0, min_low_pfn, max_low_pfn);
/* Add active regions with valid PFNs. */
for (i = 0; i < lmb.memory.cnt; i++) {
unsigned long start_pfn, end_pfn;
start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
__add_active_range(0, start_pfn, end_pfn);
}
/*
* Add all physical memory to the bootmem map and mark each
* area as present.
*/
register_bootmem_low_pages();
/* Reserve the sections we're already using. */
for (i = 0; i < lmb.reserved.cnt; i++)
reserve_bootmem(lmb.reserved.region[i].base,
lmb_size_bytes(&lmb.reserved, i),
BOOTMEM_DEFAULT);
node_set_online(0);
/*
* Reserve the kernel text and
* Reserve the bootmem bitmap. We do this in two steps (first step
* was init_bootmem()), because this catches the (definitely buggy)
* case of us accidentally initializing the bootmem allocator with
* an invalid RAM area.
*/
reserve_bootmem(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
(PFN_PHYS(free_pfn) + bootmap_size + PAGE_SIZE - 1) -
(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET),
BOOTMEM_DEFAULT);
/*
* Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
*/
if (CONFIG_ZERO_PAGE_OFFSET != 0)
reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET,
BOOTMEM_DEFAULT);
sparse_memory_present_with_active_regions(0);
#ifdef CONFIG_BLK_DEV_INITRD
@ -296,12 +303,37 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
static void __init setup_memory(void)
{
unsigned long start_pfn;
u64 base = min_low_pfn << PAGE_SHIFT;
u64 size = (max_low_pfn << PAGE_SHIFT) - base;
/*
* Partially used pages are not usable - thus
* we are rounding upwards:
*/
start_pfn = PFN_UP(__pa(_end));
lmb_add(base, size);
/*
* Reserve the kernel text and
* Reserve the bootmem bitmap. We do this in two steps (first step
* was init_bootmem()), because this catches the (definitely buggy)
* case of us accidentally initializing the bootmem allocator with
* an invalid RAM area.
*/
lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
(PFN_PHYS(start_pfn) + PAGE_SIZE - 1) -
(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));
/*
* Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
*/
if (CONFIG_ZERO_PAGE_OFFSET != 0)
lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET);
lmb_analyze();
lmb_dump_all();
setup_bootmem_allocator(start_pfn);
}
#else
@ -402,6 +434,7 @@ void __init setup_arch(char **cmdline_p)
nodes_clear(node_online_map);
/* Setup bootmem with available RAM */
lmb_init();
setup_memory();
sparse_init();

View File

@ -106,8 +106,8 @@ EXPORT_SYMBOL(flush_dcache_page);
EXPORT_SYMBOL(clear_user_page);
#endif
#ifdef CONFIG_FUNCTION_TRACER
EXPORT_SYMBOL(mcount);
#ifdef CONFIG_MCOUNT
DECLARE_EXPORT(mcount);
#endif
EXPORT_SYMBOL(csum_partial);
EXPORT_SYMBOL(csum_partial_copy_generic);

View File

@ -13,47 +13,93 @@
#include <linux/stacktrace.h>
#include <linux/thread_info.h>
#include <linux/module.h>
#include <asm/unwinder.h>
#include <asm/ptrace.h>
#include <asm/stacktrace.h>
static void save_stack_warning(void *data, char *msg)
{
}
static void
save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
{
}
static int save_stack_stack(void *data, char *name)
{
return 0;
}
/*
* Save stack-backtrace addresses into a stack_trace buffer.
*/
static void save_stack_address(void *data, unsigned long addr, int reliable)
{
struct stack_trace *trace = data;
if (!reliable)
return;
if (trace->skip > 0) {
trace->skip--;
return;
}
if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = addr;
}
static const struct stacktrace_ops save_stack_ops = {
.warning = save_stack_warning,
.warning_symbol = save_stack_warning_symbol,
.stack = save_stack_stack,
.address = save_stack_address,
};
void save_stack_trace(struct stack_trace *trace)
{
unsigned long *sp = (unsigned long *)current_stack_pointer;
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;
}
}
unwind_stack(current, NULL, sp, &save_stack_ops, trace);
if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = ULONG_MAX;
}
EXPORT_SYMBOL_GPL(save_stack_trace);
static void
save_stack_address_nosched(void *data, unsigned long addr, int reliable)
{
struct stack_trace *trace = (struct stack_trace *)data;
if (!reliable)
return;
if (in_sched_functions(addr))
return;
if (trace->skip > 0) {
trace->skip--;
return;
}
if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = addr;
}
static const struct stacktrace_ops save_stack_ops_nosched = {
.warning = save_stack_warning,
.warning_symbol = save_stack_warning_symbol,
.stack = save_stack_stack,
.address = save_stack_address_nosched,
};
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
{
unsigned long *sp = (unsigned long *)tsk->thread.sp;
while (!kstack_end(sp)) {
unsigned long addr = *sp++;
if (__kernel_text_address(addr)) {
if (in_sched_functions(addr))
break;
if (trace->skip > 0)
trace->skip--;
else
trace->entries[trace->nr_entries++] = addr;
if (trace->nr_entries >= trace->max_entries)
break;
}
}
unwind_stack(current, NULL, sp, &save_stack_ops_nosched, trace);
if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = ULONG_MAX;
}
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);

View File

@ -21,6 +21,7 @@
#include <linux/smp.h>
#include <linux/rtc.h>
#include <asm/clock.h>
#include <asm/hwblk.h>
#include <asm/rtc.h>
/* Dummy RTC ops */
@ -91,21 +92,8 @@ module_init(rtc_generic_init);
void (*board_time_init)(void);
void __init time_init(void)
static void __init sh_late_time_init(void)
{
if (board_time_init)
board_time_init();
clk_init();
rtc_sh_get_time(&xtime);
set_normalized_timespec(&wall_to_monotonic,
-xtime.tv_sec, -xtime.tv_nsec);
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
local_timer_setup(smp_processor_id());
#endif
/*
* Make sure all compiled-in early timers register themselves.
*
@ -118,3 +106,22 @@ void __init time_init(void)
early_platform_driver_register_all("earlytimer");
early_platform_driver_probe("earlytimer", 2, 0);
}
void __init time_init(void)
{
if (board_time_init)
board_time_init();
hwblk_init();
clk_init();
rtc_sh_get_time(&xtime);
set_normalized_timespec(&wall_to_monotonic,
-xtime.tv_sec, -xtime.tv_nsec);
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
local_timer_setup(smp_processor_id());
#endif
late_time_init = sh_late_time_init;
}

View File

@ -858,30 +858,6 @@ void __init trap_init(void)
per_cpu_trap_init();
}
void show_trace(struct task_struct *tsk, unsigned long *sp,
struct pt_regs *regs)
{
unsigned long addr;
if (regs && user_mode(regs))
return;
printk("\nCall trace:\n");
while (!kstack_end(sp)) {
addr = *sp++;
if (kernel_text_address(addr))
print_ip_sym(addr);
}
printk("\n");
if (!tsk)
tsk = current;
debug_show_held_locks(tsk);
}
void show_stack(struct task_struct *tsk, unsigned long *sp)
{
unsigned long stack;

162
arch/sh/kernel/unwinder.c Normal file
View File

@ -0,0 +1,162 @@
/*
* Copyright (C) 2009 Matt Fleming
*
* Based, in part, on kernel/time/clocksource.c.
*
* This file provides arbitration code for stack unwinders.
*
* Multiple stack unwinders can be available on a system, usually with
* the most accurate unwinder being the currently active one.
*/
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <asm/unwinder.h>
#include <asm/atomic.h>
/*
* This is the most basic stack unwinder an architecture can
* provide. For architectures without reliable frame pointers, e.g.
* RISC CPUs, it can be implemented by looking through the stack for
* addresses that lie within the kernel text section.
*
* Other CPUs, e.g. x86, can use their frame pointer register to
* construct more accurate stack traces.
*/
static struct list_head unwinder_list;
static struct unwinder stack_reader = {
.name = "stack-reader",
.dump = stack_reader_dump,
.rating = 50,
.list = {
.next = &unwinder_list,
.prev = &unwinder_list,
},
};
/*
* "curr_unwinder" points to the stack unwinder currently in use. This
* is the unwinder with the highest rating.
*
* "unwinder_list" is a linked-list of all available unwinders, sorted
* by rating.
*
* All modifications of "curr_unwinder" and "unwinder_list" must be
* performed whilst holding "unwinder_lock".
*/
static struct unwinder *curr_unwinder = &stack_reader;
static struct list_head unwinder_list = {
.next = &stack_reader.list,
.prev = &stack_reader.list,
};
static DEFINE_SPINLOCK(unwinder_lock);
static atomic_t unwinder_running = ATOMIC_INIT(0);
/**
* select_unwinder - Select the best registered stack unwinder.
*
* Private function. Must hold unwinder_lock when called.
*
* Select the stack unwinder with the best rating. This is useful for
* setting up curr_unwinder.
*/
static struct unwinder *select_unwinder(void)
{
struct unwinder *best;
if (list_empty(&unwinder_list))
return NULL;
best = list_entry(unwinder_list.next, struct unwinder, list);
if (best == curr_unwinder)
return NULL;
return best;
}
/*
* Enqueue the stack unwinder sorted by rating.
*/
static int unwinder_enqueue(struct unwinder *ops)
{
struct list_head *tmp, *entry = &unwinder_list;
list_for_each(tmp, &unwinder_list) {
struct unwinder *o;
o = list_entry(tmp, struct unwinder, list);
if (o == ops)
return -EBUSY;
/* Keep track of the place, where to insert */
if (o->rating >= ops->rating)
entry = tmp;
}
list_add(&ops->list, entry);
return 0;
}
/**
* unwinder_register - Used to install new stack unwinder
* @u: unwinder to be registered
*
* Install the new stack unwinder on the unwinder list, which is sorted
* by rating.
*
* Returns -EBUSY if registration fails, zero otherwise.
*/
int unwinder_register(struct unwinder *u)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&unwinder_lock, flags);
ret = unwinder_enqueue(u);
if (!ret)
curr_unwinder = select_unwinder();
spin_unlock_irqrestore(&unwinder_lock, flags);
return ret;
}
/*
* Unwind the call stack and pass information to the stacktrace_ops
* functions. Also handle the case where we need to switch to a new
* stack dumper because the current one faulted unexpectedly.
*/
void unwind_stack(struct task_struct *task, struct pt_regs *regs,
unsigned long *sp, const struct stacktrace_ops *ops,
void *data)
{
unsigned long flags;
/*
* The problem with unwinders with high ratings is that they are
* inherently more complicated than the simple ones with lower
* ratings. We are therefore more likely to fault in the
* complicated ones, e.g. hitting BUG()s. If we fault in the
* code for the current stack unwinder we try to downgrade to
* one with a lower rating.
*
* Hopefully this will give us a semi-reliable stacktrace so we
* can diagnose why curr_unwinder->dump() faulted.
*/
if (atomic_inc_return(&unwinder_running) != 1) {
spin_lock_irqsave(&unwinder_lock, flags);
if (!list_is_singular(&unwinder_list)) {
list_del(&curr_unwinder->list);
curr_unwinder = select_unwinder();
}
spin_unlock_irqrestore(&unwinder_lock, flags);
atomic_dec(&unwinder_running);
}
curr_unwinder->dump(task, regs, sp, ops, data);
atomic_dec(&unwinder_running);
}

View File

@ -12,7 +12,7 @@ OUTPUT_ARCH(sh)
#include <asm/thread_info.h>
#include <asm/cache.h>
#include <asm-generic/vmlinux.lds.h>
#include <asm/vmlinux.lds.h>
ENTRY(_start)
SECTIONS
@ -50,12 +50,7 @@ SECTIONS
_etext = .; /* End of text section */
} = 0x0009
. = ALIGN(16); /* Exception table */
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
__start___ex_table = .;
*(__ex_table)
__stop___ex_table = .;
}
EXCEPTION_TABLE(16)
NOTES
RO_DATA(PAGE_SIZE)
@ -71,69 +66,16 @@ SECTIONS
__uncached_end = .;
}
. = ALIGN(THREAD_SIZE);
.data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
*(.data.init_task)
. = ALIGN(L1_CACHE_BYTES);
*(.data.cacheline_aligned)
. = ALIGN(L1_CACHE_BYTES);
*(.data.read_mostly)
. = ALIGN(PAGE_SIZE);
*(.data.page_aligned)
__nosave_begin = .;
*(.data.nosave)
. = ALIGN(PAGE_SIZE);
__nosave_end = .;
DATA_DATA
CONSTRUCTORS
}
RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
_edata = .; /* End of data section */
DWARF_EH_FRAME
. = ALIGN(PAGE_SIZE); /* Init code and data */
.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
__init_begin = .;
_sinittext = .;
INIT_TEXT
_einittext = .;
}
.init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { INIT_DATA }
. = ALIGN(16);
.init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
__setup_start = .;
*(.init.setup)
__setup_end = .;
}
.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
__initcall_start = .;
INITCALLS
__initcall_end = .;
}
.con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
}
SECURITY_INIT
#ifdef CONFIG_BLK_DEV_INITRD
. = ALIGN(PAGE_SIZE);
.init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
__initramfs_start = .;
*(.init.ramfs)
__initramfs_end = .;
}
#endif
INIT_TEXT_SECTION(PAGE_SIZE)
INIT_DATA_SECTION(16)
. = ALIGN(4);
.machvec.init : AT(ADDR(.machvec.init) - LOAD_OFFSET) {
@ -152,16 +94,10 @@ SECTIONS
.exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { EXIT_DATA }
. = ALIGN(PAGE_SIZE);
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
__init_end = .;
__bss_start = .; /* BSS */
*(.bss.page_aligned)
*(.bss)
*(COMMON)
. = ALIGN(4);
BSS_SECTION(0, PAGE_SIZE, 4)
_ebss = .; /* uClinux MTD sucks */
_end = . ;
}
/*
* When something in the kernel is NOT compiled as a module, the
@ -170,7 +106,7 @@ SECTIONS
* it's a module.
*/
/DISCARD/ : {
*(.exitcall.exit)
EXIT_CALL
}
STABS_DEBUG

View File

@ -24,7 +24,7 @@ memcpy-y := memcpy.o
memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o
lib-$(CONFIG_MMU) += copy_page.o clear_page.o
lib-$(CONFIG_FUNCTION_TRACER) += mcount.o
lib-$(CONFIG_MCOUNT) += mcount.o
lib-y += $(memcpy-y) $(udivsi3-y)
EXTRA_CFLAGS += -Werror

View File

@ -1,14 +1,16 @@
/*
* arch/sh/lib/mcount.S
*
* Copyright (C) 2008 Paul Mundt
* Copyright (C) 2008 Matt Fleming
* Copyright (C) 2008, 2009 Paul Mundt
* Copyright (C) 2008, 2009 Matt Fleming
*
* 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 <asm/ftrace.h>
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
#define MCOUNT_ENTER() \
mov.l r4, @-r15; \
@ -28,6 +30,55 @@
rts; \
mov.l @r15+, r4
#ifdef CONFIG_STACK_DEBUG
/*
* Perform diagnostic checks on the state of the kernel stack.
*
* Check for stack overflow. If there is less than 1KB free
* then it has overflowed.
*
* Make sure the stack pointer contains a valid address. Valid
* addresses for kernel stacks are anywhere after the bss
* (after _ebss) and anywhere in init_thread_union (init_stack).
*/
#define STACK_CHECK() \
mov #(THREAD_SIZE >> 10), r0; \
shll8 r0; \
shll2 r0; \
\
/* r1 = sp & (THREAD_SIZE - 1) */ \
mov #-1, r1; \
add r0, r1; \
and r15, r1; \
\
mov #TI_SIZE, r3; \
mov #(STACK_WARN >> 8), r2; \
shll8 r2; \
add r3, r2; \
\
/* Is the stack overflowing? */ \
cmp/hi r2, r1; \
bf stack_panic; \
\
/* If sp > _ebss then we're OK. */ \
mov.l .L_ebss, r1; \
cmp/hi r1, r15; \
bt 1f; \
\
/* If sp < init_stack, we're not OK. */ \
mov.l .L_init_thread_union, r1; \
cmp/hs r1, r15; \
bf stack_panic; \
\
/* If sp > init_stack && sp < _ebss, not OK. */ \
add r0, r1; \
cmp/hs r1, r15; \
bt stack_panic; \
1:
#else
#define STACK_CHECK()
#endif /* CONFIG_STACK_DEBUG */
.align 2
.globl _mcount
.type _mcount,@function
@ -35,6 +86,19 @@
.type mcount,@function
_mcount:
mcount:
STACK_CHECK()
#ifndef CONFIG_FUNCTION_TRACER
rts
nop
#else
#ifndef CONFIG_DYNAMIC_FTRACE
mov.l .Lfunction_trace_stop, r0
mov.l @r0, r0
tst r0, r0
bf ftrace_stub
#endif
MCOUNT_ENTER()
#ifdef CONFIG_DYNAMIC_FTRACE
@ -52,6 +116,38 @@ mcount_call:
jsr @r6
nop
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
mov.l .Lftrace_graph_return, r6
mov.l .Lftrace_stub, r7
cmp/eq r6, r7
bt 1f
mov.l .Lftrace_graph_caller, r0
jmp @r0
nop
1:
mov.l .Lftrace_graph_entry, r6
mov.l .Lftrace_graph_entry_stub, r7
cmp/eq r6, r7
bt skip_trace
mov.l .Lftrace_graph_caller, r0
jmp @r0
nop
.align 2
.Lftrace_graph_return:
.long ftrace_graph_return
.Lftrace_graph_entry:
.long ftrace_graph_entry
.Lftrace_graph_entry_stub:
.long ftrace_graph_entry_stub
.Lftrace_graph_caller:
.long ftrace_graph_caller
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
.globl skip_trace
skip_trace:
MCOUNT_LEAVE()
@ -60,8 +156,29 @@ skip_trace:
.long ftrace_trace_function
#ifdef CONFIG_DYNAMIC_FTRACE
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
/*
* NOTE: Do not move either ftrace_graph_call or ftrace_caller
* as this will affect the calculation of GRAPH_INSN_OFFSET.
*/
.globl ftrace_graph_call
ftrace_graph_call:
mov.l .Lskip_trace, r0
jmp @r0
nop
.align 2
.Lskip_trace:
.long skip_trace
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
.globl ftrace_caller
ftrace_caller:
mov.l .Lfunction_trace_stop, r0
mov.l @r0, r0
tst r0, r0
bf ftrace_stub
MCOUNT_ENTER()
.globl ftrace_call
@ -70,9 +187,18 @@ ftrace_call:
jsr @r6
nop
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
bra ftrace_graph_call
nop
#else
MCOUNT_LEAVE()
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
#endif /* CONFIG_DYNAMIC_FTRACE */
.align 2
.Lfunction_trace_stop:
.long function_trace_stop
/*
* NOTE: From here on the locations of the .Lftrace_stub label and
* ftrace_stub itself are fixed. Adding additional data here will skew
@ -80,7 +206,6 @@ ftrace_call:
* Place new labels either after the ftrace_stub body, or before
* ftrace_caller. You have been warned.
*/
.align 2
.Lftrace_stub:
.long ftrace_stub
@ -88,3 +213,98 @@ ftrace_call:
ftrace_stub:
rts
nop
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_caller
ftrace_graph_caller:
mov.l 2f, r0
mov.l @r0, r0
tst r0, r0
bt 1f
mov.l 3f, r1
jmp @r1
nop
1:
/*
* MCOUNT_ENTER() pushed 5 registers onto the stack, so
* the stack address containing our return address is
* r15 + 20.
*/
mov #20, r0
add r15, r0
mov r0, r4
mov.l .Lprepare_ftrace_return, r0
jsr @r0
nop
MCOUNT_LEAVE()
.align 2
2: .long function_trace_stop
3: .long skip_trace
.Lprepare_ftrace_return:
.long prepare_ftrace_return
.globl return_to_handler
return_to_handler:
/*
* Save the return values.
*/
mov.l r0, @-r15
mov.l r1, @-r15
mov #0, r4
mov.l .Lftrace_return_to_handler, r0
jsr @r0
nop
/*
* The return value from ftrace_return_handler has the real
* address that we should return to.
*/
lds r0, pr
mov.l @r15+, r1
rts
mov.l @r15+, r0
.align 2
.Lftrace_return_to_handler:
.long ftrace_return_to_handler
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
#endif /* CONFIG_FUNCTION_TRACER */
#ifdef CONFIG_STACK_DEBUG
.globl stack_panic
stack_panic:
mov.l .Ldump_stack, r0
jsr @r0
nop
mov.l .Lpanic, r0
jsr @r0
mov.l .Lpanic_s, r4
rts
nop
.align 2
.L_ebss:
.long _ebss
.L_init_thread_union:
.long init_thread_union
.Lpanic:
.long panic
.Lpanic_s:
.long .Lpanic_str
.Ldump_stack:
.long dump_stack
.section .rodata
.align 2
.Lpanic_str:
.string "Stack error"
#endif /* CONFIG_STACK_DEBUG */

View File

@ -2,7 +2,7 @@
* Page fault handler for SH with an MMU.
*
* Copyright (C) 1999 Niibe Yutaka
* Copyright (C) 2003 - 2008 Paul Mundt
* Copyright (C) 2003 - 2009 Paul Mundt
*
* Based on linux/arch/i386/mm/fault.c:
* Copyright (C) 1995 Linus Torvalds
@ -25,18 +25,91 @@ static inline int notify_page_fault(struct pt_regs *regs, int trap)
{
int ret = 0;
#ifdef CONFIG_KPROBES
if (!user_mode(regs)) {
if (kprobes_built_in() && !user_mode(regs)) {
preempt_disable();
if (kprobe_running() && kprobe_fault_handler(regs, trap))
ret = 1;
preempt_enable();
}
#endif
return ret;
}
static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
{
unsigned index = pgd_index(address);
pgd_t *pgd_k;
pud_t *pud, *pud_k;
pmd_t *pmd, *pmd_k;
pgd += index;
pgd_k = init_mm.pgd + index;
if (!pgd_present(*pgd_k))
return NULL;
pud = pud_offset(pgd, address);
pud_k = pud_offset(pgd_k, address);
if (!pud_present(*pud_k))
return NULL;
pmd = pmd_offset(pud, address);
pmd_k = pmd_offset(pud_k, address);
if (!pmd_present(*pmd_k))
return NULL;
if (!pmd_present(*pmd))
set_pmd(pmd, *pmd_k);
else {
/*
* The page tables are fully synchronised so there must
* be another reason for the fault. Return NULL here to
* signal that we have not taken care of the fault.
*/
BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
return NULL;
}
return pmd_k;
}
/*
* Handle a fault on the vmalloc or module mapping area
*/
static noinline int vmalloc_fault(unsigned long address)
{
pgd_t *pgd_k;
pmd_t *pmd_k;
pte_t *pte_k;
/* Make sure we are in vmalloc area: */
if (!(address >= VMALLOC_START && address < VMALLOC_END))
return -1;
/*
* Synchronize this task's top level page-table
* with the 'reference' page table.
*
* Do _not_ use "current" here. We might be inside
* an interrupt in the middle of a task switch..
*/
pgd_k = get_TTB();
pmd_k = vmalloc_sync_one(pgd_k, address);
if (!pmd_k)
return -1;
pte_k = pte_offset_kernel(pmd_k, address);
if (!pte_present(*pte_k))
return -1;
return 0;
}
static int fault_in_kernel_space(unsigned long address)
{
return address >= TASK_SIZE;
}
/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate
@ -46,6 +119,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
unsigned long writeaccess,
unsigned long address)
{
unsigned long vec;
struct task_struct *tsk;
struct mm_struct *mm;
struct vm_area_struct * vma;
@ -53,59 +127,30 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
int fault;
siginfo_t info;
/*
* We don't bother with any notifier callbacks here, as they are
* all handled through the __do_page_fault() fast-path.
*/
tsk = current;
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;
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)) {
if (!pud_present(*pud_k))
goto bad_area_nosemaphore;
set_pud(pud, *pud_k);
return;
}
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;
}
mm = tsk->mm;
si_code = SEGV_MAPERR;
vec = lookup_exception_vector();
if (unlikely(notify_page_fault(regs, lookup_exception_vector())))
/*
* We fault-in kernel-space virtual memory on-demand. The
* 'reference' page table is init_mm.pgd.
*
* NOTE! We MUST NOT take any locks for this case. We may
* be in an interrupt or a critical region, and should
* only copy the information from the master page table,
* nothing more.
*/
if (unlikely(fault_in_kernel_space(address))) {
if (vmalloc_fault(address) >= 0)
return;
if (notify_page_fault(regs, vec))
return;
goto bad_area_nosemaphore;
}
if (unlikely(notify_page_fault(regs, vec)))
return;
/* Only enable interrupts if they were on before the fault */
@ -115,8 +160,8 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
/*
* If we're in an interrupt or have no user
* context, we must not take the fault..
* If we're in an interrupt, have no user context or are running
* in an atomic region then we must not take the fault:
*/
if (in_atomic() || !mm)
goto no_context;
@ -132,6 +177,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
goto bad_area;
if (expand_stack(vma, address))
goto bad_area;
/*
* Ok, we have a good vm_area for this memory access, so
* we can handle it..

View File

@ -94,7 +94,6 @@ static struct resource *shmedia_find_resource(struct resource *root,
static void __iomem *shmedia_alloc_io(unsigned long phys, unsigned long size,
const char *name, unsigned long flags)
{
static int printed_full;
struct xresource *xres;
struct resource *res;
char *tack;
@ -108,11 +107,8 @@ static void __iomem *shmedia_alloc_io(unsigned long phys, unsigned long size,
tack = xres->xname;
res = &xres->xres;
} else {
if (!printed_full) {
printk(KERN_NOTICE "%s: done with statics, "
printk_once(KERN_NOTICE "%s: done with statics, "
"switching to kmalloc\n", __func__);
printed_full = 1;
}
tlen = strlen(name);
tack = kmalloc(sizeof(struct resource) + tlen + 1, GFP_KERNEL);
if (!tack)

View File

@ -9,6 +9,7 @@
*/
#include <linux/module.h>
#include <linux/bootmem.h>
#include <linux/lmb.h>
#include <linux/mm.h>
#include <linux/numa.h>
#include <linux/pfn.h>
@ -26,6 +27,15 @@ EXPORT_SYMBOL_GPL(node_data);
void __init setup_memory(void)
{
unsigned long free_pfn = PFN_UP(__pa(_end));
u64 base = min_low_pfn << PAGE_SHIFT;
u64 size = (max_low_pfn << PAGE_SHIFT) - min_low_pfn;
lmb_add(base, size);
/* Reserve the LMB regions used by the kernel, initrd, etc.. */
lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
(PFN_PHYS(free_pfn) + PAGE_SIZE - 1) -
(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));
/*
* Node 0 sets up its pgdat at the first available pfn,
@ -45,24 +55,23 @@ void __init setup_memory(void)
void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
{
unsigned long bootmap_pages, bootmap_start, bootmap_size;
unsigned long start_pfn, free_pfn, end_pfn;
unsigned long bootmap_pages;
unsigned long start_pfn, end_pfn;
unsigned long bootmem_paddr;
/* Don't allow bogus node assignment */
BUG_ON(nid > MAX_NUMNODES || nid == 0);
/*
* The free pfn starts at the beginning of the range, and is
* advanced as necessary for pgdat and node map allocations.
*/
free_pfn = start_pfn = start >> PAGE_SHIFT;
start_pfn = start >> PAGE_SHIFT;
end_pfn = end >> PAGE_SHIFT;
lmb_add(start, end - start);
__add_active_range(nid, start_pfn, end_pfn);
/* Node-local pgdat */
NODE_DATA(nid) = pfn_to_kaddr(free_pfn);
free_pfn += PFN_UP(sizeof(struct pglist_data));
NODE_DATA(nid) = __va(lmb_alloc_base(sizeof(struct pglist_data),
SMP_CACHE_BYTES, end_pfn));
memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
@ -71,16 +80,17 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
/* Node-local bootmap */
bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
bootmap_start = (unsigned long)pfn_to_kaddr(free_pfn);
bootmap_size = init_bootmem_node(NODE_DATA(nid), free_pfn, start_pfn,
end_pfn);
bootmem_paddr = lmb_alloc_base(bootmap_pages << PAGE_SHIFT,
PAGE_SIZE, end_pfn);
init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
start_pfn, end_pfn);
free_bootmem_with_active_regions(nid, end_pfn);
/* Reserve the pgdat and bootmap space with the bootmem allocator */
reserve_bootmem_node(NODE_DATA(nid), start_pfn << PAGE_SHIFT,
sizeof(struct pglist_data), BOOTMEM_DEFAULT);
reserve_bootmem_node(NODE_DATA(nid), free_pfn << PAGE_SHIFT,
reserve_bootmem_node(NODE_DATA(nid), bootmem_paddr,
bootmap_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
/* It's up */

View File

@ -17,9 +17,43 @@
#include <linux/sched.h>
#include <linux/kallsyms.h>
#include <linux/mm.h>
#include <asm/unwinder.h>
#include <asm/ptrace.h>
#include <asm/uaccess.h>
#include <asm/sections.h>
#include <asm/stacktrace.h>
static void backtrace_warning_symbol(void *data, char *msg,
unsigned long symbol)
{
/* Ignore warnings */
}
static void backtrace_warning(void *data, char *msg)
{
/* Ignore warnings */
}
static int backtrace_stack(void *data, char *name)
{
/* Yes, we want all stacks */
return 0;
}
static void backtrace_address(void *data, unsigned long addr, int reliable)
{
unsigned int *depth = data;
if ((*depth)--)
oprofile_add_trace(addr);
}
static struct stacktrace_ops backtrace_ops = {
.warning = backtrace_warning,
.warning_symbol = backtrace_warning_symbol,
.stack = backtrace_stack,
.address = backtrace_address,
};
/* Limit to stop backtracing too far. */
static int backtrace_limit = 20;
@ -47,50 +81,6 @@ user_backtrace(unsigned long *stackaddr, struct pt_regs *regs)
return stackaddr;
}
/*
* | | /\ Higher addresses
* | |
* --------------- stack base (address of current_thread_info)
* | thread info |
* . .
* | stack |
* --------------- saved regs->regs[15] value if valid
* . .
* --------------- struct pt_regs stored on stack (struct pt_regs *)
* | |
* . .
* | |
* --------------- ???
* | |
* | | \/ Lower addresses
*
* Thus, &pt_regs <-> stack base restricts the valid(ish) fp values
*/
static int valid_kernel_stack(unsigned long *stackaddr, struct pt_regs *regs)
{
unsigned long stack = (unsigned long)regs;
unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
return ((unsigned long)stackaddr > stack) && ((unsigned long)stackaddr < stack_base);
}
static unsigned long *
kernel_backtrace(unsigned long *stackaddr, struct pt_regs *regs)
{
unsigned long addr;
/*
* If not a valid kernel address, keep going till we find one
* or the SP stops being a valid address.
*/
do {
addr = *stackaddr++;
oprofile_add_trace(addr);
} while (valid_kernel_stack(stackaddr, regs));
return stackaddr;
}
void sh_backtrace(struct pt_regs * const regs, unsigned int depth)
{
unsigned long *stackaddr;
@ -103,9 +93,9 @@ void sh_backtrace(struct pt_regs * const regs, unsigned int depth)
stackaddr = (unsigned long *)regs->regs[15];
if (!user_mode(regs)) {
while (depth-- && valid_kernel_stack(stackaddr, regs))
stackaddr = kernel_backtrace(stackaddr, regs);
if (depth)
unwind_stack(NULL, regs, stackaddr,
&backtrace_ops, &depth);
return;
}

View File

@ -56,3 +56,4 @@ SH7785LCR SH_SH7785LCR
URQUELL SH_URQUELL
ESPT SH_ESPT
POLARIS SH_POLARIS
KFR2R09 SH_KFR2R09

View File

@ -662,10 +662,11 @@ static irqreturn_t sci_rx_interrupt(int irq, void *port)
static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
{
struct uart_port *port = ptr;
unsigned long flags;
spin_lock_irq(&port->lock);
spin_lock_irqsave(&port->lock, flags);
sci_transmit_chars(port);
spin_unlock_irq(&port->lock);
spin_unlock_irqrestore(&port->lock, flags);
return IRQ_HANDLED;
}

View File

@ -360,16 +360,6 @@ config USB_M66592
default USB_GADGET
select USB_GADGET_SELECTED
config SUPERH_BUILT_IN_M66592
boolean "Enable SuperH built-in USB like the M66592"
depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722
help
SH7722 has USB like the M66592.
The transfer rate is very slow when use "Ethernet Gadget".
However, this problem is improved if change a value of
NET_IP_ALIGN to 4.
#
# Controllers available only in discrete form (and all PCI controllers)
#

Some files were not shown because too many files have changed in this diff Show More