diff --git a/.mailmap b/.mailmap index 2909c33bc54e..658003aa9446 100644 --- a/.mailmap +++ b/.mailmap @@ -111,6 +111,7 @@ Uwe Kleine-König Uwe Kleine-König Uwe Kleine-König Valdis Kletnieks +Viresh Kumar Takashi YOSHII Yusuke Goda Gustavo Padovan diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 5bc8a476c15e..cfedf63cce15 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -219,6 +219,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_scale What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_scale What: /sys/bus/iio/devices/iio:deviceX/in_voltage_scale What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_scale What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale What: /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale @@ -273,6 +274,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available What: /sys/.../iio:deviceX/in_voltageX_scale_available What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available What: /sys/.../iio:deviceX/out_voltageX_scale_available +What: /sys/.../iio:deviceX/out_altvoltageX_scale_available What: /sys/.../iio:deviceX/in_capacitance_scale_available KernelVersion: 2.635 Contact: linux-iio@vger.kernel.org @@ -298,14 +300,19 @@ Description: gives the 3dB frequency of the filter in Hz. What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_raw +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_raw KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Raw (unscaled, no bias etc.) output voltage for channel Y. The number must always be specified and unique if the output corresponds to a single channel. + While DAC like devices typically use out_voltage, + a continuous frequency generating device, such as + a DDS or PLL should use out_altvoltage. What: /sys/bus/iio/devices/iio:deviceX/out_voltageY&Z_raw +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY&Z_raw KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: @@ -316,6 +323,8 @@ Description: What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown_mode What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown_mode +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown_mode +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown_mode KernelVersion: 2.6.38 Contact: linux-iio@vger.kernel.org Description: @@ -330,6 +339,8 @@ Description: What: /sys/.../iio:deviceX/out_votlageY_powerdown_mode_available What: /sys/.../iio:deviceX/out_voltage_powerdown_mode_available +What: /sys/.../iio:deviceX/out_altvotlageY_powerdown_mode_available +What: /sys/.../iio:deviceX/out_altvoltage_powerdown_mode_available KernelVersion: 2.6.38 Contact: linux-iio@vger.kernel.org Description: @@ -338,6 +349,8 @@ Description: What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown KernelVersion: 2.6.38 Contact: linux-iio@vger.kernel.org Description: @@ -346,6 +359,24 @@ Description: normal operation. Y may be suppressed if all outputs are controlled together. +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_frequency +KernelVersion: 3.4.0 +Contact: linux-iio@vger.kernel.org +Description: + Output frequency for channel Y in Hz. The number must always be + specified and unique if the output corresponds to a single + channel. + +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_phase +KernelVersion: 3.4.0 +Contact: linux-iio@vger.kernel.org +Description: + Phase in radians of one frequency/clock output Y + (out_altvoltageY) relative to another frequency/clock output + (out_altvoltageZ) of the device X. The number must always be + specified and unique if the output corresponds to a single + channel. + What: /sys/bus/iio/devices/iio:deviceX/events KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org diff --git a/Documentation/arm/SPEAr/overview.txt b/Documentation/arm/SPEAr/overview.txt index 57aae7765c74..65610bf52ebf 100644 --- a/Documentation/arm/SPEAr/overview.txt +++ b/Documentation/arm/SPEAr/overview.txt @@ -60,4 +60,4 @@ Introduction Document Author --------------- - Viresh Kumar , (c) 2010-2012 ST Microelectronics + Viresh Kumar , (c) 2010-2012 ST Microelectronics diff --git a/Documentation/hwmon/coretemp b/Documentation/hwmon/coretemp index 84d46c0c71a3..c86b50c03ea8 100644 --- a/Documentation/hwmon/coretemp +++ b/Documentation/hwmon/coretemp @@ -6,7 +6,9 @@ Supported chips: Prefix: 'coretemp' CPUID: family 0x6, models 0xe (Pentium M DC), 0xf (Core 2 DC 65nm), 0x16 (Core 2 SC 65nm), 0x17 (Penryn 45nm), - 0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield) + 0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield), + 0x26 (Tunnel Creek Atom), 0x27 (Medfield Atom), + 0x36 (Cedar Trail Atom) Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual Volume 3A: System Programming Guide http://softwarecommunity.intel.com/Wiki/Mobility/720.htm @@ -52,6 +54,17 @@ Some information comes from ark.intel.com Process Processor TjMax(C) +22nm Core i5/i7 Processors + i7 3920XM, 3820QM, 3720QM, 3667U, 3520M 105 + i5 3427U, 3360M/3320M 105 + i7 3770/3770K 105 + i5 3570/3570K, 3550, 3470/3450 105 + i7 3770S 103 + i5 3570S/3550S, 3475S/3470S/3450S 103 + i7 3770T 94 + i5 3570T 94 + i5 3470T 91 + 32nm Core i3/i5/i7 Processors i7 660UM/640/620, 640LM/620, 620M, 610E 105 i5 540UM/520/430, 540M/520/450/430 105 @@ -65,6 +78,11 @@ Process Processor TjMax(C) U3400 105 P4505/P4500 90 +32nm Atom Processors + Z2460 90 + D2700/2550/2500 100 + N2850/2800/2650/2600 100 + 45nm Xeon Processors 5400 Quad-Core X5492, X5482, X5472, X5470, X5460, X5450 85 E5472, E5462, E5450/40/30/20/10/05 85 @@ -85,6 +103,8 @@ Process Processor TjMax(C) N475/470/455/450 100 N280/270 90 330/230 125 + E680/660/640/620 90 + E680T/660T/640T/620T 110 45nm Core2 Processors Solo ULV SU3500/3300 100 diff --git a/MAINTAINERS b/MAINTAINERS index 3e30a3afe2a4..eb22272b2116 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -579,7 +579,7 @@ F: drivers/net/appletalk/ F: net/appletalk/ ARASAN COMPACT FLASH PATA CONTROLLER -M: Viresh Kumar +M: Viresh Kumar L: linux-ide@vger.kernel.org S: Maintained F: include/linux/pata_arasan_cf_data.h @@ -5296,7 +5296,7 @@ S: Maintained F: drivers/pinctrl/ PIN CONTROLLER - ST SPEAR -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear @@ -5873,7 +5873,7 @@ S: Maintained F: drivers/tty/serial SYNOPSYS DESIGNWARE DMAC DRIVER -M: Viresh Kumar +M: Viresh Kumar S: Maintained F: include/linux/dw_dmac.h F: drivers/dma/dw_dmac_regs.h @@ -6021,7 +6021,7 @@ S: Maintained F: drivers/mmc/host/sdhci-s3c.c SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) ST SPEAR DRIVER -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-mmc@vger.kernel.org S: Maintained @@ -6377,7 +6377,7 @@ S: Maintained F: include/linux/compiler.h SPEAR PLATFORM SUPPORT -M: Viresh Kumar +M: Viresh Kumar M: Shiraz Hashim L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -6386,7 +6386,7 @@ S: Maintained F: arch/arm/plat-spear/ SPEAR13XX MACHINE SUPPORT -M: Viresh Kumar +M: Viresh Kumar M: Shiraz Hashim L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -6395,7 +6395,7 @@ S: Maintained F: arch/arm/mach-spear13xx/ SPEAR3XX MACHINE SUPPORT -M: Viresh Kumar +M: Viresh Kumar M: Shiraz Hashim L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -6406,7 +6406,7 @@ F: arch/arm/mach-spear3xx/ SPEAR6XX MACHINE SUPPORT M: Rajeev Kumar M: Shiraz Hashim -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear @@ -6414,7 +6414,7 @@ S: Maintained F: arch/arm/mach-spear6xx/ SPEAR CLOCK FRAMEWORK SUPPORT -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear @@ -7421,7 +7421,7 @@ F: include/linux/vlynq.h VME SUBSYSTEM M: Martyn Welch -M: Manohar Vanga +M: Manohar Vanga M: Greg Kroah-Hartman L: devel@driverdev.osuosl.org S: Maintained diff --git a/Makefile b/Makefile index b771af583389..3fdfde2c1b7d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 5 SUBLEVEL = 0 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc4 NAME = Saber-toothed Squirrel # *DOCUMENTATION* @@ -561,6 +561,8 @@ else KBUILD_CFLAGS += -O2 endif +include $(srctree)/arch/$(SRCARCH)/Makefile + ifdef CONFIG_READABLE_ASM # Disable optimizations that make assembler listings hard to read. # reorder blocks reorders the control in the function @@ -571,8 +573,6 @@ KBUILD_CFLAGS += $(call cc-option,-fno-reorder-blocks,) \ $(call cc-option,-fno-partial-inlining) endif -include $(srctree)/arch/$(SRCARCH)/Makefile - ifneq ($(CONFIG_FRAME_WARN),0) KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b1b27525b24d..a91009c61870 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -589,6 +589,7 @@ config ARCH_ORION5X select PCI select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS + select NEED_MACH_IO_H select PLAT_ORION help Support for the following Marvell Orion 5x series SoCs: diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi index f2ab4ea7cc0e..581cb081cb0f 100644 --- a/arch/arm/boot/dts/omap2.dtsi +++ b/arch/arm/boot/dts/omap2.dtsi @@ -44,6 +44,8 @@ compatible = "ti,omap2-intc"; interrupt-controller; #interrupt-cells = <1>; + ti,intc-size = <96>; + reg = <0x480FE000 0x1000>; }; uart1: serial@4806a000 { diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts index 8314e4171884..dd4358bc26e2 100644 --- a/arch/arm/boot/dts/spear1310-evb.dts +++ b/arch/arm/boot/dts/spear1310-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr1310 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi index 9e61da404d57..419ea7413d23 100644 --- a/arch/arm/boot/dts/spear1310.dtsi +++ b/arch/arm/boot/dts/spear1310.dtsi @@ -1,7 +1,7 @@ /* * DTS file for all SPEAr1310 SoCs * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts index 0d8472e5ab9f..c9a54e06fb68 100644 --- a/arch/arm/boot/dts/spear1340-evb.dts +++ b/arch/arm/boot/dts/spear1340-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr1340 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi index a26fc47a55e8..d71fe2a68f09 100644 --- a/arch/arm/boot/dts/spear1340.dtsi +++ b/arch/arm/boot/dts/spear1340.dtsi @@ -1,7 +1,7 @@ /* * DTS file for all SPEAr1340 SoCs * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi index 1f8e1e1481df..10dcec7e7321 100644 --- a/arch/arm/boot/dts/spear13xx.dtsi +++ b/arch/arm/boot/dts/spear13xx.dtsi @@ -1,7 +1,7 @@ /* * DTS file for all SPEAr13xx SoCs * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear300-evb.dts b/arch/arm/boot/dts/spear300-evb.dts index fc82b1a26458..d71b8d581e3d 100644 --- a/arch/arm/boot/dts/spear300-evb.dts +++ b/arch/arm/boot/dts/spear300-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr300 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi index 01c5e358fdb2..ed3627c116cc 100644 --- a/arch/arm/boot/dts/spear300.dtsi +++ b/arch/arm/boot/dts/spear300.dtsi @@ -1,7 +1,7 @@ /* * DTS file for SPEAr300 SoC * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear310-evb.dts b/arch/arm/boot/dts/spear310-evb.dts index dc5e2d445a93..b00544e0cd5d 100644 --- a/arch/arm/boot/dts/spear310-evb.dts +++ b/arch/arm/boot/dts/spear310-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr310 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi index e47081c494d9..62fc4fb3e5f9 100644 --- a/arch/arm/boot/dts/spear310.dtsi +++ b/arch/arm/boot/dts/spear310.dtsi @@ -1,7 +1,7 @@ /* * DTS file for SPEAr310 SoC * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts index 6308fa3bec1e..c13fd1f3b09f 100644 --- a/arch/arm/boot/dts/spear320-evb.dts +++ b/arch/arm/boot/dts/spear320-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr320 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi index 5372ca399b1f..1f49d69595a0 100644 --- a/arch/arm/boot/dts/spear320.dtsi +++ b/arch/arm/boot/dts/spear320.dtsi @@ -1,7 +1,7 @@ /* * DTS file for SPEAr320 SoC * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear3xx.dtsi b/arch/arm/boot/dts/spear3xx.dtsi index 91072553963f..3a8bb5736928 100644 --- a/arch/arm/boot/dts/spear3xx.dtsi +++ b/arch/arm/boot/dts/spear3xx.dtsi @@ -1,7 +1,7 @@ /* * DTS file for all SPEAr3xx SoCs * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h index 7be54690aeec..e42cf597f6e6 100644 --- a/arch/arm/include/asm/futex.h +++ b/arch/arm/include/asm/futex.h @@ -19,6 +19,7 @@ " .long 1b, 4f, 2b, 4f\n" \ " .popsection\n" \ " .pushsection .fixup,\"ax\"\n" \ + " .align 2\n" \ "4: mov %0, " err_reg "\n" \ " b 3b\n" \ " .popsection" diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h index e0d1c0cfa548..6b9b077d86b3 100644 --- a/arch/arm/include/asm/hardware/sp810.h +++ b/arch/arm/include/asm/hardware/sp810.h @@ -4,7 +4,7 @@ * ARM PrimeXsys System Controller SP810 header file * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 437f0c426517..0d1851ca6eb9 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -495,6 +495,7 @@ ENDPROC(__und_usr) * The out of line fixup for the ldrt above. */ .pushsection .fixup, "ax" + .align 2 4: mov pc, r9 .popsection .pushsection __ex_table,"a" diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c index 8f96ec778e8d..6123daf397a7 100644 --- a/arch/arm/kernel/kprobes-thumb.c +++ b/arch/arm/kernel/kprobes-thumb.c @@ -660,7 +660,7 @@ static const union decode_item t32_table_1111_100x[] = { /* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */ /* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */ /* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */ - DECODE_EMULATEX (0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal, + DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal, REGS(PC, NOSPPCX, 0, 0, 0)), /* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */ diff --git a/arch/arm/mach-kirkwood/board-iconnect.c b/arch/arm/mach-kirkwood/board-iconnect.c index 2222c5739519..b0d3cc49269d 100644 --- a/arch/arm/mach-kirkwood/board-iconnect.c +++ b/arch/arm/mach-kirkwood/board-iconnect.c @@ -20,9 +20,6 @@ #include #include #include -#include -#include -#include #include #include #include diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index e1d2c6def5e6..f261cd242643 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -159,6 +159,7 @@ static struct clk __init *clk_register_gate_fn(struct device *dev, gate_fn->gate.flags = clk_gate_flags; gate_fn->gate.lock = lock; gate_fn->gate.hw.init = &init; + gate_fn->fn = fn; /* ops is the gate ops, but with our disable function */ if (clk_gate_fn_ops.disable != clk_gate_fn_disable) { diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h index 3eee37a3b501..a115142f8690 100644 --- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h +++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h @@ -38,6 +38,7 @@ #define IRQ_MASK_HIGH_OFF 0x0014 #define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300) +#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE | 0x0300) #define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128) #define L2_WRITETHROUGH 0x00000010 diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h index fede3d503efa..c5b68510776b 100644 --- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h @@ -80,6 +80,7 @@ #define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100) #define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x20000) +#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x20000) #define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x30000) diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 8ca14e88a31a..2c5d0ed75285 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -83,11 +83,9 @@ static struct musb_hdrc_config musb_config = { }; static struct musb_hdrc_platform_data tusb_data = { -#if defined(CONFIG_USB_MUSB_OTG) +#ifdef CONFIG_USB_GADGET_MUSB_HDRC .mode = MUSB_OTG, -#elif defined(CONFIG_USB_MUSB_PERIPHERAL) - .mode = MUSB_PERIPHERAL, -#else /* defined(CONFIG_USB_MUSB_HOST) */ +#else .mode = MUSB_HOST, #endif .set_power = tusb_set_power, diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 79c6909eeb78..580fd17208da 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -81,13 +81,13 @@ static u8 omap3_beagle_version; static struct { int mmc1_gpio_wp; int usb_pwr_level; - int reset_gpio; + int dvi_pd_gpio; int usr_button_gpio; int mmc_caps; } beagle_config = { .mmc1_gpio_wp = -EINVAL, .usb_pwr_level = GPIOF_OUT_INIT_LOW, - .reset_gpio = 129, + .dvi_pd_gpio = -EINVAL, .usr_button_gpio = 4, .mmc_caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, }; @@ -126,21 +126,21 @@ static void __init omap3_beagle_init_rev(void) printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n"); omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX; beagle_config.mmc1_gpio_wp = 29; - beagle_config.reset_gpio = 170; + beagle_config.dvi_pd_gpio = 170; beagle_config.usr_button_gpio = 7; break; case 6: printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n"); omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3; beagle_config.mmc1_gpio_wp = 23; - beagle_config.reset_gpio = 170; + beagle_config.dvi_pd_gpio = 170; beagle_config.usr_button_gpio = 7; break; case 5: printk(KERN_INFO "OMAP3 Beagle Rev: C4\n"); omap3_beagle_version = OMAP3BEAGLE_BOARD_C4; beagle_config.mmc1_gpio_wp = 23; - beagle_config.reset_gpio = 170; + beagle_config.dvi_pd_gpio = 170; beagle_config.usr_button_gpio = 7; break; case 0: @@ -274,11 +274,9 @@ static int beagle_twl_gpio_setup(struct device *dev, if (r) pr_err("%s: unable to configure nDVI_PWR_EN\n", __func__); - r = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH, - "DVI_LDO_EN"); - if (r) - pr_err("%s: unable to configure DVI_LDO_EN\n", - __func__); + + beagle_config.dvi_pd_gpio = gpio + 2; + } else { /* * REVISIT: need ehci-omap hooks for external VBUS @@ -287,7 +285,7 @@ static int beagle_twl_gpio_setup(struct device *dev, if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC")) pr_err("%s: unable to configure EHCI_nOC\n", __func__); } - dvi_panel.power_down_gpio = beagle_config.reset_gpio; + dvi_panel.power_down_gpio = beagle_config.dvi_pd_gpio; gpio_request_one(gpio + TWL4030_GPIO_MAX, beagle_config.usb_pwr_level, "nEN_USB_PWR"); @@ -499,7 +497,7 @@ static void __init omap3_beagle_init(void) omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap3_beagle_init_rev(); - if (beagle_config.mmc1_gpio_wp != -EINVAL) + if (gpio_is_valid(beagle_config.mmc1_gpio_wp)) omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT); mmc[0].caps = beagle_config.mmc_caps; omap_hsmmc_init(mmc); @@ -510,15 +508,13 @@ static void __init omap3_beagle_init(void) platform_add_devices(omap3_beagle_devices, ARRAY_SIZE(omap3_beagle_devices)); + if (gpio_is_valid(beagle_config.dvi_pd_gpio)) + omap_mux_init_gpio(beagle_config.dvi_pd_gpio, OMAP_PIN_OUTPUT); omap_display_init(&beagle_dss_data); omap_serial_init(); omap_sdrc_init(mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_params); - omap_mux_init_gpio(170, OMAP_PIN_INPUT); - /* REVISIT leave DVI powered down until it's needed ... */ - gpio_request_one(170, GPIOF_OUT_INIT_HIGH, "DVI_nPD"); - usb_musb_init(NULL); usbhs_init(&usbhs_bdata); omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions, diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 2172f6603848..e2b701e164f6 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -84,6 +84,7 @@ static struct clk slimbus_clk = { static struct clk sys_32k_ck = { .name = "sys_32k_ck", + .clkdm_name = "prm_clkdm", .rate = 32768, .ops = &clkops_null, }; @@ -512,6 +513,7 @@ static struct clk ddrphy_ck = { .name = "ddrphy_ck", .parent = &dpll_core_m2_ck, .ops = &clkops_null, + .clkdm_name = "l3_emif_clkdm", .fixed_div = 2, .recalc = &omap_fixed_divisor_recalc, }; @@ -769,6 +771,7 @@ static const struct clksel dpll_mpu_m2_div[] = { static struct clk dpll_mpu_m2_ck = { .name = "dpll_mpu_m2_ck", .parent = &dpll_mpu_ck, + .clkdm_name = "cm_clkdm", .clksel = dpll_mpu_m2_div, .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_MPU, .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, @@ -1149,6 +1152,7 @@ static const struct clksel l3_div_div[] = { static struct clk l3_div_ck = { .name = "l3_div_ck", .parent = &div_core_ck, + .clkdm_name = "cm_clkdm", .clksel = l3_div_div, .clksel_reg = OMAP4430_CM_CLKSEL_CORE, .clksel_mask = OMAP4430_CLKSEL_L3_MASK, @@ -2824,6 +2828,7 @@ static const struct clksel trace_clk_div_div[] = { static struct clk trace_clk_div_ck = { .name = "trace_clk_div_ck", .parent = &pmd_trace_clk_mux_ck, + .clkdm_name = "emu_sys_clkdm", .clksel = trace_clk_div_div, .clksel_reg = OMAP4430_CM_EMU_DEBUGSS_CLKCTRL, .clksel_mask = OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK, diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index a7bc096bd407..f24e3f7a2bbc 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -22,4 +22,15 @@ */ #define MAX_MODULE_READY_TIME 2000 +/* + * MAX_MODULE_DISABLE_TIME: max duration in microseconds to wait for + * the PRCM to request that a module enter the inactive state in the + * case of OMAP2 & 3. In the case of OMAP4 this is the max duration + * in microseconds for the module to reach the inactive state from + * a functional state. + * XXX FSUSB on OMAP4430 takes ~4ms to idle after reset during + * kernel init. + */ +#define MAX_MODULE_DISABLE_TIME 5000 + #endif diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index 8c86d294b1a3..1a39945d9ff8 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -313,9 +313,9 @@ int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_off omap_test_timeout((_clkctrl_idlest(part, inst, cdoffs, clkctrl_offs) == CLKCTRL_IDLEST_DISABLED), - MAX_MODULE_READY_TIME, i); + MAX_MODULE_DISABLE_TIME, i); - return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; + return (i < MAX_MODULE_DISABLE_TIME) ? 0 : -EBUSY; } /** diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 4b46b91cca5c..9fe6829f4c16 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -41,6 +41,7 @@ #include "control.h" #include "mux.h" #include "prm.h" +#include "common.h" #define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ #define OMAP_MUX_BASE_SZ 0x5ca diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index bf86f7e8f91f..773193670ea2 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -530,7 +530,7 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v) if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v); if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP) - _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v); + _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART, v); /* XXX test pwrdm_get_wken for this hwmod's subsystem */ diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 950454a3fa31..f30e861ce6d9 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -393,8 +393,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_counter_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0004, .sysc_flags = SYSC_HAS_SIDLEMODE, - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), + .idlemodes = (SIDLE_FORCE | SIDLE_NO), .sysc_fields = &omap_hwmod_sysc_type1, }; @@ -854,6 +853,11 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { .name = "dss_hdmi", .class = &omap44xx_hdmi_hwmod_class, .clkdm_name = "l3_dss_clkdm", + /* + * HDMI audio requires to use no-idle mode. Hence, + * set idle mode by software. + */ + .flags = HWMOD_SWSUP_SIDLE, .mpu_irqs = omap44xx_dss_hdmi_irqs, .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, .main_clk = "dss_48mhz_clk", diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c index 4c90477e6f82..d52651a05daa 100644 --- a/arch/arm/mach-omap2/omap_phy_internal.c +++ b/arch/arm/mach-omap2/omap_phy_internal.c @@ -239,21 +239,15 @@ void am35x_set_mode(u8 musb_mode) devconf2 &= ~CONF2_OTGMODE; switch (musb_mode) { -#ifdef CONFIG_USB_MUSB_HDRC_HCD case MUSB_HOST: /* Force VBUS valid, ID = 0 */ devconf2 |= CONF2_FORCE_HOST; break; -#endif -#ifdef CONFIG_USB_GADGET_MUSB_HDRC case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ devconf2 |= CONF2_FORCE_DEVICE; break; -#endif -#ifdef CONFIG_USB_MUSB_OTG case MUSB_OTG: /* Don't override the VBUS/ID comparators */ devconf2 |= CONF2_NO_OVERRIDE; break; -#endif default: pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode); } diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index b19d1b43c12e..c4a576856661 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c @@ -41,12 +41,10 @@ static struct musb_hdrc_config musb_config = { }; static struct musb_hdrc_platform_data musb_plat = { -#ifdef CONFIG_USB_MUSB_OTG +#ifdef CONFIG_USB_GADGET_MUSB_HDRC .mode = MUSB_OTG, -#elif defined(CONFIG_USB_MUSB_HDRC_HCD) +#else .mode = MUSB_HOST, -#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) - .mode = MUSB_PERIPHERAL, #endif /* .clock is set dynamically */ .config = &musb_config, diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c index db84a46ce7fd..805bea6edf17 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c @@ -300,7 +300,7 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, printk(error, 3, status); return status; } - tusb_resources[2].start = irq + IH_GPIO_BASE; + tusb_resources[2].start = gpio_to_irq(irq); /* set up memory timings ... can speed them up later */ if (!ps_refclk) { diff --git a/arch/arm/mach-orion5x/include/mach/bridge-regs.h b/arch/arm/mach-orion5x/include/mach/bridge-regs.h index 96484bcd34ca..11a3c1e9801f 100644 --- a/arch/arm/mach-orion5x/include/mach/bridge-regs.h +++ b/arch/arm/mach-orion5x/include/mach/bridge-regs.h @@ -35,5 +35,5 @@ #define MAIN_IRQ_MASK (ORION5X_BRIDGE_VIRT_BASE | 0x204) #define TIMER_VIRT_BASE (ORION5X_BRIDGE_VIRT_BASE | 0x300) - +#define TIMER_PHYS_BASE (ORION5X_BRIDGE_PHYS_BASE | 0x300) #endif diff --git a/arch/arm/mach-orion5x/include/mach/io.h b/arch/arm/mach-orion5x/include/mach/io.h new file mode 100644 index 000000000000..1aa5d0a50a0b --- /dev/null +++ b/arch/arm/mach-orion5x/include/mach/io.h @@ -0,0 +1,22 @@ +/* + * arch/arm/mach-orion5x/include/mach/io.h + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __ASM_ARCH_IO_H +#define __ASM_ARCH_IO_H + +#include +#include + +#define IO_SPACE_LIMIT SZ_2M +static inline void __iomem *__io(unsigned long addr) +{ + return (void __iomem *)(addr + ORION5X_PCIE_IO_VIRT_BASE); +} + +#define __io(a) __io(a) +#endif diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h index 2745f5d95b3f..683e085ce162 100644 --- a/arch/arm/mach-orion5x/include/mach/orion5x.h +++ b/arch/arm/mach-orion5x/include/mach/orion5x.h @@ -82,6 +82,7 @@ #define UART1_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE | 0x2100) #define ORION5X_BRIDGE_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x20000) +#define ORION5X_BRIDGE_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x20000) #define ORION5X_PCI_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x30000) diff --git a/arch/arm/mach-spear13xx/include/mach/debug-macro.S b/arch/arm/mach-spear13xx/include/mach/debug-macro.S index ea1564609bd4..9e3ae6bfe50d 100644 --- a/arch/arm/mach-spear13xx/include/mach/debug-macro.S +++ b/arch/arm/mach-spear13xx/include/mach/debug-macro.S @@ -4,7 +4,7 @@ * Debugging macro include header spear13xx machine family * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/dma.h b/arch/arm/mach-spear13xx/include/mach/dma.h index 383ab04dc6c9..d50bdb605925 100644 --- a/arch/arm/mach-spear13xx/include/mach/dma.h +++ b/arch/arm/mach-spear13xx/include/mach/dma.h @@ -4,7 +4,7 @@ * DMA information for SPEAr13xx machine family * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h index 6d8c45b9f298..dac57fd0cdfd 100644 --- a/arch/arm/mach-spear13xx/include/mach/generic.h +++ b/arch/arm/mach-spear13xx/include/mach/generic.h @@ -4,7 +4,7 @@ * spear13xx machine family generic header file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/gpio.h b/arch/arm/mach-spear13xx/include/mach/gpio.h index cd6f4f86a56b..85f176311f63 100644 --- a/arch/arm/mach-spear13xx/include/mach/gpio.h +++ b/arch/arm/mach-spear13xx/include/mach/gpio.h @@ -4,7 +4,7 @@ * GPIO macros for SPEAr13xx machine family * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/irqs.h b/arch/arm/mach-spear13xx/include/mach/irqs.h index f542a24aa5f2..271a62b4cd31 100644 --- a/arch/arm/mach-spear13xx/include/mach/irqs.h +++ b/arch/arm/mach-spear13xx/include/mach/irqs.h @@ -4,7 +4,7 @@ * IRQ helper macros for spear13xx machine family * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h index 30c57ef72686..65f27def239b 100644 --- a/arch/arm/mach-spear13xx/include/mach/spear.h +++ b/arch/arm/mach-spear13xx/include/mach/spear.h @@ -4,7 +4,7 @@ * spear13xx Machine family specific definition * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/timex.h b/arch/arm/mach-spear13xx/include/mach/timex.h index 31af3e8d976e..3a58b8284a6a 100644 --- a/arch/arm/mach-spear13xx/include/mach/timex.h +++ b/arch/arm/mach-spear13xx/include/mach/timex.h @@ -4,7 +4,7 @@ * SPEAr3XX machine family specific timex definitions * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/uncompress.h b/arch/arm/mach-spear13xx/include/mach/uncompress.h index c7840896ae6e..70fe72f05dea 100644 --- a/arch/arm/mach-spear13xx/include/mach/uncompress.h +++ b/arch/arm/mach-spear13xx/include/mach/uncompress.h @@ -4,7 +4,7 @@ * Serial port stubs for kernel decompress status messages * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c index fefd15b2f380..732d29bc7330 100644 --- a/arch/arm/mach-spear13xx/spear1310.c +++ b/arch/arm/mach-spear13xx/spear1310.c @@ -4,7 +4,7 @@ * SPEAr1310 machine source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/spear1340.c b/arch/arm/mach-spear13xx/spear1340.c index ee38cbc56869..81e4ed76ad06 100644 --- a/arch/arm/mach-spear13xx/spear1340.c +++ b/arch/arm/mach-spear13xx/spear1340.c @@ -4,7 +4,7 @@ * SPEAr1340 machine source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c index 50b349ae863d..cf936b106e27 100644 --- a/arch/arm/mach-spear13xx/spear13xx.c +++ b/arch/arm/mach-spear13xx/spear13xx.c @@ -4,7 +4,7 @@ * SPEAr13XX machines common source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/debug-macro.S b/arch/arm/mach-spear3xx/include/mach/debug-macro.S index 590519f10d6e..0a6381fad5d9 100644 --- a/arch/arm/mach-spear3xx/include/mach/debug-macro.S +++ b/arch/arm/mach-spear3xx/include/mach/debug-macro.S @@ -4,7 +4,7 @@ * Debugging macro include header spear3xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h index 4a95b9453c2a..ce19113ca791 100644 --- a/arch/arm/mach-spear3xx/include/mach/generic.h +++ b/arch/arm/mach-spear3xx/include/mach/generic.h @@ -4,7 +4,7 @@ * SPEAr3XX machine family generic header file * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/gpio.h b/arch/arm/mach-spear3xx/include/mach/gpio.h index 451b2081bfc9..2ac74c6db7f1 100644 --- a/arch/arm/mach-spear3xx/include/mach/gpio.h +++ b/arch/arm/mach-spear3xx/include/mach/gpio.h @@ -4,7 +4,7 @@ * GPIO macros for SPEAr3xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h index 51bd62a0254c..803de76f5f36 100644 --- a/arch/arm/mach-spear3xx/include/mach/irqs.h +++ b/arch/arm/mach-spear3xx/include/mach/irqs.h @@ -4,7 +4,7 @@ * IRQ helper macros for SPEAr3xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/misc_regs.h b/arch/arm/mach-spear3xx/include/mach/misc_regs.h index 18e2ac576f25..6309bf68d6f8 100644 --- a/arch/arm/mach-spear3xx/include/mach/misc_regs.h +++ b/arch/arm/mach-spear3xx/include/mach/misc_regs.h @@ -4,7 +4,7 @@ * Miscellaneous registers definitions for SPEAr3xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/spear.h b/arch/arm/mach-spear3xx/include/mach/spear.h index 51eb953148a9..8cca95193d4d 100644 --- a/arch/arm/mach-spear3xx/include/mach/spear.h +++ b/arch/arm/mach-spear3xx/include/mach/spear.h @@ -4,7 +4,7 @@ * SPEAr3xx Machine family specific definition * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/timex.h b/arch/arm/mach-spear3xx/include/mach/timex.h index a38cc9de876f..9f5d08bd0c44 100644 --- a/arch/arm/mach-spear3xx/include/mach/timex.h +++ b/arch/arm/mach-spear3xx/include/mach/timex.h @@ -4,7 +4,7 @@ * SPEAr3XX machine family specific timex definitions * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/uncompress.h b/arch/arm/mach-spear3xx/include/mach/uncompress.h index 53ba8bbc0dfa..b909b011f7c8 100644 --- a/arch/arm/mach-spear3xx/include/mach/uncompress.h +++ b/arch/arm/mach-spear3xx/include/mach/uncompress.h @@ -4,7 +4,7 @@ * Serial port stubs for kernel decompress status messages * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c index f74a05bdb829..0f882ecb7d81 100644 --- a/arch/arm/mach-spear3xx/spear300.c +++ b/arch/arm/mach-spear3xx/spear300.c @@ -4,7 +4,7 @@ * SPEAr300 machine source file * * Copyright (C) 2009-2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c index 84dfb0900747..bbcf4571d361 100644 --- a/arch/arm/mach-spear3xx/spear310.c +++ b/arch/arm/mach-spear3xx/spear310.c @@ -4,7 +4,7 @@ * SPEAr310 machine source file * * Copyright (C) 2009-2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c index a88fa841d29d..88d483bcd66a 100644 --- a/arch/arm/mach-spear3xx/spear320.c +++ b/arch/arm/mach-spear3xx/spear320.c @@ -4,7 +4,7 @@ * SPEAr320 machine source file * * Copyright (C) 2009-2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c index f22419ed74a8..0f41bd1c47c3 100644 --- a/arch/arm/mach-spear3xx/spear3xx.c +++ b/arch/arm/mach-spear3xx/spear3xx.c @@ -4,7 +4,7 @@ * SPEAr3XX machines common source file * * Copyright (C) 2009-2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear6xx/include/mach/gpio.h b/arch/arm/mach-spear6xx/include/mach/gpio.h index 3a789dbb69f7..d42cefc0356d 100644 --- a/arch/arm/mach-spear6xx/include/mach/gpio.h +++ b/arch/arm/mach-spear6xx/include/mach/gpio.h @@ -4,7 +4,7 @@ * GPIO macros for SPEAr6xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear6xx/include/mach/misc_regs.h b/arch/arm/mach-spear6xx/include/mach/misc_regs.h index 179e45774b3a..c34acc201d34 100644 --- a/arch/arm/mach-spear6xx/include/mach/misc_regs.h +++ b/arch/arm/mach-spear6xx/include/mach/misc_regs.h @@ -4,7 +4,7 @@ * Miscellaneous registers definitions for SPEAr6xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c index 4d6a2ee99c3b..5beb7ebe2948 100644 --- a/arch/arm/mach-tegra/reset.c +++ b/arch/arm/mach-tegra/reset.c @@ -33,7 +33,7 @@ static bool is_enabled; -static void tegra_cpu_reset_handler_enable(void) +static void __init tegra_cpu_reset_handler_enable(void) { void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE); void __iomem *evp_cpu_reset = diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 9c74ac545849..1509a3cb5833 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -580,43 +580,12 @@ static void ux500_uart0_reset(void) udelay(1); } -/* This needs to be referenced by callbacks */ -struct pinctrl *u0_p; -struct pinctrl_state *u0_def; -struct pinctrl_state *u0_sleep; - -static void ux500_uart0_init(void) -{ - int ret; - - if (IS_ERR(u0_p) || IS_ERR(u0_def)) - return; - - ret = pinctrl_select_state(u0_p, u0_def); - if (ret) - pr_err("could not set UART0 defstate\n"); -} - -static void ux500_uart0_exit(void) -{ - int ret; - - if (IS_ERR(u0_p) || IS_ERR(u0_sleep)) - return; - - ret = pinctrl_select_state(u0_p, u0_sleep); - if (ret) - pr_err("could not set UART0 idlestate\n"); -} - static struct amba_pl011_data uart0_plat = { #ifdef CONFIG_STE_DMA40 .dma_filter = stedma40_filter, .dma_rx_param = &uart0_dma_cfg_rx, .dma_tx_param = &uart0_dma_cfg_tx, #endif - .init = ux500_uart0_init, - .exit = ux500_uart0_exit, .reset = ux500_uart0_reset, }; @@ -638,28 +607,7 @@ static struct amba_pl011_data uart2_plat = { static void __init mop500_uart_init(struct device *parent) { - struct amba_device *uart0_device; - - uart0_device = db8500_add_uart0(parent, &uart0_plat); - if (uart0_device) { - u0_p = pinctrl_get(&uart0_device->dev); - if (IS_ERR(u0_p)) - dev_err(&uart0_device->dev, - "could not get UART0 pinctrl\n"); - else { - u0_def = pinctrl_lookup_state(u0_p, - PINCTRL_STATE_DEFAULT); - if (IS_ERR(u0_def)) { - dev_err(&uart0_device->dev, - "could not get UART0 defstate\n"); - } - u0_sleep = pinctrl_lookup_state(u0_p, - PINCTRL_STATE_SLEEP); - if (IS_ERR(u0_sleep)) - dev_err(&uart0_device->dev, - "could not get UART0 idlestate\n"); - } - } + db8500_add_uart0(parent, &uart0_plat); db8500_add_uart1(parent, &uart1_plat); db8500_add_uart2(parent, &uart2_plat); } diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 62135849f48b..c641fb685017 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -762,6 +762,11 @@ static int build_body(struct jit_ctx *ctx) update_on_xread(ctx); emit(ARM_MOV_R(r_A, r_X), ctx); break; + case BPF_S_ANC_ALU_XOR_X: + /* A ^= X */ + update_on_xread(ctx); + emit(ARM_EOR_R(r_A, r_A, r_X), ctx); + break; case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol) */ ctx->seen |= SEEN_SKB; diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h index 99ae5e3f46d2..7fa2f7d3cb90 100644 --- a/arch/arm/net/bpf_jit_32.h +++ b/arch/arm/net/bpf_jit_32.h @@ -68,6 +68,8 @@ #define ARM_INST_CMP_R 0x01500000 #define ARM_INST_CMP_I 0x03500000 +#define ARM_INST_EOR_R 0x00200000 + #define ARM_INST_LDRB_I 0x05d00000 #define ARM_INST_LDRB_R 0x07d00000 #define ARM_INST_LDRH_I 0x01d000b0 @@ -132,6 +134,8 @@ #define ARM_CMP_R(rn, rm) _AL3_R(ARM_INST_CMP, 0, rn, rm) #define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm) +#define ARM_EOR_R(rd, rn, rm) _AL3_R(ARM_INST_EOR, rd, rn, rm) + #define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \ | (off)) #define ARM_LDRB_I(rt, rn, off) (ARM_INST_LDRB_I | (rt) << 12 | (rn) << 16 \ diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 62ec5c452792..706b7e29397f 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -461,6 +461,7 @@ static int clk_dbg_show_summary(struct seq_file *s, void *unused) struct clk *c; struct clk *pa; + mutex_lock(&clocks_mutex); seq_printf(s, "%-30s %-30s %-10s %s\n", "clock-name", "parent-name", "rate", "use-count"); @@ -469,6 +470,7 @@ static int clk_dbg_show_summary(struct seq_file *s, void *unused) seq_printf(s, "%-30s %-30s %-10lu %d\n", c->name, pa ? pa->name : "none", c->rate, c->usecount); } + mutex_unlock(&clocks_mutex); return 0; } diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index 61fd837624a8..c1793786aea9 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -582,7 +582,7 @@ void __init orion_spi_1_init(unsigned long mapbase) * Watchdog ****************************************************************************/ static struct resource orion_wdt_resource = - DEFINE_RES_MEM(TIMER_VIRT_BASE, 0x28); + DEFINE_RES_MEM(TIMER_PHYS_BASE, 0x28); static struct platform_device orion_wdt_device = { .name = "orion_wdt", diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c index 58b79809d20c..584c9bf8ed2d 100644 --- a/arch/arm/plat-pxa/ssp.c +++ b/arch/arm/plat-pxa/ssp.c @@ -193,6 +193,7 @@ static const struct platform_device_id ssp_id_table[] = { { "pxa25x-nssp", PXA25x_NSSP }, { "pxa27x-ssp", PXA27x_SSP }, { "pxa168-ssp", PXA168_SSP }, + { "pxa910-ssp", PXA910_SSP }, { }, }; diff --git a/arch/arm/plat-spear/include/plat/debug-macro.S b/arch/arm/plat-spear/include/plat/debug-macro.S index ab3de721c5db..75b05ad0fbad 100644 --- a/arch/arm/plat-spear/include/plat/debug-macro.S +++ b/arch/arm/plat-spear/include/plat/debug-macro.S @@ -4,7 +4,7 @@ * Debugging macro include header for spear platform * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/include/plat/pl080.h b/arch/arm/plat-spear/include/plat/pl080.h index e14a3e4932f9..2bc6b54460a8 100644 --- a/arch/arm/plat-spear/include/plat/pl080.h +++ b/arch/arm/plat-spear/include/plat/pl080.h @@ -4,7 +4,7 @@ * DMAC pl080 definitions for SPEAr platform * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/include/plat/shirq.h b/arch/arm/plat-spear/include/plat/shirq.h index 03ed8b585dcf..88a7fbd24793 100644 --- a/arch/arm/plat-spear/include/plat/shirq.h +++ b/arch/arm/plat-spear/include/plat/shirq.h @@ -4,7 +4,7 @@ * SPEAr platform shared irq layer header file * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/include/plat/timex.h b/arch/arm/plat-spear/include/plat/timex.h index 914d09dd50fd..ef95e5b780bd 100644 --- a/arch/arm/plat-spear/include/plat/timex.h +++ b/arch/arm/plat-spear/include/plat/timex.h @@ -4,7 +4,7 @@ * SPEAr platform specific timex definitions * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/include/plat/uncompress.h b/arch/arm/plat-spear/include/plat/uncompress.h index 6dd455bafdfd..2ce6cb17a98b 100644 --- a/arch/arm/plat-spear/include/plat/uncompress.h +++ b/arch/arm/plat-spear/include/plat/uncompress.h @@ -4,7 +4,7 @@ * Serial port stubs for kernel decompress status messages * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/pl080.c b/arch/arm/plat-spear/pl080.c index a56a067717c1..12cf27f935f9 100644 --- a/arch/arm/plat-spear/pl080.c +++ b/arch/arm/plat-spear/pl080.c @@ -4,7 +4,7 @@ * DMAC pl080 definitions for SPEAr platform * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/restart.c b/arch/arm/plat-spear/restart.c index ea0a61302b7e..4f990115b1bd 100644 --- a/arch/arm/plat-spear/restart.c +++ b/arch/arm/plat-spear/restart.c @@ -4,7 +4,7 @@ * SPEAr platform specific restart functions * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/shirq.c b/arch/arm/plat-spear/shirq.c index 961fb7261243..853e891e1184 100644 --- a/arch/arm/plat-spear/shirq.c +++ b/arch/arm/plat-spear/shirq.c @@ -4,7 +4,7 @@ * SPEAr platform shared irq layer source file * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c index 68d651081bd3..d0b1607f2711 100644 --- a/arch/h8300/kernel/setup.c +++ b/arch/h8300/kernel/setup.c @@ -35,6 +35,7 @@ #include #include #include +#include #if defined(__H8300H__) #define CPU "H8/300H" @@ -54,7 +55,6 @@ unsigned long memory_end; char __initdata command_line[COMMAND_LINE_SIZE]; -extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end; extern int _ramstart, _ramend; extern char _target_name[]; extern void h8300_gpio_init(void); @@ -119,9 +119,9 @@ void __init setup_arch(char **cmdline_p) memory_end = CONFIG_BLKDEV_RESERVE_ADDRESS; #endif - init_mm.start_code = (unsigned long) &_stext; - init_mm.end_code = (unsigned long) &_etext; - init_mm.end_data = (unsigned long) &_edata; + init_mm.start_code = (unsigned long) _stext; + init_mm.end_code = (unsigned long) _etext; + init_mm.end_data = (unsigned long) _edata; init_mm.brk = (unsigned long) 0; #if (defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)) && defined(CONFIG_GDB_MAGICPRINT) @@ -134,15 +134,12 @@ void __init setup_arch(char **cmdline_p) printk(KERN_INFO "H8/300 series support by Yoshinori Sato \n"); #ifdef DEBUG - printk(KERN_DEBUG "KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x " - "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext, - (int) &_sdata, (int) &_edata, - (int) &_sbss, (int) &_ebss); - printk(KERN_DEBUG "KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x " - "STACK=0x%06x-0x%06x\n", - (int) &_ebss, (int) memory_start, - (int) memory_start, (int) memory_end, - (int) memory_end, (int) &_ramend); + printk(KERN_DEBUG "KERNEL -> TEXT=0x%p-0x%p DATA=0x%p-0x%p " + "BSS=0x%p-0x%p\n", _stext, _etext, _sdata, _edata, __bss_start, + __bss_stop); + printk(KERN_DEBUG "KERNEL -> ROMFS=0x%p-0x%06lx MEM=0x%06lx-0x%06lx " + "STACK=0x%06lx-0x%p\n", __bss_stop, memory_start, memory_start, + memory_end, memory_end, &_ramend); #endif #ifdef CONFIG_DEFAULT_CMDLINE diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c index 973369c32a95..981e25094b1a 100644 --- a/arch/h8300/mm/init.c +++ b/arch/h8300/mm/init.c @@ -36,6 +36,7 @@ #include #include #include +#include #undef DEBUG @@ -123,7 +124,6 @@ void __init mem_init(void) int codek = 0, datak = 0, initk = 0; /* DAVIDM look at setup memory map generically with reserved area */ unsigned long tmp; - extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end; extern unsigned long _ramend, _ramstart; unsigned long len = &_ramend - &_ramstart; unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */ @@ -142,9 +142,9 @@ void __init mem_init(void) /* this will put all memory onto the freelists */ totalram_pages = free_all_bootmem(); - codek = (&_etext - &_stext) >> 10; - datak = (&_ebss - &_sdata) >> 10; - initk = (&__init_begin - &__init_end) >> 10; + codek = (_etext - _stext) >> 10; + datak = (__bss_stop - _sdata) >> 10; + initk = (__init_begin - __init_end) >> 10; tmp = nr_free_pages() << PAGE_SHIFT; printk(KERN_INFO "Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n", @@ -178,22 +178,21 @@ free_initmem(void) { #ifdef CONFIG_RAMKERNEL unsigned long addr; - extern char __init_begin, __init_end; /* * the following code should be cool even if these sections * are not page aligned. */ - addr = PAGE_ALIGN((unsigned long)(&__init_begin)); + addr = PAGE_ALIGN((unsigned long)(__init_begin)); /* next to check that the page we free is not a partial page */ - for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) { + for (; addr + PAGE_SIZE < (unsigned long)__init_end; addr +=PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); free_page(addr); totalram_pages++; } printk(KERN_INFO "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n", - (addr - PAGE_ALIGN((long) &__init_begin)) >> 10, - (int)(PAGE_ALIGN((unsigned long)(&__init_begin))), + (addr - PAGE_ALIGN((long) __init_begin)) >> 10, + (int)(PAGE_ALIGN((unsigned long)__init_begin)), (int)(addr - PAGE_SIZE)); #endif } diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index c6af1d623839..3abe1b86e583 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -268,24 +268,45 @@ static unsigned long do_h_register_vpa(struct kvm_vcpu *vcpu, return err; } -static void kvmppc_update_vpa(struct kvm *kvm, struct kvmppc_vpa *vpap) +static void kvmppc_update_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *vpap) { + struct kvm *kvm = vcpu->kvm; void *va; unsigned long nb; + unsigned long gpa; + + /* + * We need to pin the page pointed to by vpap->next_gpa, + * but we can't call kvmppc_pin_guest_page under the lock + * as it does get_user_pages() and down_read(). So we + * have to drop the lock, pin the page, then get the lock + * again and check that a new area didn't get registered + * in the meantime. + */ + for (;;) { + gpa = vpap->next_gpa; + spin_unlock(&vcpu->arch.vpa_update_lock); + va = NULL; + nb = 0; + if (gpa) + va = kvmppc_pin_guest_page(kvm, vpap->next_gpa, &nb); + spin_lock(&vcpu->arch.vpa_update_lock); + if (gpa == vpap->next_gpa) + break; + /* sigh... unpin that one and try again */ + if (va) + kvmppc_unpin_guest_page(kvm, va); + } vpap->update_pending = 0; - va = NULL; - if (vpap->next_gpa) { - va = kvmppc_pin_guest_page(kvm, vpap->next_gpa, &nb); - if (nb < vpap->len) { - /* - * If it's now too short, it must be that userspace - * has changed the mappings underlying guest memory, - * so unregister the region. - */ - kvmppc_unpin_guest_page(kvm, va); - va = NULL; - } + if (va && nb < vpap->len) { + /* + * If it's now too short, it must be that userspace + * has changed the mappings underlying guest memory, + * so unregister the region. + */ + kvmppc_unpin_guest_page(kvm, va); + va = NULL; } if (vpap->pinned_addr) kvmppc_unpin_guest_page(kvm, vpap->pinned_addr); @@ -296,20 +317,18 @@ static void kvmppc_update_vpa(struct kvm *kvm, struct kvmppc_vpa *vpap) static void kvmppc_update_vpas(struct kvm_vcpu *vcpu) { - struct kvm *kvm = vcpu->kvm; - spin_lock(&vcpu->arch.vpa_update_lock); if (vcpu->arch.vpa.update_pending) { - kvmppc_update_vpa(kvm, &vcpu->arch.vpa); + kvmppc_update_vpa(vcpu, &vcpu->arch.vpa); init_vpa(vcpu, vcpu->arch.vpa.pinned_addr); } if (vcpu->arch.dtl.update_pending) { - kvmppc_update_vpa(kvm, &vcpu->arch.dtl); + kvmppc_update_vpa(vcpu, &vcpu->arch.dtl); vcpu->arch.dtl_ptr = vcpu->arch.dtl.pinned_addr; vcpu->arch.dtl_index = 0; } if (vcpu->arch.slb_shadow.update_pending) - kvmppc_update_vpa(kvm, &vcpu->arch.slb_shadow); + kvmppc_update_vpa(vcpu, &vcpu->arch.slb_shadow); spin_unlock(&vcpu->arch.vpa_update_lock); } @@ -800,12 +819,39 @@ static int kvmppc_run_core(struct kvmppc_vcore *vc) struct kvm_vcpu *vcpu, *vcpu0, *vnext; long ret; u64 now; - int ptid, i; + int ptid, i, need_vpa_update; /* don't start if any threads have a signal pending */ - list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) + need_vpa_update = 0; + list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { if (signal_pending(vcpu->arch.run_task)) return 0; + need_vpa_update |= vcpu->arch.vpa.update_pending | + vcpu->arch.slb_shadow.update_pending | + vcpu->arch.dtl.update_pending; + } + + /* + * Initialize *vc, in particular vc->vcore_state, so we can + * drop the vcore lock if necessary. + */ + vc->n_woken = 0; + vc->nap_count = 0; + vc->entry_exit_count = 0; + vc->vcore_state = VCORE_RUNNING; + vc->in_guest = 0; + vc->napping_threads = 0; + + /* + * Updating any of the vpas requires calling kvmppc_pin_guest_page, + * which can't be called with any spinlocks held. + */ + if (need_vpa_update) { + spin_unlock(&vc->lock); + list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) + kvmppc_update_vpas(vcpu); + spin_lock(&vc->lock); + } /* * Make sure we are running on thread 0, and that @@ -838,20 +884,10 @@ static int kvmppc_run_core(struct kvmppc_vcore *vc) if (vcpu->arch.ceded) vcpu->arch.ptid = ptid++; - vc->n_woken = 0; - vc->nap_count = 0; - vc->entry_exit_count = 0; - vc->vcore_state = VCORE_RUNNING; vc->stolen_tb += mftb() - vc->preempt_tb; - vc->in_guest = 0; vc->pcpu = smp_processor_id(); - vc->napping_threads = 0; list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { kvmppc_start_thread(vcpu); - if (vcpu->arch.vpa.update_pending || - vcpu->arch.slb_shadow.update_pending || - vcpu->arch.dtl.update_pending) - kvmppc_update_vpas(vcpu); kvmppc_create_dtl_entry(vcpu, vc); } /* Grab any remaining hw threads so they can't go into the kernel */ diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 36f957f31842..8733a86ad52e 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -68,9 +68,7 @@ static const char *pseries_nvram_os_partitions[] = { }; static void oops_to_nvram(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason, - const char *old_msgs, unsigned long old_len, - const char *new_msgs, unsigned long new_len); + enum kmsg_dump_reason reason); static struct kmsg_dumper nvram_kmsg_dumper = { .dump = oops_to_nvram @@ -503,28 +501,6 @@ int __init pSeries_nvram_init(void) return 0; } -/* - * Try to capture the last capture_len bytes of the printk buffer. Return - * the amount actually captured. - */ -static size_t capture_last_msgs(const char *old_msgs, size_t old_len, - const char *new_msgs, size_t new_len, - char *captured, size_t capture_len) -{ - if (new_len >= capture_len) { - memcpy(captured, new_msgs + (new_len - capture_len), - capture_len); - return capture_len; - } else { - /* Grab the end of old_msgs. */ - size_t old_tail_len = min(old_len, capture_len - new_len); - memcpy(captured, old_msgs + (old_len - old_tail_len), - old_tail_len); - memcpy(captured + old_tail_len, new_msgs, new_len); - return old_tail_len + new_len; - } -} - /* * Are we using the ibm,rtas-log for oops/panic reports? And if so, * would logging this oops/panic overwrite an RTAS event that rtas_errd @@ -541,27 +517,6 @@ static int clobbering_unread_rtas_event(void) NVRAM_RTAS_READ_TIMEOUT); } -/* Squeeze out each line's severity prefix. */ -static size_t elide_severities(char *buf, size_t len) -{ - char *in, *out, *buf_end = buf + len; - /* Assume a at the very beginning marks the start of a line. */ - int newline = 1; - - in = out = buf; - while (in < buf_end) { - if (newline && in+3 <= buf_end && - *in == '<' && isdigit(in[1]) && in[2] == '>') { - in += 3; - newline = 0; - } else { - newline = (*in == '\n'); - *out++ = *in++; - } - } - return out - buf; -} - /* Derived from logfs_compress() */ static int nvram_compress(const void *in, void *out, size_t inlen, size_t outlen) @@ -619,9 +574,7 @@ static int zip_oops(size_t text_len) * partition. If that's too much, go back and capture uncompressed text. */ static void oops_to_nvram(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason, - const char *old_msgs, unsigned long old_len, - const char *new_msgs, unsigned long new_len) + enum kmsg_dump_reason reason) { static unsigned int oops_count = 0; static bool panicking = false; @@ -660,14 +613,14 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, return; if (big_oops_buf) { - text_len = capture_last_msgs(old_msgs, old_len, - new_msgs, new_len, big_oops_buf, big_oops_buf_sz); - text_len = elide_severities(big_oops_buf, text_len); + kmsg_dump_get_buffer(dumper, false, + big_oops_buf, big_oops_buf_sz, &text_len); rc = zip_oops(text_len); } if (rc != 0) { - text_len = capture_last_msgs(old_msgs, old_len, - new_msgs, new_len, oops_data, oops_data_sz); + kmsg_dump_rewind(dumper); + kmsg_dump_get_buffer(dumper, true, + oops_data, oops_data_sz, &text_len); err_type = ERR_TYPE_KERNEL_PANIC; *oops_len = (u16) text_len; } diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index 5cffdc55f075..3e244f31e56b 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c @@ -443,7 +443,7 @@ static int __init vio_init(void) root_vdev = vio_create_one(hp, root, NULL); err = -ENODEV; if (!root_vdev) { - printk(KERN_ERR "VIO: Coult not create root device.\n"); + printk(KERN_ERR "VIO: Could not create root device.\n"); goto out_release; } diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h index 43876f16caf1..cb00ccc7d571 100644 --- a/arch/x86/include/asm/pgtable-3level.h +++ b/arch/x86/include/asm/pgtable-3level.h @@ -47,16 +47,26 @@ static inline void native_set_pte(pte_t *ptep, pte_t pte) * they can run pmd_offset_map_lock or pmd_trans_huge or other pmd * operations. * - * Without THP if the mmap_sem is hold for reading, the - * pmd can only transition from null to not null while pmd_read_atomic runs. - * So there's no need of literally reading it atomically. + * Without THP if the mmap_sem is hold for reading, the pmd can only + * transition from null to not null while pmd_read_atomic runs. So + * we can always return atomic pmd values with this function. * * With THP if the mmap_sem is hold for reading, the pmd can become - * THP or null or point to a pte (and in turn become "stable") at any - * time under pmd_read_atomic, so it's mandatory to read it atomically - * with cmpxchg8b. + * trans_huge or none or point to a pte (and in turn become "stable") + * at any time under pmd_read_atomic. We could read it really + * atomically here with a atomic64_read for the THP enabled case (and + * it would be a whole lot simpler), but to avoid using cmpxchg8b we + * only return an atomic pmdval if the low part of the pmdval is later + * found stable (i.e. pointing to a pte). And we're returning a none + * pmdval if the low part of the pmd is none. In some cases the high + * and low part of the pmdval returned may not be consistent if THP is + * enabled (the low part may point to previously mapped hugepage, + * while the high part may point to a more recently mapped hugepage), + * but pmd_none_or_trans_huge_or_clear_bad() only needs the low part + * of the pmd to be read atomically to decide if the pmd is unstable + * or not, with the only exception of when the low part of the pmd is + * zero in which case we return a none pmd. */ -#ifndef CONFIG_TRANSPARENT_HUGEPAGE static inline pmd_t pmd_read_atomic(pmd_t *pmdp) { pmdval_t ret; @@ -74,12 +84,6 @@ static inline pmd_t pmd_read_atomic(pmd_t *pmdp) return (pmd_t) { ret }; } -#else /* CONFIG_TRANSPARENT_HUGEPAGE */ -static inline pmd_t pmd_read_atomic(pmd_t *pmdp) -{ - return (pmd_t) { atomic64_read((atomic64_t *)pmdp) }; -} -#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) { diff --git a/arch/x86/platform/mrst/early_printk_mrst.c b/arch/x86/platform/mrst/early_printk_mrst.c index 3c6e328483c7..028454f0c3a5 100644 --- a/arch/x86/platform/mrst/early_printk_mrst.c +++ b/arch/x86/platform/mrst/early_printk_mrst.c @@ -110,19 +110,16 @@ static struct kmsg_dumper dw_dumper; static int dumper_registered; static void dw_kmsg_dump(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason, - const char *s1, unsigned long l1, - const char *s2, unsigned long l2) + enum kmsg_dump_reason reason) { - int i; + static char line[1024]; + size_t len; /* When run to this, we'd better re-init the HW */ mrst_early_console_init(); - for (i = 0; i < l1; i++) - early_mrst_console.write(&early_mrst_console, s1 + i, 1); - for (i = 0; i < l2; i++) - early_mrst_console.write(&early_mrst_console, s2 + i, 1); + while (kmsg_dump_get_line(dumper, true, line, sizeof(line), &len)) + early_mrst_console.write(&early_mrst_console, line, len); } /* Set the ratio rate to 115200, 8n1, IRQ disabled */ diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 7608559de93a..f973754ddf90 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -68,8 +68,8 @@ endif # Only build variant and/or platform if it includes a Makefile -buildvar := $(shell test -a $(srctree)/arch/xtensa/variants/$(VARIANT)/Makefile && echo arch/xtensa/variants/$(VARIANT)/) -buildplf := $(shell test -a $(srctree)/arch/xtensa/platforms/$(PLATFORM)/Makefile && echo arch/xtensa/platforms/$(PLATFORM)/) +buildvar := $(shell test -e $(srctree)/arch/xtensa/variants/$(VARIANT)/Makefile && echo arch/xtensa/variants/$(VARIANT)/) +buildplf := $(shell test -e $(srctree)/arch/xtensa/platforms/$(PLATFORM)/Makefile && echo arch/xtensa/platforms/$(PLATFORM)/) # Find libgcc.a diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index 88ecea3facb4..ee2e2089483d 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -83,7 +83,6 @@ SECTIONS _text = .; _stext = .; - _ftext = .; .text : { @@ -112,7 +111,7 @@ SECTIONS EXCEPTION_TABLE(16) /* Data section */ - _fdata = .; + _sdata = .; RW_DATA_SECTION(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE) _edata = .; diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index ba150e5de2eb..db955179da2d 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -26,11 +26,7 @@ #include #include - -/* References to section boundaries */ - -extern char _ftext, _etext, _fdata, _edata, _rodata_end; -extern char __init_begin, __init_end; +#include /* * mem_reserve(start, end, must_exist) @@ -197,9 +193,9 @@ void __init mem_init(void) reservedpages++; } - codesize = (unsigned long) &_etext - (unsigned long) &_ftext; - datasize = (unsigned long) &_edata - (unsigned long) &_fdata; - initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; + codesize = (unsigned long) _etext - (unsigned long) _stext; + datasize = (unsigned long) _edata - (unsigned long) _sdata; + initsize = (unsigned long) __init_end - (unsigned long) __init_begin; printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, " "%ldk data, %ldk init %ldk highmem)\n", @@ -237,7 +233,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) void free_initmem(void) { - free_reserved_mem(&__init_begin, &__init_end); - printk("Freeing unused kernel memory: %dk freed\n", - (&__init_end - &__init_begin) >> 10); + free_reserved_mem(__init_begin, __init_end); + printk("Freeing unused kernel memory: %zuk freed\n", + (__init_end - __init_begin) >> 10); } diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 3239517f4d90..ac6a5beb28f3 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -4,7 +4,7 @@ * Arasan Compact Flash host controller source file * * Copyright (C) 2011 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -959,7 +959,7 @@ static struct platform_driver arasan_cf_driver = { module_platform_driver(arasan_cf_driver); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("Arasan ATA Compact Flash driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 1b1cbb571d38..dcb8a6e48692 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -100,7 +100,7 @@ static void driver_deferred_probe_add(struct device *dev) mutex_lock(&deferred_probe_mutex); if (list_empty(&dev->p->deferred_probe)) { dev_dbg(dev, "Added to deferred list\n"); - list_add(&dev->p->deferred_probe, &deferred_probe_pending_list); + list_add_tail(&dev->p->deferred_probe, &deferred_probe_pending_list); } mutex_unlock(&deferred_probe_mutex); } diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 0a4185279417..92622d44e12d 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -12,6 +12,7 @@ #include #include "agp.h" #include "intel-agp.h" +#include int intel_agp_enabled; EXPORT_SYMBOL(intel_agp_enabled); @@ -747,7 +748,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, bridge->capndx = cap_ptr; - if (intel_gmch_probe(pdev, bridge)) + if (intel_gmch_probe(pdev, NULL, bridge)) goto found_gmch; for (i = 0; intel_agp_chipsets[i].name != NULL; i++) { @@ -824,7 +825,7 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev) agp_remove_bridge(bridge); - intel_gmch_remove(pdev); + intel_gmch_remove(); agp_put_bridge(bridge); } diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index 8e2d9140f300..57226424690c 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h @@ -251,7 +251,4 @@ #define PCI_DEVICE_ID_INTEL_HASWELL_SDV 0x0c16 /* SDV */ #define PCI_DEVICE_ID_INTEL_HASWELL_E_HB 0x0c04 -int intel_gmch_probe(struct pci_dev *pdev, - struct agp_bridge_data *bridge); -void intel_gmch_remove(struct pci_dev *pdev); #endif diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 1237e7575c3f..9ed92ef5829b 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -66,7 +66,6 @@ static struct _intel_private { struct pci_dev *bridge_dev; u8 __iomem *registers; phys_addr_t gtt_bus_addr; - phys_addr_t gma_bus_addr; u32 PGETBL_save; u32 __iomem *gtt; /* I915G */ bool clear_fake_agp; /* on first access via agp, fill with scratch */ @@ -76,6 +75,7 @@ static struct _intel_private { struct resource ifp_resource; int resource_valid; struct page *scratch_page; + int refcount; } intel_private; #define INTEL_GTT_GEN intel_private.driver->gen @@ -648,6 +648,7 @@ static void intel_gtt_cleanup(void) static int intel_gtt_init(void) { + u32 gma_addr; u32 gtt_map_size; int ret; @@ -694,6 +695,15 @@ static int intel_gtt_init(void) return ret; } + if (INTEL_GTT_GEN <= 2) + pci_read_config_dword(intel_private.pcidev, I810_GMADDR, + &gma_addr); + else + pci_read_config_dword(intel_private.pcidev, I915_GMADDR, + &gma_addr); + + intel_private.base.gma_bus_addr = (gma_addr & PCI_BASE_ADDRESS_MEM_MASK); + return 0; } @@ -767,20 +777,10 @@ static void i830_write_entry(dma_addr_t addr, unsigned int entry, writel(addr | pte_flags, intel_private.gtt + entry); } -static bool intel_enable_gtt(void) +bool intel_enable_gtt(void) { - u32 gma_addr; u8 __iomem *reg; - if (INTEL_GTT_GEN <= 2) - pci_read_config_dword(intel_private.pcidev, I810_GMADDR, - &gma_addr); - else - pci_read_config_dword(intel_private.pcidev, I915_GMADDR, - &gma_addr); - - intel_private.gma_bus_addr = (gma_addr & PCI_BASE_ADDRESS_MEM_MASK); - if (INTEL_GTT_GEN >= 6) return true; @@ -823,6 +823,7 @@ static bool intel_enable_gtt(void) return true; } +EXPORT_SYMBOL(intel_enable_gtt); static int i830_setup(void) { @@ -860,7 +861,7 @@ static int intel_fake_agp_configure(void) return -EIO; intel_private.clear_fake_agp = true; - agp_bridge->gart_bus_addr = intel_private.gma_bus_addr; + agp_bridge->gart_bus_addr = intel_private.base.gma_bus_addr; return 0; } @@ -1182,9 +1183,17 @@ static void gen6_write_entry(dma_addr_t addr, unsigned int entry, static void valleyview_write_entry(dma_addr_t addr, unsigned int entry, unsigned int flags) { + unsigned int type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT; + unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT; u32 pte_flags; - pte_flags = GEN6_PTE_UNCACHED | I810_PTE_VALID; + if (type_mask == AGP_USER_MEMORY) + pte_flags = GEN6_PTE_UNCACHED | I810_PTE_VALID; + else { + pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; + if (gfdt) + pte_flags |= GEN6_PTE_GFDT; + } /* gen6 has bit11-4 for physical addr bit39-32 */ addr |= (addr >> 28) & 0xff0; @@ -1244,6 +1253,7 @@ static int i9xx_setup(void) switch (INTEL_GTT_GEN) { case 5: case 6: + case 7: gtt_offset = MB(2); break; case 4: @@ -1379,7 +1389,6 @@ static const struct intel_gtt_driver valleyview_gtt_driver = { .write_entry = valleyview_write_entry, .dma_mask_size = 40, .check_flags = gen6_check_flags, - .chipset_flush = i9xx_chipset_flush, }; /* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of @@ -1523,14 +1532,32 @@ static int find_gmch(u16 device) return 1; } -int intel_gmch_probe(struct pci_dev *pdev, - struct agp_bridge_data *bridge) +int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, + struct agp_bridge_data *bridge) { int i, mask; - intel_private.driver = NULL; + + /* + * Can be called from the fake agp driver but also directly from + * drm/i915.ko. Hence we need to check whether everything is set up + * already. + */ + if (intel_private.driver) { + intel_private.refcount++; + return 1; + } for (i = 0; intel_gtt_chipsets[i].name != NULL; i++) { - if (find_gmch(intel_gtt_chipsets[i].gmch_chip_id)) { + if (gpu_pdev) { + if (gpu_pdev->device == + intel_gtt_chipsets[i].gmch_chip_id) { + intel_private.pcidev = pci_dev_get(gpu_pdev); + intel_private.driver = + intel_gtt_chipsets[i].gtt_driver; + + break; + } + } else if (find_gmch(intel_gtt_chipsets[i].gmch_chip_id)) { intel_private.driver = intel_gtt_chipsets[i].gtt_driver; break; @@ -1540,13 +1567,17 @@ int intel_gmch_probe(struct pci_dev *pdev, if (!intel_private.driver) return 0; - bridge->driver = &intel_fake_agp_driver; - bridge->dev_private_data = &intel_private; - bridge->dev = pdev; + intel_private.refcount++; - intel_private.bridge_dev = pci_dev_get(pdev); + if (bridge) { + bridge->driver = &intel_fake_agp_driver; + bridge->dev_private_data = &intel_private; + bridge->dev = bridge_pdev; + } - dev_info(&pdev->dev, "Intel %s Chipset\n", intel_gtt_chipsets[i].name); + intel_private.bridge_dev = pci_dev_get(bridge_pdev); + + dev_info(&bridge_pdev->dev, "Intel %s Chipset\n", intel_gtt_chipsets[i].name); mask = intel_private.driver->dma_mask_size; if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask))) @@ -1556,11 +1587,11 @@ int intel_gmch_probe(struct pci_dev *pdev, pci_set_consistent_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask)); - /*if (bridge->driver == &intel_810_driver) - return 1;*/ + if (intel_gtt_init() != 0) { + intel_gmch_remove(); - if (intel_gtt_init() != 0) return 0; + } return 1; } @@ -1579,12 +1610,16 @@ void intel_gtt_chipset_flush(void) } EXPORT_SYMBOL(intel_gtt_chipset_flush); -void intel_gmch_remove(struct pci_dev *pdev) +void intel_gmch_remove(void) { + if (--intel_private.refcount) + return; + if (intel_private.pcidev) pci_dev_put(intel_private.pcidev); if (intel_private.bridge_dev) pci_dev_put(intel_private.bridge_dev); + intel_private.driver = NULL; } EXPORT_SYMBOL(intel_gmch_remove); diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c index 6289f0eee24c..731c9046cf7b 100644 --- a/drivers/char/hw_random/atmel-rng.c +++ b/drivers/char/hw_random/atmel-rng.c @@ -34,7 +34,7 @@ static int atmel_trng_read(struct hwrng *rng, void *buf, size_t max, u32 *data = buf; /* data ready? */ - if (readl(trng->base + TRNG_ODATA) & 1) { + if (readl(trng->base + TRNG_ISR) & 1) { *data = readl(trng->base + TRNG_ODATA); /* ensure data ready is only set again AFTER the next data diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c index af34074e702b..6756e7c3bc07 100644 --- a/drivers/clk/spear/clk-aux-synth.c +++ b/drivers/clk/spear/clk-aux-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c index 4dbdb3fe18e0..958aa3ad1d60 100644 --- a/drivers/clk/spear/clk-frac-synth.c +++ b/drivers/clk/spear/clk-frac-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c index b471c9762a97..1afc18c4effc 100644 --- a/drivers/clk/spear/clk-gpt-synth.c +++ b/drivers/clk/spear/clk-gpt-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c index dcd4bdf4b0d9..5f1b6badeb15 100644 --- a/drivers/clk/spear/clk-vco-pll.c +++ b/drivers/clk/spear/clk-vco-pll.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk.c b/drivers/clk/spear/clk.c index 376d4e5ff326..7cd63788d546 100644 --- a/drivers/clk/spear/clk.c +++ b/drivers/clk/spear/clk.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk.h b/drivers/clk/spear/clk.h index 3321c46a071c..931737677dfa 100644 --- a/drivers/clk/spear/clk.h +++ b/drivers/clk/spear/clk.h @@ -2,7 +2,7 @@ * Clock framework definitions for SPEAr platform * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index 42b68df9aeef..8f05652d53e6 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -4,7 +4,7 @@ * SPEAr1310 machine clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index f130919d5bf8..e3ea72162236 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -4,7 +4,7 @@ * SPEAr1340 machine clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index 440bb3e4c971..01dd6daff2a1 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -2,7 +2,7 @@ * SPEAr3xx machines clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index f9a20b382304..554d64b062a1 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c @@ -2,7 +2,7 @@ * SPEAr6xx machines clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index e23dc82d43ac..721296157577 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -1626,4 +1626,4 @@ module_exit(dw_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver"); MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index fb4f4990f5eb..1dc2a4ad0026 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -815,8 +815,6 @@ static int sdma_request_channel(struct sdma_channel *sdmac) init_completion(&sdmac->done); - sdmac->buf_tail = 0; - return 0; out: @@ -927,6 +925,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( sdmac->flags = 0; + sdmac->buf_tail = 0; + dev_dbg(sdma->dev, "setting up %d entries for channel %d.\n", sg_len, channel); @@ -1027,6 +1027,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( sdmac->status = DMA_IN_PROGRESS; + sdmac->buf_tail = 0; + sdmac->flags |= IMX_DMA_SG_LOOP; sdmac->direction = direction; ret = sdma_load_context(sdmac); diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index cbcc28e79be6..e4feba6b03c0 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -392,6 +392,8 @@ struct pl330_req { struct pl330_reqcfg *cfg; /* Pointer to first xfer in the request. */ struct pl330_xfer *x; + /* Hook to attach to DMAC's list of reqs with due callback */ + struct list_head rqd; }; /* @@ -461,8 +463,6 @@ struct _pl330_req { /* Number of bytes taken to setup MC for the req */ u32 mc_len; struct pl330_req *r; - /* Hook to attach to DMAC's list of reqs with due callback */ - struct list_head rqd; }; /* ToBeDone for tasklet */ @@ -1683,7 +1683,7 @@ static void pl330_dotask(unsigned long data) /* Returns 1 if state was updated, 0 otherwise */ static int pl330_update(const struct pl330_info *pi) { - struct _pl330_req *rqdone; + struct pl330_req *rqdone, *tmp; struct pl330_dmac *pl330; unsigned long flags; void __iomem *regs; @@ -1750,7 +1750,10 @@ static int pl330_update(const struct pl330_info *pi) if (active == -1) /* Aborted */ continue; - rqdone = &thrd->req[active]; + /* Detach the req */ + rqdone = thrd->req[active].r; + thrd->req[active].r = NULL; + mark_free(thrd, active); /* Get going again ASAP */ @@ -1762,20 +1765,11 @@ static int pl330_update(const struct pl330_info *pi) } /* Now that we are in no hurry, do the callbacks */ - while (!list_empty(&pl330->req_done)) { - struct pl330_req *r; - - rqdone = container_of(pl330->req_done.next, - struct _pl330_req, rqd); - - list_del_init(&rqdone->rqd); - - /* Detach the req */ - r = rqdone->r; - rqdone->r = NULL; + list_for_each_entry_safe(rqdone, tmp, &pl330->req_done, rqd) { + list_del(&rqdone->rqd); spin_unlock_irqrestore(&pl330->lock, flags); - _callback(r, PL330_ERR_NONE); + _callback(rqdone, PL330_ERR_NONE); spin_lock_irqsave(&pl330->lock, flags); } @@ -2321,7 +2315,7 @@ static void pl330_tasklet(unsigned long data) /* Pick up ripe tomatoes */ list_for_each_entry_safe(desc, _dt, &pch->work_list, node) if (desc->status == DONE) { - if (pch->cyclic) + if (!pch->cyclic) dma_cookie_complete(&desc->txd); list_move_tail(&desc->node, &list); } @@ -2539,7 +2533,7 @@ static inline void _init_desc(struct dma_pl330_desc *desc) } /* Returns the number of descriptors added to the DMAC pool */ -int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) +static int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) { struct dma_pl330_desc *desc; unsigned long flags; diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 10f375032e96..de5ba86e8b89 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -164,7 +164,7 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems) else return (char *)ptr; - r = size % align; + r = (unsigned long)p % align; if (r == 0) return (char *)ptr; diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index d27778f65a5d..a499c7ed820a 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1814,12 +1814,6 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val, if (mce->bank != 8) return NOTIFY_DONE; -#ifdef CONFIG_SMP - /* Only handle if it is the right mc controller */ - if (mce->socketid != pvt->i7core_dev->socket) - return NOTIFY_DONE; -#endif - smp_rmb(); if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) { smp_wmb(); @@ -2116,8 +2110,6 @@ static void i7core_unregister_mci(struct i7core_dev *i7core_dev) if (pvt->enable_scrub) disable_sdram_scrub_setting(mci); - mce_unregister_decode_chain(&i7_mce_dec); - /* Disable EDAC polling */ i7core_pci_ctl_release(pvt); @@ -2222,8 +2214,6 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev) /* DCLK for scrub rate setting */ pvt->dclk_freq = get_dclk_freq(); - mce_register_decode_chain(&i7_mce_dec); - return 0; fail0: @@ -2367,8 +2357,10 @@ static int __init i7core_init(void) pci_rc = pci_register_driver(&i7core_driver); - if (pci_rc >= 0) + if (pci_rc >= 0) { + mce_register_decode_chain(&i7_mce_dec); return 0; + } i7core_printk(KERN_ERR, "Failed to register device with error %d.\n", pci_rc); @@ -2384,6 +2376,7 @@ static void __exit i7core_exit(void) { debugf2("MC: " __FILE__ ": %s()\n", __func__); pci_unregister_driver(&i7core_driver); + mce_unregister_decode_chain(&i7_mce_dec); } module_init(i7core_init); diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 4c402353ba98..0e374625f6f8 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -980,7 +980,8 @@ static int __devinit mpc85xx_mc_err_probe(struct platform_device *op) layers[1].type = EDAC_MC_LAYER_CHANNEL; layers[1].size = 1; layers[1].is_virt_csrow = false; - mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), sizeof(*pdata)); + mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), layers, + sizeof(*pdata)); if (!mci) { devres_release_group(&op->dev, mpc85xx_mc_err_probe); return -ENOMEM; diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index 4adaf4b7da99..36ad17e79d61 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -555,7 +555,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) pvt->is_close_pg = false; } - pci_read_config_dword(pvt->pci_ta, RANK_CFG_A, ®); + pci_read_config_dword(pvt->pci_ddrio, RANK_CFG_A, ®); if (IS_RDIMM_ENABLED(reg)) { /* FIXME: Can also be LRDIMM */ debugf0("Memory is registered\n"); @@ -1604,8 +1604,6 @@ static void sbridge_unregister_mci(struct sbridge_dev *sbridge_dev) debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n", __func__, mci, &sbridge_dev->pdev[0]->dev); - mce_unregister_decode_chain(&sbridge_mce_dec); - /* Remove MC sysfs nodes */ edac_mc_del_mc(mci->dev); @@ -1682,7 +1680,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev) goto fail0; } - mce_register_decode_chain(&sbridge_mce_dec); return 0; fail0: @@ -1811,8 +1808,10 @@ static int __init sbridge_init(void) pci_rc = pci_register_driver(&sbridge_driver); - if (pci_rc >= 0) + if (pci_rc >= 0) { + mce_register_decode_chain(&sbridge_mce_dec); return 0; + } sbridge_printk(KERN_ERR, "Failed to register device with error %d.\n", pci_rc); @@ -1828,6 +1827,7 @@ static void __exit sbridge_exit(void) { debugf2("MC: " __FILE__ ": %s()\n", __func__); pci_unregister_driver(&sbridge_driver); + mce_unregister_decode_chain(&sbridge_mce_dec); } module_init(sbridge_init); diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 23416e443765..a4ed30bd9a41 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -116,8 +116,8 @@ const char *max8997_extcon_cable[] = { [5] = "Charge-downstream", [6] = "MHL", [7] = "Dock-desk", - [7] = "Dock-card", - [8] = "JIG", + [8] = "Dock-card", + [9] = "JIG", NULL, }; @@ -514,6 +514,7 @@ static int __devexit max8997_muic_remove(struct platform_device *pdev) extcon_dev_unregister(info->edev); + kfree(info->edev); kfree(info); return 0; diff --git a/drivers/extcon/extcon_class.c b/drivers/extcon/extcon_class.c index f598a700ec15..159aeb07b3ba 100644 --- a/drivers/extcon/extcon_class.c +++ b/drivers/extcon/extcon_class.c @@ -762,7 +762,7 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev) #if defined(CONFIG_ANDROID) if (switch_class) ret = class_compat_create_link(switch_class, edev->dev, - dev); + NULL); #endif /* CONFIG_ANDROID */ spin_lock_init(&edev->lock); diff --git a/drivers/extcon/extcon_gpio.c b/drivers/extcon/extcon_gpio.c index fe7a07b47336..8a0dcc11c7c7 100644 --- a/drivers/extcon/extcon_gpio.c +++ b/drivers/extcon/extcon_gpio.c @@ -125,6 +125,7 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev) if (ret < 0) goto err_request_irq; + platform_set_drvdata(pdev, extcon_data); /* Perform initial detection */ gpio_extcon_work(&extcon_data->work.work); @@ -146,6 +147,7 @@ static int __devexit gpio_extcon_remove(struct platform_device *pdev) struct gpio_extcon_data *extcon_data = platform_get_drvdata(pdev); cancel_delayed_work_sync(&extcon_data->work); + free_irq(extcon_data->irq, extcon_data); gpio_free(extcon_data->gpio); extcon_dev_unregister(&extcon_data->edev); devm_kfree(&pdev->dev, extcon_data); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index eb92fe257a39..5873e481e5d2 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -610,7 +610,7 @@ static bool drm_monitor_supports_rb(struct edid *edid) { if (edid->revision >= 4) { - bool ret; + bool ret = false; drm_for_each_detailed_block((u8 *)edid, is_rb, &ret); return ret; } diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 2e9268da58d8..b0bacdba6d7e 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -7,6 +7,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ i915_debugfs.o \ i915_suspend.o \ i915_gem.o \ + i915_gem_context.o \ i915_gem_debug.o \ i915_gem_evict.o \ i915_gem_execbuffer.o \ diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4fa00fcfbc96..2909b123baf5 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -713,6 +713,7 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, "EIR: 0x%08x\n", error->eir); seq_printf(m, "IER: 0x%08x\n", error->ier); seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); + seq_printf(m, "CCID: 0x%08x\n", error->ccid); for (i = 0; i < dev_priv->num_fence_regs; i++) seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 262a74d1f852..9563ab8390e7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1006,6 +1006,9 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_ALIASING_PPGTT: value = dev_priv->mm.aliasing_ppgtt ? 1 : 0; break; + case I915_PARAM_HAS_WAIT_TIMEOUT: + value = 1; + break; default: DRM_DEBUG_DRIVER("Unknown parameter %d\n", param->param); @@ -1082,8 +1085,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data, ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12); - dev_priv->dri1.gfx_hws_cpu_addr = ioremap_wc(dev->agp->base + hws->addr, - 4096); + dev_priv->dri1.gfx_hws_cpu_addr = + ioremap_wc(dev_priv->mm.gtt_base_addr + hws->addr, 4096); if (dev_priv->dri1.gfx_hws_cpu_addr == NULL) { i915_dma_cleanup(dev); ring->status_page.gfx_addr = 0; @@ -1401,6 +1404,27 @@ i915_mtrr_setup(struct drm_i915_private *dev_priv, unsigned long base, } } +static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) +{ + struct apertures_struct *ap; + struct pci_dev *pdev = dev_priv->dev->pdev; + bool primary; + + ap = alloc_apertures(1); + if (!ap) + return; + + ap->ranges[0].base = dev_priv->dev->agp->base; + ap->ranges[0].size = + dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; + primary = + pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; + + remove_conflicting_framebuffers(ap, "inteldrmfb", primary); + + kfree(ap); +} + /** * i915_driver_load - setup chip and create an initial config * @dev: DRM device @@ -1446,6 +1470,22 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto free_priv; } + ret = intel_gmch_probe(dev_priv->bridge_dev, dev->pdev, NULL); + if (!ret) { + DRM_ERROR("failed to set up gmch\n"); + ret = -EIO; + goto put_bridge; + } + + dev_priv->mm.gtt = intel_gtt_get(); + if (!dev_priv->mm.gtt) { + DRM_ERROR("Failed to initialize GTT\n"); + ret = -ENODEV; + goto put_gmch; + } + + i915_kick_out_firmware_fb(dev_priv); + pci_set_master(dev->pdev); /* overlay on gen2 is broken and can't address above 1G */ @@ -1468,26 +1508,22 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (!dev_priv->regs) { DRM_ERROR("failed to map registers\n"); ret = -EIO; - goto put_bridge; - } - - dev_priv->mm.gtt = intel_gtt_get(); - if (!dev_priv->mm.gtt) { - DRM_ERROR("Failed to initialize GTT\n"); - ret = -ENODEV; - goto out_rmmap; + goto put_gmch; } aperture_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; + dev_priv->mm.gtt_base_addr = dev_priv->mm.gtt->gma_bus_addr; dev_priv->mm.gtt_mapping = - io_mapping_create_wc(dev->agp->base, aperture_size); + io_mapping_create_wc(dev_priv->mm.gtt_base_addr, + aperture_size); if (dev_priv->mm.gtt_mapping == NULL) { ret = -EIO; goto out_rmmap; } - i915_mtrr_setup(dev_priv, dev->agp->base, aperture_size); + i915_mtrr_setup(dev_priv, dev_priv->mm.gtt_base_addr, + aperture_size); /* The i915 workqueue is primarily used for batched retirement of * requests (and thus managing bo) once the task has been completed @@ -1599,13 +1635,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) destroy_workqueue(dev_priv->wq); out_mtrrfree: if (dev_priv->mm.gtt_mtrr >= 0) { - mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, - dev->agp->agp_info.aper_size * 1024 * 1024); + mtrr_del(dev_priv->mm.gtt_mtrr, + dev_priv->mm.gtt_base_addr, + aperture_size); dev_priv->mm.gtt_mtrr = -1; } io_mapping_free(dev_priv->mm.gtt_mapping); out_rmmap: pci_iounmap(dev->pdev, dev_priv->regs); +put_gmch: + intel_gmch_remove(); put_bridge: pci_dev_put(dev_priv->bridge_dev); free_priv: @@ -1637,8 +1676,9 @@ int i915_driver_unload(struct drm_device *dev) io_mapping_free(dev_priv->mm.gtt_mapping); if (dev_priv->mm.gtt_mtrr >= 0) { - mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, - dev->agp->agp_info.aper_size * 1024 * 1024); + mtrr_del(dev_priv->mm.gtt_mtrr, + dev_priv->mm.gtt_base_addr, + dev_priv->mm.gtt->gtt_mappable_entries * PAGE_SIZE); dev_priv->mm.gtt_mtrr = -1; } @@ -1679,6 +1719,7 @@ int i915_driver_unload(struct drm_device *dev) mutex_lock(&dev->struct_mutex); i915_gem_free_all_phys_object(dev); i915_gem_cleanup_ringbuffer(dev); + i915_gem_context_fini(dev); mutex_unlock(&dev->struct_mutex); i915_gem_cleanup_aliasing_ppgtt(dev); i915_gem_cleanup_stolen(dev); @@ -1718,6 +1759,8 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file) spin_lock_init(&file_priv->mm.lock); INIT_LIST_HEAD(&file_priv->mm.request_list); + idr_init(&file_priv->context_idr); + return 0; } @@ -1750,6 +1793,7 @@ void i915_driver_lastclose(struct drm_device * dev) void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) { + i915_gem_context_close(dev, file_priv); i915_gem_release(dev, file_priv); } @@ -1804,6 +1848,8 @@ struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, intel_sprite_get_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_UNLOCKED), }; int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 9fe9ebe52a7a..a378c0800304 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -358,6 +358,9 @@ static const struct pci_device_id pciidlist[] = { /* aka */ INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ INTEL_VGA_DEVICE(0x0c16, &intel_haswell_d_info), /* SDV */ + INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), + INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), + INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), {0, 0, 0} }; @@ -805,7 +808,7 @@ static int gen6_do_reset(struct drm_device *dev) return ret; } -static int intel_gpu_reset(struct drm_device *dev) +int intel_gpu_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int ret = -ENODEV; @@ -866,8 +869,6 @@ int i915_reset(struct drm_device *dev) if (!mutex_trylock(&dev->struct_mutex)) return -EBUSY; - dev_priv->stop_rings = 0; - i915_gem_reset(dev); ret = -ENODEV; @@ -909,12 +910,16 @@ int i915_reset(struct drm_device *dev) for_each_ring(ring, dev_priv, i) ring->init(ring); + i915_gem_context_init(dev); i915_gem_init_ppgtt(dev); - mutex_unlock(&dev->struct_mutex); + /* + * It would make sense to re-init all the other hw state, at + * least the rps/rc6/emon init done within modeset_init_hw. For + * some unknown reason, this blows up my ilk, so don't. + */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) - intel_modeset_init_hw(dev); + mutex_unlock(&dev->struct_mutex); drm_irq_uninstall(dev); drm_irq_install(dev); @@ -1149,6 +1154,84 @@ MODULE_LICENSE("GPL and additional rights"); ((reg) < 0x40000) && \ ((reg) != FORCEWAKE)) +static bool IS_DISPLAYREG(u32 reg) +{ + /* + * This should make it easier to transition modules over to the + * new register block scheme, since we can do it incrementally. + */ + if (reg >= 0x180000) + return false; + + if (reg >= RENDER_RING_BASE && + reg < RENDER_RING_BASE + 0xff) + return false; + if (reg >= GEN6_BSD_RING_BASE && + reg < GEN6_BSD_RING_BASE + 0xff) + return false; + if (reg >= BLT_RING_BASE && + reg < BLT_RING_BASE + 0xff) + return false; + + if (reg == PGTBL_ER) + return false; + + if (reg >= IPEIR_I965 && + reg < HWSTAM) + return false; + + if (reg == MI_MODE) + return false; + + if (reg == GFX_MODE_GEN7) + return false; + + if (reg == RENDER_HWS_PGA_GEN7 || + reg == BSD_HWS_PGA_GEN7 || + reg == BLT_HWS_PGA_GEN7) + return false; + + if (reg == GEN6_BSD_SLEEP_PSMI_CONTROL || + reg == GEN6_BSD_RNCID) + return false; + + if (reg == GEN6_BLITTER_ECOSKPD) + return false; + + if (reg >= 0x4000c && + reg <= 0x4002c) + return false; + + if (reg >= 0x4f000 && + reg <= 0x4f08f) + return false; + + if (reg >= 0x4f100 && + reg <= 0x4f11f) + return false; + + if (reg >= VLV_MASTER_IER && + reg <= GEN6_PMIER) + return false; + + if (reg >= FENCE_REG_SANDYBRIDGE_0 && + reg < (FENCE_REG_SANDYBRIDGE_0 + (16*8))) + return false; + + if (reg >= VLV_IIR_RW && + reg <= VLV_ISR) + return false; + + if (reg == FORCEWAKE_VLV || + reg == FORCEWAKE_ACK_VLV) + return false; + + if (reg == GEN6_GDRST) + return false; + + return true; +} + #define __i915_read(x, y) \ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ u##x val = 0; \ @@ -1161,6 +1244,8 @@ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ if (dev_priv->forcewake_count == 0) \ dev_priv->display.force_wake_put(dev_priv); \ spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ + } else if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \ + val = read##y(dev_priv->regs + reg + 0x180000); \ } else { \ val = read##y(dev_priv->regs + reg); \ } \ @@ -1181,7 +1266,11 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ } \ - write##y(val, dev_priv->regs + reg); \ + if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \ + write##y(val, dev_priv->regs + reg + 0x180000); \ + } else { \ + write##y(val, dev_priv->regs + reg); \ + } \ if (unlikely(__fifo_ret)) { \ gen6_gt_check_fifodbg(dev_priv); \ } \ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7cc36dbffbd8..a0c15abbdcef 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -176,6 +176,7 @@ struct drm_i915_error_state { u32 eir; u32 pgtbl_er; u32 ier; + u32 ccid; bool waiting[I915_NUM_RINGS]; u32 pipestat[I915_MAX_PIPES]; u32 tail[I915_NUM_RINGS]; @@ -309,6 +310,17 @@ struct i915_hw_ppgtt { dma_addr_t scratch_page_dma_addr; }; + +/* This must match up with the value previously used for execbuf2.rsvd1. */ +#define DEFAULT_CONTEXT_ID 0 +struct i915_hw_context { + int id; + bool is_initialized; + struct drm_i915_file_private *file_priv; + struct intel_ring_buffer *ring; + struct drm_i915_gem_object *obj; +}; + enum no_fbc_reason { FBC_NO_OUTPUT, /* no outputs enabled to compress */ FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */ @@ -652,6 +664,7 @@ typedef struct drm_i915_private { unsigned long gtt_end; struct io_mapping *gtt_mapping; + phys_addr_t gtt_base_addr; int gtt_mtrr; /** PPGTT used for aliasing the PPGTT with the GTT */ @@ -821,6 +834,8 @@ typedef struct drm_i915_private { struct drm_property *force_audio_property; struct work_struct parity_error_work; + bool hw_contexts_disabled; + uint32_t hw_context_size; } drm_i915_private_t; /* Iterate over initialised rings */ @@ -1030,6 +1045,7 @@ struct drm_i915_file_private { struct spinlock lock; struct list_head request_list; } mm; + struct idr context_idr; }; #define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) @@ -1075,7 +1091,8 @@ struct drm_i915_file_private { #define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) -#define HAS_ALIASING_PPGTT(dev) (INTEL_INFO(dev)->gen >=6) +#define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6) +#define HAS_ALIASING_PPGTT(dev) (INTEL_INFO(dev)->gen >=6 && !IS_VALLEYVIEW(dev)) #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) @@ -1170,6 +1187,7 @@ extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, extern int i915_emit_box(struct drm_device *dev, struct drm_clip_rect *box, int DR1, int DR4); +extern int intel_gpu_reset(struct drm_device *dev); extern int i915_reset(struct drm_device *dev); extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); @@ -1365,6 +1383,16 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, struct dma_buf *i915_gem_prime_export(struct drm_device *dev, struct drm_gem_object *gem_obj, int flags); +/* i915_gem_context.c */ +void i915_gem_context_init(struct drm_device *dev); +void i915_gem_context_fini(struct drm_device *dev); +void i915_gem_context_close(struct drm_device *dev, struct drm_file *file); +int i915_switch_context(struct intel_ring_buffer *ring, + struct drm_file *file, int to_id); +int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); +int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); /* i915_gem_gtt.c */ int __must_check i915_gem_init_aliasing_ppgtt(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index af67803e635f..6a98c0659324 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1122,7 +1122,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) obj->fault_mappable = true; - pfn = ((dev->agp->base + obj->gtt_offset) >> PAGE_SHIFT) + + pfn = ((dev_priv->mm.gtt_base_addr + obj->gtt_offset) >> PAGE_SHIFT) + page_offset; /* Finally, remap it using the new GTT offset */ @@ -1568,6 +1568,21 @@ i915_add_request(struct intel_ring_buffer *ring, int was_empty; int ret; + /* + * Emit any outstanding flushes - execbuf can fail to emit the flush + * after having emitted the batchbuffer command. Hence we need to fix + * things up similar to emitting the lazy request. The difference here + * is that the flush _must_ happen before the next request, no matter + * what. + */ + if (ring->gpu_caches_dirty) { + ret = i915_gem_flush_ring(ring, 0, I915_GEM_GPU_DOMAINS); + if (ret) + return ret; + + ring->gpu_caches_dirty = false; + } + BUG_ON(request == NULL); seqno = i915_gem_next_request_seqno(ring); @@ -1613,6 +1628,9 @@ i915_add_request(struct intel_ring_buffer *ring, queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); } + + WARN_ON(!list_empty(&ring->gpu_write_list)); + return 0; } @@ -1827,14 +1845,11 @@ i915_gem_retire_work_handler(struct work_struct *work) */ idle = true; for_each_ring(ring, dev_priv, i) { - if (!list_empty(&ring->gpu_write_list)) { + if (ring->gpu_caches_dirty) { struct drm_i915_gem_request *request; - int ret; - ret = i915_gem_flush_ring(ring, - 0, I915_GEM_GPU_DOMAINS); request = kzalloc(sizeof(*request), GFP_KERNEL); - if (ret || request == NULL || + if (request == NULL || i915_add_request(ring, NULL, request)) kfree(request); } @@ -2082,11 +2097,14 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) struct drm_i915_gem_wait *args = data; struct drm_i915_gem_object *obj; struct intel_ring_buffer *ring = NULL; - struct timespec timeout; + struct timespec timeout_stack, *timeout = NULL; u32 seqno = 0; int ret = 0; - timeout = ns_to_timespec(args->timeout_ns); + if (args->timeout_ns >= 0) { + timeout_stack = ns_to_timespec(args->timeout_ns); + timeout = &timeout_stack; + } ret = i915_mutex_lock_interruptible(dev); if (ret) @@ -2122,9 +2140,11 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); - ret = __wait_seqno(ring, seqno, true, &timeout); - WARN_ON(!timespec_valid(&timeout)); - args->timeout_ns = timespec_to_ns(&timeout); + ret = __wait_seqno(ring, seqno, true, timeout); + if (timeout) { + WARN_ON(!timespec_valid(timeout)); + args->timeout_ns = timespec_to_ns(timeout); + } return ret; out: @@ -2327,6 +2347,10 @@ int i915_gpu_idle(struct drm_device *dev) /* Is the device fubar? */ if (WARN_ON(!list_empty(&ring->gpu_write_list))) return -EBUSY; + + ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); + if (ret) + return ret; } return 0; @@ -3684,6 +3708,9 @@ i915_gem_init_hw(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; int ret; + if (!intel_enable_gtt()) + return -EIO; + i915_gem_l3_remap(dev); i915_gem_init_swizzling(dev); @@ -3706,6 +3733,11 @@ i915_gem_init_hw(struct drm_device *dev) dev_priv->next_seqno = 1; + /* + * XXX: There was some w/a described somewhere suggesting loading + * contexts before PPGTT. + */ + i915_gem_context_init(dev); i915_gem_init_ppgtt(dev); return 0; diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c new file mode 100644 index 000000000000..e58e8366f473 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -0,0 +1,535 @@ +/* + * Copyright © 2011-2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Ben Widawsky + * + */ + +/* + * This file implements HW context support. On gen5+ a HW context consists of an + * opaque GPU object which is referenced at times of context saves and restores. + * With RC6 enabled, the context is also referenced as the GPU enters and exists + * from RC6 (GPU has it's own internal power context, except on gen5). Though + * something like a context does exist for the media ring, the code only + * supports contexts for the render ring. + * + * In software, there is a distinction between contexts created by the user, + * and the default HW context. The default HW context is used by GPU clients + * that do not request setup of their own hardware context. The default + * context's state is never restored to help prevent programming errors. This + * would happen if a client ran and piggy-backed off another clients GPU state. + * The default context only exists to give the GPU some offset to load as the + * current to invoke a save of the context we actually care about. In fact, the + * code could likely be constructed, albeit in a more complicated fashion, to + * never use the default context, though that limits the driver's ability to + * swap out, and/or destroy other contexts. + * + * All other contexts are created as a request by the GPU client. These contexts + * store GPU state, and thus allow GPU clients to not re-emit state (and + * potentially query certain state) at any time. The kernel driver makes + * certain that the appropriate commands are inserted. + * + * The context life cycle is semi-complicated in that context BOs may live + * longer than the context itself because of the way the hardware, and object + * tracking works. Below is a very crude representation of the state machine + * describing the context life. + * refcount pincount active + * S0: initial state 0 0 0 + * S1: context created 1 0 0 + * S2: context is currently running 2 1 X + * S3: GPU referenced, but not current 2 0 1 + * S4: context is current, but destroyed 1 1 0 + * S5: like S3, but destroyed 1 0 1 + * + * The most common (but not all) transitions: + * S0->S1: client creates a context + * S1->S2: client submits execbuf with context + * S2->S3: other clients submits execbuf with context + * S3->S1: context object was retired + * S3->S2: clients submits another execbuf + * S2->S4: context destroy called with current context + * S3->S5->S0: destroy path + * S4->S5->S0: destroy path on current context + * + * There are two confusing terms used above: + * The "current context" means the context which is currently running on the + * GPU. The GPU has loaded it's state already and has stored away the gtt + * offset of the BO. The GPU is not actively referencing the data at this + * offset, but it will on the next context switch. The only way to avoid this + * is to do a GPU reset. + * + * An "active context' is one which was previously the "current context" and is + * on the active list waiting for the next context switch to occur. Until this + * happens, the object must remain at the same gtt offset. It is therefore + * possible to destroy a context, but it is still active. + * + */ + +#include "drmP.h" +#include "i915_drm.h" +#include "i915_drv.h" + +/* This is a HW constraint. The value below is the largest known requirement + * I've seen in a spec to date, and that was a workaround for a non-shipping + * part. It should be safe to decrease this, but it's more future proof as is. + */ +#define CONTEXT_ALIGN (64<<10) + +static struct i915_hw_context * +i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id); +static int do_switch(struct drm_i915_gem_object *from_obj, + struct i915_hw_context *to, u32 seqno); + +static int get_context_size(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int ret; + u32 reg; + + switch (INTEL_INFO(dev)->gen) { + case 6: + reg = I915_READ(CXT_SIZE); + ret = GEN6_CXT_TOTAL_SIZE(reg) * 64; + break; + case 7: + reg = I915_READ(GEN7_CTX_SIZE); + ret = GEN7_CTX_TOTAL_SIZE(reg) * 64; + break; + default: + BUG(); + } + + return ret; +} + +static void do_destroy(struct i915_hw_context *ctx) +{ + struct drm_device *dev = ctx->obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + if (ctx->file_priv) + idr_remove(&ctx->file_priv->context_idr, ctx->id); + else + BUG_ON(ctx != dev_priv->ring[RCS].default_context); + + drm_gem_object_unreference(&ctx->obj->base); + kfree(ctx); +} + +static int +create_hw_context(struct drm_device *dev, + struct drm_i915_file_private *file_priv, + struct i915_hw_context **ctx_out) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int ret, id; + + *ctx_out = kzalloc(sizeof(struct drm_i915_file_private), GFP_KERNEL); + if (*ctx_out == NULL) + return -ENOMEM; + + (*ctx_out)->obj = i915_gem_alloc_object(dev, + dev_priv->hw_context_size); + if ((*ctx_out)->obj == NULL) { + kfree(*ctx_out); + DRM_DEBUG_DRIVER("Context object allocated failed\n"); + return -ENOMEM; + } + + /* The ring associated with the context object is handled by the normal + * object tracking code. We give an initial ring value simple to pass an + * assertion in the context switch code. + */ + (*ctx_out)->ring = &dev_priv->ring[RCS]; + + /* Default context will never have a file_priv */ + if (file_priv == NULL) + return 0; + + (*ctx_out)->file_priv = file_priv; + +again: + if (idr_pre_get(&file_priv->context_idr, GFP_KERNEL) == 0) { + ret = -ENOMEM; + DRM_DEBUG_DRIVER("idr allocation failed\n"); + goto err_out; + } + + ret = idr_get_new_above(&file_priv->context_idr, *ctx_out, + DEFAULT_CONTEXT_ID + 1, &id); + if (ret == 0) + (*ctx_out)->id = id; + + if (ret == -EAGAIN) + goto again; + else if (ret) + goto err_out; + + return 0; + +err_out: + do_destroy(*ctx_out); + return ret; +} + +static inline bool is_default_context(struct i915_hw_context *ctx) +{ + return (ctx == ctx->ring->default_context); +} + +/** + * The default context needs to exist per ring that uses contexts. It stores the + * context state of the GPU for applications that don't utilize HW contexts, as + * well as an idle case. + */ +static int create_default_context(struct drm_i915_private *dev_priv) +{ + struct i915_hw_context *ctx; + int ret; + + BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); + + ret = create_hw_context(dev_priv->dev, NULL, + &dev_priv->ring[RCS].default_context); + if (ret) + return ret; + + /* We may need to do things with the shrinker which require us to + * immediately switch back to the default context. This can cause a + * problem as pinning the default context also requires GTT space which + * may not be available. To avoid this we always pin the + * default context. + */ + ctx = dev_priv->ring[RCS].default_context; + ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false); + if (ret) { + do_destroy(ctx); + return ret; + } + + ret = do_switch(NULL, ctx, 0); + if (ret) { + i915_gem_object_unpin(ctx->obj); + do_destroy(ctx); + } else { + DRM_DEBUG_DRIVER("Default HW context loaded\n"); + } + + return ret; +} + +void i915_gem_context_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t ctx_size; + + if (!HAS_HW_CONTEXTS(dev)) { + dev_priv->hw_contexts_disabled = true; + return; + } + + /* If called from reset, or thaw... we've been here already */ + if (dev_priv->hw_contexts_disabled || + dev_priv->ring[RCS].default_context) + return; + + ctx_size = get_context_size(dev); + dev_priv->hw_context_size = get_context_size(dev); + dev_priv->hw_context_size = round_up(dev_priv->hw_context_size, 4096); + + if (ctx_size <= 0 || ctx_size > (1<<20)) { + dev_priv->hw_contexts_disabled = true; + return; + } + + if (create_default_context(dev_priv)) { + dev_priv->hw_contexts_disabled = true; + return; + } + + DRM_DEBUG_DRIVER("HW context support initialized\n"); +} + +void i915_gem_context_fini(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (dev_priv->hw_contexts_disabled) + return; + + /* The only known way to stop the gpu from accessing the hw context is + * to reset it. Do this as the very last operation to avoid confusing + * other code, leading to spurious errors. */ + intel_gpu_reset(dev); + + i915_gem_object_unpin(dev_priv->ring[RCS].default_context->obj); + + do_destroy(dev_priv->ring[RCS].default_context); +} + +static int context_idr_cleanup(int id, void *p, void *data) +{ + struct i915_hw_context *ctx = p; + + BUG_ON(id == DEFAULT_CONTEXT_ID); + + do_destroy(ctx); + + return 0; +} + +void i915_gem_context_close(struct drm_device *dev, struct drm_file *file) +{ + struct drm_i915_file_private *file_priv = file->driver_priv; + + mutex_lock(&dev->struct_mutex); + idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); + idr_destroy(&file_priv->context_idr); + mutex_unlock(&dev->struct_mutex); +} + +static struct i915_hw_context * +i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id) +{ + return (struct i915_hw_context *)idr_find(&file_priv->context_idr, id); +} + +static inline int +mi_set_context(struct intel_ring_buffer *ring, + struct i915_hw_context *new_context, + u32 hw_flags) +{ + int ret; + + /* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB + * invalidation prior to MI_SET_CONTEXT. On GEN6 we don't set the value + * explicitly, so we rely on the value at ring init, stored in + * itlb_before_ctx_switch. + */ + if (IS_GEN6(ring->dev) && ring->itlb_before_ctx_switch) { + ret = ring->flush(ring, 0, 0); + if (ret) + return ret; + } + + ret = intel_ring_begin(ring, 6); + if (ret) + return ret; + + if (IS_GEN7(ring->dev)) + intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE); + else + intel_ring_emit(ring, MI_NOOP); + + intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(ring, MI_SET_CONTEXT); + intel_ring_emit(ring, new_context->obj->gtt_offset | + MI_MM_SPACE_GTT | + MI_SAVE_EXT_STATE_EN | + MI_RESTORE_EXT_STATE_EN | + hw_flags); + /* w/a: MI_SET_CONTEXT must always be followed by MI_NOOP */ + intel_ring_emit(ring, MI_NOOP); + + if (IS_GEN7(ring->dev)) + intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE); + else + intel_ring_emit(ring, MI_NOOP); + + intel_ring_advance(ring); + + return ret; +} + +static int do_switch(struct drm_i915_gem_object *from_obj, + struct i915_hw_context *to, + u32 seqno) +{ + struct intel_ring_buffer *ring = NULL; + u32 hw_flags = 0; + int ret; + + BUG_ON(to == NULL); + BUG_ON(from_obj != NULL && from_obj->pin_count == 0); + + ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false); + if (ret) + return ret; + + if (!to->obj->has_global_gtt_mapping) + i915_gem_gtt_bind_object(to->obj, to->obj->cache_level); + + if (!to->is_initialized || is_default_context(to)) + hw_flags |= MI_RESTORE_INHIBIT; + else if (WARN_ON_ONCE(from_obj == to->obj)) /* not yet expected */ + hw_flags |= MI_FORCE_RESTORE; + + ring = to->ring; + ret = mi_set_context(ring, to, hw_flags); + if (ret) { + i915_gem_object_unpin(to->obj); + return ret; + } + + /* The backing object for the context is done after switching to the + * *next* context. Therefore we cannot retire the previous context until + * the next context has already started running. In fact, the below code + * is a bit suboptimal because the retiring can occur simply after the + * MI_SET_CONTEXT instead of when the next seqno has completed. + */ + if (from_obj != NULL) { + from_obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION; + i915_gem_object_move_to_active(from_obj, ring, seqno); + /* As long as MI_SET_CONTEXT is serializing, ie. it flushes the + * whole damn pipeline, we don't need to explicitly mark the + * object dirty. The only exception is that the context must be + * correct in case the object gets swapped out. Ideally we'd be + * able to defer doing this until we know the object would be + * swapped, but there is no way to do that yet. + */ + from_obj->dirty = 1; + BUG_ON(from_obj->ring != to->ring); + i915_gem_object_unpin(from_obj); + } + + ring->last_context_obj = to->obj; + to->is_initialized = true; + + return 0; +} + +/** + * i915_switch_context() - perform a GPU context switch. + * @ring: ring for which we'll execute the context switch + * @file_priv: file_priv associated with the context, may be NULL + * @id: context id number + * @seqno: sequence number by which the new context will be switched to + * @flags: + * + * The context life cycle is simple. The context refcount is incremented and + * decremented by 1 and create and destroy. If the context is in use by the GPU, + * it will have a refoucnt > 1. This allows us to destroy the context abstract + * object while letting the normal object tracking destroy the backing BO. + */ +int i915_switch_context(struct intel_ring_buffer *ring, + struct drm_file *file, + int to_id) +{ + struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_file_private *file_priv = NULL; + struct i915_hw_context *to; + struct drm_i915_gem_object *from_obj = ring->last_context_obj; + int ret; + + if (dev_priv->hw_contexts_disabled) + return 0; + + if (ring != &dev_priv->ring[RCS]) + return 0; + + if (file) + file_priv = file->driver_priv; + + if (to_id == DEFAULT_CONTEXT_ID) { + to = ring->default_context; + } else { + to = i915_gem_context_get(file_priv, to_id); + if (to == NULL) + return -ENOENT; + } + + if (from_obj == to->obj) + return 0; + + ret = do_switch(from_obj, to, i915_gem_next_request_seqno(to->ring)); + if (ret) + return ret; + + /* Just to make the code a little cleaner we take the object reference + * after the switch was successful. It would be more intuitive to ref + * the 'to' object before the switch but we know the refcount must be >0 + * if context_get() succeeded, and we hold struct mutex. So it's safe to + * do this here/now + */ + drm_gem_object_reference(&to->obj->base); + if (from_obj != NULL) + drm_gem_object_unreference(&from_obj->base); + return ret; +} + +int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_context_create *args = data; + struct drm_i915_file_private *file_priv = file->driver_priv; + struct i915_hw_context *ctx; + int ret; + + if (!(dev->driver->driver_features & DRIVER_GEM)) + return -ENODEV; + + if (dev_priv->hw_contexts_disabled) + return -ENODEV; + + ret = i915_mutex_lock_interruptible(dev); + if (ret) + return ret; + + ret = create_hw_context(dev, file_priv, &ctx); + mutex_unlock(&dev->struct_mutex); + + args->ctx_id = ctx->id; + DRM_DEBUG_DRIVER("HW context %d created\n", args->ctx_id); + + return ret; +} + +int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_i915_gem_context_destroy *args = data; + struct drm_i915_file_private *file_priv = file->driver_priv; + struct i915_hw_context *ctx; + int ret; + + if (!(dev->driver->driver_features & DRIVER_GEM)) + return -ENODEV; + + ret = i915_mutex_lock_interruptible(dev); + if (ret) + return ret; + + ctx = i915_gem_context_get(file_priv, args->ctx_id); + if (!ctx) { + mutex_unlock(&dev->struct_mutex); + return -ENOENT; + } + + do_destroy(ctx); + + mutex_unlock(&dev->struct_mutex); + + DRM_DEBUG_DRIVER("HW context %d destroyed\n", args->ctx_id); + return 0; +} diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index a4f6aaabca99..bddf7bed183f 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c @@ -132,7 +132,8 @@ i915_gem_object_check_coherency(struct drm_i915_gem_object *obj, int handle) __func__, obj, obj->gtt_offset, handle, obj->size / 1024); - gtt_mapping = ioremap(dev->agp->base + obj->gtt_offset, obj->base.size); + gtt_mapping = ioremap(dev_priv->mm.gtt_base_addr + obj->gtt_offset, + obj->base.size); if (gtt_mapping == NULL) { DRM_ERROR("failed to map GTT space\n"); return; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 974a9f1068a3..88e2e114189c 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -810,33 +810,16 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, return ret; } -static int +static void i915_gem_execbuffer_flush(struct drm_device *dev, uint32_t invalidate_domains, - uint32_t flush_domains, - uint32_t flush_rings) + uint32_t flush_domains) { - drm_i915_private_t *dev_priv = dev->dev_private; - int i, ret; - if (flush_domains & I915_GEM_DOMAIN_CPU) intel_gtt_chipset_flush(); if (flush_domains & I915_GEM_DOMAIN_GTT) wmb(); - - if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { - for (i = 0; i < I915_NUM_RINGS; i++) - if (flush_rings & (1 << i)) { - ret = i915_gem_flush_ring(&dev_priv->ring[i], - invalidate_domains, - flush_domains); - if (ret) - return ret; - } - } - - return 0; } static int @@ -885,12 +868,9 @@ i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, i915_gem_object_set_to_gpu_domain(obj, ring, &cd); if (cd.invalidate_domains | cd.flush_domains) { - ret = i915_gem_execbuffer_flush(ring->dev, - cd.invalidate_domains, - cd.flush_domains, - cd.flush_rings); - if (ret) - return ret; + i915_gem_execbuffer_flush(ring->dev, + cd.invalidate_domains, + cd.flush_domains); } if (cd.flips) { @@ -905,6 +885,11 @@ i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, return ret; } + /* Unconditionally invalidate gpu caches. */ + ret = i915_gem_flush_ring(ring, I915_GEM_GPU_DOMAINS, 0); + if (ret) + return ret; + return 0; } @@ -983,26 +968,13 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring) { struct drm_i915_gem_request *request; - u32 invalidate; - /* - * Ensure that the commands in the batch buffer are - * finished before the interrupt fires. - * - * The sampler always gets flushed on i965 (sigh). - */ - invalidate = I915_GEM_DOMAIN_COMMAND; - if (INTEL_INFO(dev)->gen >= 4) - invalidate |= I915_GEM_DOMAIN_SAMPLER; - if (ring->flush(ring, invalidate, 0)) { - i915_gem_next_request_seqno(ring); - return; - } + /* Unconditionally force add_request to emit a full flush. */ + ring->gpu_caches_dirty = true; /* Add a breadcrumb for the completion of the batch buffer */ request = kzalloc(sizeof(*request), GFP_KERNEL); if (request == NULL || i915_add_request(ring, file, request)) { - i915_gem_next_request_seqno(ring); kfree(request); } } @@ -1044,6 +1016,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_i915_gem_object *batch_obj; struct drm_clip_rect *cliprects = NULL; struct intel_ring_buffer *ring; + u32 ctx_id = i915_execbuffer2_get_context_id(*args); u32 exec_start, exec_len; u32 seqno; u32 mask; @@ -1065,9 +1038,19 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, break; case I915_EXEC_BSD: ring = &dev_priv->ring[VCS]; + if (ctx_id != 0) { + DRM_DEBUG("Ring %s doesn't support contexts\n", + ring->name); + return -EPERM; + } break; case I915_EXEC_BLT: ring = &dev_priv->ring[BCS]; + if (ctx_id != 0) { + DRM_DEBUG("Ring %s doesn't support contexts\n", + ring->name); + return -EPERM; + } break; default: DRM_DEBUG("execbuf with unknown ring: %d\n", @@ -1261,6 +1244,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto err; } + ret = i915_switch_context(ring, file, ctx_id); + if (ret) + goto err; + trace_i915_gem_ring_dispatch(ring, seqno); exec_start = batch_obj->gtt_offset + args->batch_start_offset; @@ -1367,6 +1354,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, exec2.num_cliprects = args->num_cliprects; exec2.cliprects_ptr = args->cliprects_ptr; exec2.flags = I915_EXEC_RENDER; + i915_execbuffer2_set_context_id(exec2, 0); ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list); if (!ret) { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 75e0b029e1fa..23f2ea0f0651 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -513,15 +513,10 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) unsigned long irqflags; int pipe; u32 pipe_stats[I915_MAX_PIPES]; - u32 vblank_status; - int vblank = 0; bool blc_event; atomic_inc(&dev_priv->irq_received); - vblank_status = PIPE_START_VBLANK_INTERRUPT_STATUS | - PIPE_VBLANK_INTERRUPT_STATUS; - while (true) { iir = I915_READ(VLV_IIR); gt_iir = I915_READ(GTIIR); @@ -551,6 +546,16 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) } spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + for_each_pipe(pipe) { + if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) + drm_handle_vblank(dev, pipe); + + if (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) { + intel_prepare_page_flip(dev, pipe); + intel_finish_page_flip(dev, pipe); + } + } + /* Consume port. Then clear IIR or we'll miss events */ if (iir & I915_DISPLAY_PORT_INTERRUPT) { u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); @@ -565,19 +570,6 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) I915_READ(PORT_HOTPLUG_STAT); } - - if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) { - drm_handle_vblank(dev, 0); - vblank++; - intel_finish_page_flip(dev, 0); - } - - if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) { - drm_handle_vblank(dev, 1); - vblank++; - intel_finish_page_flip(dev, 0); - } - if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) blc_event = true; @@ -1188,6 +1180,7 @@ static void i915_capture_error_state(struct drm_device *dev) kref_init(&error->ref); error->eir = I915_READ(EIR); error->pgtbl_er = I915_READ(PGTBL_ER); + error->ccid = I915_READ(CCID); if (HAS_PCH_SPLIT(dev)) error->ier = I915_READ(DEIER) | I915_READ(GTIER); @@ -1510,23 +1503,20 @@ static int valleyview_enable_vblank(struct drm_device *dev, int pipe) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; - u32 dpfl, imr; + u32 imr; if (!i915_pipe_enabled(dev, pipe)) return -EINVAL; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - dpfl = I915_READ(VLV_DPFLIPSTAT); imr = I915_READ(VLV_IMR); - if (pipe == 0) { - dpfl |= PIPEA_VBLANK_INT_EN; + if (pipe == 0) imr &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT; - } else { - dpfl |= PIPEA_VBLANK_INT_EN; + else imr &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; - } - I915_WRITE(VLV_DPFLIPSTAT, dpfl); I915_WRITE(VLV_IMR, imr); + i915_enable_pipestat(dev_priv, pipe, + PIPE_START_VBLANK_INTERRUPT_ENABLE); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); return 0; @@ -1576,20 +1566,17 @@ static void valleyview_disable_vblank(struct drm_device *dev, int pipe) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; - u32 dpfl, imr; + u32 imr; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - dpfl = I915_READ(VLV_DPFLIPSTAT); + i915_disable_pipestat(dev_priv, pipe, + PIPE_START_VBLANK_INTERRUPT_ENABLE); imr = I915_READ(VLV_IMR); - if (pipe == 0) { - dpfl &= ~PIPEA_VBLANK_INT_EN; + if (pipe == 0) imr |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT; - } else { - dpfl &= ~PIPEB_VBLANK_INT_EN; + else imr |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; - } I915_WRITE(VLV_IMR, imr); - I915_WRITE(VLV_DPFLIPSTAT, dpfl); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } @@ -1923,16 +1910,24 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) static int valleyview_irq_postinstall(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 render_irqs; u32 enable_mask; u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); + u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV; u16 msid; enable_mask = I915_DISPLAY_PORT_INTERRUPT; - enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | + enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | + I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | + I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; - dev_priv->irq_mask = ~enable_mask; + /* + *Leave vblank interrupts masked initially. enable/disable will + * toggle them based on usage. + */ + dev_priv->irq_mask = (~enable_mask) | + I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | + I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; dev_priv->pipestat[0] = 0; dev_priv->pipestat[1] = 0; @@ -1951,26 +1946,27 @@ static int valleyview_irq_postinstall(struct drm_device *dev) I915_WRITE(PIPESTAT(1), 0xffff); POSTING_READ(VLV_IER); + i915_enable_pipestat(dev_priv, 0, pipestat_enable); + i915_enable_pipestat(dev_priv, 1, pipestat_enable); + I915_WRITE(VLV_IIR, 0xffffffff); I915_WRITE(VLV_IIR, 0xffffffff); - render_irqs = GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT | - GT_GEN6_BLT_CS_ERROR_INTERRUPT | - GT_GEN6_BLT_USER_INTERRUPT | - GT_GEN6_BSD_USER_INTERRUPT | - GT_GEN6_BSD_CS_ERROR_INTERRUPT | - GT_GEN7_L3_PARITY_ERROR_INTERRUPT | - GT_PIPE_NOTIFY | - GT_RENDER_CS_ERROR_INTERRUPT | - GT_SYNC_STATUS | - GT_USER_INTERRUPT; - - dev_priv->gt_irq_mask = ~render_irqs; + dev_priv->gt_irq_mask = ~0; I915_WRITE(GTIIR, I915_READ(GTIIR)); I915_WRITE(GTIIR, I915_READ(GTIIR)); - I915_WRITE(GTIMR, 0); - I915_WRITE(GTIER, render_irqs); + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + I915_WRITE(GTIER, GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT | + GT_GEN6_BLT_CS_ERROR_INTERRUPT | + GT_GEN6_BLT_USER_INTERRUPT | + GT_GEN6_BSD_USER_INTERRUPT | + GT_GEN6_BSD_CS_ERROR_INTERRUPT | + GT_GEN7_L3_PARITY_ERROR_INTERRUPT | + GT_PIPE_NOTIFY | + GT_RENDER_CS_ERROR_INTERRUPT | + GT_SYNC_STATUS | + GT_USER_INTERRUPT); POSTING_READ(GTIER); /* ack & enable invalid PTE error interrupts */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 35113d8d7b05..9dfc4c5ff31e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -217,6 +217,9 @@ #define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19) #define MI_DISPLAY_FLIP_IVB_PLANE_C (4 << 19) #define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19) +#define MI_ARB_ON_OFF MI_INSTR(0x08, 0) +#define MI_ARB_ENABLE (1<<0) +#define MI_ARB_DISABLE (0<<0) #define MI_SET_CONTEXT MI_INSTR(0x18, 0) #define MI_MM_SPACE_GTT (1<<8) @@ -299,6 +302,7 @@ #define DISPLAY_PLANE_B (1<<20) #define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2)) #define PIPE_CONTROL_CS_STALL (1<<20) +#define PIPE_CONTROL_TLB_INVALIDATE (1<<18) #define PIPE_CONTROL_QW_WRITE (1<<14) #define PIPE_CONTROL_DEPTH_STALL (1<<13) #define PIPE_CONTROL_WRITE_FLUSH (1<<12) @@ -908,6 +912,7 @@ #define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ #define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */ +#define DPLL_LOCK_VLV (1<<15) #define DPLL_INTEGRATED_CLOCK_VLV (1<<13) #define SRX_INDEX 0x3c4 @@ -1462,6 +1467,27 @@ */ #define CCID 0x2180 #define CCID_EN (1<<0) +#define CXT_SIZE 0x21a0 +#define GEN6_CXT_POWER_SIZE(cxt_reg) ((cxt_reg >> 24) & 0x3f) +#define GEN6_CXT_RING_SIZE(cxt_reg) ((cxt_reg >> 18) & 0x3f) +#define GEN6_CXT_RENDER_SIZE(cxt_reg) ((cxt_reg >> 12) & 0x3f) +#define GEN6_CXT_EXTENDED_SIZE(cxt_reg) ((cxt_reg >> 6) & 0x3f) +#define GEN6_CXT_PIPELINE_SIZE(cxt_reg) ((cxt_reg >> 0) & 0x3f) +#define GEN6_CXT_TOTAL_SIZE(cxt_reg) (GEN6_CXT_POWER_SIZE(cxt_reg) + \ + GEN6_CXT_RING_SIZE(cxt_reg) + \ + GEN6_CXT_RENDER_SIZE(cxt_reg) + \ + GEN6_CXT_EXTENDED_SIZE(cxt_reg) + \ + GEN6_CXT_PIPELINE_SIZE(cxt_reg)) +#define GEN7_CTX_SIZE 0x21a8 +#define GEN7_CTX_RENDER_SIZE(ctx_reg) ((ctx_reg >> 16) & 0x3f) +#define GEN7_CTX_EXTENDED_SIZE(ctx_reg) ((ctx_reg >> 9) & 0x7f) +#define GEN7_CTX_GT1_SIZE(ctx_reg) ((ctx_reg >> 6) & 0x7) +#define GEN7_CTX_VFSTATE_SIZE(ctx_reg) ((ctx_reg >> 0) & 0x3f) +#define GEN7_CTX_TOTAL_SIZE(ctx_reg) (GEN7_CTX_RENDER_SIZE(ctx_reg) + \ + GEN7_CTX_EXTENDED_SIZE(ctx_reg) + \ + GEN7_CTX_GT1_SIZE(ctx_reg) + \ + GEN7_CTX_VFSTATE_SIZE(ctx_reg)) + /* * Overlay regs */ @@ -1815,18 +1841,35 @@ #define PFIT_AUTO_RATIOS 0x61238 /* Backlight control */ -#define BLC_PWM_CTL 0x61254 -#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) #define BLC_PWM_CTL2 0x61250 /* 965+ only */ -#define BLM_COMBINATION_MODE (1 << 30) +#define BLM_PWM_ENABLE (1 << 31) +#define BLM_COMBINATION_MODE (1 << 30) /* gen4 only */ +#define BLM_PIPE_SELECT (1 << 29) +#define BLM_PIPE_SELECT_IVB (3 << 29) +#define BLM_PIPE_A (0 << 29) +#define BLM_PIPE_B (1 << 29) +#define BLM_PIPE_C (2 << 29) /* ivb + */ +#define BLM_PIPE(pipe) ((pipe) << 29) +#define BLM_POLARITY_I965 (1 << 28) /* gen4 only */ +#define BLM_PHASE_IN_INTERUPT_STATUS (1 << 26) +#define BLM_PHASE_IN_ENABLE (1 << 25) +#define BLM_PHASE_IN_INTERUPT_ENABL (1 << 24) +#define BLM_PHASE_IN_TIME_BASE_SHIFT (16) +#define BLM_PHASE_IN_TIME_BASE_MASK (0xff << 16) +#define BLM_PHASE_IN_COUNT_SHIFT (8) +#define BLM_PHASE_IN_COUNT_MASK (0xff << 8) +#define BLM_PHASE_IN_INCR_SHIFT (0) +#define BLM_PHASE_IN_INCR_MASK (0xff << 0) +#define BLC_PWM_CTL 0x61254 /* * This is the most significant 15 bits of the number of backlight cycles in a * complete cycle of the modulated backlight control. * * The actual value is this field multiplied by two. */ -#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) -#define BLM_LEGACY_MODE (1 << 16) +#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) +#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) +#define BLM_LEGACY_MODE (1 << 16) /* gen2 only */ /* * This is the number of cycles out of the backlight modulation cycle for which * the backlight is on. @@ -1836,9 +1879,24 @@ */ #define BACKLIGHT_DUTY_CYCLE_SHIFT (0) #define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) +#define BACKLIGHT_DUTY_CYCLE_MASK_PNV (0xfffe) +#define BLM_POLARITY_PNV (1 << 0) /* pnv only */ #define BLC_HIST_CTL 0x61260 +/* New registers for PCH-split platforms. Safe where new bits show up, the + * register layout machtes with gen4 BLC_PWM_CTL[12]. */ +#define BLC_PWM_CPU_CTL2 0x48250 +#define BLC_PWM_CPU_CTL 0x48254 + +/* PCH CTL1 is totally different, all but the below bits are reserved. CTL2 is + * like the normal CTL from gen4 and earlier. Hooray for confusing naming. */ +#define BLC_PWM_PCH_CTL1 0xc8250 +#define BLM_PCH_PWM_ENABLE (1 << 30) +#define BLM_PCH_OVERRIDE_ENABLE (1 << 30) +#define BLM_PCH_POLARITY (1 << 29) +#define BLC_PWM_PCH_CTL2 0xc8254 + /* TV port control */ #define TV_CTL 0x68000 /** Enables the TV encoder */ @@ -2603,13 +2661,13 @@ #define PIPESTAT(pipe) _PIPE(pipe, _PIPEASTAT, _PIPEBSTAT) #define VLV_DPFLIPSTAT 0x70028 -#define PIPEB_LINE_COMPARE_STATUS (1<<29) +#define PIPEB_LINE_COMPARE_INT_EN (1<<29) #define PIPEB_HLINE_INT_EN (1<<28) #define PIPEB_VBLANK_INT_EN (1<<27) #define SPRITED_FLIPDONE_INT_EN (1<<26) #define SPRITEC_FLIPDONE_INT_EN (1<<25) #define PLANEB_FLIPDONE_INT_EN (1<<24) -#define PIPEA_LINE_COMPARE_STATUS (1<<21) +#define PIPEA_LINE_COMPARE_INT_EN (1<<21) #define PIPEA_HLINE_INT_EN (1<<20) #define PIPEA_VBLANK_INT_EN (1<<19) #define SPRITEB_FLIPDONE_INT_EN (1<<18) @@ -3844,7 +3902,6 @@ #define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16) /* or SDVOB */ -#define VLV_HDMIB 0x61140 #define HDMIB 0xe1140 #define PORT_ENABLE (1 << 31) #define TRANSCODER(pipe) ((pipe) << 30) @@ -3875,20 +3932,18 @@ #define PCH_LVDS 0xe1180 #define LVDS_DETECTED (1 << 1) -#define BLC_PWM_CPU_CTL2 0x48250 -#define PWM_ENABLE (1 << 31) -#define PWM_PIPE_A (0 << 29) -#define PWM_PIPE_B (1 << 29) -#define BLC_PWM_CPU_CTL 0x48254 +/* vlv has 2 sets of panel control regs. */ +#define PIPEA_PP_STATUS 0x61200 +#define PIPEA_PP_CONTROL 0x61204 +#define PIPEA_PP_ON_DELAYS 0x61208 +#define PIPEA_PP_OFF_DELAYS 0x6120c +#define PIPEA_PP_DIVISOR 0x61210 -#define BLC_PWM_PCH_CTL1 0xc8250 -#define PWM_PCH_ENABLE (1 << 31) -#define PWM_POLARITY_ACTIVE_LOW (1 << 29) -#define PWM_POLARITY_ACTIVE_HIGH (0 << 29) -#define PWM_POLARITY_ACTIVE_LOW2 (1 << 28) -#define PWM_POLARITY_ACTIVE_HIGH2 (0 << 28) - -#define BLC_PWM_PCH_CTL2 0xc8254 +#define PIPEB_PP_STATUS 0x61300 +#define PIPEB_PP_CONTROL 0x61304 +#define PIPEB_PP_ON_DELAYS 0x61308 +#define PIPEB_PP_OFF_DELAYS 0x6130c +#define PIPEB_PP_DIVISOR 0x61310 #define PCH_PP_STATUS 0xc7200 #define PCH_PP_CONTROL 0xc7204 @@ -4032,10 +4087,15 @@ # define GEN6_CSUNIT_CLOCK_GATE_DISABLE (1 << 7) #define GEN6_UCGCTL2 0x9404 +# define GEN7_VDSUNIT_CLOCK_GATE_DISABLE (1 << 30) +# define GEN7_TDLUNIT_CLOCK_GATE_DISABLE (1 << 22) # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13) # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) # define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11) +#define GEN7_UCGCTL4 0x940c +#define GEN7_L3BANK2X_CLOCK_GATE_DISABLE (1<<25) + #define GEN6_RPNSWREQ 0xA008 #define GEN6_TURBO_DISABLE (1<<31) #define GEN6_FREQUENCY(x) ((x)<<25) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 75a70c46ef1b..61d55d3141c7 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -88,6 +88,9 @@ static void gmch_crt_dpms(struct drm_encoder *encoder, int mode) temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); temp &= ~ADPA_DAC_ENABLE; + if (IS_VALLEYVIEW(dev) && mode != DRM_MODE_DPMS_ON) + mode = DRM_MODE_DPMS_OFF; + switch (mode) { case DRM_MODE_DPMS_ON: temp |= ADPA_DAC_ENABLE; @@ -230,6 +233,42 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) return ret; } +static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 adpa; + bool ret; + u32 save_adpa; + + save_adpa = adpa = I915_READ(ADPA); + DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa); + + adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER; + + I915_WRITE(ADPA, adpa); + + if (wait_for((I915_READ(ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, + 1000)) { + DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); + I915_WRITE(ADPA, save_adpa); + } + + /* Check the status to see if both blue and green are on now */ + adpa = I915_READ(ADPA); + if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0) + ret = true; + else + ret = false; + + DRM_DEBUG_KMS("valleyview hotplug adpa=0x%x, result %d\n", adpa, ret); + + /* FIXME: debug force function and remove */ + ret = true; + + return ret; +} + /** * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence. * @@ -249,6 +288,9 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) if (HAS_PCH_SPLIT(dev)) return intel_ironlake_crt_detect_hotplug(connector); + if (IS_VALLEYVIEW(dev)) + return valleyview_crt_detect_hotplug(connector); + /* * On 4 series desktop, CRT detect sequence need to be done twice * to get a reliable result. @@ -453,18 +495,27 @@ intel_crt_detect(struct drm_connector *connector, bool force) struct intel_load_detect_pipe tmp; if (I915_HAS_HOTPLUG(dev)) { + /* We can not rely on the HPD pin always being correctly wired + * up, for example many KVM do not pass it through, and so + * only trust an assertion that the monitor is connected. + */ if (intel_crt_detect_hotplug(connector)) { DRM_DEBUG_KMS("CRT detected via hotplug\n"); return connector_status_connected; - } else { + } else DRM_DEBUG_KMS("CRT not detected via hotplug\n"); - return connector_status_disconnected; - } } if (intel_crt_detect_ddc(connector)) return connector_status_connected; + /* Load detection is broken on HPD capable machines. Whoever wants a + * broken monitor (without edid) to work behind a broken kvm (that fails + * to have the right resistors for HP detection) needs to fix this up. + * For now just bail out. */ + if (I915_HAS_HOTPLUG(dev)) + return connector_status_disconnected; + if (!force) return connector->status; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index add1a15dc8b3..b3052ef70d16 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -98,6 +98,11 @@ intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *match_clock, intel_clock_t *best_clock); +static bool +intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock); + static inline u32 /* units of 100MHz */ intel_fdi_link_freq(struct drm_device *dev) { @@ -359,6 +364,48 @@ static const intel_limit_t intel_limits_ironlake_display_port = { .find_pll = intel_find_pll_ironlake_dp, }; +static const intel_limit_t intel_limits_vlv_dac = { + .dot = { .min = 25000, .max = 270000 }, + .vco = { .min = 4000000, .max = 6000000 }, + .n = { .min = 1, .max = 7 }, + .m = { .min = 22, .max = 450 }, /* guess */ + .m1 = { .min = 2, .max = 3 }, + .m2 = { .min = 11, .max = 156 }, + .p = { .min = 10, .max = 30 }, + .p1 = { .min = 2, .max = 3 }, + .p2 = { .dot_limit = 270000, + .p2_slow = 2, .p2_fast = 20 }, + .find_pll = intel_vlv_find_best_pll, +}; + +static const intel_limit_t intel_limits_vlv_hdmi = { + .dot = { .min = 20000, .max = 165000 }, + .vco = { .min = 5994000, .max = 4000000 }, + .n = { .min = 1, .max = 7 }, + .m = { .min = 60, .max = 300 }, /* guess */ + .m1 = { .min = 2, .max = 3 }, + .m2 = { .min = 11, .max = 156 }, + .p = { .min = 10, .max = 30 }, + .p1 = { .min = 2, .max = 3 }, + .p2 = { .dot_limit = 270000, + .p2_slow = 2, .p2_fast = 20 }, + .find_pll = intel_vlv_find_best_pll, +}; + +static const intel_limit_t intel_limits_vlv_dp = { + .dot = { .min = 162000, .max = 270000 }, + .vco = { .min = 5994000, .max = 4000000 }, + .n = { .min = 1, .max = 7 }, + .m = { .min = 60, .max = 300 }, /* guess */ + .m1 = { .min = 2, .max = 3 }, + .m2 = { .min = 11, .max = 156 }, + .p = { .min = 10, .max = 30 }, + .p1 = { .min = 2, .max = 3 }, + .p2 = { .dot_limit = 270000, + .p2_slow = 2, .p2_fast = 20 }, + .find_pll = intel_vlv_find_best_pll, +}; + u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg) { unsigned long flags; @@ -384,6 +431,28 @@ u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg) return val; } +static void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, + u32 val) +{ + unsigned long flags; + + spin_lock_irqsave(&dev_priv->dpio_lock, flags); + if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { + DRM_ERROR("DPIO idle wait timed out\n"); + goto out_unlock; + } + + I915_WRITE(DPIO_DATA, val); + I915_WRITE(DPIO_REG, reg); + I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_WRITE | DPIO_PORTID | + DPIO_BYTE); + if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) + DRM_ERROR("DPIO write wait timed out\n"); + +out_unlock: + spin_unlock_irqrestore(&dev_priv->dpio_lock, flags); +} + static void vlv_init_dpio(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -434,7 +503,7 @@ static bool is_dual_link_lvds(struct drm_i915_private *dev_priv, * register is uninitialized. */ val = I915_READ(reg); - if (!(val & ~LVDS_DETECTED)) + if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED))) val = dev_priv->bios_lvds_val; dev_priv->lvds_val = val; } @@ -510,6 +579,13 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk) limit = &intel_limits_pineview_lvds; else limit = &intel_limits_pineview_sdvo; + } else if (IS_VALLEYVIEW(dev)) { + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) + limit = &intel_limits_vlv_dac; + else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) + limit = &intel_limits_vlv_hdmi; + else + limit = &intel_limits_vlv_dp; } else if (!IS_GEN2(dev)) { if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) limit = &intel_limits_i9xx_lvds; @@ -783,6 +859,73 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, memcpy(best_clock, &clock, sizeof(intel_clock_t)); return true; } +static bool +intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock) +{ + u32 p1, p2, m1, m2, vco, bestn, bestm1, bestm2, bestp1, bestp2; + u32 m, n, fastclk; + u32 updrate, minupdate, fracbits, p; + unsigned long bestppm, ppm, absppm; + int dotclk, flag; + + dotclk = target * 1000; + bestppm = 1000000; + ppm = absppm = 0; + fastclk = dotclk / (2*100); + updrate = 0; + minupdate = 19200; + fracbits = 1; + n = p = p1 = p2 = m = m1 = m2 = vco = bestn = 0; + bestm1 = bestm2 = bestp1 = bestp2 = 0; + + /* based on hardware requirement, prefer smaller n to precision */ + for (n = limit->n.min; n <= ((refclk) / minupdate); n++) { + updrate = refclk / n; + for (p1 = limit->p1.max; p1 > limit->p1.min; p1--) { + for (p2 = limit->p2.p2_fast+1; p2 > 0; p2--) { + if (p2 > 10) + p2 = p2 - 1; + p = p1 * p2; + /* based on hardware requirement, prefer bigger m1,m2 values */ + for (m1 = limit->m1.min; m1 <= limit->m1.max; m1++) { + m2 = (((2*(fastclk * p * n / m1 )) + + refclk) / (2*refclk)); + m = m1 * m2; + vco = updrate * m; + if (vco >= limit->vco.min && vco < limit->vco.max) { + ppm = 1000000 * ((vco / p) - fastclk) / fastclk; + absppm = (ppm > 0) ? ppm : (-ppm); + if (absppm < 100 && ((p1 * p2) > (bestp1 * bestp2))) { + bestppm = 0; + flag = 1; + } + if (absppm < bestppm - 10) { + bestppm = absppm; + flag = 1; + } + if (flag) { + bestn = n; + bestm1 = m1; + bestm2 = m2; + bestp1 = p1; + bestp2 = p2; + flag = 0; + } + } + } + } + } + } + best_clock->n = bestn; + best_clock->m1 = bestm1; + best_clock->m2 = bestm2; + best_clock->p1 = bestp1; + best_clock->p2 = bestp2; + + return true; +} static void ironlake_wait_for_vblank(struct drm_device *dev, int pipe) { @@ -1232,6 +1375,9 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val), "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", reg, pipe_name(pipe)); + + WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), + "IBX PCH dp port still using transcoder B\n"); } static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, @@ -1241,6 +1387,9 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, WARN(hdmi_pipe_enabled(dev_priv, val, pipe), "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", reg, pipe_name(pipe)); + + WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), + "IBX PCH hdmi port still using transcoder B\n"); } static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, @@ -1287,7 +1436,7 @@ static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) u32 val; /* No really, not for ILK+ */ - BUG_ON(dev_priv->info->gen >= 5); + BUG_ON(!IS_VALLEYVIEW(dev_priv->dev) && dev_priv->info->gen >= 5); /* PLL is protected by panel, make sure we can write it */ if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev)) @@ -1344,7 +1493,7 @@ intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value) unsigned long flags; spin_lock_irqsave(&dev_priv->dpio_lock, flags); - if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_READY) == 0, + if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, 100)) { DRM_ERROR("timeout waiting for SBI to become ready\n"); goto out_unlock; @@ -1358,7 +1507,7 @@ intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value) SBI_BUSY | SBI_CTL_OP_CRWR); - if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_READY | SBI_RESPONSE_SUCCESS)) == 0, + if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, 100)) { DRM_ERROR("timeout waiting for SBI to complete write transaction\n"); goto out_unlock; @@ -1372,10 +1521,10 @@ static u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg) { unsigned long flags; - u32 value; + u32 value = 0; spin_lock_irqsave(&dev_priv->dpio_lock, flags); - if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_READY) == 0, + if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, 100)) { DRM_ERROR("timeout waiting for SBI to become ready\n"); goto out_unlock; @@ -1387,7 +1536,7 @@ intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg) SBI_BUSY | SBI_CTL_OP_CRRD); - if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_READY | SBI_RESPONSE_SUCCESS)) == 0, + if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, 100)) { DRM_ERROR("timeout waiting for SBI to complete read transaction\n"); goto out_unlock; @@ -3666,13 +3815,37 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, return display_bpc != bpc; } +static int vlv_get_refclk(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int refclk = 27000; /* for DP & HDMI */ + + return 100000; /* only one validated so far */ + + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { + refclk = 96000; + } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { + if (intel_panel_use_ssc(dev_priv)) + refclk = 100000; + else + refclk = 96000; + } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) { + refclk = 100000; + } + + return refclk; +} + static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; int refclk; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + if (IS_VALLEYVIEW(dev)) { + refclk = vlv_get_refclk(crtc); + } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { refclk = dev_priv->lvds_ssc_freq * 1000; DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", @@ -3787,6 +3960,72 @@ static void intel_update_lvds(struct drm_crtc *crtc, intel_clock_t *clock, I915_WRITE(LVDS, temp); } +static void vlv_update_pll(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, + intel_clock_t *clock, intel_clock_t *reduced_clock, + int refclk, int num_connectors) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + u32 dpll, mdiv, pdiv; + u32 bestn, bestm1, bestm2, bestp1, bestp2; + bool is_hdmi; + + is_hdmi = intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI); + + bestn = clock->n; + bestm1 = clock->m1; + bestm2 = clock->m2; + bestp1 = clock->p1; + bestp2 = clock->p2; + + /* Enable DPIO clock input */ + dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV | + DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV; + I915_WRITE(DPLL(pipe), dpll); + POSTING_READ(DPLL(pipe)); + + mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK)); + mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT)); + mdiv |= ((bestn << DPIO_N_SHIFT)); + mdiv |= (1 << DPIO_POST_DIV_SHIFT); + mdiv |= (1 << DPIO_K_SHIFT); + mdiv |= DPIO_ENABLE_CALIBRATION; + intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); + + intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), 0x01000000); + + pdiv = DPIO_REFSEL_OVERRIDE | (5 << DPIO_PLL_MODESEL_SHIFT) | + (3 << DPIO_BIAS_CURRENT_CTL_SHIFT) | (1<<20) | + (8 << DPIO_DRIVER_CTL_SHIFT) | (5 << DPIO_CLK_BIAS_CTL_SHIFT); + intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), pdiv); + + intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), 0x009f0051); + + dpll |= DPLL_VCO_ENABLE; + I915_WRITE(DPLL(pipe), dpll); + POSTING_READ(DPLL(pipe)); + if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) + DRM_ERROR("DPLL %d failed to lock\n", pipe); + + if (is_hdmi) { + u32 temp = intel_mode_get_pixel_multiplier(adjusted_mode); + + if (temp > 1) + temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; + else + temp = 0; + + I915_WRITE(DPLL_MD(pipe), temp); + POSTING_READ(DPLL_MD(pipe)); + } + + intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x641); /* ??? */ +} + static void i9xx_update_pll(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -4044,6 +4283,9 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, if (IS_GEN2(dev)) i8xx_update_pll(crtc, adjusted_mode, &clock, num_connectors); + else if (IS_VALLEYVIEW(dev)) + vlv_update_pll(crtc, mode,adjusted_mode, &clock, NULL, + refclk, num_connectors); else i9xx_update_pll(crtc, mode, adjusted_mode, &clock, has_reduced_clock ? &reduced_clock : NULL, @@ -6543,7 +6785,24 @@ static void intel_setup_outputs(struct drm_device *dev) if (!dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) intel_dp_init(dev, PCH_DP_D); + } else if (IS_VALLEYVIEW(dev)) { + int found; + if (I915_READ(SDVOB) & PORT_DETECTED) { + /* SDVOB multiplex with HDMIB */ + found = intel_sdvo_init(dev, SDVOB, true); + if (!found) + intel_hdmi_init(dev, SDVOB); + if (!found && (I915_READ(DP_B) & DP_DETECTED)) + intel_dp_init(dev, DP_B); + } + + if (I915_READ(SDVOC) & PORT_DETECTED) + intel_hdmi_init(dev, SDVOC); + + /* Shares lanes with HDMI on SDVOC */ + if (I915_READ(DP_C) & DP_DETECTED) + intel_dp_init(dev, DP_C); } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { bool found = false; @@ -6906,9 +7165,9 @@ static void ivb_pch_pwm_override(struct drm_device *dev) * IVB has CPU eDP backlight regs too, set things up to let the * PCH regs control the backlight */ - I915_WRITE(BLC_PWM_CPU_CTL2, PWM_ENABLE); + I915_WRITE(BLC_PWM_CPU_CTL2, BLM_PWM_ENABLE); I915_WRITE(BLC_PWM_CPU_CTL, 0); - I915_WRITE(BLC_PWM_PCH_CTL1, PWM_ENABLE | (1<<30)); + I915_WRITE(BLC_PWM_PCH_CTL1, BLM_PCH_PWM_ENABLE | BLM_PCH_OVERRIDE_ENABLE); } void intel_modeset_init_hw(struct drm_device *dev) @@ -6965,7 +7224,7 @@ void intel_modeset_init(struct drm_device *dev) dev->mode_config.max_width = 8192; dev->mode_config.max_height = 8192; } - dev->mode_config.fb_base = dev->agp->base; + dev->mode_config.fb_base = dev_priv->mm.gtt_base_addr; DRM_DEBUG_KMS("%d display pipe%s available.\n", dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : ""); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index c35edd7ca84d..5290e9df327b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -169,6 +169,7 @@ struct intel_crtc { u8 lut_r[256], lut_g[256], lut_b[256]; int dpms_mode; bool active; /* is the crtc on? independent of the dpms mode */ + bool primary_disabled; /* is the crtc obscured by a plane? */ bool busy; /* is scanout buffer being updated frequently? */ struct timer_list idle_timer; bool lowfreq_avail; @@ -191,7 +192,6 @@ struct intel_plane { struct drm_plane base; enum pipe pipe; struct drm_i915_gem_object *obj; - bool primary_disabled; int max_downscale; u32 lut_r[1024], lut_g[1024], lut_b[1024]; void (*update_plane)(struct drm_plane *plane, @@ -379,7 +379,8 @@ extern u32 intel_panel_get_max_backlight(struct drm_device *dev); extern u32 intel_panel_get_backlight(struct drm_device *dev); extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); extern int intel_panel_setup_backlight(struct drm_device *dev); -extern void intel_panel_enable_backlight(struct drm_device *dev); +extern void intel_panel_enable_backlight(struct drm_device *dev, + enum pipe pipe); extern void intel_panel_disable_backlight(struct drm_device *dev); extern void intel_panel_destroy_backlight(struct drm_device *dev); extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index bf8690720a0c..e9f8338bd802 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -140,7 +140,9 @@ static int intelfb_create(struct intel_fbdev *ifbdev, info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset; info->fix.smem_len = size; - info->screen_base = ioremap_wc(dev->agp->base + obj->gtt_offset, size); + info->screen_base = + ioremap_wc(dev_priv->mm.gtt_base_addr + obj->gtt_offset, + size); if (!info->screen_base) { ret = -ENOSPC; goto out_unpin; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index b507d38faa10..5b2c88ca6edb 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -37,6 +37,19 @@ #include "i915_drm.h" #include "i915_drv.h" +static void +assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi) +{ + struct drm_device *dev = intel_hdmi->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t enabled_bits; + + enabled_bits = IS_HASWELL(dev) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE; + + WARN(I915_READ(intel_hdmi->sdvox_reg) & enabled_bits, + "HDMI port enabled, expecting disabled\n"); +} + struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder) { return container_of(encoder, struct intel_hdmi, base.base); @@ -334,6 +347,8 @@ static void g4x_set_infoframes(struct drm_encoder *encoder, u32 val = I915_READ(reg); u32 port; + assert_hdmi_port_disabled(intel_hdmi); + /* If the registers were not initialized yet, they might be zeroes, * which means we're selecting the AVI DIP and we're setting its * frequency to once. This seems to really confuse the HW and make @@ -395,6 +410,8 @@ static void ibx_set_infoframes(struct drm_encoder *encoder, u32 val = I915_READ(reg); u32 port; + assert_hdmi_port_disabled(intel_hdmi); + /* See the big comment in g4x_set_infoframes() */ val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC; @@ -451,6 +468,8 @@ static void cpt_set_infoframes(struct drm_encoder *encoder, u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe); u32 val = I915_READ(reg); + assert_hdmi_port_disabled(intel_hdmi); + /* See the big comment in g4x_set_infoframes() */ val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC; @@ -484,6 +503,8 @@ static void vlv_set_infoframes(struct drm_encoder *encoder, u32 reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe); u32 val = I915_READ(reg); + assert_hdmi_port_disabled(intel_hdmi); + /* See the big comment in g4x_set_infoframes() */ val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC; @@ -516,6 +537,8 @@ static void hsw_set_infoframes(struct drm_encoder *encoder, u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe); u32 val = I915_READ(reg); + assert_hdmi_port_disabled(intel_hdmi); + if (!intel_hdmi->has_hdmi_sink) { I915_WRITE(reg, 0); POSTING_READ(reg); @@ -569,7 +592,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, if (HAS_PCH_CPT(dev)) sdvox |= PORT_TRANS_SEL_CPT(intel_crtc->pipe); - else if (intel_crtc->pipe == 1) + else if (intel_crtc->pipe == PIPE_B) sdvox |= SDVO_PIPE_B_SELECT; I915_WRITE(intel_hdmi->sdvox_reg, sdvox); @@ -591,6 +614,36 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) temp = I915_READ(intel_hdmi->sdvox_reg); + /* HW workaround for IBX, we need to move the port to transcoder A + * before disabling it. */ + if (HAS_PCH_IBX(dev)) { + struct drm_crtc *crtc = encoder->crtc; + int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1; + + if (mode != DRM_MODE_DPMS_ON) { + if (temp & SDVO_PIPE_B_SELECT) { + temp &= ~SDVO_PIPE_B_SELECT; + I915_WRITE(intel_hdmi->sdvox_reg, temp); + POSTING_READ(intel_hdmi->sdvox_reg); + + /* Again we need to write this twice. */ + I915_WRITE(intel_hdmi->sdvox_reg, temp); + POSTING_READ(intel_hdmi->sdvox_reg); + + /* Transcoder selection bits only update + * effectively on vblank. */ + if (crtc) + intel_wait_for_vblank(dev, pipe); + else + msleep(50); + } + } else { + /* Restore the transcoder select bit. */ + if (pipe == PIPE_B) + enable_bits |= SDVO_PIPE_B_SELECT; + } + } + /* HW workaround, need to toggle enable bit off and on for 12bpc, but * we do this anyway which shows more stable in testing. */ diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 08eb04c787e8..05fcadbeac66 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -71,6 +71,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) static void intel_lvds_enable(struct intel_lvds *intel_lvds) { struct drm_device *dev = intel_lvds->base.base.dev; + struct intel_crtc *intel_crtc = to_intel_crtc(intel_lvds->base.base.crtc); struct drm_i915_private *dev_priv = dev->dev_private; u32 ctl_reg, lvds_reg, stat_reg; @@ -107,7 +108,7 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds) if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) DRM_ERROR("timed out waiting for panel to power on\n"); - intel_panel_enable_backlight(dev); + intel_panel_enable_backlight(dev, intel_crtc->pipe); } static void intel_lvds_disable(struct intel_lvds *intel_lvds) @@ -777,6 +778,14 @@ static const struct dmi_system_id intel_no_lvds[] = { DMI_MATCH(DMI_BOARD_NAME, "MS-7469"), }, }, + { + .callback = intel_no_lvds_dmi_callback, + .ident = "ZOTAC ZBOXSD-ID12/ID13", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ZOTAC"), + DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), + }, + }, { } /* terminating entry */ }; @@ -967,6 +976,8 @@ bool intel_lvds_init(struct drm_device *dev) intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); if (HAS_PCH_SPLIT(dev)) intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); + else if (IS_GEN4(dev)) + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); else intel_encoder->crtc_mask = (1 << 1); @@ -1074,35 +1085,14 @@ bool intel_lvds_init(struct drm_device *dev) goto failed; out: + /* + * Unlock registers and just + * leave them unlocked + */ if (HAS_PCH_SPLIT(dev)) { - u32 pwm; - - pipe = (I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT) ? 1 : 0; - - /* make sure PWM is enabled and locked to the LVDS pipe */ - pwm = I915_READ(BLC_PWM_CPU_CTL2); - if (pipe == 0 && (pwm & PWM_PIPE_B)) - I915_WRITE(BLC_PWM_CPU_CTL2, pwm & ~PWM_ENABLE); - if (pipe) - pwm |= PWM_PIPE_B; - else - pwm &= ~PWM_PIPE_B; - I915_WRITE(BLC_PWM_CPU_CTL2, pwm | PWM_ENABLE); - - pwm = I915_READ(BLC_PWM_PCH_CTL1); - pwm |= PWM_PCH_ENABLE; - I915_WRITE(BLC_PWM_PCH_CTL1, pwm); - /* - * Unlock registers and just - * leave them unlocked - */ I915_WRITE(PCH_PP_CONTROL, I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); } else { - /* - * Unlock registers and just - * leave them unlocked - */ I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); } diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 7180cc828f94..58c7ee7238b8 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -287,9 +287,18 @@ void intel_panel_disable_backlight(struct drm_device *dev) dev_priv->backlight_enabled = false; intel_panel_actually_set_backlight(dev, 0); + + if (INTEL_INFO(dev)->gen >= 4) { + uint32_t reg; + + reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2; + + I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE); + } } -void intel_panel_enable_backlight(struct drm_device *dev) +void intel_panel_enable_backlight(struct drm_device *dev, + enum pipe pipe) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -298,6 +307,33 @@ void intel_panel_enable_backlight(struct drm_device *dev) dev_priv->backlight_enabled = true; intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); + + if (INTEL_INFO(dev)->gen >= 4) { + uint32_t reg, tmp; + + reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2; + + + tmp = I915_READ(reg); + + /* Note that this can also get called through dpms changes. And + * we don't track the backlight dpms state, hence check whether + * we have to do anything first. */ + if (tmp & BLM_PWM_ENABLE) + return; + + if (dev_priv->num_pipe == 3) + tmp &= ~BLM_PIPE_SELECT_IVB; + else + tmp &= ~BLM_PIPE_SELECT; + + tmp |= BLM_PIPE(pipe); + tmp &= ~BLM_PWM_ENABLE; + + I915_WRITE(reg, tmp); + POSTING_READ(reg); + I915_WRITE(reg, tmp | BLM_PWM_ENABLE); + } } static void intel_panel_init_backlight(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d0ce2a5b1d3f..7504fbce05cc 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -405,7 +405,9 @@ void intel_update_fbc(struct drm_device *dev) * - going to an unsupported config (interlace, pixel multiply, etc.) */ list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { - if (tmp_crtc->enabled && tmp_crtc->fb) { + if (tmp_crtc->enabled && + !to_intel_crtc(tmp_crtc)->primary_disabled && + tmp_crtc->fb) { if (crtc) { DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; @@ -3328,8 +3330,12 @@ static void gen6_init_clock_gating(struct drm_device *dev) * * According to the spec, bit 11 (RCCUNIT) must also be set, * but we didn't debug actual testcases to find it out. + * + * Also apply WaDisableVDSUnitClockGating and + * WaDisableRCPBUnitClockGating. */ I915_WRITE(GEN6_UCGCTL2, + GEN7_VDSUNIT_CLOCK_GATE_DISABLE | GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); @@ -3357,6 +3363,9 @@ static void gen6_init_clock_gating(struct drm_device *dev) ILK_DPARB_CLK_GATE | ILK_DPFD_CLK_GATE); + I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | + GEN6_MBCTL_ENABLE_BOOT_FETCH); + for_each_pipe(pipe) { I915_WRITE(DSPCNTR(pipe), I915_READ(DSPCNTR(pipe)) | @@ -3382,6 +3391,7 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; int pipe; uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; + uint32_t snpcr; I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); @@ -3389,11 +3399,6 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); - /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. - * This implements the WaDisableRCZUnitClockGating workaround. - */ - I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); - I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); I915_WRITE(IVB_CHICKEN3, @@ -3410,6 +3415,23 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, GEN7_WA_L3_CHICKEN_MODE); + /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock + * gating disable must be set. Failure to set it results in + * flickering pixels due to Z write ordering failures after + * some amount of runtime in the Mesa "fire" demo, and Unigine + * Sanctuary and Tropics, and apparently anything else with + * alpha test or pixel discard. + * + * According to the spec, bit 11 (RCCUNIT) must also be set, + * but we didn't debug actual testcases to find it out. + * + * According to the spec, bit 13 (RCZUNIT) must be set on IVB. + * This implements the WaDisableRCZUnitClockGating workaround. + */ + I915_WRITE(GEN6_UCGCTL2, + GEN6_RCZUNIT_CLOCK_GATE_DISABLE | + GEN6_RCCUNIT_CLOCK_GATE_DISABLE); + /* This is required by WaCatErrorRejectionIssue */ I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | @@ -3422,11 +3444,19 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) intel_flush_display_plane(dev_priv, pipe); } + I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | + GEN6_MBCTL_ENABLE_BOOT_FETCH); + gen7_setup_fixed_func_scheduler(dev_priv); /* WaDisable4x2SubspanOptimization */ I915_WRITE(CACHE_MODE_1, _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); + + snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); + snpcr &= ~GEN6_MBC_SNPCR_MASK; + snpcr |= GEN6_MBC_SNPCR_MED; + I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr); } static void valleyview_init_clock_gating(struct drm_device *dev) @@ -3441,11 +3471,6 @@ static void valleyview_init_clock_gating(struct drm_device *dev) I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); - /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. - * This implements the WaDisableRCZUnitClockGating workaround. - */ - I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); - I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); I915_WRITE(IVB_CHICKEN3, @@ -3465,6 +3490,35 @@ static void valleyview_init_clock_gating(struct drm_device *dev) I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); + I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | + GEN6_MBCTL_ENABLE_BOOT_FETCH); + + + /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock + * gating disable must be set. Failure to set it results in + * flickering pixels due to Z write ordering failures after + * some amount of runtime in the Mesa "fire" demo, and Unigine + * Sanctuary and Tropics, and apparently anything else with + * alpha test or pixel discard. + * + * According to the spec, bit 11 (RCCUNIT) must also be set, + * but we didn't debug actual testcases to find it out. + * + * According to the spec, bit 13 (RCZUNIT) must be set on IVB. + * This implements the WaDisableRCZUnitClockGating workaround. + * + * Also apply WaDisableVDSUnitClockGating and + * WaDisableRCPBUnitClockGating. + */ + I915_WRITE(GEN6_UCGCTL2, + GEN7_VDSUNIT_CLOCK_GATE_DISABLE | + GEN7_TDLUNIT_CLOCK_GATE_DISABLE | + GEN6_RCZUNIT_CLOCK_GATE_DISABLE | + GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | + GEN6_RCCUNIT_CLOCK_GATE_DISABLE); + + I915_WRITE(GEN7_UCGCTL4, GEN7_L3BANK2X_CLOCK_GATE_DISABLE); + for_each_pipe(pipe) { I915_WRITE(DSPCNTR(pipe), I915_READ(DSPCNTR(pipe)) | @@ -3474,6 +3528,19 @@ static void valleyview_init_clock_gating(struct drm_device *dev) I915_WRITE(CACHE_MODE_1, _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); + + /* + * On ValleyView, the GUnit needs to signal the GT + * when flip and other events complete. So enable + * all the GUnit->GT interrupts here + */ + I915_WRITE(VLV_DPFLIPSTAT, PIPEB_LINE_COMPARE_INT_EN | + PIPEB_HLINE_INT_EN | PIPEB_VBLANK_INT_EN | + SPRITED_FLIPDONE_INT_EN | SPRITEC_FLIPDONE_INT_EN | + PLANEB_FLIPDONE_INT_EN | PIPEA_LINE_COMPARE_INT_EN | + PIPEA_HLINE_INT_EN | PIPEA_VBLANK_INT_EN | + SPRITEB_FLIPDONE_INT_EN | SPRITEA_FLIPDONE_INT_EN | + PLANEA_FLIPDONE_INT_EN); } static void g4x_init_clock_gating(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f30850b079e9..f30a53a8917e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -226,6 +226,7 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring, * impact. */ flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; + flags |= PIPE_CONTROL_TLB_INVALIDATE; flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; @@ -433,6 +434,13 @@ static int init_render_ring(struct intel_ring_buffer *ring) */ I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); + + /* This is not explicitly set for GEN6, so read the register. + * see intel_ring_mi_set_context() for why we care. + * TODO: consider explicitly setting the bit for GEN5 + */ + ring->itlb_before_ctx_switch = + !!(I915_READ(GFX_MODE) & GFX_TLB_INVALIDATE_ALWAYS); } if (INTEL_INFO(dev)->gen >= 6) @@ -979,6 +987,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, struct intel_ring_buffer *ring) { struct drm_i915_gem_object *obj; + struct drm_i915_private *dev_priv = dev->dev_private; int ret; ring->dev = dev; @@ -1012,8 +1021,9 @@ static int intel_init_ring_buffer(struct drm_device *dev, if (ret) goto err_unpin; - ring->virtual_start = ioremap_wc(dev->agp->base + obj->gtt_offset, - ring->size); + ring->virtual_start = + ioremap_wc(dev_priv->mm.gtt->gma_bus_addr + obj->gtt_offset, + ring->size); if (ring->virtual_start == NULL) { DRM_ERROR("Failed to map ringbuffer.\n"); ret = -EINVAL; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 55d3da26bae7..1d3c81fdad92 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -113,9 +113,17 @@ struct intel_ring_buffer { * Do we have some not yet emitted requests outstanding? */ u32 outstanding_lazy_request; + bool gpu_caches_dirty; wait_queue_head_t irq_queue; + /** + * Do an explicit TLB flush before MI_SET_CONTEXT + */ + bool itlb_before_ctx_switch; + struct i915_hw_context *default_context; + struct drm_i915_gem_object *last_context_obj; + void *private; }; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 2a20fb0781d7..9d7777bc1545 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -326,6 +326,12 @@ intel_enable_primary(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int reg = DSPCNTR(intel_crtc->plane); + if (!intel_crtc->primary_disabled) + return; + + intel_crtc->primary_disabled = false; + intel_update_fbc(dev); + I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); } @@ -337,7 +343,13 @@ intel_disable_primary(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int reg = DSPCNTR(intel_crtc->plane); + if (intel_crtc->primary_disabled) + return; + I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); + + intel_crtc->primary_disabled = true; + intel_update_fbc(dev); } static int @@ -485,18 +497,14 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, * Be sure to re-enable the primary before the sprite is no longer * covering it fully. */ - if (!disable_primary && intel_plane->primary_disabled) { + if (!disable_primary) intel_enable_primary(crtc); - intel_plane->primary_disabled = false; - } intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y, crtc_w, crtc_h, x, y, src_w, src_h); - if (disable_primary) { + if (disable_primary) intel_disable_primary(crtc); - intel_plane->primary_disabled = true; - } /* Unpin old obj after new one is active to avoid ugliness */ if (old_obj) { @@ -527,11 +535,8 @@ intel_disable_plane(struct drm_plane *plane) struct intel_plane *intel_plane = to_intel_plane(plane); int ret = 0; - if (intel_plane->primary_disabled) { + if (plane->crtc) intel_enable_primary(plane->crtc); - intel_plane->primary_disabled = false; - } - intel_plane->disable_plane(plane); if (!intel_plane->obj) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 01d77d1554f4..3904d7964a4b 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1149,7 +1149,9 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, } if (tiling_flags & RADEON_TILING_MACRO) { - if (rdev->family >= CHIP_CAYMAN) + if (rdev->family >= CHIP_TAHITI) + tmp = rdev->config.si.tile_config; + else if (rdev->family >= CHIP_CAYMAN) tmp = rdev->config.cayman.tile_config; else tmp = rdev->config.evergreen.tile_config; @@ -1177,6 +1179,12 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, } else if (tiling_flags & RADEON_TILING_MICRO) fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); + if ((rdev->family == CHIP_TAHITI) || + (rdev->family == CHIP_PITCAIRN)) + fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16); + else if (rdev->family == CHIP_VERDE) + fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16); + switch (radeon_crtc->crtc_id) { case 0: WREG32(AVIVO_D1VGA_CONTROL, 0); diff --git a/drivers/gpu/drm/radeon/si_reg.h b/drivers/gpu/drm/radeon/si_reg.h index eda938a7cb6e..501f9d431d57 100644 --- a/drivers/gpu/drm/radeon/si_reg.h +++ b/drivers/gpu/drm/radeon/si_reg.h @@ -30,4 +30,76 @@ #define SI_DC_GPIO_HPD_EN 0x65b8 #define SI_DC_GPIO_HPD_Y 0x65bc +#define SI_GRPH_CONTROL 0x6804 +# define SI_GRPH_DEPTH(x) (((x) & 0x3) << 0) +# define SI_GRPH_DEPTH_8BPP 0 +# define SI_GRPH_DEPTH_16BPP 1 +# define SI_GRPH_DEPTH_32BPP 2 +# define SI_GRPH_NUM_BANKS(x) (((x) & 0x3) << 2) +# define SI_ADDR_SURF_2_BANK 0 +# define SI_ADDR_SURF_4_BANK 1 +# define SI_ADDR_SURF_8_BANK 2 +# define SI_ADDR_SURF_16_BANK 3 +# define SI_GRPH_Z(x) (((x) & 0x3) << 4) +# define SI_GRPH_BANK_WIDTH(x) (((x) & 0x3) << 6) +# define SI_ADDR_SURF_BANK_WIDTH_1 0 +# define SI_ADDR_SURF_BANK_WIDTH_2 1 +# define SI_ADDR_SURF_BANK_WIDTH_4 2 +# define SI_ADDR_SURF_BANK_WIDTH_8 3 +# define SI_GRPH_FORMAT(x) (((x) & 0x7) << 8) +/* 8 BPP */ +# define SI_GRPH_FORMAT_INDEXED 0 +/* 16 BPP */ +# define SI_GRPH_FORMAT_ARGB1555 0 +# define SI_GRPH_FORMAT_ARGB565 1 +# define SI_GRPH_FORMAT_ARGB4444 2 +# define SI_GRPH_FORMAT_AI88 3 +# define SI_GRPH_FORMAT_MONO16 4 +# define SI_GRPH_FORMAT_BGRA5551 5 +/* 32 BPP */ +# define SI_GRPH_FORMAT_ARGB8888 0 +# define SI_GRPH_FORMAT_ARGB2101010 1 +# define SI_GRPH_FORMAT_32BPP_DIG 2 +# define SI_GRPH_FORMAT_8B_ARGB2101010 3 +# define SI_GRPH_FORMAT_BGRA1010102 4 +# define SI_GRPH_FORMAT_8B_BGRA1010102 5 +# define SI_GRPH_FORMAT_RGB111110 6 +# define SI_GRPH_FORMAT_BGR101111 7 +# define SI_GRPH_BANK_HEIGHT(x) (((x) & 0x3) << 11) +# define SI_ADDR_SURF_BANK_HEIGHT_1 0 +# define SI_ADDR_SURF_BANK_HEIGHT_2 1 +# define SI_ADDR_SURF_BANK_HEIGHT_4 2 +# define SI_ADDR_SURF_BANK_HEIGHT_8 3 +# define SI_GRPH_TILE_SPLIT(x) (((x) & 0x7) << 13) +# define SI_ADDR_SURF_TILE_SPLIT_64B 0 +# define SI_ADDR_SURF_TILE_SPLIT_128B 1 +# define SI_ADDR_SURF_TILE_SPLIT_256B 2 +# define SI_ADDR_SURF_TILE_SPLIT_512B 3 +# define SI_ADDR_SURF_TILE_SPLIT_1KB 4 +# define SI_ADDR_SURF_TILE_SPLIT_2KB 5 +# define SI_ADDR_SURF_TILE_SPLIT_4KB 6 +# define SI_GRPH_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 18) +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_1 0 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_2 1 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_4 2 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_8 3 +# define SI_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20) +# define SI_GRPH_ARRAY_LINEAR_GENERAL 0 +# define SI_GRPH_ARRAY_LINEAR_ALIGNED 1 +# define SI_GRPH_ARRAY_1D_TILED_THIN1 2 +# define SI_GRPH_ARRAY_2D_TILED_THIN1 4 +# define SI_GRPH_PIPE_CONFIG(x) (((x) & 0x1f) << 24) +# define SI_ADDR_SURF_P2 0 +# define SI_ADDR_SURF_P4_8x16 4 +# define SI_ADDR_SURF_P4_16x16 5 +# define SI_ADDR_SURF_P4_16x32 6 +# define SI_ADDR_SURF_P4_32x32 7 +# define SI_ADDR_SURF_P8_16x16_8x16 8 +# define SI_ADDR_SURF_P8_16x32_8x16 9 +# define SI_ADDR_SURF_P8_32x32_8x16 10 +# define SI_ADDR_SURF_P8_16x32_16x16 11 +# define SI_ADDR_SURF_P8_32x32_16x16 12 +# define SI_ADDR_SURF_P8_32x32_16x32 13 +# define SI_ADDR_SURF_P8_32x64_32x32 14 + #endif diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index f082e48ab113..70d62f5bc909 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -215,7 +215,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) int i; if (send_command(cmd) || send_argument(key)) { - pr_warn("%s: read arg fail\n", key); + pr_warn("%.4s: read arg fail\n", key); return -EIO; } @@ -223,7 +223,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) for (i = 0; i < len; i++) { if (__wait_status(0x05)) { - pr_warn("%s: read data fail\n", key); + pr_warn("%.4s: read data fail\n", key); return -EIO; } buffer[i] = inb(APPLESMC_DATA_PORT); diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index b9d512331ed4..7f1feb2f467a 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -191,6 +191,24 @@ static ssize_t show_temp(struct device *dev, return tdata->valid ? sprintf(buf, "%d\n", tdata->temp) : -EAGAIN; } +struct tjmax { + char const *id; + int tjmax; +}; + +static struct tjmax __cpuinitconst tjmax_table[] = { + { "CPU D410", 100000 }, + { "CPU D425", 100000 }, + { "CPU D510", 100000 }, + { "CPU D525", 100000 }, + { "CPU N450", 100000 }, + { "CPU N455", 100000 }, + { "CPU N470", 100000 }, + { "CPU N475", 100000 }, + { "CPU 230", 100000 }, + { "CPU 330", 125000 }, +}; + static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) { @@ -202,6 +220,13 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, int err; u32 eax, edx; struct pci_dev *host_bridge; + int i; + + /* explicit tjmax table entries override heuristics */ + for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) { + if (strstr(c->x86_model_id, tjmax_table[i].id)) + return tjmax_table[i].tjmax; + } /* Early chips have no MSR for TjMax */ @@ -210,7 +235,8 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, /* Atom CPUs */ - if (c->x86_model == 0x1c) { + if (c->x86_model == 0x1c || c->x86_model == 0x26 + || c->x86_model == 0x27) { usemsr_ee = 0; host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); @@ -223,6 +249,9 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, tjmax = 90000; pci_dev_put(host_bridge); + } else if (c->x86_model == 0x36) { + usemsr_ee = 0; + tjmax = 100000; } if (c->x86_model > 0xe && usemsr_ee) { @@ -772,7 +801,7 @@ MODULE_DEVICE_TABLE(x86cpu, coretemp_ids); static int __init coretemp_init(void) { - int i, err = -ENODEV; + int i, err; /* * CPUID.06H.EAX[0] indicates whether the CPU has thermal diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c index 9691f664c76e..e7d234b59312 100644 --- a/drivers/hwmon/emc2103.c +++ b/drivers/hwmon/emc2103.c @@ -451,11 +451,15 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, data->fan_rpm_control = true; break; default: - mutex_unlock(&data->update_lock); - return -EINVAL; + count = -EINVAL; + goto err; } - read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); + result = read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); + if (result) { + count = result; + goto err; + } if (data->fan_rpm_control) conf_reg |= 0x80; @@ -463,7 +467,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, conf_reg &= ~0x80; i2c_smbus_write_byte_data(client, REG_FAN_CONF1, conf_reg); - +err: mutex_unlock(&data->update_lock); return count; } diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 56eecefcec75..2ec93da41e2c 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -8,8 +8,7 @@ menuconfig IIO help The industrial I/O subsystem provides a unified framework for drivers for many different types of embedded sensors using a - number of different physical interfaces (i2c, spi, etc). See - Documentation/iio for more information. + number of different physical interfaces (i2c, spi, etc). if IIO diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 1ddd8861c71b..4f947e4377ef 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -661,7 +661,6 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev) * New channel registration method - relies on the fact a group does * not need to be initialized if it is name is NULL. */ - INIT_LIST_HEAD(&indio_dev->channel_attr_list); if (indio_dev->channels) for (i = 0; i < indio_dev->num_channels; i++) { ret = iio_device_add_channel_sysfs(indio_dev, @@ -725,12 +724,16 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) static void iio_dev_release(struct device *device) { struct iio_dev *indio_dev = dev_to_iio_dev(device); - cdev_del(&indio_dev->chrdev); + if (indio_dev->chrdev.dev) + cdev_del(&indio_dev->chrdev); if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) iio_device_unregister_trigger_consumer(indio_dev); iio_device_unregister_eventset(indio_dev); iio_device_unregister_sysfs(indio_dev); iio_device_unregister_debugfs(indio_dev); + + ida_simple_remove(&iio_ida, indio_dev->id); + kfree(indio_dev); } static struct device_type iio_dev_type = { @@ -761,6 +764,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) dev_set_drvdata(&dev->dev, (void *)dev); mutex_init(&dev->mlock); mutex_init(&dev->info_exist_lock); + INIT_LIST_HEAD(&dev->channel_attr_list); dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); if (dev->id < 0) { @@ -778,10 +782,8 @@ EXPORT_SYMBOL(iio_device_alloc); void iio_device_free(struct iio_dev *dev) { - if (dev) { - ida_simple_remove(&iio_ida, dev->id); - kfree(dev); - } + if (dev) + put_device(&dev->dev); } EXPORT_SYMBOL(iio_device_free); @@ -902,7 +904,7 @@ void iio_device_unregister(struct iio_dev *indio_dev) mutex_lock(&indio_dev->info_exist_lock); indio_dev->info = NULL; mutex_unlock(&indio_dev->info_exist_lock); - device_unregister(&indio_dev->dev); + device_del(&indio_dev->dev); } EXPORT_SYMBOL(iio_device_unregister); subsys_initcall(iio_init); diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 55d5642eb10a..2e826f9702c6 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1184,7 +1184,7 @@ static void cma_set_req_event_data(struct rdma_cm_event *event, static int cma_check_req_qp_type(struct rdma_cm_id *id, struct ib_cm_event *ib_event) { - return (((ib_event->event == IB_CM_REQ_RECEIVED) || + return (((ib_event->event == IB_CM_REQ_RECEIVED) && (ib_event->param.req_rcvd.qp_type == id->qp_type)) || ((ib_event->event == IB_CM_SIDR_REQ_RECEIVED) && (id->qp_type == IB_QPT_UD)) || diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h index 037f5cea85bd..48970af23679 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma.h @@ -61,6 +61,7 @@ struct ocrdma_dev_attr { u32 max_inline_data; int max_send_sge; int max_recv_sge; + int max_srq_sge; int max_mr; u64 max_mr_size; u32 max_num_mr_pbl; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 9343a1522977..71942af4fce9 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c @@ -990,8 +990,6 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, struct ocrdma_dev_attr *attr, struct ocrdma_mbx_query_config *rsp) { - int max_q_mem; - attr->max_pd = (rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT; @@ -1004,6 +1002,9 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, attr->max_recv_sge = (rsp->max_write_send_sge & OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT; + attr->max_srq_sge = (rsp->max_srq_rqe_sge & + OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK) >> + OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET; attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp & OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT; @@ -1037,18 +1038,15 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, attr->max_inline_data = attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) + sizeof(struct ocrdma_sge)); - max_q_mem = OCRDMA_Q_PAGE_BASE_SIZE << (OCRDMA_MAX_Q_PAGE_SIZE_CNT - 1); - /* hw can queue one less then the configured size, - * so publish less by one to stack. - */ if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { - dev->attr.max_wqe = max_q_mem / dev->attr.wqe_size; attr->ird = 1; attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE; attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES; - } else - dev->attr.max_wqe = (max_q_mem / dev->attr.wqe_size) - 1; - dev->attr.max_rqe = (max_q_mem / dev->attr.rqe_size) - 1; + } + dev->attr.max_wqe = rsp->max_wqes_rqes_per_q >> + OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET; + dev->attr.max_rqe = rsp->max_wqes_rqes_per_q & + OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK; } static int ocrdma_check_fw_config(struct ocrdma_dev *dev, diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index 04fef3de6d75..b050e629e9c3 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c @@ -97,13 +97,11 @@ static void ocrdma_build_sgid_mac(union ib_gid *sgid, unsigned char *mac_addr, sgid->raw[15] = mac_addr[5]; } -static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, +static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, bool is_vlan, u16 vlan_id) { int i; - bool found = false; union ib_gid new_sgid; - int free_idx = OCRDMA_MAX_SGID; unsigned long flags; memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid)); @@ -115,23 +113,19 @@ static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid, sizeof(union ib_gid))) { /* found free entry */ - if (!found) { - free_idx = i; - found = true; - break; - } + memcpy(&dev->sgid_tbl[i], &new_sgid, + sizeof(union ib_gid)); + spin_unlock_irqrestore(&dev->sgid_lock, flags); + return true; } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid, sizeof(union ib_gid))) { /* entry already present, no addition is required. */ spin_unlock_irqrestore(&dev->sgid_lock, flags); - return; + return false; } } - /* if entry doesn't exist and if table has some space, add entry */ - if (found) - memcpy(&dev->sgid_tbl[free_idx], &new_sgid, - sizeof(union ib_gid)); spin_unlock_irqrestore(&dev->sgid_lock, flags); + return false; } static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, @@ -167,7 +161,8 @@ static void ocrdma_add_default_sgid(struct ocrdma_dev *dev) ocrdma_get_guid(dev, &sgid->raw[8]); } -static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) { struct net_device *netdev, *tmp; u16 vlan_id; @@ -175,8 +170,6 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) netdev = dev->nic_info.netdev; - ocrdma_add_default_sgid(dev); - rcu_read_lock(); for_each_netdev_rcu(&init_net, tmp) { if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) { @@ -194,10 +187,23 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) } } rcu_read_unlock(); +} +#else +static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) +{ + +} +#endif /* VLAN */ + +static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) +{ + ocrdma_add_default_sgid(dev); + ocrdma_add_vlan_sgids(dev); return 0; } -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) || \ +defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) static int ocrdma_inet6addr_event(struct notifier_block *notifier, unsigned long event, void *ptr) @@ -208,6 +214,7 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, struct ib_event gid_event; struct ocrdma_dev *dev; bool found = false; + bool updated = false; bool is_vlan = false; u16 vid = 0; @@ -233,23 +240,21 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, mutex_lock(&dev->dev_lock); switch (event) { case NETDEV_UP: - ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); + updated = ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); break; case NETDEV_DOWN: - found = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); - if (found) { - /* found the matching entry, notify - * the consumers about it - */ - gid_event.device = &dev->ibdev; - gid_event.element.port_num = 1; - gid_event.event = IB_EVENT_GID_CHANGE; - ib_dispatch_event(&gid_event); - } + updated = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); break; default: break; } + if (updated) { + /* GID table updated, notify the consumers about it */ + gid_event.device = &dev->ibdev; + gid_event.element.port_num = 1; + gid_event.event = IB_EVENT_GID_CHANGE; + ib_dispatch_event(&gid_event); + } mutex_unlock(&dev->dev_lock); return NOTIFY_OK; } @@ -258,7 +263,7 @@ static struct notifier_block ocrdma_inet6addr_notifier = { .notifier_call = ocrdma_inet6addr_event }; -#endif /* IPV6 */ +#endif /* IPV6 and VLAN */ static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device, u8 port_num) diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h index 7fd80cc0f037..c75cbdfa87e7 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h @@ -418,6 +418,9 @@ enum { OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT = 0, OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK = 0xFFFF, + OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT = 16, + OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_MASK = 0xFFFF << + OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT, OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT = 0, OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK = 0xFFFF, @@ -458,7 +461,7 @@ enum { OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET = 0, OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, + OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET, OCRDMA_MBX_QUERY_CFG_MAX_CQ_OFFSET = 16, OCRDMA_MBX_QUERY_CFG_MAX_CQ_MASK = 0xFFFF << diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index d16d172b6b6b..2e2e7aecc990 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -53,7 +53,7 @@ int ocrdma_query_gid(struct ib_device *ibdev, u8 port, dev = get_ocrdma_dev(ibdev); memset(sgid, 0, sizeof(*sgid)); - if (index > OCRDMA_MAX_SGID) + if (index >= OCRDMA_MAX_SGID) return -EINVAL; memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid)); @@ -83,8 +83,8 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) IB_DEVICE_SHUTDOWN_PORT | IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_LOCAL_DMA_LKEY; - attr->max_sge = dev->attr.max_send_sge; - attr->max_sge_rd = dev->attr.max_send_sge; + attr->max_sge = min(dev->attr.max_send_sge, dev->attr.max_srq_sge); + attr->max_sge_rd = 0; attr->max_cq = dev->attr.max_cq; attr->max_cqe = dev->attr.max_cqe; attr->max_mr = dev->attr.max_mr; @@ -97,7 +97,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) min(dev->attr.max_ord_per_qp, dev->attr.max_ird_per_qp); attr->max_qp_init_rd_atom = dev->attr.max_ord_per_qp; attr->max_srq = (dev->attr.max_qp - 1); - attr->max_srq_sge = attr->max_sge; + attr->max_srq_sge = attr->max_srq_sge; attr->max_srq_wr = dev->attr.max_rqe; attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay; attr->max_fast_reg_page_list_len = 0; @@ -2301,8 +2301,10 @@ static bool ocrdma_poll_err_rcqe(struct ocrdma_qp *qp, struct ocrdma_cqe *cqe, *stop = true; expand = false; } - } else + } else { + *polled = true; expand = ocrdma_update_err_rcqe(ibwc, cqe, qp, status); + } return expand; } diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index af2d9086d7e8..c370c2d87c17 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index 373f423b1181..947a06a1845f 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c @@ -6,7 +6,7 @@ * * License Terms: GNU General Public License, version 2 * Author: Rabin Vincent for ST-Ericsson - * Author: Viresh Kumar for ST Microelectronics + * Author: Viresh Kumar for ST Microelectronics */ #include diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c index afd459013ecb..9edfe864cc05 100644 --- a/drivers/mfd/stmpe-spi.c +++ b/drivers/mfd/stmpe-spi.c @@ -4,7 +4,7 @@ * Copyright (C) ST Microelectronics SA 2011 * * License Terms: GNU General Public License, version 2 - * Author: Viresh Kumar for ST Microelectronics + * Author: Viresh Kumar for ST Microelectronics */ #include @@ -146,4 +146,4 @@ module_exit(stmpe_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver"); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 93936f1b75eb..23f5463d4cae 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -835,7 +835,7 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, struct mei_cl *cl, struct mei_io_list *cmpl_list) { - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + + if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + sizeof(struct hbm_flow_control))) { /* return the cancel routine */ list_del(&cb_pos->cb_list); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index c70333228337..7de13891e49e 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -982,7 +982,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, err = request_threaded_irq(pdev->irq, NULL, mei_interrupt_thread_handler, - 0, mei_driver_name, dev); + IRQF_ONESHOT, mei_driver_name, dev); else err = request_threaded_irq(pdev->irq, mei_interrupt_quick_handler, @@ -992,7 +992,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, if (err) { dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n", pdev->irq); - goto unmap_memory; + goto disable_msi; } INIT_DELAYED_WORK(&dev->timer_work, mei_timer); if (mei_hw_init(dev)) { @@ -1023,8 +1023,8 @@ static int __devinit mei_probe(struct pci_dev *pdev, mei_disable_interrupts(dev); flush_scheduled_work(); free_irq(pdev->irq, dev); +disable_msi: pci_disable_msi(pdev); -unmap_memory: pci_iounmap(pdev, dev->mem_addr); free_device: kfree(dev); @@ -1101,6 +1101,8 @@ static void __devexit mei_remove(struct pci_dev *pdev) pci_release_regions(pdev); pci_disable_device(pdev); + + misc_deregister(&mei_misc_device); } #ifdef CONFIG_PM static int mei_pci_suspend(struct device *device) @@ -1216,7 +1218,6 @@ module_init(mei_init_module); */ static void __exit mei_exit_module(void) { - misc_deregister(&mei_misc_device); pci_unregister_driver(&mei_driver); pr_debug("unloaded successfully.\n"); diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 6be5605707b4..e2ec0505eb5c 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -341,7 +341,7 @@ static const struct watchdog_ops wd_ops = { }; static const struct watchdog_info wd_info = { .identity = INTEL_AMT_WATCHDOG_ID, - .options = WDIOF_KEEPALIVEPING, + .options = WDIOF_KEEPALIVEPING | WDIOF_ALARMONLY, }; static struct watchdog_device amt_wd_dev = { diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 2d4a4b746750..258b203397aa 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1326,7 +1326,7 @@ static int mmc_suspend(struct mmc_host *host) if (!err) mmc_card_set_sleep(host->card); } else if (!mmc_host_is_spi(host)) - mmc_deselect_cards(host); + err = mmc_deselect_cards(host); host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); mmc_release_host(host); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index c272c6868ecf..b2b43f624b9e 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1075,16 +1075,18 @@ static void mmc_sd_detect(struct mmc_host *host) */ static int mmc_sd_suspend(struct mmc_host *host) { + int err = 0; + BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); if (!mmc_host_is_spi(host)) - mmc_deselect_cards(host); + err = mmc_deselect_cards(host); host->card->state &= ~MMC_STATE_HIGHSPEED; mmc_release_host(host); - return 0; + return err; } /* diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 13d0e95380ab..41c5fd8848f4 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -218,6 +218,12 @@ static int sdio_enable_wide(struct mmc_card *card) if (ret) return ret; + if ((ctrl & SDIO_BUS_WIDTH_MASK) == SDIO_BUS_WIDTH_RESERVED) + pr_warning("%s: SDIO_CCCR_IF is invalid: 0x%02x\n", + mmc_hostname(card->host), ctrl); + + /* set as 4-bit bus width */ + ctrl &= ~SDIO_BUS_WIDTH_MASK; ctrl |= SDIO_BUS_WIDTH_4BIT; ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h index 787aba1682bb..ab56f7db5315 100644 --- a/drivers/mmc/host/atmel-mci-regs.h +++ b/drivers/mmc/host/atmel-mci-regs.h @@ -140,4 +140,18 @@ #define atmci_writel(port,reg,value) \ __raw_writel((value), (port)->regs + reg) +/* + * Fix sconfig's burst size according to atmel MCI. We need to convert them as: + * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3. + * + * This can be done by finding most significant bit set. + */ +static inline unsigned int atmci_convert_chksize(unsigned int maxburst) +{ + if (maxburst > 1) + return fls(maxburst) - 2; + else + return 0; +} + #endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */ diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 420aca642b14..f2c115e06438 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -910,6 +910,7 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) enum dma_data_direction direction; enum dma_transfer_direction slave_dirn; unsigned int sglen; + u32 maxburst; u32 iflags; data->error = -EINPROGRESS; @@ -943,17 +944,18 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) if (!chan) return -ENODEV; - if (host->caps.has_dma) - atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(3) | ATMCI_DMAEN); - if (data->flags & MMC_DATA_READ) { direction = DMA_FROM_DEVICE; host->dma_conf.direction = slave_dirn = DMA_DEV_TO_MEM; + maxburst = atmci_convert_chksize(host->dma_conf.src_maxburst); } else { direction = DMA_TO_DEVICE; host->dma_conf.direction = slave_dirn = DMA_MEM_TO_DEV; + maxburst = atmci_convert_chksize(host->dma_conf.dst_maxburst); } + atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(maxburst) | ATMCI_DMAEN); + sglen = dma_map_sg(chan->device->dev, data->sg, data->sg_len, direction); @@ -2314,6 +2316,8 @@ static int __init atmci_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); + setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host); + /* We need at least one slot to succeed */ nr_slots = 0; ret = -ENODEV; @@ -2352,8 +2356,6 @@ static int __init atmci_probe(struct platform_device *pdev) } } - setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host); - dev_info(&pdev->dev, "Atmel MCI controller at 0x%08lx irq %d, %u slots\n", host->mapbase, irq, nr_slots); diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 9bbf45f8c538..1ca5e72ceb65 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -418,6 +418,8 @@ static int dw_mci_idmac_init(struct dw_mci *host) p->des3 = host->sg_dma; p->des0 = IDMAC_DES0_ER; + mci_writel(host, BMOD, SDMMC_IDMAC_SWRESET); + /* Mask out interrupts - get Tx & Rx complete only */ mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | SDMMC_IDMAC_INT_RI | SDMMC_IDMAC_INT_TI); @@ -615,14 +617,15 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot) u32 div; if (slot->clock != host->current_speed) { - if (host->bus_hz % slot->clock) + div = host->bus_hz / slot->clock; + if (host->bus_hz % slot->clock && host->bus_hz > slot->clock) /* * move the + 1 after the divide to prevent * over-clocking the card. */ - div = ((host->bus_hz / slot->clock) >> 1) + 1; - else - div = (host->bus_hz / slot->clock) >> 1; + div += 1; + + div = (host->bus_hz != slot->clock) ? DIV_ROUND_UP(div, 2) : 0; dev_info(&slot->mmc->class_dev, "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ" @@ -939,8 +942,8 @@ static void dw_mci_command_complete(struct dw_mci *host, struct mmc_command *cmd mdelay(20); if (cmd->data) { - host->data = NULL; dw_mci_stop_dma(host); + host->data = NULL; } } } @@ -1623,7 +1626,6 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) { mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI); mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI); - set_bit(EVENT_DATA_COMPLETE, &host->pending_events); host->dma_ops->complete(host); } #endif @@ -1725,7 +1727,8 @@ static void dw_mci_work_routine_card(struct work_struct *work) #ifdef CONFIG_MMC_DW_IDMAC ctrl = mci_readl(host, BMOD); - ctrl |= 0x01; /* Software reset of DMA */ + /* Software reset of DMA */ + ctrl |= SDMMC_IDMAC_SWRESET; mci_writel(host, BMOD, ctrl); #endif @@ -1950,10 +1953,6 @@ int dw_mci_probe(struct dw_mci *host) spin_lock_init(&host->lock); INIT_LIST_HEAD(&host->queue); - - host->dma_ops = host->pdata->dma_ops; - dw_mci_init_dma(host); - /* * Get the host data width - this assumes that HCON has been set with * the correct values. @@ -1981,10 +1980,11 @@ int dw_mci_probe(struct dw_mci *host) } /* Reset all blocks */ - if (!mci_wait_reset(&host->dev, host)) { - ret = -ENODEV; - goto err_dmaunmap; - } + if (!mci_wait_reset(&host->dev, host)) + return -ENODEV; + + host->dma_ops = host->pdata->dma_ops; + dw_mci_init_dma(host); /* Clear the interrupts for the host controller */ mci_writel(host, RINTSTS, 0xFFFFFFFF); @@ -2170,14 +2170,14 @@ int dw_mci_resume(struct dw_mci *host) if (host->vmmc) regulator_enable(host->vmmc); - if (host->dma_ops->init) - host->dma_ops->init(host); - if (!mci_wait_reset(&host->dev, host)) { ret = -ENODEV; return ret; } + if (host->dma_ops->init) + host->dma_ops->init(host); + /* Restore the old value at FIFOTH register */ mci_writel(host, FIFOTH, host->fifoth_val); diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index f0fcce40cd8d..50ff19a62368 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1216,12 +1216,7 @@ static void mmci_dt_populate_generic_pdata(struct device_node *np, int bus_width = 0; pdata->gpio_wp = of_get_named_gpio(np, "wp-gpios", 0); - if (!pdata->gpio_wp) - pdata->gpio_wp = -1; - pdata->gpio_cd = of_get_named_gpio(np, "cd-gpios", 0); - if (!pdata->gpio_cd) - pdata->gpio_cd = -1; if (of_get_property(np, "cd-inverted", NULL)) pdata->cd_invert = true; @@ -1276,6 +1271,12 @@ static int __devinit mmci_probe(struct amba_device *dev, return -EINVAL; } + if (!plat) { + plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL); + if (!plat) + return -ENOMEM; + } + if (np) mmci_dt_populate_generic_pdata(np, plat); @@ -1424,6 +1425,10 @@ static int __devinit mmci_probe(struct amba_device *dev, writel(0, host->base + MMCIMASK1); writel(0xfff, host->base + MMCICLEAR); + if (plat->gpio_cd == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err_gpio_cd; + } if (gpio_is_valid(plat->gpio_cd)) { ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)"); if (ret == 0) @@ -1447,6 +1452,10 @@ static int __devinit mmci_probe(struct amba_device *dev, if (ret >= 0) host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd); } + if (plat->gpio_wp == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err_gpio_wp; + } if (gpio_is_valid(plat->gpio_wp)) { ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)"); if (ret == 0) diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 34a90266ab11..277161d279b8 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -894,8 +894,8 @@ static struct platform_driver mxs_mmc_driver = { .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &mxs_mmc_pm_ops, - .of_match_table = mxs_mmc_dt_ids, #endif + .of_match_table = mxs_mmc_dt_ids, }, }; diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 552196c764d4..3e8dcf8d2e05 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1300,7 +1300,7 @@ static const struct mmc_host_ops mmc_omap_ops = { .set_ios = mmc_omap_set_ios, }; -static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id) +static int __devinit mmc_omap_new_slot(struct mmc_omap_host *host, int id) { struct mmc_omap_slot *slot = NULL; struct mmc_host *mmc; @@ -1485,24 +1485,26 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev) } host->nr_slots = pdata->nr_slots; - for (i = 0; i < pdata->nr_slots; i++) { - ret = mmc_omap_new_slot(host, i); - if (ret < 0) { - while (--i >= 0) - mmc_omap_remove_slot(host->slots[i]); - - goto err_plat_cleanup; - } - } - host->reg_shift = (cpu_is_omap7xx() ? 1 : 2); host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0); if (!host->mmc_omap_wq) goto err_plat_cleanup; + for (i = 0; i < pdata->nr_slots; i++) { + ret = mmc_omap_new_slot(host, i); + if (ret < 0) { + while (--i >= 0) + mmc_omap_remove_slot(host->slots[i]); + + goto err_destroy_wq; + } + } + return 0; +err_destroy_wq: + destroy_workqueue(host->mmc_omap_wq); err_plat_cleanup: if (pdata->cleanup) pdata->cleanup(&pdev->dev); diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 55a164fcaa15..a50c205ea208 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -404,7 +404,7 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc) if (sc->ext_cd_irq && request_threaded_irq(sc->ext_cd_irq, NULL, sdhci_s3c_gpio_card_detect_thread, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, dev_name(dev), sc) == 0) { int status = gpio_get_value(sc->ext_cd_gpio); if (pdata->ext_cd_gpio_invert) diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c index 1fe32dfa7cd4..423da8194cd8 100644 --- a/drivers/mmc/host/sdhci-spear.c +++ b/drivers/mmc/host/sdhci-spear.c @@ -4,7 +4,7 @@ * Support of SDHCI platform devices for spear soc family * * Copyright (C) 2010 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * Inspired by sdhci-pltfm.c * @@ -289,5 +289,5 @@ static struct platform_driver sdhci_driver = { module_platform_driver(sdhci_driver); MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver"); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index e626732aff77..f4b8b4db3a9a 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -680,8 +680,8 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) } if (count >= 0xF) { - pr_warning("%s: Too large timeout 0x%x requested for CMD%d!\n", - mmc_hostname(host->mmc), count, cmd->opcode); + DBG("%s: Too large timeout 0x%x requested for CMD%d!\n", + mmc_hostname(host->mmc), count, cmd->opcode); count = 0xE; } diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index ae36d7e1e913..551e316e4454 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -304,32 +304,17 @@ static void find_next_position(struct mtdoops_context *cxt) } static void mtdoops_do_dump(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason, const char *s1, unsigned long l1, - const char *s2, unsigned long l2) + enum kmsg_dump_reason reason) { struct mtdoops_context *cxt = container_of(dumper, struct mtdoops_context, dump); - unsigned long s1_start, s2_start; - unsigned long l1_cpy, l2_cpy; - char *dst; - - if (reason != KMSG_DUMP_OOPS && - reason != KMSG_DUMP_PANIC) - return; /* Only dump oopses if dump_oops is set */ if (reason == KMSG_DUMP_OOPS && !dump_oops) return; - dst = cxt->oops_buf + MTDOOPS_HEADER_SIZE; /* Skip the header */ - l2_cpy = min(l2, record_size - MTDOOPS_HEADER_SIZE); - l1_cpy = min(l1, record_size - MTDOOPS_HEADER_SIZE - l2_cpy); - - s2_start = l2 - l2_cpy; - s1_start = l1 - l1_cpy; - - memcpy(dst, s1 + s1_start, l1_cpy); - memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy); + kmsg_dump_get_buffer(dumper, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE, + record_size - MTDOOPS_HEADER_SIZE, NULL); /* Panics must be written immediately */ if (reason != KMSG_DUMP_OOPS) @@ -375,6 +360,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd) return; } + cxt->dump.max_reason = KMSG_DUMP_OOPS; cxt->dump.dump = mtdoops_do_dump; err = kmsg_dump_register(&cxt->dump); if (err) { diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index acd03a4f9730..1b988f26bdf1 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -3767,7 +3767,7 @@ static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan) if (prev_status >= B43_STAT_STARTED) { err = b43_wireless_core_start(up_dev); if (err) { - b43err(wl, "Fatal: Coult not start device for " + b43err(wl, "Fatal: Could not start device for " "selected %s-GHz band\n", band_to_string(chan->band)); b43_wireless_core_exit(up_dev); diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index cd9c9bc186d9..eae691e2f7dd 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2633,7 +2633,7 @@ static int b43legacy_switch_phymode(struct b43legacy_wl *wl, if (prev_status >= B43legacy_STAT_STARTED) { err = b43legacy_wireless_core_start(up_dev); if (err) { - b43legacyerr(wl, "Fatal: Coult not start device for " + b43legacyerr(wl, "Fatal: Could not start device for " "newly selected %s-PHY mode\n", phymode_to_string(new_mode)); b43legacy_wireless_core_exit(up_dev); diff --git a/drivers/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c index afb50ee64598..4ba4636b6a4a 100644 --- a/drivers/pinctrl/pinctrl-mxs.c +++ b/drivers/pinctrl/pinctrl-mxs.c @@ -137,7 +137,7 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, free_group: if (!purecfg) - free(group); + kfree(group); free: kfree(new_map); return ret; diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index e8937e7e4999..3e7e47d6b385 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -1438,7 +1438,27 @@ static int nmk_pmx_enable(struct pinctrl_dev *pctldev, unsigned function, dev_dbg(npct->dev, "enable group %s, %u pins\n", g->name, g->npins); - /* Handle this special glitch on altfunction C */ + /* + * If we're setting altfunc C by setting both AFSLA and AFSLB to 1, + * we may pass through an undesired state. In this case we take + * some extra care. + * + * Safe sequence used to switch IOs between GPIO and Alternate-C mode: + * - Save SLPM registers (since we have a shadow register in the + * nmk_chip we're using that as backup) + * - Set SLPM=0 for the IOs you want to switch and others to 1 + * - Configure the GPIO registers for the IOs that are being switched + * - Set IOFORCE=1 + * - Modify the AFLSA/B registers for the IOs that are being switched + * - Set IOFORCE=0 + * - Restore SLPM registers + * - Any spurious wake up event during switch sequence to be ignored + * and cleared + * + * We REALLY need to save ALL slpm registers, because the external + * IOFORCE will switch *all* ports to their sleepmode setting to as + * to avoid glitches. (Not just one port!) + */ glitch = (g->altsetting == NMK_GPIO_ALT_C); if (glitch) { diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index 5ae50aadf885..b3f6b2873fdd 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * Inspired from: * - U300 Pinctl drivers diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h index 9155783bb47f..d950eb78d939 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.h +++ b/drivers/pinctrl/spear/pinctrl-spear.h @@ -2,7 +2,7 @@ * Driver header file for the ST Microelectronics SPEAr pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c index fff168be7f00..d6cca8c81b92 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/drivers/pinctrl/spear/pinctrl-spear1310.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr1310 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -2192,7 +2192,7 @@ static void __exit spear1310_pinctrl_exit(void) } module_exit(spear1310_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr1310 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear1310_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c index a8ab2a6f51bf..a0eb057e55bd 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/drivers/pinctrl/spear/pinctrl-spear1340.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr1340 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -1983,7 +1983,7 @@ static void __exit spear1340_pinctrl_exit(void) } module_exit(spear1340_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr1340 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear1340_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c index 9c82a35e4e78..4dfc2849b172 100644 --- a/drivers/pinctrl/spear/pinctrl-spear300.c +++ b/drivers/pinctrl/spear/pinctrl-spear300.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr300 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -702,7 +702,7 @@ static void __exit spear300_pinctrl_exit(void) } module_exit(spear300_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr300 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear300_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c index 1a9707605125..96883693fb7e 100644 --- a/drivers/pinctrl/spear/pinctrl-spear310.c +++ b/drivers/pinctrl/spear/pinctrl-spear310.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr310 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -425,7 +425,7 @@ static void __exit spear310_pinctrl_exit(void) } module_exit(spear310_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr310 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, SPEAr310_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c index de726e6c283a..020b1e0bdb3e 100644 --- a/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/drivers/pinctrl/spear/pinctrl-spear320.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr320 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -3462,7 +3462,7 @@ static void __exit spear320_pinctrl_exit(void) } module_exit(spear320_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr320 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear320_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c index 91c883bc46a6..0242378f7cb8 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.c +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr3xx pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.h b/drivers/pinctrl/spear/pinctrl-spear3xx.h index 5d5fdd8df7b8..31f44347f17c 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.h +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.h @@ -2,7 +2,7 @@ * Header file for the ST Microelectronics SPEAr3xx pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index e1b8c54ace5a..a739f5ca936a 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -794,17 +794,17 @@ static __devinit int ab8500_regulator_register(struct platform_device *pdev, } static struct of_regulator_match ab8500_regulator_matches[] = { - { .name = "LDO-AUX1", .driver_data = (void *) AB8500_LDO_AUX1, }, - { .name = "LDO-AUX2", .driver_data = (void *) AB8500_LDO_AUX2, }, - { .name = "LDO-AUX3", .driver_data = (void *) AB8500_LDO_AUX3, }, - { .name = "LDO-INTCORE", .driver_data = (void *) AB8500_LDO_INTCORE, }, - { .name = "LDO-TVOUT", .driver_data = (void *) AB8500_LDO_TVOUT, }, - { .name = "LDO-USB", .driver_data = (void *) AB8500_LDO_USB, }, - { .name = "LDO-AUDIO", .driver_data = (void *) AB8500_LDO_AUDIO, }, - { .name = "LDO-ANAMIC1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, - { .name = "LDO-ANAMIC2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, - { .name = "LDO-DMIC", .driver_data = (void *) AB8500_LDO_DMIC, }, - { .name = "LDO-ANA", .driver_data = (void *) AB8500_LDO_ANA, }, + { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, }, + { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, }, + { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, }, + { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, }, + { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, }, + { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, }, + { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, }, + { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, + { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, + { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, }, + { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, }, }; static __devinit int diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 968f97f3cb3d..9dbb491b6efa 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -452,26 +452,26 @@ static __devinit int db8500_regulator_register(struct platform_device *pdev, } static struct of_regulator_match db8500_regulator_matches[] = { - { .name = "db8500-vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, - { .name = "db8500-varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, - { .name = "db8500-vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, - { .name = "db8500-vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, - { .name = "db8500-vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, - { .name = "db8500-vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, - { .name = "db8500-vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, - { .name = "db8500-vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, - { .name = "db8500-sva-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, - { .name = "db8500-sva-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, - { .name = "db8500-sva-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, - { .name = "db8500-sia-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, - { .name = "db8500-sia-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, - { .name = "db8500-sia-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, - { .name = "db8500-sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, - { .name = "db8500-b2r2-mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, - { .name = "db8500-esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, - { .name = "db8500-esram12-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, - { .name = "db8500-esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, - { .name = "db8500-esram34-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, + { .name = "db8500_vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, + { .name = "db8500_varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, + { .name = "db8500_vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, + { .name = "db8500_vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, + { .name = "db8500_vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, + { .name = "db8500_vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, + { .name = "db8500_vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, + { .name = "db8500_vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, + { .name = "db8500_sva_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, + { .name = "db8500_sva_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, + { .name = "db8500_sva_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, + { .name = "db8500_sia_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, + { .name = "db8500_sia_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, + { .name = "db8500_sia_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, + { .name = "db8500_sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, + { .name = "db8500_b2r2_mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, + { .name = "db8500_esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, + { .name = "db8500_esram12_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, + { .name = "db8500_esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, + { .name = "db8500_esram34_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, }; static __devinit int diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 290d6fc01029..9caadb482178 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -451,7 +451,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, desc = reg_voltage_map[reg_id]; - if (old_sel < new_sel) + if ((old_sel < new_sel) && s5m8767->ramp_delay) return DIV_ROUND_UP(desc->step * (new_sel - old_sel), s5m8767->ramp_delay * 1000); return 0; diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c index 69425c4e86f3..de138e30d3e6 100644 --- a/drivers/remoteproc/omap_remoteproc.c +++ b/drivers/remoteproc/omap_remoteproc.c @@ -182,7 +182,7 @@ static int __devinit omap_rproc_probe(struct platform_device *pdev) ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (ret) { - dev_err(pdev->dev.parent, "dma_set_coherent_mask: %d\n", ret); + dev_err(&pdev->dev, "dma_set_coherent_mask: %d\n", ret); return ret; } diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 8ea7bccc7100..66324ee4678f 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -247,7 +247,7 @@ rproc_load_segments(struct rproc *rproc, const u8 *elf_data, size_t len) } if (offset + filesz > len) { - dev_err(dev, "truncated fw: need 0x%x avail 0x%x\n", + dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n", offset + filesz, len); ret = -EINVAL; break; @@ -934,7 +934,7 @@ static void rproc_resource_cleanup(struct rproc *rproc) unmapped = iommu_unmap(rproc->domain, entry->da, entry->len); if (unmapped != entry->len) { /* nothing much to do besides complaining */ - dev_err(dev, "failed to unmap %u/%u\n", entry->len, + dev_err(dev, "failed to unmap %u/%zu\n", entry->len, unmapped); } @@ -1020,7 +1020,7 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) ehdr = (struct elf32_hdr *)fw->data; - dev_info(dev, "Booting fw image %s, size %d\n", name, fw->size); + dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size); /* * if enabling an IOMMU isn't relevant for this rproc, this is @@ -1041,8 +1041,10 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) /* look for the resource table */ table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz); - if (!table) + if (!table) { + ret = -EINVAL; goto clean_up; + } /* handle fw resources which are required to boot rproc */ ret = rproc_handle_boot_rsc(rproc, table, tablesz); diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 46ef5fe51db5..0c73dd4f43a0 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -801,7 +801,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) mcspi_dma = &mcspi->dma_channels[spi->chip_select]; if (!cs) { - cs = devm_kzalloc(&spi->dev , sizeof *cs, GFP_KERNEL); + cs = kzalloc(sizeof *cs, GFP_KERNEL); if (!cs) return -ENOMEM; cs->base = mcspi->base + spi->chip_select * 0x14; @@ -842,6 +842,7 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) cs = spi->controller_state; list_del(&cs->node); + kfree(cs); } if (spi->chip_select < spi->master->num_chipselect) { diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 1c3d6386ea36..aeac1caba3f9 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -981,6 +982,8 @@ void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver, } EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); +#if IS_ENABLED(CONFIG_USB) + static int comedi_old_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { @@ -1043,3 +1046,5 @@ void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver, comedi_driver_unregister(comedi_driver); } EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister); + +#endif diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c index 292af0f7f451..51665132c61b 100644 --- a/drivers/staging/gdm72xx/netlink_k.c +++ b/drivers/staging/gdm72xx/netlink_k.c @@ -104,7 +104,7 @@ struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type, void netlink_exit(struct sock *sock) { - sock_release(sock->sk_socket); + netlink_kernel_release(sock); } int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt index 0338c7cd0a8b..f03fbd3bb454 100644 --- a/drivers/staging/iio/Documentation/device.txt +++ b/drivers/staging/iio/Documentation/device.txt @@ -29,8 +29,6 @@ Then fill in the following: * info->driver_module: Set to THIS_MODULE. Used to ensure correct ownership of various resources allocate by the core. - * info->num_interrupt_lines: - Number of event triggering hardware lines the device has. * info->event_attrs: Attributes used to enable / disable hardware events. * info->attrs: diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 2490dd25093b..8f1b3af02f29 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -13,6 +13,7 @@ config AD7291 config AD7298 tristate "Analog Devices AD7298 ADC driver" depends on SPI + select IIO_KFIFO_BUF if IIO_BUFFER help Say yes here to build support for Analog Devices AD7298 8 Channel ADC with temperature sensor. diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index 10ab6dc823b9..a13afff2dfe6 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -235,7 +235,8 @@ static const struct attribute_group ad7606_attribute_group_range = { .indexed = 1, \ .channel = num, \ .address = num, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .scan_index = num, \ .scan_type = IIO_ST('s', 16, 16, 0), \ } diff --git a/drivers/staging/omapdrm/omap_fbdev.c b/drivers/staging/omapdrm/omap_fbdev.c index 11acd4c35ed2..8c6ed3b0c6f6 100644 --- a/drivers/staging/omapdrm/omap_fbdev.c +++ b/drivers/staging/omapdrm/omap_fbdev.c @@ -208,7 +208,8 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, */ ret = omap_gem_get_paddr(fbdev->bo, &paddr, true); if (ret) { - dev_err(dev->dev, "could not map (paddr)!\n"); + dev_err(dev->dev, + "could not map (paddr)! Skipping framebuffer alloc\n"); ret = -ENOMEM; goto fail; } @@ -388,8 +389,11 @@ void omap_fbdev_free(struct drm_device *dev) fbi = helper->fbdev; - unregister_framebuffer(fbi); - framebuffer_release(fbi); + /* only cleanup framebuffer if it is present */ + if (fbi) { + unregister_framebuffer(fbi); + framebuffer_release(fbi); + } drm_fb_helper_fini(helper); diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index 9bd18e2d0513..69f616c6964e 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -102,6 +102,8 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = { /* - */ {USB_DEVICE(0x20F4, 0x646B)}, {USB_DEVICE(0x083A, 0xC512)}, + {USB_DEVICE(0x25D4, 0x4CA1)}, + {USB_DEVICE(0x25D4, 0x4CAB)}, /* RTL8191SU */ /* Realtek */ diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 47d061b9ad4d..6e1958a325bd 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c @@ -3113,7 +3113,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * /** * serial8250_register_8250_port - register a serial port - * @port: serial port template + * @up: serial port template * * Configure the serial port specified by the request. If the * port exists and is in use, it is hung up and unregistered diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 4ad721fb8405..c17923ec6e95 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -133,6 +133,10 @@ struct pl011_dmatx_data { struct uart_amba_port { struct uart_port port; struct clk *clk; + /* Two optional pin states - default & sleep */ + struct pinctrl *pinctrl; + struct pinctrl_state *pins_default; + struct pinctrl_state *pins_sleep; const struct vendor_data *vendor; unsigned int dmacr; /* dma control reg */ unsigned int im; /* interrupt mask */ @@ -1312,6 +1316,14 @@ static int pl011_startup(struct uart_port *port) unsigned int cr; int retval; + /* Optionaly enable pins to be muxed in and configured */ + if (!IS_ERR(uap->pins_default)) { + retval = pinctrl_select_state(uap->pinctrl, uap->pins_default); + if (retval) + dev_err(port->dev, + "could not set default pins\n"); + } + retval = clk_prepare(uap->clk); if (retval) goto out; @@ -1420,6 +1432,7 @@ static void pl011_shutdown(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int cr; + int retval; /* * disable all interrupts @@ -1462,6 +1475,14 @@ static void pl011_shutdown(struct uart_port *port) */ clk_disable(uap->clk); clk_unprepare(uap->clk); + /* Optionally let pins go into sleep states */ + if (!IS_ERR(uap->pins_sleep)) { + retval = pinctrl_select_state(uap->pinctrl, uap->pins_sleep); + if (retval) + dev_err(port->dev, + "could not set pins to sleep state\n"); + } + if (uap->port.dev->platform_data) { struct amba_pl011_data *plat; @@ -1792,6 +1813,14 @@ static int __init pl011_console_setup(struct console *co, char *options) if (!uap) return -ENODEV; + /* Allow pins to be muxed in and configured */ + if (!IS_ERR(uap->pins_default)) { + ret = pinctrl_select_state(uap->pinctrl, uap->pins_default); + if (ret) + dev_err(uap->port.dev, + "could not set default pins\n"); + } + ret = clk_prepare(uap->clk); if (ret) return ret; @@ -1844,7 +1873,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) { struct uart_amba_port *uap; struct vendor_data *vendor = id->data; - struct pinctrl *pinctrl; void __iomem *base; int i, ret; @@ -1869,11 +1897,20 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) goto free; } - pinctrl = devm_pinctrl_get_select_default(&dev->dev); - if (IS_ERR(pinctrl)) { - ret = PTR_ERR(pinctrl); + uap->pinctrl = devm_pinctrl_get(&dev->dev); + if (IS_ERR(uap->pinctrl)) { + ret = PTR_ERR(uap->pinctrl); goto unmap; } + uap->pins_default = pinctrl_lookup_state(uap->pinctrl, + PINCTRL_STATE_DEFAULT); + if (IS_ERR(uap->pins_default)) + dev_err(&dev->dev, "could not get default pinstate\n"); + + uap->pins_sleep = pinctrl_lookup_state(uap->pinctrl, + PINCTRL_STATE_SLEEP); + if (IS_ERR(uap->pins_sleep)) + dev_dbg(&dev->dev, "could not get sleep pinstate\n"); uap->clk = clk_get(&dev->dev, NULL); if (IS_ERR(uap->clk)) { diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index 34bd345da775..6ae2a58d62f2 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -466,7 +466,7 @@ static void serial_txx9_break_ctl(struct uart_port *port, int break_state) spin_unlock_irqrestore(&up->port.lock, flags); } -#if defined(CONFIG_SERIAL_TXX9_CONSOLE) || (CONFIG_CONSOLE_POLL) +#if defined(CONFIG_SERIAL_TXX9_CONSOLE) || defined(CONFIG_CONSOLE_POLL) /* * Wait for transmitter & holding register to empty */ diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index afcd13676542..e4841c36798b 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -4,7 +4,7 @@ * Watchdog driver for ARM SP805 watchdog module * * Copyright (C) 2010 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2 or later. This program is licensed "as is" without any @@ -331,6 +331,6 @@ static struct amba_driver sp805_wdt_driver = { module_amba_driver(sp805_wdt_driver); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ARM SP805 Watchdog Driver"); MODULE_LICENSE("GPL"); diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 8f7d1237b7a0..7301cdb4b2cb 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -179,61 +179,74 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id, static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, struct ulist *parents, int level, - struct btrfs_key *key, u64 time_seq, + struct btrfs_key *key_for_search, u64 time_seq, u64 wanted_disk_byte, const u64 *extent_item_pos) { - int ret; - int slot = path->slots[level]; - struct extent_buffer *eb = path->nodes[level]; + int ret = 0; + int slot; + struct extent_buffer *eb; + struct btrfs_key key; struct btrfs_file_extent_item *fi; struct extent_inode_elem *eie = NULL; u64 disk_byte; - u64 wanted_objectid = key->objectid; -add_parent: - if (level == 0 && extent_item_pos) { - fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); - ret = check_extent_in_eb(key, eb, fi, *extent_item_pos, &eie); + if (level != 0) { + eb = path->nodes[level]; + ret = ulist_add(parents, eb->start, 0, GFP_NOFS); if (ret < 0) return ret; - } - ret = ulist_add(parents, eb->start, (unsigned long)eie, GFP_NOFS); - if (ret < 0) - return ret; - - if (level != 0) return 0; + } /* - * if the current leaf is full with EXTENT_DATA items, we must - * check the next one if that holds a reference as well. - * ref->count cannot be used to skip this check. - * repeat this until we don't find any additional EXTENT_DATA items. + * We normally enter this function with the path already pointing to + * the first item to check. But sometimes, we may enter it with + * slot==nritems. In that case, go to the next leaf before we continue. */ - while (1) { - eie = NULL; + if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) ret = btrfs_next_old_leaf(root, path, time_seq); - if (ret < 0) - return ret; - if (ret) - return 0; + while (!ret) { eb = path->nodes[0]; - for (slot = 0; slot < btrfs_header_nritems(eb); ++slot) { - btrfs_item_key_to_cpu(eb, key, slot); - if (key->objectid != wanted_objectid || - key->type != BTRFS_EXTENT_DATA_KEY) - return 0; - fi = btrfs_item_ptr(eb, slot, - struct btrfs_file_extent_item); - disk_byte = btrfs_file_extent_disk_bytenr(eb, fi); - if (disk_byte == wanted_disk_byte) - goto add_parent; + slot = path->slots[0]; + + btrfs_item_key_to_cpu(eb, &key, slot); + + if (key.objectid != key_for_search->objectid || + key.type != BTRFS_EXTENT_DATA_KEY) + break; + + fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); + disk_byte = btrfs_file_extent_disk_bytenr(eb, fi); + + if (disk_byte == wanted_disk_byte) { + eie = NULL; + if (extent_item_pos) { + ret = check_extent_in_eb(&key, eb, fi, + *extent_item_pos, + &eie); + if (ret < 0) + break; + } + if (!ret) { + ret = ulist_add(parents, eb->start, + (unsigned long)eie, GFP_NOFS); + if (ret < 0) + break; + if (!extent_item_pos) { + ret = btrfs_next_old_leaf(root, path, + time_seq); + continue; + } + } } + ret = btrfs_next_old_item(root, path, time_seq); } - return 0; + if (ret > 0) + ret = 0; + return ret; } /* @@ -250,7 +263,6 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, struct btrfs_path *path; struct btrfs_root *root; struct btrfs_key root_key; - struct btrfs_key key = {0}; struct extent_buffer *eb; int ret = 0; int root_level; @@ -295,11 +307,9 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, goto out; } - if (level == 0) - btrfs_item_key_to_cpu(eb, &key, path->slots[0]); - - ret = add_all_parents(root, path, parents, level, &key, time_seq, - ref->wanted_disk_byte, extent_item_pos); + ret = add_all_parents(root, path, parents, level, &ref->key_for_search, + time_seq, ref->wanted_disk_byte, + extent_item_pos); out: btrfs_free_path(path); return ret; diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 8b73b2d4deb7..fa5c45b39075 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2755,13 +2755,18 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path, u64 time_seq); -static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) +static inline int btrfs_next_old_item(struct btrfs_root *root, + struct btrfs_path *p, u64 time_seq) { ++p->slots[0]; if (p->slots[0] >= btrfs_header_nritems(p->nodes[0])) - return btrfs_next_leaf(root, p); + return btrfs_next_old_leaf(root, p, time_seq); return 0; } +static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) +{ + return btrfs_next_old_item(root, p, 0); +} int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); int __must_check btrfs_drop_snapshot(struct btrfs_root *root, diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index e1890b1d3075..7b845ff4af99 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -3426,6 +3426,7 @@ int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, mutex_unlock(&head->mutex); btrfs_put_delayed_ref(ref); + spin_lock(&delayed_refs->lock); continue; } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a4f02501da40..d8bb0dbc4941 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -987,7 +987,7 @@ static noinline void async_cow_start(struct btrfs_work *work) async_cow->start, async_cow->end, async_cow, &num_added); if (num_added == 0) { - iput(async_cow->inode); + btrfs_add_delayed_iput(async_cow->inode); async_cow->inode = NULL; } } @@ -1023,7 +1023,7 @@ static noinline void async_cow_free(struct btrfs_work *work) struct async_cow *async_cow; async_cow = container_of(work, struct async_cow, work); if (async_cow->inode) - iput(async_cow->inode); + btrfs_add_delayed_iput(async_cow->inode); kfree(async_cow); } diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 173b1d22e59b..8b67304e4b80 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -54,7 +54,12 @@ (CONGESTION_ON_THRESH(congestion_kb) - \ (CONGESTION_ON_THRESH(congestion_kb) >> 2)) - +static inline struct ceph_snap_context *page_snap_context(struct page *page) +{ + if (PagePrivate(page)) + return (void *)page->private; + return NULL; +} /* * Dirty a page. Optimistically adjust accounting, on the assumption @@ -142,10 +147,9 @@ static void ceph_invalidatepage(struct page *page, unsigned long offset) { struct inode *inode; struct ceph_inode_info *ci; - struct ceph_snap_context *snapc = (void *)page->private; + struct ceph_snap_context *snapc = page_snap_context(page); BUG_ON(!PageLocked(page)); - BUG_ON(!page->private); BUG_ON(!PagePrivate(page)); BUG_ON(!page->mapping); @@ -182,7 +186,6 @@ static int ceph_releasepage(struct page *page, gfp_t g) struct inode *inode = page->mapping ? page->mapping->host : NULL; dout("%p releasepage %p idx %lu\n", inode, page, page->index); WARN_ON(PageDirty(page)); - WARN_ON(page->private); WARN_ON(PagePrivate(page)); return 0; } @@ -443,7 +446,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) osdc = &fsc->client->osdc; /* verify this is a writeable snap context */ - snapc = (void *)page->private; + snapc = page_snap_context(page); if (snapc == NULL) { dout("writepage %p page %p not dirty?\n", inode, page); goto out; @@ -451,7 +454,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) oldest = get_oldest_context(inode, &snap_size); if (snapc->seq > oldest->seq) { dout("writepage %p page %p snapc %p not writeable - noop\n", - inode, page, (void *)page->private); + inode, page, snapc); /* we should only noop if called by kswapd */ WARN_ON((current->flags & PF_MEMALLOC) == 0); ceph_put_snap_context(oldest); @@ -591,7 +594,7 @@ static void writepages_finish(struct ceph_osd_request *req, clear_bdi_congested(&fsc->backing_dev_info, BLK_RW_ASYNC); - ceph_put_snap_context((void *)page->private); + ceph_put_snap_context(page_snap_context(page)); page->private = 0; ClearPagePrivate(page); dout("unlocking %d %p\n", i, page); @@ -795,7 +798,7 @@ static int ceph_writepages_start(struct address_space *mapping, } /* only if matching snap context */ - pgsnapc = (void *)page->private; + pgsnapc = page_snap_context(page); if (pgsnapc->seq > snapc->seq) { dout("page snapc %p %lld > oldest %p %lld\n", pgsnapc, pgsnapc->seq, snapc, snapc->seq); @@ -984,7 +987,7 @@ static int ceph_update_writeable_page(struct file *file, BUG_ON(!ci->i_snap_realm); down_read(&mdsc->snap_rwsem); BUG_ON(!ci->i_snap_realm->cached_context); - snapc = (void *)page->private; + snapc = page_snap_context(page); if (snapc && snapc != ci->i_head_snapc) { /* * this page is already dirty in another (older) snap diff --git a/fs/exec.c b/fs/exec.c index a79786a8d2c8..da27b91ff1e8 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -819,10 +819,10 @@ static int exec_mmap(struct mm_struct *mm) /* Notify parent that we're no longer interested in the old VM */ tsk = current; old_mm = current->mm; - sync_mm_rss(old_mm); mm_release(tsk, old_mm); if (old_mm) { + sync_mm_rss(old_mm); /* * Make sure that if there is a core dump in progress * for the old mm, we get out and die instead of going diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index c640ba57074b..09addc8615fa 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c @@ -31,6 +31,7 @@ static int hfsplus_ioctl_bless(struct file *file, int __user *user_flags) struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); struct hfsplus_vh *vh = sbi->s_vhdr; struct hfsplus_vh *bvh = sbi->s_backup_vhdr; + u32 cnid = (unsigned long)dentry->d_fsdata; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -41,8 +42,12 @@ static int hfsplus_ioctl_bless(struct file *file, int __user *user_flags) vh->finder_info[0] = bvh->finder_info[0] = cpu_to_be32(parent_ino(dentry)); - /* Bootloader */ - vh->finder_info[1] = bvh->finder_info[1] = cpu_to_be32(inode->i_ino); + /* + * Bootloader. Just using the inode here breaks in the case of + * hard links - the firmware wants the ID of the hard link file, + * but the inode points at the indirect inode + */ + vh->finder_info[1] = bvh->finder_info[1] = cpu_to_be32(cnid); /* Per spec, the OS X system folder - same as finder_info[0] here */ vh->finder_info[5] = bvh->finder_info[5] = diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index 7daf4b852d1c..90effcccca9a 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c @@ -56,7 +56,7 @@ int hfsplus_submit_bio(struct super_block *sb, sector_t sector, DECLARE_COMPLETION_ONSTACK(wait); struct bio *bio; int ret = 0; - unsigned int io_size; + u64 io_size; loff_t start; int offset; diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 17ba6b995659..f005b5bebdc7 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -207,7 +207,6 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_ static void nfs4_shutdown_session(struct nfs_client *clp) { if (nfs4_has_session(clp)) { - nfs4_deviceid_purge_client(clp); nfs4_destroy_session(clp->cl_session); nfs4_destroy_clientid(clp); } diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 3168f6e3d4d4..9a4cbfc85d81 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -490,6 +490,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) dreq->error = -EIO; spin_unlock(cinfo.lock); } + nfs_release_request(req); } nfs_pageio_complete(&desc); diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index b5b86a05059c..864c51e4b400 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c @@ -57,6 +57,11 @@ unsigned int nfs_idmap_cache_timeout = 600; static const struct cred *id_resolver_cache; static struct key_type key_type_id_resolver_legacy; +struct idmap { + struct rpc_pipe *idmap_pipe; + struct key_construction *idmap_key_cons; + struct mutex idmap_mutex; +}; /** * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields @@ -310,9 +315,11 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen, name, namelen, type, data, data_size, NULL); if (ret < 0) { + mutex_lock(&idmap->idmap_mutex); ret = nfs_idmap_request_key(&key_type_id_resolver_legacy, name, namelen, type, data, data_size, idmap); + mutex_unlock(&idmap->idmap_mutex); } return ret; } @@ -354,11 +361,6 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *typ /* idmap classic begins here */ module_param(nfs_idmap_cache_timeout, int, 0644); -struct idmap { - struct rpc_pipe *idmap_pipe; - struct key_construction *idmap_key_cons; -}; - enum { Opt_find_uid, Opt_find_gid, Opt_find_user, Opt_find_group, Opt_find_err }; @@ -469,6 +471,7 @@ nfs_idmap_new(struct nfs_client *clp) return error; } idmap->idmap_pipe = pipe; + mutex_init(&idmap->idmap_mutex); clp->cl_idmap = idmap; return 0; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index e605d695dbcb..f7296983eba6 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1530,7 +1530,6 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi) nfsi->delegation_state = 0; init_rwsem(&nfsi->rwsem); nfsi->layout = NULL; - atomic_set(&nfsi->commit_info.rpcs_out, 0); #endif } @@ -1545,6 +1544,7 @@ static void init_once(void *foo) INIT_LIST_HEAD(&nfsi->commit_info.list); nfsi->npages = 0; nfsi->commit_info.ncommit = 0; + atomic_set(&nfsi->commit_info.rpcs_out, 0); atomic_set(&nfsi->silly_count, 1); INIT_HLIST_HEAD(&nfsi->silly_list); init_waitqueue_head(&nfsi->waitqueue); diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index b8323aa7b543..bbc49caa7a82 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -70,6 +70,10 @@ find_pnfs_driver(u32 id) spin_lock(&pnfs_spinlock); local = find_pnfs_driver_locked(id); + if (local != NULL && !try_module_get(local->owner)) { + dprintk("%s: Could not grab reference on module\n", __func__); + local = NULL; + } spin_unlock(&pnfs_spinlock); return local; } @@ -80,6 +84,9 @@ unset_pnfs_layoutdriver(struct nfs_server *nfss) if (nfss->pnfs_curr_ld) { if (nfss->pnfs_curr_ld->clear_layoutdriver) nfss->pnfs_curr_ld->clear_layoutdriver(nfss); + /* Decrement the MDS count. Purge the deviceid cache if zero */ + if (atomic_dec_and_test(&nfss->nfs_client->cl_mds_count)) + nfs4_deviceid_purge_client(nfss->nfs_client); module_put(nfss->pnfs_curr_ld->owner); } nfss->pnfs_curr_ld = NULL; @@ -115,10 +122,6 @@ set_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh, goto out_no_driver; } } - if (!try_module_get(ld_type->owner)) { - dprintk("%s: Could not grab reference on module\n", __func__); - goto out_no_driver; - } server->pnfs_curr_ld = ld_type; if (ld_type->set_layoutdriver && ld_type->set_layoutdriver(server, mntfh)) { @@ -127,6 +130,8 @@ set_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh, module_put(ld_type->owner); goto out_no_driver; } + /* Bump the MDS count */ + atomic_inc(&server->nfs_client->cl_mds_count); dprintk("%s: pNFS module for %u set\n", __func__, id); return; diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c index 08a07a218d26..57ceaf33d177 100644 --- a/fs/nilfs2/gcinode.c +++ b/fs/nilfs2/gcinode.c @@ -191,6 +191,8 @@ void nilfs_remove_all_gcinodes(struct the_nilfs *nilfs) while (!list_empty(head)) { ii = list_first_entry(head, struct nilfs_inode_info, i_dirty); list_del_init(&ii->i_dirty); + truncate_inode_pages(&ii->vfs_inode.i_data, 0); + nilfs_btnode_cache_clear(&ii->i_btnode_cache); iput(&ii->vfs_inode); } } diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 0e72ad6f22aa..88e11fb346b6 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -2309,6 +2309,8 @@ nilfs_remove_written_gcinodes(struct the_nilfs *nilfs, struct list_head *head) if (!test_bit(NILFS_I_UPDATED, &ii->i_state)) continue; list_del_init(&ii->i_dirty); + truncate_inode_pages(&ii->vfs_inode.i_data, 0); + nilfs_btnode_cache_clear(&ii->i_btnode_cache); iput(&ii->vfs_inode); } } diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index aeb19e68e086..11a2aa2a56c4 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c @@ -258,7 +258,7 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, return rc; } -int pstore_fill_super(struct super_block *sb, void *data, int silent) +static int pstore_fill_super(struct super_block *sb, void *data, int silent) { struct inode *inode; diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 82c585f715e3..03ce7a9b81cc 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -94,20 +94,15 @@ static const char *get_reason_str(enum kmsg_dump_reason reason) * as we can from the end of the buffer. */ static void pstore_dump(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason, - const char *s1, unsigned long l1, - const char *s2, unsigned long l2) + enum kmsg_dump_reason reason) { - unsigned long s1_start, s2_start; - unsigned long l1_cpy, l2_cpy; - unsigned long size, total = 0; - char *dst; + unsigned long total = 0; const char *why; u64 id; - int hsize, ret; unsigned int part = 1; unsigned long flags = 0; int is_locked = 0; + int ret; why = get_reason_str(reason); @@ -119,30 +114,25 @@ static void pstore_dump(struct kmsg_dumper *dumper, spin_lock_irqsave(&psinfo->buf_lock, flags); oopscount++; while (total < kmsg_bytes) { + char *dst; + unsigned long size; + int hsize; + size_t len; + dst = psinfo->buf; hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, part); size = psinfo->bufsize - hsize; dst += hsize; - l2_cpy = min(l2, size); - l1_cpy = min(l1, size - l2_cpy); - - if (l1_cpy + l2_cpy == 0) + if (!kmsg_dump_get_buffer(dumper, true, dst, size, &len)) break; - s2_start = l2 - l2_cpy; - s1_start = l1 - l1_cpy; - - memcpy(dst, s1 + s1_start, l1_cpy); - memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy); - ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part, - hsize + l1_cpy + l2_cpy, psinfo); + hsize + len, psinfo); if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted()) pstore_new_entry = 1; - l1 -= l1_cpy; - l2 -= l2_cpy; - total += l1_cpy + l2_cpy; + + total += hsize + len; part++; } if (in_nmi()) { diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 9123cce28c1e..453030f9c5bc 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -106,6 +106,8 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, time->tv_sec = 0; time->tv_nsec = 0; + /* Update old/shadowed buffer. */ + persistent_ram_save_old(prz); size = persistent_ram_old_size(prz); *buf = kmalloc(size, GFP_KERNEL); if (*buf == NULL) @@ -184,6 +186,7 @@ static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, return -EINVAL; persistent_ram_free_old(cxt->przs[id]); + persistent_ram_zap(cxt->przs[id]); return 0; } diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 31f8d184f3a0..c5fbdbbf81ac 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -250,23 +250,24 @@ static void notrace persistent_ram_update(struct persistent_ram_zone *prz, persistent_ram_update_ecc(prz, start, count); } -static void __init -persistent_ram_save_old(struct persistent_ram_zone *prz) +void persistent_ram_save_old(struct persistent_ram_zone *prz) { struct persistent_ram_buffer *buffer = prz->buffer; size_t size = buffer_size(prz); size_t start = buffer_start(prz); - char *dest; - persistent_ram_ecc_old(prz); + if (!size) + return; - dest = kmalloc(size, GFP_KERNEL); - if (dest == NULL) { + if (!prz->old_log) { + persistent_ram_ecc_old(prz); + prz->old_log = kmalloc(size, GFP_KERNEL); + } + if (!prz->old_log) { pr_err("persistent_ram: failed to allocate buffer\n"); return; } - prz->old_log = dest; prz->old_log_size = size; memcpy(prz->old_log, &buffer->data[start], size - start); memcpy(prz->old_log + size - start, &buffer->data[0], start); @@ -319,6 +320,13 @@ void persistent_ram_free_old(struct persistent_ram_zone *prz) prz->old_log_size = 0; } +void persistent_ram_zap(struct persistent_ram_zone *prz) +{ + atomic_set(&prz->buffer->start, 0); + atomic_set(&prz->buffer->size, 0); + persistent_ram_update_header_ecc(prz); +} + static void *persistent_ram_vmap(phys_addr_t start, size_t size) { struct page **pages; @@ -405,6 +413,7 @@ static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool " size %zu, start %zu\n", buffer_size(prz), buffer_start(prz)); persistent_ram_save_old(prz); + return 0; } } else { pr_info("persistent_ram: no valid data in buffer" @@ -412,8 +421,7 @@ static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool } prz->buffer->sig = PERSISTENT_RAM_SIG; - atomic_set(&prz->buffer->start, 0); - atomic_set(&prz->buffer->size, 0); + persistent_ram_zap(prz); return 0; } @@ -448,7 +456,6 @@ struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start, goto err; persistent_ram_post_init(prz, ecc); - persistent_ram_update_header_ecc(prz); return prz; err: diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 229641fb8e67..9d1aeb7e2734 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -1080,6 +1080,7 @@ xfs_alloc_ag_vextent_near( goto restart; } + xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); trace_xfs_alloc_size_neither(args); args->agbno = NULLAGBLOCK; return 0; @@ -2441,7 +2442,7 @@ xfs_alloc_vextent( DECLARE_COMPLETION_ONSTACK(done); args->done = &done; - INIT_WORK(&args->work, xfs_alloc_vextent_worker); + INIT_WORK_ONSTACK(&args->work, xfs_alloc_vextent_worker); queue_work(xfs_alloc_wq, &args->work); wait_for_completion(&done); return args->result; diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index ae31c313a79e..8dad722c0041 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -981,10 +981,15 @@ xfs_vm_writepage( imap_valid = 0; } } else { - if (PageUptodate(page)) { + if (PageUptodate(page)) ASSERT(buffer_mapped(bh)); - imap_valid = 0; - } + /* + * This buffer is not uptodate and will not be + * written to disk. Ensure that we will put any + * subsequent writeable buffers into a new + * ioend. + */ + imap_valid = 0; continue; } diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 172d3cc8f8cb..a4beb421018a 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -201,14 +201,7 @@ xfs_buf_alloc( bp->b_length = numblks; bp->b_io_length = numblks; bp->b_flags = flags; - - /* - * We do not set the block number here in the buffer because we have not - * finished initialising the buffer. We insert the buffer into the cache - * in this state, so this ensures that we are unable to do IO on a - * buffer that hasn't been fully initialised. - */ - bp->b_bn = XFS_BUF_DADDR_NULL; + bp->b_bn = blkno; atomic_set(&bp->b_pin_count, 0); init_waitqueue_head(&bp->b_waiters); @@ -567,11 +560,6 @@ xfs_buf_get( if (bp != new_bp) xfs_buf_free(new_bp); - /* - * Now we have a workable buffer, fill in the block number so - * that we can do IO on it. - */ - bp->b_bn = blkno; bp->b_io_length = bp->b_length; found: @@ -772,7 +760,7 @@ xfs_buf_get_uncached( int error, i; xfs_buf_t *bp; - bp = xfs_buf_alloc(target, 0, numblks, 0); + bp = xfs_buf_alloc(target, XFS_BUF_DADDR_NULL, numblks, 0); if (unlikely(bp == NULL)) goto fail; diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 6cdbf90c6f7b..d041d47d9d86 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -504,6 +504,14 @@ xfs_inode_item_push( goto out_unlock; } + /* + * Stale inode items should force out the iclog. + */ + if (ip->i_flags & XFS_ISTALE) { + rval = XFS_ITEM_PINNED; + goto out_unlock; + } + /* * Someone else is already flushing the inode. Nothing we can do * here but wait for the flush to finish and remove the item from @@ -514,15 +522,6 @@ xfs_inode_item_push( goto out_unlock; } - /* - * Stale inode items should force out the iclog. - */ - if (ip->i_flags & XFS_ISTALE) { - xfs_ifunlock(ip); - xfs_iunlock(ip, XFS_ILOCK_SHARED); - return XFS_ITEM_PINNED; - } - ASSERT(iip->ili_fields != 0 || XFS_FORCED_SHUTDOWN(ip->i_mount)); ASSERT(iip->ili_logged == 0 || XFS_FORCED_SHUTDOWN(ip->i_mount)); diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index f30d9807dc48..d90d4a388609 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -38,13 +38,21 @@ kmem_zone_t *xfs_log_ticket_zone; /* Local miscellaneous function prototypes */ -STATIC int xlog_commit_record(struct log *log, struct xlog_ticket *ticket, - xlog_in_core_t **, xfs_lsn_t *); +STATIC int +xlog_commit_record( + struct xlog *log, + struct xlog_ticket *ticket, + struct xlog_in_core **iclog, + xfs_lsn_t *commitlsnp); + STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp, xfs_buftarg_t *log_target, xfs_daddr_t blk_offset, int num_bblks); -STATIC int xlog_space_left(struct log *log, atomic64_t *head); +STATIC int +xlog_space_left( + struct xlog *log, + atomic64_t *head); STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); STATIC void xlog_dealloc_log(xlog_t *log); @@ -64,8 +72,10 @@ STATIC void xlog_state_switch_iclogs(xlog_t *log, int eventual_size); STATIC void xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog); -STATIC void xlog_grant_push_ail(struct log *log, - int need_bytes); +STATIC void +xlog_grant_push_ail( + struct xlog *log, + int need_bytes); STATIC void xlog_regrant_reserve_log_space(xlog_t *log, xlog_ticket_t *ticket); STATIC void xlog_ungrant_log_space(xlog_t *log, @@ -73,7 +83,9 @@ STATIC void xlog_ungrant_log_space(xlog_t *log, #if defined(DEBUG) STATIC void xlog_verify_dest_ptr(xlog_t *log, char *ptr); -STATIC void xlog_verify_grant_tail(struct log *log); +STATIC void +xlog_verify_grant_tail( + struct xlog *log); STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog, int count, boolean_t syncing); STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, @@ -89,9 +101,9 @@ STATIC int xlog_iclogs_empty(xlog_t *log); static void xlog_grant_sub_space( - struct log *log, - atomic64_t *head, - int bytes) + struct xlog *log, + atomic64_t *head, + int bytes) { int64_t head_val = atomic64_read(head); int64_t new, old; @@ -115,9 +127,9 @@ xlog_grant_sub_space( static void xlog_grant_add_space( - struct log *log, - atomic64_t *head, - int bytes) + struct xlog *log, + atomic64_t *head, + int bytes) { int64_t head_val = atomic64_read(head); int64_t new, old; @@ -165,7 +177,7 @@ xlog_grant_head_wake_all( static inline int xlog_ticket_reservation( - struct log *log, + struct xlog *log, struct xlog_grant_head *head, struct xlog_ticket *tic) { @@ -182,7 +194,7 @@ xlog_ticket_reservation( STATIC bool xlog_grant_head_wake( - struct log *log, + struct xlog *log, struct xlog_grant_head *head, int *free_bytes) { @@ -204,7 +216,7 @@ xlog_grant_head_wake( STATIC int xlog_grant_head_wait( - struct log *log, + struct xlog *log, struct xlog_grant_head *head, struct xlog_ticket *tic, int need_bytes) @@ -256,7 +268,7 @@ xlog_grant_head_wait( */ STATIC int xlog_grant_head_check( - struct log *log, + struct xlog *log, struct xlog_grant_head *head, struct xlog_ticket *tic, int *need_bytes) @@ -323,7 +335,7 @@ xfs_log_regrant( struct xfs_mount *mp, struct xlog_ticket *tic) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; int need_bytes; int error = 0; @@ -389,7 +401,7 @@ xfs_log_reserve( bool permanent, uint t_type) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; struct xlog_ticket *tic; int need_bytes; int error = 0; @@ -465,7 +477,7 @@ xfs_log_done( struct xlog_in_core **iclog, uint flags) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; xfs_lsn_t lsn = 0; if (XLOG_FORCED_SHUTDOWN(log) || @@ -810,6 +822,7 @@ xfs_log_unmount_write(xfs_mount_t *mp) void xfs_log_unmount(xfs_mount_t *mp) { + cancel_delayed_work_sync(&mp->m_sync_work); xfs_trans_ail_destroy(mp); xlog_dealloc_log(mp->m_log); } @@ -838,7 +851,7 @@ void xfs_log_space_wake( struct xfs_mount *mp) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; int free_bytes; if (XLOG_FORCED_SHUTDOWN(log)) @@ -916,7 +929,7 @@ xfs_lsn_t xlog_assign_tail_lsn_locked( struct xfs_mount *mp) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; struct xfs_log_item *lip; xfs_lsn_t tail_lsn; @@ -965,7 +978,7 @@ xlog_assign_tail_lsn( */ STATIC int xlog_space_left( - struct log *log, + struct xlog *log, atomic64_t *head) { int free_bytes; @@ -1277,7 +1290,7 @@ xlog_alloc_log(xfs_mount_t *mp, */ STATIC int xlog_commit_record( - struct log *log, + struct xlog *log, struct xlog_ticket *ticket, struct xlog_in_core **iclog, xfs_lsn_t *commitlsnp) @@ -1311,7 +1324,7 @@ xlog_commit_record( */ STATIC void xlog_grant_push_ail( - struct log *log, + struct xlog *log, int need_bytes) { xfs_lsn_t threshold_lsn = 0; @@ -1790,7 +1803,7 @@ xlog_write_start_rec( static xlog_op_header_t * xlog_write_setup_ophdr( - struct log *log, + struct xlog *log, struct xlog_op_header *ophdr, struct xlog_ticket *ticket, uint flags) @@ -1873,7 +1886,7 @@ xlog_write_setup_copy( static int xlog_write_copy_finish( - struct log *log, + struct xlog *log, struct xlog_in_core *iclog, uint flags, int *record_cnt, @@ -1958,7 +1971,7 @@ xlog_write_copy_finish( */ int xlog_write( - struct log *log, + struct xlog *log, struct xfs_log_vec *log_vector, struct xlog_ticket *ticket, xfs_lsn_t *start_lsn, @@ -2821,7 +2834,7 @@ _xfs_log_force( uint flags, int *log_flushed) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; struct xlog_in_core *iclog; xfs_lsn_t lsn; @@ -2969,7 +2982,7 @@ _xfs_log_force_lsn( uint flags, int *log_flushed) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; struct xlog_in_core *iclog; int already_slept = 0; @@ -3147,7 +3160,7 @@ xfs_log_ticket_get( */ xlog_ticket_t * xlog_ticket_alloc( - struct log *log, + struct xlog *log, int unit_bytes, int cnt, char client, @@ -3278,7 +3291,7 @@ xlog_ticket_alloc( */ void xlog_verify_dest_ptr( - struct log *log, + struct xlog *log, char *ptr) { int i; @@ -3307,7 +3320,7 @@ xlog_verify_dest_ptr( */ STATIC void xlog_verify_grant_tail( - struct log *log) + struct xlog *log) { int tail_cycle, tail_blocks; int cycle, space; diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 7d6197c58493..ddc4529d07d3 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -44,7 +44,7 @@ */ static struct xlog_ticket * xlog_cil_ticket_alloc( - struct log *log) + struct xlog *log) { struct xlog_ticket *tic; @@ -72,7 +72,7 @@ xlog_cil_ticket_alloc( */ void xlog_cil_init_post_recovery( - struct log *log) + struct xlog *log) { log->l_cilp->xc_ctx->ticket = xlog_cil_ticket_alloc(log); log->l_cilp->xc_ctx->sequence = 1; @@ -182,7 +182,7 @@ xlog_cil_prepare_log_vecs( */ STATIC void xfs_cil_prepare_item( - struct log *log, + struct xlog *log, struct xfs_log_vec *lv, int *len, int *diff_iovecs) @@ -231,7 +231,7 @@ xfs_cil_prepare_item( */ static void xlog_cil_insert_items( - struct log *log, + struct xlog *log, struct xfs_log_vec *log_vector, struct xlog_ticket *ticket) { @@ -373,7 +373,7 @@ xlog_cil_committed( */ STATIC int xlog_cil_push( - struct log *log) + struct xlog *log) { struct xfs_cil *cil = log->l_cilp; struct xfs_log_vec *lv; @@ -601,7 +601,7 @@ xlog_cil_push_work( */ static void xlog_cil_push_background( - struct log *log) + struct xlog *log) { struct xfs_cil *cil = log->l_cilp; @@ -629,7 +629,7 @@ xlog_cil_push_background( static void xlog_cil_push_foreground( - struct log *log, + struct xlog *log, xfs_lsn_t push_seq) { struct xfs_cil *cil = log->l_cilp; @@ -683,7 +683,7 @@ xfs_log_commit_cil( xfs_lsn_t *commit_lsn, int flags) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; int log_flags = 0; struct xfs_log_vec *log_vector; @@ -754,7 +754,7 @@ xfs_log_commit_cil( */ xfs_lsn_t xlog_cil_force_lsn( - struct log *log, + struct xlog *log, xfs_lsn_t sequence) { struct xfs_cil *cil = log->l_cilp; @@ -833,7 +833,7 @@ xfs_log_item_in_current_chkpt( */ int xlog_cil_init( - struct log *log) + struct xlog *log) { struct xfs_cil *cil; struct xfs_cil_ctx *ctx; @@ -869,7 +869,7 @@ xlog_cil_init( void xlog_cil_destroy( - struct log *log) + struct xlog *log) { if (log->l_cilp->xc_ctx) { if (log->l_cilp->xc_ctx->ticket) diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 5bc33261f5be..72eba2201b14 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -19,7 +19,7 @@ #define __XFS_LOG_PRIV_H__ struct xfs_buf; -struct log; +struct xlog; struct xlog_ticket; struct xfs_mount; @@ -352,7 +352,7 @@ typedef struct xlog_in_core { struct xlog_in_core *ic_next; struct xlog_in_core *ic_prev; struct xfs_buf *ic_bp; - struct log *ic_log; + struct xlog *ic_log; int ic_size; int ic_offset; int ic_bwritecnt; @@ -409,7 +409,7 @@ struct xfs_cil_ctx { * operations almost as efficient as the old logging methods. */ struct xfs_cil { - struct log *xc_log; + struct xlog *xc_log; struct list_head xc_cil; spinlock_t xc_cil_lock; struct xfs_cil_ctx *xc_ctx; @@ -487,7 +487,7 @@ struct xlog_grant_head { * overflow 31 bits worth of byte offset, so using a byte number will mean * that round off problems won't occur when releasing partial reservations. */ -typedef struct log { +typedef struct xlog { /* The following fields don't need locking */ struct xfs_mount *l_mp; /* mount point */ struct xfs_ail *l_ailp; /* AIL log is working with */ @@ -553,9 +553,14 @@ extern int xlog_recover_finish(xlog_t *log); extern void xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int); extern kmem_zone_t *xfs_log_ticket_zone; -struct xlog_ticket *xlog_ticket_alloc(struct log *log, int unit_bytes, - int count, char client, bool permanent, - xfs_km_flags_t alloc_flags); +struct xlog_ticket * +xlog_ticket_alloc( + struct xlog *log, + int unit_bytes, + int count, + char client, + bool permanent, + xfs_km_flags_t alloc_flags); static inline void @@ -567,9 +572,14 @@ xlog_write_adv_cnt(void **ptr, int *len, int *off, size_t bytes) } void xlog_print_tic_res(struct xfs_mount *mp, struct xlog_ticket *ticket); -int xlog_write(struct log *log, struct xfs_log_vec *log_vector, - struct xlog_ticket *tic, xfs_lsn_t *start_lsn, - xlog_in_core_t **commit_iclog, uint flags); +int +xlog_write( + struct xlog *log, + struct xfs_log_vec *log_vector, + struct xlog_ticket *tic, + xfs_lsn_t *start_lsn, + struct xlog_in_core **commit_iclog, + uint flags); /* * When we crack an atomic LSN, we sample it first so that the value will not @@ -629,17 +639,23 @@ xlog_assign_grant_head(atomic64_t *head, int cycle, int space) /* * Committed Item List interfaces */ -int xlog_cil_init(struct log *log); -void xlog_cil_init_post_recovery(struct log *log); -void xlog_cil_destroy(struct log *log); +int +xlog_cil_init(struct xlog *log); +void +xlog_cil_init_post_recovery(struct xlog *log); +void +xlog_cil_destroy(struct xlog *log); /* * CIL force routines */ -xfs_lsn_t xlog_cil_force_lsn(struct log *log, xfs_lsn_t sequence); +xfs_lsn_t +xlog_cil_force_lsn( + struct xlog *log, + xfs_lsn_t sequence); static inline void -xlog_cil_force(struct log *log) +xlog_cil_force(struct xlog *log) { xlog_cil_force_lsn(log, log->l_cilp->xc_current_sequence); } diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index ca386909131a..a7be98abd6a9 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1471,8 +1471,8 @@ xlog_recover_add_item( STATIC int xlog_recover_add_to_cont_trans( - struct log *log, - xlog_recover_t *trans, + struct xlog *log, + struct xlog_recover *trans, xfs_caddr_t dp, int len) { @@ -1517,8 +1517,8 @@ xlog_recover_add_to_cont_trans( */ STATIC int xlog_recover_add_to_trans( - struct log *log, - xlog_recover_t *trans, + struct xlog *log, + struct xlog_recover *trans, xfs_caddr_t dp, int len) { @@ -1588,8 +1588,8 @@ xlog_recover_add_to_trans( */ STATIC int xlog_recover_reorder_trans( - struct log *log, - xlog_recover_t *trans, + struct xlog *log, + struct xlog_recover *trans, int pass) { xlog_recover_item_t *item, *n; @@ -1642,8 +1642,8 @@ xlog_recover_reorder_trans( */ STATIC int xlog_recover_buffer_pass1( - struct log *log, - xlog_recover_item_t *item) + struct xlog *log, + struct xlog_recover_item *item) { xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr; struct list_head *bucket; @@ -1696,7 +1696,7 @@ xlog_recover_buffer_pass1( */ STATIC int xlog_check_buffer_cancelled( - struct log *log, + struct xlog *log, xfs_daddr_t blkno, uint len, ushort flags) @@ -2689,9 +2689,9 @@ xlog_recover_free_trans( STATIC int xlog_recover_commit_pass1( - struct log *log, - struct xlog_recover *trans, - xlog_recover_item_t *item) + struct xlog *log, + struct xlog_recover *trans, + struct xlog_recover_item *item) { trace_xfs_log_recover_item_recover(log, trans, item, XLOG_RECOVER_PASS1); @@ -2716,10 +2716,10 @@ xlog_recover_commit_pass1( STATIC int xlog_recover_commit_pass2( - struct log *log, - struct xlog_recover *trans, - struct list_head *buffer_list, - xlog_recover_item_t *item) + struct xlog *log, + struct xlog_recover *trans, + struct list_head *buffer_list, + struct xlog_recover_item *item) { trace_xfs_log_recover_item_recover(log, trans, item, XLOG_RECOVER_PASS2); @@ -2753,7 +2753,7 @@ xlog_recover_commit_pass2( */ STATIC int xlog_recover_commit_trans( - struct log *log, + struct xlog *log, struct xlog_recover *trans, int pass) { @@ -2793,8 +2793,8 @@ xlog_recover_commit_trans( STATIC int xlog_recover_unmount_trans( - struct log *log, - xlog_recover_t *trans) + struct xlog *log, + struct xlog_recover *trans) { /* Do nothing now */ xfs_warn(log->l_mp, "%s: Unmount LR", __func__); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 8b89c5ac72d9..90c1fc9eaea4 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -53,7 +53,7 @@ typedef struct xfs_trans_reservations { #include "xfs_sync.h" -struct log; +struct xlog; struct xfs_mount_args; struct xfs_inode; struct xfs_bmbt_irec; @@ -133,7 +133,7 @@ typedef struct xfs_mount { uint m_readio_blocks; /* min read size blocks */ uint m_writeio_log; /* min write size log bytes */ uint m_writeio_blocks; /* min write size blocks */ - struct log *m_log; /* log specific stuff */ + struct xlog *m_log; /* log specific stuff */ int m_logbufs; /* number of log buffers */ int m_logbsize; /* size of each log buffer */ uint m_rsumlevels; /* rt summary levels */ diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c index c9d3409c5ca3..1e9ee064dbb2 100644 --- a/fs/xfs/xfs_sync.c +++ b/fs/xfs/xfs_sync.c @@ -386,23 +386,23 @@ xfs_sync_worker( * We shouldn't write/force the log if we are in the mount/unmount * process or on a read only filesystem. The workqueue still needs to be * active in both cases, however, because it is used for inode reclaim - * during these times. Use the s_umount semaphore to provide exclusion - * with unmount. + * during these times. Use the MS_ACTIVE flag to avoid doing anything + * during mount. Doing work during unmount is avoided by calling + * cancel_delayed_work_sync on this work queue before tearing down + * the ail and the log in xfs_log_unmount. */ - if (down_read_trylock(&mp->m_super->s_umount)) { - if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { - /* dgc: errors ignored here */ - if (mp->m_super->s_frozen == SB_UNFROZEN && - xfs_log_need_covered(mp)) - error = xfs_fs_log_dummy(mp); - else - xfs_log_force(mp, 0); + if (!(mp->m_super->s_flags & MS_ACTIVE) && + !(mp->m_flags & XFS_MOUNT_RDONLY)) { + /* dgc: errors ignored here */ + if (mp->m_super->s_frozen == SB_UNFROZEN && + xfs_log_need_covered(mp)) + error = xfs_fs_log_dummy(mp); + else + xfs_log_force(mp, 0); - /* start pushing all the metadata that is currently - * dirty */ - xfs_ail_push_all(mp->m_ail); - } - up_read(&mp->m_super->s_umount); + /* start pushing all the metadata that is currently + * dirty */ + xfs_ail_push_all(mp->m_ail); } /* queue us up again */ diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 7cf9d3529e51..caf5dabfd553 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -32,7 +32,7 @@ struct xfs_da_node_entry; struct xfs_dquot; struct xfs_log_item; struct xlog_ticket; -struct log; +struct xlog; struct xlog_recover; struct xlog_recover_item; struct xfs_buf_log_format; @@ -762,7 +762,7 @@ DEFINE_DQUOT_EVENT(xfs_dqflush_force); DEFINE_DQUOT_EVENT(xfs_dqflush_done); DECLARE_EVENT_CLASS(xfs_loggrant_class, - TP_PROTO(struct log *log, struct xlog_ticket *tic), + TP_PROTO(struct xlog *log, struct xlog_ticket *tic), TP_ARGS(log, tic), TP_STRUCT__entry( __field(dev_t, dev) @@ -830,7 +830,7 @@ DECLARE_EVENT_CLASS(xfs_loggrant_class, #define DEFINE_LOGGRANT_EVENT(name) \ DEFINE_EVENT(xfs_loggrant_class, name, \ - TP_PROTO(struct log *log, struct xlog_ticket *tic), \ + TP_PROTO(struct xlog *log, struct xlog_ticket *tic), \ TP_ARGS(log, tic)) DEFINE_LOGGRANT_EVENT(xfs_log_done_nonperm); DEFINE_LOGGRANT_EVENT(xfs_log_done_perm); @@ -1664,7 +1664,7 @@ DEFINE_SWAPEXT_EVENT(xfs_swap_extent_before); DEFINE_SWAPEXT_EVENT(xfs_swap_extent_after); DECLARE_EVENT_CLASS(xfs_log_recover_item_class, - TP_PROTO(struct log *log, struct xlog_recover *trans, + TP_PROTO(struct xlog *log, struct xlog_recover *trans, struct xlog_recover_item *item, int pass), TP_ARGS(log, trans, item, pass), TP_STRUCT__entry( @@ -1698,7 +1698,7 @@ DECLARE_EVENT_CLASS(xfs_log_recover_item_class, #define DEFINE_LOG_RECOVER_ITEM(name) \ DEFINE_EVENT(xfs_log_recover_item_class, name, \ - TP_PROTO(struct log *log, struct xlog_recover *trans, \ + TP_PROTO(struct xlog *log, struct xlog_recover *trans, \ struct xlog_recover_item *item, int pass), \ TP_ARGS(log, trans, item, pass)) @@ -1709,7 +1709,7 @@ DEFINE_LOG_RECOVER_ITEM(xfs_log_recover_item_reorder_tail); DEFINE_LOG_RECOVER_ITEM(xfs_log_recover_item_recover); DECLARE_EVENT_CLASS(xfs_log_recover_buf_item_class, - TP_PROTO(struct log *log, struct xfs_buf_log_format *buf_f), + TP_PROTO(struct xlog *log, struct xfs_buf_log_format *buf_f), TP_ARGS(log, buf_f), TP_STRUCT__entry( __field(dev_t, dev) @@ -1739,7 +1739,7 @@ DECLARE_EVENT_CLASS(xfs_log_recover_buf_item_class, #define DEFINE_LOG_RECOVER_BUF_ITEM(name) \ DEFINE_EVENT(xfs_log_recover_buf_item_class, name, \ - TP_PROTO(struct log *log, struct xfs_buf_log_format *buf_f), \ + TP_PROTO(struct xlog *log, struct xfs_buf_log_format *buf_f), \ TP_ARGS(log, buf_f)) DEFINE_LOG_RECOVER_BUF_ITEM(xfs_log_recover_buf_not_cancel); @@ -1752,7 +1752,7 @@ DEFINE_LOG_RECOVER_BUF_ITEM(xfs_log_recover_buf_reg_buf); DEFINE_LOG_RECOVER_BUF_ITEM(xfs_log_recover_buf_dquot_buf); DECLARE_EVENT_CLASS(xfs_log_recover_ino_item_class, - TP_PROTO(struct log *log, struct xfs_inode_log_format *in_f), + TP_PROTO(struct xlog *log, struct xfs_inode_log_format *in_f), TP_ARGS(log, in_f), TP_STRUCT__entry( __field(dev_t, dev) @@ -1790,7 +1790,7 @@ DECLARE_EVENT_CLASS(xfs_log_recover_ino_item_class, ) #define DEFINE_LOG_RECOVER_INO_ITEM(name) \ DEFINE_EVENT(xfs_log_recover_ino_item_class, name, \ - TP_PROTO(struct log *log, struct xfs_inode_log_format *in_f), \ + TP_PROTO(struct xlog *log, struct xfs_inode_log_format *in_f), \ TP_ARGS(log, in_f)) DEFINE_LOG_RECOVER_INO_ITEM(xfs_log_recover_inode_recover); diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 9f02005f217a..506ec19a3736 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -2,7 +2,6 @@ #define _ASM_GENERIC_BUG_H #include -#include #ifdef CONFIG_BUG @@ -32,6 +31,9 @@ struct bug_entry { #endif /* CONFIG_GENERIC_BUG */ +#ifndef __ASSEMBLY__ +#include + /* * Don't use BUG() or BUG_ON() unless there's really no way out; one * example might be detecting data structure corruption in the middle @@ -61,7 +63,6 @@ struct bug_entry { * to provide better diagnostics. */ #ifndef __WARN_TAINT -#ifndef __ASSEMBLY__ extern __printf(3, 4) void warn_slowpath_fmt(const char *file, const int line, const char *fmt, ...); @@ -70,7 +71,6 @@ void warn_slowpath_fmt_taint(const char *file, const int line, unsigned taint, const char *fmt, ...); extern void warn_slowpath_null(const char *file, const int line); #define WANT_WARN_ON_SLOWPATH -#endif #define __WARN() warn_slowpath_null(__FILE__, __LINE__) #define __WARN_printf(arg...) warn_slowpath_fmt(__FILE__, __LINE__, arg) #define __WARN_printf_taint(taint, arg...) \ @@ -203,4 +203,6 @@ extern void warn_slowpath_null(const char *file, const int line); # define WARN_ON_SMP(x) ({0;}) #endif +#endif /* __ASSEMBLY__ */ + #endif diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 6f2b45a9b6bc..ff4947b7a976 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -484,6 +484,16 @@ static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd) /* * The barrier will stabilize the pmdval in a register or on * the stack so that it will stop changing under the code. + * + * When CONFIG_TRANSPARENT_HUGEPAGE=y on x86 32bit PAE, + * pmd_read_atomic is allowed to return a not atomic pmdval + * (for example pointing to an hugepage that has never been + * mapped in the pmd). The below checks will only care about + * the low part of the pmd with 32bit PAE x86 anyway, with the + * exception of pmd_none(). So the important thing is that if + * the low part of the pmd is found null, the high part will + * be also null or the pmd_none() check below would be + * confused. */ #ifdef CONFIG_TRANSPARENT_HUGEPAGE barrier(); diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 81368ab6c611..a7aec391b7b7 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -1,7 +1,3 @@ -/* - This file is auto-generated from the drm_pciids.txt in the DRM CVS - Please contact dri-devel@lists.sf.net to add new cards to this list -*/ #define radeon_PCI_IDS \ {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ {0x1002, 0x3151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index bab174334da5..8cc70837f929 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -201,6 +201,8 @@ typedef struct _drm_i915_sarea { #define DRM_I915_GET_SPRITE_COLORKEY 0x2a #define DRM_I915_SET_SPRITE_COLORKEY 0x2b #define DRM_I915_GEM_WAIT 0x2c +#define DRM_I915_GEM_CONTEXT_CREATE 0x2d +#define DRM_I915_GEM_CONTEXT_DESTROY 0x2e #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -245,6 +247,8 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey) #define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey) #define DRM_IOCTL_I915_GEM_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait) +#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create) +#define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy) /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -300,6 +304,7 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_HAS_GEN7_SOL_RESET 16 #define I915_PARAM_HAS_LLC 17 #define I915_PARAM_HAS_ALIASING_PPGTT 18 +#define I915_PARAM_HAS_WAIT_TIMEOUT 19 typedef struct drm_i915_getparam { int param; @@ -658,13 +663,19 @@ struct drm_i915_gem_execbuffer2 { #define I915_EXEC_CONSTANTS_ABSOLUTE (1<<6) #define I915_EXEC_CONSTANTS_REL_SURFACE (2<<6) /* gen4/5 only */ __u64 flags; - __u64 rsvd1; + __u64 rsvd1; /* now used for context info */ __u64 rsvd2; }; /** Resets the SO write offset registers for transform feedback on gen7. */ #define I915_EXEC_GEN7_SOL_RESET (1<<8) +#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff) +#define i915_execbuffer2_set_context_id(eb2, context) \ + (eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK +#define i915_execbuffer2_get_context_id(eb2) \ + ((eb2).rsvd1 & I915_EXEC_CONTEXT_ID_MASK) + struct drm_i915_gem_pin { /** Handle of the buffer to be pinned. */ __u32 handle; @@ -893,7 +904,18 @@ struct drm_i915_gem_wait { __u32 bo_handle; __u32 flags; /** Number of nanoseconds to wait, Returns time remaining. */ - __u64 timeout_ns; + __s64 timeout_ns; +}; + +struct drm_i915_gem_context_create { + /* output: id of new context*/ + __u32 ctx_id; + __u32 pad; +}; + +struct drm_i915_gem_context_destroy { + __u32 ctx_id; + __u32 pad; }; #endif /* _I915_DRM_H_ */ diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h index 923afb5dcf0c..8e29d551bb3c 100644 --- a/include/drm/intel-gtt.h +++ b/include/drm/intel-gtt.h @@ -19,8 +19,16 @@ const struct intel_gtt { dma_addr_t scratch_page_dma; /* for ppgtt PDE access */ u32 __iomem *gtt; + /* needed for ioremap in drm/i915 */ + phys_addr_t gma_bus_addr; } *intel_gtt_get(void); +int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, + struct agp_bridge_data *bridge); +void intel_gmch_remove(void); + +bool intel_enable_gtt(void); + void intel_gtt_chipset_flush(void); void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg); void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries); diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index e5834aa24b9e..6a6d7aefe12d 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -47,9 +47,9 @@ */ #if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4) -# define inline inline __attribute__((always_inline)) -# define __inline__ __inline__ __attribute__((always_inline)) -# define __inline __inline __attribute__((always_inline)) +# define inline inline __attribute__((always_inline)) notrace +# define __inline__ __inline__ __attribute__((always_inline)) notrace +# define __inline __inline __attribute__((always_inline)) notrace #else /* A lot of inline functions can cause havoc with function tracing */ # define inline inline notrace diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h index 35f7237ec972..d6bd50110ec2 100644 --- a/include/linux/kmsg_dump.h +++ b/include/linux/kmsg_dump.h @@ -21,6 +21,7 @@ * is passed to the kernel. */ enum kmsg_dump_reason { + KMSG_DUMP_UNDEF, KMSG_DUMP_PANIC, KMSG_DUMP_OOPS, KMSG_DUMP_EMERG, @@ -31,23 +32,37 @@ enum kmsg_dump_reason { /** * struct kmsg_dumper - kernel crash message dumper structure - * @dump: The callback which gets called on crashes. The buffer is passed - * as two sections, where s1 (length l1) contains the older - * messages and s2 (length l2) contains the newer. * @list: Entry in the dumper list (private) + * @dump: Call into dumping code which will retrieve the data with + * through the record iterator + * @max_reason: filter for highest reason number that should be dumped * @registered: Flag that specifies if this is already registered */ struct kmsg_dumper { - void (*dump)(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason, - const char *s1, unsigned long l1, - const char *s2, unsigned long l2); struct list_head list; - int registered; + void (*dump)(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason); + enum kmsg_dump_reason max_reason; + bool active; + bool registered; + + /* private state of the kmsg iterator */ + u32 cur_idx; + u32 next_idx; + u64 cur_seq; + u64 next_seq; }; #ifdef CONFIG_PRINTK void kmsg_dump(enum kmsg_dump_reason reason); +bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, + char *line, size_t size, size_t *len); + +bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, + char *buf, size_t size, size_t *len); + +void kmsg_dump_rewind(struct kmsg_dumper *dumper); + int kmsg_dump_register(struct kmsg_dumper *dumper); int kmsg_dump_unregister(struct kmsg_dumper *dumper); @@ -56,6 +71,22 @@ static inline void kmsg_dump(enum kmsg_dump_reason reason) { } +static inline bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, + const char *line, size_t size, size_t *len) +{ + return false; +} + +static inline bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, + char *buf, size_t size, size_t *len) +{ + return false; +} + +static inline void kmsg_dump_rewind(struct kmsg_dumper *dumper) +{ +} + static inline int kmsg_dump_register(struct kmsg_dumper *dumper) { return -EINVAL; diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index dad95bdd06d7..704a626d94a0 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -57,8 +57,18 @@ struct page { }; union { +#if defined(CONFIG_HAVE_CMPXCHG_DOUBLE) && \ + defined(CONFIG_HAVE_ALIGNED_STRUCT_PAGE) /* Used for cmpxchg_double in slub */ unsigned long counters; +#else + /* + * Keep _count separate from slub cmpxchg_double data. + * As the rest of the double word is protected by + * slab_lock but _count is not. + */ + unsigned counters; +#endif struct { diff --git a/include/linux/mmc/sdhci-spear.h b/include/linux/mmc/sdhci-spear.h index 5cdc96da9dd5..e78c0e236e9d 100644 --- a/include/linux/mmc/sdhci-spear.h +++ b/include/linux/mmc/sdhci-spear.h @@ -4,7 +4,7 @@ * SDHCI declarations specific to ST SPEAr platform * * Copyright (C) 2010 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h index c9fe66c58f8f..17446d3c3602 100644 --- a/include/linux/mmc/sdio.h +++ b/include/linux/mmc/sdio.h @@ -98,7 +98,9 @@ #define SDIO_CCCR_IF 0x07 /* bus interface controls */ +#define SDIO_BUS_WIDTH_MASK 0x03 /* data bus width setting */ #define SDIO_BUS_WIDTH_1BIT 0x00 +#define SDIO_BUS_WIDTH_RESERVED 0x01 #define SDIO_BUS_WIDTH_4BIT 0x02 #define SDIO_BUS_ECSI 0x20 /* Enable continuous SPI interrupt */ #define SDIO_BUS_SCSI 0x40 /* Support continuous SPI interrupt */ diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index fbb78fb09bd2..f58325a1d8fb 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -25,6 +25,7 @@ struct nfs41_impl_id; */ struct nfs_client { atomic_t cl_count; + atomic_t cl_mds_count; int cl_cons_state; /* current construction state (-ve: init error) */ #define NFS_CS_READY 0 /* ready to be used */ #define NFS_CS_INITING 1 /* busy initialising */ diff --git a/include/linux/pata_arasan_cf_data.h b/include/linux/pata_arasan_cf_data.h index a6ee9aa898bb..a7b4fc386e63 100644 --- a/include/linux/pata_arasan_cf_data.h +++ b/include/linux/pata_arasan_cf_data.h @@ -4,7 +4,7 @@ * Arasan Compact Flash host controller platform data header file * * Copyright (C) 2011 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h index 7ed7fd4dba49..3b823d49a85a 100644 --- a/include/linux/pstore_ram.h +++ b/include/linux/pstore_ram.h @@ -69,12 +69,14 @@ struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start, size_t size, bool ecc); void persistent_ram_free(struct persistent_ram_zone *prz); +void persistent_ram_zap(struct persistent_ram_zone *prz); struct persistent_ram_zone *persistent_ram_init_ringbuffer(struct device *dev, bool ecc); int persistent_ram_write(struct persistent_ram_zone *prz, const void *s, unsigned int count); +void persistent_ram_save_old(struct persistent_ram_zone *prz); size_t persistent_ram_old_size(struct persistent_ram_zone *prz); void *persistent_ram_old(struct persistent_ram_zone *prz); void persistent_ram_free_old(struct persistent_ram_zone *prz); diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h index 44835fb39793..f36632061c66 100644 --- a/include/linux/pxa2xx_ssp.h +++ b/include/linux/pxa2xx_ssp.h @@ -160,7 +160,9 @@ enum pxa_ssp_type { PXA25x_SSP, /* pxa 210, 250, 255, 26x */ PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ PXA27x_SSP, + PXA3xx_SSP, PXA168_SSP, + PXA910_SSP, CE4100_SSP, }; diff --git a/include/linux/spi/pxa2xx_spi.h b/include/linux/spi/pxa2xx_spi.h index d3e1075f7b60..c73d1445c77e 100644 --- a/include/linux/spi/pxa2xx_spi.h +++ b/include/linux/spi/pxa2xx_spi.h @@ -43,7 +43,7 @@ struct pxa2xx_spi_chip { void (*cs_control)(u32 command); }; -#ifdef CONFIG_ARCH_PXA +#if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP) #include #include diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h index d844b7790ea6..ddb419cf4530 100644 --- a/include/linux/vga_switcheroo.h +++ b/include/linux/vga_switcheroo.h @@ -7,6 +7,9 @@ * vga_switcheroo.h - Support for laptop with dual GPU using one set of outputs */ +#ifndef _LINUX_VGA_SWITCHEROO_H_ +#define _LINUX_VGA_SWITCHEROO_H_ + #include struct pci_dev; @@ -73,3 +76,4 @@ static inline int vga_switcheroo_get_client_state(struct pci_dev *dev) { return #endif +#endif /* _LINUX_VGA_SWITCHEROO_H_ */ diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 72fcd3069a90..2097684cf194 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -255,12 +255,17 @@ int cgroup_lock_is_held(void) EXPORT_SYMBOL_GPL(cgroup_lock_is_held); +static int css_unbias_refcnt(int refcnt) +{ + return refcnt >= 0 ? refcnt : refcnt - CSS_DEACT_BIAS; +} + /* the current nr of refs, always >= 0 whether @css is deactivated or not */ static int css_refcnt(struct cgroup_subsys_state *css) { int v = atomic_read(&css->refcnt); - return v >= 0 ? v : v - CSS_DEACT_BIAS; + return css_unbias_refcnt(v); } /* convenient tests for these bits */ @@ -4982,10 +4987,12 @@ EXPORT_SYMBOL_GPL(__css_tryget); void __css_put(struct cgroup_subsys_state *css) { struct cgroup *cgrp = css->cgroup; + int v; rcu_read_lock(); - atomic_dec(&css->refcnt); - switch (css_refcnt(css)) { + v = css_unbias_refcnt(atomic_dec_return(&css->refcnt)); + + switch (v) { case 1: if (notify_on_release(cgrp)) { set_bit(CGRP_RELEASABLE, &cgrp->flags); diff --git a/kernel/events/core.c b/kernel/events/core.c index f85c0154b333..d7d71d6ec972 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -253,9 +253,9 @@ perf_cgroup_match(struct perf_event *event) return !event->cgrp || event->cgrp == cpuctx->cgrp; } -static inline void perf_get_cgroup(struct perf_event *event) +static inline bool perf_tryget_cgroup(struct perf_event *event) { - css_get(&event->cgrp->css); + return css_tryget(&event->cgrp->css); } static inline void perf_put_cgroup(struct perf_event *event) @@ -484,7 +484,11 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event, event->cgrp = cgrp; /* must be done before we fput() the file */ - perf_get_cgroup(event); + if (!perf_tryget_cgroup(event)) { + event->cgrp = NULL; + ret = -ENOENT; + goto out; + } /* * all events in a group must monitor diff --git a/kernel/exit.c b/kernel/exit.c index 34867cc5b42a..2f59cc334516 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -72,6 +72,18 @@ static void __unhash_process(struct task_struct *p, bool group_dead) list_del_rcu(&p->tasks); list_del_init(&p->sibling); __this_cpu_dec(process_counts); + /* + * If we are the last child process in a pid namespace to be + * reaped, notify the reaper sleeping zap_pid_ns_processes(). + */ + if (IS_ENABLED(CONFIG_PID_NS)) { + struct task_struct *parent = p->real_parent; + + if ((task_active_pid_ns(parent)->child_reaper == parent) && + list_empty(&parent->children) && + (parent->flags & PF_EXITING)) + wake_up_process(parent); + } } list_del_rcu(&p->thread_group); } @@ -643,6 +655,7 @@ static void exit_mm(struct task_struct * tsk) mm_release(tsk, mm); if (!mm) return; + sync_mm_rss(mm); /* * Serialize with any possible pending coredump. * We must hold mmap_sem around checking core_state @@ -719,12 +732,6 @@ static struct task_struct *find_new_reaper(struct task_struct *father) zap_pid_ns_processes(pid_ns); write_lock_irq(&tasklist_lock); - /* - * We can not clear ->child_reaper or leave it alone. - * There may by stealth EXIT_DEAD tasks on ->children, - * forget_original_parent() must move them somewhere. - */ - pid_ns->child_reaper = init_pid_ns.child_reaper; } else if (father->signal->has_child_subreaper) { struct task_struct *reaper; diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 16b20e38c4a1..b3c7fd554250 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -184,11 +184,31 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) } read_unlock(&tasklist_lock); + /* Firstly reap the EXIT_ZOMBIE children we may have. */ do { clear_thread_flag(TIF_SIGPENDING); rc = sys_wait4(-1, NULL, __WALL, NULL); } while (rc != -ECHILD); + /* + * sys_wait4() above can't reap the TASK_DEAD children. + * Make sure they all go away, see __unhash_process(). + */ + for (;;) { + bool need_wait = false; + + read_lock(&tasklist_lock); + if (!list_empty(¤t->children)) { + __set_current_state(TASK_UNINTERRUPTIBLE); + need_wait = true; + } + read_unlock(&tasklist_lock); + + if (!need_wait) + break; + schedule(); + } + if (pid_ns->reboot) current->signal->group_exit_code = pid_ns->reboot; diff --git a/kernel/printk.c b/kernel/printk.c index 32462d2b364a..a2276b916769 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -227,10 +227,10 @@ static u32 clear_idx; #define LOG_LINE_MAX 1024 /* record buffer */ -#if !defined(CONFIG_64BIT) || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) #define LOG_ALIGN 4 #else -#define LOG_ALIGN 8 +#define LOG_ALIGN __alignof__(struct log) #endif #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); @@ -414,7 +414,9 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, if (!user) return -EBADF; - mutex_lock(&user->lock); + ret = mutex_lock_interruptible(&user->lock); + if (ret) + return ret; raw_spin_lock(&logbuf_lock); while (user->seq == log_next_seq) { if (file->f_flags & O_NONBLOCK) { @@ -878,7 +880,9 @@ static int syslog_print(char __user *buf, int size) syslog_seq++; raw_spin_unlock_irq(&logbuf_lock); - if (len > 0 && copy_to_user(buf, text, len)) + if (len > size) + len = -EINVAL; + else if (len > 0 && copy_to_user(buf, text, len)) len = -EFAULT; kfree(text); @@ -909,7 +913,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) /* * Find first record that fits, including all following records, * into the user-provided buffer for this dump. - */ + */ seq = clear_seq; idx = clear_idx; while (seq < log_next_seq) { @@ -919,6 +923,8 @@ static int syslog_print_all(char __user *buf, int size, bool clear) idx = log_next(idx); seq++; } + + /* move first record forward until length fits into the buffer */ seq = clear_seq; idx = clear_idx; while (len > size && seq < log_next_seq) { @@ -929,7 +935,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) seq++; } - /* last message in this dump */ + /* last message fitting into this dump */ next_seq = log_next_seq; len = 0; @@ -974,6 +980,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) { bool clear = false; static int saved_console_loglevel = -1; + static DEFINE_MUTEX(syslog_mutex); int error; error = check_syslog_permissions(type, from_file); @@ -1000,11 +1007,17 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) error = -EFAULT; goto out; } - error = wait_event_interruptible(log_wait, - syslog_seq != log_next_seq); + error = mutex_lock_interruptible(&syslog_mutex); if (error) goto out; + error = wait_event_interruptible(log_wait, + syslog_seq != log_next_seq); + if (error) { + mutex_unlock(&syslog_mutex); + goto out; + } error = syslog_print(buf, len); + mutex_unlock(&syslog_mutex); break; /* Read/clear last kernel messages */ case SYSLOG_ACTION_READ_CLEAR: @@ -2300,48 +2313,210 @@ module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | S_IWUSR); * kmsg_dump - dump kernel log to kernel message dumpers. * @reason: the reason (oops, panic etc) for dumping * - * Iterate through each of the dump devices and call the oops/panic - * callbacks with the log buffer. + * Call each of the registered dumper's dump() callback, which can + * retrieve the kmsg records with kmsg_dump_get_line() or + * kmsg_dump_get_buffer(). */ void kmsg_dump(enum kmsg_dump_reason reason) { - u64 idx; struct kmsg_dumper *dumper; - const char *s1, *s2; - unsigned long l1, l2; unsigned long flags; if ((reason > KMSG_DUMP_OOPS) && !always_kmsg_dump) return; - /* Theoretically, the log could move on after we do this, but - there's not a lot we can do about that. The new messages - will overwrite the start of what we dump. */ - - raw_spin_lock_irqsave(&logbuf_lock, flags); - if (syslog_seq < log_first_seq) - idx = syslog_idx; - else - idx = log_first_idx; - - if (idx > log_next_idx) { - s1 = log_buf; - l1 = log_next_idx; - - s2 = log_buf + idx; - l2 = log_buf_len - idx; - } else { - s1 = ""; - l1 = 0; - - s2 = log_buf + idx; - l2 = log_next_idx - idx; - } - raw_spin_unlock_irqrestore(&logbuf_lock, flags); - rcu_read_lock(); - list_for_each_entry_rcu(dumper, &dump_list, list) - dumper->dump(dumper, reason, s1, l1, s2, l2); + list_for_each_entry_rcu(dumper, &dump_list, list) { + if (dumper->max_reason && reason > dumper->max_reason) + continue; + + /* initialize iterator with data about the stored records */ + dumper->active = true; + + raw_spin_lock_irqsave(&logbuf_lock, flags); + dumper->cur_seq = clear_seq; + dumper->cur_idx = clear_idx; + dumper->next_seq = log_next_seq; + dumper->next_idx = log_next_idx; + raw_spin_unlock_irqrestore(&logbuf_lock, flags); + + /* invoke dumper which will iterate over records */ + dumper->dump(dumper, reason); + + /* reset iterator */ + dumper->active = false; + } rcu_read_unlock(); } + +/** + * kmsg_dump_get_line - retrieve one kmsg log line + * @dumper: registered kmsg dumper + * @syslog: include the "<4>" prefixes + * @line: buffer to copy the line to + * @size: maximum size of the buffer + * @len: length of line placed into buffer + * + * Start at the beginning of the kmsg buffer, with the oldest kmsg + * record, and copy one record into the provided buffer. + * + * Consecutive calls will return the next available record moving + * towards the end of the buffer with the youngest messages. + * + * A return value of FALSE indicates that there are no more records to + * read. + */ +bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, + char *line, size_t size, size_t *len) +{ + unsigned long flags; + struct log *msg; + size_t l = 0; + bool ret = false; + + if (!dumper->active) + goto out; + + raw_spin_lock_irqsave(&logbuf_lock, flags); + if (dumper->cur_seq < log_first_seq) { + /* messages are gone, move to first available one */ + dumper->cur_seq = log_first_seq; + dumper->cur_idx = log_first_idx; + } + + /* last entry */ + if (dumper->cur_seq >= log_next_seq) { + raw_spin_unlock_irqrestore(&logbuf_lock, flags); + goto out; + } + + msg = log_from_idx(dumper->cur_idx); + l = msg_print_text(msg, syslog, + line, size); + + dumper->cur_idx = log_next(dumper->cur_idx); + dumper->cur_seq++; + ret = true; + raw_spin_unlock_irqrestore(&logbuf_lock, flags); +out: + if (len) + *len = l; + return ret; +} +EXPORT_SYMBOL_GPL(kmsg_dump_get_line); + +/** + * kmsg_dump_get_buffer - copy kmsg log lines + * @dumper: registered kmsg dumper + * @syslog: include the "<4>" prefixes + * @line: buffer to copy the line to + * @size: maximum size of the buffer + * @len: length of line placed into buffer + * + * Start at the end of the kmsg buffer and fill the provided buffer + * with as many of the the *youngest* kmsg records that fit into it. + * If the buffer is large enough, all available kmsg records will be + * copied with a single call. + * + * Consecutive calls will fill the buffer with the next block of + * available older records, not including the earlier retrieved ones. + * + * A return value of FALSE indicates that there are no more records to + * read. + */ +bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, + char *buf, size_t size, size_t *len) +{ + unsigned long flags; + u64 seq; + u32 idx; + u64 next_seq; + u32 next_idx; + size_t l = 0; + bool ret = false; + + if (!dumper->active) + goto out; + + raw_spin_lock_irqsave(&logbuf_lock, flags); + if (dumper->cur_seq < log_first_seq) { + /* messages are gone, move to first available one */ + dumper->cur_seq = log_first_seq; + dumper->cur_idx = log_first_idx; + } + + /* last entry */ + if (dumper->cur_seq >= dumper->next_seq) { + raw_spin_unlock_irqrestore(&logbuf_lock, flags); + goto out; + } + + /* calculate length of entire buffer */ + seq = dumper->cur_seq; + idx = dumper->cur_idx; + while (seq < dumper->next_seq) { + struct log *msg = log_from_idx(idx); + + l += msg_print_text(msg, true, NULL, 0); + idx = log_next(idx); + seq++; + } + + /* move first record forward until length fits into the buffer */ + seq = dumper->cur_seq; + idx = dumper->cur_idx; + while (l > size && seq < dumper->next_seq) { + struct log *msg = log_from_idx(idx); + + l -= msg_print_text(msg, true, NULL, 0); + idx = log_next(idx); + seq++; + } + + /* last message in next interation */ + next_seq = seq; + next_idx = idx; + + l = 0; + while (seq < dumper->next_seq) { + struct log *msg = log_from_idx(idx); + + l += msg_print_text(msg, syslog, + buf + l, size - l); + + idx = log_next(idx); + seq++; + } + + dumper->next_seq = next_seq; + dumper->next_idx = next_idx; + ret = true; + raw_spin_unlock_irqrestore(&logbuf_lock, flags); +out: + if (len) + *len = l; + return ret; +} +EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer); + +/** + * kmsg_dump_rewind - reset the interator + * @dumper: registered kmsg dumper + * + * Reset the dumper's iterator so that kmsg_dump_get_line() and + * kmsg_dump_get_buffer() can be called again and used multiple + * times within the same dumper.dump() callback. + */ +void kmsg_dump_rewind(struct kmsg_dumper *dumper) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&logbuf_lock, flags); + dumper->cur_seq = clear_seq; + dumper->cur_idx = clear_idx; + dumper->next_seq = log_next_seq; + dumper->next_idx = log_next_idx; + raw_spin_unlock_irqrestore(&logbuf_lock, flags); +} +EXPORT_SYMBOL_GPL(kmsg_dump_rewind); #endif diff --git a/kernel/sys.c b/kernel/sys.c index f0ec44dcd415..e0c8ffc50d7f 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -2127,9 +2127,6 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, else return -EINVAL; break; - case PR_GET_TID_ADDRESS: - error = prctl_get_tid_address(me, (int __user **)arg2); - break; default: return -EINVAL; } @@ -2147,6 +2144,9 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, case PR_SET_MM: error = prctl_set_mm(arg2, arg3, arg4, arg5); break; + case PR_GET_TID_ADDRESS: + error = prctl_get_tid_address(me, (int __user **)arg2); + break; case PR_SET_CHILD_SUBREAPER: me->signal->is_child_subreaper = !!arg2; error = 0; diff --git a/lib/fault-inject.c b/lib/fault-inject.c index 6805453c18e7..f7210ad6cffd 100644 --- a/lib/fault-inject.c +++ b/lib/fault-inject.c @@ -101,6 +101,10 @@ static inline bool fail_stacktrace(struct fault_attr *attr) bool should_fail(struct fault_attr *attr, ssize_t size) { + /* No need to check any other properties if the probability is 0 */ + if (attr->probability == 0) + return false; + if (attr->task_filter && !fail_task(attr, current)) return false; diff --git a/mm/memblock.c b/mm/memblock.c index 32a0a5e4d79d..d4382095f8bd 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -184,7 +184,24 @@ static void __init_memblock memblock_remove_region(struct memblock_type *type, u } } -static int __init_memblock memblock_double_array(struct memblock_type *type) +/** + * memblock_double_array - double the size of the memblock regions array + * @type: memblock type of the regions array being doubled + * @new_area_start: starting address of memory range to avoid overlap with + * @new_area_size: size of memory range to avoid overlap with + * + * Double the size of the @type regions array. If memblock is being used to + * allocate memory for a new reserved regions array and there is a previously + * allocated memory range [@new_area_start,@new_area_start+@new_area_size] + * waiting to be reserved, ensure the memory used by the new array does + * not overlap. + * + * RETURNS: + * 0 on success, -1 on failure. + */ +static int __init_memblock memblock_double_array(struct memblock_type *type, + phys_addr_t new_area_start, + phys_addr_t new_area_size) { struct memblock_region *new_array, *old_array; phys_addr_t old_size, new_size, addr; @@ -222,7 +239,18 @@ static int __init_memblock memblock_double_array(struct memblock_type *type) new_array = kmalloc(new_size, GFP_KERNEL); addr = new_array ? __pa(new_array) : 0; } else { - addr = memblock_find_in_range(0, MEMBLOCK_ALLOC_ACCESSIBLE, new_size, sizeof(phys_addr_t)); + /* only exclude range when trying to double reserved.regions */ + if (type != &memblock.reserved) + new_area_start = new_area_size = 0; + + addr = memblock_find_in_range(new_area_start + new_area_size, + memblock.current_limit, + new_size, sizeof(phys_addr_t)); + if (!addr && new_area_size) + addr = memblock_find_in_range(0, + min(new_area_start, memblock.current_limit), + new_size, sizeof(phys_addr_t)); + new_array = addr ? __va(addr) : 0; } if (!addr) { @@ -399,7 +427,7 @@ static int __init_memblock memblock_add_region(struct memblock_type *type, */ if (!insert) { while (type->cnt + nr_new > type->max) - if (memblock_double_array(type) < 0) + if (memblock_double_array(type, obase, size) < 0) return -ENOMEM; insert = true; goto repeat; @@ -450,7 +478,7 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type, /* we'll create at most two more regions */ while (type->cnt + 2 > type->max) - if (memblock_double_array(type) < 0) + if (memblock_double_array(type, base, size) < 0) return -ENOMEM; for (i = 0; i < type->cnt; i++) { @@ -540,9 +568,9 @@ int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size) * __next_free_mem_range - next function for for_each_free_mem_range() * @idx: pointer to u64 loop variable * @nid: nid: node selector, %MAX_NUMNODES for all nodes - * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL - * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL - * @p_nid: ptr to int for nid of the range, can be %NULL + * @out_start: ptr to phys_addr_t for start address of the range, can be %NULL + * @out_end: ptr to phys_addr_t for end address of the range, can be %NULL + * @out_nid: ptr to int for nid of the range, can be %NULL * * Find the first free area from *@idx which matches @nid, fill the out * parameters, and update *@idx for the next iteration. The lower 32bit of @@ -616,9 +644,9 @@ void __init_memblock __next_free_mem_range(u64 *idx, int nid, * __next_free_mem_range_rev - next function for for_each_free_mem_range_reverse() * @idx: pointer to u64 loop variable * @nid: nid: node selector, %MAX_NUMNODES for all nodes - * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL - * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL - * @p_nid: ptr to int for nid of the range, can be %NULL + * @out_start: ptr to phys_addr_t for start address of the range, can be %NULL + * @out_end: ptr to phys_addr_t for end address of the range, can be %NULL + * @out_nid: ptr to int for nid of the range, can be %NULL * * Reverse of __next_free_mem_range(). */ diff --git a/mm/memcontrol.c b/mm/memcontrol.c index ac35bccadb7b..f72b5e52451a 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1148,7 +1148,7 @@ bool __mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg, { if (root_memcg == memcg) return true; - if (!root_memcg->use_hierarchy) + if (!root_memcg->use_hierarchy || !memcg) return false; return css_is_ancestor(&memcg->css, &root_memcg->css); } @@ -1234,7 +1234,7 @@ int mem_cgroup_inactive_file_is_low(struct lruvec *lruvec) /** * mem_cgroup_margin - calculate chargeable space of a memory cgroup - * @mem: the memory cgroup + * @memcg: the memory cgroup * * Returns the maximum amount of memory @mem can be charged with, in * pages. @@ -1508,7 +1508,7 @@ static unsigned long mem_cgroup_reclaim(struct mem_cgroup *memcg, /** * test_mem_cgroup_node_reclaimable - * @mem: the target memcg + * @memcg: the target memcg * @nid: the node ID to be checked. * @noswap : specify true here if the user wants flle only information. * diff --git a/mm/memory.c b/mm/memory.c index 1b7dc662bf9f..2466d1250231 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1225,7 +1225,15 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb, next = pmd_addr_end(addr, end); if (pmd_trans_huge(*pmd)) { if (next - addr != HPAGE_PMD_SIZE) { - VM_BUG_ON(!rwsem_is_locked(&tlb->mm->mmap_sem)); +#ifdef CONFIG_DEBUG_VM + if (!rwsem_is_locked(&tlb->mm->mmap_sem)) { + pr_err("%s: mmap_sem is unlocked! addr=0x%lx end=0x%lx vma->vm_start=0x%lx vma->vm_end=0x%lx\n", + __func__, addr, end, + vma->vm_start, + vma->vm_end); + BUG(); + } +#endif split_huge_page_pmd(vma->vm_mm, pmd); } else if (zap_huge_pmd(tlb, vma, pmd, addr)) goto next; @@ -1366,7 +1374,7 @@ void unmap_vmas(struct mmu_gather *tlb, /** * zap_page_range - remove user pages in a given range * @vma: vm_area_struct holding the applicable pages - * @address: starting address of pages to zap + * @start: starting address of pages to zap * @size: number of bytes to zap * @details: details of nonlinear truncation or shared cache invalidation * diff --git a/mm/mempolicy.c b/mm/mempolicy.c index f15c1b24ca18..1d771e4200d2 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1177,7 +1177,7 @@ static long do_mbind(unsigned long start, unsigned long len, if (!list_empty(&pagelist)) { nr_failed = migrate_pages(&pagelist, new_vma_page, (unsigned long)vma, - false, true); + false, MIGRATE_SYNC); if (nr_failed) putback_lru_pages(&pagelist); } diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 416637f0e924..ac300c99baf6 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -184,6 +184,7 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, const nodemask_t *nodemask, unsigned long totalpages) { long points; + long adj; if (oom_unkillable_task(p, memcg, nodemask)) return 0; @@ -192,7 +193,8 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, if (!p) return 0; - if (p->signal->oom_score_adj == OOM_SCORE_ADJ_MIN) { + adj = p->signal->oom_score_adj; + if (adj == OOM_SCORE_ADJ_MIN) { task_unlock(p); return 0; } @@ -210,14 +212,11 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, * implementation used by LSMs. */ if (has_capability_noaudit(p, CAP_SYS_ADMIN)) - points -= 30 * totalpages / 1000; + adj -= 30; - /* - * /proc/pid/oom_score_adj ranges from -1000 to +1000 such that it may - * either completely disable oom killing or always prefer a certain - * task. - */ - points += p->signal->oom_score_adj * totalpages / 1000; + /* Normalize to oom_score_adj units */ + adj *= totalpages / 1000; + points += adj; /* * Never return 0 for an eligible task regardless of the root bonus and @@ -366,7 +365,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints, /** * dump_tasks - dump current memory state of all system tasks - * @mem: current's memory controller, if constrained + * @memcg: current's memory controller, if constrained * @nodemask: nodemask passed to page allocator for mempolicy ooms * * Dumps the current memory state of all eligible tasks. Tasks not in the same diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c index 1ccbd714059c..eb750f851395 100644 --- a/mm/page_cgroup.c +++ b/mm/page_cgroup.c @@ -392,7 +392,7 @@ static struct swap_cgroup *lookup_swap_cgroup(swp_entry_t ent, /** * swap_cgroup_cmpxchg - cmpxchg mem_cgroup's id for this swp_entry. - * @end: swap entry to be cmpxchged + * @ent: swap entry to be cmpxchged * @old: old id * @new: new id * @@ -422,7 +422,7 @@ unsigned short swap_cgroup_cmpxchg(swp_entry_t ent, /** * swap_cgroup_record - record mem_cgroup for this swp_entry. * @ent: swap entry to be recorded into - * @mem: mem_cgroup to be recorded + * @id: mem_cgroup to be recorded * * Returns old value at success, 0 at failure. * (Of course, old value can be 0.) diff --git a/mm/pagewalk.c b/mm/pagewalk.c index aa9701e12714..6c118d012bb5 100644 --- a/mm/pagewalk.c +++ b/mm/pagewalk.c @@ -162,7 +162,6 @@ static int walk_hugetlb_range(struct vm_area_struct *vma, /** * walk_page_range - walk a memory map's page tables with a callback - * @mm: memory map to walk * @addr: starting address * @end: ending address * @walk: set of callbacks to invoke for each level of the tree diff --git a/mm/percpu-vm.c b/mm/percpu-vm.c index 405d331804c3..3707c71ae4cd 100644 --- a/mm/percpu-vm.c +++ b/mm/percpu-vm.c @@ -360,7 +360,6 @@ static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size) * @chunk: chunk to depopulate * @off: offset to the area to depopulate * @size: size of the area to depopulate in bytes - * @flush: whether to flush cache and tlb or not * * For each cpu, depopulate and unmap pages [@page_start,@page_end) * from @chunk. If @flush is true, vcache is flushed before unmapping diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 5af18d11b518..2a167658bb95 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -192,10 +192,10 @@ static int pack_sg_list(struct scatterlist *sg, int start, s = rest_of_page(data); if (s > count) s = count; + BUG_ON(index > limit); sg_set_buf(&sg[index++], data, s); count -= s; data += s; - BUG_ON(index > limit); } return index-start; diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index a776f751edbf..ba4323bce0e9 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -504,13 +504,6 @@ void ceph_destroy_client(struct ceph_client *client) /* unmount */ ceph_osdc_stop(&client->osdc); - /* - * make sure osd connections close out before destroying the - * auth module, which is needed to free those connections' - * ceph_authorizers. - */ - ceph_msgr_flush(); - ceph_monc_stop(&client->monc); ceph_debugfs_client_cleanup(client); diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 524f4e4f598b..b332c3d76059 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -563,6 +563,10 @@ static void prepare_write_message(struct ceph_connection *con) m->hdr.seq = cpu_to_le64(++con->out_seq); m->needs_out_seq = false; } +#ifdef CONFIG_BLOCK + else + m->bio_iter = NULL; +#endif dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n", m, con->out_seq, le16_to_cpu(m->hdr.type), diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index 10d6008d31f2..d0649a9655be 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c @@ -847,6 +847,14 @@ void ceph_monc_stop(struct ceph_mon_client *monc) mutex_unlock(&monc->mutex); + /* + * flush msgr queue before we destroy ourselves to ensure that: + * - any work that references our embedded con is finished. + * - any osd_client or other work that may reference an authorizer + * finishes before we shut down the auth subsystem. + */ + ceph_msgr_flush(); + ceph_auth_destroy(monc->auth); ceph_msg_put(monc->m_auth); diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 1ffebed5ce0f..ca59e66c9787 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -139,15 +139,15 @@ void ceph_osdc_release_request(struct kref *kref) if (req->r_request) ceph_msg_put(req->r_request); - if (req->r_reply) - ceph_msg_put(req->r_reply); if (req->r_con_filling_msg) { dout("release_request revoking pages %p from con %p\n", req->r_pages, req->r_con_filling_msg); ceph_con_revoke_message(req->r_con_filling_msg, req->r_reply); - ceph_con_put(req->r_con_filling_msg); + req->r_con_filling_msg->ops->put(req->r_con_filling_msg); } + if (req->r_reply) + ceph_msg_put(req->r_reply); if (req->r_own_pages) ceph_release_page_vector(req->r_pages, req->r_num_pages); @@ -1216,7 +1216,7 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, if (req->r_con_filling_msg == con && req->r_reply == msg) { dout(" dropping con_filling_msg ref %p\n", con); req->r_con_filling_msg = NULL; - ceph_con_put(con); + con->ops->put(con); } if (!req->r_got_reply) { @@ -2028,7 +2028,7 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, dout("get_reply revoking msg %p from old con %p\n", req->r_reply, req->r_con_filling_msg); ceph_con_revoke_message(req->r_con_filling_msg, req->r_reply); - ceph_con_put(req->r_con_filling_msg); + req->r_con_filling_msg->ops->put(req->r_con_filling_msg); req->r_con_filling_msg = NULL; } @@ -2063,7 +2063,7 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, #endif } *skip = 0; - req->r_con_filling_msg = ceph_con_get(con); + req->r_con_filling_msg = con->ops->get(con); dout("get_reply tid %lld %p\n", tid, m); out: diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 0948c6b5a321..8b673dd4627f 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -83,6 +83,8 @@ push(@signature_tags, "Signed-off-by:"); push(@signature_tags, "Reviewed-by:"); push(@signature_tags, "Acked-by:"); +my $signature_pattern = "\(" . join("|", @signature_tags) . "\)"; + # rfc822 email address - preloaded methods go here. my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])"; my $rfc822_char = '[\\000-\\377]'; @@ -473,7 +475,6 @@ my @subsystem = (); my @status = (); my %deduplicate_name_hash = (); my %deduplicate_address_hash = (); -my $signature_pattern; my @maintainers = get_maintainers(); diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 41ca803a1fff..7504e62188d6 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -4393,20 +4393,19 @@ void snd_hda_update_power_acct(struct hda_codec *codec) codec->power_jiffies += delta; } -/** - * snd_hda_power_up - Power-up the codec - * @codec: HD-audio codec - * - * Increment the power-up counter and power up the hardware really when - * not turned on yet. - */ -void snd_hda_power_up(struct hda_codec *codec) +/* Transition to powered up, if wait_power_down then wait for a pending + * transition to D3 to complete. A pending D3 transition is indicated + * with power_transition == -1. */ +static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down) { struct hda_bus *bus = codec->bus; spin_lock(&codec->power_lock); codec->power_count++; - if (codec->power_on || codec->power_transition > 0) { + /* Return if power_on or transitioning to power_on, unless currently + * powering down. */ + if ((codec->power_on || codec->power_transition > 0) && + !(wait_power_down && codec->power_transition < 0)) { spin_unlock(&codec->power_lock); return; } @@ -4430,8 +4429,37 @@ void snd_hda_power_up(struct hda_codec *codec) codec->power_transition = 0; spin_unlock(&codec->power_lock); } + +/** + * snd_hda_power_up - Power-up the codec + * @codec: HD-audio codec + * + * Increment the power-up counter and power up the hardware really when + * not turned on yet. + */ +void snd_hda_power_up(struct hda_codec *codec) +{ + __snd_hda_power_up(codec, false); +} EXPORT_SYMBOL_HDA(snd_hda_power_up); +/** + * snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending + * D3 transition to complete. This differs from snd_hda_power_up() when + * power_transition == -1. snd_hda_power_up sees this case as a nop, + * snd_hda_power_up_d3wait waits for the D3 transition to complete then powers + * back up. + * @codec: HD-audio codec + * + * Cancel any power down operation hapenning on the work queue, then power up. + */ +void snd_hda_power_up_d3wait(struct hda_codec *codec) +{ + /* This will cancel and wait for pending power_work to complete. */ + __snd_hda_power_up(codec, true); +} +EXPORT_SYMBOL_HDA(snd_hda_power_up_d3wait); + #define power_save(codec) \ ((codec)->bus->power_save ? *(codec)->bus->power_save : 0) diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 4fc3960c8591..2fdaadbb4326 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -1056,10 +1056,12 @@ const char *snd_hda_get_jack_location(u32 cfg); */ #ifdef CONFIG_SND_HDA_POWER_SAVE void snd_hda_power_up(struct hda_codec *codec); +void snd_hda_power_up_d3wait(struct hda_codec *codec); void snd_hda_power_down(struct hda_codec *codec); void snd_hda_update_power_acct(struct hda_codec *codec); #else static inline void snd_hda_power_up(struct hda_codec *codec) {} +static inline void snd_hda_power_up_d3wait(struct hda_codec *codec) {} static inline void snd_hda_power_down(struct hda_codec *codec) {} #endif diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 02763827dde0..7757536b9d5f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1766,7 +1766,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) buff_step); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, buff_step); - snd_hda_power_up(apcm->codec); + snd_hda_power_up_d3wait(apcm->codec); err = hinfo->ops.open(hinfo, apcm->codec, substream); if (err < 0) { azx_release_device(azx_dev); diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 65d525d74c54..812acd83fb48 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1863,6 +1863,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, return ret; } + regcache_cache_only(wm8904->regmap, false); regcache_sync(wm8904->regmap); /* Enable bias */ @@ -1899,14 +1900,8 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, WM8904_BIAS_ENA, 0); -#ifdef CONFIG_REGULATOR - /* Post 2.6.34 we will be able to get a callback when - * the regulators are disabled which we can use but - * for now just assume that the power will be cut if - * the regulator API is in use. - */ - codec->cache_sync = 1; -#endif + regcache_cache_only(wm8904->regmap, true); + regcache_mark_dirty(wm8904->regmap); regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); @@ -2084,10 +2079,8 @@ static int wm8904_probe(struct snd_soc_codec *codec) { struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); struct wm8904_pdata *pdata = wm8904->pdata; - u16 *reg_cache = codec->reg_cache; int ret, i; - codec->cache_sync = 1; codec->control_data = wm8904->regmap; switch (wm8904->devtype) { @@ -2150,6 +2143,7 @@ static int wm8904_probe(struct snd_soc_codec *codec) goto err_enable; } + regcache_cache_only(wm8904->regmap, true); /* Change some default settings - latch VU and enable ZC */ snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT, WM8904_ADC_VU, WM8904_ADC_VU); @@ -2180,14 +2174,18 @@ static int wm8904_probe(struct snd_soc_codec *codec) if (!pdata->gpio_cfg[i]) continue; - reg_cache[WM8904_GPIO_CONTROL_1 + i] - = pdata->gpio_cfg[i] & 0xffff; + regmap_update_bits(wm8904->regmap, + WM8904_GPIO_CONTROL_1 + i, + 0xffff, + pdata->gpio_cfg[i]); } /* Zero is the default value for these anyway */ for (i = 0; i < WM8904_MIC_REGS; i++) - reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i] - = pdata->mic_cfg[i]; + regmap_update_bits(wm8904->regmap, + WM8904_MIC_BIAS_CONTROL_0 + i, + 0xffff, + pdata->mic_cfg[i]); } /* Set Class W by default - this will be managed by the Class diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 8af422e38fd0..dc9b42b7fc4d 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -2837,8 +2837,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) } } - regcache_cache_only(codec->control_data, true); - /* Apply platform data settings */ snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL, WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK, @@ -3051,7 +3049,6 @@ static int wm8996_remove(struct snd_soc_codec *codec) for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) regulator_unregister_notifier(wm8996->supplies[i].consumer, &wm8996->disable_nb[i]); - regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); return 0; } @@ -3206,14 +3203,15 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, dev_info(&i2c->dev, "revision %c\n", (reg & WM8996_CHIP_REV_MASK) + 'A'); - regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); - ret = wm8996_reset(wm8996); if (ret < 0) { dev_err(&i2c->dev, "Failed to issue reset\n"); goto err_regmap; } + regcache_cache_only(wm8996->regmap, true); + regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); + wm8996_init_gpio(wm8996); ret = snd_soc_register_codec(&i2c->dev, diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 1c2aa7fab3fd..4da5fc55c7ee 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -33,7 +33,6 @@ #include #include -#include #include "../../arm/pxa2xx-pcm.h" #include "pxa-ssp.h" @@ -194,7 +193,7 @@ static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div) { u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0); - if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) { + if (ssp->type == PXA25x_SSP) { sscr0 &= ~0x0000ff00; sscr0 |= ((div - 2)/2) << 8; /* 2..512 */ } else { @@ -212,7 +211,7 @@ static u32 pxa_ssp_get_scr(struct ssp_device *ssp) u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0); u32 div; - if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) + if (ssp->type == PXA25x_SSP) div = ((sscr0 >> 8) & 0xff) * 2 + 2; else div = ((sscr0 >> 8) & 0xfff) + 1; @@ -242,7 +241,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, break; case PXA_SSP_CLK_PLL: /* Internal PLL is fixed */ - if (cpu_is_pxa25x()) + if (ssp->type == PXA25x_SSP) priv->sysclk = 1843200; else priv->sysclk = 13000000; @@ -266,11 +265,11 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, /* The SSP clock must be disabled when changing SSP clock mode * on PXA2xx. On PXA3xx it must be enabled when doing so. */ - if (!cpu_is_pxa3xx()) + if (ssp->type != PXA3xx_SSP) clk_disable(ssp->clk); val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0; pxa_ssp_write_reg(ssp, SSCR0, val); - if (!cpu_is_pxa3xx()) + if (ssp->type != PXA3xx_SSP) clk_enable(ssp->clk); return 0; @@ -294,24 +293,20 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, case PXA_SSP_AUDIO_DIV_SCDB: val = pxa_ssp_read_reg(ssp, SSACD); val &= ~SSACD_SCDB; -#if defined(CONFIG_PXA3xx) - if (cpu_is_pxa3xx()) + if (ssp->type == PXA3xx_SSP) val &= ~SSACD_SCDX8; -#endif switch (div) { case PXA_SSP_CLK_SCDB_1: val |= SSACD_SCDB; break; case PXA_SSP_CLK_SCDB_4: break; -#if defined(CONFIG_PXA3xx) case PXA_SSP_CLK_SCDB_8: - if (cpu_is_pxa3xx()) + if (ssp->type == PXA3xx_SSP) val |= SSACD_SCDX8; else return -EINVAL; break; -#endif default: return -EINVAL; } @@ -337,10 +332,8 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, struct ssp_device *ssp = priv->ssp; u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70; -#if defined(CONFIG_PXA3xx) - if (cpu_is_pxa3xx()) + if (ssp->type == PXA3xx_SSP) pxa_ssp_write_reg(ssp, SSACDD, 0); -#endif switch (freq_out) { case 5622000: @@ -365,11 +358,10 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, break; default: -#ifdef CONFIG_PXA3xx /* PXA3xx has a clock ditherer which can be used to generate * a wider range of frequencies - calculate a value for it. */ - if (cpu_is_pxa3xx()) { + if (ssp->type == PXA3xx_SSP) { u32 val; u64 tmp = 19968; tmp *= 1000000; @@ -386,7 +378,6 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, val, freq_out); break; } -#endif return -EINVAL; } @@ -590,10 +581,8 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, /* bit size */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: -#ifdef CONFIG_PXA3xx - if (cpu_is_pxa3xx()) + if (ssp->type == PXA3xx_SSP) sscr0 |= SSCR0_FPCKE; -#endif sscr0 |= SSCR0_DataSize(16); break; case SNDRV_PCM_FORMAT_S24_LE: @@ -618,9 +607,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, * trying and failing a lot; some of the registers * needed for that mode are only available on PXA3xx. */ - -#ifdef CONFIG_PXA3xx - if (!cpu_is_pxa3xx()) + if (ssp->type != PXA3xx_SSP) return -EINVAL; sspsp |= SSPSP_SFRMWDTH(width * 2); @@ -628,9 +615,6 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, sspsp |= SSPSP_EDMYSTOP(3); sspsp |= SSPSP_DMYSTOP(3); sspsp |= SSPSP_DMYSTRT(1); -#else - return -EINVAL; -#endif } else { /* The frame width is the width the LRCLK is * asserted for; the delay is expressed in diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 0b0df49d9d33..3b6da91188a9 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -346,6 +346,17 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) return 0; } +static int tegra_wm8903_remove(struct snd_soc_card *card) +{ + struct snd_soc_pcm_runtime *rtd = &(card->rtd[0]); + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_codec *codec = codec_dai->codec; + + wm8903_mic_detect(codec, NULL, 0, 0); + + return 0; +} + static struct snd_soc_dai_link tegra_wm8903_dai = { .name = "WM8903", .stream_name = "WM8903 PCM", @@ -363,6 +374,8 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = { .dai_link = &tegra_wm8903_dai, .num_links = 1, + .remove = tegra_wm8903_remove, + .controls = tegra_wm8903_controls, .num_controls = ARRAY_SIZE(tegra_wm8903_controls), .dapm_widgets = tegra_wm8903_dapm_widgets, diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index 6f9715ab32fe..56ad923bf6b5 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c @@ -209,7 +209,7 @@ static int usb6fire_fw_ezusb_upload( int ret; u8 data; struct usb_device *device = interface_to_usbdev(intf); - const struct firmware *fw = 0; + const struct firmware *fw = NULL; struct ihex_record *rec = kmalloc(sizeof(struct ihex_record), GFP_KERNEL); diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index cdf8b7601973..54607f8c4f66 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -354,17 +354,21 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && get_endpoint(alts, 1)->bSynchAddress != 0 && !implicit_fb)) { - snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n", - dev->devnum, fmt->iface, fmt->altsetting); + snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. bmAttributes %02x, bLength %d, bSynchAddress %02x\n", + dev->devnum, fmt->iface, fmt->altsetting, + get_endpoint(alts, 1)->bmAttributes, + get_endpoint(alts, 1)->bLength, + get_endpoint(alts, 1)->bSynchAddress); return -EINVAL; } ep = get_endpoint(alts, 1)->bEndpointAddress; - if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && + if (!implicit_fb && + get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) || - (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)) || - ( is_playback && !implicit_fb))) { - snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n", - dev->devnum, fmt->iface, fmt->altsetting); + (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) { + snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n", + dev->devnum, fmt->iface, fmt->altsetting, + is_playback, ep, get_endpoint(alts, 0)->bSynchAddress); return -EINVAL; } @@ -1147,7 +1151,8 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea return -EINVAL; } -int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd) +static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, + int cmd) { int err; struct snd_usb_substream *subs = substream->runtime->private_data; diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 146fd6147e84..d9834b362943 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -701,14 +701,18 @@ int main(void) pfd.fd = fd; while (1) { + struct sockaddr *addr_p = (struct sockaddr *) &addr; + socklen_t addr_l = sizeof(addr); pfd.events = POLLIN; pfd.revents = 0; poll(&pfd, 1, -1); - len = recv(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0); + len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0, + addr_p, &addr_l); - if (len < 0) { - syslog(LOG_ERR, "recv failed; error:%d", len); + if (len < 0 || addr.nl_pid) { + syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s", + addr.nl_pid, errno, strerror(errno)); close(fd); return -1; } diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 262589991ea4..07b5c7703dd1 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1179,6 +1179,12 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) fprintf(stderr, "cannot use both --output and --log-fd\n"); usage_with_options(stat_usage, options); } + + if (output_fd < 0) { + fprintf(stderr, "argument to --log-fd must be a > 0\n"); + usage_with_options(stat_usage, options); + } + if (!output) { struct timespec tm; mode = append_file ? "a" : "w"; @@ -1190,7 +1196,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) } clock_gettime(CLOCK_REALTIME, &tm); fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); - } else if (output_fd != 2) { + } else if (output_fd > 0) { mode = append_file ? "a" : "w"; output = fdopen(output_fd, mode); if (!output) { diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 2dd5edf161b7..e909d43cf542 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1942,7 +1942,6 @@ int perf_file_header__read(struct perf_file_header *header, else return -1; } else if (ph->needs_swap) { - unsigned int i; /* * feature bitmap is declared as an array of unsigned longs -- * not good since its size can differ between the host that @@ -1958,14 +1957,17 @@ int perf_file_header__read(struct perf_file_header *header, * file), punt and fallback to the original behavior -- * clearing all feature bits and setting buildid. */ - for (i = 0; i < BITS_TO_LONGS(HEADER_FEAT_BITS); ++i) - header->adds_features[i] = bswap_64(header->adds_features[i]); + mem_bswap_64(&header->adds_features, + BITS_TO_U64(HEADER_FEAT_BITS)); if (!test_bit(HEADER_HOSTNAME, header->adds_features)) { - for (i = 0; i < BITS_TO_LONGS(HEADER_FEAT_BITS); ++i) { - header->adds_features[i] = bswap_64(header->adds_features[i]); - header->adds_features[i] = bswap_32(header->adds_features[i]); - } + /* unswap as u64 */ + mem_bswap_64(&header->adds_features, + BITS_TO_U64(HEADER_FEAT_BITS)); + + /* unswap as u32 */ + mem_bswap_32(&header->adds_features, + BITS_TO_U32(HEADER_FEAT_BITS)); } if (!test_bit(HEADER_HOSTNAME, header->adds_features)) { @@ -2091,6 +2093,35 @@ static int read_attr(int fd, struct perf_header *ph, return ret <= 0 ? -1 : 0; } +static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel) +{ + struct event_format *event = trace_find_event(evsel->attr.config); + char bf[128]; + + if (event == NULL) + return -1; + + snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name); + evsel->name = strdup(bf); + if (event->name == NULL) + return -1; + + return 0; +} + +static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist) +{ + struct perf_evsel *pos; + + list_for_each_entry(pos, &evlist->entries, node) { + if (pos->attr.type == PERF_TYPE_TRACEPOINT && + perf_evsel__set_tracepoint_name(pos)) + return -1; + } + + return 0; +} + int perf_session__read_header(struct perf_session *session, int fd) { struct perf_header *header = &session->header; @@ -2172,6 +2203,9 @@ int perf_session__read_header(struct perf_session *session, int fd) lseek(fd, header->data_offset, SEEK_SET); + if (perf_evlist__set_tracepoint_names(session->evlist)) + goto out_delete_evlist; + header->frozen = 1; return 0; out_errno: diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h index f1584833bd22..587a230d2075 100644 --- a/tools/perf/util/include/linux/bitops.h +++ b/tools/perf/util/include/linux/bitops.h @@ -8,6 +8,8 @@ #define BITS_PER_LONG __WORDSIZE #define BITS_PER_BYTE 8 #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) +#define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64)) +#define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) #define for_each_set_bit(bit, addr, size) \ for ((bit) = find_first_bit((addr), (size)); \ diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 2600916efa83..c3e399bcf18d 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -442,6 +442,16 @@ static void perf_tool__fill_defaults(struct perf_tool *tool) tool->finished_round = process_finished_round_stub; } } + +void mem_bswap_32(void *src, int byte_size) +{ + u32 *m = src; + while (byte_size > 0) { + *m = bswap_32(*m); + byte_size -= sizeof(u32); + ++m; + } +} void mem_bswap_64(void *src, int byte_size) { diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 7a5434c00565..0c702e3f0a36 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -80,6 +80,7 @@ struct branch_info *machine__resolve_bstack(struct machine *self, bool perf_session__has_traces(struct perf_session *self, const char *msg); void mem_bswap_64(void *src, int byte_size); +void mem_bswap_32(void *src, int byte_size); void perf_event__attr_swap(struct perf_event_attr *attr); int perf_session__create_kernel_maps(struct perf_session *self); diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index 01f572c10c71..b1e091ae2f37 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c @@ -635,7 +635,6 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, int r = 0, idx; struct kvm_assigned_dev_kernel *match; struct pci_dev *dev; - u8 header_type; if (!(assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU)) return -EINVAL; @@ -668,8 +667,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, } /* Don't allow bridges to be assigned */ - pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type); - if ((header_type & PCI_HEADER_TYPE) != PCI_HEADER_TYPE_NORMAL) { + if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) { r = -EPERM; goto out_put; }