diff options
Diffstat (limited to 'arch/sh')
67 files changed, 507 insertions, 740 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 3e723aaa5e18..a24595d83ad6 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -13,6 +13,7 @@ config SUPERH select HAVE_DMA_ATTRS select HAVE_IRQ_WORK select HAVE_PERF_EVENTS + select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A) select PERF_USE_VMALLOC select HAVE_KERNEL_GZIP @@ -29,6 +30,10 @@ config SUPERH select GENERIC_ATOMIC64 select GENERIC_IRQ_SHOW select GENERIC_SMP_IDLE_THREAD + select GENERIC_CLOCKEVENTS + select GENERIC_CMOS_UPDATE if SH_SH03 || SH_DREAMCAST + select GENERIC_STRNCPY_FROM_USER + select GENERIC_STRNLEN_USER help The SuperH is a RISC processor targeted for use in embedded systems and consumer electronics; it was also used in the Sega Dreamcast @@ -55,6 +60,7 @@ config SUPERH32 config SUPERH64 def_bool ARCH = "sh64" + select KALLSYMS config ARCH_DEFCONFIG string @@ -87,16 +93,6 @@ config GENERIC_GPIO config GENERIC_CALIBRATE_DELAY bool -config GENERIC_CLOCKEVENTS - def_bool y - -config GENERIC_CLOCKEVENTS_BROADCAST - bool - -config GENERIC_CMOS_UPDATE - def_bool y - depends on SH_SH03 || SH_DREAMCAST - config GENERIC_LOCKBREAK def_bool y depends on SMP && PREEMPT @@ -611,8 +607,6 @@ config SH_CLK_CPG_LEGACY !CPU_SUBTYPE_SH7734 && !CPU_SUBTYPE_SH7264 && \ !CPU_SUBTYPE_SH7269 -source "kernel/time/Kconfig" - endmenu menu "CPU Frequency scaling" diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 46edf070da1c..aed701c7b11b 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -9,6 +9,12 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # +ifneq ($(SUBARCH),$(ARCH)) + ifeq ($(CROSS_COMPILE),) + CROSS_COMPILE := $(call cc-cross-prefix, $(UTS_MACHINE)-linux- $(UTS_MACHINE)-linux-gnu- $(UTS_MACHINE)-unknown-linux-gnu-) + endif +endif + isa-y := any isa-$(CONFIG_SH_DSP) := sh isa-$(CONFIG_CPU_SH2) := sh2 @@ -106,19 +112,13 @@ LDFLAGS_vmlinux += --defsym phys_stext=_stext-$(CONFIG_PAGE_OFFSET) \ KBUILD_DEFCONFIG := cayman_defconfig endif -ifneq ($(SUBARCH),$(ARCH)) - ifeq ($(CROSS_COMPILE),) - CROSS_COMPILE := $(call cc-cross-prefix, $(UTS_MACHINE)-linux- $(UTS_MACHINE)-linux-gnu- $(UTS_MACHINE)-unknown-linux-gnu-) - endif -endif - ifdef CONFIG_CPU_LITTLE_ENDIAN ld-bfd := elf32-$(UTS_MACHINE)-linux -LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64' --oformat $(ld-bfd) +LDFLAGS_vmlinux += --defsym jiffies=jiffies_64 --oformat $(ld-bfd) LDFLAGS += -EL else ld-bfd := elf32-$(UTS_MACHINE)big-linux -LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64+4' --oformat $(ld-bfd) +LDFLAGS_vmlinux += --defsym jiffies=jiffies_64+4 --oformat $(ld-bfd) LDFLAGS += -EB endif diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index 1f56b35d3248..7048c03490d9 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig @@ -44,6 +44,8 @@ config SH_7721_SOLUTION_ENGINE config SH_7722_SOLUTION_ENGINE bool "SolutionEngine7722" select SOLUTION_ENGINE + select GENERIC_IRQ_CHIP + select IRQ_DOMAIN depends on CPU_SUBTYPE_SH7722 help Select 7722 SolutionEngine if configuring for a Hitachi SH772 @@ -80,6 +82,8 @@ config SH_7780_SOLUTION_ENGINE config SH_7343_SOLUTION_ENGINE bool "SolutionEngine7343" select SOLUTION_ENGINE + select GENERIC_IRQ_CHIP + select IRQ_DOMAIN depends on CPU_SUBTYPE_SH7343 help Select 7343 SolutionEngine if configuring for a Hitachi @@ -295,6 +299,7 @@ config SH_X3PROTO bool "SH-X3 Prototype board" depends on CPU_SUBTYPE_SHX3 select NO_IOPORT if !PCI + select IRQ_DOMAIN config SH_MAGIC_PANEL_R2 bool "Magic Panel R2" diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c index f63d323f411f..2789647abebe 100644 --- a/arch/sh/boards/mach-dreamcast/irq.c +++ b/arch/sh/boards/mach-dreamcast/irq.c @@ -8,10 +8,11 @@ * This file is part of the LinuxDC project (www.linuxdc.org) * Released under the terms of the GNU GPL v2.0 */ - #include <linux/irq.h> #include <linux/io.h> -#include <asm/irq.h> +#include <linux/irq.h> +#include <linux/export.h> +#include <linux/err.h> #include <mach/sysasic.h> /* @@ -141,26 +142,15 @@ int systemasic_irq_demux(int irq) void systemasic_irq_init(void) { - int i, nid = cpu_to_node(boot_cpu_data); - - /* Assign all virtual IRQs to the System ASIC int. handler */ - for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) { - unsigned int irq; - - irq = create_irq_nr(i, nid); - if (unlikely(irq == 0)) { - pr_err("%s: failed hooking irq %d for systemasic\n", - __func__, i); - return; - } + int irq_base, i; - if (unlikely(irq != i)) { - pr_err("%s: got irq %d but wanted %d, bailing.\n", - __func__, irq, i); - destroy_irq(irq); - return; - } + irq_base = irq_alloc_descs(HW_EVENT_IRQ_BASE, HW_EVENT_IRQ_BASE, + HW_EVENT_IRQ_MAX - HW_EVENT_IRQ_BASE, -1); + if (IS_ERR_VALUE(irq_base)) { + pr_err("%s: failed hooking irqs\n", __func__); + return; + } + for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) irq_set_chip_and_handler(i, &systemasic_int, handle_level_irq); - } } diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 34cd0c5ff2e1..a8a1ca741c85 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -188,7 +188,6 @@ static struct platform_nand_data migor_nand_flash_data = { .partitions = migor_nand_flash_partitions, .nr_partitions = ARRAY_SIZE(migor_nand_flash_partitions), .chip_delay = 20, - .part_probe_types = (const char *[]) { "cmdlinepart", NULL }, }, .ctrl = { .dev_ready = migor_nand_flash_ready, diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c index fd45ffc48340..7646bf0486c2 100644 --- a/arch/sh/boards/mach-se/7343/irq.c +++ b/arch/sh/boards/mach-se/7343/irq.c @@ -1,86 +1,129 @@ /* - * linux/arch/sh/boards/se/7343/irq.c + * Hitachi UL SolutionEngine 7343 FPGA IRQ Support. * * Copyright (C) 2008 Yoshihiro Shimoda + * Copyright (C) 2012 Paul Mundt * - * Based on linux/arch/sh/boards/se/7722/irq.c + * Based on linux/arch/sh/boards/se/7343/irq.c * Copyright (C) 2007 Nobuhiro Iwamatsu * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ +#define DRV_NAME "SE7343-FPGA" +#define pr_fmt(fmt) DRV_NAME ": " fmt + +#define irq_reg_readl ioread16 +#define irq_reg_writel iowrite16 + #include <linux/init.h> #include <linux/irq.h> #include <linux/interrupt.h> +#include <linux/irqdomain.h> #include <linux/io.h> +#include <asm/sizes.h> #include <mach-se/mach/se7343.h> -unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, }; +#define PA_CPLD_BASE_ADDR 0x11400000 +#define PA_CPLD_ST_REG 0x08 /* CPLD Interrupt status register */ +#define PA_CPLD_IMSK_REG 0x0a /* CPLD Interrupt mask register */ -static void disable_se7343_irq(struct irq_data *data) -{ - unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); - __raw_writew(__raw_readw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK); -} +static void __iomem *se7343_irq_regs; +struct irq_domain *se7343_irq_domain; -static void enable_se7343_irq(struct irq_data *data) +static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc) { - unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); - __raw_writew(__raw_readw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK); -} + struct irq_data *data = irq_get_irq_data(irq); + struct irq_chip *chip = irq_data_get_irq_chip(data); + unsigned long mask; + int bit; -static struct irq_chip se7343_irq_chip __read_mostly = { - .name = "SE7343-FPGA", - .irq_mask = disable_se7343_irq, - .irq_unmask = enable_se7343_irq, -}; + chip->irq_mask_ack(data); -static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc) + mask = ioread16(se7343_irq_regs + PA_CPLD_ST_REG); + + for_each_set_bit(bit, &mask, SE7343_FPGA_IRQ_NR) + generic_handle_irq(irq_linear_revmap(se7343_irq_domain, bit)); + + chip->irq_unmask(data); +} + +static void __init se7343_domain_init(void) { - unsigned short intv = __raw_readw(PA_CPLD_ST); - unsigned int ext_irq = 0; + int i; - intv &= (1 << SE7343_FPGA_IRQ_NR) - 1; + se7343_irq_domain = irq_domain_add_linear(NULL, SE7343_FPGA_IRQ_NR, + &irq_domain_simple_ops, NULL); + if (unlikely(!se7343_irq_domain)) { + printk("Failed to get IRQ domain\n"); + return; + } - for (; intv; intv >>= 1, ext_irq++) { - if (!(intv & 1)) - continue; + for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) { + int irq = irq_create_mapping(se7343_irq_domain, i); - generic_handle_irq(se7343_fpga_irq[ext_irq]); + if (unlikely(irq == 0)) { + printk("Failed to allocate IRQ %d\n", i); + return; + } } } -/* - * Initialize IRQ setting - */ -void __init init_7343se_IRQ(void) +static void __init se7343_gc_init(void) { - int i, irq; + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + unsigned int irq_base; - __raw_writew(0, PA_CPLD_IMSK); /* disable all irqs */ - __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ + irq_base = irq_linear_revmap(se7343_irq_domain, 0); - for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) { - irq = create_irq(); - if (irq < 0) - return; - se7343_fpga_irq[i] = irq; + gc = irq_alloc_generic_chip(DRV_NAME, 1, irq_base, se7343_irq_regs, + handle_level_irq); + if (unlikely(!gc)) + return; - irq_set_chip_and_handler_name(se7343_fpga_irq[i], - &se7343_irq_chip, - handle_level_irq, - "level"); + ct = gc->chip_types; + ct->chip.irq_mask = irq_gc_mask_set_bit; + ct->chip.irq_unmask = irq_gc_mask_clr_bit; - irq_set_chip_data(se7343_fpga_irq[i], (void *)i); - } + ct->regs.mask = PA_CPLD_IMSK_REG; + + irq_setup_generic_chip(gc, IRQ_MSK(SE7343_FPGA_IRQ_NR), + IRQ_GC_INIT_MASK_CACHE, + IRQ_NOREQUEST | IRQ_NOPROBE, 0); irq_set_chained_handler(IRQ0_IRQ, se7343_irq_demux); irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); + irq_set_chained_handler(IRQ1_IRQ, se7343_irq_demux); irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); + irq_set_chained_handler(IRQ4_IRQ, se7343_irq_demux); irq_set_irq_type(IRQ4_IRQ, IRQ_TYPE_LEVEL_LOW); + irq_set_chained_handler(IRQ5_IRQ, se7343_irq_demux); irq_set_irq_type(IRQ5_IRQ, IRQ_TYPE_LEVEL_LOW); } + +/* + * Initialize IRQ setting + */ +void __init init_7343se_IRQ(void) +{ + se7343_irq_regs = ioremap(PA_CPLD_BASE_ADDR, SZ_16); + if (unlikely(!se7343_irq_regs)) { + pr_err("Failed to remap CPLD\n"); + return; + } + + /* + * All FPGA IRQs disabled by default + */ + iowrite16(0, se7343_irq_regs + PA_CPLD_IMSK_REG); + + __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ + + se7343_domain_init(); + se7343_gc_init(); +} diff --git a/arch/sh/boards/mach-se/7343/setup.c b/arch/sh/boards/mach-se/7343/setup.c index d2370af56d77..8ce4f2a202a8 100644 --- a/arch/sh/boards/mach-se/7343/setup.c +++ b/arch/sh/boards/mach-se/7343/setup.c @@ -5,6 +5,7 @@ #include <linux/serial_reg.h> #include <linux/usb/isp116x.h> #include <linux/delay.h> +#include <linux/irqdomain.h> #include <asm/machvec.h> #include <mach-se/mach/se7343.h> #include <asm/heartbeat.h> @@ -145,11 +146,12 @@ static struct platform_device *sh7343se_platform_devices[] __initdata = { static int __init sh7343se_devices_setup(void) { /* Wire-up dynamic vectors */ - serial_platform_data[0].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTA]; - serial_platform_data[1].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTB]; - + serial_platform_data[0].irq = irq_find_mapping(se7343_irq_domain, + SE7343_FPGA_IRQ_UARTA); + serial_platform_data[1].irq = irq_find_mapping(se7343_irq_domain, + SE7343_FPGA_IRQ_UARTB); usb_resources[2].start = usb_resources[2].end = - se7343_fpga_irq[SE7343_FPGA_IRQ_USB]; + irq_find_mapping(se7343_irq_domain, SE7343_FPGA_IRQ_USB); return platform_add_devices(sh7343se_platform_devices, ARRAY_SIZE(sh7343se_platform_devices)); diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c index aac92f21ebd2..f5e2af1bf040 100644 --- a/arch/sh/boards/mach-se/7722/irq.c +++ b/arch/sh/boards/mach-se/7722/irq.c @@ -1,79 +1,96 @@ /* - * linux/arch/sh/boards/se/7722/irq.c + * Hitachi UL SolutionEngine 7722 FPGA IRQ Support. * * Copyright (C) 2007 Nobuhiro Iwamatsu - * - * Hitachi UL SolutionEngine 7722 Support. + * Copyright (C) 2012 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. */ +#define DRV_NAME "SE7722-FPGA" +#define pr_fmt(fmt) DRV_NAME ": " fmt + +#define irq_reg_readl ioread16 +#define irq_reg_writel iowrite16 + #include <linux/init.h> #include <linux/irq.h> #include <linux/interrupt.h> -#include <asm/irq.h> -#include <asm/io.h> +#include <linux/irqdomain.h> +#include <linux/io.h> +#include <linux/err.h> +#include <asm/sizes.h> #include <mach-se/mach/se7722.h> -unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, }; +#define IRQ01_BASE_ADDR 0x11800000 +#define IRQ01_MODE_REG 0 +#define IRQ01_STS_REG 4 +#define IRQ01_MASK_REG 8 -static void disable_se7722_irq(struct irq_data *data) -{ - unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); - __raw_writew(__raw_readw(IRQ01_MASK) | 1 << bit, IRQ01_MASK); -} +static void __iomem *se7722_irq_regs; +struct irq_domain *se7722_irq_domain; -static void enable_se7722_irq(struct irq_data *data) +static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) { - unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); - __raw_writew(__raw_readw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK); -} + struct irq_data *data = irq_get_irq_data(irq); + struct irq_chip *chip = irq_data_get_irq_chip(data); + unsigned long mask; + int bit; -static struct irq_chip se7722_irq_chip __read_mostly = { - .name = "SE7722-FPGA", - .irq_mask = disable_se7722_irq, - .irq_unmask = enable_se7722_irq, -}; + chip->irq_mask_ack(data); -static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) + mask = ioread16(se7722_irq_regs + IRQ01_STS_REG); + + for_each_set_bit(bit, &mask, SE7722_FPGA_IRQ_NR) + generic_handle_irq(irq_linear_revmap(se7722_irq_domain, bit)); + + chip->irq_unmask(data); +} + +static void __init se7722_domain_init(void) { - unsigned short intv = __raw_readw(IRQ01_STS); - unsigned int ext_irq = 0; + int i; - intv &= (1 << SE7722_FPGA_IRQ_NR) - 1; + se7722_irq_domain = irq_domain_add_linear(NULL, SE7722_FPGA_IRQ_NR, + &irq_domain_simple_ops, NULL); + if (unlikely(!se7722_irq_domain)) { + printk("Failed to get IRQ domain\n"); + return; + } - for (; intv; intv >>= 1, ext_irq++) { - if (!(intv & 1)) - continue; + for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { + int irq = irq_create_mapping(se7722_irq_domain, i); - generic_handle_irq(se7722_fpga_irq[ext_irq]); + if (unlikely(irq == 0)) { + printk("Failed to allocate IRQ %d\n", i); + return; + } } } -/* - * Initialize IRQ setting - */ -void __init init_se7722_IRQ(void) +static void __init se7722_gc_init(void) { - int i, irq; + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + unsigned int irq_base; - __raw_writew(0, IRQ01_MASK); /* disable all irqs */ - __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ + irq_base = irq_linear_revmap(se7722_irq_domain, 0); - for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { - irq = create_irq(); - if (irq < 0) - return; - se7722_fpga_irq[i] = irq; + gc = irq_alloc_generic_chip(DRV_NAME, 1, irq_base, se7722_irq_regs, + handle_level_irq); + if (unlikely(!gc)) + return; - irq_set_chip_and_handler_name(se7722_fpga_irq[i], - &se7722_irq_chip, - handle_level_irq, - "level"); + ct = gc->chip_types; + ct->chip.irq_mask = irq_gc_mask_set_bit; + ct->chip.irq_unmask = irq_gc_mask_clr_bit; - irq_set_chip_data(se7722_fpga_irq[i], (void *)i); - } + ct->regs.mask = IRQ01_MASK_REG; + + irq_setup_generic_chip(gc, IRQ_MSK(SE7722_FPGA_IRQ_NR), + IRQ_GC_INIT_MASK_CACHE, + IRQ_NOREQUEST | IRQ_NOPROBE, 0); irq_set_chained_handler(IRQ0_IRQ, se7722_irq_demux); irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); @@ -81,3 +98,25 @@ void __init init_se7722_IRQ(void) irq_set_chained_handler(IRQ1_IRQ, se7722_irq_demux); irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); } + +/* + * Initialize FPGA IRQs + */ +void __init init_se7722_IRQ(void) +{ + se7722_irq_regs = ioremap(IRQ01_BASE_ADDR, SZ_16); + if (unlikely(!se7722_irq_regs)) { + printk("Failed to remap IRQ01 regs\n"); + return; + } + + /* + * All FPGA IRQs disabled by default + */ + iowrite16(0, se7722_irq_regs + IRQ01_MASK_REG); + + __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ + + se7722_domain_init(); + se7722_gc_init(); +} diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c index 8f7f0550cfde..e04e2bc46984 100644 --- a/arch/sh/boards/mach-se/7722/setup.c +++ b/arch/sh/boards/mach-se/7722/setup.c @@ -2,6 +2,7 @@ * linux/arch/sh/boards/se/7722/setup.c * * Copyright (C) 2007 Nobuhiro Iwamatsu + * Copyright (C) 2012 Paul Mundt * * Hitachi UL SolutionEngine 7722 Support. * @@ -15,6 +16,7 @@ #include <linux/ata_platform.h> #include <linux/input.h> #include <linux/input/sh_keysc.h> +#include <linux/irqdomain.h> #include <linux/smc91x.h> #include <linux/sh_intc.h> #include <mach-se/mach/se7722.h> @@ -143,10 +145,10 @@ static int __init se7722_devices_setup(void) /* Wire-up dynamic vectors */ cf_ide_resources[2].start = cf_ide_resources[2].end = - se7722_fpga_irq[SE7722_FPGA_IRQ_MRSHPC0]; + irq_find_mapping(se7722_irq_domain, SE7722_FPGA_IRQ_MRSHPC0); smc91x_eth_resources[1].start = smc91x_eth_resources[1].end = - se7722_fpga_irq[SE7722_FPGA_IRQ_SMC]; + irq_find_mapping(se7722_irq_domain, SE7722_FPGA_IRQ_SMC); return platform_add_devices(se7722_devices, ARRAY_SIZE(se7722_devices)); } diff --git a/arch/sh/boards/mach-se/7724/irq.c b/arch/sh/boards/mach-se/7724/irq.c index c6342ce7768d..5d1d3ec9a6cd 100644 --- a/arch/sh/boards/mach-se/7724/irq.c +++ b/arch/sh/boards/mach-se/7724/irq.c @@ -17,8 +17,10 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/interrupt.h> -#include <asm/irq.h> -#include <asm/io.h> +#include <linux/export.h> +#include <linux/topology.h> +#include <linux/io.h> +#include <linux/err.h> #include <mach-se/mach/se7724.h> struct fpga_irq { @@ -111,7 +113,7 @@ static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc) */ void __init init_se7724_IRQ(void) { - int i, nid = cpu_to_node(boot_cpu_data); + int irq_base, i; __raw_writew(0xffff, IRQ0_MR); /* mask all */ __raw_writew(0xffff, IRQ1_MR); /* mask all */ @@ -121,28 +123,16 @@ void __init init_se7724_IRQ(void) __raw_writew(0x0000, IRQ2_SR); /* clear irq */ __raw_writew(0x002a, IRQ_MODE); /* set irq type */ - for (i = 0; i < SE7724_FPGA_IRQ_NR; i++) { - int irq, wanted; - - wanted = SE7724_FPGA_IRQ_BASE + i; - - irq = create_irq_nr(wanted, nid); - if (unlikely(irq == 0)) { - pr_err("%s: failed hooking irq %d for FPGA\n", - __func__, wanted); - return; - } - - if (unlikely(irq != wanted)) { - pr_err("%s: got irq %d but wanted %d, bailing.\n", - __func__, irq, wanted); - destroy_irq(irq); - return; - } + irq_base = irq_alloc_descs(SE7724_FPGA_IRQ_BASE, SE7724_FPGA_IRQ_BASE, + SE7724_FPGA_IRQ_NR, numa_node_id()); + if (IS_ERR_VALUE(irq_base)) { + pr_err("%s: failed hooking irqs for FPGA\n", __func__); + return; + } - irq_set_chip_and_handler_name(irq, &se7724_irq_chip, + for (i = 0; i < SE7724_FPGA_IRQ_NR; i++) + irq_set_chip_and_handler_name(irq_base + i, &se7724_irq_chip, handle_level_irq, "level"); - } irq_set_chained_handler(IRQ0_IRQ, se7724_irq_demux); irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); diff --git a/arch/sh/boards/mach-x3proto/gpio.c b/arch/sh/boards/mach-x3proto/gpio.c index f33b2b57019c..3ea65e9b56e8 100644 --- a/arch/sh/boards/mach-x3proto/gpio.c +++ b/arch/sh/boards/mach-x3proto/gpio.c @@ -3,7 +3,7 @@ * * Renesas SH-X3 Prototype Baseboard GPIO Support. * - * Copyright (C) 2010 Paul Mundt + * Copyright (C) 2010 - 2012 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 @@ -17,6 +17,7 @@ #include <linux/irq.h> #include <linux/kernel.h> #include <linux/spinlock.h> +#include <linux/irqdomain.h> #include <linux/io.h> #include <mach/ilsel.h> #include <mach/hardware.h> @@ -26,7 +27,7 @@ #define KEYDETR 0xb81c0004 static DEFINE_SPINLOCK(x3proto_gpio_lock); -static unsigned int x3proto_gpio_irq_map[NR_BASEBOARD_GPIOS] = { 0, }; +static struct irq_domain *x3proto_irq_domain; static int x3proto_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) { @@ -49,7 +50,14 @@ static int x3proto_gpio_get(struct gpio_chip *chip, unsigned gpio) static int x3proto_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) { - return x3proto_gpio_irq_map[gpio]; + int virq; + + if (gpio < chip->ngpio) + virq = irq_create_mapping(x3proto_irq_domain, gpio); + else + virq = -ENXIO; + + return virq; } static void x3proto_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) @@ -62,9 +70,8 @@ static void x3proto_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) chip->irq_mask_ack(data); mask = __raw_readw(KEYDETR); - for_each_set_bit(pin, &mask, NR_BASEBOARD_GPIOS) - generic_handle_irq(x3proto_gpio_to_irq(NULL, pin)); + generic_handle_irq(irq_linear_revmap(x3proto_irq_domain, pin)); chip->irq_unmask(data); } @@ -78,10 +85,23 @@ struct gpio_chip x3proto_gpio_chip = { .ngpio = NR_BASEBOARD_GPIOS, }; +static int x3proto_gpio_irq_map(struct irq_domain *domain, unsigned int virq, + irq_hw_number_t hwirq) +{ + irq_set_chip_and_handler_name(virq, &dummy_irq_chip, handle_simple_irq, + "gpio"); + + return 0; +} + +static struct irq_domain_ops x3proto_gpio_irq_ops = { + .map = x3proto_gpio_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + int __init x3proto_gpio_setup(void) { - int ilsel; - int ret, i; + int ilsel, ret; ilsel = ilsel_enable(ILSEL_KEY); if (unlikely(ilsel < 0)) @@ -91,21 +111,10 @@ int __init x3proto_gpio_setup(void) if (unlikely(ret)) goto err_gpio; - for (i = 0; i < NR_BASEBOARD_GPIOS; i++) { - unsigned long flags; - int irq = create_irq(); - - if (unlikely(irq < 0)) { - ret = -EINVAL; - goto err_irq; - } - - spin_lock_irqsave(&x3proto_gpio_lock, flags); - x3proto_gpio_irq_map[i] = irq; - irq_set_chip_and_handler_name(irq, &dummy_irq_chip, - handle_simple_irq, "gpio"); - spin_unlock_irqrestore(&x3proto_gpio_lock, flags); - } + x3proto_irq_domain = irq_domain_add_linear(NULL, NR_BASEBOARD_GPIOS, + &x3proto_gpio_irq_ops, NULL); + if (unlikely(!x3proto_irq_domain)) + goto err_irq; pr_info("registering '%s' support, handling GPIOs %u -> %u, " "bound to IRQ %u\n", @@ -119,10 +128,6 @@ int __init x3proto_gpio_setup(void) return 0; err_irq: - for (; i >= 0; --i) - if (x3proto_gpio_irq_map[i]) - destroy_irq(x3proto_gpio_irq_map[i]); - ret = gpiochip_remove(&x3proto_gpio_chip); if (unlikely(ret)) pr_err("Failed deregistering GPIO\n"); diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c index eb4ea4d44d59..e9735616bdc8 100644 --- a/arch/sh/cchips/hd6446x/hd64461.c +++ b/arch/sh/cchips/hd6446x/hd64461.c @@ -73,10 +73,7 @@ static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc) int __init setup_hd64461(void) { - int i, nid = cpu_to_node(boot_cpu_data); - - if (!MACH_HD64461) - return 0; + int irq_base, i; printk(KERN_INFO "HD64461 configured at 0x%x on irq %d(mapped into %d to %d)\n", @@ -89,28 +86,16 @@ int __init setup_hd64461(void) #endif __raw_writew(0xffff, HD64461_NIMR); - /* IRQ 80 -> 95 belongs to HD64461 */ - for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { - unsigned int irq; - - irq = create_irq_nr(i, nid); - if (unlikely(irq == 0)) { - pr_err("%s: failed hooking irq %d for HD64461\n", - __func__, i); - return -EBUSY; - } - - if (unlikely(irq != i)) { - pr_err("%s: got irq %d but wanted %d, bailing.\n", - __func__, irq, i); - destroy_irq(irq); - return -EINVAL; - } - - irq_set_chip_and_handler(i, &hd64461_irq_chip, - handle_level_irq); + irq_base = irq_alloc_descs(HD64461_IRQBASE, HD64461_IRQBASE, 16, -1); + if (IS_ERR_VALUE(irq_base)) { + pr_err("%s: failed hooking irqs for HD64461\n", __func__); + return irq_base; } + for (i = 0; i < 16; i++) + irq_set_chip_and_handler(irq_base + i, &hd64461_irq_chip, + handle_level_irq); + irq_set_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux); irq_set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW); diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild index 7beb42322f60..7b673ddcd555 100644 --- a/arch/sh/include/asm/Kbuild +++ b/arch/sh/include/asm/Kbuild @@ -1,5 +1,39 @@ include include/asm-generic/Kbuild.asm +generic-y += bitsperlong.h +generic-y += cputime.h +generic-y += current.h +generic-y += delay.h +generic-y += div64.h +generic-y += emergency-restart.h +generic-y += errno.h +generic-y += fcntl.h +generic-y += ioctl.h +generic-y += ipcbuf.h +generic-y += irq_regs.h +generic-y += kvm_para.h +generic-y += local.h +generic-y += local64.h +generic-y += param.h +generic-y += parport.h +generic-y += percpu.h +generic-y += poll.h +generic-y += mman.h +generic-y += msgbuf.h +generic-y += resource.h +generic-y += scatterlist.h +generic-y += sembuf.h +generic-y += serial.h +generic-y += shmbuf.h +generic-y += siginfo.h +generic-y += sizes.h +generic-y += socket.h +generic-y += statfs.h +generic-y += termbits.h +generic-y += termios.h +generic-y += ucontext.h +generic-y += xor.h + header-y += cachectl.h header-y += cpu-features.h header-y += hw_breakpoint.h diff --git a/arch/sh/include/asm/bitsperlong.h b/arch/sh/include/asm/bitsperlong.h deleted file mode 100644 index 6dc0bb0c13b2..000000000000 --- a/arch/sh/include/asm/bitsperlong.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/bitsperlong.h> diff --git a/arch/sh/include/asm/cputime.h b/arch/sh/include/asm/cputime.h deleted file mode 100644 index 6ca395d1393e..000000000000 --- a/arch/sh/include/asm/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __SH_CPUTIME_H -#define __SH_CPUTIME_H - -#include <asm-generic/cputime.h> - -#endif /* __SH_CPUTIME_H */ diff --git a/arch/sh/include/asm/current.h b/arch/sh/include/asm/current.h deleted file mode 100644 index 4c51401b5537..000000000000 --- a/arch/sh/include/asm/current.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/current.h> diff --git a/arch/sh/include/asm/delay.h b/arch/sh/include/asm/delay.h deleted file mode 100644 index 9670e127b7b2..000000000000 --- a/arch/sh/include/asm/delay.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/delay.h> diff --git a/arch/sh/include/asm/div64.h b/arch/sh/include/asm/div64.h deleted file mode 100644 index 6cd978cefb28..000000000000 --- a/arch/sh/include/asm/div64.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/div64.h> diff --git a/arch/sh/include/asm/emergency-restart.h b/arch/sh/include/asm/emergency-restart.h deleted file mode 100644 index 108d8c48e42e..000000000000 --- a/arch/sh/include/asm/emergency-restart.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - -#include <asm-generic/emergency-restart.h> - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/arch/sh/include/asm/errno.h b/arch/sh/include/asm/errno.h deleted file mode 100644 index 51cf6f9cebb8..000000000000 --- a/arch/sh/include/asm/errno.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_SH_ERRNO_H -#define __ASM_SH_ERRNO_H - -#include <asm-generic/errno.h> - -#endif /* __ASM_SH_ERRNO_H */ diff --git a/arch/sh/include/asm/fcntl.h b/arch/sh/include/asm/fcntl.h deleted file mode 100644 index 46ab12db5739..000000000000 --- a/arch/sh/include/asm/fcntl.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/fcntl.h> diff --git a/arch/sh/include/asm/ioctl.h b/arch/sh/include/asm/ioctl.h deleted file mode 100644 index b279fe06dfe5..000000000000 --- a/arch/sh/include/asm/ioctl.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ioctl.h> diff --git a/arch/sh/include/asm/ipcbuf.h b/arch/sh/include/asm/ipcbuf.h deleted file mode 100644 index 84c7e51cb6d0..000000000000 --- a/arch/sh/include/asm/ipcbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ipcbuf.h> diff --git a/arch/sh/include/asm/irq_regs.h b/arch/sh/include/asm/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/arch/sh/include/asm/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/irq_regs.h> diff --git a/arch/sh/include/asm/kdebug.h b/arch/sh/include/asm/kdebug.h index a6201f10c273..8d6a831e7ba1 100644 --- a/arch/sh/include/asm/kdebug.h +++ b/arch/sh/include/asm/kdebug.h @@ -10,6 +10,8 @@ enum die_val { DIE_SSTEP, }; +/* arch/sh/kernel/dumpstack.c */ extern void printk_address(unsigned long address, int reliable); +extern void dump_mem(const char *str, unsigned long bottom, unsigned long top); #endif /* __ASM_SH_KDEBUG_H */ diff --git a/arch/sh/include/asm/local.h b/arch/sh/include/asm/local.h deleted file mode 100644 index 9ed9b9cb459a..000000000000 --- a/arch/sh/include/asm/local.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_SH_LOCAL_H -#define __ASM_SH_LOCAL_H - -#include <asm-generic/local.h> - -#endif /* __ASM_SH_LOCAL_H */ - diff --git a/arch/sh/include/asm/local64.h b/arch/sh/include/asm/local64.h deleted file mode 100644 index 36c93b5cc239..000000000000 --- a/arch/sh/include/asm/local64.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/local64.h> diff --git a/arch/sh/include/asm/mman.h b/arch/sh/include/asm/mman.h deleted file mode 100644 index 8eebf89f5ab1..000000000000 --- a/arch/sh/include/asm/mman.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/mman.h> diff --git a/arch/sh/include/asm/msgbuf.h b/arch/sh/include/asm/msgbuf.h deleted file mode 100644 index 809134c644a6..000000000000 --- a/arch/sh/include/asm/msgbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/msgbuf.h> diff --git a/arch/sh/include/asm/param.h b/arch/sh/include/asm/param.h deleted file mode 100644 index 965d45427975..000000000000 --- a/arch/sh/include/asm/param.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/param.h> diff --git a/arch/sh/include/asm/parport.h b/arch/sh/include/asm/parport.h deleted file mode 100644 index cf252af64590..000000000000 --- a/arch/sh/include/asm/parport.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/parport.h> diff --git a/arch/sh/include/asm/percpu.h b/arch/sh/include/asm/percpu.h deleted file mode 100644 index 4db4b39a4399..000000000000 --- a/arch/sh/include/asm/percpu.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ARCH_SH_PERCPU -#define __ARCH_SH_PERCPU - -#include <asm-generic/percpu.h> - -#endif /* __ARCH_SH_PERCPU */ diff --git a/arch/sh/include/asm/poll.h b/arch/sh/include/asm/poll.h deleted file mode 100644 index c98509d3149e..000000000000 --- a/arch/sh/include/asm/poll.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/poll.h> diff --git a/arch/sh/include/asm/posix_types_32.h b/arch/sh/include/asm/posix_types_32.h index abda58467ece..ba0bdc423b07 100644 --- a/arch/sh/include/asm/posix_types_32.h +++ b/arch/sh/include/asm/posix_types_32.h @@ -3,8 +3,6 @@ typedef unsigned short __kernel_mode_t; #define __kernel_mode_t __kernel_mode_t -typedef unsigned short __kernel_nlink_t; -#define __kernel_nlink_t __kernel_nlink_t typedef unsigned short __kernel_ipc_pid_t; #define __kernel_ipc_pid_t __kernel_ipc_pid_t typedef unsigned short __kernel_uid_t; diff --git a/arch/sh/include/asm/posix_types_64.h b/arch/sh/include/asm/posix_types_64.h index fcda07b4a616..244f7e950e17 100644 --- a/arch/sh/include/asm/posix_types_64.h +++ b/arch/sh/include/asm/posix_types_64.h @@ -3,8 +3,6 @@ typedef unsigned short __kernel_mode_t; #define __kernel_mode_t __kernel_mode_t -typedef unsigned short __kernel_nlink_t; -#define __kernel_nlink_t __kernel_nlink_t typedef unsigned short __kernel_ipc_pid_t; #define __kernel_ipc_pid_t __kernel_ipc_pid_t typedef unsigned short __kernel_uid_t; diff --git a/arch/sh/include/asm/resource.h b/arch/sh/include/asm/resource.h deleted file mode 100644 index 9c2499a86ec0..000000000000 --- a/arch/sh/include/asm/resource.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_SH_RESOURCE_H -#define __ASM_SH_RESOURCE_H - -#include <asm-generic/resource.h> - -#endif /* __ASM_SH_RESOURCE_H */ diff --git a/arch/sh/include/asm/scatterlist.h b/arch/sh/include/asm/scatterlist.h deleted file mode 100644 index 98dfc3510f10..000000000000 --- a/arch/sh/include/asm/scatterlist.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_SH_SCATTERLIST_H -#define __ASM_SH_SCATTERLIST_H - -#include <asm-generic/scatterlist.h> - -#endif /* __ASM_SH_SCATTERLIST_H */ diff --git a/arch/sh/include/asm/sembuf.h b/arch/sh/include/asm/sembuf.h deleted file mode 100644 index 7673b83cfef7..000000000000 --- a/arch/sh/include/asm/sembuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/sembuf.h> diff --git a/arch/sh/include/asm/serial.h b/arch/sh/include/asm/serial.h deleted file mode 100644 index a0cb0caff152..000000000000 --- a/arch/sh/include/asm/serial.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/serial.h> diff --git a/arch/sh/include/asm/shmbuf.h b/arch/sh/include/asm/shmbuf.h deleted file mode 100644 index 83c05fc2de38..000000000000 --- a/arch/sh/include/asm/shmbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/shmbuf.h> diff --git a/arch/sh/include/asm/siginfo.h b/arch/sh/include/asm/siginfo.h deleted file mode 100644 index 813040ed68a9..000000000000 --- a/arch/sh/include/asm/siginfo.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_SH_SIGINFO_H -#define __ASM_SH_SIGINFO_H - -#include <asm-generic/siginfo.h> - -#endif /* __ASM_SH_SIGINFO_H */ diff --git a/arch/sh/include/asm/sizes.h b/arch/sh/include/asm/sizes.h deleted file mode 100644 index dd248c2e1085..000000000000 --- a/arch/sh/include/asm/sizes.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/sizes.h> diff --git a/arch/sh/include/asm/socket.h b/arch/sh/include/asm/socket.h deleted file mode 100644 index 6b71384b9d8b..000000000000 --- a/arch/sh/include/asm/socket.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/socket.h> diff --git a/arch/sh/include/asm/statfs.h b/arch/sh/include/asm/statfs.h deleted file mode 100644 index 9202a023328f..000000000000 --- a/arch/sh/include/asm/statfs.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_SH_STATFS_H -#define __ASM_SH_STATFS_H - -#include <asm-generic/statfs.h> - -#endif /* __ASM_SH_STATFS_H */ diff --git a/arch/sh/include/asm/termbits.h b/arch/sh/include/asm/termbits.h deleted file mode 100644 index 3935b106de79..000000000000 --- a/arch/sh/include/asm/termbits.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/termbits.h> diff --git a/arch/sh/include/asm/termios.h b/arch/sh/include/asm/termios.h deleted file mode 100644 index 280d78a9d966..000000000000 --- a/arch/sh/include/asm/termios.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/termios.h> diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index 0c04ffc4f12c..bc13b57cdc83 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -169,7 +169,7 @@ static inline void set_restore_sigmask(void) { struct thread_info *ti = current_thread_info(); ti->status |= TS_RESTORE_SIGMASK; - set_bit(TIF_SIGPENDING, (unsigned long *)&ti->flags); + WARN_ON(!test_bit(TIF_SIGPENDING, (unsigned long *)&ti->flags)); } #define TI_FLAG_FAULT_CODE_SHIFT 24 @@ -189,6 +189,23 @@ static inline unsigned int get_thread_fault_code(void) struct thread_info *ti = current_thread_info(); return ti->flags >> TI_FLAG_FAULT_CODE_SHIFT; } + +static inline void clear_restore_sigmask(void) +{ + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; +} +static inline bool test_restore_sigmask(void) +{ + return current_thread_info()->status & TS_RESTORE_SIGMASK; +} +static inline bool test_and_clear_restore_sigmask(void) +{ + struct thread_info *ti = current_thread_info(); + if (!(ti->status & TS_RESTORE_SIGMASK)) + return false; + ti->status &= ~TS_RESTORE_SIGMASK; + return true; +} #endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/arch/sh/include/asm/uaccess.h b/arch/sh/include/asm/uaccess.h index 050f221fa898..8698a80ed00c 100644 --- a/arch/sh/include/asm/uaccess.h +++ b/arch/sh/include/asm/uaccess.h @@ -25,6 +25,8 @@ (__chk_user_ptr(addr), \ __access_ok((unsigned long __force)(addr), (size))) +#define user_addr_max() (current_thread_info()->addr_limit.seg) + /* * Uh, these should become the main single-value transfer routines ... * They automatically use the right size if we just have the right @@ -100,6 +102,11 @@ struct __large_struct { unsigned long buf[100]; }; # include "uaccess_64.h" #endif +extern long strncpy_from_user(char *dest, const char __user *src, long count); + +extern __must_check long strlen_user(const char __user *str); +extern __must_check long strnlen_user(const char __user *str, long n); + /* Generic arbitrary sized copy. */ /* Return the number of bytes NOT copied */ __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); @@ -137,37 +144,6 @@ __kernel_size_t __clear_user(void *addr, __kernel_size_t size); __cl_size; \ }) -/** - * strncpy_from_user: - Copy a NUL terminated string from userspace. - * @dst: Destination address, in kernel space. This buffer must be at - * least @count bytes long. - * @src: Source address, in user space. - * @count: Maximum number of bytes to copy, including the trailing NUL. - * - * Copies a NUL-terminated string from userspace to kernel space. - * - * On success, returns the length of the string (not including the trailing - * NUL). - * - * If access to userspace fails, returns -EFAULT (some data may have been - * copied). - * - * If @count is smaller than the length of the string, copies @count bytes - * and returns @count. - */ -#define strncpy_from_user(dest,src,count) \ -({ \ - unsigned long __sfu_src = (unsigned long)(src); \ - int __sfu_count = (int)(count); \ - long __sfu_res = -EFAULT; \ - \ - if (__access_ok(__sfu_src, __sfu_count)) \ - __sfu_res = __strncpy_from_user((unsigned long)(dest), \ - __sfu_src, __sfu_count); \ - \ - __sfu_res; \ -}) - static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) { @@ -192,43 +168,6 @@ copy_to_user(void __user *to, const void *from, unsigned long n) return __copy_size; } -/** - * strnlen_user: - Get the size of a string in user space. - * @s: The string to measure. - * @n: The maximum valid length - * - * Context: User context only. This function may sleep. - * - * Get the size of a NUL-terminated string in user space. - * - * Returns the size of the string INCLUDING the terminating NUL. - * On exception, returns 0. - * If the string is too long, returns a value greater than @n. - */ -static inline long strnlen_user(const char __user *s, long n) -{ - if (!__addr_ok(s)) - return 0; - else - return __strnlen_user(s, n); -} - -/** - * strlen_user: - Get the size of a string in user space. - * @str: The string to measure. - * - * Context: User context only. This function may sleep. - * - * Get the size of a NUL-terminated string in user space. - * - * Returns the size of the string INCLUDING the terminating NUL. - * On exception, returns 0. - * - * If there is a limit on the length of a valid string, you may wish to - * consider using strnlen_user() instead. - */ -#define strlen_user(str) strnlen_user(str, ~0UL >> 1) - /* * The exception table consists of pairs of addresses: the first is the * address of an instruction that is allowed to fault, and the second is diff --git a/arch/sh/include/asm/uaccess_32.h b/arch/sh/include/asm/uaccess_32.h index ae0d24f6653f..c0de7ee35ab7 100644 --- a/arch/sh/include/asm/uaccess_32.h +++ b/arch/sh/include/asm/uaccess_32.h @@ -170,79 +170,4 @@ __asm__ __volatile__( \ extern void __put_user_unknown(void); -static inline int -__strncpy_from_user(unsigned long __dest, unsigned long __user __src, int __count) -{ - __kernel_size_t res; - unsigned long __dummy, _d, _s, _c; - - __asm__ __volatile__( - "9:\n" - "mov.b @%2+, %1\n\t" - "cmp/eq #0, %1\n\t" - "bt/s 2f\n" - "1:\n" - "mov.b %1, @%3\n\t" - "dt %4\n\t" - "bf/s 9b\n\t" - " add #1, %3\n\t" - "2:\n\t" - "sub %4, %0\n" - "3:\n" - ".section .fixup,\"ax\"\n" - "4:\n\t" - "mov.l 5f, %1\n\t" - "jmp @%1\n\t" - " mov %9, %0\n\t" - ".balign 4\n" - "5: .long 3b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .balign 4\n" - " .long 9b,4b\n" - ".previous" - : "=r" (res), "=&z" (__dummy), "=r" (_s), "=r" (_d), "=r"(_c) - : "0" (__count), "2" (__src), "3" (__dest), "4" (__count), - "i" (-EFAULT) - : "memory", "t"); - - return res; -} - -/* - * Return the size of a string (including the ending 0 even when we have - * exceeded the maximum string length). - */ -static inline long __strnlen_user(const char __user *__s, long __n) -{ - unsigned long res; - unsigned long __dummy; - - __asm__ __volatile__( - "1:\t" - "mov.b @(%0,%3), %1\n\t" - "cmp/eq %4, %0\n\t" - "bt/s 2f\n\t" - " add #1, %0\n\t" - "tst %1, %1\n\t" - "bf 1b\n\t" - "2:\n" - ".section .fixup,\"ax\"\n" - "3:\n\t" - "mov.l 4f, %1\n\t" - "jmp @%1\n\t" - " mov #0, %0\n" - ".balign 4\n" - "4: .long 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .balign 4\n" - " .long 1b,3b\n" - ".previous" - : "=z" (res), "=&r" (__dummy) - : "0" (0), "r" (__s), "r" (__n) - : "t"); - return res; -} - #endif /* __ASM_SH_UACCESS_32_H */ diff --git a/arch/sh/include/asm/uaccess_64.h b/arch/sh/include/asm/uaccess_64.h index 56fd20b8cdcc..2e07e0f40c6a 100644 --- a/arch/sh/include/asm/uaccess_64.h +++ b/arch/sh/include/asm/uaccess_64.h @@ -84,8 +84,4 @@ extern long __put_user_asm_l(void *, long); extern long __put_user_asm_q(void *, long); extern void __put_user_unknown(void); -extern long __strnlen_user(const char *__s, long __n); -extern int __strncpy_from_user(unsigned long __dest, - unsigned long __user __src, int __count); - #endif /* __ASM_SH_UACCESS_64_H */ diff --git a/arch/sh/include/asm/ucontext.h b/arch/sh/include/asm/ucontext.h deleted file mode 100644 index 9bc07b9f30fb..000000000000 --- a/arch/sh/include/asm/ucontext.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ucontext.h> diff --git a/arch/sh/include/asm/word-at-a-time.h b/arch/sh/include/asm/word-at-a-time.h new file mode 100644 index 000000000000..6e38953ff7fd --- /dev/null +++ b/arch/sh/include/asm/word-at-a-time.h @@ -0,0 +1,53 @@ +#ifndef __ASM_SH_WORD_AT_A_TIME_H +#define __ASM_SH_WORD_AT_A_TIME_H + +#ifdef CONFIG_CPU_BIG_ENDIAN +# include <asm-generic/word-at-a-time.h> +#else +/* + * Little-endian version cribbed from x86. + */ +struct word_at_a_time { + const unsigned long one_bits, high_bits; +}; + +#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) } + +/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */ +static inline long count_masked_bytes(long mask) +{ + /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */ + long a = (0x0ff0001+mask) >> 23; + /* Fix the 1 for 00 case */ + return a & mask; +} + +/* Return nonzero if it has a zero */ +static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c) +{ + unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits; + *bits = mask; + return mask; +} + +static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c) +{ + return bits; +} + +static inline unsigned long create_zero_mask(unsigned long bits) +{ + bits = (bits - 1) & ~bits; + return bits >> 7; +} + +/* The mask we created is directly usable as a bytemask */ +#define zero_bytemask(mask) (mask) + +static inline unsigned long find_zero(unsigned long mask) +{ + return count_masked_bytes(mask); +} +#endif + +#endif diff --git a/arch/sh/include/asm/xor.h b/arch/sh/include/asm/xor.h deleted file mode 100644 index c82eb12a5b18..000000000000 --- a/arch/sh/include/asm/xor.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/xor.h> diff --git a/arch/sh/include/cpu-sh2a/cpu/ubc.h b/arch/sh/include/cpu-sh2a/cpu/ubc.h deleted file mode 100644 index 1192e1c761a7..000000000000 --- a/arch/sh/include/cpu-sh2a/cpu/ubc.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * SH-2A UBC definitions - * - * Copyright (C) 2008 Kieran Bingham - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ - -#ifndef __ASM_CPU_SH2A_UBC_H -#define __ASM_CPU_SH2A_UBC_H - -#define UBC_BARA 0xfffc0400 -#define UBC_BAMRA 0xfffc0404 -#define UBC_BBRA 0xfffc04a0 /* 16 bit access */ -#define UBC_BDRA 0xfffc0408 -#define UBC_BDMRA 0xfffc040c - -#define UBC_BARB 0xfffc0410 -#define UBC_BAMRB 0xfffc0414 -#define UBC_BBRB 0xfffc04b0 /* 16 bit access */ -#define UBC_BDRB 0xfffc0418 -#define UBC_BDMRB 0xfffc041c - -#define UBC_BRCR 0xfffc04c0 - -#endif /* __ASM_CPU_SH2A_UBC_H */ diff --git a/arch/sh/include/mach-se/mach/se7343.h b/arch/sh/include/mach-se/mach/se7343.h index 50b5d575dff0..542521c970c6 100644 --- a/arch/sh/include/mach-se/mach/se7343.h +++ b/arch/sh/include/mach-se/mach/se7343.h @@ -50,9 +50,6 @@ #define PA_LED 0xb0C00000 /* LED */ #define LED_SHIFT 0 #define PA_DIPSW 0xb0900000 /* Dip switch 31 */ -#define PA_CPLD_MODESET 0xb1400004 /* CPLD Mode set register */ -#define PA_CPLD_ST 0xb1400008 /* CPLD Interrupt status register */ -#define PA_CPLD_IMSK 0xb140000a /* CPLD Interrupt mask register */ /* Area 5 */ #define PA_EXT5 0x14000000 #define PA_EXT5_SIZE 0x04000000 @@ -135,8 +132,10 @@ #define SE7343_FPGA_IRQ_NR 12 +struct irq_domain; + /* arch/sh/boards/se/7343/irq.c */ -extern unsigned int se7343_fpga_irq[]; +extern struct irq_domain *se7343_irq_domain; void init_7343se_IRQ(void); diff --git a/arch/sh/include/mach-se/mach/se7722.h b/arch/sh/include/mach-se/mach/se7722.h index 201081ebdbce..637e7ac753f8 100644 --- a/arch/sh/include/mach-se/mach/se7722.h +++ b/arch/sh/include/mach-se/mach/se7722.h @@ -81,12 +81,6 @@ #define IRQ0_IRQ evt2irq(0x600) #define IRQ1_IRQ evt2irq(0x620) -#define IRQ01_MODE 0xb1800000 -#define IRQ01_STS 0xb1800004 -#define IRQ01_MASK 0xb1800008 - -/* Bits in IRQ01_* registers */ - #define SE7722_FPGA_IRQ_USB 0 /* IRQ0 */ #define SE7722_FPGA_IRQ_SMC 1 /* IRQ0 */ #define SE7722_FPGA_IRQ_MRSHPC0 2 /* IRQ1 */ @@ -95,8 +89,10 @@ #define SE7722_FPGA_IRQ_MRSHPC3 5 /* IRQ1 */ #define SE7722_FPGA_IRQ_NR 6 +struct irq_domain; + /* arch/sh/boards/se/7722/irq.c */ -extern unsigned int se7722_fpga_irq[]; +extern struct irq_domain *se7722_irq_domain; void init_se7722_IRQ(void); diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S index ff1f0e6e9bec..b7cf6a547f11 100644 --- a/arch/sh/kernel/cpu/sh5/entry.S +++ b/arch/sh/kernel/cpu/sh5/entry.S @@ -1569,86 +1569,6 @@ ___clear_user_exit: #endif /* CONFIG_MMU */ /* - * int __strncpy_from_user(unsigned long __dest, unsigned long __src, - * int __count) - * - * Inputs: - * (r2) target address - * (r3) source address - * (r4) maximum size in bytes - * - * Ouputs: - * (*r2) copied data - * (r2) -EFAULT (in case of faulting) - * copied data (otherwise) - */ - .global __strncpy_from_user -__strncpy_from_user: - pta ___strncpy_from_user1, tr0 - pta ___strncpy_from_user_done, tr1 - or r4, ZERO, r5 /* r5 = original count */ - beq/u r4, r63, tr1 /* early exit if r4==0 */ - movi -(EFAULT), r6 /* r6 = reply, no real fixup */ - or ZERO, ZERO, r7 /* r7 = data, clear top byte of data */ - -___strncpy_from_user1: - ld.b r3, 0, r7 /* Fault address: only in reading */ - st.b r2, 0, r7 - addi r2, 1, r2 - addi r3, 1, r3 - beq/u ZERO, r7, tr1 - addi r4, -1, r4 /* return real number of copied bytes */ - bne/l ZERO, r4, tr0 - -___strncpy_from_user_done: - sub r5, r4, r6 /* If done, return copied */ - -___strncpy_from_user_exit: - or r6, ZERO, r2 - ptabs LINK, tr0 - blink tr0, ZERO - -/* - * extern long __strnlen_user(const char *__s, long __n) - * - * Inputs: - * (r2) source address - * (r3) source size in bytes - * - * Ouputs: - * (r2) -EFAULT (in case of faulting) - * string length (otherwise) - */ - .global __strnlen_user -__strnlen_user: - pta ___strnlen_user_set_reply, tr0 - pta ___strnlen_user1, tr1 - or ZERO, ZERO, r5 /* r5 = counter */ - movi -(EFAULT), r6 /* r6 = reply, no real fixup */ - or ZERO, ZERO, r7 /* r7 = data, clear top byte of data */ - beq r3, ZERO, tr0 - -___strnlen_user1: - ldx.b r2, r5, r7 /* Fault address: only in reading */ - addi r3, -1, r3 /* No real fixup */ - addi r5, 1, r5 - beq r3, ZERO, tr0 - bne r7, ZERO, tr1 -! The line below used to be active. This meant led to a junk byte lying between each pair -! of entries in the argv & envp structures in memory. Whilst the program saw the right data -! via the argv and envp arguments to main, it meant the 'flat' representation visible through -! /proc/$pid/cmdline was corrupt, causing trouble with ps, for example. -! addi r5, 1, r5 /* Include '\0' */ - -___strnlen_user_set_reply: - or r5, ZERO, r6 /* If done, return counter */ - -___strnlen_user_exit: - or r6, ZERO, r2 - ptabs LINK, tr0 - blink tr0, ZERO - -/* * extern long __get_user_asm_?(void *val, long addr) * * Inputs: @@ -1982,8 +1902,6 @@ asm_uaccess_start: .long ___copy_user2, ___copy_user_exit .long ___clear_user1, ___clear_user_exit #endif - .long ___strncpy_from_user1, ___strncpy_from_user_exit - .long ___strnlen_user1, ___strnlen_user_exit .long ___get_user_asm_b1, ___get_user_asm_b_exit .long ___get_user_asm_w1, ___get_user_asm_w_exit .long ___get_user_asm_l1, ___get_user_asm_l_exit diff --git a/arch/sh/kernel/cpu/sh5/unwind.c b/arch/sh/kernel/cpu/sh5/unwind.c index b205b25eaf45..10aed41757fc 100644 --- a/arch/sh/kernel/cpu/sh5/unwind.c +++ b/arch/sh/kernel/cpu/sh5/unwind.c @@ -16,6 +16,8 @@ #include <asm/ptrace.h> #include <asm/processor.h> #include <asm/io.h> +#include <asm/unwinder.h> +#include <asm/stacktrace.h> static u8 regcache[63]; @@ -199,8 +201,11 @@ static int lookup_prev_stack_frame(unsigned long fp, unsigned long pc, return 0; } -/* Don't put this on the stack since we'll want to call sh64_unwind - * when we're close to underflowing the stack anyway. */ +/* + * Don't put this on the stack since we'll want to call in to + * sh64_unwinder_dump() when we're close to underflowing the stack + * anyway. + */ static struct pt_regs here_regs; extern const char syscall_ret; @@ -208,17 +213,19 @@ extern const char ret_from_syscall; extern const char ret_from_exception; extern const char ret_from_irq; -static void sh64_unwind_inner(struct pt_regs *regs); +static void sh64_unwind_inner(const struct stacktrace_ops *ops, + void *data, struct pt_regs *regs); -static void unwind_nested (unsigned long pc, unsigned long fp) +static inline void unwind_nested(const struct stacktrace_ops *ops, void *data, + unsigned long pc, unsigned long fp) { if ((fp >= __MEMORY_START) && - ((fp & 7) == 0)) { - sh64_unwind_inner((struct pt_regs *) fp); - } + ((fp & 7) == 0)) + sh64_unwind_inner(ops, data, (struct pt_regs *)fp); } -static void sh64_unwind_inner(struct pt_regs *regs) +static void sh64_unwind_inner(const struct stacktrace_ops *ops, + void *data, struct pt_regs *regs) { unsigned long pc, fp; int ofs = 0; @@ -232,29 +239,29 @@ static void sh64_unwind_inner(struct pt_regs *regs) int cond; unsigned long next_fp, next_pc; - if (pc == ((unsigned long) &syscall_ret & ~1)) { + if (pc == ((unsigned long)&syscall_ret & ~1)) { printk("SYSCALL\n"); - unwind_nested(pc,fp); + unwind_nested(ops, data, pc, fp); return; } - if (pc == ((unsigned long) &ret_from_syscall & ~1)) { + if (pc == ((unsigned long)&ret_from_syscall & ~1)) { printk("SYSCALL (PREEMPTED)\n"); - unwind_nested(pc,fp); + unwind_nested(ops, data, pc, fp); return; } /* In this case, the PC is discovered by lookup_prev_stack_frame but it has 4 taken off it to look like the 'caller' */ - if (pc == ((unsigned long) &ret_from_exception & ~1)) { + if (pc == ((unsigned long)&ret_from_exception & ~1)) { printk("EXCEPTION\n"); - unwind_nested(pc,fp); + unwind_nested(ops, data, pc, fp); return; } - if (pc == ((unsigned long) &ret_from_irq & ~1)) { + if (pc == ((unsigned long)&ret_from_irq & ~1)) { printk("IRQ\n"); - unwind_nested(pc,fp); + unwind_nested(ops, data, pc, fp); return; } @@ -263,8 +270,7 @@ static void sh64_unwind_inner(struct pt_regs *regs) pc -= ofs; - printk("[<%08lx>] ", pc); - print_symbol("%s\n", pc); + ops->address(data, pc, 1); if (first_pass) { /* If the innermost frame is a leaf function, it's @@ -287,10 +293,13 @@ static void sh64_unwind_inner(struct pt_regs *regs) } printk("\n"); - } -void sh64_unwind(struct pt_regs *regs) +static void sh64_unwinder_dump(struct task_struct *task, + struct pt_regs *regs, + unsigned long *sp, + const struct stacktrace_ops *ops, + void *data) { if (!regs) { /* @@ -320,7 +329,17 @@ void sh64_unwind(struct pt_regs *regs) ); } - printk("\nCall Trace:\n"); - sh64_unwind_inner(regs); + sh64_unwind_inner(ops, data, regs); } +static struct unwinder sh64_unwinder = { + .name = "sh64-unwinder", + .dump = sh64_unwinder_dump, + .rating = 150, +}; + +static int __init sh64_unwinder_init(void) +{ + return unwinder_register(&sh64_unwinder); +} +early_initcall(sh64_unwinder_init); diff --git a/arch/sh/kernel/dumpstack.c b/arch/sh/kernel/dumpstack.c index 694158b9a50f..7617dc4129ac 100644 --- a/arch/sh/kernel/dumpstack.c +++ b/arch/sh/kernel/dumpstack.c @@ -2,13 +2,48 @@ * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs * Copyright (C) 2009 Matt Fleming + * Copyright (C) 2002 - 2012 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/kallsyms.h> #include <linux/ftrace.h> #include <linux/debug_locks.h> +#include <linux/kdebug.h> +#include <linux/export.h> +#include <linux/uaccess.h> #include <asm/unwinder.h> #include <asm/stacktrace.h> +void dump_mem(const char *str, unsigned long bottom, unsigned long top) +{ + unsigned long p; + int i; + + printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); + + for (p = bottom & ~31; p < top; ) { + printk("%04lx: ", p & 0xffff); + + for (i = 0; i < 8; i++, p += 4) { + unsigned int val; + + if (p < bottom || p >= top) + printk(" "); + else { + if (__get_user(val, (unsigned int __user *)p)) { + printk("\n"); + return; + } + printk("%08x ", val); + } + } + printk("\n"); + } +} + void printk_address(unsigned long address, int reliable) { printk(" [<%p>] %s%pS\n", (void *) address, @@ -106,3 +141,26 @@ void show_trace(struct task_struct *tsk, unsigned long *sp, debug_show_held_locks(tsk); } + +void show_stack(struct task_struct *tsk, unsigned long *sp) +{ + unsigned long stack; + + if (!tsk) + tsk = current; + if (tsk == current) + sp = (unsigned long *)current_stack_pointer; + else + sp = (unsigned long *)tsk->thread.sp; + + stack = (unsigned long)sp; + dump_mem("Stack: ", stack, THREAD_SIZE + + (unsigned long)task_stack_page(tsk)); + show_trace(tsk, sp, NULL); +} + +void dump_stack(void) +{ + show_stack(NULL, NULL); +} +EXPORT_SYMBOL(dump_stack); diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 9b7a459a4613..055d91b70305 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -4,6 +4,7 @@ #include <linux/sched.h> #include <linux/export.h> #include <linux/stackprotector.h> +#include <asm/fpu.h> struct kmem_cache *task_xstate_cachep = NULL; unsigned int xstate_size; diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index 4264583eabac..602545b12a86 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c @@ -33,6 +33,7 @@ #include <asm/switch_to.h> struct task_struct *last_task_used_math = NULL; +struct pt_regs fake_swapper_regs = { 0, }; void show_regs(struct pt_regs *regs) { diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c index 45afa5c51f67..26a0774f5272 100644 --- a/arch/sh/kernel/sh_ksyms_64.c +++ b/arch/sh/kernel/sh_ksyms_64.c @@ -32,8 +32,6 @@ EXPORT_SYMBOL(__get_user_asm_b); EXPORT_SYMBOL(__get_user_asm_w); EXPORT_SYMBOL(__get_user_asm_l); EXPORT_SYMBOL(__get_user_asm_q); -EXPORT_SYMBOL(__strnlen_user); -EXPORT_SYMBOL(__strncpy_from_user); EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(__copy_user); diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index cb4172c8af7d..d6b7b6154f87 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c @@ -32,8 +32,6 @@ #include <asm/syscalls.h> #include <asm/fpu.h> -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - struct fdpic_func_descriptor { unsigned long text; unsigned long GOT; @@ -226,7 +224,6 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5, sizeof(frame->extramask)))) goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); if (restore_sigcontext(regs, &frame->sc, &r0)) @@ -256,7 +253,6 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) @@ -522,10 +518,11 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs, /* * OK, we're invoking a handler */ -static int +static void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *oldset, struct pt_regs *regs, unsigned int save_r0) + struct pt_regs *regs, unsigned int save_r0) { + sigset_t *oldset = sigmask_to_save(); int ret; /* Set up the stack frame */ @@ -534,10 +531,10 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, else ret = setup_frame(sig, ka, oldset, regs); - if (ret == 0) - block_sigmask(ka, sig); - - return ret; + if (ret) + return; + signal_delivered(sig, info, ka, regs, + test_thread_flag(TIF_SINGLESTEP)); } /* @@ -554,7 +551,6 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) siginfo_t info; int signr; struct k_sigaction ka; - sigset_t *oldset; /* * We want the common case to go fast, which @@ -565,30 +561,12 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) if (!user_mode(regs)) return; - if (current_thread_info()->status & TS_RESTORE_SIGMASK) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { handle_syscall_restart(save_r0, regs, &ka.sa); /* Whee! Actually deliver the signal. */ - if (handle_signal(signr, &ka, &info, oldset, - regs, save_r0) == 0) { - /* - * 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 TS_RESTORE_SIGMASK flag - */ - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - - tracehook_signal_handler(signr, &info, &ka, regs, - test_thread_flag(TIF_SINGLESTEP)); - } - + handle_signal(signr, &ka, &info, regs, save_r0); return; } @@ -610,10 +588,7 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) * If there's no signal to deliver, we just put the saved sigmask * back. */ - if (current_thread_info()->status & TS_RESTORE_SIGMASK) { - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } + restore_saved_sigmask(); } asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0, @@ -626,7 +601,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0, if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } } diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index b589a354c069..6b5b3dfe886b 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c @@ -41,11 +41,9 @@ #define DEBUG_SIG 0 -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - -static int +static void handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, - sigset_t *oldset, struct pt_regs * regs); + struct pt_regs * regs); static inline void handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa) @@ -88,7 +86,6 @@ static void do_signal(struct pt_regs *regs) siginfo_t info; int signr; struct k_sigaction ka; - sigset_t *oldset; /* * We want the common case to go fast, which @@ -99,28 +96,13 @@ static void do_signal(struct pt_regs *regs) if (!user_mode(regs)) return; - if (current_thread_info()->status & TS_RESTORE_SIGMASK) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, &ka, regs, 0); if (signr > 0) { handle_syscall_restart(regs, &ka.sa); /* Whee! Actually deliver the signal. */ - if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { - /* - * If a signal was successfully delivered, the - * saved sigmask is in its frame, and we can - * clear the TS_RESTORE_SIGMASK flag. - */ - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - - tracehook_signal_handler(signr, &info, &ka, regs, - test_thread_flag(TIF_SINGLESTEP)); - return; - } + handle_signal(signr, &info, &ka, regs); + return; } /* Did we come from a system call? */ @@ -143,12 +125,7 @@ static void do_signal(struct pt_regs *regs) } /* No signal to deliver -- put the saved sigmask back */ - if (current_thread_info()->status & TS_RESTORE_SIGMASK) { - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } - - return; + restore_saved_sigmask(); } /* @@ -351,7 +328,6 @@ asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3, sizeof(frame->extramask)))) goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); if (restore_sigcontext(regs, &frame->sc, &ret)) @@ -384,7 +360,6 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret)) @@ -659,10 +634,11 @@ give_sigsegv: /* * OK, we're invoking a handler */ -static int +static void handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, - sigset_t *oldset, struct pt_regs * regs) + struct pt_regs * regs) { + sigset_t *oldset = sigmask_to_save(); int ret; /* Set up the stack frame */ @@ -671,10 +647,11 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, else ret = setup_frame(sig, ka, oldset, regs); - if (ret == 0) - block_sigmask(ka, sig); + if (ret) + return; - return ret; + signal_delivered(sig, info, ka, regs, + test_thread_flag(TIF_SINGLESTEP)); } asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) @@ -685,7 +662,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } } diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index b86e9ca79455..2062aa88af41 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -123,7 +123,6 @@ void native_play_dead(void) int __cpu_disable(void) { unsigned int cpu = smp_processor_id(); - struct task_struct *p; int ret; ret = mp_ops->cpu_disable(cpu); @@ -153,11 +152,7 @@ int __cpu_disable(void) flush_cache_all(); local_flush_tlb_all(); - read_lock(&tasklist_lock); - for_each_process(p) - if (p->mm) - cpumask_clear_cpu(cpu, mm_cpumask(p->mm)); - read_unlock(&tasklist_lock); + clear_tasks_mm_cpumask(cpu); return 0; } diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index a37175deb73f..b8f5a51841ec 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -48,33 +48,6 @@ #define TRAP_ILLEGAL_SLOT_INST 13 #endif -static void dump_mem(const char *str, unsigned long bottom, unsigned long top) -{ - unsigned long p; - int i; - - printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); - - for (p = bottom & ~31; p < top; ) { - printk("%04lx: ", p & 0xffff); - - for (i = 0; i < 8; i++, p += 4) { - unsigned int val; - - if (p < bottom || p >= top) - printk(" "); - else { - if (__get_user(val, (unsigned int __user *)p)) { - printk("\n"); - return; - } - printk("%08x ", val); - } - } - printk("\n"); - } -} - static DEFINE_SPINLOCK(die_lock); void die(const char * str, struct pt_regs * regs, long err) @@ -900,26 +873,3 @@ void __init trap_init(void) set_exception_table_vec(TRAP_UBC, breakpoint_trap_handler); #endif } - -void show_stack(struct task_struct *tsk, unsigned long *sp) -{ - unsigned long stack; - - if (!tsk) - tsk = current; - if (tsk == current) - sp = (unsigned long *)current_stack_pointer; - else - sp = (unsigned long *)tsk->thread.sp; - - stack = (unsigned long)sp; - dump_mem("Stack: ", stack, THREAD_SIZE + - (unsigned long)task_stack_page(tsk)); - show_trace(tsk, sp, NULL); -} - -void dump_stack(void) -{ - show_stack(NULL, NULL); -} -EXPORT_SYMBOL(dump_stack); diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c index 8dae93ed8aff..ba95d63e623d 100644 --- a/arch/sh/kernel/traps_64.c +++ b/arch/sh/kernel/traps_64.c @@ -253,32 +253,6 @@ int do_unknown_trapa(unsigned long scId, struct pt_regs *regs) return -ENOSYS; } -void show_stack(struct task_struct *tsk, unsigned long *sp) -{ -#ifdef CONFIG_KALLSYMS - extern void sh64_unwind(struct pt_regs *regs); - struct pt_regs *regs; - - regs = tsk ? tsk->thread.kregs : NULL; - - sh64_unwind(regs); -#else - printk(KERN_ERR "Can't backtrace on sh64 without CONFIG_KALLSYMS\n"); -#endif -} - -void show_task(unsigned long *sp) -{ - show_stack(NULL, sp); -} - -void dump_stack(void) -{ - show_task(NULL); -} -/* Needed by any user of WARN_ON in view of the defn in include/asm-sh/bug.h */ -EXPORT_SYMBOL(dump_stack); - static void do_unhandled_exception(int trapnr, int signr, char *str, char *fn_name, unsigned long error_code, struct pt_regs *regs, struct task_struct *tsk) { |