diff options
Diffstat (limited to 'arch')
720 files changed, 29597 insertions, 19097 deletions
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile index 2f283b2fb164..63104ebd1806 100644 --- a/arch/alpha/Makefile +++ b/arch/alpha/Makefile @@ -12,73 +12,22 @@ NM := $(NM) -B LDFLAGS_vmlinux := -static -N #-relax CHECKFLAGS += -D__alpha__ -m64 -cflags-y := -pipe -mno-fp-regs -ffixed-8 - -# Determine if we can use the BWX instructions with GAS. -old_gas := $(shell if $(AS) --version 2>&1 | grep 'version 2.7' > /dev/null; then echo y; else echo n; fi) - -ifeq ($(old_gas),y) -$(error The assembler '$(AS)' does not support the BWX instruction) -endif - -# Determine if GCC understands the -mcpu= option. -have_mcpu := $(call cc-option-yn, -mcpu=ev5) -have_mcpu_pca56 := $(call cc-option-yn, -mcpu=pca56) -have_mcpu_ev6 := $(call cc-option-yn, -mcpu=ev6) -have_mcpu_ev67 := $(call cc-option-yn, -mcpu=ev67) -have_msmall_data := $(call cc-option-yn, -msmall-data) - -cflags-$(have_msmall_data) += -msmall-data - -# Turn on the proper cpu optimizations. -ifeq ($(have_mcpu),y) - mcpu_done := n - # If GENERIC, make sure to turn off any instruction set extensions that - # the host compiler might have on by default. Given that EV4 and EV5 - # have the same instruction set, prefer EV5 because an EV5 schedule is - # more likely to keep an EV4 processor busy than vice-versa. - ifeq ($(CONFIG_ALPHA_GENERIC),y) - mcpu := ev5 - mcpu_done := y - endif - ifeq ($(mcpu_done)$(CONFIG_ALPHA_SX164)$(have_mcpu_pca56),nyy) - mcpu := pca56 - mcpu_done := y - endif - ifeq ($(mcpu_done)$(CONFIG_ALPHA_POLARIS)$(have_mcpu_pca56),nyy) - mcpu := pca56 - mcpu_done := y - endif - ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV4),ny) - mcpu := ev4 - mcpu_done := y - endif - ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV56),ny) - mcpu := ev56 - mcpu_done := y - endif - ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV5),ny) - mcpu := ev5 - mcpu_done := y - endif - ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV67)$(have_mcpu_ev67),nyy) - mcpu := ev67 - mcpu_done := y - endif - ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV6),ny) - ifeq ($(have_mcpu_ev6),y) - mcpu := ev6 - else - ifeq ($(have_mcpu_pca56),y) - mcpu := pca56 - else - mcpu=ev56 - endif - endif - mcpu_done := y - endif - cflags-$(mcpu_done) += -mcpu=$(mcpu) -endif +cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data + +cpuflags-$(CONFIG_ALPHA_EV67) := -mcpu=ev67 +cpuflags-$(CONFIG_ALPHA_EV6) := -mcpu=ev6 +cpuflags-$(CONFIG_ALPHA_POLARIS) := -mcpu=pca56 +cpuflags-$(CONFIG_ALPHA_SX164) := -mcpu=pca56 +cpuflags-$(CONFIG_ALPHA_EV56) := -mcpu=ev56 +cpuflags-$(CONFIG_ALPHA_EV5) := -mcpu=ev5 +cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4 +# If GENERIC, make sure to turn off any instruction set extensions that +# the host compiler might have on by default. Given that EV4 and EV5 +# have the same instruction set, prefer EV5 because an EV5 schedule is +# more likely to keep an EV4 processor busy than vice-versa. +cpuflags-$(CONFIG_ALPHA_GENERIC) := -mcpu=ev5 + +cflags-y += $(cpuflags-y) # For TSUNAMI, we must have the assembler not emulate our instructions. diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index debc8f03886c..5fc61e281ac7 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -917,15 +917,6 @@ sys_pipe: .end sys_pipe .align 4 - .globl sys_ptrace - .ent sys_ptrace -sys_ptrace: - .prologue 0 - mov $sp, $20 - jmp $31, do_sys_ptrace -.end sys_ptrace - - .align 4 .globl sys_execve .ent sys_execve sys_execve: diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c index 83a781842266..1e9ad52c460e 100644 --- a/arch/alpha/kernel/ptrace.c +++ b/arch/alpha/kernel/ptrace.c @@ -260,38 +260,12 @@ void ptrace_disable(struct task_struct *child) ptrace_cancel_bpt(child); } -asmlinkage long -do_sys_ptrace(long request, long pid, long addr, long data, - struct pt_regs *regs) +long arch_ptrace(struct task_struct *child, long request, long addr, long data) { - struct task_struct *child; unsigned long tmp; size_t copied; long ret; - lock_kernel(); - DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n", - request, pid, addr, data)); - if (request == PTRACE_TRACEME) { - ret = ptrace_traceme(); - goto out_notsk; - } - - child = ptrace_get_task_struct(pid); - if (IS_ERR(child)) { - ret = PTR_ERR(child); - goto out_notsk; - } - - if (request == PTRACE_ATTACH) { - ret = ptrace_attach(child); - goto out; - } - - ret = ptrace_check_attach(child, request == PTRACE_KILL); - if (ret < 0) - goto out; - switch (request) { /* When I and D space are separate, these will need to be fixed. */ case PTRACE_PEEKTEXT: /* read word at location addr. */ @@ -301,13 +275,13 @@ do_sys_ptrace(long request, long pid, long addr, long data, if (copied != sizeof(tmp)) break; - regs->r0 = 0; /* special return: no errors */ + force_successful_syscall_return(); ret = tmp; break; /* Read register number ADDR. */ case PTRACE_PEEKUSR: - regs->r0 = 0; /* special return: no errors */ + force_successful_syscall_return(); ret = get_reg(child, addr); DBG(DBG_MEM, ("peek $%ld->%#lx\n", addr, ret)); break; @@ -353,7 +327,7 @@ do_sys_ptrace(long request, long pid, long addr, long data, /* make sure single-step breakpoint is gone. */ ptrace_cancel_bpt(child); wake_up_process(child); - goto out; + break; case PTRACE_SINGLESTEP: /* execute single instruction. */ ret = -EIO; @@ -366,20 +340,12 @@ do_sys_ptrace(long request, long pid, long addr, long data, wake_up_process(child); /* give it a chance to run. */ ret = 0; - goto out; - - case PTRACE_DETACH: /* detach a process that was attached. */ - ret = ptrace_detach(child, data); - goto out; + break; default: ret = ptrace_request(child, request, addr, data); - goto out; + break; } - out: - put_task_struct(child); - out_notsk: - unlock_kernel(); return ret; } diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S index 7af07d3ad5f0..55c05b511f4c 100644 --- a/arch/alpha/kernel/vmlinux.lds.S +++ b/arch/alpha/kernel/vmlinux.lds.S @@ -1,4 +1,5 @@ #include <asm-generic/vmlinux.lds.h> +#include <asm/page.h> OUTPUT_FORMAT("elf64-alpha") OUTPUT_ARCH(alpha) @@ -8,138 +9,145 @@ jiffies = jiffies_64; SECTIONS { #ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS - . = 0xfffffc0000310000; + . = 0xfffffc0000310000; #else - . = 0xfffffc0001010000; + . = 0xfffffc0001010000; #endif - _text = .; /* Text and read-only data */ - .text : { + _text = .; /* Text and read-only data */ + .text : { *(.text.head) - TEXT_TEXT - SCHED_TEXT - LOCK_TEXT - *(.fixup) - *(.gnu.warning) - } :kernel - _etext = .; /* End of text section */ - - . = ALIGN(16); - __start___ex_table = .; /* Exception table */ - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - NOTES :kernel :note - .dummy : { *(.dummy) } :kernel - - RODATA - - /* Will be freed after init */ - . = ALIGN(8192); /* Init code and data */ - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - .init.data : { *(.init.data) } - - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - - . = ALIGN(8); - __initcall_start = .; - .initcall.init : { - INITCALLS - } - __initcall_end = .; + TEXT_TEXT + SCHED_TEXT + LOCK_TEXT + *(.fixup) + *(.gnu.warning) + } :kernel + _etext = .; /* End of text section */ + + /* Exception table */ + . = ALIGN(16); + __ex_table : { + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } + + NOTES :kernel :note + .dummy : { + *(.dummy) + } :kernel + + RODATA + + /* Will be freed after init */ + . = ALIGN(PAGE_SIZE); + /* Init code and data */ + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { + *(.init.data) + } + + . = ALIGN(16); + .init.setup : { + __setup_start = .; + *(.init.setup) + __setup_end = .; + } + + . = ALIGN(8); + .initcall.init : { + __initcall_start = .; + INITCALLS + __initcall_end = .; + } #ifdef CONFIG_BLK_DEV_INITRD - . = ALIGN(8192); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; + . = ALIGN(PAGE_SIZE); + .init.ramfs : { + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + } #endif - . = ALIGN(8); - .con_initcall.init : { - __con_initcall_start = .; - *(.con_initcall.init) - __con_initcall_end = .; - } - - . = ALIGN(8); - SECURITY_INIT - - PERCPU(8192) - - . = ALIGN(2*8192); - __init_end = .; - /* Freed after init ends here */ - - /* Note 2 page alignment above. */ - .data.init_thread : { *(.data.init_thread) } - - . = ALIGN(8192); - .data.page_aligned : { *(.data.page_aligned) } - - . = ALIGN(64); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - _data = .; - .data : { /* Data */ - DATA_DATA - CONSTRUCTORS - } - - .got : { *(.got) } - .sdata : { *(.sdata) } - - _edata = .; /* End of data section */ - - __bss_start = .; - .sbss : { *(.sbss) *(.scommon) } - .bss : { *(.bss) *(COMMON) } - __bss_stop = .; - - _end = .; - - /* Sections to be discarded */ - /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } - - .mdebug 0 : { *(.mdebug) } - .note 0 : { *(.note) } - .comment 0 : { *(.comment) } - - /* Stabs debugging sections */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } + . = ALIGN(8); + .con_initcall.init : { + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + } + + . = ALIGN(8); + SECURITY_INIT + + PERCPU(PAGE_SIZE) + + . = ALIGN(2 * PAGE_SIZE); + __init_end = .; + /* Freed after init ends here */ + + /* Note 2 page alignment above. */ + .data.init_thread : { + *(.data.init_thread) + } + + . = ALIGN(PAGE_SIZE); + .data.page_aligned : { + *(.data.page_aligned) + } + + . = ALIGN(64); + .data.cacheline_aligned : { + *(.data.cacheline_aligned) + } + + _data = .; + /* Data */ + .data : { + DATA_DATA + CONSTRUCTORS + } + + .got : { + *(.got) + } + .sdata : { + *(.sdata) + } + _edata = .; /* End of data section */ + + __bss_start = .; + .sbss : { + *(.sbss) + *(.scommon) + } + .bss : { + *(.bss) + *(COMMON) + } + __bss_stop = .; + _end = .; + + /* Sections to be discarded */ + /DISCARD/ : { + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + } + + .mdebug 0 : { + *(.mdebug) + } + .note 0 : { + *(.note) + } + + STABS_DEBUG + DWARF_DEBUG } diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index a0e18da594d9..25154df3055a 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c @@ -197,7 +197,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr, current->comm, current->pid); if (!user_mode(regs)) goto no_context; - do_exit(SIGKILL); + do_group_exit(SIGKILL); do_sigbus: /* Send a sigbus, regardless of whether we were in kernel diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 691aae309c8a..0a0c88d0039c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -318,6 +318,9 @@ config ARCH_KS8695 config ARCH_NS9XXX bool "NetSilicon NS9xxx" + select GENERIC_GPIO + select GENERIC_TIME + select GENERIC_CLOCKEVENTS help Say Y here if you intend to run this kernel on a NetSilicon NS9xxx System. @@ -336,14 +339,14 @@ config ARCH_PNX4008 This enables support for Philips PNX4008 mobile platform. config ARCH_PXA - bool "PXA2xx-based" + bool "PXA2xx/PXA3xx-based" depends on MMU select ARCH_MTD_XIP select GENERIC_GPIO select GENERIC_TIME select GENERIC_CLOCKEVENTS help - Support for Intel's PXA2XX processor line. + Support for Intel/Marvell's PXA2xx/PXA3xx processor line. config ARCH_RPC bool "RiscPC" @@ -486,7 +489,7 @@ source arch/arm/mm/Kconfig config IWMMXT bool "Enable iWMMXt support" depends on CPU_XSCALE || CPU_XSC3 - default y if PXA27x + default y if PXA27x || PXA3xx help Enable support for iWMMXt context switching at run time if running on a CPU that supports it. @@ -994,6 +997,10 @@ source "drivers/pnp/Kconfig" source "drivers/block/Kconfig" +# misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4 + +source "drivers/misc/Kconfig" + if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \ || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \ @@ -1029,16 +1036,16 @@ source "drivers/spi/Kconfig" source "drivers/w1/Kconfig" +source "drivers/power/Kconfig" + source "drivers/hwmon/Kconfig" -#source "drivers/l3/Kconfig" +source "drivers/ssb/Kconfig" -source "drivers/misc/Kconfig" +#source "drivers/l3/Kconfig" source "drivers/mfd/Kconfig" -source "drivers/leds/Kconfig" - source "drivers/media/Kconfig" source "drivers/video/Kconfig" @@ -1051,6 +1058,8 @@ source "drivers/usb/Kconfig" source "drivers/mmc/Kconfig" +source "drivers/leds/Kconfig" + source "drivers/rtc/Kconfig" source "drivers/dma/Kconfig" diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu index f087376748d1..901e6dff8437 100644 --- a/arch/arm/Kconfig-nommu +++ b/arch/arm/Kconfig-nommu @@ -26,7 +26,7 @@ config FLASH_SIZE default 0x00400000 config PROCESSOR_ID - hex + hex 'Hard wire the processor ID' default 0x00007700 depends on !CPU_CP15 help diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 0d450e757e0e..35e56c99ad1d 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -12,7 +12,7 @@ LDFLAGS_vmlinux :=-p --no-undefined -X CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET) -OBJCOPYFLAGS :=-O binary -R .note -R .comment -S +OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S GZFLAGS :=-9 #KBUILD_CFLAGS +=-pipe # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S index 236bbe578312..67ea99ef6521 100644 --- a/arch/arm/boot/compressed/head-xscale.S +++ b/arch/arm/boot/compressed/head-xscale.S @@ -33,10 +33,6 @@ __XScale_start: bic r0, r0, #0x1000 @ clear Icache mcr p15, 0, r0, c1, c0, 0 -#ifdef CONFIG_ARCH_LUBBOCK - mov r7, #MACH_TYPE_LUBBOCK -#endif - #ifdef CONFIG_ARCH_COTULLA_IDP mov r7, #MACH_TYPE_COTULLA_IDP #endif diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index e1289a256ce5..3d0b9fa42f84 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_SHARPSL_PM) += sharpsl_pm.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o obj-$(CONFIG_ARCH_IXP2000) += uengine.o obj-$(CONFIG_ARCH_IXP23XX) += uengine.o +obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index b36b1e8a105d..44ab0dad4035 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c @@ -263,7 +263,7 @@ map_single(struct device *dev, void *ptr, size_t size, * We don't need to sync the DMA buffer since * it was allocated via the coherent allocators. */ - consistent_sync(ptr, size, dir); + dma_cache_maint(ptr, size, dir); } return dma_addr; @@ -383,7 +383,7 @@ sync_single(struct device *dev, dma_addr_t dma_addr, size_t size, * via the coherent allocators. */ } else { - consistent_sync(dma_to_virt(dev, dma_addr), size, dir); + dma_cache_maint(dma_to_virt(dev, dma_addr), size, dir); } } diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c new file mode 100644 index 000000000000..c03de9bfd76b --- /dev/null +++ b/arch/arm/common/it8152.c @@ -0,0 +1,387 @@ +/* + * linux/arch/arm/common/it8152.c + * + * Copyright Compulab Ltd, 2002-2007 + * Mike Rapoport <mike@compulab.co.il> + * + * The DMA bouncing part is taken from arch/arm/mach-ixp4xx/common-pci.c + * (see this file for respective copyrights) + * + * Thanks to Guennadi Liakhovetski <gl@dsa-ac.de> for IRQ enumberation + * and demux code. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/ptrace.h> +#include <linux/interrupt.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/irq.h> +#include <linux/io.h> + +#include <asm/mach/pci.h> +#include <asm/hardware/it8152.h> + +#define MAX_SLOTS 21 + +static void it8152_mask_irq(unsigned int irq) +{ + if (irq >= IT8152_LD_IRQ(0)) { + __raw_writel((__raw_readl(IT8152_INTC_LDCNIMR) | + (1 << (irq - IT8152_LD_IRQ(0)))), + IT8152_INTC_LDCNIMR); + } else if (irq >= IT8152_LP_IRQ(0)) { + __raw_writel((__raw_readl(IT8152_INTC_LPCNIMR) | + (1 << (irq - IT8152_LP_IRQ(0)))), + IT8152_INTC_LPCNIMR); + } else if (irq >= IT8152_PD_IRQ(0)) { + __raw_writel((__raw_readl(IT8152_INTC_PDCNIMR) | + (1 << (irq - IT8152_PD_IRQ(0)))), + IT8152_INTC_PDCNIMR); + } +} + +static void it8152_unmask_irq(unsigned int irq) +{ + if (irq >= IT8152_LD_IRQ(0)) { + __raw_writel((__raw_readl(IT8152_INTC_LDCNIMR) & + ~(1 << (irq - IT8152_LD_IRQ(0)))), + IT8152_INTC_LDCNIMR); + } else if (irq >= IT8152_LP_IRQ(0)) { + __raw_writel((__raw_readl(IT8152_INTC_LPCNIMR) & + ~(1 << (irq - IT8152_LP_IRQ(0)))), + IT8152_INTC_LPCNIMR); + } else if (irq >= IT8152_PD_IRQ(0)) { + __raw_writel((__raw_readl(IT8152_INTC_PDCNIMR) & + ~(1 << (irq - IT8152_PD_IRQ(0)))), + IT8152_INTC_PDCNIMR); + } +} + +static inline void it8152_irq(int irq) +{ + struct irq_desc *desc; + + printk(KERN_DEBUG "===> %s: irq=%d\n", __FUNCTION__, irq); + + desc = irq_desc + irq; + desc_handle_irq(irq, desc); +} + +static struct irq_chip it8152_irq_chip = { + .name = "it8152", + .ack = it8152_mask_irq, + .mask = it8152_mask_irq, + .unmask = it8152_unmask_irq, +}; + +void it8152_init_irq(void) +{ + int irq; + + __raw_writel((0xffff), IT8152_INTC_PDCNIMR); + __raw_writel((0), IT8152_INTC_PDCNIRR); + __raw_writel((0xffff), IT8152_INTC_LPCNIMR); + __raw_writel((0), IT8152_INTC_LPCNIRR); + __raw_writel((0xffff), IT8152_INTC_LDCNIMR); + __raw_writel((0), IT8152_INTC_LDCNIRR); + + for (irq = IT8152_IRQ(0); irq <= IT8152_LAST_IRQ; irq++) { + set_irq_chip(irq, &it8152_irq_chip); + set_irq_handler(irq, handle_level_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } +} + +void it8152_irq_demux(unsigned int irq, struct irq_desc *desc) +{ + int bits_pd, bits_lp, bits_ld; + int i; + + printk(KERN_DEBUG "=> %s: irq = %d\n", __FUNCTION__, irq); + + while (1) { + /* Read all */ + bits_pd = __raw_readl(IT8152_INTC_PDCNIRR); + bits_lp = __raw_readl(IT8152_INTC_LPCNIRR); + bits_ld = __raw_readl(IT8152_INTC_LDCNIRR); + + /* Ack */ + __raw_writel((~bits_pd), IT8152_INTC_PDCNIRR); + __raw_writel((~bits_lp), IT8152_INTC_LPCNIRR); + __raw_writel((~bits_ld), IT8152_INTC_LDCNIRR); + + if (!(bits_ld | bits_lp | bits_pd)) { + /* Re-read to guarantee, that there was a moment of + time, when they all three were 0. */ + bits_pd = __raw_readl(IT8152_INTC_PDCNIRR); + bits_lp = __raw_readl(IT8152_INTC_LPCNIRR); + if (!(bits_ld | bits_lp | bits_pd)) + return; + } + + bits_pd &= ((1 << IT8152_PD_IRQ_COUNT) - 1); + while (bits_pd) { + i = __ffs(bits_pd); + it8152_irq(IT8152_PD_IRQ(i)); + bits_pd &= ~(1 << i); + } + + bits_lp &= ((1 << IT8152_LP_IRQ_COUNT) - 1); + while (bits_lp) { + i = __ffs(bits_pd); + it8152_irq(IT8152_LP_IRQ(i)); + bits_lp &= ~(1 << i); + } + + bits_ld &= ((1 << IT8152_LD_IRQ_COUNT) - 1); + while (bits_ld) { + i = __ffs(bits_pd); + it8152_irq(IT8152_LD_IRQ(i)); + bits_ld &= ~(1 << i); + } + } +} + +/* mapping for on-chip devices */ +int __init it8152_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if ((dev->vendor == PCI_VENDOR_ID_ITE) && + (dev->device == PCI_DEVICE_ID_ITE_8152)) { + if ((dev->class >> 8) == PCI_CLASS_MULTIMEDIA_AUDIO) + return IT8152_AUDIO_INT; + if ((dev->class >> 8) == PCI_CLASS_SERIAL_USB) + return IT8152_USB_INT; + if ((dev->class >> 8) == PCI_CLASS_SYSTEM_DMA) + return IT8152_CDMA_INT; + } + + return 0; +} + +static unsigned long it8152_pci_dev_base_address(struct pci_bus *bus, + unsigned int devfn) +{ + unsigned long addr = 0; + + if (bus->number == 0) { + if (devfn < PCI_DEVFN(MAX_SLOTS, 0)) + addr = (devfn << 8); + } else + addr = (bus->number << 16) | (devfn << 8); + + return addr; +} + +static int it8152_pci_read_config(struct pci_bus *bus, + unsigned int devfn, int where, + int size, u32 *value) +{ + unsigned long addr = it8152_pci_dev_base_address(bus, devfn); + u32 v; + int shift; + + shift = (where & 3); + + __raw_writel((addr + where), IT8152_PCI_CFG_ADDR); + v = (__raw_readl(IT8152_PCI_CFG_DATA) >> (8 * (shift))); + + *value = v; + + return PCIBIOS_SUCCESSFUL; +} + +static int it8152_pci_write_config(struct pci_bus *bus, + unsigned int devfn, int where, + int size, u32 value) +{ + unsigned long addr = it8152_pci_dev_base_address(bus, devfn); + u32 v, vtemp, mask = 0; + int shift; + + if (size == 1) + mask = 0xff; + if (size == 2) + mask = 0xffff; + + shift = (where & 3); + + __raw_writel((addr + where), IT8152_PCI_CFG_ADDR); + vtemp = __raw_readl(IT8152_PCI_CFG_DATA); + + if (mask) + vtemp &= ~(mask << (8 * shift)); + else + vtemp = 0; + + v = (value << (8 * shift)); + __raw_writel((addr + where), IT8152_PCI_CFG_ADDR); + __raw_writel((v | vtemp), IT8152_PCI_CFG_DATA); + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops it8152_ops = { + .read = it8152_pci_read_config, + .write = it8152_pci_write_config, +}; + +static struct resource it8152_io = { + .name = "IT8152 PCI I/O region", + .flags = IORESOURCE_IO, +}; + +static struct resource it8152_mem = { + .name = "IT8152 PCI memory region", + .start = 0x10000000, + .end = 0x13e00000, + .flags = IORESOURCE_MEM, +}; + +/* + * The following functions are needed for DMA bouncing. + * ITE8152 chip can addrees up to 64MByte, so all the devices + * connected to ITE8152 (PCI and USB) should have limited DMA window + */ + +/* + * Setup DMA mask to 64MB on devices connected to ITE8152. Ignore all + * other devices. + */ +static int it8152_pci_platform_notify(struct device *dev) +{ + if (dev->bus == &pci_bus_type) { + if (dev->dma_mask) + *dev->dma_mask = (SZ_64M - 1) | PHYS_OFFSET; + dev->coherent_dma_mask = (SZ_64M - 1) | PHYS_OFFSET; + dmabounce_register_dev(dev, 2048, 4096); + } + return 0; +} + +static int it8152_pci_platform_notify_remove(struct device *dev) +{ + if (dev->bus == &pci_bus_type) + dmabounce_unregister_dev(dev); + + return 0; +} + +int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) +{ + dev_dbg(dev, "%s: dma_addr %08x, size %08x\n", + __FUNCTION__, dma_addr, size); + return (dev->bus == &pci_bus_type) && + ((dma_addr + size - PHYS_OFFSET) >= SZ_64M); +} + +/* + * We override these so we properly do dmabounce otherwise drivers + * are able to set the dma_mask to 0xffffffff and we can no longer + * trap bounces. :( + * + * We just return true on everyhing except for < 64MB in which case + * we will fail miseralby and die since we can't handle that case. + */ +int pci_set_dma_mask(struct pci_dev *dev, u64 mask) +{ + printk(KERN_DEBUG "%s: %s %llx\n", + __FUNCTION__, dev->dev.bus_id, mask); + if (mask >= PHYS_OFFSET + SZ_64M - 1) + return 0; + + return -EIO; +} + +int +pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) +{ + printk(KERN_DEBUG "%s: %s %llx\n", + __FUNCTION__, dev->dev.bus_id, mask); + if (mask >= PHYS_OFFSET + SZ_64M - 1) + return 0; + + return -EIO; +} + +int __init it8152_pci_setup(int nr, struct pci_sys_data *sys) +{ + it8152_io.start = IT8152_IO_BASE + 0x12000; + it8152_io.end = IT8152_IO_BASE + 0x12000 + 0x100000; + + sys->mem_offset = 0x10000000; + sys->io_offset = IT8152_IO_BASE; + + if (request_resource(&ioport_resource, &it8152_io)) { + printk(KERN_ERR "PCI: unable to allocate IO region\n"); + goto err0; + } + if (request_resource(&iomem_resource, &it8152_mem)) { + printk(KERN_ERR "PCI: unable to allocate memory region\n"); + goto err1; + } + + sys->resource[0] = &it8152_io; + sys->resource[1] = &it8152_mem; + + if (platform_notify || platform_notify_remove) { + printk(KERN_ERR "PCI: Can't use platform_notify\n"); + goto err2; + } + + platform_notify = it8152_pci_platform_notify; + platform_notify_remove = it8152_pci_platform_notify_remove; + + return 1; + +err2: + release_resource(&it8152_io); +err1: + release_resource(&it8152_mem); +err0: + return -EBUSY; +} + +/* + * If we set up a device for bus mastering, we need to check the latency + * timer as we don't have even crappy BIOSes to set it properly. + * The implementation is from arch/i386/pci/i386.c + */ +unsigned int pcibios_max_latency = 255; + +void pcibios_set_master(struct pci_dev *dev) +{ + u8 lat; + + /* no need to update on-chip OHCI controller */ + if ((dev->vendor == PCI_VENDOR_ID_ITE) && + (dev->device == PCI_DEVICE_ID_ITE_8152) && + ((dev->class >> 8) == PCI_CLASS_SERIAL_USB)) + return; + + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) + lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; + else if (lat > pcibios_max_latency) + lat = pcibios_max_latency; + else + return; + printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", + pci_name(dev), lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); +} + + +struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_bus(nr, &it8152_ops, sys); +} + diff --git a/arch/arm/configs/cm_x270_defconfig b/arch/arm/configs/cm_x270_defconfig new file mode 100644 index 000000000000..5cab08397ae7 --- /dev/null +++ b/arch/arm/configs/cm_x270_defconfig @@ -0,0 +1,1410 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.22 +# Wed Jul 18 14:11:48 2007 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +# CONFIG_GENERIC_CLOCKEVENTS is not set +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_SYSFS_DEPRECATED=y +# 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 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=y +CONFIG_ANON_INODES=y +# CONFIG_EPOLL is not set +# CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set +# CONFIG_EVENTFD is not set +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 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_PNX4008 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +CONFIG_DMABOUNCE=y + +# +# Intel PXA2xx Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +# CONFIG_MACH_LOGICPD_PXA270 is not set +# CONFIG_MACH_MAINSTONE is not set +# CONFIG_ARCH_PXA_IDP is not set +# CONFIG_PXA_SHARPSL is not set +# CONFIG_MACH_TRIZEPS4 is not set +CONFIG_MACH_ARMCORE=y +CONFIG_PXA27x=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_OUTER_CACHE is not set +CONFIG_IWMMXT=y +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_SYSCALL=y +CONFIG_PCI_HOST_ITE8152=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCI_DEBUG is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_TICK_ONESHOT is not set +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +CONFIG_HZ=100 +# CONFIG_AEABI is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_LEGACY is not set +# CONFIG_PM_DEBUG is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set +# CONFIG_APM_EMULATION 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 is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# 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 is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +# CONFIG_IEEE80211_CRYPT_TKIP is not set +# CONFIG_IEEE80211_SOFTMAC is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_SHARP_SL is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_H1900 is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_SHARPSL is not set +# CONFIG_MTD_NAND_CAFE is not set +CONFIG_MTD_NAND_CM_X270=m +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# 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=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=12000 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_IDE=m +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# 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_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_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 is not set +# 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 +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 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 +CONFIG_DM9000=y +# CONFIG_SMC911X is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 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 is not set +CONFIG_8139TOO=m +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# 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 is not set +# CONFIG_SC92031 is not set +CONFIG_NETDEV_1000=y +# 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_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 + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET 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 +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# 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=y +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +CONFIG_TOUCHSCREEN_UCB1400=m +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_PXA=y +CONFIG_SERIAL_PXA_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 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=m +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# 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 +# CONFIG_W1 is not set +# CONFIG_HWMON is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# LED devices +# +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +CONFIG_LEDS_CM_X270=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_TIMER is not set +# CONFIG_LEDS_TRIGGER_IDE_DISK is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y +# CONFIG_USB_DABUSB 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=y +# CONFIG_FIRMWARE_EDID is not set +# 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 +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# 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_PXA=y +# CONFIG_FB_PXA_PARAMETERS is not set +CONFIG_FB_MBX=m +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_AC97_POWER_SAVE is not set + +# +# ALSA ARM devices +# +CONFIG_SND_PXA2XX_PCM=m +CONFIG_SND_PXA2XX_AC97=m + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set + +# +# System on Chip audio support +# +# CONFIG_SND_SOC is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_PERSIST is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_PXA=m +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_TIFM_SD is not set + +# +# 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 + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set +CONFIG_RTC_DRV_V3020=y + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_SA1100=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_OCFS2_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_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 is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +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_JFFS2_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 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=y +# CONFIG_SMB_NLS_DEFAULT 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 + +# +# 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 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_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 is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DETECT_SOFTLOCKUP is not set +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER 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 is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# 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_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_MANAGER=m +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# 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=m +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_DES is not set +# 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=m +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_ARC4=m +# 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 +CONFIG_CRYPTO_HW=y + +# +# 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_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig index b0efd4ca9935..b8a78ab49cdd 100644 --- a/arch/arm/configs/omap_h2_1610_defconfig +++ b/arch/arm/configs/omap_h2_1610_defconfig @@ -1,41 +1,58 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17 -# Thu Jun 29 15:25:18 2006 +# Linux kernel version: 2.6.23-rc6 +# Mon Sep 17 14:21:45 2007 # CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # 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_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +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_UID16=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -44,27 +61,30 @@ 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 -# CONFIG_SLOB is not set - -# -# 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 is not set - -# -# Block layer -# +CONFIG_BLOCK=y +# CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -86,7 +106,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91RM9200 is not set +# CONFIG_ARCH_AT91 is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set @@ -96,11 +116,16 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_IOP3XX is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set # CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_MXC is not set # CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set @@ -108,6 +133,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_S3C2410 is not set # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set CONFIG_ARCH_OMAP=y # @@ -124,6 +150,7 @@ CONFIG_ARCH_OMAP1=y CONFIG_OMAP_MUX=y # CONFIG_OMAP_MUX_DEBUG is not set CONFIG_OMAP_MUX_WARNINGS=y +CONFIG_OMAP_MCBSP=y # CONFIG_OMAP_MPU_TIMER is not set CONFIG_OMAP_32K_TIMER=y CONFIG_OMAP_32K_TIMER_HZ=128 @@ -162,6 +189,14 @@ CONFIG_OMAP_ARM_192MHZ=y # CONFIG_OMAP_ARM_30MHZ is not set # +# Boot options +# + +# +# Power management +# + +# # Processor Type # CONFIG_CPU_32=y @@ -171,6 +206,8 @@ CONFIG_CPU_ABRT_EV5TJ=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_COPY_V4WB=y CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y # # Processor Features @@ -180,10 +217,13 @@ CONFIG_ARM_THUMB=y # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_DCACHE_WRITETHROUGH is not set # CONFIG_CPU_CACHE_ROUND_ROBIN is not set +# CONFIG_OUTER_CACHE is not set # # Bus support # +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set # # PCCARD (PCMCIA/CardBus) support @@ -193,10 +233,13 @@ CONFIG_ARM_THUMB=y # # Kernel Features # +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT=y -CONFIG_NO_IDLE_HZ=y CONFIG_HZ=128 -# CONFIG_AEABI is not set +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -206,6 +249,10 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y # CONFIG_LEDS is not set CONFIG_ALIGNMENT_TRAP=y @@ -216,6 +263,7 @@ CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="mem=32M console=ttyS0,115200n8 root=0801 ro init=/bin/sh" # CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set # # CPU Frequency scaling @@ -251,7 +299,6 @@ CONFIG_FPE_NWFPE=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_AOUT=y # CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set # # Power management options @@ -259,7 +306,10 @@ CONFIG_BINFMT_AOUT=y CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set -# CONFIG_APM is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_UP_POSSIBLE=y +CONFIG_SUSPEND=y +# CONFIG_APM_EMULATION is not set # # Networking @@ -269,12 +319,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 @@ -295,29 +346,20 @@ CONFIG_IP_PNP_BOOTP=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_BIC=y +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 @@ -328,7 +370,6 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -344,7 +385,17 @@ CONFIG_TCP_CONG_BIC=y # 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 +# CONFIG_NET_9P is not set # # Device Drivers @@ -357,29 +408,10 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set - -# -# Parallel port support -# # CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set @@ -387,7 +419,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m @@ -396,6 +428,9 @@ CONFIG_ATA_OVER_ETH=m # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y # @@ -414,82 +449,42 @@ CONFIG_SCSI_PROC_FS=y # 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 Transport Attributes +# 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 - -# -# SCSI low-level drivers -# +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_SATA is not set # CONFIG_SCSI_DEBUG is not set - -# -# Multi-device support (RAID and LVM) -# +# CONFIG_ATA is not set # 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 +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# PHY device support -# # CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# CONFIG_NET_ETHERNET=y CONFIG_MII=y +# CONFIG_AX88796 is not set CONFIG_SMC91X=y # CONFIG_DM9000 is not set +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=y # CONFIG_PPP_MULTILINK is not set @@ -500,24 +495,24 @@ CONFIG_PPP=y # CONFIG_PPP_BSDCOMP is not set # CONFIG_PPP_MPPE is not set # CONFIG_PPPOE is not set +# CONFIG_PPPOL2TP is not set CONFIG_SLIP=y CONFIG_SLIP_COMPRESSED=y +CONFIG_SLHC=y # CONFIG_SLIP_SMART is not set # CONFIG_SLIP_MODE_SLIP6 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 # # Input device support # CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -537,8 +532,14 @@ CONFIG_INPUT_EVBUG=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=y +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set CONFIG_INPUT_UINPUT=y # @@ -574,15 +575,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# CONFIG_WATCHDOG=y CONFIG_WATCHDOG_NOWAYOUT=y @@ -590,25 +583,12 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set +# CONFIG_OMAP_WATCHDOG is not set # CONFIG_HW_RANDOM is not set # CONFIG_NVRAM 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 -# CONFIG_TELCLOCK is not set - -# -# I2C support -# # CONFIG_I2C is not set # @@ -616,61 +596,70 @@ CONFIG_WATCHDOG_NOWAYOUT=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# - -# -# Hardware Monitoring support -# +# CONFIG_W1 is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set # CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_PC87360 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_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set # -# Misc devices -# - -# -# LED devices +# Multifunction device drivers # +# CONFIG_MFD_SM501 is not set # CONFIG_NEW_LEDS is not set # -# LED drivers -# - -# -# LED Triggers -# - -# # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y +# 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=y +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# 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 CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# # CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_OMAP is not set # CONFIG_FB_VIRTUAL is not set # @@ -679,6 +668,7 @@ CONFIG_FB_MODE_HELPERS=y # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y CONFIG_FONT_8x8=y @@ -691,15 +681,10 @@ 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 CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -717,10 +702,10 @@ CONFIG_SOUND=y CONFIG_SOUND_PRIME=y # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set - -# -# USB support -# +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HID_DEBUG=y +CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y # CONFIG_USB_ARCH_HAS_EHCI is not set @@ -734,17 +719,22 @@ CONFIG_USB_ARCH_HAS_OHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set # -# MMC/SD Card support +# DMA Engine support # -# CONFIG_MMC is not set +# CONFIG_DMA_ENGINE is not set # -# Real Time Clock +# DMA Clients +# + +# +# DMA Devices # -CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set # # File systems @@ -753,10 +743,12 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP 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=y @@ -787,6 +779,7 @@ CONFIG_FAT_DEFAULT_CODEPAGE=437 # Pseudo filesystems # CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set @@ -825,6 +818,7 @@ CONFIG_LOCKD_V4=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 @@ -832,7 +826,6 @@ CONFIG_RPCSEC_GSS_KRB5=y # 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 @@ -885,6 +878,11 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_UTF8 is not set # +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# # Profiling support # # CONFIG_PROFILING is not set @@ -893,13 +891,14 @@ CONFIG_NLS_DEFAULT="iso8859-1" # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set # CONFIG_DEBUG_USER is not set # @@ -907,12 +906,12 @@ CONFIG_FRAME_POINTER=y # # 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_MANAGER=y # CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=y @@ -921,7 +920,14 @@ CONFIG_CRYPTO_MD5=y # 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 @@ -935,17 +941,22 @@ CONFIG_CRYPTO_DES=y # 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 -# +CONFIG_CRYPTO_HW=y # # 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_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/configs/omap_osk_5912_defconfig b/arch/arm/configs/omap_osk_5912_defconfig new file mode 100644 index 000000000000..8c1f15c7c45c --- /dev/null +++ b/arch/arm/configs/omap_osk_5912_defconfig @@ -0,0 +1,1073 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.23-rc6 +# Mon Sep 17 14:15:05 2007 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +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 is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=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 +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 +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +CONFIG_ARCH_OMAP=y + +# +# TI OMAP Implementations +# +CONFIG_ARCH_OMAP_OTG=y +CONFIG_ARCH_OMAP1=y +# CONFIG_ARCH_OMAP2 is not set + +# +# OMAP Feature Selections +# +CONFIG_OMAP_RESET_CLOCKS=y +CONFIG_OMAP_MUX=y +# CONFIG_OMAP_MUX_DEBUG is not set +CONFIG_OMAP_MUX_WARNINGS=y +CONFIG_OMAP_MCBSP=y +# CONFIG_OMAP_MPU_TIMER is not set +CONFIG_OMAP_32K_TIMER=y +CONFIG_OMAP_32K_TIMER_HZ=128 +# CONFIG_OMAP_DM_TIMER is not set +CONFIG_OMAP_LL_DEBUG_UART1=y +# CONFIG_OMAP_LL_DEBUG_UART2 is not set +# CONFIG_OMAP_LL_DEBUG_UART3 is not set +CONFIG_OMAP_SERIAL_WAKE=y + +# +# OMAP Core Type +# +# CONFIG_ARCH_OMAP730 is not set +# CONFIG_ARCH_OMAP15XX is not set +CONFIG_ARCH_OMAP16XX=y + +# +# OMAP Board Type +# +# CONFIG_MACH_OMAP_INNOVATOR is not set +# CONFIG_MACH_OMAP_H2 is not set +# CONFIG_MACH_OMAP_H3 is not set +CONFIG_MACH_OMAP_OSK=y +# CONFIG_OMAP_OSK_MISTRAL is not set +# CONFIG_MACH_NOKIA770 is not set +# CONFIG_MACH_OMAP_GENERIC is not set + +# +# OMAP CPU Speed +# +# CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER is not set +# CONFIG_OMAP_ARM_216MHZ is not set +CONFIG_OMAP_ARM_192MHZ=y +# CONFIG_OMAP_ARM_168MHZ is not set +# CONFIG_OMAP_ARM_120MHZ is not set +# CONFIG_OMAP_ARM_60MHZ is not set +# CONFIG_OMAP_ARM_30MHZ is not set + +# +# Boot options +# + +# +# Power management +# + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_IOCTL=y + +# +# PC-card bridges +# +CONFIG_OMAP_CF=y + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_PREEMPT is not set +CONFIG_HZ=128 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x10400000,8M root=/dev/ram0 rw" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_LEGACY is not set +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_UP_POSSIBLE=y +CONFIG_SUSPEND=y +# CONFIG_APM_EMULATION is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=m +# 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=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE 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 is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_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 +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_OMAP_NOR=y +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_IDE=m +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +CONFIG_SMC91X=y +# CONFIG_DM9000 is not set +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_NET_PCMCIA is not set +# CONFIG_WAN is not set +CONFIG_PPP=y +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +# CONFIG_PPP_ASYNC is not set +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPP_MPPE is not set +# CONFIG_PPPOE is not set +# CONFIG_PPPOL2TP is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=y +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=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=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=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_KEYBOARD_OMAP=y +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_CS is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=m +CONFIG_HW_RANDOM_OMAP=m +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_OMAP=y +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_ISP1301_OMAP is not set +CONFIG_TPS65010=y +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_NEW_LEDS 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_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# 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 +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_OMAP is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HID_DEBUG=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +# 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 +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP 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 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# 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_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +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_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN 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 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# 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 + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# 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_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# 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 is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# 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_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index a2dd930d11ef..e5747547b44c 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -279,6 +279,25 @@ static void __devinit pci_fixup_cy82c693(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693); +static void __init pci_fixup_it8152(struct pci_dev *dev) +{ + int i; + /* fixup for ITE 8152 devices */ + /* FIXME: add defines for class 0x68000 and 0x80103 */ + if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST || + dev->class == 0x68000 || + dev->class == 0x80103) { + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + } + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8152, pci_fixup_it8152); + + + void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) { if (debug_pci) @@ -292,9 +311,12 @@ void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) */ static inline int pdev_bad_for_parity(struct pci_dev *dev) { - return (dev->vendor == PCI_VENDOR_ID_INTERG && - (dev->device == PCI_DEVICE_ID_INTERG_2000 || - dev->device == PCI_DEVICE_ID_INTERG_2010)); + return ((dev->vendor == PCI_VENDOR_ID_INTERG && + (dev->device == PCI_DEVICE_ID_INTERG_2000 || + dev->device == PCI_DEVICE_ID_INTERG_2010)) || + (dev->vendor == PCI_VENDOR_ID_ITE && + dev->device == PCI_DEVICE_ID_ITE_8152)); + } /* diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index a98d0c933db0..cecf658e3625 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -361,6 +361,7 @@ CALL(sys_signalfd) /* 350 */ CALL(sys_timerfd) CALL(sys_eventfd) + CALL(sys_fallocate) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 78c9f1a3d41f..5feee722ea98 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -731,10 +731,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = 0; break; - case PTRACE_DETACH: - ret = ptrace_detach(child, data); - break; - case PTRACE_GETREGS: ret = ptrace_getregs(child, (void __user *)data); break; diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S index 7baadae7cb27..062c111c572f 100644 --- a/arch/arm/kernel/relocate_kernel.S +++ b/arch/arm/kernel/relocate_kernel.S @@ -7,6 +7,23 @@ .globl relocate_new_kernel relocate_new_kernel: + /* Move boot params back to where the kernel expects them */ + + ldr r0,kexec_boot_params_address + teq r0,#0 + beq 8f + + ldr r1,kexec_boot_params_copy + mov r6,#KEXEC_BOOT_PARAMS_SIZE/4 +7: + ldr r5,[r1],#4 + str r5,[r0],#4 + subs r6,r6,#1 + bne 7b + +8: + /* Boot params moved, now go on with the kernel */ + ldr r0,kexec_indirection_page ldr r1,kexec_start_address @@ -50,7 +67,7 @@ relocate_new_kernel: mov lr,r1 mov r0,#0 ldr r1,kexec_mach_type - mov r2,#0 + ldr r2,kexec_boot_params_address mov pc,lr .globl kexec_start_address @@ -65,6 +82,16 @@ kexec_indirection_page: kexec_mach_type: .long 0x0 + /* phy addr where new kernel will expect to find boot params */ + .globl kexec_boot_params_address +kexec_boot_params_address: + .long 0x0 + + /* phy addr where old kernel put a copy of orig boot params */ + .globl kexec_boot_params_copy +kexec_boot_params_copy: + .long 0x0 + relocate_new_kernel_end: .globl relocate_new_kernel_size diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 4de432ec903a..bf56eb337df1 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -24,6 +24,7 @@ #include <linux/interrupt.h> #include <linux/smp.h> #include <linux/fs.h> +#include <linux/kexec.h> #include <asm/cpu.h> #include <asm/elf.h> @@ -304,10 +305,23 @@ int cpu_architecture(void) cpu_arch = (processor_id >> 16) & 7; if (cpu_arch) cpu_arch += CPU_ARCH_ARMv3; - } else { - /* the revised CPUID */ - cpu_arch = ((processor_id >> 12) & 0xf) - 0xb + CPU_ARCH_ARMv6; - } + } else if ((processor_id & 0x000f0000) == 0x000f0000) { + unsigned int mmfr0; + + /* Revised CPUID format. Read the Memory Model Feature + * Register 0 and check for VMSAv7 or PMSAv7 */ + asm("mrc p15, 0, %0, c0, c1, 4" + : "=r" (mmfr0)); + if ((mmfr0 & 0x0000000f) == 0x00000003 || + (mmfr0 & 0x000000f0) == 0x00000030) + cpu_arch = CPU_ARCH_ARMv7; + else if ((mmfr0 & 0x0000000f) == 0x00000002 || + (mmfr0 & 0x000000f0) == 0x00000020) + cpu_arch = CPU_ARCH_ARMv6; + else + cpu_arch = CPU_ARCH_UNKNOWN; + } else + cpu_arch = CPU_ARCH_UNKNOWN; return cpu_arch; } @@ -770,6 +784,23 @@ static int __init customize_machine(void) } arch_initcall(customize_machine); +#ifdef CONFIG_KEXEC + +/* Physical addr of where the boot params should be for this machine */ +extern unsigned long kexec_boot_params_address; + +/* Physical addr of the buffer into which the boot params are copied */ +extern unsigned long kexec_boot_params_copy; + +/* Pointer to the boot params buffer, for manipulation and display */ +unsigned long kexec_boot_params; +EXPORT_SYMBOL(kexec_boot_params); + +/* The buffer itself - make sure it is sized correctly */ +static unsigned long kexec_boot_params_buf[(KEXEC_BOOT_PARAMS_SIZE + 3) / 4]; + +#endif + void __init setup_arch(char **cmdline_p) { struct tag *tags = (struct tag *)&init_tags; @@ -788,6 +819,18 @@ void __init setup_arch(char **cmdline_p) else if (mdesc->boot_params) tags = phys_to_virt(mdesc->boot_params); +#ifdef CONFIG_KEXEC + kexec_boot_params_copy = virt_to_phys(kexec_boot_params_buf); + kexec_boot_params = (unsigned long)kexec_boot_params_buf; + if (__atags_pointer) { + kexec_boot_params_address = __atags_pointer; + memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE); + } else if (mdesc->boot_params) { + kexec_boot_params_address = mdesc->boot_params; + memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE); + } +#endif + /* * If we have the old style parameters, convert them to * a tag list. diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index a31157f1655a..05a9f8a1b45e 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -7,6 +7,8 @@ choice config ARCH_AT91RM9200 bool "AT91RM9200" + select GENERIC_TIME + select GENERIC_CLOCKEVENTS config ARCH_AT91SAM9260 bool "AT91SAM9260 or AT91SAM9XE" @@ -20,8 +22,15 @@ config ARCH_AT91SAM9263 config ARCH_AT91SAM9RL bool "AT91SAM9RL" +config ARCH_AT91X40 + bool "AT91x40" + endchoice +config AT91_PMC_UNIT + bool + default !ARCH_AT91X40 + # ---------------------------------------------------------- if ARCH_AT91RM9200 @@ -169,6 +178,22 @@ endif # ---------------------------------------------------------- +if ARCH_AT91X40 + +comment "AT91X40 Board Type" + +config MACH_AT91EB01 + bool "Atmel AT91EB01 Evaluation Kit" + help + Select this if you are using Atmel's AT91EB01 Evaluation Kit. + It is also a popular target for simulators such as GDB's + ARM simulator (commonly known as the ARMulator) and the + Skyeye simulator. + +endif + +# ---------------------------------------------------------- + comment "AT91 Board Options" config MTD_AT91_DATAFLASH_CARD diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index a4d80eb056ee..a21f08c64ea6 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -2,11 +2,12 @@ # Makefile for the linux kernel. # -obj-y := clock.o irq.o gpio.o +obj-y := irq.o gpio.o obj-m := obj-n := obj- := +obj-$(CONFIG_AT91_PMC_UNIT) += clock.o obj-$(CONFIG_PM) += pm.o # CPU-specific support @@ -15,6 +16,7 @@ obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_d obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o +obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o # AT91RM9200 board-specific support obj-$(CONFIG_MACH_ONEARM) += board-1arm.o @@ -27,6 +29,7 @@ obj-$(CONFIG_MACH_KB9200) += board-kb9202.o obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o obj-$(CONFIG_MACH_KAFA) += board-kafa.o obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o +obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o # AT91SAM9260 board-specific support obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index a6340357585d..50392ff71513 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -19,70 +19,64 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <linux/init.h> +#include <linux/kernel.h> #include <linux/interrupt.h> #include <linux/irq.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/time.h> +#include <linux/clockchips.h> -#include <asm/hardware.h> -#include <asm/io.h> #include <asm/mach/time.h> #include <asm/arch/at91_st.h> static unsigned long last_crtr; +static u32 irqmask; +static struct clock_event_device clkevt; /* - * The ST_CRTR is updated asynchronously to the master clock. It is therefore - * necessary to read it twice (with the same value) to ensure accuracy. + * The ST_CRTR is updated asynchronously to the master clock ... but + * the updates as seen by the CPU don't seem to be strictly monotonic. + * Waiting until we read the same value twice avoids glitching. */ -static inline unsigned long read_CRTR(void) { +static inline unsigned long read_CRTR(void) +{ unsigned long x1, x2; + x1 = at91_sys_read(AT91_ST_CRTR); do { - x1 = at91_sys_read(AT91_ST_CRTR); x2 = at91_sys_read(AT91_ST_CRTR); - } while (x1 != x2); - + if (x1 == x2) + break; + x1 = x2; + } while (1); return x1; } /* - * Returns number of microseconds since last timer interrupt. Note that interrupts - * will have been disabled by do_gettimeofday() - * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy. - * 'tick' is usecs per jiffy (linux/timex.h). - */ -static unsigned long at91rm9200_gettimeoffset(void) -{ - unsigned long elapsed; - - elapsed = (read_CRTR() - last_crtr) & AT91_ST_ALMV; - - return (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH; -} - -/* * IRQ handler for the timer. */ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) { - if (at91_sys_read(AT91_ST_SR) & AT91_ST_PITS) { /* This is a shared interrupt */ - write_seqlock(&xtime_lock); + u32 sr = at91_sys_read(AT91_ST_SR) & irqmask; - while (((read_CRTR() - last_crtr) & AT91_ST_ALMV) >= LATCH) { - timer_tick(); - last_crtr = (last_crtr + LATCH) & AT91_ST_ALMV; - } + /* simulate "oneshot" timer with alarm */ + if (sr & AT91_ST_ALMS) { + clkevt.event_handler(&clkevt); + return IRQ_HANDLED; + } - write_sequnlock(&xtime_lock); + /* periodic mode should handle delayed ticks */ + if (sr & AT91_ST_PITS) { + u32 crtr = read_CRTR(); + while (((crtr - last_crtr) & AT91_ST_CRTV) >= LATCH) { + last_crtr += LATCH; + clkevt.event_handler(&clkevt); + } return IRQ_HANDLED; } - else - return IRQ_NONE; /* not handled */ + + /* this irq is shared ... */ + return IRQ_NONE; } static struct irqaction at91rm9200_timer_irq = { @@ -91,56 +85,127 @@ static struct irqaction at91rm9200_timer_irq = { .handler = at91rm9200_timer_interrupt }; -void at91rm9200_timer_reset(void) +static cycle_t read_clk32k(void) { - last_crtr = 0; + return read_CRTR(); +} - /* Real time counter incremented every 30.51758 microseconds */ - at91_sys_write(AT91_ST_RTMR, 1); +static struct clocksource clk32k = { + .name = "32k_counter", + .rating = 150, + .read = read_clk32k, + .mask = CLOCKSOURCE_MASK(20), + .shift = 10, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static void +clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) +{ + /* Disable and flush pending timer interrupts */ + at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS); + (void) at91_sys_read(AT91_ST_SR); - /* Set Period Interval timer */ - at91_sys_write(AT91_ST_PIMR, LATCH); + last_crtr = read_CRTR(); + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + /* PIT for periodic irqs; fixed rate of 1/HZ */ + irqmask = AT91_ST_PITS; + at91_sys_write(AT91_ST_PIMR, LATCH); + break; + case CLOCK_EVT_MODE_ONESHOT: + /* ALM for oneshot irqs, set by next_event() + * before 32 seconds have passed + */ + irqmask = AT91_ST_ALMS; + at91_sys_write(AT91_ST_RTAR, last_crtr); + break; + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_RESUME: + irqmask = 0; + break; + } + at91_sys_write(AT91_ST_IER, irqmask); +} - /* Clear any pending interrupts */ +static int +clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev) +{ + unsigned long flags; + u32 alm; + int status = 0; + + BUG_ON(delta < 2); + + /* Use "raw" primitives so we behave correctly on RT kernels. */ + raw_local_irq_save(flags); + + /* The alarm IRQ uses absolute time (now+delta), not the relative + * time (delta) in our calling convention. Like all clockevents + * using such "match" hardware, we have a race to defend against. + * + * Our defense here is to have set up the clockevent device so the + * delta is at least two. That way we never end up writing RTAR + * with the value then held in CRTR ... which would mean the match + * wouldn't trigger until 32 seconds later, after CRTR wraps. + */ + alm = read_CRTR(); + + /* Cancel any pending alarm; flush any pending IRQ */ + at91_sys_write(AT91_ST_RTAR, alm); (void) at91_sys_read(AT91_ST_SR); - /* Enable Period Interval Timer interrupt */ - at91_sys_write(AT91_ST_IER, AT91_ST_PITS); + /* Schedule alarm by writing RTAR. */ + alm += delta; + at91_sys_write(AT91_ST_RTAR, alm); + + raw_local_irq_restore(flags); + return status; } +static struct clock_event_device clkevt = { + .name = "at91_tick", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, + .rating = 150, + .cpumask = CPU_MASK_CPU0, + .set_next_event = clkevt32k_next_event, + .set_mode = clkevt32k_mode, +}; + /* - * Set up timer interrupt. + * ST (system timer) module supports both clockevents and clocksource. */ void __init at91rm9200_timer_init(void) { - /* Disable all timer interrupts */ - at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); - (void) at91_sys_read(AT91_ST_SR); /* Clear any pending interrupts */ + /* Disable all timer interrupts, and clear any pending ones */ + at91_sys_write(AT91_ST_IDR, + AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); + (void) at91_sys_read(AT91_ST_SR); /* Make IRQs happen for the system timer */ setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq); - /* Change the kernel's 'tick' value to 10009 usec. (the default is 10000) */ - tick_usec = (LATCH * 1000000) / CLOCK_TICK_RATE; + /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used + * directly for the clocksource and all clockevents, after adjusting + * its prescaler from the 1 Hz default. + */ + at91_sys_write(AT91_ST_RTMR, 1); - /* Initialize and enable the timer interrupt */ - at91rm9200_timer_reset(); -} + /* Setup timer clockevent, with minimum of two ticks (important!!) */ + clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift); + clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt); + clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1; + clkevt.cpumask = cpumask_of_cpu(0); + clockevents_register_device(&clkevt); -#ifdef CONFIG_PM -static void at91rm9200_timer_suspend(void) -{ - /* disable Period Interval Timer interrupt */ - at91_sys_write(AT91_ST_IDR, AT91_ST_PITS); + /* register clocksource */ + clk32k.mult = clocksource_hz2mult(AT91_SLOW_CLOCK, clk32k.shift); + clocksource_register(&clk32k); } -#else -#define at91rm9200_timer_suspend NULL -#endif struct sys_timer at91rm9200_timer = { .init = at91rm9200_timer_init, - .offset = at91rm9200_gettimeoffset, - .suspend = at91rm9200_timer_suspend, - .resume = at91rm9200_timer_reset, }; diff --git a/arch/arm/mach-at91/at91x40.c b/arch/arm/mach-at91/at91x40.c new file mode 100644 index 000000000000..1de121fc55f4 --- /dev/null +++ b/arch/arm/mach-at91/at91x40.c @@ -0,0 +1,67 @@ +/* + * arch/arm/mach-at91/at91x40.c + * + * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com> + * Copyright (C) 2005 SAN People + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <asm/mach/arch.h> +#include <asm/arch/at91x40.h> +#include <asm/arch/at91_st.h> +#include "generic.h" + +/* + * This is used in the gpio code, stub locally. + */ +int clk_enable(struct clk *clk) +{ + return 0; +} + +void __init at91x40_initialize(unsigned long main_clock) +{ + at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1) + | (1 << AT91X40_ID_IRQ2); +} + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91x40_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller (FIQ) */ + 0, /* System Peripherals */ + 0, /* USART 0 */ + 0, /* USART 1 */ + 2, /* Timer Counter 0 */ + 2, /* Timer Counter 1 */ + 2, /* Timer Counter 2 */ + 0, /* Watchdog timer */ + 0, /* Parallel IO Controller A */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* External IRQ0 */ + 0, /* External IRQ1 */ + 0, /* External IRQ2 */ +}; + +void __init at91x40_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +{ + if (!priority) + priority = at91x40_default_irq_priority; + + at91_aic_init(priority); +} + diff --git a/arch/arm/mach-at91/at91x40_time.c b/arch/arm/mach-at91/at91x40_time.c new file mode 100644 index 000000000000..eddc882f1b4a --- /dev/null +++ b/arch/arm/mach-at91/at91x40_time.c @@ -0,0 +1,80 @@ +/* + * arch/arm/mach-at91/at91x40_time.c + * + * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/time.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/mach/time.h> +#include <asm/arch/at91_tc.h> + +/* + * 3 counter/timer units present. + */ +#define AT91_TC_CLK0BASE 0 +#define AT91_TC_CLK1BASE 0x40 +#define AT91_TC_CLK2BASE 0x80 + +static unsigned long at91x40_gettimeoffset(void) +{ + return (at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CV) * 1000000 / (AT91X40_MASTER_CLOCK / 128)); +} + +static irqreturn_t at91x40_timer_interrupt(int irq, void *dev_id) +{ + at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_SR); + timer_tick(); + return IRQ_HANDLED; +} + +static struct irqaction at91x40_timer_irq = { + .name = "at91_tick", + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = at91x40_timer_interrupt +}; + +void __init at91x40_timer_init(void) +{ + unsigned int v; + + at91_sys_write(AT91_TC + AT91_TC_BCR, 0); + v = at91_sys_read(AT91_TC + AT91_TC_BMR); + v = (v & ~AT91_TC_TC1XC1S) | AT91_TC_TC1XC1S_NONE; + at91_sys_write(AT91_TC + AT91_TC_BMR, v); + + at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS); + at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG)); + at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff); + at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1); + at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4)); + + setup_irq(AT91X40_ID_TC1, &at91x40_timer_irq); + + at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN)); +} + +struct sys_timer at91x40_timer = { + .init = at91x40_timer_init, + .offset = at91x40_gettimeoffset, +}; + diff --git a/arch/arm/mach-at91/board-eb01.c b/arch/arm/mach-at91/board-eb01.c new file mode 100644 index 000000000000..0c1e3858e7df --- /dev/null +++ b/arch/arm/mach-at91/board-eb01.c @@ -0,0 +1,44 @@ +/* + * arch/arm/mach-at91/board-eb01.c + * + * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/irq.h> +#include <asm/mach-types.h> +#include <asm/hardware.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/arch/board.h> +#include "generic.h" + +static void __init at91eb01_map_io(void) +{ + at91x40_initialize(40000000); +} + +MACHINE_START(AT91EB01, "Atmel AT91 EB01") + /* Maintainer: Greg Ungerer <gerg@snapgear.com> */ + .timer = &at91x40_timer, + .init_irq = at91x40_init_interrupts, + .map_io = at91eb01_map_io, +MACHINE_END + diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 68ed71a3e6c6..77d4c0a37842 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -14,6 +14,7 @@ extern void __init at91sam9260_initialize(unsigned long main_clock); extern void __init at91sam9261_initialize(unsigned long main_clock); extern void __init at91sam9263_initialize(unsigned long main_clock); extern void __init at91sam9rl_initialize(unsigned long main_clock); +extern void __init at91x40_initialize(unsigned long main_clock); /* Interrupts */ extern void __init at91rm9200_init_interrupts(unsigned int priority[]); @@ -21,12 +22,14 @@ extern void __init at91sam9260_init_interrupts(unsigned int priority[]); extern void __init at91sam9261_init_interrupts(unsigned int priority[]); extern void __init at91sam9263_init_interrupts(unsigned int priority[]); extern void __init at91sam9rl_init_interrupts(unsigned int priority[]); +extern void __init at91x40_init_interrupts(unsigned int priority[]); extern void __init at91_aic_init(unsigned int priority[]); /* Timer */ struct sys_timer; extern struct sys_timer at91rm9200_timer; extern struct sys_timer at91sam926x_timer; +extern struct sys_timer at91x40_timer; /* Clocks */ extern int __init at91_clock_init(unsigned long main_clock); diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index 4dde34f25e63..986205ec9269 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c @@ -193,7 +193,11 @@ static struct irq_chip clps7500_no_chip = { .unmask = cl7500_no_action, }; -static struct irqaction irq_isa = { no_action, 0, CPU_MASK_NONE, "isa", NULL, NULL }; +static struct irqaction irq_isa = { + .handler = no_action, + .mask = CPU_MASK_NONE, + .name = "isa", +}; static void __init clps7500_init_irq(void) { diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig index 575a21dabd2f..ea8549bfbef2 100644 --- a/arch/arm/mach-ep93xx/Kconfig +++ b/arch/arm/mach-ep93xx/Kconfig @@ -27,6 +27,12 @@ config MACH_EDB9302A Say 'Y' here if you want your kernel to support the Cirrus Logic EDB9302A Evaluation Board. +config MACH_EDB9307 + bool "Support Cirrus Logic EDB9307" + help + Say 'Y' here if you want your kernel to support the Cirrus + Logic EDB9307 Evaluation Board. + config MACH_EDB9312 bool "Support Cirrus Logic EDB9312" help diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile index 0d3bf932654e..0ecf99761feb 100644 --- a/arch/arm/mach-ep93xx/Makefile +++ b/arch/arm/mach-ep93xx/Makefile @@ -9,6 +9,7 @@ obj- := obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o obj-$(CONFIG_MACH_EDB9302) += edb9302.o obj-$(CONFIG_MACH_EDB9302A) += edb9302a.o +obj-$(CONFIG_MACH_EDB9307) += edb9307.o obj-$(CONFIG_MACH_EDB9312) += edb9312.o obj-$(CONFIG_MACH_EDB9315) += edb9315.o obj-$(CONFIG_MACH_EDB9315A) += edb9315a.o diff --git a/arch/arm/mach-ep93xx/edb9307.c b/arch/arm/mach-ep93xx/edb9307.c new file mode 100644 index 000000000000..d6a5698da91f --- /dev/null +++ b/arch/arm/mach-ep93xx/edb9307.c @@ -0,0 +1,91 @@ +/* + * arch/arm/mach-ep93xx/edb9307.c + * Cirrus Logic EDB9307 support. + * + * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <asm/io.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +static struct physmap_flash_data edb9307_flash_data = { + .width = 4, +}; + +static struct resource edb9307_flash_resource = { + .start = 0x60000000, + .end = 0x61ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device edb9307_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &edb9307_flash_data, + }, + .num_resources = 1, + .resource = &edb9307_flash_resource, +}; + +static struct ep93xx_eth_data edb9307_eth_data = { + .phy_id = 1, +}; + +static struct resource edb9307_eth_resource[] = { + { + .start = EP93XX_ETHERNET_PHYS_BASE, + .end = EP93XX_ETHERNET_PHYS_BASE + 0xffff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_EP93XX_ETHERNET, + .end = IRQ_EP93XX_ETHERNET, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device edb9307_eth_device = { + .name = "ep93xx-eth", + .id = -1, + .dev = { + .platform_data = &edb9307_eth_data, + }, + .num_resources = 2, + .resource = edb9307_eth_resource, +}; + +static void __init edb9307_init_machine(void) +{ + ep93xx_init_devices(); + platform_device_register(&edb9307_flash); + + memcpy(edb9307_eth_data.dev_addr, + (void *)(EP93XX_ETHERNET_BASE + 0x50), 6); + platform_device_register(&edb9307_eth_device); +} + +MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board") + /* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */ + .phys_io = EP93XX_APB_PHYS_BASE, + .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ep93xx_map_io, + .init_irq = ep93xx_init_irq, + .timer = &ep93xx_timer, + .init_machine = edb9307_init_machine, +MACHINE_END diff --git a/arch/arm/mach-footbridge/isa.c b/arch/arm/mach-footbridge/isa.c index 28846c7edaaf..725a219d0ed5 100644 --- a/arch/arm/mach-footbridge/isa.c +++ b/arch/arm/mach-footbridge/isa.c @@ -12,6 +12,39 @@ #include <asm/irq.h> +static struct resource rtc_resources[] = { + [0] = { + .start = 0x70, + .end = 0x73, + .flags = IORESOURCE_IO, + }, + [1] = { + .start = IRQ_ISA_RTC_ALARM, + .end = IRQ_ISA_RTC_ALARM, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device rtc_device = { + .name = "rtc_cmos", + .id = -1, + .resource = rtc_resources, + .num_resources = ARRAY_SIZE(rtc_resources), +}; + +static struct resource serial_resources[] = { + [0] = { + .start = 0x3f8, + .end = 0x3ff, + .flags = IORESOURCE_IO, + }, + [1] = { + .start = 0x2f8, + .end = 0x2ff, + .flags = IORESOURCE_IO, + }, +}; + static struct plat_serial8250_port serial_platform_data[] = { { .iobase = 0x3f8, @@ -38,11 +71,21 @@ static struct platform_device serial_device = { .dev = { .platform_data = serial_platform_data, }, + .resource = serial_resources, + .num_resources = ARRAY_SIZE(serial_resources), }; static int __init footbridge_isa_init(void) { - return platform_device_register(&serial_device); + int err; + + err = platform_device_register(&rtc_device); + if (err) + printk(KERN_ERR "Unable to register RTC device: %d\n", err); + err = platform_device_register(&serial_device); + if (err) + printk(KERN_ERR "Unable to register serial device: %d\n", err); + return 0; } arch_initcall(footbridge_isa_init); diff --git a/arch/arm/mach-imx/cpufreq.c b/arch/arm/mach-imx/cpufreq.c index 467d899fbe75..e548ba74a4d2 100644 --- a/arch/arm/mach-imx/cpufreq.c +++ b/arch/arm/mach-imx/cpufreq.c @@ -269,7 +269,6 @@ static int __init imx_cpufreq_driver_init(struct cpufreq_policy *policy) return -EINVAL; policy->cur = policy->min = policy->max = imx_get_speed(0); - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.min_freq = 8000; policy->cpuinfo.max_freq = 200000; /* Manual states, that PLL stabilizes in two CLK32 periods */ diff --git a/arch/arm/mach-ns9xxx/Makefile b/arch/arm/mach-ns9xxx/Makefile index 4476411b8140..6fb82b855a55 100644 --- a/arch/arm/mach-ns9xxx/Makefile +++ b/arch/arm/mach-ns9xxx/Makefile @@ -1,4 +1,4 @@ -obj-y := irq.o time.o generic.o +obj-y := irq.o time.o generic.o gpio.o obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o obj-$(CONFIG_MACH_CC9P9360JS) += mach-cc9p9360js.o diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/arch/arm/mach-ns9xxx/board-a9m9750dev.c index 925048e7adfe..0f65177f9e5f 100644 --- a/arch/arm/mach-ns9xxx/board-a9m9750dev.c +++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.c @@ -13,6 +13,7 @@ #include <linux/irq.h> #include <asm/mach/map.h> +#include <asm/gpio.h> #include <asm/arch-ns9xxx/board.h> #include <asm/arch-ns9xxx/regs-sys.h> @@ -44,7 +45,13 @@ static void a9m9750dev_fpga_ack_irq(unsigned int irq) static void a9m9750dev_fpga_mask_irq(unsigned int irq) { - FPGA_IER &= ~(1 << (irq - FPGA_IRQ(0))); + u8 ier; + + ier = __raw_readb(FPGA_IER); + + ier &= ~(1 << (irq - FPGA_IRQ(0))); + + __raw_writeb(ier, FPGA_IER); } static void a9m9750dev_fpga_maskack_irq(unsigned int irq) @@ -55,7 +62,13 @@ static void a9m9750dev_fpga_maskack_irq(unsigned int irq) static void a9m9750dev_fpga_unmask_irq(unsigned int irq) { - FPGA_IER |= 1 << (irq - FPGA_IRQ(0)); + u8 ier; + + ier = __raw_readb(FPGA_IER); + + ier |= 1 << (irq - FPGA_IRQ(0)); + + __raw_writeb(ier, FPGA_IER); } static struct irq_chip a9m9750dev_fpga_chip = { @@ -68,30 +81,34 @@ static struct irq_chip a9m9750dev_fpga_chip = { static void a9m9750dev_fpga_demux_handler(unsigned int irq, struct irq_desc *desc) { - int stat = FPGA_ISR; + u8 stat = __raw_readb(FPGA_ISR); + + desc->chip->mask_ack(irq); while (stat != 0) { int irqno = fls(stat) - 1; + struct irq_desc *fpgadesc; stat &= ~(1 << irqno); - desc = irq_desc + FPGA_IRQ(irqno); + fpgadesc = irq_desc + FPGA_IRQ(irqno); - desc_handle_irq(FPGA_IRQ(irqno), desc); + desc_handle_irq(FPGA_IRQ(irqno), fpgadesc); } + + desc->chip->unmask(irq); } void __init board_a9m9750dev_init_irq(void) { - u32 reg; + u32 eic; int i; - /* - * configure gpio for IRQ_EXT2 - * use GPIO 11, because GPIO 32 is used for the LCD - */ - /* XXX: proper GPIO handling */ - BBU_GCONFb1(1) &= ~0x2000; + if (gpio_request(11, "board a9m9750dev extirq2") == 0) + ns9xxx_gpio_configure(11, 0, 1); + else + printk(KERN_ERR "%s: cannot get gpio 11 for IRQ_EXT2\n", + __func__); for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) { set_irq_chip(i, &a9m9750dev_fpga_chip); @@ -100,10 +117,10 @@ void __init board_a9m9750dev_init_irq(void) } /* IRQ_EXT2: level sensitive + active low */ - reg = SYS_EIC(2); - REGSET(reg, SYS_EIC, PLTY, AL); - REGSET(reg, SYS_EIC, LVEDG, LEVEL); - SYS_EIC(2) = reg; + eic = __raw_readl(SYS_EIC(2)); + REGSET(eic, SYS_EIC, PLTY, AL); + REGSET(eic, SYS_EIC, LVEDG, LEVEL); + __raw_writel(eic, SYS_EIC(2)); set_irq_chained_handler(IRQ_EXT2, a9m9750dev_fpga_demux_handler); @@ -167,17 +184,18 @@ void __init board_a9m9750dev_init_machine(void) u32 reg; /* setup static CS0: memory base ... */ - REGSETIM(SYS_SMCSSMB(0), SYS_SMCSSMB, CSxB, - NS9XXX_CSxSTAT_PHYS(0) >> 12); + reg = __raw_readl(SYS_SMCSSMB(0)); + REGSETIM(reg, SYS_SMCSSMB, CSxB, NS9XXX_CSxSTAT_PHYS(0) >> 12); + __raw_writel(reg, SYS_SMCSSMB(0)); /* ... and mask */ - reg = SYS_SMCSSMM(0); + reg = __raw_readl(SYS_SMCSSMM(0)); REGSETIM(reg, SYS_SMCSSMM, CSxM, 0xfffff); REGSET(reg, SYS_SMCSSMM, CSEx, EN); - SYS_SMCSSMM(0) = reg; + __raw_writel(reg, SYS_SMCSSMM(0)); /* setup static CS0: memory configuration */ - reg = MEM_SMC(0); + reg = __raw_readl(MEM_SMC(0)); REGSET(reg, MEM_SMC, PSMC, OFF); REGSET(reg, MEM_SMC, BSMC, OFF); REGSET(reg, MEM_SMC, EW, OFF); @@ -185,13 +203,13 @@ void __init board_a9m9750dev_init_machine(void) REGSET(reg, MEM_SMC, PC, AL); REGSET(reg, MEM_SMC, PM, DIS); REGSET(reg, MEM_SMC, MW, 8); - MEM_SMC(0) = reg; + __raw_writel(reg, MEM_SMC(0)); /* setup static CS0: timing */ - MEM_SMWED(0) = 0x2; - MEM_SMOED(0) = 0x2; - MEM_SMRD(0) = 0x6; - MEM_SMWD(0) = 0x6; + __raw_writel(0x2, MEM_SMWED(0)); + __raw_writel(0x2, MEM_SMOED(0)); + __raw_writel(0x6, MEM_SMRD(0)); + __raw_writel(0x6, MEM_SMWD(0)); platform_add_devices(board_a9m9750dev_devices, ARRAY_SIZE(board_a9m9750dev_devices)); diff --git a/arch/arm/mach-ns9xxx/gpio.c b/arch/arm/mach-ns9xxx/gpio.c new file mode 100644 index 000000000000..b2230213b983 --- /dev/null +++ b/arch/arm/mach-ns9xxx/gpio.c @@ -0,0 +1,190 @@ +/* + * arch/arm/mach-ns9xxx/gpio.c + * + * Copyright (C) 2006 by Digi International Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#include <linux/compiler.h> +#include <linux/init.h> +#include <linux/spinlock.h> +#include <linux/module.h> + +#include <asm/arch-ns9xxx/gpio.h> +#include <asm/arch-ns9xxx/processor.h> +#include <asm/arch-ns9xxx/regs-bbu.h> +#include <asm/io.h> +#include <asm/bug.h> +#include <asm/types.h> +#include <asm/bitops.h> + +#if defined(CONFIG_PROCESSOR_NS9360) +#define GPIO_MAX 72 +#elif defined(CONFIG_PROCESSOR_NS9750) +#define GPIO_MAX 49 +#endif + +/* protects BBU_GCONFx and BBU_GCTRLx */ +static spinlock_t gpio_lock = __SPIN_LOCK_UNLOCKED(gpio_lock); + +/* only access gpiores with atomic ops */ +static DECLARE_BITMAP(gpiores, GPIO_MAX); + +static inline int ns9xxx_valid_gpio(unsigned gpio) +{ +#if defined(CONFIG_PROCESSOR_NS9360) + if (processor_is_ns9360()) + return gpio <= 72; + else +#endif +#if defined(CONFIG_PROCESSOR_NS9750) + if (processor_is_ns9750()) + return gpio <= 49; + else +#endif + BUG(); +} + +static inline void __iomem *ns9xxx_gpio_get_gconfaddr(unsigned gpio) +{ + if (gpio < 56) + return BBU_GCONFb1(gpio / 8); + else + /* + * this could be optimised away on + * ns9750 only builds, but it isn't ... + */ + return BBU_GCONFb2((gpio - 56) / 8); +} + +static inline void __iomem *ns9xxx_gpio_get_gctrladdr(unsigned gpio) +{ + if (gpio < 32) + return BBU_GCTRL1; + else if (gpio < 64) + return BBU_GCTRL2; + else + /* this could be optimised away on ns9750 only builds */ + return BBU_GCTRL3; +} + +static inline void __iomem *ns9xxx_gpio_get_gstataddr(unsigned gpio) +{ + if (gpio < 32) + return BBU_GSTAT1; + else if (gpio < 64) + return BBU_GSTAT2; + else + /* this could be optimised away on ns9750 only builds */ + return BBU_GSTAT3; +} + +int gpio_request(unsigned gpio, const char *label) +{ + if (likely(ns9xxx_valid_gpio(gpio))) + return test_and_set_bit(gpio, gpiores) ? -EBUSY : 0; + else + return -EINVAL; +} +EXPORT_SYMBOL(gpio_request); + +void gpio_free(unsigned gpio) +{ + clear_bit(gpio, gpiores); + return; +} +EXPORT_SYMBOL(gpio_free); + +/* + * each gpio can serve for 4 different purposes [0..3]. These are called + * "functions" and passed in the parameter func. Functions 0-2 are always some + * special things, function 3 is GPIO. If func == 3 dir specifies input or + * output, and with inv you can enable an inverter (independent of func). + */ +static int __ns9xxx_gpio_configure(unsigned gpio, int dir, int inv, int func) +{ + void __iomem *conf = ns9xxx_gpio_get_gconfaddr(gpio); + u32 confval; + unsigned long flags; + + spin_lock_irqsave(&gpio_lock, flags); + + confval = __raw_readl(conf); + REGSETIM_IDX(confval, BBU_GCONFx, DIR, gpio & 7, dir); + REGSETIM_IDX(confval, BBU_GCONFx, INV, gpio & 7, inv); + REGSETIM_IDX(confval, BBU_GCONFx, FUNC, gpio & 7, func); + __raw_writel(confval, conf); + + spin_unlock_irqrestore(&gpio_lock, flags); + + return 0; +} + +int ns9xxx_gpio_configure(unsigned gpio, int inv, int func) +{ + if (likely(ns9xxx_valid_gpio(gpio))) { + if (func == 3) { + printk(KERN_WARNING "use gpio_direction_input " + "or gpio_direction_output\n"); + return -EINVAL; + } else + return __ns9xxx_gpio_configure(gpio, 0, inv, func); + } else + return -EINVAL; +} +EXPORT_SYMBOL(ns9xxx_gpio_configure); + +int gpio_direction_input(unsigned gpio) +{ + if (likely(ns9xxx_valid_gpio(gpio))) { + return __ns9xxx_gpio_configure(gpio, 0, 0, 3); + } else + return -EINVAL; +} +EXPORT_SYMBOL(gpio_direction_input); + +int gpio_direction_output(unsigned gpio, int value) +{ + if (likely(ns9xxx_valid_gpio(gpio))) { + gpio_set_value(gpio, value); + + return __ns9xxx_gpio_configure(gpio, 1, 0, 3); + } else + return -EINVAL; +} +EXPORT_SYMBOL(gpio_direction_output); + +int gpio_get_value(unsigned gpio) +{ + void __iomem *stat = ns9xxx_gpio_get_gstataddr(gpio); + int ret; + + ret = 1 & (__raw_readl(stat) >> (gpio & 31)); + + return ret; +} +EXPORT_SYMBOL(gpio_get_value); + +void gpio_set_value(unsigned gpio, int value) +{ + void __iomem *ctrl = ns9xxx_gpio_get_gctrladdr(gpio); + u32 ctrlval; + unsigned long flags; + + spin_lock_irqsave(&gpio_lock, flags); + + ctrlval = __raw_readl(ctrl); + + if (value) + ctrlval |= 1 << (gpio & 31); + else + ctrlval &= ~(1 << (gpio & 31)); + + __raw_writel(ctrlval, ctrl); + + spin_unlock_irqrestore(&gpio_lock, flags); +} +EXPORT_SYMBOL(gpio_set_value); diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c index b8c7b00522e6..00001b874e97 100644 --- a/arch/arm/mach-ns9xxx/irq.c +++ b/arch/arm/mach-ns9xxx/irq.c @@ -9,6 +9,7 @@ * the Free Software Foundation. */ #include <linux/interrupt.h> +#include <asm/io.h> #include <asm/mach/irq.h> #include <asm/mach-types.h> #include <asm/arch-ns9xxx/regs-sys.h> @@ -17,48 +18,17 @@ #include "generic.h" -static void ns9xxx_ack_irq_timer(unsigned int irq) -{ - u32 tc = SYS_TC(irq - IRQ_TIMER0); - - /* - * If the timer is programmed to halt on terminal count, the - * timer must be disabled before clearing the interrupt. - */ - if (REGGET(tc, SYS_TCx, REN) == 0) { - REGSET(tc, SYS_TCx, TEN, DIS); - SYS_TC(irq - IRQ_TIMER0) = tc; - } - - REGSET(tc, SYS_TCx, INTC, SET); - SYS_TC(irq - IRQ_TIMER0) = tc; - - REGSET(tc, SYS_TCx, INTC, UNSET); - SYS_TC(irq - IRQ_TIMER0) = tc; -} - -static void (*ns9xxx_ack_irq_functions[NR_IRQS])(unsigned int) = { - [IRQ_TIMER0] = ns9xxx_ack_irq_timer, - [IRQ_TIMER1] = ns9xxx_ack_irq_timer, - [IRQ_TIMER2] = ns9xxx_ack_irq_timer, - [IRQ_TIMER3] = ns9xxx_ack_irq_timer, -}; - static void ns9xxx_mask_irq(unsigned int irq) { /* XXX: better use cpp symbols */ - SYS_IC(irq / 4) &= ~(1 << (7 + 8 * (3 - (irq & 3)))); + u32 ic = __raw_readl(SYS_IC(irq / 4)); + ic &= ~(1 << (7 + 8 * (3 - (irq & 3)))); + __raw_writel(ic, SYS_IC(irq / 4)); } static void ns9xxx_ack_irq(unsigned int irq) { - if (!ns9xxx_ack_irq_functions[irq]) { - printk(KERN_ERR "no ack function for irq %u\n", irq); - BUG(); - } - - ns9xxx_ack_irq_functions[irq](irq); - SYS_ISRADDR = 0; + __raw_writel(0, SYS_ISRADDR); } static void ns9xxx_maskack_irq(unsigned int irq) @@ -70,7 +40,9 @@ static void ns9xxx_maskack_irq(unsigned int irq) static void ns9xxx_unmask_irq(unsigned int irq) { /* XXX: better use cpp symbols */ - SYS_IC(irq / 4) |= 1 << (7 + 8 * (3 - (irq & 3))); + u32 ic = __raw_readl(SYS_IC(irq / 4)); + ic |= 1 << (7 + 8 * (3 - (irq & 3))); + __raw_writel(ic, SYS_IC(irq / 4)); } static struct irq_chip ns9xxx_chip = { @@ -86,14 +58,14 @@ void __init ns9xxx_init_irq(void) /* disable all IRQs */ for (i = 0; i < 8; ++i) - SYS_IC(i) = (4 * i) << 24 | (4 * i + 1) << 16 | - (4 * i + 2) << 8 | (4 * i + 3); + __raw_writel((4 * i) << 24 | (4 * i + 1) << 16 | + (4 * i + 2) << 8 | (4 * i + 3), SYS_IC(i)); /* simple interrupt prio table: * prio(x) < prio(y) <=> x < y */ for (i = 0; i < 32; ++i) - SYS_IVA(i) = i; + __raw_writel(i, SYS_IVA(i)); for (i = IRQ_WATCHDOG; i <= IRQ_EXT3; ++i) { set_irq_chip(i, &ns9xxx_chip); diff --git a/arch/arm/mach-ns9xxx/time.c b/arch/arm/mach-ns9xxx/time.c index b97d0c54a388..c3dd1f4acb99 100644 --- a/arch/arm/mach-ns9xxx/time.c +++ b/arch/arm/mach-ns9xxx/time.c @@ -11,78 +11,174 @@ #include <linux/jiffies.h> #include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/stringify.h> +#include <linux/clocksource.h> +#include <linux/clockchips.h> + #include <asm/arch-ns9xxx/regs-sys.h> #include <asm/arch-ns9xxx/clock.h> #include <asm/arch-ns9xxx/irqs.h> #include <asm/arch/system.h> #include "generic.h" -#define TIMERCLOCKSELECT 64 +#define TIMER_CLOCKSOURCE 0 +#define TIMER_CLOCKEVENT 1 +static u32 latch; + +static cycle_t ns9xxx_clocksource_read(void) +{ + return __raw_readl(SYS_TR(TIMER_CLOCKSOURCE)); +} -static u32 usecs_per_tick; +static struct clocksource ns9xxx_clocksource = { + .name = "ns9xxx-timer" __stringify(TIMER_CLOCKSOURCE), + .rating = 300, + .read = ns9xxx_clocksource_read, + .mask = CLOCKSOURCE_MASK(32), + .shift = 20, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; -static irqreturn_t -ns9xxx_timer_interrupt(int irq, void *dev_id) +static void ns9xxx_clockevent_setmode(enum clock_event_mode mode, + struct clock_event_device *clk) { - write_seqlock(&xtime_lock); - timer_tick(); - write_sequnlock(&xtime_lock); + u32 tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT)); + + switch(mode) { + case CLOCK_EVT_MODE_PERIODIC: + __raw_writel(latch, SYS_TRC(TIMER_CLOCKEVENT)); + REGSET(tc, SYS_TCx, REN, EN); + REGSET(tc, SYS_TCx, INTS, EN); + REGSET(tc, SYS_TCx, TEN, EN); + break; + + case CLOCK_EVT_MODE_ONESHOT: + REGSET(tc, SYS_TCx, REN, DIS); + REGSET(tc, SYS_TCx, INTS, EN); + + /* fall through */ + + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_RESUME: + default: + REGSET(tc, SYS_TCx, TEN, DIS); + break; + } + + __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT)); +} - return IRQ_HANDLED; +static int ns9xxx_clockevent_setnextevent(unsigned long evt, + struct clock_event_device *clk) +{ + u32 tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT)); + + if (REGGET(tc, SYS_TCx, TEN)) { + REGSET(tc, SYS_TCx, TEN, DIS); + __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT)); + } + + REGSET(tc, SYS_TCx, TEN, EN); + + __raw_writel(evt, SYS_TRC(TIMER_CLOCKEVENT)); + + __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT)); + + return 0; } -static unsigned long ns9xxx_timer_gettimeoffset(void) +static struct clock_event_device ns9xxx_clockevent_device = { + .name = "ns9xxx-timer" __stringify(TIMER_CLOCKEVENT), + .shift = 20, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_mode = ns9xxx_clockevent_setmode, + .set_next_event = ns9xxx_clockevent_setnextevent, +}; + +static irqreturn_t ns9xxx_clockevent_handler(int irq, void *dev_id) { - /* return the microseconds which have passed since the last interrupt - * was _serviced_. That is, if an interrupt is pending or the counter - * reloads, return one period more. */ + int timerno = irq - IRQ_TIMER0; + u32 tc; - u32 counter1 = SYS_TR(0); - int pending = SYS_ISR & (1 << IRQ_TIMER0); - u32 counter2 = SYS_TR(0); - u32 elapsed; + struct clock_event_device *evt = &ns9xxx_clockevent_device; - if (pending || counter2 > counter1) - elapsed = 2 * SYS_TRC(0) - counter2; - else - elapsed = SYS_TRC(0) - counter1; + /* clear irq */ + tc = __raw_readl(SYS_TC(timerno)); + if (REGGET(tc, SYS_TCx, REN) == SYS_TCx_REN_DIS) { + REGSET(tc, SYS_TCx, TEN, DIS); + __raw_writel(tc, SYS_TC(timerno)); + } + REGSET(tc, SYS_TCx, INTC, SET); + __raw_writel(tc, SYS_TC(timerno)); + REGSET(tc, SYS_TCx, INTC, UNSET); + __raw_writel(tc, SYS_TC(timerno)); - return (elapsed * usecs_per_tick) >> 16; + evt->event_handler(evt); + return IRQ_HANDLED; } -static struct irqaction ns9xxx_timer_irq = { - .name = "NS9xxx Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = ns9xxx_timer_interrupt, +static struct irqaction ns9xxx_clockevent_action = { + .name = "ns9xxx-timer" __stringify(TIMER_CLOCKEVENT), + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = ns9xxx_clockevent_handler, }; static void __init ns9xxx_timer_init(void) { int tc; - usecs_per_tick = - SH_DIV(1000000 * TIMERCLOCKSELECT, ns9xxx_cpuclock(), 16); + tc = __raw_readl(SYS_TC(TIMER_CLOCKSOURCE)); + if (REGGET(tc, SYS_TCx, TEN)) { + REGSET(tc, SYS_TCx, TEN, DIS); + __raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE)); + } - /* disable timer */ - if ((tc = SYS_TC(0)) & SYS_TCx_TEN) - SYS_TC(0) = tc & ~SYS_TCx_TEN; - - SYS_TRC(0) = SH_DIV(ns9xxx_cpuclock(), (TIMERCLOCKSELECT * HZ), 0); + __raw_writel(0, SYS_TRC(TIMER_CLOCKSOURCE)); REGSET(tc, SYS_TCx, TEN, EN); - REGSET(tc, SYS_TCx, TLCS, DIV64); /* This must match TIMERCLOCKSELECT */ - REGSET(tc, SYS_TCx, INTS, EN); - REGSET(tc, SYS_TCx, UDS, DOWN); REGSET(tc, SYS_TCx, TDBG, STOP); + REGSET(tc, SYS_TCx, TLCS, CPU); + REGSET(tc, SYS_TCx, TM, IEE); + REGSET(tc, SYS_TCx, INTS, DIS); + REGSET(tc, SYS_TCx, UDS, UP); REGSET(tc, SYS_TCx, TSZ, 32); REGSET(tc, SYS_TCx, REN, EN); - SYS_TC(0) = tc; - setup_irq(IRQ_TIMER0, &ns9xxx_timer_irq); + __raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE)); + + ns9xxx_clocksource.mult = clocksource_hz2mult(ns9xxx_cpuclock(), + ns9xxx_clocksource.shift); + + clocksource_register(&ns9xxx_clocksource); + + latch = SH_DIV(ns9xxx_cpuclock(), HZ, 0); + + tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT)); + REGSET(tc, SYS_TCx, TEN, DIS); + REGSET(tc, SYS_TCx, TDBG, STOP); + REGSET(tc, SYS_TCx, TLCS, CPU); + REGSET(tc, SYS_TCx, TM, IEE); + REGSET(tc, SYS_TCx, INTS, DIS); + REGSET(tc, SYS_TCx, UDS, DOWN); + REGSET(tc, SYS_TCx, TSZ, 32); + REGSET(tc, SYS_TCx, REN, EN); + __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT)); + + ns9xxx_clockevent_device.mult = div_sc(ns9xxx_cpuclock(), + NSEC_PER_SEC, ns9xxx_clockevent_device.shift); + ns9xxx_clockevent_device.max_delta_ns = + clockevent_delta2ns(-1, &ns9xxx_clockevent_device); + ns9xxx_clockevent_device.min_delta_ns = + clockevent_delta2ns(1, &ns9xxx_clockevent_device); + + ns9xxx_clockevent_device.cpumask = cpumask_of_cpu(0); + clockevents_register_device(&ns9xxx_clockevent_device); + + setup_irq(IRQ_TIMER0 + TIMER_CLOCKEVENT, &ns9xxx_clockevent_action); } struct sys_timer ns9xxx_timer = { .init = ns9xxx_timer_init, - .offset = ns9xxx_timer_gettimeoffset, }; diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig index f6ecdd3a2478..79f0b1f8497b 100644 --- a/arch/arm/mach-omap1/Kconfig +++ b/arch/arm/mach-omap1/Kconfig @@ -84,11 +84,39 @@ config MACH_OMAP_PALMTE bool "Palm Tungsten E" depends on ARCH_OMAP1 && ARCH_OMAP15XX help - Support for the Palm Tungsten E PDA. Currently only the LCD panel - is supported. To boot the kernel, you'll need a PalmOS compatible - bootloader; check out http://palmtelinux.sourceforge.net for more - information. - Say Y here if you have such a PDA, say NO otherwise. + Support for the Palm Tungsten E PDA. To boot the kernel, you'll + need a PalmOS compatible bootloader; check out + http://palmtelinux.sourceforge.net/ for more information. + Say Y here if you have this PDA model, say N otherwise. + +config MACH_OMAP_PALMZ71 + bool "Palm Zire71" + depends on ARCH_OMAP1 && ARCH_OMAP15XX + help + Support for the Palm Zire71 PDA. To boot the kernel, + you'll need a PalmOS compatible bootloader; check out + http://hackndev.com/palm/z71 for more informations. + Say Y here if you have such a PDA, say N otherwise. + +config MACH_OMAP_PALMTT + bool "Palm Tungsten|T" + depends on ARCH_OMAP1 && ARCH_OMAP15XX + help + Support for the Palm Tungsten|T PDA. To boot the kernel, you'll + need a PalmOS compatible bootloader (Garux); check out + http://www.hackndev.com/palm/tt/ for more information. + Say Y here if you have this PDA model, say N otherwise. + +config MACH_SX1 + bool "Siemens SX1" + depends on ARCH_OMAP1 && ARCH_OMAP15XX + help + Support for the Siemens SX1 phone. To boot the kernel, + you'll need a SX1 compatible bootloader; check out + http://forum.oslik.ru and + http://www.handhelds.org/moin/moin.cgi/SiemensSX1 + for more information. + Say Y here if you have such a phone, say NO otherwise. config MACH_NOKIA770 bool "Nokia 770" diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index a8b9a00cea22..391b6f4827f6 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile @@ -22,8 +22,11 @@ obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o +obj-$(CONFIG_MACH_OMAP_PALMZ71) += board-palmz71.o +obj-$(CONFIG_MACH_OMAP_PALMTT) += board-palmtt.o obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o +obj-$(CONFIG_MACH_SX1) += board-sx1.o ifeq ($(CONFIG_ARCH_OMAP15XX),y) # Innovator-1510 FPGA diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 8437d065ada5..c73ca61e585e 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -14,6 +14,7 @@ #include <linux/kernel.h> #include <linux/init.h> +#include <linux/input.h> #include <linux/platform_device.h> #include <asm/hardware.h> @@ -23,6 +24,7 @@ #include <asm/arch/board-ams-delta.h> #include <asm/arch/gpio.h> +#include <asm/arch/keypad.h> #include <asm/arch/mux.h> #include <asm/arch/usb.h> #include <asm/arch/board.h> @@ -31,6 +33,86 @@ static u8 ams_delta_latch1_reg; static u16 ams_delta_latch2_reg; +static int ams_delta_keymap[] = { + KEY(0, 0, KEY_F1), /* Advert */ + + KEY(3, 0, KEY_COFFEE), /* Games */ + KEY(2, 0, KEY_QUESTION), /* Directory */ + KEY(3, 2, KEY_CONNECT), /* Internet */ + KEY(2, 1, KEY_SHOP), /* Services */ + KEY(1, 1, KEY_PHONE), /* VoiceMail */ + + KEY(1, 0, KEY_DELETE), /* Delete */ + KEY(2, 2, KEY_PLAY), /* Play */ + KEY(0, 1, KEY_PAGEUP), /* Up */ + KEY(3, 1, KEY_PAGEDOWN), /* Down */ + KEY(0, 2, KEY_EMAIL), /* ReadEmail */ + KEY(1, 2, KEY_STOP), /* Stop */ + + /* Numeric keypad portion */ + KEY(7, 0, KEY_KP1), + KEY(6, 0, KEY_KP2), + KEY(5, 0, KEY_KP3), + KEY(7, 1, KEY_KP4), + KEY(6, 1, KEY_KP5), + KEY(5, 1, KEY_KP6), + KEY(7, 2, KEY_KP7), + KEY(6, 2, KEY_KP8), + KEY(5, 2, KEY_KP9), + KEY(6, 3, KEY_KP0), + KEY(7, 3, KEY_KPASTERISK), + KEY(5, 3, KEY_KPDOT), /* # key */ + KEY(2, 7, KEY_NUMLOCK), /* Mute */ + KEY(1, 7, KEY_KPMINUS), /* Recall */ + KEY(1, 6, KEY_KPPLUS), /* Redial */ + KEY(6, 7, KEY_KPSLASH), /* Handsfree */ + KEY(0, 6, KEY_ENTER), /* Video */ + + KEY(4, 7, KEY_CAMERA), /* Photo */ + + KEY(4, 0, KEY_F2), /* Home */ + KEY(4, 1, KEY_F3), /* Office */ + KEY(4, 2, KEY_F4), /* Mobile */ + KEY(7, 7, KEY_F5), /* SMS */ + KEY(5, 7, KEY_F6), /* Email */ + + /* QWERTY portion of keypad */ + KEY(4, 3, KEY_Q), + KEY(3, 3, KEY_W), + KEY(2, 3, KEY_E), + KEY(1, 3, KEY_R), + KEY(0, 3, KEY_T), + KEY(7, 4, KEY_Y), + KEY(6, 4, KEY_U), + KEY(5, 4, KEY_I), + KEY(4, 4, KEY_O), + KEY(3, 4, KEY_P), + + KEY(2, 4, KEY_A), + KEY(1, 4, KEY_S), + KEY(0, 4, KEY_D), + KEY(7, 5, KEY_F), + KEY(6, 5, KEY_G), + KEY(5, 5, KEY_H), + KEY(4, 5, KEY_J), + KEY(3, 5, KEY_K), + KEY(2, 5, KEY_L), + + KEY(1, 5, KEY_Z), + KEY(0, 5, KEY_X), + KEY(7, 6, KEY_C), + KEY(6, 6, KEY_V), + KEY(5, 6, KEY_B), + KEY(4, 6, KEY_N), + KEY(3, 6, KEY_M), + KEY(2, 6, KEY_SPACE), + + KEY(0, 7, KEY_LEFTSHIFT), /* Vol up */ + KEY(3, 7, KEY_LEFTCTRL), /* Vol down */ + + 0 +}; + void ams_delta_latch1_write(u8 mask, u8 value) { ams_delta_latch1_reg &= ~mask; @@ -76,6 +158,10 @@ static struct map_desc ams_delta_io_desc[] __initdata = { } }; +static struct omap_lcd_config ams_delta_lcd_config __initdata = { + .ctrl_name = "internal", +}; + static struct omap_uart_config ams_delta_uart_config __initdata = { .enabled_uarts = 1, }; @@ -87,16 +173,50 @@ static struct omap_usb_config ams_delta_usb_config __initdata = { }; static struct omap_board_config_kernel ams_delta_config[] = { + { OMAP_TAG_LCD, &ams_delta_lcd_config }, { OMAP_TAG_UART, &ams_delta_uart_config }, { OMAP_TAG_USB, &ams_delta_usb_config }, }; +static struct resource ams_delta_kp_resources[] = { + [0] = { + .start = INT_KEYBOARD, + .end = INT_KEYBOARD, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct omap_kp_platform_data ams_delta_kp_data = { + .rows = 8, + .cols = 8, + .keymap = ams_delta_keymap, + .keymapsize = ARRAY_SIZE(ams_delta_keymap), + .delay = 9, +}; + +static struct platform_device ams_delta_kp_device = { + .name = "omap-keypad", + .id = -1, + .dev = { + .platform_data = &ams_delta_kp_data, + }, + .num_resources = ARRAY_SIZE(ams_delta_kp_resources), + .resource = ams_delta_kp_resources, +}; + +static struct platform_device ams_delta_lcd_device = { + .name = "lcd_ams_delta", + .id = -1, +}; + static struct platform_device ams_delta_led_device = { .name = "ams-delta-led", .id = -1 }; static struct platform_device *ams_delta_devices[] __initdata = { + &ams_delta_kp_device, + &ams_delta_lcd_device, &ams_delta_led_device, }; diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 48c8c9195dc3..b0921622566f 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -20,22 +20,23 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/delay.h> +#include <linux/i2c.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> #include <linux/input.h> -#include <linux/workqueue.h> #include <asm/hardware.h> +#include <asm/gpio.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h> #include <asm/mach/map.h> -#include <asm/arch/gpio.h> +#include <asm/arch/tps65010.h> #include <asm/arch/mux.h> #include <asm/arch/tc.h> #include <asm/arch/irda.h> @@ -139,6 +140,66 @@ static struct platform_device h2_nor_device = { .resource = &h2_nor_resource, }; +#if 0 /* REVISIT: Enable when nand_platform_data is applied */ + +static struct mtd_partition h2_nand_partitions[] = { +#if 0 + /* REVISIT: enable these partitions if you make NAND BOOT + * work on your H2 (rev C or newer); published versions of + * x-load only support P2 and H3. + */ + { + .name = "xloader", + .offset = 0, + .size = 64 * 1024, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "bootloader", + .offset = MTDPART_OFS_APPEND, + .size = 256 * 1024, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = 192 * 1024, + }, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = 2 * SZ_1M, + }, +#endif + { + .name = "filesystem", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + }, +}; + +/* dip switches control NAND chip access: 8 bit, 16 bit, or neither */ +static struct nand_platform_data h2_nand_data = { + .options = NAND_SAMSUNG_LP_OPTIONS, + .parts = h2_nand_partitions, + .nr_parts = ARRAY_SIZE(h2_nand_partitions), +}; + +static struct resource h2_nand_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device h2_nand_device = { + .name = "omapnand", + .id = 0, + .dev = { + .platform_data = &h2_nand_data, + }, + .num_resources = 1, + .resource = &h2_nand_resource, +}; +#endif + static struct resource h2_smc91x_resources[] = { [0] = { .start = OMAP1610_ETHR_START, /* Physical */ @@ -218,11 +279,15 @@ static struct resource h2_irda_resources[] = { .flags = IORESOURCE_IRQ, }, }; + +static u64 irda_dmamask = 0xffffffff; + static struct platform_device h2_irda_device = { .name = "omapirda", .id = 0, .dev = { .platform_data = &h2_irda_data, + .dma_mask = &irda_dmamask, }, .num_resources = ARRAY_SIZE(h2_irda_resources), .resource = h2_irda_resources, @@ -270,6 +335,7 @@ static struct platform_device h2_mcbsp1_device = { static struct platform_device *h2_devices[] __initdata = { &h2_nor_device, + //&h2_nand_device, &h2_smc91x_device, &h2_irda_device, &h2_kp_device, @@ -277,6 +343,20 @@ static struct platform_device *h2_devices[] __initdata = { &h2_mcbsp1_device, }; +static struct i2c_board_info __initdata h2_i2c_board_info[] = { + { + I2C_BOARD_INFO("tps65010", 0x48), + .type = "tps65010", + .irq = OMAP_GPIO_IRQ(58), + }, + /* TODO when driver support is ready: + * - isp1301 OTG transceiver + * - optional ov9640 camera sensor at 0x30 + * - pcf9754 for aGPS control + * - ... etc + */ +}; + static void __init h2_init_smc91x(void) { if ((omap_request_gpio(0)) < 0) { @@ -333,6 +413,13 @@ static struct omap_board_config_kernel h2_config[] __initdata = { { OMAP_TAG_LCD, &h2_lcd_config }, }; +#define H2_NAND_RB_GPIO_PIN 62 + +static int h2_nand_dev_ready(struct nand_platform_data *data) +{ + return omap_get_gpio_datain(H2_NAND_RB_GPIO_PIN); +} + static void __init h2_init(void) { /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped @@ -347,6 +434,13 @@ static void __init h2_init(void) h2_nor_resource.end = h2_nor_resource.start = omap_cs3_phys(); h2_nor_resource.end += SZ_32M - 1; +#if 0 /* REVISIT: Enable when nand_platform_data is applied */ + h2_nand_resource.end = h2_nand_resource.start = OMAP_CS2B_PHYS; + h2_nand_resource.end += SZ_4K - 1; + if (!(omap_request_gpio(H2_NAND_RB_GPIO_PIN))) + h2_nand_data.dev_ready = h2_nand_dev_ready; +#endif + omap_cfg_reg(L3_1610_FLASH_CS2B_OE); omap_cfg_reg(M8_1610_FLASH_CS2B_WE); @@ -367,6 +461,14 @@ static void __init h2_init(void) omap_board_config = h2_config; omap_board_config_size = ARRAY_SIZE(h2_config); omap_serial_init(); + + /* irq for tps65010 chip */ + omap_cfg_reg(W4_GPIO58); + if (gpio_request(58, "tps65010") == 0) + gpio_direction_input(58); + + i2c_register_board_info(1, h2_i2c_board_info, + ARRAY_SIZE(h2_i2c_board_info)); } static void __init h2_map_io(void) @@ -374,6 +476,22 @@ static void __init h2_map_io(void) omap1_map_common_io(); } +#ifdef CONFIG_TPS65010 +static int __init h2_tps_init(void) +{ + if (!machine_is_omap_h2()) + return 0; + + /* gpio3 for SD, gpio4 for VDD_DSP */ + /* FIXME send power to DSP iff it's configured */ + + /* Enable LOW_PWR */ + tps65010_set_low_pwr(ON); + return 0; +} +fs_initcall(h2_tps_init); +#endif + MACHINE_START(OMAP_H2, "TI-H2") /* Maintainer: Imre Deak <imre.deak@nokia.com> */ .phys_io = 0xfff00000, diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 79d4ef4c54d4..4f84ae273a1f 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -21,6 +21,7 @@ #include <linux/platform_device.h> #include <linux/errno.h> #include <linux/workqueue.h> +#include <linux/i2c.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> @@ -29,12 +30,14 @@ #include <asm/setup.h> #include <asm/page.h> #include <asm/hardware.h> +#include <asm/gpio.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h> #include <asm/mach/map.h> -#include <asm/arch/gpio.h> +#include <asm/arch/tps65010.h> #include <asm/arch/gpioexpander.h> #include <asm/arch/irqs.h> #include <asm/arch/mux.h> @@ -44,6 +47,8 @@ #include <asm/arch/keypad.h> #include <asm/arch/dma.h> #include <asm/arch/common.h> +#include <asm/arch/mcbsp.h> +#include <asm/arch/omap-alsa.h> extern int omap_gpio_init(void); @@ -351,11 +356,14 @@ static struct resource h3_irda_resources[] = { }, }; +static u64 irda_dmamask = 0xffffffff; + static struct platform_device h3_irda_device = { .name = "omapirda", .id = 0, .dev = { .platform_data = &h3_irda_data, + .dma_mask = &irda_dmamask, }, .num_resources = ARRAY_SIZE(h3_irda_resources), .resource = h3_irda_resources, @@ -366,6 +374,41 @@ static struct platform_device h3_lcd_device = { .id = -1, }; +static struct omap_mcbsp_reg_cfg mcbsp_regs = { + .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), + .spcr1 = RINTM(3) | RRST, + .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | + RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(1), + .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), + .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | + XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(1) | XFIG, + .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), + .srgr1 = FWID(15), + .srgr2 = GSYNC | CLKSP | FSGM | FPER(31), + + .pcr0 = CLKRM | SCLKME | FSXP | FSRP | CLKXP | CLKRP, + //.pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ +}; + +static struct omap_alsa_codec_config alsa_config = { + .name = "H3 TSC2101", + .mcbsp_regs_alsa = &mcbsp_regs, + .codec_configure_dev = NULL, // tsc2101_configure, + .codec_set_samplerate = NULL, // tsc2101_set_samplerate, + .codec_clock_setup = NULL, // tsc2101_clock_setup, + .codec_clock_on = NULL, // tsc2101_clock_on, + .codec_clock_off = NULL, // tsc2101_clock_off, + .get_default_samplerate = NULL, // tsc2101_get_default_samplerate, +}; + +static struct platform_device h3_mcbsp1_device = { + .name = "omap_alsa_mcbsp", + .id = 1, + .dev = { + .platform_data = &alsa_config, + }, +}; + static struct platform_device *devices[] __initdata = { &nor_device, &nand_device, @@ -374,6 +417,7 @@ static struct platform_device *devices[] __initdata = { &h3_irda_device, &h3_kp_device, &h3_lcd_device, + &h3_mcbsp1_device, }; static struct omap_usb_config h3_usb_config __initdata = { @@ -413,6 +457,19 @@ static struct omap_board_config_kernel h3_config[] = { { OMAP_TAG_LCD, &h3_lcd_config }, }; +static struct i2c_board_info __initdata h3_i2c_board_info[] = { + { + I2C_BOARD_INFO("tps65010", 0x48), + .type = "tps65013", + /* .irq = OMAP_GPIO_IRQ(??), */ + }, + /* TODO when driver support is ready: + * - isp1301 OTG transceiver + * - optional ov9640 camera sensor at 0x30 + * - ... + */ +}; + #define H3_NAND_RB_GPIO_PIN 10 static int nand_dev_ready(struct nand_platform_data *data) @@ -446,6 +503,10 @@ static void __init h3_init(void) omap_board_config = h3_config; omap_board_config_size = ARRAY_SIZE(h3_config); omap_serial_init(); + + /* FIXME setup irq for tps65013 chip */ + i2c_register_board_info(1, h3_i2c_board_info, + ARRAY_SIZE(h3_i2c_board_info)); } static void __init h3_init_smc91x(void) @@ -470,6 +531,23 @@ static void __init h3_map_io(void) omap1_map_common_io(); } +#ifdef CONFIG_TPS65010 +static int __init h3_tps_init(void) +{ + if (!machine_is_omap_h3()) + return 0; + + /* gpio4 for SD, gpio3 for VDD_DSP */ + /* FIXME send power to DSP iff it's configured */ + + /* Enable LOW_PWR */ + tps65013_set_low_pwr(ON); + + return 0; +} +fs_initcall(h3_tps_init); +#endif + MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") /* Maintainer: Texas Instruments, Inc. */ .phys_io = 0xfff00000, diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 70014f751bc4..22db19a53647 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -33,6 +33,12 @@ #include <asm/arch/dsp_common.h> #include <asm/arch/aic23.h> #include <asm/arch/gpio.h> +#include <asm/arch/omapfb.h> +#include <asm/arch/lcd_mipid.h> + +#include "../plat-omap/dsp/dsp_common.h" + +#define ADS7846_PENDOWN_GPIO 15 static void __init omap_nokia770_init_irq(void) { @@ -91,9 +97,44 @@ static struct platform_device nokia770_kp_device = { }; static struct platform_device *nokia770_devices[] __initdata = { - &nokia770_kp_device, + &nokia770_kp_device, +}; + +static void mipid_shutdown(struct mipid_platform_data *pdata) +{ + if (pdata->nreset_gpio != -1) { + printk(KERN_INFO "shutdown LCD\n"); + omap_set_gpio_dataout(pdata->nreset_gpio, 0); + msleep(120); + } +} + +static struct mipid_platform_data nokia770_mipid_platform_data = { + .shutdown = mipid_shutdown, }; +static void mipid_dev_init(void) +{ + const struct omap_lcd_config *conf; + + conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config); + if (conf != NULL) { + nokia770_mipid_platform_data.nreset_gpio = conf->nreset_gpio; + nokia770_mipid_platform_data.data_lines = conf->data_lines; + } +} + +static void ads7846_dev_init(void) +{ + if (omap_request_gpio(ADS7846_PENDOWN_GPIO) < 0) + printk(KERN_ERR "can't get ads7846 pen down GPIO\n"); +} + +static int ads7846_get_pendown_state(void) +{ + return !omap_get_gpio_datain(ADS7846_PENDOWN_GPIO); +} + static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = { .x_max = 0x0fff, .y_max = 0x0fff, @@ -101,14 +142,17 @@ static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = .pressure_max = 255, .debounce_max = 10, .debounce_tol = 3, + .debounce_rep = 1, + .get_pendown_state = ads7846_get_pendown_state, }; static struct spi_board_info nokia770_spi_board_info[] __initdata = { [0] = { - .modalias = "lcd_mipid", + .modalias = "lcd_mipid", .bus_num = 2, .chip_select = 3, .max_speed_hz = 12000000, + .platform_data = &nokia770_mipid_platform_data, }, [1] = { .modalias = "ads7846", @@ -153,6 +197,7 @@ static struct omap_board_config_kernel nokia770_config[] = { { OMAP_TAG_MMC, &nokia770_mmc_config }, }; +#if defined(CONFIG_OMAP_DSP) /* * audio power control */ @@ -183,7 +228,7 @@ static void nokia770_audio_pwr_up(void) clk_enable(dspxor_ck); /* Turn on codec */ - tlv320aic23_power_up(); + aic23_power_up(); if (omap_get_gpio_datain(HEADPHONE_GPIO)) /* HP not connected, turn on amplifier */ @@ -197,7 +242,7 @@ static void codec_delayed_power_down(struct work_struct *work) { down(&audio_pwr_sem); if (audio_pwr_state == -1) - tlv320aic23_power_down(); + aic23_power_down(); clk_disable(dspxor_ck); up(&audio_pwr_sem); } @@ -213,7 +258,8 @@ static void nokia770_audio_pwr_down(void) schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */ } -void nokia770_audio_pwr_up_request(int stage) +static int +nokia770_audio_pwr_up_request(struct dsp_kfunc_device *kdev, int stage) { down(&audio_pwr_sem); if (audio_pwr_state == -1) @@ -221,9 +267,11 @@ void nokia770_audio_pwr_up_request(int stage) /* force audio_pwr_state = 0, even if it was 1. */ audio_pwr_state = 0; up(&audio_pwr_sem); + return 0; } -void nokia770_audio_pwr_down_request(int stage) +static int +nokia770_audio_pwr_down_request(struct dsp_kfunc_device *kdev, int stage) { down(&audio_pwr_sem); switch (stage) { @@ -239,8 +287,39 @@ void nokia770_audio_pwr_down_request(int stage) break; } up(&audio_pwr_sem); + return 0; } +static struct dsp_kfunc_device nokia770_audio_device = { + .name = "audio", + .type = DSP_KFUNC_DEV_TYPE_AUDIO, + .enable = nokia770_audio_pwr_up_request, + .disable = nokia770_audio_pwr_down_request, +}; + +static __init int omap_dsp_init(void) +{ + int ret; + + dspxor_ck = clk_get(0, "dspxor_ck"); + if (IS_ERR(dspxor_ck)) { + printk(KERN_ERR "couldn't acquire dspxor_ck\n"); + return PTR_ERR(dspxor_ck); + } + + ret = dsp_kfunc_device_register(&nokia770_audio_device); + if (ret) { + printk(KERN_ERR + "KFUNC device registration faild: %s\n", + nokia770_audio_device.name); + goto out; + } + return 0; + out: + return ret; +} +#endif /* CONFIG_OMAP_DSP */ + static void __init omap_nokia770_init(void) { nokia770_config[0].data = &nokia770_usb_config; @@ -250,10 +329,11 @@ static void __init omap_nokia770_init(void) ARRAY_SIZE(nokia770_spi_board_info)); omap_board_config = nokia770_config; omap_board_config_size = ARRAY_SIZE(nokia770_config); + omap_gpio_init(); omap_serial_init(); - omap_dsp_audio_pwr_up_request = nokia770_audio_pwr_up_request; - omap_dsp_audio_pwr_down_request = nokia770_audio_pwr_down_request; - dspxor_ck = clk_get(0, "dspxor_ck"); + omap_dsp_init(); + ads7846_dev_init(); + mipid_dev_init(); } static void __init omap_nokia770_map_io(void) diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index e7130293a03f..5db182da322b 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -29,20 +29,24 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> +#include <linux/interrupt.h> #include <linux/irq.h> #include <linux/interrupt.h> +#include <linux/i2c.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <asm/hardware.h> +#include <asm/gpio.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/flash.h> -#include <asm/arch/gpio.h> #include <asm/arch/usb.h> +#include <asm/arch/tps65010.h> #include <asm/arch/mux.h> #include <asm/arch/tc.h> #include <asm/arch/common.h> @@ -179,6 +183,19 @@ static struct platform_device *osk5912_devices[] __initdata = { &osk5912_mcbsp1_device, }; +static struct i2c_board_info __initdata osk_i2c_board_info[] = { + { + I2C_BOARD_INFO("tps65010", 0x48), + .type = "tps65010", + .irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1)), + }, + /* TODO when driver support is ready: + * - aic23 audio chip at 0x1a + * - on Mistral, 24c04 eeprom at 0x50 + * - optionally on Mistral, ov9640 camera sensor at 0x30 + */ +}; + static void __init osk_init_smc91x(void) { if ((omap_request_gpio(0)) < 0) { @@ -292,6 +309,18 @@ static struct platform_device osk5912_kp_device = { .resource = osk5912_kp_resources, }; +static struct omap_backlight_config mistral_bl_data = { + .default_intensity = 0xa0, +}; + +static struct platform_device mistral_bl_device = { + .name = "omap-bl", + .id = -1, + .dev = { + .platform_data = &mistral_bl_data, + }, +}; + static struct platform_device osk5912_lcd_device = { .name = "lcd_osk", .id = -1, @@ -299,6 +328,7 @@ static struct platform_device osk5912_lcd_device = { static struct platform_device *mistral_devices[] __initdata = { &osk5912_kp_device, + &mistral_bl_device, &osk5912_lcd_device, }; @@ -342,6 +372,38 @@ static void __init osk_mistral_init(void) * can't talk to the ads or even the i2c eeprom. */ + /* parallel camera interface */ + omap_cfg_reg(J15_1610_CAM_LCLK); + omap_cfg_reg(J18_1610_CAM_D7); + omap_cfg_reg(J19_1610_CAM_D6); + omap_cfg_reg(J14_1610_CAM_D5); + omap_cfg_reg(K18_1610_CAM_D4); + omap_cfg_reg(K19_1610_CAM_D3); + omap_cfg_reg(K15_1610_CAM_D2); + omap_cfg_reg(K14_1610_CAM_D1); + omap_cfg_reg(L19_1610_CAM_D0); + omap_cfg_reg(L18_1610_CAM_VS); + omap_cfg_reg(L15_1610_CAM_HS); + omap_cfg_reg(M19_1610_CAM_RSTZ); + omap_cfg_reg(Y15_1610_CAM_OUTCLK); + + /* serial camera interface */ + omap_cfg_reg(H19_1610_CAM_EXCLK); + omap_cfg_reg(W13_1610_CCP_CLKM); + omap_cfg_reg(Y12_1610_CCP_CLKP); + /* CCP_DATAM CONFLICTS WITH UART1.TX (and serial console) */ + // omap_cfg_reg(Y14_1610_CCP_DATAM); + omap_cfg_reg(W14_1610_CCP_DATAP); + + /* CAM_PWDN */ + if (omap_request_gpio(11) == 0) { + omap_cfg_reg(N20_1610_GPIO11); + omap_set_gpio_direction(11, 0 /* out */); + omap_set_gpio_dataout(11, 0 /* off */); + } else + pr_debug("OSK+Mistral: CAM_PWDN is awol\n"); + + // omap_cfg_reg(P19_1610_GPIO6); // BUSY omap_cfg_reg(P20_1610_GPIO4); // PENIRQ set_irq_type(OMAP_GPIO_IRQ(4), IRQT_FALLING); @@ -372,6 +434,15 @@ static void __init osk_mistral_init(void) } else printk(KERN_ERR "OSK+Mistral: wakeup button is awol\n"); + /* LCD: backlight, and power; power controls other devices on the + * board, like the touchscreen, EEPROM, and wakeup (!) switch. + */ + omap_cfg_reg(PWL); + if (omap_request_gpio(2) == 0) { + omap_set_gpio_direction(2, 0 /* out */); + omap_set_gpio_dataout(2, 1 /* on */); + } + platform_add_devices(mistral_devices, ARRAY_SIZE(mistral_devices)); } #else @@ -397,6 +468,14 @@ static void __init osk_init(void) omap_board_config_size = ARRAY_SIZE(osk_config); USB_TRANSCEIVER_CTRL_REG |= (3 << 1); + /* irq for tps65010 chip */ + /* bootloader effectively does: omap_cfg_reg(U19_1610_MPUIO1); */ + if (gpio_request(OMAP_MPUIO(1), "tps65010") == 0) + gpio_direction_input(OMAP_MPUIO(1)); + + i2c_register_board_info(1, osk_i2c_board_info, + ARRAY_SIZE(osk_i2c_board_info)); + omap_serial_init(); osk_mistral_init(); } @@ -406,6 +485,44 @@ static void __init osk_map_io(void) omap1_map_common_io(); } +#ifdef CONFIG_TPS65010 +static int __init osk_tps_init(void) +{ + if (!machine_is_omap_osk()) + return 0; + + /* Let LED1 (D9) blink */ + tps65010_set_led(LED1, BLINK); + + /* Disable LED 2 (D2) */ + tps65010_set_led(LED2, OFF); + + /* Set GPIO 1 HIGH to disable VBUS power supply; + * OHCI driver powers it up/down as needed. + */ + tps65010_set_gpio_out_value(GPIO1, HIGH); + + /* Set GPIO 2 low to turn on LED D3 */ + tps65010_set_gpio_out_value(GPIO2, HIGH); + + /* Set GPIO 3 low to take ethernet out of reset */ + tps65010_set_gpio_out_value(GPIO3, LOW); + + /* gpio4 for VDD_DSP */ + /* FIXME send power to DSP iff it's configured */ + + /* Enable LOW_PWR */ + tps65010_set_low_pwr(ON); + + /* Switch VLDO2 to 3.0V for AIC23 */ + tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V + | TPS_LDO1_ENABLE); + + return 0; +} +fs_initcall(osk_tps_init); +#endif + MACHINE_START(OMAP_OSK, "TI-OSK") /* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */ .phys_io = 0xfff00000, diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 015824185629..2f9d00a00135 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -17,49 +17,189 @@ #include <linux/kernel.h> #include <linux/init.h> +#include <linux/input.h> #include <linux/platform_device.h> -#include <linux/notifier.h> -#include <linux/clk.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/spi/spi.h> +#include <linux/spi/tsc2102.h> +#include <linux/interrupt.h> +#include <asm/apm.h> #include <asm/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/mach/flash.h> #include <asm/arch/gpio.h> #include <asm/arch/mux.h> #include <asm/arch/usb.h> +#include <asm/arch/tc.h> +#include <asm/arch/dma.h> #include <asm/arch/board.h> +#include <asm/arch/irda.h> +#include <asm/arch/keypad.h> #include <asm/arch/common.h> +#include <asm/arch/mcbsp.h> +#include <asm/arch/omap-alsa.h> -static void __init omap_generic_init_irq(void) +static void __init omap_palmte_init_irq(void) { omap1_init_common_hw(); omap_init_irq(); + omap_gpio_init(); } +static int palmte_keymap[] = { + KEY(0, 0, KEY_F1), + KEY(0, 1, KEY_F2), + KEY(0, 2, KEY_F3), + KEY(0, 3, KEY_F4), + KEY(0, 4, KEY_POWER), + KEY(1, 0, KEY_LEFT), + KEY(1, 1, KEY_DOWN), + KEY(1, 2, KEY_UP), + KEY(1, 3, KEY_RIGHT), + KEY(1, 4, KEY_CENTER), + 0, +}; + +static struct omap_kp_platform_data palmte_kp_data = { + .rows = 8, + .cols = 8, + .keymap = palmte_keymap, + .rep = 1, + .delay = 12, +}; + +static struct resource palmte_kp_resources[] = { + [0] = { + .start = INT_KEYBOARD, + .end = INT_KEYBOARD, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device palmte_kp_device = { + .name = "omap-keypad", + .id = -1, + .dev = { + .platform_data = &palmte_kp_data, + }, + .num_resources = ARRAY_SIZE(palmte_kp_resources), + .resource = palmte_kp_resources, +}; + +static struct mtd_partition palmte_rom_partitions[] = { + /* PalmOS "Small ROM", contains the bootloader and the debugger */ + { + .name = "smallrom", + .offset = 0, + .size = 0xa000, + .mask_flags = MTD_WRITEABLE, + }, + /* PalmOS "Big ROM", a filesystem with all the OS code and data */ + { + .name = "bigrom", + .offset = SZ_128K, + /* + * 0x5f0000 bytes big in the multi-language ("EFIGS") version, + * 0x7b0000 bytes in the English-only ("enUS") version. + */ + .size = 0x7b0000, + .mask_flags = MTD_WRITEABLE, + }, +}; + +static struct flash_platform_data palmte_rom_data = { + .map_name = "map_rom", + .width = 2, + .parts = palmte_rom_partitions, + .nr_parts = ARRAY_SIZE(palmte_rom_partitions), +}; + +static struct resource palmte_rom_resource = { + .start = OMAP_CS0_PHYS, + .end = OMAP_CS0_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device palmte_rom_device = { + .name = "omapflash", + .id = -1, + .dev = { + .platform_data = &palmte_rom_data, + }, + .num_resources = 1, + .resource = &palmte_rom_resource, +}; + static struct platform_device palmte_lcd_device = { .name = "lcd_palmte", .id = -1, }; +static struct omap_backlight_config palmte_backlight_config = { + .default_intensity = 0xa0, +}; + +static struct platform_device palmte_backlight_device = { + .name = "omap-bl", + .id = -1, + .dev = { + .platform_data = &palmte_backlight_config, + }, +}; + +static struct omap_irda_config palmte_irda_config = { + .transceiver_cap = IR_SIRMODE, + .rx_channel = OMAP_DMA_UART3_RX, + .tx_channel = OMAP_DMA_UART3_TX, + .dest_start = UART3_THR, + .src_start = UART3_RHR, + .tx_trigger = 0, + .rx_trigger = 0, +}; + +static struct resource palmte_irda_resources[] = { + [0] = { + .start = INT_UART3, + .end = INT_UART3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device palmte_irda_device = { + .name = "omapirda", + .id = -1, + .dev = { + .platform_data = &palmte_irda_config, + }, + .num_resources = ARRAY_SIZE(palmte_irda_resources), + .resource = palmte_irda_resources, +}; + static struct platform_device *devices[] __initdata = { + &palmte_rom_device, + &palmte_kp_device, &palmte_lcd_device, + &palmte_backlight_device, + &palmte_irda_device, }; static struct omap_usb_config palmte_usb_config __initdata = { - .register_dev = 1, + .register_dev = 1, /* Mini-B only receptacle */ .hmc_mode = 0, - .pins[0] = 3, + .pins[0] = 2, }; static struct omap_mmc_config palmte_mmc_config __initdata = { - .mmc [0] = { + .mmc[0] = { .enabled = 1, - .wire4 = 1, - .wp_pin = OMAP_MPUIO(3), - .power_pin = -1, - .switch_pin = -1, + .wp_pin = PALMTE_MMC_WP_GPIO, + .power_pin = PALMTE_MMC_POWER_GPIO, + .switch_pin = PALMTE_MMC_SWITCH_GPIO, }, }; @@ -67,21 +207,222 @@ static struct omap_lcd_config palmte_lcd_config __initdata = { .ctrl_name = "internal", }; +static struct omap_uart_config palmte_uart_config __initdata = { + .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2), +}; + +static struct omap_mcbsp_reg_cfg palmte_mcbsp1_regs = { + .spcr2 = FRST | GRST | XRST | XINTM(3), + .xcr2 = XDATDLY(1) | XFIG, + .xcr1 = XWDLEN1(OMAP_MCBSP_WORD_32), + .pcr0 = SCLKME | FSXP | CLKXP, +}; + +static struct omap_alsa_codec_config palmte_alsa_config = { + .name = "TSC2102 audio", + .mcbsp_regs_alsa = &palmte_mcbsp1_regs, + .codec_configure_dev = NULL, /* tsc2102_configure, */ + .codec_set_samplerate = NULL, /* tsc2102_set_samplerate, */ + .codec_clock_setup = NULL, /* tsc2102_clock_setup, */ + .codec_clock_on = NULL, /* tsc2102_clock_on, */ + .codec_clock_off = NULL, /* tsc2102_clock_off, */ + .get_default_samplerate = NULL, /* tsc2102_get_default_samplerate, */ +}; + +#ifdef CONFIG_APM +/* + * Values measured in 10 minute intervals averaged over 10 samples. + * May differ slightly from device to device but should be accurate + * enough to give basic idea of battery life left and trigger + * potential alerts. + */ +static const int palmte_battery_sample[] = { + 2194, 2157, 2138, 2120, + 2104, 2089, 2075, 2061, + 2048, 2038, 2026, 2016, + 2008, 1998, 1989, 1980, + 1970, 1958, 1945, 1928, + 1910, 1888, 1860, 1827, + 1791, 1751, 1709, 1656, +}; + +#define INTERVAL 10 +#define BATTERY_HIGH_TRESHOLD 66 +#define BATTERY_LOW_TRESHOLD 33 + +static void palmte_get_power_status(struct apm_power_info *info, int *battery) +{ + int charging, batt, hi, lo, mid; + + charging = !omap_get_gpio_datain(PALMTE_DC_GPIO); + batt = battery[0]; + if (charging) + batt -= 60; + + hi = ARRAY_SIZE(palmte_battery_sample); + lo = 0; + + info->battery_flag = 0; + info->units = APM_UNITS_MINS; + + if (batt > palmte_battery_sample[lo]) { + info->battery_life = 100; + info->time = INTERVAL * ARRAY_SIZE(palmte_battery_sample); + } else if (batt <= palmte_battery_sample[hi - 1]) { + info->battery_life = 0; + info->time = 0; + } else { + while (hi > lo + 1) { + mid = (hi + lo) >> 2; + if (batt <= palmte_battery_sample[mid]) + lo = mid; + else + hi = mid; + } + + mid = palmte_battery_sample[lo] - palmte_battery_sample[hi]; + hi = palmte_battery_sample[lo] - batt; + info->battery_life = 100 - (100 * lo + 100 * hi / mid) / + ARRAY_SIZE(palmte_battery_sample); + info->time = INTERVAL * (ARRAY_SIZE(palmte_battery_sample) - + lo) - INTERVAL * hi / mid; + } + + if (charging) { + info->ac_line_status = APM_AC_ONLINE; + info->battery_status = APM_BATTERY_STATUS_CHARGING; + info->battery_flag |= APM_BATTERY_FLAG_CHARGING; + } else { + info->ac_line_status = APM_AC_OFFLINE; + if (info->battery_life > BATTERY_HIGH_TRESHOLD) + info->battery_status = APM_BATTERY_STATUS_HIGH; + else if (info->battery_life > BATTERY_LOW_TRESHOLD) + info->battery_status = APM_BATTERY_STATUS_LOW; + else + info->battery_status = APM_BATTERY_STATUS_CRITICAL; + } + + if (info->battery_life > BATTERY_HIGH_TRESHOLD) + info->battery_flag |= APM_BATTERY_FLAG_HIGH; + else if (info->battery_life > BATTERY_LOW_TRESHOLD) + info->battery_flag |= APM_BATTERY_FLAG_LOW; + else + info->battery_flag |= APM_BATTERY_FLAG_CRITICAL; +} +#else +#define palmte_get_power_status NULL +#endif + +static struct tsc2102_config palmte_tsc2102_config = { + .use_internal = 0, + .monitor = TSC_BAT1 | TSC_AUX | TSC_TEMP, + .temp_at25c = { 2200, 2615 }, + .apm_report = palmte_get_power_status, + .alsa_config = &palmte_alsa_config, +}; + static struct omap_board_config_kernel palmte_config[] = { - { OMAP_TAG_USB, &palmte_usb_config }, - { OMAP_TAG_MMC, &palmte_mmc_config }, - { OMAP_TAG_LCD, &palmte_lcd_config }, + { OMAP_TAG_USB, &palmte_usb_config }, + { OMAP_TAG_MMC, &palmte_mmc_config }, + { OMAP_TAG_LCD, &palmte_lcd_config }, + { OMAP_TAG_UART, &palmte_uart_config }, }; -static void __init omap_generic_init(void) +static struct spi_board_info palmte_spi_info[] __initdata = { + { + .modalias = "tsc2102", + .bus_num = 2, /* uWire (officially) */ + .chip_select = 0, /* As opposed to 3 */ + .irq = OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO), + .platform_data = &palmte_tsc2102_config, + .max_speed_hz = 8000000, + }, +}; + +/* Periodically check for changes on important input pins */ +struct timer_list palmte_pin_timer; +int prev_power, prev_headphones; + +static void palmte_pin_handler(unsigned long data) { + int power, headphones; + + power = !omap_get_gpio_datain(PALMTE_DC_GPIO); + headphones = omap_get_gpio_datain(PALMTE_HEADPHONES_GPIO); + + if (power && !prev_power) + printk(KERN_INFO "PM: cable connected\n"); + else if (!power && prev_power) + printk(KERN_INFO "PM: cable disconnected\n"); + + if (headphones && !prev_headphones) { + /* Headphones connected, disable speaker */ + omap_set_gpio_dataout(PALMTE_SPEAKER_GPIO, 0); + printk(KERN_INFO "PM: speaker off\n"); + } else if (!headphones && prev_headphones) { + /* Headphones unplugged, re-enable speaker */ + omap_set_gpio_dataout(PALMTE_SPEAKER_GPIO, 1); + printk(KERN_INFO "PM: speaker on\n"); + } + + prev_power = power; + prev_headphones = headphones; + mod_timer(&palmte_pin_timer, jiffies + msecs_to_jiffies(500)); +} + +static void __init palmte_gpio_setup(void) +{ + /* Set TSC2102 PINTDAV pin as input */ + if (omap_request_gpio(PALMTE_PINTDAV_GPIO)) { + printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n"); + return; + } + omap_set_gpio_direction(PALMTE_PINTDAV_GPIO, 1); + + /* Monitor cable-connected signals */ + if (omap_request_gpio(PALMTE_DC_GPIO) || + omap_request_gpio(PALMTE_USB_OR_DC_GPIO) || + omap_request_gpio(PALMTE_USBDETECT_GPIO)) { + printk(KERN_ERR "Could not reserve cable signal GPIO!\n"); + return; + } + omap_set_gpio_direction(PALMTE_DC_GPIO, 1); + omap_set_gpio_direction(PALMTE_USB_OR_DC_GPIO, 1); + omap_set_gpio_direction(PALMTE_USBDETECT_GPIO, 1); + + /* Set speaker-enable pin as output */ + if (omap_request_gpio(PALMTE_SPEAKER_GPIO)) { + printk(KERN_ERR "Could not reserve speaker GPIO!\n"); + return; + } + omap_set_gpio_direction(PALMTE_SPEAKER_GPIO, 0); + + /* Monitor the headphones-connected signal */ + if (omap_request_gpio(PALMTE_HEADPHONES_GPIO)) { + printk(KERN_ERR "Could not reserve headphones signal GPIO!\n"); + return; + } + omap_set_gpio_direction(PALMTE_HEADPHONES_GPIO, 1); + + prev_power = omap_get_gpio_datain(PALMTE_DC_GPIO); + prev_headphones = !omap_get_gpio_datain(PALMTE_HEADPHONES_GPIO); + setup_timer(&palmte_pin_timer, palmte_pin_handler, 0); + palmte_pin_handler(0); +} + +static void __init omap_palmte_init(void) { omap_board_config = palmte_config; omap_board_config_size = ARRAY_SIZE(palmte_config); platform_add_devices(devices, ARRAY_SIZE(devices)); + + spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info)); + + omap_serial_init(); + palmte_gpio_setup(); } -static void __init omap_generic_map_io(void) +static void __init omap_palmte_map_io(void) { omap1_map_common_io(); } @@ -90,8 +431,8 @@ MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") .phys_io = 0xfff00000, .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, .boot_params = 0x10000100, - .map_io = omap_generic_map_io, - .init_irq = omap_generic_init_irq, - .init_machine = omap_generic_init, + .map_io = omap_palmte_map_io, + .init_irq = omap_palmte_init_irq, + .init_machine = omap_palmte_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c new file mode 100644 index 000000000000..e47010fec275 --- /dev/null +++ b/arch/arm/mach-omap1/board-palmtt.c @@ -0,0 +1,357 @@ +/* + * linux/arch/arm/mach-omap1/board-palmtt.c + * + * Modified from board-palmtt2.c + * + * Modified and amended for Palm Tungsten|T + * by Marek Vasut <marek.vasut@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/delay.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/notifier.h> +#include <linux/clk.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/leds.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/flash.h> + +#include <asm/arch/led.h> +#include <asm/arch/mcbsp.h> +#include <asm/arch/gpio.h> +#include <asm/arch/mux.h> +#include <asm/arch/usb.h> +#include <asm/arch/dma.h> +#include <asm/arch/tc.h> +#include <asm/arch/board.h> +#include <asm/arch/irda.h> +#include <asm/arch/keypad.h> +#include <asm/arch/common.h> +#include <asm/arch/omap-alsa.h> + +#include <linux/input.h> +#include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> + +static int palmtt_keymap[] = { + KEY(0, 0, KEY_ESC), + KEY(0, 1, KEY_SPACE), + KEY(0, 2, KEY_LEFTCTRL), + KEY(0, 3, KEY_TAB), + KEY(0, 4, KEY_ENTER), + KEY(1, 0, KEY_LEFT), + KEY(1, 1, KEY_DOWN), + KEY(1, 2, KEY_UP), + KEY(1, 3, KEY_RIGHT), + KEY(2, 0, KEY_SLEEP), + KEY(2, 4, KEY_Y), + 0 +}; + +static struct mtd_partition palmtt_partitions[] = { + { + .name = "write8k", + .offset = 0, + .size = SZ_8K, + .mask_flags = 0, + }, + { + .name = "PalmOS-BootLoader(ro)", + .offset = SZ_8K, + .size = 7 * SZ_8K, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "u-boot", + .offset = MTDPART_OFS_APPEND, + .size = 8 * SZ_8K, + .mask_flags = 0, + }, + { + .name = "PalmOS-FS(ro)", + .offset = MTDPART_OFS_APPEND, + .size = 7 * SZ_1M + 4 * SZ_64K - 16 * SZ_8K, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "u-boot(rez)", + .offset = MTDPART_OFS_APPEND, + .size = SZ_128K, + .mask_flags = 0 + }, + { + .name = "empty", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + } +}; + +static struct flash_platform_data palmtt_flash_data = { + .map_name = "cfi_probe", + .width = 2, + .parts = palmtt_partitions, + .nr_parts = ARRAY_SIZE(palmtt_partitions), +}; + +static struct resource palmtt_flash_resource = { + .start = OMAP_CS0_PHYS, + .end = OMAP_CS0_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device palmtt_flash_device = { + .name = "omapflash", + .id = 0, + .dev = { + .platform_data = &palmtt_flash_data, + }, + .num_resources = 1, + .resource = &palmtt_flash_resource, +}; + +#define DEFAULT_BITPERSAMPLE 16 + +static struct omap_mcbsp_reg_cfg mcbsp_regs = { + .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), + .spcr1 = RINTM(3) | RRST, + .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | + RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0), + .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | + RWDLEN1(OMAP_MCBSP_WORD_16), + .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | + XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG, + .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | + XWDLEN1(OMAP_MCBSP_WORD_16), + .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1), + .srgr2 = GSYNC | CLKSP | FSGM | + FPER(DEFAULT_BITPERSAMPLE * 2 - 1), + .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ +}; + +static struct omap_alsa_codec_config alsa_config = { + .name = "PalmTT AIC23", + .mcbsp_regs_alsa = &mcbsp_regs, + .codec_configure_dev = NULL, // aic23_configure, + .codec_set_samplerate = NULL, // aic23_set_samplerate, + .codec_clock_setup = NULL, // aic23_clock_setup, + .codec_clock_on = NULL, // aic23_clock_on, + .codec_clock_off = NULL, // aic23_clock_off, + .get_default_samplerate = NULL, // aic23_get_default_samplerate, +}; + +static struct platform_device palmtt_mcbsp1_device = { + .name = "omap_alsa_mcbsp", + .id = 1, + .dev = { + .platform_data = &alsa_config, + }, +}; + +static struct resource palmtt_kp_resources[] = { + [0] = { + .start = INT_KEYBOARD, + .end = INT_KEYBOARD, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct omap_kp_platform_data palmtt_kp_data = { + .rows = 6, + .cols = 3, + .keymap = palmtt_keymap, +}; + +static struct platform_device palmtt_kp_device = { + .name = "omap-keypad", + .id = -1, + .dev = { + .platform_data = &palmtt_kp_data, + }, + .num_resources = ARRAY_SIZE(palmtt_kp_resources), + .resource = palmtt_kp_resources, +}; + +static struct platform_device palmtt_lcd_device = { + .name = "lcd_palmtt", + .id = -1, +}; +static struct omap_irda_config palmtt_irda_config = { + .transceiver_cap = IR_SIRMODE, + .rx_channel = OMAP_DMA_UART3_RX, + .tx_channel = OMAP_DMA_UART3_TX, + .dest_start = UART3_THR, + .src_start = UART3_RHR, + .tx_trigger = 0, + .rx_trigger = 0, +}; + +static struct resource palmtt_irda_resources[] = { + [0] = { + .start = INT_UART3, + .end = INT_UART3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device palmtt_irda_device = { + .name = "omapirda", + .id = -1, + .dev = { + .platform_data = &palmtt_irda_config, + }, + .num_resources = ARRAY_SIZE(palmtt_irda_resources), + .resource = palmtt_irda_resources, +}; + +static struct platform_device palmtt_spi_device = { + .name = "spi_palmtt", + .id = -1, +}; + +static struct omap_backlight_config palmtt_backlight_config = { + .default_intensity = 0xa0, +}; + +static struct platform_device palmtt_backlight_device = { + .name = "omap-bl", + .id = -1, + .dev = { + .platform_data= &palmtt_backlight_config, + }, +}; + +static struct omap_led_config palmtt_led_config[] = { + { + .cdev = { + .name = "palmtt:led0", + }, + .gpio = PALMTT_LED_GPIO, + }, +}; + +static struct omap_led_platform_data palmtt_led_data = { + .nr_leds = ARRAY_SIZE(palmtt_led_config), + .leds = palmtt_led_config, +}; + +static struct platform_device palmtt_led_device = { + .name = "omap-led", + .id = -1, + .dev = { + .platform_data = &palmtt_led_data, + }, +}; + +static struct platform_device *palmtt_devices[] __initdata = { + &palmtt_flash_device, + &palmtt_mcbsp1_device, + &palmtt_kp_device, + &palmtt_lcd_device, + &palmtt_irda_device, + &palmtt_spi_device, + &palmtt_backlight_device, + &palmtt_led_device, +}; + +static int palmtt_get_pendown_state(void) +{ + return !omap_get_gpio_datain(6); +} + +static const struct ads7846_platform_data palmtt_ts_info = { + .model = 7846, + .vref_delay_usecs = 100, /* internal, no capacitor */ + .x_plate_ohms = 419, + .y_plate_ohms = 486, + .get_pendown_state = palmtt_get_pendown_state, +}; + +static struct spi_board_info __initdata palmtt_boardinfo[] = { + { + /* MicroWire (bus 2) CS0 has an ads7846e */ + .modalias = "ads7846", + .platform_data = &palmtt_ts_info, + .irq = OMAP_GPIO_IRQ(6), + .max_speed_hz = 120000 /* max sample rate at 3V */ + * 26 /* command + data + overhead */, + .bus_num = 2, + .chip_select = 0, + } +}; + +static void __init omap_palmtt_init_irq(void) +{ + omap1_init_common_hw(); + omap_init_irq(); +} + +static struct omap_usb_config palmtt_usb_config __initdata = { + .register_dev = 1, + .hmc_mode = 0, + .pins[0] = 2, +}; + +static struct omap_lcd_config palmtt_lcd_config __initdata = { + .ctrl_name = "internal", +}; + +static struct omap_uart_config palmtt_uart_config __initdata = { + .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2), +}; + +static struct omap_board_config_kernel palmtt_config[] = { + { OMAP_TAG_USB, &palmtt_usb_config }, + { OMAP_TAG_LCD, &palmtt_lcd_config }, + { OMAP_TAG_UART, &palmtt_uart_config }, +}; + +static void __init omap_mpu_wdt_mode(int mode) { + if (mode) + omap_writew(0x8000, OMAP_WDT_TIMER_MODE); + else { + omap_writew(0x00f5, OMAP_WDT_TIMER_MODE); + omap_writew(0x00a0, OMAP_WDT_TIMER_MODE); + } +} + +static void __init omap_palmtt_init(void) +{ + omap_mpu_wdt_mode(0); + + omap_board_config = palmtt_config; + omap_board_config_size = ARRAY_SIZE(palmtt_config); + + platform_add_devices(palmtt_devices, ARRAY_SIZE(palmtt_devices)); + + spi_register_board_info(palmtt_boardinfo,ARRAY_SIZE(palmtt_boardinfo)); + omap_serial_init(); +} + +static void __init omap_palmtt_map_io(void) +{ + omap1_map_common_io(); +} + +MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T") + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = omap_palmtt_map_io, + .init_irq = omap_palmtt_init_irq, + .init_machine = omap_palmtt_init, + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c new file mode 100644 index 000000000000..c275d517764a --- /dev/null +++ b/arch/arm/mach-omap1/board-palmz71.c @@ -0,0 +1,383 @@ +/* + * linux/arch/arm/mach-omap1/board-palmz71.c + * + * Modified from board-generic.c + * + * Support for the Palm Zire71 PDA. + * + * Original version : Laurent Gonzalez + * + * Modified for zire71 : Marek Vasut + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/delay.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/notifier.h> +#include <linux/clk.h> +#include <linux/irq.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/flash.h> + +#include <asm/arch/mcbsp.h> +#include <asm/arch/gpio.h> +#include <asm/arch/mux.h> +#include <asm/arch/usb.h> +#include <asm/arch/dma.h> +#include <asm/arch/tc.h> +#include <asm/arch/board.h> +#include <asm/arch/irda.h> +#include <asm/arch/keypad.h> +#include <asm/arch/common.h> +#include <asm/arch/omap-alsa.h> + +#include <linux/input.h> +#include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> + +static void __init +omap_palmz71_init_irq(void) +{ + omap1_init_common_hw(); + omap_init_irq(); + omap_gpio_init(); +} + +static int palmz71_keymap[] = { + KEY(0, 0, KEY_F1), + KEY(0, 1, KEY_F2), + KEY(0, 2, KEY_F3), + KEY(0, 3, KEY_F4), + KEY(0, 4, KEY_POWER), + KEY(1, 0, KEY_LEFT), + KEY(1, 1, KEY_DOWN), + KEY(1, 2, KEY_UP), + KEY(1, 3, KEY_RIGHT), + KEY(1, 4, KEY_CENTER), + KEY(2, 0, KEY_CAMERA), + 0, +}; + +static struct omap_kp_platform_data palmz71_kp_data = { + .rows = 8, + .cols = 8, + .keymap = palmz71_keymap, + .rep = 1, + .delay = 80, +}; + +static struct resource palmz71_kp_resources[] = { + [0] = { + .start = INT_KEYBOARD, + .end = INT_KEYBOARD, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device palmz71_kp_device = { + .name = "omap-keypad", + .id = -1, + .dev = { + .platform_data = &palmz71_kp_data, + }, + .num_resources = ARRAY_SIZE(palmz71_kp_resources), + .resource = palmz71_kp_resources, +}; + +static struct mtd_partition palmz71_rom_partitions[] = { + /* PalmOS "Small ROM", contains the bootloader and the debugger */ + { + .name = "smallrom", + .offset = 0, + .size = 0xa000, + .mask_flags = MTD_WRITEABLE, + }, + /* PalmOS "Big ROM", a filesystem with all the OS code and data */ + { + .name = "bigrom", + .offset = SZ_128K, + /* + * 0x5f0000 bytes big in the multi-language ("EFIGS") version, + * 0x7b0000 bytes in the English-only ("enUS") version. + */ + .size = 0x7b0000, + .mask_flags = MTD_WRITEABLE, + }, +}; + +static struct flash_platform_data palmz71_rom_data = { + .map_name = "map_rom", + .name = "onboardrom", + .width = 2, + .parts = palmz71_rom_partitions, + .nr_parts = ARRAY_SIZE(palmz71_rom_partitions), +}; + +static struct resource palmz71_rom_resource = { + .start = OMAP_CS0_PHYS, + .end = OMAP_CS0_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device palmz71_rom_device = { + .name = "omapflash", + .id = -1, + .dev = { + .platform_data = &palmz71_rom_data, + }, + .num_resources = 1, + .resource = &palmz71_rom_resource, +}; + +static struct platform_device palmz71_lcd_device = { + .name = "lcd_palmz71", + .id = -1, +}; + +static struct omap_irda_config palmz71_irda_config = { + .transceiver_cap = IR_SIRMODE, + .rx_channel = OMAP_DMA_UART3_RX, + .tx_channel = OMAP_DMA_UART3_TX, + .dest_start = UART3_THR, + .src_start = UART3_RHR, + .tx_trigger = 0, + .rx_trigger = 0, +}; + +static struct resource palmz71_irda_resources[] = { + [0] = { + .start = INT_UART3, + .end = INT_UART3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device palmz71_irda_device = { + .name = "omapirda", + .id = -1, + .dev = { + .platform_data = &palmz71_irda_config, + }, + .num_resources = ARRAY_SIZE(palmz71_irda_resources), + .resource = palmz71_irda_resources, +}; + +static struct platform_device palmz71_spi_device = { + .name = "spi_palmz71", + .id = -1, +}; + +#define DEFAULT_BITPERSAMPLE 16 + +static struct omap_mcbsp_reg_cfg mcbsp_regs = { + .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), + .spcr1 = RINTM(3) | RRST, + .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | + RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0), + .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), + .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | + XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG, + .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), + .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1), + .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1), + .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ +}; + +static struct omap_alsa_codec_config alsa_config = { + .name = "PalmZ71 AIC23", + .mcbsp_regs_alsa = &mcbsp_regs, + .codec_configure_dev = NULL, /* aic23_configure */ + .codec_set_samplerate = NULL, /* aic23_set_samplerate */ + .codec_clock_setup = NULL, /* aic23_clock_setup */ + .codec_clock_on = NULL, /* aic23_clock_on */ + .codec_clock_off = NULL, /* aic23_clock_off */ + .get_default_samplerate = NULL, /* aic23_get_default_samplerate */ +}; + +static struct platform_device palmz71_mcbsp1_device = { + .name = "omap_alsa_mcbsp", + .id = 1, + .dev = { + .platform_data = &alsa_config, + }, +}; + +static struct omap_backlight_config palmz71_backlight_config = { + .default_intensity = 0xa0, +}; + +static struct platform_device palmz71_backlight_device = { + .name = "omap-bl", + .id = -1, + .dev = { + .platform_data = &palmz71_backlight_config, + }, +}; + +static struct platform_device *devices[] __initdata = { + &palmz71_rom_device, + &palmz71_kp_device, + &palmz71_mcbsp1_device, + &palmz71_lcd_device, + &palmz71_irda_device, + &palmz71_spi_device, + &palmz71_backlight_device, +}; + +static int +palmz71_get_pendown_state(void) +{ + return !omap_get_gpio_datain(PALMZ71_PENIRQ_GPIO); +} + +static const struct ads7846_platform_data palmz71_ts_info = { + .model = 7846, + .vref_delay_usecs = 100, /* internal, no capacitor */ + .x_plate_ohms = 419, + .y_plate_ohms = 486, + .get_pendown_state = palmz71_get_pendown_state, +}; + +static struct spi_board_info __initdata palmz71_boardinfo[] = { { + /* MicroWire (bus 2) CS0 has an ads7846e */ + .modalias = "ads7846", + .platform_data = &palmz71_ts_info, + .irq = OMAP_GPIO_IRQ(PALMZ71_PENIRQ_GPIO), + .max_speed_hz = 120000 /* max sample rate at 3V */ + * 26 /* command + data + overhead */, + .bus_num = 2, + .chip_select = 0, +} }; + +static struct omap_usb_config palmz71_usb_config __initdata = { + .register_dev = 1, /* Mini-B only receptacle */ + .hmc_mode = 0, + .pins[0] = 2, +}; + +static struct omap_mmc_config palmz71_mmc_config __initdata = { + .mmc[0] = { + .enabled = 1, + .wire4 = 0, + .wp_pin = PALMZ71_MMC_WP_GPIO, + .power_pin = -1, + .switch_pin = PALMZ71_MMC_IN_GPIO, + }, +}; + +static struct omap_lcd_config palmz71_lcd_config __initdata = { + .ctrl_name = "internal", +}; + +static struct omap_uart_config palmz71_uart_config __initdata = { + .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2), +}; + +static struct omap_board_config_kernel palmz71_config[] = { + {OMAP_TAG_USB, &palmz71_usb_config}, + {OMAP_TAG_MMC, &palmz71_mmc_config}, + {OMAP_TAG_LCD, &palmz71_lcd_config}, + {OMAP_TAG_UART, &palmz71_uart_config}, +}; + +static irqreturn_t +palmz71_powercable(int irq, void *dev_id) +{ + if (omap_get_gpio_datain(PALMZ71_USBDETECT_GPIO)) { + printk(KERN_INFO "PM: Power cable connected\n"); + set_irq_type(OMAP_GPIO_IRQ(PALMZ71_USBDETECT_GPIO), + IRQT_FALLING); + } else { + printk(KERN_INFO "PM: Power cable disconnected\n"); + set_irq_type(OMAP_GPIO_IRQ(PALMZ71_USBDETECT_GPIO), + IRQT_RISING); + } + return IRQ_HANDLED; +} + +static void __init +omap_mpu_wdt_mode(int mode) +{ + if (mode) + omap_writew(0x8000, OMAP_WDT_TIMER_MODE); + else { + omap_writew(0x00f5, OMAP_WDT_TIMER_MODE); + omap_writew(0x00a0, OMAP_WDT_TIMER_MODE); + } +} + +static void __init +palmz71_gpio_setup(int early) +{ + if (early) { + /* Only set GPIO1 so we have a working serial */ + omap_set_gpio_dataout(1, 1); + omap_set_gpio_direction(1, 0); + } else { + /* Set MMC/SD host WP pin as input */ + if (omap_request_gpio(PALMZ71_MMC_WP_GPIO)) { + printk(KERN_ERR "Could not reserve WP GPIO!\n"); + return; + } + omap_set_gpio_direction(PALMZ71_MMC_WP_GPIO, 1); + + /* Monitor the Power-cable-connected signal */ + if (omap_request_gpio(PALMZ71_USBDETECT_GPIO)) { + printk(KERN_ERR + "Could not reserve cable signal GPIO!\n"); + return; + } + omap_set_gpio_direction(PALMZ71_USBDETECT_GPIO, 1); + if (request_irq(OMAP_GPIO_IRQ(PALMZ71_USBDETECT_GPIO), + palmz71_powercable, IRQF_SAMPLE_RANDOM, + "palmz71-cable", 0)) + printk(KERN_ERR + "IRQ request for power cable failed!\n"); + palmz71_powercable(OMAP_GPIO_IRQ(PALMZ71_USBDETECT_GPIO), 0); + } +} + +static void __init +omap_palmz71_init(void) +{ + palmz71_gpio_setup(1); + omap_mpu_wdt_mode(0); + + omap_board_config = palmz71_config; + omap_board_config_size = ARRAY_SIZE(palmz71_config); + + platform_add_devices(devices, ARRAY_SIZE(devices)); + + spi_register_board_info(palmz71_boardinfo, + ARRAY_SIZE(palmz71_boardinfo)); + omap_serial_init(); + palmz71_gpio_setup(0); +} + +static void __init +omap_palmz71_map_io(void) +{ + omap1_map_common_io(); +} + +MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71") + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100,.map_io = omap_palmz71_map_io, + .init_irq = omap_palmz71_init_irq, + .init_machine = omap_palmz71_init, + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c new file mode 100644 index 000000000000..2743d639aa05 --- /dev/null +++ b/arch/arm/mach-omap1/board-sx1.c @@ -0,0 +1,494 @@ +/* +* linux/arch/arm/mach-omap1/board-sx1.c +* +* Modified from board-generic.c +* +* Support for the Siemens SX1 mobile phone. +* +* Original version : Vladimir Ananiev (Vovan888-at-gmail com) +* +* Maintainters : Vladimir Ananiev (aka Vovan888), Sergge +* oslik.ru +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/input.h> +#include <linux/platform_device.h> +#include <linux/notifier.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/types.h> +#include <linux/i2c.h> +#include <linux/errno.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/map.h> + +#include <asm/arch/gpio.h> +#include <asm/arch/mux.h> +#include <asm/arch/irda.h> +#include <asm/arch/usb.h> +#include <asm/arch/tc.h> +#include <asm/arch/board.h> +#include <asm/arch/common.h> +#include <asm/arch/mcbsp.h> +#include <asm/arch/omap-alsa.h> +#include <asm/arch/keypad.h> + +/* Write to I2C device */ +int i2c_write_byte(u8 devaddr, u8 regoffset, u8 value) +{ + struct i2c_adapter *adap; + int err; + struct i2c_msg msg[1]; + unsigned char data[2]; + + adap = i2c_get_adapter(0); + if (!adap) + return -ENODEV; + msg->addr = devaddr; /* I2C address of chip */ + msg->flags = 0; + msg->len = 2; + msg->buf = data; + data[0] = regoffset; /* register num */ + data[1] = value; /* register data */ + err = i2c_transfer(adap, msg, 1); + if (err >= 0) + return 0; + return err; +} + +/* Read from I2C device */ +int i2c_read_byte(u8 devaddr, u8 regoffset, u8 * value) +{ + struct i2c_adapter *adap; + int err; + struct i2c_msg msg[1]; + unsigned char data[2]; + + adap = i2c_get_adapter(0); + if (!adap) + return -ENODEV; + + msg->addr = devaddr; /* I2C address of chip */ + msg->flags = 0; + msg->len = 1; + msg->buf = data; + data[0] = regoffset; /* register num */ + err = i2c_transfer(adap, msg, 1); + + msg->addr = devaddr; /* I2C address */ + msg->flags = I2C_M_RD; + msg->len = 1; + msg->buf = data; + err = i2c_transfer(adap, msg, 1); + *value = data[0]; + + if (err >= 0) + return 0; + return err; +} +/* set keyboard backlight intensity */ +int sx1_setkeylight(u8 keylight) +{ + if (keylight > SOFIA_MAX_LIGHT_VAL) + keylight = SOFIA_MAX_LIGHT_VAL; + return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight); +} +/* get current keylight intensity */ +int sx1_getkeylight(u8 * keylight) +{ + return i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight); +} +/* set LCD backlight intensity */ +int sx1_setbacklight(u8 backlight) +{ + if (backlight > SOFIA_MAX_LIGHT_VAL) + backlight = SOFIA_MAX_LIGHT_VAL; + return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG, backlight); +} +/* get current LCD backlight intensity */ +int sx1_getbacklight (u8 * backlight) +{ + return i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG, backlight); +} +/* set LCD backlight power on/off */ +int sx1_setmmipower(u8 onoff) +{ + int err; + u8 dat = 0; + err = i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat); + if (err < 0) + return err; + if (onoff) + dat |= SOFIA_MMILIGHT_POWER; + else + dat &= ~SOFIA_MMILIGHT_POWER; + return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat); +} +/* set MMC power on/off */ +int sx1_setmmcpower(u8 onoff) +{ + int err; + u8 dat = 0; + err = i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat); + if (err < 0) + return err; + if (onoff) + dat |= SOFIA_MMC_POWER; + else + dat &= ~SOFIA_MMC_POWER; + return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat); +} +/* set USB power on/off */ +int sx1_setusbpower(u8 onoff) +{ + int err; + u8 dat = 0; + err = i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat); + if (err < 0) + return err; + if (onoff) + dat |= SOFIA_USB_POWER; + else + dat &= ~SOFIA_USB_POWER; + return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat); +} + +EXPORT_SYMBOL(sx1_setkeylight); +EXPORT_SYMBOL(sx1_getkeylight); +EXPORT_SYMBOL(sx1_setbacklight); +EXPORT_SYMBOL(sx1_getbacklight); +EXPORT_SYMBOL(sx1_setmmipower); +EXPORT_SYMBOL(sx1_setmmcpower); +EXPORT_SYMBOL(sx1_setusbpower); + +/*----------- Keypad -------------------------*/ + +static int sx1_keymap[] = { + KEY(5, 3, GROUP_0 | 117), /* camera Qt::Key_F17 */ + KEY(0, 4, GROUP_0 | 114), /* voice memo Qt::Key_F14 */ + KEY(1, 4, GROUP_2 | 114), /* voice memo */ + KEY(2, 4, GROUP_3 | 114), /* voice memo */ + KEY(0, 0, GROUP_1 | KEY_F12), /* red button Qt::Key_Hangup */ + KEY(4, 3, GROUP_1 | KEY_LEFT), + KEY(2, 3, GROUP_1 | KEY_DOWN), + KEY(1, 3, GROUP_1 | KEY_RIGHT), + KEY(0, 3, GROUP_1 | KEY_UP), + KEY(3, 3, GROUP_1 | KEY_POWER), /* joystick press or Qt::Key_Select */ + KEY(5, 0, GROUP_1 | KEY_1), + KEY(4, 0, GROUP_1 | KEY_2), + KEY(3, 0, GROUP_1 | KEY_3), + KEY(3, 4, GROUP_1 | KEY_4), + KEY(4, 4, GROUP_1 | KEY_5), + KEY(5, 4, GROUP_1 | KEY_KPASTERISK),/* "*" */ + KEY(4, 1, GROUP_1 | KEY_6), + KEY(5, 1, GROUP_1 | KEY_7), + KEY(3, 1, GROUP_1 | KEY_8), + KEY(3, 2, GROUP_1 | KEY_9), + KEY(5, 2, GROUP_1 | KEY_0), + KEY(4, 2, GROUP_1 | 113), /* # F13 Toggle input method Qt::Key_F13 */ + KEY(0, 1, GROUP_1 | KEY_F11), /* green button Qt::Key_Call */ + KEY(1, 2, GROUP_1 | KEY_YEN), /* left soft Qt::Key_Context1 */ + KEY(2, 2, GROUP_1 | KEY_F8), /* right soft Qt::Key_Back */ + KEY(2, 1, GROUP_1 | KEY_LEFTSHIFT), /* shift */ + KEY(1, 1, GROUP_1 | KEY_BACKSPACE), /* C (clear) */ + KEY(0, 2, GROUP_1 | KEY_F7), /* menu Qt::Key_Menu */ + 0 +}; + +static struct resource sx1_kp_resources[] = { + [0] = { + .start = INT_KEYBOARD, + .end = INT_KEYBOARD, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct omap_kp_platform_data sx1_kp_data = { + .rows = 6, + .cols = 6, + .keymap = sx1_keymap, + .keymapsize = ARRAY_SIZE(sx1_keymap), + .delay = 80, +}; + +static struct platform_device sx1_kp_device = { + .name = "omap-keypad", + .id = -1, + .dev = { + .platform_data = &sx1_kp_data, + }, + .num_resources = ARRAY_SIZE(sx1_kp_resources), + .resource = sx1_kp_resources, +}; + +/*----------- IRDA -------------------------*/ + +static struct omap_irda_config sx1_irda_data = { + .transceiver_cap = IR_SIRMODE, + .rx_channel = OMAP_DMA_UART3_RX, + .tx_channel = OMAP_DMA_UART3_TX, + .dest_start = UART3_THR, + .src_start = UART3_RHR, + .tx_trigger = 0, + .rx_trigger = 0, +}; + +static struct resource sx1_irda_resources[] = { + [0] = { + .start = INT_UART3, + .end = INT_UART3, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 irda_dmamask = 0xffffffff; + +static struct platform_device sx1_irda_device = { + .name = "omapirda", + .id = 0, + .dev = { + .platform_data = &sx1_irda_data, + .dma_mask = &irda_dmamask, + }, + .num_resources = ARRAY_SIZE(sx1_irda_resources), + .resource = sx1_irda_resources, +}; + +/*----------- McBSP & Sound -------------------------*/ + +/* Playback interface - McBSP1 */ +static struct omap_mcbsp_reg_cfg mcbsp1_regs = { + .spcr2 = XINTM(3), /* SPCR2=30 */ + .spcr1 = RINTM(3), /* SPCR1=30 */ + .rcr2 = 0, /* RCR2 =00 */ + .rcr1 = RFRLEN1(1) | RWDLEN1(OMAP_MCBSP_WORD_16), /* RCR1=140 */ + .xcr2 = 0, /* XCR2 = 0 */ + .xcr1 = XFRLEN1(1) | XWDLEN1(OMAP_MCBSP_WORD_16), /* XCR1 = 140 */ + .srgr1 = FWID(15) | CLKGDV(12), /* SRGR1=0f0c */ + .srgr2 = FSGM | FPER(31), /* SRGR2=101f */ + .pcr0 = FSXM | FSRM | CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP, + /* PCR0 =0f0f */ +}; + +/* TODO: PCM interface - McBSP2 */ +static struct omap_mcbsp_reg_cfg mcbsp2_regs = { + .spcr2 = FRST | GRST | XRST | XINTM(3), /* SPCR2=F1 */ + .spcr1 = RINTM(3) | RRST, /* SPCR1=30 */ + .rcr2 = 0, /* RCR2 =00 */ + .rcr1 = RFRLEN1(1) | RWDLEN1(OMAP_MCBSP_WORD_16), /* RCR1 = 140 */ + .xcr2 = 0, /* XCR2 = 0 */ + .xcr1 = XFRLEN1(1) | XWDLEN1(OMAP_MCBSP_WORD_16), /* XCR1 = 140 */ + .srgr1 = FWID(15) | CLKGDV(12), /* SRGR1=0f0c */ + .srgr2 = FSGM | FPER(31), /* SRGR2=101f */ + .pcr0 = FSXM | FSRM | CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP, + /* PCR0=0f0f */ + /* mcbsp: slave */ +}; + +static struct omap_alsa_codec_config sx1_alsa_config = { + .name = "SX1 EGold", + .mcbsp_regs_alsa = &mcbsp1_regs, +}; + +static struct platform_device sx1_mcbsp1_device = { + .name = "omap_alsa_mcbsp", + .id = 1, + .dev = { + .platform_data = &sx1_alsa_config, + }, +}; + +/*----------- MTD -------------------------*/ + +static struct mtd_partition sx1_partitions[] = { + /* bootloader (U-Boot, etc) in first sector */ + { + .name = "bootloader", + .offset = 0x01800000, + .size = SZ_128K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader params in the next sector */ + { + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = SZ_128K, + .mask_flags = 0, + }, + /* kernel */ + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M - 2 * SZ_128K, + .mask_flags = 0 + }, + /* file system */ + { + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + } +}; + +static struct flash_platform_data sx1_flash_data = { + .map_name = "cfi_probe", + .width = 2, + .parts = sx1_partitions, + .nr_parts = ARRAY_SIZE(sx1_partitions), +}; + +#ifdef CONFIG_SX1_OLD_FLASH +/* MTD Intel StrataFlash - old flashes */ +static struct resource sx1_old_flash_resource[] = { + [0] = { + .start = OMAP_CS0_PHYS, /* Physical */ + .end = OMAP_CS0_PHYS + SZ_16M - 1,, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OMAP_CS1_PHYS, + .end = OMAP_CS1_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device sx1_flash_device = { + .name = "omapflash", + .id = 0, + .dev = { + .platform_data = &sx1_flash_data, + }, + .num_resources = 2, + .resource = &sx1_old_flash_resource, +}; +#else +/* MTD Intel 4000 flash - new flashes */ +static struct resource sx1_new_flash_resource = { + .start = OMAP_CS0_PHYS, + .end = OMAP_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device sx1_flash_device = { + .name = "omapflash", + .id = 0, + .dev = { + .platform_data = &sx1_flash_data, + }, + .num_resources = 1, + .resource = &sx1_new_flash_resource, +}; +#endif + +/*----------- USB -------------------------*/ + +static struct omap_usb_config sx1_usb_config __initdata = { + .otg = 0, + .register_dev = 1, + .register_host = 0, + .hmc_mode = 0, + .pins[0] = 2, + .pins[1] = 0, + .pins[2] = 0, +}; + +/*----------- MMC -------------------------*/ + +static struct omap_mmc_config sx1_mmc_config __initdata = { + .mmc [0] = { + .enabled = 1, + .wire4 = 0, + .wp_pin = -1, + .power_pin = -1, /* power is in Sofia */ + .switch_pin = OMAP_MPUIO(3), + }, +}; + +/*----------- LCD -------------------------*/ + +static struct platform_device sx1_lcd_device = { + .name = "lcd_sx1", + .id = -1, +}; + +static struct omap_lcd_config sx1_lcd_config __initdata = { + .ctrl_name = "internal", +}; + +/*-----------------------------------------*/ +static struct platform_device *sx1_devices[] __initdata = { + &sx1_flash_device, + &sx1_kp_device, + &sx1_lcd_device, + &sx1_mcbsp1_device, + &sx1_irda_device, +}; +/*-----------------------------------------*/ + +static struct omap_uart_config sx1_uart_config __initdata = { + .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), +}; + +static struct omap_board_config_kernel sx1_config[] = { + { OMAP_TAG_USB, &sx1_usb_config }, + { OMAP_TAG_MMC, &sx1_mmc_config }, + { OMAP_TAG_LCD, &sx1_lcd_config }, + { OMAP_TAG_UART, &sx1_uart_config }, +}; +/*-----------------------------------------*/ +static void __init omap_sx1_init(void) +{ + platform_add_devices(sx1_devices, ARRAY_SIZE(sx1_devices)); + + omap_board_config = sx1_config; + omap_board_config_size = ARRAY_SIZE(sx1_config); + omap_serial_init(); + + /* turn on USB power */ + /* sx1_setusbpower(1); cant do it here because i2c is not ready */ + omap_request_gpio(1); /* A_IRDA_OFF */ + omap_request_gpio(11); /* A_SWITCH */ + omap_request_gpio(15); /* A_USB_ON */ + omap_set_gpio_direction(1, 0);/* gpio1 -> output */ + omap_set_gpio_direction(11, 0);/* gpio11 -> output */ + omap_set_gpio_direction(15, 0);/* gpio15 -> output */ + /* set GPIO data */ + omap_set_gpio_dataout(1, 1);/*A_IRDA_OFF = 1 */ + omap_set_gpio_dataout(11, 0);/*A_SWITCH = 0 */ + omap_set_gpio_dataout(15, 0);/*A_USB_ON = 0 */ + +} +/*----------------------------------------*/ +static void __init omap_sx1_init_irq(void) +{ + omap1_init_common_hw(); + omap_init_irq(); + omap_gpio_init(); +} +/*----------------------------------------*/ + +static void __init omap_sx1_map_io(void) +{ + omap1_map_common_io(); +} + +MACHINE_START(SX1, "OMAP310 based Siemens SX1") + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = omap_sx1_map_io, + .init_irq = omap_sx1_init_irq, + .init_machine = omap_sx1_init, + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index 447a586eb334..214dd19889ac 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -235,7 +235,7 @@ static struct notifier_block panic_block = { static int __init voiceblue_setup(void) { /* Setup panic notifier */ - notifier_chain_register(&panic_notifier_list, &panic_block); + atomic_notifier_chain_register(&panic_notifier_list, &panic_block); return 0; } diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index f625f6dd228a..5d9faa68d2ec 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -49,6 +49,15 @@ static void omap1_uart_recalc(struct clk * clk) clk->rate = 12000000; } +static void omap1_sossi_recalc(struct clk *clk) +{ + u32 div = omap_readl(MOD_CONF_CTRL_1); + + div = (div >> 17) & 0x7; + div++; + clk->rate = clk->parent->rate / div; +} + static int omap1_clk_enable_dsp_domain(struct clk *clk) { int retval; @@ -396,6 +405,31 @@ static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate) return 0; } +static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate) +{ + u32 l; + int div; + unsigned long p_rate; + + p_rate = clk->parent->rate; + /* Round towards slower frequency */ + div = (p_rate + rate - 1) / rate; + div--; + if (div < 0 || div > 7) + return -EINVAL; + + l = omap_readl(MOD_CONF_CTRL_1); + l &= ~(7 << 17); + l |= div << 17; + omap_writel(l, MOD_CONF_CTRL_1); + + clk->rate = p_rate / (div + 1); + if (unlikely(clk->flags & RATE_PROPAGATES)) + propagate_rate(clk); + + return 0; +} + static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate) { return 96000000 / calc_ext_dsor(rate); diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h index f7df00205c4a..6eadf72828d8 100644 --- a/arch/arm/mach-omap1/clock.h +++ b/arch/arm/mach-omap1/clock.h @@ -17,6 +17,8 @@ static int omap1_clk_enable_generic(struct clk * clk); static void omap1_clk_disable_generic(struct clk * clk); static void omap1_ckctl_recalc(struct clk * clk); static void omap1_watchdog_recalc(struct clk * clk); +static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate); +static void omap1_sossi_recalc(struct clk *clk); static void omap1_ckctl_recalc_dsp_domain(struct clk * clk); static int omap1_clk_enable_dsp_domain(struct clk * clk); static int omap1_clk_set_rate_dsp_domain(struct clk * clk, unsigned long rate); @@ -168,9 +170,10 @@ static struct clk ck_dpll1 = { static struct arm_idlect1_clk ck_dpll1out = { .clk = { - .name = "ck_dpll1out", + .name = "ck_dpll1out", .parent = &ck_dpll1, - .flags = CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL, + .flags = CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL | + ENABLE_REG_32BIT | RATE_PROPAGATES, .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_CKOUT_ARM, .recalc = &followparent_recalc, @@ -180,6 +183,19 @@ static struct arm_idlect1_clk ck_dpll1out = { .idlect_shift = 12, }; +static struct clk sossi_ck = { + .name = "ck_sossi", + .parent = &ck_dpll1out.clk, + .flags = CLOCK_IN_OMAP16XX | CLOCK_NO_IDLE_PARENT | + ENABLE_REG_32BIT, + .enable_reg = (void __iomem *)MOD_CONF_CTRL_1, + .enable_bit = 16, + .recalc = &omap1_sossi_recalc, + .set_rate = &omap1_set_sossi_rate, + .enable = &omap1_clk_enable_generic, + .disable = &omap1_clk_disable_generic, +}; + static struct clk arm_ck = { .name = "arm_ck", .parent = &ck_dpll1, @@ -282,7 +298,7 @@ static struct clk arminth_ck16xx = { static struct clk dsp_ck = { .name = "dsp_ck", .parent = &ck_dpll1, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | RATE_CKCTL, .enable_reg = (void __iomem *)ARM_CKCTL, .enable_bit = EN_DSPCK, @@ -295,7 +311,7 @@ static struct clk dsp_ck = { static struct clk dspmmu_ck = { .name = "dspmmu_ck", .parent = &ck_dpll1, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | RATE_CKCTL | ALWAYS_ENABLED, .rate_offset = CKCTL_DSPMMUDIV_OFFSET, .recalc = &omap1_ckctl_recalc, @@ -306,7 +322,7 @@ static struct clk dspmmu_ck = { static struct clk dspper_ck = { .name = "dspper_ck", .parent = &ck_dpll1, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | RATE_CKCTL | VIRTUAL_IO_ADDRESS, .enable_reg = (void __iomem *)DSP_IDLECT2, .enable_bit = EN_PERCK, @@ -320,7 +336,7 @@ static struct clk dspper_ck = { static struct clk dspxor_ck = { .name = "dspxor_ck", .parent = &ck_ref, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | VIRTUAL_IO_ADDRESS, .enable_reg = (void __iomem *)DSP_IDLECT2, .enable_bit = EN_XORPCK, @@ -332,7 +348,7 @@ static struct clk dspxor_ck = { static struct clk dsptim_ck = { .name = "dsptim_ck", .parent = &ck_ref, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | VIRTUAL_IO_ADDRESS, .enable_reg = (void __iomem *)DSP_IDLECT2, .enable_bit = EN_DSPTIMCK, @@ -374,7 +390,7 @@ static struct clk arminth_ck1510 = { static struct clk tipb_ck = { /* No-idle controlled by "tc_ck" */ - .name = "tibp_ck", + .name = "tipb_ck", .parent = &tc_ck.clk, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, @@ -733,7 +749,7 @@ remains active during MPU idle whenever this is enabled */ static struct clk i2c_fck = { .name = "i2c_fck", .id = 1, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT | ALWAYS_ENABLED, .parent = &armxor_ck.clk, @@ -760,6 +776,7 @@ static struct clk * onchip_clks[] = { &ck_dpll1, /* CK_GEN1 clocks */ &ck_dpll1out.clk, + &sossi_ck, &arm_ck, &armper_ck.clk, &arm_gpio_ck, diff --git a/arch/arm/mach-omap1/leds-innovator.c b/arch/arm/mach-omap1/leds-innovator.c index a0cd001ac39a..e7835d6f53a0 100644 --- a/arch/arm/mach-omap1/leds-innovator.c +++ b/arch/arm/mach-omap1/leds-innovator.c @@ -95,8 +95,5 @@ void innovator_leds_event(led_event_t evt) break; } - if (led_state & LED_STATE_ENABLED) - ; - local_irq_restore(flags); } diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c index 5432335bc493..52c70e5fcf65 100644 --- a/arch/arm/mach-omap1/mux.c +++ b/arch/arm/mach-omap1/mux.c @@ -283,6 +283,30 @@ MUX_CFG("R11_1610_CF_IOIS16", B, 0, 3, 2, 16, 1, 2, 1, 1) MUX_CFG("V10_1610_CF_IREQ", A, 24, 3, 2, 14, 0, 2, 0, 1) MUX_CFG("W10_1610_CF_RESET", A, 18, 3, 2, 12, 1, 2, 1, 1) MUX_CFG("W11_1610_CF_CD1", 10, 15, 3, 3, 8, 1, 3, 1, 1) + +/* parallel camera */ +MUX_CFG("J15_1610_CAM_LCLK", 4, 24, 0, 0, 18, 1, 0, 0, 0) +MUX_CFG("J18_1610_CAM_D7", 4, 27, 0, 0, 19, 1, 0, 0, 0) +MUX_CFG("J19_1610_CAM_D6", 5, 0, 0, 0, 20, 1, 0, 0, 0) +MUX_CFG("J14_1610_CAM_D5", 5, 3, 0, 0, 21, 1, 0, 0, 0) +MUX_CFG("K18_1610_CAM_D4", 5, 6, 0, 0, 22, 1, 0, 0, 0) +MUX_CFG("K19_1610_CAM_D3", 5, 9, 0, 0, 23, 1, 0, 0, 0) +MUX_CFG("K15_1610_CAM_D2", 5, 12, 0, 0, 24, 1, 0, 0, 0) +MUX_CFG("K14_1610_CAM_D1", 5, 15, 0, 0, 25, 1, 0, 0, 0) +MUX_CFG("L19_1610_CAM_D0", 5, 18, 0, 0, 26, 1, 0, 0, 0) +MUX_CFG("L18_1610_CAM_VS", 5, 21, 0, 0, 27, 1, 0, 0, 0) +MUX_CFG("L15_1610_CAM_HS", 5, 24, 0, 0, 28, 1, 0, 0, 0) +MUX_CFG("M19_1610_CAM_RSTZ", 5, 27, 0, 0, 29, 0, 0, 0, 0) +MUX_CFG("Y15_1610_CAM_OUTCLK", A, 0, 6, 2, 6, 0, 2, 0, 0) + +/* serial camera */ +MUX_CFG("H19_1610_CAM_EXCLK", 4, 21, 0, 0, 17, 0, 0, 0, 0) + /* REVISIT 5912 spec sez CCP_* can't pullup or pulldown ... ? */ +MUX_CFG("Y12_1610_CCP_CLKP", 8, 18, 6, 1, 24, 1, 1, 0, 0) +MUX_CFG("W13_1610_CCP_CLKM", 9, 0, 6, 1, 28, 1, 1, 0, 0) +MUX_CFG("W14_1610_CCP_DATAP", 9, 24, 6, 2, 4, 1, 2, 0, 0) +MUX_CFG("Y14_1610_CCP_DATAM", 9, 21, 6, 2, 3, 1, 2, 0, 0) + }; #endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */ diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 2e68be607295..089b8208de0e 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -153,11 +153,8 @@ void omap_pm_idle(void) use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1); #endif - if (omap_dma_running()) { + if (omap_dma_running()) use_idlect1 &= ~(1 << 6); - if (omap_lcd_dma_ext_running()) - use_idlect1 &= ~(1 << 12); - } /* We should be able to remove the do_sleep variable and multiple * tests above as soon as drivers, timer and DMA code have been fixed. diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 7393109f5c30..7069c9d536f1 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -11,6 +11,10 @@ config ARCH_OMAP2420 select OMAP_DM_TIMER select ARCH_OMAP_OTG +config ARCH_OMAP2430 + bool "OMAP2430 support" + depends on ARCH_OMAP24XX + comment "OMAP Board Type" depends on ARCH_OMAP2 @@ -21,8 +25,13 @@ config MACH_OMAP_GENERIC config MACH_OMAP_H4 bool "OMAP 2420 H4 board" depends on ARCH_OMAP2 && ARCH_OMAP24XX - select OMAP_DEBUG_LEDS if LEDS || LEDS_OMAP_DEBUG + select OMAP_DEBUG_DEVICES config MACH_OMAP_APOLLON bool "OMAP 2420 Apollon board" depends on ARCH_OMAP2 && ARCH_OMAP24XX + +config MACH_OMAP_2430SDP + bool "OMAP 2430 SDP board" + depends on ARCH_OMAP2 && ARCH_OMAP24XX + diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 266d88e77bdc..b05b738d31e6 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -14,5 +14,6 @@ obj-$(CONFIG_PM) += pm.o pm-domain.o sleep.o # Specific board support obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o +obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c new file mode 100644 index 000000000000..7e76fbf19b5d --- /dev/null +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -0,0 +1,218 @@ +/* + * linux/arch/arm/mach-omap2/board-2430sdp.c + * + * Copyright (C) 2006 Texas Instruments + * + * Modified from mach-omap2/board-generic.c + * + * Initial Code : Based on a patch from Komal Shah and Richard Woodruff + * Updated the Code for 2430 SDP : Syed Mohammed Khasim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/clk.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/flash.h> + +#include <asm/arch/gpio.h> +#include <asm/arch/mux.h> +#include <asm/arch/board.h> +#include <asm/arch/common.h> +#include <asm/arch/gpmc.h> +#include "prcm-regs.h" + +#include <asm/io.h> + + +#define SDP2430_FLASH_CS 0 +#define SDP2430_SMC91X_CS 5 + +static struct mtd_partition sdp2430_partitions[] = { + /* bootloader (U-Boot, etc) in first sector */ + { + .name = "bootloader", + .offset = 0, + .size = SZ_256K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader params in the next sector */ + { + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = SZ_128K, + .mask_flags = 0, + }, + /* kernel */ + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + .mask_flags = 0 + }, + /* file system */ + { + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + } +}; + +static struct flash_platform_data sdp2430_flash_data = { + .map_name = "cfi_probe", + .width = 2, + .parts = sdp2430_partitions, + .nr_parts = ARRAY_SIZE(sdp2430_partitions), +}; + +static struct resource sdp2430_flash_resource = { + .start = SDP2430_CS0_BASE, + .end = SDP2430_CS0_BASE + SZ_64M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device sdp2430_flash_device = { + .name = "omapflash", + .id = 0, + .dev = { + .platform_data = &sdp2430_flash_data, + }, + .num_resources = 1, + .resource = &sdp2430_flash_resource, +}; + +static struct resource sdp2430_smc91x_resources[] = { + [0] = { + .start = SDP2430_CS0_BASE, + .end = SDP2430_CS0_BASE + SZ_64M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ), + .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdp2430_smc91x_device = { + .name = "smc91x", + .id = -1, + .num_resources = ARRAY_SIZE(sdp2430_smc91x_resources), + .resource = sdp2430_smc91x_resources, +}; + +static struct platform_device *sdp2430_devices[] __initdata = { + &sdp2430_smc91x_device, + &sdp2430_flash_device, +}; + +static inline void __init sdp2430_init_smc91x(void) +{ + int eth_cs; + unsigned long cs_mem_base; + unsigned int rate; + struct clk *l3ck; + + eth_cs = SDP2430_SMC91X_CS; + + l3ck = clk_get(NULL, "core_l3_ck"); + if (IS_ERR(l3ck)) + rate = 100000000; + else + rate = clk_get_rate(l3ck); + + /* Make sure CS1 timings are correct, for 2430 always muxed */ + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200); + + if (rate >= 160000000) { + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01); + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803); + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a); + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F); + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4); + } else if (rate >= 130000000) { + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00); + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802); + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09); + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F); + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4); + } else { /* rate = 100000000 */ + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00); + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802); + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09); + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F); + gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2); + } + + if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) { + printk(KERN_ERR "Failed to request GPMC mem for smc91x\n"); + return; + } + + sdp2430_smc91x_resources[0].start = cs_mem_base + 0x300; + sdp2430_smc91x_resources[0].end = cs_mem_base + 0x30f; + udelay(100); + + if (omap_request_gpio(OMAP24XX_ETHR_GPIO_IRQ) < 0) { + printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", + OMAP24XX_ETHR_GPIO_IRQ); + gpmc_cs_free(eth_cs); + return; + } + omap_set_gpio_direction(OMAP24XX_ETHR_GPIO_IRQ, 1); + +} + +static void __init omap_2430sdp_init_irq(void) +{ + omap2_init_common_hw(); + omap_init_irq(); + omap_gpio_init(); + sdp2430_init_smc91x(); +} + +static struct omap_uart_config sdp2430_uart_config __initdata = { + .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), +}; + +static struct omap_board_config_kernel sdp2430_config[] = { + {OMAP_TAG_UART, &sdp2430_uart_config}, +}; + +static void __init omap_2430sdp_init(void) +{ + platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices)); + omap_board_config = sdp2430_config; + omap_board_config_size = ARRAY_SIZE(sdp2430_config); + omap_serial_init(); +} + +static void __init omap_2430sdp_map_io(void) +{ + omap2_map_common_io(); +} + +MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board") + /* Maintainer: Syed Khasim - Texas Instruments Inc */ + .phys_io = 0x48000000, + .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, + .boot_params = 0x80000100, + .map_io = omap_2430sdp_map_io, + .init_irq = omap_2430sdp_init_irq, + .init_machine = omap_2430sdp_init, + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 878ff9181d0e..3bb49c17c858 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -25,6 +25,8 @@ #include <linux/irq.h> #include <linux/interrupt.h> #include <linux/delay.h> +#include <linux/leds.h> +#include <linux/irq.h> #include <asm/hardware.h> #include <asm/mach-types.h> @@ -32,10 +34,12 @@ #include <asm/mach/flash.h> #include <asm/arch/gpio.h> +#include <asm/arch/led.h> #include <asm/arch/mux.h> #include <asm/arch/usb.h> #include <asm/arch/board.h> #include <asm/arch/common.h> +#include <asm/arch/gpmc.h> #include "prcm-regs.h" /* LED & Switch macros */ @@ -46,6 +50,9 @@ #define SW_UP_GPIO17 17 #define SW_DOWN_GPIO58 58 +#define APOLLON_FLASH_CS 0 +#define APOLLON_ETH_CS 1 + static struct mtd_partition apollon_partitions[] = { { .name = "X-Loader + U-Boot", @@ -85,10 +92,10 @@ static struct flash_platform_data apollon_flash_data = { .nr_parts = ARRAY_SIZE(apollon_partitions), }; -static struct resource apollon_flash_resource = { - .start = APOLLON_CS0_BASE, - .end = APOLLON_CS0_BASE + SZ_128K, - .flags = IORESOURCE_MEM, +static struct resource apollon_flash_resource[] = { + [0] = { + .flags = IORESOURCE_MEM, + }, }; static struct platform_device apollon_onenand_device = { @@ -97,14 +104,24 @@ static struct platform_device apollon_onenand_device = { .dev = { .platform_data = &apollon_flash_data, }, - .num_resources = ARRAY_SIZE(&apollon_flash_resource), - .resource = &apollon_flash_resource, + .num_resources = ARRAY_SIZE(apollon_flash_resource), + .resource = apollon_flash_resource, }; +static void __init apollon_flash_init(void) +{ + unsigned long base; + + if (gpmc_cs_request(APOLLON_FLASH_CS, SZ_128K, &base) < 0) { + printk(KERN_ERR "Cannot request OneNAND GPMC CS\n"); + return; + } + apollon_flash_resource[0].start = base; + apollon_flash_resource[0].end = base + SZ_128K - 1; +} + static struct resource apollon_smc91x_resources[] = { [0] = { - .start = APOLLON_ETHR_START, /* Physical */ - .end = APOLLON_ETHR_START + 0xf, .flags = IORESOURCE_MEM, }, [1] = { @@ -126,14 +143,51 @@ static struct platform_device apollon_lcd_device = { .id = -1, }; +static struct omap_led_config apollon_led_config[] = { + { + .cdev = { + .name = "apollon:led0", + }, + .gpio = LED0_GPIO13, + }, + { + .cdev = { + .name = "apollon:led1", + }, + .gpio = LED1_GPIO14, + }, + { + .cdev = { + .name = "apollon:led2", + }, + .gpio = LED2_GPIO15, + }, +}; + +static struct omap_led_platform_data apollon_led_data = { + .nr_leds = ARRAY_SIZE(apollon_led_config), + .leds = apollon_led_config, +}; + +static struct platform_device apollon_led_device = { + .name = "omap-led", + .id = -1, + .dev = { + .platform_data = &apollon_led_data, + }, +}; + static struct platform_device *apollon_devices[] __initdata = { &apollon_onenand_device, &apollon_smc91x_device, &apollon_lcd_device, + &apollon_led_device, }; static inline void __init apollon_init_smc91x(void) { + unsigned long base; + /* Make sure CS1 timings are correct */ GPMC_CONFIG1_1 = 0x00011203; GPMC_CONFIG2_1 = 0x001f1f01; @@ -141,13 +195,20 @@ static inline void __init apollon_init_smc91x(void) GPMC_CONFIG4_1 = 0x1c091c09; GPMC_CONFIG5_1 = 0x041f1f1f; GPMC_CONFIG6_1 = 0x000004c4; - GPMC_CONFIG7_1 = 0x00000f40 | (APOLLON_CS1_BASE >> 24); + + if (gpmc_cs_request(APOLLON_ETH_CS, SZ_16M, &base) < 0) { + printk(KERN_ERR "Failed to request GPMC CS for smc91x\n"); + return; + } + apollon_smc91x_resources[0].start = base + 0x300; + apollon_smc91x_resources[0].end = base + 0x30f; udelay(100); omap_cfg_reg(W4__24XX_GPIO74); if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) { printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", APOLLON_ETHR_GPIO_IRQ); + gpmc_cs_free(APOLLON_ETH_CS); return; } omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1); @@ -175,6 +236,13 @@ static struct omap_mmc_config apollon_mmc_config __initdata = { }, }; +static struct omap_usb_config apollon_usb_config __initdata = { + .register_dev = 1, + .hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */ + + .pins[0] = 6, +}; + static struct omap_lcd_config apollon_lcd_config __initdata = { .ctrl_name = "internal", }; @@ -182,6 +250,7 @@ static struct omap_lcd_config apollon_lcd_config __initdata = { static struct omap_board_config_kernel apollon_config[] = { { OMAP_TAG_UART, &apollon_uart_config }, { OMAP_TAG_MMC, &apollon_mmc_config }, + { OMAP_TAG_USB, &apollon_usb_config }, { OMAP_TAG_LCD, &apollon_lcd_config }, }; @@ -250,10 +319,22 @@ static void __init apollon_sw_init(void) return; } +static void __init apollon_usb_init(void) +{ + /* USB device */ + /* DEVICE_SUSPEND */ + omap_cfg_reg(P21_242X_GPIO12); + omap_request_gpio(12); + omap_set_gpio_direction(12, 0); /* OUT */ + omap_set_gpio_dataout(12, 0); +} + static void __init omap_apollon_init(void) { apollon_led_init(); apollon_sw_init(); + apollon_flash_init(); + apollon_usb_init(); /* REVISIT: where's the correct place */ omap_cfg_reg(W19_24XX_SYS_NIRQ); diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 452193f01531..f125f432cc3e 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -131,26 +131,6 @@ static struct platform_device h4_flash_device = { .resource = &h4_flash_resource, }; -static struct resource h4_smc91x_resources[] = { - [0] = { - .start = OMAP24XX_ETHR_START, /* Physical */ - .end = OMAP24XX_ETHR_START + 0xf, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ), - .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device h4_smc91x_device = { - .name = "smc91x", - .id = -1, - .num_resources = ARRAY_SIZE(h4_smc91x_resources), - .resource = h4_smc91x_resources, -}; - /* Select between the IrDA and aGPS module */ static int h4_select_irda(struct device *dev, int state) @@ -266,29 +246,14 @@ static struct platform_device h4_lcd_device = { .id = -1, }; -static struct resource h4_led_resources[] = { - [0] = { - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device h4_led_device = { - .name = "omap_dbg_led", - .id = -1, - .num_resources = ARRAY_SIZE(h4_led_resources), - .resource = h4_led_resources, -}; - static struct platform_device *h4_devices[] __initdata = { - &h4_smc91x_device, &h4_flash_device, &h4_irda_device, &h4_kp_device, &h4_lcd_device, - &h4_led_device, }; -static inline void __init h4_init_smc91x(void) +static inline void __init h4_init_debug(void) { /* Make sure CS1 timings are correct */ GPMC_CONFIG1_1 = 0x00011200; @@ -301,12 +266,8 @@ static inline void __init h4_init_smc91x(void) udelay(100); omap_cfg_reg(M15_24XX_GPIO92); - if (omap_request_gpio(OMAP24XX_ETHR_GPIO_IRQ) < 0) { - printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", - OMAP24XX_ETHR_GPIO_IRQ); - return; - } - omap_set_gpio_direction(OMAP24XX_ETHR_GPIO_IRQ, 1); + if (debug_card_init(cs_mem_base, OMAP24XX_ETHR_GPIO_IRQ) < 0) + gpmc_cs_free(eth_cs); } static void __init omap_h4_init_irq(void) @@ -314,7 +275,6 @@ static void __init omap_h4_init_irq(void) omap2_init_common_hw(); omap_init_irq(); omap_gpio_init(); - h4_init_smc91x(); } static struct omap_uart_config h4_uart_config __initdata = { diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 52ec2f2d6360..b603bc5f8e5b 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -55,8 +55,10 @@ static void omap_init_i2c(void) if (machine_is_omap_h4()) return; - omap_cfg_reg(J15_24XX_I2C2_SCL); - omap_cfg_reg(H19_24XX_I2C2_SDA); + if (!cpu_is_omap2430()) { + omap_cfg_reg(J15_24XX_I2C2_SCL); + omap_cfg_reg(H19_24XX_I2C2_SDA); + } (void) platform_device_register(&omap_i2c_device2); } diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index e290b989aa94..5a4cc2076a7d 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -22,7 +22,14 @@ #undef DEBUG +#ifdef CONFIG_ARCH_OMAP2420 #define GPMC_BASE 0x6800a000 +#endif + +#ifdef CONFIG_ARCH_OMAP2430 +#define GPMC_BASE 0x6E000000 +#endif + #define GPMC_REVISION 0x00 #define GPMC_SYSCONFIG 0x10 #define GPMC_SYSSTATUS 0x14 @@ -88,7 +95,7 @@ u32 gpmc_cs_read_reg(int cs, int idx) } /* TODO: Add support for gpmc_fck to clock framework and use it */ -static unsigned long gpmc_get_fclk_period(void) +unsigned long gpmc_get_fclk_period(void) { /* In picoseconds */ return 1000000000 / ((clk_get_rate(gpmc_l3_clk)) / 1000); @@ -104,6 +111,13 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns) return (time_ns * 1000 + tick_ps - 1) / tick_ps; } +unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns) +{ + unsigned long ticks = gpmc_ns_to_ticks(time_ns); + + return ticks * gpmc_get_fclk_period() / 1000; +} + #ifdef DEBUG static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, int time, const char *name) @@ -120,15 +134,21 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, else ticks = gpmc_ns_to_ticks(time); nr_bits = end_bit - st_bit + 1; - if (ticks >= 1 << nr_bits) + if (ticks >= 1 << nr_bits) { +#ifdef DEBUG + printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n", + cs, name, time, ticks, 1 << nr_bits); +#endif return -1; + } mask = (1 << nr_bits) - 1; l = gpmc_cs_read_reg(cs, reg); #ifdef DEBUG - printk(KERN_INFO "GPMC CS%d: %-10s: %d ticks, %3lu ns (was %i ticks)\n", + printk(KERN_INFO + "GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000, - (l >> st_bit) & mask); + (l >> st_bit) & mask, time); #endif l &= ~(mask << st_bit); l |= ticks << st_bit; @@ -157,7 +177,7 @@ int gpmc_cs_calc_divider(int cs, unsigned int sync_clk) div = l / gpmc_get_fclk_period(); if (div > 4) return -1; - if (div < 0) + if (div <= 0) div = 1; return div; @@ -191,14 +211,19 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); + /* caller is expected to have initialized CONFIG1 to cover + * at least sync vs async + */ + l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) { #ifdef DEBUG - printk(KERN_INFO "GPMC CS%d CLK period is %lu (div %d)\n", - cs, gpmc_get_fclk_period(), div); + printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n", + cs, (div * gpmc_get_fclk_period()) / 1000, div); #endif - - l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - l &= ~0x03; - l |= (div - 1); + l &= ~0x03; + l |= (div - 1); + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); + } return 0; } diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 871ace4fccb8..4dfd878d7968 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -17,7 +17,13 @@ #include <asm/io.h> +#if defined(CONFIG_ARCH_OMAP2420) #define OMAP24XX_TAP_BASE io_p2v(0x48014000) +#endif + +#if defined(CONFIG_ARCH_OMAP2430) +#define OMAP24XX_TAP_BASE io_p2v(0x4900A000) +#endif #define OMAP_TAP_IDCODE 0x0204 #define OMAP_TAP_PROD_ID 0x0208 diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 82dc70f6b779..5a4091f582ed 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -5,6 +5,7 @@ * * Copyright (C) 2005 Nokia Corporation * Author: Juha Yrjölä <juha.yrjola@nokia.com> + * Updated map desc to add 2430 support : <x0khasim@ti.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -26,6 +27,7 @@ extern void omap_sram_init(void); extern int omap2_clk_init(void); extern void omap2_check_revision(void); +extern void omap2_init_memory(void); extern void gpmc_init(void); extern void omapfb_reserve_sdram(void); @@ -40,6 +42,20 @@ static struct map_desc omap2_io_desc[] __initdata = { .length = L3_24XX_SIZE, .type = MT_DEVICE }, +#ifdef CONFIG_ARCH_OMAP2430 + { + .virtual = L4_WK_243X_VIRT, + .pfn = __phys_to_pfn(L4_WK_243X_PHYS), + .length = L4_WK_243X_SIZE, + .type = MT_DEVICE + }, + { + .virtual = OMAP243X_GPMC_VIRT, + .pfn = __phys_to_pfn(OMAP243X_GPMC_PHYS), + .length = OMAP243X_GPMC_SIZE, + .type = MT_DEVICE + }, +#endif { .virtual = DSP_MEM_24XX_VIRT, .pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS), @@ -80,5 +96,11 @@ void __init omap2_init_common_hw(void) { omap2_mux_init(); omap2_clk_init(); +/* + * Need to Fix this for 2430 + */ +#ifndef CONFIG_ARCH_OMAP2430 + omap2_init_memory(); +#endif gpmc_init(); } diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index a39d30680300..f064f725e724 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -37,7 +37,7 @@ static struct omap_irq_bank { } __attribute__ ((aligned(4))) irq_banks[] = { { /* MPU INTC */ - .base_reg = OMAP24XX_IC_BASE, + .base_reg = IO_ADDRESS(OMAP24XX_IC_BASE), .nr_irqs = 96, }, { /* XXX: DSP INTC */ @@ -47,7 +47,7 @@ static struct omap_irq_bank { /* XXX: FIQ and additional INTC support (only MPU at the moment) */ static void omap_ack_irq(unsigned int irq) { - omap_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL); + __raw_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL); } static void omap_mask_irq(unsigned int irq) @@ -60,7 +60,7 @@ static void omap_mask_irq(unsigned int irq) irq %= 32; } - omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset); + __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset); } static void omap_unmask_irq(unsigned int irq) @@ -73,7 +73,7 @@ static void omap_unmask_irq(unsigned int irq) irq %= 32; } - omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset); + __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset); } static void omap_mask_ack_irq(unsigned int irq) @@ -93,17 +93,20 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank) { unsigned long tmp; - tmp = omap_readl(bank->base_reg + INTC_REVISION) & 0xff; + tmp = __raw_readl(bank->base_reg + INTC_REVISION) & 0xff; printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx " "(revision %ld.%ld) with %d interrupts\n", bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs); - tmp = omap_readl(bank->base_reg + INTC_SYSCONFIG); + tmp = __raw_readl(bank->base_reg + INTC_SYSCONFIG); tmp |= 1 << 1; /* soft reset */ - omap_writel(tmp, bank->base_reg + INTC_SYSCONFIG); + __raw_writel(tmp, bank->base_reg + INTC_SYSCONFIG); - while (!(omap_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1)) + while (!(__raw_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1)) /* Wait for reset to complete */; + + /* Enable autoidle */ + __raw_writel(1 << 0, bank->base_reg + INTC_SYSCONFIG); } void __init omap_init_irq(void) diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/memory.c index 85cbc2a2e663..3e5d8cd4ea4f 100644 --- a/arch/arm/mach-omap2/memory.c +++ b/arch/arm/mach-omap2/memory.c @@ -30,6 +30,7 @@ #include "prcm-regs.h" #include "memory.h" + static struct memory_timings mem_timings; u32 omap2_memory_get_slow_dll_ctrl(void) @@ -99,3 +100,20 @@ void omap2_init_memory_params(u32 force_lock_to_unlock_mode) /* 90 degree phase for anything below 133Mhz + disable DLL filter */ mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8)); } + +/* turn on smart idle modes for SDRAM scheduler and controller */ +void __init omap2_init_memory(void) +{ + u32 l; + + l = SMS_SYSCONFIG; + l &= ~(0x3 << 3); + l |= (0x2 << 3); + SMS_SYSCONFIG = l; + + l = SDRC_SYSCONFIG; + l &= ~(0x3 << 3); + l |= (0x2 << 3); + SDRC_SYSCONFIG = l; + +} diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 0439906d5da7..05750975d746 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -53,8 +53,8 @@ MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1) MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1) /* 24xx GPMC chipselects, wait pin monitoring */ -MUX_CFG_24XX("E2_GPMC_NCS2", 0x08e, 0, 1, 1, 1) -MUX_CFG_24XX("L2_GPMC_NCS7", 0x093, 0, 1, 1, 1) +MUX_CFG_24XX("E2_GPMC_NCS2", 0x08e, 0, 1, 1, 1) +MUX_CFG_24XX("L2_GPMC_NCS7", 0x093, 0, 1, 1, 1) MUX_CFG_24XX("L3_GPMC_WAIT0", 0x09a, 0, 1, 1, 1) MUX_CFG_24XX("N7_GPMC_WAIT1", 0x09b, 0, 1, 1, 1) MUX_CFG_24XX("M1_GPMC_WAIT2", 0x09c, 0, 1, 1, 1) @@ -67,18 +67,18 @@ MUX_CFG_24XX("W15_24XX_MCBSP2_DR", 0x126, 1, 1, 0, 1) MUX_CFG_24XX("V15_24XX_MCBSP2_DX", 0x127, 1, 1, 0, 1) /* 24xx GPIO */ -MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1) -MUX_CFG_24XX("P21_242X_GPIO12", 0x0ca, 3, 0, 0, 1) -MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1) -MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1) -MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1) -MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1) -MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1) -MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1) +MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1) +MUX_CFG_24XX("P21_242X_GPIO12", 0x0ca, 3, 0, 0, 1) +MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1) +MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1) +MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1) +MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1) +MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1) +MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1) MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1) -MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1) +MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1) MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1) -MUX_CFG_24XX("J15_24XX_GPIO99", 0x113, 3, 1, 1, 1) +MUX_CFG_24XX("J15_24XX_GPIO99", 0x113, 3, 1, 1, 1) MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1) MUX_CFG_24XX("P14_24XX_GPIO125", 0x140, 3, 1, 1, 1) @@ -95,17 +95,17 @@ MUX_CFG_24XX("T3_242X_GPIO55", 0xd9, 3, 0, 0, 1) MUX_CFG_24XX("U2_242X_GPIO56", 0xda, 3, 0, 0, 1) /* 24xx external DMA requests */ -MUX_CFG_24XX("AA10_242X_DMAREQ0", 0x0e5, 2, 0, 0, 1) -MUX_CFG_24XX("AA6_242X_DMAREQ1", 0x0e6, 2, 0, 0, 1) -MUX_CFG_24XX("E4_242X_DMAREQ2", 0x074, 2, 0, 0, 1) -MUX_CFG_24XX("G4_242X_DMAREQ3", 0x073, 2, 0, 0, 1) -MUX_CFG_24XX("D3_242X_DMAREQ4", 0x072, 2, 0, 0, 1) -MUX_CFG_24XX("E3_242X_DMAREQ5", 0x071, 2, 0, 0, 1) +MUX_CFG_24XX("AA10_242X_DMAREQ0", 0x0e5, 2, 0, 0, 1) +MUX_CFG_24XX("AA6_242X_DMAREQ1", 0x0e6, 2, 0, 0, 1) +MUX_CFG_24XX("E4_242X_DMAREQ2", 0x074, 2, 0, 0, 1) +MUX_CFG_24XX("G4_242X_DMAREQ3", 0x073, 2, 0, 0, 1) +MUX_CFG_24XX("D3_242X_DMAREQ4", 0x072, 2, 0, 0, 1) +MUX_CFG_24XX("E3_242X_DMAREQ5", 0x071, 2, 0, 0, 1) /* TSC IRQ */ MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1) -/* UART3 */ +/* UART3 */ MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1) MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1) diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c new file mode 100644 index 000000000000..80bb42eb5082 --- /dev/null +++ b/arch/arm/mach-omap2/usb-tusb6010.c @@ -0,0 +1,349 @@ +/* + * linux/arch/arm/mach-omap2/usb-tusb6010.c + * + * Copyright (C) 2006 Nokia Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/platform_device.h> + +#include <linux/usb/musb.h> + +#include <asm/arch/gpmc.h> +#include <asm/arch/gpio.h> +#include <asm/arch/mux.h> + + +static u8 async_cs, sync_cs; +static unsigned refclk_psec; + + +/* t2_ps, when quantized to fclk units, must happen no earlier than + * the clock after after t1_NS. + * + * Return a possibly updated value of t2_ps, converted to nsec. + */ +static unsigned +next_clk(unsigned t1_NS, unsigned t2_ps, unsigned fclk_ps) +{ + unsigned t1_ps = t1_NS * 1000; + unsigned t1_f, t2_f; + + if ((t1_ps + fclk_ps) < t2_ps) + return t2_ps / 1000; + + t1_f = (t1_ps + fclk_ps - 1) / fclk_ps; + t2_f = (t2_ps + fclk_ps - 1) / fclk_ps; + + if (t1_f >= t2_f) + t2_f = t1_f + 1; + + return (t2_f * fclk_ps) / 1000; +} + +/* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */ + +static int tusb_set_async_mode(unsigned sysclk_ps, unsigned fclk_ps) +{ + struct gpmc_timings t; + unsigned t_acsnh_advnh = sysclk_ps + 3000; + unsigned tmp; + + memset(&t, 0, sizeof(t)); + + /* CS_ON = t_acsnh_acsnl */ + t.cs_on = 8; + /* ADV_ON = t_acsnh_advnh - t_advn */ + t.adv_on = next_clk(t.cs_on, t_acsnh_advnh - 7000, fclk_ps); + + /* + * READ ... from omap2420 TRM fig 12-13 + */ + + /* ADV_RD_OFF = t_acsnh_advnh */ + t.adv_rd_off = next_clk(t.adv_on, t_acsnh_advnh, fclk_ps); + + /* OE_ON = t_acsnh_advnh + t_advn_oen (then wait for nRDY) */ + t.oe_on = next_clk(t.adv_on, t_acsnh_advnh + 1000, fclk_ps); + + /* ACCESS = counters continue only after nRDY */ + tmp = t.oe_on * 1000 + 300; + t.access = next_clk(t.oe_on, tmp, fclk_ps); + + /* OE_OFF = after data gets sampled */ + tmp = t.access * 1000; + t.oe_off = next_clk(t.access, tmp, fclk_ps); + + t.cs_rd_off = t.oe_off; + + tmp = t.cs_rd_off * 1000 + 7000 /* t_acsn_rdy_z */; + t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps); + + /* + * WRITE ... from omap2420 TRM fig 12-15 + */ + + /* ADV_WR_OFF = t_acsnh_advnh */ + t.adv_wr_off = t.adv_rd_off; + + /* WE_ON = t_acsnh_advnh + t_advn_wen (then wait for nRDY) */ + t.we_on = next_clk(t.adv_wr_off, t_acsnh_advnh + 1000, fclk_ps); + + /* WE_OFF = after data gets sampled */ + tmp = t.we_on * 1000 + 300; + t.we_off = next_clk(t.we_on, tmp, fclk_ps); + + t.cs_wr_off = t.we_off; + + tmp = t.cs_wr_off * 1000 + 7000 /* t_acsn_rdy_z */; + t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps); + + return gpmc_cs_set_timings(async_cs, &t); +} + +static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps) +{ + struct gpmc_timings t; + unsigned t_scsnh_advnh = sysclk_ps + 3000; + unsigned tmp; + + memset(&t, 0, sizeof(t)); + t.cs_on = 8; + + /* ADV_ON = t_acsnh_advnh - t_advn */ + t.adv_on = next_clk(t.cs_on, t_scsnh_advnh - 7000, fclk_ps); + + /* GPMC_CLK rate = fclk rate / div */ + t.sync_clk = 12 /* 11.1 nsec */; + tmp = (t.sync_clk * 1000 + fclk_ps - 1) / fclk_ps; + if (tmp > 4) + return -ERANGE; + if (tmp <= 0) + tmp = 1; + t.page_burst_access = (fclk_ps * tmp) / 1000; + + /* + * READ ... based on omap2420 TRM fig 12-19, 12-20 + */ + + /* ADV_RD_OFF = t_scsnh_advnh */ + t.adv_rd_off = next_clk(t.adv_on, t_scsnh_advnh, fclk_ps); + + /* OE_ON = t_scsnh_advnh + t_advn_oen * fclk_ps (then wait for nRDY) */ + tmp = (t.adv_rd_off * 1000) + (3 * fclk_ps); + t.oe_on = next_clk(t.adv_on, tmp, fclk_ps); + + /* ACCESS = number of clock cycles after t_adv_eon */ + tmp = (t.oe_on * 1000) + (5 * fclk_ps); + t.access = next_clk(t.oe_on, tmp, fclk_ps); + + /* OE_OFF = after data gets sampled */ + tmp = (t.access * 1000) + (1 * fclk_ps); + t.oe_off = next_clk(t.access, tmp, fclk_ps); + + t.cs_rd_off = t.oe_off; + + tmp = t.cs_rd_off * 1000 + 7000 /* t_scsn_rdy_z */; + t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps); + + /* + * WRITE ... based on omap2420 TRM fig 12-21 + */ + + /* ADV_WR_OFF = t_scsnh_advnh */ + t.adv_wr_off = t.adv_rd_off; + + /* WE_ON = t_scsnh_advnh + t_advn_wen * fclk_ps (then wait for nRDY) */ + tmp = (t.adv_wr_off * 1000) + (3 * fclk_ps); + t.we_on = next_clk(t.adv_wr_off, tmp, fclk_ps); + + /* WE_OFF = number of clock cycles after t_adv_wen */ + tmp = (t.we_on * 1000) + (6 * fclk_ps); + t.we_off = next_clk(t.we_on, tmp, fclk_ps); + + t.cs_wr_off = t.we_off; + + tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */; + t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps); + + return gpmc_cs_set_timings(sync_cs, &t); +} + +extern unsigned long gpmc_get_fclk_period(void); + +/* tusb driver calls this when it changes the chip's clocking */ +int tusb6010_platform_retime(unsigned is_refclk) +{ + static const char error[] = + KERN_ERR "tusb6010 %s retime error %d\n"; + + unsigned fclk_ps = gpmc_get_fclk_period(); + unsigned sysclk_ps; + int status; + + if (!refclk_psec) + return -ENODEV; + + sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60; + + status = tusb_set_async_mode(sysclk_ps, fclk_ps); + if (status < 0) { + printk(error, "async", status); + goto done; + } + status = tusb_set_sync_mode(sysclk_ps, fclk_ps); + if (status < 0) + printk(error, "sync", status); +done: + return status; +} +EXPORT_SYMBOL_GPL(tusb6010_platform_retime); + +static struct resource tusb_resources[] = { + /* Order is significant! The start/end fields + * are updated during setup.. + */ + { /* Asynchronous access */ + .flags = IORESOURCE_MEM, + }, + { /* Synchronous access */ + .flags = IORESOURCE_MEM, + }, + { /* IRQ */ + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 tusb_dmamask = ~(u32)0; + +static struct platform_device tusb_device = { + .name = "musb_hdrc", + .id = -1, + .dev = { + .dma_mask = &tusb_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(tusb_resources), + .resource = tusb_resources, +}; + + +/* this may be called only from board-*.c setup code */ +int __init +tusb6010_setup_interface(struct musb_hdrc_platform_data *data, + unsigned ps_refclk, unsigned waitpin, + unsigned async, unsigned sync, + unsigned irq, unsigned dmachan) +{ + int status; + static char error[] __initdata = + KERN_ERR "tusb6010 init error %d, %d\n"; + + /* ASYNC region, primarily for PIO */ + status = gpmc_cs_request(async, SZ_16M, (unsigned long *) + &tusb_resources[0].start); + if (status < 0) { + printk(error, 1, status); + return status; + } + tusb_resources[0].end = tusb_resources[0].start + 0x9ff; + async_cs = async; + gpmc_cs_write_reg(async, GPMC_CS_CONFIG1, + GPMC_CONFIG1_PAGE_LEN(2) + | GPMC_CONFIG1_WAIT_READ_MON + | GPMC_CONFIG1_WAIT_WRITE_MON + | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin) + | GPMC_CONFIG1_READTYPE_ASYNC + | GPMC_CONFIG1_WRITETYPE_ASYNC + | GPMC_CONFIG1_DEVICESIZE_16 + | GPMC_CONFIG1_DEVICETYPE_NOR + | GPMC_CONFIG1_MUXADDDATA); + + + /* SYNC region, primarily for DMA */ + status = gpmc_cs_request(sync, SZ_16M, (unsigned long *) + &tusb_resources[1].start); + if (status < 0) { + printk(error, 2, status); + return status; + } + tusb_resources[1].end = tusb_resources[1].start + 0x9ff; + sync_cs = sync; + gpmc_cs_write_reg(sync, GPMC_CS_CONFIG1, + GPMC_CONFIG1_READMULTIPLE_SUPP + | GPMC_CONFIG1_READTYPE_SYNC + | GPMC_CONFIG1_WRITEMULTIPLE_SUPP + | GPMC_CONFIG1_WRITETYPE_SYNC + | GPMC_CONFIG1_CLKACTIVATIONTIME(1) + | GPMC_CONFIG1_PAGE_LEN(2) + | GPMC_CONFIG1_WAIT_READ_MON + | GPMC_CONFIG1_WAIT_WRITE_MON + | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin) + | GPMC_CONFIG1_DEVICESIZE_16 + | GPMC_CONFIG1_DEVICETYPE_NOR + | GPMC_CONFIG1_MUXADDDATA + /* fclk divider gets set later */ + ); + + /* IRQ */ + status = omap_request_gpio(irq); + if (status < 0) { + printk(error, 3, status); + return status; + } + omap_set_gpio_direction(irq, 1); + tusb_resources[2].start = irq + IH_GPIO_BASE; + + /* set up memory timings ... can speed them up later */ + if (!ps_refclk) { + printk(error, 4, status); + return -ENODEV; + } + refclk_psec = ps_refclk; + status = tusb6010_platform_retime(1); + if (status < 0) { + printk(error, 5, status); + return status; + } + + /* finish device setup ... */ + if (!data) { + printk(error, 6, status); + return -ENODEV; + } + data->multipoint = 1; + tusb_device.dev.platform_data = data; + + /* REVISIT let the driver know what DMA channels work */ + if (!dmachan) + tusb_device.dev.dma_mask = NULL; + else { + /* assume OMAP 2420 ES2.0 and later */ + if (dmachan & (1 << 0)) + omap_cfg_reg(AA10_242X_DMAREQ0); + if (dmachan & (1 << 1)) + omap_cfg_reg(AA6_242X_DMAREQ1); + if (dmachan & (1 << 2)) + omap_cfg_reg(E4_242X_DMAREQ2); + if (dmachan & (1 << 3)) + omap_cfg_reg(G4_242X_DMAREQ3); + if (dmachan & (1 << 4)) + omap_cfg_reg(D3_242X_DMAREQ4); + if (dmachan & (1 << 5)) + omap_cfg_reg(E3_242X_DMAREQ5); + } + + /* so far so good ... register the device */ + status = platform_device_register(&tusb_device); + if (status < 0) { + printk(error, 7, status); + return status; + } + return 0; +} diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 5ebec6d88b51..656d49661a29 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -1,6 +1,24 @@ if ARCH_PXA -menu "Intel PXA2xx Implementations" +menu "Intel PXA2xx/PXA3xx Implementations" + +if PXA3xx + +menu "Supported PXA3xx Processor Variants" + +config CPU_PXA300 + bool "PXA300 (codename Monahans-L)" + +config CPU_PXA310 + bool "PXA310 (codename Monahans-LV)" + select CPU_PXA300 + +config CPU_PXA320 + bool "PXA320 (codename Monahans-P)" + +endmenu + +endif choice prompt "Select target board" @@ -41,6 +59,15 @@ config MACH_EM_X270 bool "CompuLab EM-x270 platform" select PXA27x +config MACH_ZYLONITE + bool "PXA3xx Development Platform" + select PXA3xx + +config MACH_ARMCORE + bool "CompuLab CM-X270 modules" + select PXA27x + select IWMMXT + endchoice if PXA_SHARPSL @@ -130,6 +157,11 @@ config PXA27x help Select code specific to PXA27x variants +config PXA3xx + bool + help + Select code specific to PXA3xx variants + config PXA_SHARP_C7xx bool select PXA_SSP diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 7d6ab5c59ab9..4263527e5123 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -3,36 +3,51 @@ # # Common support (must be linked before board specific support) -obj-y += clock.o generic.o irq.o dma.o time.o -obj-$(CONFIG_PXA25x) += pxa25x.o -obj-$(CONFIG_PXA27x) += pxa27x.o +obj-y += clock.o generic.o irq.o dma.o time.o +obj-$(CONFIG_PXA25x) += pxa25x.o +obj-$(CONFIG_PXA27x) += pxa27x.o +obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o +obj-$(CONFIG_CPU_PXA300) += pxa300.o +obj-$(CONFIG_CPU_PXA320) += pxa320.o # Specific board support -obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o +obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o -obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o -obj-$(CONFIG_ARCH_PXA_IDP) += idp.o +obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o +obj-$(CONFIG_ARCH_PXA_IDP) += idp.o obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o -obj-$(CONFIG_MACH_TOSA) += tosa.o -obj-$(CONFIG_MACH_EM_X270) += em-x270.o +obj-$(CONFIG_MACH_TOSA) += tosa.o +obj-$(CONFIG_MACH_EM_X270) += em-x270.o + +ifeq ($(CONFIG_MACH_ZYLONITE),y) + obj-y += zylonite.o + obj-$(CONFIG_CPU_PXA300) += zylonite_pxa300.o + obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o +endif + +obj-$(CONFIG_MACH_ARMCORE) += cm-x270.o # Support for blinky lights led-y := leds.o -led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o -led-$(CONFIG_MACH_MAINSTONE) += leds-mainstone.o -led-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o -led-$(CONFIG_MACH_TRIZEPS4) += leds-trizeps4.o +led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o +led-$(CONFIG_MACH_MAINSTONE) += leds-mainstone.o +led-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o +led-$(CONFIG_MACH_TRIZEPS4) += leds-trizeps4.o -obj-$(CONFIG_LEDS) += $(led-y) +obj-$(CONFIG_LEDS) += $(led-y) # Misc features -obj-$(CONFIG_PM) += pm.o sleep.o -obj-$(CONFIG_PXA_SSP) += ssp.o +obj-$(CONFIG_PM) += pm.o sleep.o +obj-$(CONFIG_PXA_SSP) += ssp.o ifeq ($(CONFIG_PXA27x),y) -obj-$(CONFIG_PM) += standby.o +obj-$(CONFIG_PM) += standby.o +endif + +ifeq ($(CONFIG_PCI),y) +obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o endif diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c index 34a31caa6f9d..83ef5ecaf432 100644 --- a/arch/arm/mach-pxa/clock.c +++ b/arch/arm/mach-pxa/clock.c @@ -9,19 +9,15 @@ #include <linux/string.h> #include <linux/clk.h> #include <linux/spinlock.h> +#include <linux/platform_device.h> +#include <linux/delay.h> #include <asm/arch/pxa-regs.h> #include <asm/hardware.h> -struct clk { - struct list_head node; - unsigned long rate; - struct module *owner; - const char *name; - unsigned int enabled; - void (*enable)(void); - void (*disable)(void); -}; +#include "devices.h" +#include "generic.h" +#include "clock.h" static LIST_HEAD(clocks); static DEFINE_MUTEX(clocks_mutex); @@ -33,7 +29,8 @@ struct clk *clk_get(struct device *dev, const char *id) mutex_lock(&clocks_mutex); list_for_each_entry(p, &clocks, node) { - if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + if (strcmp(id, p->name) == 0 && + (p->dev == NULL || p->dev == dev)) { clk = p; break; } @@ -46,7 +43,6 @@ EXPORT_SYMBOL(clk_get); void clk_put(struct clk *clk) { - module_put(clk->owner); } EXPORT_SYMBOL(clk_put); @@ -56,8 +52,12 @@ int clk_enable(struct clk *clk) spin_lock_irqsave(&clocks_lock, flags); if (clk->enabled++ == 0) - clk->enable(); + clk->ops->enable(clk); spin_unlock_irqrestore(&clocks_lock, flags); + + if (clk->delay) + udelay(clk->delay); + return 0; } EXPORT_SYMBOL(clk_enable); @@ -70,54 +70,75 @@ void clk_disable(struct clk *clk) spin_lock_irqsave(&clocks_lock, flags); if (--clk->enabled == 0) - clk->disable(); + clk->ops->disable(clk); spin_unlock_irqrestore(&clocks_lock, flags); } EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { - return clk->rate; + unsigned long rate; + + rate = clk->rate; + if (clk->ops->getrate) + rate = clk->ops->getrate(clk); + + return rate; } EXPORT_SYMBOL(clk_get_rate); -static void clk_gpio27_enable(void) +static void clk_gpio27_enable(struct clk *clk) { pxa_gpio_mode(GPIO11_3_6MHz_MD); } -static void clk_gpio27_disable(void) +static void clk_gpio27_disable(struct clk *clk) { } -static struct clk clk_gpio27 = { - .name = "GPIO27_CLK", - .rate = 3686400, +static const struct clkops clk_gpio27_ops = { .enable = clk_gpio27_enable, .disable = clk_gpio27_disable, }; -int clk_register(struct clk *clk) + +void clk_cken_enable(struct clk *clk) { - mutex_lock(&clocks_mutex); - list_add(&clk->node, &clocks); - mutex_unlock(&clocks_mutex); - return 0; + CKEN |= 1 << clk->cken; } -EXPORT_SYMBOL(clk_register); -void clk_unregister(struct clk *clk) +void clk_cken_disable(struct clk *clk) { + CKEN &= ~(1 << clk->cken); +} + +const struct clkops clk_cken_ops = { + .enable = clk_cken_enable, + .disable = clk_cken_disable, +}; + +static struct clk common_clks[] = { + { + .name = "GPIO27_CLK", + .ops = &clk_gpio27_ops, + .rate = 3686400, + }, +}; + +void clks_register(struct clk *clks, size_t num) +{ + int i; + mutex_lock(&clocks_mutex); - list_del(&clk->node); + for (i = 0; i < num; i++) + list_add(&clks[i].node, &clocks); mutex_unlock(&clocks_mutex); } -EXPORT_SYMBOL(clk_unregister); static int __init clk_init(void) { - clk_register(&clk_gpio27); + clks_register(common_clks, ARRAY_SIZE(common_clks)); return 0; } arch_initcall(clk_init); diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h new file mode 100644 index 000000000000..bc6b77e1592e --- /dev/null +++ b/arch/arm/mach-pxa/clock.h @@ -0,0 +1,43 @@ +struct clk; + +struct clkops { + void (*enable)(struct clk *); + void (*disable)(struct clk *); + unsigned long (*getrate)(struct clk *); +}; + +struct clk { + struct list_head node; + const char *name; + struct device *dev; + const struct clkops *ops; + unsigned long rate; + unsigned int cken; + unsigned int delay; + unsigned int enabled; +}; + +#define INIT_CKEN(_name, _cken, _rate, _delay, _dev) \ + { \ + .name = _name, \ + .dev = _dev, \ + .ops = &clk_cken_ops, \ + .rate = _rate, \ + .cken = CKEN_##_cken, \ + .delay = _delay, \ + } + +#define INIT_CK(_name, _cken, _ops, _dev) \ + { \ + .name = _name, \ + .dev = _dev, \ + .ops = _ops, \ + .cken = CKEN_##_cken, \ + } + +extern const struct clkops clk_cken_ops; + +void clk_cken_enable(struct clk *clk); +void clk_cken_disable(struct clk *clk); + +void clks_register(struct clk *clks, size_t num); diff --git a/arch/arm/mach-pxa/cm-x270-pci.c b/arch/arm/mach-pxa/cm-x270-pci.c new file mode 100644 index 000000000000..878d3b9b8633 --- /dev/null +++ b/arch/arm/mach-pxa/cm-x270-pci.c @@ -0,0 +1,218 @@ +/* + * linux/arch/arm/mach-pxa/cm-x270-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + * + * Copyright (C) 2007 Compulab, Ltd. + * Mike Rapoport <mike@compulab.co.il> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/irq.h> + +#include <asm/mach/pci.h> +#include <asm/arch/cm-x270.h> +#include <asm/arch/pxa-regs.h> +#include <asm/mach-types.h> + +#include <asm/hardware/it8152.h> + +unsigned long it8152_base_address = CMX270_IT8152_VIRT; + +/* + * Only first 64MB of memory can be accessed via PCI. + * We use GFP_DMA to allocate safe buffers to do map/unmap. + * This is really ugly and we need a better way of specifying + * DMA-capable regions of memory. + */ +void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size, + unsigned long *zhole_size) +{ + unsigned int sz = SZ_64M >> PAGE_SHIFT; + + printk(KERN_INFO "Adjusting zones for CM-x270\n"); + + /* + * Only adjust if > 64M on current system + */ + if (node || (zone_size[0] <= sz)) + return; + + zone_size[1] = zone_size[0] - sz; + zone_size[0] = sz; + zhole_size[1] = zhole_size[0]; + zhole_size[0] = 0; +} + +static void cmx270_it8152_irq_demux(unsigned int irq, struct irq_desc *desc) +{ + /* clear our parent irq */ + GEDR(GPIO_IT8152_IRQ) = GPIO_bit(GPIO_IT8152_IRQ); + + it8152_irq_demux(irq, desc); +} + +void __cmx270_pci_init_irq(void) +{ + it8152_init_irq(); + pxa_gpio_mode(IRQ_TO_GPIO(GPIO_IT8152_IRQ)); + set_irq_type(IRQ_GPIO(GPIO_IT8152_IRQ), IRQT_RISING); + + set_irq_chained_handler(IRQ_GPIO(GPIO_IT8152_IRQ), + cmx270_it8152_irq_demux); +} + +#ifdef CONFIG_PM +static unsigned long sleep_save_ite[10]; + +void __cmx270_pci_suspend(void) +{ + /* save ITE state */ + sleep_save_ite[0] = __raw_readl(IT8152_INTC_PDCNIMR); + sleep_save_ite[1] = __raw_readl(IT8152_INTC_LPCNIMR); + sleep_save_ite[2] = __raw_readl(IT8152_INTC_LPNIAR); + + /* Clear ITE IRQ's */ + __raw_writel((0), IT8152_INTC_PDCNIRR); + __raw_writel((0), IT8152_INTC_LPCNIRR); +} + +void __cmx270_pci_resume(void) +{ + /* restore IT8152 state */ + __raw_writel((sleep_save_ite[0]), IT8152_INTC_PDCNIMR); + __raw_writel((sleep_save_ite[1]), IT8152_INTC_LPCNIMR); + __raw_writel((sleep_save_ite[2]), IT8152_INTC_LPNIAR); +} +#else +void cmx270_pci_suspend(void) {} +void cmx270_pci_resume(void) {} +#endif + +/* PCI IRQ mapping*/ +static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + printk(KERN_DEBUG "===> %s: %s slot=%x, pin=%x\n", __FUNCTION__, + pci_name(dev), slot, pin); + + irq = it8152_pci_map_irq(dev, slot, pin); + if (irq) + return irq; + + /* + Here comes the ugly part. The routing is baseboard specific, + but defining a platform for each possible base of CM-x270 is + unrealistic. Here we keep mapping for ATXBase and SB-x270. + */ + /* ATXBASE PCI slot */ + if (slot == 7) + return IT8152_PCI_INTA; + + /* ATXBase/SB-x270 CardBus */ + if (slot == 8 || slot == 0) + return IT8152_PCI_INTB; + + /* ATXBase Ethernet */ + if (slot == 9) + return IT8152_PCI_INTA; + + /* SB-x270 Ethernet */ + if (slot == 16) + return IT8152_PCI_INTA; + + /* PC104+ interrupt routing */ + if ((slot == 17) || (slot == 19)) + return IT8152_PCI_INTA; + if ((slot == 18) || (slot == 20)) + return IT8152_PCI_INTB; + + return(0); +} + +static struct pci_bus * __init +cmx270_pci_scan_bus(int nr, struct pci_sys_data *sys) +{ + printk(KERN_INFO "Initializing CM-X270 PCI subsystem\n"); + + __raw_writel(0x800, IT8152_PCI_CFG_ADDR); + if (__raw_readl(IT8152_PCI_CFG_DATA) == 0x81521283) { + printk(KERN_INFO "PCI Bridge found.\n"); + + /* set PCI I/O base at 0 */ + writel(0x848, IT8152_PCI_CFG_ADDR); + writel(0, IT8152_PCI_CFG_DATA); + + /* set PCI memory base at 0 */ + writel(0x840, IT8152_PCI_CFG_ADDR); + writel(0, IT8152_PCI_CFG_DATA); + + writel(0x20, IT8152_GPIO_GPDR); + + /* CardBus Controller on ATXbase baseboard */ + writel(0x4000, IT8152_PCI_CFG_ADDR); + if (readl(IT8152_PCI_CFG_DATA) == 0xAC51104C) { + printk(KERN_INFO "CardBus Bridge found.\n"); + + /* Configure socket 0 */ + writel(0x408C, IT8152_PCI_CFG_ADDR); + writel(0x1022, IT8152_PCI_CFG_DATA); + + writel(0x4080, IT8152_PCI_CFG_ADDR); + writel(0x3844d060, IT8152_PCI_CFG_DATA); + + writel(0x4090, IT8152_PCI_CFG_ADDR); + writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) | + 0x60440000), + IT8152_PCI_CFG_DATA); + + writel(0x4018, IT8152_PCI_CFG_ADDR); + writel(0xb0000000, IT8152_PCI_CFG_DATA); + + /* Configure socket 1 */ + writel(0x418C, IT8152_PCI_CFG_ADDR); + writel(0x1022, IT8152_PCI_CFG_DATA); + + writel(0x4180, IT8152_PCI_CFG_ADDR); + writel(0x3844d060, IT8152_PCI_CFG_DATA); + + writel(0x4190, IT8152_PCI_CFG_ADDR); + writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) | + 0x60440000), + IT8152_PCI_CFG_DATA); + + writel(0x4118, IT8152_PCI_CFG_ADDR); + writel(0xb0000000, IT8152_PCI_CFG_DATA); + } + } + return it8152_pci_scan_bus(nr, sys); +} + +static struct hw_pci cmx270_pci __initdata = { + .swizzle = pci_std_swizzle, + .map_irq = cmx270_pci_map_irq, + .nr_controllers = 1, + .setup = it8152_pci_setup, + .scan = cmx270_pci_scan_bus, +}; + +static int __init cmx270_init_pci(void) +{ + if (machine_is_armcore()) + pci_common_init(&cmx270_pci); + + return 0; +} + +subsys_initcall(cmx270_init_pci); diff --git a/arch/arm/mach-pxa/cm-x270-pci.h b/arch/arm/mach-pxa/cm-x270-pci.h new file mode 100644 index 000000000000..ffe37b66f9a0 --- /dev/null +++ b/arch/arm/mach-pxa/cm-x270-pci.h @@ -0,0 +1,13 @@ +extern void __cmx270_pci_init_irq(void); +extern void __cmx270_pci_suspend(void); +extern void __cmx270_pci_resume(void); + +#ifdef CONFIG_PCI +#define cmx270_pci_init_irq __cmx270_pci_init_irq +#define cmx270_pci_suspend __cmx270_pci_suspend +#define cmx270_pci_resume __cmx270_pci_resume +#else +#define cmx270_pci_init_irq() do {} while (0) +#define cmx270_pci_suspend() do {} while (0) +#define cmx270_pci_resume() do {} while (0) +#endif diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c new file mode 100644 index 000000000000..177664ccb2e2 --- /dev/null +++ b/arch/arm/mach-pxa/cm-x270.c @@ -0,0 +1,645 @@ +/* + * linux/arch/arm/mach-pxa/cm-x270.c + * + * Copyright (C) 2007 CompuLab, Ltd. + * Mike Rapoport <mike@compulab.co.il> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/types.h> +#include <linux/pm.h> +#include <linux/fb.h> +#include <linux/platform_device.h> +#include <linux/irq.h> +#include <linux/sysdev.h> +#include <linux/io.h> +#include <linux/delay.h> + +#include <linux/dm9000.h> +#include <linux/rtc-v3020.h> +#include <linux/serial_8250.h> + +#include <video/mbxfb.h> + +#include <asm/mach/arch.h> +#include <asm/mach-types.h> +#include <asm/mach/map.h> + +#include <asm/arch/pxa-regs.h> +#include <asm/arch/pxafb.h> +#include <asm/arch/ohci.h> +#include <asm/arch/mmc.h> +#include <asm/arch/bitfield.h> +#include <asm/arch/cm-x270.h> + +#include <asm/hardware/it8152.h> + +#include "generic.h" +#include "cm-x270-pci.h" + +#define RTC_PHYS_BASE (PXA_CS1_PHYS + (5 << 22)) +#define DM9000_PHYS_BASE (PXA_CS1_PHYS + (6 << 22)) + +static struct resource cmx270_dm9k_resource[] = { + [0] = { + .start = DM9000_PHYS_BASE, + .end = DM9000_PHYS_BASE + 4, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DM9000_PHYS_BASE + 8, + .end = DM9000_PHYS_BASE + 8 + 500, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = CMX270_ETHIRQ, + .end = CMX270_ETHIRQ, + .flags = IORESOURCE_IRQ, + } +}; + +/* for the moment we limit ourselves to 32bit IO until some + * better IO routines can be written and tested + */ +static struct dm9000_plat_data cmx270_dm9k_platdata = { + .flags = DM9000_PLATF_32BITONLY, +}; + +/* Ethernet device */ +static struct platform_device cmx270_device_dm9k = { + .name = "dm9000", + .id = 0, + .num_resources = ARRAY_SIZE(cmx270_dm9k_resource), + .resource = cmx270_dm9k_resource, + .dev = { + .platform_data = &cmx270_dm9k_platdata, + } +}; + +/* audio device */ +static struct platform_device cmx270_audio_device = { + .name = "pxa2xx-ac97", + .id = -1, +}; + +/* touchscreen controller */ +static struct platform_device cmx270_ts_device = { + .name = "ucb1400_ts", + .id = -1, +}; + +/* RTC */ +static struct resource cmx270_v3020_resource[] = { + [0] = { + .start = RTC_PHYS_BASE, + .end = RTC_PHYS_BASE + 4, + .flags = IORESOURCE_MEM, + }, +}; + +struct v3020_platform_data cmx270_v3020_pdata = { + .leftshift = 16, +}; + +static struct platform_device cmx270_rtc_device = { + .name = "v3020", + .num_resources = ARRAY_SIZE(cmx270_v3020_resource), + .resource = cmx270_v3020_resource, + .id = -1, + .dev = { + .platform_data = &cmx270_v3020_pdata, + } +}; + +/* + * CM-X270 LEDs + */ +static struct platform_device cmx270_led_device = { + .name = "cm-x270-led", + .id = -1, +}; + +/* 2700G graphics */ +static u64 fb_dma_mask = ~(u64)0; + +static struct resource cmx270_2700G_resource[] = { + /* frame buffer memory including ODFB and External SDRAM */ + [0] = { + .start = MARATHON_PHYS, + .end = MARATHON_PHYS + 0x02000000, + .flags = IORESOURCE_MEM, + }, + /* Marathon registers */ + [1] = { + .start = MARATHON_PHYS + 0x03fe0000, + .end = MARATHON_PHYS + 0x03ffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static unsigned long save_lcd_regs[10]; + +static int cmx270_marathon_probe(struct fb_info *fb) +{ + /* save PXA-270 pin settings before enabling 2700G */ + save_lcd_regs[0] = GPDR1; + save_lcd_regs[1] = GPDR2; + save_lcd_regs[2] = GAFR1_U; + save_lcd_regs[3] = GAFR2_L; + save_lcd_regs[4] = GAFR2_U; + + /* Disable PXA-270 on-chip controller driving pins */ + GPDR1 &= ~(0xfc000000); + GPDR2 &= ~(0x00c03fff); + GAFR1_U &= ~(0xfff00000); + GAFR2_L &= ~(0x0fffffff); + GAFR2_U &= ~(0x0000f000); + return 0; +} + +static int cmx270_marathon_remove(struct fb_info *fb) +{ + GPDR1 = save_lcd_regs[0]; + GPDR2 = save_lcd_regs[1]; + GAFR1_U = save_lcd_regs[2]; + GAFR2_L = save_lcd_regs[3]; + GAFR2_U = save_lcd_regs[4]; + return 0; +} + +static struct mbxfb_platform_data cmx270_2700G_data = { + .xres = { + .min = 240, + .max = 1200, + .defval = 640, + }, + .yres = { + .min = 240, + .max = 1200, + .defval = 480, + }, + .bpp = { + .min = 16, + .max = 32, + .defval = 16, + }, + .memsize = 8*1024*1024, + .probe = cmx270_marathon_probe, + .remove = cmx270_marathon_remove, +}; + +static struct platform_device cmx270_2700G = { + .name = "mbx-fb", + .dev = { + .platform_data = &cmx270_2700G_data, + .dma_mask = &fb_dma_mask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(cmx270_2700G_resource), + .resource = cmx270_2700G_resource, + .id = -1, +}; + +static u64 ata_dma_mask = ~(u64)0; + +static struct platform_device cmx270_ata = { + .name = "pata_cm_x270", + .id = -1, + .dev = { + .dma_mask = &ata_dma_mask, + .coherent_dma_mask = 0xffffffff, + }, +}; + +/* platform devices */ +static struct platform_device *platform_devices[] __initdata = { + &cmx270_device_dm9k, + &cmx270_audio_device, + &cmx270_rtc_device, + &cmx270_2700G, + &cmx270_led_device, + &cmx270_ts_device, + &cmx270_ata, +}; + +/* Map PCI companion and IDE/General Purpose CS statically */ +static struct map_desc cmx270_io_desc[] __initdata = { + [0] = { /* IDE/general purpose space */ + .virtual = CMX270_IDE104_VIRT, + .pfn = __phys_to_pfn(CMX270_IDE104_PHYS), + .length = SZ_64M - SZ_8M, + .type = MT_DEVICE + }, + [1] = { /* PCI bridge */ + .virtual = CMX270_IT8152_VIRT, + .pfn = __phys_to_pfn(CMX270_IT8152_PHYS), + .length = SZ_64M, + .type = MT_DEVICE + }, +}; + +/* + Display definitions + keep these for backwards compatibility, although symbolic names (as + e.g. in lpd270.c) looks better +*/ +#define MTYPE_STN320x240 0 +#define MTYPE_TFT640x480 1 +#define MTYPE_CRT640x480 2 +#define MTYPE_CRT800x600 3 +#define MTYPE_TFT320x240 6 +#define MTYPE_STN640x480 7 + +static struct pxafb_mode_info generic_stn_320x240_mode = { + .pixclock = 76923, + .bpp = 8, + .xres = 320, + .yres = 240, + .hsync_len = 3, + .vsync_len = 2, + .left_margin = 3, + .upper_margin = 0, + .right_margin = 3, + .lower_margin = 0, + .sync = (FB_SYNC_HOR_HIGH_ACT | + FB_SYNC_VERT_HIGH_ACT), + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info generic_stn_320x240 = { + .modes = &generic_stn_320x240_mode, + .num_modes = 1, + .lccr0 = 0, + .lccr3 = (LCCR3_PixClkDiv(0x03) | + LCCR3_Acb(0xff) | + LCCR3_PCP), + .cmap_inverse = 0, + .cmap_static = 0, +}; + +static struct pxafb_mode_info generic_tft_640x480_mode = { + .pixclock = 38461, + .bpp = 8, + .xres = 640, + .yres = 480, + .hsync_len = 60, + .vsync_len = 2, + .left_margin = 70, + .upper_margin = 10, + .right_margin = 70, + .lower_margin = 5, + .sync = 0, + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info generic_tft_640x480 = { + .modes = &generic_tft_640x480_mode, + .num_modes = 1, + .lccr0 = (LCCR0_PAS), + .lccr3 = (LCCR3_PixClkDiv(0x01) | + LCCR3_Acb(0xff) | + LCCR3_PCP), + .cmap_inverse = 0, + .cmap_static = 0, +}; + +static struct pxafb_mode_info generic_crt_640x480_mode = { + .pixclock = 38461, + .bpp = 8, + .xres = 640, + .yres = 480, + .hsync_len = 63, + .vsync_len = 2, + .left_margin = 81, + .upper_margin = 33, + .right_margin = 16, + .lower_margin = 10, + .sync = (FB_SYNC_HOR_HIGH_ACT | + FB_SYNC_VERT_HIGH_ACT), + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info generic_crt_640x480 = { + .modes = &generic_crt_640x480_mode, + .num_modes = 1, + .lccr0 = (LCCR0_PAS), + .lccr3 = (LCCR3_PixClkDiv(0x01) | + LCCR3_Acb(0xff)), + .cmap_inverse = 0, + .cmap_static = 0, +}; + +static struct pxafb_mode_info generic_crt_800x600_mode = { + .pixclock = 28846, + .bpp = 8, + .xres = 800, + .yres = 600, + .hsync_len = 63, + .vsync_len = 2, + .left_margin = 26, + .upper_margin = 21, + .right_margin = 26, + .lower_margin = 11, + .sync = (FB_SYNC_HOR_HIGH_ACT | + FB_SYNC_VERT_HIGH_ACT), + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info generic_crt_800x600 = { + .modes = &generic_crt_800x600_mode, + .num_modes = 1, + .lccr0 = (LCCR0_PAS), + .lccr3 = (LCCR3_PixClkDiv(0x02) | + LCCR3_Acb(0xff)), + .cmap_inverse = 0, + .cmap_static = 0, +}; + +static struct pxafb_mode_info generic_tft_320x240_mode = { + .pixclock = 134615, + .bpp = 16, + .xres = 320, + .yres = 240, + .hsync_len = 63, + .vsync_len = 7, + .left_margin = 75, + .upper_margin = 0, + .right_margin = 15, + .lower_margin = 15, + .sync = 0, + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info generic_tft_320x240 = { + .modes = &generic_tft_320x240_mode, + .num_modes = 1, + .lccr0 = (LCCR0_PAS), + .lccr3 = (LCCR3_PixClkDiv(0x06) | + LCCR3_Acb(0xff) | + LCCR3_PCP), + .cmap_inverse = 0, + .cmap_static = 0, +}; + +static struct pxafb_mode_info generic_stn_640x480_mode = { + .pixclock = 57692, + .bpp = 8, + .xres = 640, + .yres = 480, + .hsync_len = 4, + .vsync_len = 2, + .left_margin = 10, + .upper_margin = 5, + .right_margin = 10, + .lower_margin = 5, + .sync = (FB_SYNC_HOR_HIGH_ACT | + FB_SYNC_VERT_HIGH_ACT), + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info generic_stn_640x480 = { + .modes = &generic_stn_640x480_mode, + .num_modes = 1, + .lccr0 = 0, + .lccr3 = (LCCR3_PixClkDiv(0x02) | + LCCR3_Acb(0xff)), + .cmap_inverse = 0, + .cmap_static = 0, +}; + +static struct pxafb_mach_info *cmx270_display = &generic_crt_640x480; + +static int __init cmx270_set_display(char *str) +{ + int disp_type = simple_strtol(str, NULL, 0); + switch (disp_type) { + case MTYPE_STN320x240: + cmx270_display = &generic_stn_320x240; + break; + case MTYPE_TFT640x480: + cmx270_display = &generic_tft_640x480; + break; + case MTYPE_CRT640x480: + cmx270_display = &generic_crt_640x480; + break; + case MTYPE_CRT800x600: + cmx270_display = &generic_crt_800x600; + break; + case MTYPE_TFT320x240: + cmx270_display = &generic_tft_320x240; + break; + case MTYPE_STN640x480: + cmx270_display = &generic_stn_640x480; + break; + default: /* fallback to CRT 640x480 */ + cmx270_display = &generic_crt_640x480; + break; + } + return 1; +} + +/* + This should be done really early to get proper configuration for + frame buffer. + Indeed, pxafb parameters can be used istead, but CM-X270 bootloader + has limitied line length for kernel command line, and also it will + break compatibitlty with proprietary releases already in field. +*/ +__setup("monitor=", cmx270_set_display); + +/* PXA27x OHCI controller setup */ +static int cmx270_ohci_init(struct device *dev) +{ + /* Set the Power Control Polarity Low */ + UHCHR = (UHCHR | UHCHR_PCPL) & + ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE); + + return 0; +} + +static struct pxaohci_platform_data cmx270_ohci_platform_data = { + .port_mode = PMM_PERPORT_MODE, + .init = cmx270_ohci_init, +}; + + +static int cmx270_mci_init(struct device *dev, + irq_handler_t cmx270_detect_int, + void *data) +{ + int err; + + /* + * setup GPIO for PXA27x MMC controller + */ + pxa_gpio_mode(GPIO32_MMCCLK_MD); + pxa_gpio_mode(GPIO112_MMCCMD_MD); + pxa_gpio_mode(GPIO92_MMCDAT0_MD); + pxa_gpio_mode(GPIO109_MMCDAT1_MD); + pxa_gpio_mode(GPIO110_MMCDAT2_MD); + pxa_gpio_mode(GPIO111_MMCDAT3_MD); + + /* SB-X270 uses GPIO105 as SD power enable */ + pxa_gpio_mode(105 | GPIO_OUT); + + /* card detect IRQ on GPIO 83 */ + pxa_gpio_mode(IRQ_TO_GPIO(CMX270_MMC_IRQ)); + set_irq_type(CMX270_MMC_IRQ, IRQT_FALLING); + + err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int, + IRQF_DISABLED | IRQF_TRIGGER_FALLING, + "MMC card detect", data); + if (err) { + printk(KERN_ERR "cmx270_mci_init: MMC/SD: can't" + " request MMC card detect IRQ\n"); + return -1; + } + + return 0; +} + +static void cmx270_mci_setpower(struct device *dev, unsigned int vdd) +{ + struct pxamci_platform_data *p_d = dev->platform_data; + + if ((1 << vdd) & p_d->ocr_mask) { + printk(KERN_DEBUG "%s: on\n", __FUNCTION__); + GPCR(105) = GPIO_bit(105); + } else { + GPSR(105) = GPIO_bit(105); + printk(KERN_DEBUG "%s: off\n", __FUNCTION__); + } +} + +static void cmx270_mci_exit(struct device *dev, void *data) +{ + free_irq(CMX270_MMC_IRQ, data); +} + +static struct pxamci_platform_data cmx270_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .init = cmx270_mci_init, + .setpower = cmx270_mci_setpower, + .exit = cmx270_mci_exit, +}; + +#ifdef CONFIG_PM +static unsigned long sleep_save_msc[10]; + +static int cmx270_suspend(struct sys_device *dev, pm_message_t state) +{ + cmx270_pci_suspend(); + + /* save MSC registers */ + sleep_save_msc[0] = MSC0; + sleep_save_msc[1] = MSC1; + sleep_save_msc[2] = MSC2; + + /* setup power saving mode registers */ + PCFR = 0x0; + PSLR = 0xff400000; + PMCR = 0x00000005; + PWER = 0x80000000; + PFER = 0x00000000; + PRER = 0x00000000; + PGSR0 = 0xC0018800; + PGSR1 = 0x004F0002; + PGSR2 = 0x6021C000; + PGSR3 = 0x00020000; + + return 0; +} + +static int cmx270_resume(struct sys_device *dev) +{ + cmx270_pci_resume(); + + /* restore MSC registers */ + MSC0 = sleep_save_msc[0]; + MSC1 = sleep_save_msc[1]; + MSC2 = sleep_save_msc[2]; + + return 0; +} + +static struct sysdev_class cmx270_pm_sysclass = { + set_kset_name("pm"), + .resume = cmx270_resume, + .suspend = cmx270_suspend, +}; + +static struct sys_device cmx270_pm_device = { + .cls = &cmx270_pm_sysclass, +}; + +static int __init cmx270_pm_init(void) +{ + int error; + error = sysdev_class_register(&cmx270_pm_sysclass); + if (error == 0) + error = sysdev_register(&cmx270_pm_device); + return error; +} +#else +static int __init cmx270_pm_init(void) { return 0; } +#endif + +static void __init cmx270_init(void) +{ + cmx270_pm_init(); + + set_pxa_fb_info(cmx270_display); + + /* register CM-X270 platform devices */ + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + + /* set MCI and OHCI platform parameters */ + pxa_set_mci_info(&cmx270_mci_platform_data); + pxa_set_ohci_info(&cmx270_ohci_platform_data); + + /* This enables the STUART */ + pxa_gpio_mode(GPIO46_STRXD_MD); + pxa_gpio_mode(GPIO47_STTXD_MD); + + /* This enables the BTUART */ + pxa_gpio_mode(GPIO42_BTRXD_MD); + pxa_gpio_mode(GPIO43_BTTXD_MD); + pxa_gpio_mode(GPIO44_BTCTS_MD); + pxa_gpio_mode(GPIO45_BTRTS_MD); +} + +static void __init cmx270_init_irq(void) +{ + pxa27x_init_irq(); + + + cmx270_pci_init_irq(); + + /* Setup interrupt for dm9000 */ + pxa_gpio_mode(IRQ_TO_GPIO(CMX270_ETHIRQ)); + set_irq_type(CMX270_ETHIRQ, IRQT_RISING); + + /* Setup interrupt for 2700G */ + pxa_gpio_mode(IRQ_TO_GPIO(CMX270_GFXIRQ)); + set_irq_type(CMX270_GFXIRQ, IRQT_FALLING); +} + +static void __init cmx270_map_io(void) +{ + pxa_map_io(); + iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc)); +} + + +MACHINE_START(ARMCORE, "Compulab CM-x270") + .boot_params = 0xa0000100, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .map_io = cmx270_map_io, + .init_irq = cmx270_init_irq, + .timer = &pxa_timer, + .init_machine = cmx270_init, +MACHINE_END diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index 636fdb1c049c..94c8d5cdd60a 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -9,3 +9,6 @@ extern struct platform_device pxa_device_i2c; extern struct platform_device pxa_device_i2s; extern struct platform_device pxa_device_ficp; extern struct platform_device pxa_device_rtc; + +extern struct platform_device pxa27x_device_i2c_power; +extern struct platform_device pxa27x_device_ohci; diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 5510f6fdce55..1c34946ee16e 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -25,10 +25,6 @@ #include <linux/pm.h> #include <linux/string.h> -#include <linux/sched.h> -#include <asm/cnt32_to_63.h> -#include <asm/div64.h> - #include <asm/hardware.h> #include <asm/irq.h> #include <asm/system.h> @@ -47,66 +43,39 @@ #include "generic.h" /* - * This is the PXA2xx sched_clock implementation. This has a resolution - * of at least 308ns and a maximum value that depends on the value of - * CLOCK_TICK_RATE. - * - * The return value is guaranteed to be monotonic in that range as - * long as there is always less than 582 seconds between successive - * calls to this function. + * Get the clock frequency as reflected by CCCR and the turbo flag. + * We assume these values have been applied via a fcs. + * If info is not 0 we also display the current settings. */ -unsigned long long sched_clock(void) +unsigned int get_clk_frequency_khz(int info) { - unsigned long long v = cnt32_to_63(OSCR); - /* Note: top bit ov v needs cleared unless multiplier is even. */ - -#if CLOCK_TICK_RATE == 3686400 - /* 1E9 / 3686400 => 78125 / 288, max value = 32025597s (370 days). */ - /* The <<1 is used to get rid of tick.hi top bit */ - v *= 78125<<1; - do_div(v, 288<<1); -#elif CLOCK_TICK_RATE == 3250000 - /* 1E9 / 3250000 => 4000 / 13, max value = 709490156s (8211 days) */ - v *= 4000; - do_div(v, 13); -#elif CLOCK_TICK_RATE == 3249600 - /* 1E9 / 3249600 => 625000 / 2031, max value = 4541295s (52 days) */ - v *= 625000; - do_div(v, 2031); -#else -#warning "consider fixing sched_clock for your value of CLOCK_TICK_RATE" - /* - * 96-bit math to perform tick * NSEC_PER_SEC / CLOCK_TICK_RATE for - * any value of CLOCK_TICK_RATE. Max value is in the 80 thousand - * years range and truncation to unsigned long long limits it to - * sched_clock's max range of ~584 years. This is nice but with - * higher computation cost. - */ - { - union { - unsigned long long val; - struct { unsigned long lo, hi; }; - } x; - unsigned long long y; - - x.val = v; - x.hi &= 0x7fffffff; - y = (unsigned long long)x.lo * NSEC_PER_SEC; - x.lo = y; - y = (y >> 32) + (unsigned long long)x.hi * NSEC_PER_SEC; - x.hi = do_div(y, CLOCK_TICK_RATE); - do_div(x.val, CLOCK_TICK_RATE); - x.hi += y; - v = x.val; - } -#endif + if (cpu_is_pxa21x() || cpu_is_pxa25x()) + return pxa25x_get_clk_frequency_khz(info); + else if (cpu_is_pxa27x()) + return pxa27x_get_clk_frequency_khz(info); + else + return pxa3xx_get_clk_frequency_khz(info); +} +EXPORT_SYMBOL(get_clk_frequency_khz); - return v; +/* + * Return the current memory clock frequency in units of 10kHz + */ +unsigned int get_memclk_frequency_10khz(void) +{ + if (cpu_is_pxa21x() || cpu_is_pxa25x()) + return pxa25x_get_memclk_frequency_10khz(); + else if (cpu_is_pxa27x()) + return pxa27x_get_memclk_frequency_10khz(); + else + return pxa3xx_get_memclk_frequency_10khz(); } +EXPORT_SYMBOL(get_memclk_frequency_10khz); /* * Handy function to set GPIO alternate functions */ +int pxa_last_gpio; int pxa_gpio_mode(int gpio_mode) { @@ -115,7 +84,7 @@ int pxa_gpio_mode(int gpio_mode) int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; int gafr; - if (gpio > PXA_LAST_GPIO) + if (gpio > pxa_last_gpio) return -EINVAL; local_irq_save(flags); @@ -136,6 +105,44 @@ int pxa_gpio_mode(int gpio_mode) EXPORT_SYMBOL(pxa_gpio_mode); +int gpio_direction_input(unsigned gpio) +{ + unsigned long flags; + u32 mask; + + if (gpio > pxa_last_gpio) + return -EINVAL; + + mask = GPIO_bit(gpio); + local_irq_save(flags); + GPDR(gpio) &= ~mask; + local_irq_restore(flags); + + return 0; +} +EXPORT_SYMBOL(gpio_direction_input); + +int gpio_direction_output(unsigned gpio, int value) +{ + unsigned long flags; + u32 mask; + + if (gpio > pxa_last_gpio) + return -EINVAL; + + mask = GPIO_bit(gpio); + local_irq_save(flags); + if (value) + GPSR(gpio) = mask; + else + GPCR(gpio) = mask; + GPDR(gpio) |= mask; + local_irq_restore(flags); + + return 0; +} +EXPORT_SYMBOL(gpio_direction_output); + /* * Return GPIO level */ @@ -159,7 +166,7 @@ EXPORT_SYMBOL(pxa_gpio_set_value); /* * Routine to safely enable or disable a clock in the CKEN */ -void pxa_set_cken(int clock, int enable) +void __pxa_set_cken(int clock, int enable) { unsigned long flags; local_irq_save(flags); @@ -172,7 +179,7 @@ void pxa_set_cken(int clock, int enable) local_irq_restore(flags); } -EXPORT_SYMBOL(pxa_set_cken); +EXPORT_SYMBOL(__pxa_set_cken); /* * Intel PXA2xx internal register mapping. @@ -329,21 +336,80 @@ void __init set_pxa_fb_parent(struct device *parent_dev) pxa_device_fb.dev.parent = parent_dev; } +static struct resource pxa_resource_ffuart[] = { + { + .start = __PREG(FFUART), + .end = __PREG(FFUART) + 35, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_FFUART, + .end = IRQ_FFUART, + .flags = IORESOURCE_IRQ, + } +}; + struct platform_device pxa_device_ffuart= { .name = "pxa2xx-uart", .id = 0, + .resource = pxa_resource_ffuart, + .num_resources = ARRAY_SIZE(pxa_resource_ffuart), }; + +static struct resource pxa_resource_btuart[] = { + { + .start = __PREG(BTUART), + .end = __PREG(BTUART) + 35, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_BTUART, + .end = IRQ_BTUART, + .flags = IORESOURCE_IRQ, + } +}; + struct platform_device pxa_device_btuart = { .name = "pxa2xx-uart", .id = 1, + .resource = pxa_resource_btuart, + .num_resources = ARRAY_SIZE(pxa_resource_btuart), }; + +static struct resource pxa_resource_stuart[] = { + { + .start = __PREG(STUART), + .end = __PREG(STUART) + 35, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_STUART, + .end = IRQ_STUART, + .flags = IORESOURCE_IRQ, + } +}; + struct platform_device pxa_device_stuart = { .name = "pxa2xx-uart", .id = 2, + .resource = pxa_resource_stuart, + .num_resources = ARRAY_SIZE(pxa_resource_stuart), }; + +static struct resource pxa_resource_hwuart[] = { + { + .start = __PREG(HWUART), + .end = __PREG(HWUART) + 47, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_HWUART, + .end = IRQ_HWUART, + .flags = IORESOURCE_IRQ, + } +}; + struct platform_device pxa_device_hwuart = { .name = "pxa2xx-uart", .id = 3, + .resource = pxa_resource_hwuart, + .num_resources = ARRAY_SIZE(pxa_resource_hwuart), }; static struct resource pxai2c_resources[] = { diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index 91ab2ad8b34b..b30f240a16c7 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h @@ -15,14 +15,40 @@ extern struct sys_timer pxa_timer; extern void __init pxa_init_irq_low(void); extern void __init pxa_init_irq_high(void); extern void __init pxa_init_irq_gpio(int gpio_nr); +extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)); extern void __init pxa25x_init_irq(void); extern void __init pxa27x_init_irq(void); +extern void __init pxa3xx_init_irq(void); extern void __init pxa_map_io(void); extern unsigned int get_clk_frequency_khz(int info); +extern int pxa_last_gpio; #define SET_BANK(__nr,__start,__size) \ mi->bank[__nr].start = (__start), \ mi->bank[__nr].size = (__size), \ mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27) +#ifdef CONFIG_PXA25x +extern unsigned pxa25x_get_clk_frequency_khz(int); +extern unsigned pxa25x_get_memclk_frequency_10khz(void); +#else +#define pxa25x_get_clk_frequency_khz(x) (0) +#define pxa25x_get_memclk_frequency_10khz() (0) +#endif + +#ifdef CONFIG_PXA27x +extern unsigned pxa27x_get_clk_frequency_khz(int); +extern unsigned pxa27x_get_memclk_frequency_10khz(void); +#else +#define pxa27x_get_clk_frequency_khz(x) (0) +#define pxa27x_get_memclk_frequency_10khz() (0) +#endif + +#ifdef CONFIG_PXA3xx +extern unsigned pxa3xx_get_clk_frequency_khz(int); +extern unsigned pxa3xx_get_memclk_frequency_10khz(void); +#else +#define pxa3xx_get_clk_frequency_khz(x) (0) +#define pxa3xx_get_memclk_frequency_10khz() (0) +#endif diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index ae2ae08032d7..07acb45b16ea 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -38,33 +38,11 @@ static void pxa_unmask_low_irq(unsigned int irq) ICMR |= (1 << irq); } -static int pxa_set_wake(unsigned int irq, unsigned int on) -{ - u32 mask; - - switch (irq) { - case IRQ_RTCAlrm: - mask = PWER_RTC; - break; -#ifdef CONFIG_PXA27x - /* REVISIT can handle USBH1, USBH2, USB, MSL, USIM, ... */ -#endif - default: - return -EINVAL; - } - if (on) - PWER |= mask; - else - PWER &= ~mask; - return 0; -} - static struct irq_chip pxa_internal_chip_low = { .name = "SC", .ack = pxa_mask_low_irq, .mask = pxa_mask_low_irq, .unmask = pxa_unmask_low_irq, - .set_wake = pxa_set_wake, }; void __init pxa_init_irq_low(void) @@ -87,7 +65,7 @@ void __init pxa_init_irq_low(void) } } -#ifdef CONFIG_PXA27x +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) /* * This is for the second set of internal IRQs as found on the PXA27x. @@ -125,26 +103,6 @@ void __init pxa_init_irq_high(void) } #endif -/* Note that if an input/irq line ever gets changed to an output during - * suspend, the relevant PWER, PRER, and PFER bits should be cleared. - */ -#ifdef CONFIG_PXA27x - -/* PXA27x: Various gpios can issue wakeup events. This logic only - * handles the simple cases, not the WEMUX2 and WEMUX3 options - */ -#define PXA27x_GPIO_NOWAKE_MASK \ - ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2)) -#define WAKEMASK(gpio) \ - (((gpio) <= 15) \ - ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \ - : ((gpio == 35) ? (1 << 24) : 0)) -#else - -/* pxa 210, 250, 255, 26x: gpios 0..15 can issue wakeups */ -#define WAKEMASK(gpio) (((gpio) <= 15) ? (1 << (gpio)) : 0) -#endif - /* * PXA GPIO edge detection for IRQs: * IRQs are generated on Falling-Edge, Rising-Edge, or both. @@ -158,11 +116,9 @@ static long GPIO_IRQ_mask[4]; static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) { int gpio, idx; - u32 mask; gpio = IRQ_TO_GPIO(irq); idx = gpio >> 5; - mask = WAKEMASK(gpio); if (type == IRQT_PROBE) { /* Don't mess with enabled GPIOs using preconfigured edges or @@ -182,19 +138,15 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) if (type & __IRQT_RISEDGE) { /* printk("rising "); */ __set_bit (gpio, GPIO_IRQ_rising_edge); - PRER |= mask; } else { __clear_bit (gpio, GPIO_IRQ_rising_edge); - PRER &= ~mask; } if (type & __IRQT_FALEDGE) { /* printk("falling "); */ __set_bit (gpio, GPIO_IRQ_falling_edge); - PFER |= mask; } else { __clear_bit (gpio, GPIO_IRQ_falling_edge); - PFER &= ~mask; } /* printk("edges\n"); */ @@ -213,29 +165,12 @@ static void pxa_ack_low_gpio(unsigned int irq) GEDR0 = (1 << (irq - IRQ_GPIO0)); } -static int pxa_set_gpio_wake(unsigned int irq, unsigned int on) -{ - int gpio = IRQ_TO_GPIO(irq); - u32 mask = WAKEMASK(gpio); - - if (!mask) - return -EINVAL; - - if (on) - PWER |= mask; - else - PWER &= ~mask; - return 0; -} - - static struct irq_chip pxa_low_gpio_chip = { .name = "GPIO-l", .ack = pxa_ack_low_gpio, .mask = pxa_mask_low_irq, .unmask = pxa_unmask_low_irq, .set_type = pxa_gpio_irq_type, - .set_wake = pxa_set_gpio_wake, }; /* @@ -342,13 +277,14 @@ static struct irq_chip pxa_muxed_gpio_chip = { .mask = pxa_mask_muxed_gpio, .unmask = pxa_unmask_muxed_gpio, .set_type = pxa_gpio_irq_type, - .set_wake = pxa_set_gpio_wake, }; void __init pxa_init_irq_gpio(int gpio_nr) { int irq, i; + pxa_last_gpio = gpio_nr - 1; + /* clear all GPIO edge detects */ for (i = 0; i < gpio_nr; i += 32) { GFER(i) = 0; @@ -375,3 +311,13 @@ void __init pxa_init_irq_gpio(int gpio_nr) set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low); set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler); } + +void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)) +{ + pxa_internal_chip_low.set_wake = set_wake; +#ifdef CONFIG_PXA27x + pxa_internal_chip_high.set_wake = set_wake; +#endif + pxa_low_gpio_chip.set_wake = set_wake; + pxa_muxed_gpio_chip.set_wake = set_wake; +} diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index e70048fd00a5..011a1a72b61c 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -512,6 +512,25 @@ static void __init lubbock_map_io(void) pxa_gpio_mode(GPIO44_BTCTS_MD); pxa_gpio_mode(GPIO45_BTRTS_MD); + GPSR(GPIO48_nPOE) = + GPIO_bit(GPIO48_nPOE) | + GPIO_bit(GPIO49_nPWE) | + GPIO_bit(GPIO50_nPIOR) | + GPIO_bit(GPIO51_nPIOW) | + GPIO_bit(GPIO52_nPCE_1) | + GPIO_bit(GPIO53_nPCE_2); + + pxa_gpio_mode(GPIO48_nPOE_MD); + pxa_gpio_mode(GPIO49_nPWE_MD); + pxa_gpio_mode(GPIO50_nPIOR_MD); + pxa_gpio_mode(GPIO51_nPIOW_MD); + pxa_gpio_mode(GPIO52_nPCE_1_MD); + pxa_gpio_mode(GPIO53_nPCE_2_MD); + pxa_gpio_mode(GPIO54_pSKTSEL_MD); + pxa_gpio_mode(GPIO55_nPREG_MD); + pxa_gpio_mode(GPIO56_nPWAIT_MD); + pxa_gpio_mode(GPIO57_nIOIS16_MD); + /* This is for the SMC chip select */ pxa_gpio_mode(GPIO79_nCS_3_MD); diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index b02c79c7e6a3..a4bc3483cbb3 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -444,6 +444,25 @@ static void __init mainstone_init(void) */ pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD); + GPSR(GPIO48_nPOE) = + GPIO_bit(GPIO48_nPOE) | + GPIO_bit(GPIO49_nPWE) | + GPIO_bit(GPIO50_nPIOR) | + GPIO_bit(GPIO51_nPIOW) | + GPIO_bit(GPIO85_nPCE_1) | + GPIO_bit(GPIO54_nPCE_2); + + pxa_gpio_mode(GPIO48_nPOE_MD); + pxa_gpio_mode(GPIO49_nPWE_MD); + pxa_gpio_mode(GPIO50_nPIOR_MD); + pxa_gpio_mode(GPIO51_nPIOW_MD); + pxa_gpio_mode(GPIO85_nPCE_1_MD); + pxa_gpio_mode(GPIO54_nPCE_2_MD); + pxa_gpio_mode(GPIO79_pSKTSEL_MD); + pxa_gpio_mode(GPIO55_nPREG_MD); + pxa_gpio_mode(GPIO56_nPWAIT_MD); + pxa_gpio_mode(GPIO57_nIOIS16_MD); + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); /* reading Mainstone's "Virtual Configuration Register" diff --git a/arch/arm/mach-pxa/mfp.c b/arch/arm/mach-pxa/mfp.c new file mode 100644 index 000000000000..5cd3cadbbd10 --- /dev/null +++ b/arch/arm/mach-pxa/mfp.c @@ -0,0 +1,235 @@ +/* + * linux/arch/arm/mach-pxa/mfp.c + * + * PXA3xx Multi-Function Pin Support + * + * Copyright (C) 2007 Marvell Internation Ltd. + * + * 2007-08-21: eric miao <eric.y.miao@gmail.com> + * initial version + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> + +#include <asm/hardware.h> +#include <asm/arch/mfp.h> + +/* mfp_spin_lock is used to ensure that MFP register configuration + * (most likely a read-modify-write operation) is atomic, and that + * mfp_table[] is consistent + */ +static DEFINE_SPINLOCK(mfp_spin_lock); + +static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE); +static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX]; + +#define mfpr_readl(off) \ + __raw_readl(mfpr_mmio_base + (off)) + +#define mfpr_writel(off, val) \ + __raw_writel(val, mfpr_mmio_base + (off)) + +/* + * perform a read-back of any MFPR register to make sure the + * previous writings are finished + */ +#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0) + +static inline void __mfp_config(int pin, unsigned long val) +{ + unsigned long off = mfp_table[pin].mfpr_off; + + mfp_table[pin].mfpr_val = val; + mfpr_writel(off, val); +} + +void pxa3xx_mfp_config(mfp_cfg_t *mfp_cfgs, int num) +{ + int i, pin; + unsigned long val, flags; + mfp_cfg_t *mfp_cfg = mfp_cfgs; + + spin_lock_irqsave(&mfp_spin_lock, flags); + + for (i = 0; i < num; i++, mfp_cfg++) { + pin = MFP_CFG_PIN(*mfp_cfg); + val = MFP_CFG_VAL(*mfp_cfg); + + BUG_ON(pin >= MFP_PIN_MAX); + + __mfp_config(pin, val); + } + + mfpr_sync(); + spin_unlock_irqrestore(&mfp_spin_lock, flags); +} + +unsigned long pxa3xx_mfp_read(int mfp) +{ + unsigned long val, flags; + + BUG_ON(mfp >= MFP_PIN_MAX); + + spin_lock_irqsave(&mfp_spin_lock, flags); + val = mfpr_readl(mfp_table[mfp].mfpr_off); + spin_unlock_irqrestore(&mfp_spin_lock, flags); + + return val; +} + +void pxa3xx_mfp_write(int mfp, unsigned long val) +{ + unsigned long flags; + + BUG_ON(mfp >= MFP_PIN_MAX); + + spin_lock_irqsave(&mfp_spin_lock, flags); + mfpr_writel(mfp_table[mfp].mfpr_off, val); + mfpr_sync(); + spin_unlock_irqrestore(&mfp_spin_lock, flags); +} + +void pxa3xx_mfp_set_afds(int mfp, int af, int ds) +{ + uint32_t mfpr_off, mfpr_val; + unsigned long flags; + + BUG_ON(mfp >= MFP_PIN_MAX); + + spin_lock_irqsave(&mfp_spin_lock, flags); + mfpr_off = mfp_table[mfp].mfpr_off; + + mfpr_val = mfpr_readl(mfpr_off); + mfpr_val &= ~(MFPR_AF_MASK | MFPR_DRV_MASK); + mfpr_val |= (((af & 0x7) << MFPR_ALT_OFFSET) | + ((ds & 0x7) << MFPR_DRV_OFFSET)); + + mfpr_writel(mfpr_off, mfpr_val); + mfpr_sync(); + + spin_unlock_irqrestore(&mfp_spin_lock, flags); +} + +void pxa3xx_mfp_set_rdh(int mfp, int rdh) +{ + uint32_t mfpr_off, mfpr_val; + unsigned long flags; + + BUG_ON(mfp >= MFP_PIN_MAX); + + spin_lock_irqsave(&mfp_spin_lock, flags); + + mfpr_off = mfp_table[mfp].mfpr_off; + + mfpr_val = mfpr_readl(mfpr_off); + mfpr_val &= ~MFPR_RDH_MASK; + + if (likely(rdh)) + mfpr_val |= (1u << MFPR_SS_OFFSET); + + mfpr_writel(mfpr_off, mfpr_val); + mfpr_sync(); + + spin_unlock_irqrestore(&mfp_spin_lock, flags); +} + +void pxa3xx_mfp_set_lpm(int mfp, int lpm) +{ + uint32_t mfpr_off, mfpr_val; + unsigned long flags; + + BUG_ON(mfp >= MFP_PIN_MAX); + + spin_lock_irqsave(&mfp_spin_lock, flags); + + mfpr_off = mfp_table[mfp].mfpr_off; + mfpr_val = mfpr_readl(mfpr_off); + mfpr_val &= ~MFPR_LPM_MASK; + + if (lpm & 0x1) mfpr_val |= 1u << MFPR_SON_OFFSET; + if (lpm & 0x2) mfpr_val |= 1u << MFPR_SD_OFFSET; + if (lpm & 0x4) mfpr_val |= 1u << MFPR_PU_OFFSET; + if (lpm & 0x8) mfpr_val |= 1u << MFPR_PD_OFFSET; + if (lpm &0x10) mfpr_val |= 1u << MFPR_PS_OFFSET; + + mfpr_writel(mfpr_off, mfpr_val); + mfpr_sync(); + + spin_unlock_irqrestore(&mfp_spin_lock, flags); +} + +void pxa3xx_mfp_set_pull(int mfp, int pull) +{ + uint32_t mfpr_off, mfpr_val; + unsigned long flags; + + BUG_ON(mfp >= MFP_PIN_MAX); + + spin_lock_irqsave(&mfp_spin_lock, flags); + + mfpr_off = mfp_table[mfp].mfpr_off; + mfpr_val = mfpr_readl(mfpr_off); + mfpr_val &= ~MFPR_PULL_MASK; + mfpr_val |= ((pull & 0x7u) << MFPR_PD_OFFSET); + + mfpr_writel(mfpr_off, mfpr_val); + mfpr_sync(); + + spin_unlock_irqrestore(&mfp_spin_lock, flags); +} + +void pxa3xx_mfp_set_edge(int mfp, int edge) +{ + uint32_t mfpr_off, mfpr_val; + unsigned long flags; + + BUG_ON(mfp >= MFP_PIN_MAX); + + spin_lock_irqsave(&mfp_spin_lock, flags); + + mfpr_off = mfp_table[mfp].mfpr_off; + mfpr_val = mfpr_readl(mfpr_off); + + mfpr_val &= ~MFPR_EDGE_MASK; + mfpr_val |= (edge & 0x3u) << MFPR_ERE_OFFSET; + mfpr_val |= (!edge & 0x1) << MFPR_EC_OFFSET; + + mfpr_writel(mfpr_off, mfpr_val); + mfpr_sync(); + + spin_unlock_irqrestore(&mfp_spin_lock, flags); +} + +void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map) +{ + struct pxa3xx_mfp_addr_map *p; + unsigned long offset, flags; + int i; + + spin_lock_irqsave(&mfp_spin_lock, flags); + + for (p = map; p->start != MFP_PIN_INVALID; p++) { + offset = p->offset; + i = p->start; + + do { + mfp_table[i].mfpr_off = offset; + mfp_table[i].mfpr_val = 0; + offset += 4; i++; + } while ((i <= p->end) && (p->end != -1)); + } + + spin_unlock_irqrestore(&mfp_spin_lock, flags); +} + +void __init pxa3xx_init_mfp(void) +{ + memset(mfp_table, 0, sizeof(mfp_table)); +} diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 6dfcca72e90f..0d6a72504caa 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -30,6 +30,7 @@ #include "generic.h" #include "devices.h" +#include "clock.h" /* * Various clock factors driven by the CCCR register. @@ -53,7 +54,7 @@ static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 }; * We assume these values have been applied via a fcs. * If info is not 0 we also display the current settings. */ -unsigned int get_clk_frequency_khz(int info) +unsigned int pxa25x_get_clk_frequency_khz(int info) { unsigned long cccr, turbo; unsigned int l, L, m, M, n2, N; @@ -86,27 +87,48 @@ unsigned int get_clk_frequency_khz(int info) return (turbo & 1) ? (N/1000) : (M/1000); } -EXPORT_SYMBOL(get_clk_frequency_khz); - /* * Return the current memory clock frequency in units of 10kHz */ -unsigned int get_memclk_frequency_10khz(void) +unsigned int pxa25x_get_memclk_frequency_10khz(void) { return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK / 10000; } -EXPORT_SYMBOL(get_memclk_frequency_10khz); - -/* - * Return the current LCD clock frequency in units of 10kHz - */ -unsigned int get_lcdclk_frequency_10khz(void) +static unsigned long clk_pxa25x_lcd_getrate(struct clk *clk) { - return get_memclk_frequency_10khz(); + return pxa25x_get_memclk_frequency_10khz() * 10000; } -EXPORT_SYMBOL(get_lcdclk_frequency_10khz); +static const struct clkops clk_pxa25x_lcd_ops = { + .enable = clk_cken_enable, + .disable = clk_cken_disable, + .getrate = clk_pxa25x_lcd_getrate, +}; + +/* + * 3.6864MHz -> OST, GPIO, SSP, PWM, PLLs (95.842MHz, 147.456MHz) + * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz + * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly) + */ +static struct clk pxa25x_clks[] = { + INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev), + INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev), + INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev), + INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev), + INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL), + INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev), + INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev), + INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev), + /* + INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), + INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), + INIT_CKEN("SSPCLK", SSP, 3686400, 0, NULL), + INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL), + INIT_CKEN("NSSPCLK", NSSP, 3686400, 0, NULL), + */ + INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL), +}; #ifdef CONFIG_PM @@ -205,10 +227,52 @@ static void __init pxa25x_init_pm(void) } #endif +/* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm + */ + +static int pxa25x_set_wake(unsigned int irq, unsigned int on) +{ + int gpio = IRQ_TO_GPIO(irq); + uint32_t gpio_bit, mask = 0; + + if (gpio >= 0 && gpio <= 15) { + gpio_bit = GPIO_bit(gpio); + mask = gpio_bit; + if (on) { + if (GRER(gpio) | gpio_bit) + PRER |= gpio_bit; + else + PRER &= ~gpio_bit; + + if (GFER(gpio) | gpio_bit) + PFER |= gpio_bit; + else + PFER &= ~gpio_bit; + } + goto set_pwer; + } + + if (irq == IRQ_RTCAlrm) { + mask = PWER_RTC; + goto set_pwer; + } + + return -EINVAL; + +set_pwer: + if (on) + PWER |= mask; + else + PWER &=~mask; + + return 0; +} + void __init pxa25x_init_irq(void) { pxa_init_irq_low(); pxa_init_irq_gpio(85); + pxa_init_irq_set_wake(pxa25x_set_wake); } static struct platform_device *pxa25x_devices[] __initdata = { @@ -229,6 +293,8 @@ static int __init pxa25x_init(void) int ret = 0; if (cpu_is_pxa21x() || cpu_is_pxa25x()) { + clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks)); + if ((ret = pxa_init_dma(16))) return ret; #ifdef CONFIG_PM diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 203371ab19db..2d7fc39732e4 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -27,6 +27,7 @@ #include "generic.h" #include "devices.h" +#include "clock.h" /* Crystal clock: 13MHz */ #define BASE_CLK 13000000 @@ -36,7 +37,7 @@ * We assume these values have been applied via a fcs. * If info is not 0 we also display the current settings. */ -unsigned int get_clk_frequency_khz( int info) +unsigned int pxa27x_get_clk_frequency_khz(int info) { unsigned long ccsr, clkcfg; unsigned int l, L, m, M, n2, N, S; @@ -79,7 +80,7 @@ unsigned int get_clk_frequency_khz( int info) * Return the current mem clock frequency in units of 10kHz as * reflected by CCCR[A], B, and L */ -unsigned int get_memclk_frequency_10khz(void) +unsigned int pxa27x_get_memclk_frequency_10khz(void) { unsigned long ccsr, clkcfg; unsigned int l, L, m, M; @@ -104,7 +105,7 @@ unsigned int get_memclk_frequency_10khz(void) /* * Return the current LCD clock frequency in units of 10kHz as */ -unsigned int get_lcdclk_frequency_10khz(void) +static unsigned int pxa27x_get_lcdclk_frequency_10khz(void) { unsigned long ccsr; unsigned int l, L, k, K; @@ -120,9 +121,47 @@ unsigned int get_lcdclk_frequency_10khz(void) return (K / 10000); } -EXPORT_SYMBOL(get_clk_frequency_khz); -EXPORT_SYMBOL(get_memclk_frequency_10khz); -EXPORT_SYMBOL(get_lcdclk_frequency_10khz); +static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk) +{ + return pxa27x_get_lcdclk_frequency_10khz() * 10000; +} + +static const struct clkops clk_pxa27x_lcd_ops = { + .enable = clk_cken_enable, + .disable = clk_cken_disable, + .getrate = clk_pxa27x_lcd_getrate, +}; + +static struct clk pxa27x_clks[] = { + INIT_CK("LCDCLK", LCD, &clk_pxa27x_lcd_ops, &pxa_device_fb.dev), + INIT_CK("CAMCLK", CAMERA, &clk_pxa27x_lcd_ops, NULL), + + INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev), + INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev), + INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL), + + INIT_CKEN("I2SCLK", I2S, 14682000, 0, &pxa_device_i2s.dev), + INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), + INIT_CKEN("UDCCLK", USB, 48000000, 5, &pxa_device_udc.dev), + INIT_CKEN("MMCCLK", MMC, 19500000, 0, &pxa_device_mci.dev), + INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev), + + INIT_CKEN("USBCLK", USB, 48000000, 0, &pxa27x_device_ohci.dev), + INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev), + INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL), + + /* + INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL), + INIT_CKEN("SSPCLK", SSP1, 13000000, 0, NULL), + INIT_CKEN("SSPCLK", SSP2, 13000000, 0, NULL), + INIT_CKEN("SSPCLK", SSP3, 13000000, 0, NULL), + INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL), + INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL), + INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL), + INIT_CKEN("IMCLK", IM, 0, 0, NULL), + INIT_CKEN("MEMCLK", MEMC, 0, 0, NULL), + */ +}; #ifdef CONFIG_PM @@ -267,6 +306,69 @@ static void __init pxa27x_init_pm(void) } #endif +/* PXA27x: Various gpios can issue wakeup events. This logic only + * handles the simple cases, not the WEMUX2 and WEMUX3 options + */ +#define PXA27x_GPIO_NOWAKE_MASK \ + ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2)) +#define WAKEMASK(gpio) \ + (((gpio) <= 15) \ + ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \ + : ((gpio == 35) ? (1 << 24) : 0)) + +static int pxa27x_set_wake(unsigned int irq, unsigned int on) +{ + int gpio = IRQ_TO_GPIO(irq); + uint32_t mask; + + if ((gpio >= 0 && gpio <= 15) || (gpio == 35)) { + if (WAKEMASK(gpio) == 0) + return -EINVAL; + + mask = WAKEMASK(gpio); + + if (on) { + if (GRER(gpio) | GPIO_bit(gpio)) + PRER |= mask; + else + PRER &= ~mask; + + if (GFER(gpio) | GPIO_bit(gpio)) + PFER |= mask; + else + PFER &= ~mask; + } + goto set_pwer; + } + + switch (irq) { + case IRQ_RTCAlrm: + mask = PWER_RTC; + break; + case IRQ_USB: + mask = 1u << 26; + break; + default: + return -EINVAL; + } + +set_pwer: + if (on) + PWER |= mask; + else + PWER &=~mask; + + return 0; +} + +void __init pxa27x_init_irq(void) +{ + pxa_init_irq_low(); + pxa_init_irq_high(); + pxa_init_irq_gpio(128); + pxa_init_irq_set_wake(pxa27x_set_wake); +} + /* * device registration specific to PXA27x. */ @@ -286,7 +388,7 @@ static struct resource pxa27x_ohci_resources[] = { }, }; -static struct platform_device pxa27x_device_ohci = { +struct platform_device pxa27x_device_ohci = { .name = "pxa27x-ohci", .id = -1, .dev = { @@ -314,7 +416,7 @@ static struct resource i2c_power_resources[] = { }, }; -static struct platform_device pxa27x_device_i2c_power = { +struct platform_device pxa27x_device_i2c_power = { .name = "pxa2xx-i2c", .id = 1, .resource = i2c_power_resources, @@ -336,17 +438,12 @@ static struct platform_device *devices[] __initdata = { &pxa27x_device_ohci, }; -void __init pxa27x_init_irq(void) -{ - pxa_init_irq_low(); - pxa_init_irq_high(); - pxa_init_irq_gpio(128); -} - static int __init pxa27x_init(void) { int ret = 0; if (cpu_is_pxa27x()) { + clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks)); + if ((ret = pxa_init_dma(32))) return ret; #ifdef CONFIG_PM diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c new file mode 100644 index 000000000000..5363b1322652 --- /dev/null +++ b/arch/arm/mach-pxa/pxa300.c @@ -0,0 +1,93 @@ +/* + * linux/arch/arm/mach-pxa/pxa300.c + * + * Code specific to PXA300/PXA310 + * + * Copyright (C) 2007 Marvell Internation Ltd. + * + * 2007-08-21: eric miao <eric.y.miao@gmail.com> + * initial version + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/kernel.h> + +#include <asm/hardware.h> +#include <asm/arch/mfp-pxa300.h> + +static struct pxa3xx_mfp_addr_map pxa300_mfp_addr_map[] __initdata = { + + MFP_ADDR_X(GPIO0, GPIO2, 0x00b4), + MFP_ADDR_X(GPIO3, GPIO26, 0x027c), + MFP_ADDR_X(GPIO27, GPIO127, 0x0400), + MFP_ADDR_X(GPIO0_2, GPIO6_2, 0x02ec), + + MFP_ADDR(nBE0, 0x0204), + MFP_ADDR(nBE1, 0x0208), + + MFP_ADDR(nLUA, 0x0244), + MFP_ADDR(nLLA, 0x0254), + + MFP_ADDR(DF_CLE_nOE, 0x0240), + MFP_ADDR(DF_nRE_nOE, 0x0200), + MFP_ADDR(DF_ALE_nWE, 0x020C), + MFP_ADDR(DF_INT_RnB, 0x00C8), + MFP_ADDR(DF_nCS0, 0x0248), + MFP_ADDR(DF_nCS1, 0x0278), + MFP_ADDR(DF_nWE, 0x00CC), + + MFP_ADDR(DF_ADDR0, 0x0210), + MFP_ADDR(DF_ADDR1, 0x0214), + MFP_ADDR(DF_ADDR2, 0x0218), + MFP_ADDR(DF_ADDR3, 0x021C), + + MFP_ADDR(DF_IO0, 0x0220), + MFP_ADDR(DF_IO1, 0x0228), + MFP_ADDR(DF_IO2, 0x0230), + MFP_ADDR(DF_IO3, 0x0238), + MFP_ADDR(DF_IO4, 0x0258), + MFP_ADDR(DF_IO5, 0x0260), + MFP_ADDR(DF_IO6, 0x0268), + MFP_ADDR(DF_IO7, 0x0270), + MFP_ADDR(DF_IO8, 0x0224), + MFP_ADDR(DF_IO9, 0x022C), + MFP_ADDR(DF_IO10, 0x0234), + MFP_ADDR(DF_IO11, 0x023C), + MFP_ADDR(DF_IO12, 0x025C), + MFP_ADDR(DF_IO13, 0x0264), + MFP_ADDR(DF_IO14, 0x026C), + MFP_ADDR(DF_IO15, 0x0274), + + MFP_ADDR_END, +}; + +/* override pxa300 MFP register addresses */ +static struct pxa3xx_mfp_addr_map pxa310_mfp_addr_map[] __initdata = { + MFP_ADDR_X(GPIO30, GPIO98, 0x0418), + MFP_ADDR_X(GPIO7_2, GPIO12_2, 0x052C), + + MFP_ADDR(ULPI_STP, 0x040C), + MFP_ADDR(ULPI_NXT, 0x0410), + MFP_ADDR(ULPI_DIR, 0x0414), + + MFP_ADDR_END, +}; + +static int __init pxa300_init(void) +{ + if (cpu_is_pxa300() || cpu_is_pxa310()) { + pxa3xx_init_mfp(); + pxa3xx_mfp_init_addr(pxa300_mfp_addr_map); + } + + if (cpu_is_pxa310()) + pxa3xx_mfp_init_addr(pxa310_mfp_addr_map); + + return 0; +} + +core_initcall(pxa300_init); diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c new file mode 100644 index 000000000000..cd9eba5b3df9 --- /dev/null +++ b/arch/arm/mach-pxa/pxa320.c @@ -0,0 +1,88 @@ +/* + * linux/arch/arm/mach-pxa/pxa320.c + * + * Code specific to PXA320 + * + * Copyright (C) 2007 Marvell Internation Ltd. + * + * 2007-08-21: eric miao <eric.y.miao@gmail.com> + * initial version + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/kernel.h> + +#include <asm/hardware.h> +#include <asm/arch/mfp.h> +#include <asm/arch/mfp-pxa320.h> + +static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = { + + MFP_ADDR_X(GPIO0, GPIO4, 0x0124), + MFP_ADDR_X(GPIO5, GPIO26, 0x028C), + MFP_ADDR_X(GPIO27, GPIO62, 0x0400), + MFP_ADDR_X(GPIO63, GPIO73, 0x04B4), + MFP_ADDR_X(GPIO74, GPIO98, 0x04F0), + MFP_ADDR_X(GPIO99, GPIO127, 0x0600), + MFP_ADDR_X(GPIO0_2, GPIO5_2, 0x0674), + MFP_ADDR_X(GPIO6_2, GPIO13_2, 0x0494), + MFP_ADDR_X(GPIO14_2, GPIO17_2, 0x04E0), + + MFP_ADDR(nXCVREN, 0x0138), + MFP_ADDR(DF_CLE_nOE, 0x0204), + MFP_ADDR(DF_nADV1_ALE, 0x0208), + MFP_ADDR(DF_SCLK_S, 0x020C), + MFP_ADDR(DF_SCLK_E, 0x0210), + MFP_ADDR(nBE0, 0x0214), + MFP_ADDR(nBE1, 0x0218), + MFP_ADDR(DF_nADV2_ALE, 0x021C), + MFP_ADDR(DF_INT_RnB, 0x0220), + MFP_ADDR(DF_nCS0, 0x0224), + MFP_ADDR(DF_nCS1, 0x0228), + MFP_ADDR(DF_nWE, 0x022C), + MFP_ADDR(DF_nRE_nOE, 0x0230), + MFP_ADDR(nLUA, 0x0234), + MFP_ADDR(nLLA, 0x0238), + MFP_ADDR(DF_ADDR0, 0x023C), + MFP_ADDR(DF_ADDR1, 0x0240), + MFP_ADDR(DF_ADDR2, 0x0244), + MFP_ADDR(DF_ADDR3, 0x0248), + MFP_ADDR(DF_IO0, 0x024C), + MFP_ADDR(DF_IO8, 0x0250), + MFP_ADDR(DF_IO1, 0x0254), + MFP_ADDR(DF_IO9, 0x0258), + MFP_ADDR(DF_IO2, 0x025C), + MFP_ADDR(DF_IO10, 0x0260), + MFP_ADDR(DF_IO3, 0x0264), + MFP_ADDR(DF_IO11, 0x0268), + MFP_ADDR(DF_IO4, 0x026C), + MFP_ADDR(DF_IO12, 0x0270), + MFP_ADDR(DF_IO5, 0x0274), + MFP_ADDR(DF_IO13, 0x0278), + MFP_ADDR(DF_IO6, 0x027C), + MFP_ADDR(DF_IO14, 0x0280), + MFP_ADDR(DF_IO7, 0x0284), + MFP_ADDR(DF_IO15, 0x0288), + + MFP_ADDR_END, +}; + +static void __init pxa320_init_mfp(void) +{ + pxa3xx_init_mfp(); + pxa3xx_mfp_init_addr(pxa320_mfp_addr_map); +} + +static int __init pxa320_init(void) +{ + if (cpu_is_pxa320()) + pxa320_init_mfp(); + + return 0; +} + +core_initcall(pxa320_init); diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c new file mode 100644 index 000000000000..39f0de8c189e --- /dev/null +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -0,0 +1,216 @@ +/* + * linux/arch/arm/mach-pxa/pxa3xx.c + * + * code specific to pxa3xx aka Monahans + * + * Copyright (C) 2006 Marvell International Ltd. + * + * 2007-09-02: eric miao <eric.y.miao@gmail.com> + * initial version + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pm.h> +#include <linux/platform_device.h> +#include <linux/irq.h> + +#include <asm/hardware.h> +#include <asm/arch/pxa3xx-regs.h> +#include <asm/arch/ohci.h> +#include <asm/arch/pm.h> +#include <asm/arch/dma.h> +#include <asm/arch/ssp.h> + +#include "generic.h" +#include "devices.h" +#include "clock.h" + +/* Crystal clock: 13MHz */ +#define BASE_CLK 13000000 + +/* Ring Oscillator Clock: 60MHz */ +#define RO_CLK 60000000 + +#define ACCR_D0CS (1 << 26) + +/* crystal frequency to static memory controller multiplier (SMCFS) */ +static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, }; + +/* crystal frequency to HSIO bus frequency multiplier (HSS) */ +static unsigned char hss_mult[4] = { 8, 12, 16, 0 }; + +/* + * Get the clock frequency as reflected by CCSR and the turbo flag. + * We assume these values have been applied via a fcs. + * If info is not 0 we also display the current settings. + */ +unsigned int pxa3xx_get_clk_frequency_khz(int info) +{ + unsigned long acsr, xclkcfg; + unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS; + + /* Read XCLKCFG register turbo bit */ + __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg)); + t = xclkcfg & 0x1; + + acsr = ACSR; + + xl = acsr & 0x1f; + xn = (acsr >> 8) & 0x7; + hss = (acsr >> 14) & 0x3; + + XL = xl * BASE_CLK; + XN = xn * XL; + + ro = acsr & ACCR_D0CS; + + CLK = (ro) ? RO_CLK : ((t) ? XN : XL); + HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK; + + if (info) { + pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n", + RO_CLK / 1000000, (RO_CLK % 1000000) / 10000, + (ro) ? "" : "in"); + pr_info("Run Mode clock: %d.%02dMHz (*%d)\n", + XL / 1000000, (XL % 1000000) / 10000, xl); + pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n", + XN / 1000000, (XN % 1000000) / 10000, xn, + (t) ? "" : "in"); + pr_info("HSIO bus clock: %d.%02dMHz\n", + HSS / 1000000, (HSS % 1000000) / 10000); + } + + return CLK; +} + +/* + * Return the current static memory controller clock frequency + * in units of 10kHz + */ +unsigned int pxa3xx_get_memclk_frequency_10khz(void) +{ + unsigned long acsr; + unsigned int smcfs, clk = 0; + + acsr = ACSR; + + smcfs = (acsr >> 23) & 0x7; + clk = (acsr & ACCR_D0CS) ? RO_CLK : smcfs_mult[smcfs] * BASE_CLK; + + return (clk / 10000); +} + +/* + * Return the current HSIO bus clock frequency + */ +static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk) +{ + unsigned long acsr; + unsigned int hss, hsio_clk; + + acsr = ACSR; + + hss = (acsr >> 14) & 0x3; + hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK; + + return hsio_clk; +} + +static void clk_pxa3xx_cken_enable(struct clk *clk) +{ + unsigned long mask = 1ul << (clk->cken & 0x1f); + + local_irq_disable(); + + if (clk->cken < 32) + CKENA |= mask; + else + CKENB |= mask; + + local_irq_enable(); +} + +static void clk_pxa3xx_cken_disable(struct clk *clk) +{ + unsigned long mask = 1ul << (clk->cken & 0x1f); + + local_irq_disable(); + + if (clk->cken < 32) + CKENA &= ~mask; + else + CKENB &= ~mask; + + local_irq_enable(); +} + +static const struct clkops clk_pxa3xx_hsio_ops = { + .enable = clk_pxa3xx_cken_enable, + .disable = clk_pxa3xx_cken_disable, + .getrate = clk_pxa3xx_hsio_getrate, +}; + +static struct clk pxa3xx_clks[] = { + INIT_CK("LCDCLK", LCD, &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev), + INIT_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_ops, NULL), + + INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev), + INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev), + INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL), + + INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), + INIT_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev), +}; + +void __init pxa3xx_init_irq(void) +{ + /* enable CP6 access */ + u32 value; + __asm__ __volatile__("mrc p15, 0, %0, c15, c1, 0\n": "=r"(value)); + value |= (1 << 6); + __asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value)); + + pxa_init_irq_low(); + pxa_init_irq_high(); + pxa_init_irq_gpio(128); +} + +/* + * device registration specific to PXA3xx. + */ + +static struct platform_device *devices[] __initdata = { + &pxa_device_mci, + &pxa_device_udc, + &pxa_device_fb, + &pxa_device_ffuart, + &pxa_device_btuart, + &pxa_device_stuart, + &pxa_device_i2c, + &pxa_device_i2s, + &pxa_device_ficp, + &pxa_device_rtc, +}; + +static int __init pxa3xx_init(void) +{ + int ret = 0; + + if (cpu_is_pxa3xx()) { + clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks)); + + if ((ret = pxa_init_dma(32))) + return ret; + + return platform_add_devices(devices, ARRAY_SIZE(devices)); + } + return 0; +} + +subsys_initcall(pxa3xx_init); diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 98d27e646b09..ec4286c7931c 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -16,10 +16,48 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/clockchips.h> +#include <linux/sched.h> +#include <asm/div64.h> +#include <asm/cnt32_to_63.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> #include <asm/arch/pxa-regs.h> +#include <asm/mach-types.h> + +/* + * This is PXA's sched_clock implementation. This has a resolution + * of at least 308 ns and a maximum value of 208 days. + * + * The return value is guaranteed to be monotonic in that range as + * long as there is always less than 582 seconds between successive + * calls to sched_clock() which should always be the case in practice. + */ + +#define OSCR2NS_SCALE_FACTOR 10 + +static unsigned long oscr2ns_scale; + +static void __init set_oscr2ns_scale(unsigned long oscr_rate) +{ + unsigned long long v = 1000000000ULL << OSCR2NS_SCALE_FACTOR; + do_div(v, oscr_rate); + oscr2ns_scale = v; + /* + * We want an even value to automatically clear the top bit + * returned by cnt32_to_63() without an additional run time + * instruction. So if the LSB is 1 then round it up. + */ + if (oscr2ns_scale & 1) + oscr2ns_scale++; +} + +unsigned long long sched_clock(void) +{ + unsigned long long v = cnt32_to_63(OSCR); + return (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR; +} + static irqreturn_t pxa_ost0_interrupt(int irq, void *dev_id) @@ -149,18 +187,29 @@ static struct irqaction pxa_ost0_irq = { static void __init pxa_timer_init(void) { + unsigned long clock_tick_rate; + OIER = 0; OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; + if (cpu_is_pxa21x() || cpu_is_pxa25x()) + clock_tick_rate = 3686400; + else if (machine_is_mainstone()) + clock_tick_rate = 3249600; + else + clock_tick_rate = 3250000; + + set_oscr2ns_scale(clock_tick_rate); + ckevt_pxa_osmr0.mult = - div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); + div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); ckevt_pxa_osmr0.max_delta_ns = clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0); ckevt_pxa_osmr0.min_delta_ns = clockevent_delta2ns(MIN_OSCR_DELTA, &ckevt_pxa_osmr0) + 1; cksrc_pxa_oscr0.mult = - clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_pxa_oscr0.shift); + clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift); setup_irq(IRQ_OST0, &pxa_ost0_irq); diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c new file mode 100644 index 000000000000..3f18d760dd1b --- /dev/null +++ b/arch/arm/mach-pxa/zylonite.c @@ -0,0 +1,184 @@ +/* + * linux/arch/arm/mach-pxa/zylonite.c + * + * Support for the PXA3xx Development Platform (aka Zylonite) + * + * Copyright (C) 2006 Marvell International Ltd. + * + * 2007-09-04: eric miao <eric.y.miao@gmail.com> + * rewrite to align with latest kernel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/platform_device.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/hardware.h> +#include <asm/arch/gpio.h> +#include <asm/arch/pxafb.h> +#include <asm/arch/zylonite.h> + +#include "generic.h" + +int gpio_backlight; +int gpio_eth_irq; + +int lcd_id; +int lcd_orientation; + +static struct resource smc91x_resources[] = { + [0] = { + .start = ZYLONITE_ETH_PHYS + 0x300, + .end = ZYLONITE_ETH_PHYS + 0xfffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = -1, /* for run-time assignment */ + .end = -1, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES) +static void zylonite_backlight_power(int on) +{ + gpio_set_value(gpio_backlight, on); +} + +static struct pxafb_mode_info toshiba_ltm035a776c_mode = { + .pixclock = 110000, + .xres = 240, + .yres = 320, + .bpp = 16, + .hsync_len = 4, + .left_margin = 6, + .right_margin = 4, + .vsync_len = 2, + .upper_margin = 2, + .lower_margin = 3, + .sync = FB_SYNC_VERT_HIGH_ACT, +}; + +static struct pxafb_mode_info toshiba_ltm04c380k_mode = { + .pixclock = 50000, + .xres = 640, + .yres = 480, + .bpp = 16, + .hsync_len = 1, + .left_margin = 0x9f, + .right_margin = 1, + .vsync_len = 44, + .upper_margin = 0, + .lower_margin = 0, + .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, +}; + +static struct pxafb_mach_info zylonite_toshiba_lcd_info = { + .num_modes = 1, + .lccr0 = LCCR0_Act, + .lccr3 = LCCR3_PCP, + .pxafb_backlight_power = zylonite_backlight_power, +}; + +static struct pxafb_mode_info sharp_ls037_modes[] = { + [0] = { + .pixclock = 158000, + .xres = 240, + .yres = 320, + .bpp = 16, + .hsync_len = 4, + .left_margin = 39, + .right_margin = 39, + .vsync_len = 1, + .upper_margin = 2, + .lower_margin = 3, + .sync = 0, + }, + [1] = { + .pixclock = 39700, + .xres = 480, + .yres = 640, + .bpp = 16, + .hsync_len = 8, + .left_margin = 81, + .right_margin = 81, + .vsync_len = 1, + .upper_margin = 2, + .lower_margin = 7, + .sync = 0, + }, +}; + +static struct pxafb_mach_info zylonite_sharp_lcd_info = { + .modes = sharp_ls037_modes, + .num_modes = 2, + .lccr0 = LCCR0_Act, + .lccr3 = LCCR3_PCP | LCCR3_HSP | LCCR3_VSP, + .pxafb_backlight_power = zylonite_backlight_power, +}; + +static void __init zylonite_init_lcd(void) +{ + /* backlight GPIO: output, default on */ + gpio_direction_output(gpio_backlight, 1); + + if (lcd_id & 0x20) { + set_pxa_fb_info(&zylonite_sharp_lcd_info); + return; + } + + /* legacy LCD panels, it would be handy here if LCD panel type can + * be decided at run-time + */ + if (1) + zylonite_toshiba_lcd_info.modes = &toshiba_ltm035a776c_mode; + else + zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode; + + set_pxa_fb_info(&zylonite_toshiba_lcd_info); +} +#else +static inline void zylonite_init_lcd(void) {} +#endif + +static void __init zylonite_init(void) +{ + /* board-processor specific initialization */ + zylonite_pxa300_init(); + zylonite_pxa320_init(); + + /* + * Note: We depend that the bootloader set + * the correct value to MSC register for SMC91x. + */ + smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq); + smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq); + platform_device_register(&smc91x_device); + + zylonite_init_lcd(); +} + +MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)") + .phys_io = 0x40000000, + .boot_params = 0xa0000100, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .map_io = pxa_map_io, + .init_irq = pxa3xx_init_irq, + .timer = &pxa_timer, + .init_machine = zylonite_init, +MACHINE_END diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c new file mode 100644 index 000000000000..b5fbd2f4c693 --- /dev/null +++ b/arch/arm/mach-pxa/zylonite_pxa300.c @@ -0,0 +1,188 @@ +/* + * linux/arch/arm/mach-pxa/zylonite_pxa300.c + * + * PXA300/PXA310 specific support code for the + * PXA3xx Development Platform (aka Zylonite) + * + * Copyright (C) 2007 Marvell Internation Ltd. + * 2007-08-21: eric miao <eric.y.miao@gmail.com> + * initial version + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/gpio.h> +#include <asm/arch/mfp-pxa300.h> +#include <asm/arch/zylonite.h> + +#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) + +/* PXA300/PXA310 common configurations */ +static mfp_cfg_t common_mfp_cfg[] __initdata = { + /* LCD */ + GPIO54_LCD_LDD_0, + GPIO55_LCD_LDD_1, + GPIO56_LCD_LDD_2, + GPIO57_LCD_LDD_3, + GPIO58_LCD_LDD_4, + GPIO59_LCD_LDD_5, + GPIO60_LCD_LDD_6, + GPIO61_LCD_LDD_7, + GPIO62_LCD_LDD_8, + GPIO63_LCD_LDD_9, + GPIO64_LCD_LDD_10, + GPIO65_LCD_LDD_11, + GPIO66_LCD_LDD_12, + GPIO67_LCD_LDD_13, + GPIO68_LCD_LDD_14, + GPIO69_LCD_LDD_15, + GPIO70_LCD_LDD_16, + GPIO71_LCD_LDD_17, + GPIO72_LCD_FCLK, + GPIO73_LCD_LCLK, + GPIO74_LCD_PCLK, + GPIO75_LCD_BIAS, + GPIO76_LCD_VSYNC, + GPIO127_LCD_CS_N, + + /* BTUART */ + GPIO111_UART2_RTS, + GPIO112_UART2_RXD, + GPIO113_UART2_TXD, + GPIO114_UART2_CTS, + + /* STUART */ + GPIO109_UART3_TXD, + GPIO110_UART3_RXD, + + /* AC97 */ + GPIO23_AC97_nACRESET, + GPIO24_AC97_SYSCLK, + GPIO29_AC97_BITCLK, + GPIO25_AC97_SDATA_IN_0, + GPIO27_AC97_SDATA_OUT, + GPIO28_AC97_SYNC, + + /* Keypad */ + GPIO107_KP_DKIN_0, + GPIO108_KP_DKIN_1, + GPIO115_KP_MKIN_0, + GPIO116_KP_MKIN_1, + GPIO117_KP_MKIN_2, + GPIO118_KP_MKIN_3, + GPIO119_KP_MKIN_4, + GPIO120_KP_MKIN_5, + GPIO2_2_KP_MKIN_6, + GPIO3_2_KP_MKIN_7, + GPIO121_KP_MKOUT_0, + GPIO122_KP_MKOUT_1, + GPIO123_KP_MKOUT_2, + GPIO124_KP_MKOUT_3, + GPIO125_KP_MKOUT_4, + GPIO4_2_KP_MKOUT_5, + GPIO5_2_KP_MKOUT_6, + GPIO6_2_KP_MKOUT_7, +}; + +static mfp_cfg_t pxa300_mfp_cfg[] __initdata = { + /* FFUART */ + GPIO30_UART1_RXD, + GPIO31_UART1_TXD, + GPIO32_UART1_CTS, + GPIO37_UART1_RTS, + GPIO33_UART1_DCD, + GPIO34_UART1_DSR, + GPIO35_UART1_RI, + GPIO36_UART1_DTR, + + /* Ethernet */ + GPIO2_nCS3, + GPIO99_GPIO, +}; + +static mfp_cfg_t pxa310_mfp_cfg[] __initdata = { + /* FFUART */ + GPIO99_UART1_RXD, + GPIO100_UART1_TXD, + GPIO101_UART1_CTS, + GPIO106_UART1_RTS, + + /* Ethernet */ + GPIO2_nCS3, + GPIO102_GPIO, +}; + +#define NUM_LCD_DETECT_PINS 7 + +static int lcd_detect_pins[] __initdata = { + MFP_PIN_GPIO71, /* LCD_LDD_17 - ORIENT */ + MFP_PIN_GPIO70, /* LCD_LDD_16 - LCDID[5] */ + MFP_PIN_GPIO75, /* LCD_BIAS - LCDID[4] */ + MFP_PIN_GPIO73, /* LCD_LCLK - LCDID[3] */ + MFP_PIN_GPIO72, /* LCD_FCLK - LCDID[2] */ + MFP_PIN_GPIO127,/* LCD_CS_N - LCDID[1] */ + MFP_PIN_GPIO76, /* LCD_VSYNC - LCDID[0] */ +}; + +static void __init zylonite_detect_lcd_panel(void) +{ + unsigned long mfpr_save[NUM_LCD_DETECT_PINS]; + int i, gpio, id = 0; + + /* save the original MFP settings of these pins and configure + * them as GPIO Input, DS01X, Pull Neither, Edge Clear + */ + for (i = 0; i < NUM_LCD_DETECT_PINS; i++) { + mfpr_save[i] = pxa3xx_mfp_read(lcd_detect_pins[i]); + pxa3xx_mfp_write(lcd_detect_pins[i], 0x8440); + } + + for (i = 0; i < NUM_LCD_DETECT_PINS; i++) { + id = id << 1; + gpio = mfp_to_gpio(lcd_detect_pins[i]); + gpio_direction_input(gpio); + + if (gpio_get_value(gpio)) + id = id | 0x1; + } + + /* lcd id, flush out bit 1 */ + lcd_id = id & 0x3d; + + /* lcd orientation, portrait or landscape */ + lcd_orientation = (id >> 6) & 0x1; + + /* restore the original MFP settings */ + for (i = 0; i < NUM_LCD_DETECT_PINS; i++) + pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]); +} + +void __init zylonite_pxa300_init(void) +{ + if (cpu_is_pxa300() || cpu_is_pxa310()) { + /* initialize MFP */ + pxa3xx_mfp_config(ARRAY_AND_SIZE(common_mfp_cfg)); + + /* detect LCD panel */ + zylonite_detect_lcd_panel(); + + /* GPIO pin assignment */ + gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20); + } + + if (cpu_is_pxa300()) { + pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa300_mfp_cfg)); + gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO99); + } + + if (cpu_is_pxa310()) { + pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg)); + gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102); + } +} diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c new file mode 100644 index 000000000000..63cb36be086b --- /dev/null +++ b/arch/arm/mach-pxa/zylonite_pxa320.c @@ -0,0 +1,173 @@ +/* + * linux/arch/arm/mach-pxa/zylonite_pxa320.c + * + * PXA320 specific support code for the + * PXA3xx Development Platform (aka Zylonite) + * + * Copyright (C) 2007 Marvell Internation Ltd. + * 2007-08-21: eric miao <eric.y.miao@gmail.com> + * initial version + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/arch/gpio.h> +#include <asm/arch/mfp-pxa320.h> +#include <asm/arch/zylonite.h> + +#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) + +static mfp_cfg_t mfp_cfg[] __initdata = { + /* LCD */ + GPIO6_2_LCD_LDD_0, + GPIO7_2_LCD_LDD_1, + GPIO8_2_LCD_LDD_2, + GPIO9_2_LCD_LDD_3, + GPIO10_2_LCD_LDD_4, + GPIO11_2_LCD_LDD_5, + GPIO12_2_LCD_LDD_6, + GPIO13_2_LCD_LDD_7, + GPIO63_LCD_LDD_8, + GPIO64_LCD_LDD_9, + GPIO65_LCD_LDD_10, + GPIO66_LCD_LDD_11, + GPIO67_LCD_LDD_12, + GPIO68_LCD_LDD_13, + GPIO69_LCD_LDD_14, + GPIO70_LCD_LDD_15, + GPIO71_LCD_LDD_16, + GPIO72_LCD_LDD_17, + GPIO73_LCD_CS_N, + GPIO74_LCD_VSYNC, + GPIO14_2_LCD_FCLK, + GPIO15_2_LCD_LCLK, + GPIO16_2_LCD_PCLK, + GPIO17_2_LCD_BIAS, + + /* FFUART */ + GPIO41_UART1_RXD, + GPIO42_UART1_TXD, + GPIO43_UART1_CTS, + GPIO44_UART1_DCD, + GPIO45_UART1_DSR, + GPIO46_UART1_RI, + GPIO47_UART1_DTR, + GPIO48_UART1_RTS, + + /* AC97 */ + GPIO34_AC97_SYSCLK, + GPIO35_AC97_SDATA_IN_0, + GPIO37_AC97_SDATA_OUT, + GPIO38_AC97_SYNC, + GPIO39_AC97_BITCLK, + GPIO40_AC97_nACRESET, + + /* I2C */ + GPIO32_I2C_SCL, + GPIO33_I2C_SDA, + + /* Keypad */ + GPIO105_KP_DKIN_0, + GPIO106_KP_DKIN_1, + GPIO113_KP_MKIN_0, + GPIO114_KP_MKIN_1, + GPIO115_KP_MKIN_2, + GPIO116_KP_MKIN_3, + GPIO117_KP_MKIN_4, + GPIO118_KP_MKIN_5, + GPIO119_KP_MKIN_6, + GPIO120_KP_MKIN_7, + GPIO121_KP_MKOUT_0, + GPIO122_KP_MKOUT_1, + GPIO123_KP_MKOUT_2, + GPIO124_KP_MKOUT_3, + GPIO125_KP_MKOUT_4, + GPIO126_KP_MKOUT_5, + GPIO127_KP_MKOUT_6, + GPIO5_2_KP_MKOUT_7, + + /* Ethernet */ + GPIO4_nCS3, + GPIO90_GPIO, +}; + +#define NUM_LCD_DETECT_PINS 7 + +static int lcd_detect_pins[] __initdata = { + MFP_PIN_GPIO72, /* LCD_LDD_17 - ORIENT */ + MFP_PIN_GPIO71, /* LCD_LDD_16 - LCDID[5] */ + MFP_PIN_GPIO17_2, /* LCD_BIAS - LCDID[4] */ + MFP_PIN_GPIO15_2, /* LCD_LCLK - LCDID[3] */ + MFP_PIN_GPIO14_2, /* LCD_FCLK - LCDID[2] */ + MFP_PIN_GPIO73, /* LCD_CS_N - LCDID[1] */ + MFP_PIN_GPIO74, /* LCD_VSYNC - LCDID[0] */ + /* + * set the MFP_PIN_GPIO 14/15/17 to alternate function other than + * GPIO to avoid input level confliction with 14_2, 15_2, 17_2 + */ + MFP_PIN_GPIO14, + MFP_PIN_GPIO15, + MFP_PIN_GPIO17, +}; + +static int lcd_detect_mfpr[] __initdata = { + /* AF0, DS 1X, Pull Neither, Edge Clear */ + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0xc442, /* Backlight, Pull-Up, AF2 */ + 0x8445, /* AF5 */ + 0x8445, /* AF5 */ +}; + +static void __init zylonite_detect_lcd_panel(void) +{ + unsigned long mfpr_save[ARRAY_SIZE(lcd_detect_pins)]; + int i, gpio, id = 0; + + /* save the original MFP settings of these pins and configure them + * as GPIO Input, DS01X, Pull Neither, Edge Clear + */ + for (i = 0; i < ARRAY_SIZE(lcd_detect_pins); i++) { + mfpr_save[i] = pxa3xx_mfp_read(lcd_detect_pins[i]); + pxa3xx_mfp_write(lcd_detect_pins[i], lcd_detect_mfpr[i]); + } + + for (i = 0; i < NUM_LCD_DETECT_PINS; i++) { + id = id << 1; + gpio = mfp_to_gpio(lcd_detect_pins[i]); + gpio_direction_input(gpio); + + if (gpio_get_value(gpio)) + id = id | 0x1; + } + + /* lcd id, flush out bit 1 */ + lcd_id = id & 0x3d; + + /* lcd orientation, portrait or landscape */ + lcd_orientation = (id >> 6) & 0x1; + + /* restore the original MFP settings */ + for (i = 0; i < ARRAY_SIZE(lcd_detect_pins); i++) + pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]); +} + +void __init zylonite_pxa320_init(void) +{ + if (cpu_is_pxa320()) { + /* initialize MFP */ + pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_cfg)); + + /* detect LCD panel */ + zylonite_detect_lcd_panel(); + + /* GPIO pin assignment */ + gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO14); + gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9); + } +} diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index 80d83739ab9f..8f12e855ef5f 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c @@ -145,7 +145,7 @@ static struct s3c24xx_dma_order __initdata s3c2410_dma_order = { }, }; -static int s3c2410_dma_add(struct sys_device *sysdev) +static int __init s3c2410_dma_add(struct sys_device *sysdev) { s3c2410_dma_init(); s3c24xx_dma_order_set(&s3c2410_dma_order); diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c index 43bb5e106302..a67a0685664d 100644 --- a/arch/arm/mach-s3c2410/mach-amlm5900.c +++ b/arch/arm/mach-s3c2410/mach-amlm5900.c @@ -168,13 +168,31 @@ static void __init amlm5900_map_io(void) } #ifdef CONFIG_FB_S3C2410 -static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = { +static struct s3c2410fb_display __initdata amlm5900_lcd_info = { .width = 160, .height = 160, -/* commented out until stn patch is submitted -* .type = S3C2410_LCDCON1_STN4, -*/ + .type = S3C2410_LCDCON1_STN4, + + .pixclock = 680000, /* HCLK = 100MHz */ + .xres = 160, + .yres = 160, + .bpp = 4, + .left_margin = 1 << (4 + 3), + .right_margin = 8 << 3, + .hsync_len = 48, + .upper_margin = 0, + .lower_margin = 0, + + .lcdcon5 = 0x00000001, +}; + +static struct s3c2410fb_mach_info __initdata amlm5900_fb_info = { + + .displays = &amlm5900_lcd_info, + .num_displays = 1, + .default_display = 0, + .gpccon = 0xaaaaaaaa, .gpccon_mask = 0xffffffff, .gpcup = 0x0000ffff, @@ -184,32 +202,6 @@ static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = { .gpdcon_mask = 0xffffffff, .gpdup = 0x0000ffff, .gpdup_mask = 0xffffffff, - - .xres = { - .min = 160, - .max = 160, - .defval = 160, - }, - - .yres = { - .min = 160, - .max = 160, - .defval = 160, - }, - - .bpp = { - .min = 4, - .max = 4, - .defval = 4, - }, - - .regs = { - .lcdcon1 = 0x00008225, - .lcdcon2 = 0x0027c000, - .lcdcon3 = 0x00182708, - .lcdcon4 = 0x00000002, - .lcdcon5 = 0x00000001, - } }; #endif @@ -239,7 +231,7 @@ static void __init amlm5900_init(void) { amlm5900_init_pm(); #ifdef CONFIG_FB_S3C2410 - s3c24xx_fb_set_platdata(&amlm5900_lcd_info); + s3c24xx_fb_set_platdata(&amlm5900_fb_info); #endif platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices)); } diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index bc926992b4e4..587864fe25fb 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -467,35 +467,70 @@ static struct platform_device bast_device_axpp = { /* LCD/VGA controller */ -static struct s3c2410fb_mach_info __initdata bast_lcd_info = { - .width = 640, - .height = 480, - - .xres = { - .min = 320, - .max = 1024, - .defval = 640, - }, +static struct s3c2410fb_display __initdata bast_lcd_info[] = { + { + .type = S3C2410_LCDCON1_TFT, + .width = 640, + .height = 480, + + .pixclock = 33333, + .xres = 640, + .yres = 480, + .bpp = 4, + .left_margin = 40, + .right_margin = 20, + .hsync_len = 88, + .upper_margin = 30, + .lower_margin = 32, + .vsync_len = 3, - .yres = { - .min = 240, - .max = 600, - .defval = 480, + .lcdcon5 = 0x00014b02, }, + { + .type = S3C2410_LCDCON1_TFT, + .width = 640, + .height = 480, + + .pixclock = 33333, + .xres = 640, + .yres = 480, + .bpp = 8, + .left_margin = 40, + .right_margin = 20, + .hsync_len = 88, + .upper_margin = 30, + .lower_margin = 32, + .vsync_len = 3, - .bpp = { - .min = 4, - .max = 16, - .defval = 8, + .lcdcon5 = 0x00014b02, }, + { + .type = S3C2410_LCDCON1_TFT, + .width = 640, + .height = 480, + + .pixclock = 33333, + .xres = 640, + .yres = 480, + .bpp = 16, + .left_margin = 40, + .right_margin = 20, + .hsync_len = 88, + .upper_margin = 30, + .lower_margin = 32, + .vsync_len = 3, - .regs = { - .lcdcon1 = 0x00000176, - .lcdcon2 = 0x1d77c7c2, - .lcdcon3 = 0x013a7f13, - .lcdcon4 = 0x00000057, .lcdcon5 = 0x00014b02, - } + }, +}; + +/* LCD/VGA controller */ + +static struct s3c2410fb_mach_info __initdata bast_fb_info = { + + .displays = bast_lcd_info, + .num_displays = ARRAY_SIZE(bast_lcd_info), + .default_display = 4, }; /* Standard BAST devices */ @@ -552,7 +587,7 @@ static void __init bast_map_io(void) static void __init bast_init(void) { - s3c24xx_fb_set_platdata(&bast_lcd_info); + s3c24xx_fb_set_platdata(&bast_fb_info); platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices)); } diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 9a172b4ad720..7c1145e87c12 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -133,29 +133,31 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = { /** * Set lcd on or off **/ -static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = { - .fixed_syncs= 1, - .regs={ - .lcdcon1= S3C2410_LCDCON1_TFT16BPP | \ - S3C2410_LCDCON1_TFT | \ - S3C2410_LCDCON1_CLKVAL(0x0C), - - .lcdcon2= S3C2410_LCDCON2_VBPD(7) | \ - S3C2410_LCDCON2_LINEVAL(319) | \ - S3C2410_LCDCON2_VFPD(6) | \ - S3C2410_LCDCON2_VSPW(0), - - .lcdcon3= S3C2410_LCDCON3_HBPD(19) | \ - S3C2410_LCDCON3_HOZVAL(239) | \ - S3C2410_LCDCON3_HFPD(7), - - .lcdcon4= S3C2410_LCDCON4_MVAL(0) | \ - S3C2410_LCDCON4_HSPW(3), - - .lcdcon5= S3C2410_LCDCON5_FRM565 | \ - S3C2410_LCDCON5_INVVLINE | \ - S3C2410_LCDCON5_HWSWP, - }, +static struct s3c2410fb_display h1940_lcd __initdata = { + .lcdcon5= S3C2410_LCDCON5_FRM565 | \ + S3C2410_LCDCON5_INVVLINE | \ + S3C2410_LCDCON5_HWSWP, + + .type = S3C2410_LCDCON1_TFT, + .width = 240, + .height = 320, + .pixclock = 260000, + .xres = 240, + .yres = 320, + .bpp = 16, + .left_margin = 20, + .right_margin = 8, + .hsync_len = 4, + .upper_margin = 8, + .lower_margin = 7, + .vsync_len = 1, +}; + +static struct s3c2410fb_mach_info h1940_fb_info __initdata = { + .displays = &h1940_lcd, + .num_displays = 1, + .default_display = 0, + .lpcsel= 0x02, .gpccon= 0xaa940659, .gpccon_mask= 0xffffffff, @@ -165,12 +167,6 @@ static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = { .gpdcon_mask= 0xffffffff, .gpdup= 0x0000faff, .gpdup_mask= 0xffffffff, - - .width= 240, - .height= 320, - .xres= {240,240,240}, - .yres= {320,320,320}, - .bpp= {16,16,16}, }; static struct platform_device s3c_device_leds = { @@ -217,7 +213,7 @@ static void __init h1940_init(void) { u32 tmp; - s3c24xx_fb_set_platdata(&h1940_lcdcfg); + s3c24xx_fb_set_platdata(&h1940_fb_info); s3c24xx_udc_set_platdata(&h1940_udc_cfg); /* Turn off suspend on both USB ports, and switch the diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c index e670b1e1631b..a1caf4b0adac 100644 --- a/arch/arm/mach-s3c2410/mach-qt2410.c +++ b/arch/arm/mach-s3c2410/mach-qt2410.c @@ -95,157 +95,83 @@ static struct s3c2410_uartcfg smdk2410_uartcfgs[] = { /* LCD driver info */ -/* Configuration for 640x480 SHARP LQ080V3DG01 */ -static struct s3c2410fb_mach_info qt2410_biglcd_cfg __initdata = { - .regs = { - - .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | - S3C2410_LCDCON1_TFT | - S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */ - - .lcdcon2 = S3C2410_LCDCON2_VBPD(18) | /* 19 */ - S3C2410_LCDCON2_LINEVAL(479) | - S3C2410_LCDCON2_VFPD(10) | /* 11 */ - S3C2410_LCDCON2_VSPW(14), /* 15 */ - - .lcdcon3 = S3C2410_LCDCON3_HBPD(43) | /* 44 */ - S3C2410_LCDCON3_HOZVAL(639) | /* 640 */ - S3C2410_LCDCON3_HFPD(115), /* 116 */ - - .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | - S3C2410_LCDCON4_HSPW(95), /* 96 */ - - .lcdcon5 = S3C2410_LCDCON5_FRM565 | - S3C2410_LCDCON5_INVVLINE | - S3C2410_LCDCON5_INVVFRAME | - S3C2410_LCDCON5_PWREN | - S3C2410_LCDCON5_HWSWP, +static struct s3c2410fb_display qt2410_lcd_cfg[] __initdata = { + { + /* Configuration for 640x480 SHARP LQ080V3DG01 */ + .lcdcon5 = S3C2410_LCDCON5_FRM565 | + S3C2410_LCDCON5_INVVLINE | + S3C2410_LCDCON5_INVVFRAME | + S3C2410_LCDCON5_PWREN | + S3C2410_LCDCON5_HWSWP, + + .type = S3C2410_LCDCON1_TFT, + .width = 640, + .height = 480, + + .pixclock = 40000, /* HCLK/4 */ + .xres = 640, + .yres = 480, + .bpp = 16, + .left_margin = 44, + .right_margin = 116, + .hsync_len = 96, + .upper_margin = 19, + .lower_margin = 11, + .vsync_len = 15, }, - - .lpcsel = ((0xCE6) & ~7) | 1<<4, - - .width = 640, - .height = 480, - - .xres = { - .min = 640, - .max = 640, - .defval = 640, - }, - - .yres = { - .min = 480, - .max = 480, - .defval = 480, - }, - - .bpp = { - .min = 16, - .max = 16, - .defval = 16, - }, -}; - -/* Configuration for 480x640 toppoly TD028TTEC1 */ -static struct s3c2410fb_mach_info qt2410_prodlcd_cfg __initdata = { - .regs = { - - .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | - S3C2410_LCDCON1_TFT | - S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */ - - .lcdcon2 = S3C2410_LCDCON2_VBPD(1) | /* 2 */ - S3C2410_LCDCON2_LINEVAL(639) |/* 640 */ - S3C2410_LCDCON2_VFPD(3) | /* 4 */ - S3C2410_LCDCON2_VSPW(1), /* 2 */ - - .lcdcon3 = S3C2410_LCDCON3_HBPD(7) | /* 8 */ - S3C2410_LCDCON3_HOZVAL(479) | /* 479 */ - S3C2410_LCDCON3_HFPD(23), /* 24 */ - - .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | - S3C2410_LCDCON4_HSPW(7), /* 8 */ - - .lcdcon5 = S3C2410_LCDCON5_FRM565 | - S3C2410_LCDCON5_INVVLINE | - S3C2410_LCDCON5_INVVFRAME | - S3C2410_LCDCON5_PWREN | - S3C2410_LCDCON5_HWSWP, - }, - - .lpcsel = ((0xCE6) & ~7) | 1<<4, - - .width = 480, - .height = 640, - - .xres = { - .min = 480, - .max = 480, - .defval = 480, + { + /* Configuration for 480x640 toppoly TD028TTEC1 */ + .lcdcon5 = S3C2410_LCDCON5_FRM565 | + S3C2410_LCDCON5_INVVLINE | + S3C2410_LCDCON5_INVVFRAME | + S3C2410_LCDCON5_PWREN | + S3C2410_LCDCON5_HWSWP, + + .type = S3C2410_LCDCON1_TFT, + .width = 480, + .height = 640, + .pixclock = 40000, /* HCLK/4 */ + .xres = 480, + .yres = 640, + .bpp = 16, + .left_margin = 8, + .right_margin = 24, + .hsync_len = 8, + .upper_margin = 2, + .lower_margin = 4, + .vsync_len = 2, }, - - .yres = { - .min = 640, - .max = 640, - .defval = 640, - }, - - .bpp = { - .min = 16, - .max = 16, - .defval = 16, + { + /* Config for 240x320 LCD */ + .lcdcon5 = S3C2410_LCDCON5_FRM565 | + S3C2410_LCDCON5_INVVLINE | + S3C2410_LCDCON5_INVVFRAME | + S3C2410_LCDCON5_PWREN | + S3C2410_LCDCON5_HWSWP, + + .type = S3C2410_LCDCON1_TFT, + .width = 240, + .height = 320, + .pixclock = 100000, /* HCLK/10 */ + .xres = 240, + .yres = 320, + .bpp = 16, + .left_margin = 13, + .right_margin = 8, + .hsync_len = 4, + .upper_margin = 2, + .lower_margin = 7, + .vsync_len = 4, }, }; -/* Config for 240x320 LCD */ -static struct s3c2410fb_mach_info qt2410_lcd_cfg __initdata = { - .regs = { - - .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | - S3C2410_LCDCON1_TFT | - S3C2410_LCDCON1_CLKVAL(0x04), - - .lcdcon2 = S3C2410_LCDCON2_VBPD(1) | - S3C2410_LCDCON2_LINEVAL(319) | - S3C2410_LCDCON2_VFPD(6) | - S3C2410_LCDCON2_VSPW(3), - - .lcdcon3 = S3C2410_LCDCON3_HBPD(12) | - S3C2410_LCDCON3_HOZVAL(239) | - S3C2410_LCDCON3_HFPD(7), - .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | - S3C2410_LCDCON4_HSPW(3), - - .lcdcon5 = S3C2410_LCDCON5_FRM565 | - S3C2410_LCDCON5_INVVLINE | - S3C2410_LCDCON5_INVVFRAME | - S3C2410_LCDCON5_PWREN | - S3C2410_LCDCON5_HWSWP, - }, +static struct s3c2410fb_mach_info qt2410_fb_info __initdata = { + .displays = qt2410_lcd_cfg, + .num_displays = ARRAY_SIZE(qt2410_lcd_cfg), + .default_display = 0, .lpcsel = ((0xCE6) & ~7) | 1<<4, - - .width = 240, - .height = 320, - - .xres = { - .min = 240, - .max = 240, - .defval = 240, - }, - - .yres = { - .min = 320, - .max = 320, - .defval = 320, - }, - - .bpp = { - .min = 16, - .max = 16, - .defval = 16, - }, }; /* CS8900 */ @@ -408,16 +334,17 @@ static void __init qt2410_machine_init(void) switch (tft_type) { case 'p': /* production */ - s3c24xx_fb_set_platdata(&qt2410_prodlcd_cfg); + qt2410_fb_info.default_display = 1; break; case 'b': /* big */ - s3c24xx_fb_set_platdata(&qt2410_biglcd_cfg); + qt2410_fb_info.default_display = 0; break; case 's': /* small */ default: - s3c24xx_fb_set_platdata(&qt2410_lcd_cfg); + qt2410_fb_info.default_display = 2; break; } + s3c24xx_fb_set_platdata(&qt2410_fb_info); s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT); s3c2410_gpio_setpin(S3C2410_GPB0, 1); diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c index 4b9425c1bf72..53c1d5bbce19 100644 --- a/arch/arm/mach-s3c2412/dma.c +++ b/arch/arm/mach-s3c2412/dma.c @@ -144,7 +144,7 @@ static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = { .map_size = ARRAY_SIZE(s3c2412_dma_mappings), }; -static int s3c2412_dma_add(struct sys_device *sysdev) +static int __init s3c2412_dma_add(struct sys_device *sysdev) { s3c2410_dma_init(); return s3c24xx_dma_init_map(&s3c2412_dma_sel); diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c index f0d66828f965..e9d0c769f5da 100644 --- a/arch/arm/mach-s3c2412/irq.c +++ b/arch/arm/mach-s3c2412/irq.c @@ -38,6 +38,9 @@ #include <asm/plat-s3c24xx/irq.h> #include <asm/plat-s3c24xx/pm.h> +#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1) +#define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0)))) + /* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by * having them turn up in both the INT* and the EINT* registers. Whilst * both show the status, they both now need to be acked when the IRQs @@ -105,6 +108,51 @@ static struct irq_chip s3c2412_irq_eint0t4 = { .set_type = s3c_irqext_type, }; +#define INTBIT(x) (1 << ((x) - S3C2410_IRQSUB(0))) + +/* CF and SDI sub interrupts */ + +static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc) +{ + unsigned int subsrc, submsk; + + subsrc = __raw_readl(S3C2410_SUBSRCPND); + submsk = __raw_readl(S3C2410_INTSUBMSK); + + subsrc &= ~submsk; + + if (subsrc & INTBIT(IRQ_S3C2412_SDI)) + desc_handle_irq(IRQ_S3C2412_SDI, irq_desc + IRQ_S3C2412_SDI); + + if (subsrc & INTBIT(IRQ_S3C2412_CF)) + desc_handle_irq(IRQ_S3C2412_CF, irq_desc + IRQ_S3C2412_CF); +} + +#define INTMSK_CFSDI (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0)) +#define SUBMSK_CFSDI INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF) + +static void s3c2412_irq_cfsdi_mask(unsigned int irqno) +{ + s3c_irqsub_mask(irqno, INTMSK_CFSDI, SUBMSK_CFSDI); +} + +static void s3c2412_irq_cfsdi_unmask(unsigned int irqno) +{ + s3c_irqsub_unmask(irqno, INTMSK_CFSDI); +} + +static void s3c2412_irq_cfsdi_ack(unsigned int irqno) +{ + s3c_irqsub_maskack(irqno, INTMSK_CFSDI, SUBMSK_CFSDI); +} + +static struct irq_chip s3c2412_irq_cfsdi = { + .name = "s3c2412-cfsdi", + .ack = s3c2412_irq_cfsdi_ack, + .mask = s3c2412_irq_cfsdi_mask, + .unmask = s3c2412_irq_cfsdi_unmask, +}; + static int s3c2412_irq_add(struct sys_device *sysdev) { unsigned int irqno; @@ -115,6 +163,16 @@ static int s3c2412_irq_add(struct sys_device *sysdev) set_irq_flags(irqno, IRQF_VALID); } + /* add demux support for CF/SDI */ + + set_irq_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi); + + for (irqno = IRQ_S3C2412_SDI; irqno <= IRQ_S3C2412_CF; irqno++) { + set_irq_chip(irqno, &s3c2412_irq_cfsdi); + set_irq_handler(irqno, handle_level_irq); + set_irq_flags(irqno, IRQF_VALID); + } + return 0; } diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c index e0ccb404623f..4f92a1562d77 100644 --- a/arch/arm/mach-s3c2412/s3c2412.c +++ b/arch/arm/mach-s3c2412/s3c2412.c @@ -78,6 +78,11 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no) s3c_device_lcd.name = "s3c2412-lcd"; s3c_device_nand.name = "s3c2412-nand"; + /* alter IRQ of SDI controller */ + + s3c_device_sdi.resource[1].start = IRQ_S3C2412_SDI; + s3c_device_sdi.resource[1].end = IRQ_S3C2412_SDI; + /* spi channel related changes, s3c2412/13 specific */ s3c_device_spi0.name = "s3c2412-spi"; s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24; diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c index f509f062e749..0b1260827ac6 100644 --- a/arch/arm/mach-s3c2440/dma.c +++ b/arch/arm/mach-s3c2440/dma.c @@ -190,7 +190,7 @@ static struct s3c24xx_dma_order __initdata s3c2440_dma_order = { }, }; -static int s3c2440_dma_add(struct sys_device *sysdev) +static int __init s3c2440_dma_add(struct sys_device *sysdev) { s3c2410_dma_init(); s3c24xx_dma_order_set(&s3c2440_dma_order); diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c index b59e6d39f2f2..bac40c4878a5 100644 --- a/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/arch/arm/mach-s3c2440/mach-rx3715.c @@ -110,28 +110,32 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = { /* framebuffer lcd controller information */ -static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = { - .regs = { - .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | \ - S3C2410_LCDCON1_TFT | \ - S3C2410_LCDCON1_CLKVAL(0x0C), - - .lcdcon2 = S3C2410_LCDCON2_VBPD(5) | \ - S3C2410_LCDCON2_LINEVAL(319) | \ - S3C2410_LCDCON2_VFPD(6) | \ - S3C2410_LCDCON2_VSPW(2), - - .lcdcon3 = S3C2410_LCDCON3_HBPD(35) | \ - S3C2410_LCDCON3_HOZVAL(239) | \ - S3C2410_LCDCON3_HFPD(35), - - .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | \ - S3C2410_LCDCON4_HSPW(7), - - .lcdcon5 = S3C2410_LCDCON5_INVVLINE | - S3C2410_LCDCON5_FRM565 | - S3C2410_LCDCON5_HWSWP, - }, +static struct s3c2410fb_display rx3715_lcdcfg __initdata = { + .lcdcon5 = S3C2410_LCDCON5_INVVLINE | + S3C2410_LCDCON5_FRM565 | + S3C2410_LCDCON5_HWSWP, + + .type = S3C2410_LCDCON1_TFT, + .width = 240, + .height = 320, + + .pixclock = 260000, + .xres = 240, + .yres = 320, + .bpp = 16, + .left_margin = 36, + .right_margin = 36, + .hsync_len = 8, + .upper_margin = 6, + .lower_margin = 7, + .vsync_len = 3, +}; + +static struct s3c2410fb_mach_info rx3715_fb_info __initdata = { + + .displays = &rx3715_lcdcfg, + .num_displays = 1, + .default_display = 0, .lpcsel = 0xf82, @@ -144,28 +148,6 @@ static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = { .gpdcon_mask = 0xffc0fff0, .gpdup = 0x0000faff, .gpdup_mask = 0xffffffff, - - .fixed_syncs = 1, - .width = 240, - .height = 320, - - .xres = { - .min = 240, - .max = 240, - .defval = 240, - }, - - .yres = { - .max = 320, - .min = 320, - .defval = 320, - }, - - .bpp = { - .min = 16, - .max = 16, - .defval = 16, - }, }; static struct mtd_partition rx3715_nand_part[] = { @@ -224,7 +206,7 @@ static void __init rx3715_init_machine(void) #endif s3c2410_pm_init(); - s3c24xx_fb_set_platdata(&rx3715_lcdcfg); + s3c24xx_fb_set_platdata(&rx3715_fb_info); platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices)); } diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c index 670115b8a12e..4552828bf800 100644 --- a/arch/arm/mach-s3c2440/mach-smdk2440.c +++ b/arch/arm/mach-s3c2440/mach-smdk2440.c @@ -103,31 +103,35 @@ static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = { /* LCD driver info */ -static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = { - .regs = { - - .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | - S3C2410_LCDCON1_TFT | - S3C2410_LCDCON1_CLKVAL(0x04), - - .lcdcon2 = S3C2410_LCDCON2_VBPD(7) | - S3C2410_LCDCON2_LINEVAL(319) | - S3C2410_LCDCON2_VFPD(6) | - S3C2410_LCDCON2_VSPW(3), - - .lcdcon3 = S3C2410_LCDCON3_HBPD(19) | - S3C2410_LCDCON3_HOZVAL(239) | - S3C2410_LCDCON3_HFPD(7), - - .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | - S3C2410_LCDCON4_HSPW(3), - - .lcdcon5 = S3C2410_LCDCON5_FRM565 | - S3C2410_LCDCON5_INVVLINE | - S3C2410_LCDCON5_INVVFRAME | - S3C2410_LCDCON5_PWREN | - S3C2410_LCDCON5_HWSWP, - }, +static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = { + + .lcdcon5 = S3C2410_LCDCON5_FRM565 | + S3C2410_LCDCON5_INVVLINE | + S3C2410_LCDCON5_INVVFRAME | + S3C2410_LCDCON5_PWREN | + S3C2410_LCDCON5_HWSWP, + + .type = S3C2410_LCDCON1_TFT, + + .width = 240, + .height = 320, + + .pixclock = 166667, /* HCLK 60 MHz, divisor 10 */ + .xres = 240, + .yres = 320, + .bpp = 16, + .left_margin = 20, + .right_margin = 8, + .hsync_len = 4, + .upper_margin = 8, + .lower_margin = 7, + .vsync_len = 4, +}; + +static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = { + .displays = &smdk2440_lcd_cfg, + .num_displays = 1, + .default_display = 0, #if 0 /* currently setup by downloader */ @@ -142,28 +146,6 @@ static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = { #endif .lpcsel = ((0xCE6) & ~7) | 1<<4, - .type = S3C2410_LCDCON1_TFT16BPP, - - .width = 240, - .height = 320, - - .xres = { - .min = 240, - .max = 240, - .defval = 240, - }, - - .yres = { - .min = 320, - .max = 320, - .defval = 320, - }, - - .bpp = { - .min = 16, - .max = 16, - .defval = 16, - }, }; static struct platform_device *smdk2440_devices[] __initdata = { @@ -183,7 +165,7 @@ static void __init smdk2440_map_io(void) static void __init smdk2440_machine_init(void) { - s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg); + s3c24xx_fb_set_platdata(&smdk2440_fb_info); platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices)); smdk_machine_init(); diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c index fc3ede82af8f..f6c006d4297b 100644 --- a/arch/arm/mach-s3c2443/dma.c +++ b/arch/arm/mach-s3c2443/dma.c @@ -162,7 +162,7 @@ static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = { .map_size = ARRAY_SIZE(s3c2443_dma_mappings), }; -static int s3c2443_dma_add(struct sys_device *sysdev) +static int __init s3c2443_dma_add(struct sys_device *sysdev) { s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100); return s3c24xx_dma_init_map(&s3c2443_dma_sel); diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c index 6cd4818f3f0d..f9ad498a6fc0 100644 --- a/arch/arm/mach-s3c2443/irq.c +++ b/arch/arm/mach-s3c2443/irq.c @@ -252,7 +252,7 @@ static int __init s3c2443_add_sub(unsigned int base, return 0; } -static int s3c2443_irq_add(struct sys_device *sysdev) +static int __init s3c2443_irq_add(struct sys_device *sysdev) { printk("S3C2443: IRQ Support\n"); @@ -280,7 +280,7 @@ static struct sysdev_driver s3c2443_irq_driver = { .add = s3c2443_irq_add, }; -static int s3c2443_irq_init(void) +static int __init s3c2443_irq_init(void) { return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_irq_driver); } diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c index 78f4c1346044..36b47ff5af11 100644 --- a/arch/arm/mach-sa1100/cpu-sa1110.c +++ b/arch/arm/mach-sa1100/cpu-sa1110.c @@ -331,7 +331,6 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy) if (policy->cpu != 0) return -EINVAL; policy->cur = policy->min = policy->max = sa11x0_getspeed(0); - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.min_freq = 59000; policy->cpuinfo.max_freq = 287000; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 12161ae445da..7868f4dc1d00 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -322,7 +322,7 @@ config CPU_SA1100 # XScale config CPU_XSCALE bool - depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000 + depends on ARCH_IOP32X || ARCH_IOP33X || PXA25x || PXA27x || ARCH_IXP4XX || ARCH_IXP2000 default y select CPU_32v5 select CPU_ABRT_EV5T @@ -333,7 +333,7 @@ config CPU_XSCALE # XScale Core Version 3 config CPU_XSC3 bool - depends on ARCH_IXP23XX || ARCH_IOP13XX + depends on ARCH_IXP23XX || ARCH_IOP13XX || PXA3xx default y select CPU_32v5 select CPU_ABRT_EV5T diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 1f9f94f9af4b..cefdf2f9f26e 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -481,7 +481,7 @@ core_initcall(consistent_init); * platforms with CONFIG_DMABOUNCE. * Use the driver DMA support - see dma-mapping.h (dma_sync_*) */ -void consistent_sync(const void *start, size_t size, int direction) +void dma_cache_maint(const void *start, size_t size, int direction) { const void *end = start + size; @@ -504,4 +504,4 @@ void consistent_sync(const void *start, size_t size, int direction) BUG(); } } -EXPORT_SYMBOL(consistent_sync); +EXPORT_SYMBOL(dma_cache_maint); diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 846cce48e2b7..59ed1d05b71b 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -266,7 +266,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) * the page fault gracefully. */ printk("VM: killing process %s\n", tsk->comm); - do_exit(SIGKILL); + do_group_exit(SIGKILL); return 0; } if (fault & VM_FAULT_SIGBUS) { diff --git a/arch/arm/nwfpe/ARM-gcc.h b/arch/arm/nwfpe/ARM-gcc.h index e6598470b076..436e54aa02ec 100644 --- a/arch/arm/nwfpe/ARM-gcc.h +++ b/arch/arm/nwfpe/ARM-gcc.h @@ -68,7 +68,7 @@ a compiler does not support explicit inlining, this macro should be defined to be `static'. ------------------------------------------------------------------------------- */ -#define INLINE extern __inline__ +#define INLINE static inline /* For use as a GCC soft-float library we need some special function names. */ diff --git a/arch/arm/nwfpe/entry.S b/arch/arm/nwfpe/entry.S index 1dc13bc6d810..48bca0db4607 100644 --- a/arch/arm/nwfpe/entry.S +++ b/arch/arm/nwfpe/entry.S @@ -70,13 +70,24 @@ floating point instructions. GCC attempts to group floating point instructions to allow the emulator to spread the cost of the trap over several floating point instructions. */ +#include <asm/asm-offsets.h> + .globl nwfpe_enter nwfpe_enter: mov r4, lr @ save the failure-return addresses mov sl, sp @ we access the registers via 'sl' - ldr r5, [sp, #60] @ get contents of PC; + ldr r5, [sp, #S_PC] @ get contents of PC; + mov r6, r0 @ save the opcode emulate: + ldr r1, [sp, #S_PSR] @ fetch the PSR + bl checkCondition @ check the condition + cmp r0, #0 @ r0 = 0 ==> condition failed + + @ if condition code failed to match, next insn + beq next @ get the next instruction; + + mov r0, r6 @ prepare for EmulateAll() bl EmulateAll @ emulate the instruction cmp r0, #0 @ was emulation successful moveq pc, r4 @ no, return failure @@ -91,18 +102,10 @@ next: teqne r2, #0x0E000000 movne pc, r9 @ return ok if not a fp insn - str r5, [sp, #60] @ update PC copy in regs + str r5, [sp, #S_PC] @ update PC copy in regs mov r0, r6 @ save a copy - ldr r1, [sp, #64] @ fetch the condition codes - bl checkCondition @ check the condition - cmp r0, #0 @ r0 = 0 ==> condition failed - - @ if condition code failed to match, next insn - beq next @ get the next instruction; - - mov r0, r6 @ prepare for EmulateAll() - b emulate @ if r0 != 0, goto EmulateAll + b emulate @ check condition and emulate @ We need to be prepared for the instructions at .Lx1 and .Lx2 @ to fault. Emit the appropriate exception gunk to fix things up. diff --git a/arch/arm/nwfpe/fpa11.inl b/arch/arm/nwfpe/fpa11.inl index 10c3caf2868f..ab8d6826245f 100644 --- a/arch/arm/nwfpe/fpa11.inl +++ b/arch/arm/nwfpe/fpa11.inl @@ -22,13 +22,13 @@ #include "fpa11.h" /* Read and write floating point status register */ -extern __inline__ unsigned int readFPSR(void) +static inline unsigned int readFPSR(void) { FPA11 *fpa11 = GET_FPA11(); return (fpa11->fpsr); } -extern __inline__ void writeFPSR(FPSR reg) +static inline void writeFPSR(FPSR reg) { FPA11 *fpa11 = GET_FPA11(); /* the sysid byte in the status register is readonly */ @@ -36,14 +36,14 @@ extern __inline__ void writeFPSR(FPSR reg) } /* Read and write floating point control register */ -extern __inline__ FPCR readFPCR(void) +static inline FPCR readFPCR(void) { FPA11 *fpa11 = GET_FPA11(); /* clear SB, AB and DA bits before returning FPCR */ return (fpa11->fpcr & ~MASK_RFC); } -extern __inline__ void writeFPCR(FPCR reg) +static inline void writeFPCR(FPCR reg) { FPA11 *fpa11 = GET_FPA11(); fpa11->fpcr &= ~MASK_WFC; /* clear SB, AB and DA bits */ diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index cfc69f3842fd..c1f7e5a819a3 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -20,10 +20,15 @@ endchoice comment "OMAP Feature Selections" -config OMAP_DEBUG_LEDS +config OMAP_DEBUG_DEVICES bool help - For debug card leds on TI reference boards. + For debug cards on TI reference boards. + +config OMAP_DEBUG_LEDS + bool + depends on OMAP_DEBUG_DEVICES + default y if LEDS || LEDS_OMAP_DEBUG config OMAP_RESET_CLOCKS bool "Reset unused clocks during boot" diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 41a3c1cf3bd4..2549129aabc6 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -17,4 +17,5 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o obj-$(CONFIG_CPU_FREQ) += cpu-omap.o obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o +obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c index a0c71dca2373..c0d63b0c61c9 100644 --- a/arch/arm/plat-omap/cpu-omap.c +++ b/arch/arm/plat-omap/cpu-omap.c @@ -108,7 +108,6 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy) if (policy->cpu != 0) return -EINVAL; policy->cur = policy->min = policy->max = omap_getspeed(0); - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, VERY_HI_RATE) / 1000; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; diff --git a/arch/arm/plat-omap/debug-devices.c b/arch/arm/plat-omap/debug-devices.c new file mode 100644 index 000000000000..83a5f8b91857 --- /dev/null +++ b/arch/arm/plat-omap/debug-devices.c @@ -0,0 +1,86 @@ +/* + * linux/arch/arm/plat-omap/debug-devices.c + * + * Copyright (C) 2005 Nokia Corporation + * Modified from mach-omap2/board-h4.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> + +#include <asm/hardware.h> +#include <asm/io.h> + +#include <asm/arch/board.h> +#include <asm/arch/gpio.h> + + +/* Many OMAP development platforms reuse the same "debug board"; these + * platforms include H2, H3, H4, and Perseus2. + */ + +static struct resource smc91x_resources[] = { + [0] = { + .flags = IORESOURCE_MEM, + }, + [1] = { + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = -1, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static struct resource led_resources[] = { + [0] = { + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device led_device = { + .name = "omap_dbg_led", + .id = -1, + .num_resources = ARRAY_SIZE(led_resources), + .resource = led_resources, +}; + +static struct platform_device *debug_devices[] __initdata = { + &smc91x_device, + &led_device, + /* ps2 kbd + mouse ports */ + /* 4 extra uarts */ + /* 6 input dip switches */ + /* 8 output pins */ +}; + +int __init debug_card_init(u32 addr, unsigned gpio) +{ + int status; + + smc91x_resources[0].start = addr + 0x300; + smc91x_resources[0].end = addr + 0x30f; + + smc91x_resources[1].start = OMAP_GPIO_IRQ(gpio); + smc91x_resources[1].end = OMAP_GPIO_IRQ(gpio); + + status = omap_request_gpio(gpio); + if (status < 0) { + printk(KERN_ERR "GPIO%d unavailable for smc91x IRQ\n", gpio); + return status; + } + omap_set_gpio_direction(gpio, 1); + + led_resources[0].start = addr; + led_resources[0].end = addr + SZ_4K - 1; + + return platform_add_devices(debug_devices, ARRAY_SIZE(debug_devices)); +} diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 88d5b6d9f950..05a38498cbe0 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -1347,11 +1347,6 @@ void omap_stop_lcd_dma(void) omap_writew(w, OMAP1610_DMA_LCD_CTRL); } -int omap_lcd_dma_ext_running(void) -{ - return lcd_dma.ext_ctrl && lcd_dma.active; -} - /*----------------------------------------------------------------------------*/ static int __init omap_init_dma(void) @@ -1493,7 +1488,6 @@ EXPORT_SYMBOL(omap_free_lcd_dma); EXPORT_SYMBOL(omap_enable_lcd_dma); EXPORT_SYMBOL(omap_setup_lcd_dma); EXPORT_SYMBOL(omap_stop_lcd_dma); -EXPORT_SYMBOL(omap_lcd_dma_ext_running); EXPORT_SYMBOL(omap_set_lcd_dma_b1); EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer); EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller); diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 6d048490c559..992ca435a922 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -1372,7 +1372,7 @@ int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq, return ret; } -int s3c2410_dma_init(void) +int __init s3c2410_dma_init(void) { return s3c24xx_dma_init(4, IRQ_DMA0, 0x40); } diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S index d47113bbc34c..a646cbe8244c 100644 --- a/arch/arm/plat-s3c24xx/sleep.S +++ b/arch/arm/plat-s3c24xx/sleep.S @@ -96,6 +96,14 @@ resume_with_mmu: s3c2410_sleep_save_phys: .word 0 + + /* sleep magic, to allow the bootloader to check for an valid + * image to resume to. Must be the first word before the + * s3c2410_cpu_resume entry. + */ + + .word 0x2bedf00d + /* s3c2410_cpu_resume * * resume code entry for bootloader to call diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c index 4942ee662e0b..20b1c9d8f945 100644 --- a/arch/avr32/kernel/kprobes.c +++ b/arch/avr32/kernel/kprobes.c @@ -22,6 +22,8 @@ DEFINE_PER_CPU(struct kprobe *, current_kprobe); static unsigned long kprobe_status; static struct pt_regs jprobe_saved_regs; +struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}}; + int __kprobes arch_prepare_kprobe(struct kprobe *p) { int ret = 0; diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c index 39060cbeb2a3..9e16b8a447f2 100644 --- a/arch/avr32/kernel/ptrace.c +++ b/arch/avr32/kernel/ptrace.c @@ -227,11 +227,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = 0; break; - /* Detach a process that was attached */ - case PTRACE_DETACH: - ret = ptrace_detach(child, data); - break; - case PTRACE_GETREGS: ret = ptrace_getregs(child, (void __user *)data); break; diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c index ae2d2c593b2b..11472f8701bd 100644 --- a/arch/avr32/mm/fault.c +++ b/arch/avr32/mm/fault.c @@ -216,7 +216,7 @@ out_of_memory: } printk("VM: Killing process %s\n", tsk->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index 64ce5fea8609..85caf9b711a1 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c @@ -385,12 +385,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; } - case PTRACE_DETACH: - { /* detach a process that was attached. */ - ret = ptrace_detach(child, data); - break; - } - case PTRACE_GETREGS: { diff --git a/arch/blackfin/mach-bf533/cpu.c b/arch/blackfin/mach-bf533/cpu.c index 6fd9cfd0a31b..b7a0e0fbd9af 100644 --- a/arch/blackfin/mach-bf533/cpu.c +++ b/arch/blackfin/mach-bf533/cpu.c @@ -118,8 +118,6 @@ static int __init __bf533_cpu_init(struct cpufreq_policy *policy) if (policy->cpu != 0) return -EINVAL; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; /*Now ,only support one cpu */ policy->cur = bf533_getfreq(0); diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c index 5e9d09eb8579..6668c8e4a3fc 100644 --- a/arch/blackfin/mach-bf537/boards/generic_board.c +++ b/arch/blackfin/mach-bf537/boards/generic_board.c @@ -40,7 +40,7 @@ #include <linux/pata_platform.h> #include <linux/irq.h> #include <linux/interrupt.h> -#include <linux/usb_sl811.h> +#include <linux/usb/sl811.h> #include <asm/dma.h> #include <asm/bfin5xx_spi.h> #include <asm/reboot.h> diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c index 20507e92a3a4..f83a2544004d 100644 --- a/arch/blackfin/mach-bf537/boards/pnav10.c +++ b/arch/blackfin/mach-bf537/boards/pnav10.c @@ -40,7 +40,7 @@ #include <linux/irq.h> #include <asm/dma.h> #include <asm/bfin5xx_spi.h> -#include <linux/usb_sl811.h> +#include <linux/usb/sl811.h> #include <linux/spi/ad7877.h> diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 47d7d4a0e73d..f42ba3aa86d7 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -40,7 +40,7 @@ #include <linux/pata_platform.h> #include <linux/irq.h> #include <linux/interrupt.h> -#include <linux/usb_sl811.h> +#include <linux/usb/sl811.h> #include <asm/dma.h> #include <asm/bfin5xx_spi.h> #include <asm/reboot.h> diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 2c47db494f7d..046e6d84bbfc 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -88,7 +88,7 @@ static struct platform_device bf54x_lq043_device = { #endif #if defined(CONFIG_KEYBOARD_BFIN) || defined(CONFIG_KEYBOARD_BFIN_MODULE) -static int bf548_keymap[] = { +static const unsigned int bf548_keymap[] = { KEYVAL(0, 0, KEY_ENTER), KEYVAL(0, 1, KEY_HELP), KEYVAL(0, 2, KEY_0), @@ -110,8 +110,8 @@ static int bf548_keymap[] = { static struct bfin_kpad_platform_data bf54x_kpad_data = { .rows = 4, .cols = 4, - .keymap = bf548_keymap, - .keymapsize = ARRAY_SIZE(bf548_keymap), + .keymap = bf548_keymap, + .keymapsize = ARRAY_SIZE(bf548_keymap), .repeat = 0, .debounce_time = 5000, /* ns (5ms) */ .coldrive_time = 1000, /* ns (1ms) */ diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c index f4f9db698b44..b570ae9b6cad 100644 --- a/arch/cris/arch-v10/kernel/ptrace.c +++ b/arch/cris/arch-v10/kernel/ptrace.c @@ -177,10 +177,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = 0; break; - case PTRACE_DETACH: - ret = ptrace_detach(child, data); - break; - /* Get all GP registers from the child. */ case PTRACE_GETREGS: { int i; diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index 077e973c33f0..575a14bb1106 100644 --- a/arch/cris/arch-v10/kernel/time.c +++ b/arch/cris/arch-v10/kernel/time.c @@ -254,8 +254,12 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * it needs to be IRQF_DISABLED to make the jiffies update work properly */ -static struct irqaction irq2 = { timer_interrupt, IRQF_SHARED | IRQF_DISABLED, - CPU_MASK_NONE, "timer", NULL, NULL}; +static struct irqaction irq2 = { + .handler = timer_interrupt, + .flags = IRQF_SHARED | IRQF_DISABLED, + .mask = CPU_MASK_NONE, + .name = "timer", +}; void __init time_init(void) diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c index 38ece0cd47cb..2df60529a8af 100644 --- a/arch/cris/arch-v32/kernel/ptrace.c +++ b/arch/cris/arch-v32/kernel/ptrace.c @@ -245,10 +245,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; } - case PTRACE_DETACH: - ret = ptrace_detach(child, data); - break; - /* Get all GP registers from the child. */ case PTRACE_GETREGS: { int i; diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c index 77e655f26560..697494bc2de1 100644 --- a/arch/cris/arch-v32/kernel/smp.c +++ b/arch/cris/arch-v32/kernel/smp.c @@ -63,8 +63,12 @@ static unsigned long irq_regs[NR_CPUS] = static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int send_ipi(int vector, int wait, cpumask_t cpu_mask); -static struct irqaction irq_ipi = { crisv32_ipi_interrupt, IRQF_DISABLED, - CPU_MASK_NONE, "ipi", NULL, NULL}; +static struct irqaction irq_ipi = { + .handler = crisv32_ipi_interrupt, + .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, + .name = "ipi", +}; extern void cris_mmu_init(void); extern void cris_timer_init(void); diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c index 8672ab7d7978..8aab81430695 100644 --- a/arch/cris/mm/fault.c +++ b/arch/cris/mm/fault.c @@ -360,7 +360,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs, up_read(&mm->mmap_sem); printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c index ed588d73d7d8..e83e0bccfab9 100644 --- a/arch/frv/kernel/time.c +++ b/arch/frv/kernel/time.c @@ -43,7 +43,10 @@ unsigned long __delay_loops_MHz; static irqreturn_t timer_interrupt(int irq, void *dummy); static struct irqaction timer_irq = { - timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL + .handler = timer_interrupt, + .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, + .name = "timer", }; static inline int set_rtc_mmss(unsigned long nowtime) diff --git a/arch/frv/mm/fault.c b/arch/frv/mm/fault.c index 6798fa0257b1..05093d41d98e 100644 --- a/arch/frv/mm/fault.c +++ b/arch/frv/mm/fault.c @@ -259,7 +259,7 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear up_read(&mm->mmap_sem); printk("VM: killing process %s\n", current->comm); if (user_mode(__frame)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 2d85e4b87307..bf9aafad4978 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -214,6 +214,17 @@ config X86_ES7000 endchoice +config SCHED_NO_NO_OMIT_FRAME_POINTER + bool "Single-depth WCHAN output" + default y + help + Calculate simpler /proc/<PID>/wchan values. If this option + is disabled then wchan values will recurse back to the + caller function. This provides more accurate wchan values, + at the expense of slightly more scheduling overhead. + + If in doubt, say "Y". + config PARAVIRT bool "Paravirtualization support (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -1137,6 +1148,11 @@ config PCI_MMCONFIG depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) default y +config PCI_DOMAINS + bool + depends on PCI + default y + source "drivers/pci/pcie/Kconfig" source "drivers/pci/Kconfig" @@ -1206,6 +1222,16 @@ config SCx200HR_TIMER processor goes idle (as is done by the scheduler). The other workaround is idle=poll boot option. +config GEODE_MFGPT_TIMER + bool "Geode Multi-Function General Purpose Timer (MFGPT) events" + depends on MGEODE_LX && GENERIC_TIME && GENERIC_CLOCKEVENTS + default y + help + This driver provides a clock event source based on the MFGPT + timer(s) in the CS5535 and CS5536 companion chip for the geode. + MFGPTs have a better resolution and max interval than the + generic PIT, and are suitable for use as high-res timers. + config K8_NB def_bool y depends on AGP_AMD64 diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 8c39913d1729..59b91ac861ac 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -54,6 +54,11 @@ config ARCH_HAS_ILOG2_U64 bool default n +config HUGETLB_PAGE_SIZE_VARIABLE + bool + depends on HUGETLB_PAGE + default y + config GENERIC_FIND_NEXT_BIT bool default y @@ -300,6 +305,9 @@ config HOTPLUG_CPU config ARCH_ENABLE_MEMORY_HOTPLUG def_bool y +config ARCH_ENABLE_MEMORY_HOTREMOVE + def_bool y + config SCHED_SMT bool "SMT scheduler support" depends on SMP @@ -348,6 +356,7 @@ config ARCH_FLATMEM_ENABLE config ARCH_SPARSEMEM_ENABLE def_bool y depends on ARCH_DISCONTIGMEM_ENABLE + select SPARSEMEM_VMEMMAP_ENABLE config ARCH_DISCONTIGMEM_DEFAULT def_bool y if (IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) @@ -461,6 +470,16 @@ config IA64_ESI firmware extensions, such as the ability to inject memory-errors for test-purposes. If you're unsure, say N. +config IA64_HP_AML_NFW + bool "Support ACPI AML calls to native firmware" + help + This driver installs a global ACPI Operation Region handler for + region 0xA1. AML methods can use this OpRegion to call arbitrary + native firmware functions. The driver installs the OpRegion + handler if there is an HPQ5001 device or if the user supplies + the "force" module parameter, e.g., with the "aml_nfw.force" + kernel command line option. + source "drivers/sn/Kconfig" config KEXEC diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index 9aecfceeb38c..449d3e75bfc2 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig @@ -1,40 +1,40 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc1 -# Mon Oct 9 10:53:59 2006 +# Linux kernel version: 2.6.23-rc6 +# Tue Sep 18 11:24:01 2007 # CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_TASKSTATS=y # CONFIG_TASK_DELAY_ACCT is not set -# CONFIG_UTS_NS is not set +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +# CONFIG_USER_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=20 CONFIG_CPUSETS=y +CONFIG_SYSFS_DEPRECATED=y CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_TASK_XACCT=y CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set -# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -44,18 +44,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_SLUB=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 -# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set @@ -63,12 +65,9 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y CONFIG_STOP_MACHINE=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_BLK_DEV_BSG=y # # IO Schedulers @@ -88,12 +87,15 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_IA64=y CONFIG_64BIT=y +CONFIG_QUICKLIST=y CONFIG_MMU=y -CONFIG_SWIOTLB=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_DMI=y CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y @@ -116,6 +118,7 @@ CONFIG_IA64_PAGE_SIZE_16KB=y CONFIG_PGTABLE_4=y # 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_IA64_L1_CACHE_SHIFT=7 @@ -128,7 +131,10 @@ CONFIG_NR_CPUS=1024 # CONFIG_HOTPLUG_CPU is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_SCHED_SMT=y -CONFIG_PREEMPT=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_BKL=y CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_FLATMEM_MANUAL is not set CONFIG_DISCONTIGMEM_MANUAL=y @@ -140,6 +146,9 @@ CONFIG_NEED_MULTIPLE_NODES=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y CONFIG_RESOURCES_64BIT=y +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=1 +CONFIG_VIRT_TO_BUS=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_DISCONTIGMEM_ENABLE=y CONFIG_ARCH_FLATMEM_ENABLE=y @@ -154,16 +163,17 @@ CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y CONFIG_HAVE_ARCH_NODEDATA_EXTENSION=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y +CONFIG_COMPAT_FOR_U64_ALIGNMENT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y +CONFIG_IA64_MC_ERR_INJECT=y CONFIG_SGI_SN=y # CONFIG_IA64_ESI is not set # # SN Devices # -CONFIG_SGI_IOC4=y CONFIG_SGI_IOC3=y # @@ -171,6 +181,7 @@ CONFIG_SGI_IOC3=y # CONFIG_EFI_VARS=y CONFIG_EFI_PCDP=y +CONFIG_DMIID=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set @@ -180,12 +191,9 @@ CONFIG_BINFMT_ELF=y CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set - -# -# ACPI (Advanced Configuration and Power Interface) Support -# CONFIG_ACPI=y +# CONFIG_ACPI_PROCFS is not set +CONFIG_ACPI_PROC_EVENT=y # CONFIG_ACPI_BUTTON is not set # CONFIG_ACPI_FAN is not set # CONFIG_ACPI_DOCK is not set @@ -208,17 +216,14 @@ CONFIG_ACPI_SYSTEM=y # CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +CONFIG_PCI_SYSCALL=y CONFIG_PCIEPORTBUS=y CONFIG_HOTPLUG_PCI_PCIE=y # CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set CONFIG_PCIEAER=y +CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set -# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set - -# -# PCI Hotplug Support -# CONFIG_HOTPLUG_PCI=y # CONFIG_HOTPLUG_PCI_FAKE is not set # CONFIG_HOTPLUG_PCI_ACPI is not set @@ -239,13 +244,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y 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=y @@ -261,7 +266,7 @@ CONFIG_SYN_COOKIES=y # 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_TUNNEL=m CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y @@ -270,9 +275,11 @@ CONFIG_INET_TCP_DIAG=m # 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=m # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set @@ -283,25 +290,13 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=m CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m # CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES 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 @@ -327,7 +322,17 @@ CONFIG_INET6_XFRM_MODE_BEET=m # 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 +# CONFIG_NET_9P is not set # # Device Drivers @@ -340,31 +345,19 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # 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 - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set - -# -# Parallel port support -# # CONFIG_PARPORT is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set # -# Plug and Play support -# -# CONFIG_PNP is not set - -# -# Block devices +# Protocols # +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -379,13 +372,13 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m - -# -# ATA/ATAPI/MFM/RLL support -# +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +CONFIG_SGI_IOC4=y +# CONFIG_TIFM_CORE is not set CONFIG_IDE=y CONFIG_IDE_MAX_HWIFS=4 CONFIG_BLK_DEV_IDE=y @@ -400,20 +393,23 @@ CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_BLK_DEV_IDEACPI is not set # CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y # # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_BLK_DEV_IDEPNP is not set CONFIG_BLK_DEV_IDEPCI=y CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_IDEPCI_PCIBUS_ORDER=y # CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_GENERIC is not set # CONFIG_BLK_DEV_OPTI621 is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set @@ -428,6 +424,7 @@ CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8213 is not set # CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set @@ -438,10 +435,10 @@ CONFIG_BLK_DEV_SGIIOC4=y # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_TC86C001 is not set # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y # CONFIG_BLK_DEV_HD is not set # @@ -449,6 +446,8 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y @@ -469,6 +468,8 @@ CONFIG_CHR_DEV_SCH=m # CONFIG_SCSI_MULTI_LUN is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -478,11 +479,9 @@ CONFIG_SCSI_FC_ATTRS=y CONFIG_SCSI_ISCSI_ATTRS=m CONFIG_SCSI_SAS_ATTRS=y CONFIG_SCSI_SAS_LIBSAS=y +# CONFIG_SCSI_SAS_ATA is not set # CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set - -# -# SCSI low-level drivers -# +CONFIG_SCSI_LOWLEVEL=y CONFIG_ISCSI_TCP=m # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set @@ -512,11 +511,10 @@ CONFIG_SCSI_QLA_FC=y # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# +# CONFIG_SCSI_SRP is not set CONFIG_ATA=y +CONFIG_ATA_NONSTANDARD=y +CONFIG_ATA_ACPI=y # CONFIG_SATA_AHCI is not set # CONFIG_SATA_SVW is not set # CONFIG_ATA_PIIX is not set @@ -532,10 +530,12 @@ CONFIG_ATA=y # CONFIG_SATA_ULI is not set # CONFIG_SATA_VIA is not set CONFIG_SATA_VITESSE=y +# 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 @@ -547,8 +547,10 @@ CONFIG_SATA_VITESSE=y # 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 @@ -565,10 +567,6 @@ CONFIG_SATA_VITESSE=y # CONFIG_PATA_SIS is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set - -# -# Multi-device support (RAID and LVM) -# CONFIG_MD=y CONFIG_BLK_DEV_MD=y CONFIG_MD_LINEAR=y @@ -587,6 +585,8 @@ CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH_EMC=m +# CONFIG_DM_MULTIPATH_RDAC is not set +# CONFIG_DM_DELAY is not set # # Fusion MPT device support @@ -597,43 +597,25 @@ CONFIG_FUSION_FC=y CONFIG_FUSION_SAS=y CONFIG_FUSION_MAX_SGE=128 CONFIG_FUSION_CTL=m +CONFIG_FUSION_LOGGING=y # # 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_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# +# CONFIG_NET_SB1000 is not set # CONFIG_ARCNET is not set - -# -# PHY device support -# - -# -# Ethernet (10 or 100Mbit) -# # CONFIG_NET_ETHERNET 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 @@ -645,32 +627,39 @@ CONFIG_NETDEVICES=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y # CONFIG_BNX2 is not set # CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +# CONFIG_CHELSIO_T1_NAPI is not set +CONFIG_CHELSIO_T3=m # CONFIG_IXGB is not set CONFIG_S2IO=m # CONFIG_S2IO_NAPI is not set # CONFIG_MYRI10GE is not set - -# -# Token Ring devices -# +# CONFIG_NETXEN_NIC is not set +# CONFIG_MLX4_CORE is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) +# Wireless LAN # -# CONFIG_NET_RADIO is not set +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # -# Wan interfaces +# USB Network Adapters # +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -680,18 +669,9 @@ CONFIG_S2IO=m # CONFIG_SHAPER is not set CONFIG_NETCONSOLE=y CONFIG_NETPOLL=y -# CONFIG_NETPOLL_RX is not set # CONFIG_NETPOLL_TRAP is not set CONFIG_NET_POLL_CONTROLLER=y - -# -# ISDN subsystem -# # CONFIG_ISDN is not set - -# -# Telephony Support -# # CONFIG_PHONE is not set # @@ -699,6 +679,7 @@ CONFIG_NET_POLL_CONTROLLER=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -718,6 +699,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # 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 @@ -741,6 +723,7 @@ CONFIG_SERIAL_NONSTANDARD=y # CONFIG_DIGIEPCA is not set # CONFIG_MOXA_INTELLIO is not set # CONFIG_MOXA_SMARTIO is not set +# CONFIG_MOXA_SMARTIO_NEW is not set # CONFIG_ISI is not set # CONFIG_SYNCLINKMP is not set # CONFIG_SYNCLINK_GT is not set @@ -752,7 +735,6 @@ CONFIG_SERIAL_NONSTANDARD=y CONFIG_SGI_SNSC=y CONFIG_SGI_TIOCX=y CONFIG_SGI_MBCS=m -CONFIG_MSPEC=y # # Serial drivers @@ -771,28 +753,13 @@ CONFIG_SERIAL_SGI_IOC3=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set CONFIG_EFI_RTC=y -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# CONFIG_AGP=y -# CONFIG_AGP_SIS is not set -# CONFIG_AGP_VIA is not set CONFIG_AGP_SGI_TIOCA=y # CONFIG_DRM is not set CONFIG_RAW_DRIVER=m @@ -800,16 +767,8 @@ CONFIG_MAX_RAW_DEVS=256 # CONFIG_HPET is not set # CONFIG_HANGCHECK_TIMER is not set CONFIG_MMTIMER=y - -# -# TPM devices -# # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# +CONFIG_DEVPORT=y # CONFIG_I2C is not set # @@ -817,37 +776,33 @@ CONFIG_MMTIMER=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# - -# -# Hardware Monitoring support -# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set # -# Misc devices +# Multifunction device drivers # -# CONFIG_TIFM_CORE 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 is not set # -# Digital Video Broadcasting Devices +# Graphics support # -# CONFIG_DVB is not set -# CONFIG_USB_DABUSB 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_VIDEO_OUTPUT_CONTROL=m # CONFIG_FB is not set # @@ -856,16 +811,29 @@ CONFIG_FIRMWARE_EDID=y CONFIG_VGA_CONSOLE=y # CONFIG_VGACON_SOFT_SCROLLBACK is not set CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound # # CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HID_DEBUG=y # -# USB support +# USB Input Devices +# +CONFIG_USB_HID=m +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set + +# +# USB HID Boot Protocol drivers # +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y @@ -876,9 +844,10 @@ CONFIG_USB=m # Miscellaneous USB options # # CONFIG_USB_DEVICEFS is not set -# CONFIG_USB_BANDWIDTH is not set +CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set +# CONFIG_USB_PERSIST is not set # CONFIG_USB_OTG is not set # @@ -890,10 +859,12 @@ CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=m -# CONFIG_USB_OHCI_BIG_ENDIAN is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=m # CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set # # USB Device Class drivers @@ -912,47 +883,10 @@ CONFIG_USB_UHCI_HCD=m # CONFIG_USB_LIBUSUAL is not set # -# USB Input Devices -# -CONFIG_USB_HID=m -CONFIG_USB_HIDINPUT=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_TRANCEVIBRATOR is not set - -# # USB Imaging devices # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set CONFIG_USB_MON=y # @@ -974,6 +908,7 @@ CONFIG_USB_MON=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -983,6 +918,8 @@ CONFIG_USB_MON=y # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set # # USB DSL modem support @@ -992,48 +929,24 @@ CONFIG_USB_MON=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set - -# -# LED devices -# # CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# CONFIG_INFINIBAND=m # CONFIG_INFINIBAND_USER_MAD is not set CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MEM=y CONFIG_INFINIBAND_ADDR_TRANS=y CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_MTHCA_DEBUG=y # CONFIG_INFINIBAND_AMSO1100 is not set +# CONFIG_INFINIBAND_CXGB3 is not set +# CONFIG_MLX4_INFINIBAND is not set CONFIG_INFINIBAND_IPOIB=m +# CONFIG_INFINIBAND_IPOIB_CM is not set CONFIG_INFINIBAND_IPOIB_DEBUG=y # CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set CONFIG_INFINIBAND_SRP=m # CONFIG_INFINIBAND_ISER is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# # CONFIG_RTC_CLASS is not set # @@ -1050,6 +963,12 @@ CONFIG_INFINIBAND_SRP=m # # +# Userspace I/O +# +# CONFIG_UIO is not set +CONFIG_MSPEC=y + +# # File systems # CONFIG_EXT2_FS=y @@ -1061,6 +980,7 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1161,6 +1081,7 @@ CONFIG_EXPORTFS=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m +# CONFIG_SUNRPC_BIND34 is not set CONFIG_RPCSEC_GSS_KRB5=m # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1174,7 +1095,6 @@ CONFIG_CIFS=m # 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 @@ -1196,6 +1116,7 @@ CONFIG_SGI_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -1244,18 +1165,25 @@ CONFIG_NLS_UTF8=y # # Distributed Lock Manager # +# CONFIG_DLM is not set # # Library routines # +CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set CONFIG_CRC16=m +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m CONFIG_GENERIC_ALLOCATOR=y CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_PENDING_IRQ=y @@ -1274,25 +1202,28 @@ CONFIG_IRQ_PER_CPU=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=20 +# CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_SLUB_DEBUG_ON is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_RWSEMS 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_INFO=y -# CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set CONFIG_IA64_GRANULE_16MB=y # CONFIG_IA64_GRANULE_64MB is not set # CONFIG_IA64_PRINT_HAZARDS is not set @@ -1306,16 +1237,17 @@ CONFIG_SYSVIPC_COMPAT=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set - -# -# Cryptographic options -# +CONFIG_XOR_BLOCKS=y +CONFIG_ASYNC_CORE=y +CONFIG_ASYNC_MEMCPY=y +CONFIG_ASYNC_XOR=y CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=m CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=m +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 @@ -1324,9 +1256,14 @@ CONFIG_CRYPTO_SHA1=m # 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=m +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_SERPENT is not set @@ -1340,8 +1277,6 @@ CONFIG_CRYPTO_DES=m CONFIG_CRYPTO_DEFLATE=m # CONFIG_CRYPTO_MICHAEL_MIC is not set CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# +# CONFIG_CRYPTO_HW is not set diff --git a/arch/ia64/hp/common/Makefile b/arch/ia64/hp/common/Makefile index f61a60057ff7..9e179dd06b85 100644 --- a/arch/ia64/hp/common/Makefile +++ b/arch/ia64/hp/common/Makefile @@ -8,3 +8,4 @@ obj-y := sba_iommu.o obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += hwsw_iommu.o obj-$(CONFIG_IA64_GENERIC) += hwsw_iommu.o +obj-$(CONFIG_IA64_HP_AML_NFW) += aml_nfw.o diff --git a/arch/ia64/hp/common/aml_nfw.c b/arch/ia64/hp/common/aml_nfw.c new file mode 100644 index 000000000000..4abd2c79bb1d --- /dev/null +++ b/arch/ia64/hp/common/aml_nfw.c @@ -0,0 +1,236 @@ +/* + * OpRegion handler to allow AML to call native firmware + * + * (c) Copyright 2007 Hewlett-Packard Development Company, L.P. + * Bjorn Helgaas <bjorn.helgaas@hp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This driver implements HP Open Source Review Board proposal 1842, + * which was approved on 9/20/2006. + * + * For technical documentation, see the HP SPPA Firmware EAS, Appendix F. + * + * ACPI does not define a mechanism for AML methods to call native firmware + * interfaces such as PAL or SAL. This OpRegion handler adds such a mechanism. + * After the handler is installed, an AML method can call native firmware by + * storing the arguments and firmware entry point to specific offsets in the + * OpRegion. When AML reads the "return value" offset from the OpRegion, this + * handler loads up the arguments, makes the firmware call, and returns the + * result. + */ + +#include <linux/module.h> +#include <acpi/acpi_bus.h> +#include <acpi/acpi_drivers.h> +#include <asm/sal.h> + +MODULE_AUTHOR("Bjorn Helgaas <bjorn.helgaas@hp.com>"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ACPI opregion handler for native firmware calls"); + +static int force_register; +module_param_named(force, force_register, bool, 0); +MODULE_PARM_DESC(force, "Install opregion handler even without HPQ5001 device"); + +#define AML_NFW_SPACE 0xA1 + +struct ia64_pdesc { + void *ip; + void *gp; +}; + +/* + * N.B. The layout of this structure is defined in the HP SPPA FW EAS, and + * the member offsets are embedded in AML methods. + */ +struct ia64_nfw_context { + u64 arg[8]; + struct ia64_sal_retval ret; + u64 ip; + u64 gp; + u64 pad[2]; +}; + +static void *virt_map(u64 address) +{ + if (address & (1UL << 63)) + return (void *) (__IA64_UNCACHED_OFFSET | address); + + return __va(address); +} + +static void aml_nfw_execute(struct ia64_nfw_context *c) +{ + struct ia64_pdesc virt_entry; + ia64_sal_handler entry; + + virt_entry.ip = virt_map(c->ip); + virt_entry.gp = virt_map(c->gp); + + entry = (ia64_sal_handler) &virt_entry; + + IA64_FW_CALL(entry, c->ret, + c->arg[0], c->arg[1], c->arg[2], c->arg[3], + c->arg[4], c->arg[5], c->arg[6], c->arg[7]); +} + +static void aml_nfw_read_arg(u8 *offset, u32 bit_width, acpi_integer *value) +{ + switch (bit_width) { + case 8: + *value = *(u8 *)offset; + break; + case 16: + *value = *(u16 *)offset; + break; + case 32: + *value = *(u32 *)offset; + break; + case 64: + *value = *(u64 *)offset; + break; + } +} + +static void aml_nfw_write_arg(u8 *offset, u32 bit_width, acpi_integer *value) +{ + switch (bit_width) { + case 8: + *(u8 *) offset = *value; + break; + case 16: + *(u16 *) offset = *value; + break; + case 32: + *(u32 *) offset = *value; + break; + case 64: + *(u64 *) offset = *value; + break; + } +} + +static acpi_status aml_nfw_handler(u32 function, acpi_physical_address address, + u32 bit_width, acpi_integer *value, void *handler_context, + void *region_context) +{ + struct ia64_nfw_context *context = handler_context; + u8 *offset = (u8 *) context + address; + + if (bit_width != 8 && bit_width != 16 && + bit_width != 32 && bit_width != 64) + return AE_BAD_PARAMETER; + + if (address + (bit_width >> 3) > sizeof(struct ia64_nfw_context)) + return AE_BAD_PARAMETER; + + switch (function) { + case ACPI_READ: + if (address == offsetof(struct ia64_nfw_context, ret)) + aml_nfw_execute(context); + aml_nfw_read_arg(offset, bit_width, value); + break; + case ACPI_WRITE: + aml_nfw_write_arg(offset, bit_width, value); + break; + } + + return AE_OK; +} + +static struct ia64_nfw_context global_context; +static int global_handler_registered; + +static int aml_nfw_add_global_handler(void) +{ + acpi_status status; + + if (global_handler_registered) + return 0; + + status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, + AML_NFW_SPACE, aml_nfw_handler, NULL, &global_context); + if (ACPI_FAILURE(status)) + return -ENODEV; + + global_handler_registered = 1; + printk(KERN_INFO "Global 0x%02X opregion handler registered\n", + AML_NFW_SPACE); + return 0; +} + +static int aml_nfw_remove_global_handler(void) +{ + acpi_status status; + + if (!global_handler_registered) + return 0; + + status = acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, + AML_NFW_SPACE, aml_nfw_handler); + if (ACPI_FAILURE(status)) + return -ENODEV; + + global_handler_registered = 0; + printk(KERN_INFO "Global 0x%02X opregion handler removed\n", + AML_NFW_SPACE); + return 0; +} + +static int aml_nfw_add(struct acpi_device *device) +{ + /* + * We would normally allocate a new context structure and install + * the address space handler for the specific device we found. + * But the HP-UX implementation shares a single global context + * and always puts the handler at the root, so we'll do the same. + */ + return aml_nfw_add_global_handler(); +} + +static int aml_nfw_remove(struct acpi_device *device, int type) +{ + return aml_nfw_remove_global_handler(); +} + +static const struct acpi_device_id aml_nfw_ids[] = { + {"HPQ5001", 0}, + {"", 0} +}; + +static struct acpi_driver acpi_aml_nfw_driver = { + .name = "native firmware", + .ids = aml_nfw_ids, + .ops = { + .add = aml_nfw_add, + .remove = aml_nfw_remove, + }, +}; + +static int __init aml_nfw_init(void) +{ + int result; + + if (force_register) + aml_nfw_add_global_handler(); + + result = acpi_bus_register_driver(&acpi_aml_nfw_driver); + if (result < 0) { + aml_nfw_remove_global_handler(); + return result; + } + + return 0; +} + +static void __exit aml_nfw_exit(void) +{ + acpi_bus_unregister_driver(&acpi_aml_nfw_driver); + aml_nfw_remove_global_handler(); +} + +module_init(aml_nfw_init); +module_exit(aml_nfw_exit); diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index e980e7aa2306..4338f4123f31 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -396,7 +396,7 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents) printk(KERN_DEBUG " %d : DMA %08lx/%05x CPU %p\n", nents, startsg->dma_address, startsg->dma_length, sba_sg_address(startsg)); - startsg++; + startsg = sg_next(startsg); } } @@ -409,7 +409,7 @@ sba_check_sg( struct ioc *ioc, struct scatterlist *startsg, int nents) while (the_nents-- > 0) { if (sba_sg_address(the_sg) == 0x0UL) sba_dump_sg(NULL, startsg, nents); - the_sg++; + the_sg = sg_next(the_sg); } } @@ -1201,7 +1201,7 @@ sba_fill_pdir( u32 pide = startsg->dma_address & ~PIDE_FLAG; dma_offset = (unsigned long) pide & ~iovp_mask; startsg->dma_address = 0; - dma_sg++; + dma_sg = sg_next(dma_sg); dma_sg->dma_address = pide | ioc->ibase; pdirp = &(ioc->pdir_base[pide >> iovp_shift]); n_mappings++; @@ -1228,7 +1228,7 @@ sba_fill_pdir( pdirp++; } while (cnt > 0); } - startsg++; + startsg = sg_next(startsg); } /* force pdir update */ wmb(); @@ -1297,7 +1297,7 @@ sba_coalesce_chunks( struct ioc *ioc, while (--nents > 0) { unsigned long vaddr; /* tmp */ - startsg++; + startsg = sg_next(startsg); /* PARANOID */ startsg->dma_address = startsg->dma_length = 0; @@ -1407,7 +1407,7 @@ int sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, int di #ifdef ALLOW_IOV_BYPASS_SG ASSERT(to_pci_dev(dev)->dma_mask); if (likely((ioc->dma_mask & ~to_pci_dev(dev)->dma_mask) == 0)) { - for (sg = sglist ; filled < nents ; filled++, sg++){ + for_each_sg(sglist, sg, nents, filled) { sg->dma_length = sg->length; sg->dma_address = virt_to_phys(sba_sg_address(sg)); } @@ -1501,7 +1501,7 @@ void sba_unmap_sg (struct device *dev, struct scatterlist *sglist, int nents, in while (nents && sglist->dma_length) { sba_unmap_single(dev, sglist->dma_address, sglist->dma_length, dir); - sglist++; + sglist = sg_next(sglist); nents--; } diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c index 4552a1cf5b33..a3a558a06757 100644 --- a/arch/ia64/hp/sim/simscsi.c +++ b/arch/ia64/hp/sim/simscsi.c @@ -360,6 +360,7 @@ static struct scsi_host_template driver_template = { .max_sectors = 1024, .cmd_per_lun = SIMSCSI_REQ_QUEUE_LEN, .use_clustering = DISABLE_CLUSTERING, + .use_sg_chaining = ENABLE_SG_CHAINING, }; static int __init @@ -372,8 +373,13 @@ simscsi_init(void) return -ENOMEM; error = scsi_add_host(host, NULL); - if (!error) - scsi_scan_host(host); + if (error) + goto free_host; + scsi_scan_host(host); + return 0; + + free_host: + scsi_host_put(host); return error; } diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c index 8c6ec7070844..b8498ea62068 100644 --- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c +++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c @@ -321,8 +321,6 @@ acpi_cpufreq_cpu_init ( data->acpi_data.states[i].transition_latency * 1000; } } - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - policy->cur = processor_get_freq(data, policy->cpu); /* table init */ diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c index 1d64ef478dde..f1cf2df97a2d 100644 --- a/arch/ia64/kernel/crash.c +++ b/arch/ia64/kernel/crash.c @@ -118,11 +118,6 @@ machine_crash_shutdown(struct pt_regs *pt) static void machine_kdump_on_init(void) { - if (!ia64_kimage) { - printk(KERN_NOTICE "machine_kdump_on_init(): " - "kdump not configured\n"); - return; - } local_irq_disable(); kexec_disable_iosapic(); machine_kexec(ia64_kimage); @@ -156,6 +151,14 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data) if (!kdump_on_init) return NOTIFY_DONE; + if (!ia64_kimage) { + if (val == DIE_INIT_MONARCH_LEAVE) + ia64_mca_printk(KERN_NOTICE + "%s: kdump not configured\n", + __FUNCTION__); + return NOTIFY_DONE; + } + if (val != DIE_INIT_MONARCH_LEAVE && val != DIE_INIT_SLAVE_LEAVE && val != DIE_INIT_MONARCH_PROCESS && diff --git a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S index 6d198339bf85..44817d97ab43 100644 --- a/arch/ia64/kernel/gate.lds.S +++ b/arch/ia64/kernel/gate.lds.S @@ -1,7 +1,8 @@ /* - * Linker script for gate DSO. The gate pages are an ELF shared object prelinked to its - * virtual address, with only one read-only segment and one execute-only segment (both fit - * in one page). This script controls its layout. + * Linker script for gate DSO. The gate pages are an ELF shared object + * prelinked to its virtual address, with only one read-only segment and + * one execute-only segment (both fit in one page). This script controls + * its layout. */ @@ -9,72 +10,80 @@ SECTIONS { - . = GATE_ADDR + SIZEOF_HEADERS; - - .hash : { *(.hash) } :readable - .gnu.hash : { *(.gnu.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - .dynamic : { *(.dynamic) } :readable :dynamic - - /* - * This linker script is used both with -r and with -shared. For the layouts to match, - * we need to skip more than enough space for the dynamic symbol table et al. If this - * amount is insufficient, ld -shared will barf. Just increase it here. - */ - . = GATE_ADDR + 0x500; - - .data.patch : { - __start_gate_mckinley_e9_patchlist = .; - *(.data.patch.mckinley_e9) - __end_gate_mckinley_e9_patchlist = .; - - __start_gate_vtop_patchlist = .; - *(.data.patch.vtop) - __end_gate_vtop_patchlist = .; - - __start_gate_fsyscall_patchlist = .; - *(.data.patch.fsyscall_table) - __end_gate_fsyscall_patchlist = .; - - __start_gate_brl_fsys_bubble_down_patchlist = .; - *(.data.patch.brl_fsys_bubble_down) - __end_gate_brl_fsys_bubble_down_patchlist = .; - } :readable - .IA_64.unwind_info : { *(.IA_64.unwind_info*) } - .IA_64.unwind : { *(.IA_64.unwind*) } :readable :unwind + . = GATE_ADDR + SIZEOF_HEADERS; + + .hash : { *(.hash) } :readable + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + + .dynamic : { *(.dynamic) } :readable :dynamic + + /* + * This linker script is used both with -r and with -shared. For + * the layouts to match, we need to skip more than enough space for + * the dynamic symbol table et al. If this amount is insufficient, + * ld -shared will barf. Just increase it here. + */ + . = GATE_ADDR + 0x500; + + .data.patch : { + __start_gate_mckinley_e9_patchlist = .; + *(.data.patch.mckinley_e9) + __end_gate_mckinley_e9_patchlist = .; + + __start_gate_vtop_patchlist = .; + *(.data.patch.vtop) + __end_gate_vtop_patchlist = .; + + __start_gate_fsyscall_patchlist = .; + *(.data.patch.fsyscall_table) + __end_gate_fsyscall_patchlist = .; + + __start_gate_brl_fsys_bubble_down_patchlist = .; + *(.data.patch.brl_fsys_bubble_down) + __end_gate_brl_fsys_bubble_down_patchlist = .; + } :readable + + .IA_64.unwind_info : { *(.IA_64.unwind_info*) } + .IA_64.unwind : { *(.IA_64.unwind*) } :readable :unwind #ifdef HAVE_BUGGY_SEGREL - .text (GATE_ADDR + PAGE_SIZE) : { *(.text) *(.text.*) } :readable + .text (GATE_ADDR + PAGE_SIZE) : { *(.text) *(.text.*) } :readable #else - . = ALIGN (PERCPU_PAGE_SIZE) + (. & (PERCPU_PAGE_SIZE - 1)); - .text : { *(.text) *(.text.*) } :epc + . = ALIGN(PERCPU_PAGE_SIZE) + (. & (PERCPU_PAGE_SIZE - 1)); + .text : { *(.text) *(.text.*) } :epc #endif - /DISCARD/ : { - *(.got.plt) *(.got) - *(.data .data.* .gnu.linkonce.d.*) - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(__ex_table) - *(__mca_table) - } + /DISCARD/ : { + *(.got.plt) *(.got) + *(.data .data.* .gnu.linkonce.d.*) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(__ex_table) + *(__mca_table) + } } /* + * ld does not recognize this name token; use the constant. + */ +#define PT_IA_64_UNWIND 0x70000001 + +/* * We must supply the ELF program headers explicitly to get just one * PT_LOAD segment, and set the flags explicitly to make segments read-only. */ PHDRS { - readable PT_LOAD FILEHDR PHDRS FLAGS(4); /* PF_R */ + readable PT_LOAD FILEHDR PHDRS FLAGS(4); /* PF_R */ #ifndef HAVE_BUGGY_SEGREL - epc PT_LOAD FILEHDR PHDRS FLAGS(1); /* PF_X */ + epc PT_LOAD FILEHDR PHDRS FLAGS(1); /* PF_X */ #endif - dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ - unwind 0x70000001; /* PT_IA_64_UNWIND, but ld doesn't match the name */ + dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ + unwind PT_IA_64_UNWIND; } /* @@ -82,14 +91,14 @@ PHDRS */ VERSION { - LINUX_2.5 { - global: - __kernel_syscall_via_break; - __kernel_syscall_via_epc; - __kernel_sigtramp; - - local: *; - }; + LINUX_2.5 { + global: + __kernel_syscall_via_break; + __kernel_syscall_via_epc; + __kernel_sigtramp; + + local: *; + }; } /* The ELF entry point can be used to set the AT_SYSINFO value. */ diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 5dc98b5abcfb..5fd65d8302c8 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -40,6 +40,8 @@ extern void jprobe_inst_return(void); DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); +struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}}; + enum instruction_type {A, I, M, F, B, L, X, u}; static enum instruction_type bundle_encoding[32][3] = { { M, I, I }, /* 00 */ diff --git a/arch/ia64/kernel/machine_kexec.c b/arch/ia64/kernel/machine_kexec.c index 4f0f3b8c1ee2..58e943a5d95c 100644 --- a/arch/ia64/kernel/machine_kexec.c +++ b/arch/ia64/kernel/machine_kexec.c @@ -79,7 +79,6 @@ static void ia64_machine_kexec(struct unw_frame_info *info, void *arg) relocate_new_kernel_t rnk; void *pal_addr = efi_get_pal_addr(); unsigned long code_addr = (unsigned long)page_address(image->control_code_page); - unsigned long vector; int ii; BUG_ON(!image); @@ -107,11 +106,8 @@ static void ia64_machine_kexec(struct unw_frame_info *info, void *arg) /* unmask TPR and clear any pending interrupts */ ia64_setreg(_IA64_REG_CR_TPR, 0); ia64_srlz_d(); - vector = ia64_get_ivr(); - while (vector != IA64_SPURIOUS_INT_VECTOR) { + while (ia64_get_ivr() != IA64_SPURIOUS_INT_VECTOR) ia64_eoi(); - vector = ia64_get_ivr(); - } platform_kernel_launch_event(); rnk = (relocate_new_kernel_t)&code_addr; (*rnk)(image->head, image->start, ia64_boot_param, diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 63b73f3d4c9f..cc87025e8f54 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -701,8 +701,7 @@ ia64_mca_cmc_vector_enable_keventd(struct work_struct *unused) /* * ia64_mca_wakeup * - * Send an inter-cpu interrupt to wake-up a particular cpu - * and mark that cpu to be out of rendez. + * Send an inter-cpu interrupt to wake-up a particular cpu. * * Inputs : cpuid * Outputs : None @@ -711,14 +710,12 @@ static void ia64_mca_wakeup(int cpu) { platform_send_ipi(cpu, IA64_MCA_WAKEUP_VECTOR, IA64_IPI_DM_INT, 0); - ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; - } /* * ia64_mca_wakeup_all * - * Wakeup all the cpus which have rendez'ed previously. + * Wakeup all the slave cpus which have rendez'ed previously. * * Inputs : None * Outputs : None @@ -741,7 +738,10 @@ ia64_mca_wakeup_all(void) * * This is handler used to put slave processors into spinloop * while the monarch processor does the mca handling and later - * wake each slave up once the monarch is done. + * wake each slave up once the monarch is done. The state + * IA64_MCA_RENDEZ_CHECKIN_DONE indicates the cpu is rendez'ed + * in SAL. The state IA64_MCA_RENDEZ_CHECKIN_NOTDONE indicates + * the cpu has come out of OS rendezvous. * * Inputs : None * Outputs : None @@ -778,6 +778,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg) (long)&nd, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); + ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; /* Enable all interrupts */ local_irq_restore(flags); return IRQ_HANDLED; @@ -1135,30 +1136,27 @@ no_mod: static void ia64_wait_for_slaves(int monarch, const char *type) { - int c, wait = 0, missing = 0; - for_each_online_cpu(c) { - if (c == monarch) - continue; - if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) { - udelay(1000); /* short wait first */ - wait = 1; - break; - } - } - if (!wait) - goto all_in; - for_each_online_cpu(c) { - if (c == monarch) - continue; - if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) { - udelay(5*1000000); /* wait 5 seconds for slaves (arbitrary) */ - if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) - missing = 1; - break; + int c, i , wait; + + /* + * wait 5 seconds total for slaves (arbitrary) + */ + for (i = 0; i < 5000; i++) { + wait = 0; + for_each_online_cpu(c) { + if (c == monarch) + continue; + if (ia64_mc_info.imi_rendez_checkin[c] + == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) { + udelay(1000); /* short wait */ + wait = 1; + break; + } } + if (!wait) + goto all_in; } - if (!missing) - goto all_in; + /* * Maybe slave(s) dead. Print buffered messages immediately. */ @@ -1224,26 +1222,27 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); + + ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA; if (sos->monarch) { ia64_wait_for_slaves(cpu, "MCA"); + + /* Wakeup all the processors which are spinning in the + * rendezvous loop. They will leave SAL, then spin in the OS + * with interrupts disabled until this monarch cpu leaves the + * MCA handler. That gets control back to the OS so we can + * backtrace the other cpus, backtrace when spinning in SAL + * does not work. + */ + ia64_mca_wakeup_all(); + if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, (long)&nd, 0, 0) + == NOTIFY_STOP) + ia64_mca_spin(__FUNCTION__); } else { - ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA; while (cpu_isset(cpu, mca_cpu)) cpu_relax(); /* spin until monarch wakes us */ - ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; } - /* Wakeup all the processors which are spinning in the rendezvous loop. - * They will leave SAL, then spin in the OS with interrupts disabled - * until this monarch cpu leaves the MCA handler. That gets control - * back to the OS so we can backtrace the other cpus, backtrace when - * spinning in SAL does not work. - */ - ia64_mca_wakeup_all(); - if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, (long)&nd, 0, 0) - == NOTIFY_STOP) - ia64_mca_spin(__FUNCTION__); - /* Get the MCA error record and log it */ ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA); @@ -1277,21 +1276,22 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, /* wake up the next monarch cpu, * and put this cpu in the rendez loop. */ - ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA; for_each_online_cpu(i) { if (cpu_isset(i, mca_cpu)) { monarch_cpu = i; cpu_clear(i, mca_cpu); /* wake next cpu */ while (monarch_cpu != -1) cpu_relax(); /* spin until last cpu leaves */ - ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; set_curr_task(cpu, previous_current); + ia64_mc_info.imi_rendez_checkin[cpu] + = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; return; } } } set_curr_task(cpu, previous_current); - monarch_cpu = -1; + ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; + monarch_cpu = -1; /* This frees the slaves and previous monarchs */ } static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd); diff --git a/arch/ia64/kernel/mca_drv.h b/arch/ia64/kernel/mca_drv.h index c85e943ba5fd..485e34d0b199 100644 --- a/arch/ia64/kernel/mca_drv.h +++ b/arch/ia64/kernel/mca_drv.h @@ -118,7 +118,5 @@ struct mca_table_entry { extern const struct mca_table_entry *search_mca_tables (unsigned long addr); extern int mca_recover_range(unsigned long); -extern void ia64_mca_printk(const char * fmt, ...) - __attribute__ ((format (printf, 1, 2))); extern void ia64_mlogbuf_dump(void); diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 85829e27785c..6ef6ffb943a0 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -907,7 +907,7 @@ palinfo_read_entry(char *page, char **start, off_t off, int count, int *eof, voi return len; } -static void +static void __cpuinit create_palinfo_proc_entries(unsigned int cpu) { # define CPUSTR "cpu%d" @@ -968,7 +968,7 @@ remove_palinfo_proc_entries(unsigned int hcpu) } } -static int palinfo_cpu_callback(struct notifier_block *nfb, +static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int hotcpu = (unsigned long)hcpu; @@ -986,7 +986,7 @@ static int palinfo_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block palinfo_cpu_notifier = +static struct notifier_block palinfo_cpu_notifier __cpuinitdata = { .notifier_call = palinfo_cpu_callback, .priority = 0, diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 14b8e5a6222b..f55fa07849c4 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -1538,13 +1538,6 @@ init_pfm_fs(void) return err; } -static void __exit -exit_pfm_fs(void) -{ - unregister_filesystem(&pfm_fs_type); - mntput(pfmfs_mnt); -} - static ssize_t pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos) { diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index 25cd75f50ab1..779c3cca206c 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c @@ -574,7 +574,7 @@ static const struct file_operations salinfo_data_fops = { .write = salinfo_log_write, }; -static int __devinit +static int __cpuinit salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) { unsigned int i, cpu = (unsigned long)hcpu; @@ -615,7 +615,7 @@ salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu return NOTIFY_OK; } -static struct notifier_block salinfo_cpu_notifier = +static struct notifier_block salinfo_cpu_notifier __cpuinitdata = { .notifier_call = salinfo_cpu_callback, .priority = 0, diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 9e392a30d197..777c8d8bd5e7 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -528,10 +528,6 @@ setup_arch (char **cmdline_p) #ifdef CONFIG_SMP cpu_physical_id(0) = hard_smp_processor_id(); - - cpu_set(0, cpu_sibling_map[0]); - cpu_set(0, cpu_core_map[0]); - check_for_logical_procs(); if (smp_num_cpucores > 1) printk(KERN_INFO @@ -873,6 +869,14 @@ cpu_init (void) void *cpu_data; cpu_data = per_cpu_init(); + /* + * insert boot cpu into sibling and core mapes + * (must be done after per_cpu area is setup) + */ + if (smp_processor_id() == 0) { + cpu_set(0, per_cpu(cpu_sibling_map, 0)); + cpu_set(0, cpu_core_map[0]); + } /* * We set ar.k3 so that assembly code in MCA handler can compute diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 308772f7cddc..c57dbce25c12 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -138,7 +138,9 @@ cpumask_t cpu_possible_map = CPU_MASK_NONE; EXPORT_SYMBOL(cpu_possible_map); cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; -cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; +DEFINE_PER_CPU_SHARED_ALIGNED(cpumask_t, cpu_sibling_map); +EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); + int smp_num_siblings = 1; int smp_num_cpucores = 1; @@ -650,12 +652,12 @@ clear_cpu_sibling_map(int cpu) { int i; - for_each_cpu_mask(i, cpu_sibling_map[cpu]) - cpu_clear(cpu, cpu_sibling_map[i]); + for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu)) + cpu_clear(cpu, per_cpu(cpu_sibling_map, i)); for_each_cpu_mask(i, cpu_core_map[cpu]) cpu_clear(cpu, cpu_core_map[i]); - cpu_sibling_map[cpu] = cpu_core_map[cpu] = CPU_MASK_NONE; + per_cpu(cpu_sibling_map, cpu) = cpu_core_map[cpu] = CPU_MASK_NONE; } static void @@ -666,7 +668,7 @@ remove_siblinginfo(int cpu) if (cpu_data(cpu)->threads_per_core == 1 && cpu_data(cpu)->cores_per_socket == 1) { cpu_clear(cpu, cpu_core_map[cpu]); - cpu_clear(cpu, cpu_sibling_map[cpu]); + cpu_clear(cpu, per_cpu(cpu_sibling_map, cpu)); return; } @@ -807,8 +809,8 @@ set_cpu_sibling_map(int cpu) cpu_set(i, cpu_core_map[cpu]); cpu_set(cpu, cpu_core_map[i]); if (cpu_data(cpu)->core_id == cpu_data(i)->core_id) { - cpu_set(i, cpu_sibling_map[cpu]); - cpu_set(cpu, cpu_sibling_map[i]); + cpu_set(i, per_cpu(cpu_sibling_map, cpu)); + cpu_set(cpu, per_cpu(cpu_sibling_map, i)); } } } @@ -839,7 +841,7 @@ __cpu_up (unsigned int cpu) if (cpu_data(cpu)->threads_per_core == 1 && cpu_data(cpu)->cores_per_socket == 1) { - cpu_set(cpu, cpu_sibling_map[cpu]); + cpu_set(cpu, per_cpu(cpu_sibling_map, cpu)); cpu_set(cpu, cpu_core_map[cpu]); return 0; } diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index 94ae3c87d828..14261fee5f4d 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -118,11 +118,11 @@ struct cpu_cache_info { struct kobject kobj; }; -static struct cpu_cache_info all_cpu_cache_info[NR_CPUS]; +static struct cpu_cache_info all_cpu_cache_info[NR_CPUS] __cpuinitdata; #define LEAF_KOBJECT_PTR(x,y) (&all_cpu_cache_info[x].cache_leaves[y]) #ifdef CONFIG_SMP -static void cache_shared_cpu_map_setup( unsigned int cpu, +static void __cpuinit cache_shared_cpu_map_setup( unsigned int cpu, struct cache_info * this_leaf) { pal_cache_shared_info_t csi; @@ -157,7 +157,7 @@ static void cache_shared_cpu_map_setup( unsigned int cpu, &csi) == PAL_STATUS_SUCCESS); } #else -static void cache_shared_cpu_map_setup(unsigned int cpu, +static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, struct cache_info * this_leaf) { cpu_set(cpu, this_leaf->shared_cpu_map); @@ -428,13 +428,13 @@ static struct notifier_block __cpuinitdata cache_cpu_notifier = .notifier_call = cache_cpu_callback }; -static int __cpuinit cache_sysfs_init(void) +static int __init cache_sysfs_init(void) { int i; for_each_online_cpu(i) { - cache_cpu_callback(&cache_cpu_notifier, CPU_ONLINE, - (void *)(long)i); + struct sys_device *sys_dev = get_cpu_sysdev((unsigned int)i); + cache_add_dev(sys_dev); } register_hotcpu_notifier(&cache_cpu_notifier); diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index c58e933694d5..a7be4f203420 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c @@ -196,7 +196,7 @@ unsigned long uncached_alloc_page(int starting_nid) nid = starting_nid; do { - if (!node_online(nid)) + if (!node_state(nid, N_HIGH_MEMORY)) continue; uc_pool = &uncached_pools[nid]; if (uc_pool->pool == NULL) @@ -268,7 +268,7 @@ static int __init uncached_init(void) { int nid; - for_each_online_node(nid) { + for_each_node_state(nid, N_ONLINE) { uncached_pools[nid].pool = gen_pool_create(PAGE_SHIFT, nid); mutex_init(&uncached_pools[nid].add_chunk_mutex); } diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 0d34585058c8..5628067a74d2 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -715,3 +715,11 @@ void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat) scatter_node_data(); } #endif + +#ifdef CONFIG_SPARSEMEM_VMEMMAP +int __meminit vmemmap_populate(struct page *start_page, + unsigned long size, int node) +{ + return vmemmap_populate_basepages(start_page, size, node); +} +#endif diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index 9150ffaff9e8..32f26253c4e8 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c @@ -281,6 +281,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re } printk(KERN_CRIT "VM: killing process %s\n", current->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; } diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c index a9ff685aea25..d3ce8f3bcaa6 100644 --- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c @@ -194,6 +194,6 @@ static int __init hugetlb_setup_sz(char *str) * override here with new page shift. */ ia64_set_rr(HPAGE_REGION_BASE, hpage_shift << 2); - return 1; + return 0; } -__setup("hugepagesz=", hugetlb_setup_sz); +early_param("hugepagesz", hugetlb_setup_sz); diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index c14abefabafa..3e10152abbf0 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -54,15 +54,12 @@ struct page *zero_page_memmap_ptr; /* map entry for zero page */ EXPORT_SYMBOL(zero_page_memmap_ptr); void -lazy_mmu_prot_update (pte_t pte) +__ia64_sync_icache_dcache (pte_t pte) { unsigned long addr; struct page *page; unsigned long order; - if (!pte_exec(pte)) - return; /* not an executable page... */ - page = pte_page(pte); addr = (unsigned long) page_address(page); @@ -721,10 +718,21 @@ int arch_add_memory(int nid, u64 start, u64 size) return ret; } - +#ifdef CONFIG_MEMORY_HOTREMOVE int remove_memory(u64 start, u64 size) { - return -EINVAL; + unsigned long start_pfn, end_pfn; + unsigned long timeout = 120 * HZ; + int ret; + start_pfn = start >> PAGE_SHIFT; + end_pfn = start_pfn + (size >> PAGE_SHIFT); + ret = offline_pages(start_pfn, end_pfn, timeout); + if (ret) + goto out; + /* we can free mem_map at this point */ +out: + return ret; } EXPORT_SYMBOL_GPL(remove_memory); +#endif /* CONFIG_MEMORY_HOTREMOVE */ #endif diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index 5a289e4de838..a88eba3314d7 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c @@ -66,8 +66,7 @@ static int tiocx_match(struct device *dev, struct device_driver *drv) } -static int tiocx_uevent(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size) +static int tiocx_uevent(struct device *dev, struct kobj_uevent_env *env) { return -ENODEV; } diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index d79ddacfba2d..ecd8a52b9b9e 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -218,16 +218,17 @@ EXPORT_SYMBOL(sn_dma_unmap_single); * * Unmap a set of streaming mode DMA translations. */ -void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sg, +void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, int nhwentries, int direction) { int i; struct pci_dev *pdev = to_pci_dev(dev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); + struct scatterlist *sg; BUG_ON(dev->bus != &pci_bus_type); - for (i = 0; i < nhwentries; i++, sg++) { + for_each_sg(sgl, sg, nhwentries, i) { provider->dma_unmap(pdev, sg->dma_address, direction); sg->dma_address = (dma_addr_t) NULL; sg->dma_length = 0; @@ -244,11 +245,11 @@ EXPORT_SYMBOL(sn_dma_unmap_sg); * * Maps each entry of @sg for DMA. */ -int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries, +int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, int nhwentries, int direction) { unsigned long phys_addr; - struct scatterlist *saved_sg = sg; + struct scatterlist *saved_sg = sgl, *sg; struct pci_dev *pdev = to_pci_dev(dev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); int i; @@ -258,7 +259,7 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries, /* * Setup a DMA address for each entry in the scatterlist. */ - for (i = 0; i < nhwentries; i++, sg++) { + for_each_sg(sgl, sg, nhwentries, i) { phys_addr = SG_ENT_PHYS_ADDRESS(sg); sg->dma_address = provider->dma_map(pdev, phys_addr, sg->length, diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c index 62a51429306e..ed4d0756c5db 100644 --- a/arch/m32r/kernel/ptrace.c +++ b/arch/m32r/kernel/ptrace.c @@ -570,7 +570,7 @@ withdraw_debug_trap(struct pt_regs *regs) } } -static void +void init_debug_traps(struct task_struct *child) { struct debug_trap *p = &child->thread.debug_trap; @@ -593,8 +593,8 @@ void ptrace_disable(struct task_struct *child) /* nothing to do.. */ } -static int -do_ptrace(long request, struct task_struct *child, long addr, long data) +long +arch_ptrace(struct task_struct *child, long request, long addr, long data) { int ret; @@ -704,14 +704,6 @@ do_ptrace(long request, struct task_struct *child, long addr, long data) break; } - /* - * detach a process that was attached. - */ - case PTRACE_DETACH: - ret = 0; - ret = ptrace_detach(child, data); - break; - case PTRACE_GETREGS: ret = ptrace_getregs(child, (void __user *)data); break; @@ -728,42 +720,6 @@ do_ptrace(long request, struct task_struct *child, long addr, long data) return ret; } -asmlinkage long sys_ptrace(long request, long pid, long addr, long data) -{ - struct task_struct *child; - int ret; - - lock_kernel(); - if (request == PTRACE_TRACEME) { - ret = ptrace_traceme(); - goto out; - } - - child = ptrace_get_task_struct(pid); - if (IS_ERR(child)) { - ret = PTR_ERR(child); - goto out; - } - - if (request == PTRACE_ATTACH) { - ret = ptrace_attach(child); - if (ret == 0) - init_debug_traps(child); - goto out_tsk; - } - - ret = ptrace_check_attach(child, request == PTRACE_KILL); - if (ret == 0) - ret = do_ptrace(request, child, addr, data); - -out_tsk: - put_task_struct(child); -out: - unlock_kernel(); - - return ret; -} - /* notification of system call entry/exit * - triggered by current->work.syscall_trace */ diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c index 3858c9f39ba5..994cc1556355 100644 --- a/arch/m32r/kernel/time.c +++ b/arch/m32r/kernel/time.c @@ -228,8 +228,12 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, - "MFT2", NULL, NULL }; +struct irqaction irq0 = { + .handler = timer_interrupt, + .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, + .name = "MFT2", +}; void __init time_init(void) { diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c index 676a1c443d28..70a766aad3e0 100644 --- a/arch/m32r/mm/fault.c +++ b/arch/m32r/mm/fault.c @@ -278,7 +278,7 @@ out_of_memory: } printk("VM: killing process %s\n", tsk->comm); if (error_code & ACE_USERMODE) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c index 2b5f64726a2e..880add120eb3 100644 --- a/arch/m68k/atari/atakeyb.c +++ b/arch/m68k/atari/atakeyb.c @@ -1,6 +1,4 @@ /* - * linux/atari/atakeyb.c - * * Atari Keyboard driver for 680x0 Linux * * This file is subject to the terms and conditions of the GNU General Public @@ -11,6 +9,9 @@ /* * Atari support by Robert de Vries * enhanced by Bjoern Brauel and Roman Hodek + * + * 2.6 and input cleanup (removed autorepeat stuff) for 2.6.21 + * 06/07 Michael Schmitz */ #include <linux/module.h> @@ -32,7 +33,6 @@ #include <asm/atari_joystick.h> #include <asm/irq.h> -static void atakeyb_rep(unsigned long ignore); extern unsigned int keymap_count; /* Hook for MIDI serial driver */ @@ -104,25 +104,6 @@ static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, }; * - Keypad Left/Right Parenthesis mapped to new K_PPAREN[LR] */ -static u_short ataplain_map[NR_KEYS] __initdata = { - 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, - 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf008, 0xf009, - 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, - 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, - 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, - 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, - 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf200, - 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, - 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf114, - 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200, - 0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf1ff, 0xf11b, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307, - 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303, - 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200 -}; - typedef enum kb_state_t { KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK, RESYNC } KB_STATE_T; @@ -137,41 +118,6 @@ typedef struct keyboard_state { KEYBOARD_STATE kb_state; -#define DEFAULT_KEYB_REP_DELAY (HZ/4) -#define DEFAULT_KEYB_REP_RATE (HZ/25) - -/* These could be settable by some ioctl() in future... */ -static unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY; -static unsigned int key_repeat_rate = DEFAULT_KEYB_REP_RATE; - -static unsigned char rep_scancode; -static struct timer_list atakeyb_rep_timer = { - .function = atakeyb_rep, -}; - -static void atakeyb_rep(unsigned long ignore) -{ - /* Disable keyboard for the time we call handle_scancode(), else a race - * in the keyboard tty queue may happen */ - atari_disable_irq(IRQ_MFP_ACIA); - del_timer(&atakeyb_rep_timer); - - /* A keyboard int may have come in before we disabled the irq, so - * double-check whether rep_scancode is still != 0 */ - if (rep_scancode) { - init_timer(&atakeyb_rep_timer); - atakeyb_rep_timer.expires = jiffies + key_repeat_rate; - add_timer(&atakeyb_rep_timer); - - //handle_scancode(rep_scancode, 1); - if (atari_input_keyboard_interrupt_hook) - atari_input_keyboard_interrupt_hook(rep_scancode, 1); - } - - atari_enable_irq(IRQ_MFP_ACIA); -} - - /* ++roman: If a keyboard overrun happened, we can't tell in general how much * bytes have been lost and in which state of the packet structure we are now. * This usually causes keyboards bytes to be interpreted as mouse movements @@ -209,9 +155,6 @@ repeat: /* ...happens often if interrupts were disabled for too long */ printk(KERN_DEBUG "Keyboard overrun\n"); scancode = acia.key_data; - /* Turn off autorepeating in case a break code has been lost */ - del_timer(&atakeyb_rep_timer); - rep_scancode = 0; if (ikbd_self_test) /* During self test, don't do resyncing, just process the code */ goto interpret_scancode; @@ -281,11 +224,12 @@ repeat: * make codes instead. Therefore, simply ignore * break_flag... */ - int keyval = plain_map[scancode], keytyp; + int keyval, keytyp; set_bit(scancode, broken_keys); self_test_last_rcv = jiffies; - keyval = plain_map[scancode]; + /* new Linux scancodes; approx. */ + keyval = scancode; keytyp = KTYP(keyval) - 0xf0; keyval = KVAL(keyval); @@ -301,19 +245,6 @@ repeat: } else if (test_bit(scancode, broken_keys)) break; -#if 0 // FIXME; hangs at boot - if (break_flag) { - del_timer(&atakeyb_rep_timer); - rep_scancode = 0; - } else { - del_timer(&atakeyb_rep_timer); - rep_scancode = scancode; - atakeyb_rep_timer.expires = jiffies + key_repeat_delay; - add_timer(&atakeyb_rep_timer); - } -#endif - - // handle_scancode(scancode, !break_flag); if (atari_input_keyboard_interrupt_hook) atari_input_keyboard_interrupt_hook((unsigned char)scancode, !break_flag); break; @@ -639,9 +570,6 @@ int __init atari_keyb_init(void) if (atari_keyb_done) return 0; - /* setup key map */ - memcpy(key_maps[0], ataplain_map, sizeof(plain_map)); - kb_state.state = KEYBOARD; kb_state.len = 0; @@ -704,26 +632,6 @@ int __init atari_keyb_init(void) return 0; } -int atari_kbdrate(struct kbd_repeat *k) -{ - if (k->delay > 0) { - /* convert from msec to jiffies */ - key_repeat_delay = (k->delay * HZ + 500) / 1000; - if (key_repeat_delay < 1) - key_repeat_delay = 1; - } - if (k->period > 0) { - key_repeat_rate = (k->period * HZ + 500) / 1000; - if (key_repeat_rate < 1) - key_repeat_rate = 1; - } - - k->delay = key_repeat_delay * 1000 / HZ; - k->period = key_repeat_rate * 1000 / HZ; - - return 0; -} - int atari_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode) { #ifdef CONFIG_MAGIC_SYSRQ diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c index e792d3cba4c7..2075543c2d92 100644 --- a/arch/m68k/kernel/ptrace.c +++ b/arch/m68k/kernel/ptrace.c @@ -226,10 +226,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) wake_up_process(child); break; - case PTRACE_DETACH: /* detach a process that was attached. */ - ret = ptrace_detach(child, data); - break; - case PTRACE_GETREGS: /* Get all gp regs from the child. */ for (i = 0; i < 19; i++) { tmp = get_reg(child, i); diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c index 578b48f47b9e..eaa618681159 100644 --- a/arch/m68k/mm/fault.c +++ b/arch/m68k/mm/fault.c @@ -188,7 +188,7 @@ out_of_memory: printk("VM: killing process %s\n", current->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); no_context: current->thread.signo = SIGBUS; diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index f943736541cb..235d4514e0a9 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -133,6 +133,7 @@ config LASAT select DMA_NONCOHERENT select SYS_HAS_EARLY_PRINTK select HW_HAS_PCI + select IRQ_CPU select PCI_GT64XXX_PCI0 select MIPS_NILE4 select R5000_CPU_SCACHE @@ -410,6 +411,7 @@ config SGI_IP32 select BOOT_ELF32 select DMA_NONCOHERENT select HW_HAS_PCI + select IRQ_CPU select R5000_CPU_SCACHE select RM7000_CPU_SCACHE select SYS_HAS_CPU_R5000 diff --git a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c index 7acfe9bf5fc3..98a4e34b0248 100644 --- a/arch/mips/au1000/common/au1xxx_irqmap.c +++ b/arch/mips/au1000/common/au1xxx_irqmap.c @@ -54,7 +54,7 @@ * Careful if you change match 2 request! * The interrupt handler is called directly from the low level dispatch code. */ -au1xxx_irq_map_t __initdata au1xxx_ic0_map[] = { +struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = { #if defined(CONFIG_SOC_AU1000) { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c index 461cf0139737..9d6ad43fded6 100644 --- a/arch/mips/au1000/common/dbdma.c +++ b/arch/mips/au1000/common/dbdma.c @@ -859,7 +859,7 @@ dbdma_interrupt(int irq, void *dev_id) intstat = dbdma_gptr->ddma_intstat; au_sync(); - chan_index = au_ffs(intstat) - 1; + chan_index = ffs(intstat); ctp = chan_tab_ptr[chan_index]; cp = ctp->chan_ptr; diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c index a6640b998c6e..c00f308fd505 100644 --- a/arch/mips/au1000/common/irq.c +++ b/arch/mips/au1000/common/irq.c @@ -26,39 +26,18 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/errno.h> +#include <linux/bitops.h> #include <linux/init.h> -#include <linux/irq.h> -#include <linux/kernel_stat.h> -#include <linux/module.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/types.h> +#include <linux/io.h> #include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/timex.h> -#include <linux/slab.h> -#include <linux/random.h> -#include <linux/delay.h> -#include <linux/bitops.h> +#include <linux/irq.h> -#include <asm/bootinfo.h> -#include <asm/io.h> #include <asm/mipsregs.h> -#include <asm/system.h> #include <asm/mach-au1x00/au1000.h> #ifdef CONFIG_MIPS_PB1000 #include <asm/mach-pb1x00/pb1000.h> #endif -#undef DEBUG_IRQ -#ifdef DEBUG_IRQ -/* note: prints function name for you */ -#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args) -#else -#define DPRINTK(fmt, args...) -#endif - #define EXT_INTC0_REQ0 2 /* IP 2 */ #define EXT_INTC0_REQ1 3 /* IP 3 */ #define EXT_INTC1_REQ0 4 /* IP 4 */ @@ -69,16 +48,98 @@ void (*board_init_irq)(void); static DEFINE_SPINLOCK(irq_lock); +#ifdef CONFIG_PM + +/* + * Save/restore the interrupt controller state. + * Called from the save/restore core registers as part of the + * au_sleep function in power.c.....maybe I should just pm_register() + * them instead? + */ +static unsigned int sleep_intctl_config0[2]; +static unsigned int sleep_intctl_config1[2]; +static unsigned int sleep_intctl_config2[2]; +static unsigned int sleep_intctl_src[2]; +static unsigned int sleep_intctl_assign[2]; +static unsigned int sleep_intctl_wake[2]; +static unsigned int sleep_intctl_mask[2]; + +void save_au1xxx_intctl(void) +{ + sleep_intctl_config0[0] = au_readl(IC0_CFG0RD); + sleep_intctl_config1[0] = au_readl(IC0_CFG1RD); + sleep_intctl_config2[0] = au_readl(IC0_CFG2RD); + sleep_intctl_src[0] = au_readl(IC0_SRCRD); + sleep_intctl_assign[0] = au_readl(IC0_ASSIGNRD); + sleep_intctl_wake[0] = au_readl(IC0_WAKERD); + sleep_intctl_mask[0] = au_readl(IC0_MASKRD); + + sleep_intctl_config0[1] = au_readl(IC1_CFG0RD); + sleep_intctl_config1[1] = au_readl(IC1_CFG1RD); + sleep_intctl_config2[1] = au_readl(IC1_CFG2RD); + sleep_intctl_src[1] = au_readl(IC1_SRCRD); + sleep_intctl_assign[1] = au_readl(IC1_ASSIGNRD); + sleep_intctl_wake[1] = au_readl(IC1_WAKERD); + sleep_intctl_mask[1] = au_readl(IC1_MASKRD); +} + +/* + * For most restore operations, we clear the entire register and + * then set the bits we found during the save. + */ +void restore_au1xxx_intctl(void) +{ + au_writel(0xffffffff, IC0_MASKCLR); au_sync(); + + au_writel(0xffffffff, IC0_CFG0CLR); au_sync(); + au_writel(sleep_intctl_config0[0], IC0_CFG0SET); au_sync(); + au_writel(0xffffffff, IC0_CFG1CLR); au_sync(); + au_writel(sleep_intctl_config1[0], IC0_CFG1SET); au_sync(); + au_writel(0xffffffff, IC0_CFG2CLR); au_sync(); + au_writel(sleep_intctl_config2[0], IC0_CFG2SET); au_sync(); + au_writel(0xffffffff, IC0_SRCCLR); au_sync(); + au_writel(sleep_intctl_src[0], IC0_SRCSET); au_sync(); + au_writel(0xffffffff, IC0_ASSIGNCLR); au_sync(); + au_writel(sleep_intctl_assign[0], IC0_ASSIGNSET); au_sync(); + au_writel(0xffffffff, IC0_WAKECLR); au_sync(); + au_writel(sleep_intctl_wake[0], IC0_WAKESET); au_sync(); + au_writel(0xffffffff, IC0_RISINGCLR); au_sync(); + au_writel(0xffffffff, IC0_FALLINGCLR); au_sync(); + au_writel(0x00000000, IC0_TESTBIT); au_sync(); + + au_writel(0xffffffff, IC1_MASKCLR); au_sync(); + + au_writel(0xffffffff, IC1_CFG0CLR); au_sync(); + au_writel(sleep_intctl_config0[1], IC1_CFG0SET); au_sync(); + au_writel(0xffffffff, IC1_CFG1CLR); au_sync(); + au_writel(sleep_intctl_config1[1], IC1_CFG1SET); au_sync(); + au_writel(0xffffffff, IC1_CFG2CLR); au_sync(); + au_writel(sleep_intctl_config2[1], IC1_CFG2SET); au_sync(); + au_writel(0xffffffff, IC1_SRCCLR); au_sync(); + au_writel(sleep_intctl_src[1], IC1_SRCSET); au_sync(); + au_writel(0xffffffff, IC1_ASSIGNCLR); au_sync(); + au_writel(sleep_intctl_assign[1], IC1_ASSIGNSET); au_sync(); + au_writel(0xffffffff, IC1_WAKECLR); au_sync(); + au_writel(sleep_intctl_wake[1], IC1_WAKESET); au_sync(); + au_writel(0xffffffff, IC1_RISINGCLR); au_sync(); + au_writel(0xffffffff, IC1_FALLINGCLR); au_sync(); + au_writel(0x00000000, IC1_TESTBIT); au_sync(); + + au_writel(sleep_intctl_mask[1], IC1_MASKSET); au_sync(); + + au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync(); +} +#endif /* CONFIG_PM */ + inline void local_enable_irq(unsigned int irq_nr) { if (irq_nr > AU1000_LAST_INTC0_INT) { - au_writel(1<<(irq_nr-32), IC1_MASKSET); - au_writel(1<<(irq_nr-32), IC1_WAKESET); - } - else { - au_writel(1<<irq_nr, IC0_MASKSET); - au_writel(1<<irq_nr, IC0_WAKESET); + au_writel(1 << (irq_nr - 32), IC1_MASKSET); + au_writel(1 << (irq_nr - 32), IC1_WAKESET); + } else { + au_writel(1 << irq_nr, IC0_MASKSET); + au_writel(1 << irq_nr, IC0_WAKESET); } au_sync(); } @@ -87,12 +148,11 @@ inline void local_enable_irq(unsigned int irq_nr) inline void local_disable_irq(unsigned int irq_nr) { if (irq_nr > AU1000_LAST_INTC0_INT) { - au_writel(1<<(irq_nr-32), IC1_MASKCLR); - au_writel(1<<(irq_nr-32), IC1_WAKECLR); - } - else { - au_writel(1<<irq_nr, IC0_MASKCLR); - au_writel(1<<irq_nr, IC0_WAKECLR); + au_writel(1 << (irq_nr - 32), IC1_MASKCLR); + au_writel(1 << (irq_nr - 32), IC1_WAKECLR); + } else { + au_writel(1 << irq_nr, IC0_MASKCLR); + au_writel(1 << irq_nr, IC0_WAKECLR); } au_sync(); } @@ -101,12 +161,11 @@ inline void local_disable_irq(unsigned int irq_nr) static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr) { if (irq_nr > AU1000_LAST_INTC0_INT) { - au_writel(1<<(irq_nr-32), IC1_RISINGCLR); - au_writel(1<<(irq_nr-32), IC1_MASKCLR); - } - else { - au_writel(1<<irq_nr, IC0_RISINGCLR); - au_writel(1<<irq_nr, IC0_MASKCLR); + au_writel(1 << (irq_nr - 32), IC1_RISINGCLR); + au_writel(1 << (irq_nr - 32), IC1_MASKCLR); + } else { + au_writel(1 << irq_nr, IC0_RISINGCLR); + au_writel(1 << irq_nr, IC0_MASKCLR); } au_sync(); } @@ -115,12 +174,11 @@ static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr) static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr) { if (irq_nr > AU1000_LAST_INTC0_INT) { - au_writel(1<<(irq_nr-32), IC1_FALLINGCLR); - au_writel(1<<(irq_nr-32), IC1_MASKCLR); - } - else { - au_writel(1<<irq_nr, IC0_FALLINGCLR); - au_writel(1<<irq_nr, IC0_MASKCLR); + au_writel(1 << (irq_nr - 32), IC1_FALLINGCLR); + au_writel(1 << (irq_nr - 32), IC1_MASKCLR); + } else { + au_writel(1 << irq_nr, IC0_FALLINGCLR); + au_writel(1 << irq_nr, IC0_MASKCLR); } au_sync(); } @@ -132,14 +190,13 @@ static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr) * both edges at once, or if we do, that we don't care. */ if (irq_nr > AU1000_LAST_INTC0_INT) { - au_writel(1<<(irq_nr-32), IC1_FALLINGCLR); - au_writel(1<<(irq_nr-32), IC1_RISINGCLR); - au_writel(1<<(irq_nr-32), IC1_MASKCLR); - } - else { - au_writel(1<<irq_nr, IC0_FALLINGCLR); - au_writel(1<<irq_nr, IC0_RISINGCLR); - au_writel(1<<irq_nr, IC0_MASKCLR); + au_writel(1 << (irq_nr - 32), IC1_FALLINGCLR); + au_writel(1 << (irq_nr - 32), IC1_RISINGCLR); + au_writel(1 << (irq_nr - 32), IC1_MASKCLR); + } else { + au_writel(1 << irq_nr, IC0_FALLINGCLR); + au_writel(1 << irq_nr, IC0_RISINGCLR); + au_writel(1 << irq_nr, IC0_MASKCLR); } au_sync(); } @@ -162,9 +219,9 @@ static inline void mask_and_ack_level_irq(unsigned int irq_nr) static void end_irq(unsigned int irq_nr) { - if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + if (!(irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS))) local_enable_irq(irq_nr); - } + #if defined(CONFIG_MIPS_PB1000) if (irq_nr == AU1000_GPIO_15) { au_writel(0x4000, PB1000_MDR); /* enable int */ @@ -181,15 +238,12 @@ unsigned long save_local_and_disable(int controller) spin_lock_irqsave(&irq_lock, flags); if (controller) { mask = au_readl(IC1_MASKSET); - for (i=32; i<64; i++) { + for (i = 32; i < 64; i++) local_disable_irq(i); - } - } - else { + } else { mask = au_readl(IC0_MASKSET); - for (i=0; i<32; i++) { + for (i = 0; i < 32; i++) local_disable_irq(i); - } } spin_unlock_irqrestore(&irq_lock, flags); @@ -202,10 +256,10 @@ void restore_local_and_enable(int controller, unsigned long mask) unsigned long flags, new_mask; spin_lock_irqsave(&irq_lock, flags); - for (i=0; i<32; i++) { - if (mask & (1<<i)) { + for (i = 0; i < 32; i++) { + if (mask & (1 << i)) { if (controller) - local_enable_irq(i+32); + local_enable_irq(i + 32); else local_enable_irq(i); } @@ -220,39 +274,39 @@ void restore_local_and_enable(int controller, unsigned long mask) static struct irq_chip rise_edge_irq_type = { - .name = "Au1000 Rise Edge", - .ack = mask_and_ack_rise_edge_irq, - .mask = local_disable_irq, - .mask_ack = mask_and_ack_rise_edge_irq, - .unmask = local_enable_irq, - .end = end_irq, + .name = "Au1000 Rise Edge", + .ack = mask_and_ack_rise_edge_irq, + .mask = local_disable_irq, + .mask_ack = mask_and_ack_rise_edge_irq, + .unmask = local_enable_irq, + .end = end_irq, }; static struct irq_chip fall_edge_irq_type = { - .name = "Au1000 Fall Edge", - .ack = mask_and_ack_fall_edge_irq, - .mask = local_disable_irq, - .mask_ack = mask_and_ack_fall_edge_irq, - .unmask = local_enable_irq, - .end = end_irq, + .name = "Au1000 Fall Edge", + .ack = mask_and_ack_fall_edge_irq, + .mask = local_disable_irq, + .mask_ack = mask_and_ack_fall_edge_irq, + .unmask = local_enable_irq, + .end = end_irq, }; static struct irq_chip either_edge_irq_type = { - .name = "Au1000 Rise or Fall Edge", - .ack = mask_and_ack_either_edge_irq, - .mask = local_disable_irq, - .mask_ack = mask_and_ack_either_edge_irq, - .unmask = local_enable_irq, - .end = end_irq, + .name = "Au1000 Rise or Fall Edge", + .ack = mask_and_ack_either_edge_irq, + .mask = local_disable_irq, + .mask_ack = mask_and_ack_either_edge_irq, + .unmask = local_enable_irq, + .end = end_irq, }; static struct irq_chip level_irq_type = { - .name = "Au1000 Level", - .ack = mask_and_ack_level_irq, - .mask = local_disable_irq, - .mask_ack = mask_and_ack_level_irq, - .unmask = local_enable_irq, - .end = end_irq, + .name = "Au1000 Level", + .ack = mask_and_ack_level_irq, + .mask = local_disable_irq, + .mask_ack = mask_and_ack_level_irq, + .unmask = local_enable_irq, + .end = end_irq, }; #ifdef CONFIG_PM @@ -263,7 +317,8 @@ void startup_match20_interrupt(irq_handler_t handler) static struct irqaction action; memset(&action, 0, sizeof(struct irqaction)); - /* This is a big problem.... since we didn't use request_irq + /* + * This is a big problem.... since we didn't use request_irq * when kernel/irq.c calls probe_irq_xxx this interrupt will * be probed for usage. This will end up disabling the device :( * Give it a bogus "action" pointer -- this will keep it from @@ -292,173 +347,112 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) /* Config2[n], Config1[n], Config0[n] */ if (irq_nr > AU1000_LAST_INTC0_INT) { switch (type) { - case INTC_INT_RISE_EDGE: /* 0:0:1 */ - au_writel(1<<(irq_nr-32), IC1_CFG2CLR); - au_writel(1<<(irq_nr-32), IC1_CFG1CLR); - au_writel(1<<(irq_nr-32), IC1_CFG0SET); - set_irq_chip(irq_nr, &rise_edge_irq_type); - break; - case INTC_INT_FALL_EDGE: /* 0:1:0 */ - au_writel(1<<(irq_nr-32), IC1_CFG2CLR); - au_writel(1<<(irq_nr-32), IC1_CFG1SET); - au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - set_irq_chip(irq_nr, &fall_edge_irq_type); - break; - case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ - au_writel(1<<(irq_nr-32), IC1_CFG2CLR); - au_writel(1<<(irq_nr-32), IC1_CFG1SET); - au_writel(1<<(irq_nr-32), IC1_CFG0SET); - set_irq_chip(irq_nr, &either_edge_irq_type); - break; - case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ - au_writel(1<<(irq_nr-32), IC1_CFG2SET); - au_writel(1<<(irq_nr-32), IC1_CFG1CLR); - au_writel(1<<(irq_nr-32), IC1_CFG0SET); - set_irq_chip(irq_nr, &level_irq_type); - break; - case INTC_INT_LOW_LEVEL: /* 1:1:0 */ - au_writel(1<<(irq_nr-32), IC1_CFG2SET); - au_writel(1<<(irq_nr-32), IC1_CFG1SET); - au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - set_irq_chip(irq_nr, &level_irq_type); - break; - case INTC_INT_DISABLED: /* 0:0:0 */ - au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - au_writel(1<<(irq_nr-32), IC1_CFG1CLR); - au_writel(1<<(irq_nr-32), IC1_CFG2CLR); - break; - default: /* disable the interrupt */ - printk("unexpected int type %d (irq %d)\n", type, irq_nr); - au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - au_writel(1<<(irq_nr-32), IC1_CFG1CLR); - au_writel(1<<(irq_nr-32), IC1_CFG2CLR); - return; + case INTC_INT_RISE_EDGE: /* 0:0:1 */ + au_writel(1 << (irq_nr - 32), IC1_CFG2CLR); + au_writel(1 << (irq_nr - 32), IC1_CFG1CLR); + au_writel(1 << (irq_nr - 32), IC1_CFG0SET); + set_irq_chip(irq_nr, &rise_edge_irq_type); + break; + case INTC_INT_FALL_EDGE: /* 0:1:0 */ + au_writel(1 << (irq_nr - 32), IC1_CFG2CLR); + au_writel(1 << (irq_nr - 32), IC1_CFG1SET); + au_writel(1 << (irq_nr - 32), IC1_CFG0CLR); + set_irq_chip(irq_nr, &fall_edge_irq_type); + break; + case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ + au_writel(1 << (irq_nr - 32), IC1_CFG2CLR); + au_writel(1 << (irq_nr - 32), IC1_CFG1SET); + au_writel(1 << (irq_nr - 32), IC1_CFG0SET); + set_irq_chip(irq_nr, &either_edge_irq_type); + break; + case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ + au_writel(1 << (irq_nr - 32), IC1_CFG2SET); + au_writel(1 << (irq_nr - 32), IC1_CFG1CLR); + au_writel(1 << (irq_nr - 32), IC1_CFG0SET); + set_irq_chip(irq_nr, &level_irq_type); + break; + case INTC_INT_LOW_LEVEL: /* 1:1:0 */ + au_writel(1 << (irq_nr - 32), IC1_CFG2SET); + au_writel(1 << (irq_nr - 32), IC1_CFG1SET); + au_writel(1 << (irq_nr - 32), IC1_CFG0CLR); + set_irq_chip(irq_nr, &level_irq_type); + break; + case INTC_INT_DISABLED: /* 0:0:0 */ + au_writel(1 << (irq_nr - 32), IC1_CFG0CLR); + au_writel(1 << (irq_nr - 32), IC1_CFG1CLR); + au_writel(1 << (irq_nr - 32), IC1_CFG2CLR); + break; + default: /* disable the interrupt */ + printk(KERN_WARNING "unexpected int type %d (irq %d)\n", + type, irq_nr); + au_writel(1 << (irq_nr - 32), IC1_CFG0CLR); + au_writel(1 << (irq_nr - 32), IC1_CFG1CLR); + au_writel(1 << (irq_nr - 32), IC1_CFG2CLR); + return; } if (int_req) /* assign to interrupt request 1 */ - au_writel(1<<(irq_nr-32), IC1_ASSIGNCLR); + au_writel(1 << (irq_nr - 32), IC1_ASSIGNCLR); else /* assign to interrupt request 0 */ - au_writel(1<<(irq_nr-32), IC1_ASSIGNSET); - au_writel(1<<(irq_nr-32), IC1_SRCSET); - au_writel(1<<(irq_nr-32), IC1_MASKCLR); - au_writel(1<<(irq_nr-32), IC1_WAKECLR); - } - else { + au_writel(1 << (irq_nr - 32), IC1_ASSIGNSET); + au_writel(1 << (irq_nr - 32), IC1_SRCSET); + au_writel(1 << (irq_nr - 32), IC1_MASKCLR); + au_writel(1 << (irq_nr - 32), IC1_WAKECLR); + } else { switch (type) { - case INTC_INT_RISE_EDGE: /* 0:0:1 */ - au_writel(1<<irq_nr, IC0_CFG2CLR); - au_writel(1<<irq_nr, IC0_CFG1CLR); - au_writel(1<<irq_nr, IC0_CFG0SET); - set_irq_chip(irq_nr, &rise_edge_irq_type); - break; - case INTC_INT_FALL_EDGE: /* 0:1:0 */ - au_writel(1<<irq_nr, IC0_CFG2CLR); - au_writel(1<<irq_nr, IC0_CFG1SET); - au_writel(1<<irq_nr, IC0_CFG0CLR); - set_irq_chip(irq_nr, &fall_edge_irq_type); - break; - case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ - au_writel(1<<irq_nr, IC0_CFG2CLR); - au_writel(1<<irq_nr, IC0_CFG1SET); - au_writel(1<<irq_nr, IC0_CFG0SET); - set_irq_chip(irq_nr, &either_edge_irq_type); - break; - case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ - au_writel(1<<irq_nr, IC0_CFG2SET); - au_writel(1<<irq_nr, IC0_CFG1CLR); - au_writel(1<<irq_nr, IC0_CFG0SET); - set_irq_chip(irq_nr, &level_irq_type); - break; - case INTC_INT_LOW_LEVEL: /* 1:1:0 */ - au_writel(1<<irq_nr, IC0_CFG2SET); - au_writel(1<<irq_nr, IC0_CFG1SET); - au_writel(1<<irq_nr, IC0_CFG0CLR); - set_irq_chip(irq_nr, &level_irq_type); - break; - case INTC_INT_DISABLED: /* 0:0:0 */ - au_writel(1<<irq_nr, IC0_CFG0CLR); - au_writel(1<<irq_nr, IC0_CFG1CLR); - au_writel(1<<irq_nr, IC0_CFG2CLR); - break; - default: /* disable the interrupt */ - printk("unexpected int type %d (irq %d)\n", type, irq_nr); - au_writel(1<<irq_nr, IC0_CFG0CLR); - au_writel(1<<irq_nr, IC0_CFG1CLR); - au_writel(1<<irq_nr, IC0_CFG2CLR); - return; + case INTC_INT_RISE_EDGE: /* 0:0:1 */ + au_writel(1 << irq_nr, IC0_CFG2CLR); + au_writel(1 << irq_nr, IC0_CFG1CLR); + au_writel(1 << irq_nr, IC0_CFG0SET); + set_irq_chip(irq_nr, &rise_edge_irq_type); + break; + case INTC_INT_FALL_EDGE: /* 0:1:0 */ + au_writel(1 << irq_nr, IC0_CFG2CLR); + au_writel(1 << irq_nr, IC0_CFG1SET); + au_writel(1 << irq_nr, IC0_CFG0CLR); + set_irq_chip(irq_nr, &fall_edge_irq_type); + break; + case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ + au_writel(1 << irq_nr, IC0_CFG2CLR); + au_writel(1 << irq_nr, IC0_CFG1SET); + au_writel(1 << irq_nr, IC0_CFG0SET); + set_irq_chip(irq_nr, &either_edge_irq_type); + break; + case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ + au_writel(1 << irq_nr, IC0_CFG2SET); + au_writel(1 << irq_nr, IC0_CFG1CLR); + au_writel(1 << irq_nr, IC0_CFG0SET); + set_irq_chip(irq_nr, &level_irq_type); + break; + case INTC_INT_LOW_LEVEL: /* 1:1:0 */ + au_writel(1 << irq_nr, IC0_CFG2SET); + au_writel(1 << irq_nr, IC0_CFG1SET); + au_writel(1 << irq_nr, IC0_CFG0CLR); + set_irq_chip(irq_nr, &level_irq_type); + break; + case INTC_INT_DISABLED: /* 0:0:0 */ + au_writel(1 << irq_nr, IC0_CFG0CLR); + au_writel(1 << irq_nr, IC0_CFG1CLR); + au_writel(1 << irq_nr, IC0_CFG2CLR); + break; + default: /* disable the interrupt */ + printk(KERN_WARNING "unexpected int type %d (irq %d)\n", + type, irq_nr); + au_writel(1 << irq_nr, IC0_CFG0CLR); + au_writel(1 << irq_nr, IC0_CFG1CLR); + au_writel(1 << irq_nr, IC0_CFG2CLR); + return; } if (int_req) /* assign to interrupt request 1 */ - au_writel(1<<irq_nr, IC0_ASSIGNCLR); + au_writel(1 << irq_nr, IC0_ASSIGNCLR); else /* assign to interrupt request 0 */ - au_writel(1<<irq_nr, IC0_ASSIGNSET); - au_writel(1<<irq_nr, IC0_SRCSET); - au_writel(1<<irq_nr, IC0_MASKCLR); - au_writel(1<<irq_nr, IC0_WAKECLR); + au_writel(1 << irq_nr, IC0_ASSIGNSET); + au_writel(1 << irq_nr, IC0_SRCSET); + au_writel(1 << irq_nr, IC0_MASKCLR); + au_writel(1 << irq_nr, IC0_WAKECLR); } au_sync(); } - -void __init arch_init_irq(void) -{ - int i; - unsigned long cp0_status; - au1xxx_irq_map_t *imp; - extern au1xxx_irq_map_t au1xxx_irq_map[]; - extern au1xxx_irq_map_t au1xxx_ic0_map[]; - extern int au1xxx_nr_irqs; - extern int au1xxx_ic0_nr_irqs; - - cp0_status = read_c0_status(); - - /* Initialize interrupt controllers to a safe state. - */ - au_writel(0xffffffff, IC0_CFG0CLR); - au_writel(0xffffffff, IC0_CFG1CLR); - au_writel(0xffffffff, IC0_CFG2CLR); - au_writel(0xffffffff, IC0_MASKCLR); - au_writel(0xffffffff, IC0_ASSIGNSET); - au_writel(0xffffffff, IC0_WAKECLR); - au_writel(0xffffffff, IC0_SRCSET); - au_writel(0xffffffff, IC0_FALLINGCLR); - au_writel(0xffffffff, IC0_RISINGCLR); - au_writel(0x00000000, IC0_TESTBIT); - - au_writel(0xffffffff, IC1_CFG0CLR); - au_writel(0xffffffff, IC1_CFG1CLR); - au_writel(0xffffffff, IC1_CFG2CLR); - au_writel(0xffffffff, IC1_MASKCLR); - au_writel(0xffffffff, IC1_ASSIGNSET); - au_writel(0xffffffff, IC1_WAKECLR); - au_writel(0xffffffff, IC1_SRCSET); - au_writel(0xffffffff, IC1_FALLINGCLR); - au_writel(0xffffffff, IC1_RISINGCLR); - au_writel(0x00000000, IC1_TESTBIT); - - /* Initialize IC0, which is fixed per processor. - */ - imp = au1xxx_ic0_map; - for (i=0; i<au1xxx_ic0_nr_irqs; i++) { - setup_local_irq(imp->im_irq, imp->im_type, imp->im_request); - imp++; - } - - /* Now set up the irq mapping for the board. - */ - imp = au1xxx_irq_map; - for (i=0; i<au1xxx_nr_irqs; i++) { - setup_local_irq(imp->im_irq, imp->im_type, imp->im_request); - imp++; - } - - set_c0_status(ALLINTS); - - /* Board specific IRQ initialization. - */ - if (board_init_irq) - (*board_init_irq)(); -} - - /* * Interrupts are nested. Even if an interrupt handler is registered * as "fast", we might get another interrupt before we return from @@ -468,26 +462,27 @@ void __init arch_init_irq(void) static void intc0_req0_irqdispatch(void) { int irq = 0; - static unsigned long intc0_req0 = 0; + static unsigned long intc0_req0; intc0_req0 |= au_readl(IC0_REQ0INT); if (!intc0_req0) return; + #ifdef AU1000_USB_DEV_REQ_INT /* * Because of the tight timing of SETUP token to reply * transactions, the USB devices-side packet complete * interrupt needs the highest priority. */ - if ((intc0_req0 & (1<<AU1000_USB_DEV_REQ_INT))) { - intc0_req0 &= ~(1<<AU1000_USB_DEV_REQ_INT); + if ((intc0_req0 & (1 << AU1000_USB_DEV_REQ_INT))) { + intc0_req0 &= ~(1 << AU1000_USB_DEV_REQ_INT); do_IRQ(AU1000_USB_DEV_REQ_INT); return; } #endif - irq = au_ffs(intc0_req0) - 1; - intc0_req0 &= ~(1<<irq); + irq = ffs(intc0_req0); + intc0_req0 &= ~(1 << irq); do_IRQ(irq); } @@ -495,15 +490,15 @@ static void intc0_req0_irqdispatch(void) static void intc0_req1_irqdispatch(void) { int irq = 0; - static unsigned long intc0_req1 = 0; + static unsigned long intc0_req1; intc0_req1 |= au_readl(IC0_REQ1INT); if (!intc0_req1) return; - irq = au_ffs(intc0_req1) - 1; - intc0_req1 &= ~(1<<irq); + irq = ffs(intc0_req1); + intc0_req1 &= ~(1 << irq); do_IRQ(irq); } @@ -515,15 +510,15 @@ static void intc0_req1_irqdispatch(void) static void intc1_req0_irqdispatch(void) { int irq = 0; - static unsigned long intc1_req0 = 0; + static unsigned long intc1_req0; intc1_req0 |= au_readl(IC1_REQ0INT); if (!intc1_req0) return; - irq = au_ffs(intc1_req0) - 1; - intc1_req0 &= ~(1<<irq); + irq = ffs(intc1_req0); + intc1_req0 &= ~(1 << irq); irq += 32; do_IRQ(irq); } @@ -532,102 +527,19 @@ static void intc1_req0_irqdispatch(void) static void intc1_req1_irqdispatch(void) { int irq = 0; - static unsigned long intc1_req1 = 0; + static unsigned long intc1_req1; intc1_req1 |= au_readl(IC1_REQ1INT); if (!intc1_req1) return; - irq = au_ffs(intc1_req1) - 1; - intc1_req1 &= ~(1<<irq); + irq = ffs(intc1_req1); + intc1_req1 &= ~(1 << irq); irq += 32; do_IRQ(irq); } -#ifdef CONFIG_PM - -/* Save/restore the interrupt controller state. - * Called from the save/restore core registers as part of the - * au_sleep function in power.c.....maybe I should just pm_register() - * them instead? - */ -static unsigned int sleep_intctl_config0[2]; -static unsigned int sleep_intctl_config1[2]; -static unsigned int sleep_intctl_config2[2]; -static unsigned int sleep_intctl_src[2]; -static unsigned int sleep_intctl_assign[2]; -static unsigned int sleep_intctl_wake[2]; -static unsigned int sleep_intctl_mask[2]; - -void -save_au1xxx_intctl(void) -{ - sleep_intctl_config0[0] = au_readl(IC0_CFG0RD); - sleep_intctl_config1[0] = au_readl(IC0_CFG1RD); - sleep_intctl_config2[0] = au_readl(IC0_CFG2RD); - sleep_intctl_src[0] = au_readl(IC0_SRCRD); - sleep_intctl_assign[0] = au_readl(IC0_ASSIGNRD); - sleep_intctl_wake[0] = au_readl(IC0_WAKERD); - sleep_intctl_mask[0] = au_readl(IC0_MASKRD); - - sleep_intctl_config0[1] = au_readl(IC1_CFG0RD); - sleep_intctl_config1[1] = au_readl(IC1_CFG1RD); - sleep_intctl_config2[1] = au_readl(IC1_CFG2RD); - sleep_intctl_src[1] = au_readl(IC1_SRCRD); - sleep_intctl_assign[1] = au_readl(IC1_ASSIGNRD); - sleep_intctl_wake[1] = au_readl(IC1_WAKERD); - sleep_intctl_mask[1] = au_readl(IC1_MASKRD); -} - -/* For most restore operations, we clear the entire register and - * then set the bits we found during the save. - */ -void -restore_au1xxx_intctl(void) -{ - au_writel(0xffffffff, IC0_MASKCLR); au_sync(); - - au_writel(0xffffffff, IC0_CFG0CLR); au_sync(); - au_writel(sleep_intctl_config0[0], IC0_CFG0SET); au_sync(); - au_writel(0xffffffff, IC0_CFG1CLR); au_sync(); - au_writel(sleep_intctl_config1[0], IC0_CFG1SET); au_sync(); - au_writel(0xffffffff, IC0_CFG2CLR); au_sync(); - au_writel(sleep_intctl_config2[0], IC0_CFG2SET); au_sync(); - au_writel(0xffffffff, IC0_SRCCLR); au_sync(); - au_writel(sleep_intctl_src[0], IC0_SRCSET); au_sync(); - au_writel(0xffffffff, IC0_ASSIGNCLR); au_sync(); - au_writel(sleep_intctl_assign[0], IC0_ASSIGNSET); au_sync(); - au_writel(0xffffffff, IC0_WAKECLR); au_sync(); - au_writel(sleep_intctl_wake[0], IC0_WAKESET); au_sync(); - au_writel(0xffffffff, IC0_RISINGCLR); au_sync(); - au_writel(0xffffffff, IC0_FALLINGCLR); au_sync(); - au_writel(0x00000000, IC0_TESTBIT); au_sync(); - - au_writel(0xffffffff, IC1_MASKCLR); au_sync(); - - au_writel(0xffffffff, IC1_CFG0CLR); au_sync(); - au_writel(sleep_intctl_config0[1], IC1_CFG0SET); au_sync(); - au_writel(0xffffffff, IC1_CFG1CLR); au_sync(); - au_writel(sleep_intctl_config1[1], IC1_CFG1SET); au_sync(); - au_writel(0xffffffff, IC1_CFG2CLR); au_sync(); - au_writel(sleep_intctl_config2[1], IC1_CFG2SET); au_sync(); - au_writel(0xffffffff, IC1_SRCCLR); au_sync(); - au_writel(sleep_intctl_src[1], IC1_SRCSET); au_sync(); - au_writel(0xffffffff, IC1_ASSIGNCLR); au_sync(); - au_writel(sleep_intctl_assign[1], IC1_ASSIGNSET); au_sync(); - au_writel(0xffffffff, IC1_WAKECLR); au_sync(); - au_writel(sleep_intctl_wake[1], IC1_WAKESET); au_sync(); - au_writel(0xffffffff, IC1_RISINGCLR); au_sync(); - au_writel(0xffffffff, IC1_FALLINGCLR); au_sync(); - au_writel(0x00000000, IC1_TESTBIT); au_sync(); - - au_writel(sleep_intctl_mask[1], IC1_MASKSET); au_sync(); - - au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync(); -} -#endif /* CONFIG_PM */ - asmlinkage void plat_irq_dispatch(void) { unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; @@ -645,3 +557,63 @@ asmlinkage void plat_irq_dispatch(void) else spurious_interrupt(); } + +void __init arch_init_irq(void) +{ + int i; + unsigned long cp0_status; + struct au1xxx_irqmap *imp; + extern struct au1xxx_irqmap au1xxx_irq_map[]; + extern struct au1xxx_irqmap au1xxx_ic0_map[]; + extern int au1xxx_nr_irqs; + extern int au1xxx_ic0_nr_irqs; + + cp0_status = read_c0_status(); + + /* Initialize interrupt controllers to a safe state. + */ + au_writel(0xffffffff, IC0_CFG0CLR); + au_writel(0xffffffff, IC0_CFG1CLR); + au_writel(0xffffffff, IC0_CFG2CLR); + au_writel(0xffffffff, IC0_MASKCLR); + au_writel(0xffffffff, IC0_ASSIGNSET); + au_writel(0xffffffff, IC0_WAKECLR); + au_writel(0xffffffff, IC0_SRCSET); + au_writel(0xffffffff, IC0_FALLINGCLR); + au_writel(0xffffffff, IC0_RISINGCLR); + au_writel(0x00000000, IC0_TESTBIT); + + au_writel(0xffffffff, IC1_CFG0CLR); + au_writel(0xffffffff, IC1_CFG1CLR); + au_writel(0xffffffff, IC1_CFG2CLR); + au_writel(0xffffffff, IC1_MASKCLR); + au_writel(0xffffffff, IC1_ASSIGNSET); + au_writel(0xffffffff, IC1_WAKECLR); + au_writel(0xffffffff, IC1_SRCSET); + au_writel(0xffffffff, IC1_FALLINGCLR); + au_writel(0xffffffff, IC1_RISINGCLR); + au_writel(0x00000000, IC1_TESTBIT); + + /* Initialize IC0, which is fixed per processor. + */ + imp = au1xxx_ic0_map; + for (i = 0; i < au1xxx_ic0_nr_irqs; i++) { + setup_local_irq(imp->im_irq, imp->im_type, imp->im_request); + imp++; + } + + /* Now set up the irq mapping for the board. + */ + imp = au1xxx_irq_map; + for (i = 0; i < au1xxx_nr_irqs; i++) { + setup_local_irq(imp->im_irq, imp->im_type, imp->im_request); + imp++; + } + + set_c0_status(ALLINTS); + + /* Board specific IRQ initialization. + */ + if (board_init_irq) + (*board_init_irq)(); +} diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c index a8637cdb5b4b..90d70695aa60 100644 --- a/arch/mips/au1000/common/prom.c +++ b/arch/mips/au1000/common/prom.c @@ -33,7 +33,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> @@ -41,18 +40,16 @@ #include <asm/bootinfo.h> -/* #define DEBUG_CMDLINE */ - -extern int prom_argc; -extern char **prom_argv, **prom_envp; - +int prom_argc; +char **prom_argv; +char **prom_envp; char * __init_or_module prom_getcmdline(void) { return &(arcs_cmdline[0]); } -void prom_init_cmdline(void) +void prom_init_cmdline(void) { char *cp; int actr; @@ -61,7 +58,7 @@ void prom_init_cmdline(void) cp = &(arcs_cmdline[0]); while(actr < prom_argc) { - strcpy(cp, prom_argv[actr]); + strcpy(cp, prom_argv[actr]); cp += strlen(prom_argv[actr]); *cp++ = ' '; actr++; @@ -70,10 +67,8 @@ void prom_init_cmdline(void) --cp; if (prom_argc > 1) *cp = '\0'; - } - char *prom_getenv(char *envname) { /* @@ -95,21 +90,23 @@ char *prom_getenv(char *envname) } env++; } + return NULL; } -inline unsigned char str2hexnum(unsigned char c) +static inline unsigned char str2hexnum(unsigned char c) { - if(c >= '0' && c <= '9') + if (c >= '0' && c <= '9') return c - '0'; - if(c >= 'a' && c <= 'f') + if (c >= 'a' && c <= 'f') return c - 'a' + 10; - if(c >= 'A' && c <= 'F') + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + return 0; /* foo */ } -inline void str2eaddr(unsigned char *ea, unsigned char *str) +static inline void str2eaddr(unsigned char *ea, unsigned char *str) { int i; @@ -124,35 +121,29 @@ inline void str2eaddr(unsigned char *ea, unsigned char *str) } } -int get_ethernet_addr(char *ethernet_addr) +int prom_get_ethernet_addr(char *ethernet_addr) { - char *ethaddr_str; + char *ethaddr_str; + char *argptr; - ethaddr_str = prom_getenv("ethaddr"); + /* Check the environment variables first */ + ethaddr_str = prom_getenv("ethaddr"); if (!ethaddr_str) { - printk("ethaddr not set in boot prom\n"); - return -1; - } - str2eaddr(ethernet_addr, ethaddr_str); - -#if 0 - { - int i; + /* Check command line */ + argptr = prom_getcmdline(); + ethaddr_str = strstr(argptr, "ethaddr="); + if (!ethaddr_str) + return -1; - printk("get_ethernet_addr: "); - for (i=0; i<5; i++) - printk("%02x:", (unsigned char)*(ethernet_addr+i)); - printk("%02x\n", *(ethernet_addr+i)); + ethaddr_str += strlen("ethaddr="); } -#endif + + str2eaddr(ethernet_addr, ethaddr_str); return 0; } +EXPORT_SYMBOL(prom_get_ethernet_addr); void __init prom_free_prom_memory(void) { } - -EXPORT_SYMBOL(prom_getcmdline); -EXPORT_SYMBOL(get_ethernet_addr); -EXPORT_SYMBOL(str2eaddr); diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c index b212c0726125..a90d425d4651 100644 --- a/arch/mips/au1000/common/setup.c +++ b/arch/mips/au1000/common/setup.c @@ -40,10 +40,11 @@ #include <asm/mipsregs.h> #include <asm/reboot.h> #include <asm/pgtable.h> -#include <asm/mach-au1x00/au1000.h> #include <asm/time.h> -extern char * prom_getcmdline(void); +#include <au1000.h> +#include <prom.h> + extern void __init board_setup(void); extern void au1000_restart(char *); extern void au1000_halt(void); diff --git a/arch/mips/au1000/db1x00/init.c b/arch/mips/au1000/db1x00/init.c index 4d7bcfc8cf73..43298fd9459c 100644 --- a/arch/mips/au1000/db1x00/init.c +++ b/arch/mips/au1000/db1x00/init.c @@ -31,15 +31,13 @@ #include <linux/mm.h> #include <linux/sched.h> #include <linux/bootmem.h> -#include <asm/addrspace.h> -#include <asm/bootinfo.h> #include <linux/string.h> #include <linux/kernel.h> -int prom_argc; -char **prom_argv, **prom_envp; -extern void __init prom_init_cmdline(void); -extern char *prom_getenv(char *envname); +#include <asm/addrspace.h> +#include <asm/bootinfo.h> + +#include <prom.h> const char *get_system_type(void) { diff --git a/arch/mips/au1000/db1x00/irqmap.c b/arch/mips/au1000/db1x00/irqmap.c index 3e5729145c2b..09cea03411b0 100644 --- a/arch/mips/au1000/db1x00/irqmap.c +++ b/arch/mips/au1000/db1x00/irqmap.c @@ -79,7 +79,7 @@ char irq_tab_alchemy[][5] __initdata = { #endif -au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { +struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { #ifndef CONFIG_MIPS_MIRAGE #ifdef CONFIG_MIPS_DB1550 diff --git a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c index 2aa7b2ed6a8c..cdeae3212a2d 100644 --- a/arch/mips/au1000/mtx-1/init.c +++ b/arch/mips/au1000/mtx-1/init.c @@ -34,13 +34,11 @@ #include <linux/init.h> #include <linux/mm.h> #include <linux/bootmem.h> + #include <asm/addrspace.h> #include <asm/bootinfo.h> -int prom_argc; -char **prom_argv, **prom_envp; -extern void __init prom_init_cmdline(void); -extern char *prom_getenv(char *envname); +#include <prom.h> const char *get_system_type(void) { diff --git a/arch/mips/au1000/mtx-1/irqmap.c b/arch/mips/au1000/mtx-1/irqmap.c index a4fa0f227e42..49c612aeddcf 100644 --- a/arch/mips/au1000/mtx-1/irqmap.c +++ b/arch/mips/au1000/mtx-1/irqmap.c @@ -58,7 +58,7 @@ char irq_tab_alchemy[][5] __initdata = { [7] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 07 - AdapterD-Slot1 (bottom) */ }; -au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { +struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, diff --git a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c index 4535f7208e18..ddccaf6997d0 100644 --- a/arch/mips/au1000/pb1000/init.c +++ b/arch/mips/au1000/pb1000/init.c @@ -30,15 +30,13 @@ #include <linux/mm.h> #include <linux/sched.h> #include <linux/bootmem.h> -#include <asm/addrspace.h> -#include <asm/bootinfo.h> #include <linux/string.h> #include <linux/kernel.h> -int prom_argc; -char **prom_argv, **prom_envp; -extern void __init prom_init_cmdline(void); -extern char *prom_getenv(char *envname); +#include <asm/addrspace.h> +#include <asm/bootinfo.h> + +#include <prom.h> const char *get_system_type(void) { diff --git a/arch/mips/au1000/pb1000/irqmap.c b/arch/mips/au1000/pb1000/irqmap.c index 156500ba467f..88e354508204 100644 --- a/arch/mips/au1000/pb1000/irqmap.c +++ b/arch/mips/au1000/pb1000/irqmap.c @@ -47,7 +47,7 @@ #include <asm/system.h> #include <asm/mach-au1x00/au1000.h> -au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { +struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { { AU1000_GPIO_15, INTC_INT_LOW_LEVEL, 0 }, }; diff --git a/arch/mips/au1000/pb1100/init.c b/arch/mips/au1000/pb1100/init.c index 7ba6852de7cd..c93fd39b4aba 100644 --- a/arch/mips/au1000/pb1100/init.c +++ b/arch/mips/au1000/pb1100/init.c @@ -31,15 +31,13 @@ #include <linux/mm.h> #include <linux/sched.h> #include <linux/bootmem.h> -#include <asm/addrspace.h> -#include <asm/bootinfo.h> #include <linux/string.h> #include <linux/kernel.h> -int prom_argc; -char **prom_argv, **prom_envp; -extern void __init prom_init_cmdline(void); -extern char *prom_getenv(char *envname); +#include <asm/addrspace.h> +#include <asm/bootinfo.h> + +#include <prom.h> const char *get_system_type(void) { diff --git a/arch/mips/au1000/pb1100/irqmap.c b/arch/mips/au1000/pb1100/irqmap.c index d986916221b7..880456bf8c11 100644 --- a/arch/mips/au1000/pb1100/irqmap.c +++ b/arch/mips/au1000/pb1100/irqmap.c @@ -47,7 +47,7 @@ #include <asm/system.h> #include <asm/mach-au1x00/au1000.h> -au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { +struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { { AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted# { AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG# { AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ# diff --git a/arch/mips/au1000/pb1200/board_setup.c b/arch/mips/au1000/pb1200/board_setup.c index 2122515f79d7..5dbc9868f598 100644 --- a/arch/mips/au1000/pb1200/board_setup.c +++ b/arch/mips/au1000/pb1200/board_setup.c @@ -41,8 +41,10 @@ #include <asm/mipsregs.h> #include <asm/reboot.h> #include <asm/pgtable.h> -#include <asm/mach-au1x00/au1000.h> -#include <asm/mach-au1x00/au1xxx_dbdma.h> + +#include <au1000.h> +#include <au1xxx_dbdma.h> +#include <prom.h> #ifdef CONFIG_MIPS_PB1200 #include <asm/mach-pb1x00/pb1200.h> diff --git a/arch/mips/au1000/pb1200/init.c b/arch/mips/au1000/pb1200/init.c index 5a70029d5388..c251570749ee 100644 --- a/arch/mips/au1000/pb1200/init.c +++ b/arch/mips/au1000/pb1200/init.c @@ -31,15 +31,13 @@ #include <linux/mm.h> #include <linux/sched.h> #include <linux/bootmem.h> -#include <asm/addrspace.h> -#include <asm/bootinfo.h> #include <linux/string.h> #include <linux/kernel.h> -int prom_argc; -char **prom_argv, **prom_envp; -extern void __init prom_init_cmdline(void); -extern char *prom_getenv(char *envname); +#include <asm/addrspace.h> +#include <asm/bootinfo.h> + +#include <prom.h> const char *get_system_type(void) { diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c index 7c708db04a88..3bee274445f5 100644 --- a/arch/mips/au1000/pb1200/irqmap.c +++ b/arch/mips/au1000/pb1200/irqmap.c @@ -54,7 +54,7 @@ #define PB1200_INT_END DB1200_INT_END #endif -au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { +struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { { AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, // This is exteranl interrupt cascade }; @@ -74,7 +74,7 @@ irqreturn_t pb1200_cascade_handler( int irq, void *dev_id) bcsr->int_status = bisr; for( ; bisr; bisr &= (bisr-1) ) { - extirq_nr = (PB1200_INT_BEGIN-1) + au_ffs(bisr); + extirq_nr = PB1200_INT_BEGIN + au_ffs(bisr); /* Ack and dispatch IRQ */ do_IRQ(extirq_nr); } diff --git a/arch/mips/au1000/pb1500/init.c b/arch/mips/au1000/pb1500/init.c index e58a9d6c5021..507d4b204161 100644 --- a/arch/mips/au1000/pb1500/init.c +++ b/arch/mips/au1000/pb1500/init.c @@ -31,15 +31,13 @@ #include <linux/mm.h> #include <linux/sched.h> #include <linux/bootmem.h> -#include <asm/addrspace.h> -#include <asm/bootinfo.h> #include <linux/string.h> #include <linux/kernel.h> -int prom_argc; -char **prom_argv, **prom_envp; -extern void __init prom_init_cmdline(void); -extern char *prom_getenv(char *envname); +#include <asm/addrspace.h> +#include <asm/bootinfo.h> + +#include <prom.h> const char *get_system_type(void) { diff --git a/arch/mips/au1000/pb1500/irqmap.c b/arch/mips/au1000/pb1500/irqmap.c index 409d1612bb63..810f695e24bb 100644 --- a/arch/mips/au1000/pb1500/irqmap.c +++ b/arch/mips/au1000/pb1500/irqmap.c @@ -52,7 +52,7 @@ char irq_tab_alchemy[][5] __initdata = { [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */ }; -au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { +struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, diff --git a/arch/mips/au1000/pb1550/init.c b/arch/mips/au1000/pb1550/init.c index fad53bf5aad1..b03eee601e36 100644 --- a/arch/mips/au1000/pb1550/init.c +++ b/arch/mips/au1000/pb1550/init.c @@ -31,15 +31,13 @@ #include <linux/mm.h> #include <linux/sched.h> #include <linux/bootmem.h> -#include <asm/addrspace.h> -#include <asm/bootinfo.h> #include <linux/string.h> #include <linux/kernel.h> -int prom_argc; -char **prom_argv, **prom_envp; -extern void __init prom_init_cmdline(void); -extern char *prom_getenv(char *envname); +#include <asm/addrspace.h> +#include <asm/bootinfo.h> + +#include <prom.h> const char *get_system_type(void) { diff --git a/arch/mips/au1000/pb1550/irqmap.c b/arch/mips/au1000/pb1550/irqmap.c index 24a9d186cf5a..56becab28e5d 100644 --- a/arch/mips/au1000/pb1550/irqmap.c +++ b/arch/mips/au1000/pb1550/irqmap.c @@ -52,7 +52,7 @@ char irq_tab_alchemy[][5] __initdata = { [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */ }; -au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { +struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, }; diff --git a/arch/mips/au1000/xxs1500/init.c b/arch/mips/au1000/xxs1500/init.c index 9f839c36f69e..6532939f377a 100644 --- a/arch/mips/au1000/xxs1500/init.c +++ b/arch/mips/au1000/xxs1500/init.c @@ -30,15 +30,13 @@ #include <linux/mm.h> #include <linux/sched.h> #include <linux/bootmem.h> -#include <asm/addrspace.h> -#include <asm/bootinfo.h> #include <linux/string.h> #include <linux/kernel.h> -int prom_argc; -char **prom_argv, **prom_envp; -extern void __init prom_init_cmdline(void); -extern char *prom_getenv(char *envname); +#include <asm/addrspace.h> +#include <asm/bootinfo.h> + +#include <prom.h> const char *get_system_type(void) { diff --git a/arch/mips/au1000/xxs1500/irqmap.c b/arch/mips/au1000/xxs1500/irqmap.c index 3844c6429e27..389349295d70 100644 --- a/arch/mips/au1000/xxs1500/irqmap.c +++ b/arch/mips/au1000/xxs1500/irqmap.c @@ -47,7 +47,7 @@ #include <asm/system.h> #include <asm/au1000.h> -au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { +struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c index 7f14f70a1b88..0c7aee1682cd 100644 --- a/arch/mips/jmr3927/rbhma3100/setup.c +++ b/arch/mips/jmr3927/rbhma3100/setup.c @@ -425,7 +425,7 @@ static int __init jmr3927_rtc_init(void) .flags = IORESOURCE_MEM, }; struct platform_device *dev; - dev = platform_device_register_simple("ds1742", -1, &res, 1); + dev = platform_device_register_simple("rtc-ds1742", -1, &res, 1); return IS_ERR(dev) ? PTR_ERR(dev) : 0; } device_initcall(jmr3927_rtc_init); diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 58aa6fec1146..999f7853de26 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -435,10 +435,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) wake_up_process(child); break; - case PTRACE_DETACH: /* detach a process that was attached. */ - ret = ptrace_detach(child, data); - break; - case PTRACE_GET_THREAD_AREA: ret = put_user(task_thread_info(child)->tp_value, (unsigned long __user *) data); diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 432f2e376aea..63989e9df4f9 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -379,7 +379,7 @@ void flush_tlb_mm(struct mm_struct *mm) unsigned int cpu; cpu_clear(smp_processor_id(), mask); - for_each_online_cpu(cpu) + for_each_cpu_mask(cpu, mask) if (cpu_context(cpu, mm)) cpu_context(cpu, mm) = 0; } @@ -419,7 +419,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned l unsigned int cpu; cpu_clear(smp_processor_id(), mask); - for_each_online_cpu(cpu) + for_each_cpu_mask(cpu, mask) if (cpu_context(cpu, mm)) cpu_context(cpu, mm) = 0; } @@ -466,7 +466,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) unsigned int cpu; cpu_clear(smp_processor_id(), mask); - for_each_online_cpu(cpu) + for_each_cpu_mask(cpu, mask) if (cpu_context(cpu, vma->vm_mm)) cpu_context(cpu, vma->vm_mm) = 0; } diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 5892491b40eb..05b365167a09 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -421,7 +421,7 @@ void __cpuinit mips_clockevent_init(void) cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); cd->shift = 32; cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); - cd->min_delta_ns = clockevent_delta2ns(0x30, cd); + cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->rating = 300; cd->irq = irq; diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 632bce1bf420..9c0c478d71ac 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -104,7 +104,7 @@ static int __init set_raw_show_trace(char *str) __setup("raw_show_trace", set_raw_show_trace); #endif -static void show_backtrace(struct task_struct *task, struct pt_regs *regs) +static void show_backtrace(struct task_struct *task, const struct pt_regs *regs) { unsigned long sp = regs->regs[29]; unsigned long ra = regs->regs[31]; @@ -126,7 +126,8 @@ static void show_backtrace(struct task_struct *task, struct pt_regs *regs) * This routine abuses get_user()/put_user() to reference pointers * with at least a bit of error checking ... */ -static void show_stacktrace(struct task_struct *task, struct pt_regs *regs) +static void show_stacktrace(struct task_struct *task, + const struct pt_regs *regs) { const int field = 2 * sizeof(unsigned long); long stackdata; @@ -203,7 +204,7 @@ static void show_code(unsigned int __user *pc) } } -void show_regs(struct pt_regs *regs) +static void __show_regs(const struct pt_regs *regs) { const int field = 2 * sizeof(unsigned long); unsigned int cause = regs->cp0_cause; @@ -299,9 +300,17 @@ void show_regs(struct pt_regs *regs) cpu_name_string()); } -void show_registers(struct pt_regs *regs) +/* + * FIXME: really the generic show_regs should take a const pointer argument. + */ +void show_regs(struct pt_regs *regs) +{ + __show_regs((struct pt_regs *)regs); +} + +void show_registers(const struct pt_regs *regs) { - show_regs(regs); + __show_regs(regs); print_modules(); printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n", current->comm, current->pid, current_thread_info(), current); @@ -312,7 +321,7 @@ void show_registers(struct pt_regs *regs) static DEFINE_SPINLOCK(die_lock); -void __noreturn die(const char * str, struct pt_regs * regs) +void __noreturn die(const char * str, const struct pt_regs * regs) { static int die_counter; #ifdef CONFIG_MIPS_MT_SMTC diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 84f9a4cc6f2f..2781cff1485e 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -5,6 +5,10 @@ #define mips mips OUTPUT_ARCH(mips) ENTRY(kernel_entry) +PHDRS { + text PT_LOAD FLAGS(7); /* RWX */ + note PT_NOTE FLAGS(4); /* R__ */ +} jiffies = JIFFIES; SECTIONS @@ -22,7 +26,6 @@ SECTIONS */ /* . = 0xa800000000300000; */ - /* . = 0xa800000000300000; */ . = 0xffffffff80300000; #endif . = LOADADDR; @@ -32,9 +35,10 @@ SECTIONS TEXT_TEXT SCHED_TEXT LOCK_TEXT + KPROBES_TEXT *(.fixup) *(.gnu.warning) - } =0 + } :text = 0 _etext = .; /* End of text section */ /* Exception table */ @@ -51,6 +55,10 @@ SECTIONS *(__dbe_table) __stop___dbe_table = .; } + + NOTES :text :note + .dummy : { *(.dummy) } :text + RODATA /* writeable */ @@ -201,7 +209,4 @@ SECTIONS *(.gptab.bss) *(.gptab.sbss) } - .note : { - *(.note) - } } diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 61b729fa0548..df8cbe4c7c0d 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -1317,7 +1317,8 @@ static void kspd_sp_exit( int sp_id) } #endif -static ssize_t store_kill(struct class_device *dev, const char *buf, size_t len) +static ssize_t store_kill(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len) { struct vpe *vpe = get_vpe(tclimit); struct vpe_notifications *not; @@ -1334,14 +1335,16 @@ static ssize_t store_kill(struct class_device *dev, const char *buf, size_t len) return len; } -static ssize_t show_ntcs(struct class_device *cd, char *buf) +static ssize_t show_ntcs(struct device *cd, struct device_attribute *attr, + char *buf) { struct vpe *vpe = get_vpe(tclimit); return sprintf(buf, "%d\n", vpe->ntcs); } -static ssize_t store_ntcs(struct class_device *dev, const char *buf, size_t len) +static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len) { struct vpe *vpe = get_vpe(tclimit); unsigned long new; @@ -1362,13 +1365,13 @@ out_einval: return -EINVAL;; } -static struct class_device_attribute vpe_class_attributes[] = { +static struct device_attribute vpe_class_attributes[] = { __ATTR(kill, S_IWUSR, NULL, store_kill), __ATTR(ntcs, S_IRUGO | S_IWUSR, show_ntcs, store_ntcs), {} }; -static void vpe_class_device_release(struct class_device *cd) +static void vpe_device_release(struct device *cd) { kfree(cd); } @@ -1376,11 +1379,11 @@ static void vpe_class_device_release(struct class_device *cd) struct class vpe_class = { .name = "vpe", .owner = THIS_MODULE, - .release = vpe_class_device_release, - .class_dev_attrs = vpe_class_attributes, + .dev_release = vpe_device_release, + .dev_attrs = vpe_class_attributes, }; -struct class_device vpe_device; +struct device vpe_device; static int __init vpe_module_init(void) { @@ -1423,12 +1426,12 @@ static int __init vpe_module_init(void) goto out_chrdev; } - class_device_initialize(&vpe_device); + device_initialize(&vpe_device); vpe_device.class = &vpe_class, vpe_device.parent = NULL, - strlcpy(vpe_device.class_id, "vpe1", BUS_ID_SIZE); + strlcpy(vpe_device.bus_id, "vpe1", BUS_ID_SIZE); vpe_device.devt = MKDEV(major, minor); - err = class_device_add(&vpe_device); + err = device_add(&vpe_device); if (err) { printk(KERN_ERR "Adding vpe_device failed\n"); goto out_class; @@ -1573,7 +1576,7 @@ static void __exit vpe_module_exit(void) } } - class_device_del(&vpe_device); + device_del(&vpe_device); unregister_chrdev(major, module_name); } diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index 5f35289bfff5..ba9692be3564 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c @@ -26,6 +26,7 @@ #include <linux/kernel_stat.h> #include <asm/bootinfo.h> +#include <asm/irq_cpu.h> #include <asm/lasat/lasatint.h> #include <asm/time.h> #include <asm/gdb-stub.h> @@ -88,7 +89,7 @@ asmlinkage void plat_irq_dispatch(void) int irq; if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */ - ll_timer_interrupt(7); + do_IRQ(7); return; } @@ -96,7 +97,7 @@ asmlinkage void plat_irq_dispatch(void) /* if int_status == 0, then the interrupt has already been cleared */ if (int_status) { - irq = ls1bit32(int_status); + irq = LASATINT_BASE + ls1bit32(int_status); do_IRQ(irq); } @@ -125,6 +126,7 @@ void __init arch_init_irq(void) panic("arch_init_irq: mips_machtype incorrect"); } - for (i = 0; i <= LASATINT_END; i++) + mips_cpu_irq_init(); + for (i = LASATINT_BASE; i <= LASATINT_END; i++) set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq); } diff --git a/arch/mips/mipssim/sim_cmdline.c b/arch/mips/mipssim/sim_cmdline.c index c63021a5dc6c..74240e1ce5a5 100644 --- a/arch/mips/mipssim/sim_cmdline.c +++ b/arch/mips/mipssim/sim_cmdline.c @@ -28,8 +28,5 @@ char * __init prom_getcmdline(void) void __init prom_init_cmdline(void) { - char *cp; - cp = arcs_cmdline; - /* Get boot line from environment? */ - *cp = '\0'; + /* XXX: Get boot line from environment? */ } diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 971f6c047b8a..d7088331fb0f 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -983,11 +983,15 @@ static void __init probe_pcache(void) printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", icache_size >> 10, - cpu_has_vtag_icache ? "virtually tagged" : "physically tagged", + cpu_has_vtag_icache ? "VIVT" : "VIPT", way_string[c->icache.ways], c->icache.linesz); - printk("Primary data cache %ldkB, %s, linesize %d bytes.\n", - dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz); + printk("Primary data cache %ldkB, %s, %s, %s, linesize %d bytes\n", + dcache_size >> 10, way_string[c->dcache.ways], + (c->dcache.flags & MIPS_CACHE_PINDEX) ? "PIPT" : "VIPT", + (c->dcache.flags & MIPS_CACHE_ALIASES) ? + "cache aliases" : "no aliases", + c->dcache.linesz); } /* diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 521771b373de..5699c7713e2f 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -180,7 +180,7 @@ out_of_memory: } printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 5240432e6d1d..110ee7656b41 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -211,7 +211,7 @@ void copy_user_highpage(struct page *to, struct page *from, void *vfrom, *vto; vto = kmap_atomic(to, KM_USER1); - if (cpu_has_dc_aliases && !Page_dcache_dirty(from)) { + if (cpu_has_dc_aliases && page_mapped(from)) { vfrom = kmap_coherent(from, vaddr); copy_page(vto, vfrom); kunmap_coherent(); @@ -234,12 +234,15 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len) { - if (cpu_has_dc_aliases) { + if (cpu_has_dc_aliases && page_mapped(page)) { void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); memcpy(vto, src, len); kunmap_coherent(); - } else + } else { memcpy(dst, src, len); + if (cpu_has_dc_aliases) + SetPageDcacheDirty(page); + } if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) flush_cache_page(vma, vaddr, page_to_pfn(page)); } @@ -250,13 +253,15 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len) { - if (cpu_has_dc_aliases) { - void *vfrom = - kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); + if (cpu_has_dc_aliases && page_mapped(page)) { + void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); memcpy(dst, vfrom, len); kunmap_coherent(); - } else + } else { memcpy(dst, src, len); + if (cpu_has_dc_aliases) + SetPageDcacheDirty(page); + } } EXPORT_SYMBOL(copy_from_user_page); diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 01b0961acfb6..a61246d3533d 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -66,7 +66,7 @@ static inline int __maybe_unused r10000_llsc_war(void) * why; it's not an issue caused by the core RTL. * */ -static int __init m4kc_tlbp_war(void) +static __init int __attribute__((unused)) m4kc_tlbp_war(void) { return (current_cpu_data.processor_id & 0xffff00) == (PRID_COMP_MIPS | PRID_IMP_4KC); @@ -140,7 +140,7 @@ struct insn { | (e) << RE_SH \ | (f) << FUNC_SH) -static struct insn insn_table[] __initdata = { +static __initdata struct insn insn_table[] = { { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD }, { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD }, @@ -193,7 +193,7 @@ static struct insn insn_table[] __initdata = { #undef M -static u32 __init build_rs(u32 arg) +static __init u32 build_rs(u32 arg) { if (arg & ~RS_MASK) printk(KERN_WARNING "TLB synthesizer field overflow\n"); @@ -201,7 +201,7 @@ static u32 __init build_rs(u32 arg) return (arg & RS_MASK) << RS_SH; } -static u32 __init build_rt(u32 arg) +static __init u32 build_rt(u32 arg) { if (arg & ~RT_MASK) printk(KERN_WARNING "TLB synthesizer field overflow\n"); @@ -209,7 +209,7 @@ static u32 __init build_rt(u32 arg) return (arg & RT_MASK) << RT_SH; } -static u32 __init build_rd(u32 arg) +static __init u32 build_rd(u32 arg) { if (arg & ~RD_MASK) printk(KERN_WARNING "TLB synthesizer field overflow\n"); @@ -217,7 +217,7 @@ static u32 __init build_rd(u32 arg) return (arg & RD_MASK) << RD_SH; } -static u32 __init build_re(u32 arg) +static __init u32 build_re(u32 arg) { if (arg & ~RE_MASK) printk(KERN_WARNING "TLB synthesizer field overflow\n"); @@ -225,7 +225,7 @@ static u32 __init build_re(u32 arg) return (arg & RE_MASK) << RE_SH; } -static u32 __init build_simm(s32 arg) +static __init u32 build_simm(s32 arg) { if (arg > 0x7fff || arg < -0x8000) printk(KERN_WARNING "TLB synthesizer field overflow\n"); @@ -233,7 +233,7 @@ static u32 __init build_simm(s32 arg) return arg & 0xffff; } -static u32 __init build_uimm(u32 arg) +static __init u32 build_uimm(u32 arg) { if (arg & ~IMM_MASK) printk(KERN_WARNING "TLB synthesizer field overflow\n"); @@ -241,7 +241,7 @@ static u32 __init build_uimm(u32 arg) return arg & IMM_MASK; } -static u32 __init build_bimm(s32 arg) +static __init u32 build_bimm(s32 arg) { if (arg > 0x1ffff || arg < -0x20000) printk(KERN_WARNING "TLB synthesizer field overflow\n"); @@ -252,7 +252,7 @@ static u32 __init build_bimm(s32 arg) return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff); } -static u32 __init build_jimm(u32 arg) +static __init u32 build_jimm(u32 arg) { if (arg & ~((JIMM_MASK) << 2)) printk(KERN_WARNING "TLB synthesizer field overflow\n"); @@ -260,7 +260,7 @@ static u32 __init build_jimm(u32 arg) return (arg >> 2) & JIMM_MASK; } -static u32 __init build_func(u32 arg) +static __init u32 build_func(u32 arg) { if (arg & ~FUNC_MASK) printk(KERN_WARNING "TLB synthesizer field overflow\n"); @@ -268,7 +268,7 @@ static u32 __init build_func(u32 arg) return arg & FUNC_MASK; } -static u32 __init build_set(u32 arg) +static __init u32 build_set(u32 arg) { if (arg & ~SET_MASK) printk(KERN_WARNING "TLB synthesizer field overflow\n"); @@ -315,69 +315,69 @@ static void __init build_insn(u32 **buf, enum opcode opc, ...) } #define I_u1u2u3(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ unsigned int b, unsigned int c) \ { \ build_insn(buf, insn##op, a, b, c); \ } #define I_u2u1u3(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ unsigned int b, unsigned int c) \ { \ build_insn(buf, insn##op, b, a, c); \ } #define I_u3u1u2(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ unsigned int b, unsigned int c) \ { \ build_insn(buf, insn##op, b, c, a); \ } #define I_u1u2s3(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ unsigned int b, signed int c) \ { \ build_insn(buf, insn##op, a, b, c); \ } #define I_u2s3u1(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ signed int b, unsigned int c) \ { \ build_insn(buf, insn##op, c, a, b); \ } #define I_u2u1s3(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ unsigned int b, signed int c) \ { \ build_insn(buf, insn##op, b, a, c); \ } #define I_u1u2(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ unsigned int b) \ { \ build_insn(buf, insn##op, a, b); \ } #define I_u1s2(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ signed int b) \ { \ build_insn(buf, insn##op, a, b); \ } #define I_u1(op) \ - static inline void i##op(u32 **buf, unsigned int a) \ + static inline void __init i##op(u32 **buf, unsigned int a) \ { \ build_insn(buf, insn##op, a); \ } #define I_0(op) \ - static inline void i##op(u32 **buf) \ + static inline void __init i##op(u32 **buf) \ { \ build_insn(buf, insn##op); \ } @@ -457,7 +457,7 @@ struct label { enum label_id lab; }; -static void __init build_label(struct label **lab, u32 *addr, +static __init void build_label(struct label **lab, u32 *addr, enum label_id l) { (*lab)->addr = addr; @@ -526,34 +526,34 @@ L_LA(_r3000_write_probe_fail) #define i_ehb(buf) i_sll(buf, 0, 0, 3) #ifdef CONFIG_64BIT -static int __init __maybe_unused in_compat_space_p(long addr) +static __init int __maybe_unused in_compat_space_p(long addr) { /* Is this address in 32bit compat space? */ return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L); } -static int __init __maybe_unused rel_highest(long val) +static __init int __maybe_unused rel_highest(long val) { return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000; } -static int __init __maybe_unused rel_higher(long val) +static __init int __maybe_unused rel_higher(long val) { return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000; } #endif -static int __init rel_hi(long val) +static __init int rel_hi(long val) { return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000; } -static int __init rel_lo(long val) +static __init int rel_lo(long val) { return ((val & 0xffff) ^ 0x8000) - 0x8000; } -static void __init i_LA_mostly(u32 **buf, unsigned int rs, long addr) +static __init void i_LA_mostly(u32 **buf, unsigned int rs, long addr) { #ifdef CONFIG_64BIT if (!in_compat_space_p(addr)) { @@ -571,7 +571,7 @@ static void __init i_LA_mostly(u32 **buf, unsigned int rs, long addr) i_lui(buf, rs, rel_hi(addr)); } -static void __init __maybe_unused i_LA(u32 **buf, unsigned int rs, +static __init void __maybe_unused i_LA(u32 **buf, unsigned int rs, long addr) { i_LA_mostly(buf, rs, addr); @@ -589,7 +589,7 @@ struct reloc { enum label_id lab; }; -static void __init r_mips_pc16(struct reloc **rel, u32 *addr, +static __init void r_mips_pc16(struct reloc **rel, u32 *addr, enum label_id l) { (*rel)->addr = addr; @@ -614,7 +614,7 @@ static inline void __resolve_relocs(struct reloc *rel, struct label *lab) } } -static void __init resolve_relocs(struct reloc *rel, struct label *lab) +static __init void resolve_relocs(struct reloc *rel, struct label *lab) { struct label *l; @@ -624,7 +624,7 @@ static void __init resolve_relocs(struct reloc *rel, struct label *lab) __resolve_relocs(rel, l); } -static void __init move_relocs(struct reloc *rel, u32 *first, u32 *end, +static __init void move_relocs(struct reloc *rel, u32 *first, u32 *end, long off) { for (; rel->lab != label_invalid; rel++) @@ -632,7 +632,7 @@ static void __init move_relocs(struct reloc *rel, u32 *first, u32 *end, rel->addr += off; } -static void __init move_labels(struct label *lab, u32 *first, u32 *end, +static __init void move_labels(struct label *lab, u32 *first, u32 *end, long off) { for (; lab->lab != label_invalid; lab++) @@ -640,7 +640,7 @@ static void __init move_labels(struct label *lab, u32 *first, u32 *end, lab->addr += off; } -static void __init copy_handler(struct reloc *rel, struct label *lab, +static __init void copy_handler(struct reloc *rel, struct label *lab, u32 *first, u32 *end, u32 *target) { long off = (long)(target - first); @@ -651,7 +651,7 @@ static void __init copy_handler(struct reloc *rel, struct label *lab, move_labels(lab, first, end, off); } -static int __init __maybe_unused insn_has_bdelay(struct reloc *rel, +static __init int __maybe_unused insn_has_bdelay(struct reloc *rel, u32 *addr) { for (; rel->lab != label_invalid; rel++) { @@ -743,11 +743,11 @@ il_bgez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l) * We deliberately chose a buffer size of 128, so we won't scribble * over anything important on overflow before we panic. */ -static u32 tlb_handler[128] __initdata; +static __initdata u32 tlb_handler[128]; /* simply assume worst case size for labels and relocs */ -static struct label labels[128] __initdata; -static struct reloc relocs[128] __initdata; +static __initdata struct label labels[128]; +static __initdata struct reloc relocs[128]; /* * The R3000 TLB handler is simple. @@ -801,7 +801,7 @@ static void __init build_r3000_tlb_refill_handler(void) * other one.To keep things simple, we first assume linear space, * then we relocate it to the final handler layout as needed. */ -static u32 final_handler[64] __initdata; +static __initdata u32 final_handler[64]; /* * Hazards @@ -825,7 +825,7 @@ static u32 final_handler[64] __initdata; * * As if we MIPS hackers wouldn't know how to nop pipelines happy ... */ -static void __init __maybe_unused build_tlb_probe_entry(u32 **p) +static __init void __maybe_unused build_tlb_probe_entry(u32 **p) { switch (current_cpu_type()) { /* Found by experiment: R4600 v2.0 needs this, too. */ @@ -849,7 +849,7 @@ static void __init __maybe_unused build_tlb_probe_entry(u32 **p) */ enum tlb_write_entry { tlb_random, tlb_indexed }; -static void __init build_tlb_write_entry(u32 **p, struct label **l, +static __init void build_tlb_write_entry(u32 **p, struct label **l, struct reloc **r, enum tlb_write_entry wmode) { @@ -993,7 +993,7 @@ static void __init build_tlb_write_entry(u32 **p, struct label **l, * TMP and PTR are scratch. * TMP will be clobbered, PTR will hold the pmd entry. */ -static void __init +static __init void build_get_pmde64(u32 **p, struct label **l, struct reloc **r, unsigned int tmp, unsigned int ptr) { @@ -1054,7 +1054,7 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r, * BVADDR is the faulting address, PTR is scratch. * PTR will hold the pgd for vmalloc. */ -static void __init +static __init void build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r, unsigned int bvaddr, unsigned int ptr) { @@ -1118,7 +1118,7 @@ build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r, * TMP and PTR are scratch. * TMP will be clobbered, PTR will hold the pgd entry. */ -static void __init __maybe_unused +static __init void __maybe_unused build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) { long pgdc = (long)pgd_current; @@ -1153,7 +1153,7 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) #endif /* !CONFIG_64BIT */ -static void __init build_adjust_context(u32 **p, unsigned int ctx) +static __init void build_adjust_context(u32 **p, unsigned int ctx) { unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12; unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1); @@ -1179,7 +1179,7 @@ static void __init build_adjust_context(u32 **p, unsigned int ctx) i_andi(p, ctx, ctx, mask); } -static void __init build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr) +static __init void build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr) { /* * Bug workaround for the Nevada. It seems as if under certain @@ -1204,7 +1204,7 @@ static void __init build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr) i_ADDU(p, ptr, ptr, tmp); /* add in offset */ } -static void __init build_update_entries(u32 **p, unsigned int tmp, +static __init void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep) { /* diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c index 5abd5c7119be..174f314933b5 100644 --- a/arch/mips/pci/pci-lasat.c +++ b/arch/mips/pci/pci-lasat.c @@ -10,6 +10,7 @@ #include <linux/pci.h> #include <linux/types.h> #include <asm/bootinfo.h> +#include <asm/lasat/lasatint.h> extern struct pci_ops nile4_pci_ops; extern struct pci_ops gt64xxx_pci0_ops; @@ -54,15 +55,15 @@ static int __init lasat_pci_setup(void) arch_initcall(lasat_pci_setup); -#define LASATINT_ETH1 0 -#define LASATINT_ETH0 1 -#define LASATINT_HDC 2 -#define LASATINT_COMP 3 -#define LASATINT_HDLC 4 -#define LASATINT_PCIA 5 -#define LASATINT_PCIB 6 -#define LASATINT_PCIC 7 -#define LASATINT_PCID 8 +#define LASATINT_ETH1 (LASATINT_BASE + 0) +#define LASATINT_ETH0 (LASATINT_BASE + 1) +#define LASATINT_HDC (LASATINT_BASE + 2) +#define LASATINT_COMP (LASATINT_BASE + 3) +#define LASATINT_HDLC (LASATINT_BASE + 4) +#define LASATINT_PCIA (LASATINT_BASE + 5) +#define LASATINT_PCIB (LASATINT_BASE + 6) +#define LASATINT_PCIC (LASATINT_BASE + 7) +#define LASATINT_PCID (LASATINT_BASE + 8) int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile index 1fb3e353e212..e3acb51b70b5 100644 --- a/arch/mips/sgi-ip22/Makefile +++ b/arch/mips/sgi-ip22/Makefile @@ -7,3 +7,5 @@ obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \ ip22-time.o ip22-nvram.o ip22-platform.o ip22-reset.o ip22-setup.o obj-$(CONFIG_EISA) += ip22-eisa.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c index 63afd7e44428..a435b31cf031 100644 --- a/arch/mips/sgi-ip22/ip22-reset.c +++ b/arch/mips/sgi-ip22/ip22-reset.c @@ -232,11 +232,18 @@ static struct notifier_block panic_block = { static int __init reboot_setup(void) { + int res; + _machine_restart = sgi_machine_restart; _machine_halt = sgi_machine_halt; pm_power_off = sgi_machine_power_off; - request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL); + res = request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL); + if (res) { + printk(KERN_ERR "Allocation of front panel IRQ failed\n"); + return res; + } + init_timer(&blink_timer); blink_timer.function = blink_timeout; atomic_notifier_chain_register(&panic_notifier_list, &panic_block); diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index 7f4b793c3df3..7e8094f617bf 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -20,6 +20,7 @@ #include <linux/random.h> #include <linux/sched.h> +#include <asm/irq_cpu.h> #include <asm/mipsregs.h> #include <asm/signal.h> #include <asm/system.h> @@ -46,7 +47,8 @@ static void inline flush_mace_bus(void) #define DBG(x...) #endif -/* O2 irq map +/* + * O2 irq map * * IP0 -> software (ignored) * IP1 -> software (ignored) @@ -55,60 +57,60 @@ static void inline flush_mace_bus(void) * IP4 -> (irq2) X unknown * IP5 -> (irq3) X unknown * IP6 -> (irq4) X unknown - * IP7 -> (irq5) 0 CPU count/compare timer (system timer) + * IP7 -> (irq5) 7 CPU count/compare timer (system timer) * * crime: (C) * * CRIME_INT_STAT 31:0: * - * 0 -> 1 Video in 1 - * 1 -> 2 Video in 2 - * 2 -> 3 Video out - * 3 -> 4 Mace ethernet + * 0 -> 8 Video in 1 + * 1 -> 9 Video in 2 + * 2 -> 10 Video out + * 3 -> 11 Mace ethernet * 4 -> S SuperIO sub-interrupt * 5 -> M Miscellaneous sub-interrupt * 6 -> A Audio sub-interrupt - * 7 -> 8 PCI bridge errors - * 8 -> 9 PCI SCSI aic7xxx 0 - * 9 -> 10 PCI SCSI aic7xxx 1 - * 10 -> 11 PCI slot 0 - * 11 -> 12 unused (PCI slot 1) - * 12 -> 13 unused (PCI slot 2) - * 13 -> 14 unused (PCI shared 0) - * 14 -> 15 unused (PCI shared 1) - * 15 -> 16 unused (PCI shared 2) - * 16 -> 17 GBE0 (E) - * 17 -> 18 GBE1 (E) - * 18 -> 19 GBE2 (E) - * 19 -> 20 GBE3 (E) - * 20 -> 21 CPU errors - * 21 -> 22 Memory errors - * 22 -> 23 RE empty edge (E) - * 23 -> 24 RE full edge (E) - * 24 -> 25 RE idle edge (E) - * 25 -> 26 RE empty level - * 26 -> 27 RE full level - * 27 -> 28 RE idle level - * 28 -> 29 unused (software 0) (E) - * 29 -> 30 unused (software 1) (E) - * 30 -> 31 unused (software 2) - crime 1.5 CPU SysCorError (E) - * 31 -> 32 VICE + * 7 -> 15 PCI bridge errors + * 8 -> 16 PCI SCSI aic7xxx 0 + * 9 -> 17 PCI SCSI aic7xxx 1 + * 10 -> 18 PCI slot 0 + * 11 -> 19 unused (PCI slot 1) + * 12 -> 20 unused (PCI slot 2) + * 13 -> 21 unused (PCI shared 0) + * 14 -> 22 unused (PCI shared 1) + * 15 -> 23 unused (PCI shared 2) + * 16 -> 24 GBE0 (E) + * 17 -> 25 GBE1 (E) + * 18 -> 26 GBE2 (E) + * 19 -> 27 GBE3 (E) + * 20 -> 28 CPU errors + * 21 -> 29 Memory errors + * 22 -> 30 RE empty edge (E) + * 23 -> 31 RE full edge (E) + * 24 -> 32 RE idle edge (E) + * 25 -> 33 RE empty level + * 26 -> 34 RE full level + * 27 -> 35 RE idle level + * 28 -> 36 unused (software 0) (E) + * 29 -> 37 unused (software 1) (E) + * 30 -> 38 unused (software 2) - crime 1.5 CPU SysCorError (E) + * 31 -> 39 VICE * * S, M, A: Use the MACE ISA interrupt register * MACE_ISA_INT_STAT 31:0 * - * 0-7 -> 33-40 Audio - * 8 -> 41 RTC - * 9 -> 42 Keyboard + * 0-7 -> 40-47 Audio + * 8 -> 48 RTC + * 9 -> 49 Keyboard * 10 -> X Keyboard polled - * 11 -> 44 Mouse + * 11 -> 51 Mouse * 12 -> X Mouse polled - * 13-15 -> 46-48 Count/compare timers - * 16-19 -> 49-52 Parallel (16 E) - * 20-25 -> 53-58 Serial 1 (22 E) - * 26-31 -> 59-64 Serial 2 (28 E) + * 13-15 -> 53-55 Count/compare timers + * 16-19 -> 56-59 Parallel (16 E) + * 20-25 -> 60-62 Serial 1 (22 E) + * 26-31 -> 66-71 Serial 2 (28 E) * - * Note that this means IRQs 5-7, 43, and 45 do not exist. This is a + * Note that this means IRQs 12-14, 50, and 52 do not exist. This is a * different IRQ map than IRIX uses, but that's OK as Linux irq handling * is quite different anyway. */ @@ -131,36 +133,6 @@ struct irqaction cpuerr_irq = { }; /* - * For interrupts wired from a single device to the CPU. Only the clock - * uses this it seems, which is IRQ 0 and IP7. - */ - -static void enable_cpu_irq(unsigned int irq) -{ - set_c0_status(STATUSF_IP7); -} - -static void disable_cpu_irq(unsigned int irq) -{ - clear_c0_status(STATUSF_IP7); -} - -static void end_cpu_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_cpu_irq(irq); -} - -static struct irq_chip ip32_cpu_interrupt = { - .name = "IP32 CPU", - .ack = disable_cpu_irq, - .mask = disable_cpu_irq, - .mask_ack = disable_cpu_irq, - .unmask = enable_cpu_irq, - .end = end_cpu_irq, -}; - -/* * This is for pure CRIME interrupts - ie not MACE. The advantage? * We get to split the register in half and do faster lookups. */ @@ -422,15 +394,23 @@ static void ip32_irq0(void) uint64_t crime_int; int irq = 0; + /* + * Sanity check interrupt numbering enum. + * MACE got 32 interrupts and there are 32 MACE ISA interrupts daisy + * chained. + */ + BUILD_BUG_ON(CRIME_VICE_IRQ - MACE_VID_IN1_IRQ != 31); + BUILD_BUG_ON(MACEISA_SERIAL2_RDMAOR_IRQ - MACEISA_AUDIO_SW_IRQ != 31); + crime_int = crime->istat & crime_mask; - irq = __ffs(crime_int); + irq = MACE_VID_IN1_IRQ + __ffs(crime_int); crime_int = 1 << irq; if (crime_int & CRIME_MACEISA_INT_MASK) { unsigned long mace_int = mace->perif.ctrl.istat; - irq = __ffs(mace_int & maceisa_mask) + 32; + irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ; } - irq++; + DBG("*irq %u*\n", irq); do_IRQ(irq); } @@ -457,7 +437,7 @@ static void ip32_irq4(void) static void ip32_irq5(void) { - do_IRQ(IP32_R4K_TIMER_IRQ); + do_IRQ(MIPS_CPU_IRQ_BASE + 7); } asmlinkage void plat_irq_dispatch(void) @@ -490,21 +470,25 @@ void __init arch_init_irq(void) mace->perif.ctrl.istat = 0; mace->perif.ctrl.imask = 0; - for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { - struct irq_chip *controller; - - if (irq == IP32_R4K_TIMER_IRQ) - controller = &ip32_cpu_interrupt; - else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ) - controller = &ip32_mace_interrupt; - else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ) - controller = &ip32_macepci_interrupt; - else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ) - controller = &ip32_crime_interrupt; - else - controller = &ip32_maceisa_interrupt; - - set_irq_chip(irq, controller); + mips_cpu_irq_init(); + for (irq = MIPS_CPU_IRQ_BASE + 8; irq <= IP32_IRQ_MAX; irq++) { + struct irq_chip *chip; + + switch (irq) { + case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ: + chip = &ip32_mace_interrupt; + break; + case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ: + chip = &ip32_macepci_interrupt; + break; + case CRIME_GBE0_IRQ ... CRIME_VICE_IRQ: + chip = &ip32_crime_interrupt; + break; + default: + chip = &ip32_maceisa_interrupt; + } + + set_irq_chip(irq, chip); } setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c index 4125a5ba119e..fc75bfcb0c0e 100644 --- a/arch/mips/sgi-ip32/ip32-setup.c +++ b/arch/mips/sgi-ip32/ip32-setup.c @@ -83,7 +83,7 @@ void __init plat_time_init(void) void __init plat_timer_setup(struct irqaction *irq) { irq->handler = no_action; - setup_irq(IP32_R4K_TIMER_IRQ, irq); + setup_irq(MIPS_CPU_IRQ_BASE + 7, irq); } void __init plat_mem_setup(void) diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c index acaf613358c7..b97102a1c635 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c @@ -963,7 +963,7 @@ static int __init toshiba_rbtx4927_rtc_init(void) .flags = IORESOURCE_MEM, }; struct platform_device *dev = - platform_device_register_simple("ds1742", -1, &res, 1); + platform_device_register_simple("rtc-ds1742", -1, &res, 1); return IS_ERR(dev) ? PTR_ERR(dev) : 0; } device_initcall(toshiba_rbtx4927_rtc_init); diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 26ec774c5027..49c637970789 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -329,10 +329,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) /* give it a chance to run. */ goto out_wake; - case PTRACE_DETACH: - ret = ptrace_detach(child, data); - goto out_tsk; - case PTRACE_GETEVENTMSG: ret = put_user(child->ptrace_message, (unsigned int __user *) data); goto out_tsk; diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 7899ab87785a..1c091b415cd9 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -263,6 +263,6 @@ no_context: up_read(&mm->mmap_sem); printk(KERN_CRIT "VM: killing process %s\n", current->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; } diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 037664d496d7..5e001ad588a7 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -295,6 +295,7 @@ config ARCH_FLATMEM_ENABLE config ARCH_SPARSEMEM_ENABLE def_bool y depends on PPC64 + select SPARSEMEM_VMEMMAP_ENABLE config ARCH_SPARSEMEM_DEFAULT def_bool y diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c index 7b0e754383cf..9001104b56b0 100644 --- a/arch/powerpc/kernel/dma_64.c +++ b/arch/powerpc/kernel/dma_64.c @@ -154,12 +154,13 @@ static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr, { } -static int dma_direct_map_sg(struct device *dev, struct scatterlist *sg, +static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents, enum dma_data_direction direction) { + struct scatterlist *sg; int i; - for (i = 0; i < nents; i++, sg++) { + for_each_sg(sgl, sg, nents, i) { sg->dma_address = (page_to_phys(sg->page) + sg->offset) | dma_direct_offset; sg->dma_length = sg->length; diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 53bf64623bd8..2e16ca5778a3 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -87,15 +87,16 @@ static void ibmebus_unmap_single(struct device *dev, } static int ibmebus_map_sg(struct device *dev, - struct scatterlist *sg, + struct scatterlist *sgl, int nents, enum dma_data_direction direction) { + struct scatterlist *sg; int i; - for (i = 0; i < nents; i++) { - sg[i].dma_address = (dma_addr_t)page_address(sg[i].page) - + sg[i].offset; - sg[i].dma_length = sg[i].length; + for_each_sg(sgl, sg, nents, i) { + sg->dma_address = (dma_addr_t)page_address(sg->page) + + sg->offset; + sg->dma_length = sg->length; } return nents; diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index e4ec6eee81a8..306a6f75b6c5 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -277,7 +277,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, dma_addr_t dma_next = 0, dma_addr; unsigned long flags; struct scatterlist *s, *outs, *segstart; - int outcount, incount; + int outcount, incount, i; unsigned long handle; BUG_ON(direction == DMA_NONE); @@ -297,7 +297,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, spin_lock_irqsave(&(tbl->it_lock), flags); - for (s = outs; nelems; nelems--, s++) { + for_each_sg(sglist, s, nelems, i) { unsigned long vaddr, npages, entry, slen; slen = s->length; @@ -341,7 +341,8 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, if (novmerge || (dma_addr != dma_next)) { /* Can't merge: create a new segment */ segstart = s; - outcount++; outs++; + outcount++; + outs = sg_next(outs); DBG(" can't merge, new segment.\n"); } else { outs->dma_length += s->length; @@ -374,7 +375,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, * next entry of the sglist if we didn't fill the list completely */ if (outcount < incount) { - outs++; + outs = sg_next(outs); outs->dma_address = DMA_ERROR_CODE; outs->dma_length = 0; } @@ -385,7 +386,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, return outcount; failure: - for (s = &sglist[0]; s <= outs; s++) { + for_each_sg(sglist, s, nelems, i) { if (s->dma_length != 0) { unsigned long vaddr, npages; @@ -395,6 +396,8 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, s->dma_address = DMA_ERROR_CODE; s->dma_length = 0; } + if (s == outs) + break; } spin_unlock_irqrestore(&(tbl->it_lock), flags); return 0; @@ -404,6 +407,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, int nelems, enum dma_data_direction direction) { + struct scatterlist *sg; unsigned long flags; BUG_ON(direction == DMA_NONE); @@ -413,15 +417,16 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, spin_lock_irqsave(&(tbl->it_lock), flags); + sg = sglist; while (nelems--) { unsigned int npages; - dma_addr_t dma_handle = sglist->dma_address; + dma_addr_t dma_handle = sg->dma_address; - if (sglist->dma_length == 0) + if (sg->dma_length == 0) break; - npages = iommu_num_pages(dma_handle,sglist->dma_length); + npages = iommu_num_pages(dma_handle, sg->dma_length); __iommu_free(tbl, dma_handle, npages); - sglist++; + sg = sg_next(sg); } /* Flush/invalidate TLBs if necessary. As for iommu_free(), we diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 440f5a87271f..5338e4855712 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -38,6 +38,8 @@ DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); +struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}}; + int __kprobes arch_prepare_kprobe(struct kprobe *p) { int ret = 0; diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 89b911e83c04..8f3db32fac8b 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -57,26 +57,21 @@ ssize_t of_device_get_modalias(struct of_device *ofdev, return tsize; } -int of_device_uevent(struct device *dev, - char **envp, int num_envp, char *buffer, int buffer_size) +int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) { struct of_device *ofdev; const char *compat; - int i = 0, length = 0, seen = 0, cplen, sl; + int seen = 0, cplen, sl; if (!dev) return -ENODEV; ofdev = to_of_device(dev); - if (add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "OF_NAME=%s", ofdev->node->name)) + if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name)) return -ENOMEM; - if (add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "OF_TYPE=%s", ofdev->node->type)) + if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type)) return -ENOMEM; /* Since the compatible field can contain pretty much anything @@ -85,9 +80,7 @@ int of_device_uevent(struct device *dev, compat = of_get_property(ofdev->node, "compatible", &cplen); while (compat && *compat && cplen > 0) { - if (add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "OF_COMPATIBLE_%d=%s", seen, compat)) + if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) return -ENOMEM; sl = strlen (compat) + 1; @@ -96,25 +89,17 @@ int of_device_uevent(struct device *dev, seen++; } - if (add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "OF_COMPATIBLE_N=%d", seen)) + if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen)) return -ENOMEM; /* modalias is trickier, we add it in 2 steps */ - if (add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "MODALIAS=")) + if (add_uevent_var(env, "MODALIAS=")) return -ENOMEM; - - sl = of_device_get_modalias(ofdev, &buffer[length-1], - buffer_size-length); - if (sl >= (buffer_size-length)) + sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1], + sizeof(env->buf) - env->buflen); + if (sl >= (sizeof(env->buf) - env->buflen)) return -ENOMEM; - - length += sl; - - envp[i] = NULL; + env->buflen += sl; return 0; } diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index cf7732cdd6c7..3e17d154d0d4 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -505,10 +505,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = ptrace_set_debugreg(child, addr, data); break; - case PTRACE_DETACH: - ret = ptrace_detach(child, data); - break; - #ifdef CONFIG_PPC64 case PTRACE_GETREGS64: #endif diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 36c90ba2d312..2de00f870edc 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -413,16 +413,28 @@ void __init smp_setup_cpu_maps(void) of_node_put(dn); } + vdso_data->processorCount = num_present_cpus(); +#endif /* CONFIG_PPC64 */ +} + +/* + * Being that cpu_sibling_map is now a per_cpu array, then it cannot + * be initialized until the per_cpu areas have been created. This + * function is now called from setup_per_cpu_areas(). + */ +void __init smp_setup_cpu_sibling_map(void) +{ +#if defined(CONFIG_PPC64) + int cpu; + /* * Do the sibling map; assume only two threads per processor. */ for_each_possible_cpu(cpu) { - cpu_set(cpu, cpu_sibling_map[cpu]); + cpu_set(cpu, per_cpu(cpu_sibling_map, cpu)); if (cpu_has_feature(CPU_FTR_SMT)) - cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); + cpu_set(cpu ^ 0x1, per_cpu(cpu_sibling_map, cpu)); } - - vdso_data->processorCount = num_present_cpus(); #endif /* CONFIG_PPC64 */ } #endif /* CONFIG_SMP */ diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 008ab6823b02..0e014550b83f 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -597,6 +597,9 @@ void __init setup_per_cpu_areas(void) paca[i].data_offset = ptr - __per_cpu_start; memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); } + + /* Now that per_cpu is setup, initialize cpu_sibling_map */ + smp_setup_cpu_sibling_map(); } #endif diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index d30f08fa0297..338950aeb6f6 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -61,11 +61,11 @@ struct thread_info *secondary_ti; cpumask_t cpu_possible_map = CPU_MASK_NONE; cpumask_t cpu_online_map = CPU_MASK_NONE; -cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; +DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE; EXPORT_SYMBOL(cpu_online_map); EXPORT_SYMBOL(cpu_possible_map); -EXPORT_SYMBOL(cpu_sibling_map); +EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); /* SMP operations for this machine */ struct smp_ops_t *smp_ops; diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S index 26e138c4ce17..9352ab5200e5 100644 --- a/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S @@ -1,130 +1,147 @@ - /* * This is the infamous ld script for the 32 bits vdso * library */ #include <asm/vdso.h> -/* Default link addresses for the vDSOs */ OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc") OUTPUT_ARCH(powerpc:common) ENTRY(_start) SECTIONS { - . = VDSO32_LBASE + SIZEOF_HEADERS; - .hash : { *(.hash) } :text - .gnu.hash : { *(.gnu.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - - .note : { *(.note.*) } :text :note - - . = ALIGN (16); - .text : - { - *(.text .stub .text.* .gnu.linkonce.t.*) - } - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - - . = ALIGN(8); - __ftr_fixup : { - *(__ftr_fixup) - } + . = VDSO32_LBASE + SIZEOF_HEADERS; + + .hash : { *(.hash) } :text + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + + .note : { *(.note.*) } :text :note + + . = ALIGN(16); + .text : { + *(.text .stub .text.* .gnu.linkonce.t.*) + } + PROVIDE(__etext = .); + PROVIDE(_etext = .); + PROVIDE(etext = .); + + . = ALIGN(8); + __ftr_fixup : { *(__ftr_fixup) } #ifdef CONFIG_PPC64 - . = ALIGN(8); - __fw_ftr_fixup : { - *(__fw_ftr_fixup) - } + . = ALIGN(8); + __fw_ftr_fixup : { *(__fw_ftr_fixup) } #endif - /* Other stuff is appended to the text segment: */ - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - - .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr - .eh_frame : { KEEP (*(.eh_frame)) } :text - .gcc_except_table : { *(.gcc_except_table) } - .fixup : { *(.fixup) } - - .dynamic : { *(.dynamic) } :text :dynamic - .got : { *(.got) } - .plt : { *(.plt) } - - _end = .; - __end = .; - PROVIDE (end = .); - - - /* Stabs debugging sections are here too - */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - - /DISCARD/ : { *(.note.GNU-stack) } - /DISCARD/ : { *(.data .data.* .gnu.linkonce.d.* .sdata*) } - /DISCARD/ : { *(.bss .sbss .dynbss .dynsbss) } + /* + * Other stuff is appended to the text segment: + */ + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr + .eh_frame : { KEEP (*(.eh_frame)) } :text + .gcc_except_table : { *(.gcc_except_table) } + .fixup : { *(.fixup) } + + .dynamic : { *(.dynamic) } :text :dynamic + .got : { *(.got) } + .plt : { *(.plt) } + + _end = .; + __end = .; + PROVIDE(end = .); + + /* + * Stabs debugging sections are here too. + */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + /* + * DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. + */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + /DISCARD/ : { + *(.note.GNU-stack) + *(.data .data.* .gnu.linkonce.d.* .sdata*) + *(.bss .sbss .dynbss .dynsbss) + } } +/* + * Very old versions of ld do not recognize this name token; use the constant. + */ +#define PT_GNU_EH_FRAME 0x6474e550 +/* + * We must supply the ELF program headers explicitly to get just one + * PT_LOAD segment, and set the flags explicitly to make segments read-only. + */ PHDRS { - text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ - note PT_NOTE FLAGS(4); /* PF_R */ - dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ - eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ + text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ + dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ + note PT_NOTE FLAGS(4); /* PF_R */ + eh_frame_hdr PT_GNU_EH_FRAME; } - /* * This controls what symbols we export from the DSO. */ VERSION { - VDSO_VERSION_STRING { - global: - __kernel_datapage_offset; /* Has to be there for the kernel to find */ - __kernel_get_syscall_map; - __kernel_gettimeofday; - __kernel_clock_gettime; - __kernel_clock_getres; - __kernel_get_tbfreq; - __kernel_sync_dicache; - __kernel_sync_dicache_p5; - __kernel_sigtramp32; - __kernel_sigtramp_rt32; - local: *; - }; + VDSO_VERSION_STRING { + global: + /* + * Has to be there for the kernel to find + */ + __kernel_datapage_offset; + + __kernel_get_syscall_map; + __kernel_gettimeofday; + __kernel_clock_gettime; + __kernel_clock_getres; + __kernel_get_tbfreq; + __kernel_sync_dicache; + __kernel_sync_dicache_p5; + __kernel_sigtramp32; + __kernel_sigtramp_rt32; + + local: *; + }; } diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index 2d70f35d50b5..932b3fdb34b9 100644 --- a/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S @@ -10,100 +10,114 @@ ENTRY(_start) SECTIONS { - . = VDSO64_LBASE + SIZEOF_HEADERS; - .hash : { *(.hash) } :text - .gnu.hash : { *(.gnu.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - - .note : { *(.note.*) } :text :note - - . = ALIGN (16); - .text : - { - *(.text .stub .text.* .gnu.linkonce.t.*) - *(.sfpr .glink) - } :text - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - - . = ALIGN(8); - __ftr_fixup : { - *(__ftr_fixup) - } - - . = ALIGN(8); - __fw_ftr_fixup : { - *(__fw_ftr_fixup) - } - - /* Other stuff is appended to the text segment: */ - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr - .eh_frame : { KEEP (*(.eh_frame)) } :text - .gcc_except_table : { *(.gcc_except_table) } - - .opd ALIGN(8) : { KEEP (*(.opd)) } - .got ALIGN(8) : { *(.got .toc) } - .rela.dyn ALIGN(8) : { *(.rela.dyn) } - - .dynamic : { *(.dynamic) } :text :dynamic - - _end = .; - PROVIDE (end = .); - - /* Stabs debugging sections are here too - */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sectio/ns. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - - /DISCARD/ : { *(.note.GNU-stack) } - /DISCARD/ : { *(.branch_lt) } - /DISCARD/ : { *(.data .data.* .gnu.linkonce.d.*) } - /DISCARD/ : { *(.bss .sbss .dynbss .dynsbss) } + . = VDSO64_LBASE + SIZEOF_HEADERS; + + .hash : { *(.hash) } :text + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + + .note : { *(.note.*) } :text :note + + . = ALIGN(16); + .text : { + *(.text .stub .text.* .gnu.linkonce.t.*) + *(.sfpr .glink) + } :text + PROVIDE(__etext = .); + PROVIDE(_etext = .); + PROVIDE(etext = .); + + . = ALIGN(8); + __ftr_fixup : { *(__ftr_fixup) } + + . = ALIGN(8); + __fw_ftr_fixup : { *(__fw_ftr_fixup) } + + /* + * Other stuff is appended to the text segment: + */ + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr + .eh_frame : { KEEP (*(.eh_frame)) } :text + .gcc_except_table : { *(.gcc_except_table) } + + .opd ALIGN(8) : { KEEP (*(.opd)) } + .got ALIGN(8) : { *(.got .toc) } + .rela.dyn ALIGN(8) : { *(.rela.dyn) } + + .dynamic : { *(.dynamic) } :text :dynamic + + _end = .; + PROVIDE(end = .); + + /* + * Stabs debugging sections are here too. + */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + /* + * DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. + */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + /DISCARD/ : { + *(.note.GNU-stack) + *(.branch_lt) + *(.data .data.* .gnu.linkonce.d.* .sdata*) + *(.bss .sbss .dynbss .dynsbss) + } } +/* + * Very old versions of ld do not recognize this name token; use the constant. + */ +#define PT_GNU_EH_FRAME 0x6474e550 + +/* + * We must supply the ELF program headers explicitly to get just one + * PT_LOAD segment, and set the flags explicitly to make segments read-only. + */ PHDRS { - text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ - note PT_NOTE FLAGS(4); /* PF_R */ - dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ - eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ + text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ + dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ + note PT_NOTE FLAGS(4); /* PF_R */ + eh_frame_hdr PT_GNU_EH_FRAME; } /* @@ -111,17 +125,22 @@ PHDRS */ VERSION { - VDSO_VERSION_STRING { - global: - __kernel_datapage_offset; /* Has to be there for the kernel to find */ - __kernel_get_syscall_map; - __kernel_gettimeofday; - __kernel_clock_gettime; - __kernel_clock_getres; - __kernel_get_tbfreq; - __kernel_sync_dicache; - __kernel_sync_dicache_p5; - __kernel_sigtramp_rt64; - local: *; - }; + VDSO_VERSION_STRING { + global: + /* + * Has to be there for the kernel to find + */ + __kernel_datapage_offset; + + __kernel_get_syscall_map; + __kernel_gettimeofday; + __kernel_clock_gettime; + __kernel_clock_getres; + __kernel_get_tbfreq; + __kernel_sync_dicache; + __kernel_sync_dicache_p5; + __kernel_sigtramp_rt64; + + local: *; + }; } diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index cb22a3557c4e..19a5656001c0 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -317,30 +317,20 @@ static int vio_bus_match(struct device *dev, struct device_driver *drv) return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL); } -static int vio_hotplug(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size) +static int vio_hotplug(struct device *dev, struct kobj_uevent_env *env) { const struct vio_dev *vio_dev = to_vio_dev(dev); struct device_node *dn; const char *cp; - int length; - - if (!num_envp) - return -ENOMEM; dn = dev->archdata.of_node; if (!dn) return -ENODEV; - cp = of_get_property(dn, "compatible", &length); + cp = of_get_property(dn, "compatible", NULL); if (!cp) return -ENODEV; - envp[0] = buffer; - length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s", - vio_dev->type, cp); - if ((buffer_size - length) <= 0) - return -ENOMEM; - envp[1] = NULL; + add_uevent_var(env, "MODALIAS=vio:T%sS%s", vio_dev->type, cp); return 0; } diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index fa90f6561b9f..29ed495444f5 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -183,3 +183,70 @@ void pgtable_cache_init(void) zero_ctor); } } + +#ifdef CONFIG_SPARSEMEM_VMEMMAP +/* + * Given an address within the vmemmap, determine the pfn of the page that + * represents the start of the section it is within. Note that we have to + * do this by hand as the proffered address may not be correctly aligned. + * Subtraction of non-aligned pointers produces undefined results. + */ +unsigned long __meminit vmemmap_section_start(unsigned long page) +{ + unsigned long offset = page - ((unsigned long)(vmemmap)); + + /* Return the pfn of the start of the section. */ + return (offset / sizeof(struct page)) & PAGE_SECTION_MASK; +} + +/* + * Check if this vmemmap page is already initialised. If any section + * which overlaps this vmemmap page is initialised then this page is + * initialised already. + */ +int __meminit vmemmap_populated(unsigned long start, int page_size) +{ + unsigned long end = start + page_size; + + for (; start < end; start += (PAGES_PER_SECTION * sizeof(struct page))) + if (pfn_valid(vmemmap_section_start(start))) + return 1; + + return 0; +} + +int __meminit vmemmap_populate(struct page *start_page, + unsigned long nr_pages, int node) +{ + unsigned long mode_rw; + unsigned long start = (unsigned long)start_page; + unsigned long end = (unsigned long)(start_page + nr_pages); + unsigned long page_size = 1 << mmu_psize_defs[mmu_linear_psize].shift; + + mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX; + + /* Align to the page size of the linear mapping. */ + start = _ALIGN_DOWN(start, page_size); + + for (; start < end; start += page_size) { + int mapped; + void *p; + + if (vmemmap_populated(start, page_size)) + continue; + + p = vmemmap_alloc_block(page_size, node); + if (!p) + return -ENOMEM; + + printk(KERN_WARNING "vmemmap %08lx allocated at %p, " + "physical %p.\n", start, p, __pa(p)); + + mapped = htab_bolt_mapping(start, start + page_size, + __pa(p), mode_rw, mmu_linear_psize); + BUG_ON(mapped < 0); + } + + return 0; +} +#endif diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 32dcfc9b0082..81eb96ec13b2 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -129,51 +129,6 @@ int __devinit arch_add_memory(int nid, u64 start, u64 size) return __add_pages(zone, start_pfn, nr_pages); } -/* - * First pass at this code will check to determine if the remove - * request is within the RMO. Do not allow removal within the RMO. - */ -int __devinit remove_memory(u64 start, u64 size) -{ - struct zone *zone; - unsigned long start_pfn, end_pfn, nr_pages; - - start_pfn = start >> PAGE_SHIFT; - nr_pages = size >> PAGE_SHIFT; - end_pfn = start_pfn + nr_pages; - - printk("%s(): Attempting to remove memoy in range " - "%lx to %lx\n", __func__, start, start+size); - /* - * check for range within RMO - */ - zone = page_zone(pfn_to_page(start_pfn)); - - printk("%s(): memory will be removed from " - "the %s zone\n", __func__, zone->name); - - /* - * not handling removing memory ranges that - * overlap multiple zones yet - */ - if (end_pfn > (zone->zone_start_pfn + zone->spanned_pages)) - goto overlap; - - /* make sure it is NOT in RMO */ - if ((start < lmb.rmo_size) || ((start+size) < lmb.rmo_size)) { - printk("%s(): range to be removed must NOT be in RMO!\n", - __func__); - goto in_rmo; - } - - return __remove_pages(zone, start_pfn, nr_pages); - -overlap: - printk("%s(): memory range to be removed overlaps " - "multiple zones!!!\n", __func__); -in_rmo: - return -1; -} #endif /* CONFIG_MEMORY_HOTPLUG */ void show_mem(void) diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c index 0caa3d955c3b..65b7ae426238 100644 --- a/arch/powerpc/platforms/52xx/lite5200.c +++ b/arch/powerpc/platforms/52xx/lite5200.c @@ -18,6 +18,8 @@ #include <linux/init.h> #include <linux/pci.h> #include <linux/of.h> +#include <linux/root_dev.h> +#include <linux/initrd.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> @@ -156,18 +158,6 @@ static void __init lite5200_setup_arch(void) of_node_put(np); } #endif - -#ifdef CONFIG_BLK_DEV_INITRD - if (initrd_start) - ROOT_DEV = Root_RAM0; - else -#endif -#ifdef CONFIG_ROOT_NFS - ROOT_DEV = Root_NFS; -#else - ROOT_DEV = Root_HDA1; -#endif - } /* diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 1245b2f517bb..095988f13bf4 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -77,12 +77,7 @@ static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val) { pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n); - dcr_write(msic->dcr_host, msic->dcr_host.base + dcr_n, val); -} - -static u32 msic_dcr_read(struct axon_msic *msic, unsigned int dcr_n) -{ - return dcr_read(msic->dcr_host, msic->dcr_host.base + dcr_n); + dcr_write(msic->dcr_host, dcr_n, val); } static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc) @@ -91,7 +86,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc) u32 write_offset, msi; int idx; - write_offset = msic_dcr_read(msic, MSIC_WRITE_OFFSET_REG); + write_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG); pr_debug("axon_msi: original write_offset 0x%x\n", write_offset); /* write_offset doesn't wrap properly, so we have to mask it */ @@ -306,7 +301,7 @@ static int axon_msi_notify_reboot(struct notifier_block *nb, list_for_each_entry(msic, &axon_msic_list, list) { pr_debug("axon_msi: disabling %s\n", msic->irq_host->of_node->full_name); - tmp = msic_dcr_read(msic, MSIC_CTRL_REG); + tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG); tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE; msic_dcr_write(msic, MSIC_CTRL_REG, tmp); } diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c index 901236fa0f07..13d5a87f13b1 100644 --- a/arch/powerpc/platforms/cell/cbe_cpufreq.c +++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c @@ -107,8 +107,6 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) pr_debug("%d: %d\n", i, cbe_freqs[i].frequency); } - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - /* if DEBUG is enabled set_pmode() measures the latency * of a transition */ policy->cpuinfo.transition_latency = 25000; @@ -119,7 +117,7 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->cur = cbe_freqs[cur_pmode].frequency; #ifdef CONFIG_SMP - policy->cpus = cpu_sibling_map[policy->cpu]; + policy->cpus = per_cpu(cpu_sibling_map, policy->cpu); #endif cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu); diff --git a/arch/powerpc/platforms/pasemi/cpufreq.c b/arch/powerpc/platforms/pasemi/cpufreq.c index 3ae083851b01..1cfb8b0c8fec 100644 --- a/arch/powerpc/platforms/pasemi/cpufreq.c +++ b/arch/powerpc/platforms/pasemi/cpufreq.c @@ -195,8 +195,6 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) pr_debug("%d: %d\n", i, pas_freqs[i].frequency); } - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - policy->cpuinfo.transition_latency = get_gizmo_latency(); cur_astate = get_cur_astate(policy->cpu); diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c index 1fe35dab0e9e..c04abcc28a7a 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/arch/powerpc/platforms/powermac/cpufreq_32.c @@ -410,7 +410,6 @@ static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) if (policy->cpu != 0) return -ENODEV; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = cur_freq; diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c index 00f50298c342..4dfb4bc242b5 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_64.c +++ b/arch/powerpc/platforms/powermac/cpufreq_64.c @@ -357,7 +357,6 @@ static unsigned int g5_cpufreq_get_speed(unsigned int cpu) static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy) { - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = g5_cpu_freqs[g5_query_freq()].frequency; /* secondary CPUs are tied to the primary one by the diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 4bb634a17e43..07e64b48e7fc 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -437,18 +437,12 @@ static void ps3_system_bus_shutdown(struct device *_dev) dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); } -static int ps3_system_bus_uevent(struct device *_dev, char **envp, - int num_envp, char *buffer, int buffer_size) +static int ps3_system_bus_uevent(struct device *_dev, struct kobj_uevent_env *env) { struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); - int i = 0, length = 0; - if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, - &length, "MODALIAS=ps3:%d", - dev->match_id)) + if (add_uevent_var(env, "MODALIAS=ps3:%d", dev->match_id)) return -ENOMEM; - - envp[i] = NULL; return 0; } @@ -622,17 +616,18 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr, } } -static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sg, int nents, - enum dma_data_direction direction) +static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl, + int nents, enum dma_data_direction direction) { #if defined(CONFIG_PS3_DYNAMIC_DMA) BUG_ON("do"); return -EPERM; #else struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); + struct scatterlist *sg; int i; - for (i = 0; i < nents; i++, sg++) { + for_each_sg(sgl, sg, nents, i) { int result = ps3_dma_map(dev->d_region, page_to_phys(sg->page) + sg->offset, sg->length, &sg->dma_address, 0); diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c index ab11c0b29024..427027c7ea0f 100644 --- a/arch/powerpc/sysdev/dcr.c +++ b/arch/powerpc/sysdev/dcr.c @@ -126,13 +126,13 @@ dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n, } EXPORT_SYMBOL_GPL(dcr_map); -void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c) +void dcr_unmap(dcr_host_t host, unsigned int dcr_c) { dcr_host_t h = host; if (h.token == NULL) return; - h.token += dcr_n * h.stride; + h.token += host.base * h.stride; iounmap(h.token); h.token = NULL; } diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 893e65439e85..e47938899a92 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -156,7 +156,7 @@ static inline u32 _mpic_read(enum mpic_reg_type type, switch(type) { #ifdef CONFIG_PPC_DCR case mpic_access_dcr: - return dcr_read(rb->dhost, rb->dhost.base + reg); + return dcr_read(rb->dhost, reg); #endif case mpic_access_mmio_be: return in_be32(rb->base + (reg >> 2)); @@ -173,7 +173,7 @@ static inline void _mpic_write(enum mpic_reg_type type, switch(type) { #ifdef CONFIG_PPC_DCR case mpic_access_dcr: - return dcr_write(rb->dhost, rb->dhost.base + reg, value); + return dcr_write(rb->dhost, reg, value); #endif case mpic_access_mmio_be: return out_be32(rb->base + (reg >> 2), value); diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index b98244e277fb..94913ddcf76e 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -297,7 +297,7 @@ out_of_memory: } printk("VM: killing process %s\n", current->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); return SIGKILL; do_sigbus: diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 62391fb1f61f..ac61cf43a7d9 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -547,8 +547,7 @@ static void __cpuinit appldata_online_cpu(int cpu) spin_unlock(&appldata_timer_lock); } -static void -appldata_offline_cpu(int cpu) +static void __cpuinit appldata_offline_cpu(int cpu) { del_virt_timer(&per_cpu(appldata_timer, cpu)); if (atomic_dec_and_test(&appldata_expire_count)) { @@ -560,9 +559,9 @@ appldata_offline_cpu(int cpu) spin_unlock(&appldata_timer_lock); } -static int __cpuinit -appldata_cpu_notify(struct notifier_block *self, - unsigned long action, void *hcpu) +static int __cpuinit appldata_cpu_notify(struct notifier_block *self, + unsigned long action, + void *hcpu) { switch (action) { case CPU_ONLINE: @@ -608,63 +607,15 @@ static int __init appldata_init(void) register_hotcpu_notifier(&appldata_nb); appldata_sysctl_header = register_sysctl_table(appldata_dir_table); -#ifdef MODULE - appldata_dir_table[0].de->owner = THIS_MODULE; - appldata_table[0].de->owner = THIS_MODULE; - appldata_table[1].de->owner = THIS_MODULE; -#endif P_DEBUG("Base interface initialized.\n"); return 0; } -/* - * appldata_exit() - * - * stop timer, unregister /proc entries - */ -static void __exit appldata_exit(void) -{ - struct list_head *lh; - struct appldata_ops *ops; - int rc, i; +__initcall(appldata_init); - P_DEBUG("Unloading module ...\n"); - /* - * ops list should be empty, but just in case something went wrong... - */ - spin_lock(&appldata_ops_lock); - list_for_each(lh, &appldata_ops_list) { - ops = list_entry(lh, struct appldata_ops, list); - rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, - (unsigned long) ops->data, ops->size, - ops->mod_lvl); - if (rc != 0) { - P_ERROR("STOP DIAG 0xDC for %s failed, " - "return code: %d\n", ops->name, rc); - } - } - spin_unlock(&appldata_ops_lock); - - for_each_online_cpu(i) - appldata_offline_cpu(i); - - appldata_timer_active = 0; - - unregister_sysctl_table(appldata_sysctl_header); - - destroy_workqueue(appldata_wq); - P_DEBUG("... module unloaded!\n"); -} /**************************** init / exit <END> ******************************/ - -module_init(appldata_init); -module_exit(appldata_exit); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Gerald Schaefer"); -MODULE_DESCRIPTION("Linux-VM Monitor Stream, base infrastructure"); - EXPORT_SYMBOL_GPL(appldata_register_ops); EXPORT_SYMBOL_GPL(appldata_unregister_ops); EXPORT_SYMBOL_GPL(appldata_diag); diff --git a/arch/s390/kernel/audit.c b/arch/s390/kernel/audit.c index d1c76fe10f29..f4932c22ebe4 100644 --- a/arch/s390/kernel/audit.c +++ b/arch/s390/kernel/audit.c @@ -2,6 +2,7 @@ #include <linux/types.h> #include <linux/audit.h> #include <asm/unistd.h> +#include "audit.h" static unsigned dir_class[] = { #include <asm-generic/audit_dir_write.h> @@ -40,7 +41,6 @@ int audit_classify_arch(int arch) int audit_classify_syscall(int abi, unsigned syscall) { #ifdef CONFIG_COMPAT - extern int s390_classify_syscall(unsigned); if (abi == AUDIT_ARCH_S390) return s390_classify_syscall(syscall); #endif @@ -61,11 +61,6 @@ int audit_classify_syscall(int abi, unsigned syscall) static int __init audit_classes_init(void) { #ifdef CONFIG_COMPAT - extern __u32 s390_dir_class[]; - extern __u32 s390_write_class[]; - extern __u32 s390_read_class[]; - extern __u32 s390_chattr_class[]; - extern __u32 s390_signal_class[]; audit_register_class(AUDIT_CLASS_WRITE_32, s390_write_class); audit_register_class(AUDIT_CLASS_READ_32, s390_read_class); audit_register_class(AUDIT_CLASS_DIR_WRITE_32, s390_dir_class); diff --git a/arch/s390/kernel/audit.h b/arch/s390/kernel/audit.h new file mode 100644 index 000000000000..12b56f4b5a73 --- /dev/null +++ b/arch/s390/kernel/audit.h @@ -0,0 +1,15 @@ +#ifndef __ARCH_S390_KERNEL_AUDIT_H +#define __ARCH_S390_KERNEL_AUDIT_H + +#include <linux/types.h> + +#ifdef CONFIG_COMPAT +extern int s390_classify_syscall(unsigned); +extern __u32 s390_dir_class[]; +extern __u32 s390_write_class[]; +extern __u32 s390_read_class[]; +extern __u32 s390_chattr_class[]; +extern __u32 s390_signal_class[]; +#endif /* CONFIG_COMPAT */ + +#endif /* __ARCH_S390_KERNEL_AUDIT_H */ diff --git a/arch/s390/kernel/compat_audit.c b/arch/s390/kernel/compat_audit.c index 0569f5126e49..d6487bf879e5 100644 --- a/arch/s390/kernel/compat_audit.c +++ b/arch/s390/kernel/compat_audit.c @@ -1,5 +1,6 @@ #undef __s390x__ #include <asm/unistd.h> +#include "audit.h" unsigned s390_dir_class[] = { #include <asm-generic/audit_dir_write.h> diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c index 6c89f30c8e31..d8c1131e0815 100644 --- a/arch/s390/kernel/cpcmd.c +++ b/arch/s390/kernel/cpcmd.c @@ -2,7 +2,7 @@ * arch/s390/kernel/cpcmd.c * * S390 version - * Copyright (C) 1999,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Copyright IBM Corp. 1999,2007 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), * Christian Borntraeger (cborntra@de.ibm.com), */ @@ -21,6 +21,49 @@ static DEFINE_SPINLOCK(cpcmd_lock); static char cpcmd_buf[241]; +static int diag8_noresponse(int cmdlen) +{ + register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf; + register unsigned long reg3 asm ("3") = cmdlen; + + asm volatile( +#ifndef CONFIG_64BIT + " diag %1,%0,0x8\n" +#else /* CONFIG_64BIT */ + " sam31\n" + " diag %1,%0,0x8\n" + " sam64\n" +#endif /* CONFIG_64BIT */ + : "+d" (reg3) : "d" (reg2) : "cc"); + return reg3; +} + +static int diag8_response(int cmdlen, char *response, int *rlen) +{ + register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf; + register unsigned long reg3 asm ("3") = (addr_t) response; + register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L; + register unsigned long reg5 asm ("5") = *rlen; + + asm volatile( +#ifndef CONFIG_64BIT + " diag %2,%0,0x8\n" + " brc 8,1f\n" + " ar %1,%4\n" +#else /* CONFIG_64BIT */ + " sam31\n" + " diag %2,%0,0x8\n" + " sam64\n" + " brc 8,1f\n" + " agr %1,%4\n" +#endif /* CONFIG_64BIT */ + "1:\n" + : "+d" (reg4), "+d" (reg5) + : "d" (reg2), "d" (reg3), "d" (*rlen) : "cc"); + *rlen = reg5; + return reg4; +} + /* * __cpcmd has some restrictions over cpcmd * - the response buffer must reside below 2GB (if any) @@ -28,59 +71,27 @@ static char cpcmd_buf[241]; */ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) { - unsigned cmdlen; - int return_code, return_len; + int cmdlen; + int rc; + int response_len; cmdlen = strlen(cmd); BUG_ON(cmdlen > 240); memcpy(cpcmd_buf, cmd, cmdlen); ASCEBC(cpcmd_buf, cmdlen); - if (response != NULL && rlen > 0) { - register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf; - register unsigned long reg3 asm ("3") = (addr_t) response; - register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L; - register unsigned long reg5 asm ("5") = rlen; - + if (response) { memset(response, 0, rlen); - asm volatile( -#ifndef CONFIG_64BIT - " diag %2,%0,0x8\n" - " brc 8,1f\n" - " ar %1,%4\n" -#else /* CONFIG_64BIT */ - " sam31\n" - " diag %2,%0,0x8\n" - " sam64\n" - " brc 8,1f\n" - " agr %1,%4\n" -#endif /* CONFIG_64BIT */ - "1:\n" - : "+d" (reg4), "+d" (reg5) - : "d" (reg2), "d" (reg3), "d" (rlen) : "cc"); - return_code = (int) reg4; - return_len = (int) reg5; - EBCASC(response, rlen); + response_len = rlen; + rc = diag8_response(cmdlen, response, &rlen); + EBCASC(response, response_len); } else { - register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf; - register unsigned long reg3 asm ("3") = cmdlen; - return_len = 0; - asm volatile( -#ifndef CONFIG_64BIT - " diag %1,%0,0x8\n" -#else /* CONFIG_64BIT */ - " sam31\n" - " diag %1,%0,0x8\n" - " sam64\n" -#endif /* CONFIG_64BIT */ - : "+d" (reg3) : "d" (reg2) : "cc"); - return_code = (int) reg3; + rc = diag8_noresponse(cmdlen); } - if (response_code != NULL) - *response_code = return_code; - return return_len; + if (response_code) + *response_code = rc; + return rlen; } - EXPORT_SYMBOL(__cpcmd); int cpcmd(const char *cmd, char *response, int rlen, int *response_code) @@ -109,5 +120,4 @@ int cpcmd(const char *cmd, char *response, int rlen, int *response_code) } return len; } - EXPORT_SYMBOL(cpcmd); diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index 50d2235df732..c14a336f6300 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c @@ -1162,6 +1162,7 @@ static int print_insn(char *buffer, unsigned char *code, unsigned long addr) unsigned int value; char separator; char *ptr; + int i; ptr = buffer; insn = find_insn(code); @@ -1169,7 +1170,8 @@ static int print_insn(char *buffer, unsigned char *code, unsigned long addr) ptr += sprintf(ptr, "%.5s\t", insn->name); /* Extract the operands. */ separator = 0; - for (ops = formats[insn->format] + 1; *ops != 0; ops++) { + for (ops = formats[insn->format] + 1, i = 0; + *ops != 0 && i < 6; ops++, i++) { operand = operands + *ops; value = extract_operand(code, operand); if ((operand->flags & OPERAND_INDEX) && value == 0) @@ -1241,7 +1243,6 @@ void show_code(struct pt_regs *regs) } /* Find a starting point for the disassembly. */ while (start < 32) { - hops = 0; for (i = 0, hops = 0; start + i < 32 && hops < 3; hops++) { if (!find_insn(code + start + i)) break; diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index f3bceb165321..139ca153d5cc 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -68,9 +68,15 @@ STACK_SIZE = 1 << STACK_SHIFT l %r1,BASED(.Ltrace_irq_off) basr %r14,%r1 .endm + + .macro LOCKDEP_SYS_EXIT + l %r1,BASED(.Llockdep_sys_exit) + basr %r14,%r1 + .endm #else #define TRACE_IRQS_ON #define TRACE_IRQS_OFF +#define LOCKDEP_SYS_EXIT #endif /* @@ -260,6 +266,7 @@ sysc_return: bno BASED(sysc_leave) tm __TI_flags+3(%r9),_TIF_WORK_SVC bnz BASED(sysc_work) # there is work to do (signals etc.) + LOCKDEP_SYS_EXIT sysc_leave: RESTORE_ALL __LC_RETURN_PSW,1 @@ -283,6 +290,7 @@ sysc_work: bo BASED(sysc_restart) tm __TI_flags+3(%r9),_TIF_SINGLE_STEP bo BASED(sysc_singlestep) + LOCKDEP_SYS_EXIT b BASED(sysc_leave) # @@ -572,6 +580,7 @@ io_return: #endif tm __TI_flags+3(%r9),_TIF_WORK_INT bnz BASED(io_work) # there is work to do (signals etc.) + LOCKDEP_SYS_EXIT io_leave: RESTORE_ALL __LC_RETURN_PSW,0 io_done: @@ -618,6 +627,7 @@ io_work_loop: bo BASED(io_reschedule) tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) bnz BASED(io_sigpending) + LOCKDEP_SYS_EXIT b BASED(io_leave) # @@ -1040,6 +1050,8 @@ cleanup_io_leave_insn: .Ltrace_irq_on: .long trace_hardirqs_on .Ltrace_irq_off: .long trace_hardirqs_off +.Llockdep_sys_exit: + .long lockdep_sys_exit #endif .Lcritical_start: .long __critical_start + 0x80000000 diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 9c0d5cc8269d..05e26d1fdf40 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -66,9 +66,14 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ .macro TRACE_IRQS_OFF brasl %r14,trace_hardirqs_off .endm + + .macro LOCKDEP_SYS_EXIT + brasl %r14,lockdep_sys_exit + .endm #else #define TRACE_IRQS_ON #define TRACE_IRQS_OFF +#define LOCKDEP_SYS_EXIT #endif .macro STORE_TIMER lc_offset @@ -255,6 +260,7 @@ sysc_return: jno sysc_leave tm __TI_flags+7(%r9),_TIF_WORK_SVC jnz sysc_work # there is work to do (signals etc.) + LOCKDEP_SYS_EXIT sysc_leave: RESTORE_ALL __LC_RETURN_PSW,1 @@ -278,6 +284,7 @@ sysc_work: jo sysc_restart tm __TI_flags+7(%r9),_TIF_SINGLE_STEP jo sysc_singlestep + LOCKDEP_SYS_EXIT j sysc_leave # @@ -558,6 +565,7 @@ io_return: #endif tm __TI_flags+7(%r9),_TIF_WORK_INT jnz io_work # there is work to do (signals etc.) + LOCKDEP_SYS_EXIT io_leave: RESTORE_ALL __LC_RETURN_PSW,0 io_done: @@ -605,6 +613,7 @@ io_work_loop: jo io_reschedule tm __TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) jnz io_sigpending + LOCKDEP_SYS_EXIT j io_leave # diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 8b8f136d9cc7..66b51901c87d 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -735,10 +735,10 @@ void do_reipl(void) case REIPL_METHOD_CCW_VM: reipl_get_ascii_loadparm(loadparm); if (strlen(loadparm) == 0) - sprintf(buf, "IPL %X", + sprintf(buf, "IPL %X CLEAR", reipl_block_ccw->ipl_info.ccw.devno); else - sprintf(buf, "IPL %X LOADPARM '%s'", + sprintf(buf, "IPL %X CLEAR LOADPARM '%s'", reipl_block_ccw->ipl_info.ccw.devno, loadparm); __cpcmd(buf, NULL, 0, NULL); break; diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index e40373d9fbce..c5549a206284 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -33,6 +33,8 @@ DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); +struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}}; + int __kprobes arch_prepare_kprobe(struct kprobe *p) { /* Make sure the probe isn't going on a difficult instruction */ diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index f4503ca27630..1d81bf9488ae 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -683,11 +683,6 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) wake_up_process(child); return 0; - case PTRACE_DETACH: - /* detach a process that was attached. */ - return ptrace_detach(child, data); - - /* Do requests that differ for 31/64 bit */ default: #ifdef CONFIG_COMPAT diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index b4622a3889b0..849120e3e28a 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -2,6 +2,7 @@ * Written by Martin Schwidefsky (schwidefsky@de.ibm.com) */ +#include <asm/page.h> #include <asm-generic/vmlinux.lds.h> #ifndef CONFIG_64BIT @@ -18,121 +19,142 @@ jiffies = jiffies_64; SECTIONS { - . = 0x00000000; - _text = .; /* Text and read-only data */ - .text : { - *(.text.head) + . = 0x00000000; + .text : { + _text = .; /* Text and read-only data */ + *(.text.head) TEXT_TEXT - SCHED_TEXT - LOCK_TEXT - KPROBES_TEXT - *(.fixup) - *(.gnu.warning) + SCHED_TEXT + LOCK_TEXT + KPROBES_TEXT + *(.fixup) + *(.gnu.warning) } = 0x0700 - _etext = .; /* End of text section */ + _etext = .; /* End of text section */ - RODATA + RODATA #ifdef CONFIG_SHARED_KERNEL - . = ALIGN(1048576); /* VM shared segments are 1MB aligned */ + . = ALIGN(0x100000); /* VM shared segments are 1MB aligned */ #endif - . = ALIGN(4096); - _eshared = .; /* End of shareable data */ - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - NOTES - - BUG_TABLE - - .data : { /* Data */ - DATA_DATA - CONSTRUCTORS - } - - . = ALIGN(4096); - __nosave_begin = .; - .data_nosave : { *(.data.nosave) } - . = ALIGN(4096); - __nosave_end = .; - - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - - . = ALIGN(256); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - . = ALIGN(256); - .data.read_mostly : { *(.data.read_mostly) } - _edata = .; /* End of data section */ - - . = ALIGN(8192); /* init_task */ - .data.init_task : { *(.data.init_task) } - - /* will be freed after init */ - . = ALIGN(4096); /* Init code and data */ - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - /* - * .exit.text is discarded at runtime, not link time, - * to deal with references from __bug_table - */ - .exit.text : { *(.exit.text) } - - .init.data : { *(.init.data) } - . = ALIGN(256); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __initcall_start = .; - .initcall.init : { - INITCALLS - } - __initcall_end = .; - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - SECURITY_INIT + . = ALIGN(PAGE_SIZE); + _eshared = .; /* End of shareable data */ + + . = ALIGN(16); /* Exception table */ + __ex_table : { + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } + + NOTES + BUG_TABLE + + .data : { /* Data */ + DATA_DATA + CONSTRUCTORS + } + + . = ALIGN(PAGE_SIZE); + .data_nosave : { + __nosave_begin = .; + *(.data.nosave) + } + . = ALIGN(PAGE_SIZE); + __nosave_end = .; + + . = ALIGN(PAGE_SIZE); + .data.page_aligned : { + *(.data.idt) + } + + . = ALIGN(0x100); + .data.cacheline_aligned : { + *(.data.cacheline_aligned) + } + + . = ALIGN(0x100); + .data.read_mostly : { + *(.data.read_mostly) + } + _edata = .; /* End of data section */ + + . = ALIGN(2 * PAGE_SIZE); /* init_task */ + .data.init_task : { + *(.data.init_task) + } + + /* will be freed after init */ + . = ALIGN(PAGE_SIZE); /* Init code and data */ + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + /* + * .exit.text is discarded at runtime, not link time, + * to deal with references from __bug_table + */ + .exit.text : { + *(.exit.text) + } + + .init.data : { + *(.init.data) + } + . = ALIGN(0x100); + .init.setup : { + __setup_start = .; + *(.init.setup) + __setup_end = .; + } + .initcall.init : { + __initcall_start = .; + INITCALLS + __initcall_end = .; + } + + .con_initcall.init : { + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + } + SECURITY_INIT #ifdef CONFIG_BLK_DEV_INITRD - . = ALIGN(256); - __initramfs_start = .; - .init.ramfs : { *(.init.initramfs) } - . = ALIGN(2); - __initramfs_end = .; + . = ALIGN(0x100); + .init.ramfs : { + __initramfs_start = .; + *(.init.ramfs) + . = ALIGN(2); + __initramfs_end = .; + } #endif - PERCPU(4096) - . = ALIGN(4096); - __init_end = .; - /* freed after init ends here */ - - __bss_start = .; /* BSS */ - .bss : { *(.bss) } - . = ALIGN(2); - __bss_stop = .; - - _end = . ; - - /* Sections to be discarded */ - /DISCARD/ : { - *(.exit.data) *(.exitcall.exit) - } - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } + + PERCPU(PAGE_SIZE) + . = ALIGN(PAGE_SIZE); + __init_end = .; /* freed after init ends here */ + + /* BSS */ + .bss : { + __bss_start = .; + *(.bss) + . = ALIGN(2); + __bss_stop = .; + } + + _end = . ; + + /* Sections to be discarded */ + /DISCARD/ : { + *(.exit.data) + *(.exitcall.exit) + } + + /* Debugging sections. */ + STABS_DEBUG + DWARF_DEBUG } diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 54055194e9af..14c241ccdd4d 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -218,7 +218,7 @@ static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code, } printk("VM: killing process %s\n", tsk->comm); if (regs->psw.mask & PSW_MASK_PSTATE) - do_exit(SIGKILL); + do_group_exit(SIGKILL); do_no_context(regs, error_code, address); return 0; } @@ -468,7 +468,7 @@ typedef struct { __u64 refselmk; __u64 refcmpmk; __u64 reserved; -} __attribute__ ((packed)) pfault_refbk_t; +} __attribute__ ((packed, aligned(8))) pfault_refbk_t; int pfault_init(void) { diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 54878f07cf0c..44982c1dfa23 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -118,7 +118,7 @@ endchoice config SH_FPU bool "FPU support" - depends on CPU_SH4 + depends on CPU_HAS_FPU default y help Selecting this option will enable support for SH processors that @@ -178,12 +178,6 @@ config CPU_HAS_INTEVT config CPU_HAS_MASKREG_IRQ bool -config CPU_HAS_INTC_IRQ - bool - -config CPU_HAS_INTC2_IRQ - bool - config CPU_HAS_IPR_IRQ bool @@ -205,6 +199,9 @@ config CPU_HAS_PTEA config CPU_HAS_DSP bool +config CPU_HAS_FPU + bool + endmenu menu "Board support" @@ -258,7 +255,6 @@ config SH_7780_SOLUTION_ENGINE bool "SolutionEngine7780" select SOLUTION_ENGINE select SYS_SUPPORTS_PCI - select CPU_HAS_INTC2_IRQ depends on CPU_SUBTYPE_SH7780 help Select 7780 SolutionEngine if configuring for a Renesas SH7780 @@ -309,7 +305,7 @@ config SH_MPC1211 config SH_SH03 bool "Interface CTP/PCI-SH03" - depends on CPU_SUBTYPE_SH7751 && BROKEN + depends on CPU_SUBTYPE_SH7751 select CPU_HAS_IPR_IRQ select SYS_SUPPORTS_PCI help @@ -395,11 +391,22 @@ config SH_LBOX_RE2 help Select L-BOX RE2 if configuring for the NTT COMWARE L-BOX RE2. +config SH_X3PROTO + bool "SH-X3 Prototype board" + depends on CPU_SUBTYPE_SHX3 + +config SH_MAGIC_PANEL_R2 + bool "Magic Panel R2" + depends on CPU_SUBTYPE_SH7720 + help + Select Magic Panel R2 if configuring for Magic Panel R2. + 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/boards/magicpanelr2/Kconfig" menu "Timer and clock configuration" @@ -563,10 +570,19 @@ config NR_CPUS source "kernel/Kconfig.preempt" -config NODES_SHIFT - int - default "1" - depends on NEED_MULTIPLE_NODES +config GUSA + def_bool y + depends on !SMP + help + This enables support for gUSA (general UserSpace Atomicity). + This is the default implementation for both UP and non-ll/sc + CPUs, and is used by the libc, amongst others. + + For additional information, design information can be found + in <http://lc.linux.or.jp/lc2002/papers/niibe0919p.pdf>. + + This should only be disabled for special cases where alternate + atomicity implementations exist. endmenu @@ -659,6 +675,17 @@ config SUPERHYWAY tristate "SuperHyway Bus support" depends on CPU_SUBTYPE_SH4_202 +config MAPLE + bool "Maple Bus support" + depends on SH_DREAMCAST + help + The Maple Bus is SEGA's serial communication bus for peripherals + on the Dreamcast. Without this bus support you won't be able to + get your Dreamcast keyboard etc to work, so most users + probably want to say 'Y' here, unless you are only using the + Dreamcast with a serial line terminal or a remote network + connection. + config CF_ENABLER bool "Compact Flash Enabler support" depends on SOLUTION_ENGINE || SH_SH03 diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 52f6a99c8ecc..b507b501f0cf 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -28,13 +28,17 @@ config EARLY_SCIF_CONSOLE serial I/O. config EARLY_SCIF_CONSOLE_PORT - hex "SCIF port for early console" + hex depends on EARLY_SCIF_CONSOLE default "0xffe00000" if CPU_SUBTYPE_SH7780 + default "0xffea0000" if CPU_SUBTYPE_SH7785 default "0xfffe9800" if CPU_SUBTYPE_SH7206 default "0xf8420000" if CPU_SUBTYPE_SH7619 default "0xa4400000" if CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7705 + default "0xa4430000" if CPU_SUBTYPE_SH7720 + default "0xffc30000" if CPU_SUBTYPE_SHX3 default "0xffe80000" if CPU_SH4 + default "0x00000000" config EARLY_PRINTK bool "Early printk support" diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 0353296c2c93..408342b175c8 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -118,6 +118,7 @@ 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_X3PROTO) += renesas/x3proto machdir-$(CONFIG_SH_SH4202_MICRODEV) += superh/microdev machdir-$(CONFIG_SH_LANDISK) += landisk machdir-$(CONFIG_SH_TITAN) += titan @@ -125,6 +126,7 @@ 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_MAGIC_PANEL_R2) += magicpanelr2 incdir-y := $(notdir $(machdir-y)) @@ -135,7 +137,7 @@ endif # Companion chips core-$(CONFIG_HD6446X_SERIES) += arch/sh/cchips/hd6446x/ -core-$(CONFIG_VOYAGERGX) += arch/sh/cchips/voyagergx/ +core-$(CONFIG_MFD_SM501) += arch/sh/cchips/voyagergx/ cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2 cpuincdir-$(CONFIG_CPU_SH2A) := cpu-sh2a diff --git a/arch/sh/boards/hp6xx/hp6xx_apm.c b/arch/sh/boards/hp6xx/hp6xx_apm.c index d1c1460c8a06..640ca2a74f16 100644 --- a/arch/sh/boards/hp6xx/hp6xx_apm.c +++ b/arch/sh/boards/hp6xx/hp6xx_apm.c @@ -20,9 +20,9 @@ #define APM_CRITICAL 10 #define APM_LOW 30 -#define HP680_BATTERY_MAX 875 -#define HP680_BATTERY_MIN 600 -#define HP680_BATTERY_AC_ON 900 +#define HP680_BATTERY_MAX 898 +#define HP680_BATTERY_MIN 486 +#define HP680_BATTERY_AC_ON 1023 #define MODNAME "hp6x0_apm" @@ -65,7 +65,7 @@ static void hp6x0_apm_get_power_status(struct apm_power_info *info) static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev) { - if (!apm_suspended) + if (!APM_DISABLED) apm_queue_event(APM_USER_SUSPEND); return IRQ_HANDLED; @@ -91,7 +91,6 @@ static int __init hp6x0_apm_init(void) static void __exit hp6x0_apm_exit(void) { free_irq(HP680_BTN_IRQ, 0); - apm_get_info = NULL; } module_init(hp6x0_apm_init); diff --git a/arch/sh/boards/hp6xx/setup.c b/arch/sh/boards/hp6xx/setup.c index 7ae708930bac..2f414ac3c690 100644 --- a/arch/sh/boards/hp6xx/setup.c +++ b/arch/sh/boards/hp6xx/setup.c @@ -7,7 +7,7 @@ * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. * - * Setup code for an HP680 (internal peripherials only) + * Setup code for HP620/HP660/HP680/HP690 (internal peripherials only) */ #include <linux/types.h> #include <linux/init.h> @@ -19,7 +19,7 @@ #include <asm/cpu/dac.h> #define SCPCR 0xa4000116 -#define SCPDR 0xa4000136 +#define SCPDR 0xa4000136 /* CF Slot */ static struct resource cf_ide_resources[] = { @@ -34,7 +34,7 @@ static struct resource cf_ide_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { - .start = 93, + .start = 77, .flags = IORESOURCE_IRQ, }, }; @@ -46,10 +46,22 @@ static struct platform_device cf_ide_device = { .resource = cf_ide_resources, }; +static struct platform_device jornadakbd_device = { + .name = "jornada680_kbd", + .id = -1, +}; + static struct platform_device *hp6xx_devices[] __initdata = { - &cf_ide_device, + &cf_ide_device, + &jornadakbd_device, }; +static void __init hp6xx_init_irq(void) +{ + /* Gets touchscreen and powerbutton IRQ working */ + plat_irq_setup_pins(IRQ_MODE_IRQ); +} + static int __init hp6xx_devices_setup(void) { return platform_add_devices(hp6xx_devices, ARRAY_SIZE(hp6xx_devices)); @@ -61,11 +73,11 @@ static void __init hp6xx_setup(char **cmdline_p) u16 v; v = inw(HD64461_STBCR); - v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | - HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST | - HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST | - HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST | - HD64461_STBCR_SAFECKE_IST; + v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | + HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST | + HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST | + HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST| + HD64461_STBCR_SAFECKE_IST; #ifndef CONFIG_HD64461_ENABLER v |= HD64461_STBCR_SPC1ST; #endif @@ -101,6 +113,9 @@ device_initcall(hp6xx_devices_setup); static struct sh_machine_vector mv_hp6xx __initmv = { .mv_name = "hp6xx", .mv_setup = hp6xx_setup, - .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM, + /* IRQ's : CPU(64) + CCHIP(16) + FREE_TO_USE(6) */ + .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM + 6, .mv_irq_demux = hd64461_irq_demux, + /* Enable IRQ0 -> IRQ3 in IRQ_MODE */ + .mv_init_irq = hp6xx_init_irq, }; diff --git a/arch/sh/boards/magicpanelr2/Kconfig b/arch/sh/boards/magicpanelr2/Kconfig new file mode 100644 index 000000000000..b0abddc3e84f --- /dev/null +++ b/arch/sh/boards/magicpanelr2/Kconfig @@ -0,0 +1,13 @@ +if SH_MAGIC_PANEL_R2 + +menu "Magic Panel R2 options" + +config SH_MAGIC_PANEL_R2_VERSION + int SH_MAGIC_PANEL_R2_VERSION + default "3" + help + Set the version of the Magic Panel R2 + +endmenu + +endif diff --git a/arch/sh/boards/magicpanelr2/Makefile b/arch/sh/boards/magicpanelr2/Makefile new file mode 100644 index 000000000000..7a6d586b9072 --- /dev/null +++ b/arch/sh/boards/magicpanelr2/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the Magic Panel specific parts +# + +obj-y := setup.o
\ No newline at end of file diff --git a/arch/sh/boards/magicpanelr2/setup.c b/arch/sh/boards/magicpanelr2/setup.c new file mode 100644 index 000000000000..f3b8b07ea5d6 --- /dev/null +++ b/arch/sh/boards/magicpanelr2/setup.c @@ -0,0 +1,394 @@ +/* + * linux/arch/sh/boards/magicpanel/setup.c + * + * Copyright (C) 2007 Markus Brunner, Mark Jonas + * + * Magic Panel Release 2 board setup + * + * 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/irq.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/mtd/map.h> +#include <asm/magicpanelr2.h> +#include <asm/heartbeat.h> + +#define LAN9115_READY (ctrl_inl(0xA8000084UL) & 0x00000001UL) + +/* Prefer cmdline over RedBoot */ +static const char *probes[] = { "cmdlinepart", "RedBoot", NULL }; + +/* Wait until reset finished. Timeout is 100ms. */ +static int __init ethernet_reset_finished(void) +{ + int i; + + if (LAN9115_READY) + return 1; + + for (i = 0; i < 10; ++i) { + mdelay(10); + if (LAN9115_READY) + return 1; + } + + return 0; +} + +static void __init reset_ethernet(void) +{ + /* PMDR: LAN_RESET=on */ + CLRBITS_OUTB(0x10, PORT_PMDR); + + udelay(200); + + /* PMDR: LAN_RESET=off */ + SETBITS_OUTB(0x10, PORT_PMDR); +} + +static void __init setup_chip_select(void) +{ + /* CS2: LAN (0x08000000 - 0x0bffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + ctrl_outl(0x36db0400, CS2BCR); + /* (SW:1.5 WR:3 HW:1.5), ext. wait */ + ctrl_outl(0x000003c0, CS2WCR); + + /* CS4: CAN1 (0xb0000000 - 0xb3ffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + ctrl_outl(0x00000200, CS4BCR); + /* (SW:1.5 WR:3 HW:1.5), ext. wait */ + ctrl_outl(0x00100981, CS4WCR); + + /* CS5a: CAN2 (0xb4000000 - 0xb5ffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + ctrl_outl(0x00000200, CS5ABCR); + /* (SW:1.5 WR:3 HW:1.5), ext. wait */ + ctrl_outl(0x00100981, CS5AWCR); + + /* CS5b: CAN3 (0xb6000000 - 0xb7ffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + ctrl_outl(0x00000200, CS5BBCR); + /* (SW:1.5 WR:3 HW:1.5), ext. wait */ + ctrl_outl(0x00100981, CS5BWCR); + + /* CS6a: Rotary (0xb8000000 - 0xb9ffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + ctrl_outl(0x00000200, CS6ABCR); + /* (SW:1.5 WR:3 HW:1.5), no ext. wait */ + ctrl_outl(0x001009C1, CS6AWCR); +} + +static void __init setup_port_multiplexing(void) +{ + /* A7 GPO(LED8); A6 GPO(LED7); A5 GPO(LED6); A4 GPO(LED5); + * A3 GPO(LED4); A2 GPO(LED3); A1 GPO(LED2); A0 GPO(LED1); + */ + ctrl_outw(0x5555, PORT_PACR); /* 01 01 01 01 01 01 01 01 */ + + /* B7 GPO(RST4); B6 GPO(RST3); B5 GPO(RST2); B4 GPO(RST1); + * B3 GPO(PB3); B2 GPO(PB2); B1 GPO(PB1); B0 GPO(PB0); + */ + ctrl_outw(0x5555, PORT_PBCR); /* 01 01 01 01 01 01 01 01 */ + + /* C7 GPO(PC7); C6 GPO(PC6); C5 GPO(PC5); C4 GPO(PC4); + * C3 LCD_DATA3; C2 LCD_DATA2; C1 LCD_DATA1; C0 LCD_DATA0; + */ + ctrl_outw(0x5500, PORT_PCCR); /* 01 01 01 01 00 00 00 00 */ + + /* D7 GPO(PD7); D6 GPO(PD6); D5 GPO(PD5); D4 GPO(PD4); + * D3 GPO(PD3); D2 GPO(PD2); D1 GPO(PD1); D0 GPO(PD0); + */ + ctrl_outw(0x5555, PORT_PDCR); /* 01 01 01 01 01 01 01 01 */ + + /* E7 (x); E6 GPI(nu); E5 GPI(nu); E4 LCD_M_DISP; + * E3 LCD_CL1; E2 LCD_CL2; E1 LCD_DON; E0 LCD_FLM; + */ + ctrl_outw(0x3C00, PORT_PECR); /* 00 11 11 00 00 00 00 00 */ + + /* F7 (x); F6 DA1(VLCD); F5 DA0(nc); F4 AN3; + * F3 AN2(MID_AD); F2 AN1(EARTH_AD); F1 AN0(TEMP); F0 GPI+(nc); + */ + ctrl_outw(0x0002, PORT_PFCR); /* 00 00 00 00 00 00 00 10 */ + + /* G7 (x); G6 IRQ5(TOUCH_BUSY); G5 IRQ4(TOUCH_IRQ); G4 GPI(KEY2); + * G3 GPI(KEY1); G2 GPO(LED11); G1 GPO(LED10); G0 GPO(LED9); + */ + ctrl_outw(0x03D5, PORT_PGCR); /* 00 00 00 11 11 01 01 01 */ + + /* H7 (x); H6 /RAS(BRAS); H5 /CAS(BCAS); H4 CKE(BCKE); + * H3 GPO(EARTH_OFF); H2 GPO(EARTH_TEST); H1 USB2_PWR; H0 USB1_PWR; + */ + ctrl_outw(0x0050, PORT_PHCR); /* 00 00 00 00 01 01 00 00 */ + + /* J7 (x); J6 AUDCK; J5 ASEBRKAK; J4 AUDATA3; + * J3 AUDATA2; J2 AUDATA1; J1 AUDATA0; J0 AUDSYNC; + */ + ctrl_outw(0x0000, PORT_PJCR); /* 00 00 00 00 00 00 00 00 */ + + /* K7 (x); K6 (x); K5 (x); K4 (x); + * K3 PINT7(/PWR2); K2 PINT6(/PWR1); K1 PINT5(nu); K0 PINT4(FLASH_READY) + */ + ctrl_outw(0x00FF, PORT_PKCR); /* 00 00 00 00 11 11 11 11 */ + + /* L7 TRST; L6 TMS; L5 TDO; L4 TDI; + * L3 TCK; L2 (x); L1 (x); L0 (x); + */ + ctrl_outw(0x0000, PORT_PLCR); /* 00 00 00 00 00 00 00 00 */ + + /* M7 GPO(CURRENT_SINK); M6 GPO(PWR_SWITCH); M5 GPO(LAN_SPEED); + * M4 GPO(LAN_RESET); M3 GPO(BUZZER); M2 GPO(LCD_BL); + * M1 CS5B(CAN3_CS); M0 GPI+(nc); + */ + ctrl_outw(0x5552, PORT_PMCR); /* 01 01 01 01 01 01 00 10 */ + + /* CURRENT_SINK=off, PWR_SWITCH=off, LAN_SPEED=100MBit, + * LAN_RESET=off, BUZZER=off, LCD_BL=off + */ +#if CONFIG_SH_MAGIC_PANEL_R2_VERSION == 2 + ctrl_outb(0x30, PORT_PMDR); +#elif CONFIG_SH_MAGIC_PANEL_R2_VERSION == 3 + ctrl_outb(0xF0, PORT_PMDR); +#else +#error Unknown revision of PLATFORM_MP_R2 +#endif + + /* P7 (x); P6 (x); P5 (x); + * P4 GPO(nu); P3 IRQ3(LAN_IRQ); P2 IRQ2(CAN3_IRQ); + * P1 IRQ1(CAN2_IRQ); P0 IRQ0(CAN1_IRQ) + */ + ctrl_outw(0x0100, PORT_PPCR); /* 00 00 00 01 00 00 00 00 */ + ctrl_outb(0x10, PORT_PPDR); + + /* R7 A25; R6 A24; R5 A23; R4 A22; + * R3 A21; R2 A20; R1 A19; R0 A0; + */ + ctrl_outw(0x0000, PORT_PRCR); /* 00 00 00 00 00 00 00 00 */ + + /* S7 (x); S6 (x); S5 (x); S4 GPO(EEPROM_CS2); + * S3 GPO(EEPROM_CS1); S2 SIOF0_TXD; S1 SIOF0_RXD; S0 SIOF0_SCK; + */ + ctrl_outw(0x0140, PORT_PSCR); /* 00 00 00 01 01 00 00 00 */ + + /* T7 (x); T6 (x); T5 (x); T4 COM1_CTS; + * T3 COM1_RTS; T2 COM1_TXD; T1 COM1_RXD; T0 GPO(WDOG) + */ + ctrl_outw(0x0001, PORT_PTCR); /* 00 00 00 00 00 00 00 01 */ + + /* U7 (x); U6 (x); U5 (x); U4 GPI+(/AC_FAULT); + * U3 GPO(TOUCH_CS); U2 TOUCH_TXD; U1 TOUCH_RXD; U0 TOUCH_SCK; + */ + ctrl_outw(0x0240, PORT_PUCR); /* 00 00 00 10 01 00 00 00 */ + + /* V7 (x); V6 (x); V5 (x); V4 GPO(MID2); + * V3 GPO(MID1); V2 CARD_TxD; V1 CARD_RxD; V0 GPI+(/BAT_FAULT); + */ + ctrl_outw(0x0142, PORT_PVCR); /* 00 00 00 01 01 00 00 10 */ +} + +static void __init mpr2_setup(char **cmdline_p) +{ + __set_io_port_base(0xa0000000); + + /* set Pin Select Register A: + * /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2, + * /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND + */ + ctrl_outw(0xAABC, PORT_PSELA); + /* set Pin Select Register B: + * /SCIF0_RTS, /SCIF0_CTS, LCD_VCPWC, + * LCD_VEPWC, IIC_SDA, IIC_SCL, Reserved + */ + ctrl_outw(0x3C00, PORT_PSELB); + /* set Pin Select Register C: + * SIOF1_SCK, SIOF1_RxD, SCIF1_RxD, SCIF1_TxD, Reserved + */ + ctrl_outw(0x0000, PORT_PSELC); + /* set Pin Select Register D: Reserved, SIOF1_TxD, Reserved, SIOF1_MCLK, + * Reserved, SIOF1_SYNC, Reserved, SCIF1_SCK, Reserved + */ + ctrl_outw(0x0000, PORT_PSELD); + /* set USB TxRx Control: Reserved, DRV, Reserved, USB_TRANS, USB_SEL */ + ctrl_outw(0x0101, PORT_UTRCTL); + /* set USB Clock Control: USSCS, USSTB, Reserved (HighByte always A5) */ + ctrl_outw(0xA5C0, PORT_UCLKCR_W); + + setup_chip_select(); + + setup_port_multiplexing(); + + reset_ethernet(); + + printk(KERN_INFO "Magic Panel Release 2 A.%i\n", + CONFIG_SH_MAGIC_PANEL_R2_VERSION); + + if (ethernet_reset_finished() == 0) + printk(KERN_WARNING "Ethernet not ready\n"); +} + +static struct resource smc911x_resources[] = { + [0] = { + .start = 0xa8000000, + .end = 0xabffffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 35, + .end = 35, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc911x_device = { + .name = "smc911x", + .id = -1, + .num_resources = ARRAY_SIZE(smc911x_resources), + .resource = smc911x_resources, +}; + +static struct resource heartbeat_resources[] = { + [0] = { + .start = PA_LED, + .end = PA_LED, + .flags = IORESOURCE_MEM, + }, +}; + +static struct heartbeat_data heartbeat_data = { + .flags = HEARTBEAT_INVERTED, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .dev = { + .platform_data = &heartbeat_data, + }, + .num_resources = ARRAY_SIZE(heartbeat_resources), + .resource = heartbeat_resources, +}; + +static struct mtd_partition *parsed_partitions; + +static struct mtd_partition mpr2_partitions[] = { + /* Reserved for bootloader, read-only */ + { + .name = "Bootloader", + .offset = 0x00000000UL, + .size = MPR2_MTD_BOOTLOADER_SIZE, + .mask_flags = MTD_WRITEABLE, + }, + /* Reserved for kernel image */ + { + .name = "Kernel", + .offset = MTDPART_OFS_NXTBLK, + .size = MPR2_MTD_KERNEL_SIZE, + }, + /* Rest is used for Flash FS */ + { + .name = "Flash_FS", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct physmap_flash_data flash_data = { + .width = 2, +}; + +static struct resource flash_resource = { + .start = 0x00000000, + .end = 0x2000000UL, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device flash_device = { + .name = "physmap-flash", + .id = -1, + .resource = &flash_resource, + .num_resources = 1, + .dev = { + .platform_data = &flash_data, + }, +}; + +static struct mtd_info *flash_mtd; + +static struct map_info mpr2_flash_map = { + .name = "Magic Panel R2 Flash", + .size = 0x2000000UL, + .bankwidth = 2, +}; + +static void __init set_mtd_partitions(void) +{ + int nr_parts = 0; + + simple_map_init(&mpr2_flash_map); + flash_mtd = do_map_probe("cfi_probe", &mpr2_flash_map); + nr_parts = parse_mtd_partitions(flash_mtd, probes, + &parsed_partitions, 0); + /* If there is no partition table, used the hard coded table */ + if (nr_parts <= 0) { + flash_data.parts = mpr2_partitions; + flash_data.nr_parts = ARRAY_SIZE(mpr2_partitions); + } else { + flash_data.nr_parts = nr_parts; + flash_data.parts = parsed_partitions; + } +} + +/* + * Add all resources to the platform_device + */ + +static struct platform_device *mpr2_devices[] __initdata = { + &heartbeat_device, + &smc911x_device, + &flash_device, +}; + + +static int __init mpr2_devices_setup(void) +{ + set_mtd_partitions(); + return platform_add_devices(mpr2_devices, ARRAY_SIZE(mpr2_devices)); +} +device_initcall(mpr2_devices_setup); + +/* + * Initialize IRQ setting + */ +static void __init init_mpr2_IRQ(void) +{ + plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-5 */ + + set_irq_type(32, IRQ_TYPE_LEVEL_LOW); /* IRQ0 CAN1 */ + set_irq_type(33, IRQ_TYPE_LEVEL_LOW); /* IRQ1 CAN2 */ + set_irq_type(34, IRQ_TYPE_LEVEL_LOW); /* IRQ2 CAN3 */ + set_irq_type(35, IRQ_TYPE_LEVEL_LOW); /* IRQ3 SMSC9115 */ + set_irq_type(36, IRQ_TYPE_EDGE_RISING); /* IRQ4 touchscreen */ + set_irq_type(37, IRQ_TYPE_EDGE_FALLING); /* IRQ5 touchscreen */ + + intc_set_priority(32, 13); /* IRQ0 CAN1 */ + intc_set_priority(33, 13); /* IRQ0 CAN2 */ + intc_set_priority(34, 13); /* IRQ0 CAN3 */ + intc_set_priority(35, 6); /* IRQ3 SMSC9115 */ +} + +/* + * The Machine Vector + */ + +static struct sh_machine_vector mv_mpr2 __initmv = { + .mv_name = "mpr2", + .mv_setup = mpr2_setup, + .mv_init_irq = init_mpr2_IRQ, +}; diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c index 8ce03e00b0ae..fede36361dc7 100644 --- a/arch/sh/boards/mpc1211/setup.c +++ b/arch/sh/boards/mpc1211/setup.c @@ -285,7 +285,7 @@ static int put_smb_blk(unsigned char *p, int address, int command, int no) static struct resource heartbeat_resources[] = { [0] = { .start = 0xa2000000, - .end = 0xa2000000 + 8 - 1, + .end = 0xa2000000, .flags = IORESOURCE_MEM, }, }; diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile index b1d20afb4eb3..dd26182fbf58 100644 --- a/arch/sh/boards/renesas/r7780rp/Makefile +++ b/arch/sh/boards/renesas/r7780rp/Makefile @@ -1,9 +1,10 @@ # # Makefile for the R7780RP-1 specific parts of the kernel # -irqinit-y := irq-r7780rp.o +irqinit-$(CONFIG_SH_R7780MP) := irq-r7780mp.o irqinit-$(CONFIG_SH_R7785RP) := irq-r7785rp.o -obj-y := setup.o irq.o $(irqinit-y) +irqinit-$(CONFIG_SH_R7780RP) := irq-r7780rp.o irq.o +obj-y := setup.o $(irqinit-y) ifneq ($(CONFIG_SH_R7785RP),y) obj-$(CONFIG_PUSH_SWITCH) += psw.o diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c new file mode 100644 index 000000000000..59b47fe061f9 --- /dev/null +++ b/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c @@ -0,0 +1,61 @@ +/* + * Renesas Solutions Highlander R7780MP Support. + * + * Copyright (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2007 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <asm/r7780rp.h> + +enum { + UNUSED = 0, + + /* board specific interrupt sources */ + AX88796, /* Ethernet controller */ + CF, /* Compact Flash */ + PSW, /* Push Switch */ + EXT1, /* EXT1n IRQ */ + EXT4, /* EXT4n IRQ */ +}; + +static struct intc_vect vectors[] __initdata = { + INTC_IRQ(CF, IRQ_CF), + INTC_IRQ(PSW, IRQ_PSW), + INTC_IRQ(AX88796, IRQ_AX88796), + INTC_IRQ(EXT1, IRQ_EXT1), + INTC_IRQ(EXT4, IRQ_EXT4), +}; + +static struct intc_mask_reg mask_registers[] __initdata = { + { 0xa4000000, 0, 16, /* IRLMSK */ + { 0, 0, 0, 0, CF, 0, 0, 0, + 0, 0, 0, EXT4, 0, EXT1, PSW, AX88796 } }, +}; + +static unsigned char irl2irq[HL_NR_IRL] __initdata = { + 0, IRQ_CF, 0, 0, + 0, 0, 0, 0, + 0, IRQ_EXT4, 0, IRQ_EXT1, + 0, IRQ_AX88796, IRQ_PSW, +}; + +static DECLARE_INTC_DESC(intc_desc, "r7780mp", vectors, + NULL, NULL, mask_registers, NULL, NULL); + +unsigned char * __init highlander_init_irq_r7780mp(void) +{ + if ((ctrl_inw(0xa4000700) & 0xf000) == 0x2000) { + printk(KERN_INFO "Using r7780mp interrupt controller.\n"); + register_intc_controller(&intc_desc); + return irl2irq; + } + + return NULL; +} diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c index f5f358746c9e..fa4a534cade9 100644 --- a/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c +++ b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c @@ -9,13 +9,15 @@ * for more details. */ #include <linux/init.h> -#include <asm/io.h> +#include <linux/io.h> #include <asm/r7780rp.h> -void __init highlander_init_irq(void) +unsigned char * __init highlander_init_irq_r7780rp(void) { int i; for (i = 0; i < 15; i++) make_r7780rp_irq(i); + + return NULL; } diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c index dd6ec4ce44dc..b2c6a84673bd 100644 --- a/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c +++ b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c @@ -1,19 +1,55 @@ /* - * Renesas Solutions Highlander R7780RP-1 Support. + * Renesas Solutions Highlander R7785RP Support. * * Copyright (C) 2002 Atom Create Engineering Co., Ltd. * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2007 Magnus Damm * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ #include <linux/init.h> -#include <asm/io.h> +#include <linux/irq.h> +#include <linux/io.h> #include <asm/r7780rp.h> -void __init highlander_init_irq(void) +enum { + UNUSED = 0, + + /* board specific interrupt sources */ + AX88796, /* Ethernet controller */ + CF, /* Compact Flash */ +}; + +static struct intc_vect vectors[] __initdata = { + INTC_IRQ(CF, IRQ_CF), + INTC_IRQ(AX88796, IRQ_AX88796), +}; + +static struct intc_mask_reg mask_registers[] __initdata = { + { 0xa4000010, 0, 16, /* IRLMCR1 */ + { 0, 0, 0, 0, CF, AX88796, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 } }, +}; + +static unsigned char irl2irq[HL_NR_IRL] __initdata = { + 0, IRQ_CF, 0, 0, + 0, 0, 0, 0, + 0, 0, IRQ_AX88796, 0, + 0, 0, 0, +}; + +static DECLARE_INTC_DESC(intc_desc, "r7785rp", vectors, + NULL, NULL, mask_registers, NULL, NULL); + +unsigned char * __init highlander_init_irq_r7785rp(void) { + if ((ctrl_inw(0xa4000158) & 0xf000) != 0x1000) + return NULL; + + printk(KERN_INFO "Using r7785rp interrupt controller.\n"); + ctrl_outw(0x0000, PA_IRLSSR1); /* FPGA IRLSSR1(CF_CD clear) */ /* Setup the FPGA IRL */ @@ -24,6 +60,6 @@ void __init highlander_init_irq(void) ctrl_outw(0x4321, PA_IRLPRE); /* FPGA IRLE */ ctrl_outw(0x0000, PA_IRLPRF); /* FPGA IRLF */ - make_r7780rp_irq(1); /* CF card */ - make_r7780rp_irq(10); /* On-board ethernet */ + register_intc_controller(&intc_desc); + return irl2irq; } diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c index adb529d01bae..afe9de73666a 100644 --- a/arch/sh/boards/renesas/r7780rp/setup.c +++ b/arch/sh/boards/renesas/r7780rp/setup.c @@ -19,6 +19,7 @@ #include <asm/machvec.h> #include <asm/r7780rp.h> #include <asm/clock.h> +#include <asm/heartbeat.h> #include <asm/io.h> static struct resource r8a66597_usb_host_resources[] = { @@ -30,8 +31,8 @@ static struct resource r8a66597_usb_host_resources[] = { }, [1] = { .name = "r8a66597_hcd", - .start = 11, /* irq number */ - .end = 11, + .start = IRQ_EXT1, /* irq number */ + .end = IRQ_EXT1, .flags = IORESOURCE_IRQ, }, }; @@ -56,8 +57,8 @@ static struct resource m66592_usb_peripheral_resources[] = { }, [1] = { .name = "m66592_udc", - .start = 9, /* irq number */ - .end = 9, + .start = IRQ_EXT4, /* irq number */ + .end = IRQ_EXT4, .flags = IORESOURCE_IRQ, }, }; @@ -85,11 +86,7 @@ static struct resource cf_ide_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { -#ifdef CONFIG_SH_R7780RP - .start = 4, -#else - .start = 1, -#endif + .start = IRQ_CF, .flags = IORESOURCE_IRQ, }, }; @@ -108,16 +105,23 @@ static struct platform_device cf_ide_device = { }, }; -static unsigned char heartbeat_bit_pos[] = { 2, 1, 0, 3, 6, 5, 4, 7 }; - static struct resource heartbeat_resources[] = { [0] = { .start = PA_OBLED, - .end = PA_OBLED + ARRAY_SIZE(heartbeat_bit_pos) - 1, + .end = PA_OBLED, .flags = IORESOURCE_MEM, }, }; +#ifndef CONFIG_SH_R7785RP +static unsigned char heartbeat_bit_pos[] = { 2, 1, 0, 3, 6, 5, 4, 7 }; + +static struct heartbeat_data heartbeat_data = { + .bit_pos = heartbeat_bit_pos, + .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), +}; +#endif + static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, @@ -125,7 +129,7 @@ static struct platform_device heartbeat_device = { /* R7785RP has a slightly more sensible FPGA.. */ #ifndef CONFIG_SH_R7785RP .dev = { - .platform_data = heartbeat_bit_pos, + .platform_data = &heartbeat_data, }, #endif .num_resources = ARRAY_SIZE(heartbeat_resources), @@ -217,12 +221,50 @@ static void __init highlander_setup(char **cmdline_p) pm_power_off = r7780rp_power_off; } +static unsigned char irl2irq[HL_NR_IRL]; + +int highlander_irq_demux(int irq) +{ + if (irq >= HL_NR_IRL || !irl2irq[irq]) + return irq; + + return irl2irq[irq]; +} + +void __init highlander_init_irq(void) +{ + unsigned char *ucp = NULL; + + do { +#ifdef CONFIG_SH_R7780MP + ucp = highlander_init_irq_r7780mp(); + if (ucp) + break; +#endif +#ifdef CONFIG_SH_R7785RP + ucp = highlander_init_irq_r7785rp(); + if (ucp) + break; +#endif +#ifdef CONFIG_SH_R7780RP + highlander_init_irq_r7780rp(); + ucp = irl2irq; + break; +#endif + } while (0); + + if (ucp) { + plat_irq_setup_pins(IRQ_MODE_IRL3210); + memcpy(irl2irq, ucp, HL_NR_IRL); + } +} + /* * The Machine Vector */ 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, + .mv_irq_demux = highlander_irq_demux, }; diff --git a/arch/sh/boards/renesas/rts7751r2d/Kconfig b/arch/sh/boards/renesas/rts7751r2d/Kconfig index 7780d1fb13ff..8122a9667fc9 100644 --- a/arch/sh/boards/renesas/rts7751r2d/Kconfig +++ b/arch/sh/boards/renesas/rts7751r2d/Kconfig @@ -1,11 +1,22 @@ if SH_RTS7751R2D -menu "RTS7751R2D options" +menu "RTS7751R2D Board Revision" -config RTS7751R2D_REV11 - bool "RTS7751R2D Rev. 1.1 board support" +config RTS7751R2D_PLUS + bool "R2D-PLUS" help - Selecting this option will support version rev. 1.1. + Selecting this option will configure the kernel for R2D-PLUS. + + R2D-PLUS is the smaller of the two R2D board versions, equipped + with a single PCI slot. + +config RTS7751R2D_1 + bool "R2D-1" + help + Selecting this option will configure the kernel for R2D-1. + + R2D-1 is the larger of the two R2D board versions, equipped + with two PCI slots. endmenu endif diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c index 0bae9041aceb..7cc2813adfe4 100644 --- a/arch/sh/boards/renesas/rts7751r2d/irq.c +++ b/arch/sh/boards/renesas/rts7751r2d/irq.c @@ -1,84 +1,159 @@ /* * linux/arch/sh/boards/renesas/rts7751r2d/irq.c * + * Copyright (C) 2007 Magnus Damm * Copyright (C) 2000 Kazumoto Kojima * - * Renesas Technology Sales RTS7751R2D Support. + * Renesas Technology Sales RTS7751R2D Support, R2D-PLUS and R2D-1. * * Modified for RTS7751R2D by * Atom Create Engineering Co., Ltd. 2002. */ #include <linux/init.h> -#include <linux/interrupt.h> #include <linux/irq.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <asm/voyagergx.h> #include <asm/rts7751r2d.h> -#if defined(CONFIG_RTS7751R2D_REV11) -static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0}; -#else -static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0}; -#endif +#define R2D_NR_IRL 13 -extern int voyagergx_irq_demux(int irq); -extern void setup_voyagergx_irq(void); +enum { + UNUSED = 0, -static void enable_rts7751r2d_irq(unsigned int irq) -{ - /* Set priority in IPR back to original value */ - ctrl_outw(ctrl_inw(IRLCNTR1) | (1 << mask_pos[irq]), IRLCNTR1); -} + /* board specific interrupt sources (R2D-1 and R2D-PLUS) */ + EXT, /* EXT_INT0-3 */ + RTC_T, RTC_A, /* Real Time Clock */ + AX88796, /* Ethernet controller (R2D-1 board) */ + KEY, /* Key input (R2D-PLUS board) */ + SDCARD, /* SD Card */ + CF_CD, CF_IDE, /* CF Card Detect + CF IDE */ + SM501, /* SM501 aka Voyager */ + PCI_INTD_RTL8139, /* Ethernet controller */ + PCI_INTC_PCI1520, /* Cardbus/PCMCIA bridge */ + PCI_INTB_RTL8139, /* Ethernet controller with HUB (R2D-PLUS board) */ + PCI_INTB_SLOT, /* PCI Slot 3.3v (R2D-1 board) */ + PCI_INTA_SLOT, /* PCI Slot 3.3v */ + TP, /* Touch Panel */ +}; -static void disable_rts7751r2d_irq(unsigned int irq) -{ - /* Set the priority in IPR to 0 */ - ctrl_outw(ctrl_inw(IRLCNTR1) & (0xffff ^ (1 << mask_pos[irq])), - IRLCNTR1); -} +#ifdef CONFIG_RTS7751R2D_1 + +/* Vectors for R2D-1 */ +static struct intc_vect vectors_r2d_1[] __initdata = { + INTC_IRQ(EXT, IRQ_EXT), + INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A), + INTC_IRQ(AX88796, IRQ_AX88796), INTC_IRQ(SDCARD, IRQ_SDCARD), + INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE), /* ng */ + INTC_IRQ(SM501, IRQ_VOYAGER), + INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD), + INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC), + INTC_IRQ(PCI_INTB_SLOT, IRQ_PCI_INTB), + INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA), + INTC_IRQ(TP, IRQ_TP), +}; + +/* IRLMSK mask register layout for R2D-1 */ +static struct intc_mask_reg mask_registers_r2d_1[] __initdata = { + { 0xa4000000, 0, 16, /* IRLMSK */ + { TP, PCI_INTA_SLOT, PCI_INTB_SLOT, + PCI_INTC_PCI1520, PCI_INTD_RTL8139, + SM501, CF_IDE, CF_CD, SDCARD, AX88796, + RTC_A, RTC_T, 0, 0, 0, EXT } }, +}; + +/* IRLn to IRQ table for R2D-1 */ +static unsigned char irl2irq_r2d_1[R2D_NR_IRL] __initdata = { + IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC, + IRQ_VOYAGER, IRQ_AX88796, IRQ_RTC_A, IRQ_RTC_T, + IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT, + IRQ_TP, +}; + +static DECLARE_INTC_DESC(intc_desc_r2d_1, "r2d-1", vectors_r2d_1, + NULL, NULL, mask_registers_r2d_1, NULL, NULL); + +#endif /* CONFIG_RTS7751R2D_1 */ + +#ifdef CONFIG_RTS7751R2D_PLUS + +/* Vectors for R2D-PLUS */ +static struct intc_vect vectors_r2d_plus[] __initdata = { + INTC_IRQ(EXT, IRQ_EXT), + INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A), + INTC_IRQ(KEY, IRQ_KEY), INTC_IRQ(SDCARD, IRQ_SDCARD), + INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE), + INTC_IRQ(SM501, IRQ_VOYAGER), + INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD), + INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC), + INTC_IRQ(PCI_INTB_RTL8139, IRQ_PCI_INTB), + INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA), + INTC_IRQ(TP, IRQ_TP), +}; + +/* IRLMSK mask register layout for R2D-PLUS */ +static struct intc_mask_reg mask_registers_r2d_plus[] __initdata = { + { 0xa4000000, 0, 16, /* IRLMSK */ + { TP, PCI_INTA_SLOT, PCI_INTB_RTL8139, + PCI_INTC_PCI1520, PCI_INTD_RTL8139, + SM501, CF_IDE, CF_CD, SDCARD, KEY, + RTC_A, RTC_T, 0, 0, 0, EXT } }, +}; + +/* IRLn to IRQ table for R2D-PLUS */ +static unsigned char irl2irq_r2d_plus[R2D_NR_IRL] __initdata = { + IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC, + IRQ_VOYAGER, IRQ_KEY, IRQ_RTC_A, IRQ_RTC_T, + IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT, + IRQ_TP, +}; + +static DECLARE_INTC_DESC(intc_desc_r2d_plus, "r2d-plus", vectors_r2d_plus, + NULL, NULL, mask_registers_r2d_plus, NULL, NULL); + +#endif /* CONFIG_RTS7751R2D_PLUS */ + +static unsigned char irl2irq[R2D_NR_IRL]; int rts7751r2d_irq_demux(int irq) { - return voyagergx_irq_demux(irq); -} + if (irq >= R2D_NR_IRL || !irl2irq[irq]) + return irq; -static struct irq_chip rts7751r2d_irq_chip __read_mostly = { - .name = "rts7751r2d", - .mask = disable_rts7751r2d_irq, - .unmask = enable_rts7751r2d_irq, - .mask_ack = disable_rts7751r2d_irq, -}; + return irl2irq[irq]; +} /* * Initialize IRQ setting */ void __init init_rts7751r2d_IRQ(void) { - int i; - - /* IRL0=KEY Input - * IRL1=Ethernet - * IRL2=CF Card - * IRL3=CF Card Insert - * IRL4=PCMCIA - * IRL5=VOYAGER - * IRL6=RTC Alarm - * IRL7=RTC Timer - * IRL8=SD Card - * IRL9=PCI Slot #1 - * IRL10=PCI Slot #2 - * IRL11=Extention #0 - * IRL12=Extention #1 - * IRL13=Extention #2 - * IRL14=Extention #3 - */ - - for (i=0; i<15; i++) { - disable_irq_nosync(i); - set_irq_chip_and_handler_name(i, &rts7751r2d_irq_chip, - handle_level_irq, "level"); - enable_rts7751r2d_irq(i); + struct intc_desc *d; + + switch (ctrl_inw(PA_VERREG) & 0xf0) { +#ifdef CONFIG_RTS7751R2D_PLUS + case 0x10: + printk(KERN_INFO "Using R2D-PLUS interrupt controller.\n"); + d = &intc_desc_r2d_plus; + memcpy(irl2irq, irl2irq_r2d_plus, R2D_NR_IRL); + break; +#endif +#ifdef CONFIG_RTS7751R2D_1 + case 0x00: /* according to manual */ + case 0x30: /* in reality */ + printk(KERN_INFO "Using R2D-1 interrupt controller.\n"); + d = &intc_desc_r2d_1; + memcpy(irl2irq, irl2irq_r2d_1, R2D_NR_IRL); + break; +#endif + default: + printk(KERN_INFO "Unknown R2D interrupt controller 0x%04x\n", + ctrl_inw(PA_VERREG)); + return; } + register_intc_controller(d); +#ifdef CONFIG_MFD_SM501 setup_voyagergx_irq(); +#endif } diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c index 6f7029d33241..37f2c0b447fe 100644 --- a/arch/sh/boards/renesas/rts7751r2d/setup.c +++ b/arch/sh/boards/renesas/rts7751r2d/setup.c @@ -45,20 +45,16 @@ static void __init voyagergx_serial_init(void) static struct resource cf_ide_resources[] = { [0] = { .start = PA_AREA5_IO + 0x1000, - .end = PA_AREA5_IO + 0x1000 + 0x08 - 1, + .end = PA_AREA5_IO + 0x1000 + 0x10 - 0x2, .flags = IORESOURCE_MEM, }, [1] = { .start = PA_AREA5_IO + 0x80c, - .end = PA_AREA5_IO + 0x80c + 0x16 - 1, + .end = PA_AREA5_IO + 0x80c, .flags = IORESOURCE_MEM, }, [2] = { -#ifdef CONFIG_RTS7751R2D_REV11 - .start = 1, -#else - .start = 2, -#endif + .start = IRQ_CF_IDE, .flags = IORESOURCE_IRQ, }, }; @@ -77,12 +73,28 @@ static struct platform_device cf_ide_device = { }, }; +static struct resource heartbeat_resources[] = { + [0] = { + .start = PA_OUTPORT, + .end = PA_OUTPORT, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .num_resources = ARRAY_SIZE(heartbeat_resources), + .resource = heartbeat_resources, +}; + +#ifdef CONFIG_MFD_SM501 static struct plat_serial8250_port uart_platform_data[] = { { .membase = (void __iomem *)VOYAGER_UART_BASE, .mapbase = VOYAGER_UART_BASE, .iotype = UPIO_MEM, - .irq = VOYAGER_UART0_IRQ, + .irq = IRQ_SM501_U0, .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, .regshift = 2, .uartclk = (9600 * 16), @@ -98,21 +110,6 @@ static struct platform_device uart_device = { }, }; -static struct resource heartbeat_resources[] = { - [0] = { - .start = PA_OUTPORT, - .end = PA_OUTPORT + 8 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device heartbeat_device = { - .name = "heartbeat", - .id = -1, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, -}; - static struct resource sm501_resources[] = { [0] = { .start = 0x10000000, @@ -125,7 +122,7 @@ static struct resource sm501_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { - .start = 32, + .start = IRQ_SM501_CV, .flags = IORESOURCE_IRQ, }, }; @@ -137,22 +134,19 @@ static struct platform_device sm501_device = { .resource = sm501_resources, }; +#endif /* CONFIG_MFD_SM501 */ + static struct platform_device *rts7751r2d_devices[] __initdata = { +#ifdef CONFIG_MFD_SM501 &uart_device, - &heartbeat_device, &sm501_device, +#endif + &cf_ide_device, + &heartbeat_device, }; static int __init rts7751r2d_devices_setup(void) { - int ret; - - if (ctrl_inw(PA_BVERREG) == 0x10) { /* only working on R2D-PLUS */ - ret = platform_device_register(&cf_ide_device); - if (ret) - return ret; - } - return platform_add_devices(rts7751r2d_devices, ARRAY_SIZE(rts7751r2d_devices)); } @@ -163,6 +157,34 @@ static void rts7751r2d_power_off(void) ctrl_outw(0x0001, PA_POWOFF); } +static inline unsigned char is_ide_ioaddr(unsigned long addr) +{ + return ((cf_ide_resources[0].start <= addr && + addr <= cf_ide_resources[0].end) || + (cf_ide_resources[1].start <= addr && + addr <= cf_ide_resources[1].end)); +} + +void rts7751r2d_writeb(u8 b, void __iomem *addr) +{ + unsigned long tmp = (unsigned long __force)addr; + + if (is_ide_ioaddr(tmp)) + ctrl_outw((u16)b, tmp); + else + ctrl_outb(b, tmp); +} + +u8 rts7751r2d_readb(void __iomem *addr) +{ + unsigned long tmp = (unsigned long __force)addr; + + if (is_ide_ioaddr(tmp)) + return ctrl_inw(tmp) & 0xff; + else + return ctrl_inb(tmp); +} + /* * Initialize the board */ @@ -187,12 +209,11 @@ static void __init rts7751r2d_setup(char **cmdline_p) static struct sh_machine_vector mv_rts7751r2d __initmv = { .mv_name = "RTS7751R2D", .mv_setup = rts7751r2d_setup, - .mv_nr_irqs = 72, - .mv_init_irq = init_rts7751r2d_IRQ, .mv_irq_demux = rts7751r2d_irq_demux, - -#ifdef CONFIG_USB_SM501 + .mv_writeb = rts7751r2d_writeb, + .mv_readb = rts7751r2d_readb, +#if defined(CONFIG_MFD_SM501) && defined(CONFIG_USB_OHCI_HCD) .mv_consistent_alloc = voyagergx_consistent_alloc, .mv_consistent_free = voyagergx_consistent_free, #endif diff --git a/arch/sh/boards/renesas/x3proto/Makefile b/arch/sh/boards/renesas/x3proto/Makefile new file mode 100644 index 000000000000..983e4551fecf --- /dev/null +++ b/arch/sh/boards/renesas/x3proto/Makefile @@ -0,0 +1 @@ +obj-y += setup.o ilsel.o diff --git a/arch/sh/boards/renesas/x3proto/ilsel.c b/arch/sh/boards/renesas/x3proto/ilsel.c new file mode 100644 index 000000000000..6d4454fef97c --- /dev/null +++ b/arch/sh/boards/renesas/x3proto/ilsel.c @@ -0,0 +1,151 @@ +/* + * arch/sh/boards/renesas/x3proto/ilsel.c + * + * Helper routines for SH-X3 proto board ILSEL. + * + * 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/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/bitmap.h> +#include <linux/io.h> +#include <asm/ilsel.h> + +/* + * ILSEL is split across: + * + * ILSEL0 - 0xb8100004 [ Levels 1 - 4 ] + * ILSEL1 - 0xb8100006 [ Levels 5 - 8 ] + * ILSEL2 - 0xb8100008 [ Levels 9 - 12 ] + * ILSEL3 - 0xb810000a [ Levels 13 - 15 ] + * + * With each level being relative to an ilsel_source_t. + */ +#define ILSEL_BASE 0xb8100004 +#define ILSEL_LEVELS 15 + +/* + * ILSEL level map, in descending order from the highest level down. + * + * Supported levels are 1 - 15 spread across ILSEL0 - ILSEL4, mapping + * directly to IRLs. As the IRQs are numbered in reverse order relative + * to the interrupt level, the level map is carefully managed to ensure a + * 1:1 mapping between the bit position and the IRQ number. + * + * This careful constructions allows ilsel_enable*() to be referenced + * directly for hooking up an ILSEL set and getting back an IRQ which can + * subsequently be used for internal accounting in the (optional) disable + * path. + */ +static unsigned long ilsel_level_map; + +static inline unsigned int ilsel_offset(unsigned int bit) +{ + return ILSEL_LEVELS - bit - 1; +} + +static inline unsigned long mk_ilsel_addr(unsigned int bit) +{ + return ILSEL_BASE + ((ilsel_offset(bit) >> 1) & ~0x1); +} + +static inline unsigned int mk_ilsel_shift(unsigned int bit) +{ + return (ilsel_offset(bit) & 0x3) << 2; +} + +static void __ilsel_enable(ilsel_source_t set, unsigned int bit) +{ + unsigned int tmp, shift; + unsigned long addr; + + addr = mk_ilsel_addr(bit); + shift = mk_ilsel_shift(bit); + + pr_debug("%s: bit#%d: addr - 0x%08lx (shift %d, set %d)\n", + __FUNCTION__, bit, addr, shift, set); + + tmp = ctrl_inw(addr); + tmp &= ~(0xf << shift); + tmp |= set << shift; + ctrl_outw(tmp, addr); +} + +/** + * ilsel_enable - Enable an ILSEL set. + * @set: ILSEL source (see ilsel_source_t enum in include/asm-sh/ilsel.h). + * + * Enables a given non-aliased ILSEL source (<= ILSEL_KEY) at the highest + * available interrupt level. Callers should take care to order callsites + * noting descending interrupt levels. Aliasing FPGA and external board + * IRQs need to use ilsel_enable_fixed(). + * + * The return value is an IRQ number that can later be taken down with + * ilsel_disable(). + */ +int ilsel_enable(ilsel_source_t set) +{ + unsigned int bit; + + /* Aliased sources must use ilsel_enable_fixed() */ + BUG_ON(set > ILSEL_KEY); + + do { + bit = find_first_zero_bit(&ilsel_level_map, ILSEL_LEVELS); + } while (test_and_set_bit(bit, &ilsel_level_map)); + + __ilsel_enable(set, bit); + + return bit; +} +EXPORT_SYMBOL_GPL(ilsel_enable); + +/** + * ilsel_enable_fixed - Enable an ILSEL set at a fixed interrupt level + * @set: ILSEL source (see ilsel_source_t enum in include/asm-sh/ilsel.h). + * @level: Interrupt level (1 - 15) + * + * Enables a given ILSEL source at a fixed interrupt level. Necessary + * both for level reservation as well as for aliased sources that only + * exist on special ILSEL#s. + * + * Returns an IRQ number (as ilsel_enable()). + */ +int ilsel_enable_fixed(ilsel_source_t set, unsigned int level) +{ + unsigned int bit = ilsel_offset(level - 1); + + if (test_and_set_bit(bit, &ilsel_level_map)) + return -EBUSY; + + __ilsel_enable(set, bit); + + return bit; +} +EXPORT_SYMBOL_GPL(ilsel_enable_fixed); + +/** + * ilsel_disable - Disable an ILSEL set + * @irq: Bit position for ILSEL set value (retval from enable routines) + * + * Disable a previously enabled ILSEL set. + */ +void ilsel_disable(unsigned int irq) +{ + unsigned long addr; + unsigned int tmp; + + addr = mk_ilsel_addr(irq); + + tmp = ctrl_inw(addr); + tmp &= ~(0xf << mk_ilsel_shift(irq)); + ctrl_outw(tmp, addr); + + clear_bit(irq, &ilsel_level_map); +} +EXPORT_SYMBOL_GPL(ilsel_disable); diff --git a/arch/sh/boards/renesas/x3proto/setup.c b/arch/sh/boards/renesas/x3proto/setup.c new file mode 100644 index 000000000000..abc5b6d418fe --- /dev/null +++ b/arch/sh/boards/renesas/x3proto/setup.c @@ -0,0 +1,136 @@ +/* + * arch/sh/boards/renesas/x3proto/setup.c + * + * Renesas SH-X3 Prototype Board Support. + * + * 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/init.h> +#include <linux/platform_device.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <asm/ilsel.h> + +static struct resource heartbeat_resources[] = { + [0] = { + .start = 0xb8140020, + .end = 0xb8140020, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .num_resources = ARRAY_SIZE(heartbeat_resources), + .resource = heartbeat_resources, +}; + +static struct resource smc91x_resources[] = { + [0] = { + .start = 0x18000300, + .end = 0x18000300 + 0x10 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + /* Filled in by ilsel */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = -1, + .resource = smc91x_resources, + .num_resources = ARRAY_SIZE(smc91x_resources), +}; + +static struct resource r8a66597_usb_host_resources[] = { + [0] = { + .name = "r8a66597_hcd", + .start = 0x18040000, + .end = 0x18080000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "r8a66597_hcd", + /* Filled in by ilsel */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device r8a66597_usb_host_device = { + .name = "r8a66597_hcd", + .id = -1, + .dev = { + .dma_mask = NULL, /* don't use dma */ + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(r8a66597_usb_host_resources), + .resource = r8a66597_usb_host_resources, +}; + +static struct resource m66592_usb_peripheral_resources[] = { + [0] = { + .name = "m66592_udc", + .start = 0x18080000, + .end = 0x180c0000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "m66592_udc", + /* Filled in by ilsel */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device m66592_usb_peripheral_device = { + .name = "m66592_udc", + .id = -1, + .dev = { + .dma_mask = NULL, /* don't use dma */ + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources), + .resource = m66592_usb_peripheral_resources, +}; + +static struct platform_device *x3proto_devices[] __initdata = { + &heartbeat_device, + &smc91x_device, + &r8a66597_usb_host_device, + &m66592_usb_peripheral_device, +}; + +static int __init x3proto_devices_setup(void) +{ + r8a66597_usb_host_resources[1].start = + r8a66597_usb_host_resources[1].end = ilsel_enable(ILSEL_USBH_I); + + m66592_usb_peripheral_resources[1].start = + m66592_usb_peripheral_resources[1].end = ilsel_enable(ILSEL_USBP_I); + + smc91x_resources[1].start = + smc91x_resources[1].end = ilsel_enable(ILSEL_LAN); + + return platform_add_devices(x3proto_devices, + ARRAY_SIZE(x3proto_devices)); +} +device_initcall(x3proto_devices_setup); + +static void __init x3proto_init_irq(void) +{ + plat_irq_setup_pins(IRQ_MODE_IRL3210); + + /* Set ICR0.LVLMODE */ + ctrl_outl(ctrl_inl(0xfe410000) | (1 << 21), 0xfe410000); +} + +static struct sh_machine_vector mv_x3proto __initmv = { + .mv_name = "x3proto", + .mv_init_irq = x3proto_init_irq, +}; diff --git a/arch/sh/boards/se/7206/io.c b/arch/sh/boards/se/7206/io.c index b557273e0cbe..1308e618e044 100644 --- a/arch/sh/boards/se/7206/io.c +++ b/arch/sh/boards/se/7206/io.c @@ -26,22 +26,24 @@ static inline void delay(void) static inline volatile __u16 * port2adr(unsigned int port) { - if (port >= 0x2000) + if (port >= 0x2000 && port < 0x2020) return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); - else if (port >= 0x300 || port < 0x310) + else if (port >= 0x300 && port < 0x310) return (volatile __u16 *) (PA_SMSC + (port - 0x300)); + + return (volatile __u16 *)port; } unsigned char se7206_inb(unsigned long port) { - return (*port2adr(port))&0xff; + return (*port2adr(port)) & 0xff; } unsigned char se7206_inb_p(unsigned long port) { unsigned long v; - v = (*port2adr(port))&0xff; + v = (*port2adr(port)) & 0xff; delay(); return v; } @@ -51,12 +53,6 @@ unsigned short se7206_inw(unsigned long port) return *port2adr(port);; } -unsigned int se7206_inl(unsigned long port) -{ - maybebadio(port); - return 0; -} - void se7206_outb(unsigned char value, unsigned long port) { *(port2adr(port)) = value; @@ -73,11 +69,6 @@ void se7206_outw(unsigned short value, unsigned long port) *port2adr(port) = value; } -void se7206_outl(unsigned int value, unsigned long port) -{ - maybebadio(port); -} - void se7206_insb(unsigned long port, void *addr, unsigned long count) { volatile __u16 *p = port2adr(port); @@ -95,11 +86,6 @@ void se7206_insw(unsigned long port, void *addr, unsigned long count) *ap++ = *p; } -void se7206_insl(unsigned long port, void *addr, unsigned long count) -{ - maybebadio(port); -} - void se7206_outsb(unsigned long port, const void *addr, unsigned long count) { volatile __u16 *p = port2adr(port); @@ -116,8 +102,3 @@ void se7206_outsw(unsigned long port, const void *addr, unsigned long count) while (count--) *p = *ap++; } - -void se7206_outsl(unsigned long port, const void *addr, unsigned long count) -{ - maybebadio(port); -} diff --git a/arch/sh/boards/se/7206/setup.c b/arch/sh/boards/se/7206/setup.c index a074b62505ef..5b3ee089d91d 100644 --- a/arch/sh/boards/se/7206/setup.c +++ b/arch/sh/boards/se/7206/setup.c @@ -6,14 +6,13 @@ * Copyright (C) 2007 Paul Mundt * * Hitachi 7206 SolutionEngine Support. - * */ - #include <linux/init.h> #include <linux/platform_device.h> #include <asm/se7206.h> #include <asm/io.h> #include <asm/machvec.h> +#include <asm/heartbeat.h> static struct resource smc91x_resources[] = { [0] = { @@ -37,10 +36,16 @@ static struct platform_device smc91x_device = { static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; +static struct heartbeat_data heartbeat_data = { + .bit_pos = heartbeat_bit_pos, + .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), + .regsize = 32, +}; + static struct resource heartbeat_resources[] = { [0] = { .start = PA_LED, - .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1, + .end = PA_LED, .flags = IORESOURCE_MEM, }, }; @@ -49,7 +54,7 @@ static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, .dev = { - .platform_data = heartbeat_bit_pos, + .platform_data = &heartbeat_data, }, .num_resources = ARRAY_SIZE(heartbeat_resources), .resource = heartbeat_resources, @@ -75,24 +80,18 @@ static struct sh_machine_vector mv_se __initmv = { .mv_nr_irqs = 256, .mv_inb = se7206_inb, .mv_inw = se7206_inw, - .mv_inl = se7206_inl, .mv_outb = se7206_outb, .mv_outw = se7206_outw, - .mv_outl = se7206_outl, .mv_inb_p = se7206_inb_p, .mv_inw_p = se7206_inw, - .mv_inl_p = se7206_inl, .mv_outb_p = se7206_outb_p, .mv_outw_p = se7206_outw, - .mv_outl_p = se7206_outl, .mv_insb = se7206_insb, .mv_insw = se7206_insw, - .mv_insl = se7206_insl, .mv_outsb = se7206_outsb, .mv_outsw = se7206_outsw, - .mv_outsl = se7206_outsl, .mv_init_irq = init_se7206_IRQ, }; diff --git a/arch/sh/boards/se/7343/irq.c b/arch/sh/boards/se/7343/irq.c index 360153ecc55b..763f6deba814 100644 --- a/arch/sh/boards/se/7343/irq.c +++ b/arch/sh/boards/se/7343/irq.c @@ -99,8 +99,11 @@ shmse_irq_demux(int irq) * * We configure IRQ5 as a cascade IRQ. */ -static struct irqaction irq5 = { no_action, 0, CPU_MASK_NONE, "IRQ5-cascade", - NULL, NULL}; +static struct irqaction irq5 = { + .handler = no_action, + .mask = CPU_MASK_NONE, + .name = "IRQ5-cascade", +}; static struct ipr_data se7343_irq5_ipr_map[] = { { IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY }, diff --git a/arch/sh/boards/se/7343/setup.c b/arch/sh/boards/se/7343/setup.c index 8fec155e2ff7..c9431b3a051b 100644 --- a/arch/sh/boards/se/7343/setup.c +++ b/arch/sh/boards/se/7343/setup.c @@ -33,7 +33,7 @@ static struct platform_device smc91x_device = { static struct resource heartbeat_resources[] = { [0] = { .start = PA_LED, - .end = PA_LED + 8 - 1, + .end = PA_LED, .flags = IORESOURCE_MEM, }, }; diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c index 2962da148f3f..d07a3368f546 100644 --- a/arch/sh/boards/se/770x/setup.c +++ b/arch/sh/boards/se/770x/setup.c @@ -12,6 +12,7 @@ #include <asm/se.h> #include <asm/io.h> #include <asm/smc37c93x.h> +#include <asm/heartbeat.h> void init_se_IRQ(void); @@ -90,10 +91,15 @@ static struct platform_device cf_ide_device = { static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; +static struct heartbeat_data heartbeat_data = { + .bit_pos = heartbeat_bit_pos, + .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), +}; + static struct resource heartbeat_resources[] = { [0] = { .start = PA_LED, - .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1, + .end = PA_LED, .flags = IORESOURCE_MEM, }, }; @@ -102,7 +108,7 @@ static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, .dev = { - .platform_data = heartbeat_bit_pos, + .platform_data = &heartbeat_data, }, .num_resources = ARRAY_SIZE(heartbeat_resources), .resource = heartbeat_resources, diff --git a/arch/sh/boards/se/7722/setup.c b/arch/sh/boards/se/7722/setup.c index 495fc7e2b60f..03b63457e178 100644 --- a/arch/sh/boards/se/7722/setup.c +++ b/arch/sh/boards/se/7722/setup.c @@ -18,12 +18,10 @@ #include <asm/io.h> /* Heartbeat */ -static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - static struct resource heartbeat_resources[] = { [0] = { .start = PA_LED, - .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1, + .end = PA_LED, .flags = IORESOURCE_MEM, }, }; @@ -31,9 +29,6 @@ static struct resource heartbeat_resources[] = { static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - .dev = { - .platform_data = heartbeat_bit_pos, - }, .num_resources = ARRAY_SIZE(heartbeat_resources), .resource = heartbeat_resources, }; @@ -109,7 +104,7 @@ static void __init se7722_setup(char **cmdline_p) ctrl_outl(0x00051001, MSTPCR0); ctrl_outl(0x00000000, MSTPCR1); /* KEYSC, VOU, BEU, CEU, VEU, VPU, LCDC */ - ctrl_outl(0xffffbfC0, MSTPCR2); + ctrl_outl(0xffffbfC0, MSTPCR2); ctrl_outw(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */ ctrl_outw(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */ diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c index 7873d07e40c1..deefbfd92591 100644 --- a/arch/sh/boards/se/7751/setup.c +++ b/arch/sh/boards/se/7751/setup.c @@ -13,13 +13,19 @@ #include <asm/machvec.h> #include <asm/se7751.h> #include <asm/io.h> +#include <asm/heartbeat.h> static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; +static struct heartbeat_data heartbeat_data = { + .bit_pos = heartbeat_bit_pos, + .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), +}; + static struct resource heartbeat_resources[] = { [0] = { .start = PA_LED, - .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1, + .end = PA_LED, .flags = IORESOURCE_MEM, }, }; @@ -28,14 +34,13 @@ static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, .dev = { - .platform_data = heartbeat_bit_pos, + .platform_data = &heartbeat_data, }, .num_resources = ARRAY_SIZE(heartbeat_resources), .resource = heartbeat_resources, }; static struct platform_device *se7751_devices[] __initdata = { - &smc91x_device, &heartbeat_device, }; diff --git a/arch/sh/boards/se/7780/irq.c b/arch/sh/boards/se/7780/irq.c index 874914746009..6bd70da6bb47 100644 --- a/arch/sh/boards/se/7780/irq.c +++ b/arch/sh/boards/se/7780/irq.c @@ -16,32 +16,6 @@ #include <asm/io.h> #include <asm/se7780.h> -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 */ - { 6, 0, 29, 0, 29, 3 }, /* daughter board EXTINT3 */ - { 8, 0, 28, 0, 28, 3 }, /* SMC 91C111 (LAN) */ - { 10, 0, 27, 0, 27, 3 }, /* daughter board EXTINT4 */ - { 4, 0, 30, 0, 30, 3 }, /* daughter board EXTINT5 */ - { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT6 */ - { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT7 */ - { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT8 */ - { 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 */ @@ -68,5 +42,5 @@ void __init init_se7780_IRQ(void) /* FPGA + 0x0A */ ctrl_outw((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3); - register_intc2_controller(&intc2_irq_desc); + plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-7 */ } diff --git a/arch/sh/boards/se/7780/setup.c b/arch/sh/boards/se/7780/setup.c index 723f2fd4d55b..76e53b26a808 100644 --- a/arch/sh/boards/se/7780/setup.c +++ b/arch/sh/boards/se/7780/setup.c @@ -16,12 +16,10 @@ #include <asm/io.h> /* Heartbeat */ -static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - static struct resource heartbeat_resources[] = { [0] = { .start = PA_LED, - .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1, + .end = PA_LED, .flags = IORESOURCE_MEM, }, }; @@ -29,9 +27,6 @@ static struct resource heartbeat_resources[] = { static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - .dev = { - .platform_data = heartbeat_bit_pos, - }, .num_resources = ARRAY_SIZE(heartbeat_resources), .resource = heartbeat_resources, }; diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c index 9c031a8c0a1c..934ac4f1c48f 100644 --- a/arch/sh/boards/sh03/setup.c +++ b/arch/sh/boards/sh03/setup.c @@ -15,33 +15,9 @@ #include <asm/sh03/sh03.h> #include <asm/addrspace.h> -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); - register_ipr_controller(&ipr_irq_desc); + plat_irq_setup_pins(IRQ_MODE_IRQ); } extern void *cf_io_base; @@ -68,7 +44,7 @@ static void __init sh03_setup(char **cmdline_p) static struct resource heartbeat_resources[] = { [0] = { .start = 0xa0800000, - .end = 0xa0800000 + 8 - 1, + .end = 0xa0800000, .flags = IORESOURCE_MEM, }, }; diff --git a/arch/sh/boards/shmin/setup.c b/arch/sh/boards/shmin/setup.c index dfd124509f42..16e5dae8ecfb 100644 --- a/arch/sh/boards/shmin/setup.c +++ b/arch/sh/boards/shmin/setup.c @@ -14,36 +14,12 @@ #define PFC_PHCR 0xa400010eUL #define INTC_ICR1 0xa4000010UL -#define INTC_IPRC 0xa4000016UL - -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. - register_ipr_controller(&ipr_irq_desc); + plat_irq_setup_pins(IRQ_MODE_IRQ); } static void __iomem *shmin_ioport_map(unsigned long port, unsigned int size) diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c index 84271d85a8dd..2b594f600002 100644 --- a/arch/sh/boards/snapgear/setup.c +++ b/arch/sh/boards/snapgear/setup.c @@ -68,37 +68,11 @@ module_init(eraseconfig_init); * IRL3 = crypto */ -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) { - /* enable individual interrupt mode for externals */ - ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); - printk("Setup SnapGear IRQ/IPR ...\n"); - - register_ipr_controller(&ipr_irq_desc); + /* enable individual interrupt mode for externals */ + plat_irq_setup_pins(IRQ_MODE_IRQ); } /* diff --git a/arch/sh/boards/titan/setup.c b/arch/sh/boards/titan/setup.c index 606d25a4b870..5de3b2ad71af 100644 --- a/arch/sh/boards/titan/setup.c +++ b/arch/sh/boards/titan/setup.c @@ -12,38 +12,10 @@ #include <asm/titan.h> #include <asm/io.h> -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) */ - { TITAN_IRQ_MPCIA, 3, 4, 8 }, /* mPCI A (top) */ - { 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 */ - register_ipr_controller(&ipr_irq_desc); + plat_irq_setup_pins(IRQ_MODE_IRQ); } static struct sh_machine_vector mv_titan __initmv = { diff --git a/arch/sh/cchips/Kconfig b/arch/sh/cchips/Kconfig index 2e516e9a6ede..7892361eedc8 100644 --- a/arch/sh/cchips/Kconfig +++ b/arch/sh/cchips/Kconfig @@ -1,18 +1,5 @@ menu "Companion Chips" -config VOYAGERGX - bool "VoyagerGX chip support" - depends on SH_RTS7751R2D - help - Selecting this option will support Silicon Motion, Inc. SM501. - Designed to complement needs for the embedded industry, it - provides video and 2D capability. To reduce system cost a - wide variety of include I/O is supported, including analog RGB - and digital LCD Panel interface, 8-bit parallel interface, USB, - UART, IrDA, Zoom Video, AC97 or I2S, SSP, PWM, and I2C. There - are additional GPIO bits that can be used to interface to - external as well. - config HD6446X_SERIES bool diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c index 97f6512aa1b7..f1a4a0763c59 100644 --- a/arch/sh/cchips/hd6446x/hd64461.c +++ b/arch/sh/cchips/hd6446x/hd64461.c @@ -14,6 +14,9 @@ #include <asm/irq.h> #include <asm/hd64461.h> +/* This belongs in cpu specific */ +#define INTC_ICR1 0xA4140010UL + static void disable_hd64461_irq(unsigned int irq) { unsigned short nimr; @@ -121,10 +124,15 @@ int hd64461_irq_demux(int irq) } } } - return __irq_demux(irq); + return irq; } -static struct irqaction irq0 = { hd64461_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "HD64461", NULL, NULL }; +static struct irqaction irq0 = { + .handler = hd64461_interrupt, + .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, + .name = "HD64461", +}; int __init setup_hd64461(void) { @@ -143,6 +151,7 @@ int __init setup_hd64461(void) #endif outw(0xffff, HD64461_NIMR); + /* IRQ 80 -> 95 belongs to HD64461 */ for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { irq_desc[i].chip = &hd64461_irq_type; } diff --git a/arch/sh/cchips/hd6446x/hd64465/setup.c b/arch/sh/cchips/hd6446x/hd64465/setup.c index d126e1f30dee..5cef0db4018b 100644 --- a/arch/sh/cchips/hd6446x/hd64465/setup.c +++ b/arch/sh/cchips/hd6446x/hd64465/setup.c @@ -147,7 +147,12 @@ int hd64465_irq_demux(int irq) return irq; } -static struct irqaction irq0 = { hd64465_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "HD64465", NULL, NULL}; +static struct irqaction irq0 = { + .handler = hd64465_interrupt, + .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, + .name = "HD64465", +}; static int __init setup_hd64465(void) diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c index d70e5c8461b5..ade303876841 100644 --- a/arch/sh/cchips/voyagergx/irq.c +++ b/arch/sh/cchips/voyagergx/irq.c @@ -23,149 +23,79 @@ #include <asm/voyagergx.h> #include <asm/rts7751r2d.h> -static void disable_voyagergx_irq(unsigned int irq) -{ - unsigned long val; - unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); - - pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); - val = readl((void __iomem *)VOYAGER_INT_MASK); - val &= ~mask; - writel(val, (void __iomem *)VOYAGER_INT_MASK); -} - -static void enable_voyagergx_irq(unsigned int irq) -{ - unsigned long val; - unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); - - pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); - val = readl((void __iomem *)VOYAGER_INT_MASK); - val |= mask; - writel(val, (void __iomem *)VOYAGER_INT_MASK); -} - -static void mask_and_ack_voyagergx(unsigned int irq) -{ - disable_voyagergx_irq(irq); -} - -static void end_voyagergx_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_voyagergx_irq(irq); -} - -static unsigned int startup_voyagergx_irq(unsigned int irq) -{ - enable_voyagergx_irq(irq); - return 0; -} - -static void shutdown_voyagergx_irq(unsigned int irq) -{ - disable_voyagergx_irq(irq); -} - -static struct hw_interrupt_type voyagergx_irq_type = { - .typename = "VOYAGERGX-IRQ", - .startup = startup_voyagergx_irq, - .shutdown = shutdown_voyagergx_irq, - .enable = enable_voyagergx_irq, - .disable = disable_voyagergx_irq, - .ack = mask_and_ack_voyagergx, - .end = end_voyagergx_irq, +enum { + UNUSED = 0, + + /* voyager specific interrupt sources */ + UP, G54, G53, G52, G51, G50, G49, G48, + I2C, PW, DMA, PCI, I2S, AC, US, + U1, U0, CV, MC, S1, S0, + UH, TWOD, ZD, PV, CI, }; -static irqreturn_t voyagergx_interrupt(int irq, void *dev_id) -{ - printk(KERN_INFO - "VoyagerGX: spurious interrupt, status: 0x%x\n", - (unsigned int)readl((void __iomem *)INT_STATUS)); - return IRQ_HANDLED; -} - -static struct { - int (*func)(int, void *); - void *dev; -} voyagergx_demux[VOYAGER_IRQ_NUM]; +static struct intc_vect vectors[] __initdata = { + INTC_IRQ(UP, IRQ_SM501_UP), INTC_IRQ(G54, IRQ_SM501_G54), + INTC_IRQ(G53, IRQ_SM501_G53), INTC_IRQ(G52, IRQ_SM501_G52), + INTC_IRQ(G51, IRQ_SM501_G51), INTC_IRQ(G50, IRQ_SM501_G50), + INTC_IRQ(G49, IRQ_SM501_G49), INTC_IRQ(G48, IRQ_SM501_G48), + INTC_IRQ(I2C, IRQ_SM501_I2C), INTC_IRQ(PW, IRQ_SM501_PW), + INTC_IRQ(DMA, IRQ_SM501_DMA), INTC_IRQ(PCI, IRQ_SM501_PCI), + INTC_IRQ(I2S, IRQ_SM501_I2S), INTC_IRQ(AC, IRQ_SM501_AC), + INTC_IRQ(US, IRQ_SM501_US), INTC_IRQ(U1, IRQ_SM501_U1), + INTC_IRQ(U0, IRQ_SM501_U0), INTC_IRQ(CV, IRQ_SM501_CV), + INTC_IRQ(MC, IRQ_SM501_MC), INTC_IRQ(S1, IRQ_SM501_S1), + INTC_IRQ(S0, IRQ_SM501_S0), INTC_IRQ(UH, IRQ_SM501_UH), + INTC_IRQ(TWOD, IRQ_SM501_2D), INTC_IRQ(ZD, IRQ_SM501_ZD), + INTC_IRQ(PV, IRQ_SM501_PV), INTC_IRQ(CI, IRQ_SM501_CI), +}; -void voyagergx_register_irq_demux(int irq, - int (*demux)(int irq, void *dev), void *dev) -{ - voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = demux; - voyagergx_demux[irq - VOYAGER_IRQ_BASE].dev = dev; -} +static struct intc_mask_reg mask_registers[] __initdata = { + { VOYAGER_INT_MASK, 0, 32, /* "Interrupt Mask", MMIO_base + 0x30 */ + { UP, G54, G53, G52, G51, G50, G49, G48, + I2C, PW, 0, DMA, PCI, I2S, AC, US, + 0, 0, U1, U0, CV, MC, S1, S0, + 0, UH, 0, 0, TWOD, ZD, PV, CI } }, +}; -void voyagergx_unregister_irq_demux(int irq) -{ - voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = 0; -} +static DECLARE_INTC_DESC(intc_desc, "voyagergx", vectors, + NULL, NULL, mask_registers, NULL, NULL); + +static unsigned int voyagergx_stat2irq[32] = { + IRQ_SM501_CI, IRQ_SM501_PV, IRQ_SM501_ZD, IRQ_SM501_2D, + 0, 0, IRQ_SM501_UH, 0, + IRQ_SM501_S0, IRQ_SM501_S1, IRQ_SM501_MC, IRQ_SM501_CV, + IRQ_SM501_U0, IRQ_SM501_U1, 0, 0, + IRQ_SM501_US, IRQ_SM501_AC, IRQ_SM501_I2S, IRQ_SM501_PCI, + IRQ_SM501_DMA, 0, IRQ_SM501_PW, IRQ_SM501_I2C, + IRQ_SM501_G48, IRQ_SM501_G49, IRQ_SM501_G50, IRQ_SM501_G51, + IRQ_SM501_G52, IRQ_SM501_G53, IRQ_SM501_G54, IRQ_SM501_UP +}; -int voyagergx_irq_demux(int irq) +static void voyagergx_irq_demux(unsigned int irq, struct irq_desc *desc) { - - if (irq == IRQ_VOYAGER ) { - unsigned long i = 0, bit __attribute__ ((unused)); - unsigned long val = readl((void __iomem *)INT_STATUS); - - if (val & (1 << 1)) - i = 1; - else if (val & (1 << 2)) - i = 2; - else if (val & (1 << 6)) - i = 6; - else if (val & (1 << 10)) - i = 10; - else if (val & (1 << 11)) - i = 11; - else if (val & (1 << 12)) - i = 12; - else if (val & (1 << 17)) - i = 17; - else - printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val); - pr_debug("voyagergx_irq_demux %ld \n", i); - if (i < VOYAGER_IRQ_NUM) { - irq = VOYAGER_IRQ_BASE + i; - if (voyagergx_demux[i].func != 0) - irq = voyagergx_demux[i].func(irq, - voyagergx_demux[i].dev); + unsigned long intv = ctrl_inl(INT_STATUS); + struct irq_desc *ext_desc; + unsigned int ext_irq; + unsigned int k = 0; + + while (intv) { + ext_irq = voyagergx_stat2irq[k]; + if (ext_irq && (intv & 1)) { + ext_desc = irq_desc + ext_irq; + handle_level_irq(ext_irq, ext_desc); } + intv >>= 1; + k++; } - return irq; } -static struct irqaction irq0 = { - .name = "voyagergx", - .handler = voyagergx_interrupt, - .flags = IRQF_DISABLED, - .mask = CPU_MASK_NONE, -}; - void __init setup_voyagergx_irq(void) { - int i, flag; - - printk(KERN_INFO "VoyagerGX configured at 0x%x on irq %d(mapped into %d to %d)\n", - VOYAGER_BASE, + printk(KERN_INFO "VoyagerGX on irq %d (mapped into %d to %d)\n", IRQ_VOYAGER, VOYAGER_IRQ_BASE, VOYAGER_IRQ_BASE + VOYAGER_IRQ_NUM - 1); - for (i=0; i<VOYAGER_IRQ_NUM; i++) { - flag = 0; - switch (VOYAGER_IRQ_BASE + i) { - case VOYAGER_USBH_IRQ: - case VOYAGER_8051_IRQ: - case VOYAGER_UART0_IRQ: - case VOYAGER_UART1_IRQ: - case VOYAGER_AC97_IRQ: - flag = 1; - } - if (flag == 1) - irq_desc[VOYAGER_IRQ_BASE + i].chip = &voyagergx_irq_type; - } - - setup_irq(IRQ_VOYAGER, &irq0); + register_intc_controller(&intc_desc); + set_irq_chained_handler(IRQ_VOYAGER, voyagergx_irq_demux); } diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig index 3fdd270eecf7..57728788b753 100644 --- a/arch/sh/configs/dreamcast_defconfig +++ b/arch/sh/configs/dreamcast_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22-rc4 -# Sat Jul 7 03:47:45 2007 +# Linux kernel version: 2.6.23-rc7 +# Fri Sep 21 15:46:27 2007 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -18,30 +18,26 @@ 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_ARCH_NO_VIRT_TO_BUS=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # 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_USER_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 @@ -64,7 +60,6 @@ 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 @@ -74,24 +69,17 @@ CONFIG_SLAB=y 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 +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -112,7 +100,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_CPU_SH4=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 @@ -120,6 +107,7 @@ CONFIG_CPU_SH4=y # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set # CONFIG_CPU_SUBTYPE_SH7712 is not set +# CONFIG_CPU_SUBTYPE_SH7720 is not set # CONFIG_CPU_SUBTYPE_SH7750 is not set CONFIG_CPU_SUBTYPE_SH7091=y # CONFIG_CPU_SUBTYPE_SH7750R is not set @@ -134,7 +122,6 @@ CONFIG_CPU_SUBTYPE_SH7091=y # CONFIG_CPU_SUBTYPE_SH7780 is not set # 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 @@ -177,7 +164,9 @@ CONFIG_NR_QUICK=2 # Cache configuration # # CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set +CONFIG_CACHE_WRITEBACK=y +# CONFIG_CACHE_WRITETHROUGH is not set +# CONFIG_CACHE_OFF is not set # # Processor features @@ -185,12 +174,11 @@ CONFIG_NR_QUICK=2 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 +CONFIG_CPU_HAS_FPU=y # # Board support @@ -270,6 +258,7 @@ CONFIG_CMDLINE="console=ttySC1,115200 panic=3" # # Bus options # +CONFIG_MAPLE=y CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y CONFIG_PCI_AUTO=y @@ -368,6 +357,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -380,27 +370,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER 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_DEV=y # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set @@ -411,14 +384,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# +CONFIG_MISC_DEVICES=y # CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 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 # @@ -426,12 +396,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set # @@ -444,26 +411,16 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # 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_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN 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 @@ -472,10 +429,6 @@ CONFIG_MII=y # 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 @@ -520,15 +473,7 @@ CONFIG_8139TOO=y # 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 # @@ -536,6 +481,7 @@ CONFIG_8139TOO=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -606,10 +552,6 @@ 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=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -631,10 +573,6 @@ CONFIG_HW_RANDOM=y # 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 @@ -644,11 +582,8 @@ CONFIG_DEVPORT=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# # CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # @@ -673,6 +608,7 @@ CONFIG_DEVPORT=y # # CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y # CONFIG_FB_DDC is not set @@ -699,7 +635,6 @@ CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set CONFIG_FB_PVR2=y -# CONFIG_FB_EPSON1355 is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set @@ -725,6 +660,7 @@ CONFIG_FB_PVR2=y # CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y CONFIG_FONT_8x8=y @@ -749,16 +685,10 @@ CONFIG_LOGO_SUPERH_CLUT224=y # Sound # # CONFIG_SOUND is not set - -# -# HID Devices -# +CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set - -# -# USB support -# +CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y @@ -773,32 +703,8 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # 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_CLASS is not set # @@ -815,6 +721,11 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # +# Userspace I/O +# +# CONFIG_UIO is not set + +# # File systems # # CONFIG_EXT2_FS is not set @@ -890,7 +801,6 @@ CONFIG_RAMFS=y # 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 @@ -935,10 +845,6 @@ CONFIG_ENABLE_MUST_CHECK=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set - -# -# Cryptographic options -# # CONFIG_CRYPTO is not set # @@ -949,6 +855,7 @@ CONFIG_BITREVERSE=y # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig index b931d9b2d579..756d38dc2f71 100644 --- a/arch/sh/configs/hp6xx_defconfig +++ b/arch/sh/configs/hp6xx_defconfig @@ -1,37 +1,47 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Tue Oct 3 11:10:06 2006 +# Linux kernel version: 2.6.23-rc4 +# Tue Sep 11 19:42:44 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_PM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=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_ARCH_NO_VIRT_TO_BUS=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y # CONFIG_SYSVIPC is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_UTS_NS is not set -# CONFIG_IKCONFIG is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_USER_NS is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_EMBEDDED=y CONFIG_UID16=y @@ -44,27 +54,25 @@ 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 -# # CONFIG_MODULES is not set - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -82,55 +90,17 @@ 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=y -# 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_UNKNOWN is not set - -# -# Processor selection -# CONFIG_CPU_SH3=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7619 is not set +# CONFIG_CPU_SUBTYPE_SH7206 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=y # CONFIG_CPU_SUBTYPE_SH7710 is not set - -# -# SH-4 Processor Support -# +# CONFIG_CPU_SUBTYPE_SH7712 is not set +# CONFIG_CPU_SUBTYPE_SH7720 is not set # CONFIG_CPU_SUBTYPE_SH7750 is not set # CONFIG_CPU_SUBTYPE_SH7091 is not set # CONFIG_CPU_SUBTYPE_SH7750R is not set @@ -139,66 +109,78 @@ CONFIG_CPU_SUBTYPE_SH7709=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 - -# -# SH4AL-DSP Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set +# CONFIG_CPU_SUBTYPE_SHX3 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_START=0x0d000000 CONFIG_MEMORY_SIZE=0x00400000 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_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 +CONFIG_CACHE_WRITEBACK=y +# CONFIG_CACHE_WRITETHROUGH is not set +# CONFIG_CACHE_OFF is not set # # Processor features # CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set # CONFIG_SH_FPU_EMU is not set -# CONFIG_SH_DSP is not set CONFIG_SH_ADC=y CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_PINT_IRQ=y CONFIG_CPU_HAS_SR_RB=y # -# Timer support +# Board support +# +# CONFIG_SH_SOLUTION_ENGINE is not set +CONFIG_SH_HP6XX=y + +# +# Timer and clock configuration # CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=16 CONFIG_SH_PCLK_FREQ=22110000 +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set # # CPU Frequency scaling @@ -208,6 +190,7 @@ CONFIG_SH_PCLK_FREQ=22110000 # # DMA support # +CONFIG_SH_DMA_API=y CONFIG_SH_DMA=y CONFIG_NR_ONCHIP_DMA_CHANNELS=4 # CONFIG_NR_DMA_CHANNELS_BOOL is not set @@ -223,14 +206,21 @@ CONFIG_HD64461_IOBASE=0xb0000000 CONFIG_HD64461_ENABLER=y # +# 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=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -240,14 +230,13 @@ 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_ISA=y -# CONFIG_PCI is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set # # PCCARD (PCMCIA/CardBus) support @@ -266,14 +255,9 @@ CONFIG_PCMCIA_IOCTL=y CONFIG_PCMCIA_PROBE=y # -# PCI Hotplug Support -# - -# # Executable file formats # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set # CONFIG_BINFMT_MISC is not set # @@ -282,8 +266,9 @@ CONFIG_BINFMT_ELF=y CONFIG_PM=y CONFIG_PM_LEGACY=y # CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set -CONFIG_APM=y +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_APM_EMULATION=y # # Networking @@ -301,109 +286,76 @@ CONFIG_APM=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set - -# -# Parallel port support -# # CONFIG_PARPORT is not set - -# -# Plug and Play support -# # CONFIG_PNP is not set - -# -# Block devices -# +CONFIG_BLK_DEV=y # 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_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=4 -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -CONFIG_BLK_DEV_IDECS=y -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -# CONFIG_IDE_ARM is not set -# CONFIG_IDE_CHIPSETS is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set # # SCSI device support # # CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Multi-device support (RAID and LVM) -# +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 + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_PATA_LEGACY is not set +# CONFIG_PATA_PCMCIA is not set +# CONFIG_PATA_QDI is not set +# CONFIG_PATA_WINBOND_VLB is not set +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 -# - -# -# ISDN subsystem -# - -# -# Telephony Support -# # CONFIG_PHONE is not set # @@ -411,19 +363,17 @@ CONFIG_IDE_GENERIC=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_POLLDEV=y # # Userland interfaces # -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_TSDEV=y CONFIG_INPUT_TSDEV_SCREEN_X=240 CONFIG_INPUT_TSDEV_SCREEN_Y=320 -# CONFIG_INPUT_EVDEV is not set +CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set # @@ -436,9 +386,12 @@ CONFIG_INPUT_KEYBOARD=y # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_KEYBOARD_HP6XX=y # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELO is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set @@ -447,6 +400,7 @@ CONFIG_TOUCHSCREEN_HP600=y # CONFIG_TOUCHSCREEN_PENMOUNT is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set # CONFIG_INPUT_MISC is not set # @@ -476,46 +430,29 @@ CONFIG_HW_CONSOLE=y # # Non-8250 serial port support # -# CONFIG_SERIAL_SH_SCI is not set +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=3 +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_LEGACY_PTY_COUNT=64 # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=y -# CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # -# Ftape, the floppy tape device driver -# - -# # PCMCIA character devices # # CONFIG_SYNCLINK_CS is not set # CONFIG_CARDMAN_4000 is not set # CONFIG_CARDMAN_4040 is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# +CONFIG_DEVPORT=y # CONFIG_I2C is not set # @@ -523,48 +460,55 @@ CONFIG_HW_RANDOM=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set # -# Dallas's 1-wire bus -# - -# -# 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_DAB is not set # -# Digital Video Broadcasting Devices +# Graphics support # +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_HP680=y # -# Graphics support +# Display device support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=y 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 -# CONFIG_FB_EPSON1355 is not set + +# +# Frame buffer hardware drivers +# # CONFIG_FB_S1D13XXX is not set CONFIG_FB_HIT=y # CONFIG_FB_VIRTUAL is not set @@ -575,6 +519,7 @@ CONFIG_FB_HIT=y # CONFIG_MDA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y # CONFIG_FONT_8x8 is not set @@ -587,79 +532,49 @@ CONFIG_FONT_PEARL_8x8=y # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set # CONFIG_FONT_10x18 is not set - -# -# Logo configuration -# # CONFIG_LOGO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound # -CONFIG_SOUND=y - -# -# Advanced Linux Sound Architecture -# -# CONFIG_SND is not set - -# -# Open Sound System -# -CONFIG_SOUND_PRIME=y -# CONFIG_OSS_OBSOLETE_DRIVER is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -CONFIG_SOUND_SH_DAC_AUDIO=y -CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL=1 - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set - -# -# LED devices -# # CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set # -# LED drivers -# - -# -# LED Triggers +# 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 # -# InfiniBand support +# SPI RTC drivers # # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# Platform RTC drivers # +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_V3020 is not set # -# Real Time Clock +# on-CPU RTC drivers # -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_DRV_SH=y # # DMA Engine support @@ -675,16 +590,23 @@ CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL=1 # # +# Userspace I/O +# +# CONFIG_UIO is not set + +# # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y @@ -705,7 +627,7 @@ CONFIG_DNOTIFY=y # DOS/FAT/NT Filesystems # CONFIG_FAT_FS=y -# CONFIG_MSDOS_FS is not set +CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" @@ -755,7 +677,7 @@ 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_850=y # CONFIG_NLS_CODEPAGE_852 is not set # CONFIG_NLS_CODEPAGE_855 is not set # CONFIG_NLS_CODEPAGE_857 is not set @@ -799,34 +721,73 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # 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_UNWIND_INFO is not set # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_KGDB is not set +# CONFIG_EARLY_SCIF_CONSOLE 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 +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# 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=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_DES is not set +# 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_HW is not set # # Library routines # +CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set +CONFIG_CRC16=y +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # 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/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig new file mode 100644 index 000000000000..f8398a5f10ee --- /dev/null +++ b/arch/sh/configs/magicpanelr2_defconfig @@ -0,0 +1,925 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.23-rc2 +# Fri Aug 17 12:15:16 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_ARCH_NO_VIRT_TO_BUS=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +CONFIG_AUDIT=y +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +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 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG 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_SH3=y +# CONFIG_CPU_SUBTYPE_SH7619 is not set +# CONFIG_CPU_SUBTYPE_SH7206 is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set +# CONFIG_CPU_SUBTYPE_SH7712 is not set +CONFIG_CPU_SUBTYPE_SH7720=y +# 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 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=0x03F00000 +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_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_CACHE_WRITEBACK=y +# CONFIG_CACHE_WRITETHROUGH is not set +# CONFIG_CACHE_OFF is not set + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set +# CONFIG_SH_FPU_EMU is not set +CONFIG_SH_DSP=y +CONFIG_SH_ADC=y +CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_INTC_IRQ=y +CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_DSP=y + +# +# Board support +# +CONFIG_SH_MAGIC_PANEL_R2=y + +# +# Magic Panel R2 options +# +CONFIG_SH_MAGIC_PANEL_R2_VERSION=3 + +# +# Timer and clock configuration +# +CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=16 +CONFIG_SH_PCLK_FREQ=24000000 +# 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_API=y +CONFIG_SH_DMA=y +CONFIG_NR_ONCHIP_DMA_CHANNELS=6 +# CONFIG_NR_DMA_CHANNELS_BOOL 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 is not set +# CONFIG_CRASH_DUMP is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +# CONFIG_CMDLINE_BOOL is not set + +# +# 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=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=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 is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +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 is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_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 +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x0000000 +CONFIG_MTD_PHYSMAP_LEN=0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=0 +# CONFIG_MTD_SOLUTIONENGINE is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_STNIC is not set +# CONFIG_SMC91X is not set +CONFIG_SMC911X=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# 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 +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +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=y +# 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=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL 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 + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA 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 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY 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_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_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_HCTOSYS is not set +# 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 + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 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 +# + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# 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 is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG 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 +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_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_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WRITEBUFFER is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN 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 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_BIND34=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# 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 + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# 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_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 is not set + +# +# 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 is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER 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_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_DEBUG_KOBJECT=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +# CONFIG_FORCED_INLINING is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SH_STANDARD_BIOS is not set +CONFIG_EARLY_SCIF_CONSOLE=y +CONFIG_EARLY_SCIF_CONSOLE_PORT=0xa4430000 +CONFIG_EARLY_PRINTK=y +# CONFIG_DEBUG_BOOTMEM is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_4KSTACKS is not set +CONFIG_SH_KGDB=y + +# +# KGDB configuration options +# +# CONFIG_MORE_COMPILE_OPTIONS is not set +# CONFIG_KGDB_NMI is not set +CONFIG_KGDB_SYSRQ=y + +# +# Serial port setup +# +CONFIG_KGDB_DEFPORT=0 +CONFIG_KGDB_DEFBAUD=115200 +CONFIG_KGDB_DEFPARITY_N=y +# CONFIG_KGDB_DEFPARITY_E is not set +# CONFIG_KGDB_DEFPARITY_O is not set +CONFIG_KGDB_DEFBITS_8=y +# CONFIG_KGDB_DEFBITS_7 is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/sh/configs/rts7751r2d_defconfig b/arch/sh/configs/rts7751r2d1_defconfig index b64f73b704d6..2dc754e5b733 100644 --- a/arch/sh/configs/rts7751r2d_defconfig +++ b/arch/sh/configs/rts7751r2d1_defconfig @@ -1,46 +1,47 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc1 -# Thu Mar 1 16:42:40 2007 +# Linux kernel version: 2.6.23-rc2 +# Tue Aug 14 18:04:44 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_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_ARCH_NO_VIRT_TO_BUS=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=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 is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +# CONFIG_USER_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_BLK_DEV_INITRD is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_EMBEDDED=y @@ -54,31 +55,29 @@ 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 -# CONFIG_MODULES=y # CONFIG_MODULE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set # CONFIG_KMOD is not set - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -96,61 +95,16 @@ 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_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=y -# 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 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 # 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 # CONFIG_CPU_SUBTYPE_SH7707 is not set # CONFIG_CPU_SUBTYPE_SH7708 is not set # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set - -# -# SH-4 Processor Support -# +# CONFIG_CPU_SUBTYPE_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 @@ -159,35 +113,30 @@ CONFIG_CPU_SH4=y CONFIG_CPU_SUBTYPE_SH7751R=y # 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_SHX3 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 @@ -197,17 +146,19 @@ 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 +CONFIG_CACHE_WRITEBACK=y +# CONFIG_CACHE_WRITETHROUGH is not set +# CONFIG_CACHE_OFF is not set # # Processor features @@ -215,7 +166,6 @@ CONFIG_ZONE_DMA_FLAG=0 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 is not set CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_INTC_IRQ=y @@ -223,17 +173,31 @@ CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_PTEA=y # -# Timer support +# Board support # -CONFIG_SH_TMU=y +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set +CONFIG_SH_RTS7751R2D=y +# CONFIG_SH_LANDISK is not set +# CONFIG_SH_TITAN is not set +# CONFIG_SH_LBOX_RE2 is not set # # RTS7751R2D options # -CONFIG_RTS7751R2D_REV11=y +# CONFIG_RTS7751R2D_PLUS is not set +CONFIG_RTS7751R2D_1=y + +# +# Timer and clock configuration +# +CONFIG_SH_TMU=y CONFIG_SH_TIMER_IRQ=16 -# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=60000000 +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set # # CPU Frequency scaling @@ -244,19 +208,15 @@ CONFIG_SH_PCLK_FREQ=60000000 # DMA support # # CONFIG_SH_DMA is not set -# CONFIG_NR_ONCHIP_DMA_CHANNELS is not set -# CONFIG_NR_DMA_CHANNELS_BOOL is not set # # Companion Chips # -CONFIG_VOYAGERGX=y -# CONFIG_HD6446X_SERIES is not set -CONFIG_HEARTBEAT=y # # Additional SuperH Device Drivers # +CONFIG_HEARTBEAT=y # CONFIG_PUSH_SWITCH is not set # @@ -268,7 +228,7 @@ CONFIG_HZ_250=y # 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=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -289,15 +249,12 @@ 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 # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# CONFIG_HOTPLUG_PCI=y # CONFIG_HOTPLUG_PCI_FAKE is not set # CONFIG_HOTPLUG_PCI_CPCI is not set @@ -307,15 +264,9 @@ CONFIG_HOTPLUG_PCI=y # 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 @@ -323,7 +274,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -360,20 +310,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 @@ -399,8 +337,17 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # 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 +# CONFIG_NET_9P is not set # # Device Drivers @@ -413,31 +360,10 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=m # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # 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_DEV=y # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set @@ -449,19 +375,13 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# # CONFIG_IDE is not set # @@ -469,6 +389,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -490,6 +411,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 @@ -497,12 +419,8 @@ CONFIG_BLK_DEV_SD=y # 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_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set @@ -512,7 +430,6 @@ CONFIG_BLK_DEV_SD=y # 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 @@ -535,10 +452,6 @@ CONFIG_BLK_DEV_SD=y # 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 @@ -561,6 +474,7 @@ CONFIG_ATA=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 @@ -593,10 +507,6 @@ CONFIG_ATA=y # 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 # @@ -610,35 +520,18 @@ CONFIG_PATA_PLATFORM=y # # 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_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN 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 - -# -# Ethernet (10 or 100Mbit) -# CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_STNIC is not set @@ -647,10 +540,6 @@ CONFIG_MII=y # 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 @@ -677,10 +566,7 @@ CONFIG_8139TOO=y # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 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 @@ -691,61 +577,26 @@ CONFIG_8139TOO=y # 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 - -# -# 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=m -# CONFIG_PLX_HERMES is not set -# CONFIG_TMD_HERMES is not set -# CONFIG_NORTEL_HERMES is not set -# CONFIG_PCI_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 @@ -756,15 +607,7 @@ CONFIG_NET_WIRELESS=y # 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 # @@ -772,6 +615,7 @@ CONFIG_NET_WIRELESS=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -788,6 +632,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 @@ -828,32 +673,15 @@ 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 - -# -# 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 # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y # CONFIG_I2C is not set # @@ -861,21 +689,24 @@ CONFIG_HW_RANDOM=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# +# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set # CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set # @@ -887,22 +718,31 @@ CONFIG_MFD_SM501=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_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # 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 @@ -910,14 +750,13 @@ CONFIG_FB_CFB_IMAGEBLIT=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 # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set -# CONFIG_FB_EPSON1355 is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set @@ -932,7 +771,10 @@ CONFIG_FB_CFB_IMAGEBLIT=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_SM501=y # CONFIG_FB_VIRTUAL is not set @@ -941,14 +783,11 @@ CONFIG_FB_SM501=y # CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y - -# -# Logo configuration -# CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set @@ -1048,35 +887,34 @@ CONFIG_SND_AC97_CODEC=m # CONFIG_SND_VIA82XX_MODEM is not set # CONFIG_SND_VX222 is not set CONFIG_SND_YMFPCI=m +CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y # CONFIG_SND_AC97_POWER_SAVE is not set # -# SoC audio support +# SUPERH devices +# + +# +# System on Chip audio support # # CONFIG_SND_SOC is not set # +# SoC Audio support for SuperH +# + +# # 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_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set CONFIG_AC97_BUS=m - -# -# HID Devices -# +CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set - -# -# USB support -# +CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y @@ -1090,37 +928,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set - -# -# LED devices -# # CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# # 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 @@ -1134,18 +944,28 @@ 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 + +# +# SPI RTC drivers +# # -# RTC drivers +# Platform RTC drivers # # CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 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_M48T59 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 @@ -1159,12 +979,9 @@ CONFIG_RTC_DRV_SH=y # # -# Auxiliary Display support -# - -# -# Virtualization +# Userspace I/O # +# CONFIG_UIO is not set # # File systems @@ -1247,7 +1064,6 @@ CONFIG_RAMFS=y # 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 @@ -1321,7 +1137,6 @@ CONFIG_ENABLE_MUST_CHECK=y # 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_SH_STANDARD_BIOS is not set CONFIG_EARLY_SCIF_CONSOLE=y @@ -1334,10 +1149,6 @@ CONFIG_EARLY_PRINTK=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set - -# -# Cryptographic options -# # CONFIG_CRYPTO is not set # @@ -1346,8 +1157,11 @@ CONFIG_EARLY_PRINTK=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_CRC7 is not set # 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/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig new file mode 100644 index 000000000000..4ff5a752dcd9 --- /dev/null +++ b/arch/sh/configs/rts7751r2dplus_defconfig @@ -0,0 +1,1167 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.23-rc2 +# Tue Aug 14 16:33:08 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_ARCH_NO_VIRT_TO_BUS=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_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_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=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 +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System type +# +CONFIG_CPU_SH4=y +# CONFIG_CPU_SUBTYPE_SH7619 is not set +# CONFIG_CPU_SUBTYPE_SH7206 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=y +# 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 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_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_CACHE_WRITEBACK=y +# CONFIG_CACHE_WRITETHROUGH is not set +# CONFIG_CACHE_OFF is not set + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_SH_FPU=y +# CONFIG_SH_STORE_QUEUES is not set +CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_INTC_IRQ=y +CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_PTEA=y + +# +# Board support +# +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set +CONFIG_SH_RTS7751R2D=y +# CONFIG_SH_LANDISK is not set +# CONFIG_SH_TITAN is not set +# CONFIG_SH_LBOX_RE2 is not set + +# +# RTS7751R2D options +# +CONFIG_RTS7751R2D_PLUS=y +# CONFIG_RTS7751R2D_1 is not set + +# +# Timer and clock configuration +# +CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=16 +CONFIG_SH_PCLK_FREQ=60000000 +# 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 +# + +# +# 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 is not set +# CONFIG_CRASH_DUMP is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00010000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +# CONFIG_UBC_WAKEUP is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=serial" + +# +# 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 + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_FAKE is not set +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC 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 is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=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 is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_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 +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# 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 +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_LOWLEVEL=y +# 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_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 is not set +# 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 +# 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 +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set +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 +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 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 is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# 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 is not set +# CONFIG_SC92031 is not set +CONFIG_NETDEV_1000=y +# 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_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 +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# 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 + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_CONSOLE is not set +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=1 +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 +# 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 +# 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 +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_SM501=y + +# +# 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_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# 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 +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# 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_SM501=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +# CONFIG_LOGO_SUPERH_MONO is not set +# CONFIG_LOGO_SUPERH_VGA16 is not set +CONFIG_LOGO_SUPERH_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VX222 is not set +CONFIG_SND_YMFPCI=m +CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y +# CONFIG_SND_AC97_POWER_SAVE is not set + +# +# SUPERH devices +# + +# +# System on Chip audio support +# +# CONFIG_SND_SOC is not set + +# +# SoC Audio support for SuperH +# + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=m +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +CONFIG_USB_SUPPORT=y +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 +# CONFIG_NEW_LEDS is not set +# CONFIG_INFINIBAND is not set +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 + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 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 +# + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP 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=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 is not set + +# +# 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 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 is not set +# CONFIG_HUGETLB_PAGE is not set +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 + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# 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 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=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 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 + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=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_DEBUG_BUGVERBOSE is not set +# CONFIG_SH_STANDARD_BIOS is not set +CONFIG_EARLY_SCIF_CONSOLE=y +CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000 +CONFIG_EARLY_PRINTK=y +# CONFIG_SH_KGDB is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# 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_CRC7 is not set +# 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/se7206_defconfig b/arch/sh/configs/se7206_defconfig index f2f2a3c9c32d..0d0cda908270 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22-rc4 -# Fri Jun 15 19:37:46 2007 +# Linux kernel version: 2.6.23-rc4 +# Thu Sep 13 16:40:16 2007 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -17,25 +17,22 @@ 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_ARCH_NO_VIRT_TO_BUS=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_SYSVIPC is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 @@ -60,23 +57,17 @@ 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_SLUB_DEBUG=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=1 - -# -# Loadable module support -# # CONFIG_MODULES is not set - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -98,7 +89,6 @@ CONFIG_CPU_SH2=y CONFIG_CPU_SH2A=y # CONFIG_CPU_SUBTYPE_SH7619 is not set CONFIG_CPU_SUBTYPE_SH7206=y -# 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 @@ -106,6 +96,7 @@ CONFIG_CPU_SUBTYPE_SH7206=y # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set # CONFIG_CPU_SUBTYPE_SH7712 is not set +# CONFIG_CPU_SUBTYPE_SH7720 is not set # CONFIG_CPU_SUBTYPE_SH7750 is not set # CONFIG_CPU_SUBTYPE_SH7091 is not set # CONFIG_CPU_SUBTYPE_SH7750R is not set @@ -119,7 +110,7 @@ CONFIG_CPU_SUBTYPE_SH7206=y # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set # CONFIG_CPU_SUBTYPE_SH7785 is not set -# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SHX3 is not set # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set @@ -136,15 +127,16 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 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 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_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_STATIC=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set @@ -155,7 +147,9 @@ CONFIG_NR_QUICK=2 # Cache configuration # # CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set +CONFIG_CACHE_WRITEBACK=y +# CONFIG_CACHE_WRITETHROUGH is not set +# CONFIG_CACHE_OFF is not set # # Processor features @@ -163,8 +157,6 @@ CONFIG_NR_QUICK=2 # CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_CPU_BIG_ENDIAN=y # CONFIG_SH_FPU_EMU is not set -# CONFIG_SH_DSP is not set -CONFIG_CPU_HAS_IPR_IRQ=y # # Board support @@ -185,12 +177,23 @@ CONFIG_SH_CLK_MD=6 # # CPU Frequency scaling # -# CONFIG_CPU_FREQ is not set +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +# CONFIG_SH_CPU_FREQ is not set # # DMA support # -# CONFIG_SH_DMA is not set # # Companion Chips @@ -199,17 +202,17 @@ CONFIG_SH_CLK_MD=6 # # Additional SuperH Device Drivers # -# CONFIG_HEARTBEAT is not set +CONFIG_HEARTBEAT=y # CONFIG_PUSH_SWITCH is not set # # Kernel features # -CONFIG_HZ_100=y +# CONFIG_HZ_100 is not set # CONFIG_HZ_250 is not set # CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=100 +CONFIG_HZ_1000=y +CONFIG_HZ=1000 # CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set CONFIG_PREEMPT_NONE=y @@ -221,11 +224,13 @@ CONFIG_PREEMPT_NONE=y # CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 -# CONFIG_CMDLINE_BOOL is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttySC3,115200 earlyprintk=serial ignore_loglevel" # # Bus options # +# CONFIG_CF_ENABLER is not set # CONFIG_ARCH_SUPPORTS_MSI is not set # @@ -315,6 +320,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -325,11 +331,9 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD 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_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set @@ -411,31 +415,16 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4 # UBI - Unsorted block images # # CONFIG_MTD_UBI 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=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_BLINK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set # CONFIG_IDE is not set # @@ -443,27 +432,18 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4 # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_STNIC is not set @@ -483,15 +463,7 @@ CONFIG_NETDEV_10000=y # 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 # @@ -499,6 +471,7 @@ CONFIG_NETDEV_10000=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -546,19 +519,11 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set @@ -567,11 +532,8 @@ CONFIG_SERIAL_CORE_CONSOLE=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# # CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # @@ -596,25 +558,21 @@ CONFIG_DAB=y # # CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=y # CONFIG_FB is not set # # Sound # # CONFIG_SOUND is not set - -# -# HID Devices -# +CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' @@ -625,31 +583,7 @@ CONFIG_HID=y # # 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_CLASS is not set # @@ -666,6 +600,11 @@ CONFIG_HID=y # # +# Userspace I/O +# +# CONFIG_UIO is not set + +# # File systems # # CONFIG_EXT2_FS is not set @@ -736,7 +675,6 @@ CONFIG_RAMFS=y # 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 @@ -752,12 +690,12 @@ CONFIG_MSDOS_PARTITION=y # # Distributed Lock Manager # -# CONFIG_DLM is not set # # Profiling support # -# CONFIG_PROFILING is not set +CONFIG_PROFILING=y +# CONFIG_OPROFILE is not set # # Kernel hacking @@ -768,19 +706,41 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y # 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_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +CONFIG_SLUB_DEBUG_ON=y +# 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_LOCK_STAT is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# 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=y +CONFIG_FORCED_INLINING=y +# CONFIG_FAULT_INJECTION is not set # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set +CONFIG_EARLY_SCIF_CONSOLE=y +CONFIG_EARLY_SCIF_CONSOLE_PORT=0xfffe9800 +CONFIG_EARLY_PRINTK=y +# CONFIG_DEBUG_BOOTMEM is not set +CONFIG_DEBUG_STACKOVERFLOW=y +CONFIG_DEBUG_STACK_USAGE=y +# CONFIG_4KSTACKS is not set # # Security options # # CONFIG_KEYS is not set - -# -# Cryptographic options -# # CONFIG_CRYPTO is not set # @@ -791,6 +751,7 @@ CONFIG_BITREVERSE=y # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_HAS_IOMEM=y diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig index 219bad558b10..a794c082709b 100644 --- a/arch/sh/configs/shx3_defconfig +++ b/arch/sh/configs/shx3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22-rc4 -# Wed Jun 20 14:09:27 2007 +# Linux kernel version: 2.6.23-rc7 +# Fri Sep 21 19:07:30 2007 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -13,32 +13,33 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_SYS_SUPPORTS_SMP=y +CONFIG_SYS_SUPPORTS_NUMA=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_ARCH_NO_VIRT_TO_BUS=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # 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_UTS_NS is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 @@ -63,34 +64,26 @@ 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_SLAB is not set # CONFIG_SLUB is not set -# CONFIG_SLOB is not set +CONFIG_SLOB=y 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 +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -113,7 +106,6 @@ 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 @@ -121,6 +113,7 @@ CONFIG_CPU_SHX3=y # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set # CONFIG_CPU_SUBTYPE_SH7712 is not set +# CONFIG_CPU_SUBTYPE_SH7720 is not set # CONFIG_CPU_SUBTYPE_SH7750 is not set # CONFIG_CPU_SUBTYPE_SH7091 is not set # CONFIG_CPU_SUBTYPE_SH7750R is not set @@ -135,7 +128,6 @@ CONFIG_CPU_SHX3=y # 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 @@ -148,12 +140,15 @@ CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_VSYSCALL=y +# CONFIG_NUMA is not set CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y -CONFIG_MAX_ACTIVE_REGIONS=1 +CONFIG_MAX_ACTIVE_REGIONS=6 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_MEMORY_PROBE=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_64KB is not set @@ -163,12 +158,14 @@ 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_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_STATIC=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 @@ -178,24 +175,25 @@ CONFIG_NR_QUICK=2 # Cache configuration # # CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set +# CONFIG_CACHE_WRITEBACK is not set +# CONFIG_CACHE_WRITETHROUGH is not set +CONFIG_CACHE_OFF=y # # 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_FPU=y CONFIG_SH_STORE_QUEUES=y CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_INTC2_IRQ=y CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_FPU=y # # Board support # +CONFIG_SH_X3PROTO=y # # Timer and clock configuration @@ -204,13 +202,25 @@ CONFIG_SH_TMU=y CONFIG_SH_TIMER_IRQ=16 CONFIG_SH_PCLK_FREQ=50000000 CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y +# CONFIG_NO_HZ is not set CONFIG_HIGH_RES_TIMERS=y # # CPU Frequency scaling # -# CONFIG_CPU_FREQ is not set +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_SH_CPU_FREQ=y # # DMA support @@ -237,6 +247,7 @@ 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 @@ -249,7 +260,7 @@ 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" +CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=bios ignore_loglevel" # # Bus options @@ -265,12 +276,106 @@ CONFIG_CMDLINE="console=ttySC0,115200 ip=192.168.1.2:::255.255.255.0 root=/dev/n # Executable file formats # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set +CONFIG_BINFMT_MISC=y # # Networking # -# CONFIG_NET is not set +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_UNIX is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=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=m +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=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_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 +# CONFIG_NET_9P is not set # # Device Drivers @@ -285,37 +390,21 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # 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_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=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_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set # CONFIG_IDE is not set # @@ -323,6 +412,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -351,73 +441,54 @@ CONFIG_SCSI_WAIT_SCAN=m # # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set # 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_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_STNIC is not set +CONFIG_SMC91X=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# 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 +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set # CONFIG_PHONE is not set # # Input device support # -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# 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 +# CONFIG_INPUT 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_SERIO is not set # CONFIG_GAMEPORT is not set # @@ -442,19 +513,18 @@ CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set # -# IPMI +# Watchdog Device Drivers # -# CONFIG_IPMI_HANDLER is not set -# CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_SH_WDT is not set +# CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set @@ -463,11 +533,8 @@ CONFIG_HW_RANDOM=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# # CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # @@ -479,6 +546,7 @@ CONFIG_HW_RANDOM=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set # CONFIG_DAB is not set # @@ -491,24 +559,18 @@ CONFIG_HW_RANDOM=y # # CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m # 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_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' @@ -517,68 +579,32 @@ CONFIG_HW_RANDOM=y # # USB Gadget Support # -# CONFIG_USB_GADGET is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +CONFIG_USB_GADGET_M66592=y +CONFIG_USB_M66592=y +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_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 +# CONFIG_RTC_CLASS is not set # # DMA Engine support @@ -594,6 +620,11 @@ CONFIG_RTC_DRV_SH=y # # +# Userspace I/O +# +CONFIG_UIO=m + +# # File systems # CONFIG_EXT2_FS=y @@ -612,6 +643,7 @@ CONFIG_FS_MBCACHE=y # 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 CONFIG_INOTIFY=y @@ -667,6 +699,17 @@ CONFIG_RAMFS=y # CONFIG_UFS_FS is not set # +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# # Partition Types # # CONFIG_PARTITION_ADVANCED is not set @@ -678,6 +721,11 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# # Profiling support # CONFIG_PROFILING=y @@ -687,31 +735,28 @@ CONFIG_PROFILING=y # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_TIME is not set # 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_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=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_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_LOCKDEP=y -CONFIG_DEBUG_LOCKDEP=y +# CONFIG_LOCK_STAT is not set # 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 @@ -735,10 +780,6 @@ CONFIG_DEBUG_STACK_USAGE=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set - -# -# Cryptographic options -# # CONFIG_CRYPTO is not set # @@ -749,6 +790,7 @@ CONFIG_BITREVERSE=y # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig index ee711431e504..4e711a0c3dae 100644 --- a/arch/sh/drivers/dma/Kconfig +++ b/arch/sh/drivers/dma/Kconfig @@ -12,6 +12,7 @@ config SH_DMA config NR_ONCHIP_DMA_CHANNELS int depends on SH_DMA + default "6" if CPU_SUBTYPE_SH7720 default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R default "12" if CPU_SUBTYPE_SH7780 default "4" diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 06ed0609a95d..958bac1c585a 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -24,13 +24,19 @@ static int dmte_irq_map[] = { DMTE1_IRQ, DMTE2_IRQ, DMTE3_IRQ, -#if defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ +#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ + defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ defined(CONFIG_CPU_SUBTYPE_SH7760) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) || \ defined(CONFIG_CPU_SUBTYPE_SH7780) DMTE4_IRQ, DMTE5_IRQ, +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ + defined(CONFIG_CPU_SUBTYPE_SH7760) || \ + defined(CONFIG_CPU_SUBTYPE_SH7780) DMTE6_IRQ, - DMTE7_IRQ, + DMTE7_IRQ, #endif }; @@ -196,7 +202,8 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan) return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan); } -#ifdef CONFIG_CPU_SUBTYPE_SH7780 +#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ + defined(CONFIG_CPU_SUBTYPE_SH7780) #define dmaor_read_reg() ctrl_inw(DMAOR) #define dmaor_write_reg(data) ctrl_outw(data, DMAOR) #else diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c index 10c1828c9ff5..b76a14f12ce2 100644 --- a/arch/sh/drivers/heartbeat.c +++ b/arch/sh/drivers/heartbeat.c @@ -24,24 +24,44 @@ #include <linux/sched.h> #include <linux/timer.h> #include <linux/io.h> +#include <asm/heartbeat.h> #define DRV_NAME "heartbeat" -#define DRV_VERSION "0.1.0" +#define DRV_VERSION "0.1.1" -struct heartbeat_data { - void __iomem *base; - unsigned char bit_pos[8]; - struct timer_list timer; -}; +static unsigned char default_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + +static inline void heartbeat_toggle_bit(struct heartbeat_data *hd, + unsigned bit, unsigned int inverted) +{ + unsigned int new; + + new = (1 << hd->bit_pos[bit]); + if (inverted) + new = ~new; + + switch (hd->regsize) { + case 32: + iowrite32(new, hd->base); + break; + case 16: + iowrite16(new, hd->base); + break; + default: + iowrite8(new, hd->base); + break; + } +} static void heartbeat_timer(unsigned long data) { struct heartbeat_data *hd = (struct heartbeat_data *)data; static unsigned bit = 0, up = 1; - ctrl_outw(1 << hd->bit_pos[bit], (unsigned long)hd->base); + heartbeat_toggle_bit(hd, bit, hd->flags & HEARTBEAT_INVERTED); + bit += up; - if ((bit == 0) || (bit == ARRAY_SIZE(hd->bit_pos)-1)) + if ((bit == 0) || (bit == (hd->nr_bits)-1)) up = -up; mod_timer(&hd->timer, jiffies + (110 - ((300 << FSHIFT) / @@ -64,21 +84,31 @@ static int heartbeat_drv_probe(struct platform_device *pdev) return -EINVAL; } - hd = kmalloc(sizeof(struct heartbeat_data), GFP_KERNEL); - if (unlikely(!hd)) - return -ENOMEM; - if (pdev->dev.platform_data) { - memcpy(hd->bit_pos, pdev->dev.platform_data, - ARRAY_SIZE(hd->bit_pos)); + hd = pdev->dev.platform_data; } else { - int i; + hd = kzalloc(sizeof(struct heartbeat_data), GFP_KERNEL); + if (unlikely(!hd)) + return -ENOMEM; + } + + hd->base = ioremap_nocache(res->start, res->end - res->start + 1); + if (!unlikely(hd->base)) { + dev_err(&pdev->dev, "ioremap failed\n"); + + if (!pdev->dev.platform_data) + kfree(hd); + + return -ENXIO; + } - for (i = 0; i < ARRAY_SIZE(hd->bit_pos); i++) - hd->bit_pos[i] = i; + if (!hd->nr_bits) { + hd->bit_pos = default_bit_pos; + hd->nr_bits = ARRAY_SIZE(default_bit_pos); } - hd->base = (void __iomem *)(unsigned long)res->start; + if (!hd->regsize) + hd->regsize = 8; /* default access size */ setup_timer(&hd->timer, heartbeat_timer, (unsigned long)hd); platform_set_drvdata(pdev, hd); @@ -91,10 +121,12 @@ static int heartbeat_drv_remove(struct platform_device *pdev) struct heartbeat_data *hd = platform_get_drvdata(pdev); del_timer_sync(&hd->timer); + iounmap(hd->base); platform_set_drvdata(pdev, NULL); - kfree(hd); + if (!pdev->dev.platform_data) + kfree(hd); return 0; } diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c index 4a518d948049..ec8430c8d2d1 100644 --- a/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/arch/sh/drivers/pci/ops-rts7751r2d.c @@ -19,10 +19,10 @@ #include "pci-sh4.h" static u8 rts7751r2d_irq_tab[] __initdata = { - IRQ_PCISLOT1, - IRQ_PCISLOT2, - IRQ_PCMCIA, - IRQ_PCIETH, + IRQ_PCI_INTA, + IRQ_PCI_INTB, + IRQ_PCI_INTC, + IRQ_PCI_INTD, }; int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 5508e45d4838..e516087fb435 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -79,19 +79,6 @@ static int __init sh7780_pci_init(void) ctrl_outl(0xAAAA0000, INTC_ICR1); /* INTPRI: priority=3(all) */ ctrl_outl(0x33333333, INTC_INTPRI); - } else { - /* INTC SH-4 Mode */ - ctrl_outl(0x00200000, INTC_ICR0); - /* enable PCIINTA - PCIINTD */ - ctrl_outl(0x00078000, INTC_INT2MSKCR); - /* disable IRL4-7 Interrupt */ - ctrl_outl(0x40000000, INTC_INTMSK1); - /* disable IRL4-7 Interrupt */ - ctrl_outl(0x0000fffe, INTC_INTMSK2); - /* enable IRL0-3 Interrupt */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); - /* enable IRL0-3 Interrupt */ - ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); } if ((ret = sh4_pci_check_direct()) != 0) diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 92807ffa8e20..b5f1e23ed57c 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -83,6 +83,8 @@ static void propagate_rate(struct clk *clk) continue; if (likely(clkp->ops && clkp->ops->recalc)) clkp->ops->recalc(clkp); + if (unlikely(clkp->flags & CLK_RATE_PROPAGATES)) + propagate_rate(clkp); } } diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 9172e97dc26a..c217c4bf0085 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -22,6 +22,7 @@ #include <asm/cache.h> #include <asm/io.h> #include <asm/ubc.h> +#include <asm/smp.h> /* * Generic wrapper for command line arguments to disable on-chip @@ -143,12 +144,15 @@ static void __init cache_init(void) flags &= ~CCR_CACHE_EMODE; #endif -#ifdef CONFIG_SH_WRITETHROUGH - /* Turn on Write-through caching */ +#if defined(CONFIG_CACHE_WRITETHROUGH) + /* Write-through */ flags |= CCR_CACHE_WT; -#else - /* .. or default to Write-back */ +#elif defined(CONFIG_CACHE_WRITEBACK) + /* Write-back */ flags |= CCR_CACHE_CB; +#else + /* Off */ + flags &= ~CCR_CACHE_ENABLE; #endif ctrl_outl(flags, CCR); @@ -213,8 +217,11 @@ static void __init dsp_init(void) * Each processor family is still responsible for doing its own probing * and cache configuration in detect_cpu_and_cache_system(). */ -asmlinkage void __init sh_cpu_init(void) + +asmlinkage void __cpuinit sh_cpu_init(void) { + current_thread_info()->cpu = hard_smp_processor_id(); + /* First, probe the CPU */ detect_cpu_and_cache_system(); @@ -224,9 +231,10 @@ asmlinkage void __init sh_cpu_init(void) /* Init the cache */ cache_init(); - shm_align_mask = max_t(unsigned long, - current_cpu_data.dcache.way_size - 1, - PAGE_SIZE - 1); + if (raw_smp_processor_id() == 0) + shm_align_mask = max_t(unsigned long, + current_cpu_data.dcache.way_size - 1, + PAGE_SIZE - 1); /* Disable the FPU */ if (fpu_disabled) { @@ -265,6 +273,7 @@ asmlinkage void __init sh_cpu_init(void) * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So .. * we wake it up and hope that all is well. */ - ubc_wakeup(); + if (raw_smp_processor_id() == 0) + ubc_wakeup(); speculative_execution_init(); } diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile index 60bfc05cf354..8da8e178f09c 100644 --- a/arch/sh/kernel/cpu/irq/Makefile +++ b/arch/sh/kernel/cpu/irq/Makefile @@ -1,9 +1,7 @@ # # Makefile for the Linux/SuperH CPU-specifc IRQ handlers. # -obj-y += imask.o +obj-y += imask.o intc.o obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o -obj-$(CONFIG_CPU_HAS_INTC_IRQ) += intc.o -obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c index 9345a7130e9e..6ac018c15e03 100644 --- a/arch/sh/kernel/cpu/irq/intc.c +++ b/arch/sh/kernel/cpu/irq/intc.c @@ -20,145 +20,258 @@ #include <linux/module.h> #include <linux/io.h> #include <linux/interrupt.h> +#include <linux/bootmem.h> + +#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ + ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ + ((addr_e) << 16) | ((addr_d << 24))) + +#define _INTC_SHIFT(h) (h & 0x1f) +#define _INTC_WIDTH(h) ((h >> 5) & 0xf) +#define _INTC_FN(h) ((h >> 9) & 0xf) +#define _INTC_MODE(h) ((h >> 13) & 0x7) +#define _INTC_ADDR_E(h) ((h >> 16) & 0xff) +#define _INTC_ADDR_D(h) ((h >> 24) & 0xff) + +struct intc_handle_int { + unsigned int irq; + unsigned long handle; +}; + +struct intc_desc_int { + unsigned long *reg; +#ifdef CONFIG_SMP + unsigned long *smp; +#endif + unsigned int nr_reg; + struct intc_handle_int *prio; + unsigned int nr_prio; + struct intc_handle_int *sense; + unsigned int nr_sense; + struct irq_chip chip; +}; -#define _INTC_MK(fn, idx, bit, value) \ - ((fn) << 24 | ((value) << 16) | ((idx) << 8) | (bit)) -#define _INTC_FN(h) (h >> 24) -#define _INTC_VALUE(h) ((h >> 16) & 0xff) -#define _INTC_IDX(h) ((h >> 8) & 0xff) -#define _INTC_BIT(h) (h & 0xff) +#ifdef CONFIG_SMP +#define IS_SMP(x) x.smp +#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c)) +#define SMP_NR(d, x) ((d->smp[(x)] >> 8) ? (d->smp[(x)] >> 8) : 1) +#else +#define IS_SMP(x) 0 +#define INTC_REG(d, x, c) (d->reg[(x)]) +#define SMP_NR(d, x) 1 +#endif -#define _INTC_PTR(desc, member, data) \ - (desc->member + _INTC_IDX(data)) +static unsigned int intc_prio_level[NR_IRQS]; /* for now */ -static inline struct intc_desc *get_intc_desc(unsigned int irq) +static inline struct intc_desc_int *get_intc_desc(unsigned int irq) { struct irq_chip *chip = get_irq_chip(irq); - return (void *)((char *)chip - offsetof(struct intc_desc, chip)); + return (void *)((char *)chip - offsetof(struct intc_desc_int, chip)); } static inline unsigned int set_field(unsigned int value, unsigned int field_value, - unsigned int width, - unsigned int shift) + unsigned int handle) { + unsigned int width = _INTC_WIDTH(handle); + unsigned int shift = _INTC_SHIFT(handle); + value &= ~(((1 << width) - 1) << shift); value |= field_value << shift; return value; } -static inline unsigned int set_prio_field(struct intc_desc *desc, - unsigned int value, - unsigned int priority, - unsigned int data) +static void write_8(unsigned long addr, unsigned long h, unsigned long data) { - unsigned int width = _INTC_PTR(desc, prio_regs, data)->field_width; - - return set_field(value, priority, width, _INTC_BIT(data)); + ctrl_outb(set_field(0, data, h), addr); } -static void disable_prio_16(struct intc_desc *desc, unsigned int data) +static void write_16(unsigned long addr, unsigned long h, unsigned long data) { - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; - - ctrl_outw(set_prio_field(desc, ctrl_inw(addr), 0, data), addr); + ctrl_outw(set_field(0, data, h), addr); } -static void enable_prio_16(struct intc_desc *desc, unsigned int data) +static void write_32(unsigned long addr, unsigned long h, unsigned long data) { - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; - unsigned int prio = _INTC_VALUE(data); - - ctrl_outw(set_prio_field(desc, ctrl_inw(addr), prio, data), addr); + ctrl_outl(set_field(0, data, h), addr); } -static void disable_prio_32(struct intc_desc *desc, unsigned int data) +static void modify_8(unsigned long addr, unsigned long h, unsigned long data) { - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; - - ctrl_outl(set_prio_field(desc, ctrl_inl(addr), 0, data), addr); + ctrl_outb(set_field(ctrl_inb(addr), data, h), addr); } -static void enable_prio_32(struct intc_desc *desc, unsigned int data) +static void modify_16(unsigned long addr, unsigned long h, unsigned long data) { - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; - unsigned int prio = _INTC_VALUE(data); - - ctrl_outl(set_prio_field(desc, ctrl_inl(addr), prio, data), addr); + ctrl_outw(set_field(ctrl_inw(addr), data, h), addr); } -static void disable_mask_8(struct intc_desc *desc, unsigned int data) +static void modify_32(unsigned long addr, unsigned long h, unsigned long data) { - ctrl_outb(1 << _INTC_BIT(data), - _INTC_PTR(desc, mask_regs, data)->set_reg); + ctrl_outl(set_field(ctrl_inl(addr), data, h), addr); } -static void enable_mask_8(struct intc_desc *desc, unsigned int data) +enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 }; + +static void (*intc_reg_fns[])(unsigned long addr, + unsigned long h, + unsigned long data) = { + [REG_FN_WRITE_BASE + 0] = write_8, + [REG_FN_WRITE_BASE + 1] = write_16, + [REG_FN_WRITE_BASE + 3] = write_32, + [REG_FN_MODIFY_BASE + 0] = modify_8, + [REG_FN_MODIFY_BASE + 1] = modify_16, + [REG_FN_MODIFY_BASE + 3] = modify_32, +}; + +enum { MODE_ENABLE_REG = 0, /* Bit(s) set -> interrupt enabled */ + MODE_MASK_REG, /* Bit(s) set -> interrupt disabled */ + MODE_DUAL_REG, /* Two registers, set bit to enable / disable */ + MODE_PRIO_REG, /* Priority value written to enable interrupt */ + MODE_PCLR_REG, /* Above plus all bits set to disable interrupt */ +}; + +static void intc_mode_field(unsigned long addr, + unsigned long handle, + void (*fn)(unsigned long, + unsigned long, + unsigned long), + unsigned int irq) { - ctrl_outb(1 << _INTC_BIT(data), - _INTC_PTR(desc, mask_regs, data)->clr_reg); + fn(addr, handle, ((1 << _INTC_WIDTH(handle)) - 1)); } -static void disable_mask_32(struct intc_desc *desc, unsigned int data) +static void intc_mode_zero(unsigned long addr, + unsigned long handle, + void (*fn)(unsigned long, + unsigned long, + unsigned long), + unsigned int irq) { - ctrl_outl(1 << _INTC_BIT(data), - _INTC_PTR(desc, mask_regs, data)->set_reg); + fn(addr, handle, 0); } -static void enable_mask_32(struct intc_desc *desc, unsigned int data) +static void intc_mode_prio(unsigned long addr, + unsigned long handle, + void (*fn)(unsigned long, + unsigned long, + unsigned long), + unsigned int irq) { - ctrl_outl(1 << _INTC_BIT(data), - _INTC_PTR(desc, mask_regs, data)->clr_reg); + fn(addr, handle, intc_prio_level[irq]); } -enum { REG_FN_ERROR=0, - REG_FN_MASK_8, REG_FN_MASK_32, - REG_FN_PRIO_16, REG_FN_PRIO_32 }; - -static struct { - void (*enable)(struct intc_desc *, unsigned int); - void (*disable)(struct intc_desc *, unsigned int); -} intc_reg_fns[] = { - [REG_FN_MASK_8] = { enable_mask_8, disable_mask_8 }, - [REG_FN_MASK_32] = { enable_mask_32, disable_mask_32 }, - [REG_FN_PRIO_16] = { enable_prio_16, disable_prio_16 }, - [REG_FN_PRIO_32] = { enable_prio_32, disable_prio_32 }, +static void (*intc_enable_fns[])(unsigned long addr, + unsigned long handle, + void (*fn)(unsigned long, + unsigned long, + unsigned long), + unsigned int irq) = { + [MODE_ENABLE_REG] = intc_mode_field, + [MODE_MASK_REG] = intc_mode_zero, + [MODE_DUAL_REG] = intc_mode_field, + [MODE_PRIO_REG] = intc_mode_prio, + [MODE_PCLR_REG] = intc_mode_prio, }; -static void intc_enable(unsigned int irq) +static void (*intc_disable_fns[])(unsigned long addr, + unsigned long handle, + void (*fn)(unsigned long, + unsigned long, + unsigned long), + unsigned int irq) = { + [MODE_ENABLE_REG] = intc_mode_zero, + [MODE_MASK_REG] = intc_mode_field, + [MODE_DUAL_REG] = intc_mode_field, + [MODE_PRIO_REG] = intc_mode_zero, + [MODE_PCLR_REG] = intc_mode_field, +}; + +static inline void _intc_enable(unsigned int irq, unsigned long handle) { - struct intc_desc *desc = get_intc_desc(irq); - unsigned int data = (unsigned int) get_irq_chip_data(irq); + struct intc_desc_int *d = get_intc_desc(irq); + unsigned long addr; + unsigned int cpu; + + for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) { + addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu); + intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\ + [_INTC_FN(handle)], irq); + } +} - intc_reg_fns[_INTC_FN(data)].enable(desc, data); +static void intc_enable(unsigned int irq) +{ + _intc_enable(irq, (unsigned long)get_irq_chip_data(irq)); } static void intc_disable(unsigned int irq) { - struct intc_desc *desc = get_intc_desc(irq); - unsigned int data = (unsigned int) get_irq_chip_data(irq); - - intc_reg_fns[_INTC_FN(data)].disable(desc, data); + struct intc_desc_int *d = get_intc_desc(irq); + unsigned long handle = (unsigned long) get_irq_chip_data(irq); + unsigned long addr; + unsigned int cpu; + + for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { + addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu); + intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\ + [_INTC_FN(handle)], irq); + } } -static void set_sense_16(struct intc_desc *desc, unsigned int data) +static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, + unsigned int nr_hp, + unsigned int irq) { - unsigned long addr = _INTC_PTR(desc, sense_regs, data)->reg; - unsigned int width = _INTC_PTR(desc, sense_regs, data)->field_width; - unsigned int bit = _INTC_BIT(data); - unsigned int value = _INTC_VALUE(data); + int i; + + /* this doesn't scale well, but... + * + * this function should only be used for cerain uncommon + * operations such as intc_set_priority() and intc_set_sense() + * and in those rare cases performance doesn't matter that much. + * keeping the memory footprint low is more important. + * + * one rather simple way to speed this up and still keep the + * memory footprint down is to make sure the array is sorted + * and then perform a bisect to lookup the irq. + */ - ctrl_outw(set_field(ctrl_inw(addr), value, width, bit), addr); + for (i = 0; i < nr_hp; i++) { + if ((hp + i)->irq != irq) + continue; + + return hp + i; + } + + return NULL; } -static void set_sense_32(struct intc_desc *desc, unsigned int data) +int intc_set_priority(unsigned int irq, unsigned int prio) { - unsigned long addr = _INTC_PTR(desc, sense_regs, data)->reg; - unsigned int width = _INTC_PTR(desc, sense_regs, data)->field_width; - unsigned int bit = _INTC_BIT(data); - unsigned int value = _INTC_VALUE(data); + struct intc_desc_int *d = get_intc_desc(irq); + struct intc_handle_int *ihp; + + if (!intc_prio_level[irq] || prio <= 1) + return -EINVAL; + + ihp = intc_find_irq(d->prio, d->nr_prio, irq); + if (ihp) { + if (prio >= (1 << _INTC_WIDTH(ihp->handle))) + return -EINVAL; - ctrl_outl(set_field(ctrl_inl(addr), value, width, bit), addr); + intc_prio_level[irq] = prio; + + /* + * only set secondary masking method directly + * primary masking method is using intc_prio_level[irq] + * priority level will be set during next enable() + */ + + if (_INTC_FN(ihp->handle) != REG_FN_ERR) + _intc_enable(irq, ihp->handle); + } + return 0; } #define VALID(x) (x | 0x80) @@ -172,79 +285,38 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { static int intc_set_sense(unsigned int irq, unsigned int type) { - struct intc_desc *desc = get_intc_desc(irq); + struct intc_desc_int *d = get_intc_desc(irq); unsigned char value = intc_irq_sense_table[type & IRQ_TYPE_SENSE_MASK]; - unsigned int i, j, data, bit; - intc_enum enum_id = 0; - - for (i = 0; i < desc->nr_vectors; i++) { - struct intc_vect *vect = desc->vectors + i; - - if (evt2irq(vect->vect) != irq) - continue; + struct intc_handle_int *ihp; + unsigned long addr; - enum_id = vect->enum_id; - break; - } - - if (!enum_id || !value) + if (!value) return -EINVAL; - value ^= VALID(0); - - for (i = 0; i < desc->nr_sense_regs; i++) { - struct intc_sense_reg *sr = desc->sense_regs + i; - - for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) { - if (sr->enum_ids[j] != enum_id) - continue; - - bit = sr->reg_width - ((j + 1) * sr->field_width); - data = _INTC_MK(0, i, bit, value); - - switch(sr->reg_width) { - case 16: - set_sense_16(desc, data); - break; - case 32: - set_sense_32(desc, data); - break; - } - - return 0; - } + ihp = intc_find_irq(d->sense, d->nr_sense, irq); + if (ihp) { + addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0); + intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value); } - - return -EINVAL; + return 0; } -static unsigned int __init intc_find_mask_handler(unsigned int width) +static unsigned int __init intc_get_reg(struct intc_desc_int *d, + unsigned long address) { - switch (width) { - case 8: - return REG_FN_MASK_8; - case 32: - return REG_FN_MASK_32; - } + unsigned int k; - BUG(); - return REG_FN_ERROR; -} - -static unsigned int __init intc_find_prio_handler(unsigned int width) -{ - switch (width) { - case 16: - return REG_FN_PRIO_16; - case 32: - return REG_FN_PRIO_32; + for (k = 0; k < d->nr_reg; k++) { + if (d->reg[k] == address) + return k; } BUG(); - return REG_FN_ERROR; + return 0; } -static intc_enum __init intc_grp_id(struct intc_desc *desc, intc_enum enum_id) +static intc_enum __init intc_grp_id(struct intc_desc *desc, + intc_enum enum_id) { struct intc_group *g = desc->groups; unsigned int i, j; @@ -289,10 +361,12 @@ static unsigned int __init intc_prio_value(struct intc_desc *desc, } static unsigned int __init intc_mask_data(struct intc_desc *desc, + struct intc_desc_int *d, intc_enum enum_id, int do_grps) { struct intc_mask_reg *mr = desc->mask_regs; - unsigned int i, j, fn; + unsigned int i, j, fn, mode; + unsigned long reg_e, reg_d; for (i = 0; mr && enum_id && i < desc->nr_mask_regs; i++) { mr = desc->mask_regs + i; @@ -301,25 +375,46 @@ static unsigned int __init intc_mask_data(struct intc_desc *desc, if (mr->enum_ids[j] != enum_id) continue; - fn = intc_find_mask_handler(mr->reg_width); - if (fn == REG_FN_ERROR) - return 0; + if (mr->set_reg && mr->clr_reg) { + fn = REG_FN_WRITE_BASE; + mode = MODE_DUAL_REG; + reg_e = mr->clr_reg; + reg_d = mr->set_reg; + } else { + fn = REG_FN_MODIFY_BASE; + if (mr->set_reg) { + mode = MODE_ENABLE_REG; + reg_e = mr->set_reg; + reg_d = mr->set_reg; + } else { + mode = MODE_MASK_REG; + reg_e = mr->clr_reg; + reg_d = mr->clr_reg; + } + } - return _INTC_MK(fn, i, (mr->reg_width - 1) - j, 0); + fn += (mr->reg_width >> 3) - 1; + return _INTC_MK(fn, mode, + intc_get_reg(d, reg_e), + intc_get_reg(d, reg_d), + 1, + (mr->reg_width - 1) - j); } } if (do_grps) - return intc_mask_data(desc, intc_grp_id(desc, enum_id), 0); + return intc_mask_data(desc, d, intc_grp_id(desc, enum_id), 0); return 0; } static unsigned int __init intc_prio_data(struct intc_desc *desc, + struct intc_desc_int *d, intc_enum enum_id, int do_grps) { struct intc_prio_reg *pr = desc->prio_regs; - unsigned int i, j, fn, bit, prio; + unsigned int i, j, fn, mode, bit; + unsigned long reg_e, reg_d; for (i = 0; pr && enum_id && i < desc->nr_prio_regs; i++) { pr = desc->prio_regs + i; @@ -328,28 +423,72 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc, if (pr->enum_ids[j] != enum_id) continue; - fn = intc_find_prio_handler(pr->reg_width); - if (fn == REG_FN_ERROR) - return 0; + if (pr->set_reg && pr->clr_reg) { + fn = REG_FN_WRITE_BASE; + mode = MODE_PCLR_REG; + reg_e = pr->set_reg; + reg_d = pr->clr_reg; + } else { + fn = REG_FN_MODIFY_BASE; + mode = MODE_PRIO_REG; + if (!pr->set_reg) + BUG(); + reg_e = pr->set_reg; + reg_d = pr->set_reg; + } - prio = intc_prio_value(desc, enum_id, 1); + fn += (pr->reg_width >> 3) - 1; bit = pr->reg_width - ((j + 1) * pr->field_width); BUG_ON(bit < 0); - return _INTC_MK(fn, i, bit, prio); + return _INTC_MK(fn, mode, + intc_get_reg(d, reg_e), + intc_get_reg(d, reg_d), + pr->field_width, bit); } } if (do_grps) - return intc_prio_data(desc, intc_grp_id(desc, enum_id), 0); + return intc_prio_data(desc, d, intc_grp_id(desc, enum_id), 0); return 0; } -static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id, +static unsigned int __init intc_sense_data(struct intc_desc *desc, + struct intc_desc_int *d, + intc_enum enum_id) +{ + struct intc_sense_reg *sr = desc->sense_regs; + unsigned int i, j, fn, bit; + + for (i = 0; sr && enum_id && i < desc->nr_sense_regs; i++) { + sr = desc->sense_regs + i; + + for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) { + if (sr->enum_ids[j] != enum_id) + continue; + + fn = REG_FN_MODIFY_BASE; + fn += (sr->reg_width >> 3) - 1; + bit = sr->reg_width - ((j + 1) * sr->field_width); + + BUG_ON(bit < 0); + + return _INTC_MK(fn, 0, intc_get_reg(d, sr->reg), + 0, sr->field_width, bit); + } + } + + return 0; +} + +static void __init intc_register_irq(struct intc_desc *desc, + struct intc_desc_int *d, + intc_enum enum_id, unsigned int irq) { + struct intc_handle_int *hp; unsigned int data[2], primary; /* Prefer single interrupt source bitmap over other combinations: @@ -359,15 +498,15 @@ static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id, * 4. priority, multiple interrupt sources (groups) */ - data[0] = intc_mask_data(desc, enum_id, 0); - data[1] = intc_prio_data(desc, enum_id, 0); + data[0] = intc_mask_data(desc, d, enum_id, 0); + data[1] = intc_prio_data(desc, d, enum_id, 0); primary = 0; if (!data[0] && data[1]) primary = 1; - data[0] = data[0] ? data[0] : intc_mask_data(desc, enum_id, 1); - data[1] = data[1] ? data[1] : intc_prio_data(desc, enum_id, 1); + data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1); + data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1); if (!data[primary]) primary ^= 1; @@ -375,31 +514,118 @@ static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id, BUG_ON(!data[primary]); /* must have primary masking method */ disable_irq_nosync(irq); - set_irq_chip_and_handler_name(irq, &desc->chip, + set_irq_chip_and_handler_name(irq, &d->chip, handle_level_irq, "level"); set_irq_chip_data(irq, (void *)data[primary]); + /* record the desired priority level */ + intc_prio_level[irq] = intc_prio_value(desc, enum_id, 1); + /* enable secondary masking method if present */ if (data[!primary]) - intc_reg_fns[_INTC_FN(data[!primary])].enable(desc, - data[!primary]); + _intc_enable(irq, data[!primary]); + + /* add irq to d->prio list if priority is available */ + if (data[1]) { + hp = d->prio + d->nr_prio; + hp->irq = irq; + hp->handle = data[1]; + + if (primary) { + /* + * only secondary priority should access registers, so + * set _INTC_FN(h) = REG_FN_ERR for intc_set_priority() + */ + + hp->handle &= ~_INTC_MK(0x0f, 0, 0, 0, 0, 0); + hp->handle |= _INTC_MK(REG_FN_ERR, 0, 0, 0, 0, 0); + } + d->nr_prio++; + } + + /* add irq to d->sense list if sense is available */ + data[0] = intc_sense_data(desc, d, enum_id); + if (data[0]) { + (d->sense + d->nr_sense)->irq = irq; + (d->sense + d->nr_sense)->handle = data[0]; + d->nr_sense++; + } /* irq should be disabled by default */ - desc->chip.mask(irq); + d->chip.mask(irq); } +static unsigned int __init save_reg(struct intc_desc_int *d, + unsigned int cnt, + unsigned long value, + unsigned int smp) +{ + if (value) { + d->reg[cnt] = value; +#ifdef CONFIG_SMP + d->smp[cnt] = smp; +#endif + return 1; + } + + return 0; +} + + void __init register_intc_controller(struct intc_desc *desc) { - unsigned int i; + unsigned int i, k, smp; + struct intc_desc_int *d; + + d = alloc_bootmem(sizeof(*d)); + + d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0; + d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0; + d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; + + d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg)); +#ifdef CONFIG_SMP + d->smp = alloc_bootmem(d->nr_reg * sizeof(*d->smp)); +#endif + k = 0; + + if (desc->mask_regs) { + for (i = 0; i < desc->nr_mask_regs; i++) { + smp = IS_SMP(desc->mask_regs[i]); + k += save_reg(d, k, desc->mask_regs[i].set_reg, smp); + k += save_reg(d, k, desc->mask_regs[i].clr_reg, smp); + } + } + + if (desc->prio_regs) { + d->prio = alloc_bootmem(desc->nr_vectors * sizeof(*d->prio)); + + for (i = 0; i < desc->nr_prio_regs; i++) { + smp = IS_SMP(desc->prio_regs[i]); + k += save_reg(d, k, desc->prio_regs[i].set_reg, smp); + k += save_reg(d, k, desc->prio_regs[i].clr_reg, smp); + } + } + + if (desc->sense_regs) { + d->sense = alloc_bootmem(desc->nr_vectors * sizeof(*d->sense)); + + for (i = 0; i < desc->nr_sense_regs; i++) { + k += save_reg(d, k, desc->sense_regs[i].reg, 0); + } + } + + BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ - desc->chip.mask = intc_disable; - desc->chip.unmask = intc_enable; - desc->chip.mask_ack = intc_disable; - desc->chip.set_type = intc_set_sense; + d->chip.name = desc->name; + d->chip.mask = intc_disable; + d->chip.unmask = intc_enable; + d->chip.mask_ack = intc_disable; + d->chip.set_type = intc_set_sense; for (i = 0; i < desc->nr_vectors; i++) { struct intc_vect *vect = desc->vectors + i; - intc_register_irq(desc, vect->enum_id, evt2irq(vect->vect)); + intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect)); } } diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c deleted file mode 100644 index cc5221390e09..000000000000 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Interrupt handling for INTC2-based IRQ. - * - * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) - * Copyright (C) 2005, 2006 Paul Mundt (lethal@linux-sh.org) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * These are the "new Hitachi style" interrupts, as present on the - * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780. - */ -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/io.h> -#include <asm/smp.h> - -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); - 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); - struct intc2_desc *d = get_intc2_desc(irq); - - ctrl_outl(1 << p->msk_shift, d->mskclr_base + p->msk_offset + - (hard_smp_processor_id() * 4)); -} - -/* - * Setup an INTC2 style interrupt. - * NOTE: Unlike IPR interrupts, parameters are not shifted by this code, - * allowing the use of the numbers straight out of the datasheet. - * For example: - * PIO1 which is INTPRI00[19,16] and INTMSK00[13] - * would be: ^ ^ ^ ^ - * | | | | - * { 84, 0, 16, 0, 13 }, - * - * in the intc2_data table. - */ -void register_intc2_controller(struct intc2_desc *desc) -{ - int 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 = desc->intc2_data + i; - - disable_irq_nosync(p->irq); - - if (desc->prio_base) { - /* Set the priority level */ - local_irq_save(flags); - - 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); - } - - set_irq_chip_and_handler_name(p->irq, &desc->chip, - handle_level_irq, "level"); - set_irq_chip_data(p->irq, p); - - disable_intc2_irq(p->irq); - } -} diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index abbf17427e52..5916d9096b99 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c @@ -10,26 +10,25 @@ * 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_SH7619) - current_cpu_data.type = CPU_SH7619; - current_cpu_data.dcache.ways = 4; - current_cpu_data.dcache.way_incr = (1<<12); - current_cpu_data.dcache.sets = 256; - current_cpu_data.dcache.entry_shift = 4; - current_cpu_data.dcache.linesz = L1_CACHE_BYTES; - current_cpu_data.dcache.flags = 0; + boot_cpu_data.type = CPU_SH7619; + boot_cpu_data.dcache.ways = 4; + boot_cpu_data.dcache.way_incr = (1<<12); + boot_cpu_data.dcache.sets = 256; + boot_cpu_data.dcache.entry_shift = 4; + boot_cpu_data.dcache.linesz = L1_CACHE_BYTES; + boot_cpu_data.dcache.flags = 0; #endif /* * SH-2 doesn't have separate caches */ - current_cpu_data.dcache.flags |= SH_CACHE_COMBINED; - current_cpu_data.icache = current_cpu_data.dcache; + boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED; + boot_cpu_data.icache = boot_cpu_data.dcache; return 0; } diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index a979b981e6a3..ec6adc3f306f 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -12,6 +12,61 @@ #include <linux/serial.h> #include <asm/sci.h> +enum { + UNUSED = 0, + + /* interrupt sources */ + IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, + WDT, EDMAC, CMT0, CMT1, + SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI, + SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI, + SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI, + HIF_HIFI, HIF_HIFBI, + DMAC0, DMAC1, DMAC2, DMAC3, + SIOF, + + /* interrupt groups */ + SCIF0, SCIF1, SCIF2, +}; + +static struct intc_vect vectors[] __initdata = { + INTC_IRQ(IRQ0, 64), INTC_IRQ(IRQ1, 65), + INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67), + INTC_IRQ(IRQ4, 80), INTC_IRQ(IRQ5, 81), + INTC_IRQ(IRQ6, 82), INTC_IRQ(IRQ7, 83), + INTC_IRQ(WDT, 84), INTC_IRQ(EDMAC, 85), + INTC_IRQ(CMT0, 86), INTC_IRQ(CMT1, 87), + INTC_IRQ(SCIF0_ERI, 88), INTC_IRQ(SCIF0_RXI, 89), + INTC_IRQ(SCIF0_BRI, 90), INTC_IRQ(SCIF0_TXI, 91), + INTC_IRQ(SCIF1_ERI, 92), INTC_IRQ(SCIF1_RXI, 93), + INTC_IRQ(SCIF1_BRI, 94), INTC_IRQ(SCIF1_TXI, 95), + INTC_IRQ(SCIF2_ERI, 96), INTC_IRQ(SCIF2_RXI, 97), + INTC_IRQ(SCIF2_BRI, 98), INTC_IRQ(SCIF2_TXI, 99), + INTC_IRQ(HIF_HIFI, 100), INTC_IRQ(HIF_HIFBI, 101), + INTC_IRQ(DMAC0, 104), INTC_IRQ(DMAC1, 105), + INTC_IRQ(DMAC2, 106), INTC_IRQ(DMAC3, 107), + INTC_IRQ(SIOF, 108), +}; + +static struct intc_group groups[] __initdata = { + INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), + INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI), + INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI), +}; + +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xf8140006, 0, 16, 4, /* IPRA */ { IRQ0, IRQ1, IRQ2, IRQ3 } }, + { 0xf8140008, 0, 16, 4, /* IPRB */ { IRQ4, IRQ5, IRQ6, IRQ7 } }, + { 0xf8080000, 0, 16, 4, /* IPRC */ { WDT, EDMAC, CMT0, CMT1 } }, + { 0xf8080002, 0, 16, 4, /* IPRD */ { SCIF0, SCIF1, SCIF2 } }, + { 0xf8080004, 0, 16, 4, /* IPRE */ { HIF_HIFI, HIF_HIFBI } }, + { 0xf8080006, 0, 16, 4, /* IPRF */ { DMAC0, DMAC1, DMAC2, DMAC3 } }, + { 0xf8080008, 0, 16, 4, /* IPRG */ { SIOF } }, +}; + +static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, groups, + NULL, NULL, prio_registers, NULL); + static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xf8400000, @@ -52,43 +107,7 @@ static int __init sh7619_devices_setup(void) } __initcall(sh7619_devices_setup); -static struct ipr_data ipr_irq_table[] = { - { 86, 0, 4, 2 }, /* CMI0 */ - { 88, 1, 12, 3 }, /* SCIF0_ERI */ - { 89, 1, 12, 3 }, /* SCIF0_RXI */ - { 90, 1, 12, 3 }, /* SCIF0_BRI */ - { 91, 1, 12, 3 }, /* SCIF0_TXI */ - { 92, 1, 8, 3 }, /* SCIF1_ERI */ - { 93, 1, 8, 3 }, /* SCIF1_RXI */ - { 94, 1, 8, 3 }, /* SCIF1_BRI */ - { 95, 1, 8, 3 }, /* SCIF1_TXI */ - { 96, 1, 4, 3 }, /* SCIF2_ERI */ - { 97, 1, 4, 3 }, /* SCIF2_RXI */ - { 98, 1, 4, 3 }, /* SCIF2_BRI */ - { 99, 1, 4, 3 }, /* SCIF2_TXI */ -}; - -static unsigned long ipr_offsets[] = { - 0xf8080000, /* IPRC */ - 0xf8080002, /* IPRD */ - 0xf8080004, /* IPRE */ - 0xf8080006, /* IPRF */ - 0xf8080008, /* IPRG */ -}; - -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 plat_irq_setup(void) { - register_ipr_controller(&ipr_irq_desc); + register_intc_controller(&intc_desc); } diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c index f455c3509789..6d02465704b9 100644 --- a/arch/sh/kernel/cpu/sh2a/probe.c +++ b/arch/sh/kernel/cpu/sh2a/probe.c @@ -17,15 +17,15 @@ int __init detect_cpu_and_cache_system(void) { /* Just SH7206 for now .. */ - current_cpu_data.type = CPU_SH7206; - current_cpu_data.flags |= CPU_HAS_OP32; + boot_cpu_data.type = CPU_SH7206; + boot_cpu_data.flags |= CPU_HAS_OP32; - current_cpu_data.dcache.ways = 4; - current_cpu_data.dcache.way_incr = (1 << 11); - current_cpu_data.dcache.sets = 128; - current_cpu_data.dcache.entry_shift = 4; - current_cpu_data.dcache.linesz = L1_CACHE_BYTES; - current_cpu_data.dcache.flags = 0; + boot_cpu_data.dcache.ways = 4; + boot_cpu_data.dcache.way_incr = (1 << 11); + boot_cpu_data.dcache.sets = 128; + boot_cpu_data.dcache.entry_shift = 4; + boot_cpu_data.dcache.linesz = L1_CACHE_BYTES; + boot_cpu_data.dcache.flags = 0; /* * The icache is the same as the dcache as far as this setup is @@ -33,7 +33,7 @@ int __init detect_cpu_and_cache_system(void) * lacks the U bit that the dcache has, none of this has any bearing * on the cache info. */ - current_cpu_data.icache = current_cpu_data.dcache; + boot_cpu_data.icache = boot_cpu_data.dcache; return 0; } diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index deab16500167..bd745aa87222 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -12,27 +12,184 @@ #include <linux/serial.h> #include <asm/sci.h> +enum { + UNUSED = 0, + + /* interrupt sources */ + IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, + PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7, + ADC_ADI0, ADC_ADI1, + DMAC0_DEI, DMAC0_HEI, DMAC1_DEI, DMAC1_HEI, + DMAC2_DEI, DMAC2_HEI, DMAC3_DEI, DMAC3_HEI, + DMAC4_DEI, DMAC4_HEI, DMAC5_DEI, DMAC5_HEI, + DMAC6_DEI, DMAC6_HEI, DMAC7_DEI, DMAC7_HEI, + CMT0, CMT1, BSC, WDT, + MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D, + MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F, + MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U, + MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U, + MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V, + MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V, + MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W, + POE2_OEI1, POE2_OEI2, + MTU2S_TGI3A, MTU2S_TGI3B, MTU2S_TGI3C, MTU2S_TGI3D, MTU2S_TCI3V, + MTU2S_TGI4A, MTU2S_TGI4B, MTU2S_TGI4C, MTU2S_TGI4D, MTU2S_TCI4V, + MTU2S_TGI5U, MTU2S_TGI5V, MTU2S_TGI5W, + POE2_OEI3, + IIC3_STPI, IIC3_NAKI, IIC3_RXI, IIC3_TXI, IIC3_TEI, + SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI, + SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI, + SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI, + SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI, + + /* interrupt groups */ + PINT, DMAC0, DMAC1, DMAC2, DMAC3, DMAC4, DMAC5, DMAC6, DMAC7, + MTU0_ABCD, MTU0_VEF, MTU1_AB, MTU1_VU, MTU2_AB, MTU2_VU, + MTU3_ABCD, MTU4_ABCD, MTU5, POE2_12, MTU3S_ABCD, MTU4S_ABCD, MTU5S, + IIC3, SCIF0, SCIF1, SCIF2, SCIF3, +}; + +static struct intc_vect vectors[] __initdata = { + INTC_IRQ(IRQ0, 64), INTC_IRQ(IRQ1, 65), + INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67), + INTC_IRQ(IRQ4, 68), INTC_IRQ(IRQ5, 69), + INTC_IRQ(IRQ6, 70), INTC_IRQ(IRQ7, 71), + INTC_IRQ(PINT0, 80), INTC_IRQ(PINT1, 81), + INTC_IRQ(PINT2, 82), INTC_IRQ(PINT3, 83), + INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85), + INTC_IRQ(PINT6, 86), INTC_IRQ(PINT7, 87), + INTC_IRQ(ADC_ADI0, 92), INTC_IRQ(ADC_ADI1, 96), + INTC_IRQ(DMAC0_DEI, 108), INTC_IRQ(DMAC0_HEI, 109), + INTC_IRQ(DMAC1_DEI, 112), INTC_IRQ(DMAC1_HEI, 113), + INTC_IRQ(DMAC2_DEI, 116), INTC_IRQ(DMAC2_HEI, 117), + INTC_IRQ(DMAC3_DEI, 120), INTC_IRQ(DMAC3_HEI, 121), + INTC_IRQ(DMAC4_DEI, 124), INTC_IRQ(DMAC4_HEI, 125), + INTC_IRQ(DMAC5_DEI, 128), INTC_IRQ(DMAC5_HEI, 129), + INTC_IRQ(DMAC6_DEI, 132), INTC_IRQ(DMAC6_HEI, 133), + INTC_IRQ(DMAC7_DEI, 136), INTC_IRQ(DMAC7_HEI, 137), + INTC_IRQ(CMT0, 140), INTC_IRQ(CMT1, 144), + INTC_IRQ(BSC, 148), INTC_IRQ(WDT, 152), + INTC_IRQ(MTU2_TGI0A, 156), INTC_IRQ(MTU2_TGI0B, 157), + INTC_IRQ(MTU2_TGI0C, 158), INTC_IRQ(MTU2_TGI0D, 159), + INTC_IRQ(MTU2_TCI0V, 160), + INTC_IRQ(MTU2_TGI0E, 161), INTC_IRQ(MTU2_TGI0F, 162), + INTC_IRQ(MTU2_TGI1A, 164), INTC_IRQ(MTU2_TGI1B, 165), + INTC_IRQ(MTU2_TCI1V, 168), INTC_IRQ(MTU2_TCI1U, 169), + INTC_IRQ(MTU2_TGI2A, 172), INTC_IRQ(MTU2_TGI2B, 173), + INTC_IRQ(MTU2_TCI2V, 176), INTC_IRQ(MTU2_TCI2U, 177), + INTC_IRQ(MTU2_TGI3A, 180), INTC_IRQ(MTU2_TGI3B, 181), + INTC_IRQ(MTU2_TGI3C, 182), INTC_IRQ(MTU2_TGI3D, 183), + INTC_IRQ(MTU2_TCI3V, 184), + INTC_IRQ(MTU2_TGI4A, 188), INTC_IRQ(MTU2_TGI4B, 189), + INTC_IRQ(MTU2_TGI4C, 190), INTC_IRQ(MTU2_TGI4D, 191), + INTC_IRQ(MTU2_TCI4V, 192), + INTC_IRQ(MTU2_TGI5U, 196), INTC_IRQ(MTU2_TGI5V, 197), + INTC_IRQ(MTU2_TGI5W, 198), + INTC_IRQ(POE2_OEI1, 200), INTC_IRQ(POE2_OEI2, 201), + INTC_IRQ(MTU2S_TGI3A, 204), INTC_IRQ(MTU2S_TGI3B, 205), + INTC_IRQ(MTU2S_TGI3C, 206), INTC_IRQ(MTU2S_TGI3D, 207), + INTC_IRQ(MTU2S_TCI3V, 208), + INTC_IRQ(MTU2S_TGI4A, 212), INTC_IRQ(MTU2S_TGI4B, 213), + INTC_IRQ(MTU2S_TGI4C, 214), INTC_IRQ(MTU2S_TGI4D, 215), + INTC_IRQ(MTU2S_TCI4V, 216), + INTC_IRQ(MTU2S_TGI5U, 220), INTC_IRQ(MTU2S_TGI5V, 221), + INTC_IRQ(MTU2S_TGI5W, 222), + INTC_IRQ(POE2_OEI3, 224), + INTC_IRQ(IIC3_STPI, 228), INTC_IRQ(IIC3_NAKI, 229), + INTC_IRQ(IIC3_RXI, 230), INTC_IRQ(IIC3_TXI, 231), + INTC_IRQ(IIC3_TEI, 232), + INTC_IRQ(SCIF0_BRI, 240), INTC_IRQ(SCIF0_ERI, 241), + INTC_IRQ(SCIF0_RXI, 242), INTC_IRQ(SCIF0_TXI, 243), + INTC_IRQ(SCIF1_BRI, 244), INTC_IRQ(SCIF1_ERI, 245), + INTC_IRQ(SCIF1_RXI, 246), INTC_IRQ(SCIF1_TXI, 247), + INTC_IRQ(SCIF2_BRI, 248), INTC_IRQ(SCIF2_ERI, 249), + INTC_IRQ(SCIF2_RXI, 250), INTC_IRQ(SCIF2_TXI, 251), + INTC_IRQ(SCIF3_BRI, 252), INTC_IRQ(SCIF3_ERI, 253), + INTC_IRQ(SCIF3_RXI, 254), INTC_IRQ(SCIF3_TXI, 255), +}; + +static struct intc_group groups[] __initdata = { + INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3, + PINT4, PINT5, PINT6, PINT7), + INTC_GROUP(DMAC0, DMAC0_DEI, DMAC0_HEI), + INTC_GROUP(DMAC1, DMAC1_DEI, DMAC1_HEI), + INTC_GROUP(DMAC2, DMAC2_DEI, DMAC2_HEI), + INTC_GROUP(DMAC3, DMAC3_DEI, DMAC3_HEI), + INTC_GROUP(DMAC4, DMAC4_DEI, DMAC4_HEI), + INTC_GROUP(DMAC5, DMAC5_DEI, DMAC5_HEI), + INTC_GROUP(DMAC6, DMAC6_DEI, DMAC6_HEI), + INTC_GROUP(DMAC7, DMAC7_DEI, DMAC7_HEI), + INTC_GROUP(MTU0_ABCD, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D), + INTC_GROUP(MTU0_VEF, MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F), + INTC_GROUP(MTU1_AB, MTU2_TGI1A, MTU2_TGI1B), + INTC_GROUP(MTU1_VU, MTU2_TCI1V, MTU2_TCI1U), + INTC_GROUP(MTU2_AB, MTU2_TGI2A, MTU2_TGI2B), + INTC_GROUP(MTU2_VU, MTU2_TCI2V, MTU2_TCI2U), + INTC_GROUP(MTU3_ABCD, MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D), + INTC_GROUP(MTU4_ABCD, MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D), + INTC_GROUP(MTU5, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W), + INTC_GROUP(POE2_12, POE2_OEI1, POE2_OEI2), + INTC_GROUP(MTU3S_ABCD, MTU2S_TGI3A, MTU2S_TGI3B, + MTU2S_TGI3C, MTU2S_TGI3D), + INTC_GROUP(MTU4S_ABCD, MTU2S_TGI4A, MTU2S_TGI4B, + MTU2S_TGI4C, MTU2S_TGI4D), + INTC_GROUP(MTU5S, MTU2S_TGI5U, MTU2S_TGI5V, MTU2S_TGI5W), + INTC_GROUP(IIC3, IIC3_STPI, IIC3_NAKI, IIC3_RXI, IIC3_TXI, IIC3_TEI), + INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI), + INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI), + INTC_GROUP(SCIF2, SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI), + INTC_GROUP(SCIF3, SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI), +}; + +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xfffe0818, 0, 16, 4, /* IPR01 */ { IRQ0, IRQ1, IRQ2, IRQ3 } }, + { 0xfffe081a, 0, 16, 4, /* IPR02 */ { IRQ4, IRQ5, IRQ6, IRQ7 } }, + { 0xfffe0820, 0, 16, 4, /* IPR05 */ { PINT, 0, ADC_ADI0, ADC_ADI1 } }, + { 0xfffe0c00, 0, 16, 4, /* IPR06 */ { DMAC0, DMAC1, DMAC2, DMAC3 } }, + { 0xfffe0c02, 0, 16, 4, /* IPR07 */ { DMAC4, DMAC5, DMAC6, DMAC7 } }, + { 0xfffe0c04, 0, 16, 4, /* IPR08 */ { CMT0, CMT1, BSC, WDT } }, + { 0xfffe0c06, 0, 16, 4, /* IPR09 */ { MTU0_ABCD, MTU0_VEF, + MTU1_AB, MTU1_VU } }, + { 0xfffe0c08, 0, 16, 4, /* IPR10 */ { MTU2_AB, MTU2_VU, + MTU3_ABCD, MTU2_TCI3V } }, + { 0xfffe0c0a, 0, 16, 4, /* IPR11 */ { MTU4_ABCD, MTU2_TCI4V, + MTU5, POE2_12 } }, + { 0xfffe0c0c, 0, 16, 4, /* IPR12 */ { MTU3S_ABCD, MTU2S_TCI3V, + MTU4S_ABCD, MTU2S_TCI4V } }, + { 0xfffe0c0e, 0, 16, 4, /* IPR13 */ { MTU5S, POE2_OEI3, IIC3, 0 } }, + { 0xfffe0c10, 0, 16, 4, /* IPR14 */ { SCIF0, SCIF1, SCIF2, SCIF3 } }, +}; + +static struct intc_mask_reg mask_registers[] __initdata = { + { 0xfffe0808, 0, 16, /* PINTER */ + { 0, 0, 0, 0, 0, 0, 0, 0, + PINT7, PINT6, PINT5, PINT4, PINT3, PINT2, PINT1, PINT0 } }, +}; + +static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups, + NULL, mask_registers, prio_registers, NULL); + static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xfffe8000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 241, 242, 243, 240}, + .irqs = { 241, 242, 243, 240 }, }, { .mapbase = 0xfffe8800, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 247, 244, 245, 246}, + .irqs = { 245, 246, 247, 244 }, }, { .mapbase = 0xfffe9000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 249, 250, 251, 248}, + .irqs = { 249, 250, 251, 248 }, }, { .mapbase = 0xfffe9800, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 253, 254, 255, 252}, + .irqs = { 253, 254, 255, 252 }, }, { .flags = 0, } @@ -57,57 +214,7 @@ static int __init sh7206_devices_setup(void) } __initcall(sh7206_devices_setup); -static struct ipr_data ipr_irq_table[] = { - { 140, 7, 12, 2 }, /* CMI0 */ - { 164, 8, 4, 2 }, /* MTU2_TGI1A */ - { 240, 13, 12, 3 }, /* SCIF0_BRI */ - { 241, 13, 12, 3 }, /* SCIF0_ERI */ - { 242, 13, 12, 3 }, /* SCIF0_RXI */ - { 243, 13, 12, 3 }, /* SCIF0_TXI */ - { 244, 13, 8, 3 }, /* SCIF1_BRI */ - { 245, 13, 8, 3 }, /* SCIF1_ERI */ - { 246, 13, 8, 3 }, /* SCIF1_RXI */ - { 247, 13, 8, 3 }, /* SCIF1_TXI */ - { 248, 13, 4, 3 }, /* SCIF2_BRI */ - { 249, 13, 4, 3 }, /* SCIF2_ERI */ - { 250, 13, 4, 3 }, /* SCIF2_RXI */ - { 251, 13, 4, 3 }, /* SCIF2_TXI */ - { 252, 13, 0, 3 }, /* SCIF3_BRI */ - { 253, 13, 0, 3 }, /* SCIF3_ERI */ - { 254, 13, 0, 3 }, /* SCIF3_RXI */ - { 255, 13, 0, 3 }, /* SCIF3_TXI */ -}; - -static unsigned long ipr_offsets[] = { - 0xfffe0818, /* IPR01 */ - 0xfffe081a, /* IPR02 */ - 0, /* unused */ - 0, /* unused */ - 0xfffe0820, /* IPR05 */ - 0xfffe0c00, /* IPR06 */ - 0xfffe0c02, /* IPR07 */ - 0xfffe0c04, /* IPR08 */ - 0xfffe0c06, /* IPR09 */ - 0xfffe0c08, /* IPR10 */ - 0xfffe0c0a, /* IPR11 */ - 0xfffe0c0c, /* IPR12 */ - 0xfffe0c0e, /* IPR13 */ - 0xfffe0c10, /* IPR14 */ -}; - -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 plat_irq_setup(void) { - register_ipr_controller(&ipr_irq_desc); + register_intc_controller(&intc_desc); } diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile index 55b750763f66..646eb6933614 100644 --- a/arch/sh/kernel/cpu/sh3/Makefile +++ b/arch/sh/kernel/cpu/sh3/Makefile @@ -6,12 +6,13 @@ obj-y := ex.o probe.o entry.o # CPU subtype setup obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o -obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh7709.o -obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh7709.o -obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh7708.o -obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh7709.o +obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh770x.o +obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh770x.o +obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh770x.o +obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh770x.o obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o +obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o # Primary on-chip clocks (common) clock-$(CONFIG_CPU_SH3) := clock-sh3.o @@ -19,5 +20,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7705) := clock-sh7705.o clock-$(CONFIG_CPU_SUBTYPE_SH7706) := clock-sh7706.o clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7710.o +clock-$(CONFIG_CPU_SUBTYPE_SH7720) := clock-sh7710.o obj-y += $(clock-y) diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c index 647623b22edc..bf579e061e09 100644 --- a/arch/sh/kernel/cpu/sh3/probe.c +++ b/arch/sh/kernel/cpu/sh3/probe.c @@ -50,44 +50,47 @@ int __init detect_cpu_and_cache_system(void) back_to_P1(); - current_cpu_data.dcache.ways = 4; - current_cpu_data.dcache.entry_shift = 4; - current_cpu_data.dcache.linesz = L1_CACHE_BYTES; - current_cpu_data.dcache.flags = 0; + boot_cpu_data.dcache.ways = 4; + boot_cpu_data.dcache.entry_shift = 4; + boot_cpu_data.dcache.linesz = L1_CACHE_BYTES; + boot_cpu_data.dcache.flags = 0; /* * 7709A/7729 has 16K cache (256-entry), while 7702 has only * 2K(direct) 7702 is not supported (yet) */ if (data0 == data1 && data2 == data3) { /* Shadow */ - current_cpu_data.dcache.way_incr = (1 << 11); - current_cpu_data.dcache.entry_mask = 0x7f0; - current_cpu_data.dcache.sets = 128; - current_cpu_data.type = CPU_SH7708; + boot_cpu_data.dcache.way_incr = (1 << 11); + boot_cpu_data.dcache.entry_mask = 0x7f0; + boot_cpu_data.dcache.sets = 128; + boot_cpu_data.type = CPU_SH7708; - current_cpu_data.flags |= CPU_HAS_MMU_PAGE_ASSOC; + boot_cpu_data.flags |= CPU_HAS_MMU_PAGE_ASSOC; } else { /* 7709A or 7729 */ - current_cpu_data.dcache.way_incr = (1 << 12); - current_cpu_data.dcache.entry_mask = 0xff0; - current_cpu_data.dcache.sets = 256; - current_cpu_data.type = CPU_SH7729; + boot_cpu_data.dcache.way_incr = (1 << 12); + boot_cpu_data.dcache.entry_mask = 0xff0; + boot_cpu_data.dcache.sets = 256; + boot_cpu_data.type = CPU_SH7729; #if defined(CONFIG_CPU_SUBTYPE_SH7706) - current_cpu_data.type = CPU_SH7706; + boot_cpu_data.type = CPU_SH7706; #endif #if defined(CONFIG_CPU_SUBTYPE_SH7710) - current_cpu_data.type = CPU_SH7710; + boot_cpu_data.type = CPU_SH7710; #endif #if defined(CONFIG_CPU_SUBTYPE_SH7712) - current_cpu_data.type = CPU_SH7712; + boot_cpu_data.type = CPU_SH7712; +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7720) + boot_cpu_data.type = CPU_SH7720; #endif #if defined(CONFIG_CPU_SUBTYPE_SH7705) - current_cpu_data.type = CPU_SH7705; + boot_cpu_data.type = CPU_SH7705; #if defined(CONFIG_SH7705_CACHE_32KB) - current_cpu_data.dcache.way_incr = (1 << 13); - current_cpu_data.dcache.entry_mask = 0x1ff0; - current_cpu_data.dcache.sets = 512; + boot_cpu_data.dcache.way_incr = (1 << 13); + boot_cpu_data.dcache.entry_mask = 0x1ff0; + boot_cpu_data.dcache.sets = 512; ctrl_outl(CCR_CACHE_32KB, CCR3); #else ctrl_outl(CCR_CACHE_16KB, CCR3); @@ -98,9 +101,8 @@ int __init detect_cpu_and_cache_system(void) /* * SH-3 doesn't have separate caches */ - current_cpu_data.dcache.flags |= SH_CACHE_COMBINED; - current_cpu_data.icache = current_cpu_data.dcache; + boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED; + boot_cpu_data.icache = boot_cpu_data.dcache; return 0; } - diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index ebd9d06d8bdd..f6c65f2659e9 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -1,7 +1,7 @@ /* * SH7705 Setup * - * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2006, 2007 Paul Mundt * Copyright (C) 2007 Nobuhiro Iwamatsu * * This file is subject to the terms and conditions of the GNU General Public @@ -10,8 +10,90 @@ */ #include <linux/platform_device.h> #include <linux/init.h> +#include <linux/irq.h> #include <linux/serial.h> #include <asm/sci.h> +#include <asm/rtc.h> + +enum { + UNUSED = 0, + + /* interrupt sources */ + IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, + PINT07, PINT815, + DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3, + SCIF0_ERI, SCIF0_RXI, SCIF0_TXI, + SCIF2_ERI, SCIF2_RXI, SCIF2_TXI, + ADC_ADI, + USB_USI0, USB_USI1, + TPU0, TPU1, TPU2, TPU3, + TMU0, TMU1, TMU2_TUNI, TMU2_TICPI, + RTC_ATI, RTC_PRI, RTC_CUI, + WDT, + REF_RCMI, + + /* interrupt groups */ + RTC, TMU2, DMAC, USB, SCIF2, SCIF0, +}; + +static struct intc_vect vectors[] __initdata = { + INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), + INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720), + INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820), + INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860), + INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0), + INTC_VECT(SCIF0_TXI, 0x8e0), + INTC_VECT(SCIF2_ERI, 0x900), INTC_VECT(SCIF2_RXI, 0x920), + INTC_VECT(SCIF2_TXI, 0x960), + INTC_VECT(ADC_ADI, 0x980), + INTC_VECT(USB_USI0, 0xa20), INTC_VECT(USB_USI1, 0xa40), + INTC_VECT(TPU0, 0xc00), INTC_VECT(TPU1, 0xc20), + INTC_VECT(TPU3, 0xc80), INTC_VECT(TPU1, 0xca0), + INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), + INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460), + INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), + INTC_VECT(RTC_CUI, 0x4c0), + INTC_VECT(WDT, 0x560), + INTC_VECT(REF_RCMI, 0x580), +}; + +static struct intc_group groups[] __initdata = { + INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), + INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI), + INTC_GROUP(DMAC, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3), + INTC_GROUP(USB, USB_USI0, USB_USI1), + INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI), + INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI), +}; + +static struct intc_prio priorities[] __initdata = { + INTC_PRIO(DMAC, 7), + INTC_PRIO(SCIF2, 3), + INTC_PRIO(SCIF0, 3), +}; + +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, + { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, 0, 0 } }, + { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, + { 0xa4000018, 0, 16, 4, /* IPRD */ { PINT07, PINT815, IRQ5, IRQ4 } }, + { 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC, SCIF0, SCIF2, ADC_ADI } }, + { 0xa4080000, 0, 16, 4, /* IPRF */ { 0, 0, USB } }, + { 0xa4080002, 0, 16, 4, /* IPRG */ { TPU0, TPU1 } }, + { 0xa4080004, 0, 16, 4, /* IPRH */ { TPU2, TPU3 } }, + +}; + +static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups, + priorities, NULL, prio_registers, NULL); + +static struct intc_vect vectors_irq[] __initdata = { + INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), + INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), +}; + +static DECLARE_INTC_DESC(intc_desc_irq, "sh7705-irq", vectors_irq, NULL, + priorities, NULL, prio_registers, NULL); static struct plat_sci_port sci_platform_data[] = { { @@ -37,8 +119,43 @@ static struct platform_device sci_device = { }, }; +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 sh_rtc_platform_info rtc_info = { + .capabilities = RTC_CAP_4_DIGIT_YEAR, +}; + +static struct platform_device rtc_device = { + .name = "sh-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, + .dev = { + .platform_data = &rtc_info, + }, +}; + static struct platform_device *sh7705_devices[] __initdata = { &sci_device, + &rtc_device, }; static int __init sh7705_devices_setup(void) @@ -48,51 +165,16 @@ static int __init sh7705_devices_setup(void) } __initcall(sh7705_devices_setup); -static struct ipr_data ipr_irq_table[] = { - /* IRQ, IPR-idx, shift, priority */ - { 16, 0, 12, 2 }, /* TMU0 TUNI*/ - { 17, 0, 8, 2 }, /* TMU1 TUNI */ - { 18, 0, 4, 2 }, /* TMU2 TUNI */ - { 27, 1, 12, 2 }, /* WDT ITI */ - { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ - { 21, 0, 0, 2 }, /* RTC PRI (period) */ - { 22, 0, 0, 2 }, /* RTC CUI (carry) */ - { 48, 4, 12, 7 }, /* DMAC DMTE0 */ - { 49, 4, 12, 7 }, /* DMAC DMTE1 */ - { 50, 4, 12, 7 }, /* DMAC DMTE2 */ - { 51, 4, 12, 7 }, /* DMAC DMTE3 */ - { 52, 4, 8, 3 }, /* SCIF0 ERI */ - { 53, 4, 8, 3 }, /* SCIF0 RXI */ - { 55, 4, 8, 3 }, /* SCIF0 TXI */ - { 56, 4, 4, 3 }, /* SCIF1 ERI */ - { 57, 4, 4, 3 }, /* SCIF1 RXI */ - { 59, 4, 4, 3 }, /* SCIF1 TXI */ -}; - -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 */ -}; - -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 plat_irq_setup_pins(int mode) +{ + if (mode == IRQ_MODE_IRQ) { + register_intc_controller(&intc_desc_irq); + return; + } + BUG(); +} void __init plat_irq_setup(void) { - register_ipr_controller(&ipr_irq_desc); + register_intc_controller(&intc_desc); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7708.c b/arch/sh/kernel/cpu/sh3/setup-sh7708.c deleted file mode 100644 index f933723911ca..000000000000 --- a/arch/sh/kernel/cpu/sh3/setup-sh7708.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SH7708 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include <linux/platform_device.h> -#include <linux/init.h> -#include <linux/serial.h> -#include <asm/sci.h> - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xfffffe80, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCI, - .irqs = { 23, 24, 25, 0 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7708_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7708_devices_setup(void) -{ - return platform_add_devices(sh7708_devices, - ARRAY_SIZE(sh7708_devices)); -} -__initcall(sh7708_devices_setup); diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/arch/sh/kernel/cpu/sh3/setup-sh7709.c deleted file mode 100644 index 086f8e2545af..000000000000 --- a/arch/sh/kernel/cpu/sh3/setup-sh7709.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * SH7707/SH7709 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include <linux/platform_device.h> -#include <linux/init.h> -#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, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCI, - .irqs = { 23, 24, 25, 0 }, - }, { - .mapbase = 0xa4000150, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 56, 57, 59, 58 }, - }, { - .mapbase = 0xa4000140, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_IRDA, - .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 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) -{ - return platform_add_devices(sh7709_devices, - ARRAY_SIZE(sh7709_devices)); -} -__initcall(sh7709_devices_setup); - -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 plat_irq_setup(void) -{ - register_ipr_controller(&ipr_irq_desc); -} diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c new file mode 100644 index 000000000000..60b04b1f9453 --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -0,0 +1,224 @@ +/* + * SH3 Setup code for SH7706, SH7707, SH7708, SH7709 + * + * Copyright (C) 2007 Magnus Damm + * + * Based on setup-sh7709.c + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/platform_device.h> +#include <linux/serial.h> +#include <asm/sci.h> + +enum { + UNUSED = 0, + + /* interrupt sources */ + IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, + PINT07, PINT815, + DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3, + SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI, + SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI, + SCI_ERI, SCI_RXI, SCI_TXI, SCI_TEI, + ADC_ADI, + LCDC, PCC0, PCC1, + TMU0, TMU1, TMU2_TUNI, TMU2_TICPI, + RTC_ATI, RTC_PRI, RTC_CUI, + WDT, + REF_RCMI, REF_ROVI, + + /* interrupt groups */ + RTC, REF, TMU2, DMAC, SCI, SCIF2, SCIF0, +}; + +static struct intc_vect vectors[] __initdata = { + INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), + INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460), + INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), + INTC_VECT(RTC_CUI, 0x4c0), + INTC_VECT(SCI_ERI, 0x4e0), INTC_VECT(SCI_RXI, 0x500), + INTC_VECT(SCI_TXI, 0x520), INTC_VECT(SCI_TEI, 0x540), + INTC_VECT(WDT, 0x560), + INTC_VECT(REF_RCMI, 0x580), + INTC_VECT(REF_ROVI, 0x5a0), +#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) + INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), + INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820), + INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860), + INTC_VECT(ADC_ADI, 0x980), + INTC_VECT(SCIF2_ERI, 0x900), INTC_VECT(SCIF2_RXI, 0x920), + INTC_VECT(SCIF2_BRI, 0x940), INTC_VECT(SCIF2_TXI, 0x960), +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) + INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720), + INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0), + INTC_VECT(SCIF0_BRI, 0x8c0), INTC_VECT(SCIF0_TXI, 0x8e0), +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7707) + INTC_VECT(LCDC, 0x9a0), + INTC_VECT(PCC0, 0x9c0), INTC_VECT(PCC1, 0x9e0), +#endif +}; + +static struct intc_group groups[] __initdata = { + INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), + INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI), + INTC_GROUP(REF, REF_RCMI, REF_ROVI), + INTC_GROUP(DMAC, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3), + INTC_GROUP(SCI, SCI_ERI, SCI_RXI, SCI_TXI, SCI_TEI), + INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), + INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI), +}; + +static struct intc_prio priorities[] __initdata = { + INTC_PRIO(DMAC, 7), + INTC_PRIO(SCI, 3), + INTC_PRIO(SCIF2, 3), + INTC_PRIO(SCIF0, 3), +}; + +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, + { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, SCI, 0 } }, +#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) + { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, + { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } }, + { 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC, 0, SCIF2, ADC_ADI } }, +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) + { 0xa4000018, 0, 16, 4, /* IPRD */ { PINT07, PINT815, } }, + { 0xa400001a, 0, 16, 4, /* IPRE */ { 0, SCIF0 } }, +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7707) + { 0xa400001c, 0, 16, 4, /* IPRF */ { 0, LCDC, PCC0, PCC1, } }, +#endif +}; + +static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups, + priorities, NULL, prio_registers, NULL); + +#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) +static struct intc_vect vectors_irq[] __initdata = { + INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), + INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), +}; + +static DECLARE_INTC_DESC(intc_desc_irq, "sh770x-irq", vectors_irq, NULL, + priorities, NULL, prio_registers, NULL); +#endif + +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 platform_device rtc_device = { + .name = "sh-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, +}; + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xfffffe80, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCI, + .irqs = { 23, 24, 25, 0 }, + }, +#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) + { + .mapbase = 0xa4000150, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 56, 57, 59, 58 }, + }, +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) + { + .mapbase = 0xa4000140, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_IRDA, + .irqs = { 52, 53, 55, 54 }, + }, +#endif + { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh770x_devices[] __initdata = { + &sci_device, + &rtc_device, +}; + +static int __init sh770x_devices_setup(void) +{ + return platform_add_devices(sh770x_devices, + ARRAY_SIZE(sh770x_devices)); +} +__initcall(sh770x_devices_setup); + +#define INTC_ICR1 0xa4000010UL +#define INTC_ICR1_IRQLVL (1<<14) + +void __init plat_irq_setup_pins(int mode) +{ + if (mode == IRQ_MODE_IRQ) { +#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) + ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1); + register_intc_controller(&intc_desc_irq); + return; +#endif + } + BUG(); +} + +void __init plat_irq_setup(void) +{ + register_intc_controller(&intc_desc); +} diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 132284893373..84e5629fa841 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -1,7 +1,7 @@ /* - * SH7710 Setup + * SH3 Setup code for SH7710, SH7712 * - * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2006, 2007 Paul Mundt * Copyright (C) 2007 Nobuhiro Iwamatsu * * This file is subject to the terms and conditions of the GNU General Public @@ -10,8 +10,140 @@ */ #include <linux/platform_device.h> #include <linux/init.h> +#include <linux/irq.h> #include <linux/serial.h> #include <asm/sci.h> +#include <asm/rtc.h> + +enum { + UNUSED = 0, + + /* interrupt sources */ + IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, + DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3, + SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI, + SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI, + DMAC_DEI4, DMAC_DEI5, + IPSEC, + EDMAC0, EDMAC1, EDMAC2, + SIOF0_ERI, SIOF0_TXI, SIOF0_RXI, SIOF0_CCI, + SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI, + TMU0, TMU1, TMU2, + RTC_ATI, RTC_PRI, RTC_CUI, + WDT, + REF, + + /* interrupt groups */ + RTC, DMAC1, SCIF0, SCIF1, DMAC2, SIOF0, SIOF1, +}; + +static struct intc_vect vectors[] __initdata = { + INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), + INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820), + INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860), + INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0), + INTC_VECT(SCIF0_BRI, 0x8c0), INTC_VECT(SCIF0_TXI, 0x8e0), + INTC_VECT(SCIF1_ERI, 0x900), INTC_VECT(SCIF1_RXI, 0x920), + INTC_VECT(SCIF1_BRI, 0x940), INTC_VECT(SCIF1_TXI, 0x960), + INTC_VECT(DMAC_DEI4, 0xb80), INTC_VECT(DMAC_DEI5, 0xba0), +#ifdef CONFIG_CPU_SUBTYPE_SH7710 + INTC_VECT(IPSEC, 0xbe0), +#endif + INTC_VECT(EDMAC0, 0xc00), INTC_VECT(EDMAC1, 0xc20), + INTC_VECT(EDMAC2, 0xc40), + INTC_VECT(SIOF0_ERI, 0xe00), INTC_VECT(SIOF0_TXI, 0xe20), + INTC_VECT(SIOF0_RXI, 0xe40), INTC_VECT(SIOF0_CCI, 0xe60), + INTC_VECT(SIOF1_ERI, 0xe80), INTC_VECT(SIOF1_TXI, 0xea0), + INTC_VECT(SIOF1_RXI, 0xec0), INTC_VECT(SIOF1_CCI, 0xee0), + INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), + INTC_VECT(TMU2, 0x440), + INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), + INTC_VECT(RTC_CUI, 0x4c0), + INTC_VECT(WDT, 0x560), + INTC_VECT(REF, 0x580), +}; + +static struct intc_group groups[] __initdata = { + INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), + INTC_GROUP(DMAC1, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3), + INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), + INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI), + INTC_GROUP(DMAC2, DMAC_DEI4, DMAC_DEI5), + INTC_GROUP(SIOF0, SIOF0_ERI, SIOF0_TXI, SIOF0_RXI, SIOF0_CCI), + INTC_GROUP(SIOF1, SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI), +}; + +static struct intc_prio priorities[] __initdata = { + INTC_PRIO(DMAC1, 7), + INTC_PRIO(DMAC2, 7), + INTC_PRIO(SCIF0, 3), + INTC_PRIO(SCIF1, 3), + INTC_PRIO(SIOF0, 3), + INTC_PRIO(SIOF1, 3), + INTC_PRIO(EDMAC0, 5), + INTC_PRIO(EDMAC1, 5), + INTC_PRIO(EDMAC2, 5), +}; + +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, + { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } }, + { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, + { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } }, + { 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC1, SCIF0, SCIF1 } }, + { 0xa4080000, 0, 16, 4, /* IPRF */ { 0, DMAC2 } }, +#ifdef CONFIG_CPU_SUBTYPE_SH7710 + { 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC } }, +#endif + { 0xa4080002, 0, 16, 4, /* IPRG */ { EDMAC0, EDMAC1, EDMAC2 } }, + { 0xa4080004, 0, 16, 4, /* IPRH */ { 0, 0, 0, SIOF0 } }, + { 0xa4080006, 0, 16, 4, /* IPRI */ { 0, 0, SIOF1 } }, +}; + +static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups, + priorities, NULL, prio_registers, NULL); + +static struct intc_vect vectors_irq[] __initdata = { + INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), + INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), +}; + +static DECLARE_INTC_DESC(intc_desc_irq, "sh7710-irq", vectors_irq, NULL, + priorities, NULL, prio_registers, NULL); + +static struct resource rtc_resources[] = { + [0] = { + .start = 0xa413fec0, + .end = 0xa413fec0 + 0x1e, + .flags = IORESOURCE_IO, + }, + [1] = { + .start = 20, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 21, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = 22, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_rtc_platform_info rtc_info = { + .capabilities = RTC_CAP_4_DIGIT_YEAR, +}; + +static struct platform_device rtc_device = { + .name = "sh-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, + .dev = { + .platform_data = &rtc_info, + }, +}; static struct plat_sci_port sci_platform_data[] = { { @@ -20,7 +152,7 @@ static struct plat_sci_port sci_platform_data[] = { .type = PORT_SCIF, .irqs = { 52, 53, 55, 54 }, }, { - .mapbase = 0xa4420000, + .mapbase = 0xa4410000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 56, 57, 59, 58 }, @@ -40,6 +172,7 @@ static struct platform_device sci_device = { static struct platform_device *sh7710_devices[] __initdata = { &sci_device, + &rtc_device, }; static int __init sh7710_devices_setup(void) @@ -49,59 +182,16 @@ static int __init sh7710_devices_setup(void) } __initcall(sh7710_devices_setup); -static struct ipr_data ipr_irq_table[] = { - /* IRQ, IPR-idx, shift, priority */ - { 16, 0, 12, 2 }, /* TMU0 TUNI*/ - { 17, 0, 8, 2 }, /* TMU1 TUNI */ - { 18, 0, 4, 2 }, /* TMU2 TUNI */ - { 27, 1, 12, 2 }, /* WDT ITI */ - { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ - { 21, 0, 0, 2 }, /* RTC PRI (period) */ - { 22, 0, 0, 2 }, /* RTC CUI (carry) */ - { 48, 4, 12, 7 }, /* DMAC DMTE0 */ - { 49, 4, 12, 7 }, /* DMAC DMTE1 */ - { 50, 4, 12, 7 }, /* DMAC DMTE2 */ - { 51, 4, 12, 7 }, /* DMAC DMTE3 */ - { 52, 4, 8, 3 }, /* SCIF0 ERI */ - { 53, 4, 8, 3 }, /* SCIF0 RXI */ - { 54, 4, 8, 3 }, /* SCIF0 BRI */ - { 55, 4, 8, 3 }, /* SCIF0 TXI */ - { 56, 4, 4, 3 }, /* SCIF1 ERI */ - { 57, 4, 4, 3 }, /* SCIF1 RXI */ - { 58, 4, 4, 3 }, /* SCIF1 BRI */ - { 59, 4, 4, 3 }, /* SCIF1 TXI */ - { 76, 5, 8, 7 }, /* DMAC DMTE4 */ - { 77, 5, 8, 7 }, /* DMAC DMTE5 */ - { 80, 6, 12, 5 }, /* EDMAC EINT0 */ - { 81, 6, 8, 5 }, /* EDMAC EINT1 */ - { 82, 6, 4, 5 }, /* EDMAC EINT2 */ -}; - -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 */ -}; - -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 plat_irq_setup_pins(int mode) +{ + if (mode == IRQ_MODE_IRQ) { + register_intc_controller(&intc_desc_irq); + return; + } + BUG(); +} void __init plat_irq_setup(void) { - register_ipr_controller(&ipr_irq_desc); + register_intc_controller(&intc_desc); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c new file mode 100644 index 000000000000..a0929b8a95ae --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -0,0 +1,210 @@ +/* + * SH7720 Setup + * + * Copyright (C) 2007 Markus Brunner, Mark Jonas + * + * Based on arch/sh/kernel/cpu/sh4/setup-sh7750.c: + * + * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2006 Jamie Lenehan + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/platform_device.h> +#include <linux/init.h> +#include <linux/serial.h> +#include <linux/io.h> +#include <asm/sci.h> +#include <asm/rtc.h> + +#define INTC_ICR1 0xA4140010UL +#define INTC_ICR_IRLM 0x4000 +#define INTC_ICR_IRQ (~INTC_ICR_IRLM) + +static struct resource rtc_resources[] = { + [0] = { + .start = 0xa413fec0, + .end = 0xa413fec0 + 0x28 - 1, + .flags = IORESOURCE_IO, + }, + [1] = { + /* Period IRQ */ + .start = 21, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* Carry IRQ */ + .start = 22, + .flags = IORESOURCE_IRQ, + }, + [3] = { + /* Alarm IRQ */ + .start = 20, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_rtc_platform_info rtc_info = { + .capabilities = RTC_CAP_4_DIGIT_YEAR, +}; + +static struct platform_device rtc_device = { + .name = "sh-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, + .dev = { + .platform_data = &rtc_info, + }, +}; + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xa4430000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 80, 80, 80 }, + }, { + .mapbase = 0xa4438000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 81, 81, 81, 81 }, + }, { + + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7720_devices[] __initdata = { + &rtc_device, + &sci_device, +}; + +static int __init sh7720_devices_setup(void) +{ + return platform_add_devices(sh7720_devices, + ARRAY_SIZE(sh7720_devices)); +} +__initcall(sh7720_devices_setup); + +enum { + UNUSED = 0, + + /* interrupt sources */ + TMU0, TMU1, TMU2, RTC_ATI, RTC_PRI, RTC_CUI, + WDT, REF_RCMI, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND, + IRQ0, IRQ1, IRQ2, IRQ3, + USBF_SPD, TMU_SUNI, IRQ5, IRQ4, + DMAC1_DEI0, DMAC1_DEI1, DMAC1_DEI2, DMAC1_DEI3, LCDC, SSL, + ADC, DMAC2_DEI4, DMAC2_DEI5, USBFI0, USBFI1, CMT, + SCIF0, SCIF1, + PINT07, PINT815, TPU0, TPU1, TPU2, TPU3, IIC, + SIOF0, SIOF1, MMCI0, MMCI1, MMCI2, MMCI3, PCC, + USBHI, AFEIF, + H_UDI, + /* interrupt groups */ + TMU, RTC, SIM, DMAC1, USBFI, DMAC2, USB, TPU, MMC, +}; + +static struct intc_vect vectors[] __initdata = { + INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), + INTC_VECT(TMU2, 0x440), INTC_VECT(RTC_ATI, 0x480), + INTC_VECT(RTC_PRI, 0x4a0), INTC_VECT(RTC_CUI, 0x4c0), + INTC_VECT(SIM_ERI, 0x4e0), INTC_VECT(SIM_RXI, 0x500), + INTC_VECT(SIM_TXI, 0x520), INTC_VECT(SIM_TEND, 0x540), + INTC_VECT(WDT, 0x560), INTC_VECT(REF_RCMI, 0x580), + /* H_UDI cannot be masked */ INTC_VECT(TMU_SUNI, 0x6c0), + INTC_VECT(USBF_SPD, 0x6e0), INTC_VECT(DMAC1_DEI0, 0x800), + INTC_VECT(DMAC1_DEI1, 0x820), INTC_VECT(DMAC1_DEI2, 0x840), + INTC_VECT(DMAC1_DEI3, 0x860), INTC_VECT(LCDC, 0x900), + INTC_VECT(SSL, 0x980), INTC_VECT(USBFI0, 0xa20), + INTC_VECT(USBFI1, 0xa40), INTC_VECT(USBHI, 0xa60), + INTC_VECT(DMAC2_DEI4, 0xb80), INTC_VECT(DMAC2_DEI5, 0xba0), + INTC_VECT(ADC, 0xbe0), INTC_VECT(SCIF0, 0xc00), + INTC_VECT(SCIF1, 0xc20), INTC_VECT(PINT07, 0xc80), + INTC_VECT(PINT815, 0xca0), INTC_VECT(SIOF0, 0xd00), + INTC_VECT(SIOF1, 0xd20), INTC_VECT(TPU0, 0xd80), + INTC_VECT(TPU1, 0xda0), INTC_VECT(TPU2, 0xdc0), + INTC_VECT(TPU3, 0xde0), INTC_VECT(IIC, 0xe00), + INTC_VECT(MMCI0, 0xe80), INTC_VECT(MMCI1, 0xea0), + INTC_VECT(MMCI2, 0xec0), INTC_VECT(MMCI3, 0xee0), + INTC_VECT(CMT, 0xf00), INTC_VECT(PCC, 0xf60), + INTC_VECT(AFEIF, 0xfe0), +}; + +static struct intc_group groups[] __initdata = { + INTC_GROUP(TMU, TMU0, TMU1, TMU2), + INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), + INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND), + INTC_GROUP(DMAC1, DMAC1_DEI0, DMAC1_DEI1, DMAC1_DEI2, DMAC1_DEI3), + INTC_GROUP(USBFI, USBFI0, USBFI1), + INTC_GROUP(DMAC2, DMAC2_DEI4, DMAC2_DEI5), + INTC_GROUP(TPU, TPU0, TPU1, TPU2, TPU3), + INTC_GROUP(MMC, MMCI0, MMCI1, MMCI2, MMCI3), +}; + +static struct intc_prio priorities[] __initdata = { + INTC_PRIO(SCIF0, 2), + INTC_PRIO(SCIF1, 2), + INTC_PRIO(DMAC1, 1), + INTC_PRIO(DMAC2, 1), + INTC_PRIO(RTC, 2), + INTC_PRIO(TMU, 2), + INTC_PRIO(TPU, 2), +}; + +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xA414FEE2UL, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, + { 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } }, + { 0xA4140016UL, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, + { 0xA4140018UL, 0, 16, 4, /* IPRD */ { USBF_SPD, TMU_SUNI, IRQ5, IRQ4 } }, + { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, SSL } }, + { 0xA4080000UL, 0, 16, 4, /* IPRF */ { ADC, DMAC2, USBFI, CMT } }, + { 0xA4080002UL, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, 0, 0 } }, + { 0xA4080004UL, 0, 16, 4, /* IPRH */ { PINT07, PINT815, TPU, IIC } }, + { 0xA4080006UL, 0, 16, 4, /* IPRI */ { SIOF0, SIOF1, MMC, PCC } }, + { 0xA4080008UL, 0, 16, 4, /* IPRJ */ { 0, USBHI, 0, AFEIF } }, +}; + +static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups, + priorities, NULL, prio_registers, NULL); + +static struct intc_sense_reg sense_registers[] __initdata = { + { INTC_ICR1, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } }, +}; + +static struct intc_vect vectors_irq[] __initdata = { + INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), + INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), + INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), +}; + +static DECLARE_INTC_DESC(intc_irq_desc, "sh7720-irq", vectors_irq, + NULL, priorities, NULL, prio_registers, sense_registers); + +void __init plat_irq_setup_pins(int mode) +{ + switch (mode) { + case IRQ_MODE_IRQ: + ctrl_outw(ctrl_inw(INTC_ICR1) & INTC_ICR_IRQ, INTC_ICR1); + register_intc_controller(&intc_irq_desc); + break; + default: + BUG(); + } +} + +void __init plat_irq_setup(void) +{ + register_intc_controller(&intc_desc); +} diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index 98d28fb1ce16..21375d777e99 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -3,7 +3,7 @@ * * CPU Subtype Probing for SH-4. * - * Copyright (C) 2001 - 2006 Paul Mundt + * Copyright (C) 2001 - 2007 Paul Mundt * Copyright (C) 2003 Richard Curnow * * This file is subject to the terms and conditions of the GNU General Public @@ -12,7 +12,6 @@ */ #include <linux/init.h> #include <linux/io.h> -#include <linux/smp.h> #include <asm/processor.h> #include <asm/cache.h> @@ -36,37 +35,34 @@ int __init detect_cpu_and_cache_system(void) /* * Setup some sane SH-4 defaults for the icache */ - current_cpu_data.icache.way_incr = (1 << 13); - current_cpu_data.icache.entry_shift = 5; - current_cpu_data.icache.sets = 256; - current_cpu_data.icache.ways = 1; - current_cpu_data.icache.linesz = L1_CACHE_BYTES; + boot_cpu_data.icache.way_incr = (1 << 13); + boot_cpu_data.icache.entry_shift = 5; + boot_cpu_data.icache.sets = 256; + boot_cpu_data.icache.ways = 1; + boot_cpu_data.icache.linesz = L1_CACHE_BYTES; /* * And again for the dcache .. */ - current_cpu_data.dcache.way_incr = (1 << 14); - current_cpu_data.dcache.entry_shift = 5; - current_cpu_data.dcache.sets = 512; - current_cpu_data.dcache.ways = 1; - current_cpu_data.dcache.linesz = L1_CACHE_BYTES; + boot_cpu_data.dcache.way_incr = (1 << 14); + boot_cpu_data.dcache.entry_shift = 5; + boot_cpu_data.dcache.sets = 512; + boot_cpu_data.dcache.ways = 1; + boot_cpu_data.dcache.linesz = L1_CACHE_BYTES; /* - * Setup some generic flags we can probe - * (L2 and DSP detection only work on SH-4A) + * Setup some generic flags we can probe on SH-4A parts */ if (((pvr >> 16) & 0xff) == 0x10) { - if ((cvr & 0x02000000) == 0) - current_cpu_data.flags |= CPU_HAS_L2_CACHE; if ((cvr & 0x10000000) == 0) - current_cpu_data.flags |= CPU_HAS_DSP; + boot_cpu_data.flags |= CPU_HAS_DSP; - current_cpu_data.flags |= CPU_HAS_LLSC; + boot_cpu_data.flags |= CPU_HAS_LLSC; } /* FPU detection works for everyone */ if ((cvr & 0x20000000) == 1) - current_cpu_data.flags |= CPU_HAS_FPU; + boot_cpu_data.flags |= CPU_HAS_FPU; /* Mask off the upper chip ID */ pvr &= 0xffff; @@ -77,140 +73,140 @@ int __init detect_cpu_and_cache_system(void) */ switch (pvr) { case 0x205: - current_cpu_data.type = CPU_SH7750; - current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | + boot_cpu_data.type = CPU_SH7750; + boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | CPU_HAS_PERF_COUNTER; break; case 0x206: - current_cpu_data.type = CPU_SH7750S; - current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | + boot_cpu_data.type = CPU_SH7750S; + boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | CPU_HAS_PERF_COUNTER; break; case 0x1100: - current_cpu_data.type = CPU_SH7751; - current_cpu_data.flags |= CPU_HAS_FPU; + boot_cpu_data.type = CPU_SH7751; + boot_cpu_data.flags |= CPU_HAS_FPU; break; case 0x2001: case 0x2004: - current_cpu_data.type = CPU_SH7770; - current_cpu_data.icache.ways = 4; - current_cpu_data.dcache.ways = 4; + boot_cpu_data.type = CPU_SH7770; + boot_cpu_data.icache.ways = 4; + boot_cpu_data.dcache.ways = 4; - current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_LLSC; + boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_LLSC; break; case 0x2006: case 0x200A: if (prr == 0x61) - current_cpu_data.type = CPU_SH7781; + boot_cpu_data.type = CPU_SH7781; else - current_cpu_data.type = CPU_SH7780; + boot_cpu_data.type = CPU_SH7780; - current_cpu_data.icache.ways = 4; - current_cpu_data.dcache.ways = 4; + boot_cpu_data.icache.ways = 4; + boot_cpu_data.dcache.ways = 4; - current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | + boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | CPU_HAS_LLSC; break; case 0x3000: case 0x3003: case 0x3009: - current_cpu_data.type = CPU_SH7343; - current_cpu_data.icache.ways = 4; - current_cpu_data.dcache.ways = 4; - current_cpu_data.flags |= CPU_HAS_LLSC; + boot_cpu_data.type = CPU_SH7343; + boot_cpu_data.icache.ways = 4; + boot_cpu_data.dcache.ways = 4; + boot_cpu_data.flags |= CPU_HAS_LLSC; break; case 0x3004: case 0x3007: - current_cpu_data.type = CPU_SH7785; - current_cpu_data.icache.ways = 4; - current_cpu_data.dcache.ways = 4; - current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | + boot_cpu_data.type = CPU_SH7785; + boot_cpu_data.icache.ways = 4; + boot_cpu_data.dcache.ways = 4; + boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | CPU_HAS_LLSC; break; case 0x3008: if (prr == 0xa0) { - current_cpu_data.type = CPU_SH7722; - current_cpu_data.icache.ways = 4; - current_cpu_data.dcache.ways = 4; - current_cpu_data.flags |= CPU_HAS_LLSC; + boot_cpu_data.type = CPU_SH7722; + boot_cpu_data.icache.ways = 4; + boot_cpu_data.dcache.ways = 4; + boot_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 | + boot_cpu_data.type = CPU_SHX3; + boot_cpu_data.icache.ways = 4; + boot_cpu_data.dcache.ways = 4; + boot_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; + boot_cpu_data.type = CPU_ST40RA; + boot_cpu_data.flags |= CPU_HAS_FPU; break; case 0x8100: - current_cpu_data.type = CPU_ST40GX1; - current_cpu_data.flags |= CPU_HAS_FPU; + boot_cpu_data.type = CPU_ST40GX1; + boot_cpu_data.flags |= CPU_HAS_FPU; break; case 0x700: - current_cpu_data.type = CPU_SH4_501; - current_cpu_data.icache.ways = 2; - current_cpu_data.dcache.ways = 2; + boot_cpu_data.type = CPU_SH4_501; + boot_cpu_data.icache.ways = 2; + boot_cpu_data.dcache.ways = 2; break; case 0x600: - current_cpu_data.type = CPU_SH4_202; - current_cpu_data.icache.ways = 2; - current_cpu_data.dcache.ways = 2; - current_cpu_data.flags |= CPU_HAS_FPU; + boot_cpu_data.type = CPU_SH4_202; + boot_cpu_data.icache.ways = 2; + boot_cpu_data.dcache.ways = 2; + boot_cpu_data.flags |= CPU_HAS_FPU; break; case 0x500 ... 0x501: switch (prr) { case 0x10: - current_cpu_data.type = CPU_SH7750R; + boot_cpu_data.type = CPU_SH7750R; break; case 0x11: - current_cpu_data.type = CPU_SH7751R; + boot_cpu_data.type = CPU_SH7751R; break; case 0x50 ... 0x5f: - current_cpu_data.type = CPU_SH7760; + boot_cpu_data.type = CPU_SH7760; break; } - current_cpu_data.icache.ways = 2; - current_cpu_data.dcache.ways = 2; + boot_cpu_data.icache.ways = 2; + boot_cpu_data.dcache.ways = 2; - current_cpu_data.flags |= CPU_HAS_FPU; + boot_cpu_data.flags |= CPU_HAS_FPU; break; default: - current_cpu_data.type = CPU_SH_NONE; + boot_cpu_data.type = CPU_SH_NONE; break; } #ifdef CONFIG_SH_DIRECT_MAPPED - current_cpu_data.icache.ways = 1; - current_cpu_data.dcache.ways = 1; + boot_cpu_data.icache.ways = 1; + boot_cpu_data.dcache.ways = 1; #endif #ifdef CONFIG_CPU_HAS_PTEA - current_cpu_data.flags |= CPU_HAS_PTEA; + boot_cpu_data.flags |= CPU_HAS_PTEA; #endif /* * On anything that's not a direct-mapped cache, look to the CVR * for I/D-cache specifics. */ - if (current_cpu_data.icache.ways > 1) { + if (boot_cpu_data.icache.ways > 1) { size = sizes[(cvr >> 20) & 0xf]; - current_cpu_data.icache.way_incr = (size >> 1); - current_cpu_data.icache.sets = (size >> 6); + boot_cpu_data.icache.way_incr = (size >> 1); + boot_cpu_data.icache.sets = (size >> 6); } /* And the rest of the D-cache */ - if (current_cpu_data.dcache.ways > 1) { + if (boot_cpu_data.dcache.ways > 1) { size = sizes[(cvr >> 16) & 0xf]; - current_cpu_data.dcache.way_incr = (size >> 1); - current_cpu_data.dcache.sets = (size >> 6); + boot_cpu_data.dcache.way_incr = (size >> 1); + boot_cpu_data.dcache.sets = (size >> 6); } /* @@ -218,7 +214,7 @@ int __init detect_cpu_and_cache_system(void) * * SH-4A's have an optional PIPT L2. */ - if (current_cpu_data.flags & CPU_HAS_L2_CACHE) { + if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) { /* * Size calculation is much more sensible * than it is for the L1. @@ -229,22 +225,22 @@ int __init detect_cpu_and_cache_system(void) BUG_ON(!size); - current_cpu_data.scache.way_incr = (1 << 16); - current_cpu_data.scache.entry_shift = 5; - current_cpu_data.scache.ways = 4; - current_cpu_data.scache.linesz = L1_CACHE_BYTES; + boot_cpu_data.scache.way_incr = (1 << 16); + boot_cpu_data.scache.entry_shift = 5; + boot_cpu_data.scache.ways = 4; + boot_cpu_data.scache.linesz = L1_CACHE_BYTES; - current_cpu_data.scache.entry_mask = - (current_cpu_data.scache.way_incr - - current_cpu_data.scache.linesz); + boot_cpu_data.scache.entry_mask = + (boot_cpu_data.scache.way_incr - + boot_cpu_data.scache.linesz); - current_cpu_data.scache.sets = size / - (current_cpu_data.scache.linesz * - current_cpu_data.scache.ways); + boot_cpu_data.scache.sets = size / + (boot_cpu_data.scache.linesz * + boot_cpu_data.scache.ways); - current_cpu_data.scache.way_size = - (current_cpu_data.scache.sets * - current_cpu_data.scache.linesz); + boot_cpu_data.scache.way_size = + (boot_cpu_data.scache.sets * + boot_cpu_data.scache.linesz); } return 0; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index f2286de22bd5..523f68a9ce0e 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -104,7 +104,7 @@ enum { DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF, }; -static struct intc_vect vectors[] = { +static struct intc_vect vectors[] __initdata = { INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620), INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460), @@ -118,7 +118,7 @@ static struct intc_vect vectors[] = { INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0), }; -static struct intc_group groups[] = { +static struct intc_group groups[] __initdata = { INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI), INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI), @@ -126,20 +126,20 @@ static struct intc_group groups[] = { INTC_GROUP(REF, REF_RCMI, REF_ROVI), }; -static struct intc_prio priorities[] = { +static struct intc_prio priorities[] __initdata = { INTC_PRIO(SCIF, 3), INTC_PRIO(SCI1, 3), INTC_PRIO(DMAC, 7), }; -static struct intc_prio_reg prio_registers[] = { - { 0xffd00004, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, - { 0xffd00008, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } }, - { 0xffd0000c, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } }, - { 0xffd00010, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } }, - { 0xfe080000, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0, - TMU4, TMU3, - PCIC1, PCIC0_PCISERR } }, +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, + { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } }, + { 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } }, + { 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } }, + { 0xfe080000, 0, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0, + TMU4, TMU3, + PCIC1, PCIC0_PCISERR } }, }; static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups, @@ -150,13 +150,13 @@ static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups, defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ defined(CONFIG_CPU_SUBTYPE_SH7751) || \ defined(CONFIG_CPU_SUBTYPE_SH7091) -static struct intc_vect vectors_dma4[] = { +static struct intc_vect vectors_dma4[] __initdata = { INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660), INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0), INTC_VECT(DMAC_DMAE, 0x6c0), }; -static struct intc_group groups_dma4[] = { +static struct intc_group groups_dma4[] __initdata = { INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3, DMAC_DMAE), }; @@ -168,7 +168,7 @@ static DECLARE_INTC_DESC(intc_desc_dma4, "sh7750_dma4", /* SH7750R and SH7751R both have 8-channel DMA controllers */ #if defined(CONFIG_CPU_SUBTYPE_SH7750R) || defined(CONFIG_CPU_SUBTYPE_SH7751R) -static struct intc_vect vectors_dma8[] = { +static struct intc_vect vectors_dma8[] __initdata = { INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660), INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0), INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0), @@ -176,7 +176,7 @@ static struct intc_vect vectors_dma8[] = { INTC_VECT(DMAC_DMAE, 0x6c0), }; -static struct intc_group groups_dma8[] = { +static struct intc_group groups_dma8[] __initdata = { INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE), @@ -191,11 +191,11 @@ static DECLARE_INTC_DESC(intc_desc_dma8, "sh7750_dma8", #if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ defined(CONFIG_CPU_SUBTYPE_SH7751) || \ defined(CONFIG_CPU_SUBTYPE_SH7751R) -static struct intc_vect vectors_tmu34[] = { +static struct intc_vect vectors_tmu34[] __initdata = { INTC_VECT(TMU3, 0xb00), INTC_VECT(TMU4, 0xb80), }; -static struct intc_mask_reg mask_registers[] = { +static struct intc_mask_reg mask_registers[] __initdata = { { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TMU4, TMU3, @@ -210,7 +210,7 @@ static DECLARE_INTC_DESC(intc_desc_tmu34, "sh7750_tmu34", #endif /* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */ -static struct intc_vect vectors_irlm[] = { +static struct intc_vect vectors_irlm[] __initdata = { INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0), INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360), }; @@ -220,14 +220,14 @@ static DECLARE_INTC_DESC(intc_desc_irlm, "sh7750_irlm", vectors_irlm, NULL, /* SH7751 and SH7751R both have PCI */ #if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7751R) -static struct intc_vect vectors_pci[] = { +static struct intc_vect vectors_pci[] __initdata = { INTC_VECT(PCIC0_PCISERR, 0xa00), INTC_VECT(PCIC1_PCIERR, 0xae0), INTC_VECT(PCIC1_PCIPWDWN, 0xac0), INTC_VECT(PCIC1_PCIPWON, 0xaa0), INTC_VECT(PCIC1_PCIDMA0, 0xa80), INTC_VECT(PCIC1_PCIDMA1, 0xa60), INTC_VECT(PCIC1_PCIDMA2, 0xa40), INTC_VECT(PCIC1_PCIDMA3, 0xa20), }; -static struct intc_group groups_pci[] = { +static struct intc_group groups_pci[] __initdata = { INTC_GROUP(PCIC1, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON, PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3), }; @@ -282,13 +282,19 @@ void __init plat_irq_setup(void) #define INTC_ICR 0xffd00000UL #define INTC_ICR_IRLM (1<<7) -/* enable individual interrupt mode for external interupts */ -void __init ipr_irq_enable_irlm(void) +void __init plat_irq_setup_pins(int mode) { #if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7091) BUG(); /* impossible to mask interrupts on SH7750 and SH7091 */ + return; #endif - register_intc_controller(&intc_desc_irlm); - ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); + switch (mode) { + case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */ + ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); + register_intc_controller(&intc_desc_irlm); + break; + default: + BUG(); + } } diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 47fa27056253..7a898cb1d940 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -12,6 +12,136 @@ #include <linux/serial.h> #include <asm/sci.h> +enum { + UNUSED = 0, + + /* interrupt sources */ + IRL0, IRL1, IRL2, IRL3, + HUDI, GPIOI, + DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3, + DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7, + DMAC_DMAE, + IRQ4, IRQ5, IRQ6, IRQ7, + HCAN20, HCAN21, + SSI0, SSI1, + HAC0, HAC1, + I2C0, I2C1, + USB, LCDC, + DMABRG0, DMABRG1, DMABRG2, + SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI, + SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI, + SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI, + SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI, + HSPI, + MMCIF0, MMCIF1, MMCIF2, MMCIF3, + MFI, ADC, CMT, + TMU0, TMU1, TMU2_TUNI, TMU2_TICPI, + WDT, + REF_RCMI, REF_ROVI, + + /* interrupt groups */ + DMAC, DMABRG, SCIF0, SCIF1, SCIF2, SIM, MMCIF, TMU2, REF, +}; + +static struct intc_vect vectors[] __initdata = { + INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620), + INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660), + INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0), + INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0), + INTC_VECT(DMAC_DMTE6, 0x7c0), INTC_VECT(DMAC_DMTE7, 0x7e0), + INTC_VECT(DMAC_DMAE, 0x6c0), + INTC_VECT(IRQ4, 0x800), INTC_VECT(IRQ5, 0x820), + INTC_VECT(IRQ6, 0x840), INTC_VECT(IRQ6, 0x860), + INTC_VECT(HCAN20, 0x900), INTC_VECT(HCAN21, 0x920), + INTC_VECT(SSI0, 0x940), INTC_VECT(SSI1, 0x960), + INTC_VECT(HAC0, 0x980), INTC_VECT(HAC1, 0x9a0), + INTC_VECT(I2C0, 0x9c0), INTC_VECT(I2C1, 0x9e0), + INTC_VECT(USB, 0xa00), INTC_VECT(LCDC, 0xa20), + INTC_VECT(DMABRG0, 0xa80), INTC_VECT(DMABRG1, 0xaa0), + INTC_VECT(DMABRG2, 0xac0), + INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0), + INTC_VECT(SCIF0_BRI, 0x8c0), INTC_VECT(SCIF0_TXI, 0x8e0), + INTC_VECT(SCIF1_ERI, 0xb00), INTC_VECT(SCIF1_RXI, 0xb20), + INTC_VECT(SCIF1_BRI, 0xb40), INTC_VECT(SCIF1_TXI, 0xb60), + INTC_VECT(SCIF2_ERI, 0xb80), INTC_VECT(SCIF2_RXI, 0xba0), + INTC_VECT(SCIF2_BRI, 0xbc0), INTC_VECT(SCIF2_TXI, 0xbe0), + INTC_VECT(SIM_ERI, 0xc00), INTC_VECT(SIM_RXI, 0xc20), + INTC_VECT(SIM_TXI, 0xc40), INTC_VECT(SIM_TEI, 0xc60), + INTC_VECT(HSPI, 0xc80), + INTC_VECT(MMCIF0, 0xd00), INTC_VECT(MMCIF1, 0xd20), + INTC_VECT(MMCIF2, 0xd40), INTC_VECT(MMCIF3, 0xd60), + INTC_VECT(MFI, 0xe80), /* 0xf80 according to data sheet */ + INTC_VECT(ADC, 0xf80), INTC_VECT(CMT, 0xfa0), + INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), + INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460), + INTC_VECT(WDT, 0x560), + INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0), +}; + +static struct intc_group groups[] __initdata = { + INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, + DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5, + DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE), + INTC_GROUP(DMABRG, DMABRG0, DMABRG1, DMABRG2), + INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), + INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI), + INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI), + INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI), + INTC_GROUP(MMCIF, MMCIF0, MMCIF1, MMCIF2, MMCIF3), + INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI), + INTC_GROUP(REF, REF_RCMI, REF_ROVI), +}; + +static struct intc_prio priorities[] __initdata = { + INTC_PRIO(SCIF0, 3), + INTC_PRIO(SCIF1, 3), + INTC_PRIO(SCIF2, 3), + INTC_PRIO(SIM, 3), + INTC_PRIO(DMAC, 7), + INTC_PRIO(DMABRG, 13), +}; + +static struct intc_mask_reg mask_registers[] __initdata = { + { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */ + { IRQ4, IRQ5, IRQ6, IRQ7, 0, 0, HCAN20, HCAN21, + SSI0, SSI1, HAC0, HAC1, I2C0, I2C1, USB, LCDC, + 0, DMABRG0, DMABRG1, DMABRG2, + SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI, + SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI, + SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI, } }, + { 0xfe080044, 0xfe080064, 32, /* INTMSK04 / INTMSKCLR04 */ + { 0, 0, 0, 0, 0, 0, 0, 0, + SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI, + HSPI, MMCIF0, MMCIF1, MMCIF2, + MMCIF3, 0, 0, 0, 0, 0, 0, 0, + 0, MFI, 0, 0, 0, 0, ADC, CMT, } }, +}; + +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2 } }, + { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } }, + { 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, 0, HUDI } }, + { 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } }, + { 0xfe080000, 0, 32, 4, /* INTPRI00 */ { IRQ4, IRQ5, IRQ6, IRQ7 } }, + { 0xfe080004, 0, 32, 4, /* INTPRI04 */ { HCAN20, HCAN21, SSI0, SSI1, + HAC0, HAC1, I2C0, I2C1 } }, + { 0xfe080008, 0, 32, 4, /* INTPRI08 */ { USB, LCDC, DMABRG, SCIF0, + SCIF1, SCIF2, SIM, HSPI } }, + { 0xfe08000c, 0, 32, 4, /* INTPRI0C */ { 0, 0, MMCIF, 0, + MFI, 0, ADC, CMT } }, +}; + +static DECLARE_INTC_DESC(intc_desc, "sh7760", vectors, groups, + priorities, mask_registers, prio_registers, NULL); + +static struct intc_vect vectors_irq[] __initdata = { + INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0), + INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360), +}; + +static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups, + priorities, mask_registers, prio_registers, NULL); + static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xfe600000, @@ -29,6 +159,11 @@ static struct plat_sci_port sci_platform_data[] = { .type = PORT_SCIF, .irqs = { 76, 77, 79, 78 }, }, { + .mapbase = 0xfe480000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCI, + .irqs = { 80, 81, 82, 0 }, + }, { .flags = 0, } }; @@ -52,114 +187,18 @@ static int __init sh7760_devices_setup(void) } __initcall(sh7760_devices_setup); -static struct intc2_data intc2_irq_table[] = { - {48, 0, 28, 0, 31, 3}, /* IRQ 4 */ - {49, 0, 24, 0, 30, 3}, /* IRQ 3 */ - {50, 0, 20, 0, 29, 3}, /* IRQ 2 */ - {51, 0, 16, 0, 28, 3}, /* IRQ 1 */ - {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */ - {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */ - {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */ - {59, 4, 16, 0, 22, 3}, /* I2S_CHAN1 */ - {60, 4, 12, 0, 21, 3}, /* AC97_CHAN0 */ - {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */ - {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */ - {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */ - {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */ - {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */ - {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */ - {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */ - {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */ - {65, 8, 24, 0, 16, 3}, /* LCDC */ - {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */ - {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */ - {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */ - {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */ - {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */ - {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */ - {75, 8, 12, 0, 4, 3}, /* SCIF1_TXI_IRQ */ - {76, 8, 8, 0, 3, 3}, /* SCIF2_ERI_IRQ */ - {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */ - {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */ - {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */ - {80, 8, 4, 4, 23, 3}, /* SIM_ERI */ - {81, 8, 4, 4, 22, 3}, /* SIM_RXI */ - {82, 8, 4, 4, 21, 3}, /* SIM_TXI */ - {83, 8, 4, 4, 20, 3}, /* SIM_TEI */ - {84, 8, 0, 4, 19, 3}, /* HSPII */ - {88, 12, 20, 4, 18, 3}, /* MMCI0 */ - {89, 12, 20, 4, 17, 3}, /* MMCI1 */ - {90, 12, 20, 4, 16, 3}, /* MMCI2 */ - {91, 12, 20, 4, 15, 3}, /* MMCI3 */ - {92, 12, 12, 4, 6, 3}, /* MFI */ - {108,12, 4, 4, 1, 3}, /* ADC */ - {109,12, 0, 4, 0, 3}, /* CMTI */ -}; - -static struct intc2_desc intc2_irq_desc __read_mostly = { - .prio_base = 0xfe080000, - .msk_base = 0xfe080040, - .mskclr_base = 0xfe080060, - - .intc2_data = intc2_irq_table, - .nr_irqs = ARRAY_SIZE(intc2_irq_table), - - .chip = { - .name = "INTC2-sh7760", - }, -}; - -static struct ipr_data ipr_irq_table[] = { - /* IRQ, IPR-idx, shift, priority */ - { 16, 0, 12, 2 }, /* TMU0 TUNI*/ - { 17, 0, 8, 2 }, /* TMU1 TUNI */ - { 18, 0, 4, 2 }, /* TMU2 TUNI */ - { 19, 0, 4, 2 }, /* TMU2 TIPCI */ - { 27, 1, 12, 2 }, /* WDT ITI */ - { 28, 1, 8, 2 }, /* REF RCMI */ - { 29, 1, 8, 2 }, /* REF ROVI */ - { 32, 2, 0, 7 }, /* HUDI */ - { 33, 2, 12, 7 }, /* GPIOI */ - { 34, 2, 8, 7 }, /* DMAC DMTE0 */ - { 35, 2, 8, 7 }, /* DMAC DMTE1 */ - { 36, 2, 8, 7 }, /* DMAC DMTE2 */ - { 37, 2, 8, 7 }, /* DMAC DMTE3 */ - { 38, 2, 8, 7 }, /* DMAC DMAE */ - { 44, 2, 8, 7 }, /* DMAC DMTE4 */ - { 45, 2, 8, 7 }, /* DMAC DMTE5 */ - { 46, 2, 8, 7 }, /* DMAC DMTE6 */ - { 47, 2, 8, 7 }, /* DMAC DMTE7 */ -/* these here are only valid if INTC_ICR bit 7 is set to 1! - * XXX: maybe CONFIG_SH_IRLMODE symbol? SH7751 could use it too */ -#if 0 - { 2, 3, 12, 3 }, /* IRL0 */ - { 5, 3, 8, 3 }, /* IRL1 */ - { 8, 3, 4, 3 }, /* IRL2 */ - { 11, 3, 0, 3 }, /* IRL3 */ -#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 = { - .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-sh7760", - }, -}; +void __init plat_irq_setup_pins(int mode) +{ + switch (mode) { + case IRQ_MODE_IRQ: + register_intc_controller(&intc_desc_irq); + break; + default: + BUG(); + } +} void __init plat_irq_setup(void) { - register_intc2_controller(&intc2_irq_desc); - register_ipr_controller(&ipr_irq_desc); + register_intc_controller(&intc_desc); } diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index c21512c6044e..b22a78c807e6 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c @@ -58,11 +58,11 @@ do { \ */ void sq_flush_range(unsigned long start, unsigned int len) { - volatile unsigned long *sq = (unsigned long *)start; + unsigned long *sq = (unsigned long *)start; /* Flush the queues */ for (len >>= 5; len--; sq += 8) - prefetchw((void *)sq); + prefetchw(sq); /* Wait for completion */ store_queue_barrier(); diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index e6a1fb5f8484..24539873943a 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -10,6 +10,9 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o +# SMP setup +smp-$(CONFIG_CPU_SUBTYPE_SHX3) := smp-shx3.o + # Primary on-chip clocks (common) clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o @@ -18,4 +21,5 @@ 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) +obj-y += $(clock-y) +obj-$(CONFIG_SMP) += $(smp-y) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index 91d61cf91ba1..c0a3f079dfdc 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -41,3 +41,7 @@ static int __init sh7343_devices_setup(void) ARRAY_SIZE(sh7343_devices)); } __initcall(sh7343_devices_setup); + +void __init plat_irq_setup(void) +{ +} diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 25b913e07e2c..55f66104431d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -84,7 +84,7 @@ enum { SIM, RTC, DMAC0123, VIOVOU, USB, DMAC45, FLCTL, I2C, SDHI, }; -static struct intc_vect vectors[] = { +static struct intc_vect vectors[] __initdata = { INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), @@ -117,7 +117,7 @@ static struct intc_vect vectors[] = { INTC_VECT(JPU, 0x560), INTC_VECT(LCDC, 0x580), }; -static struct intc_group groups[] = { +static struct intc_group groups[] __initdata = { INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI), INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), INTC_GROUP(DMAC0123, DMAC0, DMAC1, DMAC2, DMAC3), @@ -130,7 +130,7 @@ static struct intc_group groups[] = { INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3), }; -static struct intc_prio priorities[] = { +static struct intc_prio priorities[] __initdata = { INTC_PRIO(SCIF0, 3), INTC_PRIO(SCIF1, 3), INTC_PRIO(SCIF2, 3), @@ -138,7 +138,7 @@ static struct intc_prio priorities[] = { INTC_PRIO(TMU1, 2), }; -static struct intc_mask_reg mask_registers[] = { +static struct intc_mask_reg mask_registers[] __initdata = { { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ { } }, { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ @@ -168,24 +168,24 @@ static struct intc_mask_reg mask_registers[] = { { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; -static struct intc_prio_reg prio_registers[] = { - { 0xa4080000, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, IRDA } }, - { 0xa4080004, 16, 4, /* IPRB */ { JPU, LCDC, SIM } }, - { 0xa4080008, 16, 4, /* IPRC */ { } }, - { 0xa408000c, 16, 4, /* IPRD */ { } }, - { 0xa4080010, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, 0, VPU } }, - { 0xa4080014, 16, 4, /* IPRF */ { KEYSC, DMAC45, USB, CMT } }, - { 0xa4080018, 16, 4, /* IPRG */ { SCIF0, SCIF1, SCIF2 } }, - { 0xa408001c, 16, 4, /* IPRH */ { SIOF0, SIOF1, FLCTL, I2C } }, - { 0xa4080020, 16, 4, /* IPRI */ { SIO, 0, TSIF, RTC } }, - { 0xa4080024, 16, 4, /* IPRJ */ { 0, 0, SIU } }, - { 0xa4080028, 16, 4, /* IPRK */ { 0, 0, 0, SDHI } }, - { 0xa408002c, 16, 4, /* IPRL */ { TWODG, 0, TPU } }, - { 0xa4140010, 32, 4, /* INTPRI00 */ +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, IRDA } }, + { 0xa4080004, 0, 16, 4, /* IPRB */ { JPU, LCDC, SIM } }, + { 0xa4080008, 0, 16, 4, /* IPRC */ { } }, + { 0xa408000c, 0, 16, 4, /* IPRD */ { } }, + { 0xa4080010, 0, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, 0, VPU } }, + { 0xa4080014, 0, 16, 4, /* IPRF */ { KEYSC, DMAC45, USB, CMT } }, + { 0xa4080018, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, SCIF2 } }, + { 0xa408001c, 0, 16, 4, /* IPRH */ { SIOF0, SIOF1, FLCTL, I2C } }, + { 0xa4080020, 0, 16, 4, /* IPRI */ { SIO, 0, TSIF, RTC } }, + { 0xa4080024, 0, 16, 4, /* IPRJ */ { 0, 0, SIU } }, + { 0xa4080028, 0, 16, 4, /* IPRK */ { 0, 0, 0, SDHI } }, + { 0xa408002c, 0, 16, 4, /* IPRL */ { TWODG, 0, TPU } }, + { 0xa4140010, 0, 32, 4, /* INTPRI00 */ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; -static struct intc_sense_reg sense_registers[] = { +static struct intc_sense_reg sense_registers[] __initdata = { { 0xa414001c, 16, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index 6a04cc5f5aca..32f4f59a837b 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -51,3 +51,7 @@ static int __init sh7770_devices_setup(void) ARRAY_SIZE(sh7770_devices)); } __initcall(sh7770_devices_setup); + +void __init plat_irq_setup(void) +{ +} diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index a4127ec15203..e8fd33ff0605 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -10,6 +10,7 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> +#include <linux/io.h> #include <asm/sci.h> static struct resource rtc_resources[] = { @@ -114,7 +115,7 @@ enum { PCIC5, SCIF1, MMCIF, TMU345, FLCTL, GPIO, }; -static struct intc_vect vectors[] = { +static struct intc_vect vectors[] __initdata = { INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), INTC_VECT(RTC_CUI, 0x4c0), INTC_VECT(WDT, 0x560), @@ -150,7 +151,7 @@ static struct intc_vect vectors[] = { INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0), }; -static struct intc_group groups[] = { +static struct intc_group groups[] __initdata = { INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI), INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, @@ -167,12 +168,12 @@ static struct intc_group groups[] = { INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3), }; -static struct intc_prio priorities[] = { +static struct intc_prio priorities[] __initdata = { INTC_PRIO(SCIF0, 3), INTC_PRIO(SCIF1, 3), }; -static struct intc_mask_reg mask_registers[] = { +static struct intc_mask_reg mask_registers[] __initdata = { { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */ { 0, 0, 0, 0, 0, 0, GPIO, FLCTL, SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB, @@ -180,16 +181,18 @@ static struct intc_mask_reg mask_registers[] = { HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } }, }; -static struct intc_prio_reg prio_registers[] = { - { 0xffd40000, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, TMU2, TMU2_TICPI } }, - { 0xffd40004, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } }, - { 0xffd40008, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } }, - { 0xffd4000c, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } }, - { 0xffd40010, 32, 8, /* INT2PRI4 */ { CMT, HAC, PCISERR, PCIINTA, } }, - { 0xffd40014, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC, - PCIINTD, PCIC5 } }, - { 0xffd40018, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } }, - { 0xffd4001c, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } }, +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, + TMU2, TMU2_TICPI } }, + { 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } }, + { 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } }, + { 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } }, + { 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { CMT, HAC, + PCISERR, PCIINTA, } }, + { 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC, + PCIINTD, PCIC5 } }, + { 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } }, + { 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } }, }; static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities, @@ -197,24 +200,24 @@ static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities, /* Support for external interrupt pins in IRQ mode */ -static struct intc_vect irq_vectors[] = { +static struct intc_vect irq_vectors[] __initdata = { INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380), INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200), }; -static struct intc_mask_reg irq_mask_registers[] = { +static struct intc_mask_reg irq_mask_registers[] __initdata = { { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; -static struct intc_prio_reg irq_prio_registers[] = { - { 0xffd00010, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, - IRQ4, IRQ5, IRQ6, IRQ7 } }, +static struct intc_prio_reg irq_prio_registers[] __initdata = { + { 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, + IRQ4, IRQ5, IRQ6, IRQ7 } }, }; -static struct intc_sense_reg irq_sense_registers[] = { +static struct intc_sense_reg irq_sense_registers[] __initdata = { { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; @@ -225,7 +228,7 @@ static DECLARE_INTC_DESC(intc_irq_desc, "sh7780-irq", irq_vectors, /* External interrupt pins in IRL mode */ -static struct intc_vect irl_vectors[] = { +static struct intc_vect irl_vectors[] __initdata = { INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0), @@ -236,16 +239,16 @@ static struct intc_vect irl_vectors[] = { INTC_VECT(IRL_HHHL, 0x3c0), }; -static struct intc_mask_reg irl3210_mask_registers[] = { - { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */ +static struct intc_mask_reg irl3210_mask_registers[] __initdata = { + { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */ { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, IRL_HHLL, IRL_HHLH, IRL_HHHL, } }, }; -static struct intc_mask_reg irl7654_mask_registers[] = { - { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */ +static struct intc_mask_reg irl7654_mask_registers[] __initdata = { + { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, @@ -259,8 +262,28 @@ static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors, static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors, NULL, NULL, irl3210_mask_registers, NULL, NULL); +#define INTC_ICR0 0xffd00000 +#define INTC_INTMSK0 0xffd00044 +#define INTC_INTMSK1 0xffd00048 +#define INTC_INTMSK2 0xffd40080 +#define INTC_INTMSKCLR1 0xffd00068 +#define INTC_INTMSKCLR2 0xffd40084 + void __init plat_irq_setup(void) { + /* disable IRQ7-0 */ + ctrl_outl(0xff000000, INTC_INTMSK0); + + /* disable IRL3-0 + IRL7-4 */ + ctrl_outl(0xc0000000, INTC_INTMSK1); + ctrl_outl(0xfffefffe, INTC_INTMSK2); + + /* select IRL mode for IRL3-0 + IRL7-4 */ + ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); + + /* disable holding function, ie enable "SH-4 Mode" */ + ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0); + register_intc_controller(&intc_desc); } @@ -268,12 +291,28 @@ void __init plat_irq_setup_pins(int mode) { switch (mode) { case IRQ_MODE_IRQ: + /* select IRQ mode for IRL3-0 + IRL7-4 */ + ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0); register_intc_controller(&intc_irq_desc); break; case IRQ_MODE_IRL7654: - register_intc_controller(&intc_irl7654_desc); + /* enable IRL7-4 but don't provide any masking */ + ctrl_outl(0x40000000, INTC_INTMSKCLR1); + ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL3210: + /* enable IRL0-3 but don't provide any masking */ + ctrl_outl(0x80000000, INTC_INTMSKCLR1); + ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); + break; + case IRQ_MODE_IRL7654_MASK: + /* enable IRL7-4 and mask using cpu intc controller */ + ctrl_outl(0x40000000, INTC_INTMSKCLR1); + register_intc_controller(&intc_irl7654_desc); + break; + case IRQ_MODE_IRL3210_MASK: + /* enable IRL0-3 and mask using cpu intc controller */ + ctrl_outl(0x80000000, INTC_INTMSKCLR1); register_intc_controller(&intc_irl3210_desc); break; default: diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index cf047562e43f..39b215d6cee5 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -10,6 +10,9 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> +#include <linux/io.h> +#include <linux/mm.h> +#include <asm/mmzone.h> #include <asm/sci.h> static struct plat_sci_port sci_platform_data[] = { @@ -72,46 +75,281 @@ static int __init sh7785_devices_setup(void) } __initcall(sh7785_devices_setup); -static struct intc2_data intc2_irq_table[] = { - { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ - - { 40, 8, 24, 0, 2, 3 }, /* SCIF0 ERI */ - { 41, 8, 24, 0, 2, 3 }, /* SCIF0 RXI */ - { 42, 8, 24, 0, 2, 3 }, /* SCIF0 BRI */ - { 43, 8, 24, 0, 2, 3 }, /* SCIF0 TXI */ - - { 44, 8, 16, 0, 3, 3 }, /* SCIF1 ERI */ - { 45, 8, 16, 0, 3, 3 }, /* SCIF1 RXI */ - { 46, 8, 16, 0, 3, 3 }, /* SCIF1 BRI */ - { 47, 8, 16, 0, 3, 3 }, /* SCIF1 TXI */ - - { 64, 0x14, 8, 0, 14, 2 }, /* PCIC0 */ - { 65, 0x14, 0, 0, 15, 2 }, /* PCIC1 */ - { 66, 0x18, 24, 0, 16, 2 }, /* PCIC2 */ - { 67, 0x18, 16, 0, 17, 2 }, /* PCIC3 */ - { 68, 0x18, 8, 0, 18, 2 }, /* PCIC4 */ - - { 60, 8, 8, 0, 4, 3 }, /* SCIF2 ERI, RXI, BRI, TXI */ - { 60, 8, 0, 0, 5, 3 }, /* SCIF3 ERI, RXI, BRI, TXI */ - { 60, 12, 24, 0, 6, 3 }, /* SCIF4 ERI, RXI, BRI, TXI */ - { 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */ +enum { + UNUSED = 0, + + /* interrupt sources */ + + IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH, + IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH, + IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH, + IRL0_HHLL, IRL0_HHLH, IRL0_HHHL, + + IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH, + IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH, + IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH, + IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, + + IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, + WDT, + TMU0, TMU1, TMU2, TMU2_TICPI, + HUDI, + DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, + DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE, + SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI, + SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI, + DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9, + DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE, + HSPI, + SCIF2, SCIF3, SCIF4, SCIF5, + PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, + PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0, + SIOF, + MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY, + DU, + GDTA_GACLI, GDTA_GAMCI, GDTA_GAERI, + TMU3, TMU4, TMU5, + SSI0, SSI1, + HAC0, HAC1, + FLCTL_FLSTE, FLCTL_FLEND, FLCTL_FLTRQ0, FLCTL_FLTRQ1, + GPIOI0, GPIOI1, GPIOI2, GPIOI3, + + /* interrupt groups */ + + TMU012, DMAC0, SCIF0, SCIF1, DMAC1, + PCIC5, MMCIF, GDTA, TMU345, FLCTL, GPIO }; -static struct intc2_desc intc2_irq_desc __read_mostly = { - .prio_base = 0xffd40000, - .msk_base = 0xffd40038, - .mskclr_base = 0xffd4003c, +static struct intc_vect vectors[] __initdata = { + INTC_VECT(WDT, 0x560), + INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0), + INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0), + INTC_VECT(HUDI, 0x600), + INTC_VECT(DMAC0_DMINT0, 0x620), INTC_VECT(DMAC0_DMINT1, 0x640), + INTC_VECT(DMAC0_DMINT2, 0x660), INTC_VECT(DMAC0_DMINT3, 0x680), + INTC_VECT(DMAC0_DMINT4, 0x6a0), INTC_VECT(DMAC0_DMINT5, 0x6c0), + INTC_VECT(DMAC0_DMAE, 0x6e0), + INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720), + INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760), + INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0), + INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0), + INTC_VECT(DMAC1_DMINT6, 0x880), INTC_VECT(DMAC1_DMINT7, 0x8a0), + INTC_VECT(DMAC1_DMINT8, 0x8c0), INTC_VECT(DMAC1_DMINT9, 0x8e0), + INTC_VECT(DMAC1_DMINT10, 0x900), INTC_VECT(DMAC1_DMINT11, 0x920), + INTC_VECT(DMAC1_DMAE, 0x940), + INTC_VECT(HSPI, 0x960), + INTC_VECT(SCIF2, 0x980), INTC_VECT(SCIF3, 0x9a0), + INTC_VECT(SCIF4, 0x9c0), INTC_VECT(SCIF5, 0x9e0), + INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20), + INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60), + INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0), + INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0), + INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20), + INTC_VECT(SIOF, 0xc00), + INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20), + INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60), + INTC_VECT(DU, 0xd80), + INTC_VECT(GDTA_GACLI, 0xda0), INTC_VECT(GDTA_GAMCI, 0xdc0), + INTC_VECT(GDTA_GAERI, 0xde0), + INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20), + INTC_VECT(TMU5, 0xe40), + INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0), + INTC_VECT(HAC0, 0xec0), INTC_VECT(HAC1, 0xee0), + INTC_VECT(FLCTL_FLSTE, 0xf00), INTC_VECT(FLCTL_FLEND, 0xf20), + INTC_VECT(FLCTL_FLTRQ0, 0xf40), INTC_VECT(FLCTL_FLTRQ1, 0xf60), + INTC_VECT(GPIOI0, 0xf80), INTC_VECT(GPIOI1, 0xfa0), + INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0), +}; - .intc2_data = intc2_irq_table, - .nr_irqs = ARRAY_SIZE(intc2_irq_table), +static struct intc_group groups[] __initdata = { + INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI), + INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, + DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE), + INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), + INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI), + INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, + DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE), + INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0), + INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY), + INTC_GROUP(GDTA, GDTA_GACLI, GDTA_GAMCI, GDTA_GAERI), + INTC_GROUP(TMU345, TMU3, TMU4, TMU5), + INTC_GROUP(FLCTL, FLCTL_FLSTE, FLCTL_FLEND, + FLCTL_FLTRQ0, FLCTL_FLTRQ1), + INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3), +}; - .chip = { - .name = "INTC2-sh7785", - }, +static struct intc_prio priorities[] __initdata = { + INTC_PRIO(SCIF0, 3), + INTC_PRIO(SCIF1, 3), + INTC_PRIO(SCIF2, 3), + INTC_PRIO(SCIF3, 3), + INTC_PRIO(SCIF4, 3), + INTC_PRIO(SCIF5, 3), +}; + +static struct intc_mask_reg mask_registers[] __initdata = { + { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */ + { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, + + { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */ + { IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH, + IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH, + IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH, + IRL0_HHLL, IRL0_HHLH, IRL0_HHHL, 0, + IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH, + IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH, + IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH, + IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } }, + + { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */ + { 0, 0, 0, GDTA, DU, SSI0, SSI1, GPIO, + FLCTL, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB, + PCIINTA, PCISERR, HAC1, HAC0, DMAC1, DMAC0, HUDI, WDT, + SCIF5, SCIF4, SCIF3, SCIF2, SCIF1, SCIF0, TMU345, TMU012 } }, +}; + +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, + IRQ4, IRQ5, IRQ6, IRQ7 } }, + { 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, + TMU2, TMU2_TICPI } }, + { 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, } }, + { 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, + SCIF2, SCIF3 } }, + { 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { SCIF4, SCIF5, WDT, } }, + { 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { HUDI, DMAC0, DMAC1, } }, + { 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { HAC0, HAC1, + PCISERR, PCIINTA } }, + { 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { PCIINTB, PCIINTC, + PCIINTD, PCIC5 } }, + { 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { SIOF, HSPI, MMCIF, } }, + { 0xffd40020, 0, 32, 8, /* INT2PRI8 */ { FLCTL, GPIO, SSI0, SSI1, } }, + { 0xffd40024, 0, 32, 8, /* INT2PRI9 */ { DU, GDTA, } }, }; +static DECLARE_INTC_DESC(intc_desc, "sh7785", vectors, groups, priorities, + mask_registers, prio_registers, NULL); + +/* Support for external interrupt pins in IRQ mode */ + +static struct intc_vect vectors_irq0123[] __initdata = { + INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), + INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), +}; + +static struct intc_vect vectors_irq4567[] __initdata = { + INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380), + INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200), +}; + +static struct intc_sense_reg sense_registers[] __initdata = { + { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, + IRQ4, IRQ5, IRQ6, IRQ7 } }, +}; + +static DECLARE_INTC_DESC(intc_desc_irq0123, "sh7785-irq0123", vectors_irq0123, + NULL, NULL, mask_registers, prio_registers, + sense_registers); + +static DECLARE_INTC_DESC(intc_desc_irq4567, "sh7785-irq4567", vectors_irq4567, + NULL, NULL, mask_registers, prio_registers, + sense_registers); + +/* External interrupt pins in IRL mode */ + +static struct intc_vect vectors_irl0123[] __initdata = { + INTC_VECT(IRL0_LLLL, 0x200), INTC_VECT(IRL0_LLLH, 0x220), + INTC_VECT(IRL0_LLHL, 0x240), INTC_VECT(IRL0_LLHH, 0x260), + INTC_VECT(IRL0_LHLL, 0x280), INTC_VECT(IRL0_LHLH, 0x2a0), + INTC_VECT(IRL0_LHHL, 0x2c0), INTC_VECT(IRL0_LHHH, 0x2e0), + INTC_VECT(IRL0_HLLL, 0x300), INTC_VECT(IRL0_HLLH, 0x320), + INTC_VECT(IRL0_HLHL, 0x340), INTC_VECT(IRL0_HLHH, 0x360), + INTC_VECT(IRL0_HHLL, 0x380), INTC_VECT(IRL0_HHLH, 0x3a0), + INTC_VECT(IRL0_HHHL, 0x3c0), +}; + +static struct intc_vect vectors_irl4567[] __initdata = { + INTC_VECT(IRL4_LLLL, 0xb00), INTC_VECT(IRL4_LLLH, 0xb20), + INTC_VECT(IRL4_LLHL, 0xb40), INTC_VECT(IRL4_LLHH, 0xb60), + INTC_VECT(IRL4_LHLL, 0xb80), INTC_VECT(IRL4_LHLH, 0xba0), + INTC_VECT(IRL4_LHHL, 0xbc0), INTC_VECT(IRL4_LHHH, 0xbe0), + INTC_VECT(IRL4_HLLL, 0xc00), INTC_VECT(IRL4_HLLH, 0xc20), + INTC_VECT(IRL4_HLHL, 0xc40), INTC_VECT(IRL4_HLHH, 0xc60), + INTC_VECT(IRL4_HHLL, 0xc80), INTC_VECT(IRL4_HHLH, 0xca0), + INTC_VECT(IRL4_HHHL, 0xcc0), +}; + +static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7785-irl0123", vectors_irl0123, + NULL, NULL, mask_registers, NULL, NULL); + +static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7785-irl4567", vectors_irl4567, + NULL, NULL, mask_registers, NULL, NULL); + +#define INTC_ICR0 0xffd00000 +#define INTC_INTMSK0 0xffd00044 +#define INTC_INTMSK1 0xffd00048 +#define INTC_INTMSK2 0xffd40080 +#define INTC_INTMSKCLR1 0xffd00068 +#define INTC_INTMSKCLR2 0xffd40084 + void __init plat_irq_setup(void) { - register_intc2_controller(&intc2_irq_desc); + /* disable IRQ3-0 + IRQ7-4 */ + ctrl_outl(0xff000000, INTC_INTMSK0); + + /* disable IRL3-0 + IRL7-4 */ + ctrl_outl(0xc0000000, INTC_INTMSK1); + ctrl_outl(0xfffefffe, INTC_INTMSK2); + + /* select IRL mode for IRL3-0 + IRL7-4 */ + ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); + + /* disable holding function, ie enable "SH-4 Mode" */ + ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0); + + register_intc_controller(&intc_desc); +} + +void __init plat_irq_setup_pins(int mode) +{ + switch (mode) { + case IRQ_MODE_IRQ7654: + /* select IRQ mode for IRL7-4 */ + ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0); + register_intc_controller(&intc_desc_irq4567); + break; + case IRQ_MODE_IRQ3210: + /* select IRQ mode for IRL3-0 */ + ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0); + register_intc_controller(&intc_desc_irq0123); + break; + case IRQ_MODE_IRL7654: + /* enable IRL7-4 but don't provide any masking */ + ctrl_outl(0x40000000, INTC_INTMSKCLR1); + ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); + break; + case IRQ_MODE_IRL3210: + /* enable IRL0-3 but don't provide any masking */ + ctrl_outl(0x80000000, INTC_INTMSKCLR1); + ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); + break; + case IRQ_MODE_IRL7654_MASK: + /* enable IRL7-4 and mask using cpu intc controller */ + ctrl_outl(0x40000000, INTC_INTMSKCLR1); + register_intc_controller(&intc_desc_irl4567); + break; + case IRQ_MODE_IRL3210_MASK: + /* enable IRL0-3 and mask using cpu intc controller */ + ctrl_outl(0x80000000, INTC_INTMSKCLR1); + register_intc_controller(&intc_desc_irl0123); + break; + default: + BUG(); + } } +void __init plat_mem_setup(void) +{ + /* Register the URAM space as Node 1 */ + setup_bootmem_node(1, 0xe55f0000, 0xe5610000); +} diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 704c064f70dc..c6cdd7e3b049 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -11,6 +11,7 @@ #include <linux/init.h> #include <linux/serial.h> #include <linux/io.h> +#include <asm/mmzone.h> #include <asm/sci.h> static struct plat_sci_port sci_platform_data[] = { @@ -58,28 +59,229 @@ static int __init shx3_devices_setup(void) } __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 */ +enum { + UNUSED = 0, + + /* interrupt sources */ + IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, + IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, + IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, + IRL_HHLL, IRL_HHLH, IRL_HHHL, + IRQ0, IRQ1, IRQ2, IRQ3, + HUDII, + TMU0, TMU1, TMU2, TMU3, TMU4, TMU5, + PCII0, PCII1, PCII2, PCII3, PCII4, + PCII5, PCII6, PCII7, PCII8, PCII9, + SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI, + SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI, + SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI, + SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI, + DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, + DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE, + DU, + DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9, + DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE, + IIC, VIN0, VIN1, VCORE0, ATAPI, + DTU0_TEND, DTU0_AE, DTU0_TMISS, + DTU1_TEND, DTU1_AE, DTU1_TMISS, + DTU2_TEND, DTU2_AE, DTU2_TMISS, + DTU3_TEND, DTU3_AE, DTU3_TMISS, + FE0, FE1, + GPIO0, GPIO1, GPIO2, GPIO3, + PAM, IRM, + INTICI0, INTICI1, INTICI2, INTICI3, + INTICI4, INTICI5, INTICI6, INTICI7, + + /* interrupt groups */ + IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3, + DMAC0, DMAC1, DTU0, DTU1, DTU2, DTU3, +}; + +static struct intc_vect vectors[] __initdata = { + INTC_VECT(HUDII, 0x3e0), + INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), + INTC_VECT(TMU2, 0x440), INTC_VECT(TMU3, 0x460), + INTC_VECT(TMU4, 0x480), INTC_VECT(TMU5, 0x4a0), + INTC_VECT(PCII0, 0x500), INTC_VECT(PCII1, 0x520), + INTC_VECT(PCII2, 0x540), INTC_VECT(PCII3, 0x560), + INTC_VECT(PCII4, 0x580), INTC_VECT(PCII5, 0x5a0), + INTC_VECT(PCII6, 0x5c0), INTC_VECT(PCII7, 0x5e0), + INTC_VECT(PCII8, 0x600), INTC_VECT(PCII9, 0x620), + INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720), + INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760), + INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0), + INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0), + INTC_VECT(SCIF2_ERI, 0x800), INTC_VECT(SCIF2_RXI, 0x820), + INTC_VECT(SCIF2_BRI, 0x840), INTC_VECT(SCIF2_TXI, 0x860), + INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0), + INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0), + INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920), + INTC_VECT(DMAC0_DMINT2, 0x940), INTC_VECT(DMAC0_DMINT3, 0x960), + INTC_VECT(DMAC0_DMINT4, 0x980), INTC_VECT(DMAC0_DMINT5, 0x9a0), + INTC_VECT(DMAC0_DMAE, 0x9c0), + INTC_VECT(DU, 0x9e0), + INTC_VECT(DMAC1_DMINT6, 0xa00), INTC_VECT(DMAC1_DMINT7, 0xa20), + INTC_VECT(DMAC1_DMINT8, 0xa40), INTC_VECT(DMAC1_DMINT9, 0xa60), + INTC_VECT(DMAC1_DMINT10, 0xa80), INTC_VECT(DMAC1_DMINT11, 0xaa0), + INTC_VECT(DMAC1_DMAE, 0xac0), + INTC_VECT(IIC, 0xae0), + INTC_VECT(VIN0, 0xb00), INTC_VECT(VIN1, 0xb20), + INTC_VECT(VCORE0, 0xb00), INTC_VECT(ATAPI, 0xb60), + INTC_VECT(DTU0_TEND, 0xc00), INTC_VECT(DTU0_AE, 0xc20), + INTC_VECT(DTU0_TMISS, 0xc40), + INTC_VECT(DTU1_TEND, 0xc60), INTC_VECT(DTU1_AE, 0xc80), + INTC_VECT(DTU1_TMISS, 0xca0), + INTC_VECT(DTU2_TEND, 0xcc0), INTC_VECT(DTU2_AE, 0xce0), + INTC_VECT(DTU2_TMISS, 0xd00), + INTC_VECT(DTU3_TEND, 0xd20), INTC_VECT(DTU3_AE, 0xd40), + INTC_VECT(DTU3_TMISS, 0xd60), + INTC_VECT(FE0, 0xe00), INTC_VECT(FE1, 0xe20), + INTC_VECT(GPIO0, 0xe40), INTC_VECT(GPIO1, 0xe60), + INTC_VECT(GPIO2, 0xe80), INTC_VECT(GPIO3, 0xea0), + INTC_VECT(PAM, 0xec0), INTC_VECT(IRM, 0xee0), + INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20), + INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60), + INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0), + INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0), }; -static struct intc2_desc intc2_irq_desc __read_mostly = { - .prio_base = 0xfe410000, - .msk_base = 0xfe410820, - .mskclr_base = 0xfe410850, +static struct intc_group groups[] __initdata = { + INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, + IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, + IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, + IRL_HHLL, IRL_HHLH, IRL_HHHL), + INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9), + INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), + INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI), + INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI), + INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI), + INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, + DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE), + INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, + DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11), + INTC_GROUP(DTU0, DTU0_TEND, DTU0_AE, DTU0_TMISS), + INTC_GROUP(DTU1, DTU1_TEND, DTU1_AE, DTU1_TMISS), + INTC_GROUP(DTU2, DTU2_TEND, DTU2_AE, DTU2_TMISS), + INTC_GROUP(DTU3, DTU3_TEND, DTU3_AE, DTU3_TMISS), +}; - .intc2_data = intc2_irq_table, - .nr_irqs = ARRAY_SIZE(intc2_irq_table), +static struct intc_prio priorities[] __initdata = { + INTC_PRIO(SCIF0, 3), + INTC_PRIO(SCIF1, 3), + INTC_PRIO(SCIF2, 3), + INTC_PRIO(SCIF3, 3), +}; - .chip = { - .name = "INTC2-SHX3", - }, +static struct intc_mask_reg mask_registers[] __initdata = { + { 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */ + { IRQ0, IRQ1, IRQ2, IRQ3 } }, + { 0xfe410040, 0xfe410060, 32, /* CnINTMSK1 / CnINTMSKCLR1 */ + { IRL } }, + { 0xfe410820, 0xfe410850, 32, /* CnINT2MSK0 / CnINT2MSKCLR0 */ + { FE1, FE0, 0, ATAPI, VCORE0, VIN1, VIN0, IIC, + DU, GPIO3, GPIO2, GPIO1, GPIO0, PAM, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* HUDI bits ignored */ + 0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, } }, + { 0xfe410830, 0xfe410860, 32, /* CnINT2MSK1 / CnINT2MSKCLR1 */ + { 0, 0, 0, 0, DTU3, DTU2, DTU1, DTU0, /* IRM bits ignored */ + PCII9, PCII8, PCII7, PCII6, PCII5, PCII4, PCII3, PCII2, + PCII1, PCII0, DMAC1_DMAE, DMAC1_DMINT11, + DMAC1_DMINT10, DMAC1_DMINT9, DMAC1_DMINT8, DMAC1_DMINT7, + DMAC1_DMINT6, DMAC0_DMAE, DMAC0_DMINT5, DMAC0_DMINT4, + DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 } }, + { 0xfe410840, 0xfe410870, 32, /* CnINT2MSK2 / CnINT2MSKCLR2 */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + SCIF3_TXI, SCIF3_BRI, SCIF3_RXI, SCIF3_ERI, + SCIF2_TXI, SCIF2_BRI, SCIF2_RXI, SCIF2_ERI, + SCIF1_TXI, SCIF1_BRI, SCIF1_RXI, SCIF1_ERI, + SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI } }, +}; + +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } }, + + { 0xfe410800, 0, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4, + TMU3, TMU2, TMU1, TMU0 } }, + { 0xfe410804, 0, 32, 4, /* INT2PRI1 */ { DTU3, DTU2, DTU1, DTU0, + SCIF3, SCIF2, + SCIF1, SCIF0 } }, + { 0xfe410808, 0, 32, 4, /* INT2PRI2 */ { DMAC1, DMAC0, + PCII56789, PCII4, + PCII3, PCII2, + PCII1, PCII0 } }, + { 0xfe41080c, 0, 32, 4, /* INT2PRI3 */ { FE1, FE0, ATAPI, VCORE0, + VIN1, VIN0, IIC, DU} }, + { 0xfe410810, 0, 32, 4, /* INT2PRI4 */ { 0, 0, PAM, GPIO3, + GPIO2, GPIO1, GPIO0, IRM } }, + { 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */ + { INTICI7, INTICI6, INTICI5, INTICI4, + INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 4) }, +}; + +static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups, priorities, + mask_registers, prio_registers, NULL); + +/* Support for external interrupt pins in IRQ mode */ +static struct intc_vect vectors_irq[] __initdata = { + INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), + INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), +}; + +static struct intc_sense_reg sense_registers[] __initdata = { + { 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3 } }, }; +static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups, + priorities, mask_registers, prio_registers, + sense_registers); + +/* External interrupt pins in IRL mode */ +static struct intc_vect vectors_irl[] __initdata = { + INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), + INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), + INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0), + INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0), + INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320), + INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360), + INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0), + INTC_VECT(IRL_HHHL, 0x3c0), +}; + +static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups, + priorities, mask_registers, prio_registers, NULL); + +void __init plat_irq_setup_pins(int mode) +{ + switch (mode) { + case IRQ_MODE_IRQ: + register_intc_controller(&intc_desc_irq); + break; + case IRQ_MODE_IRL3210: + register_intc_controller(&intc_desc_irl); + break; + default: + BUG(); + } +} + void __init plat_irq_setup(void) { - register_intc2_controller(&intc2_irq_desc); + register_intc_controller(&intc_desc); +} + +void __init plat_mem_setup(void) +{ + unsigned int nid = 1; + + /* Register CPU#0 URAM space as Node 1 */ + setup_bootmem_node(nid++, 0x145f0000, 0x14610000); /* CPU0 */ + +#if 0 + /* XXX: Not yet.. */ + setup_bootmem_node(nid++, 0x14df0000, 0x14e10000); /* CPU1 */ + setup_bootmem_node(nid++, 0x155f0000, 0x15610000); /* CPU2 */ + setup_bootmem_node(nid++, 0x15df0000, 0x15e10000); /* CPU3 */ +#endif + + setup_bootmem_node(nid++, 0x16000000, 0x16020000); /* CSM */ } diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c new file mode 100644 index 000000000000..e5e06845fa43 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c @@ -0,0 +1,120 @@ +/* + * SH-X3 SMP + * + * Copyright (C) 2007 Paul Mundt + * Copyright (C) 2007 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/cpumask.h> +#include <linux/smp.h> +#include <linux/interrupt.h> +#include <linux/io.h> + +void __init plat_smp_setup(void) +{ + unsigned int cpu = 0; + int i, num; + + cpus_clear(cpu_possible_map); + cpu_set(cpu, cpu_possible_map); + + __cpu_number_map[0] = 0; + __cpu_logical_map[0] = 0; + + /* + * Do this stupidly for now.. we don't have an easy way to probe + * for the total number of cores. + */ + for (i = 1, num = 0; i < NR_CPUS; i++) { + cpu_set(i, cpu_possible_map); + __cpu_number_map[i] = ++num; + __cpu_logical_map[num] = i; + } + + printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num); +} + +void __init plat_prepare_cpus(unsigned int max_cpus) +{ +} + +#define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12)) +#define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12)) + +#define STBCR_MSTP 0x00000001 +#define STBCR_RESET 0x00000002 +#define STBCR_LTSLP 0x80000000 + +#define STBCR_AP_VAL (STBCR_RESET | STBCR_LTSLP) + +void plat_start_cpu(unsigned int cpu, unsigned long entry_point) +{ + ctrl_outl(entry_point, RESET_REG(cpu)); + + if (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP)) + ctrl_outl(STBCR_MSTP, STBCR_REG(cpu)); + + while (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP)) + ; + + /* Start up secondary processor by sending a reset */ + ctrl_outl(STBCR_AP_VAL, STBCR_REG(cpu)); +} + +int plat_smp_processor_id(void) +{ + return ctrl_inl(0xff000048); /* CPIDR */ +} + +void plat_send_ipi(unsigned int cpu, unsigned int message) +{ + unsigned long addr = 0xfe410070 + (cpu * 4); + + BUG_ON(cpu >= 4); + BUG_ON(message >= SMP_MSG_NR); + + ctrl_outl(1 << (message << 2), addr); /* C0INTICI..CnINTICI */ +} + +struct ipi_data { + void (*handler)(void *); + void *arg; + unsigned int message; +}; + +static irqreturn_t ipi_interrupt_handler(int irq, void *arg) +{ + struct ipi_data *id = arg; + unsigned int cpu = hard_smp_processor_id(); + unsigned int offs = 4 * cpu; + unsigned int x; + + x = ctrl_inl(0xfe410070 + offs); /* C0INITICI..CnINTICI */ + x &= (1 << (id->message << 2)); + ctrl_outl(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */ + + id->handler(id->arg); + + return IRQ_HANDLED; +} + +static struct ipi_data ipi_handlers[SMP_MSG_NR]; + +int plat_register_ipi_handler(unsigned int message, + void (*handler)(void *), void *arg) +{ + struct ipi_data *id = &ipi_handlers[message]; + + BUG_ON(SMP_MSG_NR >= 8); + BUG_ON(message >= SMP_MSG_NR); + + id->handler = handler; + id->arg = arg; + id->message = message; + + return request_irq(104 + message, ipi_interrupt_handler, 0, "IPI", id); +} diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c index e61890217c50..e0590ffebd73 100644 --- a/arch/sh/kernel/cpufreq.c +++ b/arch/sh/kernel/cpufreq.c @@ -77,8 +77,6 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy, static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy) { - printk(KERN_INFO "cpufreq: SuperH CPU frequency driver.\n"); - if (!cpu_online(policy->cpu)) return -ENODEV; @@ -93,7 +91,6 @@ static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->cpuinfo.max_freq = (clk_round_rate(cpuclk, ~0UL) + 500) / 1000; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cur = sh_cpufreq_get(policy->cpu); policy->min = policy->cpuinfo.min_freq; policy->max = policy->cpuinfo.max_freq; @@ -144,6 +141,7 @@ static struct cpufreq_driver sh_cpufreq_driver = { static int __init sh_cpufreq_module_init(void) { + printk(KERN_INFO "cpufreq: SuperH CPU frequency driver.\n"); return cpufreq_register_driver(&sh_cpufreq_driver); } diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index 80b637c30203..2f30977558ad 100644 --- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -3,7 +3,7 @@ * * Copyright (C) 1999, 2000 Niibe Yutaka * Copyright (C) 2002 M. R. Brown - * Copyright (C) 2004 - 2006 Paul Mundt + * Copyright (C) 2004 - 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 @@ -13,6 +13,7 @@ #include <linux/tty.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/delay.h> #ifdef CONFIG_SH_STANDARD_BIOS #include <asm/sh_bios.h> @@ -62,6 +63,16 @@ static struct console bios_console = { #include <linux/serial_core.h> #include "../../../drivers/serial/sh-sci.h" +#if defined(CONFIG_CPU_SUBTYPE_SH7720) +#define EPK_SCSMR_VALUE 0x000 +#define EPK_SCBRR_VALUE 0x00C +#define EPK_FIFO_SIZE 64 +#define EPK_FIFO_BITS (0x7f00 >> 8) +#else +#define EPK_FIFO_SIZE 16 +#define EPK_FIFO_BITS (0x1f00 >> 8) +#endif + static struct uart_port scif_port = { .mapbase = CONFIG_EARLY_SCIF_CONSOLE_PORT, .membase = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT, @@ -69,7 +80,7 @@ static struct uart_port scif_port = { static void scif_sercon_putc(int c) { - while (((sci_in(&scif_port, SCFDR) & 0x1f00 >> 8) == 16)) + while (((sci_in(&scif_port, SCFDR) & EPK_FIFO_BITS) >= EPK_FIFO_SIZE)) ; sci_out(&scif_port, SCxTDR, c); @@ -105,7 +116,22 @@ static struct console scif_console = { .index = -1, }; -#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) +#if !defined(CONFIG_SH_STANDARD_BIOS) +#if defined(CONFIG_CPU_SUBTYPE_SH7720) +static void scif_sercon_init(char *s) +{ + sci_out(&scif_port, SCSCR, 0x0000); /* clear TE and RE */ + sci_out(&scif_port, SCFCR, 0x4006); /* reset */ + sci_out(&scif_port, SCSCR, 0x0000); /* select internal clock */ + sci_out(&scif_port, SCSMR, EPK_SCSMR_VALUE); + sci_out(&scif_port, SCBRR, EPK_SCBRR_VALUE); + + mdelay(1); /* wait 1-bit time */ + + sci_out(&scif_port, SCFCR, 0x0030); /* TTRG=b'11 */ + sci_out(&scif_port, SCSCR, 0x0030); /* TE, RE */ +} +#elif defined(CONFIG_CPU_SH4) #define DEFAULT_BAUD 115200 /* * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4 @@ -146,7 +172,8 @@ static void scif_sercon_init(char *s) ctrl_outw(0, scif_port.mapbase + 36); ctrl_outw(0x30, scif_port.mapbase + 8); } -#endif /* CONFIG_CPU_SH4 && !CONFIG_SH_STANDARD_BIOS */ +#endif /* defined(CONFIG_CPU_SUBTYPE_SH7720) */ +#endif /* !defined(CONFIG_SH_STANDARD_BIOS) */ #endif /* CONFIG_EARLY_SCIF_CONSOLE */ /* @@ -163,17 +190,12 @@ static struct console *early_console = #endif ; -static int __initdata keep_early; -static int early_console_initialized; - -int __init setup_early_printk(char *buf) +static int __init setup_early_printk(char *buf) { - if (!buf) - return 0; + int keep_early = 0; - if (early_console_initialized) + if (!buf) return 0; - early_console_initialized = 1; if (strstr(buf, "keep")) keep_early = 1; @@ -186,7 +208,8 @@ int __init setup_early_printk(char *buf) if (!strncmp(buf, "serial", 6)) { early_console = &scif_console; -#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) +#if (defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SUBTYPE_SH7720)) && \ + !defined(CONFIG_SH_STANDARD_BIOS) scif_sercon_init(buf + 6); #endif } diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index b46728027195..e0317ed080c3 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -176,7 +176,7 @@ work_notifysig: jmp @r1 lds r0, pr work_resched: -#ifndef CONFIG_PREEMPT +#if defined(CONFIG_GUSA) && !defined(CONFIG_PREEMPT) ! gUSA handling mov.l @(OFF_SP,r15), r0 ! get user space stack pointer mov r0, r1 diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S index 0bccc0ca5a0f..3338239717f1 100644 --- a/arch/sh/kernel/head.S +++ b/arch/sh/kernel/head.S @@ -54,8 +54,8 @@ ENTRY(_stext) mov.l 1f, r0 ! MD=1, RB=0, BL=0, IMASK=0xF ldc r0, sr ! Initialize global interrupt mask - mov #0, r0 #ifdef CONFIG_CPU_HAS_SR_RB + mov #0, r0 ldc r0, r6_bank #endif @@ -72,15 +72,18 @@ ENTRY(_stext) ! mov.l 2f, r0 mov r0, r15 ! Set initial r15 (stack pointer) - mov #(THREAD_SIZE >> 10), r1 - shll8 r1 ! r1 = THREAD_SIZE - shll2 r1 - sub r1, r0 ! #ifdef CONFIG_CPU_HAS_SR_RB + mov.l 7f, r0 ldc r0, r7_bank ! ... and initial thread_info #endif ! Clear BSS area +#ifdef CONFIG_SMP + mov.l 3f, r0 + cmp/eq #0, r0 ! skip clear if set to zero + bt 10f +#endif + mov.l 3f, r1 add #4, r1 mov.l 4f, r2 @@ -89,13 +92,14 @@ ENTRY(_stext) bf/s 9b ! while (r1 < r2) mov.l r0,@-r2 +10: ! Additional CPU initialization mov.l 6f, r0 jsr @r0 nop SYNCO() ! Wait for pending instructions.. - + ! Start kernel mov.l 5f, r0 jmp @r0 @@ -107,8 +111,10 @@ ENTRY(_stext) #else 1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF #endif +ENTRY(stack_start) 2: .long init_thread_union+THREAD_SIZE 3: .long __bss_start 4: .long _end 5: .long start_kernel 6: .long sh_cpu_init +7: .long init_thread_union diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c index edd1ec214e6d..2fdc700dfd6e 100644 --- a/arch/sh/kernel/kgdb_stub.c +++ b/arch/sh/kernel/kgdb_stub.c @@ -150,13 +150,6 @@ struct kgdb_regs trap_registers; char kgdb_in_gdb_mode; char in_nmi; /* Set during NMI to prevent reentry */ int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */ -int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */ - -/* Exposed for user access */ -struct task_struct *kgdb_current; -unsigned int kgdb_g_imask; -int kgdb_trapa_val; -int kgdb_excode; /* Default values for SCI (can override via kernel args in setup.c) */ #ifndef CONFIG_KGDB_DEFPORT @@ -616,7 +609,7 @@ static short *get_step_address(void) else addr = trap_registers.pc + 2; - kgdb_flush_icache_range(addr, addr + 2); + flush_icache_range(addr, addr + 2); return (short *) addr; } @@ -639,8 +632,7 @@ static void do_single_step(void) *addr = STEP_OPCODE; /* Flush and return */ - kgdb_flush_icache_range((long) addr, (long) addr + 2); - return; + flush_icache_range((long) addr, (long) addr + 2); } /* Undo a single step */ @@ -650,7 +642,7 @@ static void undo_single_step(void) /* Use stepped_address in case we stopped elsewhere */ if (stepped_opcode != 0) { *(short*)stepped_address = stepped_opcode; - kgdb_flush_icache_range(stepped_address, stepped_address + 2); + flush_icache_range(stepped_address, stepped_address + 2); } stepped_opcode = 0; } @@ -736,7 +728,7 @@ static void write_mem_msg(int binary) ebin_to_mem(ptr, (char*)addr, length); else hex_to_mem(ptr, (char*)addr, length); - kgdb_flush_icache_range(addr, addr + length); + flush_icache_range(addr, addr + length); ptr = 0; send_ok_msg(); } @@ -815,14 +807,10 @@ static void set_regs_msg(void) /* * Bring up the ports.. */ -static int kgdb_serial_setup(void) +static int __init kgdb_serial_setup(void) { - extern int kgdb_console_setup(struct console *co, char *options); struct console dummy; - - kgdb_console_setup(&dummy, 0); - - return 0; + return kgdb_console_setup(&dummy, 0); } #else #define kgdb_serial_setup() 0 @@ -833,22 +821,6 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) { int sigval; - if (excep_code == NMI_VEC) { -#ifndef CONFIG_KGDB_NMI - printk(KERN_NOTICE "KGDB: Ignoring unexpected NMI?\n"); - return; -#else /* CONFIG_KGDB_NMI */ - if (!kgdb_enabled) { - kgdb_enabled = 1; - kgdb_init(); - } -#endif /* CONFIG_KGDB_NMI */ - } - - /* Ignore if we're disabled */ - if (!kgdb_enabled) - return; - /* Enter GDB mode (e.g. after detach) */ if (!kgdb_in_gdb_mode) { /* Do serial setup, notify user, issue preemptive ack */ @@ -959,18 +931,10 @@ static void handle_exception(struct pt_regs *regs) /* Get excode for command loop call, user access */ asm("stc r2_bank, %0":"=r"(excep_code)); - kgdb_excode = excep_code; - - /* Other interesting environment items for reference */ - asm("stc r6_bank, %0":"=r"(kgdb_g_imask)); - kgdb_current = current; - kgdb_trapa_val = trapa_value; /* Act on the exception */ kgdb_command_loop(excep_code, trapa_value); - kgdb_current = NULL; - /* Copy back the (maybe modified) registers */ for (count = 0; count < 16; count++) regs->regs[count] = trap_registers.regs[count]; @@ -994,11 +958,8 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5, } /* Initialise the KGDB data structures and serial configuration */ -int kgdb_init(void) +int __init kgdb_init(void) { - if (!kgdb_enabled) - return 1; - in_nmi = 0; kgdb_nofault = 0; stepped_opcode = 0; diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 15ae322dbd74..b4469992d6b2 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -19,6 +19,7 @@ #include <linux/tick.h> #include <linux/reboot.h> #include <linux/fs.h> +#include <linux/preempt.h> #include <asm/uaccess.h> #include <asm/mmu_context.h> #include <asm/pgalloc.h> @@ -349,12 +350,11 @@ struct task_struct *__switch_to(struct task_struct *prev, unlazy_fpu(prev, task_pt_regs(prev)); #endif -#ifdef CONFIG_PREEMPT +#if defined(CONFIG_GUSA) && defined(CONFIG_PREEMPT) { - unsigned long flags; struct pt_regs *regs; - local_irq_save(flags); + preempt_disable(); regs = task_pt_regs(prev); if (user_mode(regs) && regs->regs[15] >= 0xc0000000) { int offset = (int)regs->regs[15]; @@ -365,7 +365,7 @@ struct task_struct *__switch_to(struct task_struct *prev, /* Go to rewind point */ regs->pc = regs->regs[0] + offset; } - local_irq_restore(flags); + preempt_enable_no_resched(); } #endif diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c index f64a2d2416d4..ac725f0aeb72 100644 --- a/arch/sh/kernel/ptrace.c +++ b/arch/sh/kernel/ptrace.c @@ -211,10 +211,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; } - case PTRACE_DETACH: /* detach a process that was attached. */ - ret = ptrace_detach(child, data); - break; - #ifdef CONFIG_SH_DSP case PTRACE_GETDSPREGS: { unsigned long dp; diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 2cf7dec0d690..b3027a6775b9 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -22,6 +22,7 @@ #include <linux/mm.h> #include <linux/kexec.h> #include <linux/module.h> +#include <linux/smp.h> #include <asm/uaccess.h> #include <asm/io.h> #include <asm/page.h> @@ -42,7 +43,13 @@ extern void * __rd_start, * __rd_end; * This value will be used at the very early stage of serial setup. * The bigger value means no problem. */ -struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, }; +struct sh_cpuinfo cpu_data[NR_CPUS] __read_mostly = { + [0] = { + .type = CPU_SH_NONE, + .loops_per_jiffy = 10000000, + }, +}; +EXPORT_SYMBOL(cpu_data); /* * The machine vector. First entry in .machvec.init, or clobbered by @@ -272,6 +279,10 @@ void __init setup_arch(char **cmdline_p) sh_mv.mv_setup(cmdline_p); paging_init(); + +#ifdef CONFIG_SMP + plat_smp_setup(); +#endif } static const char *cpu_name[] = { @@ -279,7 +290,7 @@ static const char *cpu_name[] = { [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708", [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710", - [CPU_SH7712] = "SH7712", + [CPU_SH7712] = "SH7712", [CPU_SH7720] = "SH7720", [CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750", [CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R", [CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R", diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index 37aef0a85197..548e4285b375 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -8,7 +8,7 @@ #include <linux/vmalloc.h> #include <linux/pci.h> #include <linux/irq.h> - +#include <asm/sections.h> #include <asm/semaphore.h> #include <asm/processor.h> #include <asm/uaccess.h> @@ -43,7 +43,6 @@ EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(__copy_user); -EXPORT_SYMBOL(boot_cpu_data); #ifdef CONFIG_MMU EXPORT_SYMBOL(get_vm_area); @@ -53,6 +52,7 @@ EXPORT_SYMBOL(get_vm_area); EXPORT_SYMBOL(__up); EXPORT_SYMBOL(__down); EXPORT_SYMBOL(__down_interruptible); +EXPORT_SYMBOL(__down_trylock); EXPORT_SYMBOL(__udelay); EXPORT_SYMBOL(__ndelay); @@ -128,7 +128,8 @@ DECLARE_EXPORT(__movstrSI12_i4); #endif /* __GNUC__ == 4 */ #endif -#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) +#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \ + defined(CONFIG_SH7705_CACHE_32KB)) /* needed by some modules */ EXPORT_SYMBOL(flush_cache_all); EXPORT_SYMBOL(flush_cache_range); @@ -136,17 +137,11 @@ EXPORT_SYMBOL(flush_dcache_page); EXPORT_SYMBOL(__flush_purge_region); #endif -#if defined(CONFIG_MMU) && (defined(CONFIG_CPU_SH4) || \ - defined(CONFIG_SH7705_CACHE_32KB)) +#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \ + (defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)) EXPORT_SYMBOL(clear_user_page); #endif -EXPORT_SYMBOL(__down_trylock); - -#ifdef CONFIG_SMP -EXPORT_SYMBOL(synchronize_irq); -#endif - EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(csum_partial_copy_generic); #ifdef CONFIG_IPV6 @@ -154,3 +149,4 @@ EXPORT_SYMBOL(csum_ipv6_magic); #endif EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(__clear_user); +EXPORT_SYMBOL(_ebss); diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index 706d81ccd101..2f42442cf164 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c @@ -507,13 +507,11 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, ctrl_inw(regs->pc - 4)); break; } +#ifdef CONFIG_GUSA } else { /* gUSA handling */ -#ifdef CONFIG_PREEMPT - unsigned long flags; + preempt_disable(); - local_irq_save(flags); -#endif if (regs->regs[15] >= 0xc0000000) { int offset = (int)regs->regs[15]; @@ -524,8 +522,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, regs->pc = regs->regs[0] + offset - instruction_size(ctrl_inw(regs->pc-4)); } -#ifdef CONFIG_PREEMPT - local_irq_restore(flags); + + preempt_enable_no_resched(); #endif } diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 283e1425ced5..94075e1a1e61 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -3,68 +3,40 @@ * * SMP support for the SuperH processors. * - * Copyright (C) 2002, 2003 Paul Mundt + * Copyright (C) 2002 - 2007 Paul Mundt + * Copyright (C) 2006 - 2007 Akio Idehara * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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/err.h> #include <linux/cache.h> #include <linux/cpumask.h> #include <linux/delay.h> #include <linux/init.h> -#include <linux/interrupt.h> #include <linux/spinlock.h> -#include <linux/threads.h> +#include <linux/mm.h> #include <linux/module.h> -#include <linux/time.h> -#include <linux/timex.h> -#include <linux/sched.h> -#include <linux/module.h> - +#include <linux/interrupt.h> #include <asm/atomic.h> #include <asm/processor.h> #include <asm/system.h> #include <asm/mmu_context.h> #include <asm/smp.h> +#include <asm/cacheflush.h> +#include <asm/sections.h> -/* - * This was written with the Sega Saturn (SMP SH-2 7604) in mind, - * but is designed to be usable regardless if there's an MMU - * present or not. - */ -struct sh_cpuinfo cpu_data[NR_CPUS]; - -extern void per_cpu_trap_init(void); +int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ +int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */ cpumask_t cpu_possible_map; EXPORT_SYMBOL(cpu_possible_map); cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); -static atomic_t cpus_booted = ATOMIC_INIT(0); -/* These are defined by the board-specific code. */ - -/* - * Cause the function described by call_data to be executed on the passed - * cpu. When the function has finished, increment the finished field of - * call_data. - */ -void __smp_send_ipi(unsigned int cpu, unsigned int action); - -/* - * Find the number of available processors - */ -unsigned int __smp_probe_cpus(void); - -/* - * Start a particular processor - */ -void __smp_slave_init(unsigned int cpu); +static atomic_t cpus_booted = ATOMIC_INIT(0); /* * Run specified function on a particular processor. @@ -73,74 +45,123 @@ void __smp_call_function(unsigned int cpu); static inline void __init smp_store_cpu_info(unsigned int cpu) { - cpu_data[cpu].loops_per_jiffy = loops_per_jiffy; + struct sh_cpuinfo *c = cpu_data + cpu; + + c->loops_per_jiffy = loops_per_jiffy; } void __init smp_prepare_cpus(unsigned int max_cpus) { unsigned int cpu = smp_processor_id(); - int i; - atomic_set(&cpus_booted, 1); - smp_store_cpu_info(cpu); - - for (i = 0; i < __smp_probe_cpus(); i++) - cpu_set(i, cpu_possible_map); + init_new_context(current, &init_mm); + current_thread_info()->cpu = cpu; + plat_prepare_cpus(max_cpus); + +#ifndef CONFIG_HOTPLUG_CPU + cpu_present_map = cpu_possible_map; +#endif } void __devinit smp_prepare_boot_cpu(void) { unsigned int cpu = smp_processor_id(); + __cpu_number_map[0] = cpu; + __cpu_logical_map[0] = cpu; + cpu_set(cpu, cpu_online_map); cpu_set(cpu, cpu_possible_map); } -int __cpu_up(unsigned int cpu) +asmlinkage void __cpuinit start_secondary(void) { - struct task_struct *tsk; + unsigned int cpu; + struct mm_struct *mm = &init_mm; - tsk = fork_idle(cpu); + atomic_inc(&mm->mm_count); + atomic_inc(&mm->mm_users); + current->active_mm = mm; + BUG_ON(current->mm); + enter_lazy_tlb(mm, current); - if (IS_ERR(tsk)) - panic("Failed forking idle task for cpu %d\n", cpu); - - task_thread_info(tsk)->cpu = cpu; + per_cpu_trap_init(); + + preempt_disable(); + + local_irq_enable(); + + calibrate_delay(); + + cpu = smp_processor_id(); + smp_store_cpu_info(cpu); cpu_set(cpu, cpu_online_map); - return 0; + cpu_idle(); } -int start_secondary(void *unused) +extern struct { + unsigned long sp; + unsigned long bss_start; + unsigned long bss_end; + void *start_kernel_fn; + void *cpu_init_fn; + void *thread_info; +} stack_start; + +int __cpuinit __cpu_up(unsigned int cpu) { - unsigned int cpu; + struct task_struct *tsk; + unsigned long timeout; - cpu = smp_processor_id(); + tsk = fork_idle(cpu); + if (IS_ERR(tsk)) { + printk(KERN_ERR "Failed forking idle task for cpu %d\n", cpu); + return PTR_ERR(tsk); + } - atomic_inc(&init_mm.mm_count); - current->active_mm = &init_mm; + /* Fill in data in head.S for secondary cpus */ + stack_start.sp = tsk->thread.sp; + stack_start.thread_info = tsk->stack; + stack_start.bss_start = 0; /* don't clear bss for secondary cpus */ + stack_start.start_kernel_fn = start_secondary; - smp_store_cpu_info(cpu); + flush_cache_all(); - __smp_slave_init(cpu); - preempt_disable(); - per_cpu_trap_init(); - - atomic_inc(&cpus_booted); + plat_start_cpu(cpu, (unsigned long)_stext); - cpu_idle(); - return 0; + timeout = jiffies + HZ; + while (time_before(jiffies, timeout)) { + if (cpu_online(cpu)) + break; + + udelay(10); + } + + if (cpu_online(cpu)) + return 0; + + return -ENOENT; } void __init smp_cpus_done(unsigned int max_cpus) { - smp_mb(); + unsigned long bogosum = 0; + int cpu; + + for_each_online_cpu(cpu) + bogosum += cpu_data[cpu].loops_per_jiffy; + + printk(KERN_INFO "SMP: Total of %d processors activated " + "(%lu.%02lu BogoMIPS).\n", num_online_cpus(), + bogosum / (500000/HZ), + (bogosum / (5000/HZ)) % 100); } void smp_send_reschedule(int cpu) { - __smp_send_ipi(cpu, SMP_MSG_RESCHEDULE); + plat_send_ipi(cpu, SMP_MSG_RESCHEDULE); } static void stop_this_cpu(void *unused) @@ -157,7 +178,6 @@ void smp_send_stop(void) smp_call_function(stop_this_cpu, 0, 1, 0); } - struct smp_fn_call_struct smp_fn_call = { .lock = SPIN_LOCK_UNLOCKED, .finished = ATOMIC_INIT(0), @@ -175,9 +195,6 @@ int smp_call_function(void (*func)(void *info), void *info, int retry, int wait) unsigned int nr_cpus = atomic_read(&cpus_booted); int i; - if (nr_cpus < 2) - return 0; - /* Can deadlock when called with interrupts disabled */ WARN_ON(irqs_disabled()); @@ -189,7 +206,7 @@ int smp_call_function(void (*func)(void *info), void *info, int retry, int wait) for (i = 0; i < nr_cpus; i++) if (i != smp_processor_id()) - __smp_call_function(i); + plat_send_ipi(i, SMP_MSG_FUNCTION); if (wait) while (atomic_read(&smp_fn_call.finished) != (nr_cpus - 1)); @@ -205,3 +222,143 @@ int setup_profiling_timer(unsigned int multiplier) return 0; } +static void flush_tlb_all_ipi(void *info) +{ + local_flush_tlb_all(); +} + +void flush_tlb_all(void) +{ + on_each_cpu(flush_tlb_all_ipi, 0, 1, 1); +} + +static void flush_tlb_mm_ipi(void *mm) +{ + local_flush_tlb_mm((struct mm_struct *)mm); +} + +/* + * The following tlb flush calls are invoked when old translations are + * being torn down, or pte attributes are changing. For single threaded + * address spaces, a new context is obtained on the current cpu, and tlb + * context on other cpus are invalidated to force a new context allocation + * at switch_mm time, should the mm ever be used on other cpus. For + * multithreaded address spaces, intercpu interrupts have to be sent. + * Another case where intercpu interrupts are required is when the target + * mm might be active on another cpu (eg debuggers doing the flushes on + * behalf of debugees, kswapd stealing pages from another process etc). + * Kanoj 07/00. + */ + +void flush_tlb_mm(struct mm_struct *mm) +{ + preempt_disable(); + + if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { + smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1); + } else { + int i; + for (i = 0; i < num_online_cpus(); i++) + if (smp_processor_id() != i) + cpu_context(i, mm) = 0; + } + local_flush_tlb_mm(mm); + + preempt_enable(); +} + +struct flush_tlb_data { + struct vm_area_struct *vma; + unsigned long addr1; + unsigned long addr2; +}; + +static void flush_tlb_range_ipi(void *info) +{ + struct flush_tlb_data *fd = (struct flush_tlb_data *)info; + + local_flush_tlb_range(fd->vma, fd->addr1, fd->addr2); +} + +void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + + preempt_disable(); + if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { + struct flush_tlb_data fd; + + fd.vma = vma; + fd.addr1 = start; + fd.addr2 = end; + smp_call_function(flush_tlb_range_ipi, (void *)&fd, 1, 1); + } else { + int i; + for (i = 0; i < num_online_cpus(); i++) + if (smp_processor_id() != i) + cpu_context(i, mm) = 0; + } + local_flush_tlb_range(vma, start, end); + preempt_enable(); +} + +static void flush_tlb_kernel_range_ipi(void *info) +{ + struct flush_tlb_data *fd = (struct flush_tlb_data *)info; + + local_flush_tlb_kernel_range(fd->addr1, fd->addr2); +} + +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + struct flush_tlb_data fd; + + fd.addr1 = start; + fd.addr2 = end; + on_each_cpu(flush_tlb_kernel_range_ipi, (void *)&fd, 1, 1); +} + +static void flush_tlb_page_ipi(void *info) +{ + struct flush_tlb_data *fd = (struct flush_tlb_data *)info; + + local_flush_tlb_page(fd->vma, fd->addr1); +} + +void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + preempt_disable(); + if ((atomic_read(&vma->vm_mm->mm_users) != 1) || + (current->mm != vma->vm_mm)) { + struct flush_tlb_data fd; + + fd.vma = vma; + fd.addr1 = page; + smp_call_function(flush_tlb_page_ipi, (void *)&fd, 1, 1); + } else { + int i; + for (i = 0; i < num_online_cpus(); i++) + if (smp_processor_id() != i) + cpu_context(i, vma->vm_mm) = 0; + } + local_flush_tlb_page(vma, page); + preempt_enable(); +} + +static void flush_tlb_one_ipi(void *info) +{ + struct flush_tlb_data *fd = (struct flush_tlb_data *)info; + local_flush_tlb_one(fd->addr1, fd->addr2); +} + +void flush_tlb_one(unsigned long asid, unsigned long vaddr) +{ + struct flush_tlb_data fd; + + fd.addr1 = asid; + fd.addr2 = vaddr; + + smp_call_function(flush_tlb_one_ipi, (void *)&fd, 1, 1); + local_flush_tlb_one(asid, vaddr); +} diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S index 91fb7024e06f..10bec45415ba 100644 --- a/arch/sh/kernel/syscalls.S +++ b/arch/sh/kernel/syscalls.S @@ -14,24 +14,6 @@ #include <linux/sys.h> #include <linux/linkage.h> -#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE) -#define sys_nfsservctl sys_ni_syscall -#endif - -#if !defined(CONFIG_MMU) -#define sys_madvise sys_ni_syscall -#define sys_readahead sys_ni_syscall -#define sys_mprotect sys_ni_syscall -#define sys_msync sys_ni_syscall -#define sys_mlock sys_ni_syscall -#define sys_munlock sys_ni_syscall -#define sys_mlockall sys_ni_syscall -#define sys_munlockall sys_ni_syscall -#define sys_mremap sys_ni_syscall -#define sys_mincore sys_ni_syscall -#define sys_remap_file_pages sys_ni_syscall -#endif - .data ENTRY(sys_call_table) .long sys_restart_syscall /* 0 - old "setup()" system call*/ diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index 8a545d54e2d3..628ec9a15e38 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c @@ -173,7 +173,8 @@ static int tmu_timer_init(void) tmu_timer_stop(); -#if !defined(CONFIG_CPU_SUBTYPE_SH7760) && \ +#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && \ + !defined(CONFIG_CPU_SUBTYPE_SH7760) && \ !defined(CONFIG_CPU_SUBTYPE_SH7785) && \ !defined(CONFIG_CPU_SUBTYPE_SHX3) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 67015044d74a..dcb46e71da1c 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -807,12 +807,13 @@ static inline void __init gdb_vbr_init(void) } #endif -void __init per_cpu_trap_init(void) +void __cpuinit per_cpu_trap_init(void) { extern void *vbr_base; #ifdef CONFIG_SH_STANDARD_BIOS - gdb_vbr_init(); + if (raw_smp_processor_id() == 0) + gdb_vbr_init(); #endif /* NOTE: The VBR value should be at P1 diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 9cb95af7b090..6d5abba2ee27 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -62,6 +62,8 @@ SECTIONS __nosave_end = .; PERCPU(PAGE_SIZE) + + . = ALIGN(L1_CACHE_BYTES); .data.cacheline_aligned : { *(.data.cacheline_aligned) } _edata = .; /* End of data section */ @@ -89,7 +91,14 @@ SECTIONS __con_initcall_end = .; SECURITY_INIT + /* .exit.text is discarded at runtime, not link time, to deal with + references from .rodata */ + .exit.text : { *(.exit.text) } + .exit.data : { *(.exit.data) } + #ifdef CONFIG_BLK_DEV_INITRD + . = ALIGN(PAGE_SIZE); + __initramfs_start = .; .init.ramfs : { *(.init.ramfs) } __initramfs_end = .; @@ -107,6 +116,7 @@ SECTIONS *(.bss.page_aligned) *(.bss) . = ALIGN(4); + _ebss = .; /* uClinux MTD sucks */ _end = . ; } diff --git a/arch/sh/kernel/vsyscall/vsyscall.lds.S b/arch/sh/kernel/vsyscall/vsyscall.lds.S index b13c3d439fee..c9bf2af35d35 100644 --- a/arch/sh/kernel/vsyscall/vsyscall.lds.S +++ b/arch/sh/kernel/vsyscall/vsyscall.lds.S @@ -17,45 +17,52 @@ ENTRY(__kernel_vsyscall); SECTIONS { - . = SIZEOF_HEADERS; + . = SIZEOF_HEADERS; - .hash : { *(.hash) } :text - .gnu.hash : { *(.gnu.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } + .hash : { *(.hash) } :text + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } - /* This linker script is used both with -r and with -shared. - For the layouts to match, we need to skip more than enough - space for the dynamic symbol table et al. If this amount - is insufficient, ld -shared will barf. Just increase it here. */ - . = 0x400; + /* + * This linker script is used both with -r and with -shared. + * For the layouts to match, we need to skip more than enough + * space for the dynamic symbol table et al. If this amount + * is insufficient, ld -shared will barf. Just increase it here. + */ + . = 0x400; - .text : { *(.text) } :text =0x90909090 - .note : { *(.note.*) } :text :note - .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr - .eh_frame : { KEEP (*(.eh_frame)) } :text - .dynamic : { *(.dynamic) } :text :dynamic - .useless : { - *(.got.plt) *(.got) - *(.data .data.* .gnu.linkonce.d.*) - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - } :text + .text : { *(.text) } :text =0x90909090 + .note : { *(.note.*) } :text :note + .eh_frame_hdr : { *(.eh_frame_hdr ) } :text :eh_frame_hdr + .eh_frame : { KEEP (*(.eh_frame)) } :text + .dynamic : { *(.dynamic) } :text :dynamic + .useless : { + *(.got.plt) *(.got) + *(.data .data.* .gnu.linkonce.d.*) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + } :text } /* + * Very old versions of ld do not recognize this name token; use the constant. + */ +#define PT_GNU_EH_FRAME 0x6474e550 + +/* * We must supply the ELF program headers explicitly to get just one * PT_LOAD segment, and set the flags explicitly to make segments read-only. */ PHDRS { - text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ - dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ - note PT_NOTE FLAGS(4); /* PF_R */ - eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ + text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ + dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ + note PT_NOTE FLAGS(4); /* PF_R */ + eh_frame_hdr PT_GNU_EH_FRAME; } /* @@ -63,12 +70,12 @@ PHDRS */ VERSION { - LINUX_2.6 { - global: - __kernel_vsyscall; - __kernel_sigreturn; - __kernel_rt_sigreturn; + LINUX_2.6 { + global: + __kernel_vsyscall; + __kernel_sigreturn; + __kernel_rt_sigreturn; - local: *; - }; + local: *; + }; } diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 43f3972a5fb9..cf446bbab5b0 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -2,7 +2,6 @@ # Processor families # config CPU_SH2 - select SH_WRITETHROUGH if !CPU_SH2A bool config CPU_SH2A @@ -19,6 +18,7 @@ config CPU_SH4 select CPU_HAS_INTEVT select CPU_HAS_SR_RB select CPU_HAS_PTEA if (!CPU_SUBTYPE_ST40 && !CPU_SH4A) || CPU_SHX2 + select CPU_HAS_FPU if !CPU_SH4AL_DSP config CPU_SH4A bool @@ -32,7 +32,6 @@ config CPU_SH4AL_DSP config CPU_SUBTYPE_ST40 bool select CPU_SH4 - select CPU_HAS_INTC2_IRQ config CPU_SHX2 bool @@ -52,26 +51,22 @@ choice config CPU_SUBTYPE_SH7619 bool "Support SH7619 processor" select CPU_SH2 - select CPU_HAS_IPR_IRQ # SH-2A Processor Support config CPU_SUBTYPE_SH7206 bool "Support SH7206 processor" select CPU_SH2A - select CPU_HAS_IPR_IRQ # SH-3 Processor Support config CPU_SUBTYPE_SH7705 bool "Support SH7705 processor" select CPU_SH3 - select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH7706 bool "Support SH7706 processor" select CPU_SH3 - select CPU_HAS_IPR_IRQ help Select SH7706 if you have a 133 Mhz SH-3 HD6417706 CPU. @@ -91,14 +86,12 @@ config CPU_SUBTYPE_SH7708 config CPU_SUBTYPE_SH7709 bool "Support SH7709 processor" select CPU_SH3 - select CPU_HAS_IPR_IRQ help Select SH7709 if you have a 80 Mhz SH-3 HD6417709 CPU. config CPU_SUBTYPE_SH7710 bool "Support SH7710 processor" select CPU_SH3 - select CPU_HAS_IPR_IRQ select CPU_HAS_DSP help Select SH7710 if you have a SH3-DSP SH7710 CPU. @@ -106,24 +99,28 @@ config CPU_SUBTYPE_SH7710 config CPU_SUBTYPE_SH7712 bool "Support SH7712 processor" select CPU_SH3 - select CPU_HAS_IPR_IRQ select CPU_HAS_DSP help Select SH7712 if you have a SH3-DSP SH7712 CPU. +config CPU_SUBTYPE_SH7720 + bool "Support SH7720 processor" + select CPU_SH3 + select CPU_HAS_DSP + help + Select SH7720 if you have a SH3-DSP SH7720 CPU. + # SH-4 Processor Support config CPU_SUBTYPE_SH7750 bool "Support SH7750 processor" select CPU_SH4 - select CPU_HAS_INTC_IRQ help Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. config CPU_SUBTYPE_SH7091 bool "Support SH7091 processor" select CPU_SH4 - select CPU_HAS_INTC_IRQ help Select SH7091 if you have an SH-4 based Sega device (such as the Dreamcast, Naomi, and Naomi 2). @@ -131,17 +128,14 @@ config CPU_SUBTYPE_SH7091 config CPU_SUBTYPE_SH7750R bool "Support SH7750R processor" select CPU_SH4 - select CPU_HAS_INTC_IRQ config CPU_SUBTYPE_SH7750S bool "Support SH7750S processor" select CPU_SH4 - select CPU_HAS_INTC_IRQ config CPU_SUBTYPE_SH7751 bool "Support SH7751 processor" select CPU_SH4 - select CPU_HAS_INTC_IRQ help Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU, or if you have a HD6417751R CPU. @@ -149,13 +143,10 @@ config CPU_SUBTYPE_SH7751 config CPU_SUBTYPE_SH7751R bool "Support SH7751R processor" select CPU_SH4 - select CPU_HAS_INTC_IRQ config CPU_SUBTYPE_SH7760 bool "Support SH7760 processor" select CPU_SH4 - select CPU_HAS_INTC2_IRQ - select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH4_202 bool "Support SH4-202 processor" @@ -185,19 +176,21 @@ config CPU_SUBTYPE_SH7770 config CPU_SUBTYPE_SH7780 bool "Support SH7780 processor" select CPU_SH4A - select CPU_HAS_INTC_IRQ config CPU_SUBTYPE_SH7785 bool "Support SH7785 processor" select CPU_SH4A select CPU_SHX2 - select CPU_HAS_INTC2_IRQ + select ARCH_SPARSEMEM_ENABLE + select SYS_SUPPORTS_NUMA config CPU_SUBTYPE_SHX3 bool "Support SH-X3 processor" select CPU_SH4A select CPU_SHX3 - select CPU_HAS_INTC2_IRQ + select ARCH_SPARSEMEM_ENABLE + select SYS_SUPPORTS_NUMA + select SYS_SUPPORTS_SMP # SH4AL-DSP Processor Support @@ -209,7 +202,6 @@ config CPU_SUBTYPE_SH7722 bool "Support SH7722 processor" select CPU_SH4AL_DSP select CPU_SHX2 - select CPU_HAS_INTC_IRQ select ARCH_SPARSEMEM_ENABLE select SYS_SUPPORTS_NUMA @@ -274,7 +266,7 @@ config 32BIT config X2TLB bool "Enable extended TLB mode" - depends on CPU_SHX2 && MMU && EXPERIMENTAL + depends on (CPU_SHX2 || CPU_SHX3) && MMU && EXPERIMENTAL help Selecting this option will enable the extended mode of the SH-X2 TLB. For legacy SH-X behaviour and interoperability, say N. For @@ -307,6 +299,7 @@ config NUMA config NODES_SHIFT int + default "3" if CPU_SUBTYPE_SHX3 default "1" depends on NEED_MULTIPLE_NODES @@ -323,7 +316,9 @@ config ARCH_SPARSEMEM_DEFAULT config MAX_ACTIVE_REGIONS int - default "2" if (CPU_SUBTYPE_SH7722 && SPARSEMEM) + default "6" if (CPU_SUBTYPE_SHX3 && SPARSEMEM) + default "2" if SPARSEMEM && (CPU_SUBTYPE_SH7722 || \ + CPU_SUBTYPE_SH7785) default "1" config ARCH_POPULATES_NODE_MAP @@ -342,25 +337,27 @@ config ARCH_MEMORY_PROBE choice prompt "Kernel page size" + default PAGE_SIZE_8KB if X2TLB default PAGE_SIZE_4KB config PAGE_SIZE_4KB bool "4kB" + depends on !X2TLB help This is the default page size used by all SuperH CPUs. config PAGE_SIZE_8KB bool "8kB" - depends on EXPERIMENTAL && X2TLB + depends on X2TLB help This enables 8kB pages as supported by SH-X2 and later MMUs. config PAGE_SIZE_64KB bool "64kB" - depends on EXPERIMENTAL && CPU_SH4 + depends on CPU_SH4 help This enables support for 64kB pages, possible on all SH-4 - CPUs and later. Highly experimental, not recommended. + CPUs and later. endchoice @@ -412,8 +409,17 @@ config SH_DIRECT_MAPPED Turn this option off for platforms that do not have a direct-mapped cache, and you have no need to run the caches in such a configuration. -config SH_WRITETHROUGH - bool "Use write-through caching" +choice + prompt "Cache mode" + default CACHE_WRITEBACK if CPU_SH2A || CPU_SH3 || CPU_SH4 + default CACHE_WRITETHROUGH if (CPU_SH2 && !CPU_SH2A) + +config CACHE_WRITEBACK + bool "Write-back" + depends on CPU_SH2A || CPU_SH3 || CPU_SH4 + +config CACHE_WRITETHROUGH + bool "Write-through" help Selecting this option will configure the caches in write-through mode, as opposed to the default write-back configuration. @@ -424,4 +430,9 @@ config SH_WRITETHROUGH If unsure, say N. +config CACHE_OFF + bool "Off" + +endchoice + endmenu diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 4061e89d84d0..ee30fb44dfe1 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -4,29 +4,32 @@ obj-y := init.o extable.o consistent.o -obj-$(CONFIG_CPU_SH2) += cache-sh2.o -obj-$(CONFIG_CPU_SH3) += cache-sh3.o -obj-$(CONFIG_CPU_SH4) += cache-sh4.o +ifndef CONFIG_CACHE_OFF +obj-$(CONFIG_CPU_SH2) += cache-sh2.o +obj-$(CONFIG_CPU_SH3) += cache-sh3.o +obj-$(CONFIG_CPU_SH4) += cache-sh4.o +obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o +endif mmu-y := tlb-nommu.o pg-nommu.o -mmu-$(CONFIG_CPU_SH3) += fault-nommu.o -mmu-$(CONFIG_CPU_SH4) += fault-nommu.o mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o tlb-flush.o \ ioremap.o obj-y += $(mmu-y) ifdef CONFIG_DEBUG_FS -obj-$(CONFIG_CPU_SH4) += cache-debugfs.o +obj-$(CONFIG_CPU_SH4) += cache-debugfs.o endif ifdef CONFIG_MMU -obj-$(CONFIG_CPU_SH3) += tlb-sh3.o -obj-$(CONFIG_CPU_SH4) += tlb-sh4.o pg-sh4.o -obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o +obj-$(CONFIG_CPU_SH3) += tlb-sh3.o +obj-$(CONFIG_CPU_SH4) += tlb-sh4.o +ifndef CONFIG_CACHE_OFF +obj-$(CONFIG_CPU_SH4) += pg-sh4.o +obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o +endif 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/cache-sh4.c b/arch/sh/mm/cache-sh4.c index 86486326ef1d..226b190c5b9c 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -2,7 +2,7 @@ * arch/sh/mm/cache-sh4.c * * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2001 - 2006 Paul Mundt + * Copyright (C) 2001 - 2007 Paul Mundt * Copyright (C) 2003 Richard Curnow * * This file is subject to the terms and conditions of the GNU General Public @@ -44,7 +44,7 @@ static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) = static void compute_alias(struct cache_info *c) { c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1); - c->n_aliases = (c->alias_mask >> PAGE_SHIFT) + 1; + c->n_aliases = c->alias_mask ? (c->alias_mask >> PAGE_SHIFT) + 1 : 0; } static void __init emit_cache_params(void) @@ -54,21 +54,35 @@ static void __init emit_cache_params(void) ctrl_inl(CCN_CVR), ctrl_inl(CCN_PRR)); printk("I-cache : n_ways=%d n_sets=%d way_incr=%d\n", - current_cpu_data.icache.ways, - current_cpu_data.icache.sets, - current_cpu_data.icache.way_incr); + boot_cpu_data.icache.ways, + boot_cpu_data.icache.sets, + boot_cpu_data.icache.way_incr); printk("I-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n", - current_cpu_data.icache.entry_mask, - current_cpu_data.icache.alias_mask, - current_cpu_data.icache.n_aliases); + boot_cpu_data.icache.entry_mask, + boot_cpu_data.icache.alias_mask, + boot_cpu_data.icache.n_aliases); printk("D-cache : n_ways=%d n_sets=%d way_incr=%d\n", - current_cpu_data.dcache.ways, - current_cpu_data.dcache.sets, - current_cpu_data.dcache.way_incr); + boot_cpu_data.dcache.ways, + boot_cpu_data.dcache.sets, + boot_cpu_data.dcache.way_incr); printk("D-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n", - current_cpu_data.dcache.entry_mask, - current_cpu_data.dcache.alias_mask, - current_cpu_data.dcache.n_aliases); + boot_cpu_data.dcache.entry_mask, + boot_cpu_data.dcache.alias_mask, + boot_cpu_data.dcache.n_aliases); + + /* + * Emit Secondary Cache parameters if the CPU has a probed L2. + */ + if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) { + printk("S-cache : n_ways=%d n_sets=%d way_incr=%d\n", + boot_cpu_data.scache.ways, + boot_cpu_data.scache.sets, + boot_cpu_data.scache.way_incr); + printk("S-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n", + boot_cpu_data.scache.entry_mask, + boot_cpu_data.scache.alias_mask, + boot_cpu_data.scache.n_aliases); + } if (!__flush_dcache_segment_fn) panic("unknown number of cache ways\n"); @@ -79,10 +93,11 @@ static void __init emit_cache_params(void) */ void __init p3_cache_init(void) { - compute_alias(¤t_cpu_data.icache); - compute_alias(¤t_cpu_data.dcache); + compute_alias(&boot_cpu_data.icache); + compute_alias(&boot_cpu_data.dcache); + compute_alias(&boot_cpu_data.scache); - switch (current_cpu_data.dcache.ways) { + switch (boot_cpu_data.dcache.ways) { case 1: __flush_dcache_segment_fn = __flush_dcache_segment_1way; break; @@ -187,13 +202,13 @@ void flush_cache_sigtramp(unsigned long addr) : "m" (__m(v))); index = CACHE_IC_ADDRESS_ARRAY | - (v & current_cpu_data.icache.entry_mask); + (v & boot_cpu_data.icache.entry_mask); local_irq_save(flags); jump_to_P2(); - for (i = 0; i < current_cpu_data.icache.ways; - i++, index += current_cpu_data.icache.way_incr) + for (i = 0; i < boot_cpu_data.icache.ways; + i++, index += boot_cpu_data.icache.way_incr) ctrl_outl(0, index); /* Clear out Valid-bit */ back_to_P1(); @@ -210,7 +225,7 @@ static inline void flush_cache_4096(unsigned long start, * All types of SH-4 require PC to be in P2 to operate on the I-cache. * Some types of SH-4 require PC to be in P2 to operate on the D-cache. */ - if ((current_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) || + if ((boot_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) || (start < CACHE_OC_ADDRESS_ARRAY)) exec_offset = 0x20000000; @@ -232,7 +247,7 @@ void flush_dcache_page(struct page *page) int i, n; /* Loop all the D-cache */ - n = current_cpu_data.dcache.n_aliases; + n = boot_cpu_data.dcache.n_aliases; for (i = 0; i < n; i++, addr += 4096) flush_cache_4096(addr, phys); } @@ -264,7 +279,7 @@ static inline void flush_icache_all(void) void flush_dcache_all(void) { - (*__flush_dcache_segment_fn)(0UL, current_cpu_data.dcache.way_size); + (*__flush_dcache_segment_fn)(0UL, boot_cpu_data.dcache.way_size); wmb(); } @@ -278,8 +293,8 @@ static void __flush_cache_mm(struct mm_struct *mm, unsigned long start, unsigned long end) { unsigned long d = 0, p = start & PAGE_MASK; - unsigned long alias_mask = current_cpu_data.dcache.alias_mask; - unsigned long n_aliases = current_cpu_data.dcache.n_aliases; + unsigned long alias_mask = boot_cpu_data.dcache.alias_mask; + unsigned long n_aliases = boot_cpu_data.dcache.n_aliases; unsigned long select_bit; unsigned long all_aliases_mask; unsigned long addr_offset; @@ -366,7 +381,7 @@ void flush_cache_mm(struct mm_struct *mm) * If cache is only 4k-per-way, there are never any 'aliases'. Since * the cache is physically tagged, the data can just be left in there. */ - if (current_cpu_data.dcache.n_aliases == 0) + if (boot_cpu_data.dcache.n_aliases == 0) return; /* @@ -403,7 +418,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address, unsigned long phys = pfn << PAGE_SHIFT; unsigned int alias_mask; - alias_mask = current_cpu_data.dcache.alias_mask; + alias_mask = boot_cpu_data.dcache.alias_mask; /* We only need to flush D-cache when we have alias */ if ((address^phys) & alias_mask) { @@ -417,7 +432,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address, phys); } - alias_mask = current_cpu_data.icache.alias_mask; + alias_mask = boot_cpu_data.icache.alias_mask; if (vma->vm_flags & VM_EXEC) { /* * Evict entries from the portion of the cache from which code @@ -449,7 +464,7 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, * If cache is only 4k-per-way, there are never any 'aliases'. Since * the cache is physically tagged, the data can just be left in there. */ - if (current_cpu_data.dcache.n_aliases == 0) + if (boot_cpu_data.dcache.n_aliases == 0) return; /* @@ -510,7 +525,7 @@ static void __flush_cache_4096(unsigned long addr, unsigned long phys, unsigned long a, ea, p; unsigned long temp_pc; - dcache = ¤t_cpu_data.dcache; + dcache = &boot_cpu_data.dcache; /* Write this way for better assembly. */ way_count = dcache->ways; way_incr = dcache->way_incr; @@ -585,7 +600,7 @@ static void __flush_dcache_segment_1way(unsigned long start, base_addr = ((base_addr >> 16) << 16); base_addr |= start; - dcache = ¤t_cpu_data.dcache; + dcache = &boot_cpu_data.dcache; linesz = dcache->linesz; way_incr = dcache->way_incr; way_size = dcache->way_size; @@ -627,7 +642,7 @@ static void __flush_dcache_segment_2way(unsigned long start, base_addr = ((base_addr >> 16) << 16); base_addr |= start; - dcache = ¤t_cpu_data.dcache; + dcache = &boot_cpu_data.dcache; linesz = dcache->linesz; way_incr = dcache->way_incr; way_size = dcache->way_size; @@ -686,7 +701,7 @@ static void __flush_dcache_segment_4way(unsigned long start, base_addr = ((base_addr >> 16) << 16); base_addr |= start; - dcache = ¤t_cpu_data.dcache; + dcache = &boot_cpu_data.dcache; linesz = dcache->linesz; way_incr = dcache->way_incr; way_size = dcache->way_size; diff --git a/arch/sh/mm/copy_page.S b/arch/sh/mm/copy_page.S index ae039f2da162..a81dbdb05596 100644 --- a/arch/sh/mm/copy_page.S +++ b/arch/sh/mm/copy_page.S @@ -141,47 +141,38 @@ ENTRY(__copy_user_page) .long 9999b, 6000f ; \ .previous ENTRY(__copy_user) - tst r6,r6 ! Check explicitly for zero - bf 1f - rts - mov #0,r0 ! normal return -1: - mov.l r10,@-r15 - mov.l r9,@-r15 - mov.l r8,@-r15 + ! Check if small number of bytes + mov #11,r0 mov r4,r3 - add r6,r3 ! last destination address - mov #12,r0 ! Check if small number of bytes - cmp/gt r0,r6 - bt 2f - bra .L_cleanup_loop - nop -2: - neg r5,r0 ! Calculate bytes needed to align source + cmp/gt r0,r6 ! r6 (len) > r0 (11) + bf/s .L_cleanup_loop_no_pop + add r6,r3 ! last destination address + + ! Calculate bytes needed to align to src + mov.l r11,@-r15 + neg r5,r0 + mov.l r10,@-r15 add #4,r0 + mov.l r9,@-r15 and #3,r0 + mov.l r8,@-r15 tst r0,r0 - bt .L_jump - mov r0,r1 + bt 2f -.L_loop1: - ! Copy bytes to align source -EX( mov.b @r5+,r0 ) - dt r1 -EX( mov.b r0,@r4 ) +1: + ! Copy bytes to long word align src +EX( mov.b @r5+,r1 ) + dt r0 add #-1,r6 - bf/s .L_loop1 +EX( mov.b r1,@r4 ) + bf/s 1b add #1,r4 -.L_jump: - mov r6,r2 ! Calculate number of longwords to copy + ! Jump to appropriate routine depending on dest +2: mov #3,r1 + mov r6, r2 + and r4,r1 shlr2 r2 - tst r2,r2 - bt .L_cleanup - - mov r4,r0 ! Jump to appropriate routine - and #3,r0 - mov r0,r1 shll2 r1 mova .L_jump_tbl,r0 mov.l @(r0,r1),r1 @@ -195,43 +186,97 @@ EX( mov.b r0,@r4 ) .long .L_dest10 .long .L_dest11 +/* + * Come here if there are less than 12 bytes to copy + * + * Keep the branch target close, so the bf/s callee doesn't overflow + * and result in a more expensive branch being inserted. This is the + * fast-path for small copies, the jump via the jump table will hit the + * default slow-path cleanup. -PFM. + */ +.L_cleanup_loop_no_pop: + tst r6,r6 ! Check explicitly for zero + bt 1f + +2: +EX( mov.b @r5+,r0 ) + dt r6 +EX( mov.b r0,@r4 ) + bf/s 2b + add #1,r4 + +1: mov #0,r0 ! normal return +5000: + +# Exception handler: +.section .fixup, "ax" +6000: + mov.l 8000f,r1 + mov r3,r0 + jmp @r1 + sub r4,r0 + .align 2 +8000: .long 5000b + +.previous + rts + nop + ! Destination = 00 .L_dest00: - mov r2,r7 - shlr2 r7 - shlr r7 - tst r7,r7 - mov #7,r0 - bt/s 1f - and r0,r2 - .align 2 + ! Skip the large copy for small transfers + mov #(32+32-4), r0 + cmp/gt r6, r0 ! r0 (60) > r6 (len) + bt 1f + + ! Align dest to a 32 byte boundary + neg r4,r0 + add #0x20, r0 + and #0x1f, r0 + tst r0, r0 + bt 2f + + sub r0, r6 + shlr2 r0 +3: +EX( mov.l @r5+,r1 ) + dt r0 +EX( mov.l r1,@r4 ) + bf/s 3b + add #4,r4 + 2: EX( mov.l @r5+,r0 ) +EX( mov.l @r5+,r1 ) +EX( mov.l @r5+,r2 ) +EX( mov.l @r5+,r7 ) EX( mov.l @r5+,r8 ) EX( mov.l @r5+,r9 ) EX( mov.l @r5+,r10 ) -EX( mov.l r0,@r4 ) -EX( mov.l r8,@(4,r4) ) -EX( mov.l r9,@(8,r4) ) -EX( mov.l r10,@(12,r4) ) -EX( mov.l @r5+,r0 ) -EX( mov.l @r5+,r8 ) -EX( mov.l @r5+,r9 ) -EX( mov.l @r5+,r10 ) - dt r7 -EX( mov.l r0,@(16,r4) ) -EX( mov.l r8,@(20,r4) ) -EX( mov.l r9,@(24,r4) ) -EX( mov.l r10,@(28,r4) ) +EX( mov.l @r5+,r11 ) +EX( movca.l r0,@r4 ) + add #-32, r6 +EX( mov.l r1,@(4,r4) ) + mov #32, r0 +EX( mov.l r2,@(8,r4) ) + cmp/gt r6, r0 ! r0 (32) > r6 (len) +EX( mov.l r7,@(12,r4) ) +EX( mov.l r8,@(16,r4) ) +EX( mov.l r9,@(20,r4) ) +EX( mov.l r10,@(24,r4) ) +EX( mov.l r11,@(28,r4) ) bf/s 2b add #32,r4 - tst r2,r2 + +1: mov r6, r0 + shlr2 r0 + tst r0, r0 bt .L_cleanup 1: -EX( mov.l @r5+,r0 ) - dt r2 -EX( mov.l r0,@r4 ) +EX( mov.l @r5+,r1 ) + dt r0 +EX( mov.l r1,@r4 ) bf/s 1b add #4,r4 @@ -250,7 +295,7 @@ EX( mov.l r0,@r4 ) and r0,r2 2: dt r7 -#ifdef __LITTLE_ENDIAN__ +#ifdef CONFIG_CPU_LITTLE_ENDIAN EX( mov.l @r5+,r0 ) EX( mov.l @r5+,r1 ) EX( mov.l @r5+,r8 ) @@ -320,7 +365,7 @@ EX( mov.w r0,@(2,r4) ) 1: ! Read longword, write two words per iteration EX( mov.l @r5+,r0 ) dt r2 -#ifdef __LITTLE_ENDIAN__ +#ifdef CONFIG_CPU_LITTLE_ENDIAN EX( mov.w r0,@r4 ) shlr16 r0 EX( mov.w r0,@(2,r4) ) @@ -342,7 +387,7 @@ EX( mov.w r0,@r4 ) ! Read longword, write byte, word, byte per iteration EX( mov.l @r5+,r0 ) dt r2 -#ifdef __LITTLE_ENDIAN__ +#ifdef CONFIG_CPU_LITTLE_ENDIAN EX( mov.b r0,@r4 ) shlr8 r0 add #1,r4 @@ -379,6 +424,7 @@ EX( mov.b r0,@r4 ) .L_exit: mov #0,r0 ! normal return + 5000: # Exception handler: @@ -394,5 +440,6 @@ EX( mov.b r0,@r4 ) .previous mov.l @r15+,r8 mov.l @r15+,r9 + mov.l @r15+,r10 rts - mov.l @r15+,r10 + mov.l @r15+,r11 diff --git a/arch/sh/mm/fault-nommu.c b/arch/sh/mm/fault-nommu.c deleted file mode 100644 index c6f5b51ec2c7..000000000000 --- a/arch/sh/mm/fault-nommu.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * arch/sh/mm/fault-nommu.c - * - * Copyright (C) 2002 - 2007 Paul Mundt - * - * Based on linux/arch/sh/mm/fault.c: - * Copyright (C) 1999 Niibe Yutaka - * - * Released under the terms of the GNU GPL v2.0. - */ -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/hardirq.h> -#include <linux/kprobes.h> -#include <asm/system.h> -#include <asm/ptrace.h> -#include <asm/kgdb.h> - -/* - * This routine handles page faults. It determines the address, - * and the problem, and then passes it off to one of the appropriate - * routines. - */ -asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, - unsigned long writeaccess, - unsigned long address) -{ - trace_hardirqs_on(); - local_irq_enable(); - -#if defined(CONFIG_SH_KGDB) - if (kgdb_nofault && kgdb_bus_err_hook) - kgdb_bus_err_hook(); -#endif - - /* - * Oops. The kernel tried to access some bad page. We'll have to - * 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); - - die("Oops", regs, writeaccess); - do_exit(SIGKILL); -} - -asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, - unsigned long writeaccess, - unsigned long address) -{ -#if defined(CONFIG_SH_KGDB) - if (kgdb_nofault && kgdb_bus_err_hook) - kgdb_bus_err_hook(); -#endif - - return (address >= TASK_SIZE); -} diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 04a39aa7f1f9..4729668ce5bf 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -214,7 +214,7 @@ out_of_memory: } printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 82b68c789a5f..d5e160da64b2 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -294,12 +294,6 @@ int arch_add_memory(int nid, u64 start, u64 size) } 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) { diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index a08a4a958add..7d43758dc244 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -145,7 +145,7 @@ repeat: ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos)); -#ifdef CONFIG_SH_WRITETHROUGH +#ifdef CONFIG_CACHE_WRITETHROUGH /* * When we are in 32-bit address extended mode, CCR.CB becomes * invalid, so care must be taken to manually adjust cacheable diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c index f74cf667c8fa..2d1dd6044307 100644 --- a/arch/sh/mm/tlb-sh4.c +++ b/arch/sh/mm/tlb-sh4.c @@ -4,27 +4,14 @@ * SH-4 specific TLB operations * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002 Paul Mundt + * Copyright (C) 2002 - 2007 Paul Mundt * * Released under the terms of the GNU GPL v2.0. */ -#include <linux/signal.h> -#include <linux/sched.h> #include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/types.h> -#include <linux/ptrace.h> -#include <linux/mman.h> #include <linux/mm.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> -#include <linux/interrupt.h> - +#include <linux/io.h> #include <asm/system.h> -#include <asm/io.h> -#include <asm/uaccess.h> -#include <asm/pgalloc.h> #include <asm/mmu_context.h> #include <asm/cacheflush.h> @@ -34,22 +21,27 @@ void update_mmu_cache(struct vm_area_struct * vma, unsigned long flags; unsigned long pteval; unsigned long vpn; - struct page *page; - unsigned long pfn; /* Ptrace may call this routine. */ if (vma && current->active_mm != vma->vm_mm) return; - pfn = pte_pfn(pte); - if (pfn_valid(pfn)) { - page = pfn_to_page(pfn); - if (!test_bit(PG_mapped, &page->flags)) { - unsigned long phys = pte_val(pte) & PTE_PHYS_MASK; - __flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE); - __set_bit(PG_mapped, &page->flags); +#ifndef CONFIG_CACHE_OFF + { + unsigned long pfn = pte_pfn(pte); + + if (pfn_valid(pfn)) { + struct page *page = pfn_to_page(pfn); + + if (!test_bit(PG_mapped, &page->flags)) { + unsigned long phys = pte_val(pte) & PTE_PHYS_MASK; + __flush_wback_region((void *)P1SEGADDR(phys), + PAGE_SIZE); + __set_bit(PG_mapped, &page->flags); + } } } +#endif local_irq_save(flags); @@ -57,16 +49,26 @@ void update_mmu_cache(struct vm_area_struct * vma, vpn = (address & MMU_VPN_MASK) | get_asid(); ctrl_outl(vpn, MMU_PTEH); - pteval = pte_val(pte); + pteval = pte.pte_low; /* Set PTEA register */ +#ifdef CONFIG_X2TLB + /* + * For the extended mode TLB this is trivial, only the ESZ and + * EPR bits need to be written out to PTEA, with the remainder of + * the protection bits (with the exception of the compat-mode SZ + * and PR bits, which are cleared) being written out in PTEL. + */ + ctrl_outl(pte.pte_high, MMU_PTEA); +#else if (cpu_data->flags & CPU_HAS_PTEA) /* TODO: make this look less hacky */ ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA); +#endif /* Set PTEL register */ pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */ -#ifdef CONFIG_SH_WRITETHROUGH +#ifdef CONFIG_CACHE_WRITETHROUGH pteval |= _PAGE_WT; #endif /* conveniently, we want all the software flags to be 0 anyway */ @@ -93,4 +95,3 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page) ctrl_outl(data, addr); back_to_P1(); } - diff --git a/arch/sh64/Kconfig b/arch/sh64/Kconfig index 5664631d8ae5..b3327ce8e82f 100644 --- a/arch/sh64/Kconfig +++ b/arch/sh64/Kconfig @@ -36,6 +36,14 @@ config GENERIC_CALIBRATE_DELAY bool default y +config GENERIC_HARDIRQS + bool + default y + +config GENERIC_IRQ_PROBE + bool + default y + config RWSEM_XCHGADD_ALGORITHM bool @@ -58,18 +66,12 @@ choice prompt "SuperH system type" default SH_SIMULATOR -config SH_GENERIC - bool "Generic" - config SH_SIMULATOR bool "Simulator" config SH_CAYMAN bool "Cayman" -config SH_ROMRAM - bool "ROM/RAM" - config SH_HARP bool "ST50-Harp" @@ -152,60 +154,54 @@ comment "Memory options" config CACHED_MEMORY_OFFSET hex "Cached Area Offset" - depends on SH_HARP || SH_CAYMAN || SH_SIMULATOR default "20000000" config MEMORY_START hex "Physical memory start address" - depends on SH_HARP || SH_CAYMAN || SH_SIMULATOR default "80000000" config MEMORY_SIZE_IN_MB - int "Memory size (in MB)" if SH_HARP || SH_CAYMAN || SH_SIMULATOR - default "64" if SH_HARP || SH_CAYMAN + int "Memory size (in MB)" default "8" if SH_SIMULATOR + default "64" comment "Cache options" -config DCACHE_DISABLED - bool "DCache Disabling" - depends on SH_HARP || SH_CAYMAN || SH_SIMULATOR - choice prompt "DCache mode" - depends on !DCACHE_DISABLED && !SH_SIMULATOR + default DCACHE_DISABLED if SH_SIMULATOR default DCACHE_WRITE_BACK config DCACHE_WRITE_BACK bool "Write-back" + depends on !SH_SIMULATOR config DCACHE_WRITE_THROUGH bool "Write-through" + depends on !SH_SIMULATOR + +config DCACHE_DISABLED + bool "Disabled" endchoice config ICACHE_DISABLED bool "ICache Disabling" - depends on SH_HARP || SH_CAYMAN || SH_SIMULATOR config PCIDEVICE_MEMORY_START hex - depends on SH_HARP || SH_CAYMAN || SH_SIMULATOR default "C0000000" config DEVICE_MEMORY_START hex - depends on SH_HARP || SH_CAYMAN || SH_SIMULATOR default "E0000000" config FLASH_MEMORY_START hex "Flash memory/on-chip devices start address" - depends on SH_HARP || SH_CAYMAN || SH_SIMULATOR default "00000000" config PCI_BLOCK_START hex "PCI block start address" - depends on SH_HARP || SH_CAYMAN || SH_SIMULATOR default "40000000" comment "CPU Subtype specific options" @@ -214,8 +210,10 @@ config SH64_ID2815_WORKAROUND bool "Include workaround for SH5-101 cut2 silicon defect ID2815" comment "Misc options" + config HEARTBEAT bool "Heartbeat LED" + depends on SH_CAYMAN config HDSP253_LED bool "Support for HDSP-253 LED" @@ -242,6 +240,7 @@ config SBUS config PCI bool "PCI support" + depends on SH_CAYMAN 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 @@ -294,15 +293,3 @@ source "security/Kconfig" source "crypto/Kconfig" source "lib/Kconfig" - -# -# Use the generic interrupt handling code in kernel/irq/: -# -config GENERIC_HARDIRQS - bool - default y - -config GENERIC_IRQ_PROBE - bool - default y - diff --git a/arch/sh64/Kconfig.debug b/arch/sh64/Kconfig.debug index 26d842c07139..05c07c4e4ed6 100644 --- a/arch/sh64/Kconfig.debug +++ b/arch/sh64/Kconfig.debug @@ -5,9 +5,6 @@ source "lib/Kconfig.debug" config EARLY_PRINTK bool "Early SCIF console support" -config DEBUG_KERNEL_WITH_GDB_STUB - bool "GDB Stub kernel debug" - config SH64_PROC_TLB bool "Debug: report TLB fill/purge activity through /proc/tlb" depends on PROC_FS @@ -28,17 +25,9 @@ config POOR_MANS_STRACE config SH_ALPHANUMERIC bool "Enable debug outputs to on-board alphanumeric display" + depends on SH_CAYMAN config SH_NO_BSS_INIT bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)" -config FRAME_POINTER - bool "Compile the kernel with frame pointers" - default y if KGDB - help - If you say Y here the resulting kernel image will be slightly larger - and slower, but it will give very useful debugging information. - If you don't debug the kernel, you can say N, but we may not be able - to solve problems without frame pointers. - endmenu diff --git a/arch/sh64/Makefile b/arch/sh64/Makefile index 9e874de0a096..8dac7e1a2be6 100644 --- a/arch/sh64/Makefile +++ b/arch/sh64/Makefile @@ -40,6 +40,8 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -R .stab -R .stabstr -S # KBUILD_DEFCONFIG := cayman_defconfig +KBUILD_IMAGE := arch/$(ARCH)/boot/zImage + ifdef LOADADDR LINKFLAGS += -Ttext $(word 1,$(LOADADDR)) endif @@ -47,7 +49,6 @@ endif machine-$(CONFIG_SH_CAYMAN) := cayman machine-$(CONFIG_SH_SIMULATOR) := sim machine-$(CONFIG_SH_HARP) := harp -machine-$(CONFIG_SH_ROMRAM) := romram head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o @@ -106,6 +107,5 @@ arch/$(ARCH)/lib/syscalltab.h: arch/sh64/kernel/syscalls.S CLEAN_FILES += arch/$(ARCH)/lib/syscalltab.h define archhelp - @echo ' zImage - Compressed kernel image (arch/sh64/boot/zImage)' + @echo '* zImage - Compressed kernel image' endef - diff --git a/arch/sh64/configs/cayman_defconfig b/arch/sh64/configs/cayman_defconfig index 784434143343..91b59118c1b1 100644 --- a/arch/sh64/configs/cayman_defconfig +++ b/arch/sh64/configs/cayman_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22 -# Fri Jul 20 12:28:34 2007 +# Linux kernel version: 2.6.23-rc8 +# Tue Oct 9 15:37:16 2007 # CONFIG_SUPERH=y CONFIG_SUPERH64=y @@ -11,21 +11,20 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # 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 @@ -57,7 +56,6 @@ 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 @@ -67,7 +65,12 @@ CONFIG_SLAB=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_MODULES is not set +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 CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set @@ -90,10 +93,8 @@ CONFIG_DEFAULT_IOSCHED="cfq" # # System type # -# CONFIG_SH_GENERIC is not set # CONFIG_SH_SIMULATOR is not set CONFIG_SH_CAYMAN=y -# CONFIG_SH_ROMRAM is not set # CONFIG_SH_HARP is not set CONFIG_CPU_SH5=y CONFIG_CPU_SUBTYPE_SH5_101=y @@ -119,9 +120,9 @@ CONFIG_MEMORY_SIZE_IN_MB=128 # # Cache options # -# CONFIG_DCACHE_DISABLED is not set CONFIG_DCACHE_WRITE_BACK=y # CONFIG_DCACHE_WRITE_THROUGH is not set +# CONFIG_DCACHE_DISABLED is not set # CONFIG_ICACHE_DISABLED is not set CONFIG_PCIDEVICE_MEMORY_START=C0000000 CONFIG_DEVICE_MEMORY_START=E0000000 @@ -151,7 +152,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=1 -CONFIG_VIRT_TO_BUS=y # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -276,7 +276,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_MTD is not set # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y -# 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 @@ -325,6 +324,7 @@ CONFIG_SCSI_MULTI_LUN=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 @@ -332,12 +332,8 @@ CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_SPI_ATTRS=y # 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_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set @@ -347,7 +343,6 @@ CONFIG_SCSI_SPI_ATTRS=y # 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 @@ -449,6 +444,7 @@ CONFIG_NETDEV_1000=y # 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 @@ -572,7 +568,6 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -# CONFIG_SH_WDT is not set # # PCI-based Watchdog Cards @@ -586,7 +581,59 @@ CONFIG_HW_RANDOM=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set CONFIG_DEVPORT=y -# CONFIG_I2C is not set +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set # # SPI support @@ -599,16 +646,51 @@ CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set @@ -621,8 +703,115 @@ CONFIG_HWMON=y # # Multimedia devices # -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_V4L1 is not set +# CONFIG_VIDEO_V4L1_COMPAT is not set +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_TEA5761 is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_CAFE_CCIC is not set +# CONFIG_RADIO_ADAPTERS is not set +CONFIG_DVB_CORE=y +# CONFIG_DVB_CORE_ATTACH is not set +CONFIG_DVB_CAPTURE_DRIVERS=y + +# +# Supported SAA7146 based PCI Adapters +# + +# +# Supported FlexCopII (B2C2) Adapters +# +# CONFIG_DVB_B2C2_FLEXCOP is not set + +# +# Supported BT878 Adapters +# + +# +# Supported Pluto2 Adapters +# +# CONFIG_DVB_PLUTO2 is not set + +# +# Supported DVB Frontends +# + +# +# Customise DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set + +# +# DVB-S (satellite) frontends +# +# CONFIG_DVB_STV0299 is not set +# CONFIG_DVB_CX24110 is not set +# CONFIG_DVB_CX24123 is not set +# CONFIG_DVB_TDA8083 is not set +# CONFIG_DVB_MT312 is not set +# CONFIG_DVB_VES1X93 is not set +# CONFIG_DVB_S5H1420 is not set +# CONFIG_DVB_TDA10086 is not set + +# +# DVB-T (terrestrial) frontends +# +# CONFIG_DVB_SP8870 is not set +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_CX22700 is not set +# CONFIG_DVB_CX22702 is not set +# CONFIG_DVB_L64781 is not set +# CONFIG_DVB_TDA1004X is not set +# CONFIG_DVB_NXT6000 is not set +# CONFIG_DVB_MT352 is not set +# CONFIG_DVB_ZL10353 is not set +# CONFIG_DVB_DIB3000MB is not set +# CONFIG_DVB_DIB3000MC is not set +# CONFIG_DVB_DIB7000M is not set +# CONFIG_DVB_DIB7000P is not set + +# +# DVB-C (cable) frontends +# +# CONFIG_DVB_VES1820 is not set +# CONFIG_DVB_TDA10021 is not set +# CONFIG_DVB_TDA10023 is not set +# CONFIG_DVB_STV0297 is not set + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +# CONFIG_DVB_NXT200X is not set +# CONFIG_DVB_OR51211 is not set +# CONFIG_DVB_OR51132 is not set +# CONFIG_DVB_BCM3510 is not set +# CONFIG_DVB_LGDT330X is not set + +# +# Tuners/PLL support +# +# CONFIG_DVB_PLL is not set +# CONFIG_DVB_TDA826X is not set +# CONFIG_DVB_TDA827X is not set +# CONFIG_DVB_TUNER_QT1010 is not set +# CONFIG_DVB_TUNER_MT2060 is not set + +# +# Miscellaneous devices +# +# CONFIG_DVB_LNBP21 is not set +# CONFIG_DVB_ISL6421 is not set +# CONFIG_DVB_TUA6100 is not set CONFIG_DAB=y # @@ -635,6 +824,7 @@ CONFIG_DAB=y # # CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y # CONFIG_FB_DDC is not set @@ -728,24 +918,8 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set - -# -# LED devices -# # CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# # CONFIG_INFINIBAND is not set - -# -# Real Time Clock -# # CONFIG_RTC_CLASS is not set # @@ -929,9 +1103,9 @@ CONFIG_DEBUG_BUGVERBOSE=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_EARLY_PRINTK is not set -# CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set CONFIG_SH64_PROC_TLB=y CONFIG_SH64_PROC_ASIDS=y CONFIG_SH64_SR_WATCH=y @@ -960,5 +1134,3 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/sh64/configs/harp_defconfig b/arch/sh64/configs/harp_defconfig new file mode 100644 index 000000000000..e4b84b51baf8 --- /dev/null +++ b/arch/sh64/configs/harp_defconfig @@ -0,0 +1,756 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.23-rc8 +# Mon Oct 1 18:01:38 2007 +# +CONFIG_SUPERH=y +CONFIG_SUPERH64=y +CONFIG_MMU=y +CONFIG_QUICKLIST=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_NO_VIRT_TO_BUS=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +# CONFIG_SYSVIPC is not set +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_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_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +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=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=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 +# CONFIG_MODULES is not set +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# +# System type +# +# CONFIG_SH_SIMULATOR is not set +# CONFIG_SH_CAYMAN is not set +CONFIG_SH_HARP=y +CONFIG_CPU_SH5=y +CONFIG_CPU_SUBTYPE_SH5_101=y +# CONFIG_CPU_SUBTYPE_SH5_103 is not set +CONFIG_LITTLE_ENDIAN=y +# CONFIG_BIG_ENDIAN is not set +CONFIG_SH_FPU=y +# CONFIG_SH64_FPU_DENORM_FLUSH is not set +CONFIG_SH64_PGTABLE_2_LEVEL=y +# CONFIG_SH64_PGTABLE_3_LEVEL is not set +CONFIG_HUGETLB_PAGE_SIZE_64K=y +# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set +CONFIG_SH64_USER_MISALIGNED_FIXUP=y + +# +# Memory options +# +CONFIG_CACHED_MEMORY_OFFSET=0x20000000 +CONFIG_MEMORY_START=0x80000000 +CONFIG_MEMORY_SIZE_IN_MB=128 + +# +# Cache options +# +CONFIG_DCACHE_WRITE_BACK=y +# CONFIG_DCACHE_WRITE_THROUGH is not set +# CONFIG_DCACHE_DISABLED is not set +# CONFIG_ICACHE_DISABLED is not set +CONFIG_PCIDEVICE_MEMORY_START=C0000000 +CONFIG_DEVICE_MEMORY_START=E0000000 +CONFIG_FLASH_MEMORY_START=0x00000000 +CONFIG_PCI_BLOCK_START=0x40000000 + +# +# CPU Subtype specific options +# +CONFIG_SH64_ID2815_WORKAROUND=y + +# +# Misc options +# +# CONFIG_SH_DMA is not set +CONFIG_PREEMPT=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=1 + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +# 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=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 is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# 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 is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_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 +# CONFIG_NET_9P 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 +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=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=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_STNIC is not set +# CONFIG_SMC91X is not set +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y + +# +# 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 +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=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 is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING 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 +# CONFIG_IPMI_HANDLER is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_PC87360 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_SENSORS_W83627EHF 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_VIDEO_OUTPUT_CONTROL=y +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# 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 +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +# CONFIG_LOGO_SUPERH_MONO is not set +# CONFIG_LOGO_SUPERH_VGA16 is not set +CONFIG_LOGO_SUPERH_CLUT224=y + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# 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 +# CONFIG_NEW_LEDS is not set +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# 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_OCFS2_FS is not set +CONFIG_MINIX_FS=y +CONFIG_ROMFS_FS=y +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 + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# 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 + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=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_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES 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 is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y +# CONFIG_FAULT_INJECTION is not set +# CONFIG_EARLY_PRINTK is not set +# CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set +CONFIG_SH64_PROC_TLB=y +CONFIG_SH64_PROC_ASIDS=y +CONFIG_SH64_SR_WATCH=y +# CONFIG_POOR_MANS_STRACE is not set +# CONFIG_SH_ALPHANUMERIC is not set +# CONFIG_SH_NO_BSS_INIT is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# 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_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/sh64/configs/sim_defconfig b/arch/sh64/configs/sim_defconfig new file mode 100644 index 000000000000..f83bae659dc3 --- /dev/null +++ b/arch/sh64/configs/sim_defconfig @@ -0,0 +1,566 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.23-rc8 +# Mon Oct 1 17:50:35 2007 +# +CONFIG_SUPERH=y +CONFIG_SUPERH64=y +CONFIG_MMU=y +CONFIG_QUICKLIST=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_NO_VIRT_TO_BUS=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +# CONFIG_SYSVIPC is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_USER_NS is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +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=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=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 +# CONFIG_MODULES is not set +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# +# System type +# +CONFIG_SH_SIMULATOR=y +# CONFIG_SH_CAYMAN is not set +# CONFIG_SH_HARP is not set +CONFIG_CPU_SH5=y +CONFIG_CPU_SUBTYPE_SH5_101=y +# CONFIG_CPU_SUBTYPE_SH5_103 is not set +CONFIG_LITTLE_ENDIAN=y +# CONFIG_BIG_ENDIAN is not set +CONFIG_SH_FPU=y +# CONFIG_SH64_FPU_DENORM_FLUSH is not set +CONFIG_SH64_PGTABLE_2_LEVEL=y +# CONFIG_SH64_PGTABLE_3_LEVEL is not set +CONFIG_HUGETLB_PAGE_SIZE_64K=y +# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set +CONFIG_SH64_USER_MISALIGNED_FIXUP=y + +# +# Memory options +# +CONFIG_CACHED_MEMORY_OFFSET=0x20000000 +CONFIG_MEMORY_START=0x80000000 +CONFIG_MEMORY_SIZE_IN_MB=128 + +# +# Cache options +# +# CONFIG_DCACHE_WRITE_BACK is not set +# CONFIG_DCACHE_WRITE_THROUGH is not set +CONFIG_DCACHE_DISABLED=y +# CONFIG_ICACHE_DISABLED is not set +CONFIG_PCIDEVICE_MEMORY_START=C0000000 +CONFIG_DEVICE_MEMORY_START=E0000000 +CONFIG_FLASH_MEMORY_START=0x00000000 +CONFIG_PCI_BLOCK_START=0x40000000 + +# +# CPU Subtype specific options +# +CONFIG_SH64_ID2815_WORKAROUND=y + +# +# Misc options +# +# CONFIG_SH_DMA is not set +CONFIG_PREEMPT=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=1 + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +# 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 +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +# CONFIG_BLK_DEV is not set +# CONFIG_MISC_DEVICES is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=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=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=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 is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING 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 is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY 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=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_VIDEO_OUTPUT_CONTROL=y +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# 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 +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +# CONFIG_LOGO_SUPERH_MONO is not set +# CONFIG_LOGO_SUPERH_VGA16 is not set +CONFIG_LOGO_SUPERH_CLUT224=y + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# 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=y +CONFIG_ROMFS_FS=y +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=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +CONFIG_PROFILING=y +# CONFIG_OPROFILE is not set + +# +# Kernel hacking +# +# 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_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES 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 is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y +# CONFIG_FAULT_INJECTION is not set +# CONFIG_EARLY_PRINTK is not set +# CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set +CONFIG_SH64_PROC_TLB=y +CONFIG_SH64_PROC_ASIDS=y +CONFIG_SH64_SR_WATCH=y +# CONFIG_POOR_MANS_STRACE is not set +# CONFIG_SH_ALPHANUMERIC is not set +CONFIG_SH_NO_BSS_INIT=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# 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_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/sh64/kernel/Makefile b/arch/sh64/kernel/Makefile index 5816657c079c..e3467bda6167 100644 --- a/arch/sh64/kernel/Makefile +++ b/arch/sh64/kernel/Makefile @@ -25,7 +25,7 @@ obj-$(CONFIG_SH_DMA) += dma.o obj-$(CONFIG_SH_FPU) += fpu.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_KALLSYMS) += unwind.o -obj-$(CONFIG_PCI) += pci-dma.o pcibios.o +obj-$(CONFIG_PCI) += pcibios.o obj-$(CONFIG_MODULES) += module.o ifeq ($(CONFIG_PCI),y) diff --git a/arch/sh64/kernel/alphanum.c b/arch/sh64/kernel/alphanum.c index 91707c1acd70..d1619d95fbaa 100644 --- a/arch/sh64/kernel/alphanum.c +++ b/arch/sh64/kernel/alphanum.c @@ -13,7 +13,6 @@ #include <linux/sched.h> void mach_alphanum(int pos, unsigned char val); -void mach_led(int pos, int val); void print_seg(char *file, int line) { diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c index df06c6477468..8a2d339cf760 100644 --- a/arch/sh64/kernel/ptrace.c +++ b/arch/sh64/kernel/ptrace.c @@ -244,10 +244,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; } - case PTRACE_DETACH: /* detach a process that was attached. */ - ret = ptrace_detach(child, data); - break; - default: ret = ptrace_request(child, request, addr, data); break; diff --git a/arch/sh64/kernel/sh_ksyms.c b/arch/sh64/kernel/sh_ksyms.c index 461ea3de316f..b1705acc8e64 100644 --- a/arch/sh64/kernel/sh_ksyms.c +++ b/arch/sh64/kernel/sh_ksyms.c @@ -31,16 +31,11 @@ extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); /* platform dependent support */ EXPORT_SYMBOL(dump_fpu); -EXPORT_SYMBOL(iounmap); -EXPORT_SYMBOL(enable_irq); -EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(kernel_thread); /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy_nocheck); -EXPORT_SYMBOL(strstr); - #ifdef CONFIG_VT EXPORT_SYMBOL(screen_info); #endif @@ -50,27 +45,18 @@ EXPORT_SYMBOL(__down_trylock); EXPORT_SYMBOL(__up); EXPORT_SYMBOL(__put_user_asm_l); EXPORT_SYMBOL(__get_user_asm_l); -EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(__copy_user); EXPORT_SYMBOL(memcpy); -EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(memscan); -EXPORT_SYMBOL(strchr); -EXPORT_SYMBOL(strlen); - +EXPORT_SYMBOL(udelay); +EXPORT_SYMBOL(__udelay); +EXPORT_SYMBOL(ndelay); +EXPORT_SYMBOL(__ndelay); EXPORT_SYMBOL(flush_dcache_page); - -/* For ext3 */ EXPORT_SYMBOL(sh64_page_clear); /* Ugh. These come in from libgcc.a at link time. */ +#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name) -extern void __sdivsi3(void); -extern void __muldi3(void); -extern void __udivsi3(void); -extern char __div_table; -EXPORT_SYMBOL(__sdivsi3); -EXPORT_SYMBOL(__muldi3); -EXPORT_SYMBOL(__udivsi3); -EXPORT_SYMBOL(__div_table); - - +DECLARE_EXPORT(__sdivsi3); +DECLARE_EXPORT(__muldi3); +DECLARE_EXPORT(__udivsi3); diff --git a/arch/sh64/kernel/time.c b/arch/sh64/kernel/time.c index b37f4f4981d2..06f3c179e345 100644 --- a/arch/sh64/kernel/time.c +++ b/arch/sh64/kernel/time.c @@ -476,8 +476,18 @@ static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL}; -static struct irqaction irq1 = { sh64_rtc_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "rtc", NULL, NULL}; +static struct irqaction irq0 = { + .handler = timer_interrupt, + .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, + .name = "timer", +}; +static struct irqaction irq1 = { + .handler = sh64_rtc_interrupt, + .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, + .name = "rtc", +}; void __init time_init(void) { diff --git a/arch/sh64/kernel/vmlinux.lds.S b/arch/sh64/kernel/vmlinux.lds.S index 267b4f9af2e1..f533a064da5f 100644 --- a/arch/sh64/kernel/vmlinux.lds.S +++ b/arch/sh64/kernel/vmlinux.lds.S @@ -30,14 +30,6 @@ #define LOAD_OFFSET CONFIG_CACHED_MEMORY_OFFSET #include <asm-generic/vmlinux.lds.h> -#ifdef NOTDEF -#ifdef CONFIG_LITTLE_ENDIAN -OUTPUT_FORMAT("elf32-sh64l-linux", "elf32-sh64l-linux", "elf32-sh64l-linux") -#else -OUTPUT_FORMAT("elf32-sh64", "elf32-sh64", "elf32-sh64") -#endif -#endif - OUTPUT_ARCH(sh:sh5) #define C_PHYS(x) AT (ADDR(x) - LOAD_OFFSET) @@ -74,10 +66,12 @@ SECTIONS __ex_table : C_PHYS(__ex_table) { *(__ex_table) } __stop___ex_table = .; - RODATA - _etext = .; /* End of text section */ + NOTES + + RODATA + .data : C_PHYS(.data) { /* Data */ DATA_DATA CONSTRUCTORS @@ -86,13 +80,9 @@ SECTIONS . = ALIGN(PAGE_SIZE); .data.page_aligned : C_PHYS(.data.page_aligned) { *(.data.page_aligned) } - . = ALIGN(PAGE_SIZE); - __per_cpu_start = .; - .data.percpu : C_PHYS(.data.percpu) { - *(.data.percpu) - *(.data.percpu.shared_aligned) - } - __per_cpu_end = . ; + PERCPU(PAGE_SIZE) + + . = ALIGN(L1_CACHE_BYTES); .data.cacheline_aligned : C_PHYS(.data.cacheline_aligned) { *(.data.cacheline_aligned) } _edata = .; /* End of data section */ @@ -145,38 +135,6 @@ SECTIONS *(.exitcall.exit) } - /* Stabs debugging sections. */ - .stab 0 : C_PHYS(.stab) { *(.stab) } - .stabstr 0 : C_PHYS(.stabstr) { *(.stabstr) } - .stab.excl 0 : C_PHYS(.stab.excl) { *(.stab.excl) } - .stab.exclstr 0 : C_PHYS(.stab.exclstr) { *(.stab.exclstr) } - .stab.index 0 : C_PHYS(.stab.index) { *(.stab.index) } - .stab.indexstr 0 : C_PHYS(.stab.indexstr) { *(.stab.indexstr) } - .comment 0 : C_PHYS(.comment) { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging section are relative to the beginning - of the section so we begin .debug at 0. */ - /* DWARF 1 */ - .debug 0 : C_PHYS(.debug) { *(.debug) } - .line 0 : C_PHYS(.line) { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : C_PHYS(.debug_srcinfo) { *(.debug_srcinfo) } - .debug_sfnames 0 : C_PHYS(.debug_sfnames) { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : C_PHYS(.debug_aranges) { *(.debug_aranges) } - .debug_pubnames 0 : C_PHYS(.debug_pubnames) { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : C_PHYS(.debug_info) { *(.debug_info) } - .debug_abbrev 0 : C_PHYS(.debug_abbrev) { *(.debug_abbrev) } - .debug_line 0 : C_PHYS(.debug_line) { *(.debug_line) } - .debug_frame 0 : C_PHYS(.debug_frame) { *(.debug_frame) } - .debug_str 0 : C_PHYS(.debug_str) { *(.debug_str) } - .debug_loc 0 : C_PHYS(.debug_loc) { *(.debug_loc) } - .debug_macinfo 0 : C_PHYS(.debug_macinfo) { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : C_PHYS(.debug_weaknames) { *(.debug_weaknames) } - .debug_funcnames 0 : C_PHYS(.debug_funcnames) { *(.debug_funcnames) } - .debug_typenames 0 : C_PHYS(.debug_typenames) { *(.debug_typenames) } - .debug_varnames 0 : C_PHYS(.debug_varnames) { *(.debug_varnames) } - /* These must appear regardless of . */ + STABS_DEBUG + DWARF_DEBUG } diff --git a/arch/sh64/lib/c-checksum.c b/arch/sh64/lib/c-checksum.c index bd5501760240..053137abd8a0 100644 --- a/arch/sh64/lib/c-checksum.c +++ b/arch/sh64/lib/c-checksum.c @@ -10,6 +10,7 @@ #include <linux/string.h> #include <linux/errno.h> #include <linux/kernel.h> +#include <linux/module.h> #include <asm/byteorder.h> #include <asm/uaccess.h> @@ -110,7 +111,7 @@ static unsigned long do_csum(const unsigned char *buff, int len) if (odd) result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); - pr_debug("\nCHECKSUM is 0x%x\n", result); + pr_debug("\nCHECKSUM is 0x%lx\n", result); out: return result; diff --git a/arch/sh64/lib/io.c b/arch/sh64/lib/io.c index 587baa3dffb9..a3f3a2b8e25b 100644 --- a/arch/sh64/lib/io.c +++ b/arch/sh64/lib/io.c @@ -11,30 +11,11 @@ #include <linux/kernel.h> #include <linux/types.h> #include <linux/delay.h> +#include <linux/module.h> #include <asm/system.h> #include <asm/processor.h> #include <asm/io.h> -/* - * readX/writeX() are used to access memory mapped devices. On some - * architectures the memory mapped IO stuff needs to be accessed - * differently. On the SuperH architecture, we just read/write the - * memory location directly. - */ - -/* This is horrible at the moment - needs more work to do something sensible */ -#define IO_DELAY() - -#define OUT_DELAY(x,type) \ -void out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();} - -#define IN_DELAY(x,type) \ -unsigned type in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;} - -#if 1 -OUT_DELAY(b, long) OUT_DELAY(w, long) OUT_DELAY(l, long) - IN_DELAY(b, long) IN_DELAY(w, long) IN_DELAY(l, long) -#endif /* Now for the string version of these functions */ void outsb(unsigned long port, const void *addr, unsigned long count) { @@ -45,6 +26,7 @@ void outsb(unsigned long port, const void *addr, unsigned long count) outb(*p, port); } } +EXPORT_SYMBOL(outsb); void insb(unsigned long port, void *addr, unsigned long count) { @@ -55,6 +37,7 @@ void insb(unsigned long port, void *addr, unsigned long count) *p = inb(port); } } +EXPORT_SYMBOL(insb); /* For the 16 and 32 bit string functions, we have to worry about alignment. * The SH does not do unaligned accesses, so we have to read as bytes and @@ -74,6 +57,7 @@ void outsw(unsigned long port, const void *addr, unsigned long count) outw(tmp, port); } } +EXPORT_SYMBOL(outsw); void insw(unsigned long port, void *addr, unsigned long count) { @@ -87,6 +71,7 @@ void insw(unsigned long port, void *addr, unsigned long count) p[1] = (tmp >> 8) & 0xff; } } +EXPORT_SYMBOL(insw); void outsl(unsigned long port, const void *addr, unsigned long count) { @@ -100,6 +85,7 @@ void outsl(unsigned long port, const void *addr, unsigned long count) outl(tmp, port); } } +EXPORT_SYMBOL(outsl); void insl(unsigned long port, void *addr, unsigned long count) { @@ -116,6 +102,7 @@ void insl(unsigned long port, void *addr, unsigned long count) } } +EXPORT_SYMBOL(insl); void memcpy_toio(void __iomem *to, const void *from, long count) { @@ -126,6 +113,7 @@ void memcpy_toio(void __iomem *to, const void *from, long count) writeb(*p++, to++); } } +EXPORT_SYMBOL(memcpy_toio); void memcpy_fromio(void *to, void __iomem *from, long count) { @@ -137,3 +125,4 @@ void memcpy_fromio(void *to, void __iomem *from, long count) from++; } } +EXPORT_SYMBOL(memcpy_fromio); diff --git a/arch/sh64/lib/iomap.c b/arch/sh64/lib/iomap.c index 5cd3d5e9c762..253d1e351d49 100644 --- a/arch/sh64/lib/iomap.c +++ b/arch/sh64/lib/iomap.c @@ -17,12 +17,15 @@ ioport_map(unsigned long port, unsigned int len) { return (void __iomem *)port; } +EXPORT_SYMBOL(ioport_map); void ioport_unmap(void __iomem *addr) { /* Nothing .. */ } +EXPORT_SYMBOL(ioport_unmap); +#ifdef CONFIG_PCI void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) { unsigned long start = pci_resource_start(dev, bar); @@ -41,14 +44,11 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) /* What? */ return NULL; } +EXPORT_SYMBOL(pci_iomap); void pci_iounmap(struct pci_dev *dev, void __iomem *addr) { /* Nothing .. */ } - -EXPORT_SYMBOL(ioport_map); -EXPORT_SYMBOL(ioport_unmap); -EXPORT_SYMBOL(pci_iomap); EXPORT_SYMBOL(pci_iounmap); - +#endif diff --git a/arch/sh64/mach-cayman/setup.c b/arch/sh64/mach-cayman/setup.c index c3611cc2735f..726c520d7eb9 100644 --- a/arch/sh64/mach-cayman/setup.c +++ b/arch/sh64/mach-cayman/setup.c @@ -18,19 +18,11 @@ * lethal@linux-sh.org: 15th May 2003 * Use the generic procfs cpuinfo interface, just return a valid board name. */ - -#include <linux/stddef.h> #include <linux/init.h> -#include <linux/mm.h> -#include <linux/bootmem.h> -#include <linux/delay.h> #include <linux/kernel.h> -#include <linux/seq_file.h> -#include <asm/processor.h> #include <asm/platform.h> -#include <asm/io.h> #include <asm/irq.h> -#include <asm/page.h> +#include <asm/io.h> /* * Platform Dependent Interrupt Priorities. diff --git a/arch/sh64/mach-harp/Makefile b/arch/sh64/mach-harp/Makefile index 63f065bad2f9..2f2963fa2131 100644 --- a/arch/sh64/mach-harp/Makefile +++ b/arch/sh64/mach-harp/Makefile @@ -1,14 +1 @@ -# -# Makefile for the ST50 Harp specific parts of the kernel -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# - -O_TARGET := harp.o - obj-y := setup.o - -include $(TOPDIR)/Rules.make - diff --git a/arch/sh64/mach-harp/setup.c b/arch/sh64/mach-harp/setup.c index fcd90afac297..05011cb369bb 100644 --- a/arch/sh64/mach-harp/setup.c +++ b/arch/sh64/mach-harp/setup.c @@ -17,20 +17,10 @@ * lethal@linux-sh.org: 15th May 2003 * Use the generic procfs cpuinfo interface, just return a valid board name. */ - -#include <linux/stddef.h> #include <linux/init.h> -#include <linux/mm.h> -#include <linux/bootmem.h> -#include <linux/delay.h> #include <linux/kernel.h> -#include <asm/processor.h> #include <asm/platform.h> -#include <asm/io.h> #include <asm/irq.h> -#include <asm/page.h> - -#define RES_COUNT(res) ((sizeof((res))/sizeof(struct resource))) /* * Platform Dependent Interrupt Priorities. @@ -78,8 +68,10 @@ struct resource io_resources[] = { }; struct resource kram_resources[] = { - { "Kernel code", 0, 0 }, /* These must be last in the array */ - { "Kernel data", 0, 0 } /* These must be last in the array */ + /* These must be last in the array */ + { .name = "Kernel code", .start = 0, .end = 0 }, + /* These must be last in the array */ + { .name = "Kernel data", .start = 0, .end = 0 } }; struct resource xram_resources[] = { @@ -95,13 +87,13 @@ struct sh64_platform platform_parms = { .initial_root_dev = 0x0100, .loader_type = 1, .io_res_p = io_resources, - .io_res_count = RES_COUNT(io_resources), + .io_res_count = ARRAY_SIZE(io_resources), .kram_res_p = kram_resources, - .kram_res_count = RES_COUNT(kram_resources), + .kram_res_count = ARRAY_SIZE(kram_resources), .xram_res_p = xram_resources, - .xram_res_count = RES_COUNT(xram_resources), + .xram_res_count = ARRAY_SIZE(xram_resources), .rom_res_p = rom_resources, - .rom_res_count = RES_COUNT(rom_resources), + .rom_res_count = ARRAY_SIZE(rom_resources), }; int platform_int_priority[NR_INTC_IRQS] = { @@ -135,4 +127,3 @@ const char *get_system_type(void) { return "ST50 Harp"; } - diff --git a/arch/sh64/mach-romram/Makefile b/arch/sh64/mach-romram/Makefile deleted file mode 100644 index 02d05c05afa1..000000000000 --- a/arch/sh64/mach-romram/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# Makefile for the SH-5 ROM/RAM specific parts of the kernel -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# - -O_TARGET := romram.o - -obj-y := setup.o - -include $(TOPDIR)/Rules.make - diff --git a/arch/sh64/mach-romram/setup.c b/arch/sh64/mach-romram/setup.c deleted file mode 100644 index eb98a1640cc1..000000000000 --- a/arch/sh64/mach-romram/setup.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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. - * - * arch/sh64/mach-romram/setup.c - * - * SH-5 ROM/RAM Platform Support - * - * This file handles the architecture-dependent parts of initialization - * - * Copyright (C) 2000, 2001 Paolo Alberelli - * - * benedict.gaster@superh.com: 3rd May 2002 - * Added support for ramdisk, removing statically linked romfs at the same time. * - * - * lethal@linux-sh.org: 15th May 2003 - * Use the generic procfs cpuinfo interface, just return a valid board name. - * - * Sean.McGoogan@superh.com 17th Feb 2004 - * copied from arch/sh64/mach-harp/setup.c - */ - -#include <linux/stddef.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/bootmem.h> -#include <linux/delay.h> -#include <linux/kernel.h> -#include <asm/processor.h> -#include <asm/platform.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/page.h> - -#define RES_COUNT(res) ((sizeof((res))/sizeof(struct resource))) - -/* - * Platform Dependent Interrupt Priorities. - */ - -/* Using defaults defined in irq.h */ -#define RES NO_PRIORITY /* Disabled */ -#define IR0 IRL0_PRIORITY /* IRLs */ -#define IR1 IRL1_PRIORITY -#define IR2 IRL2_PRIORITY -#define IR3 IRL3_PRIORITY -#define PCA INTA_PRIORITY /* PCI Ints */ -#define PCB INTB_PRIORITY -#define PCC INTC_PRIORITY -#define PCD INTD_PRIORITY -#define SER TOP_PRIORITY -#define ERR TOP_PRIORITY -#define PW0 TOP_PRIORITY -#define PW1 TOP_PRIORITY -#define PW2 TOP_PRIORITY -#define PW3 TOP_PRIORITY -#define DM0 NO_PRIORITY /* DMA Ints */ -#define DM1 NO_PRIORITY -#define DM2 NO_PRIORITY -#define DM3 NO_PRIORITY -#define DAE NO_PRIORITY -#define TU0 TIMER_PRIORITY /* TMU Ints */ -#define TU1 NO_PRIORITY -#define TU2 NO_PRIORITY -#define TI2 NO_PRIORITY -#define ATI NO_PRIORITY /* RTC Ints */ -#define PRI NO_PRIORITY -#define CUI RTC_PRIORITY -#define ERI SCIF_PRIORITY /* SCIF Ints */ -#define RXI SCIF_PRIORITY -#define BRI SCIF_PRIORITY -#define TXI SCIF_PRIORITY -#define ITI TOP_PRIORITY /* WDT Ints */ - -/* - * Platform dependent structures: maps and parms block. - */ -struct resource io_resources[] = { - /* To be updated with external devices */ -}; - -struct resource kram_resources[] = { - { "Kernel code", 0, 0 }, /* These must be last in the array */ - { "Kernel data", 0, 0 } /* These must be last in the array */ -}; - -struct resource xram_resources[] = { - /* To be updated with external devices */ -}; - -struct resource rom_resources[] = { - /* To be updated with external devices */ -}; - -struct sh64_platform platform_parms = { - .readonly_rootfs = 1, - .initial_root_dev = 0x0100, - .loader_type = 1, - .io_res_p = io_resources, - .io_res_count = RES_COUNT(io_resources), - .kram_res_p = kram_resources, - .kram_res_count = RES_COUNT(kram_resources), - .xram_res_p = xram_resources, - .xram_res_count = RES_COUNT(xram_resources), - .rom_res_p = rom_resources, - .rom_res_count = RES_COUNT(rom_resources), -}; - -int platform_int_priority[NR_INTC_IRQS] = { - IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD, /* IRQ 0- 7 */ - RES, RES, RES, RES, SER, ERR, PW3, PW2, /* IRQ 8-15 */ - PW1, PW0, DM0, DM1, DM2, DM3, DAE, RES, /* IRQ 16-23 */ - RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 24-31 */ - TU0, TU1, TU2, TI2, ATI, PRI, CUI, ERI, /* IRQ 32-39 */ - RXI, BRI, TXI, RES, RES, RES, RES, RES, /* IRQ 40-47 */ - RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 48-55 */ - RES, RES, RES, RES, RES, RES, RES, ITI, /* IRQ 56-63 */ -}; - -void __init platform_setup(void) -{ - /* ROM/RAM platform leaves the decision to head.S, for now */ - platform_parms.fpu_flags = fpu_in_use; -} - -void __init platform_monitor(void) -{ - /* Nothing yet .. */ -} - -void __init platform_reserve(void) -{ - /* Nothing yet .. */ -} - -const char *get_system_type(void) -{ - return "ROM/RAM"; -} - diff --git a/arch/sh64/mach-sim/Makefile b/arch/sh64/mach-sim/Makefile index 819c4078fdc6..2f2963fa2131 100644 --- a/arch/sh64/mach-sim/Makefile +++ b/arch/sh64/mach-sim/Makefile @@ -1,14 +1 @@ -# -# Makefile for the SH-5 Simulator specific parts of the kernel -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# - -O_TARGET := sim.o - obj-y := setup.o - -include $(TOPDIR)/Rules.make - diff --git a/arch/sh64/mach-sim/setup.c b/arch/sh64/mach-sim/setup.c index f09400c1ad1b..e3386ec1ce1f 100644 --- a/arch/sh64/mach-sim/setup.c +++ b/arch/sh64/mach-sim/setup.c @@ -14,46 +14,10 @@ * lethal@linux-sh.org: 15th May 2003 * Use the generic procfs cpuinfo interface, just return a valid board name. */ - -#include <linux/stddef.h> #include <linux/init.h> -#include <linux/mm.h> -#include <linux/bootmem.h> -#include <linux/delay.h> #include <linux/kernel.h> -#include <asm/addrspace.h> -#include <asm/processor.h> #include <asm/platform.h> -#include <asm/io.h> #include <asm/irq.h> -#include <asm/page.h> - -#ifdef CONFIG_BLK_DEV_INITRD -#include "../rootfs/rootfs.h" -#endif - -static __init void platform_monitor(void); -static __init void platform_setup(void); -static __init void platform_reserve(void); - - -#define PHYS_MEMORY CONFIG_MEMORY_SIZE_IN_MB*1024*1024 - -#if (PHYS_MEMORY < P1SEG_FOOTPRINT_RAM) -#error "Invalid kernel configuration. Physical memory below footprint requirements." -#endif - -#define RAM_DISK_START CONFIG_MEMORY_START+P1SEG_INITRD_BLOCK /* Top of 4MB */ -#ifdef PLATFORM_ROMFS_SIZE -#define RAM_DISK_SIZE (PAGE_ALIGN(PLATFORM_ROMFS_SIZE)) /* Variable Top */ -#if ((RAM_DISK_START + RAM_DISK_SIZE) > (CONFIG_MEMORY_START + PHYS_MEMORY)) -#error "Invalid kernel configuration. ROM RootFS exceeding physical memory." -#endif -#else -#define RAM_DISK_SIZE P1SEG_INITRD_BLOCK_SIZE /* Top of 4MB */ -#endif - -#define RES_COUNT(res) ((sizeof((res))/sizeof(struct resource))) /* * Platform Dependent Interrupt Priorities. @@ -101,8 +65,10 @@ struct resource io_resources[] = { }; struct resource kram_resources[] = { - { "Kernel code", 0, 0 }, /* These must be last in the array */ - { "Kernel data", 0, 0 } /* These must be last in the array */ + /* These must be last in the array */ + { .name = "Kernel code", .start = 0, .end = 0 }, + /* These must be last in the array */ + { .name = "Kernel data", .start = 0, .end = 0 } }; struct resource xram_resources[] = { @@ -117,16 +83,14 @@ struct sh64_platform platform_parms = { .readonly_rootfs = 1, .initial_root_dev = 0x0100, .loader_type = 1, - .initrd_start = RAM_DISK_START, - .initrd_size = RAM_DISK_SIZE, .io_res_p = io_resources, - .io_res_count = RES_COUNT(io_resources), + .io_res_count = ARRAY_SIZE(io_resources), .kram_res_p = kram_resources, - .kram_res_count = RES_COUNT(kram_resources), + .kram_res_count = ARRAY_SIZE(kram_resources), .xram_res_p = xram_resources, - .xram_res_count = RES_COUNT(xram_resources), + .xram_res_count = ARRAY_SIZE(xram_resources), .rom_res_p = rom_resources, - .rom_res_count = RES_COUNT(rom_resources), + .rom_res_count = ARRAY_SIZE(rom_resources), }; int platform_int_priority[NR_IRQS] = { @@ -160,4 +124,3 @@ const char *get_system_type(void) { return "SH-5 Simulator"; } - diff --git a/arch/sh64/mm/Makefile b/arch/sh64/mm/Makefile index ff19378ac90a..d0e813632480 100644 --- a/arch/sh64/mm/Makefile +++ b/arch/sh64/mm/Makefile @@ -13,7 +13,8 @@ # unless it's something special (ie not a .c file). # -obj-y := init.o fault.o ioremap.o extable.o cache.o tlbmiss.o tlb.o +obj-y := cache.o consistent.o extable.o fault.o init.o ioremap.o \ + tlbmiss.o tlb.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o @@ -41,4 +42,3 @@ CFLAGS_tlbmiss.o += -ffixed-r7 \ -ffixed-r41 -ffixed-r42 -ffixed-r43 \ -ffixed-r60 -ffixed-r61 -ffixed-r62 \ -fomit-frame-pointer - diff --git a/arch/sh64/kernel/pci-dma.c b/arch/sh64/mm/consistent.c index a9328f894755..8875a2a40da7 100644 --- a/arch/sh64/kernel/pci-dma.c +++ b/arch/sh64/mm/consistent.c @@ -11,6 +11,7 @@ #include <linux/mm.h> #include <linux/string.h> #include <linux/pci.h> +#include <linux/module.h> #include <asm/io.h> void *consistent_alloc(struct pci_dev *hwdev, size_t size, @@ -36,6 +37,7 @@ void *consistent_alloc(struct pci_dev *hwdev, size_t size, return vp; } +EXPORT_SYMBOL(consistent_alloc); void consistent_free(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) @@ -47,4 +49,4 @@ void consistent_free(struct pci_dev *hwdev, size_t size, iounmap(vaddr); } - +EXPORT_SYMBOL(consistent_free); diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c index 0d069d82141f..dd81c669c79b 100644 --- a/arch/sh64/mm/fault.c +++ b/arch/sh64/mm/fault.c @@ -334,7 +334,7 @@ out_of_memory: } printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/sh64/mm/init.c b/arch/sh64/mm/init.c index 559717f30d1f..21cf42de23e2 100644 --- a/arch/sh64/mm/init.c +++ b/arch/sh64/mm/init.c @@ -22,10 +22,6 @@ #include <asm/pgtable.h> #include <asm/tlb.h> -#ifdef CONFIG_BLK_DEV_INITRD -#include <linux/blk.h> -#endif - DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); /* diff --git a/arch/sh64/mm/ioremap.c b/arch/sh64/mm/ioremap.c index 990857756d44..535304e6601f 100644 --- a/arch/sh64/mm/ioremap.c +++ b/arch/sh64/mm/ioremap.c @@ -19,11 +19,12 @@ #include <linux/sched.h> #include <linux/string.h> #include <linux/io.h> -#include <asm/pgalloc.h> -#include <asm/tlbflush.h> #include <linux/ioport.h> #include <linux/bootmem.h> #include <linux/proc_fs.h> +#include <linux/module.h> +#include <asm/pgalloc.h> +#include <asm/tlbflush.h> static void shmedia_mapioaddr(unsigned long, unsigned long); static unsigned long shmedia_ioremap(struct resource *, u32, int); @@ -80,6 +81,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag } return (void *) (offset + (char *)addr); } +EXPORT_SYMBOL(__ioremap); void iounmap(void *addr) { @@ -94,6 +96,7 @@ void iounmap(void *addr) kfree(area); } +EXPORT_SYMBOL(iounmap); static struct resource shmedia_iomap = { .name = "shmedia_iomap", diff --git a/arch/sparc/Kconfig.debug b/arch/sparc/Kconfig.debug index 120f6b529348..87dd496f15eb 100644 --- a/arch/sparc/Kconfig.debug +++ b/arch/sparc/Kconfig.debug @@ -1,5 +1,9 @@ menu "Kernel hacking" +config TRACE_IRQFLAGS_SUPPORT + bool + default y + source "lib/Kconfig.debug" config DEBUG_STACK_USAGE diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 62182d2d7b0d..9c3ed88853f3 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -35,6 +35,7 @@ #include <linux/slab.h> #include <linux/pci.h> /* struct pci_dev */ #include <linux/proc_fs.h> +#include <linux/scatterlist.h> #include <asm/io.h> #include <asm/vaddrs.h> @@ -717,19 +718,19 @@ void pci_unmap_page(struct pci_dev *hwdev, * Device ownership issues as mentioned above for pci_map_single are * the same here. */ -int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, +int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction) { + struct scatterlist *sg; int n; BUG_ON(direction == PCI_DMA_NONE); /* IIep is write-through, not flushing. */ - for (n = 0; n < nents; n++) { + for_each_sg(sgl, sg, nents, n) { BUG_ON(page_address(sg->page) == NULL); sg->dvma_address = virt_to_phys(page_address(sg->page)) + sg->offset; sg->dvma_length = sg->length; - sg++; } return nents; } @@ -738,19 +739,19 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, * Again, cpu read rules concerning calls here are the same as for * pci_unmap_single() above. */ -void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, +void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction) { + struct scatterlist *sg; int n; BUG_ON(direction == PCI_DMA_NONE); if (direction != PCI_DMA_TODEVICE) { - for (n = 0; n < nents; n++) { + for_each_sg(sgl, sg, nents, n) { BUG_ON(page_address(sg->page) == NULL); mmu_inval_dma_area( (unsigned long) page_address(sg->page), (sg->length + PAGE_SIZE-1) & PAGE_MASK); - sg++; } } } @@ -789,34 +790,34 @@ void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t ba, size_t * The same as pci_dma_sync_single_* but for a scatter-gather list, * same rules and usage. */ -void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) +void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction) { + struct scatterlist *sg; int n; BUG_ON(direction == PCI_DMA_NONE); if (direction != PCI_DMA_TODEVICE) { - for (n = 0; n < nents; n++) { + for_each_sg(sgl, sg, nents, n) { BUG_ON(page_address(sg->page) == NULL); mmu_inval_dma_area( (unsigned long) page_address(sg->page), (sg->length + PAGE_SIZE-1) & PAGE_MASK); - sg++; } } } -void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) +void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction) { + struct scatterlist *sg; int n; BUG_ON(direction == PCI_DMA_NONE); if (direction != PCI_DMA_TODEVICE) { - for (n = 0; n < nents; n++) { + for_each_sg(sgl, sg, nents, n) { BUG_ON(page_address(sg->page) == NULL); mmu_inval_dma_area( (unsigned long) page_address(sg->page), (sg->length + PAGE_SIZE-1) & PAGE_MASK); - sg++; } } } diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index b76dc03fc318..722d67d32961 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c @@ -56,7 +56,7 @@ #define SMP_NOP2 #define SMP_NOP3 #endif /* SMP */ -unsigned long __local_irq_save(void) +unsigned long __raw_local_irq_save(void) { unsigned long retval; unsigned long tmp; @@ -74,7 +74,7 @@ unsigned long __local_irq_save(void) return retval; } -void local_irq_enable(void) +void raw_local_irq_enable(void) { unsigned long tmp; @@ -89,7 +89,7 @@ void local_irq_enable(void) : "memory"); } -void local_irq_restore(unsigned long old_psr) +void raw_local_irq_restore(unsigned long old_psr) { unsigned long tmp; @@ -105,9 +105,9 @@ void local_irq_restore(unsigned long old_psr) : "memory"); } -EXPORT_SYMBOL(__local_irq_save); -EXPORT_SYMBOL(local_irq_enable); -EXPORT_SYMBOL(local_irq_restore); +EXPORT_SYMBOL(__raw_local_irq_save); +EXPORT_SYMBOL(raw_local_irq_enable); +EXPORT_SYMBOL(raw_local_irq_restore); /* * Dave Redman (djhr@tadpole.co.uk) diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index 36383f73d685..fb2caef79cec 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c @@ -588,7 +588,10 @@ __setup("of_debug=", of_debug); int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) { /* initialize common driver fields */ - drv->driver.name = drv->name; + if (!drv->driver.name) + drv->driver.name = drv->name; + if (!drv->driver.owner) + drv->driver.owner = drv->owner; drv->driver.bus = bus; /* register with core */ diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 6a2513321620..4bf78a5e8e0f 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -347,9 +347,11 @@ static struct of_device_id clock_match[] = { }; static struct of_platform_driver clock_driver = { - .name = "clock", .match_table = clock_match, .probe = clock_probe, + .driver = { + .name = "clock", + }, }; diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 15109c156e83..a8b4200f9cc3 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -1,6 +1,7 @@ /* ld script to make SparcLinux kernel */ #include <asm-generic/vmlinux.lds.h> +#include <asm/page.h> OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc") OUTPUT_ARCH(sparc) @@ -8,84 +9,104 @@ ENTRY(_start) jiffies = jiffies_64 + 4; SECTIONS { - . = 0x10000 + SIZEOF_HEADERS; - .text 0xf0004000 : - { - _text = .; - TEXT_TEXT - SCHED_TEXT - LOCK_TEXT - *(.gnu.warning) - } =0 - _etext = .; - PROVIDE (etext = .); - RODATA - .data : - { - DATA_DATA - CONSTRUCTORS - } - .data1 : { *(.data1) } - _edata = .; - PROVIDE (edata = .); - __start___fixup = .; - .fixup : { *(.fixup) } - __stop___fixup = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; + . = 0x10000 + SIZEOF_HEADERS; + .text 0xf0004000 : + { + _text = .; + TEXT_TEXT + SCHED_TEXT + LOCK_TEXT + *(.gnu.warning) + } = 0 + _etext = .; + PROVIDE (etext = .); + RODATA + .data : { + DATA_DATA + CONSTRUCTORS + } + .data1 : { + *(.data1) + } + _edata = .; + PROVIDE (edata = .); - NOTES + .fixup : { + __start___fixup = .; + *(.fixup) + __stop___fixup = .; + } + __ex_table : { + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } - . = ALIGN(4096); - __init_begin = .; - _sinittext = .; - .init.text : { - *(.init.text) - } - _einittext = .; - __init_text_end = .; - .init.data : { *(.init.data) } - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __initcall_start = .; - .initcall.init : { - INITCALLS - } - __initcall_end = .; - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - SECURITY_INIT + NOTES + + . = ALIGN(PAGE_SIZE); + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + __init_text_end = .; + .init.data : { + *(.init.data) + } + . = ALIGN(16); + .init.setup : { + __setup_start = .; + *(.init.setup) + __setup_end = .; + } + .initcall.init : { + __initcall_start = .; + INITCALLS + __initcall_end = .; + } + .con_initcall.init : { + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + } + SECURITY_INIT #ifdef CONFIG_BLK_DEV_INITRD - . = ALIGN(4096); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; + . = ALIGN(PAGE_SIZE); + .init.ramfs : { + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + } #endif - PERCPU(4096) - . = ALIGN(4096); - __init_end = .; - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - __bss_start = .; - .sbss : { *(.sbss) *(.scommon) } - .bss : - { - *(.dynbss) - *(.bss) - *(COMMON) - } - _end = . ; - PROVIDE (end = .); - /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } + PERCPU(PAGE_SIZE) + . = ALIGN(PAGE_SIZE); + __init_end = .; + . = ALIGN(32); + .data.cacheline_aligned : { + *(.data.cacheline_aligned) + } - STABS_DEBUG + __bss_start = .; + .sbss : { + *(.sbss) + *(.scommon) } + .bss : { + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); + /DISCARD/ : { + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + } - DWARF_DEBUG + STABS_DEBUG + DWARF_DEBUG } diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c index 50747fe44356..e4d9c8e19df5 100644 --- a/arch/sparc/mm/fault.c +++ b/arch/sparc/mm/fault.c @@ -369,7 +369,7 @@ out_of_memory: up_read(&mm->mmap_sem); printk("VM: killing process %s\n", tsk->comm); if (from_user) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 7c89893b1fe8..375b4db63704 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -11,8 +11,8 @@ #include <linux/mm.h> #include <linux/highmem.h> /* pte_offset_map => kmap_atomic */ #include <linux/bitops.h> +#include <linux/scatterlist.h> -#include <asm/scatterlist.h> #include <asm/pgalloc.h> #include <asm/pgtable.h> #include <asm/sbus.h> @@ -144,8 +144,9 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus spin_lock_irqsave(&iounit->lock, flags); while (sz != 0) { --sz; - sg[sz].dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg[sz].page) + sg[sz].offset, sg[sz].length); - sg[sz].dvma_length = sg[sz].length; + sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg->page) + sg->offset, sg->length); + sg->dvma_length = sg->length; + sg = sg_next(sg); } spin_unlock_irqrestore(&iounit->lock, flags); } @@ -173,11 +174,12 @@ static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_ spin_lock_irqsave(&iounit->lock, flags); while (sz != 0) { --sz; - len = ((sg[sz].dvma_address & ~PAGE_MASK) + sg[sz].length + (PAGE_SIZE-1)) >> PAGE_SHIFT; - vaddr = (sg[sz].dvma_address - IOUNIT_DMA_BASE) >> PAGE_SHIFT; + len = ((sg->dvma_address & ~PAGE_MASK) + sg->length + (PAGE_SIZE-1)) >> PAGE_SHIFT; + vaddr = (sg->dvma_address - IOUNIT_DMA_BASE) >> PAGE_SHIFT; IOD(("iounit_release %08lx-%08lx\n", (long)vaddr, (long)len+vaddr)); for (len += vaddr; vaddr < len; vaddr++) clear_bit(vaddr, iounit->bmap); + sg = sg_next(sg); } spin_unlock_irqrestore(&iounit->lock, flags); } diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 52e907af9d29..283656d9f6ea 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c @@ -12,8 +12,8 @@ #include <linux/mm.h> #include <linux/slab.h> #include <linux/highmem.h> /* pte_offset_map => kmap_atomic */ +#include <linux/scatterlist.h> -#include <asm/scatterlist.h> #include <asm/pgalloc.h> #include <asm/pgtable.h> #include <asm/sbus.h> @@ -240,7 +240,7 @@ static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sb n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; sg->dvma_length = (__u32) sg->length; - sg++; + sg = sg_next(sg); } } @@ -254,7 +254,7 @@ static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbu n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; sg->dvma_length = (__u32) sg->length; - sg++; + sg = sg_next(sg); } } @@ -285,7 +285,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; sg->dvma_length = (__u32) sg->length; - sg++; + sg = sg_next(sg); } } @@ -325,7 +325,7 @@ static void iommu_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_b n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; iommu_release_one(sg->dvma_address & PAGE_MASK, n, sbus); sg->dvma_address = 0x21212121; - sg++; + sg = sg_next(sg); } } diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 005a3e72d4f2..ee6708fc4492 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -17,8 +17,8 @@ #include <linux/highmem.h> #include <linux/fs.h> #include <linux/seq_file.h> +#include <linux/scatterlist.h> -#include <asm/scatterlist.h> #include <asm/page.h> #include <asm/pgalloc.h> #include <asm/pgtable.h> @@ -1228,8 +1228,9 @@ static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus * { while (sz != 0) { --sz; - sg[sz].dvma_address = (__u32)sun4c_lockarea(page_address(sg[sz].page) + sg[sz].offset, sg[sz].length); - sg[sz].dvma_length = sg[sz].length; + sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg->page) + sg->offset, sg->length); + sg->dvma_length = sg->length; + sg = sg_next(sg); } } @@ -1244,7 +1245,8 @@ static void sun4c_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_b { while (sz != 0) { --sz; - sun4c_unlockarea((char *)sg[sz].dvma_address, sg[sz].length); + sun4c_unlockarea((char *)sg->dvma_address, sg->length); + sg = sg_next(sg); } } diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 33dabf588bdd..2f22fa90461a 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -240,10 +240,10 @@ config ARCH_SELECT_MEMORY_MODEL config ARCH_SPARSEMEM_ENABLE def_bool y + select SPARSEMEM_VMEMMAP_ENABLE config ARCH_SPARSEMEM_DEFAULT def_bool y - select SPARSEMEM_STATIC source "mm/Kconfig" diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 7d07297db878..1aa2c4048e4b 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.23-rc6 -# Sun Sep 16 09:52:11 2007 +# Linux kernel version: 2.6.23 +# Sat Oct 13 21:53:54 2007 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -69,7 +69,6 @@ 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 @@ -89,6 +88,7 @@ CONFIG_KMOD=y CONFIG_BLOCK=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_BLK_DEV_BSG=y +CONFIG_BLOCK_COMPAT=y # # IO Schedulers @@ -111,6 +111,7 @@ CONFIG_GENERIC_HARDIRQS=y CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # CONFIG_SMP is not set CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_TABLE=m @@ -119,6 +120,8 @@ CONFIG_CPU_FREQ_STAT=m CONFIG_CPU_FREQ_STAT_DETAILS=y CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=m CONFIG_CPU_FREQ_GOV_USERSPACE=m @@ -213,6 +216,7 @@ CONFIG_INET_TUNNEL=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -304,6 +308,7 @@ CONFIG_NET_TCPPROBE=m # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y # CONFIG_PREVENT_FIRMWARE_BUILD is not set CONFIG_FW_LOADER=y @@ -355,6 +360,11 @@ CONFIG_IDE_PROC_FS=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_BLK_DEV_PLATFORM is not set + +# +# PCI IDE chipsets support +# CONFIG_BLK_DEV_IDEPCI=y # CONFIG_IDEPCI_SHARE_IRQ is not set CONFIG_IDEPCI_PCIBUS_ORDER=y @@ -391,7 +401,6 @@ CONFIG_BLK_DEV_ALI15X3=y # CONFIG_BLK_DEV_TC86C001 is not set # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set # CONFIG_BLK_DEV_HD is not set # @@ -505,6 +514,8 @@ CONFIG_DUMMY=m # CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_IP1000 is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y @@ -518,13 +529,16 @@ CONFIG_CASSINI=m # CONFIG_NET_VENDOR_3COM is not set # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 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 @@ -543,6 +557,7 @@ CONFIG_NETDEV_1000=y CONFIG_E1000=m CONFIG_E1000_NAPI=y # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +# CONFIG_E1000E is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -560,11 +575,14 @@ CONFIG_BNX2=m CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set # CONFIG_CHELSIO_T3 is not set +# CONFIG_IXGBE 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_NIU is not set # CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set # CONFIG_TR is not set # @@ -820,6 +838,12 @@ CONFIG_HWMON=y # CONFIG_HWMON_DEBUG_CHIP is not set # +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# # Multifunction device drivers # # CONFIG_MFD_SM501 is not set @@ -1399,6 +1423,7 @@ CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=y CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y @@ -1417,6 +1442,7 @@ CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_XTS=m # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_FCRYPT=m @@ -1431,11 +1457,13 @@ CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_HW=y # diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 40d2f3aae91e..112c46e66578 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o \ pci_psycho.o pci_sabre.o pci_schizo.o \ pci_sun4v.o pci_sun4v_asm.o pci_fire.o +obj-$(CONFIG_PCI_MSI) += pci_msi.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 diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c index 7b379761e9f8..c55f0293eacd 100644 --- a/arch/sparc64/kernel/auxio.c +++ b/arch/sparc64/kernel/auxio.c @@ -148,9 +148,11 @@ static int __devinit auxio_probe(struct of_device *dev, const struct of_device_i } static struct of_platform_driver auxio_driver = { - .name = "auxio", .match_table = auxio_match, .probe = auxio_probe, + .driver = { + .name = "auxio", + }, }; static int __init auxio_init(void) diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 8059531bf0ac..c9b0d7af64ae 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -429,16 +429,16 @@ do_ivec: stxa %g0, [%g0] ASI_INTR_RECEIVE membar #Sync - sethi %hi(ivector_table), %g2 - sllx %g3, 3, %g3 - or %g2, %lo(ivector_table), %g2 + sethi %hi(ivector_table_pa), %g2 + ldx [%g2 + %lo(ivector_table_pa)], %g2 + sllx %g3, 4, %g3 add %g2, %g3, %g3 - TRAP_LOAD_IRQ_WORK(%g6, %g1) + TRAP_LOAD_IRQ_WORK_PA(%g6, %g1) - lduw [%g6], %g5 /* g5 = irq_work(cpu) */ - stw %g5, [%g3 + 0x00] /* bucket->irq_chain = g5 */ - stw %g3, [%g6] /* irq_work(cpu) = bucket */ + ldx [%g6], %g5 + stxa %g5, [%g3] ASI_PHYS_USE_EC + stx %g3, [%g6] wr %g0, 1 << PIL_DEVICE_IRQ, %set_softint retry do_ivec_xcall: diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c index b35a62167e9c..db3ffcf7a120 100644 --- a/arch/sparc64/kernel/iommu.c +++ b/arch/sparc64/kernel/iommu.c @@ -10,6 +10,7 @@ #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/errno.h> +#include <linux/scatterlist.h> #ifdef CONFIG_PCI #include <linux/pci.h> @@ -480,7 +481,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, unsigned long iopte_protection) { struct scatterlist *dma_sg = sg; - struct scatterlist *sg_end = sg + nelems; + struct scatterlist *sg_end = sg_last(sg, nelems); int i; for (i = 0; i < nused; i++) { @@ -515,7 +516,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL))); break; } - sg++; + sg = sg_next(sg); } pteval = iopte_protection | (pteval & IOPTE_PAGE); @@ -528,24 +529,24 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, } pteval = (pteval & IOPTE_PAGE) + len; - sg++; + sg = sg_next(sg); /* Skip over any tail mappings we've fully mapped, * adjusting pteval along the way. Stop when we * detect a page crossing event. */ - while (sg < sg_end && + while (sg != sg_end && (pteval << (64 - IO_PAGE_SHIFT)) != 0UL && (pteval == SG_ENT_PHYS_ADDRESS(sg)) && ((pteval ^ (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { pteval += sg->length; - sg++; + sg = sg_next(sg); } if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) pteval = ~0UL; } while (dma_npages != 0); - dma_sg++; + dma_sg = sg_next(dma_sg); } } @@ -606,7 +607,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, sgtmp = sglist; while (used && sgtmp->dma_length) { sgtmp->dma_address += dma_base; - sgtmp++; + sgtmp = sg_next(sgtmp); used--; } used = nelems - used; @@ -642,6 +643,7 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, struct strbuf *strbuf; iopte_t *base; unsigned long flags, ctx, i, npages; + struct scatterlist *sg, *sgprv; u32 bus_addr; if (unlikely(direction == DMA_NONE)) { @@ -654,11 +656,14 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, bus_addr = sglist->dma_address & IO_PAGE_MASK; - for (i = 1; i < nelems; i++) - if (sglist[i].dma_length == 0) + sgprv = NULL; + for_each_sg(sglist, sg, nelems, i) { + if (sg->dma_length == 0) break; - i--; - npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - + sgprv = sg; + } + + npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) - bus_addr) >> IO_PAGE_SHIFT; base = iommu->page_table + @@ -730,6 +735,7 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev, struct iommu *iommu; struct strbuf *strbuf; unsigned long flags, ctx, npages, i; + struct scatterlist *sg, *sgprv; u32 bus_addr; iommu = dev->archdata.iommu; @@ -753,11 +759,14 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev, /* Step 2: Kick data out of streaming buffers. */ bus_addr = sglist[0].dma_address & IO_PAGE_MASK; - for(i = 1; i < nelems; i++) - if (!sglist[i].dma_length) + sgprv = NULL; + for_each_sg(sglist, sg, nelems, i) { + if (sg->dma_length == 0) break; - i--; - npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) + sgprv = sg; + } + + npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) - bus_addr) >> IO_PAGE_SHIFT; strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 23956096b3bf..f3922e5a89f6 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -21,7 +21,6 @@ #include <linux/seq_file.h> #include <linux/bootmem.h> #include <linux/irq.h> -#include <linux/msi.h> #include <asm/ptrace.h> #include <asm/processor.h> @@ -43,6 +42,7 @@ #include <asm/auxio.h> #include <asm/head.h> #include <asm/hypervisor.h> +#include <asm/cacheflush.h> /* UPA nodes send interrupt packet to UltraSparc with first data reg * value low 5 (7 on Starfire) bits holding the IRQ identifier being @@ -52,86 +52,128 @@ * To make processing these packets efficient and race free we use * an array of irq buckets below. The interrupt vector handler in * entry.S feeds incoming packets into per-cpu pil-indexed lists. - * The IVEC handler does not need to act atomically, the PIL dispatch - * code uses CAS to get an atomic snapshot of the list and clear it - * at the same time. * * If you make changes to ino_bucket, please update hand coded assembler * of the vectored interrupt trap handler(s) in entry.S and sun4v_ivec.S */ struct ino_bucket { - /* Next handler in per-CPU IRQ worklist. We know that - * bucket pointers have the high 32-bits clear, so to - * save space we only store the bits we need. - */ -/*0x00*/unsigned int irq_chain; +/*0x00*/unsigned long __irq_chain_pa; /* Virtual interrupt number assigned to this INO. */ -/*0x04*/unsigned int virt_irq; +/*0x08*/unsigned int __virt_irq; +/*0x0c*/unsigned int __pad; }; #define NUM_IVECS (IMAP_INR + 1) -struct ino_bucket ivector_table[NUM_IVECS] __attribute__ ((aligned (SMP_CACHE_BYTES))); - -#define __irq_ino(irq) \ - (((struct ino_bucket *)(unsigned long)(irq)) - &ivector_table[0]) -#define __bucket(irq) ((struct ino_bucket *)(unsigned long)(irq)) -#define __irq(bucket) ((unsigned int)(unsigned long)(bucket)) - -/* This has to be in the main kernel image, it cannot be - * turned into per-cpu data. The reason is that the main - * kernel image is locked into the TLB and this structure - * is accessed from the vectored interrupt trap handler. If - * access to this structure takes a TLB miss it could cause - * the 5-level sparc v9 trap stack to overflow. +struct ino_bucket *ivector_table; +unsigned long ivector_table_pa; + +/* On several sun4u processors, it is illegal to mix bypass and + * non-bypass accesses. Therefore we access all INO buckets + * using bypass accesses only. */ -#define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist) +static unsigned long bucket_get_chain_pa(unsigned long bucket_pa) +{ + unsigned long ret; + + __asm__ __volatile__("ldxa [%1] %2, %0" + : "=&r" (ret) + : "r" (bucket_pa + + offsetof(struct ino_bucket, + __irq_chain_pa)), + "i" (ASI_PHYS_USE_EC)); + + return ret; +} + +static void bucket_clear_chain_pa(unsigned long bucket_pa) +{ + __asm__ __volatile__("stxa %%g0, [%0] %1" + : /* no outputs */ + : "r" (bucket_pa + + offsetof(struct ino_bucket, + __irq_chain_pa)), + "i" (ASI_PHYS_USE_EC)); +} + +static unsigned int bucket_get_virt_irq(unsigned long bucket_pa) +{ + unsigned int ret; + + __asm__ __volatile__("lduwa [%1] %2, %0" + : "=&r" (ret) + : "r" (bucket_pa + + offsetof(struct ino_bucket, + __virt_irq)), + "i" (ASI_PHYS_USE_EC)); + + return ret; +} + +static void bucket_set_virt_irq(unsigned long bucket_pa, + unsigned int virt_irq) +{ + __asm__ __volatile__("stwa %0, [%1] %2" + : /* no outputs */ + : "r" (virt_irq), + "r" (bucket_pa + + offsetof(struct ino_bucket, + __virt_irq)), + "i" (ASI_PHYS_USE_EC)); +} + +#define irq_work_pa(__cpu) &(trap_block[(__cpu)].irq_worklist_pa) static struct { - unsigned int irq; unsigned int dev_handle; unsigned int dev_ino; -} virt_to_real_irq_table[NR_IRQS]; + unsigned int in_use; +} virt_irq_table[NR_IRQS]; +static DEFINE_SPINLOCK(virt_irq_alloc_lock); -static unsigned char virt_irq_alloc(unsigned int real_irq) +unsigned char virt_irq_alloc(unsigned int dev_handle, + unsigned int dev_ino) { + unsigned long flags; unsigned char ent; BUILD_BUG_ON(NR_IRQS >= 256); + spin_lock_irqsave(&virt_irq_alloc_lock, flags); + for (ent = 1; ent < NR_IRQS; ent++) { - if (!virt_to_real_irq_table[ent].irq) + if (!virt_irq_table[ent].in_use) break; } if (ent >= NR_IRQS) { printk(KERN_ERR "IRQ: Out of virtual IRQs.\n"); - return 0; + ent = 0; + } else { + virt_irq_table[ent].dev_handle = dev_handle; + virt_irq_table[ent].dev_ino = dev_ino; + virt_irq_table[ent].in_use = 1; } - virt_to_real_irq_table[ent].irq = real_irq; + spin_unlock_irqrestore(&virt_irq_alloc_lock, flags); return ent; } #ifdef CONFIG_PCI_MSI -static void virt_irq_free(unsigned int virt_irq) +void virt_irq_free(unsigned int virt_irq) { - unsigned int real_irq; + unsigned long flags; if (virt_irq >= NR_IRQS) return; - real_irq = virt_to_real_irq_table[virt_irq].irq; - virt_to_real_irq_table[virt_irq].irq = 0; + spin_lock_irqsave(&virt_irq_alloc_lock, flags); - __bucket(real_irq)->virt_irq = 0; -} -#endif + virt_irq_table[virt_irq].in_use = 0; -static unsigned int virt_to_real_irq(unsigned char virt_irq) -{ - return virt_to_real_irq_table[virt_irq].irq; + spin_unlock_irqrestore(&virt_irq_alloc_lock, flags); } +#endif /* * /proc/interrupts printing: @@ -217,38 +259,8 @@ struct irq_handler_data { void (*pre_handler)(unsigned int, void *, void *); void *pre_handler_arg1; void *pre_handler_arg2; - - u32 msi; }; -void sparc64_set_msi(unsigned int virt_irq, u32 msi) -{ - struct irq_handler_data *data = get_irq_chip_data(virt_irq); - - if (data) - data->msi = msi; -} - -u32 sparc64_get_msi(unsigned int virt_irq) -{ - struct irq_handler_data *data = get_irq_chip_data(virt_irq); - - if (data) - return data->msi; - return 0xffffffff; -} - -static inline struct ino_bucket *virt_irq_to_bucket(unsigned int virt_irq) -{ - unsigned int real_irq = virt_to_real_irq(virt_irq); - struct ino_bucket *bucket = NULL; - - if (likely(real_irq)) - bucket = __bucket(real_irq); - - return bucket; -} - #ifdef CONFIG_SMP static int irq_choose_cpu(unsigned int virt_irq) { @@ -348,201 +360,152 @@ static void sun4u_irq_end(unsigned int virt_irq) static void sun4v_irq_enable(unsigned int virt_irq) { - 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; + unsigned int ino = virt_irq_table[virt_irq].dev_ino; + unsigned long cpuid = irq_choose_cpu(virt_irq); + int err; - cpuid = irq_choose_cpu(virt_irq); - - err = sun4v_intr_settarget(ino, cpuid); - if (err != HV_EOK) - printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): " - "err(%d)\n", ino, cpuid, err); - err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); - if (err != HV_EOK) - printk(KERN_ERR "sun4v_intr_setstate(%x): " - "err(%d)\n", ino, err); - err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED); - if (err != HV_EOK) - printk(KERN_ERR "sun4v_intr_setenabled(%x): err(%d)\n", - ino, err); - } + err = sun4v_intr_settarget(ino, cpuid); + if (err != HV_EOK) + printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): " + "err(%d)\n", ino, cpuid, err); + err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); + if (err != HV_EOK) + printk(KERN_ERR "sun4v_intr_setstate(%x): " + "err(%d)\n", ino, err); + err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED); + if (err != HV_EOK) + printk(KERN_ERR "sun4v_intr_setenabled(%x): err(%d)\n", + ino, err); } 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]; + unsigned int ino = virt_irq_table[virt_irq].dev_ino; + unsigned long cpuid = irq_choose_cpu(virt_irq); + int err; - 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(KERN_ERR "sun4v_intr_settarget(%x,%lu): " - "err(%d)\n", ino, cpuid, err); - } + err = sun4v_intr_settarget(ino, cpuid); + if (err != HV_EOK) + printk(KERN_ERR "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); - unsigned int ino = bucket - &ivector_table[0]; - - if (likely(bucket)) { - int err; - - err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED); - if (err != HV_EOK) - printk(KERN_ERR "sun4v_intr_setenabled(%x): " - "err(%d)\n", ino, err); - } -} - -#ifdef CONFIG_PCI_MSI -static void sun4v_msi_enable(unsigned int virt_irq) -{ - sun4v_irq_enable(virt_irq); - unmask_msi_irq(virt_irq); -} + unsigned int ino = virt_irq_table[virt_irq].dev_ino; + int err; -static void sun4v_msi_disable(unsigned int virt_irq) -{ - mask_msi_irq(virt_irq); - sun4v_irq_disable(virt_irq); + err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED); + if (err != HV_EOK) + printk(KERN_ERR "sun4v_intr_setenabled(%x): " + "err(%d)\n", ino, err); } -#endif 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]; + unsigned int ino = virt_irq_table[virt_irq].dev_ino; struct irq_desc *desc = irq_desc + virt_irq; + int err; if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) return; - if (likely(bucket)) { - int err; - - err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); - if (err != HV_EOK) - printk(KERN_ERR "sun4v_intr_setstate(%x): " - "err(%d)\n", ino, err); - } + err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); + if (err != HV_EOK) + printk(KERN_ERR "sun4v_intr_setstate(%x): " + "err(%d)\n", ino, err); } static void sun4v_virq_enable(unsigned int virt_irq) { - struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); - - if (likely(bucket)) { - unsigned long cpuid, dev_handle, dev_ino; - int err; - - cpuid = irq_choose_cpu(virt_irq); - - dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; - dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; - - err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); - if (err != HV_EOK) - printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): " - "err(%d)\n", - dev_handle, dev_ino, cpuid, err); - err = sun4v_vintr_set_state(dev_handle, dev_ino, - HV_INTR_STATE_IDLE); - if (err != HV_EOK) - printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," - "HV_INTR_STATE_IDLE): err(%d)\n", - dev_handle, dev_ino, err); - err = sun4v_vintr_set_valid(dev_handle, dev_ino, - HV_INTR_ENABLED); - if (err != HV_EOK) - printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," - "HV_INTR_ENABLED): err(%d)\n", - dev_handle, dev_ino, err); - } + unsigned long cpuid, dev_handle, dev_ino; + int err; + + cpuid = irq_choose_cpu(virt_irq); + + dev_handle = virt_irq_table[virt_irq].dev_handle; + dev_ino = virt_irq_table[virt_irq].dev_ino; + + err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); + if (err != HV_EOK) + printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): " + "err(%d)\n", + dev_handle, dev_ino, cpuid, err); + err = sun4v_vintr_set_state(dev_handle, dev_ino, + HV_INTR_STATE_IDLE); + if (err != HV_EOK) + printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," + "HV_INTR_STATE_IDLE): err(%d)\n", + dev_handle, dev_ino, err); + err = sun4v_vintr_set_valid(dev_handle, dev_ino, + HV_INTR_ENABLED); + if (err != HV_EOK) + printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," + "HV_INTR_ENABLED): err(%d)\n", + dev_handle, dev_ino, err); } static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask) { - struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); + unsigned long cpuid, dev_handle, dev_ino; + int err; - if (likely(bucket)) { - unsigned long cpuid, dev_handle, dev_ino; - int err; + cpuid = irq_choose_cpu(virt_irq); - cpuid = irq_choose_cpu(virt_irq); + dev_handle = virt_irq_table[virt_irq].dev_handle; + dev_ino = virt_irq_table[virt_irq].dev_ino; - dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; - dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; - - err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); - if (err != HV_EOK) - printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): " - "err(%d)\n", - dev_handle, dev_ino, cpuid, err); - } + err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); + if (err != HV_EOK) + printk(KERN_ERR "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); + unsigned long dev_handle, dev_ino; + int err; - if (likely(bucket)) { - unsigned long dev_handle, dev_ino; - int err; + dev_handle = virt_irq_table[virt_irq].dev_handle; + dev_ino = virt_irq_table[virt_irq].dev_ino; - dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; - dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; - - err = sun4v_vintr_set_valid(dev_handle, dev_ino, - HV_INTR_DISABLED); - if (err != HV_EOK) - printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," - "HV_INTR_DISABLED): err(%d)\n", - dev_handle, dev_ino, err); - } + err = sun4v_vintr_set_valid(dev_handle, dev_ino, + HV_INTR_DISABLED); + if (err != HV_EOK) + printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," + "HV_INTR_DISABLED): err(%d)\n", + dev_handle, dev_ino, err); } static void sun4v_virq_end(unsigned int virt_irq) { - struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); struct irq_desc *desc = irq_desc + virt_irq; + unsigned long dev_handle, dev_ino; + int err; if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) return; - if (likely(bucket)) { - unsigned long dev_handle, dev_ino; - int err; + dev_handle = virt_irq_table[virt_irq].dev_handle; + dev_ino = virt_irq_table[virt_irq].dev_ino; - dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; - dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; - - err = sun4v_vintr_set_state(dev_handle, dev_ino, - HV_INTR_STATE_IDLE); - if (err != HV_EOK) - printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," - "HV_INTR_STATE_IDLE): err(%d)\n", - dev_handle, dev_ino, err); - } + err = sun4v_vintr_set_state(dev_handle, dev_ino, + HV_INTR_STATE_IDLE); + if (err != HV_EOK) + printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," + "HV_INTR_STATE_IDLE): err(%d)\n", + dev_handle, dev_ino, err); } static void run_pre_handler(unsigned int virt_irq) { - struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); struct irq_handler_data *data = get_irq_chip_data(virt_irq); + unsigned int ino; + ino = virt_irq_table[virt_irq].dev_ino; if (likely(data->pre_handler)) { - data->pre_handler(__irq_ino(__irq(bucket)), + data->pre_handler(ino, data->pre_handler_arg1, data->pre_handler_arg2); } @@ -573,28 +536,6 @@ static struct irq_chip sun4v_irq = { .set_affinity = sun4v_set_affinity, }; -static struct irq_chip sun4v_irq_ack = { - .typename = "sun4v+ack", - .enable = sun4v_irq_enable, - .disable = sun4v_irq_disable, - .ack = run_pre_handler, - .end = sun4v_irq_end, - .set_affinity = sun4v_set_affinity, -}; - -#ifdef CONFIG_PCI_MSI -static struct irq_chip sun4v_msi = { - .typename = "sun4v+msi", - .mask = mask_msi_irq, - .unmask = unmask_msi_irq, - .enable = sun4v_msi_enable, - .disable = sun4v_msi_disable, - .ack = run_pre_handler, - .end = sun4v_irq_end, - .set_affinity = sun4v_set_affinity, -}; -#endif - static struct irq_chip sun4v_virq = { .typename = "vsun4v", .enable = sun4v_virq_enable, @@ -603,59 +544,48 @@ static struct irq_chip sun4v_virq = { .set_affinity = sun4v_virt_set_affinity, }; -static struct irq_chip sun4v_virq_ack = { - .typename = "vsun4v+ack", - .enable = sun4v_virq_enable, - .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, void (*func)(unsigned int, void *, void *), void *arg1, void *arg2) { struct irq_handler_data *data = get_irq_chip_data(virt_irq); - struct irq_chip *chip; + struct irq_chip *chip = get_irq_chip(virt_irq); + + if (WARN_ON(chip == &sun4v_irq || chip == &sun4v_virq)) { + printk(KERN_ERR "IRQ: Trying to install pre-handler on " + "sun4v irq %u\n", virt_irq); + return; + } data->pre_handler = func; data->pre_handler_arg1 = arg1; data->pre_handler_arg2 = arg2; - chip = get_irq_chip(virt_irq); - if (chip == &sun4u_irq_ack || - chip == &sun4v_irq_ack || - chip == &sun4v_virq_ack -#ifdef CONFIG_PCI_MSI - || chip == &sun4v_msi -#endif - ) + if (chip == &sun4u_irq_ack) return; - chip = (chip == &sun4u_irq ? - &sun4u_irq_ack : - (chip == &sun4v_irq ? - &sun4v_irq_ack : &sun4v_virq_ack)); - set_irq_chip(virt_irq, chip); + set_irq_chip(virt_irq, &sun4u_irq_ack); } unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) { struct ino_bucket *bucket; struct irq_handler_data *data; + unsigned int virt_irq; int ino; BUG_ON(tlb_type == hypervisor); ino = (upa_readq(imap) & (IMAP_IGN | IMAP_INO)) + inofixup; bucket = &ivector_table[ino]; - if (!bucket->virt_irq) { - bucket->virt_irq = virt_irq_alloc(__irq(bucket)); - set_irq_chip(bucket->virt_irq, &sun4u_irq); + virt_irq = bucket_get_virt_irq(__pa(bucket)); + if (!virt_irq) { + virt_irq = virt_irq_alloc(0, ino); + bucket_set_virt_irq(__pa(bucket), virt_irq); + set_irq_chip(virt_irq, &sun4u_irq); } - data = get_irq_chip_data(bucket->virt_irq); + data = get_irq_chip_data(virt_irq); if (unlikely(data)) goto out; @@ -664,13 +594,13 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); prom_halt(); } - set_irq_chip_data(bucket->virt_irq, data); + set_irq_chip_data(virt_irq, data); data->imap = imap; data->iclr = iclr; out: - return bucket->virt_irq; + return virt_irq; } static unsigned int sun4v_build_common(unsigned long sysino, @@ -678,16 +608,19 @@ static unsigned int sun4v_build_common(unsigned long sysino, { struct ino_bucket *bucket; struct irq_handler_data *data; + unsigned int virt_irq; BUG_ON(tlb_type != hypervisor); bucket = &ivector_table[sysino]; - if (!bucket->virt_irq) { - bucket->virt_irq = virt_irq_alloc(__irq(bucket)); - set_irq_chip(bucket->virt_irq, chip); + virt_irq = bucket_get_virt_irq(__pa(bucket)); + if (!virt_irq) { + virt_irq = virt_irq_alloc(0, sysino); + bucket_set_virt_irq(__pa(bucket), virt_irq); + set_irq_chip(virt_irq, chip); } - data = get_irq_chip_data(bucket->virt_irq); + data = get_irq_chip_data(virt_irq); if (unlikely(data)) goto out; @@ -696,7 +629,7 @@ static unsigned int sun4v_build_common(unsigned long sysino, prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); prom_halt(); } - set_irq_chip_data(bucket->virt_irq, data); + set_irq_chip_data(virt_irq, data); /* Catch accidental accesses to these things. IMAP/ICLR handling * is done by hypervisor calls on sun4v platforms, not by direct @@ -706,7 +639,7 @@ static unsigned int sun4v_build_common(unsigned long sysino, data->iclr = ~0UL; out: - return bucket->virt_irq; + return virt_irq; } unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) @@ -718,86 +651,52 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) { - unsigned long sysino, hv_err; - unsigned int virq; - - BUG_ON(devhandle & devino); - - sysino = devhandle | devino; - BUG_ON(sysino & ~(IMAP_IGN | IMAP_INO)); - - hv_err = sun4v_vintr_set_cookie(devhandle, devino, sysino); - if (hv_err) { - prom_printf("IRQ: Fatal, cannot set cookie for [%x:%x] " - "err=%lu\n", devhandle, devino, hv_err); - prom_halt(); - } - - virq = sun4v_build_common(sysino, &sun4v_virq); - - virt_to_real_irq_table[virq].dev_handle = devhandle; - virt_to_real_irq_table[virq].dev_ino = devino; - - return virq; -} - -#ifdef CONFIG_PCI_MSI -unsigned int sun4v_build_msi(u32 devhandle, unsigned int *virt_irq_p, - unsigned int msi_start, unsigned int msi_end) -{ - struct ino_bucket *bucket; struct irq_handler_data *data; - unsigned long sysino; - unsigned int devino; - - BUG_ON(tlb_type != hypervisor); - - /* Find a free devino in the given range. */ - for (devino = msi_start; devino < msi_end; devino++) { - sysino = sun4v_devino_to_sysino(devhandle, devino); - bucket = &ivector_table[sysino]; - if (!bucket->virt_irq) - break; - } - if (devino >= msi_end) - return -ENOSPC; + struct ino_bucket *bucket; + unsigned long hv_err, cookie; + unsigned int virt_irq; - sysino = sun4v_devino_to_sysino(devhandle, devino); - bucket = &ivector_table[sysino]; - bucket->virt_irq = virt_irq_alloc(__irq(bucket)); - *virt_irq_p = bucket->virt_irq; - set_irq_chip(bucket->virt_irq, &sun4v_msi); + bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); + if (unlikely(!bucket)) + return 0; + __flush_dcache_range((unsigned long) bucket, + ((unsigned long) bucket + + sizeof(struct ino_bucket))); - data = get_irq_chip_data(bucket->virt_irq); - if (unlikely(data)) - return devino; + virt_irq = virt_irq_alloc(devhandle, devino); + bucket_set_virt_irq(__pa(bucket), virt_irq); + set_irq_chip(virt_irq, &sun4v_virq); data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); - if (unlikely(!data)) { - virt_irq_free(*virt_irq_p); - return -ENOMEM; - } - set_irq_chip_data(bucket->virt_irq, data); + if (unlikely(!data)) + return 0; + + set_irq_chip_data(virt_irq, data); + /* Catch accidental accesses to these things. IMAP/ICLR handling + * is done by hypervisor calls on sun4v platforms, not by direct + * register accesses. + */ data->imap = ~0UL; data->iclr = ~0UL; - return devino; -} + cookie = ~__pa(bucket); + hv_err = sun4v_vintr_set_cookie(devhandle, devino, cookie); + if (hv_err) { + prom_printf("IRQ: Fatal, cannot set cookie for [%x:%x] " + "err=%lu\n", devhandle, devino, hv_err); + prom_halt(); + } -void sun4v_destroy_msi(unsigned int virt_irq) -{ - virt_irq_free(virt_irq); + return virt_irq; } -#endif void ack_bad_irq(unsigned int virt_irq) { - struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); - unsigned int ino = 0xdeadbeef; + unsigned int ino = virt_irq_table[virt_irq].dev_ino; - if (bucket) - ino = bucket - &ivector_table[0]; + if (!ino) + ino = 0xdeadbeef; printk(KERN_CRIT "Unexpected IRQ from ino[%x] virt_irq[%u]\n", ino, virt_irq); @@ -805,7 +704,7 @@ void ack_bad_irq(unsigned int virt_irq) void handler_irq(int irq, struct pt_regs *regs) { - struct ino_bucket *bucket; + unsigned long pstate, bucket_pa; struct pt_regs *old_regs; clear_softint(1 << irq); @@ -813,15 +712,28 @@ void handler_irq(int irq, struct pt_regs *regs) old_regs = set_irq_regs(regs); irq_enter(); - /* Sliiiick... */ - bucket = __bucket(xchg32(irq_work(smp_processor_id()), 0)); - while (bucket) { - struct ino_bucket *next = __bucket(bucket->irq_chain); + /* Grab an atomic snapshot of the pending IVECs. */ + __asm__ __volatile__("rdpr %%pstate, %0\n\t" + "wrpr %0, %3, %%pstate\n\t" + "ldx [%2], %1\n\t" + "stx %%g0, [%2]\n\t" + "wrpr %0, 0x0, %%pstate\n\t" + : "=&r" (pstate), "=&r" (bucket_pa) + : "r" (irq_work_pa(smp_processor_id())), + "i" (PSTATE_IE) + : "memory"); + + while (bucket_pa) { + unsigned long next_pa; + unsigned int virt_irq; - bucket->irq_chain = 0; - __do_IRQ(bucket->virt_irq); + next_pa = bucket_get_chain_pa(bucket_pa); + virt_irq = bucket_get_virt_irq(bucket_pa); + bucket_clear_chain_pa(bucket_pa); - bucket = next; + __do_IRQ(virt_irq); + + bucket_pa = next_pa; } irq_exit(); @@ -921,7 +833,7 @@ void init_irqwork_curcpu(void) { int cpu = hard_smp_processor_id(); - trap_block[cpu].irq_worklist = 0; + trap_block[cpu].irq_worklist_pa = 0UL; } /* Please be very careful with register_one_mondo() and @@ -1035,9 +947,21 @@ static struct irqaction timer_irq_action = { /* Only invoked on boot processor. */ void __init init_IRQ(void) { + unsigned long size; + map_prom_timers(); kill_prom_timer(); - memset(&ivector_table[0], 0, sizeof(ivector_table)); + + size = sizeof(struct ino_bucket) * NUM_IVECS; + ivector_table = alloc_bootmem_low(size); + if (!ivector_table) { + prom_printf("Fatal error, cannot allocate ivector_table\n"); + prom_halt(); + } + __flush_dcache_range((unsigned long) ivector_table, + ((unsigned long) ivector_table) + size); + + ivector_table_pa = __pa(ivector_table); if (tlb_type == hypervisor) sun4v_init_mondo_queues(); diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index c93a15b785fa..d94f901d321e 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c @@ -42,6 +42,8 @@ DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); +struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}}; + int __kprobes arch_prepare_kprobe(struct kprobe *p) { p->ainsn.insn[0] = *p->addr; diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S index d4024ac0d619..964527d2ffa0 100644 --- a/arch/sparc64/kernel/ktlb.S +++ b/arch/sparc64/kernel/ktlb.S @@ -226,6 +226,15 @@ kvmap_dtlb_load: ba,pt %xcc, sun4v_dtlb_load mov %g5, %g3 +kvmap_vmemmap: + sub %g4, %g5, %g5 + srlx %g5, 22, %g5 + sethi %hi(vmemmap_table), %g1 + sllx %g5, 3, %g5 + or %g1, %lo(vmemmap_table), %g1 + ba,pt %xcc, kvmap_dtlb_load + ldx [%g1 + %g5], %g5 + kvmap_dtlb_nonlinear: /* Catch kernel NULL pointer derefs. */ sethi %hi(PAGE_SIZE), %g5 @@ -233,6 +242,13 @@ kvmap_dtlb_nonlinear: bleu,pn %xcc, kvmap_dtlb_longpath nop + /* Do not use the TSB for vmemmap. */ + mov (VMEMMAP_BASE >> 24), %g5 + sllx %g5, 24, %g5 + cmp %g4,%g5 + bgeu,pn %xcc, kvmap_vmemmap + nop + KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load) kvmap_dtlb_tsbmiss: diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 4cc77485f536..42d779866fba 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -872,7 +872,10 @@ __setup("of_debug=", of_debug); int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) { /* initialize common driver fields */ - drv->driver.name = drv->name; + if (!drv->driver.name) + drv->driver.name = drv->name; + if (!drv->driver.owner) + drv->driver.owner = drv->owner; drv->driver.bus = bus; /* register with core */ diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index e8dac81d8a0d..9b808640a193 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -29,8 +29,6 @@ #include "pci_impl.h" -unsigned long pci_memspace_mask = 0xffffffffUL; - #ifndef CONFIG_PCI /* A "nop" PCI implementation. */ asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn, @@ -1066,8 +1064,8 @@ static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struc return 0; } -/* Adjust vm_pgoff of VMA such that it is the physical page offset corresponding - * to the 32-bit pci bus offset for DEV requested by the user. +/* Adjust vm_pgoff of VMA such that it is the physical page offset + * corresponding to the 32-bit pci bus offset for DEV requested by the user. * * Basically, the user finds the base address for his device which he wishes * to mmap. They read the 32-bit value from the config space base register, @@ -1076,21 +1074,35 @@ static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struc * * Returns negative error code on failure, zero on success. */ -static int __pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma, +static int __pci_mmap_make_offset(struct pci_dev *pdev, + struct vm_area_struct *vma, enum pci_mmap_state mmap_state) { - unsigned long user_offset = vma->vm_pgoff << PAGE_SHIFT; - unsigned long user32 = user_offset & pci_memspace_mask; - unsigned long largest_base, this_base, addr32; - int i; + unsigned long user_paddr, user_size; + int i, err; - if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) - return __pci_mmap_make_offset_bus(dev, vma, mmap_state); + /* First compute the physical address in vma->vm_pgoff, + * making sure the user offset is within range in the + * appropriate PCI space. + */ + err = __pci_mmap_make_offset_bus(pdev, vma, mmap_state); + if (err) + return err; + + /* If this is a mapping on a host bridge, any address + * is OK. + */ + if ((pdev->class >> 8) == PCI_CLASS_BRIDGE_HOST) + return err; + + /* Otherwise make sure it's in the range for one of the + * device's resources. + */ + user_paddr = vma->vm_pgoff << PAGE_SHIFT; + user_size = vma->vm_end - vma->vm_start; - /* Figure out which base address this is for. */ - largest_base = 0UL; for (i = 0; i <= PCI_ROM_RESOURCE; i++) { - struct resource *rp = &dev->resource[i]; + struct resource *rp = &pdev->resource[i]; /* Active? */ if (!rp->flags) @@ -1108,26 +1120,14 @@ static int __pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vm continue; } - this_base = rp->start; - - addr32 = (this_base & PAGE_MASK) & pci_memspace_mask; - - if (mmap_state == pci_mmap_io) - addr32 &= 0xffffff; - - if (addr32 <= user32 && this_base > largest_base) - largest_base = this_base; + if ((rp->start <= user_paddr) && + (user_paddr + user_size) <= (rp->end + 1UL)) + break; } - if (largest_base == 0UL) + if (i > PCI_ROM_RESOURCE) return -EINVAL; - /* Now construct the final physical address. */ - if (mmap_state == pci_mmap_io) - vma->vm_pgoff = (((largest_base & ~0xffffffUL) | user32) >> PAGE_SHIFT); - else - vma->vm_pgoff = (((largest_base & ~(pci_memspace_mask)) | user32) >> PAGE_SHIFT); - return 0; } diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c index 14d67fe21ab2..fef3b37487bf 100644 --- a/arch/sparc64/kernel/pci_fire.c +++ b/arch/sparc64/kernel/pci_fire.c @@ -6,9 +6,12 @@ #include <linux/pci.h> #include <linux/slab.h> #include <linux/init.h> +#include <linux/msi.h> +#include <linux/irq.h> #include <asm/oplib.h> #include <asm/prom.h> +#include <asm/irq.h> #include "pci_impl.h" @@ -84,6 +87,266 @@ static int pci_fire_pbm_iommu_init(struct pci_pbm_info *pbm) return 0; } +#ifdef CONFIG_PCI_MSI +struct pci_msiq_entry { + u64 word0; +#define MSIQ_WORD0_RESV 0x8000000000000000UL +#define MSIQ_WORD0_FMT_TYPE 0x7f00000000000000UL +#define MSIQ_WORD0_FMT_TYPE_SHIFT 56 +#define MSIQ_WORD0_LEN 0x00ffc00000000000UL +#define MSIQ_WORD0_LEN_SHIFT 46 +#define MSIQ_WORD0_ADDR0 0x00003fff00000000UL +#define MSIQ_WORD0_ADDR0_SHIFT 32 +#define MSIQ_WORD0_RID 0x00000000ffff0000UL +#define MSIQ_WORD0_RID_SHIFT 16 +#define MSIQ_WORD0_DATA0 0x000000000000ffffUL +#define MSIQ_WORD0_DATA0_SHIFT 0 + +#define MSIQ_TYPE_MSG 0x6 +#define MSIQ_TYPE_MSI32 0xb +#define MSIQ_TYPE_MSI64 0xf + + u64 word1; +#define MSIQ_WORD1_ADDR1 0xffffffffffff0000UL +#define MSIQ_WORD1_ADDR1_SHIFT 16 +#define MSIQ_WORD1_DATA1 0x000000000000ffffUL +#define MSIQ_WORD1_DATA1_SHIFT 0 + + u64 resv[6]; +}; + +/* All MSI registers are offset from pbm->pbm_regs */ +#define EVENT_QUEUE_BASE_ADDR_REG 0x010000UL +#define EVENT_QUEUE_BASE_ADDR_ALL_ONES 0xfffc000000000000UL + +#define EVENT_QUEUE_CONTROL_SET(EQ) (0x011000UL + (EQ) * 0x8UL) +#define EVENT_QUEUE_CONTROL_SET_OFLOW 0x0200000000000000UL +#define EVENT_QUEUE_CONTROL_SET_EN 0x0000100000000000UL + +#define EVENT_QUEUE_CONTROL_CLEAR(EQ) (0x011200UL + (EQ) * 0x8UL) +#define EVENT_QUEUE_CONTROL_CLEAR_OF 0x0200000000000000UL +#define EVENT_QUEUE_CONTROL_CLEAR_E2I 0x0000800000000000UL +#define EVENT_QUEUE_CONTROL_CLEAR_DIS 0x0000100000000000UL + +#define EVENT_QUEUE_STATE(EQ) (0x011400UL + (EQ) * 0x8UL) +#define EVENT_QUEUE_STATE_MASK 0x0000000000000007UL +#define EVENT_QUEUE_STATE_IDLE 0x0000000000000001UL +#define EVENT_QUEUE_STATE_ACTIVE 0x0000000000000002UL +#define EVENT_QUEUE_STATE_ERROR 0x0000000000000004UL + +#define EVENT_QUEUE_TAIL(EQ) (0x011600UL + (EQ) * 0x8UL) +#define EVENT_QUEUE_TAIL_OFLOW 0x0200000000000000UL +#define EVENT_QUEUE_TAIL_VAL 0x000000000000007fUL + +#define EVENT_QUEUE_HEAD(EQ) (0x011800UL + (EQ) * 0x8UL) +#define EVENT_QUEUE_HEAD_VAL 0x000000000000007fUL + +#define MSI_MAP(MSI) (0x020000UL + (MSI) * 0x8UL) +#define MSI_MAP_VALID 0x8000000000000000UL +#define MSI_MAP_EQWR_N 0x4000000000000000UL +#define MSI_MAP_EQNUM 0x000000000000003fUL + +#define MSI_CLEAR(MSI) (0x028000UL + (MSI) * 0x8UL) +#define MSI_CLEAR_EQWR_N 0x4000000000000000UL + +#define IMONDO_DATA0 0x02C000UL +#define IMONDO_DATA0_DATA 0xffffffffffffffc0UL + +#define IMONDO_DATA1 0x02C008UL +#define IMONDO_DATA1_DATA 0xffffffffffffffffUL + +#define MSI_32BIT_ADDR 0x034000UL +#define MSI_32BIT_ADDR_VAL 0x00000000ffff0000UL + +#define MSI_64BIT_ADDR 0x034008UL +#define MSI_64BIT_ADDR_VAL 0xffffffffffff0000UL + +static int pci_fire_get_head(struct pci_pbm_info *pbm, unsigned long msiqid, + unsigned long *head) +{ + *head = fire_read(pbm->pbm_regs + EVENT_QUEUE_HEAD(msiqid)); + return 0; +} + +static int pci_fire_dequeue_msi(struct pci_pbm_info *pbm, unsigned long msiqid, + unsigned long *head, unsigned long *msi) +{ + unsigned long type_fmt, type, msi_num; + struct pci_msiq_entry *base, *ep; + + base = (pbm->msi_queues + ((msiqid - pbm->msiq_first) * 8192)); + ep = &base[*head]; + + if ((ep->word0 & MSIQ_WORD0_FMT_TYPE) == 0) + return 0; + + type_fmt = ((ep->word0 & MSIQ_WORD0_FMT_TYPE) >> + MSIQ_WORD0_FMT_TYPE_SHIFT); + type = (type_fmt >> 3); + if (unlikely(type != MSIQ_TYPE_MSI32 && + type != MSIQ_TYPE_MSI64)) + return -EINVAL; + + *msi = msi_num = ((ep->word0 & MSIQ_WORD0_DATA0) >> + MSIQ_WORD0_DATA0_SHIFT); + + fire_write(pbm->pbm_regs + MSI_CLEAR(msi_num), + MSI_CLEAR_EQWR_N); + + /* Clear the entry. */ + ep->word0 &= ~MSIQ_WORD0_FMT_TYPE; + + /* Go to next entry in ring. */ + (*head)++; + if (*head >= pbm->msiq_ent_count) + *head = 0; + + return 1; +} + +static int pci_fire_set_head(struct pci_pbm_info *pbm, unsigned long msiqid, + unsigned long head) +{ + fire_write(pbm->pbm_regs + EVENT_QUEUE_HEAD(msiqid), head); + return 0; +} + +static int pci_fire_msi_setup(struct pci_pbm_info *pbm, unsigned long msiqid, + unsigned long msi, int is_msi64) +{ + u64 val; + + val = fire_read(pbm->pbm_regs + MSI_MAP(msi)); + val &= ~(MSI_MAP_EQNUM); + val |= msiqid; + fire_write(pbm->pbm_regs + MSI_MAP(msi), val); + + fire_write(pbm->pbm_regs + MSI_CLEAR(msi), + MSI_CLEAR_EQWR_N); + + val = fire_read(pbm->pbm_regs + MSI_MAP(msi)); + val |= MSI_MAP_VALID; + fire_write(pbm->pbm_regs + MSI_MAP(msi), val); + + return 0; +} + +static int pci_fire_msi_teardown(struct pci_pbm_info *pbm, unsigned long msi) +{ + unsigned long msiqid; + u64 val; + + val = fire_read(pbm->pbm_regs + MSI_MAP(msi)); + msiqid = (val & MSI_MAP_EQNUM); + + val &= ~MSI_MAP_VALID; + + fire_write(pbm->pbm_regs + MSI_MAP(msi), val); + + return 0; +} + +static int pci_fire_msiq_alloc(struct pci_pbm_info *pbm) +{ + unsigned long pages, order, i; + + order = get_order(512 * 1024); + pages = __get_free_pages(GFP_KERNEL | __GFP_COMP, order); + if (pages == 0UL) { + printk(KERN_ERR "MSI: Cannot allocate MSI queues (o=%lu).\n", + order); + return -ENOMEM; + } + memset((char *)pages, 0, PAGE_SIZE << order); + pbm->msi_queues = (void *) pages; + + fire_write(pbm->pbm_regs + EVENT_QUEUE_BASE_ADDR_REG, + (EVENT_QUEUE_BASE_ADDR_ALL_ONES | + __pa(pbm->msi_queues))); + + fire_write(pbm->pbm_regs + IMONDO_DATA0, + pbm->portid << 6); + fire_write(pbm->pbm_regs + IMONDO_DATA1, 0); + + fire_write(pbm->pbm_regs + MSI_32BIT_ADDR, + pbm->msi32_start); + fire_write(pbm->pbm_regs + MSI_64BIT_ADDR, + pbm->msi64_start); + + for (i = 0; i < pbm->msiq_num; i++) { + fire_write(pbm->pbm_regs + EVENT_QUEUE_HEAD(i), 0); + fire_write(pbm->pbm_regs + EVENT_QUEUE_TAIL(i), 0); + } + + return 0; +} + +static void pci_fire_msiq_free(struct pci_pbm_info *pbm) +{ + unsigned long pages, order; + + order = get_order(512 * 1024); + pages = (unsigned long) pbm->msi_queues; + + free_pages(pages, order); + + pbm->msi_queues = NULL; +} + +static int pci_fire_msiq_build_irq(struct pci_pbm_info *pbm, + unsigned long msiqid, + unsigned long devino) +{ + unsigned long cregs = (unsigned long) pbm->pbm_regs; + unsigned long imap_reg, iclr_reg, int_ctrlr; + unsigned int virt_irq; + int fixup; + u64 val; + + imap_reg = cregs + (0x001000UL + (devino * 0x08UL)); + iclr_reg = cregs + (0x001400UL + (devino * 0x08UL)); + + /* XXX iterate amongst the 4 IRQ controllers XXX */ + int_ctrlr = (1UL << 6); + + val = fire_read(imap_reg); + val |= (1UL << 63) | int_ctrlr; + fire_write(imap_reg, val); + + fixup = ((pbm->portid << 6) | devino) - int_ctrlr; + + virt_irq = build_irq(fixup, iclr_reg, imap_reg); + if (!virt_irq) + return -ENOMEM; + + fire_write(pbm->pbm_regs + + EVENT_QUEUE_CONTROL_SET(msiqid), + EVENT_QUEUE_CONTROL_SET_EN); + + return virt_irq; +} + +static const struct sparc64_msiq_ops pci_fire_msiq_ops = { + .get_head = pci_fire_get_head, + .dequeue_msi = pci_fire_dequeue_msi, + .set_head = pci_fire_set_head, + .msi_setup = pci_fire_msi_setup, + .msi_teardown = pci_fire_msi_teardown, + .msiq_alloc = pci_fire_msiq_alloc, + .msiq_free = pci_fire_msiq_free, + .msiq_build_irq = pci_fire_msiq_build_irq, +}; + +static void pci_fire_msi_init(struct pci_pbm_info *pbm) +{ + sparc64_pbm_msi_init(pbm, &pci_fire_msiq_ops); +} +#else /* CONFIG_PCI_MSI */ +static void pci_fire_msi_init(struct pci_pbm_info *pbm) +{ +} +#endif /* !(CONFIG_PCI_MSI) */ + /* Based at pbm->controller_regs */ #define FIRE_PARITY_CONTROL 0x470010UL #define FIRE_PARITY_ENAB 0x8000000000000000UL @@ -176,6 +439,7 @@ static int pci_fire_pbm_init(struct pci_controller_info *p, { const struct linux_prom64_registers *regs; struct pci_pbm_info *pbm; + int err; if ((portid & 1) == 0) pbm = &p->pbm_A; @@ -208,7 +472,13 @@ static int pci_fire_pbm_init(struct pci_controller_info *p, pci_fire_hw_init(pbm); - return pci_fire_pbm_iommu_init(pbm); + err = pci_fire_pbm_iommu_init(pbm); + if (err) + return err; + + pci_fire_msi_init(pbm); + + return 0; } static inline int portid_compare(u32 x, u32 y) @@ -249,13 +519,6 @@ void fire_pci_init(struct device_node *dp, const char *model_name) p->pbm_B.iommu = iommu; - /* XXX MSI support XXX */ - - /* Like PSYCHO and SCHIZO we have a 2GB aligned area - * for memory space. - */ - pci_memspace_mask = 0x7fffffffUL; - if (pci_fire_pbm_init(p, dp, portid)) goto fatal_memory_error; diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index f660c2b685eb..4a50da13ce48 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h @@ -29,6 +29,33 @@ #define PCI_STC_FLUSHFLAG_SET(STC) \ (*((STC)->strbuf_flushflag) != 0UL) +#ifdef CONFIG_PCI_MSI +struct pci_pbm_info; +struct sparc64_msiq_ops { + int (*get_head)(struct pci_pbm_info *pbm, unsigned long msiqid, + unsigned long *head); + int (*dequeue_msi)(struct pci_pbm_info *pbm, unsigned long msiqid, + unsigned long *head, unsigned long *msi); + int (*set_head)(struct pci_pbm_info *pbm, unsigned long msiqid, + unsigned long head); + int (*msi_setup)(struct pci_pbm_info *pbm, unsigned long msiqid, + unsigned long msi, int is_msi64); + int (*msi_teardown)(struct pci_pbm_info *pbm, unsigned long msi); + int (*msiq_alloc)(struct pci_pbm_info *pbm); + void (*msiq_free)(struct pci_pbm_info *pbm); + int (*msiq_build_irq)(struct pci_pbm_info *pbm, unsigned long msiqid, + unsigned long devino); +}; + +extern void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, + const struct sparc64_msiq_ops *ops); + +struct sparc64_msiq_cookie { + struct pci_pbm_info *pbm; + unsigned long msiqid; +}; +#endif + struct pci_controller_info; struct pci_pbm_info { @@ -90,6 +117,8 @@ struct pci_pbm_info { u32 msiq_ent_count; u32 msiq_first; u32 msiq_first_devino; + u32 msiq_rotor; + struct sparc64_msiq_cookie *msiq_irq_cookies; u32 msi_num; u32 msi_first; u32 msi_data_mask; @@ -100,9 +129,11 @@ struct pci_pbm_info { u32 msi64_len; void *msi_queues; unsigned long *msi_bitmap; + unsigned int *msi_irq_table; int (*setup_msi_irq)(unsigned int *virt_irq_p, struct pci_dev *pdev, struct msi_desc *entry); void (*teardown_msi_irq)(unsigned int virt_irq, struct pci_dev *pdev); + const struct sparc64_msiq_ops *msi_ops; #endif /* !(CONFIG_PCI_MSI) */ /* This PBM's streaming buffer. */ @@ -126,7 +157,6 @@ struct pci_controller_info { }; extern struct pci_pbm_info *pci_pbm_root; -extern unsigned long pci_memspace_mask; extern int pci_num_pbms; diff --git a/arch/sparc64/kernel/pci_msi.c b/arch/sparc64/kernel/pci_msi.c new file mode 100644 index 000000000000..31a165fd3e48 --- /dev/null +++ b/arch/sparc64/kernel/pci_msi.c @@ -0,0 +1,433 @@ +/* pci_msi.c: Sparc64 MSI support common layer. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/irq.h> + +#include "pci_impl.h" + +static irqreturn_t sparc64_msiq_interrupt(int irq, void *cookie) +{ + struct sparc64_msiq_cookie *msiq_cookie = cookie; + struct pci_pbm_info *pbm = msiq_cookie->pbm; + unsigned long msiqid = msiq_cookie->msiqid; + const struct sparc64_msiq_ops *ops; + unsigned long orig_head, head; + int err; + + ops = pbm->msi_ops; + + err = ops->get_head(pbm, msiqid, &head); + if (unlikely(err < 0)) + goto err_get_head; + + orig_head = head; + for (;;) { + unsigned long msi; + + err = ops->dequeue_msi(pbm, msiqid, &head, &msi); + if (likely(err > 0)) + __do_IRQ(pbm->msi_irq_table[msi - pbm->msi_first]); + + if (unlikely(err < 0)) + goto err_dequeue; + + if (err == 0) + break; + } + if (likely(head != orig_head)) { + err = ops->set_head(pbm, msiqid, head); + if (unlikely(err < 0)) + goto err_set_head; + } + return IRQ_HANDLED; + +err_get_head: + printk(KERN_EMERG "MSI: Get head on msiqid[%lu] gives error %d\n", + msiqid, err); + goto err_out; + +err_dequeue: + printk(KERN_EMERG "MSI: Dequeue head[%lu] from msiqid[%lu] " + "gives error %d\n", + head, msiqid, err); + goto err_out; + +err_set_head: + printk(KERN_EMERG "MSI: Set head[%lu] on msiqid[%lu] " + "gives error %d\n", + head, msiqid, err); + goto err_out; + +err_out: + return IRQ_NONE; +} + +static u32 pick_msiq(struct pci_pbm_info *pbm) +{ + static DEFINE_SPINLOCK(rotor_lock); + unsigned long flags; + u32 ret, rotor; + + spin_lock_irqsave(&rotor_lock, flags); + + rotor = pbm->msiq_rotor; + ret = pbm->msiq_first + rotor; + + if (++rotor >= pbm->msiq_num) + rotor = 0; + pbm->msiq_rotor = rotor; + + spin_unlock_irqrestore(&rotor_lock, flags); + + return ret; +} + + +static int alloc_msi(struct pci_pbm_info *pbm) +{ + int i; + + for (i = 0; i < pbm->msi_num; i++) { + if (!test_and_set_bit(i, pbm->msi_bitmap)) + return i + pbm->msi_first; + } + + return -ENOENT; +} + +static void free_msi(struct pci_pbm_info *pbm, int msi_num) +{ + msi_num -= pbm->msi_first; + clear_bit(msi_num, pbm->msi_bitmap); +} + +static struct irq_chip msi_irq = { + .typename = "PCI-MSI", + .mask = mask_msi_irq, + .unmask = unmask_msi_irq, + .enable = unmask_msi_irq, + .disable = mask_msi_irq, + /* XXX affinity XXX */ +}; + +int sparc64_setup_msi_irq(unsigned int *virt_irq_p, + struct pci_dev *pdev, + struct msi_desc *entry) +{ + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; + const struct sparc64_msiq_ops *ops = pbm->msi_ops; + struct msi_msg msg; + int msi, err; + u32 msiqid; + + *virt_irq_p = virt_irq_alloc(0, 0); + err = -ENOMEM; + if (!*virt_irq_p) + goto out_err; + + set_irq_chip(*virt_irq_p, &msi_irq); + + err = alloc_msi(pbm); + if (unlikely(err < 0)) + goto out_virt_irq_free; + + msi = err; + + msiqid = pick_msiq(pbm); + + err = ops->msi_setup(pbm, msiqid, msi, + (entry->msi_attrib.is_64 ? 1 : 0)); + if (err) + goto out_msi_free; + + pbm->msi_irq_table[msi - pbm->msi_first] = *virt_irq_p; + + if (entry->msi_attrib.is_64) { + msg.address_hi = pbm->msi64_start >> 32; + msg.address_lo = pbm->msi64_start & 0xffffffff; + } else { + msg.address_hi = 0; + msg.address_lo = pbm->msi32_start; + } + msg.data = msi; + + set_irq_msi(*virt_irq_p, entry); + write_msi_msg(*virt_irq_p, &msg); + + return 0; + +out_msi_free: + free_msi(pbm, msi); + +out_virt_irq_free: + set_irq_chip(*virt_irq_p, NULL); + virt_irq_free(*virt_irq_p); + *virt_irq_p = 0; + +out_err: + return err; +} + +void sparc64_teardown_msi_irq(unsigned int virt_irq, + struct pci_dev *pdev) +{ + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; + const struct sparc64_msiq_ops *ops = pbm->msi_ops; + unsigned int msi_num; + int i, err; + + for (i = 0; i < pbm->msi_num; i++) { + if (pbm->msi_irq_table[i] == virt_irq) + break; + } + if (i >= pbm->msi_num) { + printk(KERN_ERR "%s: teardown: No MSI for irq %u\n", + pbm->name, virt_irq); + return; + } + + msi_num = pbm->msi_first + i; + pbm->msi_irq_table[i] = ~0U; + + err = ops->msi_teardown(pbm, msi_num); + if (err) { + printk(KERN_ERR "%s: teardown: ops->teardown() on MSI %u, " + "irq %u, gives error %d\n", + pbm->name, msi_num, virt_irq, err); + return; + } + + free_msi(pbm, msi_num); + + set_irq_chip(virt_irq, NULL); + virt_irq_free(virt_irq); +} + +static int msi_bitmap_alloc(struct pci_pbm_info *pbm) +{ + unsigned long size, bits_per_ulong; + + bits_per_ulong = sizeof(unsigned long) * 8; + size = (pbm->msi_num + (bits_per_ulong - 1)) & ~(bits_per_ulong - 1); + size /= 8; + BUG_ON(size % sizeof(unsigned long)); + + pbm->msi_bitmap = kzalloc(size, GFP_KERNEL); + if (!pbm->msi_bitmap) + return -ENOMEM; + + return 0; +} + +static void msi_bitmap_free(struct pci_pbm_info *pbm) +{ + kfree(pbm->msi_bitmap); + pbm->msi_bitmap = NULL; +} + +static int msi_table_alloc(struct pci_pbm_info *pbm) +{ + int size, i; + + size = pbm->msiq_num * sizeof(struct sparc64_msiq_cookie); + pbm->msiq_irq_cookies = kzalloc(size, GFP_KERNEL); + if (!pbm->msiq_irq_cookies) + return -ENOMEM; + + for (i = 0; i < pbm->msiq_num; i++) { + struct sparc64_msiq_cookie *p; + + p = &pbm->msiq_irq_cookies[i]; + p->pbm = pbm; + p->msiqid = pbm->msiq_first + i; + } + + size = pbm->msi_num * sizeof(unsigned int); + pbm->msi_irq_table = kzalloc(size, GFP_KERNEL); + if (!pbm->msi_irq_table) { + kfree(pbm->msiq_irq_cookies); + pbm->msiq_irq_cookies = NULL; + return -ENOMEM; + } + + return 0; +} + +static void msi_table_free(struct pci_pbm_info *pbm) +{ + kfree(pbm->msiq_irq_cookies); + pbm->msiq_irq_cookies = NULL; + + kfree(pbm->msi_irq_table); + pbm->msi_irq_table = NULL; +} + +static int bringup_one_msi_queue(struct pci_pbm_info *pbm, + const struct sparc64_msiq_ops *ops, + unsigned long msiqid, + unsigned long devino) +{ + int irq = ops->msiq_build_irq(pbm, msiqid, devino); + int err; + + if (irq < 0) + return irq; + + err = request_irq(irq, sparc64_msiq_interrupt, 0, + "MSIQ", + &pbm->msiq_irq_cookies[msiqid - pbm->msiq_first]); + if (err) + return err; + + return 0; +} + +static int sparc64_bringup_msi_queues(struct pci_pbm_info *pbm, + const struct sparc64_msiq_ops *ops) +{ + int i; + + for (i = 0; i < pbm->msiq_num; i++) { + unsigned long msiqid = i + pbm->msiq_first; + unsigned long devino = i + pbm->msiq_first_devino; + int err; + + err = bringup_one_msi_queue(pbm, ops, msiqid, devino); + if (err) + return err; + } + + return 0; +} + +void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, + const struct sparc64_msiq_ops *ops) +{ + const u32 *val; + int len; + + val = of_get_property(pbm->prom_node, "#msi-eqs", &len); + if (!val || len != 4) + goto no_msi; + pbm->msiq_num = *val; + if (pbm->msiq_num) { + const struct msiq_prop { + u32 first_msiq; + u32 num_msiq; + u32 first_devino; + } *mqp; + const struct msi_range_prop { + u32 first_msi; + u32 num_msi; + } *mrng; + const struct addr_range_prop { + u32 msi32_high; + u32 msi32_low; + u32 msi32_len; + u32 msi64_high; + u32 msi64_low; + u32 msi64_len; + } *arng; + + val = of_get_property(pbm->prom_node, "msi-eq-size", &len); + if (!val || len != 4) + goto no_msi; + + pbm->msiq_ent_count = *val; + + mqp = of_get_property(pbm->prom_node, + "msi-eq-to-devino", &len); + if (!mqp) + mqp = of_get_property(pbm->prom_node, + "msi-eq-devino", &len); + if (!mqp || len != sizeof(struct msiq_prop)) + goto no_msi; + + pbm->msiq_first = mqp->first_msiq; + pbm->msiq_first_devino = mqp->first_devino; + + val = of_get_property(pbm->prom_node, "#msi", &len); + if (!val || len != 4) + goto no_msi; + pbm->msi_num = *val; + + mrng = of_get_property(pbm->prom_node, "msi-ranges", &len); + if (!mrng || len != sizeof(struct msi_range_prop)) + goto no_msi; + pbm->msi_first = mrng->first_msi; + + val = of_get_property(pbm->prom_node, "msi-data-mask", &len); + if (!val || len != 4) + goto no_msi; + pbm->msi_data_mask = *val; + + val = of_get_property(pbm->prom_node, "msix-data-width", &len); + if (!val || len != 4) + goto no_msi; + pbm->msix_data_width = *val; + + arng = of_get_property(pbm->prom_node, "msi-address-ranges", + &len); + if (!arng || len != sizeof(struct addr_range_prop)) + goto no_msi; + pbm->msi32_start = ((u64)arng->msi32_high << 32) | + (u64) arng->msi32_low; + pbm->msi64_start = ((u64)arng->msi64_high << 32) | + (u64) arng->msi64_low; + pbm->msi32_len = arng->msi32_len; + pbm->msi64_len = arng->msi64_len; + + if (msi_bitmap_alloc(pbm)) + goto no_msi; + + if (msi_table_alloc(pbm)) { + msi_bitmap_free(pbm); + goto no_msi; + } + + if (ops->msiq_alloc(pbm)) { + msi_table_free(pbm); + msi_bitmap_free(pbm); + goto no_msi; + } + + if (sparc64_bringup_msi_queues(pbm, ops)) { + ops->msiq_free(pbm); + msi_table_free(pbm); + msi_bitmap_free(pbm); + goto no_msi; + } + + printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] " + "devino[0x%x]\n", + pbm->name, + pbm->msiq_first, pbm->msiq_num, + pbm->msiq_ent_count, + pbm->msiq_first_devino); + printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] " + "width[%u]\n", + pbm->name, + pbm->msi_first, pbm->msi_num, pbm->msi_data_mask, + pbm->msix_data_width); + printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] " + "addr64[0x%lx:0x%x]\n", + pbm->name, + pbm->msi32_start, pbm->msi32_len, + pbm->msi64_start, pbm->msi64_len); + printk(KERN_INFO "%s: MSI queues at RA [%016lx]\n", + pbm->name, + __pa(pbm->msi_queues)); + + pbm->msi_ops = ops; + pbm->setup_msi_irq = sparc64_setup_msi_irq; + pbm->teardown_msi_irq = sparc64_teardown_msi_irq; + } + return; + +no_msi: + pbm->msiq_num = 0; + printk(KERN_INFO "%s: No MSI support.\n", pbm->name); +} diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index b6b4cfea5b5f..d27ee5d528a2 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1058,12 +1058,6 @@ void psycho_init(struct device_node *dp, char *model_name) p->pbm_A.config_space = p->pbm_B.config_space = (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE); - /* - * Psycho's PCI MEM space is mapped to a 2GB aligned area, so - * we need to adjust our MEM space mask. - */ - pci_memspace_mask = 0x7fffffffUL; - psycho_controller_hwinit(&p->pbm_A); if (psycho_iommu_init(&p->pbm_A)) diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 3c30bfa1f3a3..9546ba9f5dee 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1464,9 +1464,6 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ p->pbm_B.iommu = iommu; - /* Like PSYCHO we have a 2GB aligned area for memory space. */ - pci_memspace_mask = 0x7fffffffUL; - if (schizo_pbm_init(p, dp, portid, chip_type)) goto fatal_memory_error; diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index da724b13e89e..cacacfae5451 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -13,6 +13,7 @@ #include <linux/irq.h> #include <linux/msi.h> #include <linux/log2.h> +#include <linux/scatterlist.h> #include <asm/iommu.h> #include <asm/irq.h> @@ -373,7 +374,7 @@ static inline long fill_sg(long entry, struct device *dev, int nused, int nelems, unsigned long prot) { struct scatterlist *dma_sg = sg; - struct scatterlist *sg_end = sg + nelems; + struct scatterlist *sg_end = sg_last(sg, nelems); unsigned long flags; int i; @@ -413,7 +414,7 @@ static inline long fill_sg(long entry, struct device *dev, len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL))); break; } - sg++; + sg = sg_next(sg); } pteval = (pteval & IOPTE_PAGE); @@ -431,24 +432,25 @@ static inline long fill_sg(long entry, struct device *dev, } pteval = (pteval & IOPTE_PAGE) + len; - sg++; + sg = sg_next(sg); /* Skip over any tail mappings we've fully mapped, * adjusting pteval along the way. Stop when we * detect a page crossing event. */ - while (sg < sg_end && - (pteval << (64 - IO_PAGE_SHIFT)) != 0UL && + while ((pteval << (64 - IO_PAGE_SHIFT)) != 0UL && (pteval == SG_ENT_PHYS_ADDRESS(sg)) && ((pteval ^ (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { pteval += sg->length; - sg++; + if (sg == sg_end) + break; + sg = sg_next(sg); } if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) pteval = ~0UL; } while (dma_npages != 0); - dma_sg++; + dma_sg = sg_next(dma_sg); } if (unlikely(iommu_batch_end() < 0L)) @@ -510,7 +512,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, sgtmp = sglist; while (used && sgtmp->dma_length) { sgtmp->dma_address += dma_base; - sgtmp++; + sgtmp = sg_next(sgtmp); used--; } used = nelems - used; @@ -545,6 +547,7 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, struct pci_pbm_info *pbm; struct iommu *iommu; unsigned long flags, i, npages; + struct scatterlist *sg, *sgprv; long entry; u32 devhandle, bus_addr; @@ -558,12 +561,15 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, devhandle = pbm->devhandle; bus_addr = sglist->dma_address & IO_PAGE_MASK; - - for (i = 1; i < nelems; i++) - if (sglist[i].dma_length == 0) + sgprv = NULL; + for_each_sg(sglist, sg, nelems, i) { + if (sg->dma_length == 0) break; - i--; - npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - + + sgprv = sg; + } + + npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) - bus_addr) >> IO_PAGE_SHIFT; entry = ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); @@ -748,111 +754,102 @@ struct pci_sun4v_msiq_entry { u64 reserved2; }; -/* For now this just runs as a pre-handler for the real interrupt handler. - * So we just walk through the queue and ACK all the entries, update the - * head pointer, and return. - * - * In the longer term it would be nice to do something more integrated - * wherein we can pass in some of this MSI info to the drivers. This - * would be most useful for PCIe fabric error messages, although we could - * invoke those directly from the loop here in order to pass the info around. - */ -static void pci_sun4v_msi_prehandler(unsigned int ino, void *data1, void *data2) +static int pci_sun4v_get_head(struct pci_pbm_info *pbm, unsigned long msiqid, + unsigned long *head) { - struct pci_pbm_info *pbm = data1; - struct pci_sun4v_msiq_entry *base, *ep; - unsigned long msiqid, orig_head, head, type, err; - - msiqid = (unsigned long) data2; + unsigned long err, limit; - head = 0xdeadbeef; - err = pci_sun4v_msiq_gethead(pbm->devhandle, msiqid, &head); + err = pci_sun4v_msiq_gethead(pbm->devhandle, msiqid, head); if (unlikely(err)) - goto hv_error_get; - - if (unlikely(head >= (pbm->msiq_ent_count * sizeof(struct pci_sun4v_msiq_entry)))) - goto bad_offset; - - head /= sizeof(struct pci_sun4v_msiq_entry); - orig_head = head; - base = (pbm->msi_queues + ((msiqid - pbm->msiq_first) * - (pbm->msiq_ent_count * - sizeof(struct pci_sun4v_msiq_entry)))); - ep = &base[head]; - while ((ep->version_type & MSIQ_TYPE_MASK) != 0) { - type = (ep->version_type & MSIQ_TYPE_MASK) >> MSIQ_TYPE_SHIFT; - if (unlikely(type != MSIQ_TYPE_MSI32 && - type != MSIQ_TYPE_MSI64)) - goto bad_type; - - pci_sun4v_msi_setstate(pbm->devhandle, - ep->msi_data /* msi_num */, - HV_MSISTATE_IDLE); - - /* Clear the entry. */ - ep->version_type &= ~MSIQ_TYPE_MASK; - - /* Go to next entry in ring. */ - head++; - if (head >= pbm->msiq_ent_count) - head = 0; - ep = &base[head]; - } + return -ENXIO; - if (likely(head != orig_head)) { - /* ACK entries by updating head pointer. */ - head *= sizeof(struct pci_sun4v_msiq_entry); - err = pci_sun4v_msiq_sethead(pbm->devhandle, msiqid, head); - if (unlikely(err)) - goto hv_error_set; - } - return; + limit = pbm->msiq_ent_count * sizeof(struct pci_sun4v_msiq_entry); + if (unlikely(*head >= limit)) + return -EFBIG; -hv_error_set: - printk(KERN_EMERG "MSI: Hypervisor set head gives error %lu\n", err); - goto hv_error_cont; + return 0; +} -hv_error_get: - printk(KERN_EMERG "MSI: Hypervisor get head gives error %lu\n", err); +static int pci_sun4v_dequeue_msi(struct pci_pbm_info *pbm, + unsigned long msiqid, unsigned long *head, + unsigned long *msi) +{ + struct pci_sun4v_msiq_entry *ep; + unsigned long err, type; -hv_error_cont: - printk(KERN_EMERG "MSI: devhandle[%x] msiqid[%lx] head[%lu]\n", - pbm->devhandle, msiqid, head); - return; + /* Note: void pointer arithmetic, 'head' is a byte offset */ + ep = (pbm->msi_queues + ((msiqid - pbm->msiq_first) * + (pbm->msiq_ent_count * + sizeof(struct pci_sun4v_msiq_entry))) + + *head); -bad_offset: - printk(KERN_EMERG "MSI: Hypervisor gives bad offset %lx max(%lx)\n", - head, pbm->msiq_ent_count * sizeof(struct pci_sun4v_msiq_entry)); - return; + if ((ep->version_type & MSIQ_TYPE_MASK) == 0) + return 0; -bad_type: - printk(KERN_EMERG "MSI: Entry has bad type %lx\n", type); - return; + type = (ep->version_type & MSIQ_TYPE_MASK) >> MSIQ_TYPE_SHIFT; + if (unlikely(type != MSIQ_TYPE_MSI32 && + type != MSIQ_TYPE_MSI64)) + return -EINVAL; + + *msi = ep->msi_data; + + err = pci_sun4v_msi_setstate(pbm->devhandle, + ep->msi_data /* msi_num */, + HV_MSISTATE_IDLE); + if (unlikely(err)) + return -ENXIO; + + /* Clear the entry. */ + ep->version_type &= ~MSIQ_TYPE_MASK; + + (*head) += sizeof(struct pci_sun4v_msiq_entry); + if (*head >= + (pbm->msiq_ent_count * sizeof(struct pci_sun4v_msiq_entry))) + *head = 0; + + return 1; } -static int msi_bitmap_alloc(struct pci_pbm_info *pbm) +static int pci_sun4v_set_head(struct pci_pbm_info *pbm, unsigned long msiqid, + unsigned long head) { - unsigned long size, bits_per_ulong; + unsigned long err; - bits_per_ulong = sizeof(unsigned long) * 8; - size = (pbm->msi_num + (bits_per_ulong - 1)) & ~(bits_per_ulong - 1); - size /= 8; - BUG_ON(size % sizeof(unsigned long)); + err = pci_sun4v_msiq_sethead(pbm->devhandle, msiqid, head); + if (unlikely(err)) + return -EINVAL; - pbm->msi_bitmap = kzalloc(size, GFP_KERNEL); - if (!pbm->msi_bitmap) - return -ENOMEM; + return 0; +} +static int pci_sun4v_msi_setup(struct pci_pbm_info *pbm, unsigned long msiqid, + unsigned long msi, int is_msi64) +{ + if (pci_sun4v_msi_setmsiq(pbm->devhandle, msi, msiqid, + (is_msi64 ? + HV_MSITYPE_MSI64 : HV_MSITYPE_MSI32))) + return -ENXIO; + if (pci_sun4v_msi_setstate(pbm->devhandle, msi, HV_MSISTATE_IDLE)) + return -ENXIO; + if (pci_sun4v_msi_setvalid(pbm->devhandle, msi, HV_MSIVALID_VALID)) + return -ENXIO; return 0; } -static void msi_bitmap_free(struct pci_pbm_info *pbm) +static int pci_sun4v_msi_teardown(struct pci_pbm_info *pbm, unsigned long msi) { - kfree(pbm->msi_bitmap); - pbm->msi_bitmap = NULL; + unsigned long err, msiqid; + + err = pci_sun4v_msi_getmsiq(pbm->devhandle, msi, &msiqid); + if (err) + return -ENXIO; + + pci_sun4v_msi_setvalid(pbm->devhandle, msi, HV_MSIVALID_INVALID); + + return 0; } -static int msi_queue_alloc(struct pci_pbm_info *pbm) +static int pci_sun4v_msiq_alloc(struct pci_pbm_info *pbm) { unsigned long q_size, alloc_size, pages, order; int i; @@ -906,232 +903,59 @@ h_error: return -EINVAL; } - -static int alloc_msi(struct pci_pbm_info *pbm) +static void pci_sun4v_msiq_free(struct pci_pbm_info *pbm) { + unsigned long q_size, alloc_size, pages, order; int i; - for (i = 0; i < pbm->msi_num; i++) { - if (!test_and_set_bit(i, pbm->msi_bitmap)) - return i + pbm->msi_first; - } - - return -ENOENT; -} - -static void free_msi(struct pci_pbm_info *pbm, int msi_num) -{ - msi_num -= pbm->msi_first; - clear_bit(msi_num, pbm->msi_bitmap); -} - -static int pci_sun4v_setup_msi_irq(unsigned int *virt_irq_p, - struct pci_dev *pdev, - struct msi_desc *entry) -{ - struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; - unsigned long devino, msiqid; - struct msi_msg msg; - int msi_num, err; - - *virt_irq_p = 0; - - msi_num = alloc_msi(pbm); - if (msi_num < 0) - return msi_num; - - err = sun4v_build_msi(pbm->devhandle, virt_irq_p, - pbm->msiq_first_devino, - (pbm->msiq_first_devino + - pbm->msiq_num)); - if (err < 0) - goto out_err; - devino = err; - - msiqid = ((devino - pbm->msiq_first_devino) + - pbm->msiq_first); - - err = -EINVAL; - if (pci_sun4v_msiq_setstate(pbm->devhandle, msiqid, HV_MSIQSTATE_IDLE)) - if (err) - goto out_err; - - if (pci_sun4v_msiq_setvalid(pbm->devhandle, msiqid, HV_MSIQ_VALID)) - goto out_err; - - if (pci_sun4v_msi_setmsiq(pbm->devhandle, - msi_num, msiqid, - (entry->msi_attrib.is_64 ? - HV_MSITYPE_MSI64 : HV_MSITYPE_MSI32))) - goto out_err; - - if (pci_sun4v_msi_setstate(pbm->devhandle, msi_num, HV_MSISTATE_IDLE)) - goto out_err; - - if (pci_sun4v_msi_setvalid(pbm->devhandle, msi_num, HV_MSIVALID_VALID)) - goto out_err; - - sparc64_set_msi(*virt_irq_p, msi_num); + for (i = 0; i < pbm->msiq_num; i++) { + unsigned long msiqid = pbm->msiq_first + i; - if (entry->msi_attrib.is_64) { - msg.address_hi = pbm->msi64_start >> 32; - msg.address_lo = pbm->msi64_start & 0xffffffff; - } else { - msg.address_hi = 0; - msg.address_lo = pbm->msi32_start; + (void) pci_sun4v_msiq_conf(pbm->devhandle, msiqid, 0UL, 0); } - msg.data = msi_num; - set_irq_msi(*virt_irq_p, entry); - write_msi_msg(*virt_irq_p, &msg); - - irq_install_pre_handler(*virt_irq_p, - pci_sun4v_msi_prehandler, - pbm, (void *) msiqid); + q_size = pbm->msiq_ent_count * sizeof(struct pci_sun4v_msiq_entry); + alloc_size = (pbm->msiq_num * q_size); + order = get_order(alloc_size); - return 0; + pages = (unsigned long) pbm->msi_queues; -out_err: - free_msi(pbm, msi_num); - return err; + free_pages(pages, order); + pbm->msi_queues = NULL; } -static void pci_sun4v_teardown_msi_irq(unsigned int virt_irq, - struct pci_dev *pdev) +static int pci_sun4v_msiq_build_irq(struct pci_pbm_info *pbm, + unsigned long msiqid, + unsigned long devino) { - struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; - unsigned long msiqid, err; - unsigned int msi_num; - - msi_num = sparc64_get_msi(virt_irq); - err = pci_sun4v_msi_getmsiq(pbm->devhandle, msi_num, &msiqid); - if (err) { - printk(KERN_ERR "%s: getmsiq gives error %lu\n", - pbm->name, err); - return; - } + unsigned int virt_irq = sun4v_build_irq(pbm->devhandle, devino); - pci_sun4v_msi_setvalid(pbm->devhandle, msi_num, HV_MSIVALID_INVALID); - pci_sun4v_msiq_setvalid(pbm->devhandle, msiqid, HV_MSIQ_INVALID); + if (!virt_irq) + return -ENOMEM; - free_msi(pbm, msi_num); + if (pci_sun4v_msiq_setstate(pbm->devhandle, msiqid, HV_MSIQSTATE_IDLE)) + return -EINVAL; + if (pci_sun4v_msiq_setvalid(pbm->devhandle, msiqid, HV_MSIQ_VALID)) + return -EINVAL; - /* The sun4v_destroy_msi() will liberate the devino and thus the MSIQ - * allocation. - */ - sun4v_destroy_msi(virt_irq); + return virt_irq; } +static const struct sparc64_msiq_ops pci_sun4v_msiq_ops = { + .get_head = pci_sun4v_get_head, + .dequeue_msi = pci_sun4v_dequeue_msi, + .set_head = pci_sun4v_set_head, + .msi_setup = pci_sun4v_msi_setup, + .msi_teardown = pci_sun4v_msi_teardown, + .msiq_alloc = pci_sun4v_msiq_alloc, + .msiq_free = pci_sun4v_msiq_free, + .msiq_build_irq = pci_sun4v_msiq_build_irq, +}; + static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) { - const u32 *val; - int len; - - val = of_get_property(pbm->prom_node, "#msi-eqs", &len); - if (!val || len != 4) - goto no_msi; - pbm->msiq_num = *val; - if (pbm->msiq_num) { - const struct msiq_prop { - u32 first_msiq; - u32 num_msiq; - u32 first_devino; - } *mqp; - const struct msi_range_prop { - u32 first_msi; - u32 num_msi; - } *mrng; - const struct addr_range_prop { - u32 msi32_high; - u32 msi32_low; - u32 msi32_len; - u32 msi64_high; - u32 msi64_low; - u32 msi64_len; - } *arng; - - val = of_get_property(pbm->prom_node, "msi-eq-size", &len); - if (!val || len != 4) - goto no_msi; - - pbm->msiq_ent_count = *val; - - mqp = of_get_property(pbm->prom_node, - "msi-eq-to-devino", &len); - if (!mqp || len != sizeof(struct msiq_prop)) - goto no_msi; - - pbm->msiq_first = mqp->first_msiq; - pbm->msiq_first_devino = mqp->first_devino; - - val = of_get_property(pbm->prom_node, "#msi", &len); - if (!val || len != 4) - goto no_msi; - pbm->msi_num = *val; - - mrng = of_get_property(pbm->prom_node, "msi-ranges", &len); - if (!mrng || len != sizeof(struct msi_range_prop)) - goto no_msi; - pbm->msi_first = mrng->first_msi; - - val = of_get_property(pbm->prom_node, "msi-data-mask", &len); - if (!val || len != 4) - goto no_msi; - pbm->msi_data_mask = *val; - - val = of_get_property(pbm->prom_node, "msix-data-width", &len); - if (!val || len != 4) - goto no_msi; - pbm->msix_data_width = *val; - - arng = of_get_property(pbm->prom_node, "msi-address-ranges", - &len); - if (!arng || len != sizeof(struct addr_range_prop)) - goto no_msi; - pbm->msi32_start = ((u64)arng->msi32_high << 32) | - (u64) arng->msi32_low; - pbm->msi64_start = ((u64)arng->msi64_high << 32) | - (u64) arng->msi64_low; - pbm->msi32_len = arng->msi32_len; - pbm->msi64_len = arng->msi64_len; - - if (msi_bitmap_alloc(pbm)) - goto no_msi; - - if (msi_queue_alloc(pbm)) { - msi_bitmap_free(pbm); - goto no_msi; - } - - printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] " - "devino[0x%x]\n", - pbm->name, - pbm->msiq_first, pbm->msiq_num, - pbm->msiq_ent_count, - pbm->msiq_first_devino); - printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] " - "width[%u]\n", - pbm->name, - pbm->msi_first, pbm->msi_num, pbm->msi_data_mask, - pbm->msix_data_width); - printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] " - "addr64[0x%lx:0x%x]\n", - pbm->name, - pbm->msi32_start, pbm->msi32_len, - pbm->msi64_start, pbm->msi64_len); - printk(KERN_INFO "%s: MSI queues at RA [%p]\n", - pbm->name, - pbm->msi_queues); - } - pbm->setup_msi_irq = pci_sun4v_setup_msi_irq; - pbm->teardown_msi_irq = pci_sun4v_teardown_msi_irq; - - return; - -no_msi: - pbm->msiq_num = 0; - printk(KERN_INFO "%s: No MSI support.\n", pbm->name); + sparc64_pbm_msi_init(pbm, &pci_sun4v_msiq_ops); } #else /* CONFIG_PCI_MSI */ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) @@ -1237,11 +1061,6 @@ void __init sun4v_pci_init(struct device_node *dp, char *model_name) p->pbm_B.iommu = iommu; - /* Like PSYCHO and SCHIZO we have a 2GB aligned area - * for memory space. - */ - pci_memspace_mask = 0x7fffffffUL; - pci_sun4v_pbm_init(p, dp, devhandle); return; diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index 881a09ee4c4c..850cdffdd69c 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c @@ -105,9 +105,11 @@ static struct of_device_id power_match[] = { }; static struct of_platform_driver power_driver = { - .name = "power", .match_table = power_match, .probe = power_probe, + .driver = { + .name = "power", + }, }; void __init power_init(void) diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index c73b7a48b036..407d74a8a542 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -52,14 +52,13 @@ int sparc64_multi_core __read_mostly; cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE; cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; -cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly = - { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; +DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = 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_PER_CPU_SYMBOL(cpu_sibling_map); EXPORT_SYMBOL(cpu_core_map); static cpumask_t smp_commenced_mask; @@ -1261,16 +1260,16 @@ void __devinit smp_fill_in_sib_core_maps(void) for_each_present_cpu(i) { unsigned int j; - cpus_clear(cpu_sibling_map[i]); + cpus_clear(per_cpu(cpu_sibling_map, i)); if (cpu_data(i).proc_id == -1) { - cpu_set(i, cpu_sibling_map[i]); + cpu_set(i, per_cpu(cpu_sibling_map, i)); continue; } for_each_present_cpu(j) { if (cpu_data(i).proc_id == cpu_data(j).proc_id) - cpu_set(j, cpu_sibling_map[i]); + cpu_set(j, per_cpu(cpu_sibling_map, i)); } } } @@ -1342,9 +1341,9 @@ int __cpu_disable(void) 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]); + for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu)) + cpu_clear(cpu, per_cpu(cpu_sibling_map, i)); + cpus_clear(per_cpu(cpu_sibling_map, cpu)); c = &cpu_data(cpu); diff --git a/arch/sparc64/kernel/sun4v_ivec.S b/arch/sparc64/kernel/sun4v_ivec.S index 574bc248bca6..e2f8e1b4882a 100644 --- a/arch/sparc64/kernel/sun4v_ivec.S +++ b/arch/sparc64/kernel/sun4v_ivec.S @@ -96,19 +96,21 @@ sun4v_dev_mondo: stxa %g2, [%g4] ASI_QUEUE membar #Sync - /* Get &__irq_work[smp_processor_id()] into %g1. */ - TRAP_LOAD_IRQ_WORK(%g1, %g4) + TRAP_LOAD_IRQ_WORK_PA(%g1, %g4) - /* Get &ivector_table[IVEC] into %g4. */ - sethi %hi(ivector_table), %g4 - sllx %g3, 3, %g3 - or %g4, %lo(ivector_table), %g4 + /* For VIRQs, cookie is encoded as ~bucket_phys_addr */ + brlz,pt %g3, 1f + xnor %g3, %g0, %g4 + + /* Get __pa(&ivector_table[IVEC]) into %g4. */ + sethi %hi(ivector_table_pa), %g4 + ldx [%g4 + %lo(ivector_table_pa)], %g4 + sllx %g3, 4, %g3 add %g4, %g3, %g4 - /* Insert ivector_table[] entry into __irq_work[] queue. */ - lduw [%g1], %g2 /* g2 = irq_work(cpu) */ - stw %g2, [%g4 + 0x00] /* bucket->irq_chain = g2 */ - stw %g4, [%g1] /* irq_work(cpu) = bucket */ +1: ldx [%g1], %g2 + stxa %g2, [%g4] ASI_PHYS_USE_EC + stx %g4, [%g1] /* Signal the interrupt by setting (1 << pil) in %softint. */ wr %g0, 1 << PIL_DEVICE_IRQ, %set_softint diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index d108eeb0734f..0d5c50264945 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -436,7 +436,7 @@ out: asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, unsigned long third, void __user *ptr, long fifth) { - int err; + long err; /* No need for backward compatibility. We can start fresh... */ if (call <= SEMCTL) { @@ -453,16 +453,9 @@ asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, err = sys_semget(first, (int)second, (int)third); goto out; case SEMCTL: { - union semun fourth; - err = -EINVAL; - if (!ptr) - goto out; - err = -EFAULT; - if (get_user(fourth.__pad, - (void __user * __user *) ptr)) - goto out; - err = sys_semctl(first, (int)second | IPC_64, - (int)third, fourth); + err = sys_semctl(first, third, + (int)second | IPC_64, + (union semun) ptr); goto out; } default: diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 69cad1b653c1..cd8c740cba1d 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -764,9 +764,11 @@ static struct of_device_id clock_match[] = { }; static struct of_platform_driver clock_driver = { - .name = "clock", .match_table = clock_match, .probe = clock_probe, + .driver = { + .name = "clock", + }, }; static int __init clock_init(void) diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 6ef42b8e53d8..34573a55b6e5 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -2569,8 +2569,8 @@ void __init trap_init(void) offsetof(struct trap_per_cpu, tsb_huge)) || (TRAP_PER_CPU_TSB_HUGE_TEMP != offsetof(struct trap_per_cpu, tsb_huge_temp)) || - (TRAP_PER_CPU_IRQ_WORKLIST != - offsetof(struct trap_per_cpu, irq_worklist)) || + (TRAP_PER_CPU_IRQ_WORKLIST_PA != + offsetof(struct trap_per_cpu, irq_worklist_pa)) || (TRAP_PER_CPU_CPU_MONDO_QMASK != offsetof(struct trap_per_cpu, cpu_mondo_qmask)) || (TRAP_PER_CPU_DEV_MONDO_QMASK != diff --git a/arch/sparc64/kernel/us2e_cpufreq.c b/arch/sparc64/kernel/us2e_cpufreq.c index 1f83fe6a82d6..791c15138f3a 100644 --- a/arch/sparc64/kernel/us2e_cpufreq.c +++ b/arch/sparc64/kernel/us2e_cpufreq.c @@ -326,7 +326,6 @@ static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) table[2].index = 5; table[3].frequency = CPUFREQ_TABLE_END; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 0; policy->cur = clock_tick; diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S index b982fa3dd748..9fcd503bc04a 100644 --- a/arch/sparc64/kernel/vmlinux.lds.S +++ b/arch/sparc64/kernel/vmlinux.lds.S @@ -10,105 +10,138 @@ ENTRY(_start) jiffies = jiffies_64; SECTIONS { - swapper_low_pmd_dir = 0x0000000000402000; - . = 0x4000; - .text 0x0000000000404000 : - { - _text = .; - TEXT_TEXT - SCHED_TEXT - LOCK_TEXT - KPROBES_TEXT - *(.gnu.warning) - } =0 - _etext = .; - PROVIDE (etext = .); + swapper_low_pmd_dir = 0x0000000000402000; + . = 0x4000; + .text 0x0000000000404000 : { + _text = .; + TEXT_TEXT + SCHED_TEXT + LOCK_TEXT + KPROBES_TEXT + *(.gnu.warning) + } = 0 + _etext = .; + PROVIDE (etext = .); - RO_DATA(PAGE_SIZE) + RO_DATA(PAGE_SIZE) + .data : { + DATA_DATA + CONSTRUCTORS + } + .data1 : { + *(.data1) + } + . = ALIGN(64); + .data.cacheline_aligned : { + *(.data.cacheline_aligned) + } + . = ALIGN(64); + .data.read_mostly : { + *(.data.read_mostly) + } + _edata = .; + PROVIDE (edata = .); + .fixup : { + *(.fixup) + } + . = ALIGN(16); + __ex_table : { + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } + NOTES - .data : - { - DATA_DATA - CONSTRUCTORS - } - .data1 : { *(.data1) } - . = ALIGN(64); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - . = ALIGN(64); - .data.read_mostly : { *(.data.read_mostly) } - _edata = .; - PROVIDE (edata = .); - .fixup : { *(.fixup) } + . = ALIGN(PAGE_SIZE); + .init.text : { + __init_begin = .; + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { + *(.init.data) + } + . = ALIGN(16); + .init.setup : { + __setup_start = .; + *(.init.setup) + __setup_end = .; + } + .initcall.init : { + __initcall_start = .; + INITCALLS + __initcall_end = .; + } + .con_initcall.init : { + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + } + SECURITY_INIT - . = ALIGN(16); - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; + . = ALIGN(4); + .tsb_ldquad_phys_patch : { + __tsb_ldquad_phys_patch = .; + *(.tsb_ldquad_phys_patch) + __tsb_ldquad_phys_patch_end = .; + } - NOTES + .tsb_phys_patch : { + __tsb_phys_patch = .; + *(.tsb_phys_patch) + __tsb_phys_patch_end = .; + } - . = ALIGN(PAGE_SIZE); - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - .init.data : { *(.init.data) } - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __initcall_start = .; - .initcall.init : { - INITCALLS - } - __initcall_end = .; - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - SECURITY_INIT - . = ALIGN(4); - __tsb_ldquad_phys_patch = .; - .tsb_ldquad_phys_patch : { *(.tsb_ldquad_phys_patch) } - __tsb_ldquad_phys_patch_end = .; - __tsb_phys_patch = .; - .tsb_phys_patch : { *(.tsb_phys_patch) } - __tsb_phys_patch_end = .; - __cpuid_patch = .; - .cpuid_patch : { *(.cpuid_patch) } - __cpuid_patch_end = .; - __sun4v_1insn_patch = .; - .sun4v_1insn_patch : { *(.sun4v_1insn_patch) } - __sun4v_1insn_patch_end = .; - __sun4v_2insn_patch = .; - .sun4v_2insn_patch : { *(.sun4v_2insn_patch) } - __sun4v_2insn_patch_end = .; + .cpuid_patch : { + __cpuid_patch = .; + *(.cpuid_patch) + __cpuid_patch_end = .; + } + + .sun4v_1insn_patch : { + __sun4v_1insn_patch = .; + *(.sun4v_1insn_patch) + __sun4v_1insn_patch_end = .; + } + .sun4v_2insn_patch : { + __sun4v_2insn_patch = .; + *(.sun4v_2insn_patch) + __sun4v_2insn_patch_end = .; + } #ifdef CONFIG_BLK_DEV_INITRD - . = ALIGN(PAGE_SIZE); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; + . = ALIGN(PAGE_SIZE); + .init.ramfs : { + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + } #endif - PERCPU(PAGE_SIZE) + PERCPU(PAGE_SIZE) - . = ALIGN(PAGE_SIZE); - __init_end = .; - __bss_start = .; - .sbss : { *(.sbss) *(.scommon) } - .bss : - { - *(.dynbss) - *(.bss) - *(COMMON) - } - _end = . ; - PROVIDE (end = .); - /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } + . = ALIGN(PAGE_SIZE); + __init_end = .; + __bss_start = .; + .sbss : { + *(.sbss) + *(.scommon) + } + .bss : { + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); - STABS_DEBUG + /DISCARD/ : { + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + } - DWARF_DEBUG + STABS_DEBUG + DWARF_DEBUG } diff --git a/arch/sparc64/lib/xor.S b/arch/sparc64/lib/xor.S index a79c8888170d..f44f58f40234 100644 --- a/arch/sparc64/lib/xor.S +++ b/arch/sparc64/lib/xor.S @@ -491,12 +491,12 @@ xor_niagara_4: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3 */ ldda [%i1 + 0x10] %asi, %i2 /* %i2/%i3 = src1 + 0x10 */ xor %g2, %i4, %g2 xor %g3, %i5, %g3 - ldda [%i7 + 0x10] %asi, %i4 /* %i4/%i5 = src2 + 0x10 */ + ldda [%l7 + 0x10] %asi, %i4 /* %i4/%i5 = src2 + 0x10 */ xor %l0, %g2, %l0 xor %l1, %g3, %l1 stxa %l0, [%i0 + 0x00] %asi stxa %l1, [%i0 + 0x08] %asi - ldda [%i6 + 0x10] %asi, %g2 /* %g2/%g3 = src3 + 0x10 */ + ldda [%l6 + 0x10] %asi, %g2 /* %g2/%g3 = src3 + 0x10 */ ldda [%i0 + 0x10] %asi, %l0 /* %l0/%l1 = dest + 0x10 */ xor %i4, %i2, %i4 @@ -504,12 +504,12 @@ xor_niagara_4: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3 */ ldda [%i1 + 0x20] %asi, %i2 /* %i2/%i3 = src1 + 0x20 */ xor %g2, %i4, %g2 xor %g3, %i5, %g3 - ldda [%i7 + 0x20] %asi, %i4 /* %i4/%i5 = src2 + 0x20 */ + ldda [%l7 + 0x20] %asi, %i4 /* %i4/%i5 = src2 + 0x20 */ xor %l0, %g2, %l0 xor %l1, %g3, %l1 stxa %l0, [%i0 + 0x10] %asi stxa %l1, [%i0 + 0x18] %asi - ldda [%i6 + 0x20] %asi, %g2 /* %g2/%g3 = src3 + 0x20 */ + ldda [%l6 + 0x20] %asi, %g2 /* %g2/%g3 = src3 + 0x20 */ ldda [%i0 + 0x20] %asi, %l0 /* %l0/%l1 = dest + 0x20 */ xor %i4, %i2, %i4 @@ -517,12 +517,12 @@ xor_niagara_4: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3 */ ldda [%i1 + 0x30] %asi, %i2 /* %i2/%i3 = src1 + 0x30 */ xor %g2, %i4, %g2 xor %g3, %i5, %g3 - ldda [%i7 + 0x30] %asi, %i4 /* %i4/%i5 = src2 + 0x30 */ + ldda [%l7 + 0x30] %asi, %i4 /* %i4/%i5 = src2 + 0x30 */ xor %l0, %g2, %l0 xor %l1, %g3, %l1 stxa %l0, [%i0 + 0x20] %asi stxa %l1, [%i0 + 0x28] %asi - ldda [%i6 + 0x30] %asi, %g2 /* %g2/%g3 = src3 + 0x30 */ + ldda [%l6 + 0x30] %asi, %g2 /* %g2/%g3 = src3 + 0x30 */ ldda [%i0 + 0x30] %asi, %l0 /* %l0/%l1 = dest + 0x30 */ prefetch [%i1 + 0x40], #one_read diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 9f7740eee8d2..e2027f27c0fe 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -463,7 +463,7 @@ out_of_memory: up_read(&mm->mmap_sem); printk("VM: killing process %s\n", current->comm); if (!(regs->tstate & TSTATE_PRIV)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto handle_kernel_fault; intr_or_no_mm: diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 3010227fe243..100c4456ed1e 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -631,7 +631,6 @@ void prom_world(int enter) __asm__ __volatile__("flushw"); } -#ifdef DCACHE_ALIASING_POSSIBLE void __flush_dcache_range(unsigned long start, unsigned long end) { unsigned long va; @@ -655,7 +654,6 @@ void __flush_dcache_range(unsigned long start, unsigned long end) "i" (ASI_DCACHE_INVALIDATE)); } } -#endif /* DCACHE_ALIASING_POSSIBLE */ /* get_new_mmu_context() uses "cache + 1". */ DEFINE_SPINLOCK(ctx_alloc_lock); @@ -1647,6 +1645,58 @@ EXPORT_SYMBOL(_PAGE_E); unsigned long _PAGE_CACHE __read_mostly; EXPORT_SYMBOL(_PAGE_CACHE); +#ifdef CONFIG_SPARSEMEM_VMEMMAP + +#define VMEMMAP_CHUNK_SHIFT 22 +#define VMEMMAP_CHUNK (1UL << VMEMMAP_CHUNK_SHIFT) +#define VMEMMAP_CHUNK_MASK ~(VMEMMAP_CHUNK - 1UL) +#define VMEMMAP_ALIGN(x) (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK) + +#define VMEMMAP_SIZE ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \ + sizeof(struct page *)) >> VMEMMAP_CHUNK_SHIFT) +unsigned long vmemmap_table[VMEMMAP_SIZE]; + +int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) +{ + unsigned long vstart = (unsigned long) start; + unsigned long vend = (unsigned long) (start + nr); + unsigned long phys_start = (vstart - VMEMMAP_BASE); + unsigned long phys_end = (vend - VMEMMAP_BASE); + unsigned long addr = phys_start & VMEMMAP_CHUNK_MASK; + unsigned long end = VMEMMAP_ALIGN(phys_end); + unsigned long pte_base; + + pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4U | + _PAGE_CP_4U | _PAGE_CV_4U | + _PAGE_P_4U | _PAGE_W_4U); + if (tlb_type == hypervisor) + pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V | + _PAGE_CP_4V | _PAGE_CV_4V | + _PAGE_P_4V | _PAGE_W_4V); + + for (; addr < end; addr += VMEMMAP_CHUNK) { + unsigned long *vmem_pp = + vmemmap_table + (addr >> VMEMMAP_CHUNK_SHIFT); + void *block; + + if (!(*vmem_pp & _PAGE_VALID)) { + block = vmemmap_alloc_block(1UL << 22, node); + if (!block) + return -ENOMEM; + + *vmem_pp = pte_base | __pa(block); + + printk(KERN_INFO "[%p-%p] page_structs=%lu " + "node=%d entry=%lu/%lu\n", start, block, nr, + node, + addr >> VMEMMAP_CHUNK_SHIFT, + VMEMMAP_SIZE >> VMEMMAP_CHUNK_SHIFT); + } + } + return 0; +} +#endif /* CONFIG_SPARSEMEM_VMEMMAP */ + static void prot_init_common(unsigned long page_none, unsigned long page_shared, unsigned long page_copy, @@ -1911,9 +1961,4 @@ void online_page(struct page *page) num_physpages++; } -int remove_memory(u64 start, u64 size) -{ - return -EINVAL; -} - #endif /* CONFIG_MEMORY_HOTPLUG */ diff --git a/arch/um/Kconfig b/arch/um/Kconfig index e6ff30266542..740d8a922e48 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -55,6 +55,14 @@ config GENERIC_BUG default y depends on BUG +config GENERIC_TIME + bool + default y + +config GENERIC_CLOCKEVENTS + bool + default y + # Used in kernel/irq/manage.c and include/linux/irq.h config IRQ_RELEASE_METHOD bool @@ -62,63 +70,25 @@ config IRQ_RELEASE_METHOD menu "UML-specific options" -config MODE_TT - bool "Tracing thread support (DEPRECATED)" - default n - depends on BROKEN - help - This option controls whether tracing thread support is compiled - into UML. This option is largely obsolete, given that skas0 provides - skas security and performance without needing to patch the host. - It is safe to say 'N' here; saying 'Y' may cause additional problems - with the resulting binary even if you run UML in SKAS mode, and running - in TT mode is strongly *NOT RECOMMENDED*. - config STATIC_LINK bool "Force a static link" default n - depends on !MODE_TT help - If CONFIG_MODE_TT is disabled, then this option gives you the ability - to force a static link of UML. Normally, if only skas mode is built - in to UML, it will be linked as a shared binary. This is inconvenient - for use in a chroot jail. So, if you intend to run UML inside a - chroot, and you disable CONFIG_MODE_TT, you probably want to say Y - here. - Additionally, this option enables using higher memory spaces (up to - 2.75G) for UML - disabling CONFIG_MODE_TT and enabling this option leads - to best results for this. - -config KERNEL_HALF_GIGS - int "Kernel address space size (in .5G units)" - default "1" - depends on MODE_TT - help - This determines the amount of address space that UML will allocate for - its own, measured in half Gigabyte units. The default is 1. - Change this only if you need to boot UML with an unusually large amount - of physical memory. - -config MODE_SKAS - bool "Separate Kernel Address Space support" if MODE_TT - default y - help - This option controls whether skas (separate kernel address space) - support is compiled in. - Unless you have specific needs to use TT mode (which applies almost only - to developers), you should say Y here. - SKAS mode will make use of the SKAS3 patch if it is applied on the host - (and your UML will run in SKAS3 mode), but if no SKAS patch is applied - on the host it will run in SKAS0 mode, which is anyway faster than TT - mode. + This option gives you the ability to force a static link of UML. + Normally, UML is linked as a shared binary. This is inconvenient for + use in a chroot jail. So, if you intend to run UML inside a chroot, + you probably want to say Y here. + Additionally, this option enables using higher memory spaces (up to + 2.75G) for UML. source "arch/um/Kconfig.arch" source "mm/Kconfig" +source "kernel/time/Kconfig" config LD_SCRIPT_STATIC bool default y - depends on MODE_TT || STATIC_LINK + depends on STATIC_LINK config LD_SCRIPT_DYN bool @@ -128,18 +98,18 @@ config LD_SCRIPT_DYN config NET bool "Networking support" help - Unless you really know what you are doing, you should say Y here. - The reason is that some programs need kernel networking support even - when running on a stand-alone machine that isn't connected to any - other computer. If you are upgrading from an older kernel, you - should consider updating your networking tools too because changes - in the kernel and the tools often go hand in hand. The tools are - contained in the package net-tools, the location and version number - of which are given in <file:Documentation/Changes>. + Unless you really know what you are doing, you should say Y here. + The reason is that some programs need kernel networking support even + when running on a stand-alone machine that isn't connected to any + other computer. If you are upgrading from an older kernel, you + should consider updating your networking tools too because changes + in the kernel and the tools often go hand in hand. The tools are + contained in the package net-tools, the location and version number + of which are given in <file:Documentation/Changes>. - For a general introduction to Linux networking, it is highly - recommended to read the NET-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. + For a general introduction to Linux networking, it is highly + recommended to read the NET-HOWTO, available from + <http://www.tldp.org/docs.html#howto>. source "fs/Kconfig.binfmt" @@ -147,99 +117,99 @@ source "fs/Kconfig.binfmt" config HOSTFS tristate "Host filesystem" help - While the User-Mode Linux port uses its own root file system for - booting and normal file access, this module lets the UML user - access files stored on the host. It does not require any - network connection between the Host and UML. An example use of - this might be: + While the User-Mode Linux port uses its own root file system for + booting and normal file access, this module lets the UML user + access files stored on the host. It does not require any + network connection between the Host and UML. An example use of + this might be: - mount none /tmp/fromhost -t hostfs -o /tmp/umlshare + mount none /tmp/fromhost -t hostfs -o /tmp/umlshare - where /tmp/fromhost is an empty directory inside UML and - /tmp/umlshare is a directory on the host with files the UML user - wishes to access. + where /tmp/fromhost is an empty directory inside UML and + /tmp/umlshare is a directory on the host with files the UML user + wishes to access. - For more information, see - <http://user-mode-linux.sourceforge.net/hostfs.html>. + For more information, see + <http://user-mode-linux.sourceforge.net/hostfs.html>. - If you'd like to be able to work with files stored on the host, - say Y or M here; otherwise say N. + If you'd like to be able to work with files stored on the host, + say Y or M here; otherwise say N. config HPPFS tristate "HoneyPot ProcFS (EXPERIMENTAL)" depends on EXPERIMENTAL help - hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc - entries to be overridden, removed, or fabricated from the host. - Its purpose is to allow a UML to appear to be a physical machine - by removing or changing anything in /proc which gives away the - identity of a UML. + hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc + entries to be overridden, removed, or fabricated from the host. + Its purpose is to allow a UML to appear to be a physical machine + by removing or changing anything in /proc which gives away the + identity of a UML. - See <http://user-mode-linux.sf.net/hppfs.html> for more information. + See <http://user-mode-linux.sf.net/hppfs.html> for more information. - You only need this if you are setting up a UML honeypot. Otherwise, - it is safe to say 'N' here. + You only need this if you are setting up a UML honeypot. Otherwise, + it is safe to say 'N' here. config MCONSOLE bool "Management console" default y help - The user mode linux management console is a low-level interface to - the kernel, somewhat like the i386 SysRq interface. Since there is - a full-blown operating system running under every user mode linux - instance, there is much greater flexibility possible than with the - SysRq mechanism. + The user mode linux management console is a low-level interface to + the kernel, somewhat like the i386 SysRq interface. Since there is + a full-blown operating system running under every user mode linux + instance, there is much greater flexibility possible than with the + SysRq mechanism. - If you answer 'Y' to this option, to use this feature, you need the - mconsole client (called uml_mconsole) which is present in CVS in - 2.4.5-9um and later (path /tools/mconsole), and is also in the - distribution RPM package in 2.4.6 and later. + If you answer 'Y' to this option, to use this feature, you need the + mconsole client (called uml_mconsole) which is present in CVS in + 2.4.5-9um and later (path /tools/mconsole), and is also in the + distribution RPM package in 2.4.6 and later. - It is safe to say 'Y' here. + It is safe to say 'Y' here. config MAGIC_SYSRQ bool "Magic SysRq key" depends on MCONSOLE - ---help--- - If you say Y here, you will have some control over the system even - if the system crashes for example during kernel debugging (e.g., you - will be able to flush the buffer cache to disk, reboot the system - immediately or dump some status information). A key for each of the - possible requests is provided. + help + If you say Y here, you will have some control over the system even + if the system crashes for example during kernel debugging (e.g., you + will be able to flush the buffer cache to disk, reboot the system + immediately or dump some status information). A key for each of the + possible requests is provided. - This is the feature normally accomplished by pressing a key - while holding SysRq (Alt+PrintScreen). + This is the feature normally accomplished by pressing a key + while holding SysRq (Alt+PrintScreen). - On UML, this is accomplished by sending a "sysrq" command with - mconsole, followed by the letter for the requested command. + On UML, this is accomplished by sending a "sysrq" command with + mconsole, followed by the letter for the requested command. - The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y - unless you really know what this hack does. + The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y + unless you really know what this hack does. config SMP bool "Symmetric multi-processing support (EXPERIMENTAL)" default n #SMP_BROKEN is for x86_64. - depends on MODE_TT && EXPERIMENTAL && (!SMP_BROKEN || (BROKEN && SMP_BROKEN)) + depends on EXPERIMENTAL && (!SMP_BROKEN || (BROKEN && SMP_BROKEN)) help - This option enables UML SMP support. - It is NOT related to having a real SMP box. Not directly, at least. + This option enables UML SMP support. + It is NOT related to having a real SMP box. Not directly, at least. - UML implements virtual SMP by allowing as many processes to run - simultaneously on the host as there are virtual processors configured. + UML implements virtual SMP by allowing as many processes to run + simultaneously on the host as there are virtual processors configured. - Obviously, if the host is a uniprocessor, those processes will - timeshare, but, inside UML, will appear to be running simultaneously. - If the host is a multiprocessor, then UML processes may run - simultaneously, depending on the host scheduler. + Obviously, if the host is a uniprocessor, those processes will + timeshare, but, inside UML, will appear to be running simultaneously. + If the host is a multiprocessor, then UML processes may run + simultaneously, depending on the host scheduler. - This, however, is supported only in TT mode. So, if you use the SKAS - patch on your host, switching to TT mode and enabling SMP usually gives - you worse performances. - Also, since the support for SMP has been under-developed, there could - be some bugs being exposed by enabling SMP. + This, however, is supported only in TT mode. So, if you use the SKAS + patch on your host, switching to TT mode and enabling SMP usually + gives you worse performances. + Also, since the support for SMP has been under-developed, there could + be some bugs being exposed by enabling SMP. - If you don't know what to do, say N. + If you don't know what to do, say N. config NR_CPUS int "Maximum number of CPUs (2-32)" @@ -251,29 +221,24 @@ config NEST_LEVEL int "Nesting level" default "0" help - This is set to the number of layers of UMLs that this UML will be run - in. Normally, this is zero, meaning that it will run directly on the - host. Setting it to one will build a UML that can run inside a UML - that is running on the host. Generally, if you intend this UML to run - inside another UML, set CONFIG_NEST_LEVEL to one more than the host - UML. - - Note that if the hosting UML has its CONFIG_KERNEL_HALF_GIGS set to - greater than one, then the guest UML should have its CONFIG_NEST_LEVEL - set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS. - Only change this if you are running nested UMLs. + This is set to the number of layers of UMLs that this UML will be run + in. Normally, this is zero, meaning that it will run directly on the + host. Setting it to one will build a UML that can run inside a UML + that is running on the host. Generally, if you intend this UML to run + inside another UML, set CONFIG_NEST_LEVEL to one more than the host + UML. config HIGHMEM bool "Highmem support (EXPERIMENTAL)" depends on !64BIT && EXPERIMENTAL default n help - This was used to allow UML to run with big amounts of memory. - Currently it is unstable, so if unsure say N. + This was used to allow UML to run with big amounts of memory. + Currently it is unstable, so if unsure say N. - To use big amounts of memory, it is recommended to disable TT mode (i.e. - CONFIG_MODE_TT) and enable static linking (i.e. CONFIG_STATIC_LINK) - - this should allow the guest to use up to 2.75G of memory. + To use big amounts of memory, it is recommended enable static + linking (i.e. CONFIG_STATIC_LINK) - this should allow the + guest to use up to 2.75G of memory. config KERNEL_STACK_ORDER int "Kernel stack size order" @@ -281,20 +246,9 @@ config KERNEL_STACK_ORDER range 1 10 if 64BIT default 0 if !64BIT help - This option determines the size of UML kernel stacks. They will - be 1 << order pages. The default is OK unless you're running Valgrind - on UML, in which case, set this to 3. - -config UML_REAL_TIME_CLOCK - bool "Real-time Clock" - default y - help - This option makes UML time deltas match wall clock deltas. This should - normally be enabled. The exception would be if you are debugging with - UML and spend long times with UML stopped at a breakpoint. In this - case, when UML is restarted, it will call the timer enough times to make - up for the time spent at the breakpoint. This could result in a - noticeable lag. If this is a problem, then disable this option. + This option determines the size of UML kernel stacks. They will + be 1 << order pages. The default is OK unless you're running Valgrind + on UML, in which case, set this to 3. endmenu diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char index a5b079d5e865..9a78d354f0b4 100644 --- a/arch/um/Kconfig.char +++ b/arch/um/Kconfig.char @@ -5,7 +5,7 @@ config STDERR_CONSOLE bool "stderr console" default y help - console driver which dumps all printk messages to stderr. + console driver which dumps all printk messages to stderr. config STDIO_CONSOLE bool @@ -14,60 +14,58 @@ config STDIO_CONSOLE config SSL bool "Virtual serial line" help - The User-Mode Linux environment allows you to create virtual serial - lines on the UML that are usually made to show up on the host as - ttys or ptys. + The User-Mode Linux environment allows you to create virtual serial + lines on the UML that are usually made to show up on the host as + ttys or ptys. - See <http://user-mode-linux.sourceforge.net/input.html> for more - information and command line examples of how to use this facility. + See <http://user-mode-linux.sourceforge.net/input.html> for more + information and command line examples of how to use this facility. - Unless you have a specific reason for disabling this, say Y. + Unless you have a specific reason for disabling this, say Y. config NULL_CHAN bool "null channel support" help - This option enables support for attaching UML consoles and serial - lines to a device similar to /dev/null. Data written to it disappears - and there is never any data to be read. + This option enables support for attaching UML consoles and serial + lines to a device similar to /dev/null. Data written to it disappears + and there is never any data to be read. config PORT_CHAN bool "port channel support" help - This option enables support for attaching UML consoles and serial - lines to host portals. They may be accessed with 'telnet <host> - <port number>'. Any number of consoles and serial lines may be - attached to a single portal, although what UML device you get when - you telnet to that portal will be unpredictable. - It is safe to say 'Y' here. + This option enables support for attaching UML consoles and serial + lines to host portals. They may be accessed with 'telnet <host> + <port number>'. Any number of consoles and serial lines may be + attached to a single portal, although what UML device you get when + you telnet to that portal will be unpredictable. + It is safe to say 'Y' here. config PTY_CHAN bool "pty channel support" help - This option enables support for attaching UML consoles and serial - lines to host pseudo-terminals. Access to both traditional - pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled - with this option. The assignment of UML devices to host devices - will be announced in the kernel message log. - It is safe to say 'Y' here. + This option enables support for attaching UML consoles and serial + lines to host pseudo-terminals. Access to both traditional + pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled + with this option. The assignment of UML devices to host devices + will be announced in the kernel message log. + It is safe to say 'Y' here. config TTY_CHAN bool "tty channel support" help - This option enables support for attaching UML consoles and serial - lines to host terminals. Access to both virtual consoles - (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and - /dev/pts/*) are controlled by this option. - It is safe to say 'Y' here. + This option enables support for attaching UML consoles and serial + lines to host terminals. Access to both virtual consoles + (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and + /dev/pts/*) are controlled by this option. + It is safe to say 'Y' here. config XTERM_CHAN bool "xterm channel support" help - This option enables support for attaching UML consoles and serial - lines to xterms. Each UML device so assigned will be brought up in - its own xterm. - If you disable this option, then CONFIG_PT_PROXY will be disabled as - well, since UML's gdb currently requires an xterm. - It is safe to say 'Y' here. + This option enables support for attaching UML consoles and serial + lines to xterms. Each UML device so assigned will be brought up in + its own xterm. + It is safe to say 'Y' here. config NOCONFIG_CHAN bool @@ -77,39 +75,39 @@ config CON_ZERO_CHAN string "Default main console channel initialization" default "fd:0,fd:1" help - This is the string describing the channel to which the main console - will be attached by default. This value can be overridden from the - command line. The default value is "fd:0,fd:1", which attaches the - main console to stdin and stdout. - It is safe to leave this unchanged. + This is the string describing the channel to which the main console + will be attached by default. This value can be overridden from the + command line. The default value is "fd:0,fd:1", which attaches the + main console to stdin and stdout. + It is safe to leave this unchanged. config CON_CHAN string "Default console channel initialization" default "xterm" help - This is the string describing the channel to which all consoles - except the main console will be attached by default. This value can - be overridden from the command line. The default value is "xterm", - which brings them up in xterms. - It is safe to leave this unchanged, although you may wish to change - this if you expect the UML that you build to be run in environments - which don't have X or xterm available. + This is the string describing the channel to which all consoles + except the main console will be attached by default. This value can + be overridden from the command line. The default value is "xterm", + which brings them up in xterms. + It is safe to leave this unchanged, although you may wish to change + this if you expect the UML that you build to be run in environments + which don't have X or xterm available. config SSL_CHAN string "Default serial line channel initialization" default "pty" help - This is the string describing the channel to which the serial lines - will be attached by default. This value can be overridden from the - command line. The default value is "pty", which attaches them to - traditional pseudo-terminals. - It is safe to leave this unchanged, although you may wish to change - this if you expect the UML that you build to be run in environments - which don't have a set of /dev/pty* devices. + This is the string describing the channel to which the serial lines + will be attached by default. This value can be overridden from the + command line. The default value is "pty", which attaches them to + traditional pseudo-terminals. + It is safe to leave this unchanged, although you may wish to change + this if you expect the UML that you build to be run in environments + which don't have a set of /dev/pty* devices. config UNIX98_PTYS bool "Unix98 PTY support" - ---help--- + help A pseudo terminal (PTY) is a software device consisting of two halves: a master and a slave. The slave device behaves identical to a physical terminal; the master device is used by a process to @@ -132,7 +130,7 @@ config UNIX98_PTYS config LEGACY_PTYS bool "Legacy (BSD) PTY support" default y - ---help--- + help A pseudo terminal (PTY) is a software device consisting of two halves: a master and a slave. The slave device behaves identical to a physical terminal; the master device is used by a process to @@ -170,7 +168,7 @@ config LEGACY_PTY_COUNT int "Maximum number of legacy PTY in use" depends on LEGACY_PTYS default "256" - ---help--- + help The maximum number of legacy PTYs that can be used at any one time. The default is 256, and should be more than enough. Embedded systems may want to reduce this to save memory. @@ -196,10 +194,10 @@ config UML_WATCHDOG config UML_SOUND tristate "Sound support" help - This option enables UML sound support. If enabled, it will pull in - soundcore and the UML hostaudio relay, which acts as a intermediary - between the host's dsp and mixer devices and the UML sound system. - It is safe to say 'Y' here. + This option enables UML sound support. If enabled, it will pull in + soundcore and the UML hostaudio relay, which acts as a intermediary + between the host's dsp and mixer devices and the UML sound system. + It is safe to say 'Y' here. config SOUND tristate @@ -217,22 +215,21 @@ config HW_RANDOM config UML_RANDOM tristate "Hardware random number generator" help - This option enables UML's "hardware" random number generator. It - attaches itself to the host's /dev/random, supplying as much entropy - as the host has, rather than the small amount the UML gets from its - own drivers. It registers itself as a standard hardware random number - generator, major 10, minor 183, and the canonical device name is - /dev/hwrng. - The way to make use of this is to install the rng-tools package - (check your distro, or download from - http://sourceforge.net/projects/gkernel/). rngd periodically reads - /dev/hwrng and injects the entropy into /dev/random. + This option enables UML's "hardware" random number generator. It + attaches itself to the host's /dev/random, supplying as much entropy + as the host has, rather than the small amount the UML gets from its + own drivers. It registers itself as a standard hardware random number + generator, major 10, minor 183, and the canonical device name is + /dev/hwrng. + The way to make use of this is to install the rng-tools package + (check your distro, or download from + http://sourceforge.net/projects/gkernel/). rngd periodically reads + /dev/hwrng and injects the entropy into /dev/random. config MMAPPER tristate "iomem emulation driver" help - This driver allows a host file to be used as emulated IO memory inside - UML. + This driver allows a host file to be used as emulated IO memory inside + UML. endmenu - diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug index c86f5eb29fd5..1f6462ffd3e8 100644 --- a/arch/um/Kconfig.debug +++ b/arch/um/Kconfig.debug @@ -2,50 +2,31 @@ menu "Kernel hacking" source "lib/Kconfig.debug" -config CMDLINE_ON_HOST - bool "Show command line arguments on the host in TT mode" - depends on MODE_TT - default !DEBUG_INFO - help - This controls whether arguments in guest processes should be shown on - the host's ps output. - Enabling this option hinders debugging on some recent GDB versions - (because GDB gets "confused" when we do an execvp()). So probably you - should disable it. - -config PT_PROXY - bool "Enable ptrace proxy" - depends on XTERM_CHAN && DEBUG_INFO && MODE_TT - help - This option enables a debugging interface which allows gdb to debug - the kernel without needing to actually attach to kernel threads. - If you want to do kernel debugging, say Y here; otherwise say N. - config GPROF bool "Enable gprof support" - depends on DEBUG_INFO && MODE_SKAS && !MODE_TT + depends on DEBUG_INFO help - This allows profiling of a User-Mode Linux kernel with the gprof - utility. + This allows profiling of a User-Mode Linux kernel with the gprof + utility. - See <http://user-mode-linux.sourceforge.net/gprof.html> for more - details. + See <http://user-mode-linux.sourceforge.net/gprof.html> for more + details. - If you're involved in UML kernel development and want to use gprof, - say Y. If you're unsure, say N. + If you're involved in UML kernel development and want to use gprof, + say Y. If you're unsure, say N. config GCOV bool "Enable gcov support" - depends on DEBUG_INFO && MODE_SKAS + depends on DEBUG_INFO help - This option allows developers to retrieve coverage data from a UML - session. + This option allows developers to retrieve coverage data from a UML + session. - See <http://user-mode-linux.sourceforge.net/gprof.html> for more - details. + See <http://user-mode-linux.sourceforge.net/gprof.html> for more + details. - If you're involved in UML kernel development and want to use gcov, - say Y. If you're unsure, say N. + 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" diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386 index d6cffb27fff8..9876d80d85dd 100644 --- a/arch/um/Kconfig.i386 +++ b/arch/um/Kconfig.i386 @@ -65,20 +65,6 @@ config 3_LEVEL_PGTABLES However, this it experimental on 32-bit architectures, so if unsure say N (on x86-64 it's automatically enabled, instead, as it's safe there). -config STUB_CODE - hex - default 0xbfffe000 if !HOST_VMSPLIT_2G - default 0x7fffe000 if HOST_VMSPLIT_2G - -config STUB_DATA - hex - default 0xbffff000 if !HOST_VMSPLIT_2G - default 0x7ffff000 if HOST_VMSPLIT_2G - -config STUB_START - hex - default STUB_CODE - config ARCH_HAS_SC_SIGNALS bool default y diff --git a/arch/um/Kconfig.net b/arch/um/Kconfig.net index 14a04ebdeae9..66e50026ade9 100644 --- a/arch/um/Kconfig.net +++ b/arch/um/Kconfig.net @@ -108,6 +108,28 @@ config UML_NET_DAEMON more than one without conflict. If you don't need UML networking, say N. +config UML_NET_VDE + bool "VDE transport" + depends on UML_NET + help + This User-Mode Linux network transport allows one or more running + UMLs on a single host to communicate with each other and also + with the rest of the world using Virtual Distributed Ethernet, + an improved fork of uml_switch. + + You must have libvdeplug installed in order to build the vde + transport into UML. + + To use this form of networking, you will need to run vde_switch + on the host. + + For more information, see <http://wiki.virtualsquare.org/> + That site has a good overview of what VDE is and also examples + of the UML command line to use to enable VDE networking. + + If you need UML networking with VDE, + say Y. + config UML_NET_MCAST bool "Multicast transport" depends on UML_NET diff --git a/arch/um/Kconfig.x86_64 b/arch/um/Kconfig.x86_64 index f60e9e506424..d632e9a89cc3 100644 --- a/arch/um/Kconfig.x86_64 +++ b/arch/um/Kconfig.x86_64 @@ -17,24 +17,12 @@ config SEMAPHORE_SLEEPERS config TOP_ADDR hex - default 0x80000000 + default 0x7fc0000000 config 3_LEVEL_PGTABLES bool default y -config STUB_CODE - hex - default 0x7fbfffe000 - -config STUB_DATA - hex - default 0x7fbffff000 - -config STUB_START - hex - default STUB_CODE - config ARCH_HAS_SC_SIGNALS bool default n diff --git a/arch/um/Makefile b/arch/um/Makefile index d08d3bc518e3..82c2ac48040d 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -2,7 +2,7 @@ # This file is included by the global makefile so that you can add your own # architecture-specific flags and dependencies. # -# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) +# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) # Licensed under the GPL # @@ -31,18 +31,9 @@ SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \ $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h -um-modes-$(CONFIG_MODE_TT) += tt -um-modes-$(CONFIG_MODE_SKAS) += skas +MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include/skas -MODE_INCLUDE += $(foreach mode,$(um-modes-y),\ - -I$(srctree)/$(ARCH_DIR)/include/$(mode)) - -MAKEFILES-INCL += $(foreach mode,$(um-modes-y),\ - $(srctree)/$(ARCH_DIR)/Makefile-$(mode)) - -ifneq ($(MAKEFILES-INCL),) - include $(MAKEFILES-INCL) -endif +include $(srctree)/$(ARCH_DIR)/Makefile-skas ARCH_INCLUDE := -I$(ARCH_DIR)/include ifneq ($(KBUILD_SRC),) @@ -60,7 +51,8 @@ SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH) KBUILD_CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ - -Din6addr_loopback=kernel_in6addr_loopback + -Din6addr_loopback=kernel_in6addr_loopback \ + -Din6addr_any=kernel_in6addr_any KBUILD_AFLAGS += $(ARCH_INCLUDE) @@ -88,9 +80,8 @@ KBUILD_CFLAGS += $(call cc-option,-fno-unit-at-a-time,) # included; the values here are meaningless CONFIG_NEST_LEVEL ?= 0 -CONFIG_KERNEL_HALF_GIGS ?= 0 -SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000) +SIZE = ($(CONFIG_NEST_LEVEL) * 0x20000000) PHONY += linux @@ -123,7 +114,6 @@ CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) $(call cc-option, -fno-stack-protector,) \ $(call cc-option, -fno-stack-protector-all,) -CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT CONFIG_KERNEL_STACK_ORDER ?= 2 STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) @@ -131,13 +121,10 @@ ifndef START START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] ) endif -CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \ - -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \ - -DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \ - -DKERNEL_STACK_SIZE=$(STACK_SIZE) \ - -DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap.o +CPPFLAGS_vmlinux.lds = -U$(SUBARCH) -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \ + -DELF_FORMAT="$(ELF_FORMAT)" -DKERNEL_STACK_SIZE=$(STACK_SIZE) -#The wrappers will select whether using "malloc" or the kernel allocator. +# The wrappers will select whether using "malloc" or the kernel allocator. LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) @@ -150,8 +137,8 @@ define cmd_vmlinux__ FORCE ,$^) ; rm -f linux endef -#When cleaning we don't include .config, so we don't include -#TT or skas makefiles and don't clean skas_ptregs.h. +# When cleaning we don't include .config, so we don't include +# TT or skas makefiles and don't clean skas_ptregs.h. CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \ $(ARCH_DIR)/include/user_constants.h \ $(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch @@ -176,9 +163,9 @@ include/asm-um/arch: @echo ' SYMLINK $@' ifneq ($(KBUILD_SRC),) $(Q)mkdir -p $(objtree)/include/asm-um - $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch + $(Q)ln -fsn $(srctree)/include/asm-$(HEADER_ARCH) include/asm-um/arch else - $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch + $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(HEADER_ARCH) arch endif $(objtree)/$(ARCH_DIR)/include: @@ -232,4 +219,4 @@ $(ARCH_DIR)/include/kern_constants.h: $(objtree)/$(ARCH_DIR)/include @echo ' SYMLINK $@' $(Q)ln -sf ../../../include/asm-um/asm-offsets.h $@ -export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS +export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 index d10e4dc0dae8..0178df306939 100644 --- a/arch/um/Makefile-i386 +++ b/arch/um/Makefile-i386 @@ -1,17 +1,14 @@ -core-y += arch/um/sys-i386/ arch/i386/crypto/ +core-y += arch/um/sys-i386/ arch/x86/crypto/ TOP_ADDR := $(CONFIG_TOP_ADDR) -ifeq ($(CONFIG_MODE_SKAS),y) - ifneq ($(CONFIG_MODE_TT),y) - START := 0x8048000 - endif -endif +START := 0x8048000 LDFLAGS += -m elf_i386 ELF_ARCH := $(SUBARCH) ELF_FORMAT := elf32-$(SUBARCH) OBJCOPYFLAGS := -O binary -R .note -R .comment -S +HEADER_ARCH := x86 ifeq ("$(origin SUBARCH)", "command line") ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)") @@ -24,6 +21,11 @@ export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS endif endif +CFLAGS += -DCONFIG_X86_32 +AFLAGS += -DCONFIG_X86_32 +CONFIG_X86_32 := y +export CONFIG_X86_32 + ARCH_KERNEL_DEFINES += -U__$(SUBARCH)__ -U$(SUBARCH) # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y. diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 index bcfd6ea30030..fe5316f0c6a5 100644 --- a/arch/um/Makefile-x86_64 +++ b/arch/um/Makefile-x86_64 @@ -1,7 +1,7 @@ # Copyright 2003 - 2004 Pathscale, Inc # Released under the GPL -core-y += arch/um/sys-x86_64/ arch/x86_64/crypto/ +core-y += arch/um/sys-x86_64/ arch/x86/crypto/ START := 0x60000000 _extra_flags_ = -fno-builtin -m64 @@ -18,6 +18,7 @@ KBUILD_CPPFLAGS += -m64 ELF_ARCH := i386:x86-64 ELF_FORMAT := elf64-x86-64 +HEADER_ARCH := x86 # Not on all 64-bit distros /lib is a symlink to /lib64. PLD is an example. diff --git a/arch/um/defconfig b/arch/um/defconfig index 1e0f677c2f46..f609edede065 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -12,9 +12,7 @@ CONFIG_IRQ_RELEASE_METHOD=y # # UML-specific options # -# CONFIG_MODE_TT is not set # CONFIG_STATIC_LINK is not set -CONFIG_MODE_SKAS=y # # Host processor type and features @@ -61,9 +59,6 @@ CONFIG_SEMAPHORE_SLEEPERS=y # CONFIG_HOST_2G_2G is not set CONFIG_TOP_ADDR=0xc0000000 # CONFIG_3_LEVEL_PGTABLES is not set -CONFIG_STUB_CODE=0xbfffe000 -CONFIG_STUB_DATA=0xbffff000 -CONFIG_STUB_START=0xbfffe000 CONFIG_ARCH_HAS_SC_SIGNALS=y CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y CONFIG_GENERIC_HWEIGHT=y @@ -75,6 +70,9 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_LD_SCRIPT_DYN=y CONFIG_NET=y CONFIG_BINFMT_ELF=y @@ -82,11 +80,10 @@ CONFIG_BINFMT_MISC=m # CONFIG_HOSTFS is not set # CONFIG_HPPFS is not set CONFIG_MCONSOLE=y -# CONFIG_MAGIC_SYSRQ is not set +CONFIG_MAGIC_SYSRQ=y CONFIG_NEST_LEVEL=0 # CONFIG_HIGHMEM is not set CONFIG_KERNEL_STACK_ORDER=0 -CONFIG_UML_REAL_TIME_CLOCK=y # # Code maturity level options diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile index 0f780dd0d4c4..d283e7b022a0 100644 --- a/arch/um/drivers/Makefile +++ b/arch/um/drivers/Makefile @@ -19,10 +19,16 @@ harddog-objs := harddog_kern.o harddog_user.o LDFLAGS_pcap.o := -r $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libpcap.a) -targets := pcap_kern.o pcap_user.o +LDFLAGS_vde.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libvdeplug.a) + +targets := pcap_kern.o pcap_user.o vde_kern.o vde_user.o $(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o $(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_pcap.o) + +$(obj)/vde.o: $(obj)/vde_kern.o $(obj)/vde_user.o + $(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_vde.o) + #XXX: The call below does not work because the flags are added before the # object name, so nothing from the library gets linked. #$(call if_changed,ld) @@ -37,6 +43,7 @@ obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o obj-$(CONFIG_UML_NET_DAEMON) += daemon.o +obj-$(CONFIG_UML_NET_VDE) += vde.o obj-$(CONFIG_UML_NET_MCAST) += mcast.o obj-$(CONFIG_UML_NET_PCAP) += pcap.o obj-$(CONFIG_UML_NET) += net.o @@ -54,6 +61,6 @@ obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o obj-$(CONFIG_UML_RANDOM) += random.o # pcap_user.o must be added explicitly. -USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o +USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o vde_user.o include arch/um/scripts/Makefile.rules diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 629b00e3b0b0..db3082b4da46 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -1,28 +1,19 @@ /* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) * Licensed under the GPL */ -#include <linux/stddef.h> -#include <linux/kernel.h> -#include <linux/list.h> #include <linux/slab.h> #include <linux/tty.h> -#include <linux/string.h> #include <linux/tty_flip.h> -#include <asm/irq.h> #include "chan_kern.h" -#include "kern.h" -#include "irq_user.h" -#include "sigio.h" -#include "line.h" #include "os.h" #ifdef CONFIG_NOCONFIG_CHAN static void *not_configged_init(char *str, int device, const struct chan_opts *opts) { - printk("Using a channel type which is configured out of " + printk(KERN_ERR "Using a channel type which is configured out of " "UML\n"); return NULL; } @@ -30,34 +21,34 @@ static void *not_configged_init(char *str, int device, static int not_configged_open(int input, int output, int primary, void *data, char **dev_out) { - printk("Using a channel type which is configured out of " + printk(KERN_ERR "Using a channel type which is configured out of " "UML\n"); return -ENODEV; } static void not_configged_close(int fd, void *data) { - printk("Using a channel type which is configured out of " + printk(KERN_ERR "Using a channel type which is configured out of " "UML\n"); } static int not_configged_read(int fd, char *c_out, void *data) { - printk("Using a channel type which is configured out of " + printk(KERN_ERR "Using a channel type which is configured out of " "UML\n"); return -EIO; } static int not_configged_write(int fd, const char *buf, int len, void *data) { - printk("Using a channel type which is configured out of " + printk(KERN_ERR "Using a channel type which is configured out of " "UML\n"); return -EIO; } static int not_configged_console_write(int fd, const char *buf, int len) { - printk("Using a channel type which is configured out of " + printk(KERN_ERR "Using a channel type which is configured out of " "UML\n"); return -EIO; } @@ -65,14 +56,14 @@ static int not_configged_console_write(int fd, const char *buf, int len) static int not_configged_window_size(int fd, void *data, unsigned short *rows, unsigned short *cols) { - printk("Using a channel type which is configured out of " + printk(KERN_ERR "Using a channel type which is configured out of " "UML\n"); return -ENODEV; } static void not_configged_free(void *data) { - printk("Using a channel type which is configured out of " + printk(KERN_ERR "Using a channel type which is configured out of " "UML\n"); } @@ -89,64 +80,17 @@ static const struct chan_ops not_configged_ops = { }; #endif /* CONFIG_NOCONFIG_CHAN */ -void generic_close(int fd, void *unused) -{ - os_close_file(fd); -} - -int generic_read(int fd, char *c_out, void *unused) -{ - int n; - - n = os_read_file(fd, c_out, sizeof(*c_out)); - - if(n == -EAGAIN) - return 0; - else if(n == 0) - return -EIO; - return n; -} - -/* XXX Trivial wrapper around os_write_file */ - -int generic_write(int fd, const char *buf, int n, void *unused) -{ - return os_write_file(fd, buf, n); -} - -int generic_window_size(int fd, void *unused, unsigned short *rows_out, - unsigned short *cols_out) -{ - int rows, cols; - int ret; - - ret = os_window_size(fd, &rows, &cols); - if(ret < 0) - return ret; - - ret = ((*rows_out != rows) || (*cols_out != cols)); - - *rows_out = rows; - *cols_out = cols; - - return ret; -} - -void generic_free(void *data) -{ - kfree(data); -} - static void tty_receive_char(struct tty_struct *tty, char ch) { - if(tty == NULL) return; + if (tty == NULL) + return; - if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) { - if(ch == STOP_CHAR(tty)){ + if (I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) { + if (ch == STOP_CHAR(tty)) { stop_tty(tty); return; } - else if(ch == START_CHAR(tty)){ + else if (ch == START_CHAR(tty)) { start_tty(tty); return; } @@ -159,14 +103,14 @@ static int open_one_chan(struct chan *chan) { int fd, err; - if(chan->opened) + if (chan->opened) return 0; - if(chan->ops->open == NULL) + if (chan->ops->open == NULL) fd = 0; else fd = (*chan->ops->open)(chan->input, chan->output, chan->primary, chan->data, &chan->dev); - if(fd < 0) + if (fd < 0) return fd; err = os_set_fd_block(fd, 0); @@ -187,10 +131,10 @@ int open_chan(struct list_head *chans) struct chan *chan; int ret, err = 0; - list_for_each(ele, chans){ + list_for_each(ele, chans) { chan = list_entry(ele, struct chan, list); ret = open_one_chan(chan); - if(chan->primary) + if (chan->primary) err = ret; } return err; @@ -201,9 +145,9 @@ void chan_enable_winch(struct list_head *chans, struct tty_struct *tty) struct list_head *ele; struct chan *chan; - list_for_each(ele, chans){ + list_for_each(ele, chans) { chan = list_entry(ele, struct chan, list); - if(chan->primary && chan->output && chan->ops->winch){ + if (chan->primary && chan->output && chan->ops->winch) { register_winch(chan->fd, tty); return; } @@ -216,7 +160,7 @@ int enable_chan(struct line *line) struct chan *chan; int err; - list_for_each(ele, &line->chan_list){ + list_for_each(ele, &line->chan_list) { chan = list_entry(ele, struct chan, list); err = open_one_chan(chan); if (err) { @@ -226,7 +170,7 @@ int enable_chan(struct line *line) continue; } - if(chan->enabled) + if (chan->enabled) continue; err = line_setup_irq(chan->fd, chan->input, chan->output, line, chan); @@ -263,12 +207,12 @@ void free_irqs(void) list_splice_init(&irqs_to_free, &list); spin_unlock_irqrestore(&irqs_to_free_lock, flags); - list_for_each(ele, &list){ + list_for_each(ele, &list) { chan = list_entry(ele, struct chan, free_list); - if(chan->input) + if (chan->input) free_irq(chan->line->driver->read_irq, chan); - if(chan->output) + if (chan->output) free_irq(chan->line->driver->write_irq, chan); chan->enabled = 0; } @@ -278,22 +222,22 @@ static void close_one_chan(struct chan *chan, int delay_free_irq) { unsigned long flags; - if(!chan->opened) + if (!chan->opened) return; - if(delay_free_irq){ + if (delay_free_irq) { spin_lock_irqsave(&irqs_to_free_lock, flags); list_add(&chan->free_list, &irqs_to_free); spin_unlock_irqrestore(&irqs_to_free_lock, flags); } else { - if(chan->input) + if (chan->input) free_irq(chan->line->driver->read_irq, chan); - if(chan->output) + if (chan->output) free_irq(chan->line->driver->write_irq, chan); chan->enabled = 0; } - if(chan->ops->close != NULL) + if (chan->ops->close != NULL) (*chan->ops->close)(chan->fd, chan->data); chan->opened = 0; @@ -322,7 +266,7 @@ void deactivate_chan(struct list_head *chans, int irq) list_for_each(ele, chans) { chan = list_entry(ele, struct chan, list); - if(chan->enabled && chan->input) + if (chan->enabled && chan->input) deactivate_fd(chan->fd, irq); } } @@ -335,7 +279,7 @@ void reactivate_chan(struct list_head *chans, int irq) list_for_each(ele, chans) { chan = list_entry(ele, struct chan, list); - if(chan->enabled && chan->input) + if (chan->enabled && chan->input) reactivate_fd(chan->fd, irq); } } @@ -347,10 +291,14 @@ int write_chan(struct list_head *chans, const char *buf, int len, struct chan *chan = NULL; int n, ret = 0; + if (len == 0) + return 0; + list_for_each(ele, chans) { chan = list_entry(ele, struct chan, list); if (!chan->output || (chan->ops->write == NULL)) continue; + n = chan->ops->write(chan->fd, buf, len, chan->data); if (chan->primary) { ret = n; @@ -367,12 +315,14 @@ int console_write_chan(struct list_head *chans, const char *buf, int len) struct chan *chan; int n, ret = 0; - list_for_each(ele, chans){ + list_for_each(ele, chans) { chan = list_entry(ele, struct chan, list); - if(!chan->output || (chan->ops->console_write == NULL)) + if (!chan->output || (chan->ops->console_write == NULL)) continue; + n = chan->ops->console_write(chan->fd, buf, len); - if(chan->primary) ret = n; + if (chan->primary) + ret = n; } return ret; } @@ -382,10 +332,11 @@ int console_open_chan(struct line *line, struct console *co) int err; err = open_chan(&line->chan_list); - if(err) + if (err) return err; - printk("Console initialized on /dev/%s%d\n", co->name, co->index); + printk(KERN_INFO "Console initialized on /dev/%s%d\n", co->name, + co->index); return 0; } @@ -395,10 +346,10 @@ int chan_window_size(struct list_head *chans, unsigned short *rows_out, struct list_head *ele; struct chan *chan; - list_for_each(ele, chans){ + list_for_each(ele, chans) { chan = list_entry(ele, struct chan, list); - if(chan->primary){ - if(chan->ops->window_size == NULL) + if (chan->primary) { + if (chan->ops->window_size == NULL) return 0; return chan->ops->window_size(chan->fd, chan->data, rows_out, cols_out); @@ -413,10 +364,11 @@ static void free_one_chan(struct chan *chan, int delay_free_irq) close_one_chan(chan, delay_free_irq); - if(chan->ops->free != NULL) + if (chan->ops->free != NULL) (*chan->ops->free)(chan->data); - if(chan->primary && chan->output) ignore_sigio_fd(chan->fd); + if (chan->primary && chan->output) + ignore_sigio_fd(chan->fd); kfree(chan); } @@ -425,7 +377,7 @@ static void free_chan(struct list_head *chans, int delay_free_irq) struct list_head *ele, *next; struct chan *chan; - list_for_each_safe(ele, next, chans){ + list_for_each_safe(ele, next, chans) { chan = list_entry(ele, struct chan, list); free_one_chan(chan, delay_free_irq); } @@ -436,14 +388,14 @@ static int one_chan_config_string(struct chan *chan, char *str, int size, { int n = 0; - if(chan == NULL){ + if (chan == NULL) { CONFIG_CHUNK(str, size, n, "none", 1); return n; } CONFIG_CHUNK(str, size, n, chan->ops->type, 0); - if(chan->dev == NULL){ + if (chan->dev == NULL) { CONFIG_CHUNK(str, size, n, "", 1); return n; } @@ -463,7 +415,7 @@ static int chan_pair_config_string(struct chan *in, struct chan *out, str += n; size -= n; - if(in == out){ + if (in == out) { CONFIG_CHUNK(str, size, n, "", 1); return n; } @@ -483,13 +435,13 @@ int chan_config_string(struct list_head *chans, char *str, int size, struct list_head *ele; struct chan *chan, *in = NULL, *out = NULL; - list_for_each(ele, chans){ + list_for_each(ele, chans) { chan = list_entry(ele, struct chan, list); - if(!chan->primary) + if (!chan->primary) continue; - if(chan->input) + if (chan->input) in = chan; - if(chan->output) + if (chan->output) out = chan; } @@ -548,27 +500,27 @@ static struct chan *parse_chan(struct line *line, char *str, int device, ops = NULL; data = NULL; - for(i = 0; i < ARRAY_SIZE(chan_table); i++){ + for(i = 0; i < ARRAY_SIZE(chan_table); i++) { entry = &chan_table[i]; - if(!strncmp(str, entry->key, strlen(entry->key))){ + if (!strncmp(str, entry->key, strlen(entry->key))) { ops = entry->ops; str += strlen(entry->key); break; } } - if(ops == NULL){ + if (ops == NULL) { *error_out = "No match for configured backends"; return NULL; } data = (*ops->init)(str, device, opts); - if(data == NULL){ + if (data == NULL) { *error_out = "Configuration failed"; return NULL; } chan = kmalloc(sizeof(*chan), GFP_ATOMIC); - if(chan == NULL){ + if (chan == NULL) { *error_out = "Memory allocation failed"; return NULL; } @@ -594,26 +546,26 @@ int parse_chan_pair(char *str, struct line *line, int device, struct chan *new, *chan; char *in, *out; - if(!list_empty(chans)){ + if (!list_empty(chans)) { chan = list_entry(chans->next, struct chan, list); free_chan(chans, 0); INIT_LIST_HEAD(chans); } out = strchr(str, ','); - if(out != NULL){ + if (out != NULL) { in = str; *out = '\0'; out++; new = parse_chan(line, in, device, opts, error_out); - if(new == NULL) + if (new == NULL) return -1; new->input = 1; list_add(&new->list, chans); new = parse_chan(line, out, device, opts, error_out); - if(new == NULL) + if (new == NULL) return -1; list_add(&new->list, chans); @@ -621,7 +573,7 @@ int parse_chan_pair(char *str, struct line *line, int device, } else { new = parse_chan(line, str, device, opts, error_out); - if(new == NULL) + if (new == NULL) return -1; list_add(&new->list, chans); @@ -636,9 +588,9 @@ int chan_out_fd(struct list_head *chans) struct list_head *ele; struct chan *chan; - list_for_each(ele, chans){ + list_for_each(ele, chans) { chan = list_entry(ele, struct chan, list); - if(chan->primary && chan->output) + if (chan->primary && chan->output) return chan->fd; } return -1; @@ -652,23 +604,25 @@ void chan_interrupt(struct list_head *chans, struct delayed_work *task, int err; char c; - list_for_each_safe(ele, next, chans){ + list_for_each_safe(ele, next, chans) { chan = list_entry(ele, struct chan, list); - if(!chan->input || (chan->ops->read == NULL)) continue; + if (!chan->input || (chan->ops->read == NULL)) + continue; do { if (tty && !tty_buffer_request_room(tty, 1)) { schedule_delayed_work(task, 1); goto out; } err = chan->ops->read(chan->fd, &c, chan->data); - if(err > 0) + if (err > 0) tty_receive_char(tty, c); - } while(err > 0); + } while (err > 0); - if(err == 0) reactivate_fd(chan->fd, irq); - if(err == -EIO){ - if(chan->primary){ - if(tty != NULL) + if (err == 0) + reactivate_fd(chan->fd, irq); + if (err == -EIO) { + if (chan->primary) { + if (tty != NULL) tty_hangup(tty); close_chan(chans, 1); return; @@ -677,5 +631,6 @@ void chan_interrupt(struct list_head *chans, struct delayed_work *task, } } out: - if(tty) tty_flip_buffer_push(tty); + if (tty) + tty_flip_buffer_push(tty); } diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 4d438f36ea2e..b88e93b3a39f 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -1,51 +1,107 @@ -/* - * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) * Licensed under the GPL */ -#include <unistd.h> #include <stdlib.h> +#include <unistd.h> #include <errno.h> -#include <termios.h> -#include <string.h> -#include <signal.h> #include <sched.h> -#include <sys/stat.h> +#include <signal.h> +#include <termios.h> #include <sys/ioctl.h> -#include <sys/socket.h> -#include "kern_util.h" #include "chan_user.h" -#include "user.h" #include "os.h" -#include "choose-mode.h" -#include "mode.h" +#include "um_malloc.h" +#include "user.h" + +void generic_close(int fd, void *unused) +{ + close(fd); +} + +int generic_read(int fd, char *c_out, void *unused) +{ + int n; + + n = read(fd, c_out, sizeof(*c_out)); + if (n > 0) + return n; + else if (errno == EAGAIN) + return 0; + else if (n == 0) + return -EIO; + return -errno; +} + +/* XXX Trivial wrapper around write */ + +int generic_write(int fd, const char *buf, int n, void *unused) +{ + int err; + + err = write(fd, buf, n); + if (err > 0) + return err; + else if (errno == EAGAIN) + return 0; + else if (err == 0) + return -EIO; + return -errno; +} + +int generic_window_size(int fd, void *unused, unsigned short *rows_out, + unsigned short *cols_out) +{ + struct winsize size; + int ret; + + if (ioctl(fd, TIOCGWINSZ, &size) < 0) + return -errno; + + ret = ((*rows_out != size.ws_row) || (*cols_out != size.ws_col)); + + *rows_out = size.ws_row; + *cols_out = size.ws_col; + + return ret; +} + +void generic_free(void *data) +{ + kfree(data); +} int generic_console_write(int fd, const char *buf, int n) { struct termios save, new; int err; - if(isatty(fd)){ + if (isatty(fd)) { CATCH_EINTR(err = tcgetattr(fd, &save)); if (err) goto error; new = save; - /* The terminal becomes a bit less raw, to handle \n also as + /* + * The terminal becomes a bit less raw, to handle \n also as * "Carriage Return", not only as "New Line". Otherwise, the new - * line won't start at the first column.*/ + * line won't start at the first column. + */ new.c_oflag |= OPOST; CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &new)); if (err) goto error; } err = generic_write(fd, buf, n, NULL); - /* Restore raw mode, in any case; we *must* ignore any error apart - * EINTR, except for debug.*/ - if(isatty(fd)) + /* + * Restore raw mode, in any case; we *must* ignore any error apart + * EINTR, except for debug. + */ + if (isatty(fd)) CATCH_EINTR(tcsetattr(fd, TCSAFLUSH, &save)); - return(err); + return err; error: - return(-errno); + return -errno; } /* @@ -82,62 +138,73 @@ static int winch_thread(void *arg) struct winch_data *data = arg; sigset_t sigs; int pty_fd, pipe_fd; - int count, err; + int count; char c = 1; pty_fd = data->pty_fd; pipe_fd = data->pipe_fd; - count = os_write_file(pipe_fd, &c, sizeof(c)); - if(count != sizeof(c)) - printk("winch_thread : failed to write synchronization " - "byte, err = %d\n", -count); + count = write(pipe_fd, &c, sizeof(c)); + if (count != sizeof(c)) + printk(UM_KERN_ERR "winch_thread : failed to write " + "synchronization byte, err = %d\n", -count); - /* We are not using SIG_IGN on purpose, so don't fix it as I thought to + /* + * We are not using SIG_IGN on purpose, so don't fix it as I thought to * do! If using SIG_IGN, the sigsuspend() call below would not stop on - * SIGWINCH. */ + * SIGWINCH. + */ signal(SIGWINCH, winch_handler); sigfillset(&sigs); /* Block all signals possible. */ - if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){ - printk("winch_thread : sigprocmask failed, errno = %d\n", - errno); + if (sigprocmask(SIG_SETMASK, &sigs, NULL) < 0) { + printk(UM_KERN_ERR "winch_thread : sigprocmask failed, " + "errno = %d\n", errno); exit(1); } /* In sigsuspend(), block anything else than SIGWINCH. */ sigdelset(&sigs, SIGWINCH); - if(setsid() < 0){ - printk("winch_thread : setsid failed, errno = %d\n", errno); + if (setsid() < 0) { + printk(UM_KERN_ERR "winch_thread : setsid failed, errno = %d\n", + errno); + exit(1); + } + + if (ioctl(pty_fd, TIOCSCTTY, 0) < 0) { + printk(UM_KERN_ERR "winch_thread : TIOCSCTTY failed on " + "fd %d err = %d\n", pty_fd, errno); exit(1); } - err = os_new_tty_pgrp(pty_fd, os_getpid()); - if(err < 0){ - printk("winch_thread : new_tty_pgrp failed on fd %d, " - "err = %d\n", pty_fd, -err); + if (tcsetpgrp(pty_fd, os_getpid()) < 0) { + printk(UM_KERN_ERR "winch_thread : tcsetpgrp failed on " + "fd %d err = %d\n", pty_fd, errno); exit(1); } - /* These are synchronization calls between various UML threads on the + /* + * These are synchronization calls between various UML threads on the * host - since they are not different kernel threads, we cannot use * kernel semaphores. We don't use SysV semaphores because they are - * persistent. */ - count = os_read_file(pipe_fd, &c, sizeof(c)); - if(count != sizeof(c)) - printk("winch_thread : failed to read synchronization byte, " - "err = %d\n", -count); - - while(1){ - /* This will be interrupted by SIGWINCH only, since + * persistent. + */ + count = read(pipe_fd, &c, sizeof(c)); + if (count != sizeof(c)) + printk(UM_KERN_ERR "winch_thread : failed to read " + "synchronization byte, err = %d\n", errno); + + while(1) { + /* + * This will be interrupted by SIGWINCH only, since * other signals are blocked. */ sigsuspend(&sigs); - count = os_write_file(pipe_fd, &c, sizeof(c)); - if(count != sizeof(c)) - printk("winch_thread : write failed, err = %d\n", - -count); + count = write(pipe_fd, &c, sizeof(c)); + if (count != sizeof(c)) + printk(UM_KERN_ERR "winch_thread : write failed, " + "err = %d\n", errno); } } @@ -149,44 +216,49 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out, char c; err = os_pipe(fds, 1, 1); - if(err < 0){ - printk("winch_tramp : os_pipe failed, err = %d\n", -err); + if (err < 0) { + printk(UM_KERN_ERR "winch_tramp : os_pipe failed, err = %d\n", + -err); goto 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 + /* + * CLONE_FILES so this thread doesn't hold open files which are open * 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_out); - if(err < 0){ - printk("fork of winch_thread failed - errno = %d\n", -err); + if (err < 0) { + printk(UM_KERN_ERR "fork of winch_thread failed - errno = %d\n", + -err); goto out_close; } *fd_out = fds[0]; - n = os_read_file(fds[0], &c, sizeof(c)); - if(n != sizeof(c)){ - printk("winch_tramp : failed to read synchronization byte\n"); - printk("read failed, err = %d\n", -n); - printk("fd %d will not support SIGWINCH\n", fd); - err = -EINVAL; + n = read(fds[0], &c, sizeof(c)); + if (n != sizeof(c)) { + printk(UM_KERN_ERR "winch_tramp : failed to read " + "synchronization byte\n"); + printk(UM_KERN_ERR "read failed, err = %d\n", errno); + printk(UM_KERN_ERR "fd %d will not support SIGWINCH\n", fd); + err = -EINVAL; goto out_close; } if (os_set_fd_block(*fd_out, 0)) { - printk("winch_tramp: failed to set thread_fd non-blocking.\n"); + printk(UM_KERN_ERR "winch_tramp: failed to set thread_fd " + "non-blocking.\n"); goto out_close; } return err; out_close: - os_close_file(fds[1]); - os_close_file(fds[0]); + close(fds[1]); + close(fds[0]); out: return err; } @@ -197,21 +269,20 @@ void register_winch(int fd, struct tty_struct *tty) int pid, thread, count, thread_fd = -1; char c = 1; - if(!isatty(fd)) + if (!isatty(fd)) return; pid = tcgetpgrp(fd); - if (!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, tty) && - (pid == -1)) { + if (!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); + count = write(thread_fd, &c, sizeof(c)); + if (count != sizeof(c)) + printk(UM_KERN_ERR "register_winch : failed to write " + "synchronization byte, err = %d\n", errno); } } diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c index 0ec4052db9c5..93f227a25ba4 100644 --- a/arch/um/drivers/cow_user.c +++ b/arch/um/drivers/cow_user.c @@ -1,17 +1,18 @@ -#include <stddef.h> -#include <string.h> -#include <errno.h> -/* _XOPEN_SOURCE is needed for pread, but we define _GNU_SOURCE, which defines +/* + * Copyright (C) 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) + * Licensed under the GPL + */ + +/* + * _XOPEN_SOURCE is needed for pread, but we define _GNU_SOURCE, which defines * that. */ #include <unistd.h> #include <byteswap.h> -#include <sys/time.h> -#include <sys/param.h> -#include <sys/user.h> - -#include "os.h" - +#include <errno.h> +#include <string.h> +#include <arpa/inet.h> +#include <asm/types.h> #include "cow.h" #include "cow_sys.h" @@ -28,7 +29,8 @@ struct cow_header_v1 { __s32 sectorsize; } __attribute__((packed)); -/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in +/* + * Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in * case other systems have different values for MAXPATHLEN. * * The same must hold for V2 - we want file format compatibility, not anything @@ -46,7 +48,8 @@ struct cow_header_v2 { __s32 sectorsize; } __attribute__((packed)); -/* Changes from V2 - +/* + * Changes from V2 - * PATH_LEN_V3 as described above * Explicitly specify field bit lengths for systems with different * lengths for the usual C types. Not sure whether char or @@ -70,7 +73,8 @@ struct cow_header_v2 { * Fixed (finally!) the rounding bug */ -/* Until Dec2005, __attribute__((packed)) was left out from the below +/* + * Until Dec2005, __attribute__((packed)) was left out from the below * definition, leading on 64-bit systems to 4 bytes of padding after mtime, to * align size to 8-byte alignment. This shifted all fields above (no padding * was present on 32-bit, no other padding was added). @@ -122,7 +126,7 @@ void cow_sizes(int version, __u64 size, int sectorsize, int align, int bitmap_offset, unsigned long *bitmap_len_out, int *data_offset_out) { - if(version < 3){ + if (version < 3) { *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize); *data_offset_out = bitmap_offset + *bitmap_len_out; @@ -144,46 +148,46 @@ static int absolutize(char *to, int size, char *from) char save_cwd[256], *slash; int remaining; - if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) { + if (getcwd(save_cwd, sizeof(save_cwd)) == NULL) { cow_printf("absolutize : unable to get cwd - errno = %d\n", errno); - return(-1); + return -1; } slash = strrchr(from, '/'); - if(slash != NULL){ + if (slash != NULL) { *slash = '\0'; - if(chdir(from)){ + if (chdir(from)) { *slash = '/'; cow_printf("absolutize : Can't cd to '%s' - " "errno = %d\n", from, errno); - return(-1); + return -1; } *slash = '/'; - if(getcwd(to, size) == NULL){ + if (getcwd(to, size) == NULL) { cow_printf("absolutize : unable to get cwd of '%s' - " "errno = %d\n", from, errno); - return(-1); + return -1; } remaining = size - strlen(to); - if(strlen(slash) + 1 > remaining){ + if (strlen(slash) + 1 > remaining) { cow_printf("absolutize : unable to fit '%s' into %d " "chars\n", from, size); - return(-1); + return -1; } strcat(to, slash); } else { - if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){ + if (strlen(save_cwd) + 1 + strlen(from) + 1 > size) { cow_printf("absolutize : unable to fit '%s' into %d " "chars\n", from, size); - return(-1); + return -1; } strcpy(to, save_cwd); strcat(to, "/"); strcat(to, from); } chdir(save_cwd); - return(0); + return 0; } int write_cow_header(char *cow_file, int fd, char *backing_file, @@ -194,22 +198,23 @@ int write_cow_header(char *cow_file, int fd, char *backing_file, int err; err = cow_seek_file(fd, 0); - if(err < 0){ + if (err < 0) { cow_printf("write_cow_header - lseek failed, err = %d\n", -err); goto out; } err = -ENOMEM; header = cow_malloc(sizeof(*header)); - if(header == NULL){ - cow_printf("write_cow_header - failed to allocate COW V3 header\n"); + if (header == NULL) { + cow_printf("write_cow_header - failed to allocate COW V3 " + "header\n"); goto out; } header->magic = htonl(COW_MAGIC); header->version = htonl(COW_VERSION); err = -EINVAL; - if(strlen(backing_file) > sizeof(header->backing_file) - 1){ + if (strlen(backing_file) > sizeof(header->backing_file) - 1) { /* Below, %zd is for a size_t value */ cow_printf("Backing file name \"%s\" is too long - names are " "limited to %zd characters\n", backing_file, @@ -217,12 +222,12 @@ int write_cow_header(char *cow_file, int fd, char *backing_file, goto out_free; } - if(absolutize(header->backing_file, sizeof(header->backing_file), + if (absolutize(header->backing_file, sizeof(header->backing_file), backing_file)) goto out_free; err = os_file_modtime(header->backing_file, &modtime); - if(err < 0){ + if (err < 0) { cow_printf("write_cow_header - backing file '%s' mtime " "request failed, err = %d\n", header->backing_file, -err); @@ -230,7 +235,7 @@ int write_cow_header(char *cow_file, int fd, char *backing_file, } err = cow_file_size(header->backing_file, size); - if(err < 0){ + if (err < 0) { cow_printf("write_cow_header - couldn't get size of " "backing file '%s', err = %d\n", header->backing_file, -err); @@ -244,7 +249,7 @@ int write_cow_header(char *cow_file, int fd, char *backing_file, header->cow_format = COW_BITMAP; err = cow_write_file(fd, header, sizeof(*header)); - if(err != sizeof(*header)){ + if (err != sizeof(*header)) { cow_printf("write_cow_header - write of header to " "new COW file '%s' failed, err = %d\n", cow_file, -err); @@ -254,14 +259,14 @@ int write_cow_header(char *cow_file, int fd, char *backing_file, out_free: cow_free(header); out: - return(err); + return err; } int file_reader(__u64 offset, char *buf, int len, void *arg) { int fd = *((int *) arg); - return(pread(fd, buf, len, offset)); + return pread(fd, buf, len, offset); } /* XXX Need to sanity-check the values read from the header */ @@ -278,31 +283,29 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, unsigned long version, magic; header = cow_malloc(sizeof(*header)); - if(header == NULL){ + if (header == NULL) { cow_printf("read_cow_header - Failed to allocate header\n"); - return(-ENOMEM); + return -ENOMEM; } err = -EINVAL; n = (*reader)(0, (char *) header, sizeof(*header), arg); - if(n < offsetof(typeof(header->v1), backing_file)){ + if (n < offsetof(typeof(header->v1), backing_file)) { cow_printf("read_cow_header - short header\n"); goto out; } magic = header->v1.magic; - if(magic == COW_MAGIC) { + if (magic == COW_MAGIC) version = header->v1.version; - } - else if(magic == ntohl(COW_MAGIC)){ + else if (magic == ntohl(COW_MAGIC)) version = ntohl(header->v1.version); - } /* No error printed because the non-COW case comes through here */ else goto out; *version_out = version; - if(version == 1){ - if(n < sizeof(header->v1)){ + if (version == 1) { + if (n < sizeof(header->v1)) { cow_printf("read_cow_header - failed to read V1 " "header\n"); goto out; @@ -314,8 +317,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, *align_out = *sectorsize_out; file = header->v1.backing_file; } - else if(version == 2){ - if(n < sizeof(header->v2)){ + else if (version == 2) { + if (n < sizeof(header->v2)) { cow_printf("read_cow_header - failed to read V2 " "header\n"); goto out; @@ -328,8 +331,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, file = header->v2.backing_file; } /* This is very subtle - see above at union cow_header definition */ - else if(version == 3 && (*((int*)header->v3.backing_file) != 0)){ - if(n < sizeof(header->v3)){ + else if (version == 3 && (*((int*)header->v3.backing_file) != 0)) { + if (n < sizeof(header->v3)) { cow_printf("read_cow_header - failed to read V3 " "header\n"); goto out; @@ -345,17 +348,18 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out); file = header->v3.backing_file; } - else if(version == 3){ + else if (version == 3) { cow_printf("read_cow_header - broken V3 file with" " 64-bit layout - recovering content.\n"); - if(n < sizeof(header->v3_b)){ + if (n < sizeof(header->v3_b)) { cow_printf("read_cow_header - failed to read V3 " "header\n"); goto out; } - /* this was used until Dec2005 - 64bits are needed to represent + /* + * this was used until Dec2005 - 64bits are needed to represent * 2038+. I.e. we can safely do this truncating cast. * * Additionally, we must use ntohl() instead of ntohll(), since @@ -381,7 +385,7 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, } err = -ENOMEM; *backing_file_out = cow_strdup(file); - if(*backing_file_out == NULL){ + if (*backing_file_out == NULL) { cow_printf("read_cow_header - failed to allocate backing " "file\n"); goto out; @@ -389,7 +393,7 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, err = 0; out: cow_free(header); - return(err); + return err; } int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize, @@ -402,7 +406,7 @@ int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize, err = write_cow_header(cow_file, fd, backing_file, sectorsize, alignment, &size); - if(err) + if (err) goto out; *bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment); @@ -411,17 +415,18 @@ int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize, offset = *data_offset_out + size - sizeof(zero); err = cow_seek_file(fd, offset); - if(err < 0){ + if (err < 0) { cow_printf("cow bitmap lseek failed : err = %d\n", -err); goto out; } - /* does not really matter how much we write it is just to set EOF + /* + * does not really matter how much we write it is just to set EOF * this also sets the entire COW bitmap * to zero without having to allocate it */ err = cow_write_file(fd, &zero, sizeof(zero)); - if(err != sizeof(zero)){ + if (err != sizeof(zero)) { cow_printf("Write of bitmap to new COW file '%s' failed, " "err = %d\n", cow_file, -err); if (err >= 0) @@ -429,15 +434,7 @@ int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize, goto out; } - return(0); - + return 0; out: - return(err); + return err; } - -/* - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/daemon.h b/arch/um/drivers/daemon.h index 3bc3cf6b94aa..6e0e891f8a00 100644 --- a/arch/um/drivers/daemon.h +++ b/arch/um/drivers/daemon.h @@ -1,8 +1,11 @@ -/* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) +/* + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ +#ifndef __DAEMON_H__ +#define __DAEMON_H__ + #include "net_user.h" #define SWITCH_VERSION 3 @@ -20,16 +23,7 @@ struct daemon_data { extern const struct net_user_info daemon_user_info; -extern int daemon_user_write(int fd, void *buf, int len, +extern int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri); -/* - * 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: - */ +#endif diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c index adeece11e596..d53ff52bb404 100644 --- a/arch/um/drivers/daemon_kern.c +++ b/arch/um/drivers/daemon_kern.c @@ -1,16 +1,14 @@ /* - * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and * James Leu (jleu@mindspring.net). + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Copyright (C) 2001 by various other people who didn't put their name here. * Licensed under the GPL. */ -#include "linux/kernel.h" #include "linux/init.h" -#include "linux/netdevice.h" -#include "linux/etherdevice.h" +#include <linux/netdevice.h> #include "net_kern.h" -#include "net_user.h" #include "daemon.h" struct daemon_init { @@ -36,25 +34,21 @@ static void daemon_init(struct net_device *dev, void *data) dpri->data_addr = NULL; dpri->local_addr = NULL; - printk("daemon backend (uml_switch version %d) - %s:%s", + printk("daemon backend (uml_switch version %d) - %s:%s", SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock); printk("\n"); } -static int daemon_read(int fd, struct sk_buff **skb, - struct uml_net_private *lp) +static int daemon_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); - if(*skb == NULL) return(-ENOMEM); - return(net_recvfrom(fd, skb_mac_header(*skb), - (*skb)->dev->mtu + ETH_HEADER_OTHER)); + return net_recvfrom(fd, skb_mac_header(skb), + skb->dev->mtu + ETH_HEADER_OTHER); } -static int daemon_write(int fd, struct sk_buff **skb, - struct uml_net_private *lp) +static int daemon_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - return(daemon_user_write(fd, (*skb)->data, (*skb)->len, - (struct daemon_data *) &lp->user)); + return daemon_user_write(fd, skb->data, skb->len, + (struct daemon_data *) &lp->user); } static const struct net_kern_info daemon_kern_info = { @@ -72,14 +66,14 @@ static int daemon_setup(char *str, char **mac_out, void *data) *init = ((struct daemon_init) { .sock_type = "unix", .ctl_sock = "/tmp/uml.ctl" }); - + remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock, NULL); - if(remain != NULL) + if (remain != NULL) printk(KERN_WARNING "daemon_setup : Ignoring data socket " "specification\n"); - - return(1); + + return 1; } static struct transport daemon_transport = { diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index 8d2008f06682..f23c109a055c 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -1,24 +1,23 @@ /* - * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and * James Leu (jleu@mindspring.net). * Copyright (C) 2001 by various other people who didn't put their name here. * Licensed under the GPL. */ -#include <errno.h> -#include <unistd.h> #include <stdint.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> #include <sys/socket.h> -#include <sys/un.h> #include <sys/time.h> -#include "net_user.h" +#include <sys/un.h> #include "daemon.h" -#include "kern_util.h" -#include "user.h" +#include "net_user.h" #include "os.h" #include "um_malloc.h" - -#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) +#include "user.h" enum request_type { REQ_NEW_CONTROL }; @@ -36,8 +35,9 @@ static struct sockaddr_un *new_addr(void *name, int len) struct sockaddr_un *sun; sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL); - if(sun == NULL){ - printk("new_addr: allocation of sockaddr_un failed\n"); + if (sun == NULL) { + printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un " + "failed\n"); return NULL; } sun->sun_family = AF_UNIX; @@ -54,38 +54,39 @@ static int connect_to_switch(struct daemon_data *pri) int fd, n, err; pri->control = socket(AF_UNIX, SOCK_STREAM, 0); - if(pri->control < 0){ + if (pri->control < 0) { err = -errno; - printk("daemon_open : control socket failed, errno = %d\n", - -err); + printk(UM_KERN_ERR "daemon_open : control socket failed, " + "errno = %d\n", -err); return err; } - if(connect(pri->control, (struct sockaddr *) ctl_addr, - sizeof(*ctl_addr)) < 0){ + if (connect(pri->control, (struct sockaddr *) ctl_addr, + sizeof(*ctl_addr)) < 0) { err = -errno; - printk("daemon_open : control connect failed, errno = %d\n", - -err); + printk(UM_KERN_ERR "daemon_open : control connect failed, " + "errno = %d\n", -err); goto out; } fd = socket(AF_UNIX, SOCK_DGRAM, 0); - if(fd < 0){ + if (fd < 0) { err = -errno; - printk("daemon_open : data socket failed, errno = %d\n", - -err); + printk(UM_KERN_ERR "daemon_open : data socket failed, " + "errno = %d\n", -err); goto out; } - if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){ + if (bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0) { err = -errno; - printk("daemon_open : data bind failed, errno = %d\n", - -err); + printk(UM_KERN_ERR "daemon_open : data bind failed, " + "errno = %d\n", -err); goto out_close; } sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL); - if(sun == NULL){ - printk("new_addr: allocation of sockaddr_un failed\n"); + if (sun == NULL) { + printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un " + "failed\n"); err = -ENOMEM; goto out_close; } @@ -94,18 +95,18 @@ static int connect_to_switch(struct daemon_data *pri) req.version = SWITCH_VERSION; req.type = REQ_NEW_CONTROL; req.sock = *local_addr; - n = os_write_file(pri->control, &req, sizeof(req)); - if(n != sizeof(req)){ - printk("daemon_open : control setup request failed, err = %d\n", - -n); + n = write(pri->control, &req, sizeof(req)); + if (n != sizeof(req)) { + printk(UM_KERN_ERR "daemon_open : control setup request " + "failed, err = %d\n", -errno); err = -ENOTCONN; goto out_free; } - n = os_read_file(pri->control, sun, sizeof(*sun)); - if(n != sizeof(*sun)){ - printk("daemon_open : read of data socket failed, err = %d\n", - -n); + n = read(pri->control, sun, sizeof(*sun)); + if (n != sizeof(*sun)) { + printk(UM_KERN_ERR "daemon_open : read of data socket failed, " + "err = %d\n", -errno); err = -ENOTCONN; goto out_free; } @@ -116,9 +117,9 @@ static int connect_to_switch(struct daemon_data *pri) out_free: kfree(sun); out_close: - os_close_file(fd); + close(fd); out: - os_close_file(pri->control); + close(pri->control); return err; } @@ -132,8 +133,8 @@ static int daemon_user_init(void *data, void *dev) int usecs; } name; - if(!strcmp(pri->sock_type, "unix")) - pri->ctl_addr = new_addr(pri->ctl_sock, + if (!strcmp(pri->sock_type, "unix")) + pri->ctl_addr = new_addr(pri->ctl_sock, strlen(pri->ctl_sock) + 1); name.zero = 0; name.pid = os_getpid(); @@ -142,7 +143,7 @@ static int daemon_user_init(void *data, void *dev) pri->local_addr = new_addr(&name, sizeof(name)); pri->dev = dev; pri->fd = connect_to_switch(pri); - if(pri->fd < 0){ + if (pri->fd < 0) { kfree(pri->local_addr); pri->local_addr = NULL; return pri->fd; @@ -161,9 +162,9 @@ static void daemon_remove(void *data) { struct daemon_data *pri = data; - os_close_file(pri->fd); + close(pri->fd); pri->fd = -1; - os_close_file(pri->control); + close(pri->control); pri->control = -1; kfree(pri->data_addr); @@ -181,18 +182,13 @@ int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri) return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); } -static int daemon_set_mtu(int mtu, void *data) -{ - return mtu; -} - const struct net_user_info daemon_user_info = { .init = daemon_user_init, .open = daemon_open, .close = NULL, .remove = daemon_remove, - .set_mtu = daemon_set_mtu, .add_address = NULL, .delete_address = NULL, - .max_packet = MAX_PACKET - ETH_HEADER_OTHER + .mtu = ETH_MAX_PACKET, + .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER, }; diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c index 39c01ffd45c9..0a2bb5b64b82 100644 --- a/arch/um/drivers/fd.c +++ b/arch/um/drivers/fd.c @@ -1,17 +1,18 @@ -/* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) +/* + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) * Licensed under the GPL */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> -#include <termios.h> #include <errno.h> -#include "user.h" +#include <termios.h> #include "chan_user.h" +#include "kern_constants.h" #include "os.h" #include "um_malloc.h" +#include "user.h" struct fd_chan { int fd; @@ -26,22 +27,26 @@ static void *fd_init(char *str, int device, const struct chan_opts *opts) char *end; int n; - if(*str != ':'){ - printk("fd_init : channel type 'fd' must specify a file " - "descriptor\n"); - return(NULL); + if (*str != ':') { + printk(UM_KERN_ERR "fd_init : channel type 'fd' must specify a " + "file descriptor\n"); + return NULL; } str++; n = strtoul(str, &end, 0); - if((*end != '\0') || (end == str)){ - printk("fd_init : couldn't parse file descriptor '%s'\n", str); - return(NULL); + if ((*end != '\0') || (end == str)) { + printk(UM_KERN_ERR "fd_init : couldn't parse file descriptor " + "'%s'\n", str); + return NULL; } + data = kmalloc(sizeof(*data), UM_GFP_KERNEL); - if(data == NULL) return(NULL); + if (data == NULL) + return NULL; + *data = ((struct fd_chan) { .fd = n, .raw = opts->raw }); - return(data); + return data; } static int fd_open(int input, int output, int primary, void *d, char **dev_out) @@ -49,18 +54,18 @@ static int fd_open(int input, int output, int primary, void *d, char **dev_out) struct fd_chan *data = d; int err; - if(data->raw && isatty(data->fd)){ + if (data->raw && isatty(data->fd)) { CATCH_EINTR(err = tcgetattr(data->fd, &data->tt)); - if(err) - return(err); + if (err) + return err; err = raw(data->fd); - if(err) - return(err); + if (err) + return err; } sprintf(data->str, "%d", data->fd); *dev_out = data->str; - return(data->fd); + return data->fd; } static void fd_close(int fd, void *d) @@ -68,13 +73,14 @@ static void fd_close(int fd, void *d) struct fd_chan *data = d; int err; - if(data->raw && isatty(fd)){ - CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt)); - if(err) - printk("Failed to restore terminal state - " - "errno = %d\n", -err); - data->raw = 0; - } + if (!data->raw || !isatty(fd)) + return; + + CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt)); + if (err) + printk(UM_KERN_ERR "Failed to restore terminal state - " + "errno = %d\n", -err); + data->raw = 0; } const struct chan_ops fd_ops = { @@ -89,14 +95,3 @@ const struct chan_ops fd_ops = { .free = generic_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/harddog_kern.c b/arch/um/drivers/harddog_kern.c index 55601687b3bc..a9ad4bd6d953 100644 --- a/arch/um/drivers/harddog_kern.c +++ b/arch/um/drivers/harddog_kern.c @@ -69,7 +69,7 @@ static int harddog_open(struct inode *inode, struct file *file) spin_lock(&lock); if(timer_alive) goto err; -#ifdef CONFIG_HARDDOG_NOWAYOUT +#ifdef CONFIG_WATCHDOG_NOWAYOUT __module_get(THIS_MODULE); #endif diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index 1171790f742c..b56f8e0196a9 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -1,16 +1,13 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ #include <stdio.h> #include <unistd.h> #include <errno.h> -#include "user.h" -#include "mconsole.h" #include "os.h" -#include "choose-mode.h" -#include "mode.h" +#include "user.h" struct dog_data { int stdin; @@ -25,10 +22,10 @@ static void pre_exec(void *d) dup2(data->stdin, 0); dup2(data->stdout, 1); dup2(data->stdout, 2); - os_close_file(data->stdin); - os_close_file(data->stdout); - os_close_file(data->close_me[0]); - os_close_file(data->close_me[1]); + close(data->stdin); + close(data->stdout); + close(data->close_me[0]); + close(data->close_me[1]); } int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) @@ -42,13 +39,13 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) char **args = NULL; err = os_pipe(in_fds, 1, 0); - if(err < 0){ + if (err < 0) { printk("harddog_open - os_pipe failed, err = %d\n", -err); goto out; } err = os_pipe(out_fds, 1, 0); - if(err < 0){ + if (err < 0) { printk("harddog_open - os_pipe failed, err = %d\n", -err); goto out_close_in; } @@ -58,37 +55,37 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) data.close_me[0] = out_fds[1]; data.close_me[1] = in_fds[0]; - if(sock != NULL){ + if (sock != NULL) { mconsole_args[2] = sock; args = mconsole_args; } else { /* XXX The os_getpid() is not SMP correct */ - sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid())); + sprintf(pid_buf, "%d", os_getpid()); args = pid_args; } pid = run_helper(pre_exec, &data, args); - os_close_file(out_fds[0]); - os_close_file(in_fds[1]); + close(out_fds[0]); + close(in_fds[1]); - if(pid < 0){ + if (pid < 0) { err = -pid; printk("harddog_open - run_helper failed, errno = %d\n", -err); goto out_close_out; } - n = os_read_file(in_fds[0], &c, sizeof(c)); - if(n == 0){ + n = read(in_fds[0], &c, sizeof(c)); + if (n == 0) { printk("harddog_open - EOF on watchdog pipe\n"); helper_wait(pid); err = -EIO; goto out_close_out; } - else if(n < 0){ + else if (n < 0) { printk("harddog_open - read of watchdog pipe failed, " - "err = %d\n", -n); + "err = %d\n", errno); helper_wait(pid); err = n; goto out_close_out; @@ -98,19 +95,19 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) return 0; out_close_in: - os_close_file(in_fds[0]); - os_close_file(in_fds[1]); + close(in_fds[0]); + close(in_fds[1]); out_close_out: - os_close_file(out_fds[0]); - os_close_file(out_fds[1]); + close(out_fds[0]); + close(out_fds[1]); out: return err; } void stop_watchdog(int in_fd, int out_fd) { - os_close_file(in_fd); - os_close_file(out_fd); + close(in_fd); + close(out_fd); } int ping_watchdog(int fd) @@ -118,10 +115,11 @@ int ping_watchdog(int fd) int n; char c = '\n'; - n = os_write_file(fd, &c, sizeof(c)); - if(n != sizeof(c)){ - printk("ping_watchdog - write failed, err = %d\n", -n); - if(n < 0) + n = write(fd, &c, sizeof(c)); + if (n != sizeof(c)) { + printk("ping_watchdog - write failed, ret = %d, err = %d\n", + n, errno); + if (n < 0) return n; return -EIO; } diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index 10e08a8c17c3..ff1b22b69e9c 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -1,16 +1,14 @@ -/* - * Copyright (C) 2002 Steve Schmidtke +/* + * Copyright (C) 2002 Steve Schmidtke * Licensed under the GPL */ +#include "linux/fs.h" #include "linux/module.h" -#include "linux/init.h" #include "linux/slab.h" -#include "linux/fs.h" #include "linux/sound.h" #include "linux/soundcard.h" #include "asm/uaccess.h" -#include "kern_util.h" #include "init.h" #include "os.h" @@ -25,7 +23,8 @@ struct hostmixer_state { #define HOSTAUDIO_DEV_DSP "/dev/sound/dsp" #define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer" -/* Changed either at boot time or module load time. At boot, this is +/* + * Changed either at boot time or module load time. At boot, this is * single-threaded; at module load, multiple modules would each have * their own copy of these variables. */ @@ -44,7 +43,7 @@ static char *mixer = HOSTAUDIO_DEV_MIXER; static int set_dsp(char *name, int *add) { dsp = name; - return(0); + return 0; } __uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP); @@ -52,7 +51,7 @@ __uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP); static int set_mixer(char *name, int *add) { mixer = name; - return(0); + return 0; } __uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP); @@ -77,23 +76,23 @@ static ssize_t hostaudio_read(struct file *file, char __user *buffer, int err; #ifdef DEBUG - printk("hostaudio: read called, count = %d\n", count); + printk(KERN_DEBUG "hostaudio: read called, count = %d\n", count); #endif kbuf = kmalloc(count, GFP_KERNEL); - if(kbuf == NULL) - return(-ENOMEM); + if (kbuf == NULL) + return -ENOMEM; err = os_read_file(state->fd, kbuf, count); - if(err < 0) + if (err < 0) goto out; - if(copy_to_user(buffer, kbuf, err)) + if (copy_to_user(buffer, kbuf, err)) err = -EFAULT; out: kfree(kbuf); - return(err); + return err; } static ssize_t hostaudio_write(struct file *file, const char __user *buffer, @@ -104,40 +103,40 @@ static ssize_t hostaudio_write(struct file *file, const char __user *buffer, int err; #ifdef DEBUG - printk("hostaudio: write called, count = %d\n", count); + printk(KERN_DEBUG "hostaudio: write called, count = %d\n", count); #endif kbuf = kmalloc(count, GFP_KERNEL); - if(kbuf == NULL) - return(-ENOMEM); + if (kbuf == NULL) + return -ENOMEM; err = -EFAULT; - if(copy_from_user(kbuf, buffer, count)) + if (copy_from_user(kbuf, buffer, count)) goto out; err = os_write_file(state->fd, kbuf, count); - if(err < 0) + if (err < 0) goto out; *ppos += err; out: kfree(kbuf); - return(err); + return err; } -static unsigned int hostaudio_poll(struct file *file, +static unsigned int hostaudio_poll(struct file *file, struct poll_table_struct *wait) { unsigned int mask = 0; #ifdef DEBUG - printk("hostaudio: poll called (unimplemented)\n"); + printk(KERN_DEBUG "hostaudio: poll called (unimplemented)\n"); #endif - return(mask); + return mask; } -static int hostaudio_ioctl(struct inode *inode, struct file *file, +static int hostaudio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct hostaudio_state *state = file->private_data; @@ -145,7 +144,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file, int err; #ifdef DEBUG - printk("hostaudio: ioctl called, cmd = %u\n", cmd); + printk(KERN_DEBUG "hostaudio: ioctl called, cmd = %u\n", cmd); #endif switch(cmd){ case SNDCTL_DSP_SPEED: @@ -154,8 +153,8 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file, case SNDCTL_DSP_CHANNELS: case SNDCTL_DSP_SUBDIVIDE: case SNDCTL_DSP_SETFRAGMENT: - if(get_user(data, (int __user *) arg)) - return(-EFAULT); + if (get_user(data, (int __user *) arg)) + return EFAULT; break; default: break; @@ -170,14 +169,14 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file, case SNDCTL_DSP_CHANNELS: case SNDCTL_DSP_SUBDIVIDE: case SNDCTL_DSP_SETFRAGMENT: - if(put_user(data, (int __user *) arg)) - return(-EFAULT); + if (put_user(data, (int __user *) arg)) + return -EFAULT; break; default: break; } - return(err); + return err; } static int hostaudio_open(struct inode *inode, struct file *file) @@ -187,24 +186,26 @@ static int hostaudio_open(struct inode *inode, struct file *file) int ret; #ifdef DEBUG - printk("hostaudio: open called (host: %s)\n", dsp); + printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp); #endif state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL); - if(state == NULL) - return(-ENOMEM); + if (state == NULL) + return -ENOMEM; - if(file->f_mode & FMODE_READ) r = 1; - if(file->f_mode & FMODE_WRITE) w = 1; + if (file->f_mode & FMODE_READ) + r = 1; + if (file->f_mode & FMODE_WRITE) + w = 1; ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); - if(ret < 0){ + if (ret < 0) { kfree(state); - return(ret); + return ret; } state->fd = ret; file->private_data = state; - return(0); + return 0; } static int hostaudio_release(struct inode *inode, struct file *file) @@ -212,26 +213,26 @@ static int hostaudio_release(struct inode *inode, struct file *file) struct hostaudio_state *state = file->private_data; #ifdef DEBUG - printk("hostaudio: release called\n"); + printk(KERN_DEBUG "hostaudio: release called\n"); #endif os_close_file(state->fd); kfree(state); - return(0); + return 0; } /* /dev/mixer file operations */ -static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file, +static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct hostmixer_state *state = file->private_data; #ifdef DEBUG - printk("hostmixer: ioctl called\n"); + printk(KERN_DEBUG "hostmixer: ioctl called\n"); #endif - return(os_ioctl_generic(state->fd, cmd, arg)); + return os_ioctl_generic(state->fd, cmd, arg); } static int hostmixer_open_mixdev(struct inode *inode, struct file *file) @@ -241,26 +242,29 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file) int ret; #ifdef DEBUG - printk("hostmixer: open called (host: %s)\n", mixer); + printk(KERN_DEBUG "hostmixer: open called (host: %s)\n", mixer); #endif state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL); - if(state == NULL) return(-ENOMEM); + if (state == NULL) + return -ENOMEM; - if(file->f_mode & FMODE_READ) r = 1; - if(file->f_mode & FMODE_WRITE) w = 1; + if (file->f_mode & FMODE_READ) + r = 1; + if (file->f_mode & FMODE_WRITE) + w = 1; ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); - - if(ret < 0){ - printk("hostaudio_open_mixdev failed to open '%s', err = %d\n", - dsp, -ret); + + if (ret < 0) { + printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', " + "err = %d\n", dsp, -ret); kfree(state); - return(ret); + return ret; } file->private_data = state; - return(0); + return 0; } static int hostmixer_release(struct inode *inode, struct file *file) @@ -268,13 +272,13 @@ static int hostmixer_release(struct inode *inode, struct file *file) struct hostmixer_state *state = file->private_data; #ifdef DEBUG - printk("hostmixer: release called\n"); + printk(KERN_DEBUG "hostmixer: release called\n"); #endif os_close_file(state->fd); kfree(state); - return(0); + return 0; } /* kernel module operations */ @@ -314,13 +318,13 @@ static int __init hostaudio_init_module(void) dsp, mixer); module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1); - if(module_data.dev_audio < 0){ + if (module_data.dev_audio < 0) { printk(KERN_ERR "hostaudio: couldn't register DSP device!\n"); return -ENODEV; } module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1); - if(module_data.dev_mixer < 0){ + if (module_data.dev_mixer < 0) { printk(KERN_ERR "hostmixer: couldn't register mixer " "device!\n"); unregister_sound_dsp(module_data.dev_audio); diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 3e0b68e297f2..76fe0b0da996 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -1,22 +1,14 @@ /* - * 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 "linux/kernel.h" -#include "linux/sched.h" -#include "linux/slab.h" -#include "linux/list.h" +#include "linux/irqreturn.h" #include "linux/kd.h" -#include "linux/interrupt.h" -#include "asm/uaccess.h" #include "chan_kern.h" +#include "irq_kern.h" #include "irq_user.h" -#include "line.h" -#include "kern.h" -#include "kern_util.h" #include "os.h" -#include "irq_kern.h" #define LINE_BUFSIZE 4096 @@ -35,12 +27,13 @@ static void line_timer_cb(struct work_struct *work) { struct line *line = container_of(work, struct line, task.work); - if(!line->throttled) + if (!line->throttled) chan_interrupt(&line->chan_list, &line->task, line->tty, line->driver->read_irq); } -/* Returns the free space inside the ring buffer of this line. +/* + * Returns the free space inside the ring buffer of this line. * * Should be called while holding line->lock (this does not modify datas). */ @@ -107,11 +100,12 @@ static int buffer_data(struct line *line, const char *buf, int len) { int end, room; - if(line->buffer == NULL){ + if (line->buffer == NULL) { line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC); if (line->buffer == NULL) { - printk("buffer_data - atomic allocation failed\n"); - return(0); + printk(KERN_ERR "buffer_data - atomic allocation " + "failed\n"); + return 0; } line->head = line->buffer; line->tail = line->buffer; @@ -122,7 +116,7 @@ static int buffer_data(struct line *line, const char *buf, int len) end = line->buffer + LINE_BUFSIZE - line->tail; - if (len < end){ + if (len < end) { memcpy(line->tail, buf, len); line->tail += len; } @@ -162,8 +156,10 @@ static int flush_buffer(struct line *line) if (n < 0) return n; if (n == count) { - /* We have flushed from ->head to buffer end, now we - * must flush only from the beginning to ->tail.*/ + /* + * We have flushed from ->head to buffer end, now we + * must flush only from the beginning to ->tail. + */ line->head = line->buffer; } else { line->head += n; @@ -175,7 +171,7 @@ static int flush_buffer(struct line *line) n = write_chan(&line->chan_list, line->head, count, line->driver->write_irq); - if(n < 0) + if (n < 0) return n; line->head += n; @@ -189,19 +185,18 @@ void line_flush_buffer(struct tty_struct *tty) int err; /*XXX: copied from line_write, verify if it is correct!*/ - if(tty->stopped) + if (tty->stopped) return; spin_lock_irqsave(&line->lock, flags); err = flush_buffer(line); - /*if (err == 1) - err = 0;*/ spin_unlock_irqrestore(&line->lock, flags); - //return err; } -/* We map both ->flush_chars and ->put_char (which go in pair) onto ->flush_buffer - * and ->write. Hope it's not that bad.*/ +/* + * We map both ->flush_chars and ->put_char (which go in pair) onto + * ->flush_buffer and ->write. Hope it's not that bad. + */ void line_flush_chars(struct tty_struct *tty) { line_flush_buffer(tty); @@ -216,18 +211,15 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len) { struct line *line = tty->driver_data; unsigned long flags; - int n, err, ret = 0; + int n, ret = 0; - if(tty->stopped) + if (tty->stopped) return 0; spin_lock_irqsave(&line->lock, flags); - if (line->head != line->tail) { + if (line->head != line->tail) ret = buffer_data(line, buf, len); - err = flush_buffer(line); - if (err <= 0 && (err != -EAGAIN || !ret)) - ret = err; - } else { + else { n = write_chan(&line->chan_list, buf, len, line->driver->write_irq); if (n < 0) { @@ -257,17 +249,17 @@ static const struct { } tty_ioctls[] = { /* don't print these, they flood the log ... */ { TCGETS, NULL, "TCGETS" }, - { TCSETS, NULL, "TCSETS" }, - { TCSETSW, NULL, "TCSETSW" }, - { TCFLSH, NULL, "TCFLSH" }, - { TCSBRK, NULL, "TCSBRK" }, + { TCSETS, NULL, "TCSETS" }, + { TCSETSW, NULL, "TCSETSW" }, + { TCFLSH, NULL, "TCFLSH" }, + { TCSBRK, NULL, "TCSBRK" }, /* general tty stuff */ - { TCSETSF, KERN_DEBUG, "TCSETSF" }, - { TCGETA, KERN_DEBUG, "TCGETA" }, - { TIOCMGET, KERN_DEBUG, "TIOCMGET" }, - { TCSBRKP, KERN_DEBUG, "TCSBRKP" }, - { TIOCMSET, KERN_DEBUG, "TIOCMSET" }, + { TCSETSF, KERN_DEBUG, "TCSETSF" }, + { TCGETA, KERN_DEBUG, "TCGETA" }, + { TIOCMGET, KERN_DEBUG, "TIOCMGET" }, + { TCSBRKP, KERN_DEBUG, "TCSBRKP" }, + { TIOCMSET, KERN_DEBUG, "TIOCMSET" }, /* linux-specific ones */ { TIOCLINUX, KERN_INFO, "TIOCLINUX" }, @@ -324,12 +316,7 @@ int line_ioctl(struct tty_struct *tty, struct file * file, for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++) if (cmd == tty_ioctls[i].cmd) break; - if (i < ARRAY_SIZE(tty_ioctls)) { - if (NULL != tty_ioctls[i].level) - printk("%s%s: %s: ioctl %s called\n", - tty_ioctls[i].level, __FUNCTION__, - tty->name, tty_ioctls[i].name); - } else { + if (i == ARRAY_SIZE(tty_ioctls)) { printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n", __FUNCTION__, tty->name, cmd); } @@ -355,11 +342,12 @@ void line_unthrottle(struct tty_struct *tty) chan_interrupt(&line->chan_list, &line->task, tty, line->driver->read_irq); - /* Maybe there is enough stuff pending that calling the interrupt + /* + * Maybe there is enough stuff pending that calling the interrupt * throttles us again. In this case, line->throttled will be 1 * again and we shouldn't turn the interrupt back on. */ - if(!line->throttled) + if (!line->throttled) reactivate_chan(&line->chan_list, line->driver->read_irq); } @@ -370,27 +358,30 @@ static irqreturn_t line_write_interrupt(int irq, void *data) struct tty_struct *tty = line->tty; int err; - /* Interrupts are disabled here because we registered the interrupt with - * IRQF_DISABLED (see line_setup_irq).*/ + /* + * Interrupts are disabled here because we registered the interrupt with + * IRQF_DISABLED (see line_setup_irq). + */ spin_lock(&line->lock); err = flush_buffer(line); if (err == 0) { return IRQ_NONE; - } else if(err < 0) { + } else if (err < 0) { line->head = line->buffer; line->tail = line->buffer; } spin_unlock(&line->lock); - if(tty == NULL) + if (tty == NULL) return IRQ_NONE; if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && (tty->ldisc.write_wakeup != NULL)) (tty->ldisc.write_wakeup)(tty); - /* BLOCKING mode + /* + * BLOCKING mode * In blocking mode, everything sleeps on tty->write_wait. * Sleeping in the console driver would break non-blocking * writes. @@ -420,7 +411,8 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data) return err; } -/* Normally, a driver like this can rely mostly on the tty layer +/* + * Normally, a driver like this can rely mostly on the tty layer * locking, particularly when it comes to the driver structure. * However, in this case, mconsole requests can come in "from the * side", and race with opens and closes. @@ -442,11 +434,11 @@ int line_open(struct line *lines, struct tty_struct *tty) int err = -ENODEV; spin_lock(&line->count_lock); - if(!line->valid) + if (!line->valid) goto out_unlock; err = 0; - if(tty->count > 1) + if (tty->count > 1) goto out_unlock; spin_unlock(&line->count_lock); @@ -460,7 +452,7 @@ int line_open(struct line *lines, struct tty_struct *tty) INIT_DELAYED_WORK(&line->task, line_timer_cb); - if(!line->sigio){ + if (!line->sigio) { chan_enable_winch(&line->chan_list, tty); line->sigio = 1; } @@ -481,20 +473,21 @@ void line_close(struct tty_struct *tty, struct file * filp) { struct line *line = tty->driver_data; - /* If line_open fails (and tty->driver_data is never set), + /* + * If line_open fails (and tty->driver_data is never set), * tty_open will call line_close. So just return in this case. */ - if(line == NULL) + if (line == NULL) return; /* We ignore the error anyway! */ flush_buffer(line); spin_lock(&line->count_lock); - if(!line->valid) + if (!line->valid) goto out_unlock; - if(tty->count > 1) + if (tty->count > 1) goto out_unlock; spin_unlock(&line->count_lock); @@ -502,10 +495,10 @@ void line_close(struct tty_struct *tty, struct file * filp) line->tty = NULL; tty->driver_data = NULL; - if(line->sigio){ + if (line->sigio) { unregister_winch(tty); line->sigio = 0; - } + } return; @@ -529,12 +522,12 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio, spin_lock(&line->count_lock); - if(line->tty != NULL){ + if (line->tty != NULL) { *error_out = "Device is already open"; goto out; } - if (line->init_pri <= init_prio){ + if (line->init_pri <= init_prio) { line->init_pri = init_prio; if (!strcmp(init, "none")) line->valid = 0; @@ -549,7 +542,8 @@ out: return err; } -/* Common setup code for both startup command line and mconsole initialization. +/* + * Common setup code for both startup command line and mconsole initialization. * @lines contains the array (of size @num) to modify; * @init is the setup string; * @error_out is an error string in the case of failure; @@ -561,14 +555,16 @@ int line_setup(struct line *lines, unsigned int num, char *init, int i, n, err; char *end; - if(*init == '=') { - /* We said con=/ssl= instead of con#=, so we are configuring all - * consoles at once.*/ + if (*init == '=') { + /* + * We said con=/ssl= instead of con#=, so we are configuring all + * consoles at once. + */ n = -1; } else { n = simple_strtoul(init, &end, 0); - if(*end != '='){ + if (*end != '=') { *error_out = "Couldn't parse device number"; return -EINVAL; } @@ -580,16 +576,16 @@ int line_setup(struct line *lines, unsigned int num, char *init, *error_out = "Device number out of range"; return -EINVAL; } - else if (n >= 0){ + else if (n >= 0) { err = setup_one_line(lines, n, init, INIT_ONE, error_out); - if(err) + if (err) return err; } else { - for(i = 0; i < num; i++){ + for(i = 0; i < num; i++) { err = setup_one_line(lines, i, init, INIT_ALL, error_out); - if(err) + if (err) return err; } } @@ -603,18 +599,18 @@ int line_config(struct line *lines, unsigned int num, char *str, char *new; int n; - if(*str == '='){ + if (*str == '=') { *error_out = "Can't configure all devices from mconsole"; return -EINVAL; } new = kstrdup(str, GFP_KERNEL); - if(new == NULL){ + if (new == NULL) { *error_out = "Failed to allocate memory"; return -ENOMEM; } n = line_setup(lines, num, new, error_out); - if(n < 0) + if (n < 0) return n; line = &lines[n]; @@ -629,12 +625,12 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, int dev, n = 0; dev = simple_strtoul(name, &end, 0); - if((*end != '\0') || (end == name)){ + if ((*end != '\0') || (end == name)) { *error_out = "line_get_config failed to parse device number"; return 0; } - if((dev < 0) || (dev >= num)){ + if ((dev < 0) || (dev >= num)) { *error_out = "device number out of range"; return 0; } @@ -642,9 +638,9 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, line = &lines[dev]; spin_lock(&line->count_lock); - if(!line->valid) + if (!line->valid) CONFIG_CHUNK(str, size, n, "none", 1); - else if(line->tty == NULL) + else if (line->tty == NULL) CONFIG_CHUNK(str, size, n, line->init_str, 1); else n = chan_config_string(&line->chan_list, str, size, error_out); spin_unlock(&line->count_lock); @@ -655,16 +651,16 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, int line_id(char **str, int *start_out, int *end_out) { char *end; - int n; + int n; n = simple_strtoul(*str, &end, 0); - if((*end != '\0') || (end == *str)) - return -1; + if ((*end != '\0') || (end == *str)) + return -1; - *str = end; - *start_out = n; - *end_out = n; - return n; + *str = end; + *start_out = n; + *end_out = n; + return n; } int line_remove(struct line *lines, unsigned int num, int n, char **error_out) @@ -674,7 +670,7 @@ int line_remove(struct line *lines, unsigned int num, int n, char **error_out) sprintf(config, "%d=none", n); err = line_setup(lines, num, config, error_out); - if(err >= 0) + if (err >= 0) err = 0; return err; } @@ -700,14 +696,14 @@ struct tty_driver *register_lines(struct line_driver *line_driver, tty_set_operations(driver, ops); if (tty_register_driver(driver)) { - printk("%s: can't register %s driver\n", - __FUNCTION__,line_driver->name); + printk(KERN_ERR "register_lines : can't register %s driver\n", + line_driver->name); put_tty_driver(driver); return NULL; } - for(i = 0; i < nlines; i++){ - if(!lines[i].valid) + for(i = 0; i < nlines; i++) { + if (!lines[i].valid) tty_unregister_device(driver, i); } @@ -724,20 +720,20 @@ void lines_init(struct line *lines, int nlines, struct chan_opts *opts) char *error; int i; - for(i = 0; i < nlines; i++){ + for(i = 0; i < nlines; i++) { line = &lines[i]; INIT_LIST_HEAD(&line->chan_list); - if(line->init_str == NULL) + if (line->init_str == NULL) continue; line->init_str = kstrdup(line->init_str, GFP_KERNEL); - if(line->init_str == NULL) - printk("lines_init - kstrdup returned NULL\n"); + if (line->init_str == NULL) + printk(KERN_ERR "lines_init - kstrdup returned NULL\n"); - if(parse_chan_pair(line->init_str, line, i, opts, &error)){ - printk("parse_chan_pair failed for device %d : %s\n", - i, error); + if (parse_chan_pair(line->init_str, line, i, opts, &error)) { + printk(KERN_ERR "parse_chan_pair failed for " + "device %d : %s\n", i, error); line->valid = 0; } } @@ -775,14 +771,14 @@ static irqreturn_t winch_interrupt(int irq, void *data) int err; char c; - if(winch->fd != -1){ + if (winch->fd != -1) { err = generic_read(winch->fd, &c, NULL); - if(err < 0){ - if(err != -EAGAIN){ - printk("winch_interrupt : read failed, " - "errno = %d\n", -err); - printk("fd %d is losing SIGWINCH support\n", - winch->tty_fd); + if (err < 0) { + if (err != -EAGAIN) { + printk(KERN_ERR "winch_interrupt : " + "read failed, errno = %d\n", -err); + printk(KERN_ERR "fd %d is losing SIGWINCH " + "support\n", winch->tty_fd); free_winch(winch, 0); return IRQ_HANDLED; } @@ -797,7 +793,7 @@ static irqreturn_t winch_interrupt(int irq, void *data) kill_pgrp(tty->pgrp, SIGWINCH, 1); } out: - if(winch->fd != -1) + if (winch->fd != -1) reactivate_fd(winch->fd, WINCH_IRQ); return IRQ_HANDLED; } @@ -809,7 +805,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, winch = kmalloc(sizeof(*winch), GFP_KERNEL); if (winch == NULL) { - printk("register_winch_irq - kmalloc failed\n"); + printk(KERN_ERR "register_winch_irq - kmalloc failed\n"); goto cleanup; } @@ -823,7 +819,8 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, 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"); + printk(KERN_ERR "register_winch_irq - failed to register " + "IRQ\n"); goto out_free; } @@ -849,13 +846,13 @@ static void unregister_winch(struct tty_struct *tty) spin_lock(&winch_handler_lock); - list_for_each(ele, &winch_handlers){ + list_for_each(ele, &winch_handlers) { winch = list_entry(ele, struct winch, list); - if(winch->tty == tty){ + if (winch->tty == tty) { free_winch(winch, 1); break; - } - } + } + } spin_unlock(&winch_handler_lock); } @@ -866,7 +863,7 @@ static void winch_cleanup(void) spin_lock(&winch_handler_lock); - list_for_each_safe(ele, next, &winch_handlers){ + list_for_each_safe(ele, next, &winch_handlers) { winch = list_entry(ele, struct winch, list); free_winch(winch, 1); } @@ -881,13 +878,13 @@ char *add_xterm_umid(char *base) int len; umid = get_umid(); - if(*umid == '\0') + if (*umid == '\0') return base; len = strlen(base) + strlen(" ()") + strlen(umid) + 1; title = kmalloc(len, GFP_KERNEL); - if(title == NULL){ - printk("Failed to allocate buffer for xterm title\n"); + if (title == NULL) { + printk(KERN_ERR "Failed to allocate buffer for xterm title\n"); return base; } diff --git a/arch/um/drivers/mcast.h b/arch/um/drivers/mcast.h index bc56af9d3e53..6fa282e896be 100644 --- a/arch/um/drivers/mcast.h +++ b/arch/um/drivers/mcast.h @@ -1,8 +1,11 @@ /* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ +#ifndef __DRIVERS_MCAST_H +#define __DRIVERS_MCAST_H + #include "net_user.h" struct mcast_data { @@ -18,13 +21,4 @@ extern const struct net_user_info mcast_user_info; extern int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri); -/* - * 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: - */ +#endif diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c index e6b8e0dd72a8..822092f149be 100644 --- a/arch/um/drivers/mcast_kern.c +++ b/arch/um/drivers/mcast_kern.c @@ -1,24 +1,20 @@ /* * user-mode-linux networking multicast transport * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org> + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * * based on the existing uml-networking code, which is - * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and * James Leu (jleu@mindspring.net). * Copyright (C) 2001 by various other people who didn't put their name here. * * Licensed under the GPL. */ -#include "linux/kernel.h" #include "linux/init.h" -#include "linux/netdevice.h" -#include "linux/etherdevice.h" -#include "linux/in.h" -#include "linux/inet.h" -#include "net_kern.h" -#include "net_user.h" +#include <linux/netdevice.h> #include "mcast.h" +#include "net_kern.h" struct mcast_init { char *addr; @@ -39,26 +35,20 @@ static void mcast_init(struct net_device *dev, void *data) dpri->ttl = init->ttl; dpri->dev = dev; - printk("mcast backend "); - printk("multicast address: %s:%u, TTL:%u ", + printk("mcast backend multicast address: %s:%u, TTL:%u\n", dpri->addr, dpri->port, dpri->ttl); - - printk("\n"); } -static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) +static int mcast_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); - if(*skb == NULL) return(-ENOMEM); - return(net_recvfrom(fd, skb_mac_header(*skb), - (*skb)->dev->mtu + ETH_HEADER_OTHER)); + return net_recvfrom(fd, skb_mac_header(skb), + skb->dev->mtu + ETH_HEADER_OTHER); } -static int mcast_write(int fd, struct sk_buff **skb, - struct uml_net_private *lp) +static int mcast_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - return mcast_user_write(fd, (*skb)->data, (*skb)->len, - (struct mcast_data *) &lp->user); + return mcast_user_write(fd, skb->data, skb->len, + (struct mcast_data *) &lp->user); } static const struct net_kern_info mcast_kern_info = { @@ -81,34 +71,34 @@ int mcast_setup(char *str, char **mac_out, void *data) remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str, NULL); - if(remain != NULL){ + if (remain != NULL) { printk(KERN_ERR "mcast_setup - Extra garbage on " "specification : '%s'\n", remain); - return(0); + return 0; } - - if(port_str != NULL){ + + if (port_str != NULL) { init->port = simple_strtoul(port_str, &last, 10); - if((*last != '\0') || (last == port_str)){ - printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", + if ((*last != '\0') || (last == port_str)) { + printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", port_str); - return(0); + return 0; } } - if(ttl_str != NULL){ + if (ttl_str != NULL) { init->ttl = simple_strtoul(ttl_str, &last, 10); - if((*last != '\0') || (last == ttl_str)){ - printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n", + if ((*last != '\0') || (last == ttl_str)) { + printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n", ttl_str); - return(0); + return 0; } } printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr, init->port, init->ttl); - return(1); + return 1; } static struct transport mcast_transport = { diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index 236a3dfc297d..5f647d7a7292 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -1,9 +1,10 @@ /* * user-mode-linux networking multicast transport + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org> * * based on the existing uml-networking code, which is - * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and * James Leu (jleu@mindspring.net). * Copyright (C) 2001 by various other people who didn't put their name here. * @@ -11,28 +12,22 @@ * */ -#include <errno.h> #include <unistd.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/time.h> +#include <errno.h> #include <netinet/in.h> -#include "net_user.h" #include "mcast.h" -#include "kern_util.h" -#include "user.h" -#include "os.h" +#include "net_user.h" #include "um_malloc.h" - -#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) +#include "user.h" static struct sockaddr_in *new_addr(char *addr, unsigned short port) { struct sockaddr_in *sin; sin = kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL); - if(sin == NULL){ - printk("new_addr: allocation of sockaddr_in failed\n"); + if (sin == NULL) { + printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in " + "failed\n"); return NULL; } sin->sin_family = AF_INET; @@ -71,17 +66,17 @@ static int mcast_open(void *data) fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd < 0){ + if (fd < 0) { err = -errno; - printk("mcast_open : data socket failed, errno = %d\n", - errno); + printk(UM_KERN_ERR "mcast_open : data socket failed, " + "errno = %d\n", errno); goto out; } if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { err = -errno; - printk("mcast_open: SO_REUSEADDR failed, errno = %d\n", - errno); + printk(UM_KERN_ERR "mcast_open: SO_REUSEADDR failed, " + "errno = %d\n", errno); goto out_close; } @@ -89,45 +84,46 @@ static int mcast_open(void *data) if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl, sizeof(pri->ttl)) < 0) { err = -errno; - printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n", - errno); + printk(UM_KERN_ERR "mcast_open: IP_MULTICAST_TTL failed, " + "error = %d\n", errno); goto out_close; } /* set LOOP, so data does get fed back to local sockets */ if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) { err = -errno; - printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n", - errno); + printk(UM_KERN_ERR "mcast_open: IP_MULTICAST_LOOP failed, " + "error = %d\n", errno); goto out_close; } /* bind socket to mcast address */ if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) { err = -errno; - printk("mcast_open : data bind failed, errno = %d\n", errno); + printk(UM_KERN_ERR "mcast_open : data bind failed, " + "errno = %d\n", errno); goto out_close; } /* subscribe to the multicast group */ mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr; mreq.imr_interface.s_addr = 0; - if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, + if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { err = -errno; - printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n", - errno); - printk("There appears not to be a multicast-capable network " - "interface on the host.\n"); - printk("eth0 should be configured in order to use the " - "multicast transport.\n"); + printk(UM_KERN_ERR "mcast_open: IP_ADD_MEMBERSHIP failed, " + "error = %d\n", errno); + printk(UM_KERN_ERR "There appears not to be a multicast-" + "capable network interface on the host.\n"); + printk(UM_KERN_ERR "eth0 should be configured in order to use " + "the multicast transport.\n"); goto out_close; } return fd; out_close: - os_close_file(fd); + close(fd); out: return err; } @@ -142,11 +138,11 @@ static void mcast_close(int fd, void *data) mreq.imr_interface.s_addr = 0; if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { - printk("mcast_open: IP_DROP_MEMBERSHIP failed, error = %d\n", - errno); + printk(UM_KERN_ERR "mcast_open: IP_DROP_MEMBERSHIP failed, " + "error = %d\n", errno); } - os_close_file(fd); + close(fd); } int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri) @@ -156,18 +152,13 @@ int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri) return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); } -static int mcast_set_mtu(int mtu, void *data) -{ - return mtu; -} - const struct net_user_info mcast_user_info = { .init = mcast_user_init, .open = mcast_open, .close = mcast_close, .remove = mcast_remove, - .set_mtu = mcast_set_mtu, .add_address = NULL, .delete_address = NULL, - .max_packet = MAX_PACKET - ETH_HEADER_OTHER + .mtu = ETH_MAX_PACKET, + .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER, }; diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index d87090507401..0f3c7d14a6e3 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -1,44 +1,35 @@ /* * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) - * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/kernel.h" -#include "linux/slab.h" -#include "linux/init.h" -#include "linux/notifier.h" -#include "linux/reboot.h" -#include "linux/utsname.h" +#include "linux/console.h" #include "linux/ctype.h" #include "linux/interrupt.h" -#include "linux/sysrq.h" -#include "linux/workqueue.h" +#include "linux/list.h" +#include "linux/mm.h" #include "linux/module.h" -#include "linux/file.h" -#include "linux/fs.h" -#include "linux/namei.h" +#include "linux/notifier.h" +#include "linux/reboot.h" #include "linux/proc_fs.h" +#include "linux/slab.h" #include "linux/syscalls.h" -#include "linux/list.h" -#include "linux/mm.h" -#include "linux/console.h" -#include "asm/irq.h" +#include "linux/utsname.h" +#include "linux/workqueue.h" #include "asm/uaccess.h" +#include "init.h" +#include "irq_kern.h" +#include "irq_user.h" #include "kern_util.h" -#include "kern.h" #include "mconsole.h" #include "mconsole_kern.h" -#include "irq_user.h" -#include "init.h" #include "os.h" -#include "irq_kern.h" -#include "choose-mode.h" static int do_unlink_socket(struct notifier_block *notifier, unsigned long what, void *data) { - return(mconsole_unlink_socket()); + return mconsole_unlink_socket(); } @@ -59,10 +50,9 @@ static void mc_work_proc(struct work_struct *unused) struct mconsole_entry *req; unsigned long flags; - while(!list_empty(&mc_requests)){ + while (!list_empty(&mc_requests)) { local_irq_save(flags); - req = list_entry(mc_requests.next, struct mconsole_entry, - list); + req = list_entry(mc_requests.next, struct mconsole_entry, list); list_del(&req->list); local_irq_restore(flags); req->request.cmd->handler(&req->request); @@ -80,12 +70,12 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id) static struct mc_request req; /* that's OK */ fd = (long) dev_id; - while (mconsole_get_request(fd, &req)){ - if(req.cmd->context == MCONSOLE_INTR) + while (mconsole_get_request(fd, &req)) { + if (req.cmd->context == MCONSOLE_INTR) (*req.cmd->handler)(&req); else { new = kmalloc(sizeof(*new), GFP_NOWAIT); - if(new == NULL) + if (new == NULL) mconsole_reply(&req, "Out of memory", 1, 0); else { new->request = req; @@ -94,10 +84,10 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id) } } } - if(!list_empty(&mc_requests)) + if (!list_empty(&mc_requests)) schedule_work(&mconsole_work); reactivate_fd(fd, MCONSOLE_IRQ); - return(IRQ_HANDLED); + return IRQ_HANDLED; } void mconsole_version(struct mc_request *req) @@ -105,8 +95,8 @@ void mconsole_version(struct mc_request *req) char version[256]; sprintf(version, "%s %s %s %s %s", utsname()->sysname, - utsname()->nodename, utsname()->release, - utsname()->version, utsname()->machine); + utsname()->nodename, utsname()->release, utsname()->version, + utsname()->machine); mconsole_reply(req, version, 0, 0); } @@ -118,7 +108,7 @@ void mconsole_log(struct mc_request *req) ptr += strlen("log "); len = req->len - (ptr - req->request.data); - printk("%.*s", len, ptr); + printk(KERN_WARNING "%.*s", len, ptr); mconsole_reply(req, "", 0, 0); } @@ -137,17 +127,17 @@ void mconsole_proc(struct mc_request *req) char *ptr = req->request.data, *buf; ptr += strlen("proc"); - while(isspace(*ptr)) ptr++; + while (isspace(*ptr)) ptr++; proc = get_fs_type("proc"); - if(proc == NULL){ + if (proc == NULL) { mconsole_reply(req, "procfs not registered", 1, 0); goto out; } super = (*proc->get_sb)(proc, 0, NULL, NULL); put_filesystem(proc); - if(super == NULL){ + if (super == NULL) { mconsole_reply(req, "Failed to get procfs superblock", 1, 0); goto out; } @@ -162,29 +152,29 @@ void mconsole_proc(struct mc_request *req) * if commenting out these two calls + the below read cycle. To * make UML crash again, it was enough to readd either one.*/ err = link_path_walk(ptr, &nd); - if(err){ + if (err) { mconsole_reply(req, "Failed to look up file", 1, 0); goto out_kill; } file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); - if(IS_ERR(file)){ + if (IS_ERR(file)) { mconsole_reply(req, "Failed to open file", 1, 0); goto out_kill; } /*END*/ buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if(buf == NULL){ + if (buf == NULL) { mconsole_reply(req, "Failed to allocate buffer", 1, 0); goto out_fput; } - if((file->f_op != NULL) && (file->f_op->read != NULL)){ + if ((file->f_op != NULL) && (file->f_op->read != NULL)) { do { n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, &file->f_pos); - if(n >= 0){ + if (n >= 0) { buf[n] = '\0'; mconsole_reply(req, buf, 0, (n > 0)); } @@ -193,7 +183,7 @@ void mconsole_proc(struct mc_request *req) 1, 0); goto out_free; } - } while(n > 0); + } while (n > 0); } else mconsole_reply(req, "", 0, 0); @@ -217,18 +207,19 @@ void mconsole_proc(struct mc_request *req) char *ptr = req->request.data; ptr += strlen("proc"); - while(isspace(*ptr)) ptr++; + while (isspace(*ptr)) + ptr++; snprintf(path, sizeof(path), "/proc/%s", ptr); fd = sys_open(path, 0, 0); if (fd < 0) { mconsole_reply(req, "Failed to open file", 1, 0); - printk("open %s: %d\n",path,fd); + printk(KERN_ERR "open %s: %d\n",path,fd); goto out; } buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if(buf == NULL){ + if (buf == NULL) { mconsole_reply(req, "Failed to allocate buffer", 1, 0); goto out_close; } @@ -239,7 +230,7 @@ void mconsole_proc(struct mc_request *req) mconsole_reply(req, "Read of file failed", 1, 0); goto out_free; } - /*Begin the file content on his own line.*/ + /* Begin the file content on his own line. */ if (first_chunk) { mconsole_reply(req, "\n", 0, 1); first_chunk = 0; @@ -351,12 +342,12 @@ static struct mc_device *mconsole_find_dev(char *name) struct list_head *ele; struct mc_device *dev; - list_for_each(ele, &mconsole_devices){ + list_for_each(ele, &mconsole_devices) { dev = list_entry(ele, struct mc_device, list); - if(!strncmp(name, dev->name, strlen(dev->name))) - return(dev); + if (!strncmp(name, dev->name, strlen(dev->name))) + return dev; } - return(NULL); + return NULL; } #define UNPLUGGED_PER_PAGE \ @@ -378,15 +369,15 @@ static int mem_config(char *str, char **error_out) int err = -EINVAL, i, add; char *ret; - if(str[0] != '='){ + if (str[0] != '=') { *error_out = "Expected '=' after 'mem'"; goto out; } str++; - if(str[0] == '-') + if (str[0] == '-') add = 0; - else if(str[0] == '+'){ + else if (str[0] == '+') { add = 1; } else { @@ -396,7 +387,7 @@ static int mem_config(char *str, char **error_out) str++; diff = memparse(str, &ret); - if(*ret != '\0'){ + if (*ret != '\0') { *error_out = "Failed to parse memory increment"; goto out; } @@ -404,17 +395,17 @@ static int mem_config(char *str, char **error_out) diff /= PAGE_SIZE; down(&plug_mem_mutex); - for(i = 0; i < diff; i++){ + for (i = 0; i < diff; i++) { struct unplugged_pages *unplugged; void *addr; - if(add){ - if(list_empty(&unplugged_pages)) + if (add) { + if (list_empty(&unplugged_pages)) break; unplugged = list_entry(unplugged_pages.next, struct unplugged_pages, list); - if(unplug_index > 0) + if (unplug_index > 0) addr = unplugged->pages[--unplug_index]; else { list_del(&unplugged->list); @@ -429,11 +420,11 @@ static int mem_config(char *str, char **error_out) struct page *page; page = alloc_page(GFP_ATOMIC); - if(page == NULL) + if (page == NULL) break; unplugged = page_address(page); - if(unplug_index == UNPLUGGED_PER_PAGE){ + if (unplug_index == UNPLUGGED_PER_PAGE) { list_add(&unplugged->list, &unplugged_pages); unplug_index = 0; } @@ -445,9 +436,9 @@ static int mem_config(char *str, char **error_out) struct unplugged_pages, list); err = os_drop_memory(addr, PAGE_SIZE); - if(err){ - printk("Failed to release memory - " - "errno = %d\n", err); + if (err) { + printk(KERN_ERR "Failed to release " + "memory - errno = %d\n", err); *error_out = "Failed to release memory"; goto out_unlock; } @@ -501,10 +492,10 @@ static struct mc_device mem_mc = { static int __init mem_mc_init(void) { - if(can_drop_memory()) + if (can_drop_memory()) mconsole_register_dev(&mem_mc); - else printk("Can't release memory to the host - memory hotplug won't " - "be supported\n"); + else printk(KERN_ERR "Can't release memory to the host - memory " + "hotplug won't be supported\n"); return 0; } @@ -519,7 +510,7 @@ static void mconsole_get_config(int (*get_config)(char *, char *, int, char default_buf[CONFIG_BUF_SIZE], *error, *buf; int n, size; - if(get_config == NULL){ + if (get_config == NULL) { mconsole_reply(req, "No get_config routine defined", 1, 0); return; } @@ -528,30 +519,30 @@ static void mconsole_get_config(int (*get_config)(char *, char *, int, size = ARRAY_SIZE(default_buf); buf = default_buf; - while(1){ + while (1) { n = (*get_config)(name, buf, size, &error); - if(error != NULL){ + if (error != NULL) { mconsole_reply(req, error, 1, 0); goto out; } - if(n <= size){ + if (n <= size) { mconsole_reply(req, buf, 0, 0); goto out; } - if(buf != default_buf) + if (buf != default_buf) kfree(buf); size = n; buf = kmalloc(size, GFP_KERNEL); - if(buf == NULL){ + if (buf == NULL) { mconsole_reply(req, "Failed to allocate buffer", 1, 0); return; } } out: - if(buf != default_buf) + if (buf != default_buf) kfree(buf); } @@ -562,19 +553,20 @@ void mconsole_config(struct mc_request *req) int err; ptr += strlen("config"); - while(isspace(*ptr)) ptr++; + while (isspace(*ptr)) + ptr++; dev = mconsole_find_dev(ptr); - if(dev == NULL){ + if (dev == NULL) { mconsole_reply(req, "Bad configuration option", 1, 0); return; } name = &ptr[strlen(dev->name)]; ptr = name; - while((*ptr != '=') && (*ptr != '\0')) + while ((*ptr != '=') && (*ptr != '\0')) ptr++; - if(*ptr == '='){ + if (*ptr == '=') { err = (*dev->config)(name, &error_string); mconsole_reply(req, error_string, err, 0); } @@ -589,9 +581,9 @@ void mconsole_remove(struct mc_request *req) int err, start, end, n; ptr += strlen("remove"); - while(isspace(*ptr)) ptr++; + while (isspace(*ptr)) ptr++; dev = mconsole_find_dev(ptr); - if(dev == NULL){ + if (dev == NULL) { mconsole_reply(req, "Bad remove option", 1, 0); return; } @@ -600,11 +592,11 @@ void mconsole_remove(struct mc_request *req) err = 1; n = (*dev->id)(&ptr, &start, &end); - if(n < 0){ + if (n < 0) { err_msg = "Couldn't parse device number"; goto out; } - else if((n < start) || (n > end)){ + else if ((n < start) || (n > end)) { sprintf(error, "Invalid device number - must be between " "%d and %d", start, end); err_msg = error; @@ -613,16 +605,16 @@ void mconsole_remove(struct mc_request *req) err_msg = NULL; err = (*dev->remove)(n, &err_msg); - switch(err){ + switch(err) { case 0: err_msg = ""; break; case -ENODEV: - if(err_msg == NULL) + if (err_msg == NULL) err_msg = "Device doesn't exist"; break; case -EBUSY: - if(err_msg == NULL) + if (err_msg == NULL) err_msg = "Device is currently open"; break; default: @@ -640,35 +632,28 @@ struct mconsole_output { static DEFINE_SPINLOCK(client_lock); static LIST_HEAD(clients); static char console_buf[MCONSOLE_MAX_DATA]; -static int console_index = 0; static void console_write(struct console *console, const char *string, - unsigned len) + unsigned int len) { struct list_head *ele; int n; - if(list_empty(&clients)) + if (list_empty(&clients)) return; - while(1){ - n = min((size_t) len, ARRAY_SIZE(console_buf) - console_index); - strncpy(&console_buf[console_index], string, n); - console_index += n; + while (len > 0) { + n = min((size_t) len, ARRAY_SIZE(console_buf)); + strncpy(console_buf, string, n); string += n; len -= n; - if(len == 0) - return; - list_for_each(ele, &clients){ + list_for_each(ele, &clients) { struct mconsole_output *entry; entry = list_entry(ele, struct mconsole_output, list); - mconsole_reply_len(entry->req, console_buf, - console_index, 0, 1); + mconsole_reply_len(entry->req, console_buf, n, 0, 1); } - - console_index = 0; } } @@ -698,8 +683,7 @@ static void with_console(struct mc_request *req, void (*proc)(void *), (*proc)(arg); - mconsole_reply_len(req, console_buf, console_index, 0, 0); - console_index = 0; + mconsole_reply_len(req, "", 0, 0, 0); spin_lock_irqsave(&client_lock, flags); list_del(&entry.list); @@ -707,6 +691,9 @@ static void with_console(struct mc_request *req, void (*proc)(void *), } #ifdef CONFIG_MAGIC_SYSRQ + +#include <linux/sysrq.h> + static void sysrq_proc(void *arg) { char *op = arg; @@ -718,12 +705,13 @@ void mconsole_sysrq(struct mc_request *req) char *ptr = req->request.data; ptr += strlen("sysrq"); - while(isspace(*ptr)) ptr++; + while (isspace(*ptr)) ptr++; - /* With 'b', the system will shut down without a chance to reply, + /* + * With 'b', the system will shut down without a chance to reply, * so in this case, we reply first. */ - if(*ptr == 'b') + if (*ptr == 'b') mconsole_reply(req, "", 0, 0); with_console(req, sysrq_proc, ptr); @@ -735,8 +723,6 @@ void mconsole_sysrq(struct mc_request *req) } #endif -#ifdef CONFIG_MODE_SKAS - static void stack_proc(void *arg) { struct task_struct *from = current, *to = arg; @@ -745,29 +731,34 @@ static void stack_proc(void *arg) switch_to(from, to, from); } -/* Mconsole stack trace +/* + * Mconsole stack trace * Added by Allan Graves, Jeff Dike * Dumps a stacks registers to the linux console. * Usage stack <pid>. */ -static void do_stack_trace(struct mc_request *req) +void mconsole_stack(struct mc_request *req) { char *ptr = req->request.data; int pid_requested= -1; struct task_struct *from = NULL; struct task_struct *to = NULL; - /* Would be nice: + /* + * Would be nice: * 1) Send showregs output to mconsole. * 2) Add a way to stack dump all pids. */ ptr += strlen("stack"); - while(isspace(*ptr)) ptr++; + while (isspace(*ptr)) + ptr++; - /* Should really check for multiple pids or reject bad args here */ + /* + * Should really check for multiple pids or reject bad args here + */ /* What do the arguments in mconsole_reply mean? */ - if(sscanf(ptr, "%d", &pid_requested) == 0){ + if (sscanf(ptr, "%d", &pid_requested) == 0) { mconsole_reply(req, "Please specify a pid", 1, 0); return; } @@ -775,25 +766,15 @@ static void do_stack_trace(struct mc_request *req) from = current; to = find_task_by_pid(pid_requested); - if((to == NULL) || (pid_requested == 0)) { + if ((to == NULL) || (pid_requested == 0)) { mconsole_reply(req, "Couldn't find that pid", 1, 0); return; } with_console(req, stack_proc, to); } -#endif /* CONFIG_MODE_SKAS */ -void mconsole_stack(struct mc_request *req) -{ - /* This command doesn't work in TT mode, so let's check and then - * get out of here - */ - CHOOSE_MODE(mconsole_reply(req, "Sorry, this doesn't work in TT mode", - 1, 0), - do_stack_trace(req)); -} - -/* Changed by mconsole_setup, which is __setup, and called before SMP is +/* + * Changed by mconsole_setup, which is __setup, and called before SMP is * active. */ static char *notify_socket = NULL; @@ -805,13 +786,14 @@ static int __init mconsole_init(void) int err; char file[256]; - if(umid_file_name("mconsole", file, sizeof(file))) return(-1); + if (umid_file_name("mconsole", file, sizeof(file))) + return -1; snprintf(mconsole_socket_name, sizeof(file), "%s", file); sock = os_create_unix_socket(file, sizeof(file), 1); - if (sock < 0){ - printk("Failed to initialize management console\n"); - return(1); + if (sock < 0) { + printk(KERN_ERR "Failed to initialize management console\n"); + return 1; } register_reboot_notifier(&reboot_notifier); @@ -819,14 +801,14 @@ static int __init mconsole_init(void) err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "mconsole", (void *)sock); - if (err){ - printk("Failed to get IRQ for management console\n"); - return(1); + if (err) { + printk(KERN_ERR "Failed to get IRQ for management console\n"); + return 1; } - if(notify_socket != NULL){ + if (notify_socket != NULL) { notify_socket = kstrdup(notify_socket, GFP_KERNEL); - if(notify_socket != NULL) + if (notify_socket != NULL) mconsole_notify(notify_socket, MCONSOLE_SOCKET, mconsole_socket_name, strlen(mconsole_socket_name) + 1); @@ -834,9 +816,9 @@ static int __init mconsole_init(void) "string\n"); } - printk("mconsole (version %d) initialized on %s\n", + printk(KERN_INFO "mconsole (version %d) initialized on %s\n", MCONSOLE_VERSION, mconsole_socket_name); - return(0); + return 0; } __initcall(mconsole_init); @@ -847,10 +829,10 @@ static int write_proc_mconsole(struct file *file, const char __user *buffer, char *buf; buf = kmalloc(count + 1, GFP_KERNEL); - if(buf == NULL) - return(-ENOMEM); + if (buf == NULL) + return -ENOMEM; - if(copy_from_user(buf, buffer, count)){ + if (copy_from_user(buf, buffer, count)) { count = -EFAULT; goto out; } @@ -860,24 +842,26 @@ static int write_proc_mconsole(struct file *file, const char __user *buffer, mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count); out: kfree(buf); - return(count); + return count; } static int create_proc_mconsole(void) { struct proc_dir_entry *ent; - if(notify_socket == NULL) return(0); + if (notify_socket == NULL) + return 0; ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL); - if(ent == NULL){ - printk(KERN_INFO "create_proc_mconsole : create_proc_entry failed\n"); - return(0); + if (ent == NULL) { + printk(KERN_INFO "create_proc_mconsole : create_proc_entry " + "failed\n"); + return 0; } ent->read_proc = NULL; ent->write_proc = write_proc_mconsole; - return(0); + return 0; } static DEFINE_SPINLOCK(notify_spinlock); @@ -894,19 +878,19 @@ void unlock_notify(void) __initcall(create_proc_mconsole); -#define NOTIFY "=notify:" +#define NOTIFY "notify:" static int mconsole_setup(char *str) { - if(!strncmp(str, NOTIFY, strlen(NOTIFY))){ + if (!strncmp(str, NOTIFY, strlen(NOTIFY))) { str += strlen(NOTIFY); notify_socket = str; } else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str); - return(1); + return 1; } -__setup("mconsole", mconsole_setup); +__setup("mconsole=", mconsole_setup); __uml_help(mconsole_setup, "mconsole=notify:<socket>\n" @@ -921,11 +905,12 @@ static int notify_panic(struct notifier_block *self, unsigned long unused1, { char *message = ptr; - if(notify_socket == NULL) return(0); + if (notify_socket == NULL) + return 0; mconsole_notify(notify_socket, MCONSOLE_PANIC, message, strlen(message) + 1); - return(0); + return 0; } static struct notifier_block panic_exit_notifier = { @@ -938,14 +923,14 @@ static int add_notifier(void) { atomic_notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); - return(0); + return 0; } __initcall(add_notifier); char *mconsole_notify_socket(void) { - return(notify_socket); + return notify_socket; } EXPORT_SYMBOL(mconsole_notify_socket); diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index f31e71546e52..430c024a19b0 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c @@ -1,25 +1,22 @@ /* * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) - * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <stdio.h> -#include <stdlib.h> #include <errno.h> -#include <signal.h> +#include <string.h> +#include <unistd.h> #include <sys/socket.h> -#include <sys/types.h> #include <sys/uio.h> #include <sys/un.h> -#include <unistd.h> -#include "user.h" -#include "sysdep/ptrace.h" +#include "kern_constants.h" #include "mconsole.h" -#include "os.h" +#include "user.h" static struct mconsole_command commands[] = { - /* With uts namespaces, uts information becomes process-specific, so + /* + * With uts namespaces, uts information becomes process-specific, so * we need a process context. If we try handling this in interrupt * context, we may hit an exiting process without a valid uts * namespace. @@ -36,7 +33,7 @@ static struct mconsole_command commands[] = { { "go", mconsole_go, MCONSOLE_INTR }, { "log", mconsole_log, MCONSOLE_INTR }, { "proc", mconsole_proc, MCONSOLE_PROC }, - { "stack", mconsole_stack, MCONSOLE_INTR }, + { "stack", mconsole_stack, MCONSOLE_INTR }, }; /* Initialized in mconsole_init, which is an initcall */ @@ -44,21 +41,21 @@ char mconsole_socket_name[256]; int mconsole_reply_v0(struct mc_request *req, char *reply) { - struct iovec iov; - struct msghdr msg; + struct iovec iov; + struct msghdr msg; - iov.iov_base = reply; - iov.iov_len = strlen(reply); + iov.iov_base = reply; + iov.iov_len = strlen(reply); - msg.msg_name = &(req->origin); - msg.msg_namelen = req->originlen; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; + msg.msg_name = &(req->origin); + msg.msg_namelen = req->originlen; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; - return sendmsg(req->originating_fd, &msg, 0); + return sendmsg(req->originating_fd, &msg, 0); } static struct mconsole_command *mconsole_parse(struct mc_request *req) @@ -66,10 +63,10 @@ static struct mconsole_command *mconsole_parse(struct mc_request *req) struct mconsole_command *cmd; int i; - for(i = 0; i < ARRAY_SIZE(commands); i++){ + for (i = 0; i < ARRAY_SIZE(commands); i++) { cmd = &commands[i]; - if(!strncmp(req->request.data, cmd->command, - strlen(cmd->command))){ + if (!strncmp(req->request.data, cmd->command, + strlen(cmd->command))) { return cmd; } } @@ -94,9 +91,9 @@ int mconsole_get_request(int fd, struct mc_request *req) req->originating_fd = fd; - if(req->request.magic != MCONSOLE_MAGIC){ + if (req->request.magic != MCONSOLE_MAGIC) { /* Unversioned request */ - len = MIN(sizeof(req->request.data) - 1, + len = MIN(sizeof(req->request.data) - 1, strlen((char *) &req->request)); memmove(req->request.data, &req->request, len); req->request.data[len] = '\0'; @@ -107,32 +104,33 @@ int mconsole_get_request(int fd, struct mc_request *req) mconsole_reply_v0(req, "ERR Version 0 mconsole clients are " "not supported by this driver"); - return(0); + return 0; } - if(req->request.len >= MCONSOLE_MAX_DATA){ + if (req->request.len >= MCONSOLE_MAX_DATA) { mconsole_reply(req, "Request too large", 1, 0); - return(0); + return 0; } - if(req->request.version != MCONSOLE_VERSION){ - mconsole_reply(req, "This driver only supports version " - STRING(MCONSOLE_VERSION) " clients", 1, 0); + if (req->request.version != MCONSOLE_VERSION) { + mconsole_reply(req, "This driver only supports version " + STRING(MCONSOLE_VERSION) " clients", 1, 0); } - + req->request.data[req->request.len] = '\0'; req->cmd = mconsole_parse(req); - if(req->cmd == NULL){ + if (req->cmd == NULL) { mconsole_reply(req, "Unknown command", 1, 0); - return(0); + return 0; } - return(1); + return 1; } int mconsole_reply_len(struct mc_request *req, const char *str, int total, int err, int more) { - /* XXX This is a stack consumption problem. It'd be nice to + /* + * XXX This is a stack consumption problem. It'd be nice to * make it global and serialize access to it, but there are a * ton of callers to this function. */ @@ -147,7 +145,7 @@ int mconsole_reply_len(struct mc_request *req, const char *str, int total, len = MIN(total, MCONSOLE_MAX_DATA - 1); - if(len == total) reply.more = more; + if (len == total) reply.more = more; else reply.more = 1; memcpy(reply.data, str, len); @@ -161,9 +159,10 @@ int mconsole_reply_len(struct mc_request *req, const char *str, int total, n = sendto(req->originating_fd, &reply, len, 0, (struct sockaddr *) req->origin, req->originlen); - if(n < 0) return(-errno); - } while(total > 0); - return(0); + if (n < 0) + return -errno; + } while (total > 0); + return 0; } int mconsole_reply(struct mc_request *req, const char *str, int err, int more) @@ -187,18 +186,18 @@ int mconsole_notify(char *sock_name, int type, const void *data, int len) int n, err = 0; lock_notify(); - if(notify_sock < 0){ + if (notify_sock < 0) { notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0); - if(notify_sock < 0){ + if (notify_sock < 0) { err = -errno; - printk("mconsole_notify - socket failed, errno = %d\n", - err); + printk(UM_KERN_ERR "mconsole_notify - socket failed, " + "errno = %d\n", errno); } } unlock_notify(); - - if(err) - return(err); + + if (err) + return err; target.sun_family = AF_UNIX; strcpy(target.sun_path, sock_name); @@ -212,22 +211,12 @@ int mconsole_notify(char *sock_name, int type, const void *data, int len) err = 0; len = sizeof(packet) + packet.len - sizeof(packet.data); - n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target, + n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target, sizeof(target)); - if(n < 0){ + if (n < 0) { err = -errno; - printk("mconsole_notify - sendto failed, errno = %d\n", errno); + printk(UM_KERN_ERR "mconsole_notify - sendto failed, " + "errno = %d\n", errno); } - return(err); + return err; } - -/* - * 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/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index 867666a02339..67b2f55a602f 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c @@ -9,27 +9,29 @@ * */ -#include <linux/init.h> -#include <linux/module.h> -#include <linux/mm.h> +#include <linux/stddef.h> +#include <linux/types.h> #include <linux/fs.h> +#include <linux/init.h> #include <linux/miscdevice.h> +#include <linux/module.h> +#include <linux/mm.h> #include <asm/uaccess.h> #include "mem_user.h" - + /* These are set in mmapper_init, which is called at boot time */ static unsigned long mmapper_size; -static unsigned long p_buf = 0; -static char *v_buf = NULL; +static unsigned long p_buf; +static char *v_buf; -static ssize_t -mmapper_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +static ssize_t mmapper_read(struct file *file, char __user *buf, size_t count, + loff_t *ppos) { return simple_read_from_buffer(buf, count, ppos, v_buf, mmapper_size); } -static ssize_t -mmapper_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +static ssize_t mmapper_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) { if (*ppos > mmapper_size) return -EINVAL; @@ -39,48 +41,46 @@ mmapper_write(struct file *file, const char __user *buf, size_t count, loff_t *p if (copy_from_user(&v_buf[*ppos], buf, count)) return -EFAULT; - + return count; } -static int -mmapper_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static int mmapper_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { - return(-ENOIOCTLCMD); + return -ENOIOCTLCMD; } -static int -mmapper_mmap(struct file *file, struct vm_area_struct * vma) +static int mmapper_mmap(struct file *file, struct vm_area_struct *vma) { int ret = -EINVAL; int size; if (vma->vm_pgoff != 0) goto out; - + size = vma->vm_end - vma->vm_start; - if(size > mmapper_size) return(-EFAULT); + if (size > mmapper_size) + return -EFAULT; - /* XXX A comment above remap_pfn_range says it should only be + /* + * XXX A comment above remap_pfn_range says it should only be * called when the mm semaphore is held */ if (remap_pfn_range(vma, vma->vm_start, p_buf >> PAGE_SHIFT, size, - vma->vm_page_prot)) + vma->vm_page_prot)) goto out; ret = 0; out: return ret; } -static int -mmapper_open(struct inode *inode, struct file *file) +static int mmapper_open(struct inode *inode, struct file *file) { return 0; } -static int -mmapper_release(struct inode *inode, struct file *file) +static int mmapper_release(struct inode *inode, struct file *file) { return 0; } @@ -95,7 +95,9 @@ static const struct file_operations mmapper_fops = { .release = mmapper_release, }; -/* No locking needed - only used (and modified) by below initcall and exitcall. */ +/* + * No locking needed - only used (and modified) by below initcall and exitcall. + */ static struct miscdevice mmapper_dev = { .minor = MISC_DYNAMIC_MINOR, .name = "mmapper", @@ -109,13 +111,13 @@ static int __init mmapper_init(void) printk(KERN_INFO "Mapper v0.1\n"); v_buf = (char *) find_iomem("mmapper", &mmapper_size); - if(mmapper_size == 0){ + if (mmapper_size == 0) { printk(KERN_ERR "mmapper_init - find_iomem failed\n"); goto out; } err = misc_register(&mmapper_dev); - if(err){ + if (err) { printk(KERN_ERR "mmapper - misc_register failed, err = %d\n", err); goto out; @@ -136,9 +138,3 @@ module_exit(mmapper_exit); MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>"); MODULE_DESCRIPTION("DSPLinux simulator mmapper driver"); -/* - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index d35d0c1ee7f4..8c01fa81a1ae 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -1,33 +1,28 @@ /* + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and * James Leu (jleu@mindspring.net). * Copyright (C) 2001 by various other people who didn't put their name here. * Licensed under the GPL. */ -#include "linux/kernel.h" -#include "linux/netdevice.h" -#include "linux/rtnetlink.h" -#include "linux/skbuff.h" -#include "linux/socket.h" -#include "linux/spinlock.h" -#include "linux/module.h" -#include "linux/init.h" -#include "linux/etherdevice.h" -#include "linux/list.h" -#include "linux/inetdevice.h" -#include "linux/ctype.h" -#include "linux/bootmem.h" -#include "linux/ethtool.h" -#include "linux/platform_device.h" -#include "asm/uaccess.h" -#include "kern_util.h" -#include "net_kern.h" -#include "net_user.h" -#include "mconsole_kern.h" +#include <linux/bootmem.h> +#include <linux/etherdevice.h> +#include <linux/ethtool.h> +#include <linux/inetdevice.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/netdevice.h> +#include <linux/platform_device.h> +#include <linux/rtnetlink.h> +#include <linux/skbuff.h> +#include <linux/spinlock.h> #include "init.h" -#include "irq_user.h" #include "irq_kern.h" +#include "irq_user.h" +#include "mconsole_kern.h" +#include "net_kern.h" +#include "net_user.h" static inline void set_ether_mac(struct net_device *dev, unsigned char *addr) { @@ -39,6 +34,46 @@ static inline void set_ether_mac(struct net_device *dev, unsigned char *addr) static DEFINE_SPINLOCK(opened_lock); static LIST_HEAD(opened); +/* + * The drop_skb is used when we can't allocate an skb. The + * packet is read into drop_skb in order to get the data off the + * connection to the host. + * It is reallocated whenever a maximum packet size is seen which is + * larger than any seen before. update_drop_skb is called from + * eth_configure when a new interface is added. + */ +static DEFINE_SPINLOCK(drop_lock); +static struct sk_buff *drop_skb; +static int drop_max; + +static int update_drop_skb(int max) +{ + struct sk_buff *new; + unsigned long flags; + int err = 0; + + spin_lock_irqsave(&drop_lock, flags); + + if (max <= drop_max) + goto out; + + err = -ENOMEM; + new = dev_alloc_skb(max); + if (new == NULL) + goto out; + + skb_put(new, max); + + kfree_skb(drop_skb); + drop_skb = new; + drop_max = max; + err = 0; +out: + spin_unlock_irqrestore(&drop_lock, flags); + + return err; +} + static int uml_net_rx(struct net_device *dev) { struct uml_net_private *lp = dev->priv; @@ -46,16 +81,19 @@ static int uml_net_rx(struct net_device *dev) struct sk_buff *skb; /* If we can't allocate memory, try again next round. */ - skb = dev_alloc_skb(dev->mtu); + skb = dev_alloc_skb(lp->max_packet); if (skb == NULL) { + drop_skb->dev = dev; + /* Read a packet into drop_skb and don't do anything with it. */ + (*lp->read)(lp->fd, drop_skb, lp); lp->stats.rx_dropped++; return 0; } skb->dev = dev; - skb_put(skb, dev->mtu); + skb_put(skb, lp->max_packet); skb_reset_mac_header(skb); - pkt_len = (*lp->read)(lp->fd, &skb, lp); + pkt_len = (*lp->read)(lp->fd, skb, lp); if (pkt_len > 0) { skb_trim(skb, pkt_len); @@ -84,12 +122,12 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id) struct uml_net_private *lp = dev->priv; int err; - if(!netif_running(dev)) - return(IRQ_NONE); + if (!netif_running(dev)) + return IRQ_NONE; spin_lock(&lp->lock); - while((err = uml_net_rx(dev)) > 0) ; - if(err < 0) { + while ((err = uml_net_rx(dev)) > 0) ; + if (err < 0) { printk(KERN_ERR "Device '%s' read returned %d, shutting it down\n", dev->name, err); @@ -115,20 +153,20 @@ static int uml_net_open(struct net_device *dev) struct uml_net_private *lp = dev->priv; int err; - if(lp->fd >= 0){ + if (lp->fd >= 0) { err = -ENXIO; goto out; } lp->fd = (*lp->open)(&lp->user); - if(lp->fd < 0){ + if (lp->fd < 0) { err = lp->fd; goto out; } err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt, IRQF_DISABLED | IRQF_SHARED, dev->name, dev); - if(err != 0){ + if (err != 0) { printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err); err = -ENETUNREACH; goto out_close; @@ -141,7 +179,7 @@ static int uml_net_open(struct net_device *dev) * is full when we get here. In this case, new data is never queued, * SIGIOs never arrive, and the net never works. */ - while((err = uml_net_rx(dev)) > 0) ; + while ((err = uml_net_rx(dev)) > 0) ; spin_lock(&opened_lock); list_add(&lp->list, &opened); @@ -149,7 +187,7 @@ static int uml_net_open(struct net_device *dev) return 0; out_close: - if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); + if (lp->close != NULL) (*lp->close)(lp->fd, &lp->user); lp->fd = -1; out: return err; @@ -162,7 +200,7 @@ static int uml_net_close(struct net_device *dev) netif_stop_queue(dev); free_irq(dev->irq, dev); - if(lp->close != NULL) + if (lp->close != NULL) (*lp->close)(lp->fd, &lp->user); lp->fd = -1; @@ -183,9 +221,9 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_lock_irqsave(&lp->lock, flags); - len = (*lp->write)(lp->fd, &skb, lp); + len = (*lp->write)(lp->fd, skb, lp); - if(len == skb->len) { + if (len == skb->len) { lp->stats.tx_packets++; lp->stats.tx_bytes += skb->len; dev->trans_start = jiffies; @@ -194,7 +232,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) /* this is normally done in the interrupt when tx finishes */ netif_wake_queue(dev); } - else if(len == 0){ + else if (len == 0) { netif_start_queue(dev); lp->stats.tx_dropped++; } @@ -218,8 +256,10 @@ static struct net_device_stats *uml_net_get_stats(struct net_device *dev) static void uml_net_set_multicast_list(struct net_device *dev) { - if (dev->flags & IFF_PROMISC) return; - else if (dev->mc_count) dev->flags |= IFF_ALLMULTI; + if (dev->flags & IFF_PROMISC) + return; + else if (dev->mc_count) + dev->flags |= IFF_ALLMULTI; else dev->flags &= ~IFF_ALLMULTI; } @@ -243,22 +283,9 @@ static int uml_net_set_mac(struct net_device *dev, void *addr) static int uml_net_change_mtu(struct net_device *dev, int new_mtu) { - struct uml_net_private *lp = dev->priv; - int err = 0; - - spin_lock_irq(&lp->lock); - - new_mtu = (*lp->set_mtu)(new_mtu, &lp->user); - if(new_mtu < 0){ - err = new_mtu; - goto out; - } - dev->mtu = new_mtu; - out: - spin_unlock_irq(&lp->lock); - return err; + return 0; } static void uml_net_get_drvinfo(struct net_device *dev, @@ -288,13 +315,13 @@ static void setup_etheraddr(char *str, unsigned char *addr, char *name) char *end; int i; - if(str == NULL) + if (str == NULL) goto random; - for(i=0;i<6;i++){ + for (i = 0;i < 6; i++) { addr[i] = simple_strtoul(str, &end, 16); - if((end == str) || - ((*end != ':') && (*end != ',') && (*end != '\0'))){ + if ((end == str) || + ((*end != ':') && (*end != ',') && (*end != '\0'))) { printk(KERN_ERR "setup_etheraddr: failed to parse '%s' " "as an ethernet address\n", str); @@ -349,7 +376,7 @@ static void net_device_release(struct device *dev) struct net_device *netdev = device->dev; struct uml_net_private *lp = netdev->priv; - if(lp->remove != NULL) + if (lp->remove != NULL) (*lp->remove)(&lp->user); list_del(&device->list); kfree(device); @@ -413,7 +440,7 @@ static void eth_configure(int n, void *init, char *mac, device->pdev.name = DRIVER_NAME; device->pdev.dev.release = net_device_release; device->pdev.dev.driver_data = device; - if(platform_device_register(&device->pdev)) + if (platform_device_register(&device->pdev)) goto out_free_netdev; SET_NETDEV_DEV(dev,&device->pdev.dev); @@ -430,6 +457,7 @@ static void eth_configure(int n, void *init, char *mac, .dev = dev, .fd = -1, .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0}, + .max_packet = transport->user->max_packet, .protocol = transport->kern->protocol, .open = transport->user->open, .close = transport->user->close, @@ -437,8 +465,7 @@ static void eth_configure(int n, void *init, char *mac, .read = transport->kern->read, .write = transport->kern->write, .add_address = transport->user->add_address, - .delete_address = transport->user->delete_address, - .set_mtu = transport->user->set_mtu }); + .delete_address = transport->user->delete_address }); init_timer(&lp->tl); spin_lock_init(&lp->lock); @@ -450,7 +477,7 @@ static void eth_configure(int n, void *init, char *mac, goto out_unregister; set_ether_mac(dev, device->mac); - dev->mtu = transport->user->max_packet; + dev->mtu = transport->user->mtu; dev->open = uml_net_open; dev->hard_start_xmit = uml_net_start_xmit; dev->stop = uml_net_close; @@ -463,6 +490,10 @@ static void eth_configure(int n, void *init, char *mac, dev->watchdog_timeo = (HZ >> 1); dev->irq = UM_ETH_IRQ; + err = update_drop_skb(lp->max_packet); + if (err) + goto out_undo_user_init; + rtnl_lock(); err = register_netdevice(dev); rtnl_unlock(); @@ -493,9 +524,9 @@ static struct uml_net *find_device(int n) struct list_head *ele; spin_lock(&devices_lock); - list_for_each(ele, &devices){ + list_for_each(ele, &devices) { device = list_entry(ele, struct uml_net, list); - if(device->index == n) + if (device->index == n) goto out; } device = NULL; @@ -511,19 +542,19 @@ static int eth_parse(char *str, int *index_out, char **str_out, int n, err = -EINVAL;; n = simple_strtoul(str, &end, 0); - if(end == str){ + if (end == str) { *error_out = "Bad device number"; return err; } str = end; - if(*str != '='){ + if (*str != '=') { *error_out = "Expected '=' after device number"; return err; } str++; - if(find_device(n)){ + if (find_device(n)) { *error_out = "Device already configured"; return err; } @@ -551,20 +582,20 @@ static int check_transport(struct transport *transport, char *eth, int n, int len; len = strlen(transport->name); - if(strncmp(eth, transport->name, len)) + if (strncmp(eth, transport->name, len)) return 0; eth += len; - if(*eth == ',') + if (*eth == ',') eth++; - else if(*eth != '\0') + else if (*eth != '\0') return 0; *init_out = kmalloc(transport->setup_size, GFP_KERNEL); - if(*init_out == NULL) + if (*init_out == NULL) return 1; - if(!transport->setup(eth, mac_out, *init_out)){ + if (!transport->setup(eth, mac_out, *init_out)) { kfree(*init_out); *init_out = NULL; } @@ -584,13 +615,13 @@ void register_transport(struct transport *new) list_add(&new->list, &transports); spin_unlock(&transports_lock); - list_for_each_safe(ele, next, ð_cmd_line){ + list_for_each_safe(ele, next, ð_cmd_line) { eth = list_entry(ele, struct eth_init, list); match = check_transport(new, eth->init, eth->index, &init, &mac); - if(!match) + if (!match) continue; - else if(init != NULL){ + else if (init != NULL) { eth_configure(eth->index, init, mac, new); kfree(init); } @@ -607,11 +638,11 @@ static int eth_setup_common(char *str, int index) int found = 0; spin_lock(&transports_lock); - list_for_each(ele, &transports){ + list_for_each(ele, &transports) { transport = list_entry(ele, struct transport, list); - if(!check_transport(transport, str, index, &init, &mac)) + if (!check_transport(transport, str, index, &init, &mac)) continue; - if(init != NULL){ + if (init != NULL) { eth_configure(index, init, mac, transport); kfree(init); } @@ -630,15 +661,15 @@ static int __init eth_setup(char *str) int n, err; err = eth_parse(str, &n, &str, &error); - if(err){ + if (err) { printk(KERN_ERR "eth_setup - Couldn't parse '%s' : %s\n", str, error); return 1; } new = alloc_bootmem(sizeof(*new)); - if (new == NULL){ - printk("eth_init : alloc_bootmem failed\n"); + if (new == NULL) { + printk(KERN_ERR "eth_init : alloc_bootmem failed\n"); return 1; } @@ -661,36 +692,36 @@ static int net_config(char *str, char **error_out) int n, err; err = eth_parse(str, &n, &str, error_out); - if(err) + if (err) return err; /* This string is broken up and the pieces used by the underlying * driver. So, it is freed only if eth_setup_common fails. */ str = kstrdup(str, GFP_KERNEL); - if(str == NULL){ + if (str == NULL) { *error_out = "net_config failed to strdup string"; return -ENOMEM; } err = !eth_setup_common(str, n); - if(err) + if (err) kfree(str); - return(err); + return err; } static int net_id(char **str, int *start_out, int *end_out) { - char *end; - int n; + char *end; + int n; n = simple_strtoul(*str, &end, 0); - if((*end != '\0') || (end == *str)) + if ((*end != '\0') || (end == *str)) return -1; - *start_out = n; - *end_out = n; - *str = end; - return n; + *start_out = n; + *end_out = n; + *str = end; + return n; } static int net_remove(int n, char **error_out) @@ -700,12 +731,12 @@ static int net_remove(int n, char **error_out) struct uml_net_private *lp; device = find_device(n); - if(device == NULL) + if (device == NULL) return -ENODEV; dev = device->dev; lp = dev->priv; - if(lp->fd > 0) + if (lp->fd > 0) return -EBUSY; unregister_netdev(dev); platform_device_unregister(&device->pdev); @@ -731,13 +762,13 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event, void (*proc)(unsigned char *, unsigned char *, void *); unsigned char addr_buf[4], netmask_buf[4]; - if(dev->open != uml_net_open) + if (dev->open != uml_net_open) return NOTIFY_DONE; lp = dev->priv; proc = NULL; - switch (event){ + switch (event) { case NETDEV_UP: proc = lp->add_address; break; @@ -745,7 +776,7 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event, proc = lp->delete_address; break; } - if(proc != NULL){ + if (proc != NULL) { memcpy(addr_buf, &ifa->ifa_address, sizeof(addr_buf)); memcpy(netmask_buf, &ifa->ifa_mask, sizeof(netmask_buf)); (*proc)(addr_buf, netmask_buf, &lp->user); @@ -773,13 +804,13 @@ static int uml_net_init(void) * addresses which have already been set up get handled properly. */ spin_lock(&opened_lock); - list_for_each(ele, &opened){ + list_for_each(ele, &opened) { lp = list_entry(ele, struct uml_net_private, list); ip = lp->dev->ip_ptr; - if(ip == NULL) + if (ip == NULL) continue; in = ip->ifa_list; - while(in != NULL){ + while (in != NULL) { uml_inetaddr_event(NULL, NETDEV_UP, in); in = in->ifa_next; } @@ -797,12 +828,12 @@ static void close_devices(void) struct uml_net_private *lp; spin_lock(&opened_lock); - list_for_each(ele, &opened){ + list_for_each(ele, &opened) { lp = list_entry(ele, struct uml_net_private, list); free_irq(lp->dev->irq, lp->dev); - if((lp->close != NULL) && (lp->fd >= 0)) + if ((lp->close != NULL) && (lp->fd >= 0)) (*lp->close)(lp->fd, &lp->user); - if(lp->remove != NULL) + if (lp->remove != NULL) (*lp->remove)(&lp->user); } spin_unlock(&opened_lock); @@ -810,19 +841,6 @@ static void close_devices(void) __uml_exitcall(close_devices); -struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra) -{ - if((skb != NULL) && (skb_tailroom(skb) < extra)){ - struct sk_buff *skb2; - - skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC); - dev_kfree_skb(skb); - skb = skb2; - } - if(skb != NULL) skb_put(skb, extra); - return(skb); -} - void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *, void *), void *arg) @@ -832,9 +850,9 @@ void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *, struct in_ifaddr *in; unsigned char address[4], netmask[4]; - if(ip == NULL) return; + if (ip == NULL) return; in = ip->ifa_list; - while(in != NULL){ + while (in != NULL) { memcpy(address, &in->ifa_address, sizeof(address)); memcpy(netmask, &in->ifa_mask, sizeof(netmask)); (*cb)(address, netmask, arg); @@ -849,15 +867,15 @@ int dev_netmask(void *d, void *m) struct in_ifaddr *in; __be32 *mask_out = m; - if(ip == NULL) - return(1); + if (ip == NULL) + return 1; in = ip->ifa_list; - if(in == NULL) - return(1); + if (in == NULL) + return 1; *mask_out = in->ifa_mask; - return(0); + return 0; } void *get_output_buffer(int *len_out) @@ -865,7 +883,7 @@ void *get_output_buffer(int *len_out) void *ret; ret = (void *) __get_free_pages(GFP_KERNEL, 0); - if(ret) *len_out = PAGE_SIZE; + if (ret) *len_out = PAGE_SIZE; else *len_out = 0; return ret; } @@ -881,16 +899,16 @@ int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out, char *remain; remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL); - if(remain != NULL){ - printk("tap_setup_common - Extra garbage on specification : " - "'%s'\n", remain); - return(1); + if (remain != NULL) { + printk(KERN_ERR "tap_setup_common - Extra garbage on " + "specification : '%s'\n", remain); + return 1; } - return(0); + return 0; } unsigned short eth_protocol(struct sk_buff *skb) { - return(eth_type_trans(skb, skb->dev)); + return eth_type_trans(skb, skb->dev); } diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index da946e3e1bf2..90d7f2e8ead8 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -1,34 +1,32 @@ -/* - * 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 <stddef.h> -#include <stdarg.h> -#include <unistd.h> #include <stdio.h> +#include <unistd.h> +#include <stdarg.h> #include <errno.h> -#include <stdlib.h> +#include <stddef.h> #include <string.h> #include <sys/socket.h> #include <sys/wait.h> -#include <sys/time.h> -#include "user.h" -#include "kern_util.h" #include "net_user.h" +#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "kern_constants.h" +#include "user.h" int tap_open_common(void *dev, char *gate_addr) { int tap_addr[4]; - if(gate_addr == NULL) + if (gate_addr == NULL) return 0; - if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], - &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){ - printk("Invalid tap IP address - '%s'\n", gate_addr); + if (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], + &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4) { + printk(UM_KERN_ERR "Invalid tap IP address - '%s'\n", + gate_addr); return -EINVAL; } return 0; @@ -38,15 +36,15 @@ void tap_check_ips(char *gate_addr, unsigned char *eth_addr) { int tap_addr[4]; - if((gate_addr != NULL) && - (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], - &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) && - (eth_addr[0] == tap_addr[0]) && - (eth_addr[1] == tap_addr[1]) && - (eth_addr[2] == tap_addr[2]) && - (eth_addr[3] == tap_addr[3])){ - printk("The tap IP address and the UML eth IP address" - " must be different\n"); + if ((gate_addr != NULL) && + (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], + &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) && + (eth_addr[0] == tap_addr[0]) && + (eth_addr[1] == tap_addr[1]) && + (eth_addr[2] == tap_addr[2]) && + (eth_addr[3] == tap_addr[3])) { + printk(UM_KERN_ERR "The tap IP address and the UML eth IP " + "address must be different\n"); } } @@ -57,24 +55,28 @@ void read_output(int fd, char *output, int len) char c; char *str; - if(output == NULL){ + if (output == NULL) { output = &c; len = sizeof(c); } - + *output = '\0'; - ret = os_read_file(fd, &remain, sizeof(remain)); + ret = read(fd, &remain, sizeof(remain)); if (ret != sizeof(remain)) { + if (ret < 0) + ret = -errno; expected = sizeof(remain); str = "length"; goto err; } - while(remain != 0){ + while (remain != 0) { expected = (remain < len) ? remain : len; - ret = os_read_file(fd, output, expected); + ret = read(fd, output, expected); if (ret != expected) { + if (ret < 0) + ret = -errno; str = "data"; goto err; } @@ -85,20 +87,22 @@ void read_output(int fd, char *output, int len) err: if (ret < 0) - printk("read_output - read of %s failed, errno = %d\n", str, -ret); + printk(UM_KERN_ERR "read_output - read of %s failed, " + "errno = %d\n", str, -ret); else - printk("read_output - read of %s failed, read only %d of %d bytes\n", str, ret, expected); + printk(UM_KERN_ERR "read_output - read of %s failed, read only " + "%d of %d bytes\n", str, ret, expected); } int net_read(int fd, void *buf, int len) { int n; - n = os_read_file(fd, buf, len); + n = read(fd, buf, len); - if(n == -EAGAIN) + if ((n < 0) && (errno == EAGAIN)) return 0; - else if(n == 0) + else if (n == 0) return -ENOTCONN; return n; } @@ -108,12 +112,12 @@ int net_recvfrom(int fd, void *buf, int len) int n; CATCH_EINTR(n = recvfrom(fd, buf, len, 0, NULL, NULL)); - if(n < 0){ - if(errno == EAGAIN) + if (n < 0) { + if (errno == EAGAIN) return 0; return -errno; } - else if(n == 0) + else if (n == 0) return -ENOTCONN; return n; } @@ -122,11 +126,11 @@ int net_write(int fd, void *buf, int len) { int n; - n = os_write_file(fd, buf, len); + n = write(fd, buf, len); - if(n == -EAGAIN) + if ((n < 0) && (errno == EAGAIN)) return 0; - else if(n == 0) + else if (n == 0) return -ENOTCONN; return n; } @@ -136,12 +140,12 @@ int net_send(int fd, void *buf, int len) int n; CATCH_EINTR(n = send(fd, buf, len, 0)); - if(n < 0){ - if(errno == EAGAIN) + if (n < 0) { + if (errno == EAGAIN) return 0; return -errno; } - else if(n == 0) + else if (n == 0) return -ENOTCONN; return n; } @@ -152,12 +156,12 @@ int net_sendto(int fd, void *buf, int len, void *to, int sock_len) CATCH_EINTR(n = sendto(fd, buf, len, 0, (struct sockaddr *) to, sock_len)); - if(n < 0){ - if(errno == EAGAIN) + if (n < 0) { + if (errno == EAGAIN) return 0; return -errno; } - else if(n == 0) + else if (n == 0) return -ENOTCONN; return n; } @@ -171,7 +175,7 @@ static void change_pre_exec(void *arg) { struct change_pre_exec_data *data = arg; - os_close_file(data->close_me); + close(data->close_me); dup2(data->stdout, 1); } @@ -181,8 +185,9 @@ static int change_tramp(char **argv, char *output, int output_len) struct change_pre_exec_data pe_data; err = os_pipe(fds, 1, 0); - if(err < 0){ - printk("change_tramp - pipe failed, err = %d\n", -err); + if (err < 0) { + printk(UM_KERN_ERR "change_tramp - pipe failed, err = %d\n", + -err); return err; } pe_data.close_me = fds[0]; @@ -192,8 +197,8 @@ static int change_tramp(char **argv, char *output, int output_len) if (pid > 0) /* Avoid hang as we won't get data in failure case. */ read_output(fds[0], output, output_len); - os_close_file(fds[0]); - os_close_file(fds[1]); + close(fds[0]); + close(fds[1]); if (pid > 0) CATCH_EINTR(err = waitpid(pid, NULL, 0)); @@ -206,25 +211,26 @@ static void change(char *dev, char *what, unsigned char *addr, char addr_buf[sizeof("255.255.255.255\0")]; char netmask_buf[sizeof("255.255.255.255\0")]; char version[sizeof("nnnnn\0")]; - char *argv[] = { "uml_net", version, what, dev, addr_buf, + char *argv[] = { "uml_net", version, what, dev, addr_buf, netmask_buf, NULL }; char *output; int output_len, pid; sprintf(version, "%d", UML_NET_VERSION); sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); - sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1], + sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1], netmask[2], netmask[3]); output_len = UM_KERN_PAGE_SIZE; output = kmalloc(output_len, UM_GFP_KERNEL); - if(output == NULL) - printk("change : failed to allocate output buffer\n"); + if (output == NULL) + printk(UM_KERN_ERR "change : failed to allocate output " + "buffer\n"); pid = change_tramp(argv, output, output_len); - if(pid < 0) return; + if (pid < 0) return; - if(output != NULL){ + if (output != NULL) { printk("%s", output); kfree(output); } @@ -246,13 +252,13 @@ char *split_if_spec(char *str, ...) va_list ap; va_start(ap, str); - while((arg = va_arg(ap, char **)) != NULL){ - if(*str == '\0') + while ((arg = va_arg(ap, char **)) != NULL) { + if (*str == '\0') return NULL; end = strchr(str, ','); - if(end != str) + if (end != str) *arg = str; - if(end == NULL) + if (end == NULL) return NULL; *end++ = '\0'; str = end; diff --git a/arch/um/drivers/null.c b/arch/um/drivers/null.c index 9016c68beee8..21ad3d7932b3 100644 --- a/arch/um/drivers/null.c +++ b/arch/um/drivers/null.c @@ -1,10 +1,11 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) +/* + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) * Licensed under the GPL */ -#include <stdlib.h> +#include <stddef.h> #include <errno.h> +#include <fcntl.h> #include "chan_user.h" #include "os.h" @@ -13,19 +14,23 @@ static int null_chan; static void *null_init(char *str, int device, const struct chan_opts *opts) { - return(&null_chan); + return &null_chan; } static int null_open(int input, int output, int primary, void *d, char **dev_out) { + int fd; + *dev_out = NULL; - return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0)); + + fd = open(DEV_NULL, O_RDWR); + return (fd < 0) ? -errno : fd; } static int null_read(int fd, char *c_out, void *unused) { - return(-ENODEV); + return -ENODEV; } static void null_free(void *data) @@ -44,14 +49,3 @@ const struct chan_ops null_ops = { .free = null_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/pcap_kern.c b/arch/um/drivers/pcap_kern.c index c329931673d6..3a750dd39be1 100644 --- a/arch/um/drivers/pcap_kern.c +++ b/arch/um/drivers/pcap_kern.c @@ -1,13 +1,11 @@ /* - * Copyright (C) 2002 Jeff Dike <jdike@karaya.com> + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL. */ #include "linux/init.h" -#include "linux/netdevice.h" -#include "linux/etherdevice.h" +#include <linux/netdevice.h> #include "net_kern.h" -#include "net_user.h" #include "pcap_user.h" struct pcap_init { @@ -33,19 +31,14 @@ void pcap_init(struct net_device *dev, void *data) printk("pcap backend, host interface %s\n", ppri->host_if); } -static int pcap_read(int fd, struct sk_buff **skb, - struct uml_net_private *lp) +static int pcap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); - if(*skb == NULL) - return -ENOMEM; - - return pcap_user_read(fd, skb_mac_header(*skb), - (*skb)->dev->mtu + ETH_HEADER_OTHER, + return pcap_user_read(fd, skb_mac_header(skb), + skb->dev->mtu + ETH_HEADER_OTHER, (struct pcap_data *) &lp->user); } -static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) +static int pcap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) { return -EPERM; } @@ -71,28 +64,29 @@ int pcap_setup(char *str, char **mac_out, void *data) remain = split_if_spec(str, &host_if, &init->filter, &options[0], &options[1], mac_out, NULL); - if(remain != NULL){ + if (remain != NULL) { printk(KERN_ERR "pcap_setup - Extra garbage on " "specification : '%s'\n", remain); return 0; } - if(host_if != NULL) + if (host_if != NULL) init->host_if = host_if; - for(i = 0; i < ARRAY_SIZE(options); i++){ - if(options[i] == NULL) + for (i = 0; i < ARRAY_SIZE(options); i++) { + if (options[i] == NULL) continue; - if(!strcmp(options[i], "promisc")) + if (!strcmp(options[i], "promisc")) init->promisc = 1; - else if(!strcmp(options[i], "nopromisc")) + else if (!strcmp(options[i], "nopromisc")) init->promisc = 0; - else if(!strcmp(options[i], "optimize")) + else if (!strcmp(options[i], "optimize")) init->optimize = 1; - else if(!strcmp(options[i], "nooptimize")) + else if (!strcmp(options[i], "nooptimize")) init->optimize = 0; else { - printk("pcap_setup : bad option - '%s'\n", options[i]); + printk(KERN_ERR "pcap_setup : bad option - '%s'\n", + options[i]); return 0; } } diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c index 1316456e2a28..e9809356c530 100644 --- a/arch/um/drivers/pcap_user.c +++ b/arch/um/drivers/pcap_user.c @@ -1,21 +1,17 @@ /* - * Copyright (C) 2002 Jeff Dike <jdike@karaya.com> + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL. */ -#include <unistd.h> -#include <stdlib.h> -#include <string.h> #include <errno.h> #include <pcap.h> +#include <string.h> #include <asm/types.h> #include "net_user.h" #include "pcap_user.h" -#include "user.h" -#include "um_malloc.h" #include "kern_constants.h" - -#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) +#include "um_malloc.h" +#include "user.h" #define PCAP_FD(p) (*(int *)(p)) @@ -25,8 +21,9 @@ static int pcap_user_init(void *data, void *dev) pcap_t *p; char errors[PCAP_ERRBUF_SIZE]; - p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors); - if(p == NULL){ + p = pcap_open_live(pri->host_if, ETH_MAX_PACKET + ETH_HEADER_OTHER, + pri->promisc, 0, errors); + if (p == NULL) { printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - " "'%s'\n", errors); return -EINVAL; @@ -43,50 +40,55 @@ static int pcap_open(void *data) __u32 netmask; int err; - if(pri->pcap == NULL) + if (pri->pcap == NULL) return -ENODEV; - if(pri->filter != NULL){ + if (pri->filter != NULL) { err = dev_netmask(pri->dev, &netmask); - if(err < 0){ + if (err < 0) { printk(UM_KERN_ERR "pcap_open : dev_netmask failed\n"); return -EIO; } - pri->compiled = kmalloc(sizeof(struct bpf_program), UM_GFP_KERNEL); - if(pri->compiled == NULL){ + pri->compiled = kmalloc(sizeof(struct bpf_program), + UM_GFP_KERNEL); + if (pri->compiled == NULL) { printk(UM_KERN_ERR "pcap_open : kmalloc failed\n"); return -ENOMEM; } - err = pcap_compile(pri->pcap, - (struct bpf_program *) pri->compiled, + err = pcap_compile(pri->pcap, + (struct bpf_program *) pri->compiled, pri->filter, pri->optimize, netmask); - if(err < 0){ + if (err < 0) { printk(UM_KERN_ERR "pcap_open : pcap_compile failed - " "'%s'\n", pcap_geterr(pri->pcap)); - return -EIO; + goto out; } err = pcap_setfilter(pri->pcap, pri->compiled); - if(err < 0){ + if (err < 0) { printk(UM_KERN_ERR "pcap_open : pcap_setfilter " "failed - '%s'\n", pcap_geterr(pri->pcap)); - return -EIO; + goto out; } } return PCAP_FD(pri->pcap); + + out: + kfree(pri->compiled); + return -EIO; } static void pcap_remove(void *data) { struct pcap_data *pri = data; - if(pri->compiled != NULL) + if (pri->compiled != NULL) pcap_freecode(pri->compiled); - if(pri->pcap != NULL) + if (pri->pcap != NULL) pcap_close(pri->pcap); } @@ -95,7 +97,7 @@ struct pcap_handler_data { int len; }; -static void handler(u_char *data, const struct pcap_pkthdr *header, +static void handler(u_char *data, const struct pcap_pkthdr *header, const u_char *packet) { int len; @@ -115,12 +117,12 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri) int n; n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata); - if(n < 0){ + if (n < 0) { printk(UM_KERN_ERR "pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap)); return -EIO; } - else if(n == 0) + else if (n == 0) return 0; return hdata.len; } @@ -130,8 +132,8 @@ const struct net_user_info pcap_user_info = { .open = pcap_open, .close = NULL, .remove = pcap_remove, - .set_mtu = NULL, .add_address = NULL, .delete_address = NULL, - .max_packet = MAX_PACKET - ETH_HEADER_OTHER + .mtu = ETH_MAX_PACKET, + .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER, }; diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index 1c8efd95c421..330543b3129b 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -1,24 +1,16 @@ /* - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) * Licensed under the GPL */ -#include "linux/list.h" -#include "linux/sched.h" -#include "linux/slab.h" +#include "linux/completion.h" #include "linux/interrupt.h" -#include "linux/spinlock.h" -#include "linux/errno.h" +#include "linux/list.h" #include "asm/atomic.h" -#include "asm/semaphore.h" -#include "asm/errno.h" -#include "kern_util.h" -#include "kern.h" -#include "irq_user.h" -#include "irq_kern.h" -#include "port.h" #include "init.h" +#include "irq_kern.h" #include "os.h" +#include "port.h" struct port_list { struct list_head list; @@ -53,8 +45,8 @@ static irqreturn_t pipe_interrupt(int irq, void *data) int fd; fd = os_rcv_fd(conn->socket[0], &conn->helper_pid); - if(fd < 0){ - if(fd == -EAGAIN) + if (fd < 0) { + if (fd == -EAGAIN) return IRQ_NONE; printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", @@ -81,18 +73,18 @@ static irqreturn_t pipe_interrupt(int irq, void *data) static int port_accept(struct port_list *port) { struct connection *conn; - int fd, socket[2], pid, ret = 0; + int fd, socket[2], pid; fd = port_connection(port->fd, socket, &pid); - if(fd < 0){ - if(fd != -EAGAIN) + if (fd < 0) { + if (fd != -EAGAIN) printk(KERN_ERR "port_accept : port_connection " "returned %d\n", -fd); goto out; } conn = kmalloc(sizeof(*conn), GFP_ATOMIC); - if(conn == NULL){ + if (conn == NULL) { printk(KERN_ERR "port_accept : failed to allocate " "connection\n"); goto out_close; @@ -104,17 +96,17 @@ static int port_accept(struct port_list *port) .telnetd_pid = pid, .port = port }); - if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, + if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, - "telnetd", conn)){ + "telnetd", conn)) { printk(KERN_ERR "port_accept : failed to get IRQ for " "telnetd\n"); goto out_free; } - if(atomic_read(&port->wait_count) == 0){ + if (atomic_read(&port->wait_count) == 0) { os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); - printk("No one waiting for port\n"); + printk(KERN_ERR "No one waiting for port\n"); } list_add(&conn->list, &port->pending); return 1; @@ -123,28 +115,29 @@ static int port_accept(struct port_list *port) kfree(conn); out_close: os_close_file(fd); - if(pid != -1) - os_kill_process(pid, 1); + os_kill_process(pid, 1); out: - return ret; + return 0; } static DECLARE_MUTEX(ports_sem); static LIST_HEAD(ports); -void port_work_proc(struct work_struct *unused) +static void port_work_proc(struct work_struct *unused) { struct port_list *port; struct list_head *ele; unsigned long flags; local_irq_save(flags); - list_for_each(ele, &ports){ + list_for_each(ele, &ports) { port = list_entry(ele, struct port_list, list); - if(!port->has_connection) + if (!port->has_connection) continue; + reactivate_fd(port->fd, ACCEPT_IRQ); - while(port_accept(port)) ; + while (port_accept(port)) + ; port->has_connection = 0; } local_irq_restore(flags); @@ -169,25 +162,27 @@ void *port_data(int port_num) int fd; down(&ports_sem); - list_for_each(ele, &ports){ + list_for_each(ele, &ports) { port = list_entry(ele, struct port_list, list); - if(port->port == port_num) goto found; + if (port->port == port_num) + goto found; } port = kmalloc(sizeof(struct port_list), GFP_KERNEL); - if(port == NULL){ + if (port == NULL) { printk(KERN_ERR "Allocation of port list failed\n"); goto out; } fd = port_listen_fd(port_num); - if(fd < 0){ + if (fd < 0) { printk(KERN_ERR "binding to port %d failed, errno = %d\n", port_num, -fd); goto out_free; } - if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, + + if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, - "port", port)){ + "port", port)) { printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); goto out_close; } @@ -206,7 +201,7 @@ void *port_data(int port_num) found: dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL); - if(dev == NULL){ + if (dev == NULL) { printk(KERN_ERR "Allocation of port device entry failed\n"); goto out; } @@ -216,10 +211,10 @@ void *port_data(int port_num) .telnetd_pid = -1 }); goto out; - out_free: - kfree(port); out_close: os_close_file(fd); + out_free: + kfree(port); out: up(&ports_sem); return dev; @@ -233,9 +228,9 @@ int port_wait(void *data) int fd; atomic_inc(&port->wait_count); - while(1){ + while (1) { fd = -ERESTARTSYS; - if(wait_for_completion_interruptible(&port->done)) + if (wait_for_completion_interruptible(&port->done)) goto out; spin_lock(&port->lock); @@ -258,7 +253,8 @@ int port_wait(void *data) */ free_irq(TELNETD_IRQ, conn); - if(conn->fd >= 0) break; + if (conn->fd >= 0) + break; os_close_file(conn->fd); kfree(conn); } @@ -276,9 +272,9 @@ void port_remove_dev(void *d) { struct port_dev *dev = d; - if(dev->helper_pid != -1) + if (dev->helper_pid != -1) os_kill_process(dev->helper_pid, 0); - if(dev->telnetd_pid != -1) + if (dev->telnetd_pid != -1) os_kill_process(dev->telnetd_pid, 1); dev->helper_pid = -1; dev->telnetd_pid = -1; @@ -297,7 +293,7 @@ static void free_port(void) struct list_head *ele; struct port_list *port; - list_for_each(ele, &ports){ + list_for_each(ele, &ports) { port = list_entry(ele, struct port_list, list); free_irq_by_fd(port->fd); os_close_file(port->fd); diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c index c799b00012c7..addd75902656 100644 --- a/arch/um/drivers/port_user.c +++ b/arch/um/drivers/port_user.c @@ -1,24 +1,20 @@ /* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) * Licensed under the GPL */ #include <stdio.h> -#include <stddef.h> #include <stdlib.h> -#include <string.h> #include <errno.h> -#include <unistd.h> #include <termios.h> -#include <sys/socket.h> -#include <sys/un.h> +#include <unistd.h> #include <netinet/in.h> -#include "kern_util.h" -#include "user.h" #include "chan_user.h" -#include "port.h" +#include "kern_constants.h" #include "os.h" +#include "port.h" #include "um_malloc.h" +#include "user.h" struct port_chan { int raw; @@ -34,24 +30,25 @@ static void *port_init(char *str, int device, const struct chan_opts *opts) char *end; int port; - if(*str != ':'){ - printk("port_init : channel type 'port' must specify a " - "port number\n"); + if (*str != ':') { + printk(UM_KERN_ERR "port_init : channel type 'port' must " + "specify a port number\n"); return NULL; } str++; port = strtoul(str, &end, 0); - if((*end != '\0') || (end == str)){ - printk("port_init : couldn't parse port '%s'\n", str); + if ((*end != '\0') || (end == str)) { + printk(UM_KERN_ERR "port_init : couldn't parse port '%s'\n", + str); return NULL; } kern_data = port_data(port); - if(kern_data == NULL) + if (kern_data == NULL) return NULL; data = kmalloc(sizeof(*data), UM_GFP_KERNEL); - if(data == NULL) + if (data == NULL) goto err; *data = ((struct port_chan) { .raw = opts->raw, @@ -79,13 +76,13 @@ static int port_open(int input, int output, int primary, void *d, int fd, err; fd = port_wait(data->kernel_data); - if((fd >= 0) && data->raw){ + if ((fd >= 0) && data->raw) { CATCH_EINTR(err = tcgetattr(fd, &data->tt)); - if(err) + if (err) return err; err = raw(fd); - if(err) + if (err) return err; } *dev_out = data->dev; @@ -119,11 +116,11 @@ int port_listen_fd(int port) int fd, err, arg; fd = socket(PF_INET, SOCK_STREAM, 0); - if(fd == -1) + if (fd == -1) return -errno; arg = 1; - if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0){ + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0) { err = -errno; goto out; } @@ -131,23 +128,23 @@ int port_listen_fd(int port) addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = htonl(INADDR_ANY); - if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){ + if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { err = -errno; goto out; } - if(listen(fd, 1) < 0){ + if (listen(fd, 1) < 0) { err = -errno; goto out; } err = os_set_fd_block(fd, 0); - if(err < 0) + if (err < 0) goto out; return fd; out: - os_close_file(fd); + close(fd); return err; } @@ -163,10 +160,10 @@ void port_pre_exec(void *arg) dup2(data->sock_fd, 0); dup2(data->sock_fd, 1); dup2(data->sock_fd, 2); - os_close_file(data->sock_fd); + close(data->sock_fd); dup2(data->pipe_fd, 3); - os_shutdown_socket(3, 1, 0); - os_close_file(data->pipe_fd); + shutdown(3, SHUT_RD); + close(data->pipe_fd); } int port_connection(int fd, int *socket, int *pid_out) @@ -176,12 +173,12 @@ int port_connection(int fd, int *socket, int *pid_out) "/usr/lib/uml/port-helper", NULL }; struct port_pre_exec_data data; - new = os_accept_connection(fd); - if(new < 0) - return new; + new = accept(fd, NULL, 0); + if (new < 0) + return -errno; err = os_pipe(socket, 0, 0); - if(err < 0) + if (err < 0) goto out_close; data = ((struct port_pre_exec_data) @@ -189,18 +186,18 @@ int port_connection(int fd, int *socket, int *pid_out) .pipe_fd = socket[1] }); err = run_helper(port_pre_exec, &data, argv); - if(err < 0) + if (err < 0) goto out_shutdown; *pid_out = err; return new; out_shutdown: - os_shutdown_socket(socket[0], 1, 1); - os_close_file(socket[0]); - os_shutdown_socket(socket[1], 1, 1); - os_close_file(socket[1]); + shutdown(socket[0], SHUT_RDWR); + close(socket[0]); + shutdown(socket[1], SHUT_RDWR); + close(socket[1]); out_close: - os_close_file(new); + close(new); return err; } diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index 1e3fd619a837..49c79dda6046 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -6,16 +6,16 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> -#include <string.h> -#include <fcntl.h> #include <errno.h> +#include <fcntl.h> +#include <string.h> #include <termios.h> #include <sys/stat.h> #include "chan_user.h" -#include "os.h" -#include "user.h" #include "kern_constants.h" +#include "os.h" #include "um_malloc.h" +#include "user.h" struct pty_chan { void (*announce)(char *dev_name, int dev); @@ -33,7 +33,7 @@ static void *pty_chan_init(char *str, int device, const struct chan_opts *opts) if (data == NULL) return NULL; - *data = ((struct pty_chan) { .announce = opts->announce, + *data = ((struct pty_chan) { .announce = opts->announce, .dev = device, .raw = opts->raw }); return data; @@ -56,11 +56,11 @@ static int pts_open(int input, int output, int primary, void *d, if (data->raw) { CATCH_EINTR(err = tcgetattr(fd, &data->tt)); if (err) - return err; + goto out_close; err = raw(fd); if (err) - return err; + goto out_close; } dev = ptsname(fd); @@ -71,6 +71,10 @@ static int pts_open(int input, int output, int primary, void *d, (*data->announce)(dev, data->dev); return fd; + +out_close: + close(fd); + return err; } static int getmaster(char *line) @@ -97,7 +101,7 @@ static int getmaster(char *line) *tp = 't'; err = access(line, R_OK | W_OK); *tp = 'p'; - if(!err) + if (!err) return master; close(master); } @@ -119,12 +123,14 @@ static int pty_open(int input, int output, int primary, void *d, if (fd < 0) return fd; - if(data->raw){ + if (data->raw) { err = raw(fd); - if (err) + if (err) { + close(fd); return err; + } } - + if (data->announce) (*data->announce)(dev, data->dev); diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c index 125c44f77638..ae67e7158e71 100644 --- a/arch/um/drivers/slip_kern.c +++ b/arch/um/drivers/slip_kern.c @@ -1,11 +1,12 @@ -#include "linux/kernel.h" -#include "linux/stddef.h" -#include "linux/init.h" -#include "linux/netdevice.h" -#include "linux/if_arp.h" +/* + * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL. + */ + +#include <linux/if_arp.h> +#include <linux/init.h> +#include <linux/netdevice.h> #include "net_kern.h" -#include "net_user.h" -#include "kern.h" #include "slip.h" struct slip_init { @@ -43,21 +44,19 @@ void slip_init(struct net_device *dev, void *data) static unsigned short slip_protocol(struct sk_buff *skbuff) { - return(htons(ETH_P_IP)); + return htons(ETH_P_IP); } -static int slip_read(int fd, struct sk_buff **skb, - struct uml_net_private *lp) +static int slip_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - return(slip_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu, - (struct slip_data *) &lp->user)); + return slip_user_read(fd, skb_mac_header(skb), skb->dev->mtu, + (struct slip_data *) &lp->user); } -static int slip_write(int fd, struct sk_buff **skb, - struct uml_net_private *lp) +static int slip_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - return(slip_user_write(fd, (*skb)->data, (*skb)->len, - (struct slip_data *) &lp->user)); + return slip_user_write(fd, skb->data, skb->len, + (struct slip_data *) &lp->user); } const struct net_kern_info slip_kern_info = { @@ -71,12 +70,11 @@ static int slip_setup(char *str, char **mac_out, void *data) { struct slip_init *init = data; - *init = ((struct slip_init) - { .gate_addr = NULL }); + *init = ((struct slip_init) { .gate_addr = NULL }); - if(str[0] != '\0') + if (str[0] != '\0') init->gate_addr = str; - return(1); + return 1; } static struct transport slip_transport = { diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index c0b73c28cff0..5f06204d6871 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -1,21 +1,22 @@ +/* + * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL. + */ + #include <stdio.h> #include <stdlib.h> #include <unistd.h> -#include <stddef.h> -#include <sched.h> -#include <string.h> #include <errno.h> +#include <fcntl.h> +#include <string.h> #include <sys/termios.h> #include <sys/wait.h> -#include <sys/signal.h> -#include "kern_util.h" -#include "user.h" +#include "kern_constants.h" #include "net_user.h" -#include "slip.h" -#include "slip_common.h" #include "os.h" +#include "slip.h" #include "um_malloc.h" -#include "kern_constants.h" +#include "user.h" static int slip_user_init(void *data, void *dev) { @@ -31,8 +32,9 @@ static int set_up_tty(int fd) struct termios tios; if (tcgetattr(fd, &tios) < 0) { - printk("could not get initial terminal attributes\n"); - return(-1); + printk(UM_KERN_ERR "could not get initial terminal " + "attributes\n"); + return -1; } tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL; @@ -48,10 +50,10 @@ static int set_up_tty(int fd) cfsetispeed(&tios, B38400); if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { - printk("failed to set terminal attributes\n"); - return(-1); + printk(UM_KERN_ERR "failed to set terminal attributes\n"); + return -1; } - return(0); + return 0; } struct slip_pre_exec_data { @@ -64,9 +66,11 @@ static void slip_pre_exec(void *arg) { struct slip_pre_exec_data *data = arg; - if(data->stdin >= 0) dup2(data->stdin, 0); + if (data->stdin >= 0) + dup2(data->stdin, 0); dup2(data->stdout, 1); - if(data->close_me >= 0) os_close_file(data->close_me); + if (data->close_me >= 0) + close(data->close_me); } static int slip_tramp(char **argv, int fd) @@ -76,8 +80,9 @@ static int slip_tramp(char **argv, int fd) int status, pid, fds[2], err, output_len; err = os_pipe(fds, 1, 0); - if(err < 0){ - printk("slip_tramp : pipe failed, err = %d\n", -err); + if (err < 0) { + printk(UM_KERN_ERR "slip_tramp : pipe failed, err = %d\n", + -err); goto out; } @@ -86,41 +91,42 @@ static int slip_tramp(char **argv, int fd) pe_data.stdout = fds[1]; pe_data.close_me = fds[0]; err = run_helper(slip_pre_exec, &pe_data, argv); - if(err < 0) + if (err < 0) goto out_close; pid = err; output_len = UM_KERN_PAGE_SIZE; output = kmalloc(output_len, UM_GFP_KERNEL); - if(output == NULL){ - printk("slip_tramp : failed to allocate output buffer\n"); + if (output == NULL) { + printk(UM_KERN_ERR "slip_tramp : failed to allocate output " + "buffer\n"); os_kill_process(pid, 1); err = -ENOMEM; goto out_free; } - os_close_file(fds[1]); + close(fds[1]); read_output(fds[0], output, output_len); printk("%s", output); CATCH_EINTR(err = waitpid(pid, &status, 0)); - if(err < 0) + if (err < 0) err = errno; - else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ - printk("'%s' didn't exit with status 0\n", argv[0]); + else if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { + printk(UM_KERN_ERR "'%s' didn't exit with status 0\n", argv[0]); err = -EINVAL; } else err = 0; - os_close_file(fds[0]); + close(fds[0]); out_free: kfree(output); return err; out_close: - os_close_file(fds[0]); - os_close_file(fds[1]); + close(fds[0]); + close(fds[1]); out: return err; } @@ -130,60 +136,64 @@ static int slip_open(void *data) struct slip_data *pri = data; char version_buf[sizeof("nnnnn\0")]; char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; - char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf, + char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf, NULL }; int sfd, mfd, err; err = get_pty(); - if(err < 0){ - printk("slip-open : Failed to open pty, err = %d\n", -err); + if (err < 0) { + printk(UM_KERN_ERR "slip-open : Failed to open pty, err = %d\n", + -err); goto out; } mfd = err; - err = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0); - if(err < 0){ - printk("Couldn't open tty for slip line, err = %d\n", -err); + err = open(ptsname(mfd), O_RDWR, 0); + if (err < 0) { + printk(UM_KERN_ERR "Couldn't open tty for slip line, " + "err = %d\n", -err); goto out_close; } sfd = err; - if(set_up_tty(sfd)) + if (set_up_tty(sfd)) goto out_close2; pri->slave = sfd; pri->slip.pos = 0; pri->slip.esc = 0; - if(pri->gate_addr != NULL){ + if (pri->gate_addr != NULL) { sprintf(version_buf, "%d", UML_NET_VERSION); strcpy(gate_buf, pri->gate_addr); err = slip_tramp(argv, sfd); - if(err < 0){ - printk("slip_tramp failed - err = %d\n", -err); + if (err < 0) { + printk(UM_KERN_ERR "slip_tramp failed - err = %d\n", + -err); goto out_close2; } err = os_get_ifname(pri->slave, pri->name); - if(err < 0){ - printk("get_ifname failed, err = %d\n", -err); + if (err < 0) { + printk(UM_KERN_ERR "get_ifname failed, err = %d\n", + -err); goto out_close2; } iter_addresses(pri->dev, open_addr, pri->name); } else { err = os_set_slip(sfd); - if(err < 0){ - printk("Failed to set slip discipline encapsulation - " - "err = %d\n", -err); + if (err < 0) { + printk(UM_KERN_ERR "Failed to set slip discipline " + "encapsulation - err = %d\n", -err); goto out_close2; } } - return(mfd); + return mfd; out_close2: - os_close_file(sfd); + close(sfd); out_close: - os_close_file(mfd); + close(mfd); out: return err; } @@ -192,21 +202,21 @@ static void slip_close(int fd, void *data) { struct slip_data *pri = data; char version_buf[sizeof("nnnnn\0")]; - char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name, + char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name, NULL }; int err; - if(pri->gate_addr != NULL) + if (pri->gate_addr != NULL) iter_addresses(pri->dev, close_addr, pri->name); sprintf(version_buf, "%d", UML_NET_VERSION); err = slip_tramp(argv, pri->slave); - if(err != 0) - printk("slip_tramp failed - errno = %d\n", -err); - os_close_file(fd); - os_close_file(pri->slave); + if (err != 0) + printk(UM_KERN_ERR "slip_tramp failed - errno = %d\n", -err); + close(fd); + close(pri->slave); pri->slave = -1; } @@ -220,17 +230,13 @@ int slip_user_write(int fd, void *buf, int len, struct slip_data *pri) return slip_proto_write(fd, buf, len, &pri->slip); } -static int slip_set_mtu(int mtu, void *data) -{ - return(mtu); -} - static void slip_add_addr(unsigned char *addr, unsigned char *netmask, void *data) { struct slip_data *pri = data; - if(pri->slave < 0) return; + if (pri->slave < 0) + return; open_addr(addr, netmask, pri->name); } @@ -239,7 +245,8 @@ static void slip_del_addr(unsigned char *addr, unsigned char *netmask, { struct slip_data *pri = data; - if(pri->slave < 0) return; + if (pri->slave < 0) + return; close_addr(addr, netmask, pri->name); } @@ -248,8 +255,8 @@ const struct net_user_info slip_user_info = { .open = slip_open, .close = slip_close, .remove = NULL, - .set_mtu = slip_set_mtu, .add_address = slip_add_addr, .delete_address = slip_del_addr, - .max_packet = BUF_SIZE + .mtu = BUF_SIZE, + .max_packet = BUF_SIZE, }; diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c index 0a0324a6d290..240ee650865d 100644 --- a/arch/um/drivers/slirp_kern.c +++ b/arch/um/drivers/slirp_kern.c @@ -1,11 +1,14 @@ -#include "linux/kernel.h" -#include "linux/stddef.h" +/* + * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL. + */ + +#include <linux/if_arp.h> #include "linux/init.h" -#include "linux/netdevice.h" -#include "linux/if_arp.h" +#include <linux/netdevice.h> +#include <linux/string.h> #include "net_kern.h" #include "net_user.h" -#include "kern.h" #include "slirp.h" struct slirp_init { @@ -39,29 +42,26 @@ void slirp_init(struct net_device *dev, void *data) dev->tx_queue_len = 256; dev->flags = IFF_NOARP; printk("SLIRP backend - command line:"); - for(i=0;spri->argw.argv[i]!=NULL;i++) { + for (i = 0; spri->argw.argv[i] != NULL; i++) printk(" '%s'",spri->argw.argv[i]); - } printk("\n"); } static unsigned short slirp_protocol(struct sk_buff *skbuff) { - return(htons(ETH_P_IP)); + return htons(ETH_P_IP); } -static int slirp_read(int fd, struct sk_buff **skb, - struct uml_net_private *lp) +static int slirp_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - return(slirp_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu, - (struct slirp_data *) &lp->user)); + return slirp_user_read(fd, skb_mac_header(skb), skb->dev->mtu, + (struct slirp_data *) &lp->user); } -static int slirp_write(int fd, struct sk_buff **skb, - struct uml_net_private *lp) +static int slirp_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - return(slirp_user_write(fd, (*skb)->data, (*skb)->len, - (struct slirp_data *) &lp->user)); + return slirp_user_write(fd, skb->data, skb->len, + (struct slirp_data *) &lp->user); } const struct net_kern_info slirp_kern_info = { @@ -76,31 +76,32 @@ static int slirp_setup(char *str, char **mac_out, void *data) struct slirp_init *init = data; int i=0; - *init = ((struct slirp_init) - { .argw = { { "slirp", NULL } } }); + *init = ((struct slirp_init) { .argw = { { "slirp", NULL } } }); str = split_if_spec(str, mac_out, NULL); - if(str == NULL) { /* no command line given after MAC addr */ - return(1); - } + if (str == NULL) /* no command line given after MAC addr */ + return 1; do { - if(i>=SLIRP_MAX_ARGS-1) { - printk("slirp_setup: truncating slirp arguments\n"); + if (i >= SLIRP_MAX_ARGS - 1) { + printk(KERN_WARNING "slirp_setup: truncating slirp " + "arguments\n"); break; } init->argw.argv[i++] = str; while(*str && *str!=',') { - if(*str=='_') *str=' '; + if (*str == '_') + *str=' '; str++; } - if(*str!=',') + if (*str != ',') break; - *str++='\0'; - } while(1); - init->argw.argv[i]=NULL; - return(1); + *str++ = '\0'; + } while (1); + + init->argw.argv[i] = NULL; + return 1; } static struct transport slirp_transport = { diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index 0e462f64f227..1865089ff41a 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c @@ -1,18 +1,17 @@ -#include <stdio.h> -#include <stdlib.h> +/* + * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL. + */ + #include <unistd.h> -#include <stddef.h> -#include <sched.h> -#include <string.h> #include <errno.h> +#include <string.h> #include <sys/wait.h> -#include <sys/signal.h> -#include "kern_util.h" -#include "user.h" +#include "kern_constants.h" #include "net_user.h" -#include "slirp.h" -#include "slip_common.h" #include "os.h" +#include "slirp.h" +#include "user.h" static int slirp_user_init(void *data, void *dev) { @@ -31,8 +30,10 @@ static void slirp_pre_exec(void *arg) { struct slirp_pre_exec_data *data = arg; - if(data->stdin != -1) dup2(data->stdin, 0); - if(data->stdout != -1) dup2(data->stdout, 1); + if (data->stdin != -1) + dup2(data->stdin, 0); + if (data->stdout != -1) + dup2(data->stdout, 1); } static int slirp_tramp(char **argv, int fd) @@ -44,7 +45,7 @@ static int slirp_tramp(char **argv, int fd) pe_data.stdout = fd; pid = run_helper(slirp_pre_exec, &pe_data, argv); - return(pid); + return pid; } static int slirp_open(void *data) @@ -53,12 +54,12 @@ static int slirp_open(void *data) int fds[2], pid, err; err = os_pipe(fds, 1, 1); - if(err) - return(err); + if (err) + return err; err = slirp_tramp(pri->argw.argv, fds[1]); - if(err < 0){ - printk("slirp_tramp failed - errno = %d\n", -err); + if (err < 0) { + printk(UM_KERN_ERR "slirp_tramp failed - errno = %d\n", -err); goto out; } pid = err; @@ -68,10 +69,10 @@ static int slirp_open(void *data) pri->slip.esc = 0; pri->pid = err; - return(fds[0]); + return fds[0]; out: - os_close_file(fds[0]); - os_close_file(fds[1]); + close(fds[0]); + close(fds[1]); return err; } @@ -80,31 +81,33 @@ static void slirp_close(int fd, void *data) struct slirp_data *pri = data; int status,err; - os_close_file(fd); - os_close_file(pri->slave); + close(fd); + close(pri->slave); pri->slave = -1; - if(pri->pid<1) { - printk("slirp_close: no child process to shut down\n"); + if (pri->pid<1) { + printk(UM_KERN_ERR "slirp_close: no child process to shut " + "down\n"); return; } #if 0 - if(kill(pri->pid, SIGHUP)<0) { - printk("slirp_close: sending hangup to %d failed (%d)\n", - pri->pid, errno); + if (kill(pri->pid, SIGHUP)<0) { + printk(UM_KERN_ERR "slirp_close: sending hangup to %d failed " + "(%d)\n", pri->pid, errno); } #endif CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG)); - if(err < 0) { - printk("slirp_close: waitpid returned %d\n", errno); + if (err < 0) { + printk(UM_KERN_ERR "slirp_close: waitpid returned %d\n", errno); return; } - if(err == 0) { - printk("slirp_close: process %d has not exited\n", pri->pid); + if (err == 0) { + printk(UM_KERN_ERR "slirp_close: process %d has not exited\n", + pri->pid); return; } @@ -121,18 +124,13 @@ int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri) return slip_proto_write(fd, buf, len, &pri->slip); } -static int slirp_set_mtu(int mtu, void *data) -{ - return(mtu); -} - const struct net_user_info slirp_user_info = { .init = slirp_user_init, .open = slirp_open, .close = slirp_close, .remove = NULL, - .set_mtu = slirp_set_mtu, .add_address = NULL, .delete_address = NULL, - .max_packet = BUF_SIZE + .mtu = BUF_SIZE, + .max_packet = BUF_SIZE, }; diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c index a9f87e19c5bf..c930fedc5172 100644 --- a/arch/um/drivers/tty.c +++ b/arch/um/drivers/tty.c @@ -1,16 +1,16 @@ /* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) * Licensed under the GPL */ -#include <stdio.h> -#include <termios.h> #include <errno.h> -#include <unistd.h> +#include <fcntl.h> +#include <termios.h> #include "chan_user.h" -#include "user.h" +#include "kern_constants.h" #include "os.h" #include "um_malloc.h" +#include "user.h" struct tty_chan { char *dev; @@ -22,15 +22,15 @@ static void *tty_chan_init(char *str, int device, const struct chan_opts *opts) { struct tty_chan *data; - if(*str != ':'){ - printk("tty_init : channel type 'tty' must specify " + if (*str != ':') { + printk(UM_KERN_ERR "tty_init : channel type 'tty' must specify " "a device\n"); return NULL; } str++; data = kmalloc(sizeof(*data), UM_GFP_KERNEL); - if(data == NULL) + if (data == NULL) return NULL; *data = ((struct tty_chan) { .dev = str, .raw = opts->raw }); @@ -42,19 +42,26 @@ static int tty_open(int input, int output, int primary, void *d, char **dev_out) { struct tty_chan *data = d; - int fd, err; + int fd, err, mode = 0; + + if (input && output) + mode = O_RDWR; + else if (input) + mode = O_RDONLY; + else if (output) + mode = O_WRONLY; - fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0); - if(fd < 0) - return fd; + fd = open(data->dev, mode); + if (fd < 0) + return -errno; - if(data->raw){ + if (data->raw) { CATCH_EINTR(err = tcgetattr(fd, &data->tt)); - if(err) + if (err) return err; err = raw(fd); - if(err) + if (err) return err; } diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 0eabe73c964d..25b248a02507 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -615,7 +615,7 @@ static int ubd_open_dev(struct ubd *ubd_dev) blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long)); err = -ENOMEM; - ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len); + ubd_dev->cow.bitmap = vmalloc(ubd_dev->cow.bitmap_len); if(ubd_dev->cow.bitmap == NULL){ printk(KERN_ERR "Failed to vmalloc COW bitmap\n"); goto error; diff --git a/arch/um/drivers/vde.h b/arch/um/drivers/vde.h new file mode 100644 index 000000000000..fc3a05902ba1 --- /dev/null +++ b/arch/um/drivers/vde.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org). + * Licensed under the GPL. + */ + +#ifndef __UM_VDE_H__ +#define __UM_VDE_H__ + +struct vde_data { + char *vde_switch; + char *descr; + void *args; + void *conn; + void *dev; +}; + +struct vde_init { + char *vde_switch; + char *descr; + int port; + char *group; + int mode; +}; + +extern const struct net_user_info vde_user_info; + +extern void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init); + +extern int vde_user_read(void *conn, void *buf, int len); +extern int vde_user_write(void *conn, void *buf, int len); + +#endif diff --git a/arch/um/drivers/vde_kern.c b/arch/um/drivers/vde_kern.c new file mode 100644 index 000000000000..add7e722defb --- /dev/null +++ b/arch/um/drivers/vde_kern.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org). + * Licensed under the GPL. + * + * Transport usage: + * ethN=vde,<vde_switch>,<mac addr>,<port>,<group>,<mode>,<description> + * + */ + +#include "linux/init.h" +#include <linux/netdevice.h> +#include "net_kern.h" +#include "net_user.h" +#include "vde.h" + +static void vde_init(struct net_device *dev, void *data) +{ + struct vde_init *init = data; + struct uml_net_private *pri; + struct vde_data *vpri; + + pri = dev->priv; + vpri = (struct vde_data *) pri->user; + + vpri->vde_switch = init->vde_switch; + vpri->descr = init->descr ? init->descr : "UML vde_transport"; + vpri->args = NULL; + vpri->conn = NULL; + vpri->dev = dev; + + printk("vde backend - %s, ", vpri->vde_switch ? + vpri->vde_switch : "(default socket)"); + + vde_init_libstuff(vpri, init); + + printk("\n"); +} + +static int vde_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) +{ + struct vde_data *pri = (struct vde_data *) &lp->user; + + if (pri->conn != NULL) + return vde_user_read(pri->conn, skb_mac_header(skb), + skb->dev->mtu + ETH_HEADER_OTHER); + + printk(KERN_ERR "vde_read - we have no VDECONN to read from"); + return -EBADF; +} + +static int vde_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) +{ + struct vde_data *pri = (struct vde_data *) &lp->user; + + if (pri->conn != NULL) + return vde_user_write((void *)pri->conn, skb->data, + skb->len); + + printk(KERN_ERR "vde_write - we have no VDECONN to write to"); + return -EBADF; +} + +static const struct net_kern_info vde_kern_info = { + .init = vde_init, + .protocol = eth_protocol, + .read = vde_read, + .write = vde_write, +}; + +static int vde_setup(char *str, char **mac_out, void *data) +{ + struct vde_init *init = data; + char *remain, *port_str = NULL, *mode_str = NULL, *last; + + *init = ((struct vde_init) + { .vde_switch = NULL, + .descr = NULL, + .port = 0, + .group = NULL, + .mode = 0 }); + + remain = split_if_spec(str, &init->vde_switch, mac_out, &port_str, + &init->group, &mode_str, &init->descr, NULL); + + if (remain != NULL) + printk(KERN_WARNING "vde_setup - Ignoring extra data :" + "'%s'\n", remain); + + if (port_str != NULL) { + init->port = simple_strtoul(port_str, &last, 10); + if ((*last != '\0') || (last == port_str)) { + printk(KERN_ERR "vde_setup - Bad port : '%s'\n", + port_str); + return 0; + } + } + + if (mode_str != NULL) { + init->mode = simple_strtoul(mode_str, &last, 8); + if ((*last != '\0') || (last == mode_str)) { + printk(KERN_ERR "vde_setup - Bad mode : '%s'\n", + mode_str); + return 0; + } + } + + printk(KERN_INFO "Configured vde device: %s\n", init->vde_switch ? + init->vde_switch : "(default socket)"); + + return 1; +} + +static struct transport vde_transport = { + .list = LIST_HEAD_INIT(vde_transport.list), + .name = "vde", + .setup = vde_setup, + .user = &vde_user_info, + .kern = &vde_kern_info, + .private_size = sizeof(struct vde_data), + .setup_size = sizeof(struct vde_init), +}; + +static int register_vde(void) +{ + register_transport(&vde_transport); + return 0; +} + +late_initcall(register_vde); diff --git a/arch/um/drivers/vde_user.c b/arch/um/drivers/vde_user.c new file mode 100644 index 000000000000..d9941fe5f931 --- /dev/null +++ b/arch/um/drivers/vde_user.c @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org). + * Licensed under the GPL. + */ + +#include <stddef.h> +#include <errno.h> +#include <libvdeplug.h> +#include "kern_constants.h" +#include "net_user.h" +#include "um_malloc.h" +#include "user.h" +#include "vde.h" + +static int vde_user_init(void *data, void *dev) +{ + struct vde_data *pri = data; + VDECONN *conn = NULL; + int err = -EINVAL; + + pri->dev = dev; + + conn = vde_open(pri->vde_switch, pri->descr, pri->args); + + if (conn == NULL) { + err = -errno; + printk(UM_KERN_ERR "vde_user_init: vde_open failed, " + "errno = %d\n", errno); + return err; + } + + printk(UM_KERN_INFO "vde backend - connection opened\n"); + + pri->conn = conn; + + return 0; +} + +static int vde_user_open(void *data) +{ + struct vde_data *pri = data; + + if (pri->conn != NULL) + return vde_datafd(pri->conn); + + printk(UM_KERN_WARNING "vde_open - we have no VDECONN to open"); + return -EINVAL; +} + +static void vde_remove(void *data) +{ + struct vde_data *pri = data; + + if (pri->conn != NULL) { + printk(UM_KERN_INFO "vde backend - closing connection\n"); + vde_close(pri->conn); + pri->conn = NULL; + kfree(pri->args); + pri->args = NULL; + return; + } + + printk(UM_KERN_WARNING "vde_remove - we have no VDECONN to remove"); +} + +const struct net_user_info vde_user_info = { + .init = vde_user_init, + .open = vde_user_open, + .close = NULL, + .remove = vde_remove, + .add_address = NULL, + .delete_address = NULL, + .mtu = ETH_MAX_PACKET, + .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER, +}; + +void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init) +{ + struct vde_open_args *args; + + vpri->args = kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL); + if (vpri->args == NULL) { + printk(UM_KERN_ERR "vde_init_libstuff - vde_open_args" + "allocation failed"); + return; + } + + args = vpri->args; + + args->port = init->port; + args->group = init->group; + args->mode = init->mode ? init->mode : 0700; + + args->port ? printk(UM_KERN_INFO "port %d", args->port) : + printk(UM_KERN_INFO "undefined port"); +} + +int vde_user_read(void *conn, void *buf, int len) +{ + VDECONN *vconn = conn; + int rv; + + if (vconn == NULL) + return 0; + + rv = vde_recv(vconn, buf, len, 0); + if (rv < 0) { + if (errno == EAGAIN) + return 0; + return -errno; + } + else if (rv == 0) + return -ENOTCONN; + + return rv; +} + +int vde_user_write(void *conn, void *buf, int len) +{ + VDECONN *vconn = conn; + + if (vconn == NULL) + return 0; + + return vde_send(vconn, buf, len, 0); +} + diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index fd817e541543..8a1c18a9b240 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -1,20 +1,21 @@ -/* +/* * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <stdlib.h> +#include <stddef.h> #include <stdio.h> +#include <stdlib.h> #include <unistd.h> -#include <string.h> #include <errno.h> +#include <string.h> #include <termios.h> #include "chan_user.h" +#include "kern_constants.h" #include "os.h" -#include "init.h" +#include "um_malloc.h" #include "user.h" #include "xterm.h" -#include "kern_constants.h" struct xterm_chan { int pid; @@ -29,7 +30,7 @@ static void *xterm_init(char *str, int device, const struct chan_opts *opts) { struct xterm_chan *data; - data = malloc(sizeof(*data)); + data = kmalloc(sizeof(*data), UM_GFP_KERNEL); if (data == NULL) return NULL; *data = ((struct xterm_chan) { .pid = -1, @@ -95,8 +96,10 @@ static int xterm_open(int input, int output, int primary, void *d, 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. */ + /* + * 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") == NULL) { printk(UM_KERN_ERR "xterm_open: $DISPLAY not set.\n"); return -ENODEV; @@ -195,7 +198,7 @@ static int xterm_open(int input, int output, int primary, void *d, static void xterm_close(int fd, void *d) { struct xterm_chan *data = d; - + if (data->pid != -1) os_kill_process(data->pid, 1); data->pid = -1; @@ -207,11 +210,6 @@ static void xterm_close(int fd, void *d) os_close_file(fd); } -static void xterm_free(void *d) -{ - free(d); -} - const struct chan_ops xterm_ops = { .type = "xterm", .init = xterm_init, @@ -221,6 +219,6 @@ const struct chan_ops xterm_ops = { .write = generic_write, .console_write = generic_console_write, .window_size = generic_window_size, - .free = xterm_free, + .free = generic_free, .winch = 1, }; diff --git a/arch/um/include/arch.h b/arch/um/include/arch.h index 10ad52daa8c5..49c601ff2bac 100644 --- a/arch/um/include/arch.h +++ b/arch/um/include/arch.h @@ -9,7 +9,7 @@ #include "sysdep/ptrace.h" extern void arch_check_bugs(void); -extern int arch_fixup(unsigned long address, union uml_pt_regs *regs); -extern int arch_handle_signal(int sig, union uml_pt_regs *regs); +extern int arch_fixup(unsigned long address, struct uml_pt_regs *regs); +extern int arch_handle_signal(int sig, struct uml_pt_regs *regs); #endif diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h index fccf187bf4e1..a5cdf953e04a 100644 --- a/arch/um/include/as-layout.h +++ b/arch/um/include/as-layout.h @@ -6,6 +6,28 @@ #ifndef __START_H__ #define __START_H__ +#include "uml-config.h" +#include "kern_constants.h" + +/* + * Assembly doesn't want any casting, but C does, so define these + * without casts here, and define new symbols with casts inside the C + * section. + */ +#define ASM_STUB_CODE (UML_CONFIG_TOP_ADDR - 2 * UM_KERN_PAGE_SIZE) +#define ASM_STUB_DATA (UML_CONFIG_TOP_ADDR - UM_KERN_PAGE_SIZE) +#define ASM_STUB_START ASM_STUB_CODE + +/* + * This file is included by the assembly stubs, which just want the + * definitions above. + */ +#ifndef __ASSEMBLY__ + +#define STUB_CODE ((unsigned long) ASM_STUB_CODE) +#define STUB_DATA ((unsigned long) ASM_STUB_DATA) +#define STUB_START ((unsigned long) ASM_STUB_START) + #include "sysdep/ptrace.h" struct cpu_task { @@ -28,8 +50,9 @@ extern unsigned long _unprotected_end; extern unsigned long brk_start; extern int linux_main(int argc, char **argv); -extern void set_cmdline(char *cmd); -extern void (*sig_info[])(int, union uml_pt_regs *); +extern void (*sig_info[])(int, struct uml_pt_regs *); + +#endif #endif diff --git a/arch/um/include/choose-mode.h b/arch/um/include/choose-mode.h deleted file mode 100644 index b87b36a87d91..000000000000 --- a/arch/um/include/choose-mode.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __CHOOSE_MODE_H__ -#define __CHOOSE_MODE_H__ - -#include "uml-config.h" - -#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS) -#define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas)) - -extern int mode_tt; -static inline void *__choose_mode(void *tt, void *skas) { - return mode_tt ? tt : skas; -} - -#define __CHOOSE_MODE(tt, skas) (*( (typeof(tt) *) __choose_mode(&(tt), &(skas)))) - -#elif defined(UML_CONFIG_MODE_SKAS) -#define CHOOSE_MODE(tt, skas) (skas) - -#elif defined(UML_CONFIG_MODE_TT) -#define CHOOSE_MODE(tt, skas) (tt) - -#else -#error CONFIG_MODE_SKAS and CONFIG_MODE_TT are both disabled -#endif - -#define CHOOSE_MODE_PROC(tt, skas, args...) \ - CHOOSE_MODE(tt(args), skas(args)) - -#ifndef __CHOOSE_MODE -#define __CHOOSE_MODE(tt, skas) CHOOSE_MODE(tt, skas) -#endif - -#endif diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h index 6eee343e53eb..0edab695ed4e 100644 --- a/arch/um/include/common-offsets.h +++ b/arch/um/include/common-offsets.h @@ -1,15 +1,13 @@ /* for use by sys-$SUBARCH/kernel-offsets.c */ DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); -#ifdef CONFIG_MODE_TT -OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); -#endif OFFSET(HOST_TASK_REGS, task_struct, thread.regs); OFFSET(HOST_TASK_PID, task_struct, pid); DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK); +DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT); DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); DEFINE_STR(UM_KERN_EMERG, KERN_EMERG); @@ -34,3 +32,9 @@ DEFINE(UM_GFP_ATOMIC, GFP_ATOMIC); DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); DEFINE(UM_THREAD_SIZE, THREAD_SIZE); + +DEFINE(UM_HZ, HZ); + +DEFINE(UM_USEC_PER_SEC, USEC_PER_SEC); +DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); +DEFINE(UM_NSEC_PER_USEC, NSEC_PER_USEC); diff --git a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h index 15d311b9be9e..884a9c17eea0 100644 --- a/arch/um/include/irq_user.h +++ b/arch/um/include/irq_user.h @@ -1,12 +1,12 @@ /* - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ #ifndef __IRQ_USER_H__ #define __IRQ_USER_H__ -#include "uml-config.h" +#include "sysdep/ptrace.h" struct irq_fd { struct irq_fd *next; @@ -21,7 +21,7 @@ struct irq_fd { enum { IRQ_READ, IRQ_WRITE }; -extern void sigio_handler(int sig, union uml_pt_regs *regs); +extern void sigio_handler(int sig, struct uml_pt_regs *regs); extern int activate_fd(int irq, int fd, int type, void *dev_id); extern void free_irq_by_irq_and_dev(unsigned int irq, void *dev_id); extern void free_irq_by_fd(int fd); @@ -30,8 +30,4 @@ extern void deactivate_fd(int fd, int irqnum); extern int deactivate_all_fds(void); extern int activate_ipi(int fd, int pid); -#ifdef CONFIG_MODE_TT -extern void forward_interrupts(int pid); -#endif - #endif diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 6c2be26f1d7d..74ce8e5370a6 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -8,9 +8,8 @@ #include "sysdep/ptrace.h" #include "sysdep/faultinfo.h" -#include "uml-config.h" -typedef void (*kern_hndl)(int, union uml_pt_regs *); +typedef void (*kern_hndl)(int, struct uml_pt_regs *); struct kern_handlers { kern_hndl relay_signal; @@ -34,9 +33,6 @@ extern int nsyscalls; UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1) extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg); -#ifdef UML_CONFIG_MODE_TT -extern unsigned long stack_sp(unsigned long page); -#endif extern int kernel_thread_proc(void *data); extern void syscall_segv(int sig); extern int current_pid(void); @@ -44,7 +40,7 @@ extern unsigned long alloc_stack(int order, int atomic); extern int do_signal(void); extern int is_stack_fault(unsigned long sp); extern unsigned long segv(struct faultinfo fi, unsigned long ip, - int is_user, union uml_pt_regs *regs); + int is_user, struct uml_pt_regs *regs); extern int handle_page_fault(unsigned long address, unsigned long ip, int is_write, int is_user, int *code_out); extern void syscall_ready(void); @@ -57,7 +53,7 @@ extern int need_finish_fork(void); extern void free_stack(unsigned long stack, int order); extern void add_input_request(int op, void (*proc)(int), void *arg); extern char *current_cmd(void); -extern void timer_handler(int sig, union uml_pt_regs *regs); +extern void timer_handler(int sig, struct uml_pt_regs *regs); extern int set_signals(int enable); extern int pid_to_processor_id(int pid); extern void deliver_signals(void *t); @@ -67,9 +63,8 @@ extern void finish_fork(void); extern void paging_init(void); extern void init_flush_vm(void); extern void *syscall_sp(void *t); -extern void syscall_trace(union uml_pt_regs *regs, int entryexit); -extern int hz(void); -extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs); +extern void syscall_trace(struct uml_pt_regs *regs, int entryexit); +extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs); extern void interrupt_end(void); extern void initial_thread_cb(void (*proc)(void *), void *arg); extern int debugger_signal(int status, int pid); @@ -79,10 +74,9 @@ extern int init_ptrace_proxy(int idle_pid, int startup, int stop); extern int init_parent_proxy(int pid); extern int singlestepping(void *t); extern void check_stack_overflow(void *ptr); -extern void relay_signal(int sig, union uml_pt_regs *regs); +extern void relay_signal(int sig, struct uml_pt_regs *regs); extern int user_context(unsigned long sp); -extern void timer_irq(union uml_pt_regs *regs); -extern void unprotect_stack(unsigned long stack); +extern void timer_irq(struct uml_pt_regs *regs); extern void do_uml_exitcalls(void); extern int attach_debugger(int idle_pid, int pid, int stop); extern int config_gdb(char *str); @@ -113,11 +107,9 @@ extern void time_init_kern(void); /* Are we disallowed to sleep? Used to choose between GFP_KERNEL and GFP_ATOMIC. */ extern int __cant_sleep(void); -extern void sigio_handler(int sig, union uml_pt_regs *regs); - -extern void copy_sc(union uml_pt_regs *regs, void *from); - +extern void sigio_handler(int sig, struct uml_pt_regs *regs); +extern void copy_sc(struct uml_pt_regs *regs, void *from); extern unsigned long to_irq_stack(unsigned long *mask_out); unsigned long from_irq_stack(int nested); - +extern int start_uml(void); #endif diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h index b282839c1625..c139ae1d6826 100644 --- a/arch/um/include/mconsole.h +++ b/arch/um/include/mconsole.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -63,7 +63,7 @@ struct mc_request struct mconsole_request request; struct mconsole_command *cmd; - union uml_pt_regs regs; + struct uml_pt_regs regs; }; extern char mconsole_socket_name[]; @@ -96,14 +96,3 @@ extern void lock_notify(void); extern void unlock_notify(void); #endif - -/* - * 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/mem.h b/arch/um/include/mem.h index e8ff0d8fa610..5cd40e99e8d5 100644 --- a/arch/um/include/mem.h +++ b/arch/um/include/mem.h @@ -1,18 +1,12 @@ /* - * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ #ifndef __MEM_H__ #define __MEM_H__ -#include "linux/types.h" - -extern int phys_mapping(unsigned long phys, __u64 *offset_out); -extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w); -extern int is_remapped(void *virt); -extern int physmem_remove_mapping(void *virt); -extern void physmem_forget_descriptor(int fd); +extern int phys_mapping(unsigned long phys, unsigned long long *offset_out); extern unsigned long uml_physmem; static inline unsigned long to_phys(void *virt) @@ -26,14 +20,3 @@ static inline void *to_virt(unsigned long phys) } #endif - -/* - * 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/mode.h b/arch/um/include/mode.h deleted file mode 100644 index 786cf563eb05..000000000000 --- a/arch/um/include/mode.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __MODE_H__ -#define __MODE_H__ - -#include "uml-config.h" - -#ifdef UML_CONFIG_MODE_TT -#include "mode-tt.h" -#endif - -#ifdef UML_CONFIG_MODE_SKAS -#include "mode-skas.h" -#endif - -#endif - -/* - * 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/mode_kern.h b/arch/um/include/mode_kern.h deleted file mode 100644 index 88e5e77bf517..000000000000 --- a/arch/um/include/mode_kern.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __MODE_KERN_H__ -#define __MODE_KERN_H__ - -#ifdef CONFIG_MODE_TT -#include "mode_kern_tt.h" -#endif - -#ifdef CONFIG_MODE_SKAS -#include "mode_kern_skas.h" -#endif - -#endif diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h index 9237056b9103..d843c7924a7c 100644 --- a/arch/um/include/net_kern.h +++ b/arch/um/include/net_kern.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -30,24 +30,24 @@ struct uml_net_private { struct work_struct work; int fd; unsigned char mac[ETH_ALEN]; + int max_packet; unsigned short (*protocol)(struct sk_buff *); int (*open)(void *); void (*close)(int, void *); void (*remove)(void *); - int (*read)(int, struct sk_buff **skb, struct uml_net_private *); - int (*write)(int, struct sk_buff **skb, struct uml_net_private *); + int (*read)(int, struct sk_buff *skb, struct uml_net_private *); + int (*write)(int, struct sk_buff *skb, struct uml_net_private *); void (*add_address)(unsigned char *, unsigned char *, void *); void (*delete_address)(unsigned char *, unsigned char *, void *); - int (*set_mtu)(int mtu, void *); char user[0]; }; struct net_kern_info { void (*init)(struct net_device *, void *); unsigned short (*protocol)(struct sk_buff *); - int (*read)(int, struct sk_buff **skb, struct uml_net_private *); - int (*write)(int, struct sk_buff **skb, struct uml_net_private *); + int (*read)(int, struct sk_buff *skb, struct uml_net_private *); + int (*write)(int, struct sk_buff *skb, struct uml_net_private *); }; struct transport { @@ -62,7 +62,6 @@ struct transport { extern struct net_device *ether_init(int); extern unsigned short ether_protocol(struct sk_buff *); -extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra); extern int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out, char **gate_addr); extern void register_transport(struct transport *new); diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h index cfe7c50634b9..63bee158cd8e 100644 --- a/arch/um/include/net_user.h +++ b/arch/um/include/net_user.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -18,10 +18,10 @@ struct net_user_info { int (*open)(void *); void (*close)(int, void *); void (*remove)(void *); - int (*set_mtu)(int mtu, void *); void (*add_address)(unsigned char *, unsigned char *, void *); void (*delete_address)(unsigned char *, unsigned char *, void *); int max_packet; + int mtu; }; extern void ether_user_init(void *data, void *dev); diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 930b261ea483..fbf0a87c6eaa 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -1,20 +1,18 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ #ifndef __OS_H__ #define __OS_H__ -#include "uml-config.h" -#include "asm/types.h" -#include "../os/include/file.h" -#include "sysdep/ptrace.h" -#include "kern_util.h" -#include "skas/mm_id.h" +#include <stdarg.h> #include "irq_user.h" +#include "kern_util.h" +#include "longjmp.h" +#include "mm_id.h" #include "sysdep/tls.h" -#include "sysdep/archsetjmp.h" +#include "../os/include/file.h" #define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) @@ -130,18 +128,15 @@ static inline struct openflags of_cloexec(struct openflags flags) extern int os_stat_file(const char *file_name, struct uml_stat *buf); extern int os_stat_fd(const int fd, struct uml_stat *buf); extern int os_access(const char *file, int mode); -extern void os_print_error(int error, const char* str); extern int os_get_exec_close(int fd, int *close_on_exec); -extern int os_set_exec_close(int fd, int close_on_exec); +extern int os_set_exec_close(int fd); extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg); -extern int os_window_size(int fd, int *rows, int *cols); -extern int os_new_tty_pgrp(int fd, int pid); extern int os_get_ifname(int fd, char *namebuf); extern int os_set_slip(int fd); extern int os_set_owner(int fd, int pid); extern int os_mode_fd(int fd, int mode); -extern int os_seek_file(int fd, __u64 offset); +extern int os_seek_file(int fd, unsigned long long offset); extern int os_open_file(char *file, struct openflags flags, int mode); extern int os_read_file(int fd, void *buf, int len); extern int os_write_file(int fd, const void *buf, int count); @@ -179,11 +174,7 @@ extern void check_host_supports_tls(int *supports_tls, int *tls_min); /* Make sure they are clear when running in TT mode. Required by * SEGV_MAYBE_FIXABLE */ -#ifdef UML_CONFIG_MODE_SKAS #define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0) -#else -#define clear_can_do_skas() do {} while (0) -#endif /* mem.c */ extern int create_mem_file(unsigned long long len); @@ -194,20 +185,13 @@ extern int os_process_parent(int pid); extern void os_stop_process(int pid); extern void os_kill_process(int pid, int reap_child); extern void os_kill_ptraced_process(int pid, int reap_child); -#ifdef UML_CONFIG_MODE_TT -extern void os_usr1_process(int pid); -#endif extern long os_ptrace_ldt(long pid, long addr, long data); extern int os_getpid(void); extern int os_getpgrp(void); -#ifdef UML_CONFIG_MODE_TT -extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); -extern void stop(void); -#endif extern void init_new_thread_signals(void); -extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); +extern int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr); extern int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, int r, int w, int x); @@ -218,21 +202,9 @@ extern int os_drop_memory(void *addr, int length); extern int can_drop_memory(void); extern void os_flush_stdout(void); -/* tt.c - * for tt mode only (will be deleted in future...) - */ -extern void forward_ipi(int fd, int pid); -extern void kill_child_dead(int pid); -extern int wait_for_stop(int pid, int sig, int cont_type, void *relay); -extern int protect_memory(unsigned long addr, unsigned long len, - int r, int w, int x, int must_succeed); -extern void forward_pending_sigio(int target); -extern int start_fork_tramp(void *arg, unsigned long temp_stack, - int clone_flags, int (*tramp)(void *)); - /* uaccess.c */ extern unsigned long __do_user_copy(void *to, const void *from, int n, - void **fault_addr, void **fault_catcher, + void **fault_addr, jmp_buf **fault_catcher, void (*op)(void *to, const void *from, int n), int *faulted_out); @@ -255,6 +227,7 @@ extern int set_umid(char *name); extern char *get_umid(void); /* signal.c */ +extern void timer_init(void); extern void set_sigstack(void *sig_stack, int size); extern void remove_sigstack(void); extern void set_handler(int sig, void (*handler)(int), int flags, ...); @@ -266,7 +239,6 @@ extern int set_signals(int enable); /* trap.c */ extern void os_fill_handlinfo(struct kern_handlers h); -extern void do_longjmp(void *p, int val); /* util.c */ extern void stack_protections(unsigned long address); @@ -277,17 +249,12 @@ extern int setjmp_wrapper(void (*proc)(void *, void *), ...); extern void os_dump_core(void); /* time.c */ -#define BILLION (1000 * 1000 * 1000) - -extern void switch_timers(int to_real); -extern void idle_sleep(int secs); -extern int set_interval(int is_virtual); -#ifdef CONFIG_MODE_TT -extern void enable_timer(void); -#endif -extern void disable_timer(void); +extern void idle_sleep(unsigned long long nsecs); +extern int set_interval(void); +extern int timer_one_shot(int ticks); +extern long long disable_timer(void); extern void uml_idle_timer(void); -extern unsigned long long os_nsecs(void); +extern long long os_nsecs(void); /* skas/mem.c */ extern long run_syscall_stub(struct mm_id * mm_idp, @@ -308,7 +275,9 @@ extern int protect(struct mm_id * mm_idp, unsigned long addr, extern int is_skas_winch(int pid, int fd, void *data); extern int start_userspace(unsigned long stub_stack); extern int copy_context_skas0(unsigned long stack, int pid); -extern void userspace(union uml_pt_regs *regs); +extern void save_registers(int pid, struct uml_pt_regs *regs); +extern void restore_registers(int pid, struct uml_pt_regs *regs); +extern void userspace(struct uml_pt_regs *regs); extern void map_stub_pages(int fd, unsigned long code, unsigned long data, unsigned long stack); extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)); diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h index f845b3629a6d..0e27406a43a4 100644 --- a/arch/um/include/registers.h +++ b/arch/um/include/registers.h @@ -9,13 +9,15 @@ #include "sysdep/ptrace.h" #include "sysdep/archsetjmp.h" -extern void init_thread_registers(union uml_pt_regs *to); +extern void init_thread_registers(struct uml_pt_regs *to); extern int save_fp_registers(int pid, unsigned long *fp_regs); extern int restore_fp_registers(int pid, unsigned long *fp_regs); -extern void save_registers(int pid, union uml_pt_regs *regs); -extern void restore_registers(int pid, union uml_pt_regs *regs); +extern int save_fpx_registers(int pid, unsigned long *fp_regs); +extern int restore_fpx_registers(int pid, unsigned long *fp_regs); +extern void save_registers(int pid, struct uml_pt_regs *regs); +extern void restore_registers(int pid, struct uml_pt_regs *regs); extern void init_registers(int pid); -extern void get_safe_registers(unsigned long * regs, unsigned long * fp_regs); +extern void get_safe_registers(unsigned long *regs); extern unsigned long get_thread_reg(int reg, jmp_buf *buf); #endif diff --git a/arch/um/include/skas/mmu-skas.h b/arch/um/include/skas/mmu-skas.h deleted file mode 100644 index b26986c0c3d2..000000000000 --- a/arch/um/include/skas/mmu-skas.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SKAS_MMU_H -#define __SKAS_MMU_H - -#include "mm_id.h" -#include "asm/ldt.h" - -struct mmu_context_skas { - struct mm_id id; - unsigned long last_page_table; -#ifdef CONFIG_3_LEVEL_PGTABLES - unsigned long last_pmd; -#endif - uml_ldt_t ldt; -}; - -extern void switch_mm_skas(struct mm_id * mm_idp); - -#endif diff --git a/arch/um/include/skas/mode-skas.h b/arch/um/include/skas/mode-skas.h index 8bc6916bbbb1..e065feb000df 100644 --- a/arch/um/include/skas/mode-skas.h +++ b/arch/um/include/skas/mode-skas.h @@ -1,18 +1,11 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) * Licensed under the GPL */ #ifndef __MODE_SKAS_H__ #define __MODE_SKAS_H__ -#include <sysdep/ptrace.h> - -extern unsigned long exec_regs[]; -extern unsigned long exec_fp_regs[]; -extern unsigned long exec_fpx_regs[]; -extern int have_fpx_regs; - extern void kill_off_processes_skas(void); #endif diff --git a/arch/um/include/skas/mode_kern_skas.h b/arch/um/include/skas/mode_kern_skas.h deleted file mode 100644 index 8ee6285dfacc..000000000000 --- a/arch/um/include/skas/mode_kern_skas.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SKAS_MODE_KERN_H__ -#define __SKAS_MODE_KERN_H__ - -#include "linux/sched.h" -#include "asm/page.h" -#include "asm/ptrace.h" - -extern void flush_thread_skas(void); -extern void switch_to_skas(void *prev, void *next); -extern void start_thread_skas(struct pt_regs *regs, unsigned long eip, - unsigned long esp); -extern int copy_thread_skas(int nr, unsigned long clone_flags, - unsigned long sp, unsigned long stack_top, - struct task_struct *p, struct pt_regs *regs); -extern void release_thread_skas(struct task_struct *task); -extern void init_idle_skas(void); -extern void flush_tlb_kernel_range_skas(unsigned long start, - unsigned long end); -extern void flush_tlb_kernel_vm_skas(void); -extern void __flush_tlb_one_skas(unsigned long addr); -extern void flush_tlb_range_skas(struct vm_area_struct *vma, - unsigned long start, unsigned long end); -extern void flush_tlb_mm_skas(struct mm_struct *mm); -extern void force_flush_all_skas(void); -extern long execute_syscall_skas(void *r); -extern void before_mem_skas(unsigned long unused); -extern unsigned long set_task_sizes_skas(unsigned long *task_size_out); -extern int start_uml_skas(void); -extern int external_pid_skas(struct task_struct *task); -extern int thread_pid_skas(struct task_struct *task); -extern void flush_tlb_page_skas(struct vm_area_struct *vma, - unsigned long address); - -#define kmem_end_skas (host_task_size - 1024 * 1024) - -#endif diff --git a/arch/um/include/skas/skas.h b/arch/um/include/skas/skas.h index e88926b16072..b073f8a86bd3 100644 --- a/arch/um/include/skas/skas.h +++ b/arch/um/include/skas/skas.h @@ -1,12 +1,11 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ #ifndef __SKAS_H #define __SKAS_H -#include "mm_id.h" #include "sysdep/ptrace.h" extern int userspace_pid[]; @@ -15,7 +14,7 @@ extern int skas_needs_stub; extern int user_thread(unsigned long stack, int flags); extern void new_thread_handler(void); -extern void handle_syscall(union uml_pt_regs *regs); +extern void handle_syscall(struct uml_pt_regs *regs); extern int new_mm(unsigned long stack); extern void get_skas_faultinfo(int pid, struct faultinfo * fi); extern long execute_syscall_skas(void *r); diff --git a/arch/um/include/skas/uaccess-skas.h b/arch/um/include/skas/uaccess-skas.h deleted file mode 100644 index 224a75f4c025..000000000000 --- a/arch/um/include/skas/uaccess-skas.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SKAS_UACCESS_H -#define __SKAS_UACCESS_H - -#include "asm/errno.h" - -/* No SKAS-specific checking. */ -#define access_ok_skas(type, addr, size) 0 - -extern int copy_from_user_skas(void *to, const void __user *from, int n); -extern int copy_to_user_skas(void __user *to, const void *from, int n); -extern int strncpy_from_user_skas(char *dst, const char __user *src, int count); -extern int __clear_user_skas(void __user *mem, int len); -extern int clear_user_skas(void __user *mem, int len); -extern int strnlen_user_skas(const void __user *str, int len); - -#endif diff --git a/arch/um/include/sysdep-i386/kernel-offsets.h b/arch/um/include/sysdep-i386/kernel-offsets.h index 97ec9d894d75..5868526b5eef 100644 --- a/arch/um/include/sysdep-i386/kernel-offsets.h +++ b/arch/um/include/sysdep-i386/kernel-offsets.h @@ -17,6 +17,5 @@ void foo(void) { - OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs); #include <common-offsets.h> } diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h index 52b398bcafcf..11c08969d134 100644 --- a/arch/um/include/sysdep-i386/ptrace.h +++ b/arch/um/include/sysdep-i386/ptrace.h @@ -1,5 +1,5 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -9,17 +9,11 @@ #include "uml-config.h" #include "user_constants.h" #include "sysdep/faultinfo.h" -#include "choose-mode.h" #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) #define MAX_REG_OFFSET (UM_FRAME_SIZE) -#ifdef UML_CONFIG_PT_PROXY -extern void update_debugregs(int seq); -#else static inline void update_debugregs(int seq) {} -#endif - /* syscall emulation path in ptrace */ @@ -31,12 +25,6 @@ void set_using_sysemu(int value); int get_using_sysemu(void); extern int sysemu_supported; -#ifdef UML_CONFIG_MODE_TT -#include "sysdep/sc.h" -#endif - -#ifdef UML_CONFIG_MODE_SKAS - #include "skas_ptregs.h" #define REGS_IP(r) ((r)[HOST_IP]) @@ -60,70 +48,36 @@ extern int sysemu_supported; #define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) -#endif #ifndef PTRACE_SYSEMU_SINGLESTEP #define PTRACE_SYSEMU_SINGLESTEP 32 #endif -union uml_pt_regs { -#ifdef UML_CONFIG_MODE_TT - struct tt_regs { - long syscall; - void *sc; - struct faultinfo faultinfo; - } tt; -#endif -#ifdef UML_CONFIG_MODE_SKAS - struct skas_regs { - unsigned long regs[MAX_REG_NR]; - unsigned long fp[HOST_FP_SIZE]; - unsigned long xfp[HOST_XFP_SIZE]; - struct faultinfo faultinfo; - long syscall; - int is_user; - } skas; -#endif +struct uml_pt_regs { + unsigned long gp[MAX_REG_NR]; + struct faultinfo faultinfo; + long syscall; + int is_user; }; #define EMPTY_UML_PT_REGS { } -extern int mode_tt; - -#define UPT_SC(r) ((r)->tt.sc) -#define UPT_IP(r) \ - __CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs)) -#define UPT_SP(r) \ - __CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs)) -#define UPT_EFLAGS(r) \ - __CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs)) -#define UPT_EAX(r) \ - __CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs)) -#define UPT_EBX(r) \ - __CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs)) -#define UPT_ECX(r) \ - __CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs)) -#define UPT_EDX(r) \ - __CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs)) -#define UPT_ESI(r) \ - __CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs)) -#define UPT_EDI(r) \ - __CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs)) -#define UPT_EBP(r) \ - __CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs)) -#define UPT_ORIG_EAX(r) \ - __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall) -#define UPT_CS(r) \ - __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) -#define UPT_SS(r) \ - __CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs)) -#define UPT_DS(r) \ - __CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs)) -#define UPT_ES(r) \ - __CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs)) -#define UPT_FS(r) \ - __CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs)) -#define UPT_GS(r) \ - __CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs)) +#define UPT_IP(r) REGS_IP((r)->gp) +#define UPT_SP(r) REGS_SP((r)->gp) +#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp) +#define UPT_EAX(r) REGS_EAX((r)->gp) +#define UPT_EBX(r) REGS_EBX((r)->gp) +#define UPT_ECX(r) REGS_ECX((r)->gp) +#define UPT_EDX(r) REGS_EDX((r)->gp) +#define UPT_ESI(r) REGS_ESI((r)->gp) +#define UPT_EDI(r) REGS_EDI((r)->gp) +#define UPT_EBP(r) REGS_EBP((r)->gp) +#define UPT_ORIG_EAX(r) ((r)->syscall) +#define UPT_CS(r) REGS_CS((r)->gp) +#define UPT_SS(r) REGS_SS((r)->gp) +#define UPT_DS(r) REGS_DS((r)->gp) +#define UPT_ES(r) REGS_ES((r)->gp) +#define UPT_FS(r) REGS_FS((r)->gp) +#define UPT_GS(r) REGS_GS((r)->gp) #define UPT_SYSCALL_ARG1(r) UPT_EBX(r) #define UPT_SYSCALL_ARG2(r) UPT_ECX(r) @@ -134,20 +88,19 @@ extern int mode_tt; extern int user_context(unsigned long sp); -#define UPT_IS_USER(r) \ - CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user) +#define UPT_IS_USER(r) ((r)->is_user) struct syscall_args { unsigned long args[6]; }; #define SYSCALL_ARGS(r) ((struct syscall_args) \ - { .args = { UPT_SYSCALL_ARG1(r), \ - UPT_SYSCALL_ARG2(r), \ - UPT_SYSCALL_ARG3(r), \ - UPT_SYSCALL_ARG4(r), \ - UPT_SYSCALL_ARG5(r), \ - UPT_SYSCALL_ARG6(r) } } ) + { .args = { UPT_SYSCALL_ARG1(r), \ + UPT_SYSCALL_ARG2(r), \ + UPT_SYSCALL_ARG3(r), \ + UPT_SYSCALL_ARG4(r), \ + UPT_SYSCALL_ARG5(r), \ + UPT_SYSCALL_ARG6(r) } } ) #define UPT_REG(regs, reg) \ ({ unsigned long val; \ @@ -175,7 +128,6 @@ struct syscall_args { } \ val; \ }) - #define UPT_SET(regs, reg, val) \ do { \ @@ -204,29 +156,16 @@ struct syscall_args { } while (0) #define UPT_SET_SYSCALL_RETURN(r, res) \ - CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \ - REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res))) + REGS_SET_SYSCALL_RETURN((r)->regs, (res)) -#define UPT_RESTART_SYSCALL(r) \ - CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \ - REGS_RESTART_SYSCALL((r)->skas.regs)) +#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) #define UPT_ORIG_SYSCALL(r) UPT_EAX(r) #define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) #define UPT_SYSCALL_RET(r) UPT_EAX(r) -#define UPT_FAULTINFO(r) \ - CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo)) +#define UPT_FAULTINFO(r) (&(r)->faultinfo) -#endif +extern void arch_init_registers(int pid); -/* - * 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: - */ +#endif diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h index 23fd2644d7ed..67e77122aa45 100644 --- a/arch/um/include/sysdep-i386/sigcontext.h +++ b/arch/um/include/sysdep-i386/sigcontext.h @@ -1,19 +1,15 @@ /* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ #ifndef __SYS_SIGCONTEXT_I386_H #define __SYS_SIGCONTEXT_I386_H -#include "uml-config.h" -#include <sysdep/sc.h> +#include "sysdep/sc.h" #define IP_RESTART_SYSCALL(ip) ((ip) -= 2) -#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) -#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result) - #define GET_FAULTINFO_FROM_SC(fi,sc) \ { \ (fi).cr2 = SC_CR2(sc); \ @@ -21,32 +17,10 @@ (fi).trap_no = SC_TRAPNO(sc); \ } -/* ptrace expects that, at the start of a system call, %eax contains - * -ENOSYS, so this makes it so. - */ -#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) - /* This is Page Fault */ #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) /* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ -#ifdef UML_CONFIG_MODE_SKAS #define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) -#else -#define SEGV_MAYBE_FIXABLE(fi) 0 -#endif - -extern unsigned long *sc_sigmask(void *sc_ptr); -extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); #endif -/* - * 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/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h index 4fffae75ba53..8c097b87fca7 100644 --- a/arch/um/include/sysdep-i386/stub.h +++ b/arch/um/include/sysdep-i386/stub.h @@ -9,7 +9,7 @@ #include <sys/mman.h> #include <asm/ptrace.h> #include <asm/unistd.h> -#include <asm/page.h> +#include "as-layout.h" #include "stub-data.h" #include "kern_constants.h" #include "uml-config.h" @@ -19,7 +19,7 @@ extern void stub_clone_handler(void); #define STUB_SYSCALL_RET EAX #define STUB_MMAP_NR __NR_mmap2 -#define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT) +#define MMAP_OFFSET(o) ((o) >> UM_KERN_PAGE_SHIFT) static inline long stub_syscall0(long syscall) { @@ -90,12 +90,12 @@ static inline void remap_stack(int fd, unsigned long offset) { __asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;" "movl %7, %%ebx ; movl %%eax, (%%ebx)" - : : "g" (STUB_MMAP_NR), "b" (UML_CONFIG_STUB_DATA), - "c" (UM_KERN_PAGE_SIZE), + : : "g" (STUB_MMAP_NR), "b" (STUB_DATA), + "c" (UM_KERN_PAGE_SIZE), "d" (PROT_READ | PROT_WRITE), - "S" (MAP_FIXED | MAP_SHARED), "D" (fd), - "a" (offset), - "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err) + "S" (MAP_FIXED | MAP_SHARED), "D" (fd), + "a" (offset), + "i" (&((struct stub_data *) STUB_DATA)->err) : "memory"); } diff --git a/arch/um/include/sysdep-i386/thread.h b/arch/um/include/sysdep-i386/thread.h deleted file mode 100644 index 243fed44d780..000000000000 --- a/arch/um/include/sysdep-i386/thread.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __UM_THREAD_H -#define __UM_THREAD_H - -#include <kern_constants.h> - -#define TASK_DEBUGREGS(task) ((unsigned long *) &(((char *) (task))[HOST_TASK_DEBUGREGS])) -#ifdef UML_CONFIG_MODE_TT -#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID])) -#endif - -#endif diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h index 62403bd99661..9ea44d111f33 100644 --- a/arch/um/include/sysdep-x86_64/ptrace.h +++ b/arch/um/include/sysdep-x86_64/ptrace.h @@ -1,5 +1,6 @@ /* * Copyright 2003 PathScale, Inc. + * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * * Licensed under the GPL */ @@ -14,11 +15,6 @@ #define MAX_REG_OFFSET (UM_FRAME_SIZE) #define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) -#ifdef UML_CONFIG_MODE_TT -#include "sysdep/sc.h" -#endif - -#ifdef UML_CONFIG_MODE_SKAS #include "skas_ptregs.h" #define REGS_IP(r) ((r)[HOST_IP]) @@ -88,78 +84,51 @@ #define REGS_ERR(r) ((r)->fault_type) -#endif - -#include "choose-mode.h" - -/* XXX */ -union uml_pt_regs { -#ifdef UML_CONFIG_MODE_TT - struct tt_regs { - long syscall; - unsigned long orig_rax; - void *sc; - struct faultinfo faultinfo; - } tt; -#endif -#ifdef UML_CONFIG_MODE_SKAS - struct skas_regs { - unsigned long regs[MAX_REG_NR]; - unsigned long fp[HOST_FP_SIZE]; - struct faultinfo faultinfo; - long syscall; - int is_user; - } skas; -#endif +struct uml_pt_regs { + unsigned long gp[MAX_REG_NR]; + struct faultinfo faultinfo; + long syscall; + int is_user; }; #define EMPTY_UML_PT_REGS { } -/* XXX */ -extern int mode_tt; - -#define UPT_RBX(r) __CHOOSE_MODE(SC_RBX(UPT_SC(r)), REGS_RBX((r)->skas.regs)) -#define UPT_RCX(r) __CHOOSE_MODE(SC_RCX(UPT_SC(r)), REGS_RCX((r)->skas.regs)) -#define UPT_RDX(r) __CHOOSE_MODE(SC_RDX(UPT_SC(r)), REGS_RDX((r)->skas.regs)) -#define UPT_RSI(r) __CHOOSE_MODE(SC_RSI(UPT_SC(r)), REGS_RSI((r)->skas.regs)) -#define UPT_RDI(r) __CHOOSE_MODE(SC_RDI(UPT_SC(r)), REGS_RDI((r)->skas.regs)) -#define UPT_RBP(r) __CHOOSE_MODE(SC_RBP(UPT_SC(r)), REGS_RBP((r)->skas.regs)) -#define UPT_RAX(r) __CHOOSE_MODE(SC_RAX(UPT_SC(r)), REGS_RAX((r)->skas.regs)) -#define UPT_R8(r) __CHOOSE_MODE(SC_R8(UPT_SC(r)), REGS_R8((r)->skas.regs)) -#define UPT_R9(r) __CHOOSE_MODE(SC_R9(UPT_SC(r)), REGS_R9((r)->skas.regs)) -#define UPT_R10(r) __CHOOSE_MODE(SC_R10(UPT_SC(r)), REGS_R10((r)->skas.regs)) -#define UPT_R11(r) __CHOOSE_MODE(SC_R11(UPT_SC(r)), REGS_R11((r)->skas.regs)) -#define UPT_R12(r) __CHOOSE_MODE(SC_R12(UPT_SC(r)), REGS_R12((r)->skas.regs)) -#define UPT_R13(r) __CHOOSE_MODE(SC_R13(UPT_SC(r)), REGS_R13((r)->skas.regs)) -#define UPT_R14(r) __CHOOSE_MODE(SC_R14(UPT_SC(r)), REGS_R14((r)->skas.regs)) -#define UPT_R15(r) __CHOOSE_MODE(SC_R15(UPT_SC(r)), REGS_R15((r)->skas.regs)) -#define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) -#define UPT_FS_BASE(r) \ - __CHOOSE_MODE(SC_FS_BASE(UPT_SC(r)), REGS_FS_BASE((r)->skas.regs)) -#define UPT_FS(r) __CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs)) -#define UPT_GS_BASE(r) \ - __CHOOSE_MODE(SC_GS_BASE(UPT_SC(r)), REGS_GS_BASE((r)->skas.regs)) -#define UPT_GS(r) __CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs)) -#define UPT_DS(r) __CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs)) -#define UPT_ES(r) __CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs)) -#define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) -#define UPT_SS(r) __CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs)) -#define UPT_ORIG_RAX(r) \ - __CHOOSE_MODE((r)->tt.orig_rax, REGS_ORIG_RAX((r)->skas.regs)) - -#define UPT_IP(r) __CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs)) -#define UPT_SP(r) __CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs)) - -#define UPT_EFLAGS(r) \ - __CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs)) -#define UPT_SC(r) ((r)->tt.sc) -#define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall) +#define UPT_RBX(r) REGS_RBX((r)->gp) +#define UPT_RCX(r) REGS_RCX((r)->gp) +#define UPT_RDX(r) REGS_RDX((r)->gp) +#define UPT_RSI(r) REGS_RSI((r)->gp) +#define UPT_RDI(r) REGS_RDI((r)->gp) +#define UPT_RBP(r) REGS_RBP((r)->gp) +#define UPT_RAX(r) REGS_RAX((r)->gp) +#define UPT_R8(r) REGS_R8((r)->gp) +#define UPT_R9(r) REGS_R9((r)->gp) +#define UPT_R10(r) REGS_R10((r)->gp) +#define UPT_R11(r) REGS_R11((r)->gp) +#define UPT_R12(r) REGS_R12((r)->gp) +#define UPT_R13(r) REGS_R13((r)->gp) +#define UPT_R14(r) REGS_R14((r)->gp) +#define UPT_R15(r) REGS_R15((r)->gp) +#define UPT_CS(r) REGS_CS((r)->gp) +#define UPT_FS_BASE(r) REGS_FS_BASE((r)->gp) +#define UPT_FS(r) REGS_FS((r)->gp) +#define UPT_GS_BASE(r) REGS_GS_BASE((r)->gp) +#define UPT_GS(r) REGS_GS((r)->gp) +#define UPT_DS(r) REGS_DS((r)->gp) +#define UPT_ES(r) REGS_ES((r)->gp) +#define UPT_CS(r) REGS_CS((r)->gp) +#define UPT_SS(r) REGS_SS((r)->gp) +#define UPT_ORIG_RAX(r) REGS_ORIG_RAX((r)->gp) + +#define UPT_IP(r) REGS_IP((r)->gp) +#define UPT_SP(r) REGS_SP((r)->gp) + +#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp) +#define UPT_SYSCALL_NR(r) ((r)->syscall) #define UPT_SYSCALL_RET(r) UPT_RAX(r) extern int user_context(unsigned long sp); -#define UPT_IS_USER(r) \ - CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user) +#define UPT_IS_USER(r) ((r)->is_user) #define UPT_SYSCALL_ARG1(r) UPT_RDI(r) #define UPT_SYSCALL_ARG2(r) UPT_RSI(r) @@ -173,101 +142,99 @@ struct syscall_args { }; #define SYSCALL_ARGS(r) ((struct syscall_args) \ - { .args = { UPT_SYSCALL_ARG1(r), \ - UPT_SYSCALL_ARG2(r), \ - UPT_SYSCALL_ARG3(r), \ - UPT_SYSCALL_ARG4(r), \ - UPT_SYSCALL_ARG5(r), \ - UPT_SYSCALL_ARG6(r) } } ) + { .args = { UPT_SYSCALL_ARG1(r), \ + UPT_SYSCALL_ARG2(r), \ + UPT_SYSCALL_ARG3(r), \ + UPT_SYSCALL_ARG4(r), \ + UPT_SYSCALL_ARG5(r), \ + UPT_SYSCALL_ARG6(r) } } ) #define UPT_REG(regs, reg) \ - ({ unsigned long val; \ - switch(reg){ \ - case R8: val = UPT_R8(regs); break; \ - case R9: val = UPT_R9(regs); break; \ - case R10: val = UPT_R10(regs); break; \ - case R11: val = UPT_R11(regs); break; \ - case R12: val = UPT_R12(regs); break; \ - case R13: val = UPT_R13(regs); break; \ - case R14: val = UPT_R14(regs); break; \ - case R15: val = UPT_R15(regs); break; \ - case RIP: val = UPT_IP(regs); break; \ - case RSP: val = UPT_SP(regs); break; \ - case RAX: val = UPT_RAX(regs); break; \ - case RBX: val = UPT_RBX(regs); break; \ - case RCX: val = UPT_RCX(regs); break; \ - case RDX: val = UPT_RDX(regs); break; \ - case RSI: val = UPT_RSI(regs); break; \ - case RDI: val = UPT_RDI(regs); break; \ - case RBP: val = UPT_RBP(regs); break; \ - case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \ - case CS: val = UPT_CS(regs); break; \ - case SS: val = UPT_SS(regs); break; \ - case FS_BASE: val = UPT_FS_BASE(regs); break; \ - case GS_BASE: val = UPT_GS_BASE(regs); break; \ - case DS: val = UPT_DS(regs); break; \ - case ES: val = UPT_ES(regs); break; \ - case FS : val = UPT_FS (regs); break; \ - case GS: val = UPT_GS(regs); break; \ - case EFLAGS: val = UPT_EFLAGS(regs); break; \ - default : \ - panic("Bad register in UPT_REG : %d\n", reg); \ - val = -1; \ - } \ - val; \ - }) + ({ unsigned long val; \ + switch(reg){ \ + case R8: val = UPT_R8(regs); break; \ + case R9: val = UPT_R9(regs); break; \ + case R10: val = UPT_R10(regs); break; \ + case R11: val = UPT_R11(regs); break; \ + case R12: val = UPT_R12(regs); break; \ + case R13: val = UPT_R13(regs); break; \ + case R14: val = UPT_R14(regs); break; \ + case R15: val = UPT_R15(regs); break; \ + case RIP: val = UPT_IP(regs); break; \ + case RSP: val = UPT_SP(regs); break; \ + case RAX: val = UPT_RAX(regs); break; \ + case RBX: val = UPT_RBX(regs); break; \ + case RCX: val = UPT_RCX(regs); break; \ + case RDX: val = UPT_RDX(regs); break; \ + case RSI: val = UPT_RSI(regs); break; \ + case RDI: val = UPT_RDI(regs); break; \ + case RBP: val = UPT_RBP(regs); break; \ + case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \ + case CS: val = UPT_CS(regs); break; \ + case SS: val = UPT_SS(regs); break; \ + case FS_BASE: val = UPT_FS_BASE(regs); break; \ + case GS_BASE: val = UPT_GS_BASE(regs); break; \ + case DS: val = UPT_DS(regs); break; \ + case ES: val = UPT_ES(regs); break; \ + case FS : val = UPT_FS (regs); break; \ + case GS: val = UPT_GS(regs); break; \ + case EFLAGS: val = UPT_EFLAGS(regs); break; \ + default : \ + panic("Bad register in UPT_REG : %d\n", reg); \ + val = -1; \ + } \ + val; \ + }) #define UPT_SET(regs, reg, val) \ - ({ unsigned long __upt_val = val; \ - switch(reg){ \ - case R8: UPT_R8(regs) = __upt_val; break; \ - case R9: UPT_R9(regs) = __upt_val; break; \ - case R10: UPT_R10(regs) = __upt_val; break; \ - case R11: UPT_R11(regs) = __upt_val; break; \ - case R12: UPT_R12(regs) = __upt_val; break; \ - case R13: UPT_R13(regs) = __upt_val; break; \ - case R14: UPT_R14(regs) = __upt_val; break; \ - case R15: UPT_R15(regs) = __upt_val; break; \ - case RIP: UPT_IP(regs) = __upt_val; break; \ - case RSP: UPT_SP(regs) = __upt_val; break; \ - case RAX: UPT_RAX(regs) = __upt_val; break; \ - case RBX: UPT_RBX(regs) = __upt_val; break; \ - case RCX: UPT_RCX(regs) = __upt_val; break; \ - case RDX: UPT_RDX(regs) = __upt_val; break; \ - case RSI: UPT_RSI(regs) = __upt_val; break; \ - case RDI: UPT_RDI(regs) = __upt_val; break; \ - case RBP: UPT_RBP(regs) = __upt_val; break; \ - case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ - case CS: UPT_CS(regs) = __upt_val; break; \ - case SS: UPT_SS(regs) = __upt_val; break; \ - case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \ - case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \ - case DS: UPT_DS(regs) = __upt_val; break; \ - case ES: UPT_ES(regs) = __upt_val; break; \ - case FS: UPT_FS(regs) = __upt_val; break; \ - case GS: UPT_GS(regs) = __upt_val; break; \ - case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \ - default : \ - panic("Bad register in UPT_SET : %d\n", reg); \ - break; \ - } \ - __upt_val; \ - }) + ({ unsigned long __upt_val = val; \ + switch(reg){ \ + case R8: UPT_R8(regs) = __upt_val; break; \ + case R9: UPT_R9(regs) = __upt_val; break; \ + case R10: UPT_R10(regs) = __upt_val; break; \ + case R11: UPT_R11(regs) = __upt_val; break; \ + case R12: UPT_R12(regs) = __upt_val; break; \ + case R13: UPT_R13(regs) = __upt_val; break; \ + case R14: UPT_R14(regs) = __upt_val; break; \ + case R15: UPT_R15(regs) = __upt_val; break; \ + case RIP: UPT_IP(regs) = __upt_val; break; \ + case RSP: UPT_SP(regs) = __upt_val; break; \ + case RAX: UPT_RAX(regs) = __upt_val; break; \ + case RBX: UPT_RBX(regs) = __upt_val; break; \ + case RCX: UPT_RCX(regs) = __upt_val; break; \ + case RDX: UPT_RDX(regs) = __upt_val; break; \ + case RSI: UPT_RSI(regs) = __upt_val; break; \ + case RDI: UPT_RDI(regs) = __upt_val; break; \ + case RBP: UPT_RBP(regs) = __upt_val; break; \ + case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ + case CS: UPT_CS(regs) = __upt_val; break; \ + case SS: UPT_SS(regs) = __upt_val; break; \ + case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \ + case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \ + case DS: UPT_DS(regs) = __upt_val; break; \ + case ES: UPT_ES(regs) = __upt_val; break; \ + case FS: UPT_FS(regs) = __upt_val; break; \ + case GS: UPT_GS(regs) = __upt_val; break; \ + case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \ + default : \ + panic("Bad register in UPT_SET : %d\n", reg); \ + break; \ + } \ + __upt_val; \ + }) #define UPT_SET_SYSCALL_RETURN(r, res) \ - CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \ - REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res))) + REGS_SET_SYSCALL_RETURN((r)->regs, (res)) + +#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) -#define UPT_RESTART_SYSCALL(r) \ - CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \ - REGS_RESTART_SYSCALL((r)->skas.regs)) +#define UPT_SEGV_IS_FIXABLE(r) REGS_SEGV_IS_FIXABLE(&r->skas) -#define UPT_SEGV_IS_FIXABLE(r) \ - CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ - REGS_SEGV_IS_FIXABLE(&r->skas)) +#define UPT_FAULTINFO(r) (&(r)->faultinfo) -#define UPT_FAULTINFO(r) \ - CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo)) +static inline void arch_init_registers(int pid) +{ +} #endif diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h index 41073235e7ad..0155133b1458 100644 --- a/arch/um/include/sysdep-x86_64/sigcontext.h +++ b/arch/um/include/sysdep-x86_64/sigcontext.h @@ -11,43 +11,17 @@ #define IP_RESTART_SYSCALL(ip) ((ip) -= 2) -#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) -#define SC_SET_SYSCALL_RETURN(sc, result) SC_RAX(sc) = (result) - -#define SC_FAULT_ADDR(sc) SC_CR2(sc) -#define SC_FAULT_TYPE(sc) SC_ERR(sc) - -#define GET_FAULTINFO_FROM_SC(fi,sc) \ +#define GET_FAULTINFO_FROM_SC(fi, sc) \ { \ (fi).cr2 = SC_CR2(sc); \ (fi).error_code = SC_ERR(sc); \ (fi).trap_no = SC_TRAPNO(sc); \ } -/* ptrace expects that, at the start of a system call, %eax contains - * -ENOSYS, so this makes it so. - */ - -#define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0) - /* This is Page Fault */ #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) /* No broken SKAS API, which doesn't pass trap_no, here. */ #define SEGV_MAYBE_FIXABLE(fi) 0 -extern unsigned long *sc_sigmask(void *sc_ptr); - #endif - -/* - * 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/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h index 92e989f81761..655f9c2de3ac 100644 --- a/arch/um/include/sysdep-x86_64/stub.h +++ b/arch/um/include/sysdep-x86_64/stub.h @@ -9,6 +9,7 @@ #include <sys/mman.h> #include <asm/unistd.h> #include <sysdep/ptrace_user.h> +#include "as-layout.h" #include "stub-data.h" #include "kern_constants.h" #include "uml-config.h" @@ -94,13 +95,13 @@ static inline void remap_stack(long fd, unsigned long offset) { __asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; " "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; " - "movq %%rax, (%%rbx)": - : "a" (STUB_MMAP_NR), "D" (UML_CONFIG_STUB_DATA), - "S" (UM_KERN_PAGE_SIZE), - "d" (PROT_READ | PROT_WRITE), - "g" (MAP_FIXED | MAP_SHARED), "g" (fd), + "movq %%rax, (%%rbx)": + : "a" (STUB_MMAP_NR), "D" (STUB_DATA), + "S" (UM_KERN_PAGE_SIZE), + "d" (PROT_READ | PROT_WRITE), + "g" (MAP_FIXED | MAP_SHARED), "g" (fd), "g" (offset), - "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err) + "i" (&((struct stub_data *) STUB_DATA)->err) : __syscall_clobber, "r10", "r8", "r9" ); } diff --git a/arch/um/include/sysdep-x86_64/thread.h b/arch/um/include/sysdep-x86_64/thread.h deleted file mode 100644 index cbef3e1697f4..000000000000 --- a/arch/um/include/sysdep-x86_64/thread.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __UM_THREAD_H -#define __UM_THREAD_H - -#include <kern_constants.h> - -#ifdef UML_CONFIG_MODE_TT -#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID])) -#endif - -#endif diff --git a/arch/um/include/task.h b/arch/um/include/task.h index 6375ba7203c9..3fe726b3cf48 100644 --- a/arch/um/include/task.h +++ b/arch/um/include/task.h @@ -3,7 +3,7 @@ #include <kern_constants.h> -#define TASK_REGS(task) ((union uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS])) +#define TASK_REGS(task) ((struct uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS])) #define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID])) #endif diff --git a/arch/um/include/tlb.h b/arch/um/include/tlb.h index bcd1a4afb842..ecd2265b301b 100644 --- a/arch/um/include/tlb.h +++ b/arch/um/include/tlb.h @@ -8,34 +8,7 @@ #include "um_mmu.h" -struct host_vm_op { - enum { NONE, MMAP, MUNMAP, MPROTECT } type; - union { - struct { - unsigned long addr; - unsigned long len; - unsigned int prot; - int fd; - __u64 offset; - } mmap; - struct { - unsigned long addr; - unsigned long len; - } munmap; - struct { - unsigned long addr; - unsigned long len; - unsigned int prot; - } mprotect; - } u; -}; - extern void force_flush_all(void); -extern void fix_range_common(struct mm_struct *mm, unsigned long start_addr, - unsigned long end_addr, int force, - int (*do_ops)(union mm_context *, - struct host_vm_op *, int, int, - void **)); extern int flush_tlb_kernel_range_common(unsigned long start, unsigned long end); diff --git a/arch/um/include/tt/debug.h b/arch/um/include/tt/debug.h deleted file mode 100644 index 9778fa838296..000000000000 --- a/arch/um/include/tt/debug.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) and - * Lars Brinkhoff. - * Licensed under the GPL - */ - -#ifndef __UML_TT_DEBUG_H -#define __UML_TT_DEBUG_H - -extern int debugger_proxy(int status, pid_t pid); -extern void child_proxy(pid_t pid, int status); -extern void init_proxy (pid_t pid, int waiting, int status); -extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd); -extern void fake_child_exit(void); -extern int gdb_config(char *str); -extern int gdb_remove(int unused); - -#endif diff --git a/arch/um/include/tt/mmu-tt.h b/arch/um/include/tt/mmu-tt.h deleted file mode 100644 index 572a78b22587..000000000000 --- a/arch/um/include/tt/mmu-tt.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __TT_MMU_H -#define __TT_MMU_H - -struct mmu_context_tt { -}; - -#endif diff --git a/arch/um/include/tt/mode-tt.h b/arch/um/include/tt/mode-tt.h deleted file mode 100644 index 2823cd56eea2..000000000000 --- a/arch/um/include/tt/mode-tt.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __MODE_TT_H__ -#define __MODE_TT_H__ - -#include "sysdep/ptrace.h" - -enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB }; - -extern int tracing_pid; - -extern int tracer(int (*init_proc)(void *), void *sp); -extern void sig_handler_common_tt(int sig, void *sc); -extern void syscall_handler_tt(int sig, union uml_pt_regs *regs); -extern void reboot_tt(void); -extern void halt_tt(void); -extern int is_tracer_winch(int pid, int fd, void *data); -extern void kill_off_processes_tt(void); - -#endif diff --git a/arch/um/include/tt/mode_kern_tt.h b/arch/um/include/tt/mode_kern_tt.h deleted file mode 100644 index a4fc63057195..000000000000 --- a/arch/um/include/tt/mode_kern_tt.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __TT_MODE_KERN_H__ -#define __TT_MODE_KERN_H__ - -#include "linux/sched.h" -#include "asm/page.h" -#include "asm/ptrace.h" -#include "asm/uaccess.h" - -extern void switch_to_tt(void *prev, void *next); -extern void flush_thread_tt(void); -extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, - unsigned long esp); -extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, - unsigned long stack_top, struct task_struct *p, - struct pt_regs *regs); -extern void release_thread_tt(struct task_struct *task); -extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); -extern void init_idle_tt(void); -extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); -extern void flush_tlb_kernel_vm_tt(void); -extern void __flush_tlb_one_tt(unsigned long addr); -extern void flush_tlb_range_tt(struct vm_area_struct *vma, - unsigned long start, unsigned long end); -extern void flush_tlb_mm_tt(struct mm_struct *mm); -extern void force_flush_all_tt(void); -extern long execute_syscall_tt(void *r); -extern void before_mem_tt(unsigned long brk_start); -extern unsigned long set_task_sizes_tt(unsigned long *task_size_out); -extern int start_uml_tt(void); -extern int external_pid_tt(struct task_struct *task); -extern int thread_pid_tt(struct task_struct *task); - -#define kmem_end_tt (host_task_size - ABOVE_KMEM) - -#endif diff --git a/arch/um/include/tt/tt.h b/arch/um/include/tt/tt.h deleted file mode 100644 index acb8356e1f98..000000000000 --- a/arch/um/include/tt/tt.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __TT_H__ -#define __TT_H__ - -#include "sysdep/ptrace.h" - -extern int gdb_pid; -extern int debug; -extern int debug_stop; -extern int debug_trace; - -extern int honeypot; - -extern int fork_tramp(void *sig_stack); -extern int do_proc_op(void *t, int proc_id); -extern int tracer(int (*init_proc)(void *), void *sp); -extern void attach_process(int pid); -extern void tracer_panic(char *format, ...) - __attribute__ ((format (printf, 1, 2))); -extern void set_init_pid(int pid); -extern int set_user_mode(void *task); -extern void set_tracing(void *t, int tracing); -extern int is_tracing(void *task); -extern void syscall_handler(int sig, union uml_pt_regs *regs); -extern void exit_kernel(int pid, void *task); -extern void do_syscall(void *task, int pid, int local_using_sysemu); -extern void do_sigtrap(void *task); -extern int is_valid_pid(int pid); -extern void remap_data(void *segment_start, void *segment_end, int w); -extern long execute_syscall_tt(void *r); - -#endif - diff --git a/arch/um/include/tt/uaccess-tt.h b/arch/um/include/tt/uaccess-tt.h deleted file mode 100644 index 13a64f61fcf4..000000000000 --- a/arch/um/include/tt/uaccess-tt.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __TT_UACCESS_H -#define __TT_UACCESS_H - -#include "linux/string.h" -#include "linux/sched.h" -#include "asm/processor.h" -#include "asm/errno.h" -#include "asm/current.h" -#include "asm/a.out.h" -#include "uml_uaccess.h" - -#define ABOVE_KMEM (16 * 1024 * 1024) - -extern unsigned long end_vm; -extern unsigned long uml_physmem; - -#define is_stack(addr, size) \ - (((unsigned long) (addr) < STACK_TOP) && \ - ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \ - (((unsigned long) (addr) + (size)) <= STACK_TOP)) - -#define access_ok_tt(type, addr, size) \ - (is_stack(addr, size)) - -extern int __do_copy_from_user(void *to, const void *from, int n, - void **fault_addr, void **fault_catcher); -extern int __do_strncpy_from_user(char *dst, const char *src, size_t n, - void **fault_addr, void **fault_catcher); -extern int __do_clear_user(void *mem, size_t len, void **fault_addr, - void **fault_catcher); -extern int __do_strnlen_user(const char *str, unsigned long n, - void **fault_addr, void **fault_catcher); - -extern int copy_from_user_tt(void *to, const void __user *from, int n); -extern int copy_to_user_tt(void __user *to, const void *from, int n); -extern int strncpy_from_user_tt(char *dst, const char __user *src, int count); -extern int __clear_user_tt(void __user *mem, int len); -extern int clear_user_tt(void __user *mem, int len); -extern int strnlen_user_tt(const void __user *str, int len); - -#endif diff --git a/arch/um/include/um_mmu.h b/arch/um/include/um_mmu.h index 0fa643238300..8855d8df512f 100644 --- a/arch/um/include/um_mmu.h +++ b/arch/um/include/um_mmu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -7,34 +7,22 @@ #define __ARCH_UM_MMU_H #include "uml-config.h" -#include "choose-mode.h" +#include "mm_id.h" +#include "asm/ldt.h" -#ifdef UML_CONFIG_MODE_TT -#include "mmu-tt.h" +typedef struct mm_context { + struct mm_id id; + unsigned long last_page_table; +#ifdef CONFIG_3_LEVEL_PGTABLES + unsigned long last_pmd; #endif + struct uml_ldt ldt; +} mm_context_t; -#ifdef UML_CONFIG_MODE_SKAS -#include "mmu-skas.h" -#endif +extern void __switch_mm(struct mm_id * mm_idp); -typedef union mm_context { -#ifdef UML_CONFIG_MODE_TT - struct mmu_context_tt tt; -#endif -#ifdef UML_CONFIG_MODE_SKAS - struct mmu_context_skas skas; -#endif -} mm_context_t; +/* Avoid tangled inclusion with asm/ldt.h */ +extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm); +extern void free_ldt(struct mm_context *mm); #endif - -/* - * 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/um_uaccess.h b/arch/um/include/um_uaccess.h index 5126a99b5961..fdfc06b85605 100644 --- a/arch/um/include/um_uaccess.h +++ b/arch/um/include/um_uaccess.h @@ -1,26 +1,16 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ #ifndef __ARCH_UM_UACCESS_H #define __ARCH_UM_UACCESS_H -#include "choose-mode.h" - -#ifdef CONFIG_MODE_TT -#include "uaccess-tt.h" -#endif - -#ifdef CONFIG_MODE_SKAS -#include "uaccess-skas.h" -#endif - #include "asm/fixmap.h" #define __under_task_size(addr, size) \ (((unsigned long) (addr) < TASK_SIZE) && \ - (((unsigned long) (addr) + (size)) < TASK_SIZE)) + (((unsigned long) (addr) + (size)) < TASK_SIZE)) #define __access_ok_vsyscall(type, addr, size) \ ((type == VERIFY_READ) && \ @@ -35,20 +25,14 @@ (__addr_range_nowrap(addr, size) && \ (__under_task_size(addr, size) || \ __access_ok_vsyscall(type, addr, size) || \ - segment_eq(get_fs(), KERNEL_DS) || \ - CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size))) + segment_eq(get_fs(), KERNEL_DS))) -static inline int copy_from_user(void *to, const void __user *from, int n) -{ - return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to, - from, n)); -} +extern int copy_from_user(void *to, const void __user *from, int n); +extern int copy_to_user(void __user *to, const void *from, int n); -static inline int copy_to_user(void __user *to, const void *from, int n) -{ - return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to, - from, n)); -} +extern int __do_copy_to_user(void *to, const void *from, int n, + void **fault_addr, jmp_buf **fault_catcher); +extern void __do_copy(void *to, const void *from, int n); /* * strncpy_from_user: - Copy a NUL terminated string from userspace. @@ -69,11 +53,7 @@ static inline int copy_to_user(void __user *to, const void *from, int n) * and returns @count. */ -static inline int strncpy_from_user(char *dst, const char __user *src, int count) -{ - return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas, - dst, src, count)); -} +extern int strncpy_from_user(char *dst, const char __user *src, int count); /* * __clear_user: - Zero a block of memory in user space, with less checking. @@ -86,10 +66,7 @@ static inline int strncpy_from_user(char *dst, const char __user *src, int count * Returns number of bytes that could not be cleared. * On success, this will be zero. */ -static inline int __clear_user(void *mem, int len) -{ - return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len)); -} +extern int __clear_user(void __user *mem, int len); /* * clear_user: - Zero a block of memory in user space. @@ -101,10 +78,7 @@ static inline int __clear_user(void *mem, int len) * Returns number of bytes that could not be cleared. * On success, this will be zero. */ -static inline int clear_user(void __user *mem, int len) -{ - return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len)); -} +extern int clear_user(void __user *mem, int len); /* * strlen_user: - Get the size of a string in user space. @@ -117,20 +91,6 @@ static inline int clear_user(void __user *mem, int len) * On exception, returns 0. * If the string is too long, returns a value greater than @n. */ -static inline int strnlen_user(const void __user *str, long len) -{ - return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len)); -} +extern int strnlen_user(const void __user *str, int len); #endif - -/* - * 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/uml_uaccess.h b/arch/um/include/uml_uaccess.h deleted file mode 100644 index c0df11d06f5e..000000000000 --- a/arch/um/include/uml_uaccess.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __UML_UACCESS_H__ -#define __UML_UACCESS_H__ - -extern int __do_copy_to_user(void *to, const void *from, int n, - void **fault_addr, void **fault_catcher); -void __do_copy(void *to, const void *from, int n); - -#endif - -/* - * 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/user.h b/arch/um/include/user.h index d380e6d91a90..99033ff28a78 100644 --- a/arch/um/include/user.h +++ b/arch/um/include/user.h @@ -14,10 +14,12 @@ */ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -/* - * This will provide the size_t definition in both kernel and userspace builds - */ +/* This is to get size_t */ +#ifdef __KERNEL__ #include <linux/types.h> +#else +#include <stddef.h> +#endif extern void panic(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index c5cf4a0827b0..499e5e95e609 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) +# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux,intel}.com) # Licensed under the GPL # @@ -9,15 +9,12 @@ clean-files := obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \ physmem.o process.o ptrace.o reboot.o sigio.o \ signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \ - um_arch.o umid.o + um_arch.o umid.o skas/ obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o obj-$(CONFIG_GPROF) += gprof_syms.o obj-$(CONFIG_GCOV) += gmon_syms.o -obj-$(CONFIG_MODE_TT) += tt/ -obj-$(CONFIG_MODE_SKAS) += skas/ - USER_OBJS := config.o include arch/um/scripts/Makefile.rules diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S index 41850906116e..3866f4960f04 100644 --- a/arch/um/kernel/dyn.lds.S +++ b/arch/um/kernel/dyn.lds.S @@ -10,8 +10,6 @@ SECTIONS PROVIDE (__executable_start = START); . = START + SIZEOF_HEADERS; .interp : { *(.interp) } - /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start - * is remapped.*/ __binary_start = .; . = ALIGN(4096); /* Init code and data */ _text = .; diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index ce6828fd396f..8196450451cd 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -1,35 +1,44 @@ /* - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/slab.h" +#include "linux/stddef.h" +#include "linux/fs.h" #include "linux/smp_lock.h" #include "linux/ptrace.h" -#include "linux/fs.h" -#include "asm/ptrace.h" -#include "asm/pgtable.h" -#include "asm/tlbflush.h" +#include "linux/sched.h" +#include "asm/current.h" +#include "asm/processor.h" #include "asm/uaccess.h" -#include "kern_util.h" #include "as-layout.h" #include "mem_user.h" -#include "kern.h" -#include "irq_user.h" -#include "tlb.h" +#include "skas.h" #include "os.h" -#include "choose-mode.h" -#include "mode_kern.h" void flush_thread(void) { + void *data = NULL; + unsigned long end = proc_mm ? task_size : STUB_START; + int ret; + arch_flush_thread(¤t->thread.arch); - CHOOSE_MODE(flush_thread_tt(), flush_thread_skas()); + + ret = unmap(¤t->mm->context.id, 0, end, 1, &data); + if (ret) { + printk(KERN_ERR "flush_thread - clearing address space failed, " + "err = %d\n", ret); + force_sig(SIGKILL, current); + } + + __switch_mm(¤t->mm->context.id); } void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) { - CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp); + set_fs(USER_DS); + PT_REGS_IP(regs) = eip; + PT_REGS_SP(regs) = esp; } #ifdef CONFIG_TTY_LOG @@ -39,7 +48,7 @@ extern void log_exec(char **argv, void *tty); static long execve1(char *file, char __user * __user *argv, char __user *__user *env) { - long error; + long error; #ifdef CONFIG_TTY_LOG struct tty_struct *tty; @@ -49,17 +58,16 @@ static long execve1(char *file, char __user * __user *argv, log_exec(argv, tty); mutex_unlock(&tty_mutex); #endif - error = do_execve(file, argv, env, ¤t->thread.regs); - if (error == 0){ + error = do_execve(file, argv, env, ¤t->thread.regs); + if (error == 0) { task_lock(current); - current->ptrace &= ~PT_DTRACE; + current->ptrace &= ~PT_DTRACE; #ifdef SUBARCH_EXECVE1 SUBARCH_EXECVE1(¤t->thread.regs.regs); #endif task_unlock(current); - set_cmdline(current_cmd()); - } - return(error); + } + return error; } long um_execve(char *file, char __user *__user *argv, char __user *__user *env) @@ -67,9 +75,9 @@ long um_execve(char *file, char __user *__user *argv, char __user *__user *env) long err; err = execve1(file, argv, env); - if(!err) - do_longjmp(current->thread.exec_buf, 1); - return(err); + if (!err) + UML_LONGJMP(current->thread.exec_buf, 1); + return err; } long sys_execve(char __user *file, char __user *__user *argv, @@ -86,5 +94,5 @@ long sys_execve(char __user *file, char __user *__user *argv, putname(filename); out: unlock_kernel(); - return(error); + return error; } diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c index cba516e6c99a..dcfceca95052 100644 --- a/arch/um/kernel/init_task.c +++ b/arch/um/kernel/init_task.c @@ -3,16 +3,12 @@ * Licensed under the GPL */ -#include "linux/mm.h" -#include "linux/fs.h" -#include "linux/module.h" #include "linux/sched.h" #include "linux/init_task.h" +#include "linux/fs.h" +#include "linux/module.h" #include "linux/mqueue.h" #include "asm/uaccess.h" -#include "asm/pgtable.h" -#include "mem_user.h" -#include "os.h" static struct fs_struct init_fs = INIT_FS; struct mm_struct init_mm = INIT_MM(init_mm); @@ -46,8 +42,3 @@ union thread_union init_thread_union union thread_union cpu0_irqstack __attribute__((__section__(".data.init_irqstack"))) = { INIT_THREAD_INFO(init_task) }; - -void unprotect_stack(unsigned long stack) -{ - os_protect_memory((void *) stack, THREAD_SIZE, 1, 1, 0); -} diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index cf0dd9cf8c43..277fce17b088 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -1,37 +1,19 @@ /* - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c: * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar */ -#include "linux/kernel.h" -#include "linux/module.h" -#include "linux/smp.h" -#include "linux/kernel_stat.h" +#include "linux/cpumask.h" +#include "linux/hardirq.h" #include "linux/interrupt.h" -#include "linux/random.h" -#include "linux/slab.h" -#include "linux/file.h" -#include "linux/proc_fs.h" -#include "linux/init.h" +#include "linux/kernel_stat.h" +#include "linux/module.h" #include "linux/seq_file.h" -#include "linux/profile.h" -#include "linux/hardirq.h" -#include "asm/irq.h" -#include "asm/hw_irq.h" -#include "asm/atomic.h" -#include "asm/signal.h" -#include "asm/system.h" -#include "asm/errno.h" -#include "asm/uaccess.h" +#include "as-layout.h" #include "kern_util.h" -#include "irq_user.h" -#include "irq_kern.h" #include "os.h" -#include "sigio.h" -#include "misc_constants.h" -#include "as-layout.h" /* * Generic, controller-independent functions: @@ -71,9 +53,8 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) { + } else if (i == NR_IRQS) seq_putc(p, '\n'); - } return 0; } @@ -91,7 +72,7 @@ static struct irq_fd **last_irq_ptr = &active_fds; extern void free_irqs(void); -void sigio_handler(int sig, union uml_pt_regs *regs) +void sigio_handler(int sig, struct uml_pt_regs *regs) { struct irq_fd *irq_fd; int n; @@ -102,11 +83,13 @@ void sigio_handler(int sig, union uml_pt_regs *regs) while (1) { n = os_waiting_for_events(active_fds); if (n <= 0) { - if(n == -EINTR) continue; + if (n == -EINTR) + continue; else break; } - for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { + for (irq_fd = active_fds; irq_fd != NULL; + irq_fd = irq_fd->next) { if (irq_fd->current_events != 0) { irq_fd->current_events = 0; do_IRQ(irq_fd->irq, regs); @@ -138,8 +121,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id) if (type == IRQ_READ) events = UM_POLLIN | UM_POLLPRI; - else - events = UM_POLLOUT; + else events = UM_POLLOUT; *new_fd = ((struct irq_fd) { .next = NULL, .id = dev_id, .fd = fd, @@ -153,9 +135,10 @@ int activate_fd(int irq, int fd, int type, void *dev_id) spin_lock_irqsave(&irq_lock, flags); for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { if ((irq_fd->fd == fd) && (irq_fd->type == type)) { - printk("Registering fd %d twice\n", fd); - printk("Irqs : %d, %d\n", irq_fd->irq, irq); - printk("Ids : 0x%p, 0x%p\n", irq_fd->id, dev_id); + printk(KERN_ERR "Registering fd %d twice\n", fd); + printk(KERN_ERR "Irqs : %d, %d\n", irq_fd->irq, irq); + printk(KERN_ERR "Ids : 0x%p, 0x%p\n", irq_fd->id, + dev_id); goto out_unlock; } } @@ -171,7 +154,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id) if (n == 0) break; - /* n > 0 + /* + * n > 0 * It means we couldn't put new pollfd to current pollfds * and tmp_fds is NULL or too small for new pollfds array. * Needed size is equal to n as minimum. @@ -197,7 +181,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id) spin_unlock_irqrestore(&irq_lock, flags); - /* This calls activate_fd, so it has to be outside the critical + /* + * This calls activate_fd, so it has to be outside the critical * section. */ maybe_sigio_broken(fd, (type == IRQ_READ)); @@ -264,13 +249,14 @@ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out) i++; } if (irq == NULL) { - printk("find_irq_by_fd doesn't have descriptor %d\n", fd); + printk(KERN_ERR "find_irq_by_fd doesn't have descriptor %d\n", + fd); goto out; } fdi = os_get_pollfd(i); if ((fdi != -1) && (fdi != fd)) { - printk("find_irq_by_fd - mismatch between active_fds and " - "pollfds, fd %d vs %d, need %d\n", irq->fd, + printk(KERN_ERR "find_irq_by_fd - mismatch between active_fds " + "and pollfds, fd %d vs %d, need %d\n", irq->fd, fdi, fd); irq = NULL; goto out; @@ -306,7 +292,7 @@ void deactivate_fd(int fd, int irqnum) spin_lock_irqsave(&irq_lock, flags); irq = find_irq_by_fd(fd, irqnum, &i); - if(irq == NULL){ + if (irq == NULL) { spin_unlock_irqrestore(&irq_lock, flags); return; } @@ -339,36 +325,12 @@ int deactivate_all_fds(void) return 0; } -#ifdef CONFIG_MODE_TT -void forward_interrupts(int pid) -{ - struct irq_fd *irq; - unsigned long flags; - int err; - - spin_lock_irqsave(&irq_lock, flags); - for (irq = active_fds; irq != NULL; irq = irq->next) { - err = os_set_owner(irq->fd, pid); - if (err < 0) { - /* XXX Just remove the irq rather than - * print out an infinite stream of these - */ - printk("Failed to forward %d to pid %d, err = %d\n", - irq->fd, pid, -err); - } - - irq->pid = pid; - } - spin_unlock_irqrestore(&irq_lock, flags); -} -#endif - /* * do_IRQ handles all normal device IRQ's (the special * SMP cross-CPU interrupts have their own specific * handlers). */ -unsigned int do_IRQ(int irq, union uml_pt_regs *regs) +unsigned int do_IRQ(int irq, struct uml_pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs((struct pt_regs *)regs); irq_enter(); @@ -396,8 +358,10 @@ int um_request_irq(unsigned int irq, int fd, int type, EXPORT_SYMBOL(um_request_irq); EXPORT_SYMBOL(reactivate_fd); -/* hw_interrupt_type must define (startup || enable) && - * (shutdown || disable) && end */ +/* + * hw_interrupt_type must define (startup || enable) && + * (shutdown || disable) && end + */ static void dummy(unsigned int irq) { } @@ -446,7 +410,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler) err = os_pipe(fds, 1, 1); if (err) { - printk("init_aio_irq - os_pipe failed, err = %d\n", -err); + printk(KERN_ERR "init_aio_irq - os_pipe failed, err = %d\n", + -err); goto out; } @@ -454,7 +419,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler) IRQF_DISABLED | IRQF_SAMPLE_RANDOM, name, (void *) (long) fds[0]); if (err) { - printk("init_aio_irq - : um_request_irq failed, err = %d\n", + printk(KERN_ERR "init_aio_irq - : um_request_irq failed, " + "err = %d\n", err); goto out_close; } @@ -525,8 +491,9 @@ unsigned long to_irq_stack(unsigned long *mask_out) int nested; mask = xchg(&pending_mask, *mask_out); - if(mask != 0){ - /* If any interrupts come in at this point, we want to + if (mask != 0) { + /* + * If any interrupts come in at this point, we want to * make sure that their bits aren't lost by our * putting our bit in. So, this loop accumulates bits * until xchg returns the same value that we put in. @@ -538,13 +505,13 @@ unsigned long to_irq_stack(unsigned long *mask_out) do { old |= mask; mask = xchg(&pending_mask, old); - } while(mask != old); + } while (mask != old); return 1; } ti = current_thread_info(); nested = (ti->real_thread != NULL); - if(!nested){ + if (!nested) { struct task_struct *task; struct thread_info *tti; diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 7b3e53fb8070..1b388b41d95d 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -1,22 +1,15 @@ /* - * Copyright (C) 2001 - 2004 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ #include "linux/module.h" -#include "linux/string.h" -#include "linux/smp_lock.h" -#include "linux/spinlock.h" -#include "linux/highmem.h" -#include "asm/current.h" -#include "asm/processor.h" -#include "asm/unistd.h" -#include "asm/pgalloc.h" -#include "asm/pgtable.h" -#include "asm/page.h" +#include "linux/syscalls.h" +#include "asm/a.out.h" #include "asm/tlbflush.h" -#include "kern_util.h" +#include "asm/uaccess.h" #include "as-layout.h" +#include "kern_util.h" #include "mem_user.h" #include "os.h" @@ -34,30 +27,19 @@ EXPORT_SYMBOL(get_kmem_end); EXPORT_SYMBOL(high_physmem); EXPORT_SYMBOL(empty_zero_page); EXPORT_SYMBOL(um_virt_to_phys); -EXPORT_SYMBOL(mode_tt); EXPORT_SYMBOL(handle_page_fault); EXPORT_SYMBOL(find_iomem); -#ifdef CONFIG_MODE_TT -EXPORT_SYMBOL(stop); -EXPORT_SYMBOL(strncpy_from_user_tt); -EXPORT_SYMBOL(copy_from_user_tt); -EXPORT_SYMBOL(copy_to_user_tt); -#endif - -#ifdef CONFIG_MODE_SKAS -EXPORT_SYMBOL(strnlen_user_skas); -EXPORT_SYMBOL(strncpy_from_user_skas); -EXPORT_SYMBOL(copy_to_user_skas); -EXPORT_SYMBOL(copy_from_user_skas); -EXPORT_SYMBOL(clear_user_skas); -#endif +EXPORT_SYMBOL(strnlen_user); +EXPORT_SYMBOL(strncpy_from_user); +EXPORT_SYMBOL(copy_to_user); +EXPORT_SYMBOL(copy_from_user); +EXPORT_SYMBOL(clear_user); EXPORT_SYMBOL(uml_strdup); EXPORT_SYMBOL(os_stat_fd); EXPORT_SYMBOL(os_stat_file); EXPORT_SYMBOL(os_access); -EXPORT_SYMBOL(os_print_error); EXPORT_SYMBOL(os_get_exec_close); EXPORT_SYMBOL(os_set_exec_close); EXPORT_SYMBOL(os_getpid); @@ -85,9 +67,6 @@ EXPORT_SYMBOL(run_helper); EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(dump_thread); -EXPORT_SYMBOL(do_gettimeofday); -EXPORT_SYMBOL(do_settimeofday); - #ifdef CONFIG_SMP /* required for SMP */ diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index d2b11f242698..8456397f5f4d 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -17,7 +17,7 @@ #include "as-layout.h" #include "kern.h" #include "mem_user.h" -#include "uml_uaccess.h" +#include "um_uaccess.h" #include "os.h" #include "linux/types.h" #include "linux/string.h" diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index 5ee7e851bbc1..e66432f42485 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -1,25 +1,17 @@ /* - * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/mm.h" -#include "linux/rbtree.h" -#include "linux/slab.h" -#include "linux/vmalloc.h" #include "linux/bootmem.h" -#include "linux/module.h" +#include "linux/mm.h" #include "linux/pfn.h" -#include "asm/types.h" -#include "asm/pgtable.h" -#include "kern_util.h" +#include "asm/page.h" #include "as-layout.h" -#include "mode_kern.h" -#include "mem.h" +#include "init.h" +#include "kern.h" #include "mem_user.h" #include "os.h" -#include "kern.h" -#include "init.h" static int physmem_fd = -1; @@ -49,10 +41,10 @@ int __init init_maps(unsigned long physmem, unsigned long iomem, total_len = phys_len + iomem_len + highmem_len; map = alloc_bootmem_low_pages(total_len); - if(map == NULL) + if (map == NULL) return -ENOMEM; - for(i = 0; i < total_pages; i++){ + for (i = 0; i < total_pages; i++) { p = &map[i]; memset(p, 0, sizeof(struct page)); SetPageReserved(p); @@ -68,8 +60,8 @@ static unsigned long kmem_top = 0; unsigned long get_kmem_end(void) { - if(kmem_top == 0) - kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas); + if (kmem_top == 0) + kmem_top = host_task_size - 1024 * 1024; return kmem_top; } @@ -81,9 +73,9 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len, fd = phys_mapping(phys, &offset); err = os_map_memory((void *) virt, fd, offset, len, r, w, x); - if(err) { - if(err == -ENOMEM) - printk("try increasing the host's " + if (err) { + if (err == -ENOMEM) + printk(KERN_ERR "try increasing the host's " "/proc/sys/vm/max_map_count to <physical " "memory size>/4096\n"); panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, " @@ -105,13 +97,16 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end, offset = uml_reserved - uml_physmem; err = os_map_memory((void *) uml_reserved, physmem_fd, offset, - len - offset, 1, 1, 0); - if(err < 0){ - os_print_error(err, "Mapping memory"); + len - offset, 1, 1, 1); + if (err < 0) { + printf("setup_physmem - mapping %ld bytes of memory at 0x%p " + "failed - errno = %d\n", len - offset, + (void *) uml_reserved, err); exit(1); } - /* Special kludge - This page will be mapped in to userspace processes + /* + * Special kludge - This page will be mapped in to userspace processes * from physmem_fd, so it needs to be written out there. */ os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); @@ -122,20 +117,20 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end, len - bootmap_size - reserve); } -int phys_mapping(unsigned long phys, __u64 *offset_out) +int phys_mapping(unsigned long phys, unsigned long long *offset_out) { int fd = -1; - if(phys < physmem_size){ + if (phys < physmem_size) { fd = physmem_fd; *offset_out = phys; } - else if(phys < __pa(end_iomem)){ + else if (phys < __pa(end_iomem)) { struct iomem_region *region = iomem_regions; - while(region != NULL){ - if((phys >= region->phys) && - (phys < region->phys + region->size)){ + while (region != NULL) { + if ((phys >= region->phys) && + (phys < region->phys + region->size)) { fd = region->fd; *offset_out = phys - region->phys; break; @@ -143,7 +138,7 @@ int phys_mapping(unsigned long phys, __u64 *offset_out) region = region->next; } } - else if(phys < __pa(end_iomem) + highmem){ + else if (phys < __pa(end_iomem) + highmem) { fd = physmem_fd; *offset_out = phys - iomem_size; } @@ -188,8 +183,8 @@ unsigned long find_iomem(char *driver, unsigned long *len_out) { struct iomem_region *region = iomem_regions; - while(region != NULL){ - if(!strcmp(region->driver, driver)){ + while (region != NULL) { + if (!strcmp(region->driver, driver)) { *len_out = region->size; return region->virt; } @@ -206,12 +201,12 @@ int setup_iomem(void) unsigned long iomem_start = high_physmem + PAGE_SIZE; int err; - while(region != NULL){ + while (region != NULL) { err = os_map_memory((void *) iomem_start, region->fd, 0, region->size, 1, 1, 0); - if(err) - printk("Mapping iomem region for driver '%s' failed, " - "errno = %d\n", region->driver, -err); + if (err) + printk(KERN_ERR "Mapping iomem region for driver '%s' " + "failed, errno = %d\n", region->driver, -err); else { region->virt = iomem_start; region->phys = __pa(region->virt); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index bfa52f206bb6..0eae00b3e588 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -1,53 +1,30 @@ /* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Copyright 2003 PathScale, Inc. * Licensed under the GPL */ -#include "linux/kernel.h" -#include "linux/sched.h" -#include "linux/interrupt.h" -#include "linux/string.h" +#include "linux/stddef.h" +#include "linux/err.h" +#include "linux/hardirq.h" #include "linux/mm.h" -#include "linux/slab.h" -#include "linux/utsname.h" -#include "linux/fs.h" -#include "linux/utime.h" -#include "linux/smp_lock.h" -#include "linux/module.h" -#include "linux/init.h" -#include "linux/capability.h" -#include "linux/vmalloc.h" -#include "linux/spinlock.h" +#include "linux/personality.h" #include "linux/proc_fs.h" #include "linux/ptrace.h" #include "linux/random.h" -#include "linux/personality.h" -#include "asm/unistd.h" -#include "asm/mman.h" -#include "asm/segment.h" -#include "asm/stat.h" +#include "linux/sched.h" +#include "linux/tick.h" +#include "linux/threads.h" #include "asm/pgtable.h" -#include "asm/processor.h" -#include "asm/tlbflush.h" #include "asm/uaccess.h" -#include "asm/user.h" -#include "kern_util.h" #include "as-layout.h" -#include "kern.h" -#include "signal_kern.h" -#include "init.h" -#include "irq_user.h" -#include "mem_user.h" -#include "tlb.h" -#include "frame_kern.h" -#include "sigcontext.h" +#include "kern_util.h" #include "os.h" -#include "mode.h" -#include "mode_kern.h" -#include "choose-mode.h" +#include "skas.h" +#include "tlb.h" -/* This is a per-cpu array. A processor only modifies its entry and it only +/* + * 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 * entry. */ @@ -55,15 +32,16 @@ struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; static inline int external_pid(struct task_struct *task) { - return CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task); + /* FIXME: Need to look up userspace_pid by cpu */ + return userspace_pid[0]; } int pid_to_processor_id(int pid) { int i; - for(i = 0; i < ncpus; i++){ - if(cpu_tasks[i].pid == pid) + for(i = 0; i < ncpus; i++) { + if (cpu_tasks[i].pid == pid) return i; } return -1; @@ -82,9 +60,9 @@ unsigned long alloc_stack(int order, int atomic) if (atomic) flags = GFP_ATOMIC; page = __get_free_pages(flags, order); - if(page == 0) + if (page == 0) return 0; - stack_protections(page); + return page; } @@ -105,6 +83,8 @@ static inline void set_current(struct task_struct *task) { external_pid(task), task }); } +extern void arch_switch_to(struct task_struct *from, struct task_struct *to); + void *_switch_to(void *prev, void *next, void *last) { struct task_struct *from = prev; @@ -114,9 +94,14 @@ void *_switch_to(void *prev, void *next, void *last) set_current(to); do { - current->thread.saved_task = NULL ; - CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next); - if(current->thread.saved_task) + current->thread.saved_task = NULL; + + switch_threads(&from->thread.switch_buf, + &to->thread.switch_buf); + + arch_switch_to(current->thread.prev_sched, current); + + if (current->thread.saved_task) show_regs(&(current->thread.regs)); next= current->thread.saved_task; prev= current; @@ -128,20 +113,14 @@ void *_switch_to(void *prev, void *next, void *last) void interrupt_end(void) { - if(need_resched()) + if (need_resched()) schedule(); - if(test_tsk_thread_flag(current, TIF_SIGPENDING)) + if (test_tsk_thread_flag(current, TIF_SIGPENDING)) do_signal(); } -void release_thread(struct task_struct *task) -{ - CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task)); -} - void exit_thread(void) { - unprotect_stack((unsigned long) current_thread); } void *get_current(void) @@ -149,28 +128,99 @@ void *get_current(void) return current; } +extern void schedule_tail(struct task_struct *prev); + +/* + * This is called magically, by its address being stuffed in a jmp_buf + * and being longjmp-d to. + */ +void new_thread_handler(void) +{ + int (*fn)(void *), n; + void *arg; + + if (current->thread.prev_sched != NULL) + schedule_tail(current->thread.prev_sched); + current->thread.prev_sched = NULL; + + fn = current->thread.request.u.thread.proc; + arg = current->thread.request.u.thread.arg; + + /* + * The return value is 1 if the kernel thread execs a process, + * 0 if it just exits + */ + n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); + if (n == 1) { + /* Handle any immediate reschedules or signals */ + interrupt_end(); + userspace(¤t->thread.regs.regs); + } + else do_exit(0); +} + +/* Called magically, see new_thread_handler above */ +void fork_handler(void) +{ + force_flush_all(); + if (current->thread.prev_sched == NULL) + panic("blech"); + + schedule_tail(current->thread.prev_sched); + + /* + * XXX: if interrupt_end() calls schedule, this call to + * arch_switch_to isn't needed. We could want to apply this to + * improve performance. -bb + */ + arch_switch_to(current->thread.prev_sched, current); + + current->thread.prev_sched = NULL; + + /* Handle any immediate reschedules or signals */ + interrupt_end(); + + userspace(¤t->thread.regs.regs); +} + int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, unsigned long stack_top, struct task_struct * p, struct pt_regs *regs) { - int ret; + void (*handler)(void); + int ret = 0; p->thread = (struct thread_struct) INIT_THREAD; - ret = CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr, - clone_flags, sp, stack_top, p, regs); - if (ret || !current->thread.forking) - goto out; + if (current->thread.forking) { + memcpy(&p->thread.regs.regs, ®s->regs, + sizeof(p->thread.regs.regs)); + REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.gp, 0); + if (sp != 0) + REGS_SP(p->thread.regs.regs.gp) = sp; - clear_flushed_tls(p); + handler = fork_handler; - /* - * Set a new TLS for the child thread? - */ - if (clone_flags & CLONE_SETTLS) - ret = arch_copy_tls(p); + arch_copy_thread(¤t->thread.arch, &p->thread.arch); + } + else { + init_thread_registers(&p->thread.regs.regs); + p->thread.request.u.thread = current->thread.request.u.thread; + handler = new_thread_handler; + } + + new_thread(task_stack_page(p), &p->thread.switch_buf, handler); + + if (current->thread.forking) { + clear_flushed_tls(p); + + /* + * Set a new TLS for the child thread? + */ + if (clone_flags & CLONE_SETTLS) + ret = arch_copy_tls(p); + } -out: return ret; } @@ -179,39 +229,35 @@ void initial_thread_cb(void (*proc)(void *), void *arg) int save_kmalloc_ok = kmalloc_ok; kmalloc_ok = 0; - CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc, - arg); + initial_thread_cb_skas(proc, arg); kmalloc_ok = save_kmalloc_ok; } -#ifdef CONFIG_MODE_TT -unsigned long stack_sp(unsigned long page) -{ - return page + PAGE_SIZE - sizeof(void *); -} -#endif - void default_idle(void) { - CHOOSE_MODE(uml_idle_timer(), (void) 0); + unsigned long long nsecs; - while(1){ + while(1) { /* endless idle loop with no priority at all */ /* * although we are an idle CPU, we do not want to * get into the scheduler unnecessarily. */ - if(need_resched()) + if (need_resched()) schedule(); - idle_sleep(10); + tick_nohz_stop_sched_tick(); + nsecs = disable_timer(); + idle_sleep(nsecs); + tick_nohz_restart_sched_tick(); } } void cpu_idle(void) { - CHOOSE_MODE(init_idle_tt(), init_idle_skas()); + cpu_tasks[current_thread->cpu].pid = os_getpid(); + default_idle(); } void *um_virt_to_phys(struct task_struct *task, unsigned long addr, @@ -223,26 +269,26 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr, pte_t *pte; pte_t ptent; - if(task->mm == NULL) + if (task->mm == NULL) return ERR_PTR(-EINVAL); pgd = pgd_offset(task->mm, addr); - if(!pgd_present(*pgd)) + if (!pgd_present(*pgd)) return ERR_PTR(-EINVAL); pud = pud_offset(pgd, addr); - if(!pud_present(*pud)) + if (!pud_present(*pud)) return ERR_PTR(-EINVAL); pmd = pmd_offset(pud, addr); - if(!pmd_present(*pmd)) + if (!pmd_present(*pmd)) return ERR_PTR(-EINVAL); pte = pte_offset_kernel(pmd, addr); ptent = *pte; - if(!pte_present(ptent)) + if (!pte_present(ptent)) return ERR_PTR(-EINVAL); - if(pte_out != NULL) + if (pte_out != NULL) *pte_out = ptent; return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK); } @@ -315,7 +361,7 @@ int smp_sigio_handler(void) #ifdef CONFIG_SMP int cpu = current_thread->cpu; IPI_handler(cpu); - if(cpu != 0) + if (cpu != 0) return 1; #endif return 0; @@ -343,7 +389,8 @@ int get_using_sysemu(void) static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data) { - if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/ + if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) + /* No overflow */ *eof = 1; return strlen(buf); @@ -358,7 +405,8 @@ static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned if (tmp[0] >= '0' && tmp[0] <= '2') set_using_sysemu(tmp[0] - '0'); - return count; /*We use the first char, but pretend to write everything*/ + /* We use the first char, but pretend to write everything */ + return count; } int __init make_proc_sysemu(void) @@ -388,10 +436,10 @@ int singlestepping(void * t) struct task_struct *task = t ? t : current; if ( ! (task->ptrace & PT_DTRACE) ) - return(0); + return 0; if (task->thread.singlestep_syscall) - return(1); + return 1; return 2; } diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 6916c8888dba..a0eba0833068 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -1,35 +1,27 @@ -/* - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/sched.h" -#include "linux/mm.h" -#include "linux/errno.h" -#include "linux/smp_lock.h" -#include "linux/security.h" -#include "linux/ptrace.h" #include "linux/audit.h" +#include "linux/ptrace.h" +#include "linux/sched.h" +#include "asm/uaccess.h" #ifdef CONFIG_PROC_MM -#include "linux/proc_mm.h" +#include "proc_mm.h" #endif -#include "asm/ptrace.h" -#include "asm/uaccess.h" -#include "kern_util.h" #include "skas_ptrace.h" -#include "sysdep/ptrace.h" -#include "os.h" static inline void set_singlestepping(struct task_struct *child, int on) { - if (on) - child->ptrace |= PT_DTRACE; - else - child->ptrace &= ~PT_DTRACE; - child->thread.singlestep_syscall = 0; + if (on) + child->ptrace |= PT_DTRACE; + else + child->ptrace &= ~PT_DTRACE; + child->thread.singlestep_syscall = 0; #ifdef SUBARCH_SET_SINGLESTEPPING - SUBARCH_SET_SINGLESTEPPING(child, on); + SUBARCH_SET_SINGLESTEPPING(child, on); #endif } @@ -37,8 +29,8 @@ static inline void set_singlestepping(struct task_struct *child, int on) * Called by kernel/ptrace.c when detaching.. */ void ptrace_disable(struct task_struct *child) -{ - set_singlestepping(child,0); +{ + set_singlestepping(child,0); } extern int peek_user(struct task_struct * child, long addr, long data); @@ -50,40 +42,40 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) unsigned long __user *p = (void __user *)(unsigned long)data; switch (request) { - /* when I and D space are separate, these will need to be fixed. */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ + /* read word at location addr. */ + case PTRACE_PEEKTEXT: case PTRACE_PEEKDATA: ret = generic_ptrace_peekdata(child, addr, data); break; /* read the word at location addr in the USER area. */ - case PTRACE_PEEKUSR: - ret = peek_user(child, addr, data); - break; + case PTRACE_PEEKUSR: + ret = peek_user(child, addr, data); + break; - /* when I and D space are separate, this will have to be fixed. */ - case PTRACE_POKETEXT: /* write the word at location addr. */ + /* write the word at location addr. */ + case PTRACE_POKETEXT: case PTRACE_POKEDATA: ret = generic_ptrace_pokedata(child, addr, data); break; - case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ - ret = poke_user(child, addr, data); - break; + /* write the word at location addr in the USER area */ + case PTRACE_POKEUSR: + ret = poke_user(child, addr, data); + break; - case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ - case PTRACE_CONT: { /* restart after signal. */ + /* continue and stop at next (return from) syscall */ + case PTRACE_SYSCALL: + /* restart after signal. */ + case PTRACE_CONT: { ret = -EIO; if (!valid_signal(data)) break; - set_singlestepping(child, 0); - if (request == PTRACE_SYSCALL) { + set_singlestepping(child, 0); + if (request == PTRACE_SYSCALL) set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - } - else { - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - } + else clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->exit_code = data; wake_up_process(child); ret = 0; @@ -91,8 +83,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) } /* - * make the child exit. Best I can do is send it a sigkill. - * perhaps it should be put in the status that it wants to + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to * exit. */ case PTRACE_KILL: { @@ -100,7 +92,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) if (child->exit_state == EXIT_ZOMBIE) /* already dead */ break; - set_singlestepping(child, 0); + set_singlestepping(child, 0); child->exit_code = SIGKILL; wake_up_process(child); break; @@ -111,7 +103,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) if (!valid_signal(data)) break; clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - set_singlestepping(child, 1); + set_singlestepping(child, 1); child->exit_code = data; /* give it a chance to run. */ wake_up_process(child); @@ -119,11 +111,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; } - case PTRACE_DETACH: - /* detach a process that was attached. */ - ret = ptrace_detach(child, data); - break; - #ifdef PTRACE_GETREGS case PTRACE_GETREGS: { /* Get all gp regs from the child. */ if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) { @@ -156,22 +143,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) #endif #ifdef PTRACE_GETFPREGS case PTRACE_GETFPREGS: /* Get the child FPU state. */ - ret = get_fpregs(data, child); + ret = get_fpregs((struct user_i387_struct __user *) data, + child); break; #endif #ifdef PTRACE_SETFPREGS case PTRACE_SETFPREGS: /* Set the child FPU state. */ - ret = set_fpregs(data, child); - break; -#endif -#ifdef PTRACE_GETFPXREGS - case PTRACE_GETFPXREGS: /* Get the child FPU state. */ - ret = get_fpxregs(data, child); - break; -#endif -#ifdef PTRACE_SETFPXREGS - case PTRACE_SETFPXREGS: /* Set the child FPU state. */ - ret = set_fpxregs(data, child); + ret = set_fpregs((struct user_i387_struct __user *) data, + child); break; #endif case PTRACE_GET_THREAD_AREA: @@ -185,14 +164,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; case PTRACE_FAULTINFO: { - /* Take the info from thread->arch->faultinfo, + /* + * Take the info from thread->arch->faultinfo, * but transfer max. sizeof(struct ptrace_faultinfo). * On i386, ptrace_faultinfo is smaller! */ ret = copy_to_user(p, &child->thread.arch.faultinfo, sizeof(struct ptrace_faultinfo)); - if(ret) - break; break; } @@ -200,12 +178,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_LDT: { struct ptrace_ldt ldt; - if(copy_from_user(&ldt, p, sizeof(ldt))){ + if (copy_from_user(&ldt, p, sizeof(ldt))) { ret = -EIO; break; } - /* This one is confusing, so just punt and return -EIO for + /* + * This one is confusing, so just punt and return -EIO for * now */ ret = -EIO; @@ -217,7 +196,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) struct mm_struct *old = child->mm; struct mm_struct *new = proc_mm_get_mm(data); - if(IS_ERR(new)){ + if (IS_ERR(new)) { ret = PTR_ERR(new); break; } @@ -231,20 +210,22 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) } #endif #ifdef PTRACE_ARCH_PRCTL - case PTRACE_ARCH_PRCTL: - /* XXX Calls ptrace on the host - needs some SMP thinking */ - ret = arch_prctl_skas(child, data, (void *) addr); - break; + case PTRACE_ARCH_PRCTL: + /* XXX Calls ptrace on the host - needs some SMP thinking */ + ret = arch_prctl(child, data, (void *) addr); + break; #endif default: ret = ptrace_request(child, request, addr, data); + if (ret == -EIO) + ret = subarch_ptrace(child, request, addr, data); break; } return ret; } -void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs, +void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, int error_code) { struct siginfo info; @@ -260,10 +241,11 @@ void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs, force_sig_info(SIGTRAP, &info, tsk); } -/* XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and +/* + * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check */ -void syscall_trace(union uml_pt_regs *regs, int entryexit) +void syscall_trace(struct uml_pt_regs *regs, int entryexit) { int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit; int tracesysgood; @@ -277,7 +259,7 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit) UPT_SYSCALL_ARG3(regs), UPT_SYSCALL_ARG4(regs)); else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs)), - UPT_SYSCALL_RET(regs)); + UPT_SYSCALL_RET(regs)); } /* Fake a debug trap */ @@ -290,15 +272,18 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit) if (!(current->ptrace & PT_PTRACED)) return; - /* the 0x80 provides a way for the tracing parent to distinguish - between a syscall stop and SIGTRAP delivery */ + /* + * the 0x80 provides a way for the tracing parent to distinguish + * between a syscall stop and SIGTRAP delivery + */ tracesysgood = (current->ptrace & PT_TRACESYSGOOD); ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0)); if (entryexit) /* force do_signal() --> is_syscall() */ set_thread_flag(TIF_SIGPENDING); - /* this isn't the same as continuing with a signal, but it will do + /* + * this isn't the same as continuing with a signal, but it will do * for normal use. strace only continues with a signal if the * stopping signal is not SIGTRAP. -brl */ diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c index 7e4305a1fd3c..04cebcf0679f 100644 --- a/arch/um/kernel/reboot.c +++ b/arch/um/kernel/reboot.c @@ -1,60 +1,53 @@ /* - * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/module.h" #include "linux/sched.h" -#include "asm/smp.h" -#include "kern_util.h" -#include "kern.h" #include "os.h" -#include "mode.h" -#include "choose-mode.h" +#include "skas.h" void (*pm_power_off)(void); -#ifdef CONFIG_SMP -static void kill_idlers(int me) -{ -#ifdef CONFIG_MODE_TT - struct task_struct *p; - int i; - - for(i = 0; i < ARRAY_SIZE(idle_threads); i++){ - p = idle_threads[i]; - if((p != NULL) && (p->thread.mode.tt.extern_pid != me)) - os_kill_process(p->thread.mode.tt.extern_pid, 0); - } -#endif -} -#endif - static void kill_off_processes(void) { - CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas()); -#ifdef CONFIG_SMP - kill_idlers(os_getpid()); -#endif + if(proc_mm) + /* + * FIXME: need to loop over userspace_pids + */ + os_kill_ptraced_process(userspace_pid[0], 1); + else { + struct task_struct *p; + int pid, me; + + me = os_getpid(); + for_each_process(p){ + if(p->mm == NULL) + continue; + + pid = p->mm->context.id.u.pid; + os_kill_ptraced_process(pid, 1); + } + } } void uml_cleanup(void) { - kmalloc_ok = 0; + kmalloc_ok = 0; do_uml_exitcalls(); kill_off_processes(); } void machine_restart(char * __unused) { - uml_cleanup(); - CHOOSE_MODE(reboot_tt(), reboot_skas()); + uml_cleanup(); + reboot_skas(); } void machine_power_off(void) { - uml_cleanup(); - CHOOSE_MODE(halt_tt(), halt_skas()); + uml_cleanup(); + halt_skas(); } void machine_halt(void) diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c index c4020c3d7857..19cb97733937 100644 --- a/arch/um/kernel/signal.c +++ b/arch/um/kernel/signal.c @@ -1,29 +1,17 @@ /* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/stddef.h" -#include "linux/sys.h" -#include "linux/sched.h" -#include "linux/wait.h" -#include "linux/kernel.h" -#include "linux/smp_lock.h" #include "linux/module.h" -#include "linux/slab.h" -#include "linux/tty.h" -#include "linux/binfmts.h" #include "linux/ptrace.h" +#include "linux/sched.h" +#include "asm/siginfo.h" #include "asm/signal.h" -#include "asm/uaccess.h" #include "asm/unistd.h" -#include "asm/ucontext.h" -#include "kern_util.h" -#include "signal_kern.h" -#include "kern.h" #include "frame_kern.h" +#include "kern_util.h" #include "sigcontext.h" -#include "mode.h" EXPORT_SYMBOL(block_signals); EXPORT_SYMBOL(unblock_signals); @@ -46,9 +34,9 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, current_thread_info()->restart_block.fn = do_no_restart_syscall; /* Did we come from a system call? */ - if(PT_REGS_SYSCALL_NR(regs) >= 0){ + if (PT_REGS_SYSCALL_NR(regs) >= 0) { /* If so, check system call restarting.. */ - switch(PT_REGS_SYSCALL_RET(regs)){ + switch(PT_REGS_SYSCALL_RET(regs)) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: PT_REGS_SYSCALL_RET(regs) = -EINTR; @@ -68,17 +56,17 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, } sp = PT_REGS_SP(regs); - if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) + if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) sp = current->sas_ss_sp + current->sas_ss_size; #ifdef CONFIG_ARCH_HAS_SC_SIGNALS - if(!(ka->sa.sa_flags & SA_SIGINFO)) + if (!(ka->sa.sa_flags & SA_SIGINFO)) err = setup_signal_stack_sc(sp, signr, ka, regs, oldset); else #endif err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset); - if(err){ + if (err) { spin_lock_irq(¤t->sighand->siglock); current->blocked = *oldset; recalc_sigpending(); @@ -88,7 +76,7 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); - if(!(ka->sa.sa_flags & SA_NODEFER)) + if (!(ka->sa.sa_flags & SA_NODEFER)) sigaddset(¤t->blocked, signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); @@ -109,14 +97,16 @@ static int kern_do_signal(struct pt_regs *regs) else oldset = ¤t->blocked; - while((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0){ + while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) { handled_sig = 1; /* Whee! Actually deliver the signal. */ - if(!handle_signal(regs, sig, &ka_copy, &info, oldset)){ - /* a signal was successfully delivered; the saved + if (!handle_signal(regs, sig, &ka_copy, &info, oldset)) { + /* + * a signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ + * clear the TIF_RESTORE_SIGMASK flag + */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); break; @@ -124,9 +114,9 @@ static int kern_do_signal(struct pt_regs *regs) } /* Did we come from a system call? */ - if(!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)){ + if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) { /* Restart the system call - no handlers present */ - switch(PT_REGS_SYSCALL_RET(regs)){ + switch(PT_REGS_SYSCALL_RET(regs)) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: @@ -137,22 +127,25 @@ static int kern_do_signal(struct pt_regs *regs) PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall; PT_REGS_RESTART_SYSCALL(regs); break; - } + } } - /* This closes a way to execute a system call on the host. If + /* + * This closes a way to execute a system call on the host. If * you set a breakpoint on a system call instruction and singlestep * from it, the tracing thread used to PTRACE_SINGLESTEP the process * rather than PTRACE_SYSCALL it, allowing the system call to execute * on the host. The tracing thread will check this flag and * PTRACE_SYSCALL if necessary. */ - if(current->ptrace & PT_DTRACE) + if (current->ptrace & PT_DTRACE) current->thread.singlestep_syscall = is_syscall(PT_REGS_IP(¤t->thread.regs)); - /* if there's no signal to deliver, we just put the saved sigmask - * back */ + /* + * if there's no signal to deliver, we just put the saved sigmask + * back + */ if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile index 3e3fa7e7e3cf..0b76d8869c94 100644 --- a/arch/um/kernel/skas/Makefile +++ b/arch/um/kernel/skas/Makefile @@ -1,9 +1,9 @@ # -# Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com) +# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) # Licensed under the GPL # -obj-y := clone.o exec.o mem.o mmu.o process.o syscall.o tlb.o uaccess.o +obj-y := clone.o mmu.o process.o syscall.o uaccess.o # clone.o is in the stub, so it can't be built with profiling # GCC hardened also auto-enables -fpic, but we need %ebx so it can't work -> diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c index 47b812b3bca8..d119f4f7d897 100644 --- a/arch/um/kernel/skas/clone.c +++ b/arch/um/kernel/skas/clone.c @@ -4,6 +4,7 @@ #include <sys/time.h> #include <asm/unistd.h> #include <asm/page.h> +#include "as-layout.h" #include "ptrace_user.h" #include "skas.h" #include "stub-data.h" @@ -21,12 +22,11 @@ void __attribute__ ((__section__ (".__syscall_stub"))) stub_clone_handler(void) { - struct stub_data *data = (struct stub_data *) UML_CONFIG_STUB_DATA; + struct stub_data *data = (struct stub_data *) STUB_DATA; long err; err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, - UML_CONFIG_STUB_DATA + UM_KERN_PAGE_SIZE / 2 - - sizeof(void *)); + STUB_DATA + UM_KERN_PAGE_SIZE / 2 - sizeof(void *)); if(err != 0) goto out; diff --git a/arch/um/kernel/skas/exec.c b/arch/um/kernel/skas/exec.c deleted file mode 100644 index 580eb6468949..000000000000 --- a/arch/um/kernel/skas/exec.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include "linux/kernel.h" -#include "asm/current.h" -#include "asm/page.h" -#include "asm/signal.h" -#include "asm/ptrace.h" -#include "asm/uaccess.h" -#include "asm/mmu_context.h" -#include "tlb.h" -#include "skas.h" -#include "um_mmu.h" -#include "os.h" - -void flush_thread_skas(void) -{ - void *data = NULL; - unsigned long end = proc_mm ? task_size : CONFIG_STUB_START; - int ret; - - ret = unmap(¤t->mm->context.skas.id, 0, end, 1, &data); - if(ret){ - printk("flush_thread_skas - clearing address space failed, " - "err = %d\n", ret); - force_sig(SIGKILL, current); - } - - switch_mm_skas(¤t->mm->context.skas.id); -} - -void start_thread_skas(struct pt_regs *regs, unsigned long eip, - unsigned long esp) -{ - set_fs(USER_DS); - PT_REGS_IP(regs) = eip; - PT_REGS_SP(regs) = esp; -} diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c deleted file mode 100644 index 7c18dfcd7d8e..000000000000 --- a/arch/um/kernel/skas/mem.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include "linux/mm.h" -#include "asm/pgtable.h" -#include "mem_user.h" -#include "skas.h" - -unsigned long set_task_sizes_skas(unsigned long *task_size_out) -{ - /* Round up to the nearest 4M */ - unsigned long host_task_size = ROUND_4M((unsigned long) - &host_task_size); - - if (!skas_needs_stub) - *task_size_out = host_task_size; - else *task_size_out = CONFIG_STUB_START & PGDIR_MASK; - - return host_task_size; -} diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index 2c6d090a2e87..f859ec306cd5 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c @@ -1,20 +1,13 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) +/* + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/sched.h" -#include "linux/list.h" -#include "linux/spinlock.h" -#include "linux/slab.h" -#include "linux/errno.h" #include "linux/mm.h" -#include "asm/current.h" -#include "asm/segment.h" -#include "asm/mmu.h" +#include "linux/sched.h" #include "asm/pgalloc.h" #include "asm/pgtable.h" -#include "asm/ldt.h" +#include "as-layout.h" #include "os.h" #include "skas.h" @@ -41,10 +34,11 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, if (!pte) goto out_pte; - /* There's an interaction between the skas0 stub pages, stack + /* + * There's an interaction between the skas0 stub pages, stack * randomization, and the BUG at the end of exit_mmap. exit_mmap - * checks that the number of page tables freed is the same as had - * been allocated. If the stack is on the last page table page, + * checks that the number of page tables freed is the same as had + * been allocated. If the stack is on the last page table page, * then the stack pte page will be freed, and if not, it won't. To * avoid having to know where the stack is, or if the process mapped * something at the top of its address space for some other reason, @@ -54,76 +48,77 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, * destroy_context_skas. */ - mm->context.skas.last_page_table = pmd_page_vaddr(*pmd); + mm->context.last_page_table = pmd_page_vaddr(*pmd); #ifdef CONFIG_3_LEVEL_PGTABLES - mm->context.skas.last_pmd = (unsigned long) __va(pud_val(*pud)); + mm->context.last_pmd = (unsigned long) __va(pud_val(*pud)); #endif *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); *pte = pte_mkread(*pte); - return(0); + return 0; out_pmd: pud_free(pud); out_pte: pmd_free(pmd); out: - return(-ENOMEM); + return -ENOMEM; } -int init_new_context_skas(struct task_struct *task, struct mm_struct *mm) +int init_new_context(struct task_struct *task, struct mm_struct *mm) { - struct mmu_context_skas *from_mm = NULL; - struct mmu_context_skas *to_mm = &mm->context.skas; + struct mm_context *from_mm = NULL; + struct mm_context *to_mm = &mm->context; unsigned long stack = 0; int ret = -ENOMEM; - if(skas_needs_stub){ + if (skas_needs_stub) { stack = get_zeroed_page(GFP_KERNEL); - if(stack == 0) + if (stack == 0) goto out; - /* This zeros the entry that pgd_alloc didn't, needed since + /* + * This zeros the entry that pgd_alloc didn't, needed since * we are about to reinitialize it, and want mm.nr_ptes to * be accurate. */ mm->pgd[USER_PTRS_PER_PGD] = __pgd(0); - ret = init_stub_pte(mm, CONFIG_STUB_CODE, + ret = init_stub_pte(mm, STUB_CODE, (unsigned long) &__syscall_stub_start); - if(ret) + if (ret) goto out_free; - ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack); - if(ret) + ret = init_stub_pte(mm, STUB_DATA, stack); + if (ret) goto out_free; mm->nr_ptes--; } to_mm->id.stack = stack; - if(current->mm != NULL && current->mm != &init_mm) - from_mm = ¤t->mm->context.skas; + if (current->mm != NULL && current->mm != &init_mm) + from_mm = ¤t->mm->context; - if(proc_mm){ + if (proc_mm) { ret = new_mm(stack); - if(ret < 0){ - printk("init_new_context_skas - new_mm failed, " - "errno = %d\n", ret); + if (ret < 0) { + printk(KERN_ERR "init_new_context_skas - " + "new_mm failed, errno = %d\n", ret); goto out_free; } to_mm->id.u.mm_fd = ret; } else { - if(from_mm) + if (from_mm) to_mm->id.u.pid = copy_context_skas0(stack, from_mm->id.u.pid); else to_mm->id.u.pid = start_userspace(stack); } ret = init_new_ldt(to_mm, from_mm); - if(ret < 0){ - printk("init_new_context_skas - init_ldt" + if (ret < 0) { + printk(KERN_ERR "init_new_context_skas - init_ldt" " failed, errno = %d\n", ret); goto out_free; } @@ -131,22 +126,22 @@ int init_new_context_skas(struct task_struct *task, struct mm_struct *mm) return 0; out_free: - if(to_mm->id.stack != 0) + if (to_mm->id.stack != 0) free_page(to_mm->id.stack); out: return ret; } -void destroy_context_skas(struct mm_struct *mm) +void destroy_context(struct mm_struct *mm) { - struct mmu_context_skas *mmu = &mm->context.skas; + struct mm_context *mmu = &mm->context; - if(proc_mm) + if (proc_mm) os_close_file(mmu->id.u.mm_fd); else os_kill_ptraced_process(mmu->id.u.pid, 1); - if(!proc_mm || !ptrace_faultinfo){ + if (!proc_mm || !ptrace_faultinfo) { free_page(mmu->id.stack); pte_lock_deinit(virt_to_page(mmu->last_page_table)); pte_free_kernel((pte_t *) mmu->last_page_table); @@ -155,4 +150,6 @@ void destroy_context_skas(struct mm_struct *mm) pmd_free((pmd_t *) mmu->last_pmd); #endif } + + free_ldt(mmu); } diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 48051a98525f..fce389c2342f 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -1,146 +1,26 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/sched.h" -#include "linux/slab.h" -#include "linux/ptrace.h" -#include "linux/proc_fs.h" -#include "linux/file.h" -#include "linux/errno.h" #include "linux/init.h" -#include "asm/uaccess.h" -#include "asm/atomic.h" -#include "kern_util.h" +#include "linux/sched.h" #include "as-layout.h" -#include "skas.h" #include "os.h" -#include "tlb.h" -#include "kern.h" -#include "mode.h" -#include "registers.h" - -void switch_to_skas(void *prev, void *next) -{ - struct task_struct *from, *to; - - from = prev; - to = next; - - /* XXX need to check runqueues[cpu].idle */ - if(current->pid == 0) - switch_timers(0); - - switch_threads(&from->thread.mode.skas.switch_buf, - &to->thread.mode.skas.switch_buf); - - arch_switch_to_skas(current->thread.prev_sched, current); - - if(current->pid == 0) - switch_timers(1); -} - -extern void schedule_tail(struct task_struct *prev); - -/* This is called magically, by its address being stuffed in a jmp_buf - * and being longjmp-d to. - */ -void new_thread_handler(void) -{ - int (*fn)(void *), n; - void *arg; - - if(current->thread.prev_sched != NULL) - schedule_tail(current->thread.prev_sched); - current->thread.prev_sched = NULL; - - fn = current->thread.request.u.thread.proc; - arg = current->thread.request.u.thread.arg; - - /* The return value is 1 if the kernel thread execs a process, - * 0 if it just exits - */ - n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); - if(n == 1){ - /* Handle any immediate reschedules or signals */ - interrupt_end(); - userspace(¤t->thread.regs.regs); - } - else do_exit(0); -} - -void release_thread_skas(struct task_struct *task) -{ -} - -/* Called magically, see new_thread_handler above */ -void fork_handler(void) -{ - force_flush_all(); - if(current->thread.prev_sched == NULL) - panic("blech"); - - schedule_tail(current->thread.prev_sched); - - /* XXX: if interrupt_end() calls schedule, this call to - * arch_switch_to_skas isn't needed. We could want to apply this to - * improve performance. -bb */ - arch_switch_to_skas(current->thread.prev_sched, current); - - current->thread.prev_sched = NULL; - -/* Handle any immediate reschedules or signals */ - interrupt_end(); - - userspace(¤t->thread.regs.regs); -} - -int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, - unsigned long stack_top, struct task_struct * p, - struct pt_regs *regs) -{ - void (*handler)(void); - - if(current->thread.forking){ - memcpy(&p->thread.regs.regs.skas, ®s->regs.skas, - sizeof(p->thread.regs.regs.skas)); - REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0); - if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp; - - handler = fork_handler; - - arch_copy_thread(¤t->thread.arch, &p->thread.arch); - } - else { - init_thread_registers(&p->thread.regs.regs); - p->thread.request.u.thread = current->thread.request.u.thread; - handler = new_thread_handler; - } - - new_thread(task_stack_page(p), &p->thread.mode.skas.switch_buf, - handler); - return(0); -} +#include "skas.h" int new_mm(unsigned long stack) { int fd; fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0); - if(fd < 0) - return(fd); + if (fd < 0) + return fd; - if(skas_needs_stub) - map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack); + if (skas_needs_stub) + map_stub_pages(fd, STUB_CODE, STUB_DATA, stack); - return(fd); -} - -void init_idle_skas(void) -{ - cpu_tasks[current_thread->cpu].pid = os_getpid(); - default_idle(); + return fd; } extern void start_kernel(void); @@ -158,67 +38,32 @@ static int __init start_kernel_proc(void *unused) cpu_online_map = cpumask_of_cpu(0); #endif start_kernel(); - return(0); + return 0; } extern int userspace_pid[]; extern char cpu0_irqstack[]; -int __init start_uml_skas(void) +int __init start_uml(void) { stack_protections((unsigned long) &cpu0_irqstack); set_sigstack(cpu0_irqstack, THREAD_SIZE); - if(proc_mm) + if (proc_mm) userspace_pid[0] = start_userspace(0); init_new_thread_signals(); init_task.thread.request.u.thread.proc = start_kernel_proc; init_task.thread.request.u.thread.arg = NULL; - return(start_idle_thread(task_stack_page(&init_task), - &init_task.thread.mode.skas.switch_buf)); -} - -int external_pid_skas(struct task_struct *task) -{ - /* FIXME: Need to look up userspace_pid by cpu */ - return(userspace_pid[0]); -} - -int thread_pid_skas(struct task_struct *task) -{ - /* FIXME: Need to look up userspace_pid by cpu */ - return(userspace_pid[0]); -} - -void kill_off_processes_skas(void) -{ - if(proc_mm) - /* - * FIXME: need to loop over userspace_pids in - * kill_off_processes_skas - */ - os_kill_ptraced_process(userspace_pid[0], 1); - else { - struct task_struct *p; - int pid, me; - - me = os_getpid(); - for_each_process(p){ - if(p->mm == NULL) - continue; - - pid = p->mm->context.skas.id.u.pid; - os_kill_ptraced_process(pid, 1); - } - } + return start_idle_thread(task_stack_page(&init_task), + &init_task.thread.switch_buf); } unsigned long current_stub_stack(void) { - if(current->mm == NULL) - return(0); + if (current->mm == NULL) + return 0; - return(current->mm->context.skas.id.stack); + return current->mm->context.id.stack; } diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index 0ae4eea21be4..50b476f2b38d 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c @@ -1,19 +1,15 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/sys.h" +#include "linux/kernel.h" #include "linux/ptrace.h" -#include "asm/errno.h" -#include "asm/unistd.h" -#include "asm/ptrace.h" -#include "asm/current.h" -#include "sysdep/syscalls.h" #include "kern_util.h" -#include "syscall.h" +#include "sysdep/ptrace.h" +#include "sysdep/syscalls.h" -void handle_syscall(union uml_pt_regs *r) +void handle_syscall(struct uml_pt_regs *r) { struct pt_regs *regs = container_of(r, struct pt_regs, regs); long result; @@ -24,7 +20,8 @@ void handle_syscall(union uml_pt_regs *r) current->thread.nsyscalls++; nsyscalls++; - /* This should go in the declaration of syscall, but when I do that, + /* + * This should go in the declaration of syscall, but when I do that, * strace -f -c bash -c 'ls ; ls' breaks, sometimes not tracing * children at all, sometimes hanging when bash doesn't see the first * ls exit. @@ -33,11 +30,11 @@ void handle_syscall(union uml_pt_regs *r) * in case it's a compiler bug. */ syscall = UPT_SYSCALL_NR(r); - if((syscall >= NR_syscalls) || (syscall < 0)) + if ((syscall >= NR_syscalls) || (syscall < 0)) result = -ENOSYS; else result = EXECUTE_SYSCALL(syscall, regs); - REGS_SET_SYSCALL_RETURN(r->skas.regs, result); + REGS_SET_SYSCALL_RETURN(r->gp, result); syscall_trace(r, 1); } diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c deleted file mode 100644 index c0f0693743ba..000000000000 --- a/arch/um/kernel/skas/tlb.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Copyright 2003 PathScale, Inc. - * Licensed under the GPL - */ - -#include "linux/stddef.h" -#include "linux/sched.h" -#include "linux/mm.h" -#include "asm/page.h" -#include "asm/pgtable.h" -#include "asm/mmu.h" -#include "mem_user.h" -#include "mem.h" -#include "skas.h" -#include "os.h" -#include "tlb.h" - -static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, - int finished, void **flush) -{ - struct host_vm_op *op; - int i, ret = 0; - - for(i = 0; i <= last && !ret; i++){ - op = &ops[i]; - switch(op->type){ - case MMAP: - ret = map(&mmu->skas.id, op->u.mmap.addr, - op->u.mmap.len, op->u.mmap.prot, - op->u.mmap.fd, op->u.mmap.offset, finished, - flush); - break; - case MUNMAP: - ret = unmap(&mmu->skas.id, op->u.munmap.addr, - op->u.munmap.len, finished, flush); - break; - case MPROTECT: - ret = protect(&mmu->skas.id, op->u.mprotect.addr, - op->u.mprotect.len, op->u.mprotect.prot, - finished, flush); - break; - default: - printk("Unknown op type %d in do_ops\n", op->type); - break; - } - } - - return ret; -} - -extern int proc_mm; - -static void fix_range(struct mm_struct *mm, unsigned long start_addr, - unsigned long end_addr, int force) -{ - if(!proc_mm && (end_addr > CONFIG_STUB_START)) - end_addr = CONFIG_STUB_START; - - fix_range_common(mm, start_addr, end_addr, force, do_ops); -} - -void __flush_tlb_one_skas(unsigned long addr) -{ - flush_tlb_kernel_range_common(addr, addr + PAGE_SIZE); -} - -void flush_tlb_range_skas(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - if(vma->vm_mm == NULL) - flush_tlb_kernel_range_common(start, end); - else fix_range(vma->vm_mm, start, end, 0); -} - -void flush_tlb_mm_skas(struct mm_struct *mm) -{ - unsigned long end; - - /* Don't bother flushing if this address space is about to be - * destroyed. - */ - if(atomic_read(&mm->mm_users) == 0) - return; - - end = proc_mm ? task_size : CONFIG_STUB_START; - fix_range(mm, 0, end, 0); -} - -void force_flush_all_skas(void) -{ - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma = mm->mmap; - - while(vma != NULL) { - fix_range(mm, vma->vm_start, vma->vm_end, 1); - vma = vma->vm_next; - } -} - -void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address) -{ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - struct mm_struct *mm = vma->vm_mm; - void *flush = NULL; - int r, w, x, prot, err = 0; - struct mm_id *mm_id; - - pgd = pgd_offset(mm, address); - if(!pgd_present(*pgd)) - goto kill; - - pud = pud_offset(pgd, address); - if(!pud_present(*pud)) - goto kill; - - pmd = pmd_offset(pud, address); - if(!pmd_present(*pmd)) - goto kill; - - pte = pte_offset_kernel(pmd, address); - - r = pte_read(*pte); - w = pte_write(*pte); - x = pte_exec(*pte); - if (!pte_young(*pte)) { - r = 0; - w = 0; - } else if (!pte_dirty(*pte)) { - w = 0; - } - - mm_id = &mm->context.skas.id; - prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | - (x ? UM_PROT_EXEC : 0)); - if(pte_newpage(*pte)){ - if(pte_present(*pte)){ - unsigned long long offset; - int fd; - - fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset); - err = map(mm_id, address, PAGE_SIZE, prot, fd, offset, - 1, &flush); - } - else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush); - } - else if(pte_newprot(*pte)) - err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush); - - if(err) - goto kill; - - *pte = pte_mkuptodate(*pte); - - return; - -kill: - printk("Failed to flush page for address 0x%lx\n", address); - force_sig(SIGKILL, current); -} - diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index 8912cec0fe43..1d8b119f2d0e 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c @@ -1,18 +1,14 @@ /* - * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/compiler.h" -#include "linux/stddef.h" -#include "linux/kernel.h" -#include "linux/string.h" -#include "linux/fs.h" -#include "linux/hardirq.h" +#include "linux/err.h" #include "linux/highmem.h" +#include "linux/mm.h" +#include "asm/current.h" #include "asm/page.h" #include "asm/pgtable.h" -#include "asm/uaccess.h" #include "kern_util.h" #include "os.h" @@ -27,16 +23,16 @@ static unsigned long maybe_map(unsigned long virt, int is_write) void *phys = um_virt_to_phys(current, virt, &pte); int dummy_code; - if(IS_ERR(phys) || (is_write && !pte_write(pte))){ + if (IS_ERR(phys) || (is_write && !pte_write(pte))) { err = handle_page_fault(virt, 0, is_write, 1, &dummy_code); - if(err) - return(-1UL); + if (err) + return -1UL; phys = um_virt_to_phys(current, virt, NULL); } - if(IS_ERR(phys)) - phys = (void *) -1; + if (IS_ERR(phys)) + phys = (void *) -1; - return((unsigned long) phys); + return (unsigned long) phys; } static int do_op_one_page(unsigned long addr, int len, int is_write, @@ -46,17 +42,18 @@ static int do_op_one_page(unsigned long addr, int len, int is_write, int n; addr = maybe_map(addr, is_write); - if(addr == -1UL) - return(-1); + if (addr == -1UL) + return -1; page = phys_to_page(addr); - addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) + (addr & ~PAGE_MASK); + addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) + + (addr & ~PAGE_MASK); n = (*op)(addr, len, arg); kunmap_atomic(page, KM_UML_USERCOPY); - return(n); + return n; } static void do_buffer_op(void *jmpbuf, void *arg_ptr) @@ -81,21 +78,21 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr) current->thread.fault_catcher = jmpbuf; n = do_op_one_page(addr, size, is_write, op, arg); - if(n != 0){ + if (n != 0) { *res = (n < 0 ? remain : 0); goto out; } addr += size; remain -= size; - if(remain == 0){ + if (remain == 0) { *res = 0; goto out; } - while(addr < ((addr + remain) & PAGE_MASK)){ + while(addr < ((addr + remain) & PAGE_MASK)) { n = do_op_one_page(addr, PAGE_SIZE, is_write, op, arg); - if(n != 0){ + if (n != 0) { *res = (n < 0 ? remain : 0); goto out; } @@ -103,13 +100,13 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr) addr += PAGE_SIZE; remain -= PAGE_SIZE; } - if(remain == 0){ + if (remain == 0) { *res = 0; goto out; } n = do_op_one_page(addr, remain, is_write, op, arg); - if(n != 0) + if (n != 0) *res = (n < 0 ? remain : 0); else *res = 0; out: @@ -124,10 +121,10 @@ static int buffer_op(unsigned long addr, int len, int is_write, faulted = setjmp_wrapper(do_buffer_op, addr, len, is_write, op, arg, &res); - if(!faulted) - return(res); + if (!faulted) + return res; - return(addr + len - (unsigned long) current->thread.fault_addr); + return addr + len - (unsigned long) current->thread.fault_addr; } static int copy_chunk_from_user(unsigned long from, int len, void *arg) @@ -136,19 +133,19 @@ static int copy_chunk_from_user(unsigned long from, int len, void *arg) memcpy((void *) to, (void *) from, len); *to_ptr += len; - return(0); + return 0; } -int copy_from_user_skas(void *to, const void __user *from, int n) +int copy_from_user(void *to, const void __user *from, int n) { - if(segment_eq(get_fs(), KERNEL_DS)){ + if (segment_eq(get_fs(), KERNEL_DS)) { memcpy(to, (__force void*)from, n); - return(0); + return 0; } - return(access_ok(VERIFY_READ, from, n) ? + return access_ok(VERIFY_READ, from, n) ? buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to): - n); + n; } static int copy_chunk_to_user(unsigned long to, int len, void *arg) @@ -157,19 +154,19 @@ static int copy_chunk_to_user(unsigned long to, int len, void *arg) memcpy((void *) to, (void *) from, len); *from_ptr += len; - return(0); + return 0; } -int copy_to_user_skas(void __user *to, const void *from, int n) +int copy_to_user(void __user *to, const void *from, int n) { - if(segment_eq(get_fs(), KERNEL_DS)){ - memcpy((__force void*)to, from, n); - return(0); + if (segment_eq(get_fs(), KERNEL_DS)) { + memcpy((__force void *) to, from, n); + return 0; } - return(access_ok(VERIFY_WRITE, to, n) ? + return access_ok(VERIFY_WRITE, to, n) ? buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) : - n); + n; } static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) @@ -181,51 +178,51 @@ static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) n = strnlen(to, len); *to_ptr += n; - if(n < len) - return(1); - return(0); + if (n < len) + return 1; + return 0; } -int strncpy_from_user_skas(char *dst, const char __user *src, int count) +int strncpy_from_user(char *dst, const char __user *src, int count) { int n; char *ptr = dst; - if(segment_eq(get_fs(), KERNEL_DS)){ - strncpy(dst, (__force void*)src, count); - return(strnlen(dst, count)); + if (segment_eq(get_fs(), KERNEL_DS)) { + strncpy(dst, (__force void *) src, count); + return strnlen(dst, count); } - if(!access_ok(VERIFY_READ, src, 1)) - return(-EFAULT); + if (!access_ok(VERIFY_READ, src, 1)) + return -EFAULT; n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user, &ptr); - if(n != 0) - return(-EFAULT); - return(strnlen(dst, count)); + if (n != 0) + return -EFAULT; + return strnlen(dst, count); } static int clear_chunk(unsigned long addr, int len, void *unused) { memset((void *) addr, 0, len); - return(0); + return 0; } -int __clear_user_skas(void __user *mem, int len) +int __clear_user(void __user *mem, int len) { - return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL)); + return buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL); } -int clear_user_skas(void __user *mem, int len) +int clear_user(void __user *mem, int len) { - if(segment_eq(get_fs(), KERNEL_DS)){ + if (segment_eq(get_fs(), KERNEL_DS)) { memset((__force void*)mem, 0, len); - return(0); + return 0; } - return(access_ok(VERIFY_WRITE, mem, len) ? - buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len); + return access_ok(VERIFY_WRITE, mem, len) ? + buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len; } static int strnlen_chunk(unsigned long str, int len, void *arg) @@ -235,31 +232,20 @@ static int strnlen_chunk(unsigned long str, int len, void *arg) n = strnlen((void *) str, len); *len_ptr += n; - if(n < len) - return(1); - return(0); + if (n < len) + return 1; + return 0; } -int strnlen_user_skas(const void __user *str, int len) +int strnlen_user(const void __user *str, int len) { int count = 0, n; - if(segment_eq(get_fs(), KERNEL_DS)) - return(strnlen((__force char*)str, len) + 1); + if (segment_eq(get_fs(), KERNEL_DS)) + return strnlen((__force char*)str, len) + 1; n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count); - if(n == 0) - return(count + 1); - return(-EFAULT); + if (n == 0) + return count + 1; + return -EFAULT; } - -/* - * 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/kernel/smp.c b/arch/um/kernel/smp.c index e6a7778006ad..36d89cf8d20b 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -56,12 +56,12 @@ void smp_send_stop(void) int i; printk(KERN_INFO "Stopping all CPUs..."); - for(i = 0; i < num_online_cpus(); i++){ - if(i == current_thread->cpu) + for (i = 0; i < num_online_cpus(); i++) { + if (i == current_thread->cpu) continue; os_write_file(cpu_data[i].ipi_pipe[1], "S", 1); } - printk("done\n"); + printk(KERN_INFO "done\n"); } static cpumask_t smp_commenced_mask = CPU_MASK_NONE; @@ -72,7 +72,7 @@ static int idle_proc(void *cpup) int cpu = (int) cpup, err; err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1); - if(err < 0) + if (err < 0) panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err); os_set_fd_async(cpu_data[cpu].ipi_pipe[0], @@ -80,7 +80,7 @@ static int idle_proc(void *cpup) wmb(); if (cpu_test_and_set(cpu, cpu_callin_map)) { - printk("huh, CPU#%d already present??\n", cpu); + printk(KERN_ERR "huh, CPU#%d already present??\n", cpu); BUG(); } @@ -95,12 +95,11 @@ static int idle_proc(void *cpup) static struct task_struct *idle_thread(int cpu) { struct task_struct *new_task; - unsigned char c; current->thread.request.u.thread.proc = idle_proc; current->thread.request.u.thread.arg = (void *) cpu; new_task = fork_idle(cpu); - if(IS_ERR(new_task)) + if (IS_ERR(new_task)) panic("copy_process failed in idle_thread, error = %ld", PTR_ERR(new_task)); @@ -108,9 +107,7 @@ static struct task_struct *idle_thread(int cpu) { .pid = new_task->thread.mode.tt.extern_pid, .task = new_task } ); idle_threads[cpu] = new_task; - CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, - sizeof(c)), - ({ panic("skas mode doesn't support SMP"); })); + panic("skas mode doesn't support SMP"); return new_task; } @@ -129,14 +126,14 @@ void smp_prepare_cpus(unsigned int maxcpus) cpu_set(me, cpu_callin_map); err = os_pipe(cpu_data[me].ipi_pipe, 1, 1); - if(err < 0) + if (err < 0) panic("CPU#0 failed to create IPI pipe, errno = %d", -err); os_set_fd_async(cpu_data[me].ipi_pipe[0], current->thread.mode.tt.extern_pid); - for(cpu = 1; cpu < ncpus; cpu++){ - printk("Booting processor %d...\n", cpu); + for (cpu = 1; cpu < ncpus; cpu++) { + printk(KERN_INFO "Booting processor %d...\n", cpu); idle = idle_thread(cpu); @@ -147,8 +144,8 @@ void smp_prepare_cpus(unsigned int maxcpus) cpu_relax(); if (cpu_isset(cpu, cpu_callin_map)) - printk("done\n"); - else printk("failed\n"); + printk(KERN_INFO "done\n"); + else printk(KERN_INFO "failed\n"); } } @@ -190,13 +187,14 @@ void IPI_handler(int cpu) break; case 'S': - printk("CPU#%d stopping\n", cpu); - while(1) + printk(KERN_INFO "CPU#%d stopping\n", cpu); + while (1) pause(); break; default: - printk("CPU#%d received unknown IPI [%c]!\n", cpu, c); + printk(KERN_ERR "CPU#%d received unknown IPI [%c]!\n", + cpu, c); break; } } diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 7b3b67333ff3..b9d92b2089ae 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c @@ -1,27 +1,17 @@ /* - * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/sched.h" #include "linux/file.h" -#include "linux/smp_lock.h" -#include "linux/mm.h" #include "linux/fs.h" +#include "linux/mm.h" +#include "linux/sched.h" #include "linux/utsname.h" -#include "linux/msg.h" -#include "linux/shm.h" -#include "linux/sys.h" -#include "linux/syscalls.h" -#include "linux/unistd.h" -#include "linux/slab.h" -#include "linux/utime.h" +#include "asm/current.h" #include "asm/mman.h" #include "asm/uaccess.h" -#include "kern_util.h" -#include "sysdep/syscalls.h" -#include "mode_kern.h" -#include "choose-mode.h" +#include "asm/unistd.h" /* Unlocked, I don't care if this is a bit off */ int nsyscalls = 0; @@ -34,7 +24,7 @@ long sys_fork(void) ret = do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs), ¤t->thread.regs, 0, NULL, NULL); current->thread.forking = 0; - return(ret); + return ret; } long sys_vfork(void) @@ -46,7 +36,7 @@ long sys_vfork(void) UPT_SP(¤t->thread.regs.regs), ¤t->thread.regs, 0, NULL, NULL); current->thread.forking = 0; - return(ret); + return ret; } /* common code for old and new mmaps */ @@ -92,15 +82,15 @@ long old_mmap(unsigned long addr, unsigned long len, */ long sys_pipe(unsigned long __user * fildes) { - int fd[2]; - long error; + int fd[2]; + long error; - error = do_pipe(fd); - if (!error) { + error = do_pipe(fd); + if (!error) { if (copy_to_user(fildes, fd, sizeof(fd))) - error = -EFAULT; - } - return error; + error = -EFAULT; + } + return error; } @@ -124,7 +114,7 @@ long sys_olduname(struct oldold_utsname __user * name) if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; - down_read(&uts_sem); + down_read(&uts_sem); error = __copy_to_user(&name->sysname, &utsname()->sysname, __OLD_UTS_LEN); diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 259c49da7ff5..1ac746a9eae1 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -1,189 +1,126 @@ /* - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/kernel.h" -#include "linux/module.h" -#include "linux/unistd.h" -#include "linux/stddef.h" -#include "linux/spinlock.h" -#include "linux/time.h" -#include "linux/sched.h" +#include "linux/clockchips.h" #include "linux/interrupt.h" -#include "linux/init.h" -#include "linux/delay.h" -#include "linux/hrtimer.h" +#include "linux/jiffies.h" +#include "linux/threads.h" #include "asm/irq.h" #include "asm/param.h" -#include "asm/current.h" #include "kern_util.h" -#include "mode.h" #include "os.h" -int hz(void) -{ - return(HZ); -} - /* * Scheduler clock - returns current time in nanosec units. */ unsigned long long sched_clock(void) { - return (unsigned long long)jiffies_64 * (1000000000 / HZ); + return (unsigned long long)jiffies_64 * (NSEC_PER_SEC / HZ); } -#ifdef CONFIG_UML_REAL_TIME_CLOCK -static unsigned long long prev_nsecs[NR_CPUS]; -static long long delta[NR_CPUS]; /* Deviation per interval */ -#endif +void timer_handler(int sig, struct uml_pt_regs *regs) +{ + unsigned long flags; + + local_irq_save(flags); + do_IRQ(TIMER_IRQ, regs); + local_irq_restore(flags); +} -void timer_irq(union uml_pt_regs *regs) +static void itimer_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) { - unsigned long long ticks = 0; -#ifdef CONFIG_UML_REAL_TIME_CLOCK - int c = cpu(); - if(prev_nsecs[c]){ - /* We've had 1 tick */ - unsigned long long nsecs = os_nsecs(); - - delta[c] += nsecs - prev_nsecs[c]; - prev_nsecs[c] = nsecs; - - /* Protect against the host clock being set backwards */ - if(delta[c] < 0) - delta[c] = 0; - - ticks += (delta[c] * HZ) / BILLION; - delta[c] -= (ticks * BILLION) / HZ; - } - else prev_nsecs[c] = os_nsecs(); -#else - ticks = 1; -#endif - while(ticks > 0){ - do_IRQ(TIMER_IRQ, regs); - ticks--; + switch(mode) { + case CLOCK_EVT_MODE_PERIODIC: + set_interval(); + break; + + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_ONESHOT: + disable_timer(); + break; + + case CLOCK_EVT_MODE_RESUME: + break; } } -/* Protects local_offset */ -static DEFINE_SPINLOCK(timer_spinlock); -static unsigned long long local_offset = 0; - -static inline unsigned long long get_time(void) +static int itimer_next_event(unsigned long delta, + struct clock_event_device *evt) { - unsigned long long nsecs; - unsigned long flags; - - spin_lock_irqsave(&timer_spinlock, flags); - nsecs = os_nsecs(); - nsecs += local_offset; - spin_unlock_irqrestore(&timer_spinlock, flags); - - return nsecs; + return timer_one_shot(delta + 1); } -irqreturn_t um_timer(int irq, void *dev) +static struct clock_event_device itimer_clockevent = { + .name = "itimer", + .rating = 250, + .cpumask = CPU_MASK_ALL, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_mode = itimer_set_mode, + .set_next_event = itimer_next_event, + .shift = 32, + .irq = 0, +}; + +static irqreturn_t um_timer(int irq, void *dev) { - unsigned long long nsecs; - unsigned long flags; - - write_seqlock_irqsave(&xtime_lock, flags); - - do_timer(1); - -#ifdef CONFIG_UML_REAL_TIME_CLOCK - nsecs = get_time(); -#else - nsecs = (unsigned long long) xtime.tv_sec * BILLION + xtime.tv_nsec + - BILLION / HZ; -#endif - xtime.tv_sec = nsecs / NSEC_PER_SEC; - xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC; - - write_sequnlock_irqrestore(&xtime_lock, flags); + (*itimer_clockevent.event_handler)(&itimer_clockevent); return IRQ_HANDLED; } -static void register_timer(void) +static cycle_t itimer_read(void) +{ + return os_nsecs(); +} + +static struct clocksource itimer_clocksource = { + .name = "itimer", + .rating = 300, + .read = itimer_read, + .mask = CLOCKSOURCE_MASK(64), + .mult = 1, + .shift = 0, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static void __init setup_itimer(void) { int err; err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL); - if(err != 0) + if (err != 0) printk(KERN_ERR "register_timer : request_irq failed - " "errno = %d\n", -err); - err = set_interval(1); - if(err != 0) - printk(KERN_ERR "register_timer : set_interval failed - " - "errno = %d\n", -err); + itimer_clockevent.mult = div_sc(HZ, NSEC_PER_SEC, 32); + itimer_clockevent.max_delta_ns = + clockevent_delta2ns(60 * HZ, &itimer_clockevent); + itimer_clockevent.min_delta_ns = + clockevent_delta2ns(1, &itimer_clockevent); + err = clocksource_register(&itimer_clocksource); + if (err) { + printk(KERN_ERR "clocksource_register returned %d\n", err); + return; + } + clockevents_register_device(&itimer_clockevent); } extern void (*late_time_init)(void); -void time_init(void) +void __init time_init(void) { long long nsecs; - nsecs = os_nsecs(); - set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, - -nsecs % BILLION); - set_normalized_timespec(&xtime, nsecs / BILLION, nsecs % BILLION); - late_time_init = register_timer; -} - -void do_gettimeofday(struct timeval *tv) -{ -#ifdef CONFIG_UML_REAL_TIME_CLOCK - unsigned long long nsecs = get_time(); -#else - unsigned long long nsecs = (unsigned long long) xtime.tv_sec * BILLION + - xtime.tv_nsec; -#endif - tv->tv_sec = nsecs / NSEC_PER_SEC; - /* Careful about calculations here - this was originally done as - * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC - * which gave bogus (> 1000000) values. Dunno why, suspect gcc - * (4.0.0) miscompiled it, or there's a subtle 64/32-bit conversion - * problem that I missed. - */ - nsecs -= tv->tv_sec * NSEC_PER_SEC; - tv->tv_usec = (unsigned long) nsecs / NSEC_PER_USEC; -} - -static inline void set_time(unsigned long long nsecs) -{ - unsigned long long now; - unsigned long flags; - - spin_lock_irqsave(&timer_spinlock, flags); - now = os_nsecs(); - local_offset = nsecs - now; - spin_unlock_irqrestore(&timer_spinlock, flags); - - clock_was_set(); -} - -int do_settimeofday(struct timespec *tv) -{ - set_time((unsigned long long) tv->tv_sec * NSEC_PER_SEC + tv->tv_nsec); - - return 0; -} + timer_init(); -void timer_handler(int sig, union uml_pt_regs *regs) -{ - if(current_thread->cpu == 0) - timer_irq(regs); - local_irq_disable(); - irq_enter(); - update_process_times(CHOOSE_MODE( - (UPT_SC(regs) && user_context(UPT_SP(regs))), - (regs)->skas.is_user)); - irq_exit(); - local_irq_enable(); + nsecs = os_nsecs(); + set_normalized_timespec(&wall_to_monotonic, -nsecs / NSEC_PER_SEC, + -nsecs % NSEC_PER_SEC); + set_normalized_timespec(&xtime, nsecs / NSEC_PER_SEC, + nsecs % NSEC_PER_SEC); + late_time_init = setup_itimer; } diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 8a8d52851443..f4a0e407eee4 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -1,130 +1,182 @@ /* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ #include "linux/mm.h" -#include "asm/page.h" -#include "asm/pgalloc.h" #include "asm/pgtable.h" #include "asm/tlbflush.h" -#include "choose-mode.h" -#include "mode_kern.h" #include "as-layout.h" -#include "tlb.h" -#include "mem.h" #include "mem_user.h" #include "os.h" +#include "skas.h" +#include "tlb.h" + +struct host_vm_change { + struct host_vm_op { + enum { NONE, MMAP, MUNMAP, MPROTECT } type; + union { + struct { + unsigned long addr; + unsigned long len; + unsigned int prot; + int fd; + __u64 offset; + } mmap; + struct { + unsigned long addr; + unsigned long len; + } munmap; + struct { + unsigned long addr; + unsigned long len; + unsigned int prot; + } mprotect; + } u; + } ops[1]; + int index; + struct mm_id *id; + void *data; + int force; +}; + +#define INIT_HVC(mm, force) \ + ((struct host_vm_change) \ + { .ops = { { .type = NONE } }, \ + .id = &mm->context.id, \ + .data = NULL, \ + .index = 0, \ + .force = force }) + +static int do_ops(struct host_vm_change *hvc, int end, + int finished) +{ + struct host_vm_op *op; + int i, ret = 0; + + for (i = 0; i < end && !ret; i++) { + op = &hvc->ops[i]; + switch(op->type) { + case MMAP: + ret = map(hvc->id, op->u.mmap.addr, op->u.mmap.len, + op->u.mmap.prot, op->u.mmap.fd, + op->u.mmap.offset, finished, &hvc->data); + break; + case MUNMAP: + ret = unmap(hvc->id, op->u.munmap.addr, + op->u.munmap.len, finished, &hvc->data); + break; + case MPROTECT: + ret = protect(hvc->id, op->u.mprotect.addr, + op->u.mprotect.len, op->u.mprotect.prot, + finished, &hvc->data); + break; + default: + printk(KERN_ERR "Unknown op type %d in do_ops\n", + op->type); + break; + } + } + + return ret; +} static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, - unsigned int prot, struct host_vm_op *ops, int *index, - int last_filled, union mm_context *mmu, void **flush, - int (*do_ops)(union mm_context *, struct host_vm_op *, - int, int, void **)) + unsigned int prot, struct host_vm_change *hvc) { __u64 offset; struct host_vm_op *last; int fd, ret = 0; fd = phys_mapping(phys, &offset); - if(*index != -1){ - last = &ops[*index]; - if((last->type == MMAP) && + if (hvc->index != 0) { + last = &hvc->ops[hvc->index - 1]; + if ((last->type == MMAP) && (last->u.mmap.addr + last->u.mmap.len == virt) && (last->u.mmap.prot == prot) && (last->u.mmap.fd == fd) && - (last->u.mmap.offset + last->u.mmap.len == offset)){ + (last->u.mmap.offset + last->u.mmap.len == offset)) { last->u.mmap.len += len; return 0; } } - if(*index == last_filled){ - ret = (*do_ops)(mmu, ops, last_filled, 0, flush); - *index = -1; + if (hvc->index == ARRAY_SIZE(hvc->ops)) { + ret = do_ops(hvc, ARRAY_SIZE(hvc->ops), 0); + hvc->index = 0; } - ops[++*index] = ((struct host_vm_op) { .type = MMAP, - .u = { .mmap = { - .addr = virt, - .len = len, - .prot = prot, - .fd = fd, - .offset = offset } + hvc->ops[hvc->index++] = ((struct host_vm_op) + { .type = MMAP, + .u = { .mmap = { .addr = virt, + .len = len, + .prot = prot, + .fd = fd, + .offset = offset } } }); return ret; } static int add_munmap(unsigned long addr, unsigned long len, - struct host_vm_op *ops, int *index, int last_filled, - union mm_context *mmu, void **flush, - int (*do_ops)(union mm_context *, struct host_vm_op *, - int, int, void **)) + struct host_vm_change *hvc) { struct host_vm_op *last; int ret = 0; - if(*index != -1){ - last = &ops[*index]; - if((last->type == MUNMAP) && - (last->u.munmap.addr + last->u.mmap.len == addr)){ + if (hvc->index != 0) { + last = &hvc->ops[hvc->index - 1]; + if ((last->type == MUNMAP) && + (last->u.munmap.addr + last->u.mmap.len == addr)) { last->u.munmap.len += len; return 0; } } - if(*index == last_filled){ - ret = (*do_ops)(mmu, ops, last_filled, 0, flush); - *index = -1; + if (hvc->index == ARRAY_SIZE(hvc->ops)) { + ret = do_ops(hvc, ARRAY_SIZE(hvc->ops), 0); + hvc->index = 0; } - ops[++*index] = ((struct host_vm_op) { .type = MUNMAP, - .u = { .munmap = { - .addr = addr, - .len = len } } }); + hvc->ops[hvc->index++] = ((struct host_vm_op) + { .type = MUNMAP, + .u = { .munmap = { .addr = addr, + .len = len } } }); return ret; } static int add_mprotect(unsigned long addr, unsigned long len, - unsigned int prot, struct host_vm_op *ops, int *index, - int last_filled, union mm_context *mmu, void **flush, - int (*do_ops)(union mm_context *, struct host_vm_op *, - int, int, void **)) + unsigned int prot, struct host_vm_change *hvc) { struct host_vm_op *last; int ret = 0; - if(*index != -1){ - last = &ops[*index]; - if((last->type == MPROTECT) && + if (hvc->index != 0) { + last = &hvc->ops[hvc->index - 1]; + if ((last->type == MPROTECT) && (last->u.mprotect.addr + last->u.mprotect.len == addr) && - (last->u.mprotect.prot == prot)){ + (last->u.mprotect.prot == prot)) { last->u.mprotect.len += len; return 0; } } - if(*index == last_filled){ - ret = (*do_ops)(mmu, ops, last_filled, 0, flush); - *index = -1; + if (hvc->index == ARRAY_SIZE(hvc->ops)) { + ret = do_ops(hvc, ARRAY_SIZE(hvc->ops), 0); + hvc->index = 0; } - ops[++*index] = ((struct host_vm_op) { .type = MPROTECT, - .u = { .mprotect = { - .addr = addr, - .len = len, - .prot = prot } } }); + hvc->ops[hvc->index++] = ((struct host_vm_op) + { .type = MPROTECT, + .u = { .mprotect = { .addr = addr, + .len = len, + .prot = prot } } }); return ret; } #define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1)) static inline int update_pte_range(pmd_t *pmd, unsigned long addr, - unsigned long end, struct host_vm_op *ops, - int last_op, int *op_index, int force, - union mm_context *mmu, void **flush, - int (*do_ops)(union mm_context *, - struct host_vm_op *, int, int, - void **)) + unsigned long end, + struct host_vm_change *hvc) { pte_t *pte; int r, w, x, prot, ret = 0; @@ -142,29 +194,22 @@ static inline int update_pte_range(pmd_t *pmd, unsigned long addr, } prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | (x ? UM_PROT_EXEC : 0)); - if(force || pte_newpage(*pte)){ - if(pte_present(*pte)) + if (hvc->force || pte_newpage(*pte)) { + if (pte_present(*pte)) ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK, - PAGE_SIZE, prot, ops, op_index, - last_op, mmu, flush, do_ops); - else ret = add_munmap(addr, PAGE_SIZE, ops, op_index, - last_op, mmu, flush, do_ops); + PAGE_SIZE, prot, hvc); + else ret = add_munmap(addr, PAGE_SIZE, hvc); } - else if(pte_newprot(*pte)) - ret = add_mprotect(addr, PAGE_SIZE, prot, ops, op_index, - last_op, mmu, flush, do_ops); + else if (pte_newprot(*pte)) + ret = add_mprotect(addr, PAGE_SIZE, prot, hvc); *pte = pte_mkuptodate(*pte); } while (pte++, addr += PAGE_SIZE, ((addr != end) && !ret)); return ret; } static inline int update_pmd_range(pud_t *pud, unsigned long addr, - unsigned long end, struct host_vm_op *ops, - int last_op, int *op_index, int force, - union mm_context *mmu, void **flush, - int (*do_ops)(union mm_context *, - struct host_vm_op *, int, int, - void **)) + unsigned long end, + struct host_vm_change *hvc) { pmd_t *pmd; unsigned long next; @@ -173,28 +218,20 @@ static inline int update_pmd_range(pud_t *pud, unsigned long addr, pmd = pmd_offset(pud, addr); do { next = pmd_addr_end(addr, end); - if(!pmd_present(*pmd)){ - if(force || pmd_newpage(*pmd)){ - ret = add_munmap(addr, next - addr, ops, - op_index, last_op, mmu, - flush, do_ops); + if (!pmd_present(*pmd)) { + if (hvc->force || pmd_newpage(*pmd)) { + ret = add_munmap(addr, next - addr, hvc); pmd_mkuptodate(*pmd); } } - else ret = update_pte_range(pmd, addr, next, ops, last_op, - op_index, force, mmu, flush, - do_ops); + else ret = update_pte_range(pmd, addr, next, hvc); } while (pmd++, addr = next, ((addr != end) && !ret)); return ret; } static inline int update_pud_range(pgd_t *pgd, unsigned long addr, - unsigned long end, struct host_vm_op *ops, - int last_op, int *op_index, int force, - union mm_context *mmu, void **flush, - int (*do_ops)(union mm_context *, - struct host_vm_op *, int, int, - void **)) + unsigned long end, + struct host_vm_change *hvc) { pud_t *pud; unsigned long next; @@ -203,56 +240,45 @@ static inline int update_pud_range(pgd_t *pgd, unsigned long addr, pud = pud_offset(pgd, addr); do { next = pud_addr_end(addr, end); - if(!pud_present(*pud)){ - if(force || pud_newpage(*pud)){ - ret = add_munmap(addr, next - addr, ops, - op_index, last_op, mmu, - flush, do_ops); + if (!pud_present(*pud)) { + if (hvc->force || pud_newpage(*pud)) { + ret = add_munmap(addr, next - addr, hvc); pud_mkuptodate(*pud); } } - else ret = update_pmd_range(pud, addr, next, ops, last_op, - op_index, force, mmu, flush, - do_ops); + else ret = update_pmd_range(pud, addr, next, hvc); } while (pud++, addr = next, ((addr != end) && !ret)); return ret; } void fix_range_common(struct mm_struct *mm, unsigned long start_addr, - unsigned long end_addr, int force, - int (*do_ops)(union mm_context *, struct host_vm_op *, - int, int, void **)) + unsigned long end_addr, int force) { pgd_t *pgd; - union mm_context *mmu = &mm->context; - struct host_vm_op ops[1]; + struct host_vm_change hvc; unsigned long addr = start_addr, next; - int ret = 0, last_op = ARRAY_SIZE(ops) - 1, op_index = -1; - void *flush = NULL; + int ret = 0; - ops[0].type = NONE; + hvc = INIT_HVC(mm, force); pgd = pgd_offset(mm, addr); do { next = pgd_addr_end(addr, end_addr); - if(!pgd_present(*pgd)){ - if (force || pgd_newpage(*pgd)){ - ret = add_munmap(addr, next - addr, ops, - &op_index, last_op, mmu, - &flush, do_ops); + if (!pgd_present(*pgd)) { + if (force || pgd_newpage(*pgd)) { + ret = add_munmap(addr, next - addr, &hvc); pgd_mkuptodate(*pgd); } } - else ret = update_pud_range(pgd, addr, next, ops, last_op, - &op_index, force, mmu, &flush, - do_ops); + else ret = update_pud_range(pgd, addr, next, &hvc); } while (pgd++, addr = next, ((addr != end_addr) && !ret)); - if(!ret) - ret = (*do_ops)(mmu, ops, op_index, 1, &flush); + if (!ret) + ret = do_ops(&hvc, hvc.index, 1); /* This is not an else because ret is modified above */ - if(ret) { - printk("fix_range_common: failed, killing current process\n"); + if (ret) { + printk(KERN_ERR "fix_range_common: failed, killing current " + "process\n"); force_sig(SIGKILL, current); } } @@ -268,17 +294,17 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) int updated = 0, err; mm = &init_mm; - for(addr = start; addr < end;){ + for (addr = start; addr < end;) { pgd = pgd_offset(mm, addr); - if(!pgd_present(*pgd)){ + if (!pgd_present(*pgd)) { last = ADD_ROUND(addr, PGDIR_SIZE); - if(last > end) + if (last > end) last = end; - if(pgd_newpage(*pgd)){ + if (pgd_newpage(*pgd)) { updated = 1; err = os_unmap_memory((void *) addr, last - addr); - if(err < 0) + if (err < 0) panic("munmap failed, errno = %d\n", -err); } @@ -287,15 +313,15 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) } pud = pud_offset(pgd, addr); - if(!pud_present(*pud)){ + if (!pud_present(*pud)) { last = ADD_ROUND(addr, PUD_SIZE); - if(last > end) + if (last > end) last = end; - if(pud_newpage(*pud)){ + if (pud_newpage(*pud)) { updated = 1; err = os_unmap_memory((void *) addr, last - addr); - if(err < 0) + if (err < 0) panic("munmap failed, errno = %d\n", -err); } @@ -304,15 +330,15 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) } pmd = pmd_offset(pud, addr); - if(!pmd_present(*pmd)){ + if (!pmd_present(*pmd)) { last = ADD_ROUND(addr, PMD_SIZE); - if(last > end) + if (last > end) last = end; - if(pmd_newpage(*pmd)){ + if (pmd_newpage(*pmd)) { updated = 1; err = os_unmap_memory((void *) addr, last - addr); - if(err < 0) + if (err < 0) panic("munmap failed, errno = %d\n", -err); } @@ -321,45 +347,110 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) } pte = pte_offset_kernel(pmd, addr); - if(!pte_present(*pte) || pte_newpage(*pte)){ + if (!pte_present(*pte) || pte_newpage(*pte)) { updated = 1; err = os_unmap_memory((void *) addr, PAGE_SIZE); - if(err < 0) + if (err < 0) panic("munmap failed, errno = %d\n", -err); - if(pte_present(*pte)) + if (pte_present(*pte)) map_memory(addr, pte_val(*pte) & PAGE_MASK, PAGE_SIZE, 1, 1, 1); } - else if(pte_newprot(*pte)){ + else if (pte_newprot(*pte)) { updated = 1; os_protect_memory((void *) addr, PAGE_SIZE, 1, 1, 1); } addr += PAGE_SIZE; } - return(updated); + return updated; +} + +void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + struct mm_struct *mm = vma->vm_mm; + void *flush = NULL; + int r, w, x, prot, err = 0; + struct mm_id *mm_id; + + address &= PAGE_MASK; + pgd = pgd_offset(mm, address); + if (!pgd_present(*pgd)) + goto kill; + + pud = pud_offset(pgd, address); + if (!pud_present(*pud)) + goto kill; + + pmd = pmd_offset(pud, address); + if (!pmd_present(*pmd)) + goto kill; + + pte = pte_offset_kernel(pmd, address); + + r = pte_read(*pte); + w = pte_write(*pte); + x = pte_exec(*pte); + if (!pte_young(*pte)) { + r = 0; + w = 0; + } else if (!pte_dirty(*pte)) { + w = 0; + } + + mm_id = &mm->context.id; + prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | + (x ? UM_PROT_EXEC : 0)); + if (pte_newpage(*pte)) { + if (pte_present(*pte)) { + unsigned long long offset; + int fd; + + fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset); + err = map(mm_id, address, PAGE_SIZE, prot, fd, offset, + 1, &flush); + } + else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush); + } + else if (pte_newprot(*pte)) + err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush); + + if (err) + goto kill; + + *pte = pte_mkuptodate(*pte); + + return; + +kill: + printk(KERN_ERR "Failed to flush page for address 0x%lx\n", address); + force_sig(SIGKILL, current); } pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address) { - return(pgd_offset(mm, address)); + return pgd_offset(mm, address); } pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address) { - return(pud_offset(pgd, address)); + return pud_offset(pgd, address); } pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address) { - return(pmd_offset(pud, address)); + return pmd_offset(pud, address); } pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address) { - return(pte_offset_kernel(pmd, address)); + return pte_offset_kernel(pmd, address); } pte_t *addr_pte(struct task_struct *task, unsigned long addr) @@ -368,7 +459,7 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr) pud_t *pud = pud_offset(pgd, addr); pmd_t *pmd = pmd_offset(pud, addr); - return(pte_offset_map(pmd, addr)); + return pte_offset_map(pmd, addr); } void flush_tlb_all(void) @@ -378,35 +469,58 @@ void flush_tlb_all(void) void flush_tlb_kernel_range(unsigned long start, unsigned long end) { - CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt, - flush_tlb_kernel_range_common, start, end); + flush_tlb_kernel_range_common(start, end); } void flush_tlb_kernel_vm(void) { - CHOOSE_MODE(flush_tlb_kernel_vm_tt(), - flush_tlb_kernel_range_common(start_vm, end_vm)); + flush_tlb_kernel_range_common(start_vm, end_vm); } void __flush_tlb_one(unsigned long addr) { - CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr); + flush_tlb_kernel_range_common(addr, addr + PAGE_SIZE); +} + +static void fix_range(struct mm_struct *mm, unsigned long start_addr, + unsigned long end_addr, int force) +{ + if (!proc_mm && (end_addr > STUB_START)) + end_addr = STUB_START; + + fix_range_common(mm, start_addr, end_addr, force); } void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start, - end); + if (vma->vm_mm == NULL) + flush_tlb_kernel_range_common(start, end); + else fix_range(vma->vm_mm, start, end, 0); } void flush_tlb_mm(struct mm_struct *mm) { - CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm); + unsigned long end; + + /* + * Don't bother flushing if this address space is about to be + * destroyed. + */ + if (atomic_read(&mm->mm_users) == 0) + return; + + end = proc_mm ? task_size : STUB_START; + fix_range(mm, 0, end, 0); } void force_flush_all(void) { - CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas()); -} + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma = mm->mmap; + while (vma != NULL) { + fix_range(mm, vma->vm_start, vma->vm_end, 1); + vma = vma->vm_next; + } +} diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 3850d53f79fd..bd060551e619 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -1,40 +1,24 @@ /* - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/kernel.h" -#include "asm/errno.h" -#include "linux/sched.h" -#include "linux/mm.h" -#include "linux/spinlock.h" -#include "linux/init.h" -#include "linux/ptrace.h" -#include "asm/semaphore.h" -#include "asm/pgtable.h" -#include "asm/pgalloc.h" -#include "asm/tlbflush.h" -#include "asm/a.out.h" -#include "asm/current.h" -#include "asm/irq.h" -#include "sysdep/sigcontext.h" -#include "kern_util.h" -#include "as-layout.h" +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/hardirq.h> +#include <asm/current.h> +#include <asm/pgtable.h> +#include <asm/tlbflush.h> #include "arch.h" -#include "kern.h" -#include "chan_kern.h" -#include "mconsole_kern.h" -#include "mem.h" -#include "mem_kern.h" -#include "sysdep/sigcontext.h" -#include "sysdep/ptrace.h" -#include "os.h" -#ifdef CONFIG_MODE_SKAS -#include "skas.h" -#endif +#include "as-layout.h" +#include "kern_util.h" #include "os.h" +#include "sysdep/sigcontext.h" -/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */ +/* + * Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by + * segv(). + */ int handle_page_fault(unsigned long address, unsigned long ip, int is_write, int is_user, int *code_out) { @@ -48,31 +32,33 @@ int handle_page_fault(unsigned long address, unsigned long ip, *code_out = SEGV_MAPERR; - /* If the fault was during atomic operation, don't take the fault, just - * fail. */ + /* + * If the fault was during atomic operation, don't take the fault, just + * fail. + */ if (in_atomic()) goto out_nosemaphore; down_read(&mm->mmap_sem); vma = find_vma(mm, address); - if(!vma) + if (!vma) goto out; - else if(vma->vm_start <= address) + else if (vma->vm_start <= address) goto good_area; - else if(!(vma->vm_flags & VM_GROWSDOWN)) + else if (!(vma->vm_flags & VM_GROWSDOWN)) goto out; - else if(is_user && !ARCH_IS_STACKGROW(address)) + else if (is_user && !ARCH_IS_STACKGROW(address)) goto out; - else if(expand_stack(vma, address)) + else if (expand_stack(vma, address)) goto out; good_area: *code_out = SEGV_ACCERR; - if(is_write && !(vma->vm_flags & VM_WRITE)) + if (is_write && !(vma->vm_flags & VM_WRITE)) goto out; /* Don't require VM_READ|VM_EXEC for write faults! */ - if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC))) + if (!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC))) goto out; do { @@ -98,9 +84,10 @@ survive: pud = pud_offset(pgd, address); pmd = pmd_offset(pud, address); pte = pte_offset_kernel(pmd, address); - } while(!pte_present(*pte)); + } while (!pte_present(*pte)); err = 0; - /* The below warning was added in place of + /* + * The below warning was added in place of * pte_mkyoung(); if (is_write) pte_mkdirty(); * If it's triggered, we'd see normally a hang here (a clean pte is * marked read-only to emulate the dirty bit). @@ -114,7 +101,7 @@ survive: out: up_read(&mm->mmap_sem); out_nosemaphore: - return(err); + return err; /* * We ran out of memory, or some other thing happened to us that made @@ -141,11 +128,11 @@ static void bad_segv(struct faultinfo fi, unsigned long ip) force_sig_info(SIGSEGV, &si, current); } -static void segv_handler(int sig, union uml_pt_regs *regs) +static void segv_handler(int sig, struct uml_pt_regs *regs) { struct faultinfo * fi = UPT_FAULTINFO(regs); - if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){ + if (UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)) { bad_segv(*fi, UPT_IP(regs)); return; } @@ -159,45 +146,49 @@ static void segv_handler(int sig, union uml_pt_regs *regs) * give us bad data! */ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, - union uml_pt_regs *regs) + struct uml_pt_regs *regs) { struct siginfo si; - void *catcher; + jmp_buf *catcher; int err; int is_write = FAULT_WRITE(fi); unsigned long address = FAULT_ADDRESS(fi); - if(!is_user && (address >= start_vm) && (address < end_vm)){ + if (!is_user && (address >= start_vm) && (address < end_vm)) { flush_tlb_kernel_vm(); return 0; } - else if(current->mm == NULL) { + else if (current->mm == NULL) { show_regs(container_of(regs, struct pt_regs, regs)); - panic("Segfault with no mm"); + panic("Segfault with no mm"); } if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi)) - err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); + err = handle_page_fault(address, ip, is_write, is_user, + &si.si_code); else { err = -EFAULT; - /* A thread accessed NULL, we get a fault, but CR2 is invalid. - * This code is used in __do_copy_from_user() of TT mode. */ + /* + * A thread accessed NULL, we get a fault, but CR2 is invalid. + * This code is used in __do_copy_from_user() of TT mode. + * XXX tt mode is gone, so maybe this isn't needed any more + */ address = 0; } catcher = current->thread.fault_catcher; - if(!err) + if (!err) return 0; - else if(catcher != NULL){ + else if (catcher != NULL) { current->thread.fault_addr = (void *) address; - do_longjmp(catcher, 1); + UML_LONGJMP(catcher, 1); } - else if(current->thread.fault_addr != NULL) + else if (current->thread.fault_addr != NULL) panic("fault_addr set but no fault catcher"); - else if(!is_user && arch_fixup(ip, regs)) + else if (!is_user && arch_fixup(ip, regs)) return 0; - if(!is_user) { + if (!is_user) { show_regs(container_of(regs, struct pt_regs, regs)); panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", address, ip); @@ -211,7 +202,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, current->thread.arch.faultinfo = fi; force_sig_info(SIGBUS, &si, current); } else if (err == -ENOMEM) { - printk("VM: killing process %s\n", current->comm); + printk(KERN_INFO "VM: killing process %s\n", current->comm); do_exit(SIGKILL); } else { BUG_ON(err != -EFAULT); @@ -223,15 +214,15 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, return 0; } -void relay_signal(int sig, union uml_pt_regs *regs) +void relay_signal(int sig, struct uml_pt_regs *regs) { - if(arch_handle_signal(sig, regs)) + if (arch_handle_signal(sig, regs)) return; - if(!UPT_IS_USER(regs)){ - if(sig == SIGBUS) - printk("Bus error - the host /dev/shm or /tmp mount " - "likely just ran out of space\n"); + if (!UPT_IS_USER(regs)) { + if (sig == SIGBUS) + printk(KERN_ERR "Bus error - the host /dev/shm or /tmp " + "mount likely just ran out of space\n"); panic("Kernel mode signal %d", sig); } @@ -239,14 +230,14 @@ void relay_signal(int sig, union uml_pt_regs *regs) force_sig(sig, current); } -static void bus_handler(int sig, union uml_pt_regs *regs) +static void bus_handler(int sig, struct uml_pt_regs *regs) { - if(current->thread.fault_catcher != NULL) - do_longjmp(current->thread.fault_catcher, 1); + if (current->thread.fault_catcher != NULL) + UML_LONGJMP(current->thread.fault_catcher, 1); else relay_signal(sig, regs); } -static void winch(int sig, union uml_pt_regs *regs) +static void winch(int sig, struct uml_pt_regs *regs) { do_IRQ(WINCH_IRQ, regs); } diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile deleted file mode 100644 index 6939e5af8472..000000000000 --- a/arch/um/kernel/tt/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) -# Licensed under the GPL -# - -obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ - syscall_kern.o syscall_user.o tlb.o tracer.o trap_user.o \ - uaccess.o uaccess_user.o - -obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/ - -USER_OBJS := gdb.o tracer.o - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c deleted file mode 100644 index 40126cb51801..000000000000 --- a/arch/um/kernel/tt/exec_kern.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include "linux/kernel.h" -#include "linux/mm.h" -#include "asm/signal.h" -#include "asm/ptrace.h" -#include "asm/uaccess.h" -#include "asm/pgalloc.h" -#include "asm/tlbflush.h" -#include "kern_util.h" -#include "irq_user.h" -#include "mem_user.h" -#include "os.h" -#include "tlb.h" -#include "mode.h" - -static int exec_tramp(void *sig_stack) -{ - init_new_thread_stack(sig_stack, NULL); - init_new_thread_signals(); - os_stop_process(os_getpid()); - return(0); -} - -void flush_thread_tt(void) -{ - unsigned long stack; - int new_pid; - - stack = alloc_stack(0, 0); - if(stack == 0){ - printk(KERN_ERR - "flush_thread : failed to allocate temporary stack\n"); - do_exit(SIGKILL); - } - - new_pid = start_fork_tramp(task_stack_page(current), stack, 0, exec_tramp); - if(new_pid < 0){ - printk(KERN_ERR - "flush_thread : new thread failed, errno = %d\n", - -new_pid); - do_exit(SIGKILL); - } - - if(current_thread->cpu == 0) - forward_interrupts(new_pid); - current->thread.request.op = OP_EXEC; - current->thread.request.u.exec.pid = new_pid; - unprotect_stack((unsigned long) current_thread); - os_usr1_process(os_getpid()); - change_sig(SIGUSR1, 1); - - change_sig(SIGUSR1, 0); - enable_timer(); - free_page(stack); - protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1); - stack_protections((unsigned long) current_thread); - force_flush_all(); - unblock_signals(); -} - -void start_thread_tt(struct pt_regs *regs, unsigned long eip, - unsigned long esp) -{ - set_fs(USER_DS); - flush_tlb_mm(current->mm); - PT_REGS_IP(regs) = eip; - PT_REGS_SP(regs) = esp; - PT_FIX_EXEC_STACK(esp); -} - -/* - * 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/kernel/tt/exec_user.c b/arch/um/kernel/tt/exec_user.c deleted file mode 100644 index 7b5f2181cf51..000000000000 --- a/arch/um/kernel/tt/exec_user.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <sched.h> -#include <errno.h> -#include <sys/wait.h> -#include <signal.h> -#include "kern_util.h" -#include "user.h" -#include "ptrace_user.h" -#include "os.h" - -void do_exec(int old_pid, int new_pid) -{ - unsigned long regs[FRAME_SIZE]; - int err; - - if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) || - (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0)) - tracer_panic("do_exec failed to attach proc - errno = %d", - errno); - - CATCH_EINTR(err = waitpid(new_pid, 0, WUNTRACED)); - if (err < 0) - tracer_panic("do_exec failed to attach proc in waitpid - errno = %d", - errno); - - if(ptrace_getregs(old_pid, regs) < 0) - tracer_panic("do_exec failed to get registers - errno = %d", - errno); - - os_kill_ptraced_process(old_pid, 0); - - if (ptrace(PTRACE_OLDSETOPTIONS, new_pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) - tracer_panic("do_exec: PTRACE_SETOPTIONS failed, errno = %d", errno); - - if(ptrace_setregs(new_pid, regs) < 0) - tracer_panic("do_exec failed to start new proc - errno = %d", - errno); -} - -/* - * 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/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c deleted file mode 100644 index 030e4658f36b..000000000000 --- a/arch/um/kernel/tt/gdb.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <signal.h> -#include <sys/types.h> -#include "ptrace_user.h" -#include "uml-config.h" -#include "kern_constants.h" -#include "chan_user.h" -#include "init.h" -#include "user.h" -#include "debug.h" -#include "kern_util.h" -#include "tt.h" -#include "sysdep/thread.h" -#include "os.h" - -extern int debugger_pid; -extern int debugger_fd; -extern int debugger_parent; - -int detach(int pid, int sig) -{ - return(ptrace(PTRACE_DETACH, pid, 0, sig)); -} - -int attach(int pid) -{ - int err; - - err = ptrace(PTRACE_ATTACH, pid, 0, 0); - if(err < 0) return(-errno); - else return(err); -} - -int cont(int pid) -{ - return(ptrace(PTRACE_CONT, pid, 0, 0)); -} - -#ifdef UML_CONFIG_PT_PROXY - -int debugger_signal(int status, pid_t pid) -{ - return(debugger_proxy(status, pid)); -} - -void child_signal(pid_t pid, int status) -{ - child_proxy(pid, status); -} - -static void gdb_announce(char *dev_name, int dev) -{ - printf("gdb assigned device '%s'\n", dev_name); -} - -static struct chan_opts opts = { - .announce = gdb_announce, - .xterm_title = "UML kernel debugger", - .raw = 0, - .tramp_stack = 0, - .in_kernel = 0, -}; - -/* Accessed by the tracing thread, which automatically serializes access */ -static void *xterm_data; -static int xterm_fd; - -extern void *xterm_init(char *, int, struct chan_opts *); -extern int xterm_open(int, int, int, void *, char **); -extern void xterm_close(int, void *); - -int open_gdb_chan(void) -{ - char stack[UM_KERN_PAGE_SIZE], *dummy; - - opts.tramp_stack = (unsigned long) stack; - xterm_data = xterm_init("", 0, &opts); - xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy); - return(xterm_fd); -} - -static void exit_debugger_cb(void *unused) -{ - if(debugger_pid != -1){ - if(gdb_pid != -1){ - fake_child_exit(); - gdb_pid = -1; - } - else kill_child_dead(debugger_pid); - debugger_pid = -1; - if(debugger_parent != -1) - detach(debugger_parent, SIGINT); - } - if(xterm_data != NULL) xterm_close(xterm_fd, xterm_data); -} - -static void exit_debugger(void) -{ - initial_thread_cb(exit_debugger_cb, NULL); -} - -__uml_exitcall(exit_debugger); - -struct gdb_data { - char *str; - int err; -}; - -extern char *linux_prog; - -static void config_gdb_cb(void *arg) -{ - struct gdb_data *data = arg; - void *task; - int pid; - - data->err = -1; - if(debugger_pid != -1) exit_debugger_cb(NULL); - if(!strncmp(data->str, "pid,", strlen("pid,"))){ - data->str += strlen("pid,"); - pid = strtoul(data->str, NULL, 0); - task = cpu_tasks[0].task; - debugger_pid = attach_debugger(TASK_EXTERN_PID(task), pid, 0); - if(debugger_pid != -1){ - data->err = 0; - gdb_pid = pid; - } - return; - } - data->err = 0; - debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd); - init_proxy(debugger_pid, 0, 0); -} - -int gdb_config(char *str, char **error_out) -{ - struct gdb_data data; - - if(*str++ != '=') return(-1); - data.str = str; - initial_thread_cb(config_gdb_cb, &data); - return(data.err); -} - -void remove_gdb_cb(void *unused) -{ - exit_debugger_cb(NULL); -} - -int gdb_remove(int unused, char **error_out) -{ - initial_thread_cb(remove_gdb_cb, NULL); - return 0; -} - -void signal_usr1(int sig) -{ - if(debugger_pid != -1){ - printf("The debugger is already running\n"); - return; - } - debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd); - init_proxy(debugger_pid, 0, 0); -} - -int init_ptrace_proxy(int idle_pid, int startup, int stop) -{ - int pid, status; - - pid = start_debugger(linux_prog, startup, stop, &debugger_fd); - status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL); - if(pid < 0){ - cont(idle_pid); - return(-1); - } - init_proxy(pid, 1, status); - return(pid); -} - -int attach_debugger(int idle_pid, int pid, int stop) -{ - int status = 0, err; - - err = attach(pid); - if(err < 0){ - printf("Failed to attach pid %d, errno = %d\n", pid, -err); - return(-1); - } - if(stop) status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL); - init_proxy(pid, 1, status); - return(pid); -} - -#ifdef notdef /* Put this back in when it does something useful */ -static int __init uml_gdb_init_setup(char *line, int *add) -{ - gdb_init = uml_strdup(line); - return 0; -} - -__uml_setup("gdb=", uml_gdb_init_setup, -"gdb=<channel description>\n\n" -); -#endif - -static int __init uml_gdb_pid_setup(char *line, int *add) -{ - gdb_pid = strtoul(line, NULL, 0); - *add = 0; - return 0; -} - -__uml_setup("gdb-pid=", uml_gdb_pid_setup, -"gdb-pid=<pid>\n" -" gdb-pid is used to attach an external debugger to UML. This may be\n" -" an already-running gdb or a debugger-like process like strace.\n\n" -); - -#else - -int debugger_signal(int status, pid_t pid){ return(0); } -void child_signal(pid_t pid, int status){ } -int init_ptrace_proxy(int idle_pid, int startup, int stop) -{ - printf("debug requested when CONFIG_PT_PROXY is off\n"); - kill_child_dead(idle_pid); - exit(1); -} - -void signal_usr1(int sig) -{ - printf("debug requested when CONFIG_PT_PROXY is off\n"); -} - -int attach_debugger(int idle_pid, int pid, int stop) -{ - printf("attach_debugger called when CONFIG_PT_PROXY " - "is off\n"); - return(-1); -} - -int config_gdb(char *str) -{ - return(-1); -} - -int remove_gdb(void) -{ - return(-1); -} - -int init_parent_proxy(int pid) -{ - return(-1); -} - -void debugger_parent_signal(int status, int pid) -{ -} - -#endif - -/* - * 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/kernel/tt/gdb_kern.c b/arch/um/kernel/tt/gdb_kern.c deleted file mode 100644 index 03b06bc00771..000000000000 --- a/arch/um/kernel/tt/gdb_kern.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include "linux/init.h" -#include "mconsole_kern.h" - -#ifdef CONFIG_MCONSOLE - -extern int gdb_config(char *str, char **error_out); -extern int gdb_remove(int n, char **error_out); - -static struct mc_device gdb_mc = { - .list = INIT_LIST_HEAD(gdb_mc.list), - .name = "gdb", - .config = gdb_config, - .remove = gdb_remove, -}; - -int gdb_mc_init(void) -{ - mconsole_register_dev(&gdb_mc); - return(0); -} - -__initcall(gdb_mc_init); - -#endif - -/* - * 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/kernel/tt/include/mode-tt.h b/arch/um/kernel/tt/include/mode-tt.h deleted file mode 100644 index e171e15fead5..000000000000 --- a/arch/um/kernel/tt/include/mode-tt.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __MODE_TT_H__ -#define __MODE_TT_H__ - -#include "sysdep/ptrace.h" - -enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB }; - -extern int tracing_pid; - -extern int tracer(int (*init_proc)(void *), void *sp); -extern void sig_handler_common_tt(int sig, void *sc); -extern void syscall_handler_tt(int sig, union uml_pt_regs *regs); -extern void reboot_tt(void); -extern void halt_tt(void); -extern int is_tracer_winch(int pid, int fd, void *data); -extern void kill_off_processes_tt(void); - -#endif - -/* - * 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/kernel/tt/ksyms.c b/arch/um/kernel/tt/ksyms.c deleted file mode 100644 index 84a9385a8fef..000000000000 --- a/arch/um/kernel/tt/ksyms.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include "linux/module.h" -#include "asm/uaccess.h" -#include "mode.h" - -EXPORT_SYMBOL(__do_copy_from_user); -EXPORT_SYMBOL(__do_copy_to_user); -EXPORT_SYMBOL(__do_strncpy_from_user); -EXPORT_SYMBOL(__do_strnlen_user); -EXPORT_SYMBOL(__do_clear_user); -EXPORT_SYMBOL(clear_user_tt); - -EXPORT_SYMBOL(tracing_pid); -EXPORT_SYMBOL(honeypot); - -/* - * 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/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c deleted file mode 100644 index d0c3c4975f28..000000000000 --- a/arch/um/kernel/tt/mem.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include "linux/stddef.h" -#include "linux/mm.h" -#include "asm/uaccess.h" -#include "mem_user.h" -#include "kern_util.h" -#include "kern.h" -#include "tt.h" - -void before_mem_tt(unsigned long brk_start) -{ - if(debug) - remap_data(UML_ROUND_DOWN(&_stext), UML_ROUND_UP(&_etext), 1); - remap_data(UML_ROUND_DOWN(&_sdata), UML_ROUND_UP(&_edata), 1); - remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1); -} - -#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000) -#define START (CONFIG_TOP_ADDR - SIZE) - -unsigned long set_task_sizes_tt(unsigned long *task_size_out) -{ - unsigned long host_task_size; - - /* Round up to the nearest 4M */ - host_task_size = ROUND_4M((unsigned long) &host_task_size); - *task_size_out = START; - - return host_task_size; -} diff --git a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c deleted file mode 100644 index 9774f6360c32..000000000000 --- a/arch/um/kernel/tt/mem_user.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <sys/mman.h> -#include "tt.h" -#include "mem_user.h" -#include "os.h" - -void remap_data(void *segment_start, void *segment_end, int w) -{ - void *addr; - unsigned long size; - int data, prot; - - if(w) prot = PROT_WRITE; - else prot = 0; - prot |= PROT_READ | PROT_EXEC; - size = (unsigned long) segment_end - - (unsigned long) segment_start; - data = create_mem_file(size); - addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0); - if(addr == MAP_FAILED){ - perror("mapping new data segment"); - exit(1); - } - memcpy(addr, segment_start, size); - if(switcheroo(data, prot, addr, segment_start, size) < 0){ - printf("switcheroo failed\n"); - exit(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/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c deleted file mode 100644 index 74347adf81bf..000000000000 --- a/arch/um/kernel/tt/process_kern.c +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include "linux/sched.h" -#include "linux/signal.h" -#include "linux/kernel.h" -#include "linux/interrupt.h" -#include "linux/ptrace.h" -#include "asm/system.h" -#include "asm/pgalloc.h" -#include "asm/ptrace.h" -#include "asm/tlbflush.h" -#include "irq_user.h" -#include "kern_util.h" -#include "os.h" -#include "kern.h" -#include "sigcontext.h" -#include "mem_user.h" -#include "tlb.h" -#include "mode.h" -#include "mode_kern.h" -#include "init.h" -#include "tt.h" - -void switch_to_tt(void *prev, void *next) -{ - struct task_struct *from, *to, *prev_sched; - unsigned long flags; - int err, vtalrm, alrm, prof, cpu; - char c; - - from = prev; - to = next; - - cpu = task_thread_info(from)->cpu; - if(cpu == 0) - forward_interrupts(to->thread.mode.tt.extern_pid); -#ifdef CONFIG_SMP - forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid); -#endif - local_irq_save(flags); - - vtalrm = change_sig(SIGVTALRM, 0); - alrm = change_sig(SIGALRM, 0); - prof = change_sig(SIGPROF, 0); - - forward_pending_sigio(to->thread.mode.tt.extern_pid); - - c = 0; - - /* Notice that here we "up" the semaphore on which "to" is waiting, and - * below (the read) we wait on this semaphore (which is implemented by - * switch_pipe) and go sleeping. Thus, after that, we have resumed in - * "to", and can't use any more the value of "from" (which is outdated), - * nor the value in "to" (since it was the task which stole us the CPU, - * which we don't care about). */ - - err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); - if(err != sizeof(c)) - panic("write of switch_pipe failed, err = %d", -err); - - if(from->thread.mode.tt.switch_pipe[0] == -1) - os_kill_process(os_getpid(), 0); - - err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, - sizeof(c)); - if(err != sizeof(c)) - panic("read of switch_pipe failed, errno = %d", -err); - - /* If the process that we have just scheduled away from has exited, - * then it needs to be killed here. The reason is that, even though - * it will kill itself when it next runs, that may be too late. Its - * stack will be freed, possibly before then, and if that happens, - * we have a use-after-free situation. So, it gets killed here - * in case it has not already killed itself. - */ - prev_sched = current->thread.prev_sched; - if(prev_sched->thread.mode.tt.switch_pipe[0] == -1) - os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); - - change_sig(SIGVTALRM, vtalrm); - change_sig(SIGALRM, alrm); - change_sig(SIGPROF, prof); - - arch_switch_to_tt(prev_sched, current); - - flush_tlb_all(); - local_irq_restore(flags); -} - -void release_thread_tt(struct task_struct *task) -{ - int pid = task->thread.mode.tt.extern_pid; - - /* - * We first have to kill the other process, before - * closing its switch_pipe. Else it might wake up - * and receive "EOF" before we could kill it. - */ - if(os_getpid() != pid) - os_kill_process(pid, 0); - - os_close_file(task->thread.mode.tt.switch_pipe[0]); - os_close_file(task->thread.mode.tt.switch_pipe[1]); - /* use switch_pipe as flag: thread is released */ - task->thread.mode.tt.switch_pipe[0] = -1; -} - -void suspend_new_thread(int fd) -{ - int err; - char c; - - os_stop_process(os_getpid()); - err = os_read_file(fd, &c, sizeof(c)); - if(err != sizeof(c)) - panic("read failed in suspend_new_thread, err = %d", -err); -} - -void schedule_tail(struct task_struct *prev); - -static void new_thread_handler(int sig) -{ - unsigned long disable; - int (*fn)(void *); - void *arg; - - fn = current->thread.request.u.thread.proc; - arg = current->thread.request.u.thread.arg; - - UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1); - disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) | - (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1)); - SC_SIGMASK(UPT_SC(¤t->thread.regs.regs)) &= ~disable; - - suspend_new_thread(current->thread.mode.tt.switch_pipe[0]); - - force_flush_all(); - if(current->thread.prev_sched != NULL) - schedule_tail(current->thread.prev_sched); - current->thread.prev_sched = NULL; - - init_new_thread_signals(); - enable_timer(); - free_page(current->thread.temp_stack); - set_cmdline("(kernel thread)"); - - change_sig(SIGUSR1, 1); - change_sig(SIGPROF, 1); - local_irq_enable(); - if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf)) - do_exit(0); - - /* XXX No set_user_mode here because a newly execed process will - * immediately segfault on its non-existent IP, coming straight back - * to the signal handler, which will call set_user_mode on its way - * out. This should probably change since it's confusing. - */ -} - -static int new_thread_proc(void *stack) -{ - /* local_irq_disable is needed to block out signals until this thread is - * properly scheduled. Otherwise, the tracing thread will get mighty - * upset about any signals that arrive before that. - * This has the complication that it sets the saved signal mask in - * the sigcontext to block signals. This gets restored when this - * thread (or a descendant, since they get a copy of this sigcontext) - * returns to userspace. - * So, this is compensated for elsewhere. - * XXX There is still a small window until local_irq_disable() actually - * finishes where signals are possible - shouldn't be a problem in - * practice since SIGIO hasn't been forwarded here yet, and the - * local_irq_disable should finish before a SIGVTALRM has time to be - * delivered. - */ - - local_irq_disable(); - init_new_thread_stack(stack, new_thread_handler); - os_usr1_process(os_getpid()); - change_sig(SIGUSR1, 1); - return(0); -} - -/* Signal masking - signals are blocked at the start of fork_tramp. They - * are re-enabled when finish_fork_handler is entered by fork_tramp hitting - * itself with a SIGUSR1. set_user_mode has to be run with SIGUSR1 off, - * so it is blocked before it's called. They are re-enabled on sigreturn - * despite the fact that they were blocked when the SIGUSR1 was issued because - * copy_thread copies the parent's sigcontext, including the signal mask - * onto the signal frame. - */ - -void finish_fork_handler(int sig) -{ - UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1); - suspend_new_thread(current->thread.mode.tt.switch_pipe[0]); - - force_flush_all(); - if(current->thread.prev_sched != NULL) - schedule_tail(current->thread.prev_sched); - current->thread.prev_sched = NULL; - - enable_timer(); - change_sig(SIGVTALRM, 1); - local_irq_enable(); - if(current->mm != current->parent->mm) - protect_memory(uml_reserved, high_physmem - uml_reserved, 1, - 1, 0, 1); - stack_protections((unsigned long) current_thread); - - free_page(current->thread.temp_stack); - local_irq_disable(); - change_sig(SIGUSR1, 0); - set_user_mode(current); -} - -int fork_tramp(void *stack) -{ - local_irq_disable(); - arch_init_thread(); - init_new_thread_stack(stack, finish_fork_handler); - - os_usr1_process(os_getpid()); - change_sig(SIGUSR1, 1); - return(0); -} - -int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, - unsigned long stack_top, struct task_struct * p, - struct pt_regs *regs) -{ - int (*tramp)(void *); - int new_pid, err; - unsigned long stack; - - if(current->thread.forking) - tramp = fork_tramp; - else { - tramp = new_thread_proc; - p->thread.request.u.thread = current->thread.request.u.thread; - } - - err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1); - if(err < 0){ - printk("copy_thread : pipe failed, err = %d\n", -err); - return(err); - } - - stack = alloc_stack(0, 0); - if(stack == 0){ - printk(KERN_ERR "copy_thread : failed to allocate " - "temporary stack\n"); - return(-ENOMEM); - } - - clone_flags &= CLONE_VM; - p->thread.temp_stack = stack; - new_pid = start_fork_tramp(task_stack_page(p), stack, clone_flags, tramp); - if(new_pid < 0){ - printk(KERN_ERR "copy_thread : clone failed - errno = %d\n", - -new_pid); - return(new_pid); - } - - if(current->thread.forking){ - sc_to_sc(UPT_SC(&p->thread.regs.regs), UPT_SC(®s->regs)); - SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0); - if(sp != 0) - SC_SP(UPT_SC(&p->thread.regs.regs)) = sp; - } - p->thread.mode.tt.extern_pid = new_pid; - - current->thread.request.op = OP_FORK; - current->thread.request.u.fork.pid = new_pid; - os_usr1_process(os_getpid()); - - /* Enable the signal and then disable it to ensure that it is handled - * here, and nowhere else. - */ - change_sig(SIGUSR1, 1); - - change_sig(SIGUSR1, 0); - err = 0; - return(err); -} - -void reboot_tt(void) -{ - current->thread.request.op = OP_REBOOT; - os_usr1_process(os_getpid()); - change_sig(SIGUSR1, 1); -} - -void halt_tt(void) -{ - current->thread.request.op = OP_HALT; - os_usr1_process(os_getpid()); - change_sig(SIGUSR1, 1); -} - -void kill_off_processes_tt(void) -{ - struct task_struct *p; - int me; - - me = os_getpid(); - for_each_process(p){ - if(p->thread.mode.tt.extern_pid != me) - os_kill_process(p->thread.mode.tt.extern_pid, 0); - } - if(init_task.thread.mode.tt.extern_pid != me) - os_kill_process(init_task.thread.mode.tt.extern_pid, 0); -} - -void initial_thread_cb_tt(void (*proc)(void *), void *arg) -{ - if(os_getpid() == tracing_pid){ - (*proc)(arg); - } - else { - current->thread.request.op = OP_CB; - current->thread.request.u.cb.proc = proc; - current->thread.request.u.cb.arg = arg; - os_usr1_process(os_getpid()); - change_sig(SIGUSR1, 1); - - change_sig(SIGUSR1, 0); - } -} - -int do_proc_op(void *t, int proc_id) -{ - struct task_struct *task; - struct thread_struct *thread; - int op, pid; - - task = t; - thread = &task->thread; - op = thread->request.op; - switch(op){ - case OP_NONE: - case OP_TRACE_ON: - break; - case OP_EXEC: - pid = thread->request.u.exec.pid; - do_exec(thread->mode.tt.extern_pid, pid); - thread->mode.tt.extern_pid = pid; - cpu_tasks[task_thread_info(task)->cpu].pid = pid; - break; - case OP_FORK: - attach_process(thread->request.u.fork.pid); - break; - case OP_CB: - (*thread->request.u.cb.proc)(thread->request.u.cb.arg); - break; - case OP_REBOOT: - case OP_HALT: - break; - default: - tracer_panic("Bad op in do_proc_op"); - break; - } - thread->request.op = OP_NONE; - return(op); -} - -void init_idle_tt(void) -{ - default_idle(); -} - -extern void start_kernel(void); - -static int start_kernel_proc(void *unused) -{ - int pid; - - block_signals(); - pid = os_getpid(); - - cpu_tasks[0].pid = pid; - cpu_tasks[0].task = current; -#ifdef CONFIG_SMP - cpu_online_map = cpumask_of_cpu(0); -#endif - if(debug) os_stop_process(pid); - start_kernel(); - return(0); -} - -void set_tracing(void *task, int tracing) -{ - ((struct task_struct *) task)->thread.mode.tt.tracing = tracing; -} - -int is_tracing(void *t) -{ - return (((struct task_struct *) t)->thread.mode.tt.tracing); -} - -int set_user_mode(void *t) -{ - struct task_struct *task; - - task = t ? t : current; - if(task->thread.mode.tt.tracing) - return(1); - task->thread.request.op = OP_TRACE_ON; - os_usr1_process(os_getpid()); - return(0); -} - -void set_init_pid(int pid) -{ - int err; - - init_task.thread.mode.tt.extern_pid = pid; - err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1); - if(err) - panic("Can't create switch pipe for init_task, errno = %d", - -err); -} - -int start_uml_tt(void) -{ - void *sp; - int pages; - - pages = (1 << CONFIG_KERNEL_STACK_ORDER); - sp = task_stack_page(&init_task) + - pages * PAGE_SIZE - sizeof(unsigned long); - return(tracer(start_kernel_proc, sp)); -} - -int external_pid_tt(struct task_struct *task) -{ - return(task->thread.mode.tt.extern_pid); -} - -int thread_pid_tt(struct task_struct *task) -{ - return(task->thread.mode.tt.extern_pid); -} - -int is_valid_pid(int pid) -{ - struct task_struct *task; - - read_lock(&tasklist_lock); - for_each_process(task){ - if(task->thread.mode.tt.extern_pid == pid){ - read_unlock(&tasklist_lock); - return(1); - } - } - read_unlock(&tasklist_lock); - return(0); -} diff --git a/arch/um/kernel/tt/ptproxy/Makefile b/arch/um/kernel/tt/ptproxy/Makefile deleted file mode 100644 index 3ad5b774de59..000000000000 --- a/arch/um/kernel/tt/ptproxy/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -# Licensed under the GPL -# - -obj-y = proxy.o ptrace.o sysdep.o wait.o - -USER_OBJS := $(obj-y) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c deleted file mode 100644 index 420c23f311f3..000000000000 --- a/arch/um/kernel/tt/ptproxy/proxy.c +++ /dev/null @@ -1,377 +0,0 @@ -/********************************************************************** -proxy.c - -Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing -terms and conditions. - -Jeff Dike (jdike@karaya.com) : Modified for integration into uml -**********************************************************************/ - -/* XXX This file shouldn't refer to CONFIG_* */ - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <signal.h> -#include <string.h> -#include <termios.h> -#include <sys/wait.h> -#include <sys/types.h> -#include <sys/ioctl.h> -#include <asm/unistd.h> -#include "ptrace_user.h" - -#include "ptproxy.h" -#include "sysdep.h" -#include "wait.h" - -#include "user.h" -#include "os.h" -#include "tempfile.h" - -static int debugger_wait(debugger_state *debugger, int *status, int options, - int (*syscall)(debugger_state *debugger, pid_t child), - int (*normal_return)(debugger_state *debugger, - pid_t unused), - int (*wait_return)(debugger_state *debugger, - pid_t unused)) -{ - if(debugger->real_wait){ - debugger->handle_trace = normal_return; - syscall_continue(debugger->pid); - debugger->real_wait = 0; - return(1); - } - debugger->wait_status_ptr = status; - debugger->wait_options = options; - if((debugger->debugee != NULL) && debugger->debugee->event){ - syscall_continue(debugger->pid); - wait_for_stop(debugger->pid, SIGTRAP, PTRACE_SYSCALL, - NULL); - (*wait_return)(debugger, -1); - return(0); - } - else if(debugger->wait_options & WNOHANG){ - syscall_cancel(debugger->pid, 0); - debugger->handle_trace = syscall; - return(0); - } - else { - syscall_pause(debugger->pid); - debugger->handle_trace = wait_return; - debugger->waiting = 1; - } - return(1); -} - -/* - * Handle debugger trap, i.e. syscall. - */ - -int debugger_syscall(debugger_state *debugger, pid_t child) -{ - long arg1, arg2, arg3, arg4, arg5, result; - int syscall, ret = 0; - - syscall = get_syscall(debugger->pid, &arg1, &arg2, &arg3, &arg4, - &arg5); - - switch(syscall){ - case __NR_execve: - /* execve never returns */ - debugger->handle_trace = debugger_syscall; - break; - - case __NR_ptrace: - if(debugger->debugee->pid != 0) arg2 = debugger->debugee->pid; - if(!debugger->debugee->in_context) - child = debugger->debugee->pid; - result = proxy_ptrace(debugger, arg1, arg2, arg3, arg4, child, - &ret); - syscall_cancel(debugger->pid, result); - debugger->handle_trace = debugger_syscall; - return(ret); - -#ifdef __NR_waitpid - case __NR_waitpid: -#endif - case __NR_wait4: - if(!debugger_wait(debugger, (int *) arg2, arg3, - debugger_syscall, debugger_normal_return, - proxy_wait_return)) - return(0); - break; - - case __NR_kill: - if(!debugger->debugee->in_context) - child = debugger->debugee->pid; - if(arg1 == debugger->debugee->pid){ - result = kill(child, arg2); - syscall_cancel(debugger->pid, result); - debugger->handle_trace = debugger_syscall; - return(0); - } - else debugger->handle_trace = debugger_normal_return; - break; - - default: - debugger->handle_trace = debugger_normal_return; - } - - syscall_continue(debugger->pid); - return(0); -} - -/* Used by the tracing thread */ -static debugger_state parent; -static int parent_syscall(debugger_state *debugger, int pid); - -int init_parent_proxy(int pid) -{ - parent = ((debugger_state) { .pid = pid, - .wait_options = 0, - .wait_status_ptr = NULL, - .waiting = 0, - .real_wait = 0, - .expecting_child = 0, - .handle_trace = parent_syscall, - .debugee = NULL } ); - return(0); -} - -int parent_normal_return(debugger_state *debugger, pid_t unused) -{ - debugger->handle_trace = parent_syscall; - syscall_continue(debugger->pid); - return(0); -} - -static int parent_syscall(debugger_state *debugger, int pid) -{ - long arg1, arg2, arg3, arg4, arg5; - int syscall; - - syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5); - - if((syscall == __NR_wait4) -#ifdef __NR_waitpid - || (syscall == __NR_waitpid) -#endif - ){ - debugger_wait(&parent, (int *) arg2, arg3, parent_syscall, - parent_normal_return, parent_wait_return); - } - else ptrace(PTRACE_SYSCALL, pid, 0, 0); - return(0); -} - -int debugger_normal_return(debugger_state *debugger, pid_t unused) -{ - debugger->handle_trace = debugger_syscall; - syscall_continue(debugger->pid); - return(0); -} - -void debugger_cancelled_return(debugger_state *debugger, int result) -{ - debugger->handle_trace = debugger_syscall; - syscall_set_result(debugger->pid, result); - syscall_continue(debugger->pid); -} - -/* Used by the tracing thread */ -static debugger_state debugger; -static debugee_state debugee; - -void init_proxy (pid_t debugger_pid, int stopped, int status) -{ - debugger.pid = debugger_pid; - debugger.handle_trace = debugger_syscall; - debugger.debugee = &debugee; - debugger.waiting = 0; - debugger.real_wait = 0; - debugger.expecting_child = 0; - - debugee.pid = 0; - debugee.traced = 0; - debugee.stopped = stopped; - debugee.event = 0; - debugee.zombie = 0; - debugee.died = 0; - debugee.wait_status = status; - debugee.in_context = 1; -} - -int debugger_proxy(int status, int pid) -{ - int ret = 0, sig; - - if(WIFSTOPPED(status)){ - sig = WSTOPSIG(status); - if (sig == SIGTRAP) - ret = (*debugger.handle_trace)(&debugger, pid); - - else if(sig == SIGCHLD){ - if(debugger.expecting_child){ - ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig); - debugger.expecting_child = 0; - } - else if(debugger.waiting) - real_wait_return(&debugger); - else { - ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig); - debugger.real_wait = 1; - } - } - else ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig); - } - else if(WIFEXITED(status)){ - tracer_panic("debugger (pid %d) exited with status %d", - debugger.pid, WEXITSTATUS(status)); - } - else if(WIFSIGNALED(status)){ - tracer_panic("debugger (pid %d) exited with signal %d", - debugger.pid, WTERMSIG(status)); - } - else { - tracer_panic("proxy got unknown status (0x%x) on debugger " - "(pid %d)", status, debugger.pid); - } - return(ret); -} - -void child_proxy(pid_t pid, int status) -{ - debugee.event = 1; - debugee.wait_status = status; - - if(WIFSTOPPED(status)){ - debugee.stopped = 1; - debugger.expecting_child = 1; - kill(debugger.pid, SIGCHLD); - } - else if(WIFEXITED(status) || WIFSIGNALED(status)){ - debugee.zombie = 1; - debugger.expecting_child = 1; - kill(debugger.pid, SIGCHLD); - } - else panic("proxy got unknown status (0x%x) on child (pid %d)", - status, pid); -} - -void debugger_parent_signal(int status, int pid) -{ - int sig; - - if(WIFSTOPPED(status)){ - sig = WSTOPSIG(status); - if(sig == SIGTRAP) (*parent.handle_trace)(&parent, pid); - else ptrace(PTRACE_SYSCALL, pid, 0, sig); - } -} - -void fake_child_exit(void) -{ - int status, pid; - - child_proxy(1, W_EXITCODE(0, 0)); - while(debugger.waiting == 1){ - CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED)); - if(pid != debugger.pid){ - printk("fake_child_exit - waitpid failed, " - "errno = %d\n", errno); - return; - } - debugger_proxy(status, debugger.pid); - } - CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED)); - if(pid != debugger.pid){ - printk("fake_child_exit - waitpid failed, " - "errno = %d\n", errno); - return; - } - if(ptrace(PTRACE_DETACH, debugger.pid, 0, SIGCONT) < 0) - printk("fake_child_exit - PTRACE_DETACH failed, errno = %d\n", - errno); -} - -char gdb_init_string[] = -"att 1 \n\ -b panic \n\ -b stop \n\ -handle SIGWINCH nostop noprint pass \n\ -"; - -int start_debugger(char *prog, int startup, int stop, int *fd_out) -{ - int slave, child; - - slave = open_gdb_chan(); - child = fork(); - if(child == 0){ - char *tempname = NULL; - int fd; - - if(setsid() < 0) perror("setsid"); - if((dup2(slave, 0) < 0) || (dup2(slave, 1) < 0) || - (dup2(slave, 2) < 0)){ - printk("start_debugger : dup2 failed, errno = %d\n", - errno); - exit(1); - } - if(ioctl(0, TIOCSCTTY, 0) < 0){ - printk("start_debugger : TIOCSCTTY failed, " - "errno = %d\n", errno); - exit(1); - } - if(tcsetpgrp (1, os_getpid()) < 0){ - printk("start_debugger : tcsetpgrp failed, " - "errno = %d\n", errno); -#ifdef notdef - exit(1); -#endif - } - fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0); - if(fd < 0){ - printk("start_debugger : make_tempfile failed," - "err = %d\n", -fd); - exit(1); - } - os_write_file(fd, gdb_init_string, - sizeof(gdb_init_string) - 1); - if(startup){ - if(stop){ - os_write_file(fd, "b start_kernel\n", - strlen("b start_kernel\n")); - } - os_write_file(fd, "c\n", strlen("c\n")); - } - if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ - printk("start_debugger : PTRACE_TRACEME failed, " - "errno = %d\n", errno); - exit(1); - } - execlp("gdb", "gdb", "--command", tempname, prog, NULL); - printk("start_debugger : exec of gdb failed, errno = %d\n", - errno); - } - if(child < 0){ - printk("start_debugger : fork for gdb failed, errno = %d\n", - errno); - return(-1); - } - *fd_out = slave; - return(child); -} - -/* - * 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/kernel/tt/ptproxy/ptproxy.h b/arch/um/kernel/tt/ptproxy/ptproxy.h deleted file mode 100644 index 5eb0285b1968..000000000000 --- a/arch/um/kernel/tt/ptproxy/ptproxy.h +++ /dev/null @@ -1,61 +0,0 @@ -/********************************************************************** -ptproxy.h - -Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing -terms and conditions. -**********************************************************************/ - -#ifndef __PTPROXY_H -#define __PTPROXY_H - -#include <sys/types.h> - -typedef struct debugger debugger_state; -typedef struct debugee debugee_state; - -struct debugger -{ - pid_t pid; - int wait_options; - int *wait_status_ptr; - unsigned int waiting : 1; - unsigned int real_wait : 1; - unsigned int expecting_child : 1; - int (*handle_trace) (debugger_state *, pid_t); - - debugee_state *debugee; -}; - -struct debugee -{ - pid_t pid; - int wait_status; - unsigned int died : 1; - unsigned int event : 1; - unsigned int stopped : 1; - unsigned int trace_singlestep : 1; - unsigned int trace_syscall : 1; - unsigned int traced : 1; - unsigned int zombie : 1; - unsigned int in_context : 1; -}; - -extern int debugger_syscall(debugger_state *debugger, pid_t pid); -extern int debugger_normal_return (debugger_state *debugger, pid_t unused); - -extern long proxy_ptrace (struct debugger *, int, pid_t, long, long, pid_t, - int *strace_out); -extern void debugger_cancelled_return(debugger_state *debugger, int result); - -#endif - -/* - * 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/kernel/tt/ptproxy/ptrace.c b/arch/um/kernel/tt/ptproxy/ptrace.c deleted file mode 100644 index 4b4f6179b212..000000000000 --- a/arch/um/kernel/tt/ptproxy/ptrace.c +++ /dev/null @@ -1,237 +0,0 @@ -/********************************************************************** -ptrace.c - -Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing -terms and conditions. - -Jeff Dike (jdike@karaya.com) : Modified for integration into uml -**********************************************************************/ - -#include <errno.h> -#include <unistd.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/wait.h> - -#include "ptproxy.h" -#include "debug.h" -#include "kern_util.h" -#include "ptrace_user.h" -#include "tt.h" -#include "os.h" - -long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2, - long arg3, long arg4, pid_t child, int *ret) -{ - sigset_t relay; - long result; - int status; - - *ret = 0; - if(debugger->debugee->died) return(-ESRCH); - - switch(arg1){ - case PTRACE_ATTACH: - if(debugger->debugee->traced) return(-EPERM); - - debugger->debugee->pid = arg2; - debugger->debugee->traced = 1; - - if(is_valid_pid(arg2) && (arg2 != child)){ - debugger->debugee->in_context = 0; - kill(arg2, SIGSTOP); - debugger->debugee->event = 1; - debugger->debugee->wait_status = W_STOPCODE(SIGSTOP); - } - else { - debugger->debugee->in_context = 1; - if(debugger->debugee->stopped) - child_proxy(child, W_STOPCODE(SIGSTOP)); - else kill(child, SIGSTOP); - } - - return(0); - - case PTRACE_DETACH: - if(!debugger->debugee->traced) return(-EPERM); - - debugger->debugee->traced = 0; - debugger->debugee->pid = 0; - if(!debugger->debugee->in_context) - kill(child, SIGCONT); - - return(0); - - case PTRACE_CONT: - if(!debugger->debugee->in_context) return(-EPERM); - *ret = PTRACE_CONT; - return(ptrace(PTRACE_CONT, child, arg3, arg4)); - -#ifdef UM_HAVE_GETFPREGS - case PTRACE_GETFPREGS: - { - long regs[FP_FRAME_SIZE]; - int i, result; - - result = ptrace(PTRACE_GETFPREGS, child, 0, regs); - if(result == -1) return(-errno); - - for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) - ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i, - regs[i]); - return(result); - } -#endif - -#ifdef UM_HAVE_GETFPXREGS - case PTRACE_GETFPXREGS: - { - long regs[FPX_FRAME_SIZE]; - int i, result; - - result = ptrace(PTRACE_GETFPXREGS, child, 0, regs); - if(result == -1) return(-errno); - - for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) - ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i, - regs[i]); - return(result); - } -#endif - -#ifdef UM_HAVE_GETREGS - case PTRACE_GETREGS: - { - long regs[FRAME_SIZE]; - int i, result; - - result = ptrace(PTRACE_GETREGS, child, 0, regs); - if(result == -1) return(-errno); - - for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) - ptrace (PTRACE_POKEDATA, debugger->pid, - arg4 + 4 * i, regs[i]); - return(result); - } - break; -#endif - - case PTRACE_KILL: - result = ptrace(PTRACE_KILL, child, arg3, arg4); - if(result == -1) return(-errno); - - return(result); - - case PTRACE_PEEKDATA: - case PTRACE_PEEKTEXT: - case PTRACE_PEEKUSR: - /* The value being read out could be -1, so we have to - * check errno to see if there's an error, and zero it - * beforehand so we're not faked out by an old error - */ - - errno = 0; - result = ptrace(arg1, child, arg3, 0); - if((result == -1) && (errno != 0)) return(-errno); - - result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result); - if(result == -1) return(-errno); - - return(result); - - case PTRACE_POKEDATA: - case PTRACE_POKETEXT: - case PTRACE_POKEUSR: - result = ptrace(arg1, child, arg3, arg4); - if(result == -1) return(-errno); - - if(arg1 == PTRACE_POKEUSR) ptrace_pokeuser(arg3, arg4); - return(result); - -#ifdef UM_HAVE_SETFPREGS - case PTRACE_SETFPREGS: - { - long regs[FP_FRAME_SIZE]; - int i; - - for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) - regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid, - arg4 + 4 * i, 0); - result = ptrace(PTRACE_SETFPREGS, child, 0, regs); - if(result == -1) return(-errno); - - return(result); - } -#endif - -#ifdef UM_HAVE_SETFPXREGS - case PTRACE_SETFPXREGS: - { - long regs[FPX_FRAME_SIZE]; - int i; - - for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) - regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid, - arg4 + 4 * i, 0); - result = ptrace(PTRACE_SETFPXREGS, child, 0, regs); - if(result == -1) return(-errno); - - return(result); - } -#endif - -#ifdef UM_HAVE_SETREGS - case PTRACE_SETREGS: - { - long regs[FRAME_SIZE]; - int i; - - for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) - regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid, - arg4 + 4 * i, 0); - result = ptrace(PTRACE_SETREGS, child, 0, regs); - if(result == -1) return(-errno); - - return(result); - } -#endif - - case PTRACE_SINGLESTEP: - if(!debugger->debugee->in_context) return(-EPERM); - sigemptyset(&relay); - sigaddset(&relay, SIGSEGV); - sigaddset(&relay, SIGILL); - sigaddset(&relay, SIGBUS); - result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4); - if(result == -1) return(-errno); - - status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP, - &relay); - child_proxy(child, status); - return(result); - - case PTRACE_SYSCALL: - if(!debugger->debugee->in_context) return(-EPERM); - result = ptrace(PTRACE_SYSCALL, child, arg3, arg4); - if(result == -1) return(-errno); - - *ret = PTRACE_SYSCALL; - return(result); - - case PTRACE_TRACEME: - default: - return(-EINVAL); - } -} - -/* - * 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/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c deleted file mode 100644 index e0e1ab0588ad..000000000000 --- a/arch/um/kernel/tt/ptproxy/sysdep.c +++ /dev/null @@ -1,70 +0,0 @@ -/********************************************************************** -sysdep.c - -Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing -terms and conditions. -**********************************************************************/ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <signal.h> -#include <errno.h> -#include <sys/types.h> -#include <linux/unistd.h> -#include "ptrace_user.h" -#include "user.h" -#include "os.h" - -int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4, - long *arg5) -{ - *arg1 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG1_OFFSET, 0); - *arg2 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG2_OFFSET, 0); - *arg3 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG3_OFFSET, 0); - *arg4 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG4_OFFSET, 0); - *arg5 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG5_OFFSET, 0); - return(ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET, 0)); -} - -void syscall_cancel(pid_t pid, int result) -{ - if((ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, - __NR_getpid) < 0) || - (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) || - (wait_for_stop(pid, SIGTRAP, PTRACE_SYSCALL, NULL) < 0) || - (ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, result) < 0) || - (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)) - printk("ptproxy: couldn't cancel syscall: errno = %d\n", - errno); -} - -void syscall_set_result(pid_t pid, long result) -{ - ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, result); -} - -void syscall_continue(pid_t pid) -{ - ptrace(PTRACE_SYSCALL, pid, 0, 0); -} - -int syscall_pause(pid_t pid) -{ - if(ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, __NR_pause) < 0){ - printk("syscall_change - ptrace failed, errno = %d\n", errno); - return(-1); - } - return(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/kernel/tt/ptproxy/sysdep.h b/arch/um/kernel/tt/ptproxy/sysdep.h deleted file mode 100644 index 735f488049aa..000000000000 --- a/arch/um/kernel/tt/ptproxy/sysdep.h +++ /dev/null @@ -1,25 +0,0 @@ -/********************************************************************** -sysdep.h - -Copyright (C) 1999 Lars Brinkhoff. -Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -See the file COPYING for licensing terms and conditions. -**********************************************************************/ - -extern int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, - long *arg4, long *arg5); -extern void syscall_cancel (pid_t pid, long result); -extern void syscall_set_result (pid_t pid, long result); -extern void syscall_continue (pid_t pid); -extern int syscall_pause(pid_t pid); - -/* - * 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/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c deleted file mode 100644 index bdd4af4b65fc..000000000000 --- a/arch/um/kernel/tt/ptproxy/wait.c +++ /dev/null @@ -1,85 +0,0 @@ -/********************************************************************** -wait.c - -Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing -terms and conditions. - -**********************************************************************/ - -#include <errno.h> -#include <signal.h> -#include <sys/wait.h> - -#include "ptproxy.h" -#include "sysdep.h" -#include "wait.h" -#include "ptrace_user.h" -#include "sysdep/ptrace.h" -#include "sysdep/sigcontext.h" - -int proxy_wait_return(struct debugger *debugger, pid_t unused) -{ - debugger->waiting = 0; - - if(debugger->debugee->died || (debugger->wait_options & __WCLONE)){ - debugger_cancelled_return(debugger, -ECHILD); - return(0); - } - - if(debugger->debugee->zombie && debugger->debugee->event) - debugger->debugee->died = 1; - - if(debugger->debugee->event){ - debugger->debugee->event = 0; - ptrace(PTRACE_POKEDATA, debugger->pid, - debugger->wait_status_ptr, - debugger->debugee->wait_status); - /* if (wait4) - ptrace (PTRACE_POKEDATA, pid, rusage_ptr, ...); */ - debugger_cancelled_return(debugger, debugger->debugee->pid); - return(0); - } - - /* pause will return -EINTR, which happens to be right for wait */ - debugger_normal_return(debugger, -1); - return(0); -} - -int parent_wait_return(struct debugger *debugger, pid_t unused) -{ - return(debugger_normal_return(debugger, -1)); -} - -int real_wait_return(struct debugger *debugger) -{ - unsigned long ip; - int pid; - - pid = debugger->pid; - - ip = ptrace(PTRACE_PEEKUSR, pid, PT_IP_OFFSET, 0); - IP_RESTART_SYSCALL(ip); - - if(ptrace(PTRACE_POKEUSR, pid, PT_IP_OFFSET, ip) < 0) - tracer_panic("real_wait_return : Failed to restart system " - "call, errno = %d\n", errno); - - if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) || - (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) || - (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) || - debugger_normal_return(debugger, -1)) - tracer_panic("real_wait_return : gdb failed to wait, " - "errno = %d\n", errno); - return(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/kernel/tt/ptproxy/wait.h b/arch/um/kernel/tt/ptproxy/wait.h deleted file mode 100644 index 542e73ee2cee..000000000000 --- a/arch/um/kernel/tt/ptproxy/wait.h +++ /dev/null @@ -1,15 +0,0 @@ -/********************************************************************** -wait.h - -Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing -terms and conditions. -**********************************************************************/ - -#ifndef __PTPROXY_WAIT_H -#define __PTPROXY_WAIT_H - -extern int proxy_wait_return(struct debugger *debugger, pid_t unused); -extern int real_wait_return(struct debugger *debugger); -extern int parent_wait_return(struct debugger *debugger, pid_t unused); - -#endif diff --git a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c deleted file mode 100644 index 293caa6d0c2d..000000000000 --- a/arch/um/kernel/tt/syscall_kern.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include "linux/types.h" -#include "linux/utime.h" -#include "linux/sys.h" -#include "linux/ptrace.h" -#include "asm/unistd.h" -#include "asm/ptrace.h" -#include "asm/uaccess.h" -#include "asm/stat.h" -#include "sysdep/syscalls.h" -#include "sysdep/sigcontext.h" -#include "kern_util.h" -#include "syscall.h" - -void syscall_handler_tt(int sig, struct pt_regs *regs) -{ - void *sc; - long result; - int syscall; - - sc = UPT_SC(®s->regs); - SC_START_SYSCALL(sc); - - syscall = UPT_SYSCALL_NR(®s->regs); - syscall_trace(®s->regs, 0); - - current->thread.nsyscalls++; - nsyscalls++; - - if((syscall >= NR_syscalls) || (syscall < 0)) - result = -ENOSYS; - else result = EXECUTE_SYSCALL(syscall, regs); - - /* regs->sc may have changed while the system call ran (there may - * have been an interrupt or segfault), so it needs to be refreshed. - */ - UPT_SC(®s->regs) = sc; - - SC_SET_SYSCALL_RETURN(sc, result); - - syscall_trace(®s->regs, 1); -} diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c deleted file mode 100644 index f52b47aff1d2..000000000000 --- a/arch/um/kernel/tt/syscall_user.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include <unistd.h> -#include <signal.h> -#include <errno.h> -#include <asm/unistd.h> -#include "sysdep/ptrace.h" -#include "sigcontext.h" -#include "ptrace_user.h" -#include "task.h" -#include "kern_util.h" -#include "syscall.h" -#include "tt.h" - -void do_sigtrap(void *task) -{ - UPT_SYSCALL_NR(TASK_REGS(task)) = -1; -} - -void do_syscall(void *task, int pid, int local_using_sysemu) -{ - unsigned long proc_regs[FRAME_SIZE]; - - if(ptrace_getregs(pid, proc_regs) < 0) - tracer_panic("Couldn't read registers"); - - UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs); - -#ifdef UPT_ORIGGPR2 - UPT_ORIGGPR2(TASK_REGS(task)) = REGS_ORIGGPR2(proc_regs); -#endif - - if(((unsigned long *) PT_IP(proc_regs) >= &_stext) && - ((unsigned long *) PT_IP(proc_regs) <= &_etext)) - tracer_panic("I'm tracing myself and I can't get out"); - - /* advanced sysemu mode set syscall number to -1 automatically */ - if (local_using_sysemu==2) - return; - - /* syscall number -1 in sysemu skips syscall restarting in host */ - if(ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, - local_using_sysemu ? -1 : __NR_getpid) < 0) - tracer_panic("do_syscall : Nullifying syscall failed, " - "errno = %d", errno); -} - -/* - * 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/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c deleted file mode 100644 index 7caa24fe05df..000000000000 --- a/arch/um/kernel/tt/tlb.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Copyright 2003 PathScale, Inc. - * Licensed under the GPL - */ - -#include "linux/stddef.h" -#include "linux/kernel.h" -#include "linux/sched.h" -#include "linux/mm.h" -#include "asm/page.h" -#include "asm/pgtable.h" -#include "asm/uaccess.h" -#include "asm/tlbflush.h" -#include "mem_user.h" -#include "os.h" -#include "tlb.h" - -static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, - int finished, void **flush) -{ - struct host_vm_op *op; - int i, ret=0; - - for(i = 0; i <= last && !ret; i++){ - op = &ops[i]; - switch(op->type){ - case MMAP: - ret = os_map_memory((void *) op->u.mmap.addr, - op->u.mmap.fd, op->u.mmap.offset, - op->u.mmap.len, op->u.mmap.r, - op->u.mmap.w, op->u.mmap.x); - break; - case MUNMAP: - ret = os_unmap_memory((void *) op->u.munmap.addr, - op->u.munmap.len); - break; - case MPROTECT: - ret = protect_memory(op->u.mprotect.addr, - op->u.munmap.len, - op->u.mprotect.r, - op->u.mprotect.w, - op->u.mprotect.x, 1); - protect_memory(op->u.mprotect.addr, op->u.munmap.len, - op->u.mprotect.r, op->u.mprotect.w, - op->u.mprotect.x, 1); - break; - default: - printk("Unknown op type %d in do_ops\n", op->type); - break; - } - } - - return ret; -} - -static void fix_range(struct mm_struct *mm, unsigned long start_addr, - unsigned long end_addr, int force) -{ - if((current->thread.mode.tt.extern_pid != -1) && - (current->thread.mode.tt.extern_pid != os_getpid())) - panic("fix_range fixing wrong address space, current = 0x%p", - current); - - fix_range_common(mm, start_addr, end_addr, force, do_ops); -} - -atomic_t vmchange_seq = ATOMIC_INIT(1); - -void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end) -{ - if(flush_tlb_kernel_range_common(start, end)) - atomic_inc(&vmchange_seq); -} - -void flush_tlb_kernel_vm_tt(void) -{ - flush_tlb_kernel_range(start_vm, end_vm); -} - -void __flush_tlb_one_tt(unsigned long addr) -{ - flush_tlb_kernel_range(addr, addr + PAGE_SIZE); -} - -void flush_tlb_range_tt(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - if(vma->vm_mm != current->mm) return; - - /* Assumes that the range start ... end is entirely within - * either process memory or kernel vm - */ - if((start >= start_vm) && (start < end_vm)){ - if(flush_tlb_kernel_range_common(start, end)) - atomic_inc(&vmchange_seq); - } - else fix_range(vma->vm_mm, start, end, 0); -} - -void flush_tlb_mm_tt(struct mm_struct *mm) -{ - unsigned long seq; - - if(mm != current->mm) return; - - fix_range(mm, 0, STACK_TOP, 0); - - seq = atomic_read(&vmchange_seq); - if(current->thread.mode.tt.vm_seq == seq) - return; - current->thread.mode.tt.vm_seq = seq; - flush_tlb_kernel_range_common(start_vm, end_vm); -} - -void force_flush_all_tt(void) -{ - fix_range(current->mm, 0, STACK_TOP, 1); - flush_tlb_kernel_range_common(start_vm, end_vm); -} diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c deleted file mode 100644 index c23588393f6e..000000000000 --- a/arch/um/kernel/tt/tracer.c +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <unistd.h> -#include <signal.h> -#include <errno.h> -#include <sched.h> -#include <string.h> -#include <sys/mman.h> -#include <sys/time.h> -#include <sys/wait.h> -#include "user.h" -#include "sysdep/ptrace.h" -#include "sigcontext.h" -#include "sysdep/sigcontext.h" -#include "os.h" -#include "mem_user.h" -#include "process.h" -#include "kern_util.h" -#include "chan_user.h" -#include "ptrace_user.h" -#include "irq_user.h" -#include "mode.h" -#include "tt.h" - -static int tracer_winch[2]; - -int is_tracer_winch(int pid, int fd, void *data) -{ - if(pid != os_getpgrp()) - return(0); - - register_winch_irq(tracer_winch[0], fd, -1, data); - return(1); -} - -static void tracer_winch_handler(int sig) -{ - int n; - char c = 1; - - n = os_write_file(tracer_winch[1], &c, sizeof(c)); - if(n != sizeof(c)) - printk("tracer_winch_handler - write failed, err = %d\n", -n); -} - -/* Called only by the tracing thread during initialization */ - -static void setup_tracer_winch(void) -{ - int err; - - err = os_pipe(tracer_winch, 1, 1); - if(err < 0){ - printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err); - return; - } - signal(SIGWINCH, tracer_winch_handler); -} - -void attach_process(int pid) -{ - if((ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) || - (ptrace(PTRACE_CONT, pid, 0, 0) < 0)) - tracer_panic("OP_FORK failed to attach pid"); - wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL); - if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) - tracer_panic("OP_FORK: PTRACE_SETOPTIONS failed, errno = %d", errno); - if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) - tracer_panic("OP_FORK failed to continue process"); -} - -void tracer_panic(char *format, ...) -{ - va_list ap; - - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - printf("\n"); - while(1) pause(); -} - -static void tracer_segv(int sig, struct sigcontext sc) -{ - struct faultinfo fi; - GET_FAULTINFO_FROM_SC(fi, &sc); - printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n", - FAULT_ADDRESS(fi), SC_IP(&sc)); - while(1) - pause(); -} - -/* Changed early in boot, and then only read */ -int debug = 0; -int debug_stop = 1; -int debug_parent = 0; -int honeypot = 0; - -static int signal_tramp(void *arg) -{ - int (*proc)(void *); - - if(honeypot && munmap((void *) (host_task_size - 0x10000000), - 0x10000000)) - panic("Unmapping stack failed"); - if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) - panic("ptrace PTRACE_TRACEME failed"); - os_stop_process(os_getpid()); - change_sig(SIGWINCH, 0); - signal(SIGUSR1, SIG_IGN); - change_sig(SIGCHLD, 0); - signal(SIGSEGV, (__sighandler_t) sig_handler); - set_cmdline("(idle thread)"); - set_init_pid(os_getpid()); - init_irq_signals(0); - proc = arg; - return((*proc)(NULL)); -} - -static void sleeping_process_signal(int pid, int sig) -{ - switch(sig){ - /* These two result from UML being ^Z-ed and bg-ed. PTRACE_CONT is - * right because the process must be in the kernel already. - */ - case SIGCONT: - case SIGTSTP: - if(ptrace(PTRACE_CONT, pid, 0, sig) < 0) - tracer_panic("sleeping_process_signal : Failed to " - "continue pid %d, signal = %d, " - "errno = %d\n", pid, sig, errno); - break; - - /* This happens when the debugger (e.g. strace) is doing system call - * tracing on the kernel. During a context switch, the current task - * will be set to the incoming process and the outgoing process will - * hop into write and then read. Since it's not the current process - * any more, the trace of those will land here. So, we need to just - * PTRACE_SYSCALL it. - */ - case (SIGTRAP + 0x80): - if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) - tracer_panic("sleeping_process_signal : Failed to " - "PTRACE_SYSCALL pid %d, errno = %d\n", - pid, errno); - break; - case SIGSTOP: - break; - default: - tracer_panic("sleeping process %d got unexpected " - "signal : %d\n", pid, sig); - break; - } -} - -/* Accessed only by the tracing thread */ -int debugger_pid = -1; -int debugger_parent = -1; -int debugger_fd = -1; -int gdb_pid = -1; - -struct { - int pid; - int signal; - unsigned long addr; - struct timeval time; -} signal_record[1024][32]; - -int signal_index[32]; -int nsignals = 0; -int debug_trace = 0; - -extern void signal_usr1(int sig); - -int tracing_pid = -1; - -int tracer(int (*init_proc)(void *), void *sp) -{ - void *task = NULL; - int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0; - int proc_id = 0, n, err, old_tracing = 0, strace = 0; - int local_using_sysemu = 0; - - signal(SIGPIPE, SIG_IGN); - setup_tracer_winch(); - tracing_pid = os_getpid(); - printf("tracing thread pid = %d\n", tracing_pid); - - pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc); - CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0){ - printf("waitpid on idle thread failed, errno = %d\n", errno); - exit(1); - } - if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) { - printf("Failed to PTRACE_SETOPTIONS for idle thread, errno = %d\n", errno); - exit(1); - } - if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){ - printf("Failed to continue idle thread, errno = %d\n", errno); - exit(1); - } - - signal(SIGSEGV, (sighandler_t) tracer_segv); - signal(SIGUSR1, signal_usr1); - if(debug_trace){ - printf("Tracing thread pausing to be attached\n"); - stop(); - } - if(debug){ - if(gdb_pid != -1) - debugger_pid = attach_debugger(pid, gdb_pid, 1); - else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop); - if(debug_parent){ - debugger_parent = os_process_parent(debugger_pid); - init_parent_proxy(debugger_parent); - err = attach(debugger_parent); - if(err){ - printf("Failed to attach debugger parent %d, " - "errno = %d\n", debugger_parent, -err); - debugger_parent = -1; - } - else { - if(ptrace(PTRACE_SYSCALL, debugger_parent, - 0, 0) < 0){ - printf("Failed to continue debugger " - "parent, errno = %d\n", errno); - debugger_parent = -1; - } - } - } - } - set_cmdline("(tracing thread)"); - while(1){ - CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED)); - if(pid <= 0){ - if(errno != ECHILD){ - printf("wait failed - errno = %d\n", errno); - } - continue; - } - if(pid == debugger_pid){ - int cont = 0; - - if(WIFEXITED(status) || WIFSIGNALED(status)) - debugger_pid = -1; - /* XXX Figure out how to deal with gdb and SMP */ - else cont = debugger_signal(status, cpu_tasks[0].pid); - if(cont == PTRACE_SYSCALL) strace = 1; - continue; - } - else if(pid == debugger_parent){ - debugger_parent_signal(status, pid); - continue; - } - nsignals++; - if(WIFEXITED(status)) ; -#ifdef notdef - { - printf("Child %d exited with status %d\n", pid, - WEXITSTATUS(status)); - } -#endif - else if(WIFSIGNALED(status)){ - sig = WTERMSIG(status); - if(sig != 9){ - printf("Child %d exited with signal %d\n", pid, - sig); - } - } - else if(WIFSTOPPED(status)){ - proc_id = pid_to_processor_id(pid); - sig = WSTOPSIG(status); - if(proc_id == -1){ - sleeping_process_signal(pid, sig); - continue; - } - - task = cpu_tasks[proc_id].task; - tracing = is_tracing(task); - old_tracing = tracing; - - /* Assume: no syscall, when coming from user */ - if ( tracing ) - do_sigtrap(task); - - switch(sig){ - case SIGUSR1: - sig = 0; - op = do_proc_op(task, proc_id); - switch(op){ - /* - * This is called when entering user mode; after - * this, we start intercepting syscalls. - * - * In fact, a process is started in kernel mode, - * so with is_tracing() == 0 (and that is reset - * when executing syscalls, since UML kernel has - * the right to do syscalls); - */ - case OP_TRACE_ON: - arch_leave_kernel(task, pid); - tracing = 1; - break; - case OP_REBOOT: - case OP_HALT: - unmap_physmem(); - kmalloc_ok = 0; - os_kill_ptraced_process(pid, 0); - /* Now let's reap remaining zombies */ - errno = 0; - do { - waitpid(-1, &status, - WUNTRACED); - } while (errno != ECHILD); - return(op == OP_REBOOT); - case OP_NONE: - printf("Detaching pid %d\n", pid); - detach(pid, SIGSTOP); - continue; - default: - break; - } - /* OP_EXEC switches host processes on us, - * we want to continue the new one. - */ - pid = cpu_tasks[proc_id].pid; - break; - case (SIGTRAP + 0x80): - if(!tracing && (debugger_pid != -1)){ - child_signal(pid, status & 0x7fff); - continue; - } - tracing = 0; - /* local_using_sysemu has been already set - * below, since if we are here, is_tracing() on - * the traced task was 1, i.e. the process had - * already run through one iteration of the - * loop which executed a OP_TRACE_ON request.*/ - do_syscall(task, pid, local_using_sysemu); - sig = SIGUSR2; - break; - case SIGTRAP: - if(!tracing && (debugger_pid != -1)){ - child_signal(pid, status); - continue; - } - tracing = 0; - break; - case SIGPROF: - if(tracing) sig = 0; - break; - case SIGCHLD: - case SIGHUP: - sig = 0; - break; - case SIGSEGV: - case SIGIO: - case SIGALRM: - case SIGVTALRM: - case SIGFPE: - case SIGBUS: - case SIGILL: - case SIGWINCH: - - default: - tracing = 0; - break; - } - set_tracing(task, tracing); - - if(!tracing && old_tracing) - arch_enter_kernel(task, pid); - - if(!tracing && (debugger_pid != -1) && (sig != 0) && - (sig != SIGALRM) && (sig != SIGVTALRM) && - (sig != SIGSEGV) && (sig != SIGTRAP) && - (sig != SIGUSR2) && (sig != SIGIO) && - (sig != SIGFPE)){ - child_signal(pid, status); - continue; - } - - local_using_sysemu = get_using_sysemu(); - - if(tracing) - cont_type = SELECT_PTRACE_OPERATION(local_using_sysemu, - singlestepping(task)); - else if((debugger_pid != -1) && strace) - cont_type = PTRACE_SYSCALL; - else - cont_type = PTRACE_CONT; - - if(ptrace(cont_type, pid, 0, sig) != 0){ - tracer_panic("ptrace failed to continue " - "process - errno = %d\n", - errno); - } - } - } - return(0); -} - -static int __init uml_debug_setup(char *line, int *add) -{ - char *next; - - debug = 1; - *add = 0; - if(*line != '=') return(0); - line++; - - while(line != NULL){ - next = strchr(line, ','); - if(next) *next++ = '\0'; - - if(!strcmp(line, "go")) debug_stop = 0; - else if(!strcmp(line, "parent")) debug_parent = 1; - else printf("Unknown debug option : '%s'\n", line); - - line = next; - } - return(0); -} - -__uml_setup("debug", uml_debug_setup, -"debug\n" -" Starts up the kernel under the control of gdb. See the \n" -" kernel debugging tutorial and the debugging session pages\n" -" at http://user-mode-linux.sourceforge.net/ for more information.\n\n" -); - -static int __init uml_debugtrace_setup(char *line, int *add) -{ - debug_trace = 1; - return 0; -} -__uml_setup("debugtrace", uml_debugtrace_setup, -"debugtrace\n" -" Causes the tracing thread to pause until it is attached by a\n" -" debugger and continued. This is mostly for debugging crashes\n" -" early during boot, and should be pretty much obsoleted by\n" -" the debug switch.\n\n" -); - -/* - * 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/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c deleted file mode 100644 index 3032eb5e2467..000000000000 --- a/arch/um/kernel/tt/trap_user.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include <stdlib.h> -#include <errno.h> -#include <signal.h> -#include "sysdep/ptrace.h" -#include "sysdep/sigcontext.h" -#include "kern_util.h" -#include "task.h" -#include "tt.h" -#include "os.h" - -void sig_handler_common_tt(int sig, void *sc_ptr) -{ - struct sigcontext *sc = sc_ptr; - struct tt_regs save_regs, *r; - int save_errno = errno, is_user = 0; - void (*handler)(int, union uml_pt_regs *); - - /* This is done because to allow SIGSEGV to be delivered inside a SEGV - * handler. This can happen in copy_user, and if SEGV is disabled, - * the process will die. - */ - if(sig == SIGSEGV) - change_sig(SIGSEGV, 1); - - r = &TASK_REGS(get_current())->tt; - if ( sig == SIGFPE || sig == SIGSEGV || - sig == SIGBUS || sig == SIGILL || - sig == SIGTRAP ) { - GET_FAULTINFO_FROM_SC(r->faultinfo, sc); - } - save_regs = *r; - if (sc) - is_user = user_context(SC_SP(sc)); - r->sc = sc; - if(sig != SIGUSR2) - r->syscall = -1; - - handler = sig_info[sig]; - - /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */ - if (sig != SIGIO && sig != SIGWINCH && - sig != SIGVTALRM && sig != SIGALRM) - unblock_signals(); - - handler(sig, (union uml_pt_regs *) r); - - if(is_user){ - interrupt_end(); - block_signals(); - set_user_mode(NULL); - } - *r = save_regs; - errno = save_errno; -} - -/* - * 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/kernel/tt/uaccess.c b/arch/um/kernel/tt/uaccess.c deleted file mode 100644 index 1cb60726567e..000000000000 --- a/arch/um/kernel/tt/uaccess.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include "linux/sched.h" -#include "asm/uaccess.h" - -int copy_from_user_tt(void *to, const void __user *from, int n) -{ - if(!access_ok(VERIFY_READ, from, n)) - return(n); - - return(__do_copy_from_user(to, from, n, ¤t->thread.fault_addr, - ¤t->thread.fault_catcher)); -} - -int copy_to_user_tt(void __user *to, const void *from, int n) -{ - if(!access_ok(VERIFY_WRITE, to, n)) - return(n); - - return(__do_copy_to_user(to, from, n, ¤t->thread.fault_addr, - ¤t->thread.fault_catcher)); -} - -int strncpy_from_user_tt(char *dst, const char __user *src, int count) -{ - int n; - - if(!access_ok(VERIFY_READ, src, 1)) - return(-EFAULT); - - n = __do_strncpy_from_user(dst, src, count, - ¤t->thread.fault_addr, - ¤t->thread.fault_catcher); - if(n < 0) return(-EFAULT); - return(n); -} - -int __clear_user_tt(void __user *mem, int len) -{ - return(__do_clear_user(mem, len, - ¤t->thread.fault_addr, - ¤t->thread.fault_catcher)); -} - -int clear_user_tt(void __user *mem, int len) -{ - if(!access_ok(VERIFY_WRITE, mem, len)) - return(len); - - return(__do_clear_user(mem, len, ¤t->thread.fault_addr, - ¤t->thread.fault_catcher)); -} - -int strnlen_user_tt(const void __user *str, int len) -{ - return(__do_strnlen_user(str, len, - ¤t->thread.fault_addr, - ¤t->thread.fault_catcher)); -} - -/* - * 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/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c deleted file mode 100644 index 0e5c82c5e5b7..000000000000 --- a/arch/um/kernel/tt/uaccess_user.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk) - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include <string.h> -#include "uml_uaccess.h" -#include "task.h" -#include "kern_util.h" -#include "os.h" -#include "longjmp.h" - -int __do_copy_from_user(void *to, const void *from, int n, - void **fault_addr, void **fault_catcher) -{ - struct tt_regs save = TASK_REGS(get_current())->tt; - unsigned long fault; - int faulted; - - fault = __do_user_copy(to, from, n, fault_addr, fault_catcher, - __do_copy, &faulted); - TASK_REGS(get_current())->tt = save; - - if(!faulted) - return 0; - else if (fault) - return n - (fault - (unsigned long) from); - else - /* In case of a general protection fault, we don't have the - * fault address, so NULL is used instead. Pretend we didn't - * copy anything. */ - return n; -} - -static void __do_strncpy(void *dst, const void *src, int count) -{ - strncpy(dst, src, count); -} - -int __do_strncpy_from_user(char *dst, const char *src, unsigned long count, - void **fault_addr, void **fault_catcher) -{ - struct tt_regs save = TASK_REGS(get_current())->tt; - unsigned long fault; - int faulted; - - fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher, - __do_strncpy, &faulted); - TASK_REGS(get_current())->tt = save; - - if(!faulted) return(strlen(dst)); - else return(-1); -} - -static void __do_clear(void *to, const void *from, int n) -{ - memset(to, 0, n); -} - -int __do_clear_user(void *mem, unsigned long len, - void **fault_addr, void **fault_catcher) -{ - struct tt_regs save = TASK_REGS(get_current())->tt; - unsigned long fault; - int faulted; - - fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher, - __do_clear, &faulted); - TASK_REGS(get_current())->tt = save; - - if(!faulted) return(0); - else return(len - (fault - (unsigned long) mem)); -} - -int __do_strnlen_user(const char *str, unsigned long n, - void **fault_addr, void **fault_catcher) -{ - struct tt_regs save = TASK_REGS(get_current())->tt; - int ret; - unsigned long *faddrp = (unsigned long *)fault_addr; - jmp_buf jbuf; - - *fault_catcher = &jbuf; - if(UML_SETJMP(&jbuf) == 0) - ret = strlen(str) + 1; - else ret = *faddrp - (unsigned long) str; - - *fault_addr = NULL; - *fault_catcher = NULL; - - TASK_REGS(get_current())->tt = save; - 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/kernel/uaccess.c b/arch/um/kernel/uaccess.c index 054e3de0784e..d7436aacd26f 100644 --- a/arch/um/kernel/uaccess.c +++ b/arch/um/kernel/uaccess.c @@ -18,7 +18,7 @@ void __do_copy(void *to, const void *from, int n) int __do_copy_to_user(void *to, const void *from, int n, - void **fault_addr, void **fault_catcher) + void **fault_addr, jmp_buf **fault_catcher) { unsigned long fault; int faulted; diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index ecc458fe51b9..f1c71393f578 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -1,46 +1,24 @@ /* - * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/kernel.h" -#include "linux/sched.h" -#include "linux/notifier.h" -#include "linux/mm.h" -#include "linux/types.h" -#include "linux/tty.h" -#include "linux/init.h" -#include "linux/bootmem.h" -#include "linux/spinlock.h" -#include "linux/utsname.h" -#include "linux/sysrq.h" -#include "linux/seq_file.h" #include "linux/delay.h" +#include "linux/mm.h" #include "linux/module.h" +#include "linux/seq_file.h" +#include "linux/string.h" #include "linux/utsname.h" -#include "asm/page.h" #include "asm/pgtable.h" -#include "asm/ptrace.h" -#include "asm/elf.h" -#include "asm/user.h" +#include "asm/processor.h" #include "asm/setup.h" -#include "ubd_user.h" -#include "asm/current.h" -#include "kern_util.h" -#include "as-layout.h" #include "arch.h" +#include "as-layout.h" +#include "init.h" #include "kern.h" #include "mem_user.h" -#include "mem.h" -#include "initrd.h" -#include "init.h" #include "os.h" -#include "choose-mode.h" -#include "mode_kern.h" -#include "mode.h" -#ifdef UML_CONFIG_MODE_SKAS #include "skas.h" -#endif #define DEFAULT_COMMAND_LINE "root=98:0" @@ -53,7 +31,7 @@ static void __init add_arg(char *arg) printf("add_arg: Too many command line arguments!\n"); exit(1); } - if(strlen(command_line) > 0) + if (strlen(command_line) > 0) strcat(command_line, " "); strcat(command_line, arg); } @@ -70,8 +48,8 @@ struct cpuinfo_um boot_cpu_data = { unsigned long thread_saved_pc(struct task_struct *task) { - return os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas, - task)); + /* FIXME: Need to look up userspace_pid by cpu */ + return os_process_pc(userspace_pid[0]); } /* Changed in setup_arch, which is called in early boot */ @@ -90,7 +68,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "processor\t: %d\n", index); seq_printf(m, "vendor_id\t: User Mode Linux\n"); seq_printf(m, "model name\t: UML\n"); - seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas")); + seq_printf(m, "mode\t\t: skas\n"); seq_printf(m, "host\t\t: %s\n", host_info); seq_printf(m, "bogomips\t: %lu.%02lu\n\n", loops_per_jiffy/(500000/HZ), @@ -132,44 +110,13 @@ unsigned long end_vm; /* Set in uml_ncpus_setup */ int ncpus = 1; -#ifdef CONFIG_CMDLINE_ON_HOST -/* Pointer set in linux_main, the array itself is private to each thread, - * and changed at address space creation time so this poses no concurrency - * problems. - */ -static char *argv1_begin = NULL; -static char *argv1_end = NULL; -#endif - /* Set in early boot */ static int have_root __initdata = 0; /* Set in uml_mem_setup and modified in linux_main */ long long physmem_size = 32 * 1024 * 1024; -void set_cmdline(char *cmd) -{ -#ifdef CONFIG_CMDLINE_ON_HOST - char *umid, *ptr; - - if(CHOOSE_MODE(honeypot, 0)) return; - - umid = get_umid(); - if(*umid != '\0'){ - snprintf(argv1_begin, - (argv1_end - argv1_begin) * sizeof(*ptr), - "(%s) ", umid); - ptr = &argv1_begin[strlen(argv1_begin)]; - } - else ptr = argv1_begin; - - snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd); - memset(argv1_begin + strlen(argv1_begin), '\0', - argv1_end - argv1_begin - strlen(argv1_begin)); -#endif -} - -static char *usage_string = +static char *usage_string = "User Mode Linux v%s\n" " available at http://user-mode-linux.sourceforge.net/\n\n"; @@ -201,13 +148,10 @@ __uml_setup("root=", uml_root_setup, " root=/dev/ubd5\n\n" ); -#ifndef CONFIG_MODE_TT - static int __init no_skas_debug_setup(char *line, int *add) { printf("'debug' is not necessary to gdb UML in skas mode - run \n"); - printf("'gdb linux' and disable CONFIG_CMDLINE_ON_HOST if gdb \n"); - printf("doesn't work as expected\n"); + printf("'gdb linux'"); return 0; } @@ -217,8 +161,6 @@ __uml_setup("debug", no_skas_debug_setup, " this flag is not needed to run gdb on UML in skas mode\n\n" ); -#endif - #ifdef CONFIG_SMP static int __init uml_ncpus_setup(char *line, int *add) { @@ -232,56 +174,10 @@ static int __init uml_ncpus_setup(char *line, int *add) __uml_setup("ncpus=", uml_ncpus_setup, "ncpus=<# of desired CPUs>\n" -" This tells an SMP kernel how many virtual processors to start.\n\n" +" This tells an SMP kernel how many virtual processors to start.\n\n" ); #endif -static int force_tt = 0; - -#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS) -#define DEFAULT_TT 0 - -static int __init mode_tt_setup(char *line, int *add) -{ - force_tt = 1; - return 0; -} - -#else -#ifdef CONFIG_MODE_SKAS - -#define DEFAULT_TT 0 - -static int __init mode_tt_setup(char *line, int *add) -{ - printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n"); - return 0; -} - -#else -#ifdef CONFIG_MODE_TT - -#define DEFAULT_TT 1 - -static int __init mode_tt_setup(char *line, int *add) -{ - printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n"); - return 0; -} - -#endif -#endif -#endif - -__uml_setup("mode=tt", mode_tt_setup, -"mode=tt\n" -" When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n" -" forces UML to run in tt (tracing thread) mode. It is not the default\n" -" because it's slower and less secure than skas mode.\n\n" -); - -int mode_tt = DEFAULT_TT; - static int __init Usage(char *line, int *add) { const char **p; @@ -310,9 +206,8 @@ static int __init uml_checksetup(char *line, int *add) int n; n = strlen(p->str); - if(!strncmp(line, p->str, n)){ - if (p->setup_func(line + n, add)) return 1; - } + if (!strncmp(line, p->str, n) && p->setup_func(line + n, add)) + return 1; p++; } return 0; @@ -323,7 +218,7 @@ static void __init uml_postsetup(void) initcall_t *p; p = &__uml_postsetup_start; - while(p < &__uml_postsetup_end){ + while(p < &__uml_postsetup_end) { (*p)(); p++; } @@ -339,6 +234,20 @@ EXPORT_SYMBOL(end_iomem); extern char __binary_start; +static unsigned long set_task_sizes_skas(unsigned long *task_size_out) +{ + /* Round up to the nearest 4M */ + unsigned long host_task_size = ROUND_4M((unsigned long) + &host_task_size); + + if (!skas_needs_stub) + *task_size_out = host_task_size; + else + *task_size_out = STUB_START & PGDIR_MASK; + + return host_task_size; +} + int __init linux_main(int argc, char **argv) { unsigned long avail, diff; @@ -346,45 +255,30 @@ int __init linux_main(int argc, char **argv) unsigned int i, add; char * mode; - for (i = 1; i < argc; i++){ - if((i == 1) && (argv[i][0] == ' ')) continue; + for (i = 1; i < argc; i++) { + if ((i == 1) && (argv[i][0] == ' ')) + continue; add = 1; uml_checksetup(argv[i], &add); if (add) add_arg(argv[i]); } - if(have_root == 0) + if (have_root == 0) add_arg(DEFAULT_COMMAND_LINE); + /* OS sanity checks that need to happen before the kernel runs */ os_early_checks(); - if (force_tt) - clear_can_do_skas(); - mode_tt = force_tt ? 1 : !can_do_skas(); -#ifndef CONFIG_MODE_TT - if (mode_tt) { - /*Since CONFIG_MODE_TT is #undef'ed, force_tt cannot be 1. So, - * can_do_skas() returned 0, and the message is correct. */ - printf("Support for TT mode is disabled, and no SKAS support is present on the host.\n"); - exit(1); - } -#endif -#ifndef CONFIG_MODE_SKAS - mode = "TT"; -#else - /* Show to the user the result of selection */ - if (mode_tt) - mode = "TT"; - else if (proc_mm && ptrace_faultinfo) + can_do_skas(); + + if (proc_mm && ptrace_faultinfo) mode = "SKAS3"; else mode = "SKAS0"; -#endif printf("UML running in %s mode\n", mode); - host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt, - set_task_sizes_skas, &task_size); + host_task_size = set_task_sizes_skas(&task_size); /* * Setting up handlers to 'sig_info' struct @@ -392,13 +286,15 @@ int __init linux_main(int argc, char **argv) os_fill_handlinfo(handlinfo_kern); brk_start = (unsigned long) sbrk(0); - CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start); - /* Increase physical memory size for exec-shield users - so they actually get what they asked for. This should - add zero for non-exec shield users */ + + /* + * Increase physical memory size for exec-shield users + * so they actually get what they asked for. This should + * add zero for non-exec shield users + */ diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); - if(diff > 1024 * 1024){ + if (diff > 1024 * 1024) { printf("Adding %ld bytes to physical memory to account for " "exec-shield gap\n", diff); physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); @@ -411,20 +307,16 @@ int __init linux_main(int argc, char **argv) setup_machinename(init_utsname()->machine); -#ifdef CONFIG_CMDLINE_ON_HOST - argv1_begin = argv[1]; - argv1_end = &argv[1][strlen(argv[1])]; -#endif - highmem = 0; iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; - /* Zones have to begin on a 1 << MAX_ORDER page boundary, + /* + * Zones have to begin on a 1 << MAX_ORDER page boundary, * so this makes sure that's true for highmem */ max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1); - if(physmem_size + iomem_size > max_physmem){ + if (physmem_size + iomem_size > max_physmem) { highmem = physmem_size + iomem_size - max_physmem; physmem_size -= highmem; #ifndef CONFIG_HIGHMEM @@ -441,7 +333,7 @@ int __init linux_main(int argc, char **argv) start_vm = VMALLOC_START; setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); - if(init_maps(physmem_size, iomem_size, highmem)){ + if (init_maps(physmem_size, iomem_size, highmem)) { printf("Failed to allocate mem_map for %Lu bytes of physical " "memory and %Lu bytes of highmem\n", physmem_size, highmem); @@ -450,10 +342,11 @@ int __init linux_main(int argc, char **argv) virtmem_size = physmem_size; avail = get_kmem_end() - start_vm; - if(physmem_size > avail) virtmem_size = avail; + if (physmem_size > avail) + virtmem_size = avail; end_vm = start_vm + virtmem_size; - if(virtmem_size < physmem_size) + if (virtmem_size < physmem_size) printf("Kernel virtual memory size shrunk to %lu bytes\n", virtmem_size); @@ -462,7 +355,7 @@ int __init linux_main(int argc, char **argv) stack_protections((unsigned long) &init_thread_info); os_flush_stdout(); - return CHOOSE_MODE(start_uml_tt(), start_uml_skas()); + return start_uml(); } extern int uml_exitcode; diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 81acdc24348e..13df191e2b41 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -18,13 +18,6 @@ SECTIONS . = START + SIZEOF_HEADERS; -#ifdef MODE_TT - .remap_data : { UNMAP_PATH (.data .bss) } - .remap : { UNMAP_PATH (.text) } - - . = ALIGN(4096); /* Init code and data */ -#endif - _text = .; _stext = .; __init_begin = .; diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index 2f8c79464015..8e129af8170d 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -1,23 +1,18 @@ # -# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) +# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) # Licensed under the GPL # obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ - sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \ - user_syms.o util.o drivers/ sys-$(SUBARCH)/ - -obj-$(CONFIG_MODE_SKAS) += skas/ - -obj-$(CONFIG_MODE_TT) += tt.o -user-objs-$(CONFIG_MODE_TT) += tt.o + registers.o sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o \ + umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/ obj-$(CONFIG_TTY_LOG) += tty_log.o user-objs-$(CONFIG_TTY_LOG) += tty_log.o USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ - main.o mem.o process.o sigio.o signal.o start_up.o time.o trap.o tty.o \ - tls.o uaccess.o umid.o util.o + main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \ + trap.o tty.o tls.o uaccess.o umid.o util.o CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 59348359f9ab..4158118c4a56 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -1,20 +1,19 @@ /* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <stdlib.h> #include <unistd.h> +#include <sched.h> #include <signal.h> #include <errno.h> -#include <sched.h> -#include <sys/syscall.h> -#include "os.h" +#include <sys/time.h> +#include <asm/unistd.h> #include "aio.h" #include "init.h" -#include "user.h" -#include "mode.h" #include "kern_constants.h" +#include "os.h" +#include "user.h" struct aio_thread_req { enum aio_type type; @@ -28,7 +27,8 @@ struct aio_thread_req { #if defined(HAVE_AIO_ABI) #include <linux/aio_abi.h> -/* If we have the headers, we are going to build with AIO enabled. +/* + * If we have the headers, we are going to build with AIO enabled. * If we don't have aio in libc, we define the necessary stubs here. */ @@ -52,7 +52,8 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr, #endif -/* The AIO_MMAP cases force the mmapped page into memory here +/* + * The AIO_MMAP cases force the mmapped page into memory here * rather than in whatever place first touches the data. I used * to do this by touching the page, but that's delicate because * gcc is prone to optimizing that away. So, what's done here @@ -106,12 +107,12 @@ static int aio_thread(void *arg) signal(SIGWINCH, SIG_IGN); - while(1){ + while (1) { n = io_getevents(ctx, 1, 1, &event, NULL); - if(n < 0){ - if(errno == EINTR) + if (n < 0) { + if (errno == EINTR) continue; - printk("aio_thread - io_getevents failed, " + printk(UM_KERN_ERR "aio_thread - io_getevents failed, " "errno = %d\n", errno); } else { @@ -120,9 +121,9 @@ static int aio_thread(void *arg) .err = event.res }); reply_fd = ((struct aio_context *) reply.data)->reply_fd; err = write(reply_fd, &reply, sizeof(reply)); - if(err != sizeof(reply)) - printk("aio_thread - write failed, fd = %d, " - "err = %d\n", reply_fd, errno); + if (err != sizeof(reply)) + printk(UM_KERN_ERR "aio_thread - write failed, " + "fd = %d, err = %d\n", reply_fd, errno); } } return 0; @@ -137,10 +138,10 @@ static int do_not_aio(struct aio_thread_req *req) int n; actual = lseek64(req->io_fd, req->offset, SEEK_SET); - if(actual != req->offset) + if (actual != req->offset) return -errno; - switch(req->type){ + switch(req->type) { case AIO_READ: n = read(req->io_fd, req->buf, req->len); break; @@ -151,11 +152,12 @@ static int do_not_aio(struct aio_thread_req *req) n = read(req->io_fd, &c, sizeof(c)); break; default: - printk("do_not_aio - bad request type : %d\n", req->type); + printk(UM_KERN_ERR "do_not_aio - bad request type : %d\n", + req->type); return -EINVAL; } - if(n < 0) + if (n < 0) return -errno; return 0; } @@ -173,16 +175,18 @@ static int not_aio_thread(void *arg) int err; signal(SIGWINCH, SIG_IGN); - while(1){ + while (1) { err = read(aio_req_fd_r, &req, sizeof(req)); - if(err != sizeof(req)){ - if(err < 0) - printk("not_aio_thread - read failed, " - "fd = %d, err = %d\n", aio_req_fd_r, + if (err != sizeof(req)) { + if (err < 0) + printk(UM_KERN_ERR "not_aio_thread - " + "read failed, fd = %d, err = %d\n", + aio_req_fd_r, errno); else { - printk("not_aio_thread - short read, fd = %d, " - "length = %d\n", aio_req_fd_r, err); + printk(UM_KERN_ERR "not_aio_thread - short " + "read, fd = %d, length = %d\n", + aio_req_fd_r, err); } continue; } @@ -190,9 +194,9 @@ static int not_aio_thread(void *arg) reply = ((struct aio_thread_reply) { .data = req.aio, .err = err }); err = write(req.aio->reply_fd, &reply, sizeof(reply)); - if(err != sizeof(reply)) - printk("not_aio_thread - write failed, fd = %d, " - "err = %d\n", req.aio->reply_fd, errno); + if (err != sizeof(reply)) + printk(UM_KERN_ERR "not_aio_thread - write failed, " + "fd = %d, err = %d\n", req.aio->reply_fd, errno); } return 0; @@ -203,35 +207,36 @@ static int init_aio_24(void) int fds[2], err; err = os_pipe(fds, 1, 1); - if(err) + if (err) goto out; aio_req_fd_w = fds[0]; aio_req_fd_r = fds[1]; err = os_set_fd_block(aio_req_fd_w, 0); - if(err) + if (err) goto out_close_pipe; err = run_helper_thread(not_aio_thread, NULL, CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack); - if(err < 0) + if (err < 0) goto out_close_pipe; aio_pid = err; goto out; out_close_pipe: - os_close_file(fds[0]); - os_close_file(fds[1]); + close(fds[0]); + close(fds[1]); aio_req_fd_w = -1; aio_req_fd_r = -1; out: #ifndef HAVE_AIO_ABI - printk("/usr/include/linux/aio_abi.h not present during build\n"); + printk(UM_KERN_INFO "/usr/include/linux/aio_abi.h not present during " + "build\n"); #endif - printk("2.6 host AIO support not used - falling back to I/O " - "thread\n"); + printk(UM_KERN_INFO "2.6 host AIO support not used - falling back to " + "I/O thread\n"); return 0; } @@ -241,21 +246,21 @@ static int init_aio_26(void) { int err; - if(io_setup(256, &ctx)){ + if (io_setup(256, &ctx)) { err = -errno; - printk("aio_thread failed to initialize context, err = %d\n", - errno); + printk(UM_KERN_ERR "aio_thread failed to initialize context, " + "err = %d\n", errno); return err; } err = run_helper_thread(aio_thread, NULL, CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack); - if(err < 0) + if (err < 0) return err; aio_pid = err; - printk("Using 2.6 host AIO\n"); + printk(UM_KERN_INFO "Using 2.6 host AIO\n"); return 0; } @@ -266,13 +271,13 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, int err; err = do_aio(ctx, type, io_fd, buf, len, offset, aio); - if(err){ + if (err) { reply = ((struct aio_thread_reply) { .data = aio, .err = err }); err = write(aio->reply_fd, &reply, sizeof(reply)); - if(err != sizeof(reply)){ + if (err != sizeof(reply)) { err = -errno; - printk("submit_aio_26 - write failed, " + printk(UM_KERN_ERR "submit_aio_26 - write failed, " "fd = %d, err = %d\n", aio->reply_fd, -err); } else err = 0; @@ -320,28 +325,24 @@ static int init_aio(void) { int err; - CHOOSE_MODE(({ if(!aio_24){ - printk("Disabling 2.6 AIO in tt mode\n"); - aio_24 = 1; - } }), (void) 0); - - if(!aio_24){ + if (!aio_24) { err = init_aio_26(); - if(err && (errno == ENOSYS)){ - printk("2.6 AIO not supported on the host - " - "reverting to 2.4 AIO\n"); + if (err && (errno == ENOSYS)) { + printk(UM_KERN_INFO "2.6 AIO not supported on the " + "host - reverting to 2.4 AIO\n"); aio_24 = 1; } else return err; } - if(aio_24) + if (aio_24) return init_aio_24(); return 0; } -/* The reason for the __initcall/__uml_exitcall asymmetry is that init_aio +/* + * The reason for the __initcall/__uml_exitcall asymmetry is that init_aio * needs to be called when the kernel is running because it calls run_helper, * which needs get_free_page. exit_aio is a __uml_exitcall because the generic * kernel does not run __exitcalls on shutdown, and can't because many of them @@ -372,7 +373,7 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len, int err; err = write(aio_req_fd_w, &req, sizeof(req)); - if(err == sizeof(req)) + if (err == sizeof(req)) err = 0; else err = -errno; @@ -384,9 +385,8 @@ int submit_aio(enum aio_type type, int io_fd, char *buf, int len, struct aio_context *aio) { aio->reply_fd = reply_fd; - if(aio_24) + if (aio_24) return submit_aio_24(type, io_fd, buf, len, offset, aio); - else { + else return submit_aio_26(type, io_fd, buf, len, offset, aio); - } } diff --git a/arch/um/os-Linux/drivers/etap.h b/arch/um/os-Linux/drivers/etap.h index 57ecdaf2f67e..ddffd41c3f3f 100644 --- a/arch/um/os-Linux/drivers/etap.h +++ b/arch/um/os-Linux/drivers/etap.h @@ -1,8 +1,11 @@ /* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ +#ifndef __DRIVERS_ETAP_H +#define __DRIVERS_ETAP_H + #include "net_user.h" struct ethertap_data { @@ -15,13 +18,4 @@ struct ethertap_data { extern const struct net_user_info ethertap_user_info; -/* - * 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: - */ +#endif diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c index 12689141414d..04f11b9f1ac0 100644 --- a/arch/um/os-Linux/drivers/ethertap_kern.c +++ b/arch/um/os-Linux/drivers/ethertap_kern.c @@ -1,16 +1,15 @@ /* - * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and * James Leu (jleu@mindspring.net). + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Copyright (C) 2001 by various other people who didn't put their name here. * Licensed under the GPL. */ #include "linux/init.h" -#include "linux/netdevice.h" -#include "linux/etherdevice.h" -#include "net_kern.h" -#include "net_user.h" +#include <linux/netdevice.h> #include "etap.h" +#include "net_kern.h" struct ethertap_init { char *dev_name; @@ -37,32 +36,24 @@ static void etap_init(struct net_device *dev, void *data) printk("\n"); } -static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) +static int etap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) { int len; - *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP); - if(*skb == NULL) return(-ENOMEM); - len = net_recvfrom(fd, skb_mac_header(*skb), - (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP); - if(len <= 0) return(len); - skb_pull(*skb, 2); + len = net_recvfrom(fd, skb_mac_header(skb), + skb->dev->mtu + 2 + ETH_HEADER_ETHERTAP); + if (len <= 0) + return(len); + + skb_pull(skb, 2); len -= 2; - return(len); + return len; } -static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) +static int etap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - if(skb_headroom(*skb) < 2){ - struct sk_buff *skb2; - - skb2 = skb_realloc_headroom(*skb, 2); - dev_kfree_skb(*skb); - if (skb2 == NULL) return(-ENOMEM); - *skb = skb2; - } - skb_push(*skb, 2); - return(net_send(fd, (*skb)->data, (*skb)->len)); + skb_push(skb, 2); + return net_send(fd, skb->data, skb->len); } const struct net_kern_info ethertap_kern_info = { @@ -79,15 +70,15 @@ int ethertap_setup(char *str, char **mac_out, void *data) *init = ((struct ethertap_init) { .dev_name = NULL, .gate_addr = NULL }); - if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out, + if (tap_setup_common(str, "ethertap", &init->dev_name, mac_out, &init->gate_addr)) - return(0); - if(init->dev_name == NULL){ - printk("ethertap_setup : Missing tap device name\n"); - return(0); + return 0; + if (init->dev_name == NULL) { + printk(KERN_ERR "ethertap_setup : Missing tap device name\n"); + return 0; } - return(1); + return 1; } static struct transport ethertap_transport = { @@ -97,6 +88,7 @@ static struct transport ethertap_transport = { .user = ðertap_user_info, .kern = ðertap_kern_info, .private_size = sizeof(struct ethertap_data), + .setup_size = sizeof(struct ethertap_init), }; static int register_ethertap(void) diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 61d3953c7ac9..4ff553603449 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and * James Leu (jleu@mindspring.net). * Copyright (C) 2001 by various other people who didn't put their name here. @@ -7,20 +8,16 @@ #include <stdio.h> #include <unistd.h> -#include <stddef.h> -#include <stdlib.h> -#include <sys/errno.h> +#include <errno.h> +#include <string.h> #include <sys/socket.h> #include <sys/wait.h> -#include <sys/un.h> -#include <net/if.h> -#include "user.h" -#include "kern_util.h" -#include "net_user.h" #include "etap.h" +#include "kern_constants.h" #include "os.h" +#include "net_user.h" #include "um_malloc.h" -#include "kern_constants.h" +#include "user.h" #define MAX_PACKET ETH_MAX_PACKET @@ -49,16 +46,18 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask, memcpy(change.addr, addr, sizeof(change.addr)); memcpy(change.netmask, netmask, sizeof(change.netmask)); CATCH_EINTR(n = write(fd, &change, sizeof(change))); - if(n != sizeof(change)){ - printk("etap_change - request failed, err = %d\n", errno); + if (n != sizeof(change)) { + printk(UM_KERN_ERR "etap_change - request failed, err = %d\n", + errno); return; } output = kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL); - if(output == NULL) - printk("etap_change : Failed to allocate output buffer\n"); + if (output == NULL) + printk(UM_KERN_ERR "etap_change : Failed to allocate output " + "buffer\n"); read_output(fd, output, UM_KERN_PAGE_SIZE); - if(output != NULL){ + if (output != NULL) { printk("%s", output); kfree(output); } @@ -87,11 +86,11 @@ static void etap_pre_exec(void *arg) struct etap_pre_exec_data *data = arg; dup2(data->control_remote, 1); - os_close_file(data->data_me); - os_close_file(data->control_me); + close(data->data_me); + close(data->control_me); } -static int etap_tramp(char *dev, char *gate, int control_me, +static int etap_tramp(char *dev, char *gate, int control_me, int control_remote, int data_me, int data_remote) { struct etap_pre_exec_data pe_data; @@ -101,13 +100,13 @@ static int etap_tramp(char *dev, char *gate, int control_me, char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; char *setup_args[] = { "uml_net", version_buf, "ethertap", dev, data_fd_buf, gate_buf, NULL }; - char *nosetup_args[] = { "uml_net", version_buf, "ethertap", + char *nosetup_args[] = { "uml_net", version_buf, "ethertap", dev, data_fd_buf, NULL }; char **args, c; sprintf(data_fd_buf, "%d", data_remote); sprintf(version_buf, "%d", UML_NET_VERSION); - if(gate != NULL){ + if (gate != NULL) { strcpy(gate_buf, gate); args = setup_args; } @@ -119,24 +118,26 @@ static int etap_tramp(char *dev, char *gate, int control_me, pe_data.data_me = data_me; pid = run_helper(etap_pre_exec, &pe_data, args); - if(pid < 0) + if (pid < 0) err = pid; - os_close_file(data_remote); - os_close_file(control_remote); + close(data_remote); + close(control_remote); CATCH_EINTR(n = read(control_me, &c, sizeof(c))); - if(n != sizeof(c)){ + if (n != sizeof(c)) { err = -errno; - printk("etap_tramp : read of status failed, err = %d\n", -err); + printk(UM_KERN_ERR "etap_tramp : read of status failed, " + "err = %d\n", -err); return err; } - if(c != 1){ - printk("etap_tramp : uml_net failed\n"); + if (c != 1) { + printk(UM_KERN_ERR "etap_tramp : uml_net failed\n"); err = -EINVAL; CATCH_EINTR(n = waitpid(pid, &status, 0)); - if(n < 0) + if (n < 0) err = -errno; - else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)) - printk("uml_net didn't exit with status 1\n"); + else if (!WIFEXITED(status) || (WEXITSTATUS(status) != 1)) + printk(UM_KERN_ERR "uml_net didn't exit with " + "status 1\n"); } return err; } @@ -148,43 +149,56 @@ static int etap_open(void *data) int data_fds[2], control_fds[2], err, output_len; err = tap_open_common(pri->dev, pri->gate_addr); - if(err) + if (err) return err; - err = os_pipe(data_fds, 0, 0); - if(err < 0){ - printk("data os_pipe failed - err = %d\n", -err); + err = socketpair(AF_UNIX, SOCK_DGRAM, 0, data_fds); + if (err) { + err = -errno; + printk(UM_KERN_ERR "etap_open - data socketpair failed - " + "err = %d\n", errno); return err; } - err = os_pipe(control_fds, 1, 0); - if(err < 0){ - printk("control os_pipe failed - err = %d\n", -err); - return err; + err = socketpair(AF_UNIX, SOCK_STREAM, 0, control_fds); + if (err) { + err = -errno; + printk(UM_KERN_ERR "etap_open - control socketpair failed - " + "err = %d\n", errno); + goto out_close_data; } - err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], + 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 = kmalloc(output_len, UM_GFP_KERNEL); read_output(control_fds[0], output, output_len); - if(output == NULL) - printk("etap_open : failed to allocate output buffer\n"); + if (output == NULL) + printk(UM_KERN_ERR "etap_open : failed to allocate output " + "buffer\n"); else { printk("%s", output); kfree(output); } - if(err < 0){ - printk("etap_tramp failed - err = %d\n", -err); - return err; + if (err < 0) { + printk(UM_KERN_ERR "etap_tramp failed - err = %d\n", -err); + goto out_close_control; } pri->data_fd = data_fds[0]; pri->control_fd = control_fds[0]; iter_addresses(pri->dev, etap_open_addr, &pri->control_fd); return data_fds[0]; + +out_close_control: + close(control_fds[0]); + close(control_fds[1]); +out_close_data: + close(data_fds[0]); + close(data_fds[1]); + return err; } static void etap_close(int fd, void *data) @@ -192,37 +206,41 @@ static void etap_close(int fd, void *data) struct ethertap_data *pri = data; iter_addresses(pri->dev, etap_close_addr, &pri->control_fd); - os_close_file(fd); - os_shutdown_socket(pri->data_fd, 1, 1); - os_close_file(pri->data_fd); + close(fd); + + if (shutdown(pri->data_fd, SHUT_RDWR) < 0) + printk(UM_KERN_ERR "etap_close - shutdown data socket failed, " + "errno = %d\n", errno); + + if (shutdown(pri->control_fd, SHUT_RDWR) < 0) + printk(UM_KERN_ERR "etap_close - shutdown control socket " + "failed, errno = %d\n", errno); + + close(pri->data_fd); pri->data_fd = -1; - os_close_file(pri->control_fd); + close(pri->control_fd); pri->control_fd = -1; } -static int etap_set_mtu(int mtu, void *data) -{ - return mtu; -} - static void etap_add_addr(unsigned char *addr, unsigned char *netmask, void *data) { struct ethertap_data *pri = data; tap_check_ips(pri->gate_addr, addr); - if(pri->control_fd == -1) + if (pri->control_fd == -1) return; etap_open_addr(addr, netmask, &pri->control_fd); } -static void etap_del_addr(unsigned char *addr, unsigned char *netmask, +static void etap_del_addr(unsigned char *addr, unsigned char *netmask, void *data) { struct ethertap_data *pri = data; - if(pri->control_fd == -1) + if (pri->control_fd == -1) return; + etap_close_addr(addr, netmask, &pri->control_fd); } @@ -231,8 +249,8 @@ const struct net_user_info ethertap_user_info = { .open = etap_open, .close = etap_close, .remove = NULL, - .set_mtu = etap_set_mtu, .add_address = etap_add_addr, .delete_address = etap_del_addr, - .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP + .mtu = ETH_MAX_PACKET, + .max_packet = ETH_MAX_PACKET + ETH_HEADER_ETHERTAP, }; diff --git a/arch/um/os-Linux/drivers/tuntap.h b/arch/um/os-Linux/drivers/tuntap.h index d3e8d3af6245..f17c31586c84 100644 --- a/arch/um/os-Linux/drivers/tuntap.h +++ b/arch/um/os-Linux/drivers/tuntap.h @@ -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 */ @@ -19,14 +19,3 @@ struct tuntap_data { extern const struct net_user_info tuntap_user_info; #endif - -/* - * 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/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c index f1714e7fb1d0..9d384807b077 100644 --- a/arch/um/os-Linux/drivers/tuntap_kern.c +++ b/arch/um/os-Linux/drivers/tuntap_kern.c @@ -1,16 +1,13 @@ -/* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) +/* + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/stddef.h" -#include "linux/netdevice.h" -#include "linux/etherdevice.h" -#include "linux/skbuff.h" -#include "linux/init.h" -#include "asm/errno.h" +#include <linux/netdevice.h> +#include <linux/init.h> +#include <linux/skbuff.h> +#include <asm/errno.h> #include "net_kern.h" -#include "net_user.h" #include "tuntap.h" struct tuntap_init { @@ -38,19 +35,15 @@ static void tuntap_init(struct net_device *dev, void *data) printk("\n"); } -static int tuntap_read(int fd, struct sk_buff **skb, - struct uml_net_private *lp) +static int tuntap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); - if(*skb == NULL) return(-ENOMEM); - return(net_read(fd, skb_mac_header(*skb), - (*skb)->dev->mtu + ETH_HEADER_OTHER)); + return net_read(fd, skb_mac_header(skb), + skb->dev->mtu + ETH_HEADER_OTHER); } -static int tuntap_write(int fd, struct sk_buff **skb, - struct uml_net_private *lp) +static int tuntap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - return(net_write(fd, (*skb)->data, (*skb)->len)); + return net_write(fd, skb->data, skb->len); } const struct net_kern_info tuntap_kern_info = { @@ -67,11 +60,11 @@ int tuntap_setup(char *str, char **mac_out, void *data) *init = ((struct tuntap_init) { .dev_name = NULL, .gate_addr = NULL }); - if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out, + if (tap_setup_common(str, "tuntap", &init->dev_name, mac_out, &init->gate_addr)) - return(0); + return 0; - return(1); + return 1; } static struct transport tuntap_transport = { diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index f848b4ea9343..6c55d3c8ead8 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -1,27 +1,22 @@ /* - * 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 <stddef.h> -#include <stdlib.h> #include <unistd.h> #include <errno.h> -#include <sys/wait.h> +#include <string.h> +#include <linux/if_tun.h> +#include <net/if.h> +#include <sys/ioctl.h> #include <sys/socket.h> -#include <sys/un.h> +#include <sys/wait.h> #include <sys/uio.h> -#include <sys/ioctl.h> -#include <net/if.h> -#include <linux/if_tun.h> -#include "net_user.h" +#include "kern_constants.h" +#include "os.h" #include "tuntap.h" -#include "kern_util.h" #include "user.h" -#include "os.h" - -#define MAX_PACKET ETH_MAX_PACKET static int tuntap_user_init(void *data, void *dev) { @@ -37,7 +32,7 @@ static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask, struct tuntap_data *pri = data; tap_check_ips(pri->gate_addr, addr); - if((pri->fd == -1) || pri->fixed_config) + if ((pri->fd == -1) || pri->fixed_config) return; open_addr(addr, netmask, pri->dev_name); } @@ -47,7 +42,7 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask, { struct tuntap_data *pri = data; - if((pri->fd == -1) || pri->fixed_config) + if ((pri->fd == -1) || pri->fixed_config) return; close_addr(addr, netmask, pri->dev_name); } @@ -62,7 +57,7 @@ static void tuntap_pre_exec(void *arg) struct tuntap_pre_exec_data *data = arg; dup2(data->stdout, 1); - os_close_file(data->close_me); + close(data->close_me); } static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, @@ -85,14 +80,14 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, pid = run_helper(tuntap_pre_exec, &data, argv); - if(pid < 0) + if (pid < 0) return -pid; - os_close_file(remote); + close(remote); msg.msg_name = NULL; msg.msg_namelen = 0; - if(buffer != NULL){ + if (buffer != NULL) { iov = ((struct iovec) { buffer, buffer_len }); msg.msg_iov = &iov; msg.msg_iovlen = 1; @@ -106,26 +101,28 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, msg.msg_flags = 0; n = recvmsg(me, &msg, 0); *used_out = n; - if(n < 0){ + if (n < 0) { err = -errno; - printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", - errno); + printk(UM_KERN_ERR "tuntap_open_tramp : recvmsg failed - " + "errno = %d\n", errno); return err; } CATCH_EINTR(waitpid(pid, NULL, 0)); cmsg = CMSG_FIRSTHDR(&msg); - if(cmsg == NULL){ - printk("tuntap_open_tramp : didn't receive a message\n"); + if (cmsg == NULL) { + printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a " + "message\n"); return -EINVAL; } - if((cmsg->cmsg_level != SOL_SOCKET) || - (cmsg->cmsg_type != SCM_RIGHTS)){ - printk("tuntap_open_tramp : didn't receive a descriptor\n"); + if ((cmsg->cmsg_level != SOL_SOCKET) || + (cmsg->cmsg_type != SCM_RIGHTS)) { + printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a " + "descriptor\n"); return -EINVAL; } *fd_out = ((int *) CMSG_DATA(cmsg))[0]; - os_set_exec_close(*fd_out, 1); + os_set_exec_close(*fd_out); return 0; } @@ -137,47 +134,51 @@ static int tuntap_open(void *data) int err, fds[2], len, used; err = tap_open_common(pri->dev, pri->gate_addr); - if(err < 0) + if (err < 0) return err; - if(pri->fixed_config){ + if (pri->fixed_config) { pri->fd = os_open_file("/dev/net/tun", of_cloexec(of_rdwr(OPENFLAGS())), 0); - if(pri->fd < 0){ - printk("Failed to open /dev/net/tun, err = %d\n", - -pri->fd); + if (pri->fd < 0) { + printk(UM_KERN_ERR "Failed to open /dev/net/tun, " + "err = %d\n", -pri->fd); return pri->fd; } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name)); - if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){ + if (ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0) { err = -errno; - printk("TUNSETIFF failed, errno = %d\n", errno); - os_close_file(pri->fd); + printk(UM_KERN_ERR "TUNSETIFF failed, errno = %d\n", + errno); + close(pri->fd); return err; } } else { - err = os_pipe(fds, 0, 0); - if(err < 0){ - printk("tuntap_open : os_pipe failed - err = %d\n", - -err); + err = socketpair(AF_UNIX, SOCK_DGRAM, 0, fds); + if (err) { + err = -errno; + printk(UM_KERN_ERR "tuntap_open : socketpair failed - " + "errno = %d\n", errno); return err; } buffer = get_output_buffer(&len); - if(buffer != NULL) len--; + if (buffer != NULL) + len--; used = 0; err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0], fds[1], buffer, len, &used); output = buffer; - if(err < 0) { + if (err < 0) { printk("%s", output); free_output_buffer(buffer); - printk("tuntap_open_tramp failed - err = %d\n", -err); + printk(UM_KERN_ERR "tuntap_open_tramp failed - " + "err = %d\n", -err); return err; } @@ -186,7 +187,7 @@ static int tuntap_open(void *data) printk("%s", output); free_output_buffer(buffer); - os_close_file(fds[0]); + close(fds[0]); iter_addresses(pri->dev, open_addr, pri->dev_name); } @@ -197,24 +198,19 @@ static void tuntap_close(int fd, void *data) { struct tuntap_data *pri = data; - if(!pri->fixed_config) + if (!pri->fixed_config) iter_addresses(pri->dev, close_addr, pri->dev_name); - os_close_file(fd); + close(fd); pri->fd = -1; } -static int tuntap_set_mtu(int mtu, void *data) -{ - return mtu; -} - const struct net_user_info tuntap_user_info = { .init = tuntap_user_init, .open = tuntap_open, .close = tuntap_close, .remove = NULL, - .set_mtu = tuntap_set_mtu, .add_address = tuntap_add_addr, .delete_address = tuntap_del_addr, - .max_packet = MAX_PACKET + .mtu = ETH_MAX_PACKET, + .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER, }; diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index c3ecc2a84e0c..b542a3a021bf 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -82,13 +82,6 @@ int os_access(const char* file, int mode) return 0; } -void os_print_error(int error, const char* str) -{ - errno = error < 0 ? -error : error; - - perror(str); -} - /* FIXME? required only by hostaudio (because it passes ioctls verbatim) */ int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg) { @@ -101,30 +94,6 @@ int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg) return err; } -int os_window_size(int fd, int *rows, int *cols) -{ - struct winsize size; - - if(ioctl(fd, TIOCGWINSZ, &size) < 0) - return -errno; - - *rows = size.ws_row; - *cols = size.ws_col; - - return 0; -} - -int os_new_tty_pgrp(int fd, int pid) -{ - if(ioctl(fd, TIOCSCTTY, 0) < 0) - return -errno; - - if(tcsetpgrp(fd, pid) < 0) - return -errno; - - return 0; -} - /* FIXME: ensure namebuf in os_get_if_name is big enough */ int os_get_ifname(int fd, char* namebuf) { @@ -205,19 +174,19 @@ int os_file_mode(char *file, struct openflags *mode_out) *mode_out = OPENFLAGS(); - err = os_access(file, OS_ACC_W_OK); - if((err < 0) && (err != -EACCES)) - return(err); - - *mode_out = of_write(*mode_out); - - err = os_access(file, OS_ACC_R_OK); - if((err < 0) && (err != -EACCES)) - return(err); + err = access(file, W_OK); + if(err && (errno != EACCES)) + return -errno; + else if(!err) + *mode_out = of_write(*mode_out); - *mode_out = of_read(*mode_out); + err = access(file, R_OK); + if(err && (errno != EACCES)) + return -errno; + else if(!err) + *mode_out = of_read(*mode_out); - return(0); + return err; } int os_open_file(char *file, struct openflags flags, int mode) @@ -236,15 +205,15 @@ int os_open_file(char *file, struct openflags flags, int mode) fd = open64(file, f, mode); if(fd < 0) - return(-errno); + return -errno; if(flags.cl && fcntl(fd, F_SETFD, 1)){ err = -errno; - os_close_file(fd); + close(fd); return err; } - return(fd); + return fd; } int os_connect_socket(char *name) @@ -280,9 +249,9 @@ void os_close_file(int fd) close(fd); } -int os_seek_file(int fd, __u64 offset) +int os_seek_file(int fd, unsigned long long offset) { - __u64 actual; + unsigned long long actual; actual = lseek64(fd, offset, SEEK_SET); if(actual != offset) @@ -316,31 +285,33 @@ int os_file_size(char *file, unsigned long long *size_out) err = os_stat_file(file, &buf); if(err < 0){ printk("Couldn't stat \"%s\" : err = %d\n", file, -err); - return(err); + return err; } if(S_ISBLK(buf.ust_mode)){ int fd; long blocks; - fd = os_open_file(file, of_read(OPENFLAGS()), 0); - if(fd < 0){ - printk("Couldn't open \"%s\", errno = %d\n", file, -fd); - return(fd); + fd = open(file, O_RDONLY, 0); + if(fd < 0) { + err = -errno; + printk("Couldn't open \"%s\", errno = %d\n", file, + errno); + return err; } if(ioctl(fd, BLKGETSIZE, &blocks) < 0){ err = -errno; printk("Couldn't get the block size of \"%s\", " "errno = %d\n", file, errno); - os_close_file(fd); - return(err); + close(fd); + return err; } *size_out = ((long long) blocks) * 512; - os_close_file(fd); - return(0); + close(fd); } - *size_out = buf.ust_size; - return(0); + else *size_out = buf.ust_size; + + return 0; } int os_file_modtime(char *file, unsigned long *modtime) @@ -358,35 +329,28 @@ int os_file_modtime(char *file, unsigned long *modtime) return 0; } -int os_get_exec_close(int fd, int* close_on_exec) +int os_get_exec_close(int fd, int *close_on_exec) { int ret; - do { - ret = fcntl(fd, F_GETFD); - } while((ret < 0) && (errno == EINTR)) ; + CATCH_EINTR(ret = fcntl(fd, F_GETFD)); if(ret < 0) - return(-errno); + return -errno; - *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0; - return(ret); + *close_on_exec = (ret & FD_CLOEXEC) ? 1 : 0; + return ret; } -int os_set_exec_close(int fd, int close_on_exec) +int os_set_exec_close(int fd) { - int flag, err; - - if(close_on_exec) flag = FD_CLOEXEC; - else flag = 0; + int err; - do { - err = fcntl(fd, F_SETFD, flag); - } while((err < 0) && (errno == EINTR)) ; + CATCH_EINTR(err = fcntl(fd, F_SETFD, FD_CLOEXEC)); if(err < 0) - return(-errno); - return(err); + return -errno; + return err; } int os_pipe(int *fds, int stream, int close_on_exec) @@ -395,16 +359,16 @@ int os_pipe(int *fds, int stream, int close_on_exec) err = socketpair(AF_UNIX, type, 0, fds); if(err < 0) - return(-errno); + return -errno; if(!close_on_exec) - return(0); + return 0; - err = os_set_exec_close(fds[0], 1); + err = os_set_exec_close(fds[0]); if(err < 0) goto error; - err = os_set_exec_close(fds[1], 1); + err = os_set_exec_close(fds[1]); if(err < 0) goto error; @@ -412,9 +376,9 @@ int os_pipe(int *fds, int stream, int close_on_exec) error: printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err); - os_close_file(fds[1]); - os_close_file(fds[0]); - return(err); + close(fds[1]); + close(fds[0]); + return err; } int os_set_fd_async(int fd, int owner) @@ -561,7 +525,7 @@ int os_create_unix_socket(char *file, int len, int close_on_exec) return -errno; if(close_on_exec) { - err = os_set_exec_close(sock, 1); + err = os_set_exec_close(sock); if(err < 0) printk("create_unix_socket : close_on_exec failed, " "err = %d", -err); diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index d81af7b8587a..7a72dbb61b0d 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -11,6 +11,7 @@ #include <limits.h> #include <sys/signal.h> #include <sys/wait.h> +#include <sys/socket.h> #include "user.h" #include "kern_util.h" #include "os.h" @@ -54,13 +55,14 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) if (stack == 0) return -ENOMEM; - ret = os_pipe(fds, 1, 0); + ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); if (ret < 0) { - printk("run_helper : pipe failed, ret = %d\n", -ret); + ret = -errno; + printk("run_helper : pipe failed, errno = %d\n", errno); goto out_free; } - ret = os_set_exec_close(fds[1], 1); + ret = os_set_exec_close(fds[1]); if (ret < 0) { printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n", -ret); diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index a633fa8e0a94..6aa6f95d6524 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c @@ -145,11 +145,7 @@ void init_irq_signals(int on_sigstack) flags = on_sigstack ? SA_ONSTACK : 0; - set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, - flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); - set_handler(SIGALRM, (__sighandler_t) alarm_handler, - flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART, - SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); + SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); signal(SIGWINCH, SIG_IGN); } diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index e85f4995a011..82c3778627b8 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -1,33 +1,21 @@ /* - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <unistd.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> -#include <signal.h> +#include <unistd.h> #include <errno.h> +#include <signal.h> +#include <string.h> #include <sys/resource.h> -#include <sys/mman.h> -#include <sys/user.h> -#include <asm/page.h> -#include "kern_util.h" #include "as-layout.h" -#include "mem_user.h" -#include "irq_user.h" -#include "user.h" #include "init.h" -#include "mode.h" -#include "choose-mode.h" -#include "uml-config.h" +#include "kern_constants.h" +#include "kern_util.h" #include "os.h" #include "um_malloc.h" -#include "kern_constants.h" - -/* Set in main, unchanged thereafter */ -char *linux_prog; #define PGD_BOUND (4 * 1024 * 1024) #define STACKSIZE (8 * 1024 * 1024) @@ -37,13 +25,13 @@ static void set_stklim(void) { struct rlimit lim; - if(getrlimit(RLIMIT_STACK, &lim) < 0){ + if (getrlimit(RLIMIT_STACK, &lim) < 0) { perror("getrlimit"); exit(1); } - if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){ + if ((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)) { lim.rlim_cur = STACKSIZE; - if(setrlimit(RLIMIT_STACK, &lim) < 0){ + if (setrlimit(RLIMIT_STACK, &lim) < 0) { perror("setrlimit"); exit(1); } @@ -55,7 +43,7 @@ static __init void do_uml_initcalls(void) initcall_t *call; call = &__uml_initcall_start; - while (call < &__uml_initcall_end){ + while (call < &__uml_initcall_end) { (*call)(); call++; } @@ -74,7 +62,8 @@ static void install_fatal_handler(int sig) /* All signals are enabled in this handler ... */ sigemptyset(&action.sa_mask); - /* ... including the signal being handled, plus we want the + /* + * ... including the signal being handled, plus we want the * handler reset to the default behavior, so that if an exit * handler is hanging for some reason, the UML will just die * after this signal is sent a second time. @@ -82,7 +71,7 @@ static void install_fatal_handler(int sig) action.sa_flags = SA_RESETHAND | SA_NODEFER; action.sa_restorer = NULL; action.sa_handler = last_ditch_exit; - if(sigaction(sig, &action, NULL) < 0){ + if (sigaction(sig, &action, NULL) < 0) { printf("failed to install handler for signal %d - errno = %d\n", errno); exit(1); @@ -98,7 +87,8 @@ static void setup_env_path(void) int path_len = 0; old_path = getenv("PATH"); - /* if no PATH variable is set or it has an empty value + /* + * if no PATH variable is set or it has an empty value * just use the default + /usr/lib/uml */ if (!old_path || (path_len = strlen(old_path)) == 0) { @@ -126,93 +116,68 @@ int __init main(int argc, char **argv, char **envp) char **new_argv; int ret, i, err; -#ifdef UML_CONFIG_CMDLINE_ON_HOST - /* Allocate memory for thread command lines */ - if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){ - - char padding[THREAD_NAME_LEN] = { - [ 0 ... THREAD_NAME_LEN - 2] = ' ', '\0' - }; - - new_argv = malloc((argc + 2) * sizeof(char*)); - if(!new_argv) { - perror("Allocating extended argv"); - exit(1); - } - - new_argv[0] = argv[0]; - new_argv[1] = padding; - - for(i = 2; i <= argc; i++) - new_argv[i] = argv[i - 1]; - new_argv[argc + 1] = NULL; - - execvp(new_argv[0], new_argv); - perror("execing with extended args"); - exit(1); - } -#endif - - linux_prog = argv[0]; - set_stklim(); setup_env_path(); new_argv = malloc((argc + 1) * sizeof(char *)); - if(new_argv == NULL){ + if (new_argv == NULL) { perror("Mallocing argv"); exit(1); } - for(i=0;i<argc;i++){ + for (i = 0; i < argc; i++) { new_argv[i] = strdup(argv[i]); - if(new_argv[i] == NULL){ + if (new_argv[i] == NULL) { perror("Mallocing an arg"); exit(1); } } new_argv[argc] = NULL; - /* Allow these signals to bring down a UML if all other + /* + * Allow these signals to bring down a UML if all other * methods of control fail. */ install_fatal_handler(SIGINT); install_fatal_handler(SIGTERM); install_fatal_handler(SIGHUP); - scan_elf_aux( envp); + scan_elf_aux(envp); do_uml_initcalls(); ret = linux_main(argc, argv); - /* Disable SIGPROF - I have no idea why libc doesn't do this or turn + /* + * Disable SIGPROF - I have no idea why libc doesn't do this or turn * off the profiling time, but UML dies with a SIGPROF just before * exiting when profiling is active. */ change_sig(SIGPROF, 0); - /* This signal stuff used to be in the reboot case. However, + /* + * This signal stuff used to be in the reboot case. However, * sometimes a SIGVTALRM can come in when we're halting (reproducably * when writing out gcov information, presumably because that takes * some time) and cause a segfault. */ - /* stop timers and set SIG*ALRM to be ignored */ + /* stop timers and set SIGVTALRM to be ignored */ disable_timer(); /* disable SIGIO for the fds and set SIGIO to be ignored */ err = deactivate_all_fds(); - if(err) + if (err) printf("deactivate_all_fds failed, errno = %d\n", -err); - /* Let any pending signals fire now. This ensures + /* + * Let any pending signals fire now. This ensures * that they won't be delivered after the exec, when * they are definitely not expected. */ unblock_signals(); /* Reboot */ - if(ret){ + if (ret) { printf("\n"); execvp(new_argv[0], new_argv); perror("Failed to exec kernel"); @@ -222,26 +187,24 @@ int __init main(int argc, char **argv, char **envp) return uml_exitcode; } -#define CAN_KMALLOC() \ - (kmalloc_ok && CHOOSE_MODE((os_getpid() != tracing_pid), 1)) - extern void *__real_malloc(int); void *__wrap_malloc(int size) { void *ret; - if(!CAN_KMALLOC()) + if (!kmalloc_ok) return __real_malloc(size); - else if(size <= UM_KERN_PAGE_SIZE) + else if (size <= UM_KERN_PAGE_SIZE) /* finding contiguous pages can be hard*/ ret = kmalloc(size, UM_GFP_KERNEL); else ret = vmalloc(size); - /* glibc people insist that if malloc fails, errno should be + /* + * glibc people insist that if malloc fails, errno should be * set by malloc as well. So we do. */ - if(ret == NULL) + if (ret == NULL) errno = ENOMEM; return ret; @@ -251,7 +214,7 @@ void *__wrap_calloc(int n, int size) { void *ptr = __wrap_malloc(n * size); - if(ptr == NULL) + if (ptr == NULL) return NULL; memset(ptr, 0, n * size); return ptr; @@ -265,7 +228,8 @@ void __wrap_free(void *ptr) { unsigned long addr = (unsigned long) ptr; - /* We need to know how the allocation happened, so it can be correctly + /* + * We need to know how the allocation happened, so it can be correctly * freed. This is done by seeing what region of memory the pointer is * in - * physical memory - kmalloc/kfree @@ -283,12 +247,12 @@ void __wrap_free(void *ptr) * there is a possibility for memory leaks. */ - if((addr >= uml_physmem) && (addr < high_physmem)){ - if(CAN_KMALLOC()) + if ((addr >= uml_physmem) && (addr < high_physmem)) { + if (kmalloc_ok) kfree(ptr); } - else if((addr >= start_vm) && (addr < end_vm)){ - if(CAN_KMALLOC()) + else if ((addr >= start_vm) && (addr < end_vm)) { + if (kmalloc_ok) vfree(ptr); } else __real_free(ptr); diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index c6378c6d10d2..436f8d20b20f 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -218,7 +218,7 @@ int __init create_tmp_file(unsigned long long len) err = fchmod(fd, 0777); if(err < 0){ - perror("os_mode_fd"); + perror("fchmod"); exit(1); } @@ -226,7 +226,7 @@ int __init create_tmp_file(unsigned long long len) * increase the file size by one byte, to the desired length. */ if (lseek64(fd, len - 1, SEEK_SET) < 0) { - perror("os_seek_file"); + perror("lseek64"); exit(1); } @@ -247,7 +247,7 @@ int __init create_mem_file(unsigned long long len) fd = create_tmp_file(len); - err = os_set_exec_close(fd, 1); + err = os_set_exec_close(fd); if(err < 0){ errno = -err; perror("exec_close"); diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index e9c143297512..37781db4ceca 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -1,27 +1,24 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com) +/* + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <unistd.h> #include <stdio.h> +#include <unistd.h> #include <errno.h> #include <signal.h> +#include <fcntl.h> #include <sys/mman.h> +#include <sys/ptrace.h> #include <sys/wait.h> -#include <sys/mman.h> -#include <sys/syscall.h> -#include "ptrace_user.h" +#include <asm/unistd.h> +#include "init.h" +#include "kern_constants.h" +#include "longjmp.h" #include "os.h" -#include "user.h" #include "process.h" -#include "irq_user.h" -#include "kern_util.h" -#include "longjmp.h" #include "skas_ptrace.h" -#include "kern_constants.h" -#include "uml-config.h" -#include "init.h" +#include "user.h" #define ARBITRARY_ADDR -1 #define FAILURE_PID -1 @@ -32,30 +29,32 @@ unsigned long os_process_pc(int pid) { char proc_stat[STAT_PATH_LEN], buf[256]; - unsigned long pc; + unsigned long pc = ARBITRARY_ADDR; int fd, err; sprintf(proc_stat, "/proc/%d/stat", pid); - fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0); - if(fd < 0){ - printk("os_process_pc - couldn't open '%s', err = %d\n", - proc_stat, -fd); - return ARBITRARY_ADDR; + fd = open(proc_stat, O_RDONLY, 0); + if (fd < 0) { + printk(UM_KERN_ERR "os_process_pc - couldn't open '%s', " + "errno = %d\n", proc_stat, errno); + goto out; } CATCH_EINTR(err = read(fd, buf, sizeof(buf))); - if(err < 0){ - printk("os_process_pc - couldn't read '%s', err = %d\n", - proc_stat, errno); - os_close_file(fd); - return ARBITRARY_ADDR; + if (err < 0) { + printk(UM_KERN_ERR "os_process_pc - couldn't read '%s', " + "err = %d\n", proc_stat, errno); + goto out_close; } os_close_file(fd); pc = ARBITRARY_ADDR; - if(sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d " - "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " - "%*d %*d %*d %*d %*d %lu", &pc) != 1){ - printk("os_process_pc - couldn't find pc in '%s'\n", buf); - } + if (sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d " + "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " + "%*d %*d %*d %*d %*d %lu", &pc) != 1) + printk(UM_KERN_ERR "os_process_pc - couldn't find pc in '%s'\n", + buf); + out_close: + close(fd); + out: return pc; } @@ -63,30 +62,32 @@ int os_process_parent(int pid) { char stat[STAT_PATH_LEN]; char data[256]; - int parent, n, fd; + int parent = FAILURE_PID, n, fd; - if(pid == -1) - return -1; + if (pid == -1) + return parent; snprintf(stat, sizeof(stat), "/proc/%d/stat", pid); - fd = os_open_file(stat, of_read(OPENFLAGS()), 0); - if(fd < 0){ - printk("Couldn't open '%s', err = %d\n", stat, -fd); - return FAILURE_PID; + fd = open(stat, O_RDONLY, 0); + if (fd < 0) { + printk(UM_KERN_ERR "Couldn't open '%s', errno = %d\n", stat, + errno); + return parent; } CATCH_EINTR(n = read(fd, data, sizeof(data))); - os_close_file(fd); + close(fd); - if(n < 0){ - printk("Couldn't read '%s', err = %d\n", stat, errno); - return FAILURE_PID; + if (n < 0) { + printk(UM_KERN_ERR "Couldn't read '%s', errno = %d\n", stat, + errno); + return parent; } parent = FAILURE_PID; n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent); - if(n != 1) - printk("Failed to scan '%s'\n", data); + if (n != 1) + printk(UM_KERN_ERR "Failed to scan '%s'\n", data); return parent; } @@ -99,9 +100,8 @@ void os_stop_process(int pid) void os_kill_process(int pid, int reap_child) { kill(pid, SIGKILL); - if(reap_child) + if (reap_child) CATCH_EINTR(waitpid(pid, NULL, 0)); - } /* This is here uniquely to have access to the userspace errno, i.e. the one @@ -129,17 +129,10 @@ void os_kill_ptraced_process(int pid, int reap_child) kill(pid, SIGKILL); ptrace(PTRACE_KILL, pid); ptrace(PTRACE_CONT, pid); - if(reap_child) + if (reap_child) CATCH_EINTR(waitpid(pid, NULL, 0)); } -#ifdef UML_CONFIG_MODE_TT -void os_usr1_process(int pid) -{ - kill(pid, SIGUSR1); -} -#endif - /* Don't use the glibc version, which caches the result in TLS. It misses some * syscalls, and also breaks with clone(), which does not unshare the TLS. */ @@ -160,34 +153,35 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, void *loc; int prot; - prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | (x ? PROT_EXEC : 0); loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, fd, off); - if(loc == MAP_FAILED) + if (loc == MAP_FAILED) return -errno; return 0; } int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) { - int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | + int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | (x ? PROT_EXEC : 0)); - if(mprotect(addr, len, prot) < 0) + if (mprotect(addr, len, prot) < 0) return -errno; - return 0; + + return 0; } int os_unmap_memory(void *addr, int len) { - int err; + int err; - err = munmap(addr, len); - if(err < 0) + err = munmap(addr, len); + if (err < 0) return -errno; - return 0; + return 0; } #ifndef MADV_REMOVE @@ -199,7 +193,7 @@ int os_drop_memory(void *addr, int length) int err; err = madvise(addr, length, MADV_REMOVE); - if(err < 0) + if (err < 0) err = -errno; return err; } @@ -209,22 +203,24 @@ int __init can_drop_memory(void) void *addr; int fd, ok = 0; - printk("Checking host MADV_REMOVE support..."); + printk(UM_KERN_INFO "Checking host MADV_REMOVE support..."); fd = create_mem_file(UM_KERN_PAGE_SIZE); - if(fd < 0){ - printk("Creating test memory file failed, err = %d\n", -fd); + if (fd < 0) { + printk(UM_KERN_ERR "Creating test memory file failed, " + "err = %d\n", -fd); goto out; } addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if(addr == MAP_FAILED){ - printk("Mapping test memory file failed, err = %d\n", -errno); + if (addr == MAP_FAILED) { + printk(UM_KERN_ERR "Mapping test memory file failed, " + "err = %d\n", -errno); goto out_close; } - if(madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0){ - printk("MADV_REMOVE failed, err = %d\n", -errno); + if (madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0) { + printk(UM_KERN_ERR "MADV_REMOVE failed, err = %d\n", -errno); goto out_unmap; } @@ -239,58 +235,31 @@ out: return ok; } -#ifdef UML_CONFIG_MODE_TT -void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) -{ - int flags = 0, pages; - - if(sig_stack != NULL){ - pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER); - set_sigstack(sig_stack, pages * UM_KERN_PAGE_SIZE); - flags = SA_ONSTACK; - } - if(usr1_handler){ - struct sigaction sa; - - sa.sa_handler = usr1_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = flags; - sa.sa_restorer = NULL; - if(sigaction(SIGUSR1, &sa, NULL) < 0) - panic("init_new_thread_stack - sigaction failed - " - "errno = %d\n", errno); - } -} -#endif - void init_new_thread_signals(void) { set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); + SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); set_handler(SIGTRAP, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); + SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); set_handler(SIGFPE, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); + SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); set_handler(SIGILL, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); + SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); set_handler(SIGBUS, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); - set_handler(SIGUSR2, (__sighandler_t) sig_handler, - SA_ONSTACK, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, - -1); + SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); signal(SIGHUP, SIG_IGN); init_irq_signals(1); } -int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) +int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr) { jmp_buf buf; int n; *jmp_ptr = &buf; n = UML_SETJMP(&buf); - if(n != 0) + if (n != 0) return n; (*fn)(arg); return 0; diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c new file mode 100644 index 000000000000..a32ba6ab1211 --- /dev/null +++ b/arch/um/os-Linux/registers.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2004 PathScale, Inc + * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include <errno.h> +#include <string.h> +#include <sys/ptrace.h> +#include "sysdep/ptrace.h" +#include "user.h" + +/* This is set once at boot time and not changed thereafter */ + +static unsigned long exec_regs[MAX_REG_NR]; + +void init_thread_registers(struct uml_pt_regs *to) +{ + memcpy(to->gp, exec_regs, sizeof(to->gp)); +} + +void save_registers(int pid, struct uml_pt_regs *regs) +{ + int err; + + err = ptrace(PTRACE_GETREGS, pid, 0, regs->gp); + if (err < 0) + panic("save_registers - saving registers failed, errno = %d\n", + errno); +} + +void restore_registers(int pid, struct uml_pt_regs *regs) +{ + int err; + + err = ptrace(PTRACE_SETREGS, pid, 0, regs->gp); + if (err < 0) + panic("restore_registers - saving registers failed, " + "errno = %d\n", errno); +} + +void init_registers(int pid) +{ + int err; + + err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); + if (err) + panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", + errno); + + arch_init_registers(pid); +} + +void get_safe_registers(unsigned long *regs) +{ + memcpy(regs, exec_regs, sizeof(exec_regs)); +} diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index b98f7ea2d2f6..e9800b0b5689 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -1,26 +1,21 @@ /* * Copyright (C) 2004 PathScale, Inc + * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <signal.h> -#include <stdio.h> -#include <unistd.h> #include <stdlib.h> -#include <errno.h> #include <stdarg.h> -#include <string.h> -#include <sys/mman.h> -#include "user.h" -#include "signal_kern.h" -#include "sysdep/sigcontext.h" -#include "sysdep/barrier.h" -#include "sigcontext.h" -#include "mode.h" +#include <errno.h> +#include <signal.h> +#include <strings.h> #include "os.h" +#include "sysdep/barrier.h" +#include "sysdep/sigcontext.h" +#include "user.h" -/* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled - * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to +/* + * These are the asynchronous signals. SIGPROF is excluded because we want to * be able to profile all of UML, not just the non-critical sections. If * profiling is not thread-safe, then that is not my problem. We can disable * profiling when SMP is enabled in that case. @@ -31,10 +26,8 @@ #define SIGVTALRM_BIT 1 #define SIGVTALRM_MASK (1 << SIGVTALRM_BIT) -#define SIGALRM_BIT 2 -#define SIGALRM_MASK (1 << SIGALRM_BIT) - -/* These are used by both the signal handlers and +/* + * These are used by both the signal handlers and * block/unblock_signals. I don't want modifications cached in a * register - they must go straight to memory. */ @@ -46,34 +39,27 @@ void sig_handler(int sig, struct sigcontext *sc) int enabled; enabled = signals_enabled; - if(!enabled && (sig == SIGIO)){ + if (!enabled && (sig == SIGIO)) { pending |= SIGIO_MASK; return; } block_signals(); - CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas, - sig, sc); + sig_handler_common_skas(sig, sc); set_signals(enabled); } -static void real_alarm_handler(int sig, struct sigcontext *sc) +static void real_alarm_handler(struct sigcontext *sc) { - union uml_pt_regs regs; + struct uml_pt_regs regs; - if(sig == SIGALRM) - switch_timers(0); - - if(sc != NULL) + if (sc != NULL) copy_sc(®s, sc); - regs.skas.is_user = 0; + regs.is_user = 0; unblock_signals(); - timer_handler(sig, ®s); - - if(sig == SIGALRM) - switch_timers(1); + timer_handler(SIGVTALRM, ®s); } void alarm_handler(int sig, struct sigcontext *sc) @@ -81,27 +67,30 @@ void alarm_handler(int sig, struct sigcontext *sc) int enabled; enabled = signals_enabled; - if(!signals_enabled){ - if(sig == SIGVTALRM) - pending |= SIGVTALRM_MASK; - else pending |= SIGALRM_MASK; - + if (!signals_enabled) { + pending |= SIGVTALRM_MASK; return; } block_signals(); - real_alarm_handler(sig, sc); + real_alarm_handler(sc); set_signals(enabled); } +void timer_init(void) +{ + set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, + SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, -1); +} + void set_sigstack(void *sig_stack, int size) { stack_t stack = ((stack_t) { .ss_flags = 0, .ss_sp = (__ptr_t) sig_stack, .ss_size = size - sizeof(void *) }); - if(sigaltstack(&stack, NULL) != 0) + if (sigaltstack(&stack, NULL) != 0) panic("enabling signal stack failed, errno = %d\n", errno); } @@ -111,7 +100,7 @@ void remove_sigstack(void) .ss_sp = NULL, .ss_size = 0 }); - if(sigaltstack(&stack, NULL) != 0) + if (sigaltstack(&stack, NULL) != 0) panic("disabling signal stack failed, errno = %d\n", errno); } @@ -135,26 +124,27 @@ void handle_signal(int sig, struct sigcontext *sc) * with this interrupt. */ bail = to_irq_stack(&pending); - if(bail) + if (bail) return; nested = pending & 1; pending &= ~1; - while((sig = ffs(pending)) != 0){ + while ((sig = ffs(pending)) != 0){ sig--; pending &= ~(1 << sig); (*handlers[sig])(sig, sc); } - /* Again, pending comes back with a mask of signals + /* + * Again, pending comes back with a mask of signals * that arrived while tearing down the stack. If this * is non-zero, we just go back, set up the stack * again, and handle the new interrupts. */ - if(!nested) + if (!nested) pending = from_irq_stack(nested); - } while(pending); + } while (pending); } extern void hard_handler(int sig); @@ -172,18 +162,18 @@ void set_handler(int sig, void (*handler)(int), int flags, ...) sigemptyset(&action.sa_mask); va_start(ap, flags); - while((mask = va_arg(ap, int)) != -1) + while ((mask = va_arg(ap, int)) != -1) sigaddset(&action.sa_mask, mask); va_end(ap); action.sa_flags = flags; action.sa_restorer = NULL; - if(sigaction(sig, &action, NULL) < 0) + if (sigaction(sig, &action, NULL) < 0) panic("sigaction failed - errno = %d\n", errno); sigemptyset(&sig_mask); sigaddset(&sig_mask, sig); - if(sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0) + if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0) panic("sigprocmask failed - errno = %d\n", errno); } @@ -194,13 +184,14 @@ int change_sig(int signal, int on) sigemptyset(&sigset); sigaddset(&sigset, signal); sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old); - return(!sigismember(&old, signal)); + return !sigismember(&old, signal); } void block_signals(void) { signals_enabled = 0; - /* This must return with signals disabled, so this barrier + /* + * This must return with signals disabled, so this barrier * ensures that writes are flushed out before the return. * This might matter if gcc figures out how to inline this and * decides to shuffle this code into the caller. @@ -212,27 +203,31 @@ void unblock_signals(void) { int save_pending; - if(signals_enabled == 1) + if (signals_enabled == 1) return; - /* We loop because the IRQ handler returns with interrupts off. So, + /* + * We loop because the IRQ handler returns with interrupts off. So, * interrupts may have arrived and we need to re-enable them and * recheck pending. */ - while(1){ - /* Save and reset save_pending after enabling signals. This + while(1) { + /* + * Save and reset save_pending after enabling signals. This * way, pending won't be changed while we're reading it. */ signals_enabled = 1; - /* Setting signals_enabled and reading pending must + /* + * Setting signals_enabled and reading pending must * happen in this order. */ mb(); save_pending = pending; - if(save_pending == 0){ - /* This must return with signals enabled, so + if (save_pending == 0) { + /* + * This must return with signals enabled, so * this barrier ensures that writes are * flushed out before the return. This might * matter if gcc figures out how to inline @@ -245,26 +240,24 @@ void unblock_signals(void) pending = 0; - /* We have pending interrupts, so disable signals, as the + /* + * We have pending interrupts, so disable signals, as the * handlers expect them off when they are called. They will * be enabled again above. */ signals_enabled = 0; - /* Deal with SIGIO first because the alarm handler might + /* + * Deal with SIGIO first because the alarm handler might * schedule, leaving the pending SIGIO stranded until we come * back here. */ - if(save_pending & SIGIO_MASK) - CHOOSE_MODE_PROC(sig_handler_common_tt, - sig_handler_common_skas, SIGIO, NULL); - - if(save_pending & SIGALRM_MASK) - real_alarm_handler(SIGALRM, NULL); + if (save_pending & SIGIO_MASK) + sig_handler_common_skas(SIGIO, NULL); - if(save_pending & SIGVTALRM_MASK) - real_alarm_handler(SIGVTALRM, NULL); + if (save_pending & SIGVTALRM_MASK) + real_alarm_handler(NULL); } } @@ -276,11 +269,11 @@ int get_signals(void) int set_signals(int enable) { int ret; - if(signals_enabled == enable) + if (signals_enabled == enable) return enable; ret = signals_enabled; - if(enable) + if (enable) unblock_signals(); else block_signals(); diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index 0f7df4eb903f..484e68f9f7ae 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -1,31 +1,26 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <signal.h> +#include <stddef.h> +#include <unistd.h> #include <errno.h> #include <string.h> -#include <unistd.h> #include <sys/mman.h> -#include <sys/wait.h> -#include <asm/page.h> -#include <asm/unistd.h> -#include "mem_user.h" -#include "mem.h" -#include "skas.h" -#include "user.h" +#include "init.h" +#include "kern_constants.h" +#include "as-layout.h" +#include "mm_id.h" #include "os.h" #include "proc_mm.h" #include "ptrace_user.h" -#include "kern_util.h" -#include "task.h" #include "registers.h" -#include "uml-config.h" +#include "skas.h" +#include "user.h" #include "sysdep/ptrace.h" #include "sysdep/stub.h" -#include "init.h" -#include "kern_constants.h" +#include "uml-config.h" extern unsigned long batch_syscall_stub, __syscall_stub_start; @@ -34,7 +29,7 @@ extern void wait_stub_done(int pid); static inline unsigned long *check_init_stack(struct mm_id * mm_idp, unsigned long *stack) { - if(stack == NULL) { + if (stack == NULL) { stack = (unsigned long *) mm_idp->stack + 2; *stack = 0; } @@ -45,8 +40,8 @@ static unsigned long syscall_regs[MAX_REG_NR]; static int __init init_syscall_regs(void) { - get_safe_registers(syscall_regs, NULL); - syscall_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + + get_safe_registers(syscall_regs); + syscall_regs[REGS_IP_INDEX] = STUB_CODE + ((unsigned long) &batch_syscall_stub - (unsigned long) &__syscall_stub_start); return 0; @@ -68,29 +63,30 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) unsigned long * syscall; int err, pid = mm_idp->u.pid; - if(proc_mm) + if (proc_mm) /* FIXME: Need to look up userspace_pid by cpu */ pid = userspace_pid[0]; multi_count++; n = ptrace_setregs(pid, syscall_regs); - if(n < 0){ - printk("Registers - \n"); - for(i = 0; i < MAX_REG_NR; i++) - printk("\t%d\t0x%lx\n", i, syscall_regs[i]); + if (n < 0) { + printk(UM_KERN_ERR "Registers - \n"); + for (i = 0; i < MAX_REG_NR; i++) + printk(UM_KERN_ERR "\t%d\t0x%lx\n", i, syscall_regs[i]); panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", -n); } err = ptrace(PTRACE_CONT, pid, 0, 0); - if(err) + if (err) panic("Failed to continue stub, pid = %d, errno = %d\n", pid, errno); wait_stub_done(pid); - /* When the stub stops, we find the following values on the + /* + * When the stub stops, we find the following values on the * beginning of the stack: * (long )return_value * (long )offset to failed sycall-data (0, if no error) @@ -98,26 +94,26 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) ret = *((unsigned long *) mm_idp->stack); offset = *((unsigned long *) mm_idp->stack + 1); if (offset) { - data = (unsigned long *)(mm_idp->stack + - offset - UML_CONFIG_STUB_DATA); - printk("do_syscall_stub : ret = %ld, offset = %ld, " + data = (unsigned long *)(mm_idp->stack + offset - STUB_DATA); + printk(UM_KERN_ERR "do_syscall_stub : ret = %ld, offset = %ld, " "data = %p\n", ret, offset, data); syscall = (unsigned long *)((unsigned long)data + data[0]); - printk("do_syscall_stub: syscall %ld failed, return value = " - "0x%lx, expected return value = 0x%lx\n", + printk(UM_KERN_ERR "do_syscall_stub: syscall %ld failed, " + "return value = 0x%lx, expected return value = 0x%lx\n", syscall[0], ret, syscall[7]); - printk(" syscall parameters: " + printk(UM_KERN_ERR " syscall parameters: " "0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", syscall[1], syscall[2], syscall[3], syscall[4], syscall[5], syscall[6]); - for(n = 1; n < data[0]/sizeof(long); n++) { - if(n == 1) - printk(" additional syscall data:"); - if(n % 4 == 1) - printk("\n "); + for (n = 1; n < data[0]/sizeof(long); n++) { + if (n == 1) + printk(UM_KERN_ERR " additional syscall " + "data:"); + if (n % 4 == 1) + printk("\n" UM_KERN_ERR " "); printk(" 0x%lx", data[n]); } - if(n > 1) + if (n > 1) printk("\n"); } else ret = 0; @@ -133,7 +129,7 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall, { unsigned long *stack = check_init_stack(mm_idp, *addr); - if(done && *addr == NULL) + if (done && *addr == NULL) single_count++; *stack += sizeof(long); @@ -150,8 +146,8 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall, *stack = 0; multi_op_count++; - if(!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) < - UM_KERN_PAGE_SIZE - 10 * sizeof(long))){ + if (!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) < + UM_KERN_PAGE_SIZE - 10 * sizeof(long))) { *addr = stack; return 0; } @@ -166,14 +162,15 @@ long syscall_stub_data(struct mm_id * mm_idp, unsigned long *stack; int ret = 0; - /* If *addr still is uninitialized, it *must* contain NULL. + /* + * If *addr still is uninitialized, it *must* contain NULL. * Thus in this case do_syscall_stub correctly won't be called. */ - if((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >= + if ((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >= UM_KERN_PAGE_SIZE - (10 + data_count) * sizeof(long)) { ret = do_syscall_stub(mm_idp, addr); /* in case of error, don't overwrite data on stack */ - if(ret) + if (ret) return ret; } @@ -185,7 +182,7 @@ long syscall_stub_data(struct mm_id * mm_idp, memcpy(stack + 1, data, data_count * sizeof(long)); *stub_addr = (void *)(((unsigned long)(stack + 1) & - ~UM_KERN_PAGE_MASK) + UML_CONFIG_STUB_DATA); + ~UM_KERN_PAGE_MASK) + STUB_DATA); return 0; } @@ -195,7 +192,7 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot, { int ret; - if(proc_mm){ + if (proc_mm) { struct proc_mm_op map; int fd = mm_idp->u.mm_fd; @@ -211,9 +208,10 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot, .offset= offset } } } ); CATCH_EINTR(ret = write(fd, &map, sizeof(map))); - if(ret != sizeof(map)){ + if (ret != sizeof(map)) { ret = -errno; - printk("map : /proc/mm map failed, err = %d\n", -ret); + printk(UM_KERN_ERR "map : /proc/mm map failed, " + "err = %d\n", -ret); } else ret = 0; } @@ -234,7 +232,7 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, { int ret; - if(proc_mm){ + if (proc_mm) { struct proc_mm_op unmap; int fd = mm_idp->u.mm_fd; @@ -245,9 +243,10 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, (unsigned long) addr, .len = len } } } ); CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap))); - if(ret != sizeof(unmap)){ + if (ret != sizeof(unmap)) { ret = -errno; - printk("unmap - proc_mm write returned %d\n", ret); + printk(UM_KERN_ERR "unmap - proc_mm write returned " + "%d\n", ret); } else ret = 0; } @@ -268,7 +267,7 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, struct proc_mm_op protect; int ret; - if(proc_mm){ + if (proc_mm) { int fd = mm_idp->u.mm_fd; protect = ((struct proc_mm_op) { .op = MM_MPROTECT, @@ -280,9 +279,9 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, .prot = prot } } } ); CATCH_EINTR(ret = write(fd, &protect, sizeof(protect))); - if(ret != sizeof(protect)){ + if (ret != sizeof(protect)) { ret = -errno; - printk("protect failed, err = %d", -ret); + printk(UM_KERN_ERR "protect failed, err = %d", -ret); } else ret = 0; } @@ -295,7 +294,3 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, return ret; } - -void before_mem_skas(unsigned long unused) -{ -} diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index ba9af8d62055..d77c81d7068a 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -1,48 +1,38 @@ /* - * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2002- 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ #include <stdlib.h> -#include <string.h> #include <unistd.h> -#include <errno.h> -#include <signal.h> #include <sched.h> -#include "ptrace_user.h" -#include <sys/wait.h> +#include <errno.h> +#include <string.h> #include <sys/mman.h> -#include <sys/user.h> -#include <sys/time.h> -#include <sys/syscall.h> -#include <asm/types.h> -#include "user.h" -#include "sysdep/ptrace.h" -#include "kern_util.h" -#include "skas.h" -#include "stub-data.h" -#include "mm_id.h" -#include "sysdep/sigcontext.h" -#include "sysdep/stub.h" -#include "os.h" -#include "proc_mm.h" -#include "skas_ptrace.h" +#include <sys/ptrace.h> +#include <sys/wait.h> +#include <asm/unistd.h> +#include "as-layout.h" #include "chan_user.h" -#include "registers.h" +#include "kern_constants.h" #include "mem.h" -#include "uml-config.h" +#include "os.h" #include "process.h" -#include "longjmp.h" -#include "kern_constants.h" -#include "as-layout.h" +#include "proc_mm.h" +#include "ptrace_user.h" +#include "registers.h" +#include "skas.h" +#include "skas_ptrace.h" +#include "user.h" +#include "sysdep/stub.h" int is_skas_winch(int pid, int fd, void *data) { - if(pid != os_getpgrp()) - return(0); + if (pid != getpgrp()) + return 0; register_winch_irq(-1, fd, -1, data, 0); - return(1); + return 1; } static int ptrace_dump_regs(int pid) @@ -50,13 +40,12 @@ static int ptrace_dump_regs(int pid) unsigned long regs[MAX_REG_NR]; int i; - if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) + if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) return -errno; - else { - printk("Stub registers -\n"); - for(i = 0; i < ARRAY_SIZE(regs); i++) - printk("\t%d - %lx\n", i, regs[i]); - } + + printk(UM_KERN_ERR "Stub registers -\n"); + for (i = 0; i < ARRAY_SIZE(regs); i++) + printk(UM_KERN_ERR "\t%d - %lx\n", i, regs[i]); return 0; } @@ -74,27 +63,28 @@ void wait_stub_done(int pid) { int n, status, err; - while(1){ + while (1) { CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if((n < 0) || !WIFSTOPPED(status)) + if ((n < 0) || !WIFSTOPPED(status)) goto bad_wait; - if(((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0) + if (((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0) break; err = ptrace(PTRACE_CONT, pid, 0, 0); - if(err) + if (err) panic("wait_stub_done : continue failed, errno = %d\n", errno); } - if(((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) + if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) return; bad_wait: err = ptrace_dump_regs(pid); - if(err) - printk("Failed to get registers from stub, errno = %d\n", -err); + if (err) + printk(UM_KERN_ERR "Failed to get registers from stub, " + "errno = %d\n", -err); panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, " "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status); } @@ -105,9 +95,9 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi) { int err; - if(ptrace_faultinfo){ + if (ptrace_faultinfo) { err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); - if(err) + if (err) panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " "errno = %d\n", errno); @@ -119,52 +109,57 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi) } else { err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); - if(err) + if (err) panic("Failed to continue stub, pid = %d, errno = %d\n", pid, errno); wait_stub_done(pid); - /* faultinfo is prepared by the stub-segv-handler at start of + /* + * faultinfo is prepared by the stub-segv-handler at start of * the stub stack page. We just have to copy it. */ memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); } } -static void handle_segv(int pid, union uml_pt_regs * regs) +static void handle_segv(int pid, struct uml_pt_regs * regs) { - get_skas_faultinfo(pid, ®s->skas.faultinfo); - segv(regs->skas.faultinfo, 0, 1, NULL); + get_skas_faultinfo(pid, ®s->faultinfo); + segv(regs->faultinfo, 0, 1, NULL); } -/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ -static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu) +/* + * To use the same value of using_sysemu as the caller, ask it that value + * (in local_using_sysemu + */ +static void handle_trap(int pid, struct uml_pt_regs *regs, + int local_using_sysemu) { int err, status; /* Mark this as a syscall */ - UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs); + UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->gp); if (!local_using_sysemu) { err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); - if(err < 0) - panic("handle_trap - nullifying syscall failed errno = %d\n", - errno); + if (err < 0) + panic("handle_trap - nullifying syscall failed, " + "errno = %d\n", errno); err = ptrace(PTRACE_SYSCALL, pid, 0, 0); - if(err < 0) - panic("handle_trap - continuing to end of syscall failed, " - "errno = %d\n", errno); + if (err < 0) + panic("handle_trap - continuing to end of syscall " + "failed, errno = %d\n", errno); CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); - if((err < 0) || !WIFSTOPPED(status) || - (WSTOPSIG(status) != SIGTRAP + 0x80)){ + if ((err < 0) || !WIFSTOPPED(status) || + (WSTOPSIG(status) != SIGTRAP + 0x80)) { err = ptrace_dump_regs(pid); - if(err) - printk("Failed to get registers from process, " - "errno = %d\n", -err); + if (err) + printk(UM_KERN_ERR "Failed to get registers " + "from process, errno = %d\n", -err); panic("handle_trap - failed to wait at end of syscall, " "errno = %d, status = %d\n", errno, status); } @@ -182,63 +177,64 @@ static int userspace_tramp(void *stack) ptrace(PTRACE_TRACEME, 0, 0, 0); - init_new_thread_signals(); - err = set_interval(1); - if(err) + signal(SIGTERM, SIG_DFL); + err = set_interval(); + if (err) panic("userspace_tramp - setting timer failed, errno = %d\n", err); - if(!proc_mm){ - /* This has a pte, but it can't be mapped in with the usual + if (!proc_mm) { + /* + * This has a pte, but it can't be mapped in with the usual * tlb_flush mechanism because this is part of that mechanism */ int fd; - __u64 offset; + unsigned long long offset; fd = phys_mapping(to_phys(&__syscall_stub_start), &offset); - addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE, + addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE, PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset); - if(addr == MAP_FAILED){ - printk("mapping mmap stub failed, errno = %d\n", - errno); + if (addr == MAP_FAILED) { + printk(UM_KERN_ERR "mapping mmap stub at 0x%lx failed, " + "errno = %d\n", STUB_CODE, errno); exit(1); } - if(stack != NULL){ + if (stack != NULL) { fd = phys_mapping(to_phys(stack), &offset); - addr = mmap((void *) UML_CONFIG_STUB_DATA, + addr = mmap((void *) STUB_DATA, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, offset); - if(addr == MAP_FAILED){ - printk("mapping segfault stack failed, " - "errno = %d\n", errno); + if (addr == MAP_FAILED) { + printk(UM_KERN_ERR "mapping segfault stack " + "at 0x%lx failed, errno = %d\n", + STUB_DATA, errno); exit(1); } } } - if(!ptrace_faultinfo && (stack != NULL)){ + if (!ptrace_faultinfo && (stack != NULL)) { struct sigaction sa; - unsigned long v = UML_CONFIG_STUB_CODE + + unsigned long v = STUB_CODE + (unsigned long) stub_segv_handler - (unsigned long) &__syscall_stub_start; - set_sigstack((void *) UML_CONFIG_STUB_DATA, UM_KERN_PAGE_SIZE); + set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE); sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO); sigaddset(&sa.sa_mask, SIGWINCH); - sigaddset(&sa.sa_mask, SIGALRM); sigaddset(&sa.sa_mask, SIGVTALRM); sigaddset(&sa.sa_mask, SIGUSR1); sa.sa_flags = SA_ONSTACK; sa.sa_handler = (void *) v; sa.sa_restorer = NULL; - if(sigaction(SIGSEGV, &sa, NULL) < 0) + if (sigaction(SIGSEGV, &sa, NULL) < 0) panic("userspace_tramp - setting SIGSEGV handler " "failed - errno = %d\n", errno); } - os_stop_process(os_getpid()); - return(0); + kill(os_getpid(), SIGSTOP); + return 0; } /* Each element set once, and only accessed by a single processor anyway */ @@ -255,44 +251,55 @@ int start_userspace(unsigned long stub_stack) stack = mmap(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if(stack == MAP_FAILED) + if (stack == MAP_FAILED) panic("start_userspace : mmap failed, errno = %d", errno); sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); flags = CLONE_FILES | SIGCHLD; - if(proc_mm) flags |= CLONE_VM; + if (proc_mm) + flags |= CLONE_VM; + pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); - if(pid < 0) + if (pid < 0) panic("start_userspace : clone failed, errno = %d", errno); do { CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0) + if (n < 0) panic("start_userspace : wait failed, errno = %d", errno); - } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM)); + } while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM)); - if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) + if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) panic("start_userspace : expected SIGSTOP, got status = %d", status); - if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0) - panic("start_userspace : PTRACE_OLDSETOPTIONS failed, errno=%d\n", - errno); + if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, + (void *) PTRACE_O_TRACESYSGOOD) < 0) + panic("start_userspace : PTRACE_OLDSETOPTIONS failed, " + "errno = %d\n", errno); - if(munmap(stack, UM_KERN_PAGE_SIZE) < 0) + if (munmap(stack, UM_KERN_PAGE_SIZE) < 0) panic("start_userspace : munmap failed, errno = %d\n", errno); - return(pid); + return pid; } -void userspace(union uml_pt_regs *regs) +void userspace(struct uml_pt_regs *regs) { + struct itimerval timer; + unsigned long long nsecs, now; int err, status, op, pid = userspace_pid[0]; /* To prevent races if using_sysemu changes under us.*/ int local_using_sysemu; - while(1){ + if (getitimer(ITIMER_VIRTUAL, &timer)) + printk("Failed to get itimer, errno = %d\n", errno); + nsecs = timer.it_value.tv_sec * UM_NSEC_PER_SEC + + timer.it_value.tv_usec * UM_NSEC_PER_USEC; + nsecs += os_nsecs(); + + while (1) { restore_registers(pid, regs); /* Now we set local_using_sysemu to be used for one loop */ @@ -302,26 +309,28 @@ void userspace(union uml_pt_regs *regs) singlestepping(NULL)); err = ptrace(op, pid, 0, 0); - if(err) + if (err) panic("userspace - could not resume userspace process, " "pid=%d, ptrace operation = %d, errno = %d\n", pid, op, errno); CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); - if(err < 0) + if (err < 0) panic("userspace - waitpid failed, errno = %d\n", errno); - regs->skas.is_user = 1; + regs->is_user = 1; save_registers(pid, regs); UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ - if(WIFSTOPPED(status)){ + if (WIFSTOPPED(status)) { int sig = WSTOPSIG(status); - switch(sig){ + switch(sig) { case SIGSEGV: - if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){ - get_skas_faultinfo(pid, ®s->skas.faultinfo); + if (PTRACE_FULL_FAULTINFO || + !ptrace_faultinfo) { + get_skas_faultinfo(pid, + ®s->faultinfo); (*sig_info[SIGSEGV])(SIGSEGV, regs); } else handle_segv(pid, regs); @@ -332,8 +341,20 @@ void userspace(union uml_pt_regs *regs) case SIGTRAP: relay_signal(SIGTRAP, regs); break; - case SIGIO: case SIGVTALRM: + now = os_nsecs(); + if(now < nsecs) + break; + block_signals(); + (*sig_info[sig])(sig, regs); + unblock_signals(); + nsecs = timer.it_value.tv_sec * + UM_NSEC_PER_SEC + + timer.it_value.tv_usec * + UM_NSEC_PER_USEC; + nsecs += os_nsecs(); + break; + case SIGIO: case SIGILL: case SIGBUS: case SIGFPE: @@ -343,30 +364,29 @@ void userspace(union uml_pt_regs *regs) unblock_signals(); break; default: - printk("userspace - child stopped with signal " - "%d\n", sig); + printk(UM_KERN_ERR "userspace - child stopped " + "with signal %d\n", sig); } pid = userspace_pid[0]; interrupt_end(); /* Avoid -ERESTARTSYS handling in host */ - if(PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET) - PT_SYSCALL_NR(regs->skas.regs) = -1; + if (PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET) + PT_SYSCALL_NR(regs->gp) = -1; } } } static unsigned long thread_regs[MAX_REG_NR]; -static unsigned long thread_fp_regs[HOST_FP_SIZE]; static int __init init_thread_regs(void) { - get_safe_registers(thread_regs, thread_fp_regs); + get_safe_registers(thread_regs); /* Set parent's instruction pointer to start of clone-stub */ - thread_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + + thread_regs[REGS_IP_INDEX] = STUB_CODE + (unsigned long) stub_clone_handler - (unsigned long) &__syscall_stub_start; - thread_regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + UM_KERN_PAGE_SIZE - + thread_regs[REGS_SP_INDEX] = STUB_DATA + UM_KERN_PAGE_SIZE - sizeof(void *); #ifdef __SIGNAL_FRAMESIZE thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE; @@ -378,53 +398,53 @@ __initcall(init_thread_regs); int copy_context_skas0(unsigned long new_stack, int pid) { + struct timeval tv = { .tv_sec = 0, .tv_usec = UM_USEC_PER_SEC / UM_HZ }; int err; unsigned long current_stack = current_stub_stack(); struct stub_data *data = (struct stub_data *) current_stack; struct stub_data *child_data = (struct stub_data *) new_stack; - __u64 new_offset; + unsigned long long new_offset; int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset); - /* prepare offset and fd of child's stack as argument for parent's + /* + * prepare offset and fd of child's stack as argument for parent's * and child's mmap2 calls */ *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset), .fd = new_fd, .timer = ((struct itimerval) - { { 0, 1000000 / hz() }, - { 0, 1000000 / hz() }})}); + { .it_value = tv, + .it_interval = tv }) }); + err = ptrace_setregs(pid, thread_regs); - if(err < 0) + if (err < 0) panic("copy_context_skas0 : PTRACE_SETREGS failed, " "pid = %d, errno = %d\n", pid, -err); - err = ptrace_setfpregs(pid, thread_fp_regs); - if(err < 0) - panic("copy_context_skas0 : PTRACE_SETFPREGS failed, " - "pid = %d, errno = %d\n", pid, -err); - /* set a well known return code for detection of child write failure */ child_data->err = 12345678; - /* Wait, until parent has finished its work: read child's pid from + /* + * Wait, until parent has finished its work: read child's pid from * parent's stack, and check, if bad result. */ err = ptrace(PTRACE_CONT, pid, 0, 0); - if(err) + if (err) panic("Failed to continue new process, pid = %d, " "errno = %d\n", pid, errno); wait_stub_done(pid); pid = data->err; - if(pid < 0) + if (pid < 0) panic("copy_context_skas0 - stub-parent reports error %d\n", -pid); - /* Wait, until child has finished too: read child's result from + /* + * Wait, until child has finished too: read child's result from * child's stack and check it. */ wait_stub_done(pid); - if (child_data->err != UML_CONFIG_STUB_DATA) + if (child_data->err != STUB_DATA) panic("copy_context_skas0 - stub-child reports error %ld\n", child_data->err); @@ -446,7 +466,7 @@ void map_stub_pages(int fd, unsigned long code, { struct proc_mm_op mmop; int n; - __u64 code_offset; + unsigned long long code_offset; int code_fd = phys_mapping(to_phys((void *) &__syscall_stub_start), &code_offset); @@ -461,16 +481,17 @@ void map_stub_pages(int fd, unsigned long code, .offset = code_offset } } }); CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); - if(n != sizeof(mmop)){ + if (n != sizeof(mmop)) { n = errno; - printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n", - code, code_fd, (unsigned long long) code_offset); + printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, " + "offset = %llx\n", code, code_fd, + (unsigned long long) code_offset); panic("map_stub_pages : /proc/mm map for code failed, " "err = %d\n", n); } - if ( stack ) { - __u64 map_offset; + if (stack) { + unsigned long long map_offset; int map_fd = phys_mapping(to_phys((void *)stack), &map_offset); mmop = ((struct proc_mm_op) { .op = MM_MMAP, @@ -484,7 +505,7 @@ void map_stub_pages(int fd, unsigned long code, .offset = map_offset } } }); CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); - if(n != sizeof(mmop)) + if (n != sizeof(mmop)) panic("map_stub_pages : /proc/mm map for data failed, " "err = %d\n", errno); } @@ -504,7 +525,7 @@ void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)) void switch_threads(jmp_buf *me, jmp_buf *you) { - if(UML_SETJMP(me) == 0) + if (UML_SETJMP(me) == 0) UML_LONGJMP(you, 1); } @@ -520,8 +541,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) int n; set_handler(SIGWINCH, (__sighandler_t) sig_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, - SIGVTALRM, -1); + SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGVTALRM, -1); /* * Can't use UML_SETJMP or UML_LONGJMP here because they save @@ -532,7 +552,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) * after returning to the jumper. */ n = setjmp(initial_jmpbuf); - switch(n){ + switch(n) { case INIT_JMP_NEW_THREAD: (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler; (*switch_buf)[0].JB_SP = (unsigned long) stack + @@ -544,10 +564,10 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) break; case INIT_JMP_HALT: kmalloc_ok = 0; - return(0); + return 0; case INIT_JMP_REBOOT: kmalloc_ok = 0; - return(1); + return 1; default: panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); } @@ -563,7 +583,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) cb_back = &here; block_signals(); - if(UML_SETJMP(&here) == 0) + if (UML_SETJMP(&here) == 0) UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); unblock_signals(); @@ -584,16 +604,16 @@ void reboot_skas(void) UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); } -void switch_mm_skas(struct mm_id *mm_idp) +void __switch_mm(struct mm_id *mm_idp) { int err; - /* FIXME: need cpu pid in switch_mm_skas */ - if(proc_mm){ + /* FIXME: need cpu pid in __switch_mm */ + if (proc_mm) { err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_idp->u.mm_fd); - if(err) - panic("switch_mm_skas - PTRACE_SWITCH_MM failed, " + if (err) + panic("__switch_mm - PTRACE_SWITCH_MM failed, " "errno = %d\n", errno); } else userspace_pid[0] = mm_idp->u.pid; diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c index 3b600c2e63b8..3b1b9244f468 100644 --- a/arch/um/os-Linux/skas/trap.c +++ b/arch/um/os-Linux/skas/trap.c @@ -1,37 +1,43 @@ /* - * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <signal.h> -#include <errno.h> +#if 0 #include "kern_util.h" -#include "as-layout.h" -#include "task.h" -#include "sigcontext.h" #include "skas.h" #include "ptrace_user.h" -#include "sysdep/ptrace.h" #include "sysdep/ptrace_user.h" +#endif + +#include <errno.h> +#include <signal.h> +#include "sysdep/ptrace.h" +#include "kern_constants.h" +#include "as-layout.h" #include "os.h" +#include "sigcontext.h" +#include "task.h" -static union uml_pt_regs ksig_regs[UM_NR_CPUS]; +static struct uml_pt_regs ksig_regs[UM_NR_CPUS]; void sig_handler_common_skas(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; - union uml_pt_regs *r; - void (*handler)(int, union uml_pt_regs *); + struct uml_pt_regs *r; + void (*handler)(int, struct uml_pt_regs *); int save_user, save_errno = errno; - /* This is done because to allow SIGSEGV to be delivered inside a SEGV + /* + * This is done because to allow SIGSEGV to be delivered inside a SEGV * handler. This can happen in copy_user, and if SEGV is disabled, * the process will die. * XXX Figure out why this is better than SA_NODEFER */ - if(sig == SIGSEGV) { + if (sig == SIGSEGV) { change_sig(SIGSEGV, 1); - /* For segfaults, we want the data from the + /* + * For segfaults, we want the data from the * sigcontext. In this case, we don't want to mangle * the process registers, so use a static set of * registers. For other signals, the process @@ -42,25 +48,22 @@ void sig_handler_common_skas(int sig, void *sc_ptr) } else r = TASK_REGS(get_current()); - save_user = r->skas.is_user; - r->skas.is_user = 0; - if ( sig == SIGFPE || sig == SIGSEGV || - sig == SIGBUS || sig == SIGILL || - sig == SIGTRAP ) { - GET_FAULTINFO_FROM_SC(r->skas.faultinfo, sc); - } + save_user = r->is_user; + r->is_user = 0; + if ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || + (sig == SIGILL) || (sig == SIGTRAP)) + GET_FAULTINFO_FROM_SC(r->faultinfo, sc); change_sig(SIGUSR1, 1); handler = sig_info[sig]; - /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */ - if (sig != SIGIO && sig != SIGWINCH && - sig != SIGVTALRM && sig != SIGALRM) + /* unblock SIGVTALRM, SIGIO if sig isn't IRQ signal */ + if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM)) unblock_signals(); handler(sig, r); errno = save_errno; - r->skas.is_user = save_user; + r->is_user = save_user; } diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 46f613975c19..7b81f6c08a5e 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -1,75 +1,65 @@ /* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <pty.h> #include <stdio.h> -#include <stddef.h> -#include <stdarg.h> #include <stdlib.h> -#include <string.h> +#include <stdarg.h> #include <unistd.h> -#include <signal.h> -#include <sched.h> -#include <fcntl.h> #include <errno.h> -#include <sys/time.h> -#include <sys/wait.h> +#include <fcntl.h> +#include <sched.h> +#include <signal.h> +#include <string.h> #include <sys/mman.h> -#include <sys/resource.h> +#include <sys/ptrace.h> +#include <sys/stat.h> +#include <sys/wait.h> #include <asm/unistd.h> -#include <asm/page.h> -#include <sys/types.h> -#include "kern_util.h" -#include "user.h" -#include "signal_kern.h" -#include "sysdep/ptrace.h" -#include "sysdep/sigcontext.h" -#include "irq_user.h" -#include "ptrace_user.h" -#include "mem_user.h" #include "init.h" -#include "os.h" -#include "uml-config.h" -#include "choose-mode.h" -#include "mode.h" -#include "tempfile.h" #include "kern_constants.h" - -#ifdef UML_CONFIG_MODE_SKAS -#include "skas.h" -#include "skas_ptrace.h" +#include "os.h" +#include "mem_user.h" +#include "ptrace_user.h" #include "registers.h" -#endif +#include "skas_ptrace.h" -static int ptrace_child(void *arg) +static int ptrace_child(void) { int ret; + /* Calling os_getpid because some libcs cached getpid incorrectly */ int pid = os_getpid(), ppid = getppid(); int sc_result; change_sig(SIGWINCH, 0); - if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ + if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) { perror("ptrace"); - os_kill_process(pid, 0); + kill(pid, SIGKILL); } kill(pid, SIGSTOP); - /*This syscall will be intercepted by the parent. Don't call more than - * once, please.*/ + /* + * This syscall will be intercepted by the parent. Don't call more than + * once, please. + */ sc_result = os_getpid(); if (sc_result == pid) - ret = 1; /*Nothing modified by the parent, we are running - normally.*/ + /* Nothing modified by the parent, we are running normally. */ + ret = 1; else if (sc_result == ppid) - ret = 0; /*Expected in check_ptrace and check_sysemu when they - succeed in modifying the stack frame*/ + /* + * Expected in check_ptrace and check_sysemu when they succeed + * in modifying the stack frame + */ + ret = 0; else - ret = 2; /*Serious trouble! This could be caused by a bug in - host 2.6 SKAS3/2.6 patch before release -V6, together - with a bug in the UML code itself.*/ + /* Serious trouble! This could be caused by a bug in host 2.6 + * SKAS3/2.6 patch before release -V6, together with a bug in + * the UML code itself. + */ + ret = 2; _exit(ret); } @@ -101,29 +91,23 @@ static void non_fatal(char *fmt, ...) fflush(stdout); } -static int start_ptraced_child(void **stack_out) +static int start_ptraced_child(void) { - void *stack; - unsigned long sp; int pid, n, status; - stack = mmap(NULL, UM_KERN_PAGE_SIZE, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if(stack == MAP_FAILED) - fatal_perror("check_ptrace : mmap failed"); - sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); - pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); - if(pid < 0) - fatal_perror("start_ptraced_child : clone failed"); + pid = fork(); + if (pid == 0) + ptrace_child(); + else if (pid < 0) + fatal_perror("start_ptraced_child : fork failed"); + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0) - fatal_perror("check_ptrace : clone failed"); - if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) + if (n < 0) + fatal_perror("check_ptrace : waitpid failed"); + if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) fatal("check_ptrace : expected SIGSTOP, got status = %d", status); - *stack_out = stack; return pid; } @@ -133,15 +117,14 @@ static int start_ptraced_child(void **stack_out) * So only for SYSEMU features we test mustpanic, while normal host features * must work anyway! */ -static int stop_ptraced_child(int pid, void *stack, int exitcode, - int mustexit) +static int stop_ptraced_child(int pid, int exitcode, int mustexit) { int status, n, ret = 0; - if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) + if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) fatal_perror("stop_ptraced_child : ptrace failed"); CATCH_EINTR(n = waitpid(pid, &status, 0)); - if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { + if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { int exit_with = WEXITSTATUS(status); if (exit_with == 2) non_fatal("check_ptrace : child exited with status 2. " @@ -154,8 +137,6 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, ret = -1; } - if(munmap(stack, UM_KERN_PAGE_SIZE) < 0) - fatal_perror("check_ptrace : munmap failed"); return ret; } @@ -207,40 +188,39 @@ __uml_setup("nosysemu", nosysemu_cmd_param, static void __init check_sysemu(void) { - void *stack; unsigned long regs[MAX_REG_NR]; int pid, n, status, count=0; non_fatal("Checking syscall emulation patch for ptrace..."); sysemu_supported = 0; - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); - if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) + if (ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) goto fail; CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if (n < 0) fatal_perror("check_sysemu : wait failed"); - if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) + if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) fatal("check_sysemu : expected SIGTRAP, got status = %d", status); - if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) + if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) fatal_perror("check_sysemu : PTRACE_GETREGS failed"); - if(PT_SYSCALL_NR(regs) != __NR_getpid){ + if (PT_SYSCALL_NR(regs) != __NR_getpid) { non_fatal("check_sysemu got system call number %d, " "expected %d...", PT_SYSCALL_NR(regs), __NR_getpid); goto fail; } n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); - if(n < 0){ + if (n < 0) { non_fatal("check_sysemu : failed to modify system call " "return"); goto fail; } - if (stop_ptraced_child(pid, stack, 0, 0) < 0) + if (stop_ptraced_child(pid, 0, 0) < 0) goto fail_stopped; sysemu_supported = 1; @@ -248,90 +228,90 @@ static void __init check_sysemu(void) set_using_sysemu(!force_sysemu_disabled); non_fatal("Checking advanced syscall emulation patch for ptrace..."); - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); - if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, + if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *) PTRACE_O_TRACESYSGOOD) < 0)) fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed"); - while(1){ + while (1) { count++; - if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) + if (ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) goto fail; CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0) + if (n < 0) fatal_perror("check_ptrace : wait failed"); - if(WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))){ + if (WIFSTOPPED(status) && + (WSTOPSIG(status) == (SIGTRAP|0x80))) { if (!count) fatal("check_ptrace : SYSEMU_SINGLESTEP " "doesn't singlestep"); n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); - if(n < 0) + if (n < 0) fatal_perror("check_sysemu : failed to modify " "system call return"); break; } - else if(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) + else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) count++; else fatal("check_ptrace : expected SIGTRAP or " "(SIGTRAP | 0x80), got status = %d", status); } - if (stop_ptraced_child(pid, stack, 0, 0) < 0) + if (stop_ptraced_child(pid, 0, 0) < 0) goto fail_stopped; sysemu_supported = 2; non_fatal("OK\n"); - if ( !force_sysemu_disabled ) + if (!force_sysemu_disabled) set_using_sysemu(sysemu_supported); return; fail: - stop_ptraced_child(pid, stack, 1, 0); + stop_ptraced_child(pid, 1, 0); fail_stopped: non_fatal("missing\n"); } static void __init check_ptrace(void) { - void *stack; int pid, syscall, n, status; non_fatal("Checking that ptrace can change system call numbers..."); - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); - if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, + if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *) PTRACE_O_TRACESYSGOOD) < 0)) fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed"); - while(1){ - if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) + while (1) { + if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) fatal_perror("check_ptrace : ptrace failed"); CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0) + if (n < 0) fatal_perror("check_ptrace : wait failed"); - if(!WIFSTOPPED(status) || + if (!WIFSTOPPED(status) || (WSTOPSIG(status) != (SIGTRAP | 0x80))) fatal("check_ptrace : expected (SIGTRAP|0x80), " "got status = %d", status); syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET, 0); - if(syscall == __NR_getpid){ + if (syscall == __NR_getpid) { n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, __NR_getppid); - if(n < 0) + if (n < 0) fatal_perror("check_ptrace : failed to modify " "system call"); break; } } - stop_ptraced_child(pid, stack, 0, 1); + stop_ptraced_child(pid, 0, 1); non_fatal("OK\n"); check_sysemu(); } @@ -343,18 +323,18 @@ static void __init check_coredump_limit(void) struct rlimit lim; int err = getrlimit(RLIMIT_CORE, &lim); - if(err){ + if (err) { perror("Getting core dump limit"); return; } printf("Core dump limits :\n\tsoft - "); - if(lim.rlim_cur == RLIM_INFINITY) + if (lim.rlim_cur == RLIM_INFINITY) printf("NONE\n"); else printf("%lu\n", lim.rlim_cur); printf("\thard - "); - if(lim.rlim_max == RLIM_INFINITY) + if (lim.rlim_max == RLIM_INFINITY) printf("NONE\n"); else printf("%lu\n", lim.rlim_max); } @@ -408,20 +388,18 @@ __uml_setup("noptraceldt", noptraceldt_cmd_param, " To support PTRACE_LDT, the host needs to be patched using\n" " the current skas3 patch.\n\n"); -#ifdef UML_CONFIG_MODE_SKAS static inline void check_skas3_ptrace_faultinfo(void) { struct ptrace_faultinfo fi; - void *stack; int pid, n; non_fatal(" - PTRACE_FAULTINFO..."); - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); if (n < 0) { ptrace_faultinfo = 0; - if(errno == EIO) + if (errno == EIO) non_fatal("not found\n"); else perror("not found"); @@ -434,13 +412,12 @@ static inline void check_skas3_ptrace_faultinfo(void) } init_registers(pid); - stop_ptraced_child(pid, stack, 1, 1); + stop_ptraced_child(pid, 1, 1); } static inline void check_skas3_ptrace_ldt(void) { #ifdef PTRACE_LDT - void *stack; int pid, n; unsigned char ldtbuf[40]; struct ptrace_ldt ldt_op = (struct ptrace_ldt) { @@ -449,11 +426,11 @@ static inline void check_skas3_ptrace_ldt(void) .bytecount = sizeof(ldtbuf)}; non_fatal(" - PTRACE_LDT..."); - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op); if (n < 0) { - if(errno == EIO) + if (errno == EIO) non_fatal("not found\n"); else { perror("not found"); @@ -461,13 +438,13 @@ static inline void check_skas3_ptrace_ldt(void) ptrace_ldt = 0; } else { - if(ptrace_ldt) + if (ptrace_ldt) non_fatal("found\n"); else non_fatal("found, but use is disabled\n"); } - stop_ptraced_child(pid, stack, 1, 1); + stop_ptraced_child(pid, 1, 1); #else /* PTRACE_LDT might be disabled via cmdline option. * We want to override this, else we might use the stub @@ -484,12 +461,9 @@ static inline void check_skas3_proc_mm(void) proc_mm = 0; perror("not found"); } - else { - if (!proc_mm) - non_fatal("found but disabled on command line\n"); - else - non_fatal("found\n"); - } + else if (!proc_mm) + non_fatal("found but disabled on command line\n"); + else non_fatal("found\n"); } int can_do_skas(void) @@ -500,17 +474,11 @@ int can_do_skas(void) check_skas3_ptrace_faultinfo(); check_skas3_ptrace_ldt(); - if(!proc_mm || !ptrace_faultinfo || !ptrace_ldt) + if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt) skas_needs_stub = 1; return 1; } -#else -int can_do_skas(void) -{ - return 0; -} -#endif int __init parse_iomem(char *str, int *add) { @@ -521,25 +489,25 @@ int __init parse_iomem(char *str, int *add) driver = str; file = strchr(str,','); - if(file == NULL){ + if (file == NULL) { printf("parse_iomem : failed to parse iomem\n"); goto out; } *file = '\0'; file++; fd = open(file, O_RDWR, 0); - if(fd < 0){ - os_print_error(fd, "parse_iomem - Couldn't open io file"); + if (fd < 0) { + perror("parse_iomem - Couldn't open io file"); goto out; } - if(fstat64(fd, &buf) < 0){ + if (fstat64(fd, &buf) < 0) { perror("parse_iomem - cannot stat_fd file"); goto out_close; } new = malloc(sizeof(*new)); - if(new == NULL){ + if (new == NULL) { perror("Couldn't allocate iomem_region struct"); goto out_close; } diff --git a/arch/um/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile index 37806621b25d..a841262c594a 100644 --- a/arch/um/os-Linux/sys-i386/Makefile +++ b/arch/um/os-Linux/sys-i386/Makefile @@ -1,9 +1,9 @@ # -# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) +# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) # Licensed under the GPL # -obj-$(CONFIG_MODE_SKAS) = registers.o signal.o tls.o +obj-y = registers.o signal.o tls.o USER_OBJS := $(obj-y) diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index 84b44f9cd42a..d1997ca76e5c 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c @@ -1,144 +1,73 @@ /* * Copyright (C) 2004 PathScale, Inc + * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ #include <errno.h> -#include <string.h> -#include "sysdep/ptrace_user.h" -#include "sysdep/ptrace.h" -#include "uml-config.h" -#include "skas_ptregs.h" -#include "registers.h" +#include "kern_constants.h" #include "longjmp.h" #include "user.h" +#include "sysdep/ptrace_user.h" -/* These are set once at boot time and not changed thereafter */ - -static unsigned long exec_regs[MAX_REG_NR]; -static unsigned long exec_fp_regs[HOST_FP_SIZE]; -static unsigned long exec_fpx_regs[HOST_XFP_SIZE]; -static int have_fpx_regs = 1; - -void init_thread_registers(union uml_pt_regs *to) -{ - memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs)); - memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp)); - if(have_fpx_regs) - memcpy(to->skas.xfp, exec_fpx_regs, sizeof(to->skas.xfp)); -} - -/* XXX These need to use [GS]ETFPXREGS and copy_sc_{to,from}_user_skas needs - * to pass in a sufficiently large buffer - */ int save_fp_registers(int pid, unsigned long *fp_regs) { - if(ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) + if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) return -errno; return 0; } int restore_fp_registers(int pid, unsigned long *fp_regs) { - if(ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) + if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) return -errno; return 0; } -static int move_registers(int pid, int int_op, union uml_pt_regs *regs, - int fp_op, unsigned long *fp_regs) +int save_fpx_registers(int pid, unsigned long *fp_regs) { - if(ptrace(int_op, pid, 0, regs->skas.regs) < 0) - return -errno; - - if(ptrace(fp_op, pid, 0, fp_regs) < 0) + if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0) return -errno; - return 0; } -void save_registers(int pid, union uml_pt_regs *regs) +int restore_fpx_registers(int pid, unsigned long *fp_regs) { - unsigned long *fp_regs; - int err, fp_op; - - if(have_fpx_regs){ - fp_op = PTRACE_GETFPXREGS; - fp_regs = regs->skas.xfp; - } - else { - fp_op = PTRACE_GETFPREGS; - fp_regs = regs->skas.fp; - } - - err = move_registers(pid, PTRACE_GETREGS, regs, fp_op, fp_regs); - if(err) - panic("save_registers - saving registers failed, errno = %d\n", - -err); + if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0) + return -errno; + return 0; } -void restore_registers(int pid, union uml_pt_regs *regs) +unsigned long get_thread_reg(int reg, jmp_buf *buf) { - unsigned long *fp_regs; - int err, fp_op; - - if(have_fpx_regs){ - fp_op = PTRACE_SETFPXREGS; - fp_regs = regs->skas.xfp; - } - else { - fp_op = PTRACE_SETFPREGS; - fp_regs = regs->skas.fp; + switch (reg) { + case EIP: + return buf[0]->__eip; + case UESP: + return buf[0]->__esp; + case EBP: + return buf[0]->__ebp; + default: + printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", + reg); + return 0; } - - err = move_registers(pid, PTRACE_SETREGS, regs, fp_op, fp_regs); - if(err) - panic("restore_registers - saving registers failed, " - "errno = %d\n", -err); } -void init_registers(int pid) +int have_fpx_regs = 1; + +void arch_init_registers(int pid) { + unsigned long fpx_regs[HOST_XFP_SIZE]; int err; - memset(exec_regs, 0, sizeof(exec_regs)); - err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); - if(err) - panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", - errno); - - errno = 0; - err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs); + err = ptrace(PTRACE_GETFPXREGS, pid, 0, fpx_regs); if(!err) return; + if(errno != EIO) panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", errno); have_fpx_regs = 0; - - err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); - if(err) - panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", - errno); -} - -void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) -{ - memcpy(regs, exec_regs, sizeof(exec_regs)); - if(fp_regs != NULL) - memcpy(fp_regs, exec_fp_regs, - HOST_FP_SIZE * sizeof(unsigned long)); -} - -unsigned long get_thread_reg(int reg, jmp_buf *buf) -{ - switch(reg){ - case EIP: return buf[0]->__eip; - case UESP: return buf[0]->__esp; - case EBP: return buf[0]->__ebp; - default: - printk("get_thread_regs - unknown register %d\n", reg); - return 0; - } } diff --git a/arch/um/os-Linux/sys-x86_64/Makefile b/arch/um/os-Linux/sys-x86_64/Makefile index 7955e061a678..a42a4ef02e1e 100644 --- a/arch/um/os-Linux/sys-x86_64/Makefile +++ b/arch/um/os-Linux/sys-x86_64/Makefile @@ -1,9 +1,9 @@ # -# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) +# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) # Licensed under the GPL # -obj-$(CONFIG_MODE_SKAS) = registers.o prctl.o signal.o +obj-y = registers.o prctl.o signal.o USER_OBJS := $(obj-y) diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c index 9467315b8059..9bfa789992de 100644 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ b/arch/um/os-Linux/sys-x86_64/registers.c @@ -1,23 +1,15 @@ /* - * Copyright (C) 2004 PathScale, Inc + * Copyright (C) 2006-2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ #include <errno.h> #include <sys/ptrace.h> -#include <string.h> -#include "ptrace_user.h" -#include "uml-config.h" -#include "skas_ptregs.h" -#include "registers.h" +#define __FRAME_OFFSETS +#include <asm/ptrace.h> #include "longjmp.h" #include "user.h" -/* These are set once at boot time and not changed thereafter */ - -static unsigned long exec_regs[MAX_REG_NR]; -static unsigned long exec_fp_regs[HOST_FP_SIZE]; - int save_fp_registers(int pid, unsigned long *fp_regs) { if(ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) @@ -32,67 +24,6 @@ int restore_fp_registers(int pid, unsigned long *fp_regs) return 0; } -void init_thread_registers(union uml_pt_regs *to) -{ - memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs)); - memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp)); -} - -static int move_registers(int pid, int int_op, int fp_op, - union uml_pt_regs *regs) -{ - if(ptrace(int_op, pid, 0, regs->skas.regs) < 0) - return -errno; - - if(ptrace(fp_op, pid, 0, regs->skas.fp) < 0) - return -errno; - - return 0; -} - -void save_registers(int pid, union uml_pt_regs *regs) -{ - int err; - - err = move_registers(pid, PTRACE_GETREGS, PTRACE_GETFPREGS, regs); - if(err) - panic("save_registers - saving registers failed, errno = %d\n", - -err); -} - -void restore_registers(int pid, union uml_pt_regs *regs) -{ - int err; - - err = move_registers(pid, PTRACE_SETREGS, PTRACE_SETFPREGS, regs); - if(err) - panic("restore_registers - saving registers failed, " - "errno = %d\n", -err); -} - -void init_registers(int pid) -{ - int err; - - err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); - if(err) - panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", - errno); - - err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); - if(err) - panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", - errno); -} - -void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) -{ - memcpy(regs, exec_regs, sizeof(exec_regs)); - if(fp_regs != NULL) - memcpy(fp_regs, exec_fp_regs, - HOST_FP_SIZE * sizeof(unsigned long)); -} - unsigned long get_thread_reg(int reg, jmp_buf *buf) { switch(reg){ diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 5de169b168f6..e34e1effe0f5 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -1,101 +1,86 @@ /* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> +#include <stddef.h> +#include <errno.h> +#include <signal.h> #include <time.h> #include <sys/time.h> -#include <signal.h> -#include <errno.h> -#include "kern_util.h" -#include "user.h" -#include "process.h" #include "kern_constants.h" #include "os.h" -#include "uml-config.h" +#include "user.h" -int set_interval(int is_virtual) +int set_interval(void) { - int usec = 1000000/hz(); - int timer_type = is_virtual ? ITIMER_VIRTUAL : ITIMER_REAL; + int usec = UM_USEC_PER_SEC / UM_HZ; struct itimerval interval = ((struct itimerval) { { 0, usec }, { 0, usec } }); - if(setitimer(timer_type, &interval, NULL) == -1) + if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1) return -errno; return 0; } -#ifdef UML_CONFIG_MODE_TT -void enable_timer(void) +int timer_one_shot(int ticks) { - set_interval(1); -} -#endif + unsigned long usec = ticks * UM_USEC_PER_SEC / UM_HZ; + unsigned long sec = usec / UM_USEC_PER_SEC; + struct itimerval interval; -void disable_timer(void) -{ - struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); - if((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) || - (setitimer(ITIMER_REAL, &disable, NULL) < 0)) - printk("disnable_timer - setitimer failed, errno = %d\n", - errno); - /* If there are signals already queued, after unblocking ignore them */ - signal(SIGALRM, SIG_IGN); - signal(SIGVTALRM, SIG_IGN); + usec %= UM_USEC_PER_SEC; + interval = ((struct itimerval) { { 0, 0 }, { sec, usec } }); + + if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1) + return -errno; + + return 0; } -void switch_timers(int to_real) +/** + * timeval_to_ns - Convert timeval to nanoseconds + * @ts: pointer to the timeval variable to be converted + * + * Returns the scalar nanosecond representation of the timeval + * parameter. + * + * Ripped from linux/time.h because it's a kernel header, and thus + * unusable from here. + */ +static inline long long timeval_to_ns(const struct timeval *tv) { - struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); - struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() }, - { 0, 1000000/hz() }}); - int old, new; - - if(to_real){ - old = ITIMER_VIRTUAL; - new = ITIMER_REAL; - } - else { - old = ITIMER_REAL; - new = ITIMER_VIRTUAL; - } - - if((setitimer(old, &disable, NULL) < 0) || - (setitimer(new, &enable, NULL))) - printk("switch_timers - setitimer failed, errno = %d\n", - errno); + return ((long long) tv->tv_sec * UM_NSEC_PER_SEC) + + tv->tv_usec * UM_NSEC_PER_USEC; } -#ifdef UML_CONFIG_MODE_TT -void uml_idle_timer(void) +long long disable_timer(void) { - if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR) - panic("Couldn't unset SIGVTALRM handler"); + struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } }); + + if(setitimer(ITIMER_VIRTUAL, &time, &time) < 0) + printk(UM_KERN_ERR "disable_timer - setitimer failed, " + "errno = %d\n", errno); - set_handler(SIGALRM, (__sighandler_t) alarm_handler, - SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); - set_interval(0); + return timeval_to_ns(&time.it_value); } -#endif -unsigned long long os_nsecs(void) +long long os_nsecs(void) { struct timeval tv; gettimeofday(&tv, NULL); - return((unsigned long long) tv.tv_sec * BILLION + tv.tv_usec * 1000); + return timeval_to_ns(&tv); } -void idle_sleep(int secs) +extern void alarm_handler(int sig, struct sigcontext *sc); + +void idle_sleep(unsigned long long nsecs) { - struct timespec ts; + struct timespec ts = { .tv_sec = nsecs / UM_NSEC_PER_SEC, + .tv_nsec = nsecs % UM_NSEC_PER_SEC }; - ts.tv_sec = secs; - ts.tv_nsec = 0; - nanosleep(&ts, NULL); + if (nanosleep(&ts, &ts) == 0) + alarm_handler(SIGVTALRM, NULL); } diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c index 16215b990804..73277801ef14 100644 --- a/arch/um/os-Linux/tls.c +++ b/arch/um/os-Linux/tls.c @@ -1,18 +1,9 @@ #include <errno.h> -#include <unistd.h> #include <sys/ptrace.h> -#include <sys/syscall.h> -#include <asm/ldt.h> #include "sysdep/tls.h" -#include "uml-config.h" /* TLS support - we basically rely on the host's one.*/ -/* In TT mode, this should be called only by the tracing thread, and makes sense - * only for PTRACE_SET_THREAD_AREA. In SKAS mode, it's used normally. - * - */ - #ifndef PTRACE_GET_THREAD_AREA #define PTRACE_GET_THREAD_AREA 25 #endif @@ -32,8 +23,6 @@ int os_set_thread_area(user_desc_t *info, int pid) return ret; } -#ifdef UML_CONFIG_MODE_SKAS - int os_get_thread_area(user_desc_t *info, int pid) { int ret; @@ -44,32 +33,3 @@ int os_get_thread_area(user_desc_t *info, int pid) ret = -errno; return ret; } - -#endif - -#ifdef UML_CONFIG_MODE_TT -#include "linux/unistd.h" - -int do_set_thread_area_tt(user_desc_t *info) -{ - int ret; - - ret = syscall(__NR_set_thread_area,info); - if (ret < 0) { - ret = -errno; - } - return ret; -} - -int do_get_thread_area_tt(user_desc_t *info) -{ - int ret; - - ret = syscall(__NR_get_thread_area,info); - if (ret < 0) { - ret = -errno; - } - return ret; -} - -#endif /* UML_CONFIG_MODE_TT */ diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c index 295da657931a..2a1c9843e32e 100644 --- a/arch/um/os-Linux/trap.c +++ b/arch/um/os-Linux/trap.c @@ -1,22 +1,14 @@ /* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <stdlib.h> #include <signal.h> -#include "kern_util.h" #include "os.h" -#include "mode.h" -#include "longjmp.h" - -void usr2_handler(int sig, union uml_pt_regs *regs) -{ - CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0); -} +#include "sysdep/ptrace.h" /* Initialized from linux_main() */ -void (*sig_info[NSIG])(int, union uml_pt_regs *); +void (*sig_info[NSIG])(int, struct uml_pt_regs *); void os_fill_handlinfo(struct kern_handlers h) { @@ -28,13 +20,4 @@ void os_fill_handlinfo(struct kern_handlers h) sig_info[SIGSEGV] = h.page_fault; sig_info[SIGIO] = h.sigio_handler; sig_info[SIGVTALRM] = h.timer_handler; - sig_info[SIGALRM] = h.timer_handler; - sig_info[SIGUSR2] = usr2_handler; -} - -void do_longjmp(void *b, int val) -{ - jmp_buf *buf = b; - - UML_LONGJMP(buf, val); } diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c deleted file mode 100644 index bcf9359c4e9f..000000000000 --- a/arch/um/os-Linux/tt.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include <stdio.h> -#include <unistd.h> -#include <signal.h> -#include <sched.h> -#include <errno.h> -#include <stdarg.h> -#include <stdlib.h> -#include <sys/time.h> -#include <sys/ptrace.h> -#include <linux/ptrace.h> -#include <sys/wait.h> -#include <sys/mman.h> -#include <asm/ptrace.h> -#include <asm/unistd.h> -#include <asm/page.h> -#include "kern_util.h" -#include "user.h" -#include "signal_kern.h" -#include "sysdep/ptrace.h" -#include "sysdep/sigcontext.h" -#include "irq_user.h" -#include "ptrace_user.h" -#include "init.h" -#include "os.h" -#include "uml-config.h" -#include "choose-mode.h" -#include "mode.h" -#include "tempfile.h" -#include "kern_constants.h" - -int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, - int must_succeed) -{ - int err; - - err = os_protect_memory((void *) addr, len, r, w, x); - if(err < 0){ - if(must_succeed) - panic("protect failed, err = %d", -err); - else return(err); - } - return(0); -} - -void kill_child_dead(int pid) -{ - kill(pid, SIGKILL); - kill(pid, SIGCONT); - do { - int n; - CATCH_EINTR(n = waitpid(pid, NULL, 0)); - if (n > 0) - kill(pid, SIGCONT); - else - break; - } while(1); -} - -void stop(void) -{ - while(1) sleep(1000000); -} - -int wait_for_stop(int pid, int sig, int cont_type, void *relay) -{ - sigset_t *relay_signals = relay; - int status, ret; - - while(1){ - CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED)); - if((ret < 0) || - !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){ - if(ret < 0){ - printk("wait failed, errno = %d\n", - errno); - } - else if(WIFEXITED(status)) - printk("process %d exited with status %d\n", - pid, WEXITSTATUS(status)); - else if(WIFSIGNALED(status)) - printk("process %d exited with signal %d\n", - pid, WTERMSIG(status)); - else if((WSTOPSIG(status) == SIGVTALRM) || - (WSTOPSIG(status) == SIGALRM) || - (WSTOPSIG(status) == SIGIO) || - (WSTOPSIG(status) == SIGPROF) || - (WSTOPSIG(status) == SIGCHLD) || - (WSTOPSIG(status) == SIGWINCH) || - (WSTOPSIG(status) == SIGINT)){ - ptrace(cont_type, pid, 0, WSTOPSIG(status)); - continue; - } - else if((relay_signals != NULL) && - sigismember(relay_signals, WSTOPSIG(status))){ - ptrace(cont_type, pid, 0, WSTOPSIG(status)); - continue; - } - else printk("process %d stopped with signal %d\n", - pid, WSTOPSIG(status)); - panic("wait_for_stop failed to wait for %d to stop " - "with %d\n", pid, sig); - } - return(status); - } -} - -void forward_ipi(int fd, int pid) -{ - int err; - - err = os_set_owner(fd, pid); - if(err < 0) - printk("forward_ipi: set_owner failed, fd = %d, me = %d, " - "target = %d, err = %d\n", fd, os_getpid(), pid, -err); -} - -/* - *------------------------- - * only for tt mode (will be deleted in future...) - *------------------------- - */ - -struct tramp { - int (*tramp)(void *); - void *tramp_data; - unsigned long temp_stack; - int flags; - int pid; -}; - -/* See above for why sigkill is here */ - -int sigkill = SIGKILL; - -int outer_tramp(void *arg) -{ - struct tramp *t; - int sig = sigkill; - - t = arg; - t->pid = clone(t->tramp, (void *) t->temp_stack + UM_KERN_PAGE_SIZE/2, - t->flags, t->tramp_data); - if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL); - kill(os_getpid(), sig); - _exit(0); -} - -int start_fork_tramp(void *thread_arg, unsigned long temp_stack, - int clone_flags, int (*tramp)(void *)) -{ - struct tramp arg; - unsigned long sp; - int new_pid, status, err; - - /* The trampoline will run on the temporary stack */ - sp = stack_sp(temp_stack); - - clone_flags |= CLONE_FILES | SIGCHLD; - - arg.tramp = tramp; - arg.tramp_data = thread_arg; - arg.temp_stack = temp_stack; - arg.flags = clone_flags; - - /* Start the process and wait for it to kill itself */ - new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg); - if(new_pid < 0) - return(new_pid); - - CATCH_EINTR(err = waitpid(new_pid, &status, 0)); - if(err < 0) - panic("Waiting for outer trampoline failed - errno = %d", - errno); - - if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL)) - panic("outer trampoline didn't exit with SIGKILL, " - "status = %d", status); - - return(arg.pid); -} - -void forward_pending_sigio(int target) -{ - sigset_t sigs; - - if(sigpending(&sigs)) - panic("forward_pending_sigio : sigpending failed"); - if(sigismember(&sigs, SIGIO)) - kill(target, SIGIO); -} - diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c index bbb73a650370..8d27b6d1df91 100644 --- a/arch/um/os-Linux/uaccess.c +++ b/arch/um/os-Linux/uaccess.c @@ -8,7 +8,7 @@ #include "longjmp.h" unsigned long __do_user_copy(void *to, const void *from, int n, - void **fault_addr, void **fault_catcher, + void **fault_addr, jmp_buf **fault_catcher, void (*op)(void *to, const void *from, int n), int *faulted_out) { diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index b462863f7172..106fa8641553 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c @@ -1,17 +1,21 @@ +/* + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + #include <stdio.h> -#include <unistd.h> #include <stdlib.h> -#include <string.h> +#include <dirent.h> #include <errno.h> +#include <fcntl.h> #include <signal.h> -#include <dirent.h> -#include <sys/fcntl.h> +#include <string.h> +#include <unistd.h> #include <sys/stat.h> -#include <sys/param.h> #include "init.h" +#include "kern_constants.h" #include "os.h" #include "user.h" -#include "mode.h" #define UML_DIR "~/.uml/" @@ -28,13 +32,13 @@ static int __init make_uml_dir(void) char dir[512] = { '\0' }; int len, err; - if(*uml_dir == '~'){ + if (*uml_dir == '~') { char *home = getenv("HOME"); err = -ENOENT; - if(home == NULL){ - printk("make_uml_dir : no value in environment for " - "$HOME\n"); + if (home == NULL) { + printk(UM_KERN_ERR "make_uml_dir : no value in " + "environment for $HOME\n"); goto err; } strlcpy(dir, home, sizeof(dir)); @@ -53,7 +57,7 @@ static int __init make_uml_dir(void) } strcpy(uml_dir, dir); - if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){ + if ((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)) { printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno)); err = -errno; goto err_free; @@ -70,8 +74,8 @@ err: /* * Unlinks the files contained in @dir and then removes @dir. * Doesn't handle directory trees, so it's not like rm -rf, but almost such. We - * ignore ENOENT errors for anything (they happen, strangely enough - possibly due - * to races between multiple dying UML threads). + * ignore ENOENT errors for anything (they happen, strangely enough - possibly + * due to races between multiple dying UML threads). */ static int remove_files_and_dir(char *dir) { @@ -116,7 +120,8 @@ out: return ret; } -/* This says that there isn't already a user of the specified directory even if +/* + * This says that there isn't already a user of the specified directory even if * there are errors during the checking. This is because if these errors * happen, the directory is unusable by the pre-existing UML, so we might as * well take it over. This could happen either by @@ -134,44 +139,45 @@ static inline int is_umdir_used(char *dir) int dead, fd, p, n, err; n = snprintf(file, sizeof(file), "%s/pid", dir); - if(n >= sizeof(file)){ - printk("is_umdir_used - pid filename too long\n"); + if (n >= sizeof(file)) { + printk(UM_KERN_ERR "is_umdir_used - pid filename too long\n"); err = -E2BIG; goto out; } dead = 0; fd = open(file, O_RDONLY); - if(fd < 0) { + if (fd < 0) { fd = -errno; - if(fd != -ENOENT){ - printk("is_umdir_used : couldn't open pid file '%s', " - "err = %d\n", file, -fd); + if (fd != -ENOENT) { + printk(UM_KERN_ERR "is_umdir_used : couldn't open pid " + "file '%s', err = %d\n", file, -fd); } goto out; } err = 0; n = read(fd, pid, sizeof(pid)); - if(n < 0){ - printk("is_umdir_used : couldn't read pid file '%s', " - "err = %d\n", file, errno); + if (n < 0) { + printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file " + "'%s', err = %d\n", file, errno); goto out_close; - } else if(n == 0){ - printk("is_umdir_used : couldn't read pid file '%s', " - "0-byte read\n", file); + } else if (n == 0) { + printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file " + "'%s', 0-byte read\n", file); goto out_close; } p = strtoul(pid, &end, 0); - if(end == pid){ - printk("is_umdir_used : couldn't parse pid file '%s', " - "errno = %d\n", file, errno); + if (end == pid) { + printk(UM_KERN_ERR "is_umdir_used : couldn't parse pid file " + "'%s', errno = %d\n", file, errno); goto out_close; } - if((kill(p, 0) == 0) || (errno != ESRCH)){ - printk("umid \"%s\" is already in use by pid %d\n", umid, p); + if ((kill(p, 0) == 0) || (errno != ESRCH)) { + printk(UM_KERN_ERR "umid \"%s\" is already in use by pid %d\n", + umid, p); return 1; } @@ -195,8 +201,8 @@ static int umdir_take_if_dead(char *dir) ret = remove_files_and_dir(dir); if (ret) { - printk("is_umdir_used - remove_files_and_dir failed with " - "err = %d\n", ret); + printk(UM_KERN_ERR "is_umdir_used - remove_files_and_dir " + "failed with err = %d\n", ret); } return ret; } @@ -207,27 +213,28 @@ static void __init create_pid_file(void) char pid[sizeof("nnnnn\0")]; int fd, n; - if(umid_file_name("pid", file, sizeof(file))) + if (umid_file_name("pid", file, sizeof(file))) return; fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644); - if(fd < 0){ - printk("Open of machine pid file \"%s\" failed: %s\n", - file, strerror(errno)); + if (fd < 0) { + printk(UM_KERN_ERR "Open of machine pid file \"%s\" failed: " + "%s\n", file, strerror(errno)); return; } snprintf(pid, sizeof(pid), "%d\n", getpid()); n = write(fd, pid, strlen(pid)); - if(n != strlen(pid)) - printk("Write of pid file failed - err = %d\n", errno); + if (n != strlen(pid)) + printk(UM_KERN_ERR "Write of pid file failed - err = %d\n", + errno); close(fd); } int __init set_umid(char *name) { - if(strlen(name) > UMID_LEN - 1) + if (strlen(name) > UMID_LEN - 1) return -E2BIG; strlcpy(umid, name, sizeof(umid)); @@ -243,18 +250,18 @@ int __init make_umid(void) int fd, err; char tmp[256]; - if(umid_setup) + if (umid_setup) return 0; make_uml_dir(); - if(*umid == '\0'){ + if (*umid == '\0') { strlcpy(tmp, uml_dir, sizeof(tmp)); strlcat(tmp, "XXXXXX", sizeof(tmp)); fd = mkstemp(tmp); - if(fd < 0){ - printk("make_umid - mkstemp(%s) failed: %s\n", - tmp, strerror(errno)); + if (fd < 0) { + printk(UM_KERN_ERR "make_umid - mkstemp(%s) failed: " + "%s\n", tmp, strerror(errno)); err = -errno; goto err; } @@ -263,11 +270,12 @@ int __init make_umid(void) set_umid(&tmp[strlen(uml_dir)]); - /* There's a nice tiny little race between this unlink and + /* + * There's a nice tiny little race between this unlink and * the mkdir below. It'd be nice if there were a mkstemp * for directories. */ - if(unlink(tmp)){ + if (unlink(tmp)) { err = -errno; goto err; } @@ -275,9 +283,9 @@ int __init make_umid(void) snprintf(tmp, sizeof(tmp), "%s%s", uml_dir, umid); err = mkdir(tmp, 0777); - if(err < 0){ + if (err < 0) { err = -errno; - if(err != -EEXIST) + if (err != -EEXIST) goto err; if (umdir_take_if_dead(tmp) < 0) @@ -285,9 +293,10 @@ int __init make_umid(void) err = mkdir(tmp, 0777); } - if(err){ + if (err) { err = -errno; - printk("Failed to create '%s' - err = %d\n", umid, -errno); + printk(UM_KERN_ERR "Failed to create '%s' - err = %d\n", umid, + errno); goto err; } @@ -302,14 +311,15 @@ int __init make_umid(void) static int __init make_umid_init(void) { - if(!make_umid()) + if (!make_umid()) return 0; - /* If initializing with the given umid failed, then try again with + /* + * If initializing with the given umid failed, then try again with * a random one. */ - printk("Failed to initialize umid \"%s\", trying with a random umid\n", - umid); + printk(UM_KERN_ERR "Failed to initialize umid \"%s\", trying with a " + "random umid\n", umid); *umid = '\0'; make_umid(); @@ -323,12 +333,12 @@ int __init umid_file_name(char *name, char *buf, int len) int n, err; err = make_umid(); - if(err) + if (err) return err; n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name); - if(n >= len){ - printk("umid_file_name : buffer too short\n"); + if (n >= len) { + printk(UM_KERN_ERR "umid_file_name : buffer too short\n"); return -E2BIG; } @@ -342,21 +352,22 @@ char *get_umid(void) static int __init set_uml_dir(char *name, int *add) { - if(*name == '\0'){ + if (*name == '\0') { printf("uml_dir can't be an empty string\n"); return 0; } - if(name[strlen(name) - 1] == '/'){ + if (name[strlen(name) - 1] == '/') { uml_dir = name; return 0; } uml_dir = malloc(strlen(name) + 2); - if(uml_dir == NULL){ + if (uml_dir == NULL) { printf("Failed to malloc uml_dir - error = %d\n", errno); - /* Return 0 here because do_initcalls doesn't look at + /* + * Return 0 here because do_initcalls doesn't look at * the return value. */ return 0; @@ -377,7 +388,7 @@ static void remove_umid_dir(void) sprintf(dir, "%s%s", uml_dir, umid); err = remove_files_and_dir(dir); - if(err) + if (err) printf("remove_umid_dir - remove_files_and_dir failed with " "err = %d\n", err); } diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 7cbcf484e13d..ef095436a78c 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -105,6 +105,44 @@ int setjmp_wrapper(void (*proc)(void *, void *), ...) void os_dump_core(void) { + int pid; + signal(SIGSEGV, SIG_DFL); + + /* + * We are about to SIGTERM this entire process group to ensure that + * nothing is around to run after the kernel exits. The + * kernel wants to abort, not die through SIGTERM, so we + * ignore it here. + */ + + signal(SIGTERM, SIG_IGN); + kill(0, SIGTERM); + /* + * Most of the other processes associated with this UML are + * likely sTopped, so give them a SIGCONT so they see the + * SIGTERM. + */ + kill(0, SIGCONT); + + /* + * Now, having sent signals to everyone but us, make sure they + * die by ptrace. Processes can survive what's been done to + * them so far - the mechanism I understand is receiving a + * SIGSEGV and segfaulting immediately upon return. There is + * always a SIGSEGV pending, and (I'm guessing) signals are + * processed in numeric order so the SIGTERM (signal 15 vs + * SIGSEGV being signal 11) is never handled. + * + * Run a waitpid loop until we get some kind of error. + * Hopefully, it's ECHILD, but there's not a lot we can do if + * it's something else. Tell os_kill_ptraced_process not to + * wait for the child to report its death because there's + * nothing reasonable to do if that fails. + */ + + while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) + os_kill_ptraced_process(pid, 0); + abort(); } diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index a9a4b85ca516..61107b68e05b 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -21,12 +21,12 @@ $(UNPROFILE_OBJS:.o=.%): \ $(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF) -# The stubs and unmap.o can't try to call mcount or update basic block data +# The stubs can't try to call mcount or update basic block data define unprofile $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) endef ifdef subarch-obj-y obj-y += subarch.o -subarch-y = $(addprefix ../../$(SUBARCH)/,$(subarch-obj-y)) +subarch-y = $(addprefix ../../$(HEADER_ARCH)/,$(subarch-obj-y)) endif diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 8909b07d9ee7..964dc1a04c37 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile @@ -1,23 +1,21 @@ +# +# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) +# + obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ - ptrace_user.o setjmp.o signal.o sigcontext.o syscalls.o sysrq.o \ + ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ sys_call_table.o tls.o -obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o - -subarch-obj-y = lib/bitops.o lib/semaphore.o lib/string.o -subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o -subarch-obj-$(CONFIG_MODULES) += kernel/module.o +subarch-obj-y = lib/bitops_32.o lib/semaphore_32.o lib/string_32.o +subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o +subarch-obj-$(CONFIG_MODULES) += kernel/module_32.o -USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o +USER_OBJS := bugs.o ptrace_user.o fault.o USER_OBJS += user-offsets.s extra-y += user-offsets.s -extra-$(CONFIG_MODE_TT) += unmap.o - UNPROFILE_OBJS := stub_segv.o CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) include arch/um/scripts/Makefile.rules - -$(obj)/unmap.%: _c_flags = $(call unprofile,$(KBUILD_CFLAGS)) diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index 0393e44813e7..806895d73bcc 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -1,18 +1,15 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <unistd.h> #include <errno.h> +#include <signal.h> #include <string.h> -#include <sys/signal.h> -#include <asm/ldt.h> -#include "kern_util.h" -#include "user.h" -#include "sysdep/ptrace.h" -#include "task.h" +#include "kern_constants.h" #include "os.h" +#include "task.h" +#include "user.h" #define MAXTOKEN 64 @@ -30,18 +27,20 @@ static char token(int fd, char *buf, int len, char stop) do { n = os_read_file(fd, ptr, sizeof(*ptr)); c = *ptr++; - if(n != sizeof(*ptr)){ - if(n == 0) + if (n != sizeof(*ptr)) { + if (n == 0) return 0; - printk("Reading /proc/cpuinfo failed, err = %d\n", -n); - if(n < 0) + printk(UM_KERN_ERR "Reading /proc/cpuinfo failed, " + "err = %d\n", -n); + if (n < 0) return n; else return -EIO; } - } while((c != '\n') && (c != stop) && (ptr < end)); + } while ((c != '\n') && (c != stop) && (ptr < end)); - if(ptr == end){ - printk("Failed to find '%c' in /proc/cpuinfo\n", stop); + if (ptr == end) { + printk(UM_KERN_ERR "Failed to find '%c' in /proc/cpuinfo\n", + stop); return -1; } *(ptr - 1) = '\0'; @@ -54,26 +53,27 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) char c; scratch[len - 1] = '\0'; - while(1){ + while (1) { c = token(fd, scratch, len - 1, ':'); - if(c <= 0) + if (c <= 0) return 0; - else if(c != ':'){ - printk("Failed to find ':' in /proc/cpuinfo\n"); + else if (c != ':') { + printk(UM_KERN_ERR "Failed to find ':' in " + "/proc/cpuinfo\n"); return 0; } - if(!strncmp(scratch, key, strlen(key))) + if (!strncmp(scratch, key, strlen(key))) return 1; do { n = os_read_file(fd, &c, sizeof(c)); - if(n != sizeof(c)){ - printk("Failed to find newline in " + if (n != sizeof(c)) { + printk(UM_KERN_ERR "Failed to find newline in " "/proc/cpuinfo, err = %d\n", -n); return 0; } - } while(c != '\n'); + } while (c != '\n'); } return 0; } @@ -83,46 +83,50 @@ static int check_cpu_flag(char *feature, int *have_it) char buf[MAXTOKEN], c; int fd, len = ARRAY_SIZE(buf); - printk("Checking for host processor %s support...", feature); + printk(UM_KERN_INFO "Checking for host processor %s support...", + feature); fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); - if(fd < 0){ - printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); + if (fd < 0) { + printk(UM_KERN_ERR "Couldn't open /proc/cpuinfo, err = %d\n", + -fd); return 0; } *have_it = 0; - if(!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf))) + if (!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf))) goto out; c = token(fd, buf, len - 1, ' '); - if(c < 0) + if (c < 0) goto out; - else if(c != ' '){ - printk("Failed to find ' ' in /proc/cpuinfo\n"); + else if (c != ' ') { + printk(UM_KERN_ERR "Failed to find ' ' in /proc/cpuinfo\n"); goto out; } - while(1){ + while (1) { c = token(fd, buf, len - 1, ' '); - if(c < 0) + if (c < 0) goto out; - else if(c == '\n') break; + else if (c == '\n') + break; - if(!strcmp(buf, feature)){ + if (!strcmp(buf, feature)) { *have_it = 1; goto out; } } out: - if(*have_it == 0) + if (*have_it == 0) printk("No\n"); - else if(*have_it == 1) + else if (*have_it == 1) printk("Yes\n"); os_close_file(fd); return 1; } -#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems +#if 0 /* + * This doesn't work in tt mode, plus it's causing compilation problems * for some people. */ static void disable_lcall(void) @@ -135,8 +139,9 @@ static void disable_lcall(void) ldt.base_addr = 0; ldt.limit = 0; err = modify_ldt(1, &ldt, sizeof(ldt)); - if(err) - printk("Failed to disable lcall7 - errno = %d\n", errno); + if (err) + printk(UM_KERN_ERR "Failed to disable lcall7 - errno = %d\n", + errno); } #endif @@ -151,40 +156,41 @@ void arch_check_bugs(void) { int have_it; - if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){ - printk("/proc/cpuinfo not available - skipping CPU capability " - "checks\n"); + if (os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0) { + printk(UM_KERN_ERR "/proc/cpuinfo not available - skipping CPU " + "capability checks\n"); return; } - if(check_cpu_flag("cmov", &have_it)) + if (check_cpu_flag("cmov", &have_it)) host_has_cmov = have_it; - if(check_cpu_flag("xmm", &have_it)) + if (check_cpu_flag("xmm", &have_it)) host_has_xmm = have_it; } -int arch_handle_signal(int sig, union uml_pt_regs *regs) +int arch_handle_signal(int sig, struct uml_pt_regs *regs) { unsigned char tmp[2]; - /* This is testing for a cmov (0x0f 0x4x) instruction causing a + /* + * This is testing for a cmov (0x0f 0x4x) instruction causing a * SIGILL in init. */ - if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) + if ((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return 0; if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) panic("SIGILL in init, could not read instructions!\n"); - if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) + if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) return 0; - if(host_has_cmov == 0) + if (host_has_cmov == 0) panic("SIGILL caused by cmov, which this processor doesn't " "implement, boot a filesystem compiled for older " "processors"); - else if(host_has_cmov == 1) + else if (host_has_cmov == 1) panic("SIGILL caused by cmov, which this processor claims to " "implement"); - else if(host_has_cmov == -1) + else if (host_has_cmov == -1) panic("SIGILL caused by cmov, couldn't tell if this processor " "implements it, boot a filesystem compiled for older " "processors"); diff --git a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c index 745b4fd49e9f..d670f68532f4 100644 --- a/arch/um/sys-i386/fault.c +++ b/arch/um/sys-i386/fault.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -15,14 +15,14 @@ struct exception_table_entry const struct exception_table_entry *search_exception_tables(unsigned long add); /* Compare this to arch/i386/mm/extable.c:fixup_exception() */ -int arch_fixup(unsigned long address, union uml_pt_regs *regs) +int arch_fixup(unsigned long address, struct uml_pt_regs *regs) { const struct exception_table_entry *fixup; fixup = search_exception_tables(address); - if(fixup != 0){ + if (fixup != 0) { UPT_IP(regs) = fixup->fixup; - return(1); + return 1; } - return(0); + return 0; } diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index a939a7ef0227..67c0958eb984 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c @@ -1,106 +1,30 @@ /* - * 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 "linux/sched.h" -#include "linux/slab.h" -#include "linux/types.h" -#include "linux/errno.h" -#include "linux/spinlock.h" -#include "asm/uaccess.h" -#include "asm/smp.h" -#include "asm/ldt.h" +#include "linux/mm.h" #include "asm/unistd.h" -#include "choose-mode.h" -#include "kern.h" -#include "mode_kern.h" #include "os.h" - -extern int modify_ldt(int func, void *ptr, unsigned long bytecount); - -#ifdef CONFIG_MODE_TT - -static long do_modify_ldt_tt(int func, void __user *ptr, - unsigned long bytecount) -{ - struct user_desc info; - int res = 0; - void *buf = NULL; - void *p = NULL; /* What we pass to host. */ - - switch(func){ - case 1: - case 0x11: /* write_ldt */ - /* Do this check now to avoid overflows. */ - if (bytecount != sizeof(struct user_desc)) { - res = -EINVAL; - goto out; - } - - if(copy_from_user(&info, ptr, sizeof(info))) { - res = -EFAULT; - goto out; - } - - p = &info; - break; - case 0: - case 2: /* read_ldt */ - - /* The use of info avoids kmalloc on the write case, not on the - * read one. */ - buf = kmalloc(bytecount, GFP_KERNEL); - if (!buf) { - res = -ENOMEM; - goto out; - } - p = buf; - break; - default: - res = -ENOSYS; - goto out; - } - - res = modify_ldt(func, p, bytecount); - if(res < 0) - goto out; - - switch(func){ - case 0: - case 2: - /* Modify_ldt was for reading and returned the number of read - * bytes.*/ - if(copy_to_user(ptr, p, res)) - res = -EFAULT; - break; - } - -out: - kfree(buf); - return res; -} - -#endif - -#ifdef CONFIG_MODE_SKAS - +#include "proc_mm.h" #include "skas.h" #include "skas_ptrace.h" -#include "asm/mmu_context.h" -#include "proc_mm.h" +#include "sysdep/tls.h" + +extern int modify_ldt(int func, void *ptr, unsigned long bytecount); long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc, void **addr, int done) { long res; - if(proc_mm){ - /* This is a special handling for the case, that the mm to + if (proc_mm) { + /* + * This is a special handling for the case, that the mm to * modify isn't current->active_mm. * If this is called directly by modify_ldt, * (current->active_mm->context.skas.u == mm_idp) - * will be true. So no call to switch_mm_skas(mm_idp) is done. + * will be true. So no call to __switch_mm(mm_idp) is done. * If this is called in case of init_new_ldt or PTRACE_LDT, * mm_idp won't belong to current->active_mm, but child->mm. * So we need to switch child's mm into our userspace, then @@ -108,12 +32,12 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc, * * Note: I'm unsure: should interrupts be disabled here? */ - if(!current->active_mm || current->active_mm == &init_mm || - mm_idp != ¤t->active_mm->context.skas.id) - switch_mm_skas(mm_idp); + if (!current->active_mm || current->active_mm == &init_mm || + mm_idp != ¤t->active_mm->context.id) + __switch_mm(mm_idp); } - if(ptrace_ldt) { + if (ptrace_ldt) { struct ptrace_ldt ldt_op = (struct ptrace_ldt) { .func = func, .ptr = desc, @@ -121,7 +45,7 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc, u32 cpu; int pid; - if(!proc_mm) + if (!proc_mm) pid = mm_idp->u.pid; else { cpu = get_cpu(); @@ -130,7 +54,7 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc, res = os_ptrace_ldt(pid, 0, (unsigned long) &ldt_op); - if(proc_mm) + if (proc_mm) put_cpu(); } else { @@ -139,7 +63,7 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc, (sizeof(*desc) + sizeof(long) - 1) & ~(sizeof(long) - 1), addr, &stub_addr); - if(!res){ + if (!res) { unsigned long args[] = { func, (unsigned long)stub_addr, sizeof(*desc), @@ -149,13 +73,14 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc, } } - if(proc_mm){ - /* This is the second part of special handling, that makes + if (proc_mm) { + /* + * This is the second part of special handling, that makes * PTRACE_LDT possible to implement. */ - if(current->active_mm && current->active_mm != &init_mm && - mm_idp != ¤t->active_mm->context.skas.id) - switch_mm_skas(¤t->active_mm->context.skas.id); + if (current->active_mm && current->active_mm != &init_mm && + mm_idp != ¤t->active_mm->context.id) + __switch_mm(¤t->active_mm->context.id); } return res; @@ -170,21 +95,22 @@ static long read_ldt_from_host(void __user * ptr, unsigned long bytecount) .ptr = kmalloc(bytecount, GFP_KERNEL)}; u32 cpu; - if(ptrace_ldt.ptr == NULL) + if (ptrace_ldt.ptr == NULL) return -ENOMEM; - /* This is called from sys_modify_ldt only, so userspace_pid gives + /* + * This is called from sys_modify_ldt only, so userspace_pid gives * us the right number */ cpu = get_cpu(); res = os_ptrace_ldt(userspace_pid[cpu], 0, (unsigned long) &ptrace_ldt); put_cpu(); - if(res < 0) + if (res < 0) goto out; n = copy_to_user(ptr, ptrace_ldt.ptr, res); - if(n != 0) + if (n != 0) res = -EFAULT; out: @@ -209,35 +135,34 @@ static int read_ldt(void __user * ptr, unsigned long bytecount) { int i, err = 0; unsigned long size; - uml_ldt_t * ldt = ¤t->mm->context.skas.ldt; + uml_ldt_t * ldt = ¤t->mm->context.ldt; - if(!ldt->entry_count) + if (!ldt->entry_count) goto out; - if(bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) + if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; err = bytecount; - if(ptrace_ldt){ + if (ptrace_ldt) return read_ldt_from_host(ptr, bytecount); - } down(&ldt->semaphore); - if(ldt->entry_count <= LDT_DIRECT_ENTRIES){ + if (ldt->entry_count <= LDT_DIRECT_ENTRIES) { size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES; - if(size > bytecount) + if (size > bytecount) size = bytecount; - if(copy_to_user(ptr, ldt->u.entries, size)) + if (copy_to_user(ptr, ldt->u.entries, size)) err = -EFAULT; bytecount -= size; ptr += size; } else { - for(i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount; - i++){ + for (i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount; + i++) { size = PAGE_SIZE; - if(size > bytecount) + if (size > bytecount) size = bytecount; - if(copy_to_user(ptr, ldt->u.pages[i], size)){ + if (copy_to_user(ptr, ldt->u.pages[i], size)) { err = -EFAULT; break; } @@ -247,10 +172,10 @@ static int read_ldt(void __user * ptr, unsigned long bytecount) } up(&ldt->semaphore); - if(bytecount == 0 || err == -EFAULT) + if (bytecount == 0 || err == -EFAULT) goto out; - if(clear_user(ptr, bytecount)) + if (clear_user(ptr, bytecount)) err = -EFAULT; out: @@ -261,15 +186,16 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount) { int err; - if(bytecount > 5*LDT_ENTRY_SIZE) + if (bytecount > 5*LDT_ENTRY_SIZE) bytecount = 5*LDT_ENTRY_SIZE; err = bytecount; - /* UML doesn't support lcall7 and lcall27. + /* + * UML doesn't support lcall7 and lcall27. * So, we don't really have a default ldt, but emulate * an empty ldt of common host default ldt size. */ - if(clear_user(ptr, bytecount)) + if (clear_user(ptr, bytecount)) err = -EFAULT; return err; @@ -277,60 +203,60 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount) static int write_ldt(void __user * ptr, unsigned long bytecount, int func) { - uml_ldt_t * ldt = ¤t->mm->context.skas.ldt; - struct mm_id * mm_idp = ¤t->mm->context.skas.id; + uml_ldt_t * ldt = ¤t->mm->context.ldt; + struct mm_id * mm_idp = ¤t->mm->context.id; int i, err; struct user_desc ldt_info; struct ldt_entry entry0, *ldt_p; void *addr = NULL; err = -EINVAL; - if(bytecount != sizeof(ldt_info)) + if (bytecount != sizeof(ldt_info)) goto out; err = -EFAULT; - if(copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) + if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) goto out; err = -EINVAL; - if(ldt_info.entry_number >= LDT_ENTRIES) + if (ldt_info.entry_number >= LDT_ENTRIES) goto out; - if(ldt_info.contents == 3){ + if (ldt_info.contents == 3) { if (func == 1) goto out; if (ldt_info.seg_not_present == 0) goto out; } - if(!ptrace_ldt) - down(&ldt->semaphore); + if (!ptrace_ldt) + down(&ldt->semaphore); err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1); - if(err) + if (err) goto out_unlock; - else if(ptrace_ldt) { - /* With PTRACE_LDT available, this is used as a flag only */ - ldt->entry_count = 1; - goto out; - } - - if(ldt_info.entry_number >= ldt->entry_count && - ldt_info.entry_number >= LDT_DIRECT_ENTRIES){ - for(i=ldt->entry_count/LDT_ENTRIES_PER_PAGE; - i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number; - i++){ - if(i == 0) + else if (ptrace_ldt) { + /* With PTRACE_LDT available, this is used as a flag only */ + ldt->entry_count = 1; + goto out; + } + + if (ldt_info.entry_number >= ldt->entry_count && + ldt_info.entry_number >= LDT_DIRECT_ENTRIES) { + for (i=ldt->entry_count/LDT_ENTRIES_PER_PAGE; + i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number; + i++) { + if (i == 0) memcpy(&entry0, ldt->u.entries, sizeof(entry0)); ldt->u.pages[i] = (struct ldt_entry *) __get_free_page(GFP_KERNEL|__GFP_ZERO); - if(!ldt->u.pages[i]){ + if (!ldt->u.pages[i]) { err = -ENOMEM; /* Undo the change in host */ memset(&ldt_info, 0, sizeof(ldt_info)); write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1); goto out_unlock; } - if(i == 0) { + if (i == 0) { memcpy(ldt->u.pages[0], &entry0, sizeof(entry0)); memcpy(ldt->u.pages[0]+1, ldt->u.entries+1, @@ -339,17 +265,17 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func) ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE; } } - if(ldt->entry_count <= ldt_info.entry_number) + if (ldt->entry_count <= ldt_info.entry_number) ldt->entry_count = ldt_info.entry_number + 1; - if(ldt->entry_count <= LDT_DIRECT_ENTRIES) + if (ldt->entry_count <= LDT_DIRECT_ENTRIES) ldt_p = ldt->u.entries + ldt_info.entry_number; else ldt_p = ldt->u.pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] + ldt_info.entry_number%LDT_ENTRIES_PER_PAGE; - if(ldt_info.base_addr == 0 && ldt_info.limit == 0 && - (func == 1 || LDT_empty(&ldt_info))){ + if (ldt_info.base_addr == 0 && ldt_info.limit == 0 && + (func == 1 || LDT_empty(&ldt_info))) { ldt_p->a = 0; ldt_p->b = 0; } @@ -400,7 +326,7 @@ static void ldt_get_host_info(void) spin_lock(&host_ldt_lock); - if(host_ldt_entries != NULL){ + if (host_ldt_entries != NULL) { spin_unlock(&host_ldt_lock); return; } @@ -408,49 +334,49 @@ static void ldt_get_host_info(void) spin_unlock(&host_ldt_lock); - for(i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++); + for (i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++) + ; ldt = (struct ldt_entry *) __get_free_pages(GFP_KERNEL|__GFP_ZERO, order); - if(ldt == NULL) { - printk("ldt_get_host_info: couldn't allocate buffer for host " - "ldt\n"); + if (ldt == NULL) { + printk(KERN_ERR "ldt_get_host_info: couldn't allocate buffer " + "for host ldt\n"); return; } ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE); - if(ret < 0) { - printk("ldt_get_host_info: couldn't read host ldt\n"); + if (ret < 0) { + printk(KERN_ERR "ldt_get_host_info: couldn't read host ldt\n"); goto out_free; } - if(ret == 0) { + if (ret == 0) { /* default_ldt is active, simply write an empty entry 0 */ host_ldt_entries = dummy_list; goto out_free; } - for(i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++){ - if(ldt[i].a != 0 || ldt[i].b != 0) + for (i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++) { + if (ldt[i].a != 0 || ldt[i].b != 0) size++; } - if(size < ARRAY_SIZE(dummy_list)) + if (size < ARRAY_SIZE(dummy_list)) host_ldt_entries = dummy_list; else { size = (size + 1) * sizeof(dummy_list[0]); tmp = kmalloc(size, GFP_KERNEL); - if(tmp == NULL) { - printk("ldt_get_host_info: couldn't allocate host ldt " - "list\n"); + if (tmp == NULL) { + printk(KERN_ERR "ldt_get_host_info: couldn't allocate " + "host ldt list\n"); goto out_free; } host_ldt_entries = tmp; } - for(i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++){ - if(ldt[i].a != 0 || ldt[i].b != 0) { + for (i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++) { + if (ldt[i].a != 0 || ldt[i].b != 0) host_ldt_entries[k++] = i; - } } host_ldt_entries[k] = -1; @@ -458,8 +384,7 @@ out_free: free_pages((unsigned long)ldt, order); } -long init_new_ldt(struct mmu_context_skas * new_mm, - struct mmu_context_skas * from_mm) +long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm) { struct user_desc desc; short * num_p; @@ -469,15 +394,15 @@ long init_new_ldt(struct mmu_context_skas * new_mm, struct proc_mm_op copy; - if(!ptrace_ldt) + if (!ptrace_ldt) init_MUTEX(&new_mm->ldt.semaphore); - if(!from_mm){ + if (!from_mm) { memset(&desc, 0, sizeof(desc)); /* * We have to initialize a clean ldt. */ - if(proc_mm) { + if (proc_mm) { /* * If the new mm was created using proc_mm, host's * default-ldt currently is assigned, which normally @@ -485,8 +410,7 @@ long init_new_ldt(struct mmu_context_skas * new_mm, * To remove these gates, we simply write an empty * entry as number 0 to the host. */ - err = write_ldt_entry(&new_mm->id, 1, &desc, - &addr, 1); + err = write_ldt_entry(&new_mm->id, 1, &desc, &addr, 1); } else{ /* @@ -495,11 +419,11 @@ long init_new_ldt(struct mmu_context_skas * new_mm, * will be reset in the following loop */ ldt_get_host_info(); - for(num_p=host_ldt_entries; *num_p != -1; num_p++){ + for (num_p=host_ldt_entries; *num_p != -1; num_p++) { desc.entry_number = *num_p; err = write_ldt_entry(&new_mm->id, 1, &desc, &addr, *(num_p + 1) == -1); - if(err) + if (err) break; } } @@ -508,8 +432,9 @@ long init_new_ldt(struct mmu_context_skas * new_mm, goto out; } - if(proc_mm){ - /* We have a valid from_mm, so we now have to copy the LDT of + if (proc_mm) { + /* + * We have a valid from_mm, so we now have to copy the LDT of * from_mm to new_mm, because using proc_mm an new mm with * an empty/default LDT was created in new_mm() */ @@ -518,27 +443,27 @@ long init_new_ldt(struct mmu_context_skas * new_mm, { .copy_segments = from_mm->id.u.mm_fd } } ); i = os_write_file(new_mm->id.u.mm_fd, ©, sizeof(copy)); - if(i != sizeof(copy)) - printk("new_mm : /proc/mm copy_segments failed, " - "err = %d\n", -i); + if (i != sizeof(copy)) + printk(KERN_ERR "new_mm : /proc/mm copy_segments " + "failed, err = %d\n", -i); } - if(!ptrace_ldt) { - /* Our local LDT is used to supply the data for + if (!ptrace_ldt) { + /* + * Our local LDT is used to supply the data for * modify_ldt(READLDT), if PTRACE_LDT isn't available, * i.e., we have to use the stub for modify_ldt, which * can't handle the big read buffer of up to 64kB. */ down(&from_mm->ldt.semaphore); - if(from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES){ + if (from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES) memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries, sizeof(new_mm->ldt.u.entries)); - } - else{ + else { i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; - while(i-->0){ + while (i-->0) { page = __get_free_page(GFP_KERNEL|__GFP_ZERO); - if (!page){ + if (!page) { err = -ENOMEM; break; } @@ -557,22 +482,19 @@ long init_new_ldt(struct mmu_context_skas * new_mm, } -void free_ldt(struct mmu_context_skas * mm) +void free_ldt(struct mm_context *mm) { int i; - if(!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES){ + if (!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES) { i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; - while(i-- > 0){ - free_page((long )mm->ldt.u.pages[i]); - } + while (i-- > 0) + free_page((long) mm->ldt.u.pages[i]); } mm->ldt.entry_count = 0; } -#endif int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) { - return CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func, - ptr, bytecount); + return do_modify_ldt_skas(func, ptr, bytecount); } diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index 28bf01150323..9657c89fdf31 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c @@ -1,35 +1,26 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <linux/compiler.h> -#include "linux/sched.h" #include "linux/mm.h" -#include "asm/elf.h" -#include "asm/ptrace.h" +#include "linux/sched.h" #include "asm/uaccess.h" -#include "asm/unistd.h" -#include "sysdep/ptrace.h" -#include "sysdep/sigcontext.h" -#include "sysdep/sc.h" +#include "skas.h" -void arch_switch_to_tt(struct task_struct *from, struct task_struct *to) -{ - update_debugregs(to->thread.arch.debugregs_seq); - arch_switch_tls_tt(from, to); -} +extern int arch_switch_tls(struct task_struct *from, struct task_struct *to); -void arch_switch_to_skas(struct task_struct *from, struct task_struct *to) +void arch_switch_to(struct task_struct *from, struct task_struct *to) { - int err = arch_switch_tls_skas(from, to); + int err = arch_switch_tls(from, to); if (!err) return; if (err != -EINVAL) - printk(KERN_WARNING "arch_switch_tls_skas failed, errno %d, not EINVAL\n", -err); + printk(KERN_WARNING "arch_switch_tls failed, errno %d, " + "not EINVAL\n", -err); else - printk(KERN_WARNING "arch_switch_tls_skas failed, errno = EINVAL\n"); + printk(KERN_WARNING "arch_switch_tls failed, errno = EINVAL\n"); } int is_syscall(unsigned long addr) @@ -38,21 +29,21 @@ int is_syscall(unsigned long addr) int n; n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); - if(n){ + if (n) { /* access_process_vm() grants access to vsyscall and stub, * while copy_from_user doesn't. Maybe access_process_vm is * slow, but that doesn't matter, since it will be called only * in case of singlestepping, if copy_from_user failed. */ n = access_process_vm(current, addr, &instr, sizeof(instr), 0); - if(n != sizeof(instr)) { - printk("is_syscall : failed to read instruction from " - "0x%lx\n", addr); - return(1); + if (n != sizeof(instr)) { + printk(KERN_ERR "is_syscall : failed to read " + "instruction from 0x%lx\n", addr); + return 1; } } /* int 0x80 or sysenter */ - return((instr == 0x80cd) || (instr == 0x340f)); + return (instr == 0x80cd) || (instr == 0x340f); } /* determines which flags the user has access to. */ @@ -96,21 +87,21 @@ int putreg(struct task_struct *child, int regno, unsigned long value) int poke_user(struct task_struct *child, long addr, long data) { - if ((addr & 3) || addr < 0) - return -EIO; - - if (addr < MAX_REG_OFFSET) - return putreg(child, addr, data); + if ((addr & 3) || addr < 0) + return -EIO; - else if((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))){ - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - if((addr == 4) || (addr == 5)) return -EIO; - child->thread.arch.debugregs[addr] = data; - return 0; - } - return -EIO; + if (addr < MAX_REG_OFFSET) + return putreg(child, addr, data); + else if ((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))) { + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + if ((addr == 4) || (addr == 5)) + return -EIO; + child->thread.arch.debugregs[addr] = data; + return 0; + } + return -EIO; } unsigned long getreg(struct task_struct *child, int regno) @@ -133,20 +124,20 @@ unsigned long getreg(struct task_struct *child, int regno) return retval; } +/* read the word at location addr in the USER area. */ int peek_user(struct task_struct *child, long addr, long data) { -/* read the word at location addr in the USER area. */ unsigned long tmp; if ((addr & 3) || addr < 0) return -EIO; tmp = 0; /* Default return condition */ - if(addr < MAX_REG_OFFSET){ + if (addr < MAX_REG_OFFSET) { tmp = getreg(child, addr); } - else if((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))){ + else if ((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))) { addr -= offsetof(struct user, u_debugreg[0]); addr = addr >> 2; tmp = child->thread.arch.debugregs[addr]; @@ -154,277 +145,68 @@ int peek_user(struct task_struct *child, long addr, long data) return put_user(tmp, (unsigned long __user *) data); } -struct i387_fxsave_struct { - unsigned short cwd; - unsigned short swd; - unsigned short twd; - unsigned short fop; - long fip; - long fcs; - long foo; - long fos; - long mxcsr; - long reserved; - long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ - long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ - long padding[56]; -}; - -/* - * FPU tag word conversions. - */ - -static inline unsigned short twd_i387_to_fxsr( unsigned short twd ) +int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { - unsigned int tmp; /* to avoid 16 bit prefixes in the code */ - - /* Transform each pair of bits into 01 (valid) or 00 (empty) */ - tmp = ~twd; - tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ - /* and move the valid bits to the lower byte. */ - tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ - tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ - tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ - return tmp; -} + int err, n, cpu = ((struct thread_info *) child->stack)->cpu; + long fpregs[HOST_FP_SIZE]; -static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave ) -{ - struct _fpxreg *st = NULL; - unsigned long twd = (unsigned long) fxsave->twd; - unsigned long tag; - unsigned long ret = 0xffff0000; - int i; + BUG_ON(sizeof(*buf) != sizeof(fpregs)); + err = save_fp_registers(userspace_pid[cpu], fpregs); + if (err) + return err; -#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16); + n = copy_to_user((void *) buf, fpregs, sizeof(fpregs)); + if(n > 0) + return -EFAULT; - for ( i = 0 ; i < 8 ; i++ ) { - if ( twd & 0x1 ) { - st = (struct _fpxreg *) FPREG_ADDR( fxsave, i ); - - switch ( st->exponent & 0x7fff ) { - case 0x7fff: - tag = 2; /* Special */ - break; - case 0x0000: - if ( !st->significand[0] && - !st->significand[1] && - !st->significand[2] && - !st->significand[3] ) { - tag = 1; /* Zero */ - } else { - tag = 2; /* Special */ - } - break; - default: - if ( st->significand[3] & 0x8000 ) { - tag = 0; /* Valid */ - } else { - tag = 2; /* Special */ - } - break; - } - } else { - tag = 3; /* Empty */ - } - ret |= (tag << (2 * i)); - twd = twd >> 1; - } - return ret; + return n; } -/* - * FXSR floating point environment conversions. - */ - -#ifdef CONFIG_MODE_TT -static inline int convert_fxsr_to_user_tt(struct _fpstate __user *buf, - struct pt_regs *regs) +int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { - struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs)); - unsigned long env[7]; - struct _fpreg __user *to; - struct _fpxreg *from; - int i; + int n, cpu = ((struct thread_info *) child->stack)->cpu; + long fpregs[HOST_FP_SIZE]; - env[0] = (unsigned long)fxsave->cwd | 0xffff0000; - env[1] = (unsigned long)fxsave->swd | 0xffff0000; - env[2] = twd_fxsr_to_i387(fxsave); - env[3] = fxsave->fip; - env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16); - env[5] = fxsave->foo; - env[6] = fxsave->fos; + BUG_ON(sizeof(*buf) != sizeof(fpregs)); + n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs)); + if (n > 0) + return -EFAULT; - if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) ) - return 1; - - to = &buf->_st[0]; - from = (struct _fpxreg *) &fxsave->st_space[0]; - for ( i = 0 ; i < 8 ; i++, to++, from++ ) { - if ( __copy_to_user( to, from, sizeof(*to) ) ) - return 1; - } - return 0; + return restore_fp_registers(userspace_pid[cpu], fpregs); } -#endif -static inline int convert_fxsr_to_user(struct _fpstate __user *buf, - struct pt_regs *regs) +int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) { - return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0)); -} + int err, n, cpu = ((struct thread_info *) child->stack)->cpu; + long fpregs[HOST_XFP_SIZE]; -#ifdef CONFIG_MODE_TT -static inline int convert_fxsr_from_user_tt(struct pt_regs *regs, - struct _fpstate __user *buf) -{ - struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs)); - unsigned long env[7]; - struct _fpxreg *to; - struct _fpreg __user *from; - int i; - - if ( __copy_from_user( env, buf, 7 * sizeof(long) ) ) - return 1; + BUG_ON(sizeof(*buf) != sizeof(fpregs)); + err = save_fpx_registers(userspace_pid[cpu], fpregs); + if (err) + return err; - fxsave->cwd = (unsigned short)(env[0] & 0xffff); - fxsave->swd = (unsigned short)(env[1] & 0xffff); - fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff)); - fxsave->fip = env[3]; - fxsave->fop = (unsigned short)((env[4] & 0xffff0000) >> 16); - fxsave->fcs = (env[4] & 0xffff); - fxsave->foo = env[5]; - fxsave->fos = env[6]; + n = copy_to_user((void *) buf, fpregs, sizeof(fpregs)); + if(n > 0) + return -EFAULT; - to = (struct _fpxreg *) &fxsave->st_space[0]; - from = &buf->_st[0]; - for ( i = 0 ; i < 8 ; i++, to++, from++ ) { - if ( __copy_from_user( to, from, sizeof(*from) ) ) - return 1; - } - return 0; -} -#endif - -static inline int convert_fxsr_from_user(struct pt_regs *regs, - struct _fpstate __user *buf) -{ - return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0)); -} - -int get_fpregs(unsigned long buf, struct task_struct *child) -{ - int err; - - err = convert_fxsr_to_user((struct _fpstate __user *) buf, - &child->thread.regs); - if(err) return(-EFAULT); - else return(0); -} - -int set_fpregs(unsigned long buf, struct task_struct *child) -{ - int err; - - err = convert_fxsr_from_user(&child->thread.regs, - (struct _fpstate __user *) buf); - if(err) return(-EFAULT); - else return(0); -} - -#ifdef CONFIG_MODE_TT -int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk) -{ - struct pt_regs *regs = &tsk->thread.regs; - struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs)); - int err; - - err = __copy_to_user((void __user *) buf, fxsave, - sizeof(struct user_fxsr_struct)); - if(err) return -EFAULT; - else return 0; -} -#endif - -int get_fpxregs(unsigned long buf, struct task_struct *tsk) -{ - return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0)); -} - -#ifdef CONFIG_MODE_TT -int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk) -{ - struct pt_regs *regs = &tsk->thread.regs; - struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs)); - int err; - - err = __copy_from_user(fxsave, (void __user *) buf, - sizeof(struct user_fxsr_struct) ); - if(err) return -EFAULT; - else return 0; -} -#endif - -int set_fpxregs(unsigned long buf, struct task_struct *tsk) -{ - return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0)); -} - -#ifdef notdef -int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) -{ - fpu->cwd = (((SC_FP_CW(PT_REGS_SC(regs)) & 0xffff) << 16) | - (SC_FP_SW(PT_REGS_SC(regs)) & 0xffff)); - fpu->swd = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff; - fpu->twd = SC_FP_IPOFF(PT_REGS_SC(regs)); - fpu->fip = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff; - fpu->fcs = SC_FP_DATAOFF(PT_REGS_SC(regs)); - fpu->foo = SC_FP_DATASEL(PT_REGS_SC(regs)); - fpu->fos = 0; - memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)), - sizeof(fpu->st_space)); - return(1); + return n; } -#endif -#ifdef CONFIG_MODE_TT -static inline void copy_fpu_fxsave_tt(struct pt_regs *regs, - struct user_i387_struct *buf) +int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) { - struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs)); - unsigned short *to; - unsigned short *from; - int i; + int n, cpu = ((struct thread_info *) child->stack)->cpu; + long fpregs[HOST_XFP_SIZE]; - memcpy( buf, fpu, 7 * sizeof(long) ); + BUG_ON(sizeof(*buf) != sizeof(fpregs)); + n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs)); + if (n > 0) + return -EFAULT; - to = (unsigned short *) &buf->st_space[0]; - from = (unsigned short *) &fpu->st_space[0]; - for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) { - memcpy( to, from, 5 * sizeof(unsigned short) ); - } + return restore_fpx_registers(userspace_pid[cpu], fpregs); } -#endif -static inline void copy_fpu_fxsave(struct pt_regs *regs, - struct user_i387_struct *buf) +long subarch_ptrace(struct task_struct *child, long request, long addr, + long data) { - (void) CHOOSE_MODE(copy_fpu_fxsave_tt(regs, buf), 0); + return -EIO; } - -int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu ) -{ - copy_fpu_fxsave(regs, (struct user_i387_struct *) fpu); - return(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/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c index 40ff0c831bd0..5cf97bc229b9 100644 --- a/arch/um/sys-i386/ptrace_user.c +++ b/arch/um/sys-i386/ptrace_user.c @@ -1,20 +1,10 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include <stdio.h> -#include <stddef.h> #include <errno.h> -#include <unistd.h> -#include "ptrace_user.h" -/* Grr, asm/user.h includes asm/ptrace.h, so has to follow ptrace_user.h */ -#include <asm/user.h> -#include "kern_util.h" -#include "sysdep/thread.h" -#include "user.h" -#include "os.h" -#include "uml-config.h" +#include <sys/ptrace.h> int ptrace_getregs(long pid, unsigned long *regs_out) { @@ -43,89 +33,3 @@ int ptrace_setfpregs(long pid, unsigned long *regs) return -errno; return 0; } - -#ifdef UML_CONFIG_MODE_TT - -static void write_debugregs(int pid, unsigned long *regs) -{ - struct user *dummy; - int nregs, i; - - dummy = NULL; - nregs = ARRAY_SIZE(dummy->u_debugreg); - for(i = 0; i < nregs; i++){ - if((i == 4) || (i == 5)) continue; - if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i], - regs[i]) < 0) - printk("write_debugregs - ptrace failed on " - "register %d, value = 0x%lx, errno = %d\n", i, - regs[i], errno); - } -} - -static void read_debugregs(int pid, unsigned long *regs) -{ - struct user *dummy; - int nregs, i; - - dummy = NULL; - nregs = ARRAY_SIZE(dummy->u_debugreg); - for(i = 0; i < nregs; i++){ - regs[i] = ptrace(PTRACE_PEEKUSR, pid, - &dummy->u_debugreg[i], 0); - } -} - -/* Accessed only by the tracing thread */ -static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 }; - -void arch_enter_kernel(void *task, int pid) -{ - read_debugregs(pid, TASK_DEBUGREGS(task)); - write_debugregs(pid, kernel_debugregs); -} - -void arch_leave_kernel(void *task, int pid) -{ - read_debugregs(pid, kernel_debugregs); - write_debugregs(pid, TASK_DEBUGREGS(task)); -} - -#ifdef UML_CONFIG_PT_PROXY -/* Accessed only by the tracing thread */ -static int debugregs_seq; - -/* Only called by the ptrace proxy */ -void ptrace_pokeuser(unsigned long addr, unsigned long data) -{ - if((addr < offsetof(struct user, u_debugreg[0])) || - (addr > offsetof(struct user, u_debugreg[7]))) - return; - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - if(kernel_debugregs[addr] == data) return; - - kernel_debugregs[addr] = data; - debugregs_seq++; -} - -static void update_debugregs_cb(void *arg) -{ - int pid = *((int *) arg); - - write_debugregs(pid, kernel_debugregs); -} - -/* Optimized out in its header when not defined */ -void update_debugregs(int seq) -{ - int me; - - if(seq == debugregs_seq) return; - - me = os_getpid(); - initial_thread_cb(update_debugregs_cb, &me); -} -#endif - -#endif diff --git a/arch/um/sys-i386/sigcontext.c b/arch/um/sys-i386/sigcontext.c deleted file mode 100644 index 467d489c31cd..000000000000 --- a/arch/um/sys-i386/sigcontext.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include <stddef.h> -#include <string.h> -#include <asm/ptrace.h> -#include <asm/sigcontext.h> -#include "sysdep/ptrace.h" -#include "kern_util.h" - -void sc_to_sc(void *to_ptr, void *from_ptr) -{ - struct sigcontext *to = to_ptr, *from = from_ptr; - - memcpy(to, from, sizeof(*to) + sizeof(struct _fpstate)); - if(from->fpstate != NULL) - to->fpstate = (struct _fpstate *) (to + 1); -} - -unsigned long *sc_sigmask(void *sc_ptr) -{ - struct sigcontext *sc = sc_ptr; - return &sc->oldmask; -} - -int sc_get_fpregs(unsigned long buf, void *sc_ptr) -{ - struct sigcontext *sc = sc_ptr; - struct _fpstate *from = sc->fpstate, *to = (struct _fpstate *) buf; - int err = 0; - - if(from == NULL){ - err |= clear_user_proc(&to->cw, sizeof(to->cw)); - err |= clear_user_proc(&to->sw, sizeof(to->sw)); - err |= clear_user_proc(&to->tag, sizeof(to->tag)); - err |= clear_user_proc(&to->ipoff, sizeof(to->ipoff)); - err |= clear_user_proc(&to->cssel, sizeof(to->cssel)); - err |= clear_user_proc(&to->dataoff, sizeof(to->dataoff)); - err |= clear_user_proc(&to->datasel, sizeof(to->datasel)); - err |= clear_user_proc(&to->_st, sizeof(to->_st)); - } - else { - err |= copy_to_user_proc(&to->cw, &from->cw, sizeof(to->cw)); - err |= copy_to_user_proc(&to->sw, &from->sw, sizeof(to->sw)); - err |= copy_to_user_proc(&to->tag, &from->tag, - sizeof(to->tag)); - err |= copy_to_user_proc(&to->ipoff, &from->ipoff, - sizeof(to->ipoff)); - err |= copy_to_user_proc(&to->cssel,& from->cssel, - sizeof(to->cssel)); - err |= copy_to_user_proc(&to->dataoff, &from->dataoff, - sizeof(to->dataoff)); - err |= copy_to_user_proc(&to->datasel, &from->datasel, - sizeof(to->datasel)); - err |= copy_to_user_proc(to->_st, from->_st, sizeof(to->_st)); - } - return(err); -} - -/* - * 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/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 1cbf95f6858a..0147227ce18d 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c @@ -1,189 +1,293 @@ /* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) + * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/signal.h" #include "linux/ptrace.h" -#include "asm/current.h" -#include "asm/ucontext.h" -#include "asm/uaccess.h" #include "asm/unistd.h" +#include "asm/uaccess.h" +#include "asm/ucontext.h" #include "frame_kern.h" -#include "sigcontext.h" -#include "registers.h" -#include "mode.h" - -#ifdef CONFIG_MODE_SKAS - #include "skas.h" -void copy_sc(union uml_pt_regs *regs, void *from) +void copy_sc(struct uml_pt_regs *regs, void *from) { struct sigcontext *sc = from; - REGS_GS(regs->skas.regs) = sc->gs; - REGS_FS(regs->skas.regs) = sc->fs; - REGS_ES(regs->skas.regs) = sc->es; - REGS_DS(regs->skas.regs) = sc->ds; - REGS_EDI(regs->skas.regs) = sc->edi; - REGS_ESI(regs->skas.regs) = sc->esi; - REGS_EBP(regs->skas.regs) = sc->ebp; - REGS_SP(regs->skas.regs) = sc->esp; - REGS_EBX(regs->skas.regs) = sc->ebx; - REGS_EDX(regs->skas.regs) = sc->edx; - REGS_ECX(regs->skas.regs) = sc->ecx; - REGS_EAX(regs->skas.regs) = sc->eax; - REGS_IP(regs->skas.regs) = sc->eip; - REGS_CS(regs->skas.regs) = sc->cs; - REGS_EFLAGS(regs->skas.regs) = sc->eflags; - REGS_SS(regs->skas.regs) = sc->ss; + REGS_GS(regs->gp) = sc->gs; + REGS_FS(regs->gp) = sc->fs; + REGS_ES(regs->gp) = sc->es; + REGS_DS(regs->gp) = sc->ds; + REGS_EDI(regs->gp) = sc->edi; + REGS_ESI(regs->gp) = sc->esi; + REGS_EBP(regs->gp) = sc->ebp; + REGS_SP(regs->gp) = sc->esp; + REGS_EBX(regs->gp) = sc->ebx; + REGS_EDX(regs->gp) = sc->edx; + REGS_ECX(regs->gp) = sc->ecx; + REGS_EAX(regs->gp) = sc->eax; + REGS_IP(regs->gp) = sc->eip; + REGS_CS(regs->gp) = sc->cs; + REGS_EFLAGS(regs->gp) = sc->eflags; + REGS_SS(regs->gp) = sc->ss; } -static int copy_sc_from_user_skas(struct pt_regs *regs, - struct sigcontext __user *from) +/* + * FPU tag word conversions. + */ + +static inline unsigned short twd_i387_to_fxsr(unsigned short twd) { - struct sigcontext sc; - unsigned long fpregs[HOST_FP_SIZE]; - int err; + unsigned int tmp; /* to avoid 16 bit prefixes in the code */ + + /* Transform each pair of bits into 01 (valid) or 00 (empty) */ + tmp = ~twd; + tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ + /* and move the valid bits to the lower byte. */ + tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ + tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ + tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ + return tmp; +} - err = copy_from_user(&sc, from, sizeof(sc)); - err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs)); - if(err) - return err; +static inline unsigned long twd_fxsr_to_i387(struct user_fxsr_struct *fxsave) +{ + struct _fpxreg *st = NULL; + unsigned long twd = (unsigned long) fxsave->twd; + unsigned long tag; + unsigned long ret = 0xffff0000; + int i; + +#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16); + + for (i = 0; i < 8; i++) { + if (twd & 0x1) { + st = (struct _fpxreg *) FPREG_ADDR(fxsave, i); + + switch (st->exponent & 0x7fff) { + case 0x7fff: + tag = 2; /* Special */ + break; + case 0x0000: + if ( !st->significand[0] && + !st->significand[1] && + !st->significand[2] && + !st->significand[3] ) { + tag = 1; /* Zero */ + } else { + tag = 2; /* Special */ + } + break; + default: + if (st->significand[3] & 0x8000) { + tag = 0; /* Valid */ + } else { + tag = 2; /* Special */ + } + break; + } + } else { + tag = 3; /* Empty */ + } + ret |= (tag << (2 * i)); + twd = twd >> 1; + } + return ret; +} - copy_sc(®s->regs, &sc); +static int convert_fxsr_to_user(struct _fpstate __user *buf, + struct user_fxsr_struct *fxsave) +{ + unsigned long env[7]; + struct _fpreg __user *to; + struct _fpxreg *from; + int i; + + env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul; + env[1] = (unsigned long)fxsave->swd | 0xffff0000ul; + env[2] = twd_fxsr_to_i387(fxsave); + env[3] = fxsave->fip; + env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16); + env[5] = fxsave->foo; + env[6] = fxsave->fos; + + if (__copy_to_user(buf, env, 7 * sizeof(unsigned long))) + return 1; - err = restore_fp_registers(userspace_pid[0], fpregs); - if(err < 0) { - printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, " - "errno = %d\n", -err); - return err; - } + to = &buf->_st[0]; + from = (struct _fpxreg *) &fxsave->st_space[0]; + for (i = 0; i < 8; i++, to++, from++) { + unsigned long __user *t = (unsigned long __user *)to; + unsigned long *f = (unsigned long *)from; + if (__put_user(*f, t) || + __put_user(*(f + 1), t + 1) || + __put_user(from->exponent, &to->exponent)) + return 1; + } return 0; } -int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp, - struct pt_regs *regs, unsigned long sp) +static int convert_fxsr_from_user(struct user_fxsr_struct *fxsave, + struct _fpstate __user *buf) { - struct sigcontext sc; - unsigned long fpregs[HOST_FP_SIZE]; - struct faultinfo * fi = ¤t->thread.arch.faultinfo; - int err; + unsigned long env[7]; + struct _fpxreg *to; + struct _fpreg __user *from; + int i; - sc.gs = REGS_GS(regs->regs.skas.regs); - sc.fs = REGS_FS(regs->regs.skas.regs); - sc.es = REGS_ES(regs->regs.skas.regs); - sc.ds = REGS_DS(regs->regs.skas.regs); - sc.edi = REGS_EDI(regs->regs.skas.regs); - sc.esi = REGS_ESI(regs->regs.skas.regs); - sc.ebp = REGS_EBP(regs->regs.skas.regs); - sc.esp = sp; - sc.ebx = REGS_EBX(regs->regs.skas.regs); - sc.edx = REGS_EDX(regs->regs.skas.regs); - sc.ecx = REGS_ECX(regs->regs.skas.regs); - sc.eax = REGS_EAX(regs->regs.skas.regs); - sc.eip = REGS_IP(regs->regs.skas.regs); - sc.cs = REGS_CS(regs->regs.skas.regs); - sc.eflags = REGS_EFLAGS(regs->regs.skas.regs); - sc.esp_at_signal = regs->regs.skas.regs[UESP]; - sc.ss = regs->regs.skas.regs[SS]; - sc.cr2 = fi->cr2; - sc.err = fi->error_code; - sc.trapno = fi->trap_no; - - err = save_fp_registers(userspace_pid[0], fpregs); - if(err < 0){ - printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, " - "errno = %d\n", err); + if (copy_from_user( env, buf, 7 * sizeof(long))) return 1; - } - to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); - sc.fpstate = to_fp; - if(err) - return err; - - return copy_to_user(to, &sc, sizeof(sc)) || - copy_to_user(to_fp, fpregs, sizeof(fpregs)); + fxsave->cwd = (unsigned short)(env[0] & 0xffff); + fxsave->swd = (unsigned short)(env[1] & 0xffff); + fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff)); + fxsave->fip = env[3]; + fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16); + fxsave->fcs = (env[4] & 0xffff); + fxsave->foo = env[5]; + fxsave->fos = env[6]; + + to = (struct _fpxreg *) &fxsave->st_space[0]; + from = &buf->_st[0]; + for (i = 0; i < 8; i++, to++, from++) { + unsigned long *t = (unsigned long *)to; + unsigned long __user *f = (unsigned long __user *)from; + + if (__get_user(*t, f) || + __get_user(*(t + 1), f + 1) || + __get_user(to->exponent, &from->exponent)) + return 1; + } + return 0; } -#endif -#ifdef CONFIG_MODE_TT +extern int have_fpx_regs; -/* These copy a sigcontext to/from userspace. They copy the fpstate pointer, - * blowing away the old, good one. So, that value is saved, and then restored - * after the sigcontext copy. In copy_from, the variable holding the saved - * fpstate pointer, and the sigcontext that it should be restored to are both - * in the kernel, so we can just restore using an assignment. In copy_to, the - * saved pointer is in the kernel, but the sigcontext is in userspace, so we - * copy_to_user it. - */ -int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from, - int fpsize) +static int copy_sc_from_user(struct pt_regs *regs, + struct sigcontext __user *from) { - struct _fpstate *to_fp; - struct _fpstate __user *from_fp; - unsigned long sigs; + struct sigcontext sc; int err; - to_fp = to->fpstate; - sigs = to->oldmask; - err = copy_from_user(to, from, sizeof(*to)); - from_fp = to->fpstate; - to->oldmask = sigs; - to->fpstate = to_fp; - if(to_fp != NULL) - err |= copy_from_user(to_fp, from_fp, fpsize); - return err; + err = copy_from_user(&sc, from, sizeof(sc)); + if (err) + return err; + + copy_sc(®s->regs, &sc); + if (have_fpx_regs) { + struct user_fxsr_struct fpx; + + err = copy_from_user(&fpx, &sc.fpstate->_fxsr_env[0], + sizeof(struct user_fxsr_struct)); + if (err) + return 1; + + err = convert_fxsr_from_user(&fpx, sc.fpstate); + if (err) + return 1; + + err = restore_fpx_registers(userspace_pid[current_thread->cpu], + (unsigned long *) &fpx); + if (err < 0) { + printk(KERN_ERR "copy_sc_from_user - " + "restore_fpx_registers failed, errno = %d\n", + -err); + return 1; + } + } + else { + struct user_i387_struct fp; + + err = copy_from_user(&fp, sc.fpstate, + sizeof(struct user_i387_struct)); + if (err) + return 1; + + err = restore_fp_registers(userspace_pid[current_thread->cpu], + (unsigned long *) &fp); + if (err < 0) { + printk(KERN_ERR "copy_sc_from_user - " + "restore_fp_registers failed, errno = %d\n", + -err); + return 1; + } + } + + return 0; } -int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp, - struct sigcontext *from, int fpsize, unsigned long sp) +static int copy_sc_to_user(struct sigcontext __user *to, + struct _fpstate __user *to_fp, struct pt_regs *regs, + unsigned long sp) { - struct _fpstate __user *to_fp; - struct _fpstate *from_fp; + struct sigcontext sc; + struct faultinfo * fi = ¤t->thread.arch.faultinfo; int err; - to_fp = (fp ? fp : (struct _fpstate __user *) (to + 1)); - from_fp = from->fpstate; - err = copy_to_user(to, from, sizeof(*to)); + sc.gs = REGS_GS(regs->regs.gp); + sc.fs = REGS_FS(regs->regs.gp); + sc.es = REGS_ES(regs->regs.gp); + sc.ds = REGS_DS(regs->regs.gp); + sc.edi = REGS_EDI(regs->regs.gp); + sc.esi = REGS_ESI(regs->regs.gp); + sc.ebp = REGS_EBP(regs->regs.gp); + sc.esp = sp; + sc.ebx = REGS_EBX(regs->regs.gp); + sc.edx = REGS_EDX(regs->regs.gp); + sc.ecx = REGS_ECX(regs->regs.gp); + sc.eax = REGS_EAX(regs->regs.gp); + sc.eip = REGS_IP(regs->regs.gp); + sc.cs = REGS_CS(regs->regs.gp); + sc.eflags = REGS_EFLAGS(regs->regs.gp); + sc.esp_at_signal = regs->regs.gp[UESP]; + sc.ss = regs->regs.gp[SS]; + sc.cr2 = fi->cr2; + sc.err = fi->error_code; + sc.trapno = fi->trap_no; - /* The SP in the sigcontext is the updated one for the signal - * delivery. The sp passed in is the original, and this needs - * to be restored, so we stick it in separately. - */ - err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp)); + to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); + sc.fpstate = to_fp; - if(from_fp != NULL){ - err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); - err |= copy_to_user(to_fp, from_fp, fpsize); + if (have_fpx_regs) { + struct user_fxsr_struct fpx; + + err = save_fpx_registers(userspace_pid[current_thread->cpu], + (unsigned long *) &fpx); + if (err < 0){ + printk(KERN_ERR "copy_sc_to_user - save_fpx_registers " + "failed, errno = %d\n", err); + return 1; + } + + err = convert_fxsr_to_user(to_fp, &fpx); + if (err) + return 1; + + err |= __put_user(fpx.swd, &to_fp->status); + err |= __put_user(X86_FXSR_MAGIC, &to_fp->magic); + if (err) + return 1; + + if (copy_to_user(&to_fp->_fxsr_env[0], &fpx, + sizeof(struct user_fxsr_struct))) + return 1; } - return err; -} -#endif - -static int copy_sc_from_user(struct pt_regs *to, void __user *from) -{ - int ret; + else { + struct user_i387_struct fp; - ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, - sizeof(struct _fpstate)), - copy_sc_from_user_skas(to, from)); - return ret; -} + err = save_fp_registers(userspace_pid[current_thread->cpu], + (unsigned long *) &fp); + if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct))) + return 1; + } -static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp, - struct pt_regs *from, unsigned long sp) -{ - return CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), - sizeof(*fp), sp), - copy_sc_to_user_skas(to, fp, from, sp)); + return copy_to_user(to, &sc, sizeof(sc)); } -static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp, - sigset_t *set, unsigned long sp) +static int copy_ucontext_to_user(struct ucontext __user *uc, + struct _fpstate __user *fp, sigset_t *set, + unsigned long sp) { int err = 0; @@ -233,7 +337,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig, return 1; restorer = frame->retcode; - if(ka->sa.sa_flags & SA_RESTORER) + if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; /* Update SP now because the page fault handler refuses to extend @@ -265,7 +369,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig, err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2)); err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); - if(err) + if (err) goto err; PT_REGS_SP(regs) = (unsigned long) frame; @@ -298,7 +402,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, return 1; restorer = frame->retcode; - if(ka->sa.sa_flags & SA_RESTORER) + if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; /* See comment above about why this is here */ @@ -323,7 +427,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1)); err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); - if(err) + if (err) goto err; PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; @@ -350,8 +454,8 @@ long sys_sigreturn(struct pt_regs regs) unsigned long __user *extramask = frame->extramask; int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); - if(copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) || - copy_from_user(&set.sig[1], extramask, sig_size)) + if (copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) || + copy_from_user(&set.sig[1], extramask, sig_size)) goto segfault; sigdelsetmask(&set, ~_BLOCKABLE); @@ -361,7 +465,7 @@ long sys_sigreturn(struct pt_regs regs) recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if(copy_sc_from_user(¤t->thread.regs, sc)) + if (copy_sc_from_user(¤t->thread.regs, sc)) goto segfault; /* Avoid ERESTART handling */ @@ -376,12 +480,13 @@ long sys_sigreturn(struct pt_regs regs) long sys_rt_sigreturn(struct pt_regs regs) { unsigned long sp = PT_REGS_SP(¤t->thread.regs); - struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (sp - 4); + struct rt_sigframe __user *frame = + (struct rt_sigframe __user *) (sp - 4); sigset_t set; struct ucontext __user *uc = &frame->uc; int sig_size = _NSIG_WORDS * sizeof(unsigned long); - if(copy_from_user(&set, &uc->uc_sigmask, sig_size)) + if (copy_from_user(&set, &uc->uc_sigmask, sig_size)) goto segfault; sigdelsetmask(&set, ~_BLOCKABLE); @@ -391,7 +496,7 @@ long sys_rt_sigreturn(struct pt_regs regs) recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if(copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) + if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) goto segfault; /* Avoid ERESTART handling */ diff --git a/arch/um/sys-i386/stub.S b/arch/um/sys-i386/stub.S index 6a70d9ab5c29..e730772c401b 100644 --- a/arch/um/sys-i386/stub.S +++ b/arch/um/sys-i386/stub.S @@ -1,4 +1,5 @@ #include "uml-config.h" +#include "as-layout.h" .globl syscall_stub .section .__syscall_stub, "x" @@ -6,7 +7,7 @@ .globl batch_syscall_stub batch_syscall_stub: /* load pointer to first operation */ - mov $(UML_CONFIG_STUB_DATA+8), %esp + mov $(ASM_STUB_DATA+8), %esp again: /* load length of additional data */ @@ -14,12 +15,12 @@ again: /* if(length == 0) : end of list */ /* write possible 0 to header */ - mov %eax, UML_CONFIG_STUB_DATA+4 + mov %eax, ASM_STUB_DATA+4 cmpl $0, %eax jz done /* save current pointer */ - mov %esp, UML_CONFIG_STUB_DATA+4 + mov %esp, ASM_STUB_DATA+4 /* skip additional data */ add %eax, %esp @@ -45,7 +46,7 @@ again: done: /* save return value */ - mov %eax, UML_CONFIG_STUB_DATA + mov %eax, ASM_STUB_DATA /* stop */ int3 diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c index 2355dc19c46c..b3999cb76bfd 100644 --- a/arch/um/sys-i386/stub_segv.c +++ b/arch/um/sys-i386/stub_segv.c @@ -6,6 +6,7 @@ #include <signal.h> #include <sys/select.h> /* The only way I can see to get sigset_t */ #include <asm/unistd.h> +#include "as-layout.h" #include "uml-config.h" #include "sysdep/stub.h" #include "sysdep/sigcontext.h" @@ -17,8 +18,7 @@ stub_segv_handler(int sig) struct sigcontext *sc = (struct sigcontext *) (&sig + 1); int pid; - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), - sc); + GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc); pid = stub_syscall0(__NR_getpid); stub_syscall2(__NR_kill, pid, SIGUSR1); diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c index fea8e5e15cc4..b02266ab5c55 100644 --- a/arch/um/sys-i386/tls.c +++ b/arch/um/sys-i386/tls.c @@ -3,25 +3,12 @@ * Licensed under the GPL */ -#include "linux/kernel.h" +#include "linux/percpu.h" #include "linux/sched.h" -#include "linux/slab.h" -#include "linux/types.h" #include "asm/uaccess.h" -#include "asm/ptrace.h" -#include "asm/segment.h" -#include "asm/smp.h" -#include "asm/desc.h" -#include "choose-mode.h" -#include "kern.h" -#include "kern_util.h" -#include "mode_kern.h" #include "os.h" -#include "mode.h" - -#ifdef CONFIG_MODE_SKAS #include "skas.h" -#endif +#include "sysdep/tls.h" /* * If needed we can detect when it's uninitialized. @@ -31,8 +18,7 @@ static int host_supports_tls = -1; int host_gdt_entry_tls_min; -#ifdef CONFIG_MODE_SKAS -int do_set_thread_area_skas(struct user_desc *info) +int do_set_thread_area(struct user_desc *info) { int ret; u32 cpu; @@ -43,7 +29,7 @@ int do_set_thread_area_skas(struct user_desc *info) return ret; } -int do_get_thread_area_skas(struct user_desc *info) +int do_get_thread_area(struct user_desc *info) { int ret; u32 cpu; @@ -53,7 +39,6 @@ int do_get_thread_area_skas(struct user_desc *info) put_cpu(); return ret; } -#endif /* * sys_get_thread_area: get a yet unused TLS descriptor index. @@ -82,7 +67,8 @@ static inline void clear_user_desc(struct user_desc* info) /* Postcondition: LDT_empty(info) returns true. */ memset(info, 0, sizeof(*info)); - /* Check the LDT_empty or the i386 sys_get_thread_area code - we obtain + /* + * Check the LDT_empty or the i386 sys_get_thread_area code - we obtain * indeed an empty user_desc. */ info->read_exec_only = 1; @@ -97,10 +83,13 @@ static int load_TLS(int flags, struct task_struct *to) int idx; for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) { - struct uml_tls_struct* curr = &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN]; + struct uml_tls_struct* curr = + &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN]; - /* Actually, now if it wasn't flushed it gets cleared and - * flushed to the host, which will clear it.*/ + /* + * Actually, now if it wasn't flushed it gets cleared and + * flushed to the host, which will clear it. + */ if (!curr->present) { if (!curr->flushed) { clear_user_desc(&curr->tls); @@ -124,7 +113,8 @@ out: return ret; } -/* Verify if we need to do a flush for the new process, i.e. if there are any +/* + * Verify if we need to do a flush for the new process, i.e. if there are any * present desc's, only if they haven't been flushed. */ static inline int needs_TLS_update(struct task_struct *task) @@ -133,10 +123,13 @@ static inline int needs_TLS_update(struct task_struct *task) int ret = 0; for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { - struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; + struct uml_tls_struct* curr = + &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; - /* Can't test curr->present, we may need to clear a descriptor - * which had a value. */ + /* + * Can't test curr->present, we may need to clear a descriptor + * which had a value. + */ if (curr->flushed) continue; ret = 1; @@ -145,7 +138,8 @@ static inline int needs_TLS_update(struct task_struct *task) return ret; } -/* On a newly forked process, the TLS descriptors haven't yet been flushed. So +/* + * On a newly forked process, the TLS descriptors haven't yet been flushed. So * we mark them as such and the first switch_to will do the job. */ void clear_flushed_tls(struct task_struct *task) @@ -153,10 +147,13 @@ void clear_flushed_tls(struct task_struct *task) int i; for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { - struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; + struct uml_tls_struct* curr = + &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; - /* Still correct to do this, if it wasn't present on the host it - * will remain as flushed as it was. */ + /* + * Still correct to do this, if it wasn't present on the host it + * will remain as flushed as it was. + */ if (!curr->present) continue; @@ -164,40 +161,33 @@ void clear_flushed_tls(struct task_struct *task) } } -/* In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a +/* + * In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a * common host process. So this is needed in SKAS0 too. * * However, if each thread had a different host process (and this was discussed * for SMP support) this won't be needed. * * And this will not need be used when (and if) we'll add support to the host - * SKAS patch. */ + * SKAS patch. + */ -int arch_switch_tls_skas(struct task_struct *from, struct task_struct *to) +int arch_switch_tls(struct task_struct *from, struct task_struct *to) { if (!host_supports_tls) return 0; - /* We have no need whatsoever to switch TLS for kernel threads; beyond + /* + * We have no need whatsoever to switch TLS for kernel threads; beyond * that, that would also result in us calling os_set_thread_area with - * userspace_pid[cpu] == 0, which gives an error. */ + * userspace_pid[cpu] == 0, which gives an error. + */ if (likely(to->mm)) return load_TLS(O_FORCE, to); return 0; } -int arch_switch_tls_tt(struct task_struct *from, struct task_struct *to) -{ - if (!host_supports_tls) - return 0; - - if (needs_TLS_update(to)) - return load_TLS(0, to); - - return 0; -} - static int set_tls_entry(struct task_struct* task, struct user_desc *info, int idx, int flushed) { @@ -251,17 +241,20 @@ static int get_tls_entry(struct task_struct* task, struct user_desc *info, int i *info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls; out: - /* Temporary debugging check, to make sure that things have been + /* + * Temporary debugging check, to make sure that things have been * flushed. This could be triggered if load_TLS() failed. */ - if (unlikely(task == current && !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) { + if (unlikely(task == current && + !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) { printk(KERN_ERR "get_tls_entry: task with pid %d got here " "without flushed TLS.", current->pid); } return 0; clear: - /* When the TLS entry has not been set, the values read to user in the + /* + * When the TLS entry has not been set, the values read to user in the * tls_array are 0 (because it's cleared at boot, see * arch/i386/kernel/head.S:cpu_gdt_table). Emulate that. */ @@ -293,7 +286,7 @@ asmlinkage int sys_set_thread_area(struct user_desc __user *user_desc) return -EFAULT; } - ret = CHOOSE_MODE_PROC(do_set_thread_area_tt, do_set_thread_area_skas, &info); + ret = do_set_thread_area(&info); if (ret) return ret; return set_tls_entry(current, &info, idx, 1); @@ -363,8 +356,10 @@ out: } -/* XXX: This part is probably common to i386 and x86-64. Don't create a common - * file for now, do that when implementing x86-64 support.*/ +/* + * XXX: This part is probably common to i386 and x86-64. Don't create a common + * file for now, do that when implementing x86-64 support. + */ static int __init __setup_host_supports_tls(void) { check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min); diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c deleted file mode 100644 index 1b0ad0e4adcd..000000000000 --- a/arch/um/sys-i386/unmap.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include <linux/mman.h> -#include <asm/unistd.h> - -static int errno; - -static inline _syscall2(int,munmap,void *,start,size_t,len) -static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) -int switcheroo(int fd, int prot, void *from, void *to, int size) -{ - if(munmap(to, size) < 0){ - return(-1); - } - if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ - return(-1); - } - if(munmap(from, size) < 0){ - return(-1); - } - return(0); -} diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c index 29118cf5ff25..514241526a1b 100644 --- a/arch/um/sys-i386/user-offsets.c +++ b/arch/um/sys-i386/user-offsets.c @@ -2,9 +2,9 @@ #include <stddef.h> #include <signal.h> #include <sys/poll.h> +#include <sys/user.h> #include <sys/mman.h> #include <asm/ptrace.h> -#include <asm/user.h> #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -48,8 +48,8 @@ void foo(void) OFFSET(HOST_SC_FP_ST, _fpstate, _st); OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env); - DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_i387_struct)); - DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fxsr_struct)); + DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct)); + DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fpxregs_struct)); DEFINE(HOST_IP, EIP); DEFINE(HOST_SP, UESP); diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index e446a9916fd7..3c22de532088 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -5,27 +5,22 @@ # obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ - setjmp.o sigcontext.o signal.o syscalls.o syscall_table.o sysrq.o \ - ksyms.o tls.o + setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \ + sysrq.o ksyms.o tls.o -obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o obj-$(CONFIG_MODULES) += um_module.o -subarch-obj-y = lib/bitops.o lib/csum-partial.o lib/memcpy.o lib/thunk.o -subarch-obj-$(CONFIG_MODULES) += kernel/module.o +subarch-obj-y = lib/bitops_64.o lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o +subarch-obj-$(CONFIG_MODULES) += kernel/module_64.o ldt-y = ../sys-i386/ldt.o -USER_OBJS := ptrace_user.o sigcontext.o +USER_OBJS := ptrace_user.o USER_OBJS += user-offsets.s extra-y += user-offsets.s -extra-$(CONFIG_MODE_TT) += unmap.o - UNPROFILE_OBJS := stub_segv.o CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) include arch/um/scripts/Makefile.rules - -$(obj)/unmap.%: _c_flags = $(call unprofile,$(KBUILD_CFLAGS)) diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c index 095478890371..506b6765bbcb 100644 --- a/arch/um/sys-x86_64/bugs.c +++ b/arch/um/sys-x86_64/bugs.c @@ -14,7 +14,7 @@ void arch_check_bugs(void) { } -int arch_handle_signal(int sig, union uml_pt_regs *regs) +int arch_handle_signal(int sig, struct uml_pt_regs *regs) { return 0; } diff --git a/arch/um/sys-x86_64/fault.c b/arch/um/sys-x86_64/fault.c index 4636b1465b6c..ce85117fc64e 100644 --- a/arch/um/sys-x86_64/fault.c +++ b/arch/um/sys-x86_64/fault.c @@ -14,14 +14,15 @@ struct exception_table_entry }; const struct exception_table_entry *search_exception_tables(unsigned long add); -int arch_fixup(unsigned long address, union uml_pt_regs *regs) + +int arch_fixup(unsigned long address, struct uml_pt_regs *regs) { const struct exception_table_entry *fixup; fixup = search_exception_tables(address); - if(fixup != 0){ + if (fixup != 0) { UPT_IP(regs) = fixup->fixup; - return(1); + return 1; } - return(0); + return 0; } diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index 1970d78aa528..a3cfeed17af4 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c @@ -1,5 +1,6 @@ /* * Copyright 2003 PathScale, Inc. + * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * * Licensed under the GPL */ @@ -12,17 +13,10 @@ #include <asm/uaccess.h> #include <asm/elf.h> -/* XXX x86_64 */ -unsigned long not_ss; -unsigned long not_ds; -unsigned long not_es; - -#define SC_SS(r) (not_ss) -#define SC_DS(r) (not_ds) -#define SC_ES(r) (not_es) - -/* determines which flags the user has access to. */ -/* 1 = access 0 = no access */ +/* + * determines which flags the user has access to. + * 1 = access 0 = no access + */ #define FLAG_MASK 0x44dd5UL int putreg(struct task_struct *child, int regno, unsigned long value) @@ -66,20 +60,21 @@ int putreg(struct task_struct *child, int regno, unsigned long value) int poke_user(struct task_struct *child, long addr, long data) { - if ((addr & 3) || addr < 0) - return -EIO; - - if (addr < MAX_REG_OFFSET) - return putreg(child, addr, data); - else if((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))){ - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - if((addr == 4) || (addr == 5)) return -EIO; - child->thread.arch.debugregs[addr] = data; - return 0; - } - return -EIO; + if ((addr & 3) || addr < 0) + return -EIO; + + if (addr < MAX_REG_OFFSET) + return putreg(child, addr, data); + else if ((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))){ + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + if ((addr == 4) || (addr == 5)) + return -EIO; + child->thread.arch.debugregs[addr] = data; + return 0; + } + return -EIO; } unsigned long getreg(struct task_struct *child, int regno) @@ -107,29 +102,22 @@ unsigned long getreg(struct task_struct *child, int regno) int peek_user(struct task_struct *child, long addr, long data) { /* read the word at location addr in the USER area. */ - unsigned long tmp; - - if ((addr & 3) || addr < 0) - return -EIO; - - tmp = 0; /* Default return condition */ - if(addr < MAX_REG_OFFSET){ - tmp = getreg(child, addr); - } - else if((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))){ - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - tmp = child->thread.arch.debugregs[addr]; - } - return put_user(tmp, (unsigned long *) data); -} + unsigned long tmp; -void arch_switch(void) -{ -/* XXX - printk("arch_switch\n"); -*/ + if ((addr & 3) || addr < 0) + return -EIO; + + tmp = 0; /* Default return condition */ + if (addr < MAX_REG_OFFSET){ + tmp = getreg(child, addr); + } + else if ((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))){ + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + tmp = child->thread.arch.debugregs[addr]; + } + return put_user(tmp, (unsigned long *) data); } /* XXX Mostly copied from sys-i386 */ @@ -139,54 +127,68 @@ int is_syscall(unsigned long addr) int n; n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); - if(n){ + if (n){ /* access_process_vm() grants access to vsyscall and stub, * while copy_from_user doesn't. Maybe access_process_vm is * slow, but that doesn't matter, since it will be called only * in case of singlestepping, if copy_from_user failed. */ n = access_process_vm(current, addr, &instr, sizeof(instr), 0); - if(n != sizeof(instr)) { + if (n != sizeof(instr)) { printk("is_syscall : failed to read instruction from " "0x%lx\n", addr); - return(1); + return 1; } } /* sysenter */ - return(instr == 0x050f); + return instr == 0x050f; } -int get_fpregs(unsigned long buf, struct task_struct *child) +int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { - panic("get_fpregs"); - return(0); -} + int err, n, cpu = ((struct thread_info *) child->stack)->cpu; + long fpregs[HOST_FP_SIZE]; -int set_fpregs(unsigned long buf, struct task_struct *child) -{ - panic("set_fpregs"); - return(0); + BUG_ON(sizeof(*buf) != sizeof(fpregs)); + err = save_fp_registers(userspace_pid[cpu], fpregs); + if (err) + return err; + + n = copy_to_user((void *) buf, fpregs, sizeof(fpregs)); + if(n > 0) + return -EFAULT; + + return n; } -int get_fpxregs(unsigned long buf, struct task_struct *tsk) +int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { - panic("get_fpxregs"); - return(0); + int n, cpu = ((struct thread_info *) child->stack)->cpu; + long fpregs[HOST_FP_SIZE]; + + BUG_ON(sizeof(*buf) != sizeof(fpregs)); + n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs)); + if (n > 0) + return -EFAULT; + + return restore_fp_registers(userspace_pid[cpu], fpregs); } -int set_fpxregs(unsigned long buf, struct task_struct *tsk) +long subarch_ptrace(struct task_struct *child, long request, long addr, + long data) { - panic("set_fxpregs"); - return(0); -} + int ret = -EIO; -/* - * 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: - */ + switch (request) { + case PTRACE_GETFPXREGS: /* Get the child FPU state. */ + ret = get_fpregs((struct user_i387_struct __user *) data, + child); + break; + case PTRACE_SETFPXREGS: /* Set the child FPU state. */ + ret = set_fpregs((struct user_i387_struct __user *) data, + child); + break; + } + + return ret; +} diff --git a/arch/um/sys-x86_64/sigcontext.c b/arch/um/sys-x86_64/sigcontext.c deleted file mode 100644 index c88e64def6f2..000000000000 --- a/arch/um/sys-x86_64/sigcontext.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include <stdio.h> -#include <string.h> -#include <signal.h> -#include "user.h" - -void sc_to_sc(void *to_ptr, void *from_ptr) -{ - struct sigcontext *to = to_ptr, *from = from_ptr; - int size = sizeof(*to); /* + sizeof(struct _fpstate); */ - - memcpy(to, from, size); - if(from->fpstate != NULL) - to->fpstate = (struct _fpstate *) (to + 1); - - to->fpstate = NULL; -} - -unsigned long *sc_sigmask(void *sc_ptr) -{ - struct sigcontext *sc = sc_ptr; - - return(&sc->oldmask); -} - -/* 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/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index fe8ec04d35bb..1778d33808f4 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -1,111 +1,121 @@ /* * Copyright (C) 2003 PathScale, Inc. + * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#include "linux/stddef.h" -#include "linux/errno.h" #include "linux/personality.h" #include "linux/ptrace.h" -#include "asm/current.h" +#include "asm/unistd.h" #include "asm/uaccess.h" -#include "asm/sigcontext.h" -#include "asm/ptrace.h" -#include "asm/arch/ucontext.h" -#include "choose-mode.h" -#include "sysdep/ptrace.h" +#include "asm/ucontext.h" #include "frame_kern.h" - -#ifdef CONFIG_MODE_SKAS - #include "skas.h" -void copy_sc(union uml_pt_regs *regs, void *from) +void copy_sc(struct uml_pt_regs *regs, void *from) { struct sigcontext *sc = from; -#define GETREG(regs, regno, sc, regname) \ - (regs)->skas.regs[(regno) / sizeof(unsigned long)] = (sc)->regname - - GETREG(regs, R8, sc, r8); - GETREG(regs, R9, sc, r9); - GETREG(regs, R10, sc, r10); - GETREG(regs, R11, sc, r11); - GETREG(regs, R12, sc, r12); - GETREG(regs, R13, sc, r13); - GETREG(regs, R14, sc, r14); - GETREG(regs, R15, sc, r15); - GETREG(regs, RDI, sc, rdi); - GETREG(regs, RSI, sc, rsi); - GETREG(regs, RBP, sc, rbp); - GETREG(regs, RBX, sc, rbx); - GETREG(regs, RDX, sc, rdx); - GETREG(regs, RAX, sc, rax); - GETREG(regs, RCX, sc, rcx); - GETREG(regs, RSP, sc, rsp); - GETREG(regs, RIP, sc, rip); - GETREG(regs, EFLAGS, sc, eflags); - GETREG(regs, CS, sc, cs); +#define GETREG(regs, regno, sc, regname) \ + (regs)->gp[(regno) / sizeof(unsigned long)] = (sc)->regname + + GETREG(regs, R8, sc, r8); + GETREG(regs, R9, sc, r9); + GETREG(regs, R10, sc, r10); + GETREG(regs, R11, sc, r11); + GETREG(regs, R12, sc, r12); + GETREG(regs, R13, sc, r13); + GETREG(regs, R14, sc, r14); + GETREG(regs, R15, sc, r15); + GETREG(regs, RDI, sc, rdi); + GETREG(regs, RSI, sc, rsi); + GETREG(regs, RBP, sc, rbp); + GETREG(regs, RBX, sc, rbx); + GETREG(regs, RDX, sc, rdx); + GETREG(regs, RAX, sc, rax); + GETREG(regs, RCX, sc, rcx); + GETREG(regs, RSP, sc, rsp); + GETREG(regs, RIP, sc, rip); + GETREG(regs, EFLAGS, sc, eflags); + GETREG(regs, CS, sc, cs); #undef GETREG } -static int copy_sc_from_user_skas(struct pt_regs *regs, - struct sigcontext __user *from) +static int copy_sc_from_user(struct pt_regs *regs, + struct sigcontext __user *from, + struct _fpstate __user *fpp) { - int err = 0; - -#define GETREG(regs, regno, sc, regname) \ - __get_user((regs)->regs.skas.regs[(regno) / sizeof(unsigned long)], \ - &(sc)->regname) - - err |= GETREG(regs, R8, from, r8); - err |= GETREG(regs, R9, from, r9); - err |= GETREG(regs, R10, from, r10); - err |= GETREG(regs, R11, from, r11); - err |= GETREG(regs, R12, from, r12); - err |= GETREG(regs, R13, from, r13); - err |= GETREG(regs, R14, from, r14); - err |= GETREG(regs, R15, from, r15); - err |= GETREG(regs, RDI, from, rdi); - err |= GETREG(regs, RSI, from, rsi); - err |= GETREG(regs, RBP, from, rbp); - err |= GETREG(regs, RBX, from, rbx); - err |= GETREG(regs, RDX, from, rdx); - err |= GETREG(regs, RAX, from, rax); - err |= GETREG(regs, RCX, from, rcx); - err |= GETREG(regs, RSP, from, rsp); - err |= GETREG(regs, RIP, from, rip); - err |= GETREG(regs, EFLAGS, from, eflags); - err |= GETREG(regs, CS, from, cs); + struct user_i387_struct fp; + int err = 0; + +#define GETREG(regs, regno, sc, regname) \ + __get_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \ + &(sc)->regname) + + err |= GETREG(regs, R8, from, r8); + err |= GETREG(regs, R9, from, r9); + err |= GETREG(regs, R10, from, r10); + err |= GETREG(regs, R11, from, r11); + err |= GETREG(regs, R12, from, r12); + err |= GETREG(regs, R13, from, r13); + err |= GETREG(regs, R14, from, r14); + err |= GETREG(regs, R15, from, r15); + err |= GETREG(regs, RDI, from, rdi); + err |= GETREG(regs, RSI, from, rsi); + err |= GETREG(regs, RBP, from, rbp); + err |= GETREG(regs, RBX, from, rbx); + err |= GETREG(regs, RDX, from, rdx); + err |= GETREG(regs, RAX, from, rax); + err |= GETREG(regs, RCX, from, rcx); + err |= GETREG(regs, RSP, from, rsp); + err |= GETREG(regs, RIP, from, rip); + err |= GETREG(regs, EFLAGS, from, eflags); + err |= GETREG(regs, CS, from, cs); + if (err) + return 1; #undef GETREG - return err; + err = copy_from_user(&fp, fpp, sizeof(struct user_i387_struct)); + if (err) + return 1; + + err = restore_fp_registers(userspace_pid[current_thread->cpu], + (unsigned long *) &fp); + if (err < 0) { + printk(KERN_ERR "copy_sc_from_user - " + "restore_fp_registers failed, errno = %d\n", + -err); + return 1; + } + + return 0; } -int copy_sc_to_user_skas(struct sigcontext __user *to, - struct _fpstate __user *to_fp, - struct pt_regs *regs, unsigned long mask, - unsigned long sp) +static int copy_sc_to_user(struct sigcontext __user *to, + struct _fpstate __user *to_fp, struct pt_regs *regs, + unsigned long mask, unsigned long sp) { - struct faultinfo * fi = ¤t->thread.arch.faultinfo; + struct faultinfo * fi = ¤t->thread.arch.faultinfo; + struct user_i387_struct fp; int err = 0; err |= __put_user(0, &to->gs); err |= __put_user(0, &to->fs); -#define PUTREG(regs, regno, sc, regname) \ - __put_user((regs)->regs.skas.regs[(regno) / sizeof(unsigned long)], \ - &(sc)->regname) +#define PUTREG(regs, regno, sc, regname) \ + __put_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \ + &(sc)->regname) err |= PUTREG(regs, RDI, to, rdi); err |= PUTREG(regs, RSI, to, rsi); err |= PUTREG(regs, RBP, to, rbp); - /* Must use orignal RSP, which is passed in, rather than what's in - * the pt_regs, because that's already been updated to point at the - * signal frame. - */ + /* + * Must use orignal RSP, which is passed in, rather than what's in + * the pt_regs, because that's already been updated to point at the + * signal frame. + */ err |= __put_user(sp, &to->rsp); err |= PUTREG(regs, RBX, to, rbx); err |= PUTREG(regs, RDX, to, rdx); @@ -121,91 +131,38 @@ int copy_sc_to_user_skas(struct sigcontext __user *to, err |= PUTREG(regs, R15, to, r15); err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */ - err |= __put_user(fi->cr2, &to->cr2); - err |= __put_user(fi->error_code, &to->err); - err |= __put_user(fi->trap_no, &to->trapno); + err |= __put_user(fi->cr2, &to->cr2); + err |= __put_user(fi->error_code, &to->err); + err |= __put_user(fi->trap_no, &to->trapno); err |= PUTREG(regs, RIP, to, rip); err |= PUTREG(regs, EFLAGS, to, eflags); #undef PUTREG err |= __put_user(mask, &to->oldmask); - - return(err); -} - -#endif - -#ifdef CONFIG_MODE_TT -int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from, - int fpsize) -{ - struct _fpstate *to_fp; - struct _fpstate __user *from_fp; - unsigned long sigs; - int err; - - to_fp = to->fpstate; - sigs = to->oldmask; - err = copy_from_user(to, from, sizeof(*to)); - from_fp = to->fpstate; - to->fpstate = to_fp; - to->oldmask = sigs; - if(to_fp != NULL) - err |= copy_from_user(to_fp, from_fp, fpsize); - return(err); -} - -int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp, - struct sigcontext *from, int fpsize, unsigned long sp) -{ - struct _fpstate __user *to_fp; - struct _fpstate *from_fp; - int err; - - to_fp = (fp ? fp : (struct _fpstate __user *) (to + 1)); - from_fp = from->fpstate; - err = copy_to_user(to, from, sizeof(*to)); - /* The SP in the sigcontext is the updated one for the signal - * delivery. The sp passed in is the original, and this needs - * to be restored, so we stick it in separately. - */ - err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp)); - - if(from_fp != NULL){ - err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); - err |= copy_to_user(to_fp, from_fp, fpsize); + if (err) + return 1; + + err = save_fp_registers(userspace_pid[current_thread->cpu], + (unsigned long *) &fp); + if (err < 0) { + printk(KERN_ERR "copy_sc_from_user - restore_fp_registers " + "failed, errno = %d\n", -err); + return 1; } - return err; -} -#endif - -static int copy_sc_from_user(struct pt_regs *to, void __user *from) -{ - int ret; - - ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, - sizeof(struct _fpstate)), - copy_sc_from_user_skas(to, from)); - return(ret); -} + if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct))) + return 1; -static int copy_sc_to_user(struct sigcontext __user *to, - struct _fpstate __user *fp, - struct pt_regs *from, unsigned long mask, - unsigned long sp) -{ - return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), - sizeof(*fp), sp), - copy_sc_to_user_skas(to, fp, from, mask, sp))); + return err; } struct rt_sigframe { - char __user *pretcode; - struct ucontext uc; - struct siginfo info; + char __user *pretcode; + struct ucontext uc; + struct siginfo info; + struct _fpstate fpstate; }; #define round_down(m, n) (((m) / (n)) * (n)) @@ -215,7 +172,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, siginfo_t *info, sigset_t *set) { struct rt_sigframe __user *frame; - struct _fpstate __user *fp = NULL; unsigned long save_sp = PT_REGS_RSP(regs); int err = 0; struct task_struct *me = current; @@ -223,15 +179,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, frame = (struct rt_sigframe __user *) round_down(stack_top - sizeof(struct rt_sigframe), 16); /* Subtract 128 for a red zone and 8 for proper alignment */ - frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8); - - if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) - goto out; + frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8); -#if 0 /* XXX */ - if (save_i387(fp) < 0) - err |= -1; -#endif if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto out; @@ -241,7 +190,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, goto out; } - /* Update SP now because the page fault handler refuses to extend + /* + * Update SP now because the page fault handler refuses to extend * the stack if the faulting address is too far below the current * SP, which frame now certainly is. If there's an error, the original * value is restored on the way out. @@ -258,9 +208,9 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, err |= __put_user(sas_ss_flags(save_sp), &frame->uc.uc_stack.ss_flags); err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= copy_sc_to_user(&frame->uc.uc_mcontext, fp, regs, set->sig[0], - save_sp); - err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate); + err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs, + set->sig[0], save_sp); + err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate); if (sizeof(*set) == 16) { __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); @@ -269,8 +219,10 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); - /* Set up to return from userspace. If provided, use a stub - already in userspace. */ + /* + * Set up to return from userspace. If provided, use a stub + * already in userspace. + */ /* x86-64 should always use SA_RESTORER. */ if (ka->sa.sa_flags & SA_RESTORER) err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); @@ -292,8 +244,10 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, /* In case the signal handler was declared without prototypes */ PT_REGS_RAX(regs) = 0; - /* This also works for non SA_SIGINFO handlers because they expect the - next argument after the signal number on the stack. */ + /* + * This also works for non SA_SIGINFO handlers because they expect the + * next argument after the signal number on the stack. + */ PT_REGS_RSI(regs) = (unsigned long) &frame->info; PT_REGS_RDX(regs) = (unsigned long) &frame->uc; PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler; @@ -313,7 +267,7 @@ long sys_rt_sigreturn(struct pt_regs *regs) struct ucontext __user *uc = &frame->uc; sigset_t set; - if(copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) + if (copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) goto segfault; sigdelsetmask(&set, ~_BLOCKABLE); @@ -323,24 +277,15 @@ long sys_rt_sigreturn(struct pt_regs *regs) recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if(copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) + if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext, + &frame->fpstate)) goto segfault; /* Avoid ERESTART handling */ PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return(PT_REGS_SYSCALL_RET(¤t->thread.regs)); + return PT_REGS_SYSCALL_RET(¤t->thread.regs); segfault: force_sig(SIGSEGV, current); return 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/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S index 03c279735784..4afe204a6af7 100644 --- a/arch/um/sys-x86_64/stub.S +++ b/arch/um/sys-x86_64/stub.S @@ -1,4 +1,5 @@ #include "uml-config.h" +#include "as-layout.h" .globl syscall_stub .section .__syscall_stub, "x" @@ -7,18 +8,18 @@ syscall_stub: /* We don't have 64-bit constants, so this constructs the address * we need. */ - movq $(UML_CONFIG_STUB_DATA >> 32), %rbx + movq $(ASM_STUB_DATA >> 32), %rbx salq $32, %rbx - movq $(UML_CONFIG_STUB_DATA & 0xffffffff), %rcx + movq $(ASM_STUB_DATA & 0xffffffff), %rcx or %rcx, %rbx movq %rax, (%rbx) int3 .globl batch_syscall_stub batch_syscall_stub: - mov $(UML_CONFIG_STUB_DATA >> 32), %rbx + mov $(ASM_STUB_DATA >> 32), %rbx sal $32, %rbx - mov $(UML_CONFIG_STUB_DATA & 0xffffffff), %rax + mov $(ASM_STUB_DATA & 0xffffffff), %rax or %rax, %rbx /* load pointer to first operation */ mov %rbx, %rsp diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c index 652fa34c2cd3..3afb590f0072 100644 --- a/arch/um/sys-x86_64/stub_segv.c +++ b/arch/um/sys-x86_64/stub_segv.c @@ -6,6 +6,7 @@ #include <stddef.h> #include <signal.h> #include <asm/unistd.h> +#include "as-layout.h" #include "uml-config.h" #include "sysdep/sigcontext.h" #include "sysdep/faultinfo.h" @@ -33,7 +34,7 @@ stub_segv_handler(int sig) int pid; __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :); - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), + GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), &uc->uc_mcontext); pid = stub_syscall0(__NR_getpid); diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c index b3f6350cac44..86f6b18410ee 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/um/sys-x86_64/syscalls.c @@ -1,70 +1,36 @@ /* + * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Copyright 2003 PathScale, Inc. * * Licensed under the GPL */ #include "linux/linkage.h" -#include "linux/slab.h" -#include "linux/shm.h" -#include "linux/utsname.h" #include "linux/personality.h" -#include "asm/uaccess.h" -#define __FRAME_OFFSETS -#include "asm/ptrace.h" -#include "asm/unistd.h" +#include "linux/utsname.h" #include "asm/prctl.h" /* XXX This should get the constants from libc */ -#include "choose-mode.h" -#include "kern.h" +#include "asm/uaccess.h" #include "os.h" asmlinkage long sys_uname64(struct new_utsname __user * name) { int err; + down_read(&uts_sem); err = copy_to_user(name, utsname(), sizeof (*name)); up_read(&uts_sem); + if (personality(current->personality) == PER_LINUX32) err |= copy_to_user(&name->machine, "i686", 5); - return err ? -EFAULT : 0; -} - -#ifdef CONFIG_MODE_TT -extern long arch_prctl(int code, unsigned long addr); - -static long arch_prctl_tt(int code, unsigned long addr) -{ - unsigned long tmp; - long ret; - - switch(code){ - case ARCH_SET_GS: - case ARCH_SET_FS: - ret = arch_prctl(code, addr); - break; - case ARCH_GET_FS: - case ARCH_GET_GS: - ret = arch_prctl(code, (unsigned long) &tmp); - if(!ret) - ret = put_user(tmp, (long __user *)addr); - break; - default: - ret = -EINVAL; - break; - } - return(ret); + return err ? -EFAULT : 0; } -#endif - -#ifdef CONFIG_MODE_SKAS -long arch_prctl_skas(struct task_struct *task, int code, - unsigned long __user *addr) +long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) { - unsigned long *ptr = addr, tmp; + unsigned long *ptr = addr, tmp; long ret; - int pid = task->mm->context.skas.id.u.pid; + int pid = task->mm->context.id.u.pid; /* * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to @@ -79,52 +45,50 @@ long arch_prctl_skas(struct task_struct *task, int code, * arch_prctl is run on the host, then the registers are read * back. */ - switch(code){ + switch (code) { case ARCH_SET_FS: case ARCH_SET_GS: - restore_registers(pid, ¤t->thread.regs.regs); - break; - case ARCH_GET_FS: - case ARCH_GET_GS: - /* - * With these two, we read to a local pointer and - * put_user it to the userspace pointer that we were - * given. If addr isn't valid (because it hasn't been - * faulted in or is just bogus), we want put_user to - * fault it in (or return -EFAULT) instead of having - * the host return -EFAULT. - */ - ptr = &tmp; - } + restore_registers(pid, ¤t->thread.regs.regs); + break; + case ARCH_GET_FS: + case ARCH_GET_GS: + /* + * With these two, we read to a local pointer and + * put_user it to the userspace pointer that we were + * given. If addr isn't valid (because it hasn't been + * faulted in or is just bogus), we want put_user to + * fault it in (or return -EFAULT) instead of having + * the host return -EFAULT. + */ + ptr = &tmp; + } - ret = os_arch_prctl(pid, code, ptr); - if(ret) - return ret; + ret = os_arch_prctl(pid, code, ptr); + if (ret) + return ret; - switch(code){ + switch (code) { case ARCH_SET_FS: current->thread.arch.fs = (unsigned long) ptr; save_registers(pid, ¤t->thread.regs.regs); break; case ARCH_SET_GS: - save_registers(pid, ¤t->thread.regs.regs); + save_registers(pid, ¤t->thread.regs.regs); break; case ARCH_GET_FS: ret = put_user(tmp, addr); - break; + break; case ARCH_GET_GS: ret = put_user(tmp, addr); - break; + break; } return ret; } -#endif long sys_arch_prctl(int code, unsigned long addr) { - return CHOOSE_MODE_PROC(arch_prctl_tt, arch_prctl_skas, current, code, - (unsigned long __user *) addr); + return arch_prctl(current, code, (unsigned long __user *) addr); } long sys_clone(unsigned long clone_flags, unsigned long newsp, @@ -141,10 +105,10 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp, return ret; } -void arch_switch_to_skas(struct task_struct *from, struct task_struct *to) +void arch_switch_to(struct task_struct *from, struct task_struct *to) { - if((to->thread.arch.fs == 0) || (to->mm == NULL)) - return; + if ((to->thread.arch.fs == 0) || (to->mm == NULL)) + return; - arch_prctl_skas(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs); + arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs); } diff --git a/arch/um/sys-x86_64/tls.c b/arch/um/sys-x86_64/tls.c index febbc94be25f..f7ba46200ecd 100644 --- a/arch/um/sys-x86_64/tls.c +++ b/arch/um/sys-x86_64/tls.c @@ -11,7 +11,7 @@ int arch_copy_tls(struct task_struct *t) * (which is argument 5, child_tid, of clone) so it can be set * during context switches. */ - t->thread.arch.fs = t->thread.regs.regs.skas.regs[R8 / sizeof(long)]; + t->thread.arch.fs = t->thread.regs.regs.gp[R8 / sizeof(long)]; - return 0; + return 0; } diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c deleted file mode 100644 index f4a4bffd8a18..000000000000 --- a/arch/um/sys-x86_64/unmap.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include <linux/mman.h> -#include <asm/unistd.h> - -static int errno; - -static inline _syscall2(int,munmap,void *,start,size_t,len) -static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) -int switcheroo(int fd, int prot, void *from, void *to, int size) -{ - if(munmap(to, size) < 0){ - return(-1); - } - if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ - return(-1); - } - if(munmap(from, size) < 0){ - return(-1); - } - return(0); -} diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c index 0d5fd764c21f..f1ef2a8dfbc6 100644 --- a/arch/um/sys-x86_64/user-offsets.c +++ b/arch/um/sys-x86_64/user-offsets.c @@ -3,17 +3,10 @@ #include <signal.h> #include <sys/poll.h> #include <sys/mman.h> +#include <sys/user.h> #define __FRAME_OFFSETS #include <asm/ptrace.h> #include <asm/types.h> -/* For some reason, x86_64 defines u64 and u32 only in <pci/types.h>, which I - * refuse to include here, even though they're used throughout the headers. - * These are used in asm/user.h, and that include can't be avoided because of - * the sizeof(struct user_regs_struct) below. - */ -typedef __u64 u64; -typedef __u32 u32; -#include <asm/user.h> #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) diff --git a/arch/v850/kernel/fpga85e2c.c b/arch/v850/kernel/fpga85e2c.c index 5c4923558a75..ab9cf16a85c8 100644 --- a/arch/v850/kernel/fpga85e2c.c +++ b/arch/v850/kernel/fpga85e2c.c @@ -160,5 +160,8 @@ static void make_reg_snap (int irq, void *dummy, struct pt_regs *regs) static int reg_snap_dev_id; static struct irqaction reg_snap_action = { - make_reg_snap, 0, CPU_MASK_NONE, "reg_snap", ®_snap_dev_id, 0 + .handler = make_reg_snap, + .mask = CPU_MASK_NONE, + .name = "reg_snap", + .dev_id = ®_snap_dev_id, }; diff --git a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c index f0905b03523b..d810c93fe665 100644 --- a/arch/v850/kernel/time.c +++ b/arch/v850/kernel/time.c @@ -92,12 +92,11 @@ static irqreturn_t timer_interrupt (int irq, void *dummy, struct pt_regs *regs) static int timer_dev_id; static struct irqaction timer_irqaction = { - timer_interrupt, - IRQF_DISABLED, - CPU_MASK_NONE, - "timer", - &timer_dev_id, - NULL + .handler = timer_interrupt, + .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, + .name = "timer", + .dev_id = &timer_dev_id, }; void time_init (void) diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32 index c624193740fd..7ff02063b858 100644 --- a/arch/x86/kernel/Makefile_32 +++ b/arch/x86/kernel/Makefile_32 @@ -7,7 +7,7 @@ extra-y := head_32.o init_task_32.o vmlinux.lds obj-y := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \ ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \ pci-dma_32.o i386_ksyms_32.o i387_32.o bootflag.o e820_32.o\ - quirks.o i8237.o topology.o alternative.o i8253_32.o tsc_32.o + quirks.o i8237.o topology.o alternative.o i8253.o tsc_32.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-y += cpu/ @@ -37,9 +37,9 @@ obj-$(CONFIG_EFI) += efi_32.o efi_stub_32.o obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o obj-$(CONFIG_VM86) += vm86_32.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -obj-$(CONFIG_HPET_TIMER) += hpet_32.o +obj-$(CONFIG_HPET_TIMER) += hpet.o obj-$(CONFIG_K8_NB) += k8.o -obj-$(CONFIG_MGEODE_LX) += geode_32.o +obj-$(CONFIG_MGEODE_LX) += geode_32.o mfgpt_32.o obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o obj-$(CONFIG_PARAVIRT) += paravirt_32.o diff --git a/arch/x86/kernel/Makefile_64 b/arch/x86/kernel/Makefile_64 index 3ab017a0a3b9..43da66213a47 100644 --- a/arch/x86/kernel/Makefile_64 +++ b/arch/x86/kernel/Makefile_64 @@ -8,8 +8,8 @@ obj-y := process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \ ptrace_64.o time_64.o ioport_64.o ldt_64.o setup_64.o i8259_64.o sys_x86_64.o \ x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \ setup64.o bootflag.o e820_64.o reboot_64.o quirks.o i8237.o \ - pci-dma_64.o pci-nommu_64.o alternative.o hpet_64.o tsc_64.o bugs_64.o \ - perfctr-watchdog.o + pci-dma_64.o pci-nommu_64.o alternative.o hpet.o tsc_64.o bugs_64.o \ + perfctr-watchdog.o i8253.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_X86_MCE) += mce_64.o therm_throt.o diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index bd72d94e713e..11b03d3c6fda 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -10,6 +10,7 @@ #include <asm/pgtable.h> #include <asm/mce.h> #include <asm/nmi.h> +#include <asm/vsyscall.h> #define MAX_PATCH_LEN (255-1) diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index 925758dbca0c..09b82093bc75 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c @@ -25,6 +25,7 @@ #include <linux/sysdev.h> #include <linux/module.h> #include <linux/ioport.h> +#include <linux/clockchips.h> #include <asm/atomic.h> #include <asm/smp.h> @@ -39,12 +40,9 @@ #include <asm/hpet.h> #include <asm/apic.h> -int apic_mapped; int apic_verbosity; -int apic_runs_main_timer; -int apic_calibrate_pmtmr __initdata; - -int disable_apic_timer __initdata; +int disable_apic_timer __cpuinitdata; +static int apic_calibrate_pmtmr __initdata; /* Local APIC timer works in C2? */ int local_apic_timer_c2_ok; @@ -56,14 +54,78 @@ static struct resource lapic_resource = { .flags = IORESOURCE_MEM | IORESOURCE_BUSY, }; +static unsigned int calibration_result; + +static int lapic_next_event(unsigned long delta, + struct clock_event_device *evt); +static void lapic_timer_setup(enum clock_event_mode mode, + struct clock_event_device *evt); + +static void lapic_timer_broadcast(cpumask_t mask); + +static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen); + +static struct clock_event_device lapic_clockevent = { + .name = "lapic", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT + | CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY, + .shift = 32, + .set_mode = lapic_timer_setup, + .set_next_event = lapic_next_event, + .broadcast = lapic_timer_broadcast, + .rating = 100, + .irq = -1, +}; +static DEFINE_PER_CPU(struct clock_event_device, lapic_events); + +static int lapic_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + apic_write(APIC_TMICT, delta); + return 0; +} + +static void lapic_timer_setup(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned long flags; + unsigned int v; + + /* Lapic used as dummy for broadcast ? */ + if (evt->features & CLOCK_EVT_FEAT_DUMMY) + return; + + local_irq_save(flags); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + case CLOCK_EVT_MODE_ONESHOT: + __setup_APIC_LVTT(calibration_result, + mode != CLOCK_EVT_MODE_PERIODIC, 1); + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + v = apic_read(APIC_LVTT); + v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); + apic_write(APIC_LVTT, v); + break; + case CLOCK_EVT_MODE_RESUME: + /* Nothing to do here */ + break; + } + + local_irq_restore(flags); +} + /* - * cpu_mask that denotes the CPUs that needs timer interrupt coming in as - * IPIs in place of local APIC timers + * Local APIC timer broadcast function */ -static cpumask_t timer_interrupt_broadcast_ipi_mask; - -/* Using APIC to generate smp_local_timer_interrupt? */ -int using_apic_timer __read_mostly = 0; +static void lapic_timer_broadcast(cpumask_t mask) +{ +#ifdef CONFIG_SMP + send_IPI_mask(mask, LOCAL_TIMER_VECTOR); +#endif +} static void apic_pm_activate(void); @@ -184,7 +246,10 @@ void disconnect_bsp_APIC(int virt_wire_setup) apic_write(APIC_SPIV, value); if (!virt_wire_setup) { - /* For LVT0 make it edge triggered, active high, external and enabled */ + /* + * For LVT0 make it edge triggered, active high, + * external and enabled + */ value = apic_read(APIC_LVT0); value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | @@ -420,10 +485,12 @@ void __cpuinit setup_local_APIC (void) value = apic_read(APIC_LVT0) & APIC_LVT_MASKED; if (!smp_processor_id() && !value) { value = APIC_DM_EXTINT; - apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", smp_processor_id()); + apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", + smp_processor_id()); } else { value = APIC_DM_EXTINT | APIC_LVT_MASKED; - apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", smp_processor_id()); + apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", + smp_processor_id()); } apic_write(APIC_LVT0, value); @@ -706,8 +773,8 @@ void __init init_apic_mappings(void) apic_phys = mp_lapic_addr; set_fixmap_nocache(FIX_APIC_BASE, apic_phys); - apic_mapped = 1; - apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys); + apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", + APIC_BASE, apic_phys); /* Put local APIC into the resource map. */ lapic_resource.start = apic_phys; @@ -730,12 +797,14 @@ void __init init_apic_mappings(void) if (smp_found_config) { ioapic_phys = mp_ioapics[i].mpc_apicaddr; } else { - ioapic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE); + ioapic_phys = (unsigned long) + alloc_bootmem_pages(PAGE_SIZE); ioapic_phys = __pa(ioapic_phys); } set_fixmap_nocache(idx, ioapic_phys); - apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n", - __fix_to_virt(idx), ioapic_phys); + apic_printk(APIC_VERBOSE, + "mapped IOAPIC to %016lx (%016lx)\n", + __fix_to_virt(idx), ioapic_phys); idx++; if (ioapic_res != NULL) { @@ -758,16 +827,14 @@ void __init init_apic_mappings(void) * P5 APIC double write bug. */ -#define APIC_DIVISOR 16 - -static void __setup_APIC_LVTT(unsigned int clocks) +static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) { unsigned int lvtt_value, tmp_value; - int cpu = smp_processor_id(); - lvtt_value = APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR; - - if (cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) + lvtt_value = LOCAL_TIMER_VECTOR; + if (!oneshot) + lvtt_value |= APIC_LVT_TIMER_PERIODIC; + if (!irqen) lvtt_value |= APIC_LVT_MASKED; apic_write(APIC_LVTT, lvtt_value); @@ -780,44 +847,18 @@ static void __setup_APIC_LVTT(unsigned int clocks) & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) | APIC_TDR_DIV_16); - apic_write(APIC_TMICT, clocks/APIC_DIVISOR); + if (!oneshot) + apic_write(APIC_TMICT, clocks); } -static void setup_APIC_timer(unsigned int clocks) +static void setup_APIC_timer(void) { - unsigned long flags; + struct clock_event_device *levt = &__get_cpu_var(lapic_events); - local_irq_save(flags); + memcpy(levt, &lapic_clockevent, sizeof(*levt)); + levt->cpumask = cpumask_of_cpu(smp_processor_id()); - /* wait for irq slice */ - if (hpet_address && hpet_use_timer) { - u32 trigger = hpet_readl(HPET_T0_CMP); - while (hpet_readl(HPET_T0_CMP) == trigger) - /* do nothing */ ; - } else { - int c1, c2; - outb_p(0x00, 0x43); - c2 = inb_p(0x40); - c2 |= inb_p(0x40) << 8; - do { - c1 = c2; - outb_p(0x00, 0x43); - c2 = inb_p(0x40); - c2 |= inb_p(0x40) << 8; - } while (c2 - c1 < 300); - } - __setup_APIC_LVTT(clocks); - /* Turn off PIT interrupt if we use APIC timer as main timer. - Only works with the PM timer right now - TBD fix it for HPET too. */ - if ((pmtmr_ioport != 0) && - smp_processor_id() == boot_cpu_id && - apic_runs_main_timer == 1 && - !cpu_isset(boot_cpu_id, timer_interrupt_broadcast_ipi_mask)) { - stop_timer_interrupt(); - apic_runs_main_timer++; - } - local_irq_restore(flags); + clockevents_register_device(levt); } /* @@ -835,17 +876,22 @@ static void setup_APIC_timer(unsigned int clocks) #define TICK_COUNT 100000000 -static int __init calibrate_APIC_clock(void) +static void __init calibrate_APIC_clock(void) { unsigned apic, apic_start; unsigned long tsc, tsc_start; int result; + + local_irq_disable(); + /* * Put whatever arbitrary (but long enough) timeout * value into the APIC clock, we just want to get the * counter running for calibration. + * + * No interrupt enable ! */ - __setup_APIC_LVTT(4000000000); + __setup_APIC_LVTT(250000000, 0, 0); apic_start = apic_read(APIC_TMCCT); #ifdef CONFIG_X86_PM_TIMER @@ -867,123 +913,88 @@ static int __init calibrate_APIC_clock(void) result = (apic_start - apic) * 1000L * tsc_khz / (tsc - tsc_start); } - printk("result %d\n", result); + local_irq_enable(); + + printk(KERN_DEBUG "APIC timer calibration result %d\n", result); printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n", result / 1000 / 1000, result / 1000 % 1000); - return result * APIC_DIVISOR / HZ; -} + /* Calculate the scaled math multiplication factor */ + lapic_clockevent.mult = div_sc(result, NSEC_PER_SEC, 32); + lapic_clockevent.max_delta_ns = + clockevent_delta2ns(0x7FFFFF, &lapic_clockevent); + lapic_clockevent.min_delta_ns = + clockevent_delta2ns(0xF, &lapic_clockevent); -static unsigned int calibration_result; + calibration_result = result / HZ; +} void __init setup_boot_APIC_clock (void) { + /* + * The local apic timer can be disabled via the kernel commandline. + * Register the lapic timer as a dummy clock event source on SMP + * systems, so the broadcast mechanism is used. On UP systems simply + * ignore it. + */ if (disable_apic_timer) { printk(KERN_INFO "Disabling APIC timer\n"); + /* No broadcast on UP ! */ + if (num_possible_cpus() > 1) + setup_APIC_timer(); return; } printk(KERN_INFO "Using local APIC timer interrupts.\n"); - using_apic_timer = 1; - - local_irq_disable(); + calibrate_APIC_clock(); - calibration_result = calibrate_APIC_clock(); /* - * Now set up the timer for real. + * If nmi_watchdog is set to IO_APIC, we need the + * PIT/HPET going. Otherwise register lapic as a dummy + * device. */ - setup_APIC_timer(calibration_result); - - local_irq_enable(); -} - -void __cpuinit setup_secondary_APIC_clock(void) -{ - local_irq_disable(); /* FIXME: Do we need this? --RR */ - setup_APIC_timer(calibration_result); - local_irq_enable(); -} - -void disable_APIC_timer(void) -{ - if (using_apic_timer) { - unsigned long v; + if (nmi_watchdog != NMI_IO_APIC) + lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; + else + printk(KERN_WARNING "APIC timer registered as dummy," + " due to nmi_watchdog=1!\n"); - v = apic_read(APIC_LVTT); - /* - * When an illegal vector value (0-15) is written to an LVT - * entry and delivery mode is Fixed, the APIC may signal an - * illegal vector error, with out regard to whether the mask - * bit is set or whether an interrupt is actually seen on input. - * - * Boot sequence might call this function when the LVTT has - * '0' vector value. So make sure vector field is set to - * valid value. - */ - v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); - apic_write(APIC_LVTT, v); - } + setup_APIC_timer(); } -void enable_APIC_timer(void) +/* + * AMD C1E enabled CPUs have a real nasty problem: Some BIOSes set the + * C1E flag only in the secondary CPU, so when we detect the wreckage + * we already have enabled the boot CPU local apic timer. Check, if + * disable_apic_timer is set and the DUMMY flag is cleared. If yes, + * set the DUMMY flag again and force the broadcast mode in the + * clockevents layer. + */ +void __cpuinit check_boot_apic_timer_broadcast(void) { - int cpu = smp_processor_id(); + struct clock_event_device *levt = &per_cpu(lapic_events, boot_cpu_id); - if (using_apic_timer && - !cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) { - unsigned long v; + if (!disable_apic_timer || + (lapic_clockevent.features & CLOCK_EVT_FEAT_DUMMY)) + return; - v = apic_read(APIC_LVTT); - apic_write(APIC_LVTT, v & ~APIC_LVT_MASKED); - } -} + printk(KERN_INFO "AMD C1E detected late. Force timer broadcast.\n"); + lapic_clockevent.features |= CLOCK_EVT_FEAT_DUMMY; + levt->features |= CLOCK_EVT_FEAT_DUMMY; -void switch_APIC_timer_to_ipi(void *cpumask) -{ - cpumask_t mask = *(cpumask_t *)cpumask; - int cpu = smp_processor_id(); - - if (cpu_isset(cpu, mask) && - !cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) { - disable_APIC_timer(); - cpu_set(cpu, timer_interrupt_broadcast_ipi_mask); - } + local_irq_enable(); + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, &boot_cpu_id); + local_irq_disable(); } -EXPORT_SYMBOL(switch_APIC_timer_to_ipi); -void smp_send_timer_broadcast_ipi(void) +void __cpuinit setup_secondary_APIC_clock(void) { - int cpu = smp_processor_id(); - cpumask_t mask; - - cpus_and(mask, cpu_online_map, timer_interrupt_broadcast_ipi_mask); - - if (cpu_isset(cpu, mask)) { - cpu_clear(cpu, mask); - add_pda(apic_timer_irqs, 1); - smp_local_timer_interrupt(); - } - - if (!cpus_empty(mask)) { - send_IPI_mask(mask, LOCAL_TIMER_VECTOR); - } + check_boot_apic_timer_broadcast(); + setup_APIC_timer(); } -void switch_ipi_to_APIC_timer(void *cpumask) -{ - cpumask_t mask = *(cpumask_t *)cpumask; - int cpu = smp_processor_id(); - - if (cpu_isset(cpu, mask) && - cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) { - cpu_clear(cpu, timer_interrupt_broadcast_ipi_mask); - enable_APIC_timer(); - } -} -EXPORT_SYMBOL(switch_ipi_to_APIC_timer); - int setup_profiling_timer(unsigned int multiplier) { return -EINVAL; @@ -997,8 +1008,6 @@ void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector, apic_write(reg, v); } -#undef APIC_DIVISOR - /* * Local timer interrupt handler. It does both profiling and * process statistics/rescheduling. @@ -1011,22 +1020,34 @@ void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector, void smp_local_timer_interrupt(void) { - profile_tick(CPU_PROFILING); -#ifdef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); -#endif - if (apic_runs_main_timer > 1 && smp_processor_id() == boot_cpu_id) - main_timer_handler(); + int cpu = smp_processor_id(); + struct clock_event_device *evt = &per_cpu(lapic_events, cpu); + /* - * We take the 'long' return path, and there every subsystem - * grabs the appropriate locks (kernel lock/ irq lock). + * Normally we should not be here till LAPIC has been initialized but + * in some cases like kdump, its possible that there is a pending LAPIC + * timer interrupt from previous kernel's context and is delivered in + * new kernel the moment interrupts are enabled. * - * We might want to decouple profiling from the 'long path', - * and do the profiling totally in assembly. - * - * Currently this isn't too much of an issue (performance wise), - * we can take more than 100K local irqs per second on a 100 MHz P5. + * Interrupts are enabled early and LAPIC is setup much later, hence + * its possible that when we get here evt->event_handler is NULL. + * Check for event_handler being NULL and discard the interrupt as + * spurious. + */ + if (!evt->event_handler) { + printk(KERN_WARNING + "Spurious LAPIC timer interrupt on cpu %d\n", cpu); + /* Switch it off */ + lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt); + return; + } + + /* + * the NMI deadlock-detector uses this. */ + add_pda(apic_timer_irqs, 1); + + evt->event_handler(evt); } /* @@ -1042,11 +1063,6 @@ void smp_apic_timer_interrupt(struct pt_regs *regs) struct pt_regs *old_regs = set_irq_regs(regs); /* - * the NMI deadlock-detector uses this. - */ - add_pda(apic_timer_irqs, 1); - - /* * NOTE! We'd better ACK the irq immediately, * because timer handling can be slow. */ @@ -1225,29 +1241,13 @@ static __init int setup_noapictimer(char *str) disable_apic_timer = 1; return 1; } - -static __init int setup_apicmaintimer(char *str) -{ - apic_runs_main_timer = 1; - nohpet = 1; - return 1; -} -__setup("apicmaintimer", setup_apicmaintimer); - -static __init int setup_noapicmaintimer(char *str) -{ - apic_runs_main_timer = -1; - return 1; -} -__setup("noapicmaintimer", setup_noapicmaintimer); +__setup("noapictimer", setup_noapictimer); static __init int setup_apicpmtimer(char *s) { apic_calibrate_pmtmr = 1; notsc_setup(NULL); - return setup_apicmaintimer(NULL); + return 0; } __setup("apicpmtimer", setup_apicpmtimer); -__setup("noapictimer", setup_noapictimer); - diff --git a/arch/x86/kernel/bugs_64.c b/arch/x86/kernel/bugs_64.c index 4e5e9d364d63..9a189cef6404 100644 --- a/arch/x86/kernel/bugs_64.c +++ b/arch/x86/kernel/bugs_64.c @@ -1,6 +1,4 @@ /* - * arch/x86_64/kernel/bugs.c - * * Copyright (C) 1994 Linus Torvalds * Copyright (C) 2000 SuSE */ diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 59266f03d1cd..205fd5ba57f7 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1,6 +1,4 @@ /* - * arch/i386/cpu/bugs.c - * * Copyright (C) 1994 Linus Torvalds * * Cyrix stuff, June 1998 by: diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index b6434a7ef8b2..2ca43ba32bc0 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -595,7 +595,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) dmi_check_system(sw_any_bug_dmi_table); if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) { policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; - policy->cpus = cpu_core_map[cpu]; + policy->cpus = per_cpu(cpu_core_map, cpu); } #endif @@ -646,7 +646,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->cpuinfo.transition_latency = perf->states[i].transition_latency * 1000; } - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; data->max_freq = perf->states[0].core_frequency * 1000; /* table init */ diff --git a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c index 66acd5039918..32f0bda3fc95 100644 --- a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c +++ b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c @@ -363,7 +363,6 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy) policy->cur = nforce2_get(policy->cpu); policy->min = policy->cpuinfo.min_freq; policy->max = policy->cpuinfo.max_freq; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; return 0; } diff --git a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c index f43d98e11cc7..c11baaf9f2b4 100644 --- a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c +++ b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c @@ -253,7 +253,6 @@ static int eps_cpu_init(struct cpufreq_policy *policy) f_table[k].frequency = CPUFREQ_TABLE_END; } - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 140000; /* 844mV -> 700mV in ns */ policy->cur = fsb * current_multiplier; diff --git a/arch/x86/kernel/cpu/cpufreq/elanfreq.c b/arch/x86/kernel/cpu/cpufreq/elanfreq.c index f317276afa7a..1e7ae7dafcf6 100644 --- a/arch/x86/kernel/cpu/cpufreq/elanfreq.c +++ b/arch/x86/kernel/cpu/cpufreq/elanfreq.c @@ -219,7 +219,6 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy) } /* cpuinfo and default policy values */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = elanfreq_get_cpu_frequency(0); diff --git a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c index 461dabc4e495..ed2bda127c44 100644 --- a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c @@ -420,7 +420,6 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) policy->min = maxfreq / POLICY_MIN_DIV; policy->max = maxfreq; policy->cur = curfreq; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.min_freq = maxfreq / max_duration; policy->cpuinfo.max_freq = maxfreq; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c index f0cce3c2dc3a..5045f5d583c8 100644 --- a/arch/x86/kernel/cpu/cpufreq/longhaul.c +++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c @@ -710,6 +710,10 @@ static int enable_arbiter_disable(void) reg = 0x78; dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, NULL); + /* Find PM133/VT8605 host bridge */ + if (dev == NULL) + dev = pci_get_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_8605_0, NULL); /* Find CLE266 host bridge */ if (dev == NULL) { reg = 0x76; @@ -918,7 +922,6 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) if ((longhaul_version != TYPE_LONGHAUL_V1) && (scale_voltage != 0)) longhaul_setup_voltagescaling(); - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 200000; /* nsec */ policy->cur = calc_speed(longhaul_get_cpu_mult()); diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c index 4c76b511e194..793eae854f4f 100644 --- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c @@ -200,7 +200,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) unsigned int i; #ifdef CONFIG_SMP - policy->cpus = cpu_sibling_map[policy->cpu]; + policy->cpus = per_cpu(cpu_sibling_map, policy->cpu); #endif /* Errata workaround */ @@ -229,7 +229,6 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu); /* cpuinfo and default policy values */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 1000000; /* assumed */ policy->cur = stock_freq; diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c index f89524051e4a..6d0285339317 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c @@ -160,7 +160,6 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) } /* cpuinfo and default policy values */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = busfreq * max_multiplier; diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c index ca3e1d341889..7decd6a50ffa 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c @@ -637,8 +637,6 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) printk (KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n", minimum_speed/1000, maximum_speed/1000); - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - policy->cpuinfo.transition_latency = cpufreq_scale(2000000UL, fsb, latency); policy->cur = powernow_get(0); diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 34ed53a06730..c06ac680c9ca 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -57,7 +57,7 @@ static struct powernow_k8_data *powernow_data[NR_CPUS]; static int cpu_family = CPU_OPTERON; #ifndef CONFIG_SMP -static cpumask_t cpu_core_map[1]; +DEFINE_PER_CPU(cpumask_t, cpu_core_map); #endif /* Return a frequency in MHz, given an input fid */ @@ -76,7 +76,10 @@ static u32 find_khz_freq_from_fid(u32 fid) /* Return a frequency in MHz, given an input fid and did */ static u32 find_freq_from_fiddid(u32 fid, u32 did) { - return 100 * (fid + 0x10) >> did; + if (current_cpu_data.x86 == 0x10) + return 100 * (fid + 0x10) >> did; + else + return 100 * (fid + 0x8) >> did; } static u32 find_khz_freq_from_fiddid(u32 fid, u32 did) @@ -664,7 +667,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid); data->powernow_table = powernow_table; - if (first_cpu(cpu_core_map[data->cpu]) == data->cpu) + if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu) print_basics(data); for (j = 0; j < data->numps; j++) @@ -818,7 +821,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) /* fill in data */ data->numps = data->acpi_data.state_count; - if (first_cpu(cpu_core_map[data->cpu]) == data->cpu) + if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu) print_basics(data); powernow_k8_acpi_pst_values(data, 0); @@ -1208,11 +1211,10 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) /* run on any CPU again */ set_cpus_allowed(current, oldmask); - pol->governor = CPUFREQ_DEFAULT_GOVERNOR; if (cpu_family == CPU_HW_PSTATE) pol->cpus = cpumask_of_cpu(pol->cpu); else - pol->cpus = cpu_core_map[pol->cpu]; + pol->cpus = per_cpu(cpu_core_map, pol->cpu); data->available_cores = &(pol->cpus); /* Take a crude guess here. @@ -1279,7 +1281,7 @@ static unsigned int powernowk8_get (unsigned int cpu) cpumask_t oldmask = current->cpus_allowed; unsigned int khz = 0; - data = powernow_data[first_cpu(cpu_core_map[cpu])]; + data = powernow_data[first_cpu(per_cpu(cpu_core_map, cpu))]; if (!data) return -EINVAL; @@ -1325,21 +1327,16 @@ static struct cpufreq_driver cpufreq_amd64_driver = { static int __cpuinit powernowk8_init(void) { unsigned int i, supported_cpus = 0; - unsigned int booted_cores = 1; for_each_online_cpu(i) { if (check_supported_cpu(i)) supported_cpus++; } -#ifdef CONFIG_SMP - booted_cores = cpu_data[0].booted_cores; -#endif - if (supported_cpus == num_online_cpus()) { printk(KERN_INFO PFX "Found %d %s " "processors (%d cpu cores) (" VERSION ")\n", - supported_cpus/booted_cores, + num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus); return cpufreq_register_driver(&cpufreq_amd64_driver); } diff --git a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c index b8fb4b521c62..d9f3e90a7ae0 100644 --- a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c +++ b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c @@ -111,7 +111,6 @@ static int sc520_freq_cpu_init(struct cpufreq_policy *policy) return -ENODEV; /* cpuinfo and default policy values */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 1000000; /* 1ms */ policy->cur = sc520_freq_get_cpu_frequency(0); diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c index 6c5dc2c85aeb..811d47438546 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c @@ -393,7 +393,6 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) freq = get_cur_freq(policy->cpu); - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 10000; /* 10uS transition latency */ policy->cur = freq; diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c index a5b2346faf1f..14d68aa301ee 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c @@ -322,7 +322,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) /* only run on CPU to be set, or on its sibling */ #ifdef CONFIG_SMP - policy->cpus = cpu_sibling_map[policy->cpu]; + policy->cpus = per_cpu(cpu_sibling_map, policy->cpu); #endif cpus_allowed = current->cpus_allowed; @@ -348,7 +348,6 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) (speed / 1000)); /* cpuinfo and default policy values */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cur = speed; result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c index e1c509aa3054..f2b5a621d27b 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c @@ -290,7 +290,6 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) (speed / 1000)); /* cpuinfo and default policy values */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = speed; diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index 1e31b6caffb1..879a0f789b1e 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c @@ -122,7 +122,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) #ifdef CONFIG_X86_HT if (c->x86_max_cores * smp_num_siblings > 1) { seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); - seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[n])); + seq_printf(m, "siblings\t: %d\n", + cpus_weight(per_cpu(cpu_core_map, n))); seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); } diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index 5c2faa10e9fa..f4548c93ccf5 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c @@ -11,8 +11,6 @@ * ----------------------------------------------------------------------- */ /* - * cpuid.c - * * x86 CPUID access device * * This device is accessed by lseek() to the appropriate CPUID level diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c index 3f532df488bc..32e75d0731a9 100644 --- a/arch/x86/kernel/crash_dump_32.c +++ b/arch/x86/kernel/crash_dump_32.c @@ -1,5 +1,5 @@ /* - * kernel/crash_dump.c - Memory preserving reboot related code. + * Memory preserving reboot related code. * * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) * Copyright (C) IBM Corporation, 2004. All rights reserved diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c index 942deac4d43a..15e6c6bc4a46 100644 --- a/arch/x86/kernel/crash_dump_64.c +++ b/arch/x86/kernel/crash_dump_64.c @@ -1,5 +1,5 @@ /* - * kernel/crash_dump.c - Memory preserving reboot related code. + * Memory preserving reboot related code. * * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) * Copyright (C) IBM Corporation, 2004. All rights reserved diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 290b7bc82da3..8099fea0a72f 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -251,6 +251,7 @@ check_userspace: jb resume_kernel # not returning to v8086 or userspace ENTRY(resume_userspace) + LOCKDEP_SYS_EXIT DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret @@ -338,6 +339,7 @@ sysenter_past_esp: jae syscall_badsys call *sys_call_table(,%eax,4) movl %eax,PT_EAX(%esp) + LOCKDEP_SYS_EXIT DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx @@ -377,6 +379,7 @@ syscall_call: call *sys_call_table(,%eax,4) movl %eax,PT_EAX(%esp) # store the return value syscall_exit: + LOCKDEP_SYS_EXIT DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret @@ -467,6 +470,7 @@ work_pending: jz work_notifysig work_resched: call schedule + LOCKDEP_SYS_EXIT DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 1d232e5f5658..f1cacd4897f7 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -244,6 +244,7 @@ ret_from_sys_call: movl $_TIF_ALLWORK_MASK,%edi /* edi: flagmask */ sysret_check: + LOCKDEP_SYS_EXIT GET_THREAD_INFO(%rcx) cli TRACE_IRQS_OFF @@ -333,6 +334,7 @@ int_ret_from_sys_call: movl $_TIF_ALLWORK_MASK,%edi /* edi: mask to check */ int_with_check: + LOCKDEP_SYS_EXIT_IRQ GET_THREAD_INFO(%rcx) movl threadinfo_flags(%rcx),%edx andl %edi,%edx @@ -544,11 +546,13 @@ exit_intr: retint_with_reschedule: movl $_TIF_WORK_MASK,%edi retint_check: + LOCKDEP_SYS_EXIT_IRQ movl threadinfo_flags(%rcx),%edx andl %edi,%edx CFI_REMEMBER_STATE jnz retint_careful -retint_swapgs: + +retint_swapgs: /* return to user-space */ /* * The iretq could re-enable interrupts: */ @@ -557,7 +561,7 @@ retint_swapgs: swapgs jmp restore_args -retint_restore_args: +retint_restore_args: /* return to kernel space */ cli /* * The iretq could re-enable interrupts: @@ -866,26 +870,21 @@ error_sti: movq ORIG_RAX(%rsp),%rsi /* get error code */ movq $-1,ORIG_RAX(%rsp) call *%rax - /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */ -error_exit: - movl %ebx,%eax + /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */ +error_exit: + movl %ebx,%eax RESTORE_REST cli TRACE_IRQS_OFF GET_THREAD_INFO(%rcx) testl %eax,%eax jne retint_kernel + LOCKDEP_SYS_EXIT_IRQ movl threadinfo_flags(%rcx),%edx movl $_TIF_WORK_MASK,%edi andl %edi,%edx jnz retint_careful - /* - * The iret might restore flags: - */ - TRACE_IRQS_IRETQ - swapgs - RESTORE_ARGS 0,8,0 - jmp iret_label + jmp retint_swapgs CFI_ENDPROC error_kernelspace: diff --git a/arch/x86/kernel/geode_32.c b/arch/x86/kernel/geode_32.c index 41e8aec4c61d..f12d8c5d9809 100644 --- a/arch/x86/kernel/geode_32.c +++ b/arch/x86/kernel/geode_32.c @@ -145,10 +145,14 @@ EXPORT_SYMBOL_GPL(geode_gpio_setup_event); static int __init geode_southbridge_init(void) { + int timers; + if (!is_geode()) return -ENODEV; init_lbars(); + timers = geode_mfgpt_detect(); + printk(KERN_INFO "geode: %d MFGPT timers available.\n", timers); return 0; } diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 6c34bdd22e26..8561f626edad 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -1,5 +1,5 @@ /* - * linux/arch/x86_64/kernel/head64.c -- prepare to run common code + * prepare to run common code * * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE */ diff --git a/arch/x86/kernel/hpet_32.c b/arch/x86/kernel/hpet.c index 533d4932bc79..f8367074da0d 100644 --- a/arch/x86/kernel/hpet_32.c +++ b/arch/x86/kernel/hpet.c @@ -1,5 +1,6 @@ #include <linux/clocksource.h> #include <linux/clockchips.h> +#include <linux/delay.h> #include <linux/errno.h> #include <linux/hpet.h> #include <linux/init.h> @@ -7,11 +8,11 @@ #include <linux/pm.h> #include <linux/delay.h> +#include <asm/fixmap.h> #include <asm/hpet.h> +#include <asm/i8253.h> #include <asm/io.h> -extern struct clock_event_device *global_clock_event; - #define HPET_MASK CLOCKSOURCE_MASK(32) #define HPET_SHIFT 22 @@ -22,9 +23,9 @@ extern struct clock_event_device *global_clock_event; * HPET address is set in acpi/boot.c, when an ACPI entry exists */ unsigned long hpet_address; -static void __iomem * hpet_virt_address; +static void __iomem *hpet_virt_address; -static inline unsigned long hpet_readl(unsigned long a) +unsigned long hpet_readl(unsigned long a) { return readl(hpet_virt_address + a); } @@ -34,6 +35,36 @@ static inline void hpet_writel(unsigned long d, unsigned long a) writel(d, hpet_virt_address + a); } +#ifdef CONFIG_X86_64 + +#include <asm/pgtable.h> + +static inline void hpet_set_mapping(void) +{ + set_fixmap_nocache(FIX_HPET_BASE, hpet_address); + __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE); + hpet_virt_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE); +} + +static inline void hpet_clear_mapping(void) +{ + hpet_virt_address = NULL; +} + +#else + +static inline void hpet_set_mapping(void) +{ + hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE); +} + +static inline void hpet_clear_mapping(void) +{ + iounmap(hpet_virt_address); + hpet_virt_address = NULL; +} +#endif + /* * HPET command line enable / disable */ @@ -49,6 +80,13 @@ static int __init hpet_setup(char* str) } __setup("hpet=", hpet_setup); +static int __init disable_hpet(char *str) +{ + boot_hpet_disable = 1; + return 1; +} +__setup("nohpet", disable_hpet); + static inline int is_hpet_capable(void) { return (!boot_hpet_disable && hpet_address); @@ -83,7 +121,7 @@ static void hpet_reserve_platform_timers(unsigned long id) memset(&hd, 0, sizeof (hd)); hd.hd_phys_address = hpet_address; - hd.hd_address = hpet_virt_address; + hd.hd_address = hpet; hd.hd_nirqs = nrtimers; hd.hd_flags = HPET_DATA_PLATFORM; hpet_reserve_timer(&hd, 0); @@ -111,9 +149,9 @@ static void hpet_reserve_platform_timers(unsigned long id) { } */ static unsigned long hpet_period; -static void hpet_set_mode(enum clock_event_mode mode, +static void hpet_legacy_set_mode(enum clock_event_mode mode, struct clock_event_device *evt); -static int hpet_next_event(unsigned long delta, +static int hpet_legacy_next_event(unsigned long delta, struct clock_event_device *evt); /* @@ -122,10 +160,11 @@ static int hpet_next_event(unsigned long delta, static struct clock_event_device hpet_clockevent = { .name = "hpet", .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .set_mode = hpet_set_mode, - .set_next_event = hpet_next_event, + .set_mode = hpet_legacy_set_mode, + .set_next_event = hpet_legacy_next_event, .shift = 32, .irq = 0, + .rating = 50, }; static void hpet_start_counter(void) @@ -140,7 +179,18 @@ static void hpet_start_counter(void) hpet_writel(cfg, HPET_CFG); } -static void hpet_enable_int(void) +static void hpet_resume_device(void) +{ + force_hpet_resume(); +} + +static void hpet_restart_counter(void) +{ + hpet_resume_device(); + hpet_start_counter(); +} + +static void hpet_enable_legacy_int(void) { unsigned long cfg = hpet_readl(HPET_CFG); @@ -149,7 +199,39 @@ static void hpet_enable_int(void) hpet_legacy_int_enabled = 1; } -static void hpet_set_mode(enum clock_event_mode mode, +static void hpet_legacy_clockevent_register(void) +{ + uint64_t hpet_freq; + + /* Start HPET legacy interrupts */ + hpet_enable_legacy_int(); + + /* + * The period is a femto seconds value. We need to calculate the + * scaled math multiplication factor for nanosecond to hpet tick + * conversion. + */ + hpet_freq = 1000000000000000ULL; + do_div(hpet_freq, hpet_period); + hpet_clockevent.mult = div_sc((unsigned long) hpet_freq, + NSEC_PER_SEC, 32); + /* Calculate the min / max delta */ + hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, + &hpet_clockevent); + hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30, + &hpet_clockevent); + + /* + * Start hpet with the boot cpu mask and make it + * global after the IO_APIC has been initialized. + */ + hpet_clockevent.cpumask = cpumask_of_cpu(smp_processor_id()); + clockevents_register_device(&hpet_clockevent); + global_clock_event = &hpet_clockevent; + printk(KERN_DEBUG "hpet clockevent registered\n"); +} + +static void hpet_legacy_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { unsigned long cfg, cmp, now; @@ -190,12 +272,12 @@ static void hpet_set_mode(enum clock_event_mode mode, break; case CLOCK_EVT_MODE_RESUME: - hpet_enable_int(); + hpet_enable_legacy_int(); break; } } -static int hpet_next_event(unsigned long delta, +static int hpet_legacy_next_event(unsigned long delta, struct clock_event_device *evt) { unsigned long cnt; @@ -215,6 +297,13 @@ static cycle_t read_hpet(void) return (cycle_t)hpet_readl(HPET_COUNTER); } +#ifdef CONFIG_X86_64 +static cycle_t __vsyscall_fn vread_hpet(void) +{ + return readl((const void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0); +} +#endif + static struct clocksource clocksource_hpet = { .name = "hpet", .rating = 250, @@ -222,61 +311,17 @@ static struct clocksource clocksource_hpet = { .mask = HPET_MASK, .shift = HPET_SHIFT, .flags = CLOCK_SOURCE_IS_CONTINUOUS, - .resume = hpet_start_counter, + .resume = hpet_restart_counter, +#ifdef CONFIG_X86_64 + .vread = vread_hpet, +#endif }; -/* - * Try to setup the HPET timer - */ -int __init hpet_enable(void) +static int hpet_clocksource_register(void) { - unsigned long id; - uint64_t hpet_freq; u64 tmp, start, now; cycle_t t1; - if (!is_hpet_capable()) - return 0; - - hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE); - - /* - * Read the period and check for a sane value: - */ - hpet_period = hpet_readl(HPET_PERIOD); - if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD) - goto out_nohpet; - - /* - * The period is a femto seconds value. We need to calculate the - * scaled math multiplication factor for nanosecond to hpet tick - * conversion. - */ - hpet_freq = 1000000000000000ULL; - do_div(hpet_freq, hpet_period); - hpet_clockevent.mult = div_sc((unsigned long) hpet_freq, - NSEC_PER_SEC, 32); - /* Calculate the min / max delta */ - hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, - &hpet_clockevent); - hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30, - &hpet_clockevent); - - /* - * Read the HPET ID register to retrieve the IRQ routing - * information and the number of channels - */ - id = hpet_readl(HPET_ID); - -#ifdef CONFIG_HPET_EMULATE_RTC - /* - * The legacy routing mode needs at least two channels, tick timer - * and the rtc emulation channel. - */ - if (!(id & HPET_ID_NUMBER)) - goto out_nohpet; -#endif - /* Start the counter */ hpet_start_counter(); @@ -298,7 +343,7 @@ int __init hpet_enable(void) if (t1 == read_hpet()) { printk(KERN_WARNING "HPET counter not counting. HPET disabled\n"); - goto out_nohpet; + return -ENODEV; } /* Initialize and register HPET clocksource @@ -319,27 +364,84 @@ int __init hpet_enable(void) clocksource_register(&clocksource_hpet); + return 0; +} + +/* + * Try to setup the HPET timer + */ +int __init hpet_enable(void) +{ + unsigned long id; + + if (!is_hpet_capable()) + return 0; + + hpet_set_mapping(); + + /* + * Read the period and check for a sane value: + */ + hpet_period = hpet_readl(HPET_PERIOD); + if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD) + goto out_nohpet; + + /* + * Read the HPET ID register to retrieve the IRQ routing + * information and the number of channels + */ + id = hpet_readl(HPET_ID); + +#ifdef CONFIG_HPET_EMULATE_RTC + /* + * The legacy routing mode needs at least two channels, tick timer + * and the rtc emulation channel. + */ + if (!(id & HPET_ID_NUMBER)) + goto out_nohpet; +#endif + + if (hpet_clocksource_register()) + goto out_nohpet; + if (id & HPET_ID_LEGSUP) { - hpet_enable_int(); - hpet_reserve_platform_timers(id); - /* - * Start hpet with the boot cpu mask and make it - * global after the IO_APIC has been initialized. - */ - hpet_clockevent.cpumask = cpumask_of_cpu(smp_processor_id()); - clockevents_register_device(&hpet_clockevent); - global_clock_event = &hpet_clockevent; + hpet_legacy_clockevent_register(); return 1; } return 0; out_nohpet: - iounmap(hpet_virt_address); - hpet_virt_address = NULL; + hpet_clear_mapping(); boot_hpet_disable = 1; return 0; } +/* + * Needs to be late, as the reserve_timer code calls kalloc ! + * + * Not a problem on i386 as hpet_enable is called from late_time_init, + * but on x86_64 it is necessary ! + */ +static __init int hpet_late_init(void) +{ + if (boot_hpet_disable) + return -ENODEV; + + if (!hpet_address) { + if (!force_hpet_address) + return -ENODEV; + + hpet_address = force_hpet_address; + hpet_enable(); + if (!hpet_virt_address) + return -ENODEV; + } + + hpet_reserve_platform_timers(hpet_readl(HPET_ID)); + + return 0; +} +fs_initcall(hpet_late_init); #ifdef CONFIG_HPET_EMULATE_RTC diff --git a/arch/x86/kernel/hpet_64.c b/arch/x86/kernel/hpet_64.c deleted file mode 100644 index e2d1b912e154..000000000000 --- a/arch/x86/kernel/hpet_64.c +++ /dev/null @@ -1,493 +0,0 @@ -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/init.h> -#include <linux/mc146818rtc.h> -#include <linux/time.h> -#include <linux/clocksource.h> -#include <linux/ioport.h> -#include <linux/acpi.h> -#include <linux/hpet.h> -#include <asm/pgtable.h> -#include <asm/vsyscall.h> -#include <asm/timex.h> -#include <asm/hpet.h> - -#define HPET_MASK 0xFFFFFFFF -#define HPET_SHIFT 22 - -/* FSEC = 10^-15 NSEC = 10^-9 */ -#define FSEC_PER_NSEC 1000000 - -int nohpet __initdata; - -unsigned long hpet_address; -unsigned long hpet_period; /* fsecs / HPET clock */ -unsigned long hpet_tick; /* HPET clocks / interrupt */ - -int hpet_use_timer; /* Use counter of hpet for time keeping, - * otherwise PIT - */ - -#ifdef CONFIG_HPET -static __init int late_hpet_init(void) -{ - struct hpet_data hd; - unsigned int ntimer; - - if (!hpet_address) - return 0; - - memset(&hd, 0, sizeof(hd)); - - ntimer = hpet_readl(HPET_ID); - ntimer = (ntimer & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT; - ntimer++; - - /* - * Register with driver. - * Timer0 and Timer1 is used by platform. - */ - hd.hd_phys_address = hpet_address; - hd.hd_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE); - hd.hd_nirqs = ntimer; - hd.hd_flags = HPET_DATA_PLATFORM; - hpet_reserve_timer(&hd, 0); -#ifdef CONFIG_HPET_EMULATE_RTC - hpet_reserve_timer(&hd, 1); -#endif - hd.hd_irq[0] = HPET_LEGACY_8254; - hd.hd_irq[1] = HPET_LEGACY_RTC; - if (ntimer > 2) { - struct hpet *hpet; - struct hpet_timer *timer; - int i; - - hpet = (struct hpet *) fix_to_virt(FIX_HPET_BASE); - timer = &hpet->hpet_timers[2]; - for (i = 2; i < ntimer; timer++, i++) - hd.hd_irq[i] = (timer->hpet_config & - Tn_INT_ROUTE_CNF_MASK) >> - Tn_INT_ROUTE_CNF_SHIFT; - - } - - hpet_alloc(&hd); - return 0; -} -fs_initcall(late_hpet_init); -#endif - -int hpet_timer_stop_set_go(unsigned long tick) -{ - unsigned int cfg; - -/* - * Stop the timers and reset the main counter. - */ - - cfg = hpet_readl(HPET_CFG); - cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY); - hpet_writel(cfg, HPET_CFG); - hpet_writel(0, HPET_COUNTER); - hpet_writel(0, HPET_COUNTER + 4); - -/* - * Set up timer 0, as periodic with first interrupt to happen at hpet_tick, - * and period also hpet_tick. - */ - if (hpet_use_timer) { - hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | - HPET_TN_32BIT, HPET_T0_CFG); - hpet_writel(hpet_tick, HPET_T0_CMP); /* next interrupt */ - hpet_writel(hpet_tick, HPET_T0_CMP); /* period */ - cfg |= HPET_CFG_LEGACY; - } -/* - * Go! - */ - - cfg |= HPET_CFG_ENABLE; - hpet_writel(cfg, HPET_CFG); - - return 0; -} - -static cycle_t read_hpet(void) -{ - return (cycle_t)hpet_readl(HPET_COUNTER); -} - -static cycle_t __vsyscall_fn vread_hpet(void) -{ - return readl((void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0); -} - -struct clocksource clocksource_hpet = { - .name = "hpet", - .rating = 250, - .read = read_hpet, - .mask = (cycle_t)HPET_MASK, - .mult = 0, /* set below */ - .shift = HPET_SHIFT, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, - .vread = vread_hpet, -}; - -int __init hpet_arch_init(void) -{ - unsigned int id; - u64 tmp; - - if (!hpet_address) - return -1; - set_fixmap_nocache(FIX_HPET_BASE, hpet_address); - __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE); - -/* - * Read the period, compute tick and quotient. - */ - - id = hpet_readl(HPET_ID); - - if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER)) - return -1; - - hpet_period = hpet_readl(HPET_PERIOD); - if (hpet_period < 100000 || hpet_period > 100000000) - return -1; - - hpet_tick = (FSEC_PER_TICK + hpet_period / 2) / hpet_period; - - hpet_use_timer = (id & HPET_ID_LEGSUP); - - /* - * hpet period is in femto seconds per cycle - * so we need to convert this to ns/cyc units - * aproximated by mult/2^shift - * - * fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift - * fsec/cyc * 1ns/1000000fsec * 2^shift = mult - * fsec/cyc * 2^shift * 1nsec/1000000fsec = mult - * (fsec/cyc << shift)/1000000 = mult - * (hpet_period << shift)/FSEC_PER_NSEC = mult - */ - tmp = (u64)hpet_period << HPET_SHIFT; - do_div(tmp, FSEC_PER_NSEC); - clocksource_hpet.mult = (u32)tmp; - clocksource_register(&clocksource_hpet); - - return hpet_timer_stop_set_go(hpet_tick); -} - -int hpet_reenable(void) -{ - return hpet_timer_stop_set_go(hpet_tick); -} - -/* - * calibrate_tsc() calibrates the processor TSC in a very simple way, comparing - * it to the HPET timer of known frequency. - */ - -#define TICK_COUNT 100000000 -#define SMI_THRESHOLD 50000 -#define MAX_TRIES 5 - -/* - * Some platforms take periodic SMI interrupts with 5ms duration. Make sure none - * occurs between the reads of the hpet & TSC. - */ -static void __init read_hpet_tsc(int *hpet, int *tsc) -{ - int tsc1, tsc2, hpet1, i; - - for (i = 0; i < MAX_TRIES; i++) { - tsc1 = get_cycles_sync(); - hpet1 = hpet_readl(HPET_COUNTER); - tsc2 = get_cycles_sync(); - if ((tsc2 - tsc1) < SMI_THRESHOLD) - break; - } - *hpet = hpet1; - *tsc = tsc2; -} - -unsigned int __init hpet_calibrate_tsc(void) -{ - int tsc_start, hpet_start; - int tsc_now, hpet_now; - unsigned long flags; - - local_irq_save(flags); - - read_hpet_tsc(&hpet_start, &tsc_start); - - do { - local_irq_disable(); - read_hpet_tsc(&hpet_now, &tsc_now); - local_irq_restore(flags); - } while ((tsc_now - tsc_start) < TICK_COUNT && - (hpet_now - hpet_start) < TICK_COUNT); - - return (tsc_now - tsc_start) * 1000000000L - / ((hpet_now - hpet_start) * hpet_period / 1000); -} - -#ifdef CONFIG_HPET_EMULATE_RTC -/* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET - * is enabled, we support RTC interrupt functionality in software. - * RTC has 3 kinds of interrupts: - * 1) Update Interrupt - generate an interrupt, every sec, when RTC clock - * is updated - * 2) Alarm Interrupt - generate an interrupt at a specific time of day - * 3) Periodic Interrupt - generate periodic interrupt, with frequencies - * 2Hz-8192Hz (2Hz-64Hz for non-root user) (all freqs in powers of 2) - * (1) and (2) above are implemented using polling at a frequency of - * 64 Hz. The exact frequency is a tradeoff between accuracy and interrupt - * overhead. (DEFAULT_RTC_INT_FREQ) - * For (3), we use interrupts at 64Hz or user specified periodic - * frequency, whichever is higher. - */ -#include <linux/rtc.h> - -#define DEFAULT_RTC_INT_FREQ 64 -#define RTC_NUM_INTS 1 - -static unsigned long UIE_on; -static unsigned long prev_update_sec; - -static unsigned long AIE_on; -static struct rtc_time alarm_time; - -static unsigned long PIE_on; -static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ; -static unsigned long PIE_count; - -static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */ -static unsigned int hpet_t1_cmp; /* cached comparator register */ - -int is_hpet_enabled(void) -{ - return hpet_address != 0; -} - -/* - * Timer 1 for RTC, we do not use periodic interrupt feature, - * even if HPET supports periodic interrupts on Timer 1. - * The reason being, to set up a periodic interrupt in HPET, we need to - * stop the main counter. And if we do that everytime someone diables/enables - * RTC, we will have adverse effect on main kernel timer running on Timer 0. - * So, for the time being, simulate the periodic interrupt in software. - * - * hpet_rtc_timer_init() is called for the first time and during subsequent - * interuppts reinit happens through hpet_rtc_timer_reinit(). - */ -int hpet_rtc_timer_init(void) -{ - unsigned int cfg, cnt; - unsigned long flags; - - if (!is_hpet_enabled()) - return 0; - /* - * Set the counter 1 and enable the interrupts. - */ - if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ)) - hpet_rtc_int_freq = PIE_freq; - else - hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; - - local_irq_save(flags); - - cnt = hpet_readl(HPET_COUNTER); - cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq); - hpet_writel(cnt, HPET_T1_CMP); - hpet_t1_cmp = cnt; - - cfg = hpet_readl(HPET_T1_CFG); - cfg &= ~HPET_TN_PERIODIC; - cfg |= HPET_TN_ENABLE | HPET_TN_32BIT; - hpet_writel(cfg, HPET_T1_CFG); - - local_irq_restore(flags); - - return 1; -} - -static void hpet_rtc_timer_reinit(void) -{ - unsigned int cfg, cnt, ticks_per_int, lost_ints; - - if (unlikely(!(PIE_on | AIE_on | UIE_on))) { - cfg = hpet_readl(HPET_T1_CFG); - cfg &= ~HPET_TN_ENABLE; - hpet_writel(cfg, HPET_T1_CFG); - return; - } - - if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ)) - hpet_rtc_int_freq = PIE_freq; - else - hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; - - /* It is more accurate to use the comparator value than current count.*/ - ticks_per_int = hpet_tick * HZ / hpet_rtc_int_freq; - hpet_t1_cmp += ticks_per_int; - hpet_writel(hpet_t1_cmp, HPET_T1_CMP); - - /* - * If the interrupt handler was delayed too long, the write above tries - * to schedule the next interrupt in the past and the hardware would - * not interrupt until the counter had wrapped around. - * So we have to check that the comparator wasn't set to a past time. - */ - cnt = hpet_readl(HPET_COUNTER); - if (unlikely((int)(cnt - hpet_t1_cmp) > 0)) { - lost_ints = (cnt - hpet_t1_cmp) / ticks_per_int + 1; - /* Make sure that, even with the time needed to execute - * this code, the next scheduled interrupt has been moved - * back to the future: */ - lost_ints++; - - hpet_t1_cmp += lost_ints * ticks_per_int; - hpet_writel(hpet_t1_cmp, HPET_T1_CMP); - - if (PIE_on) - PIE_count += lost_ints; - - if (printk_ratelimit()) - printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", - hpet_rtc_int_freq); - } -} - -/* - * The functions below are called from rtc driver. - * Return 0 if HPET is not being used. - * Otherwise do the necessary changes and return 1. - */ -int hpet_mask_rtc_irq_bit(unsigned long bit_mask) -{ - if (!is_hpet_enabled()) - return 0; - - if (bit_mask & RTC_UIE) - UIE_on = 0; - if (bit_mask & RTC_PIE) - PIE_on = 0; - if (bit_mask & RTC_AIE) - AIE_on = 0; - - return 1; -} - -int hpet_set_rtc_irq_bit(unsigned long bit_mask) -{ - int timer_init_reqd = 0; - - if (!is_hpet_enabled()) - return 0; - - if (!(PIE_on | AIE_on | UIE_on)) - timer_init_reqd = 1; - - if (bit_mask & RTC_UIE) { - UIE_on = 1; - } - if (bit_mask & RTC_PIE) { - PIE_on = 1; - PIE_count = 0; - } - if (bit_mask & RTC_AIE) { - AIE_on = 1; - } - - if (timer_init_reqd) - hpet_rtc_timer_init(); - - return 1; -} - -int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec) -{ - if (!is_hpet_enabled()) - return 0; - - alarm_time.tm_hour = hrs; - alarm_time.tm_min = min; - alarm_time.tm_sec = sec; - - return 1; -} - -int hpet_set_periodic_freq(unsigned long freq) -{ - if (!is_hpet_enabled()) - return 0; - - PIE_freq = freq; - PIE_count = 0; - - return 1; -} - -int hpet_rtc_dropped_irq(void) -{ - if (!is_hpet_enabled()) - return 0; - - return 1; -} - -irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) -{ - struct rtc_time curr_time; - unsigned long rtc_int_flag = 0; - int call_rtc_interrupt = 0; - - hpet_rtc_timer_reinit(); - - if (UIE_on | AIE_on) { - rtc_get_rtc_time(&curr_time); - } - if (UIE_on) { - if (curr_time.tm_sec != prev_update_sec) { - /* Set update int info, call real rtc int routine */ - call_rtc_interrupt = 1; - rtc_int_flag = RTC_UF; - prev_update_sec = curr_time.tm_sec; - } - } - if (PIE_on) { - PIE_count++; - if (PIE_count >= hpet_rtc_int_freq/PIE_freq) { - /* Set periodic int info, call real rtc int routine */ - call_rtc_interrupt = 1; - rtc_int_flag |= RTC_PF; - PIE_count = 0; - } - } - if (AIE_on) { - if ((curr_time.tm_sec == alarm_time.tm_sec) && - (curr_time.tm_min == alarm_time.tm_min) && - (curr_time.tm_hour == alarm_time.tm_hour)) { - /* Set alarm int info, call real rtc int routine */ - call_rtc_interrupt = 1; - rtc_int_flag |= RTC_AF; - } - } - if (call_rtc_interrupt) { - rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8)); - rtc_interrupt(rtc_int_flag, dev_id); - } - return IRQ_HANDLED; -} -#endif - -static int __init nohpet_setup(char *s) -{ - nohpet = 1; - return 1; -} - -__setup("nohpet", nohpet_setup); diff --git a/arch/x86/kernel/i387_32.c b/arch/x86/kernel/i387_32.c index 665847281ed2..7d2e12f6c78b 100644 --- a/arch/x86/kernel/i387_32.c +++ b/arch/x86/kernel/i387_32.c @@ -1,6 +1,4 @@ /* - * linux/arch/i386/kernel/i387.c - * * Copyright (C) 1994 Linus Torvalds * * Pentium III FXSR, SSE support diff --git a/arch/x86/kernel/i387_64.c b/arch/x86/kernel/i387_64.c index 1d58c13bc6bc..56c1f1147109 100644 --- a/arch/x86/kernel/i387_64.c +++ b/arch/x86/kernel/i387_64.c @@ -1,6 +1,4 @@ /* - * linux/arch/x86_64/kernel/i387.c - * * Copyright (C) 1994 Linus Torvalds * Copyright (C) 2002 Andi Kleen, SuSE Labs * diff --git a/arch/x86/kernel/i8237.c b/arch/x86/kernel/i8237.c index 6f508e8d7c57..29313832df0c 100644 --- a/arch/x86/kernel/i8237.c +++ b/arch/x86/kernel/i8237.c @@ -1,5 +1,5 @@ /* - * i8237.c: 8237A DMA controller suspend functions. + * 8237A DMA controller suspend functions. * * Written by Pierre Ossman, 2005. * diff --git a/arch/x86/kernel/i8253_32.c b/arch/x86/kernel/i8253.c index 6d839f2f1b1a..5cc8841ca2c6 100644 --- a/arch/x86/kernel/i8253_32.c +++ b/arch/x86/kernel/i8253.c @@ -1,5 +1,5 @@ /* - * i8253.c 8253/PIT functions + * 8253/PIT functions * */ #include <linux/clockchips.h> @@ -13,7 +13,6 @@ #include <asm/delay.h> #include <asm/i8253.h> #include <asm/io.h> -#include <asm/timer.h> DEFINE_SPINLOCK(i8253_lock); EXPORT_SYMBOL(i8253_lock); @@ -120,6 +119,7 @@ void __init setup_pit_timer(void) global_clock_event = &pit_clockevent; } +#ifndef CONFIG_X86_64 /* * Since the PIT overflows every tick, its not very useful * to just read by itself. So use jiffies to emulate a free @@ -204,3 +204,5 @@ static int __init init_pit_clocksource(void) return clocksource_register(&clocksource_pit); } arch_initcall(init_pit_clocksource); + +#endif diff --git a/arch/x86/kernel/i8259_32.c b/arch/x86/kernel/i8259_32.c index 0499cbe9871a..679bb33acbf1 100644 --- a/arch/x86/kernel/i8259_32.c +++ b/arch/x86/kernel/i8259_32.c @@ -10,7 +10,6 @@ #include <linux/sysdev.h> #include <linux/bitops.h> -#include <asm/8253pit.h> #include <asm/atomic.h> #include <asm/system.h> #include <asm/io.h> diff --git a/arch/x86/kernel/i8259_64.c b/arch/x86/kernel/i8259_64.c index 948cae646099..eb72976cc13c 100644 --- a/arch/x86/kernel/i8259_64.c +++ b/arch/x86/kernel/i8259_64.c @@ -444,46 +444,6 @@ void __init init_ISA_irqs (void) } } -static void setup_timer_hardware(void) -{ - outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ - udelay(10); - outb_p(LATCH & 0xff , 0x40); /* LSB */ - udelay(10); - outb(LATCH >> 8 , 0x40); /* MSB */ -} - -static int timer_resume(struct sys_device *dev) -{ - setup_timer_hardware(); - return 0; -} - -void i8254_timer_resume(void) -{ - setup_timer_hardware(); -} - -static struct sysdev_class timer_sysclass = { - set_kset_name("timer_pit"), - .resume = timer_resume, -}; - -static struct sys_device device_timer = { - .id = 0, - .cls = &timer_sysclass, -}; - -static int __init init_timer_sysfs(void) -{ - int error = sysdev_class_register(&timer_sysclass); - if (!error) - error = sysdev_register(&device_timer); - return error; -} - -device_initcall(init_timer_sysfs); - void __init init_IRQ(void) { int i; @@ -533,12 +493,6 @@ void __init init_IRQ(void) set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); - /* - * Set the clock to HZ Hz, we already have a valid - * vector now: - */ - setup_timer_hardware(); - if (!acpi_ioapic) setup_irq(2, &irq2); } diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index e2f4a1c68547..4ee1e5ee9b57 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c @@ -378,7 +378,7 @@ static struct irq_cpu_info { #define IRQ_ALLOWED(cpu, allowed_mask) cpu_isset(cpu, allowed_mask) -#define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i])) +#define CPU_TO_PACKAGEINDEX(i) (first_cpu(per_cpu(cpu_sibling_map, i))) static cpumask_t balance_irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL @@ -598,7 +598,7 @@ tryanotherirq: * (A+B)/2 vs B */ load = CPU_IRQ(min_loaded) >> 1; - for_each_cpu_mask(j, cpu_sibling_map[min_loaded]) { + for_each_cpu_mask(j, per_cpu(cpu_sibling_map, min_loaded)) { if (load > CPU_IRQ(j)) { /* This won't change cpu_sibling_map[min_loaded] */ load = CPU_IRQ(j); diff --git a/arch/x86/kernel/ioport_32.c b/arch/x86/kernel/ioport_32.c index 3d310a946d76..4ed48dc8df1e 100644 --- a/arch/x86/kernel/ioport_32.c +++ b/arch/x86/kernel/ioport_32.c @@ -1,6 +1,4 @@ /* - * linux/arch/i386/kernel/ioport.c - * * This contains the io-permission bitmap code - written by obz, with changes * by Linus. */ diff --git a/arch/x86/kernel/ioport_64.c b/arch/x86/kernel/ioport_64.c index 653efa30b0f4..5f62fad64dab 100644 --- a/arch/x86/kernel/ioport_64.c +++ b/arch/x86/kernel/ioport_64.c @@ -1,6 +1,4 @@ /* - * linux/arch/x86_64/kernel/ioport.c - * * This contains the io-permission bitmap code - written by obz, with changes * by Linus. */ diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index 4f681bcdb1fc..e173b763f148 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -1,6 +1,4 @@ /* - * linux/arch/i386/kernel/irq.c - * * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar * * This file contains the lowest level x86-specific interrupt diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c index bd11e42b22bf..865669efc540 100644 --- a/arch/x86/kernel/irq_64.c +++ b/arch/x86/kernel/irq_64.c @@ -1,6 +1,4 @@ /* - * linux/arch/x86_64/kernel/irq.c - * * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar * * This file contains the lowest level x86_64-specific interrupt diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c index 448a50b1324c..90f778c04b3f 100644 --- a/arch/x86/kernel/kprobes_32.c +++ b/arch/x86/kernel/kprobes_32.c @@ -1,6 +1,5 @@ /* * Kernel Probes (KProbes) - * arch/i386/kernel/kprobes.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,6 +41,13 @@ void jprobe_return_end(void); DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); +struct kretprobe_blackpoint kretprobe_blacklist[] = { + {"__switch_to", }, /* This function switches only current task, but + doesn't switch kernel stack.*/ + {NULL, NULL} /* Terminator */ +}; +const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist); + /* insert a jmp code */ static __always_inline void set_jmp_op(void *from, void *to) { @@ -558,6 +564,12 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs) resume_execution(cur, regs, kcb); regs->eflags |= kcb->kprobe_saved_eflags; +#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT + if (raw_irqs_disabled_flags(regs->eflags)) + trace_hardirqs_off(); + else + trace_hardirqs_on(); +#endif /*Restore back the original saved kprobes variables and continue. */ if (kcb->kprobe_status == KPROBE_REENTER) { @@ -579,7 +591,7 @@ out: return 1; } -static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) +int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); @@ -661,7 +673,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, ret = NOTIFY_STOP; break; case DIE_GPF: - case DIE_PAGE_FAULT: /* kprobe_running() needs smp_processor_id() */ preempt_disable(); if (kprobe_running() && @@ -695,6 +706,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr, MIN_STACK_SIZE(addr)); regs->eflags &= ~IF_MASK; + trace_hardirqs_off(); regs->eip = (unsigned long)(jp->entry); return 1; } diff --git a/arch/x86/kernel/kprobes_64.c b/arch/x86/kernel/kprobes_64.c index a30e004682e2..681b801c5e26 100644 --- a/arch/x86/kernel/kprobes_64.c +++ b/arch/x86/kernel/kprobes_64.c @@ -1,6 +1,5 @@ /* * Kernel Probes (KProbes) - * arch/x86_64/kernel/kprobes.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -49,6 +48,13 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p); DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); +struct kretprobe_blackpoint kretprobe_blacklist[] = { + {"__switch_to", }, /* This function switches only current task, but + doesn't switch kernel stack.*/ + {NULL, NULL} /* Terminator */ +}; +const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist); + /* * returns non-zero if opcode modifies the interrupt flag. */ @@ -545,6 +551,12 @@ int __kprobes post_kprobe_handler(struct pt_regs *regs) resume_execution(cur, regs, kcb); regs->eflags |= kcb->kprobe_saved_rflags; +#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT + if (raw_irqs_disabled_flags(regs->eflags)) + trace_hardirqs_off(); + else + trace_hardirqs_on(); +#endif /* Restore the original saved kprobes variables and continue. */ if (kcb->kprobe_status == KPROBE_REENTER) { @@ -652,7 +664,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, ret = NOTIFY_STOP; break; case DIE_GPF: - case DIE_PAGE_FAULT: /* kprobe_running() needs smp_processor_id() */ preempt_disable(); if (kprobe_running() && @@ -685,6 +696,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr, MIN_STACK_SIZE(addr)); regs->eflags &= ~IF_MASK; + trace_hardirqs_off(); regs->rip = (unsigned long)(jp->entry); return 1; } diff --git a/arch/x86/kernel/ldt_32.c b/arch/x86/kernel/ldt_32.c index e0b2d17f4f10..a8b18421863a 100644 --- a/arch/x86/kernel/ldt_32.c +++ b/arch/x86/kernel/ldt_32.c @@ -1,6 +1,4 @@ /* - * linux/arch/i386/kernel/ldt.c - * * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com> */ diff --git a/arch/x86/kernel/ldt_64.c b/arch/x86/kernel/ldt_64.c index bc9ffd5c19cc..3796523d616a 100644 --- a/arch/x86/kernel/ldt_64.c +++ b/arch/x86/kernel/ldt_64.c @@ -1,6 +1,4 @@ /* - * linux/arch/x86_64/kernel/ldt.c - * * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com> * Copyright (C) 2002 Andi Kleen diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 91966bafb3dc..deda9a221cf2 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c @@ -1,5 +1,5 @@ /* - * machine_kexec.c - handle transition of Linux booting another kernel + * handle transition of Linux booting another kernel * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com> * * This source code is licensed under the GNU General Public License, diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index c3a554703672..cd1899a2f0c5 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -1,5 +1,5 @@ /* - * machine_kexec.c - handle transition of Linux booting another kernel + * handle transition of Linux booting another kernel * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com> * * This source code is licensed under the GNU General Public License, diff --git a/arch/x86/kernel/mca_32.c b/arch/x86/kernel/mca_32.c index b83672b89527..9482033ed0fe 100644 --- a/arch/x86/kernel/mca_32.c +++ b/arch/x86/kernel/mca_32.c @@ -1,5 +1,4 @@ /* - * linux/arch/i386/kernel/mca.c * Written by Martin Kolinek, February 1996 * * Changes: diff --git a/arch/x86/kernel/mce_amd_64.c b/arch/x86/kernel/mce_amd_64.c index 2f8a7f18b0fe..805b62b1e0df 100644 --- a/arch/x86/kernel/mce_amd_64.c +++ b/arch/x86/kernel/mce_amd_64.c @@ -472,7 +472,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) #ifdef CONFIG_SMP if (cpu_data[cpu].cpu_core_id && shared_bank[bank]) { /* symlink */ - i = first_cpu(cpu_core_map[cpu]); + i = first_cpu(per_cpu(cpu_core_map, cpu)); /* first core not up yet */ if (cpu_data[i].cpu_core_id) @@ -492,7 +492,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) if (err) goto out; - b->cpus = cpu_core_map[cpu]; + b->cpus = per_cpu(cpu_core_map, cpu); per_cpu(threshold_banks, cpu)[bank] = b; goto out; } @@ -509,7 +509,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) #ifndef CONFIG_SMP b->cpus = CPU_MASK_ALL; #else - b->cpus = cpu_core_map[cpu]; + b->cpus = per_cpu(cpu_core_map, cpu); #endif err = kobject_register(&b->kobj); if (err) diff --git a/arch/x86/kernel/mfgpt_32.c b/arch/x86/kernel/mfgpt_32.c new file mode 100644 index 000000000000..0ab680f2d9db --- /dev/null +++ b/arch/x86/kernel/mfgpt_32.c @@ -0,0 +1,362 @@ +/* + * Driver/API for AMD Geode Multi-Function General Purpose Timers (MFGPT) + * + * Copyright (C) 2006, Advanced Micro Devices, Inc. + * Copyright (C) 2007, Andres Salomon <dilinger@debian.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * The MFGPTs are documented in AMD Geode CS5536 Companion Device Data Book. + */ + +/* + * We are using the 32Khz input clock - its the only one that has the + * ranges we find desirable. The following table lists the suitable + * divisors and the associated hz, minimum interval + * and the maximum interval: + * + * Divisor Hz Min Delta (S) Max Delta (S) + * 1 32000 .0005 2.048 + * 2 16000 .001 4.096 + * 4 8000 .002 8.192 + * 8 4000 .004 16.384 + * 16 2000 .008 32.768 + * 32 1000 .016 65.536 + * 64 500 .032 131.072 + * 128 250 .064 262.144 + * 256 125 .128 524.288 + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <asm/geode.h> + +#define F_AVAIL 0x01 + +static struct mfgpt_timer_t { + int flags; + struct module *owner; +} mfgpt_timers[MFGPT_MAX_TIMERS]; + +/* Selected from the table above */ + +#define MFGPT_DIVISOR 16 +#define MFGPT_SCALE 4 /* divisor = 2^(scale) */ +#define MFGPT_HZ (32000 / MFGPT_DIVISOR) +#define MFGPT_PERIODIC (MFGPT_HZ / HZ) + +#ifdef CONFIG_GEODE_MFGPT_TIMER +static int __init mfgpt_timer_setup(void); +#else +#define mfgpt_timer_setup() (0) +#endif + +/* Allow for disabling of MFGPTs */ +static int disable; +static int __init mfgpt_disable(char *s) +{ + disable = 1; + return 1; +} +__setup("nomfgpt", mfgpt_disable); + +/* + * Check whether any MFGPTs are available for the kernel to use. In most + * cases, firmware that uses AMD's VSA code will claim all timers during + * bootup; we certainly don't want to take them if they're already in use. + * In other cases (such as with VSAless OpenFirmware), the system firmware + * leaves timers available for us to use. + */ +int __init geode_mfgpt_detect(void) +{ + int count = 0, i; + u16 val; + + if (disable) { + printk(KERN_INFO "geode-mfgpt: Skipping MFGPT setup\n"); + return 0; + } + + for (i = 0; i < MFGPT_MAX_TIMERS; i++) { + val = geode_mfgpt_read(i, MFGPT_REG_SETUP); + if (!(val & MFGPT_SETUP_SETUP)) { + mfgpt_timers[i].flags = F_AVAIL; + count++; + } + } + + /* set up clock event device, if desired */ + i = mfgpt_timer_setup(); + + return count; +} + +int geode_mfgpt_toggle_event(int timer, int cmp, int event, int enable) +{ + u32 msr, mask, value, dummy; + int shift = (cmp == MFGPT_CMP1) ? 0 : 8; + + if (timer < 0 || timer >= MFGPT_MAX_TIMERS) + return -EIO; + + /* + * The register maps for these are described in sections 6.17.1.x of + * the AMD Geode CS5536 Companion Device Data Book. + */ + switch (event) { + case MFGPT_EVENT_RESET: + /* + * XXX: According to the docs, we cannot reset timers above + * 6; that is, resets for 7 and 8 will be ignored. Is this + * a problem? -dilinger + */ + msr = MFGPT_NR_MSR; + mask = 1 << (timer + 24); + break; + + case MFGPT_EVENT_NMI: + msr = MFGPT_NR_MSR; + mask = 1 << (timer + shift); + break; + + case MFGPT_EVENT_IRQ: + msr = MFGPT_IRQ_MSR; + mask = 1 << (timer + shift); + break; + + default: + return -EIO; + } + + rdmsr(msr, value, dummy); + + if (enable) + value |= mask; + else + value &= ~mask; + + wrmsr(msr, value, dummy); + return 0; +} + +int geode_mfgpt_set_irq(int timer, int cmp, int irq, int enable) +{ + u32 val, dummy; + int offset; + + if (timer < 0 || timer >= MFGPT_MAX_TIMERS) + return -EIO; + + if (geode_mfgpt_toggle_event(timer, cmp, MFGPT_EVENT_IRQ, enable)) + return -EIO; + + rdmsr(MSR_PIC_ZSEL_LOW, val, dummy); + + offset = (timer % 4) * 4; + + val &= ~((0xF << offset) | (0xF << (offset + 16))); + + if (enable) { + val |= (irq & 0x0F) << (offset); + val |= (irq & 0x0F) << (offset + 16); + } + + wrmsr(MSR_PIC_ZSEL_LOW, val, dummy); + return 0; +} + +static int mfgpt_get(int timer, struct module *owner) +{ + mfgpt_timers[timer].flags &= ~F_AVAIL; + mfgpt_timers[timer].owner = owner; + printk(KERN_INFO "geode-mfgpt: Registered timer %d\n", timer); + return timer; +} + +int geode_mfgpt_alloc_timer(int timer, int domain, struct module *owner) +{ + int i; + + if (!geode_get_dev_base(GEODE_DEV_MFGPT)) + return -ENODEV; + if (timer >= MFGPT_MAX_TIMERS) + return -EIO; + + if (timer < 0) { + /* Try to find an available timer */ + for (i = 0; i < MFGPT_MAX_TIMERS; i++) { + if (mfgpt_timers[i].flags & F_AVAIL) + return mfgpt_get(i, owner); + + if (i == 5 && domain == MFGPT_DOMAIN_WORKING) + break; + } + } else { + /* If they requested a specific timer, try to honor that */ + if (mfgpt_timers[timer].flags & F_AVAIL) + return mfgpt_get(timer, owner); + } + + /* No timers available - too bad */ + return -1; +} + + +#ifdef CONFIG_GEODE_MFGPT_TIMER + +/* + * The MFPGT timers on the CS5536 provide us with suitable timers to use + * as clock event sources - not as good as a HPET or APIC, but certainly + * better then the PIT. This isn't a general purpose MFGPT driver, but + * a simplified one designed specifically to act as a clock event source. + * For full details about the MFGPT, please consult the CS5536 data sheet. + */ + +#include <linux/clocksource.h> +#include <linux/clockchips.h> + +static unsigned int mfgpt_tick_mode = CLOCK_EVT_MODE_SHUTDOWN; +static u16 mfgpt_event_clock; + +static int irq = 7; +static int __init mfgpt_setup(char *str) +{ + get_option(&str, &irq); + return 1; +} +__setup("mfgpt_irq=", mfgpt_setup); + +static inline void mfgpt_disable_timer(u16 clock) +{ + u16 val = geode_mfgpt_read(clock, MFGPT_REG_SETUP); + geode_mfgpt_write(clock, MFGPT_REG_SETUP, val & ~MFGPT_SETUP_CNTEN); +} + +static int mfgpt_next_event(unsigned long, struct clock_event_device *); +static void mfgpt_set_mode(enum clock_event_mode, struct clock_event_device *); + +static struct clock_event_device mfgpt_clockevent = { + .name = "mfgpt-timer", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_mode = mfgpt_set_mode, + .set_next_event = mfgpt_next_event, + .rating = 250, + .cpumask = CPU_MASK_ALL, + .shift = 32 +}; + +static inline void mfgpt_start_timer(u16 clock, u16 delta) +{ + geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_CMP2, (u16) delta); + geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_COUNTER, 0); + + geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP, + MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2); +} + +static void mfgpt_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + mfgpt_disable_timer(mfgpt_event_clock); + + if (mode == CLOCK_EVT_MODE_PERIODIC) + mfgpt_start_timer(mfgpt_event_clock, MFGPT_PERIODIC); + + mfgpt_tick_mode = mode; +} + +static int mfgpt_next_event(unsigned long delta, struct clock_event_device *evt) +{ + mfgpt_start_timer(mfgpt_event_clock, delta); + return 0; +} + +/* Assume (foolishly?), that this interrupt was due to our tick */ + +static irqreturn_t mfgpt_tick(int irq, void *dev_id) +{ + if (mfgpt_tick_mode == CLOCK_EVT_MODE_SHUTDOWN) + return IRQ_HANDLED; + + /* Turn off the clock */ + mfgpt_disable_timer(mfgpt_event_clock); + + /* Clear the counter */ + geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_COUNTER, 0); + + /* Restart the clock in periodic mode */ + + if (mfgpt_tick_mode == CLOCK_EVT_MODE_PERIODIC) { + geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP, + MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2); + } + + mfgpt_clockevent.event_handler(&mfgpt_clockevent); + return IRQ_HANDLED; +} + +static struct irqaction mfgptirq = { + .handler = mfgpt_tick, + .flags = IRQF_DISABLED | IRQF_NOBALANCING, + .mask = CPU_MASK_NONE, + .name = "mfgpt-timer" +}; + +static int __init mfgpt_timer_setup(void) +{ + int timer, ret; + u16 val; + + timer = geode_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING, + THIS_MODULE); + if (timer < 0) { + printk(KERN_ERR + "mfgpt-timer: Could not allocate a MFPGT timer\n"); + return -ENODEV; + } + + mfgpt_event_clock = timer; + /* Set the clock scale and enable the event mode for CMP2 */ + val = MFGPT_SCALE | (3 << 8); + + geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP, val); + + /* Set up the IRQ on the MFGPT side */ + if (geode_mfgpt_setup_irq(mfgpt_event_clock, MFGPT_CMP2, irq)) { + printk(KERN_ERR "mfgpt-timer: Could not set up IRQ %d\n", irq); + return -EIO; + } + + /* And register it with the kernel */ + ret = setup_irq(irq, &mfgptirq); + + if (ret) { + printk(KERN_ERR + "mfgpt-timer: Unable to set up the interrupt.\n"); + goto err; + } + + /* Set up the clock event */ + mfgpt_clockevent.mult = div_sc(MFGPT_HZ, NSEC_PER_SEC, 32); + mfgpt_clockevent.min_delta_ns = clockevent_delta2ns(0xF, + &mfgpt_clockevent); + mfgpt_clockevent.max_delta_ns = clockevent_delta2ns(0xFFFE, + &mfgpt_clockevent); + + printk(KERN_INFO + "mfgpt-timer: registering the MFGT timer as a clock event.\n"); + clockevents_register_device(&mfgpt_clockevent); + + return 0; + +err: + geode_mfgpt_release_irq(mfgpt_event_clock, MFGPT_CMP2, irq); + printk(KERN_ERR + "mfgpt-timer: Unable to set up the MFGPT clock source\n"); + return -EIO; +} + +#endif diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 0c1069b8d638..c044de310b69 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -11,8 +11,6 @@ * ----------------------------------------------------------------------- */ /* - * msr.c - * * x86 MSR access device * * This device is accessed by lseek() to the appropriate register number diff --git a/arch/x86/kernel/nmi_32.c b/arch/x86/kernel/nmi_32.c index c7227e2180f8..f803ed0ed1c4 100644 --- a/arch/x86/kernel/nmi_32.c +++ b/arch/x86/kernel/nmi_32.c @@ -1,6 +1,4 @@ /* - * linux/arch/i386/nmi.c - * * NMI watchdog support on APIC systems * * Started by Ingo Molnar <mingo@redhat.com> @@ -353,7 +351,8 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) * Take the local apic timer and PIT/HPET into account. We don't * know which one is active, when we have highres/dyntick on */ - sum = per_cpu(irq_stat, cpu).apic_timer_irqs + kstat_cpu(cpu).irqs[0]; + sum = per_cpu(irq_stat, cpu).apic_timer_irqs + + per_cpu(irq_stat, cpu).irq0_irqs; /* if the none of the timers isn't firing, this cpu isn't doing much */ if (!touched && last_irq_sums[cpu] == sum) { diff --git a/arch/x86/kernel/nmi_64.c b/arch/x86/kernel/nmi_64.c index 0ec6d2ddb931..a576fd740062 100644 --- a/arch/x86/kernel/nmi_64.c +++ b/arch/x86/kernel/nmi_64.c @@ -1,6 +1,4 @@ /* - * linux/arch/x86_64/nmi.c - * * NMI watchdog support on APIC systems * * Started by Ingo Molnar <mingo@redhat.com> @@ -329,7 +327,7 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) touched = 1; } - sum = read_pda(apic_timer_irqs); + sum = read_pda(apic_timer_irqs) + read_pda(irq0_irqs); if (__get_cpu_var(nmi_touch)) { __get_cpu_var(nmi_touch) = 0; touched = 1; diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 71da01e73f03..a50b787b3bfa 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -35,6 +35,7 @@ #include <linux/pci_ids.h> #include <linux/pci.h> #include <linux/delay.h> +#include <linux/scatterlist.h> #include <asm/iommu.h> #include <asm/calgary.h> #include <asm/tce.h> @@ -384,31 +385,32 @@ static void calgary_unmap_sg(struct device *dev, struct scatterlist *sglist, int nelems, int direction) { struct iommu_table *tbl = find_iommu_table(dev); + struct scatterlist *s; + int i; if (!translate_phb(to_pci_dev(dev))) return; - while (nelems--) { + for_each_sg(sglist, s, nelems, i) { unsigned int npages; - dma_addr_t dma = sglist->dma_address; - unsigned int dmalen = sglist->dma_length; + dma_addr_t dma = s->dma_address; + unsigned int dmalen = s->dma_length; if (dmalen == 0) break; npages = num_dma_pages(dma, dmalen); iommu_free(tbl, dma, npages); - sglist++; } } static int calgary_nontranslate_map_sg(struct device* dev, struct scatterlist *sg, int nelems, int direction) { + struct scatterlist *s; int i; - for (i = 0; i < nelems; i++ ) { - struct scatterlist *s = &sg[i]; + for_each_sg(sg, s, nelems, i) { BUG_ON(!s->page); s->dma_address = virt_to_bus(page_address(s->page) +s->offset); s->dma_length = s->length; @@ -420,6 +422,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, int nelems, int direction) { struct iommu_table *tbl = find_iommu_table(dev); + struct scatterlist *s; unsigned long vaddr; unsigned int npages; unsigned long entry; @@ -428,8 +431,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, if (!translate_phb(to_pci_dev(dev))) return calgary_nontranslate_map_sg(dev, sg, nelems, direction); - for (i = 0; i < nelems; i++ ) { - struct scatterlist *s = &sg[i]; + for_each_sg(sg, s, nelems, i) { BUG_ON(!s->page); vaddr = (unsigned long)page_address(s->page) + s->offset; @@ -454,9 +456,9 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, return nelems; error: calgary_unmap_sg(dev, sg, nelems, direction); - for (i = 0; i < nelems; i++) { - sg[i].dma_address = bad_dma_address; - sg[i].dma_length = 0; + for_each_sg(sg, s, nelems, i) { + sg->dma_address = bad_dma_address; + sg->dma_length = 0; } return 0; } diff --git a/arch/x86/kernel/pci-dma_32.c b/arch/x86/kernel/pci-dma_32.c index 048f09b62553..0aae2f3847a5 100644 --- a/arch/x86/kernel/pci-dma_32.c +++ b/arch/x86/kernel/pci-dma_32.c @@ -63,7 +63,8 @@ void dma_free_coherent(struct device *dev, size_t size, { struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; int order = get_order(size); - + + WARN_ON(irqs_disabled()); /* for portability */ if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) { int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; diff --git a/arch/x86/kernel/pci-dma_64.c b/arch/x86/kernel/pci-dma_64.c index 29711445c818..9576a2eb375e 100644 --- a/arch/x86/kernel/pci-dma_64.c +++ b/arch/x86/kernel/pci-dma_64.c @@ -167,6 +167,7 @@ EXPORT_SYMBOL(dma_alloc_coherent); void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t bus) { + WARN_ON(irqs_disabled()); /* for portability */ if (dma_ops->unmap_single) dma_ops->unmap_single(dev, bus, size, 0); free_pages((unsigned long)vaddr, get_order(size)); diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index 4918c575d582..cfcc84e6c350 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -23,6 +23,7 @@ #include <linux/interrupt.h> #include <linux/bitops.h> #include <linux/kdebug.h> +#include <linux/scatterlist.h> #include <asm/atomic.h> #include <asm/io.h> #include <asm/mtrr.h> @@ -278,10 +279,10 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, */ static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) { + struct scatterlist *s; int i; - for (i = 0; i < nents; i++) { - struct scatterlist *s = &sg[i]; + for_each_sg(sg, s, nents, i) { if (!s->dma_length || !s->length) break; gart_unmap_single(dev, s->dma_address, s->dma_length, dir); @@ -292,14 +293,14 @@ static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, int nents, int dir) { + struct scatterlist *s; int i; #ifdef CONFIG_IOMMU_DEBUG printk(KERN_DEBUG "dma_map_sg overflow\n"); #endif - for (i = 0; i < nents; i++ ) { - struct scatterlist *s = &sg[i]; + for_each_sg(sg, s, nents, i) { unsigned long addr = page_to_phys(s->page) + s->offset; if (nonforced_iommu(dev, addr, s->length)) { addr = dma_map_area(dev, addr, s->length, dir); @@ -319,23 +320,23 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, } /* Map multiple scatterlist entries continuous into the first. */ -static int __dma_map_cont(struct scatterlist *sg, int start, int stopat, +static int __dma_map_cont(struct scatterlist *start, int nelems, struct scatterlist *sout, unsigned long pages) { unsigned long iommu_start = alloc_iommu(pages); unsigned long iommu_page = iommu_start; + struct scatterlist *s; int i; if (iommu_start == -1) return -1; - - for (i = start; i < stopat; i++) { - struct scatterlist *s = &sg[i]; + + for_each_sg(start, s, nelems, i) { unsigned long pages, addr; unsigned long phys_addr = s->dma_address; - BUG_ON(i > start && s->offset); - if (i == start) { + BUG_ON(s != start && s->offset); + if (s == start) { *sout = *s; sout->dma_address = iommu_bus_base; sout->dma_address += iommu_page*PAGE_SIZE + s->offset; @@ -357,17 +358,17 @@ static int __dma_map_cont(struct scatterlist *sg, int start, int stopat, return 0; } -static inline int dma_map_cont(struct scatterlist *sg, int start, int stopat, +static inline int dma_map_cont(struct scatterlist *start, int nelems, struct scatterlist *sout, unsigned long pages, int need) { - if (!need) { - BUG_ON(stopat - start != 1); - *sout = sg[start]; - sout->dma_length = sg[start].length; + if (!need) { + BUG_ON(nelems != 1); + *sout = *start; + sout->dma_length = start->length; return 0; - } - return __dma_map_cont(sg, start, stopat, sout, pages); + } + return __dma_map_cont(start, nelems, sout, pages); } /* @@ -381,6 +382,7 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) int start; unsigned long pages = 0; int need = 0, nextneed; + struct scatterlist *s, *ps, *start_sg, *sgmap; if (nents == 0) return 0; @@ -390,8 +392,9 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) out = 0; start = 0; - for (i = 0; i < nents; i++) { - struct scatterlist *s = &sg[i]; + start_sg = sgmap = sg; + ps = NULL; /* shut up gcc */ + for_each_sg(sg, s, nents, i) { dma_addr_t addr = page_to_phys(s->page) + s->offset; s->dma_address = addr; BUG_ON(s->length == 0); @@ -400,29 +403,33 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) /* Handle the previous not yet processed entries */ if (i > start) { - struct scatterlist *ps = &sg[i-1]; /* Can only merge when the last chunk ends on a page boundary and the new one doesn't have an offset. */ if (!iommu_merge || !nextneed || !need || s->offset || - (ps->offset + ps->length) % PAGE_SIZE) { - if (dma_map_cont(sg, start, i, sg+out, pages, - need) < 0) + (ps->offset + ps->length) % PAGE_SIZE) { + if (dma_map_cont(start_sg, i - start, sgmap, + pages, need) < 0) goto error; out++; + sgmap = sg_next(sgmap); pages = 0; - start = i; + start = i; + start_sg = s; } } need = nextneed; pages += to_pages(s->offset, s->length); + ps = s; } - if (dma_map_cont(sg, start, i, sg+out, pages, need) < 0) + if (dma_map_cont(start_sg, i - start, sgmap, pages, need) < 0) goto error; out++; flush_gart(); - if (out < nents) - sg[out].dma_length = 0; + if (out < nents) { + sgmap = sg_next(sgmap); + sgmap->dma_length = 0; + } return out; error: @@ -437,8 +444,8 @@ error: if (panic_on_overflow) panic("dma_map_sg: overflow on %lu pages\n", pages); iommu_full(dev, pages << PAGE_SHIFT, dir); - for (i = 0; i < nents; i++) - sg[i].dma_address = bad_dma_address; + for_each_sg(sg, s, nents, i) + s->dma_address = bad_dma_address; return 0; } diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c index 2a34c6c025a9..e85d4360360c 100644 --- a/arch/x86/kernel/pci-nommu_64.c +++ b/arch/x86/kernel/pci-nommu_64.c @@ -5,6 +5,7 @@ #include <linux/pci.h> #include <linux/string.h> #include <linux/dma-mapping.h> +#include <linux/scatterlist.h> #include <asm/iommu.h> #include <asm/processor.h> @@ -57,10 +58,10 @@ static void nommu_unmap_single(struct device *dev, dma_addr_t addr,size_t size, static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction) { + struct scatterlist *s; int i; - for (i = 0; i < nents; i++ ) { - struct scatterlist *s = &sg[i]; + for_each_sg(sg, s, nents, i) { BUG_ON(!s->page); s->dma_address = virt_to_bus(page_address(s->page) +s->offset); if (!check_addr("map_sg", hwdev, s->dma_address, s->length)) diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 84664710b784..097aeafce5ff 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -1,6 +1,4 @@ /* - * linux/arch/i386/kernel/process.c - * * Copyright (C) 1995 Linus Torvalds * * Pentium III FXSR, SSE support diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 98956555450b..6309b275cb9c 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -1,6 +1,4 @@ /* - * linux/arch/x86-64/kernel/process.c - * * Copyright (C) 1995 Linus Torvalds * * Pentium III FXSR, SSE support @@ -38,6 +36,7 @@ #include <linux/notifier.h> #include <linux/kprobes.h> #include <linux/kdebug.h> +#include <linux/tick.h> #include <asm/uaccess.h> #include <asm/pgtable.h> @@ -208,6 +207,8 @@ void cpu_idle (void) if (__get_cpu_var(cpu_idle_state)) __get_cpu_var(cpu_idle_state) = 0; + tick_nohz_stop_sched_tick(); + rmb(); idle = pm_idle; if (!idle) @@ -228,6 +229,7 @@ void cpu_idle (void) __exit_idle(); } + tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); schedule(); preempt_disable(); @@ -579,7 +581,7 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, * * Kprobes not supported here. Set the probe on schedule instead. */ -__kprobes struct task_struct * +struct task_struct * __switch_to(struct task_struct *prev_p, struct task_struct *next_p) { struct thread_struct *prev = &prev_p->thread, diff --git a/arch/x86/kernel/ptrace_32.c b/arch/x86/kernel/ptrace_32.c index 7c1b92522e95..8622b9cd3e38 100644 --- a/arch/x86/kernel/ptrace_32.c +++ b/arch/x86/kernel/ptrace_32.c @@ -1,4 +1,3 @@ -/* ptrace.c */ /* By Ross Biro 1/23/92 */ /* * Pentium III FXSR, SSE support @@ -525,11 +524,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = 0; break; - case PTRACE_DETACH: - /* detach a process that was attached. */ - ret = ptrace_detach(child, data); - break; - case PTRACE_GETREGS: { /* Get all gp regs from the child. */ if (!access_ok(VERIFY_WRITE, datap, FRAME_SIZE*sizeof(long))) { ret = -EIO; diff --git a/arch/x86/kernel/ptrace_64.c b/arch/x86/kernel/ptrace_64.c index eea3702427b4..86321ee6da93 100644 --- a/arch/x86/kernel/ptrace_64.c +++ b/arch/x86/kernel/ptrace_64.c @@ -1,4 +1,3 @@ -/* ptrace.c */ /* By Ross Biro 1/23/92 */ /* * Pentium III FXSR, SSE support @@ -501,11 +500,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = 0; break; - case PTRACE_DETACH: - /* detach a process that was attached. */ - ret = ptrace_detach(child, data); - break; - case PTRACE_GETREGS: { /* Get all gp regs from the child. */ if (!access_ok(VERIFY_WRITE, (unsigned __user *)data, sizeof(struct user_regs_struct))) { diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 6722469c2633..d769e204f942 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c @@ -4,6 +4,8 @@ #include <linux/pci.h> #include <linux/irq.h> +#include <asm/hpet.h> + #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI) static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) @@ -47,3 +49,206 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quir DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance); #endif + +#if defined(CONFIG_HPET_TIMER) +unsigned long force_hpet_address; + +static enum { + NONE_FORCE_HPET_RESUME, + OLD_ICH_FORCE_HPET_RESUME, + ICH_FORCE_HPET_RESUME +} force_hpet_resume_type; + +static void __iomem *rcba_base; + +static void ich_force_hpet_resume(void) +{ + u32 val; + + if (!force_hpet_address) + return; + + if (rcba_base == NULL) + BUG(); + + /* read the Function Disable register, dword mode only */ + val = readl(rcba_base + 0x3404); + if (!(val & 0x80)) { + /* HPET disabled in HPTC. Trying to enable */ + writel(val | 0x80, rcba_base + 0x3404); + } + + val = readl(rcba_base + 0x3404); + if (!(val & 0x80)) + BUG(); + else + printk(KERN_DEBUG "Force enabled HPET at resume\n"); + + return; +} + +static void ich_force_enable_hpet(struct pci_dev *dev) +{ + u32 val; + u32 uninitialized_var(rcba); + int err = 0; + + if (hpet_address || force_hpet_address) + return; + + pci_read_config_dword(dev, 0xF0, &rcba); + rcba &= 0xFFFFC000; + if (rcba == 0) { + printk(KERN_DEBUG "RCBA disabled. Cannot force enable HPET\n"); + return; + } + + /* use bits 31:14, 16 kB aligned */ + rcba_base = ioremap_nocache(rcba, 0x4000); + if (rcba_base == NULL) { + printk(KERN_DEBUG "ioremap failed. Cannot force enable HPET\n"); + return; + } + + /* read the Function Disable register, dword mode only */ + val = readl(rcba_base + 0x3404); + + if (val & 0x80) { + /* HPET is enabled in HPTC. Just not reported by BIOS */ + val = val & 0x3; + force_hpet_address = 0xFED00000 | (val << 12); + printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", + force_hpet_address); + iounmap(rcba_base); + return; + } + + /* HPET disabled in HPTC. Trying to enable */ + writel(val | 0x80, rcba_base + 0x3404); + + val = readl(rcba_base + 0x3404); + if (!(val & 0x80)) { + err = 1; + } else { + val = val & 0x3; + force_hpet_address = 0xFED00000 | (val << 12); + } + + if (err) { + force_hpet_address = 0; + iounmap(rcba_base); + printk(KERN_DEBUG "Failed to force enable HPET\n"); + } else { + force_hpet_resume_type = ICH_FORCE_HPET_RESUME; + printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", + force_hpet_address); + } +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, + ich_force_enable_hpet); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, + ich_force_enable_hpet); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, + ich_force_enable_hpet); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, + ich_force_enable_hpet); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, + ich_force_enable_hpet); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1, + ich_force_enable_hpet); + + +static struct pci_dev *cached_dev; + +static void old_ich_force_hpet_resume(void) +{ + u32 val; + u32 uninitialized_var(gen_cntl); + + if (!force_hpet_address || !cached_dev) + return; + + pci_read_config_dword(cached_dev, 0xD0, &gen_cntl); + gen_cntl &= (~(0x7 << 15)); + gen_cntl |= (0x4 << 15); + + pci_write_config_dword(cached_dev, 0xD0, gen_cntl); + pci_read_config_dword(cached_dev, 0xD0, &gen_cntl); + val = gen_cntl >> 15; + val &= 0x7; + if (val == 0x4) + printk(KERN_DEBUG "Force enabled HPET at resume\n"); + else + BUG(); +} + +static void old_ich_force_enable_hpet(struct pci_dev *dev) +{ + u32 val; + u32 uninitialized_var(gen_cntl); + + if (hpet_address || force_hpet_address) + return; + + pci_read_config_dword(dev, 0xD0, &gen_cntl); + /* + * Bit 17 is HPET enable bit. + * Bit 16:15 control the HPET base address. + */ + val = gen_cntl >> 15; + val &= 0x7; + if (val & 0x4) { + val &= 0x3; + force_hpet_address = 0xFED00000 | (val << 12); + printk(KERN_DEBUG "HPET at base address 0x%lx\n", + force_hpet_address); + return; + } + + /* + * HPET is disabled. Trying enabling at FED00000 and check + * whether it sticks + */ + gen_cntl &= (~(0x7 << 15)); + gen_cntl |= (0x4 << 15); + pci_write_config_dword(dev, 0xD0, gen_cntl); + + pci_read_config_dword(dev, 0xD0, &gen_cntl); + + val = gen_cntl >> 15; + val &= 0x7; + if (val & 0x4) { + /* HPET is enabled in HPTC. Just not reported by BIOS */ + val &= 0x3; + force_hpet_address = 0xFED00000 | (val << 12); + printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", + force_hpet_address); + cached_dev = dev; + force_hpet_resume_type = OLD_ICH_FORCE_HPET_RESUME; + return; + } + + printk(KERN_DEBUG "Failed to force enable HPET\n"); +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, + old_ich_force_enable_hpet); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12, + old_ich_force_enable_hpet); + +void force_hpet_resume(void) +{ + switch (force_hpet_resume_type) { + case ICH_FORCE_HPET_RESUME: + return ich_force_hpet_resume(); + + case OLD_ICH_FORCE_HPET_RESUME: + return old_ich_force_hpet_resume(); + + default: + break; + } +} + +#endif diff --git a/arch/x86/kernel/reboot_32.c b/arch/x86/kernel/reboot_32.c index b37ed226830a..9e2269d00918 100644 --- a/arch/x86/kernel/reboot_32.c +++ b/arch/x86/kernel/reboot_32.c @@ -1,7 +1,3 @@ -/* - * linux/arch/i386/kernel/reboot.c - */ - #include <linux/mm.h> #include <linux/module.h> #include <linux/delay.h> diff --git a/arch/x86/kernel/reboot_fixups_32.c b/arch/x86/kernel/reboot_fixups_32.c index 03e1cce58f49..8b30b26ad069 100644 --- a/arch/x86/kernel/reboot_fixups_32.c +++ b/arch/x86/kernel/reboot_fixups_32.c @@ -1,6 +1,4 @@ /* - * linux/arch/i386/kernel/reboot_fixups.c - * * This is a good place to put board specific reboot fixups. * * List of supported fixups: @@ -11,6 +9,7 @@ #include <asm/delay.h> #include <linux/pci.h> +#include <linux/interrupt.h> #include <asm/reboot_fixups.h> #include <asm/msr.h> @@ -56,6 +55,11 @@ void mach_reboot_fixups(void) struct pci_dev *dev; int i; + /* we can be called from sysrq-B code. In such a case it is + * prohibited to dig PCI */ + if (in_interrupt()) + return; + for (i=0; i < ARRAY_SIZE(fixups_table); i++) { cur = &(fixups_table[i]); dev = pci_get_device(cur->vendor, cur->device, NULL); diff --git a/arch/x86/kernel/scx200_32.c b/arch/x86/kernel/scx200_32.c index c7d3df23f589..87bc159d29df 100644 --- a/arch/x86/kernel/scx200_32.c +++ b/arch/x86/kernel/scx200_32.c @@ -1,8 +1,8 @@ -/* linux/arch/i386/kernel/scx200.c - - Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> - - National Semiconductor SCx200 support. */ +/* + * Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> + * + * National Semiconductor SCx200 support. + */ #include <linux/module.h> #include <linux/errno.h> @@ -24,7 +24,7 @@ MODULE_DESCRIPTION("NatSemi SCx200 Driver"); MODULE_LICENSE("GPL"); unsigned scx200_gpio_base = 0; -long scx200_gpio_shadow[2]; +unsigned long scx200_gpio_shadow[2]; unsigned scx200_cb_base = 0; diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index d474cd639bcb..c8e1bc38d421 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -1,6 +1,4 @@ /* - * linux/arch/i386/kernel/setup.c - * * Copyright (C) 1995 Linus Torvalds * * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index af838f6b0b7f..85b5b6310acc 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c @@ -1,10 +1,5 @@ /* - * linux/arch/x86-64/kernel/setup.c - * * Copyright (C) 1995 Linus Torvalds - * - * Nov 2001 Dave Jones <davej@suse.de> - * Forked from i386 setup code. */ /* @@ -546,6 +541,37 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) #endif } +#define ENABLE_C1E_MASK 0x18000000 +#define CPUID_PROCESSOR_SIGNATURE 1 +#define CPUID_XFAM 0x0ff00000 +#define CPUID_XFAM_K8 0x00000000 +#define CPUID_XFAM_10H 0x00100000 +#define CPUID_XFAM_11H 0x00200000 +#define CPUID_XMOD 0x000f0000 +#define CPUID_XMOD_REV_F 0x00040000 + +/* AMD systems with C1E don't have a working lAPIC timer. Check for that. */ +static __cpuinit int amd_apic_timer_broken(void) +{ + u32 lo, hi; + u32 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); + switch (eax & CPUID_XFAM) { + case CPUID_XFAM_K8: + if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F) + break; + case CPUID_XFAM_10H: + case CPUID_XFAM_11H: + rdmsr(MSR_K8_ENABLE_C1E, lo, hi); + if (lo & ENABLE_C1E_MASK) + return 1; + break; + default: + /* err on the side of caution */ + return 1; + } + return 0; +} + static void __cpuinit init_amd(struct cpuinfo_x86 *c) { unsigned level; @@ -617,6 +643,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) /* Family 10 doesn't support C states in MWAIT so don't use it */ if (c->x86 == 0x10 && !force_mwait) clear_bit(X86_FEATURE_MWAIT, &c->x86_capability); + + if (amd_apic_timer_broken()) + disable_apic_timer = 1; } static void __cpuinit detect_ht(struct cpuinfo_x86 *c) @@ -1041,7 +1070,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (smp_num_siblings * c->x86_max_cores > 1) { int cpu = c - cpu_data; seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); - seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[cpu])); + seq_printf(m, "siblings\t: %d\n", + cpus_weight(per_cpu(cpu_core_map, cpu))); seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); } diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c index c03570f7fe8e..d01d51fcce2a 100644 --- a/arch/x86/kernel/signal_32.c +++ b/arch/x86/kernel/signal_32.c @@ -1,6 +1,4 @@ /* - * linux/arch/i386/kernel/signal.c - * * Copyright (C) 1991, 1992 Linus Torvalds * * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index 739175b01e06..683802bec419 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c @@ -1,6 +1,4 @@ /* - * linux/arch/x86_64/kernel/signal.c - * * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs * diff --git a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c index e4f61d1c6248..31fc08bd15ef 100644 --- a/arch/x86/kernel/smpboot_32.c +++ b/arch/x86/kernel/smpboot_32.c @@ -70,12 +70,12 @@ EXPORT_SYMBOL(smp_num_siblings); int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; /* representing HT siblings of each logical CPU */ -cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; -EXPORT_SYMBOL(cpu_sibling_map); +DEFINE_PER_CPU(cpumask_t, cpu_sibling_map); +EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); /* representing HT and core siblings of each logical CPU */ -cpumask_t cpu_core_map[NR_CPUS] __read_mostly; -EXPORT_SYMBOL(cpu_core_map); +DEFINE_PER_CPU(cpumask_t, cpu_core_map); +EXPORT_PER_CPU_SYMBOL(cpu_core_map); /* bitmap of online cpus */ cpumask_t cpu_online_map __read_mostly; @@ -300,7 +300,7 @@ cpumask_t cpu_coregroup_map(int cpu) * And for power savings, we return cpu_core_map */ if (sched_mc_power_savings || sched_smt_power_savings) - return cpu_core_map[cpu]; + return per_cpu(cpu_core_map, cpu); else return c->llc_shared_map; } @@ -319,22 +319,22 @@ void __cpuinit set_cpu_sibling_map(int cpu) for_each_cpu_mask(i, cpu_sibling_setup_map) { if (c[cpu].phys_proc_id == c[i].phys_proc_id && c[cpu].cpu_core_id == c[i].cpu_core_id) { - cpu_set(i, cpu_sibling_map[cpu]); - cpu_set(cpu, cpu_sibling_map[i]); - cpu_set(i, cpu_core_map[cpu]); - cpu_set(cpu, cpu_core_map[i]); + cpu_set(i, per_cpu(cpu_sibling_map, cpu)); + cpu_set(cpu, per_cpu(cpu_sibling_map, i)); + cpu_set(i, per_cpu(cpu_core_map, cpu)); + cpu_set(cpu, per_cpu(cpu_core_map, i)); cpu_set(i, c[cpu].llc_shared_map); cpu_set(cpu, c[i].llc_shared_map); } } } else { - cpu_set(cpu, cpu_sibling_map[cpu]); + cpu_set(cpu, per_cpu(cpu_sibling_map, cpu)); } cpu_set(cpu, c[cpu].llc_shared_map); if (current_cpu_data.x86_max_cores == 1) { - cpu_core_map[cpu] = cpu_sibling_map[cpu]; + per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu); c[cpu].booted_cores = 1; return; } @@ -346,17 +346,17 @@ void __cpuinit set_cpu_sibling_map(int cpu) cpu_set(cpu, c[i].llc_shared_map); } if (c[cpu].phys_proc_id == c[i].phys_proc_id) { - cpu_set(i, cpu_core_map[cpu]); - cpu_set(cpu, cpu_core_map[i]); + cpu_set(i, per_cpu(cpu_core_map, cpu)); + cpu_set(cpu, per_cpu(cpu_core_map, i)); /* * Does this new cpu bringup a new core? */ - if (cpus_weight(cpu_sibling_map[cpu]) == 1) { + if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) { /* * for each core in package, increment * the booted_cores for this new cpu */ - if (first_cpu(cpu_sibling_map[i]) == i) + if (first_cpu(per_cpu(cpu_sibling_map, i)) == i) c[cpu].booted_cores++; /* * increment the core count for all @@ -983,8 +983,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus) printk(KERN_NOTICE "Local APIC not detected." " Using dummy APIC emulation.\n"); map_cpu_to_logical_apicid(); - cpu_set(0, cpu_sibling_map[0]); - cpu_set(0, cpu_core_map[0]); + cpu_set(0, per_cpu(cpu_sibling_map, 0)); + cpu_set(0, per_cpu(cpu_core_map, 0)); return; } @@ -1008,8 +1008,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus) printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); smpboot_clear_io_apic_irqs(); phys_cpu_present_map = physid_mask_of_physid(0); - cpu_set(0, cpu_sibling_map[0]); - cpu_set(0, cpu_core_map[0]); + cpu_set(0, per_cpu(cpu_sibling_map, 0)); + cpu_set(0, per_cpu(cpu_core_map, 0)); return; } @@ -1023,8 +1023,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus) printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); smpboot_clear_io_apic_irqs(); phys_cpu_present_map = physid_mask_of_physid(0); - cpu_set(0, cpu_sibling_map[0]); - cpu_set(0, cpu_core_map[0]); + cpu_set(0, per_cpu(cpu_sibling_map, 0)); + cpu_set(0, per_cpu(cpu_core_map, 0)); return; } @@ -1102,16 +1102,16 @@ static void __init smp_boot_cpus(unsigned int max_cpus) Dprintk("Boot done.\n"); /* - * construct cpu_sibling_map[], so that we can tell sibling CPUs + * construct cpu_sibling_map, so that we can tell sibling CPUs * efficiently. */ for (cpu = 0; cpu < NR_CPUS; cpu++) { - cpus_clear(cpu_sibling_map[cpu]); - cpus_clear(cpu_core_map[cpu]); + cpus_clear(per_cpu(cpu_sibling_map, cpu)); + cpus_clear(per_cpu(cpu_core_map, cpu)); } - cpu_set(0, cpu_sibling_map[0]); - cpu_set(0, cpu_core_map[0]); + cpu_set(0, per_cpu(cpu_sibling_map, 0)); + cpu_set(0, per_cpu(cpu_core_map, 0)); smpboot_setup_io_apic(); @@ -1148,19 +1148,19 @@ void remove_siblinginfo(int cpu) int sibling; struct cpuinfo_x86 *c = cpu_data; - for_each_cpu_mask(sibling, cpu_core_map[cpu]) { - cpu_clear(cpu, cpu_core_map[sibling]); - /* + for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) { + cpu_clear(cpu, per_cpu(cpu_core_map, sibling)); + /*/ * last thread sibling in this cpu core going down */ - if (cpus_weight(cpu_sibling_map[cpu]) == 1) + if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) c[sibling].booted_cores--; } - for_each_cpu_mask(sibling, cpu_sibling_map[cpu]) - cpu_clear(cpu, cpu_sibling_map[sibling]); - cpus_clear(cpu_sibling_map[cpu]); - cpus_clear(cpu_core_map[cpu]); + for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu)) + cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling)); + cpus_clear(per_cpu(cpu_sibling_map, cpu)); + cpus_clear(per_cpu(cpu_core_map, cpu)); c[cpu].phys_proc_id = 0; c[cpu].cpu_core_id = 0; cpu_clear(cpu, cpu_sibling_setup_map); diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c index 32f50783edc8..0faa0a0af272 100644 --- a/arch/x86/kernel/smpboot_64.c +++ b/arch/x86/kernel/smpboot_64.c @@ -91,12 +91,12 @@ EXPORT_SYMBOL(cpu_data); int smp_threads_ready; /* representing HT siblings of each logical CPU */ -cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; -EXPORT_SYMBOL(cpu_sibling_map); +DEFINE_PER_CPU(cpumask_t, cpu_sibling_map); +EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); /* representing HT and core siblings of each logical CPU */ -cpumask_t cpu_core_map[NR_CPUS] __read_mostly; -EXPORT_SYMBOL(cpu_core_map); +DEFINE_PER_CPU(cpumask_t, cpu_core_map); +EXPORT_PER_CPU_SYMBOL(cpu_core_map); /* * Trampoline 80x86 program as an array. @@ -223,8 +223,6 @@ void __cpuinit smp_callin(void) local_irq_disable(); Dprintk("Stack at about %p\n",&cpuid); - disable_APIC_timer(); - /* * Save our processor parameters */ @@ -245,7 +243,7 @@ cpumask_t cpu_coregroup_map(int cpu) * And for power savings, we return cpu_core_map */ if (sched_mc_power_savings || sched_smt_power_savings) - return cpu_core_map[cpu]; + return per_cpu(cpu_core_map, cpu); else return c->llc_shared_map; } @@ -264,22 +262,22 @@ static inline void set_cpu_sibling_map(int cpu) for_each_cpu_mask(i, cpu_sibling_setup_map) { if (c[cpu].phys_proc_id == c[i].phys_proc_id && c[cpu].cpu_core_id == c[i].cpu_core_id) { - cpu_set(i, cpu_sibling_map[cpu]); - cpu_set(cpu, cpu_sibling_map[i]); - cpu_set(i, cpu_core_map[cpu]); - cpu_set(cpu, cpu_core_map[i]); + cpu_set(i, per_cpu(cpu_sibling_map, cpu)); + cpu_set(cpu, per_cpu(cpu_sibling_map, i)); + cpu_set(i, per_cpu(cpu_core_map, cpu)); + cpu_set(cpu, per_cpu(cpu_core_map, i)); cpu_set(i, c[cpu].llc_shared_map); cpu_set(cpu, c[i].llc_shared_map); } } } else { - cpu_set(cpu, cpu_sibling_map[cpu]); + cpu_set(cpu, per_cpu(cpu_sibling_map, cpu)); } cpu_set(cpu, c[cpu].llc_shared_map); if (current_cpu_data.x86_max_cores == 1) { - cpu_core_map[cpu] = cpu_sibling_map[cpu]; + per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu); c[cpu].booted_cores = 1; return; } @@ -291,17 +289,17 @@ static inline void set_cpu_sibling_map(int cpu) cpu_set(cpu, c[i].llc_shared_map); } if (c[cpu].phys_proc_id == c[i].phys_proc_id) { - cpu_set(i, cpu_core_map[cpu]); - cpu_set(cpu, cpu_core_map[i]); + cpu_set(i, per_cpu(cpu_core_map, cpu)); + cpu_set(cpu, per_cpu(cpu_core_map, i)); /* * Does this new cpu bringup a new core? */ - if (cpus_weight(cpu_sibling_map[cpu]) == 1) { + if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) { /* * for each core in package, increment * the booted_cores for this new cpu */ - if (first_cpu(cpu_sibling_map[i]) == i) + if (first_cpu(per_cpu(cpu_sibling_map, i)) == i) c[cpu].booted_cores++; /* * increment the core count for all @@ -337,19 +335,12 @@ void __cpuinit start_secondary(void) */ check_tsc_sync_target(); - Dprintk("cpu %d: setting up apic clock\n", smp_processor_id()); - setup_secondary_APIC_clock(); - - Dprintk("cpu %d: enabling apic timer\n", smp_processor_id()); - if (nmi_watchdog == NMI_IO_APIC) { disable_8259A_irq(0); enable_NMI_through_LVT0(NULL); enable_8259A_irq(0); } - enable_APIC_timer(); - /* * The sibling maps must be set before turing the online map on for * this cpu @@ -378,6 +369,8 @@ void __cpuinit start_secondary(void) unlock_ipi_call_lock(); + setup_secondary_APIC_clock(); + cpu_idle(); } @@ -742,8 +735,8 @@ static __init void disable_smp(void) phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id); else phys_cpu_present_map = physid_mask_of_physid(0); - cpu_set(0, cpu_sibling_map[0]); - cpu_set(0, cpu_core_map[0]); + cpu_set(0, per_cpu(cpu_sibling_map, 0)); + cpu_set(0, per_cpu(cpu_core_map, 0)); } #ifdef CONFIG_HOTPLUG_CPU @@ -978,19 +971,19 @@ static void remove_siblinginfo(int cpu) int sibling; struct cpuinfo_x86 *c = cpu_data; - for_each_cpu_mask(sibling, cpu_core_map[cpu]) { - cpu_clear(cpu, cpu_core_map[sibling]); + for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) { + cpu_clear(cpu, per_cpu(cpu_core_map, sibling)); /* * last thread sibling in this cpu core going down */ - if (cpus_weight(cpu_sibling_map[cpu]) == 1) + if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) c[sibling].booted_cores--; } - for_each_cpu_mask(sibling, cpu_sibling_map[cpu]) - cpu_clear(cpu, cpu_sibling_map[sibling]); - cpus_clear(cpu_sibling_map[cpu]); - cpus_clear(cpu_core_map[cpu]); + for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu)) + cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling)); + cpus_clear(per_cpu(cpu_sibling_map, cpu)); + cpus_clear(per_cpu(cpu_core_map, cpu)); c[cpu].phys_proc_id = 0; c[cpu].cpu_core_id = 0; cpu_clear(cpu, cpu_sibling_setup_map); diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c index cb9109113584..413e527cdeb9 100644 --- a/arch/x86/kernel/stacktrace.c +++ b/arch/x86/kernel/stacktrace.c @@ -1,6 +1,4 @@ /* - * arch/x86_64/kernel/stacktrace.c - * * Stack trace management functions * * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c index d0e01a3acf35..91c7acc8d999 100644 --- a/arch/x86/kernel/summit_32.c +++ b/arch/x86/kernel/summit_32.c @@ -1,5 +1,5 @@ /* - * arch/i386/kernel/summit.c - IBM Summit-Specific Code + * IBM Summit-Specific Code * * Written By: Matthew Dobson, IBM Corporation * diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c index 42147304de88..f8bae9ba0324 100644 --- a/arch/x86/kernel/sys_i386_32.c +++ b/arch/x86/kernel/sys_i386_32.c @@ -1,6 +1,4 @@ /* - * linux/arch/i386/kernel/sys_i386.c - * * This file contains various random system calls that * have a non-standard calling sequence on the Linux/i386 * platform. diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c index 4770b7a2052c..907942ee6e76 100644 --- a/arch/x86/kernel/sys_x86_64.c +++ b/arch/x86/kernel/sys_x86_64.c @@ -1,7 +1,3 @@ -/* - * linux/arch/x86_64/kernel/sys_x86_64.c - */ - #include <linux/errno.h> #include <linux/sched.h> #include <linux/syscalls.h> diff --git a/arch/x86/kernel/sysenter_32.c b/arch/x86/kernel/sysenter_32.c index 4eb2e408764f..5a2d951e2608 100644 --- a/arch/x86/kernel/sysenter_32.c +++ b/arch/x86/kernel/sysenter_32.c @@ -1,6 +1,4 @@ /* - * linux/arch/i386/kernel/sysenter.c - * * (C) Copyright 2002 Linus Torvalds * Portions based on the vdso-randomization code from exec-shield: * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar diff --git a/arch/x86/kernel/time_32.c b/arch/x86/kernel/time_32.c index 19a6c678d02e..8a322c96bc23 100644 --- a/arch/x86/kernel/time_32.c +++ b/arch/x86/kernel/time_32.c @@ -1,6 +1,4 @@ /* - * linux/arch/i386/kernel/time.c - * * Copyright (C) 1991, 1992, 1995 Linus Torvalds * * This file contains the PC-specific time handling details: @@ -157,6 +155,9 @@ EXPORT_SYMBOL(profile_pc); */ irqreturn_t timer_interrupt(int irq, void *dev_id) { + /* Keep nmi watchdog up to date */ + per_cpu(irq_stat, smp_processor_id()).irq0_irqs++; + #ifdef CONFIG_X86_IO_APIC if (timer_ack) { /* diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c index 6d48a4e826d9..c821edc32216 100644 --- a/arch/x86/kernel/time_64.c +++ b/arch/x86/kernel/time_64.c @@ -1,6 +1,4 @@ /* - * linux/arch/x86-64/kernel/time.c - * * "High Precision Event Timer" based timekeeping. * * Copyright (c) 1991,1992,1995 Linus Torvalds @@ -28,11 +26,12 @@ #include <linux/cpu.h> #include <linux/kallsyms.h> #include <linux/acpi.h> +#include <linux/clockchips.h> + #ifdef CONFIG_ACPI #include <acpi/achware.h> /* for PM timer frequency */ #include <acpi/acpi_bus.h> #endif -#include <asm/8253pit.h> #include <asm/i8253.h> #include <asm/pgtable.h> #include <asm/vsyscall.h> @@ -47,12 +46,8 @@ #include <asm/nmi.h> #include <asm/vgtod.h> -static char *timename = NULL; - DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); -DEFINE_SPINLOCK(i8253_lock); -EXPORT_SYMBOL(i8253_lock); volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES; @@ -153,45 +148,12 @@ int update_persistent_clock(struct timespec now) return set_rtc_mmss(now.tv_sec); } -void main_timer_handler(void) +static irqreturn_t timer_event_interrupt(int irq, void *dev_id) { -/* - * Here we are in the timer irq handler. We have irqs locally disabled (so we - * don't need spin_lock_irqsave()) but we don't know if the timer_bh is running - * on the other CPU, so we need a lock. We also need to lock the vsyscall - * variables, because both do_timer() and us change them -arca+vojtech - */ - - write_seqlock(&xtime_lock); - -/* - * Do the timer stuff. - */ + add_pda(irq0_irqs, 1); - do_timer(1); -#ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); -#endif - -/* - * In the SMP case we use the local APIC timer interrupt to do the profiling, - * except when we simulate SMP mode on a uniprocessor system, in that case we - * have to call the local interrupt handler. - */ - - if (!using_apic_timer) - smp_local_timer_interrupt(); + global_clock_event->event_handler(global_clock_event); - write_sequnlock(&xtime_lock); -} - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - if (apic_runs_main_timer > 1) - return IRQ_HANDLED; - main_timer_handler(); - if (using_apic_timer) - smp_send_timer_broadcast_ipi(); return IRQ_HANDLED; } @@ -292,97 +254,21 @@ static unsigned int __init tsc_calibrate_cpu_khz(void) return pmc_now * tsc_khz / (tsc_now - tsc_start); } -/* - * pit_calibrate_tsc() uses the speaker output (channel 2) of - * the PIT. This is better than using the timer interrupt output, - * because we can read the value of the speaker with just one inb(), - * where we need three i/o operations for the interrupt channel. - * We count how many ticks the TSC does in 50 ms. - */ - -static unsigned int __init pit_calibrate_tsc(void) -{ - unsigned long start, end; - unsigned long flags; - - spin_lock_irqsave(&i8253_lock, flags); - - outb((inb(0x61) & ~0x02) | 0x01, 0x61); - - outb(0xb0, 0x43); - outb((PIT_TICK_RATE / (1000 / 50)) & 0xff, 0x42); - outb((PIT_TICK_RATE / (1000 / 50)) >> 8, 0x42); - start = get_cycles_sync(); - while ((inb(0x61) & 0x20) == 0); - end = get_cycles_sync(); - - spin_unlock_irqrestore(&i8253_lock, flags); - - return (end - start) / 50; -} - -#define PIT_MODE 0x43 -#define PIT_CH0 0x40 - -static void __pit_init(int val, u8 mode) -{ - unsigned long flags; - - spin_lock_irqsave(&i8253_lock, flags); - outb_p(mode, PIT_MODE); - outb_p(val & 0xff, PIT_CH0); /* LSB */ - outb_p(val >> 8, PIT_CH0); /* MSB */ - spin_unlock_irqrestore(&i8253_lock, flags); -} - -void __init pit_init(void) -{ - __pit_init(LATCH, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */ -} - -void pit_stop_interrupt(void) -{ - __pit_init(0, 0x30); /* mode 0 */ -} - -void stop_timer_interrupt(void) -{ - char *name; - if (hpet_address) { - name = "HPET"; - hpet_timer_stop_set_go(0); - } else { - name = "PIT"; - pit_stop_interrupt(); - } - printk(KERN_INFO "timer: %s interrupt stopped.\n", name); -} - static struct irqaction irq0 = { - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_IRQPOLL, + .handler = timer_event_interrupt, + .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING, .mask = CPU_MASK_NONE, .name = "timer" }; void __init time_init(void) { - if (nohpet) - hpet_address = 0; + if (!hpet_enable()) + setup_pit_timer(); - if (hpet_arch_init()) - hpet_address = 0; + setup_irq(0, &irq0); - if (hpet_use_timer) { - /* set tick_nsec to use the proper rate for HPET */ - tick_nsec = TICK_NSEC_HPET; - tsc_khz = hpet_calibrate_tsc(); - timename = "HPET"; - } else { - pit_init(); - tsc_khz = pit_calibrate_tsc(); - timename = "PIT"; - } + tsc_calibrate(); cpu_khz = tsc_khz; if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) && @@ -398,50 +284,7 @@ void __init time_init(void) else vgetcpu_mode = VGETCPU_LSL; - set_cyc2ns_scale(tsc_khz); printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000); init_tsc_clocksource(); - - setup_irq(0, &irq0); -} - -/* - * sysfs support for the timer. - */ - -static int timer_suspend(struct sys_device *dev, pm_message_t state) -{ - return 0; -} - -static int timer_resume(struct sys_device *dev) -{ - if (hpet_address) - hpet_reenable(); - else - i8254_timer_resume(); - return 0; } - -static struct sysdev_class timer_sysclass = { - .resume = timer_resume, - .suspend = timer_suspend, - set_kset_name("timer"), -}; - -/* XXX this sysfs stuff should probably go elsewhere later -john */ -static struct sys_device device_timer = { - .id = 0, - .cls = &timer_sysclass, -}; - -static int time_init_device(void) -{ - int error = sysdev_class_register(&timer_sysclass); - if (!error) - error = sysdev_register(&device_timer); - return error; -} - -device_initcall(time_init_device); diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c index 45782356a618..c25f23eb397c 100644 --- a/arch/x86/kernel/topology.c +++ b/arch/x86/kernel/topology.c @@ -1,5 +1,5 @@ /* - * arch/i386/kernel/topology.c - Populate sysfs with topology information + * Populate sysfs with topology information * * Written by: Matthew Dobson, IBM Corporation * Original Code: Paul Dorwin, IBM Corporation, Patrick Mochel, OSDL diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index 47b0bef335bd..05c27ecaf2a7 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c @@ -1,6 +1,4 @@ /* - * linux/arch/i386/traps.c - * * Copyright (C) 1991, 1992 Linus Torvalds * * Pentium III FXSR, SSE support diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 03888420775d..bc7116acf8ff 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c @@ -1,6 +1,4 @@ /* - * linux/arch/x86-64/traps.c - * * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs * diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c index 3ed0ae8c918d..b85ad754f70e 100644 --- a/arch/x86/kernel/tsc_32.c +++ b/arch/x86/kernel/tsc_32.c @@ -1,9 +1,3 @@ -/* - * This code largely moved from arch/i386/kernel/timer/timer_tsc.c - * which was originally moved from arch/i386/kernel/time.c. - * See comments there for proper credits. - */ - #include <linux/sched.h> #include <linux/clocksource.h> #include <linux/workqueue.h> diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c index 2a59bde663f2..9f22e542c374 100644 --- a/arch/x86/kernel/tsc_64.c +++ b/arch/x86/kernel/tsc_64.c @@ -6,7 +6,9 @@ #include <linux/time.h> #include <linux/acpi.h> #include <linux/cpufreq.h> +#include <linux/acpi_pmtmr.h> +#include <asm/hpet.h> #include <asm/timex.h> static int notsc __initdata = 0; @@ -18,7 +20,7 @@ EXPORT_SYMBOL(tsc_khz); static unsigned int cyc2ns_scale __read_mostly; -void set_cyc2ns_scale(unsigned long khz) +static inline void set_cyc2ns_scale(unsigned long khz) { cyc2ns_scale = (NSEC_PER_MSEC << NS_SCALE) / khz; } @@ -118,6 +120,95 @@ core_initcall(cpufreq_tsc); #endif +#define MAX_RETRIES 5 +#define SMI_TRESHOLD 50000 + +/* + * Read TSC and the reference counters. Take care of SMI disturbance + */ +static unsigned long __init tsc_read_refs(unsigned long *pm, + unsigned long *hpet) +{ + unsigned long t1, t2; + int i; + + for (i = 0; i < MAX_RETRIES; i++) { + t1 = get_cycles_sync(); + if (hpet) + *hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF; + else + *pm = acpi_pm_read_early(); + t2 = get_cycles_sync(); + if ((t2 - t1) < SMI_TRESHOLD) + return t2; + } + return ULONG_MAX; +} + +/** + * tsc_calibrate - calibrate the tsc on boot + */ +void __init tsc_calibrate(void) +{ + unsigned long flags, tsc1, tsc2, tr1, tr2, pm1, pm2, hpet1, hpet2; + int hpet = is_hpet_enabled(); + + local_irq_save(flags); + + tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL); + + outb((inb(0x61) & ~0x02) | 0x01, 0x61); + + outb(0xb0, 0x43); + outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42); + outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42); + tr1 = get_cycles_sync(); + while ((inb(0x61) & 0x20) == 0); + tr2 = get_cycles_sync(); + + tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL); + + local_irq_restore(flags); + + /* + * Preset the result with the raw and inaccurate PIT + * calibration value + */ + tsc_khz = (tr2 - tr1) / 50; + + /* hpet or pmtimer available ? */ + if (!hpet && !pm1 && !pm2) { + printk(KERN_INFO "TSC calibrated against PIT\n"); + return; + } + + /* Check, whether the sampling was disturbed by an SMI */ + if (tsc1 == ULONG_MAX || tsc2 == ULONG_MAX) { + printk(KERN_WARNING "TSC calibration disturbed by SMI, " + "using PIT calibration result\n"); + return; + } + + tsc2 = (tsc2 - tsc1) * 1000000L; + + if (hpet) { + printk(KERN_INFO "TSC calibrated against HPET\n"); + if (hpet2 < hpet1) + hpet2 += 0x100000000; + hpet2 -= hpet1; + tsc1 = (hpet2 * hpet_readl(HPET_PERIOD)) / 1000000; + } else { + printk(KERN_INFO "TSC calibrated against PM_TIMER\n"); + if (pm2 < pm1) + pm2 += ACPI_PM_OVRRUN; + pm2 -= pm1; + tsc1 = (pm2 * 1000000000) / PMTMR_TICKS_PER_SEC; + } + + tsc_khz = tsc2 / tsc1; + set_cyc2ns_scale(tsc_khz); +} + /* * Make an educated guess if the TSC is trustworthy and synchronized * over all CPUs. diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c index 355f5f506c81..9125efe66a06 100644 --- a/arch/x86/kernel/tsc_sync.c +++ b/arch/x86/kernel/tsc_sync.c @@ -1,5 +1,5 @@ /* - * arch/x86_64/kernel/tsc_sync.c: check TSC synchronization. + * check TSC synchronization. * * Copyright (C) 2006, Red Hat, Inc., Ingo Molnar * diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index f2dcd1d27c0a..157e4bedd3c5 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -1,6 +1,4 @@ /* - * linux/kernel/vm86.c - * * Copyright (C) 1994 Linus Torvalds * * 29 dec 2001 - Fixed oopses caused by unchecked access to the vm86 diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 06c34949bfdc..93847d848157 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -1,6 +1,4 @@ /* - * linux/arch/x86_64/kernel/vsyscall.c - * * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE * Copyright 2003 Andi Kleen, SuSE Labs. * diff --git a/arch/x86/lib/copy_user_nocache_64.S b/arch/x86/lib/copy_user_nocache_64.S index 4620efb12f13..5196762b3b0e 100644 --- a/arch/x86/lib/copy_user_nocache_64.S +++ b/arch/x86/lib/copy_user_nocache_64.S @@ -117,6 +117,7 @@ ENTRY(__copy_user_nocache) popq %rbx CFI_ADJUST_CFA_OFFSET -8 CFI_RESTORE rbx + sfence ret CFI_RESTORE_STATE diff --git a/arch/x86/lib/thunk_64.S b/arch/x86/lib/thunk_64.S index 55e586d352d3..6ea73f3de567 100644 --- a/arch/x86/lib/thunk_64.S +++ b/arch/x86/lib/thunk_64.S @@ -50,6 +50,10 @@ thunk trace_hardirqs_on_thunk,trace_hardirqs_on thunk trace_hardirqs_off_thunk,trace_hardirqs_off #endif + +#ifdef CONFIG_DEBUG_LOCK_ALLOC + thunk lockdep_sys_exit_thunk,lockdep_sys_exit +#endif /* SAVE_ARGS below is used only for the .cfi directives it contains. */ CFI_STARTPROC diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c index fcb38e7f3543..c686ae20fd6b 100644 --- a/arch/x86/mm/fault_32.c +++ b/arch/x86/mm/fault_32.c @@ -25,6 +25,7 @@ #include <linux/kprobes.h> #include <linux/uaccess.h> #include <linux/kdebug.h> +#include <linux/kprobes.h> #include <asm/system.h> #include <asm/desc.h> @@ -32,33 +33,27 @@ extern void die(const char *,struct pt_regs *,long); -static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); - -int register_page_fault_notifier(struct notifier_block *nb) +#ifdef CONFIG_KPROBES +static inline int notify_page_fault(struct pt_regs *regs) { - vmalloc_sync_all(); - return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); -} -EXPORT_SYMBOL_GPL(register_page_fault_notifier); + int ret = 0; + + /* kprobe_running() needs smp_processor_id() */ + if (!user_mode_vm(regs)) { + preempt_disable(); + if (kprobe_running() && kprobe_fault_handler(regs, 14)) + ret = 1; + preempt_enable(); + } -int unregister_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); + return ret; } -EXPORT_SYMBOL_GPL(unregister_page_fault_notifier); - -static inline int notify_page_fault(struct pt_regs *regs, long err) +#else +static inline int notify_page_fault(struct pt_regs *regs) { - struct die_args args = { - .regs = regs, - .str = "page fault", - .err = err, - .trapnr = 14, - .signr = SIGSEGV - }; - return atomic_notifier_call_chain(¬ify_page_fault_chain, - DIE_PAGE_FAULT, &args); + return 0; } +#endif /* * Return EIP plus the CS segment base. The segment limit is also @@ -331,7 +326,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, if (unlikely(address >= TASK_SIZE)) { if (!(error_code & 0x0000000d) && vmalloc_fault(address) >= 0) return; - if (notify_page_fault(regs, error_code) == NOTIFY_STOP) + if (notify_page_fault(regs)) return; /* * Don't take the mm semaphore here. If we fixup a prefetch @@ -340,7 +335,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, goto bad_area_nosemaphore; } - if (notify_page_fault(regs, error_code) == NOTIFY_STOP) + if (notify_page_fault(regs)) return; /* It's safe to allow irq's after cr2 has been saved and the vmalloc @@ -598,7 +593,7 @@ out_of_memory: } printk("VM: killing process %s\n", tsk->comm); if (error_code & 4) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c index 54816adb8e93..5e0e54906c48 100644 --- a/arch/x86/mm/fault_64.c +++ b/arch/x86/mm/fault_64.c @@ -25,6 +25,7 @@ #include <linux/kprobes.h> #include <linux/uaccess.h> #include <linux/kdebug.h> +#include <linux/kprobes.h> #include <asm/system.h> #include <asm/pgalloc.h> @@ -40,34 +41,27 @@ #define PF_RSVD (1<<3) #define PF_INSTR (1<<4) -static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); - -/* Hook to register for page fault notifications */ -int register_page_fault_notifier(struct notifier_block *nb) +#ifdef CONFIG_KPROBES +static inline int notify_page_fault(struct pt_regs *regs) { - vmalloc_sync_all(); - return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); -} -EXPORT_SYMBOL_GPL(register_page_fault_notifier); + int ret = 0; + + /* kprobe_running() needs smp_processor_id() */ + if (!user_mode(regs)) { + preempt_disable(); + if (kprobe_running() && kprobe_fault_handler(regs, 14)) + ret = 1; + preempt_enable(); + } -int unregister_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); + return ret; } -EXPORT_SYMBOL_GPL(unregister_page_fault_notifier); - -static inline int notify_page_fault(struct pt_regs *regs, long err) +#else +static inline int notify_page_fault(struct pt_regs *regs) { - struct die_args args = { - .regs = regs, - .str = "page fault", - .err = err, - .trapnr = 14, - .signr = SIGSEGV - }; - return atomic_notifier_call_chain(¬ify_page_fault_chain, - DIE_PAGE_FAULT, &args); + return 0; } +#endif /* Sometimes the CPU reports invalid exceptions on prefetch. Check that here and ignore. @@ -345,7 +339,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, if (vmalloc_fault(address) >= 0) return; } - if (notify_page_fault(regs, error_code) == NOTIFY_STOP) + if (notify_page_fault(regs)) return; /* * Don't take the mm semaphore here. If we fixup a prefetch @@ -354,7 +348,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, goto bad_area_nosemaphore; } - if (notify_page_fault(regs, error_code) == NOTIFY_STOP) + if (notify_page_fault(regs)) return; if (likely(regs->eflags & X86_EFLAGS_IF)) diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 730a5b177b1f..dda4e83649a0 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -735,11 +735,6 @@ int arch_add_memory(int nid, u64 start, u64 size) return __add_pages(zone, start_pfn, nr_pages); } -int remove_memory(u64 start, u64 size) -{ - return -EINVAL; -} -EXPORT_SYMBOL_GPL(remove_memory); #endif struct kmem_cache *pmd_cache; diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 458893b376f8..1e3862e41065 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -474,12 +474,6 @@ error: } EXPORT_SYMBOL_GPL(arch_add_memory); -int remove_memory(u64 start, u64 size) -{ - return -EINVAL; -} -EXPORT_SYMBOL_GPL(remove_memory); - #if !defined(CONFIG_ACPI_NUMA) && defined(CONFIG_NUMA) int memory_add_physaddr_to_nid(u64 start) { @@ -748,3 +742,48 @@ const char *arch_vma_name(struct vm_area_struct *vma) return "[vsyscall]"; return NULL; } + +#ifdef CONFIG_SPARSEMEM_VMEMMAP +/* + * Initialise the sparsemem vmemmap using huge-pages at the PMD level. + */ +int __meminit vmemmap_populate(struct page *start_page, + unsigned long size, int node) +{ + unsigned long addr = (unsigned long)start_page; + unsigned long end = (unsigned long)(start_page + size); + unsigned long next; + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + + for (; addr < end; addr = next) { + next = pmd_addr_end(addr, end); + + pgd = vmemmap_pgd_populate(addr, node); + if (!pgd) + return -ENOMEM; + pud = vmemmap_pud_populate(pgd, addr, node); + if (!pud) + return -ENOMEM; + + pmd = pmd_offset(pud, addr); + if (pmd_none(*pmd)) { + pte_t entry; + void *p = vmemmap_alloc_block(PMD_SIZE, node); + if (!p) + return -ENOMEM; + + entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL); + mk_pte_huge(entry); + set_pmd(pmd, __pmd(pte_val(entry))); + + printk(KERN_DEBUG " [%lx-%lx] PMD ->%p on node %d\n", + addr, addr + PMD_SIZE - 1, p, node); + } else + vmemmap_verify((pte_t *)pmd, node, addr, next); + } + + return 0; +} +#endif diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c index 47925927b12f..56b4757a1f47 100644 --- a/arch/x86/oprofile/op_model_p4.c +++ b/arch/x86/oprofile/op_model_p4.c @@ -379,7 +379,7 @@ static unsigned int get_stagger(void) { #ifdef CONFIG_SMP int cpu = smp_processor_id(); - return (cpu != first_cpu(cpu_sibling_map[cpu])); + return (cpu != first_cpu(per_cpu(cpu_sibling_map, cpu))); #endif return 0; } diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index bc8a44bddaa7..2d88f7c6d6ac 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -2,15 +2,199 @@ #include <linux/acpi.h> #include <linux/init.h> #include <linux/irq.h> +#include <linux/dmi.h> #include <asm/numa.h> #include "pci.h" +static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d) +{ + pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; + printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident); + return 0; +} + +static struct dmi_system_id acpi_pciprobe_dmi_table[] = { +/* + * Systems where PCI IO resource ISA alignment can be skipped + * when the ISA enable bit in the bridge control is not set + */ + { + .callback = can_skip_ioresource_align, + .ident = "IBM System x3800", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "IBM"), + DMI_MATCH(DMI_PRODUCT_NAME, "x3800"), + }, + }, + { + .callback = can_skip_ioresource_align, + .ident = "IBM System x3850", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "IBM"), + DMI_MATCH(DMI_PRODUCT_NAME, "x3850"), + }, + }, + { + .callback = can_skip_ioresource_align, + .ident = "IBM System x3950", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "IBM"), + DMI_MATCH(DMI_PRODUCT_NAME, "x3950"), + }, + }, + {} +}; + +struct pci_root_info { + char *name; + unsigned int res_num; + struct resource *res; + struct pci_bus *bus; + int busnum; +}; + +static acpi_status +resource_to_addr(struct acpi_resource *resource, + struct acpi_resource_address64 *addr) +{ + acpi_status status; + + status = acpi_resource_to_address64(resource, addr); + if (ACPI_SUCCESS(status) && + (addr->resource_type == ACPI_MEMORY_RANGE || + addr->resource_type == ACPI_IO_RANGE) && + addr->address_length > 0 && + addr->producer_consumer == ACPI_PRODUCER) { + return AE_OK; + } + return AE_ERROR; +} + +static acpi_status +count_resource(struct acpi_resource *acpi_res, void *data) +{ + struct pci_root_info *info = data; + struct acpi_resource_address64 addr; + acpi_status status; + + status = resource_to_addr(acpi_res, &addr); + if (ACPI_SUCCESS(status)) + info->res_num++; + return AE_OK; +} + +static acpi_status +setup_resource(struct acpi_resource *acpi_res, void *data) +{ + struct pci_root_info *info = data; + struct resource *res; + struct acpi_resource_address64 addr; + acpi_status status; + unsigned long flags; + struct resource *root; + + status = resource_to_addr(acpi_res, &addr); + if (!ACPI_SUCCESS(status)) + return AE_OK; + + if (addr.resource_type == ACPI_MEMORY_RANGE) { + root = &iomem_resource; + flags = IORESOURCE_MEM; + if (addr.info.mem.caching == ACPI_PREFETCHABLE_MEMORY) + flags |= IORESOURCE_PREFETCH; + } else if (addr.resource_type == ACPI_IO_RANGE) { + root = &ioport_resource; + flags = IORESOURCE_IO; + } else + return AE_OK; + + res = &info->res[info->res_num]; + res->name = info->name; + res->flags = flags; + res->start = addr.minimum + addr.translation_offset; + res->end = res->start + addr.address_length - 1; + res->child = NULL; + + if (insert_resource(root, res)) { + printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx " + "from %s for %s\n", (unsigned long) res->start, + (unsigned long) res->end, root->name, info->name); + } else { + info->bus->resource[info->res_num] = res; + info->res_num++; + } + return AE_OK; +} + +static void +adjust_transparent_bridge_resources(struct pci_bus *bus) +{ + struct pci_dev *dev; + + list_for_each_entry(dev, &bus->devices, bus_list) { + int i; + u16 class = dev->class >> 8; + + if (class == PCI_CLASS_BRIDGE_PCI && dev->transparent) { + for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) + dev->subordinate->resource[i] = + dev->bus->resource[i - 3]; + } + } +} + +static void +get_current_resources(struct acpi_device *device, int busnum, + struct pci_bus *bus) +{ + struct pci_root_info info; + size_t size; + + info.bus = bus; + info.res_num = 0; + acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, + &info); + if (!info.res_num) + return; + + size = sizeof(*info.res) * info.res_num; + info.res = kmalloc(size, GFP_KERNEL); + if (!info.res) + goto res_alloc_fail; + + info.name = kmalloc(12, GFP_KERNEL); + if (!info.name) + goto name_alloc_fail; + sprintf(info.name, "PCI Bus #%02x", busnum); + + info.res_num = 0; + acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, + &info); + if (info.res_num) + adjust_transparent_bridge_resources(bus); + + return; + +name_alloc_fail: + kfree(info.res); +res_alloc_fail: + return; +} + struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum) { struct pci_bus *bus; struct pci_sysdata *sd; int pxm; + dmi_check_system(acpi_pciprobe_dmi_table); + + if (domain && !pci_domains_supported) { + printk(KERN_WARNING "PCI: Multiple domains not supported " + "(dom %d, bus %d)\n", domain, busnum); + return NULL; + } + /* Allocate per-root-bus (not per bus) arch-specific data. * TODO: leak; this memory is never freed. * It's arguable whether it's worth the trouble to care. @@ -21,12 +205,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do return NULL; } - if (domain != 0) { - printk(KERN_WARNING "PCI: Multiple domains not supported\n"); - kfree(sd); - return NULL; - } - + sd->domain = domain; sd->node = -1; pxm = acpi_get_pxm(device->handle); @@ -47,6 +226,9 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do } } #endif + + if (bus && (pci_probe & PCI_USE__CRS)) + get_current_resources(device, busnum, bus); return bus; } diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 07d5223442bf..2d71bbc411d2 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -29,12 +29,14 @@ struct pci_raw_ops *raw_pci_ops; static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) { - return raw_pci_ops->read(0, bus->number, devfn, where, size, value); + return raw_pci_ops->read(pci_domain_nr(bus), bus->number, + devfn, where, size, value); } static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) { - return raw_pci_ops->write(0, bus->number, devfn, where, size, value); + return raw_pci_ops->write(pci_domain_nr(bus), bus->number, + devfn, where, size, value); } struct pci_ops pci_root_ops = { @@ -287,6 +289,16 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"), }, }, +#ifdef __i386__ + { + .callback = assign_all_busses, + .ident = "Compaq EVO N800c", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), + DMI_MATCH(DMI_PRODUCT_NAME, "EVO N800c"), + }, + }, +#endif {} }; @@ -426,6 +438,9 @@ char * __devinit pcibios_setup(char *str) } else if (!strcmp(str, "assign-busses")) { pci_probe |= PCI_ASSIGN_ALL_BUSSES; return NULL; + } else if (!strcmp(str, "use_crs")) { + pci_probe |= PCI_USE__CRS; + return NULL; } else if (!strcmp(str, "routeirq")) { pci_routeirq = 1; return NULL; diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index c82cbf4c7226..6cff66dd0c91 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -353,6 +353,53 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) } DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); + +static struct dmi_system_id __devinitdata msi_k8t_dmi_table[] = { + { + .ident = "MSI-K8T-Neo2Fir", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MSI"), + DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"), + }, + }, + {} +}; + +/* + * The AMD-Athlon64 board MSI "K8T Neo2-FIR" disables the onboard sound + * card if a PCI-soundcard is added. + * + * The BIOS only gives options "DISABLED" and "AUTO". This code sets + * the corresponding register-value to enable the soundcard. + * + * The soundcard is only enabled, if the mainborad is identified + * via DMI-tables and the soundcard is detected to be off. + */ +static void __devinit pci_fixup_msi_k8t_onboard_sound(struct pci_dev *dev) +{ + unsigned char val; + if (!dmi_check_system(msi_k8t_dmi_table)) + return; /* only applies to MSI K8T Neo2-FIR */ + + pci_read_config_byte(dev, 0x50, &val); + if (val & 0x40) { + pci_write_config_byte(dev, 0x50, val & (~0x40)); + + /* verify the change for status output */ + pci_read_config_byte(dev, 0x50, &val); + if (val & 0x40) + printk(KERN_INFO "PCI: Detected MSI K8T Neo2-FIR, " + "can't enable onboard soundcard!\n"); + else + printk(KERN_INFO "PCI: Detected MSI K8T Neo2-FIR, " + "enabled onboard soundcard.\n"); + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, + pci_fixup_msi_k8t_onboard_sound); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, + pci_fixup_msi_k8t_onboard_sound); + /* * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A. * diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index bcd2f94b732c..42ba0e2da1a0 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -33,6 +33,15 @@ #include "pci.h" +static int +skip_isa_ioresource_align(struct pci_dev *dev) { + + if ((pci_probe & PCI_CAN_SKIP_ISA_ALIGN) && + !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA)) + return 1; + return 0; +} + /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the @@ -50,9 +59,13 @@ void pcibios_align_resource(void *data, struct resource *res, resource_size_t size, resource_size_t align) { + struct pci_dev *dev = data; + if (res->flags & IORESOURCE_IO) { resource_size_t start = res->start; + if (skip_isa_ioresource_align(dev)) + return; if (start & 0x300) { start = (start + 0x3ff) & ~0x3ff; res->start = start; diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index d98c6b096f8e..c52150fdf82b 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c @@ -492,6 +492,26 @@ static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq return 1; } +/* + * PicoPower PT86C523 + */ +static int pirq_pico_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + outb(0x10 + ((pirq - 1) >> 1), 0x24); + return ((pirq - 1) & 1) ? (inb(0x26) >> 4) : (inb(0x26) & 0xf); +} + +static int pirq_pico_set(struct pci_dev *router, struct pci_dev *dev, int pirq, + int irq) +{ + unsigned int x; + outb(0x10 + ((pirq - 1) >> 1), 0x24); + x = inb(0x26); + x = ((pirq - 1) & 1) ? ((x & 0x0f) | (irq << 4)) : ((x & 0xf0) | (irq)); + outb(x, 0x26); + return 1; +} + #ifdef CONFIG_PCI_BIOS static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) @@ -721,6 +741,24 @@ static __init int amd_router_probe(struct irq_router *r, struct pci_dev *router, return 1; } +static __init int pico_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch (device) { + case PCI_DEVICE_ID_PICOPOWER_PT86C523: + r->name = "PicoPower PT86C523"; + r->get = pirq_pico_get; + r->set = pirq_pico_set; + return 1; + + case PCI_DEVICE_ID_PICOPOWER_PT86C523BBP: + r->name = "PicoPower PT86C523 rev. BB+"; + r->get = pirq_pico_get; + r->set = pirq_pico_set; + return 1; + } + return 0; +} + static __initdata struct irq_router_handler pirq_routers[] = { { PCI_VENDOR_ID_INTEL, intel_router_probe }, { PCI_VENDOR_ID_AL, ali_router_probe }, @@ -732,6 +770,7 @@ static __initdata struct irq_router_handler pirq_routers[] = { { PCI_VENDOR_ID_VLSI, vlsi_router_probe }, { PCI_VENDOR_ID_SERVERWORKS, serverworks_router_probe }, { PCI_VENDOR_ID_AMD, amd_router_probe }, + { PCI_VENDOR_ID_PICOPOWER, pico_router_probe }, /* Someone with docs needs to add the ATI Radeon IGP */ { 0, NULL } }; diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h index 8c66f275756f..ac56d3916c50 100644 --- a/arch/x86/pci/pci.h +++ b/arch/x86/pci/pci.h @@ -26,6 +26,8 @@ #define PCI_ASSIGN_ROMS 0x1000 #define PCI_BIOS_IRQ_SCAN 0x2000 #define PCI_ASSIGN_ALL_BUSSES 0x4000 +#define PCI_CAN_SKIP_ISA_ALIGN 0x8000 +#define PCI_USE__CRS 0x10000 extern unsigned int pci_probe; extern unsigned long pirq_table_addr; diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 557b8e24706a..4fa33c27ccb6 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -147,8 +147,13 @@ void __init xen_smp_prepare_boot_cpu(void) make_lowmem_page_readwrite(&per_cpu__gdt_page); for (cpu = 0; cpu < NR_CPUS; cpu++) { - cpus_clear(cpu_sibling_map[cpu]); - cpus_clear(cpu_core_map[cpu]); + cpus_clear(per_cpu(cpu_sibling_map, cpu)); + /* + * cpu_core_map lives in a per cpu area that is cleared + * when the per cpu array is allocated. + * + * cpus_clear(per_cpu(cpu_core_map, cpu)); + */ } xen_setup_vcpu_info_placement(); @@ -159,8 +164,13 @@ void __init xen_smp_prepare_cpus(unsigned int max_cpus) unsigned cpu; for (cpu = 0; cpu < NR_CPUS; cpu++) { - cpus_clear(cpu_sibling_map[cpu]); - cpus_clear(cpu_core_map[cpu]); + cpus_clear(per_cpu(cpu_sibling_map, cpu)); + /* + * cpu_core_ map will be zeroed when the per + * cpu area is allocated. + * + * cpus_clear(per_cpu(cpu_core_map, cpu)); + */ } smp_store_cpu_info(0); diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index b1b98e614f7c..8c83dbe4c4d0 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -36,6 +36,18 @@ config GENERIC_CMOS_UPDATE bool default y +config CLOCKSOURCE_WATCHDOG + bool + default y + +config GENERIC_CLOCKEVENTS + bool + default y + +config GENERIC_CLOCKEVENTS_BROADCAST + bool + default y + config ZONE_DMA32 bool default y @@ -130,6 +142,8 @@ source "init/Kconfig" menu "Processor type and features" +source "kernel/time/Kconfig" + choice prompt "Subarchitecture Type" default X86_PC @@ -395,6 +409,7 @@ config ARCH_DISCONTIGMEM_DEFAULT config ARCH_SPARSEMEM_ENABLE def_bool y depends on (NUMA || EXPERIMENTAL) + select SPARSEMEM_VMEMMAP_ENABLE config ARCH_MEMORY_PROBE def_bool y @@ -724,6 +739,11 @@ config PCI_MMCONFIG bool "Support mmconfig PCI config space access" depends on PCI && ACPI +config PCI_DOMAINS + bool + depends on PCI + default y + source "drivers/pci/pcie/Kconfig" source "drivers/pci/Kconfig" diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 06a13d9b69db..5533c7850d53 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -304,10 +304,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = put_user(sizeof(elf_fpregset_t), (unsigned long *) data); break; - case PTRACE_DETACH: /* detach a process that was attached. */ - ret = ptrace_detach(child, data); - break; - default: ret = ptrace_request(child, request, addr, data); goto out; diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c index 45d28f217c03..2f842859948f 100644 --- a/arch/xtensa/mm/fault.c +++ b/arch/xtensa/mm/fault.c @@ -152,7 +152,7 @@ out_of_memory: } printk("VM: killing process %s\n", current->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); bad_page_fault(regs, address, SIGKILL); return; |