diff options
189 files changed, 1914 insertions, 1848 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index ebaffe208ccb..56000b33340b 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -606,3 +606,9 @@ Why: There are two mci drivers: at91-mci and atmel-mci. The PDC support Who: Ludovic Desroches <ludovic.desroches@atmel.com> ---------------------------- + +What: net/wanrouter/ +When: June 2013 +Why: Unsupported/unmaintained/unused since 2.6 + +---------------------------- diff --git a/MAINTAINERS b/MAINTAINERS index 64e675d6d478..8cad55b9db99 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6657,7 +6657,7 @@ F: include/linux/taskstats* F: kernel/taskstats.c TC CLASSIFIER -M: Jamal Hadi Salim <hadi@cyberus.ca> +M: Jamal Hadi Salim <jhs@mojatatu.com> L: netdev@vger.kernel.org S: Maintained F: include/linux/pkt_cls.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5e7601301b41..b649c5904a4f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -525,7 +525,7 @@ config ARCH_IXP4XX select ARCH_HAS_DMA_SET_COHERENT_MASK select CLKSRC_MMIO select CPU_XSCALE - select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS select MIGHT_HAVE_PCI select NEED_MACH_IO_H diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 5ca0cdb76413..4272b2949228 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -30,6 +30,22 @@ reg = <0x10481000 0x1000>, <0x10482000 0x2000>; }; + combiner:interrupt-controller@10440000 { + compatible = "samsung,exynos4210-combiner"; + #interrupt-cells = <2>; + interrupt-controller; + samsung,combiner-nr = <32>; + reg = <0x10440000 0x1000>; + interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>, + <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>, + <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>, + <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>, + <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>, + <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>, + <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>, + <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>; + }; + watchdog { compatible = "samsung,s3c2410-wdt"; reg = <0x101D0000 0x100>; diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi index 2d696866f71c..3f5dad801a98 100644 --- a/arch/arm/boot/dts/lpc32xx.dtsi +++ b/arch/arm/boot/dts/lpc32xx.dtsi @@ -215,45 +215,8 @@ gpio: gpio@40028000 { compatible = "nxp,lpc3220-gpio"; reg = <0x40028000 0x1000>; - /* create a private address space for enumeration */ - #address-cells = <1>; - #size-cells = <0>; - - gpio_p0: gpio-bank@0 { - gpio-controller; - #gpio-cells = <2>; - reg = <0>; - }; - - gpio_p1: gpio-bank@1 { - gpio-controller; - #gpio-cells = <2>; - reg = <1>; - }; - - gpio_p2: gpio-bank@2 { - gpio-controller; - #gpio-cells = <2>; - reg = <2>; - }; - - gpio_p3: gpio-bank@3 { - gpio-controller; - #gpio-cells = <2>; - reg = <3>; - }; - - gpi_p3: gpio-bank@4 { - gpio-controller; - #gpio-cells = <2>; - reg = <4>; - }; - - gpo_p3: gpio-bank@5 { - gpio-controller; - #gpio-cells = <2>; - reg = <5>; - }; + gpio-controller; + #gpio-cells = <3>; /* bank, pin, flags */ }; watchdog@4003C000 { diff --git a/arch/arm/boot/dts/phy3250.dts b/arch/arm/boot/dts/phy3250.dts index 0167e86314c0..c4ff6d1a018b 100644 --- a/arch/arm/boot/dts/phy3250.dts +++ b/arch/arm/boot/dts/phy3250.dts @@ -131,13 +131,13 @@ compatible = "gpio-leds"; led0 { - gpios = <&gpo_p3 1 1>; /* GPO_P3 1, GPIO 80, active low */ + gpios = <&gpio 5 1 1>; /* GPO_P3 1, GPIO 80, active low */ linux,default-trigger = "heartbeat"; default-state = "off"; }; led1 { - gpios = <&gpo_p3 14 1>; /* GPO_P3 14, GPIO 93, active low */ + gpios = <&gpio 5 14 1>; /* GPO_P3 14, GPIO 93, active low */ linux,default-trigger = "timer"; default-state = "off"; }; diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts index 941b161ab78c..7e1091d91af8 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts @@ -73,7 +73,10 @@ #address-cells = <0>; interrupt-controller; reg = <0x2c001000 0x1000>, - <0x2c002000 0x100>; + <0x2c002000 0x1000>, + <0x2c004000 0x2000>, + <0x2c006000 0x2000>; + interrupts = <1 9 0xf04>; }; memory-controller@7ffd0000 { @@ -93,6 +96,14 @@ <0 91 4>; }; + timer { + compatible = "arm,armv7-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + }; + pmu { compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu"; interrupts = <0 68 4>, diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts index 6905e66d4748..18917a0f8604 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts @@ -77,13 +77,18 @@ timer@2c000600 { compatible = "arm,cortex-a5-twd-timer"; - reg = <0x2c000600 0x38>; - interrupts = <1 2 0x304>, - <1 3 0x304>; + reg = <0x2c000600 0x20>; + interrupts = <1 13 0x304>; + }; + + watchdog@2c000620 { + compatible = "arm,cortex-a5-twd-wdt"; + reg = <0x2c000620 0x20>; + interrupts = <1 14 0x304>; }; gic: interrupt-controller@2c001000 { - compatible = "arm,corex-a5-gic", "arm,cortex-a9-gic"; + compatible = "arm,cortex-a5-gic", "arm,cortex-a9-gic"; #interrupt-cells = <3>; #address-cells = <0>; interrupt-controller; diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts index da778693be54..3f0c736d31d6 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts @@ -105,8 +105,13 @@ timer@1e000600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x1e000600 0x20>; - interrupts = <1 2 0xf04>, - <1 3 0xf04>; + interrupts = <1 13 0xf04>; + }; + + watchdog@1e000620 { + compatible = "arm,cortex-a9-twd-wdt"; + reg = <0x1e000620 0x20>; + interrupts = <1 14 0xf04>; }; gic: interrupt-controller@1e001000 { diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 43ebe9094411..573be57d3d28 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -62,6 +62,8 @@ config SOC_EXYNOS5250 default y depends on ARCH_EXYNOS5 select SAMSUNG_DMADEV + select S5P_PM if PM + select S5P_SLEEP if PM help Enable EXYNOS5250 SoC support diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index 440a637c76f1..9b58024f7d43 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile @@ -22,7 +22,7 @@ obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o -obj-$(CONFIG_ARCH_EXYNOS4) += pmu.o +obj-$(CONFIG_ARCH_EXYNOS) += pmu.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c index 5aa460b01fdf..fefa336be2b4 100644 --- a/arch/arm/mach-exynos/clock-exynos5.c +++ b/arch/arm/mach-exynos/clock-exynos5.c @@ -30,7 +30,56 @@ #ifdef CONFIG_PM_SLEEP static struct sleep_save exynos5_clock_save[] = { - /* will be implemented */ + SAVE_ITEM(EXYNOS5_CLKSRC_MASK_TOP), + SAVE_ITEM(EXYNOS5_CLKSRC_MASK_GSCL), + SAVE_ITEM(EXYNOS5_CLKSRC_MASK_DISP1_0), + SAVE_ITEM(EXYNOS5_CLKSRC_MASK_FSYS), + SAVE_ITEM(EXYNOS5_CLKSRC_MASK_MAUDIO), + SAVE_ITEM(EXYNOS5_CLKSRC_MASK_PERIC0), + SAVE_ITEM(EXYNOS5_CLKSRC_MASK_PERIC1), + SAVE_ITEM(EXYNOS5_CLKGATE_IP_GSCL), + SAVE_ITEM(EXYNOS5_CLKGATE_IP_DISP1), + SAVE_ITEM(EXYNOS5_CLKGATE_IP_MFC), + SAVE_ITEM(EXYNOS5_CLKGATE_IP_G3D), + SAVE_ITEM(EXYNOS5_CLKGATE_IP_GEN), + SAVE_ITEM(EXYNOS5_CLKGATE_IP_FSYS), + SAVE_ITEM(EXYNOS5_CLKGATE_IP_PERIC), + SAVE_ITEM(EXYNOS5_CLKGATE_IP_PERIS), + SAVE_ITEM(EXYNOS5_CLKGATE_BLOCK), + SAVE_ITEM(EXYNOS5_CLKDIV_TOP0), + SAVE_ITEM(EXYNOS5_CLKDIV_TOP1), + SAVE_ITEM(EXYNOS5_CLKDIV_GSCL), + SAVE_ITEM(EXYNOS5_CLKDIV_DISP1_0), + SAVE_ITEM(EXYNOS5_CLKDIV_GEN), + SAVE_ITEM(EXYNOS5_CLKDIV_MAUDIO), + SAVE_ITEM(EXYNOS5_CLKDIV_FSYS0), + SAVE_ITEM(EXYNOS5_CLKDIV_FSYS1), + SAVE_ITEM(EXYNOS5_CLKDIV_FSYS2), + SAVE_ITEM(EXYNOS5_CLKDIV_FSYS3), + SAVE_ITEM(EXYNOS5_CLKDIV_PERIC0), + SAVE_ITEM(EXYNOS5_CLKDIV_PERIC1), + SAVE_ITEM(EXYNOS5_CLKDIV_PERIC2), + SAVE_ITEM(EXYNOS5_CLKDIV_PERIC3), + SAVE_ITEM(EXYNOS5_CLKDIV_PERIC4), + SAVE_ITEM(EXYNOS5_CLKDIV_PERIC5), + SAVE_ITEM(EXYNOS5_SCLK_DIV_ISP), + SAVE_ITEM(EXYNOS5_CLKSRC_TOP0), + SAVE_ITEM(EXYNOS5_CLKSRC_TOP1), + SAVE_ITEM(EXYNOS5_CLKSRC_TOP2), + SAVE_ITEM(EXYNOS5_CLKSRC_TOP3), + SAVE_ITEM(EXYNOS5_CLKSRC_GSCL), + SAVE_ITEM(EXYNOS5_CLKSRC_DISP1_0), + SAVE_ITEM(EXYNOS5_CLKSRC_MAUDIO), + SAVE_ITEM(EXYNOS5_CLKSRC_FSYS), + SAVE_ITEM(EXYNOS5_CLKSRC_PERIC0), + SAVE_ITEM(EXYNOS5_CLKSRC_PERIC1), + SAVE_ITEM(EXYNOS5_SCLK_SRC_ISP), + SAVE_ITEM(EXYNOS5_EPLL_CON0), + SAVE_ITEM(EXYNOS5_EPLL_CON1), + SAVE_ITEM(EXYNOS5_EPLL_CON2), + SAVE_ITEM(EXYNOS5_VPLL_CON0), + SAVE_ITEM(EXYNOS5_VPLL_CON1), + SAVE_ITEM(EXYNOS5_VPLL_CON2), }; #endif diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c index 26dac2893b8e..cff0595d0d35 100644 --- a/arch/arm/mach-exynos/cpuidle.c +++ b/arch/arm/mach-exynos/cpuidle.c @@ -100,7 +100,7 @@ static int exynos4_enter_core0_aftr(struct cpuidle_device *dev, exynos4_set_wakeupmask(); /* Set value of power down register for aftr mode */ - exynos4_sys_powerdown_conf(SYS_AFTR); + exynos_sys_powerdown_conf(SYS_AFTR); __raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR); __raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG); diff --git a/arch/arm/mach-exynos/include/mach/pm-core.h b/arch/arm/mach-exynos/include/mach/pm-core.h index 9d8da51e35ca..a67ecfaf1216 100644 --- a/arch/arm/mach-exynos/include/mach/pm-core.h +++ b/arch/arm/mach-exynos/include/mach/pm-core.h @@ -33,7 +33,7 @@ static inline void s3c_pm_arch_prepare_irqs(void) __raw_writel(tmp, S5P_WAKEUP_MASK); __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK); - __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK); + __raw_writel(s3c_irqwake_eintmask & 0xFFFFFFFE, S5P_EINT_WAKEUP_MASK); } static inline void s3c_pm_arch_stop_clocks(void) diff --git a/arch/arm/mach-exynos/include/mach/pmu.h b/arch/arm/mach-exynos/include/mach/pmu.h index e76b7faba66b..7c27c2d4bf44 100644 --- a/arch/arm/mach-exynos/include/mach/pmu.h +++ b/arch/arm/mach-exynos/include/mach/pmu.h @@ -23,12 +23,12 @@ enum sys_powerdown { }; extern unsigned long l2x0_regs_phys; -struct exynos4_pmu_conf { +struct exynos_pmu_conf { void __iomem *reg; unsigned int val[NUM_SYS_POWERDOWN]; }; -extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); +extern void exynos_sys_powerdown_conf(enum sys_powerdown mode); extern void s3c_cpu_resume(void); #endif /* __ASM_ARCH_PMU_H */ diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h index b78b5f3ad9c0..8c9b38c9c504 100644 --- a/arch/arm/mach-exynos/include/mach/regs-clock.h +++ b/arch/arm/mach-exynos/include/mach/regs-clock.h @@ -274,36 +274,51 @@ #define EXYNOS5_CLKDIV_ACP EXYNOS_CLKREG(0x08500) -#define EXYNOS5_CLKSRC_TOP2 EXYNOS_CLKREG(0x10218) #define EXYNOS5_EPLL_CON0 EXYNOS_CLKREG(0x10130) #define EXYNOS5_EPLL_CON1 EXYNOS_CLKREG(0x10134) +#define EXYNOS5_EPLL_CON2 EXYNOS_CLKREG(0x10138) #define EXYNOS5_VPLL_CON0 EXYNOS_CLKREG(0x10140) #define EXYNOS5_VPLL_CON1 EXYNOS_CLKREG(0x10144) +#define EXYNOS5_VPLL_CON2 EXYNOS_CLKREG(0x10148) #define EXYNOS5_CPLL_CON0 EXYNOS_CLKREG(0x10120) #define EXYNOS5_CLKSRC_TOP0 EXYNOS_CLKREG(0x10210) +#define EXYNOS5_CLKSRC_TOP1 EXYNOS_CLKREG(0x10214) +#define EXYNOS5_CLKSRC_TOP2 EXYNOS_CLKREG(0x10218) #define EXYNOS5_CLKSRC_TOP3 EXYNOS_CLKREG(0x1021C) #define EXYNOS5_CLKSRC_GSCL EXYNOS_CLKREG(0x10220) #define EXYNOS5_CLKSRC_DISP1_0 EXYNOS_CLKREG(0x1022C) +#define EXYNOS5_CLKSRC_MAUDIO EXYNOS_CLKREG(0x10240) #define EXYNOS5_CLKSRC_FSYS EXYNOS_CLKREG(0x10244) #define EXYNOS5_CLKSRC_PERIC0 EXYNOS_CLKREG(0x10250) +#define EXYNOS5_CLKSRC_PERIC1 EXYNOS_CLKREG(0x10254) +#define EXYNOS5_SCLK_SRC_ISP EXYNOS_CLKREG(0x10270) #define EXYNOS5_CLKSRC_MASK_TOP EXYNOS_CLKREG(0x10310) #define EXYNOS5_CLKSRC_MASK_GSCL EXYNOS_CLKREG(0x10320) #define EXYNOS5_CLKSRC_MASK_DISP1_0 EXYNOS_CLKREG(0x1032C) +#define EXYNOS5_CLKSRC_MASK_MAUDIO EXYNOS_CLKREG(0x10334) #define EXYNOS5_CLKSRC_MASK_FSYS EXYNOS_CLKREG(0x10340) #define EXYNOS5_CLKSRC_MASK_PERIC0 EXYNOS_CLKREG(0x10350) +#define EXYNOS5_CLKSRC_MASK_PERIC1 EXYNOS_CLKREG(0x10354) #define EXYNOS5_CLKDIV_TOP0 EXYNOS_CLKREG(0x10510) #define EXYNOS5_CLKDIV_TOP1 EXYNOS_CLKREG(0x10514) #define EXYNOS5_CLKDIV_GSCL EXYNOS_CLKREG(0x10520) #define EXYNOS5_CLKDIV_DISP1_0 EXYNOS_CLKREG(0x1052C) #define EXYNOS5_CLKDIV_GEN EXYNOS_CLKREG(0x1053C) +#define EXYNOS5_CLKDIV_MAUDIO EXYNOS_CLKREG(0x10544) #define EXYNOS5_CLKDIV_FSYS0 EXYNOS_CLKREG(0x10548) #define EXYNOS5_CLKDIV_FSYS1 EXYNOS_CLKREG(0x1054C) #define EXYNOS5_CLKDIV_FSYS2 EXYNOS_CLKREG(0x10550) #define EXYNOS5_CLKDIV_FSYS3 EXYNOS_CLKREG(0x10554) #define EXYNOS5_CLKDIV_PERIC0 EXYNOS_CLKREG(0x10558) +#define EXYNOS5_CLKDIV_PERIC1 EXYNOS_CLKREG(0x1055C) +#define EXYNOS5_CLKDIV_PERIC2 EXYNOS_CLKREG(0x10560) +#define EXYNOS5_CLKDIV_PERIC3 EXYNOS_CLKREG(0x10564) +#define EXYNOS5_CLKDIV_PERIC4 EXYNOS_CLKREG(0x10568) +#define EXYNOS5_CLKDIV_PERIC5 EXYNOS_CLKREG(0x1056C) +#define EXYNOS5_SCLK_DIV_ISP EXYNOS_CLKREG(0x10580) #define EXYNOS5_CLKGATE_IP_ACP EXYNOS_CLKREG(0x08800) #define EXYNOS5_CLKGATE_IP_ISP0 EXYNOS_CLKREG(0x0C800) @@ -311,6 +326,7 @@ #define EXYNOS5_CLKGATE_IP_GSCL EXYNOS_CLKREG(0x10920) #define EXYNOS5_CLKGATE_IP_DISP1 EXYNOS_CLKREG(0x10928) #define EXYNOS5_CLKGATE_IP_MFC EXYNOS_CLKREG(0x1092C) +#define EXYNOS5_CLKGATE_IP_G3D EXYNOS_CLKREG(0x10930) #define EXYNOS5_CLKGATE_IP_GEN EXYNOS_CLKREG(0x10934) #define EXYNOS5_CLKGATE_IP_FSYS EXYNOS_CLKREG(0x10944) #define EXYNOS5_CLKGATE_IP_GPS EXYNOS_CLKREG(0x1094C) diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h index 4dbb8629b200..43a99e6f56ab 100644 --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h @@ -1,9 +1,8 @@ -/* linux/arch/arm/mach-exynos4/include/mach/regs-pmu.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. +/* + * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * EXYNOS4 - Power management unit definition + * EXYNOS - Power management unit definition * * 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 @@ -229,4 +228,138 @@ #define S5P_DIS_IRQ_CORE3 S5P_PMUREG(0x1034) #define S5P_DIS_IRQ_CENTRAL3 S5P_PMUREG(0x1038) +/* For EXYNOS5 */ + +#define EXYNOS5_USB_CFG S5P_PMUREG(0x0230) + +#define EXYNOS5_ARM_CORE0_SYS_PWR_REG S5P_PMUREG(0x1000) +#define EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG S5P_PMUREG(0x1004) +#define EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1008) +#define EXYNOS5_ARM_CORE1_SYS_PWR_REG S5P_PMUREG(0x1010) +#define EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG S5P_PMUREG(0x1014) +#define EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1018) +#define EXYNOS5_FSYS_ARM_SYS_PWR_REG S5P_PMUREG(0x1040) +#define EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1048) +#define EXYNOS5_ISP_ARM_SYS_PWR_REG S5P_PMUREG(0x1050) +#define EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG S5P_PMUREG(0x1054) +#define EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1058) +#define EXYNOS5_ARM_COMMON_SYS_PWR_REG S5P_PMUREG(0x1080) +#define EXYNOS5_ARM_L2_SYS_PWR_REG S5P_PMUREG(0x10C0) +#define EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG S5P_PMUREG(0x1100) +#define EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG S5P_PMUREG(0x1104) +#define EXYNOS5_CMU_RESET_SYS_PWR_REG S5P_PMUREG(0x110C) +#define EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1120) +#define EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1124) +#define EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x112C) +#define EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG S5P_PMUREG(0x1130) +#define EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG S5P_PMUREG(0x1134) +#define EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG S5P_PMUREG(0x1138) +#define EXYNOS5_APLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1140) +#define EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1144) +#define EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1148) +#define EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x114C) +#define EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1150) +#define EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1154) +#define EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1164) +#define EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1170) +#define EXYNOS5_TOP_BUS_SYS_PWR_REG S5P_PMUREG(0x1180) +#define EXYNOS5_TOP_RETENTION_SYS_PWR_REG S5P_PMUREG(0x1184) +#define EXYNOS5_TOP_PWR_SYS_PWR_REG S5P_PMUREG(0x1188) +#define EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1190) +#define EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1194) +#define EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1198) +#define EXYNOS5_LOGIC_RESET_SYS_PWR_REG S5P_PMUREG(0x11A0) +#define EXYNOS5_OSCCLK_GATE_SYS_PWR_REG S5P_PMUREG(0x11A4) +#define EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x11B0) +#define EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x11B4) +#define EXYNOS5_USBOTG_MEM_SYS_PWR_REG S5P_PMUREG(0x11C0) +#define EXYNOS5_G2D_MEM_SYS_PWR_REG S5P_PMUREG(0x11C8) +#define EXYNOS5_USBDRD_MEM_SYS_PWR_REG S5P_PMUREG(0x11CC) +#define EXYNOS5_SDMMC_MEM_SYS_PWR_REG S5P_PMUREG(0x11D0) +#define EXYNOS5_CSSYS_MEM_SYS_PWR_REG S5P_PMUREG(0x11D4) +#define EXYNOS5_SECSS_MEM_SYS_PWR_REG S5P_PMUREG(0x11D8) +#define EXYNOS5_ROTATOR_MEM_SYS_PWR_REG S5P_PMUREG(0x11DC) +#define EXYNOS5_INTRAM_MEM_SYS_PWR_REG S5P_PMUREG(0x11E0) +#define EXYNOS5_INTROM_MEM_SYS_PWR_REG S5P_PMUREG(0x11E4) +#define EXYNOS5_JPEG_MEM_SYS_PWR_REG S5P_PMUREG(0x11E8) +#define EXYNOS5_HSI_MEM_SYS_PWR_REG S5P_PMUREG(0x11EC) +#define EXYNOS5_MCUIOP_MEM_SYS_PWR_REG S5P_PMUREG(0x11F4) +#define EXYNOS5_SATA_MEM_SYS_PWR_REG S5P_PMUREG(0x11FC) +#define EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG S5P_PMUREG(0x1200) +#define EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG S5P_PMUREG(0x1204) +#define EXYNOS5_PAD_RETENTION_EFNAND_SYS_PWR_REG S5P_PMUREG(0x1208) +#define EXYNOS5_PAD_RETENTION_GPIO_SYS_PWR_REG S5P_PMUREG(0x1220) +#define EXYNOS5_PAD_RETENTION_UART_SYS_PWR_REG S5P_PMUREG(0x1224) +#define EXYNOS5_PAD_RETENTION_MMCA_SYS_PWR_REG S5P_PMUREG(0x1228) +#define EXYNOS5_PAD_RETENTION_MMCB_SYS_PWR_REG S5P_PMUREG(0x122C) +#define EXYNOS5_PAD_RETENTION_EBIA_SYS_PWR_REG S5P_PMUREG(0x1230) +#define EXYNOS5_PAD_RETENTION_EBIB_SYS_PWR_REG S5P_PMUREG(0x1234) +#define EXYNOS5_PAD_RETENTION_SPI_SYS_PWR_REG S5P_PMUREG(0x1238) +#define EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x123C) +#define EXYNOS5_PAD_ISOLATION_SYS_PWR_REG S5P_PMUREG(0x1240) +#define EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1250) +#define EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG S5P_PMUREG(0x1260) +#define EXYNOS5_XUSBXTI_SYS_PWR_REG S5P_PMUREG(0x1280) +#define EXYNOS5_XXTI_SYS_PWR_REG S5P_PMUREG(0x1284) +#define EXYNOS5_EXT_REGULATOR_SYS_PWR_REG S5P_PMUREG(0x12C0) +#define EXYNOS5_GPIO_MODE_SYS_PWR_REG S5P_PMUREG(0x1300) +#define EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1320) +#define EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG S5P_PMUREG(0x1340) +#define EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG S5P_PMUREG(0x1344) +#define EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG S5P_PMUREG(0x1348) +#define EXYNOS5_GSCL_SYS_PWR_REG S5P_PMUREG(0x1400) +#define EXYNOS5_ISP_SYS_PWR_REG S5P_PMUREG(0x1404) +#define EXYNOS5_MFC_SYS_PWR_REG S5P_PMUREG(0x1408) +#define EXYNOS5_G3D_SYS_PWR_REG S5P_PMUREG(0x140C) +#define EXYNOS5_DISP1_SYS_PWR_REG S5P_PMUREG(0x1414) +#define EXYNOS5_MAU_SYS_PWR_REG S5P_PMUREG(0x1418) +#define EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG S5P_PMUREG(0x1480) +#define EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG S5P_PMUREG(0x1484) +#define EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG S5P_PMUREG(0x1488) +#define EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG S5P_PMUREG(0x148C) +#define EXYNOS5_CMU_CLKSTOP_DISP1_SYS_PWR_REG S5P_PMUREG(0x1494) +#define EXYNOS5_CMU_CLKSTOP_MAU_SYS_PWR_REG S5P_PMUREG(0x1498) +#define EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG S5P_PMUREG(0x14C0) +#define EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG S5P_PMUREG(0x14C4) +#define EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG S5P_PMUREG(0x14C8) +#define EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG S5P_PMUREG(0x14CC) +#define EXYNOS5_CMU_SYSCLK_DISP1_SYS_PWR_REG S5P_PMUREG(0x14D4) +#define EXYNOS5_CMU_SYSCLK_MAU_SYS_PWR_REG S5P_PMUREG(0x14D8) +#define EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG S5P_PMUREG(0x1580) +#define EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG S5P_PMUREG(0x1584) +#define EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG S5P_PMUREG(0x1588) +#define EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG S5P_PMUREG(0x158C) +#define EXYNOS5_CMU_RESET_DISP1_SYS_PWR_REG S5P_PMUREG(0x1594) +#define EXYNOS5_CMU_RESET_MAU_SYS_PWR_REG S5P_PMUREG(0x1598) + +#define EXYNOS5_ARM_CORE0_OPTION S5P_PMUREG(0x2008) +#define EXYNOS5_ARM_CORE1_OPTION S5P_PMUREG(0x2088) +#define EXYNOS5_FSYS_ARM_OPTION S5P_PMUREG(0x2208) +#define EXYNOS5_ISP_ARM_OPTION S5P_PMUREG(0x2288) +#define EXYNOS5_ARM_COMMON_OPTION S5P_PMUREG(0x2408) +#define EXYNOS5_TOP_PWR_OPTION S5P_PMUREG(0x2C48) +#define EXYNOS5_TOP_PWR_SYSMEM_OPTION S5P_PMUREG(0x2CC8) +#define EXYNOS5_JPEG_MEM_OPTION S5P_PMUREG(0x2F48) +#define EXYNOS5_GSCL_STATUS S5P_PMUREG(0x4004) +#define EXYNOS5_ISP_STATUS S5P_PMUREG(0x4024) +#define EXYNOS5_GSCL_OPTION S5P_PMUREG(0x4008) +#define EXYNOS5_ISP_OPTION S5P_PMUREG(0x4028) +#define EXYNOS5_MFC_OPTION S5P_PMUREG(0x4048) +#define EXYNOS5_G3D_CONFIGURATION S5P_PMUREG(0x4060) +#define EXYNOS5_G3D_STATUS S5P_PMUREG(0x4064) +#define EXYNOS5_G3D_OPTION S5P_PMUREG(0x4068) +#define EXYNOS5_DISP1_OPTION S5P_PMUREG(0x40A8) +#define EXYNOS5_MAU_OPTION S5P_PMUREG(0x40C8) + +#define EXYNOS5_USE_SC_FEEDBACK (1 << 1) +#define EXYNOS5_USE_SC_COUNTER (1 << 0) + +#define EXYNOS5_MANUAL_L2RSTDISABLE_CONTROL (1 << 2) +#define EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN (1 << 7) + +#define EXYNOS5_OPTION_USE_STANDBYWFE (1 << 24) +#define EXYNOS5_OPTION_USE_STANDBYWFI (1 << 16) + +#define EXYNOS5_OPTION_USE_RETENTION (1 << 4) + #endif /* __ASM_ARCH_REGS_PMU_H */ diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index 563dea9a6dbb..c06c992943a1 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -1,9 +1,8 @@ -/* linux/arch/arm/mach-exynos4/pm.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. +/* + * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * EXYNOS4210 - Power Management support + * EXYNOS - Power Management support * * Based on arch/arm/mach-s3c2410/pm.c * Copyright (c) 2006 Simtec Electronics @@ -63,90 +62,7 @@ static struct sleep_save exynos4_vpll_save[] = { SAVE_ITEM(EXYNOS4_VPLL_CON1), }; -static struct sleep_save exynos4_core_save[] = { - /* GIC side */ - SAVE_ITEM(S5P_VA_GIC_CPU + 0x000), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x004), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x008), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x00C), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x014), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x018), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x000), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x004), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x100), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x104), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x108), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x300), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x304), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x308), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x400), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x404), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x408), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x40C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x410), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x414), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x418), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x41C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x420), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x424), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x428), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x42C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x430), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x434), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x438), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x43C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x440), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x444), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x448), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x44C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x450), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x454), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x458), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x45C), - - SAVE_ITEM(S5P_VA_GIC_DIST + 0x800), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x804), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x808), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x80C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x810), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x814), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x818), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x81C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x820), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x824), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x828), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x82C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x830), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x834), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x838), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x83C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x840), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x844), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x848), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x84C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x850), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x854), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x858), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x85C), - - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC00), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC04), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC08), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC0C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC10), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC14), - - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x000), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x010), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x020), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x030), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x040), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x050), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x060), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x070), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x080), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x090), - +static struct sleep_save exynos_core_save[] = { /* SROM side */ SAVE_ITEM(S5P_SROM_BW), SAVE_ITEM(S5P_SROM_BC0), @@ -159,9 +75,11 @@ static struct sleep_save exynos4_core_save[] = { /* For Cortex-A9 Diagnostic and Power control register */ static unsigned int save_arm_register[2]; -static int exynos4_cpu_suspend(unsigned long arg) +static int exynos_cpu_suspend(unsigned long arg) { +#ifdef CONFIG_CACHE_L2X0 outer_flush_all(); +#endif /* issue the standby signal into the pm unit. */ cpu_do_idle(); @@ -170,19 +88,25 @@ static int exynos4_cpu_suspend(unsigned long arg) panic("sleep resumed to originator?"); } -static void exynos4_pm_prepare(void) +static void exynos_pm_prepare(void) { - u32 tmp; + unsigned int tmp; - s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save)); - s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); - s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); + s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); - tmp = __raw_readl(S5P_INFORM1); + if (!soc_is_exynos5250()) { + s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); + s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); + } else { + /* Disable USE_RETENTION of JPEG_MEM_OPTION */ + tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION); + tmp &= ~EXYNOS5_OPTION_USE_RETENTION; + __raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION); + } /* Set value of power down register for sleep mode */ - exynos4_sys_powerdown_conf(SYS_SLEEP); + exynos_sys_powerdown_conf(SYS_SLEEP); __raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1); /* ensure at least INFORM0 has the resume address */ @@ -191,17 +115,18 @@ static void exynos4_pm_prepare(void) /* Before enter central sequence mode, clock src register have to set */ - s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc)); + if (!soc_is_exynos5250()) + s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc)); if (soc_is_exynos4210()) s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc)); } -static int exynos4_pm_add(struct device *dev, struct subsys_interface *sif) +static int exynos_pm_add(struct device *dev, struct subsys_interface *sif) { - pm_cpu_prep = exynos4_pm_prepare; - pm_cpu_sleep = exynos4_cpu_suspend; + pm_cpu_prep = exynos_pm_prepare; + pm_cpu_sleep = exynos_cpu_suspend; return 0; } @@ -273,13 +198,13 @@ static void exynos4_restore_pll(void) } while (epll_wait || vpll_wait); } -static struct subsys_interface exynos4_pm_interface = { - .name = "exynos4_pm", +static struct subsys_interface exynos_pm_interface = { + .name = "exynos_pm", .subsys = &exynos_subsys, - .add_dev = exynos4_pm_add, + .add_dev = exynos_pm_add, }; -static __init int exynos4_pm_drvinit(void) +static __init int exynos_pm_drvinit(void) { struct clk *pll_base; unsigned int tmp; @@ -292,18 +217,20 @@ static __init int exynos4_pm_drvinit(void) tmp |= ((0xFF << 8) | (0x1F << 1)); __raw_writel(tmp, S5P_WAKEUP_MASK); - pll_base = clk_get(NULL, "xtal"); + if (!soc_is_exynos5250()) { + pll_base = clk_get(NULL, "xtal"); - if (!IS_ERR(pll_base)) { - pll_base_rate = clk_get_rate(pll_base); - clk_put(pll_base); + if (!IS_ERR(pll_base)) { + pll_base_rate = clk_get_rate(pll_base); + clk_put(pll_base); + } } - return subsys_interface_register(&exynos4_pm_interface); + return subsys_interface_register(&exynos_pm_interface); } -arch_initcall(exynos4_pm_drvinit); +arch_initcall(exynos_pm_drvinit); -static int exynos4_pm_suspend(void) +static int exynos_pm_suspend(void) { unsigned long tmp; @@ -313,27 +240,27 @@ static int exynos4_pm_suspend(void) tmp &= ~S5P_CENTRAL_LOWPWR_CFG; __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); - if (soc_is_exynos4212() || soc_is_exynos4412()) { - tmp = __raw_readl(S5P_CENTRAL_SEQ_OPTION); - tmp &= ~(S5P_USE_STANDBYWFI_ISP_ARM | - S5P_USE_STANDBYWFE_ISP_ARM); - __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); - } + /* Setting SEQ_OPTION register */ + + tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); + __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); - /* Save Power control register */ - asm ("mrc p15, 0, %0, c15, c0, 0" - : "=r" (tmp) : : "cc"); - save_arm_register[0] = tmp; + if (!soc_is_exynos5250()) { + /* Save Power control register */ + asm ("mrc p15, 0, %0, c15, c0, 0" + : "=r" (tmp) : : "cc"); + save_arm_register[0] = tmp; - /* Save Diagnostic register */ - asm ("mrc p15, 0, %0, c15, c0, 1" - : "=r" (tmp) : : "cc"); - save_arm_register[1] = tmp; + /* Save Diagnostic register */ + asm ("mrc p15, 0, %0, c15, c0, 1" + : "=r" (tmp) : : "cc"); + save_arm_register[1] = tmp; + } return 0; } -static void exynos4_pm_resume(void) +static void exynos_pm_resume(void) { unsigned long tmp; @@ -350,17 +277,19 @@ static void exynos4_pm_resume(void) /* No need to perform below restore code */ goto early_wakeup; } - /* Restore Power control register */ - tmp = save_arm_register[0]; - asm volatile ("mcr p15, 0, %0, c15, c0, 0" - : : "r" (tmp) - : "cc"); - - /* Restore Diagnostic register */ - tmp = save_arm_register[1]; - asm volatile ("mcr p15, 0, %0, c15, c0, 1" - : : "r" (tmp) - : "cc"); + if (!soc_is_exynos5250()) { + /* Restore Power control register */ + tmp = save_arm_register[0]; + asm volatile ("mcr p15, 0, %0, c15, c0, 0" + : : "r" (tmp) + : "cc"); + + /* Restore Diagnostic register */ + tmp = save_arm_register[1]; + asm volatile ("mcr p15, 0, %0, c15, c0, 1" + : : "r" (tmp) + : "cc"); + } /* For release retention */ @@ -372,26 +301,28 @@ static void exynos4_pm_resume(void) __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); - s3c_pm_do_restore_core(exynos4_core_save, ARRAY_SIZE(exynos4_core_save)); + s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); - exynos4_restore_pll(); + if (!soc_is_exynos5250()) { + exynos4_restore_pll(); #ifdef CONFIG_SMP - scu_enable(S5P_VA_SCU); + scu_enable(S5P_VA_SCU); #endif + } early_wakeup: return; } -static struct syscore_ops exynos4_pm_syscore_ops = { - .suspend = exynos4_pm_suspend, - .resume = exynos4_pm_resume, +static struct syscore_ops exynos_pm_syscore_ops = { + .suspend = exynos_pm_suspend, + .resume = exynos_pm_resume, }; -static __init int exynos4_pm_syscore_init(void) +static __init int exynos_pm_syscore_init(void) { - register_syscore_ops(&exynos4_pm_syscore_ops); + register_syscore_ops(&exynos_pm_syscore_ops); return 0; } -arch_initcall(exynos4_pm_syscore_init); +arch_initcall(exynos_pm_syscore_init); diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c index 77c6815eebee..4aacb66f7161 100644 --- a/arch/arm/mach-exynos/pmu.c +++ b/arch/arm/mach-exynos/pmu.c @@ -1,9 +1,8 @@ -/* linux/arch/arm/mach-exynos4/pmu.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. +/* + * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com/ * - * EXYNOS4210 - CPU PMU(Power Management Unit) support + * EXYNOS - CPU PMU(Power Management Unit) support * * 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 @@ -12,13 +11,14 @@ #include <linux/io.h> #include <linux/kernel.h> +#include <linux/bug.h> #include <mach/regs-clock.h> #include <mach/pmu.h> -static struct exynos4_pmu_conf *exynos4_pmu_config; +static struct exynos_pmu_conf *exynos_pmu_config; -static struct exynos4_pmu_conf exynos4210_pmu_config[] = { +static struct exynos_pmu_conf exynos4210_pmu_config[] = { /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } }, @@ -94,7 +94,7 @@ static struct exynos4_pmu_conf exynos4210_pmu_config[] = { { PMU_TABLE_END,}, }; -static struct exynos4_pmu_conf exynos4x12_pmu_config[] = { +static struct exynos_pmu_conf exynos4x12_pmu_config[] = { { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, @@ -202,7 +202,7 @@ static struct exynos4_pmu_conf exynos4x12_pmu_config[] = { { PMU_TABLE_END,}, }; -static struct exynos4_pmu_conf exynos4412_pmu_config[] = { +static struct exynos_pmu_conf exynos4412_pmu_config[] = { { S5P_ARM_CORE2_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE2, { 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CENTRAL2, { 0x0, 0x0, 0x0 } }, @@ -212,13 +212,174 @@ static struct exynos4_pmu_conf exynos4412_pmu_config[] = { { PMU_TABLE_END,}, }; -void exynos4_sys_powerdown_conf(enum sys_powerdown mode) +static struct exynos_pmu_conf exynos5250_pmu_config[] = { + /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ + { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, + { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, + { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_FSYS_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, + { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x3, 0x3, 0x3} }, + { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, + { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, + { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_USBOTG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_G2D_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_USBDRD_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_SDMMC_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_CSSYS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_SECSS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_ROTATOR_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_JPEG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_HSI_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_MCUIOP_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_SATA_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_PAD_RETENTION_GPIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_MMCA_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_MMCB_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { PMU_TABLE_END,}, +}; + +void __iomem *exynos5_list_both_cnt_feed[] = { + EXYNOS5_ARM_CORE0_OPTION, + EXYNOS5_ARM_CORE1_OPTION, + EXYNOS5_ARM_COMMON_OPTION, + EXYNOS5_GSCL_OPTION, + EXYNOS5_ISP_OPTION, + EXYNOS5_MFC_OPTION, + EXYNOS5_G3D_OPTION, + EXYNOS5_DISP1_OPTION, + EXYNOS5_MAU_OPTION, + EXYNOS5_TOP_PWR_OPTION, + EXYNOS5_TOP_PWR_SYSMEM_OPTION, +}; + +void __iomem *exynos5_list_diable_wfi_wfe[] = { + EXYNOS5_ARM_CORE1_OPTION, + EXYNOS5_FSYS_ARM_OPTION, + EXYNOS5_ISP_ARM_OPTION, +}; + +static void exynos5_init_pmu(void) { unsigned int i; + unsigned int tmp; + + /* + * Enable both SC_FEEDBACK and SC_COUNTER + */ + for (i = 0 ; i < ARRAY_SIZE(exynos5_list_both_cnt_feed) ; i++) { + tmp = __raw_readl(exynos5_list_both_cnt_feed[i]); + tmp |= (EXYNOS5_USE_SC_FEEDBACK | + EXYNOS5_USE_SC_COUNTER); + __raw_writel(tmp, exynos5_list_both_cnt_feed[i]); + } + + /* + * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable + * MANUAL_L2RSTDISABLE_CONTROL_BITFIELD Enable + */ + tmp = __raw_readl(EXYNOS5_ARM_COMMON_OPTION); + tmp |= (EXYNOS5_MANUAL_L2RSTDISABLE_CONTROL | + EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN); + __raw_writel(tmp, EXYNOS5_ARM_COMMON_OPTION); + + /* + * Disable WFI/WFE on XXX_OPTION + */ + for (i = 0 ; i < ARRAY_SIZE(exynos5_list_diable_wfi_wfe) ; i++) { + tmp = __raw_readl(exynos5_list_diable_wfi_wfe[i]); + tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE | + EXYNOS5_OPTION_USE_STANDBYWFI); + __raw_writel(tmp, exynos5_list_diable_wfi_wfe[i]); + } +} + +void exynos_sys_powerdown_conf(enum sys_powerdown mode) +{ + unsigned int i; + + if (soc_is_exynos5250()) + exynos5_init_pmu(); - for (i = 0; (exynos4_pmu_config[i].reg != PMU_TABLE_END) ; i++) - __raw_writel(exynos4_pmu_config[i].val[mode], - exynos4_pmu_config[i].reg); + for (i = 0; (exynos_pmu_config[i].reg != PMU_TABLE_END) ; i++) + __raw_writel(exynos_pmu_config[i].val[mode], + exynos_pmu_config[i].reg); if (soc_is_exynos4412()) { for (i = 0; exynos4412_pmu_config[i].reg != PMU_TABLE_END ; i++) @@ -227,20 +388,23 @@ void exynos4_sys_powerdown_conf(enum sys_powerdown mode) } } -static int __init exynos4_pmu_init(void) +static int __init exynos_pmu_init(void) { - exynos4_pmu_config = exynos4210_pmu_config; + exynos_pmu_config = exynos4210_pmu_config; if (soc_is_exynos4210()) { - exynos4_pmu_config = exynos4210_pmu_config; + exynos_pmu_config = exynos4210_pmu_config; pr_info("EXYNOS4210 PMU Initialize\n"); } else if (soc_is_exynos4212() || soc_is_exynos4412()) { - exynos4_pmu_config = exynos4x12_pmu_config; + exynos_pmu_config = exynos4x12_pmu_config; pr_info("EXYNOS4x12 PMU Initialize\n"); + } else if (soc_is_exynos5250()) { + exynos_pmu_config = exynos5250_pmu_config; + pr_info("EXYNOS5250 PMU Initialize\n"); } else { - pr_info("EXYNOS4: PMU not supported\n"); + pr_info("EXYNOS: PMU not supported\n"); } return 0; } -arch_initcall(exynos4_pmu_init); +arch_initcall(exynos_pmu_init); diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index ebbd7fc90eb4..a9f80943d01f 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -28,6 +28,7 @@ #include <linux/clockchips.h> #include <linux/io.h> #include <linux/export.h> +#include <linux/gpio.h> #include <mach/udc.h> #include <mach/hardware.h> @@ -107,7 +108,7 @@ static signed char irq2gpio[32] = { 7, 8, 9, 10, 11, 12, -1, -1, }; -int gpio_to_irq(int gpio) +static int ixp4xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) { int irq; @@ -117,7 +118,6 @@ int gpio_to_irq(int gpio) } return -EINVAL; } -EXPORT_SYMBOL(gpio_to_irq); int irq_to_gpio(unsigned int irq) { @@ -383,12 +383,56 @@ static struct platform_device *ixp46x_devices[] __initdata = { unsigned long ixp4xx_exp_bus_size; EXPORT_SYMBOL(ixp4xx_exp_bus_size); +static int ixp4xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + gpio_line_config(gpio, IXP4XX_GPIO_IN); + + return 0; +} + +static int ixp4xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, + int level) +{ + gpio_line_set(gpio, level); + gpio_line_config(gpio, IXP4XX_GPIO_OUT); + + return 0; +} + +static int ixp4xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + int value; + + gpio_line_get(gpio, &value); + + return value; +} + +static void ixp4xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, + int value) +{ + gpio_line_set(gpio, value); +} + +static struct gpio_chip ixp4xx_gpio_chip = { + .label = "IXP4XX_GPIO_CHIP", + .direction_input = ixp4xx_gpio_direction_input, + .direction_output = ixp4xx_gpio_direction_output, + .get = ixp4xx_gpio_get_value, + .set = ixp4xx_gpio_set_value, + .to_irq = ixp4xx_gpio_to_irq, + .base = 0, + .ngpio = 16, +}; + void __init ixp4xx_sys_init(void) { ixp4xx_exp_bus_size = SZ_16M; platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices)); + gpiochip_add(&ixp4xx_gpio_chip); + if (cpu_is_ixp46x()) { int region; diff --git a/arch/arm/mach-ixp4xx/include/mach/gpio.h b/arch/arm/mach-ixp4xx/include/mach/gpio.h index 83d6b4ed60bb..ef37f2635b0e 100644 --- a/arch/arm/mach-ixp4xx/include/mach/gpio.h +++ b/arch/arm/mach-ixp4xx/include/mach/gpio.h @@ -1,79 +1,2 @@ -/* - * arch/arm/mach-ixp4xx/include/mach/gpio.h - * - * IXP4XX GPIO wrappers for arch-neutral GPIO calls - * - * Written by Milan Svoboda <msvoboda@ra.rockwell.com> - * Based on PXA implementation by Philipp Zabel <philipp.zabel@gmail.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 - * - */ - -#ifndef __ASM_ARCH_IXP4XX_GPIO_H -#define __ASM_ARCH_IXP4XX_GPIO_H - -#include <linux/kernel.h> -#include <mach/hardware.h> - -#define __ARM_GPIOLIB_COMPLEX - -static inline int gpio_request(unsigned gpio, const char *label) -{ - return 0; -} - -static inline void gpio_free(unsigned gpio) -{ - might_sleep(); - - return; -} - -static inline int gpio_direction_input(unsigned gpio) -{ - gpio_line_config(gpio, IXP4XX_GPIO_IN); - return 0; -} - -static inline int gpio_direction_output(unsigned gpio, int level) -{ - gpio_line_set(gpio, level); - gpio_line_config(gpio, IXP4XX_GPIO_OUT); - return 0; -} - -static inline int gpio_get_value(unsigned gpio) -{ - int value; - - gpio_line_get(gpio, &value); - - return value; -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ - gpio_line_set(gpio, value); -} - -#include <asm-generic/gpio.h> /* cansleep wrappers */ - -extern int gpio_to_irq(int gpio); -#define gpio_to_irq gpio_to_irq -extern int irq_to_gpio(unsigned int irq); - -#endif +/* empty */ diff --git a/arch/arm/mach-s3c24xx/include/mach/irqs.h b/arch/arm/mach-s3c24xx/include/mach/irqs.h index e53b2177319e..b7a9f4d469e8 100644 --- a/arch/arm/mach-s3c24xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c24xx/include/mach/irqs.h @@ -134,6 +134,17 @@ #define IRQ_S32416_WDT S3C2410_IRQSUB(27) #define IRQ_S32416_AC97 S3C2410_IRQSUB(28) +/* second interrupt-register of s3c2416/s3c2450 */ + +#define S3C2416_IRQ(x) S3C2410_IRQ((x) + 54 + 29) +#define IRQ_S3C2416_2D S3C2416_IRQ(0) +#define IRQ_S3C2416_IIC1 S3C2416_IRQ(1) +#define IRQ_S3C2416_RESERVED2 S3C2416_IRQ(2) +#define IRQ_S3C2416_RESERVED3 S3C2416_IRQ(3) +#define IRQ_S3C2416_PCM0 S3C2416_IRQ(4) +#define IRQ_S3C2416_PCM1 S3C2416_IRQ(5) +#define IRQ_S3C2416_I2S0 S3C2416_IRQ(6) +#define IRQ_S3C2416_I2S1 S3C2416_IRQ(7) /* extra irqs for s3c2440 */ @@ -175,7 +186,9 @@ #define IRQ_S3C2443_WDT S3C2410_IRQSUB(27) #define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28) -#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416) +#if defined(CONFIG_CPU_S3C2416) +#define NR_IRQS (IRQ_S3C2416_I2S1 + 1) +#elif defined(CONFIG_CPU_S3C2443) #define NR_IRQS (IRQ_S3C2443_AC97+1) #else #define NR_IRQS (IRQ_S3C2440_AC97+1) diff --git a/arch/arm/mach-s3c24xx/irq-s3c2416.c b/arch/arm/mach-s3c24xx/irq-s3c2416.c index fd49f35e448e..23ec97370f32 100644 --- a/arch/arm/mach-s3c24xx/irq-s3c2416.c +++ b/arch/arm/mach-s3c24xx/irq-s3c2416.c @@ -27,6 +27,7 @@ #include <linux/ioport.h> #include <linux/device.h> #include <linux/io.h> +#include <linux/syscore_ops.h> #include <mach/hardware.h> #include <asm/irq.h> @@ -192,6 +193,43 @@ static struct irq_chip s3c2416_irq_uart3 = { .irq_ack = s3c2416_irq_uart3_ack, }; +/* second interrupt register */ + +static inline void s3c2416_irq_ack_second(struct irq_data *data) +{ + unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D); + + __raw_writel(bitval, S3C2416_SRCPND2); + __raw_writel(bitval, S3C2416_INTPND2); +} + +static void s3c2416_irq_mask_second(struct irq_data *data) +{ + unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D); + unsigned long mask; + + mask = __raw_readl(S3C2416_INTMSK2); + mask |= bitval; + __raw_writel(mask, S3C2416_INTMSK2); +} + +static void s3c2416_irq_unmask_second(struct irq_data *data) +{ + unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D); + unsigned long mask; + + mask = __raw_readl(S3C2416_INTMSK2); + mask &= ~bitval; + __raw_writel(mask, S3C2416_INTMSK2); +} + +struct irq_chip s3c2416_irq_second = { + .irq_ack = s3c2416_irq_ack_second, + .irq_mask = s3c2416_irq_mask_second, + .irq_unmask = s3c2416_irq_unmask_second, +}; + + /* IRQ initialisation code */ static int __init s3c2416_add_sub(unsigned int base, @@ -213,6 +251,42 @@ static int __init s3c2416_add_sub(unsigned int base, return 0; } +static void __init s3c2416_irq_add_second(void) +{ + unsigned long pend; + unsigned long last; + int irqno; + int i; + + /* first, clear all interrupts pending... */ + last = 0; + for (i = 0; i < 4; i++) { + pend = __raw_readl(S3C2416_INTPND2); + + if (pend == 0 || pend == last) + break; + + __raw_writel(pend, S3C2416_SRCPND2); + __raw_writel(pend, S3C2416_INTPND2); + printk(KERN_INFO "irq: clearing pending status %08x\n", + (int)pend); + last = pend; + } + + for (irqno = IRQ_S3C2416_2D; irqno <= IRQ_S3C2416_I2S1; irqno++) { + switch (irqno) { + case IRQ_S3C2416_RESERVED2: + case IRQ_S3C2416_RESERVED3: + /* no IRQ here */ + break; + default: + irq_set_chip_and_handler(irqno, &s3c2416_irq_second, + handle_edge_irq); + set_irq_flags(irqno, IRQF_VALID); + } + } +} + static int __init s3c2416_irq_add(struct device *dev, struct subsys_interface *sif) { @@ -232,6 +306,8 @@ static int __init s3c2416_irq_add(struct device *dev, &s3c2416_irq_wdtac97, IRQ_S3C2443_WDT, IRQ_S3C2443_AC97); + s3c2416_irq_add_second(); + return 0; } @@ -248,3 +324,25 @@ static int __init s3c2416_irq_init(void) arch_initcall(s3c2416_irq_init); +#ifdef CONFIG_PM +static struct sleep_save irq_save[] = { + SAVE_ITEM(S3C2416_INTMSK2), +}; + +int s3c2416_irq_suspend(void) +{ + s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); + + return 0; +} + +void s3c2416_irq_resume(void) +{ + s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); +} + +struct syscore_ops s3c2416_irq_syscore_ops = { + .suspend = s3c2416_irq_suspend, + .resume = s3c2416_irq_resume, +}; +#endif diff --git a/arch/arm/mach-s3c24xx/s3c2416.c b/arch/arm/mach-s3c24xx/s3c2416.c index 7743fade50df..ed5a95ece9eb 100644 --- a/arch/arm/mach-s3c24xx/s3c2416.c +++ b/arch/arm/mach-s3c24xx/s3c2416.c @@ -106,6 +106,7 @@ int __init s3c2416_init(void) register_syscore_ops(&s3c2416_pm_syscore_ops); #endif register_syscore_ops(&s3c24xx_irq_syscore_ops); + register_syscore_ops(&s3c2416_irq_syscore_ops); return device_register(&s3c2416_dev); } diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c index 179460f38db7..acb197ccf3f7 100644 --- a/arch/arm/mach-s3c64xx/cpuidle.c +++ b/arch/arm/mach-s3c64xx/cpuidle.c @@ -27,12 +27,7 @@ static int s3c64xx_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - struct timeval before, after; unsigned long tmp; - int idle_time; - - local_irq_disable(); - do_gettimeofday(&before); /* Setup PWRCFG to enter idle mode */ tmp = __raw_readl(S3C64XX_PWR_CFG); @@ -42,42 +37,32 @@ static int s3c64xx_enter_idle(struct cpuidle_device *dev, cpu_do_idle(); - do_gettimeofday(&after); - local_irq_enable(); - idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + - (after.tv_usec - before.tv_usec); - - dev->last_residency = idle_time; return index; } -static struct cpuidle_state s3c64xx_cpuidle_set[] = { - [0] = { - .enter = s3c64xx_enter_idle, - .exit_latency = 1, - .target_residency = 1, - .flags = CPUIDLE_FLAG_TIME_VALID, - .name = "IDLE", - .desc = "System active, ARM gated", - }, -}; +static DEFINE_PER_CPU(struct cpuidle_device, s3c64xx_cpuidle_device); static struct cpuidle_driver s3c64xx_cpuidle_driver = { - .name = "s3c64xx_cpuidle", - .owner = THIS_MODULE, - .state_count = ARRAY_SIZE(s3c64xx_cpuidle_set), -}; - -static struct cpuidle_device s3c64xx_cpuidle_device = { - .state_count = ARRAY_SIZE(s3c64xx_cpuidle_set), + .name = "s3c64xx_cpuidle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states = { + { + .enter = s3c64xx_enter_idle, + .exit_latency = 1, + .target_residency = 1, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "IDLE", + .desc = "System active, ARM gated", + }, + }, + .state_count = 1, }; static int __init s3c64xx_init_cpuidle(void) { int ret; - memcpy(s3c64xx_cpuidle_driver.states, s3c64xx_cpuidle_set, - sizeof(s3c64xx_cpuidle_set)); cpuidle_register_driver(&s3c64xx_cpuidle_driver); ret = cpuidle_register_device(&s3c64xx_cpuidle_device); diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index 0ace108c3e3d..7a27f5603c74 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -182,6 +182,11 @@ static const struct i2c_board_info wm1277_devs[] = { }, }; +static const struct i2c_board_info wm6230_i2c_devs[] = { + { I2C_BOARD_INFO("wm9081", 0x6c), + .platform_data = &wm9081_pdata, }, +}; + static __devinitdata const struct { u8 id; const char *name; @@ -195,7 +200,9 @@ static __devinitdata const struct { { .id = 0x03, .name = "1252-EV1 Glenlivet" }, { .id = 0x11, .name = "6249-EV2 Glenfarclas", }, { .id = 0x14, .name = "6271-EV1 Lochnagar" }, - { .id = 0x15, .name = "XXXX-EV1 Bells" }, + { .id = 0x15, .name = "6320-EV1 Bells", + .i2c_devs = wm6230_i2c_devs, + .num_i2c_devs = ARRAY_SIZE(wm6230_i2c_devs) }, { .id = 0x21, .name = "1275-EV1 Mortlach" }, { .id = 0x25, .name = "1274-EV1 Glencadam" }, { .id = 0x31, .name = "1253-EV1 Tomatin", diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index eda5e027b109..6b20a71d7dbf 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -671,6 +671,7 @@ static struct i2c_board_info i2c_devs1[] __initdata = { .irq = S3C_EINT(0), .platform_data = &glenfarclas_pmic_pdata }, + { I2C_BOARD_INFO("wlf-gf-module", 0x22) }, { I2C_BOARD_INFO("wlf-gf-module", 0x24) }, { I2C_BOARD_INFO("wlf-gf-module", 0x25) }, { I2C_BOARD_INFO("wlf-gf-module", 0x26) }, diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 04dd092211b8..fde26adaef32 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -14,7 +14,6 @@ #include <linux/ata_platform.h> #include <linux/smsc911x.h> #include <linux/spinlock.h> -#include <linux/device.h> #include <linux/usb/isp1760.h> #include <linux/clkdev.h> #include <linux/mtd/physmap.h> @@ -31,7 +30,6 @@ #include <asm/hardware/gic.h> #include <asm/hardware/timer-sp.h> #include <asm/hardware/sp810.h> -#include <asm/hardware/gic.h> #include <mach/ct-ca9x4.h> #include <mach/motherboard.h> diff --git a/arch/arm/plat-samsung/include/plat/s3c2416.h b/arch/arm/plat-samsung/include/plat/s3c2416.h index de2b5bdc5ebd..7178e338e25e 100644 --- a/arch/arm/plat-samsung/include/plat/s3c2416.h +++ b/arch/arm/plat-samsung/include/plat/s3c2416.h @@ -24,6 +24,9 @@ extern void s3c2416_init_clocks(int xtal); extern int s3c2416_baseclk_add(void); extern void s3c2416_restart(char mode, const char *cmd); + +extern struct syscore_ops s3c2416_irq_syscore_ops; + #else #define s3c2416_init_clocks NULL #define s3c2416_init_uarts NULL diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index ddb8b24b823d..3ff21b536f28 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -18,6 +18,7 @@ config PARISC select IRQ_PER_CPU select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_SMP_IDLE_THREAD + select GENERIC_STRNCPY_FROM_USER help The PA-RISC microprocessor is designed by Hewlett-Packard and used diff --git a/arch/parisc/include/asm/smp.h b/arch/parisc/include/asm/smp.h index e8f8037d872b..a5dc9066c6d8 100644 --- a/arch/parisc/include/asm/smp.h +++ b/arch/parisc/include/asm/smp.h @@ -25,7 +25,6 @@ typedef unsigned long address_t; #define cpu_number_map(cpu) (cpu) #define cpu_logical_map(cpu) (cpu) -extern void smp_send_reschedule(int cpu); extern void smp_send_all_nop(void); extern void arch_send_call_function_single_ipi(int cpu); @@ -50,6 +49,5 @@ static inline void __cpu_die (unsigned int cpu) { while(1) ; } -extern int __cpu_up (unsigned int cpu); #endif /* __ASM_SMP_H */ diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index 9ac066086f03..4ba2c93770f1 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h @@ -218,15 +218,14 @@ struct exception_data { extern unsigned long lcopy_to_user(void __user *, const void *, unsigned long); extern unsigned long lcopy_from_user(void *, const void __user *, unsigned long); extern unsigned long lcopy_in_user(void __user *, const void __user *, unsigned long); -extern long lstrncpy_from_user(char *, const char __user *, long); +extern long strncpy_from_user(char *, const char __user *, long); extern unsigned lclear_user(void __user *,unsigned long); extern long lstrnlen_user(const char __user *,long); - /* * Complex access routines -- macros */ +#define user_addr_max() (~0UL) -#define strncpy_from_user lstrncpy_from_user #define strnlen_user lstrnlen_user #define strlen_user(str) lstrnlen_user(str, 0x7fffffffL) #define clear_user lclear_user diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 535034217021..07ef351edd57 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -552,7 +552,7 @@ * entry (identifying the physical page) and %r23 up with * the from tlb entry (or nothing if only a to entry---for * clear_user_page_asm) */ - .macro do_alias spc,tmp,tmp1,va,pte,prot,fault + .macro do_alias spc,tmp,tmp1,va,pte,prot,fault,patype cmpib,COND(<>),n 0,\spc,\fault ldil L%(TMPALIAS_MAP_START),\tmp #if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000) @@ -581,11 +581,15 @@ */ cmpiclr,= 0x01,\tmp,%r0 ldi (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot -#ifdef CONFIG_64BIT +.ifc \patype,20 depd,z \prot,8,7,\prot -#else +.else +.ifc \patype,11 depw,z \prot,8,7,\prot -#endif +.else + .error "undefined PA type to do_alias" +.endif +.endif /* * OK, it is in the temp alias region, check whether "from" or "to". * Check "subtle" note in pacache.S re: r23/r26. @@ -1189,7 +1193,7 @@ dtlb_miss_20w: nop dtlb_check_alias_20w: - do_alias spc,t0,t1,va,pte,prot,dtlb_fault + do_alias spc,t0,t1,va,pte,prot,dtlb_fault,20 idtlbt pte,prot @@ -1213,7 +1217,7 @@ nadtlb_miss_20w: nop nadtlb_check_alias_20w: - do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate + do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate,20 idtlbt pte,prot @@ -1245,7 +1249,7 @@ dtlb_miss_11: nop dtlb_check_alias_11: - do_alias spc,t0,t1,va,pte,prot,dtlb_fault + do_alias spc,t0,t1,va,pte,prot,dtlb_fault,11 idtlba pte,(va) idtlbp prot,(va) @@ -1277,7 +1281,7 @@ nadtlb_miss_11: nop nadtlb_check_alias_11: - do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate + do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate,11 idtlba pte,(va) idtlbp prot,(va) @@ -1304,7 +1308,7 @@ dtlb_miss_20: nop dtlb_check_alias_20: - do_alias spc,t0,t1,va,pte,prot,dtlb_fault + do_alias spc,t0,t1,va,pte,prot,dtlb_fault,20 idtlbt pte,prot @@ -1330,7 +1334,7 @@ nadtlb_miss_20: nop nadtlb_check_alias_20: - do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate + do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate,20 idtlbt pte,prot @@ -1457,7 +1461,7 @@ naitlb_miss_20w: nop naitlb_check_alias_20w: - do_alias spc,t0,t1,va,pte,prot,naitlb_fault + do_alias spc,t0,t1,va,pte,prot,naitlb_fault,20 iitlbt pte,prot @@ -1511,7 +1515,7 @@ naitlb_miss_11: nop naitlb_check_alias_11: - do_alias spc,t0,t1,va,pte,prot,itlb_fault + do_alias spc,t0,t1,va,pte,prot,itlb_fault,11 iitlba pte,(%sr0, va) iitlbp prot,(%sr0, va) @@ -1557,7 +1561,7 @@ naitlb_miss_20: nop naitlb_check_alias_20: - do_alias spc,t0,t1,va,pte,prot,naitlb_fault + do_alias spc,t0,t1,va,pte,prot,naitlb_fault,20 iitlbt pte,prot diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index a7bb757a5497..ceec85de6290 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -44,7 +44,6 @@ EXPORT_SYMBOL(__cmpxchg_u64); #endif #include <asm/uaccess.h> -EXPORT_SYMBOL(lstrncpy_from_user); EXPORT_SYMBOL(lclear_user); EXPORT_SYMBOL(lstrnlen_user); diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index fa6f2b8163e0..64a999882e4f 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -50,8 +50,10 @@ SECTIONS . = KERNEL_BINARY_TEXT_START; _text = .; /* Text and read-only data */ - .text ALIGN(16) : { + .head ALIGN(16) : { HEAD_TEXT + } = 0 + .text ALIGN(16) : { TEXT_TEXT SCHED_TEXT LOCK_TEXT @@ -65,7 +67,7 @@ SECTIONS *(.fixup) *(.lock.text) /* out-of-line lock text */ *(.gnu.warning) - } = 0 + } /* End of text section */ _etext = .; diff --git a/arch/parisc/lib/lusercopy.S b/arch/parisc/lib/lusercopy.S index 1bd23ccec17b..6f2d9355efe2 100644 --- a/arch/parisc/lib/lusercopy.S +++ b/arch/parisc/lib/lusercopy.S @@ -61,47 +61,6 @@ .endm /* - * long lstrncpy_from_user(char *dst, const char *src, long n) - * - * Returns -EFAULT if exception before terminator, - * N if the entire buffer filled, - * otherwise strlen (i.e. excludes zero byte) - */ - -ENTRY(lstrncpy_from_user) - .proc - .callinfo NO_CALLS - .entry - comib,= 0,%r24,$lsfu_done - copy %r24,%r23 - get_sr -1: ldbs,ma 1(%sr1,%r25),%r1 -$lsfu_loop: - stbs,ma %r1,1(%r26) - comib,=,n 0,%r1,$lsfu_done - addib,<>,n -1,%r24,$lsfu_loop -2: ldbs,ma 1(%sr1,%r25),%r1 -$lsfu_done: - sub %r23,%r24,%r28 -$lsfu_exit: - bv %r0(%r2) - nop - .exit -ENDPROC(lstrncpy_from_user) - - .section .fixup,"ax" -3: fixup_branch $lsfu_exit - ldi -EFAULT,%r28 - .previous - - .section __ex_table,"aw" - ASM_ULONG_INSN 1b,3b - ASM_ULONG_INSN 2b,3b - .previous - - .procend - - /* * unsigned long lclear_user(void *to, unsigned long n) * * Returns 0 for success. diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index b403c533432c..a39b4690c171 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -87,6 +87,7 @@ config S390 select ARCH_SAVE_PAGE_KEYS if HIBERNATION select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP + select HAVE_CMPXCHG_LOCAL select ARCH_DISCARD_MEMBLOCK select ARCH_INLINE_SPIN_TRYLOCK select ARCH_INLINE_SPIN_TRYLOCK_BH diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h index e5beb490959b..a6ff5a83e227 100644 --- a/arch/s390/include/asm/bitops.h +++ b/arch/s390/include/asm/bitops.h @@ -13,8 +13,6 @@ * */ -#ifdef __KERNEL__ - #ifndef _LINUX_BITOPS_H #error only <linux/bitops.h> can be included directly #endif @@ -63,7 +61,7 @@ extern const char _ni_bitmap[]; extern const char _zb_findmap[]; extern const char _sb_findmap[]; -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define __BITOPS_ALIGN 3 #define __BITOPS_WORDSIZE 32 @@ -83,7 +81,7 @@ extern const char _sb_findmap[]; : "d" (__val), "Q" (*(unsigned long *) __addr) \ : "cc"); -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ #define __BITOPS_ALIGN 7 #define __BITOPS_WORDSIZE 64 @@ -103,7 +101,7 @@ extern const char _sb_findmap[]; : "d" (__val), "Q" (*(unsigned long *) __addr) \ : "cc"); -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ #define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE) #define __BITOPS_BARRIER() asm volatile("" : : : "memory") @@ -412,7 +410,7 @@ static inline unsigned long __ffz_word_loop(const unsigned long *addr, unsigned long bytes = 0; asm volatile( -#ifndef __s390x__ +#ifndef CONFIG_64BIT " ahi %1,-1\n" " sra %1,5\n" " jz 1f\n" @@ -449,7 +447,7 @@ static inline unsigned long __ffs_word_loop(const unsigned long *addr, unsigned long bytes = 0; asm volatile( -#ifndef __s390x__ +#ifndef CONFIG_64BIT " ahi %1,-1\n" " sra %1,5\n" " jz 1f\n" @@ -481,7 +479,7 @@ static inline unsigned long __ffs_word_loop(const unsigned long *addr, */ static inline unsigned long __ffz_word(unsigned long nr, unsigned long word) { -#ifdef __s390x__ +#ifdef CONFIG_64BIT if ((word & 0xffffffff) == 0xffffffff) { word >>= 32; nr += 32; @@ -505,7 +503,7 @@ static inline unsigned long __ffz_word(unsigned long nr, unsigned long word) */ static inline unsigned long __ffs_word(unsigned long nr, unsigned long word) { -#ifdef __s390x__ +#ifdef CONFIG_64BIT if ((word & 0xffffffff) == 0) { word >>= 32; nr += 32; @@ -546,7 +544,7 @@ static inline unsigned long __load_ulong_le(const unsigned long *p, unsigned long word; p = (unsigned long *)((unsigned long) p + offset); -#ifndef __s390x__ +#ifndef CONFIG_64BIT asm volatile( " ic %0,%O1(%R1)\n" " icm %0,2,%O1+1(%R1)\n" @@ -834,7 +832,4 @@ static inline int find_next_bit_le(void *vaddr, unsigned long size, #include <asm-generic/bitops/ext2-atomic-setbit.h> - -#endif /* __KERNEL__ */ - #endif /* _S390_BITOPS_H */ diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index fc50a3342da3..4c8d4d5b8bd2 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h @@ -10,8 +10,6 @@ #include <linux/spinlock.h> #include <asm/types.h> -#ifdef __KERNEL__ - #define LPM_ANYPATH 0xff #define __MAX_CSSID 0 @@ -291,5 +289,3 @@ int chsc_sstpc(void *page, unsigned int op, u16 ctrl); int chsc_sstpi(void *page, void *result, size_t size); #endif - -#endif diff --git a/arch/s390/include/asm/cmpxchg.h b/arch/s390/include/asm/cmpxchg.h index 81d7908416cf..8d798e962b63 100644 --- a/arch/s390/include/asm/cmpxchg.h +++ b/arch/s390/include/asm/cmpxchg.h @@ -29,7 +29,7 @@ static inline unsigned long __xchg(unsigned long x, void *ptr, int size) " cs %0,0,%4\n" " jl 0b\n" : "=&d" (old), "=Q" (*(int *) addr) - : "d" (x << shift), "d" (~(255 << shift)), + : "d" ((x & 0xff) << shift), "d" (~(0xff << shift)), "Q" (*(int *) addr) : "memory", "cc", "0"); return old >> shift; case 2: @@ -44,7 +44,7 @@ static inline unsigned long __xchg(unsigned long x, void *ptr, int size) " cs %0,0,%4\n" " jl 0b\n" : "=&d" (old), "=Q" (*(int *) addr) - : "d" (x << shift), "d" (~(65535 << shift)), + : "d" ((x & 0xffff) << shift), "d" (~(0xffff << shift)), "Q" (*(int *) addr) : "memory", "cc", "0"); return old >> shift; case 4: @@ -113,9 +113,10 @@ static inline unsigned long __cmpxchg(void *ptr, unsigned long old, " nr %1,%5\n" " jnz 0b\n" "1:" - : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) - : "d" (old << shift), "d" (new << shift), - "d" (~(255 << shift)), "Q" (*(int *) ptr) + : "=&d" (prev), "=&d" (tmp), "+Q" (*(int *) addr) + : "d" ((old & 0xff) << shift), + "d" ((new & 0xff) << shift), + "d" (~(0xff << shift)) : "memory", "cc"); return prev >> shift; case 2: @@ -134,9 +135,10 @@ static inline unsigned long __cmpxchg(void *ptr, unsigned long old, " nr %1,%5\n" " jnz 0b\n" "1:" - : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) - : "d" (old << shift), "d" (new << shift), - "d" (~(65535 << shift)), "Q" (*(int *) ptr) + : "=&d" (prev), "=&d" (tmp), "+Q" (*(int *) addr) + : "d" ((old & 0xffff) << shift), + "d" ((new & 0xffff) << shift), + "d" (~(0xffff << shift)) : "memory", "cc"); return prev >> shift; case 4: @@ -160,9 +162,14 @@ static inline unsigned long __cmpxchg(void *ptr, unsigned long old, return old; } -#define cmpxchg(ptr, o, n) \ - ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ - (unsigned long)(n), sizeof(*(ptr)))) +#define cmpxchg(ptr, o, n) \ +({ \ + __typeof__(*(ptr)) __ret; \ + __ret = (__typeof__(*(ptr))) \ + __cmpxchg((ptr), (unsigned long)(o), (unsigned long)(n), \ + sizeof(*(ptr))); \ + __ret; \ +}) #ifdef CONFIG_64BIT #define cmpxchg64(ptr, o, n) \ @@ -181,13 +188,19 @@ static inline unsigned long long __cmpxchg64(void *ptr, " cds %0,%2,%1" : "+&d" (rp_old), "=Q" (ptr) : "d" (rp_new), "Q" (ptr) - : "cc"); + : "memory", "cc"); return rp_old.pair; } -#define cmpxchg64(ptr, o, n) \ - ((__typeof__(*(ptr)))__cmpxchg64((ptr), \ - (unsigned long long)(o), \ - (unsigned long long)(n))) + +#define cmpxchg64(ptr, o, n) \ +({ \ + __typeof__(*(ptr)) __ret; \ + __ret = (__typeof__(*(ptr))) \ + __cmpxchg64((ptr), \ + (unsigned long long)(o), \ + (unsigned long long)(n)); \ + __ret; \ +}) #endif /* CONFIG_64BIT */ #include <asm-generic/cmpxchg-local.h> @@ -216,8 +229,13 @@ static inline unsigned long __cmpxchg_local(void *ptr, * them available. */ #define cmpxchg_local(ptr, o, n) \ - ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ - (unsigned long)(n), sizeof(*(ptr)))) +({ \ + __typeof__(*(ptr)) __ret; \ + __ret = (__typeof__(*(ptr))) \ + __cmpxchg_local((ptr), (unsigned long)(o), \ + (unsigned long)(n), sizeof(*(ptr))); \ + __ret; \ +}) #define cmpxchg64_local(ptr, o, n) cmpxchg64((ptr), (o), (n)) diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h index 24ef186a1c4f..718374de9c7f 100644 --- a/arch/s390/include/asm/cputime.h +++ b/arch/s390/include/asm/cputime.h @@ -21,15 +21,15 @@ typedef unsigned long long __nocast cputime64_t; static inline unsigned long __div(unsigned long long n, unsigned long base) { -#ifndef __s390x__ +#ifndef CONFIG_64BIT register_pair rp; rp.pair = n >> 1; asm ("dr %0,%1" : "+d" (rp) : "d" (base >> 1)); return rp.subreg.odd; -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ return n / base; -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ } #define cputime_one_jiffy jiffies_to_cputime(1) @@ -100,7 +100,7 @@ static inline void cputime_to_timespec(const cputime_t cputime, struct timespec *value) { unsigned long long __cputime = (__force unsigned long long) cputime; -#ifndef __s390x__ +#ifndef CONFIG_64BIT register_pair rp; rp.pair = __cputime >> 1; @@ -128,7 +128,7 @@ static inline void cputime_to_timeval(const cputime_t cputime, struct timeval *value) { unsigned long long __cputime = (__force unsigned long long) cputime; -#ifndef __s390x__ +#ifndef CONFIG_64BIT register_pair rp; rp.pair = __cputime >> 1; diff --git a/arch/s390/include/asm/ctl_reg.h b/arch/s390/include/asm/ctl_reg.h index ecde9417d669..debfda33d1f8 100644 --- a/arch/s390/include/asm/ctl_reg.h +++ b/arch/s390/include/asm/ctl_reg.h @@ -7,7 +7,7 @@ #ifndef __ASM_CTL_REG_H #define __ASM_CTL_REG_H -#ifdef __s390x__ +#ifdef CONFIG_64BIT #define __ctl_load(array, low, high) ({ \ typedef struct { char _[sizeof(array)]; } addrtype; \ @@ -25,7 +25,7 @@ : "i" (low), "i" (high)); \ }) -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ #define __ctl_load(array, low, high) ({ \ typedef struct { char _[sizeof(array)]; } addrtype; \ @@ -43,7 +43,7 @@ : "i" (low), "i" (high)); \ }) -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ #define __ctl_set_bit(cr, bit) ({ \ unsigned long __dummy; \ diff --git a/arch/s390/include/asm/current.h b/arch/s390/include/asm/current.h index 83cf36cde2da..7a68084ec2f0 100644 --- a/arch/s390/include/asm/current.h +++ b/arch/s390/include/asm/current.h @@ -11,13 +11,10 @@ #ifndef _S390_CURRENT_H #define _S390_CURRENT_H -#ifdef __KERNEL__ #include <asm/lowcore.h> struct task_struct; #define current ((struct task_struct *const)S390_lowcore.current_task) -#endif - #endif /* !(_S390_CURRENT_H) */ diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index c4ee39f7a4d6..06151e6a3098 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h @@ -107,11 +107,11 @@ /* * These are used to set parameters in the core dumps. */ -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define ELF_CLASS ELFCLASS32 -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ #define ELF_CLASS ELFCLASS64 -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ #define ELF_DATA ELFDATA2MSB #define ELF_ARCH EM_S390 @@ -181,9 +181,9 @@ extern unsigned long elf_hwcap; extern char elf_platform[]; #define ELF_PLATFORM (elf_platform) -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define SET_PERSONALITY(ex) set_personality(PER_LINUX) -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ #define SET_PERSONALITY(ex) \ do { \ if (personality(current->personality) != PER_LINUX32) \ @@ -194,7 +194,7 @@ do { \ else \ clear_thread_flag(TIF_31BIT); \ } while (0) -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ #define STACK_RND_MASK 0x7ffUL diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h index 81cf36b691f1..96bc83ea5c90 100644 --- a/arch/s390/include/asm/futex.h +++ b/arch/s390/include/asm/futex.h @@ -1,8 +1,6 @@ #ifndef _ASM_S390_FUTEX_H #define _ASM_S390_FUTEX_H -#ifdef __KERNEL__ - #include <linux/futex.h> #include <linux/uaccess.h> #include <asm/errno.h> @@ -48,5 +46,4 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return uaccess.futex_atomic_cmpxchg(uval, uaddr, oldval, newval); } -#endif /* __KERNEL__ */ #endif /* _ASM_S390_FUTEX_H */ diff --git a/arch/s390/include/asm/idals.h b/arch/s390/include/asm/idals.h index aae276d00383..aef0dde340d1 100644 --- a/arch/s390/include/asm/idals.h +++ b/arch/s390/include/asm/idals.h @@ -20,7 +20,7 @@ #include <asm/cio.h> #include <asm/uaccess.h> -#ifdef __s390x__ +#ifdef CONFIG_64BIT #define IDA_SIZE_LOG 12 /* 11 for 2k , 12 for 4k */ #else #define IDA_SIZE_LOG 11 /* 11 for 2k , 12 for 4k */ @@ -33,7 +33,7 @@ static inline int idal_is_needed(void *vaddr, unsigned int length) { -#ifdef __s390x__ +#ifdef CONFIG_64BIT return ((__pa(vaddr) + length - 1) >> 31) != 0; #else return 0; @@ -78,7 +78,7 @@ static inline unsigned long *idal_create_words(unsigned long *idaws, static inline int set_normalized_cda(struct ccw1 * ccw, void *vaddr) { -#ifdef __s390x__ +#ifdef CONFIG_64BIT unsigned int nridaws; unsigned long *idal; @@ -105,7 +105,7 @@ set_normalized_cda(struct ccw1 * ccw, void *vaddr) static inline void clear_normalized_cda(struct ccw1 * ccw) { -#ifdef __s390x__ +#ifdef CONFIG_64BIT if (ccw->flags & CCW_FLAG_IDA) { kfree((void *)(unsigned long) ccw->cda); ccw->flags &= ~CCW_FLAG_IDA; @@ -182,7 +182,7 @@ idal_buffer_free(struct idal_buffer *ib) static inline int __idal_buffer_is_needed(struct idal_buffer *ib) { -#ifdef __s390x__ +#ifdef CONFIG_64BIT return ib->size > (4096ul << ib->page_order) || idal_is_needed(ib->data[0], ib->size); #else diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h index 27216d317991..f81a0975cbea 100644 --- a/arch/s390/include/asm/io.h +++ b/arch/s390/include/asm/io.h @@ -11,8 +11,6 @@ #ifndef _S390_IO_H #define _S390_IO_H -#ifdef __KERNEL__ - #include <asm/page.h> #define IO_SPACE_LIMIT 0xffffffff @@ -46,6 +44,4 @@ void unxlate_dev_mem_ptr(unsigned long phys, void *addr); */ #define xlate_dev_kmem_ptr(p) p -#endif /* __KERNEL__ */ - #endif diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h index 5289cacd4861..2b9d41899d21 100644 --- a/arch/s390/include/asm/irq.h +++ b/arch/s390/include/asm/irq.h @@ -17,7 +17,8 @@ enum interruption_class { EXTINT_VRT, EXTINT_SCP, EXTINT_IUC, - EXTINT_CPM, + EXTINT_CMS, + EXTINT_CMC, IOINT_CIO, IOINT_QAI, IOINT_DAS, diff --git a/arch/s390/include/asm/kexec.h b/arch/s390/include/asm/kexec.h index 3f30dac804ea..f4f38826eebb 100644 --- a/arch/s390/include/asm/kexec.h +++ b/arch/s390/include/asm/kexec.h @@ -10,10 +10,8 @@ #ifndef _S390_KEXEC_H #define _S390_KEXEC_H -#ifdef __KERNEL__ -#include <asm/page.h> -#endif #include <asm/processor.h> +#include <asm/page.h> /* * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. * I.e. Maximum page that is mapped directly into kernel memory, diff --git a/arch/s390/include/asm/kmap_types.h b/arch/s390/include/asm/kmap_types.h index 94ec3ee07983..0a88622339ee 100644 --- a/arch/s390/include/asm/kmap_types.h +++ b/arch/s390/include/asm/kmap_types.h @@ -1,8 +1,6 @@ -#ifdef __KERNEL__ #ifndef _ASM_KMAP_TYPES_H #define _ASM_KMAP_TYPES_H #include <asm-generic/kmap_types.h> #endif -#endif /* __KERNEL__ */ diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 5d09e405c54d..69bdf72e95ec 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h @@ -49,7 +49,7 @@ static inline int init_new_context(struct task_struct *tsk, #define destroy_context(mm) do { } while (0) -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define LCTL_OPCODE "lctl" #else #define LCTL_OPCODE "lctlg" diff --git a/arch/s390/include/asm/module.h b/arch/s390/include/asm/module.h index 1cc1c5af705a..f0b6b26b6e59 100644 --- a/arch/s390/include/asm/module.h +++ b/arch/s390/include/asm/module.h @@ -28,7 +28,7 @@ struct mod_arch_specific struct mod_arch_syminfo *syminfo; }; -#ifdef __s390x__ +#ifdef CONFIG_64BIT #define ElfW(x) Elf64_ ## x #define ELFW(x) ELF64_ ## x #else diff --git a/arch/s390/include/asm/os_info.h b/arch/s390/include/asm/os_info.h index d07518af09ea..295f2c4f1c96 100644 --- a/arch/s390/include/asm/os_info.h +++ b/arch/s390/include/asm/os_info.h @@ -13,7 +13,6 @@ #define OS_INFO_VMCOREINFO 0 #define OS_INFO_REIPL_BLOCK 1 -#define OS_INFO_INIT_FN 2 struct os_info_entry { u64 addr; @@ -28,8 +27,8 @@ struct os_info { u16 version_minor; u64 crashkernel_addr; u64 crashkernel_size; - struct os_info_entry entry[3]; - u8 reserved[4004]; + struct os_info_entry entry[2]; + u8 reserved[4024]; } __packed; void os_info_init(void); diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h index 0fbd1899c7b0..6537e72e0853 100644 --- a/arch/s390/include/asm/percpu.h +++ b/arch/s390/include/asm/percpu.h @@ -15,7 +15,7 @@ * per cpu area, use weak definitions to force the compiler to * generate external references. */ -#if defined(CONFIG_SMP) && defined(__s390x__) && defined(MODULE) +#if defined(CONFIG_SMP) && defined(CONFIG_64BIT) && defined(MODULE) #define ARCH_NEEDS_WEAK_PER_CPU #endif diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index 78e3041919de..43078c194394 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -48,7 +48,7 @@ static inline void crst_table_init(unsigned long *crst, unsigned long entry) clear_table(crst, entry, sizeof(unsigned long)*2048); } -#ifndef __s390x__ +#ifndef CONFIG_64BIT static inline unsigned long pgd_entry_type(struct mm_struct *mm) { @@ -64,7 +64,7 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm) #define pgd_populate(mm, pgd, pud) BUG() #define pud_populate(mm, pud, pmd) BUG() -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ static inline unsigned long pgd_entry_type(struct mm_struct *mm) { @@ -106,7 +106,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) pud_val(*pud) = _REGION3_ENTRY | __pa(pmd); } -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ static inline pgd_t *pgd_alloc(struct mm_struct *mm) { diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 011358c1b18e..b3227415abda 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -74,15 +74,15 @@ static inline int is_zero_pfn(unsigned long pfn) * table can map * PGDIR_SHIFT determines what a third-level page table entry can map */ -#ifndef __s390x__ +#ifndef CONFIG_64BIT # define PMD_SHIFT 20 # define PUD_SHIFT 20 # define PGDIR_SHIFT 20 -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ # define PMD_SHIFT 20 # define PUD_SHIFT 31 # define PGDIR_SHIFT 42 -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) @@ -98,13 +98,13 @@ static inline int is_zero_pfn(unsigned long pfn) * that leads to 1024 pte per pgd */ #define PTRS_PER_PTE 256 -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define PTRS_PER_PMD 1 #define PTRS_PER_PUD 1 -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ #define PTRS_PER_PMD 2048 #define PTRS_PER_PUD 2048 -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ #define PTRS_PER_PGD 2048 #define FIRST_USER_ADDRESS 0 @@ -276,7 +276,7 @@ extern struct page *vmemmap; * swap pte is 1011 and 0001, 0011, 0101, 0111 are invalid. */ -#ifndef __s390x__ +#ifndef CONFIG_64BIT /* Bits in the segment table address-space-control-element */ #define _ASCE_SPACE_SWITCH 0x80000000UL /* space switch event */ @@ -308,7 +308,7 @@ extern struct page *vmemmap; #define KVM_UR_BIT 0x00008000UL #define KVM_UC_BIT 0x00004000UL -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ /* Bits in the segment/region table address-space-control-element */ #define _ASCE_ORIGIN ~0xfffUL/* segment table origin */ @@ -363,7 +363,7 @@ extern struct page *vmemmap; #define KVM_UR_BIT 0x0000800000000000UL #define KVM_UC_BIT 0x0000400000000000UL -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ /* * A user page table pointer has the space-switch-event bit, the @@ -424,7 +424,7 @@ static inline int mm_has_pgste(struct mm_struct *mm) /* * pgd/pmd/pte query functions */ -#ifndef __s390x__ +#ifndef CONFIG_64BIT static inline int pgd_present(pgd_t pgd) { return 1; } static inline int pgd_none(pgd_t pgd) { return 0; } @@ -434,7 +434,7 @@ static inline int pud_present(pud_t pud) { return 1; } static inline int pud_none(pud_t pud) { return 0; } static inline int pud_bad(pud_t pud) { return 0; } -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ static inline int pgd_present(pgd_t pgd) { @@ -490,7 +490,7 @@ static inline int pud_bad(pud_t pud) return (pud_val(pud) & mask) != 0; } -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ static inline int pmd_present(pmd_t pmd) { @@ -741,7 +741,7 @@ static inline int pte_young(pte_t pte) static inline void pgd_clear(pgd_t *pgd) { -#ifdef __s390x__ +#ifdef CONFIG_64BIT if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) pgd_val(*pgd) = _REGION2_ENTRY_EMPTY; #endif @@ -749,7 +749,7 @@ static inline void pgd_clear(pgd_t *pgd) static inline void pud_clear(pud_t *pud) { -#ifdef __s390x__ +#ifdef CONFIG_64BIT if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) pud_val(*pud) = _REGION3_ENTRY_EMPTY; #endif @@ -921,7 +921,7 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma, static inline void __ptep_ipte(unsigned long address, pte_t *ptep) { if (!(pte_val(*ptep) & _PAGE_INVALID)) { -#ifndef __s390x__ +#ifndef CONFIG_64BIT /* pto must point to the start of the segment table */ pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00); #else @@ -1116,7 +1116,7 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) #define pgd_offset_k(address) pgd_offset(&init_mm, address) -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) #define pud_deref(pmd) ({ BUG(); 0UL; }) @@ -1125,7 +1125,7 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) #define pud_offset(pgd, address) ((pud_t *) pgd) #define pmd_offset(pud, address) ((pmd_t *) pud + pmd_index(address)) -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ #define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) #define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN) @@ -1147,7 +1147,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) return pmd + pmd_index(address); } -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ #define pfn_pte(pfn,pgprot) mk_pte_phys(__pa((pfn) << PAGE_SHIFT),(pgprot)) #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) @@ -1196,7 +1196,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) * 0000000000111111111122222222223333333333444444444455 5555 5 55566 66 * 0123456789012345678901234567890123456789012345678901 2345 6 78901 23 */ -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define __SWP_OFFSET_MASK (~0UL >> 12) #else #define __SWP_OFFSET_MASK (~0UL >> 11) @@ -1217,11 +1217,11 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) -#ifndef __s390x__ +#ifndef CONFIG_64BIT # define PTE_FILE_MAX_BITS 26 -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ # define PTE_FILE_MAX_BITS 59 -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ #define pte_to_pgoff(__pte) \ ((((__pte).pte >> 12) << 7) + (((__pte).pte >> 1) & 0x7f)) diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 6cbf31311673..20d0585cf905 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -20,7 +20,6 @@ #include <asm/ptrace.h> #include <asm/setup.h> -#ifdef __KERNEL__ /* * Default implementation of macro that returns current * instruction pointer ("program counter"). @@ -33,39 +32,33 @@ static inline void get_cpu_id(struct cpuid *ptr) } extern void s390_adjust_jiffies(void); -extern int get_cpu_capability(unsigned int *); extern const struct seq_operations cpuinfo_op; extern int sysctl_ieee_emulation_warnings; /* * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit. */ -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define TASK_SIZE (1UL << 31) #define TASK_UNMAPPED_BASE (1UL << 30) -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ #define TASK_SIZE_OF(tsk) ((tsk)->mm->context.asce_limit) #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ (1UL << 30) : (1UL << 41)) #define TASK_SIZE TASK_SIZE_OF(current) -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ -#ifdef __KERNEL__ - -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define STACK_TOP (1UL << 31) #define STACK_TOP_MAX (1UL << 31) -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ #define STACK_TOP (1UL << (test_thread_flag(TIF_31BIT) ? 31:42)) #define STACK_TOP_MAX (1UL << 42) -#endif /* __s390x__ */ - - -#endif +#endif /* CONFIG_64BIT */ #define HAVE_ARCH_PICK_MMAP_LAYOUT @@ -182,7 +175,7 @@ static inline void psw_set_key(unsigned int key) */ static inline void __load_psw(psw_t psw) { -#ifndef __s390x__ +#ifndef CONFIG_64BIT asm volatile("lpsw %0" : : "Q" (psw) : "cc"); #else asm volatile("lpswe %0" : : "Q" (psw) : "cc"); @@ -200,7 +193,7 @@ static inline void __load_psw_mask (unsigned long mask) psw.mask = mask; -#ifndef __s390x__ +#ifndef CONFIG_64BIT asm volatile( " basr %0,0\n" "0: ahi %0,1f-0b\n" @@ -208,14 +201,14 @@ static inline void __load_psw_mask (unsigned long mask) " lpsw %1\n" "1:" : "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc"); -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ asm volatile( " larl %0,1f\n" " stg %0,%O1+8(%R1)\n" " lpswe %1\n" "1:" : "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc"); -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ } /* @@ -223,7 +216,7 @@ static inline void __load_psw_mask (unsigned long mask) */ static inline unsigned long __rewind_psw(psw_t psw, unsigned long ilc) { -#ifndef __s390x__ +#ifndef CONFIG_64BIT if (psw.addr & PSW_ADDR_AMODE) /* 31 bit mode */ return (psw.addr - ilc) | PSW_ADDR_AMODE; @@ -253,7 +246,7 @@ static inline void __noreturn disabled_wait(unsigned long code) * Store status and then load disabled wait psw, * the processor is dead afterwards */ -#ifndef __s390x__ +#ifndef CONFIG_64BIT asm volatile( " stctl 0,0,0(%2)\n" " ni 0(%2),0xef\n" /* switch off protection */ @@ -272,7 +265,7 @@ static inline void __noreturn disabled_wait(unsigned long code) " lpsw 0(%1)" : "=m" (ctl_buf) : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc"); -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ asm volatile( " stctg 0,0,0(%2)\n" " ni 4(%2),0xef\n" /* switch off protection */ @@ -305,7 +298,7 @@ static inline void __noreturn disabled_wait(unsigned long code) " lpswe 0(%1)" : "=m" (ctl_buf) : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc", "0", "1"); -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ while (1); } @@ -338,12 +331,10 @@ extern void (*s390_base_ext_handler_fn)(void); #define ARCH_LOW_ADDRESS_LIMIT 0x7fffffffUL -#endif - /* * Helper macro for exception table entries */ -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define EX_TABLE(_fault,_target) \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ diff --git a/arch/s390/include/asm/rwsem.h b/arch/s390/include/asm/rwsem.h index d0eb4653cebd..1ceee10264c3 100644 --- a/arch/s390/include/asm/rwsem.h +++ b/arch/s390/include/asm/rwsem.h @@ -41,19 +41,17 @@ #error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead" #endif -#ifdef __KERNEL__ - -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define RWSEM_UNLOCKED_VALUE 0x00000000 #define RWSEM_ACTIVE_BIAS 0x00000001 #define RWSEM_ACTIVE_MASK 0x0000ffff #define RWSEM_WAITING_BIAS (-0x00010000) -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ #define RWSEM_UNLOCKED_VALUE 0x0000000000000000L #define RWSEM_ACTIVE_BIAS 0x0000000000000001L #define RWSEM_ACTIVE_MASK 0x00000000ffffffffL #define RWSEM_WAITING_BIAS (-0x0000000100000000L) -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) @@ -65,19 +63,19 @@ static inline void __down_read(struct rw_semaphore *sem) signed long old, new; asm volatile( -#ifndef __s390x__ +#ifndef CONFIG_64BIT " l %0,%2\n" "0: lr %1,%0\n" " ahi %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ " lg %0,%2\n" "0: lgr %1,%0\n" " aghi %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory"); @@ -93,7 +91,7 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) signed long old, new; asm volatile( -#ifndef __s390x__ +#ifndef CONFIG_64BIT " l %0,%2\n" "0: ltr %1,%0\n" " jm 1f\n" @@ -101,7 +99,7 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) " cs %0,%1,%2\n" " jl 0b\n" "1:" -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ " lg %0,%2\n" "0: ltgr %1,%0\n" " jm 1f\n" @@ -109,7 +107,7 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) " csg %0,%1,%2\n" " jl 0b\n" "1:" -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory"); @@ -125,19 +123,19 @@ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) tmp = RWSEM_ACTIVE_WRITE_BIAS; asm volatile( -#ifndef __s390x__ +#ifndef CONFIG_64BIT " l %0,%2\n" "0: lr %1,%0\n" " a %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ " lg %0,%2\n" "0: lgr %1,%0\n" " ag %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "m" (tmp) : "cc", "memory"); @@ -158,19 +156,19 @@ static inline int __down_write_trylock(struct rw_semaphore *sem) signed long old; asm volatile( -#ifndef __s390x__ +#ifndef CONFIG_64BIT " l %0,%1\n" "0: ltr %0,%0\n" " jnz 1f\n" " cs %0,%3,%1\n" " jl 0b\n" -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ " lg %0,%1\n" "0: ltgr %0,%0\n" " jnz 1f\n" " csg %0,%3,%1\n" " jl 0b\n" -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ "1:" : "=&d" (old), "=Q" (sem->count) : "Q" (sem->count), "d" (RWSEM_ACTIVE_WRITE_BIAS) @@ -186,19 +184,19 @@ static inline void __up_read(struct rw_semaphore *sem) signed long old, new; asm volatile( -#ifndef __s390x__ +#ifndef CONFIG_64BIT " l %0,%2\n" "0: lr %1,%0\n" " ahi %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ " lg %0,%2\n" "0: lgr %1,%0\n" " aghi %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "i" (-RWSEM_ACTIVE_READ_BIAS) : "cc", "memory"); @@ -216,19 +214,19 @@ static inline void __up_write(struct rw_semaphore *sem) tmp = -RWSEM_ACTIVE_WRITE_BIAS; asm volatile( -#ifndef __s390x__ +#ifndef CONFIG_64BIT " l %0,%2\n" "0: lr %1,%0\n" " a %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ " lg %0,%2\n" "0: lgr %1,%0\n" " ag %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "m" (tmp) : "cc", "memory"); @@ -246,19 +244,19 @@ static inline void __downgrade_write(struct rw_semaphore *sem) tmp = -RWSEM_WAITING_BIAS; asm volatile( -#ifndef __s390x__ +#ifndef CONFIG_64BIT " l %0,%2\n" "0: lr %1,%0\n" " a %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ " lg %0,%2\n" "0: lgr %1,%0\n" " ag %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "m" (tmp) : "cc", "memory"); @@ -274,19 +272,19 @@ static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) signed long old, new; asm volatile( -#ifndef __s390x__ +#ifndef CONFIG_64BIT " l %0,%2\n" "0: lr %1,%0\n" " ar %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ " lg %0,%2\n" "0: lgr %1,%0\n" " agr %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "d" (delta) : "cc", "memory"); @@ -300,24 +298,23 @@ static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) signed long old, new; asm volatile( -#ifndef __s390x__ +#ifndef CONFIG_64BIT " l %0,%2\n" "0: lr %1,%0\n" " ar %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ " lg %0,%2\n" "0: lgr %1,%0\n" " agr %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "d" (delta) : "cc", "memory"); return new; } -#endif /* __KERNEL__ */ #endif /* _S390_RWSEM_H */ diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 7244e1f64126..40eb2ff88e9e 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -22,19 +22,19 @@ #include <asm/lowcore.h> #include <asm/types.h> -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define IPL_DEVICE (*(unsigned long *) (0x10404)) #define INITRD_START (*(unsigned long *) (0x1040C)) #define INITRD_SIZE (*(unsigned long *) (0x10414)) #define OLDMEM_BASE (*(unsigned long *) (0x1041C)) #define OLDMEM_SIZE (*(unsigned long *) (0x10424)) -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ #define IPL_DEVICE (*(unsigned long *) (0x10400)) #define INITRD_START (*(unsigned long *) (0x10408)) #define INITRD_SIZE (*(unsigned long *) (0x10410)) #define OLDMEM_BASE (*(unsigned long *) (0x10418)) #define OLDMEM_SIZE (*(unsigned long *) (0x10420)) -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ #define COMMAND_LINE ((char *) (0x10480)) #define CHUNK_READ_WRITE 0 @@ -89,7 +89,7 @@ extern unsigned int user_mode; #define MACHINE_HAS_DIAG9C (S390_lowcore.machine_flags & MACHINE_FLAG_DIAG9C) -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define MACHINE_HAS_IEEE (S390_lowcore.machine_flags & MACHINE_FLAG_IEEE) #define MACHINE_HAS_CSP (S390_lowcore.machine_flags & MACHINE_FLAG_CSP) #define MACHINE_HAS_IDTE (0) @@ -100,7 +100,7 @@ extern unsigned int user_mode; #define MACHINE_HAS_PFMF (0) #define MACHINE_HAS_SPP (0) #define MACHINE_HAS_TOPOLOGY (0) -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ #define MACHINE_HAS_IEEE (1) #define MACHINE_HAS_CSP (1) #define MACHINE_HAS_IDTE (S390_lowcore.machine_flags & MACHINE_FLAG_IDTE) @@ -111,7 +111,7 @@ extern unsigned int user_mode; #define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF) #define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP) #define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY) -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ #define ZFCPDUMP_HSA_SIZE (32UL<<20) #define ZFCPDUMP_HSA_SIZE_MAX (64UL<<20) @@ -153,19 +153,19 @@ extern void (*_machine_power_off)(void); #else /* __ASSEMBLY__ */ -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define IPL_DEVICE 0x10404 #define INITRD_START 0x1040C #define INITRD_SIZE 0x10414 #define OLDMEM_BASE 0x1041C #define OLDMEM_SIZE 0x10424 -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ #define IPL_DEVICE 0x10400 #define INITRD_START 0x10408 #define INITRD_SIZE 0x10410 #define OLDMEM_BASE 0x10418 #define OLDMEM_SIZE 0x10420 -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ #define COMMAND_LINE 0x10480 #endif /* __ASSEMBLY__ */ diff --git a/arch/s390/include/asm/sfp-util.h b/arch/s390/include/asm/sfp-util.h index ca3f8814e361..5959bfb3b693 100644 --- a/arch/s390/include/asm/sfp-util.h +++ b/arch/s390/include/asm/sfp-util.h @@ -51,7 +51,7 @@ wl = __wl; \ }) -#ifdef __s390x__ +#ifdef CONFIG_64BIT #define udiv_qrnnd(q, r, n1, n0, d) \ do { unsigned long __n; \ unsigned int __r, __d; \ diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h index cd0241db5a46..8cc160c9e1cb 100644 --- a/arch/s390/include/asm/string.h +++ b/arch/s390/include/asm/string.h @@ -9,8 +9,6 @@ #ifndef _S390_STRING_H_ #define _S390_STRING_H_ -#ifdef __KERNEL__ - #ifndef _LINUX_TYPES_H #include <linux/types.h> #endif @@ -152,6 +150,4 @@ size_t strlen(const char *s); size_t strnlen(const char * s, size_t n); #endif /* !IN_ARCH_STRING_C */ -#endif /* __KERNEL__ */ - #endif /* __S390_STRING_H_ */ diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 003b04edcff6..4e40b25cd060 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -9,15 +9,13 @@ #ifndef _ASM_THREAD_INFO_H #define _ASM_THREAD_INFO_H -#ifdef __KERNEL__ - /* * Size of kernel stack for each process */ -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define THREAD_ORDER 1 #define ASYNC_ORDER 1 -#else /* __s390x__ */ +#else /* CONFIG_64BIT */ #ifndef __SMALL_STACK #define THREAD_ORDER 2 #define ASYNC_ORDER 2 @@ -25,7 +23,7 @@ #define THREAD_ORDER 1 #define ASYNC_ORDER 1 #endif -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ #define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) #define ASYNC_SIZE (PAGE_SIZE << ASYNC_ORDER) @@ -123,8 +121,6 @@ static inline struct thread_info *current_thread_info(void) #define is_32bit_task() (1) #endif -#endif /* __KERNEL__ */ - #define PREEMPT_ACTIVE 0x4000000 #endif /* _ASM_THREAD_INFO_H */ diff --git a/arch/s390/include/asm/timer.h b/arch/s390/include/asm/timer.h index e63069ba39e3..15d647901e5c 100644 --- a/arch/s390/include/asm/timer.h +++ b/arch/s390/include/asm/timer.h @@ -10,8 +10,6 @@ #ifndef _ASM_S390_TIMER_H #define _ASM_S390_TIMER_H -#ifdef __KERNEL__ - #include <linux/timer.h> #define VTIMER_MAX_SLICE (0x7ffffffffffff000LL) @@ -50,6 +48,4 @@ extern void vtime_init(void); extern void vtime_stop_cpu(void); extern void vtime_start_leave(void); -#endif /* __KERNEL__ */ - #endif /* _ASM_S390_TIMER_H */ diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index 775a5eea8f9e..06e5acbc84bd 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h @@ -106,7 +106,7 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, unsigned long address) { -#ifdef __s390x__ +#ifdef CONFIG_64BIT if (tlb->mm->context.asce_limit <= (1UL << 31)) return; if (!tlb->fullmm) @@ -125,7 +125,7 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, unsigned long address) { -#ifdef __s390x__ +#ifdef CONFIG_64BIT if (tlb->mm->context.asce_limit <= (1UL << 42)) return; if (!tlb->fullmm) diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h index 1d8648cf2fea..9fde315f3a7c 100644 --- a/arch/s390/include/asm/tlbflush.h +++ b/arch/s390/include/asm/tlbflush.h @@ -27,12 +27,12 @@ static inline void __tlb_flush_global(void) register unsigned long reg4 asm("4"); long dummy; -#ifndef __s390x__ +#ifndef CONFIG_64BIT if (!MACHINE_HAS_CSP) { smp_ptlb_all(); return; } -#endif /* __s390x__ */ +#endif /* CONFIG_64BIT */ dummy = 0; reg2 = reg3 = 0; diff --git a/arch/s390/include/asm/types.h b/arch/s390/include/asm/types.h index 05ebbcdbbf6b..6c8c35f8df14 100644 --- a/arch/s390/include/asm/types.h +++ b/arch/s390/include/asm/types.h @@ -28,7 +28,7 @@ typedef __signed__ long saddr_t; #ifndef __ASSEMBLY__ -#ifndef __s390x__ +#ifndef CONFIG_64BIT typedef union { unsigned long long pair; struct { @@ -37,7 +37,7 @@ typedef union { } subreg; } register_pair; -#endif /* ! __s390x__ */ +#endif /* ! CONFIG_64BIT */ #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _S390_TYPES_H */ diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 8f2cada4f7c9..1f3a79bcd262 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h @@ -50,10 +50,15 @@ #define segment_eq(a,b) ((a).ar4 == (b).ar4) -#define __access_ok(addr, size) \ -({ \ - __chk_user_ptr(addr); \ - 1; \ +static inline int __range_ok(unsigned long addr, unsigned long size) +{ + return 1; +} + +#define __access_ok(addr, size) \ +({ \ + __chk_user_ptr(addr); \ + __range_ok((unsigned long)(addr), (size)); \ }) #define access_ok(type, addr, size) __access_ok(addr, size) @@ -377,7 +382,7 @@ clear_user(void __user *to, unsigned long n) } extern int memcpy_real(void *, void *, size_t); -extern void copy_to_absolute_zero(void *dest, void *src, size_t count); +extern void memcpy_absolute(void *, void *, size_t); extern int copy_to_user_real(void __user *dest, void *src, size_t count); extern int copy_from_user_real(void *dest, void __user *src, size_t count); diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h index c4a11cfad3c8..a73eb2e1e918 100644 --- a/arch/s390/include/asm/vdso.h +++ b/arch/s390/include/asm/vdso.h @@ -1,8 +1,6 @@ #ifndef __S390_VDSO_H__ #define __S390_VDSO_H__ -#ifdef __KERNEL__ - /* Default link addresses for the vDSOs */ #define VDSO32_LBASE 0 #define VDSO64_LBASE 0 @@ -45,7 +43,4 @@ void vdso_free_per_cpu(struct _lowcore *lowcore); #endif #endif /* __ASSEMBLY__ */ - -#endif /* __KERNEL__ */ - #endif /* __S390_VDSO_H__ */ diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S index 3aa4d00aaf50..c880ff72db44 100644 --- a/arch/s390/kernel/base.S +++ b/arch/s390/kernel/base.S @@ -88,6 +88,9 @@ ENTRY(diag308_reset) stctg %c0,%c15,0(%r4) larl %r4,.Lfpctl # Floating point control register stfpc 0(%r4) + larl %r4,.Lcontinue_psw # Save PSW flags + epsw %r2,%r3 + stm %r2,%r3,0(%r4) larl %r4,.Lrestart_psw # Setup restart PSW at absolute 0 lghi %r3,0 lg %r4,0(%r4) # Save PSW @@ -103,11 +106,20 @@ ENTRY(diag308_reset) lctlg %c0,%c15,0(%r4) larl %r4,.Lfpctl # Restore floating point ctl register lfpc 0(%r4) + larl %r4,.Lcontinue_psw # Restore PSW flags + lpswe 0(%r4) +.Lcontinue: br %r14 .align 16 .Lrestart_psw: .long 0x00080000,0x80000000 + .Lrestart_part2 + .section .data..nosave,"aw",@progbits +.align 8 +.Lcontinue_psw: + .quad 0,.Lcontinue + .previous + .section .bss .align 8 .Lctlregs: diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index d84181f1f5e8..6684fff17558 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -237,7 +237,7 @@ static noinline __init void detect_machine_type(void) S390_lowcore.machine_flags |= MACHINE_FLAG_VM; } -static __init void early_pgm_check_handler(void) +static void early_pgm_check_handler(void) { unsigned long addr; const struct exception_table_entry *fixup; diff --git a/arch/s390/kernel/head_kdump.S b/arch/s390/kernel/head_kdump.S index e1ac3893e972..796c976b5fdc 100644 --- a/arch/s390/kernel/head_kdump.S +++ b/arch/s390/kernel/head_kdump.S @@ -85,11 +85,6 @@ startup_kdump_relocated: basr %r13,0 0: mvc 0(8,%r0),.Lrestart_psw-0b(%r13) # Setup restart PSW - mvc 464(16,%r0),.Lpgm_psw-0b(%r13) # Setup pgm check PSW - lhi %r1,1 # Start new kernel - diag %r1,%r1,0x308 # with diag 308 - -.Lno_diag308: # No diag 308 sam31 # Switch to 31 bit addr mode sr %r1,%r1 # Erase register r1 sr %r2,%r2 # Erase register r2 @@ -98,8 +93,6 @@ startup_kdump_relocated: .align 8 .Lrestart_psw: .long 0x00080000,0x80000000 + startup -.Lpgm_psw: - .quad 0x0000000180000000,0x0000000000000000 + .Lno_diag308 #else .align 2 .Lep_startup_kdump: diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 8342e65a140d..2f6cfd460cb6 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -1528,12 +1528,15 @@ static struct shutdown_action __refdata dump_action = { static void dump_reipl_run(struct shutdown_trigger *trigger) { - u32 csum; - - csum = csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0); - copy_to_absolute_zero(&S390_lowcore.ipib_checksum, &csum, sizeof(csum)); - copy_to_absolute_zero(&S390_lowcore.ipib, &reipl_block_actual, - sizeof(reipl_block_actual)); + struct { + void *addr; + __u32 csum; + } __packed ipib; + + ipib.csum = csum_partial(reipl_block_actual, + reipl_block_actual->hdr.len, 0); + ipib.addr = reipl_block_actual; + memcpy_absolute(&S390_lowcore.ipib, &ipib, sizeof(ipib)); dump_run(trigger); } @@ -1750,6 +1753,7 @@ static struct kobj_attribute on_restart_attr = static void __do_restart(void *ignore) { + __arch_local_irq_stosm(0x04); /* enable DAT */ smp_send_stop(); #ifdef CONFIG_CRASH_DUMP crash_kexec(NULL); diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 8a22c27219dd..b4f4a7133fa1 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -42,7 +42,8 @@ static const struct irq_class intrclass_names[] = { {.name = "VRT", .desc = "[EXT] Virtio" }, {.name = "SCP", .desc = "[EXT] Service Call" }, {.name = "IUC", .desc = "[EXT] IUCV" }, - {.name = "CPM", .desc = "[EXT] CPU Measurement" }, + {.name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling" }, + {.name = "CMC", .desc = "[EXT] CPU-Measurement: Counter" }, {.name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt" }, {.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt" }, {.name = "DAS", .desc = "[I/O] DASD" }, diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index bdad47d54478..cdacf8f91b2d 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -24,6 +24,7 @@ #include <asm/ipl.h> #include <asm/diag.h> #include <asm/asm-offsets.h> +#include <asm/os_info.h> typedef void (*relocate_kernel_t)(kimage_entry_t *, unsigned long); @@ -79,8 +80,8 @@ static void __do_machine_kdump(void *image) #ifdef CONFIG_CRASH_DUMP int (*start_kdump)(int) = (void *)((struct kimage *) image)->start; - __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA); setup_regs(); + __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA); start_kdump(1); #endif } @@ -114,8 +115,13 @@ static void crash_map_pages(int enable) size % KEXEC_CRASH_MEM_ALIGN); if (enable) vmem_add_mapping(crashk_res.start, size); - else + else { vmem_remove_mapping(crashk_res.start, size); + if (size) + os_info_crashkernel_add(crashk_res.start, size); + else + os_info_crashkernel_add(0, 0); + } } /* @@ -208,6 +214,7 @@ static void __machine_kexec(void *data) { struct kimage *image = data; + __arch_local_irq_stosm(0x04); /* enable DAT */ pfault_fini(); tracing_off(); debug_locks_off(); diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c index e8d6c214d498..95fa5ac6c4ce 100644 --- a/arch/s390/kernel/os_info.c +++ b/arch/s390/kernel/os_info.c @@ -60,7 +60,7 @@ void __init os_info_init(void) os_info.version_minor = OS_INFO_VERSION_MINOR; os_info.magic = OS_INFO_MAGIC; os_info.csum = os_info_csum(&os_info); - copy_to_absolute_zero(&S390_lowcore.os_info, &ptr, sizeof(ptr)); + memcpy_absolute(&S390_lowcore.os_info, &ptr, sizeof(ptr)); } #ifdef CONFIG_CRASH_DUMP @@ -138,7 +138,6 @@ static void os_info_old_init(void) goto fail_free; os_info_old_alloc(OS_INFO_VMCOREINFO, 1); os_info_old_alloc(OS_INFO_REIPL_BLOCK, 1); - os_info_old_alloc(OS_INFO_INIT_FN, PAGE_SIZE); pr_info("crashkernel: addr=0x%lx size=%lu\n", (unsigned long) os_info_old->crashkernel_addr, (unsigned long) os_info_old->crashkernel_size); diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index cb019f429e88..9871b1971ed7 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c @@ -225,7 +225,7 @@ static void cpumf_measurement_alert(struct ext_code ext_code, if (!(alert & CPU_MF_INT_CF_MASK)) return; - kstat_cpu(smp_processor_id()).irqs[EXTINT_CPM]++; + kstat_cpu(smp_processor_id()).irqs[EXTINT_CMC]++; cpuhw = &__get_cpu_var(cpu_hw_events); /* Measurement alerts are shared and might happen when the PMU diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 06264ae8ccd9..489d1d8d96b0 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -428,10 +428,12 @@ static void __init setup_lowcore(void) lc->restart_fn = (unsigned long) do_restart; lc->restart_data = 0; lc->restart_source = -1UL; - memcpy(&S390_lowcore.restart_stack, &lc->restart_stack, - 4*sizeof(unsigned long)); - copy_to_absolute_zero(&S390_lowcore.restart_psw, - &lc->restart_psw, sizeof(psw_t)); + + /* Setup absolute zero lowcore */ + memcpy_absolute(&S390_lowcore.restart_stack, &lc->restart_stack, + 4 * sizeof(unsigned long)); + memcpy_absolute(&S390_lowcore.restart_psw, &lc->restart_psw, + sizeof(lc->restart_psw)); set_prefix((u32)(unsigned long) lc); lowcore_ptr[0] = lc; @@ -598,7 +600,7 @@ static void __init setup_vmcoreinfo(void) #ifdef CONFIG_KEXEC unsigned long ptr = paddr_vmcoreinfo_note(); - copy_to_absolute_zero(&S390_lowcore.vmcore_info, &ptr, sizeof(ptr)); + memcpy_absolute(&S390_lowcore.vmcore_info, &ptr, sizeof(ptr)); #endif } diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 647ba9425893..15cca26ccb6c 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -297,26 +297,27 @@ static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data) static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *), void *data, unsigned long stack) { - struct _lowcore *lc = pcpu->lowcore; - unsigned short this_cpu; + struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices]; + struct { + unsigned long stack; + void *func; + void *data; + unsigned long source; + } restart = { stack, func, data, stap() }; __load_psw_mask(psw_kernel_bits); - this_cpu = stap(); - if (pcpu->address == this_cpu) + if (pcpu->address == restart.source) func(data); /* should not return */ /* Stop target cpu (if func returns this stops the current cpu). */ pcpu_sigp_retry(pcpu, sigp_stop, 0); /* Restart func on the target cpu and stop the current cpu. */ - lc->restart_stack = stack; - lc->restart_fn = (unsigned long) func; - lc->restart_data = (unsigned long) data; - lc->restart_source = (unsigned long) this_cpu; + memcpy_absolute(&lc->restart_stack, &restart, sizeof(restart)); asm volatile( "0: sigp 0,%0,6 # sigp restart to target cpu\n" " brc 2,0b # busy, try again\n" "1: sigp 0,%1,5 # sigp stop to current cpu\n" " brc 2,1b # busy, try again\n" - : : "d" (pcpu->address), "d" (this_cpu) : "0", "1", "cc"); + : : "d" (pcpu->address), "d" (restart.source) : "0", "1", "cc"); for (;;) ; } @@ -800,17 +801,6 @@ void __noreturn cpu_die(void) #endif /* CONFIG_HOTPLUG_CPU */ -static void smp_call_os_info_init_fn(void) -{ - int (*init_fn)(void); - unsigned long size; - - init_fn = os_info_old_entry(OS_INFO_INIT_FN, &size); - if (!init_fn) - return; - init_fn(); -} - void __init smp_prepare_cpus(unsigned int max_cpus) { /* request the 0x1201 emergency signal external interrupt */ @@ -819,7 +809,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) /* request the 0x1202 external call external interrupt */ if (register_external_interrupt(0x1202, do_ext_call_interrupt) != 0) panic("Couldn't request external interrupt 0x1202"); - smp_call_os_info_init_fn(); smp_detect_cpus(); } @@ -943,19 +932,6 @@ static struct attribute_group cpu_common_attr_group = { .attrs = cpu_common_attrs, }; -static ssize_t show_capability(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned int capability; - int rc; - - rc = get_cpu_capability(&capability); - if (rc) - return rc; - return sprintf(buf, "%u\n", capability); -} -static DEVICE_ATTR(capability, 0444, show_capability, NULL); - static ssize_t show_idle_count(struct device *dev, struct device_attribute *attr, char *buf) { @@ -993,7 +969,6 @@ static ssize_t show_idle_time(struct device *dev, static DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL); static struct attribute *cpu_online_attrs[] = { - &dev_attr_capability.attr, &dev_attr_idle_count.attr, &dev_attr_idle_time_us.attr, NULL, diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index 2a94b774695c..fa0eb238dac7 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c @@ -393,27 +393,6 @@ static __init int create_proc_service_level(void) subsys_initcall(create_proc_service_level); /* - * Bogomips calculation based on cpu capability. - */ -int get_cpu_capability(unsigned int *capability) -{ - struct sysinfo_1_2_2 *info; - int rc; - - info = (void *) get_zeroed_page(GFP_KERNEL); - if (!info) - return -ENOMEM; - rc = stsi(info, 1, 2, 2); - if (rc == -ENOSYS) - goto out; - rc = 0; - *capability = info->capability; -out: - free_page((unsigned long) info); - return rc; -} - -/* * CPU capability might have changed. Therefore recalculate loops_per_jiffy. */ void s390_adjust_jiffies(void) diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c index 60455f104ea3..58a75a8ae90c 100644 --- a/arch/s390/lib/uaccess_mvcos.c +++ b/arch/s390/lib/uaccess_mvcos.c @@ -14,7 +14,7 @@ #include <asm/futex.h> #include "uaccess.h" -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define AHI "ahi" #define ALR "alr" #define CLR "clr" diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c index bb1a7eed42ce..57e94298539b 100644 --- a/arch/s390/lib/uaccess_std.c +++ b/arch/s390/lib/uaccess_std.c @@ -15,7 +15,7 @@ #include <asm/futex.h> #include "uaccess.h" -#ifndef __s390x__ +#ifndef CONFIG_64BIT #define AHI "ahi" #define ALR "alr" #define CLR "clr" diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 795a0a9bb2eb..921fa541dc04 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -101,19 +101,27 @@ int memcpy_real(void *dest, void *src, size_t count) } /* - * Copy memory to absolute zero + * Copy memory in absolute mode (kernel to kernel) */ -void copy_to_absolute_zero(void *dest, void *src, size_t count) +void memcpy_absolute(void *dest, void *src, size_t count) { - unsigned long cr0; + unsigned long cr0, flags, prefix; - BUG_ON((unsigned long) dest + count >= sizeof(struct _lowcore)); - preempt_disable(); + flags = arch_local_irq_save(); __ctl_store(cr0, 0, 0); __ctl_clear_bit(0, 28); /* disable lowcore protection */ - memcpy_real(dest + store_prefix(), src, count); + prefix = store_prefix(); + if (prefix) { + local_mcck_disable(); + set_prefix(0); + memcpy(dest, src, count); + set_prefix(prefix); + local_mcck_enable(); + } else { + memcpy(dest, src, count); + } __ctl_load(cr0, 0, 0); - preempt_enable(); + arch_local_irq_restore(flags); } /* @@ -188,20 +196,6 @@ static int is_swapped(unsigned long addr) } /* - * Return swapped prefix or zero page address - */ -static unsigned long get_swapped(unsigned long addr) -{ - unsigned long prefix = store_prefix(); - - if (addr < sizeof(struct _lowcore)) - return addr + prefix; - if (addr >= prefix && addr < prefix + sizeof(struct _lowcore)) - return addr - prefix; - return addr; -} - -/* * Convert a physical pointer for /dev/mem access * * For swapped prefix pages a new buffer is returned that contains a copy of @@ -218,7 +212,7 @@ void *xlate_dev_mem_ptr(unsigned long addr) size = PAGE_SIZE - (addr & ~PAGE_MASK); bounce = (void *) __get_free_page(GFP_ATOMIC); if (bounce) - memcpy_real(bounce, (void *) get_swapped(addr), size); + memcpy_absolute(bounce, (void *) addr, size); } preempt_enable(); put_online_cpus(); diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index 4799383e2df9..71ae20df674e 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -109,7 +109,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro) pte = mk_pte_phys(address, __pgprot(ro ? _PAGE_RO : 0)); pm_dir = pmd_offset(pu_dir, address); -#ifdef __s390x__ +#ifdef CONFIG_64BIT if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) && (address + HPAGE_SIZE <= start + size) && (address >= HPAGE_SIZE)) { diff --git a/arch/s390/oprofile/hwsampler.c b/arch/s390/oprofile/hwsampler.c index c6646de07bf4..a4a89fa980d6 100644 --- a/arch/s390/oprofile/hwsampler.c +++ b/arch/s390/oprofile/hwsampler.c @@ -235,7 +235,7 @@ static void hws_ext_handler(struct ext_code ext_code, if (!(param32 & CPU_MF_INT_SF_MASK)) return; - kstat_cpu(smp_processor_id()).irqs[EXTINT_CPM]++; + kstat_cpu(smp_processor_id()).irqs[EXTINT_CMS]++; atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32); if (hws_wq) diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 83bd051754e1..e74ff1377626 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -41,7 +41,6 @@ config SPARC32 def_bool !64BIT select GENERIC_ATOMIC64 select CLZ_TAB - select ARCH_USES_GETTIMEOFFSET config SPARC64 def_bool 64BIT diff --git a/arch/sparc/include/asm/asi.h b/arch/sparc/include/asm/asi.h index cbb93e5141de..61ebe7411ceb 100644 --- a/arch/sparc/include/asm/asi.h +++ b/arch/sparc/include/asm/asi.h @@ -40,11 +40,7 @@ #define ASI_M_UNA01 0x01 /* Same here... */ #define ASI_M_MXCC 0x02 /* Access to TI VIKING MXCC registers */ #define ASI_M_FLUSH_PROBE 0x03 /* Reference MMU Flush/Probe; rw, ss */ -#ifndef CONFIG_SPARC_LEON #define ASI_M_MMUREGS 0x04 /* MMU Registers; rw, ss */ -#else -#define ASI_M_MMUREGS 0x19 -#endif /* CONFIG_SPARC_LEON */ #define ASI_M_TLBDIAG 0x05 /* MMU TLB only Diagnostics */ #define ASI_M_DIAGS 0x06 /* Reference MMU Diagnostics */ #define ASI_M_IODIAG 0x07 /* MMU I/O TLB only Diagnostics */ diff --git a/arch/sparc/include/asm/asmmacro.h b/arch/sparc/include/asm/asmmacro.h index 02a172fb193a..a0e28ef02558 100644 --- a/arch/sparc/include/asm/asmmacro.h +++ b/arch/sparc/include/asm/asmmacro.h @@ -20,4 +20,26 @@ /* All traps low-level code here must end with this macro. */ #define RESTORE_ALL b ret_trap_entry; clr %l6; +/* Support for run-time patching of single instructions. + * This is used to handle the differences in the ASI for + * MMUREGS for LEON and SUN. + * + * Sample: + * LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %o0 + * SUN_PI_(lda [%g0] ASI_M_MMUREGS, %o0 + * PI == Patch Instruction + * + * For LEON we will use the first variant, + * and for all other we will use the SUN variant. + * The order is important. + */ +#define LEON_PI(...) \ +662: __VA_ARGS__ + +#define SUN_PI_(...) \ + .section .leon_1insn_patch, "ax"; \ + .word 662b; \ + __VA_ARGS__; \ + .previous + #endif /* !(_SPARC_ASMMACRO_H) */ diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index 48a7c65731d2..8493fd3c7ba5 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h @@ -12,13 +12,18 @@ extern int dma_supported(struct device *dev, u64 mask); #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -extern struct dma_map_ops *dma_ops, pci32_dma_ops; +extern struct dma_map_ops *dma_ops; +extern struct dma_map_ops *leon_dma_ops; +extern struct dma_map_ops pci32_dma_ops; + extern struct bus_type pci_bus_type; static inline struct dma_map_ops *get_dma_ops(struct device *dev) { #if defined(CONFIG_SPARC32) && defined(CONFIG_PCI) - if (dev->bus == &pci_bus_type) + if (sparc_cpu_model == sparc_leon) + return leon_dma_ops; + else if (dev->bus == &pci_bus_type) return &pci32_dma_ops; #endif return dma_ops; diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h index 07659124c140..3375c6293893 100644 --- a/arch/sparc/include/asm/leon.h +++ b/arch/sparc/include/asm/leon.h @@ -8,8 +8,6 @@ #ifndef LEON_H_INCLUDE #define LEON_H_INCLUDE -#ifdef CONFIG_SPARC_LEON - /* mmu register access, ASI_LEON_MMUREGS */ #define LEON_CNR_CTRL 0x000 #define LEON_CNR_CTXP 0x100 @@ -62,15 +60,6 @@ #ifndef __ASSEMBLY__ -/* do a virtual address read without cache */ -static inline unsigned long leon_readnobuffer_reg(unsigned long paddr) -{ - unsigned long retval; - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r"(retval) : "r"(paddr), "i"(ASI_LEON_NOCACHE)); - return retval; -} - /* do a physical address bypass write, i.e. for 0x80000000 */ static inline void leon_store_reg(unsigned long paddr, unsigned long value) { @@ -87,47 +76,16 @@ static inline unsigned long leon_load_reg(unsigned long paddr) return retval; } -static inline void leon_srmmu_disabletlb(void) -{ - unsigned int retval; - __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0), - "i"(ASI_LEON_MMUREGS)); - retval |= LEON_CNR_CTRL_TLBDIS; - __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0), - "i"(ASI_LEON_MMUREGS) : "memory"); -} - -static inline void leon_srmmu_enabletlb(void) -{ - unsigned int retval; - __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0), - "i"(ASI_LEON_MMUREGS)); - retval = retval & ~LEON_CNR_CTRL_TLBDIS; - __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0), - "i"(ASI_LEON_MMUREGS) : "memory"); -} - /* macro access for leon_load_reg() and leon_store_reg() */ #define LEON3_BYPASS_LOAD_PA(x) (leon_load_reg((unsigned long)(x))) #define LEON3_BYPASS_STORE_PA(x, v) (leon_store_reg((unsigned long)(x), (unsigned long)(v))) -#define LEON3_BYPASS_ANDIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) & v) -#define LEON3_BYPASS_ORIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) | v) #define LEON_BYPASS_LOAD_PA(x) leon_load_reg((unsigned long)(x)) #define LEON_BYPASS_STORE_PA(x, v) leon_store_reg((unsigned long)(x), (unsigned long)(v)) -#define LEON_REGLOAD_PA(x) leon_load_reg((unsigned long)(x)+LEON_PREGS) -#define LEON_REGSTORE_PA(x, v) leon_store_reg((unsigned long)(x)+LEON_PREGS, (unsigned long)(v)) -#define LEON_REGSTORE_OR_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) | (unsigned long)(v)) -#define LEON_REGSTORE_AND_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) & (unsigned long)(v)) - -/* macro access for leon_readnobuffer_reg() */ -#define LEON_BYPASSCACHE_LOAD_VA(x) leon_readnobuffer_reg((unsigned long)(x)) extern void leon_init(void); extern void leon_switch_mm(void); extern void leon_init_IRQ(void); -extern unsigned long last_valid_pfn; - static inline unsigned long sparc_leon3_get_dcachecfg(void) { unsigned int retval; @@ -230,9 +188,6 @@ static inline int sparc_leon3_cpuid(void) #error cannot determine LEON_PAGE_SIZE_LEON #endif -#define PAGE_MIN_SHIFT (12) -#define PAGE_MIN_SIZE (1UL << PAGE_MIN_SHIFT) - #define LEON3_XCCR_SETS_MASK 0x07000000UL #define LEON3_XCCR_SSIZE_MASK 0x00f00000UL @@ -242,7 +197,7 @@ static inline int sparc_leon3_cpuid(void) #ifndef __ASSEMBLY__ struct vm_area_struct; -extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr); +extern unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr); extern void leon_flush_icache_all(void); extern void leon_flush_dcache_all(void); extern void leon_flush_cache_all(void); @@ -258,15 +213,7 @@ struct leon3_cacheregs { unsigned long dccr; /* 0x0c - Data Cache Configuration Register */ }; -/* struct that hold LEON2 cache configuration register - * & configuration register - */ -struct leon2_cacheregs { - unsigned long ccr, cfg; -}; - -#ifdef __KERNEL__ - +#include <linux/irq.h> #include <linux/interrupt.h> struct device_node; @@ -292,24 +239,15 @@ extern void leon_smp_done(void); extern void leon_boot_cpus(void); extern int leon_boot_one_cpu(int i, struct task_struct *); void leon_init_smp(void); -extern void cpu_idle(void); -extern void init_IRQ(void); -extern void cpu_panic(void); -extern int __leon_processor_id(void); void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu); extern irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused); -extern unsigned int real_irq_entry[]; extern unsigned int smpleon_ipi[]; -extern unsigned int patchme_maybe_smp_msg[]; -extern unsigned int t_nmi[], linux_trap_ipi15_leon[]; -extern unsigned int linux_trap_ipi15_sun4m[]; +extern unsigned int linux_trap_ipi15_leon[]; extern int leon_ipi_irq; #endif /* CONFIG_SMP */ -#endif /* __KERNEL__ */ - #endif /* __ASSEMBLY__ */ /* macros used in leon_mm.c */ @@ -317,18 +255,4 @@ extern int leon_ipi_irq; #define _pfn_valid(pfn) ((pfn < last_valid_pfn) && (pfn >= PFN(phys_base))) #define _SRMMU_PTE_PMASK_LEON 0xffffffff -#else /* defined(CONFIG_SPARC_LEON) */ - -/* nop definitions for !LEON case */ -#define leon_init() do {} while (0) -#define leon_switch_mm() do {} while (0) -#define leon_init_IRQ() do {} while (0) -#define init_leon() do {} while (0) -#define leon_smp_done() do {} while (0) -#define leon_boot_cpus() do {} while (0) -#define leon_boot_one_cpu(i, t) 1 -#define leon_init_smp() do {} while (0) - -#endif /* !defined(CONFIG_SPARC_LEON) */ - #endif diff --git a/arch/sparc/include/asm/leon_amba.h b/arch/sparc/include/asm/leon_amba.h index e50f326e71bd..f3034eddf468 100644 --- a/arch/sparc/include/asm/leon_amba.h +++ b/arch/sparc/include/asm/leon_amba.h @@ -87,8 +87,6 @@ struct amba_prom_registers { #define LEON3_GPTIMER_CONFIG_NRTIMERS(c) ((c)->config & 0x7) #define LEON3_GPTIMER_CTRL_ISPENDING(r) (((r)&LEON3_GPTIMER_CTRL_PENDING) ? 1 : 0) -#ifdef CONFIG_SPARC_LEON - #ifndef __ASSEMBLY__ struct leon3_irqctrl_regs_map { @@ -264,6 +262,4 @@ extern unsigned int sparc_leon_eirq; #define amba_device(x) (((x) >> 12) & 0xfff) -#endif /* !defined(CONFIG_SPARC_LEON) */ - #endif diff --git a/arch/sparc/include/asm/pgtsrmmu.h b/arch/sparc/include/asm/pgtsrmmu.h index cb828703a63a..79da17866fa8 100644 --- a/arch/sparc/include/asm/pgtsrmmu.h +++ b/arch/sparc/include/asm/pgtsrmmu.h @@ -139,6 +139,7 @@ restore %g0, %g0, %g0; #ifndef __ASSEMBLY__ +extern unsigned long last_valid_pfn; /* This makes sense. Honest it does - Anton */ /* XXX Yes but it's ugly as sin. FIXME. -KMW */ @@ -148,67 +149,13 @@ extern void *srmmu_nocache_pool; #define __nocache_fix(VADDR) __va(__nocache_pa(VADDR)) /* Accessing the MMU control register. */ -static inline unsigned int srmmu_get_mmureg(void) -{ - unsigned int retval; - __asm__ __volatile__("lda [%%g0] %1, %0\n\t" : - "=r" (retval) : - "i" (ASI_M_MMUREGS)); - return retval; -} - -static inline void srmmu_set_mmureg(unsigned long regval) -{ - __asm__ __volatile__("sta %0, [%%g0] %1\n\t" : : - "r" (regval), "i" (ASI_M_MMUREGS) : "memory"); - -} - -static inline void srmmu_set_ctable_ptr(unsigned long paddr) -{ - paddr = ((paddr >> 4) & SRMMU_CTX_PMASK); - __asm__ __volatile__("sta %0, [%1] %2\n\t" : : - "r" (paddr), "r" (SRMMU_CTXTBL_PTR), - "i" (ASI_M_MMUREGS) : - "memory"); -} - -static inline void srmmu_set_context(int context) -{ - __asm__ __volatile__("sta %0, [%1] %2\n\t" : : - "r" (context), "r" (SRMMU_CTX_REG), - "i" (ASI_M_MMUREGS) : "memory"); -} - -static inline int srmmu_get_context(void) -{ - register int retval; - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (retval) : - "r" (SRMMU_CTX_REG), - "i" (ASI_M_MMUREGS)); - return retval; -} - -static inline unsigned int srmmu_get_fstatus(void) -{ - unsigned int retval; - - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (retval) : - "r" (SRMMU_FAULT_STATUS), "i" (ASI_M_MMUREGS)); - return retval; -} - -static inline unsigned int srmmu_get_faddr(void) -{ - unsigned int retval; - - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (retval) : - "r" (SRMMU_FAULT_ADDR), "i" (ASI_M_MMUREGS)); - return retval; -} +unsigned int srmmu_get_mmureg(void); +void srmmu_set_mmureg(unsigned long regval); +void srmmu_set_ctable_ptr(unsigned long paddr); +void srmmu_set_context(int context); +int srmmu_get_context(void); +unsigned int srmmu_get_fstatus(void); +unsigned int srmmu_get_faddr(void); /* This is guaranteed on all SRMMU's. */ static inline void srmmu_flush_whole_tlb(void) @@ -219,23 +166,6 @@ static inline void srmmu_flush_whole_tlb(void) } -/* These flush types are not available on all chips... */ -#ifndef CONFIG_SPARC_LEON -static inline unsigned long srmmu_hwprobe(unsigned long vaddr) -{ - unsigned long retval; - - vaddr &= PAGE_MASK; - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (retval) : - "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE)); - - return retval; -} -#else -#define srmmu_hwprobe(addr) srmmu_swprobe(addr, 0) -#endif - static inline int srmmu_get_pte (unsigned long addr) { diff --git a/arch/sparc/include/asm/psr.h b/arch/sparc/include/asm/psr.h index b8c0e5f0a66b..cee7ed9c927d 100644 --- a/arch/sparc/include/asm/psr.h +++ b/arch/sparc/include/asm/psr.h @@ -35,6 +35,14 @@ #define PSR_VERS 0x0f000000 /* cpu-version field */ #define PSR_IMPL 0xf0000000 /* cpu-implementation field */ +#define PSR_VERS_SHIFT 24 +#define PSR_IMPL_SHIFT 28 +#define PSR_VERS_SHIFTED_MASK 0xf +#define PSR_IMPL_SHIFTED_MASK 0xf + +#define PSR_IMPL_TI 0x4 +#define PSR_IMPL_LEON 0xf + #ifdef __KERNEL__ #ifndef __ASSEMBLY__ diff --git a/arch/sparc/include/asm/sections.h b/arch/sparc/include/asm/sections.h index 0b0553bbd8a0..f300d1a9b2b6 100644 --- a/arch/sparc/include/asm/sections.h +++ b/arch/sparc/include/asm/sections.h @@ -7,4 +7,7 @@ /* sparc entry point */ extern char _start[]; +extern char __leon_1insn_patch[]; +extern char __leon_1insn_patch_end[]; + #endif diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 72308f9b0096..6cf591b7e1c6 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -51,8 +51,8 @@ obj-y += of_device_common.o obj-y += of_device_$(BITS).o obj-$(CONFIG_SPARC64) += prom_irqtrans.o -obj-$(CONFIG_SPARC_LEON)+= leon_kernel.o -obj-$(CONFIG_SPARC_LEON)+= leon_pmc.o +obj-$(CONFIG_SPARC32) += leon_kernel.o +obj-$(CONFIG_SPARC32) += leon_pmc.o obj-$(CONFIG_SPARC64) += reboot.o obj-$(CONFIG_SPARC64) += sysfs.o diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index 2d1819641769..a6c94a2bf9d4 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c @@ -121,7 +121,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = { FPU(-1, NULL) } },{ - 4, + PSR_IMPL_TI, .cpu_info = { CPU(0, "Texas Instruments, Inc. - SuperSparc-(II)"), /* SparcClassic -- borned STP1010TAB-50*/ @@ -191,7 +191,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = { FPU(-1, NULL) } },{ - 0xF, /* Aeroflex Gaisler */ + PSR_IMPL_LEON, /* Aeroflex Gaisler */ .cpu_info = { CPU(3, "LEON"), CPU(-1, NULL) @@ -440,16 +440,16 @@ static int __init cpu_type_probe(void) int psr_impl, psr_vers, fpu_vers; int psr; - psr_impl = ((get_psr() >> 28) & 0xf); - psr_vers = ((get_psr() >> 24) & 0xf); + psr_impl = ((get_psr() >> PSR_IMPL_SHIFT) & PSR_IMPL_SHIFTED_MASK); + psr_vers = ((get_psr() >> PSR_VERS_SHIFT) & PSR_VERS_SHIFTED_MASK); psr = get_psr(); put_psr(psr | PSR_EF); -#ifdef CONFIG_SPARC_LEON - fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7; -#else - fpu_vers = ((get_fsr() >> 17) & 0x7); -#endif + + if (psr_impl == PSR_IMPL_LEON) + fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7; + else + fpu_vers = ((get_fsr() >> 17) & 0x7); put_psr(psr); diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 2dbe1806e530..dcaa1cf0de40 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -393,7 +393,6 @@ linux_trap_ipi15_sun4d: /* FIXME */ 1: b,a 1b -#ifdef CONFIG_SPARC_LEON .globl smpleon_ipi .extern leon_ipi_interrupt /* SMP per-cpu IPI interrupts are handled specially. */ @@ -424,8 +423,6 @@ linux_trap_ipi15_leon: b ret_trap_lockless_ipi clr %l6 -#endif /* CONFIG_SPARC_LEON */ - #endif /* CONFIG_SMP */ /* This routine handles illegal instructions and privileged @@ -770,8 +767,11 @@ srmmu_fault: mov 0x400, %l5 mov 0x300, %l4 - lda [%l5] ASI_M_MMUREGS, %l6 ! read sfar first - lda [%l4] ASI_M_MMUREGS, %l5 ! read sfsr last +LEON_PI(lda [%l5] ASI_LEON_MMUREGS, %l6) ! read sfar first +SUN_PI_(lda [%l5] ASI_M_MMUREGS, %l6) ! read sfar first + +LEON_PI(lda [%l4] ASI_LEON_MMUREGS, %l5) ! read sfsr last +SUN_PI_(lda [%l4] ASI_M_MMUREGS, %l5) ! read sfsr last andn %l6, 0xfff, %l6 srl %l5, 6, %l5 ! and encode all info into l7 diff --git a/arch/sparc/kernel/etrap_32.S b/arch/sparc/kernel/etrap_32.S index 84b5f0d2afde..e3e80d65e39a 100644 --- a/arch/sparc/kernel/etrap_32.S +++ b/arch/sparc/kernel/etrap_32.S @@ -234,7 +234,8 @@ tsetup_srmmu_stackchk: cmp %glob_tmp, %sp bleu,a 1f - lda [%g0] ASI_M_MMUREGS, %glob_tmp ! read MMU control +LEON_PI( lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control +SUN_PI_( lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control trap_setup_user_stack_is_bolixed: /* From user/kernel into invalid window w/bad user @@ -249,18 +250,25 @@ trap_setup_user_stack_is_bolixed: 1: /* Clear the fault status and turn on the no_fault bit. */ or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit - sta %glob_tmp, [%g0] ASI_M_MMUREGS ! set it +LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it +SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it /* Dump the registers and cross fingers. */ STORE_WINDOW(sp) /* Clear the no_fault bit and check the status. */ andn %glob_tmp, 0x2, %glob_tmp - sta %glob_tmp, [%g0] ASI_M_MMUREGS +LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) +SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) + mov AC_M_SFAR, %glob_tmp - lda [%glob_tmp] ASI_M_MMUREGS, %g0 +LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0) +SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0) + mov AC_M_SFSR, %glob_tmp - lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp ! save away status of winstore +LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp)! save away status of winstore +SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp) ! save away status of winstore + andcc %glob_tmp, 0x2, %g0 ! did we fault? bne trap_setup_user_stack_is_bolixed ! failure nop diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S index a0f5c20e4b9c..afeb1d770303 100644 --- a/arch/sparc/kernel/head_32.S +++ b/arch/sparc/kernel/head_32.S @@ -30,10 +30,6 @@ * the cpu-type */ .align 4 -cputyp: - .word 1 - - .align 4 .globl cputypval cputypval: .asciz "sun4m" @@ -46,8 +42,8 @@ cputypvar: .align 4 -sun4c_notsup: - .asciz "Sparc-Linux sun4/sun4c support does no longer exist.\n\n" +notsup: + .asciz "Sparc-Linux sun4/sun4c or MMU-less not supported\n\n" .align 4 sun4e_notsup: @@ -123,7 +119,7 @@ current_pc: tst %o0 be no_sun4u_here mov %g4, %o7 /* Previous %o7. */ - + mov %o0, %l0 ! stash away romvec mov %o0, %g7 ! put it here too mov %o1, %l1 ! stash away debug_vec too @@ -132,7 +128,7 @@ current_pc: set current_pc, %g5 cmp %g3, %g5 be already_mapped - nop + nop /* %l6 will hold the offset we have to subtract * from absolute symbols in order to access areas @@ -192,9 +188,9 @@ copy_prom_done: bne not_a_sun4 nop -halt_sun4_or_sun4c: +halt_notsup: ld [%g7 + 0x68], %o1 - set sun4c_notsup, %o0 + set notsup, %o0 sub %o0, %l6, %o0 call %o1 nop @@ -202,18 +198,31 @@ halt_sun4_or_sun4c: nop not_a_sun4: + /* It looks like this is a machine we support. + * Now find out what MMU we are dealing with + * LEON - identified by the psr.impl field + * Viking - identified by the psr.impl field + * In all other cases a sun4m srmmu. + * We check that the MMU is enabled in all cases. + */ + + /* Check if this is a LEON CPU */ + rd %psr, %g3 + srl %g3, PSR_IMPL_SHIFT, %g3 + and %g3, PSR_IMPL_SHIFTED_MASK, %g3 + cmp %g3, PSR_IMPL_LEON + be leon_remap /* It is a LEON - jump */ + nop + + /* Sanity-check, is MMU enabled */ lda [%g0] ASI_M_MMUREGS, %g1 andcc %g1, 1, %g0 - be halt_sun4_or_sun4c + be halt_notsup nop -srmmu_remap: - /* First, check for a viking (TI) module. */ - set 0x40000000, %g2 - rd %psr, %g3 - and %g2, %g3, %g3 - subcc %g3, 0x0, %g0 - bz srmmu_nviking + /* Check for a viking (TI) module. */ + cmp %g3, PSR_IMPL_TI + bne srmmu_not_viking nop /* Figure out what kind of viking we are on. @@ -228,14 +237,14 @@ srmmu_remap: lda [%g0] ASI_M_MMUREGS, %g3 ! peek in the control reg and %g2, %g3, %g3 subcc %g3, 0x0, %g0 - bnz srmmu_nviking ! is in mbus mode + bnz srmmu_not_viking ! is in mbus mode nop - + rd %psr, %g3 ! DO NOT TOUCH %g3 andn %g3, PSR_ET, %g2 wr %g2, 0x0, %psr WRITE_PAUSE - + /* Get context table pointer, then convert to * a physical address, which is 36 bits. */ @@ -258,12 +267,12 @@ srmmu_remap: lda [%g4] ASI_M_BYPASS, %o1 ! This is a level 1 ptr srl %o1, 0x4, %o1 ! Clear low 4 bits sll %o1, 0x8, %o1 ! Make physical - + /* Ok, pull in the PTD. */ lda [%o1] ASI_M_BYPASS, %o2 ! This is the 0x0 16MB pgd /* Calculate to KERNBASE entry. */ - add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3 + add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3 /* Poke the entry into the calculated address. */ sta %o2, [%o3] ASI_M_BYPASS @@ -293,12 +302,12 @@ srmmu_remap: b go_to_highmem nop +srmmu_not_viking: /* This works on viking's in Mbus mode and all * other MBUS modules. It is virtually the same as * the above madness sans turning traps off and flipping * the AC bit. */ -srmmu_nviking: set AC_M_CTPR, %g1 lda [%g1] ASI_M_MMUREGS, %g1 ! get ctx table ptr sll %g1, 0x4, %g1 ! make physical addr @@ -313,6 +322,29 @@ srmmu_nviking: nop ! wheee.... +leon_remap: + /* Sanity-check, is MMU enabled */ + lda [%g0] ASI_LEON_MMUREGS, %g1 + andcc %g1, 1, %g0 + be halt_notsup + nop + + /* Same code as in the srmmu_not_viking case, + * with the LEON ASI for mmuregs + */ + set AC_M_CTPR, %g1 + lda [%g1] ASI_LEON_MMUREGS, %g1 ! get ctx table ptr + sll %g1, 0x4, %g1 ! make physical addr + lda [%g1] ASI_M_BYPASS, %g1 ! ptr to level 1 pg_table + srl %g1, 0x4, %g1 + sll %g1, 0x8, %g1 ! make phys addr for l1 tbl + + lda [%g1] ASI_M_BYPASS, %g2 ! get level1 entry for 0x0 + add %g1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %g3 + sta %g2, [%g3] ASI_M_BYPASS ! place at KERNBASE entry + b go_to_highmem + nop ! wheee.... + /* Now do a non-relative jump so that PC is in high-memory */ go_to_highmem: set execute_in_high_mem, %g1 @@ -336,8 +368,9 @@ execute_in_high_mem: sethi %hi(linux_dbvec), %g1 st %o1, [%g1 + %lo(linux_dbvec)] -/* Get the machine type via the mysterious romvec node operations. */ - + /* Get the machine type via the romvec + * getprops node operation + */ add %g7, 0x1c, %l1 ld [%l1], %l0 ld [%l0], %l0 @@ -356,9 +389,42 @@ execute_in_high_mem: ! to a buf where above string ! will get stored by the prom. -#ifdef CONFIG_SPARC_LEON - /* no cpu-type check is needed, it is a SPARC-LEON */ + /* Check value of "compatible" property. + * "value" => "model" + * leon => sparc_leon + * sun4m => sun4m + * sun4s => sun4m + * sun4d => sun4d + * sun4e => "no_sun4e_here" + * '*' => "no_sun4u_here" + * Check single letters only + */ + + set cputypval, %o2 + /* If cputypval[0] == 'l' (lower case letter L) this is leon */ + ldub [%o2], %l1 + cmp %l1, 'l' + be leon_init + nop + + /* Check cputypval[4] to find the sun model */ + ldub [%o2 + 0x4], %l1 + + cmp %l1, 'm' + be sun4m_init + cmp %l1, 's' + be sun4m_init + cmp %l1, 'd' + be sun4d_init + cmp %l1, 'e' + be no_sun4e_here ! Could be a sun4e. + nop + b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :)) + nop + +leon_init: + /* LEON CPU - set boot_cpu_id */ sethi %hi(boot_cpu_id), %g2 ! boot-cpu index #ifdef CONFIG_SMP @@ -376,26 +442,6 @@ execute_in_high_mem: ba continue_boot nop -#endif - -/* Check to cputype. We may be booted on a sun4u (64 bit box), - * and sun4d needs special treatment. - */ - - set cputypval, %o2 - ldub [%o2 + 0x4], %l1 - - cmp %l1, 'm' - be sun4m_init - cmp %l1, 's' - be sun4m_init - cmp %l1, 'd' - be sun4d_init - cmp %l1, 'e' - be no_sun4e_here ! Could be a sun4e. - nop - b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :)) - nop /* CPUID in bootbus can be found at PA 0xff0140000 */ #define SUN4D_BOOTBUS_CPUID 0xf0140000 @@ -431,9 +477,9 @@ sun4m_init: /* This sucks, apparently this makes Vikings call prom panic, will fix later */ 2: rd %psr, %o1 - srl %o1, 28, %o1 ! Get a type of the CPU + srl %o1, PSR_IMPL_SHIFT, %o1 ! Get a type of the CPU - subcc %o1, 4, %g0 ! TI: Viking or MicroSPARC + subcc %o1, PSR_IMPL_TI, %g0 ! TI: Viking or MicroSPARC be continue_boot nop @@ -459,10 +505,6 @@ continue_boot: /* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's * show-time! */ - - sethi %hi(cputyp), %o0 - st %g4, [%o0 + %lo(cputyp)] - /* Turn on Supervisor, EnableFloating, and all the PIL bits. * Also puts us in register window zero with traps off. */ @@ -480,7 +522,7 @@ continue_boot: set __bss_start , %o0 ! First address of BSS set _end , %o1 ! Last address of BSS add %o0, 0x1, %o0 -1: +1: stb %g0, [%o0] subcc %o0, %o1, %g0 bl 1b @@ -546,7 +588,7 @@ continue_boot: set dest, %g2; \ ld [%g5], %g4; \ st %g4, [%g2]; - + /* Patch for window spills... */ PATCH_INSN(spnwin_patch1_7win, spnwin_patch1) PATCH_INSN(spnwin_patch2_7win, spnwin_patch2) @@ -597,7 +639,7 @@ continue_boot: st %g4, [%g5 + 0x18] st %g4, [%g5 + 0x1c] -2: +2: sethi %hi(nwindows), %g4 st %g3, [%g4 + %lo(nwindows)] ! store final value sub %g3, 0x1, %g3 @@ -617,18 +659,12 @@ continue_boot: wr %g3, PSR_ET, %psr WRITE_PAUSE - /* First we call prom_init() to set up PROMLIB, then - * off to start_kernel(). - */ - + /* Call sparc32_start_kernel(struct linux_romvec *rp) */ sethi %hi(prom_vector_p), %g5 ld [%g5 + %lo(prom_vector_p)], %o0 - call prom_init + call sparc32_start_kernel nop - call start_kernel - nop - /* We should not get here. */ call halt_me nop @@ -659,7 +695,7 @@ sun4u_5: .asciz "write" .align 4 sun4u_6: - .asciz "\n\rOn sun4u you have to use UltraLinux (64bit) kernel\n\rand not a 32bit sun4[cdem] version\n\r\n\r" + .asciz "\n\rOn sun4u you have to use sparc64 kernel\n\rand not a sparc32 version\n\r\n\r" sun4u_6e: .align 4 sun4u_7: diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index a2846f5e32d8..0f094db918c7 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -55,17 +55,13 @@ const struct sparc32_dma_ops *sparc32_dma_ops; /* This function must make sure that caches and memory are coherent after DMA * On LEON systems without cache snooping it flushes the entire D-CACHE. */ -#ifndef CONFIG_SPARC_LEON static inline void dma_make_coherent(unsigned long pa, unsigned long len) { + if (sparc_cpu_model == sparc_leon) { + if (!sparc_leon3_snooping_enabled()) + leon_flush_dcache_all(); + } } -#else -static inline void dma_make_coherent(unsigned long pa, unsigned long len) -{ - if (!sparc_leon3_snooping_enabled()) - leon_flush_dcache_all(); -} -#endif static void __iomem *_sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz); static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys, @@ -427,9 +423,6 @@ arch_initcall(sparc_register_ioport); #endif /* CONFIG_SBUS */ -/* LEON reuses PCI DMA ops */ -#if defined(CONFIG_PCI) || defined(CONFIG_SPARC_LEON) - /* Allocate and map kernel buffer using consistent mode DMA for a device. * hwdev should be valid struct pci_dev pointer for PCI devices. */ @@ -657,14 +650,11 @@ struct dma_map_ops pci32_dma_ops = { }; EXPORT_SYMBOL(pci32_dma_ops); -#endif /* CONFIG_PCI || CONFIG_SPARC_LEON */ +/* leon re-uses pci32_dma_ops */ +struct dma_map_ops *leon_dma_ops = &pci32_dma_ops; +EXPORT_SYMBOL(leon_dma_ops); -#ifdef CONFIG_SPARC_LEON -struct dma_map_ops *dma_ops = &pci32_dma_ops; -#elif defined(CONFIG_SBUS) struct dma_map_ops *dma_ops = &sbus_dma_ops; -#endif - EXPORT_SYMBOL(dma_ops); diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index ae04914f7774..c145f6fd123b 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c @@ -241,9 +241,6 @@ int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler) unsigned int cpu_irq; int err; -#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON - struct tt_entry *trap_table; -#endif err = request_irq(irq, irq_handler, 0, "floppy", NULL); if (err) @@ -264,13 +261,18 @@ int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler) table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP; INSTANTIATE(sparc_ttable) -#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON - trap_table = &trapbase_cpu1; - INSTANTIATE(trap_table) - trap_table = &trapbase_cpu2; - INSTANTIATE(trap_table) - trap_table = &trapbase_cpu3; - INSTANTIATE(trap_table) + +#if defined CONFIG_SMP + if (sparc_cpu_model != sparc_leon) { + struct tt_entry *trap_table; + + trap_table = &trapbase_cpu1; + INSTANTIATE(trap_table) + trap_table = &trapbase_cpu2; + INSTANTIATE(trap_table) + trap_table = &trapbase_cpu3; + INSTANTIATE(trap_table) + } #endif #undef INSTANTIATE /* diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index a86372d34587..291bb5de9ce0 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -26,6 +26,9 @@ static inline unsigned long kimage_addr_to_ra(const char *p) #endif #ifdef CONFIG_SPARC32 +/* setup_32.c */ +void sparc32_start_kernel(struct linux_romvec *rp); + /* cpu.c */ extern void cpu_probe(void); diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 77c1b916e4dd..e34e2c40c060 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -23,6 +23,7 @@ #include <asm/smp.h> #include <asm/setup.h> +#include "kernel.h" #include "prom.h" #include "irq.h" diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c index 519ca923f59f..4e174321097d 100644 --- a/arch/sparc/kernel/leon_pmc.c +++ b/arch/sparc/kernel/leon_pmc.c @@ -7,6 +7,7 @@ #include <linux/pm.h> #include <asm/leon_amba.h> +#include <asm/cpu_type.h> #include <asm/leon.h> /* List of Systems that need fixup instructions around power-down instruction */ @@ -65,13 +66,15 @@ void pmc_leon_idle(void) /* Install LEON Power Down function */ static int __init leon_pmc_install(void) { - /* Assign power management IDLE handler */ - if (pmc_leon_need_fixup()) - pm_idle = pmc_leon_idle_fixup; - else - pm_idle = pmc_leon_idle; + if (sparc_cpu_model == sparc_leon) { + /* Assign power management IDLE handler */ + if (pmc_leon_need_fixup()) + pm_idle = pmc_leon_idle_fixup; + else + pm_idle = pmc_leon_idle; - printk(KERN_INFO "leon: power management initialized\n"); + printk(KERN_INFO "leon: power management initialized\n"); + } return 0; } diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index a469090faf9f..0f3fb6d9c8ef 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -48,15 +48,13 @@ #include "kernel.h" -#ifdef CONFIG_SPARC_LEON - #include "irq.h" extern ctxd_t *srmmu_ctx_table_phys; static int smp_processors_ready; extern volatile unsigned long cpu_callin_map[NR_CPUS]; extern cpumask_t smp_commenced_mask; -void __init leon_configure_cache_smp(void); +void __cpuinit leon_configure_cache_smp(void); static void leon_ipi_init(void); /* IRQ number of LEON IPIs */ @@ -123,7 +121,7 @@ void __cpuinit leon_callin(void) extern struct linux_prom_registers smp_penguin_ctable; -void __init leon_configure_cache_smp(void) +void __cpuinit leon_configure_cache_smp(void) { unsigned long cfg = sparc_leon3_get_dcachecfg(); int me = smp_processor_id(); @@ -507,5 +505,3 @@ void __init leon_init_smp(void) sparc32_ipi_ops = &leon_ipi_ops; } - -#endif /* CONFIG_SPARC_LEON */ diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index fe6787cc62fc..cb36e82dcd5d 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c @@ -65,50 +65,25 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *); struct task_struct *last_task_used_math = NULL; struct thread_info *current_set[NR_CPUS]; -#ifndef CONFIG_SMP - /* * the idle loop on a Sparc... ;) */ void cpu_idle(void) { - /* endless idle loop with no priority at all */ - for (;;) { - if (pm_idle) { - while (!need_resched()) - (*pm_idle)(); - } else { - while (!need_resched()) - cpu_relax(); - } - schedule_preempt_disabled(); - } -} - -#else + set_thread_flag(TIF_POLLING_NRFLAG); -/* This is being executed in task 0 'user space'. */ -void cpu_idle(void) -{ - set_thread_flag(TIF_POLLING_NRFLAG); /* endless idle loop with no priority at all */ - while(1) { -#ifdef CONFIG_SPARC_LEON - if (pm_idle) { - while (!need_resched()) + for (;;) { + while (!need_resched()) { + if (pm_idle) (*pm_idle)(); - } else -#endif - { - while (!need_resched()) + else cpu_relax(); } schedule_preempt_disabled(); } } -#endif - /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ void machine_halt(void) { diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c index 741df916c124..1303021748c8 100644 --- a/arch/sparc/kernel/prom_common.c +++ b/arch/sparc/kernel/prom_common.c @@ -23,7 +23,6 @@ #include <linux/of_pdt.h> #include <asm/prom.h> #include <asm/oplib.h> -#include <asm/leon.h> #include "prom.h" diff --git a/arch/sparc/kernel/rtrap_32.S b/arch/sparc/kernel/rtrap_32.S index 7abc24e2bf1a..6c34de0c2abd 100644 --- a/arch/sparc/kernel/rtrap_32.S +++ b/arch/sparc/kernel/rtrap_32.S @@ -231,11 +231,14 @@ srmmu_rett_stackchk: cmp %g1, %fp bleu ret_trap_user_stack_is_bolixed mov AC_M_SFSR, %g1 - lda [%g1] ASI_M_MMUREGS, %g0 +LEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g0) +SUN_PI_(lda [%g1] ASI_M_MMUREGS, %g0) - lda [%g0] ASI_M_MMUREGS, %g1 +LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %g1) +SUN_PI_(lda [%g0] ASI_M_MMUREGS, %g1) or %g1, 0x2, %g1 - sta %g1, [%g0] ASI_M_MMUREGS +LEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS) +SUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS) restore %g0, %g0, %g0 @@ -244,13 +247,16 @@ srmmu_rett_stackchk: save %g0, %g0, %g0 andn %g1, 0x2, %g1 - sta %g1, [%g0] ASI_M_MMUREGS +LEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS) +SUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS) mov AC_M_SFAR, %g2 - lda [%g2] ASI_M_MMUREGS, %g2 +LEON_PI(lda [%g2] ASI_LEON_MMUREGS, %g2) +SUN_PI_(lda [%g2] ASI_M_MMUREGS, %g2) mov AC_M_SFSR, %g1 - lda [%g1] ASI_M_MMUREGS, %g1 +LEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g1) +SUN_PI_(lda [%g1] ASI_M_MMUREGS, %g1) andcc %g1, 0x2, %g0 be ret_trap_userwins_ok nop diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index c052313f4dc5..efe3e64bba38 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -32,6 +32,7 @@ #include <linux/cpu.h> #include <linux/kdebug.h> #include <linux/export.h> +#include <linux/start_kernel.h> #include <asm/io.h> #include <asm/processor.h> @@ -45,6 +46,7 @@ #include <asm/cpudata.h> #include <asm/setup.h> #include <asm/cacheflush.h> +#include <asm/sections.h> #include "kernel.h" @@ -237,28 +239,42 @@ static void __init per_cpu_patch(void) } } +struct leon_1insn_patch_entry { + unsigned int addr; + unsigned int insn; +}; + enum sparc_cpu sparc_cpu_model; EXPORT_SYMBOL(sparc_cpu_model); -struct tt_entry *sparc_ttable; +static __init void leon_patch(void) +{ + struct leon_1insn_patch_entry *start = (void *)__leon_1insn_patch; + struct leon_1insn_patch_entry *end = (void *)__leon_1insn_patch_end; -struct pt_regs fake_swapper_regs; + /* Default instruction is leon - no patching */ + if (sparc_cpu_model == sparc_leon) + return; -void __init setup_arch(char **cmdline_p) -{ - int i; - unsigned long highest_paddr; + while (start < end) { + unsigned long addr = start->addr; - sparc_ttable = (struct tt_entry *) &trapbase; + *(unsigned int *)(addr) = start->insn; + flushi(addr); - /* Initialize PROM console and command line. */ - *cmdline_p = prom_getbootargs(); - strcpy(boot_command_line, *cmdline_p); - parse_early_param(); + start++; + } +} - boot_flags_init(*cmdline_p); +struct tt_entry *sparc_ttable; +struct pt_regs fake_swapper_regs; - register_console(&prom_early_console); +/* Called from head_32.S - before we have setup anything + * in the kernel. Be very careful with what you do here. + */ +void __init sparc32_start_kernel(struct linux_romvec *rp) +{ + prom_init(rp); /* Set sparc_cpu_model */ sparc_cpu_model = sun_unknown; @@ -275,6 +291,26 @@ void __init setup_arch(char **cmdline_p) if (!strncmp(&cputypval[0], "leon" , 4)) sparc_cpu_model = sparc_leon; + leon_patch(); + start_kernel(); +} + +void __init setup_arch(char **cmdline_p) +{ + int i; + unsigned long highest_paddr; + + sparc_ttable = (struct tt_entry *) &trapbase; + + /* Initialize PROM console and command line. */ + *cmdline_p = prom_getbootargs(); + strcpy(boot_command_line, *cmdline_p); + parse_early_param(); + + boot_flags_init(*cmdline_p); + + register_console(&prom_early_console); + printk("ARCH: "); switch(sparc_cpu_model) { case sun4m: diff --git a/arch/sparc/kernel/trampoline_32.S b/arch/sparc/kernel/trampoline_32.S index 7364ddc9e5aa..af27acab4486 100644 --- a/arch/sparc/kernel/trampoline_32.S +++ b/arch/sparc/kernel/trampoline_32.S @@ -149,8 +149,6 @@ sun4d_cpu_startup: b,a smp_do_cpu_idle -#ifdef CONFIG_SPARC_LEON - __CPUINIT .align 4 .global leon_smp_cpu_startup, smp_penguin_ctable @@ -161,7 +159,7 @@ leon_smp_cpu_startup: ld [%g1+4],%g1 srl %g1,4,%g1 set 0x00000100,%g5 /* SRMMU_CTXTBL_PTR */ - sta %g1, [%g5] ASI_M_MMUREGS + sta %g1, [%g5] ASI_LEON_MMUREGS /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */ set (PSR_PIL | PSR_S | PSR_PS), %g1 @@ -207,5 +205,3 @@ leon_smp_cpu_startup: nop b,a smp_do_cpu_idle - -#endif diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index c72fdf55e1c1..3b05e6697710 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c @@ -2054,7 +2054,7 @@ void do_fpieee(struct pt_regs *regs) do_fpe_common(regs); } -extern int do_mathemu(struct pt_regs *, struct fpustate *); +extern int do_mathemu(struct pt_regs *, struct fpustate *, bool); void do_fpother(struct pt_regs *regs) { @@ -2068,7 +2068,7 @@ void do_fpother(struct pt_regs *regs) switch ((current_thread_info()->xfsr[0] & 0x1c000)) { case (2 << 14): /* unfinished_FPop */ case (3 << 14): /* unimplemented_FPop */ - ret = do_mathemu(regs, f); + ret = do_mathemu(regs, f, false); break; } if (ret) @@ -2308,10 +2308,12 @@ void do_illegal_instruction(struct pt_regs *regs) } else { struct fpustate *f = FPUSTATE; - /* XXX maybe verify XFSR bits like - * XXX do_fpother() does? + /* On UltraSPARC T2 and later, FPU insns which + * are not implemented in HW signal an illegal + * instruction trap and do not set the FP Trap + * Trap in the %fsr to unimplemented_FPop. */ - if (do_mathemu(regs, f)) + if (do_mathemu(regs, f, true)) return; } } diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 0e1605697b49..89c2c29f154b 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -107,6 +107,11 @@ SECTIONS *(.sun4v_2insn_patch) __sun4v_2insn_patch_end = .; } + .leon_1insn_patch : { + __leon_1insn_patch = .; + *(.leon_1insn_patch) + __leon_1insn_patch_end = .; + } .swapper_tsb_phys_patch : { __swapper_tsb_phys_patch = .; *(.swapper_tsb_phys_patch) diff --git a/arch/sparc/kernel/wof.S b/arch/sparc/kernel/wof.S index 4c2de3cf309b..28a7bc69f82b 100644 --- a/arch/sparc/kernel/wof.S +++ b/arch/sparc/kernel/wof.S @@ -332,24 +332,30 @@ spwin_srmmu_stackchk: mov AC_M_SFSR, %glob_tmp /* Clear the fault status and turn on the no_fault bit. */ - lda [%glob_tmp] ASI_M_MMUREGS, %g0 ! eat SFSR +LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0) ! eat SFSR +SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0) ! eat SFSR - lda [%g0] ASI_M_MMUREGS, %glob_tmp ! read MMU control +LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control +SUN_PI_(lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit - sta %glob_tmp, [%g0] ASI_M_MMUREGS ! set it +LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it +SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it /* Dump the registers and cross fingers. */ STORE_WINDOW(sp) /* Clear the no_fault bit and check the status. */ andn %glob_tmp, 0x2, %glob_tmp - sta %glob_tmp, [%g0] ASI_M_MMUREGS +LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) +SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) mov AC_M_SFAR, %glob_tmp - lda [%glob_tmp] ASI_M_MMUREGS, %g0 +LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0) +SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0) mov AC_M_SFSR, %glob_tmp - lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp +LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp) +SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp) andcc %glob_tmp, 0x2, %g0 ! did we fault? be,a spwin_finish_up + 0x4 ! cool beans, success restore %g0, %g0, %g0 diff --git a/arch/sparc/kernel/wuf.S b/arch/sparc/kernel/wuf.S index 9fde91a249e0..2c21cc59683e 100644 --- a/arch/sparc/kernel/wuf.S +++ b/arch/sparc/kernel/wuf.S @@ -254,16 +254,19 @@ srmmu_fwin_stackchk: mov AC_M_SFSR, %l4 cmp %l5, %sp bleu fwin_user_stack_is_bolixed - lda [%l4] ASI_M_MMUREGS, %g0 ! clear fault status +LEON_PI( lda [%l4] ASI_LEON_MMUREGS, %g0) ! clear fault status +SUN_PI_( lda [%l4] ASI_M_MMUREGS, %g0) ! clear fault status /* The technique is, turn off faults on this processor, * just let the load rip, then check the sfsr to see if * a fault did occur. Then we turn on fault traps again * and branch conditionally based upon what happened. */ - lda [%g0] ASI_M_MMUREGS, %l5 ! read mmu-ctrl reg +LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %l5) ! read mmu-ctrl reg +SUN_PI_(lda [%g0] ASI_M_MMUREGS, %l5) ! read mmu-ctrl reg or %l5, 0x2, %l5 ! turn on no-fault bit - sta %l5, [%g0] ASI_M_MMUREGS ! store it +LEON_PI(sta %l5, [%g0] ASI_LEON_MMUREGS) ! store it +SUN_PI_(sta %l5, [%g0] ASI_M_MMUREGS) ! store it /* Cross fingers and go for it. */ LOAD_WINDOW(sp) @@ -275,18 +278,22 @@ srmmu_fwin_stackchk: /* LOCATION: Window 'T' */ - lda [%g0] ASI_M_MMUREGS, %twin_tmp1 ! load mmu-ctrl again - andn %twin_tmp1, 0x2, %twin_tmp1 ! clear no-fault bit - sta %twin_tmp1, [%g0] ASI_M_MMUREGS ! store it +LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %twin_tmp1) ! load mmu-ctrl again +SUN_PI_(lda [%g0] ASI_M_MMUREGS, %twin_tmp1) ! load mmu-ctrl again + andn %twin_tmp1, 0x2, %twin_tmp1 ! clear no-fault bit +LEON_PI(sta %twin_tmp1, [%g0] ASI_LEON_MMUREGS) ! store it +SUN_PI_(sta %twin_tmp1, [%g0] ASI_M_MMUREGS) ! store it mov AC_M_SFAR, %twin_tmp2 - lda [%twin_tmp2] ASI_M_MMUREGS, %g0 ! read fault address +LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %g0) ! read fault address +SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %g0) ! read fault address mov AC_M_SFSR, %twin_tmp2 - lda [%twin_tmp2] ASI_M_MMUREGS, %twin_tmp2 ! read fault status - andcc %twin_tmp2, 0x2, %g0 ! did fault occur? +LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %twin_tmp2) ! read fault status +SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %twin_tmp2) ! read fault status + andcc %twin_tmp2, 0x2, %g0 ! did fault occur? - bne 1f ! yep, cleanup + bne 1f ! yep, cleanup nop wr %t_psr, 0x0, %psr diff --git a/arch/sparc/math-emu/math_64.c b/arch/sparc/math-emu/math_64.c index 2bbe2f28ad23..1704068da928 100644 --- a/arch/sparc/math-emu/math_64.c +++ b/arch/sparc/math-emu/math_64.c @@ -163,7 +163,7 @@ typedef union { u64 q[2]; } *argp; -int do_mathemu(struct pt_regs *regs, struct fpustate *f) +int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap) { unsigned long pc = regs->tpc; unsigned long tstate = regs->tstate; @@ -218,7 +218,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) case FSQRTS: { unsigned long x = current_thread_info()->xfsr[0]; - x = (x >> 14) & 0xf; + x = (x >> 14) & 0x7; TYPE(x,1,1,1,1,0,0); break; } @@ -226,7 +226,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) case FSQRTD: { unsigned long x = current_thread_info()->xfsr[0]; - x = (x >> 14) & 0xf; + x = (x >> 14) & 0x7; TYPE(x,2,1,2,1,0,0); break; } @@ -357,9 +357,17 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) if (type) { argp rs1 = NULL, rs2 = NULL, rd = NULL; - freg = (current_thread_info()->xfsr[0] >> 14) & 0xf; - if (freg != (type >> 9)) - goto err; + /* Starting with UltraSPARC-T2, the cpu does not set the FP Trap + * Type field in the %fsr to unimplemented_FPop. Nor does it + * use the fp_exception_other trap. Instead it signals an + * illegal instruction and leaves the FP trap type field of + * the %fsr unchanged. + */ + if (!illegal_insn_trap) { + int ftt = (current_thread_info()->xfsr[0] >> 14) & 0x7; + if (ftt != (type >> 9)) + goto err; + } current_thread_info()->xfsr[0] &= ~0x1c000; freg = ((insn >> 14) & 0x1f); switch (type & 0x3) { diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile index 69ffd3112fed..30c3eccfdf5a 100644 --- a/arch/sparc/mm/Makefile +++ b/arch/sparc/mm/Makefile @@ -8,8 +8,9 @@ obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o gup.o obj-y += fault_$(BITS).o obj-y += init_$(BITS).o obj-$(CONFIG_SPARC32) += extable.o srmmu.o iommu.o io-unit.o +obj-$(CONFIG_SPARC32) += srmmu_access.o obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o -obj-$(CONFIG_SPARC_LEON)+= leon_mm.o +obj-$(CONFIG_SPARC32) += leon_mm.o # Only used by sparc64 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o diff --git a/arch/sparc/mm/leon_mm.c b/arch/sparc/mm/leon_mm.c index 4c67ae6e5023..5bed085a2c17 100644 --- a/arch/sparc/mm/leon_mm.c +++ b/arch/sparc/mm/leon_mm.c @@ -32,7 +32,7 @@ static inline unsigned long leon_get_ctable_ptr(void) } -unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr) +unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr) { unsigned int ctxtbl; diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 256db6b22c54..62e3f5773303 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -646,6 +646,23 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start, } } +/* These flush types are not available on all chips... */ +static inline unsigned long srmmu_probe(unsigned long vaddr) +{ + unsigned long retval; + + if (sparc_cpu_model != sparc_leon) { + + vaddr &= PAGE_MASK; + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE)); + } else { + retval = leon_swprobe(vaddr, 0); + } + return retval; +} + /* * This is much cleaner than poking around physical address space * looking at the prom's page table directly which is what most @@ -665,7 +682,7 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start, break; /* probably wrap around */ if(start == 0xfef00000) start = KADB_DEBUGGER_BEGVM; - if(!(prompte = srmmu_hwprobe(start))) { + if(!(prompte = srmmu_probe(start))) { start += PAGE_SIZE; continue; } @@ -674,12 +691,12 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start, what = 0; if(!(start & ~(SRMMU_REAL_PMD_MASK))) { - if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte) + if(srmmu_probe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte) what = 1; } if(!(start & ~(SRMMU_PGDIR_MASK))) { - if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_PGDIR_SIZE) == + if(srmmu_probe((start-PAGE_SIZE) + SRMMU_PGDIR_SIZE) == prompte) what = 2; } @@ -1156,7 +1173,7 @@ static void turbosparc_flush_page_to_ram(unsigned long page) #ifdef TURBOSPARC_WRITEBACK volatile unsigned long clear; - if (srmmu_hwprobe(page)) + if (srmmu_probe(page)) turbosparc_flush_page_cache(page); clear = srmmu_get_fstatus(); #endif diff --git a/arch/sparc/mm/srmmu_access.S b/arch/sparc/mm/srmmu_access.S new file mode 100644 index 000000000000..d0a67b2c2383 --- /dev/null +++ b/arch/sparc/mm/srmmu_access.S @@ -0,0 +1,82 @@ +/* Assembler variants of srmmu access functions. + * Implemented in assembler to allow run-time patching. + * LEON uses a different ASI for MMUREGS than SUN. + * + * The leon_1insn_patch infrastructure is used + * for the run-time patching. + */ + +#include <linux/linkage.h> + +#include <asm/asmmacro.h> +#include <asm/pgtsrmmu.h> +#include <asm/asi.h> + +/* unsigned int srmmu_get_mmureg(void) */ +ENTRY(srmmu_get_mmureg) +LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %o0) +SUN_PI_(lda [%g0] ASI_M_MMUREGS, %o0) + retl + nop +ENDPROC(srmmu_get_mmureg) + +/* void srmmu_set_mmureg(unsigned long regval) */ +ENTRY(srmmu_set_mmureg) +LEON_PI(sta %o0, [%g0] ASI_LEON_MMUREGS) +SUN_PI_(sta %o0, [%g0] ASI_M_MMUREGS) + retl + nop +ENDPROC(srmmu_set_mmureg) + +/* void srmmu_set_ctable_ptr(unsigned long paddr) */ +ENTRY(srmmu_set_ctable_ptr) + /* paddr = ((paddr >> 4) & SRMMU_CTX_PMASK); */ + srl %o0, 4, %g1 + and %g1, SRMMU_CTX_PMASK, %g1 + + mov SRMMU_CTXTBL_PTR, %g2 +LEON_PI(sta %g1, [%g2] ASI_LEON_MMUREGS) +SUN_PI_(sta %g1, [%g2] ASI_M_MMUREGS) + retl + nop +ENDPROC(srmmu_set_ctable_ptr) + + +/* void srmmu_set_context(int context) */ +ENTRY(srmmu_set_context) + mov SRMMU_CTX_REG, %g1 +LEON_PI(sta %o0, [%g1] ASI_LEON_MMUREGS) +SUN_PI_(sta %o0, [%g1] ASI_M_MMUREGS) + retl + nop +ENDPROC(srmmu_set_context) + + +/* int srmmu_get_context(void) */ +ENTRY(srmmu_get_context) + mov SRMMU_CTX_REG, %o0 +LEON_PI(lda [%o0] ASI_LEON_MMUREGS, %o0) +SUN_PI_(lda [%o0] ASI_M_MMUREGS, %o0) + retl + nop +ENDPROC(srmmu_get_context) + + +/* unsigned int srmmu_get_fstatus(void) */ +ENTRY(srmmu_get_fstatus) + mov SRMMU_FAULT_STATUS, %o0 +LEON_PI(lda [%o0] ASI_LEON_MMUREGS, %o0) +SUN_PI_(lda [%o0] ASI_M_MMUREGS, %o0) + retl + nop +ENDPROC(srmmu_get_fstatus) + + +/* unsigned int srmmu_get_faddr(void) */ +ENTRY(srmmu_get_faddr) + mov SRMMU_FAULT_ADDR, %o0 +LEON_PI(lda [%o0] ASI_LEON_MMUREGS, %o0) +SUN_PI_(lda [%o0] ASI_M_MMUREGS, %o0) + retl + nop +ENDPROC(srmmu_get_faddr) diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 724aa441de7d..0c44630d1789 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -29,6 +29,7 @@ #include <asm/processor.h> #include <asm/mmu.h> #include <asm/mpspec.h> +#include <asm/realmode.h> #define COMPILER_DEPENDENT_INT64 long long #define COMPILER_DEPENDENT_UINT64 unsigned long long @@ -116,10 +117,8 @@ static inline void acpi_disable_pci(void) /* Low-level suspend routine. */ extern int acpi_suspend_lowlevel(void); -extern const unsigned char acpi_wakeup_code[]; - -/* early initialization routine */ -extern void acpi_reserve_wakeup_memory(void); +/* Physical address to resume after wakeup */ +#define acpi_wakeup_address ((unsigned long)(real_mode_header->wakeup_start)) /* * Check if the CPU can handle C2 and deeper diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index b97596e2b68c..a6983b277220 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h @@ -15,6 +15,8 @@ #include <linux/compiler.h> #include <asm/alternative.h> +#define BIT_64(n) (U64_C(1) << (n)) + /* * These have to be done with inline assembly: that way the bit-setting * is guaranteed to be atomic. All bit operations return 0 if the bit diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index b772dd6ad450..0a687fd185e6 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -1251,15 +1251,15 @@ void mce_log_therm_throt_event(__u64 status) * poller finds an MCE, poll 2x faster. When the poller finds no more * errors, poll 2x slower (up to check_interval seconds). */ -static int check_interval = 5 * 60; /* 5 minutes */ +static unsigned long check_interval = 5 * 60; /* 5 minutes */ -static DEFINE_PER_CPU(int, mce_next_interval); /* in jiffies */ +static DEFINE_PER_CPU(unsigned long, mce_next_interval); /* in jiffies */ static DEFINE_PER_CPU(struct timer_list, mce_timer); -static void mce_start_timer(unsigned long data) +static void mce_timer_fn(unsigned long data) { - struct timer_list *t = &per_cpu(mce_timer, data); - int *n; + struct timer_list *t = &__get_cpu_var(mce_timer); + unsigned long iv; WARN_ON(smp_processor_id() != data); @@ -1272,13 +1272,14 @@ static void mce_start_timer(unsigned long data) * Alert userspace if needed. If we logged an MCE, reduce the * polling interval, otherwise increase the polling interval. */ - n = &__get_cpu_var(mce_next_interval); + iv = __this_cpu_read(mce_next_interval); if (mce_notify_irq()) - *n = max(*n/2, HZ/100); + iv = max(iv, (unsigned long) HZ/100); else - *n = min(*n*2, (int)round_jiffies_relative(check_interval*HZ)); + iv = min(iv * 2, round_jiffies_relative(check_interval * HZ)); + __this_cpu_write(mce_next_interval, iv); - t->expires = jiffies + *n; + t->expires = jiffies + iv; add_timer_on(t, smp_processor_id()); } @@ -1472,9 +1473,9 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) rdmsrl(msrs[i], val); /* CntP bit set? */ - if (val & BIT(62)) { - val &= ~BIT(62); - wrmsrl(msrs[i], val); + if (val & BIT_64(62)) { + val &= ~BIT_64(62); + wrmsrl(msrs[i], val); } } @@ -1556,17 +1557,17 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c) static void __mcheck_cpu_init_timer(void) { struct timer_list *t = &__get_cpu_var(mce_timer); - int *n = &__get_cpu_var(mce_next_interval); + unsigned long iv = __this_cpu_read(mce_next_interval); - setup_timer(t, mce_start_timer, smp_processor_id()); + setup_timer(t, mce_timer_fn, smp_processor_id()); if (mce_ignore_ce) return; - *n = check_interval * HZ; - if (!*n) + __this_cpu_write(mce_next_interval, iv); + if (!iv) return; - t->expires = round_jiffies(jiffies + *n); + t->expires = round_jiffies(jiffies + iv); add_timer_on(t, smp_processor_id()); } @@ -2276,7 +2277,7 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) case CPU_DOWN_FAILED_FROZEN: if (!mce_ignore_ce && check_interval) { t->expires = round_jiffies(jiffies + - __get_cpu_var(mce_next_interval)); + per_cpu(mce_next_interval, cpu)); add_timer_on(t, cpu); } smp_call_function_single(cpu, mce_reenable_cpu, &action, 1); diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c index ac140c7be396..bdda2e6c673b 100644 --- a/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/arch/x86/kernel/cpu/mtrr/cleanup.c @@ -266,7 +266,7 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk, if (align > max_align) align = max_align; - sizek = 1 << align; + sizek = 1UL << align; if (debug_print) { char start_factor = 'K', size_factor = 'K'; unsigned long start_base, size_base; diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 9cc7b4392f7c..1460a5df92f7 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -870,7 +870,7 @@ int __init hpet_enable(void) else pr_warn("HPET initial state will not be saved\n"); cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY); - hpet_writel(cfg, HPET_Tn_CFG(i)); + hpet_writel(cfg, HPET_CFG); if (cfg) pr_warn("HPET: Unrecognized bits %#x set in global cfg\n", cfg); diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index f11729fd019c..3d68ef6d2266 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -158,31 +158,47 @@ static unsigned long pat_x_mtrr_type(u64 start, u64 end, unsigned long req_type) return req_type; } +struct pagerange_state { + unsigned long cur_pfn; + int ram; + int not_ram; +}; + +static int +pagerange_is_ram_callback(unsigned long initial_pfn, unsigned long total_nr_pages, void *arg) +{ + struct pagerange_state *state = arg; + + state->not_ram |= initial_pfn > state->cur_pfn; + state->ram |= total_nr_pages > 0; + state->cur_pfn = initial_pfn + total_nr_pages; + + return state->ram && state->not_ram; +} + static int pat_pagerange_is_ram(resource_size_t start, resource_size_t end) { - int ram_page = 0, not_rampage = 0; - unsigned long page_nr; + int ret = 0; + unsigned long start_pfn = start >> PAGE_SHIFT; + unsigned long end_pfn = (end + PAGE_SIZE - 1) >> PAGE_SHIFT; + struct pagerange_state state = {start_pfn, 0, 0}; - for (page_nr = (start >> PAGE_SHIFT); page_nr < (end >> PAGE_SHIFT); - ++page_nr) { - /* - * For legacy reasons, physical address range in the legacy ISA - * region is tracked as non-RAM. This will allow users of - * /dev/mem to map portions of legacy ISA region, even when - * some of those portions are listed(or not even listed) with - * different e820 types(RAM/reserved/..) - */ - if (page_nr >= (ISA_END_ADDRESS >> PAGE_SHIFT) && - page_is_ram(page_nr)) - ram_page = 1; - else - not_rampage = 1; - - if (ram_page == not_rampage) - return -1; + /* + * For legacy reasons, physical address range in the legacy ISA + * region is tracked as non-RAM. This will allow users of + * /dev/mem to map portions of legacy ISA region, even when + * some of those portions are listed(or not even listed) with + * different e820 types(RAM/reserved/..) + */ + if (start_pfn < ISA_END_ADDRESS >> PAGE_SHIFT) + start_pfn = ISA_END_ADDRESS >> PAGE_SHIFT; + + if (start_pfn < end_pfn) { + ret = walk_system_ram_range(start_pfn, end_pfn - start_pfn, + &state, pagerange_is_ram_callback); } - return ram_page; + return (ret > 0) ? -1 : (state.ram ? 1 : 0); } /* diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 75f33b2a5933..e74df9548a02 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1116,7 +1116,10 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { .wbinvd = native_wbinvd, .read_msr = native_read_msr_safe, + .rdmsr_regs = native_rdmsr_safe_regs, .write_msr = xen_write_msr_safe, + .wrmsr_regs = native_wrmsr_safe_regs, + .read_tsc = native_read_tsc, .read_pmc = native_read_pmc, diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index ebaa04593236..74ee4ab577b6 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -25,8 +25,6 @@ #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> -#include <asm/realmode.h> - #include "internal.h" #include "sleep.h" @@ -93,13 +91,11 @@ static struct notifier_block tts_notifier = { static int acpi_sleep_prepare(u32 acpi_state) { #ifdef CONFIG_ACPI_SLEEP - unsigned long wakeup_pa = real_mode_header->wakeup_start; /* do we have a wakeup address for S2 and S3? */ if (acpi_state == ACPI_STATE_S3) { - if (!wakeup_pa) + if (!acpi_wakeup_address) return -EFAULT; - acpi_set_firmware_waking_vector( - (acpi_physical_address)wakeup_pa); + acpi_set_firmware_waking_vector(acpi_wakeup_address); } ACPI_FLUSH_CPU_CACHE(); diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index e8cd652d2017..98510931c815 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -984,6 +984,7 @@ static uint32_t fpga_tx(struct solos_card *card) } else if (skb && card->using_dma) { SKB_CB(skb)->dma_addr = pci_map_single(card->dev, skb->data, skb->len, PCI_DMA_TODEVICE); + card->tx_skb[port] = skb; iowrite32(SKB_CB(skb)->dma_addr, card->config_regs + TX_DMA_ADDR(port)); } @@ -1152,7 +1153,8 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) db_fpga_upgrade = db_firmware_upgrade = 0; } - if (card->fpga_version >= DMA_SUPPORTED){ + if (card->fpga_version >= DMA_SUPPORTED) { + pci_set_master(dev); card->using_dma = 1; } else { card->using_dma = 0; diff --git a/drivers/edac/mce_amd.h b/drivers/edac/mce_amd.h index c6074c5cd1ef..8c87a5e87057 100644 --- a/drivers/edac/mce_amd.h +++ b/drivers/edac/mce_amd.h @@ -5,8 +5,6 @@ #include <asm/mce.h> -#define BIT_64(n) (U64_C(1) << (n)) - #define EC(x) ((x) & 0xffff) #define XEC(x, mask) (((x) >> 16) & mask) diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index 4de73643fec6..d1827e887f4e 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -1096,20 +1096,20 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, if (err) { dev_err(&pdev->dev, "32-bit PCI DMA addresses" "not supported by the card\n"); - goto err_out; + goto err_out_disable_dev; } err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); if (err) { dev_err(&pdev->dev, "32-bit PCI DMA addresses" "not supported by the card\n"); - goto err_out; + goto err_out_disable_dev; } /* IO Size check */ if (pci_resource_len(pdev, bar) < io_size) { dev_err(&pdev->dev, "Insufficient PCI resources, aborting\n"); err = -EIO; - goto err_out; + goto err_out_disable_dev; } pci_set_master(pdev); @@ -1117,7 +1117,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct r6040_private)); if (!dev) { err = -ENOMEM; - goto err_out; + goto err_out_disable_dev; } SET_NETDEV_DEV(dev, &pdev->dev); lp = netdev_priv(dev); @@ -1233,11 +1233,15 @@ err_out_mdio_irq: err_out_mdio: mdiobus_free(lp->mii_bus); err_out_unmap: + netif_napi_del(&lp->napi); + pci_set_drvdata(pdev, NULL); pci_iounmap(pdev, ioaddr); err_out_free_res: pci_release_regions(pdev); err_out_free_dev: free_netdev(dev); +err_out_disable_dev: + pci_disable_device(pdev); err_out: return err; } @@ -1251,6 +1255,9 @@ static void __devexit r6040_remove_one(struct pci_dev *pdev) mdiobus_unregister(lp->mii_bus); kfree(lp->mii_bus->irq); mdiobus_free(lp->mii_bus); + netif_napi_del(&lp->napi); + pci_set_drvdata(pdev, NULL); + pci_iounmap(pdev, lp->base); pci_release_regions(pdev); free_netdev(dev); pci_disable_device(pdev); diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index be3c22179161..667169b82526 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1101,8 +1101,12 @@ static int sh_eth_rx(struct net_device *ndev) /* Restart Rx engine if stopped. */ /* If we don't need to check status, don't. -KDU */ - if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) + if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) { + /* fix the values for the next receiving */ + mdp->cur_rx = mdp->dirty_rx = (sh_eth_read(ndev, RDFAR) - + sh_eth_read(ndev, RDLAR)) >> 4; sh_eth_write(ndev, EDRRR_R, EDRRR); + } return 0; } @@ -1199,8 +1203,6 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) /* Receive Descriptor Empty int */ ndev->stats.rx_over_errors++; - if (sh_eth_read(ndev, EDRRR) ^ EDRRR_R) - sh_eth_write(ndev, EDRRR_R, EDRRR); if (netif_msg_rx_err(mdp)) dev_err(&ndev->dev, "Receive Descriptor Empty\n"); } diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index dab9c6f671ec..1466e5d2af44 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -2390,11 +2390,11 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) retval = smsc911x_request_resources(pdev); if (retval) - goto out_return_resources; + goto out_request_resources_fail; retval = smsc911x_enable_resources(pdev); if (retval) - goto out_disable_resources; + goto out_enable_resources_fail; if (pdata->ioaddr == NULL) { SMSC_WARN(pdata, probe, "Error smsc911x base address invalid"); @@ -2501,8 +2501,9 @@ out_free_irq: free_irq(dev->irq, dev); out_disable_resources: (void)smsc911x_disable_resources(pdev); -out_return_resources: +out_enable_resources_fail: smsc911x_free_resources(pdev); +out_request_resources_fail: platform_set_drvdata(pdev, NULL); iounmap(pdata->ioaddr); free_netdev(dev); diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 71e2b0523bc2..3ae80eccd0ef 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -35,6 +35,7 @@ #include <linux/crc32.h> #include <linux/usb/usbnet.h> #include <linux/slab.h> +#include <linux/if_vlan.h> #define DRIVER_VERSION "22-Dec-2011" #define DRIVER_NAME "asix" @@ -321,7 +322,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) return 0; } - if ((size > dev->net->mtu + ETH_HLEN) || + if ((size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) || (size + offset > skb->len)) { netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", size); diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 380dbea6109d..3b206786b5e7 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -547,6 +547,8 @@ static const struct usb_device_id products[] = { {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ + {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ + {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ { } /* END */ }; MODULE_DEVICE_TABLE(usb, products); diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 9ce6995e8d08..5214b1eceb95 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -1231,11 +1231,6 @@ static int virtnet_freeze(struct virtio_device *vdev) vi->config_enable = false; mutex_unlock(&vi->config_lock); - virtqueue_disable_cb(vi->rvq); - virtqueue_disable_cb(vi->svq); - if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) - virtqueue_disable_cb(vi->cvq); - netif_device_detach(vi->dev); cancel_delayed_work_sync(&vi->refill); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 0ba81a66061f..fbaa30930076 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2415,6 +2415,22 @@ ath5k_tx_complete_poll_work(struct work_struct *work) * Initialization routines * \*************************/ +static const struct ieee80211_iface_limit if_limits[] = { + { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) }, + { .max = 4, .types = +#ifdef CONFIG_MAC80211_MESH + BIT(NL80211_IFTYPE_MESH_POINT) | +#endif + BIT(NL80211_IFTYPE_AP) }, +}; + +static const struct ieee80211_iface_combination if_comb = { + .limits = if_limits, + .n_limits = ARRAY_SIZE(if_limits), + .max_interfaces = 2048, + .num_different_channels = 1, +}; + int __devinit ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) { @@ -2436,6 +2452,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); + hw->wiphy->iface_combinations = &if_comb; + hw->wiphy->n_iface_combinations = 1; + /* SW support for IBSS_RSN is provided by mac80211 */ hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index ac53d901801d..dfb0441f406c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3809,7 +3809,7 @@ static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set) return true; } -static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) +void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) { int internal_regulator = ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 2505ac44f0c1..8396d150ce01 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -334,4 +334,7 @@ u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz); unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, struct ath9k_channel *chan); + +void ar9003_hw_internal_regulator_apply(struct ath_hw *ah); + #endif diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h index f11d9b2677fd..1bd3a3d22101 100644 --- a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2011 Atheros Communications Inc. + * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,7 +19,7 @@ #define INITVALS_9330_1P1_H static const u32 ar9331_1p1_baseband_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, @@ -27,10 +28,10 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = { {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a4, 0x037216a4}, - {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, + {0x00009e04, 0x00202020, 0x00202020, 0x00202020, 0x00202020}, {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, {0x00009e10, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e}, - {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009e14, 0x31365d5e, 0x3136605e, 0x3136605e, 0x31365d5e}, {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, @@ -55,7 +56,7 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = { {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, - {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071981}, + {0x0000a2d0, 0x00071982, 0x00071982, 0x00071982, 0x00071982}, {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000ae04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, @@ -63,7 +64,7 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = { }; static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, @@ -155,7 +156,7 @@ static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p1[][5] = { }; static const u32 ar9331_modes_high_ob_db_tx_gain_1p1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, {0x0000a2dc, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52}, {0x0000a2e0, 0xffb31c84, 0xffb31c84, 0xffb31c84, 0xffb31c84}, @@ -245,7 +246,7 @@ static const u32 ar9331_modes_high_ob_db_tx_gain_1p1[][5] = { }; static const u32 ar9331_modes_low_ob_db_tx_gain_1p1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, @@ -377,14 +378,14 @@ static const u32 ar9331_1p1_radio_core[][2] = { {0x000160b4, 0x92480040}, {0x000160c0, 0x006db6db}, {0x000160c4, 0x0186db60}, - {0x000160c8, 0x6db6db6c}, + {0x000160c8, 0x6db4db6c}, {0x000160cc, 0x6de6c300}, {0x000160d0, 0x14500820}, {0x00016100, 0x04cb0001}, {0x00016104, 0xfff80015}, {0x00016108, 0x00080010}, {0x0001610c, 0x00170000}, - {0x00016140, 0x10804000}, + {0x00016140, 0x10800000}, {0x00016144, 0x01884080}, {0x00016148, 0x000080c0}, {0x00016280, 0x01000015}, @@ -417,7 +418,7 @@ static const u32 ar9331_1p1_radio_core[][2] = { }; static const u32 ar9331_1p1_soc_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00007010, 0x00000022, 0x00000022, 0x00000022, 0x00000022}, }; @@ -691,7 +692,7 @@ static const u32 ar9331_1p1_baseband_core[][2] = { }; static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, @@ -783,7 +784,7 @@ static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { }; static const u32 ar9331_1p1_mac_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, @@ -973,26 +974,27 @@ static const u32 ar9331_1p1_mac_core[][2] = { static const u32 ar9331_common_rx_gain_1p1[][2] = { /* Addr allmodes */ - {0x0000a000, 0x00010000}, - {0x0000a004, 0x00030002}, - {0x0000a008, 0x00050004}, - {0x0000a00c, 0x00810080}, - {0x0000a010, 0x00830082}, - {0x0000a014, 0x01810180}, - {0x0000a018, 0x01830182}, - {0x0000a01c, 0x01850184}, - {0x0000a020, 0x01890188}, - {0x0000a024, 0x018b018a}, - {0x0000a028, 0x018d018c}, - {0x0000a02c, 0x01910190}, - {0x0000a030, 0x01930192}, - {0x0000a034, 0x01950194}, - {0x0000a038, 0x038a0196}, - {0x0000a03c, 0x038c038b}, - {0x0000a040, 0x0390038d}, - {0x0000a044, 0x03920391}, - {0x0000a048, 0x03940393}, - {0x0000a04c, 0x03960395}, + {0x00009e18, 0x05000000}, + {0x0000a000, 0x00060005}, + {0x0000a004, 0x00810080}, + {0x0000a008, 0x00830082}, + {0x0000a00c, 0x00850084}, + {0x0000a010, 0x01820181}, + {0x0000a014, 0x01840183}, + {0x0000a018, 0x01880185}, + {0x0000a01c, 0x018a0189}, + {0x0000a020, 0x02850284}, + {0x0000a024, 0x02890288}, + {0x0000a028, 0x028b028a}, + {0x0000a02c, 0x03850384}, + {0x0000a030, 0x03890388}, + {0x0000a034, 0x038b038a}, + {0x0000a038, 0x038d038c}, + {0x0000a03c, 0x03910390}, + {0x0000a040, 0x03930392}, + {0x0000a044, 0x03950394}, + {0x0000a048, 0x00000396}, + {0x0000a04c, 0x00000000}, {0x0000a050, 0x00000000}, {0x0000a054, 0x00000000}, {0x0000a058, 0x00000000}, @@ -1005,15 +1007,15 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { {0x0000a074, 0x00000000}, {0x0000a078, 0x00000000}, {0x0000a07c, 0x00000000}, - {0x0000a080, 0x22222229}, - {0x0000a084, 0x1d1d1d1d}, - {0x0000a088, 0x1d1d1d1d}, - {0x0000a08c, 0x1d1d1d1d}, - {0x0000a090, 0x171d1d1d}, - {0x0000a094, 0x11111717}, - {0x0000a098, 0x00030311}, - {0x0000a09c, 0x00000000}, - {0x0000a0a0, 0x00000000}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x24242428}, + {0x0000a098, 0x171e1e1e}, + {0x0000a09c, 0x02020b0b}, + {0x0000a0a0, 0x02020202}, {0x0000a0a4, 0x00000000}, {0x0000a0a8, 0x00000000}, {0x0000a0ac, 0x00000000}, @@ -1021,27 +1023,27 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { {0x0000a0b4, 0x00000000}, {0x0000a0b8, 0x00000000}, {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x001f0000}, - {0x0000a0c4, 0x01000101}, - {0x0000a0c8, 0x011e011f}, - {0x0000a0cc, 0x011c011d}, - {0x0000a0d0, 0x02030204}, - {0x0000a0d4, 0x02010202}, - {0x0000a0d8, 0x021f0200}, - {0x0000a0dc, 0x0302021e}, - {0x0000a0e0, 0x03000301}, - {0x0000a0e4, 0x031e031f}, - {0x0000a0e8, 0x0402031d}, - {0x0000a0ec, 0x04000401}, - {0x0000a0f0, 0x041e041f}, - {0x0000a0f4, 0x0502041d}, - {0x0000a0f8, 0x05000501}, - {0x0000a0fc, 0x051e051f}, - {0x0000a100, 0x06010602}, - {0x0000a104, 0x061f0600}, - {0x0000a108, 0x061d061e}, - {0x0000a10c, 0x07020703}, - {0x0000a110, 0x07000701}, + {0x0000a0c0, 0x22072208}, + {0x0000a0c4, 0x22052206}, + {0x0000a0c8, 0x22032204}, + {0x0000a0cc, 0x22012202}, + {0x0000a0d0, 0x221f2200}, + {0x0000a0d4, 0x221d221e}, + {0x0000a0d8, 0x33023303}, + {0x0000a0dc, 0x33003301}, + {0x0000a0e0, 0x331e331f}, + {0x0000a0e4, 0x4402331d}, + {0x0000a0e8, 0x44004401}, + {0x0000a0ec, 0x441e441f}, + {0x0000a0f0, 0x55025503}, + {0x0000a0f4, 0x55005501}, + {0x0000a0f8, 0x551e551f}, + {0x0000a0fc, 0x6602551d}, + {0x0000a100, 0x66006601}, + {0x0000a104, 0x661e661f}, + {0x0000a108, 0x7703661d}, + {0x0000a10c, 0x77017702}, + {0x0000a110, 0x00007700}, {0x0000a114, 0x00000000}, {0x0000a118, 0x00000000}, {0x0000a11c, 0x00000000}, @@ -1054,26 +1056,26 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { {0x0000a138, 0x00000000}, {0x0000a13c, 0x00000000}, {0x0000a140, 0x001f0000}, - {0x0000a144, 0x01000101}, - {0x0000a148, 0x011e011f}, - {0x0000a14c, 0x011c011d}, - {0x0000a150, 0x02030204}, - {0x0000a154, 0x02010202}, - {0x0000a158, 0x021f0200}, - {0x0000a15c, 0x0302021e}, - {0x0000a160, 0x03000301}, - {0x0000a164, 0x031e031f}, - {0x0000a168, 0x0402031d}, - {0x0000a16c, 0x04000401}, - {0x0000a170, 0x041e041f}, - {0x0000a174, 0x0502041d}, - {0x0000a178, 0x05000501}, - {0x0000a17c, 0x051e051f}, - {0x0000a180, 0x06010602}, - {0x0000a184, 0x061f0600}, - {0x0000a188, 0x061d061e}, - {0x0000a18c, 0x07020703}, - {0x0000a190, 0x07000701}, + {0x0000a144, 0x111f1100}, + {0x0000a148, 0x111d111e}, + {0x0000a14c, 0x111b111c}, + {0x0000a150, 0x22032204}, + {0x0000a154, 0x22012202}, + {0x0000a158, 0x221f2200}, + {0x0000a15c, 0x221d221e}, + {0x0000a160, 0x33013302}, + {0x0000a164, 0x331f3300}, + {0x0000a168, 0x4402331e}, + {0x0000a16c, 0x44004401}, + {0x0000a170, 0x441e441f}, + {0x0000a174, 0x55015502}, + {0x0000a178, 0x551f5500}, + {0x0000a17c, 0x6602551e}, + {0x0000a180, 0x66006601}, + {0x0000a184, 0x661e661f}, + {0x0000a188, 0x7703661d}, + {0x0000a18c, 0x77017702}, + {0x0000a190, 0x00007700}, {0x0000a194, 0x00000000}, {0x0000a198, 0x00000000}, {0x0000a19c, 0x00000000}, @@ -1100,14 +1102,14 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { {0x0000a1f0, 0x00000396}, {0x0000a1f4, 0x00000396}, {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000196}, + {0x0000a1fc, 0x00000296}, }; static const u32 ar9331_common_tx_gain_offset1_1[][1] = { - {0}, - {3}, - {0}, - {0}, + {0x00000000}, + {0x00000003}, + {0x00000000}, + {0x00000000}, }; static const u32 ar9331_1p1_chansel_xtal_25M[] = { diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index abe05ec85d50..7db1890448f2 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1468,6 +1468,9 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah, return false; ah->chip_fullsleep = false; + + if (AR_SREV_9330(ah)) + ar9003_hw_internal_regulator_apply(ah); ath9k_hw_init_pll(ah, chan); ath9k_hw_set_rfmode(ah, chan); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index dfa78e8b6470..4de4473776ac 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -239,7 +239,7 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - bool ret; + bool ret = true; ieee80211_stop_queues(sc->hw); @@ -250,11 +250,12 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) ath9k_debug_samp_bb_mac(sc); ath9k_hw_disable_interrupts(ah); - ret = ath_drain_all_txq(sc, retry_tx); - if (!ath_stoprecv(sc)) ret = false; + if (!ath_drain_all_txq(sc, retry_tx)) + ret = false; + if (!flush) { if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) ath_rx_tasklet(sc, 1, true); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 23eaa1b26ebe..d59dd01d6cde 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -64,7 +64,8 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid, - struct sk_buff *skb); + struct sk_buff *skb, + bool dequeue); enum { MCS_HT20, @@ -811,7 +812,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, fi = get_frame_info(skb); bf = fi->bf; if (!fi->bf) - bf = ath_tx_setup_buffer(sc, txq, tid, skb); + bf = ath_tx_setup_buffer(sc, txq, tid, skb, true); if (!bf) continue; @@ -1726,7 +1727,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, return; } - bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); + bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); if (!bf) return; @@ -1753,7 +1754,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, bf = fi->bf; if (!bf) - bf = ath_tx_setup_buffer(sc, txq, tid, skb); + bf = ath_tx_setup_buffer(sc, txq, tid, skb, false); if (!bf) return; @@ -1814,7 +1815,8 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid, - struct sk_buff *skb) + struct sk_buff *skb, + bool dequeue) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_frame_info *fi = get_frame_info(skb); @@ -1863,6 +1865,8 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, return bf; error: + if (dequeue) + __skb_unlink(skb, &tid->buf_q); dev_kfree_skb_any(skb); return NULL; } @@ -1893,7 +1897,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, */ ath_tx_send_ampdu(sc, tid, skb, txctl); } else { - bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); + bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); if (!bf) return; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index c5a34ffe6459..a299d42da8e7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -28,6 +28,7 @@ #include <linux/uaccess.h> #include <linux/firmware.h> #include <linux/usb.h> +#include <linux/vmalloc.h> #include <net/cfg80211.h> #include <defs.h> @@ -1239,7 +1240,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) return -EINVAL; } - devinfo->image = kmalloc(fw->size, GFP_ATOMIC); /* plus nvram */ + devinfo->image = vmalloc(fw->size); /* plus nvram */ if (!devinfo->image) return -ENOMEM; @@ -1603,7 +1604,7 @@ static struct usb_driver brcmf_usbdrvr = { void brcmf_usb_exit(void) { usb_deregister(&brcmf_usbdrvr); - kfree(g_image.data); + vfree(g_image.data); g_image.data = NULL; g_image.len = 0; } diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index db6c6e528022..2463c0626438 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -137,11 +137,3 @@ config IWLWIFI_EXPERIMENTAL_MFP even if the microcode doesn't advertise it. Say Y only if you want to experiment with MFP. - -config IWLWIFI_UCODE16 - bool "support uCode 16.0" - depends on IWLWIFI - help - This option enables support for uCode version 16.0. - - Say Y if you want to use 16.0 microcode. diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 406f297a9a56..d615eacbf050 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -18,7 +18,6 @@ iwlwifi-objs += iwl-notif-wait.o iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o -iwlwifi-$(CONFIG_IWLWIFI_UCODE16) += iwl-phy-db.o iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-testmode.o diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 7f793417c787..8133105ac645 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -79,7 +79,7 @@ static const struct iwl_base_params iwl2000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, - .shadow_reg_enable = true, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ .hd_v2 = true, }; @@ -97,7 +97,7 @@ static const struct iwl_base_params iwl2030_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .shadow_reg_enable = true, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ .hd_v2 = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 381b02cf339c..19f7ee84ae89 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -86,7 +86,7 @@ static const struct iwl_base_params iwl6000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, - .shadow_reg_enable = true, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ }; static const struct iwl_base_params iwl6050_base_params = { @@ -102,7 +102,7 @@ static const struct iwl_base_params iwl6050_base_params = { .chain_noise_scale = 1500, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 1024, - .shadow_reg_enable = true, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ }; static const struct iwl_base_params iwl6000_g2_base_params = { @@ -118,7 +118,7 @@ static const struct iwl_base_params iwl6000_g2_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .shadow_reg_enable = true, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ }; static const struct iwl_ht_params iwl6000_ht_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 51e1a69ffdda..8cebd7c363fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -884,6 +884,7 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, if ((priv->bt_traffic_load != priv->last_bt_traffic_load) || (priv->bt_full_concurrent != full_concurrent)) { priv->bt_full_concurrent = full_concurrent; + priv->last_bt_traffic_load = priv->bt_traffic_load; /* Update uCode's rate table. */ tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index b31584e87bc7..aea07aab3c9e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -772,7 +772,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ~IWL_STA_DRIVER_ACTIVE; priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; - spin_unlock_bh(&priv->sta_lock); + continue; } /* * Rate scaling has already been initialized, send diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 3c72bad0ae56..d742900969ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -657,17 +657,17 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, return -EINVAL; } -static int alloc_pci_desc(struct iwl_drv *drv, - struct iwl_firmware_pieces *pieces, - enum iwl_ucode_type type) +static int iwl_alloc_ucode(struct iwl_drv *drv, + struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type) { int i; for (i = 0; i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i); i++) if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]), - get_sec(pieces, type, i))) - return -1; + get_sec(pieces, type, i))) + return -ENOMEM; return 0; } @@ -825,8 +825,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) - if (alloc_pci_desc(drv, &pieces, i)) - goto err_pci_alloc; + if (iwl_alloc_ucode(drv, &pieces, i)) + goto out_free_fw; /* Now that we can no longer fail, copy information */ @@ -866,7 +866,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw); if (!drv->op_mode) - goto out_unbind; + goto out_free_fw; return; @@ -877,7 +877,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) goto out_unbind; return; - err_pci_alloc: + out_free_fw: IWL_ERR(drv, "failed to allocate pci memory\n"); iwl_dealloc_ucode(drv); release_firmware(ucode_raw); diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c deleted file mode 100644 index f166955340fe..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ /dev/null @@ -1,288 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless <ilw@linux.intel.com> - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#include <linux/slab.h> -#include <linux/string.h> - -#include "iwl-debug.h" -#include "iwl-dev.h" - -#include "iwl-phy-db.h" - -#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */ - -struct iwl_phy_db *iwl_phy_db_init(struct device *dev) -{ - struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), - GFP_KERNEL); - - if (!phy_db) - return phy_db; - - phy_db->dev = dev; - - /* TODO: add default values of the phy db. */ - return phy_db; -} - -/* - * get phy db section: returns a pointer to a phy db section specified by - * type and channel group id. - */ -static struct iwl_phy_db_entry * -iwl_phy_db_get_section(struct iwl_phy_db *phy_db, - enum iwl_phy_db_section_type type, - u16 chg_id) -{ - if (!phy_db || type < 0 || type >= IWL_PHY_DB_MAX) - return NULL; - - switch (type) { - case IWL_PHY_DB_CFG: - return &phy_db->cfg; - case IWL_PHY_DB_CALIB_NCH: - return &phy_db->calib_nch; - case IWL_PHY_DB_CALIB_CH: - return &phy_db->calib_ch; - case IWL_PHY_DB_CALIB_CHG_PAPD: - if (chg_id < 0 || chg_id >= IWL_NUM_PAPD_CH_GROUPS) - return NULL; - return &phy_db->calib_ch_group_papd[chg_id]; - case IWL_PHY_DB_CALIB_CHG_TXP: - if (chg_id < 0 || chg_id >= IWL_NUM_TXP_CH_GROUPS) - return NULL; - return &phy_db->calib_ch_group_txp[chg_id]; - default: - return NULL; - } - return NULL; -} - -static void iwl_phy_db_free_section(struct iwl_phy_db *phy_db, - enum iwl_phy_db_section_type type, - u16 chg_id) -{ - struct iwl_phy_db_entry *entry = - iwl_phy_db_get_section(phy_db, type, chg_id); - if (!entry) - return; - - kfree(entry->data); - entry->data = NULL; - entry->size = 0; -} - -void iwl_phy_db_free(struct iwl_phy_db *phy_db) -{ - int i; - - if (!phy_db) - return; - - iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CFG, 0); - iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_NCH, 0); - iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CH, 0); - for (i = 0; i < IWL_NUM_PAPD_CH_GROUPS; i++) - iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_PAPD, i); - for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++) - iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_TXP, i); - - kfree(phy_db); -} - -int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, - enum iwl_phy_db_section_type type, u8 *data, - u16 size, gfp_t alloc_ctx) -{ - struct iwl_phy_db_entry *entry; - u16 chg_id = 0; - - if (!phy_db) - return -EINVAL; - - if (type == IWL_PHY_DB_CALIB_CHG_PAPD || - type == IWL_PHY_DB_CALIB_CHG_TXP) - chg_id = le16_to_cpup((__le16 *)data); - - entry = iwl_phy_db_get_section(phy_db, type, chg_id); - if (!entry) - return -EINVAL; - - kfree(entry->data); - entry->data = kmemdup(data, size, alloc_ctx); - if (!entry->data) { - entry->size = 0; - return -ENOMEM; - } - - entry->size = size; - - if (type == IWL_PHY_DB_CALIB_CH) { - phy_db->channel_num = le32_to_cpup((__le32 *)data); - phy_db->channel_size = - (size - CHANNEL_NUM_SIZE) / phy_db->channel_num; - } - - return 0; -} - -static int is_valid_channel(u16 ch_id) -{ - if (ch_id <= 14 || - (36 <= ch_id && ch_id <= 64 && ch_id % 4 == 0) || - (100 <= ch_id && ch_id <= 140 && ch_id % 4 == 0) || - (145 <= ch_id && ch_id <= 165 && ch_id % 4 == 1)) - return 1; - return 0; -} - -static u8 ch_id_to_ch_index(u16 ch_id) -{ - if (WARN_ON(!is_valid_channel(ch_id))) - return 0xff; - - if (ch_id <= 14) - return ch_id - 1; - if (ch_id <= 64) - return (ch_id + 20) / 4; - if (ch_id <= 140) - return (ch_id - 12) / 4; - return (ch_id - 13) / 4; -} - - -static u16 channel_id_to_papd(u16 ch_id) -{ - if (WARN_ON(!is_valid_channel(ch_id))) - return 0xff; - - if (1 <= ch_id && ch_id <= 14) - return 0; - if (36 <= ch_id && ch_id <= 64) - return 1; - if (100 <= ch_id && ch_id <= 140) - return 2; - return 3; -} - -static u16 channel_id_to_txp(struct iwl_phy_db *phy_db, u16 ch_id) -{ - struct iwl_phy_db_chg_txp *txp_chg; - int i; - u8 ch_index = ch_id_to_ch_index(ch_id); - if (ch_index == 0xff) - return 0xff; - - for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++) { - txp_chg = (void *)phy_db->calib_ch_group_txp[i].data; - if (!txp_chg) - return 0xff; - /* - * Looking for the first channel group that its max channel is - * higher then wanted channel. - */ - if (le16_to_cpu(txp_chg->max_channel_idx) >= ch_index) - return i; - } - return 0xff; -} - -int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db, - enum iwl_phy_db_section_type type, u8 **data, - u16 *size, u16 ch_id) -{ - struct iwl_phy_db_entry *entry; - u32 channel_num; - u32 channel_size; - u16 ch_group_id = 0; - u16 index; - - if (!phy_db) - return -EINVAL; - - /* find wanted channel group */ - if (type == IWL_PHY_DB_CALIB_CHG_PAPD) - ch_group_id = channel_id_to_papd(ch_id); - else if (type == IWL_PHY_DB_CALIB_CHG_TXP) - ch_group_id = channel_id_to_txp(phy_db, ch_id); - - entry = iwl_phy_db_get_section(phy_db, type, ch_group_id); - if (!entry) - return -EINVAL; - - if (type == IWL_PHY_DB_CALIB_CH) { - index = ch_id_to_ch_index(ch_id); - channel_num = phy_db->channel_num; - channel_size = phy_db->channel_size; - if (index >= channel_num) { - IWL_ERR(phy_db, "Wrong channel number %d", ch_id); - return -EINVAL; - } - *data = entry->data + CHANNEL_NUM_SIZE + index * channel_size; - *size = channel_size; - } else { - *data = entry->data; - *size = entry->size; - } - return 0; -} diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h deleted file mode 100644 index c34c6a9303ab..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.h +++ /dev/null @@ -1,129 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless <ilw@linux.intel.com> - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#ifndef __IWL_PHYDB_H__ -#define __IWL_PHYDB_H__ - -#include <linux/types.h> - -#define IWL_NUM_PAPD_CH_GROUPS 4 -#define IWL_NUM_TXP_CH_GROUPS 8 - -struct iwl_phy_db_entry { - u16 size; - u8 *data; -}; - -struct iwl_shared; - -/** - * struct iwl_phy_db - stores phy configuration and calibration data. - * - * @cfg: phy configuration. - * @calib_nch: non channel specific calibration data. - * @calib_ch: channel specific calibration data. - * @calib_ch_group_papd: calibration data related to papd channel group. - * @calib_ch_group_txp: calibration data related to tx power chanel group. - */ -struct iwl_phy_db { - struct iwl_phy_db_entry cfg; - struct iwl_phy_db_entry calib_nch; - struct iwl_phy_db_entry calib_ch; - struct iwl_phy_db_entry calib_ch_group_papd[IWL_NUM_PAPD_CH_GROUPS]; - struct iwl_phy_db_entry calib_ch_group_txp[IWL_NUM_TXP_CH_GROUPS]; - - u32 channel_num; - u32 channel_size; - - /* for an access to the logger */ - struct device *dev; -}; - -enum iwl_phy_db_section_type { - IWL_PHY_DB_CFG = 1, - IWL_PHY_DB_CALIB_NCH, - IWL_PHY_DB_CALIB_CH, - IWL_PHY_DB_CALIB_CHG_PAPD, - IWL_PHY_DB_CALIB_CHG_TXP, - IWL_PHY_DB_MAX -}; - -/* for parsing of tx power channel group data that comes from the firmware*/ -struct iwl_phy_db_chg_txp { - __le32 space; - __le16 max_channel_idx; -} __packed; - -struct iwl_phy_db *iwl_phy_db_init(struct device *dev); - -void iwl_phy_db_free(struct iwl_phy_db *phy_db); - -int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, - enum iwl_phy_db_section_type type, u8 *data, - u16 size, gfp_t alloc_ctx); - -int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db, - enum iwl_phy_db_section_type type, u8 **data, - u16 *size, u16 ch_id); - -#endif /* __IWL_PHYDB_H__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 6213c05a4b52..e959207c630a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -347,7 +347,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int queue, int fifo, int sta_id, int tid, int frame_limit, u16 ssn); void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, - int index, enum dma_data_direction dma_dir); + enum dma_data_direction dma_dir); int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, struct sk_buff_head *skbs); int iwl_queue_space(const struct iwl_queue *q); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 21a8a672fbb2..a8750238ee09 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -204,33 +204,39 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, for (i = 1; i < num_tbs; i++) dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i), iwl_tfd_tb_get_len(tfd, i), dma_dir); + + tfd->num_tbs = 0; } /** * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] * @trans - transport private data * @txq - tx queue - * @index - the index of the TFD to be freed - *@dma_dir - the direction of the DMA mapping + * @dma_dir - the direction of the DMA mapping * * Does NOT advance any TFD circular buffer read/write indexes * Does NOT free the TFD itself (which is within circular buffer) */ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, - int index, enum dma_data_direction dma_dir) + enum dma_data_direction dma_dir) { struct iwl_tfd *tfd_tmp = txq->tfds; + /* rd_ptr is bounded by n_bd and idx is bounded by n_window */ + int rd_ptr = txq->q.read_ptr; + int idx = get_cmd_index(&txq->q, rd_ptr); + lockdep_assert_held(&txq->lock); - iwlagn_unmap_tfd(trans, &txq->entries[index].meta, - &tfd_tmp[index], dma_dir); + /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ + iwlagn_unmap_tfd(trans, &txq->entries[idx].meta, + &tfd_tmp[rd_ptr], dma_dir); /* free SKB */ if (txq->entries) { struct sk_buff *skb; - skb = txq->entries[index].skb; + skb = txq->entries[idx].skb; /* Can be called from irqs-disabled context * If skb is not NULL, it means that the whole queue is being @@ -238,7 +244,7 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, */ if (skb) { iwl_op_mode_free_skb(trans->op_mode, skb); - txq->entries[index].skb = NULL; + txq->entries[idx].skb = NULL; } } } @@ -973,7 +979,7 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, iwlagn_txq_inval_byte_cnt_tbl(trans, txq); - iwlagn_txq_free_tfd(trans, txq, txq->q.read_ptr, DMA_TO_DEVICE); + iwlagn_txq_free_tfd(trans, txq, DMA_TO_DEVICE); freed++; } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 2e57161854b9..ec6fb395b84d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -435,9 +435,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) spin_lock_bh(&txq->lock); while (q->write_ptr != q->read_ptr) { - /* The read_ptr needs to bound by q->n_window */ - iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr), - dma_dir); + iwlagn_txq_free_tfd(trans, txq, dma_dir); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } spin_unlock_bh(&txq->lock); diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c index 1b851f650e07..e2750a12c6f1 100644 --- a/drivers/net/wireless/ti/wl1251/sdio.c +++ b/drivers/net/wireless/ti/wl1251/sdio.c @@ -260,6 +260,7 @@ static int wl1251_sdio_probe(struct sdio_func *func, } if (wl->irq) { + irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); @@ -267,7 +268,6 @@ static int wl1251_sdio_probe(struct sdio_func *func, } irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); - disable_irq(wl->irq); wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c index 6248c354fc5c..87f6305bda2c 100644 --- a/drivers/net/wireless/ti/wl1251/spi.c +++ b/drivers/net/wireless/ti/wl1251/spi.c @@ -281,6 +281,7 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi) wl->use_eeprom = pdata->use_eeprom; + irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); @@ -289,8 +290,6 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi) irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); - disable_irq(wl->irq); - ret = wl1251_init_ieee80211(wl); if (ret) goto out_irq; diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c index 509aa881d790..f3d6fa508269 100644 --- a/drivers/net/wireless/ti/wlcore/acx.c +++ b/drivers/net/wireless/ti/wlcore/acx.c @@ -1715,6 +1715,7 @@ out: } +#ifdef CONFIG_PM /* Set the global behaviour of RX filters - On/Off + default action */ int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, enum rx_filter_action action) @@ -1794,3 +1795,4 @@ out: kfree(acx); return ret; } +#endif /* CONFIG_PM */ diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h index 8106b2ebfe60..e6a74869a5ff 100644 --- a/drivers/net/wireless/ti/wlcore/acx.h +++ b/drivers/net/wireless/ti/wlcore/acx.h @@ -1330,9 +1330,11 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); int wl1271_acx_fm_coex(struct wl1271 *wl); int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl); int wl12xx_acx_config_hangover(struct wl1271 *wl); + +#ifdef CONFIG_PM int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, enum rx_filter_action action); int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable, struct wl12xx_rx_filter *filter); - +#endif /* CONFIG_PM */ #endif /* __WL1271_ACX_H__ */ diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c index 1f1d9488dfb6..d6a3c6b07827 100644 --- a/drivers/net/wireless/ti/wlcore/rx.c +++ b/drivers/net/wireless/ti/wlcore/rx.c @@ -279,6 +279,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status) wl12xx_rearm_rx_streaming(wl, active_hlids); } +#ifdef CONFIG_PM int wl1271_rx_filter_enable(struct wl1271 *wl, int index, bool enable, struct wl12xx_rx_filter *filter) @@ -314,3 +315,4 @@ void wl1271_rx_filter_clear_all(struct wl1271 *wl) wl1271_rx_filter_enable(wl, i, 0, NULL); } } +#endif /* CONFIG_PM */ diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 2596401308a8..f4a6fcaeffb1 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -325,8 +325,7 @@ unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb) unsigned int count; int i, copy_off; - count = DIV_ROUND_UP( - offset_in_page(skb->data)+skb_headlen(skb), PAGE_SIZE); + count = DIV_ROUND_UP(skb_headlen(skb), PAGE_SIZE); copy_off = skb_headlen(skb) % PAGE_SIZE; diff --git a/drivers/nfc/pn544_hci.c b/drivers/nfc/pn544_hci.c index 46f4a9f9f5e4..281f18c2fb82 100644 --- a/drivers/nfc/pn544_hci.c +++ b/drivers/nfc/pn544_hci.c @@ -232,7 +232,7 @@ static int pn544_hci_i2c_write(struct i2c_client *client, u8 *buf, int len) static int check_crc(u8 *buf, int buflen) { - u8 len; + int len; u16 crc; len = buf[0] + 1; diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 33a6743ddc55..c05da00583f0 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -10,8 +10,6 @@ #ifndef DASD_INT_H #define DASD_INT_H -#ifdef __KERNEL__ - /* we keep old device allocation scheme; IOW, minors are still in 0..255 */ #define DASD_PER_MAJOR (1U << (MINORBITS - DASD_PARTN_BITS)) #define DASD_PARTN_MASK ((1 << DASD_PARTN_BITS) - 1) @@ -791,6 +789,4 @@ static inline int dasd_eer_enabled(struct dasd_device *device) #define dasd_eer_enabled(d) (0) #endif /* CONFIG_DASD_ERR */ -#endif /* __KERNEL__ */ - #endif /* DASD_H */ diff --git a/drivers/s390/char/sclp_sdias.c b/drivers/s390/char/sclp_sdias.c index 69e6c50d4cfb..50f7115990ff 100644 --- a/drivers/s390/char/sclp_sdias.c +++ b/drivers/s390/char/sclp_sdias.c @@ -211,7 +211,7 @@ int sclp_sdias_copy(void *dest, int start_blk, int nr_blks) sccb.evbuf.event_qual = EQ_STORE_DATA; sccb.evbuf.data_id = DI_FCP_DUMP; sccb.evbuf.event_id = 4712; -#ifdef __s390x__ +#ifdef CONFIG_64BIT sccb.evbuf.asa_size = ASA_SIZE_64; #else sccb.evbuf.asa_size = ASA_SIZE_32; diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c index 69adc80c98cd..67feac9e6ebb 100644 --- a/drivers/tty/tty_mutex.c +++ b/drivers/tty/tty_mutex.c @@ -6,11 +6,17 @@ /* Legacy tty mutex glue */ +enum { + TTY_MUTEX_NORMAL, + TTY_MUTEX_NESTED, +}; + /* * Getting the big tty mutex. */ -void __lockfunc tty_lock(struct tty_struct *tty) +static void __lockfunc tty_lock_nested(struct tty_struct *tty, + unsigned int subclass) { if (tty->magic != TTY_MAGIC) { printk(KERN_ERR "L Bad %p\n", tty); @@ -18,7 +24,12 @@ void __lockfunc tty_lock(struct tty_struct *tty) return; } tty_kref_get(tty); - mutex_lock(&tty->legacy_mutex); + mutex_lock_nested(&tty->legacy_mutex, subclass); +} + +void __lockfunc tty_lock(struct tty_struct *tty) +{ + return tty_lock_nested(tty, TTY_MUTEX_NORMAL); } EXPORT_SYMBOL(tty_lock); @@ -43,11 +54,11 @@ void __lockfunc tty_lock_pair(struct tty_struct *tty, { if (tty < tty2) { tty_lock(tty); - tty_lock(tty2); + tty_lock_nested(tty2, TTY_MUTEX_NESTED); } else { if (tty2 && tty2 != tty) tty_lock(tty2); - tty_lock(tty); + tty_lock_nested(tty, TTY_MUTEX_NESTED); } } EXPORT_SYMBOL(tty_lock_pair); diff --git a/fs/direct-io.c b/fs/direct-io.c index f4aadd15b613..0c85fae37666 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -145,50 +145,6 @@ struct dio { static struct kmem_cache *dio_cache __read_mostly; -static void __inode_dio_wait(struct inode *inode) -{ - wait_queue_head_t *wq = bit_waitqueue(&inode->i_state, __I_DIO_WAKEUP); - DEFINE_WAIT_BIT(q, &inode->i_state, __I_DIO_WAKEUP); - - do { - prepare_to_wait(wq, &q.wait, TASK_UNINTERRUPTIBLE); - if (atomic_read(&inode->i_dio_count)) - schedule(); - } while (atomic_read(&inode->i_dio_count)); - finish_wait(wq, &q.wait); -} - -/** - * inode_dio_wait - wait for outstanding DIO requests to finish - * @inode: inode to wait for - * - * Waits for all pending direct I/O requests to finish so that we can - * proceed with a truncate or equivalent operation. - * - * Must be called under a lock that serializes taking new references - * to i_dio_count, usually by inode->i_mutex. - */ -void inode_dio_wait(struct inode *inode) -{ - if (atomic_read(&inode->i_dio_count)) - __inode_dio_wait(inode); -} -EXPORT_SYMBOL(inode_dio_wait); - -/* - * inode_dio_done - signal finish of a direct I/O requests - * @inode: inode the direct I/O happens on - * - * This is called once we've finished processing a direct I/O request, - * and is used to wake up callers waiting for direct I/O to be quiesced. - */ -void inode_dio_done(struct inode *inode) -{ - if (atomic_dec_and_test(&inode->i_dio_count)) - wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); -} -EXPORT_SYMBOL(inode_dio_done); - /* * How many pages are in the queue? */ diff --git a/fs/inode.c b/fs/inode.c index 6bc8761cc333..c474c1d7062b 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1748,3 +1748,50 @@ bool inode_owner_or_capable(const struct inode *inode) return false; } EXPORT_SYMBOL(inode_owner_or_capable); + +/* + * Direct i/o helper functions + */ +static void __inode_dio_wait(struct inode *inode) +{ + wait_queue_head_t *wq = bit_waitqueue(&inode->i_state, __I_DIO_WAKEUP); + DEFINE_WAIT_BIT(q, &inode->i_state, __I_DIO_WAKEUP); + + do { + prepare_to_wait(wq, &q.wait, TASK_UNINTERRUPTIBLE); + if (atomic_read(&inode->i_dio_count)) + schedule(); + } while (atomic_read(&inode->i_dio_count)); + finish_wait(wq, &q.wait); +} + +/** + * inode_dio_wait - wait for outstanding DIO requests to finish + * @inode: inode to wait for + * + * Waits for all pending direct I/O requests to finish so that we can + * proceed with a truncate or equivalent operation. + * + * Must be called under a lock that serializes taking new references + * to i_dio_count, usually by inode->i_mutex. + */ +void inode_dio_wait(struct inode *inode) +{ + if (atomic_read(&inode->i_dio_count)) + __inode_dio_wait(inode); +} +EXPORT_SYMBOL(inode_dio_wait); + +/* + * inode_dio_done - signal finish of a direct I/O requests + * @inode: inode the direct I/O happens on + * + * This is called once we've finished processing a direct I/O request, + * and is used to wake up callers waiting for direct I/O to be quiesced. + */ +void inode_dio_done(struct inode *inode) +{ + if (atomic_dec_and_test(&inode->i_dio_count)) + wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); +} +EXPORT_SYMBOL(inode_dio_done); diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 23d170bc44f4..ad2775d3e219 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -454,6 +454,12 @@ out: return result; } +static void nfs_inode_dio_write_done(struct inode *inode) +{ + nfs_zap_mapping(inode, inode->i_mapping); + inode_dio_done(inode); +} + #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) { @@ -564,7 +570,7 @@ static void nfs_direct_write_schedule_work(struct work_struct *work) nfs_direct_write_reschedule(dreq); break; default: - nfs_zap_mapping(dreq->inode, dreq->inode->i_mapping); + nfs_inode_dio_write_done(dreq->inode); nfs_direct_complete(dreq); } } @@ -581,7 +587,7 @@ static void nfs_direct_write_schedule_work(struct work_struct *work) static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode) { - nfs_zap_mapping(inode, inode->i_mapping); + nfs_inode_dio_write_done(inode); nfs_direct_complete(dreq); } #endif @@ -766,14 +772,16 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, loff_t pos) { struct nfs_pageio_descriptor desc; + struct inode *inode = dreq->inode; ssize_t result = 0; size_t requested_bytes = 0; unsigned long seg; - nfs_pageio_init_write(&desc, dreq->inode, FLUSH_COND_STABLE, + nfs_pageio_init_write(&desc, inode, FLUSH_COND_STABLE, &nfs_direct_write_completion_ops); desc.pg_dreq = dreq; get_dreq(dreq); + atomic_inc(&inode->i_dio_count); for (seg = 0; seg < nr_segs; seg++) { const struct iovec *vec = &iov[seg]; @@ -793,6 +801,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, * generic layer handle the completion. */ if (requested_bytes == 0) { + inode_dio_done(inode); nfs_direct_req_release(dreq); return result < 0 ? result : -EIO; } diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 2f6f78c4b42d..e605d695dbcb 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -418,8 +418,10 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) return 0; /* Write all dirty data */ - if (S_ISREG(inode->i_mode)) + if (S_ISREG(inode->i_mode)) { + nfs_inode_dio_wait(inode); nfs_wb_all(inode); + } fattr = nfs_alloc_fattr(); if (fattr == NULL) @@ -503,6 +505,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) /* Flush out writes to the server in order to update c/mtime. */ if (S_ISREG(inode->i_mode)) { + nfs_inode_dio_wait(inode); err = filemap_write_and_wait(inode->i_mapping); if (err) goto out; diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 1848a7275592..18f99ef71343 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -369,6 +369,10 @@ extern int nfs_migrate_page(struct address_space *, /* direct.c */ void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, struct nfs_direct_req *dreq); +static inline void nfs_inode_dio_wait(struct inode *inode) +{ + inode_dio_wait(inode); +} /* nfs4proc.c */ extern void __nfs4_read_done_cb(struct nfs_read_data *); diff --git a/include/linux/fs.h b/include/linux/fs.h index 038076b27ea4..598a5892ff2b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2453,8 +2453,6 @@ enum { }; void dio_end_io(struct bio *bio, int error); -void inode_dio_wait(struct inode *inode); -void inode_dio_done(struct inode *inode); ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, struct block_device *bdev, const struct iovec *iov, loff_t offset, @@ -2469,12 +2467,11 @@ static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb, offset, nr_segs, get_block, NULL, NULL, DIO_LOCKING | DIO_SKIP_HOLES); } -#else -static inline void inode_dio_wait(struct inode *inode) -{ -} #endif +void inode_dio_wait(struct inode *inode); +void inode_dio_done(struct inode *inode); + extern const struct file_operations generic_ro_fops; #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) diff --git a/include/linux/genetlink.h b/include/linux/genetlink.h index 73c28dea10ae..7a114016ac7d 100644 --- a/include/linux/genetlink.h +++ b/include/linux/genetlink.h @@ -110,6 +110,9 @@ extern int lockdep_genl_is_held(void); #define genl_dereference(p) \ rcu_dereference_protected(p, lockdep_genl_is_held()) +#define MODULE_ALIAS_GENL_FAMILY(family)\ + MODULE_ALIAS_NET_PF_PROTO_NAME(PF_NETLINK, NETLINK_GENERIC, "-family-" family) + #endif /* __KERNEL__ */ #endif /* __LINUX_GENERIC_NETLINK_H */ diff --git a/include/linux/net.h b/include/linux/net.h index 2d7510f38934..e9ac2df079ba 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -313,5 +313,8 @@ extern int kernel_sock_shutdown(struct socket *sock, MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto) \ "-type-" __stringify(type)) +#define MODULE_ALIAS_NET_PF_PROTO_NAME(pf, proto, name) \ + MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto) \ + name) #endif /* __KERNEL__ */ #endif /* _LINUX_NET_H */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index e7fd468f7126..d94cb1431519 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2795,15 +2795,15 @@ do { \ #define netif_info(priv, type, dev, fmt, args...) \ netif_level(info, priv, type, dev, fmt, ##args) -#if defined(DEBUG) -#define netif_dbg(priv, type, dev, format, args...) \ - netif_printk(priv, type, KERN_DEBUG, dev, format, ##args) -#elif defined(CONFIG_DYNAMIC_DEBUG) +#if defined(CONFIG_DYNAMIC_DEBUG) #define netif_dbg(priv, type, netdev, format, args...) \ do { \ if (netif_msg_##type(priv)) \ dynamic_netdev_dbg(netdev, format, ##args); \ } while (0) +#elif defined(DEBUG) +#define netif_dbg(priv, type, dev, format, args...) \ + netif_printk(priv, type, KERN_DEBUG, dev, format, ##args) #else #define netif_dbg(priv, type, dev, format, args...) \ ({ \ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 0e501714d47f..b534a1be540a 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1896,8 +1896,6 @@ static inline int __skb_cow(struct sk_buff *skb, unsigned int headroom, { int delta = 0; - if (headroom < NET_SKB_PAD) - headroom = NET_SKB_PAD; if (headroom > skb_headroom(skb)) delta = headroom - skb_headroom(skb); diff --git a/include/net/dst.h b/include/net/dst.h index bed833d9796a..8197eadca819 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -60,6 +60,7 @@ struct dst_entry { #define DST_NOCOUNT 0x0020 #define DST_NOPEER 0x0040 #define DST_FAKE_RTABLE 0x0080 +#define DST_XFRM_TUNNEL 0x0100 short error; short obsolete; diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 3252e7e0a005..ea5fb9fcc3f5 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -468,3 +468,4 @@ module_exit(exit_net_drop_monitor); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Neil Horman <nhorman@tuxdriver.com>"); +MODULE_ALIAS_GENL_FAMILY("NET_DM"); diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 89a47b35905d..cb982a61536f 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -459,28 +459,22 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu) struct esp_data *esp = x->data; u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4); u32 align = max_t(u32, blksize, esp->padlen); - u32 rem; - - mtu -= x->props.header_len + crypto_aead_authsize(esp->aead); - rem = mtu & (align - 1); - mtu &= ~(align - 1); + unsigned int net_adj; switch (x->props.mode) { - case XFRM_MODE_TUNNEL: - break; - default: case XFRM_MODE_TRANSPORT: - /* The worst case */ - mtu -= blksize - 4; - mtu += min_t(u32, blksize - 4, rem); - break; case XFRM_MODE_BEET: - /* The worst case. */ - mtu += min_t(u32, IPV4_BEET_PHMAXLEN, rem); + net_adj = sizeof(struct iphdr); break; + case XFRM_MODE_TUNNEL: + net_adj = 0; + break; + default: + BUG(); } - return mtu - 2; + return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) - + net_adj) & ~(align - 1)) + (net_adj - 2); } static void esp4_err(struct sk_buff *skb, u32 info) diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 1e62b7557b00..db1521fcda5b 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -413,19 +413,15 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu) struct esp_data *esp = x->data; u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4); u32 align = max_t(u32, blksize, esp->padlen); - u32 rem; + unsigned int net_adj; - mtu -= x->props.header_len + crypto_aead_authsize(esp->aead); - rem = mtu & (align - 1); - mtu &= ~(align - 1); - - if (x->props.mode != XFRM_MODE_TUNNEL) { - u32 padsize = ((blksize - 1) & 7) + 1; - mtu -= blksize - padsize; - mtu += min_t(u32, blksize - padsize, rem); - } + if (x->props.mode != XFRM_MODE_TUNNEL) + net_adj = sizeof(struct ipv6hdr); + else + net_adj = 0; - return mtu - 2; + return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) - + net_adj) & ~(align - 1)) + (net_adj - 2); } static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d99fdc699625..17b8c67998bb 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1187,6 +1187,29 @@ static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src, return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; } +static void ip6_append_data_mtu(int *mtu, + int *maxfraglen, + unsigned int fragheaderlen, + struct sk_buff *skb, + struct rt6_info *rt) +{ + if (!(rt->dst.flags & DST_XFRM_TUNNEL)) { + if (skb == NULL) { + /* first fragment, reserve header_len */ + *mtu = *mtu - rt->dst.header_len; + + } else { + /* + * this fragment is not first, the headers + * space is regarded as data space. + */ + *mtu = dst_mtu(rt->dst.path); + } + *maxfraglen = ((*mtu - fragheaderlen) & ~7) + + fragheaderlen - sizeof(struct frag_hdr); + } +} + int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), void *from, int length, int transhdrlen, @@ -1196,7 +1219,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); struct inet_cork *cork; - struct sk_buff *skb; + struct sk_buff *skb, *skb_prev = NULL; unsigned int maxfraglen, fragheaderlen; int exthdrlen; int dst_exthdrlen; @@ -1253,8 +1276,12 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, inet->cork.fl.u.ip6 = *fl6; np->cork.hop_limit = hlimit; np->cork.tclass = tclass; - mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? - rt->dst.dev->mtu : dst_mtu(&rt->dst); + if (rt->dst.flags & DST_XFRM_TUNNEL) + mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? + rt->dst.dev->mtu : dst_mtu(&rt->dst); + else + mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? + rt->dst.dev->mtu : dst_mtu(rt->dst.path); if (np->frag_size < mtu) { if (np->frag_size) mtu = np->frag_size; @@ -1350,25 +1377,27 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, unsigned int fraglen; unsigned int fraggap; unsigned int alloclen; - struct sk_buff *skb_prev; alloc_new_skb: - skb_prev = skb; - /* There's no room in the current skb */ - if (skb_prev) - fraggap = skb_prev->len - maxfraglen; + if (skb) + fraggap = skb->len - maxfraglen; else fraggap = 0; + /* update mtu and maxfraglen if necessary */ + if (skb == NULL || skb_prev == NULL) + ip6_append_data_mtu(&mtu, &maxfraglen, + fragheaderlen, skb, rt); + + skb_prev = skb; /* * If remaining data exceeds the mtu, * we know we need more fragment(s). */ datalen = length + fraggap; - if (datalen > (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen) - datalen = maxfraglen - fragheaderlen; - fraglen = datalen + fragheaderlen; + if (datalen > (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen) + datalen = maxfraglen - fragheaderlen - rt->dst.trailer_len; if ((flags & MSG_MORE) && !(rt->dst.dev->features&NETIF_F_SG)) alloclen = mtu; @@ -1377,13 +1406,16 @@ alloc_new_skb: alloclen += dst_exthdrlen; - /* - * The last fragment gets additional space at tail. - * Note: we overallocate on fragments with MSG_MODE - * because we have no idea if we're the last one. - */ - if (datalen == length + fraggap) - alloclen += rt->dst.trailer_len; + if (datalen != length + fraggap) { + /* + * this is not the last fragment, the trailer + * space is regarded as data space. + */ + datalen += rt->dst.trailer_len; + } + + alloclen += rt->dst.trailer_len; + fraglen = datalen + fragheaderlen; /* * We just reserve space for fragment header. diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 889f5d13d7ba..70614e7affab 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -239,9 +239,16 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) { struct inet_sock *inet = inet_sk(sk); struct sockaddr_l2tpip *addr = (struct sockaddr_l2tpip *) uaddr; - int ret = -EINVAL; + int ret; int chk_addr_ret; + if (!sock_flag(sk, SOCK_ZAPPED)) + return -EINVAL; + if (addr_len < sizeof(struct sockaddr_l2tpip)) + return -EINVAL; + if (addr->l2tp_family != AF_INET) + return -EINVAL; + ret = -EADDRINUSE; read_lock_bh(&l2tp_ip_lock); if (__l2tp_ip_bind_lookup(&init_net, addr->l2tp_addr.s_addr, sk->sk_bound_dev_if, addr->l2tp_conn_id)) @@ -272,6 +279,8 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) sk_del_node_init(sk); write_unlock_bh(&l2tp_ip_lock); ret = 0; + sock_reset_flag(sk, SOCK_ZAPPED); + out: release_sock(sk); @@ -288,6 +297,9 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len struct sockaddr_l2tpip *lsa = (struct sockaddr_l2tpip *) uaddr; int rc; + if (sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */ + return -EINVAL; + if (addr_len < sizeof(*lsa)) return -EINVAL; @@ -311,6 +323,14 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len return rc; } +static int l2tp_ip_disconnect(struct sock *sk, int flags) +{ + if (sock_flag(sk, SOCK_ZAPPED)) + return 0; + + return udp_disconnect(sk, flags); +} + static int l2tp_ip_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { @@ -530,7 +550,7 @@ static struct proto l2tp_ip_prot = { .close = l2tp_ip_close, .bind = l2tp_ip_bind, .connect = l2tp_ip_connect, - .disconnect = udp_disconnect, + .disconnect = l2tp_ip_disconnect, .ioctl = udp_ioctl, .destroy = l2tp_ip_destroy_sock, .setsockopt = ip_setsockopt, diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 0291d8d85f30..35e1e4bde587 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -258,6 +258,10 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) int addr_type; int err; + if (!sock_flag(sk, SOCK_ZAPPED)) + return -EINVAL; + if (addr->l2tp_family != AF_INET6) + return -EINVAL; if (addr_len < sizeof(*addr)) return -EINVAL; @@ -331,6 +335,7 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) sk_del_node_init(sk); write_unlock_bh(&l2tp_ip6_lock); + sock_reset_flag(sk, SOCK_ZAPPED); release_sock(sk); return 0; @@ -354,6 +359,9 @@ static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_type; int rc; + if (sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */ + return -EINVAL; + if (addr_len < sizeof(*lsa)) return -EINVAL; @@ -383,6 +391,14 @@ static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr, return rc; } +static int l2tp_ip6_disconnect(struct sock *sk, int flags) +{ + if (sock_flag(sk, SOCK_ZAPPED)) + return 0; + + return udp_disconnect(sk, flags); +} + static int l2tp_ip6_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { @@ -689,7 +705,7 @@ static struct proto l2tp_ip6_prot = { .close = l2tp_ip6_close, .bind = l2tp_ip6_bind, .connect = l2tp_ip6_connect, - .disconnect = udp_disconnect, + .disconnect = l2tp_ip6_disconnect, .ioctl = udp_ioctl, .destroy = l2tp_ip6_destroy_sock, .setsockopt = ipv6_setsockopt, diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 8577264378fe..ddc553e76671 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -923,5 +923,4 @@ MODULE_AUTHOR("James Chapman <jchapman@katalix.com>"); MODULE_DESCRIPTION("L2TP netlink"); MODULE_LICENSE("GPL"); MODULE_VERSION("1.0"); -MODULE_ALIAS("net-pf-" __stringify(PF_NETLINK) "-proto-" \ - __stringify(NETLINK_GENERIC) "-type-" "l2tp"); +MODULE_ALIAS_GENL_FAMILY("l2tp"); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b3b3c264ff66..04c306308987 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1522,6 +1522,8 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) * anymore. The timeout will be reset if the frame is ACKed by * the AP. */ + ifmgd->probe_send_count++; + if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { ifmgd->nullfunc_failed = false; ieee80211_send_nullfunc(sdata->local, sdata, 0); @@ -1538,7 +1540,6 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) 0, (u32) -1, true, false); } - ifmgd->probe_send_count++; ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); run_again(ifmgd, ifmgd->probe_timeout); if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 5f827a6b0d8d..847215bb2a6f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -153,7 +153,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, /* Don't calculate ACKs for QoS Frames with NoAck Policy set */ if (ieee80211_is_data_qos(hdr->frame_control) && - *(ieee80211_get_qos_ctl(hdr)) | IEEE80211_QOS_CTL_ACK_POLICY_NOACK) + *(ieee80211_get_qos_ctl(hdr)) & IEEE80211_QOS_CTL_ACK_POLICY_NOACK) dur = 0; else /* Time needed to transmit ACK diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 22f2216b397e..a44c6807df01 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1371,6 +1371,12 @@ int ieee80211_reconfig(struct ieee80211_local *local) } } + /* add back keys */ + list_for_each_entry(sdata, &local->interfaces, list) + if (ieee80211_sdata_running(sdata)) + ieee80211_enable_keys(sdata); + + wake_up: /* * Clear the WLAN_STA_BLOCK_BA flag so new aggregation * sessions can be established after a resume. @@ -1392,12 +1398,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) mutex_unlock(&local->sta_mtx); } - /* add back keys */ - list_for_each_entry(sdata, &local->interfaces, list) - if (ieee80211_sdata_running(sdata)) - ieee80211_enable_keys(sdata); - - wake_up: ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_SUSPEND); diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 8340ace837f2..2cc7c1ee7690 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -836,7 +836,7 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info) #ifdef CONFIG_MODULES if (res == NULL) { genl_unlock(); - request_module("net-pf-%d-proto-%d-type-%s", + request_module("net-pf-%d-proto-%d-family-%s", PF_NETLINK, NETLINK_GENERIC, name); genl_lock(); res = genl_family_find_byname(name); diff --git a/net/rds/ib.h b/net/rds/ib.h index edfaaaf164eb..8d2b3d5a7c21 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -186,8 +186,7 @@ struct rds_ib_device { struct work_struct free_work; }; -#define pcidev_to_node(pcidev) pcibus_to_node(pcidev->bus) -#define ibdev_to_node(ibdev) pcidev_to_node(to_pci_dev(ibdev->dma_device)) +#define ibdev_to_node(ibdev) dev_to_node(ibdev->dma_device) #define rdsibdev_to_node(rdsibdev) ibdev_to_node(rdsibdev->dev) /* bits for i_ack_flags */ diff --git a/net/wanrouter/Kconfig b/net/wanrouter/Kconfig index 61ceae0b9566..a157a2e64e18 100644 --- a/net/wanrouter/Kconfig +++ b/net/wanrouter/Kconfig @@ -3,7 +3,7 @@ # config WAN_ROUTER - tristate "WAN router" + tristate "WAN router (DEPRECATED)" depends on EXPERIMENTAL ---help--- Wide Area Networks (WANs), such as X.25, frame relay and leased diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index c53e8f42aa75..ccfbd328a69d 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1921,6 +1921,9 @@ no_transform: } ok: xfrm_pols_put(pols, drop_pols); + if (dst && dst->xfrm && + dst->xfrm->props.mode == XFRM_MODE_TUNNEL) + dst->flags |= DST_XFRM_TUNNEL; return dst; nopol: |