From c601a51af10f714292f42eab45fa8c9154dc1414 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 3 Jul 2009 16:16:54 +0900 Subject: sh: Use bootmem ontop of lmb Rework the bootmem allocator to use the lmb framework. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 + arch/sh/include/asm/lmb.h | 6 ++++ arch/sh/kernel/setup.c | 71 ++++++++++++++++++++++++++++++++++------------- 3 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 arch/sh/include/asm/lmb.h (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index e2bdd7b94fd9..0fb99b0eac5b 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -10,6 +10,7 @@ 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 diff --git a/arch/sh/include/asm/lmb.h b/arch/sh/include/asm/lmb.h new file mode 100644 index 000000000000..9b437f657ffa --- /dev/null +++ b/arch/sh/include/asm/lmb.h @@ -0,0 +1,6 @@ +#ifndef __ASM_SH_LMB_H +#define __ASM_SH_LMB_H + +#define LMB_REAL_LIMIT 0 + +#endif /* __ASM_SH_LMB_H */ diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index dd38338553ef..ceb409bf7741 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -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); - register_bootmem_low_pages(); - - node_set_online(0); + /* 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); + } /* - * 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. + * Add all physical memory to the bootmem map and mark each + * area as present. */ - 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); + register_bootmem_low_pages(); - /* - * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET. - */ - if (CONFIG_ZERO_PAGE_OFFSET != 0) - reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET, + /* 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); + 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(); -- cgit v1.2.3-59-g8ed1b From 79714acbab080ad351acf4bba9a2bbc21d65c93c Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 3 Jul 2009 10:08:05 +0000 Subject: sh: hwblk base implementation This patch is the hwblk base implementation, containing structures and shared functions dealing with hardware blocks. A each processor model should provide a list of hwblks and describe which module stop bit that is associated with each hwblck and how the hwblks are grouped together into areas. The shared code keeps track of the usage count for each hwblk and the areas. Fallback implementations for processor specific code are also kept as weak symbols. The clock framework, the runtime pm code and cpuidle will all tie into this hwblk implementation. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/hwblk.h | 61 +++++++++++++++++++++ arch/sh/kernel/cpu/Makefile | 2 +- arch/sh/kernel/cpu/hwblk.c | 130 ++++++++++++++++++++++++++++++++++++++++++++ arch/sh/kernel/time.c | 2 + 4 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 arch/sh/include/asm/hwblk.h create mode 100644 arch/sh/kernel/cpu/hwblk.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/hwblk.h b/arch/sh/include/asm/hwblk.h new file mode 100644 index 000000000000..51a46f496639 --- /dev/null +++ b/arch/sh/include/asm/hwblk.h @@ -0,0 +1,61 @@ +#ifndef __ASM_SH_HWBLK_H +#define __ASM_SH_HWBLK_H + +#include +#include + +#define HWBLK_AREA_FLAG_PARENT (1 << 0) /* valid parent */ + +#define HWBLK_AREA(_flags, _parent) \ +{ \ + .flags = _flags, \ + .parent = _parent, \ +} + +struct hwblk_area { + unsigned long cnt; + 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; + unsigned long cnt; +}; + +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); + +/* 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 */ diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index eecad7cbd61e..3d6b9312dc47 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile @@ -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 diff --git a/arch/sh/kernel/cpu/hwblk.c b/arch/sh/kernel/cpu/hwblk.c new file mode 100644 index 000000000000..7c3a73deff24 --- /dev/null +++ b/arch/sh/kernel/cpu/hwblk.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_SPINLOCK(hwblk_lock); + +static void hwblk_area_inc(struct hwblk_info *info, int area) +{ + struct hwblk_area *hap = info->areas + area; + + hap->cnt++; + if (hap->cnt == 1) + if (hap->flags & HWBLK_AREA_FLAG_PARENT) + hwblk_area_inc(info, hap->parent); +} + +static void hwblk_area_dec(struct hwblk_info *info, int area) +{ + struct hwblk_area *hap = info->areas + area; + + if (hap->cnt == 1) + if (hap->flags & HWBLK_AREA_FLAG_PARENT) + hwblk_area_dec(info, hap->parent); + hap->cnt--; +} + +static void hwblk_enable(struct hwblk_info *info, int hwblk) +{ + struct hwblk *hp = info->hwblks + hwblk; + unsigned long tmp; + unsigned long flags; + + spin_lock_irqsave(&hwblk_lock, flags); + + hp->cnt++; + if (hp->cnt == 1) { + hwblk_area_inc(info, hp->area); + + tmp = __raw_readl(hp->mstp); + tmp &= ~(1 << hp->bit); + __raw_writel(tmp, hp->mstp); + } + + spin_unlock_irqrestore(&hwblk_lock, flags); +} + +static void hwblk_disable(struct hwblk_info *info, int hwblk) +{ + struct hwblk *hp = info->hwblks + hwblk; + unsigned long tmp; + unsigned long flags; + + spin_lock_irqsave(&hwblk_lock, flags); + + if (hp->cnt == 1) { + hwblk_area_dec(info, hp->area); + + tmp = __raw_readl(hp->mstp); + tmp |= 1 << hp->bit; + __raw_writel(tmp, hp->mstp); + } + hp->cnt--; + + spin_unlock_irqrestore(&hwblk_lock, flags); +} + +static 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; +} diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index 9b352a1e3fb4..d2424b068b7b 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -21,6 +21,7 @@ #include #include #include +#include #include /* Dummy RTC ops */ @@ -96,6 +97,7 @@ void __init time_init(void) if (board_time_init) board_time_init(); + hwblk_init(); clk_init(); rtc_sh_get_time(&xtime); -- cgit v1.2.3-59-g8ed1b From a61c1a636628a28ab5b42a9d36582a8f6a08893a Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 3 Jul 2009 10:15:25 +0000 Subject: sh: hwblk for sh7722 This patch contains the sh7722 specific hwblk implementation. Hwblk ids are added to the processor specific header file, module stop bits and areas are kept track of as hwblks, clocks are converted to make use of the shared hwblk code. Code to determine allowed sleep modes is also added. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/cpu-sh4/cpu/sh7722.h | 14 +++++ arch/sh/kernel/cpu/sh4a/Makefile | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 60 ++++++++++--------- arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c | 106 +++++++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+), 29 deletions(-) create mode 100644 arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c (limited to 'arch/sh') diff --git a/arch/sh/include/cpu-sh4/cpu/sh7722.h b/arch/sh/include/cpu-sh4/cpu/sh7722.h index 738ea43c5038..48560407cbe1 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7722.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7722.h @@ -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__ */ diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index ebdd391d5f42..3cafda696378 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -25,7 +25,7 @@ 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_SH7722) := clock-sh7722.o hwblk-sh7722.o clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7723.o clock-$(CONFIG_CPU_SUBTYPE_SH7724) := clock-sh7724.o clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7366.o diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 40f859354f79..1fa9e1dd1cc8 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include /* SH7722 registers */ #define FRQCR 0xa4150000 @@ -140,35 +142,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), - - MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0), - MSTP("rtc0", &r_clk, MSTPCR1, 8, 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("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), + + SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0), + SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 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 +195,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; } diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c new file mode 100644 index 000000000000..00a1c02d82b1 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c @@ -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 +#include +#include +#include +#include +#include + +/* 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) + return SUSP_SH_STANDBY | SUSP_SH_SF; + + if (!sh7722_hwblk_area[CORE_AREA_BM].cnt) + return SUSP_SH_SLEEP | SUSP_SH_SF; + + return SUSP_SH_SLEEP; +} + +int __init arch_hwblk_init(void) +{ + return hwblk_register(&sh7722_hwblk_info); +} -- cgit v1.2.3-59-g8ed1b From 7426394f20c2e74b7c560bcd266cec1b327a269b Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 3 Jul 2009 10:28:00 +0000 Subject: sh: cpuidle for SuperH Mobile using hwblk This patch adds cpuidle support for SuperH Mobile. The sleep mode selected by cpuidle is compared with the mode selected by the hwblk sleep code and the best allowed mode is entered. At this point "Sleep mode" and "Sleep mode + SF" are supported. This code can easily be extended to support "Software suspend mode", but the assembly code must first be updated to avoid loosing interrupts. Also, update the code to only copy the assembly snippet into internal memory once at bootup. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/suspend.h | 9 +++ arch/sh/kernel/cpu/shmobile/Makefile | 1 + arch/sh/kernel/cpu/shmobile/cpuidle.c | 102 ++++++++++++++++++++++++++++++++++ arch/sh/kernel/cpu/shmobile/pm.c | 26 ++++----- 4 files changed, 125 insertions(+), 13 deletions(-) create mode 100644 arch/sh/kernel/cpu/shmobile/cpuidle.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/suspend.h b/arch/sh/include/asm/suspend.h index b1b995370e79..5c8ea28ff7a4 100644 --- a/arch/sh/include/asm/suspend.h +++ b/arch/sh/include/asm/suspend.h @@ -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 */ diff --git a/arch/sh/kernel/cpu/shmobile/Makefile b/arch/sh/kernel/cpu/shmobile/Makefile index 08bfa7c7db29..e8a5111e848a 100644 --- a/arch/sh/kernel/cpu/shmobile/Makefile +++ b/arch/sh/kernel/cpu/shmobile/Makefile @@ -4,3 +4,4 @@ # Power Management & Sleep mode obj-$(CONFIG_PM) += pm.o sleep.o +obj-$(CONFIG_CPU_IDLE) += cpuidle.o diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c new file mode 100644 index 000000000000..4afdd975cc66 --- /dev/null +++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c @@ -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 +#include +#include +#include +#include +#include +#include +#include + +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); +} diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c index 8c067adf6830..de078d24ce56 100644 --- a/arch/sh/kernel/cpu/shmobile/pm.c +++ b/arch/sh/kernel/cpu/shmobile/pm.c @@ -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; } -- cgit v1.2.3-59-g8ed1b From 5084f61a4d6c9c7bfd3be07fbb5253c1a08cd568 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 3 Jul 2009 23:34:51 +0100 Subject: sh: Use bootmem ontop of lmb for NUMA Like the UP case, use lmb as the foundation of memory resource management on NUMA. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/mm/numa.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c index 095d93bec7cd..9b784fdb947c 100644 --- a/arch/sh/mm/numa.c +++ b/arch/sh/mm/numa.c @@ -9,6 +9,7 @@ */ #include #include +#include #include #include #include @@ -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 */ -- cgit v1.2.3-59-g8ed1b From c63c3105e4991b2991ba73a742b8b59bfdbe4acd Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sun, 5 Jul 2009 02:50:10 +0900 Subject: sh: use kprobes_built_in() for notify_page_fault(). Kill off the KPROBES ifdef, as per x86. Signed-off-by: Paul Mundt --- arch/sh/mm/fault_32.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c index 71925946f1e1..ce75b8882efb 100644 --- a/arch/sh/mm/fault_32.c +++ b/arch/sh/mm/fault_32.c @@ -25,14 +25,12 @@ 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; } -- cgit v1.2.3-59-g8ed1b From 0f60bb25b4036d30fd795709be09626c58c52464 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sun, 5 Jul 2009 03:18:47 +0900 Subject: sh: Tidy up vmalloc fault handling. This rewrites the vmalloc fault handling as per x86, which subsequently allows for easy future tie-in for vmalloc_sync_all(). Signed-off-by: Paul Mundt --- arch/sh/mm/fault_32.c | 153 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 97 insertions(+), 56 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c index ce75b8882efb..08d0117d90fa 100644 --- a/arch/sh/mm/fault_32.c +++ b/arch/sh/mm/fault_32.c @@ -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 @@ -35,6 +35,74 @@ static inline int notify_page_fault(struct pt_regs *regs, int trap) 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 + BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); + + 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(__va((unsigned long)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 @@ -44,6 +112,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; @@ -51,59 +120,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; + mm = tsk->mm; si_code = SEGV_MAPERR; + vec = lookup_exception_vector(); - 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); + /* + * 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; - } - - 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); + if (notify_page_fault(regs, vec)) 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; + goto bad_area_nosemaphore; } - mm = tsk->mm; - - if (unlikely(notify_page_fault(regs, lookup_exception_vector()))) + if (unlikely(notify_page_fault(regs, vec))) return; /* Only enable interrupts if they were on before the fault */ @@ -113,8 +153,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; @@ -130,10 +170,11 @@ 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.. - */ + + /* + * Ok, we have a good vm_area for this memory access, so + * we can handle it.. + */ good_area: si_code = SEGV_ACCERR; if (writeaccess) { @@ -171,10 +212,10 @@ survive: up_read(&mm->mmap_sem); return; -/* - * Something tried to access memory that isn't in our memory map.. - * Fix it, but check if it's kernel or user first.. - */ + /* + * Something tried to access memory that isn't in our memory map.. + * Fix it, but check if it's kernel or user first.. + */ bad_area: up_read(&mm->mmap_sem); -- cgit v1.2.3-59-g8ed1b From ca0d17277fd101ce4878f92b398b6ab71fb2c287 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 28 Jun 2009 12:53:07 +0100 Subject: sh: Fix the value of MCOUNT_INSN_OFFSET It seems that MCOUNT_INSN_OFFSET was calculating the distance between the wrong functions. The value that should have actually been computed is the distance between ftrace_call and ftrace_stub. I discovered this when I added some code to ftrace_caller. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/include/asm/ftrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h index 8fea7d8c8258..b09311ad1db3 100644 --- a/arch/sh/include/asm/ftrace.h +++ b/arch/sh/include/asm/ftrace.h @@ -11,10 +11,10 @@ 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 MCOUNT_INSN_OFFSET ((STUB_ADDR - CALLER_ADDR) >> 1) +#define MCOUNT_INSN_OFFSET ((STUB_ADDR - CALL_ADDR) - 4) struct dyn_arch_ftrace { /* No extra data needed on sh */ -- cgit v1.2.3-59-g8ed1b From c1340c053be7a43d837a3acb352d5008be865a55 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 28 Jun 2009 14:05:44 +0100 Subject: sh: Define HAVE_FUNCTION_TRACE_MCOUNT_TEST Enable HAVE_FUNCTION_TRACE_MCOUNT_TEST and test the value of function_trace_stop from our assembly code as opposed to using the generic C function. This should optimise our mcount/ftrace code path. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 + arch/sh/lib/mcount.S | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index e2bdd7b94fd9..801a4a79ffe3 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -31,6 +31,7 @@ config SUPERH32 select HAVE_FUNCTION_TRACER select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE + select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_ARCH_KGDB select ARCH_HIBERNATION_POSSIBLE if MMU diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S index 110fbfe1831f..cb87ef580b31 100644 --- a/arch/sh/lib/mcount.S +++ b/arch/sh/lib/mcount.S @@ -2,7 +2,7 @@ * arch/sh/lib/mcount.S * * Copyright (C) 2008 Paul Mundt - * Copyright (C) 2008 Matt Fleming + * 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 @@ -35,6 +35,12 @@ .type mcount,@function _mcount: mcount: +#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 @@ -62,6 +68,11 @@ skip_trace: #ifdef CONFIG_DYNAMIC_FTRACE .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 @@ -88,3 +99,7 @@ ftrace_call: ftrace_stub: rts nop + + .align 2 +.Lfunction_trace_stop: + .long function_trace_stop -- cgit v1.2.3-59-g8ed1b From c652d780c9cf7f860141de232b37160fe013feca Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Mon, 6 Jul 2009 20:16:33 +0900 Subject: sh: Add ftrace syscall tracing support Now that I've added TIF_SYSCALL_FTRACE the thread flags do not fit into a single byte any more. Code testing them now needs to be aware of the upper and lower bytes. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 + arch/sh/include/asm/syscall_32.h | 1 + arch/sh/include/asm/thread_info.h | 11 ++++--- arch/sh/kernel/Makefile_32 | 1 + arch/sh/kernel/entry-common.S | 18 ++++++++--- arch/sh/kernel/ftrace.c | 68 +++++++++++++++++++++++++++++++++++++++ arch/sh/kernel/ptrace_32.c | 8 +++++ arch/sh/lib/mcount.S | 2 +- 8 files changed, 100 insertions(+), 10 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 801a4a79ffe3..29e41ec6537d 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -32,6 +32,7 @@ config SUPERH32 select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACE_MCOUNT_TEST + select HAVE_FTRACE_SYSCALLS select HAVE_ARCH_KGDB select ARCH_HIBERNATION_POSSIBLE if MMU diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h index 6f83f2cc45c1..7d80df4f09cb 100644 --- a/arch/sh/include/asm/syscall_32.h +++ b/arch/sh/include/asm/syscall_32.h @@ -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(); diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index f09ac4806294..499e315f4be2 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -97,7 +97,7 @@ static inline struct thread_info *current_thread_info(void) extern struct thread_info *alloc_thread_info(struct task_struct *tsk); extern void free_thread_info(struct thread_info *ti); - + #endif /* THREAD_SHIFT < PAGE_SHIFT */ #endif /* __ASSEMBLY__ */ @@ -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 | \ diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32 index 9411e3e31e68..fee924a9c46c 100644 --- a/arch/sh/kernel/Makefile_32 +++ b/arch/sh/kernel/Makefile_32 @@ -29,6 +29,7 @@ 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_DUMP_CODE) += disassemble.o obj-$(CONFIG_HIBERNATION) += swsusp.o diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index d62359cfbbe2..d62175650c54 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -131,7 +131,7 @@ ENTRY(resume_userspace) nop #endif 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 @@ -163,7 +163,7 @@ work_resched: #endif ! 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 @@ -181,7 +181,7 @@ work_resched: 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 @@ -331,8 +331,12 @@ ENTRY(system_call) ! 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 @@ -359,7 +363,11 @@ syscall_exit: ! 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 diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c index 066f37dc32a9..4f62eced0aec 100644 --- a/arch/sh/kernel/ftrace.c +++ b/arch/sh/kernel/ftrace.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include static unsigned char ftrace_replaced_code[MCOUNT_INSN_SIZE]; @@ -131,3 +133,69 @@ int __init ftrace_dyn_arch_init(void *data) return 0; } + +#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 */ diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 3392e835a374..c198eceaee94 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -34,6 +34,8 @@ #include #include +#include + /* * 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); diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S index cb87ef580b31..71e87f9b4fda 100644 --- a/arch/sh/lib/mcount.S +++ b/arch/sh/lib/mcount.S @@ -72,7 +72,7 @@ ftrace_caller: mov.l @r0, r0 tst r0, r0 bf ftrace_stub - + MCOUNT_ENTER() .globl ftrace_call -- cgit v1.2.3-59-g8ed1b From 2802e34590f290173a3f2aa5a4d662ae5373b420 Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Thu, 9 Jul 2009 14:45:59 +0000 Subject: sh: Clean up linker script using new linker script macros. This patch converts the sh architecture to use the new linker script macros in include/asm-generic/vmlinux.lds.h. Signed-off-by: Tim Abbott Cc: Paul Mundt Cc: Sam Ravnborg Cc: linux-sh@vger.kernel.org Signed-off-by: Paul Mundt --- arch/sh/kernel/vmlinux.lds.S | 87 ++++++-------------------------------------- 1 file changed, 11 insertions(+), 76 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index f53c76acaede..674ed8feb8ae 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -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,14 @@ 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 */ . = 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_begin = .; + INIT_TEXT_SECTION(PAGE_SIZE) + INIT_DATA_SECTION(16) . = ALIGN(4); .machvec.init : AT(ADDR(.machvec.init) - LOAD_OFFSET) { @@ -152,16 +92,11 @@ 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); - _ebss = .; /* uClinux MTD sucks */ - _end = . ; - } + __init_end = .; + BSS(PAGE_SIZE) + . = ALIGN(4); + _ebss = .; /* uClinux MTD sucks */ + _end = . ; /* * When something in the kernel is NOT compiled as a module, the @@ -170,7 +105,7 @@ SECTIONS * it's a module. */ /DISCARD/ : { - *(.exitcall.exit) + EXIT_CALL } STABS_DEBUG -- cgit v1.2.3-59-g8ed1b From b99610fb9cdf390965c62c22322596d961591160 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sat, 11 Jul 2009 01:00:23 +0000 Subject: sh: Provide diagnostic kernel stack checks Enable kernel stack checking code in both the dynamic ftrace and mcount code paths. Check the stack to see if it's overflowing and make sure that the stack pointer contains an address that's either in init_stack or after the bss. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/Kconfig.debug | 11 ++++++ arch/sh/kernel/asm-offsets.c | 1 + arch/sh/lib/mcount.S | 85 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 39224b57c6ef..52a132c24aab 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -123,4 +123,15 @@ config SH64_SR_WATCH bool "Debug: set SR.WATCH to enable hardware watchpoints and trace" depends on SUPERH64 +config STACK_DEBUG + bool "Enable diagnostic checks of the kernel stack" + depends on FUNCTION_TRACER + select DEBUG_STACKOVERFLOW + default n + help + This option allows checks to be performed on the kernel stack + at runtime. Saying Y here will add overhead to every function + call and will therefore incur a major performance hit. Most + users should say N. + endmenu diff --git a/arch/sh/kernel/asm-offsets.c b/arch/sh/kernel/asm-offsets.c index 99aceb28ee24..d218e808294e 100644 --- a/arch/sh/kernel/asm-offsets.c +++ b/arch/sh/kernel/asm-offsets.c @@ -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)); diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S index 71e87f9b4fda..8596483f7b41 100644 --- a/arch/sh/lib/mcount.S +++ b/arch/sh/lib/mcount.S @@ -9,6 +9,8 @@ * for more details. */ #include +#include +#include #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 @@ -41,6 +92,8 @@ mcount: tst r0, r0 bf ftrace_stub #endif + STACK_CHECK() + MCOUNT_ENTER() #ifdef CONFIG_DYNAMIC_FTRACE @@ -73,6 +126,8 @@ ftrace_caller: tst r0, r0 bf ftrace_stub + STACK_CHECK() + MCOUNT_ENTER() .globl ftrace_call @@ -100,6 +155,36 @@ ftrace_stub: rts nop +#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 .Lfunction_trace_stop: .long function_trace_stop +.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 */ -- cgit v1.2.3-59-g8ed1b From 327933f5d6cdf083284d3c06e0370d1de464aef4 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sat, 11 Jul 2009 00:29:03 +0000 Subject: sh: Function graph tracer support Add both dynamic and static function graph tracer support for sh. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 + arch/sh/include/asm/ftrace.h | 3 + arch/sh/kernel/Makefile_32 | 1 + arch/sh/kernel/ftrace.c | 122 ++++++++++++++++++++++++++++++++++++++++ arch/sh/kernel/vmlinux_64.lds.S | 0 arch/sh/lib/Makefile | 1 + arch/sh/lib/mcount.S | 117 +++++++++++++++++++++++++++++++++++++- 7 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 arch/sh/kernel/vmlinux_64.lds.S (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 29e41ec6537d..6d110a4f7f65 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -33,6 +33,7 @@ config SUPERH32 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 diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h index b09311ad1db3..7e0bcc4d4a96 100644 --- a/arch/sh/include/asm/ftrace.h +++ b/arch/sh/include/asm/ftrace.h @@ -13,8 +13,11 @@ extern void mcount(void); #ifdef CONFIG_DYNAMIC_FTRACE #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 - CALL_ADDR) - 4) +#define GRAPH_INSN_OFFSET ((CALLER_ADDR - GRAPH_ADDR) - 4) struct dyn_arch_ftrace { /* No extra data needed on sh */ diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32 index fee924a9c46c..94ed99b68002 100644 --- a/arch/sh/kernel/Makefile_32 +++ b/arch/sh/kernel/Makefile_32 @@ -30,6 +30,7 @@ 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 diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c index 4f62eced0aec..6647dfcb781d 100644 --- a/arch/sh/kernel/ftrace.c +++ b/arch/sh/kernel/ftrace.c @@ -16,11 +16,13 @@ #include #include #include +#include #include #include #include #include +#ifdef CONFIG_DYNAMIC_FTRACE static unsigned char ftrace_replaced_code[MCOUNT_INSN_SIZE]; static unsigned char ftrace_nop[4]; @@ -133,6 +135,126 @@ 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(¤t->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 diff --git a/arch/sh/kernel/vmlinux_64.lds.S b/arch/sh/kernel/vmlinux_64.lds.S new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile index aaea580b65bb..19328d90a2d1 100644 --- a/arch/sh/lib/Makefile +++ b/arch/sh/lib/Makefile @@ -25,6 +25,7 @@ memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o lib-$(CONFIG_MMU) += copy_page.o clear_page.o lib-$(CONFIG_FUNCTION_TRACER) += mcount.o +lib-$(CONFIG_FUNCTION_GRAPH_TRACER) += mcount.o lib-y += $(memcpy-y) $(udivsi3-y) EXTRA_CFLAGS += -Werror diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S index 8596483f7b41..bd3ec648becc 100644 --- a/arch/sh/lib/mcount.S +++ b/arch/sh/lib/mcount.S @@ -111,14 +111,62 @@ 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() .align 2 .Lftrace_trace_function: - .long ftrace_trace_function + .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 @@ -136,7 +184,12 @@ 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 */ /* @@ -188,3 +241,65 @@ stack_panic: .Lpanic_str: .string "Stack error" #endif /* CONFIG_STACK_DEBUG */ + +#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 */ -- cgit v1.2.3-59-g8ed1b From 7816fecd03e480ed0b47d674ed772ca0b45e1b5e Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sat, 11 Jul 2009 00:29:04 +0000 Subject: sh: Mark __switch_to() as __notrace_funcgraph Annotate __switch_to() so that the function graph tracer does not try to trace it. Use __notrace_funcgraph, as opposed to notrace, so that other tracers can continue to trace __switch_to(). The reason that we don't want to trace __switch_to() with the function graph tracer is because of how the return address stack in task_struct is implemented. When we enter __switch_to we store the real return address on prev's ret_stack. When we return from __switch_to() we've patched the return address on the kernel stack to be return_to_handler. Calling return_to_handler we do, -> ftrace_return_to_handler() -> ftrace_pop_return_ftrace() Which tries to pop the real return address from current->ret_stack. The problem being that we stored the return address on prev->ret_stack, but current now points to next, and next->ret_stack doesn't contain the correct return address (and is possibly even empty). Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/kernel/process_32.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 92d7740faab1..9fee977f176b 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -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)); -- cgit v1.2.3-59-g8ed1b From 473d1cf4ee623b043790838bcf77e77958840bf2 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 11 Jul 2009 19:56:58 +0900 Subject: sh: Decouple mcount from ftrace. This adds a general CONFIG_MCOUNT in order to permit mcount generation without ftrace support. This is primarily for allowing platforms to enable aggressive stack overflow checking without having to enable ftrace support. Based on the sparc64 implementation. Signed-off-by: Paul Mundt --- arch/sh/Kconfig.debug | 5 +++++ arch/sh/Makefile | 4 ++++ arch/sh/boot/compressed/Makefile | 2 +- arch/sh/kernel/sh_ksyms_32.c | 2 +- arch/sh/lib/Makefile | 3 +-- 5 files changed, 12 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 52a132c24aab..75b5f4e06670 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -134,4 +134,9 @@ config STACK_DEBUG call and will therefore incur a major performance hit. Most users should say N. +config MCOUNT + def_bool y + depends on SUPERH32 + depends on STACK_DEBUG || FUNCTION_TRACER + endmenu diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 75d049b03f7e..52c34bf56962 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -186,6 +186,10 @@ KBUILD_CFLAGS += -pipe $(cflags-y) KBUILD_CPPFLAGS += $(cflags-y) KBUILD_AFLAGS += $(cflags-y) +ifeq ($(CONFIG_MCOUNT),y) + KBUILD_CFLAGS += -pg +endif + libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index 9531bf1b7c2f..3af239cb9b0d 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -23,7 +23,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 diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c index fcc5de31f83b..5b81116046c1 100644 --- a/arch/sh/kernel/sh_ksyms_32.c +++ b/arch/sh/kernel/sh_ksyms_32.c @@ -106,7 +106,7 @@ EXPORT_SYMBOL(flush_dcache_page); EXPORT_SYMBOL(clear_user_page); #endif -#ifdef CONFIG_FUNCTION_TRACER +#ifdef CONFIG_MCOUNT EXPORT_SYMBOL(mcount); #endif EXPORT_SYMBOL(csum_partial); diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile index 19328d90a2d1..c2b28d8b2dd1 100644 --- a/arch/sh/lib/Makefile +++ b/arch/sh/lib/Makefile @@ -24,8 +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_FUNCTION_GRAPH_TRACER) += mcount.o +lib-$(CONFIG_MCOUNT) += mcount.o lib-y += $(memcpy-y) $(udivsi3-y) EXTRA_CFLAGS += -Werror -- cgit v1.2.3-59-g8ed1b From 9f14b84afda297d301b81a5bcbd65e83d7b02034 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 11 Jul 2009 20:05:34 +0900 Subject: sh: Replace DEBUG_STACKOVERFLOW with STACK_DEBUG. STACK_DEBUG ties in to mcount in order to do function-granular stack overflow checks as opposed to lazily checking from IRQ context. As the default is nohz, the frequency of overflow checking is too irregular to catch much useful information, and so the mcount approach employed by sparc64 is adopted instead. This kills off the old check entirely from the do_IRQ() path and now adopts CONFIG_MCOUNT instead. Signed-off-by: Paul Mundt --- arch/sh/Kconfig.debug | 17 ++++------------- arch/sh/kernel/irq.c | 17 ----------------- 2 files changed, 4 insertions(+), 30 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 75b5f4e06670..b440fd936714 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -61,12 +61,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" @@ -123,17 +125,6 @@ config SH64_SR_WATCH bool "Debug: set SR.WATCH to enable hardware watchpoints and trace" depends on SUPERH64 -config STACK_DEBUG - bool "Enable diagnostic checks of the kernel stack" - depends on FUNCTION_TRACER - select DEBUG_STACKOVERFLOW - default n - help - This option allows checks to be performed on the kernel stack - at runtime. Saying Y here will add overhead to every function - call and will therefore incur a major performance hit. Most - users should say N. - config MCOUNT def_bool y depends on SUPERH32 diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 3d09062f4682..278c68c60488 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -114,23 +114,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 -- cgit v1.2.3-59-g8ed1b From fe27932052aebf77ac5f3e73962825d2aeb457a0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 11 Jul 2009 20:32:14 +0900 Subject: sh: Use DECLARE_EXPORT() for mcount symbol export. The function prototype for mcount is not defined if we are not building with ftrace support enabled, so use DECLARE_EXPORT() to stub one in. Signed-off-by: Paul Mundt --- arch/sh/kernel/sh_ksyms_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c index 5b81116046c1..cec610888e28 100644 --- a/arch/sh/kernel/sh_ksyms_32.c +++ b/arch/sh/kernel/sh_ksyms_32.c @@ -107,7 +107,7 @@ EXPORT_SYMBOL(clear_user_page); #endif #ifdef CONFIG_MCOUNT -EXPORT_SYMBOL(mcount); +DECLARE_EXPORT(mcount); #endif EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(csum_partial_copy_generic); -- cgit v1.2.3-59-g8ed1b From a470b95e99ea77ef1e307ff181e59a4a16caa4f4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 11 Jul 2009 20:33:34 +0900 Subject: sh: Fix up ftrace build error when STACK_DEBUG=n. Presently the closest reference to function_trace_stop is within a CONFIG_STACK_DEBUG block. When this is turned off, the build bails out with a pcrel too far error. Reorder things a bit to handle the various combinations. Signed-off-by: Paul Mundt --- arch/sh/lib/mcount.S | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S index bd3ec648becc..9e397aafc165 100644 --- a/arch/sh/lib/mcount.S +++ b/arch/sh/lib/mcount.S @@ -192,6 +192,10 @@ ftrace_call: #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 @@ -199,7 +203,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 @@ -223,8 +226,6 @@ stack_panic: nop .align 2 -.Lfunction_trace_stop: - .long function_trace_stop .L_ebss: .long _ebss .L_init_thread_union: -- cgit v1.2.3-59-g8ed1b From e460ab27b6c3ea313762169713086529d5bfb8bc Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 11 Jul 2009 21:06:53 +0900 Subject: sh: Fix up stack overflow check with ftrace disabled. Presently the STACK_CHECK() code is called in to multiple times, although it's only necessary from the mcount entry. The code still attempts to treat the nop case as an ftrace path resulting in superfluous code flow for the case where ftrace is disabled. And finally, this also fixes up references to a few undefined symbols when FUNCTION_TRACER=n. Signed-off-by: Paul Mundt --- arch/sh/lib/mcount.S | 76 +++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 36 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S index 9e397aafc165..84a57761f17e 100644 --- a/arch/sh/lib/mcount.S +++ b/arch/sh/lib/mcount.S @@ -1,7 +1,7 @@ /* * arch/sh/lib/mcount.S * - * Copyright (C) 2008 Paul Mundt + * 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 @@ -86,13 +86,18 @@ .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 - STACK_CHECK() MCOUNT_ENTER() @@ -174,8 +179,6 @@ ftrace_caller: tst r0, r0 bf ftrace_stub - STACK_CHECK() - MCOUNT_ENTER() .globl ftrace_call @@ -211,38 +214,6 @@ ftrace_stub: rts nop -#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 */ - #ifdef CONFIG_FUNCTION_GRAPH_TRACER .globl ftrace_graph_caller ftrace_graph_caller: @@ -304,3 +275,36 @@ return_to_handler: .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 */ -- cgit v1.2.3-59-g8ed1b From df8ce2595fbac8b046322fce9df61ce1cf8ddf62 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sun, 12 Jul 2009 01:37:30 +0900 Subject: sh: Tidy up gzip-based zImage decompression. This brings the zImage handling in to the current century, in preparation for handling the other compression types. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 + arch/sh/boot/compressed/misc_32.c | 106 ++++--------------------------- arch/sh/boot/compressed/misc_64.c | 127 +++----------------------------------- 3 files changed, 19 insertions(+), 215 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 120bd31a46ea..9f531ca3c8ea 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -17,6 +17,7 @@ config SUPERH select HAVE_ARCH_TRACEHOOK select HAVE_DMA_API_DEBUG select HAVE_PERF_COUNTERS + select HAVE_KERNEL_GZIP select RTC_LIB select GENERIC_ATOMIC64 help diff --git a/arch/sh/boot/compressed/misc_32.c b/arch/sh/boot/compressed/misc_32.c index efdba6b29572..1ab4f49153be 100644 --- a/arch/sh/boot/compressed/misc_32.c +++ b/arch/sh/boot/compressed/misc_32.c @@ -14,73 +14,23 @@ #include #include #include -#ifdef CONFIG_SH_STANDARD_BIOS #include -#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 unsigned char *output; static void error(char *m); @@ -93,7 +43,9 @@ static unsigned long free_mem_end_ptr; #define HEAP_SIZE 0x10000 -#include "../../../../lib/inflate.c" +#ifdef CONFIG_KERNEL_GZIP +#include "../../../../lib/decompress_inflate.c" +#endif #ifdef CONFIG_SH_STANDARD_BIOS size_t strlen(const char *s) @@ -138,44 +90,6 @@ void* memcpy(void* __dest, __const void* __src, 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"); @@ -191,16 +105,18 @@ long* stack_start = &user_stack[STACK_SIZE]; void decompress_kernel(void) { - output_data = NULL; - output_ptr = PHYSADDR((unsigned long)&_text+PAGE_SIZE); + unsigned long output_addr; + + output_addr = PHYSADDR((unsigned long)&_text+PAGE_SIZE); #ifdef CONFIG_29BIT - output_ptr |= P2SEG; + output_addr |= P2SEG; #endif + + output = (unsigned char *)output_addr; free_mem_ptr = (unsigned long)&_end; free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; - makecrc(); puts("Uncompressing Linux... "); - gunzip(); + decompress(input_data, input_len, NULL, NULL, output, NULL, error); puts("Ok, booting the kernel.\n"); } diff --git a/arch/sh/boot/compressed/misc_64.c b/arch/sh/boot/compressed/misc_64.c index 2941657e18aa..0c6894e37115 100644 --- a/arch/sh/boot/compressed/misc_64.c +++ b/arch/sh/boot/compressed/misc_64.c @@ -20,67 +20,18 @@ 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 unsigned char *output_data; static void puts(const char *); @@ -91,7 +42,9 @@ static unsigned long free_mem_end_ptr; #define HEAP_SIZE 0x10000 -#include "../../../../lib/inflate.c" +#ifdef CONFIG_KERNEL_GZIP +#include "../../../../lib/decompress_inflate.c" +#endif void puts(const char *s) { @@ -117,45 +70,6 @@ void *memcpy(void *__dest, __const void *__src, size_t __n) 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"); @@ -171,40 +85,13 @@ long *stack_start = &user_stack[STACK_SIZE]; void decompress_kernel(void) { - output_data = (uch *) (CONFIG_MEMORY_START + 0x2000); + output_data = (unsigned char *) (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"); - + decompress(input_data, input_len, NULL, NULL, output_data, NULL, error); cache_control(CACHE_DISABLE); + puts("Ok, booting the kernel.\n"); } -- cgit v1.2.3-59-g8ed1b From 07e88e1bfc128681a80578724fde6a872f413862 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 11 Jul 2009 13:21:19 -0400 Subject: sh: bzip2/lzma zImage support. This plugs in bzip2 and lzma support for zImages. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 2 ++ arch/sh/boot/compressed/.gitignore | 1 + arch/sh/boot/compressed/Makefile | 19 ++++++++++++++++--- arch/sh/boot/compressed/misc_32.c | 14 +++++++++++++- arch/sh/boot/compressed/misc_64.c | 14 +++++++++++++- arch/sh/boot/compressed/piggy.S | 8 -------- arch/sh/boot/compressed/vmlinux.scr | 10 ++++++++++ 7 files changed, 55 insertions(+), 13 deletions(-) create mode 100644 arch/sh/boot/compressed/.gitignore delete mode 100644 arch/sh/boot/compressed/piggy.S create mode 100644 arch/sh/boot/compressed/vmlinux.scr (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 9f531ca3c8ea..c4a955d25451 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -18,6 +18,8 @@ config SUPERH 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 diff --git a/arch/sh/boot/compressed/.gitignore b/arch/sh/boot/compressed/.gitignore new file mode 100644 index 000000000000..2374a83d87b2 --- /dev/null +++ b/arch/sh/boot/compressed/.gitignore @@ -0,0 +1 @@ +vmlinux.bin.* diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index 9531bf1b7c2f..0a4e7af8a71b 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -5,6 +5,7 @@ # targets := vmlinux vmlinux.bin vmlinux.bin.gz \ + vmlinux.bin.bz2 vmlinux.bin.lzma \ head_$(BITS).o misc_$(BITS).o piggy.o OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc_$(BITS).o $(obj)/cache.o @@ -38,10 +39,22 @@ $(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) + +suffix-$(CONFIG_KERNEL_GZIP) := gz +suffix-$(CONFIG_KERNEL_BZIP2) := bz2 +suffix-$(CONFIG_KERNEL_LZMA) := 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) diff --git a/arch/sh/boot/compressed/misc_32.c b/arch/sh/boot/compressed/misc_32.c index 1ab4f49153be..b86e3596918b 100644 --- a/arch/sh/boot/compressed/misc_32.c +++ b/arch/sh/boot/compressed/misc_32.c @@ -41,12 +41,24 @@ extern int _end; static unsigned long free_mem_ptr; static unsigned long free_mem_end_ptr; -#define HEAP_SIZE 0x10000 +#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) { diff --git a/arch/sh/boot/compressed/misc_64.c b/arch/sh/boot/compressed/misc_64.c index 0c6894e37115..09b7b7cd24f9 100644 --- a/arch/sh/boot/compressed/misc_64.c +++ b/arch/sh/boot/compressed/misc_64.c @@ -40,12 +40,24 @@ extern int _end; static unsigned long free_mem_ptr; static unsigned long free_mem_end_ptr; -#define HEAP_SIZE 0x10000 +#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 + void puts(const char *s) { } diff --git a/arch/sh/boot/compressed/piggy.S b/arch/sh/boot/compressed/piggy.S deleted file mode 100644 index 566071926b13..000000000000 --- a/arch/sh/boot/compressed/piggy.S +++ /dev/null @@ -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 diff --git a/arch/sh/boot/compressed/vmlinux.scr b/arch/sh/boot/compressed/vmlinux.scr new file mode 100644 index 000000000000..f02382ae5c48 --- /dev/null +++ b/arch/sh/boot/compressed/vmlinux.scr @@ -0,0 +1,10 @@ +SECTIONS +{ + .rodata.compressed : { + input_len = .; + LONG(input_data_end - input_data) input_data = .; + *(.data) + output_len = . - 4; + input_data_end = .; + } +} -- cgit v1.2.3-59-g8ed1b From b14c6d428a54fb3235e69fd78fba9080c96645be Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 11 Jul 2009 13:30:38 -0400 Subject: sh: Consolidate the sh64 changes in arch/sh/boot/compressed/misc_32.c This makes some minor changes to misc_32.c so that it can be used by sh64. Signed-off-by: Paul Mundt --- arch/sh/boot/compressed/misc_32.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boot/compressed/misc_32.c b/arch/sh/boot/compressed/misc_32.c index b86e3596918b..4eb27e61f8e3 100644 --- a/arch/sh/boot/compressed/misc_32.c +++ b/arch/sh/boot/compressed/misc_32.c @@ -26,7 +26,10 @@ #undef memcpy #define memzero(s, n) memset ((s), 0, (n)) -static void error(char *m); +/* cache.c */ +#define CACHE_ENABLE 0 +#define CACHE_DISABLE 1 +int cache_control(unsigned int command); extern char input_data[]; extern int input_len; @@ -111,9 +114,15 @@ static void error(char *x) while(1); /* Halt */ } +#ifdef CONFIG_SUPERH64 +#define stackalign 8 +#else +#define stackalign 4 +#endif + #define STACK_SIZE (4096) -long user_stack [STACK_SIZE]; -long* stack_start = &user_stack[STACK_SIZE]; +long __attribute__ ((aligned(stackalign))) user_stack[STACK_SIZE]; +long *stack_start = &user_stack[STACK_SIZE]; void decompress_kernel(void) { @@ -129,6 +138,8 @@ void decompress_kernel(void) 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"); } -- cgit v1.2.3-59-g8ed1b From 59f002964f4e6668a0132cd796b82f7f8a4803f0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 11 Jul 2009 13:32:24 -0400 Subject: sh: rename arch/sh/boot/compressed/misc_32.c -> misc.c This is now used by both sh64 and regular sh, kill off the old sh64 version now too. Signed-off-by: Paul Mundt --- arch/sh/boot/compressed/Makefile | 4 +- arch/sh/boot/compressed/misc.c | 145 ++++++++++++++++++++++++++++++++++++++ arch/sh/boot/compressed/misc_32.c | 145 -------------------------------------- arch/sh/boot/compressed/misc_64.c | 109 ---------------------------- 4 files changed, 147 insertions(+), 256 deletions(-) create mode 100644 arch/sh/boot/compressed/misc.c delete mode 100644 arch/sh/boot/compressed/misc_32.c delete mode 100644 arch/sh/boot/compressed/misc_64.c (limited to 'arch/sh') diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index 0a4e7af8a71b..3324019e207e 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -6,9 +6,9 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz \ vmlinux.bin.bz2 vmlinux.bin.lzma \ - head_$(BITS).o misc_$(BITS).o piggy.o + 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 diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c new file mode 100644 index 000000000000..4eb27e61f8e3 --- /dev/null +++ b/arch/sh/boot/compressed/misc.c @@ -0,0 +1,145 @@ +/* + * 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 +#include +#include +#include + +/* + * 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 -#include -#include -#include - -/* - * 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 - -/* cache.c */ -#define CACHE_ENABLE 0 -#define CACHE_DISABLE 1 -int cache_control(unsigned int command); - -/* - * gzip declarations - */ - -#define STATIC static - -#undef memset -#undef memcpy -#define memzero(s, n) memset ((s), 0, (n)) - -static void error(char *m); - -extern char input_data[]; -extern int input_len; - -static unsigned char *output_data; - -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; - -#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 - -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; -} - -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 = (unsigned char *) (CONFIG_MEMORY_START + 0x2000); - 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_data, NULL, error); - cache_control(CACHE_DISABLE); - puts("Ok, booting the kernel.\n"); -} -- cgit v1.2.3-59-g8ed1b From 040f43e0bf70935cbe8a775110206d11367e11db Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 11 Jul 2009 13:36:25 -0400 Subject: sh64: Don't use PHYSADDR() for output_addr calculation. Opencode the MEMORY_START offset directly, sh64 uses a slightly different calculation. Signed-off-by: Paul Mundt --- arch/sh/boot/compressed/misc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c index 4eb27e61f8e3..fd56a71ca9d9 100644 --- a/arch/sh/boot/compressed/misc.c +++ b/arch/sh/boot/compressed/misc.c @@ -128,9 +128,13 @@ 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; -- cgit v1.2.3-59-g8ed1b From 05dd2cd3bb3299540e33ff60c5b401dd88f273bd Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Mon, 13 Jul 2009 11:38:04 +0000 Subject: sh: Restore previous behaviour on kernel fault The last commit changed the behaviour on kernel faults when we were doing something other than syncing the page tables. vmalloc_sync_one() needs to return NULL if the page tables are up to date, because the reason for the fault was not a missing/inconsitent page table entry. By returning NULL if the page tables are sync'd we signal to the calling function that further work must be done to resolve this fault. Also, remove the superfluous __va() around the first argument to vmalloc_sync_one(). The value of pgd_k is already a virtual address and using it wth __va() causes a NULL dereference. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/mm/fault_32.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c index 08d0117d90fa..dbbdeba2cee5 100644 --- a/arch/sh/mm/fault_32.c +++ b/arch/sh/mm/fault_32.c @@ -60,8 +60,15 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) if (!pmd_present(*pmd)) set_pmd(pmd, *pmd_k); - else + 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; } @@ -87,7 +94,7 @@ static noinline int vmalloc_fault(unsigned long address) * an interrupt in the middle of a task switch.. */ pgd_k = get_TTB(); - pmd_k = vmalloc_sync_one(__va((unsigned long)pgd_k), address); + pmd_k = vmalloc_sync_one(pgd_k, address); if (!pmd_k) return -1; -- cgit v1.2.3-59-g8ed1b From 72849873cdf213b5d7b8ae006e6740b2d78f6ad8 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 14 Jul 2009 06:51:54 -0400 Subject: sh: Kill off zero-sized vmlinux_64.lds.S This seems to be some merge damage, kill it off. Signed-off-by: Paul Mundt --- arch/sh/kernel/vmlinux_64.lds.S | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 arch/sh/kernel/vmlinux_64.lds.S (limited to 'arch/sh') diff --git a/arch/sh/kernel/vmlinux_64.lds.S b/arch/sh/kernel/vmlinux_64.lds.S deleted file mode 100644 index e69de29bb2d1..000000000000 -- cgit v1.2.3-59-g8ed1b From 0f8ee1874fa80899debc0a0670e2bed0a28d2548 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 17 Jul 2009 14:24:55 +0000 Subject: sh: Add support for multiple hwblk counters Extend the SuperH hwblk code to support more than one counter. Contains ground work for the future Runtime PM implementation. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/hwblk.h | 13 ++++++- arch/sh/kernel/cpu/hwblk.c | 69 +++++++++++++++++++++++----------- arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c | 4 +- 3 files changed, 60 insertions(+), 26 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/hwblk.h b/arch/sh/include/asm/hwblk.h index 51a46f496639..c01d72cb6757 100644 --- a/arch/sh/include/asm/hwblk.h +++ b/arch/sh/include/asm/hwblk.h @@ -4,6 +4,9 @@ #include #include +#define HWBLK_CNT_USAGE 0 +#define HWBLK_CNT_NR 1 + #define HWBLK_AREA_FLAG_PARENT (1 << 0) /* valid parent */ #define HWBLK_AREA(_flags, _parent) \ @@ -13,7 +16,7 @@ } struct hwblk_area { - unsigned long cnt; + int cnt[HWBLK_CNT_NR]; unsigned char parent; unsigned char flags; }; @@ -29,7 +32,7 @@ struct hwblk { void __iomem *mstp; unsigned char bit; unsigned char area; - unsigned long cnt; + int cnt[HWBLK_CNT_NR]; }; struct hwblk_info { @@ -46,6 +49,12 @@ 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) \ { \ diff --git a/arch/sh/kernel/cpu/hwblk.c b/arch/sh/kernel/cpu/hwblk.c index 7c3a73deff24..c0ad7d46e784 100644 --- a/arch/sh/kernel/cpu/hwblk.c +++ b/arch/sh/kernel/cpu/hwblk.c @@ -9,38 +9,64 @@ static DEFINE_SPINLOCK(hwblk_lock); -static void hwblk_area_inc(struct hwblk_info *info, int area) +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++; - if (hap->cnt == 1) - if (hap->flags & HWBLK_AREA_FLAG_PARENT) - hwblk_area_inc(info, hap->parent); + 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 void hwblk_area_dec(struct hwblk_info *info, int area) + +static int __hwblk_mod_cnt(struct hwblk_info *info, int hwblk, + int counter, int value, int goal) { - struct hwblk_area *hap = info->areas + area; + 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); - if (hap->cnt == 1) - if (hap->flags & HWBLK_AREA_FLAG_PARENT) - hwblk_area_dec(info, hap->parent); - hap->cnt--; + return hp->cnt[counter]; } -static void hwblk_enable(struct hwblk_info *info, int hwblk) +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); - hp->cnt++; - if (hp->cnt == 1) { - hwblk_area_inc(info, hp->area); - + 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); @@ -49,27 +75,26 @@ static void hwblk_enable(struct hwblk_info *info, int hwblk) spin_unlock_irqrestore(&hwblk_lock, flags); } -static void hwblk_disable(struct hwblk_info *info, int hwblk) +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); - if (hp->cnt == 1) { - hwblk_area_dec(info, hp->area); - + 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); } - hp->cnt--; spin_unlock_irqrestore(&hwblk_lock, flags); } -static struct hwblk_info *hwblk_info; +struct hwblk_info *hwblk_info; int __init hwblk_register(struct hwblk_info *info) { diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c index 00a1c02d82b1..a288b5d92341 100644 --- a/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c @@ -91,10 +91,10 @@ static struct hwblk_info sh7722_hwblk_info = { int arch_hwblk_sleep_mode(void) { - if (!sh7722_hwblk_area[CORE_AREA].cnt) + 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) + if (!sh7722_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE]) return SUSP_SH_SLEEP | SUSP_SH_SF; return SUSP_SH_SLEEP; -- cgit v1.2.3-59-g8ed1b From 2094e504a7489a2d774d544592360e578d9325f8 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 17 Jul 2009 14:43:38 +0000 Subject: sh: hwblk support for sh7723 This patch adds hwblk support for the sh7723 processor. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/cpu-sh4/cpu/sh7723.h | 17 +++++ arch/sh/kernel/cpu/sh4a/Makefile | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 110 ++++++++++++++++--------------- arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c | 117 +++++++++++++++++++++++++++++++++ 4 files changed, 193 insertions(+), 53 deletions(-) create mode 100644 arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c (limited to 'arch/sh') diff --git a/arch/sh/include/cpu-sh4/cpu/sh7723.h b/arch/sh/include/cpu-sh4/cpu/sh7723.h index 14c8ca936781..9b36fae72324 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7723.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7723.h @@ -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__ */ diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index 3cafda696378..1d7ae38bc611 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -26,7 +26,7 @@ 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 hwblk-sh7722.o -clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7723.o +clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7723.o hwblk-sh7723.o clock-$(CONFIG_CPU_SUBTYPE_SH7724) := clock-sh7724.o clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7366.o clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index e67c2678b8ae..bf64c78eee34 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include /* SH7723 registers */ #define FRQCR 0xa4150000 @@ -140,60 +142,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), - - MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0, 1, 0), - MSTP("rtc0", &r_clk, MSTPCR1, 8, 0, 0, 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("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), + + SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0), + SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0), + + 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 +222,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; } diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c new file mode 100644 index 000000000000..a7f4684d2032 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c @@ -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 +#include +#include +#include +#include +#include + +/* 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); +} -- cgit v1.2.3-59-g8ed1b From 719a72b7c75bb239ca6184190ab994b71a31c6dc Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 17 Jul 2009 14:59:55 +0000 Subject: usb: r8a66597-hcd platform data on_chip support Convert the r8a66597-hcd driver to use the on_chip flag from platform data to enable on chip behaviour instead of relying on CONFIG_SUPERH_ON_CHIP_R8A66597 ugliness. This makes the code cleaner and also allows us to support both external and internal r8a66597 with the same kernel. It also makes the Kconfig part more future proof since we with this patch can add support for new processors with on-chip r8a66597 without modifying the Kconfig. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7724/setup.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 2 +- drivers/usb/host/Kconfig | 7 -- drivers/usb/host/r8a66597-hcd.c | 187 +++++++++++++++++++-------------- drivers/usb/host/r8a66597.h | 76 ++++++-------- include/linux/usb/r8a66597.h | 3 + 7 files changed, 147 insertions(+), 131 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 8fed45a2fb85..4fb7e48e2843 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -304,6 +304,7 @@ static struct platform_device sh_eth_device = { }; static struct r8a66597_platdata sh7724_usb0_host_data = { + .on_chip = 1, }; static struct resource sh7724_usb0_host_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index c18f7d09281b..f6d208813564 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -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[] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index e1bb80b2a27b..28516499a2c4 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -398,7 +398,7 @@ static struct platform_device rtc_device = { }; static struct r8a66597_platdata r8a66597_data = { - /* This set zero to all members */ + .on_chip = 1, }; static struct resource sh7723_usb_host_resources[] = { diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 1a920c70b5a1..f21ca7d27a43 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -336,13 +336,6 @@ config USB_R8A66597_HCD To compile this driver as a module, choose M here: the module will be called r8a66597-hcd. -config SUPERH_ON_CHIP_R8A66597 - boolean "Enable SuperH on-chip R8A66597 USB" - depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7724) - help - This driver enables support for the on-chip R8A66597 in the - SH7366, SH7723 and SH7724 processors. - config USB_WHCI_HCD tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)" depends on EXPERIMENTAL diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 09895a97c10b..82dce3e0d4d7 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -91,43 +91,43 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597) u16 tmp; int i = 0; -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) -#if defined(CONFIG_HAVE_CLK) - clk_enable(r8a66597->clk); + if (r8a66597->pdata->on_chip) { +#ifdef CONFIG_HAVE_CLK + clk_enable(r8a66597->clk); #endif - do { - r8a66597_write(r8a66597, SCKE, SYSCFG0); - tmp = r8a66597_read(r8a66597, SYSCFG0); - if (i++ > 1000) { - printk(KERN_ERR "r8a66597: register access fail.\n"); - return -ENXIO; - } - } while ((tmp & SCKE) != SCKE); - r8a66597_write(r8a66597, 0x04, 0x02); -#else - do { - r8a66597_write(r8a66597, USBE, SYSCFG0); - tmp = r8a66597_read(r8a66597, SYSCFG0); - if (i++ > 1000) { - printk(KERN_ERR "r8a66597: register access fail.\n"); - return -ENXIO; - } - } while ((tmp & USBE) != USBE); - r8a66597_bclr(r8a66597, USBE, SYSCFG0); - r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata), XTAL, - SYSCFG0); + do { + r8a66597_write(r8a66597, SCKE, SYSCFG0); + tmp = r8a66597_read(r8a66597, SYSCFG0); + if (i++ > 1000) { + printk(KERN_ERR "r8a66597: reg access fail.\n"); + return -ENXIO; + } + } while ((tmp & SCKE) != SCKE); + r8a66597_write(r8a66597, 0x04, 0x02); + } else { + do { + r8a66597_write(r8a66597, USBE, SYSCFG0); + tmp = r8a66597_read(r8a66597, SYSCFG0); + if (i++ > 1000) { + printk(KERN_ERR "r8a66597: reg access fail.\n"); + return -ENXIO; + } + } while ((tmp & USBE) != USBE); + r8a66597_bclr(r8a66597, USBE, SYSCFG0); + r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata), + XTAL, SYSCFG0); - i = 0; - r8a66597_bset(r8a66597, XCKE, SYSCFG0); - do { - msleep(1); - tmp = r8a66597_read(r8a66597, SYSCFG0); - if (i++ > 500) { - printk(KERN_ERR "r8a66597: register access fail.\n"); - return -ENXIO; - } - } while ((tmp & SCKE) != SCKE); -#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */ + i = 0; + r8a66597_bset(r8a66597, XCKE, SYSCFG0); + do { + msleep(1); + tmp = r8a66597_read(r8a66597, SYSCFG0); + if (i++ > 500) { + printk(KERN_ERR "r8a66597: reg access fail.\n"); + return -ENXIO; + } + } while ((tmp & SCKE) != SCKE); + } return 0; } @@ -136,15 +136,16 @@ static void r8a66597_clock_disable(struct r8a66597 *r8a66597) { r8a66597_bclr(r8a66597, SCKE, SYSCFG0); udelay(1); -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) -#if defined(CONFIG_HAVE_CLK) - clk_disable(r8a66597->clk); -#endif -#else - r8a66597_bclr(r8a66597, PLLC, SYSCFG0); - r8a66597_bclr(r8a66597, XCKE, SYSCFG0); - r8a66597_bclr(r8a66597, USBE, SYSCFG0); + + if (r8a66597->pdata->on_chip) { +#ifdef CONFIG_HAVE_CLK + clk_disable(r8a66597->clk); #endif + } else { + r8a66597_bclr(r8a66597, PLLC, SYSCFG0); + r8a66597_bclr(r8a66597, XCKE, SYSCFG0); + r8a66597_bclr(r8a66597, USBE, SYSCFG0); + } } static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port) @@ -205,7 +206,7 @@ static int enable_controller(struct r8a66597 *r8a66597) r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1); - for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) + for (port = 0; port < r8a66597->max_root_hub; port++) r8a66597_enable_port(r8a66597, port); return 0; @@ -218,7 +219,7 @@ static void disable_controller(struct r8a66597 *r8a66597) r8a66597_write(r8a66597, 0, INTENB0); r8a66597_write(r8a66597, 0, INTSTS0); - for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) + for (port = 0; port < r8a66597->max_root_hub; port++) r8a66597_disable_port(r8a66597, port); r8a66597_clock_disable(r8a66597); @@ -249,11 +250,12 @@ static int is_hub_limit(char *devpath) return ((strlen(devpath) >= 4) ? 1 : 0); } -static void get_port_number(char *devpath, u16 *root_port, u16 *hub_port) +static void get_port_number(struct r8a66597 *r8a66597, + char *devpath, u16 *root_port, u16 *hub_port) { if (root_port) { *root_port = (devpath[0] & 0x0F) - 1; - if (*root_port >= R8A66597_MAX_ROOT_HUB) + if (*root_port >= r8a66597->max_root_hub) printk(KERN_ERR "r8a66597: Illegal root port number.\n"); } if (hub_port) @@ -355,7 +357,8 @@ static int make_r8a66597_device(struct r8a66597 *r8a66597, INIT_LIST_HEAD(&dev->device_list); list_add_tail(&dev->device_list, &r8a66597->child_device); - get_port_number(urb->dev->devpath, &dev->root_port, &dev->hub_port); + get_port_number(r8a66597, urb->dev->devpath, + &dev->root_port, &dev->hub_port); if (!is_child_device(urb->dev->devpath)) r8a66597->root_hub[dev->root_port].dev = dev; @@ -420,7 +423,7 @@ static void free_usb_address(struct r8a66597 *r8a66597, list_del(&dev->device_list); kfree(dev); - for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) { + for (port = 0; port < r8a66597->max_root_hub; port++) { if (r8a66597->root_hub[port].dev == dev) { r8a66597->root_hub[port].dev = NULL; break; @@ -495,10 +498,20 @@ static void r8a66597_pipe_toggle(struct r8a66597 *r8a66597, r8a66597_bset(r8a66597, SQCLR, pipe->pipectr); } +static inline unsigned short mbw_value(struct r8a66597 *r8a66597) +{ + if (r8a66597->pdata->on_chip) + return MBW_32; + else + return MBW_16; +} + /* this function must be called with interrupt disabled */ static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum) { - r8a66597_mdfy(r8a66597, MBW | pipenum, MBW | CURPIPE, CFIFOSEL); + unsigned short mbw = mbw_value(r8a66597); + + r8a66597_mdfy(r8a66597, mbw | pipenum, mbw | CURPIPE, CFIFOSEL); r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, pipenum); } @@ -506,11 +519,13 @@ static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum) static inline void fifo_change_from_pipe(struct r8a66597 *r8a66597, struct r8a66597_pipe *pipe) { + unsigned short mbw = mbw_value(r8a66597); + cfifo_change(r8a66597, 0); - r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D0FIFOSEL); - r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D1FIFOSEL); + r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D0FIFOSEL); + r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D1FIFOSEL); - r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum, MBW | CURPIPE, + r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum, mbw | CURPIPE, pipe->fifosel); r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE, pipe->info.pipenum); } @@ -742,9 +757,13 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597, struct r8a66597_pipe *pipe, struct urb *urb) { -#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) int i; struct r8a66597_pipe_info *info = &pipe->info; + unsigned short mbw = mbw_value(r8a66597); + + /* pipe dma is only for external controlles */ + if (r8a66597->pdata->on_chip) + return; if ((pipe->info.pipenum != 0) && (info->type != R8A66597_INT)) { for (i = 0; i < R8A66597_MAX_DMA_CHANNEL; i++) { @@ -763,8 +782,8 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597, set_pipe_reg_addr(pipe, i); cfifo_change(r8a66597, 0); - r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum, - MBW | CURPIPE, pipe->fifosel); + r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum, + mbw | CURPIPE, pipe->fifosel); r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE, pipe->info.pipenum); @@ -772,7 +791,6 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597, break; } } -#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */ } /* this function must be called with interrupt disabled */ @@ -1769,7 +1787,7 @@ static void r8a66597_timer(unsigned long _r8a66597) spin_lock_irqsave(&r8a66597->lock, flags); - for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) + for (port = 0; port < r8a66597->max_root_hub; port++) r8a66597_root_hub_control(r8a66597, port); spin_unlock_irqrestore(&r8a66597->lock, flags); @@ -1807,7 +1825,7 @@ static void set_address_zero(struct r8a66597 *r8a66597, struct urb *urb) u16 root_port, hub_port; if (usb_address == 0) { - get_port_number(urb->dev->devpath, + get_port_number(r8a66597, urb->dev->devpath, &root_port, &hub_port); set_devadd_reg(r8a66597, 0, get_r8a66597_usb_speed(urb->dev->speed), @@ -2082,7 +2100,7 @@ static int r8a66597_hub_status_data(struct usb_hcd *hcd, char *buf) *buf = 0; /* initialize (no change) */ - for (i = 0; i < R8A66597_MAX_ROOT_HUB; i++) { + for (i = 0; i < r8a66597->max_root_hub; i++) { if (r8a66597->root_hub[i].port & 0xffff0000) *buf |= 1 << (i + 1); } @@ -2097,11 +2115,11 @@ static void r8a66597_hub_descriptor(struct r8a66597 *r8a66597, { desc->bDescriptorType = 0x29; desc->bHubContrCurrent = 0; - desc->bNbrPorts = R8A66597_MAX_ROOT_HUB; + desc->bNbrPorts = r8a66597->max_root_hub; desc->bDescLength = 9; desc->bPwrOn2PwrGood = 0; desc->wHubCharacteristics = cpu_to_le16(0x0011); - desc->bitmap[0] = ((1 << R8A66597_MAX_ROOT_HUB) - 1) << 1; + desc->bitmap[0] = ((1 << r8a66597->max_root_hub) - 1) << 1; desc->bitmap[1] = ~0; } @@ -2129,7 +2147,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, } break; case ClearPortFeature: - if (wIndex > R8A66597_MAX_ROOT_HUB) + if (wIndex > r8a66597->max_root_hub) goto error; if (wLength != 0) goto error; @@ -2162,12 +2180,12 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, *buf = 0x00; break; case GetPortStatus: - if (wIndex > R8A66597_MAX_ROOT_HUB) + if (wIndex > r8a66597->max_root_hub) goto error; *(__le32 *)buf = cpu_to_le32(rh->port); break; case SetPortFeature: - if (wIndex > R8A66597_MAX_ROOT_HUB) + if (wIndex > r8a66597->max_root_hub) goto error; if (wLength != 0) goto error; @@ -2216,7 +2234,7 @@ static int r8a66597_bus_suspend(struct usb_hcd *hcd) dbg("%s", __func__); - for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) { + for (port = 0; port < r8a66597->max_root_hub; port++) { struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; unsigned long dvstctr_reg = get_dvstctr_reg(port); @@ -2247,7 +2265,7 @@ static int r8a66597_bus_resume(struct usb_hcd *hcd) dbg("%s", __func__); - for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) { + for (port = 0; port < r8a66597->max_root_hub; port++) { struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; unsigned long dvstctr_reg = get_dvstctr_reg(port); @@ -2314,7 +2332,7 @@ static int r8a66597_suspend(struct device *dev) disable_controller(r8a66597); - for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) { + for (port = 0; port < r8a66597->max_root_hub; port++) { struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; rh->port = 0x00000000; @@ -2354,8 +2372,9 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev) del_timer_sync(&r8a66597->rh_timer); usb_remove_hcd(hcd); iounmap((void *)r8a66597->reg); -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK) - clk_put(r8a66597->clk); +#ifdef CONFIG_HAVE_CLK + if (r8a66597->pdata->on_chip) + clk_put(r8a66597->clk); #endif usb_put_hcd(hcd); return 0; @@ -2363,7 +2382,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev) static int __devinit r8a66597_probe(struct platform_device *pdev) { -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK) +#ifdef CONFIG_HAVE_CLK char clk_name[8]; #endif struct resource *res = NULL, *ires; @@ -2425,15 +2444,20 @@ static int __devinit r8a66597_probe(struct platform_device *pdev) r8a66597->pdata = pdev->dev.platform_data; r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW; -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK) - snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id); - r8a66597->clk = clk_get(&pdev->dev, clk_name); - if (IS_ERR(r8a66597->clk)) { - dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); - ret = PTR_ERR(r8a66597->clk); - goto clean_up2; - } + if (r8a66597->pdata->on_chip) { +#ifdef CONFIG_HAVE_CLK + snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id); + r8a66597->clk = clk_get(&pdev->dev, clk_name); + if (IS_ERR(r8a66597->clk)) { + dev_err(&pdev->dev, "cannot get clock \"%s\"\n", + clk_name); + ret = PTR_ERR(r8a66597->clk); + goto clean_up2; + } #endif + r8a66597->max_root_hub = 1; + } else + r8a66597->max_root_hub = 2; spin_lock_init(&r8a66597->lock); init_timer(&r8a66597->rh_timer); @@ -2463,8 +2487,9 @@ static int __devinit r8a66597_probe(struct platform_device *pdev) return 0; clean_up3: -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK) - clk_put(r8a66597->clk); +#ifdef CONFIG_HAVE_CLK + if (r8a66597->pdata->on_chip) + clk_put(r8a66597->clk); clean_up2: #endif usb_put_hcd(hcd); diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index d72680b433f9..eecbd917bc81 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h @@ -26,7 +26,7 @@ #ifndef __R8A66597_H__ #define __R8A66597_H__ -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK) +#ifdef CONFIG_HAVE_CLK #include #endif @@ -193,13 +193,9 @@ #define REW 0x4000 /* b14: Buffer rewind */ #define DCLRM 0x2000 /* b13: DMA buffer clear mode */ #define DREQE 0x1000 /* b12: DREQ output enable */ -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) -#define MBW 0x0800 -#else -#define MBW 0x0400 /* b10: Maximum bit width for FIFO access */ -#endif #define MBW_8 0x0000 /* 8bit */ #define MBW_16 0x0400 /* 16bit */ +#define MBW_32 0x0800 /* 32bit */ #define BIGEND 0x0100 /* b8: Big endian mode */ #define BYTE_LITTLE 0x0000 /* little dendian */ #define BYTE_BIG 0x0100 /* big endifan */ @@ -405,11 +401,7 @@ #define R8A66597_MAX_NUM_PIPE 10 #define R8A66597_BUF_BSIZE 8 #define R8A66597_MAX_DEVICE 10 -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) -#define R8A66597_MAX_ROOT_HUB 1 -#else #define R8A66597_MAX_ROOT_HUB 2 -#endif #define R8A66597_MAX_SAMPLING 5 #define R8A66597_RH_POLL_TIME 10 #define R8A66597_MAX_DMA_CHANNEL 2 @@ -487,7 +479,7 @@ struct r8a66597_root_hub { struct r8a66597 { spinlock_t lock; unsigned long reg; -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK) +#ifdef CONFIG_HAVE_CLK struct clk *clk; #endif struct r8a66597_platdata *pdata; @@ -504,6 +496,7 @@ struct r8a66597 { unsigned short interval_map; unsigned char pipe_cnt[R8A66597_MAX_NUM_PIPE]; unsigned char dma_map; + unsigned int max_root_hub; struct list_head child_device; unsigned long child_connect_map[4]; @@ -550,21 +543,22 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, unsigned long offset, u16 *buf, int len) { -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) unsigned long fifoaddr = r8a66597->reg + offset; unsigned long count; - count = len / 4; - insl(fifoaddr, buf, count); + if (r8a66597->pdata->on_chip) { + count = len / 4; + insl(fifoaddr, buf, count); - if (len & 0x00000003) { - unsigned long tmp = inl(fifoaddr); - memcpy((unsigned char *)buf + count * 4, &tmp, len & 0x03); + if (len & 0x00000003) { + unsigned long tmp = inl(fifoaddr); + memcpy((unsigned char *)buf + count * 4, &tmp, + len & 0x03); + } + } else { + len = (len + 1) / 2; + insw(fifoaddr, buf, len); } -#else - len = (len + 1) / 2; - insw(r8a66597->reg + offset, buf, len); -#endif } static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, @@ -578,33 +572,33 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, int len) { unsigned long fifoaddr = r8a66597->reg + offset; -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) unsigned long count; unsigned char *pb; int i; - count = len / 4; - outsl(fifoaddr, buf, count); + if (r8a66597->pdata->on_chip) { + count = len / 4; + outsl(fifoaddr, buf, count); + + if (len & 0x00000003) { + pb = (unsigned char *)buf + count * 4; + for (i = 0; i < (len & 0x00000003); i++) { + if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND) + outb(pb[i], fifoaddr + i); + else + outb(pb[i], fifoaddr + 3 - i); + } + } + } else { + int odd = len & 0x0001; - if (len & 0x00000003) { - pb = (unsigned char *)buf + count * 4; - for (i = 0; i < (len & 0x00000003); i++) { - if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND) - outb(pb[i], fifoaddr + i); - else - outb(pb[i], fifoaddr + 3 - i); + len = len / 2; + outsw(fifoaddr, buf, len); + if (unlikely(odd)) { + buf = &buf[len]; + outb((unsigned char)*buf, fifoaddr); } } -#else - int odd = len & 0x0001; - - len = len / 2; - outsw(fifoaddr, buf, len); - if (unlikely(odd)) { - buf = &buf[len]; - outb((unsigned char)*buf, fifoaddr); - } -#endif } static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, diff --git a/include/linux/usb/r8a66597.h b/include/linux/usb/r8a66597.h index e9f0384fa20c..460ee3f6a2c6 100644 --- a/include/linux/usb/r8a66597.h +++ b/include/linux/usb/r8a66597.h @@ -31,6 +31,9 @@ struct r8a66597_platdata { /* This ops can controll port power instead of DVSTCTR register. */ void (*port_power)(int port, int power); + /* set one = on chip controller, set zero = external controller */ + unsigned on_chip:1; + /* (external controller only) set R8A66597_PLATDATA_XTAL_nnMHZ */ unsigned xtal:2; -- cgit v1.2.3-59-g8ed1b From 6bde607e699b9f3c6fa5e4a97d78c7778e643b3d Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Mon, 20 Jul 2009 23:30:24 +0900 Subject: sh: Clean up linker script using new BSS_SECTION macro. Updated to use the fixed BSS linker script macros from this thread: http://www.spinics.net/lists/kernel/msg913238.html Signed-off-by: Tim Abbott Cc: Sam Ravnborg Cc: linux-sh@vger.kernel.org Signed-off-by: Paul Mundt --- arch/sh/kernel/vmlinux.lds.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 674ed8feb8ae..80dc9f8d9412 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -93,8 +93,7 @@ SECTIONS . = ALIGN(PAGE_SIZE); __init_end = .; - BSS(PAGE_SIZE) - . = ALIGN(4); + BSS_SECTION(0, PAGE_SIZE, 4) _ebss = .; /* uClinux MTD sucks */ _end = . ; -- cgit v1.2.3-59-g8ed1b From ef9b542fce00dafc6bb1d9097b045a777f4a2382 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 21 Jul 2009 17:24:36 +0900 Subject: sh: bzip2/lzma uImage support. This builds on the bzip2/lzma zImage support change and wires it up for uImages. Based on the blackfin implementation. Signed-off-by: Paul Mundt --- arch/sh/Makefile | 15 ++++++++++----- arch/sh/boot/.gitignore | 5 ++--- arch/sh/boot/Makefile | 39 ++++++++++++++++++++++++++++----------- arch/sh/boot/compressed/Makefile | 4 ---- 4 files changed, 40 insertions(+), 23 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 75d049b03f7e..2aba73eccb31 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -189,14 +189,16 @@ KBUILD_AFLAGS += $(cflags-y) 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 +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 +210,13 @@ archclean: $(Q)$(MAKE) $(clean)=arch/sh/kernel/vsyscall define archhelp - @echo '* zImage - Compressed kernel image' + @echo ' zImage - Compressed kernel image' @echo ' vmlinux.srec - Create an ELF S-record' - @echo ' uImage - Create a bootable image for U-Boot' - @echo ' uImage.srec - Create an S-record 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 diff --git a/arch/sh/boot/.gitignore b/arch/sh/boot/.gitignore index aad5edddf93b..541087d2029c 100644 --- a/arch/sh/boot/.gitignore +++ b/arch/sh/boot/.gitignore @@ -1,4 +1,3 @@ zImage -vmlinux.srec -uImage -uImage.srec +vmlinux* +uImage* diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile index 78efb04c28f3..dd2a852041e9 100644 --- a/arch/sh/boot/Makefile +++ b/arch/sh/boot/Makefile @@ -20,7 +20,12 @@ CONFIG_BOOT_LINK_OFFSET ?= 0x00800000 CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000 CONFIG_ENTRY_OFFSET ?= 0x00001000 -targets := zImage vmlinux.srec uImage uImage.srec +suffix-$(CONFIG_KERNEL_GZIP) := gz +suffix-$(CONFIG_KERNEL_BZIP2) := bz2 +suffix-$(CONFIG_KERNEL_LZMA) := lzma + +targets := zImage vmlinux.srec uImage uImage.srec uImage.gz uImage.bz2 uImage.lzma +extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma subdir- := compressed $(obj)/zImage: $(obj)/compressed/vmlinux FORCE @@ -40,9 +45,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 +57,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 +89,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 diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index 3324019e207e..b31618e9e8c8 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -48,10 +48,6 @@ $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE $(call if_changed,lzma) -suffix-$(CONFIG_KERNEL_GZIP) := gz -suffix-$(CONFIG_KERNEL_BZIP2) := bz2 -suffix-$(CONFIG_KERNEL_LZMA) := lzma - OBJCOPYFLAGS += -R .empty_zero_page LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T -- cgit v1.2.3-59-g8ed1b From c0b96cf639aa1bfa8983f734d4225091aa813e00 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 22 Jul 2009 16:50:57 +0900 Subject: sh: Provide _PAGE_SPECIAL for 32-bit. Allocate one of the unused PTE bits for _PAGE_SPECIAL directly. This is prep work for fast gup and the zero page revival. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgtable_32.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h index 72ea209195bd..0db19db913c7 100644 --- a/arch/sh/include/asm/pgtable_32.h +++ b/arch/sh/include/asm/pgtable_32.h @@ -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. -- cgit v1.2.3-59-g8ed1b From 2277ab4a1df50e05bc732fe9488d4e902bb8399a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 22 Jul 2009 19:20:49 +0900 Subject: sh: Migrate from PG_mapped to PG_dcache_dirty. This inverts the delayed dcache flush a bit to be more in line with other platforms. At the same time this also gives us the ability to do some more optimizations and cleanup. Now that the update_mmu_cache() callsite only tests for the bit, the implementation can gradually be split out and made generic, rather than relying on special implementations for each of the peculiar CPU types. SH7705 in 32kB mode and SH-4 still need slightly different handling, but this is something that can remain isolated in the varying page copy/clear routines. On top of that, SH-X3 is dcache coherent, so there is no need to bother with any of these tests in the PTEAEX version of update_mmu_cache(), so we kill that off too. Signed-off-by: Paul Mundt --- arch/sh/include/asm/page.h | 6 +++ arch/sh/include/asm/pgtable.h | 7 --- arch/sh/include/cpu-sh3/cpu/cacheflush.h | 5 +-- arch/sh/include/cpu-sh4/cpu/cacheflush.h | 2 +- arch/sh/mm/cache-sh4.c | 10 ++++- arch/sh/mm/cache-sh7705.c | 7 ++- arch/sh/mm/pg-sh4.c | 74 +++++++++++++------------------- arch/sh/mm/pg-sh7705.c | 52 ++++------------------ arch/sh/mm/tlb-pteaex.c | 17 -------- arch/sh/mm/tlb-sh3.c | 20 ++++----- arch/sh/mm/tlb-sh4.c | 23 +++++----- 11 files changed, 81 insertions(+), 142 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 49592c780a6e..a31ab40040f0 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -50,6 +50,12 @@ extern unsigned long shm_align_mask; extern unsigned long max_low_pfn, min_low_pfn; extern unsigned long memory_start, memory_end; +static inline unsigned long +pages_do_alias(unsigned long addr1, unsigned long addr2) +{ + return (addr1 ^ addr2) & shm_align_mask; +} + extern void clear_page(void *to); extern void copy_page(void *to, void *from); diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index 2a011b18090b..d9f68f9c3cb3 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -133,13 +133,6 @@ typedef pte_t *pte_addr_t; */ #define pgtable_cache_init() do { } while (0) -#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \ - defined(CONFIG_SH7705_CACHE_32KB)) -struct mm_struct; -#define __HAVE_ARCH_PTEP_GET_AND_CLEAR -pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); -#endif - struct vm_area_struct; extern void update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte); diff --git a/arch/sh/include/cpu-sh3/cpu/cacheflush.h b/arch/sh/include/cpu-sh3/cpu/cacheflush.h index 1ac27aae6700..6485ad5649ad 100644 --- a/arch/sh/include/cpu-sh3/cpu/cacheflush.h +++ b/arch/sh/include/cpu-sh3/cpu/cacheflush.h @@ -15,10 +15,7 @@ * SH4. Unlike the SH4 this is a unified cache so we need to do some work * in mmap when 'exec'ing a new binary */ - /* 32KB cache, 4kb PAGE sizes need to check bit 12 */ -#define CACHE_ALIAS 0x00001000 - -#define PG_mapped PG_arch_1 +#define PG_dcache_dirty PG_arch_1 void flush_cache_all(void); void flush_cache_mm(struct mm_struct *mm); diff --git a/arch/sh/include/cpu-sh4/cpu/cacheflush.h b/arch/sh/include/cpu-sh4/cpu/cacheflush.h index 065306d376eb..3564f1722195 100644 --- a/arch/sh/include/cpu-sh4/cpu/cacheflush.h +++ b/arch/sh/include/cpu-sh4/cpu/cacheflush.h @@ -38,6 +38,6 @@ void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, /* Initialization of P3 area for copy_user_page */ void p3_cache_init(void); -#define PG_mapped PG_arch_1 +#define PG_dcache_dirty PG_arch_1 #endif /* __ASM_CPU_SH4_CACHEFLUSH_H */ diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index 5cfe08dbb59e..c3a09b27f8d5 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -246,7 +247,14 @@ static inline void flush_cache_4096(unsigned long start, */ void flush_dcache_page(struct page *page) { - if (test_bit(PG_mapped, &page->flags)) { + struct address_space *mapping = page_mapping(page); + +#ifndef CONFIG_SMP + if (mapping && !mapping_mapped(mapping)) + set_bit(PG_dcache_dirty, &page->flags); + else +#endif + { unsigned long phys = PHYSADDR(page_address(page)); unsigned long addr = CACHE_OC_ADDRESS_ARRAY; int i, n; diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c index 22dacc778823..fa37bff306b9 100644 --- a/arch/sh/mm/cache-sh7705.c +++ b/arch/sh/mm/cache-sh7705.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -128,7 +129,11 @@ static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys) */ void flush_dcache_page(struct page *page) { - if (test_bit(PG_mapped, &page->flags)) + struct address_space *mapping = page_mapping(page); + + if (mapping && !mapping_mapped(mapping)) + set_bit(PG_dcache_dirty, &page->flags); + else __flush_dcache_page(PHYSADDR(page_address(page))); } diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c index 2fe14da1f839..f3c4b2a54fc7 100644 --- a/arch/sh/mm/pg-sh4.c +++ b/arch/sh/mm/pg-sh4.c @@ -15,8 +15,6 @@ #include #include -#define CACHE_ALIAS (current_cpu_data.dcache.alias_mask) - #define kmap_get_fixmap_pte(vaddr) \ pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) @@ -68,10 +66,9 @@ static inline void kunmap_coherent(struct page *page) */ void clear_user_page(void *to, unsigned long address, struct page *page) { - __set_bit(PG_mapped, &page->flags); - clear_page(to); - if ((((address & PAGE_MASK) ^ (unsigned long)to) & CACHE_ALIAS)) + + if (pages_do_alias((unsigned long)to, address & PAGE_MASK)) __flush_wback_region(to, PAGE_SIZE); } @@ -79,13 +76,14 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len) { - void *vto; - - __set_bit(PG_mapped, &page->flags); - - vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); - memcpy(vto, src, len); - kunmap_coherent(vto); + if (page_mapped(page) && !test_bit(PG_dcache_dirty, &page->flags)) { + void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); + memcpy(vto, src, len); + kunmap_coherent(vto); + } else { + memcpy(dst, src, len); + set_bit(PG_dcache_dirty, &page->flags); + } if (vma->vm_flags & VM_EXEC) flush_cache_page(vma, vaddr, page_to_pfn(page)); @@ -95,13 +93,14 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len) { - void *vfrom; - - __set_bit(PG_mapped, &page->flags); - - vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); - memcpy(dst, vfrom, len); - kunmap_coherent(vfrom); + if (page_mapped(page) && !test_bit(PG_dcache_dirty, &page->flags)) { + void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); + memcpy(dst, vfrom, len); + kunmap_coherent(vfrom); + } else { + memcpy(dst, src, len); + set_bit(PG_dcache_dirty, &page->flags); + } } void copy_user_highpage(struct page *to, struct page *from, @@ -109,14 +108,19 @@ void copy_user_highpage(struct page *to, struct page *from, { void *vfrom, *vto; - __set_bit(PG_mapped, &to->flags); - vto = kmap_atomic(to, KM_USER1); - vfrom = kmap_coherent(from, vaddr); - copy_page(vto, vfrom); - kunmap_coherent(vfrom); - if (((vaddr ^ (unsigned long)vto) & CACHE_ALIAS)) + if (page_mapped(from) && !test_bit(PG_dcache_dirty, &from->flags)) { + vfrom = kmap_coherent(from, vaddr); + copy_page(vto, vfrom); + kunmap_coherent(vfrom); + } else { + vfrom = kmap_atomic(from, KM_USER0); + copy_page(vto, vfrom); + kunmap_atomic(vfrom, KM_USER0); + } + + if (pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK)) __flush_wback_region(vto, PAGE_SIZE); kunmap_atomic(vto, KM_USER1); @@ -124,23 +128,3 @@ void copy_user_highpage(struct page *to, struct page *from, smp_wmb(); } EXPORT_SYMBOL(copy_user_highpage); - -/* - * For SH-4, we have our own implementation for ptep_get_and_clear - */ -pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - pte_t pte = *ptep; - - pte_clear(mm, addr, ptep); - if (!pte_not_present(pte)) { - unsigned long pfn = pte_pfn(pte); - if (pfn_valid(pfn)) { - struct page *page = pfn_to_page(pfn); - struct address_space *mapping = page_mapping(page); - if (!mapping || !mapping_writably_mapped(mapping)) - __clear_bit(PG_mapped, &page->flags); - } - } - return pte; -} diff --git a/arch/sh/mm/pg-sh7705.c b/arch/sh/mm/pg-sh7705.c index eaf25147194c..684891b5c8c0 100644 --- a/arch/sh/mm/pg-sh7705.c +++ b/arch/sh/mm/pg-sh7705.c @@ -26,7 +26,7 @@ #include #include -static inline void __flush_purge_virtual_region(void *p1, void *virt, int size) +static void __flush_purge_virtual_region(void *p1, void *virt, int size) { unsigned long v; unsigned long begin, end; @@ -75,19 +75,13 @@ static inline void __flush_purge_virtual_region(void *p1, void *virt, int size) */ void clear_user_page(void *to, unsigned long address, struct page *pg) { - struct page *page = virt_to_page(to); - - __set_bit(PG_mapped, &page->flags); - if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) { - clear_page(to); - __flush_wback_region(to, PAGE_SIZE); - } else { + if (pages_do_alias(address, (unsigned long)to)) __flush_purge_virtual_region(to, (void *)(address & 0xfffff000), PAGE_SIZE); - clear_page(to); - __flush_wback_region(to, PAGE_SIZE); - } + + clear_page(to); + __flush_wback_region(to, PAGE_SIZE); } /* @@ -98,41 +92,11 @@ void clear_user_page(void *to, unsigned long address, struct page *pg) */ void copy_user_page(void *to, void *from, unsigned long address, struct page *pg) { - struct page *page = virt_to_page(to); - - - __set_bit(PG_mapped, &page->flags); - if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) { - copy_page(to, from); - __flush_wback_region(to, PAGE_SIZE); - } else { + if (pages_do_alias(address, (unsigned long)to)) __flush_purge_virtual_region(to, (void *)(address & 0xfffff000), PAGE_SIZE); - copy_page(to, from); - __flush_wback_region(to, PAGE_SIZE); - } -} -/* - * For SH7705, we have our own implementation for ptep_get_and_clear - * Copied from pg-sh4.c - */ -pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - pte_t pte = *ptep; - - pte_clear(mm, addr, ptep); - if (!pte_not_present(pte)) { - unsigned long pfn = pte_pfn(pte); - if (pfn_valid(pfn)) { - struct page *page = pfn_to_page(pfn); - struct address_space *mapping = page_mapping(page); - if (!mapping || !mapping_writably_mapped(mapping)) - __clear_bit(PG_mapped, &page->flags); - } - } - - return pte; + copy_page(to, from); + __flush_wback_region(to, PAGE_SIZE); } - diff --git a/arch/sh/mm/tlb-pteaex.c b/arch/sh/mm/tlb-pteaex.c index 2aab3ea934d7..c39b77363352 100644 --- a/arch/sh/mm/tlb-pteaex.c +++ b/arch/sh/mm/tlb-pteaex.c @@ -27,23 +27,6 @@ void update_mmu_cache(struct vm_area_struct * vma, if (vma && current->active_mm != vma->vm_mm) return; -#ifndef CONFIG_CACHE_OFF - { - unsigned long pfn = pte_pfn(pte); - - if (pfn_valid(pfn)) { - struct page *page = pfn_to_page(pfn); - - if (!test_bit(PG_mapped, &page->flags)) { - unsigned long phys = pte_val(pte) & PTE_PHYS_MASK; - __flush_wback_region((void *)P1SEGADDR(phys), - PAGE_SIZE); - __set_bit(PG_mapped, &page->flags); - } - } - } -#endif - local_irq_save(flags); /* Set PTEH register */ diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c index 17cb7c3adf22..9b8459c74abd 100644 --- a/arch/sh/mm/tlb-sh3.c +++ b/arch/sh/mm/tlb-sh3.c @@ -33,25 +33,25 @@ void update_mmu_cache(struct vm_area_struct * vma, unsigned long flags; unsigned long pteval; unsigned long vpn; + unsigned long pfn = pte_pfn(pte); + struct page *page; /* Ptrace may call this routine. */ if (vma && current->active_mm != vma->vm_mm) return; + page = pfn_to_page(pfn); + if (pfn_valid(pfn) && page_mapping(page)) { #if defined(CONFIG_SH7705_CACHE_32KB) - { - struct page *page = pte_page(pte); - unsigned long pfn = pte_pfn(pte); + int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); + if (dirty) { + unsigned long addr = (unsigned long)page_address(page); - if (pfn_valid(pfn) && !test_bit(PG_mapped, &page->flags)) { - unsigned long phys = pte_val(pte) & PTE_PHYS_MASK; - - __flush_wback_region((void *)P1SEGADDR(phys), - PAGE_SIZE); - __set_bit(PG_mapped, &page->flags); + if (pages_do_alias(addr, address & PAGE_MASK)) + __flush_wback_region((void *)addr, PAGE_SIZE); } - } #endif + } local_irq_save(flags); diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c index f0c7b7397fa6..cf50082d2435 100644 --- a/arch/sh/mm/tlb-sh4.c +++ b/arch/sh/mm/tlb-sh4.c @@ -21,27 +21,26 @@ void update_mmu_cache(struct vm_area_struct * vma, unsigned long flags; unsigned long pteval; unsigned long vpn; + unsigned long pfn = pte_pfn(pte); + struct page *page; /* Ptrace may call this routine. */ if (vma && current->active_mm != vma->vm_mm) return; -#ifndef CONFIG_CACHE_OFF - { - unsigned long pfn = pte_pfn(pte); + page = pfn_to_page(pfn); + if (pfn_valid(pfn) && page_mapping(page)) { +#ifndef CONFIG_SMP + int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); + if (dirty) { - if (pfn_valid(pfn)) { - struct page *page = pfn_to_page(pfn); + unsigned long addr = (unsigned long)page_address(page); - if (!test_bit(PG_mapped, &page->flags)) { - unsigned long phys = pte_val(pte) & PTE_PHYS_MASK; - __flush_wback_region((void *)P1SEGADDR(phys), - PAGE_SIZE); - __set_bit(PG_mapped, &page->flags); - } + if (pages_do_alias(addr, address & PAGE_MASK)) + __flush_wback_region((void *)addr, PAGE_SIZE); } - } #endif + } local_irq_save(flags); -- cgit v1.2.3-59-g8ed1b From 2c59b0b70b9d5d61c726f179724660c4c2423f31 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 22 Jul 2009 14:41:35 +0000 Subject: usb: m66592-udc platform data on_chip support Convert the m66592-udc driver to use the on_chip flag from platform data to enable on chip behaviour instead of relying on CONFIG_SUPERH_BUILT_IN_M66592 ugliness. This makes the code cleaner and also allows us to support both external and internal m66592 with the same kernel. It also makes the Kconfig part more future proof since we with this patch can add support for new processors with on-chip m66592 without modifying the Kconfig. The patch adds a m66592 header file for platform data and ties in platform data to the existing m66592 devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-highlander/setup.c | 7 + arch/sh/boards/mach-x3proto/setup.c | 7 + arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 8 +- drivers/usb/gadget/Kconfig | 10 -- drivers/usb/gadget/m66592-udc.c | 252 +++++++++++++++++++-------------- drivers/usb/gadget/m66592-udc.h | 89 ++++++------ include/linux/usb/m66592.h | 44 ++++++ 7 files changed, 257 insertions(+), 160 deletions(-) create mode 100644 include/linux/usb/m66592.h (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c index 1639f8915000..566e69d8d729 100644 --- a/arch/sh/boards/mach-highlander/setup.c +++ b/arch/sh/boards/mach-highlander/setup.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -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, diff --git a/arch/sh/boards/mach-x3proto/setup.c b/arch/sh/boards/mach-x3proto/setup.c index 8913ae39a802..efe4cb9f8a77 100644 --- a/arch/sh/boards/mach-x3proto/setup.c +++ b/arch/sh/boards/mach-x3proto/setup.c @@ -17,6 +17,7 @@ #include #include #include +#include #include 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, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index ea524a2da3e4..0bad14a44238 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -47,9 +48,13 @@ static struct platform_device rtc_device = { .resource = rtc_resources, }; +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,6 +72,7 @@ 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, diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 7f8e83a954ac..b7f10bc25c2c 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -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) # diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 0dddd2f8ff35..a61c70caff12 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -31,38 +31,12 @@ #include "m66592-udc.h" - MODULE_DESCRIPTION("M66592 USB gadget driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Yoshihiro Shimoda"); MODULE_ALIAS("platform:m66592_udc"); -#define DRIVER_VERSION "26 Jun 2009" - -/* module parameters */ -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) -static unsigned short endian = M66592_LITTLE; -module_param(endian, ushort, 0644); -MODULE_PARM_DESC(endian, "data endian: big=0, little=0 (default=0)"); -#else -static unsigned short clock = M66592_XTAL24; -module_param(clock, ushort, 0644); -MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " - "(default=16384)"); - -static unsigned short vif = M66592_LDRV; -module_param(vif, ushort, 0644); -MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)"); - -static unsigned short endian; -module_param(endian, ushort, 0644); -MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)"); - -static unsigned short irq_sense = M66592_INTL; -module_param(irq_sense, ushort, 0644); -MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 " - "(default=2)"); -#endif +#define DRIVER_VERSION "21 July 2009" static const char udc_name[] = "m66592_udc"; static const char *m66592_ep_name[] = { @@ -244,6 +218,7 @@ static inline int get_buffer_size(struct m66592 *m66592, u16 pipenum) static inline void pipe_change(struct m66592 *m66592, u16 pipenum) { struct m66592_ep *ep = m66592->pipenum2ep[pipenum]; + unsigned short mbw; if (ep->use_dma) return; @@ -252,7 +227,12 @@ static inline void pipe_change(struct m66592 *m66592, u16 pipenum) ndelay(450); - m66592_bset(m66592, M66592_MBW, ep->fifosel); + if (m66592->pdata->on_chip) + mbw = M66592_MBW_32; + else + mbw = M66592_MBW_16; + + m66592_bset(m66592, mbw, ep->fifosel); } static int pipe_buffer_setting(struct m66592 *m66592, @@ -332,6 +312,7 @@ static void pipe_buffer_release(struct m66592 *m66592, static void pipe_initialize(struct m66592_ep *ep) { struct m66592 *m66592 = ep->m66592; + unsigned short mbw; m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel); @@ -343,7 +324,12 @@ static void pipe_initialize(struct m66592_ep *ep) ndelay(450); - m66592_bset(m66592, M66592_MBW, ep->fifosel); + if (m66592->pdata->on_chip) + mbw = M66592_MBW_32; + else + mbw = M66592_MBW_16; + + m66592_bset(m66592, mbw, ep->fifosel); } } @@ -359,15 +345,13 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, ep->fifosel = M66592_D0FIFOSEL; ep->fifoctr = M66592_D0FIFOCTR; ep->fifotrn = M66592_D0FIFOTRN; -#if !defined(CONFIG_SUPERH_BUILT_IN_M66592) - } else if (m66592->num_dma == 1) { + } else if (!m66592->pdata->on_chip && m66592->num_dma == 1) { m66592->num_dma++; ep->use_dma = 1; ep->fifoaddr = M66592_D1FIFO; ep->fifosel = M66592_D1FIFOSEL; ep->fifoctr = M66592_D1FIFOCTR; ep->fifotrn = M66592_D1FIFOTRN; -#endif } else { ep->use_dma = 0; ep->fifoaddr = M66592_CFIFO; @@ -612,76 +596,120 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req) } } -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) static void init_controller(struct m66592 *m66592) { - m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ - m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); - m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); - m66592_bset(m66592, M66592_USBE, M66592_SYSCFG); + unsigned int endian; - /* This is a workaound for SH7722 2nd cut */ - m66592_bset(m66592, 0x8000, M66592_DVSTCTR); - m66592_bset(m66592, 0x1000, M66592_TESTMODE); - m66592_bclr(m66592, 0x8000, M66592_DVSTCTR); + if (m66592->pdata->on_chip) { + if (m66592->pdata->endian) + endian = 0; /* big endian */ + else + endian = M66592_LITTLE; /* little endian */ - m66592_bset(m66592, M66592_INTL, M66592_INTENB1); + m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ + m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); + m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); + m66592_bset(m66592, M66592_USBE, M66592_SYSCFG); - m66592_write(m66592, 0, M66592_CFBCFG); - m66592_write(m66592, 0, M66592_D0FBCFG); - m66592_bset(m66592, endian, M66592_CFBCFG); - m66592_bset(m66592, endian, M66592_D0FBCFG); -} -#else /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ -static void init_controller(struct m66592 *m66592) -{ - m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), - M66592_PINCFG); - m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ - m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG); + /* This is a workaound for SH7722 2nd cut */ + m66592_bset(m66592, 0x8000, M66592_DVSTCTR); + m66592_bset(m66592, 0x1000, M66592_TESTMODE); + m66592_bclr(m66592, 0x8000, M66592_DVSTCTR); - m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); - m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); - m66592_bset(m66592, M66592_USBE, M66592_SYSCFG); + m66592_bset(m66592, M66592_INTL, M66592_INTENB1); + + m66592_write(m66592, 0, M66592_CFBCFG); + m66592_write(m66592, 0, M66592_D0FBCFG); + m66592_bset(m66592, endian, M66592_CFBCFG); + m66592_bset(m66592, endian, M66592_D0FBCFG); + } else { + unsigned int clock, vif, irq_sense; + + if (m66592->pdata->endian) + endian = M66592_BIGEND; /* big endian */ + else + endian = 0; /* little endian */ + + if (m66592->pdata->vif) + vif = M66592_LDRV; /* 3.3v */ + else + vif = 0; /* 1.5v */ + + switch (m66592->pdata->xtal) { + case M66592_PLATDATA_XTAL_12MHZ: + clock = M66592_XTAL12; + break; + case M66592_PLATDATA_XTAL_24MHZ: + clock = M66592_XTAL24; + break; + case M66592_PLATDATA_XTAL_48MHZ: + clock = M66592_XTAL48; + break; + default: + pr_warning("m66592-udc: xtal configuration error\n"); + clock = 0; + } - m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); + switch (m66592->irq_trigger) { + case IRQF_TRIGGER_LOW: + irq_sense = M66592_INTL; + break; + case IRQF_TRIGGER_FALLING: + irq_sense = 0; + break; + default: + pr_warning("m66592-udc: irq trigger config error\n"); + irq_sense = 0; + } - msleep(3); + m66592_bset(m66592, + (vif & M66592_LDRV) | (endian & M66592_BIGEND), + M66592_PINCFG); + m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ + m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, + M66592_SYSCFG); + m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); + m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); + m66592_bset(m66592, M66592_USBE, M66592_SYSCFG); - m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG); + m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); + + msleep(3); - msleep(1); + m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG); - m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG); + msleep(1); - m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1); - m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, - M66592_DMA0CFG); + m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG); + + m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1); + m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, + M66592_DMA0CFG); + } } -#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ static void disable_controller(struct m66592 *m66592) { -#if !defined(CONFIG_SUPERH_BUILT_IN_M66592) - m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); - udelay(1); - m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG); - udelay(1); - m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG); - udelay(1); - m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG); -#endif + if (!m66592->pdata->on_chip) { + m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); + udelay(1); + m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG); + udelay(1); + m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG); + udelay(1); + m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG); + } } static void m66592_start_xclock(struct m66592 *m66592) { -#if !defined(CONFIG_SUPERH_BUILT_IN_M66592) u16 tmp; - tmp = m66592_read(m66592, M66592_SYSCFG); - if (!(tmp & M66592_XCKE)) - m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); -#endif + if (!m66592->pdata->on_chip) { + tmp = m66592_read(m66592, M66592_SYSCFG); + if (!(tmp & M66592_XCKE)) + m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); + } } /*-------------------------------------------------------------------------*/ @@ -1169,8 +1197,7 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) intsts0 = m66592_read(m66592, M66592_INTSTS0); intenb0 = m66592_read(m66592, M66592_INTENB0); -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) - if (!intsts0 && !intenb0) { + if (m66592->pdata->on_chip && !intsts0 && !intenb0) { /* * When USB clock stops, it cannot read register. Even if a * clock stops, the interrupt occurs. So this driver turn on @@ -1180,7 +1207,6 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) intsts0 = m66592_read(m66592, M66592_INTSTS0); intenb0 = m66592_read(m66592, M66592_INTENB0); } -#endif savepipe = m66592_read(m66592, M66592_CFIFOSEL); @@ -1526,9 +1552,11 @@ static int __exit m66592_remove(struct platform_device *pdev) iounmap(m66592->reg); free_irq(platform_get_irq(pdev, 0), m66592); m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) - clk_disable(m66592->clk); - clk_put(m66592->clk); +#ifdef CONFIG_HAVE_CLK + if (m66592->pdata->on_chip) { + clk_disable(m66592->clk); + clk_put(m66592->clk); + } #endif kfree(m66592); return 0; @@ -1540,11 +1568,10 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r) static int __init m66592_probe(struct platform_device *pdev) { - struct resource *res; - int irq; + struct resource *res, *ires; void __iomem *reg = NULL; struct m66592 *m66592 = NULL; -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) +#ifdef CONFIG_HAVE_CLK char clk_name[8]; #endif int ret = 0; @@ -1557,10 +1584,11 @@ static int __init m66592_probe(struct platform_device *pdev) goto clean_up; } - irq = platform_get_irq(pdev, 0); - if (irq < 0) { + ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!ires) { ret = -ENODEV; - pr_err("platform_get_irq error.\n"); + dev_err(&pdev->dev, + "platform_get_resource IORESOURCE_IRQ error.\n"); goto clean_up; } @@ -1571,6 +1599,12 @@ static int __init m66592_probe(struct platform_device *pdev) goto clean_up; } + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "no platform data\n"); + ret = -ENODEV; + goto clean_up; + } + /* initialize ucd */ m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); if (m66592 == NULL) { @@ -1578,6 +1612,9 @@ static int __init m66592_probe(struct platform_device *pdev) goto clean_up; } + m66592->pdata = pdev->dev.platform_data; + m66592->irq_trigger = ires->flags & IRQF_TRIGGER_MASK; + spin_lock_init(&m66592->lock); dev_set_drvdata(&pdev->dev, m66592); @@ -1595,22 +1632,25 @@ static int __init m66592_probe(struct platform_device *pdev) m66592->timer.data = (unsigned long)m66592; m66592->reg = reg; - ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, + ret = request_irq(ires->start, m66592_irq, IRQF_DISABLED | IRQF_SHARED, udc_name, m66592); if (ret < 0) { pr_err("request_irq error (%d)\n", ret); goto clean_up; } -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) - snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id); - m66592->clk = clk_get(&pdev->dev, clk_name); - if (IS_ERR(m66592->clk)) { - dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); - ret = PTR_ERR(m66592->clk); - goto clean_up2; +#ifdef CONFIG_HAVE_CLK + if (m66592->pdata->on_chip) { + snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id); + m66592->clk = clk_get(&pdev->dev, clk_name); + if (IS_ERR(m66592->clk)) { + dev_err(&pdev->dev, "cannot get clock \"%s\"\n", + clk_name); + ret = PTR_ERR(m66592->clk); + goto clean_up2; + } + clk_enable(m66592->clk); } - clk_enable(m66592->clk); #endif INIT_LIST_HEAD(&m66592->gadget.ep_list); m66592->gadget.ep0 = &m66592->ep[0].ep; @@ -1652,12 +1692,14 @@ static int __init m66592_probe(struct platform_device *pdev) return 0; clean_up3: -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) - clk_disable(m66592->clk); - clk_put(m66592->clk); +#ifdef CONFIG_HAVE_CLK + if (m66592->pdata->on_chip) { + clk_disable(m66592->clk); + clk_put(m66592->clk); + } clean_up2: #endif - free_irq(irq, m66592); + free_irq(ires->start, m66592); clean_up: if (m66592) { if (m66592->ep0_req) diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h index 9a9c2bf9fbd5..8b960deed680 100644 --- a/drivers/usb/gadget/m66592-udc.h +++ b/drivers/usb/gadget/m66592-udc.h @@ -23,10 +23,12 @@ #ifndef __M66592_UDC_H__ #define __M66592_UDC_H__ -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) +#ifdef CONFIG_HAVE_CLK #include #endif +#include + #define M66592_SYSCFG 0x00 #define M66592_XTAL 0xC000 /* b15-14: Crystal selection */ #define M66592_XTAL48 0x8000 /* 48MHz */ @@ -76,11 +78,11 @@ #define M66592_P_TST_J 0x0001 /* PERI TEST J */ #define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) +/* built-in registers */ #define M66592_CFBCFG 0x0A #define M66592_D0FBCFG 0x0C #define M66592_LITTLE 0x0100 /* b8: Little endian mode */ -#else +/* external chip case */ #define M66592_PINCFG 0x0A #define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ #define M66592_BIGEND 0x0100 /* b8: Big endian mode */ @@ -100,8 +102,8 @@ #define M66592_PKTM 0x0020 /* b5: Packet mode */ #define M66592_DENDE 0x0010 /* b4: Dend enable */ #define M66592_OBUS 0x0004 /* b2: OUTbus mode */ -#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ +/* common case */ #define M66592_CFIFO 0x10 #define M66592_D0FIFO 0x14 #define M66592_D1FIFO 0x18 @@ -113,13 +115,9 @@ #define M66592_REW 0x4000 /* b14: Buffer rewind */ #define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ #define M66592_DREQE 0x1000 /* b12: DREQ output enable */ -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) -#define M66592_MBW 0x0800 /* b11: Maximum bit width for FIFO */ -#else -#define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO */ -#define M66592_MBW_8 0x0000 /* 8bit */ -#define M66592_MBW_16 0x0400 /* 16bit */ -#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ +#define M66592_MBW_8 0x0000 /* 8bit */ +#define M66592_MBW_16 0x0400 /* 16bit */ +#define M66592_MBW_32 0x0800 /* 32bit */ #define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ #define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ #define M66592_DEZPM 0x0080 /* b7: Zero-length packet mode */ @@ -480,9 +478,11 @@ struct m66592_ep { struct m66592 { spinlock_t lock; void __iomem *reg; -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) +#ifdef CONFIG_HAVE_CLK struct clk *clk; #endif + struct m66592_platdata *pdata; + unsigned long irq_trigger; struct usb_gadget gadget; struct usb_gadget_driver *driver; @@ -546,13 +546,13 @@ static inline void m66592_read_fifo(struct m66592 *m66592, { unsigned long fifoaddr = (unsigned long)m66592->reg + offset; -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) - len = (len + 3) / 4; - insl(fifoaddr, buf, len); -#else - len = (len + 1) / 2; - insw(fifoaddr, buf, len); -#endif + if (m66592->pdata->on_chip) { + len = (len + 3) / 4; + insl(fifoaddr, buf, len); + } else { + len = (len + 1) / 2; + insw(fifoaddr, buf, len); + } } static inline void m66592_write(struct m66592 *m66592, u16 val, @@ -566,33 +566,34 @@ static inline void m66592_write_fifo(struct m66592 *m66592, void *buf, unsigned long len) { unsigned long fifoaddr = (unsigned long)m66592->reg + offset; -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) - unsigned long count; - unsigned char *pb; - int i; - - count = len / 4; - outsl(fifoaddr, buf, count); - - if (len & 0x00000003) { - pb = buf + count * 4; - for (i = 0; i < (len & 0x00000003); i++) { - if (m66592_read(m66592, M66592_CFBCFG)) /* little */ - outb(pb[i], fifoaddr + (3 - i)); - else - outb(pb[i], fifoaddr + i); + + if (m66592->pdata->on_chip) { + unsigned long count; + unsigned char *pb; + int i; + + count = len / 4; + outsl(fifoaddr, buf, count); + + if (len & 0x00000003) { + pb = buf + count * 4; + for (i = 0; i < (len & 0x00000003); i++) { + if (m66592_read(m66592, M66592_CFBCFG)) /* le */ + outb(pb[i], fifoaddr + (3 - i)); + else + outb(pb[i], fifoaddr + i); + } + } + } else { + unsigned long odd = len & 0x0001; + + len = len / 2; + outsw(fifoaddr, buf, len); + if (odd) { + unsigned char *p = buf + len*2; + outb(*p, fifoaddr); } } -#else - unsigned long odd = len & 0x0001; - - len = len / 2; - outsw(fifoaddr, buf, len); - if (odd) { - unsigned char *p = buf + len*2; - outb(*p, fifoaddr); - } -#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ } static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, diff --git a/include/linux/usb/m66592.h b/include/linux/usb/m66592.h new file mode 100644 index 000000000000..cda9625e7df0 --- /dev/null +++ b/include/linux/usb/m66592.h @@ -0,0 +1,44 @@ +/* + * M66592 driver platform data + * + * Copyright (C) 2009 Renesas Solutions Corp. + * + * 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; 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __LINUX_USB_M66592_H +#define __LINUX_USB_M66592_H + +#define M66592_PLATDATA_XTAL_12MHZ 0x01 +#define M66592_PLATDATA_XTAL_24MHZ 0x02 +#define M66592_PLATDATA_XTAL_48MHZ 0x03 + +struct m66592_platdata { + /* one = on chip controller, zero = external controller */ + unsigned on_chip:1; + + /* one = big endian, zero = little endian */ + unsigned endian:1; + + /* (external controller only) M66592_PLATDATA_XTAL_nnMHZ */ + unsigned xtal:2; + + /* (external controller only) one = 3.3V, zero = 1.5V */ + unsigned vif:1; + +}; + +#endif /* __LINUX_USB_M66592_H */ + -- cgit v1.2.3-59-g8ed1b From 955c9863bb5855a994751843e7066017edc00410 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 22 Jul 2009 15:14:29 +0000 Subject: sh: convert processor device setup functions to arch_initcall() Convert the processor platform device setup functions from __initcall() and sometimes device_initcall() to arch_initcall(). This makes sure that the platform devices are registered a bit earlier so the devices are available when drivers register using initcall levels earlier than device_initcall(). A good example is platform devices needed by i2c-sh_mobile.c which registers a bit earlier using subsys_initcall(). Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 2 +- arch/sh/kernel/cpu/sh2a/setup-mxg.c | 2 +- arch/sh/kernel/cpu/sh2a/setup-sh7201.c | 2 +- arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 2 +- arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 2 +- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 2 +- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 2 +- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 2 +- arch/sh/kernel/cpu/sh3/setup-sh7720.c | 2 +- arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 2 +- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 2 +- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-shx3.c | 2 +- arch/sh/kernel/cpu/sh5/setup-sh5.c | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 13798733f2db..8555c05e8667 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -187,7 +187,7 @@ static int __init sh7619_devices_setup(void) return platform_add_devices(sh7619_devices, ARRAY_SIZE(sh7619_devices)); } -__initcall(sh7619_devices_setup); +arch_initcall(sh7619_devices_setup); void __init plat_irq_setup(void) { diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c index 869c2da4820b..b67376445315 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c +++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c @@ -238,7 +238,7 @@ static int __init mxg_devices_setup(void) return platform_add_devices(mxg_devices, ARRAY_SIZE(mxg_devices)); } -__initcall(mxg_devices_setup); +arch_initcall(mxg_devices_setup); void __init plat_irq_setup(void) { diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c index d8febe128066..fbde5b75deb9 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c @@ -357,7 +357,7 @@ static int __init sh7201_devices_setup(void) return platform_add_devices(sh7201_devices, ARRAY_SIZE(sh7201_devices)); } -__initcall(sh7201_devices_setup); +arch_initcall(sh7201_devices_setup); void __init plat_irq_setup(void) { diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index 62e3039d2398..d3fd536c9a84 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -367,7 +367,7 @@ static int __init sh7203_devices_setup(void) return platform_add_devices(sh7203_devices, ARRAY_SIZE(sh7203_devices)); } -__initcall(sh7203_devices_setup); +arch_initcall(sh7203_devices_setup); void __init plat_irq_setup(void) { diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index 3e6f3d7a58be..a9ccc5e8d9e9 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -338,7 +338,7 @@ static int __init sh7206_devices_setup(void) return platform_add_devices(sh7206_devices, ARRAY_SIZE(sh7206_devices)); } -__initcall(sh7206_devices_setup); +arch_initcall(sh7206_devices_setup); void __init plat_irq_setup(void) { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 88f742fed9ed..c23105983878 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -222,7 +222,7 @@ static int __init sh7705_devices_setup(void) return platform_add_devices(sh7705_devices, ARRAY_SIZE(sh7705_devices)); } -__initcall(sh7705_devices_setup); +arch_initcall(sh7705_devices_setup); static struct platform_device *sh7705_early_devices[] __initdata = { &tmu0_device, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index c56306798584..347ab35d0697 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -250,7 +250,7 @@ static int __init sh770x_devices_setup(void) return platform_add_devices(sh770x_devices, ARRAY_SIZE(sh770x_devices)); } -__initcall(sh770x_devices_setup); +arch_initcall(sh770x_devices_setup); static struct platform_device *sh770x_early_devices[] __initdata = { &tmu0_device, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index efa76c8148f4..717e90ae1097 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -226,7 +226,7 @@ static int __init sh7710_devices_setup(void) return platform_add_devices(sh7710_devices, ARRAY_SIZE(sh7710_devices)); } -__initcall(sh7710_devices_setup); +arch_initcall(sh7710_devices_setup); static struct platform_device *sh7710_early_devices[] __initdata = { &tmu0_device, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 5b2107798edb..74d8baaf8e96 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -388,7 +388,7 @@ static int __init sh7720_devices_setup(void) return platform_add_devices(sh7720_devices, ARRAY_SIZE(sh7720_devices)); } -__initcall(sh7720_devices_setup); +arch_initcall(sh7720_devices_setup); static struct platform_device *sh7720_early_devices[] __initdata = { &cmt0_device, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index 6d088d123591..de4827df19aa 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -138,7 +138,7 @@ static int __init sh4202_devices_setup(void) return platform_add_devices(sh4202_devices, ARRAY_SIZE(sh4202_devices)); } -__initcall(sh4202_devices_setup); +arch_initcall(sh4202_devices_setup); static struct platform_device *sh4202_early_devices[] __initdata = { &tmu0_device, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 851672d15cf4..1b8b122e8f3d 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -239,7 +239,7 @@ static int __init sh7750_devices_setup(void) return platform_add_devices(sh7750_devices, ARRAY_SIZE(sh7750_devices)); } -__initcall(sh7750_devices_setup); +arch_initcall(sh7750_devices_setup); static struct platform_device *sh7750_early_devices[] __initdata = { &tmu0_device, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 5b822519bd90..7fbb7be9284c 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -265,7 +265,7 @@ static int __init sh7760_devices_setup(void) return platform_add_devices(sh7760_devices, ARRAY_SIZE(sh7760_devices)); } -__initcall(sh7760_devices_setup); +arch_initcall(sh7760_devices_setup); static struct platform_device *sh7760_early_devices[] __initdata = { &tmu0_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index 6307e087c864..ac4d5672ec1a 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -325,7 +325,7 @@ static int __init sh7343_devices_setup(void) return platform_add_devices(sh7343_devices, ARRAY_SIZE(sh7343_devices)); } -__initcall(sh7343_devices_setup); +arch_initcall(sh7343_devices_setup); static struct platform_device *sh7343_early_devices[] __initdata = { &cmt_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index f6d208813564..4a9010bf4fd3 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -318,7 +318,7 @@ static int __init sh7366_devices_setup(void) return platform_add_devices(sh7366_devices, ARRAY_SIZE(sh7366_devices)); } -__initcall(sh7366_devices_setup); +arch_initcall(sh7366_devices_setup); static struct platform_device *sh7366_early_devices[] __initdata = { &cmt_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 0bad14a44238..67b0d87fcb27 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -365,7 +365,7 @@ static int __init sh7722_devices_setup(void) return platform_add_devices(sh7722_devices, ARRAY_SIZE(sh7722_devices)); } -__initcall(sh7722_devices_setup); +arch_initcall(sh7722_devices_setup); static struct platform_device *sh7722_early_devices[] __initdata = { &cmt_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 28516499a2c4..26dc4d323252 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -473,7 +473,7 @@ static int __init sh7723_devices_setup(void) return platform_add_devices(sh7723_devices, ARRAY_SIZE(sh7723_devices)); } -__initcall(sh7723_devices_setup); +arch_initcall(sh7723_devices_setup); static struct platform_device *sh7723_early_devices[] __initdata = { &cmt_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index e5ac9eb11c63..a04edaab9a29 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -508,7 +508,7 @@ static int __init sh7724_devices_setup(void) return platform_add_devices(sh7724_devices, ARRAY_SIZE(sh7724_devices)); } -device_initcall(sh7724_devices_setup); +arch_initcall(sh7724_devices_setup); static struct platform_device *sh7724_early_devices[] __initdata = { &cmt_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index f1e0c0d36da7..4659fff6b842 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -314,7 +314,7 @@ static int __init sh7763_devices_setup(void) return platform_add_devices(sh7763_devices, ARRAY_SIZE(sh7763_devices)); } -__initcall(sh7763_devices_setup); +arch_initcall(sh7763_devices_setup); static struct platform_device *sh7763_early_devices[] __initdata = { &tmu0_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index 1e86209db284..eead08d89d32 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -368,7 +368,7 @@ static int __init sh7770_devices_setup(void) return platform_add_devices(sh7770_devices, ARRAY_SIZE(sh7770_devices)); } -__initcall(sh7770_devices_setup); +arch_initcall(sh7770_devices_setup); static struct platform_device *sh7770_early_devices[] __initdata = { &tmu0_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 715e05b431e5..2c901f446959 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -256,7 +256,7 @@ static int __init sh7780_devices_setup(void) return platform_add_devices(sh7780_devices, ARRAY_SIZE(sh7780_devices)); } -__initcall(sh7780_devices_setup); +arch_initcall(sh7780_devices_setup); static struct platform_device *sh7780_early_devices[] __initdata = { &tmu0_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index af561402570b..7f6c718b6c36 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -263,7 +263,7 @@ static int __init sh7785_devices_setup(void) return platform_add_devices(sh7785_devices, ARRAY_SIZE(sh7785_devices)); } -__initcall(sh7785_devices_setup); +arch_initcall(sh7785_devices_setup); static struct platform_device *sh7785_early_devices[] __initdata = { &tmu0_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index b70049470a0b..0104a8ec5369 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -547,7 +547,7 @@ static int __init sh7786_devices_setup(void) return platform_add_devices(sh7786_devices, ARRAY_SIZE(sh7786_devices)); } -device_initcall(sh7786_devices_setup); +arch_initcall(sh7786_devices_setup); void __init plat_early_device_setup(void) { diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 53c65fd9ccef..07f078961c71 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -256,7 +256,7 @@ static int __init shx3_devices_setup(void) return platform_add_devices(shx3_devices, ARRAY_SIZE(shx3_devices)); } -__initcall(shx3_devices_setup); +arch_initcall(shx3_devices_setup); void __init plat_early_device_setup(void) { diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c index f5ff1ac57fc2..6a0f82f70032 100644 --- a/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c @@ -186,7 +186,7 @@ static int __init sh5_devices_setup(void) return platform_add_devices(sh5_devices, ARRAY_SIZE(sh5_devices)); } -__initcall(sh5_devices_setup); +arch_initcall(sh5_devices_setup); void __init plat_early_device_setup(void) { -- cgit v1.2.3-59-g8ed1b From e7d165146a7de5ceb4f68e188b2679f003744f54 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 22 Jul 2009 16:20:54 +0000 Subject: sh: kfr2r09 board support - SCIF console This patch adds basic kfr2r09 board support. Only the SCIF1 console is supported with this patch, but this patch and a proper sh7724 configuration is all that is needed. Combine with an initramfs to have a small RAM based kernel and distribution booted as zImage from RAM via JTAG. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/Makefile | 1 + arch/sh/boards/Kconfig | 7 ++++++ arch/sh/boards/mach-kfr2r09/Makefile | 1 + arch/sh/boards/mach-kfr2r09/setup.c | 48 ++++++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+) create mode 100644 arch/sh/boards/mach-kfr2r09/Makefile create mode 100644 arch/sh/boards/mach-kfr2r09/setup.c (limited to 'arch/sh') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 75d049b03f7e..d7358d70f154 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -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 diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index 2b1af0eefa6a..db04c85971ad 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig @@ -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 diff --git a/arch/sh/boards/mach-kfr2r09/Makefile b/arch/sh/boards/mach-kfr2r09/Makefile new file mode 100644 index 000000000000..77037567633b --- /dev/null +++ b/arch/sh/boards/mach-kfr2r09/Makefile @@ -0,0 +1 @@ +obj-y := setup.o diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c new file mode 100644 index 000000000000..224318abc9e6 --- /dev/null +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -0,0 +1,48 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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); + + return 0; +} +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, +}; -- cgit v1.2.3-59-g8ed1b From a366aa64f3a51ca3deebe74447f929a5614d9b90 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 22 Jul 2009 16:22:28 +0000 Subject: sh: kfr2r09 board support - NOR flash This patch adds NOR flash support to the kfr2r09 board. NOR flash support is added by describing the NOR flash chip hooked up to CS0 as platform device data for the physmap-flash MTD driver. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-kfr2r09/setup.c | 54 ++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 224318abc9e6..382bf1884300 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -18,13 +19,64 @@ #include #include +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 platform_device *kfr2r09_devices[] __initdata = { + &kfr2r09_nor_flash_device, +}; + +#define BSC_CS0BCR 0xfec10004 +#define BSC_CS0WCR 0xfec10024 + 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); - return 0; + /* setup NOR flash at CS0 */ + ctrl_outl(0x36db0400, BSC_CS0BCR); + ctrl_outl(0x00000500, BSC_CS0WCR); + + return platform_add_devices(kfr2r09_devices, + ARRAY_SIZE(kfr2r09_devices)); } device_initcall(kfr2r09_devices_setup); -- cgit v1.2.3-59-g8ed1b From 39a6bf1426af4aed2348bb533481027862346a37 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 22 Jul 2009 16:23:45 +0000 Subject: sh: kfr2r09 board support - KEYSC keypad This patch adds KEYSC keypad support to the kfr2r09 board. The keys driven by the sh7724 on-chip KEYSC block are described as a platform device and platform data for the sh_keysc driver. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-kfr2r09/setup.c | 53 +++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 382bf1884300..bf5f8f8d3b5f 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -14,9 +14,11 @@ #include #include #include +#include #include #include #include +#include #include static struct mtd_partition kfr2r09_nor_flash_partitions[] = @@ -58,8 +60,46 @@ static struct platform_device kfr2r09_nor_flash_device = { }, }; +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, + }, +}; + static struct platform_device *kfr2r09_devices[] __initdata = { &kfr2r09_nor_flash_device, + &kfr2r09_sh_keysc_device, }; #define BSC_CS0BCR 0xfec10004 @@ -75,6 +115,19 @@ static int __init kfr2r09_devices_setup(void) ctrl_outl(0x36db0400, BSC_CS0BCR); ctrl_outl(0x00000500, BSC_CS0WCR); + /* 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); + return platform_add_devices(kfr2r09_devices, ARRAY_SIZE(kfr2r09_devices)); } -- cgit v1.2.3-59-g8ed1b From 5bdef865eb358b6f3760e25e591ae115e9eeddef Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 23 Jul 2009 08:59:48 +0000 Subject: sh: kfr2r09 board support - mach-type and defconfig This patch adds a defconfig and a mach-types entry for the kfr2r09 board. At this point only a few devices like SCIF, KEYSC and NOR Flash are supported together with sh7724 devices such as IIC0, IIC1 and the multimedia blocks exported via UIO. Kexec is supported, but booting from flash is not (yet). Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/configs/kfr2r09_defconfig | 877 ++++++++++++++++++++++++++++++++++++++ arch/sh/tools/mach-types | 1 + 2 files changed, 878 insertions(+) create mode 100644 arch/sh/configs/kfr2r09_defconfig (limited to 'arch/sh') diff --git a/arch/sh/configs/kfr2r09_defconfig b/arch/sh/configs/kfr2r09_defconfig new file mode 100644 index 000000000000..90e575c34d58 --- /dev/null +++ b/arch/sh/configs/kfr2r09_defconfig @@ -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 diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index fec3a53b8650..09eef360dde1 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types @@ -56,3 +56,4 @@ SH7785LCR SH_SH7785LCR URQUELL SH_URQUELL ESPT SH_ESPT POLARIS SH_POLARIS +KFR2R09 SH_KFR2R09 -- cgit v1.2.3-59-g8ed1b From dfff0fa65ab15db45acd64b3189787d37ab163cd Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 27 Jul 2009 20:53:22 +0900 Subject: sh: wire up clear_user_highpage() for sh4, convert sh7705. This wires up clear_user_highpage() on SH-4 and subsequently converts the SH7705 32kB cache mode over to using it. Now that the SH-4 implementation handles all of the dcache purging directly in the aliasing case, there is no need to do this in the default clear_page() implementation. Signed-off-by: Paul Mundt --- arch/sh/include/asm/cacheflush.h | 2 +- arch/sh/include/asm/page.h | 12 +++-- arch/sh/include/asm/pgtable.h | 3 +- arch/sh/kernel/sh_ksyms_32.c | 6 --- arch/sh/lib/clear_page.S | 46 ------------------ arch/sh/mm/Makefile_32 | 2 +- arch/sh/mm/pg-nommu.c | 7 +-- arch/sh/mm/pg-sh4.c | 29 ++++++----- arch/sh/mm/pg-sh7705.c | 102 --------------------------------------- 9 files changed, 27 insertions(+), 182 deletions(-) delete mode 100644 arch/sh/mm/pg-sh7705.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h index 4c5462daa74c..4e360114269d 100644 --- a/arch/sh/include/asm/cacheflush.h +++ b/arch/sh/include/asm/cacheflush.h @@ -49,7 +49,7 @@ static inline void flush_kernel_dcache_page(struct page *page) flush_dcache_page(page); } -#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_CACHE_OFF) +#if (defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)) && !defined(CONFIG_CACHE_OFF) extern void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len); diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index a31ab40040f0..5208b7bfc24e 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -56,21 +56,25 @@ pages_do_alias(unsigned long addr1, unsigned long addr2) return (addr1 ^ addr2) & shm_align_mask; } -extern void clear_page(void *to); + +#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) extern void copy_page(void *to, void *from); +struct page; +struct vm_area_struct; + #if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \ (defined(CONFIG_CPU_SH5) || defined(CONFIG_CPU_SH4) || \ defined(CONFIG_SH7705_CACHE_32KB)) -struct page; -struct vm_area_struct; extern void clear_user_page(void *to, unsigned long address, struct page *page); extern void copy_user_page(void *to, void *from, unsigned long address, struct page *page); -#if defined(CONFIG_CPU_SH4) +#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) extern void copy_user_highpage(struct page *to, struct page *from, unsigned long vaddr, struct vm_area_struct *vma); #define __HAVE_ARCH_COPY_USER_HIGHPAGE +extern void clear_user_highpage(struct page *page, unsigned long vaddr); +#define clear_user_highpage clear_user_highpage #endif #else #define clear_user_page(page, vaddr, pg) clear_page(page) diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index d9f68f9c3cb3..bef3ab7fc09e 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -141,7 +141,8 @@ extern void paging_init(void); extern void page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd); -#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_CPU_SH4) && defined(CONFIG_MMU) +#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \ + defined(CONFIG_SH7705_CACHE_32KB)) && defined(CONFIG_MMU) extern void kmap_coherent_init(void); #else #define kmap_coherent_init() do { } while (0) diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c index cec610888e28..8dbe26b17c44 100644 --- a/arch/sh/kernel/sh_ksyms_32.c +++ b/arch/sh/kernel/sh_ksyms_32.c @@ -101,11 +101,6 @@ EXPORT_SYMBOL(flush_cache_range); EXPORT_SYMBOL(flush_dcache_page); #endif -#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \ - (defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)) -EXPORT_SYMBOL(clear_user_page); -#endif - #ifdef CONFIG_MCOUNT DECLARE_EXPORT(mcount); #endif @@ -114,7 +109,6 @@ EXPORT_SYMBOL(csum_partial_copy_generic); #ifdef CONFIG_IPV6 EXPORT_SYMBOL(csum_ipv6_magic); #endif -EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(_ebss); diff --git a/arch/sh/lib/clear_page.S b/arch/sh/lib/clear_page.S index 8342bfbde64c..bee9817e055d 100644 --- a/arch/sh/lib/clear_page.S +++ b/arch/sh/lib/clear_page.S @@ -8,52 +8,6 @@ #include #include -/* - * clear_page - * @to: P1 address - * - * void clear_page(void *to) - */ - -/* - * r0 --- scratch - * r4 --- to - * r5 --- to + PAGE_SIZE - */ -ENTRY(clear_page) - mov r4,r5 - mov.l .Llimit,r0 - add r0,r5 - mov #0,r0 - ! -1: -#if defined(CONFIG_CPU_SH4) - movca.l r0,@r4 - mov r4,r1 -#else - mov.l r0,@r4 -#endif - add #32,r4 - mov.l r0,@-r4 - mov.l r0,@-r4 - mov.l r0,@-r4 - mov.l r0,@-r4 - mov.l r0,@-r4 - mov.l r0,@-r4 - mov.l r0,@-r4 -#if defined(CONFIG_CPU_SH4) - ocbwb @r1 -#endif - cmp/eq r5,r4 - bf/s 1b - add #28,r4 - ! - rts - nop - - .balign 4 -.Llimit: .long (PAGE_SIZE-28) - ENTRY(__clear_user) ! mov #0, r0 diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32 index 986a1e055834..5c04bbb08d36 100644 --- a/arch/sh/mm/Makefile_32 +++ b/arch/sh/mm/Makefile_32 @@ -31,7 +31,7 @@ tlb-$(CONFIG_CPU_HAS_PTEAEX) := tlb-pteaex.o obj-y += $(tlb-y) ifndef CONFIG_CACHE_OFF obj-$(CONFIG_CPU_SH4) += pg-sh4.o -obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o +obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh4.o endif endif diff --git a/arch/sh/mm/pg-nommu.c b/arch/sh/mm/pg-nommu.c index 91ed4e695ff7..7e33b486b7e9 100644 --- a/arch/sh/mm/pg-nommu.c +++ b/arch/sh/mm/pg-nommu.c @@ -1,7 +1,7 @@ /* * arch/sh/mm/pg-nommu.c * - * clear_page()/copy_page() implementation for MMUless SH. + * copy_page()/__copy_user()/__clear_user() implementations for MMUless SH. * * Copyright (C) 2003 Paul Mundt * @@ -20,11 +20,6 @@ void copy_page(void *to, void *from) memcpy(to, from, PAGE_SIZE); } -void clear_page(void *to) -{ - memset(to, 0, PAGE_SIZE); -} - __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n) { memcpy(to, from, n); diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c index f3c4b2a54fc7..4d93070b8220 100644 --- a/arch/sh/mm/pg-sh4.c +++ b/arch/sh/mm/pg-sh4.c @@ -2,7 +2,7 @@ * arch/sh/mm/pg-sh4.c * * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2002 - 2007 Paul Mundt + * Copyright (C) 2002 - 2009 Paul Mundt * * Released under the terms of the GNU GPL v2.0. */ @@ -58,20 +58,6 @@ static inline void kunmap_coherent(struct page *page) preempt_check_resched(); } -/* - * clear_user_page - * @to: P1 address - * @address: U0 address to be mapped - * @page: page (virt_to_page(to)) - */ -void clear_user_page(void *to, unsigned long address, struct page *page) -{ - clear_page(to); - - if (pages_do_alias((unsigned long)to, address & PAGE_MASK)) - __flush_wback_region(to, PAGE_SIZE); -} - void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len) @@ -128,3 +114,16 @@ void copy_user_highpage(struct page *to, struct page *from, smp_wmb(); } EXPORT_SYMBOL(copy_user_highpage); + +void clear_user_highpage(struct page *page, unsigned long vaddr) +{ + void *kaddr = kmap_atomic(page, KM_USER0); + + clear_page(kaddr); + + if (pages_do_alias((unsigned long)kaddr, vaddr & PAGE_MASK)) + __flush_wback_region(kaddr, PAGE_SIZE); + + kunmap_atomic(kaddr, KM_USER0); +} +EXPORT_SYMBOL(clear_user_highpage); diff --git a/arch/sh/mm/pg-sh7705.c b/arch/sh/mm/pg-sh7705.c deleted file mode 100644 index 684891b5c8c0..000000000000 --- a/arch/sh/mm/pg-sh7705.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * arch/sh/mm/pg-sh7705.c - * - * Copyright (C) 1999, 2000 Niibe Yutaka - * Copyright (C) 2004 Alex Song - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void __flush_purge_virtual_region(void *p1, void *virt, int size) -{ - unsigned long v; - unsigned long begin, end; - unsigned long p1_begin; - - - begin = L1_CACHE_ALIGN((unsigned long)virt); - end = L1_CACHE_ALIGN((unsigned long)virt + size); - - p1_begin = (unsigned long)p1 & ~(L1_CACHE_BYTES - 1); - - /* do this the slow way as we may not have TLB entries - * for virt yet. */ - for (v = begin; v < end; v += L1_CACHE_BYTES) { - unsigned long p; - unsigned long ways, addr; - - p = __pa(p1_begin); - - ways = current_cpu_data.dcache.ways; - addr = CACHE_OC_ADDRESS_ARRAY; - - do { - unsigned long data; - - addr |= (v & current_cpu_data.dcache.entry_mask); - - data = ctrl_inl(addr); - if ((data & CACHE_PHYSADDR_MASK) == - (p & CACHE_PHYSADDR_MASK)) { - data &= ~(SH_CACHE_UPDATED|SH_CACHE_VALID); - ctrl_outl(data, addr); - } - - addr += current_cpu_data.dcache.way_incr; - } while (--ways); - - p1_begin += L1_CACHE_BYTES; - } -} - -/* - * clear_user_page - * @to: P1 address - * @address: U0 address to be mapped - */ -void clear_user_page(void *to, unsigned long address, struct page *pg) -{ - if (pages_do_alias(address, (unsigned long)to)) - __flush_purge_virtual_region(to, - (void *)(address & 0xfffff000), - PAGE_SIZE); - - clear_page(to); - __flush_wback_region(to, PAGE_SIZE); -} - -/* - * copy_user_page - * @to: P1 address - * @from: P1 address - * @address: U0 address to be mapped - */ -void copy_user_page(void *to, void *from, unsigned long address, struct page *pg) -{ - if (pages_do_alias(address, (unsigned long)to)) - __flush_purge_virtual_region(to, - (void *)(address & 0xfffff000), - PAGE_SIZE); - - copy_page(to, from); - __flush_wback_region(to, PAGE_SIZE); -} -- cgit v1.2.3-59-g8ed1b From 221c007b028ebf663ebee4fc90483909547d92a7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 27 Jul 2009 20:55:46 +0900 Subject: sh: Rename arch/sh/lib/clear_page.S -> __clear_user.S. Now that this only contains the __clear_user() function, rename it accordingly. Signed-off-by: Paul Mundt --- arch/sh/lib/Makefile | 2 +- arch/sh/lib/__clear_user.S | 108 +++++++++++++++++++++++++++++++++++++++++++++ arch/sh/lib/clear_page.S | 108 --------------------------------------------- 3 files changed, 109 insertions(+), 109 deletions(-) create mode 100644 arch/sh/lib/__clear_user.S delete mode 100644 arch/sh/lib/clear_page.S (limited to 'arch/sh') diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile index c2b28d8b2dd1..a969b47c5463 100644 --- a/arch/sh/lib/Makefile +++ b/arch/sh/lib/Makefile @@ -23,7 +23,7 @@ obj-y += io.o memcpy-y := memcpy.o memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o -lib-$(CONFIG_MMU) += copy_page.o clear_page.o +lib-$(CONFIG_MMU) += copy_page.o __clear_user.o lib-$(CONFIG_MCOUNT) += mcount.o lib-y += $(memcpy-y) $(udivsi3-y) diff --git a/arch/sh/lib/__clear_user.S b/arch/sh/lib/__clear_user.S new file mode 100644 index 000000000000..bee9817e055d --- /dev/null +++ b/arch/sh/lib/__clear_user.S @@ -0,0 +1,108 @@ +/* + * __clear_user_page, __clear_user, clear_page implementation of SuperH + * + * Copyright (C) 2001 Kaz Kojima + * Copyright (C) 2001, 2002 Niibe Yutaka + * Copyright (C) 2006 Paul Mundt + */ +#include +#include + +ENTRY(__clear_user) + ! + mov #0, r0 + mov #0xe0, r1 ! 0xffffffe0 + ! + ! r4..(r4+31)&~32 -------- not aligned [ Area 0 ] + ! (r4+31)&~32..(r4+r5)&~32 -------- aligned [ Area 1 ] + ! (r4+r5)&~32..r4+r5 -------- not aligned [ Area 2 ] + ! + ! Clear area 0 + mov r4, r2 + ! + tst r1, r5 ! length < 32 + bt .Larea2 ! skip to remainder + ! + add #31, r2 + and r1, r2 + cmp/eq r4, r2 + bt .Larea1 + mov r2, r3 + sub r4, r3 + mov r3, r7 + mov r4, r2 + ! +.L0: dt r3 +0: mov.b r0, @r2 + bf/s .L0 + add #1, r2 + ! + sub r7, r5 + mov r2, r4 +.Larea1: + mov r4, r3 + add r5, r3 + and r1, r3 + cmp/hi r2, r3 + bf .Larea2 + ! + ! Clear area 1 +#if defined(CONFIG_CPU_SH4) +1: movca.l r0, @r2 +#else +1: mov.l r0, @r2 +#endif + add #4, r2 +2: mov.l r0, @r2 + add #4, r2 +3: mov.l r0, @r2 + add #4, r2 +4: mov.l r0, @r2 + add #4, r2 +5: mov.l r0, @r2 + add #4, r2 +6: mov.l r0, @r2 + add #4, r2 +7: mov.l r0, @r2 + add #4, r2 +8: mov.l r0, @r2 + add #4, r2 + cmp/hi r2, r3 + bt/s 1b + nop + ! + ! Clear area 2 +.Larea2: + mov r4, r3 + add r5, r3 + cmp/hs r3, r2 + bt/s .Ldone + sub r2, r3 +.L2: dt r3 +9: mov.b r0, @r2 + bf/s .L2 + add #1, r2 + ! +.Ldone: rts + mov #0, r0 ! return 0 as normal return + + ! return the number of bytes remained +.Lbad_clear_user: + mov r4, r0 + add r5, r0 + rts + sub r2, r0 + +.section __ex_table,"a" + .align 2 + .long 0b, .Lbad_clear_user + .long 1b, .Lbad_clear_user + .long 2b, .Lbad_clear_user + .long 3b, .Lbad_clear_user + .long 4b, .Lbad_clear_user + .long 5b, .Lbad_clear_user + .long 6b, .Lbad_clear_user + .long 7b, .Lbad_clear_user + .long 8b, .Lbad_clear_user + .long 9b, .Lbad_clear_user +.previous diff --git a/arch/sh/lib/clear_page.S b/arch/sh/lib/clear_page.S deleted file mode 100644 index bee9817e055d..000000000000 --- a/arch/sh/lib/clear_page.S +++ /dev/null @@ -1,108 +0,0 @@ -/* - * __clear_user_page, __clear_user, clear_page implementation of SuperH - * - * Copyright (C) 2001 Kaz Kojima - * Copyright (C) 2001, 2002 Niibe Yutaka - * Copyright (C) 2006 Paul Mundt - */ -#include -#include - -ENTRY(__clear_user) - ! - mov #0, r0 - mov #0xe0, r1 ! 0xffffffe0 - ! - ! r4..(r4+31)&~32 -------- not aligned [ Area 0 ] - ! (r4+31)&~32..(r4+r5)&~32 -------- aligned [ Area 1 ] - ! (r4+r5)&~32..r4+r5 -------- not aligned [ Area 2 ] - ! - ! Clear area 0 - mov r4, r2 - ! - tst r1, r5 ! length < 32 - bt .Larea2 ! skip to remainder - ! - add #31, r2 - and r1, r2 - cmp/eq r4, r2 - bt .Larea1 - mov r2, r3 - sub r4, r3 - mov r3, r7 - mov r4, r2 - ! -.L0: dt r3 -0: mov.b r0, @r2 - bf/s .L0 - add #1, r2 - ! - sub r7, r5 - mov r2, r4 -.Larea1: - mov r4, r3 - add r5, r3 - and r1, r3 - cmp/hi r2, r3 - bf .Larea2 - ! - ! Clear area 1 -#if defined(CONFIG_CPU_SH4) -1: movca.l r0, @r2 -#else -1: mov.l r0, @r2 -#endif - add #4, r2 -2: mov.l r0, @r2 - add #4, r2 -3: mov.l r0, @r2 - add #4, r2 -4: mov.l r0, @r2 - add #4, r2 -5: mov.l r0, @r2 - add #4, r2 -6: mov.l r0, @r2 - add #4, r2 -7: mov.l r0, @r2 - add #4, r2 -8: mov.l r0, @r2 - add #4, r2 - cmp/hi r2, r3 - bt/s 1b - nop - ! - ! Clear area 2 -.Larea2: - mov r4, r3 - add r5, r3 - cmp/hs r3, r2 - bt/s .Ldone - sub r2, r3 -.L2: dt r3 -9: mov.b r0, @r2 - bf/s .L2 - add #1, r2 - ! -.Ldone: rts - mov #0, r0 ! return 0 as normal return - - ! return the number of bytes remained -.Lbad_clear_user: - mov r4, r0 - add r5, r0 - rts - sub r2, r0 - -.section __ex_table,"a" - .align 2 - .long 0b, .Lbad_clear_user - .long 1b, .Lbad_clear_user - .long 2b, .Lbad_clear_user - .long 3b, .Lbad_clear_user - .long 4b, .Lbad_clear_user - .long 5b, .Lbad_clear_user - .long 6b, .Lbad_clear_user - .long 7b, .Lbad_clear_user - .long 8b, .Lbad_clear_user - .long 9b, .Lbad_clear_user -.previous -- cgit v1.2.3-59-g8ed1b From 0dfae7d5a21901b28ec0452d71be64adf5ea323e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 27 Jul 2009 21:30:17 +0900 Subject: sh: Use the now generic SH-4 clear/copy page ops for all MMU platforms. Now that the SH-4 page clear/copy ops are generic, they can be used for all platforms with CONFIG_MMU=y. SH-5 remains the odd one out, but it too will gradually be converted over to using this interface. SH-3 platforms which do not contain aliases will see no impact from this change, while aliasing SH-3 platforms will get the same interface as SH-4. Signed-off-by: Paul Mundt --- arch/sh/include/asm/cacheflush.h | 15 ----- arch/sh/include/asm/page.h | 11 ++-- arch/sh/include/asm/pgtable.h | 3 +- arch/sh/mm/Makefile_32 | 6 +- arch/sh/mm/cache-sh5.c | 17 +++++ arch/sh/mm/pg-mmu.c | 136 +++++++++++++++++++++++++++++++++++++++ arch/sh/mm/pg-sh4.c | 129 ------------------------------------- 7 files changed, 161 insertions(+), 156 deletions(-) create mode 100644 arch/sh/mm/pg-mmu.c delete mode 100644 arch/sh/mm/pg-sh4.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h index 4e360114269d..4c85d55847cc 100644 --- a/arch/sh/include/asm/cacheflush.h +++ b/arch/sh/include/asm/cacheflush.h @@ -49,7 +49,6 @@ static inline void flush_kernel_dcache_page(struct page *page) flush_dcache_page(page); } -#if (defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)) && !defined(CONFIG_CACHE_OFF) extern void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len); @@ -57,20 +56,6 @@ extern void copy_to_user_page(struct vm_area_struct *vma, extern void copy_from_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len); -#else -#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ - do { \ - flush_cache_page(vma, vaddr, page_to_pfn(page));\ - memcpy(dst, src, len); \ - flush_icache_user_range(vma, page, vaddr, len); \ - } while (0) - -#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ - do { \ - flush_cache_page(vma, vaddr, page_to_pfn(page));\ - memcpy(dst, src, len); \ - } while (0) -#endif #define flush_cache_vmap(start, end) flush_cache_all() #define flush_cache_vunmap(start, end) flush_cache_all() diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 5208b7bfc24e..847eeabb9083 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -63,22 +63,23 @@ extern void copy_page(void *to, void *from); struct page; struct vm_area_struct; -#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \ - (defined(CONFIG_CPU_SH5) || defined(CONFIG_CPU_SH4) || \ - defined(CONFIG_SH7705_CACHE_32KB)) +#if defined(CONFIG_CPU_SH5) extern void clear_user_page(void *to, unsigned long address, struct page *page); extern void copy_user_page(void *to, void *from, unsigned long address, struct page *page); -#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) + +#elif defined(CONFIG_MMU) extern void copy_user_highpage(struct page *to, struct page *from, unsigned long vaddr, struct vm_area_struct *vma); #define __HAVE_ARCH_COPY_USER_HIGHPAGE extern void clear_user_highpage(struct page *page, unsigned long vaddr); #define clear_user_highpage clear_user_highpage -#endif + #else + #define clear_user_page(page, vaddr, pg) clear_page(page) #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) + #endif /* diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index bef3ab7fc09e..ba2333216c5b 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -141,8 +141,7 @@ extern void paging_init(void); extern void page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd); -#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \ - defined(CONFIG_SH7705_CACHE_32KB)) && defined(CONFIG_MMU) +#if defined(CONFIG_MMU) && !defined(CONFIG_CPU_SH5) extern void kmap_coherent_init(void); #else #define kmap_coherent_init() do { } while (0) diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32 index 5c04bbb08d36..62e280734dcb 100644 --- a/arch/sh/mm/Makefile_32 +++ b/arch/sh/mm/Makefile_32 @@ -15,7 +15,7 @@ endif obj-y += $(cache-y) mmu-y := tlb-nommu.o pg-nommu.o -mmu-$(CONFIG_MMU) := fault_32.o tlbflush_32.o ioremap_32.o +mmu-$(CONFIG_MMU) := fault_32.o tlbflush_32.o ioremap_32.o pg-mmu.o obj-y += $(mmu-y) obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o @@ -29,10 +29,6 @@ tlb-$(CONFIG_CPU_SH3) := tlb-sh3.o tlb-$(CONFIG_CPU_SH4) := tlb-sh4.o tlb-$(CONFIG_CPU_HAS_PTEAEX) := tlb-pteaex.o obj-y += $(tlb-y) -ifndef CONFIG_CACHE_OFF -obj-$(CONFIG_CPU_SH4) += pg-sh4.o -obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh4.o -endif endif obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o diff --git a/arch/sh/mm/cache-sh5.c b/arch/sh/mm/cache-sh5.c index 86762092508c..3e2d7321b636 100644 --- a/arch/sh/mm/cache-sh5.c +++ b/arch/sh/mm/cache-sh5.c @@ -831,4 +831,21 @@ void clear_user_page(void *to, unsigned long address, struct page *page) else sh64_clear_user_page_coloured(to, address); } + +void copy_to_user_page(struct vm_area_struct *vma, struct page *page, + unsigned long vaddr, void *dst, const void *src, + unsigned long len) +{ + flush_cache_page(vma, vaddr, page_to_pfn(page)); + memcpy(dst, src, len); + flush_icache_user_range(vma, page, vaddr, len); +} + +void copy_from_user_page(struct vm_area_struct *vma, struct page *page, + unsigned long vaddr, void *dst, const void *src, + unsigned long len) +{ + flush_cache_page(vma, vaddr, page_to_pfn(page)); + memcpy(dst, src, len); +} #endif diff --git a/arch/sh/mm/pg-mmu.c b/arch/sh/mm/pg-mmu.c new file mode 100644 index 000000000000..356d2cdcb209 --- /dev/null +++ b/arch/sh/mm/pg-mmu.c @@ -0,0 +1,136 @@ +/* + * arch/sh/mm/pg-mmu.c + * + * Copyright (C) 1999, 2000, 2002 Niibe Yutaka + * Copyright (C) 2002 - 2009 Paul Mundt + * + * Released under the terms of the GNU GPL v2.0. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define kmap_get_fixmap_pte(vaddr) \ + pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) + +static pte_t *kmap_coherent_pte; + +void __init kmap_coherent_init(void) +{ +#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) + unsigned long vaddr; + + /* cache the first coherent kmap pte */ + vaddr = __fix_to_virt(FIX_CMAP_BEGIN); + kmap_coherent_pte = kmap_get_fixmap_pte(vaddr); +#endif +} + +static inline void *kmap_coherent(struct page *page, unsigned long addr) +{ + enum fixed_addresses idx; + unsigned long vaddr, flags; + pte_t pte; + + inc_preempt_count(); + + idx = (addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT; + vaddr = __fix_to_virt(FIX_CMAP_END - idx); + pte = mk_pte(page, PAGE_KERNEL); + + local_irq_save(flags); + flush_tlb_one(get_asid(), vaddr); + local_irq_restore(flags); + + update_mmu_cache(NULL, vaddr, pte); + + set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte); + + return (void *)vaddr; +} + +static inline void kunmap_coherent(struct page *page) +{ + dec_preempt_count(); + preempt_check_resched(); +} + +void copy_to_user_page(struct vm_area_struct *vma, struct page *page, + unsigned long vaddr, void *dst, const void *src, + unsigned long len) +{ + if (boot_cpu_data.dcache.n_aliases && page_mapped(page) && + !test_bit(PG_dcache_dirty, &page->flags)) { + void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); + memcpy(vto, src, len); + kunmap_coherent(vto); + } else { + memcpy(dst, src, len); + if (boot_cpu_data.dcache.n_aliases) + set_bit(PG_dcache_dirty, &page->flags); + } + + if (vma->vm_flags & VM_EXEC) + flush_cache_page(vma, vaddr, page_to_pfn(page)); +} + +void copy_from_user_page(struct vm_area_struct *vma, struct page *page, + unsigned long vaddr, void *dst, const void *src, + unsigned long len) +{ + if (boot_cpu_data.dcache.n_aliases && page_mapped(page) && + !test_bit(PG_dcache_dirty, &page->flags)) { + void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); + memcpy(dst, vfrom, len); + kunmap_coherent(vfrom); + } else { + memcpy(dst, src, len); + if (boot_cpu_data.dcache.n_aliases) + set_bit(PG_dcache_dirty, &page->flags); + } +} + +void copy_user_highpage(struct page *to, struct page *from, + unsigned long vaddr, struct vm_area_struct *vma) +{ + void *vfrom, *vto; + + vto = kmap_atomic(to, KM_USER1); + + if (boot_cpu_data.dcache.n_aliases && page_mapped(from) && + !test_bit(PG_dcache_dirty, &from->flags)) { + vfrom = kmap_coherent(from, vaddr); + copy_page(vto, vfrom); + kunmap_coherent(vfrom); + } else { + vfrom = kmap_atomic(from, KM_USER0); + copy_page(vto, vfrom); + kunmap_atomic(vfrom, KM_USER0); + } + + if (pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK)) + __flush_wback_region(vto, PAGE_SIZE); + + kunmap_atomic(vto, KM_USER1); + /* Make sure this page is cleared on other CPU's too before using it */ + smp_wmb(); +} +EXPORT_SYMBOL(copy_user_highpage); + +void clear_user_highpage(struct page *page, unsigned long vaddr) +{ + void *kaddr = kmap_atomic(page, KM_USER0); + + clear_page(kaddr); + + if (pages_do_alias((unsigned long)kaddr, vaddr & PAGE_MASK)) + __flush_wback_region(kaddr, PAGE_SIZE); + + kunmap_atomic(kaddr, KM_USER0); +} +EXPORT_SYMBOL(clear_user_highpage); diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c deleted file mode 100644 index 4d93070b8220..000000000000 --- a/arch/sh/mm/pg-sh4.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * arch/sh/mm/pg-sh4.c - * - * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2002 - 2009 Paul Mundt - * - * Released under the terms of the GNU GPL v2.0. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#define kmap_get_fixmap_pte(vaddr) \ - pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) - -static pte_t *kmap_coherent_pte; - -void __init kmap_coherent_init(void) -{ - unsigned long vaddr; - - /* cache the first coherent kmap pte */ - vaddr = __fix_to_virt(FIX_CMAP_BEGIN); - kmap_coherent_pte = kmap_get_fixmap_pte(vaddr); -} - -static inline void *kmap_coherent(struct page *page, unsigned long addr) -{ - enum fixed_addresses idx; - unsigned long vaddr, flags; - pte_t pte; - - inc_preempt_count(); - - idx = (addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT; - vaddr = __fix_to_virt(FIX_CMAP_END - idx); - pte = mk_pte(page, PAGE_KERNEL); - - local_irq_save(flags); - flush_tlb_one(get_asid(), vaddr); - local_irq_restore(flags); - - update_mmu_cache(NULL, vaddr, pte); - - set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte); - - return (void *)vaddr; -} - -static inline void kunmap_coherent(struct page *page) -{ - dec_preempt_count(); - preempt_check_resched(); -} - -void copy_to_user_page(struct vm_area_struct *vma, struct page *page, - unsigned long vaddr, void *dst, const void *src, - unsigned long len) -{ - if (page_mapped(page) && !test_bit(PG_dcache_dirty, &page->flags)) { - void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); - memcpy(vto, src, len); - kunmap_coherent(vto); - } else { - memcpy(dst, src, len); - set_bit(PG_dcache_dirty, &page->flags); - } - - if (vma->vm_flags & VM_EXEC) - flush_cache_page(vma, vaddr, page_to_pfn(page)); -} - -void copy_from_user_page(struct vm_area_struct *vma, struct page *page, - unsigned long vaddr, void *dst, const void *src, - unsigned long len) -{ - if (page_mapped(page) && !test_bit(PG_dcache_dirty, &page->flags)) { - void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); - memcpy(dst, vfrom, len); - kunmap_coherent(vfrom); - } else { - memcpy(dst, src, len); - set_bit(PG_dcache_dirty, &page->flags); - } -} - -void copy_user_highpage(struct page *to, struct page *from, - unsigned long vaddr, struct vm_area_struct *vma) -{ - void *vfrom, *vto; - - vto = kmap_atomic(to, KM_USER1); - - if (page_mapped(from) && !test_bit(PG_dcache_dirty, &from->flags)) { - vfrom = kmap_coherent(from, vaddr); - copy_page(vto, vfrom); - kunmap_coherent(vfrom); - } else { - vfrom = kmap_atomic(from, KM_USER0); - copy_page(vto, vfrom); - kunmap_atomic(vfrom, KM_USER0); - } - - if (pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK)) - __flush_wback_region(vto, PAGE_SIZE); - - kunmap_atomic(vto, KM_USER1); - /* Make sure this page is cleared on other CPU's too before using it */ - smp_wmb(); -} -EXPORT_SYMBOL(copy_user_highpage); - -void clear_user_highpage(struct page *page, unsigned long vaddr) -{ - void *kaddr = kmap_atomic(page, KM_USER0); - - clear_page(kaddr); - - if (pages_do_alias((unsigned long)kaddr, vaddr & PAGE_MASK)) - __flush_wback_region(kaddr, PAGE_SIZE); - - kunmap_atomic(kaddr, KM_USER0); -} -EXPORT_SYMBOL(clear_user_highpage); -- cgit v1.2.3-59-g8ed1b From 9cef7492696a416663b4edb953a4eade8517ebeb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 29 Jul 2009 00:12:17 +0900 Subject: sh: update_mmu_cache() consolidation. This splits out a separate __update_cache()/__update_tlb() for update_mmu_cache() to wrap in to. This lets us share the common __update_cache() bits while keeping special __update_tlb() handling broken out. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgtable.h | 15 +++++++++++++-- arch/sh/mm/pg-mmu.c | 21 +++++++++++++++++++++ arch/sh/mm/tlb-nommu.c | 9 ++++++--- arch/sh/mm/tlb-pteaex.c | 13 ++++++------- arch/sh/mm/tlb-sh3.c | 29 ++++++----------------------- arch/sh/mm/tlb-sh4.c | 29 ++++++----------------------- arch/sh/mm/tlbflush_64.c | 25 +++++++++---------------- 7 files changed, 67 insertions(+), 74 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index ba2333216c5b..43ef3e99fdd1 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -134,8 +134,19 @@ typedef pte_t *pte_addr_t; #define pgtable_cache_init() do { } while (0) struct vm_area_struct; -extern void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte); + +extern void __update_cache(struct vm_area_struct *vma, + unsigned long address, pte_t pte); +extern void __update_tlb(struct vm_area_struct *vma, + unsigned long address, pte_t pte); + +static inline void +update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) +{ + __update_cache(vma, address, pte); + __update_tlb(vma, address, pte); +} + extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern void paging_init(void); extern void page_table_range_init(unsigned long start, unsigned long end, diff --git a/arch/sh/mm/pg-mmu.c b/arch/sh/mm/pg-mmu.c index 356d2cdcb209..8602f68af4c8 100644 --- a/arch/sh/mm/pg-mmu.c +++ b/arch/sh/mm/pg-mmu.c @@ -134,3 +134,24 @@ void clear_user_highpage(struct page *page, unsigned long vaddr) kunmap_atomic(kaddr, KM_USER0); } EXPORT_SYMBOL(clear_user_highpage); + +void __update_cache(struct vm_area_struct *vma, + unsigned long address, pte_t pte) +{ + struct page *page; + unsigned long pfn = pte_pfn(pte); + + if (!boot_cpu_data.dcache.n_aliases) + return; + + page = pfn_to_page(pfn); + if (pfn_valid(pfn) && page_mapping(page)) { + int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); + if (dirty) { + unsigned long addr = (unsigned long)page_address(page); + + if (pages_do_alias(addr, address & PAGE_MASK)) + __flush_wback_region((void *)addr, PAGE_SIZE); + } + } +} diff --git a/arch/sh/mm/tlb-nommu.c b/arch/sh/mm/tlb-nommu.c index 71c742b5aee3..0ef5429943df 100644 --- a/arch/sh/mm/tlb-nommu.c +++ b/arch/sh/mm/tlb-nommu.c @@ -46,10 +46,13 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) BUG(); } -void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) +{ +} + +void __update_cache(struct vm_area_struct *vma, + unsigned long address, pte_t pte) { - BUG(); } void __init page_table_range_init(unsigned long start, unsigned long end, diff --git a/arch/sh/mm/tlb-pteaex.c b/arch/sh/mm/tlb-pteaex.c index c39b77363352..9aabd313cede 100644 --- a/arch/sh/mm/tlb-pteaex.c +++ b/arch/sh/mm/tlb-pteaex.c @@ -16,15 +16,14 @@ #include #include -void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) { - unsigned long flags; - unsigned long pteval; - unsigned long vpn; + unsigned long flags, pteval, vpn; - /* Ptrace may call this routine. */ - if (vma && current->active_mm != vma->vm_mm) + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) return; local_irq_save(flags); diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c index 9b8459c74abd..425f1f23cf93 100644 --- a/arch/sh/mm/tlb-sh3.c +++ b/arch/sh/mm/tlb-sh3.c @@ -27,32 +27,16 @@ #include #include -void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) { - unsigned long flags; - unsigned long pteval; - unsigned long vpn; - unsigned long pfn = pte_pfn(pte); - struct page *page; + unsigned long flags, pteval, vpn; - /* Ptrace may call this routine. */ - if (vma && current->active_mm != vma->vm_mm) + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) return; - page = pfn_to_page(pfn); - if (pfn_valid(pfn) && page_mapping(page)) { -#if defined(CONFIG_SH7705_CACHE_32KB) - int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); - if (dirty) { - unsigned long addr = (unsigned long)page_address(page); - - if (pages_do_alias(addr, address & PAGE_MASK)) - __flush_wback_region((void *)addr, PAGE_SIZE); - } -#endif - } - local_irq_save(flags); /* Set PTEH register */ @@ -93,4 +77,3 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page) for (i = 0; i < ways; i++) ctrl_outl(data, addr + (i << 8)); } - diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c index cf50082d2435..81199f1e5945 100644 --- a/arch/sh/mm/tlb-sh4.c +++ b/arch/sh/mm/tlb-sh4.c @@ -15,33 +15,16 @@ #include #include -void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) { - unsigned long flags; - unsigned long pteval; - unsigned long vpn; - unsigned long pfn = pte_pfn(pte); - struct page *page; + unsigned long flags, pteval, vpn; - /* Ptrace may call this routine. */ - if (vma && current->active_mm != vma->vm_mm) + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) return; - page = pfn_to_page(pfn); - if (pfn_valid(pfn) && page_mapping(page)) { -#ifndef CONFIG_SMP - int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); - if (dirty) { - - unsigned long addr = (unsigned long)page_address(page); - - if (pages_do_alias(addr, address & PAGE_MASK)) - __flush_wback_region((void *)addr, PAGE_SIZE); - } -#endif - } - local_irq_save(flags); /* Set PTEH register */ diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c index 3ce40ea34824..f2e44e9ffb75 100644 --- a/arch/sh/mm/tlbflush_64.c +++ b/arch/sh/mm/tlbflush_64.c @@ -329,22 +329,6 @@ do_sigbus: goto no_context; } -void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - /* - * This appears to get called once for every pte entry that gets - * established => I don't think it's efficient to try refilling the - * TLBs with the pages - some may not get accessed even. Also, for - * executable pages, it is impossible to determine reliably here which - * TLB they should be mapped into (or both even). - * - * So, just do nothing here and handle faults on demand. In the - * TLBMISS handling case, the refill is now done anyway after the pte - * has been fixed up, so that deals with most useful cases. - */ -} - void local_flush_tlb_one(unsigned long asid, unsigned long page) { unsigned long long match, pteh=0, lpage; @@ -482,3 +466,12 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) /* FIXME: Optimize this later.. */ flush_tlb_all(); } + +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) +{ +} + +void __update_cache(struct vm_area_struct *vma, + unsigned long address, pte_t pte) +{ +} -- cgit v1.2.3-59-g8ed1b From 3ed6e129390fb872c3b7e05a232e5d380fbdfb48 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 29 Jul 2009 22:06:58 +0900 Subject: sh: Handle a NULL vma in __update_tlb() for the fast-path. The TLB miss fast-path presently calls in to update_mmu_cache() to set up the entry, and does so with a NULL vma. Check for vma validity in the __update_tlb() ptrace checks. Signed-off-by: Paul Mundt --- arch/sh/mm/tlb-pteaex.c | 2 +- arch/sh/mm/tlb-sh3.c | 2 +- arch/sh/mm/tlb-sh4.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/tlb-pteaex.c b/arch/sh/mm/tlb-pteaex.c index 9aabd313cede..409b7c2b4b9d 100644 --- a/arch/sh/mm/tlb-pteaex.c +++ b/arch/sh/mm/tlb-pteaex.c @@ -23,7 +23,7 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) /* * Handle debugger faulting in for debugee. */ - if (current->active_mm != vma->vm_mm) + if (vma && current->active_mm != vma->vm_mm) return; local_irq_save(flags); diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c index 425f1f23cf93..ace8e6d2f59d 100644 --- a/arch/sh/mm/tlb-sh3.c +++ b/arch/sh/mm/tlb-sh3.c @@ -34,7 +34,7 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) /* * Handle debugger faulting in for debugee. */ - if (current->active_mm != vma->vm_mm) + if (vma && current->active_mm != vma->vm_mm) return; local_irq_save(flags); diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c index 81199f1e5945..7d3c63e707a5 100644 --- a/arch/sh/mm/tlb-sh4.c +++ b/arch/sh/mm/tlb-sh4.c @@ -22,7 +22,7 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) /* * Handle debugger faulting in for debugee. */ - if (current->active_mm != vma->vm_mm) + if (vma && current->active_mm != vma->vm_mm) return; local_irq_save(flags); -- cgit v1.2.3-59-g8ed1b From 82b242214b6f5b96eb9b76452ac6e2b67dd81abd Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 29 Jul 2009 22:43:58 +0900 Subject: Revert "sh: Bump the earlytimer bits back to time_init()." This reverts commit 1d29ebebcb951ab6b04d22807cafb24b893310a2. Bumping up the earlytimer initialization causes IRQs to be enabled too early, which blows up lockdep: ... NR_IRQS:256 nr_irqs:256 ------------[ cut here ]------------ Badness at kernel/lockdep.c:2128 Pid : 0, Comm: swapper CPU : 0 Not tainted (2.6.31-rc3-00205-g3ed6e12-dirty #2443) PC is at trace_hardirqs_on_caller+0x48/0x10c PR is at trace_hardirqs_on_caller+0x3c/0x10c ... Revert it back to late_time_init time, which fixes up lockdep. Signed-off-by: Paul Mundt --- arch/sh/kernel/time.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index d2424b068b7b..7f95f479060f 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -92,6 +92,21 @@ module_init(rtc_generic_init); void (*board_time_init)(void); +static void __init sh_late_time_init(void) +{ + /* + * Make sure all compiled-in early timers register themselves. + * + * Run probe() for two "earlytimer" devices, these will be the + * clockevents and clocksource devices respectively. In the event + * that only a clockevents device is available, we -ENODEV on the + * clocksource and the jiffies clocksource is used transparently + * instead. No error handling is necessary here. + */ + early_platform_driver_register_all("earlytimer"); + early_platform_driver_probe("earlytimer", 2, 0); +} + void __init time_init(void) { if (board_time_init) @@ -108,15 +123,5 @@ void __init time_init(void) local_timer_setup(smp_processor_id()); #endif - /* - * Make sure all compiled-in early timers register themselves. - * - * Run probe() for two "earlytimer" devices, these will be the - * clockevents and clocksource devices respectively. In the event - * that only a clockevents device is available, we -ENODEV on the - * clocksource and the jiffies clocksource is used transparently - * instead. No error handling is necessary here. - */ - early_platform_driver_register_all("earlytimer"); - early_platform_driver_probe("earlytimer", 2, 0); + late_time_init = sh_late_time_init; } -- cgit v1.2.3-59-g8ed1b From fd78a76aefb5bf28a11d6960d29e03a11db62320 Mon Sep 17 00:00:00 2001 From: Stuart Menefy Date: Wed, 29 Jul 2009 23:01:24 +0900 Subject: sh: Rework irqflags tracing to fix up CONFIG_PROVE_LOCKING. This cleans up the irqflags tracing code quite a bit and ties it in to various missing callsites that caused an imbalance when CONFIG_PROVE_LOCKING was enabled. Previously this was catching on: 987 #ifdef CONFIG_PROVE_LOCKING 988 DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled); 989 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); 990 #endif 991 retval = -EAGAIN; with hardirqs being doubly enabled, and subsequently bailing out with the following call trace: Call trace: [<88035224>] __lock_acquire+0x616/0x6a6 [<88015a8c>] do_fork+0xf8/0x2b0 [<880331ec>] trace_hardirqs_on_caller+0xd4/0x114 [<88241074>] _spin_unlock_irq+0x20/0x64 [<88035224>] __lock_acquire+0x616/0x6a6 [<8800386c>] kernel_thread+0x48/0x70 [<88024ecc>] ____call_usermodehelper+0x0/0x110 [<88024ecc>] ____call_usermodehelper+0x0/0x110 [<88003894>] kernel_thread_helper+0x0/0x14 [<88024bac>] __call_usermodehelper+0x38/0x70 [<88025dc0>] worker_thread+0x150/0x274 [<88035b9c>] lock_release+0x0/0x198 [<88024b74>] __call_usermodehelper+0x0/0x70 [<88028cf0>] autoremove_wake_function+0x0/0x30 [<88028bf2>] kthread+0x3e/0x70 [<88025c70>] worker_thread+0x0/0x274 [<8800389c>] kernel_thread_helper+0x8/0x14 [<88028bb4>] kthread+0x0/0x70 [<88003894>] kernel_thread_helper+0x0/0x14 Reported-by: Nobuhiro Iwamatsu Signed-off-by: Stuart Menefy Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/Kconfig.debug | 2 +- arch/sh/include/asm/entry-macros.S | 72 ++++++++++++++++++++++++++++++++++++++ arch/sh/kernel/entry-common.S | 63 +++++++++------------------------ arch/sh/kernel/io_trapped.c | 7 ++-- drivers/serial/sh-sci.c | 5 +-- 5 files changed, 96 insertions(+), 53 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index b440fd936714..a6dce41296e7 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -38,7 +38,7 @@ 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 diff --git a/arch/sh/include/asm/entry-macros.S b/arch/sh/include/asm/entry-macros.S index 3a4752a65722..1bdd93891cd7 100644 --- a/arch/sh/include/asm/entry-macros.S +++ b/arch/sh/include/asm/entry-macros.S @@ -31,6 +31,78 @@ #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 diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index d62175650c54..fc26ccd82789 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -45,7 +45,7 @@ */ #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 +55,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 +63,23 @@ 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: 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,11 +122,7 @@ 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 & 0xff), r0 bt/s __restore_all @@ -156,11 +149,7 @@ 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 & 0xff), r0 @@ -172,10 +161,6 @@ 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: @@ -184,11 +169,7 @@ syscall_exit_work: 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 @@ -321,11 +302,7 @@ 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 ! @@ -355,11 +332,7 @@ 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 @@ -377,9 +350,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 diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c index 77dfecb64373..e27a19e1f46e 100644 --- a/arch/sh/kernel/io_trapped.c +++ b/arch/sh/kernel/io_trapped.c @@ -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); diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 8e2feb563347..4cbb87ad070a 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -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; } -- cgit v1.2.3-59-g8ed1b From 3c928320b2254cb6c8d8a7919a1fcf94ca7cae66 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 29 Jul 2009 15:04:05 +0000 Subject: sh: romImage support V2 This patch contains support for the romImage build target V2. The resulting romImage file should be burned to rom or flash and could be used as small boot loader. Board code should keep their setup code in the file romimage.h located in their mach include directory. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/Makefile | 2 +- arch/sh/boot/Makefile | 11 +++++++++-- arch/sh/boot/romimage/Makefile | 19 +++++++++++++++++++ arch/sh/boot/romimage/head.S | 10 ++++++++++ arch/sh/boot/romimage/vmlinux.scr | 6 ++++++ arch/sh/include/mach-common/romimage.h | 1 + 6 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 arch/sh/boot/romimage/Makefile create mode 100644 arch/sh/boot/romimage/head.S create mode 100644 arch/sh/boot/romimage/vmlinux.scr create mode 100644 arch/sh/include/mach-common/romimage.h (limited to 'arch/sh') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index c46b3d508f22..2a7e73faee89 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -195,7 +195,7 @@ libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec \ - zImage vmlinux.srec + zImage vmlinux.srec romImage PHONY += maketools $(BOOT_TARGETS) FORCE maketools: include/linux/version.h FORCE diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile index dd2a852041e9..a1316872be6f 100644 --- a/arch/sh/boot/Makefile +++ b/arch/sh/boot/Makefile @@ -24,9 +24,9 @@ suffix-$(CONFIG_KERNEL_GZIP) := gz suffix-$(CONFIG_KERNEL_BZIP2) := bz2 suffix-$(CONFIG_KERNEL_LZMA) := lzma -targets := zImage vmlinux.srec uImage uImage.srec uImage.gz uImage.bz2 uImage.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 +subdir- := compressed romimage $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) @@ -35,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" \ diff --git a/arch/sh/boot/romimage/Makefile b/arch/sh/boot/romimage/Makefile new file mode 100644 index 000000000000..5806eee84f6f --- /dev/null +++ b/arch/sh/boot/romimage/Makefile @@ -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) diff --git a/arch/sh/boot/romimage/head.S b/arch/sh/boot/romimage/head.S new file mode 100644 index 000000000000..97a087bc9c4a --- /dev/null +++ b/arch/sh/boot/romimage/head.S @@ -0,0 +1,10 @@ +/* + * linux/arch/sh/boot/romimage/head.S + * + * Board specific setup code, executed before zImage loader + */ + +.text + .global romstart +romstart: +#include diff --git a/arch/sh/boot/romimage/vmlinux.scr b/arch/sh/boot/romimage/vmlinux.scr new file mode 100644 index 000000000000..287c08f8b4bb --- /dev/null +++ b/arch/sh/boot/romimage/vmlinux.scr @@ -0,0 +1,6 @@ +SECTIONS +{ + .text : { + *(.data) + } +} diff --git a/arch/sh/include/mach-common/romimage.h b/arch/sh/include/mach-common/romimage.h new file mode 100644 index 000000000000..267e24112d82 --- /dev/null +++ b/arch/sh/include/mach-common/romimage.h @@ -0,0 +1 @@ +/* do nothing here by default */ -- cgit v1.2.3-59-g8ed1b From d162300e6c963fe255ea7f73b956a7716e24205d Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 29 Jul 2009 15:06:15 +0000 Subject: sh: kfr2r09 romImage support V2 This patch is romImage support for the kfr2r09 board V2. The partner-jet-setup.txt file is converted into assembly code which becomes the first code to execute from the reset vector. The file partner-jet-setup.txt can also be used to setup the hardware using a JTAG debugger so booting from RAM can be done without burning the code to flash. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/mach-kfr2r09/partner-jet-setup.txt | 134 +++++++++++++++++++++ arch/sh/include/mach-kfr2r09/romimage.h | 75 ++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 arch/sh/include/mach-kfr2r09/partner-jet-setup.txt create mode 100644 arch/sh/include/mach-kfr2r09/romimage.h (limited to 'arch/sh') diff --git a/arch/sh/include/mach-kfr2r09/partner-jet-setup.txt b/arch/sh/include/mach-kfr2r09/partner-jet-setup.txt new file mode 100644 index 000000000000..9c85088728a7 --- /dev/null +++ b/arch/sh/include/mach-kfr2r09/partner-jet-setup.txt @@ -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 diff --git a/arch/sh/include/mach-kfr2r09/romimage.h b/arch/sh/include/mach-kfr2r09/romimage.h new file mode 100644 index 000000000000..f5aa8e16770c --- /dev/null +++ b/arch/sh/include/mach-kfr2r09/romimage.h @@ -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" -- cgit v1.2.3-59-g8ed1b From fdeb076f20df14b1c7f2817362172548d146b121 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 30 Jul 2009 00:27:35 +0900 Subject: sh: Add romImage target to archhelp. Adds an archhelp blurb for the romImage target so it is reflected in 'make help'. Signed-off-by: Paul Mundt --- arch/sh/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/sh') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 2a7e73faee89..b6ff337fd856 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -216,6 +216,7 @@ archclean: define archhelp @echo ' zImage - Compressed kernel image' + @echo ' romImage - Compressed ROM image, if supported' @echo ' vmlinux.srec - Create an ELF S-record' @echo '* uImage - Alias to bootable U-Boot image' @echo ' uImage.srec - Create an S-record for U-Boot' -- cgit v1.2.3-59-g8ed1b From 05aa7882757f68af799140142ec44f83b2df4298 Mon Sep 17 00:00:00 2001 From: Rafael Ignacio Zurita Date: Tue, 4 Aug 2009 14:38:08 +0900 Subject: sh: Add early printk support for SH770x CPUs. This adds early printk support for SH770x (tested on SH7709 based hp6xx). Signed-off-by: Rafael Ignacio Zurita Signed-off-by: Paul Mundt --- arch/sh/Kconfig.debug | 1 + arch/sh/kernel/early_printk.c | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index a6dce41296e7..763b792b1611 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -43,6 +43,7 @@ config EARLY_SCIF_CONSOLE_PORT 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 diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index a952dcf9999d..64f2746baf91 100644 --- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -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,10 +220,8 @@ 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 } #endif -- cgit v1.2.3-59-g8ed1b From 6ba4a8f0f542e791e4158c91a844234b142578dc Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 06:57:36 +0000 Subject: sh: hwblk support for sh7724 This patch adds hwblk support for the sh7724 processor. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/cpu-sh4/cpu/sh7724.h | 17 +++++ arch/sh/kernel/cpu/sh4a/Makefile | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 119 ++++++++++++++++---------------- arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c | 121 +++++++++++++++++++++++++++++++++ 4 files changed, 201 insertions(+), 58 deletions(-) create mode 100644 arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c (limited to 'arch/sh') diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h index 66fd1184359e..0cd1f71a1116 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7724.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h @@ -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__ */ diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index 1d7ae38bc611..12cddf4c721d 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -27,7 +27,7 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7786) := clock-sh7786.o clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.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 +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 diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 5d5c9b952883..ba24e38c9fc7 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include /* SH7724 registers */ #define FRQCRA 0xa4150000 @@ -156,64 +158,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), - - 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), - - 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("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), + + 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), + + 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 +241,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; } diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c new file mode 100644 index 000000000000..1613ad6013c3 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c @@ -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 +#include +#include +#include +#include +#include + +/* 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); +} -- cgit v1.2.3-59-g8ed1b From 133b170f08d6c20578f25b1ae71f80a5e638ccb6 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:01:36 +0000 Subject: sh: clean up MSTPCRn register definitions This patch removes the unused MSTPCRn register definitions from the SuperH Mobile code for sh7722, sh7723 and sh7724. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 3 --- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 3 --- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 3 --- 3 files changed, 9 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 1fa9e1dd1cc8..5b1bbbe63b1b 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -32,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 */ diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index bf64c78eee34..e5c63911403c 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -32,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 */ diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index ba24e38c9fc7..34611d97378e 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -33,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 -- cgit v1.2.3-59-g8ed1b From 4f3243117ad42b4d1faeecd452f7b24306fcfc4a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 3 Aug 2009 04:52:03 +0000 Subject: sh: ms7724se: add 1280x720 lcdc output support There was no big meaning in the support of SVGA, but 720p support is necessary for ms7724se board. So, this patch support 720p instead of SVGA. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7724/setup.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 4fb7e48e2843..957ed176ea2c 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -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 */ @@ -546,15 +554,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; -- cgit v1.2.3-59-g8ed1b From edc67b29425b12312356fe9a92352ce6b7307c68 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 3 Aug 2009 04:52:24 +0000 Subject: sh: Add SH7724 DMAC support. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/include/asm/dma-sh.h | 1 + arch/sh/include/cpu-sh4/cpu/dma-sh4a.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h index 0c8f8e14622a..68a5f4cb0343 100644 --- a/arch/sh/include/asm/dma-sh.h +++ b/arch/sh/include/asm/dma-sh.h @@ -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) \ diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h index 0ed5178fed69..f0886bc880e0 100644 --- a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h +++ b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h @@ -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 -- cgit v1.2.3-59-g8ed1b From 9aaa74908b2117bcd560ab3ea8a9d6a491a77c28 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:47:17 +0000 Subject: sh: Runtime PM pdev hwblk These patches extend struct platform device data for a bunch of SuperH Mobile processors and embedded boards. The patches simply add hardware block ids to on-chip platform devices. Platform devices off chip (such as external ethernet controllers or flash chips) are left out which gives them a special case hardware block id of zero. Upcoming Runtime PM code will make use of the hardware block id to group devices together. The hardware block id can also be used to extend the SuperH Mobile clock framework implementation. This series of patches depend on the following: "Driver Core: Add platform device arch data V3". This patch adds a hwblk_id member to struct pdev_archdata. This member should be used to point out on-chip hardware block id. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/device.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/device.h b/arch/sh/include/asm/device.h index 8688a88303ee..783ecdc64e25 100644 --- a/arch/sh/include/asm/device.h +++ b/arch/sh/include/asm/device.h @@ -3,7 +3,9 @@ * * This file is released under the GPLv2 */ -#include + +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; +}; -- cgit v1.2.3-59-g8ed1b From f69d5782742e57d5f047ed13440bcf1b320cb074 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:47:27 +0000 Subject: sh: Runtime PM pdev hwblk - sh7722 Add hwblk_id to on-chip sh7722 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 67b0d87fcb27..35097753456c 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -17,6 +17,7 @@ #include #include #include +#include static struct resource rtc_resources[] = { [0] = { @@ -46,6 +47,9 @@ 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 = { @@ -76,6 +80,9 @@ static struct platform_device usbf_device = { }, .num_resources = ARRAY_SIZE(usbf_resources), .resource = usbf_resources, + .archdata = { + .hwblk_id = HWBLK_USBF, + }, }; static struct resource iic_resources[] = { @@ -97,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 = { @@ -125,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 = { @@ -153,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 = { @@ -181,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 = { @@ -213,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 = { @@ -244,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 = { @@ -275,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 = { @@ -305,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[] = { -- cgit v1.2.3-59-g8ed1b From 2de63cf376585508f6942aaa7337848f8c4cdd7d Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:47:35 +0000 Subject: sh: Runtime PM pdev hwblk - Migo-R Add hwblk_id to Migo-R board specific on-chip sh7722 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-migor/setup.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index f70f4644deb4..a508a0fa7315 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -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 = { -- cgit v1.2.3-59-g8ed1b From 66d9c51ac434615b0f0e864c0c9a81d7264ca3ef Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:47:44 +0000 Subject: sh: Runtime PM pdev hwblk - Solution Engine 7722 Add hwblk_id to Solution Engine 7722 board specific on-chip sh7722 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7722/setup.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c index af84904ed86f..36374078e521 100644 --- a/arch/sh/boards/mach-se/7722/setup.c +++ b/arch/sh/boards/mach-se/7722/setup.c @@ -22,6 +22,7 @@ #include #include #include +#include /* 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 = { -- cgit v1.2.3-59-g8ed1b From 09d21f9c83c49afd04850b8701772c09954054e0 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:47:53 +0000 Subject: sh: Runtime PM pdev hwblk - sh7723 Add hwblk_id to on-chip sh7723 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 26dc4d323252..4caa5a7ca86e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -18,6 +18,7 @@ #include #include #include +#include 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,6 +426,9 @@ 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 = { @@ -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 = { -- cgit v1.2.3-59-g8ed1b From d3a6f6260a3fecd9a8e301fcf37d87ee70edca12 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:48:02 +0000 Subject: sh: Runtime PM pdev hwblk - AP325RXA Add hwblk_id to AP325RXA board specific on-chip sh7723 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/board-ap325rxa.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c index 7ffd1b4315bd..07a54740d43e 100644 --- a/arch/sh/boards/board-ap325rxa.c +++ b/arch/sh/boards/board-ap325rxa.c @@ -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 = { -- cgit v1.2.3-59-g8ed1b From 593a0c898ac2f09f001d536f699966ec4bc1d25f Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:48:11 +0000 Subject: sh: Runtime PM pdev hwblk - sh7724 Add hwblk_id to on-chip sh7724 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index a04edaab9a29..f3851fd757ec 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -22,6 +22,7 @@ #include #include #include +#include /* 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 = { -- cgit v1.2.3-59-g8ed1b From 442c37534c6a46d8ed27144fb09818833edbd049 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:48:21 +0000 Subject: sh: Runtime PM pdev hwblk - kfr2r09 Add hwblk_id to kfr2r09 board specific on-chip sh7724 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-kfr2r09/setup.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index bf5f8f8d3b5f..0e9b39034df3 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -95,6 +95,9 @@ static struct platform_device kfr2r09_sh_keysc_device = { .dev = { .platform_data = &kfr2r09_sh_keysc_info, }, + .archdata = { + .hwblk_id = HWBLK_KEYSC, + }, }; static struct platform_device *kfr2r09_devices[] __initdata = { -- cgit v1.2.3-59-g8ed1b From df47cd096c8f54a5242e3a2ffb4525c804567eda Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:48:29 +0000 Subject: sh: Runtime PM pdev hwblk - Solution Engine 7724 Add hwblk_id to Solution Engine 7724 board specific on-chip sh7724 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7724/setup.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 4fb7e48e2843..8de5ebc36b67 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -174,6 +174,9 @@ static struct platform_device lcdc_device = { .dev = { .platform_data = &lcdc_info, }, + .archdata = { + .hwblk_id = HWBLK_LCDC, + }, }; /* CEU0 */ @@ -205,6 +208,9 @@ static struct platform_device ceu0_device = { .dev = { .platform_data = &sh_mobile_ceu0_info, }, + .archdata = { + .hwblk_id = HWBLK_CEU0, + }, }; /* CEU1 */ @@ -236,6 +242,9 @@ static struct platform_device ceu1_device = { .dev = { .platform_data = &sh_mobile_ceu1_info, }, + .archdata = { + .hwblk_id = HWBLK_CEU1, + }, }; /* KEYSC */ @@ -273,6 +282,9 @@ static struct platform_device keysc_device = { .dev = { .platform_data = &keysc_info, }, + .archdata = { + .hwblk_id = HWBLK_KEYSC, + }, }; /* SH Eth */ @@ -301,6 +313,9 @@ 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 = { @@ -330,6 +345,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 = { -- cgit v1.2.3-59-g8ed1b From 11d82905e0159c07fe2d1bfe5e7d80e4cea333ce Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 4 Aug 2009 15:54:33 +0900 Subject: sh: Fix up early printk build error. Missing endif in the early printk case, fix it up.. Signed-off-by: Paul Mundt --- arch/sh/kernel/early_printk.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/sh') diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index 64f2746baf91..81a46145ffa5 100644 --- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -222,6 +222,7 @@ static int __init setup_early_printk(char *buf) #if !defined(CONFIG_SH_STANDARD_BIOS) #if defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3) scif_sercon_init(buf + 6); +#endif #endif } #endif -- cgit v1.2.3-59-g8ed1b From 700487c158163f14e6ff10de770b565c1c993c69 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 4 Aug 2009 15:57:44 +0900 Subject: sh: Add a PG_dcache_dirty sanity check in kmap_coherent(). This plugs in a BUG_ON() in kmap_coherent() for PG_dcache_dirty pages to catch when things go horribly wrong. Copied from the MIPS implementation. Signed-off-by: Paul Mundt --- arch/sh/mm/pg-mmu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/mm/pg-mmu.c b/arch/sh/mm/pg-mmu.c index 8602f68af4c8..32351206edd3 100644 --- a/arch/sh/mm/pg-mmu.c +++ b/arch/sh/mm/pg-mmu.c @@ -37,6 +37,8 @@ static inline void *kmap_coherent(struct page *page, unsigned long addr) unsigned long vaddr, flags; pte_t pte; + BUG_ON(test_bit(PG_dcache_dirty, &page->flags)); + inc_preempt_count(); idx = (addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT; -- cgit v1.2.3-59-g8ed1b From 222db3e5f21fca563f5f692e000afcc01cb4395c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 4 Aug 2009 15:59:15 +0900 Subject: sh: Bring kmap_coherent() out-of-line. kmap_coherent() has gotten too big to leave as an inline, so we bring it out-of-line. Signed-off-by: Paul Mundt --- arch/sh/mm/pg-mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/pg-mmu.c b/arch/sh/mm/pg-mmu.c index 32351206edd3..e5c5122f4d62 100644 --- a/arch/sh/mm/pg-mmu.c +++ b/arch/sh/mm/pg-mmu.c @@ -31,7 +31,7 @@ void __init kmap_coherent_init(void) #endif } -static inline void *kmap_coherent(struct page *page, unsigned long addr) +static void *kmap_coherent(struct page *page, unsigned long addr) { enum fixed_addresses idx; unsigned long vaddr, flags; -- cgit v1.2.3-59-g8ed1b From b5eb10ae901fa797c19accb684825f0e36ecbe0f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 4 Aug 2009 16:00:36 +0900 Subject: sh: Drop unused arguments for kunmap_coherent(). kunmap_coherent() doesn't do anything with its arguments, so just kill them off. Signed-off-by: Paul Mundt --- arch/sh/mm/pg-mmu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/pg-mmu.c b/arch/sh/mm/pg-mmu.c index e5c5122f4d62..a9ede7bae520 100644 --- a/arch/sh/mm/pg-mmu.c +++ b/arch/sh/mm/pg-mmu.c @@ -56,7 +56,7 @@ static void *kmap_coherent(struct page *page, unsigned long addr) return (void *)vaddr; } -static inline void kunmap_coherent(struct page *page) +static inline void kunmap_coherent(void) { dec_preempt_count(); preempt_check_resched(); @@ -70,7 +70,7 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, !test_bit(PG_dcache_dirty, &page->flags)) { void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); memcpy(vto, src, len); - kunmap_coherent(vto); + kunmap_coherent(); } else { memcpy(dst, src, len); if (boot_cpu_data.dcache.n_aliases) @@ -89,7 +89,7 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page, !test_bit(PG_dcache_dirty, &page->flags)) { void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); memcpy(dst, vfrom, len); - kunmap_coherent(vfrom); + kunmap_coherent(); } else { memcpy(dst, src, len); if (boot_cpu_data.dcache.n_aliases) @@ -108,7 +108,7 @@ void copy_user_highpage(struct page *to, struct page *from, !test_bit(PG_dcache_dirty, &from->flags)) { vfrom = kmap_coherent(from, vaddr); copy_page(vto, vfrom); - kunmap_coherent(vfrom); + kunmap_coherent(); } else { vfrom = kmap_atomic(from, KM_USER0); copy_page(vto, vfrom); -- cgit v1.2.3-59-g8ed1b From c0fe478dbb14fd32e71d1383dbe302b54ce94134 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 4 Aug 2009 16:02:43 +0900 Subject: sh: Provide __flush_anon_page(). This provides a __flush_anon_page() that handles both the aliasing and non-aliasing cases. This fixes up some crashes with heavy get_user_pages() users. Signed-off-by: Paul Mundt --- arch/sh/include/asm/cacheflush.h | 14 ++++++++++++++ arch/sh/mm/pg-mmu.c | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h index 4c85d55847cc..5dffbd126e46 100644 --- a/arch/sh/include/asm/cacheflush.h +++ b/arch/sh/include/asm/cacheflush.h @@ -1,6 +1,8 @@ #ifndef __ASM_SH_CACHEFLUSH_H #define __ASM_SH_CACHEFLUSH_H +#include + #ifdef __KERNEL__ #ifdef CONFIG_CACHE_OFF @@ -43,6 +45,18 @@ extern void __flush_purge_region(void *start, int size); extern void __flush_invalidate_region(void *start, int size); #endif +#ifdef CONFIG_MMU +#define ARCH_HAS_FLUSH_ANON_PAGE +extern void __flush_anon_page(struct page *page, unsigned long); + +static inline void flush_anon_page(struct vm_area_struct *vma, + struct page *page, unsigned long vmaddr) +{ + if (boot_cpu_data.dcache.n_aliases && PageAnon(page)) + __flush_anon_page(page, vmaddr); +} +#endif + #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE static inline void flush_kernel_dcache_page(struct page *page) { diff --git a/arch/sh/mm/pg-mmu.c b/arch/sh/mm/pg-mmu.c index a9ede7bae520..027c4d83fb8e 100644 --- a/arch/sh/mm/pg-mmu.c +++ b/arch/sh/mm/pg-mmu.c @@ -157,3 +157,20 @@ void __update_cache(struct vm_area_struct *vma, } } } + +void __flush_anon_page(struct page *page, unsigned long vmaddr) +{ + unsigned long addr = (unsigned long) page_address(page); + + if (pages_do_alias(addr, vmaddr)) { + if (boot_cpu_data.dcache.n_aliases && page_mapped(page) && + !test_bit(PG_dcache_dirty, &page->flags)) { + void *kaddr; + + kaddr = kmap_coherent(page, vmaddr); + __flush_wback_region((void *)kaddr, PAGE_SIZE); + kunmap_coherent(); + } else + __flush_wback_region((void *)addr, PAGE_SIZE); + } +} -- cgit v1.2.3-59-g8ed1b From c7914834ef3b8a396b7e82ea34ac07cdcfe6f868 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 4 Aug 2009 17:14:39 +0900 Subject: sh: Tidy up NEFF-based sign extension for SH-5. This consolidates all of the NEFF-based sign extension for SH-5. In the future the other SH code will need to make use of this as well, so make it generic in preparation for more 32/64 consolidation. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgtable.h | 6 ++++++ arch/sh/kernel/process_64.c | 24 ++++++++++-------------- arch/sh/kernel/signal_64.c | 38 +++++++++++++------------------------- arch/sh/mm/fault_64.c | 11 +---------- arch/sh/mm/tlb-sh5.c | 21 +++++---------------- arch/sh/mm/tlbflush_64.c | 2 +- 6 files changed, 36 insertions(+), 66 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index 43ef3e99fdd1..3cd7127af957 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -36,6 +36,12 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #define NEFF_SIGN (1LL << (NEFF - 1)) #define NEFF_MASK (-1LL << NEFF) +static inline unsigned long long neff_sign_extend(unsigned long val) +{ + unsigned long long extended = val; + return (extended & NEFF_SIGN) ? (extended | NEFF_MASK) : extended; +} + #ifdef CONFIG_29BIT #define NPHYS 29 #else diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index 24de74214940..1192398ef582 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c @@ -425,7 +425,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, struct task_struct *p, struct pt_regs *regs) { struct pt_regs *childregs; - unsigned long long se; /* Sign extension */ #ifdef CONFIG_SH_FPU if(last_task_used_math == current) { @@ -441,11 +440,19 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, *childregs = *regs; + /* + * Sign extend the edited stack. + * Note that thread.pc and thread.pc will stay + * 32-bit wide and context switch must take care + * of NEFF sign extension. + */ if (user_mode(regs)) { - childregs->regs[15] = usp; + childregs->regs[15] = neff_sign_extend(usp); p->thread.uregs = childregs; } else { - childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE; + childregs->regs[15] = + neff_sign_extend((unsigned long)task_stack_page(p) + + THREAD_SIZE); } childregs->regs[9] = 0; /* Set return value for child */ @@ -454,17 +461,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, p->thread.sp = (unsigned long) childregs; p->thread.pc = (unsigned long) ret_from_fork; - /* - * Sign extend the edited stack. - * Note that thread.pc and thread.pc will stay - * 32-bit wide and context switch must take care - * of NEFF sign extension. - */ - - se = childregs->regs[15]; - se = (se & NEFF_SIGN) ? (se | NEFF_MASK) : se; - childregs->regs[15] = se; - return 0; } diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index 0663a0ee6021..026fd1cfe17d 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c @@ -561,13 +561,11 @@ static int setup_frame(int sig, struct k_sigaction *ka, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { - DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1; - /* * On SH5 all edited pointers are subject to NEFF */ - DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? - (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; + DEREF_REG_PR = neff_sign_extend((unsigned long) + ka->sa.sa_restorer | 0x1); } else { /* * Different approach on SH5. @@ -580,9 +578,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, * . being code, linker turns ShMedia bit on, always * dereference index -1. */ - DEREF_REG_PR = (unsigned long) frame->retcode | 0x01; - DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? - (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; + DEREF_REG_PR = neff_sign_extend((unsigned long) + frame->retcode | 0x01); if (__copy_to_user(frame->retcode, (void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0) @@ -596,9 +593,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, * Set up registers for signal handler. * All edited pointers are subject to NEFF. */ - regs->regs[REG_SP] = (unsigned long) frame; - regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ? - (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP]; + regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame); regs->regs[REG_ARG1] = signal; /* Arg for signal handler */ /* FIXME: @@ -613,8 +608,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc; regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc; - regs->pc = (unsigned long) ka->sa.sa_handler; - regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc; + regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler); set_fs(USER_DS); @@ -676,13 +670,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { - DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1; - /* * On SH5 all edited pointers are subject to NEFF */ - DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? - (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; + DEREF_REG_PR = neff_sign_extend((unsigned long) + ka->sa.sa_restorer | 0x1); } else { /* * Different approach on SH5. @@ -695,15 +687,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, * . being code, linker turns ShMedia bit on, always * dereference index -1. */ - - DEREF_REG_PR = (unsigned long) frame->retcode | 0x01; - DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? - (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; + DEREF_REG_PR = neff_sign_extend((unsigned long) + frame->retcode | 0x01); if (__copy_to_user(frame->retcode, (void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0) goto give_sigsegv; + /* Cohere the trampoline with the I-cache. */ flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15); } @@ -711,14 +702,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, * Set up registers for signal handler. * All edited pointers are subject to NEFF. */ - regs->regs[REG_SP] = (unsigned long) frame; - regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ? - (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP]; + regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame); regs->regs[REG_ARG1] = signal; /* Arg for signal handler */ regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info; regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext; - regs->pc = (unsigned long) ka->sa.sa_handler; - regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc; + regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler); set_fs(USER_DS); diff --git a/arch/sh/mm/fault_64.c b/arch/sh/mm/fault_64.c index bd63b961b2a9..2b356cec2489 100644 --- a/arch/sh/mm/fault_64.c +++ b/arch/sh/mm/fault_64.c @@ -56,16 +56,7 @@ inline void __do_tlb_refill(unsigned long address, /* * Set PTEH register */ - pteh = address & MMU_VPN_MASK; - - /* Sign extend based on neff. */ -#if (NEFF == 32) - /* Faster sign extension */ - pteh = (unsigned long long)(signed long long)(signed long)pteh; -#else - /* General case */ - pteh = (pteh & NEFF_SIGN) ? (pteh | NEFF_MASK) : pteh; -#endif + pteh = neff_sign_extend(address & MMU_VPN_MASK); /* Set the ASID. */ pteh |= get_asid() << PTEH_ASID_SHIFT; diff --git a/arch/sh/mm/tlb-sh5.c b/arch/sh/mm/tlb-sh5.c index dae131243bcc..fdb64e41ec50 100644 --- a/arch/sh/mm/tlb-sh5.c +++ b/arch/sh/mm/tlb-sh5.c @@ -117,26 +117,15 @@ int sh64_put_wired_dtlb_entry(unsigned long long entry) * Load up a virtual<->physical translation for @eaddr<->@paddr in the * pre-allocated TLB slot @config_addr (see sh64_get_wired_dtlb_entry). */ -inline void sh64_setup_tlb_slot(unsigned long long config_addr, - unsigned long eaddr, - unsigned long asid, - unsigned long paddr) +void sh64_setup_tlb_slot(unsigned long long config_addr, unsigned long eaddr, + unsigned long asid, unsigned long paddr) { unsigned long long pteh, ptel; - /* Sign extension */ -#if (NEFF == 32) - pteh = (unsigned long long)(signed long long)(signed long) eaddr; -#else -#error "Can't sign extend more than 32 bits yet" -#endif + pteh = neff_sign_extend(eaddr); pteh &= PAGE_MASK; pteh |= (asid << PTEH_ASID_SHIFT) | PTEH_VALID; -#if (NEFF == 32) - ptel = (unsigned long long)(signed long long)(signed long) paddr; -#else -#error "Can't sign extend more than 32 bits yet" -#endif + ptel = neff_sign_extend(paddr); ptel &= PAGE_MASK; ptel |= (_PAGE_CACHABLE | _PAGE_READ | _PAGE_WRITE); @@ -152,5 +141,5 @@ inline void sh64_setup_tlb_slot(unsigned long long config_addr, * * Teardown any existing mapping in the TLB slot @config_addr. */ -inline void sh64_teardown_tlb_slot(unsigned long long config_addr) +void sh64_teardown_tlb_slot(unsigned long long config_addr) __attribute__ ((alias("__flush_tlb_slot"))); diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c index f2e44e9ffb75..fa5a95a062d0 100644 --- a/arch/sh/mm/tlbflush_64.c +++ b/arch/sh/mm/tlbflush_64.c @@ -337,7 +337,7 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page) /* * Sign-extend based on neff. */ - lpage = (page & NEFF_SIGN) ? (page | NEFF_MASK) : page; + lpage = neff_sign_extend(page); match = (asid << PTEH_ASID_SHIFT) | PTEH_VALID; match |= lpage; -- cgit v1.2.3-59-g8ed1b From d14d751ff9234595639a16e53b3cf0c575946bde Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 4 Aug 2009 17:17:00 +0900 Subject: sh64: Kill off special clear_page() implementation. This can use the now generic clear_page() implementation, which is backed by the sh64 optimized memset routine. This also fixes up the case where PAGE_SIZE != 4kB. Signed-off-by: Paul Mundt --- arch/sh/kernel/sh_ksyms_64.c | 1 - arch/sh/lib64/Makefile | 2 +- arch/sh/lib64/clear_page.S | 54 -------------------------------------------- 3 files changed, 1 insertion(+), 56 deletions(-) delete mode 100644 arch/sh/lib64/clear_page.S (limited to 'arch/sh') diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c index f5bd156ea504..f96c95c07c4b 100644 --- a/arch/sh/kernel/sh_ksyms_64.c +++ b/arch/sh/kernel/sh_ksyms_64.c @@ -52,7 +52,6 @@ EXPORT_SYMBOL(__get_user_asm_l); EXPORT_SYMBOL(__get_user_asm_q); EXPORT_SYMBOL(__strnlen_user); EXPORT_SYMBOL(__strncpy_from_user); -EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(__copy_user); diff --git a/arch/sh/lib64/Makefile b/arch/sh/lib64/Makefile index 334bb2da36ea..1fee75aa1f98 100644 --- a/arch/sh/lib64/Makefile +++ b/arch/sh/lib64/Makefile @@ -11,7 +11,7 @@ # Panic should really be compiled as PIC lib-y := udelay.o dbg.o panic.o memcpy.o memset.o \ - copy_user_memcpy.o copy_page.o clear_page.o strcpy.o strlen.o + copy_user_memcpy.o copy_page.o strcpy.o strlen.o # Extracted from libgcc lib-y += udivsi3.o udivdi3.o sdivsi3.o diff --git a/arch/sh/lib64/clear_page.S b/arch/sh/lib64/clear_page.S deleted file mode 100644 index 007ab48ecc1c..000000000000 --- a/arch/sh/lib64/clear_page.S +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright 2003 Richard Curnow, SuperH (UK) Ltd. - - 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. - - Tight version of memset for the case of just clearing a page. It turns out - that having the alloco's spaced out slightly due to the increment/branch - pair causes them to contend less for access to the cache. Similarly, - keeping the stores apart from the allocos causes less contention. => Do two - separate loops. Do multiple stores per loop to amortise the - increment/branch cost a little. - - Parameters: - r2 : source effective address (start of page) - - Always clears 4096 bytes. - - Note : alloco guarded by synco to avoid TAKum03020 erratum - -*/ - - .section .text..SHmedia32,"ax" - .little - - .balign 8 - .global clear_page -clear_page: - pta/l 1f, tr1 - pta/l 2f, tr2 - ptabs/l r18, tr0 - - movi 4096, r7 - add r2, r7, r7 - add r2, r63, r6 -1: - alloco r6, 0 - synco ! TAKum03020 - addi r6, 32, r6 - bgt/l r7, r6, tr1 - - add r2, r63, r6 -2: - st.q r6, 0, r63 - st.q r6, 8, r63 - st.q r6, 16, r63 - st.q r6, 24, r63 - addi r6, 32, r6 - bgt/l r7, r6, tr2 - - blink tr0, r63 - - -- cgit v1.2.3-59-g8ed1b From 817425275271f2514f0dc6952182aa057ce80973 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 4 Aug 2009 18:06:01 +0900 Subject: sh: Split out SH-4 __flush_xxx_region() ops. This splits out the SH-4 __flush_xxx_region() functions and defines them as weak symbols. This allows us to provide optimized versions without having to ifdef cache-sh4.c to death. Signed-off-by: Paul Mundt --- arch/sh/mm/Makefile_32 | 2 +- arch/sh/mm/cache-sh4.c | 60 ----------------------------------------------- arch/sh/mm/flush-sh4.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 61 deletions(-) create mode 100644 arch/sh/mm/flush-sh4.c (limited to 'arch/sh') diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32 index 62e280734dcb..17b02522214f 100644 --- a/arch/sh/mm/Makefile_32 +++ b/arch/sh/mm/Makefile_32 @@ -8,7 +8,7 @@ ifndef CONFIG_CACHE_OFF cache-$(CONFIG_CPU_SH2) := cache-sh2.o cache-$(CONFIG_CPU_SH2A) := cache-sh2a.o cache-$(CONFIG_CPU_SH3) := cache-sh3.o -cache-$(CONFIG_CPU_SH4) := cache-sh4.o +cache-$(CONFIG_CPU_SH4) := cache-sh4.o flush-sh4.o cache-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o endif diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index c3a09b27f8d5..dfc1d0379479 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -118,66 +118,6 @@ void __init p3_cache_init(void) emit_cache_params(); } -/* - * Write back the dirty D-caches, but not invalidate them. - * - * START: Virtual Address (U0, P1, or P3) - * SIZE: Size of the region. - */ -void __flush_wback_region(void *start, int size) -{ - unsigned long v; - unsigned long begin, end; - - begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); - end = ((unsigned long)start + size + L1_CACHE_BYTES-1) - & ~(L1_CACHE_BYTES-1); - for (v = begin; v < end; v+=L1_CACHE_BYTES) { - asm volatile("ocbwb %0" - : /* no output */ - : "m" (__m(v))); - } -} - -/* - * Write back the dirty D-caches and invalidate them. - * - * START: Virtual Address (U0, P1, or P3) - * SIZE: Size of the region. - */ -void __flush_purge_region(void *start, int size) -{ - unsigned long v; - unsigned long begin, end; - - begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); - end = ((unsigned long)start + size + L1_CACHE_BYTES-1) - & ~(L1_CACHE_BYTES-1); - for (v = begin; v < end; v+=L1_CACHE_BYTES) { - asm volatile("ocbp %0" - : /* no output */ - : "m" (__m(v))); - } -} - -/* - * No write back please - */ -void __flush_invalidate_region(void *start, int size) -{ - unsigned long v; - unsigned long begin, end; - - begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); - end = ((unsigned long)start + size + L1_CACHE_BYTES-1) - & ~(L1_CACHE_BYTES-1); - for (v = begin; v < end; v+=L1_CACHE_BYTES) { - asm volatile("ocbi %0" - : /* no output */ - : "m" (__m(v))); - } -} - /* * Write back the range of D-cache, and purge the I-cache. * diff --git a/arch/sh/mm/flush-sh4.c b/arch/sh/mm/flush-sh4.c new file mode 100644 index 000000000000..e6d918f6ec0b --- /dev/null +++ b/arch/sh/mm/flush-sh4.c @@ -0,0 +1,63 @@ +#include +#include +#include + +/* + * Write back the dirty D-caches, but not invalidate them. + * + * START: Virtual Address (U0, P1, or P3) + * SIZE: Size of the region. + */ +void __weak __flush_wback_region(void *start, int size) +{ + unsigned long v; + unsigned long begin, end; + + begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + & ~(L1_CACHE_BYTES-1); + for (v = begin; v < end; v+=L1_CACHE_BYTES) { + asm volatile("ocbwb %0" + : /* no output */ + : "m" (__m(v))); + } +} + +/* + * Write back the dirty D-caches and invalidate them. + * + * START: Virtual Address (U0, P1, or P3) + * SIZE: Size of the region. + */ +void __weak __flush_purge_region(void *start, int size) +{ + unsigned long v; + unsigned long begin, end; + + begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + & ~(L1_CACHE_BYTES-1); + for (v = begin; v < end; v+=L1_CACHE_BYTES) { + asm volatile("ocbp %0" + : /* no output */ + : "m" (__m(v))); + } +} + +/* + * No write back please + */ +void __weak __flush_invalidate_region(void *start, int size) +{ + unsigned long v; + unsigned long begin, end; + + begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + & ~(L1_CACHE_BYTES-1); + for (v = begin; v < end; v+=L1_CACHE_BYTES) { + asm volatile("ocbi %0" + : /* no output */ + : "m" (__m(v))); + } +} -- cgit v1.2.3-59-g8ed1b From 0837f52463583f76670ab2350e0f1541cb0351f5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 4 Aug 2009 18:09:54 +0900 Subject: sh: Partially unroll the SH-4 __flush_xxx_region() flushers. This does a bit of unrolling for the SH-4 region flushers. Based on an earlier patch by SUGIOKA Toshinobu. Signed-off-by: Paul Mundt --- arch/sh/mm/flush-sh4.c | 104 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 21 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/flush-sh4.c b/arch/sh/mm/flush-sh4.c index e6d918f6ec0b..edefc53891a8 100644 --- a/arch/sh/mm/flush-sh4.c +++ b/arch/sh/mm/flush-sh4.c @@ -10,16 +10,37 @@ */ void __weak __flush_wback_region(void *start, int size) { - unsigned long v; - unsigned long begin, end; + unsigned long v, cnt, end; - begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + v = (unsigned long)start & ~(L1_CACHE_BYTES-1); end = ((unsigned long)start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); - for (v = begin; v < end; v+=L1_CACHE_BYTES) { - asm volatile("ocbwb %0" - : /* no output */ - : "m" (__m(v))); + cnt = (end - v) / L1_CACHE_BYTES; + + while (cnt >= 8) { + asm volatile("ocbwb @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbwb @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbwb @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbwb @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbwb @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbwb @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbwb @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbwb @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + cnt -= 8; + } + + while (cnt) { + asm volatile("ocbwb @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + cnt--; } } @@ -31,16 +52,36 @@ void __weak __flush_wback_region(void *start, int size) */ void __weak __flush_purge_region(void *start, int size) { - unsigned long v; - unsigned long begin, end; + unsigned long v, cnt, end; - begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + v = (unsigned long)start & ~(L1_CACHE_BYTES-1); end = ((unsigned long)start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); - for (v = begin; v < end; v+=L1_CACHE_BYTES) { - asm volatile("ocbp %0" - : /* no output */ - : "m" (__m(v))); + cnt = (end - v) / L1_CACHE_BYTES; + + while (cnt >= 8) { + asm volatile("ocbp @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbp @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbp @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbp @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbp @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbp @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbp @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbp @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + cnt -= 8; + } + while (cnt) { + asm volatile("ocbp @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + cnt--; } } @@ -49,15 +90,36 @@ void __weak __flush_purge_region(void *start, int size) */ void __weak __flush_invalidate_region(void *start, int size) { - unsigned long v; - unsigned long begin, end; + unsigned long v, cnt, end; - begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + v = (unsigned long)start & ~(L1_CACHE_BYTES-1); end = ((unsigned long)start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); - for (v = begin; v < end; v+=L1_CACHE_BYTES) { - asm volatile("ocbi %0" - : /* no output */ - : "m" (__m(v))); + cnt = (end - v) / L1_CACHE_BYTES; + + while (cnt >= 8) { + asm volatile("ocbi @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbi @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbi @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbi @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbi @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbi @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbi @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + asm volatile("ocbi @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + cnt -= 8; + } + + while (cnt) { + asm volatile("ocbi @%0" : : "r" (v)); + v += L1_CACHE_BYTES; + cnt--; } } -- cgit v1.2.3-59-g8ed1b From c1155e34998bc07937cdf0c9db16b6902633a255 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 4 Aug 2009 16:55:29 +0200 Subject: sh: convert to asm-generic/hardirq.h Signed-off-by: Christoph Hellwig Signed-off-by: Paul Mundt --- arch/sh/include/asm/hardirq.h | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/hardirq.h b/arch/sh/include/asm/hardirq.h index 715ee237fc77..a5be4afa790b 100644 --- a/arch/sh/include/asm/hardirq.h +++ b/arch/sh/include/asm/hardirq.h @@ -1,16 +1,9 @@ #ifndef __ASM_SH_HARDIRQ_H #define __ASM_SH_HARDIRQ_H -#include -#include - -/* entry.S is sensitive to the offsets of these fields */ -typedef struct { - unsigned int __softirq_pending; -} ____cacheline_aligned irq_cpustat_t; - -#include /* Standard mappings for irq_cpustat_t above */ - extern void ack_bad_irq(unsigned int irq); +#define ack_bad_irq ack_bad_irq + +#include #endif /* __ASM_SH_HARDIRQ_H */ -- cgit v1.2.3-59-g8ed1b From 9f26e659d8caf5820c51b9c695f0a313e636b99c Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 6 Aug 2009 14:51:30 +0000 Subject: sh: kfr2r09 board support - LCDC panel This patch adds support for the WQVGA LCD display used by the KFR2R09 board. The LCD module is a TX07D34VM0AAA made by Hitachi, and this module is made up by a R61517 chip together with a 240x400 pixel display. The screen is attached to the SuperH Mobile LCDC using a 18-bit SYS bus. The register settings used by the SYS panel setup code are based on an out-of-tree driver which apart from duplicating all LCDC driver code and writing to non-existing hardware registers also never was posted for upstream merge. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-kfr2r09/Makefile | 1 + arch/sh/boards/mach-kfr2r09/lcd_wqvga.c | 332 ++++++++++++++++++++++++++++ arch/sh/boards/mach-kfr2r09/setup.c | 94 ++++++++ arch/sh/include/mach-kfr2r09/mach/kfr2r09.h | 21 ++ 4 files changed, 448 insertions(+) create mode 100644 arch/sh/boards/mach-kfr2r09/lcd_wqvga.c create mode 100644 arch/sh/include/mach-kfr2r09/mach/kfr2r09.h (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-kfr2r09/Makefile b/arch/sh/boards/mach-kfr2r09/Makefile index 77037567633b..5d5867826e3b 100644 --- a/arch/sh/boards/mach-kfr2r09/Makefile +++ b/arch/sh/boards/mach-kfr2r09/Makefile @@ -1 +1,2 @@ obj-y := setup.o +obj-$(CONFIG_FB_SH_MOBILE_LCDC) += lcd_wqvga.o diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c new file mode 100644 index 000000000000..8ccb1cc8b589 --- /dev/null +++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c @@ -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 +#include +#include +#include +#include +#include +#include +#include