diff options
Diffstat (limited to 'arch')
207 files changed, 10521 insertions, 4412 deletions
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index 930cedc8be2..783f4e50c11 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -289,7 +289,7 @@ srm_console_device(struct console *co, int *index) return srmcons_driver; } -static int __init +static int srm_console_setup(struct console *co, char *options) { return 0; diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index 0bcb968cb60..922143ea1cd 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c @@ -420,7 +420,7 @@ marvel_init_pci(void) io7_clear_errors(io7); } -static void +static void __init marvel_init_rtc(void) { init_rtc_irq(); diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 4748e14a28b..1dd50d07693 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -144,7 +144,7 @@ irqreturn_t timer_interrupt(int irq, void *dev) return IRQ_HANDLED; } -void +void __init common_init_rtc(void) { unsigned char x; diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig index 20688bc13e9..9044f33299f 100644 --- a/arch/arm26/Kconfig +++ b/arch/arm26/Kconfig @@ -17,6 +17,9 @@ config MMU bool default y +config NO_DMA + def_bool y + config ARCH_ACORN bool default y diff --git a/arch/arm26/defconfig b/arch/arm26/defconfig index c4a89703c3d..2b7d44bf49b 100644 --- a/arch/arm26/defconfig +++ b/arch/arm26/defconfig @@ -248,7 +248,6 @@ CONFIG_I2C_CHARDEV=y # CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set diff --git a/arch/arm26/mm/init.c b/arch/arm26/mm/init.c index 562fac12eb9..36e7ee3f832 100644 --- a/arch/arm26/mm/init.c +++ b/arch/arm26/mm/init.c @@ -33,9 +33,6 @@ #include <asm/map.h> - -#define TABLE_SIZE PTRS_PER_PTE * sizeof(pte_t)) - struct mmu_gather mmu_gathers[NR_CPUS]; extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c index 86d107511dd..aaa792815cd 100644 --- a/arch/avr32/kernel/traps.c +++ b/arch/avr32/kernel/traps.c @@ -184,7 +184,7 @@ asmlinkage void do_illegal_opcode(unsigned long ecr, struct pt_regs *regs) if (!user_mode(regs) && (ecr == ECR_ILLEGAL_OPCODE)) { enum bug_trap_type type; - type = report_bug(regs->pc); + type = report_bug(regs->pc, regs); switch (type) { case BUG_TRAP_TYPE_NONE: break; diff --git a/arch/cris/arch-v10/defconfig b/arch/cris/arch-v10/defconfig index 2a3411eaace..710c20ba2be 100644 --- a/arch/cris/arch-v10/defconfig +++ b/arch/cris/arch-v10/defconfig @@ -429,7 +429,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_BFS_FS is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c index 1a071f17446..e8914d40169 100644 --- a/arch/cris/arch-v32/drivers/cryptocop.c +++ b/arch/cris/arch-v32/drivers/cryptocop.c @@ -267,10 +267,10 @@ static void print_user_dma_lists(struct cryptocop_dma_list_operation *dma_op); const struct file_operations cryptocop_fops = { - owner: THIS_MODULE, - open: cryptocop_open, - release: cryptocop_release, - ioctl: cryptocop_ioctl + .owner = THIS_MODULE, + .open = cryptocop_open, + .release = cryptocop_release, + .ioctl = cryptocop_ioctl }; diff --git a/arch/cris/arch-v32/drivers/i2c.c b/arch/cris/arch-v32/drivers/i2c.c index 5d6c52737df..e12f6cc6f4a 100644 --- a/arch/cris/arch-v32/drivers/i2c.c +++ b/arch/cris/arch-v32/drivers/i2c.c @@ -574,10 +574,10 @@ i2c_ioctl(struct inode *inode, struct file *file, } static const struct file_operations i2c_fops = { - owner: THIS_MODULE, - ioctl: i2c_ioctl, - open: i2c_open, - release: i2c_release, + .owner = THIS_MODULE, + .ioctl = i2c_ioctl, + .open = i2c_open, + .release = i2c_release, }; int __init diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c index 24b919b3821..fa8d50007e4 100644 --- a/arch/cris/arch-v32/drivers/pcf8563.c +++ b/arch/cris/arch-v32/drivers/pcf8563.c @@ -51,10 +51,10 @@ int pcf8563_open(struct inode *, struct file *); int pcf8563_release(struct inode *, struct file *); static const struct file_operations pcf8563_fops = { - owner: THIS_MODULE, - ioctl: pcf8563_ioctl, - open: pcf8563_open, - release: pcf8563_release, + .owner = THIS_MODULE, + .ioctl = pcf8563_ioctl, + .open = pcf8563_open, + .release = pcf8563_release, }; unsigned char diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index 43dc08ec751..275673c192a 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S @@ -1492,6 +1492,10 @@ sys_call_table: .long sys_move_pages .long sys_getcpu .long sys_epoll_pwait + .long sys_utimensat /* 320 */ + .long sys_signalfd + .long sys_timerfd + .long sys_eventfd syscall_table_size = (. - sys_call_table) diff --git a/arch/frv/kernel/gdb-stub.c b/arch/frv/kernel/gdb-stub.c index 1e7a101cbf4..e89cad1192a 100644 --- a/arch/frv/kernel/gdb-stub.c +++ b/arch/frv/kernel/gdb-stub.c @@ -647,17 +647,11 @@ void debug_to_serial(const char *p, int n) } #endif -#ifdef CONFIG_GDBSTUB_CONSOLE - -static kdev_t gdbstub_console_dev(struct console *con) -{ - return MKDEV(1,3); /* /dev/null */ -} +#ifdef CONFIG_GDB_CONSOLE static struct console gdbstub_console = { .name = "gdb", .write = gdbstub_console_write, /* in break.S */ - .device = gdbstub_console_dev, .flags = CON_PRINTBUFFER, .index = -1, }; @@ -2021,7 +2015,7 @@ void __init gdbstub_init(void) ptr = mem2hex(gdbstub_banner, ptr, sizeof(gdbstub_banner) - 1, 0); gdbstub_send_packet(output_buffer); #endif -#if defined(CONFIG_GDBSTUB_CONSOLE) && defined(CONFIG_GDBSTUB_IMMEDIATE) +#if defined(CONFIG_GDB_CONSOLE) && defined(CONFIG_GDBSTUB_IMMEDIATE) register_console(&gdbstub_console); #endif @@ -2031,7 +2025,7 @@ void __init gdbstub_init(void) /* * register the console at a more appropriate time */ -#if defined (CONFIG_GDBSTUB_CONSOLE) && !defined(CONFIG_GDBSTUB_IMMEDIATE) +#if defined (CONFIG_GDB_CONSOLE) && !defined(CONFIG_GDBSTUB_IMMEDIATE) static int __init gdbstub_postinit(void) { printk("registering console\n"); diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c index aa3c795d535..c1c32e4c863 100644 --- a/arch/frv/kernel/setup.c +++ b/arch/frv/kernel/setup.c @@ -60,10 +60,6 @@ static void __init setup_linux_memory(void); static void __init setup_uclinux_memory(void); #endif -#ifdef CONFIG_CONSOLE -extern struct consw *conswitchp; -#endif - #ifdef CONFIG_MB93090_MB00 static char __initdata mb93090_banner[] = "FJ/RH FR-V Linux"; static char __initdata mb93090_version[] = UTS_RELEASE; @@ -795,13 +791,6 @@ void __init setup_arch(char **cmdline_p) #endif #endif -#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) - /* we need to initialize the Flashrom device here since we might - * do things with flash early on in the boot - */ - flash_probe(); -#endif - /* deal with the command line - RedBoot may have passed one to the kernel */ memcpy(command_line, boot_command_line, sizeof(command_line)); *cmdline_p = &command_line[0]; @@ -837,11 +826,6 @@ void __init setup_arch(char **cmdline_p) #endif #endif -#ifdef CONFIG_BLK_DEV_BLKMEM - ROOT_DEV = MKDEV(BLKMEM_MAJOR,0); -#endif - /*rom_length = (unsigned long)&_flashend - (unsigned long)&_romvec;*/ - #ifdef CONFIG_MMU setup_linux_memory(); #else diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 618dbad696f..e35f74e6e50 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -68,6 +68,9 @@ config TIME_LOW_RES config NO_IOPORT def_bool y +config NO_DMA + def_bool y + config ISA bool default y diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile index b2d896a7e59..53b5c1edf59 100644 --- a/arch/h8300/Makefile +++ b/arch/h8300/Makefile @@ -61,10 +61,11 @@ archmrproper: archclean: $(Q)$(MAKE) $(clean)=$(boot) -vmlinux.srec vmlinux.bin: vmlinux +vmlinux.srec vmlinux.bin zImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ define archhelp - echo 'vmlinux.bin - Create raw binary' - echo 'vmlinux.srec - Create srec binary' + @echo 'vmlinux.bin - Create raw binary' + @echo 'vmlinux.srec - Create srec binary' + @echo 'zImage - Compressed kernel image' endef diff --git a/arch/h8300/boot/compressed/Makefile b/arch/h8300/boot/compressed/Makefile index 71aac82a8ae..d6189e057ed 100644 --- a/arch/h8300/boot/compressed/Makefile +++ b/arch/h8300/boot/compressed/Makefile @@ -15,10 +15,10 @@ OBJECTS = $(obj)/head.o $(obj)/misc.o # in order to suppress error message. # CONFIG_MEMORY_START ?= 0x00400000 -CONFIG_BOOT_LINK_OFFSET ?= 0x00400000 +CONFIG_BOOT_LINK_OFFSET ?= 0x00140000 IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)]) -LDFLAGS_vmlinux := -T $(obj)/vmlinux.lds +LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -estartup $(obj)/vmlinux.lds $(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE $(call if_changed,ld) diff --git a/arch/h8300/boot/compressed/head.S b/arch/h8300/boot/compressed/head.S index b8e90d12d19..985a81a2435 100644 --- a/arch/h8300/boot/compressed/head.S +++ b/arch/h8300/boot/compressed/head.S @@ -4,7 +4,7 @@ * Copyright (C) 2006 Yoshinori Sato */ -.h8300h + .h8300h #include <linux/linkage.h> #define SRAM_START 0xff4000 diff --git a/arch/h8300/boot/compressed/vmlinux.lds b/arch/h8300/boot/compressed/vmlinux.lds new file mode 100644 index 00000000000..65e2a0d1ae3 --- /dev/null +++ b/arch/h8300/boot/compressed/vmlinux.lds @@ -0,0 +1,32 @@ +SECTIONS +{ + .text : + { + __stext = . ; + __text = .; + *(.text.startup) + *(.text) + __etext = . ; + } + + .rodata : + { + *(.rodata) + } + .data : + + { + __sdata = . ; + ___data_start = . ; + *(.data.*) + } + .bss : + { + . = ALIGN(0x4) ; + __sbss = . ; + *(.bss*) + . = ALIGN(0x4) ; + __ebss = . ; + __end = . ; + } +} diff --git a/arch/h8300/boot/compressed/vmlinux.scr b/arch/h8300/boot/compressed/vmlinux.scr new file mode 100644 index 00000000000..a0f6962736e --- /dev/null +++ b/arch/h8300/boot/compressed/vmlinux.scr @@ -0,0 +1,9 @@ +SECTIONS +{ + .data : { + _input_len = .; + LONG(_input_data_end - _input_data) _input_data = .; + *(.data) + _input_data_end = .; + } +} diff --git a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile index ccc1a7fbf94..874f6aefee6 100644 --- a/arch/h8300/kernel/Makefile +++ b/arch/h8300/kernel/Makefile @@ -6,6 +6,7 @@ extra-y := vmlinux.lds obj-y := process.o traps.o ptrace.o irq.o \ sys_h8300.o time.o semaphore.o signal.o \ - setup.o gpio.o init_task.o syscalls.o + setup.o gpio.o init_task.o syscalls.o \ + entry.o obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o diff --git a/arch/h8300/platform/h8s/entry.S b/arch/h8300/kernel/entry.S index f3d6b8e8f95..ca743169030 100644 --- a/arch/h8300/platform/h8s/entry.S +++ b/arch/h8300/kernel/entry.S @@ -1,11 +1,10 @@ /* -*- mode: asm -*- * - * linux/arch/h8300/platform/h8s/entry.S + * linux/arch/h8300/platform/h8300h/entry.S * * Yoshinori Sato <ysato@users.sourceforge.jp> + * David McCullough <davidm@snapgear.com> * - * fairly heavy changes to fix syscall args and signal processing - * by David McCullough <davidm@snapgear.com> */ /* @@ -23,13 +22,66 @@ #include <asm/thread_info.h> #include <asm/errno.h> +#if defined(CONFIG_CPU_H8300H) +#define USERRET 8 +INTERRUPTS = 64 + .h8300h + .macro SHLL2 reg + shll.l \reg + shll.l \reg + .endm + .macro SHLR2 reg + shlr.l \reg + shlr.l \reg + .endm + .macro SAVEREGS + mov.l er0,@-sp + mov.l er1,@-sp + mov.l er2,@-sp + mov.l er3,@-sp + .endm + .macro RESTOREREGS + mov.l @sp+,er3 + mov.l @sp+,er2 + .endm + .macro SAVEEXR + .endm + .macro RESTOREEXR + .endm +#endif +#if defined(CONFIG_CPU_H8S) +#define USERRET 10 +#define USEREXR 8 +INTERRUPTS = 128 .h8300s + .macro SHLL2 reg + shll.l #2,\reg + .endm + .macro SHLR2 reg + shlr.l #2,\reg + .endm + .macro SAVEREGS + stm.l er0-er3,@-sp + .endm + .macro RESTOREREGS + ldm.l @sp+,er2-er3 + .endm + .macro SAVEEXR + mov.w @(USEREXR:16,er0),r1 + mov.w r1,@(LEXR-LER3:16,sp) /* copy EXR */ + .endm + .macro RESTOREEXR + mov.w @(LEXR-LER1:16,sp),r1 /* restore EXR */ + mov.b r1l,r1h + mov.w r1,@(USEREXR:16,er0) + .endm +#endif + /* CPU context save/restore macros. */ - + .macro SAVE_ALL mov.l er0,@-sp - stc ccr,r0l /* check kernel mode */ btst #4,r0l bne 5f @@ -39,42 +91,38 @@ mov.l @sp,er0 /* restore saved er0 */ orc #0x10,ccr /* switch kernel stack */ mov.l @SYMBOL_NAME(sw_ksp),sp - sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */ - stm.l er0-er3,@-sp - mov.l @SYMBOL_NAME(sw_usp),er0 - mov.l @(10:16,er0),er1 /* copy the RET addr */ - mov.l er1,@(LRET-LER3:16,sp) - mov.w @(8:16,er0),r1 - mov.w r1,@(LEXR-LER3:16,sp) /* copy EXR */ + sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */ + SAVEREGS + mov.l @SYMBOL_NAME(sw_usp),er0 + mov.l @(USERRET:16,er0),er1 /* copy the RET addr */ + mov.l er1,@(LRET-LER3:16,sp) + SAVEEXR - mov.w e1,r1 /* e1 highbyte = ccr */ - and #0xef,r1h /* mask mode? flag */ - sub.w r0,r0 - mov.b r1h,r0l - mov.w r0,@(LCCR-LER3:16,sp) /* copy ccr */ mov.l @(LORIG-LER3:16,sp),er0 mov.l er0,@(LER0-LER3:16,sp) /* copy ER0 */ + mov.w e1,r1 /* e1 highbyte = ccr */ + and #0xef,r1h /* mask mode? flag */ bra 6f 5: /* kernel mode */ mov.l @sp,er0 /* restore saved er0 */ subs #2,sp /* set dummy ccr */ - stm.l er0-er3,@-sp + SAVEREGS mov.w @(LRET-LER3:16,sp),r1 /* copy old ccr */ +6: mov.b r1h,r1l mov.b #0,r1h - mov.w r1,@(LCCR-LER3:16,sp) -6: + mov.w r1,@(LCCR-LER3:16,sp) /* set ccr */ mov.l er6,@-sp /* syscall arg #6 */ mov.l er5,@-sp /* syscall arg #5 */ mov.l er4,@-sp /* syscall arg #4 */ - .endm + .endm /* r1 = ccr */ .macro RESTORE_ALL mov.l @sp+,er4 mov.l @sp+,er5 mov.l @sp+,er6 - ldm.l @sp+,er2-er3 + RESTOREREGS mov.w @(LCCR-LER1:16,sp),r0 /* check kernel mode */ btst #4,r0l bne 7f @@ -83,18 +131,16 @@ mov.l @SYMBOL_NAME(sw_usp),er0 mov.l @(LER0-LER1:16,sp),er1 /* restore ER0 */ mov.l er1,@er0 - mov.w @(LEXR-LER1:16,sp),r1 /* restore EXR */ - mov.b r1l,r1h - mov.w r1,@(8:16,er0) + RESTOREEXR mov.w @(LCCR-LER1:16,sp),r1 /* restore the RET addr */ mov.b r1l,r1h mov.b @(LRET+1-LER1:16,sp),r1l mov.w r1,e1 mov.w @(LRET+2-LER1:16,sp),r1 - mov.l er1,@(10:16,er0) + mov.l er1,@(USERRET:16,er0) mov.l @sp+,er1 - add.l #(LRET-LER1),sp /* remove LORIG - LRET */ + add.l #(LRET-LER1),sp /* remove LORIG - LRET */ mov.l sp,@SYMBOL_NAME(sw_ksp) andc #0xef,ccr /* switch to user mode */ mov.l er0,sp @@ -108,7 +154,7 @@ adds #4,sp /* remove the sw created LVEC */ rte .endm - + .globl SYMBOL_NAME(system_call) .globl SYMBOL_NAME(ret_from_exception) .globl SYMBOL_NAME(ret_from_fork) @@ -116,16 +162,25 @@ .globl SYMBOL_NAME(interrupt_redirect_table) .globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp) .globl SYMBOL_NAME(resume) -.globl SYMBOL_NAME(trace_break) .globl SYMBOL_NAME(interrupt_entry) - -INTERRUPTS = 128 +.globl SYMBOL_NAME(trace_break) + #if defined(CONFIG_ROMKERNEL) .section .int_redirect,"ax" SYMBOL_NAME_LABEL(interrupt_redirect_table) +#if defined(CONFIG_CPU_H8300H) .rept 7 .long 0 .endr +#endif +#if defined(CONFIG_CPU_H8S) + .rept 5 + .long 0 + .endr + jmp @SYMBOL_NAME(trace_break) + .long 0 +#endif + jsr @SYMBOL_NAME(interrupt_entry) /* NMI */ jmp @SYMBOL_NAME(system_call) /* TRAPA #0 (System call) */ .long 0 @@ -141,20 +196,20 @@ SYMBOL_NAME_LABEL(interrupt_redirect_table) SYMBOL_NAME_LABEL(interrupt_redirect_table) .space 4 #endif - + .section .text .align 2 SYMBOL_NAME_LABEL(interrupt_entry) SAVE_ALL - mov.w @(LCCR,sp),r0 - btst #4,r0l + mov.l sp,er0 + add.l #LVEC,er0 + btst #4,r1l bne 1f + /* user LVEC */ mov.l @SYMBOL_NAME(sw_usp),er0 - mov.l @(4:16,er0),er0 - bra 2f + adds #4,er0 1: - mov.l @(LVEC:16,sp),er0 -2: + mov.l @er0,er0 /* LVEC address */ #if defined(CONFIG_ROMKERNEL) sub.l #SYMBOL_NAME(interrupt_redirect_table),er0 #endif @@ -162,69 +217,62 @@ SYMBOL_NAME_LABEL(interrupt_entry) mov.l @SYMBOL_NAME(interrupt_redirect_table),er1 sub.l er1,er0 #endif - shlr.l #2,er0 + SHLR2 er0 dec.l #1,er0 mov.l sp,er1 subs #4,er1 /* adjust ret_pc */ - jsr @SYMBOL_NAME(process_int) - mov.l @SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,er0 - beq 1f - jsr @SYMBOL_NAME(do_softirq) -1: - jmp @SYMBOL_NAME(ret_from_exception) + jsr @SYMBOL_NAME(do_IRQ) + jmp @SYMBOL_NAME(ret_from_interrupt) SYMBOL_NAME_LABEL(system_call) subs #4,sp /* dummy LVEC */ SAVE_ALL + andc #0x7f,ccr mov.l er0,er4 - mov.l #-ENOSYS,er0 - mov.l er0,@(LER0:16,sp) /* save top of frame */ mov.l sp,er0 jsr @SYMBOL_NAME(set_esp0) - cmp.l #NR_syscalls,er4 - bcc SYMBOL_NAME(ret_from_exception):16 - shll.l #2,er4 - mov.l #SYMBOL_NAME(sys_call_table),er0 - add.l er4,er0 - mov.l @er0,er0 - mov.l er0,er4 - beq SYMBOL_NAME(ret_from_exception):16 mov.l sp,er2 and.w #0xe000,r2 - mov.b @((TASK_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l + mov.b @((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l btst #(TIF_SYSCALL_TRACE & 7),r2l + beq 1f + jsr @SYMBOL_NAME(do_syscall_trace) +1: + cmp.l #NR_syscalls,er4 + bcc badsys + SHLL2 er4 + mov.l #SYMBOL_NAME(sys_call_table),er0 + add.l er4,er0 + mov.l @er0,er4 + beq SYMBOL_NAME(ret_from_exception):16 mov.l @(LER1:16,sp),er0 mov.l @(LER2:16,sp),er1 mov.l @(LER3:16,sp),er2 - andc #0x7f,ccr jsr @er4 - mov.l er0,@(LER0:16,sp) /* save the return value */ + mov.l er0,@(LER0:16,sp) /* save the return value */ + mov.l sp,er2 + and.w #0xe000,r2 + mov.b @((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l + btst #(TIF_SYSCALL_TRACE & 7),r2l + beq 2f + jsr @SYMBOL_NAME(do_syscall_trace) +2: #if defined(CONFIG_SYSCALL_PRINT) jsr @SYMBOL_NAME(syscall_print) #endif - bra SYMBOL_NAME(ret_from_exception):8 -1: - jsr SYMBOL_NAME(syscall_trace) - mov.l @(LER1:16,sp),er0 - mov.l @(LER2:16,sp),er1 - mov.l @(LER3:16,sp),er2 - jsr @er4 - mov.l er0,@(LER0:16,sp) /* save the return value */ - jsr @SYMBOL_NAME(syscall_trace) - bra SYMBOL_NAME(ret_from_exception):8 + orc #0x80,ccr + bra resume_userspace -SYMBOL_NAME_LABEL(ret_from_fork) - mov.l er2,er0 - jsr @SYMBOL_NAME(schedule_tail) - bra SYMBOL_NAME(ret_from_exception):8 +badsys: + mov.l #-ENOSYS,er0 + mov.l er0,@(LER0:16,sp) + bra resume_userspace -SYMBOL_NAME_LABEL(reschedule) - /* save top of frame */ - mov.l sp,er0 - jsr @SYMBOL_NAME(set_esp0) - jsr @SYMBOL_NAME(schedule) +#if !defined(CONFIG_PREEMPT) +#define resume_kernel restore_all +#endif SYMBOL_NAME_LABEL(ret_from_exception) #if defined(CONFIG_PREEMPT) @@ -232,58 +280,68 @@ SYMBOL_NAME_LABEL(ret_from_exception) #endif SYMBOL_NAME_LABEL(ret_from_interrupt) mov.b @(LCCR+1:16,sp),r0l - btst #4,r0l /* check if returning to kernel */ - bne done:8 /* if so, skip resched, signals */ + btst #4,r0l + bne resume_kernel:8 /* return from kernel */ +resume_userspace: andc #0x7f,ccr mov.l sp,er4 - and.w #0xe000,r4 + and.w #0xe000,r4 /* er4 <- current thread info */ mov.l @(TI_FLAGS:16,er4),er1 and.l #_TIF_WORK_MASK,er1 - beq done:8 -1: - mov.l @(TI_FLAGS:16,er4),er1 + beq restore_all:8 +work_pending: btst #TIF_NEED_RESCHED,r1l - bne SYMBOL_NAME(reschedule):16 + bne work_resched:8 + /* work notifysig */ mov.l sp,er0 - subs #4,er0 /* adjust retpc */ - mov.l er2,er1 - jsr @SYMBOL_NAME(do_signal) + subs #4,er0 /* er0: pt_regs */ + jsr @SYMBOL_NAME(do_notify_resume) + bra restore_all:8 +work_resched: + mov.l sp,er0 + jsr @SYMBOL_NAME(set_esp0) + jsr @SYMBOL_NAME(schedule) + bra resume_userspace:8 +restore_all: + RESTORE_ALL /* Does RTE */ + #if defined(CONFIG_PREEMPT) - bra done:8 /* userspace thoru */ -3: - btst #4,r0l - beq done:8 /* userspace thoru */ -4: - mov.l @(TI_PRE_COUNT:16,er4),er1 - bne done:8 - mov.l @(TI_FLAGS:16,er4),er1 - btst #TIF_NEED_RESCHED,r1l - beq done:8 - mov.b r0l,r0l - bpl done:8 /* interrupt off (exception path?) */ - mov.l #PREEMPT_ACTIVE,er1 - mov.l er1,@(TI_PRE_COUNT:16,er4) +resume_kernel: + mov.l @(TI_PRE_COUNT:16,er4),er0 + bne restore_all:8 +need_resched: + mov.l @(TI_FLAGS:16,er4),er0 + btst #TIF_NEED_RESCHED,r0l + beq restore_all:8 + mov.b @(LCCR+1:16,sp),r0l /* Interrupt Enabled? */ + bmi restore_all:8 + mov.l #PREEMPT_ACTIVE,er0 + mov.l er0,@(TI_PRE_COUNT:16,er4) andc #0x7f,ccr + mov.l sp,er0 + jsr @SYMBOL_NAME(set_esp0) jsr @SYMBOL_NAME(schedule) - sub.l er1,er1 - mov.l er1,@(TI_PRE_COUNT:16,er4) orc #0x80,ccr - bra 4b:8 + bra need_resched:8 #endif -done: - RESTORE_ALL /* Does RTE */ + +SYMBOL_NAME_LABEL(ret_from_fork) + mov.l er2,er0 + jsr @SYMBOL_NAME(schedule_tail) + jmp @SYMBOL_NAME(ret_from_exception) SYMBOL_NAME_LABEL(resume) /* - * er0 = prev - * er1 = next - * return last in er2 + * Beware - when entering resume, offset of tss is in d1, + * prev (the current task) is in a0, next (the new task) + * is in a1 and d2.b is non-zero if the mm structure is + * shared between the tasks, so don't change these + * registers until their contents are no longer needed. */ /* save sr */ sub.w r3,r3 stc ccr,r3l - stc exr,r3h mov.w r3,@(THREAD_CCR+2:16,er0) /* disable interrupts */ @@ -291,41 +349,45 @@ SYMBOL_NAME_LABEL(resume) mov.l @SYMBOL_NAME(sw_usp),er3 mov.l er3,@(THREAD_USP:16,er0) mov.l sp,@(THREAD_KSP:16,er0) - + /* Skip address space switching if they are the same. */ /* FIXME: what did we hack out of here, this does nothing! */ mov.l @(THREAD_USP:16,er1),er0 mov.l er0,@SYMBOL_NAME(sw_usp) mov.l @(THREAD_KSP:16,er1),sp - + /* restore status register */ mov.w @(THREAD_CCR+2:16,er1),r3 ldc r3l,ccr - ldc r3h,exr - rts SYMBOL_NAME_LABEL(trace_break) - subs #4,sp /* dummy LVEC */ + subs #4,sp SAVE_ALL sub.l er1,er1 dec.l #1,er1 - mov.l er1,@(LORIG,sp) + mov.l er1,@(LORIG,sp) mov.l sp,er0 jsr @SYMBOL_NAME(set_esp0) mov.l @SYMBOL_NAME(sw_usp),er0 mov.l @er0,er1 + mov.w @(-2:16,er1),r2 + cmp.w #0x5730,r2 + beq 1f subs #2,er1 - mov.l er1,@er0 + mov.l er1,@er0 +1: and.w #0xff,e1 mov.l er1,er0 jsr @SYMBOL_NAME(trace_trap) - jmp @SYMBOL_NAME(ret_from_exception) + jmp @SYMBOL_NAME(ret_from_exception) .section .bss SYMBOL_NAME_LABEL(sw_ksp) - .space 4 + .space 4 SYMBOL_NAME_LABEL(sw_usp) - .space 4 + .space 4 + + .end diff --git a/arch/h8300/kernel/ints.c b/arch/h8300/kernel/ints.c deleted file mode 100644 index 3e4f479271c..00000000000 --- a/arch/h8300/kernel/ints.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * linux/arch/h8300/kernel/ints.c - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Based on linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * - * Copyright 1996 Roman Zippel - * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com> - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/kernel_stat.h> -#include <linux/seq_file.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/random.h> -#include <linux/bootmem.h> -#include <linux/hardirq.h> - -#include <asm/system.h> -#include <asm/irq.h> -#include <asm/traps.h> -#include <asm/io.h> -#include <asm/setup.h> -#include <asm/errno.h> - -/* - * This structure has only 4 elements for speed reasons - */ -typedef struct irq_handler { - irqreturn_t (*handler)(int, void *, struct pt_regs *); - int flags; - int count; - void *dev_id; - const char *devname; -} irq_handler_t; - -static irq_handler_t *irq_list[NR_IRQS]; -static int use_kmalloc; - -extern unsigned long *interrupt_redirect_table; -extern const int h8300_saved_vectors[]; -extern const unsigned long h8300_trap_table[]; -int h8300_enable_irq_pin(unsigned int irq); -void h8300_disable_irq_pin(unsigned int irq); - -#define CPU_VECTOR ((unsigned long *)0x000000) -#define ADDR_MASK (0xffffff) - -#if defined(CONFIG_RAMKERNEL) -static unsigned long __init *get_vector_address(void) -{ - unsigned long *rom_vector = CPU_VECTOR; - unsigned long base,tmp; - int vec_no; - - base = rom_vector[EXT_IRQ0] & ADDR_MASK; - - /* check romvector format */ - for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) { - if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK)) - return NULL; - } - - /* ramvector base address */ - base -= EXT_IRQ0*4; - - /* writerble check */ - tmp = ~(*(volatile unsigned long *)base); - (*(volatile unsigned long *)base) = tmp; - if ((*(volatile unsigned long *)base) != tmp) - return NULL; - return (unsigned long *)base; -} -#endif - -void __init init_IRQ(void) -{ -#if defined(CONFIG_RAMKERNEL) - int i; - unsigned long *ramvec,*ramvec_p; - const unsigned long *trap_entry; - const int *saved_vector; - - ramvec = get_vector_address(); - if (ramvec == NULL) - panic("interrupt vector serup failed."); - else - printk(KERN_INFO "virtual vector at 0x%08lx\n",(unsigned long)ramvec); - - /* create redirect table */ - ramvec_p = ramvec; - trap_entry = h8300_trap_table; - saved_vector = h8300_saved_vectors; - for ( i = 0; i < NR_IRQS; i++) { - if (i == *saved_vector) { - ramvec_p++; - saved_vector++; - } else { - if ( i < NR_TRAPS ) { - if (*trap_entry) - *ramvec_p = VECTOR(*trap_entry); - ramvec_p++; - trap_entry++; - } else - *ramvec_p++ = REDIRECT(interrupt_entry); - } - } - interrupt_redirect_table = ramvec; -#ifdef DUMP_VECTOR - ramvec_p = ramvec; - for (i = 0; i < NR_IRQS; i++) { - if ((i % 8) == 0) - printk(KERN_DEBUG "\n%p: ",ramvec_p); - printk(KERN_DEBUG "%p ",*ramvec_p); - ramvec_p++; - } - printk(KERN_DEBUG "\n"); -#endif -#endif -} - -int request_irq(unsigned int irq, - irqreturn_t (*handler)(int, void *, struct pt_regs *), - unsigned long flags, const char *devname, void *dev_id) -{ - irq_handler_t *irq_handle; - if (irq < 0 || irq >= NR_IRQS) { - printk(KERN_ERR "Incorrect IRQ %d from %s\n", irq, devname); - return -EINVAL; - } - - if (irq_list[irq] || (h8300_enable_irq_pin(irq) == -EBUSY)) - return -EBUSY; - - if (use_kmalloc) - irq_handle = kmalloc(sizeof(irq_handler_t), GFP_ATOMIC); - else { - /* use bootmem allocater */ - irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t)); - irq_handle = (irq_handler_t *)((unsigned long)irq_handle | 0x80000000); - } - - if (irq_handle == NULL) - return -ENOMEM; - - irq_handle->handler = handler; - irq_handle->flags = flags; - irq_handle->count = 0; - irq_handle->dev_id = dev_id; - irq_handle->devname = devname; - irq_list[irq] = irq_handle; - - if (irq_handle->flags & IRQF_SAMPLE_RANDOM) - rand_initialize_irq(irq); - - enable_irq(irq); - return 0; -} - -EXPORT_SYMBOL(request_irq); - -void free_irq(unsigned int irq, void *dev_id) -{ - if (irq >= NR_IRQS) - return; - - if (!irq_list[irq] || irq_list[irq]->dev_id != dev_id) - printk(KERN_WARNING "Removing probably wrong IRQ %d from %s\n", - irq, irq_list[irq]->devname); - disable_irq(irq); - h8300_disable_irq_pin(irq); - if (((unsigned long)irq_list[irq] & 0x80000000) == 0) { - kfree(irq_list[irq]); - irq_list[irq] = NULL; - } -} - -EXPORT_SYMBOL(free_irq); - -/* - * Do we need these probe functions on the m68k? - */ -unsigned long probe_irq_on (void) -{ - return 0; -} - -EXPORT_SYMBOL(probe_irq_on); - -int probe_irq_off (unsigned long irqs) -{ - return 0; -} - -EXPORT_SYMBOL(probe_irq_off); - -void enable_irq(unsigned int irq) -{ - if (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS)) - IER_REGS |= 1 << (irq - EXT_IRQ0); -} - -void disable_irq(unsigned int irq) -{ - if (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS)) - IER_REGS &= ~(1 << (irq - EXT_IRQ0)); -} - -asmlinkage void process_int(int irq, struct pt_regs *fp) -{ - irq_enter(); - h8300_clear_isr(irq); - if (irq >= NR_TRAPS && irq < NR_IRQS) { - if (irq_list[irq]) { - irq_list[irq]->handler(irq, irq_list[irq]->dev_id, fp); - irq_list[irq]->count++; - if (irq_list[irq]->flags & IRQF_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - } - } else { - BUG(); - } - irq_exit(); -} - -int show_interrupts(struct seq_file *p, void *v) -{ - int i = *(loff_t *) v; - - if ((i < NR_IRQS) && (irq_list[i]!=NULL)) { - seq_printf(p, "%3d: %10u ",i,irq_list[i]->count); - seq_printf(p, "%s\n", irq_list[i]->devname); - } - - return 0; -} - -void init_irq_proc(void) -{ -} - -static int __init enable_kmalloc(void) -{ - use_kmalloc = 1; - return 0; -} -core_initcall(enable_kmalloc); diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c index 8f2411db7ea..8a7a991b8f7 100644 --- a/arch/h8300/kernel/ptrace.c +++ b/arch/h8300/kernel/ptrace.c @@ -219,7 +219,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) return ret; } -asmlinkage void syscall_trace(void) +asmlinkage void do_syscall_trace(void) { if (!test_thread_flag(TIF_SYSCALL_TRACE)) return; diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c index 02955604d76..62ea12d339b 100644 --- a/arch/h8300/kernel/signal.c +++ b/arch/h8300/kernel/signal.c @@ -547,3 +547,9 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset) } return 0; } + +asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) +{ + if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) + do_signal(regs, NULL); +} diff --git a/arch/h8300/platform/h8300h/Makefile b/arch/h8300/platform/h8300h/Makefile index b24ea08aa0a..c5096369ea5 100644 --- a/arch/h8300/platform/h8300h/Makefile +++ b/arch/h8300/platform/h8300h/Makefile @@ -4,4 +4,4 @@ # Reuse any files we can from the H8/300H # -obj-y := entry.o irq_pin.o ptrace_h8300h.o +obj-y := irq_pin.o ptrace_h8300h.o diff --git a/arch/h8300/platform/h8300h/entry.S b/arch/h8300/platform/h8300h/entry.S deleted file mode 100644 index f86ac3b5d4d..00000000000 --- a/arch/h8300/platform/h8300h/entry.S +++ /dev/null @@ -1,332 +0,0 @@ -/* -*- mode: asm -*- - * - * linux/arch/h8300/platform/h8300h/entry.S - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * David McCullough <davidm@snapgear.com> - * - */ - -/* - * entry.S - * include exception/interrupt gateway - * system call entry - */ - -#include <linux/sys.h> -#include <asm/unistd.h> -#include <asm/setup.h> -#include <asm/segment.h> -#include <asm/linkage.h> -#include <asm/asm-offsets.h> -#include <asm/thread_info.h> -#include <asm/errno.h> - - .h8300h - -/* CPU context save/restore macros. */ - - .macro SAVE_ALL - mov.l er0,@-sp - - stc ccr,r0l /* check kernel mode */ - btst #4,r0l - bne 5f - - mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */ - mov.l @sp,er0 - orc #0x10,ccr - mov.l @SYMBOL_NAME(sw_ksp),sp - sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */ - mov.l er0,@-sp - mov.l er1,@-sp - mov.l @SYMBOL_NAME(sw_usp),er0 - mov.l @(8:16,er0),er1 /* copy the RET addr */ - mov.l er1,@(LRET-LER1:16,sp) - - mov.w e1,r1 /* e1 highbyte = ccr */ - and #0xef,r1h /* mask mode? flag */ - sub.w r0,r0 - mov.b r1h,r0l - mov.w r0,@(LCCR-LER1:16,sp) /* copy ccr */ - mov.l @(LORIG-LER1:16,sp),er0 - mov.l er0,@(LER0-LER1:16,sp) /* copy ER0 */ - bra 6f -5: - mov.l @sp,er0 /* kernel mode */ - subs #2,sp /* dummy ccr */ - mov.l er0,@-sp - mov.l er1,@-sp - mov.w @(LRET-LER1:16,sp),r1 /* copy old ccr */ - mov.b r1h,r1l - mov.b #0,r1h - mov.w r1,@(LCCR-LER1:16,sp) /* set ccr */ -6: - mov.l er2,@-sp - mov.l er3,@-sp - mov.l er6,@-sp /* syscall arg #6 */ - mov.l er5,@-sp /* syscall arg #5 */ - mov.l er4,@-sp /* syscall arg #4 */ - .endm - - .macro RESTORE_ALL - mov.l @sp+,er4 - mov.l @sp+,er5 - mov.l @sp+,er6 - mov.l @sp+,er3 - mov.l @sp+,er2 - mov.w @(LCCR-LER1:16,sp),r0 /* check kernel mode */ - btst #4,r0l - bne 7f - - orc #0x80,ccr - mov.l @SYMBOL_NAME(sw_usp),er0 - mov.l @(LER0-LER1:16,sp),er1 /* restore ER0 */ - mov.l er1,@er0 - mov.w @(LCCR-LER1:16,sp),r1 /* restore the RET addr */ - mov.b r1l,r1h - mov.b @(LRET+1-LER1:16,sp),r1l - mov.w r1,e1 - mov.w @(LRET+2-LER1:16,sp),r1 - mov.l er1,@(8:16,er0) - - mov.l @sp+,er1 - add.l #(LRET-LER1),sp /* remove LORIG - LRET */ - mov.l sp,@SYMBOL_NAME(sw_ksp) - mov.l er0,sp - bra 8f -7: - mov.l @sp+,er1 - adds #4,sp - adds #2,sp -8: - mov.l @sp+,er0 - adds #4,sp /* remove the sw created LVEC */ - rte - .endm - -.globl SYMBOL_NAME(system_call) -.globl SYMBOL_NAME(ret_from_exception) -.globl SYMBOL_NAME(ret_from_fork) -.globl SYMBOL_NAME(ret_from_interrupt) -.globl SYMBOL_NAME(interrupt_redirect_table) -.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp) -.globl SYMBOL_NAME(resume) -.globl SYMBOL_NAME(interrupt_redirect_table) -.globl SYMBOL_NAME(interrupt_entry) -.globl SYMBOL_NAME(system_call) -.globl SYMBOL_NAME(trace_break) - -#if defined(CONFIG_ROMKERNEL) -INTERRUPTS = 64 - .section .int_redirect,"ax" -SYMBOL_NAME_LABEL(interrupt_redirect_table) - .rept 7 - .long 0 - .endr - jsr @SYMBOL_NAME(interrupt_entry) /* NMI */ - jmp @SYMBOL_NAME(system_call) /* TRAPA #0 (System call) */ - .long 0 - .long 0 - jmp @SYMBOL_NAME(trace_break) /* TRAPA #3 (breakpoint) */ - .rept INTERRUPTS-12 - jsr @SYMBOL_NAME(interrupt_entry) - .endr -#endif -#if defined(CONFIG_RAMKERNEL) -.globl SYMBOL_NAME(interrupt_redirect_table) - .section .bss -SYMBOL_NAME_LABEL(interrupt_redirect_table) - .space 4 -#endif - - .section .text - .align 2 -SYMBOL_NAME_LABEL(interrupt_entry) - SAVE_ALL - mov.w @(LCCR,sp),r0 - btst #4,r0l - bne 1f - mov.l @SYMBOL_NAME(sw_usp),er0 - mov.l @(4:16,er0),er0 - bra 2f -1: - mov.l @(LVEC,sp),er0 -2: -#if defined(CONFIG_ROMKERNEL) - sub.l #SYMBOL_NAME(interrupt_redirect_table),er0 -#endif -#if defined(CONFIG_RAMKERNEL) - mov.l @SYMBOL_NAME(interrupt_redirect_table),er1 - sub.l er1,er0 -#endif - shlr.l er0 - shlr.l er0 - dec.l #1,er0 - mov.l sp,er1 - subs #4,er1 /* adjust ret_pc */ - jsr @SYMBOL_NAME(do_IRQ) - mov.l @SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,er0 - beq 1f - jsr @SYMBOL_NAME(do_softirq) -1: - jmp @SYMBOL_NAME(ret_from_interrupt) - -SYMBOL_NAME_LABEL(system_call) - subs #4,sp /* dummy LVEC */ - SAVE_ALL - mov.w @(LCCR:16,sp),r1 - bset #4,r1l - ldc r1l,ccr - mov.l er0,er4 - mov.l #-ENOSYS,er0 - mov.l er0,@(LER0:16,sp) - - /* save top of frame */ - mov.l sp,er0 - jsr @SYMBOL_NAME(set_esp0) - cmp.l #NR_syscalls,er4 - bcc SYMBOL_NAME(ret_from_exception):16 - shll.l er4 - shll.l er4 - mov.l #SYMBOL_NAME(sys_call_table),er0 - add.l er4,er0 - mov.l @er0,er4 - beq SYMBOL_NAME(ret_from_exception):16 - mov.l sp,er2 - and.w #0xe000,r2 - mov.b @((TASK_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l - btst #(TIF_SYSCALL_TRACE & 7),r2l - bne 1f - mov.l @(LER1:16,sp),er0 - mov.l @(LER2:16,sp),er1 - mov.l @(LER3:16,sp),er2 - jsr @er4 - mov.l er0,@(LER0:16,sp) /* save the return value */ -#if defined(CONFIG_SYSCALL_PRINT) - jsr @SYMBOL_NAME(syscall_print) -#endif - bra SYMBOL_NAME(ret_from_exception):8 -1: - jsr SYMBOL_NAME(syscall_trace) - mov.l @(LER1:16,sp),er0 - mov.l @(LER2:16,sp),er1 - mov.l @(LER3:16,sp),er2 - jsr @er4 - mov.l er0,@(LER0:16,sp) /* save the return value */ - jsr @SYMBOL_NAME(syscall_trace) - bra SYMBOL_NAME(ret_from_exception):8 - -SYMBOL_NAME_LABEL(ret_from_fork) - mov.l er2,er0 - jsr @SYMBOL_NAME(schedule_tail) - bra SYMBOL_NAME(ret_from_exception):8 - -SYMBOL_NAME_LABEL(reschedule) - /* save top of frame */ - mov.l sp,er0 - jsr @SYMBOL_NAME(set_esp0) - jsr @SYMBOL_NAME(schedule) - -SYMBOL_NAME_LABEL(ret_from_exception) -#if defined(CONFIG_PREEMPT) - orc #0x80,ccr -#endif -SYMBOL_NAME_LABEL(ret_from_interrupt) - mov.b @(LCCR+1:16,sp),r0l - btst #4,r0l /* check if returning to kernel */ - bne done:8 /* if so, skip resched, signals */ - andc #0x7f,ccr - mov.l sp,er4 - and.w #0xe000,r4 - mov.l @(TI_FLAGS:16,er4),er1 - and.l #_TIF_WORK_MASK,er1 - beq done:8 -1: - mov.l @(TI_FLAGS:16,er4),er1 - btst #TIF_NEED_RESCHED,r1l - bne SYMBOL_NAME(reschedule):16 - mov.l sp,er0 - subs #4,er0 /* adjust retpc */ - mov.l er2,er1 - jsr @SYMBOL_NAME(do_signal) -#if defined(CONFIG_PREEMPT) - bra done:8 /* userspace thoru */ -3: - btst #4,r0l - beq done:8 /* userspace thoru */ -4: - mov.l @(TI_PRE_COUNT:16,er4),er1 - bne done:8 - mov.l @(TI_FLAGS:16,er4),er1 - btst #TIF_NEED_RESCHED,r1l - beq done:8 - mov.b r0l,r0l - bpl done:8 /* interrupt off (exception path?) */ - mov.l #PREEMPT_ACTIVE,er1 - mov.l er1,@(TI_PRE_COUNT:16,er4) - andc #0x7f,ccr - jsr @SYMBOL_NAME(schedule) - sub.l er1,er1 - mov.l er1,@(TI_PRE_COUNT:16,er4) - orc #0x80,ccr - bra 4b:8 -#endif -done: - RESTORE_ALL /* Does RTE */ - -SYMBOL_NAME_LABEL(resume) - /* - * Beware - when entering resume, offset of tss is in d1, - * prev (the current task) is in a0, next (the new task) - * is in a1 and d2.b is non-zero if the mm structure is - * shared between the tasks, so don't change these - * registers until their contents are no longer needed. - */ - - /* save sr */ - sub.w r3,r3 - stc ccr,r3l - mov.w r3,@(THREAD_CCR+2:16,er0) - - /* disable interrupts */ - orc #0x80,ccr - mov.l @SYMBOL_NAME(sw_usp),er3 - mov.l er3,@(THREAD_USP:16,er0) - mov.l sp,@(THREAD_KSP:16,er0) - - /* Skip address space switching if they are the same. */ - /* FIXME: what did we hack out of here, this does nothing! */ - - mov.l @(THREAD_USP:16,er1),er0 - mov.l er0,@SYMBOL_NAME(sw_usp) - mov.l @(THREAD_KSP:16,er1),sp - - /* restore status register */ - mov.w @(THREAD_CCR+2:16,er1),r3 - - ldc r3l,ccr - rts - -SYMBOL_NAME_LABEL(trace_break) - subs #4,sp - SAVE_ALL - sub.l er1,er1 - dec.l #1,er1 - mov.l er1,@(LORIG,sp) - mov.l sp,er0 - jsr @SYMBOL_NAME(set_esp0) - mov.l @SYMBOL_NAME(sw_usp),er0 - mov.l @er0,er1 - subs #2,er1 - mov.l er1,@er0 - and.w #0xff,e1 - mov.l er1,er0 - jsr @SYMBOL_NAME(trace_trap) - jmp @SYMBOL_NAME(ret_from_exception) - - .section .bss -SYMBOL_NAME_LABEL(sw_ksp) - .space 4 -SYMBOL_NAME_LABEL(sw_usp) - .space 4 diff --git a/arch/h8300/platform/h8s/Makefile b/arch/h8300/platform/h8s/Makefile index 0847b15d425..bf124188376 100644 --- a/arch/h8300/platform/h8s/Makefile +++ b/arch/h8300/platform/h8s/Makefile @@ -4,4 +4,4 @@ # Reuse any files we can from the H8S # -obj-y := entry.o ints_h8s.o ptrace_h8s.o +obj-y := ints_h8s.o ptrace_h8s.o diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index b1b2b30b1b8..8531a540ca8 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -1212,8 +1212,12 @@ source "drivers/Kconfig" source "fs/Kconfig" -menu "Instrumentation Support" +menuconfig INSTRUMENTATION + bool "Instrumentation Support" depends on EXPERIMENTAL + default y + +if INSTRUMENTATION source "arch/i386/oprofile/Kconfig" @@ -1226,7 +1230,8 @@ config KPROBES a probepoint and specifies the callback. Kprobes is useful for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". -endmenu + +endif # INSTRUMENTATION source "arch/i386/Kconfig.debug" diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index f74dfc419b5..82714668d43 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -168,6 +168,12 @@ page_pde_offset = (__PAGE_OFFSET >> 20); .section .init.text,"ax",@progbits #endif + /* Do an early initialization of the fixmap area */ + movl $(swapper_pg_dir - __PAGE_OFFSET), %edx + movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax + addl $0x007, %eax /* 0x007 = PRESENT+RW+USER */ + movl %eax, 4092(%edx) + #ifdef CONFIG_SMP ENTRY(startup_32_smp) cld @@ -507,6 +513,8 @@ ENTRY(_stext) .section ".bss.page_aligned","w" ENTRY(swapper_pg_dir) .fill 1024,4,0 +ENTRY(swapper_pg_pmd) + .fill 1024,4,0 ENTRY(empty_zero_page) .fill 4096,1,0 diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 06dfa65ad18..6c49acb9698 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -538,8 +538,31 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) return 1; } -static noinline void __switch_to_xtra(struct task_struct *next_p, - struct tss_struct *tss) +#ifdef CONFIG_SECCOMP +void hard_disable_TSC(void) +{ + write_cr4(read_cr4() | X86_CR4_TSD); +} +void disable_TSC(void) +{ + preempt_disable(); + if (!test_and_set_thread_flag(TIF_NOTSC)) + /* + * Must flip the CPU state synchronously with + * TIF_NOTSC in the current running context. + */ + hard_disable_TSC(); + preempt_enable(); +} +void hard_enable_TSC(void) +{ + write_cr4(read_cr4() & ~X86_CR4_TSD); +} +#endif /* CONFIG_SECCOMP */ + +static noinline void +__switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, + struct tss_struct *tss) { struct thread_struct *next; @@ -555,6 +578,17 @@ static noinline void __switch_to_xtra(struct task_struct *next_p, set_debugreg(next->debugreg[7], 7); } +#ifdef CONFIG_SECCOMP + if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ + test_tsk_thread_flag(next_p, TIF_NOTSC)) { + /* prev and next are different */ + if (test_tsk_thread_flag(next_p, TIF_NOTSC)) + hard_disable_TSC(); + else + hard_enable_TSC(); + } +#endif + if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { /* * Disable the bitmap via an invalid offset. We still cache @@ -586,33 +620,6 @@ static noinline void __switch_to_xtra(struct task_struct *next_p, } /* - * This function selects if the context switch from prev to next - * has to tweak the TSC disable bit in the cr4. - */ -static inline void disable_tsc(struct task_struct *prev_p, - struct task_struct *next_p) -{ - struct thread_info *prev, *next; - - /* - * gcc should eliminate the ->thread_info dereference if - * has_secure_computing returns 0 at compile time (SECCOMP=n). - */ - prev = task_thread_info(prev_p); - next = task_thread_info(next_p); - - if (has_secure_computing(prev) || has_secure_computing(next)) { - /* slow path here */ - if (has_secure_computing(prev) && - !has_secure_computing(next)) { - write_cr4(read_cr4() & ~X86_CR4_TSD); - } else if (!has_secure_computing(prev) && - has_secure_computing(next)) - write_cr4(read_cr4() | X86_CR4_TSD); - } -} - -/* * switch_to(x,yn) should switch tasks from x to y. * * We fsave/fwait so that an exception goes off at the right time @@ -689,11 +696,9 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas /* * Now maybe handle debug registers and/or IO bitmaps */ - if (unlikely((task_thread_info(next_p)->flags & _TIF_WORK_CTXSW) - || test_tsk_thread_flag(prev_p, TIF_IO_BITMAP))) - __switch_to_xtra(next_p, tss); - - disable_tsc(prev_p, next_p); + if (unlikely(task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV || + task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT)) + __switch_to_xtra(prev_p, next_p, tss); /* * Leave lazy mode, flushing any hypercalls made here. diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 90da0575fcf..28bd1c5163e 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -390,7 +390,7 @@ void die(const char * str, struct pt_regs * regs, long err) unsigned long esp; unsigned short ss; - report_bug(regs->eip); + report_bug(regs->eip, regs); printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); #ifdef CONFIG_PREEMPT diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c index c05bda66236..6f4d3d06f0e 100644 --- a/arch/ia64/ia32/binfmt_elf32.c +++ b/arch/ia64/ia32/binfmt_elf32.c @@ -261,7 +261,7 @@ elf32_set_personality (void) } static unsigned long -elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type) +elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused) { unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK; diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S index 99b665e2b1d..06efd1f9b80 100644 --- a/arch/ia64/ia32/ia32_entry.S +++ b/arch/ia64/ia32/ia32_entry.S @@ -304,7 +304,7 @@ ia32_syscall_table: data8 sys_ni_syscall /* init_module */ data8 sys_ni_syscall /* delete_module */ data8 sys_ni_syscall /* get_kernel_syms */ /* 130 */ - data8 sys_quotactl + data8 sys32_quotactl data8 sys_getpgid data8 sys_fchdir data8 sys_ni_syscall /* sys_bdflush */ diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 188fb73c684..4d9864cc92c 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -390,10 +390,6 @@ early_console_setup (char *cmdline) if (!efi_setup_pcdp_console(cmdline)) earlycons++; #endif -#ifdef CONFIG_SERIAL_8250_CONSOLE - if (!early_serial_console_init(cmdline)) - earlycons++; -#endif return (earlycons) ? 0 : -1; } diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index c3bb8a755b0..8ccf3e47bff 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -31,6 +31,9 @@ config GENERIC_IRQ_PROBE config NO_IOPORT def_bool y +config NO_DMA + def_bool y + source "init/Kconfig" diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index 941955dc3b7..846f9753468 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c @@ -377,7 +377,7 @@ unsigned long get_wchan(struct task_struct *p) fp = ((struct switch_stack *)p->thread.ksp)->a6; do { if (fp < stack_page+sizeof(struct thread_info) || - fp >= 8184+stack_page) + fp >= THREAD_SIZE-8+stack_page) return 0; pc = ((unsigned long *)fp)[1]; if (!in_sched_functions(pc)) diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c index 8133b104735..80f4e9d74ac 100644 --- a/arch/m68knommu/kernel/setup.c +++ b/arch/m68knommu/kernel/setup.c @@ -1,8 +1,8 @@ /* * linux/arch/m68knommu/kernel/setup.c * - * Copyright (C) 1999-2004 Greg Ungerer (gerg@snapgear.com) - * Copyright (C) 1998,1999 D. Jeff Dionne <jeff@lineo.ca> + * Copyright (C) 1999-2007 Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 1998,1999 D. Jeff Dionne <jeff@uClinux.org> * Copyleft ()) 2000 James D. Schettine {james@telos-systems.com} * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com> * Copyright (C) 1995 Hamish Macdonald @@ -20,17 +20,13 @@ #include <linux/sched.h> #include <linux/delay.h> #include <linux/interrupt.h> -#include <linux/fs.h> #include <linux/fb.h> #include <linux/module.h> #include <linux/console.h> -#include <linux/genhd.h> #include <linux/errno.h> #include <linux/string.h> -#include <linux/major.h> #include <linux/bootmem.h> #include <linux/seq_file.h> -#include <linux/root_dev.h> #include <linux/init.h> #include <asm/setup.h> @@ -46,34 +42,19 @@ EXPORT_SYMBOL(memory_end); char __initdata command_line[COMMAND_LINE_SIZE]; -/* setup some dummy routines */ -static void dummy_waitbut(void) -{ -} +void (*mach_trap_init)(void); -void (*mach_sched_init) (irq_handler_t handler); -void (*mach_tick)( void ); -/* machine dependent keyboard functions */ -int (*mach_keyb_init) (void); -int (*mach_kbdrate) (struct kbd_repeat *); -void (*mach_kbd_leds) (unsigned int); -/* machine dependent irq functions */ -void (*mach_init_IRQ) (void); -irq_handler_t mach_default_handler; -int (*mach_get_irq_list) (struct seq_file *, void *); -void (*mach_process_int) (int irq, struct pt_regs *fp); -void (*mach_trap_init) (void); /* machine dependent timer functions */ -unsigned long (*mach_gettimeoffset) (void); -void (*mach_gettod) (int*, int*, int*, int*, int*, int*); -int (*mach_hwclk) (int, struct rtc_time*); -int (*mach_set_clock_mmss) (unsigned long); -void (*mach_mksound)( unsigned int count, unsigned int ticks ); -void (*mach_reset)( void ); -void (*waitbut)(void) = dummy_waitbut; -void (*mach_debug_init)(void); -void (*mach_halt)( void ); -void (*mach_power_off)( void ); +void (*mach_sched_init)(irq_handler_t handler); +void (*mach_tick)(void); +void (*mach_gettod)(int*, int*, int*, int*, int*, int*); +int (*mach_set_clock_mmss)(unsigned long); +unsigned long (*mach_gettimeoffset)(void); + +/* machine dependent reboot functions */ +void (*mach_reset)(void); +void (*mach_halt)(void); +void (*mach_power_off)(void); #ifdef CONFIG_M68000 @@ -134,13 +115,6 @@ void (*mach_power_off)( void ); #define CPU "UNKNOWN" #endif -/* (es) */ -/* note: why is this defined here? the must be a better place to put this */ -#if defined( CONFIG_TELOS) || defined( CONFIG_UCDIMM ) || defined( CONFIG_UCSIMM ) || defined(CONFIG_DRAGEN2) || (defined( CONFIG_PILOT ) && defined( CONFIG_M68328 )) -#define CAT_ROMARRAY -#endif -/* (/es) */ - extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end; extern int _ramstart, _ramend; @@ -148,15 +122,8 @@ void setup_arch(char **cmdline_p) { int bootmap_size; -#if defined(CAT_ROMARRAY) && defined(DEBUG) - extern int __data_rom_start; - extern int __data_start; - int *romarray = (int *)((int) &__data_rom_start + - (int)&_edata - (int)&__data_start); -#endif - memory_start = PAGE_ALIGN(_ramstart); - memory_end = _ramend; /* by now the stack is part of the init task */ + memory_end = _ramend; init_mm.start_code = (unsigned long) &_stext; init_mm.end_code = (unsigned long) &_etext; @@ -220,11 +187,7 @@ void setup_arch(char **cmdline_p) (int) &_sbss, (int) &_ebss); printk(KERN_DEBUG "KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x " "STACK=0x%06x-0x%06x\n", -#ifdef CAT_ROMARRAY - (int) romarray, ((int) romarray) + romarray[2], -#else (int) &_ebss, (int) memory_start, -#endif (int) memory_start, (int) memory_end, (int) memory_end, (int) _ramend); #endif diff --git a/arch/m68knommu/mm/memory.c b/arch/m68knommu/mm/memory.c index 411e45248e5..1a66b71035a 100644 --- a/arch/m68knommu/mm/memory.c +++ b/arch/m68knommu/mm/memory.c @@ -17,90 +17,14 @@ #include <linux/types.h> #include <linux/slab.h> -#include <asm/setup.h> #include <asm/segment.h> #include <asm/page.h> #include <asm/pgtable.h> #include <asm/system.h> -#include <asm/traps.h> -#include <asm/io.h> /* - * cache_clear() semantics: Clear any cache entries for the area in question, - * without writing back dirty entries first. This is useful if the data will - * be overwritten anyway, e.g. by DMA to memory. The range is defined by a - * _physical_ address. - */ - -void cache_clear (unsigned long paddr, int len) -{ -} - - -/* - * Define cache invalidate functions. The ColdFire 5407 is really - * the only processor that needs to do some work here. Anything - * that has separate data and instruction caches will be a problem. - */ -#ifdef CONFIG_M5407 - -static __inline__ void cache_invalidate_lines(unsigned long paddr, int len) -{ - unsigned long sset, eset; - - sset = (paddr & 0x00000ff0); - eset = ((paddr + len) & 0x0000ff0) + 0x10; - - __asm__ __volatile__ ( - "nop\n\t" - "clrl %%d0\n\t" - "1:\n\t" - "movel %0,%%a0\n\t" - "addl %%d0,%%a0\n\t" - "2:\n\t" - ".word 0xf4e8\n\t" - "addl #0x10,%%a0\n\t" - "cmpl %1,%%a0\n\t" - "blt 2b\n\t" - "addql #1,%%d0\n\t" - "cmpil #4,%%d0\n\t" - "bne 1b" - : : "a" (sset), "a" (eset) : "d0", "a0" ); -} - -#else -#define cache_invalidate_lines(a,b) -#endif - - -/* - * cache_push() semantics: Write back any dirty cache data in the given area, - * and invalidate the range in the instruction cache. It needs not (but may) - * invalidate those entries also in the data cache. The range is defined by a - * _physical_ address. - */ - -void cache_push (unsigned long paddr, int len) -{ - cache_invalidate_lines(paddr, len); -} - - -/* - * cache_push_v() semantics: Write back any dirty cache data in the given - * area, and invalidate those entries at least in the instruction cache. This - * is intended to be used after data has been written that can be executed as - * code later. The range is defined by a _user_mode_ _virtual_ address (or, - * more exactly, the space is defined by the %sfc/%dfc register.) - */ - -void cache_push_v (unsigned long vaddr, int len) -{ - cache_invalidate_lines(vaddr, len); -} - -/* Map some physical address range into the kernel address space. The - * code is copied and adapted from map_chunk(). + * Map some physical address range into the kernel address space. + * The code is copied and adapted from map_chunk(). */ unsigned long kernel_map(unsigned long paddr, unsigned long size, diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index c3ec9f1ec0f..f9bca2d74b3 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -302,7 +302,7 @@ static void handle_break(struct pt_regs *regs) if (unlikely(iir == PARISC_BUG_BREAK_INSN && !user_mode(regs))) { /* check if a BUG() or WARN() trapped here. */ enum bug_trap_type tt; - tt = report_bug(regs->iaoq[0] & ~3); + tt = report_bug(regs->iaoq[0] & ~3, regs); if (tt == BUG_TRAP_TYPE_WARN) { regs->iaoq[0] += 4; regs->iaoq[1] += 4; diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 6beee32144c..6b8b83ebca7 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -66,6 +66,9 @@ config GENERIC_FIND_NEXT_BIT bool default y +config ARCH_NO_VIRT_TO_BUS + def_bool PPC64 + config PPC bool default y diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index bf6445ac9f1..3b8427e6283 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -777,7 +777,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) return; if (!(regs->msr & MSR_PR) && /* not user-mode */ - report_bug(regs->nip) == BUG_TRAP_TYPE_WARN) { + report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { regs->nip += 4; return; } diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index aea100be52c..0eaef7c8378 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -619,7 +619,7 @@ void program_check_exception(struct pt_regs *regs) return; if (!(regs->msr & MSR_PR) && /* not user-mode */ - report_bug(regs->nip) == BUG_TRAP_TYPE_WARN) { + report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { regs->nip += 4; return; } diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index ee9186f8fb0..81e03b9c384 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -319,7 +319,7 @@ static void __kprobes inline do_trap(long interruption_code, int signr, else { enum bug_trap_type btt; - btt = report_bug(regs->psw.addr & PSW_ADDR_INSN); + btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs); if (btt == BUG_TRAP_TYPE_WARN) return; die(str, regs, interruption_code); diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 038179ecf6a..d8ed6676ae8 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 @@ -81,24 +94,146 @@ source "init/Kconfig" menu "System type" -config SOLUTION_ENGINE - bool +source "arch/sh/mm/Kconfig" + +menu "Processor features" choice - prompt "SuperH system type" - default SH_UNKNOWN + prompt "Endianess selection" + default CPU_LITTLE_ENDIAN + help + Some SuperH machines can be configured for either little or big + endian byte order. These modes require different kernels. + +config CPU_LITTLE_ENDIAN + bool "Little Endian" + +config CPU_BIG_ENDIAN + bool "Big Endian" + +endchoice + +config SH_FPU + bool "FPU support" + depends on CPU_SH4 + default y + help + Selecting this option will enable support for SH processors that + have FPU units (ie, SH77xx). + + This option must be set in order to enable the FPU. + +config SH_FPU_EMU + bool "FPU emulation support" + depends on !SH_FPU && EXPERIMENTAL + default n + help + Selecting this option will enable support for software FPU emulation. + Most SH-3 users will want to say Y here, whereas most SH-4 users will + want to say N. + +config SH_DSP + bool "DSP support" + default y if SH4AL_DSP || !CPU_SH4 + default n + help + Selecting this option will enable support for SH processors that + have DSP units (ie, SH2-DSP, SH3-DSP, and SH4AL-DSP). + + This option must be set in order to enable the DSP. + +config SH_ADC + bool "ADC support" + depends on CPU_SH3 + default y + help + Selecting this option will allow the Linux kernel to use SH3 on-chip + ADC module. + + If unsure, say N. + +config SH_STORE_QUEUES + bool "Support for Store Queues" + depends on CPU_SH4 + help + Selecting this option will enable an in-kernel API for manipulating + the store queues integrated in the SH-4 processors. + +config SPECULATIVE_EXECUTION + bool "Speculative subroutine return" + depends on CPU_SUBTYPE_SH7780 && EXPERIMENTAL + help + This enables support for a speculative instruction fetch for + subroutine return. There are various pitfalls associated with + this, as outlined in the SH7780 hardware manual. + + If unsure, say N. + +config CPU_HAS_INTEVT + bool + +config CPU_HAS_PINT_IRQ + bool + +config CPU_HAS_MASKREG_IRQ + bool + +config CPU_HAS_INTC2_IRQ + bool + +config CPU_HAS_IPR_IRQ + bool + +config CPU_HAS_SR_RB + bool "CPU has SR.RB" + depends on CPU_SH3 || CPU_SH4 + default y + help + This will enable the use of SR.RB register bank usage. Processors + that are lacking this bit must have another method in place for + accomplishing what is taken care of by the banked registers. + + See <file:Documentation/sh/register-banks.txt> for further + information on SR.RB and register banking in the kernel in general. + +config CPU_HAS_PTEA + bool + +endmenu + +menu "Board support" + +config SOLUTION_ENGINE + bool config SH_SOLUTION_ENGINE bool "SolutionEngine" select SOLUTION_ENGINE + depends on CPU_SUBTYPE_SH7709 || CPU_SUBTYPE_SH7750 help Select SolutionEngine if configuring for a Hitachi SH7709 or SH7750 evaluation board. +config SH_7206_SOLUTION_ENGINE + bool "SolutionEngine7206" + select SOLUTION_ENGINE + depends on CPU_SUBTYPE_SH7206 + help + Select 7206 SolutionEngine if configuring for a Hitachi SH7206 + evaluation board. + +config SH_7619_SOLUTION_ENGINE + bool "SolutionEngine7619" + select SOLUTION_ENGINE + depends on CPU_SUBTYPE_SH7619 + help + Select 7619 SolutionEngine if configuring for a Hitachi SH7619 + evaluation board. + config SH_7722_SOLUTION_ENGINE bool "SolutionEngine7722" select SOLUTION_ENGINE - select CPU_SUBTYPE_SH7722 + depends on CPU_SUBTYPE_SH7722 help Select 7722 SolutionEngine if configuring for a Hitachi SH772 evaluation board. @@ -106,7 +241,7 @@ config SH_7722_SOLUTION_ENGINE config SH_7751_SOLUTION_ENGINE bool "SolutionEngine7751" select SOLUTION_ENGINE - select CPU_SUBTYPE_SH7751 + depends on CPU_SUBTYPE_SH7751 help Select 7751 SolutionEngine if configuring for a Hitachi SH7751 evaluation board. @@ -114,7 +249,8 @@ config SH_7751_SOLUTION_ENGINE config SH_7780_SOLUTION_ENGINE bool "SolutionEngine7780" select SOLUTION_ENGINE - select CPU_SUBTYPE_SH7780 + select SYS_SUPPORTS_PCI + depends on CPU_SUBTYPE_SH7780 help Select 7780 SolutionEngine if configuring for a Renesas SH7780 evaluation board. @@ -122,7 +258,7 @@ config SH_7780_SOLUTION_ENGINE config SH_7300_SOLUTION_ENGINE bool "SolutionEngine7300" select SOLUTION_ENGINE - select CPU_SUBTYPE_SH7300 + depends on CPU_SUBTYPE_SH7300 help Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V) evaluation board. @@ -130,22 +266,22 @@ config SH_7300_SOLUTION_ENGINE config SH_7343_SOLUTION_ENGINE bool "SolutionEngine7343" select SOLUTION_ENGINE - select CPU_SUBTYPE_SH7343 + depends on CPU_SUBTYPE_SH7343 help Select 7343 SolutionEngine if configuring for a Hitachi SH7343 (SH-Mobile 3AS) evaluation board. config SH_73180_SOLUTION_ENGINE - bool "SolutionEngine73180" + bool "SolutionEngine73180" select SOLUTION_ENGINE - select CPU_SUBTYPE_SH73180 + depends on CPU_SUBTYPE_SH73180 help Select 73180 SolutionEngine if configuring for a Hitachi SH73180(SH-Mobile 3) evaluation board. config SH_7751_SYSTEMH bool "SystemH7751R" - select CPU_SUBTYPE_SH7751R + depends on CPU_SUBTYPE_SH7751R help Select SystemH if you are configuring for a Renesas SystemH 7751R evaluation board. @@ -153,20 +289,17 @@ 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 <http://www.hp.com/jornada/>. -config SH_SATURN - bool "Saturn" - select CPU_SUBTYPE_SH7604 - help - Select Saturn if configuring for a SEGA Saturn. - config SH_DREAMCAST bool "Dreamcast" - select CPU_SUBTYPE_SH7091 + select SYS_SUPPORTS_PCI + depends on CPU_SUBTYPE_SH7091 help Select Dreamcast if configuring for a SEGA Dreamcast. More information at @@ -175,6 +308,7 @@ config SH_DREAMCAST config SH_MPC1211 bool "Interface MPC1211" + depends on CPU_SUBTYPE_SH7751 && BROKEN help CTP/PCI-SH02 is a CPU module computer that is produced by Interface Corporation. @@ -182,6 +316,8 @@ 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. @@ -189,7 +325,8 @@ config SH_SH03 config SH_SECUREEDGE5410 bool "SecureEdge5410" - select CPU_SUBTYPE_SH7751R + 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 @@ -197,246 +334,76 @@ config SH_SECUREEDGE5410 config SH_HS7751RVOIP bool "HS7751RVOIP" - select CPU_SUBTYPE_SH7751R + depends on CPU_SUBTYPE_SH7751R help Select HS7751RVOIP if configuring for a Renesas Technology Sales VoIP board. config SH_7710VOIPGW bool "SH7710-VOIP-GW" - select CPU_SUBTYPE_SH7710 + depends on CPU_SUBTYPE_SH7710 help Select this option to build a kernel for the SH7710 based VOIP GW. config SH_RTS7751R2D bool "RTS7751R2D" - select CPU_SUBTYPE_SH7751R + depends on CPU_SUBTYPE_SH7751R + select SYS_SUPPORTS_PCI help Select RTS7751R2D if configuring for a Renesas Technology Sales SH-Graphics board. config SH_HIGHLANDER bool "Highlander" + depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 + select SYS_SUPPORTS_PCI config SH_EDOSK7705 bool "EDOSK7705" - select CPU_SUBTYPE_SH7705 + depends on CPU_SUBTYPE_SH7705 config SH_SH4202_MICRODEV bool "SH4-202 MicroDev" - select CPU_SUBTYPE_SH4_202 + depends on CPU_SUBTYPE_SH4_202 help Select SH4-202 MicroDev if configuring for a SuperH MicroDev board with an SH4-202 CPU. config SH_LANDISK bool "LANDISK" - select CPU_SUBTYPE_SH7751R + depends on CPU_SUBTYPE_SH7751R + select SYS_SUPPORTS_PCI help I-O DATA DEVICE, INC. "LANDISK Series" support. config SH_TITAN bool "TITAN" - select CPU_SUBTYPE_SH7751R + depends on CPU_SUBTYPE_SH7751R + select SYS_SUPPORTS_PCI help Select Titan if you are configuring for a Nimble Microsystems NetEngine NP51R. config SH_SHMIN bool "SHMIN" - select CPU_SUBTYPE_SH7706 + depends on CPU_SUBTYPE_SH7706 help Select SHMIN if configuring for the SHMIN board. -config SH_7206_SOLUTION_ENGINE - bool "SolutionEngine7206" - select CPU_SUBTYPE_SH7206 - help - Select 7206 SolutionEngine if configuring for a Hitachi SH7206 - evaluation board. - -config SH_7619_SOLUTION_ENGINE - bool "SolutionEngine7619" - select CPU_SUBTYPE_SH7619 - help - Select 7619 SolutionEngine if configuring for a Hitachi SH7619 - evaluation board. - config SH_LBOX_RE2 bool "L-BOX RE2" - select CPU_SUBTYPE_SH7751R + depends on CPU_SUBTYPE_SH7751R + select SYS_SUPPORTS_PCI help Select L-BOX RE2 if configuring for the NTT COMWARE L-BOX RE2. -config SH_UNKNOWN - bool "BareCPU" - help - "Bare CPU" aka "unknown" means an SH-based system which is not one - of the specific ones mentioned above, which means you need to enter - all sorts of stuff like CONFIG_MEMORY_START because the config - system doesn't already know what it is. You get a machine vector - without any platform-specific code in it, so things like the RTC may - not work. - - This option is for the early stages of porting to a new machine. - -endchoice +endmenu source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" source "arch/sh/boards/renesas/rts7751r2d/Kconfig" source "arch/sh/boards/renesas/r7780rp/Kconfig" -source "arch/sh/mm/Kconfig" - -config CF_ENABLER - bool "Compact Flash Enabler support" - depends on SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_SH03 - ---help--- - Compact Flash is a small, removable mass storage device introduced - in 1994 originally as a PCMCIA device. If you say `Y' here, you - compile in support for Compact Flash devices directly connected to - a SuperH processor. A Compact Flash FAQ is available at - <http://www.compactflash.org/faqs/faq.htm>. - - If your board has "Directly Connected" CompactFlash at area 5 or 6, - you may want to enable this option. Then, you can use CF as - primary IDE drive (only tested for SanDisk). - - If in doubt, select 'N'. - -choice - prompt "Compact Flash Connection Area" - depends on CF_ENABLER - default CF_AREA6 - -config CF_AREA5 - bool "Area5" - help - If your board has "Directly Connected" CompactFlash, You should - select the area where your CF is connected to. - - - "Area5" if CompactFlash is connected to Area 5 (0x14000000) - - "Area6" if it is connected to Area 6 (0x18000000) - - "Area6" will work for most boards. - -config CF_AREA6 - bool "Area6" - -endchoice - -config CF_BASE_ADDR - hex - depends on CF_ENABLER - default "0xb8000000" if CF_AREA6 - default "0xb4000000" if CF_AREA5 - -menu "Processor features" - -choice - prompt "Endianess selection" - default CPU_LITTLE_ENDIAN - help - Some SuperH machines can be configured for either little or big - endian byte order. These modes require different kernels. - -config CPU_LITTLE_ENDIAN - bool "Little Endian" - -config CPU_BIG_ENDIAN - bool "Big Endian" - -endchoice - -config SH_FPU - bool "FPU support" - depends on !CPU_SH3 - default y - help - Selecting this option will enable support for SH processors that - have FPU units (ie, SH77xx). - - This option must be set in order to enable the FPU. - -config SH_FPU_EMU - bool "FPU emulation support" - depends on !SH_FPU && EXPERIMENTAL - default n - help - Selecting this option will enable support for software FPU emulation. - Most SH-3 users will want to say Y here, whereas most SH-4 users will - want to say N. - -config SH_DSP - bool "DSP support" - default y if SH4AL_DSP || !CPU_SH4 - default n - help - Selecting this option will enable support for SH processors that - have DSP units (ie, SH2-DSP, SH3-DSP, and SH4AL-DSP). - - This option must be set in order to enable the DSP. - -config SH_ADC - bool "ADC support" - depends on CPU_SH3 - default y - help - Selecting this option will allow the Linux kernel to use SH3 on-chip - ADC module. - - If unsure, say N. - -config SH_STORE_QUEUES - bool "Support for Store Queues" - depends on CPU_SH4 - help - Selecting this option will enable an in-kernel API for manipulating - the store queues integrated in the SH-4 processors. - -config SPECULATIVE_EXECUTION - bool "Speculative subroutine return" - depends on CPU_SUBTYPE_SH7780 && EXPERIMENTAL - help - This enables support for a speculative instruction fetch for - subroutine return. There are various pitfalls associated with - this, as outlined in the SH7780 hardware manual. - - If unsure, say N. - -config CPU_HAS_INTEVT - bool - -config CPU_HAS_PINT_IRQ - bool - -config CPU_HAS_MASKREG_IRQ - bool - -config CPU_HAS_INTC2_IRQ - bool - -config CPU_HAS_IPR_IRQ - bool - -config CPU_HAS_SR_RB - bool "CPU has SR.RB" - depends on CPU_SH3 || CPU_SH4 - default y - help - This will enable the use of SR.RB register bank usage. Processors - that are lacking this bit must have another method in place for - accomplishing what is taken care of by the banked registers. - - See <file:Documentation/sh/register-banks.txt> for further - information on SR.RB and register banking in the kernel in general. - -config CPU_HAS_PTEA - bool - -endmenu - menu "Timer and clock configuration" config SH_TMU @@ -473,13 +440,13 @@ config SH_PCLK_FREQ int "Peripheral clock frequency (in Hz)" default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343 default "31250000" if CPU_SUBTYPE_SH7619 + default "32000000" if CPU_SUBTYPE_SH7722 default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \ CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \ CPU_SUBTYPE_SH7206 - default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780 || \ - CPU_SUBTYPE_SH7785 - default "60000000" if CPU_SUBTYPE_SH7751 + default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R default "66000000" if CPU_SUBTYPE_SH4_202 + default "50000000" help This option is used to specify the peripheral clock frequency. This is necessary for determining the reference clock value on @@ -487,8 +454,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. @@ -560,6 +529,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 @@ -584,6 +554,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 @@ -623,6 +594,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 @@ -651,8 +623,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 @@ -690,6 +662,49 @@ config SUPERHYWAY tristate "SuperHyway Bus support" depends on CPU_SUBTYPE_SH4_202 +config CF_ENABLER + bool "Compact Flash Enabler support" + depends on SOLUTION_ENGINE || SH_SH03 + ---help--- + Compact Flash is a small, removable mass storage device introduced + in 1994 originally as a PCMCIA device. If you say `Y' here, you + compile in support for Compact Flash devices directly connected to + a SuperH processor. A Compact Flash FAQ is available at + <http://www.compactflash.org/faqs/faq.htm>. + + If your board has "Directly Connected" CompactFlash at area 5 or 6, + you may want to enable this option. Then, you can use CF as + primary IDE drive (only tested for SanDisk). + + If in doubt, select 'N'. + +choice + prompt "Compact Flash Connection Area" + depends on CF_ENABLER + default CF_AREA6 + +config CF_AREA5 + bool "Area5" + help + If your board has "Directly Connected" CompactFlash, You should + select the area where your CF is connected to. + + - "Area5" if CompactFlash is connected to Area 5 (0x14000000) + - "Area6" if it is connected to Area 6 (0x18000000) + + "Area6" will work for most boards. + +config CF_AREA6 + bool "Area6" + +endchoice + +config CF_BASE_ADDR + hex + depends on CF_ENABLER + default "0xb8000000" if CF_AREA6 + default "0xb4000000" if CF_AREA5 + source "arch/sh/drivers/pci/Kconfig" source "drivers/pci/Kconfig" @@ -707,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 b56307294b6..52f6a99c8ec 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -52,6 +52,10 @@ config EARLY_PRINTK select both the EARLY_SCIF_CONSOLE and SH_STANDARD_BIOS, using the kernel command line option to toggle back and forth. +config DEBUG_BOOTMEM + depends on DEBUG_KERNEL + bool "Debug BOOTMEM initialization" + config DEBUG_STACKOVERFLOW bool "Check for stack overflows" depends on DEBUG_KERNEL @@ -82,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 <http://kgdb.sourceforge.net/> for more information. diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 883b03b040c..77fecc62a05 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -34,20 +34,20 @@ isa-y := $(isa-y)-nofpu endif endif -cflags-$(CONFIG_CPU_SH2) := -m2 -cflags-$(CONFIG_CPU_SH2A) := -m2a $(call cc-option,-m2a-nofpu,) -cflags-$(CONFIG_CPU_SH3) := -m3 -cflags-$(CONFIG_CPU_SH4) := -m4 \ +cflags-$(CONFIG_CPU_SH2) := $(call cc-option,-m2,) +cflags-$(CONFIG_CPU_SH2A) += $(call cc-option,-m2a,) \ + $(call cc-option,-m2a-nofpu,) +cflags-$(CONFIG_CPU_SH3) := $(call cc-option,-m3,) +cflags-$(CONFIG_CPU_SH4) := $(call cc-option,-m4,) \ $(call cc-option,-mno-implicit-fp,-m4-nofpu) -cflags-$(CONFIG_CPU_SH4A) := $(call cc-option,-m4a,) $(call cc-option,-m4a-nofpu,) +cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a,) \ + $(call cc-option,-m4a-nofpu,) cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding -cflags-$(CONFIG_SH_DSP) += -Wa,-dsp - cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \ $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g') @@ -87,39 +87,37 @@ 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_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 + +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 +155,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 @@ -188,7 +198,9 @@ compressed: zImage archclean: $(Q)$(MAKE) $(clean)=$(boot) -CLEAN_FILES += include/asm-sh/machtypes.h +CLEAN_FILES += include/asm-sh/machtypes.h \ + include/asm-sh/cpu include/asm-sh/.cpu \ + include/asm-sh/mach include/asm-sh/.mach define archhelp @echo '* zImage - Compressed kernel image' diff --git a/arch/sh/boards/dreamcast/setup.c b/arch/sh/boards/dreamcast/setup.c index f13017eeeb2..8799df6e866 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 deleted file mode 100644 index 08dbba910f7..00000000000 --- a/arch/sh/boards/hp6xx/mach.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * linux/arch/sh/boards/hp6xx/mach.c - * - * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * Machine vector for the HP680 - */ -#include <asm/machvec.h> -#include <asm/hd64461.h> -#include <asm/io.h> -#include <asm/irq.h> - -struct sh_machine_vector mv_hp6xx __initmv = { - .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM, - - .mv_inb = hd64461_inb, - .mv_inw = hd64461_inw, - .mv_inl = hd64461_inl, - .mv_outb = hd64461_outb, - .mv_outw = hd64461_outw, - .mv_outl = hd64461_outl, - - .mv_inb_p = hd64461_inb_p, - .mv_inw_p = hd64461_inw, - .mv_inl_p = hd64461_inl, - .mv_outb_p = hd64461_outb_p, - .mv_outw_p = hd64461_outw, - .mv_outl_p = hd64461_outl, - - .mv_insb = hd64461_insb, - .mv_insw = hd64461_insw, - .mv_insl = hd64461_insl, - .mv_outsb = hd64461_outsb, - .mv_outsw = hd64461_outsw, - .mv_outsl = hd64461_outsl, - - .mv_readw = hd64461_readw, - .mv_writew = hd64461_writew, - - .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 6aeee85c978..7ae708930ba 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 f953c742776..eda71763ecc 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 4e20f7c63bf..9c830fdc411 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 1a0604b23ce..8ce03e00b0a 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 ec5be010771..f076c45308d 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 f7d0e304d89..fa5fa392022 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/Kconfig b/arch/sh/boards/renesas/r7780rp/Kconfig index 9fb11641fe1..fc8f28e04ba 100644 --- a/arch/sh/boards/renesas/r7780rp/Kconfig +++ b/arch/sh/boards/renesas/r7780rp/Kconfig @@ -6,18 +6,18 @@ choice config SH_R7780RP bool "R7780RP-1 board support" - select CPU_SUBTYPE_SH7780 + depends on CPU_SUBTYPE_SH7780 config SH_R7780MP bool "R7780MP board support" - select CPU_SUBTYPE_SH7780 + depends on CPU_SUBTYPE_SH7780 help Selecting this option will enable support for the mass-production version of the R7780RP. If in doubt, say Y. config SH_R7785RP bool "R7785RP board support" - select CPU_SUBTYPE_SH7785 + depends on CPU_SUBTYPE_SH7785 endchoice diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c index 0727ef92f2b..5afb864a1ec 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 593f26a85e9..656fda30ef7 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 180810b1210..2dce8bd97f9 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 936117659b7..ee78af84277 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/Makefile b/arch/sh/boards/saturn/Makefile deleted file mode 100644 index 75a3042e252..00000000000 --- 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 c6e4f7f2e68..00000000000 --- 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 <asm/saturn/io.h> -#include <asm/machvec.h> - -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 15d1d3f0f78..00000000000 --- 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 <linux/kernel.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <asm/irq.h> -#include <asm/io.h> - -/* - * 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 a3a37c9aad2..00000000000 --- a/arch/sh/boards/saturn/setup.c +++ /dev/null @@ -1,31 +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 <linux/kernel.h> -#include <linux/init.h> -#include <asm/io.h> -#include <asm/machvec.h> -#include <asm/mach/io.h> - -extern int saturn_irq_demux(int irq_nr); - -/* - * The Machine Vector - */ -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, -}; -ALIAS_MV(saturn) diff --git a/arch/sh/boards/saturn/smp.c b/arch/sh/boards/saturn/smp.c deleted file mode 100644 index 76460918c9c..00000000000 --- 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 <linux/kernel.h> -#include <linux/init.h> -#include <linux/smp.h> - -#include <asm/saturn/smpc.h> - -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/boards/se/7206/setup.c b/arch/sh/boards/se/7206/setup.c index ca714879f55..a074b62505e 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 f1960956bad..eb469f5b6e9 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 e143017c897..1deee855664 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 3fdb16f2cef..8fec155e2ff 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 52d2c4d5d2f..1d0ef7faa10 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/irq.c b/arch/sh/boards/se/770x/irq.c index c8eccff77a0..cdb0807928a 100644 --- a/arch/sh/boards/se/770x/irq.c +++ b/arch/sh/boards/se/770x/irq.c @@ -15,46 +15,7 @@ #include <asm/io.h> #include <asm/se.h> -/* - * 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/770x/setup.c b/arch/sh/boards/se/770x/setup.c index 17a2631de3b..2962da148f3 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/irq.c b/arch/sh/boards/se/7722/irq.c index 099e5deb77f..26cff0efda4 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/7722/setup.c b/arch/sh/boards/se/7722/setup.c index 636ca6c987e..6cca6cbc806 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/irq.c b/arch/sh/boards/se/7751/irq.c index e4c63a48296..c3d12590e5d 100644 --- a/arch/sh/boards/se/7751/irq.c +++ b/arch/sh/boards/se/7751/irq.c @@ -14,44 +14,31 @@ #include <asm/irq.h> #include <asm/se7751.h> -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/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c index 52c7bfa57c2..7873d07e40c 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/irq.c b/arch/sh/boards/se/7780/irq.c index 3d0625c2d07..87491474600 100644 --- a/arch/sh/boards/se/7780/irq.c +++ b/arch/sh/boards/se/7780/irq.c @@ -16,28 +16,6 @@ #include <asm/io.h> #include <asm/se7780.h> -#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/boards/se/7780/setup.c b/arch/sh/boards/se/7780/setup.c index df7d08a24c9..723f2fd4d55 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 c069c444b4e..9c031a8c0a1 100644 --- a/arch/sh/boards/sh03/setup.c +++ b/arch/sh/boards/sh03/setup.c @@ -15,17 +15,33 @@ #include <asm/sh03/sh03.h> #include <asm/addrspace.h> -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; @@ -74,11 +90,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 4a9df4a6b03..dfd124509f4 100644 --- a/arch/sh/boards/shmin/setup.c +++ b/arch/sh/boards/shmin/setup.c @@ -6,28 +6,44 @@ * SHMIN Support. */ #include <linux/init.h> +#include <linux/irq.h> #include <asm/machvec.h> #include <asm/shmin.h> #include <asm/clock.h> -#include <asm/irq.h> #include <asm/io.h> #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) @@ -43,9 +59,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 650fb364594..84271d85a8d 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); } /* @@ -96,7 +112,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 +133,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 6396cea1c89..fc8cd06d66c 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 6bcd939bfae..606d25a4b87 100644 --- a/arch/sh/boards/titan/setup.c +++ b/arch/sh/boards/titan/setup.c @@ -12,7 +12,7 @@ #include <asm/titan.h> #include <asm/io.h> -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,15 +20,33 @@ 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); } -struct sh_machine_vector mv_titan __initmv = { +static struct sh_machine_vector mv_titan __initmv = { .mv_name = "Titan", .mv_inb = titan_inb, @@ -52,4 +70,3 @@ struct sh_machine_vector mv_titan __initmv = { .mv_init_irq = init_titan_irq, }; -ALIAS_MV(titan) diff --git a/arch/sh/boards/unknown/Makefile b/arch/sh/boards/unknown/Makefile deleted file mode 100644 index 7d18f408b0c..00000000000 --- a/arch/sh/boards/unknown/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for unknown SH boards -# - -obj-y := setup.o - diff --git a/arch/sh/boards/unknown/setup.c b/arch/sh/boards/unknown/setup.c deleted file mode 100644 index bee4612de59..00000000000 --- a/arch/sh/boards/unknown/setup.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * linux/arch/sh/boards/unknown/setup.c - * - * Copyright (C) 2002 Paul Mundt - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * Setup code for an unknown machine (internal peripherals only) - * - * This is the simplest of all boards, and serves only as a quick and dirty - * method to start debugging a new board during bring-up until proper board - * setup code is written. - */ -#include <linux/init.h> -#include <asm/machvec.h> - -struct sh_machine_vector mv_unknown __initmv = { - .mv_name = "Unknown", -}; -ALIAS_MV(unknown) diff --git a/arch/sh/cchips/Kconfig b/arch/sh/cchips/Kconfig index 0582ca8346b..2e516e9a6ed 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/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig index 8b6b5a779de..3fdd270eecf 100644 --- a/arch/sh/configs/dreamcast_defconfig +++ b/arch/sh/configs/dreamcast_defconfig @@ -1,15 +1,23 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Tue Oct 3 10:51:55 2006 +# Linux kernel version: 2.6.22-rc4 +# Sat Jul 7 03:47:45 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_SYS_SUPPORTS_PCI=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" # @@ -28,6 +36,7 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set @@ -35,8 +44,10 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" +# CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_EMBEDDED=y @@ -50,14 +61,19 @@ 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_SLAB=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 -# CONFIG_SLOB is not set # # Loadable module support @@ -93,44 +109,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # System type # -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_7343_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_EC3104 is not set -# CONFIG_SH_SATURN is not set -CONFIG_SH_DREAMCAST=y -# CONFIG_SH_BIGSUR is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_7710VOIPGW is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_R7780RP is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# CONFIG_CPU_SH4=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set - -# -# SH-3 Processor Support -# +# 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 @@ -138,79 +119,93 @@ CONFIG_CPU_SH4=y # CONFIG_CPU_SUBTYPE_SH7708 is not set # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set - -# -# SH-4 Processor Support -# -CONFIG_CPU_SUBTYPE_SH7750=y +# CONFIG_CPU_SUBTYPE_SH7712 is not set +# CONFIG_CPU_SUBTYPE_SH7750 is not set CONFIG_CPU_SUBTYPE_SH7091=y -CONFIG_CPU_SUBTYPE_SH7750R=y +# CONFIG_CPU_SUBTYPE_SH7750R is not set # CONFIG_CPU_SUBTYPE_SH7750S is not set # CONFIG_CPU_SUBTYPE_SH7751 is not set # CONFIG_CPU_SUBTYPE_SH7751R is not set # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# # CONFIG_CPU_SUBTYPE_ST40STB1 is not set # CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set - -# -# SH4AL-DSP Processor Support -# +# CONFIG_CPU_SUBTYPE_SH7785 is not set +# CONFIG_CPU_SUBTYPE_SHX3 is not set # 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=0x01000000 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 is not set +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 -# CONFIG_SH_OCRAM is not set # # Processor features # CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SH_FPU=y # CONFIG_SH_DSP is not set CONFIG_SH_STORE_QUEUES=y CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_IPR_IRQ=y CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_PTEA=y # -# Timer support +# Board support +# +CONFIG_SH_DREAMCAST=y + +# +# Timer and clock configuration # CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=16 CONFIG_SH_PCLK_FREQ=49876504 +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set # # CPU Frequency scaling @@ -232,6 +227,7 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y # # DMA support # +CONFIG_SH_DMA_API=y CONFIG_SH_DMA=y CONFIG_NR_ONCHIP_DMA_CHANNELS=4 CONFIG_NR_DMA_CHANNELS_BOOL=y @@ -240,17 +236,23 @@ CONFIG_NR_DMA_CHANNELS=9 # # Companion Chips # -# CONFIG_HD6446X_SERIES is not set + +# +# Additional SuperH Device Drivers +# +# CONFIG_HEARTBEAT is not set +# CONFIG_PUSH_SWITCH is not set # # Kernel features # # CONFIG_HZ_100 is not set CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 # CONFIG_KEXEC is not set -# CONFIG_SMP is not set +# CONFIG_CRASH_DUMP is not set # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y @@ -269,33 +271,23 @@ CONFIG_CMDLINE="console=ttySC1,115200 panic=3" # Bus options # CONFIG_PCI=y -# CONFIG_SH_PCIDMA_NONCOHERENT is not set +CONFIG_SH_PCIDMA_NONCOHERENT=y CONFIG_PCI_AUTO=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # # Executable file formats # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set # CONFIG_BINFMT_MISC is not set # -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set - -# # Networking # CONFIG_NET=y @@ -303,13 +295,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -327,30 +319,20 @@ CONFIG_IP_FIB_HASH=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -376,7 +358,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -394,10 +385,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -408,6 +395,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -421,13 +409,16 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # -# ATA/ATAPI/MFM/RLL support +# Misc devices # +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -436,10 +427,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # @@ -455,6 +442,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # @@ -470,15 +458,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# # CONFIG_ARCNET is not set - -# -# PHY device support -# # CONFIG_PHYLIB is not set # @@ -521,47 +501,16 @@ CONFIG_8139TOO=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set - -# -# Token Ring devices -# +# CONFIG_SC92031 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -604,17 +553,19 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_ATKBD is not set # 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=y -CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_PS2 is not set # CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set # CONFIG_MOUSE_VSXXXAA 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 @@ -660,10 +611,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -680,14 +627,8 @@ CONFIG_SH_WDT=y # CONFIG_PCIPCWATCHDOG is not set # CONFIG_WDTPCI is not set CONFIG_HW_RANDOM=y -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set @@ -695,11 +636,7 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# +CONFIG_DEVPORT=y # CONFIG_I2C is not set # @@ -711,44 +648,51 @@ CONFIG_HW_RANDOM=y # # Dallas's 1-wire bus # +# CONFIG_W1 is not set +# CONFIG_HWMON is not set # -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Misc devices +# Multifunction device drivers # +# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set # -# Digital Video Broadcasting Devices +# Graphics support # -# CONFIG_DVB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # -# Graphics support +# Display device support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB_DDC is not set CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set @@ -763,13 +707,17 @@ CONFIG_FB_PVR2=y # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set # CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set # CONFIG_FB_SAVAGE is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set # CONFIG_FB_VIRTUAL is not set # @@ -789,10 +737,6 @@ CONFIG_FONT_8x16=y # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set # CONFIG_FONT_10x18 is not set - -# -# Logo configuration -# CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set @@ -800,7 +744,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_SUPERH_MONO is not set # CONFIG_LOGO_SUPERH_VGA16 is not set CONFIG_LOGO_SUPERH_CLUT224=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -808,6 +751,12 @@ CONFIG_LOGO_SUPERH_CLUT224=y # CONFIG_SOUND is not set # +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# # USB support # CONFIG_USB_ARCH_HAS_HCD=y @@ -823,10 +772,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -874,10 +819,12 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -957,6 +904,11 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# # Profiling support # CONFIG_PROFILING=y @@ -965,17 +917,18 @@ CONFIG_PROFILING=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_FS is not set # CONFIG_SH_STANDARD_BIOS is not set # CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_KGDB is not set +# CONFIG_SH_KGDB is not set # # Security options @@ -991,8 +944,13 @@ CONFIG_LOG_BUF_SHIFT=14 # # 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/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig new file mode 100644 index 00000000000..17f7402b31d --- /dev/null +++ b/arch/sh/configs/r7780mp_defconfig @@ -0,0 +1,1223 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.22-rc4 +# Mon Jun 11 10:24:57 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_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT 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 is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# 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 is not set +CONFIG_ANON_INODES=y +# CONFIG_EPOLL is not set +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_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_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=y +# CONFIG_CPU_SUBTYPE_SH7785 is not set +# 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=0x08000000 +CONFIG_MEMORY_SIZE=0x08000000 +# CONFIG_32BIT is not set +CONFIG_VSYSCALL=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_MAX_ACTIVE_REGIONS=1 +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_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 +# CONFIG_SH_OCRAM is not set + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_SH_FPU=y +# CONFIG_SH_DSP is not set +CONFIG_SH_STORE_QUEUES=y +CONFIG_SPECULATIVE_EXECUTION=y +CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_INTC2_IRQ=y +CONFIG_CPU_HAS_SR_RB=y + +# +# Board support +# +# CONFIG_SH_7780_SOLUTION_ENGINE is not set +CONFIG_SH_HIGHLANDER=y +# CONFIG_SH_R7780RP is not set +CONFIG_SH_R7780MP=y +# CONFIG_SH_R7785RP is not set + +# +# Timer and clock configuration +# +CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=28 +CONFIG_SH_PCLK_FREQ=32000000 +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# +# CONFIG_HD6446X_SERIES is not set + +# +# Additional SuperH Device Drivers +# +# CONFIG_HEARTBEAT is not set +CONFIG_PUSH_SWITCH=y + +# +# 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_SMP 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 root=/dev/sda1" + +# +# Bus options +# +CONFIG_PCI=y +CONFIG_SH_PCIDMA_NONCOHERENT=y +CONFIG_PCI_AUTO=y +CONFIG_PCI_AUTO_UPDATE_RESOURCES=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCI_DEBUG is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Power management options (EXPERIMENTAL) +# +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_BRIDGE=m +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set +# 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_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 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 +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# 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=m +# 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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +CONFIG_SATA_SIL=y +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +CONFIG_PATA_PLATFORM=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_STNIC is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +CONFIG_8139CP=m +CONFIG_8139TOO=m +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +# CONFIG_VIA_RHINE_NAPI is not set +# CONFIG_SC92031 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=m +# CONFIG_E1000_NAPI is not set +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_R8169=y +# CONFIG_R8169_NAPI is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=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_PCIPS2 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_SERIAL_JSM is not set +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_APPLICOM is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# 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=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y + +# +# 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=m + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=m +# CONFIG_OSS_OBSOLETE is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set + +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB 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 +# +# CONFIG_INFINIBAND is not set + +# +# 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=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# 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=m + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# 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=m + +# +# 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 + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_CODEPAGE_932=y +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=m + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +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 is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_FRAME_POINTER is not set +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 is not set +# 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=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# 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_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig index 0f5ec649daf..5c29338532d 100644 --- a/arch/sh/configs/r7785rp_defconfig +++ b/arch/sh/configs/r7785rp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc3 -# Mon Mar 12 14:26:33 2007 +# Linux kernel version: 2.6.22-rc4 +# Thu Jul 12 12:33:15 2007 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -11,7 +11,9 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_TIME is not set +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_SYS_SUPPORTS_PCI=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set @@ -43,6 +45,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_AUDIT 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 is not set @@ -60,13 +63,18 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -102,55 +110,11 @@ CONFIG_DEFAULT_IOSCHED="noop" # # System type # -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_7343_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_7710VOIPGW is not set -# CONFIG_SH_RTS7751R2D is not set -CONFIG_SH_HIGHLANDER=y -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -# CONFIG_SH_7206_SOLUTION_ENGINE is not set -# CONFIG_SH_7619_SOLUTION_ENGINE is not set -# CONFIG_SH_UNKNOWN is not set -# CONFIG_SH_R7780RP is not set -# CONFIG_SH_R7780MP is not set -CONFIG_SH_R7785RP=y - -# -# Processor selection -# CONFIG_CPU_SH4=y CONFIG_CPU_SH4A=y CONFIG_CPU_SHX2=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set # CONFIG_CPU_SUBTYPE_SH7619 is not set - -# -# SH-2A Processor Support -# # CONFIG_CPU_SUBTYPE_SH7206 is not set - -# -# SH-3 Processor Support -# # CONFIG_CPU_SUBTYPE_SH7300 is not set # CONFIG_CPU_SUBTYPE_SH7705 is not set # CONFIG_CPU_SUBTYPE_SH7706 is not set @@ -158,10 +122,7 @@ CONFIG_CPU_SHX2=y # CONFIG_CPU_SUBTYPE_SH7708 is not set # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set - -# -# SH-4 Processor Support -# +# CONFIG_CPU_SUBTYPE_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 @@ -170,23 +131,12 @@ CONFIG_CPU_SHX2=y # CONFIG_CPU_SUBTYPE_SH7751R is not set # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# # CONFIG_CPU_SUBTYPE_ST40STB1 is not set # CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set CONFIG_CPU_SUBTYPE_SH7785=y - -# -# SH4AL-DSP Processor Support -# +# CONFIG_CPU_SUBTYPE_SHX3 is not set # CONFIG_CPU_SUBTYPE_SH73180 is not set # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set @@ -194,6 +144,7 @@ CONFIG_CPU_SUBTYPE_SH7785=y # # Memory management options # +CONFIG_QUICKLIST=y CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x08000000 @@ -201,6 +152,12 @@ CONFIG_MEMORY_SIZE=0x08000000 CONFIG_32BIT=y # CONFIG_X2TLB is not set CONFIG_VSYSCALL=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_MAX_ACTIVE_REGIONS=1 +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_64KB is not set @@ -215,17 +172,17 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set +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 -# CONFIG_SH_OCRAM is not set # # Processor features @@ -241,12 +198,22 @@ CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_PTEA=y # +# Board support +# +CONFIG_SH_HIGHLANDER=y +# CONFIG_SH_R7780RP is not set +# CONFIG_SH_R7780MP is not set +CONFIG_SH_R7785RP=y + +# # Timer and clock configuration # CONFIG_SH_TMU=y CONFIG_SH_TIMER_IRQ=28 -CONFIG_NO_IDLE_HZ=y CONFIG_SH_PCLK_FREQ=50000000 +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set # # CPU Frequency scaling @@ -261,7 +228,6 @@ CONFIG_SH_PCLK_FREQ=50000000 # # Companion Chips # -# CONFIG_HD6446X_SERIES is not set # # Additional SuperH Device Drivers @@ -278,7 +244,7 @@ CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set CONFIG_HZ=250 CONFIG_KEXEC=y -# CONFIG_SMP is not set +# CONFIG_CRASH_DUMP is not set # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y @@ -300,31 +266,22 @@ CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y CONFIG_PCI_AUTO=y CONFIG_PCI_AUTO_UPDATE_RESOURCES=y +# CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # # Executable file formats # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set # CONFIG_BINFMT_MISC is not set # -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set - -# # Networking # CONFIG_NET=y @@ -332,7 +289,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -377,20 +333,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set CONFIG_BRIDGE=m @@ -417,8 +361,16 @@ CONFIG_LLC=m # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_IEEE80211 is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -438,10 +390,6 @@ CONFIG_FW_LOADER=m # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -475,12 +423,10 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # Misc devices # +# CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -509,6 +455,7 @@ CONFIG_CHR_DEV_SG=m # 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 @@ -554,10 +501,6 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set # CONFIG_SATA_AHCI is not set @@ -580,6 +523,7 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set # CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set # CONFIG_PATA_CMD64X is not set # CONFIG_PATA_CS5520 is not set # CONFIG_PATA_CS5530 is not set @@ -629,6 +573,7 @@ CONFIG_PATA_PLATFORM=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # @@ -644,15 +589,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# # CONFIG_ARCNET is not set - -# -# PHY device support -# # CONFIG_PHYLIB is not set # @@ -673,10 +610,7 @@ CONFIG_MII=y # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# +CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set @@ -689,55 +623,26 @@ CONFIG_R8169=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# +CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set # CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# +# CONFIG_MLX4_CORE is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y -# CONFIG_NET_WIRELESS_RTNETLINK is not set - -# -# Obsolete Wireless cards support (pre-802.11) -# -# CONFIG_STRIP is not set - -# -# Wireless 802.11b ISA/PCI cards support -# -# CONFIG_IPW2100 is not set -# CONFIG_IPW2200 is not set -# CONFIG_HERMES is not set -# CONFIG_ATMEL is not set - -# -# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support -# -# CONFIG_PRISM54 is not set -# CONFIG_HOSTAP is not set -CONFIG_NET_WIRELESS=y - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -789,6 +694,7 @@ CONFIG_KEYBOARD_ATKBD=y # 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 @@ -831,14 +737,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=y -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_DRM is not set @@ -848,10 +748,7 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y # CONFIG_I2C is not set # @@ -864,16 +761,15 @@ CONFIG_HW_RANDOM=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83627HF is not set # CONFIG_HWMON_DEBUG_CHIP is not set # @@ -885,22 +781,30 @@ CONFIG_HWMON=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set # -# Digital Video Broadcasting Devices +# Graphics support # -# CONFIG_DVB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # -# Graphics support +# Display device support # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set # CONFIG_FB_CFB_FILLRECT is not set # CONFIG_FB_CFB_COPYAREA is not set # CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -908,7 +812,7 @@ CONFIG_FB=y # CONFIG_FB_TILEBLITTING is not set # -# Frambuffer hardware drivers +# Frame buffer hardware drivers # # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set @@ -930,12 +834,11 @@ CONFIG_FB=y # CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set # CONFIG_FB_VIRTUAL is not set - -# -# Logo configuration -# # CONFIG_LOGO is not set # @@ -952,13 +855,10 @@ CONFIG_SOUND=m # Open Sound System # CONFIG_SOUND_PRIME=m -# CONFIG_OBSOLETE_OSS is not set -# CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_ICH is not set +# CONFIG_OSS_OBSOLETE is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set # # HID Devices @@ -982,10 +882,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -1026,18 +922,30 @@ 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 +# # -# 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_SH=y -# CONFIG_RTC_DRV_TEST 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 @@ -1051,14 +959,6 @@ CONFIG_RTC_DRV_SH=y # # -# Auxiliary Display support -# - -# -# Virtualization -# - -# # File systems # CONFIG_EXT2_FS=y @@ -1157,6 +1057,7 @@ CONFIG_EXPORTFS=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -1239,7 +1140,6 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DETECT_SOFTLOCKUP is not set # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1266,6 +1166,7 @@ CONFIG_FORCED_INLINING=y 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 @@ -1300,6 +1201,7 @@ CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set @@ -1328,7 +1230,9 @@ CONFIG_CRYPTO_DES=y 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_HAS_IOMEM=y CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig index 87ab9080fd1..f2f2a3c9c32 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig @@ -1,18 +1,22 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19 -# Wed Dec 6 14:40:15 2006 +# Linux kernel version: 2.6.22-rc4 +# Fri Jun 15 19:37:46 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 is not set +# CONFIG_GENERIC_CLOCKEVENTS is not set 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" # @@ -34,8 +38,10 @@ CONFIG_LOCALVERSION="" # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" +# CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_EMBEDDED=y @@ -48,12 +54,17 @@ CONFIG_BUG=y # CONFIG_ELF_CORE is not set # CONFIG_BASE_FULL is not set # CONFIG_FUTEX is not set +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set -CONFIG_SLAB=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y # CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=1 -# CONFIG_SLOB is not set # # Loadable module support @@ -83,53 +94,10 @@ CONFIG_DEFAULT_IOSCHED="noop" # # System type # -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_7343_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_EC3104 is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_BIGSUR is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_7710VOIPGW is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_R7780RP is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -CONFIG_SH_7206_SOLUTION_ENGINE=y -# CONFIG_SH_7619_SOLUTION_ENGINE is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# CONFIG_CPU_SH2=y CONFIG_CPU_SH2A=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set # CONFIG_CPU_SUBTYPE_SH7619 is not set - -# -# SH-2A Processor Support -# CONFIG_CPU_SUBTYPE_SH7206=y - -# -# SH-3 Processor Support -# # CONFIG_CPU_SUBTYPE_SH7300 is not set # CONFIG_CPU_SUBTYPE_SH7705 is not set # CONFIG_CPU_SUBTYPE_SH7706 is not set @@ -137,10 +105,7 @@ CONFIG_CPU_SUBTYPE_SH7206=y # CONFIG_CPU_SUBTYPE_SH7708 is not set # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set - -# -# SH-4 Processor Support -# +# CONFIG_CPU_SUBTYPE_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 @@ -149,32 +114,28 @@ CONFIG_CPU_SUBTYPE_SH7206=y # CONFIG_CPU_SUBTYPE_SH7751R is not set # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# # CONFIG_CPU_SUBTYPE_ST40STB1 is not set # CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set # CONFIG_CPU_SUBTYPE_SH7785 is not set - -# -# SH4AL-DSP Processor Support -# # 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_PAGE_OFFSET=0x00000000 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 +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 @@ -184,35 +145,42 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set +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 -# CONFIG_SH_OCRAM is not set # # Processor features # # CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_CPU_BIG_ENDIAN=y -# CONFIG_SH_FPU is not set # CONFIG_SH_FPU_EMU is not set # CONFIG_SH_DSP is not set +CONFIG_CPU_HAS_IPR_IRQ=y + +# +# Board support +# +CONFIG_SOLUTION_ENGINE=y +CONFIG_SH_7206_SOLUTION_ENGINE=y # -# Timer support +# Timer and clock configuration # CONFIG_SH_CMT=y # CONFIG_SH_MTU2 is not set CONFIG_SH_TIMER_IRQ=140 -# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_MD=6 +# CONFIG_TICK_ONESHOT is not set # # CPU Frequency scaling @@ -227,11 +195,11 @@ CONFIG_SH_CLK_MD=6 # # Companion Chips # -# CONFIG_HD6446X_SERIES is not set # # Additional SuperH Device Drivers # +# CONFIG_HEARTBEAT is not set # CONFIG_PUSH_SWITCH is not set # @@ -239,10 +207,11 @@ CONFIG_SH_CLK_MD=6 # CONFIG_HZ_100=y # CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=100 # CONFIG_KEXEC is not set -# CONFIG_SMP is not set +# CONFIG_CRASH_DUMP is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -252,23 +221,18 @@ CONFIG_PREEMPT_NONE=y # CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 -# CONFIG_UBC_WAKEUP is not set # CONFIG_CMDLINE_BOOL is not set # # Bus options # -# CONFIG_PCI is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set # # PCCARD (PCMCIA/CardBus) support # # -# PCI Hotplug Support -# - -# # Executable file formats # CONFIG_BINFMT_FLAT=y @@ -277,11 +241,6 @@ CONFIG_BINFMT_ZFLAT=y # CONFIG_BINFMT_MISC is not set # -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set - -# # Networking # CONFIG_NET=y @@ -289,7 +248,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set # CONFIG_PACKET is not set # CONFIG_UNIX is not set # CONFIG_NET_KEY is not set @@ -314,25 +272,14 @@ CONFIG_IP_FIB_HASH=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -358,7 +305,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -375,10 +331,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set CONFIG_MTD_CONCAT=y @@ -393,6 +345,7 @@ CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 # User Modules And Translation Layers # CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set @@ -424,7 +377,6 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access @@ -452,16 +404,13 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4 # CONFIG_MTD_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set # CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# # CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set # -# OneNAND Flash Device Drivers +# UBI - Unsorted block images # -# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD_UBI is not set # # Parallel port support @@ -471,6 +420,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4 # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -479,18 +429,13 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4 # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -499,10 +444,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4 # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # @@ -511,19 +452,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4 # CONFIG_MD is not set # -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# # Network device support # CONFIG_NETDEVICES=y @@ -531,10 +459,6 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# PHY device support -# # CONFIG_PHYLIB is not set # @@ -544,27 +468,14 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_STNIC is not set CONFIG_SMC91X=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y # -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -604,6 +515,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD 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 @@ -639,29 +551,15 @@ CONFIG_SERIAL_CORE_CONSOLE=y # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# # CONFIG_RAW_DRIVER is not set # # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# # CONFIG_I2C is not set # @@ -674,27 +572,30 @@ CONFIG_SERIAL_CORE_CONSOLE=y # Dallas's 1-wire bus # # CONFIG_W1 is not set +# CONFIG_HWMON is not set # -# Hardware Monitoring support +# Multifunction device drivers # -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set +# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # -# Digital Video Broadcasting Devices +# Graphics support # -# CONFIG_DVB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # -# Graphics support +# Display device support # -# CONFIG_FIRMWARE_EDID is not set +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # @@ -703,6 +604,12 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SOUND is not set # +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# # USB support # # CONFIG_USB_ARCH_HAS_HCD is not set @@ -717,10 +624,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -802,7 +705,6 @@ CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y # CONFIG_SYSFS is not set # CONFIG_TMPFS is not set -# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y @@ -816,7 +718,6 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set @@ -849,6 +750,11 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# # Profiling support # # CONFIG_PROFILING is not set @@ -861,14 +767,11 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_ENABLE_MUST_CHECK is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_UNWIND_INFO is not set -# CONFIG_HEADERS_CHECK is not set # CONFIG_SH_STANDARD_BIOS is not set # CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_KGDB is not set # # Security options @@ -883,8 +786,13 @@ CONFIG_LOG_BUF_SHIFT=14 # # 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_ZLIB_INFLATE=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig index 20ac7f4c53f..3a3c3c1f507 100644 --- a/arch/sh/configs/se7619_defconfig +++ b/arch/sh/configs/se7619_defconfig @@ -1,18 +1,22 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19 -# Wed Dec 6 16:35:36 2006 +# Linux kernel version: 2.6.22-rc4 +# Fri Jun 15 19:43:06 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 is not set +# CONFIG_GENERIC_CLOCKEVENTS is not set 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" # @@ -31,8 +35,10 @@ CONFIG_LOCALVERSION="" # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_UTS_NS is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" +# CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_EMBEDDED=y @@ -45,12 +51,17 @@ CONFIG_BUG=y # CONFIG_ELF_CORE is not set # CONFIG_BASE_FULL is not set # CONFIG_FUTEX is not set +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set -CONFIG_SLAB=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y # CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=1 -# CONFIG_SLOB is not set # # Loadable module support @@ -80,52 +91,9 @@ CONFIG_DEFAULT_IOSCHED="noop" # # System type # -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_7343_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_EC3104 is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_BIGSUR is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_7710VOIPGW is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_R7780RP is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -# CONFIG_SH_7206_SOLUTION_ENGINE is not set -CONFIG_SH_7619_SOLUTION_ENGINE=y -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# CONFIG_CPU_SH2=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set CONFIG_CPU_SUBTYPE_SH7619=y - -# -# SH-2A Processor Support -# # CONFIG_CPU_SUBTYPE_SH7206 is not set - -# -# SH-3 Processor Support -# # CONFIG_CPU_SUBTYPE_SH7300 is not set # CONFIG_CPU_SUBTYPE_SH7705 is not set # CONFIG_CPU_SUBTYPE_SH7706 is not set @@ -133,10 +101,7 @@ CONFIG_CPU_SUBTYPE_SH7619=y # CONFIG_CPU_SUBTYPE_SH7708 is not set # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set - -# -# SH-4 Processor Support -# +# CONFIG_CPU_SUBTYPE_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 @@ -145,32 +110,28 @@ CONFIG_CPU_SUBTYPE_SH7619=y # CONFIG_CPU_SUBTYPE_SH7751R is not set # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# # CONFIG_CPU_SUBTYPE_ST40STB1 is not set # CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set # CONFIG_CPU_SUBTYPE_SH7785 is not set - -# -# SH4AL-DSP Processor Support -# # 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_PAGE_OFFSET=0x00000000 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 +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 @@ -180,34 +141,41 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set +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=y -# CONFIG_SH_OCRAM is not set # # Processor features # # CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_CPU_BIG_ENDIAN=y -# CONFIG_SH_FPU is not set # CONFIG_SH_FPU_EMU is not set # CONFIG_SH_DSP is not set +CONFIG_CPU_HAS_IPR_IRQ=y + +# +# Board support +# +CONFIG_SOLUTION_ENGINE=y +CONFIG_SH_7619_SOLUTION_ENGINE=y # -# Timer support +# Timer and clock configuration # CONFIG_SH_CMT=y CONFIG_SH_TIMER_IRQ=86 -# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=31250000 CONFIG_SH_CLK_MD=5 +# CONFIG_TICK_ONESHOT is not set # # CPU Frequency scaling @@ -222,11 +190,11 @@ CONFIG_SH_CLK_MD=5 # # Companion Chips # -# CONFIG_HD6446X_SERIES is not set # # Additional SuperH Device Drivers # +# CONFIG_HEARTBEAT is not set # CONFIG_PUSH_SWITCH is not set # @@ -234,10 +202,11 @@ CONFIG_SH_CLK_MD=5 # CONFIG_HZ_100=y # CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=100 # CONFIG_KEXEC is not set -# CONFIG_SMP is not set +# CONFIG_CRASH_DUMP is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -247,23 +216,18 @@ CONFIG_PREEMPT_NONE=y # CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 -# CONFIG_UBC_WAKEUP is not set # CONFIG_CMDLINE_BOOL is not set # # Bus options # -# CONFIG_PCI is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set # # PCCARD (PCMCIA/CardBus) support # # -# PCI Hotplug Support -# - -# # Executable file formats # CONFIG_BINFMT_FLAT=y @@ -272,11 +236,6 @@ CONFIG_BINFMT_ZFLAT=y # CONFIG_BINFMT_MISC is not set # -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set - -# # Networking # # CONFIG_NET is not set @@ -295,10 +254,6 @@ CONFIG_BINFMT_ZFLAT=y # # Connector - unified userspace <-> kernelspace linker # - -# -# Memory Technology Devices (MTD) -# CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set CONFIG_MTD_CONCAT=y @@ -313,6 +268,7 @@ CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 # User Modules And Translation Layers # CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set @@ -344,7 +300,6 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access @@ -372,16 +327,13 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_MTD_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set # CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# # CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set # -# OneNAND Flash Device Drivers +# UBI - Unsorted block images # -# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD_UBI is not set # # Parallel port support @@ -391,6 +343,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -398,17 +351,12 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # # Misc devices # -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -417,10 +365,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # @@ -429,19 +373,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_MD is not set # -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# # ISDN subsystem # @@ -471,6 +402,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD 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 @@ -506,29 +438,15 @@ CONFIG_SERIAL_CORE_CONSOLE=y # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# # CONFIG_RAW_DRIVER is not set # # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# # CONFIG_I2C is not set # @@ -541,26 +459,29 @@ CONFIG_SERIAL_CORE_CONSOLE=y # Dallas's 1-wire bus # # CONFIG_W1 is not set +# CONFIG_HWMON is not set # -# Hardware Monitoring support +# Multifunction device drivers # -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set +# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_DAB=y # -# Digital Video Broadcasting Devices +# Graphics support # +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # -# Graphics support +# Display device support # -# CONFIG_FIRMWARE_EDID is not set +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # @@ -569,6 +490,12 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SOUND is not set # +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# # USB support # # CONFIG_USB_ARCH_HAS_HCD is not set @@ -583,10 +510,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -668,7 +591,6 @@ CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y # CONFIG_SYSFS is not set # CONFIG_TMPFS is not set -# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y @@ -682,7 +604,6 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set @@ -715,14 +636,11 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_ENABLE_MUST_CHECK is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_UNWIND_INFO is not set -# CONFIG_HEADERS_CHECK is not set # CONFIG_SH_STANDARD_BIOS is not set # CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_KGDB is not set # # Security options @@ -737,8 +655,13 @@ CONFIG_LOG_BUF_SHIFT=14 # # 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_ZLIB_INFLATE=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig index ca4c663dfa3..764b813c405 100644 --- a/arch/sh/configs/se7722_defconfig +++ b/arch/sh/configs/se7722_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc7 -# Fri Apr 27 16:30:30 2007 +# Linux kernel version: 2.6.22-rc4 +# Wed Jun 20 18:08:04 2007 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -11,7 +11,9 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_TIME is not set +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_SYS_SUPPORTS_NUMA=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set @@ -43,6 +45,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_AUDIT 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 @@ -60,14 +63,20 @@ 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_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -103,57 +112,12 @@ CONFIG_DEFAULT_IOSCHED="noop" # # System type # -CONFIG_SOLUTION_ENGINE=y -# CONFIG_SH_SOLUTION_ENGINE is not set -CONFIG_SH_7722_SOLUTION_ENGINE=y -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7780_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_7343_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_7710VOIPGW is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_HIGHLANDER is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -# CONFIG_SH_7206_SOLUTION_ENGINE is not set -# CONFIG_SH_7619_SOLUTION_ENGINE is not set -# CONFIG_SH_LBOX_RE2 is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# CONFIG_CPU_SH4=y CONFIG_CPU_SH4A=y CONFIG_CPU_SH4AL_DSP=y CONFIG_CPU_SHX2=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set # CONFIG_CPU_SUBTYPE_SH7619 is not set - -# -# SH-2A Processor Support -# # CONFIG_CPU_SUBTYPE_SH7206 is not set - -# -# SH-3 Processor Support -# # CONFIG_CPU_SUBTYPE_SH7300 is not set # CONFIG_CPU_SUBTYPE_SH7705 is not set # CONFIG_CPU_SUBTYPE_SH7706 is not set @@ -162,10 +126,6 @@ CONFIG_CPU_SHX2=y # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set # CONFIG_CPU_SUBTYPE_SH7712 is not set - -# -# SH-4 Processor Support -# # CONFIG_CPU_SUBTYPE_SH7750 is not set # CONFIG_CPU_SUBTYPE_SH7091 is not set # CONFIG_CPU_SUBTYPE_SH7750R is not set @@ -174,23 +134,11 @@ CONFIG_CPU_SHX2=y # CONFIG_CPU_SUBTYPE_SH7751R is not set # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# # CONFIG_CPU_SUBTYPE_ST40STB1 is not set # CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set # CONFIG_CPU_SUBTYPE_SH7785 is not set - -# -# SH4AL-DSP Processor Support -# # CONFIG_CPU_SUBTYPE_SH73180 is not set # CONFIG_CPU_SUBTYPE_SH7343 is not set CONFIG_CPU_SUBTYPE_SH7722=y @@ -198,15 +146,21 @@ CONFIG_CPU_SUBTYPE_SH7722=y # # Memory management options # +CONFIG_QUICKLIST=y CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 -# CONFIG_32BIT is not set # CONFIG_X2TLB is not set CONFIG_VSYSCALL=y -CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_NUMA=y +CONFIG_NODES_SHIFT=1 +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_MAX_ACTIVE_REGIONS=2 CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_64KB is not set @@ -216,26 +170,25 @@ CONFIG_HUGETLB_PAGE_SIZE_64K=y # 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_FLATMEM_MANUAL is not set # CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_NEED_MULTIPLE_NODES=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_STATIC=y +# CONFIG_MEMORY_HOTPLUG is not set CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_MIGRATION=y # 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 -# CONFIG_SH_OCRAM is not set -CONFIG_CF_ENABLER=y -# CONFIG_CF_AREA5 is not set -CONFIG_CF_AREA6=y -CONFIG_CF_BASE_ADDR=0xb8000000 # # Processor features @@ -252,12 +205,20 @@ CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_PTEA=y # +# Board support +# +CONFIG_SOLUTION_ENGINE=y +CONFIG_SH_7722_SOLUTION_ENGINE=y + +# # Timer and clock configuration # CONFIG_SH_TMU=y CONFIG_SH_TIMER_IRQ=16 -CONFIG_NO_IDLE_HZ=y CONFIG_SH_PCLK_FREQ=33333333 +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y # # CPU Frequency scaling @@ -272,7 +233,6 @@ CONFIG_SH_PCLK_FREQ=33333333 # # Companion Chips # -# CONFIG_HD6446X_SERIES is not set # # Additional SuperH Device Drivers @@ -290,7 +250,6 @@ CONFIG_HZ_250=y CONFIG_HZ=250 CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set -# CONFIG_SMP is not set # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y @@ -307,7 +266,11 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000 # # Bus options # -# CONFIG_PCI is not set +CONFIG_CF_ENABLER=y +# CONFIG_CF_AREA5 is not set +CONFIG_CF_AREA6=y +CONFIG_CF_BASE_ADDR=0xb8000000 +# CONFIG_ARCH_SUPPORTS_MSI is not set # # PCCARD (PCMCIA/CardBus) support @@ -315,22 +278,12 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000 # CONFIG_PCCARD is not set # -# PCI Hotplug Support -# - -# # Executable file formats # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set # CONFIG_BINFMT_MISC is not set # -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set - -# # Networking # CONFIG_NET=y @@ -338,7 +291,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -375,20 +327,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -414,7 +354,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -432,10 +381,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -464,10 +409,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # Misc devices # - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -496,6 +438,7 @@ CONFIG_BLK_DEV_SD=y # 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 @@ -511,10 +454,6 @@ CONFIG_BLK_DEV_SD=y # # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_DEBUG is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set CONFIG_PATA_PLATFORM=y @@ -525,19 +464,6 @@ CONFIG_PATA_PLATFORM=y # CONFIG_MD is not set # -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# # Network device support # CONFIG_NETDEVICES=y @@ -545,10 +471,6 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# PHY device support -# # CONFIG_PHYLIB is not set # @@ -558,27 +480,14 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_STNIC is not set CONFIG_SMC91X=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y # -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -627,6 +536,7 @@ CONFIG_KEYBOARD_ATKBD=y # 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 @@ -667,14 +577,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=y -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set @@ -682,10 +586,6 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# # CONFIG_I2C is not set # @@ -698,16 +598,15 @@ CONFIG_HW_RANDOM=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83627HF is not set # CONFIG_HWMON_DEBUG_CHIP is not set # @@ -719,16 +618,19 @@ CONFIG_HWMON=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # -# Digital Video Broadcasting Devices +# Graphics support # -# CONFIG_DVB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # -# Graphics support +# Display device support # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # @@ -757,10 +659,6 @@ CONFIG_HID=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -800,18 +698,30 @@ 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 # -# RTC drivers +# 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_SH=y -# CONFIG_RTC_DRV_TEST 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 @@ -825,14 +735,6 @@ CONFIG_RTC_DRV_SH=y # # -# Auxiliary Display support -# - -# -# Virtualization -# - -# # File systems # CONFIG_EXT2_FS=y @@ -937,23 +839,24 @@ CONFIG_MSDOS_PARTITION=y # # Profiling support # -# CONFIG_PROFILING is not set +CONFIG_PROFILING=y +# CONFIG_OPROFILE is not set # # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set +CONFIG_PRINTK_TIME=y # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_MAGIC_SYSRQ is not set +CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_SH_STANDARD_BIOS is not set +CONFIG_SH_STANDARD_BIOS=y # CONFIG_EARLY_SCIF_CONSOLE is not set +# CONFIG_EARLY_PRINTK is not set # CONFIG_SH_KGDB is not set # @@ -973,8 +876,10 @@ CONFIG_LOG_BUF_SHIFT=14 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/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig new file mode 100644 index 00000000000..219bad558b1 --- /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/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig index 99935f9daf4..333898077c7 100644 --- a/arch/sh/drivers/dma/Kconfig +++ b/arch/sh/drivers/dma/Kconfig @@ -36,23 +36,6 @@ config NR_DMA_CHANNELS support. Setting this to a higher value allows for cascading DMACs with additional channels. -config DMA_PAGE_OPS - bool "Use DMAC for page copy/clear" - depends on SH_DMA && BROKEN - help - Selecting this option will use a dual-address mode configured channel - in the SH DMAC for copy_page()/clear_page(). Primarily a performance - hack. - -config DMA_PAGE_OPS_CHANNEL - depends on DMA_PAGE_OPS - int "DMA channel for sh memory-manager page copy/clear" - default "3" - help - This allows the specification of the dual address dma channel, - in case channel 3 is unavailable. On the SH4, channels 1,2, and 3 - are dual-address capable. - config SH_DMABRG bool "SH7760 DMABRG support" depends on CPU_SUBTYPE_SH7760 diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig index 6d1cbbe6745..fbc6f2c8649 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/Makefile b/arch/sh/kernel/Makefile index 9104b625764..1f141a8ba17 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -4,10 +4,9 @@ extra-y := head.o init_task.o vmlinux.lds -obj-y := process.o signal.o traps.o irq.o \ - ptrace.o setup.o time.o sys_sh.o semaphore.o \ - io.o io_generic.o sh_ksyms.o syscalls.o \ - debugtraps.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 obj-y += cpu/ timers/ obj-$(CONFIG_VSYSCALL) += vsyscall/ @@ -17,7 +16,7 @@ obj-$(CONFIG_CF_ENABLER) += cf-enabler.o obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o -obj-$(CONFIG_MODULES) += module.o +obj-$(CONFIG_MODULES) += sh_ksyms.o module.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c index ebc73b85094..1c3b99642e1 100644 --- a/arch/sh/kernel/cf-enabler.c +++ b/arch/sh/kernel/cf-enabler.c @@ -75,11 +75,7 @@ static int __init cf_init_default(void) #if defined(CONFIG_CPU_SH4) allocate_cf_area(); #endif -#if defined(CONFIG_SH_UNKNOWN) - /* This should be done in each board's init_xxx_irq. */ - make_imask_irq(14); - disable_irq(14); -#endif + return 0; } diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 6451ad63017..9172e97dc26 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -21,8 +21,7 @@ #include <asm/cacheflush.h> #include <asm/cache.h> #include <asm/io.h> - -extern void detect_cpu_and_cache_system(void); +#include <asm/ubc.h> /* * 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/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c index d8e22f4ff0f..cc5221390e0 100644 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ b/arch/sh/kernel/cpu/irq/intc2.c @@ -13,36 +13,31 @@ #include <linux/kernel.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <asm/smp.h> -#if defined(CONFIG_CPU_SUBTYPE_SH7760) -#define INTC2_BASE 0xfe080000 -#define INTC2_INTMSK (INTC2_BASE + 0x40) -#define INTC2_INTMSKCLR (INTC2_BASE + 0x60) -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || \ - 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 + + (hard_smp_processor_id() * 4)); } 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); -static struct irq_chip intc2_irq_chip = { - .name = "INTC2", - .mask = disable_intc2_irq, - .unmask = enable_intc2_irq, - .mask_ack = disable_intc2_irq, -}; + ctrl_outl(1 << p->msk_shift, d->mskclr_base + p->msk_offset + + (hard_smp_processor_id() * 4)); +} /* * Setup an INTC2 style interrupt. @@ -56,30 +51,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/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index 210280b6fdd..98e84f40c71 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -22,58 +22,57 @@ #include <linux/io.h> #include <linux/interrupt.h> +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/entry.S b/arch/sh/kernel/cpu/sh2/entry.S index c16dc8fec48..ee8f1fe84b0 100644 --- a/arch/sh/kernel/cpu/sh2/entry.S +++ b/arch/sh/kernel/cpu/sh2/entry.S @@ -311,6 +311,7 @@ restore_all: rte nop + .align 2 #ifdef CONFIG_TRACE_IRQFLAGS 1: .long trace_hardirqs_off #endif diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index 108e81b682e..abbf17427e5 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c @@ -9,23 +9,14 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ - - #include <linux/init.h> +#include <linux/smp.h> #include <asm/processor.h> #include <asm/cache.h> 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/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index f83ff8a68f3..1a107fe22dd 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 4ed9110632b..b6e3a6351fa 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/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index b0b59d4a33c..d8e122971c3 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/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 1983fb7ad6e..a55b8ce2c54 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 c7d7c35fc83..d79ec0c0522 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7709.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7709.c @@ -12,6 +12,26 @@ #include <linux/serial.h> #include <asm/sci.h> +static struct resource rtc_resources[] = { + [0] = { + .start = 0xfffffec0, + .end = 0xfffffec0 + 0x1e, + .flags = IORESOURCE_IO, + }, + [1] = { + .start = 20, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 21, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = 22, + .flags = IORESOURCE_IRQ, + }, +}; + static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xfffffe80, @@ -41,8 +61,16 @@ static struct platform_device sci_device = { }, }; +static struct platform_device rtc_device = { + .name = "sh-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, +}; + static struct platform_device *sh7709_devices[] __initdata = { &sci_device, + &rtc_device, }; static int __init sh7709_devices_setup(void) @@ -52,32 +80,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 51760a7e7f1..f40e6dac337 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/Makefile b/arch/sh/kernel/cpu/sh4/Makefile index 8add10bd826..dadd6bffc12 100644 --- a/arch/sh/kernel/cpu/sh4/Makefile +++ b/arch/sh/kernel/cpu/sh4/Makefile @@ -10,7 +10,11 @@ obj-$(CONFIG_SH_STORE_QUEUES) += sq.o # CPU subtype setup obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o +obj-$(CONFIG_CPU_SUBTYPE_SH7750R) += setup-sh7750.o +obj-$(CONFIG_CPU_SUBTYPE_SH7750S) += setup-sh7750.o +obj-$(CONFIG_CPU_SUBTYPE_SH7091) += setup-sh7750.o obj-$(CONFIG_CPU_SUBTYPE_SH7751) += setup-sh7750.o +obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += setup-sh7750.o obj-$(CONFIG_CPU_SUBTYPE_SH7760) += setup-sh7760.o obj-$(CONFIG_CPU_SUBTYPE_SH4_202) += setup-sh4-202.o diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index fab2eb07196..66c3f75647b 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/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 03b14cf78dd..da153bcdfeb 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 b7c702821e6..3df16975567 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -96,7 +96,25 @@ static struct intc2_data intc2_irq_table[] = { {109,12, 0, 4, 0, 3}, /* CMTI */ }; -static struct ipr_data sh7760_ipr_map[] = { +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", + }, +}; + +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 */ @@ -133,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) -{ - make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); -} + .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/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index ab7422f8f82..40062328648 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 00000000000..c630b29e06a --- /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 <linux/init.h> +#include <linux/kernel.h> +#include <asm/clock.h> +#include <asm/freq.h> +#include <asm/io.h> + +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-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 1143fbf65fa..a3e159ef6df 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -1,7 +1,7 @@ /* * SH7722 Setup * - * Copyright (C) 2006 Paul Mundt + * 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 @@ -10,6 +10,8 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> +#include <linux/mm.h> +#include <asm/mmzone.h> #include <asm/sci.h> static struct plat_sci_port sci_platform_data[] = { @@ -42,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 */ @@ -67,14 +69,25 @@ static unsigned long ipr_offsets[] = { 0xa408002c, /* 11: IPRL */ }; -unsigned int map_ipridx_to_addr(int 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) { - if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) - return 0; - return ipr_offsets[idx]; + register_ipr_controller(&ipr_irq_desc); } -void __init init_IRQ_ipr(void) +void __init plat_mem_setup(void) { - make_ipr_irq(sh7722_ipr_map, ARRAY_SIZE(sh7722_ipr_map)); + /* Register the URAM space as Node 1 */ + setup_bootmem_node(1, 0x055f0000, 0x05610000); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 9aeaa2ddaa2..b57c760bffd 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 07b0de82cfe..ce10ec5d691 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/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c new file mode 100644 index 00000000000..70683ea12b8 --- /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 <linux/platform_device.h> +#include <linux/init.h> +#include <linux/serial.h> +#include <linux/io.h> +#include <asm/sci.h> + +static struct plat_sci_port sci_platform_data[] = { + { + .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/irq.c b/arch/sh/kernel/irq.c index 27b923c45b3..27897798867 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -158,15 +158,11 @@ asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs) } #ifdef CONFIG_4KSTACKS -/* - * These should really be __section__(".bss.page_aligned") as well, but - * gcc's 3.0 and earlier don't handle that correctly. - */ static char softirq_stack[NR_CPUS * THREAD_SIZE] - __attribute__((__aligned__(THREAD_SIZE))); + __attribute__((__section__(".bss.page_aligned"))); static char hardirq_stack[NR_CPUS * THREAD_SIZE] - __attribute__((__aligned__(THREAD_SIZE))); + __attribute__((__section__(".bss.page_aligned"))); /* * allocate per-cpu stacks for hardirq and for softirq processing diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c new file mode 100644 index 00000000000..23c5948f012 --- /dev/null +++ b/arch/sh/kernel/machvec.c @@ -0,0 +1,130 @@ +/* + * 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 <linux/init.h> +#include <linux/string.h> +#include <asm/machvec.h> +#include <asm/sections.h> +#include <asm/io.h> +#include <asm/irq.h> + +#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, mv->mv_name) == 0) + return mv; + + return NULL; +} + +static unsigned int __initdata machvec_selected; + +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; + + machvec_selected = 1; + + /* Boot with the generic vector */ + if (strcmp(mv_name, "generic") == 0) + return 0; + + mvp = get_mv_byname(mv_name); + if (unlikely(!mvp)) { + printk("Available vectors:\n\n\t'%s', ", sh_mv.mv_name); + 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; + + 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 (!machvec_selected) { + 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. + */ +#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/process.c b/arch/sh/kernel/process.c index a11e2aa73cb..6334a4c54c7 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -17,6 +17,7 @@ #include <linux/kexec.h> #include <linux/kdebug.h> #include <linux/tick.h> +#include <linux/reboot.h> #include <asm/uaccess.h> #include <asm/mmu_context.h> #include <asm/pgalloc.h> @@ -319,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); @@ -405,8 +404,8 @@ asmlinkage int sys_fork(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs __regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); #ifdef CONFIG_MMU + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); return do_fork(SIGCHLD, regs->regs[15], regs, 0, NULL, NULL); #else /* fork almost works, enough to trick you into looking elsewhere :-( */ @@ -449,23 +448,20 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, /* * sys_execve() executes a new program. */ -asmlinkage int sys_execve(char *ufilename, char **uargv, - char **uenvp, unsigned long r7, +asmlinkage int sys_execve(char __user *ufilename, char __user * __user *uargv, + char __user * __user *uenvp, unsigned long r7, struct pt_regs __regs) { struct pt_regs *regs = RELOC_HIDE(&__regs, 0); int error; char *filename; - filename = getname((char __user *)ufilename); + filename = getname(ufilename); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - error = do_execve(filename, - (char __user * __user *)uargv, - (char __user * __user *)uenvp, - regs); + error = do_execve(filename, uargv, uenvp, regs); if (error == 0) { task_lock(current); current->ptrace &= ~PT_DTRACE; diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c index 3fb5fc0b550..f2eaa485d04 100644 --- a/arch/sh/kernel/ptrace.c +++ b/arch/sh/kernel/ptrace.c @@ -99,7 +99,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = -EIO; if (copied != sizeof(tmp)) break; - ret = put_user(tmp,(unsigned long *) data); + ret = put_user(tmp,(unsigned long __user *) data); break; } @@ -128,7 +128,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) tmp = !!tsk_used_math(child); else tmp = 0; - ret = put_user(tmp, (unsigned long *)data); + ret = put_user(tmp, (unsigned long __user *)data); break; } @@ -196,7 +196,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_SINGLESTEP: { /* set the trap flag. */ long pc; - struct pt_regs *dummy = NULL; + struct pt_regs *regs = NULL; ret = -EIO; if (!valid_signal(data)) @@ -207,7 +207,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) child->ptrace |= PT_DTRACE; } - pc = get_stack_long(child, (long)&dummy->pc); + pc = get_stack_long(child, (long)®s->pc); /* Next scheduling will set up UBC */ if (child->thread.ubc_pc == 0) diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index c2772913593..de8e6e2f2c8 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -23,6 +23,7 @@ #include <linux/kexec.h> #include <asm/uaccess.h> #include <asm/io.h> +#include <asm/page.h> #include <asm/sections.h> #include <asm/irq.h> #include <asm/setup.h> @@ -41,20 +42,19 @@ 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 = "generic", }; + #ifdef CONFIG_VT 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 */ @@ -80,131 +80,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. @@ -230,7 +116,7 @@ static void __init register_bootmem_low_pages(void) free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages)); } -void __init setup_bootmem_allocator(unsigned long start_pfn) +void __init setup_bootmem_allocator(unsigned long free_pfn) { unsigned long bootmap_size; @@ -239,9 +125,10 @@ void __init setup_bootmem_allocator(unsigned long start_pfn) * bootstrap step all allocations (until the page allocator * is intact) must be done via bootmem_alloc(). */ - bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, + bootmap_size = init_bootmem_node(NODE_DATA(0), free_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); @@ -254,7 +141,7 @@ void __init setup_bootmem_allocator(unsigned long start_pfn) * an invalid RAM area. */ reserve_bootmem(__MEMORY_START+PAGE_SIZE, - (PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START); + (PFN_PHYS(free_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START); /* * reserve physical page 0 - it's a special BIOS page on many boxes, @@ -262,6 +149,8 @@ void __init setup_bootmem_allocator(unsigned long start_pfn) */ reserve_bootmem(__MEMORY_START, PAGE_SIZE); + sparse_memory_present_with_active_regions(0); + #ifdef CONFIG_BLK_DEV_INITRD ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); if (&__rd_start != &__rd_end) { @@ -315,10 +204,6 @@ void __init setup_arch(char **cmdline_p) { enable_mmu(); -#ifdef CONFIG_CMDLINE_BOOL - strcpy(COMMAND_LINE, CONFIG_CMDLINE); -#endif - ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); #ifdef CONFIG_BLK_DEV_RAM @@ -339,9 +224,22 @@ 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; + +#ifdef CONFIG_CMDLINE_BOOL + strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line)); +#else + strlcpy(command_line, COMMAND_LINE, sizeof(command_line)); +#endif + + /* Save unparsed command line copy for /proc/cmdline */ + memcpy(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 @@ -355,8 +253,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 @@ -366,46 +265,13 @@ void __init setup_arch(char **cmdline_p) /* Perform the machine specific initialisation */ if (likely(sh_mv.mv_setup)) 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 struct cpu cpu[NR_CPUS]; - -static int __init topology_init(void) -{ - int cpu_id; - for_each_possible_cpu(cpu_id) - register_cpu(&cpu[cpu_id], cpu_id); - - return 0; + paging_init(); } -subsys_initcall(topology_init); - 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", @@ -419,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/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index c1cfcb9f047..c968dcf09ee 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -78,6 +78,16 @@ DECLARE_EXPORT(__movstr); DECLARE_EXPORT(__movmem_i4_even); DECLARE_EXPORT(__movmem_i4_odd); DECLARE_EXPORT(__movmemSI12_i4); + +#if (__GNUC_MINOR__ == 2 || defined(__GNUC_STM_RELEASE__)) +/* + * GCC 4.2 emits these for division, as do GCC 4.1.x versions of the ST + * compiler which include backported patches. + */ +DECLARE_EXPORT(__sdivsi3_i4i); +DECLARE_EXPORT(__udiv_qrnnd_16); +DECLARE_EXPORT(__udivsi3_i4i); +#endif #else /* GCC 3.x */ DECLARE_EXPORT(__movstr_i4_even); DECLARE_EXPORT(__movstr_i4_odd); diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index e323e299878..706d81ccd10 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c @@ -23,6 +23,7 @@ #include <linux/personality.h> #include <linux/binfmts.h> #include <linux/freezer.h> +#include <linux/io.h> #include <asm/system.h> #include <asm/ucontext.h> #include <asm/uaccess.h> @@ -261,7 +262,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack(&st, NULL, regs->regs[15]); + do_sigaltstack((const stack_t __user *)&st, NULL, (unsigned long)frame); return r0; diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S index 7db1c2dc599..ff5656e60c0 100644 --- a/arch/sh/kernel/syscalls.S +++ b/arch/sh/kernel/syscalls.S @@ -308,9 +308,9 @@ ENTRY(sys_call_table) .long sys_utimes .long sys_fadvise64_64_wrapper .long sys_ni_syscall /* Reserved for vserver */ - .long sys_ni_syscall /* Reserved for mbind */ - .long sys_ni_syscall /* 275 - get_mempolicy */ - .long sys_ni_syscall /* set_mempolicy */ + .long sys_mbind + .long sys_get_mempolicy /* 275 */ + .long sys_set_mempolicy .long sys_mq_open .long sys_mq_unlink .long sys_mq_timedsend diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index 2d997e2a5b6..097ebd49f1b 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/kernel/topology.c b/arch/sh/kernel/topology.c new file mode 100644 index 00000000000..9b5844a1bda --- /dev/null +++ b/arch/sh/kernel/topology.c @@ -0,0 +1,49 @@ +/* + * arch/sh/kernel/topology.c + * + * 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 <linux/cpu.h> +#include <linux/cpumask.h> +#include <linux/init.h> +#include <linux/percpu.h> +#include <linux/node.h> +#include <linux/nodemask.h> + +static DEFINE_PER_CPU(struct cpu, cpu_devices); + +static int __init topology_init(void) +{ + int i, ret; + +#ifdef CONFIG_NEED_MULTIPLE_NODES + for_each_online_node(i) + register_one_node(i); +#endif + + for_each_present_cpu(i) { + ret = register_cpu(&per_cpu(cpu_devices, i), i); + if (unlikely(ret)) + printk(KERN_WARNING "%s: register_cpu %d failed (%d)\n", + __FUNCTION__, i, ret); + } + +#if defined(CONFIG_NUMA) && !defined(CONFIG_SMP) + /* + * In the UP case, make sure the CPU association is still + * registered under each node. Without this, sysfs fails + * to make the connection between nodes other than node0 + * and cpu0. + */ + for_each_online_node(i) + if (i != numa_node_id()) + register_cpu_under_node(raw_smp_processor_id(), i); +#endif + + return 0; +} +subsys_initcall(topology_init); diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 8f18930d5bf..05a40f3c30b 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -584,7 +584,7 @@ uspace_segv: info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = si_code; - info.si_addr = (void *) address; + info.si_addr = (void __user *)address; force_sig_info(SIGBUS, &info, current); } else { if (regs->pc & 1) @@ -617,7 +617,7 @@ uspace_segv: */ int is_dsp_inst(struct pt_regs *regs) { - unsigned short inst; + unsigned short inst = 0; /* * Safe guard if DSP mode is already enabled or we're lacking @@ -645,7 +645,6 @@ asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs __regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); siginfo_t info; switch (r4) { @@ -874,7 +873,7 @@ void __init trap_init(void) void handle_BUG(struct pt_regs *regs) { enum bug_trap_type tt; - tt = report_bug(regs->pc); + tt = report_bug(regs->pc, regs); if (tt == BUG_TRAP_TYPE_WARN) { regs->pc += 2; return; diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 4c5b57e9c3c..0696402f446 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -97,18 +97,20 @@ SECTIONS __initramfs_end = .; #endif + . = ALIGN(4); __machvec_start = .; - .init.machvec : { *(.init.machvec) } + .machvec.init : { *(.machvec.init) } __machvec_end = .; - . = ALIGN(PAGE_SIZE); - __init_end = .; - - . = ALIGN(4); - __bss_start = .; /* BSS */ - .bss : { *(.bss) } - . = ALIGN(4); - _end = . ; + . = ALIGN(PAGE_SIZE); + .bss : { + __init_end = .; + __bss_start = .; /* BSS */ + *(.bss.page_aligned) + *(.bss) + . = ALIGN(4); + _end = . ; + } /* When something in the kernel is NOT compiled as a module, the * module cleanup code and data are put into these segments. Both diff --git a/arch/sh/lib/div64-generic.c b/arch/sh/lib/div64-generic.c index c02473afd58..4bef3b5d964 100644 --- a/arch/sh/lib/div64-generic.c +++ b/arch/sh/lib/div64-generic.c @@ -4,16 +4,15 @@ #include <linux/types.h> -extern u64 __xdiv64_32(u64 n, u32 d); +extern uint64_t __xdiv64_32(u64 n, u32 d); -u64 __div64_32(u64 *xp, u32 y) +uint32_t __div64_32(u64 *xp, u32 y) { - u64 rem; - u64 q = __xdiv64_32(*xp, y); + uint32_t rem; + uint64_t q = __xdiv64_32(*xp, y); rem = *xp - q * y; *xp = q; return rem; } - diff --git a/arch/sh/lib/div64.S b/arch/sh/lib/div64.S index eefc275d64a..5ee7334ea64 100644 --- a/arch/sh/lib/div64.S +++ b/arch/sh/lib/div64.S @@ -1,12 +1,12 @@ /* - * unsigned long long __xdiv64_32(unsigned long long n, unsigned long d); + * unsigned long __xdiv64_32(unsigned long long n, unsigned long d); */ #include <linux/linkage.h> .text ENTRY(__xdiv64_32) -#ifdef __LITTLE_ENDIAN__ +#ifdef CONFIG_CPU_LITTLE_ENDIAN mov r4, r0 mov r5, r1 #else @@ -34,7 +34,7 @@ ENTRY(__xdiv64_32) rotcl r0 div1 r6, r1 .endr -#ifdef __LITTLE_ENDIAN__ +#ifdef CONFIG_CPU_LITTLE_ENDIAN mov r2, r1 rts rotcl r0 diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c index a38e1eed9e7..ac2d7abd256 100644 --- a/arch/sh/math-emu/math.c +++ b/arch/sh/math-emu/math.c @@ -507,6 +507,7 @@ static int ieee_fpe_handler(struct pt_regs *regs) unsigned short insn = *(unsigned short *)regs->pc; unsigned short finsn; unsigned long nextpc; + siginfo_t info; int nib[4] = { (insn >> 12) & 0xf, (insn >> 8) & 0xf, @@ -559,9 +560,11 @@ static int ieee_fpe_handler(struct pt_regs *regs) ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); set_tsk_thread_flag(tsk, TIF_USEDFPU); } else { - tsk->thread.trap_no = 11; - tsk->thread.error_code = 0; - force_sig(SIGFPE, tsk); + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_code = FPE_FLTINV; + info.si_addr = (void __user *)regs->pc; + force_sig_info(SIGFPE, &info, tsk); } regs->pc = nextpc; @@ -576,14 +579,17 @@ asmlinkage void do_fpu_error(unsigned long r4, unsigned long r5, struct pt_regs regs) { struct task_struct *tsk = current; + siginfo_t info; if (ieee_fpe_handler (®s)) return; regs.pc += 2; - tsk->thread.trap_no = 11; - tsk->thread.error_code = 0; - force_sig(SIGFPE, tsk); + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_code = FPE_FLTINV; + info.si_addr = (void __user *)regs.pc; + force_sig_info(SIGFPE, &info, tsk); } /** diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 253346d7b31..28d79a474cd 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -1,5 +1,3 @@ -menu "Processor selection" - # # Processor families # @@ -38,27 +36,31 @@ config CPU_SUBTYPE_ST40 config CPU_SHX2 bool +config CPU_SHX3 + bool + +choice + prompt "Processor sub-type selection" + # # Processor subtypes # -comment "SH-2 Processor Support" - -config CPU_SUBTYPE_SH7604 - bool "Support SH7604 processor" - select CPU_SH2 +# SH-2 Processor Support config CPU_SUBTYPE_SH7619 bool "Support SH7619 processor" select CPU_SH2 + select CPU_HAS_IPR_IRQ -comment "SH-2A Processor Support" +# SH-2A Processor Support config CPU_SUBTYPE_SH7206 bool "Support SH7206 processor" select CPU_SH2A + select CPU_HAS_IPR_IRQ -comment "SH-3 Processor Support" +# SH-3 Processor Support config CPU_SUBTYPE_SH7300 bool "Support SH7300 processor" @@ -113,7 +115,7 @@ config CPU_SUBTYPE_SH7712 help Select SH7712 if you have a SH3-DSP SH7712 CPU. -comment "SH-4 Processor Support" +# SH-4 Processor Support config CPU_SUBTYPE_SH7750 bool "Support SH7750 processor" @@ -125,7 +127,7 @@ config CPU_SUBTYPE_SH7750 config CPU_SUBTYPE_SH7091 bool "Support SH7091 processor" select CPU_SH4 - select CPU_SUBTYPE_SH7750 + select CPU_HAS_IPR_IRQ help Select SH7091 if you have an SH-4 based Sega device (such as the Dreamcast, Naomi, and Naomi 2). @@ -133,13 +135,11 @@ config CPU_SUBTYPE_SH7091 config CPU_SUBTYPE_SH7750R bool "Support SH7750R processor" select CPU_SH4 - select CPU_SUBTYPE_SH7750 select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH7750S bool "Support SH7750S processor" select CPU_SH4 - select CPU_SUBTYPE_SH7750 select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH7751 @@ -153,7 +153,6 @@ config CPU_SUBTYPE_SH7751 config CPU_SUBTYPE_SH7751R bool "Support SH7751R processor" select CPU_SH4 - select CPU_SUBTYPE_SH7751 select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH7760 @@ -166,7 +165,7 @@ config CPU_SUBTYPE_SH4_202 bool "Support SH4-202 processor" select CPU_SH4 -comment "ST40 Processor Support" +# ST40 Processor Support config CPU_SUBTYPE_ST40STB1 bool "Support ST40STB1/ST40RA processors" @@ -181,7 +180,7 @@ config CPU_SUBTYPE_ST40GX1 help Select ST40GX1 if you have a ST40GX1 CPU. -comment "SH-4A Processor Support" +# SH-4A Processor Support config CPU_SUBTYPE_SH7770 bool "Support SH7770 processor" @@ -198,7 +197,13 @@ config CPU_SUBTYPE_SH7785 select CPU_SHX2 select CPU_HAS_INTC2_IRQ -comment "SH4AL-DSP Processor Support" +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 bool "Support SH73180 processor" @@ -213,8 +218,10 @@ config CPU_SUBTYPE_SH7722 select CPU_SH4AL_DSP select CPU_SHX2 select CPU_HAS_IPR_IRQ + select ARCH_SPARSEMEM_ENABLE + select SYS_SUPPORTS_NUMA -endmenu +endchoice menu "Memory management options" @@ -266,7 +273,7 @@ config MEMORY_SIZE config 32BIT bool "Support 32-bit physical addressing through PMB" - depends on CPU_SH4A && MMU && (!X2TLB || BROKEN) + depends on MMU && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785) default y help If you say Y here, physical addressing will be extended to @@ -295,6 +302,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 && SYS_SUPPORTS_NUMA && 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" @@ -302,14 +320,34 @@ config NODES_SHIFT config ARCH_FLATMEM_ENABLE def_bool y + depends on !NUMA + +config ARCH_SPARSEMEM_ENABLE + def_bool y + select SPARSEMEM_STATIC + +config ARCH_SPARSEMEM_DEFAULT + def_bool y config MAX_ACTIVE_REGIONS int + default "2" if (CPU_SUBTYPE_SH7722 && SPARSEMEM) default "1" config ARCH_POPULATES_NODE_MAP def_bool y +config ARCH_SELECT_MEMORY_MODEL + def_bool y + +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + depends on SPARSEMEM + +config ARCH_MEMORY_PROBE + def_bool y + depends on MEMORY_HOTPLUG + choice prompt "Kernel page size" default PAGE_SIZE_4KB @@ -394,15 +432,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/Makefile b/arch/sh/mm/Makefile index 3ffd7f68c0a..d677d7f3afc 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -8,9 +8,6 @@ obj-$(CONFIG_CPU_SH2) += cache-sh2.o obj-$(CONFIG_CPU_SH3) += cache-sh3.o obj-$(CONFIG_CPU_SH4) += cache-sh4.o -obj-$(CONFIG_DMA_PAGE_OPS) += pg-dma.o -obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o - mmu-y := fault-nommu.o tlb-nommu.o pg-nommu.o mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o tlb-flush.o \ ioremap.o @@ -27,5 +24,7 @@ obj-$(CONFIG_CPU_SH4) += tlb-sh4.o pg-sh4.o obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o endif +obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o obj-$(CONFIG_32BIT) += pmb.o +obj-$(CONFIG_NUMA) += numa.o diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index c878faa4ae4..0b3eaf6fbb2 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -32,7 +32,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, struct task_struct *tsk; struct mm_struct *mm; struct vm_area_struct * vma; - unsigned long page; int si_code; siginfo_t info; @@ -170,24 +169,38 @@ no_context: * terminate things with extreme prejudice. * */ - if (address < PAGE_SIZE) - printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); - else - printk(KERN_ALERT "Unable to handle kernel paging request"); - printk(" at virtual address %08lx\n", address); - printk(KERN_ALERT "pc = %08lx\n", regs->pc); - page = (unsigned long)get_TTB(); - if (page) { - page = ((unsigned long *) page)[address >> PGDIR_SHIFT]; - printk(KERN_ALERT "*pde = %08lx\n", page); - if (page & _PAGE_PRESENT) { - page &= PAGE_MASK; - address &= 0x003ff000; - page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; - printk(KERN_ALERT "*pte = %08lx\n", page); + + bust_spinlocks(1); + + if (oops_may_print()) { + __typeof__(pte_val(__pte(0))) page; + + if (address < PAGE_SIZE) + printk(KERN_ALERT "Unable to handle kernel NULL " + "pointer dereference"); + else + printk(KERN_ALERT "Unable to handle kernel paging " + "request"); + printk(" at virtual address %08lx\n", address); + printk(KERN_ALERT "pc = %08lx\n", regs->pc); + page = (unsigned long)get_TTB(); + if (page) { + page = ((__typeof__(page) *) __va(page))[address >> + PGDIR_SHIFT]; + printk(KERN_ALERT "*pde = %08lx\n", page); + if (page & _PAGE_PRESENT) { + page &= PAGE_MASK; + address &= 0x003ff000; + page = ((__typeof__(page) *) + __va(page))[address >> + PAGE_SHIFT]; + printk(KERN_ALERT "*pte = %08lx\n", page); + } } } + die("Oops", regs, writeaccess); + bust_spinlocks(0); do_exit(SIGKILL); /* diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index e0e644ff320..82b68c789a5 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -18,6 +18,7 @@ #include <asm/mmu_context.h> #include <asm/tlb.h> #include <asm/cacheflush.h> +#include <asm/sections.h> #include <asm/cache.h> DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); @@ -36,14 +37,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 +53,7 @@ void show_mem(void) free++; else shared += page_count(page) - 1; - page++; - } while (page < end); - + } pgdat_resize_unlock(pgdat, &flags); } @@ -137,16 +133,12 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) } #endif /* CONFIG_MMU */ -/* References to section boundaries */ - -extern char _text, _etext, _edata, __bss_start, _end; -extern char __init_begin, __init_end; - /* * paging_init() sets up the page tables */ void __init paging_init(void) { + unsigned long max_zone_pfns[MAX_NR_ZONES]; int nid; /* We don't need to map the kernel through the TLB, as @@ -158,43 +150,39 @@ void __init paging_init(void) * check for a null value. */ set_TTB(swapper_pg_dir); + memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); + for_each_online_node(nid) { pg_data_t *pgdat = NODE_DATA(nid); - unsigned long max_zone_pfns[MAX_NR_ZONES]; unsigned long low, start_pfn; - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); - start_pfn = pgdat->bdata->node_boot_start >> PAGE_SHIFT; low = pgdat->bdata->node_low_pfn; - max_zone_pfns[ZONE_NORMAL] = low; - add_active_range(nid, start_pfn, low); + if (max_zone_pfns[ZONE_NORMAL] < low) + max_zone_pfns[ZONE_NORMAL] = 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); } + + free_area_init_nodes(max_zone_pfns); } 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; + num_physpages = 0; + high_memory = NULL; 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,13 +191,9 @@ 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); + node_high_memory = (void *)__va((pgdat->node_start_pfn + + pgdat->node_spanned_pages) << + PAGE_SHIFT); if (node_high_memory > high_memory) high_memory = node_high_memory; } @@ -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), + num_physpages << (PAGE_SHIFT-10), codesize >> 10, - reservedpages << (PAGE_SHIFT-10), datasize >> 10, initsize >> 10); @@ -264,7 +247,9 @@ void free_initmem(void) free_page(addr); totalram_pages++; } - printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); + printk("Freeing unused kernel memory: %ldk freed\n", + ((unsigned long)&__init_end - + (unsigned long)&__init_begin) >> 10); } #ifdef CONFIG_BLK_DEV_INITRD @@ -277,6 +262,50 @@ void free_initrd_mem(unsigned long start, unsigned long end) free_page(p); totalram_pages++; } - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + printk("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); +} +#endif + +#ifdef CONFIG_MEMORY_HOTPLUG +void online_page(struct page *page) +{ + ClearPageReserved(page); + init_page_count(page); + __free_page(page); + totalram_pages++; + num_physpages++; } + +int arch_add_memory(int nid, u64 start, u64 size) +{ + pg_data_t *pgdat; + unsigned long start_pfn = start >> PAGE_SHIFT; + unsigned long nr_pages = size >> PAGE_SHIFT; + int ret; + + pgdat = NODE_DATA(nid); + + /* We only have ZONE_NORMAL, so this is easy.. */ + ret = __add_pages(pgdat->node_zones + ZONE_NORMAL, start_pfn, nr_pages); + if (unlikely(ret)) + printk("%s: Failed, __add_pages() == %d\n", __FUNCTION__, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(arch_add_memory); + +int remove_memory(u64 start, u64 size) +{ + return -EINVAL; +} +EXPORT_SYMBOL_GPL(remove_memory); + +#ifdef CONFIG_NUMA +int memory_add_physaddr_to_nid(u64 addr) +{ + /* Node 0 for now.. */ + return 0; +} +EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); +#endif #endif diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c new file mode 100644 index 00000000000..8aff065dd30 --- /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 <linux/module.h> +#include <linux/bootmem.h> +#include <linux/mm.h> +#include <linux/numa.h> +#include <linux/pfn.h> +#include <asm/sections.h> + +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/arch/sh/mm/pg-dma.c b/arch/sh/mm/pg-dma.c deleted file mode 100644 index bb23679369d..00000000000 --- a/arch/sh/mm/pg-dma.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * arch/sh/mm/pg-dma.c - * - * Fast clear_page()/copy_page() implementation using the SH DMAC - * - * Copyright (C) 2003 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <asm/semaphore.h> -#include <asm/mmu_context.h> -#include <asm/addrspace.h> -#include <asm/atomic.h> -#include <asm/page.h> -#include <asm/dma.h> -#include <asm/io.h> - -/* Channel to use for page ops, must be dual-address mode capable. */ -static int dma_channel = CONFIG_DMA_PAGE_OPS_CHANNEL; - -static void copy_page_dma(void *to, void *from) -{ - /* - * This doesn't seem to get triggered until further along in the - * boot process, at which point the DMAC is already initialized. - * Fix this in the same fashion as clear_page_dma() in the event - * that this crashes due to the DMAC not being initialized. - */ - - flush_icache_range((unsigned long)from, PAGE_SIZE); - dma_write_page(dma_channel, (unsigned long)from, (unsigned long)to); - dma_wait_for_completion(dma_channel); -} - -static void clear_page_dma(void *to) -{ - /* - * We get invoked quite early on, if the DMAC hasn't been initialized - * yet, fall back on the slow manual implementation. - */ - if (dma_info[dma_channel].chan != dma_channel) { - clear_page_slow(to); - return; - } - - dma_write_page(dma_channel, (unsigned long)empty_zero_page, - (unsigned long)to); - - /* - * FIXME: Something is a bit racy here, if we poll the counter right - * away, we seem to lock. flushing the page from the dcache doesn't - * seem to make a difference one way or the other, though either a full - * icache or dcache flush does. - * - * The location of this is important as well, and must happen prior to - * the completion loop but after the transfer was initiated. - * - * Oddly enough, this doesn't appear to be an issue for copy_page().. - */ - flush_icache_range((unsigned long)to, PAGE_SIZE); - - dma_wait_for_completion(dma_channel); -} - -static int __init pg_dma_init(void) -{ - int ret; - - ret = request_dma(dma_channel, "page ops"); - if (ret != 0) - return ret; - - copy_page = copy_page_dma; - clear_page = clear_page_dma; - - return ret; -} - -static void __exit pg_dma_exit(void) -{ - free_dma(dma_channel); -} - -module_init(pg_dma_init); -module_exit(pg_dma_exit); - -MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); -MODULE_DESCRIPTION("Optimized page copy/clear routines using a dual-address mode capable DMAC channel"); -MODULE_LICENSE("GPL"); - diff --git a/arch/sh/tools/Makefile b/arch/sh/tools/Makefile index 3c370a11329..567516b58ac 100644 --- a/arch/sh/tools/Makefile +++ b/arch/sh/tools/Makefile @@ -12,4 +12,5 @@ include/asm-sh/machtypes.h: $(src)/gen-mach-types $(src)/mach-types @echo ' Generating $@' + $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index fb40f188aff..4b5e9305092 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 @@ -34,3 +33,4 @@ R7785RP SH_R7785RP TITAN SH_TITAN SHMIN SH_SHMIN 7710VOIPGW SH_7710VOIPGW +LBOXRE2 SH_LBOX_RE2 diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index e5eaa8072ae..ca26232da7a 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -160,9 +160,6 @@ static inline int srmmu_pte_none(pte_t pte) static inline int srmmu_pte_present(pte_t pte) { return ((pte_val(pte) & SRMMU_ET_MASK) == SRMMU_ET_PTE); } -static inline int srmmu_pte_read(pte_t pte) -{ return !(pte_val(pte) & SRMMU_NOREAD); } - static inline void srmmu_pte_clear(pte_t *ptep) { srmmu_set_pte(ptep, __pte(0)); } @@ -2181,7 +2178,6 @@ void __init ld_mmu_srmmu(void) BTFIXUPSET_CALL(pte_present, srmmu_pte_present, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_SWAPO0G0); - BTFIXUPSET_CALL(pte_read, srmmu_pte_read, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pmd_bad, srmmu_pmd_bad, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pmd_present, srmmu_pmd_present, BTFIXUPCALL_NORM); diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 436021ceb2e..bdd835fba02 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -1748,11 +1748,6 @@ static int sun4c_pte_present(pte_t pte) } static void sun4c_pte_clear(pte_t *ptep) { *ptep = __pte(0); } -static int sun4c_pte_read(pte_t pte) -{ - return (pte_val(pte) & _SUN4C_PAGE_READ); -} - static int sun4c_pmd_bad(pmd_t pmd) { return (((pmd_val(pmd) & ~PAGE_MASK) != PGD_TABLE) || @@ -2212,7 +2207,6 @@ void __init ld_mmu_sun4c(void) BTFIXUPSET_CALL(pte_present, sun4c_pte_present, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pte_clear, sun4c_pte_clear, BTFIXUPCALL_STG0O0); - BTFIXUPSET_CALL(pte_read, sun4c_pte_read, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pmd_bad, sun4c_pmd_bad, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pmd_present, sun4c_pmd_present, BTFIXUPCALL_NORM); diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 6566d13db04..b84b6af1241 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -108,6 +108,15 @@ config SECCOMP source kernel/Kconfig.hz +config HOTPLUG_CPU + bool "Support for hot-pluggable CPUs" + depends on SMP + select HOTPLUG + ---help--- + Say Y here to experiment with turning CPUs off and on. CPUs + can be controlled through /sys/devices/system/cpu/cpu#. + Say N if you want to disable CPU hotplug. + source "init/Kconfig" config SYSVIPC_COMPAT @@ -305,6 +314,12 @@ config SUN_IO bool default y +config SUN_LDOMS + bool "Sun Logical Domains support" + help + Say Y here is you want to support virtual devices via + Logical Domains. + config PCI bool "PCI support" select ARCH_SUPPORTS_MSI diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index f964bf28d21..b66876bf410 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -18,7 +18,7 @@ obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ pci_psycho.o pci_sabre.o pci_schizo.o \ pci_sun4v.o pci_sun4v_asm.o pci_fire.o -obj-$(CONFIG_SMP) += smp.o trampoline.o +obj-$(CONFIG_SMP) += smp.o trampoline.o hvtramp.o obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o @@ -26,6 +26,7 @@ obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o obj-$(CONFIG_KPROBES) += kprobes.o +obj-$(CONFIG_SUN_LDOMS) += ldc.o vio.o viohs.o ds.o obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o obj-y += $(obj-yy) diff --git a/arch/sparc64/kernel/ds.c b/arch/sparc64/kernel/ds.c new file mode 100644 index 00000000000..1c587107cef --- /dev/null +++ b/arch/sparc64/kernel/ds.c @@ -0,0 +1,1158 @@ +/* ds.c: Domain Services driver for Logical Domains + * + * Copyright (C) 2007 David S. Miller <davem@davemloft.net> + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include <linux/delay.h> +#include <linux/mutex.h> +#include <linux/kthread.h> +#include <linux/cpu.h> + +#include <asm/ldc.h> +#include <asm/vio.h> +#include <asm/power.h> +#include <asm/mdesc.h> +#include <asm/head.h> +#include <asm/irq.h> + +#define DRV_MODULE_NAME "ds" +#define PFX DRV_MODULE_NAME ": " +#define DRV_MODULE_VERSION "1.0" +#define DRV_MODULE_RELDATE "Jul 11, 2007" + +static char version[] __devinitdata = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; +MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); +MODULE_DESCRIPTION("Sun LDOM domain services driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_MODULE_VERSION); + +struct ds_msg_tag { + __u32 type; +#define DS_INIT_REQ 0x00 +#define DS_INIT_ACK 0x01 +#define DS_INIT_NACK 0x02 +#define DS_REG_REQ 0x03 +#define DS_REG_ACK 0x04 +#define DS_REG_NACK 0x05 +#define DS_UNREG_REQ 0x06 +#define DS_UNREG_ACK 0x07 +#define DS_UNREG_NACK 0x08 +#define DS_DATA 0x09 +#define DS_NACK 0x0a + + __u32 len; +}; + +/* Result codes */ +#define DS_OK 0x00 +#define DS_REG_VER_NACK 0x01 +#define DS_REG_DUP 0x02 +#define DS_INV_HDL 0x03 +#define DS_TYPE_UNKNOWN 0x04 + +struct ds_version { + __u16 major; + __u16 minor; +}; + +struct ds_ver_req { + struct ds_msg_tag tag; + struct ds_version ver; +}; + +struct ds_ver_ack { + struct ds_msg_tag tag; + __u16 minor; +}; + +struct ds_ver_nack { + struct ds_msg_tag tag; + __u16 major; +}; + +struct ds_reg_req { + struct ds_msg_tag tag; + __u64 handle; + __u16 major; + __u16 minor; + char svc_id[0]; +}; + +struct ds_reg_ack { + struct ds_msg_tag tag; + __u64 handle; + __u16 minor; +}; + +struct ds_reg_nack { + struct ds_msg_tag tag; + __u64 handle; + __u16 major; +}; + +struct ds_unreg_req { + struct ds_msg_tag tag; + __u64 handle; +}; + +struct ds_unreg_ack { + struct ds_msg_tag tag; + __u64 handle; +}; + +struct ds_unreg_nack { + struct ds_msg_tag tag; + __u64 handle; +}; + +struct ds_data { + struct ds_msg_tag tag; + __u64 handle; +}; + +struct ds_data_nack { + struct ds_msg_tag tag; + __u64 handle; + __u64 result; +}; + +struct ds_cap_state { + __u64 handle; + + void (*data)(struct ldc_channel *lp, + struct ds_cap_state *cp, + void *buf, int len); + + const char *service_id; + + u8 state; +#define CAP_STATE_UNKNOWN 0x00 +#define CAP_STATE_REG_SENT 0x01 +#define CAP_STATE_REGISTERED 0x02 +}; + +static void md_update_data(struct ldc_channel *lp, struct ds_cap_state *cp, + void *buf, int len); +static void domain_shutdown_data(struct ldc_channel *lp, + struct ds_cap_state *cp, + void *buf, int len); +static void domain_panic_data(struct ldc_channel *lp, + struct ds_cap_state *cp, + void *buf, int len); +#ifdef CONFIG_HOTPLUG_CPU +static void dr_cpu_data(struct ldc_channel *lp, + struct ds_cap_state *cp, + void *buf, int len); +#endif +static void ds_pri_data(struct ldc_channel *lp, + struct ds_cap_state *cp, + void *buf, int len); +static void ds_var_data(struct ldc_channel *lp, + struct ds_cap_state *cp, + void *buf, int len); + +struct ds_cap_state ds_states[] = { + { + .service_id = "md-update", + .data = md_update_data, + }, + { + .service_id = "domain-shutdown", + .data = domain_shutdown_data, + }, + { + .service_id = "domain-panic", + .data = domain_panic_data, + }, +#ifdef CONFIG_HOTPLUG_CPU + { + .service_id = "dr-cpu", + .data = dr_cpu_data, + }, +#endif + { + .service_id = "pri", + .data = ds_pri_data, + }, + { + .service_id = "var-config", + .data = ds_var_data, + }, + { + .service_id = "var-config-backup", + .data = ds_var_data, + }, +}; + +static DEFINE_SPINLOCK(ds_lock); + +struct ds_info { + struct ldc_channel *lp; + u8 hs_state; +#define DS_HS_START 0x01 +#define DS_HS_DONE 0x02 + + void *rcv_buf; + int rcv_buf_len; +}; + +static struct ds_info *ds_info; + +static struct ds_cap_state *find_cap(u64 handle) +{ + unsigned int index = handle >> 32; + + if (index >= ARRAY_SIZE(ds_states)) + return NULL; + return &ds_states[index]; +} + +static struct ds_cap_state *find_cap_by_string(const char *name) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ds_states); i++) { + if (strcmp(ds_states[i].service_id, name)) + continue; + + return &ds_states[i]; + } + return NULL; +} + +static int ds_send(struct ldc_channel *lp, void *data, int len) +{ + int err, limit = 1000; + + err = -EINVAL; + while (limit-- > 0) { + err = ldc_write(lp, data, len); + if (!err || (err != -EAGAIN)) + break; + udelay(1); + } + + return err; +} + +struct ds_md_update_req { + __u64 req_num; +}; + +struct ds_md_update_res { + __u64 req_num; + __u32 result; +}; + +static void md_update_data(struct ldc_channel *lp, + struct ds_cap_state *dp, + void *buf, int len) +{ + struct ds_data *dpkt = buf; + struct ds_md_update_req *rp; + struct { + struct ds_data data; + struct ds_md_update_res res; + } pkt; + + rp = (struct ds_md_update_req *) (dpkt + 1); + + printk(KERN_INFO PFX "Machine description update.\n"); + + memset(&pkt, 0, sizeof(pkt)); + pkt.data.tag.type = DS_DATA; + pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); + pkt.data.handle = dp->handle; + pkt.res.req_num = rp->req_num; + pkt.res.result = DS_OK; + + ds_send(lp, &pkt, sizeof(pkt)); + + mdesc_update(); +} + +struct ds_shutdown_req { + __u64 req_num; + __u32 ms_delay; +}; + +struct ds_shutdown_res { + __u64 req_num; + __u32 result; + char reason[1]; +}; + +static void domain_shutdown_data(struct ldc_channel *lp, + struct ds_cap_state *dp, + void *buf, int len) +{ + struct ds_data *dpkt = buf; + struct ds_shutdown_req *rp; + struct { + struct ds_data data; + struct ds_shutdown_res res; + } pkt; + + rp = (struct ds_shutdown_req *) (dpkt + 1); + + printk(KERN_ALERT PFX "Shutdown request from " + "LDOM manager received.\n"); + + memset(&pkt, 0, sizeof(pkt)); + pkt.data.tag.type = DS_DATA; + pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); + pkt.data.handle = dp->handle; + pkt.res.req_num = rp->req_num; + pkt.res.result = DS_OK; + pkt.res.reason[0] = 0; + + ds_send(lp, &pkt, sizeof(pkt)); + + wake_up_powerd(); +} + +struct ds_panic_req { + __u64 req_num; +}; + +struct ds_panic_res { + __u64 req_num; + __u32 result; + char reason[1]; +}; + +static void domain_panic_data(struct ldc_channel *lp, + struct ds_cap_state *dp, + void *buf, int len) +{ + struct ds_data *dpkt = buf; + struct ds_panic_req *rp; + struct { + struct ds_data data; + struct ds_panic_res res; + } pkt; + + rp = (struct ds_panic_req *) (dpkt + 1); + + printk(KERN_ALERT PFX "Panic request from " + "LDOM manager received.\n"); + + memset(&pkt, 0, sizeof(pkt)); + pkt.data.tag.type = DS_DATA; + pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); + pkt.data.handle = dp->handle; + pkt.res.req_num = rp->req_num; + pkt.res.result = DS_OK; + pkt.res.reason[0] = 0; + + ds_send(lp, &pkt, sizeof(pkt)); + + panic("PANIC requested by LDOM manager."); +} + +#ifdef CONFIG_HOTPLUG_CPU +struct dr_cpu_tag { + __u64 req_num; + __u32 type; +#define DR_CPU_CONFIGURE 0x43 +#define DR_CPU_UNCONFIGURE 0x55 +#define DR_CPU_FORCE_UNCONFIGURE 0x46 +#define DR_CPU_STATUS 0x53 + +/* Responses */ +#define DR_CPU_OK 0x6f +#define DR_CPU_ERROR 0x65 + + __u32 num_records; +}; + +struct dr_cpu_resp_entry { + __u32 cpu; + __u32 result; +#define DR_CPU_RES_OK 0x00 +#define DR_CPU_RES_FAILURE 0x01 +#define DR_CPU_RES_BLOCKED 0x02 +#define DR_CPU_RES_CPU_NOT_RESPONDING 0x03 +#define DR_CPU_RES_NOT_IN_MD 0x04 + + __u32 stat; +#define DR_CPU_STAT_NOT_PRESENT 0x00 +#define DR_CPU_STAT_UNCONFIGURED 0x01 +#define DR_CPU_STAT_CONFIGURED 0x02 + + __u32 str_off; +}; + +/* DR cpu requests get queued onto the work list by the + * dr_cpu_data() callback. The list is protected by + * ds_lock, and processed by dr_cpu_process() in order. + */ +static LIST_HEAD(dr_cpu_work_list); +static DECLARE_WAIT_QUEUE_HEAD(dr_cpu_wait); + +struct dr_cpu_queue_entry { + struct list_head list; + char req[0]; +}; + +static void __dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data) +{ + struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1); + struct ds_info *dp = ds_info; + struct { + struct ds_data data; + struct dr_cpu_tag tag; + } pkt; + int msg_len; + + memset(&pkt, 0, sizeof(pkt)); + pkt.data.tag.type = DS_DATA; + pkt.data.handle = cp->handle; + pkt.tag.req_num = tag->req_num; + pkt.tag.type = DR_CPU_ERROR; + pkt.tag.num_records = 0; + + msg_len = (sizeof(struct ds_data) + + sizeof(struct dr_cpu_tag)); + + pkt.data.tag.len = msg_len - sizeof(struct ds_msg_tag); + + ds_send(dp->lp, &pkt, msg_len); +} + +static void dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data) +{ + unsigned long flags; + + spin_lock_irqsave(&ds_lock, flags); + __dr_cpu_send_error(cp, data); + spin_unlock_irqrestore(&ds_lock, flags); +} + +#define CPU_SENTINEL 0xffffffff + +static void purge_dups(u32 *list, u32 num_ents) +{ + unsigned int i; + + for (i = 0; i < num_ents; i++) { + u32 cpu = list[i]; + unsigned int j; + + if (cpu == CPU_SENTINEL) + continue; + + for (j = i + 1; j < num_ents; j++) { + if (list[j] == cpu) + list[j] = CPU_SENTINEL; + } + } +} + +static int dr_cpu_size_response(int ncpus) +{ + return (sizeof(struct ds_data) + + sizeof(struct dr_cpu_tag) + + (sizeof(struct dr_cpu_resp_entry) * ncpus)); +} + +static void dr_cpu_init_response(struct ds_data *resp, u64 req_num, + u64 handle, int resp_len, int ncpus, + cpumask_t *mask, u32 default_stat) +{ + struct dr_cpu_resp_entry *ent; + struct dr_cpu_tag *tag; + int i, cpu; + + tag = (struct dr_cpu_tag *) (resp + 1); + ent = (struct dr_cpu_resp_entry *) (tag + 1); + + resp->tag.type = DS_DATA; + resp->tag.len = resp_len - sizeof(struct ds_msg_tag); + resp->handle = handle; + tag->req_num = req_num; + tag->type = DR_CPU_OK; + tag->num_records = ncpus; + + i = 0; + for_each_cpu_mask(cpu, *mask) { + ent[i].cpu = cpu; + ent[i].result = DR_CPU_RES_OK; + ent[i].stat = default_stat; + i++; + } + BUG_ON(i != ncpus); +} + +static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus, + u32 res, u32 stat) +{ + struct dr_cpu_resp_entry *ent; + struct dr_cpu_tag *tag; + int i; + + tag = (struct dr_cpu_tag *) (resp + 1); + ent = (struct dr_cpu_resp_entry *) (tag + 1); + + for (i = 0; i < ncpus; i++) { + if (ent[i].cpu != cpu) + continue; + ent[i].result = res; + ent[i].stat = stat; + break; + } +} + +static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num, + cpumask_t *mask) +{ + struct ds_data *resp; + int resp_len, ncpus, cpu; + unsigned long flags; + + ncpus = cpus_weight(*mask); + resp_len = dr_cpu_size_response(ncpus); + resp = kzalloc(resp_len, GFP_KERNEL); + if (!resp) + return -ENOMEM; + + dr_cpu_init_response(resp, req_num, cp->handle, + resp_len, ncpus, mask, + DR_CPU_STAT_CONFIGURED); + + mdesc_fill_in_cpu_data(*mask); + + for_each_cpu_mask(cpu, *mask) { + int err; + + printk(KERN_INFO PFX "Starting cpu %d...\n", cpu); + err = cpu_up(cpu); + if (err) { + __u32 res = DR_CPU_RES_FAILURE; + __u32 stat = DR_CPU_STAT_UNCONFIGURED; + + if (!cpu_present(cpu)) { + /* CPU not present in MD */ + res = DR_CPU_RES_NOT_IN_MD; + stat = DR_CPU_STAT_NOT_PRESENT; + } else if (err == -ENODEV) { + /* CPU did not call in successfully */ + res = DR_CPU_RES_CPU_NOT_RESPONDING; + } + + printk(KERN_INFO PFX "CPU startup failed err=%d\n", + err); + dr_cpu_mark(resp, cpu, ncpus, res, stat); + } + } + + spin_lock_irqsave(&ds_lock, flags); + ds_send(ds_info->lp, resp, resp_len); + spin_unlock_irqrestore(&ds_lock, flags); + + kfree(resp); + + /* Redistribute IRQs, taking into account the new cpus. */ + fixup_irqs(); + + return 0; +} + +static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num, + cpumask_t *mask) +{ + struct ds_data *resp; + int resp_len, ncpus, cpu; + unsigned long flags; + + ncpus = cpus_weight(*mask); + resp_len = dr_cpu_size_response(ncpus); + resp = kzalloc(resp_len, GFP_KERNEL); + if (!resp) + return -ENOMEM; + + dr_cpu_init_response(resp, req_num, cp->handle, + resp_len, ncpus, mask, + DR_CPU_STAT_UNCONFIGURED); + + for_each_cpu_mask(cpu, *mask) { + int err; + + printk(KERN_INFO PFX "CPU[%d]: Shutting down cpu %d...\n", + smp_processor_id(), cpu); + err = cpu_down(cpu); + if (err) + dr_cpu_mark(resp, cpu, ncpus, + DR_CPU_RES_FAILURE, + DR_CPU_STAT_CONFIGURED); + } + + spin_lock_irqsave(&ds_lock, flags); + ds_send(ds_info->lp, resp, resp_len); + spin_unlock_irqrestore(&ds_lock, flags); + + kfree(resp); + + return 0; +} + +static void process_dr_cpu_list(struct ds_cap_state *cp) +{ + struct dr_cpu_queue_entry *qp, *tmp; + unsigned long flags; + LIST_HEAD(todo); + cpumask_t mask; + + spin_lock_irqsave(&ds_lock, flags); + list_splice(&dr_cpu_work_list, &todo); + INIT_LIST_HEAD(&dr_cpu_work_list); + spin_unlock_irqrestore(&ds_lock, flags); + + list_for_each_entry_safe(qp, tmp, &todo, list) { + struct ds_data *data = (struct ds_data *) qp->req; + struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1); + u32 *cpu_list = (u32 *) (tag + 1); + u64 req_num = tag->req_num; + unsigned int i; + int err; + + switch (tag->type) { + case DR_CPU_CONFIGURE: + case DR_CPU_UNCONFIGURE: + case DR_CPU_FORCE_UNCONFIGURE: + break; + + default: + dr_cpu_send_error(cp, data); + goto next; + } + + purge_dups(cpu_list, tag->num_records); + + cpus_clear(mask); + for (i = 0; i < tag->num_records; i++) { + if (cpu_list[i] == CPU_SENTINEL) + continue; + + if (cpu_list[i] < NR_CPUS) + cpu_set(cpu_list[i], mask); + } + + if (tag->type == DR_CPU_CONFIGURE) + err = dr_cpu_configure(cp, req_num, &mask); + else + err = dr_cpu_unconfigure(cp, req_num, &mask); + + if (err) + dr_cpu_send_error(cp, data); + +next: + list_del(&qp->list); + kfree(qp); + } +} + +static int dr_cpu_thread(void *__unused) +{ + struct ds_cap_state *cp; + DEFINE_WAIT(wait); + + cp = find_cap_by_string("dr-cpu"); + + while (1) { + prepare_to_wait(&dr_cpu_wait, &wait, TASK_INTERRUPTIBLE); + if (list_empty(&dr_cpu_work_list)) + schedule(); + finish_wait(&dr_cpu_wait, &wait); + + if (kthread_should_stop()) + break; + + process_dr_cpu_list(cp); + } + + return 0; +} + +static void dr_cpu_data(struct ldc_channel *lp, + struct ds_cap_state *dp, + void *buf, int len) +{ + struct dr_cpu_queue_entry *qp; + struct ds_data *dpkt = buf; + struct dr_cpu_tag *rp; + + rp = (struct dr_cpu_tag *) (dpkt + 1); + + qp = kmalloc(sizeof(struct dr_cpu_queue_entry) + len, GFP_ATOMIC); + if (!qp) { + struct ds_cap_state *cp; + + cp = find_cap_by_string("dr-cpu"); + __dr_cpu_send_error(cp, dpkt); + } else { + memcpy(&qp->req, buf, len); + list_add_tail(&qp->list, &dr_cpu_work_list); + wake_up(&dr_cpu_wait); + } +} +#endif + +struct ds_pri_msg { + __u64 req_num; + __u64 type; +#define DS_PRI_REQUEST 0x00 +#define DS_PRI_DATA 0x01 +#define DS_PRI_UPDATE 0x02 +}; + +static void ds_pri_data(struct ldc_channel *lp, + struct ds_cap_state *dp, + void *buf, int len) +{ + struct ds_data *dpkt = buf; + struct ds_pri_msg *rp; + + rp = (struct ds_pri_msg *) (dpkt + 1); + + printk(KERN_INFO PFX "PRI REQ [%lx:%lx], len=%d\n", + rp->req_num, rp->type, len); +} + +struct ds_var_hdr { + __u32 type; +#define DS_VAR_SET_REQ 0x00 +#define DS_VAR_DELETE_REQ 0x01 +#define DS_VAR_SET_RESP 0x02 +#define DS_VAR_DELETE_RESP 0x03 +}; + +struct ds_var_set_msg { + struct ds_var_hdr hdr; + char name_and_value[0]; +}; + +struct ds_var_delete_msg { + struct ds_var_hdr hdr; + char name[0]; +}; + +struct ds_var_resp { + struct ds_var_hdr hdr; + __u32 result; +#define DS_VAR_SUCCESS 0x00 +#define DS_VAR_NO_SPACE 0x01 +#define DS_VAR_INVALID_VAR 0x02 +#define DS_VAR_INVALID_VAL 0x03 +#define DS_VAR_NOT_PRESENT 0x04 +}; + +static DEFINE_MUTEX(ds_var_mutex); +static int ds_var_doorbell; +static int ds_var_response; + +static void ds_var_data(struct ldc_channel *lp, + struct ds_cap_state *dp, + void *buf, int len) +{ + struct ds_data *dpkt = buf; + struct ds_var_resp *rp; + + rp = (struct ds_var_resp *) (dpkt + 1); + + if (rp->hdr.type != DS_VAR_SET_RESP && + rp->hdr.type != DS_VAR_DELETE_RESP) + return; + + ds_var_response = rp->result; + wmb(); + ds_var_doorbell = 1; +} + +void ldom_set_var(const char *var, const char *value) +{ + struct ds_info *dp = ds_info; + struct ds_cap_state *cp; + + cp = find_cap_by_string("var-config"); + if (cp->state != CAP_STATE_REGISTERED) + cp = find_cap_by_string("var-config-backup"); + + if (cp->state == CAP_STATE_REGISTERED) { + union { + struct { + struct ds_data data; + struct ds_var_set_msg msg; + } header; + char all[512]; + } pkt; + unsigned long flags; + char *base, *p; + int msg_len, loops; + + memset(&pkt, 0, sizeof(pkt)); + pkt.header.data.tag.type = DS_DATA; + pkt.header.data.handle = cp->handle; + pkt.header.msg.hdr.type = DS_VAR_SET_REQ; + base = p = &pkt.header.msg.name_and_value[0]; + strcpy(p, var); + p += strlen(var) + 1; + strcpy(p, value); + p += strlen(value) + 1; + + msg_len = (sizeof(struct ds_data) + + sizeof(struct ds_var_set_msg) + + (p - base)); + msg_len = (msg_len + 3) & ~3; + pkt.header.data.tag.len = msg_len - sizeof(struct ds_msg_tag); + + mutex_lock(&ds_var_mutex); + + spin_lock_irqsave(&ds_lock, flags); + ds_var_doorbell = 0; + ds_var_response = -1; + + ds_send(dp->lp, &pkt, msg_len); + spin_unlock_irqrestore(&ds_lock, flags); + + loops = 1000; + while (ds_var_doorbell == 0) { + if (loops-- < 0) + break; + barrier(); + udelay(100); + } + + mutex_unlock(&ds_var_mutex); + + if (ds_var_doorbell == 0 || + ds_var_response != DS_VAR_SUCCESS) + printk(KERN_ERR PFX "var-config [%s:%s] " + "failed, response(%d).\n", + var, value, + ds_var_response); + } else { + printk(KERN_ERR PFX "var-config not registered so " + "could not set (%s) variable to (%s).\n", + var, value); + } +} + +void ldom_reboot(const char *boot_command) +{ + /* Don't bother with any of this if the boot_command + * is empty. + */ + if (boot_command && strlen(boot_command)) { + char full_boot_str[256]; + + strcpy(full_boot_str, "boot "); + strcpy(full_boot_str + strlen("boot "), boot_command); + + ldom_set_var("reboot-command", full_boot_str); + } + sun4v_mach_sir(); +} + +void ldom_power_off(void) +{ + sun4v_mach_exit(0); +} + +static void ds_conn_reset(struct ds_info *dp) +{ + printk(KERN_ERR PFX "ds_conn_reset() from %p\n", + __builtin_return_address(0)); +} + +static int register_services(struct ds_info *dp) +{ + struct ldc_channel *lp = dp->lp; + int i; + + for (i = 0; i < ARRAY_SIZE(ds_states); i++) { + struct { + struct ds_reg_req req; + u8 id_buf[256]; + } pbuf; + struct ds_cap_state *cp = &ds_states[i]; + int err, msg_len; + u64 new_count; + + if (cp->state == CAP_STATE_REGISTERED) + continue; + + new_count = sched_clock() & 0xffffffff; + cp->handle = ((u64) i << 32) | new_count; + + msg_len = (sizeof(struct ds_reg_req) + + strlen(cp->service_id)); + + memset(&pbuf, 0, sizeof(pbuf)); + pbuf.req.tag.type = DS_REG_REQ; + pbuf.req.tag.len = (msg_len - sizeof(struct ds_msg_tag)); + pbuf.req.handle = cp->handle; + pbuf.req.major = 1; + pbuf.req.minor = 0; + strcpy(pbuf.req.svc_id, cp->service_id); + + err = ds_send(lp, &pbuf, msg_len); + if (err > 0) + cp->state = CAP_STATE_REG_SENT; + } + return 0; +} + +static int ds_handshake(struct ds_info *dp, struct ds_msg_tag *pkt) +{ + + if (dp->hs_state == DS_HS_START) { + if (pkt->type != DS_INIT_ACK) + goto conn_reset; + + dp->hs_state = DS_HS_DONE; + + return register_services(dp); + } + + if (dp->hs_state != DS_HS_DONE) + goto conn_reset; + + if (pkt->type == DS_REG_ACK) { + struct ds_reg_ack *ap = (struct ds_reg_ack *) pkt; + struct ds_cap_state *cp = find_cap(ap->handle); + + if (!cp) { + printk(KERN_ERR PFX "REG ACK for unknown handle %lx\n", + ap->handle); + return 0; + } + printk(KERN_INFO PFX "Registered %s service.\n", + cp->service_id); + cp->state = CAP_STATE_REGISTERED; + } else if (pkt->type == DS_REG_NACK) { + struct ds_reg_nack *np = (struct ds_reg_nack *) pkt; + struct ds_cap_state *cp = find_cap(np->handle); + + if (!cp) { + printk(KERN_ERR PFX "REG NACK for " + "unknown handle %lx\n", + np->handle); + return 0; + } + printk(KERN_INFO PFX "Could not register %s service\n", + cp->service_id); + cp->state = CAP_STATE_UNKNOWN; + } + + return 0; + +conn_reset: + ds_conn_reset(dp); + return -ECONNRESET; +} + +static int ds_data(struct ds_info *dp, struct ds_msg_tag *pkt, int len) +{ + struct ds_data *dpkt = (struct ds_data *) pkt; + struct ds_cap_state *cp = find_cap(dpkt->handle); + + if (!cp) { + struct ds_data_nack nack = { + .tag = { + .type = DS_NACK, + .len = (sizeof(struct ds_data_nack) - + sizeof(struct ds_msg_tag)), + }, + .handle = dpkt->handle, + .result = DS_INV_HDL, + }; + + printk(KERN_ERR PFX "Data for unknown handle %lu\n", + dpkt->handle); + ds_send(dp->lp, &nack, sizeof(nack)); + } else { + cp->data(dp->lp, cp, dpkt, len); + } + return 0; +} + +static void ds_up(struct ds_info *dp) +{ + struct ldc_channel *lp = dp->lp; + struct ds_ver_req req; + int err; + + req.tag.type = DS_INIT_REQ; + req.tag.len = sizeof(req) - sizeof(struct ds_msg_tag); + req.ver.major = 1; + req.ver.minor = 0; + + err = ds_send(lp, &req, sizeof(req)); + if (err > 0) + dp->hs_state = DS_HS_START; +} + +static void ds_event(void *arg, int event) +{ + struct ds_info *dp = arg; + struct ldc_channel *lp = dp->lp; + unsigned long flags; + int err; + + spin_lock_irqsave(&ds_lock, flags); + + if (event == LDC_EVENT_UP) { + ds_up(dp); + spin_unlock_irqrestore(&ds_lock, flags); + return; + } + + if (event != LDC_EVENT_DATA_READY) { + printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event); + spin_unlock_irqrestore(&ds_lock, flags); + return; + } + + err = 0; + while (1) { + struct ds_msg_tag *tag; + + err = ldc_read(lp, dp->rcv_buf, sizeof(*tag)); + + if (unlikely(err < 0)) { + if (err == -ECONNRESET) + ds_conn_reset(dp); + break; + } + if (err == 0) + break; + + tag = dp->rcv_buf; + err = ldc_read(lp, tag + 1, tag->len); + + if (unlikely(err < 0)) { + if (err == -ECONNRESET) + ds_conn_reset(dp); + break; + } + if (err < tag->len) + break; + + if (tag->type < DS_DATA) + err = ds_handshake(dp, dp->rcv_buf); + else + err = ds_data(dp, dp->rcv_buf, + sizeof(*tag) + err); + if (err == -ECONNRESET) + break; + } + + spin_unlock_irqrestore(&ds_lock, flags); +} + +static int __devinit ds_probe(struct vio_dev *vdev, + const struct vio_device_id *id) +{ + static int ds_version_printed; + struct ldc_channel_config ds_cfg = { + .event = ds_event, + .mtu = 4096, + .mode = LDC_MODE_STREAM, + }; + struct ldc_channel *lp; + struct ds_info *dp; + int err; + + if (ds_version_printed++ == 0) + printk(KERN_INFO "%s", version); + + dp = kzalloc(sizeof(*dp), GFP_KERNEL); + err = -ENOMEM; + if (!dp) + goto out_err; + + dp->rcv_buf = kzalloc(4096, GFP_KERNEL); + if (!dp->rcv_buf) + goto out_free_dp; + + dp->rcv_buf_len = 4096; + + ds_cfg.tx_irq = vdev->tx_irq; + ds_cfg.rx_irq = vdev->rx_irq; + + lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + goto out_free_rcv_buf; + } + dp->lp = lp; + + err = ldc_bind(lp, "DS"); + if (err) + goto out_free_ldc; + + ds_info = dp; + + start_powerd(); + + return err; + +out_free_ldc: + ldc_free(dp->lp); + +out_free_rcv_buf: + kfree(dp->rcv_buf); + +out_free_dp: + kfree(dp); + +out_err: + return err; +} + +static int ds_remove(struct vio_dev *vdev) +{ + return 0; +} + +static struct vio_device_id ds_match[] = { + { + .type = "domain-services-port", + }, + {}, +}; + +static struct vio_driver ds_driver = { + .id_table = ds_match, + .probe = ds_probe, + .remove = ds_remove, + .driver = { + .name = "ds", + .owner = THIS_MODULE, + } +}; + +static int __init ds_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ds_states); i++) + ds_states[i].handle = ((u64)i << 32); + +#ifdef CONFIG_HOTPLUG_CPU + kthread_run(dr_cpu_thread, NULL, "kdrcpud"); +#endif + + return vio_register_driver(&ds_driver); +} + +subsys_initcall(ds_init); diff --git a/arch/sparc64/kernel/hvtramp.S b/arch/sparc64/kernel/hvtramp.S new file mode 100644 index 00000000000..76a090e2c2a --- /dev/null +++ b/arch/sparc64/kernel/hvtramp.S @@ -0,0 +1,139 @@ +/* hvtramp.S: Hypervisor start-cpu trampoline code. + * + * Copyright (C) 2007 David S. Miller <davem@davemloft.net> + */ + +#include <asm/thread_info.h> +#include <asm/hypervisor.h> +#include <asm/scratchpad.h> +#include <asm/spitfire.h> +#include <asm/hvtramp.h> +#include <asm/pstate.h> +#include <asm/ptrace.h> +#include <asm/asi.h> + + .text + .align 8 + .globl hv_cpu_startup, hv_cpu_startup_end + + /* This code executes directly out of the hypervisor + * with physical addressing (va==pa). %o0 contains + * our client argument which for Linux points to + * a descriptor data structure which defines the + * MMU entries we need to load up. + * + * After we set things up we enable the MMU and call + * into the kernel. + * + * First setup basic privileged cpu state. + */ +hv_cpu_startup: + wrpr %g0, 0, %gl + wrpr %g0, 15, %pil + wrpr %g0, 0, %canrestore + wrpr %g0, 0, %otherwin + wrpr %g0, 6, %cansave + wrpr %g0, 6, %cleanwin + wrpr %g0, 0, %cwp + wrpr %g0, 0, %wstate + wrpr %g0, 0, %tl + + sethi %hi(sparc64_ttable_tl0), %g1 + wrpr %g1, %tba + + mov %o0, %l0 + + lduw [%l0 + HVTRAMP_DESCR_CPU], %g1 + mov SCRATCHPAD_CPUID, %g2 + stxa %g1, [%g2] ASI_SCRATCHPAD + + ldx [%l0 + HVTRAMP_DESCR_FAULT_INFO_VA], %g2 + stxa %g2, [%g0] ASI_SCRATCHPAD + + mov 0, %l1 + lduw [%l0 + HVTRAMP_DESCR_NUM_MAPPINGS], %l2 + add %l0, HVTRAMP_DESCR_MAPS, %l3 + +1: ldx [%l3 + HVTRAMP_MAPPING_VADDR], %o0 + clr %o1 + ldx [%l3 + HVTRAMP_MAPPING_TTE], %o2 + mov HV_MMU_IMMU | HV_MMU_DMMU, %o3 + mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 + ta HV_FAST_TRAP + + brnz,pn %o0, 80f + nop + + add %l1, 1, %l1 + cmp %l1, %l2 + blt,a,pt %xcc, 1b + add %l3, HVTRAMP_MAPPING_SIZE, %l3 + + ldx [%l0 + HVTRAMP_DESCR_FAULT_INFO_PA], %o0 + mov HV_FAST_MMU_FAULT_AREA_CONF, %o5 + ta HV_FAST_TRAP + + brnz,pn %o0, 80f + nop + + wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate + + ldx [%l0 + HVTRAMP_DESCR_THREAD_REG], %l6 + + mov 1, %o0 + set 1f, %o1 + mov HV_FAST_MMU_ENABLE, %o5 + ta HV_FAST_TRAP + + ba,pt %xcc, 80f + nop + +1: + wr %g0, 0, %fprs + wr %g0, ASI_P, %asi + + mov PRIMARY_CONTEXT, %g7 + stxa %g0, [%g7] ASI_MMU + membar #Sync + + mov SECONDARY_CONTEXT, %g7 + stxa %g0, [%g7] ASI_MMU + membar #Sync + + mov %l6, %g6 + ldx [%g6 + TI_TASK], %g4 + + mov 1, %g5 + sllx %g5, THREAD_SHIFT, %g5 + sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5 + add %g6, %g5, %sp + mov 0, %fp + + call init_irqwork_curcpu + nop + call hard_smp_processor_id + nop + + mov %o0, %o1 + mov 0, %o0 + mov 0, %o2 + call sun4v_init_mondo_queues + mov 1, %o3 + + call init_cur_cpu_trap + mov %g6, %o0 + + wrpr %g0, (PSTATE_PRIV | PSTATE_PEF | PSTATE_IE), %pstate + + call smp_callin + nop + call cpu_idle + mov 0, %o0 + call cpu_panic + nop + +80: ba,pt %xcc, 80b + nop + + .align 8 +hv_cpu_startup_end: diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 6b6165d36fd..8cb3358674f 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -293,6 +293,11 @@ static void sun4u_irq_enable(unsigned int virt_irq) } } +static void sun4u_set_affinity(unsigned int virt_irq, cpumask_t mask) +{ + sun4u_irq_enable(virt_irq); +} + static void sun4u_irq_disable(unsigned int virt_irq) { struct irq_handler_data *data = get_irq_chip_data(virt_irq); @@ -309,6 +314,10 @@ static void sun4u_irq_disable(unsigned int virt_irq) static void sun4u_irq_end(unsigned int virt_irq) { struct irq_handler_data *data = get_irq_chip_data(virt_irq); + struct irq_desc *desc = irq_desc + virt_irq; + + if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) + return; if (likely(data)) upa_writeq(ICLR_IDLE, data->iclr); @@ -340,6 +349,24 @@ static void sun4v_irq_enable(unsigned int virt_irq) } } +static void sun4v_set_affinity(unsigned int virt_irq, cpumask_t mask) +{ + struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); + unsigned int ino = bucket - &ivector_table[0]; + + if (likely(bucket)) { + unsigned long cpuid; + int err; + + cpuid = irq_choose_cpu(virt_irq); + + err = sun4v_intr_settarget(ino, cpuid); + if (err != HV_EOK) + printk("sun4v_intr_settarget(%x,%lu): err(%d)\n", + ino, cpuid, err); + } +} + static void sun4v_irq_disable(unsigned int virt_irq) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); @@ -373,6 +400,10 @@ static void sun4v_irq_end(unsigned int virt_irq) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); unsigned int ino = bucket - &ivector_table[0]; + struct irq_desc *desc = irq_desc + virt_irq; + + if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) + return; if (likely(bucket)) { int err; @@ -418,6 +449,28 @@ static void sun4v_virq_enable(unsigned int virt_irq) } } +static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask) +{ + struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); + unsigned int ino = bucket - &ivector_table[0]; + + if (likely(bucket)) { + unsigned long cpuid, dev_handle, dev_ino; + int err; + + cpuid = irq_choose_cpu(virt_irq); + + dev_handle = ino & IMAP_IGN; + dev_ino = ino & IMAP_INO; + + err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); + if (err != HV_EOK) + printk("sun4v_vintr_set_target(%lx,%lx,%lu): " + "err(%d)\n", + dev_handle, dev_ino, cpuid, err); + } +} + static void sun4v_virq_disable(unsigned int virt_irq) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); @@ -443,6 +496,10 @@ static void sun4v_virq_end(unsigned int virt_irq) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); unsigned int ino = bucket - &ivector_table[0]; + struct irq_desc *desc = irq_desc + virt_irq; + + if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) + return; if (likely(bucket)) { unsigned long dev_handle, dev_ino; @@ -477,6 +534,7 @@ static struct irq_chip sun4u_irq = { .enable = sun4u_irq_enable, .disable = sun4u_irq_disable, .end = sun4u_irq_end, + .set_affinity = sun4u_set_affinity, }; static struct irq_chip sun4u_irq_ack = { @@ -485,6 +543,7 @@ static struct irq_chip sun4u_irq_ack = { .disable = sun4u_irq_disable, .ack = run_pre_handler, .end = sun4u_irq_end, + .set_affinity = sun4u_set_affinity, }; static struct irq_chip sun4v_irq = { @@ -492,6 +551,7 @@ static struct irq_chip sun4v_irq = { .enable = sun4v_irq_enable, .disable = sun4v_irq_disable, .end = sun4v_irq_end, + .set_affinity = sun4v_set_affinity, }; static struct irq_chip sun4v_irq_ack = { @@ -500,6 +560,7 @@ static struct irq_chip sun4v_irq_ack = { .disable = sun4v_irq_disable, .ack = run_pre_handler, .end = sun4v_irq_end, + .set_affinity = sun4v_set_affinity, }; #ifdef CONFIG_PCI_MSI @@ -511,6 +572,7 @@ static struct irq_chip sun4v_msi = { .disable = sun4v_msi_disable, .ack = run_pre_handler, .end = sun4v_irq_end, + .set_affinity = sun4v_set_affinity, }; #endif @@ -519,6 +581,7 @@ static struct irq_chip sun4v_virq = { .enable = sun4v_virq_enable, .disable = sun4v_virq_disable, .end = sun4v_virq_end, + .set_affinity = sun4v_virt_set_affinity, }; static struct irq_chip sun4v_virq_ack = { @@ -527,6 +590,7 @@ static struct irq_chip sun4v_virq_ack = { .disable = sun4v_virq_disable, .ack = run_pre_handler, .end = sun4v_virq_end, + .set_affinity = sun4v_virt_set_affinity, }; void irq_install_pre_handler(int virt_irq, @@ -739,6 +803,26 @@ void handler_irq(int irq, struct pt_regs *regs) set_irq_regs(old_regs); } +#ifdef CONFIG_HOTPLUG_CPU +void fixup_irqs(void) +{ + unsigned int irq; + + for (irq = 0; irq < NR_IRQS; irq++) { + unsigned long flags; + + spin_lock_irqsave(&irq_desc[irq].lock, flags); + if (irq_desc[irq].action && + !(irq_desc[irq].status & IRQ_PER_CPU)) { + if (irq_desc[irq].chip->set_affinity) + irq_desc[irq].chip->set_affinity(irq, + irq_desc[irq].affinity); + } + spin_unlock_irqrestore(&irq_desc[irq].lock, flags); + } +} +#endif + struct sun5_timer { u64 count0; u64 limit0; diff --git a/arch/sparc64/kernel/ldc.c b/arch/sparc64/kernel/ldc.c new file mode 100644 index 00000000000..85a2be0b096 --- /dev/null +++ b/arch/sparc64/kernel/ldc.c @@ -0,0 +1,2373 @@ +/* ldc.c: Logical Domain Channel link-layer protocol driver. + * + * Copyright (C) 2007 David S. Miller <davem@davemloft.net> + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/spinlock.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/scatterlist.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/init.h> + +#include <asm/hypervisor.h> +#include <asm/iommu.h> +#include <asm/page.h> +#include <asm/ldc.h> +#include <asm/mdesc.h> + +#define DRV_MODULE_NAME "ldc" +#define PFX DRV_MODULE_NAME ": " +#define DRV_MODULE_VERSION "1.0" +#define DRV_MODULE_RELDATE "June 25, 2007" + +static char version[] __devinitdata = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; +#define LDC_PACKET_SIZE 64 + +/* Packet header layout for unreliable and reliable mode frames. + * When in RAW mode, packets are simply straight 64-byte payloads + * with no headers. + */ +struct ldc_packet { + u8 type; +#define LDC_CTRL 0x01 +#define LDC_DATA 0x02 +#define LDC_ERR 0x10 + + u8 stype; +#define LDC_INFO 0x01 +#define LDC_ACK 0x02 +#define LDC_NACK 0x04 + + u8 ctrl; +#define LDC_VERS 0x01 /* Link Version */ +#define LDC_RTS 0x02 /* Request To Send */ +#define LDC_RTR 0x03 /* Ready To Receive */ +#define LDC_RDX 0x04 /* Ready for Data eXchange */ +#define LDC_CTRL_MSK 0x0f + + u8 env; +#define LDC_LEN 0x3f +#define LDC_FRAG_MASK 0xc0 +#define LDC_START 0x40 +#define LDC_STOP 0x80 + + u32 seqid; + + union { + u8 u_data[LDC_PACKET_SIZE - 8]; + struct { + u32 pad; + u32 ackid; + u8 r_data[LDC_PACKET_SIZE - 8 - 8]; + } r; + } u; +}; + +struct ldc_version { + u16 major; + u16 minor; +}; + +/* Ordered from largest major to lowest. */ +static struct ldc_version ver_arr[] = { + { .major = 1, .minor = 0 }, +}; + +#define LDC_DEFAULT_MTU (4 * LDC_PACKET_SIZE) +#define LDC_DEFAULT_NUM_ENTRIES (PAGE_SIZE / LDC_PACKET_SIZE) + +struct ldc_channel; + +struct ldc_mode_ops { + int (*write)(struct ldc_channel *, const void *, unsigned int); + int (*read)(struct ldc_channel *, void *, unsigned int); +}; + +static const struct ldc_mode_ops raw_ops; +static const struct ldc_mode_ops nonraw_ops; +static const struct ldc_mode_ops stream_ops; + +int ldom_domaining_enabled; + +struct ldc_iommu { + /* Protects arena alloc/free. */ + spinlock_t lock; + struct iommu_arena arena; + struct ldc_mtable_entry *page_table; +}; + +struct ldc_channel { + /* Protects all operations that depend upon channel state. */ + spinlock_t lock; + + unsigned long id; + + u8 *mssbuf; + u32 mssbuf_len; + u32 mssbuf_off; + + struct ldc_packet *tx_base; + unsigned long tx_head; + unsigned long tx_tail; + unsigned long tx_num_entries; + unsigned long tx_ra; + + unsigned long tx_acked; + + struct ldc_packet *rx_base; + unsigned long rx_head; + unsigned long rx_tail; + unsigned long rx_num_entries; + unsigned long rx_ra; + + u32 rcv_nxt; + u32 snd_nxt; + + unsigned long chan_state; + + struct ldc_channel_config cfg; + void *event_arg; + + const struct ldc_mode_ops *mops; + + struct ldc_iommu iommu; + + struct ldc_version ver; + + u8 hs_state; +#define LDC_HS_CLOSED 0x00 +#define LDC_HS_OPEN 0x01 +#define LDC_HS_GOTVERS 0x02 +#define LDC_HS_SENTRTR 0x03 +#define LDC_HS_GOTRTR 0x04 +#define LDC_HS_COMPLETE 0x10 + + u8 flags; +#define LDC_FLAG_ALLOCED_QUEUES 0x01 +#define LDC_FLAG_REGISTERED_QUEUES 0x02 +#define LDC_FLAG_REGISTERED_IRQS 0x04 +#define LDC_FLAG_RESET 0x10 + + u8 mss; + u8 state; + +#define LDC_IRQ_NAME_MAX 32 + char rx_irq_name[LDC_IRQ_NAME_MAX]; + char tx_irq_name[LDC_IRQ_NAME_MAX]; + + struct hlist_head mh_list; + + struct hlist_node list; +}; + +#define ldcdbg(TYPE, f, a...) \ +do { if (lp->cfg.debug & LDC_DEBUG_##TYPE) \ + printk(KERN_INFO PFX "ID[%lu] " f, lp->id, ## a); \ +} while (0) + +static const char *state_to_str(u8 state) +{ + switch (state) { + case LDC_STATE_INVALID: + return "INVALID"; + case LDC_STATE_INIT: + return "INIT"; + case LDC_STATE_BOUND: + return "BOUND"; + case LDC_STATE_READY: + return "READY"; + case LDC_STATE_CONNECTED: + return "CONNECTED"; + default: + return "<UNKNOWN>"; + } +} + +static void ldc_set_state(struct ldc_channel *lp, u8 state) +{ + ldcdbg(STATE, "STATE (%s) --> (%s)\n", + state_to_str(lp->state), + state_to_str(state)); + + lp->state = state; +} + +static unsigned long __advance(unsigned long off, unsigned long num_entries) +{ + off += LDC_PACKET_SIZE; + if (off == (num_entries * LDC_PACKET_SIZE)) + off = 0; + + return off; +} + +static unsigned long rx_advance(struct ldc_channel *lp, unsigned long off) +{ + return __advance(off, lp->rx_num_entries); +} + +static unsigned long tx_advance(struct ldc_channel *lp, unsigned long off) +{ + return __advance(off, lp->tx_num_entries); +} + +static struct ldc_packet *handshake_get_tx_packet(struct ldc_channel *lp, + unsigned long *new_tail) +{ + struct ldc_packet *p; + unsigned long t; + + t = tx_advance(lp, lp->tx_tail); + if (t == lp->tx_head) + return NULL; + + *new_tail = t; + + p = lp->tx_base; + return p + (lp->tx_tail / LDC_PACKET_SIZE); +} + +/* When we are in reliable or stream mode, have to track the next packet + * we haven't gotten an ACK for in the TX queue using tx_acked. We have + * to be careful not to stomp over the queue past that point. During + * the handshake, we don't have TX data packets pending in the queue + * and that's why handshake_get_tx_packet() need not be mindful of + * lp->tx_acked. + */ +static unsigned long head_for_data(struct ldc_channel *lp) +{ + if (lp->cfg.mode == LDC_MODE_STREAM) + return lp->tx_acked; + return lp->tx_head; +} + +static int tx_has_space_for(struct ldc_channel *lp, unsigned int size) +{ + unsigned long limit, tail, new_tail, diff; + unsigned int mss; + + limit = head_for_data(lp); + tail = lp->tx_tail; + new_tail = tx_advance(lp, tail); + if (new_tail == limit) + return 0; + + if (limit > new_tail) + diff = limit - new_tail; + else + diff = (limit + + ((lp->tx_num_entries * LDC_PACKET_SIZE) - new_tail)); + diff /= LDC_PACKET_SIZE; + mss = lp->mss; + + if (diff * mss < size) + return 0; + + return 1; +} + +static struct ldc_packet *data_get_tx_packet(struct ldc_channel *lp, + unsigned long *new_tail) +{ + struct ldc_packet *p; + unsigned long h, t; + + h = head_for_data(lp); + t = tx_advance(lp, lp->tx_tail); + if (t == h) + return NULL; + + *new_tail = t; + + p = lp->tx_base; + return p + (lp->tx_tail / LDC_PACKET_SIZE); +} + +static int set_tx_tail(struct ldc_channel *lp, unsigned long tail) +{ + unsigned long orig_tail = lp->tx_tail; + int limit = 1000; + + lp->tx_tail = tail; + while (limit-- > 0) { + unsigned long err; + + err = sun4v_ldc_tx_set_qtail(lp->id, tail); + if (!err) + return 0; + + if (err != HV_EWOULDBLOCK) { + lp->tx_tail = orig_tail; + return -EINVAL; + } + udelay(1); + } + + lp->tx_tail = orig_tail; + return -EBUSY; +} + +/* This just updates the head value in the hypervisor using + * a polling loop with a timeout. The caller takes care of + * upating software state representing the head change, if any. + */ +static int __set_rx_head(struct ldc_channel *lp, unsigned long head) +{ + int limit = 1000; + + while (limit-- > 0) { + unsigned long err; + + err = sun4v_ldc_rx_set_qhead(lp->id, head); + if (!err) + return 0; + + if (err != HV_EWOULDBLOCK) + return -EINVAL; + + udelay(1); + } + + return -EBUSY; +} + +static int send_tx_packet(struct ldc_channel *lp, + struct ldc_packet *p, + unsigned long new_tail) +{ + BUG_ON(p != (lp->tx_base + (lp->tx_tail / LDC_PACKET_SIZE))); + + return set_tx_tail(lp, new_tail); +} + +static struct ldc_packet *handshake_compose_ctrl(struct ldc_channel *lp, + u8 stype, u8 ctrl, + void *data, int dlen, + unsigned long *new_tail) +{ + struct ldc_packet *p = handshake_get_tx_packet(lp, new_tail); + + if (p) { + memset(p, 0, sizeof(*p)); + p->type = LDC_CTRL; + p->stype = stype; + p->ctrl = ctrl; + if (data) + memcpy(p->u.u_data, data, dlen); + } + return p; +} + +static int start_handshake(struct ldc_channel *lp) +{ + struct ldc_packet *p; + struct ldc_version *ver; + unsigned long new_tail; + + ver = &ver_arr[0]; + + ldcdbg(HS, "SEND VER INFO maj[%u] min[%u]\n", + ver->major, ver->minor); + + p = handshake_compose_ctrl(lp, LDC_INFO, LDC_VERS, + ver, sizeof(*ver), &new_tail); + if (p) { + int err = send_tx_packet(lp, p, new_tail); + if (!err) + lp->flags &= ~LDC_FLAG_RESET; + return err; + } + return -EBUSY; +} + +static int send_version_nack(struct ldc_channel *lp, + u16 major, u16 minor) +{ + struct ldc_packet *p; + struct ldc_version ver; + unsigned long new_tail; + + ver.major = major; + ver.minor = minor; + + p = handshake_compose_ctrl(lp, LDC_NACK, LDC_VERS, + &ver, sizeof(ver), &new_tail); + if (p) { + ldcdbg(HS, "SEND VER NACK maj[%u] min[%u]\n", + ver.major, ver.minor); + + return send_tx_packet(lp, p, new_tail); + } + return -EBUSY; +} + +static int send_version_ack(struct ldc_channel *lp, + struct ldc_version *vp) +{ + struct ldc_packet *p; + unsigned long new_tail; + + p = handshake_compose_ctrl(lp, LDC_ACK, LDC_VERS, + vp, sizeof(*vp), &new_tail); + if (p) { + ldcdbg(HS, "SEND VER ACK maj[%u] min[%u]\n", + vp->major, vp->minor); + + return send_tx_packet(lp, p, new_tail); + } + return -EBUSY; +} + +static int send_rts(struct ldc_channel *lp) +{ + struct ldc_packet *p; + unsigned long new_tail; + + p = handshake_compose_ctrl(lp, LDC_INFO, LDC_RTS, NULL, 0, + &new_tail); + if (p) { + p->env = lp->cfg.mode; + p->seqid = 0; + lp->rcv_nxt = 0; + + ldcdbg(HS, "SEND RTS env[0x%x] seqid[0x%x]\n", + p->env, p->seqid); + + return send_tx_packet(lp, p, new_tail); + } + return -EBUSY; +} + +static int send_rtr(struct ldc_channel *lp) +{ + struct ldc_packet *p; + unsigned long new_tail; + + p = handshake_compose_ctrl(lp, LDC_INFO, LDC_RTR, NULL, 0, + &new_tail); + if (p) { + p->env = lp->cfg.mode; + p->seqid = 0; + + ldcdbg(HS, "SEND RTR env[0x%x] seqid[0x%x]\n", + p->env, p->seqid); + + return send_tx_packet(lp, p, new_tail); + } + return -EBUSY; +} + +static int send_rdx(struct ldc_channel *lp) +{ + struct ldc_packet *p; + unsigned long new_tail; + + p = handshake_compose_ctrl(lp, LDC_INFO, LDC_RDX, NULL, 0, + &new_tail); + if (p) { + p->env = 0; + p->seqid = ++lp->snd_nxt; + p->u.r.ackid = lp->rcv_nxt; + + ldcdbg(HS, "SEND RDX env[0x%x] seqid[0x%x] ackid[0x%x]\n", + p->env, p->seqid, p->u.r.ackid); + + return send_tx_packet(lp, p, new_tail); + } + return -EBUSY; +} + +static int send_data_nack(struct ldc_channel *lp, struct ldc_packet *data_pkt) +{ + struct ldc_packet *p; + unsigned long new_tail; + int err; + + p = data_get_tx_packet(lp, &new_tail); + if (!p) + return -EBUSY; + memset(p, 0, sizeof(*p)); + p->type = data_pkt->type; + p->stype = LDC_NACK; + p->ctrl = data_pkt->ctrl & LDC_CTRL_MSK; + p->seqid = lp->snd_nxt + 1; + p->u.r.ackid = lp->rcv_nxt; + + ldcdbg(HS, "SEND DATA NACK type[0x%x] ctl[0x%x] seq[0x%x] ack[0x%x]\n", + p->type, p->ctrl, p->seqid, p->u.r.ackid); + + err = send_tx_packet(lp, p, new_tail); + if (!err) + lp->snd_nxt++; + + return err; +} + +static int ldc_abort(struct ldc_channel *lp) +{ + unsigned long hv_err; + + ldcdbg(STATE, "ABORT\n"); + + /* We report but do not act upon the hypervisor errors because + * there really isn't much we can do if they fail at this point. + */ + hv_err = sun4v_ldc_tx_qconf(lp->id, lp->tx_ra, lp->tx_num_entries); + if (hv_err) + printk(KERN_ERR PFX "ldc_abort: " + "sun4v_ldc_tx_qconf(%lx,%lx,%lx) failed, err=%lu\n", + lp->id, lp->tx_ra, lp->tx_num_entries, hv_err); + + hv_err = sun4v_ldc_tx_get_state(lp->id, + &lp->tx_head, + &lp->tx_tail, + &lp->chan_state); + if (hv_err) + printk(KERN_ERR PFX "ldc_abort: " + "sun4v_ldc_tx_get_state(%lx,...) failed, err=%lu\n", + lp->id, hv_err); + + hv_err = sun4v_ldc_rx_qconf(lp->id, lp->rx_ra, lp->rx_num_entries); + if (hv_err) + printk(KERN_ERR PFX "ldc_abort: " + "sun4v_ldc_rx_qconf(%lx,%lx,%lx) failed, err=%lu\n", + lp->id, lp->rx_ra, lp->rx_num_entries, hv_err); + + /* Refetch the RX queue state as well, because we could be invoked + * here in the queue processing context. + */ + hv_err = sun4v_ldc_rx_get_state(lp->id, + &lp->rx_head, + &lp->rx_tail, + &lp->chan_state); + if (hv_err) + printk(KERN_ERR PFX "ldc_abort: " + "sun4v_ldc_rx_get_state(%lx,...) failed, err=%lu\n", + lp->id, hv_err); + + return -ECONNRESET; +} + +static struct ldc_version *find_by_major(u16 major) +{ + struct ldc_version *ret = NULL; + int i; + + for (i = 0; i < ARRAY_SIZE(ver_arr); i++) { + struct ldc_version *v = &ver_arr[i]; + if (v->major <= major) { + ret = v; + break; + } + } + return ret; +} + +static int process_ver_info(struct ldc_channel *lp, struct ldc_version *vp) +{ + struct ldc_version *vap; + int err; + + ldcdbg(HS, "GOT VERSION INFO major[%x] minor[%x]\n", + vp->major, vp->minor); + + if (lp->hs_state == LDC_HS_GOTVERS) { + lp->hs_state = LDC_HS_OPEN; + memset(&lp->ver, 0, sizeof(lp->ver)); + } + + vap = find_by_major(vp->major); + if (!vap) { + err = send_version_nack(lp, 0, 0); + } else if (vap->major != vp->major) { + err = send_version_nack(lp, vap->major, vap->minor); + } else { + struct ldc_version ver = *vp; + if (ver.minor > vap->minor) + ver.minor = vap->minor; + err = send_version_ack(lp, &ver); + if (!err) { + lp->ver = ver; + lp->hs_state = LDC_HS_GOTVERS; + } + } + if (err) + return ldc_abort(lp); + + return 0; +} + +static int process_ver_ack(struct ldc_channel *lp, struct ldc_version *vp) +{ + ldcdbg(HS, "GOT VERSION ACK major[%x] minor[%x]\n", + vp->major, vp->minor); + + if (lp->hs_state == LDC_HS_GOTVERS) { + if (lp->ver.major != vp->major || + lp->ver.minor != vp->minor) + return ldc_abort(lp); + } else { + lp->ver = *vp; + lp->hs_state = LDC_HS_GOTVERS; + } + if (send_rts(lp)) + return ldc_abort(lp); + return 0; +} + +static int process_ver_nack(struct ldc_channel *lp, struct ldc_version *vp) +{ + struct ldc_version *vap; + + if ((vp->major == 0 && vp->minor == 0) || + !(vap = find_by_major(vp->major))) { + return ldc_abort(lp); + } else { + struct ldc_packet *p; + unsigned long new_tail; + + p = handshake_compose_ctrl(lp, LDC_INFO, LDC_VERS, + vap, sizeof(*vap), + &new_tail); + if (p) + return send_tx_packet(lp, p, new_tail); + else + return ldc_abort(lp); + } +} + +static int process_version(struct ldc_channel *lp, + struct ldc_packet *p) +{ + struct ldc_version *vp; + + vp = (struct ldc_version *) p->u.u_data; + + switch (p->stype) { + case LDC_INFO: + return process_ver_info(lp, vp); + + case LDC_ACK: + return process_ver_ack(lp, vp); + + case LDC_NACK: + return process_ver_nack(lp, vp); + + default: + return ldc_abort(lp); + } +} + +static int process_rts(struct ldc_channel *lp, + struct ldc_packet *p) +{ + ldcdbg(HS, "GOT RTS stype[%x] seqid[%x] env[%x]\n", + p->stype, p->seqid, p->env); + + if (p->stype != LDC_INFO || + lp->hs_state != LDC_HS_GOTVERS || + p->env != lp->cfg.mode) + return ldc_abort(lp); + + lp->snd_nxt = p->seqid; + lp->rcv_nxt = p->seqid; + lp->hs_state = LDC_HS_SENTRTR; + if (send_rtr(lp)) + return ldc_abort(lp); + + return 0; +} + +static int process_rtr(struct ldc_channel *lp, + struct ldc_packet *p) +{ + ldcdbg(HS, "GOT RTR stype[%x] seqid[%x] env[%x]\n", + p->stype, p->seqid, p->env); + + if (p->stype != LDC_INFO || + p->env != lp->cfg.mode) + return ldc_abort(lp); + + lp->snd_nxt = p->seqid; + lp->hs_state = LDC_HS_COMPLETE; + ldc_set_state(lp, LDC_STATE_CONNECTED); + send_rdx(lp); + + return LDC_EVENT_UP; +} + +static int rx_seq_ok(struct ldc_channel *lp, u32 seqid) +{ + return lp->rcv_nxt + 1 == seqid; +} + +static int process_rdx(struct ldc_channel *lp, + struct ldc_packet *p) +{ + ldcdbg(HS, "GOT RDX stype[%x] seqid[%x] env[%x] ackid[%x]\n", + p->stype, p->seqid, p->env, p->u.r.ackid); + + if (p->stype != LDC_INFO || + !(rx_seq_ok(lp, p->seqid))) + return ldc_abort(lp); + + lp->rcv_nxt = p->seqid; + + lp->hs_state = LDC_HS_COMPLETE; + ldc_set_state(lp, LDC_STATE_CONNECTED); + + return LDC_EVENT_UP; +} + +static int process_control_frame(struct ldc_channel *lp, + struct ldc_packet *p) +{ + switch (p->ctrl) { + case LDC_VERS: + return process_version(lp, p); + + case LDC_RTS: + return process_rts(lp, p); + + case LDC_RTR: + return process_rtr(lp, p); + + case LDC_RDX: + return process_rdx(lp, p); + + default: + return ldc_abort(lp); + } +} + +static int process_error_frame(struct ldc_channel *lp, + struct ldc_packet *p) +{ + return ldc_abort(lp); +} + +static int process_data_ack(struct ldc_channel *lp, + struct ldc_packet *ack) +{ + unsigned long head = lp->tx_acked; + u32 ackid = ack->u.r.ackid; + + while (1) { + struct ldc_packet *p = lp->tx_base + (head / LDC_PACKET_SIZE); + + head = tx_advance(lp, head); + + if (p->seqid == ackid) { + lp->tx_acked = head; + return 0; + } + if (head == lp->tx_tail) + return ldc_abort(lp); + } + + return 0; +} + +static void send_events(struct ldc_channel *lp, unsigned int event_mask) +{ + if (event_mask & LDC_EVENT_RESET) + lp->cfg.event(lp->event_arg, LDC_EVENT_RESET); + if (event_mask & LDC_EVENT_UP) + lp->cfg.event(lp->event_arg, LDC_EVENT_UP); + if (event_mask & LDC_EVENT_DATA_READY) + lp->cfg.event(lp->event_arg, LDC_EVENT_DATA_READY); +} + +static irqreturn_t ldc_rx(int irq, void *dev_id) +{ + struct ldc_channel *lp = dev_id; + unsigned long orig_state, hv_err, flags; + unsigned int event_mask; + + spin_lock_irqsave(&lp->lock, flags); + + orig_state = lp->chan_state; + hv_err = sun4v_ldc_rx_get_state(lp->id, + &lp->rx_head, + &lp->rx_tail, + &lp->chan_state); + + ldcdbg(RX, "RX state[0x%02lx:0x%02lx] head[0x%04lx] tail[0x%04lx]\n", + orig_state, lp->chan_state, lp->rx_head, lp->rx_tail); + + event_mask = 0; + + if (lp->cfg.mode == LDC_MODE_RAW && + lp->chan_state == LDC_CHANNEL_UP) { + lp->hs_state = LDC_HS_COMPLETE; + ldc_set_state(lp, LDC_STATE_CONNECTED); + + event_mask |= LDC_EVENT_UP; + + orig_state = lp->chan_state; + } + + /* If we are in reset state, flush the RX queue and ignore + * everything. + */ + if (lp->flags & LDC_FLAG_RESET) { + (void) __set_rx_head(lp, lp->rx_tail); + goto out; + } + + /* Once we finish the handshake, we let the ldc_read() + * paths do all of the control frame and state management. + * Just trigger the callback. + */ + if (lp->hs_state == LDC_HS_COMPLETE) { +handshake_complete: + if (lp->chan_state != orig_state) { + unsigned int event = LDC_EVENT_RESET; + + if (lp->chan_state == LDC_CHANNEL_UP) + event = LDC_EVENT_UP; + + event_mask |= event; + } + if (lp->rx_head != lp->rx_tail) + event_mask |= LDC_EVENT_DATA_READY; + + goto out; + } + + if (lp->chan_state != orig_state) + goto out; + + while (lp->rx_head != lp->rx_tail) { + struct ldc_packet *p; + unsigned long new; + int err; + + p = lp->rx_base + (lp->rx_head / LDC_PACKET_SIZE); + + switch (p->type) { + case LDC_CTRL: + err = process_control_frame(lp, p); + if (err > 0) + event_mask |= err; + break; + + case LDC_DATA: + event_mask |= LDC_EVENT_DATA_READY; + err = 0; + break; + + case LDC_ERR: + err = process_error_frame(lp, p); + break; + + default: + err = ldc_abort(lp); + break; + } + + if (err < 0) + break; + + new = lp->rx_head; + new += LDC_PACKET_SIZE; + if (new == (lp->rx_num_entries * LDC_PACKET_SIZE)) + new = 0; + lp->rx_head = new; + + err = __set_rx_head(lp, new); + if (err < 0) { + (void) ldc_abort(lp); + break; + } + if (lp->hs_state == LDC_HS_COMPLETE) + goto handshake_complete; + } + +out: + spin_unlock_irqrestore(&lp->lock, flags); + + send_events(lp, event_mask); + + return IRQ_HANDLED; +} + +static irqreturn_t ldc_tx(int irq, void *dev_id) +{ + struct ldc_channel *lp = dev_id; + unsigned long flags, hv_err, orig_state; + unsigned int event_mask = 0; + + spin_lock_irqsave(&lp->lock, flags); + + orig_state = lp->chan_state; + hv_err = sun4v_ldc_tx_get_state(lp->id, + &lp->tx_head, + &lp->tx_tail, + &lp->chan_state); + + ldcdbg(TX, " TX state[0x%02lx:0x%02lx] head[0x%04lx] tail[0x%04lx]\n", + orig_state, lp->chan_state, lp->tx_head, lp->tx_tail); + + if (lp->cfg.mode == LDC_MODE_RAW && + lp->chan_state == LDC_CHANNEL_UP) { + lp->hs_state = LDC_HS_COMPLETE; + ldc_set_state(lp, LDC_STATE_CONNECTED); + + event_mask |= LDC_EVENT_UP; + } + + spin_unlock_irqrestore(&lp->lock, flags); + + send_events(lp, event_mask); + + return IRQ_HANDLED; +} + +/* XXX ldc_alloc() and ldc_free() needs to run under a mutex so + * XXX that addition and removal from the ldc_channel_list has + * XXX atomicity, otherwise the __ldc_channel_exists() check is + * XXX totally pointless as another thread can slip into ldc_alloc() + * XXX and add a channel with the same ID. There also needs to be + * XXX a spinlock for ldc_channel_list. + */ +static HLIST_HEAD(ldc_channel_list); + +static int __ldc_channel_exists(unsigned long id) +{ + struct ldc_channel *lp; + struct hlist_node *n; + + hlist_for_each_entry(lp, n, &ldc_channel_list, list) { + if (lp->id == id) + return 1; + } + return 0; +} + +static int alloc_queue(const char *name, unsigned long num_entries, + struct ldc_packet **base, unsigned long *ra) +{ + unsigned long size, order; + void *q; + + size = num_entries * LDC_PACKET_SIZE; + order = get_order(size); + + q = (void *) __get_free_pages(GFP_KERNEL, order); + if (!q) { + printk(KERN_ERR PFX "Alloc of %s queue failed with " + "size=%lu order=%lu\n", name, size, order); + return -ENOMEM; + } + + memset(q, 0, PAGE_SIZE << order); + + *base = q; + *ra = __pa(q); + + return 0; +} + +static void free_queue(unsigned long num_entries, struct ldc_packet *q) +{ + unsigned long size, order; + + if (!q) + return; + + size = num_entries * LDC_PACKET_SIZE; + order = get_order(size); + + free_pages((unsigned long)q, order); +} + +/* XXX Make this configurable... XXX */ +#define LDC_IOTABLE_SIZE (8 * 1024) + +static int ldc_iommu_init(struct ldc_channel *lp) +{ + unsigned long sz, num_tsb_entries, tsbsize, order; + struct ldc_iommu *iommu = &lp->iommu; + struct ldc_mtable_entry *table; + unsigned long hv_err; + int err; + + num_tsb_entries = LDC_IOTABLE_SIZE; + tsbsize = num_tsb_entries * sizeof(struct ldc_mtable_entry); + + spin_lock_init(&iommu->lock); + + sz = num_tsb_entries / 8; + sz = (sz + 7UL) & ~7UL; + iommu->arena.map = kzalloc(sz, GFP_KERNEL); + if (!iommu->arena.map) { + printk(KERN_ERR PFX "Alloc of arena map failed, sz=%lu\n", sz); + return -ENOMEM; + } + + iommu->arena.limit = num_tsb_entries; + + order = get_order(tsbsize); + + table = (struct ldc_mtable_entry *) + __get_free_pages(GFP_KERNEL, order); + err = -ENOMEM; + if (!table) { + printk(KERN_ERR PFX "Alloc of MTE table failed, " + "size=%lu order=%lu\n", tsbsize, order); + goto out_free_map; + } + + memset(table, 0, PAGE_SIZE << order); + + iommu->page_table = table; + + hv_err = sun4v_ldc_set_map_table(lp->id, __pa(table), + num_tsb_entries); + err = -EINVAL; + if (hv_err) + goto out_free_table; + + return 0; + +out_free_table: + free_pages((unsigned long) table, order); + iommu->page_table = NULL; + +out_free_map: + kfree(iommu->arena.map); + iommu->arena.map = NULL; + + return err; +} + +static void ldc_iommu_release(struct ldc_channel *lp) +{ + struct ldc_iommu *iommu = &lp->iommu; + unsigned long num_tsb_entries, tsbsize, order; + + (void) sun4v_ldc_set_map_table(lp->id, 0, 0); + + num_tsb_entries = iommu->arena.limit; + tsbsize = num_tsb_entries * sizeof(struct ldc_mtable_entry); + order = get_order(tsbsize); + + free_pages((unsigned long) iommu->page_table, order); + iommu->page_table = NULL; + + kfree(iommu->arena.map); + iommu->arena.map = NULL; +} + +struct ldc_channel *ldc_alloc(unsigned long id, + const struct ldc_channel_config *cfgp, + void *event_arg) +{ + struct ldc_channel *lp; + const struct ldc_mode_ops *mops; + unsigned long dummy1, dummy2, hv_err; + u8 mss, *mssbuf; + int err; + + err = -ENODEV; + if (!ldom_domaining_enabled) + goto out_err; + + err = -EINVAL; + if (!cfgp) + goto out_err; + + switch (cfgp->mode) { + case LDC_MODE_RAW: + mops = &raw_ops; + mss = LDC_PACKET_SIZE; + break; + + case LDC_MODE_UNRELIABLE: + mops = &nonraw_ops; + mss = LDC_PACKET_SIZE - 8; + break; + + case LDC_MODE_STREAM: + mops = &stream_ops; + mss = LDC_PACKET_SIZE - 8 - 8; + break; + + default: + goto out_err; + } + + if (!cfgp->event || !event_arg || !cfgp->rx_irq || !cfgp->tx_irq) + goto out_err; + + hv_err = sun4v_ldc_tx_qinfo(id, &dummy1, &dummy2); + err = -ENODEV; + if (hv_err == HV_ECHANNEL) + goto out_err; + + err = -EEXIST; + if (__ldc_channel_exists(id)) + goto out_err; + + mssbuf = NULL; + + lp = kzalloc(sizeof(*lp), GFP_KERNEL); + err = -ENOMEM; + if (!lp) + goto out_err; + + spin_lock_init(&lp->lock); + + lp->id = id; + + err = ldc_iommu_init(lp); + if (err) + goto out_free_ldc; + + lp->mops = mops; + lp->mss = mss; + + lp->cfg = *cfgp; + if (!lp->cfg.mtu) + lp->cfg.mtu = LDC_DEFAULT_MTU; + + if (lp->cfg.mode == LDC_MODE_STREAM) { + mssbuf = kzalloc(lp->cfg.mtu, GFP_KERNEL); + if (!mssbuf) { + err = -ENOMEM; + goto out_free_iommu; + } + lp->mssbuf = mssbuf; + } + + lp->event_arg = event_arg; + + /* XXX allow setting via ldc_channel_config to override defaults + * XXX or use some formula based upon mtu + */ + lp->tx_num_entries = LDC_DEFAULT_NUM_ENTRIES; + lp->rx_num_entries = LDC_DEFAULT_NUM_ENTRIES; + + err = alloc_queue("TX", lp->tx_num_entries, + &lp->tx_base, &lp->tx_ra); + if (err) + goto out_free_mssbuf; + + err = alloc_queue("RX", lp->rx_num_entries, + &lp->rx_base, &lp->rx_ra); + if (err) + goto out_free_txq; + + lp->flags |= LDC_FLAG_ALLOCED_QUEUES; + + lp->hs_state = LDC_HS_CLOSED; + ldc_set_state(lp, LDC_STATE_INIT); + + INIT_HLIST_NODE(&lp->list); + hlist_add_head(&lp->list, &ldc_channel_list); + + INIT_HLIST_HEAD(&lp->mh_list); + + return lp; + +out_free_txq: + free_queue(lp->tx_num_entries, lp->tx_base); + +out_free_mssbuf: + if (mssbuf) + kfree(mssbuf); + +out_free_iommu: + ldc_iommu_release(lp); + +out_free_ldc: + kfree(lp); + +out_err: + return ERR_PTR(err); +} +EXPORT_SYMBOL(ldc_alloc); + +void ldc_free(struct ldc_channel *lp) +{ + if (lp->flags & LDC_FLAG_REGISTERED_IRQS) { + free_irq(lp->cfg.rx_irq, lp); + free_irq(lp->cfg.tx_irq, lp); + } + + if (lp->flags & LDC_FLAG_REGISTERED_QUEUES) { + sun4v_ldc_tx_qconf(lp->id, 0, 0); + sun4v_ldc_rx_qconf(lp->id, 0, 0); + lp->flags &= ~LDC_FLAG_REGISTERED_QUEUES; + } + if (lp->flags & LDC_FLAG_ALLOCED_QUEUES) { + free_queue(lp->tx_num_entries, lp->tx_base); + free_queue(lp->rx_num_entries, lp->rx_base); + lp->flags &= ~LDC_FLAG_ALLOCED_QUEUES; + } + + hlist_del(&lp->list); + + if (lp->mssbuf) + kfree(lp->mssbuf); + + ldc_iommu_release(lp); + + kfree(lp); +} +EXPORT_SYMBOL(ldc_free); + +/* Bind the channel. This registers the LDC queues with + * the hypervisor and puts the channel into a pseudo-listening + * state. This does not initiate a handshake, ldc_connect() does + * that. + */ +int ldc_bind(struct ldc_channel *lp, const char *name) +{ + unsigned long hv_err, flags; + int err = -EINVAL; + + spin_lock_irqsave(&lp->lock, flags); + + if (!name) + goto out_err; + + if (lp->state != LDC_STATE_INIT) + goto out_err; + + snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); + snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); + + err = request_irq(lp->cfg.rx_irq, ldc_rx, + IRQF_SAMPLE_RANDOM | IRQF_SHARED, + lp->rx_irq_name, lp); + if (err) + goto out_err; + + err = request_irq(lp->cfg.tx_irq, ldc_tx, + IRQF_SAMPLE_RANDOM | IRQF_SHARED, + lp->tx_irq_name, lp); + if (err) + goto out_free_rx_irq; + + + lp->flags |= LDC_FLAG_REGISTERED_IRQS; + + err = -ENODEV; + hv_err = sun4v_ldc_tx_qconf(lp->id, 0, 0); + if (hv_err) + goto out_free_tx_irq; + + hv_err = sun4v_ldc_tx_qconf(lp->id, lp->tx_ra, lp->tx_num_entries); + if (hv_err) + goto out_free_tx_irq; + + hv_err = sun4v_ldc_rx_qconf(lp->id, 0, 0); + if (hv_err) + goto out_unmap_tx; + + hv_err = sun4v_ldc_rx_qconf(lp->id, lp->rx_ra, lp->rx_num_entries); + if (hv_err) + goto out_unmap_tx; + + lp->flags |= LDC_FLAG_REGISTERED_QUEUES; + + hv_err = sun4v_ldc_tx_get_state(lp->id, + &lp->tx_head, + &lp->tx_tail, + &lp->chan_state); + err = -EBUSY; + if (hv_err) + goto out_unmap_rx; + + lp->tx_acked = lp->tx_head; + + lp->hs_state = LDC_HS_OPEN; + ldc_set_state(lp, LDC_STATE_BOUND); + + spin_unlock_irqrestore(&lp->lock, flags); + + return 0; + +out_unmap_rx: + lp->flags &= ~LDC_FLAG_REGISTERED_QUEUES; + sun4v_ldc_rx_qconf(lp->id, 0, 0); + +out_unmap_tx: + sun4v_ldc_tx_qconf(lp->id, 0, 0); + +out_free_tx_irq: + lp->flags &= ~LDC_FLAG_REGISTERED_IRQS; + free_irq(lp->cfg.tx_irq, lp); + +out_free_rx_irq: + free_irq(lp->cfg.rx_irq, lp); + +out_err: + spin_unlock_irqrestore(&lp->lock, flags); + + return err; +} +EXPORT_SYMBOL(ldc_bind); + +int ldc_connect(struct ldc_channel *lp) +{ + unsigned long flags; + int err; + + if (lp->cfg.mode == LDC_MODE_RAW) + return -EINVAL; + + spin_lock_irqsave(&lp->lock, flags); + + if (!(lp->flags & LDC_FLAG_ALLOCED_QUEUES) || + !(lp->flags & LDC_FLAG_REGISTERED_QUEUES) || + lp->hs_state != LDC_HS_OPEN) + err = -EINVAL; + else + err = start_handshake(lp); + + spin_unlock_irqrestore(&lp->lock, flags); + + return err; +} +EXPORT_SYMBOL(ldc_connect); + +int ldc_disconnect(struct ldc_channel *lp) +{ + unsigned long hv_err, flags; + int err; + + if (lp->cfg.mode == LDC_MODE_RAW) + return -EINVAL; + + if (!(lp->flags & LDC_FLAG_ALLOCED_QUEUES) || + !(lp->flags & LDC_FLAG_REGISTERED_QUEUES)) + return -EINVAL; + + spin_lock_irqsave(&lp->lock, flags); + + err = -ENODEV; + hv_err = sun4v_ldc_tx_qconf(lp->id, 0, 0); + if (hv_err) + goto out_err; + + hv_err = sun4v_ldc_tx_qconf(lp->id, lp->tx_ra, lp->tx_num_entries); + if (hv_err) + goto out_err; + + hv_err = sun4v_ldc_rx_qconf(lp->id, 0, 0); + if (hv_err) + goto out_err; + + hv_err = sun4v_ldc_rx_qconf(lp->id, lp->rx_ra, lp->rx_num_entries); + if (hv_err) + goto out_err; + + ldc_set_state(lp, LDC_STATE_BOUND); + lp->hs_state = LDC_HS_OPEN; + lp->flags |= LDC_FLAG_RESET; + + spin_unlock_irqrestore(&lp->lock, flags); + + return 0; + +out_err: + sun4v_ldc_tx_qconf(lp->id, 0, 0); + sun4v_ldc_rx_qconf(lp->id, 0, 0); + free_irq(lp->cfg.tx_irq, lp); + free_irq(lp->cfg.rx_irq, lp); + lp->flags &= ~(LDC_FLAG_REGISTERED_IRQS | + LDC_FLAG_REGISTERED_QUEUES); + ldc_set_state(lp, LDC_STATE_INIT); + + spin_unlock_irqrestore(&lp->lock, flags); + + return err; +} +EXPORT_SYMBOL(ldc_disconnect); + +int ldc_state(struct ldc_channel *lp) +{ + return lp->state; +} +EXPORT_SYMBOL(ldc_state); + +static int write_raw(struct ldc_channel *lp, const void *buf, unsigned int size) +{ + struct ldc_packet *p; + unsigned long new_tail; + int err; + + if (size > LDC_PACKET_SIZE) + return -EMSGSIZE; + + p = data_get_tx_packet(lp, &new_tail); + if (!p) + return -EAGAIN; + + memcpy(p, buf, size); + + err = send_tx_packet(lp, p, new_tail); + if (!err) + err = size; + + return err; +} + +static int read_raw(struct ldc_channel *lp, void *buf, unsigned int size) +{ + struct ldc_packet *p; + unsigned long hv_err, new; + int err; + + if (size < LDC_PACKET_SIZE) + return -EINVAL; + + hv_err = sun4v_ldc_rx_get_state(lp->id, + &lp->rx_head, + &lp->rx_tail, + &lp->chan_state); + if (hv_err) + return ldc_abort(lp); + + if (lp->chan_state == LDC_CHANNEL_DOWN || + lp->chan_state == LDC_CHANNEL_RESETTING) + return -ECONNRESET; + + if (lp->rx_head == lp->rx_tail) + return 0; + + p = lp->rx_base + (lp->rx_head / LDC_PACKET_SIZE); + memcpy(buf, p, LDC_PACKET_SIZE); + + new = rx_advance(lp, lp->rx_head); + lp->rx_head = new; + + err = __set_rx_head(lp, new); + if (err < 0) + err = -ECONNRESET; + else + err = LDC_PACKET_SIZE; + + return err; +} + +static const struct ldc_mode_ops raw_ops = { + .write = write_raw, + .read = read_raw, +}; + +static int write_nonraw(struct ldc_channel *lp, const void *buf, + unsigned int size) +{ + unsigned long hv_err, tail; + unsigned int copied; + u32 seq; + int err; + + hv_err = sun4v_ldc_tx_get_state(lp->id, &lp->tx_head, &lp->tx_tail, + &lp->chan_state); + if (unlikely(hv_err)) + return -EBUSY; + + if (unlikely(lp->chan_state != LDC_CHANNEL_UP)) + return ldc_abort(lp); + + if (!tx_has_space_for(lp, size)) + return -EAGAIN; + + seq = lp->snd_nxt; + copied = 0; + tail = lp->tx_tail; + while (copied < size) { + struct ldc_packet *p = lp->tx_base + (tail / LDC_PACKET_SIZE); + u8 *data = ((lp->cfg.mode == LDC_MODE_UNRELIABLE) ? + p->u.u_data : + p->u.r.r_data); + int data_len; + + p->type = LDC_DATA; + p->stype = LDC_INFO; + p->ctrl = 0; + + data_len = size - copied; + if (data_len > lp->mss) + data_len = lp->mss; + + BUG_ON(data_len > LDC_LEN); + + p->env = (data_len | + (copied == 0 ? LDC_START : 0) | + (data_len == size - copied ? LDC_STOP : 0)); + + p->seqid = ++seq; + + ldcdbg(DATA, "SENT DATA [%02x:%02x:%02x:%02x:%08x]\n", + p->type, + p->stype, + p->ctrl, + p->env, + p->seqid); + + memcpy(data, buf, data_len); + buf += data_len; + copied += data_len; + + tail = tx_advance(lp, tail); + } + + err = set_tx_tail(lp, tail); + if (!err) { + lp->snd_nxt = seq; + err = size; + } + + return err; +} + +static int rx_bad_seq(struct ldc_channel *lp, struct ldc_packet *p, + struct ldc_packet *first_frag) +{ + int err; + + if (first_frag) + lp->rcv_nxt = first_frag->seqid - 1; + + err = send_data_nack(lp, p); + if (err) + return err; + + err = __set_rx_head(lp, lp->rx_tail); + if (err < 0) + return ldc_abort(lp); + + return 0; +} + +static int data_ack_nack(struct ldc_channel *lp, struct ldc_packet *p) +{ + if (p->stype & LDC_ACK) { + int err = process_data_ack(lp, p); + if (err) + return err; + } + if (p->stype & LDC_NACK) + return ldc_abort(lp); + + return 0; +} + +static int rx_data_wait(struct ldc_channel *lp, unsigned long cur_head) +{ + unsigned long dummy; + int limit = 1000; + + ldcdbg(DATA, "DATA WAIT cur_head[%lx] rx_head[%lx] rx_tail[%lx]\n", + cur_head, lp->rx_head, lp->rx_tail); + while (limit-- > 0) { + unsigned long hv_err; + + hv_err = sun4v_ldc_rx_get_state(lp->id, + &dummy, + &lp->rx_tail, + &lp->chan_state); + if (hv_err) + return ldc_abort(lp); + + if (lp->chan_state == LDC_CHANNEL_DOWN || + lp->chan_state == LDC_CHANNEL_RESETTING) + return -ECONNRESET; + + if (cur_head != lp->rx_tail) { + ldcdbg(DATA, "DATA WAIT DONE " + "head[%lx] tail[%lx] chan_state[%lx]\n", + dummy, lp->rx_tail, lp->chan_state); + return 0; + } + + udelay(1); + } + return -EAGAIN; +} + +static int rx_set_head(struct ldc_channel *lp, unsigned long head) +{ + int err = __set_rx_head(lp, head); + + if (err < 0) + return ldc_abort(lp); + + lp->rx_head = head; + return 0; +} + +static void send_data_ack(struct ldc_channel *lp) +{ + unsigned long new_tail; + struct ldc_packet *p; + + p = data_get_tx_packet(lp, &new_tail); + if (likely(p)) { + int err; + + memset(p, 0, sizeof(*p)); + p->type = LDC_DATA; + p->stype = LDC_ACK; + p->ctrl = 0; + p->seqid = lp->snd_nxt + 1; + p->u.r.ackid = lp->rcv_nxt; + + err = send_tx_packet(lp, p, new_tail); + if (!err) + lp->snd_nxt++; + } +} + +static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size) +{ + struct ldc_packet *first_frag; + unsigned long hv_err, new; + int err, copied; + + hv_err = sun4v_ldc_rx_get_state(lp->id, + &lp->rx_head, + &lp->rx_tail, + &lp->chan_state); + if (hv_err) + return ldc_abort(lp); + + if (lp->chan_state == LDC_CHANNEL_DOWN || + lp->chan_state == LDC_CHANNEL_RESETTING) + return -ECONNRESET; + + if (lp->rx_head == lp->rx_tail) + return 0; + + first_frag = NULL; + copied = err = 0; + new = lp->rx_head; + while (1) { + struct ldc_packet *p; + int pkt_len; + + BUG_ON(new == lp->rx_tail); + p = lp->rx_base + (new / LDC_PACKET_SIZE); + + ldcdbg(RX, "RX read pkt[%02x:%02x:%02x:%02x:%08x:%08x] " + "rcv_nxt[%08x]\n", + p->type, + p->stype, + p->ctrl, + p->env, + p->seqid, + p->u.r.ackid, + lp->rcv_nxt); + + if (unlikely(!rx_seq_ok(lp, p->seqid))) { + err = rx_bad_seq(lp, p, first_frag); + copied = 0; + break; + } + + if (p->type & LDC_CTRL) { + err = process_control_frame(lp, p); + if (err < 0) + break; + err = 0; + } + + lp->rcv_nxt = p->seqid; + + if (!(p->type & LDC_DATA)) { + new = rx_advance(lp, new); + goto no_data; + } + if (p->stype & (LDC_ACK | LDC_NACK)) { + err = data_ack_nack(lp, p); + if (err) + break; + } + if (!(p->stype & LDC_INFO)) { + new = rx_advance(lp, new); + err = rx_set_head(lp, new); + if (err) + break; + goto no_data; + } + + pkt_len = p->env & LDC_LEN; + + /* Every initial packet starts with the START bit set. + * + * Singleton packets will have both START+STOP set. + * + * Fragments will have START set in the first frame, STOP + * set in the last frame, and neither bit set in middle + * frames of the packet. + * + * Therefore if we are at the beginning of a packet and + * we don't see START, or we are in the middle of a fragmented + * packet and do see START, we are unsynchronized and should + * flush the RX queue. + */ + if ((first_frag == NULL && !(p->env & LDC_START)) || + (first_frag != NULL && (p->env & LDC_START))) { + if (!first_frag) + new = rx_advance(lp, new); + + err = rx_set_head(lp, new); + if (err) + break; + + if (!first_frag) + goto no_data; + } + if (!first_frag) + first_frag = p; + + if (pkt_len > size - copied) { + /* User didn't give us a big enough buffer, + * what to do? This is a pretty serious error. + * + * Since we haven't updated the RX ring head to + * consume any of the packets, signal the error + * to the user and just leave the RX ring alone. + * + * This seems the best behavior because this allows + * a user of the LDC layer to start with a small + * RX buffer for ldc_read() calls and use -EMSGSIZE + * as a cue to enlarge it's read buffer. + */ + err = -EMSGSIZE; + break; + } + + /* Ok, we are gonna eat this one. */ + new = rx_advance(lp, new); + + memcpy(buf, + (lp->cfg.mode == LDC_MODE_UNRELIABLE ? + p->u.u_data : p->u.r.r_data), pkt_len); + buf += pkt_len; + copied += pkt_len; + + if (p->env & LDC_STOP) + break; + +no_data: + if (new == lp->rx_tail) { + err = rx_data_wait(lp, new); + if (err) + break; + } + } + + if (!err) + err = rx_set_head(lp, new); + + if (err && first_frag) + lp->rcv_nxt = first_frag->seqid - 1; + + if (!err) { + err = copied; + if (err > 0 && lp->cfg.mode != LDC_MODE_UNRELIABLE) + send_data_ack(lp); + } + + return err; +} + +static const struct ldc_mode_ops nonraw_ops = { + .write = write_nonraw, + .read = read_nonraw, +}; + +static int write_stream(struct ldc_channel *lp, const void *buf, + unsigned int size) +{ + if (size > lp->cfg.mtu) + size = lp->cfg.mtu; + return write_nonraw(lp, buf, size); +} + +static int read_stream(struct ldc_channel *lp, void *buf, unsigned int size) +{ + if (!lp->mssbuf_len) { + int err = read_nonraw(lp, lp->mssbuf, lp->cfg.mtu); + if (err < 0) + return err; + + lp->mssbuf_len = err; + lp->mssbuf_off = 0; + } + + if (size > lp->mssbuf_len) + size = lp->mssbuf_len; + memcpy(buf, lp->mssbuf + lp->mssbuf_off, size); + + lp->mssbuf_off += size; + lp->mssbuf_len -= size; + + return size; +} + +static const struct ldc_mode_ops stream_ops = { + .write = write_stream, + .read = read_stream, +}; + +int ldc_write(struct ldc_channel *lp, const void *buf, unsigned int size) +{ + unsigned long flags; + int err; + + if (!buf) + return -EINVAL; + + if (!size) + return 0; + + spin_lock_irqsave(&lp->lock, flags); + + if (lp->hs_state != LDC_HS_COMPLETE) + err = -ENOTCONN; + else + err = lp->mops->write(lp, buf, size); + + spin_unlock_irqrestore(&lp->lock, flags); + + return err; +} +EXPORT_SYMBOL(ldc_write); + +int ldc_read(struct ldc_channel *lp, void *buf, unsigned int size) +{ + unsigned long flags; + int err; + + if (!buf) + return -EINVAL; + + if (!size) + return 0; + + spin_lock_irqsave(&lp->lock, flags); + + if (lp->hs_state != LDC_HS_COMPLETE) + err = -ENOTCONN; + else + err = lp->mops->read(lp, buf, size); + + spin_unlock_irqrestore(&lp->lock, flags); + + return err; +} +EXPORT_SYMBOL(ldc_read); + +static long arena_alloc(struct ldc_iommu *iommu, unsigned long npages) +{ + struct iommu_arena *arena = &iommu->arena; + unsigned long n, i, start, end, limit; + int pass; + + limit = arena->limit; + start = arena->hint; + pass = 0; + +again: + n = find_next_zero_bit(arena->map, limit, start); + end = n + npages; + if (unlikely(end >= limit)) { + if (likely(pass < 1)) { + limit = start; + start = 0; + pass++; + goto again; + } else { + /* Scanned the whole thing, give up. */ + return -1; + } + } + + for (i = n; i < end; i++) { + if (test_bit(i, arena->map)) { + start = i + 1; + goto again; + } + } + + for (i = n; i < end; i++) + __set_bit(i, arena->map); + + arena->hint = end; + + return n; +} + +#define COOKIE_PGSZ_CODE 0xf000000000000000ULL +#define COOKIE_PGSZ_CODE_SHIFT 60ULL + +static u64 pagesize_code(void) +{ + switch (PAGE_SIZE) { + default: + case (8ULL * 1024ULL): + return 0; + case (64ULL * 1024ULL): + return 1; + case (512ULL * 1024ULL): + return 2; + case (4ULL * 1024ULL * 1024ULL): + return 3; + case (32ULL * 1024ULL * 1024ULL): + return 4; + case (256ULL * 1024ULL * 1024ULL): + return 5; + } +} + +static u64 make_cookie(u64 index, u64 pgsz_code, u64 page_offset) +{ + return ((pgsz_code << COOKIE_PGSZ_CODE_SHIFT) | + (index << PAGE_SHIFT) | + page_offset); +} + +static u64 cookie_to_index(u64 cookie, unsigned long *shift) +{ + u64 szcode = cookie >> COOKIE_PGSZ_CODE_SHIFT; + + cookie &= ~COOKIE_PGSZ_CODE; + + *shift = szcode * 3; + + return (cookie >> (13ULL + (szcode * 3ULL))); +} + +static struct ldc_mtable_entry *alloc_npages(struct ldc_iommu *iommu, + unsigned long npages) +{ + long entry; + + entry = arena_alloc(iommu, npages); + if (unlikely(entry < 0)) + return NULL; + + return iommu->page_table + entry; +} + +static u64 perm_to_mte(unsigned int map_perm) +{ + u64 mte_base; + + mte_base = pagesize_code(); + + if (map_perm & LDC_MAP_SHADOW) { + if (map_perm & LDC_MAP_R) + mte_base |= LDC_MTE_COPY_R; + if (map_perm & LDC_MAP_W) + mte_base |= LDC_MTE_COPY_W; + } + if (map_perm & LDC_MAP_DIRECT) { + if (map_perm & LDC_MAP_R) + mte_base |= LDC_MTE_READ; + if (map_perm & LDC_MAP_W) + mte_base |= LDC_MTE_WRITE; + if (map_perm & LDC_MAP_X) + mte_base |= LDC_MTE_EXEC; + } + if (map_perm & LDC_MAP_IO) { + if (map_perm & LDC_MAP_R) + mte_base |= LDC_MTE_IOMMU_R; + if (map_perm & LDC_MAP_W) + mte_base |= LDC_MTE_IOMMU_W; + } + + return mte_base; +} + +static int pages_in_region(unsigned long base, long len) +{ + int count = 0; + + do { + unsigned long new = (base + PAGE_SIZE) & PAGE_MASK; + + len -= (new - base); + base = new; + count++; + } while (len > 0); + + return count; +} + +struct cookie_state { + struct ldc_mtable_entry *page_table; + struct ldc_trans_cookie *cookies; + u64 mte_base; + u64 prev_cookie; + u32 pte_idx; + u32 nc; +}; + +static void fill_cookies(struct cookie_state *sp, unsigned long pa, + unsigned long off, unsigned long len) +{ + do { + unsigned long tlen, new = pa + PAGE_SIZE; + u64 this_cookie; + + sp->page_table[sp->pte_idx].mte = sp->mte_base | pa; + + tlen = PAGE_SIZE; + if (off) + tlen = PAGE_SIZE - off; + if (tlen > len) + tlen = len; + + this_cookie = make_cookie(sp->pte_idx, + pagesize_code(), off); + + off = 0; + + if (this_cookie == sp->prev_cookie) { + sp->cookies[sp->nc - 1].cookie_size += tlen; + } else { + sp->cookies[sp->nc].cookie_addr = this_cookie; + sp->cookies[sp->nc].cookie_size = tlen; + sp->nc++; + } + sp->prev_cookie = this_cookie + tlen; + + sp->pte_idx++; + + len -= tlen; + pa = new; + } while (len > 0); +} + +static int sg_count_one(struct scatterlist *sg) +{ + unsigned long base = page_to_pfn(sg->page) << PAGE_SHIFT; + long len = sg->length; + + if ((sg->offset | len) & (8UL - 1)) + return -EFAULT; + + return pages_in_region(base + sg->offset, len); +} + +static int sg_count_pages(struct scatterlist *sg, int num_sg) +{ + int count; + int i; + + count = 0; + for (i = 0; i < num_sg; i++) { + int err = sg_count_one(sg + i); + if (err < 0) + return err; + count += err; + } + + return count; +} + +int ldc_map_sg(struct ldc_channel *lp, + struct scatterlist *sg, int num_sg, + struct ldc_trans_cookie *cookies, int ncookies, + unsigned int map_perm) +{ + unsigned long i, npages, flags; + struct ldc_mtable_entry *base; + struct cookie_state state; + struct ldc_iommu *iommu; + int err; + + if (map_perm & ~LDC_MAP_ALL) + return -EINVAL; + + err = sg_count_pages(sg, num_sg); + if (err < 0) + return err; + + npages = err; + if (err > ncookies) + return -EMSGSIZE; + + iommu = &lp->iommu; + + spin_lock_irqsave(&iommu->lock, flags); + base = alloc_npages(iommu, npages); + spin_unlock_irqrestore(&iommu->lock, flags); + + if (!base) + return -ENOMEM; + + state.page_table = iommu->page_table; + state.cookies = cookies; + state.mte_base = perm_to_mte(map_perm); + state.prev_cookie = ~(u64)0; + state.pte_idx = (base - iommu->page_table); + state.nc = 0; + + for (i = 0; i < num_sg; i++) + fill_cookies(&state, page_to_pfn(sg[i].page) << PAGE_SHIFT, + sg[i].offset, sg[i].length); + + return state.nc; +} +EXPORT_SYMBOL(ldc_map_sg); + +int ldc_map_single(struct ldc_channel *lp, + void *buf, unsigned int len, + struct ldc_trans_cookie *cookies, int ncookies, + unsigned int map_perm) +{ + unsigned long npages, pa, flags; + struct ldc_mtable_entry *base; + struct cookie_state state; + struct ldc_iommu *iommu; + + if ((map_perm & ~LDC_MAP_ALL) || (ncookies < 1)) + return -EINVAL; + + pa = __pa(buf); + if ((pa | len) & (8UL - 1)) + return -EFAULT; + + npages = pages_in_region(pa, len); + + iommu = &lp->iommu; + + spin_lock_irqsave(&iommu->lock, flags); + base = alloc_npages(iommu, npages); + spin_unlock_irqrestore(&iommu->lock, flags); + + if (!base) + return -ENOMEM; + + state.page_table = iommu->page_table; + state.cookies = cookies; + state.mte_base = perm_to_mte(map_perm); + state.prev_cookie = ~(u64)0; + state.pte_idx = (base - iommu->page_table); + state.nc = 0; + fill_cookies(&state, (pa & PAGE_MASK), (pa & ~PAGE_MASK), len); + BUG_ON(state.nc != 1); + + return state.nc; +} +EXPORT_SYMBOL(ldc_map_single); + +static void free_npages(unsigned long id, struct ldc_iommu *iommu, + u64 cookie, u64 size) +{ + struct iommu_arena *arena = &iommu->arena; + unsigned long i, shift, index, npages; + struct ldc_mtable_entry *base; + + npages = PAGE_ALIGN(((cookie & ~PAGE_MASK) + size)) >> PAGE_SHIFT; + index = cookie_to_index(cookie, &shift); + base = iommu->page_table + index; + + BUG_ON(index > arena->limit || + (index + npages) > arena->limit); + + for (i = 0; i < npages; i++) { + if (base->cookie) + sun4v_ldc_revoke(id, cookie + (i << shift), + base->cookie); + base->mte = 0; + __clear_bit(index + i, arena->map); + } +} + +void ldc_unmap(struct ldc_channel *lp, struct ldc_trans_cookie *cookies, + int ncookies) +{ + struct ldc_iommu *iommu = &lp->iommu; + unsigned long flags; + int i; + + spin_lock_irqsave(&iommu->lock, flags); + for (i = 0; i < ncookies; i++) { + u64 addr = cookies[i].cookie_addr; + u64 size = cookies[i].cookie_size; + + free_npages(lp->id, iommu, addr, size); + } + spin_unlock_irqrestore(&iommu->lock, flags); +} +EXPORT_SYMBOL(ldc_unmap); + +int ldc_copy(struct ldc_channel *lp, int copy_dir, + void *buf, unsigned int len, unsigned long offset, + struct ldc_trans_cookie *cookies, int ncookies) +{ + unsigned int orig_len; + unsigned long ra; + int i; + + if (copy_dir != LDC_COPY_IN && copy_dir != LDC_COPY_OUT) { + printk(KERN_ERR PFX "ldc_copy: ID[%lu] Bad copy_dir[%d]\n", + lp->id, copy_dir); + return -EINVAL; + } + + ra = __pa(buf); + if ((ra | len | offset) & (8UL - 1)) { + printk(KERN_ERR PFX "ldc_copy: ID[%lu] Unaligned buffer " + "ra[%lx] len[%x] offset[%lx]\n", + lp->id, ra, len, offset); + return -EFAULT; + } + + if (lp->hs_state != LDC_HS_COMPLETE || + (lp->flags & LDC_FLAG_RESET)) { + printk(KERN_ERR PFX "ldc_copy: ID[%lu] Link down hs_state[%x] " + "flags[%x]\n", lp->id, lp->hs_state, lp->flags); + return -ECONNRESET; + } + + orig_len = len; + for (i = 0; i < ncookies; i++) { + unsigned long cookie_raddr = cookies[i].cookie_addr; + unsigned long this_len = cookies[i].cookie_size; + unsigned long actual_len; + + if (unlikely(offset)) { + unsigned long this_off = offset; + + if (this_off > this_len) + this_off = this_len; + + offset -= this_off; + this_len -= this_off; + if (!this_len) + continue; + cookie_raddr += this_off; + } + + if (this_len > len) + this_len = len; + + while (1) { + unsigned long hv_err; + + hv_err = sun4v_ldc_copy(lp->id, copy_dir, + cookie_raddr, ra, + this_len, &actual_len); + if (unlikely(hv_err)) { + printk(KERN_ERR PFX "ldc_copy: ID[%lu] " + "HV error %lu\n", + lp->id, hv_err); + if (lp->hs_state != LDC_HS_COMPLETE || + (lp->flags & LDC_FLAG_RESET)) + return -ECONNRESET; + else + return -EFAULT; + } + + cookie_raddr += actual_len; + ra += actual_len; + len -= actual_len; + if (actual_len == this_len) + break; + + this_len -= actual_len; + } + + if (!len) + break; + } + + /* It is caller policy what to do about short copies. + * For example, a networking driver can declare the + * packet a runt and drop it. + */ + + return orig_len - len; +} +EXPORT_SYMBOL(ldc_copy); + +void *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len, + struct ldc_trans_cookie *cookies, int *ncookies, + unsigned int map_perm) +{ + void *buf; + int err; + + if (len & (8UL - 1)) + return ERR_PTR(-EINVAL); + + buf = kzalloc(len, GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + err = ldc_map_single(lp, buf, len, cookies, *ncookies, map_perm); + if (err < 0) { + kfree(buf); + return ERR_PTR(err); + } + *ncookies = err; + + return buf; +} +EXPORT_SYMBOL(ldc_alloc_exp_dring); + +void ldc_free_exp_dring(struct ldc_channel *lp, void *buf, unsigned int len, + struct ldc_trans_cookie *cookies, int ncookies) +{ + ldc_unmap(lp, cookies, ncookies); + kfree(buf); +} +EXPORT_SYMBOL(ldc_free_exp_dring); + +static int __init ldc_init(void) +{ + unsigned long major, minor; + struct mdesc_handle *hp; + const u64 *v; + u64 mp; + + hp = mdesc_grab(); + if (!hp) + return -ENODEV; + + mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "platform"); + if (mp == MDESC_NODE_NULL) + return -ENODEV; + + v = mdesc_get_property(hp, mp, "domaining-enabled", NULL); + if (!v) + return -ENODEV; + + major = 1; + minor = 0; + if (sun4v_hvapi_register(HV_GRP_LDOM, major, &minor)) { + printk(KERN_INFO PFX "Could not register LDOM hvapi.\n"); + return -ENODEV; + } + + printk(KERN_INFO "%s", version); + + if (!*v) { + printk(KERN_INFO PFX "Domaining disabled.\n"); + return -ENODEV; + } + ldom_domaining_enabled = 1; + + return 0; +} + +core_initcall(ldc_init); diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c index f0e16045fb1..62a38979394 100644 --- a/arch/sparc64/kernel/mdesc.c +++ b/arch/sparc64/kernel/mdesc.c @@ -6,6 +6,9 @@ #include <linux/types.h> #include <linux/bootmem.h> #include <linux/log2.h> +#include <linux/list.h> +#include <linux/slab.h> +#include <linux/mm.h> #include <asm/hypervisor.h> #include <asm/mdesc.h> @@ -29,7 +32,7 @@ struct mdesc_hdr { u32 node_sz; /* node block size */ u32 name_sz; /* name block size */ u32 data_sz; /* data block size */ -}; +} __attribute__((aligned(16))); struct mdesc_elem { u8 tag; @@ -53,306 +56,402 @@ struct mdesc_elem { } d; }; -static struct mdesc_hdr *main_mdesc; -static struct mdesc_node *allnodes; - -static struct mdesc_node *allnodes_tail; -static unsigned int unique_id; +struct mdesc_mem_ops { + struct mdesc_handle *(*alloc)(unsigned int mdesc_size); + void (*free)(struct mdesc_handle *handle); +}; -static struct mdesc_node **mdesc_hash; -static unsigned int mdesc_hash_size; +struct mdesc_handle { + struct list_head list; + struct mdesc_mem_ops *mops; + void *self_base; + atomic_t refcnt; + unsigned int handle_size; + struct mdesc_hdr mdesc; +}; -static inline unsigned int node_hashfn(u64 node) +static void mdesc_handle_init(struct mdesc_handle *hp, + unsigned int handle_size, + void *base) { - return ((unsigned int) (node ^ (node >> 8) ^ (node >> 16))) - & (mdesc_hash_size - 1); + BUG_ON(((unsigned long)&hp->mdesc) & (16UL - 1)); + + memset(hp, 0, handle_size); + INIT_LIST_HEAD(&hp->list); + hp->self_base = base; + atomic_set(&hp->refcnt, 1); + hp->handle_size = handle_size; } -static inline void hash_node(struct mdesc_node *mp) +static struct mdesc_handle *mdesc_bootmem_alloc(unsigned int mdesc_size) { - struct mdesc_node **head = &mdesc_hash[node_hashfn(mp->node)]; + struct mdesc_handle *hp; + unsigned int handle_size, alloc_size; - mp->hash_next = *head; - *head = mp; + handle_size = (sizeof(struct mdesc_handle) - + sizeof(struct mdesc_hdr) + + mdesc_size); + alloc_size = PAGE_ALIGN(handle_size); - if (allnodes_tail) { - allnodes_tail->allnodes_next = mp; - allnodes_tail = mp; - } else { - allnodes = allnodes_tail = mp; - } + hp = __alloc_bootmem(alloc_size, PAGE_SIZE, 0UL); + if (hp) + mdesc_handle_init(hp, handle_size, hp); + + return hp; } -static struct mdesc_node *find_node(u64 node) +static void mdesc_bootmem_free(struct mdesc_handle *hp) { - struct mdesc_node *mp = mdesc_hash[node_hashfn(node)]; + unsigned int alloc_size, handle_size = hp->handle_size; + unsigned long start, end; + + BUG_ON(atomic_read(&hp->refcnt) != 0); + BUG_ON(!list_empty(&hp->list)); - while (mp) { - if (mp->node == node) - return mp; + alloc_size = PAGE_ALIGN(handle_size); - mp = mp->hash_next; + start = (unsigned long) hp; + end = start + alloc_size; + + while (start < end) { + struct page *p; + + p = virt_to_page(start); + ClearPageReserved(p); + __free_page(p); + start += PAGE_SIZE; } - return NULL; } -struct property *md_find_property(const struct mdesc_node *mp, - const char *name, - int *lenp) +static struct mdesc_mem_ops bootmem_mdesc_memops = { + .alloc = mdesc_bootmem_alloc, + .free = mdesc_bootmem_free, +}; + +static struct mdesc_handle *mdesc_kmalloc(unsigned int mdesc_size) { - struct property *pp; + unsigned int handle_size; + void *base; - for (pp = mp->properties; pp != 0; pp = pp->next) { - if (strcasecmp(pp->name, name) == 0) { - if (lenp) - *lenp = pp->length; - break; - } + handle_size = (sizeof(struct mdesc_handle) - + sizeof(struct mdesc_hdr) + + mdesc_size); + + base = kmalloc(handle_size + 15, GFP_KERNEL); + if (base) { + struct mdesc_handle *hp; + unsigned long addr; + + addr = (unsigned long)base; + addr = (addr + 15UL) & ~15UL; + hp = (struct mdesc_handle *) addr; + + mdesc_handle_init(hp, handle_size, base); + return hp; } - return pp; + + return NULL; } -EXPORT_SYMBOL(md_find_property); -/* - * Find a property with a given name for a given node - * and return the value. - */ -const void *md_get_property(const struct mdesc_node *mp, const char *name, - int *lenp) +static void mdesc_kfree(struct mdesc_handle *hp) { - struct property *pp = md_find_property(mp, name, lenp); - return pp ? pp->value : NULL; + BUG_ON(atomic_read(&hp->refcnt) != 0); + BUG_ON(!list_empty(&hp->list)); + + kfree(hp->self_base); } -EXPORT_SYMBOL(md_get_property); -struct mdesc_node *md_find_node_by_name(struct mdesc_node *from, - const char *name) +static struct mdesc_mem_ops kmalloc_mdesc_memops = { + .alloc = mdesc_kmalloc, + .free = mdesc_kfree, +}; + +static struct mdesc_handle *mdesc_alloc(unsigned int mdesc_size, + struct mdesc_mem_ops *mops) { - struct mdesc_node *mp; + struct mdesc_handle *hp = mops->alloc(mdesc_size); - mp = from ? from->allnodes_next : allnodes; - for (; mp != NULL; mp = mp->allnodes_next) { - if (strcmp(mp->name, name) == 0) - break; - } - return mp; -} -EXPORT_SYMBOL(md_find_node_by_name); + if (hp) + hp->mops = mops; -static unsigned int mdesc_early_allocated; + return hp; +} -static void * __init mdesc_early_alloc(unsigned long size) +static void mdesc_free(struct mdesc_handle *hp) { - void *ret; + hp->mops->free(hp); +} - ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL); - if (ret == NULL) { - prom_printf("MDESC: alloc of %lu bytes failed.\n", size); - prom_halt(); - } +static struct mdesc_handle *cur_mdesc; +static LIST_HEAD(mdesc_zombie_list); +static DEFINE_SPINLOCK(mdesc_lock); - memset(ret, 0, size); +struct mdesc_handle *mdesc_grab(void) +{ + struct mdesc_handle *hp; + unsigned long flags; - mdesc_early_allocated += size; + spin_lock_irqsave(&mdesc_lock, flags); + hp = cur_mdesc; + if (hp) + atomic_inc(&hp->refcnt); + spin_unlock_irqrestore(&mdesc_lock, flags); - return ret; + return hp; } +EXPORT_SYMBOL(mdesc_grab); -static unsigned int __init count_arcs(struct mdesc_elem *ep) +void mdesc_release(struct mdesc_handle *hp) { - unsigned int ret = 0; + unsigned long flags; - ep++; - while (ep->tag != MD_NODE_END) { - if (ep->tag == MD_PROP_ARC) - ret++; - ep++; + spin_lock_irqsave(&mdesc_lock, flags); + if (atomic_dec_and_test(&hp->refcnt)) { + list_del_init(&hp->list); + hp->mops->free(hp); } - return ret; + spin_unlock_irqrestore(&mdesc_lock, flags); } +EXPORT_SYMBOL(mdesc_release); -static void __init mdesc_node_alloc(u64 node, struct mdesc_elem *ep, const char *names) +static void do_mdesc_update(struct work_struct *work) { - unsigned int num_arcs = count_arcs(ep); - struct mdesc_node *mp; + unsigned long len, real_len, status; + struct mdesc_handle *hp, *orig_hp; + unsigned long flags; + + (void) sun4v_mach_desc(0UL, 0UL, &len); + + hp = mdesc_alloc(len, &kmalloc_mdesc_memops); + if (!hp) { + printk(KERN_ERR "MD: mdesc alloc fails\n"); + return; + } + + status = sun4v_mach_desc(__pa(&hp->mdesc), len, &real_len); + if (status != HV_EOK || real_len > len) { + printk(KERN_ERR "MD: mdesc reread fails with %lu\n", + status); + atomic_dec(&hp->refcnt); + mdesc_free(hp); + return; + } - mp = mdesc_early_alloc(sizeof(*mp) + - (num_arcs * sizeof(struct mdesc_arc))); - mp->name = names + ep->name_offset; - mp->node = node; - mp->unique_id = unique_id++; - mp->num_arcs = num_arcs; + spin_lock_irqsave(&mdesc_lock, flags); + orig_hp = cur_mdesc; + cur_mdesc = hp; - hash_node(mp); + if (atomic_dec_and_test(&orig_hp->refcnt)) + mdesc_free(orig_hp); + else + list_add(&orig_hp->list, &mdesc_zombie_list); + spin_unlock_irqrestore(&mdesc_lock, flags); } -static inline struct mdesc_elem *node_block(struct mdesc_hdr *mdesc) +static DECLARE_WORK(mdesc_update_work, do_mdesc_update); + +void mdesc_update(void) +{ + schedule_work(&mdesc_update_work); +} + +static struct mdesc_elem *node_block(struct mdesc_hdr *mdesc) { return (struct mdesc_elem *) (mdesc + 1); } -static inline void *name_block(struct mdesc_hdr *mdesc) +static void *name_block(struct mdesc_hdr *mdesc) { return ((void *) node_block(mdesc)) + mdesc->node_sz; } -static inline void *data_block(struct mdesc_hdr *mdesc) +static void *data_block(struct mdesc_hdr *mdesc) { return ((void *) name_block(mdesc)) + mdesc->name_sz; } -/* In order to avoid recursion (the graph can be very deep) we use a - * two pass algorithm. First we allocate all the nodes and hash them. - * Then we iterate over each node, filling in the arcs and properties. - */ -static void __init build_all_nodes(struct mdesc_hdr *mdesc) +u64 mdesc_node_by_name(struct mdesc_handle *hp, + u64 from_node, const char *name) { - struct mdesc_elem *start, *ep; - struct mdesc_node *mp; - const char *names; - void *data; - u64 last_node; - - start = ep = node_block(mdesc); - last_node = mdesc->node_sz / 16; + struct mdesc_elem *ep = node_block(&hp->mdesc); + const char *names = name_block(&hp->mdesc); + u64 last_node = hp->mdesc.node_sz / 16; + u64 ret; + + if (from_node == MDESC_NODE_NULL) + from_node = 0; + + if (from_node >= last_node) + return MDESC_NODE_NULL; + + ret = ep[from_node].d.val; + while (ret < last_node) { + if (ep[ret].tag != MD_NODE) + return MDESC_NODE_NULL; + if (!strcmp(names + ep[ret].name_offset, name)) + break; + ret = ep[ret].d.val; + } + if (ret >= last_node) + ret = MDESC_NODE_NULL; + return ret; +} +EXPORT_SYMBOL(mdesc_node_by_name); - names = name_block(mdesc); +const void *mdesc_get_property(struct mdesc_handle *hp, u64 node, + const char *name, int *lenp) +{ + const char *names = name_block(&hp->mdesc); + u64 last_node = hp->mdesc.node_sz / 16; + void *data = data_block(&hp->mdesc); + struct mdesc_elem *ep; - while (1) { - u64 node = ep - start; + if (node == MDESC_NODE_NULL || node >= last_node) + return NULL; - if (ep->tag == MD_LIST_END) + ep = node_block(&hp->mdesc) + node; + ep++; + for (; ep->tag != MD_NODE_END; ep++) { + void *val = NULL; + int len = 0; + + switch (ep->tag) { + case MD_PROP_VAL: + val = &ep->d.val; + len = 8; break; - if (ep->tag != MD_NODE) { - prom_printf("MDESC: Inconsistent element list.\n"); - prom_halt(); - } - - mdesc_node_alloc(node, ep, names); + case MD_PROP_STR: + case MD_PROP_DATA: + val = data + ep->d.data.data_offset; + len = ep->d.data.data_len; + break; - if (ep->d.val >= last_node) { - printk("MDESC: Warning, early break out of node scan.\n"); - printk("MDESC: Next node [%lu] last_node [%lu].\n", - node, last_node); + default: break; } + if (!val) + continue; - ep = start + ep->d.val; + if (!strcmp(names + ep->name_offset, name)) { + if (lenp) + *lenp = len; + return val; + } } - data = data_block(mdesc); - for (mp = allnodes; mp; mp = mp->allnodes_next) { - struct mdesc_elem *ep = start + mp->node; - struct property **link = &mp->properties; - unsigned int this_arc = 0; - - ep++; - while (ep->tag != MD_NODE_END) { - switch (ep->tag) { - case MD_PROP_ARC: { - struct mdesc_node *target; - - if (this_arc >= mp->num_arcs) { - prom_printf("MDESC: ARC overrun [%u:%u]\n", - this_arc, mp->num_arcs); - prom_halt(); - } - target = find_node(ep->d.val); - if (!target) { - printk("MDESC: Warning, arc points to " - "missing node, ignoring.\n"); - break; - } - mp->arcs[this_arc].name = - (names + ep->name_offset); - mp->arcs[this_arc].arc = target; - this_arc++; - break; - } + return NULL; +} +EXPORT_SYMBOL(mdesc_get_property); - case MD_PROP_VAL: - case MD_PROP_STR: - case MD_PROP_DATA: { - struct property *p = mdesc_early_alloc(sizeof(*p)); - - p->unique_id = unique_id++; - p->name = (char *) names + ep->name_offset; - if (ep->tag == MD_PROP_VAL) { - p->value = &ep->d.val; - p->length = 8; - } else { - p->value = data + ep->d.data.data_offset; - p->length = ep->d.data.data_len; - } - *link = p; - link = &p->next; - break; - } +u64 mdesc_next_arc(struct mdesc_handle *hp, u64 from, const char *arc_type) +{ + struct mdesc_elem *ep, *base = node_block(&hp->mdesc); + const char *names = name_block(&hp->mdesc); + u64 last_node = hp->mdesc.node_sz / 16; - case MD_NOOP: - break; + if (from == MDESC_NODE_NULL || from >= last_node) + return MDESC_NODE_NULL; - default: - printk("MDESC: Warning, ignoring unknown tag type %02x\n", - ep->tag); - } - ep++; - } + ep = base + from; + + ep++; + for (; ep->tag != MD_NODE_END; ep++) { + if (ep->tag != MD_PROP_ARC) + continue; + + if (strcmp(names + ep->name_offset, arc_type)) + continue; + + return ep - base; } + + return MDESC_NODE_NULL; } +EXPORT_SYMBOL(mdesc_next_arc); -static unsigned int __init count_nodes(struct mdesc_hdr *mdesc) +u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc) { - struct mdesc_elem *ep = node_block(mdesc); - struct mdesc_elem *end; - unsigned int cnt = 0; - - end = ((void *)ep) + mdesc->node_sz; - while (ep < end) { - if (ep->tag == MD_NODE) - cnt++; - ep++; - } - return cnt; + struct mdesc_elem *ep, *base = node_block(&hp->mdesc); + + ep = base + arc; + + return ep->d.val; +} +EXPORT_SYMBOL(mdesc_arc_target); + +const char *mdesc_node_name(struct mdesc_handle *hp, u64 node) +{ + struct mdesc_elem *ep, *base = node_block(&hp->mdesc); + const char *names = name_block(&hp->mdesc); + u64 last_node = hp->mdesc.node_sz / 16; + + if (node == MDESC_NODE_NULL || node >= last_node) + return NULL; + + ep = base + node; + if (ep->tag != MD_NODE) + return NULL; + + return names + ep->name_offset; } +EXPORT_SYMBOL(mdesc_node_name); static void __init report_platform_properties(void) { - struct mdesc_node *pn = md_find_node_by_name(NULL, "platform"); + struct mdesc_handle *hp = mdesc_grab(); + u64 pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "platform"); const char *s; const u64 *v; - if (!pn) { + if (pn == MDESC_NODE_NULL) { prom_printf("No platform node in machine-description.\n"); prom_halt(); } - s = md_get_property(pn, "banner-name", NULL); + s = mdesc_get_property(hp, pn, "banner-name", NULL); printk("PLATFORM: banner-name [%s]\n", s); - s = md_get_property(pn, "name", NULL); + s = mdesc_get_property(hp, pn, "name", NULL); printk("PLATFORM: name [%s]\n", s); - v = md_get_property(pn, "hostid", NULL); + v = mdesc_get_property(hp, pn, "hostid", NULL); if (v) printk("PLATFORM: hostid [%08lx]\n", *v); - v = md_get_property(pn, "serial#", NULL); + v = mdesc_get_property(hp, pn, "serial#", NULL); if (v) printk("PLATFORM: serial# [%08lx]\n", *v); - v = md_get_property(pn, "stick-frequency", NULL); + v = mdesc_get_property(hp, pn, "stick-frequency", NULL); printk("PLATFORM: stick-frequency [%08lx]\n", *v); - v = md_get_property(pn, "mac-address", NULL); + v = mdesc_get_property(hp, pn, "mac-address", NULL); if (v) printk("PLATFORM: mac-address [%lx]\n", *v); - v = md_get_property(pn, "watchdog-resolution", NULL); + v = mdesc_get_property(hp, pn, "watchdog-resolution", NULL); if (v) printk("PLATFORM: watchdog-resolution [%lu ms]\n", *v); - v = md_get_property(pn, "watchdog-max-timeout", NULL); + v = mdesc_get_property(hp, pn, "watchdog-max-timeout", NULL); if (v) printk("PLATFORM: watchdog-max-timeout [%lu ms]\n", *v); - v = md_get_property(pn, "max-cpus", NULL); + v = mdesc_get_property(hp, pn, "max-cpus", NULL); if (v) printk("PLATFORM: max-cpus [%lu]\n", *v); + +#ifdef CONFIG_SMP + { + int max_cpu, i; + + if (v) { + max_cpu = *v; + if (max_cpu > NR_CPUS) + max_cpu = NR_CPUS; + } else { + max_cpu = NR_CPUS; + } + for (i = 0; i < max_cpu; i++) + cpu_set(i, cpu_possible_map); + } +#endif + + mdesc_release(hp); } static int inline find_in_proplist(const char *list, const char *match, int len) @@ -369,15 +468,17 @@ static int inline find_in_proplist(const char *list, const char *match, int len) return 0; } -static void __init fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_node *mp) +static void __devinit fill_in_one_cache(cpuinfo_sparc *c, + struct mdesc_handle *hp, + u64 mp) { - const u64 *level = md_get_property(mp, "level", NULL); - const u64 *size = md_get_property(mp, "size", NULL); - const u64 *line_size = md_get_property(mp, "line-size", NULL); + const u64 *level = mdesc_get_property(hp, mp, "level", NULL); + const u64 *size = mdesc_get_property(hp, mp, "size", NULL); + const u64 *line_size = mdesc_get_property(hp, mp, "line-size", NULL); const char *type; int type_len; - type = md_get_property(mp, "type", &type_len); + type = mdesc_get_property(hp, mp, "type", &type_len); switch (*level) { case 1: @@ -400,48 +501,45 @@ static void __init fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_node *mp) } if (*level == 1) { - unsigned int i; - - for (i = 0; i < mp->num_arcs; i++) { - struct mdesc_node *t = mp->arcs[i].arc; + u64 a; - if (strcmp(mp->arcs[i].name, "fwd")) - continue; + mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) { + u64 target = mdesc_arc_target(hp, a); + const char *name = mdesc_node_name(hp, target); - if (!strcmp(t->name, "cache")) - fill_in_one_cache(c, t); + if (!strcmp(name, "cache")) + fill_in_one_cache(c, hp, target); } } } -static void __init mark_core_ids(struct mdesc_node *mp, int core_id) +static void __devinit mark_core_ids(struct mdesc_handle *hp, u64 mp, + int core_id) { - unsigned int i; + u64 a; - for (i = 0; i < mp->num_arcs; i++) { - struct mdesc_node *t = mp->arcs[i].arc; + mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) { + u64 t = mdesc_arc_target(hp, a); + const char *name; const u64 *id; - if (strcmp(mp->arcs[i].name, "back")) - continue; - - if (!strcmp(t->name, "cpu")) { - id = md_get_property(t, "id", NULL); + name = mdesc_node_name(hp, t); + if (!strcmp(name, "cpu")) { + id = mdesc_get_property(hp, t, "id", NULL); if (*id < NR_CPUS) cpu_data(*id).core_id = core_id; } else { - unsigned int j; + u64 j; - for (j = 0; j < t->num_arcs; j++) { - struct mdesc_node *n = t->arcs[j].arc; + mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_BACK) { + u64 n = mdesc_arc_target(hp, j); + const char *n_name; - if (strcmp(t->arcs[j].name, "back")) + n_name = mdesc_node_name(hp, n); + if (strcmp(n_name, "cpu")) continue; - if (strcmp(n->name, "cpu")) - continue; - - id = md_get_property(n, "id", NULL); + id = mdesc_get_property(hp, n, "id", NULL); if (*id < NR_CPUS) cpu_data(*id).core_id = core_id; } @@ -449,78 +547,81 @@ static void __init mark_core_ids(struct mdesc_node *mp, int core_id) } } -static void __init set_core_ids(void) +static void __devinit set_core_ids(struct mdesc_handle *hp) { - struct mdesc_node *mp; int idx; + u64 mp; idx = 1; - md_for_each_node_by_name(mp, "cache") { - const u64 *level = md_get_property(mp, "level", NULL); + mdesc_for_each_node_by_name(hp, mp, "cache") { + const u64 *level; const char *type; int len; + level = mdesc_get_property(hp, mp, "level", NULL); if (*level != 1) continue; - type = md_get_property(mp, "type", &len); + type = mdesc_get_property(hp, mp, "type", &len); if (!find_in_proplist(type, "instn", len)) continue; - mark_core_ids(mp, idx); + mark_core_ids(hp, mp, idx); idx++; } } -static void __init mark_proc_ids(struct mdesc_node *mp, int proc_id) +static void __devinit mark_proc_ids(struct mdesc_handle *hp, u64 mp, + int proc_id) { - int i; + u64 a; - for (i = 0; i < mp->num_arcs; i++) { - struct mdesc_node *t = mp->arcs[i].arc; + mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) { + u64 t = mdesc_arc_target(hp, a); + const char *name; const u64 *id; - if (strcmp(mp->arcs[i].name, "back")) - continue; - - if (strcmp(t->name, "cpu")) + name = mdesc_node_name(hp, t); + if (strcmp(name, "cpu")) continue; - id = md_get_property(t, "id", NULL); + id = mdesc_get_property(hp, t, "id", NULL); if (*id < NR_CPUS) cpu_data(*id).proc_id = proc_id; } } -static void __init __set_proc_ids(const char *exec_unit_name) +static void __devinit __set_proc_ids(struct mdesc_handle *hp, + const char *exec_unit_name) { - struct mdesc_node *mp; int idx; + u64 mp; idx = 0; - md_for_each_node_by_name(mp, exec_unit_name) { + mdesc_for_each_node_by_name(hp, mp, exec_unit_name) { const char *type; int len; - type = md_get_property(mp, "type", &len); + type = mdesc_get_property(hp, mp, "type", &len); if (!find_in_proplist(type, "int", len) && !find_in_proplist(type, "integer", len)) continue; - mark_proc_ids(mp, idx); + mark_proc_ids(hp, mp, idx); idx++; } } -static void __init set_proc_ids(void) +static void __devinit set_proc_ids(struct mdesc_handle *hp) { - __set_proc_ids("exec_unit"); - __set_proc_ids("exec-unit"); + __set_proc_ids(hp, "exec_unit"); + __set_proc_ids(hp, "exec-unit"); } -static void __init get_one_mondo_bits(const u64 *p, unsigned int *mask, unsigned char def) +static void __devinit get_one_mondo_bits(const u64 *p, unsigned int *mask, + unsigned char def) { u64 val; @@ -538,35 +639,37 @@ use_default: *mask = ((1U << def) * 64U) - 1U; } -static void __init get_mondo_data(struct mdesc_node *mp, struct trap_per_cpu *tb) +static void __devinit get_mondo_data(struct mdesc_handle *hp, u64 mp, + struct trap_per_cpu *tb) { const u64 *val; - val = md_get_property(mp, "q-cpu-mondo-#bits", NULL); + val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL); get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7); - val = md_get_property(mp, "q-dev-mondo-#bits", NULL); + val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL); get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7); - val = md_get_property(mp, "q-resumable-#bits", NULL); + val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL); get_one_mondo_bits(val, &tb->resum_qmask, 6); - val = md_get_property(mp, "q-nonresumable-#bits", NULL); + val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL); get_one_mondo_bits(val, &tb->nonresum_qmask, 2); } -static void __init mdesc_fill_in_cpu_data(void) +void __devinit mdesc_fill_in_cpu_data(cpumask_t mask) { - struct mdesc_node *mp; + struct mdesc_handle *hp = mdesc_grab(); + u64 mp; ncpus_probed = 0; - md_for_each_node_by_name(mp, "cpu") { - const u64 *id = md_get_property(mp, "id", NULL); - const u64 *cfreq = md_get_property(mp, "clock-frequency", NULL); + mdesc_for_each_node_by_name(hp, mp, "cpu") { + const u64 *id = mdesc_get_property(hp, mp, "id", NULL); + const u64 *cfreq = mdesc_get_property(hp, mp, "clock-frequency", NULL); struct trap_per_cpu *tb; cpuinfo_sparc *c; - unsigned int i; int cpuid; + u64 a; ncpus_probed++; @@ -575,6 +678,8 @@ static void __init mdesc_fill_in_cpu_data(void) #ifdef CONFIG_SMP if (cpuid >= NR_CPUS) continue; + if (!cpu_isset(cpuid, mask)) + continue; #else /* On uniprocessor we only want the values for the * real physical cpu the kernel booted onto, however @@ -589,35 +694,30 @@ static void __init mdesc_fill_in_cpu_data(void) c->clock_tick = *cfreq; tb = &trap_block[cpuid]; - get_mondo_data(mp, tb); - - for (i = 0; i < mp->num_arcs; i++) { - struct mdesc_node *t = mp->arcs[i].arc; - unsigned int j; + get_mondo_data(hp, mp, tb); - if (strcmp(mp->arcs[i].name, "fwd")) - continue; + mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) { + u64 j, t = mdesc_arc_target(hp, a); + const char *t_name; - if (!strcmp(t->name, "cache")) { - fill_in_one_cache(c, t); + t_name = mdesc_node_name(hp, t); + if (!strcmp(t_name, "cache")) { + fill_in_one_cache(c, hp, t); continue; } - for (j = 0; j < t->num_arcs; j++) { - struct mdesc_node *n; + mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_FWD) { + u64 n = mdesc_arc_target(hp, j); + const char *n_name; - n = t->arcs[j].arc; - if (strcmp(t->arcs[j].name, "fwd")) - continue; - - if (!strcmp(n->name, "cache")) - fill_in_one_cache(c, n); + n_name = mdesc_node_name(hp, n); + if (!strcmp(n_name, "cache")) + fill_in_one_cache(c, hp, n); } } #ifdef CONFIG_SMP cpu_set(cpuid, cpu_present_map); - cpu_set(cpuid, phys_cpu_present_map); #endif c->core_id = 0; @@ -628,45 +728,43 @@ static void __init mdesc_fill_in_cpu_data(void) sparc64_multi_core = 1; #endif - set_core_ids(); - set_proc_ids(); + set_core_ids(hp); + set_proc_ids(hp); smp_fill_in_sib_core_maps(); + + mdesc_release(hp); } void __init sun4v_mdesc_init(void) { + struct mdesc_handle *hp; unsigned long len, real_len, status; + cpumask_t mask; (void) sun4v_mach_desc(0UL, 0UL, &len); printk("MDESC: Size is %lu bytes.\n", len); - main_mdesc = mdesc_early_alloc(len); + hp = mdesc_alloc(len, &bootmem_mdesc_memops); + if (hp == NULL) { + prom_printf("MDESC: alloc of %lu bytes failed.\n", len); + prom_halt(); + } - status = sun4v_mach_desc(__pa(main_mdesc), len, &real_len); + status = sun4v_mach_desc(__pa(&hp->mdesc), len, &real_len); if (status != HV_EOK || real_len > len) { prom_printf("sun4v_mach_desc fails, err(%lu), " "len(%lu), real_len(%lu)\n", status, len, real_len); + mdesc_free(hp); prom_halt(); } - len = count_nodes(main_mdesc); - printk("MDESC: %lu nodes.\n", len); - - len = roundup_pow_of_two(len); - - mdesc_hash = mdesc_early_alloc(len * sizeof(struct mdesc_node *)); - mdesc_hash_size = len; - - printk("MDESC: Hash size %lu entries.\n", len); - - build_all_nodes(main_mdesc); - - printk("MDESC: Built graph with %u bytes of memory.\n", - mdesc_early_allocated); + cur_mdesc = hp; report_platform_properties(); - mdesc_fill_in_cpu_data(); + + cpus_setall(mask); + mdesc_fill_in_cpu_data(mask); } diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index 5d6adea3967..8dd4294ad21 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c @@ -1,7 +1,6 @@ -/* $Id: power.c,v 1.10 2001/12/11 01:57:16 davem Exp $ - * power.c: Power management driver. +/* power.c: Power management driver. * - * Copyright (C) 1999 David S. Miller (davem@redhat.com) + * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) */ #include <linux/kernel.h> @@ -19,6 +18,7 @@ #include <asm/prom.h> #include <asm/of_device.h> #include <asm/io.h> +#include <asm/power.h> #include <asm/sstate.h> #include <linux/unistd.h> @@ -29,24 +29,26 @@ */ int scons_pwroff = 1; -#ifdef CONFIG_PCI -#include <linux/pci.h> static void __iomem *power_reg; static DECLARE_WAIT_QUEUE_HEAD(powerd_wait); static int button_pressed; -static irqreturn_t power_handler(int irq, void *dev_id) +void wake_up_powerd(void) { if (button_pressed == 0) { button_pressed = 1; wake_up(&powerd_wait); } +} + +static irqreturn_t power_handler(int irq, void *dev_id) +{ + wake_up_powerd(); /* FIXME: Check registers for status... */ return IRQ_HANDLED; } -#endif /* CONFIG_PCI */ extern void machine_halt(void); extern void machine_alt_power_off(void); @@ -56,19 +58,18 @@ void machine_power_off(void) { sstate_poweroff(); if (!serial_console || scons_pwroff) { -#ifdef CONFIG_PCI if (power_reg) { /* Both register bits seem to have the * same effect, so until I figure out * what the difference is... */ writel(AUXIO_PCIO_CPWR_OFF | AUXIO_PCIO_SPWR_OFF, power_reg); - } else -#endif /* CONFIG_PCI */ + } else { if (poweroff_method != NULL) { poweroff_method(); /* not reached */ } + } } machine_halt(); } @@ -76,7 +77,6 @@ void machine_power_off(void) void (*pm_power_off)(void) = machine_power_off; EXPORT_SYMBOL(pm_power_off); -#ifdef CONFIG_PCI static int powerd(void *__unused) { static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; @@ -86,7 +86,7 @@ static int powerd(void *__unused) daemonize("powerd"); add_wait_queue(&powerd_wait, &wait); -again: + for (;;) { set_task_state(current, TASK_INTERRUPTIBLE); if (button_pressed) @@ -100,16 +100,28 @@ again: /* Ok, down we go... */ button_pressed = 0; if (kernel_execve("/sbin/shutdown", argv, envp) < 0) { - printk("powerd: shutdown execution failed\n"); - add_wait_queue(&powerd_wait, &wait); - goto again; + printk(KERN_ERR "powerd: shutdown execution failed\n"); + machine_power_off(); } return 0; } +int start_powerd(void) +{ + int err; + + err = kernel_thread(powerd, NULL, CLONE_FS); + if (err < 0) + printk(KERN_ERR "power: Failed to start power daemon.\n"); + else + printk(KERN_INFO "power: powerd running.\n"); + + return err; +} + static int __init has_button_interrupt(unsigned int irq, struct device_node *dp) { - if (irq == PCI_IRQ_NONE) + if (irq == 0xffffffff) return 0; if (!of_find_property(dp, "button", NULL)) return 0; @@ -130,17 +142,14 @@ static int __devinit power_probe(struct of_device *op, const struct of_device_id poweroff_method = machine_halt; /* able to use the standard halt */ if (has_button_interrupt(irq, op->node)) { - if (kernel_thread(powerd, NULL, CLONE_FS) < 0) { - printk("Failed to start power daemon.\n"); + if (start_powerd() < 0) return 0; - } - printk("powerd running.\n"); if (request_irq(irq, power_handler, 0, "power", NULL) < 0) - printk("power: Error, cannot register IRQ handler.\n"); + printk(KERN_ERR "power: Cannot setup IRQ handler.\n"); } else { - printk("not using powerd.\n"); + printk(KERN_INFO "power: Not using powerd.\n"); } return 0; @@ -164,4 +173,3 @@ void __init power_init(void) of_register_driver(&power_driver, &of_bus_type); return; } -#endif /* CONFIG_PCI */ diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index f5f97e2c669..93557507ec9 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -29,6 +29,7 @@ #include <linux/compat.h> #include <linux/tick.h> #include <linux/init.h> +#include <linux/cpu.h> #include <asm/oplib.h> #include <asm/uaccess.h> @@ -49,7 +50,7 @@ /* #define VERBOSE_SHOWREGS */ -static void sparc64_yield(void) +static void sparc64_yield(int cpu) { if (tlb_type != hypervisor) return; @@ -57,7 +58,7 @@ static void sparc64_yield(void) clear_thread_flag(TIF_POLLING_NRFLAG); smp_mb__after_clear_bit(); - while (!need_resched()) { + while (!need_resched() && !cpu_is_offline(cpu)) { unsigned long pstate; /* Disable interrupts. */ @@ -68,7 +69,7 @@ static void sparc64_yield(void) : "=&r" (pstate) : "i" (PSTATE_IE)); - if (!need_resched()) + if (!need_resched() && !cpu_is_offline(cpu)) sun4v_cpu_yield(); /* Re-enable interrupts. */ @@ -86,15 +87,25 @@ static void sparc64_yield(void) /* The idle loop on sparc64. */ void cpu_idle(void) { + int cpu = smp_processor_id(); + set_thread_flag(TIF_POLLING_NRFLAG); while(1) { tick_nohz_stop_sched_tick(); - while (!need_resched()) - sparc64_yield(); + + while (!need_resched() && !cpu_is_offline(cpu)) + sparc64_yield(cpu); + tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); + +#ifdef CONFIG_HOTPLUG_CPU + if (cpu_is_offline(cpu)) + cpu_play_dead(); +#endif + schedule(); preempt_disable(); } diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index 61036b34666..5d220302cd5 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -1808,7 +1808,7 @@ static void __init of_fill_in_cpu_data(void) #ifdef CONFIG_SMP cpu_set(cpuid, cpu_present_map); - cpu_set(cpuid, phys_cpu_present_map); + cpu_set(cpuid, cpu_possible_map); #endif } diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 7490cc670a5..dc928e49e34 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -442,7 +442,6 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) "D$ parity tl1\t: %u\n" "I$ parity tl1\t: %u\n" #ifndef CONFIG_SMP - "Cpu0Bogo\t: %lu.%02lu\n" "Cpu0ClkTck\t: %016lx\n" #endif , @@ -455,10 +454,8 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) ncpus_probed, num_online_cpus(), dcache_parity_tl1_occurred, - icache_parity_tl1_occurred + icache_parity_tl1_occurred, #ifndef CONFIG_SMP - , cpu_data(0).udelay_val/(500000/HZ), - (cpu_data(0).udelay_val/(5000/HZ)) % 100, cpu_data(0).clock_tick #endif ); diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 40e40f968d6..b448d33321c 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -1,6 +1,6 @@ /* smp.c: Sparc64 SMP support. * - * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1997, 2007 David S. Miller (davem@davemloft.net) */ #include <linux/module.h> @@ -28,6 +28,8 @@ #include <asm/tlbflush.h> #include <asm/mmu_context.h> #include <asm/cpudata.h> +#include <asm/hvtramp.h> +#include <asm/io.h> #include <asm/irq.h> #include <asm/irq_regs.h> @@ -41,22 +43,26 @@ #include <asm/sections.h> #include <asm/prom.h> #include <asm/mdesc.h> +#include <asm/ldc.h> +#include <asm/hypervisor.h> extern void calibrate_delay(void); int sparc64_multi_core __read_mostly; -/* Please don't make this stuff initdata!!! --DaveM */ -unsigned char boot_cpu_id; - +cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE; cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; -cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE; cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; cpumask_t cpu_core_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; + +EXPORT_SYMBOL(cpu_possible_map); +EXPORT_SYMBOL(cpu_online_map); +EXPORT_SYMBOL(cpu_sibling_map); +EXPORT_SYMBOL(cpu_core_map); + static cpumask_t smp_commenced_mask; -static cpumask_t cpu_callout_map; void smp_info(struct seq_file *m) { @@ -73,18 +79,17 @@ void smp_bogo(struct seq_file *m) for_each_online_cpu(i) seq_printf(m, - "Cpu%dBogo\t: %lu.%02lu\n" "Cpu%dClkTck\t: %016lx\n", - i, cpu_data(i).udelay_val / (500000/HZ), - (cpu_data(i).udelay_val / (5000/HZ)) % 100, i, cpu_data(i).clock_tick); } +static __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock); + extern void setup_sparc64_timer(void); static volatile unsigned long callin_flag = 0; -void __init smp_callin(void) +void __devinit smp_callin(void) { int cpuid = hard_smp_processor_id(); @@ -102,8 +107,6 @@ void __init smp_callin(void) local_irq_enable(); - calibrate_delay(); - cpu_data(cpuid).udelay_val = loops_per_jiffy; callin_flag = 1; __asm__ __volatile__("membar #Sync\n\t" "flush %%g6" : : : "memory"); @@ -120,7 +123,9 @@ void __init smp_callin(void) while (!cpu_isset(cpuid, smp_commenced_mask)) rmb(); + spin_lock(&call_lock); cpu_set(cpuid, cpu_online_map); + spin_unlock(&call_lock); /* idle thread is expected to have preempt disabled */ preempt_disable(); @@ -268,6 +273,67 @@ static void smp_synchronize_one_tick(int cpu) spin_unlock_irqrestore(&itc_sync_lock, flags); } +#if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU) +/* XXX Put this in some common place. XXX */ +static unsigned long kimage_addr_to_ra(void *p) +{ + unsigned long val = (unsigned long) p; + + return kern_base + (val - KERNBASE); +} + +static void ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg) +{ + extern unsigned long sparc64_ttable_tl0; + extern unsigned long kern_locked_tte_data; + extern int bigkernel; + struct hvtramp_descr *hdesc; + unsigned long trampoline_ra; + struct trap_per_cpu *tb; + u64 tte_vaddr, tte_data; + unsigned long hv_err; + + hdesc = kzalloc(sizeof(*hdesc), GFP_KERNEL); + if (!hdesc) { + printk(KERN_ERR "ldom_startcpu_cpuid: Cannot allocate " + "hvtramp_descr.\n"); + return; + } + + hdesc->cpu = cpu; + hdesc->num_mappings = (bigkernel ? 2 : 1); + + tb = &trap_block[cpu]; + tb->hdesc = hdesc; + + hdesc->fault_info_va = (unsigned long) &tb->fault_info; + hdesc->fault_info_pa = kimage_addr_to_ra(&tb->fault_info); + + hdesc->thread_reg = thread_reg; + + tte_vaddr = (unsigned long) KERNBASE; + tte_data = kern_locked_tte_data; + + hdesc->maps[0].vaddr = tte_vaddr; + hdesc->maps[0].tte = tte_data; + if (bigkernel) { + tte_vaddr += 0x400000; + tte_data += 0x400000; + hdesc->maps[1].vaddr = tte_vaddr; + hdesc->maps[1].tte = tte_data; + } + + trampoline_ra = kimage_addr_to_ra(hv_cpu_startup); + + hv_err = sun4v_cpu_start(cpu, trampoline_ra, + kimage_addr_to_ra(&sparc64_ttable_tl0), + __pa(hdesc)); + if (hv_err) + printk(KERN_ERR "ldom_startcpu_cpuid: sun4v_cpu_start() " + "gives error %lu\n", hv_err); +} +#endif + extern void sun4v_init_mondo_queues(int use_bootmem, int cpu, int alloc, int load); extern unsigned long sparc64_cpu_startup; @@ -280,6 +346,7 @@ static struct thread_info *cpu_new_thread = NULL; static int __devinit smp_boot_one_cpu(unsigned int cpu) { + struct trap_per_cpu *tb = &trap_block[cpu]; unsigned long entry = (unsigned long)(&sparc64_cpu_startup); unsigned long cookie = @@ -290,20 +357,25 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu) p = fork_idle(cpu); callin_flag = 0; cpu_new_thread = task_thread_info(p); - cpu_set(cpu, cpu_callout_map); if (tlb_type == hypervisor) { /* Alloc the mondo queues, cpu will load them. */ sun4v_init_mondo_queues(0, cpu, 1, 0); - prom_startcpu_cpuid(cpu, entry, cookie); +#if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU) + if (ldom_domaining_enabled) + ldom_startcpu_cpuid(cpu, + (unsigned long) cpu_new_thread); + else +#endif + prom_startcpu_cpuid(cpu, entry, cookie); } else { struct device_node *dp = of_find_node_by_cpuid(cpu); prom_startcpu(dp->node, entry, cookie); } - for (timeout = 0; timeout < 5000000; timeout++) { + for (timeout = 0; timeout < 50000; timeout++) { if (callin_flag) break; udelay(100); @@ -313,11 +385,15 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu) ret = 0; } else { printk("Processor %d is stuck.\n", cpu); - cpu_clear(cpu, cpu_callout_map); ret = -ENODEV; } cpu_new_thread = NULL; + if (tb->hdesc) { + kfree(tb->hdesc); + tb->hdesc = NULL; + } + return ret; } @@ -720,7 +796,6 @@ struct call_data_struct { int wait; }; -static __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock); static struct call_data_struct *call_data; extern unsigned long xcall_call_function; @@ -1152,34 +1227,14 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) preempt_enable(); } -void __init smp_tick_init(void) -{ - boot_cpu_id = hard_smp_processor_id(); -} - /* /proc/profile writes can call this, don't __init it please. */ int setup_profiling_timer(unsigned int multiplier) { return -EINVAL; } -/* Constrain the number of cpus to max_cpus. */ void __init smp_prepare_cpus(unsigned int max_cpus) { - int i; - - if (num_possible_cpus() > max_cpus) { - for_each_possible_cpu(i) { - if (i != boot_cpu_id) { - cpu_clear(i, phys_cpu_present_map); - cpu_clear(i, cpu_present_map); - if (num_possible_cpus() <= max_cpus) - break; - } - } - } - - cpu_data(boot_cpu_id).udelay_val = loops_per_jiffy; } void __devinit smp_prepare_boot_cpu(void) @@ -1190,30 +1245,32 @@ void __devinit smp_fill_in_sib_core_maps(void) { unsigned int i; - for_each_possible_cpu(i) { + for_each_present_cpu(i) { unsigned int j; + cpus_clear(cpu_core_map[i]); if (cpu_data(i).core_id == 0) { cpu_set(i, cpu_core_map[i]); continue; } - for_each_possible_cpu(j) { + for_each_present_cpu(j) { if (cpu_data(i).core_id == cpu_data(j).core_id) cpu_set(j, cpu_core_map[i]); } } - for_each_possible_cpu(i) { + for_each_present_cpu(i) { unsigned int j; + cpus_clear(cpu_sibling_map[i]); if (cpu_data(i).proc_id == -1) { cpu_set(i, cpu_sibling_map[i]); continue; } - for_each_possible_cpu(j) { + for_each_present_cpu(j) { if (cpu_data(i).proc_id == cpu_data(j).proc_id) cpu_set(j, cpu_sibling_map[i]); @@ -1242,18 +1299,112 @@ int __cpuinit __cpu_up(unsigned int cpu) return ret; } -void __init smp_cpus_done(unsigned int max_cpus) +#ifdef CONFIG_HOTPLUG_CPU +void cpu_play_dead(void) +{ + int cpu = smp_processor_id(); + unsigned long pstate; + + idle_task_exit(); + + if (tlb_type == hypervisor) { + struct trap_per_cpu *tb = &trap_block[cpu]; + + sun4v_cpu_qconf(HV_CPU_QUEUE_CPU_MONDO, + tb->cpu_mondo_pa, 0); + sun4v_cpu_qconf(HV_CPU_QUEUE_DEVICE_MONDO, + tb->dev_mondo_pa, 0); + sun4v_cpu_qconf(HV_CPU_QUEUE_RES_ERROR, + tb->resum_mondo_pa, 0); + sun4v_cpu_qconf(HV_CPU_QUEUE_NONRES_ERROR, + tb->nonresum_mondo_pa, 0); + } + + cpu_clear(cpu, smp_commenced_mask); + membar_safe("#Sync"); + + local_irq_disable(); + + __asm__ __volatile__( + "rdpr %%pstate, %0\n\t" + "wrpr %0, %1, %%pstate" + : "=r" (pstate) + : "i" (PSTATE_IE)); + + while (1) + barrier(); +} + +int __cpu_disable(void) { - unsigned long bogosum = 0; + int cpu = smp_processor_id(); + cpuinfo_sparc *c; int i; - for_each_online_cpu(i) - bogosum += cpu_data(i).udelay_val; - printk("Total of %ld processors activated " - "(%lu.%02lu BogoMIPS).\n", - (long) num_online_cpus(), - bogosum/(500000/HZ), - (bogosum/(5000/HZ))%100); + for_each_cpu_mask(i, cpu_core_map[cpu]) + cpu_clear(cpu, cpu_core_map[i]); + cpus_clear(cpu_core_map[cpu]); + + for_each_cpu_mask(i, cpu_sibling_map[cpu]) + cpu_clear(cpu, cpu_sibling_map[i]); + cpus_clear(cpu_sibling_map[cpu]); + + c = &cpu_data(cpu); + + c->core_id = 0; + c->proc_id = -1; + + spin_lock(&call_lock); + cpu_clear(cpu, cpu_online_map); + spin_unlock(&call_lock); + + smp_wmb(); + + /* Make sure no interrupts point to this cpu. */ + fixup_irqs(); + + local_irq_enable(); + mdelay(1); + local_irq_disable(); + + return 0; +} + +void __cpu_die(unsigned int cpu) +{ + int i; + + for (i = 0; i < 100; i++) { + smp_rmb(); + if (!cpu_isset(cpu, smp_commenced_mask)) + break; + msleep(100); + } + if (cpu_isset(cpu, smp_commenced_mask)) { + printk(KERN_ERR "CPU %u didn't die...\n", cpu); + } else { +#if defined(CONFIG_SUN_LDOMS) + unsigned long hv_err; + int limit = 100; + + do { + hv_err = sun4v_cpu_stop(cpu); + if (hv_err == HV_EOK) { + cpu_clear(cpu, cpu_present_map); + break; + } + } while (--limit > 0); + if (limit <= 0) { + printk(KERN_ERR "sun4v_cpu_stop() fails err=%lu\n", + hv_err); + } +#endif + } +} +#endif + +void __init smp_cpus_done(unsigned int max_cpus) +{ } void smp_send_reschedule(int cpu) diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 6fa76161289..719d676c2dd 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,7 +1,6 @@ -/* $Id: sparc64_ksyms.c,v 1.121 2002/02/09 19:49:31 davem Exp $ - * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. +/* arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz) */ @@ -28,7 +27,6 @@ #include <net/compat.h> #include <asm/oplib.h> -#include <asm/delay.h> #include <asm/system.h> #include <asm/auxio.h> #include <asm/pgtable.h> @@ -124,10 +122,6 @@ EXPORT_SYMBOL(__write_lock); EXPORT_SYMBOL(__write_unlock); EXPORT_SYMBOL(__write_trylock); -/* CPU online map and active count. */ -EXPORT_SYMBOL(cpu_online_map); -EXPORT_SYMBOL(phys_cpu_present_map); - EXPORT_SYMBOL(smp_call_function); #endif /* CONFIG_SMP */ @@ -330,12 +324,6 @@ EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(strncmp); -/* Delay routines. */ -EXPORT_SYMBOL(__udelay); -EXPORT_SYMBOL(__ndelay); -EXPORT_SYMBOL(__const_udelay); -EXPORT_SYMBOL(__delay); - void VISenter(void); /* RAID code needs this */ EXPORT_SYMBOL(VISenter); diff --git a/arch/sparc64/kernel/sysfs.c b/arch/sparc64/kernel/sysfs.c index cdb1477af89..52816c7be0b 100644 --- a/arch/sparc64/kernel/sysfs.c +++ b/arch/sparc64/kernel/sysfs.c @@ -193,7 +193,6 @@ static ssize_t show_##NAME(struct sys_device *dev, char *buf) \ } SHOW_CPUDATA_ULONG_NAME(clock_tick, clock_tick); -SHOW_CPUDATA_ULONG_NAME(udelay_val, udelay_val); SHOW_CPUDATA_UINT_NAME(l1_dcache_size, dcache_size); SHOW_CPUDATA_UINT_NAME(l1_dcache_line_size, dcache_line_size); SHOW_CPUDATA_UINT_NAME(l1_icache_size, icache_size); @@ -203,7 +202,6 @@ SHOW_CPUDATA_UINT_NAME(l2_cache_line_size, ecache_line_size); static struct sysdev_attribute cpu_core_attrs[] = { _SYSDEV_ATTR(clock_tick, 0444, show_clock_tick, NULL), - _SYSDEV_ATTR(udelay_val, 0444, show_udelay_val, NULL), _SYSDEV_ATTR(l1_dcache_size, 0444, show_l1_dcache_size, NULL), _SYSDEV_ATTR(l1_dcache_line_size, 0444, show_l1_dcache_line_size, NULL), _SYSDEV_ATTR(l1_icache_size, 0444, show_l1_icache_size, NULL), diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index a31a0439244..62e316ab133 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -849,9 +849,6 @@ static unsigned long sparc64_init_timers(void) { struct device_node *dp; unsigned long clock; -#ifdef CONFIG_SMP - extern void smp_tick_init(void); -#endif dp = of_find_node_by_path("/"); if (tlb_type == spitfire) { @@ -874,10 +871,6 @@ static unsigned long sparc64_init_timers(void) clock = of_getintprop_default(dp, "stick-frequency", 0); } -#ifdef CONFIG_SMP - smp_tick_init(); -#endif - return clock; } @@ -1038,10 +1031,31 @@ static void __init setup_clockevent_multiplier(unsigned long hz) sparc64_clockevent.mult = mult; } +static unsigned long tb_ticks_per_usec __read_mostly; + +void __delay(unsigned long loops) +{ + unsigned long bclock, now; + + bclock = tick_ops->get_tick(); + do { + now = tick_ops->get_tick(); + } while ((now-bclock) < loops); +} +EXPORT_SYMBOL(__delay); + +void udelay(unsigned long usecs) +{ + __delay(tb_ticks_per_usec * usecs); +} +EXPORT_SYMBOL(udelay); + void __init time_init(void) { unsigned long clock = sparc64_init_timers(); + tb_ticks_per_usec = clock / USEC_PER_SEC; + timer_ticks_per_nsec_quotient = clocksource_hz2mult(clock, SPARC64_NSEC_PER_CYC_SHIFT); diff --git a/arch/sparc64/kernel/vio.c b/arch/sparc64/kernel/vio.c new file mode 100644 index 00000000000..49569b44ea1 --- /dev/null +++ b/arch/sparc64/kernel/vio.c @@ -0,0 +1,395 @@ +/* vio.c: Virtual I/O channel devices probing infrastructure. + * + * Copyright (c) 2003-2005 IBM Corp. + * Dave Engebretsen engebret@us.ibm.com + * Santiago Leon santil@us.ibm.com + * Hollis Blanchard <hollisb@us.ibm.com> + * Stephen Rothwell + * + * Adapted to sparc64 by David S. Miller davem@davemloft.net + */ + +#include <linux/kernel.h> +#include <linux/irq.h> +#include <linux/init.h> + +#include <asm/mdesc.h> +#include <asm/vio.h> + +static inline int find_in_proplist(const char *list, const char *match, + int len) +{ + while (len > 0) { + int l; + + if (!strcmp(list, match)) + return 1; + l = strlen(list) + 1; + list += l; + len -= l; + } + return 0; +} + +static const struct vio_device_id *vio_match_device( + const struct vio_device_id *matches, + const struct vio_dev *dev) +{ + const char *type, *compat; + int len; + + type = dev->type; + compat = dev->compat; + len = dev->compat_len; + + while (matches->type[0] || matches->compat[0]) { + int match = 1; + if (matches->type[0]) + match &= !strcmp(matches->type, type); + + if (matches->compat[0]) { + match &= len && + find_in_proplist(compat, matches->compat, len); + } + if (match) + return matches; + matches++; + } + return NULL; +} + +static int vio_bus_match(struct device *dev, struct device_driver *drv) +{ + struct vio_dev *vio_dev = to_vio_dev(dev); + struct vio_driver *vio_drv = to_vio_driver(drv); + const struct vio_device_id *matches = vio_drv->id_table; + + if (!matches) + return 0; + + return vio_match_device(matches, vio_dev) != NULL; +} + +static int vio_device_probe(struct device *dev) +{ + struct vio_dev *vdev = to_vio_dev(dev); + struct vio_driver *drv = to_vio_driver(dev->driver); + const struct vio_device_id *id; + int error = -ENODEV; + + if (drv->probe) { + id = vio_match_device(drv->id_table, vdev); + if (id) + error = drv->probe(vdev, id); + } + + return error; +} + +static int vio_device_remove(struct device *dev) +{ + struct vio_dev *vdev = to_vio_dev(dev); + struct vio_driver *drv = to_vio_driver(dev->driver); + + if (drv->remove) + return drv->remove(vdev); + + return 1; +} + +static ssize_t devspec_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct vio_dev *vdev = to_vio_dev(dev); + const char *str = "none"; + + if (!strcmp(vdev->type, "network")) + str = "vnet"; + else if (!strcmp(vdev->type, "block")) + str = "vdisk"; + + return sprintf(buf, "%s\n", str); +} + +static ssize_t type_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct vio_dev *vdev = to_vio_dev(dev); + return sprintf(buf, "%s\n", vdev->type); +} + +static struct device_attribute vio_dev_attrs[] = { + __ATTR_RO(devspec), + __ATTR_RO(type), + __ATTR_NULL +}; + +static struct bus_type vio_bus_type = { + .name = "vio", + .dev_attrs = vio_dev_attrs, + .match = vio_bus_match, + .probe = vio_device_probe, + .remove = vio_device_remove, +}; + +int vio_register_driver(struct vio_driver *viodrv) +{ + viodrv->driver.bus = &vio_bus_type; + + return driver_register(&viodrv->driver); +} +EXPORT_SYMBOL(vio_register_driver); + +void vio_unregister_driver(struct vio_driver *viodrv) +{ + driver_unregister(&viodrv->driver); +} +EXPORT_SYMBOL(vio_unregister_driver); + +static void __devinit vio_dev_release(struct device *dev) +{ + kfree(to_vio_dev(dev)); +} + +static ssize_t +show_pciobppath_attr(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct vio_dev *vdev; + struct device_node *dp; + + vdev = to_vio_dev(dev); + dp = vdev->dp; + + return snprintf (buf, PAGE_SIZE, "%s\n", dp->full_name); +} + +static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, + show_pciobppath_attr, NULL); + +struct device_node *cdev_node; + +static struct vio_dev *root_vdev; +static u64 cdev_cfg_handle; + +static void vio_fill_channel_info(struct mdesc_handle *hp, u64 mp, + struct vio_dev *vdev) +{ + u64 a; + + mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) { + const u64 *chan_id; + const u64 *irq; + u64 target; + + target = mdesc_arc_target(hp, a); + + irq = mdesc_get_property(hp, target, "tx-ino", NULL); + if (irq) + vdev->tx_irq = sun4v_build_virq(cdev_cfg_handle, *irq); + + irq = mdesc_get_property(hp, target, "rx-ino", NULL); + if (irq) + vdev->rx_irq = sun4v_build_virq(cdev_cfg_handle, *irq); + + chan_id = mdesc_get_property(hp, target, "id", NULL); + if (chan_id) + vdev->channel_id = *chan_id; + } +} + +static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, + struct device *parent) +{ + const char *type, *compat; + struct device_node *dp; + struct vio_dev *vdev; + int err, tlen, clen; + + type = mdesc_get_property(hp, mp, "device-type", &tlen); + if (!type) { + type = mdesc_get_property(hp, mp, "name", &tlen); + if (!type) { + type = mdesc_node_name(hp, mp); + tlen = strlen(type) + 1; + } + } + if (tlen > VIO_MAX_TYPE_LEN) { + printk(KERN_ERR "VIO: Type string [%s] is too long.\n", + type); + return NULL; + } + + compat = mdesc_get_property(hp, mp, "device-type", &clen); + if (!compat) { + clen = 0; + } else if (clen > VIO_MAX_COMPAT_LEN) { + printk(KERN_ERR "VIO: Compat len %d for [%s] is too long.\n", + clen, type); + return NULL; + } + + vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); + if (!vdev) { + printk(KERN_ERR "VIO: Could not allocate vio_dev\n"); + return NULL; + } + + vdev->mp = mp; + memcpy(vdev->type, type, tlen); + if (compat) + memcpy(vdev->compat, compat, clen); + else + memset(vdev->compat, 0, sizeof(vdev->compat)); + vdev->compat_len = clen; + + vdev->channel_id = ~0UL; + vdev->tx_irq = ~0; + vdev->rx_irq = ~0; + + vio_fill_channel_info(hp, mp, vdev); + + snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%lx", mp); + vdev->dev.parent = parent; + vdev->dev.bus = &vio_bus_type; + vdev->dev.release = vio_dev_release; + + if (parent == NULL) { + dp = cdev_node; + } else if (to_vio_dev(parent) == root_vdev) { + dp = of_get_next_child(cdev_node, NULL); + while (dp) { + if (!strcmp(dp->type, type)) + break; + + dp = of_get_next_child(cdev_node, dp); + } + } else { + dp = to_vio_dev(parent)->dp; + } + vdev->dp = dp; + + err = device_register(&vdev->dev); + if (err) { + printk(KERN_ERR "VIO: Could not register device %s, err=%d\n", + vdev->dev.bus_id, err); + kfree(vdev); + return NULL; + } + if (vdev->dp) + err = sysfs_create_file(&vdev->dev.kobj, + &dev_attr_obppath.attr); + + return vdev; +} + +static void walk_tree(struct mdesc_handle *hp, u64 n, struct vio_dev *parent) +{ + u64 a; + + mdesc_for_each_arc(a, hp, n, MDESC_ARC_TYPE_FWD) { + struct vio_dev *vdev; + u64 target; + + target = mdesc_arc_target(hp, a); + vdev = vio_create_one(hp, target, &parent->dev); + if (vdev) + walk_tree(hp, target, vdev); + } +} + +static void create_devices(struct mdesc_handle *hp, u64 root) +{ + u64 mp; + + root_vdev = vio_create_one(hp, root, NULL); + if (!root_vdev) { + printk(KERN_ERR "VIO: Coult not create root device.\n"); + return; + } + + walk_tree(hp, root, root_vdev); + + /* Domain services is odd as it doesn't sit underneath the + * channel-devices node, so we plug it in manually. + */ + mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "domain-services"); + if (mp != MDESC_NODE_NULL) { + struct vio_dev *parent = vio_create_one(hp, mp, + &root_vdev->dev); + + if (parent) + walk_tree(hp, mp, parent); + } +} + +const char *channel_devices_node = "channel-devices"; +const char *channel_devices_compat = "SUNW,sun4v-channel-devices"; +const char *cfg_handle_prop = "cfg-handle"; + +static int __init vio_init(void) +{ + struct mdesc_handle *hp; + const char *compat; + const u64 *cfg_handle; + int err, len; + u64 root; + + err = bus_register(&vio_bus_type); + if (err) { + printk(KERN_ERR "VIO: Could not register bus type err=%d\n", + err); + return err; + } + + hp = mdesc_grab(); + if (!hp) + return 0; + + root = mdesc_node_by_name(hp, MDESC_NODE_NULL, channel_devices_node); + if (root == MDESC_NODE_NULL) { + printk(KERN_INFO "VIO: No channel-devices MDESC node.\n"); + mdesc_release(hp); + return 0; + } + + cdev_node = of_find_node_by_name(NULL, "channel-devices"); + err = -ENODEV; + if (!cdev_node) { + printk(KERN_INFO "VIO: No channel-devices OBP node.\n"); + goto out_release; + } + + compat = mdesc_get_property(hp, root, "compatible", &len); + if (!compat) { + printk(KERN_ERR "VIO: Channel devices lacks compatible " + "property\n"); + goto out_release; + } + if (!find_in_proplist(compat, channel_devices_compat, len)) { + printk(KERN_ERR "VIO: Channel devices node lacks (%s) " + "compat entry.\n", channel_devices_compat); + goto out_release; + } + + cfg_handle = mdesc_get_property(hp, root, cfg_handle_prop, NULL); + if (!cfg_handle) { + printk(KERN_ERR "VIO: Channel devices lacks %s property\n", + cfg_handle_prop); + goto out_release; + } + + cdev_cfg_handle = *cfg_handle; + + create_devices(hp, root); + + mdesc_release(hp); + + return 0; + +out_release: + mdesc_release(hp); + return err; +} + +postcore_initcall(vio_init); diff --git a/arch/sparc64/kernel/viohs.c b/arch/sparc64/kernel/viohs.c new file mode 100644 index 00000000000..15613add45d --- /dev/null +++ b/arch/sparc64/kernel/viohs.c @@ -0,0 +1,792 @@ +/* viohs.c: LDOM Virtual I/O handshake helper layer. + * + * Copyright (C) 2007 David S. Miller <davem@davemloft.net> + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/delay.h> +#include <linux/sched.h> +#include <linux/slab.h> + +#include <asm/ldc.h> +#include <asm/vio.h> + +int vio_ldc_send(struct vio_driver_state *vio, void *data, int len) +{ + int err, limit = 1000; + + err = -EINVAL; + while (limit-- > 0) { + err = ldc_write(vio->lp, data, len); + if (!err || (err != -EAGAIN)) + break; + udelay(1); + } + + return err; +} +EXPORT_SYMBOL(vio_ldc_send); + +static int send_ctrl(struct vio_driver_state *vio, + struct vio_msg_tag *tag, int len) +{ + tag->sid = vio_send_sid(vio); + return vio_ldc_send(vio, tag, len); +} + +static void init_tag(struct vio_msg_tag *tag, u8 type, u8 stype, u16 stype_env) +{ + tag->type = type; + tag->stype = stype; + tag->stype_env = stype_env; +} + +static int send_version(struct vio_driver_state *vio, u16 major, u16 minor) +{ + struct vio_ver_info pkt; + + vio->_local_sid = (u32) sched_clock(); + + memset(&pkt, 0, sizeof(pkt)); + init_tag(&pkt.tag, VIO_TYPE_CTRL, VIO_SUBTYPE_INFO, VIO_VER_INFO); + pkt.major = major; + pkt.minor = minor; + pkt.dev_class = vio->dev_class; + + viodbg(HS, "SEND VERSION INFO maj[%u] min[%u] devclass[%u]\n", + major, minor, vio->dev_class); + + return send_ctrl(vio, &pkt.tag, sizeof(pkt)); +} + +static int start_handshake(struct vio_driver_state *vio) +{ + int err; + + viodbg(HS, "START HANDSHAKE\n"); + + vio->hs_state = VIO_HS_INVALID; + + err = send_version(vio, + vio->ver_table[0].major, + vio->ver_table[0].minor); + if (err < 0) + return err; + + return 0; +} + +void vio_link_state_change(struct vio_driver_state *vio, int event) +{ + if (event == LDC_EVENT_UP) { + vio->hs_state = VIO_HS_INVALID; + + switch (vio->dev_class) { + case VDEV_NETWORK: + case VDEV_NETWORK_SWITCH: + vio->dr_state = (VIO_DR_STATE_TXREQ | + VIO_DR_STATE_RXREQ); + break; + + case VDEV_DISK: + vio->dr_state = VIO_DR_STATE_TXREQ; + break; + case VDEV_DISK_SERVER: + vio->dr_state = VIO_DR_STATE_RXREQ; + break; + } + start_handshake(vio); + } +} +EXPORT_SYMBOL(vio_link_state_change); + +static int handshake_failure(struct vio_driver_state *vio) +{ + struct vio_dring_state *dr; + + /* XXX Put policy here... Perhaps start a timer to fire + * XXX in 100 ms, which will bring the link up and retry + * XXX the handshake. + */ + + viodbg(HS, "HANDSHAKE FAILURE\n"); + + vio->dr_state &= ~(VIO_DR_STATE_TXREG | + VIO_DR_STATE_RXREG); + + dr = &vio->drings[VIO_DRIVER_RX_RING]; + memset(dr, 0, sizeof(*dr)); + + kfree(vio->desc_buf); + vio->desc_buf = NULL; + vio->desc_buf_len = 0; + + vio->hs_state = VIO_HS_INVALID; + + return -ECONNRESET; +} + +static int process_unknown(struct vio_driver_state *vio, void *arg) +{ + struct vio_msg_tag *pkt = arg; + + viodbg(HS, "UNKNOWN CONTROL [%02x:%02x:%04x:%08x]\n", + pkt->type, pkt->stype, pkt->stype_env, pkt->sid); + + printk(KERN_ERR "vio: ID[%lu] Resetting connection.\n", + vio->vdev->channel_id); + + ldc_disconnect(vio->lp); + + return -ECONNRESET; +} + +static int send_dreg(struct vio_driver_state *vio) +{ + struct vio_dring_state *dr = &vio->drings[VIO_DRIVER_TX_RING]; + union { + struct vio_dring_register pkt; + char all[sizeof(struct vio_dring_register) + + (sizeof(struct ldc_trans_cookie) * + dr->ncookies)]; + } u; + int i; + + memset(&u, 0, sizeof(u)); + init_tag(&u.pkt.tag, VIO_TYPE_CTRL, VIO_SUBTYPE_INFO, VIO_DRING_REG); + u.pkt.dring_ident = 0; + u.pkt.num_descr = dr->num_entries; + u.pkt.descr_size = dr->entry_size; + u.pkt.options = VIO_TX_DRING; + u.pkt.num_cookies = dr->ncookies; + + viodbg(HS, "SEND DRING_REG INFO ndesc[%u] dsz[%u] opt[0x%x] " + "ncookies[%u]\n", + u.pkt.num_descr, u.pkt.descr_size, u.pkt.options, + u.pkt.num_cookies); + + for (i = 0; i < dr->ncookies; i++) { + u.pkt.cookies[i] = dr->cookies[i]; + + viodbg(HS, "DRING COOKIE(%d) [%016llx:%016llx]\n", + i, + (unsigned long long) u.pkt.cookies[i].cookie_addr, + (unsigned long long) u.pkt.cookies[i].cookie_size); + } + + return send_ctrl(vio, &u.pkt.tag, sizeof(u)); +} + +static int send_rdx(struct vio_driver_state *vio) +{ + struct vio_rdx pkt; + + memset(&pkt, 0, sizeof(pkt)); + + init_tag(&pkt.tag, VIO_TYPE_CTRL, VIO_SUBTYPE_INFO, VIO_RDX); + + viodbg(HS, "SEND RDX INFO\n"); + + return send_ctrl(vio, &pkt.tag, sizeof(pkt)); +} + +static int send_attr(struct vio_driver_state *vio) +{ + return vio->ops->send_attr(vio); +} + +static struct vio_version *find_by_major(struct vio_driver_state *vio, + u16 major) +{ + struct vio_version *ret = NULL; + int i; + + for (i = 0; i < vio->ver_table_entries; i++) { + struct vio_version *v = &vio->ver_table[i]; + if (v->major <= major) { + ret = v; + break; + } + } + return ret; +} + +static int process_ver_info(struct vio_driver_state *vio, + struct vio_ver_info *pkt) +{ + struct vio_version *vap; + int err; + + viodbg(HS, "GOT VERSION INFO maj[%u] min[%u] devclass[%u]\n", + pkt->major, pkt->minor, pkt->dev_class); + + if (vio->hs_state != VIO_HS_INVALID) { + /* XXX Perhaps invoke start_handshake? XXX */ + memset(&vio->ver, 0, sizeof(vio->ver)); + vio->hs_state = VIO_HS_INVALID; + } + + vap = find_by_major(vio, pkt->major); + + vio->_peer_sid = pkt->tag.sid; + + if (!vap) { + pkt->tag.stype = VIO_SUBTYPE_NACK; + pkt->major = 0; + pkt->minor = 0; + viodbg(HS, "SEND VERSION NACK maj[0] min[0]\n"); + err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); + } else if (vap->major != pkt->major) { + pkt->tag.stype = VIO_SUBTYPE_NACK; + pkt->major = vap->major; + pkt->minor = vap->minor; + viodbg(HS, "SEND VERSION NACK maj[%u] min[%u]\n", + pkt->major, pkt->minor); + err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); + } else { + struct vio_version ver = { + .major = pkt->major, + .minor = pkt->minor, + }; + if (ver.minor > vap->minor) + ver.minor = vap->minor; + pkt->minor = ver.minor; + pkt->tag.stype = VIO_SUBTYPE_ACK; + viodbg(HS, "SEND VERSION ACK maj[%u] min[%u]\n", + pkt->major, pkt->minor); + err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); + if (err > 0) { + vio->ver = ver; + vio->hs_state = VIO_HS_GOTVERS; + } + } + if (err < 0) + return handshake_failure(vio); + + return 0; +} + +static int process_ver_ack(struct vio_driver_state *vio, + struct vio_ver_info *pkt) +{ + viodbg(HS, "GOT VERSION ACK maj[%u] min[%u] devclass[%u]\n", + pkt->major, pkt->minor, pkt->dev_class); + + if (vio->hs_state & VIO_HS_GOTVERS) { + if (vio->ver.major != pkt->major || + vio->ver.minor != pkt->minor) { + pkt->tag.stype = VIO_SUBTYPE_NACK; + (void) send_ctrl(vio, &pkt->tag, sizeof(*pkt)); + return handshake_failure(vio); + } + } else { + vio->ver.major = pkt->major; + vio->ver.minor = pkt->minor; + vio->hs_state = VIO_HS_GOTVERS; + } + + switch (vio->dev_class) { + case VDEV_NETWORK: + case VDEV_DISK: + if (send_attr(vio) < 0) + return handshake_failure(vio); + break; + + default: + break; + } + + return 0; +} + +static int process_ver_nack(struct vio_driver_state *vio, + struct vio_ver_info *pkt) +{ + struct vio_version *nver; + + viodbg(HS, "GOT VERSION NACK maj[%u] min[%u] devclass[%u]\n", + pkt->major, pkt->minor, pkt->dev_class); + + if ((pkt->major == 0 && pkt->minor == 0) || + !(nver = find_by_major(vio, pkt->major))) + return handshake_failure(vio); + + if (send_version(vio, nver->major, nver->minor) < 0) + return handshake_failure(vio); + + return 0; +} + +static int process_ver(struct vio_driver_state *vio, struct vio_ver_info *pkt) +{ + switch (pkt->tag.stype) { + case VIO_SUBTYPE_INFO: + return process_ver_info(vio, pkt); + + case VIO_SUBTYPE_ACK: + return process_ver_ack(vio, pkt); + + case VIO_SUBTYPE_NACK: + return process_ver_nack(vio, pkt); + + default: + return handshake_failure(vio); + }; +} + +static int process_attr(struct vio_driver_state *vio, void *pkt) +{ + int err; + + if (!(vio->hs_state & VIO_HS_GOTVERS)) + return handshake_failure(vio); + + err = vio->ops->handle_attr(vio, pkt); + if (err < 0) { + return handshake_failure(vio); + } else { + vio->hs_state |= VIO_HS_GOT_ATTR; + + if ((vio->dr_state & VIO_DR_STATE_TXREQ) && + !(vio->hs_state & VIO_HS_SENT_DREG)) { + if (send_dreg(vio) < 0) + return handshake_failure(vio); + + vio->hs_state |= VIO_HS_SENT_DREG; + } + } + return 0; +} + +static int all_drings_registered(struct vio_driver_state *vio) +{ + int need_rx, need_tx; + + need_rx = (vio->dr_state & VIO_DR_STATE_RXREQ); + need_tx = (vio->dr_state & VIO_DR_STATE_TXREQ); + + if (need_rx && + !(vio->dr_state & VIO_DR_STATE_RXREG)) + return 0; + + if (need_tx && + !(vio->dr_state & VIO_DR_STATE_TXREG)) + return 0; + + return 1; +} + +static int process_dreg_info(struct vio_driver_state *vio, + struct vio_dring_register *pkt) +{ + struct vio_dring_state *dr; + int i, len; + + viodbg(HS, "GOT DRING_REG INFO ident[%llx] " + "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n", + (unsigned long long) pkt->dring_ident, + pkt->num_descr, pkt->descr_size, pkt->options, + pkt->num_cookies); + + if (!(vio->dr_state & VIO_DR_STATE_RXREQ)) + goto send_nack; + + if (vio->dr_state & VIO_DR_STATE_RXREG) + goto send_nack; + + vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC); + if (!vio->desc_buf) + goto send_nack; + + vio->desc_buf_len = pkt->descr_size; + + dr = &vio->drings[VIO_DRIVER_RX_RING]; + + dr->num_entries = pkt->num_descr; + dr->entry_size = pkt->descr_size; + dr->ncookies = pkt->num_cookies; + for (i = 0; i < dr->ncookies; i++) { + dr->cookies[i] = pkt->cookies[i]; + + viodbg(HS, "DRING COOKIE(%d) [%016llx:%016llx]\n", + i, + (unsigned long long) + pkt->cookies[i].cookie_addr, + (unsigned long long) + pkt->cookies[i].cookie_size); + } + + pkt->tag.stype = VIO_SUBTYPE_ACK; + pkt->dring_ident = ++dr->ident; + + viodbg(HS, "SEND DRING_REG ACK ident[%llx]\n", + (unsigned long long) pkt->dring_ident); + + len = (sizeof(*pkt) + + (dr->ncookies * sizeof(struct ldc_trans_cookie))); + if (send_ctrl(vio, &pkt->tag, len) < 0) + goto send_nack; + + vio->dr_state |= VIO_DR_STATE_RXREG; + + return 0; + +send_nack: + pkt->tag.stype = VIO_SUBTYPE_NACK; + viodbg(HS, "SEND DRING_REG NACK\n"); + (void) send_ctrl(vio, &pkt->tag, sizeof(*pkt)); + + return handshake_failure(vio); +} + +static int process_dreg_ack(struct vio_driver_state *vio, + struct vio_dring_register *pkt) +{ + struct vio_dring_state *dr; + + viodbg(HS, "GOT DRING_REG ACK ident[%llx] " + "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n", + (unsigned long long) pkt->dring_ident, + pkt->num_descr, pkt->descr_size, pkt->options, + pkt->num_cookies); + + dr = &vio->drings[VIO_DRIVER_TX_RING]; + + if (!(vio->dr_state & VIO_DR_STATE_TXREQ)) + return handshake_failure(vio); + + dr->ident = pkt->dring_ident; + vio->dr_state |= VIO_DR_STATE_TXREG; + + if (all_drings_registered(vio)) { + if (send_rdx(vio) < 0) + return handshake_failure(vio); + vio->hs_state = VIO_HS_SENT_RDX; + } + return 0; +} + +static int process_dreg_nack(struct vio_driver_state *vio, + struct vio_dring_register *pkt) +{ + viodbg(HS, "GOT DRING_REG NACK ident[%llx] " + "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n", + (unsigned long long) pkt->dring_ident, + pkt->num_descr, pkt->descr_size, pkt->options, + pkt->num_cookies); + + return handshake_failure(vio); +} + +static int process_dreg(struct vio_driver_state *vio, + struct vio_dring_register *pkt) +{ + if (!(vio->hs_state & VIO_HS_GOTVERS)) + return handshake_failure(vio); + + switch (pkt->tag.stype) { + case VIO_SUBTYPE_INFO: + return process_dreg_info(vio, pkt); + + case VIO_SUBTYPE_ACK: + return process_dreg_ack(vio, pkt); + + case VIO_SUBTYPE_NACK: + return process_dreg_nack(vio, pkt); + + default: + return handshake_failure(vio); + } +} + +static int process_dunreg(struct vio_driver_state *vio, + struct vio_dring_unregister *pkt) +{ + struct vio_dring_state *dr = &vio->drings[VIO_DRIVER_RX_RING]; + + viodbg(HS, "GOT DRING_UNREG\n"); + + if (pkt->dring_ident != dr->ident) + return 0; + + vio->dr_state &= ~VIO_DR_STATE_RXREG; + + memset(dr, 0, sizeof(*dr)); + + kfree(vio->desc_buf); + vio->desc_buf = NULL; + vio->desc_buf_len = 0; + + return 0; +} + +static int process_rdx_info(struct vio_driver_state *vio, struct vio_rdx *pkt) +{ + viodbg(HS, "GOT RDX INFO\n"); + + pkt->tag.stype = VIO_SUBTYPE_ACK; + viodbg(HS, "SEND RDX ACK\n"); + if (send_ctrl(vio, &pkt->tag, sizeof(*pkt)) < 0) + return handshake_failure(vio); + + vio->hs_state |= VIO_HS_SENT_RDX_ACK; + return 0; +} + +static int process_rdx_ack(struct vio_driver_state *vio, struct vio_rdx *pkt) +{ + viodbg(HS, "GOT RDX ACK\n"); + + if (!(vio->hs_state & VIO_HS_SENT_RDX)) + return handshake_failure(vio); + + vio->hs_state |= VIO_HS_GOT_RDX_ACK; + return 0; +} + +static int process_rdx_nack(struct vio_driver_state *vio, struct vio_rdx *pkt) +{ + viodbg(HS, "GOT RDX NACK\n"); + + return handshake_failure(vio); +} + +static int process_rdx(struct vio_driver_state *vio, struct vio_rdx *pkt) +{ + if (!all_drings_registered(vio)) + handshake_failure(vio); + + switch (pkt->tag.stype) { + case VIO_SUBTYPE_INFO: + return process_rdx_info(vio, pkt); + + case VIO_SUBTYPE_ACK: + return process_rdx_ack(vio, pkt); + + case VIO_SUBTYPE_NACK: + return process_rdx_nack(vio, pkt); + + default: + return handshake_failure(vio); + } +} + +int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt) +{ + struct vio_msg_tag *tag = pkt; + u8 prev_state = vio->hs_state; + int err; + + switch (tag->stype_env) { + case VIO_VER_INFO: + err = process_ver(vio, pkt); + break; + + case VIO_ATTR_INFO: + err = process_attr(vio, pkt); + break; + + case VIO_DRING_REG: + err = process_dreg(vio, pkt); + break; + + case VIO_DRING_UNREG: + err = process_dunreg(vio, pkt); + break; + + case VIO_RDX: + err = process_rdx(vio, pkt); + break; + + default: + err = process_unknown(vio, pkt); + break; + } + if (!err && + vio->hs_state != prev_state && + (vio->hs_state & VIO_HS_COMPLETE)) + vio->ops->handshake_complete(vio); + + return err; +} +EXPORT_SYMBOL(vio_control_pkt_engine); + +void vio_conn_reset(struct vio_driver_state *vio) +{ +} +EXPORT_SYMBOL(vio_conn_reset); + +/* The issue is that the Solaris virtual disk server just mirrors the + * SID values it gets from the client peer. So we work around that + * here in vio_{validate,send}_sid() so that the drivers don't need + * to be aware of this crap. + */ +int vio_validate_sid(struct vio_driver_state *vio, struct vio_msg_tag *tp) +{ + u32 sid; + + /* Always let VERSION+INFO packets through unchecked, they + * define the new SID. + */ + if (tp->type == VIO_TYPE_CTRL && + tp->stype == VIO_SUBTYPE_INFO && + tp->stype_env == VIO_VER_INFO) + return 0; + + /* Ok, now figure out which SID to use. */ + switch (vio->dev_class) { + case VDEV_NETWORK: + case VDEV_NETWORK_SWITCH: + case VDEV_DISK_SERVER: + default: + sid = vio->_peer_sid; + break; + + case VDEV_DISK: + sid = vio->_local_sid; + break; + } + + if (sid == tp->sid) + return 0; + viodbg(DATA, "BAD SID tag->sid[%08x] peer_sid[%08x] local_sid[%08x]\n", + tp->sid, vio->_peer_sid, vio->_local_sid); + return -EINVAL; +} +EXPORT_SYMBOL(vio_validate_sid); + +u32 vio_send_sid(struct vio_driver_state *vio) +{ + switch (vio->dev_class) { + case VDEV_NETWORK: + case VDEV_NETWORK_SWITCH: + case VDEV_DISK: + default: + return vio->_local_sid; + + case VDEV_DISK_SERVER: + return vio->_peer_sid; + } +} +EXPORT_SYMBOL(vio_send_sid); + +extern int vio_ldc_alloc(struct vio_driver_state *vio, + struct ldc_channel_config *base_cfg, + void *event_arg) +{ + struct ldc_channel_config cfg = *base_cfg; + struct ldc_channel *lp; + + cfg.tx_irq = vio->vdev->tx_irq; + cfg.rx_irq = vio->vdev->rx_irq; + + lp = ldc_alloc(vio->vdev->channel_id, &cfg, event_arg); + if (IS_ERR(lp)) + return PTR_ERR(lp); + + vio->lp = lp; + + return 0; +} +EXPORT_SYMBOL(vio_ldc_alloc); + +void vio_ldc_free(struct vio_driver_state *vio) +{ + ldc_free(vio->lp); + vio->lp = NULL; + + kfree(vio->desc_buf); + vio->desc_buf = NULL; + vio->desc_buf_len = 0; +} +EXPORT_SYMBOL(vio_ldc_free); + +void vio_port_up(struct vio_driver_state *vio) +{ + unsigned long flags; + int err, state; + + spin_lock_irqsave(&vio->lock, flags); + + state = ldc_state(vio->lp); + + err = 0; + if (state == LDC_STATE_INIT) { + err = ldc_bind(vio->lp, vio->name); + if (err) + printk(KERN_WARNING "%s: Port %lu bind failed, " + "err=%d\n", + vio->name, vio->vdev->channel_id, err); + } + + if (!err) { + err = ldc_connect(vio->lp); + if (err) + printk(KERN_WARNING "%s: Port %lu connect failed, " + "err=%d\n", + vio->name, vio->vdev->channel_id, err); + } + if (err) { + unsigned long expires = jiffies + HZ; + + expires = round_jiffies(expires); + mod_timer(&vio->timer, expires); + } + + spin_unlock_irqrestore(&vio->lock, flags); +} +EXPORT_SYMBOL(vio_port_up); + +static void vio_port_timer(unsigned long _arg) +{ + struct vio_driver_state *vio = (struct vio_driver_state *) _arg; + + vio_port_up(vio); +} + +int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev, + u8 dev_class, struct vio_version *ver_table, + int ver_table_size, struct vio_driver_ops *ops, + char *name) +{ + switch (dev_class) { + case VDEV_NETWORK: + case VDEV_NETWORK_SWITCH: + case VDEV_DISK: + case VDEV_DISK_SERVER: + break; + + default: + return -EINVAL; + } + + if (!ops->send_attr || + !ops->handle_attr || + !ops->handshake_complete) + return -EINVAL; + + if (!ver_table || ver_table_size < 0) + return -EINVAL; + + if (!name) + return -EINVAL; + + spin_lock_init(&vio->lock); + + vio->name = name; + + vio->dev_class = dev_class; + vio->vdev = vdev; + + vio->ver_table = ver_table; + vio->ver_table_entries = ver_table_size; + + vio->ops = ops; + + setup_timer(&vio->timer, vio_port_timer, (unsigned long) vio); + + return 0; +} +EXPORT_SYMBOL(vio_driver_init); diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile index 4a725d8985f..c4a6d6e7d03 100644 --- a/arch/sparc64/lib/Makefile +++ b/arch/sparc64/lib/Makefile @@ -14,6 +14,6 @@ lib-y := PeeCeeI.o copy_page.o clear_page.o strlen.o strncmp.o \ NGmemcpy.o NGcopy_from_user.o NGcopy_to_user.o NGpatch.o \ NGpage.o NGbzero.o \ copy_in_user.o user_fixup.o memmove.o \ - mcount.o ipcsum.o rwsem.o xor.o delay.o + mcount.o ipcsum.o rwsem.o xor.o obj-y += iomap.o diff --git a/arch/sparc64/lib/delay.c b/arch/sparc64/lib/delay.c deleted file mode 100644 index fb27e54a03e..00000000000 --- a/arch/sparc64/lib/delay.c +++ /dev/null @@ -1,46 +0,0 @@ -/* delay.c: Delay loops for sparc64 - * - * Copyright (C) 2004, 2006 David S. Miller <davem@davemloft.net> - * - * Based heavily upon x86 variant which is: - * Copyright (C) 1993 Linus Torvalds - * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> - */ - -#include <linux/delay.h> -#include <asm/timer.h> - -void __delay(unsigned long loops) -{ - unsigned long bclock, now; - - bclock = tick_ops->get_tick(); - do { - now = tick_ops->get_tick(); - } while ((now-bclock) < loops); -} - -/* We used to multiply by HZ after shifting down by 32 bits - * but that runs into problems for higher values of HZ and - * slow cpus. - */ -void __const_udelay(unsigned long n) -{ - n *= 4; - - n *= (cpu_data(raw_smp_processor_id()).udelay_val * (HZ/4)); - n >>= 32; - - __delay(n + 1); -} - -void __udelay(unsigned long n) -{ - __const_udelay(n * 0x10c7UL); -} - - -void __ndelay(unsigned long n) -{ - __const_udelay(n * 0x5UL); -} diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c index f3e0c14e9ee..33c5b7da31e 100644 --- a/arch/sparc64/prom/misc.c +++ b/arch/sparc64/prom/misc.c @@ -14,6 +14,7 @@ #include <asm/openprom.h> #include <asm/oplib.h> #include <asm/system.h> +#include <asm/ldc.h> int prom_service_exists(const char *service_name) { @@ -37,6 +38,10 @@ void prom_sun4v_guest_soft_state(void) /* Reset and reboot the machine with the command 'bcommand'. */ void prom_reboot(const char *bcommand) { +#ifdef CONFIG_SUN_LDOMS + if (ldom_domaining_enabled) + ldom_reboot(bcommand); +#endif p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) | P1275_INOUT(1, 0), bcommand); } @@ -91,6 +96,10 @@ void prom_cmdline(void) */ void prom_halt(void) { +#ifdef CONFIG_SUN_LDOMS + if (ldom_domaining_enabled) + ldom_power_off(); +#endif again: p1275_cmd("exit", P1275_INOUT(0, 0)); goto again; /* PROM is out to get me -DaveM */ @@ -98,6 +107,10 @@ again: void prom_halt_power_off(void) { +#ifdef CONFIG_SUN_LDOMS + if (ldom_domaining_enabled) + ldom_power_off(); +#endif p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0)); /* if nothing else helps, we just halt */ diff --git a/arch/sparc64/prom/p1275.c b/arch/sparc64/prom/p1275.c index 2b32c489860..7fcccc0e19c 100644 --- a/arch/sparc64/prom/p1275.c +++ b/arch/sparc64/prom/p1275.c @@ -16,6 +16,7 @@ #include <asm/system.h> #include <asm/spitfire.h> #include <asm/pstate.h> +#include <asm/ldc.h> struct { long prom_callback; /* 0x00 */ diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c index 500f05e2cfc..17b7ecfe7ca 100644 --- a/arch/sparc64/prom/tree.c +++ b/arch/sparc64/prom/tree.c @@ -13,6 +13,7 @@ #include <asm/openprom.h> #include <asm/oplib.h> +#include <asm/ldc.h> /* Return the child of node 'node' or zero if no this node has no * direct descendent. @@ -261,9 +262,17 @@ int prom_node_has_property(int node, const char *prop) int prom_setprop(int node, const char *pname, char *value, int size) { - if(size == 0) return 0; - if((pname == 0) || (value == 0)) return 0; + if (size == 0) + return 0; + if ((pname == 0) || (value == 0)) + return 0; +#ifdef CONFIG_SUN_LDOMS + if (ldom_domaining_enabled) { + ldom_set_var(pname, value); + return 0; + } +#endif return p1275_cmd ("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)| P1275_ARG(2,P1275_ARG_IN_BUF)| P1275_INOUT(4, 1), diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug index 09c1aca6339..c86f5eb29fd 100644 --- a/arch/um/Kconfig.debug +++ b/arch/um/Kconfig.debug @@ -47,4 +47,13 @@ config GCOV If you're involved in UML kernel development and want to use gcov, say Y. If you're unsure, say N. +config DEBUG_STACK_USAGE + bool "Stack utilization instrumentation" + default N + help + Track the maximum kernel stack usage - this will look at each + kernel stack at process exit and log it if it's the deepest + stack seen so far. + + This option will slow down process creation and destruction somewhat. endmenu diff --git a/arch/um/config.release b/arch/um/config.release deleted file mode 100644 index fc68bcb9294..00000000000 --- a/arch/um/config.release +++ /dev/null @@ -1,333 +0,0 @@ -# -# Automatically generated make config: don't edit -# -CONFIG_USERMODE=y -# CONFIG_ISA is not set -# CONFIG_SBUS is not set -# CONFIG_PCI is not set -CONFIG_UID16=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# General Setup -# -CONFIG_STDIO_CONSOLE=y -CONFIG_NET=y -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -CONFIG_BINFMT_AOUT=y -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=y -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 -CONFIG_SSL=y -CONFIG_HOSTFS=y -CONFIG_MCONSOLE=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_HOST_2G_2G is not set -# CONFIG_UML_SMP is not set -# CONFIG_SMP is not set -CONFIG_CON_ZERO_CHAN="fd:0,fd:1" -CONFIG_CON_CHAN="xterm" -CONFIG_SSL_CHAN="pty" -CONFIG_NEST_LEVEL=0 -CONFIG_KERNEL_HALF_GIGS=1 - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_KMOD=y - -# -# Devices -# -CONFIG_BLK_DEV_UBD=y -# CONFIG_BLK_DEV_UBD_SYNC is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_NBD=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_MMAPPER is not set -CONFIG_UML_SOUND=y -CONFIG_SOUND=y -CONFIG_HOSTAUDIO=y -# CONFIG_UML_WATCHDOG is not set -# CONFIG_TTY_LOG is not set -CONFIG_FD_CHAN=y -# CONFIG_NULL_CHAN is not set -CONFIG_PORT_CHAN=y -CONFIG_PTY_CHAN=y -CONFIG_TTY_CHAN=y -CONFIG_XTERM_CHAN=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network device support -# -CONFIG_UML_NET=y -CONFIG_UML_NET_ETHERTAP=y -CONFIG_UML_NET_TUNTAP=y -CONFIG_UML_NET_SLIP=y -CONFIG_UML_NET_DAEMON=y -CONFIG_UML_NET_MCAST=y -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -CONFIG_DUMMY=y -CONFIG_BONDING=m -CONFIG_EQUALIZER=m -CONFIG_TUN=y -# CONFIG_ETHERTAP is not set - -# -# Ethernet (10 or 100Mbit) -# -# CONFIG_NET_ETHERNET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_PLIP=m -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -# CONFIG_PPP_FILTER is not set -# CONFIG_PPP_ASYNC is not set -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPPOE=m -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLIP_SMART=y -# CONFIG_SLIP_MODE_SLIP6 is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -CONFIG_SHAPER=m - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# File systems -# -CONFIG_QUOTA=y -CONFIG_AUTOFS_FS=m -CONFIG_AUTOFS4_FS=m -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -CONFIG_ADFS_FS=m -# CONFIG_ADFS_FS_RW is not set -CONFIG_AFFS_FS=m -CONFIG_HFS_FS=m -CONFIG_BFS_FS=m -CONFIG_EXT3_FS=y -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_UMSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_EFS_FS=m -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=m -CONFIG_TMPFS=y -CONFIG_RAMFS=m -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -CONFIG_MINIX_FS=m -CONFIG_VXFS_FS=m -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -CONFIG_HPFS_FS=m -CONFIG_PROC_FS=y -CONFIG_DEVFS_FS=y -CONFIG_DEVFS_MOUNT=y -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -CONFIG_QNX4FS_FS=m -# CONFIG_QNX4FS_RW is not set -CONFIG_ROMFS_FS=m -CONFIG_EXT2_FS=y -CONFIG_SYSV_FS=m -CONFIG_UDF_FS=m -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_ROOT_NFS is not set -CONFIG_NFSD=y -CONFIG_NFSD_V3=y -CONFIG_SUNRPC=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -# CONFIG_SMB_FS is not set -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -# CONFIG_ZISOFS_FS is not set -CONFIG_ZLIB_FS_INFLATE=m - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_SMB_NLS is not set -CONFIG_NLS=y - -# -# Native Language Support -# -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Kernel hacking -# -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_PT_PROXY is not set -# CONFIG_GPROF is not set -# CONFIG_GCOV is not set diff --git a/arch/um/defconfig b/arch/um/defconfig index a54d0efecae..a25cd25d55d 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -189,7 +189,7 @@ CONFIG_XTERM_CHAN=y # CONFIG_NOCONFIG_CHAN is not set CONFIG_CON_ZERO_CHAN="fd:0,fd:1" CONFIG_CON_CHAN="xterm" -CONFIG_SSL_CHAN="pty" +CONFIG_SSL_CHAN="pts" CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -527,3 +527,4 @@ CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_GPROF is not set # CONFIG_GCOV is not set +# CONFIG_DEBUG_STACK_USAGE is not set diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 3aa35161176..368d3e97dfd 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -203,22 +203,37 @@ void chan_enable_winch(struct list_head *chans, struct tty_struct *tty) } } -void enable_chan(struct line *line) +int enable_chan(struct line *line) { struct list_head *ele; struct chan *chan; + int err; list_for_each(ele, &line->chan_list){ chan = list_entry(ele, struct chan, list); - if(open_one_chan(chan)) + err = open_one_chan(chan); + if (err) { + if (chan->primary) + goto out_close; + continue; + } if(chan->enabled) continue; - line_setup_irq(chan->fd, chan->input, chan->output, line, - chan); + err = line_setup_irq(chan->fd, chan->input, chan->output, line, + chan); + if (err) + goto out_close; + chan->enabled = 1; } + + return 0; + + out_close: + close_chan(&line->chan_list, 0); + return err; } /* Items are added in IRQ context, when free_irq can't be called, and diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 13f0bf852b2..4d438f36ea2 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -51,19 +51,21 @@ error: /* * UML SIGWINCH handling * - * The point of this is to handle SIGWINCH on consoles which have host ttys and - * relay them inside UML to whatever might be running on the console and cares - * about the window size (since SIGWINCH notifies about terminal size changes). + * The point of this is to handle SIGWINCH on consoles which have host + * ttys and relay them inside UML to whatever might be running on the + * console and cares about the window size (since SIGWINCH notifies + * about terminal size changes). * - * So, we have a separate thread for each host tty attached to a UML device - * (side-issue - I'm annoyed that one thread can't have multiple controlling - * ttys for purposed of handling SIGWINCH, but I imagine there are other reasons - * that doesn't make any sense). + * So, we have a separate thread for each host tty attached to a UML + * device (side-issue - I'm annoyed that one thread can't have + * multiple controlling ttys for the purpose of handling SIGWINCH, but + * I imagine there are other reasons that doesn't make any sense). * - * SIGWINCH can't be received synchronously, so you have to set up to receive it - * as a signal. That being the case, if you are going to wait for it, it is - * convenient to sit in sigsuspend() and wait for the signal to bounce you out of - * it (see below for how we make sure to exit only on SIGWINCH). + * SIGWINCH can't be received synchronously, so you have to set up to + * receive it as a signal. That being the case, if you are going to + * wait for it, it is convenient to sit in sigsuspend() and wait for + * the signal to bounce you out of it (see below for how we make sure + * to exit only on SIGWINCH). */ static void winch_handler(int sig) @@ -112,7 +114,8 @@ static int winch_thread(void *arg) err = os_new_tty_pgrp(pty_fd, os_getpid()); if(err < 0){ - printk("winch_thread : new_tty_pgrp failed, err = %d\n", -err); + printk("winch_thread : new_tty_pgrp failed on fd %d, " + "err = %d\n", pty_fd, -err); exit(1); } @@ -126,8 +129,9 @@ static int winch_thread(void *arg) "err = %d\n", -count); while(1){ - /* This will be interrupted by SIGWINCH only, since other signals - * are blocked.*/ + /* This will be interrupted by SIGWINCH only, since + * other signals are blocked. + */ sigsuspend(&sigs); count = os_write_file(pipe_fd, &c, sizeof(c)); @@ -137,10 +141,10 @@ static int winch_thread(void *arg) } } -static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) +static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out, + unsigned long *stack_out) { struct winch_data data; - unsigned long stack; int fds[2], n, err; char c; @@ -153,9 +157,11 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) data = ((struct winch_data) { .pty_fd = fd, .pipe_fd = fds[1] } ); /* CLONE_FILES so this thread doesn't hold open files which are open - * now, but later closed. This is a problem with /dev/net/tun. + * now, but later closed in a different thread. This is a + * problem with /dev/net/tun, which if held open by this + * thread, prevents the TUN/TAP device from being reused. */ - err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0); + err = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out); if(err < 0){ printk("fork of winch_thread failed - errno = %d\n", -err); goto out_close; @@ -170,7 +176,13 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) err = -EINVAL; goto out_close; } - return err ; + + if (os_set_fd_block(*fd_out, 0)) { + printk("winch_tramp: failed to set thread_fd non-blocking.\n"); + goto out_close; + } + + return err; out_close: os_close_file(fds[1]); @@ -181,25 +193,25 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) void register_winch(int fd, struct tty_struct *tty) { - int pid, thread, thread_fd = -1; - int count; + unsigned long stack; + int pid, thread, count, thread_fd = -1; char c = 1; if(!isatty(fd)) return; pid = tcgetpgrp(fd); - if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, - tty) && (pid == -1)){ - thread = winch_tramp(fd, tty, &thread_fd); - if(thread > 0){ - register_winch_irq(thread_fd, fd, thread, tty); - - count = os_write_file(thread_fd, &c, sizeof(c)); - if(count != sizeof(c)) - printk("register_winch : failed to write " - "synchronization byte, err = %d\n", - -count); - } + if (!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, tty) && + (pid == -1)) { + thread = winch_tramp(fd, tty, &thread_fd, &stack); + if (thread < 0) + return; + + register_winch_irq(thread_fd, fd, thread, tty, stack); + + count = os_write_file(thread_fd, &c, sizeof(c)); + if(count != sizeof(c)) + printk("register_winch : failed to write " + "synchronization byte, err = %d\n", -count); } } diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index 15453845d2b..ca8c9e11a39 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -8,7 +8,7 @@ static inline void *cow_malloc(int size) { - return um_kmalloc(size); + return kmalloc(size, UM_GFP_KERNEL); } static inline void cow_free(void *ptr) diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index b869e389968..8d2008f0668 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -35,7 +35,7 @@ static struct sockaddr_un *new_addr(void *name, int len) { struct sockaddr_un *sun; - sun = um_kmalloc(sizeof(struct sockaddr_un)); + sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL); if(sun == NULL){ printk("new_addr: allocation of sockaddr_un failed\n"); return NULL; @@ -83,7 +83,7 @@ static int connect_to_switch(struct daemon_data *pri) goto out_close; } - sun = um_kmalloc(sizeof(struct sockaddr_un)); + sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL); if(sun == NULL){ printk("new_addr: allocation of sockaddr_un failed\n"); err = -ENOMEM; diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c index 7f083ec47a4..39c01ffd45c 100644 --- a/arch/um/drivers/fd.c +++ b/arch/um/drivers/fd.c @@ -37,7 +37,7 @@ static void *fd_init(char *str, int device, const struct chan_opts *opts) printk("fd_init : couldn't parse file descriptor '%s'\n", str); return(NULL); } - data = um_kmalloc(sizeof(*data)); + data = kmalloc(sizeof(*data), UM_GFP_KERNEL); if(data == NULL) return(NULL); *data = ((struct fd_chan) { .fd = n, .raw = opts->raw }); diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index 5eeecf8917c..1171790f742 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -68,7 +68,7 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) args = pid_args; } - pid = run_helper(pre_exec, &data, args, NULL); + pid = run_helper(pre_exec, &data, args); os_close_file(out_fds[0]); os_close_file(in_fds[1]); diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 4bd40bb43ec..3e0b68e297f 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -454,7 +454,10 @@ int line_open(struct line *lines, struct tty_struct *tty) tty->driver_data = line; line->tty = tty; - enable_chan(line); + err = enable_chan(line); + if (err) + return err; + INIT_DELAYED_WORK(&line->task, line_timer_cb); if(!line->sigio){ @@ -746,8 +749,24 @@ struct winch { int tty_fd; int pid; struct tty_struct *tty; + unsigned long stack; }; +static void free_winch(struct winch *winch, int free_irq_ok) +{ + list_del(&winch->list); + + if (winch->pid != -1) + os_kill_process(winch->pid, 1); + if (winch->fd != -1) + os_close_file(winch->fd); + if (winch->stack != 0) + free_stack(winch->stack, 0); + if (free_irq_ok) + free_irq(WINCH_IRQ, winch); + kfree(winch); +} + static irqreturn_t winch_interrupt(int irq, void *data) { struct winch *winch = data; @@ -764,12 +783,13 @@ static irqreturn_t winch_interrupt(int irq, void *data) "errno = %d\n", -err); printk("fd %d is losing SIGWINCH support\n", winch->tty_fd); + free_winch(winch, 0); return IRQ_HANDLED; } goto out; } } - tty = winch->tty; + tty = winch->tty; if (tty != NULL) { line = tty->driver_data; chan_window_size(&line->chan_list, &tty->winsize.ws_row, @@ -782,43 +802,44 @@ static irqreturn_t winch_interrupt(int irq, void *data) return IRQ_HANDLED; } -void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty) +void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, + unsigned long stack) { struct winch *winch; winch = kmalloc(sizeof(*winch), GFP_KERNEL); if (winch == NULL) { printk("register_winch_irq - kmalloc failed\n"); - return; + goto cleanup; } *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list), .fd = fd, .tty_fd = tty_fd, .pid = pid, - .tty = tty }); + .tty = tty, + .stack = stack }); + + if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, + IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, + "winch", winch) < 0) { + printk("register_winch_irq - failed to register IRQ\n"); + goto out_free; + } spin_lock(&winch_handler_lock); list_add(&winch->list, &winch_handlers); spin_unlock(&winch_handler_lock); - if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, - IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, - "winch", winch) < 0) - printk("register_winch_irq - failed to register IRQ\n"); -} - -static void free_winch(struct winch *winch) -{ - list_del(&winch->list); - - if(winch->pid != -1) - os_kill_process(winch->pid, 1); - if(winch->fd != -1) - os_close_file(winch->fd); + return; - free_irq(WINCH_IRQ, winch); + out_free: kfree(winch); + cleanup: + os_kill_process(pid, 1); + os_close_file(fd); + if (stack != 0) + free_stack(stack, 0); } static void unregister_winch(struct tty_struct *tty) @@ -831,7 +852,7 @@ static void unregister_winch(struct tty_struct *tty) list_for_each(ele, &winch_handlers){ winch = list_entry(ele, struct winch, list); if(winch->tty == tty){ - free_winch(winch); + free_winch(winch, 1); break; } } @@ -847,7 +868,7 @@ static void winch_cleanup(void) list_for_each_safe(ele, next, &winch_handlers){ winch = list_entry(ele, struct winch, list); - free_winch(winch); + free_winch(winch, 1); } spin_unlock(&winch_handler_lock); diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index d319db16d4e..236a3dfc297 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -30,7 +30,7 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port) { struct sockaddr_in *sin; - sin = um_kmalloc(sizeof(struct sockaddr_in)); + sin = kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL); if(sin == NULL){ printk("new_addr: allocation of sockaddr_in failed\n"); return NULL; diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index 62e5ad63181..f31e71546e5 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c @@ -86,8 +86,9 @@ int mconsole_get_request(int fd, struct mc_request *req) int len; req->originlen = sizeof(req->origin); - req->len = recvfrom(fd, &req->request, sizeof(req->request), 0, - (struct sockaddr *) req->origin, &req->originlen); + req->len = recvfrom(fd, &req->request, sizeof(req->request), + MSG_DONTWAIT, (struct sockaddr *) req->origin, + &req->originlen); if (req->len < 0) return 0; diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 3503cff867c..da946e3e1bf 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -187,7 +187,7 @@ static int change_tramp(char **argv, char *output, int output_len) } pe_data.close_me = fds[0]; pe_data.stdout = fds[1]; - pid = run_helper(change_pre_exec, &pe_data, argv, NULL); + pid = run_helper(change_pre_exec, &pe_data, argv); if (pid > 0) /* Avoid hang as we won't get data in failure case. */ read_output(fds[0], output, output_len); @@ -217,7 +217,7 @@ static void change(char *dev, char *what, unsigned char *addr, netmask[2], netmask[3]); output_len = UM_KERN_PAGE_SIZE; - output = um_kmalloc(output_len); + output = kmalloc(output_len, UM_GFP_KERNEL); if(output == NULL) printk("change : failed to allocate output buffer\n"); diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c index 3f6357d24be..c799b00012c 100644 --- a/arch/um/drivers/port_user.c +++ b/arch/um/drivers/port_user.c @@ -50,7 +50,7 @@ static void *port_init(char *str, int device, const struct chan_opts *opts) if(kern_data == NULL) return NULL; - data = um_kmalloc(sizeof(*data)); + data = kmalloc(sizeof(*data), UM_GFP_KERNEL); if(data == NULL) goto err; @@ -188,7 +188,7 @@ int port_connection(int fd, int *socket, int *pid_out) { .sock_fd = new, .pipe_fd = socket[1] }); - err = run_helper(port_pre_exec, &data, argv, NULL); + err = run_helper(port_pre_exec, &data, argv); if(err < 0) goto out_shutdown; diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index df4976c9eef..1e3fd619a83 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -7,12 +7,14 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> +#include <fcntl.h> #include <errno.h> #include <termios.h> +#include <sys/stat.h> #include "chan_user.h" -#include "user.h" -#include "kern_util.h" #include "os.h" +#include "user.h" +#include "kern_constants.h" #include "um_malloc.h" struct pty_chan { @@ -27,12 +29,14 @@ static void *pty_chan_init(char *str, int device, const struct chan_opts *opts) { struct pty_chan *data; - data = um_kmalloc(sizeof(*data)); - if(data == NULL) return(NULL); + data = kmalloc(sizeof(*data), UM_GFP_KERNEL); + if (data == NULL) + return NULL; + *data = ((struct pty_chan) { .announce = opts->announce, .dev = device, .raw = opts->raw }); - return(data); + return data; } static int pts_open(int input, int output, int primary, void *d, @@ -43,31 +47,35 @@ static int pts_open(int input, int output, int primary, void *d, int fd, err; fd = get_pty(); - if(fd < 0){ + if (fd < 0) { err = -errno; - printk("open_pts : Failed to open pts\n"); + printk(UM_KERN_ERR "open_pts : Failed to open pts\n"); return err; } - if(data->raw){ + + if (data->raw) { CATCH_EINTR(err = tcgetattr(fd, &data->tt)); - if(err) - return(err); + if (err) + return err; err = raw(fd); - if(err) - return(err); + if (err) + return err; } dev = ptsname(fd); sprintf(data->dev_name, "%s", dev); *dev_out = data->dev_name; + if (data->announce) (*data->announce)(dev, data->dev); - return(fd); + + return fd; } static int getmaster(char *line) { + struct stat buf; char *pty, *bank, *cp; int master, err; @@ -75,24 +83,29 @@ static int getmaster(char *line) for (bank = "pqrs"; *bank; bank++) { line[strlen("/dev/pty")] = *bank; *pty = '0'; - if (os_stat_file(line, NULL) < 0) + /* Did we hit the end ? */ + if ((stat(line, &buf) < 0) && (errno == ENOENT)) break; + for (cp = "0123456789abcdef"; *cp; cp++) { *pty = *cp; - master = os_open_file(line, of_rdwr(OPENFLAGS()), 0); + master = open(line, O_RDWR); if (master >= 0) { char *tp = &line[strlen("/dev/")]; /* verify slave side is usable */ *tp = 't'; - err = os_access(line, OS_ACC_RW_OK); + err = access(line, R_OK | W_OK); *tp = 'p'; - if(err == 0) return(master); - (void) os_close_file(master); + if(!err) + return master; + close(master); } } } - return(-1); + + printk(UM_KERN_ERR "getmaster - no usable host pty devices\n"); + return -ENOENT; } static int pty_open(int input, int output, int primary, void *d, @@ -103,20 +116,22 @@ static int pty_open(int input, int output, int primary, void *d, char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx"; fd = getmaster(dev); - if(fd < 0) - return(-errno); + if (fd < 0) + return fd; if(data->raw){ err = raw(fd); - if(err) - return(err); + if (err) + return err; } - if(data->announce) (*data->announce)(dev, data->dev); + if (data->announce) + (*data->announce)(dev, data->dev); sprintf(data->dev_name, "%s", dev); *dev_out = data->dev_name; - return(fd); + + return fd; } const struct chan_ops pty_ops = { @@ -144,14 +159,3 @@ const struct chan_ops pts_ops = { .free = generic_free, .winch = 0, }; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 78f0e515da8..c0b73c28cff 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -85,13 +85,13 @@ static int slip_tramp(char **argv, int fd) pe_data.stdin = fd; pe_data.stdout = fds[1]; pe_data.close_me = fds[0]; - err = run_helper(slip_pre_exec, &pe_data, argv, NULL); + err = run_helper(slip_pre_exec, &pe_data, argv); if(err < 0) goto out_close; pid = err; output_len = UM_KERN_PAGE_SIZE; - output = um_kmalloc(output_len); + output = kmalloc(output_len, UM_GFP_KERNEL); if(output == NULL){ printk("slip_tramp : failed to allocate output buffer\n"); os_kill_process(pid, 1); diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index 39f889fe994..0e462f64f22 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c @@ -42,7 +42,7 @@ static int slirp_tramp(char **argv, int fd) pe_data.stdin = fd; pe_data.stdout = fd; - pid = run_helper(slirp_pre_exec, &pe_data, argv, NULL); + pid = run_helper(slirp_pre_exec, &pe_data, argv); return(pid); } diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index fd09ad9e9c0..875d60d0c6a 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -42,8 +42,6 @@ static struct chan_opts opts = { .announce = ssl_announce, .xterm_title = "Serial Line #%d", .raw = 1, - .tramp_stack = 0, - .in_kernel = 1, }; static int ssl_config(char *str, char **error_out); @@ -99,7 +97,13 @@ static int ssl_remove(int n, char **error_out) static int ssl_open(struct tty_struct *tty, struct file *filp) { - return line_open(serial_lines, tty); + int err = line_open(serial_lines, tty); + + if (err) + printk(KERN_ERR "Failed to open serial line %d, err = %d\n", + tty->index, err); + + return err; } #if 0 diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 2bb4193ac1a..656036e90b1 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c @@ -46,8 +46,6 @@ static struct chan_opts opts = { .announce = stdio_announce, .xterm_title = "Virtual Console #%d", .raw = 1, - .tramp_stack = 0, - .in_kernel = 1, }; static int con_config(char *str, char **error_out); @@ -101,7 +99,12 @@ static int con_remove(int n, char **error_out) static int con_open(struct tty_struct *tty, struct file *filp) { - return line_open(vts, tty); + int err = line_open(vts, tty); + if (err) + printk(KERN_ERR "Failed to open console %d, err = %d\n", + tty->index, err); + + return err; } /* Set in an initcall, checked in an exitcall */ diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c index c07d0d56278..a9f87e19c5b 100644 --- a/arch/um/drivers/tty.c +++ b/arch/um/drivers/tty.c @@ -29,7 +29,7 @@ static void *tty_chan_init(char *str, int device, const struct chan_opts *opts) } str++; - data = um_kmalloc(sizeof(*data)); + data = kmalloc(sizeof(*data), UM_GFP_KERNEL); if(data == NULL) return NULL; *data = ((struct tty_chan) { .dev = str, diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 2e09f162c42..fc27f6c72b4 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -712,6 +712,8 @@ static int ubd_add(int n, char **error_out) ubd_dev->queue->queuedata = ubd_dev; blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG); + if(ubd_dev->cow.file != NULL) + blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long)); err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); if(err){ *error_out = "Failed to register device"; @@ -1083,7 +1085,7 @@ static void do_ubd_request(request_queue_t *q) { struct io_thread_req *io_req; struct request *req; - int n; + int n, last_sectors; while(1){ struct ubd *dev = q->queuedata; @@ -1099,9 +1101,11 @@ static void do_ubd_request(request_queue_t *q) } req = dev->request; + last_sectors = 0; while(dev->start_sg < dev->end_sg){ struct scatterlist *sg = &dev->sg[dev->start_sg]; + req->sector += last_sectors; io_req = kmalloc(sizeof(struct io_thread_req), GFP_ATOMIC); if(io_req == NULL){ @@ -1113,6 +1117,7 @@ static void do_ubd_request(request_queue_t *q) (unsigned long long) req->sector << 9, sg->offset, sg->length, sg->page); + last_sectors = sg->length >> 9; n = os_write_file(thread_fd, &io_req, sizeof(struct io_thread_req *)); if(n != sizeof(struct io_thread_req *)){ @@ -1124,7 +1129,6 @@ static void do_ubd_request(request_queue_t *q) return; } - req->sector += sg->length >> 9; dev->start_sg++; } dev->end_sg = 0; diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index 4707b3f14c2..41d254bd38d 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -43,6 +43,12 @@ int start_io_thread(unsigned long sp, int *fd_out) kernel_fd = fds[0]; *fd_out = fds[1]; + err = os_set_fd_block(*fd_out, 0); + if (err) { + printk("start_io_thread - failed to set nonblocking I/O.\n"); + goto out_close; + } + pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD, NULL); if(pid < 0){ diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index 571c2b3325d..fd817e54154 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -1,22 +1,20 @@ /* - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <stdio.h> #include <stdlib.h> +#include <stdio.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <termios.h> -#include <signal.h> -#include <sched.h> -#include <sys/socket.h> -#include "kern_util.h" #include "chan_user.h" -#include "user.h" #include "os.h" +#include "init.h" +#include "user.h" #include "xterm.h" +#include "kern_constants.h" struct xterm_chan { int pid; @@ -25,25 +23,21 @@ struct xterm_chan { int device; int raw; struct termios tt; - unsigned long stack; - int direct_rcv; }; -/* Not static because it's called directly by the tt mode gdb code */ -void *xterm_init(char *str, int device, const struct chan_opts *opts) +static void *xterm_init(char *str, int device, const struct chan_opts *opts) { struct xterm_chan *data; data = malloc(sizeof(*data)); - if(data == NULL) return(NULL); - *data = ((struct xterm_chan) { .pid = -1, + if (data == NULL) + return NULL; + *data = ((struct xterm_chan) { .pid = -1, .helper_pid = -1, - .device = device, + .device = device, .title = opts->xterm_title, - .raw = opts->raw, - .stack = opts->tramp_stack, - .direct_rcv = !opts->in_kernel } ); - return(data); + .raw = opts->raw } ); + return data; } /* Only changed by xterm_setup, which is a setup */ @@ -57,16 +51,22 @@ static int __init xterm_setup(char *line, int *add) terminal_emulator = line; line = strchr(line, ','); - if(line == NULL) return(0); + if (line == NULL) + return 0; + *line++ = '\0'; - if(*line) title_switch = line; + if (*line) + title_switch = line; line = strchr(line, ','); - if(line == NULL) return(0); + if (line == NULL) + return 0; + *line++ = '\0'; - if(*line) exec_switch = line; + if (*line) + exec_switch = line; - return(0); + return 0; } __uml_setup("xterm=", xterm_setup, @@ -82,107 +82,128 @@ __uml_setup("xterm=", xterm_setup, " are 'xterm=gnome-terminal,-t,-x'.\n\n" ); -/* XXX This badly needs some cleaning up in the error paths - * Not static because it's called directly by the tt mode gdb code - */ -int xterm_open(int input, int output, int primary, void *d, +static int xterm_open(int input, int output, int primary, void *d, char **dev_out) { struct xterm_chan *data = d; - unsigned long stack; int pid, fd, new, err; char title[256], file[] = "/tmp/xterm-pipeXXXXXX"; - char *argv[] = { terminal_emulator, title_switch, title, exec_switch, + char *argv[] = { terminal_emulator, title_switch, title, exec_switch, "/usr/lib/uml/port-helper", "-uml-socket", file, NULL }; - if(os_access(argv[4], OS_ACC_X_OK) < 0) + if (access(argv[4], X_OK) < 0) argv[4] = "port-helper"; /* Check that DISPLAY is set, this doesn't guarantee the xterm * will work but w/o it we can be pretty sure it won't. */ - if (!getenv("DISPLAY")) { - printk("xterm_open: $DISPLAY not set.\n"); + if (getenv("DISPLAY") == NULL) { + printk(UM_KERN_ERR "xterm_open: $DISPLAY not set.\n"); return -ENODEV; } + /* + * This business of getting a descriptor to a temp file, + * deleting the file and closing the descriptor is just to get + * a known-unused name for the Unix socket that we really + * want. + */ fd = mkstemp(file); - if(fd < 0){ + if (fd < 0) { err = -errno; - printk("xterm_open : mkstemp failed, errno = %d\n", errno); + printk(UM_KERN_ERR "xterm_open : mkstemp failed, errno = %d\n", + errno); return err; } - if(unlink(file)){ + if (unlink(file)) { err = -errno; - printk("xterm_open : unlink failed, errno = %d\n", errno); + printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n", + errno); return err; } - os_close_file(fd); + close(fd); fd = os_create_unix_socket(file, sizeof(file), 1); - if(fd < 0){ - printk("xterm_open : create_unix_socket failed, errno = %d\n", - -fd); - return(fd); + if (fd < 0) { + printk(UM_KERN_ERR "xterm_open : create_unix_socket failed, " + "errno = %d\n", -fd); + return fd; } sprintf(title, data->title, data->device); - stack = data->stack; - pid = run_helper(NULL, NULL, argv, &stack); - if(pid < 0){ - printk("xterm_open : run_helper failed, errno = %d\n", -pid); - return(pid); + pid = run_helper(NULL, NULL, argv); + if (pid < 0) { + err = pid; + printk(UM_KERN_ERR "xterm_open : run_helper failed, " + "errno = %d\n", -err); + goto out_close1; } - if (data->direct_rcv) { - new = os_rcv_fd(fd, &data->helper_pid); - } else { - err = os_set_fd_block(fd, 0); - if(err < 0){ - printk("xterm_open : failed to set descriptor " - "non-blocking, err = %d\n", -err); - return(err); - } - new = xterm_fd(fd, &data->helper_pid); + err = os_set_fd_block(fd, 0); + if (err < 0) { + printk(UM_KERN_ERR "xterm_open : failed to set descriptor " + "non-blocking, err = %d\n", -err); + goto out_kill; } - if(new < 0){ - printk("xterm_open : os_rcv_fd failed, err = %d\n", -new); - goto out; + + new = xterm_fd(fd, &data->helper_pid); + if (new < 0) { + err = new; + printk(UM_KERN_ERR "xterm_open : os_rcv_fd failed, err = %d\n", + -err); + goto out_kill; + } + + err = os_set_fd_block(new, 0); + if (err) { + printk(UM_KERN_ERR "xterm_open : failed to set xterm " + "descriptor non-blocking, err = %d\n", -err); + goto out_close2; } CATCH_EINTR(err = tcgetattr(new, &data->tt)); - if(err){ + if (err) { new = err; - goto out; + goto out_close2; } - if(data->raw){ + if (data->raw) { err = raw(new); - if(err){ + if (err) { new = err; - goto out; + goto out_close2; } } + unlink(file); data->pid = pid; *dev_out = NULL; - out: - unlink(file); - return(new); + + return new; + + out_close2: + close(new); + out_kill: + os_kill_process(pid, 1); + out_close1: + close(fd); + + return err; } -/* Not static because it's called directly by the tt mode gdb code */ -void xterm_close(int fd, void *d) +static void xterm_close(int fd, void *d) { struct xterm_chan *data = d; - if(data->pid != -1) + if (data->pid != -1) os_kill_process(data->pid, 1); data->pid = -1; - if(data->helper_pid != -1) + + if (data->helper_pid != -1) os_kill_process(data->helper_pid, 0); data->helper_pid = -1; + os_close_file(fd); } @@ -203,14 +224,3 @@ const struct chan_ops xterm_ops = { .free = xterm_free, .winch = 1, }; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c index a4ce7058e10..b646bccef37 100644 --- a/arch/um/drivers/xterm_kern.c +++ b/arch/um/drivers/xterm_kern.c @@ -1,18 +1,14 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/errno.h" -#include "linux/slab.h" -#include "linux/signal.h" -#include "linux/interrupt.h" -#include "asm/irq.h" -#include "irq_user.h" +#include <linux/slab.h> +#include <linux/completion.h> +#include <linux/irqreturn.h> +#include <asm/irq.h> #include "irq_kern.h" -#include "kern_util.h" #include "os.h" -#include "xterm.h" struct xterm_wait { struct completion ready; @@ -27,12 +23,13 @@ static irqreturn_t xterm_interrupt(int irq, void *data) int fd; fd = os_rcv_fd(xterm->fd, &xterm->pid); - if(fd == -EAGAIN) - return(IRQ_NONE); + if (fd == -EAGAIN) + return IRQ_NONE; xterm->new_fd = fd; complete(&xterm->ready); - return(IRQ_HANDLED); + + return IRQ_HANDLED; } int xterm_fd(int socket, int *pid_out) @@ -41,22 +38,21 @@ int xterm_fd(int socket, int *pid_out) int err, ret; data = kmalloc(sizeof(*data), GFP_KERNEL); - if(data == NULL){ + if (data == NULL) { printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n"); - return(-ENOMEM); + return -ENOMEM; } /* This is a locked semaphore... */ - *data = ((struct xterm_wait) - { .fd = socket, - .pid = -1, - .new_fd = -1 }); + *data = ((struct xterm_wait) { .fd = socket, + .pid = -1, + .new_fd = -1 }); init_completion(&data->ready); - err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, + err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "xterm", data); - if (err){ + if (err) { printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " "err = %d\n", err); ret = err; @@ -76,16 +72,5 @@ int xterm_fd(int socket, int *pid_out) out: kfree(data); - return(ret); + return ret; } - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/include/chan_kern.h b/arch/um/include/chan_kern.h index c4b41bb1035..624b5100a3c 100644 --- a/arch/um/include/chan_kern.h +++ b/arch/um/include/chan_kern.h @@ -40,7 +40,7 @@ extern int console_open_chan(struct line *line, struct console *co); extern void deactivate_chan(struct list_head *chans, int irq); extern void reactivate_chan(struct list_head *chans, int irq); extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty); -extern void enable_chan(struct line *line); +extern int enable_chan(struct line *line); extern void close_chan(struct list_head *chans, int delay_free_irq); extern int chan_window_size(struct list_head *chans, unsigned short *rows_out, diff --git a/arch/um/include/chan_user.h b/arch/um/include/chan_user.h index 38f16d812e7..5a2263e05bb 100644 --- a/arch/um/include/chan_user.h +++ b/arch/um/include/chan_user.h @@ -12,8 +12,6 @@ struct chan_opts { void (*const announce)(char *dev_name, int dev); char *xterm_title; const int raw; - const unsigned long tramp_stack; - const int in_kernel; }; enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE }; @@ -44,7 +42,8 @@ extern void generic_free(void *data); struct tty_struct; extern void register_winch(int fd, struct tty_struct *tty); -extern void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty); +extern void register_winch_irq(int fd, int tty_fd, int pid, + struct tty_struct *tty, unsigned long stack); #define __channel_help(fn, prefix) \ __uml_help(fn, prefix "[0-9]*=<channel description>\n" \ diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h index 7376ee44e33..6eee343e53e 100644 --- a/arch/um/include/common-offsets.h +++ b/arch/um/include/common-offsets.h @@ -27,6 +27,9 @@ DEFINE(UM_ELFCLASS64, ELFCLASS64); DEFINE(UM_NR_CPUS, NR_CPUS); +DEFINE(UM_GFP_KERNEL, GFP_KERNEL); +DEFINE(UM_GFP_ATOMIC, GFP_ATOMIC); + /* For crypto assembler code. */ DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 4d9fb26387d..930b261ea48 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -239,11 +239,9 @@ extern unsigned long __do_user_copy(void *to, const void *from, int n, /* execvp.c */ extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); /* helper.c */ -extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, - unsigned long *stack_out); +extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv); extern int run_helper_thread(int (*proc)(void *), void *arg, - unsigned int flags, unsigned long *stack_out, - int stack_order); + unsigned int flags, unsigned long *stack_out); extern int helper_wait(int pid); diff --git a/arch/um/include/um_malloc.h b/arch/um/include/um_malloc.h index e6d7c5aa3f4..0ad17cb83d9 100644 --- a/arch/um/include/um_malloc.h +++ b/arch/um/include/um_malloc.h @@ -6,11 +6,17 @@ #ifndef __UM_MALLOC_H__ #define __UM_MALLOC_H__ -extern void *um_kmalloc(int size); -extern void *um_kmalloc_atomic(int size); +#include "kern_constants.h" + +extern void *__kmalloc(int size, int flags); +static inline void *kmalloc(int size, int flags) +{ + return __kmalloc(size, flags); +} + extern void kfree(const void *ptr); -extern void *um_vmalloc(int size); +extern void *vmalloc(unsigned long size); extern void vfree(void *ptr); #endif /* __UM_MALLOC_H__ */ diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index dba04d88b43..9870febdbea 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -30,7 +30,6 @@ #include "irq_kern.h" #include "os.h" #include "sigio.h" -#include "um_malloc.h" #include "misc_constants.h" #include "as-layout.h" diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 8d2c5496532..bfa52f206bb 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -46,7 +46,6 @@ #include "mode.h" #include "mode_kern.h" #include "choose-mode.h" -#include "um_malloc.h" /* This is a per-cpu array. A processor only modifies its entry and it only * cares about its entry, so it's OK if another processor is modifying its @@ -262,21 +261,6 @@ void dump_thread(struct pt_regs *regs, struct user *u) { } -void *um_kmalloc(int size) -{ - return kmalloc(size, GFP_KERNEL); -} - -void *um_kmalloc_atomic(int size) -{ - return kmalloc(size, GFP_ATOMIC); -} - -void *um_vmalloc(int size) -{ - return vmalloc(size); -} - int __cant_sleep(void) { return in_atomic() || irqs_disabled() || in_interrupt(); /* Is in_interrupt() really needed? */ diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 9bf944f6a1d..b126df4ea16 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -177,6 +177,7 @@ static int do_not_aio(struct aio_thread_req *req) static int aio_req_fd_r = -1; static int aio_req_fd_w = -1; static int aio_pid = -1; +static unsigned long aio_stack; static int not_aio_thread(void *arg) { @@ -212,7 +213,6 @@ static int not_aio_thread(void *arg) static int init_aio_24(void) { - unsigned long stack; int fds[2], err; err = os_pipe(fds, 1, 1); @@ -227,7 +227,7 @@ static int init_aio_24(void) goto out_close_pipe; err = run_helper_thread(not_aio_thread, NULL, - CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); + CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack); if(err < 0) goto out_close_pipe; @@ -252,7 +252,6 @@ out: #define DEFAULT_24_AIO 0 static int init_aio_26(void) { - unsigned long stack; int err; if(io_setup(256, &ctx)){ @@ -263,7 +262,7 @@ static int init_aio_26(void) } err = run_helper_thread(aio_thread, NULL, - CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); + CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack); if(err < 0) return err; @@ -365,8 +364,10 @@ __initcall(init_aio); static void exit_aio(void) { - if(aio_pid != -1) + if (aio_pid != -1) { os_kill_process(aio_pid, 1); + free_stack(aio_stack, 0); + } } __uml_exitcall(exit_aio); diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index acba3016128..61d3953c7ac 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -54,7 +54,7 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask, return; } - output = um_kmalloc(UM_KERN_PAGE_SIZE); + output = kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL); if(output == NULL) printk("etap_change : Failed to allocate output buffer\n"); read_output(fd, output, UM_KERN_PAGE_SIZE); @@ -117,7 +117,7 @@ static int etap_tramp(char *dev, char *gate, int control_me, pe_data.control_remote = control_remote; pe_data.control_me = control_me; pe_data.data_me = data_me; - pid = run_helper(etap_pre_exec, &pe_data, args, NULL); + pid = run_helper(etap_pre_exec, &pe_data, args); if(pid < 0) err = pid; @@ -166,7 +166,7 @@ static int etap_open(void *data) err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], control_fds[1], data_fds[0], data_fds[1]); output_len = UM_KERN_PAGE_SIZE; - output = um_kmalloc(output_len); + output = kmalloc(output_len, UM_GFP_KERNEL); read_output(control_fds[0], output, output_len); if(output == NULL) diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index 11a9779dc9f..f848b4ea934 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -83,7 +83,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, data.stdout = remote; data.close_me = me; - pid = run_helper(tuntap_pre_exec, &data, argv, NULL); + pid = run_helper(tuntap_pre_exec, &data, argv); if(pid < 0) return -pid; diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index 97bed16bf4c..d81af7b8587 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -44,17 +44,13 @@ static int helper_child(void *arg) /* Returns either the pid of the child process we run or -E* on failure. * XXX The alloc_stack here breaks if this is called in the tracing thread, so * we need to receive a preallocated stack (a local buffer is ok). */ -int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, - unsigned long *stack_out) +int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) { struct helper_data data; unsigned long stack, sp; int pid, fds[2], ret, n; - if ((stack_out != NULL) && (*stack_out != 0)) - stack = *stack_out; - else - stack = alloc_stack(0, __cant_sleep()); + stack = alloc_stack(0, __cant_sleep()); if (stack == 0) return -ENOMEM; @@ -76,8 +72,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, data.pre_data = pre_data; data.argv = argv; data.fd = fds[1]; - data.buf = __cant_sleep() ? um_kmalloc_atomic(PATH_MAX) : - um_kmalloc(PATH_MAX); + data.buf = __cant_sleep() ? kmalloc(PATH_MAX, UM_GFP_ATOMIC) : + kmalloc(PATH_MAX, UM_GFP_KERNEL); pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); if (pid < 0) { ret = -errno; @@ -113,22 +109,21 @@ out_close: close(fds[1]); close(fds[0]); out_free: - if ((stack_out == NULL) || (*stack_out == 0)) - free_stack(stack, 0); + free_stack(stack, 0); return ret; } int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, - unsigned long *stack_out, int stack_order) + unsigned long *stack_out) { unsigned long stack, sp; int pid, status, err; - stack = alloc_stack(stack_order, __cant_sleep()); + stack = alloc_stack(0, __cant_sleep()); if (stack == 0) return -ENOMEM; - sp = stack + (UM_KERN_PAGE_SIZE << stack_order) - sizeof(void *); + sp = stack + UM_KERN_PAGE_SIZE - sizeof(void *); pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); if (pid < 0) { err = -errno; @@ -147,7 +142,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) printk("run_helper_thread - thread returned status " "0x%x\n", status); - free_stack(stack, stack_order); + free_stack(stack, 0); } else *stack_out = stack; return pid; diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index fb510d40480..e85f4995a01 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -235,8 +235,8 @@ void *__wrap_malloc(int size) return __real_malloc(size); else if(size <= UM_KERN_PAGE_SIZE) /* finding contiguous pages can be hard*/ - ret = um_kmalloc(size); - else ret = um_vmalloc(size); + ret = kmalloc(size, UM_GFP_KERNEL); + else ret = vmalloc(size); /* glibc people insist that if malloc fails, errno should be * set by malloc as well. So we do. diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 8d4e0c6b8c9..dc03e9cccb6 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -26,6 +26,7 @@ * exitcall. */ static int write_sigio_pid = -1; +static unsigned long write_sigio_stack; /* These arrays are initialized before the sigio thread is started, and * the descriptors closed after it is killed. So, it can't see them change. @@ -104,7 +105,7 @@ static int need_poll(struct pollfds *polls, int n) if(n <= polls->size) return 0; - new = um_kmalloc_atomic(n * sizeof(struct pollfd)); + new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC); if(new == NULL){ printk("need_poll : failed to allocate new pollfds\n"); return -ENOMEM; @@ -144,8 +145,10 @@ static void update_thread(void) return; fail: /* Critical section start */ - if(write_sigio_pid != -1) + if (write_sigio_pid != -1) { os_kill_process(write_sigio_pid, 1); + free_stack(write_sigio_stack, 0); + } write_sigio_pid = -1; close(sigio_private[0]); close(sigio_private[1]); @@ -230,7 +233,7 @@ static struct pollfd *setup_initial_poll(int fd) { struct pollfd *p; - p = um_kmalloc(sizeof(struct pollfd)); + p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL); if (p == NULL) { printk("setup_initial_poll : failed to allocate poll\n"); return NULL; @@ -243,7 +246,6 @@ static struct pollfd *setup_initial_poll(int fd) static void write_sigio_workaround(void) { - unsigned long stack; struct pollfd *p; int err; int l_write_sigio_fds[2]; @@ -293,7 +295,8 @@ static void write_sigio_workaround(void) memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private)); write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, - CLONE_FILES | CLONE_VM, &stack, 0); + CLONE_FILES | CLONE_VM, + &write_sigio_stack); if (write_sigio_pid < 0) goto out_clear; @@ -356,10 +359,12 @@ out: static void sigio_cleanup(void) { - if(write_sigio_pid != -1){ - os_kill_process(write_sigio_pid, 1); - write_sigio_pid = -1; - } + if (write_sigio_pid == -1) + return; + + os_kill_process(write_sigio_pid, 1); + free_stack(write_sigio_stack, 0); + write_sigio_pid = -1; } __uml_exitcall(sigio_cleanup); diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 46c00cc429b..ba9af8d6205 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -41,7 +41,7 @@ int is_skas_winch(int pid, int fd, void *data) if(pid != os_getpgrp()) return(0); - register_winch_irq(-1, fd, -1, data); + register_winch_irq(-1, fd, -1, data, 0); return(1); } diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c index 3f33165ada6..419b2d5ff6d 100644 --- a/arch/um/os-Linux/user_syms.c +++ b/arch/um/os-Linux/user_syms.c @@ -5,7 +5,8 @@ * so I *must* declare good prototypes for them and then EXPORT them. * The kernel code uses the macro defined by include/linux/string.h, * so I undef macros; the userspace code does not include that and I - * add an EXPORT for the glibc one.*/ + * add an EXPORT for the glibc one. + */ #undef strlen #undef strstr @@ -61,12 +62,18 @@ EXPORT_SYMBOL_PROTO(dup2); EXPORT_SYMBOL_PROTO(__xstat); EXPORT_SYMBOL_PROTO(__lxstat); EXPORT_SYMBOL_PROTO(__lxstat64); +EXPORT_SYMBOL_PROTO(__fxstat64); EXPORT_SYMBOL_PROTO(lseek); EXPORT_SYMBOL_PROTO(lseek64); EXPORT_SYMBOL_PROTO(chown); +EXPORT_SYMBOL_PROTO(fchown); EXPORT_SYMBOL_PROTO(truncate); +EXPORT_SYMBOL_PROTO(ftruncate64); EXPORT_SYMBOL_PROTO(utime); +EXPORT_SYMBOL_PROTO(utimes); +EXPORT_SYMBOL_PROTO(futimes); EXPORT_SYMBOL_PROTO(chmod); +EXPORT_SYMBOL_PROTO(fchmod); EXPORT_SYMBOL_PROTO(rename); EXPORT_SYMBOL_PROTO(__xmknod); @@ -102,14 +109,3 @@ EXPORT_SYMBOL(__stack_smash_handler); extern long __guard __attribute__((weak)); EXPORT_SYMBOL(__guard); - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index 47565c3345d..782dea81943 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S @@ -526,7 +526,7 @@ ia32_sys_call_table: .quad sys_init_module .quad sys_delete_module .quad quiet_ni_syscall /* 130 get_kernel_syms */ - .quad sys_quotactl + .quad sys32_quotactl .quad sys_getpgid .quad sys_fchdir .quad quiet_ni_syscall /* bdflush */ diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 1fab487dee8..941c84baecc 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S @@ -73,7 +73,11 @@ startup_64: addq %rbp, init_level4_pgt + (511*8)(%rip) addq %rbp, level3_ident_pgt + 0(%rip) + addq %rbp, level3_kernel_pgt + (510*8)(%rip) + addq %rbp, level3_kernel_pgt + (511*8)(%rip) + + addq %rbp, level2_fixmap_pgt + (506*8)(%rip) /* Add an Identity mapping if I am above 1G */ leaq _text(%rip), %rdi @@ -314,7 +318,16 @@ NEXT_PAGE(level3_kernel_pgt) .fill 510,8,0 /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE - .fill 1,8,0 + .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE + +NEXT_PAGE(level2_fixmap_pgt) + .fill 506,8,0 + .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE + /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */ + .fill 5,8,0 + +NEXT_PAGE(level1_fixmap_pgt) + .fill 512,8,0 NEXT_PAGE(level2_ident_pgt) /* Since I easily can, map the first 1G. diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index aac1c0be54c..7fa155c394d 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -531,7 +531,7 @@ void die(const char * str, struct pt_regs * regs, long err) unsigned long flags = oops_begin(); if (!user_mode(regs)) - report_bug(regs->rip); + report_bug(regs->rip, regs); __die(str, regs, err); oops_end(flags); |