From e08f457c7c0cc7720f28349f8780ea752c063441 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 14 May 2007 12:52:56 +0900 Subject: sh: __user annotations for __get/__put_user(). This adds in some more __user annotations. These weren't being handled properly in some of the __get_user and __put_user paths, so tidy those up. Signed-off-by: Paul Mundt --- include/asm-sh/page.h | 1 + include/asm-sh/sections.h | 2 -- include/asm-sh/system.h | 14 ++++++++++++++ include/asm-sh/uaccess.h | 40 ++++++++++++++++++++++------------------ 4 files changed, 37 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h index 7464de4ba07d..011dfbe14a6b 100644 --- a/include/asm-sh/page.h +++ b/include/asm-sh/page.h @@ -60,6 +60,7 @@ extern void (*copy_page)(void *to, void *from); extern unsigned long shm_align_mask; extern unsigned long max_low_pfn, min_low_pfn; +extern unsigned long memory_start, memory_end; #ifdef CONFIG_MMU extern void clear_page_slow(void *to); diff --git a/include/asm-sh/sections.h b/include/asm-sh/sections.h index 57abd708b236..44c06c09e208 100644 --- a/include/asm-sh/sections.h +++ b/include/asm-sh/sections.h @@ -3,7 +3,5 @@ #include -extern char _end[]; - #endif /* __ASM_SH_SECTIONS_H */ diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index 82f3e229e621..fb22fc3f87ad 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h @@ -8,9 +8,13 @@ #include #include +#include #include #include +struct task_struct *__switch_to(struct task_struct *prev, + struct task_struct *next); + /* * switch_to() should switch tasks to task nr n, first */ @@ -271,6 +275,16 @@ extern unsigned int instruction_size(unsigned int insn); void disable_hlt(void); void enable_hlt(void); +void default_idle(void); + +asmlinkage void break_point_trap(void); +asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs __regs); +asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs __regs); + #define arch_align_stack(x) (x) #endif diff --git a/include/asm-sh/uaccess.h b/include/asm-sh/uaccess.h index 5c49ed6715f2..f18a1a5c95c0 100644 --- a/include/asm-sh/uaccess.h +++ b/include/asm-sh/uaccess.h @@ -61,8 +61,6 @@ static inline void set_fs(mm_segment_t s) */ static inline int __access_ok(unsigned long addr, unsigned long size) { - extern unsigned long memory_start, memory_end; - return ((addr >= memory_start) && ((addr + size) < memory_end)); } #else /* CONFIG_MMU */ @@ -76,7 +74,7 @@ static inline int __access_ok(unsigned long addr, unsigned long size) * __access_ok: Check if address with size is OK or not. * * We do three checks: - * (1) is it user space? + * (1) is it user space? * (2) addr + size --> carry? * (3) addr + size >= 0x80000000 (PAGE_OFFSET) * @@ -142,11 +140,12 @@ static inline int access_ok(int type, const void __user *p, unsigned long size) __get_user_nocheck((x),(ptr),sizeof(*(ptr))) struct __large_struct { unsigned long buf[100]; }; -#define __m(x) (*(struct __large_struct *)(x)) +#define __m(x) (*(struct __large_struct __user *)(x)) #define __get_user_size(x,ptr,size,retval) \ do { \ retval = 0; \ + __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ __get_user_asm(x, ptr, retval, "b"); \ @@ -175,6 +174,7 @@ do { \ #define __get_user_check(x,ptr,size) \ ({ \ long __gu_err, __gu_val; \ + __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ __get_user_1(__gu_val, (ptr), __gu_err); \ @@ -300,6 +300,7 @@ extern void __get_user_unknown(void); #define __put_user_size(x,ptr,size,retval) \ do { \ retval = 0; \ + __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ __put_user_asm(x, ptr, retval, "b"); \ @@ -328,7 +329,7 @@ do { \ #define __put_user_check(x,ptr,size) \ ({ \ long __pu_err = -EFAULT; \ - __typeof__(*(ptr)) *__pu_addr = (ptr); \ + __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ \ if (__access_ok((unsigned long)__pu_addr,size)) \ __put_user_size((x),__pu_addr,(size),__pu_err); \ @@ -406,10 +407,10 @@ __asm__ __volatile__( \ #endif extern void __put_user_unknown(void); - + /* Generic arbitrary sized copy. */ /* Return the number of bytes NOT copied */ -extern __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); +__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); #define copy_to_user(to,from,n) ({ \ void *__copy_to = (void *) (to); \ @@ -420,14 +421,6 @@ __copy_res = __copy_user(__copy_to, (void *) (from), __copy_size); \ } else __copy_res = __copy_size; \ __copy_res; }) -#define __copy_to_user(to,from,n) \ - __copy_user((void *)(to), \ - (void *)(from), n) - -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - - #define copy_from_user(to,from,n) ({ \ void *__copy_to = (void *) (to); \ void *__copy_from = (void *) (from); \ @@ -438,9 +431,20 @@ __copy_res = __copy_user(__copy_to, __copy_from, __copy_size); \ } else __copy_res = __copy_size; \ __copy_res; }) -#define __copy_from_user(to,from,n) \ - __copy_user((void *)(to), \ - (void *)(from), n) +static __always_inline unsigned long +__copy_from_user(void *to, const void __user *from, unsigned long n) +{ + return __copy_user(to, (__force void *)from, n); +} + +static __always_inline unsigned long __must_check +__copy_to_user(void __user *to, const void *from, unsigned long n) +{ + return __copy_user((__force void *)to, from, n); +} + +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user /* * Clear the area and return remaining number of bytes -- cgit v1.2.3-59-g8ed1b From 9655ad03af2d232c3b26e7562ab4f8c29b107e49 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 14 May 2007 15:59:09 +0900 Subject: sh: Fixup machvec support. This fixes up much of the machvec handling, allowing for it to be overloaded on boot. Making practical use of this still requires some Kconfig munging, however. Signed-off-by: Paul Mundt --- arch/sh/kernel/Makefile | 2 +- arch/sh/kernel/machvec.c | 105 +++++++++++++++++++++++++++ arch/sh/kernel/setup.c | 162 ++++-------------------------------------- arch/sh/kernel/vmlinux.lds.S | 3 +- include/asm-sh/machvec_init.h | 34 --------- include/asm-sh/sections.h | 2 + include/asm-sh/setup.h | 1 + 7 files changed, 125 insertions(+), 184 deletions(-) create mode 100644 arch/sh/kernel/machvec.c (limited to 'include') diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index fb623e5d1857..1f141a8ba17c 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -4,7 +4,7 @@ extra-y := head.o init_task.o vmlinux.lds -obj-y := debugtraps.o io.o io_generic.o irq.o process.o ptrace.o \ +obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process.o ptrace.o \ semaphore.o setup.o signal.o sys_sh.o syscalls.o \ time.o topology.o traps.o diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c new file mode 100644 index 000000000000..1e78191154e3 --- /dev/null +++ b/arch/sh/kernel/machvec.c @@ -0,0 +1,105 @@ +/* + * arch/sh/kernel/machvec.c + * + * The SuperH machine vector setup handlers, yanked from setup.c + * + * Copyright (C) 1999 Niibe Yutaka + * Copyright (C) 2002 - 2007 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include + +#define MV_NAME_SIZE 32 + +#define for_each_mv(mv) \ + for ((mv) = (struct sh_machine_vector *)&__machvec_start; \ + (mv) && (unsigned long)(mv) < (unsigned long)&__machvec_end; \ + (mv)++) + +static struct sh_machine_vector * __init get_mv_byname(const char *name) +{ + struct sh_machine_vector *mv; + + for_each_mv(mv) + if (strcasecmp(name, get_system_type()) == 0) + return mv; + + return NULL; +} + +static int __init early_parse_mv(char *from) +{ + char mv_name[MV_NAME_SIZE] = ""; + char *mv_end; + char *mv_comma; + int mv_len; + struct sh_machine_vector *mvp; + + mv_end = strchr(from, ' '); + if (mv_end == NULL) + mv_end = from + strlen(from); + + mv_comma = strchr(from, ','); + mv_len = mv_end - from; + if (mv_len > (MV_NAME_SIZE-1)) + mv_len = MV_NAME_SIZE-1; + memcpy(mv_name, from, mv_len); + mv_name[mv_len] = '\0'; + from = mv_end; + + if (strcmp(sh_mv.mv_name, mv_name) != 0) { + mvp = get_mv_byname(mv_name); + if (unlikely(!mvp)) { + printk("Available vectors:\n\n\t"); + for_each_mv(mvp) + printk("'%s', ", mvp->mv_name); + printk("\n\n"); + panic("Failed to select machvec '%s' -- halting.\n", + mv_name); + } else + sh_mv = *mvp; + } + + printk(KERN_NOTICE "Booting machvec: %s\n", sh_mv.mv_name); + return 0; +} +early_param("sh_mv", early_parse_mv); + +void __init sh_mv_setup(void) +{ + /* + * Manually walk the vec, fill in anything that the board hasn't yet + * by hand, wrapping to the generic implementation. + */ +#define mv_set(elem) do { \ + if (!sh_mv.mv_##elem) \ + sh_mv.mv_##elem = generic_##elem; \ +} while (0) + + mv_set(inb); mv_set(inw); mv_set(inl); + mv_set(outb); mv_set(outw); mv_set(outl); + + mv_set(inb_p); mv_set(inw_p); mv_set(inl_p); + mv_set(outb_p); mv_set(outw_p); mv_set(outl_p); + + mv_set(insb); mv_set(insw); mv_set(insl); + mv_set(outsb); mv_set(outsw); mv_set(outsl); + + mv_set(readb); mv_set(readw); mv_set(readl); + mv_set(writeb); mv_set(writew); mv_set(writel); + + mv_set(ioport_map); + mv_set(ioport_unmap); + mv_set(irq_demux); + + if (!sh_mv.mv_nr_irqs) + sh_mv.mv_nr_irqs = NR_IRQS; +} diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 61152b438325..0ad715833990 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -46,16 +46,8 @@ struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, }; struct screen_info screen_info; #endif -#if defined(CONFIG_SH_UNKNOWN) -struct sh_machine_vector sh_mv; -#endif - extern int root_mountflags; -#define MV_NAME_SIZE 32 - -static struct sh_machine_vector* __init get_mv_byname(const char* name); - /* * This is set up by the setup-routine at boot-time */ @@ -81,131 +73,17 @@ static struct resource data_resource = { .name = "Kernel data", }; unsigned long memory_start, memory_end; -static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], - struct sh_machine_vector** mvp, - unsigned long *mv_io_base) +static int __init early_parse_mem(char *p) { - char c = ' ', *to = command_line, *from = COMMAND_LINE; - int len = 0; - - /* Save unparsed command line copy for /proc/cmdline */ - memcpy(boot_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); - boot_command_line[COMMAND_LINE_SIZE-1] = '\0'; + unsigned long size; memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START; - memory_end = memory_start + __MEMORY_SIZE; - - for (;;) { - /* - * "mem=XXX[kKmM]" defines a size of memory. - */ - if (c == ' ' && !memcmp(from, "mem=", 4)) { - if (to != command_line) - to--; - { - unsigned long mem_size; - - mem_size = memparse(from+4, &from); - memory_end = memory_start + mem_size; - } - } - - if (c == ' ' && !memcmp(from, "sh_mv=", 6)) { - char* mv_end; - char* mv_comma; - int mv_len; - if (to != command_line) - to--; - from += 6; - mv_end = strchr(from, ' '); - if (mv_end == NULL) - mv_end = from + strlen(from); - - mv_comma = strchr(from, ','); - if ((mv_comma != NULL) && (mv_comma < mv_end)) { - int ints[3]; - get_options(mv_comma+1, ARRAY_SIZE(ints), ints); - *mv_io_base = ints[1]; - mv_len = mv_comma - from; - } else { - mv_len = mv_end - from; - } - if (mv_len > (MV_NAME_SIZE-1)) - mv_len = MV_NAME_SIZE-1; - memcpy(mv_name, from, mv_len); - mv_name[mv_len] = '\0'; - from = mv_end; - - *mvp = get_mv_byname(mv_name); - } - - c = *(from++); - if (!c) - break; - if (COMMAND_LINE_SIZE <= ++len) - break; - *(to++) = c; - } - *to = '\0'; - *cmdline_p = command_line; -} - -static int __init sh_mv_setup(char **cmdline_p) -{ -#ifdef CONFIG_SH_UNKNOWN - extern struct sh_machine_vector mv_unknown; -#endif - struct sh_machine_vector *mv = NULL; - char mv_name[MV_NAME_SIZE] = ""; - unsigned long mv_io_base = 0; - - parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base); - -#ifdef CONFIG_SH_UNKNOWN - if (mv == NULL) { - mv = &mv_unknown; - if (*mv_name != '\0') { - printk("Warning: Unsupported machine %s, using unknown\n", - mv_name); - } - } - sh_mv = *mv; -#endif - - /* - * Manually walk the vec, fill in anything that the board hasn't yet - * by hand, wrapping to the generic implementation. - */ -#define mv_set(elem) do { \ - if (!sh_mv.mv_##elem) \ - sh_mv.mv_##elem = generic_##elem; \ -} while (0) - - mv_set(inb); mv_set(inw); mv_set(inl); - mv_set(outb); mv_set(outw); mv_set(outl); - - mv_set(inb_p); mv_set(inw_p); mv_set(inl_p); - mv_set(outb_p); mv_set(outw_p); mv_set(outl_p); - - mv_set(insb); mv_set(insw); mv_set(insl); - mv_set(outsb); mv_set(outsw); mv_set(outsl); - - mv_set(readb); mv_set(readw); mv_set(readl); - mv_set(writeb); mv_set(writew); mv_set(writel); - - mv_set(ioport_map); - mv_set(ioport_unmap); - mv_set(irq_demux); - -#ifdef CONFIG_SH_UNKNOWN - __set_io_port_base(mv_io_base); -#endif - - if (!sh_mv.mv_nr_irqs) - sh_mv.mv_nr_irqs = NR_IRQS; + size = memparse(p, &p); + memory_end = memory_start + size; return 0; } +early_param("mem", early_parse_mem); /* * Register fully available low RAM pages with the bootmem allocator. @@ -340,9 +218,17 @@ void __init setup_arch(char **cmdline_p) data_resource.start = virt_to_phys(_etext); data_resource.end = virt_to_phys(_edata)-1; + memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START; + memory_end = memory_start + __MEMORY_SIZE; + + /* Save unparsed command line copy for /proc/cmdline */ + strlcpy(boot_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); + + *cmdline_p = command_line; + parse_early_param(); - sh_mv_setup(cmdline_p); + sh_mv_setup(); /* * Find the highest page frame number we have available @@ -369,26 +255,6 @@ void __init setup_arch(char **cmdline_p) sh_mv.mv_setup(cmdline_p); } -struct sh_machine_vector* __init get_mv_byname(const char* name) -{ - extern long __machvec_start, __machvec_end; - struct sh_machine_vector *all_vecs = - (struct sh_machine_vector *)&__machvec_start; - - int i, n = ((unsigned long)&__machvec_end - - (unsigned long)&__machvec_start)/ - sizeof(struct sh_machine_vector); - - for (i = 0; i < n; ++i) { - struct sh_machine_vector *mv = &all_vecs[i]; - if (mv == NULL) - continue; - if (strcasecmp(name, get_system_type()) == 0) { - return mv; - } - } - return NULL; -} static const char *cpu_name[] = { [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619", diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 4c5b57e9c3c1..f437a4f06da4 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -98,8 +98,9 @@ SECTIONS #endif __machvec_start = .; - .init.machvec : { *(.init.machvec) } + .machvec.init : { *(.machvec.init) } __machvec_end = .; + . = ALIGN(PAGE_SIZE); __init_end = .; diff --git a/include/asm-sh/machvec_init.h b/include/asm-sh/machvec_init.h index e397798ebd94..88a973edcf15 100644 --- a/include/asm-sh/machvec_init.h +++ b/include/asm-sh/machvec_init.h @@ -12,42 +12,8 @@ #ifndef __SH_MACHVEC_INIT_H #define __SH_MACHVEC_INIT_H - -/* - * In a GENERIC kernel, we have lots of these vectors floating about, - * all but one of which we want to go away. In a non-GENERIC kernel, - * we want only one, ever. - * - * Accomplish this in the GENERIC kernel by puting all of the vectors - * in the .init.data section where they'll go away. We'll copy the - * one we want to the real alpha_mv vector in setup_arch. - * - * Accomplish this in a non-GENERIC kernel by ifdef'ing out all but - * one of the vectors, which will not reside in .init.data. We then - * alias this one vector to alpha_mv, so no copy is needed. - * - * Upshot: set __initdata to nothing for non-GENERIC kernels. - * - * Note we do the same thing for the UNKNOWN kernel, as we need to write - * to the machine vector while setting it up. - */ - -#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_UNKNOWN) #define __initmv __attribute__((unused,__section__ (".machvec.init"))) -#define ALIAS_MV(x) -#else -#define __initmv - -/* GCC actually has a syntax for defining aliases, but is under some - delusion that you shouldn't be able to declare it extern somewhere - else beforehand. Fine. We'll do it ourselves. */ -#if 0 -#define ALIAS_MV(system) \ - struct sh_machine_vector sh_mv __attribute__((alias("mv_"#system))); -#else #define ALIAS_MV(system) \ asm(".global sh_mv\nsh_mv = mv_"#system ); -#endif -#endif /* GENERIC */ #endif /* __SH_MACHVEC_INIT_H */ diff --git a/include/asm-sh/sections.h b/include/asm-sh/sections.h index 44c06c09e208..2a696b8ee4f5 100644 --- a/include/asm-sh/sections.h +++ b/include/asm-sh/sections.h @@ -3,5 +3,7 @@ #include +extern long __machvec_start, __machvec_end; + #endif /* __ASM_SH_SECTIONS_H */ diff --git a/include/asm-sh/setup.h b/include/asm-sh/setup.h index 1583c6b7bdaa..586a9711a75d 100644 --- a/include/asm-sh/setup.h +++ b/include/asm-sh/setup.h @@ -6,6 +6,7 @@ #ifdef __KERNEL__ int setup_early_printk(char *); +void sh_mv_setup(void); #endif /* __KERNEL__ */ -- cgit v1.2.3-59-g8ed1b From 25f8151bdcdd62c6b879e3669a562c0d329eee4a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 14 May 2007 19:12:37 +0900 Subject: sh: Get multiple boards in one image working again. This tidies up the build rules and permits multiple boards to be linked in to the same kernel. The earlier Kconfig work ensures that the CPU configuration is consistent across the boards, as this is the only thing that we can't do dynamically. Signed-off-by: Paul Mundt --- arch/sh/Makefile | 88 ++++++++++++++++++++++++------------------- include/asm-sh/machvec_init.h | 2 +- 2 files changed, 51 insertions(+), 39 deletions(-) (limited to 'include') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 883b03b040c4..c7323e7dce67 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -87,39 +87,39 @@ core-y += arch/sh/kernel/ arch/sh/mm/ core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/ # Boards -machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x -machdir-$(CONFIG_SH_7722_SOLUTION_ENGINE) := se/7722 -machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751 -machdir-$(CONFIG_SH_7780_SOLUTION_ENGINE) := se/7780 -machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300 -machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) := se/7343 -machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180 -machdir-$(CONFIG_SH_HP6XX) := hp6xx -machdir-$(CONFIG_SH_SATURN) := saturn -machdir-$(CONFIG_SH_DREAMCAST) := dreamcast -machdir-$(CONFIG_SH_MPC1211) := mpc1211 -machdir-$(CONFIG_SH_SH03) := sh03 -machdir-$(CONFIG_SH_SECUREEDGE5410) := snapgear -machdir-$(CONFIG_SH_HS7751RVOIP) := renesas/hs7751rvoip -machdir-$(CONFIG_SH_RTS7751R2D) := renesas/rts7751r2d -machdir-$(CONFIG_SH_7751_SYSTEMH) := renesas/systemh -machdir-$(CONFIG_SH_EDOSK7705) := renesas/edosk7705 -machdir-$(CONFIG_SH_HIGHLANDER) := renesas/r7780rp -machdir-$(CONFIG_SH_7710VOIPGW) := renesas/sh7710voipgw -machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev -machdir-$(CONFIG_SH_LANDISK) := landisk -machdir-$(CONFIG_SH_TITAN) := titan -machdir-$(CONFIG_SH_SHMIN) := shmin -machdir-$(CONFIG_SH_7206_SOLUTION_ENGINE) := se/7206 -machdir-$(CONFIG_SH_7619_SOLUTION_ENGINE) := se/7619 -machdir-$(CONFIG_SH_LBOX_RE2) := lboxre2 -machdir-$(CONFIG_SH_UNKNOWN) := unknown - -incdir-y := $(notdir $(machdir-y)) -incdir-$(CONFIG_SH_HP6XX) := hp6xx +machdir-$(CONFIG_SH_SOLUTION_ENGINE) += se/770x +machdir-$(CONFIG_SH_7722_SOLUTION_ENGINE) += se/7722 +machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) += se/7751 +machdir-$(CONFIG_SH_7780_SOLUTION_ENGINE) += se/7780 +machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) += se/7300 +machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) += se/7343 +machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) += se/73180 +machdir-$(CONFIG_SH_HP6XX) += hp6xx +machdir-$(CONFIG_SH_SATURN) += saturn +machdir-$(CONFIG_SH_DREAMCAST) += dreamcast +machdir-$(CONFIG_SH_MPC1211) += mpc1211 +machdir-$(CONFIG_SH_SH03) += sh03 +machdir-$(CONFIG_SH_SECUREEDGE5410) += snapgear +machdir-$(CONFIG_SH_HS7751RVOIP) += renesas/hs7751rvoip +machdir-$(CONFIG_SH_RTS7751R2D) += renesas/rts7751r2d +machdir-$(CONFIG_SH_7751_SYSTEMH) += renesas/systemh +machdir-$(CONFIG_SH_EDOSK7705) += renesas/edosk7705 +machdir-$(CONFIG_SH_HIGHLANDER) += renesas/r7780rp +machdir-$(CONFIG_SH_7710VOIPGW) += renesas/sh7710voipgw +machdir-$(CONFIG_SH_SH4202_MICRODEV) += superh/microdev +machdir-$(CONFIG_SH_LANDISK) += landisk +machdir-$(CONFIG_SH_TITAN) += titan +machdir-$(CONFIG_SH_SHMIN) += shmin +machdir-$(CONFIG_SH_7206_SOLUTION_ENGINE) += se/7206 +machdir-$(CONFIG_SH_7619_SOLUTION_ENGINE) += se/7619 +machdir-$(CONFIG_SH_LBOX_RE2) += lboxre2 +machdir-$(CONFIG_SH_UNKNOWN) += unknown + +incdir-y := $(notdir $(machdir-y)) ifneq ($(machdir-y),) -core-y += arch/sh/boards/$(machdir-y)/ +core-y += $(addprefix arch/sh/boards/, \ + $(filter-out ., $(patsubst %,%/,$(machdir-y)))) endif # Companion chips @@ -157,19 +157,31 @@ include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) \ # Most boards have their own mach directories. For the ones that # don't, just reference the parent directory so the semantics are # kept roughly the same. +# +# When multiple boards are compiled in at the same time, preference +# for the mach link is given to whichever has a directory for its +# headers. However, this is only a workaround until platforms that +# can live in the same kernel image back away from relying on the +# mach link. include/asm-sh/.mach: $(wildcard include/config/sh/*.h) \ include/config/auto.conf FORCE - @echo -n ' SYMLINK include/asm-sh/mach -> ' $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi - $(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \ - echo -e 'include/asm-sh/$(incdir-y)'; \ - ln -fsn $(incdir-prefix)$(incdir-y) \ + $(Q)rm -f include/asm-sh/mach + $(Q)for i in $(incdir-y); do \ + if [ -d $(incdir-prefix)$$i ]; then \ + echo -n ' SYMLINK include/asm-sh/mach -> '; \ + echo -e "include/asm-sh/$$i"; \ + ln -fsn $(incdir-prefix)$$i \ include/asm-sh/mach; \ else \ - echo -e 'include/asm-sh'; \ - ln -fsn $(incdir-prefix) include/asm-sh/mach; \ - fi + if [ ! -d include/asm-sh/mach ]; then \ + echo -n ' SYMLINK include/asm-sh/mach -> '; \ + echo -e 'include/asm-sh'; \ + ln -fsn $(incdir-prefix) include/asm-sh/mach; \ + fi; \ + fi; \ + done @touch $@ archprepare: include/asm-sh/.cpu include/asm-sh/.mach maketools diff --git a/include/asm-sh/machvec_init.h b/include/asm-sh/machvec_init.h index 88a973edcf15..cb015b8bb365 100644 --- a/include/asm-sh/machvec_init.h +++ b/include/asm-sh/machvec_init.h @@ -14,6 +14,6 @@ #define __initmv __attribute__((unused,__section__ (".machvec.init"))) #define ALIAS_MV(system) \ - asm(".global sh_mv\nsh_mv = mv_"#system ); + asm(".weak sh_mv\nsh_mv = mv_"#system ); #endif /* __SH_MACHVEC_INIT_H */ -- cgit v1.2.3-59-g8ed1b From 82f81f4784479df17a80caff4a7156da0a2f7dea Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 15 May 2007 15:19:34 +0900 Subject: sh: Kill off machvec aliases. We now throw all of the machvecs in to .machvec.init and either select one on the command line, or copy out the first (and usually only) one to sh_mv. The rest are freed as usual. This gets rid of all of the silly sh_mv aliasing and makes the selection explicit rather than link-order dependent. Signed-off-by: Paul Mundt --- arch/sh/boards/dreamcast/setup.c | 3 +- arch/sh/boards/hp6xx/mach.c | 4 +-- arch/sh/boards/hp6xx/setup.c | 3 +- arch/sh/boards/landisk/setup.c | 3 +- arch/sh/boards/lboxre2/setup.c | 3 +- arch/sh/boards/mpc1211/setup.c | 3 +- arch/sh/boards/renesas/edosk7705/setup.c | 3 +- arch/sh/boards/renesas/hs7751rvoip/setup.c | 3 +- arch/sh/boards/renesas/r7780rp/setup.c | 3 +- arch/sh/boards/renesas/rts7751r2d/setup.c | 3 +- arch/sh/boards/renesas/sh7710voipgw/setup.c | 3 +- arch/sh/boards/renesas/systemh/setup.c | 3 +- arch/sh/boards/saturn/setup.c | 3 +- arch/sh/boards/se/7206/setup.c | 3 +- arch/sh/boards/se/7300/setup.c | 3 +- arch/sh/boards/se/73180/setup.c | 3 +- arch/sh/boards/se/7343/setup.c | 3 +- arch/sh/boards/se/7619/setup.c | 3 +- arch/sh/boards/se/770x/setup.c | 3 +- arch/sh/boards/se/7722/setup.c | 3 +- arch/sh/boards/se/7751/setup.c | 3 +- arch/sh/boards/se/7780/setup.c | 3 +- arch/sh/boards/sh03/setup.c | 3 +- arch/sh/boards/shmin/setup.c | 3 +- arch/sh/boards/snapgear/setup.c | 3 +- arch/sh/boards/superh/microdev/setup.c | 3 +- arch/sh/boards/titan/setup.c | 3 +- arch/sh/boards/unknown/setup.c | 3 +- arch/sh/kernel/machvec.c | 45 ++++++++++++++++++++--------- arch/sh/kernel/setup.c | 7 +++++ include/asm-sh/machvec.h | 4 ++- include/asm-sh/machvec_init.h | 19 ------------ 32 files changed, 69 insertions(+), 91 deletions(-) delete mode 100644 include/asm-sh/machvec_init.h (limited to 'include') diff --git a/arch/sh/boards/dreamcast/setup.c b/arch/sh/boards/dreamcast/setup.c index f13017eeeb27..8799df6e866a 100644 --- a/arch/sh/boards/dreamcast/setup.c +++ b/arch/sh/boards/dreamcast/setup.c @@ -60,7 +60,7 @@ static void __init dreamcast_setup(char **cmdline_p) #endif } -struct sh_machine_vector mv_dreamcast __initmv = { +static struct sh_machine_vector mv_dreamcast __initmv = { .mv_name = "Sega Dreamcast", .mv_setup = dreamcast_setup, .mv_irq_demux = systemasic_irq_demux, @@ -70,4 +70,3 @@ struct sh_machine_vector mv_dreamcast __initmv = { .mv_consistent_free = dreamcast_consistent_free, #endif }; -ALIAS_MV(dreamcast) diff --git a/arch/sh/boards/hp6xx/mach.c b/arch/sh/boards/hp6xx/mach.c index 08dbba910f74..35b895960474 100644 --- a/arch/sh/boards/hp6xx/mach.c +++ b/arch/sh/boards/hp6xx/mach.c @@ -13,7 +13,7 @@ #include #include -struct sh_machine_vector mv_hp6xx __initmv = { +static struct sh_machine_vector mv_hp6xx __initmv = { .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM, .mv_inb = hd64461_inb, @@ -42,5 +42,3 @@ struct sh_machine_vector mv_hp6xx __initmv = { .mv_irq_demux = hd64461_irq_demux, }; - -ALIAS_MV(hp6xx) diff --git a/arch/sh/boards/hp6xx/setup.c b/arch/sh/boards/hp6xx/setup.c index 6aeee85c9785..7ae708930bac 100644 --- a/arch/sh/boards/hp6xx/setup.c +++ b/arch/sh/boards/hp6xx/setup.c @@ -98,10 +98,9 @@ static void __init hp6xx_setup(char **cmdline_p) } device_initcall(hp6xx_devices_setup); -struct sh_machine_vector mv_hp6xx __initmv = { +static struct sh_machine_vector mv_hp6xx __initmv = { .mv_name = "hp6xx", .mv_setup = hp6xx_setup, .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM, .mv_irq_demux = hd64461_irq_demux, }; -ALIAS_MV(hp6xx) diff --git a/arch/sh/boards/landisk/setup.c b/arch/sh/boards/landisk/setup.c index f953c7427769..eda71763ecc5 100644 --- a/arch/sh/boards/landisk/setup.c +++ b/arch/sh/boards/landisk/setup.c @@ -97,10 +97,9 @@ static void __init landisk_setup(char **cmdline_p) /* * The Machine Vector */ -struct sh_machine_vector mv_landisk __initmv = { +static struct sh_machine_vector mv_landisk __initmv = { .mv_name = "LANDISK", .mv_nr_irqs = 72, .mv_setup = landisk_setup, .mv_init_irq = init_landisk_IRQ, }; -ALIAS_MV(landisk) diff --git a/arch/sh/boards/lboxre2/setup.c b/arch/sh/boards/lboxre2/setup.c index 4e20f7c63bf3..9c830fdc411b 100644 --- a/arch/sh/boards/lboxre2/setup.c +++ b/arch/sh/boards/lboxre2/setup.c @@ -77,9 +77,8 @@ device_initcall(lboxre2_devices_setup); /* * The Machine Vector */ -struct sh_machine_vector mv_lboxre2 __initmv = { +static struct sh_machine_vector mv_lboxre2 __initmv = { .mv_name = "L-BOX RE2", .mv_nr_irqs = 72, .mv_init_irq = init_lboxre2_IRQ, }; -ALIAS_MV(lboxre2) diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c index 1a0604b23ce0..8ce03e00b0ae 100644 --- a/arch/sh/boards/mpc1211/setup.c +++ b/arch/sh/boards/mpc1211/setup.c @@ -338,11 +338,10 @@ static void __init mpc1211_setup(char **cmdline_p) /* * The Machine Vector */ -struct sh_machine_vector mv_mpc1211 __initmv = { +static struct sh_machine_vector mv_mpc1211 __initmv = { .mv_name = "Interface MPC-1211(CTP/PCI/MPC-SH02)", .mv_setup = mpc1211_setup, .mv_nr_irqs = 48, .mv_irq_demux = mpc1211_irq_demux, .mv_init_irq = init_mpc1211_IRQ, }; -ALIAS_MV(mpc1211) diff --git a/arch/sh/boards/renesas/edosk7705/setup.c b/arch/sh/boards/renesas/edosk7705/setup.c index ec5be0107719..f076c45308dd 100644 --- a/arch/sh/boards/renesas/edosk7705/setup.c +++ b/arch/sh/boards/renesas/edosk7705/setup.c @@ -21,7 +21,7 @@ static void __init sh_edosk7705_init_irq(void) /* * The Machine Vector */ -struct sh_machine_vector mv_edosk7705 __initmv = { +static struct sh_machine_vector mv_edosk7705 __initmv = { .mv_name = "EDOSK7705", .mv_nr_irqs = 80, @@ -41,4 +41,3 @@ struct sh_machine_vector mv_edosk7705 __initmv = { .mv_isa_port2addr = sh_edosk7705_isa_port2addr, .mv_init_irq = sh_edosk7705_init_irq, }; -ALIAS_MV(edosk7705) diff --git a/arch/sh/boards/renesas/hs7751rvoip/setup.c b/arch/sh/boards/renesas/hs7751rvoip/setup.c index f7d0e304d899..fa5fa3920222 100644 --- a/arch/sh/boards/renesas/hs7751rvoip/setup.c +++ b/arch/sh/boards/renesas/hs7751rvoip/setup.c @@ -89,7 +89,7 @@ static void __init hs7751rvoip_setup(char **cmdline_p) printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n"); } -struct sh_machine_vector mv_hs7751rvoip __initmv = { +static struct sh_machine_vector mv_hs7751rvoip __initmv = { .mv_name = "HS7751RVoIP", .mv_setup = hs7751rvoip_setup, .mv_nr_irqs = 72, @@ -118,4 +118,3 @@ struct sh_machine_vector mv_hs7751rvoip __initmv = { .mv_init_irq = hs7751rvoip_init_irq, .mv_ioport_map = hs7751rvoip_ioport_map, }; -ALIAS_MV(hs7751rvoip) diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c index 0727ef92f2b3..5afb864a1ec5 100644 --- a/arch/sh/boards/renesas/r7780rp/setup.c +++ b/arch/sh/boards/renesas/r7780rp/setup.c @@ -166,10 +166,9 @@ static void __init highlander_setup(char **cmdline_p) /* * The Machine Vector */ -struct sh_machine_vector mv_highlander __initmv = { +static struct sh_machine_vector mv_highlander __initmv = { .mv_name = "Highlander", .mv_nr_irqs = 109, .mv_setup = highlander_setup, .mv_init_irq = highlander_init_irq, }; -ALIAS_MV(highlander) diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c index 593f26a85e9c..656fda30ef70 100644 --- a/arch/sh/boards/renesas/rts7751r2d/setup.c +++ b/arch/sh/boards/renesas/rts7751r2d/setup.c @@ -176,7 +176,7 @@ static void __init rts7751r2d_setup(char **cmdline_p) /* * The Machine Vector */ -struct sh_machine_vector mv_rts7751r2d __initmv = { +static struct sh_machine_vector mv_rts7751r2d __initmv = { .mv_name = "RTS7751R2D", .mv_setup = rts7751r2d_setup, .mv_nr_irqs = 72, @@ -189,4 +189,3 @@ struct sh_machine_vector mv_rts7751r2d __initmv = { .mv_consistent_free = voyagergx_consistent_free, #endif }; -ALIAS_MV(rts7751r2d) diff --git a/arch/sh/boards/renesas/sh7710voipgw/setup.c b/arch/sh/boards/renesas/sh7710voipgw/setup.c index 180810b12107..2dce8bd97f90 100644 --- a/arch/sh/boards/renesas/sh7710voipgw/setup.c +++ b/arch/sh/boards/renesas/sh7710voipgw/setup.c @@ -88,9 +88,8 @@ static void __init sh7710voipgw_init_irq(void) /* * The Machine Vector */ -struct sh_machine_vector mv_sh7710voipgw __initmv = { +static struct sh_machine_vector mv_sh7710voipgw __initmv = { .mv_name = "SH7710 VoIP Gateway", .mv_nr_irqs = 104, .mv_init_irq = sh7710voipgw_init_irq, }; -ALIAS_MV(sh7710voipgw) diff --git a/arch/sh/boards/renesas/systemh/setup.c b/arch/sh/boards/renesas/systemh/setup.c index 936117659b74..ee78af842778 100644 --- a/arch/sh/boards/renesas/systemh/setup.c +++ b/arch/sh/boards/renesas/systemh/setup.c @@ -28,7 +28,7 @@ static void __init sh7751systemh_init_irq(void) make_systemh_irq(0xb); /* Ethernet interrupt */ } -struct sh_machine_vector mv_7751systemh __initmv = { +static struct sh_machine_vector mv_7751systemh __initmv = { .mv_name = "7751 SystemH", .mv_nr_irqs = 72, @@ -55,4 +55,3 @@ struct sh_machine_vector mv_7751systemh __initmv = { .mv_init_irq = sh7751systemh_init_irq, }; -ALIAS_MV(7751systemh) diff --git a/arch/sh/boards/saturn/setup.c b/arch/sh/boards/saturn/setup.c index a3a37c9aad2e..7df4312fbb1f 100644 --- a/arch/sh/boards/saturn/setup.c +++ b/arch/sh/boards/saturn/setup.c @@ -18,7 +18,7 @@ extern int saturn_irq_demux(int irq_nr); /* * The Machine Vector */ -struct sh_machine_vector mv_saturn __initmv = { +static struct sh_machine_vector mv_saturn __initmv = { .mv_name = "Sega Saturn", .mv_nr_irqs = 80, /* Fix this later */ @@ -28,4 +28,3 @@ struct sh_machine_vector mv_saturn __initmv = { .mv_ioremap = saturn_ioremap, .mv_iounmap = saturn_iounmap, }; -ALIAS_MV(saturn) diff --git a/arch/sh/boards/se/7206/setup.c b/arch/sh/boards/se/7206/setup.c index ca714879f559..a074b62505ef 100644 --- a/arch/sh/boards/se/7206/setup.c +++ b/arch/sh/boards/se/7206/setup.c @@ -70,7 +70,7 @@ __initcall(se7206_devices_setup); * The Machine Vector */ -struct sh_machine_vector mv_se __initmv = { +static struct sh_machine_vector mv_se __initmv = { .mv_name = "SolutionEngine", .mv_nr_irqs = 256, .mv_inb = se7206_inb, @@ -96,4 +96,3 @@ struct sh_machine_vector mv_se __initmv = { .mv_init_irq = init_se7206_IRQ, }; -ALIAS_MV(se) diff --git a/arch/sh/boards/se/7300/setup.c b/arch/sh/boards/se/7300/setup.c index f1960956bad0..eb469f5b6e97 100644 --- a/arch/sh/boards/se/7300/setup.c +++ b/arch/sh/boards/se/7300/setup.c @@ -46,7 +46,7 @@ __initcall(se7300_devices_setup); /* * The Machine Vector */ -struct sh_machine_vector mv_7300se __initmv = { +static struct sh_machine_vector mv_7300se __initmv = { .mv_name = "SolutionEngine 7300", .mv_nr_irqs = 109, .mv_inb = sh7300se_inb, @@ -72,4 +72,3 @@ struct sh_machine_vector mv_7300se __initmv = { .mv_init_irq = init_7300se_IRQ, }; -ALIAS_MV(7300se) diff --git a/arch/sh/boards/se/73180/setup.c b/arch/sh/boards/se/73180/setup.c index e143017c8975..1deee8556642 100644 --- a/arch/sh/boards/se/73180/setup.c +++ b/arch/sh/boards/se/73180/setup.c @@ -46,7 +46,7 @@ __initcall(se73180_devices_setup); /* * The Machine Vector */ -struct sh_machine_vector mv_73180se __initmv = { +static struct sh_machine_vector mv_73180se __initmv = { .mv_name = "SolutionEngine 73180", .mv_nr_irqs = 108, .mv_inb = sh73180se_inb, @@ -73,4 +73,3 @@ struct sh_machine_vector mv_73180se __initmv = { .mv_init_irq = init_73180se_IRQ, .mv_irq_demux = shmse_irq_demux, }; -ALIAS_MV(73180se) diff --git a/arch/sh/boards/se/7343/setup.c b/arch/sh/boards/se/7343/setup.c index 3fdb16f2cef1..8fec155e2ff7 100644 --- a/arch/sh/boards/se/7343/setup.c +++ b/arch/sh/boards/se/7343/setup.c @@ -64,7 +64,7 @@ static void __init sh7343se_setup(char **cmdline_p) /* * The Machine Vector */ -struct sh_machine_vector mv_7343se __initmv = { +static struct sh_machine_vector mv_7343se __initmv = { .mv_name = "SolutionEngine 7343", .mv_setup = sh7343se_setup, .mv_nr_irqs = 108, @@ -92,4 +92,3 @@ struct sh_machine_vector mv_7343se __initmv = { .mv_init_irq = init_7343se_IRQ, .mv_irq_demux = shmse_irq_demux, }; -ALIAS_MV(7343se) diff --git a/arch/sh/boards/se/7619/setup.c b/arch/sh/boards/se/7619/setup.c index 52d2c4d5d2fa..1d0ef7faa10d 100644 --- a/arch/sh/boards/se/7619/setup.c +++ b/arch/sh/boards/se/7619/setup.c @@ -15,8 +15,7 @@ * The Machine Vector */ -struct sh_machine_vector mv_se __initmv = { +static struct sh_machine_vector mv_se __initmv = { .mv_name = "SolutionEngine", .mv_nr_irqs = 108, }; -ALIAS_MV(se) diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c index 17a2631de3ba..2962da148f3f 100644 --- a/arch/sh/boards/se/770x/setup.c +++ b/arch/sh/boards/se/770x/setup.c @@ -122,7 +122,7 @@ device_initcall(se_devices_setup); /* * The Machine Vector */ -struct sh_machine_vector mv_se __initmv = { +static struct sh_machine_vector mv_se __initmv = { .mv_name = "SolutionEngine", .mv_setup = smsc_setup, #if defined(CONFIG_CPU_SH4) @@ -160,4 +160,3 @@ struct sh_machine_vector mv_se __initmv = { .mv_init_irq = init_se_IRQ, }; -ALIAS_MV(se) diff --git a/arch/sh/boards/se/7722/setup.c b/arch/sh/boards/se/7722/setup.c index 636ca6c987e0..6cca6cbc8069 100644 --- a/arch/sh/boards/se/7722/setup.c +++ b/arch/sh/boards/se/7722/setup.c @@ -137,7 +137,7 @@ static void __init se7722_setup(char **cmdline_p) /* * The Machine Vector */ -struct sh_machine_vector mv_se7722 __initmv = { +static struct sh_machine_vector mv_se7722 __initmv = { .mv_name = "Solution Engine 7722" , .mv_setup = se7722_setup , .mv_nr_irqs = 109 , @@ -145,4 +145,3 @@ struct sh_machine_vector mv_se7722 __initmv = { .mv_irq_demux = se7722_irq_demux, }; -ALIAS_MV(se7722) diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c index 52c7bfa57c2c..7873d07e40c1 100644 --- a/arch/sh/boards/se/7751/setup.c +++ b/arch/sh/boards/se/7751/setup.c @@ -48,7 +48,7 @@ __initcall(se7751_devices_setup); /* * The Machine Vector */ -struct sh_machine_vector mv_7751se __initmv = { +static struct sh_machine_vector mv_7751se __initmv = { .mv_name = "7751 SolutionEngine", .mv_nr_irqs = 72, @@ -71,4 +71,3 @@ struct sh_machine_vector mv_7751se __initmv = { .mv_init_irq = init_7751se_IRQ, }; -ALIAS_MV(7751se) diff --git a/arch/sh/boards/se/7780/setup.c b/arch/sh/boards/se/7780/setup.c index df7d08a24c9f..723f2fd4d55b 100644 --- a/arch/sh/boards/se/7780/setup.c +++ b/arch/sh/boards/se/7780/setup.c @@ -113,10 +113,9 @@ static void __init se7780_setup(char **cmdline_p) /* * The Machine Vector */ -struct sh_machine_vector mv_se7780 __initmv = { +static struct sh_machine_vector mv_se7780 __initmv = { .mv_name = "Solution Engine 7780" , .mv_setup = se7780_setup , .mv_nr_irqs = 111 , .mv_init_irq = init_se7780_IRQ, }; -ALIAS_MV(se7780) diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c index c069c444b4ec..d7867c190a96 100644 --- a/arch/sh/boards/sh03/setup.c +++ b/arch/sh/boards/sh03/setup.c @@ -74,11 +74,10 @@ static int __init sh03_devices_setup(void) } __initcall(sh03_devices_setup); -struct sh_machine_vector mv_sh03 __initmv = { +static struct sh_machine_vector mv_sh03 __initmv = { .mv_name = "Interface (CTP/PCI-SH03)", .mv_setup = sh03_setup, .mv_nr_irqs = 48, .mv_ioport_map = sh03_ioport_map, .mv_init_irq = init_sh03_IRQ, }; -ALIAS_MV(sh03) diff --git a/arch/sh/boards/shmin/setup.c b/arch/sh/boards/shmin/setup.c index 4a9df4a6b034..9c8bb51eb4bb 100644 --- a/arch/sh/boards/shmin/setup.c +++ b/arch/sh/boards/shmin/setup.c @@ -43,9 +43,8 @@ static void __iomem *shmin_ioport_map(unsigned long port, unsigned int size) } -struct sh_machine_vector mv_shmin __initmv = { +static struct sh_machine_vector mv_shmin __initmv = { .mv_name = "SHMIN", .mv_init_irq = init_shmin_irq, .mv_ioport_map = shmin_ioport_map, }; -ALIAS_MV(shmin) diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c index 650fb3645947..b40124c092f5 100644 --- a/arch/sh/boards/snapgear/setup.c +++ b/arch/sh/boards/snapgear/setup.c @@ -96,7 +96,7 @@ static void __init snapgear_setup(char **cmdline_p) /* * The Machine Vector */ -struct sh_machine_vector mv_snapgear __initmv = { +static struct sh_machine_vector mv_snapgear __initmv = { .mv_name = "SnapGear SecureEdge5410", .mv_setup = snapgear_setup, .mv_nr_irqs = 72, @@ -117,4 +117,3 @@ struct sh_machine_vector mv_snapgear __initmv = { .mv_init_irq = init_snapgear_IRQ, }; -ALIAS_MV(snapgear) diff --git a/arch/sh/boards/superh/microdev/setup.c b/arch/sh/boards/superh/microdev/setup.c index 6396cea1c896..fc8cd06d66cf 100644 --- a/arch/sh/boards/superh/microdev/setup.c +++ b/arch/sh/boards/superh/microdev/setup.c @@ -371,7 +371,7 @@ static void __init microdev_setup(char **cmdline_p) /* * The Machine Vector */ -struct sh_machine_vector mv_sh4202_microdev __initmv = { +static struct sh_machine_vector mv_sh4202_microdev __initmv = { .mv_name = "SH4-202 MicroDev", .mv_setup = microdev_setup, .mv_nr_irqs = 72, /* QQQ need to check this - use the MACRO */ @@ -403,4 +403,3 @@ struct sh_machine_vector mv_sh4202_microdev __initmv = { .mv_heartbeat = microdev_heartbeat, #endif }; -ALIAS_MV(sh4202_microdev) diff --git a/arch/sh/boards/titan/setup.c b/arch/sh/boards/titan/setup.c index 6bcd939bfaed..630f62f69a36 100644 --- a/arch/sh/boards/titan/setup.c +++ b/arch/sh/boards/titan/setup.c @@ -28,7 +28,7 @@ static void __init init_titan_irq(void) make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map)); } -struct sh_machine_vector mv_titan __initmv = { +static struct sh_machine_vector mv_titan __initmv = { .mv_name = "Titan", .mv_inb = titan_inb, @@ -52,4 +52,3 @@ struct sh_machine_vector mv_titan __initmv = { .mv_init_irq = init_titan_irq, }; -ALIAS_MV(titan) diff --git a/arch/sh/boards/unknown/setup.c b/arch/sh/boards/unknown/setup.c index bee4612de59b..f975a1f9094b 100644 --- a/arch/sh/boards/unknown/setup.c +++ b/arch/sh/boards/unknown/setup.c @@ -15,7 +15,6 @@ #include #include -struct sh_machine_vector mv_unknown __initmv = { +static struct sh_machine_vector mv_unknown __initmv = { .mv_name = "Unknown", }; -ALIAS_MV(unknown) diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c index 1e78191154e3..e8121de5faa4 100644 --- a/arch/sh/kernel/machvec.c +++ b/arch/sh/kernel/machvec.c @@ -29,7 +29,7 @@ static struct sh_machine_vector * __init get_mv_byname(const char *name) struct sh_machine_vector *mv; for_each_mv(mv) - if (strcasecmp(name, get_system_type()) == 0) + if (strcasecmp(name, mv->mv_name) == 0) return mv; return NULL; @@ -55,26 +55,43 @@ static int __init early_parse_mv(char *from) mv_name[mv_len] = '\0'; from = mv_end; - if (strcmp(sh_mv.mv_name, mv_name) != 0) { - mvp = get_mv_byname(mv_name); - if (unlikely(!mvp)) { - printk("Available vectors:\n\n\t"); - for_each_mv(mvp) - printk("'%s', ", mvp->mv_name); - printk("\n\n"); - panic("Failed to select machvec '%s' -- halting.\n", - mv_name); - } else - sh_mv = *mvp; - } + mvp = get_mv_byname(mv_name); + if (unlikely(!mvp)) { + printk("Available vectors:\n\n\t"); + for_each_mv(mvp) + printk("'%s', ", mvp->mv_name); + printk("\n\n"); + panic("Failed to select machvec '%s' -- halting.\n", + mv_name); + } else + sh_mv = *mvp; - printk(KERN_NOTICE "Booting machvec: %s\n", sh_mv.mv_name); return 0; } early_param("sh_mv", early_parse_mv); void __init sh_mv_setup(void) { + /* + * Only overload the machvec if one hasn't been selected on + * the command line with sh_mv= + */ + if (strcmp(sh_mv.mv_name, "Unknown") != 0) { + unsigned long machvec_size; + + machvec_size = ((unsigned long)&__machvec_end - + (unsigned long)&__machvec_start); + + /* + * If the machvec hasn't been preselected, use the first + * vector (usually the only one) from .machvec.init. + */ + if (machvec_size >= sizeof(struct sh_machine_vector)) + sh_mv = *(struct sh_machine_vector *)&__machvec_start; + } + + printk(KERN_NOTICE "Booting machvec: %s\n", get_system_type()); + /* * Manually walk the vec, fill in anything that the board hasn't yet * by hand, wrapping to the generic implementation. diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 65c093145dac..55ed653c7a67 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -42,6 +42,13 @@ extern void * __rd_start, * __rd_end; * The bigger value means no problem. */ struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, }; + +/* + * The machine vector. First entry in .machvec.init, or clobbered by + * sh_mv= on the command line, prior to .machvec.init teardown. + */ +struct sh_machine_vector sh_mv = { .mv_name = "Unknown", }; + #ifdef CONFIG_VT struct screen_info screen_info; #endif diff --git a/include/asm-sh/machvec.h b/include/asm-sh/machvec.h index 70389b72ffef..088698bacf2f 100644 --- a/include/asm-sh/machvec.h +++ b/include/asm-sh/machvec.h @@ -13,7 +13,6 @@ #include #include #include -#include struct device; @@ -68,4 +67,7 @@ extern struct sh_machine_vector sh_mv; #define get_system_type() sh_mv.mv_name +#define __initmv \ + __attribute_used__ __attribute__((__section__ (".machvec.init"))) + #endif /* _ASM_SH_MACHVEC_H */ diff --git a/include/asm-sh/machvec_init.h b/include/asm-sh/machvec_init.h deleted file mode 100644 index cb015b8bb365..000000000000 --- a/include/asm-sh/machvec_init.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * include/asm-sh/machvec_init.h - * - * Copyright 2000 Stuart Menefy (stuart.menefy@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * This file has goodies to help simplify instantiation of machine vectors. - */ - -#ifndef __SH_MACHVEC_INIT_H -#define __SH_MACHVEC_INIT_H - -#define __initmv __attribute__((unused,__section__ (".machvec.init"))) -#define ALIAS_MV(system) \ - asm(".weak sh_mv\nsh_mv = mv_"#system ); - -#endif /* __SH_MACHVEC_INIT_H */ -- cgit v1.2.3-59-g8ed1b From 5900711ad7173b1cf3ee72eb21572e20b263ca0d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 23 May 2007 17:40:56 +0900 Subject: sh: pfn_valid() depends on flatmem. pfn_valid() is already defined in the sparsemem case, so we only need to define this for CONFIG_FLATMEM. Signed-off-by: Paul Mundt --- include/asm-sh/page.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h index 011dfbe14a6b..cb54b25100b1 100644 --- a/include/asm-sh/page.h +++ b/include/asm-sh/page.h @@ -135,7 +135,9 @@ typedef struct { unsigned long pgd; } pgd_t; #define PFN_START (__MEMORY_START >> PAGE_SHIFT) #define ARCH_PFN_OFFSET (PFN_START) #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) +#ifdef CONFIG_FLATMEM #define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_low_pfn) +#endif #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ -- cgit v1.2.3-59-g8ed1b From dfbb9042801eaeb4df9015bb86224291a39a0f52 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 23 May 2007 17:48:36 +0900 Subject: sh: sparsemem support. This implements basic sparsemem support for SH. Presently this only uses static sparsemem, and we still permit explicit selection of flatmem. Those boards that want sparsemem can select it as usual. Signed-off-by: Paul Mundt --- arch/sh/kernel/setup.c | 8 ++++++-- arch/sh/mm/Kconfig | 10 ++++++++++ arch/sh/mm/init.c | 29 ++++++----------------------- include/asm-sh/sparsemem.h | 16 ++++++++++++++++ 4 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 include/asm-sh/sparsemem.h (limited to 'include') diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 6f1ea9b33374..3241a6274b81 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -128,6 +128,7 @@ void __init setup_bootmem_allocator(unsigned long start_pfn) bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, min_low_pfn, max_low_pfn); + add_active_range(0, min_low_pfn, max_low_pfn); register_bootmem_low_pages(); node_set_online(0); @@ -192,6 +193,7 @@ static void __init setup_memory(void) */ start_pfn = PFN_UP(__pa(_end)); setup_bootmem_allocator(start_pfn); + sparse_memory_present_with_active_regions(0); } #else extern void __init setup_memory(void); @@ -250,8 +252,9 @@ void __init setup_arch(char **cmdline_p) min_low_pfn = __MEMORY_START >> PAGE_SHIFT; nodes_clear(node_online_map); + + /* Setup bootmem with available RAM */ setup_memory(); - paging_init(); sparse_init(); #ifdef CONFIG_DUMMY_CONSOLE @@ -261,8 +264,9 @@ void __init setup_arch(char **cmdline_p) /* Perform the machine specific initialisation */ if (likely(sh_mv.mv_setup)) sh_mv.mv_setup(cmdline_p); -} + paging_init(); +} static const char *cpu_name[] = { [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619", diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 00f64c41edba..46fd212b3ed6 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -300,6 +300,13 @@ config NODES_SHIFT config ARCH_FLATMEM_ENABLE def_bool y +config ARCH_SPARSEMEM_ENABLE + def_bool y + select SPARSEMEM_STATIC + +config ARCH_SPARSEMEM_DEFAULT + def_bool y + config MAX_ACTIVE_REGIONS int default "1" @@ -307,6 +314,9 @@ config MAX_ACTIVE_REGIONS config ARCH_POPULATES_NODE_MAP def_bool y +config ARCH_SELECT_MEMORY_MODEL + def_bool y + choice prompt "Kernel page size" default PAGE_SIZE_4KB diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index e0e644ff3204..1589466f9f87 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -36,14 +36,11 @@ void show_mem(void) show_free_areas(); for_each_online_pgdat(pgdat) { - struct page *page, *end; - unsigned long flags; + unsigned long flags, i; pgdat_resize_lock(pgdat, &flags); - page = pgdat->node_mem_map; - end = page + pgdat->node_spanned_pages; - - do { + for (i = 0; i < pgdat->node_spanned_pages; i++) { + struct page *page = pgdat_page_nr(pgdat, i); total++; if (PageReserved(page)) reserved++; @@ -55,9 +52,7 @@ void show_mem(void) free++; else shared += page_count(page) - 1; - page++; - } while (page < end); - + } pgdat_resize_unlock(pgdat, &flags); } @@ -169,15 +164,11 @@ void __init paging_init(void) low = pgdat->bdata->node_low_pfn; max_zone_pfns[ZONE_NORMAL] = low; - add_active_range(nid, start_pfn, low); printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n", nid, start_pfn, low); free_area_init_nodes(max_zone_pfns); - - printk("Node %u: mem_map starts at %p\n", - pgdat->node_id, pgdat->node_mem_map); } } @@ -185,16 +176,13 @@ static struct kcore_list kcore_mem, kcore_vmalloc; void __init mem_init(void) { - int codesize, reservedpages, datasize, initsize; + int codesize, datasize, initsize; int nid; - reservedpages = 0; - for_each_online_node(nid) { pg_data_t *pgdat = NODE_DATA(nid); unsigned long node_pages = 0; void *node_high_memory; - int i; num_physpages += pgdat->node_present_pages; @@ -203,10 +191,6 @@ void __init mem_init(void) totalram_pages += node_pages; - for (i = 0; i < node_pages; i++) - if (PageReserved(pgdat->node_mem_map + i)) - reservedpages++; - node_high_memory = (void *)((pgdat->node_start_pfn + pgdat->node_spanned_pages) << PAGE_SHIFT); @@ -239,11 +223,10 @@ void __init mem_init(void) VMALLOC_END - VMALLOC_START); printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, " - "%dk reserved, %dk data, %dk init)\n", + "%dk data, %dk init)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), totalram_pages << (PAGE_SHIFT-10), codesize >> 10, - reservedpages << (PAGE_SHIFT-10), datasize >> 10, initsize >> 10); diff --git a/include/asm-sh/sparsemem.h b/include/asm-sh/sparsemem.h new file mode 100644 index 000000000000..547a540b6667 --- /dev/null +++ b/include/asm-sh/sparsemem.h @@ -0,0 +1,16 @@ +#ifndef __ASM_SH_SPARSEMEM_H +#define __ASM_SH_SPARSEMEM_H + +#ifdef __KERNEL__ +/* + * SECTION_SIZE_BITS 2^N: how big each section will be + * MAX_PHYSADDR_BITS 2^N: how much physical address space we have + * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space + */ +#define SECTION_SIZE_BITS 26 +#define MAX_PHYSADDR_BITS 32 +#define MAX_PHYSMEM_BITS 32 + +#endif + +#endif /* __ASM_SH_SPARSEMEM_H */ -- cgit v1.2.3-59-g8ed1b From cbd2d9d8fcd9d2a46d71d0703a76773c20383c66 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Jun 2007 15:46:56 +0900 Subject: sh: Default to 4-byte alignment for SLUB objects. Slub currently defaults to 8-byte alignment for the kmalloc and slab minalign values, where 4 will suffice. In the slab case BYTES_PER_WORD == 4 already, so defining the minalign values outright doesn't cause any regressions there either. Signed-off-by: Paul Mundt --- include/asm-sh/page.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h index cb54b25100b1..6bc9bba10105 100644 --- a/include/asm-sh/page.h +++ b/include/asm-sh/page.h @@ -151,5 +151,12 @@ typedef struct { unsigned long pgd; } pgd_t; #define __HAVE_ARCH_GATE_AREA #endif +/* + * Slub defaults to 8-byte alignment, we're only interested in 4. + * Slab defaults to BYTES_PER_WORD, which ends up being the same anyways. + */ +#define ARCH_KMALLOC_MINALIGN 4 +#define ARCH_SLAB_MINALIGN 4 + #endif /* __KERNEL__ */ #endif /* __ASM_SH_PAGE_H */ -- cgit v1.2.3-59-g8ed1b From b241cb0c885e55839fb0f93c6a4539c5416cc39f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 6 Jun 2007 17:52:19 +0900 Subject: sh: Support for multiple nodes. This adds basic support for multiple nodes on SH machines. This is primarily useful for boards with many different memory blocks that are otherwise unused (SH7722/SH7785 URAM and so forth). Signed-off-by: Paul Mundt --- arch/sh/mm/Kconfig | 11 ++++++ arch/sh/mm/Makefile | 1 + arch/sh/mm/numa.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++ include/asm-sh/mmzone.h | 46 ++++++++++++++++++++++++ include/asm-sh/topology.h | 30 ++++++++++++++++ 5 files changed, 180 insertions(+) create mode 100644 arch/sh/mm/numa.c create mode 100644 include/asm-sh/mmzone.h (limited to 'include') diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 955a851c0c75..8c5b73ab4772 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -293,6 +293,17 @@ config VSYSCALL For systems with an MMU that can afford to give up a page, (the default value) say Y. +config NUMA + bool "Non Uniform Memory Access (NUMA) Support" + depends on MMU && EXPERIMENTAL + default n + help + Some SH systems have many various memories scattered around + the address space, each with varying latencies. This enables + support for these blocks by binding them to nodes and allowing + memory policies to be used for prioritizing and controlling + allocation behaviour. + config NODES_SHIFT int default "1" diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 3ffd7f68c0a2..47c330c528db 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -29,3 +29,4 @@ endif obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o obj-$(CONFIG_32BIT) += pmb.o +obj-$(CONFIG_NUMA) += numa.o diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c new file mode 100644 index 000000000000..8aff065dd307 --- /dev/null +++ b/arch/sh/mm/numa.c @@ -0,0 +1,92 @@ +/* + * arch/sh/mm/numa.c - Multiple node support for SH machines + * + * Copyright (C) 2007 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include + +static bootmem_data_t plat_node_bdata[MAX_NUMNODES]; +struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; +EXPORT_SYMBOL_GPL(node_data); + +/* + * On SH machines the conventional approach is to stash system RAM + * in node 0, and other memory blocks in to node 1 and up, ordered by + * latency. Each node's pgdat is node-local at the beginning of the node, + * immediately followed by the node mem map. + */ +void __init setup_memory(void) +{ + unsigned long free_pfn = PFN_UP(__pa(_end)); + + /* + * Node 0 sets up its pgdat at the first available pfn, + * and bumps it up before setting up the bootmem allocator. + */ + NODE_DATA(0) = pfn_to_kaddr(free_pfn); + memset(NODE_DATA(0), 0, sizeof(struct pglist_data)); + free_pfn += PFN_UP(sizeof(struct pglist_data)); + NODE_DATA(0)->bdata = &plat_node_bdata[0]; + + /* Set up node 0 */ + setup_bootmem_allocator(free_pfn); + + /* Give the platforms a chance to hook up their nodes */ + plat_mem_setup(); +} + +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; + + /* 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; + end_pfn = end >> PAGE_SHIFT; + + 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)); + memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); + + NODE_DATA(nid)->bdata = &plat_node_bdata[nid]; + NODE_DATA(nid)->node_start_pfn = start_pfn; + NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; + + /* 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); + + 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)); + reserve_bootmem_node(NODE_DATA(nid), free_pfn << PAGE_SHIFT, + bootmap_pages << PAGE_SHIFT); + + /* It's up */ + node_set_online(nid); + + /* Kick sparsemem */ + sparse_memory_present_with_active_regions(nid); +} diff --git a/include/asm-sh/mmzone.h b/include/asm-sh/mmzone.h new file mode 100644 index 000000000000..7969f381dff2 --- /dev/null +++ b/include/asm-sh/mmzone.h @@ -0,0 +1,46 @@ +#ifndef __ASM_SH_MMZONE_H +#define __ASM_SH_MMZONE_H + +#ifdef __KERNEL__ + +#ifdef CONFIG_NEED_MULTIPLE_NODES +extern struct pglist_data *node_data[]; +#define NODE_DATA(nid) (node_data[nid]) + +#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) +#define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \ + NODE_DATA(nid)->node_spanned_pages) + +static inline int pfn_to_nid(unsigned long pfn) +{ + int nid; + + for (nid = 0; nid < MAX_NUMNODES; nid++) + if (pfn >= node_start_pfn(nid) && pfn <= node_end_pfn(nid)) + break; + + return nid; +} + +static inline struct pglist_data *pfn_to_pgdat(unsigned long pfn) +{ + return NODE_DATA(pfn_to_nid(pfn)); +} + +/* arch/sh/mm/numa.c */ +void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end); +#else +static inline void +setup_bootmem_node(int nid, unsigned long start, unsigned long end) +{ +} +#endif /* CONFIG_NEED_MULTIPLE_NODES */ + +/* Platform specific mem init */ +void __init plat_mem_setup(void); + +/* arch/sh/kernel/setup.c */ +void __init setup_bootmem_allocator(unsigned long start_pfn); + +#endif /* __KERNEL__ */ +#endif /* __ASM_SH_MMZONE_H */ diff --git a/include/asm-sh/topology.h b/include/asm-sh/topology.h index cff001c316fe..f402a3b1cfa4 100644 --- a/include/asm-sh/topology.h +++ b/include/asm-sh/topology.h @@ -1,6 +1,36 @@ #ifndef _ASM_SH_TOPOLOGY_H #define _ASM_SH_TOPOLOGY_H +#ifdef CONFIG_NUMA + +/* sched_domains SD_NODE_INIT for sh machines */ +#define SD_NODE_INIT (struct sched_domain) { \ + .span = CPU_MASK_NONE, \ + .parent = NULL, \ + .child = NULL, \ + .groups = NULL, \ + .min_interval = 8, \ + .max_interval = 32, \ + .busy_factor = 32, \ + .imbalance_pct = 125, \ + .cache_nice_tries = 2, \ + .busy_idx = 3, \ + .idle_idx = 2, \ + .newidle_idx = 0, \ + .wake_idx = 1, \ + .forkexec_idx = 1, \ + .flags = SD_LOAD_BALANCE \ + | SD_BALANCE_FORK \ + | SD_BALANCE_EXEC \ + | SD_SERIALIZE \ + | SD_WAKE_BALANCE, \ + .last_balance = jiffies, \ + .balance_interval = 1, \ + .nr_balance_failed = 0, \ +} + +#endif + #include #endif /* _ASM_SH_TOPOLOGY_H */ -- cgit v1.2.3-59-g8ed1b From b9601c5e59dd25693345558a301e833741bf5874 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 8 Jun 2007 11:55:28 +0900 Subject: sh: Kill off dead SH7604 support. This was added during 2.5.x, but was never moved along. This can easily be resurrected if someone has one they wish to work with, but it's not worth keeping around in its current form. Signed-off-by: Paul Mundt --- arch/sh/Makefile | 1 - arch/sh/boards/saturn/Makefile | 8 --- arch/sh/boards/saturn/io.c | 26 --------- arch/sh/boards/saturn/irq.c | 118 ----------------------------------------- arch/sh/boards/saturn/setup.c | 30 ----------- arch/sh/boards/saturn/smp.c | 68 ------------------------ arch/sh/kernel/cpu/sh2/probe.c | 10 +--- arch/sh/kernel/setup.c | 2 +- arch/sh/mm/Kconfig | 4 -- arch/sh/tools/mach-types | 1 - include/asm-sh/cpu-sh2/cache.h | 20 +------ include/asm-sh/processor.h | 2 +- include/asm-sh/saturn/io.h | 19 ------- include/asm-sh/saturn/smpc.h | 34 ------------ 14 files changed, 5 insertions(+), 338 deletions(-) delete mode 100644 arch/sh/boards/saturn/Makefile delete mode 100644 arch/sh/boards/saturn/io.c delete mode 100644 arch/sh/boards/saturn/irq.c delete mode 100644 arch/sh/boards/saturn/setup.c delete mode 100644 arch/sh/boards/saturn/smp.c delete mode 100644 include/asm-sh/saturn/io.h delete mode 100644 include/asm-sh/saturn/smpc.h (limited to 'include') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index aa76167ceb48..6e1e17467a47 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -97,7 +97,6 @@ machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) += se/7300 machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) += se/7343 machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) += se/73180 machdir-$(CONFIG_SH_HP6XX) += hp6xx -machdir-$(CONFIG_SH_SATURN) += saturn machdir-$(CONFIG_SH_DREAMCAST) += dreamcast machdir-$(CONFIG_SH_MPC1211) += mpc1211 machdir-$(CONFIG_SH_SH03) += sh03 diff --git a/arch/sh/boards/saturn/Makefile b/arch/sh/boards/saturn/Makefile deleted file mode 100644 index 75a3042e252e..000000000000 --- a/arch/sh/boards/saturn/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for the Sega Saturn specific parts of the kernel -# - -obj-y := setup.o io.o irq.o - -obj-$(CONFIG_SMP) += smp.o - diff --git a/arch/sh/boards/saturn/io.c b/arch/sh/boards/saturn/io.c deleted file mode 100644 index c6e4f7f2e686..000000000000 --- a/arch/sh/boards/saturn/io.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * arch/sh/boards/saturn/io.c - * - * I/O routines for the Sega Saturn. - * - * Copyright (C) 2002 Paul Mundt - * - * Released under the terms of the GNU GPL v2.0. - */ -#include -#include - -unsigned long saturn_isa_port2addr(unsigned long offset) -{ - return offset; -} - -void *saturn_ioremap(unsigned long offset, unsigned long size) -{ - return (void *)offset; -} - -void saturn_iounmap(void *addr) -{ -} - diff --git a/arch/sh/boards/saturn/irq.c b/arch/sh/boards/saturn/irq.c deleted file mode 100644 index 15d1d3f0f787..000000000000 --- a/arch/sh/boards/saturn/irq.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * arch/sh/boards/saturn/irq.c - * - * Copyright (C) 2002 Paul Mundt - * - * Released under the terms of the GNU GPL v2.0. - */ -#include -#include -#include -#include -#include - -/* - * Interrupts map out as follows: - * - * Vector Name Mask - * - * 64 VBLANKIN 0x0001 - * 65 VBLANKOUT 0x0002 - * 66 HBLANKIN 0x0004 - * 67 TIMER0 0x0008 - * 68 TIMER1 0x0010 - * 69 DSPEND 0x0020 - * 70 SOUNDREQUEST 0x0040 - * 71 SYSTEMMANAGER 0x0080 - * 72 PAD 0x0100 - * 73 LEVEL2DMAEND 0x0200 - * 74 LEVEL1DMAEND 0x0400 - * 75 LEVEL0DMAEND 0x0800 - * 76 DMAILLEGAL 0x1000 - * 77 SRITEDRAWEND 0x2000 - * 78 ABUS 0x8000 - * - */ -#define SATURN_IRQ_MIN 64 /* VBLANKIN */ -#define SATURN_IRQ_MAX 78 /* ABUS */ - -#define SATURN_IRQ_MASK 0xbfff - -static inline u32 saturn_irq_mask(unsigned int irq_nr) -{ - u32 mask; - - mask = (1 << (irq_nr - SATURN_IRQ_MIN)); - mask <<= (irq_nr == SATURN_IRQ_MAX); - mask &= SATURN_IRQ_MASK; - - return mask; -} - -static inline void mask_saturn_irq(unsigned int irq_nr) -{ - u32 mask; - - mask = ctrl_inl(SATURN_IMR); - mask |= saturn_irq_mask(irq_nr); - ctrl_outl(mask, SATURN_IMR); -} - -static inline void unmask_saturn_irq(unsigned int irq_nr) -{ - u32 mask; - - mask = ctrl_inl(SATURN_IMR); - mask &= ~saturn_irq_mask(irq_nr); - ctrl_outl(mask, SATURN_IMR); -} - -static void disable_saturn_irq(unsigned int irq_nr) -{ - mask_saturn_irq(irq_nr); -} - -static void enable_saturn_irq(unsigned int irq_nr) -{ - unmask_saturn_irq(irq_nr); -} - -static void mask_and_ack_saturn_irq(unsigned int irq_nr) -{ - mask_saturn_irq(irq_nr); -} - -static void end_saturn_irq(unsigned int irq_nr) -{ - if (!(irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - unmask_saturn_irq(irq_nr); -} - -static unsigned int startup_saturn_irq(unsigned int irq_nr) -{ - unmask_saturn_irq(irq_nr); - - return 0; -} - -static void shutdown_saturn_irq(unsigned int irq_nr) -{ - mask_saturn_irq(irq_nr); -} - -static struct hw_interrupt_type saturn_int = { - .typename = "Saturn", - .enable = enable_saturn_irq, - .disable = disable_saturn_irq, - .ack = mask_and_ack_saturn_irq, - .end = end_saturn_irq, - .startup = startup_saturn_irq, - .shutdown = shutdown_saturn_irq, -}; - -int saturn_irq_demux(int irq_nr) -{ - /* FIXME */ - return irq_nr; -} - diff --git a/arch/sh/boards/saturn/setup.c b/arch/sh/boards/saturn/setup.c deleted file mode 100644 index 7df4312fbb1f..000000000000 --- a/arch/sh/boards/saturn/setup.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * arch/sh/boards/saturn/setup.c - * - * Hardware support for the Sega Saturn. - * - * Copyright (c) 2002 Paul Mundt - * - * Released under the terms of the GNU GPL v2.0. - */ -#include -#include -#include -#include -#include - -extern int saturn_irq_demux(int irq_nr); - -/* - * The Machine Vector - */ -static struct sh_machine_vector mv_saturn __initmv = { - .mv_name = "Sega Saturn", - .mv_nr_irqs = 80, /* Fix this later */ - - .mv_isa_port2addr = saturn_isa_port2addr, - .mv_irq_demux = saturn_irq_demux, - - .mv_ioremap = saturn_ioremap, - .mv_iounmap = saturn_iounmap, -}; diff --git a/arch/sh/boards/saturn/smp.c b/arch/sh/boards/saturn/smp.c deleted file mode 100644 index 76460918c9cd..000000000000 --- a/arch/sh/boards/saturn/smp.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * arch/sh/boards/saturn/smp.c - * - * SMP support for the Sega Saturn. - * - * Copyright (c) 2002 Paul Mundt - * - * Released under the terms of the GNU GPL v2.0. - */ -#include -#include -#include - -#include - -extern void start_secondary(void); - -void __smp_send_ipi(unsigned int cpu, unsigned int action) -{ - /* Nothing here yet .. */ -} - -unsigned int __smp_probe_cpus(void) -{ - /* - * This is just a straightforward master/slave configuration, - * and probing isn't really supported.. - */ - return 2; -} - -/* - * We're only allowed to do byte-access to SMPC registers. In - * addition to which, we treat them as write-only, since - * reading from them will return undefined data. - */ -static inline void smpc_slave_stop(unsigned int cpu) -{ - smpc_barrier(); - ctrl_outb(1, SMPC_STATUS); - - ctrl_outb(SMPC_CMD_SSHOFF, SMPC_COMMAND); - smpc_barrier(); -} - -static inline void smpc_slave_start(unsigned int cpu) -{ - ctrl_outb(1, SMPC_STATUS); - ctrl_outb(SMPC_CMD_SSHON, SMPC_COMMAND); - - smpc_barrier(); -} - -void __smp_slave_init(unsigned int cpu) -{ - register unsigned long vbr; - void **entry; - - __asm__ __volatile__ ("stc vbr, %0\n\t" : "=r" (vbr)); - entry = (void **)(vbr + 0x310 + 0x94); - - smpc_slave_stop(cpu); - - *(void **)entry = (void *)start_secondary; - - smpc_slave_start(cpu); -} - diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index 108e81b682ed..74765ae42929 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c @@ -17,15 +17,7 @@ int __init detect_cpu_and_cache_system(void) { -#if defined(CONFIG_CPU_SUBTYPE_SH7604) - current_cpu_data.type = CPU_SH7604; - current_cpu_data.dcache.ways = 4; - current_cpu_data.dcache.way_incr = (1<<10); - current_cpu_data.dcache.sets = 64; - current_cpu_data.dcache.entry_shift = 4; - current_cpu_data.dcache.linesz = L1_CACHE_BYTES; - current_cpu_data.dcache.flags = 0; -#elif defined(CONFIG_CPU_SUBTYPE_SH7619) +#if defined(CONFIG_CPU_SUBTYPE_SH7619) current_cpu_data.type = CPU_SH7619; current_cpu_data.dcache.ways = 4; current_cpu_data.dcache.way_incr = (1<<12); diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index c2c6bfdf4dfe..765f83c1bca4 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -271,7 +271,7 @@ void __init setup_arch(char **cmdline_p) static const char *cpu_name[] = { [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619", - [CPU_SH7604] = "SH7604", [CPU_SH7300] = "SH7300", + [CPU_SH7300] = "SH7300", [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708", [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710", diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 0c24abdd4ea1..b013a05fbc51 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -45,10 +45,6 @@ choice # SH-2 Processor Support -config CPU_SUBTYPE_SH7604 - bool "Support SH7604 processor" - select CPU_SH2 - config CPU_SUBTYPE_SH7619 bool "Support SH7619 processor" select CPU_SH2 diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index 8ae43f8c085c..4b5e9305092e 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types @@ -18,7 +18,6 @@ SE SH_SOLUTION_ENGINE HP6XX SH_HP6XX HD64461 HD64461 HD64465 HD64465 -SATURN SH_SATURN DREAMCAST SH_DREAMCAST MPC1211 SH_MPC1211 SNAPGEAR SH_SECUREEDGE5410 diff --git a/include/asm-sh/cpu-sh2/cache.h b/include/asm-sh/cpu-sh2/cache.h index 20b9796842dc..f02ba7a672b2 100644 --- a/include/asm-sh/cpu-sh2/cache.h +++ b/include/asm-sh/cpu-sh2/cache.h @@ -12,23 +12,7 @@ #define L1_CACHE_SHIFT 4 -#if defined(CONFIG_CPU_SUBTYPE_SH7604) -#define CCR 0xfffffe92 /* Address of Cache Control Register */ - -#define CCR_CACHE_CE 0x01 /* Cache enable */ -#define CCR_CACHE_ID 0x02 /* Instruction Replacement disable */ -#define CCR_CACHE_OD 0x04 /* Data Replacement disable */ -#define CCR_CACHE_TW 0x08 /* Two-way mode */ -#define CCR_CACHE_CP 0x10 /* Cache purge */ - -#define CACHE_OC_ADDRESS_ARRAY 0x60000000 - -#define CCR_CACHE_ENABLE CCR_CACHE_CE -#define CCR_CACHE_INVALIDATE CCR_CACHE_CP -#define CCR_CACHE_ORA CCR_CACHE_TW -#define CCR_CACHE_WT 0x00 /* SH-2 is _always_ write-through */ - -#elif defined(CONFIG_CPU_SUBTYPE_SH7619) +#if defined(CONFIG_CPU_SUBTYPE_SH7619) #define CCR1 0xffffffec #define CCR CCR1 @@ -49,5 +33,5 @@ #define CCR_CACHE_ENABLE CCR_CACHE_CE #define CCR_CACHE_INVALIDATE CCR_CACHE_CF #endif -#endif /* __ASM_CPU_SH2_CACHE_H */ +#endif /* __ASM_CPU_SH2_CACHE_H */ diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index d42f68e724fa..1fc5eed1b22a 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -36,7 +36,7 @@ */ enum cpu_type { /* SH-2 types */ - CPU_SH7604, CPU_SH7619, + CPU_SH7619, /* SH-2A types */ CPU_SH7206, diff --git a/include/asm-sh/saturn/io.h b/include/asm-sh/saturn/io.h deleted file mode 100644 index f1b9b5d633f4..000000000000 --- a/include/asm-sh/saturn/io.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * include/asm-sh/saturn/io.h - * - * I/O functions for use on the Sega Saturn. - * - * Copyright (C) 2002 Paul Mundt - * - * Released under the terms of the GNU GPL v2.0. - */ -#ifndef __ASM_SH_SATURN_IO_H -#define __ASM_SH_SATURN_IO_H - -/* arch/sh/boards/saturn/io.c */ -extern unsigned long saturn_isa_port2addr(unsigned long offset); -extern void *saturn_ioremap(unsigned long offset, unsigned long size); -extern void saturn_iounmap(void *addr); - -#endif /* __ASM_SH_SATURN_IO_H */ - diff --git a/include/asm-sh/saturn/smpc.h b/include/asm-sh/saturn/smpc.h deleted file mode 100644 index 5de5c12d6347..000000000000 --- a/include/asm-sh/saturn/smpc.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * include/asm-sh/saturn/smpc.h - * - * System Manager / Peripheral Control definitions. - * - * Copyright (C) 2002 Paul Mundt - * - * Released under the terms of the GNU GPL v2.0. - */ -#ifndef __ASM_SH_SATURN_SMPC_H -#define __ASM_SH_SATURN_SMPC_H - -#include - -#define SMPC_COMMAND 0x2010001f /* SMPC command register */ -#define SMPC_RESULT 0x2010005f /* SMPC result register */ -#define SMPC_STATUS 0x20100063 /* SMPC status register */ - -#define SMPC_CMD_MSHON 0x0001 /* Master SH On */ -#define SMPC_CMD_SSHON 0x0002 /* Slave SH On */ -#define SMPC_CMD_SSHOFF 0x0003 /* Slave SH Off */ -#define SMPC_CMD_SNDON 0x0004 /* Sound On */ -#define SMPC_CMD_SNDOFF 0x0005 /* Sound Off */ -#define SMPC_CMD_CDON 0x0006 /* CD On */ -#define SMPC_CMD_CDOFF 0x0007 /* CD Off */ - -static inline void smpc_barrier(void) -{ - while ((ctrl_inb(SMPC_STATUS) & 0x0001) == 0x0001) - ; -} - -#endif /* __ASM_SH_SATURN_SMPC_H */ - -- cgit v1.2.3-59-g8ed1b From 711be60522829beb82807de2867e56513934ebec Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Fri, 8 Jun 2007 11:56:31 +0900 Subject: sh: Warn against direct inclusion of . Signed-off-by: Robert P. J. Day Signed-off-by: Paul Mundt --- include/asm-sh/rwsem.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-sh/rwsem.h b/include/asm-sh/rwsem.h index 4931ba817d73..1987f3ea7f1b 100644 --- a/include/asm-sh/rwsem.h +++ b/include/asm-sh/rwsem.h @@ -1,11 +1,15 @@ /* - * include/asm-ppc/rwsem.h: R/W semaphores for SH using the stuff + * include/asm-sh/rwsem.h: R/W semaphores for SH using the stuff * in lib/rwsem.c. */ #ifndef _ASM_SH_RWSEM_H #define _ASM_SH_RWSEM_H +#ifndef _LINUX_RWSEM_H +#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead" +#endif + #ifdef __KERNEL__ #include #include -- cgit v1.2.3-59-g8ed1b From 14bea95b84a3eedfe9e12f576d5f9f63f0f1b6ff Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 11 Jun 2007 10:18:45 +0900 Subject: sh: Compile fix for SH7604 removal. There was a last remaining reference to CPU_SH7604 that broke the build, kill that off too. Signed-off-by: Paul Mundt --- include/asm-sh/bugs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-sh/bugs.h b/include/asm-sh/bugs.h index 5a117ec43c77..efc8fd3e1fad 100644 --- a/include/asm-sh/bugs.h +++ b/include/asm-sh/bugs.h @@ -22,7 +22,7 @@ static void __init check_bugs(void) current_cpu_data.loops_per_jiffy = loops_per_jiffy; switch (current_cpu_data.type) { - case CPU_SH7604 ... CPU_SH7619: + case CPU_SH7619: *p++ = '2'; break; case CPU_SH7206: -- cgit v1.2.3-59-g8ed1b From 357d59469c1179c30b8c425aba302346fac3594e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 11 Jun 2007 15:32:07 +0900 Subject: sh: Tidy up dependencies for SH-2 build. SH-2 can presently get in to some pretty bogus states, so we tidy up the dependencies a bit and get it all building again. This gets us a bit closer to a functional allyesconfig and allmodconfig, though there are still a few things to fix up. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 43 +++++++++++++++++++++++++++++++----------- arch/sh/Kconfig.debug | 1 + arch/sh/cchips/Kconfig | 6 +----- arch/sh/drivers/pci/Kconfig | 1 + arch/sh/kernel/cpu/init.c | 15 +-------------- arch/sh/kernel/cpu/sh2/probe.c | 3 +-- arch/sh/kernel/process.c | 4 +--- arch/sh/mm/Kconfig | 16 ++++------------ arch/sh/mm/init.c | 2 ++ include/asm-sh/cache.h | 4 ++++ include/asm-sh/hd64461.h | 2 +- include/asm-sh/processor.h | 4 ---- include/asm-sh/system.h | 2 +- include/asm-sh/ubc.h | 9 +++++++-- 14 files changed, 57 insertions(+), 55 deletions(-) (limited to 'include') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 78f5f2305132..b16407c9f2c4 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -55,8 +55,21 @@ config GENERIC_TIME config GENERIC_CLOCKEVENTS def_bool n +config SYS_SUPPORTS_PM + bool + config SYS_SUPPORTS_APM_EMULATION bool + select SYS_SUPPORTS_PM + +config SYS_SUPPORTS_SMP + bool + +config SYS_SUPPORTS_NUMA + bool + +config SYS_SUPPORTS_PCI + bool config ARCH_MAY_HAVE_PC_FDC bool @@ -102,7 +115,7 @@ endchoice config SH_FPU bool "FPU support" - depends on !CPU_SH3 + depends on CPU_SH4 default y help Selecting this option will enable support for SH processors that @@ -236,6 +249,7 @@ config SH_7751_SOLUTION_ENGINE config SH_7780_SOLUTION_ENGINE bool "SolutionEngine7780" select SOLUTION_ENGINE + select SYS_SUPPORTS_PCI depends on CPU_SUBTYPE_SH7780 help Select 7780 SolutionEngine if configuring for a Renesas SH7780 @@ -275,20 +289,16 @@ config SH_7751_SYSTEMH config SH_HP6XX bool "HP6XX" select SYS_SUPPORTS_APM_EMULATION + select HD6446X_SERIES depends on CPU_SUBTYPE_SH7709 help Select HP6XX if configuring for a HP jornada HP6xx. More information (hardware only) at . -config SH_SATURN - bool "Saturn" - depends on CPU_SUBTYPE_SH7604 - help - Select Saturn if configuring for a SEGA Saturn. - config SH_DREAMCAST bool "Dreamcast" + select SYS_SUPPORTS_PCI depends on CPU_SUBTYPE_SH7091 help Select Dreamcast if configuring for a SEGA Dreamcast. @@ -307,6 +317,7 @@ config SH_MPC1211 config SH_SH03 bool "Interface CTP/PCI-SH03" depends on CPU_SUBTYPE_SH7751 && BROKEN + select SYS_SUPPORTS_PCI help CTP/PCI-SH03 is a CPU module computer that is produced by Interface Corporation. @@ -315,6 +326,7 @@ config SH_SH03 config SH_SECUREEDGE5410 bool "SecureEdge5410" depends on CPU_SUBTYPE_SH7751R + select SYS_SUPPORTS_PCI help Select SecureEdge5410 if configuring for a SnapGear SH board. This includes both the OEM SecureEdge products as well as the @@ -337,6 +349,7 @@ config SH_7710VOIPGW config SH_RTS7751R2D bool "RTS7751R2D" depends on CPU_SUBTYPE_SH7751R + select SYS_SUPPORTS_PCI help Select RTS7751R2D if configuring for a Renesas Technology Sales SH-Graphics board. @@ -344,6 +357,7 @@ config SH_RTS7751R2D config SH_HIGHLANDER bool "Highlander" depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 + select SYS_SUPPORTS_PCI config SH_EDOSK7705 bool "EDOSK7705" @@ -359,12 +373,14 @@ config SH_SH4202_MICRODEV config SH_LANDISK bool "LANDISK" depends on CPU_SUBTYPE_SH7751R + select SYS_SUPPORTS_PCI help I-O DATA DEVICE, INC. "LANDISK Series" support. config SH_TITAN bool "TITAN" depends on CPU_SUBTYPE_SH7751R + select SYS_SUPPORTS_PCI help Select Titan if you are configuring for a Nimble Microsystems NetEngine NP51R. @@ -378,6 +394,7 @@ config SH_SHMIN config SH_LBOX_RE2 bool "L-BOX RE2" depends on CPU_SUBTYPE_SH7751R + select SYS_SUPPORTS_PCI help Select L-BOX RE2 if configuring for the NTT COMWARE L-BOX RE2. @@ -481,8 +498,10 @@ config SH_PCLK_FREQ config SH_CLK_MD int "CPU Mode Pin Setting" - default 0 depends on CPU_SUBTYPE_SH7619 || CPU_SUBTYPE_SH7206 + default 6 if CPU_SUBTYPE_SH7206 + default 5 if CPU_SUBTYPE_SH7619 + default 0 help MD2 - MD0 pin setting. @@ -554,6 +573,7 @@ config CRASH_DUMP config SMP bool "Symmetric multi-processing support" + depends on SYS_SUPPORTS_SMP ---help--- This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If @@ -617,6 +637,7 @@ config BOOT_LINK_OFFSET config UBC_WAKEUP bool "Wakeup UBC on startup" + depends on CPU_SH4 help Selecting this option will wakeup the User Break Controller (UBC) on startup. Although the UBC is left in an awake state when the processor @@ -645,8 +666,8 @@ menu "Bus options" # we're not using PCMCIA, so we make it dependent on # PCMCIA outright. -- PFM. config ISA - bool - default y if PCMCIA + def_bool y + depends on PCMCIA && HD6446X_SERIES help Find out whether you have ISA slots on your motherboard. ISA is the name of a bus system, i.e. the way the CPU talks to the other stuff @@ -701,7 +722,7 @@ source "fs/Kconfig.binfmt" endmenu menu "Power management options (EXPERIMENTAL)" -depends on EXPERIMENTAL +depends on EXPERIMENTAL && SYS_SUPPORTS_PM source kernel/power/Kconfig diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index d849d47d6af9..52f6a99c8ecc 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -86,6 +86,7 @@ config SH_KGDB bool "Include KGDB kernel debugger" select FRAME_POINTER select DEBUG_INFO + depends on CPU_SH3 || CPU_SH4 help Include in-kernel hooks for kgdb, the Linux kernel source level debugger. See for more information. diff --git a/arch/sh/cchips/Kconfig b/arch/sh/cchips/Kconfig index 0582ca8346b6..2e516e9a6ede 100644 --- a/arch/sh/cchips/Kconfig +++ b/arch/sh/cchips/Kconfig @@ -13,10 +13,8 @@ config VOYAGERGX are additional GPIO bits that can be used to interface to external as well. -# A board must have defined HD6446X_SERIES in order to see these config HD6446X_SERIES - bool "HD6446x support" - default n + bool choice prompt "HD6446x options" @@ -25,7 +23,6 @@ choice config HD64461 bool "Hitachi HD64461 companion chip support" - depends on CPU_SUBTYPE_SH7709 ---help--- The Hitachi HD64461 provides an interface for the SH7709 CPU, supporting a LCD controller, @@ -40,7 +37,6 @@ config HD64461 config HD64465 bool "Hitachi HD64465 companion chip support" - depends on CPU_SUBTYPE_SH7750 ---help--- The Hitachi HD64465 provides an interface for the SH7750 CPU, supporting a LCD controller, diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig index 6d1cbbe6745c..fbc6f2c8649f 100644 --- a/arch/sh/drivers/pci/Kconfig +++ b/arch/sh/drivers/pci/Kconfig @@ -1,5 +1,6 @@ config PCI bool "PCI support" + depends on SYS_SUPPORTS_PCI help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 6451ad630174..9172e97dc26a 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -21,8 +21,7 @@ #include #include #include - -extern void detect_cpu_and_cache_system(void); +#include /* * Generic wrapper for command line arguments to disable on-chip @@ -152,15 +151,6 @@ static void __init cache_init(void) flags |= CCR_CACHE_CB; #endif -#ifdef CONFIG_SH_OCRAM - /* Turn on OCRAM -- halve the OC */ - flags |= CCR_CACHE_ORA; - current_cpu_data.dcache.sets >>= 1; - - current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets * - current_cpu_data.dcache.linesz; -#endif - ctrl_outl(flags, CCR); back_to_P1(); } @@ -269,7 +259,6 @@ asmlinkage void __init sh_cpu_init(void) } #endif -#ifdef CONFIG_UBC_WAKEUP /* * Some brain-damaged loaders decided it would be a good idea to put * the UBC to sleep. This causes some issues when it comes to things @@ -277,7 +266,5 @@ asmlinkage void __init sh_cpu_init(void) * we wake it up and hope that all is well. */ ubc_wakeup(); -#endif - speculative_execution_init(); } diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index 74765ae42929..abbf17427e52 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c @@ -9,9 +9,8 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ - - #include +#include #include #include diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 9ae3da00eaae..6334a4c54c7c 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -320,9 +320,7 @@ static void ubc_set_tracing(int asid, unsigned long pc) ctrl_outl(pc, UBC_BARA); #ifdef CONFIG_MMU - /* We don't have any ASID settings for the SH-2! */ - if (current_cpu_data.type != CPU_SH7604) - ctrl_outb(asid, UBC_BASRA); + ctrl_outb(asid, UBC_BASRA); #endif ctrl_outl(0, UBC_BAMRA); diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index b013a05fbc51..58bf6225d913 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -48,6 +48,7 @@ choice config CPU_SUBTYPE_SH7619 bool "Support SH7619 processor" select CPU_SH2 + select CPU_HAS_IPR_IRQ # SH-2A Processor Support @@ -208,6 +209,7 @@ config CPU_SUBTYPE_SH7722 select CPU_SHX2 select CPU_HAS_IPR_IRQ select ARCH_SPARSEMEM_ENABLE + select SYS_SUPPORTS_NUMA endchoice @@ -292,7 +294,7 @@ config VSYSCALL config NUMA bool "Non Uniform Memory Access (NUMA) Support" - depends on MMU && SPARSEMEM && EXPERIMENTAL + depends on MMU && SYS_SUPPORTS_NUMA && EXPERIMENTAL default n help Some SH systems have many various memories scattered around @@ -308,6 +310,7 @@ config NODES_SHIFT config ARCH_FLATMEM_ENABLE def_bool y + depends on !NUMA config ARCH_SPARSEMEM_ENABLE def_bool y @@ -419,15 +422,4 @@ config SH_WRITETHROUGH If unsure, say N. -config SH_OCRAM - bool "Operand Cache RAM (OCRAM) support" - help - Selecting this option will automatically tear down the number of - sets in the dcache by half, which in turn exposes a memory range. - - The addresses for the OC RAM base will vary according to the - processor version. Consult vendor documentation for specifics. - - If unsure, say N. - endmenu diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 40d4e798e7fb..82b68c789a5f 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -300,6 +300,7 @@ int remove_memory(u64 start, u64 size) } EXPORT_SYMBOL_GPL(remove_memory); +#ifdef CONFIG_NUMA int memory_add_physaddr_to_nid(u64 addr) { /* Node 0 for now.. */ @@ -307,3 +308,4 @@ int memory_add_physaddr_to_nid(u64 addr) } EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); #endif +#endif diff --git a/include/asm-sh/cache.h b/include/asm-sh/cache.h index 9a3cb6ba9d15..7a18649d1ccb 100644 --- a/include/asm-sh/cache.h +++ b/include/asm-sh/cache.h @@ -9,6 +9,7 @@ #define __ASM_SH_CACHE_H #ifdef __KERNEL__ +#include #include #define SH_CACHE_VALID 1 @@ -48,6 +49,9 @@ struct cache_info { unsigned long flags; }; + +int __init detect_cpu_and_cache_system(void); + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* __ASM_SH_CACHE_H */ diff --git a/include/asm-sh/hd64461.h b/include/asm-sh/hd64461.h index 27e5c34e2659..c9050b2b5510 100644 --- a/include/asm-sh/hd64461.h +++ b/include/asm-sh/hd64461.h @@ -184,7 +184,7 @@ #define HD64461_NIRR 0x15000 #define HD64461_NIMR 0x15002 -#define HD64461_IRQBASE OFFCHIP_IRQ_BASE +#define HD64461_IRQBASE 64 #define HD64461_IRQ_NUM 16 #define HD64461_IRQ_UART (HD64461_IRQBASE+5) diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index 1fc5eed1b22a..1a20db096196 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -228,11 +228,7 @@ static __inline__ void grab_fpu(struct pt_regs *regs) regs->sr &= ~SR_FD; } -#ifdef CONFIG_CPU_SH4 extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs); -#else -#define save_fpu(tsk) do { } while (0) -#endif #define unlazy_fpu(tsk, regs) do { \ if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \ diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index fb22fc3f87ad..7c75045ae22b 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h @@ -126,7 +126,7 @@ static inline void sched_cacheflush(void) #define smp_read_barrier_depends() do { } while(0) #endif -#define set_mb(var, value) do { xchg(&var, value); } while (0) +#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) /* * Jump to P2 area. diff --git a/include/asm-sh/ubc.h b/include/asm-sh/ubc.h index ae9bbdeefbe1..38d46e01b846 100644 --- a/include/asm-sh/ubc.h +++ b/include/asm-sh/ubc.h @@ -51,9 +51,14 @@ #define BRCR_UBDE (1 << 0) #ifndef __ASSEMBLY__ -/* arch/sh/kernel/ubc.S */ -extern void ubc_wakeup(void); +/* arch/sh/kernel/cpu/ubc.S */ extern void ubc_sleep(void); + +#ifdef CONFIG_UBC_WAKEUP +extern void ubc_wakeup(void); +#else +#define ubc_wakeup() do { } while (0) +#endif #endif #endif /* __KERNEL__ */ -- cgit v1.2.3-59-g8ed1b From d619500aed2f9b841b2310bc94f8056ae9ca2a73 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 15 Jun 2007 10:41:54 +0900 Subject: sh: rework intc2 code The shared intc2 code currently contains cpu-specific #ifdefs. This is a tad unclean and it prevents us from using the shared code to drive board-specific irqs on the se7780 board. This patch reworks the intc2 code by moving the base addresses of the intc2 registers into struct intc2_desc. This new structure also contains the name of the controller in struct irq_chip. The idea behind putting struct irq_chip in there is that we can use offsetof() to locate the base addresses in the irq_chip callbacks. One logic change has been made - the original shared intc2 code enabled the interrupts by default but with this patch they are all disabled by default. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/se/7780/irq.c | 45 ++++++++------------------ arch/sh/kernel/cpu/irq/intc2.c | 58 ++++++++++++++++------------------ arch/sh/kernel/cpu/sh4/setup-sh7760.c | 15 ++++++++- arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 15 ++++++++- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 16 +++++++++- include/asm-sh/hw_irq.h | 19 +++++++++++ include/asm-sh/irq.h | 10 ------ 7 files changed, 103 insertions(+), 75 deletions(-) (limited to 'include') diff --git a/arch/sh/boards/se/7780/irq.c b/arch/sh/boards/se/7780/irq.c index 3d0625c2d07b..874914746009 100644 --- a/arch/sh/boards/se/7780/irq.c +++ b/arch/sh/boards/se/7780/irq.c @@ -16,28 +16,6 @@ #include #include -#define INTC_INTMSK0 0xFFD00044 -#define INTC_INTMSKCLR0 0xFFD00064 - -static void disable_se7780_irq(unsigned int irq) -{ - struct intc2_data *p = get_irq_chip_data(irq); - ctrl_outl(1 << p->msk_shift, INTC_INTMSK0 + p->msk_offset); -} - -static void enable_se7780_irq(unsigned int irq) -{ - struct intc2_data *p = get_irq_chip_data(irq); - ctrl_outl(1 << p->msk_shift, INTC_INTMSKCLR0 + p->msk_offset); -} - -static struct irq_chip se7780_irq_chip __read_mostly = { - .name = "SE7780", - .mask = disable_se7780_irq, - .unmask = enable_se7780_irq, - .mask_ack = disable_se7780_irq, -}; - static struct intc2_data intc2_irq_table[] = { { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT1 */ { 4, 0, 30, 0, 30, 3 }, /* daughter board EXTINT2 */ @@ -51,13 +29,24 @@ static struct intc2_data intc2_irq_table[] = { { 0 , 0, 24, 0, 24, 3 }, /* SM501 */ }; +static struct intc2_desc intc2_irq_desc __read_mostly = { + .prio_base = 0, /* N/A */ + .msk_base = 0xffd00044, + .mskclr_base = 0xffd00064, + + .intc2_data = intc2_irq_table, + .nr_irqs = ARRAY_SIZE(intc2_irq_table), + + .chip = { + .name = "INTC2-se7780", + }, +}; + /* * Initialize IRQ setting */ void __init init_se7780_IRQ(void) { - int i ; - /* enable all interrupt at FPGA */ ctrl_outw(0, FPGA_INTMSK1); /* mask SM501 interrupt */ @@ -79,11 +68,5 @@ void __init init_se7780_IRQ(void) /* FPGA + 0x0A */ ctrl_outw((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3); - for (i = 0; i < ARRAY_SIZE(intc2_irq_table); i++) { - disable_irq_nosync(intc2_irq_table[i].irq); - set_irq_chip_and_handler_name( intc2_irq_table[i].irq, &se7780_irq_chip, - handle_level_irq, "level"); - set_irq_chip_data( intc2_irq_table[i].irq, &intc2_irq_table[i] ); - disable_se7780_irq(intc2_irq_table[i].irq); - } + register_intc2_controller(&intc2_irq_desc); } diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c index d8e22f4ff0f0..dae02d3152e7 100644 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ b/arch/sh/kernel/cpu/irq/intc2.c @@ -14,36 +14,26 @@ #include #include -#if defined(CONFIG_CPU_SUBTYPE_SH7760) -#define INTC2_BASE 0xfe080000 -#define INTC2_INTMSK (INTC2_BASE + 0x40) -#define INTC2_INTMSKCLR (INTC2_BASE + 0x60) -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || \ - defined(CONFIG_CPU_SUBTYPE_SH7785) -#define INTC2_BASE 0xffd40000 -#define INTC2_INTMSK (INTC2_BASE + 0x38) -#define INTC2_INTMSKCLR (INTC2_BASE + 0x3c) -#endif +static inline struct intc2_desc *get_intc2_desc(unsigned int irq) +{ + struct irq_chip *chip = get_irq_chip(irq); + return (void *)((char *)chip - offsetof(struct intc2_desc, chip)); +} static void disable_intc2_irq(unsigned int irq) { struct intc2_data *p = get_irq_chip_data(irq); - ctrl_outl(1 << p->msk_shift, INTC2_INTMSK + p->msk_offset); + struct intc2_desc *d = get_intc2_desc(irq); + ctrl_outl(1 << p->msk_shift, d->msk_base + p->msk_offset); } static void enable_intc2_irq(unsigned int irq) { struct intc2_data *p = get_irq_chip_data(irq); - ctrl_outl(1 << p->msk_shift, INTC2_INTMSKCLR + p->msk_offset); + struct intc2_desc *d = get_intc2_desc(irq); + ctrl_outl(1 << p->msk_shift, d->mskclr_base + p->msk_offset); } -static struct irq_chip intc2_irq_chip = { - .name = "INTC2", - .mask = disable_intc2_irq, - .unmask = enable_intc2_irq, - .mask_ack = disable_intc2_irq, -}; - /* * Setup an INTC2 style interrupt. * NOTE: Unlike IPR interrupts, parameters are not shifted by this code, @@ -56,30 +46,36 @@ static struct irq_chip intc2_irq_chip = { * * in the intc2_data table. */ -void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs) +void register_intc2_controller(struct intc2_desc *desc) { int i; - for (i = 0; i < nr_irqs; i++) { + desc->chip.mask = disable_intc2_irq; + desc->chip.unmask = enable_intc2_irq; + desc->chip.mask_ack = disable_intc2_irq; + + for (i = 0; i < desc->nr_irqs; i++) { unsigned long ipr, flags; - struct intc2_data *p = table + i; + struct intc2_data *p = desc->intc2_data + i; disable_irq_nosync(p->irq); - /* Set the priority level */ - local_irq_save(flags); + if (desc->prio_base) { + /* Set the priority level */ + local_irq_save(flags); - ipr = ctrl_inl(INTC2_BASE + p->ipr_offset); - ipr &= ~(0xf << p->ipr_shift); - ipr |= p->priority << p->ipr_shift; - ctrl_outl(ipr, INTC2_BASE + p->ipr_offset); + ipr = ctrl_inl(desc->prio_base + p->ipr_offset); + ipr &= ~(0xf << p->ipr_shift); + ipr |= p->priority << p->ipr_shift; + ctrl_outl(ipr, desc->prio_base + p->ipr_offset); - local_irq_restore(flags); + local_irq_restore(flags); + } - set_irq_chip_and_handler_name(p->irq, &intc2_irq_chip, + set_irq_chip_and_handler_name(p->irq, &desc->chip, handle_level_irq, "level"); set_irq_chip_data(p->irq, p); - enable_intc2_irq(p->irq); + disable_intc2_irq(p->irq); } } diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index b7c702821e6f..6d3c91897774 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -96,6 +96,19 @@ static struct intc2_data intc2_irq_table[] = { {109,12, 0, 4, 0, 3}, /* CMTI */ }; +static struct intc2_desc intc2_irq_desc __read_mostly = { + .prio_base = 0xfe080000, + .msk_base = 0xfe080040, + .mskclr_base = 0xfe080060, + + .intc2_data = intc2_irq_table, + .nr_irqs = ARRAY_SIZE(intc2_irq_table), + + .chip = { + .name = "INTC2-sh7760", + }, +}; + static struct ipr_data sh7760_ipr_map[] = { /* IRQ, IPR-idx, shift, priority */ { 16, 0, 12, 2 }, /* TMU0 TUNI*/ @@ -143,7 +156,7 @@ unsigned int map_ipridx_to_addr(int idx) void __init init_IRQ_intc2(void) { - make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); + register_intc2_controller(&intc2_irq_desc); } void __init init_IRQ_ipr(void) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 9aeaa2ddaa28..b57c760bffde 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -102,7 +102,20 @@ static struct intc2_data intc2_irq_table[] = { { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */ }; +static struct intc2_desc intc2_irq_desc __read_mostly = { + .prio_base = 0xffd40000, + .msk_base = 0xffd40038, + .mskclr_base = 0xffd4003c, + + .intc2_data = intc2_irq_table, + .nr_irqs = ARRAY_SIZE(intc2_irq_table), + + .chip = { + .name = "INTC2-sh7780", + }, +}; + void __init init_IRQ_intc2(void) { - make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); + register_intc2_controller(&intc2_irq_desc); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 07b0de82cfe6..ce10ec5d6914 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -97,7 +97,21 @@ static struct intc2_data intc2_irq_table[] = { { 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */ }; +static struct intc2_desc intc2_irq_desc __read_mostly = { + .prio_base = 0xffd40000, + .msk_base = 0xffd40038, + .mskclr_base = 0xffd4003c, + + .intc2_data = intc2_irq_table, + .nr_irqs = ARRAY_SIZE(intc2_irq_table), + + .chip = { + .name = "INTC2-sh7785", + }, +}; + void __init init_IRQ_intc2(void) { - make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); + register_intc2_controller(&intc2_irq_desc); } + diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 80ee1cda7498..f9dfdc04aef5 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -5,4 +5,23 @@ extern atomic_t irq_err_count; +struct intc2_data { + unsigned short irq; + unsigned char ipr_offset, ipr_shift; + unsigned char msk_offset, msk_shift; + unsigned char priority; +}; + +struct intc2_desc { + unsigned long prio_base; + unsigned long msk_base; + unsigned long mskclr_base; + struct intc2_data *intc2_data; + unsigned int nr_irqs; + struct irq_chip chip; +}; + +void register_intc2_controller(struct intc2_desc *); +void init_IRQ_intc2(void); + #endif /* __ASM_SH_HW_IRQ_H */ diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h index e81bf21c801e..c247b733a7d6 100644 --- a/include/asm-sh/irq.h +++ b/include/asm-sh/irq.h @@ -63,16 +63,6 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs); void make_imask_irq(unsigned int irq); void init_IRQ_ipr(void); -struct intc2_data { - unsigned short irq; - unsigned char ipr_offset, ipr_shift; - unsigned char msk_offset, msk_shift; - unsigned char priority; -}; - -void make_intc2_irq(struct intc2_data *, unsigned int nr_irqs); -void init_IRQ_intc2(void); - static inline int generic_irq_demux(int irq) { return irq; -- cgit v1.2.3-59-g8ed1b From 68abdbbb03476a60d932eeba0035dd5069afec38 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 15 Jun 2007 18:56:19 +0900 Subject: sh: rework ipr code This patch reworks the ipr code by grouping the offset array together with the ipr_data structure in a new data structure called ipr_desc. This new structure also contains the name of the controller in struct irq_chip. The idea behind putting struct irq_chip in there is that we can use offsetof() to locate the base addresses in the irq_chip callbacks. This strategy has much in common with the recently merged intc2 code. One logic change has been made - the original ipr code enabled the interrupts by default but with this patch they are all disabled by default. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/se/770x/irq.c | 124 ++++++++++++++------------------- arch/sh/boards/se/7722/irq.c | 15 +++- arch/sh/boards/se/7751/irq.c | 59 ++++++---------- arch/sh/boards/sh03/setup.c | 28 ++++++-- arch/sh/boards/shmin/setup.c | 30 ++++++-- arch/sh/boards/snapgear/setup.c | 28 ++++++-- arch/sh/boards/titan/setup.c | 22 +++++- arch/sh/kernel/cpu/irq/ipr.c | 59 ++++++++-------- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 24 ++++--- arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 24 ++++--- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 40 ++++++----- arch/sh/kernel/cpu/sh3/setup-sh7709.c | 84 +++++++++++++++------- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 42 ++++++----- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 58 +++++++++------ arch/sh/kernel/cpu/sh4/setup-sh7760.c | 32 +++++---- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 21 +++--- include/asm-sh/hw_irq.h | 23 ++++++ include/asm-sh/irq.h | 30 -------- include/asm-sh/sh03/io.h | 4 -- include/asm-sh/snapgear.h | 4 -- 20 files changed, 427 insertions(+), 324 deletions(-) (limited to 'include') diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c index c8eccff77a04..cdb0807928a5 100644 --- a/arch/sh/boards/se/770x/irq.c +++ b/arch/sh/boards/se/770x/irq.c @@ -15,46 +15,7 @@ #include #include -/* - * If the problem of make_ipr_irq is solved, - * this code will become unnecessary. :-) - */ -static void se770x_disable_ipr_irq(unsigned int irq) -{ - struct ipr_data *p = get_irq_chip_data(irq); - - ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr); -} - -static void se770x_enable_ipr_irq(unsigned int irq) -{ - struct ipr_data *p = get_irq_chip_data(irq); - - ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr); -} - -static struct irq_chip se770x_irq_chip = { - .name = "MS770xSE-FPGA", - .mask = se770x_disable_ipr_irq, - .unmask = se770x_enable_ipr_irq, - .mask_ack = se770x_disable_ipr_irq, -}; - -void make_se770x_irq(struct ipr_data *table, unsigned int nr_irqs) -{ - int i; - - for (i = 0; i < nr_irqs; i++) { - unsigned int irq = table[i].irq; - disable_irq_nosync(irq); - set_irq_chip_and_handler_name(irq, &se770x_irq_chip, - handle_level_irq, "level"); - set_irq_chip_data(irq, &table[i]); - se770x_enable_ipr_irq(irq); - } -} - -static struct ipr_data se770x_ipr_map[] = { +static struct ipr_data ipr_irq_table[] = { /* * Super I/O (Just mimic PC): * 1: keyboard @@ -68,46 +29,67 @@ static struct ipr_data se770x_ipr_map[] = { */ #if defined(CONFIG_CPU_SUBTYPE_SH7705) /* This is default value */ - { 13, 0, 8, 0x0f-13 ,BCR_ILCRA}, - { 5 , 0, 4, 0x0f- 5 ,BCR_ILCRA}, - { 10, 0, 0, 0x0f-10, BCR_ILCRB}, - { 7 , 0, 4, 0x0f- 7, BCR_ILCRC}, - { 3 , 0, 0, 0x0f- 3, BCR_ILCRC}, - { 1 , 0, 12, 0x0f- 1, BCR_ILCRD}, - { 12, 0, 4, 0x0f-12, BCR_ILCRD}, /* LAN */ - { 2 , 0, 8, 0x0f- 2, BCR_ILCRE}, /* PCIRQ2 */ - { 6 , 0, 4, 0x0f- 6, BCR_ILCRE}, /* PCIRQ1 */ - { 14, 0, 0, 0x0f-14, BCR_ILCRE}, /* PCIRQ0 */ - { 0 , 0, 12, 0x0f , BCR_ILCRF}, - { 4 , 0, 4, 0x0f- 4, BCR_ILCRF}, - { 8 , 0, 12, 0x0f- 8, BCR_ILCRG}, - { 9 , 0, 8, 0x0f- 9, BCR_ILCRG}, - { 11, 0, 4, 0x0f-11, BCR_ILCRG}, + { 13, 0, 8, 0x0f-13, }, + { 5 , 0, 4, 0x0f- 5, }, + { 10, 1, 0, 0x0f-10, }, + { 7 , 2, 4, 0x0f- 7, }, + { 3 , 2, 0, 0x0f- 3, }, + { 1 , 3, 12, 0x0f- 1, }, + { 12, 3, 4, 0x0f-12, }, /* LAN */ + { 2 , 4, 8, 0x0f- 2, }, /* PCIRQ2 */ + { 6 , 4, 4, 0x0f- 6, }, /* PCIRQ1 */ + { 14, 4, 0, 0x0f-14, }, /* PCIRQ0 */ + { 0 , 5, 12, 0x0f , }, + { 4 , 5, 4, 0x0f- 4, }, + { 8 , 6, 12, 0x0f- 8, }, + { 9 , 6, 8, 0x0f- 9, }, + { 11, 6, 4, 0x0f-11, }, #else - { 14, 0, 8, 0x0f-14 ,BCR_ILCRA}, - { 12, 0, 4, 0x0f-12 ,BCR_ILCRA}, - { 8, 0, 4, 0x0f- 8 ,BCR_ILCRB}, - { 6, 0, 12, 0x0f- 6 ,BCR_ILCRC}, - { 5, 0, 8, 0x0f- 5 ,BCR_ILCRC}, - { 4, 0, 4, 0x0f- 4 ,BCR_ILCRC}, - { 3, 0, 0, 0x0f- 3 ,BCR_ILCRC}, - { 1, 0, 12, 0x0f- 1 ,BCR_ILCRD}, + { 14, 0, 8, 0x0f-14, }, + { 12, 0, 4, 0x0f-12, }, + { 8, 1, 4, 0x0f- 8, }, + { 6, 2, 12, 0x0f- 6, }, + { 5, 2, 8, 0x0f- 5, }, + { 4, 2, 4, 0x0f- 4, }, + { 3, 2, 0, 0x0f- 3, }, + { 1, 3, 12, 0x0f- 1, }, #if defined(CONFIG_STNIC) /* ST NIC */ - { 10, 0, 4, 0x0f-10 ,BCR_ILCRD}, /* LAN */ + { 10, 3, 4, 0x0f-10, }, /* LAN */ #endif /* MRSHPC IRQs setting */ - { 0, 0, 12, 0x0f- 0 ,BCR_ILCRE}, /* PCIRQ3 */ - { 11, 0, 8, 0x0f-11 ,BCR_ILCRE}, /* PCIRQ2 */ - { 9, 0, 4, 0x0f- 9 ,BCR_ILCRE}, /* PCIRQ1 */ - { 7, 0, 0, 0x0f- 7 ,BCR_ILCRE}, /* PCIRQ0 */ + { 0, 4, 12, 0x0f- 0, }, /* PCIRQ3 */ + { 11, 4, 8, 0x0f-11, }, /* PCIRQ2 */ + { 9, 4, 4, 0x0f- 9, }, /* PCIRQ1 */ + { 7, 4, 0, 0x0f- 7, }, /* PCIRQ0 */ /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ /* NOTE: #2 and #13 are not used on PC */ - { 13, 0, 4, 0x0f-13 ,BCR_ILCRG}, /* SLOTIRQ2 */ - { 2, 0, 0, 0x0f- 2 ,BCR_ILCRG}, /* SLOTIRQ1 */ + { 13, 6, 4, 0x0f-13, }, /* SLOTIRQ2 */ + { 2, 6, 0, 0x0f- 2, }, /* SLOTIRQ1 */ #endif }; +static unsigned long ipr_offsets[] = { + BCR_ILCRA, + BCR_ILCRB, + BCR_ILCRC, + BCR_ILCRD, + BCR_ILCRE, + BCR_ILCRF, + BCR_ILCRG, +}; + +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + .chip = { + .name = "IPR-se770x", + }, +}; + /* * Initialize IRQ setting */ @@ -122,5 +104,5 @@ void __init init_se_IRQ(void) ctrl_outw(0, BCR_ILCRF); ctrl_outw(0, BCR_ILCRG); - make_se770x_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map)); + register_ipr_controller(&ipr_irq_desc); } diff --git a/arch/sh/boards/se/7722/irq.c b/arch/sh/boards/se/7722/irq.c index 099e5deb77f8..26cff0efda40 100644 --- a/arch/sh/boards/se/7722/irq.c +++ b/arch/sh/boards/se/7722/irq.c @@ -19,15 +19,24 @@ #define INTC_INTMSK0 0xFFD00044 #define INTC_INTMSKCLR0 0xFFD00064 +struct se7722_data { + unsigned char irq; + unsigned char ipr_idx; + unsigned char shift; + unsigned short priority; + unsigned long addr; +}; + + static void disable_se7722_irq(unsigned int irq) { - struct ipr_data *p = get_irq_chip_data(irq); + struct se7722_data *p = get_irq_chip_data(irq); ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr ); } static void enable_se7722_irq(unsigned int irq) { - struct ipr_data *p = get_irq_chip_data(irq); + struct se7722_data *p = get_irq_chip_data(irq); ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr ); } @@ -38,7 +47,7 @@ static struct irq_chip se7722_irq_chip __read_mostly = { .mask_ack = disable_se7722_irq, }; -static struct ipr_data ipr_irq_table[] = { +static struct se7722_data ipr_irq_table[] = { /* irq ,idx,sft, priority , addr */ { MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } , { MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } , diff --git a/arch/sh/boards/se/7751/irq.c b/arch/sh/boards/se/7751/irq.c index e4c63a48296c..c3d12590e5db 100644 --- a/arch/sh/boards/se/7751/irq.c +++ b/arch/sh/boards/se/7751/irq.c @@ -14,44 +14,31 @@ #include #include -static struct ipr_data se7751_ipr_map[] = { - /* Leave old Solution Engine code in for reference. */ -#if defined(CONFIG_SH_SOLUTION_ENGINE) - /* - * Super I/O (Just mimic PC): - * 1: keyboard - * 3: serial 0 - * 4: serial 1 - * 5: printer - * 6: floppy - * 8: rtc - * 12: mouse - * 14: ide0 - */ - { 14, BCR_ILCRA, 2, 0x0f-14 }, - { 12, BCR_ILCRA, 1, 0x0f-12 }, - { 8, BCR_ILCRB, 1, 0x0f- 8 }, - { 6, BCR_ILCRC, 3, 0x0f- 6 }, - { 5, BCR_ILCRC, 2, 0x0f- 5 }, - { 4, BCR_ILCRC, 1, 0x0f- 4 }, - { 3, BCR_ILCRC, 0, 0x0f- 3 }, - { 1, BCR_ILCRD, 3, 0x0f- 1 }, +static struct ipr_data ipr_irq_table[] = { + { 13, 3, 3, 2 }, + /* Add additional entries here as drivers are added and tested. */ +}; - { 10, BCR_ILCRD, 1, 0x0f-10 }, /* LAN */ +static unsigned long ipr_offsets[] = { + BCR_ILCRA, + BCR_ILCRB, + BCR_ILCRC, + BCR_ILCRD, + BCR_ILCRE, + BCR_ILCRF, + BCR_ILCRG, +}; - { 0, BCR_ILCRE, 3, 0x0f- 0 }, /* PCIRQ3 */ - { 11, BCR_ILCRE, 2, 0x0f-11 }, /* PCIRQ2 */ - { 9, BCR_ILCRE, 1, 0x0f- 9 }, /* PCIRQ1 */ - { 7, BCR_ILCRE, 0, 0x0f- 7 }, /* PCIRQ0 */ +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), - /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ - /* NOTE: #2 and #13 are not used on PC */ - { 13, BCR_ILCRG, 1, 0x0f-13 }, /* SLOTIRQ2 */ - { 2, BCR_ILCRG, 0, 0x0f- 2 }, /* SLOTIRQ1 */ -#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE) - { 13, BCR_ILCRD, 3, 2 }, - /* Add additional entries here as drivers are added and tested. */ -#endif + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-se7751", + }, }; /* @@ -59,5 +46,5 @@ static struct ipr_data se7751_ipr_map[] = { */ void __init init_7751se_IRQ(void) { - make_ipr_irq(se7751_ipr_map, ARRAY_SIZE(se7751_ipr_map)); + register_ipr_controller(&ipr_irq_desc); } diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c index d7867c190a96..9c031a8c0a1c 100644 --- a/arch/sh/boards/sh03/setup.c +++ b/arch/sh/boards/sh03/setup.c @@ -15,17 +15,33 @@ #include #include -static struct ipr_data sh03_ipr_map[] = { - { IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY }, - { IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY }, - { IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY }, - { IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY }, +static struct ipr_data ipr_irq_table[] = { + { IRL0_IRQ, 0, IRL0_IPR_POS, IRL0_PRIORITY }, + { IRL1_IRQ, 0, IRL1_IPR_POS, IRL1_PRIORITY }, + { IRL2_IRQ, 0, IRL2_IPR_POS, IRL2_PRIORITY }, + { IRL3_IRQ, 0, IRL3_IPR_POS, IRL3_PRIORITY }, +}; + +static unsigned long ipr_offsets[] = { + INTC_IPRD, +}; + +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-sh03", + }, }; static void __init init_sh03_IRQ(void) { ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); - make_ipr_irq(sh03_ipr_map, ARRAY_SIZE(sh03_ipr_map)); + register_ipr_controller(&ipr_irq_desc); } extern void *cf_io_base; diff --git a/arch/sh/boards/shmin/setup.c b/arch/sh/boards/shmin/setup.c index 9c8bb51eb4bb..dfd124509f42 100644 --- a/arch/sh/boards/shmin/setup.c +++ b/arch/sh/boards/shmin/setup.c @@ -6,28 +6,44 @@ * SHMIN Support. */ #include +#include #include #include #include -#include #include #define PFC_PHCR 0xa400010eUL #define INTC_ICR1 0xa4000010UL #define INTC_IPRC 0xa4000016UL -static struct ipr_data shmin_ipr_map[] = { - { .irq=32, .addr=INTC_IPRC, .shift= 0, .priority=0 }, - { .irq=33, .addr=INTC_IPRC, .shift= 4, .priority=0 }, - { .irq=34, .addr=INTC_IPRC, .shift= 8, .priority=8 }, - { .irq=35, .addr=INTC_IPRC, .shift=12, .priority=0 }, +static struct ipr_data ipr_irq_table[] = { + { 32, 0, 0, 0 }, + { 33, 0, 4, 0 }, + { 34, 0, 8, 8 }, + { 35, 0, 12, 0 }, +}; + +static unsigned long ipr_offsets[] = { + INTC_IPRC, +}; + +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-shmin", + }, }; static void __init init_shmin_irq(void) { ctrl_outw(0x2a00, PFC_PHCR); // IRQ0-3=IRQ ctrl_outw(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active. - make_ipr_irq(shmin_ipr_map, ARRAY_SIZE(shmin_ipr_map)); + register_ipr_controller(&ipr_irq_desc); } static void __iomem *shmin_ioport_map(unsigned long port, unsigned int size) diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c index b40124c092f5..84271d85a8dd 100644 --- a/arch/sh/boards/snapgear/setup.c +++ b/arch/sh/boards/snapgear/setup.c @@ -68,11 +68,27 @@ module_init(eraseconfig_init); * IRL3 = crypto */ -static struct ipr_data snapgear_ipr_map[] = { - make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); - make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); - make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); - make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); +static struct ipr_data ipr_irq_table[] = { + { IRL0_IRQ, 0, IRL0_IPR_POS, IRL0_PRIORITY }, + { IRL1_IRQ, 0, IRL1_IPR_POS, IRL1_PRIORITY }, + { IRL2_IRQ, 0, IRL2_IPR_POS, IRL2_PRIORITY }, + { IRL3_IRQ, 0, IRL3_IPR_POS, IRL3_PRIORITY }, +}; + +static unsigned long ipr_offsets[] = { + INTC_IPRD, +}; + +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-snapgear", + }, }; static void __init init_snapgear_IRQ(void) @@ -82,7 +98,7 @@ static void __init init_snapgear_IRQ(void) printk("Setup SnapGear IRQ/IPR ...\n"); - make_ipr_irq(snapgear_ipr_map, ARRAY_SIZE(snapgear_ipr_map)); + register_ipr_controller(&ipr_irq_desc); } /* diff --git a/arch/sh/boards/titan/setup.c b/arch/sh/boards/titan/setup.c index 630f62f69a36..606d25a4b870 100644 --- a/arch/sh/boards/titan/setup.c +++ b/arch/sh/boards/titan/setup.c @@ -12,7 +12,7 @@ #include #include -static struct ipr_data titan_ipr_map[] = { +static struct ipr_data ipr_irq_table[] = { /* IRQ, IPR idx, shift, prio */ { TITAN_IRQ_WAN, 3, 12, 8 }, /* eth0 (WAN) */ { TITAN_IRQ_LAN, 3, 8, 8 }, /* eth1 (LAN) */ @@ -20,12 +20,30 @@ static struct ipr_data titan_ipr_map[] = { { TITAN_IRQ_USB, 3, 0, 8 }, /* mPCI B (bottom), USB */ }; +static unsigned long ipr_offsets[] = { /* stolen from setup-sh7750.c */ + 0xffd00004UL, /* 0: IPRA */ + 0xffd00008UL, /* 1: IPRB */ + 0xffd0000cUL, /* 2: IPRC */ + 0xffd00010UL, /* 3: IPRD */ +}; + +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-titan", + }, +}; static void __init init_titan_irq(void) { /* enable individual interrupt mode for externals */ ipr_irq_enable_irlm(); /* register ipr irqs */ - make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map)); + register_ipr_controller(&ipr_irq_desc); } static struct sh_machine_vector mv_titan __initmv = { diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index 210280b6fddf..98e84f40c713 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -22,58 +22,57 @@ #include #include +static inline struct ipr_desc *get_ipr_desc(unsigned int irq) +{ + struct irq_chip *chip = get_irq_chip(irq); + return (void *)((char *)chip - offsetof(struct ipr_desc, chip)); +} + static void disable_ipr_irq(unsigned int irq) { struct ipr_data *p = get_irq_chip_data(irq); + unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx]; /* Set the priority in IPR to 0 */ - ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr); + ctrl_outw(ctrl_inw(addr) & (0xffff ^ (0xf << p->shift)), addr); } static void enable_ipr_irq(unsigned int irq) { struct ipr_data *p = get_irq_chip_data(irq); + unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx]; /* Set priority in IPR back to original value */ - ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr); + ctrl_outw(ctrl_inw(addr) | (p->priority << p->shift), addr); } -static struct irq_chip ipr_irq_chip = { - .name = "IPR", - .mask = disable_ipr_irq, - .unmask = enable_ipr_irq, - .mask_ack = disable_ipr_irq, -}; - -unsigned int map_ipridx_to_addr(int idx) __attribute__ ((weak)); -unsigned int map_ipridx_to_addr(int idx) -{ - return 0; -} +/* + * The shift value is now the number of bits to shift, not the number of + * bits/4. This is to make it easier to read the value directly from the + * datasheets. The IPR address is calculated using the ipr_offset table. + */ -void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) +void register_ipr_controller(struct ipr_desc *desc) { int i; - for (i = 0; i < nr_irqs; i++) { - unsigned int irq = table[i].irq; + desc->chip.mask = disable_ipr_irq; + desc->chip.unmask = enable_ipr_irq; + desc->chip.mask_ack = disable_ipr_irq; - if (!irq) - irq = table[i].irq = i; + for (i = 0; i < desc->nr_irqs; i++) { + struct ipr_data *p = desc->ipr_data + i; - /* could the IPR index be mapped, if not we ignore this */ - if (!table[i].addr) { - table[i].addr = map_ipridx_to_addr(table[i].ipr_idx); - if (!table[i].addr) - continue; - } + BUG_ON(p->ipr_idx >= desc->nr_offsets); + BUG_ON(!desc->ipr_offsets[p->ipr_idx]); - disable_irq_nosync(irq); - set_irq_chip_and_handler_name(irq, &ipr_irq_chip, + disable_irq_nosync(p->irq); + set_irq_chip_and_handler_name(p->irq, &desc->chip, handle_level_irq, "level"); - set_irq_chip_data(irq, &table[i]); - enable_ipr_irq(irq); + set_irq_chip_data(p->irq, p); + disable_ipr_irq(p->irq); } } -EXPORT_SYMBOL(make_ipr_irq); + +EXPORT_SYMBOL(register_ipr_controller); #if !defined(CONFIG_CPU_HAS_PINT_IRQ) int ipr_irq_demux(int irq) diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index f83ff8a68f35..1a107fe22dde 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -52,7 +52,7 @@ static int __init sh7619_devices_setup(void) } __initcall(sh7619_devices_setup); -static struct ipr_data sh7619_ipr_map[] = { +static struct ipr_data ipr_irq_table[] = { { 86, 0, 4, 2 }, /* CMI0 */ { 88, 1, 12, 3 }, /* SCIF0_ERI */ { 89, 1, 12, 3 }, /* SCIF0_RXI */ @@ -68,7 +68,7 @@ static struct ipr_data sh7619_ipr_map[] = { { 99, 1, 4, 3 }, /* SCIF2_TXI */ }; -static unsigned int ipr_offsets[] = { +static unsigned long ipr_offsets[] = { 0xf8080000, /* IPRC */ 0xf8080002, /* IPRD */ 0xf8080004, /* IPRE */ @@ -76,15 +76,19 @@ static unsigned int ipr_offsets[] = { 0xf8080008, /* IPRG */ }; -/* given the IPR index return the address of the IPR register */ -unsigned int map_ipridx_to_addr(int idx) -{ - if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) - return 0; - return ipr_offsets[idx]; -} +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-sh7619", + }, +}; void __init init_IRQ_ipr(void) { - make_ipr_irq(sh7619_ipr_map, ARRAY_SIZE(sh7619_ipr_map)); + register_ipr_controller(&ipr_irq_desc); } diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index 4ed9110632bc..b6e3a6351fa6 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -57,7 +57,7 @@ static int __init sh7206_devices_setup(void) } __initcall(sh7206_devices_setup); -static struct ipr_data sh7206_ipr_map[] = { +static struct ipr_data ipr_irq_table[] = { { 140, 7, 12, 2 }, /* CMI0 */ { 164, 8, 4, 2 }, /* MTU2_TGI1A */ { 240, 13, 12, 3 }, /* SCIF0_BRI */ @@ -78,7 +78,7 @@ static struct ipr_data sh7206_ipr_map[] = { { 255, 13, 0, 3 }, /* SCIF3_TXI */ }; -static unsigned int ipr_offsets[] = { +static unsigned long ipr_offsets[] = { 0xfffe0818, /* IPR01 */ 0xfffe081a, /* IPR02 */ 0, /* unused */ @@ -95,15 +95,19 @@ static unsigned int ipr_offsets[] = { 0xfffe0c10, /* IPR14 */ }; -/* given the IPR index return the address of the IPR register */ -unsigned int map_ipridx_to_addr(int idx) -{ - if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) - return 0; - return ipr_offsets[idx]; -} +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-sh7206", + }, +}; void __init init_IRQ_ipr(void) { - make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map)); + register_ipr_controller(&ipr_irq_desc); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 1983fb7ad6ea..a55b8ce2c54c 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -48,7 +48,7 @@ static int __init sh7705_devices_setup(void) } __initcall(sh7705_devices_setup); -static struct ipr_data sh7705_ipr_map[] = { +static struct ipr_data ipr_irq_table[] = { /* IRQ, IPR-idx, shift, priority */ { 16, 0, 12, 2 }, /* TMU0 TUNI*/ { 17, 0, 8, 2 }, /* TMU1 TUNI */ @@ -70,25 +70,29 @@ static struct ipr_data sh7705_ipr_map[] = { }; static unsigned long ipr_offsets[] = { - 0xFFFFFEE2 /* 0: IPRA */ -, 0xFFFFFEE4 /* 1: IPRB */ -, 0xA4000016 /* 2: IPRC */ -, 0xA4000018 /* 3: IPRD */ -, 0xA400001A /* 4: IPRE */ -, 0xA4080000 /* 5: IPRF */ -, 0xA4080002 /* 6: IPRG */ -, 0xA4080004 /* 7: IPRH */ + 0xFFFFFEE2, /* 0: IPRA */ + 0xFFFFFEE4, /* 1: IPRB */ + 0xA4000016, /* 2: IPRC */ + 0xA4000018, /* 3: IPRD */ + 0xA400001A, /* 4: IPRE */ + 0xA4080000, /* 5: IPRF */ + 0xA4080002, /* 6: IPRG */ + 0xA4080004, /* 7: IPRH */ }; -/* given the IPR index return the address of the IPR register */ -unsigned int map_ipridx_to_addr(int idx) -{ - if (idx >= ARRAY_SIZE(ipr_offsets)) - return 0; - return ipr_offsets[idx]; -} +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-sh7705", + }, +}; -void __init init_IRQ_ipr() +void __init init_IRQ_ipr(void) { - make_ipr_irq(sh7705_ipr_map, ARRAY_SIZE(sh7705_ipr_map)); + register_ipr_controller(&ipr_irq_desc); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/arch/sh/kernel/cpu/sh3/setup-sh7709.c index c7d7c35fc834..c0265a96e7d3 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7709.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7709.c @@ -52,32 +52,66 @@ static int __init sh7709_devices_setup(void) } __initcall(sh7709_devices_setup); -#define IPRx(A,N) .addr=A, .shift=N -#define IPRA(N) IPRx(0xfffffee2UL,N) -#define IPRB(N) IPRx(0xfffffee4UL,N) -#define IPRC(N) IPRx(0xa4000016UL,N) -#define IPRD(N) IPRx(0xa4000018UL,N) -#define IPRE(N) IPRx(0xa400001aUL,N) - -static struct ipr_data sh7709_ipr_map[] = { - [16] = { IPRA(12), 2 }, /* TMU TUNI0 */ - [17] = { IPRA(8), 4 }, /* TMU TUNI1 */ - [18 ... 19] = { IPRA(4), 1 }, /* TMU TUNI1 */ - [20 ... 22] = { IPRA(0), 2 }, /* RTC CUI */ - [23 ... 26] = { IPRB(4), 3 }, /* SCI */ - [27] = { IPRB(12), 2 }, /* WDT ITI */ - [32] = { IPRC(0), 1 }, /* IRQ 0 */ - [33] = { IPRC(4), 1 }, /* IRQ 1 */ - [34] = { IPRC(8), 1 }, /* IRQ 2 APM */ - [35] = { IPRC(12), 1 }, /* IRQ 3 TOUCHSCREEN */ - [36] = { IPRD(0), 1 }, /* IRQ 4 */ - [37] = { IPRD(4), 1 }, /* IRQ 5 */ - [48 ... 51] = { IPRE(12), 7 }, /* DMA */ - [52 ... 55] = { IPRE(8), 3 }, /* IRDA */ - [56 ... 59] = { IPRE(4), 3 }, /* SCIF */ +static struct ipr_data ipr_irq_table[] = { + { 16, 0, 12, 2 }, /* TMU TUNI0 */ + { 17, 0, 8, 4 }, /* TMU TUNI1 */ + { 18, 0, 4, 1 }, /* TMU TUNI1 */ + { 19, 0, 4, 1 }, /* TMU TUNI1 */ + { 20, 0, 0, 2 }, /* RTC CUI */ + { 21, 0, 0, 2 }, /* RTC CUI */ + { 22, 0, 0, 2 }, /* RTC CUI */ + + { 23, 1, 4, 3 }, /* SCI */ + { 24, 1, 4, 3 }, /* SCI */ + { 25, 1, 4, 3 }, /* SCI */ + { 26, 1, 4, 3 }, /* SCI */ + { 27, 1, 12, 3 }, /* WDT ITI */ + + { 32, 2, 0, 1 }, /* IRQ 0 */ + { 33, 2, 4, 1 }, /* IRQ 1 */ + { 34, 2, 8, 1 }, /* IRQ 2 APM */ + { 35, 2, 12, 1 }, /* IRQ 3 TOUCHSCREEN */ + + { 36, 3, 0, 1 }, /* IRQ 4 */ + { 37, 3, 4, 1 }, /* IRQ 5 */ + + { 48, 4, 12, 7 }, /* DMA */ + { 49, 4, 12, 7 }, /* DMA */ + { 50, 4, 12, 7 }, /* DMA */ + { 51, 4, 12, 7 }, /* DMA */ + + { 52, 4, 8, 3 }, /* IRDA */ + { 53, 4, 8, 3 }, /* IRDA */ + { 54, 4, 8, 3 }, /* IRDA */ + { 55, 4, 8, 3 }, /* IRDA */ + + { 56, 4, 4, 3 }, /* SCIF */ + { 57, 4, 4, 3 }, /* SCIF */ + { 58, 4, 4, 3 }, /* SCIF */ + { 59, 4, 4, 3 }, /* SCIF */ +}; + +static unsigned long ipr_offsets[] = { + 0xfffffee2, /* 0: IPRA */ + 0xfffffee4, /* 1: IPRB */ + 0xa4000016, /* 2: IPRC */ + 0xa4000018, /* 3: IPRD */ + 0xa400001a, /* 4: IPRE */ +}; + +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-sh7709", + }, }; -void __init init_IRQ_ipr() +void __init init_IRQ_ipr(void) { - make_ipr_irq(sh7709_ipr_map, ARRAY_SIZE(sh7709_ipr_map)); + register_ipr_controller(&ipr_irq_desc); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 51760a7e7f1c..f40e6dac337d 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -49,7 +49,7 @@ static int __init sh7710_devices_setup(void) } __initcall(sh7710_devices_setup); -static struct ipr_data sh7710_ipr_map[] = { +static struct ipr_data ipr_irq_table[] = { /* IRQ, IPR-idx, shift, priority */ { 16, 0, 12, 2 }, /* TMU0 TUNI*/ { 17, 0, 8, 2 }, /* TMU1 TUNI */ @@ -78,26 +78,30 @@ static struct ipr_data sh7710_ipr_map[] = { }; static unsigned long ipr_offsets[] = { - 0xA414FEE2 /* 0: IPRA */ -, 0xA414FEE4 /* 1: IPRB */ -, 0xA4140016 /* 2: IPRC */ -, 0xA4140018 /* 3: IPRD */ -, 0xA414001A /* 4: IPRE */ -, 0xA4080000 /* 5: IPRF */ -, 0xA4080002 /* 6: IPRG */ -, 0xA4080004 /* 7: IPRH */ -, 0xA4080006 /* 8: IPRI */ + 0xA414FEE2, /* 0: IPRA */ + 0xA414FEE4, /* 1: IPRB */ + 0xA4140016, /* 2: IPRC */ + 0xA4140018, /* 3: IPRD */ + 0xA414001A, /* 4: IPRE */ + 0xA4080000, /* 5: IPRF */ + 0xA4080002, /* 6: IPRG */ + 0xA4080004, /* 7: IPRH */ + 0xA4080006, /* 8: IPRI */ }; -/* given the IPR index return the address of the IPR register */ -unsigned int map_ipridx_to_addr(int idx) -{ - if (idx >= ARRAY_SIZE(ipr_offsets)) - return 0; - return ipr_offsets[idx]; -} +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-sh7710", + }, +}; -void __init init_IRQ_ipr() +void __init init_IRQ_ipr(void) { - make_ipr_irq(sh7710_ipr_map, ARRAY_SIZE(sh7710_ipr_map)); + register_ipr_controller(&ipr_irq_desc); } diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 03b14cf78ddf..da153bcdfeb2 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -82,7 +82,7 @@ static int __init sh7750_devices_setup(void) } __initcall(sh7750_devices_setup); -static struct ipr_data sh7750_ipr_map[] = { +static struct ipr_data ipr_irq_table[] = { /* IRQ, IPR-idx, shift, priority */ { 16, 0, 12, 2 }, /* TMU0 TUNI*/ { 17, 0, 12, 2 }, /* TMU1 TUNI */ @@ -106,8 +106,27 @@ static struct ipr_data sh7750_ipr_map[] = { { 38, 2, 8, 7 }, /* DMAC DMAE */ }; +static unsigned long ipr_offsets[] = { + 0xffd00004UL, /* 0: IPRA */ + 0xffd00008UL, /* 1: IPRB */ + 0xffd0000cUL, /* 2: IPRC */ + 0xffd00010UL, /* 3: IPRD */ +}; + +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-sh7750", + }, +}; + #ifdef CONFIG_CPU_SUBTYPE_SH7751 -static struct ipr_data sh7751_ipr_map[] = { +static struct ipr_data ipr_irq_table_sh7751[] = { { 44, 2, 8, 7 }, /* DMAC DMTE4 */ { 45, 2, 8, 7 }, /* DMAC DMTE5 */ { 46, 2, 8, 7 }, /* DMAC DMTE6 */ @@ -118,21 +137,26 @@ static struct ipr_data sh7751_ipr_map[] = { /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */ /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */ }; -#endif -static unsigned long ipr_offsets[] = { - 0xffd00004UL, /* 0: IPRA */ - 0xffd00008UL, /* 1: IPRB */ - 0xffd0000cUL, /* 2: IPRC */ - 0xffd00010UL, /* 3: IPRD */ +static struct ipr_desc ipr_irq_desc_sh7751 = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table_sh7751, + .nr_irqs = ARRAY_SIZE(ipr_irq_table_sh7751), + + .chip = { + .name = "IPR-sh7751", + }, }; +#endif -/* given the IPR index return the address of the IPR register */ -unsigned int map_ipridx_to_addr(int idx) +void __init init_IRQ_ipr(void) { - if (idx >= ARRAY_SIZE(ipr_offsets)) - return 0; - return ipr_offsets[idx]; + register_ipr_controller(&ipr_irq_desc); +#ifdef CONFIG_CPU_SUBTYPE_SH7751 + register_ipr_controller(&ipr_irq_desc_sh7751); +#endif } #define INTC_ICR 0xffd00000UL @@ -143,11 +167,3 @@ void ipr_irq_enable_irlm(void) { ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); } - -void __init init_IRQ_ipr() -{ - make_ipr_irq(sh7750_ipr_map, ARRAY_SIZE(sh7750_ipr_map)); -#ifdef CONFIG_CPU_SUBTYPE_SH7751 - make_ipr_irq(sh7751_ipr_map, ARRAY_SIZE(sh7751_ipr_map)); -#endif -} diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 6d3c91897774..3df169755673 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -109,7 +109,12 @@ static struct intc2_desc intc2_irq_desc __read_mostly = { }, }; -static struct ipr_data sh7760_ipr_map[] = { +void __init init_IRQ_intc2(void) +{ + register_intc2_controller(&intc2_irq_desc); +} + +static struct ipr_data ipr_irq_table[] = { /* IRQ, IPR-idx, shift, priority */ { 16, 0, 12, 2 }, /* TMU0 TUNI*/ { 17, 0, 8, 2 }, /* TMU1 TUNI */ @@ -146,20 +151,19 @@ static unsigned long ipr_offsets[] = { 0xffd00010UL, /* 3: IPRD */ }; -/* given the IPR index return the address of the IPR register */ -unsigned int map_ipridx_to_addr(int idx) -{ - if (idx >= ARRAY_SIZE(ipr_offsets)) - return 0; - return ipr_offsets[idx]; -} +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), -void __init init_IRQ_intc2(void) -{ - register_intc2_controller(&intc2_irq_desc); -} + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-sh7760", + }, +}; -void __init init_IRQ_ipr(void) +void __init init_IRQ_ipr(void) { - make_ipr_irq(sh7760_ipr_map, ARRAY_SIZE(sh7760_ipr_map)); + register_ipr_controller(&ipr_irq_desc); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index fa07fab4797f..a3e159ef6dfe 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -44,7 +44,7 @@ static int __init sh7722_devices_setup(void) } __initcall(sh7722_devices_setup); -static struct ipr_data sh7722_ipr_map[] = { +static struct ipr_data ipr_irq_table[] = { /* IRQ, IPR-idx, shift, prio */ { 16, 0, 12, 2 }, /* TMU0 */ { 17, 0, 8, 2 }, /* TMU1 */ @@ -69,16 +69,21 @@ static unsigned long ipr_offsets[] = { 0xa408002c, /* 11: IPRL */ }; -unsigned int map_ipridx_to_addr(int idx) -{ - if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) - return 0; - return ipr_offsets[idx]; -} +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-sh7722", + }, +}; void __init init_IRQ_ipr(void) { - make_ipr_irq(sh7722_ipr_map, ARRAY_SIZE(sh7722_ipr_map)); + register_ipr_controller(&ipr_irq_desc); } void __init plat_mem_setup(void) diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index f9dfdc04aef5..4ca3f765bacc 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -24,4 +24,27 @@ struct intc2_desc { void register_intc2_controller(struct intc2_desc *); void init_IRQ_intc2(void); +struct ipr_data { + unsigned char irq; + unsigned char ipr_idx; /* Index for the IPR registered */ + unsigned char shift; /* Number of bits to shift the data */ + unsigned char priority; /* The priority */ +}; + +struct ipr_desc { + unsigned long *ipr_offsets; + unsigned int nr_offsets; + struct ipr_data *ipr_data; + unsigned int nr_irqs; + struct irq_chip chip; +}; + +void register_ipr_controller(struct ipr_desc *); +void init_IRQ_ipr(void); + +/* + * Enable individual interrupt mode for external IPR IRQs. + */ +void ipr_irq_enable_irlm(void); + #endif /* __ASM_SH_HW_IRQ_H */ diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h index c247b733a7d6..c61d902b8bff 100644 --- a/include/asm-sh/irq.h +++ b/include/asm-sh/irq.h @@ -31,37 +31,7 @@ extern unsigned short *irq_mask_register; * PINT IRQs */ void init_IRQ_pint(void); - -/* - * The shift value is now the number of bits to shift, not the number of - * bits/4. This is to make it easier to read the value directly from the - * datasheets. The IPR address, addr, will be set from ipr_idx via the - * map_ipridx_to_addr function. - */ -struct ipr_data { - unsigned int irq; - int ipr_idx; /* Index for the IPR registered */ - int shift; /* Number of bits to shift the data */ - int priority; /* The priority */ - unsigned int addr; /* Address of Interrupt Priority Register */ -}; - -/* - * Given an IPR IDX, map the value to an IPR register address. - */ -unsigned int map_ipridx_to_addr(int idx); - -/* - * Enable individual interrupt mode for external IPR IRQs. - */ -void ipr_irq_enable_irlm(void); - -/* - * Function for "on chip support modules". - */ -void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs); void make_imask_irq(unsigned int irq); -void init_IRQ_ipr(void); static inline int generic_irq_demux(int irq) { diff --git a/include/asm-sh/sh03/io.h b/include/asm-sh/sh03/io.h index df3b187ef883..4ff1eb900301 100644 --- a/include/asm-sh/sh03/io.h +++ b/include/asm-sh/sh03/io.h @@ -14,22 +14,18 @@ #define INTC_IPRD 0xffd00010UL #define IRL0_IRQ 2 -#define IRL0_IPR_ADDR INTC_IPRD #define IRL0_IPR_POS 3 #define IRL0_PRIORITY 13 #define IRL1_IRQ 5 -#define IRL1_IPR_ADDR INTC_IPRD #define IRL1_IPR_POS 2 #define IRL1_PRIORITY 10 #define IRL2_IRQ 8 -#define IRL2_IPR_ADDR INTC_IPRD #define IRL2_IPR_POS 1 #define IRL2_PRIORITY 7 #define IRL3_IRQ 11 -#define IRL3_IPR_ADDR INTC_IPRD #define IRL3_IPR_POS 0 #define IRL3_PRIORITY 4 diff --git a/include/asm-sh/snapgear.h b/include/asm-sh/snapgear.h index 2d712e72c9e5..3554e3a74e99 100644 --- a/include/asm-sh/snapgear.h +++ b/include/asm-sh/snapgear.h @@ -20,22 +20,18 @@ */ #define IRL0_IRQ 2 -#define IRL0_IPR_ADDR INTC_IPRD #define IRL0_IPR_POS 3 #define IRL0_PRIORITY 13 #define IRL1_IRQ 5 -#define IRL1_IPR_ADDR INTC_IPRD #define IRL1_IPR_POS 2 #define IRL1_PRIORITY 10 #define IRL2_IRQ 8 -#define IRL2_IPR_ADDR INTC_IPRD #define IRL2_IPR_POS 1 #define IRL2_PRIORITY 7 #define IRL3_IRQ 11 -#define IRL3_IPR_ADDR INTC_IPRD #define IRL3_IPR_POS 0 #define IRL3_PRIORITY 4 #endif -- cgit v1.2.3-59-g8ed1b From fc1d4c9c3761ca8db52b647c6a4ba50771900a12 Mon Sep 17 00:00:00 2001 From: Kaz Kojima Date: Mon, 18 Jun 2007 13:58:32 +0900 Subject: sh: Fix up futex implementation. SH is able to support a complete futex implementation on UP by way of gUSA. However, IRQ toggling must be done for the old CPUs that don't have movli.l/movco.l (LL/SC) instructions. Provide a default implementation that does this, so it's possible to optimize for newer CPUs. Follows the same scheme as the current asm-sh/atomic-*.h headers. Signed-off-by: Kaz Kojima Signed-off-by: Paul Mundt --- include/asm-sh/futex-irq.h | 111 +++++++++++++++++++++++++++++++++++++++++++++ include/asm-sh/futex.h | 79 ++++++++++++++++++++++++++++++-- 2 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 include/asm-sh/futex-irq.h (limited to 'include') diff --git a/include/asm-sh/futex-irq.h b/include/asm-sh/futex-irq.h new file mode 100644 index 000000000000..a9f16a7f9aea --- /dev/null +++ b/include/asm-sh/futex-irq.h @@ -0,0 +1,111 @@ +#ifndef __ASM_SH_FUTEX_IRQ_H +#define __ASM_SH_FUTEX_IRQ_H + +#include + +static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr, + int *oldval) +{ + unsigned long flags; + int ret; + + local_irq_save(flags); + + ret = get_user(*oldval, uaddr); + if (!ret) + ret = put_user(oparg, uaddr); + + local_irq_restore(flags); + + return ret; +} + +static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr, + int *oldval) +{ + unsigned long flags; + int ret; + + local_irq_save(flags); + + ret = get_user(*oldval, uaddr); + if (!ret) + ret = put_user(*oldval + oparg, uaddr); + + local_irq_restore(flags); + + return ret; +} + +static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr, + int *oldval) +{ + unsigned long flags; + int ret; + + local_irq_save(flags); + + ret = get_user(*oldval, uaddr); + if (!ret) + ret = put_user(*oldval | oparg, uaddr); + + local_irq_restore(flags); + + return ret; +} + +static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr, + int *oldval) +{ + unsigned long flags; + int ret; + + local_irq_save(flags); + + ret = get_user(*oldval, uaddr); + if (!ret) + ret = put_user(*oldval & oparg, uaddr); + + local_irq_restore(flags); + + return ret; +} + +static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr, + int *oldval) +{ + unsigned long flags; + int ret; + + local_irq_save(flags); + + ret = get_user(*oldval, uaddr); + if (!ret) + ret = put_user(*oldval ^ oparg, uaddr); + + local_irq_restore(flags); + + return ret; +} + +static inline int atomic_futex_op_cmpxchg_inatomic(int __user *uaddr, + int oldval, int newval) +{ + unsigned long flags; + int ret, prev = 0; + + local_irq_save(flags); + + ret = get_user(prev, uaddr); + if (!ret && oldval == prev) + ret = put_user(newval, uaddr); + + local_irq_restore(flags); + + if (ret) + return ret; + + return prev; +} + +#endif /* __ASM_SH_FUTEX_IRQ_H */ diff --git a/include/asm-sh/futex.h b/include/asm-sh/futex.h index 6a332a9f099c..74ed3681d33c 100644 --- a/include/asm-sh/futex.h +++ b/include/asm-sh/futex.h @@ -1,6 +1,77 @@ -#ifndef _ASM_FUTEX_H -#define _ASM_FUTEX_H +#ifndef __ASM_SH_FUTEX_H +#define __ASM_SH_FUTEX_H -#include +#ifdef __KERNEL__ -#endif +#include +#include +#include + +/* XXX: UP variants, fix for SH-4A and SMP.. */ +#include + +static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) +{ + int op = (encoded_op >> 28) & 7; + int cmp = (encoded_op >> 24) & 15; + int oparg = (encoded_op << 8) >> 20; + int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret; + + if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) + oparg = 1 << oparg; + + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) + return -EFAULT; + + pagefault_disable(); + + switch (op) { + case FUTEX_OP_SET: + ret = atomic_futex_op_xchg_set(oparg, uaddr, &oldval); + break; + case FUTEX_OP_ADD: + ret = atomic_futex_op_xchg_add(oparg, uaddr, &oldval); + break; + case FUTEX_OP_OR: + ret = atomic_futex_op_xchg_or(oparg, uaddr, &oldval); + break; + case FUTEX_OP_ANDN: + ret = atomic_futex_op_xchg_and(~oparg, uaddr, &oldval); + break; + case FUTEX_OP_XOR: + ret = atomic_futex_op_xchg_xor(oparg, uaddr, &oldval); + break; + default: + ret = -ENOSYS; + break; + } + + pagefault_enable(); + + if (!ret) { + switch (cmp) { + case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; + case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; + case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; + case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; + case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; + case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; + default: ret = -ENOSYS; + } + } + + return ret; +} + +static inline int +futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) +{ + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) + return -EFAULT; + + return atomic_futex_op_cmpxchg_inatomic(uaddr, oldval, newval); +} + +#endif /* __KERNEL__ */ +#endif /* __ASM_SH_FUTEX_H */ -- cgit v1.2.3-59-g8ed1b From 027e56e68543780870fda74360ca45e392c50e1c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jun 2007 18:23:49 +0900 Subject: sh: Hook up hard_smp_processor_id() for INTC2 block. We need to know the CPU ID in order to calculate the mask and ack registers effectively. Stub this in for UP. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/irq/intc2.c | 9 +++++++-- include/asm-sh/smp.h | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c index dae02d3152e7..cc5221390e09 100644 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ b/arch/sh/kernel/cpu/irq/intc2.c @@ -13,6 +13,7 @@ #include #include #include +#include static inline struct intc2_desc *get_intc2_desc(unsigned int irq) { @@ -24,14 +25,18 @@ static void disable_intc2_irq(unsigned int irq) { struct intc2_data *p = get_irq_chip_data(irq); struct intc2_desc *d = get_intc2_desc(irq); - ctrl_outl(1 << p->msk_shift, d->msk_base + p->msk_offset); + + ctrl_outl(1 << p->msk_shift, d->msk_base + p->msk_offset + + (hard_smp_processor_id() * 4)); } static void enable_intc2_irq(unsigned int irq) { struct intc2_data *p = get_irq_chip_data(irq); struct intc2_desc *d = get_intc2_desc(irq); - ctrl_outl(1 << p->msk_shift, d->mskclr_base + p->msk_offset); + + ctrl_outl(1 << p->msk_shift, d->mskclr_base + p->msk_offset + + (hard_smp_processor_id() * 4)); } /* diff --git a/include/asm-sh/smp.h b/include/asm-sh/smp.h index caa7b93f1bce..b99ca786c0c1 100644 --- a/include/asm-sh/smp.h +++ b/include/asm-sh/smp.h @@ -39,4 +39,6 @@ extern struct smp_fn_call_struct smp_fn_call; #endif /* CONFIG_SMP */ +#define hard_smp_processor_id() (0) + #endif /* __ASM_SH_SMP_H */ -- cgit v1.2.3-59-g8ed1b From 2b1bd1ac5d4bffe3fd542bfe1784a583bd7df4fa Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jun 2007 18:27:10 +0900 Subject: sh: Preliminary support for the SH-X3 CPU. This adds basic support for UP SH-X3. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 + arch/sh/configs/shx3_defconfig | 756 +++++++++++++++++++++++++++++++++++ arch/sh/kernel/cpu/sh3/entry.S | 19 + arch/sh/kernel/cpu/sh4/probe.c | 8 + arch/sh/kernel/cpu/sh4a/Makefile | 2 + arch/sh/kernel/cpu/sh4a/clock-shx3.c | 135 +++++++ arch/sh/kernel/cpu/sh4a/setup-shx3.c | 85 ++++ arch/sh/kernel/setup.c | 2 +- arch/sh/kernel/timers/timer-tmu.c | 7 +- arch/sh/mm/Kconfig | 9 + drivers/serial/sh-sci.c | 4 +- drivers/serial/sh-sci.h | 25 +- include/asm-sh/bugs.h | 2 +- include/asm-sh/cpu-sh4/freq.h | 2 + include/asm-sh/cpu-sh4/timer.h | 57 +-- include/asm-sh/processor.h | 2 +- 16 files changed, 1083 insertions(+), 33 deletions(-) create mode 100644 arch/sh/configs/shx3_defconfig create mode 100644 arch/sh/kernel/cpu/sh4a/clock-shx3.c create mode 100644 arch/sh/kernel/cpu/sh4a/setup-shx3.c (limited to 'include') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index b16407c9f2c4..d82caffd1da6 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -598,6 +598,7 @@ config NR_CPUS int "Maximum number of CPUs (2-32)" range 2 32 depends on SMP + default "4" if CPU_SHX3 default "2" help This allows you to specify the maximum number of CPUs which this diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig new file mode 100644 index 000000000000..219bad558b10 --- /dev/null +++ b/arch/sh/configs/shx3_defconfig @@ -0,0 +1,756 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.22-rc4 +# Wed Jun 20 14:09:27 2007 +# +CONFIG_SUPERH=y +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_IRQ_PROBE=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_UTS_NS is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" + +# +# System type +# +CONFIG_CPU_SH4=y +CONFIG_CPU_SH4A=y +CONFIG_CPU_SHX3=y +# CONFIG_CPU_SUBTYPE_SH7619 is not set +# CONFIG_CPU_SUBTYPE_SH7206 is not set +# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set +# CONFIG_CPU_SUBTYPE_SH7712 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_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 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_SHX3=y +# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SH7343 is not set +# CONFIG_CPU_SUBTYPE_SH7722 is not set + +# +# Memory management options +# +CONFIG_QUICKLIST=y +CONFIG_MMU=y +CONFIG_PAGE_OFFSET=0x80000000 +CONFIG_MEMORY_START=0x0c000000 +CONFIG_MEMORY_SIZE=0x04000000 +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_64KB is not set +CONFIG_HUGETLB_PAGE_SIZE_64K=y +# CONFIG_HUGETLB_PAGE_SIZE_256K is not set +# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_STATIC=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=2 + +# +# Cache configuration +# +# CONFIG_SH_DIRECT_MAPPED is not set +# CONFIG_SH_WRITETHROUGH is not set + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set +# CONFIG_SH_FPU is not set +# CONFIG_SH_FPU_EMU is not set +CONFIG_SH_DSP=y +CONFIG_SH_STORE_QUEUES=y +CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_INTC2_IRQ=y +CONFIG_CPU_HAS_SR_RB=y + +# +# Board support +# + +# +# Timer and clock configuration +# +CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=16 +CONFIG_SH_PCLK_FREQ=50000000 +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=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=y +# CONFIG_PUSH_SWITCH is not set + +# +# Kernel features +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +# CONFIG_UBC_WAKEUP is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttySC0,115200 ip=192.168.1.2:::255.255.255.0 root=/dev/nfs nfsroot=192.168.1.1:/exports/devel/rfs/mobiler noaliencache earlyprintk=bios ignore_loglevel" + +# +# Bus options +# +# CONFIG_ARCH_SUPPORTS_MSI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Networking +# +# CONFIG_NET is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set + +# +# Misc devices +# +# CONFIG_BLINK is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_DEBUG is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_PATA_PLATFORM=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# ISDN subsystem +# + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY 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=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=2 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set +# CONFIG_HWMON is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# HID Devices +# +# CONFIG_HID is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_SH=y + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +CONFIG_PROFILING=y +# CONFIG_OPROFILE is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_PRINTK_TIME=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +CONFIG_DEBUG_SLAB=y +CONFIG_DEBUG_SLAB_LEAK=y +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_LOCK_ALLOC=y +# CONFIG_PROVE_LOCKING is not set +CONFIG_LOCKDEP=y +CONFIG_DEBUG_LOCKDEP=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_VM=y +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_SH_STANDARD_BIOS=y +# CONFIG_EARLY_SCIF_CONSOLE is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_DEBUG_BOOTMEM is not set +CONFIG_DEBUG_STACKOVERFLOW=y +CONFIG_DEBUG_STACK_USAGE=y +# CONFIG_4KSTACKS is not set +# CONFIG_SH_KGDB is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index b0b59d4a33ca..d8e122971c3e 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S @@ -340,8 +340,27 @@ ENTRY(vbr_base) general_exception: mov.l 1f, k2 mov.l 2f, k3 +#ifdef CONFIG_CPU_SUBTYPE_SHX3 + mov.l @k2, k2 + + ! Is EXPEVT larger than 0x800? + mov #0x8, k0 + shll8 k0 + cmp/hs k0, k2 + bf 0f + + ! then add 0x580 (k2 is 0xd80 or 0xda0) + mov #0x58, k0 + shll2 k0 + shll2 k0 + add k0, k2 +0: + bra handle_exception + nop +#else bra handle_exception mov.l @k2, k2 +#endif .align 2 1: .long EXPEVT 2: .long ret_from_exception diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index fab2eb07196b..66c3f75647b2 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -141,6 +141,14 @@ int __init detect_cpu_and_cache_system(void) current_cpu_data.flags |= CPU_HAS_LLSC; } break; + case 0x4000: /* 1st cut */ + case 0x4001: /* 2nd cut */ + current_cpu_data.type = CPU_SHX3; + current_cpu_data.icache.ways = 4; + current_cpu_data.dcache.ways = 4; + current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | + CPU_HAS_LLSC; + break; case 0x8000: current_cpu_data.type = CPU_ST40RA; current_cpu_data.flags |= CPU_HAS_FPU; diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index ab7422f8f820..400623286487 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o +obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o # Primary on-chip clocks (common) clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o @@ -17,5 +18,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o +clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o obj-y += $(clock-y) diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c new file mode 100644 index 000000000000..c630b29e06a8 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c @@ -0,0 +1,135 @@ +/* + * arch/sh/kernel/cpu/sh4/clock-shx3.c + * + * SH-X3 support for the clock framework + * + * Copyright (C) 2006-2007 Renesas Technology Corp. + * Copyright (C) 2006-2007 Renesas Solutions Corp. + * Copyright (C) 2006-2007 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +static int ifc_divisors[] = { 1, 2, 4 ,6 }; +static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18, 24, 32, 36, 48 }; +static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18, 24, 32, 36, 48 }; +static int cfc_divisors[] = { 1, 1, 4, 6 }; + +#define IFC_POS 28 +#define IFC_MSK 0x0003 +#define BFC_MSK 0x000f +#define PFC_MSK 0x000f +#define CFC_MSK 0x0003 +#define BFC_POS 16 +#define PFC_POS 0 +#define CFC_POS 20 + +static void master_clk_init(struct clk *clk) +{ + clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK]; +} + +static struct clk_ops shx3_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK); + clk->rate = clk->parent->rate / pfc_divisors[idx]; +} + +static struct clk_ops shx3_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void bus_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> BFC_POS) & BFC_MSK); + clk->rate = clk->parent->rate / bfc_divisors[idx]; +} + +static struct clk_ops shx3_bus_clk_ops = { + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> IFC_POS) & IFC_MSK); + clk->rate = clk->parent->rate / ifc_divisors[idx]; +} + +static struct clk_ops shx3_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *shx3_clk_ops[] = { + &shx3_master_clk_ops, + &shx3_module_clk_ops, + &shx3_bus_clk_ops, + &shx3_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(shx3_clk_ops)) + *ops = shx3_clk_ops[idx]; +} + +static void shyway_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> CFC_POS) & CFC_MSK); + clk->rate = clk->parent->rate / cfc_divisors[idx]; +} + +static struct clk_ops shx3_shyway_clk_ops = { + .recalc = shyway_clk_recalc, +}; + +static struct clk shx3_shyway_clk = { + .name = "shyway_clk", + .flags = CLK_ALWAYS_ENABLED, + .ops = &shx3_shyway_clk_ops, +}; + +/* + * Additional SHx3-specific on-chip clocks that aren't already part of the + * clock framework + */ +static struct clk *shx3_onchip_clocks[] = { + &shx3_shyway_clk, +}; + +static int __init shx3_clk_init(void) +{ + struct clk *clk = clk_get(NULL, "master_clk"); + int i; + + for (i = 0; i < ARRAY_SIZE(shx3_onchip_clocks); i++) { + struct clk *clkp = shx3_onchip_clocks[i]; + + clkp->parent = clk; + clk_register(clkp); + clk_enable(clkp); + } + + /* + * Now that we have the rest of the clocks registered, we need to + * force the parent clock to propagate so that these clocks will + * automatically figure out their rate. We cheat by handing the + * parent clock its current rate and forcing child propagation. + */ + clk_set_rate(clk, clk_get_rate(clk)); + + clk_put(clk); + + return 0; +} +arch_initcall(shx3_clk_init); diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c new file mode 100644 index 000000000000..70683ea12b83 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -0,0 +1,85 @@ +/* + * SH-X3 Setup + * + * Copyright (C) 2007 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xffc30000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 40, 41, 43, 42 }, + }, { + .mapbase = 0xffc40000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 44, 45, 47, 46 }, + }, { + .mapbase = 0xffc50000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 48, 49, 51, 50 }, + }, { + .mapbase = 0xffc60000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 52, 53, 55, 54 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *shx3_devices[] __initdata = { + &sci_device, +}; + +static int __init shx3_devices_setup(void) +{ + return platform_add_devices(shx3_devices, + ARRAY_SIZE(shx3_devices)); +} +__initcall(shx3_devices_setup); + +static struct intc2_data intc2_irq_table[] = { + { 16, 0, 0, 0, 1, 2 }, /* TMU0 */ + { 40, 4, 0, 0x20, 0, 3 }, /* SCIF0 ERI */ + { 41, 4, 0, 0x20, 1, 3 }, /* SCIF0 RXI */ + { 42, 4, 0, 0x20, 2, 3 }, /* SCIF0 BRI */ + { 43, 4, 0, 0x20, 3, 3 }, /* SCIF0 TXI */ +}; + +static struct intc2_desc intc2_irq_desc __read_mostly = { + .prio_base = 0xfe410000, + .msk_base = 0xfe410820, + .mskclr_base = 0xfe410850, + + .intc2_data = intc2_irq_table, + .nr_irqs = ARRAY_SIZE(intc2_irq_table), + + .chip = { + .name = "INTC2-SHX3", + }, +}; + +void __init init_IRQ_intc2(void) +{ + register_intc2_controller(&intc2_irq_desc); +} diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 765f83c1bca4..de8e6e2f2c87 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -285,7 +285,7 @@ static const char *cpu_name[] = { [CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780", [CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343", [CPU_SH7785] = "SH7785", [CPU_SH7722] = "SH7722", - [CPU_SH_NONE] = "Unknown" + [CPU_SHX3] = "SH-X3", [CPU_SH_NONE] = "Unknown" }; const char *get_cpu_subtype(struct sh_cpuinfo *c) diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index 2d997e2a5b6c..097ebd49f1bf 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c @@ -30,7 +30,7 @@ static int tmu_timer_start(void) { - ctrl_outb(ctrl_inb(TMU_TSTR) | 0x3, TMU_TSTR); + ctrl_outb(ctrl_inb(TMU_012_TSTR) | 0x3, TMU_012_TSTR); return 0; } @@ -52,7 +52,7 @@ static void tmu0_timer_set_interval(unsigned long interval, unsigned int reload) static int tmu_timer_stop(void) { - ctrl_outb(ctrl_inb(TMU_TSTR) & ~0x3, TMU_TSTR); + ctrl_outb(ctrl_inb(TMU_012_TSTR) & ~0x3, TMU_012_TSTR); return 0; } @@ -174,7 +174,8 @@ static int tmu_timer_init(void) #if !defined(CONFIG_CPU_SUBTYPE_SH7300) && \ !defined(CONFIG_CPU_SUBTYPE_SH7760) && \ - !defined(CONFIG_CPU_SUBTYPE_SH7785) + !defined(CONFIG_CPU_SUBTYPE_SH7785) && \ + !defined(CONFIG_CPU_SUBTYPE_SHX3) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); #endif diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 6fc5550c4ba1..ea1d2716fdb3 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -36,6 +36,9 @@ config CPU_SUBTYPE_ST40 config CPU_SHX2 bool +config CPU_SHX3 + bool + choice prompt "Processor sub-type selection" @@ -193,6 +196,12 @@ config CPU_SUBTYPE_SH7785 select CPU_SHX2 select CPU_HAS_INTC2_IRQ +config CPU_SUBTYPE_SHX3 + bool "Support SH-X3 processor" + select CPU_SH4A + select CPU_SHX3 + select CPU_HAS_INTC2_IRQ + # SH4AL-DSP Processor Support config CPU_SUBTYPE_SH73180 diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 1f89496d530e..672cd1042539 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -367,7 +367,9 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) } else { #ifdef CONFIG_CPU_SUBTYPE_SH7343 /* Nothing */ -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785) +#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || \ + defined(CONFIG_CPU_SUBTYPE_SH7785) || \ + defined(CONFIG_CPU_SUBTYPE_SHX3) ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */ #else ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */ diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index da643b31715b..247fb66bf0f4 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -78,7 +78,7 @@ # define SCPDR 0xA4050136 /* 16 bit SCIF */ # define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ # define SCIF_ONLY -#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) +#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) # define SCSPTR0 0xA4400000 /* 16 bit SCIF */ # define SCI_NPORTS 2 # define SCIF_ORER 0x0001 /* overrun error bit */ @@ -173,6 +173,14 @@ # define SCIF_ORER 0x0001 /* overrun error bit */ # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCIF_ONLY +#elif defined(CONFIG_CPU_SUBTYPE_SHX3) +# define SCSPTR0 0xffc30020 /* 16 bit SCIF */ +# define SCSPTR1 0xffc40020 /* 16 bit SCIF */ +# define SCSPTR2 0xffc50020 /* 16 bit SCIF */ +# define SCSPTR3 0xffc60020 /* 16 bit SCIF */ +# define SCIF_ORER 0x0001 /* Overrun error bit */ +# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ +# define SCIF_ONLY #else # error CPU subtype not defined #endif @@ -189,7 +197,8 @@ defined(CONFIG_CPU_SUBTYPE_SH7751) || \ defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ defined(CONFIG_CPU_SUBTYPE_SH7780) || \ - defined(CONFIG_CPU_SUBTYPE_SH7785) + defined(CONFIG_CPU_SUBTYPE_SH7785) || \ + defined(CONFIG_CPU_SUBTYPE_SHX3) #define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */ #else #define SCI_CTRL_FLAGS_REIE 0 @@ -666,6 +675,18 @@ static inline int sci_rxd_in(struct uart_port *port) return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } +#elif defined(CONFIG_CPU_SUBTYPE_SHX3) +static inline int sci_rxd_in(struct uart_port *port) +{ + if (port->mapbase == 0xffc30000) + return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xffc40000) + return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xffc50000) + return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xffc60000) + return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ +} #endif /* diff --git a/include/asm-sh/bugs.h b/include/asm-sh/bugs.h index efc8fd3e1fad..aeee8da9c54f 100644 --- a/include/asm-sh/bugs.h +++ b/include/asm-sh/bugs.h @@ -35,7 +35,7 @@ static void __init check_bugs(void) case CPU_SH7750 ... CPU_SH4_501: *p++ = '4'; break; - case CPU_SH7770 ... CPU_SH7785: + case CPU_SH7770 ... CPU_SHX3: *p++ = '4'; *p++ = 'a'; break; diff --git a/include/asm-sh/cpu-sh4/freq.h b/include/asm-sh/cpu-sh4/freq.h index 39f41fcd509d..026025b51cea 100644 --- a/include/asm-sh/cpu-sh4/freq.h +++ b/include/asm-sh/cpu-sh4/freq.h @@ -22,6 +22,8 @@ #define FRQCR0 0xffc80000 #define FRQCR1 0xffc80004 #define FRQMR1 0xffc80014 +#elif defined(CONFIG_CPU_SUBTYPE_SHX3) +#define FRQCR 0xffc00014 #else #define FRQCR 0xffc00000 #define FRQCR_PSTBY 0x0200 diff --git a/include/asm-sh/cpu-sh4/timer.h b/include/asm-sh/cpu-sh4/timer.h index 8a4af126c890..d1e796b96888 100644 --- a/include/asm-sh/cpu-sh4/timer.h +++ b/include/asm-sh/cpu-sh4/timer.h @@ -1,7 +1,7 @@ /* * include/asm-sh/cpu-sh4/timer.h * - * Copyright (C) 2004 Lineo Solutions, Inc. + * Copyright (C) 2004 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 @@ -16,36 +16,45 @@ * SH7750S/SH7750R * SH7751/SH7751R * SH7760 + * SH-X3 * --------------------------------------------------------------------------- */ - -#if !defined(CONFIG_CPU_SUBTYPE_SH7760) -#define TMU_TOCR 0xffd80000 /* Byte access */ +#ifdef CONFIG_CPU_SUBTYPE_SHX3 +#define TMU_012_BASE 0xffc10000 +#define TMU_345_BASE 0xffc20000 +#else +#define TMU_012_BASE 0xffd80000 +#define TMU_345_BASE 0xfe100000 #endif -#define TMU_TSTR 0xffd80004 /* Byte access */ -#define TMU0_TCOR 0xffd80008 /* Long access */ -#define TMU0_TCNT 0xffd8000c /* Long access */ -#define TMU0_TCR 0xffd80010 /* Word access */ +#define TMU_TOCR TMU_012_BASE /* Not supported on all CPUs */ -#define TMU1_TCOR 0xffd80014 /* Long access */ -#define TMU1_TCNT 0xffd80018 /* Long access */ -#define TMU1_TCR 0xffd8001c /* Word access */ +#define TMU_012_TSTR (TMU_012_BASE + 0x04) +#define TMU_345_TSTR (TMU_345_BASE + 0x04) -#define TMU2_TCOR 0xffd80020 /* Long access */ -#define TMU2_TCNT 0xffd80024 /* Long access */ -#define TMU2_TCR 0xffd80028 /* Word access */ -#define TMU2_TCPR 0xffd8002c /* Long access */ +#define TMU0_TCOR (TMU_012_BASE + 0x08) +#define TMU0_TCNT (TMU_012_BASE + 0x0c) +#define TMU0_TCR (TMU_012_BASE + 0x10) -#if !defined(CONFIG_CPU_SUBTYPE_SH7760) -#define TMU3_TCOR 0xfe100008 /* Long access */ -#define TMU3_TCNT 0xfe10000c /* Long access */ -#define TMU3_TCR 0xfe100010 /* Word access */ +#define TMU1_TCOR (TMU_012_BASE + 0x14) +#define TMU1_TCNT (TMU_012_BASE + 0x18) +#define TMU1_TCR (TMU_012_BASE + 0x1c) -#define TMU4_TCOR 0xfe100014 /* Long access */ -#define TMU4_TCNT 0xfe100018 /* Long access */ -#define TMU4_TCR 0xfe10001c /* Word access */ -#endif +#define TMU2_TCOR (TMU_012_BASE + 0x20) +#define TMU2_TCNT (TMU_012_BASE + 0x24) +#define TMU2_TCR (TMU_012_BASE + 0x28) +#define TMU2_TCPR (TMU_012_BASE + 0x2c) -#endif /* __ASM_CPU_SH4_TIMER_H */ +#define TMU3_TCOR (TMU_345_BASE + 0x08) +#define TMU3_TCNT (TMU_345_BASE + 0x0c) +#define TMU3_TCR (TMU_345_BASE + 0x10) +#define TMU4_TCOR (TMU_345_BASE + 0x14) +#define TMU4_TCNT (TMU_345_BASE + 0x18) +#define TMU4_TCR (TMU_345_BASE + 0x1c) + +#define TMU5_TCOR (TMU_345_BASE + 0x20) +#define TMU5_TCNT (TMU_345_BASE + 0x24) +#define TMU5_TCR (TMU_345_BASE + 0x28) + +#endif /* __ASM_CPU_SH4_TIMER_H */ diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index 1a20db096196..2252e75daa26 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -52,7 +52,7 @@ enum cpu_type { CPU_SH7760, CPU_ST40RA, CPU_ST40GX1, CPU_SH4_202, CPU_SH4_501, /* SH-4A types */ - CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, + CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SHX3, /* SH4AL-DSP types */ CPU_SH73180, CPU_SH7343, CPU_SH7722, -- cgit v1.2.3-59-g8ed1b From 75f016a7ce75220d898608791870ab7da549a430 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 6 Jul 2007 10:26:03 +0900 Subject: sh: Fix timer-tmu build for SH-3. With the TMU register definitions being renamed on SH-4, SH-3 ended up breaking. Update the TSTR define to match the SH-4 convention. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt --- include/asm-sh/cpu-sh3/timer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-sh/cpu-sh3/timer.h b/include/asm-sh/cpu-sh3/timer.h index b2394cf76f49..4928b08f9d19 100644 --- a/include/asm-sh/cpu-sh3/timer.h +++ b/include/asm-sh/cpu-sh3/timer.h @@ -29,7 +29,7 @@ #endif #if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7710) -#define TMU_TSTR 0xa412fe92 /* Byte access */ +#define TMU_012_TSTR 0xa412fe92 /* Byte access */ #define TMU0_TCOR 0xa412fe94 /* Long access */ #define TMU0_TCNT 0xa412fe98 /* Long access */ @@ -44,7 +44,7 @@ #define TMU2_TCR 0xa412feb4 /* Word access */ #else -#define TMU_TSTR 0xfffffe92 /* Byte access */ +#define TMU_012_TSTR 0xfffffe92 /* Byte access */ #define TMU0_TCOR 0xfffffe94 /* Long access */ #define TMU0_TCNT 0xfffffe98 /* Long access */ -- cgit v1.2.3-59-g8ed1b From 1b898040e214d1f5acd3baf14f07ef5f610d5c8a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 7 Jul 2007 07:28:11 +0900 Subject: sh: Add parport stub for SuperIO ports. Some boards have SuperIOs with PC-style parports, toss in the stub so these can be supported. Signed-off-by: Paul Mundt --- include/asm-sh/parport.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 include/asm-sh/parport.h (limited to 'include') diff --git a/include/asm-sh/parport.h b/include/asm-sh/parport.h new file mode 100644 index 000000000000..f67ba60a2acd --- /dev/null +++ b/include/asm-sh/parport.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 1999, 2000 Tim Waugh + * + * This file should only be included by drivers/parport/parport_pc.c. + */ +#ifndef __ASM_SH_PARPORT_H +#define __ASM_SH_PARPORT_H + +static int __devinit parport_pc_find_isa_ports(int autoirq, int autodma); + +static int __devinit parport_pc_find_nonpci_ports(int autoirq, int autodma) +{ + return parport_pc_find_isa_ports(autoirq, autodma); +} + +#endif /* __ASM_SH_PARPORT_H */ -- cgit v1.2.3-59-g8ed1b From be15d65d97f924e11ad7b59b1dc23b9db8d02209 Mon Sep 17 00:00:00 2001 From: Kristoffer Ericson Date: Thu, 12 Jul 2007 10:44:41 +0900 Subject: sh: hd64461.h cleanup and added comments. Now that we dont have PIO mapping anymore we need to make sure we got the correct value in our headers. Some well needed comments have also been added. Signed-off-by: Kristoffer Ericson Signed-off-by: Paul Mundt --- include/asm-sh/hd64461.h | 397 ++++++++++++++++++++++++++--------------------- 1 file changed, 219 insertions(+), 178 deletions(-) (limited to 'include') diff --git a/include/asm-sh/hd64461.h b/include/asm-sh/hd64461.h index c9050b2b5510..4dd8592ca014 100644 --- a/include/asm-sh/hd64461.h +++ b/include/asm-sh/hd64461.h @@ -1,200 +1,241 @@ #ifndef __ASM_SH_HD64461 #define __ASM_SH_HD64461 /* - * $Id: hd64461.h,v 1.5 2004/03/16 00:07:51 lethal Exp $ + * Copyright (C) 2007 Kristoffer Ericson + * Copyright (C) 2004 Paul Mundt * Copyright (C) 2000 YAEGASHI Takeshi - * Hitachi HD64461 companion chip support + * + * Hitachi HD64461 companion chip support + * (please note manual reference 0x10000000 = 0xb0000000) */ /* Constants for PCMCIA mappings */ -#define HD64461_PCC_WINDOW 0x01000000 - -#define HD64461_PCC0_BASE 0xb8000000 /* area 6 */ -#define HD64461_PCC0_ATTR (HD64461_PCC0_BASE) -#define HD64461_PCC0_COMM (HD64461_PCC0_BASE+HD64461_PCC_WINDOW) -#define HD64461_PCC0_IO (HD64461_PCC0_BASE+2*HD64461_PCC_WINDOW) - -#define HD64461_PCC1_BASE 0xb4000000 /* area 5 */ -#define HD64461_PCC1_ATTR (HD64461_PCC1_BASE) -#define HD64461_PCC1_COMM (HD64461_PCC1_BASE+HD64461_PCC_WINDOW) - -#define HD64461_STBCR 0x10000 -#define HD64461_STBCR_CKIO_STBY 0x2000 -#define HD64461_STBCR_SAFECKE_IST 0x1000 -#define HD64461_STBCR_SLCKE_IST 0x0800 -#define HD64461_STBCR_SAFECKE_OST 0x0400 -#define HD64461_STBCR_SLCKE_OST 0x0200 -#define HD64461_STBCR_SMIAST 0x0100 -#define HD64461_STBCR_SLCDST 0x0080 -#define HD64461_STBCR_SPC0ST 0x0040 -#define HD64461_STBCR_SPC1ST 0x0020 -#define HD64461_STBCR_SAFEST 0x0010 -#define HD64461_STBCR_STM0ST 0x0008 -#define HD64461_STBCR_STM1ST 0x0004 -#define HD64461_STBCR_SIRST 0x0002 -#define HD64461_STBCR_SURTST 0x0001 - -#define HD64461_SYSCR 0x10002 -#define HD64461_SCPUCR 0x10004 - -#define HD64461_LCDCBAR 0x11000 -#define HD64461_LCDCLOR 0x11002 -#define HD64461_LCDCCR 0x11004 -#define HD64461_LCDCCR_STBACK 0x0400 -#define HD64461_LCDCCR_STREQ 0x0100 -#define HD64461_LCDCCR_MOFF 0x0080 -#define HD64461_LCDCCR_REFSEL 0x0040 -#define HD64461_LCDCCR_EPON 0x0020 -#define HD64461_LCDCCR_SPON 0x0010 - -#define HD64461_LDR1 0x11010 -#define HD64461_LDR1_DON 0x01 -#define HD64461_LDR1_DINV 0x80 - -#define HD64461_LDR2 0x11012 -#define HD64461_LDHNCR 0x11014 -#define HD64461_LDHNSR 0x11016 -#define HD64461_LDVNTR 0x11018 -#define HD64461_LDVNDR 0x1101a -#define HD64461_LDVSPR 0x1101c -#define HD64461_LDR3 0x1101e - -#define HD64461_CPTWAR 0x11030 -#define HD64461_CPTWDR 0x11032 -#define HD64461_CPTRAR 0x11034 -#define HD64461_CPTRDR 0x11036 - -#define HD64461_GRDOR 0x11040 -#define HD64461_GRSCR 0x11042 -#define HD64461_GRCFGR 0x11044 -#define HD64461_GRCFGR_ACCSTATUS 0x10 -#define HD64461_GRCFGR_ACCRESET 0x08 -#define HD64461_GRCFGR_ACCSTART_BITBLT 0x06 -#define HD64461_GRCFGR_ACCSTART_LINE 0x04 -#define HD64461_GRCFGR_COLORDEPTH16 0x01 - -#define HD64461_LNSARH 0x11046 -#define HD64461_LNSARL 0x11048 -#define HD64461_LNAXLR 0x1104a -#define HD64461_LNDGR 0x1104c -#define HD64461_LNAXR 0x1104e -#define HD64461_LNERTR 0x11050 -#define HD64461_LNMDR 0x11052 -#define HD64461_BBTSSARH 0x11054 -#define HD64461_BBTSSARL 0x11056 -#define HD64461_BBTDSARH 0x11058 -#define HD64461_BBTDSARL 0x1105a -#define HD64461_BBTDWR 0x1105c -#define HD64461_BBTDHR 0x1105e -#define HD64461_BBTPARH 0x11060 -#define HD64461_BBTPARL 0x11062 -#define HD64461_BBTMARH 0x11064 -#define HD64461_BBTMARL 0x11066 -#define HD64461_BBTROPR 0x11068 -#define HD64461_BBTMDR 0x1106a +#define HD64461_PCC_WINDOW 0x01000000 + +/* Area 6 - Slot 0 - memory and/or IO card */ +#define HD64461_PCC0_BASE (CONFIG_HD64461_IOBASE + 0x8000000) +#define HD64461_PCC0_ATTR (HD64461_PCC0_BASE) /* 0xb80000000 */ +#define HD64461_PCC0_COMM (HD64461_PCC0_BASE+HD64461_PCC_WINDOW) /* 0xb90000000 */ +#define HD64461_PCC0_IO (HD64461_PCC0_BASE+2*HD64461_PCC_WINDOW) /* 0xba0000000 */ + +/* Area 5 - Slot 1 - memory card only */ +#define HD64461_PCC1_BASE (CONFIG_HD64461_IOBASE + 0x4000000) +#define HD64461_PCC1_ATTR (HD64461_PCC1_BASE) /* 0xb4000000 */ +#define HD64461_PCC1_COMM (HD64461_PCC1_BASE+HD64461_PCC_WINDOW) /* 0xb5000000 */ + +/* Standby Control Register for HD64461 */ +#define HD64461_STBCR CONFIG_HD64461_IOBASE +#define HD64461_STBCR_CKIO_STBY 0x2000 +#define HD64461_STBCR_SAFECKE_IST 0x1000 +#define HD64461_STBCR_SLCKE_IST 0x0800 +#define HD64461_STBCR_SAFECKE_OST 0x0400 +#define HD64461_STBCR_SLCKE_OST 0x0200 +#define HD64461_STBCR_SMIAST 0x0100 +#define HD64461_STBCR_SLCDST 0x0080 +#define HD64461_STBCR_SPC0ST 0x0040 +#define HD64461_STBCR_SPC1ST 0x0020 +#define HD64461_STBCR_SAFEST 0x0010 +#define HD64461_STBCR_STM0ST 0x0008 +#define HD64461_STBCR_STM1ST 0x0004 +#define HD64461_STBCR_SIRST 0x0002 +#define HD64461_STBCR_SURTST 0x0001 + +/* System Configuration Register */ +#define HD64461_SYSCR (CONFIG_HD64461_IOBASE + 0x02) + +/* CPU Data Bus Control Register */ +#define HD64461_SCPUCR (CONFIG_HD64461_IOBASE + 0x04) + +/* Base Adress Register */ +#define HD64461_LCDCBAR (CONFIG_HD64461_IOBASE + 0x1000) + +/* Line increment adress */ +#define HD64461_LCDCLOR (CONFIG_HD64461_IOBASE + 0x1002) + +/* Controls LCD controller */ +#define HD64461_LCDCCR (CONFIG_HD64461_IOBASE + 0x1004) + +/* LCCDR control bits */ +#define HD64461_LCDCCR_STBACK 0x0400 /* Standby Back */ +#define HD64461_LCDCCR_STREQ 0x0100 /* Standby Request */ +#define HD64461_LCDCCR_MOFF 0x0080 /* Memory Off */ +#define HD64461_LCDCCR_REFSEL 0x0040 /* Refresh Select */ +#define HD64461_LCDCCR_EPON 0x0020 /* End Power On */ +#define HD64461_LCDCCR_SPON 0x0010 /* Start Power On */ + +/* Controls LCD (1) */ +#define HD64461_LDR1 (CONFIG_HD64461_IOBASE + 0x1010) +#define HD64461_LDR1_DON 0x01 /* Display On */ +#define HD64461_LDR1_DINV 0x80 /* Display Invert */ + +/* Controls LCD (2) */ +#define HD64461_LDR2 (CONFIG_HD64461_IOBASE + 0x1012) +#define HD64461_LDHNCR (CONFIG_HD64461_IOBASE + 0x1014) /* Number of horizontal characters */ +#define HD64461_LDHNSR (CONFIG_HD64461_IOBASE + 0x1016) /* Specify output start position + width of CL1 */ +#define HD64461_LDVNTR (CONFIG_HD64461_IOBASE + 0x1018) /* Specify total vertical lines */ +#define HD64461_LDVNDR (CONFIG_HD64461_IOBASE + 0x101a) /* specify number of display vertical lines */ +#define HD64461_LDVSPR (CONFIG_HD64461_IOBASE + 0x101c) /* specify vertical synchronization pos and AC nr */ + +/* Controls LCD (3) */ +#define HD64461_LDR3 (CONFIG_HD64461_IOBASE + 0x101e) + +/* Palette Registers */ +#define HD64461_CPTWAR (CONFIG_HD64461_IOBASE + 0x1030) /* Color Palette Write Adress Register */ +#define HD64461_CPTWDR (CONFIG_HD64461_IOBASE + 0x1032) /* Color Palette Write Data Register */ +#define HD64461_CPTRAR (CONFIG_HD64461_IOBASE + 0x1034) /* Color Palette Read Adress Register */ +#define HD64461_CPTRDR (CONFIG_HD64461_IOBASE + 0x1036) /* Color Palette Read Data Register */ + +#define HD64461_GRDOR (CONFIG_HD64461_IOBASE + 0x1040) /* Display Resolution Offset Register */ +#define HD64461_GRSCR (CONFIG_HD64461_IOBASE + 0x1042) /* Solid Color Register */ +#define HD64461_GRCFGR (CONFIG_HD64461_IOBASE + 0x1044) /* Accelerator Configuration Register */ + +#define HD64461_GRCFGR_ACCSTATUS 0x10 /* Accelerator Status */ +#define HD64461_GRCFGR_ACCRESET 0x08 /* Accelerator Reset */ +#define HD64461_GRCFGR_ACCSTART_BITBLT 0x06 /* Accelerator Start BITBLT */ +#define HD64461_GRCFGR_ACCSTART_LINE 0x04 /* Accelerator Start Line Drawing */ +#define HD64461_GRCFGR_COLORDEPTH16 0x01 /* Sets Colordepth 16 for Accelerator */ +#define HD64461_GRCFGR_COLORDEPTH8 0x01 /* Sets Colordepth 8 for Accelerator */ + +/* Line Drawing Registers */ +#define HD64461_LNSARH (CONFIG_HD64461_IOBASE + 0x1046) /* Line Start Adress Register (H) */ +#define HD64461_LNSARL (CONFIG_HD64461_IOBASE + 0x1048) /* Line Start Adress Register (L) */ +#define HD64461_LNAXLR (CONFIG_HD64461_IOBASE + 0x104a) /* Axis Pixel Length Register */ +#define HD64461_LNDGR (CONFIG_HD64461_IOBASE + 0x104c) /* Diagonal Register */ +#define HD64461_LNAXR (CONFIG_HD64461_IOBASE + 0x104e) /* Axial Register */ +#define HD64461_LNERTR (CONFIG_HD64461_IOBASE + 0x1050) /* Start Error Term Register */ +#define HD64461_LNMDR (CONFIG_HD64461_IOBASE + 0x1052) /* Line Mode Register */ + +/* BitBLT Registers */ +#define HD64461_BBTSSARH (CONFIG_HD64461_IOBASE + 0x1054) /* Source Start Adress Register (H) */ +#define HD64461_BBTSSARL (CONFIG_HD64461_IOBASE + 0x1056) /* Source Start Adress Register (L) */ +#define HD64461_BBTDSARH (CONFIG_HD64461_IOBASE + 0x1058) /* Destination Start Adress Register (H) */ +#define HD64461_BBTDSARL (CONFIG_HD64461_IOBASE + 0x105a) /* Destination Start Adress Register (L) */ +#define HD64461_BBTDWR (CONFIG_HD64461_IOBASE + 0x105c) /* Destination Block Width Register */ +#define HD64461_BBTDHR (CONFIG_HD64461_IOBASE + 0x105e) /* Destination Block Height Register */ +#define HD64461_BBTPARH (CONFIG_HD64461_IOBASE + 0x1060) /* Pattern Start Adress Register (H) */ +#define HD64461_BBTPARL (CONFIG_HD64461_IOBASE + 0x1062) /* Pattern Start Adress Register (L) */ +#define HD64461_BBTMARH (CONFIG_HD64461_IOBASE + 0x1064) /* Mask Start Adress Register (H) */ +#define HD64461_BBTMARL (CONFIG_HD64461_IOBASE + 0x1066) /* Mask Start Adress Register (L) */ +#define HD64461_BBTROPR (CONFIG_HD64461_IOBASE + 0x1068) /* ROP Register */ +#define HD64461_BBTMDR (CONFIG_HD64461_IOBASE + 0x106a) /* BitBLT Mode Register */ /* PC Card Controller Registers */ -#define HD64461_PCC0ISR 0x12000 /* socket 0 interface status */ -#define HD64461_PCC0GCR 0x12002 /* socket 0 general control */ -#define HD64461_PCC0CSCR 0x12004 /* socket 0 card status change */ -#define HD64461_PCC0CSCIER 0x12006 /* socket 0 card status change interrupt enable */ -#define HD64461_PCC0SCR 0x12008 /* socket 0 software control */ -#define HD64461_PCC1ISR 0x12010 /* socket 1 interface status */ -#define HD64461_PCC1GCR 0x12012 /* socket 1 general control */ -#define HD64461_PCC1CSCR 0x12014 /* socket 1 card status change */ -#define HD64461_PCC1CSCIER 0x12016 /* socket 1 card status change interrupt enable */ -#define HD64461_PCC1SCR 0x12018 /* socket 1 software control */ +/* Maps to Physical Area 6 */ +#define HD64461_PCC0ISR (CONFIG_HD64461_IOBASE + 0x2000) /* socket 0 interface status */ +#define HD64461_PCC0GCR (CONFIG_HD64461_IOBASE + 0x2002) /* socket 0 general control */ +#define HD64461_PCC0CSCR (CONFIG_HD64461_IOBASE + 0x2004) /* socket 0 card status change */ +#define HD64461_PCC0CSCIER (CONFIG_HD64461_IOBASE + 0x2006) /* socket 0 card status change interrupt enable */ +#define HD64461_PCC0SCR (CONFIG_HD64461_IOBASE + 0x2008) /* socket 0 software control */ +/* Maps to Physical Area 5 */ +#define HD64461_PCC1ISR (CONFIG_HD64461_IOBASE + 0x2010) /* socket 1 interface status */ +#define HD64461_PCC1GCR (CONFIG_HD64461_IOBASE + 0x2012) /* socket 1 general control */ +#define HD64461_PCC1CSCR (CONFIG_HD64461_IOBASE + 0x2014) /* socket 1 card status change */ +#define HD64461_PCC1CSCIER (CONFIG_HD64461_IOBASE + 0x2016) /* socket 1 card status change interrupt enable */ +#define HD64461_PCC1SCR (CONFIG_HD64461_IOBASE + 0x2018) /* socket 1 software control */ /* PCC Interface Status Register */ -#define HD64461_PCCISR_READY 0x80 /* card ready */ -#define HD64461_PCCISR_MWP 0x40 /* card write-protected */ -#define HD64461_PCCISR_VS2 0x20 /* voltage select pin 2 */ -#define HD64461_PCCISR_VS1 0x10 /* voltage select pin 1 */ -#define HD64461_PCCISR_CD2 0x08 /* card detect 2 */ -#define HD64461_PCCISR_CD1 0x04 /* card detect 1 */ -#define HD64461_PCCISR_BVD2 0x02 /* battery 1 */ -#define HD64461_PCCISR_BVD1 0x01 /* battery 1 */ - -#define HD64461_PCCISR_PCD_MASK 0x0c /* card detect */ -#define HD64461_PCCISR_BVD_MASK 0x03 /* battery voltage */ -#define HD64461_PCCISR_BVD_BATGOOD 0x03 /* battery good */ -#define HD64461_PCCISR_BVD_BATWARN 0x01 /* battery low warning */ -#define HD64461_PCCISR_BVD_BATDEAD1 0x02 /* battery dead */ -#define HD64461_PCCISR_BVD_BATDEAD2 0x00 /* battery dead */ +#define HD64461_PCCISR_READY 0x80 /* card ready */ +#define HD64461_PCCISR_MWP 0x40 /* card write-protected */ +#define HD64461_PCCISR_VS2 0x20 /* voltage select pin 2 */ +#define HD64461_PCCISR_VS1 0x10 /* voltage select pin 1 */ +#define HD64461_PCCISR_CD2 0x08 /* card detect 2 */ +#define HD64461_PCCISR_CD1 0x04 /* card detect 1 */ +#define HD64461_PCCISR_BVD2 0x02 /* battery 1 */ +#define HD64461_PCCISR_BVD1 0x01 /* battery 1 */ + +#define HD64461_PCCISR_PCD_MASK 0x0c /* card detect */ +#define HD64461_PCCISR_BVD_MASK 0x03 /* battery voltage */ +#define HD64461_PCCISR_BVD_BATGOOD 0x03 /* battery good */ +#define HD64461_PCCISR_BVD_BATWARN 0x01 /* battery low warning */ +#define HD64461_PCCISR_BVD_BATDEAD1 0x02 /* battery dead */ +#define HD64461_PCCISR_BVD_BATDEAD2 0x00 /* battery dead */ /* PCC General Control Register */ -#define HD64461_PCCGCR_DRVE 0x80 /* output drive */ -#define HD64461_PCCGCR_PCCR 0x40 /* PC card reset */ -#define HD64461_PCCGCR_PCCT 0x20 /* PC card type, 1=IO&mem, 0=mem */ -#define HD64461_PCCGCR_VCC0 0x10 /* voltage control pin VCC0SEL0 */ -#define HD64461_PCCGCR_PMMOD 0x08 /* memory mode */ -#define HD64461_PCCGCR_PA25 0x04 /* pin A25 */ -#define HD64461_PCCGCR_PA24 0x02 /* pin A24 */ -#define HD64461_PCCGCR_REG 0x01 /* pin PCC0REG# */ +#define HD64461_PCCGCR_DRVE 0x80 /* output drive */ +#define HD64461_PCCGCR_PCCR 0x40 /* PC card reset */ +#define HD64461_PCCGCR_PCCT 0x20 /* PC card type, 1=IO&mem, 0=mem */ +#define HD64461_PCCGCR_VCC0 0x10 /* voltage control pin VCC0SEL0 */ +#define HD64461_PCCGCR_PMMOD 0x08 /* memory mode */ +#define HD64461_PCCGCR_PA25 0x04 /* pin A25 */ +#define HD64461_PCCGCR_PA24 0x02 /* pin A24 */ +#define HD64461_PCCGCR_REG 0x01 /* pin PCC0REG# */ /* PCC Card Status Change Register */ -#define HD64461_PCCCSCR_SCDI 0x80 /* sw card detect intr */ -#define HD64461_PCCCSCR_SRV1 0x40 /* reserved */ -#define HD64461_PCCCSCR_IREQ 0x20 /* IREQ intr req */ -#define HD64461_PCCCSCR_SC 0x10 /* STSCHG (status change) pin */ -#define HD64461_PCCCSCR_CDC 0x08 /* CD (card detect) change */ -#define HD64461_PCCCSCR_RC 0x04 /* READY change */ -#define HD64461_PCCCSCR_BW 0x02 /* battery warning change */ -#define HD64461_PCCCSCR_BD 0x01 /* battery dead change */ +#define HD64461_PCCCSCR_SCDI 0x80 /* sw card detect intr */ +#define HD64461_PCCCSCR_SRV1 0x40 /* reserved */ +#define HD64461_PCCCSCR_IREQ 0x20 /* IREQ intr req */ +#define HD64461_PCCCSCR_SC 0x10 /* STSCHG (status change) pin */ +#define HD64461_PCCCSCR_CDC 0x08 /* CD (card detect) change */ +#define HD64461_PCCCSCR_RC 0x04 /* READY change */ +#define HD64461_PCCCSCR_BW 0x02 /* battery warning change */ +#define HD64461_PCCCSCR_BD 0x01 /* battery dead change */ /* PCC Card Status Change Interrupt Enable Register */ -#define HD64461_PCCCSCIER_CRE 0x80 /* change reset enable */ -#define HD64461_PCCCSCIER_IREQE_MASK 0x60 /* IREQ enable */ -#define HD64461_PCCCSCIER_IREQE_DISABLED 0x00 /* IREQ disabled */ -#define HD64461_PCCCSCIER_IREQE_LEVEL 0x20 /* IREQ level-triggered */ -#define HD64461_PCCCSCIER_IREQE_FALLING 0x40 /* IREQ falling-edge-trig */ -#define HD64461_PCCCSCIER_IREQE_RISING 0x60 /* IREQ rising-edge-trig */ - -#define HD64461_PCCCSCIER_SCE 0x10 /* status change enable */ -#define HD64461_PCCCSCIER_CDE 0x08 /* card detect change enable */ -#define HD64461_PCCCSCIER_RE 0x04 /* ready change enable */ -#define HD64461_PCCCSCIER_BWE 0x02 /* battery warn change enable */ -#define HD64461_PCCCSCIER_BDE 0x01 /* battery dead change enable*/ +#define HD64461_PCCCSCIER_CRE 0x80 /* change reset enable */ +#define HD64461_PCCCSCIER_IREQE_MASK 0x60 /* IREQ enable */ +#define HD64461_PCCCSCIER_IREQE_DISABLED 0x00 /* IREQ disabled */ +#define HD64461_PCCCSCIER_IREQE_LEVEL 0x20 /* IREQ level-triggered */ +#define HD64461_PCCCSCIER_IREQE_FALLING 0x40 /* IREQ falling-edge-trig */ +#define HD64461_PCCCSCIER_IREQE_RISING 0x60 /* IREQ rising-edge-trig */ + +#define HD64461_PCCCSCIER_SCE 0x10 /* status change enable */ +#define HD64461_PCCCSCIER_CDE 0x08 /* card detect change enable */ +#define HD64461_PCCCSCIER_RE 0x04 /* ready change enable */ +#define HD64461_PCCCSCIER_BWE 0x02 /* battery warn change enable */ +#define HD64461_PCCCSCIER_BDE 0x01 /* battery dead change enable*/ /* PCC Software Control Register */ -#define HD64461_PCCSCR_VCC1 0x02 /* voltage control pin 1 */ -#define HD64461_PCCSCR_SWP 0x01 /* write protect */ - -#define HD64461_P0OCR 0x1202a -#define HD64461_P1OCR 0x1202c -#define HD64461_PGCR 0x1202e - -#define HD64461_GPACR 0x14000 -#define HD64461_GPBCR 0x14002 -#define HD64461_GPCCR 0x14004 -#define HD64461_GPDCR 0x14006 -#define HD64461_GPADR 0x14010 -#define HD64461_GPBDR 0x14012 -#define HD64461_GPCDR 0x14014 -#define HD64461_GPDDR 0x14016 -#define HD64461_GPAICR 0x14020 -#define HD64461_GPBICR 0x14022 -#define HD64461_GPCICR 0x14024 -#define HD64461_GPDICR 0x14026 -#define HD64461_GPAISR 0x14040 -#define HD64461_GPBISR 0x14042 -#define HD64461_GPCISR 0x14044 -#define HD64461_GPDISR 0x14046 - -#define HD64461_NIRR 0x15000 -#define HD64461_NIMR 0x15002 - -#define HD64461_IRQBASE 64 -#define HD64461_IRQ_NUM 16 - -#define HD64461_IRQ_UART (HD64461_IRQBASE+5) -#define HD64461_IRQ_IRDA (HD64461_IRQBASE+6) -#define HD64461_IRQ_TMU1 (HD64461_IRQBASE+9) -#define HD64461_IRQ_TMU0 (HD64461_IRQBASE+10) -#define HD64461_IRQ_GPIO (HD64461_IRQBASE+11) -#define HD64461_IRQ_AFE (HD64461_IRQBASE+12) -#define HD64461_IRQ_PCC1 (HD64461_IRQBASE+13) -#define HD64461_IRQ_PCC0 (HD64461_IRQBASE+14) +#define HD64461_PCCSCR_VCC1 0x02 /* voltage control pin 1 */ +#define HD64461_PCCSCR_SWP 0x01 /* write protect */ + +/* PCC0 Output Pins Control Register */ +#define HD64461_P0OCR (CONFIG_HD64461_IOBASE + 0x202a) + +/* PCC1 Output Pins Control Register */ +#define HD64461_P1OCR (CONFIG_HD64461_IOBASE + 0x202c) + +/* PC Card General Control Register */ +#define HD64461_PGCR (CONFIG_HD64461_IOBASE + 0x202e) + +/* Port Control Registers */ +#define HD64461_GPACR (CONFIG_HD64461_IOBASE + 0x4000) /* Port A - Handles IRDA/TIMER */ +#define HD64461_GPBCR (CONFIG_HD64461_IOBASE + 0x4002) /* Port B - Handles UART */ +#define HD64461_GPCCR (CONFIG_HD64461_IOBASE + 0x4004) /* Port C - Handles PCMCIA 1 */ +#define HD64461_GPDCR (CONFIG_HD64461_IOBASE + 0x4006) /* Port D - Handles PCMCIA 1 */ + +/* Port Control Data Registers */ +#define HD64461_GPADR (CONFIG_HD64461_IOBASE + 0x4010) /* A */ +#define HD64461_GPBDR (CONFIG_HD64461_IOBASE + 0x4012) /* B */ +#define HD64461_GPCDR (CONFIG_HD64461_IOBASE + 0x4014) /* C */ +#define HD64461_GPDDR (CONFIG_HD64461_IOBASE + 0x4016) /* D */ + +/* Interrupt Control Registers */ +#define HD64461_GPAICR (CONFIG_HD64461_IOBASE + 0x4020) /* A */ +#define HD64461_GPBICR (CONFIG_HD64461_IOBASE + 0x4022) /* B */ +#define HD64461_GPCICR (CONFIG_HD64461_IOBASE + 0x4024) /* C */ +#define HD64461_GPDICR (CONFIG_HD64461_IOBASE + 0x4026) /* D */ + +/* Interrupt Status Registers */ +#define HD64461_GPAISR (CONFIG_HD64461_IOBASE + 0x4040) /* A */ +#define HD64461_GPBISR (CONFIG_HD64461_IOBASE + 0x4042) /* B */ +#define HD64461_GPCISR (CONFIG_HD64461_IOBASE + 0x4044) /* C */ +#define HD64461_GPDISR (CONFIG_HD64461_IOBASE + 0x4046) /* D */ + +/* Interrupt Request Register & Interrupt Mask Register */ +#define HD64461_NIRR (CONFIG_HD64461_IOBASE + 0x5000) +#define HD64461_NIMR (CONFIG_HD64461_IOBASE + 0x5002) + +#define HD64461_IRQBASE OFFCHIP_IRQ_BASE +#define HD64461_IRQ_NUM 16 + +#define HD64461_IRQ_UART (HD64461_IRQBASE+5) +#define HD64461_IRQ_IRDA (HD64461_IRQBASE+6) +#define HD64461_IRQ_TMU1 (HD64461_IRQBASE+9) +#define HD64461_IRQ_TMU0 (HD64461_IRQBASE+10) +#define HD64461_IRQ_GPIO (HD64461_IRQBASE+11) +#define HD64461_IRQ_AFE (HD64461_IRQBASE+12) +#define HD64461_IRQ_PCC1 (HD64461_IRQBASE+13) +#define HD64461_IRQ_PCC0 (HD64461_IRQBASE+14) #define __IO_PREFIX hd64461 #include -- cgit v1.2.3-59-g8ed1b