diff --git a/[refs] b/[refs] index 6c716954431b..f5139ec20876 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5dbbaf2de89613d19a9286d4db0a535ca2735d26 +refs/heads/master: 4610476d89d53714ca94aae081fa035908bc137a diff --git a/trunk/Documentation/devicetree/bindings/clock/imx23-clock.txt b/trunk/Documentation/devicetree/bindings/clock/imx23-clock.txt index 5083c0b834b2..baadbb11fe98 100644 --- a/trunk/Documentation/devicetree/bindings/clock/imx23-clock.txt +++ b/trunk/Documentation/devicetree/bindings/clock/imx23-clock.txt @@ -60,6 +60,11 @@ clks: clkctrl@80040000 { compatible = "fsl,imx23-clkctrl"; reg = <0x80040000 0x2000>; #clock-cells = <1>; + clock-output-names = + ... + "uart", /* 32 */ + ... + "end_of_list"; }; auart0: serial@8006c000 { diff --git a/trunk/Documentation/devicetree/bindings/clock/imx25-clock.txt b/trunk/Documentation/devicetree/bindings/clock/imx25-clock.txt index db4f2f05c4d0..c2a3525ecb4e 100644 --- a/trunk/Documentation/devicetree/bindings/clock/imx25-clock.txt +++ b/trunk/Documentation/devicetree/bindings/clock/imx25-clock.txt @@ -146,6 +146,10 @@ clks: ccm@53f80000 { compatible = "fsl,imx25-ccm"; reg = <0x53f80000 0x4000>; interrupts = <31>; + clock-output-names = ... + "uart_ipg", + "uart_serial", + ...; }; uart1: serial@43f90000 { diff --git a/trunk/Documentation/devicetree/bindings/clock/imx28-clock.txt b/trunk/Documentation/devicetree/bindings/clock/imx28-clock.txt index e6587af62ff0..52a49a4a50b3 100644 --- a/trunk/Documentation/devicetree/bindings/clock/imx28-clock.txt +++ b/trunk/Documentation/devicetree/bindings/clock/imx28-clock.txt @@ -83,6 +83,11 @@ clks: clkctrl@80040000 { compatible = "fsl,imx28-clkctrl"; reg = <0x80040000 0x2000>; #clock-cells = <1>; + clock-output-names = + ... + "uart", /* 45 */ + ... + "end_of_list"; }; auart0: serial@8006a000 { diff --git a/trunk/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/trunk/Documentation/devicetree/bindings/clock/imx6q-clock.txt index f73fdf595568..d77b4e68dc42 100644 --- a/trunk/Documentation/devicetree/bindings/clock/imx6q-clock.txt +++ b/trunk/Documentation/devicetree/bindings/clock/imx6q-clock.txt @@ -211,6 +211,10 @@ clks: ccm@020c4000 { reg = <0x020c4000 0x4000>; interrupts = <0 87 0x04 0 88 0x04>; #clock-cells = <1>; + clock-output-names = ... + "uart_ipg", + "uart_serial", + ...; }; uart1: serial@02020000 { diff --git a/trunk/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt b/trunk/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt index d4eab9227ea4..558cdf3c9abc 100644 --- a/trunk/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt +++ b/trunk/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt @@ -1,19 +1,4 @@ -Driver a GPIO line that can be used to turn the power off. - -The driver supports both level triggered and edge triggered power off. -At driver load time, the driver will request the given gpio line and -install a pm_power_off handler. If the optional properties 'input' is -not found, the GPIO line will be driven in the inactive -state. Otherwise its configured as an input. - -When the pm_power_off is called, the gpio is configured as an output, -and drive active, so triggering a level triggered power off -condition. This will also cause an inactive->active edge condition, so -triggering positive edge triggered power off. After a delay of 100ms, -the GPIO is set to inactive, thus causing an active->inactive edge, -triggering negative edge triggered power off. After another 100ms -delay the GPIO is driver active again. If the power is still on and -the CPU still running after a 3000ms delay, a WARN_ON(1) is emitted. +GPIO line that should be set high/low to power off a device Required properties: - compatible : should be "gpio-poweroff". @@ -28,9 +13,10 @@ Optional properties: property is not specified, the GPIO is initialized as an output in its inactive state. + Examples: gpio-poweroff { compatible = "gpio-poweroff"; - gpios = <&gpio 4 0>; + gpios = <&gpio 4 0>; /* GPIO 4 Active Low */ }; diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index cd5b31fec01c..7a39670d61dd 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -228,7 +228,7 @@ S: Maintained F: drivers/platform/x86/acerhdf.c ACER WMI LAPTOP EXTRAS -M: "Lee, Chun-Yi" +M: Joey Lee L: platform-driver-x86@vger.kernel.org S: Maintained F: drivers/platform/x86/acer-wmi.c @@ -648,7 +648,7 @@ F: arch/arm/ ARM SUB-ARCHITECTURES L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -S: Maintained +S: MAINTAINED F: arch/arm/mach-*/ F: arch/arm/plat-*/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git @@ -5085,7 +5085,7 @@ S: Maintained F: drivers/media/radio/radio-mr800.c MSI LAPTOP SUPPORT -M: "Lee, Chun-Yi" +M: "Lee, Chun-Yi" L: platform-driver-x86@vger.kernel.org S: Maintained F: drivers/platform/x86/msi-laptop.c @@ -5515,7 +5515,8 @@ M: Benoît Cousson M: Paul Walmsley L: linux-omap@vger.kernel.org S: Maintained -F: arch/arm/mach-omap2/omap_hwmod.* +F: arch/arm/mach-omap2/omap_hwmod.c +F: arch/arm/plat-omap/include/plat/omap_hwmod.h OMAP HWMOD DATA FOR OMAP4-BASED DEVICES M: Benoît Cousson @@ -7341,7 +7342,7 @@ S: Odd Fixes F: drivers/staging/speakup/ STAGING - TI DSP BRIDGE DRIVERS -M: Omar Ramirez Luna +M: Omar Ramirez Luna S: Odd Fixes F: drivers/staging/tidspbridge/ @@ -8533,7 +8534,7 @@ F: Documentation/x86/ F: arch/x86/ X86 PLATFORM DRIVERS -M: Matthew Garrett +M: Matthew Garrett L: platform-driver-x86@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git S: Maintained diff --git a/trunk/Makefile b/trunk/Makefile index a1667c4bcce5..80c5694b29fd 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 8 SUBLEVEL = 0 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc2 NAME = Terrified Chipmunk # *DOCUMENTATION* diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 67874b82a4ed..f95ba14ae3d0 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -371,6 +371,7 @@ config ARCH_CNS3XXX config ARCH_CLPS711X bool "Cirrus Logic CLPS711x/EP721x/EP731x-based" select ARCH_REQUIRE_GPIOLIB + select ARCH_USES_GETTIMEOFFSET select AUTO_ZRELADDR select CLKDEV_LOOKUP select COMMON_CLK @@ -1229,7 +1230,6 @@ config ARM_ERRATA_430973 config ARM_ERRATA_458693 bool "ARM errata: Processor deadlock when a false hazard is created" depends on CPU_V7 - depends on !ARCH_MULTIPLATFORM help This option enables the workaround for the 458693 Cortex-A8 (r2p0) erratum. For very specific sequences of memory operations, it is @@ -1243,7 +1243,6 @@ config ARM_ERRATA_458693 config ARM_ERRATA_460075 bool "ARM errata: Data written to the L2 cache can be overwritten with stale data" depends on CPU_V7 - depends on !ARCH_MULTIPLATFORM help This option enables the workaround for the 460075 Cortex-A8 (r2p0) erratum. Any asynchronous access to the L2 cache may encounter a @@ -1256,7 +1255,6 @@ config ARM_ERRATA_460075 config ARM_ERRATA_742230 bool "ARM errata: DMB operation may be faulty" depends on CPU_V7 && SMP - depends on !ARCH_MULTIPLATFORM help This option enables the workaround for the 742230 Cortex-A9 (r1p0..r2p2) erratum. Under rare circumstances, a DMB instruction @@ -1269,7 +1267,6 @@ config ARM_ERRATA_742230 config ARM_ERRATA_742231 bool "ARM errata: Incorrect hazard handling in the SCU may lead to data corruption" depends on CPU_V7 && SMP - depends on !ARCH_MULTIPLATFORM help This option enables the workaround for the 742231 Cortex-A9 (r2p0..r2p2) erratum. Under certain conditions, specific to the @@ -1320,7 +1317,6 @@ config PL310_ERRATA_727915 config ARM_ERRATA_743622 bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption" depends on CPU_V7 - depends on !ARCH_MULTIPLATFORM help This option enables the workaround for the 743622 Cortex-A9 (r2p*) erratum. Under very rare conditions, a faulty @@ -1334,7 +1330,6 @@ config ARM_ERRATA_743622 config ARM_ERRATA_751472 bool "ARM errata: Interrupted ICIALLUIS may prevent completion of broadcasted operation" depends on CPU_V7 - depends on !ARCH_MULTIPLATFORM help This option enables the workaround for the 751472 Cortex-A9 (prior to r3p0) erratum. An interrupted ICIALLUIS operation may prevent the diff --git a/trunk/arch/arm/boot/dts/Makefile b/trunk/arch/arm/boot/dts/Makefile index 5ebb44fe826a..e44da40d984f 100644 --- a/trunk/arch/arm/boot/dts/Makefile +++ b/trunk/arch/arm/boot/dts/Makefile @@ -155,7 +155,6 @@ dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \ dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb targets += dtbs -targets += $(dtb-y) endif # *.dtb used to be generated in the directory above. Clean out the diff --git a/trunk/arch/arm/boot/dts/armada-370-xp.dtsi b/trunk/arch/arm/boot/dts/armada-370-xp.dtsi index 4c0abe85405f..cf6c48a09eac 100644 --- a/trunk/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/trunk/arch/arm/boot/dts/armada-370-xp.dtsi @@ -50,19 +50,17 @@ ranges; serial@d0012000 { - compatible = "snps,dw-apb-uart"; + compatible = "ns16550"; reg = <0xd0012000 0x100>; reg-shift = <2>; interrupts = <41>; - reg-io-width = <4>; status = "disabled"; }; serial@d0012100 { - compatible = "snps,dw-apb-uart"; + compatible = "ns16550"; reg = <0xd0012100 0x100>; reg-shift = <2>; interrupts = <42>; - reg-io-width = <4>; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/trunk/arch/arm/boot/dts/armada-xp-mv78230.dtsi index 271855a6e224..c45c7b4dc352 100644 --- a/trunk/arch/arm/boot/dts/armada-xp-mv78230.dtsi +++ b/trunk/arch/arm/boot/dts/armada-xp-mv78230.dtsi @@ -34,14 +34,7 @@ reg = <0>; clocks = <&cpuclk 0>; }; - - cpu@1 { - device_type = "cpu"; - compatible = "marvell,sheeva-v7"; - reg = <1>; - clocks = <&cpuclk 1>; - }; - }; + } soc { pinctrl { diff --git a/trunk/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/trunk/arch/arm/boot/dts/armada-xp-mv78260.dtsi index 1c1937dbce73..a2aee5707377 100644 --- a/trunk/arch/arm/boot/dts/armada-xp-mv78260.dtsi +++ b/trunk/arch/arm/boot/dts/armada-xp-mv78260.dtsi @@ -85,13 +85,5 @@ #interrupts-cells = <2>; interrupts = <24>; }; - - ethernet@d0034000 { - compatible = "marvell,armada-370-neta"; - reg = <0xd0034000 0x2500>; - interrupts = <14>; - clocks = <&gateclk 1>; - status = "disabled"; - }; }; }; diff --git a/trunk/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/trunk/arch/arm/boot/dts/armada-xp-mv78460.dtsi index 4905cf3a5ef8..da03a129243a 100644 --- a/trunk/arch/arm/boot/dts/armada-xp-mv78460.dtsi +++ b/trunk/arch/arm/boot/dts/armada-xp-mv78460.dtsi @@ -100,13 +100,5 @@ #interrupts-cells = <2>; interrupts = <24>; }; - - ethernet@d0034000 { - compatible = "marvell,armada-370-neta"; - reg = <0xd0034000 0x2500>; - interrupts = <14>; - clocks = <&gateclk 1>; - status = "disabled"; - }; }; }; diff --git a/trunk/arch/arm/boot/dts/armada-xp.dtsi b/trunk/arch/arm/boot/dts/armada-xp.dtsi index 2e37ef101c90..367aa3f94912 100644 --- a/trunk/arch/arm/boot/dts/armada-xp.dtsi +++ b/trunk/arch/arm/boot/dts/armada-xp.dtsi @@ -42,19 +42,17 @@ soc { serial@d0012200 { - compatible = "snps,dw-apb-uart"; + compatible = "ns16550"; reg = <0xd0012200 0x100>; reg-shift = <2>; interrupts = <43>; - reg-io-width = <4>; status = "disabled"; }; serial@d0012300 { - compatible = "snps,dw-apb-uart"; + compatible = "ns16550"; reg = <0xd0012300 0x100>; reg-shift = <2>; interrupts = <44>; - reg-io-width = <4>; status = "disabled"; }; @@ -95,6 +93,14 @@ status = "disabled"; }; + ethernet@d0034000 { + compatible = "marvell,armada-370-neta"; + reg = <0xd0034000 0x2500>; + interrupts = <14>; + clocks = <&gateclk 1>; + status = "disabled"; + }; + xor@d0060900 { compatible = "marvell,orion-xor"; reg = <0xd0060900 0x100 diff --git a/trunk/arch/arm/boot/dts/dove.dtsi b/trunk/arch/arm/boot/dts/dove.dtsi index 42eac1ff3cc8..f3f7e9d8adca 100644 --- a/trunk/arch/arm/boot/dts/dove.dtsi +++ b/trunk/arch/arm/boot/dts/dove.dtsi @@ -117,7 +117,6 @@ pinctrl: pinctrl@d0200 { compatible = "marvell,dove-pinctrl"; reg = <0xd0200 0x10>; - clocks = <&gate_clk 22>; }; spi0: spi@10600 { diff --git a/trunk/arch/arm/boot/dts/ecx-2000.dts b/trunk/arch/arm/boot/dts/ecx-2000.dts index 139b40cc3a23..46477ac1de99 100644 --- a/trunk/arch/arm/boot/dts/ecx-2000.dts +++ b/trunk/arch/arm/boot/dts/ecx-2000.dts @@ -32,7 +32,6 @@ cpu@0 { compatible = "arm,cortex-a15"; - device_type = "cpu"; reg = <0>; clocks = <&a9pll>; clock-names = "cpu"; @@ -40,7 +39,6 @@ cpu@1 { compatible = "arm,cortex-a15"; - device_type = "cpu"; reg = <1>; clocks = <&a9pll>; clock-names = "cpu"; @@ -48,7 +46,6 @@ cpu@2 { compatible = "arm,cortex-a15"; - device_type = "cpu"; reg = <2>; clocks = <&a9pll>; clock-names = "cpu"; @@ -56,7 +53,6 @@ cpu@3 { compatible = "arm,cortex-a15"; - device_type = "cpu"; reg = <3>; clocks = <&a9pll>; clock-names = "cpu"; diff --git a/trunk/arch/arm/boot/dts/exynos4210-smdkv310.dts b/trunk/arch/arm/boot/dts/exynos4210-smdkv310.dts index f63490707f3a..9b23a8255e39 100644 --- a/trunk/arch/arm/boot/dts/exynos4210-smdkv310.dts +++ b/trunk/arch/arm/boot/dts/exynos4210-smdkv310.dts @@ -26,7 +26,7 @@ }; chosen { - bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc"; + bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc"; }; sdhci@12530000 { diff --git a/trunk/arch/arm/boot/dts/exynos5250.dtsi b/trunk/arch/arm/boot/dts/exynos5250.dtsi index 3acf594ea60b..2e3b6efaf1a2 100644 --- a/trunk/arch/arm/boot/dts/exynos5250.dtsi +++ b/trunk/arch/arm/boot/dts/exynos5250.dtsi @@ -574,7 +574,7 @@ hdmi { compatible = "samsung,exynos5-hdmi"; - reg = <0x14530000 0x70000>; + reg = <0x14530000 0x100000>; interrupts = <0 95 0>; }; diff --git a/trunk/arch/arm/boot/dts/exynos5440-ssdk5440.dts b/trunk/arch/arm/boot/dts/exynos5440-ssdk5440.dts index 81e2c964a900..921c83cf694f 100644 --- a/trunk/arch/arm/boot/dts/exynos5440-ssdk5440.dts +++ b/trunk/arch/arm/boot/dts/exynos5440-ssdk5440.dts @@ -21,7 +21,7 @@ }; chosen { - bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x81000000,8M console=ttySAC0,115200 init=/linuxrc"; + bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x81000000,8M console=ttySAC2,115200 init=/linuxrc"; }; spi { diff --git a/trunk/arch/arm/boot/dts/highbank.dts b/trunk/arch/arm/boot/dts/highbank.dts index 5927a8df5625..a9ae5d32e80d 100644 --- a/trunk/arch/arm/boot/dts/highbank.dts +++ b/trunk/arch/arm/boot/dts/highbank.dts @@ -30,37 +30,33 @@ #address-cells = <1>; #size-cells = <0>; - cpu@900 { + cpu@0 { compatible = "arm,cortex-a9"; - device_type = "cpu"; - reg = <0x900>; + reg = <0>; next-level-cache = <&L2>; clocks = <&a9pll>; clock-names = "cpu"; }; - cpu@901 { + cpu@1 { compatible = "arm,cortex-a9"; - device_type = "cpu"; - reg = <0x901>; + reg = <1>; next-level-cache = <&L2>; clocks = <&a9pll>; clock-names = "cpu"; }; - cpu@902 { + cpu@2 { compatible = "arm,cortex-a9"; - device_type = "cpu"; - reg = <0x902>; + reg = <2>; next-level-cache = <&L2>; clocks = <&a9pll>; clock-names = "cpu"; }; - cpu@903 { + cpu@3 { compatible = "arm,cortex-a9"; - device_type = "cpu"; - reg = <0x903>; + reg = <3>; next-level-cache = <&L2>; clocks = <&a9pll>; clock-names = "cpu"; diff --git a/trunk/arch/arm/boot/dts/imx23-olinuxino.dts b/trunk/arch/arm/boot/dts/imx23-olinuxino.dts index e7484e4ea659..7c43b8e70b9f 100644 --- a/trunk/arch/arm/boot/dts/imx23-olinuxino.dts +++ b/trunk/arch/arm/boot/dts/imx23-olinuxino.dts @@ -39,17 +39,17 @@ hog_pins_a: hog@0 { reg = <0>; fsl,pinmux-ids = < - 0x0113 /* MX23_PAD_GPMI_ALE__GPIO_0_17 */ + 0x2013 /* MX23_PAD_SSP1_DETECT__GPIO_2_1 */ >; fsl,drive-strength = <0>; fsl,voltage = <1>; fsl,pull-up = <0>; }; - led_pin_gpio2_1: led_gpio2_1@0 { + led_pin_gpio0_17: led_gpio0_17@0 { reg = <0>; fsl,pinmux-ids = < - 0x2013 /* MX23_PAD_SSP1_DETECT__GPIO_2_1 */ + 0x0113 /* MX23_PAD_GPMI_ALE__GPIO_0_17 */ >; fsl,drive-strength = <0>; fsl,voltage = <1>; @@ -110,7 +110,7 @@ leds { compatible = "gpio-leds"; pinctrl-names = "default"; - pinctrl-0 = <&led_pin_gpio2_1>; + pinctrl-0 = <&led_pin_gpio0_17>; user { label = "green"; diff --git a/trunk/arch/arm/boot/dts/imx31-bug.dts b/trunk/arch/arm/boot/dts/imx31-bug.dts index 7f67402328d3..24731cb78e8e 100644 --- a/trunk/arch/arm/boot/dts/imx31-bug.dts +++ b/trunk/arch/arm/boot/dts/imx31-bug.dts @@ -14,7 +14,7 @@ / { model = "Buglabs i.MX31 Bug 1.x"; - compatible = "buglabs,imx31-bug", "fsl,imx31"; + compatible = "fsl,imx31-bug", "fsl,imx31"; memory { reg = <0x80000000 0x8000000>; /* 128M */ diff --git a/trunk/arch/arm/boot/dts/imx53.dtsi b/trunk/arch/arm/boot/dts/imx53.dtsi index edc3f1eb6699..552aed4ff982 100644 --- a/trunk/arch/arm/boot/dts/imx53.dtsi +++ b/trunk/arch/arm/boot/dts/imx53.dtsi @@ -492,7 +492,7 @@ compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan"; reg = <0x53fcc000 0x4000>; interrupts = <83>; - clocks = <&clks 87>, <&clks 86>; + clocks = <&clks 158>, <&clks 157>; clock-names = "ipg", "per"; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-6282.dtsi b/trunk/arch/arm/boot/dts/kirkwood-6282.dtsi index 4ccea2130a6c..9ae2004d5675 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-6282.dtsi +++ b/trunk/arch/arm/boot/dts/kirkwood-6282.dtsi @@ -39,7 +39,6 @@ #size-cells = <0>; interrupts = <32>; clock-frequency = <100000>; - clocks = <&gate_clk 7>; status = "disabled"; }; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-topkick.dts b/trunk/arch/arm/boot/dts/kirkwood-topkick.dts index cd15452a52a6..c0de5a7f660d 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-topkick.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-topkick.dts @@ -82,21 +82,4 @@ gpios = <&gpio1 16 1>; }; }; - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - sata0_power: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "SATA0 Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio1 4 0>; - }; - }; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood.dtsi b/trunk/arch/arm/boot/dts/kirkwood.dtsi index 110d6cbb795b..7735cee4a9c6 100644 --- a/trunk/arch/arm/boot/dts/kirkwood.dtsi +++ b/trunk/arch/arm/boot/dts/kirkwood.dtsi @@ -144,7 +144,6 @@ compatible = "marvell,orion-ehci"; reg = <0x50000 0x1000>; interrupts = <19>; - clocks = <&gate_clk 3>; status = "okay"; }; diff --git a/trunk/arch/arm/common/vic.c b/trunk/arch/arm/common/vic.c index 8f324b99416e..e4df17ca90c7 100644 --- a/trunk/arch/arm/common/vic.c +++ b/trunk/arch/arm/common/vic.c @@ -206,7 +206,6 @@ static void __init vic_register(void __iomem *base, unsigned int irq, struct device_node *node) { struct vic_device *v; - int i; if (vic_id >= ARRAY_SIZE(vic_devices)) { printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__); @@ -221,10 +220,6 @@ static void __init vic_register(void __iomem *base, unsigned int irq, vic_id++; v->domain = irq_domain_add_simple(node, fls(valid_sources), irq, &vic_irqdomain_ops, v); - /* create an IRQ mapping for each valid IRQ */ - for (i = 0; i < fls(valid_sources); i++) - if (valid_sources & (1 << i)) - irq_create_mapping(v->domain, i); } static void vic_ack_irq(struct irq_data *d) @@ -421,9 +416,9 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent) return -EIO; /* - * Passing 0 as first IRQ makes the simple domain allocate descriptors + * Passing -1 as first IRQ makes the simple domain allocate descriptors */ - __vic_init(regs, 0, ~0, ~0, node); + __vic_init(regs, -1, ~0, ~0, node); return 0; } diff --git a/trunk/arch/arm/configs/mvebu_defconfig b/trunk/arch/arm/configs/mvebu_defconfig index b5bc96cb65a7..a702fb345c01 100644 --- a/trunk/arch/arm/configs/mvebu_defconfig +++ b/trunk/arch/arm/configs/mvebu_defconfig @@ -33,7 +33,9 @@ CONFIG_MVNETA=y CONFIG_MARVELL_PHY=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_I2C=y +CONFIG_I2C_MV64XXX=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y # CONFIG_USB_SUPPORT is not set diff --git a/trunk/arch/arm/mach-exynos/Kconfig b/trunk/arch/arm/mach-exynos/Kconfig index e103c290bc9e..91d5b6f1d5af 100644 --- a/trunk/arch/arm/mach-exynos/Kconfig +++ b/trunk/arch/arm/mach-exynos/Kconfig @@ -74,8 +74,6 @@ config SOC_EXYNOS5440 depends on ARCH_EXYNOS5 select ARM_ARCH_TIMER select AUTO_ZRELADDR - select PINCTRL - select PINCTRL_EXYNOS5440 help Enable EXYNOS5440 SoC support diff --git a/trunk/arch/arm/mach-exynos/common.c b/trunk/arch/arm/mach-exynos/common.c index 1a89824a5f78..d6d0dc651089 100644 --- a/trunk/arch/arm/mach-exynos/common.c +++ b/trunk/arch/arm/mach-exynos/common.c @@ -424,18 +424,11 @@ static void __init exynos5_init_clocks(int xtal) { printk(KERN_DEBUG "%s: initializing clocks\n", __func__); - /* EXYNOS5440 can support only common clock framework */ - - if (soc_is_exynos5440()) - return; - -#ifdef CONFIG_SOC_EXYNOS5250 s3c24xx_register_baseclocks(xtal); s5p_register_clocks(xtal); exynos5_register_clocks(); exynos5_setup_clocks(); -#endif } #define COMBINER_ENABLE_SET 0x0 diff --git a/trunk/arch/arm/mach-highbank/highbank.c b/trunk/arch/arm/mach-highbank/highbank.c index 981dc1e1da51..dc248167d206 100644 --- a/trunk/arch/arm/mach-highbank/highbank.c +++ b/trunk/arch/arm/mach-highbank/highbank.c @@ -135,7 +135,7 @@ static struct sys_timer highbank_timer = { static void highbank_power_off(void) { - highbank_set_pwr_shutdown(); + hignbank_set_pwr_shutdown(); while (1) cpu_do_idle(); diff --git a/trunk/arch/arm/mach-highbank/hotplug.c b/trunk/arch/arm/mach-highbank/hotplug.c index f30c52843396..7b60faccd551 100644 --- a/trunk/arch/arm/mach-highbank/hotplug.c +++ b/trunk/arch/arm/mach-highbank/hotplug.c @@ -30,7 +30,7 @@ void __ref highbank_cpu_die(unsigned int cpu) { flush_cache_all(); - highbank_set_cpu_jump(cpu, phys_to_virt(0)); + highbank_set_cpu_jump(cpu, secondary_startup); highbank_set_core_pwr(); cpu_do_idle(); diff --git a/trunk/arch/arm/mach-highbank/platsmp.c b/trunk/arch/arm/mach-highbank/platsmp.c index 4ecc864ac8b9..1129957f6c1d 100644 --- a/trunk/arch/arm/mach-highbank/platsmp.c +++ b/trunk/arch/arm/mach-highbank/platsmp.c @@ -32,7 +32,6 @@ static void __cpuinit highbank_secondary_init(unsigned int cpu) static int __cpuinit highbank_boot_secondary(unsigned int cpu, struct task_struct *idle) { - highbank_set_cpu_jump(cpu, secondary_startup); gic_raise_softirq(cpumask_of(cpu), 0); return 0; } @@ -62,8 +61,19 @@ static void __init highbank_smp_init_cpus(void) static void __init highbank_smp_prepare_cpus(unsigned int max_cpus) { + int i; + if (scu_base_addr) scu_enable(scu_base_addr); + + /* + * Write the address of secondary startup into the jump table + * The cores are in wfi and wait until they receive a soft interrupt + * and a non-zero value to jump to. Then the secondary CPU branches + * to this address. + */ + for (i = 1; i < max_cpus; i++) + highbank_set_cpu_jump(i, secondary_startup); } struct smp_operations highbank_smp_ops __initdata = { diff --git a/trunk/arch/arm/mach-highbank/pm.c b/trunk/arch/arm/mach-highbank/pm.c index 04eddb4f4380..74aa135966f0 100644 --- a/trunk/arch/arm/mach-highbank/pm.c +++ b/trunk/arch/arm/mach-highbank/pm.c @@ -14,12 +14,10 @@ * this program. If not, see . */ -#include #include #include #include -#include #include #include @@ -28,31 +26,16 @@ static int highbank_suspend_finish(unsigned long val) { - outer_flush_all(); - outer_disable(); - - highbank_set_pwr_suspend(); - cpu_do_idle(); - - highbank_clear_pwr_request(); return 0; } static int highbank_pm_enter(suspend_state_t state) { - cpu_pm_enter(); - cpu_cluster_pm_enter(); - + hignbank_set_pwr_suspend(); highbank_set_cpu_jump(0, cpu_resume); cpu_suspend(0, highbank_suspend_finish); - cpu_cluster_pm_exit(); - cpu_pm_exit(); - - highbank_smc1(0x102, 0x1); - if (scu_base_addr) - scu_enable(scu_base_addr); return 0; } diff --git a/trunk/arch/arm/mach-highbank/sysregs.h b/trunk/arch/arm/mach-highbank/sysregs.h index 70af9d13fcef..e13e8ea7c6cb 100644 --- a/trunk/arch/arm/mach-highbank/sysregs.h +++ b/trunk/arch/arm/mach-highbank/sysregs.h @@ -44,43 +44,28 @@ static inline void highbank_set_core_pwr(void) writel_relaxed(1, sregs_base + SREG_CPU_PWR_CTRL(cpu)); } -static inline void highbank_clear_core_pwr(void) -{ - int cpu = cpu_logical_map(smp_processor_id()); - if (scu_base_addr) - scu_power_mode(scu_base_addr, SCU_PM_NORMAL); - else - writel_relaxed(0, sregs_base + SREG_CPU_PWR_CTRL(cpu)); -} - -static inline void highbank_set_pwr_suspend(void) +static inline void hignbank_set_pwr_suspend(void) { writel(HB_PWR_SUSPEND, sregs_base + HB_SREG_A9_PWR_REQ); highbank_set_core_pwr(); } -static inline void highbank_set_pwr_shutdown(void) +static inline void hignbank_set_pwr_shutdown(void) { writel(HB_PWR_SHUTDOWN, sregs_base + HB_SREG_A9_PWR_REQ); highbank_set_core_pwr(); } -static inline void highbank_set_pwr_soft_reset(void) +static inline void hignbank_set_pwr_soft_reset(void) { writel(HB_PWR_SOFT_RESET, sregs_base + HB_SREG_A9_PWR_REQ); highbank_set_core_pwr(); } -static inline void highbank_set_pwr_hard_reset(void) +static inline void hignbank_set_pwr_hard_reset(void) { writel(HB_PWR_HARD_RESET, sregs_base + HB_SREG_A9_PWR_REQ); highbank_set_core_pwr(); } -static inline void highbank_clear_pwr_request(void) -{ - writel(~0UL, sregs_base + HB_SREG_A9_PWR_REQ); - highbank_clear_core_pwr(); -} - #endif diff --git a/trunk/arch/arm/mach-highbank/system.c b/trunk/arch/arm/mach-highbank/system.c index 37d8384dcf19..aed96ad9bd4a 100644 --- a/trunk/arch/arm/mach-highbank/system.c +++ b/trunk/arch/arm/mach-highbank/system.c @@ -22,9 +22,9 @@ void highbank_restart(char mode, const char *cmd) { if (mode == 'h') - highbank_set_pwr_hard_reset(); + hignbank_set_pwr_hard_reset(); else - highbank_set_pwr_soft_reset(); + hignbank_set_pwr_soft_reset(); while (1) cpu_do_idle(); diff --git a/trunk/arch/arm/mach-imx/Kconfig b/trunk/arch/arm/mach-imx/Kconfig index 3e628fd7a674..1ad0d76de8c7 100644 --- a/trunk/arch/arm/mach-imx/Kconfig +++ b/trunk/arch/arm/mach-imx/Kconfig @@ -841,6 +841,8 @@ config SOC_IMX6Q select ARCH_HAS_CPUFREQ select ARCH_HAS_OPP select ARM_CPU_SUSPEND if PM + select ARM_ERRATA_743622 + select ARM_ERRATA_751472 select ARM_ERRATA_754322 select ARM_ERRATA_764369 if SMP select ARM_ERRATA_775420 diff --git a/trunk/arch/arm/mach-kirkwood/board-dt.c b/trunk/arch/arm/mach-kirkwood/board-dt.c index de4fd2bb1e27..ff4150a2ad05 100644 --- a/trunk/arch/arm/mach-kirkwood/board-dt.c +++ b/trunk/arch/arm/mach-kirkwood/board-dt.c @@ -67,10 +67,6 @@ static void __init kirkwood_legacy_clk_init(void) orion_clkdev_add(NULL, "mv643xx_eth_port.1", of_clk_get_from_provider(&clkspec)); - clkspec.args[0] = CGC_BIT_SDIO; - orion_clkdev_add(NULL, "mvsdio", - of_clk_get_from_provider(&clkspec)); - } static void __init kirkwood_of_clk_init(void) diff --git a/trunk/arch/arm/mach-kirkwood/board-usi_topkick.c b/trunk/arch/arm/mach-kirkwood/board-usi_topkick.c index 23d2dd1b1b1e..15e69fcde9f4 100644 --- a/trunk/arch/arm/mach-kirkwood/board-usi_topkick.c +++ b/trunk/arch/arm/mach-kirkwood/board-usi_topkick.c @@ -64,6 +64,8 @@ static unsigned int topkick_mpp_config[] __initdata = { 0 }; +#define TOPKICK_SATA0_PWR_ENABLE 36 + void __init usi_topkick_init(void) { /* @@ -71,6 +73,8 @@ void __init usi_topkick_init(void) */ kirkwood_mpp_conf(topkick_mpp_config); + /* SATA0 power enable */ + gpio_set_value(TOPKICK_SATA0_PWR_ENABLE, 1); kirkwood_ge00_init(&topkick_ge00_data); kirkwood_sdio_init(&topkick_mvsdio_data); diff --git a/trunk/arch/arm/mach-nomadik/board-nhk8815.c b/trunk/arch/arm/mach-nomadik/board-nhk8815.c index 9f19069248da..98167a4319f7 100644 --- a/trunk/arch/arm/mach-nomadik/board-nhk8815.c +++ b/trunk/arch/arm/mach-nomadik/board-nhk8815.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/arm/mach-nomadik/include/mach/irqs.h b/trunk/arch/arm/mach-nomadik/include/mach/irqs.h index 215f8cdb4004..b549d0571548 100644 --- a/trunk/arch/arm/mach-nomadik/include/mach/irqs.h +++ b/trunk/arch/arm/mach-nomadik/include/mach/irqs.h @@ -22,49 +22,49 @@ #include -#define IRQ_VIC_START 32 /* first VIC interrupt is 1 */ +#define IRQ_VIC_START 1 /* first VIC interrupt is 1 */ /* * Interrupt numbers generic for all Nomadik Chip cuts */ -#define IRQ_WATCHDOG (IRQ_VIC_START+0) -#define IRQ_SOFTINT (IRQ_VIC_START+1) -#define IRQ_CRYPTO (IRQ_VIC_START+2) -#define IRQ_OWM (IRQ_VIC_START+3) -#define IRQ_MTU0 (IRQ_VIC_START+4) -#define IRQ_MTU1 (IRQ_VIC_START+5) -#define IRQ_GPIO0 (IRQ_VIC_START+6) -#define IRQ_GPIO1 (IRQ_VIC_START+7) -#define IRQ_GPIO2 (IRQ_VIC_START+8) -#define IRQ_GPIO3 (IRQ_VIC_START+9) -#define IRQ_RTC_RTT (IRQ_VIC_START+10) -#define IRQ_SSP (IRQ_VIC_START+11) -#define IRQ_UART0 (IRQ_VIC_START+12) -#define IRQ_DMA1 (IRQ_VIC_START+13) -#define IRQ_CLCD_MDIF (IRQ_VIC_START+14) -#define IRQ_DMA0 (IRQ_VIC_START+15) -#define IRQ_PWRFAIL (IRQ_VIC_START+16) -#define IRQ_UART1 (IRQ_VIC_START+17) -#define IRQ_FIRDA (IRQ_VIC_START+18) -#define IRQ_MSP0 (IRQ_VIC_START+19) -#define IRQ_I2C0 (IRQ_VIC_START+20) -#define IRQ_I2C1 (IRQ_VIC_START+21) -#define IRQ_SDMMC (IRQ_VIC_START+22) -#define IRQ_USBOTG (IRQ_VIC_START+23) -#define IRQ_SVA_IT0 (IRQ_VIC_START+24) -#define IRQ_SVA_IT1 (IRQ_VIC_START+25) -#define IRQ_SAA_IT0 (IRQ_VIC_START+26) -#define IRQ_SAA_IT1 (IRQ_VIC_START+27) -#define IRQ_UART2 (IRQ_VIC_START+28) -#define IRQ_MSP2 (IRQ_VIC_START+29) -#define IRQ_L2CC (IRQ_VIC_START+30) -#define IRQ_HPI (IRQ_VIC_START+31) -#define IRQ_SKE (IRQ_VIC_START+32) -#define IRQ_KP (IRQ_VIC_START+33) -#define IRQ_MEMST (IRQ_VIC_START+34) -#define IRQ_SGA_IT (IRQ_VIC_START+35) -#define IRQ_USBM (IRQ_VIC_START+36) -#define IRQ_MSP1 (IRQ_VIC_START+37) +#define IRQ_WATCHDOG 1 +#define IRQ_SOFTINT 2 +#define IRQ_CRYPTO 3 +#define IRQ_OWM 4 +#define IRQ_MTU0 5 +#define IRQ_MTU1 6 +#define IRQ_GPIO0 7 +#define IRQ_GPIO1 8 +#define IRQ_GPIO2 9 +#define IRQ_GPIO3 10 +#define IRQ_RTC_RTT 11 +#define IRQ_SSP 12 +#define IRQ_UART0 13 +#define IRQ_DMA1 14 +#define IRQ_CLCD_MDIF 15 +#define IRQ_DMA0 16 +#define IRQ_PWRFAIL 17 +#define IRQ_UART1 18 +#define IRQ_FIRDA 19 +#define IRQ_MSP0 20 +#define IRQ_I2C0 21 +#define IRQ_I2C1 22 +#define IRQ_SDMMC 23 +#define IRQ_USBOTG 24 +#define IRQ_SVA_IT0 25 +#define IRQ_SVA_IT1 26 +#define IRQ_SAA_IT0 27 +#define IRQ_SAA_IT1 28 +#define IRQ_UART2 29 +#define IRQ_MSP2 30 +#define IRQ_L2CC 49 +#define IRQ_HPI 50 +#define IRQ_SKE 51 +#define IRQ_KP 52 +#define IRQ_MEMST 55 +#define IRQ_SGA_IT 59 +#define IRQ_USBM 61 +#define IRQ_MSP1 63 #define NOMADIK_GPIO_OFFSET (IRQ_VIC_START+64) diff --git a/trunk/arch/arm/mach-omap1/board-ams-delta.c b/trunk/arch/arm/mach-omap1/board-ams-delta.c index 2e98a3ac7c5e..a8fce3ccc707 100644 --- a/trunk/arch/arm/mach-omap1/board-ams-delta.c +++ b/trunk/arch/arm/mach-omap1/board-ams-delta.c @@ -160,7 +160,7 @@ static struct omap_lcd_config ams_delta_lcd_config __initdata = { .ctrl_name = "internal", }; -static struct omap_usb_config ams_delta_usb_config __initdata = { +static struct omap_usb_config ams_delta_usb_config = { .register_host = 1, .hmc_mode = 16, .pins[0] = 2, diff --git a/trunk/arch/arm/mach-omap1/usb.c b/trunk/arch/arm/mach-omap1/usb.c index 1a1db5971cd9..104fed366b8f 100644 --- a/trunk/arch/arm/mach-omap1/usb.c +++ b/trunk/arch/arm/mach-omap1/usb.c @@ -629,14 +629,8 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config) static inline void omap_1510_usb_init(struct omap_usb_config *config) {} #endif -void __init omap1_usb_init(struct omap_usb_config *_pdata) +void __init omap1_usb_init(struct omap_usb_config *pdata) { - struct omap_usb_config *pdata; - - pdata = kmemdup(_pdata, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return; - pdata->usb0_init = omap1_usb0_init; pdata->usb1_init = omap1_usb1_init; pdata->usb2_init = omap1_usb2_init; diff --git a/trunk/arch/arm/mach-omap2/cclock3xxx_data.c b/trunk/arch/arm/mach-omap2/cclock3xxx_data.c index 6ef87580c33f..bdf39481fbd6 100644 --- a/trunk/arch/arm/mach-omap2/cclock3xxx_data.c +++ b/trunk/arch/arm/mach-omap2/cclock3xxx_data.c @@ -1167,8 +1167,6 @@ static const struct clk_ops emu_src_ck_ops = { .recalc_rate = &omap2_clksel_recalc, .get_parent = &omap2_clksel_find_parent_index, .set_parent = &omap2_clksel_set_parent, - .enable = &omap2_clkops_enable_clkdm, - .disable = &omap2_clkops_disable_clkdm, }; static struct clk emu_src_ck; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 646c14d9fdb9..081c71edddf4 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -2070,7 +2070,7 @@ static struct omap_hwmod_irq_info am33xx_usbss_mpu_irqs[] = { { .name = "usbss-irq", .irq = 17 + OMAP_INTC_START, }, { .name = "musb0-irq", .irq = 18 + OMAP_INTC_START, }, { .name = "musb1-irq", .irq = 19 + OMAP_INTC_START, }, - { .irq = -1, }, + { .irq = -1 + OMAP_INTC_START, }, }; static struct omap_hwmod am33xx_usbss_hwmod = { @@ -2515,7 +2515,7 @@ static struct omap_hwmod_ocp_if am33xx_l4_hs__cpgmac0 = { .user = OCP_USER_MPU, }; -static struct omap_hwmod_addr_space am33xx_mdio_addr_space[] = { +struct omap_hwmod_addr_space am33xx_mdio_addr_space[] = { { .pa_start = 0x4A101000, .pa_end = 0x4A101000 + SZ_256 - 1, @@ -2523,7 +2523,7 @@ static struct omap_hwmod_addr_space am33xx_mdio_addr_space[] = { { } }; -static struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio = { +struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio = { .master = &am33xx_cpgmac0_hwmod, .slave = &am33xx_mdio_hwmod, .addr = am33xx_mdio_addr_space, diff --git a/trunk/arch/arm/mach-omap2/prm2xxx.c b/trunk/arch/arm/mach-omap2/prm2xxx.c index 418de9c3b319..cc0e71430af1 100644 --- a/trunk/arch/arm/mach-omap2/prm2xxx.c +++ b/trunk/arch/arm/mach-omap2/prm2xxx.c @@ -27,14 +27,6 @@ #include "cm2xxx_3xxx.h" #include "prm-regbits-24xx.h" -/* - * OMAP24xx PM_PWSTCTRL_*.POWERSTATE and PM_PWSTST_*.LASTSTATEENTERED bits - - * these are reversed from the bits used on OMAP3+ - */ -#define OMAP24XX_PWRDM_POWER_ON 0x0 -#define OMAP24XX_PWRDM_POWER_RET 0x1 -#define OMAP24XX_PWRDM_POWER_OFF 0x3 - /* * omap2xxx_prm_reset_src_map - map from bits in the PRM_RSTST_WKUP * hardware register (which are specific to the OMAP2xxx SoCs) to @@ -75,34 +67,6 @@ static u32 omap2xxx_prm_read_reset_sources(void) return r; } -/** - * omap2xxx_pwrst_to_common_pwrst - convert OMAP2xxx pwrst to common pwrst - * @omap2xxx_pwrst: OMAP2xxx hardware power state to convert - * - * Return the common power state bits corresponding to the OMAP2xxx - * hardware power state bits @omap2xxx_pwrst, or -EINVAL upon error. - */ -static int omap2xxx_pwrst_to_common_pwrst(u8 omap2xxx_pwrst) -{ - u8 pwrst; - - switch (omap2xxx_pwrst) { - case OMAP24XX_PWRDM_POWER_OFF: - pwrst = PWRDM_POWER_OFF; - break; - case OMAP24XX_PWRDM_POWER_RET: - pwrst = PWRDM_POWER_RET; - break; - case OMAP24XX_PWRDM_POWER_ON: - pwrst = PWRDM_POWER_ON; - break; - default: - return -EINVAL; - } - - return pwrst; -} - /** * omap2xxx_prm_dpll_reset - use DPLL reset to reboot the OMAP SoC * @@ -133,56 +97,10 @@ int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm) return 0; } -static int omap2xxx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) -{ - u8 omap24xx_pwrst; - - switch (pwrst) { - case PWRDM_POWER_OFF: - omap24xx_pwrst = OMAP24XX_PWRDM_POWER_OFF; - break; - case PWRDM_POWER_RET: - omap24xx_pwrst = OMAP24XX_PWRDM_POWER_RET; - break; - case PWRDM_POWER_ON: - omap24xx_pwrst = OMAP24XX_PWRDM_POWER_ON; - break; - default: - return -EINVAL; - } - - omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK, - (omap24xx_pwrst << OMAP_POWERSTATE_SHIFT), - pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL); - return 0; -} - -static int omap2xxx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) -{ - u8 omap2xxx_pwrst; - - omap2xxx_pwrst = omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, - OMAP2_PM_PWSTCTRL, - OMAP_POWERSTATE_MASK); - - return omap2xxx_pwrst_to_common_pwrst(omap2xxx_pwrst); -} - -static int omap2xxx_pwrdm_read_pwrst(struct powerdomain *pwrdm) -{ - u8 omap2xxx_pwrst; - - omap2xxx_pwrst = omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, - OMAP2_PM_PWSTST, - OMAP_POWERSTATEST_MASK); - - return omap2xxx_pwrst_to_common_pwrst(omap2xxx_pwrst); -} - struct pwrdm_ops omap2_pwrdm_operations = { - .pwrdm_set_next_pwrst = omap2xxx_pwrdm_set_next_pwrst, - .pwrdm_read_next_pwrst = omap2xxx_pwrdm_read_next_pwrst, - .pwrdm_read_pwrst = omap2xxx_pwrdm_read_pwrst, + .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst, + .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst, + .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst, .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst, .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst, .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst, diff --git a/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c b/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c index a3e121f94a86..30517f5af707 100644 --- a/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c @@ -103,6 +103,28 @@ int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift) /* Powerdomain low-level functions */ /* Common functions across OMAP2 and OMAP3 */ +int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) +{ + omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK, + (pwrst << OMAP_POWERSTATE_SHIFT), + pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL); + return 0; +} + +int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) +{ + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + OMAP2_PM_PWSTCTRL, + OMAP_POWERSTATE_MASK); +} + +int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm) +{ + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + OMAP2_PM_PWSTST, + OMAP_POWERSTATEST_MASK); +} + int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) { diff --git a/trunk/arch/arm/mach-omap2/prm3xxx.c b/trunk/arch/arm/mach-omap2/prm3xxx.c index e648bd55b072..39822aabcff3 100644 --- a/trunk/arch/arm/mach-omap2/prm3xxx.c +++ b/trunk/arch/arm/mach-omap2/prm3xxx.c @@ -277,28 +277,6 @@ static u32 omap3xxx_prm_read_reset_sources(void) /* Powerdomain low-level functions */ -static int omap3_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) -{ - omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK, - (pwrst << OMAP_POWERSTATE_SHIFT), - pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL); - return 0; -} - -static int omap3_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) -{ - return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, - OMAP2_PM_PWSTCTRL, - OMAP_POWERSTATE_MASK); -} - -static int omap3_pwrdm_read_pwrst(struct powerdomain *pwrdm) -{ - return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, - OMAP2_PM_PWSTST, - OMAP_POWERSTATEST_MASK); -} - /* Applicable only for OMAP3. Not supported on OMAP2 */ static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) { @@ -377,9 +355,9 @@ static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm) } struct pwrdm_ops omap3_pwrdm_operations = { - .pwrdm_set_next_pwrst = omap3_pwrdm_set_next_pwrst, - .pwrdm_read_next_pwrst = omap3_pwrdm_read_next_pwrst, - .pwrdm_read_pwrst = omap3_pwrdm_read_pwrst, + .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst, + .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst, + .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst, .pwrdm_read_prev_pwrst = omap3_pwrdm_read_prev_pwrst, .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst, .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst, diff --git a/trunk/arch/arm/mach-omap2/prm44xx.c b/trunk/arch/arm/mach-omap2/prm44xx.c index c05a343d465d..7498bc77fe8b 100644 --- a/trunk/arch/arm/mach-omap2/prm44xx.c +++ b/trunk/arch/arm/mach-omap2/prm44xx.c @@ -56,9 +56,9 @@ static struct omap_prcm_irq_setup omap4_prcm_irq_setup = { * enumeration) */ static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = { - { OMAP4430_GLOBAL_WARM_SW_RST_SHIFT, + { OMAP4430_RST_GLOBAL_WARM_SW_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT }, - { OMAP4430_GLOBAL_COLD_RST_SHIFT, + { OMAP4430_RST_GLOBAL_COLD_SW_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT }, { OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT }, @@ -333,7 +333,7 @@ static u32 omap44xx_prm_read_reset_sources(void) u32 r = 0; u32 v; - v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, + v = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, OMAP4_RM_RSTST); p = omap44xx_prm_reset_src_map; diff --git a/trunk/arch/arm/mach-omap2/prm44xx.h b/trunk/arch/arm/mach-omap2/prm44xx.h index 8ee1fbdec561..22b0979206ca 100644 --- a/trunk/arch/arm/mach-omap2/prm44xx.h +++ b/trunk/arch/arm/mach-omap2/prm44xx.h @@ -62,8 +62,8 @@ /* OMAP4 specific register offsets */ #define OMAP4_RM_RSTCTRL 0x0000 -#define OMAP4_RM_RSTST 0x0004 -#define OMAP4_RM_RSTTIME 0x0008 +#define OMAP4_RM_RSTTIME 0x0004 +#define OMAP4_RM_RSTST 0x0008 #define OMAP4_PM_PWSTCTRL 0x0000 #define OMAP4_PM_PWSTST 0x0004 diff --git a/trunk/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h b/trunk/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h index b6132aa95dc0..a611ad3153c7 100644 --- a/trunk/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h +++ b/trunk/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h @@ -463,9 +463,6 @@ GPIO76_LCD_PCLK, \ GPIO77_LCD_BIAS -/* these enable a work-around for a hw bug in pxa27x during ac97 warm reset */ -#define GPIO113_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO113, AF0, DEFAULT) -#define GPIO95_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO95, AF0, DEFAULT) extern int keypad_set_wake(unsigned int on); #endif /* __ASM_ARCH_MFP_PXA27X_H */ diff --git a/trunk/arch/arm/mach-pxa/pxa27x.c b/trunk/arch/arm/mach-pxa/pxa27x.c index 616cb87b6179..8047ee0effc5 100644 --- a/trunk/arch/arm/mach-pxa/pxa27x.c +++ b/trunk/arch/arm/mach-pxa/pxa27x.c @@ -47,9 +47,9 @@ void pxa27x_clear_otgph(void) EXPORT_SYMBOL(pxa27x_clear_otgph); static unsigned long ac97_reset_config[] = { - GPIO113_AC97_nRESET_GPIO_HIGH, + GPIO113_GPIO, GPIO113_AC97_nRESET, - GPIO95_AC97_nRESET_GPIO_HIGH, + GPIO95_GPIO, GPIO95_AC97_nRESET, }; diff --git a/trunk/arch/arm/mach-versatile/include/mach/irqs.h b/trunk/arch/arm/mach-versatile/include/mach/irqs.h index 0fd771ca617b..bf44c61bd1f6 100644 --- a/trunk/arch/arm/mach-versatile/include/mach/irqs.h +++ b/trunk/arch/arm/mach-versatile/include/mach/irqs.h @@ -25,7 +25,7 @@ * IRQ interrupts definitions are the same as the INT definitions * held within platform.h */ -#define IRQ_VIC_START 32 +#define IRQ_VIC_START 0 #define IRQ_WDOGINT (IRQ_VIC_START + INT_WDOGINT) #define IRQ_SOFTINT (IRQ_VIC_START + INT_SOFTINT) #define IRQ_COMMRx (IRQ_VIC_START + INT_COMMRx) @@ -100,7 +100,7 @@ /* * Secondary interrupt controller */ -#define IRQ_SIC_START 64 +#define IRQ_SIC_START 32 #define IRQ_SIC_MMCI0B (IRQ_SIC_START + SIC_INT_MMCI0B) #define IRQ_SIC_MMCI1B (IRQ_SIC_START + SIC_INT_MMCI1B) #define IRQ_SIC_KMI0 (IRQ_SIC_START + SIC_INT_KMI0) @@ -120,7 +120,7 @@ #define IRQ_SIC_PCI1 (IRQ_SIC_START + SIC_INT_PCI1) #define IRQ_SIC_PCI2 (IRQ_SIC_START + SIC_INT_PCI2) #define IRQ_SIC_PCI3 (IRQ_SIC_START + SIC_INT_PCI3) -#define IRQ_SIC_END 95 +#define IRQ_SIC_END 63 #define IRQ_GPIO0_START (IRQ_SIC_END + 1) #define IRQ_GPIO0_END (IRQ_GPIO0_START + 31) diff --git a/trunk/arch/arm/mach-vexpress/Kconfig b/trunk/arch/arm/mach-vexpress/Kconfig index 52d315b792c8..99e63f5f99d1 100644 --- a/trunk/arch/arm/mach-vexpress/Kconfig +++ b/trunk/arch/arm/mach-vexpress/Kconfig @@ -42,6 +42,7 @@ config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA bool "Enable A5 and A9 only errata work-arounds" default y select ARM_ERRATA_720789 + select ARM_ERRATA_751472 select PL310_ERRATA_753970 if CACHE_PL310 help Provides common dependencies for Versatile Express platforms diff --git a/trunk/arch/arm/mm/cache-l2x0.c b/trunk/arch/arm/mm/cache-l2x0.c index c2f37390308a..6911b8b2745c 100644 --- a/trunk/arch/arm/mm/cache-l2x0.c +++ b/trunk/arch/arm/mm/cache-l2x0.c @@ -352,8 +352,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) /* Unmapped register. */ sync_reg_offset = L2X0_DUMMY_REG; #endif - if ((cache_id & L2X0_CACHE_ID_RTL_MASK) <= L2X0_CACHE_ID_RTL_R3P0) - outer_cache.set_debug = pl310_set_debug; + outer_cache.set_debug = pl310_set_debug; break; case L2X0_CACHE_ID_PART_L210: ways = (aux >> 13) & 0xf; @@ -460,8 +459,8 @@ static void aurora_pa_range(unsigned long start, unsigned long end, unsigned long flags; raw_spin_lock_irqsave(&l2x0_lock, flags); - writel_relaxed(start, l2x0_base + AURORA_RANGE_BASE_ADDR_REG); - writel_relaxed(end, l2x0_base + offset); + writel(start, l2x0_base + AURORA_RANGE_BASE_ADDR_REG); + writel(end, l2x0_base + offset); raw_spin_unlock_irqrestore(&l2x0_lock, flags); cache_sync(); @@ -506,21 +505,15 @@ static void aurora_clean_range(unsigned long start, unsigned long end) static void aurora_flush_range(unsigned long start, unsigned long end) { - start &= ~(CACHE_LINE_SIZE - 1); - end = ALIGN(end, CACHE_LINE_SIZE); - while (start != end) { - unsigned long range_end = calc_range_end(start, end); - /* - * If L2 is forced to WT, the L2 will always be clean and we - * just need to invalidate. - */ - if (l2_wt_override) - aurora_pa_range(start, range_end - CACHE_LINE_SIZE, - AURORA_INVAL_RANGE_REG); - else + if (!l2_wt_override) { + start &= ~(CACHE_LINE_SIZE - 1); + end = ALIGN(end, CACHE_LINE_SIZE); + while (start != end) { + unsigned long range_end = calc_range_end(start, end); aurora_pa_range(start, range_end - CACHE_LINE_SIZE, - AURORA_FLUSH_RANGE_REG); - start = range_end; + AURORA_FLUSH_RANGE_REG); + start = range_end; + } } } @@ -675,9 +668,8 @@ static void pl310_resume(void) static void aurora_resume(void) { if (!(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) { - writel_relaxed(l2x0_saved_regs.aux_ctrl, - l2x0_base + L2X0_AUX_CTRL); - writel_relaxed(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL); + writel(l2x0_saved_regs.aux_ctrl, l2x0_base + L2X0_AUX_CTRL); + writel(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL); } } diff --git a/trunk/arch/arm/mm/proc-v7.S b/trunk/arch/arm/mm/proc-v7.S index 3a3c015f8d5c..350f6a74992b 100644 --- a/trunk/arch/arm/mm/proc-v7.S +++ b/trunk/arch/arm/mm/proc-v7.S @@ -169,7 +169,6 @@ __v7_ca15mp_setup: orreq r0, r0, r10 @ Enable CPU-specific SMP bits mcreq p15, 0, r0, c1, c0, 1 #endif - b __v7_setup __v7_pj4b_setup: #ifdef CONFIG_CPU_PJ4B @@ -246,8 +245,7 @@ __v7_setup: ldr r10, =0x00000c08 @ Cortex-A8 primary part number teq r0, r10 bne 2f -#if defined(CONFIG_ARM_ERRATA_430973) && !defined(CONFIG_ARCH_MULTIPLATFORM) - +#ifdef CONFIG_ARM_ERRATA_430973 teq r5, #0x00100000 @ only present in r1p* mrceq p15, 0, r10, c1, c0, 1 @ read aux control register orreq r10, r10, #(1 << 6) @ set IBE to 1 diff --git a/trunk/arch/arm/plat-omap/counter_32k.c b/trunk/arch/arm/plat-omap/counter_32k.c index 5b0b86bb34bb..f3771cdb9838 100644 --- a/trunk/arch/arm/plat-omap/counter_32k.c +++ b/trunk/arch/arm/plat-omap/counter_32k.c @@ -22,8 +22,6 @@ #include #include -#include - /* OMAP2_32KSYNCNT_CR_OFF: offset of 32ksync counter register */ #define OMAP2_32KSYNCNT_REV_OFF 0x0 #define OMAP2_32KSYNCNT_REV_SCHEME (0x3 << 30) diff --git a/trunk/arch/arm/plat-omap/sram.c b/trunk/arch/arm/plat-omap/sram.c index a5bc92d7e476..743fc2836f7a 100644 --- a/trunk/arch/arm/plat-omap/sram.c +++ b/trunk/arch/arm/plat-omap/sram.c @@ -26,8 +26,6 @@ #include -#include - #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) static void __iomem *omap_sram_base; diff --git a/trunk/arch/arm/plat-samsung/include/plat/cpu.h b/trunk/arch/arm/plat-samsung/include/plat/cpu.h index b69e11dc679d..e0072ce8d6e9 100644 --- a/trunk/arch/arm/plat-samsung/include/plat/cpu.h +++ b/trunk/arch/arm/plat-samsung/include/plat/cpu.h @@ -43,7 +43,7 @@ extern unsigned long samsung_cpu_id; #define EXYNOS4_CPU_MASK 0xFFFE0000 #define EXYNOS5250_SOC_ID 0x43520000 -#define EXYNOS5440_SOC_ID 0xE5440000 +#define EXYNOS5440_SOC_ID 0x54400000 #define EXYNOS5_SOC_MASK 0xFFFFF000 #define IS_SAMSUNG_CPU(name, id, mask) \ diff --git a/trunk/arch/arm64/boot/dts/Makefile b/trunk/arch/arm64/boot/dts/Makefile index 32ac0aef0068..801e2d7fcbc6 100644 --- a/trunk/arch/arm64/boot/dts/Makefile +++ b/trunk/arch/arm64/boot/dts/Makefile @@ -1,5 +1,4 @@ targets += dtbs -targets += $(dtb-y) dtbs: $(addprefix $(obj)/, $(dtb-y)) diff --git a/trunk/arch/mn10300/Kconfig b/trunk/arch/mn10300/Kconfig index e70001cfa05b..aa03f2e13385 100644 --- a/trunk/arch/mn10300/Kconfig +++ b/trunk/arch/mn10300/Kconfig @@ -6,7 +6,6 @@ config MN10300 select ARCH_WANT_IPC_PARSE_VERSION select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_KGDB - select GENERIC_ATOMIC64 select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER select GENERIC_CLOCKEVENTS select MODULES_USE_ELF_RELA diff --git a/trunk/arch/powerpc/include/uapi/asm/kvm_para.h b/trunk/arch/powerpc/include/uapi/asm/kvm_para.h index e3af3286a068..ed0e0254b47f 100644 --- a/trunk/arch/powerpc/include/uapi/asm/kvm_para.h +++ b/trunk/arch/powerpc/include/uapi/asm/kvm_para.h @@ -78,7 +78,7 @@ struct kvm_vcpu_arch_shared { #define KVM_HCALL_TOKEN(num) _EV_HCALL_TOKEN(EV_KVM_VENDOR_ID, num) -#include +#include #define KVM_FEATURE_MAGIC_PAGE 1 diff --git a/trunk/arch/powerpc/kvm/book3s_hv_ras.c b/trunk/arch/powerpc/kvm/book3s_hv_ras.c index a353c485808c..35f3cf0269b3 100644 --- a/trunk/arch/powerpc/kvm/book3s_hv_ras.c +++ b/trunk/arch/powerpc/kvm/book3s_hv_ras.c @@ -79,9 +79,7 @@ static void flush_tlb_power7(struct kvm_vcpu *vcpu) static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu) { unsigned long srr1 = vcpu->arch.shregs.msr; -#ifdef CONFIG_PPC_POWERNV struct opal_machine_check_event *opal_evt; -#endif long handled = 1; if (srr1 & SRR1_MC_LDSTERR) { @@ -119,7 +117,6 @@ static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu) handled = 0; } -#ifdef CONFIG_PPC_POWERNV /* * See if OPAL has already handled the condition. * We assume that if the condition is recovered then OPAL @@ -134,7 +131,6 @@ static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu) if (handled) opal_evt->in_use = 0; -#endif return handled; } diff --git a/trunk/arch/s390/include/asm/dma.h b/trunk/arch/s390/include/asm/dma.h index bb9bdcd20864..de015d85e3e5 100644 --- a/trunk/arch/s390/include/asm/dma.h +++ b/trunk/arch/s390/include/asm/dma.h @@ -10,10 +10,4 @@ */ #define MAX_DMA_ADDRESS 0x80000000 -#ifdef CONFIG_PCI -extern int isa_dma_bridge_buggy; -#else -#define isa_dma_bridge_buggy (0) -#endif - #endif /* _ASM_S390_DMA_H */ diff --git a/trunk/arch/s390/include/asm/io.h b/trunk/arch/s390/include/asm/io.h index 27cb32185ce1..16c3eb164f4f 100644 --- a/trunk/arch/s390/include/asm/io.h +++ b/trunk/arch/s390/include/asm/io.h @@ -85,11 +85,6 @@ static inline void iounmap(volatile void __iomem *addr) #define __raw_writel zpci_write_u32 #define __raw_writeq zpci_write_u64 -#define readb_relaxed readb -#define readw_relaxed readw -#define readl_relaxed readl -#define readq_relaxed readq - #endif /* CONFIG_PCI */ #include diff --git a/trunk/arch/s390/include/asm/irq.h b/trunk/arch/s390/include/asm/irq.h index 7def77302d63..e6972f85d2b0 100644 --- a/trunk/arch/s390/include/asm/irq.h +++ b/trunk/arch/s390/include/asm/irq.h @@ -2,61 +2,43 @@ #define _ASM_IRQ_H #include -#include -#include #include -enum interruption_main_class { +enum interruption_class { EXTERNAL_INTERRUPT, IO_INTERRUPT, - NR_IRQS -}; - -enum interruption_class { - IRQEXT_CLK, - IRQEXT_EXC, - IRQEXT_EMS, - IRQEXT_TMR, - IRQEXT_TLA, - IRQEXT_PFL, - IRQEXT_DSD, - IRQEXT_VRT, - IRQEXT_SCP, - IRQEXT_IUC, - IRQEXT_CMS, - IRQEXT_CMC, - IRQEXT_CMR, - IRQIO_CIO, - IRQIO_QAI, - IRQIO_DAS, - IRQIO_C15, - IRQIO_C70, - IRQIO_TAP, - IRQIO_VMR, - IRQIO_LCS, - IRQIO_CLW, - IRQIO_CTC, - IRQIO_APB, - IRQIO_ADM, - IRQIO_CSC, - IRQIO_PCI, - IRQIO_MSI, + EXTINT_CLK, + EXTINT_EXC, + EXTINT_EMS, + EXTINT_TMR, + EXTINT_TLA, + EXTINT_PFL, + EXTINT_DSD, + EXTINT_VRT, + EXTINT_SCP, + EXTINT_IUC, + EXTINT_CMS, + EXTINT_CMC, + EXTINT_CMR, + IOINT_CIO, + IOINT_QAI, + IOINT_DAS, + IOINT_C15, + IOINT_C70, + IOINT_TAP, + IOINT_VMR, + IOINT_LCS, + IOINT_CLW, + IOINT_CTC, + IOINT_APB, + IOINT_ADM, + IOINT_CSC, + IOINT_PCI, + IOINT_MSI, NMI_NMI, - CPU_RST, - NR_ARCH_IRQS + NR_IRQS, }; -struct irq_stat { - unsigned int irqs[NR_ARCH_IRQS]; -}; - -DECLARE_PER_CPU_SHARED_ALIGNED(struct irq_stat, irq_stat); - -static __always_inline void inc_irq_stat(enum interruption_class irq) -{ - __get_cpu_var(irq_stat).irqs[irq]++; -} - struct ext_code { unsigned short subcode; unsigned short code; diff --git a/trunk/arch/s390/include/uapi/asm/unistd.h b/trunk/arch/s390/include/uapi/asm/unistd.h index 864f693c237f..63e6078699f1 100644 --- a/trunk/arch/s390/include/uapi/asm/unistd.h +++ b/trunk/arch/s390/include/uapi/asm/unistd.h @@ -279,8 +279,7 @@ #define __NR_process_vm_writev 341 #define __NR_s390_runtime_instr 342 #define __NR_kcmp 343 -#define __NR_finit_module 344 -#define NR_syscalls 345 +#define NR_syscalls 344 /* * There are some system calls that are not present on 64 bit, some diff --git a/trunk/arch/s390/kernel/compat_wrapper.S b/trunk/arch/s390/kernel/compat_wrapper.S index 9b9a805656b5..827e094a2f49 100644 --- a/trunk/arch/s390/kernel/compat_wrapper.S +++ b/trunk/arch/s390/kernel/compat_wrapper.S @@ -1659,9 +1659,3 @@ ENTRY(sys_kcmp_wrapper) llgfr %r5,%r5 # unsigned long llgfr %r6,%r6 # unsigned long jg sys_kcmp - -ENTRY(sys_finit_module_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char __user * - lgfr %r4,%r4 # int - jg sys_finit_module diff --git a/trunk/arch/s390/kernel/debug.c b/trunk/arch/s390/kernel/debug.c index 4e8215e0d4b6..ba500d8dc392 100644 --- a/trunk/arch/s390/kernel/debug.c +++ b/trunk/arch/s390/kernel/debug.c @@ -1127,14 +1127,13 @@ debug_register_view(debug_info_t * id, struct debug_view *view) if (i == DEBUG_MAX_VIEWS) { pr_err("Registering view %s/%s would exceed the maximum " "number of views %i\n", id->name, view->name, i); + debugfs_remove(pde); rc = -1; } else { id->views[i] = view; id->debugfs_entries[i] = pde; } spin_unlock_irqrestore(&id->lock, flags); - if (rc) - debugfs_remove(pde); out: return rc; } @@ -1147,9 +1146,9 @@ EXPORT_SYMBOL(debug_register_view); int debug_unregister_view(debug_info_t * id, struct debug_view *view) { - struct dentry *dentry = NULL; + int rc = 0; + int i; unsigned long flags; - int i, rc = 0; if (!id) goto out; @@ -1161,12 +1160,10 @@ debug_unregister_view(debug_info_t * id, struct debug_view *view) if (i == DEBUG_MAX_VIEWS) rc = -1; else { - dentry = id->debugfs_entries[i]; + debugfs_remove(id->debugfs_entries[i]); id->views[i] = NULL; - id->debugfs_entries[i] = NULL; } spin_unlock_irqrestore(&id->lock, flags); - debugfs_remove(dentry); out: return rc; } diff --git a/trunk/arch/s390/kernel/irq.c b/trunk/arch/s390/kernel/irq.c index 9df824ea1667..bf24293970ce 100644 --- a/trunk/arch/s390/kernel/irq.c +++ b/trunk/arch/s390/kernel/irq.c @@ -24,65 +24,43 @@ #include #include "entry.h" -DEFINE_PER_CPU_SHARED_ALIGNED(struct irq_stat, irq_stat); -EXPORT_PER_CPU_SYMBOL_GPL(irq_stat); - struct irq_class { char *name; char *desc; }; -/* - * The list of "main" irq classes on s390. This is the list of interrrupts - * that appear both in /proc/stat ("intr" line) and /proc/interrupts. - * Historically only external and I/O interrupts have been part of /proc/stat. - * We can't add the split external and I/O sub classes since the first field - * in the "intr" line in /proc/stat is supposed to be the sum of all other - * fields. - * Since the external and I/O interrupt fields are already sums we would end - * up with having a sum which accounts each interrupt twice. - */ -static const struct irq_class irqclass_main_desc[NR_IRQS] = { +static const struct irq_class intrclass_names[] = { [EXTERNAL_INTERRUPT] = {.name = "EXT"}, - [IO_INTERRUPT] = {.name = "I/O"} -}; - -/* - * The list of split external and I/O interrupts that appear only in - * /proc/interrupts. - * In addition this list contains non external / I/O events like NMIs. - */ -static const struct irq_class irqclass_sub_desc[NR_ARCH_IRQS] = { - [IRQEXT_CLK] = {.name = "CLK", .desc = "[EXT] Clock Comparator"}, - [IRQEXT_EXC] = {.name = "EXC", .desc = "[EXT] External Call"}, - [IRQEXT_EMS] = {.name = "EMS", .desc = "[EXT] Emergency Signal"}, - [IRQEXT_TMR] = {.name = "TMR", .desc = "[EXT] CPU Timer"}, - [IRQEXT_TLA] = {.name = "TAL", .desc = "[EXT] Timing Alert"}, - [IRQEXT_PFL] = {.name = "PFL", .desc = "[EXT] Pseudo Page Fault"}, - [IRQEXT_DSD] = {.name = "DSD", .desc = "[EXT] DASD Diag"}, - [IRQEXT_VRT] = {.name = "VRT", .desc = "[EXT] Virtio"}, - [IRQEXT_SCP] = {.name = "SCP", .desc = "[EXT] Service Call"}, - [IRQEXT_IUC] = {.name = "IUC", .desc = "[EXT] IUCV"}, - [IRQEXT_CMS] = {.name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling"}, - [IRQEXT_CMC] = {.name = "CMC", .desc = "[EXT] CPU-Measurement: Counter"}, - [IRQEXT_CMR] = {.name = "CMR", .desc = "[EXT] CPU-Measurement: RI"}, - [IRQIO_CIO] = {.name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt"}, - [IRQIO_QAI] = {.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt"}, - [IRQIO_DAS] = {.name = "DAS", .desc = "[I/O] DASD"}, - [IRQIO_C15] = {.name = "C15", .desc = "[I/O] 3215"}, - [IRQIO_C70] = {.name = "C70", .desc = "[I/O] 3270"}, - [IRQIO_TAP] = {.name = "TAP", .desc = "[I/O] Tape"}, - [IRQIO_VMR] = {.name = "VMR", .desc = "[I/O] Unit Record Devices"}, - [IRQIO_LCS] = {.name = "LCS", .desc = "[I/O] LCS"}, - [IRQIO_CLW] = {.name = "CLW", .desc = "[I/O] CLAW"}, - [IRQIO_CTC] = {.name = "CTC", .desc = "[I/O] CTC"}, - [IRQIO_APB] = {.name = "APB", .desc = "[I/O] AP Bus"}, - [IRQIO_ADM] = {.name = "ADM", .desc = "[I/O] EADM Subchannel"}, - [IRQIO_CSC] = {.name = "CSC", .desc = "[I/O] CHSC Subchannel"}, - [IRQIO_PCI] = {.name = "PCI", .desc = "[I/O] PCI Interrupt" }, - [IRQIO_MSI] = {.name = "MSI", .desc = "[I/O] MSI Interrupt" }, + [IO_INTERRUPT] = {.name = "I/O"}, + [EXTINT_CLK] = {.name = "CLK", .desc = "[EXT] Clock Comparator"}, + [EXTINT_EXC] = {.name = "EXC", .desc = "[EXT] External Call"}, + [EXTINT_EMS] = {.name = "EMS", .desc = "[EXT] Emergency Signal"}, + [EXTINT_TMR] = {.name = "TMR", .desc = "[EXT] CPU Timer"}, + [EXTINT_TLA] = {.name = "TAL", .desc = "[EXT] Timing Alert"}, + [EXTINT_PFL] = {.name = "PFL", .desc = "[EXT] Pseudo Page Fault"}, + [EXTINT_DSD] = {.name = "DSD", .desc = "[EXT] DASD Diag"}, + [EXTINT_VRT] = {.name = "VRT", .desc = "[EXT] Virtio"}, + [EXTINT_SCP] = {.name = "SCP", .desc = "[EXT] Service Call"}, + [EXTINT_IUC] = {.name = "IUC", .desc = "[EXT] IUCV"}, + [EXTINT_CMS] = {.name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling"}, + [EXTINT_CMC] = {.name = "CMC", .desc = "[EXT] CPU-Measurement: Counter"}, + [EXTINT_CMR] = {.name = "CMR", .desc = "[EXT] CPU-Measurement: RI"}, + [IOINT_CIO] = {.name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt"}, + [IOINT_QAI] = {.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt"}, + [IOINT_DAS] = {.name = "DAS", .desc = "[I/O] DASD"}, + [IOINT_C15] = {.name = "C15", .desc = "[I/O] 3215"}, + [IOINT_C70] = {.name = "C70", .desc = "[I/O] 3270"}, + [IOINT_TAP] = {.name = "TAP", .desc = "[I/O] Tape"}, + [IOINT_VMR] = {.name = "VMR", .desc = "[I/O] Unit Record Devices"}, + [IOINT_LCS] = {.name = "LCS", .desc = "[I/O] LCS"}, + [IOINT_CLW] = {.name = "CLW", .desc = "[I/O] CLAW"}, + [IOINT_CTC] = {.name = "CTC", .desc = "[I/O] CTC"}, + [IOINT_APB] = {.name = "APB", .desc = "[I/O] AP Bus"}, + [IOINT_ADM] = {.name = "ADM", .desc = "[I/O] EADM Subchannel"}, + [IOINT_CSC] = {.name = "CSC", .desc = "[I/O] CHSC Subchannel"}, + [IOINT_PCI] = {.name = "PCI", .desc = "[I/O] PCI Interrupt" }, + [IOINT_MSI] = {.name = "MSI", .desc = "[I/O] MSI Interrupt" }, [NMI_NMI] = {.name = "NMI", .desc = "[NMI] Machine Check"}, - [CPU_RST] = {.name = "RST", .desc = "[CPU] CPU Restart"}, }; /* @@ -90,34 +68,30 @@ static const struct irq_class irqclass_sub_desc[NR_ARCH_IRQS] = { */ int show_interrupts(struct seq_file *p, void *v) { - int irq = *(loff_t *) v; - int cpu; + int i = *(loff_t *) v, j; get_online_cpus(); - if (irq == 0) { + if (i == 0) { seq_puts(p, " "); - for_each_online_cpu(cpu) - seq_printf(p, "CPU%d ", cpu); + for_each_online_cpu(j) + seq_printf(p, "CPU%d ",j); seq_putc(p, '\n'); } - if (irq < NR_IRQS) { - seq_printf(p, "%s: ", irqclass_main_desc[irq].name); - for_each_online_cpu(cpu) - seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[irq]); - seq_putc(p, '\n'); - goto skip_arch_irqs; - } - for (irq = 0; irq < NR_ARCH_IRQS; irq++) { - seq_printf(p, "%s: ", irqclass_sub_desc[irq].name); - for_each_online_cpu(cpu) - seq_printf(p, "%10u ", per_cpu(irq_stat, cpu).irqs[irq]); - if (irqclass_sub_desc[irq].desc) - seq_printf(p, " %s", irqclass_sub_desc[irq].desc); - seq_putc(p, '\n'); - } -skip_arch_irqs: + + if (i < NR_IRQS) { + seq_printf(p, "%s: ", intrclass_names[i].name); +#ifndef CONFIG_SMP + seq_printf(p, "%10u ", kstat_irqs(i)); +#else + for_each_online_cpu(j) + seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); +#endif + if (intrclass_names[i].desc) + seq_printf(p, " %s", intrclass_names[i].desc); + seq_putc(p, '\n'); + } put_online_cpus(); - return 0; + return 0; } /* @@ -248,7 +222,7 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code, /* Serve timer interrupts first. */ clock_comparator_work(); } - kstat_incr_irqs_this_cpu(EXTERNAL_INTERRUPT, NULL); + kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; if (ext_code.code != 0x1004) __get_cpu_var(s390_idle).nohz_delay = 1; diff --git a/trunk/arch/s390/kernel/nmi.c b/trunk/arch/s390/kernel/nmi.c index 7918fbea36bb..a6daa5c5cdb0 100644 --- a/trunk/arch/s390/kernel/nmi.c +++ b/trunk/arch/s390/kernel/nmi.c @@ -254,7 +254,7 @@ void notrace s390_do_machine_check(struct pt_regs *regs) int umode; nmi_enter(); - inc_irq_stat(NMI_NMI); + kstat_cpu(smp_processor_id()).irqs[NMI_NMI]++; mci = (struct mci *) &S390_lowcore.mcck_interruption_code; mcck = &__get_cpu_var(cpu_mcck); umode = user_mode(regs); diff --git a/trunk/arch/s390/kernel/perf_cpum_cf.c b/trunk/arch/s390/kernel/perf_cpum_cf.c index 86ec7447e1f5..c4e7269d4a09 100644 --- a/trunk/arch/s390/kernel/perf_cpum_cf.c +++ b/trunk/arch/s390/kernel/perf_cpum_cf.c @@ -229,7 +229,7 @@ static void cpumf_measurement_alert(struct ext_code ext_code, if (!(alert & CPU_MF_INT_CF_MASK)) return; - inc_irq_stat(IRQEXT_CMC); + kstat_cpu(smp_processor_id()).irqs[EXTINT_CMC]++; cpuhw = &__get_cpu_var(cpu_hw_events); /* Measurement alerts are shared and might happen when the PMU diff --git a/trunk/arch/s390/kernel/runtime_instr.c b/trunk/arch/s390/kernel/runtime_instr.c index 077a99389b07..61066f6f71a5 100644 --- a/trunk/arch/s390/kernel/runtime_instr.c +++ b/trunk/arch/s390/kernel/runtime_instr.c @@ -71,7 +71,7 @@ static void runtime_instr_int_handler(struct ext_code ext_code, if (!(param32 & CPU_MF_INT_RI_MASK)) return; - inc_irq_stat(IRQEXT_CMR); + kstat_cpu(smp_processor_id()).irqs[EXTINT_CMR]++; if (!current->thread.ri_cb) return; diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index a5360de85ec7..2568590973ad 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -16,7 +16,7 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include -#include +#include #include #include #include @@ -289,7 +289,6 @@ void machine_power_off(void) * Dummy power off function. */ void (*pm_power_off)(void) = machine_power_off; -EXPORT_SYMBOL_GPL(pm_power_off); static int __init early_parse_mem(char *p) { diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 7433a2f9e5cc..0b45baa55438 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -433,9 +433,9 @@ static void do_ext_call_interrupt(struct ext_code ext_code, cpu = smp_processor_id(); if (ext_code.code == 0x1202) - inc_irq_stat(IRQEXT_EXC); + kstat_cpu(cpu).irqs[EXTINT_EXC]++; else - inc_irq_stat(IRQEXT_EMS); + kstat_cpu(cpu).irqs[EXTINT_EMS]++; /* * handle bit signal external calls */ @@ -623,10 +623,9 @@ static struct sclp_cpu_info *smp_get_cpu_info(void) return info; } -static int __cpuinit smp_add_present_cpu(int cpu); +static int smp_add_present_cpu(int cpu); -static int __cpuinit __smp_rescan_cpus(struct sclp_cpu_info *info, - int sysfs_add) +static int __smp_rescan_cpus(struct sclp_cpu_info *info, int sysfs_add) { struct pcpu *pcpu; cpumask_t avail; @@ -709,7 +708,6 @@ static void __cpuinit smp_start_secondary(void *cpuvoid) pfault_init(); notify_cpu_starting(smp_processor_id()); set_cpu_online(smp_processor_id(), true); - inc_irq_stat(CPU_RST); local_irq_enable(); /* cpu_idle will call schedule for us */ cpu_idle(); @@ -987,7 +985,7 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self, return notifier_from_errno(err); } -static int __cpuinit smp_add_present_cpu(int cpu) +static int smp_add_present_cpu(int cpu) { struct cpu *c = &pcpu_devices[cpu].cpu; struct device *s = &c->dev; diff --git a/trunk/arch/s390/kernel/syscalls.S b/trunk/arch/s390/kernel/syscalls.S index 6a6c61f94dd3..48174850f3b0 100644 --- a/trunk/arch/s390/kernel/syscalls.S +++ b/trunk/arch/s390/kernel/syscalls.S @@ -352,4 +352,3 @@ SYSCALL(sys_process_vm_readv,sys_process_vm_readv,compat_sys_process_vm_readv_wr SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev_wrapper) SYSCALL(sys_ni_syscall,sys_s390_runtime_instr,sys_s390_runtime_instr_wrapper) SYSCALL(sys_kcmp,sys_kcmp,sys_kcmp_wrapper) -SYSCALL(sys_finit_module,sys_finit_module,sys_finit_module_wrapper) diff --git a/trunk/arch/s390/kernel/time.c b/trunk/arch/s390/kernel/time.c index aff0e350d776..7fcd690d42c7 100644 --- a/trunk/arch/s390/kernel/time.c +++ b/trunk/arch/s390/kernel/time.c @@ -168,7 +168,7 @@ static void clock_comparator_interrupt(struct ext_code ext_code, unsigned int param32, unsigned long param64) { - inc_irq_stat(IRQEXT_CLK); + kstat_cpu(smp_processor_id()).irqs[EXTINT_CLK]++; if (S390_lowcore.clock_comparator == -1ULL) set_clock_comparator(S390_lowcore.clock_comparator); } @@ -179,7 +179,7 @@ static void stp_timing_alert(struct stp_irq_parm *); static void timing_alert_interrupt(struct ext_code ext_code, unsigned int param32, unsigned long param64) { - inc_irq_stat(IRQEXT_TLA); + kstat_cpu(smp_processor_id()).irqs[EXTINT_TLA]++; if (param32 & 0x00c40000) etr_timing_alert((struct etr_irq_parm *) ¶m32); if (param32 & 0x00038000) diff --git a/trunk/arch/s390/kernel/topology.c b/trunk/arch/s390/kernel/topology.c index 4b2e3e317004..f1aba87cceb8 100644 --- a/trunk/arch/s390/kernel/topology.c +++ b/trunk/arch/s390/kernel/topology.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -43,7 +42,6 @@ static struct mask_info socket_info; static struct mask_info book_info; struct cpu_topology_s390 cpu_topology[NR_CPUS]; -EXPORT_SYMBOL_GPL(cpu_topology); static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) { diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c index 2fb9e63b8fc4..42601d6e166f 100644 --- a/trunk/arch/s390/mm/fault.c +++ b/trunk/arch/s390/mm/fault.c @@ -569,7 +569,7 @@ static void pfault_interrupt(struct ext_code ext_code, subcode = ext_code.subcode; if ((subcode & 0xff00) != __SUBCODE_MASK) return; - inc_irq_stat(IRQEXT_PFL); + kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++; /* Get the token (= pid of the affected task). */ pid = sizeof(void *) == 4 ? param32 : param64; rcu_read_lock(); diff --git a/trunk/arch/s390/oprofile/hwsampler.c b/trunk/arch/s390/oprofile/hwsampler.c index b5b2916895e0..0cb385da202c 100644 --- a/trunk/arch/s390/oprofile/hwsampler.c +++ b/trunk/arch/s390/oprofile/hwsampler.c @@ -233,7 +233,7 @@ static void hws_ext_handler(struct ext_code ext_code, if (!(param32 & CPU_MF_INT_SF_MASK)) return; - inc_irq_stat(IRQEXT_CMS); + kstat_cpu(smp_processor_id()).irqs[EXTINT_CMS]++; atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32); if (hws_wq) diff --git a/trunk/arch/s390/pci/pci.c b/trunk/arch/s390/pci/pci.c index 60e0372545d2..ff49427e9941 100644 --- a/trunk/arch/s390/pci/pci.c +++ b/trunk/arch/s390/pci/pci.c @@ -160,6 +160,35 @@ int pci_proc_domain(struct pci_bus *bus) } EXPORT_SYMBOL_GPL(pci_proc_domain); +/* Store PCI function information block */ +static int zpci_store_fib(struct zpci_dev *zdev, u8 *fc) +{ + struct zpci_fib *fib; + u8 status, cc; + + fib = (void *) get_zeroed_page(GFP_KERNEL); + if (!fib) + return -ENOMEM; + + do { + cc = __stpcifc(zdev->fh, 0, fib, &status); + if (cc == 2) { + msleep(ZPCI_INSN_BUSY_DELAY); + memset(fib, 0, PAGE_SIZE); + } + } while (cc == 2); + + if (cc) + pr_err_once("%s: cc: %u status: %u\n", + __func__, cc, status); + + /* Return PCI function controls */ + *fc = fib->fc; + + free_page((unsigned long) fib); + return (cc) ? -EIO : 0; +} + /* Modify PCI: Register adapter interruptions */ static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb, u64 aibv) @@ -440,7 +469,7 @@ static void zpci_irq_handler(void *dont, void *need) int rescan = 0, max = aisb_max; struct zdev_irq_map *imap; - inc_irq_stat(IRQIO_PCI); + kstat_cpu(smp_processor_id()).irqs[IOINT_PCI]++; sbit = start; scan: @@ -452,7 +481,7 @@ static void zpci_irq_handler(void *dont, void *need) /* find vector bit */ imap = bucket->imap[sbit]; for_each_set_bit_left(mbit, &imap->aibv, imap->msi_vecs) { - inc_irq_stat(IRQIO_MSI); + kstat_cpu(smp_processor_id()).irqs[IOINT_MSI]++; clear_bit(63 - mbit, &imap->aibv); spin_lock(&imap->lock); diff --git a/trunk/arch/s390/pci/pci_dma.c b/trunk/arch/s390/pci/pci_dma.c index a547419907c3..6138468b420f 100644 --- a/trunk/arch/s390/pci/pci_dma.c +++ b/trunk/arch/s390/pci/pci_dma.c @@ -13,6 +13,8 @@ #include #include +static enum zpci_ioat_dtype zpci_ioat_dt = ZPCI_IOTA_RTTO; + static struct kmem_cache *dma_region_table_cache; static struct kmem_cache *dma_page_table_cache; diff --git a/trunk/arch/sparc/include/uapi/asm/unistd.h b/trunk/arch/sparc/include/uapi/asm/unistd.h index 62ced589bcf7..cac719d1bc5c 100644 --- a/trunk/arch/sparc/include/uapi/asm/unistd.h +++ b/trunk/arch/sparc/include/uapi/asm/unistd.h @@ -407,9 +407,8 @@ #define __NR_process_vm_writev 339 #define __NR_kern_features 340 #define __NR_kcmp 341 -#define __NR_finit_module 342 -#define NR_syscalls 343 +#define NR_syscalls 342 /* Bitmask values returned from kern_features system call. */ #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 diff --git a/trunk/arch/sparc/kernel/pci.c b/trunk/arch/sparc/kernel/pci.c index baf4366e2d6a..04bacce76fe6 100644 --- a/trunk/arch/sparc/kernel/pci.c +++ b/trunk/arch/sparc/kernel/pci.c @@ -378,8 +378,7 @@ static void apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) /* Cook up fake bus resources for SUNW,simba PCI bridges which lack * a proper 'ranges' property. */ -static void apb_fake_ranges(struct pci_dev *dev, - struct pci_bus *bus, +static void apb_fake_ranges(struct pci_dev *dev, struct pci_bus *bus, struct pci_pbm_info *pbm) { struct pci_bus_region region; @@ -404,15 +403,13 @@ static void apb_fake_ranges(struct pci_dev *dev, pcibios_bus_to_resource(dev, res, ®ion); } -static void pci_of_scan_bus(struct pci_pbm_info *pbm, - struct device_node *node, +static void pci_of_scan_bus(struct pci_pbm_info *pbm, struct device_node *node, struct pci_bus *bus); #define GET_64BIT(prop, i) ((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1]) static void of_scan_pci_bridge(struct pci_pbm_info *pbm, - struct device_node *node, - struct pci_dev *dev) + struct device_node *node, struct pci_dev *dev) { struct pci_bus *bus; const u32 *busrange, *ranges; @@ -503,8 +500,7 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm, pci_of_scan_bus(pbm, node, bus); } -static void pci_of_scan_bus(struct pci_pbm_info *pbm, - struct device_node *node, +static void pci_of_scan_bus(struct pci_pbm_info *pbm, struct device_node *node, struct pci_bus *bus) { struct device_node *child; diff --git a/trunk/arch/sparc/kernel/pci_psycho.c b/trunk/arch/sparc/kernel/pci_psycho.c index c647634ead2b..b85238289717 100644 --- a/trunk/arch/sparc/kernel/pci_psycho.c +++ b/trunk/arch/sparc/kernel/pci_psycho.c @@ -366,8 +366,7 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) pci_config_write8(addr, 64); } -static void psycho_scan_bus(struct pci_pbm_info *pbm, - struct device *parent) +static void psycho_scan_bus(struct pci_pbm_info *pbm, struct device *parent) { pbm_config_busmastering(pbm); pbm->is_66mhz_capable = 0; diff --git a/trunk/arch/sparc/kernel/pci_sabre.c b/trunk/arch/sparc/kernel/pci_sabre.c index 6f00d27e8dac..531186d7c9ab 100644 --- a/trunk/arch/sparc/kernel/pci_sabre.c +++ b/trunk/arch/sparc/kernel/pci_sabre.c @@ -442,8 +442,7 @@ static void sabre_scan_bus(struct pci_pbm_info *pbm, struct device *parent) sabre_register_error_handlers(pbm); } -static void sabre_pbm_init(struct pci_pbm_info *pbm, - struct platform_device *op) +static void sabre_pbm_init(struct pci_pbm_info *pbm, struct platform_device *op) { psycho_pbm_init_common(pbm, op, "SABRE", PBM_CHIP_TYPE_SABRE); pbm->pci_afsr = pbm->controller_regs + SABRE_PIOAFSR; diff --git a/trunk/arch/sparc/kernel/pci_schizo.c b/trunk/arch/sparc/kernel/pci_schizo.c index 8f76f23dac38..29e888158ae6 100644 --- a/trunk/arch/sparc/kernel/pci_schizo.c +++ b/trunk/arch/sparc/kernel/pci_schizo.c @@ -1306,9 +1306,8 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) } } -static int schizo_pbm_init(struct pci_pbm_info *pbm, - struct platform_device *op, u32 portid, - int chip_type) +static int schizo_pbm_init(struct pci_pbm_info *pbm, struct platform_device *op, + u32 portid, int chip_type) { const struct linux_prom64_registers *regs; struct device_node *dp = op->dev.of_node; diff --git a/trunk/arch/sparc/kernel/systbls_32.S b/trunk/arch/sparc/kernel/systbls_32.S index 6ac43c36bbbf..5147f574f125 100644 --- a/trunk/arch/sparc/kernel/systbls_32.S +++ b/trunk/arch/sparc/kernel/systbls_32.S @@ -85,4 +85,4 @@ sys_call_table: /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -/*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module +/*340*/ .long sys_ni_syscall, sys_kcmp diff --git a/trunk/arch/sparc/kernel/systbls_64.S b/trunk/arch/sparc/kernel/systbls_64.S index 1009ecb92678..cdbd9b817751 100644 --- a/trunk/arch/sparc/kernel/systbls_64.S +++ b/trunk/arch/sparc/kernel/systbls_64.S @@ -86,7 +86,7 @@ sys_call_table32: .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev -/*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module +/*340*/ .word sys_kern_features, sys_kcmp #endif /* CONFIG_COMPAT */ @@ -164,4 +164,4 @@ sys_call_table: .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -/*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module +/*340*/ .word sys_kern_features, sys_kcmp diff --git a/trunk/arch/x86/kernel/kvm.c b/trunk/arch/x86/kernel/kvm.c index 9c2bd8bd4b4c..08b973f64032 100644 --- a/trunk/arch/x86/kernel/kvm.c +++ b/trunk/arch/x86/kernel/kvm.c @@ -43,7 +43,6 @@ #include #include #include -#include static int kvmapf = 1; @@ -122,8 +121,6 @@ void kvm_async_pf_task_wait(u32 token) struct kvm_task_sleep_node n, *e; DEFINE_WAIT(wait); - rcu_irq_enter(); - spin_lock(&b->lock); e = _find_apf_task(b, token); if (e) { @@ -131,8 +128,6 @@ void kvm_async_pf_task_wait(u32 token) hlist_del(&e->link); kfree(e); spin_unlock(&b->lock); - - rcu_irq_exit(); return; } @@ -157,16 +152,13 @@ void kvm_async_pf_task_wait(u32 token) /* * We cannot reschedule. So halt. */ - rcu_irq_exit(); native_safe_halt(); - rcu_irq_enter(); local_irq_disable(); } } if (!n.halted) finish_wait(&n.wq, &wait); - rcu_irq_exit(); return; } EXPORT_SYMBOL_GPL(kvm_async_pf_task_wait); @@ -260,10 +252,10 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code) break; case KVM_PV_REASON_PAGE_NOT_PRESENT: /* page is swapped out by the host. */ - exception_enter(regs); + rcu_irq_enter(); exit_idle(); kvm_async_pf_task_wait((u32)read_cr2()); - exception_exit(regs); + rcu_irq_exit(); break; case KVM_PV_REASON_PAGE_READY: rcu_irq_enter(); diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index c243b81e3c74..76f54461f7cb 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -120,7 +120,7 @@ struct kvm_shared_msrs { }; static struct kvm_shared_msrs_global __read_mostly shared_msrs_global; -static struct kvm_shared_msrs __percpu *shared_msrs; +static DEFINE_PER_CPU(struct kvm_shared_msrs, shared_msrs); struct kvm_stats_debugfs_item debugfs_entries[] = { { "pf_fixed", VCPU_STAT(pf_fixed) }, @@ -191,10 +191,10 @@ static void kvm_on_user_return(struct user_return_notifier *urn) static void shared_msr_update(unsigned slot, u32 msr) { + struct kvm_shared_msrs *smsr; u64 value; - unsigned int cpu = smp_processor_id(); - struct kvm_shared_msrs *smsr = per_cpu_ptr(shared_msrs, cpu); + smsr = &__get_cpu_var(shared_msrs); /* only read, and nobody should modify it at this time, * so don't need lock */ if (slot >= shared_msrs_global.nr) { @@ -226,8 +226,7 @@ static void kvm_shared_msr_cpu_online(void) void kvm_set_shared_msr(unsigned slot, u64 value, u64 mask) { - unsigned int cpu = smp_processor_id(); - struct kvm_shared_msrs *smsr = per_cpu_ptr(shared_msrs, cpu); + struct kvm_shared_msrs *smsr = &__get_cpu_var(shared_msrs); if (((value ^ smsr->values[slot].curr) & mask) == 0) return; @@ -243,8 +242,7 @@ EXPORT_SYMBOL_GPL(kvm_set_shared_msr); static void drop_user_return_notifiers(void *ignore) { - unsigned int cpu = smp_processor_id(); - struct kvm_shared_msrs *smsr = per_cpu_ptr(shared_msrs, cpu); + struct kvm_shared_msrs *smsr = &__get_cpu_var(shared_msrs); if (smsr->registered) kvm_on_user_return(&smsr->urn); @@ -5235,16 +5233,9 @@ int kvm_arch_init(void *opaque) goto out; } - r = -ENOMEM; - shared_msrs = alloc_percpu(struct kvm_shared_msrs); - if (!shared_msrs) { - printk(KERN_ERR "kvm: failed to allocate percpu kvm_shared_msrs\n"); - goto out; - } - r = kvm_mmu_module_init(); if (r) - goto out_free_percpu; + goto out; kvm_set_mmio_spte_mask(); kvm_init_msr_list(); @@ -5267,8 +5258,6 @@ int kvm_arch_init(void *opaque) return 0; -out_free_percpu: - free_percpu(shared_msrs); out: return r; } @@ -5286,7 +5275,6 @@ void kvm_arch_exit(void) #endif kvm_x86_ops = NULL; kvm_mmu_module_exit(); - free_percpu(shared_msrs); } int kvm_emulate_halt(struct kvm_vcpu *vcpu) diff --git a/trunk/drivers/clk/mvebu/clk-gating-ctrl.c b/trunk/drivers/clk/mvebu/clk-gating-ctrl.c index 8fa5408b6c7d..c6d3c263b070 100644 --- a/trunk/drivers/clk/mvebu/clk-gating-ctrl.c +++ b/trunk/drivers/clk/mvebu/clk-gating-ctrl.c @@ -32,7 +32,7 @@ struct mvebu_soc_descr { #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) -static struct clk *mvebu_clk_gating_get_src( +static struct clk __init *mvebu_clk_gating_get_src( struct of_phandle_args *clkspec, void *data) { struct mvebu_gating_ctrl *ctrl = (struct mvebu_gating_ctrl *)data; diff --git a/trunk/drivers/dma/mv_xor.c b/trunk/drivers/dma/mv_xor.c index e17fad03cb80..ac71f555dd72 100644 --- a/trunk/drivers/dma/mv_xor.c +++ b/trunk/drivers/dma/mv_xor.c @@ -1361,16 +1361,13 @@ static int mv_xor_probe(struct platform_device *pdev) err_channel_add: for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) if (xordev->channels[i]) { - mv_xor_channel_remove(xordev->channels[i]); if (pdev->dev.of_node) irq_dispose_mapping(xordev->channels[i]->irq); + mv_xor_channel_remove(xordev->channels[i]); } - if (!IS_ERR(xordev->clk)) { - clk_disable_unprepare(xordev->clk); - clk_put(xordev->clk); - } - + clk_disable_unprepare(xordev->clk); + clk_put(xordev->clk); return ret; } diff --git a/trunk/drivers/edac/Kconfig b/trunk/drivers/edac/Kconfig index 66719925970f..4c6c876d9dc3 100644 --- a/trunk/drivers/edac/Kconfig +++ b/trunk/drivers/edac/Kconfig @@ -4,9 +4,6 @@ # Licensed and distributed under the GPL # -config EDAC_SUPPORT - bool - menuconfig EDAC bool "EDAC (Error Detection And Correction) reporting" depends on HAS_IOMEM @@ -30,8 +27,13 @@ menuconfig EDAC There is also a mailing list for the EDAC project, which can be found via the sourceforge page. +config EDAC_SUPPORT + bool + if EDAC +comment "Reporting subsystems" + config EDAC_LEGACY_SYSFS bool "EDAC legacy sysfs" default y diff --git a/trunk/drivers/edac/edac_mc_sysfs.c b/trunk/drivers/edac/edac_mc_sysfs.c index 0ca1ca71157f..de2df92f9c77 100644 --- a/trunk/drivers/edac/edac_mc_sysfs.c +++ b/trunk/drivers/edac/edac_mc_sysfs.c @@ -472,7 +472,8 @@ static void edac_delete_csrow_objects(struct mem_ctl_info *mci) device_remove_file(&csrow->dev, dynamic_csrow_ce_count_attr[chan]); } - device_unregister(&mci->csrows[i]->dev); + put_device(&mci->csrows[i]->dev); + device_del(&mci->csrows[i]->dev); } } #endif @@ -1054,9 +1055,11 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) struct dimm_info *dimm = mci->dimms[i]; if (dimm->nr_pages == 0) continue; - device_unregister(&dimm->dev); + put_device(&dimm->dev); + device_del(&dimm->dev); } - device_unregister(&mci->dev); + put_device(&mci->dev); + device_del(&mci->dev); bus_unregister(&mci->bus); kfree(mci->bus.name); return err; @@ -1083,14 +1086,16 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) if (dimm->nr_pages == 0) continue; edac_dbg(0, "removing device %s\n", dev_name(&dimm->dev)); - device_unregister(&dimm->dev); + put_device(&dimm->dev); + device_del(&dimm->dev); } } void edac_unregister_sysfs(struct mem_ctl_info *mci) { edac_dbg(1, "Unregistering device %s\n", dev_name(&mci->dev)); - device_unregister(&mci->dev); + put_device(&mci->dev); + device_del(&mci->dev); bus_unregister(&mci->bus); kfree(mci->bus.name); } @@ -1154,6 +1159,8 @@ int __init edac_mc_sysfs_init(void) void __exit edac_mc_sysfs_exit(void) { - device_unregister(mci_pdev); + put_device(mci_pdev); + device_del(mci_pdev); edac_put_sysfs_subsys(); + kfree(mci_pdev); } diff --git a/trunk/drivers/gpu/drm/drm_mm.c b/trunk/drivers/gpu/drm/drm_mm.c index 2aa331499f81..2bf9670ba29b 100644 --- a/trunk/drivers/gpu/drm/drm_mm.c +++ b/trunk/drivers/gpu/drm/drm_mm.c @@ -221,14 +221,12 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, BUG_ON(!hole_node->hole_follows || node->allocated); - if (adj_start < start) - adj_start = start; - if (adj_end > end) - adj_end = end; - if (mm->color_adjust) mm->color_adjust(hole_node, color, &adj_start, &adj_end); + if (adj_start < start) + adj_start = start; + if (alignment) { unsigned tmp = adj_start % alignment; if (tmp) @@ -508,7 +506,7 @@ void drm_mm_init_scan(struct drm_mm *mm, mm->scan_size = size; mm->scanned_blocks = 0; mm->scan_hit_start = 0; - mm->scan_hit_end = 0; + mm->scan_hit_size = 0; mm->scan_check_range = 0; mm->prev_scanned_node = NULL; } @@ -535,7 +533,7 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm, mm->scan_size = size; mm->scanned_blocks = 0; mm->scan_hit_start = 0; - mm->scan_hit_end = 0; + mm->scan_hit_size = 0; mm->scan_start = start; mm->scan_end = end; mm->scan_check_range = 1; @@ -554,7 +552,8 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) struct drm_mm *mm = node->mm; struct drm_mm_node *prev_node; unsigned long hole_start, hole_end; - unsigned long adj_start, adj_end; + unsigned long adj_start; + unsigned long adj_end; mm->scanned_blocks++; @@ -571,8 +570,14 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) node->node_list.next = &mm->prev_scanned_node->node_list; mm->prev_scanned_node = node; - adj_start = hole_start = drm_mm_hole_node_start(prev_node); - adj_end = hole_end = drm_mm_hole_node_end(prev_node); + hole_start = drm_mm_hole_node_start(prev_node); + hole_end = drm_mm_hole_node_end(prev_node); + + adj_start = hole_start; + adj_end = hole_end; + + if (mm->color_adjust) + mm->color_adjust(prev_node, mm->scan_color, &adj_start, &adj_end); if (mm->scan_check_range) { if (adj_start < mm->scan_start) @@ -581,14 +586,11 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) adj_end = mm->scan_end; } - if (mm->color_adjust) - mm->color_adjust(prev_node, mm->scan_color, - &adj_start, &adj_end); - if (check_free_hole(adj_start, adj_end, mm->scan_size, mm->scan_alignment)) { mm->scan_hit_start = hole_start; - mm->scan_hit_end = hole_end; + mm->scan_hit_size = hole_end; + return 1; } @@ -624,10 +626,19 @@ int drm_mm_scan_remove_block(struct drm_mm_node *node) node_list); prev_node->hole_follows = node->scanned_preceeds_hole; + INIT_LIST_HEAD(&node->node_list); list_add(&node->node_list, &prev_node->node_list); - return (drm_mm_hole_node_end(node) > mm->scan_hit_start && - node->start < mm->scan_hit_end); + /* Only need to check for containement because start&size for the + * complete resulting free block (not just the desired part) is + * stored. */ + if (node->start >= mm->scan_hit_start && + node->start + node->size + <= mm->scan_hit_start + mm->scan_hit_size) { + return 1; + } + + return 0; } EXPORT_SYMBOL(drm_mm_scan_remove_block); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.c index 57affae9568b..9601bad47a2e 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.c @@ -3,10 +3,24 @@ * Copyright (c) 2011 Samsung Electronics Co., Ltd. * Author: Inki Dae * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #include @@ -15,7 +29,6 @@ #include "exynos_drm_drv.h" #include "exynos_drm_gem.h" #include "exynos_drm_buf.h" -#include "exynos_drm_iommu.h" static int lowlevel_buffer_allocate(struct drm_device *dev, unsigned int flags, struct exynos_drm_gem_buf *buf) @@ -38,7 +51,7 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, * region will be allocated else physically contiguous * as possible. */ - if (!(flags & EXYNOS_BO_NONCONTIG)) + if (flags & EXYNOS_BO_CONTIG) dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &buf->dma_attrs); /* @@ -53,45 +66,14 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, dma_set_attr(attr, &buf->dma_attrs); dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &buf->dma_attrs); - nr_pages = buf->size >> PAGE_SHIFT; - - if (!is_drm_iommu_supported(dev)) { - dma_addr_t start_addr; - unsigned int i = 0; - - buf->pages = kzalloc(sizeof(struct page) * nr_pages, - GFP_KERNEL); - if (!buf->pages) { - DRM_ERROR("failed to allocate pages.\n"); - return -ENOMEM; - } - - buf->kvaddr = dma_alloc_attrs(dev->dev, buf->size, - &buf->dma_addr, GFP_KERNEL, - &buf->dma_attrs); - if (!buf->kvaddr) { - DRM_ERROR("failed to allocate buffer.\n"); - kfree(buf->pages); - return -ENOMEM; - } - - start_addr = buf->dma_addr; - while (i < nr_pages) { - buf->pages[i] = phys_to_page(start_addr); - start_addr += PAGE_SIZE; - i++; - } - } else { - - buf->pages = dma_alloc_attrs(dev->dev, buf->size, - &buf->dma_addr, GFP_KERNEL, - &buf->dma_attrs); - if (!buf->pages) { - DRM_ERROR("failed to allocate buffer.\n"); - return -ENOMEM; - } + buf->pages = dma_alloc_attrs(dev->dev, buf->size, + &buf->dma_addr, GFP_KERNEL, &buf->dma_attrs); + if (!buf->pages) { + DRM_ERROR("failed to allocate buffer.\n"); + return -ENOMEM; } + nr_pages = buf->size >> PAGE_SHIFT; buf->sgt = drm_prime_pages_to_sg(buf->pages, nr_pages); if (!buf->sgt) { DRM_ERROR("failed to get sg table.\n"); @@ -110,9 +92,6 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, (dma_addr_t)buf->dma_addr, &buf->dma_attrs); buf->dma_addr = (dma_addr_t)NULL; - if (!is_drm_iommu_supported(dev)) - kfree(buf->pages); - return ret; } @@ -135,14 +114,8 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev, kfree(buf->sgt); buf->sgt = NULL; - if (!is_drm_iommu_supported(dev)) { - dma_free_attrs(dev->dev, buf->size, buf->kvaddr, - (dma_addr_t)buf->dma_addr, &buf->dma_attrs); - kfree(buf->pages); - } else - dma_free_attrs(dev->dev, buf->size, buf->pages, + dma_free_attrs(dev->dev, buf->size, buf->pages, (dma_addr_t)buf->dma_addr, &buf->dma_attrs); - buf->dma_addr = (dma_addr_t)NULL; } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.h index a6412f19673c..25cf16285033 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.h @@ -3,10 +3,24 @@ * Copyright (c) 2011 Samsung Electronics Co., Ltd. * Author: Inki Dae * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_BUF_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c index ab37437bad8a..0f68a2872673 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c @@ -5,10 +5,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #include diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.h index 547c6b590357..22f6cc442c3d 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.h @@ -5,10 +5,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_CONNECTOR_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_core.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_core.c index 4667c9f67acd..94026ad76a77 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_core.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_core.c @@ -6,10 +6,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #include diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_crtc.c index e8894bc9e6d5..2efa4b031d73 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -6,10 +6,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #include @@ -393,33 +407,3 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc) exynos_drm_fn_encoder(private->crtc[crtc], &crtc, exynos_drm_disable_vblank); } - -void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int crtc) -{ - struct exynos_drm_private *dev_priv = dev->dev_private; - struct drm_pending_vblank_event *e, *t; - struct timeval now; - unsigned long flags; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - spin_lock_irqsave(&dev->event_lock, flags); - - list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list, - base.link) { - /* if event's pipe isn't same as crtc then ignore it. */ - if (crtc != e->pipe) - continue; - - do_gettimeofday(&now); - e->event.sequence = 0; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - drm_vblank_put(dev, crtc); - } - - spin_unlock_irqrestore(&dev->event_lock, flags); -} diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_crtc.h index 3e197e6ae7d9..6bae8d8c250e 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_crtc.h @@ -6,10 +6,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_CRTC_H_ @@ -18,6 +32,5 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr); int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc); void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc); -void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int crtc); #endif diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index 9df97714b6c0..61d5a8402eb8 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c @@ -3,10 +3,24 @@ * Copyright (c) 2012 Samsung Electronics Co., Ltd. * Author: Inki Dae * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #include @@ -208,7 +222,7 @@ struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev, struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); return dma_buf_export(exynos_gem_obj, &exynos_dmabuf_ops, - exynos_gem_obj->base.size, flags); + exynos_gem_obj->base.size, 0600); } struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, @@ -232,12 +246,7 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, /* is it from our device? */ if (obj->dev == drm_dev) { - /* - * Importing dmabuf exported from out own gem increases - * refcount on gem itself instead of f_count of dmabuf. - */ drm_gem_object_reference(obj); - dma_buf_put(dma_buf); return obj; } } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h index 49acfafb4fdb..662a8f98ccdb 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h @@ -3,10 +3,24 @@ * Copyright (c) 2012 Samsung Electronics Co., Ltd. * Author: Inki Dae * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_DMABUF_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.c index 3da5c2d214d8..1713e53d4751 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -5,10 +5,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #include diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h index b9e51bc09e81..f5a97745bf93 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -6,10 +6,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_DRV_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c index c63721f64aec..301485215a70 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -6,10 +6,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #include diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.h index 89e2fb0770af..88bb25a2a917 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.h @@ -5,10 +5,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_ENCODER_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.c index 294c0513f587..5426cc5a5e8d 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -6,10 +6,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #include diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.h index 517471b37566..96262e54f76d 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.h @@ -5,10 +5,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_FB_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 71f867340a88..f433eb7533a9 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -6,10 +6,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #include @@ -20,7 +34,6 @@ #include "exynos_drm_drv.h" #include "exynos_drm_fb.h" #include "exynos_drm_gem.h" -#include "exynos_drm_iommu.h" #define MAX_CONNECTOR 4 #define PREFERRED_BPP 32 @@ -98,18 +111,9 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, /* map pages with kernel virtual space. */ if (!buffer->kvaddr) { - if (is_drm_iommu_supported(dev)) { - unsigned int nr_pages = buffer->size >> PAGE_SHIFT; - - buffer->kvaddr = vmap(buffer->pages, nr_pages, VM_MAP, + unsigned int nr_pages = buffer->size >> PAGE_SHIFT; + buffer->kvaddr = vmap(buffer->pages, nr_pages, VM_MAP, pgprot_writecombine(PAGE_KERNEL)); - } else { - phys_addr_t dma_addr = buffer->dma_addr; - if (dma_addr) - buffer->kvaddr = phys_to_virt(dma_addr); - else - buffer->kvaddr = (void __iomem *)NULL; - } if (!buffer->kvaddr) { DRM_ERROR("failed to map pages to kernel space.\n"); return -EIO; @@ -124,12 +128,8 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr; fbi->screen_base = buffer->kvaddr + offset; - if (is_drm_iommu_supported(dev)) - fbi->fix.smem_start = (unsigned long) + fbi->fix.smem_start = (unsigned long) (page_to_phys(sg_page(buffer->sgt->sgl)) + offset); - else - fbi->fix.smem_start = (unsigned long)buffer->dma_addr; - fbi->screen_size = size; fbi->fix.smem_len = size; @@ -320,7 +320,7 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev, struct exynos_drm_gem_obj *exynos_gem_obj = exynos_fbd->exynos_gem_obj; struct drm_framebuffer *fb; - if (is_drm_iommu_supported(dev) && exynos_gem_obj->buffer->kvaddr) + if (exynos_gem_obj->buffer->kvaddr) vunmap(exynos_gem_obj->buffer->kvaddr); /* release drm framebuffer and real buffer */ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.h index e16d7f0ae192..ccfce8a1a451 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.h @@ -6,10 +6,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_FBDEV_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 67a83e69544b..d9963171fd0b 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -25,7 +25,7 @@ #include "exynos_drm_fimc.h" /* - * FIMC stands for Fully Interactive Mobile Camera and + * FIMC is stand for Fully Interactive Mobile Camera and * supports image scaler/rotator and input/output DMA operations. * input DMA reads image data from the memory. * output DMA writes image data to memory. @@ -163,28 +163,18 @@ struct fimc_context { bool suspended; }; -static void fimc_sw_reset(struct fimc_context *ctx) +static void fimc_sw_reset(struct fimc_context *ctx, bool pattern) { u32 cfg; - DRM_DEBUG_KMS("%s\n", __func__); - - /* stop dma operation */ - cfg = fimc_read(EXYNOS_CISTATUS); - if (EXYNOS_CISTATUS_GET_ENVID_STATUS(cfg)) { - cfg = fimc_read(EXYNOS_MSCTRL); - cfg &= ~EXYNOS_MSCTRL_ENVID; - fimc_write(cfg, EXYNOS_MSCTRL); - } + DRM_DEBUG_KMS("%s:pattern[%d]\n", __func__, pattern); cfg = fimc_read(EXYNOS_CISRCFMT); cfg |= EXYNOS_CISRCFMT_ITU601_8BIT; - fimc_write(cfg, EXYNOS_CISRCFMT); + if (pattern) + cfg |= EXYNOS_CIGCTRL_TESTPATTERN_COLOR_BAR; - /* disable image capture */ - cfg = fimc_read(EXYNOS_CIIMGCPT); - cfg &= ~(EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN); - fimc_write(cfg, EXYNOS_CIIMGCPT); + fimc_write(cfg, EXYNOS_CISRCFMT); /* s/w reset */ cfg = fimc_read(EXYNOS_CIGCTRL); @@ -705,7 +695,7 @@ static int fimc_src_set_addr(struct device *dev, { struct fimc_context *ctx = get_fimc_context(dev); struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; - struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; + struct drm_exynos_ipp_cmd_node *c_node = ippdrv->cmd; struct drm_exynos_ipp_property *property; struct drm_exynos_ipp_config *config; @@ -715,6 +705,10 @@ static int fimc_src_set_addr(struct device *dev, } property = &c_node->property; + if (!property) { + DRM_ERROR("failed to get property.\n"); + return -EINVAL; + } DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__, property->prop_id, buf_id, buf_type); @@ -1212,7 +1206,7 @@ static int fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id, } /* sequence id */ - cfg &= ~mask; + cfg &= (~mask); cfg |= (enable << buf_id); fimc_write(cfg, EXYNOS_CIFCNTSEQ); @@ -1237,7 +1231,7 @@ static int fimc_dst_set_addr(struct device *dev, { struct fimc_context *ctx = get_fimc_context(dev); struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; - struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; + struct drm_exynos_ipp_cmd_node *c_node = ippdrv->cmd; struct drm_exynos_ipp_property *property; struct drm_exynos_ipp_config *config; @@ -1247,6 +1241,10 @@ static int fimc_dst_set_addr(struct device *dev, } property = &c_node->property; + if (!property) { + DRM_ERROR("failed to get property.\n"); + return -EINVAL; + } DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__, property->prop_id, buf_id, buf_type); @@ -1319,7 +1317,7 @@ static irqreturn_t fimc_irq_handler(int irq, void *dev_id) { struct fimc_context *ctx = dev_id; struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; - struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; + struct drm_exynos_ipp_cmd_node *c_node = ippdrv->cmd; struct drm_exynos_ipp_event_work *event_work = c_node->event_work; int buf_id; @@ -1397,7 +1395,6 @@ static inline bool fimc_check_drm_flip(enum drm_exynos_flip flip) case EXYNOS_DRM_FLIP_NONE: case EXYNOS_DRM_FLIP_VERTICAL: case EXYNOS_DRM_FLIP_HORIZONTAL: - case EXYNOS_DRM_FLIP_BOTH: return true; default: DRM_DEBUG_KMS("%s:invalid flip\n", __func__); @@ -1546,7 +1543,7 @@ static int fimc_ippdrv_reset(struct device *dev) DRM_DEBUG_KMS("%s\n", __func__); /* reset h/w block */ - fimc_sw_reset(ctx); + fimc_sw_reset(ctx, false); /* reset scaler capability */ memset(&ctx->sc, 0x0, sizeof(ctx->sc)); @@ -1560,7 +1557,7 @@ static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd) { struct fimc_context *ctx = get_fimc_context(dev); struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; - struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; + struct drm_exynos_ipp_cmd_node *c_node = ippdrv->cmd; struct drm_exynos_ipp_property *property; struct drm_exynos_ipp_config *config; struct drm_exynos_pos img_pos[EXYNOS_DRM_OPS_MAX]; @@ -1576,6 +1573,10 @@ static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd) } property = &c_node->property; + if (!property) { + DRM_ERROR("failed to get property.\n"); + return -EINVAL; + } fimc_handle_irq(ctx, true, false, true); @@ -1738,64 +1739,93 @@ static int fimc_probe(struct platform_device *pdev) platform_get_device_id(pdev)->driver_data; /* clock control */ - ctx->sclk_fimc_clk = devm_clk_get(dev, "sclk_fimc"); + ctx->sclk_fimc_clk = clk_get(dev, "sclk_fimc"); if (IS_ERR(ctx->sclk_fimc_clk)) { dev_err(dev, "failed to get src fimc clock.\n"); - return PTR_ERR(ctx->sclk_fimc_clk); + ret = PTR_ERR(ctx->sclk_fimc_clk); + goto err_ctx; } clk_enable(ctx->sclk_fimc_clk); - ctx->fimc_clk = devm_clk_get(dev, "fimc"); + ctx->fimc_clk = clk_get(dev, "fimc"); if (IS_ERR(ctx->fimc_clk)) { dev_err(dev, "failed to get fimc clock.\n"); + ret = PTR_ERR(ctx->fimc_clk); clk_disable(ctx->sclk_fimc_clk); - return PTR_ERR(ctx->fimc_clk); + clk_put(ctx->sclk_fimc_clk); + goto err_ctx; } - ctx->wb_clk = devm_clk_get(dev, "pxl_async0"); + ctx->wb_clk = clk_get(dev, "pxl_async0"); if (IS_ERR(ctx->wb_clk)) { dev_err(dev, "failed to get writeback a clock.\n"); + ret = PTR_ERR(ctx->wb_clk); clk_disable(ctx->sclk_fimc_clk); - return PTR_ERR(ctx->wb_clk); + clk_put(ctx->sclk_fimc_clk); + clk_put(ctx->fimc_clk); + goto err_ctx; } - ctx->wb_b_clk = devm_clk_get(dev, "pxl_async1"); + ctx->wb_b_clk = clk_get(dev, "pxl_async1"); if (IS_ERR(ctx->wb_b_clk)) { dev_err(dev, "failed to get writeback b clock.\n"); + ret = PTR_ERR(ctx->wb_b_clk); clk_disable(ctx->sclk_fimc_clk); - return PTR_ERR(ctx->wb_b_clk); + clk_put(ctx->sclk_fimc_clk); + clk_put(ctx->fimc_clk); + clk_put(ctx->wb_clk); + goto err_ctx; } - parent_clk = devm_clk_get(dev, ddata->parent_clk); + parent_clk = clk_get(dev, ddata->parent_clk); if (IS_ERR(parent_clk)) { dev_err(dev, "failed to get parent clock.\n"); + ret = PTR_ERR(parent_clk); clk_disable(ctx->sclk_fimc_clk); - return PTR_ERR(parent_clk); + clk_put(ctx->sclk_fimc_clk); + clk_put(ctx->fimc_clk); + clk_put(ctx->wb_clk); + clk_put(ctx->wb_b_clk); + goto err_ctx; } if (clk_set_parent(ctx->sclk_fimc_clk, parent_clk)) { dev_err(dev, "failed to set parent.\n"); + ret = -EINVAL; + clk_put(parent_clk); clk_disable(ctx->sclk_fimc_clk); - return -EINVAL; + clk_put(ctx->sclk_fimc_clk); + clk_put(ctx->fimc_clk); + clk_put(ctx->wb_clk); + clk_put(ctx->wb_b_clk); + goto err_ctx; } - devm_clk_put(dev, parent_clk); + clk_put(parent_clk); clk_set_rate(ctx->sclk_fimc_clk, pdata->clk_rate); /* resource memory */ ctx->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!ctx->regs_res) { + dev_err(dev, "failed to find registers.\n"); + ret = -ENOENT; + goto err_clk; + } + ctx->regs = devm_request_and_ioremap(dev, ctx->regs_res); if (!ctx->regs) { dev_err(dev, "failed to map registers.\n"); - return -ENXIO; + ret = -ENXIO; + goto err_clk; } /* resource irq */ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "failed to request irq resource.\n"); - return -ENOENT; + ret = -ENOENT; + goto err_get_regs; } ctx->irq = res->start; @@ -1803,7 +1833,7 @@ static int fimc_probe(struct platform_device *pdev) IRQF_ONESHOT, "drm_fimc", ctx); if (ret < 0) { dev_err(dev, "failed to request irq.\n"); - return ret; + goto err_get_regs; } /* context initailization */ @@ -1849,7 +1879,15 @@ static int fimc_probe(struct platform_device *pdev) pm_runtime_disable(dev); err_get_irq: free_irq(ctx->irq, ctx); - +err_get_regs: + devm_iounmap(dev, ctx->regs); +err_clk: + clk_put(ctx->sclk_fimc_clk); + clk_put(ctx->fimc_clk); + clk_put(ctx->wb_clk); + clk_put(ctx->wb_b_clk); +err_ctx: + devm_kfree(dev, ctx); return ret; } @@ -1867,6 +1905,14 @@ static int fimc_remove(struct platform_device *pdev) pm_runtime_disable(dev); free_irq(ctx->irq, ctx); + devm_iounmap(dev, ctx->regs); + + clk_put(ctx->sclk_fimc_clk); + clk_put(ctx->fimc_clk); + clk_put(ctx->wb_clk); + clk_put(ctx->wb_b_clk); + + devm_kfree(dev, ctx); return 0; } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimc.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimc.h index 127a424c5fdf..dc970fa0d888 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimc.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimc.h @@ -6,10 +6,24 @@ * Jinyoung Jeon * Sangmin Lee * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_FIMC_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 9537761931ee..3ac911894dc7 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -663,6 +663,34 @@ static struct exynos_drm_manager fimd_manager = { .display_ops = &fimd_display_ops, }; +static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc) +{ + struct exynos_drm_private *dev_priv = drm_dev->dev_private; + struct drm_pending_vblank_event *e, *t; + struct timeval now; + unsigned long flags; + + spin_lock_irqsave(&drm_dev->event_lock, flags); + + list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list, + base.link) { + /* if event's pipe isn't same as crtc then ignore it. */ + if (crtc != e->pipe) + continue; + + do_gettimeofday(&now); + e->event.sequence = 0; + e->event.tv_sec = now.tv_sec; + e->event.tv_usec = now.tv_usec; + + list_move_tail(&e->base.link, &e->base.file_priv->event_list); + wake_up_interruptible(&e->base.file_priv->event_wait); + drm_vblank_put(drm_dev, crtc); + } + + spin_unlock_irqrestore(&drm_dev->event_lock, flags); +} + static irqreturn_t fimd_irq_handler(int irq, void *dev_id) { struct fimd_context *ctx = (struct fimd_context *)dev_id; @@ -682,7 +710,7 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id) goto out; drm_handle_vblank(drm_dev, manager->pipe); - exynos_drm_crtc_finish_pageflip(drm_dev, manager->pipe); + fimd_finish_pageflip(drm_dev, manager->pipe); /* set wait vsync event to zero and wake up queue. */ if (atomic_read(&ctx->wait_vsync_event)) { @@ -1018,7 +1046,7 @@ static int fimd_resume(struct device *dev) * of pm runtime would still be 1 so in this case, fimd driver * should be on directly not drawing on pm runtime interface. */ - if (!pm_runtime_suspended(dev)) { + if (pm_runtime_suspended(dev)) { int ret; ret = fimd_activate(ctx, true); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c index 473180776528..d48183e7e056 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -3,10 +3,24 @@ * Copyright (c) 2011 Samsung Electronics Co., Ltd. * Author: Inki Dae * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #include diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h index 35ebac47dc2b..f11f2afd5bfc 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h @@ -3,10 +3,24 @@ * Copyright (c) 2011 Samsung Electronics Co., Ltd. * Authoer: Inki Dae * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_GEM_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_gsc.c index 8140753ec9c8..4b0e8589bd19 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -25,7 +25,7 @@ #include "exynos_drm_gsc.h" /* - * GSC stands for General SCaler and + * GSC is stand for General SCaler and * supports image scaler/rotator and input/output DMA operations. * input DMA reads image data from the memory. * output DMA writes image data to memory. @@ -711,7 +711,7 @@ static int gsc_src_set_addr(struct device *dev, { struct gsc_context *ctx = get_gsc_context(dev); struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; - struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; + struct drm_exynos_ipp_cmd_node *c_node = ippdrv->cmd; struct drm_exynos_ipp_property *property; if (!c_node) { @@ -720,6 +720,10 @@ static int gsc_src_set_addr(struct device *dev, } property = &c_node->property; + if (!property) { + DRM_ERROR("failed to get property.\n"); + return -EFAULT; + } DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__, property->prop_id, buf_id, buf_type); @@ -1167,7 +1171,7 @@ static int gsc_dst_set_addr(struct device *dev, { struct gsc_context *ctx = get_gsc_context(dev); struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; - struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; + struct drm_exynos_ipp_cmd_node *c_node = ippdrv->cmd; struct drm_exynos_ipp_property *property; if (!c_node) { @@ -1176,6 +1180,10 @@ static int gsc_dst_set_addr(struct device *dev, } property = &c_node->property; + if (!property) { + DRM_ERROR("failed to get property.\n"); + return -EFAULT; + } DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__, property->prop_id, buf_id, buf_type); @@ -1304,7 +1312,7 @@ static irqreturn_t gsc_irq_handler(int irq, void *dev_id) { struct gsc_context *ctx = dev_id; struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; - struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; + struct drm_exynos_ipp_cmd_node *c_node = ippdrv->cmd; struct drm_exynos_ipp_event_work *event_work = c_node->event_work; u32 status; @@ -1391,7 +1399,7 @@ static inline bool gsc_check_drm_flip(enum drm_exynos_flip flip) case EXYNOS_DRM_FLIP_NONE: case EXYNOS_DRM_FLIP_VERTICAL: case EXYNOS_DRM_FLIP_HORIZONTAL: - case EXYNOS_DRM_FLIP_BOTH: + case EXYNOS_DRM_FLIP_VERTICAL | EXYNOS_DRM_FLIP_HORIZONTAL: return true; default: DRM_DEBUG_KMS("%s:invalid flip\n", __func__); @@ -1541,7 +1549,7 @@ static int gsc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd) { struct gsc_context *ctx = get_gsc_context(dev); struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; - struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; + struct drm_exynos_ipp_cmd_node *c_node = ippdrv->cmd; struct drm_exynos_ipp_property *property; struct drm_exynos_ipp_config *config; struct drm_exynos_pos img_pos[EXYNOS_DRM_OPS_MAX]; @@ -1557,6 +1565,10 @@ static int gsc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd) } property = &c_node->property; + if (!property) { + DRM_ERROR("failed to get property.\n"); + return -EINVAL; + } gsc_handle_irq(ctx, true, false, true); @@ -1592,7 +1604,7 @@ static int gsc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd) exynos_drm_ippnb_send_event(IPP_SET_WRITEBACK, (void *)&set_wb); /* src local path */ - cfg = gsc_read(GSC_IN_CON); + cfg = readl(GSC_IN_CON); cfg &= ~(GSC_IN_PATH_MASK | GSC_IN_LOCAL_SEL_MASK); cfg |= (GSC_IN_PATH_LOCAL | GSC_IN_LOCAL_FIMD_WB); gsc_write(cfg, GSC_IN_CON); @@ -1684,25 +1696,34 @@ static int gsc_probe(struct platform_device *pdev) return -ENOMEM; /* clock control */ - ctx->gsc_clk = devm_clk_get(dev, "gscl"); + ctx->gsc_clk = clk_get(dev, "gscl"); if (IS_ERR(ctx->gsc_clk)) { dev_err(dev, "failed to get gsc clock.\n"); - return PTR_ERR(ctx->gsc_clk); + ret = PTR_ERR(ctx->gsc_clk); + goto err_ctx; } /* resource memory */ ctx->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!ctx->regs_res) { + dev_err(dev, "failed to find registers.\n"); + ret = -ENOENT; + goto err_clk; + } + ctx->regs = devm_request_and_ioremap(dev, ctx->regs_res); if (!ctx->regs) { dev_err(dev, "failed to map registers.\n"); - return -ENXIO; + ret = -ENXIO; + goto err_clk; } /* resource irq */ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "failed to request irq resource.\n"); - return -ENOENT; + ret = -ENOENT; + goto err_get_regs; } ctx->irq = res->start; @@ -1710,7 +1731,7 @@ static int gsc_probe(struct platform_device *pdev) IRQF_ONESHOT, "drm_gsc", ctx); if (ret < 0) { dev_err(dev, "failed to request irq.\n"); - return ret; + goto err_get_regs; } /* context initailization */ @@ -1754,6 +1775,12 @@ static int gsc_probe(struct platform_device *pdev) pm_runtime_disable(dev); err_get_irq: free_irq(ctx->irq, ctx); +err_get_regs: + devm_iounmap(dev, ctx->regs); +err_clk: + clk_put(ctx->gsc_clk); +err_ctx: + devm_kfree(dev, ctx); return ret; } @@ -1771,6 +1798,11 @@ static int gsc_remove(struct platform_device *pdev) pm_runtime_disable(dev); free_irq(ctx->irq, ctx); + devm_iounmap(dev, ctx->regs); + + clk_put(ctx->gsc_clk); + + devm_kfree(dev, ctx); return 0; } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_gsc.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_gsc.h index 29ec1c5efcf2..b3c3bc618c0f 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_gsc.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_gsc.h @@ -6,10 +6,24 @@ * Jinyoung Jeon * Sangmin Lee * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_GSC_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h index 784a7e9a766c..fcc3093ec8fe 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h @@ -3,10 +3,24 @@ * Copyright (c) 2011 Samsung Electronics Co., Ltd. * Authoer: Inki Dae * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_HDMI_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_iommu.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_iommu.c index 3799d5c2b5df..2482b7f96341 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_iommu.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_iommu.c @@ -3,10 +3,24 @@ * Copyright (c) 2012 Samsung Electronics Co., Ltd. * Author: Inki Dae * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #include diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_iommu.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_iommu.h index 53b7deea8ab7..18a0ca190b98 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_iommu.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_iommu.h @@ -3,10 +3,24 @@ * Copyright (c) 2012 Samsung Electronics Co., Ltd. * Authoer: Inki Dae * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_IOMMU_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 0bda96454a02..c1f12301224c 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -27,7 +27,7 @@ #include "exynos_drm_iommu.h" /* - * IPP stands for Image Post Processing and + * IPP is stand for Image Post Processing and * supports image scaler/rotator and input/output DMA operations. * using FIMC, GSC, Rotator, so on. * IPP is integration device driver of same attribute h/w @@ -1292,7 +1292,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, property->prop_id); /* store command info in ippdrv */ - ippdrv->c_node = c_node; + ippdrv->cmd = c_node; if (!ipp_check_mem_list(c_node)) { DRM_DEBUG_KMS("%s:empty memory.\n", __func__); @@ -1303,7 +1303,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, ret = ipp_set_property(ippdrv, property); if (ret) { DRM_ERROR("failed to set property.\n"); - ippdrv->c_node = NULL; + ippdrv->cmd = NULL; return ret; } @@ -1487,6 +1487,11 @@ void ipp_sched_cmd(struct work_struct *work) mutex_lock(&c_node->cmd_lock); property = &c_node->property; + if (!property) { + DRM_ERROR("failed to get property:prop_id[%d]\n", + c_node->property.prop_id); + goto err_unlock; + } switch (cmd_work->ctrl) { case IPP_CTRL_PLAY: @@ -1699,7 +1704,7 @@ void ipp_sched_event(struct work_struct *work) return; } - c_node = ippdrv->c_node; + c_node = ippdrv->cmd; if (!c_node) { DRM_ERROR("failed to get command node.\n"); return; @@ -1890,7 +1895,7 @@ static int ipp_probe(struct platform_device *pdev) struct exynos_drm_subdrv *subdrv; int ret; - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; @@ -1911,7 +1916,8 @@ static int ipp_probe(struct platform_device *pdev) ctx->event_workq = create_singlethread_workqueue("ipp_event"); if (!ctx->event_workq) { dev_err(dev, "failed to create event workqueue\n"); - return -EINVAL; + ret = -EINVAL; + goto err_clear; } /* @@ -1952,6 +1958,8 @@ static int ipp_probe(struct platform_device *pdev) destroy_workqueue(ctx->cmd_workq); err_event_workq: destroy_workqueue(ctx->event_workq); +err_clear: + kfree(ctx); return ret; } @@ -1977,6 +1985,8 @@ static int ipp_remove(struct platform_device *pdev) destroy_workqueue(ctx->cmd_workq); destroy_workqueue(ctx->event_workq); + kfree(ctx); + return 0; } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_ipp.h index 4cadbea7dbde..28ffac95386c 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_ipp.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_ipp.h @@ -6,10 +6,24 @@ * Jinyoung Jeon * Sangmin Lee * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_IPP_H_ @@ -146,7 +160,7 @@ struct exynos_drm_ipp_ops { * @dedicated: dedicated ipp device. * @ops: source, destination operations. * @event_workq: event work queue. - * @c_node: current command information. + * @cmd: current command information. * @cmd_list: list head for command information. * @prop_list: property informations of current ipp driver. * @check_property: check property about format, size, buffer. @@ -164,7 +178,7 @@ struct exynos_drm_ippdrv { bool dedicated; struct exynos_drm_ipp_ops *ops[EXYNOS_DRM_OPS_MAX]; struct workqueue_struct *event_workq; - struct drm_exynos_ipp_cmd_node *c_node; + struct drm_exynos_ipp_cmd_node *cmd; struct list_head cmd_list; struct drm_exynos_ipp_prop_list *prop_list; diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_rotator.c index e9e83ef688f0..c748850737a1 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_rotator.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_rotator.c @@ -139,7 +139,7 @@ static irqreturn_t rotator_irq_handler(int irq, void *arg) { struct rot_context *rot = arg; struct exynos_drm_ippdrv *ippdrv = &rot->ippdrv; - struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; + struct drm_exynos_ipp_cmd_node *c_node = ippdrv->cmd; struct drm_exynos_ipp_event_work *event_work = c_node->event_work; enum rot_irq_status irq_status; u32 val; @@ -513,7 +513,6 @@ static inline bool rotator_check_drm_flip(enum drm_exynos_flip flip) case EXYNOS_DRM_FLIP_NONE: case EXYNOS_DRM_FLIP_VERTICAL: case EXYNOS_DRM_FLIP_HORIZONTAL: - case EXYNOS_DRM_FLIP_BOTH: return true; default: DRM_DEBUG_KMS("%s:invalid flip\n", __func__); @@ -656,26 +655,34 @@ static int rotator_probe(struct platform_device *pdev) platform_get_device_id(pdev)->driver_data; rot->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!rot->regs_res) { + dev_err(dev, "failed to find registers\n"); + ret = -ENOENT; + goto err_get_resource; + } + rot->regs = devm_request_and_ioremap(dev, rot->regs_res); if (!rot->regs) { dev_err(dev, "failed to map register\n"); - return -ENXIO; + ret = -ENXIO; + goto err_get_resource; } rot->irq = platform_get_irq(pdev, 0); if (rot->irq < 0) { dev_err(dev, "failed to get irq\n"); - return rot->irq; + ret = rot->irq; + goto err_get_irq; } ret = request_threaded_irq(rot->irq, NULL, rotator_irq_handler, IRQF_ONESHOT, "drm_rotator", rot); if (ret < 0) { dev_err(dev, "failed to request irq\n"); - return ret; + goto err_get_irq; } - rot->clock = devm_clk_get(dev, "rotator"); + rot->clock = clk_get(dev, "rotator"); if (IS_ERR_OR_NULL(rot->clock)) { dev_err(dev, "failed to get clock\n"); ret = PTR_ERR(rot->clock); @@ -713,8 +720,13 @@ static int rotator_probe(struct platform_device *pdev) err_ippdrv_register: devm_kfree(dev, ippdrv->prop_list); pm_runtime_disable(dev); + clk_put(rot->clock); err_clk_get: free_irq(rot->irq, rot); +err_get_irq: + devm_iounmap(dev, rot->regs); +err_get_resource: + devm_kfree(dev, rot); return ret; } @@ -728,8 +740,12 @@ static int rotator_remove(struct platform_device *pdev) exynos_drm_ippdrv_unregister(ippdrv); pm_runtime_disable(dev); + clk_put(rot->clock); free_irq(rot->irq, rot); + devm_iounmap(dev, rot->regs); + + devm_kfree(dev, rot); return 0; } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_rotator.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_rotator.h index 71a0b4c0c1e8..a2d7a14a52b6 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_rotator.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_rotator.h @@ -5,10 +5,24 @@ * YoungJun Cho * Eunchul Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_ROTATOR_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c index d0ca3c4e06c6..a5c5a179e3b6 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -372,6 +372,34 @@ static struct exynos_drm_manager vidi_manager = { .display_ops = &vidi_display_ops, }; +static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc) +{ + struct exynos_drm_private *dev_priv = drm_dev->dev_private; + struct drm_pending_vblank_event *e, *t; + struct timeval now; + unsigned long flags; + + spin_lock_irqsave(&drm_dev->event_lock, flags); + + list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list, + base.link) { + /* if event's pipe isn't same as crtc then ignore it. */ + if (crtc != e->pipe) + continue; + + do_gettimeofday(&now); + e->event.sequence = 0; + e->event.tv_sec = now.tv_sec; + e->event.tv_usec = now.tv_usec; + + list_move_tail(&e->base.link, &e->base.file_priv->event_list); + wake_up_interruptible(&e->base.file_priv->event_wait); + drm_vblank_put(drm_dev, crtc); + } + + spin_unlock_irqrestore(&drm_dev->event_lock, flags); +} + static void vidi_fake_vblank_handler(struct work_struct *work) { struct vidi_context *ctx = container_of(work, struct vidi_context, @@ -396,7 +424,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work) mutex_unlock(&ctx->lock); - exynos_drm_crtc_finish_pageflip(subdrv->drm_dev, manager->pipe); + vidi_finish_pageflip(subdrv->drm_dev, manager->pipe); } static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev) diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.h index 1e5fdaa36ccc..a4babe4e65d7 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.h @@ -3,10 +3,24 @@ * Copyright (c) 2012 Samsung Electronics Co., Ltd. * Author: Inki Dae * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_VIDI_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.h b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.h index 0ddf3957de15..1c3b6d8f1fe7 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.h @@ -5,10 +5,24 @@ * Inki Dae * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_HDMI_H_ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c index c187ea33b748..3f68b34fa127 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c @@ -35,7 +35,6 @@ #include #include "exynos_drm_drv.h" -#include "exynos_drm_crtc.h" #include "exynos_drm_hdmi.h" #include "exynos_drm_iommu.h" @@ -950,6 +949,35 @@ static struct exynos_mixer_ops mixer_ops = { .win_disable = mixer_win_disable, }; +/* for pageflip event */ +static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc) +{ + struct exynos_drm_private *dev_priv = drm_dev->dev_private; + struct drm_pending_vblank_event *e, *t; + struct timeval now; + unsigned long flags; + + spin_lock_irqsave(&drm_dev->event_lock, flags); + + list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list, + base.link) { + /* if event's pipe isn't same as crtc then ignore it. */ + if (crtc != e->pipe) + continue; + + do_gettimeofday(&now); + e->event.sequence = 0; + e->event.tv_sec = now.tv_sec; + e->event.tv_usec = now.tv_usec; + + list_move_tail(&e->base.link, &e->base.file_priv->event_list); + wake_up_interruptible(&e->base.file_priv->event_wait); + drm_vblank_put(drm_dev, crtc); + } + + spin_unlock_irqrestore(&drm_dev->event_lock, flags); +} + static irqreturn_t mixer_irq_handler(int irq, void *arg) { struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg; @@ -978,8 +1006,7 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg) } drm_handle_vblank(drm_hdmi_ctx->drm_dev, ctx->pipe); - exynos_drm_crtc_finish_pageflip(drm_hdmi_ctx->drm_dev, - ctx->pipe); + mixer_finish_pageflip(drm_hdmi_ctx->drm_dev, ctx->pipe); /* set wait vsync event to zero and wake up queue. */ if (atomic_read(&ctx->wait_vsync_event)) { diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 8febea6daa08..da3c82e301b1 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -1717,8 +1717,7 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj) } static long -__i915_gem_shrink(struct drm_i915_private *dev_priv, long target, - bool purgeable_only) +i915_gem_purge(struct drm_i915_private *dev_priv, long target) { struct drm_i915_gem_object *obj, *next; long count = 0; @@ -1726,7 +1725,7 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list, gtt_list) { - if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) && + if (i915_gem_object_is_purgeable(obj) && i915_gem_object_put_pages(obj) == 0) { count += obj->base.size >> PAGE_SHIFT; if (count >= target) @@ -1737,7 +1736,7 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, list_for_each_entry_safe(obj, next, &dev_priv->mm.inactive_list, mm_list) { - if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) && + if (i915_gem_object_is_purgeable(obj) && i915_gem_object_unbind(obj) == 0 && i915_gem_object_put_pages(obj) == 0) { count += obj->base.size >> PAGE_SHIFT; @@ -1749,12 +1748,6 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, return count; } -static long -i915_gem_purge(struct drm_i915_private *dev_priv, long target) -{ - return __i915_gem_shrink(dev_priv, target, true); -} - static void i915_gem_shrink_all(struct drm_i915_private *dev_priv) { @@ -3529,15 +3522,14 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, goto out; } - if (obj->user_pin_count == 0) { + obj->user_pin_count++; + obj->pin_filp = file; + if (obj->user_pin_count == 1) { ret = i915_gem_object_pin(obj, args->alignment, true, false); if (ret) goto out; } - obj->user_pin_count++; - obj->pin_filp = file; - /* XXX - flush the CPU caches for pinned objects * as the X server doesn't manage domains yet */ @@ -4402,9 +4394,6 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) if (nr_to_scan) { nr_to_scan -= i915_gem_purge(dev_priv, nr_to_scan); - if (nr_to_scan > 0) - nr_to_scan -= __i915_gem_shrink(dev_priv, nr_to_scan, - false); if (nr_to_scan > 0) i915_gem_shrink_all(dev_priv); } @@ -4413,7 +4402,7 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list) if (obj->pages_pin_count == 0) cnt += obj->base.size >> PAGE_SHIFT; - list_for_each_entry(obj, &dev_priv->mm.inactive_list, gtt_list) + list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) if (obj->pin_count == 0 && obj->pages_pin_count == 0) cnt += obj->base.size >> PAGE_SHIFT; diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/trunk/drivers/gpu/drm/i915/i915_gem_dmabuf.c index abeaafef6d7e..7be4241e8242 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_dmabuf.c @@ -266,12 +266,7 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, obj = dma_buf->priv; /* is it from our device? */ if (obj->base.dev == dev) { - /* - * Importing dmabuf exported from out own gem increases - * refcount on gem itself instead of f_count of dmabuf. - */ drm_gem_object_reference(&obj->base); - dma_buf_put(dma_buf); return &obj->base; } } diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index da1ad9c80bb5..a9fb046b94a1 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -8598,30 +8598,19 @@ int intel_framebuffer_init(struct drm_device *dev, { int ret; - if (obj->tiling_mode == I915_TILING_Y) { - DRM_DEBUG("hardware does not support tiling Y\n"); + if (obj->tiling_mode == I915_TILING_Y) return -EINVAL; - } - if (mode_cmd->pitches[0] & 63) { - DRM_DEBUG("pitch (%d) must be at least 64 byte aligned\n", - mode_cmd->pitches[0]); + if (mode_cmd->pitches[0] & 63) return -EINVAL; - } /* FIXME <= Gen4 stride limits are bit unclear */ - if (mode_cmd->pitches[0] > 32768) { - DRM_DEBUG("pitch (%d) must be at less than 32768\n", - mode_cmd->pitches[0]); + if (mode_cmd->pitches[0] > 32768) return -EINVAL; - } if (obj->tiling_mode != I915_TILING_NONE && - mode_cmd->pitches[0] != obj->stride) { - DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n", - mode_cmd->pitches[0], obj->stride); + mode_cmd->pitches[0] != obj->stride) return -EINVAL; - } /* Reject formats not supported by any plane early. */ switch (mode_cmd->pixel_format) { @@ -8632,10 +8621,8 @@ int intel_framebuffer_init(struct drm_device *dev, break; case DRM_FORMAT_XRGB1555: case DRM_FORMAT_ARGB1555: - if (INTEL_INFO(dev)->gen > 3) { - DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); + if (INTEL_INFO(dev)->gen > 3) return -EINVAL; - } break; case DRM_FORMAT_XBGR8888: case DRM_FORMAT_ABGR8888: @@ -8643,22 +8630,18 @@ int intel_framebuffer_init(struct drm_device *dev, case DRM_FORMAT_ARGB2101010: case DRM_FORMAT_XBGR2101010: case DRM_FORMAT_ABGR2101010: - if (INTEL_INFO(dev)->gen < 4) { - DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); + if (INTEL_INFO(dev)->gen < 4) return -EINVAL; - } break; case DRM_FORMAT_YUYV: case DRM_FORMAT_UYVY: case DRM_FORMAT_YVYU: case DRM_FORMAT_VYUY: - if (INTEL_INFO(dev)->gen < 5) { - DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); + if (INTEL_INFO(dev)->gen < 6) return -EINVAL; - } break; default: - DRM_DEBUG("unsupported pixel format 0x%08x\n", mode_cmd->pixel_format); + DRM_DEBUG_KMS("unsupported pixel format 0x%08x\n", mode_cmd->pixel_format); return -EINVAL; } diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 17aee74258ad..b9a660a53677 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -774,6 +774,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"), + }, + }, { .callback = intel_no_lvds_dmi_callback, .ident = "Gigabyte GA-D525TUD", diff --git a/trunk/drivers/gpu/drm/i915/intel_pm.c b/trunk/drivers/gpu/drm/i915/intel_pm.c index e83a11794172..e6f54ffab3ba 100644 --- a/trunk/drivers/gpu/drm/i915/intel_pm.c +++ b/trunk/drivers/gpu/drm/i915/intel_pm.c @@ -44,14 +44,6 @@ * i915.i915_enable_fbc parameter */ -static bool intel_crtc_active(struct drm_crtc *crtc) -{ - /* Be paranoid as we can arrive here with only partial - * state retrieved from the hardware during setup. - */ - return to_intel_crtc(crtc)->active && crtc->fb && crtc->mode.clock; -} - static void i8xx_disable_fbc(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -413,8 +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 (intel_crtc_active(tmp_crtc) && - !to_intel_crtc(tmp_crtc)->primary_disabled) { + if (to_intel_crtc(tmp_crtc)->active && + !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; @@ -999,7 +992,7 @@ static struct drm_crtc *single_enabled_crtc(struct drm_device *dev) struct drm_crtc *crtc, *enabled = NULL; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (intel_crtc_active(crtc)) { + if (to_intel_crtc(crtc)->active && crtc->fb) { if (enabled) return NULL; enabled = crtc; @@ -1093,7 +1086,7 @@ static bool g4x_compute_wm0(struct drm_device *dev, int entries, tlb_miss; crtc = intel_get_crtc_for_plane(dev, plane); - if (!intel_crtc_active(crtc)) { + if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) { *cursor_wm = cursor->guard_size; *plane_wm = display->guard_size; return false; @@ -1222,7 +1215,7 @@ static bool vlv_compute_drain_latency(struct drm_device *dev, int entries; crtc = intel_get_crtc_for_plane(dev, plane); - if (!intel_crtc_active(crtc)) + if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) return false; clock = crtc->mode.clock; /* VESA DOT Clock */ @@ -1483,7 +1476,7 @@ static void i9xx_update_wm(struct drm_device *dev) fifo_size = dev_priv->display.get_fifo_size(dev, 0); crtc = intel_get_crtc_for_plane(dev, 0); - if (intel_crtc_active(crtc)) { + if (to_intel_crtc(crtc)->active && crtc->fb) { int cpp = crtc->fb->bits_per_pixel / 8; if (IS_GEN2(dev)) cpp = 4; @@ -1497,7 +1490,7 @@ static void i9xx_update_wm(struct drm_device *dev) fifo_size = dev_priv->display.get_fifo_size(dev, 1); crtc = intel_get_crtc_for_plane(dev, 1); - if (intel_crtc_active(crtc)) { + if (to_intel_crtc(crtc)->active && crtc->fb) { int cpp = crtc->fb->bits_per_pixel / 8; if (IS_GEN2(dev)) cpp = 4; @@ -2051,7 +2044,7 @@ sandybridge_compute_sprite_wm(struct drm_device *dev, int plane, int entries, tlb_miss; crtc = intel_get_crtc_for_plane(dev, plane); - if (!intel_crtc_active(crtc)) { + if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) { *sprite_wm = display->guard_size; return false; } diff --git a/trunk/drivers/gpu/drm/i915/intel_sprite.c b/trunk/drivers/gpu/drm/i915/intel_sprite.c index d7b060e0a231..827dcd4edf1c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sprite.c +++ b/trunk/drivers/gpu/drm/i915/intel_sprite.c @@ -120,10 +120,11 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); - linear_offset = y * fb->pitches[0] + x * pixel_size; + linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); sprsurf_offset = intel_gen4_compute_offset_xtiled(&x, &y, - pixel_size, fb->pitches[0]); + fb->bits_per_pixel / 8, + fb->pitches[0]); linear_offset -= sprsurf_offset; /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET @@ -285,10 +286,11 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x); - linear_offset = y * fb->pitches[0] + x * pixel_size; + linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); dvssurf_offset = intel_gen4_compute_offset_xtiled(&x, &y, - pixel_size, fb->pitches[0]); + fb->bits_per_pixel / 8, + fb->pitches[0]); linear_offset -= dvssurf_offset; if (obj->tiling_mode != I915_TILING_NONE) diff --git a/trunk/drivers/gpu/drm/nouveau/core/core/client.c b/trunk/drivers/gpu/drm/nouveau/core/core/client.c index 8bbb58f94a19..c617f0480071 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/core/client.c +++ b/trunk/drivers/gpu/drm/nouveau/core/core/client.c @@ -66,8 +66,10 @@ nouveau_client_create_(const char *name, u64 devname, const char *cfg, ret = nouveau_handle_create(nv_object(client), ~0, ~0, nv_object(client), &client->root); - if (ret) + if (ret) { + nouveau_namedb_destroy(&client->base); return ret; + } /* prevent init/fini being called, os in in charge of this */ atomic_set(&nv_object(client)->usecount, 2); diff --git a/trunk/drivers/gpu/drm/nouveau/core/core/handle.c b/trunk/drivers/gpu/drm/nouveau/core/core/handle.c index 264c2b338ac3..b8d2cbf8a7a7 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/core/handle.c +++ b/trunk/drivers/gpu/drm/nouveau/core/core/handle.c @@ -109,7 +109,7 @@ nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle, while (!nv_iclass(namedb, NV_NAMEDB_CLASS)) namedb = namedb->parent; - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = *phandle = kzalloc(sizeof(*handle), GFP_KERNEL); if (!handle) return -ENOMEM; @@ -146,9 +146,6 @@ nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle, } hprintk(handle, TRACE, "created\n"); - - *phandle = handle; - return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index ca1a7d76a95b..0f09af135415 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -851,23 +851,20 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) ctrl = nv_rd32(priv, 0x610b5c + (i * 8)); - if (!(ctrl & (1 << head))) { - if (nv_device(priv)->chipset < 0x90 || - nv_device(priv)->chipset == 0x92 || - nv_device(priv)->chipset == 0xa0) { - for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) - ctrl = nv_rd32(priv, 0x610b74 + (i * 8)); - i += 4; - } else { - for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) - ctrl = nv_rd32(priv, 0x610798 + (i * 8)); - i += 4; - } + if (nv_device(priv)->chipset < 0x90 || + nv_device(priv)->chipset == 0x92 || + nv_device(priv)->chipset == 0xa0) { + for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) + ctrl = nv_rd32(priv, 0x610b74 + (i * 8)); + i += 3; + } else { + for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) + ctrl = nv_rd32(priv, 0x610798 + (i * 8)); + i += 3; } if (!(ctrl & (1 << head))) return false; - i--; data = exec_lookup(priv, head, i, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info); if (data) { @@ -901,23 +898,20 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) ctrl = nv_rd32(priv, 0x610b58 + (i * 8)); - if (!(ctrl & (1 << head))) { - if (nv_device(priv)->chipset < 0x90 || - nv_device(priv)->chipset == 0x92 || - nv_device(priv)->chipset == 0xa0) { - for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) - ctrl = nv_rd32(priv, 0x610b70 + (i * 8)); - i += 4; - } else { - for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) - ctrl = nv_rd32(priv, 0x610794 + (i * 8)); - i += 4; - } + if (nv_device(priv)->chipset < 0x90 || + nv_device(priv)->chipset == 0x92 || + nv_device(priv)->chipset == 0xa0) { + for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) + ctrl = nv_rd32(priv, 0x610b70 + (i * 8)); + i += 3; + } else { + for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) + ctrl = nv_rd32(priv, 0x610794 + (i * 8)); + i += 3; } if (!(ctrl & (1 << head))) return 0x0000; - i--; data = exec_lookup(priv, head, i, ctrl, outp, &ver, &hdr, &cnt, &len, &info1); if (!data) diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/core/client.h b/trunk/drivers/gpu/drm/nouveau/core/include/core/client.h index 63acc0346ff2..0193532ceac9 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/core/client.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/core/client.h @@ -36,9 +36,6 @@ nouveau_client(void *obj) int nouveau_client_create_(const char *name, u64 device, const char *cfg, const char *dbg, int, void **); -#define nouveau_client_destroy(p) \ - nouveau_namedb_destroy(&(p)->base) - int nouveau_client_init(struct nouveau_client *); int nouveau_client_fini(struct nouveau_client *, bool suspend); diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h index b2f3d4d0aa49..c345097592f2 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h @@ -38,8 +38,6 @@ enum nvbios_pll_type { PLL_UNK42 = 0x42, PLL_VPLL0 = 0x80, PLL_VPLL1 = 0x81, - PLL_VPLL2 = 0x82, - PLL_VPLL3 = 0x83, PLL_MAX = 0xff }; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index 690ed438b2ad..2917d552689b 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c @@ -1534,6 +1534,7 @@ init_io(struct nvbios_init *init) mdelay(10); init_wr32(init, 0x614100, 0x10000018); init_wr32(init, 0x614900, 0x10000018); + return; } value = init_rdport(init, port) & mask; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c index 7c9626258a46..f6962c9b6c36 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c @@ -52,8 +52,6 @@ nvc0_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq) switch (info.type) { case PLL_VPLL0: case PLL_VPLL1: - case PLL_VPLL2: - case PLL_VPLL3: nv_mask(priv, info.reg + 0x0c, 0x00000000, 0x00000100); nv_wr32(priv, info.reg + 0x04, (P << 16) | (N << 8) | M); nv_wr32(priv, info.reg + 0x10, fN << 16); diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c index 7606ed15b6fa..306bdf121452 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c @@ -145,14 +145,14 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin, mem->memtype = type; mem->size = size; - mutex_lock(&pfb->base.mutex); + mutex_lock(&mm->mutex); do { if (back) ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r); else ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r); if (ret) { - mutex_unlock(&pfb->base.mutex); + mutex_unlock(&mm->mutex); pfb->ram.put(pfb, &mem); return ret; } @@ -160,7 +160,7 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin, list_add_tail(&r->rl_entry, &mem->regions); size -= r->length; } while (size); - mutex_unlock(&pfb->base.mutex); + mutex_unlock(&mm->mutex); r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry); mem->offset = (u64)r->offset << 12; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c index 6565f3dbbe04..1188227ca6aa 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c @@ -40,21 +40,15 @@ nouveau_instobj_create_(struct nouveau_object *parent, if (ret) return ret; - mutex_lock(&imem->base.mutex); list_add(&iobj->head, &imem->list); - mutex_unlock(&imem->base.mutex); return 0; } void nouveau_instobj_destroy(struct nouveau_instobj *iobj) { - struct nouveau_subdev *subdev = nv_subdev(iobj->base.engine); - - mutex_lock(&subdev->mutex); - list_del(&iobj->head); - mutex_unlock(&subdev->mutex); - + if (iobj->head.prev) + list_del(&iobj->head); return nouveau_object_destroy(&iobj->base); } @@ -94,8 +88,6 @@ nouveau_instmem_init(struct nouveau_instmem *imem) if (ret) return ret; - mutex_lock(&imem->base.mutex); - list_for_each_entry(iobj, &imem->list, head) { if (iobj->suspend) { for (i = 0; i < iobj->size; i += 4) @@ -105,8 +97,6 @@ nouveau_instmem_init(struct nouveau_instmem *imem) } } - mutex_unlock(&imem->base.mutex); - return 0; } @@ -114,26 +104,17 @@ int nouveau_instmem_fini(struct nouveau_instmem *imem, bool suspend) { struct nouveau_instobj *iobj; - int i, ret = 0; + int i; if (suspend) { - mutex_lock(&imem->base.mutex); - list_for_each_entry(iobj, &imem->list, head) { iobj->suspend = vmalloc(iobj->size); - if (!iobj->suspend) { - ret = -ENOMEM; - break; - } - - for (i = 0; i < iobj->size; i += 4) - iobj->suspend[i / 4] = nv_ro32(iobj, i); + if (iobj->suspend) { + for (i = 0; i < iobj->size; i += 4) + iobj->suspend[i / 4] = nv_ro32(iobj, i); + } else + return -ENOMEM; } - - mutex_unlock(&imem->base.mutex); - - if (ret) - return ret; } return nouveau_subdev_fini(&imem->base, suspend); diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/base.c index 77c67fc970e6..082c11b75acb 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/base.c @@ -352,7 +352,7 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length, u64 mm_length = (offset + length) - mm_offset; int ret; - vm = kzalloc(sizeof(*vm), GFP_KERNEL); + vm = *pvm = kzalloc(sizeof(*vm), GFP_KERNEL); if (!vm) return -ENOMEM; @@ -376,8 +376,6 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length, return ret; } - *pvm = vm; - return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c index e620ba8271b4..ac340ba32017 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -127,26 +127,12 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, struct nouveau_encoder **pnv_encoder) { struct drm_device *dev = connector->dev; - struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_gpio *gpio = nouveau_gpio(drm->device); struct nouveau_i2c *i2c = nouveau_i2c(drm->device); - struct nouveau_i2c_port *port = NULL; - int i, panel = -ENODEV; - - /* eDP panels need powering on by us (if the VBIOS doesn't default it - * to on) before doing any AUX channel transactions. LVDS panel power - * is handled by the SOR itself, and not required for LVDS DDC. - */ - if (nv_connector->type == DCB_CONNECTOR_eDP) { - panel = gpio->get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff); - if (panel == 0) { - gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1); - msleep(300); - } - } + int i; for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { + struct nouveau_i2c_port *port = NULL; struct nouveau_encoder *nv_encoder; struct drm_mode_object *obj; int id; @@ -164,19 +150,11 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, port = i2c->find(i2c, nv_encoder->dcb->i2c_index); if (port && nv_probe_i2c(port, 0x50)) { *pnv_encoder = nv_encoder; - break; + return port; } - - port = NULL; } - /* eDP panel not detected, restore panel power GPIO to previous - * state to avoid confusing the SOR for other output types. - */ - if (!port && panel == 0) - gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel); - - return port; + return NULL; } static struct nouveau_encoder * diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c index 508b00a2ce0d..e4188f24fc75 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c @@ -225,6 +225,15 @@ nouveau_display_init(struct drm_device *dev) if (ret) return ret; + /* power on internal panel if it's not already. the init tables of + * some vbios default this to off for some reason, causing the + * panel to not work after resume + */ + if (gpio && gpio->get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff) == 0) { + gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1); + msleep(300); + } + /* enable polling for external displays */ drm_kms_helper_poll_enable(dev); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c index 8b090f1eb51d..180a45e3b525 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -84,16 +84,11 @@ nouveau_cli_create(struct pci_dev *pdev, const char *name, struct nouveau_cli *cli; int ret; - *pcli = NULL; ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config, nouveau_debug, size, pcli); cli = *pcli; - if (ret) { - if (cli) - nouveau_client_destroy(&cli->base); - *pcli = NULL; + if (ret) return ret; - } mutex_init(&cli->mutex); return 0; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_fence.h b/trunk/drivers/gpu/drm/nouveau/nouveau_fence.h index cdb83acdffe2..bedafd1c9539 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_fence.h @@ -60,7 +60,6 @@ u32 nv10_fence_read(struct nouveau_channel *); void nv10_fence_context_del(struct nouveau_channel *); void nv10_fence_destroy(struct nouveau_drm *); int nv10_fence_create(struct nouveau_drm *); -void nv17_fence_resume(struct nouveau_drm *drm); int nv50_fence_create(struct nouveau_drm *); int nv84_fence_create(struct nouveau_drm *); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_prime.c b/trunk/drivers/gpu/drm/nouveau/nouveau_prime.c index b8e05ae38212..3543fec2355e 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_prime.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -193,7 +193,6 @@ struct drm_gem_object *nouveau_gem_prime_import(struct drm_device *dev, if (nvbo->gem) { if (nvbo->gem->dev == dev) { drm_gem_object_reference(nvbo->gem); - dma_buf_put(dma_buf); return nvbo->gem; } } diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c b/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c index 39ffc07f906b..184cdf806761 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -505,7 +505,7 @@ static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) static inline bool is_powersaving_dpms(int mode) { - return mode != DRM_MODE_DPMS_ON && mode != NV_DPMS_CLEARED; + return (mode != DRM_MODE_DPMS_ON); } static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) diff --git a/trunk/drivers/gpu/drm/nouveau/nv10_fence.c b/trunk/drivers/gpu/drm/nouveau/nv10_fence.c index 03017f24d593..7ae7f97a6d4d 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv10_fence.c +++ b/trunk/drivers/gpu/drm/nouveau/nv10_fence.c @@ -162,13 +162,6 @@ nv10_fence_destroy(struct nouveau_drm *drm) kfree(priv); } -void nv17_fence_resume(struct nouveau_drm *drm) -{ - struct nv10_fence_priv *priv = drm->fence; - - nouveau_bo_wr32(priv->bo, 0, priv->sequence); -} - int nv10_fence_create(struct nouveau_drm *drm) { @@ -204,7 +197,6 @@ nv10_fence_create(struct nouveau_drm *drm) if (ret == 0) { nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); priv->base.sync = nv17_fence_sync; - priv->base.resume = nv17_fence_resume; } } diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_fence.c b/trunk/drivers/gpu/drm/nouveau/nv50_fence.c index d889f3ac0d41..c20f2727ea0b 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_fence.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_fence.c @@ -122,7 +122,6 @@ nv50_fence_create(struct nouveau_drm *drm) if (ret == 0) { nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); priv->base.sync = nv17_fence_sync; - priv->base.resume = nv17_fence_resume; } if (ret) diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index 537e259b3837..923f93647042 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -2646,7 +2646,7 @@ int r600_copy_blit(struct radeon_device *rdev, * @num_gpu_pages: number of GPU pages to xfer * @fence: radeon fence object * - * Copy GPU paging using the DMA engine (r6xx). + * Copy GPU paging using the DMA engine (r6xx-r7xx). * Used by the radeon ttm implementation to move pages if * registered as the asic copy callback. */ @@ -2669,8 +2669,8 @@ int r600_copy_dma(struct radeon_device *rdev, } size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; - num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFE); - r = radeon_ring_lock(rdev, ring, num_loops * 4 + 8); + num_loops = DIV_ROUND_UP(size_in_dw, 0xffff); + r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8); if (r) { DRM_ERROR("radeon: moving bo (%d).\n", r); radeon_semaphore_free(rdev, &sem, NULL); @@ -2693,8 +2693,8 @@ int r600_copy_dma(struct radeon_device *rdev, radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw)); radeon_ring_write(ring, dst_offset & 0xfffffffc); radeon_ring_write(ring, src_offset & 0xfffffffc); - radeon_ring_write(ring, (((upper_32_bits(dst_offset) & 0xff) << 16) | - (upper_32_bits(src_offset) & 0xff))); + radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff); + radeon_ring_write(ring, upper_32_bits(src_offset) & 0xff); src_offset += cur_size_in_dw * 4; dst_offset += cur_size_in_dw * 4; } diff --git a/trunk/drivers/gpu/drm/radeon/r600_cs.c b/trunk/drivers/gpu/drm/radeon/r600_cs.c index 69ec24ab8d63..9ea13d07cc55 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_cs.c +++ b/trunk/drivers/gpu/drm/radeon/r600_cs.c @@ -2476,10 +2476,8 @@ static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error) kfree(parser->relocs); for (i = 0; i < parser->nchunks; i++) { kfree(parser->chunks[i].kdata); - if (parser->rdev && (parser->rdev->flags & RADEON_IS_AGP)) { - kfree(parser->chunks[i].kpage[0]); - kfree(parser->chunks[i].kpage[1]); - } + kfree(parser->chunks[i].kpage[0]); + kfree(parser->chunks[i].kpage[1]); } kfree(parser->chunks); kfree(parser->chunks_array); @@ -2563,16 +2561,16 @@ int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, struct radeon_cs_chunk *relocs_chunk; unsigned idx; - *cs_reloc = NULL; if (p->chunk_relocs_idx == -1) { DRM_ERROR("No relocation chunk !\n"); return -EINVAL; } + *cs_reloc = NULL; relocs_chunk = &p->chunks[p->chunk_relocs_idx]; idx = p->dma_reloc_idx; - if (idx >= p->nrelocs) { + if (idx >= relocs_chunk->length_dw) { DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", - idx, p->nrelocs); + idx, relocs_chunk->length_dw); return -EINVAL; } *cs_reloc = p->relocs_ptr[idx]; @@ -2679,29 +2677,16 @@ int r600_dma_cs_parse(struct radeon_cs_parser *p) } p->idx += 7; } else { - if (p->family >= CHIP_RV770) { - src_offset = ib[idx+2]; - src_offset |= ((u64)(ib[idx+4] & 0xff)) << 32; - dst_offset = ib[idx+1]; - dst_offset |= ((u64)(ib[idx+3] & 0xff)) << 32; - - ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); - ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); - ib[idx+3] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; - ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; - p->idx += 5; - } else { - src_offset = ib[idx+2]; - src_offset |= ((u64)(ib[idx+3] & 0xff)) << 32; - dst_offset = ib[idx+1]; - dst_offset |= ((u64)(ib[idx+3] & 0xff0000)) << 16; + src_offset = ib[idx+2]; + src_offset |= ((u64)(ib[idx+4] & 0xff)) << 32; + dst_offset = ib[idx+1]; + dst_offset |= ((u64)(ib[idx+3] & 0xff)) << 32; - ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); - ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); - ib[idx+3] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; - ib[idx+3] += (upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff) << 16; - p->idx += 4; - } + ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); + ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); + ib[idx+3] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; + ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; + p->idx += 5; } if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { dev_warn(p->dev, "DMA copy src buffer too small (%llu %lu)\n", diff --git a/trunk/drivers/gpu/drm/radeon/radeon_asic.c b/trunk/drivers/gpu/drm/radeon/radeon_asic.c index 9056fafb00ea..596bcbe80ed0 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_asic.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_asic.c @@ -1140,9 +1140,9 @@ static struct radeon_asic rv770_asic = { .copy = { .blit = &r600_copy_blit, .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = &rv770_copy_dma, + .dma = &r600_copy_dma, .dma_ring_index = R600_RING_TYPE_DMA_INDEX, - .copy = &rv770_copy_dma, + .copy = &r600_copy_dma, .copy_ring_index = R600_RING_TYPE_DMA_INDEX, }, .surface = { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_asic.h b/trunk/drivers/gpu/drm/radeon/radeon_asic.h index 15d70e613076..5f4882cc2152 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_asic.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_asic.h @@ -403,10 +403,6 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); void r700_cp_stop(struct radeon_device *rdev); void r700_cp_fini(struct radeon_device *rdev); -int rv770_copy_dma(struct radeon_device *rdev, - uint64_t src_offset, uint64_t dst_offset, - unsigned num_gpu_pages, - struct radeon_fence **fence); /* * evergreen diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cs.c b/trunk/drivers/gpu/drm/radeon/radeon_cs.c index 469661fd1903..396baba0141a 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cs.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cs.c @@ -279,13 +279,13 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) p->chunks[p->chunk_ib_idx].length_dw); return -EINVAL; } - if (p->rdev && (p->rdev->flags & RADEON_IS_AGP)) { + if ((p->rdev->flags & RADEON_IS_AGP)) { p->chunks[p->chunk_ib_idx].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); p->chunks[p->chunk_ib_idx].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); if (p->chunks[p->chunk_ib_idx].kpage[0] == NULL || p->chunks[p->chunk_ib_idx].kpage[1] == NULL) { - kfree(p->chunks[p->chunk_ib_idx].kpage[0]); - kfree(p->chunks[p->chunk_ib_idx].kpage[1]); + kfree(p->chunks[i].kpage[0]); + kfree(p->chunks[i].kpage[1]); return -ENOMEM; } } @@ -583,8 +583,7 @@ static int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx) struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; int i; int size = PAGE_SIZE; - bool copy1 = (p->rdev && (p->rdev->flags & RADEON_IS_AGP)) ? - false : true; + bool copy1 = (p->rdev->flags & RADEON_IS_AGP) ? false : true; for (i = ibc->last_copied_page + 1; i < pg_idx; i++) { if (DRM_COPY_FROM_USER(p->ib.ptr + (i * (PAGE_SIZE/4)), diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index edfc54e41842..cd756262924d 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -896,25 +896,6 @@ static void radeon_check_arguments(struct radeon_device *rdev) } } -/** - * radeon_switcheroo_quirk_long_wakeup - return true if longer d3 delay is - * needed for waking up. - * - * @pdev: pci dev pointer - */ -static bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev) -{ - - /* 6600m in a macbook pro */ - if (pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE && - pdev->subsystem_device == 0x00e2) { - printk(KERN_INFO "radeon: quirking longer d3 wakeup delay\n"); - return true; - } - - return false; -} - /** * radeon_switcheroo_set_state - set switcheroo state * @@ -929,19 +910,10 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero struct drm_device *dev = pci_get_drvdata(pdev); pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; if (state == VGA_SWITCHEROO_ON) { - unsigned d3_delay = dev->pdev->d3_delay; - printk(KERN_INFO "radeon: switched on\n"); /* don't suspend or resume card normally */ dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - - if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev)) - dev->pdev->d3_delay = 20; - radeon_resume_kms(dev); - - dev->pdev->d3_delay = d3_delay; - dev->switch_power_state = DRM_SWITCH_POWER_ON; drm_kms_helper_poll_enable(dev); } else { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 62cd512f5c8d..f5ba2241dacc 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -640,14 +640,6 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc enum drm_connector_status found = connector_status_disconnected; bool color = true; - /* just don't bother on RN50 those chip are often connected to remoting - * console hw and often we get failure to load detect those. So to make - * everyone happy report the encoder as always connected. - */ - if (ASIC_IS_RN50(rdev)) { - return connector_status_connected; - } - /* save the regs we need */ vclk_ecp_cntl = RREG32_PLL(RADEON_VCLK_ECP_CNTL); crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_prime.c b/trunk/drivers/gpu/drm/radeon/radeon_prime.c index 26c23bb651c6..e09521858f64 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_prime.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_prime.c @@ -194,7 +194,6 @@ struct drm_gem_object *radeon_gem_prime_import(struct drm_device *dev, bo = dma_buf->priv; if (bo->gem_base.dev == dev) { drm_gem_object_reference(&bo->gem_base); - dma_buf_put(dma_buf); return &bo->gem_base; } } diff --git a/trunk/drivers/gpu/drm/radeon/rv770.c b/trunk/drivers/gpu/drm/radeon/rv770.c index 1b2444f4d8f4..87c979c4f721 100644 --- a/trunk/drivers/gpu/drm/radeon/rv770.c +++ b/trunk/drivers/gpu/drm/radeon/rv770.c @@ -887,80 +887,6 @@ static int rv770_mc_init(struct radeon_device *rdev) return 0; } -/** - * rv770_copy_dma - copy pages using the DMA engine - * - * @rdev: radeon_device pointer - * @src_offset: src GPU address - * @dst_offset: dst GPU address - * @num_gpu_pages: number of GPU pages to xfer - * @fence: radeon fence object - * - * Copy GPU paging using the DMA engine (r7xx). - * Used by the radeon ttm implementation to move pages if - * registered as the asic copy callback. - */ -int rv770_copy_dma(struct radeon_device *rdev, - uint64_t src_offset, uint64_t dst_offset, - unsigned num_gpu_pages, - struct radeon_fence **fence) -{ - struct radeon_semaphore *sem = NULL; - int ring_index = rdev->asic->copy.dma_ring_index; - struct radeon_ring *ring = &rdev->ring[ring_index]; - u32 size_in_dw, cur_size_in_dw; - int i, num_loops; - int r = 0; - - r = radeon_semaphore_create(rdev, &sem); - if (r) { - DRM_ERROR("radeon: moving bo (%d).\n", r); - return r; - } - - size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; - num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFF); - r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8); - if (r) { - DRM_ERROR("radeon: moving bo (%d).\n", r); - radeon_semaphore_free(rdev, &sem, NULL); - return r; - } - - if (radeon_fence_need_sync(*fence, ring->idx)) { - radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, - ring->idx); - radeon_fence_note_sync(*fence, ring->idx); - } else { - radeon_semaphore_free(rdev, &sem, NULL); - } - - for (i = 0; i < num_loops; i++) { - cur_size_in_dw = size_in_dw; - if (cur_size_in_dw > 0xFFFF) - cur_size_in_dw = 0xFFFF; - size_in_dw -= cur_size_in_dw; - radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw)); - radeon_ring_write(ring, dst_offset & 0xfffffffc); - radeon_ring_write(ring, src_offset & 0xfffffffc); - radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff); - radeon_ring_write(ring, upper_32_bits(src_offset) & 0xff); - src_offset += cur_size_in_dw * 4; - dst_offset += cur_size_in_dw * 4; - } - - r = radeon_fence_emit(rdev, fence, ring->idx); - if (r) { - radeon_ring_unlock_undo(rdev, ring); - return r; - } - - radeon_ring_unlock_commit(rdev, ring); - radeon_semaphore_free(rdev, &sem, *fence); - - return r; -} - static int rv770_startup(struct radeon_device *rdev) { struct radeon_ring *ring; diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo_util.c b/trunk/drivers/gpu/drm/ttm/ttm_bo_util.c index d73d6e3e17b2..9e9c5d2a5c74 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -654,13 +654,11 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, */ set_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags); - - /* ttm_buffer_object_transfer accesses bo->sync_obj */ - ret = ttm_buffer_object_transfer(bo, &ghost_obj); spin_unlock(&bdev->fence_lock); if (tmp_obj) driver->sync_obj_unref(&tmp_obj); + ret = ttm_buffer_object_transfer(bo, &ghost_obj); if (ret) return ret; diff --git a/trunk/drivers/gpu/drm/udl/udl_connector.c b/trunk/drivers/gpu/drm/udl/udl_connector.c index fe5cdbcf2636..512f44add89f 100644 --- a/trunk/drivers/gpu/drm/udl/udl_connector.c +++ b/trunk/drivers/gpu/drm/udl/udl_connector.c @@ -22,17 +22,13 @@ static u8 *udl_get_edid(struct udl_device *udl) { u8 *block; - char *rbuf; + char rbuf[3]; int ret, i; block = kmalloc(EDID_LENGTH, GFP_KERNEL); if (block == NULL) return NULL; - rbuf = kmalloc(2, GFP_KERNEL); - if (rbuf == NULL) - goto error; - for (i = 0; i < EDID_LENGTH; i++) { ret = usb_control_msg(udl->ddev->usbdev, usb_rcvctrlpipe(udl->ddev->usbdev, 0), (0x02), @@ -40,17 +36,16 @@ static u8 *udl_get_edid(struct udl_device *udl) HZ); if (ret < 1) { DRM_ERROR("Read EDID byte %d failed err %x\n", i, ret); + i--; goto error; } block[i] = rbuf[1]; } - kfree(rbuf); return block; error: kfree(block); - kfree(rbuf); return NULL; } @@ -62,14 +57,6 @@ static int udl_get_modes(struct drm_connector *connector) edid = (struct edid *)udl_get_edid(udl); - /* - * We only read the main block, but if the monitor reports extension - * blocks then the drm edid code expects them to be present, so patch - * the extension count to 0. - */ - edid->checksum += edid->extensions; - edid->extensions = 0; - drm_mode_connector_update_edid_property(connector, edid); ret = drm_add_edid_modes(connector, edid); kfree(edid); diff --git a/trunk/drivers/hwmon/vexpress.c b/trunk/drivers/hwmon/vexpress.c index d867e6bb2be1..86d7f6d858b1 100644 --- a/trunk/drivers/hwmon/vexpress.c +++ b/trunk/drivers/hwmon/vexpress.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/iio/accel/Kconfig b/trunk/drivers/iio/accel/Kconfig index 05e996fafc9d..fe4bcd7c5b12 100644 --- a/trunk/drivers/iio/accel/Kconfig +++ b/trunk/drivers/iio/accel/Kconfig @@ -8,7 +8,6 @@ config HID_SENSOR_ACCEL_3D select IIO_BUFFER select IIO_TRIGGERED_BUFFER select HID_SENSOR_IIO_COMMON - select HID_SENSOR_IIO_TRIGGER tristate "HID Accelerometers 3D" help Say yes here to build support for the HID SENSOR diff --git a/trunk/drivers/iio/adc/ad7266.c b/trunk/drivers/iio/adc/ad7266.c index bbad9b94cd75..4a5f639bc684 100644 --- a/trunk/drivers/iio/adc/ad7266.c +++ b/trunk/drivers/iio/adc/ad7266.c @@ -411,11 +411,7 @@ static int ad7266_probe(struct spi_device *spi) if (ret) goto error_put_reg; - ret = regulator_get_voltage(st->reg); - if (ret < 0) - goto error_disable_reg; - - st->vref_uv = ret; + st->vref_uv = regulator_get_voltage(st->reg); } else { /* Use internal reference */ st->vref_uv = 2500000; diff --git a/trunk/drivers/iio/adc/at91_adc.c b/trunk/drivers/iio/adc/at91_adc.c index a526c0e3aaa8..04b013561f0f 100644 --- a/trunk/drivers/iio/adc/at91_adc.c +++ b/trunk/drivers/iio/adc/at91_adc.c @@ -80,7 +80,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p) *timestamp = pf->timestamp; } - iio_push_to_buffers(idev, (u8 *)st->buffer); + iio_push_to_buffers(indio_dev, (u8 *)st->buffer); iio_trigger_notify_done(idev->trig); diff --git a/trunk/drivers/iio/adc/max1363.c b/trunk/drivers/iio/adc/max1363.c index 03b25b3dc71e..b5669be6f396 100644 --- a/trunk/drivers/iio/adc/max1363.c +++ b/trunk/drivers/iio/adc/max1363.c @@ -1605,20 +1605,19 @@ static int max1363_probe(struct i2c_client *client, return 0; error_free_irq: - if (client->irq) - free_irq(st->client->irq, indio_dev); + free_irq(st->client->irq, indio_dev); error_uninit_buffer: iio_buffer_unregister(indio_dev); error_cleanup_buffer: max1363_buffer_cleanup(indio_dev); error_free_available_scan_masks: kfree(indio_dev->available_scan_masks); +error_unregister_map: + iio_map_array_unregister(indio_dev, client->dev.platform_data); error_disable_reg: regulator_disable(st->reg); error_put_reg: regulator_put(st->reg); -error_unregister_map: - iio_map_array_unregister(indio_dev, client->dev.platform_data); error_free_device: iio_device_free(indio_dev); error_out: @@ -1636,8 +1635,10 @@ static int max1363_remove(struct i2c_client *client) iio_buffer_unregister(indio_dev); max1363_buffer_cleanup(indio_dev); kfree(indio_dev->available_scan_masks); - regulator_disable(st->reg); - regulator_put(st->reg); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } iio_map_array_unregister(indio_dev, client->dev.platform_data); iio_device_free(indio_dev); diff --git a/trunk/drivers/iio/common/hid-sensors/Kconfig b/trunk/drivers/iio/common/hid-sensors/Kconfig index 1178121b55b0..ae10778da7aa 100644 --- a/trunk/drivers/iio/common/hid-sensors/Kconfig +++ b/trunk/drivers/iio/common/hid-sensors/Kconfig @@ -6,7 +6,7 @@ menu "Hid Sensor IIO Common" config HID_SENSOR_IIO_COMMON tristate "Common modules for all HID Sensor IIO drivers" depends on HID_SENSOR_HUB - select HID_SENSOR_IIO_TRIGGER if IIO_BUFFER + select IIO_TRIGGER if IIO_BUFFER help Say yes here to build support for HID sensor to use HID sensor common processing for attributes and IIO triggers. @@ -14,17 +14,6 @@ config HID_SENSOR_IIO_COMMON HID sensor drivers, this module contains processing for those attributes. -config HID_SENSOR_IIO_TRIGGER - tristate "Common module (trigger) for all HID Sensor IIO drivers" - depends on HID_SENSOR_HUB && HID_SENSOR_IIO_COMMON - select IIO_TRIGGER - help - Say yes here to build trigger support for HID sensors. - Triggers will be send if all requested attributes were read. - - If this driver is compiled as a module, it will be named - hid-sensor-trigger. - config HID_SENSOR_ENUM_BASE_QUIRKS bool "ENUM base quirks for HID Sensor IIO drivers" depends on HID_SENSOR_IIO_COMMON diff --git a/trunk/drivers/iio/common/hid-sensors/Makefile b/trunk/drivers/iio/common/hid-sensors/Makefile index 22e7c5a82325..1f463e00c242 100644 --- a/trunk/drivers/iio/common/hid-sensors/Makefile +++ b/trunk/drivers/iio/common/hid-sensors/Makefile @@ -3,5 +3,4 @@ # obj-$(CONFIG_HID_SENSOR_IIO_COMMON) += hid-sensor-iio-common.o -obj-$(CONFIG_HID_SENSOR_IIO_TRIGGER) += hid-sensor-trigger.o -hid-sensor-iio-common-y := hid-sensor-attributes.o +hid-sensor-iio-common-y := hid-sensor-attributes.o hid-sensor-trigger.o diff --git a/trunk/drivers/iio/dac/ad5380.c b/trunk/drivers/iio/dac/ad5380.c index 483fc379a2da..6c7898c765d9 100644 --- a/trunk/drivers/iio/dac/ad5380.c +++ b/trunk/drivers/iio/dac/ad5380.c @@ -406,11 +406,7 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap, goto error_free_reg; } - ret = regulator_get_voltage(st->vref_reg); - if (ret < 0) - goto error_disable_reg; - - st->vref = ret; + st->vref = regulator_get_voltage(st->vref_reg); } else { st->vref = st->chip_info->int_vref; ctrl |= AD5380_CTRL_INT_VREF_EN; diff --git a/trunk/drivers/iio/dac/ad5446.c b/trunk/drivers/iio/dac/ad5446.c index f5583aedfb59..29f653dab2f7 100644 --- a/trunk/drivers/iio/dac/ad5446.c +++ b/trunk/drivers/iio/dac/ad5446.c @@ -226,11 +226,7 @@ static int ad5446_probe(struct device *dev, const char *name, if (ret) goto error_put_reg; - ret = regulator_get_voltage(reg); - if (ret < 0) - goto error_disable_reg; - - voltage_uv = ret; + voltage_uv = regulator_get_voltage(reg); } indio_dev = iio_device_alloc(sizeof(*st)); diff --git a/trunk/drivers/iio/dac/ad5504.c b/trunk/drivers/iio/dac/ad5504.c index 0661829f2773..b2a31a0468ed 100644 --- a/trunk/drivers/iio/dac/ad5504.c +++ b/trunk/drivers/iio/dac/ad5504.c @@ -296,11 +296,7 @@ static int ad5504_probe(struct spi_device *spi) if (ret) goto error_put_reg; - ret = regulator_get_voltage(reg); - if (ret < 0) - goto error_disable_reg; - - voltage_uv = ret; + voltage_uv = regulator_get_voltage(reg); } spi_set_drvdata(spi, indio_dev); diff --git a/trunk/drivers/iio/dac/ad5624r_spi.c b/trunk/drivers/iio/dac/ad5624r_spi.c index f6e116627b71..e9947969f9fe 100644 --- a/trunk/drivers/iio/dac/ad5624r_spi.c +++ b/trunk/drivers/iio/dac/ad5624r_spi.c @@ -238,11 +238,7 @@ static int ad5624r_probe(struct spi_device *spi) if (ret) goto error_put_reg; - ret = regulator_get_voltage(st->reg); - if (ret < 0) - goto error_disable_reg; - - voltage_uv = ret; + voltage_uv = regulator_get_voltage(st->reg); } spi_set_drvdata(spi, indio_dev); diff --git a/trunk/drivers/iio/dac/ad5686.c b/trunk/drivers/iio/dac/ad5686.c index ca9609d7a15c..36e51382ae52 100644 --- a/trunk/drivers/iio/dac/ad5686.c +++ b/trunk/drivers/iio/dac/ad5686.c @@ -332,11 +332,7 @@ static int ad5686_probe(struct spi_device *spi) if (ret) goto error_put_reg; - ret = regulator_get_voltage(st->reg); - if (ret < 0) - goto error_disable_reg; - - voltage_uv = ret; + voltage_uv = regulator_get_voltage(st->reg); } st->chip_info = diff --git a/trunk/drivers/iio/dac/ad5791.c b/trunk/drivers/iio/dac/ad5791.c index 6407b5407ddd..c84180f23139 100644 --- a/trunk/drivers/iio/dac/ad5791.c +++ b/trunk/drivers/iio/dac/ad5791.c @@ -365,11 +365,7 @@ static int ad5791_probe(struct spi_device *spi) if (ret) goto error_put_reg_pos; - ret = regulator_get_voltage(st->reg_vdd); - if (ret < 0) - goto error_disable_reg_pos; - - pos_voltage_uv = ret; + pos_voltage_uv = regulator_get_voltage(st->reg_vdd); } st->reg_vss = regulator_get(&spi->dev, "vss"); @@ -378,11 +374,7 @@ static int ad5791_probe(struct spi_device *spi) if (ret) goto error_put_reg_neg; - ret = regulator_get_voltage(st->reg_vss); - if (ret < 0) - goto error_disable_reg_neg; - - neg_voltage_uv = ret; + neg_voltage_uv = regulator_get_voltage(st->reg_vss); } st->pwr_down = true; @@ -436,7 +428,6 @@ static int ad5791_probe(struct spi_device *spi) if (!IS_ERR(st->reg_vss)) regulator_put(st->reg_vss); -error_disable_reg_pos: if (!IS_ERR(st->reg_vdd)) regulator_disable(st->reg_vdd); error_put_reg_pos: diff --git a/trunk/drivers/iio/frequency/adf4350.c b/trunk/drivers/iio/frequency/adf4350.c index a884252ac66b..e5033b4cfba0 100644 --- a/trunk/drivers/iio/frequency/adf4350.c +++ b/trunk/drivers/iio/frequency/adf4350.c @@ -173,7 +173,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) } while ((st->r1_mod > ADF4350_MAX_MODULUS) && r_cnt); } while (r_cnt == 0); - tmp = freq * (u64)st->r1_mod + (st->fpfd >> 1); + tmp = freq * (u64)st->r1_mod + (st->fpfd > 1); do_div(tmp, st->fpfd); /* Div round closest (n + d/2)/d */ st->r0_fract = do_div(tmp, st->r1_mod); st->r0_int = tmp; diff --git a/trunk/drivers/iio/gyro/Kconfig b/trunk/drivers/iio/gyro/Kconfig index 96b68f63a902..48ed1483ff27 100644 --- a/trunk/drivers/iio/gyro/Kconfig +++ b/trunk/drivers/iio/gyro/Kconfig @@ -17,7 +17,6 @@ config HID_SENSOR_GYRO_3D select IIO_BUFFER select IIO_TRIGGERED_BUFFER select HID_SENSOR_IIO_COMMON - select HID_SENSOR_IIO_TRIGGER tristate "HID Gyroscope 3D" help Say yes here to build support for the HID SENSOR diff --git a/trunk/drivers/iio/light/Kconfig b/trunk/drivers/iio/light/Kconfig index dbf80abc834f..1763c9bcb98a 100644 --- a/trunk/drivers/iio/light/Kconfig +++ b/trunk/drivers/iio/light/Kconfig @@ -47,7 +47,6 @@ config HID_SENSOR_ALS select IIO_BUFFER select IIO_TRIGGERED_BUFFER select HID_SENSOR_IIO_COMMON - select HID_SENSOR_IIO_TRIGGER tristate "HID ALS" help Say yes here to build support for the HID SENSOR diff --git a/trunk/drivers/iio/magnetometer/Kconfig b/trunk/drivers/iio/magnetometer/Kconfig index ff11d68225cf..c1f0cdd57037 100644 --- a/trunk/drivers/iio/magnetometer/Kconfig +++ b/trunk/drivers/iio/magnetometer/Kconfig @@ -8,7 +8,6 @@ config HID_SENSOR_MAGNETOMETER_3D select IIO_BUFFER select IIO_TRIGGERED_BUFFER select HID_SENSOR_IIO_COMMON - select HID_SENSOR_IIO_TRIGGER tristate "HID Magenetometer 3D" help Say yes here to build support for the HID SENSOR diff --git a/trunk/drivers/misc/mei/amthif.c b/trunk/drivers/misc/mei/amthif.c index e40ffd9502d1..18794aea6062 100644 --- a/trunk/drivers/misc/mei/amthif.c +++ b/trunk/drivers/misc/mei/amthif.c @@ -187,13 +187,13 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, wait_ret = wait_event_interruptible(dev->iamthif_cl.wait, (cb = mei_amthif_find_read_list_entry(dev, file))); - /* Locking again the Mutex */ - mutex_lock(&dev->device_lock); - if (wait_ret) return -ERESTARTSYS; dev_dbg(&dev->pdev->dev, "woke up from sleep\n"); + + /* Locking again the Mutex */ + mutex_lock(&dev->device_lock); } diff --git a/trunk/drivers/net/ethernet/adi/Kconfig b/trunk/drivers/net/ethernet/adi/Kconfig index a9481606bbcd..e49c0eff040b 100644 --- a/trunk/drivers/net/ethernet/adi/Kconfig +++ b/trunk/drivers/net/ethernet/adi/Kconfig @@ -61,7 +61,6 @@ config BFIN_RX_DESC_NUM config BFIN_MAC_USE_HWSTAMP bool "Use IEEE 1588 hwstamp" - depends on BFIN_MAC && BF518 select PTP_1588_CLOCK default y ---help--- diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index f771ddfba646..01588b66a38c 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -80,37 +80,12 @@ static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to) new_txdata_index = new_max_eth_txqs + FCOE_TXQ_IDX_OFFSET; } - memcpy(&bp->bnx2x_txq[new_txdata_index], - &bp->bnx2x_txq[old_txdata_index], + memcpy(&bp->bnx2x_txq[old_txdata_index], + &bp->bnx2x_txq[new_txdata_index], sizeof(struct bnx2x_fp_txdata)); to_fp->txdata_ptr[0] = &bp->bnx2x_txq[new_txdata_index]; } -/** - * bnx2x_shrink_eth_fp - guarantees fastpath structures stay intact - * - * @bp: driver handle - * @delta: number of eth queues which were not allocated - */ -static void bnx2x_shrink_eth_fp(struct bnx2x *bp, int delta) -{ - int i, cos, old_eth_num = BNX2X_NUM_ETH_QUEUES(bp); - - /* Queue pointer cannot be re-set on an fp-basis, as moving pointer - * backward along the array could cause memory to be overriden - */ - for (cos = 1; cos < bp->max_cos; cos++) { - for (i = 0; i < old_eth_num - delta; i++) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - int new_idx = cos * (old_eth_num - delta) + i; - - memcpy(&bp->bnx2x_txq[new_idx], fp->txdata_ptr[cos], - sizeof(struct bnx2x_fp_txdata)); - fp->txdata_ptr[cos] = &bp->bnx2x_txq[new_idx]; - } - } -} - int load_count[2][3] = { {0} }; /* per-path: 0-common, 1-port0, 2-port1 */ /* free skb in the packet ring at pos idx @@ -3888,7 +3863,6 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) int delta = BNX2X_NUM_ETH_QUEUES(bp) - i; WARN_ON(delta < 0); - bnx2x_shrink_eth_fp(bp, delta); if (CNIC_SUPPORT(bp)) /* move non eth FPs next to last eth FP * must be done in that order diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index a427b49a886c..277f17e3c8f8 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -2777,10 +2777,10 @@ static int bnx2x_set_rss_flags(struct bnx2x *bp, struct ethtool_rxnfc *info) } else if ((info->flow_type == UDP_V6_FLOW) && (bp->rss_conf_obj.udp_rss_v6 != udp_rss_requested)) { bp->rss_conf_obj.udp_rss_v6 = udp_rss_requested; + return bnx2x_config_rss_pf(bp, &bp->rss_conf_obj, 0); DP(BNX2X_MSG_ETHTOOL, "rss re-configured, UDP 4-tupple %s\n", udp_rss_requested ? "enabled" : "disabled"); - return bnx2x_config_rss_pf(bp, &bp->rss_conf_obj, 0); } else { return 0; } diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 5523da3afcdc..940ef859dc60 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -127,17 +127,6 @@ MODULE_PARM_DESC(debug, " Default debug msglevel"); struct workqueue_struct *bnx2x_wq; -struct bnx2x_mac_vals { - u32 xmac_addr; - u32 xmac_val; - u32 emac_addr; - u32 emac_val; - u32 umac_addr; - u32 umac_val; - u32 bmac_addr; - u32 bmac_val[2]; -}; - enum bnx2x_board_type { BCM57710 = 0, BCM57711, @@ -9431,19 +9420,12 @@ static inline void bnx2x_undi_int_disable(struct bnx2x *bp) bnx2x_undi_int_disable_e1h(bp); } -static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, - struct bnx2x_mac_vals *vals) +static void bnx2x_prev_unload_close_mac(struct bnx2x *bp) { u32 val, base_addr, offset, mask, reset_reg; bool mac_stopped = false; u8 port = BP_PORT(bp); - /* reset addresses as they also mark which values were changed */ - vals->bmac_addr = 0; - vals->umac_addr = 0; - vals->xmac_addr = 0; - vals->emac_addr = 0; - reset_reg = REG_RD(bp, MISC_REG_RESET_REG_2); if (!CHIP_IS_E3(bp)) { @@ -9465,18 +9447,14 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, */ wb_data[0] = REG_RD(bp, base_addr + offset); wb_data[1] = REG_RD(bp, base_addr + offset + 0x4); - vals->bmac_addr = base_addr + offset; - vals->bmac_val[0] = wb_data[0]; - vals->bmac_val[1] = wb_data[1]; wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; - REG_WR(bp, vals->bmac_addr, wb_data[0]); - REG_WR(bp, vals->bmac_addr + 0x4, wb_data[1]); + REG_WR(bp, base_addr + offset, wb_data[0]); + REG_WR(bp, base_addr + offset + 0x4, wb_data[1]); } BNX2X_DEV_INFO("Disable emac Rx\n"); - vals->emac_addr = NIG_REG_NIG_EMAC0_EN + BP_PORT(bp)*4; - vals->emac_val = REG_RD(bp, vals->emac_addr); - REG_WR(bp, vals->emac_addr, 0); + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + BP_PORT(bp)*4, 0); + mac_stopped = true; } else { if (reset_reg & MISC_REGISTERS_RESET_REG_2_XMAC) { @@ -9487,18 +9465,14 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, val & ~(1 << 1)); REG_WR(bp, base_addr + XMAC_REG_PFC_CTRL_HI, val | (1 << 1)); - vals->xmac_addr = base_addr + XMAC_REG_CTRL; - vals->xmac_val = REG_RD(bp, vals->xmac_addr); - REG_WR(bp, vals->xmac_addr, 0); + REG_WR(bp, base_addr + XMAC_REG_CTRL, 0); mac_stopped = true; } mask = MISC_REGISTERS_RESET_REG_2_UMAC0 << port; if (mask & reset_reg) { BNX2X_DEV_INFO("Disable umac Rx\n"); base_addr = BP_PORT(bp) ? GRCBASE_UMAC1 : GRCBASE_UMAC0; - vals->umac_addr = base_addr + UMAC_REG_COMMAND_CONFIG; - vals->umac_val = REG_RD(bp, vals->umac_addr); - REG_WR(bp, vals->umac_addr, 0); + REG_WR(bp, base_addr + UMAC_REG_COMMAND_CONFIG, 0); mac_stopped = true; } } @@ -9690,16 +9664,12 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) { u32 reset_reg, tmp_reg = 0, rc; bool prev_undi = false; - struct bnx2x_mac_vals mac_vals; - /* It is possible a previous function received 'common' answer, * but hasn't loaded yet, therefore creating a scenario of * multiple functions receiving 'common' on the same path. */ BNX2X_DEV_INFO("Common unload Flow\n"); - memset(&mac_vals, 0, sizeof(mac_vals)); - if (bnx2x_prev_is_path_marked(bp)) return bnx2x_prev_mcp_done(bp); @@ -9710,10 +9680,7 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) u32 timer_count = 1000; /* Close the MAC Rx to prevent BRB from filling up */ - bnx2x_prev_unload_close_mac(bp, &mac_vals); - - /* close LLH filters towards the BRB */ - bnx2x_set_rx_filter(&bp->link_params, 0); + bnx2x_prev_unload_close_mac(bp); /* Check if the UNDI driver was previously loaded * UNDI driver initializes CID offset for normal bell to 0x7 @@ -9760,17 +9727,6 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) /* No packets are in the pipeline, path is ready for reset */ bnx2x_reset_common(bp); - if (mac_vals.xmac_addr) - REG_WR(bp, mac_vals.xmac_addr, mac_vals.xmac_val); - if (mac_vals.umac_addr) - REG_WR(bp, mac_vals.umac_addr, mac_vals.umac_val); - if (mac_vals.emac_addr) - REG_WR(bp, mac_vals.emac_addr, mac_vals.emac_val); - if (mac_vals.bmac_addr) { - REG_WR(bp, mac_vals.bmac_addr, mac_vals.bmac_val[0]); - REG_WR(bp, mac_vals.bmac_addr + 4, mac_vals.bmac_val[1]); - } - rc = bnx2x_prev_mark_path(bp, prev_undi); if (rc) { bnx2x_prev_mcp_done(bp); diff --git a/trunk/drivers/net/ethernet/emulex/benet/be.h b/trunk/drivers/net/ethernet/emulex/benet/be.h index 4eba17b83ba8..3bc1912afba9 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be.h +++ b/trunk/drivers/net/ethernet/emulex/benet/be.h @@ -190,7 +190,6 @@ struct be_eq_obj { u8 idx; /* array index */ u16 tx_budget; - u16 spurious_intr; struct napi_struct napi; struct be_adapter *adapter; } ____cacheline_aligned_in_smp; diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_main.c b/trunk/drivers/net/ethernet/emulex/benet/be_main.c index 5c995700e534..9dca22be8125 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_main.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_main.c @@ -2026,30 +2026,19 @@ static irqreturn_t be_intx(int irq, void *dev) struct be_adapter *adapter = eqo->adapter; int num_evts = 0; - /* IRQ is not expected when NAPI is scheduled as the EQ - * will not be armed. - * But, this can happen on Lancer INTx where it takes - * a while to de-assert INTx or in BE2 where occasionaly - * an interrupt may be raised even when EQ is unarmed. - * If NAPI is already scheduled, then counting & notifying - * events will orphan them. + /* On Lancer, clear-intr bit of the EQ DB does not work. + * INTx is de-asserted only on notifying num evts. */ - if (napi_schedule_prep(&eqo->napi)) { + if (lancer_chip(adapter)) num_evts = events_get(eqo); - __napi_schedule(&eqo->napi); - if (num_evts) - eqo->spurious_intr = 0; - } - be_eq_notify(adapter, eqo->q.id, false, true, num_evts); - /* Return IRQ_HANDLED only for the the first spurious intr - * after a valid intr to stop the kernel from branding - * this irq as a bad one! + /* The EQ-notify may not de-assert INTx rightaway, causing + * the ISR to be invoked again. So, return HANDLED even when + * num_evts is zero. */ - if (num_evts || eqo->spurious_intr++ == 0) - return IRQ_HANDLED; - else - return IRQ_NONE; + be_eq_notify(adapter, eqo->q.id, false, true, num_evts); + napi_schedule(&eqo->napi); + return IRQ_HANDLED; } static irqreturn_t be_msix(int irq, void *dev) diff --git a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 3e73742024b0..f80cd975daed 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -4678,7 +4678,7 @@ static int qlge_probe(struct pci_dev *pdev, qdev = netdev_priv(ndev); SET_NETDEV_DEV(ndev, &pdev->dev); ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_TSO | NETIF_F_TSO_ECN | + NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN | NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM; ndev->features = ndev->hw_features | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; diff --git a/trunk/drivers/net/ethernet/xilinx/Kconfig b/trunk/drivers/net/ethernet/xilinx/Kconfig index 122d60c0481b..5778a4ae1164 100644 --- a/trunk/drivers/net/ethernet/xilinx/Kconfig +++ b/trunk/drivers/net/ethernet/xilinx/Kconfig @@ -27,7 +27,7 @@ config XILINX_EMACLITE config XILINX_AXI_EMAC tristate "Xilinx 10/100/1000 AXI Ethernet support" - depends on MICROBLAZE + depends on (PPC32 || MICROBLAZE) select PHYLIB ---help--- This driver supports the 10/100/1000 Ethernet from Xilinx for the diff --git a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 6f47100e58d7..d9f69b82cc4f 100644 --- a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -1590,7 +1590,7 @@ static int axienet_of_probe(struct platform_device *op) lp->rx_irq = irq_of_parse_and_map(np, 1); lp->tx_irq = irq_of_parse_and_map(np, 0); of_node_put(np); - if ((lp->rx_irq <= 0) || (lp->tx_irq <= 0)) { + if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) { dev_err(&op->dev, "could not determine irqs\n"); ret = -ENOMEM; goto err_iounmap_2; diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index c81680dc10eb..fbd106edbe59 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -185,7 +185,6 @@ struct tun_struct { unsigned long ageing_time; unsigned int numdisabled; struct list_head disabled; - void *security; }; static inline u32 tun_hashfn(u32 rxhash) @@ -405,8 +404,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean) struct tun_struct *tun; struct net_device *dev; - tun = rtnl_dereference(tfile->tun); - + tun = rcu_dereference_protected(tfile->tun, + lockdep_rtnl_is_held()); if (tun) { u16 index = tfile->queue_index; BUG_ON(index >= tun->numqueues); @@ -415,7 +414,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean) rcu_assign_pointer(tun->tfiles[index], tun->tfiles[tun->numqueues - 1]); rcu_assign_pointer(tfile->tun, NULL); - ntfile = rtnl_dereference(tun->tfiles[index]); + ntfile = rcu_dereference_protected(tun->tfiles[index], + lockdep_rtnl_is_held()); ntfile->queue_index = index; --tun->numqueues; @@ -429,10 +429,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean) /* Drop read queue */ skb_queue_purge(&tfile->sk.sk_receive_queue); tun_set_real_num_queues(tun); - } else if (tfile->detached && clean) { + } else if (tfile->detached && clean) tun = tun_enable_queue(tfile); - sock_put(&tfile->sk); - } if (clean) { if (tun && tun->numqueues == 0 && tun->numdisabled == 0 && @@ -460,7 +458,8 @@ static void tun_detach_all(struct net_device *dev) int i, n = tun->numqueues; for (i = 0; i < n; i++) { - tfile = rtnl_dereference(tun->tfiles[i]); + tfile = rcu_dereference_protected(tun->tfiles[i], + lockdep_rtnl_is_held()); BUG_ON(!tfile); wake_up_all(&tfile->wq.wait); rcu_assign_pointer(tfile->tun, NULL); @@ -470,7 +469,8 @@ static void tun_detach_all(struct net_device *dev) synchronize_net(); for (i = 0; i < n; i++) { - tfile = rtnl_dereference(tun->tfiles[i]); + tfile = rcu_dereference_protected(tun->tfiles[i], + lockdep_rtnl_is_held()); /* Drop read queue */ skb_queue_purge(&tfile->sk.sk_receive_queue); sock_put(&tfile->sk); @@ -481,9 +481,6 @@ static void tun_detach_all(struct net_device *dev) sock_put(&tfile->sk); } BUG_ON(tun->numdisabled != 0); - - if (tun->flags & TUN_PERSIST) - module_put(THIS_MODULE); } static int tun_attach(struct tun_struct *tun, struct file *file) @@ -491,12 +488,8 @@ static int tun_attach(struct tun_struct *tun, struct file *file) struct tun_file *tfile = file->private_data; int err; - err = security_tun_dev_attach(tfile->socket.sk, tun->security); - if (err < 0) - goto out; - err = -EINVAL; - if (rtnl_dereference(tfile->tun)) + if (rcu_dereference_protected(tfile->tun, lockdep_rtnl_is_held())) goto out; err = -EBUSY; @@ -1378,7 +1371,6 @@ static void tun_free_netdev(struct net_device *dev) BUG_ON(!(list_empty(&tun->disabled))); tun_flow_uninit(tun); - security_tun_dev_free_security(tun->security); free_netdev(dev); } @@ -1552,9 +1544,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) struct net_device *dev; int err; - if (tfile->detached) - return -EINVAL; - dev = __dev_get_by_name(net, ifr->ifr_name); if (dev) { if (ifr->ifr_flags & IFF_TUN_EXCL) @@ -1568,7 +1557,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (tun_not_capable(tun)) return -EPERM; - err = security_tun_dev_open(tun->security); + err = security_tun_dev_attach(tfile->socket.sk); if (err < 0) return err; @@ -1625,9 +1614,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) spin_lock_init(&tun->lock); - err = security_tun_dev_alloc_security(&tun->security); - if (err < 0) - goto err_free_dev; + security_tun_dev_post_create(&tfile->sk); tun_net_init(dev); @@ -1751,7 +1738,8 @@ static void tun_detach_filter(struct tun_struct *tun, int n) struct tun_file *tfile; for (i = 0; i < n; i++) { - tfile = rtnl_dereference(tun->tfiles[i]); + tfile = rcu_dereference_protected(tun->tfiles[i], + lockdep_rtnl_is_held()); sk_detach_filter(tfile->socket.sk); } @@ -1764,7 +1752,8 @@ static int tun_attach_filter(struct tun_struct *tun) struct tun_file *tfile; for (i = 0; i < tun->numqueues; i++) { - tfile = rtnl_dereference(tun->tfiles[i]); + tfile = rcu_dereference_protected(tun->tfiles[i], + lockdep_rtnl_is_held()); ret = sk_attach_filter(&tun->fprog, tfile->socket.sk); if (ret) { tun_detach_filter(tun, i); @@ -1782,7 +1771,8 @@ static void tun_set_sndbuf(struct tun_struct *tun) int i; for (i = 0; i < tun->numqueues; i++) { - tfile = rtnl_dereference(tun->tfiles[i]); + tfile = rcu_dereference_protected(tun->tfiles[i], + lockdep_rtnl_is_held()); tfile->socket.sk->sk_sndbuf = tun->sndbuf; } } @@ -1797,16 +1787,15 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr) if (ifr->ifr_flags & IFF_ATTACH_QUEUE) { tun = tfile->detached; - if (!tun) { + if (!tun) ret = -EINVAL; - goto unlock; - } - ret = security_tun_dev_attach_queue(tun->security); - if (ret < 0) - goto unlock; - ret = tun_attach(tun, file); + else if (tun_not_capable(tun)) + ret = -EPERM; + else + ret = tun_attach(tun, file); } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { - tun = rtnl_dereference(tfile->tun); + tun = rcu_dereference_protected(tfile->tun, + lockdep_rtnl_is_held()); if (!tun || !(tun->flags & TUN_TAP_MQ)) ret = -EINVAL; else @@ -1814,7 +1803,6 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr) } else ret = -EINVAL; -unlock: rtnl_unlock(); return ret; } @@ -1892,11 +1880,10 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, /* Disable/Enable persist mode. Keep an extra reference to the * module to prevent the module being unprobed. */ - if (arg && !(tun->flags & TUN_PERSIST)) { + if (arg) { tun->flags |= TUN_PERSIST; __module_get(THIS_MODULE); - } - if (!arg && (tun->flags & TUN_PERSIST)) { + } else { tun->flags &= ~TUN_PERSIST; module_put(THIS_MODULE); } diff --git a/trunk/drivers/pci/iov.c b/trunk/drivers/pci/iov.c index c18e5bf444fa..bafd2bbcaf65 100644 --- a/trunk/drivers/pci/iov.c +++ b/trunk/drivers/pci/iov.c @@ -739,7 +739,7 @@ EXPORT_SYMBOL_GPL(pci_num_vf); /** * pci_sriov_set_totalvfs -- reduce the TotalVFs available * @dev: the PCI PF device - * @numvfs: number that should be used for TotalVFs supported + * numvfs: number that should be used for TotalVFs supported * * Should be called from PF driver's probe routine with * device's mutex held. diff --git a/trunk/drivers/pinctrl/mvebu/pinctrl-dove.c b/trunk/drivers/pinctrl/mvebu/pinctrl-dove.c index 69aba3697287..750dea78f53a 100644 --- a/trunk/drivers/pinctrl/mvebu/pinctrl-dove.c +++ b/trunk/drivers/pinctrl/mvebu/pinctrl-dove.c @@ -595,11 +595,8 @@ static int dove_pinctrl_probe(struct platform_device *pdev) * grab clk to make sure it is ticking. */ clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "Unable to get pdma clock"); - return PTR_RET(clk); - } - clk_prepare_enable(clk); + if (!IS_ERR(clk)) + clk_prepare_enable(clk); return mvebu_pinctrl_probe(pdev); } diff --git a/trunk/drivers/platform/x86/acer-wmi.c b/trunk/drivers/platform/x86/acer-wmi.c index afed7018a2b5..06f4eb7ab87e 100644 --- a/trunk/drivers/platform/x86/acer-wmi.c +++ b/trunk/drivers/platform/x86/acer-wmi.c @@ -125,11 +125,8 @@ static const struct key_entry acer_wmi_keymap[] = { {KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} }, {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ {KE_IGNORE, 0x81, {KEY_SLEEP} }, - {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad Toggle */ - {KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} }, - {KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} }, + {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad On/Off */ {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} }, - {KE_KEY, 0x85, {KEY_TOUCHPAD_TOGGLE} }, {KE_END, 0} }; @@ -150,7 +147,6 @@ struct event_return_value { #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */ #define ACER_WMID3_GDS_WIMAX (1<<7) /* WiMAX */ #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */ -#define ACER_WMID3_GDS_TOUCHPAD (1<<1) /* Touchpad */ struct lm_input_params { u8 function_num; /* Function Number */ @@ -879,7 +875,7 @@ WMI_execute_u32(u32 method_id, u32 in, u32 *out) struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) }; struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; - u32 tmp = 0; + u32 tmp; acpi_status status; status = wmi_evaluate_method(WMID_GUID1, 1, method_id, &input, &result); @@ -888,14 +884,14 @@ WMI_execute_u32(u32 method_id, u32 in, u32 *out) return status; obj = (union acpi_object *) result.pointer; - if (obj) { - if (obj->type == ACPI_TYPE_BUFFER && - (obj->buffer.length == sizeof(u32) || - obj->buffer.length == sizeof(u64))) { - tmp = *((u32 *) obj->buffer.pointer); - } else if (obj->type == ACPI_TYPE_INTEGER) { - tmp = (u32) obj->integer.value; - } + if (obj && obj->type == ACPI_TYPE_BUFFER && + (obj->buffer.length == sizeof(u32) || + obj->buffer.length == sizeof(u64))) { + tmp = *((u32 *) obj->buffer.pointer); + } else if (obj->type == ACPI_TYPE_INTEGER) { + tmp = (u32) obj->integer.value; + } else { + tmp = 0; } if (out) @@ -1197,14 +1193,12 @@ static acpi_status WMID_set_capabilities(void) return status; obj = (union acpi_object *) out.pointer; - if (obj) { - if (obj->type == ACPI_TYPE_BUFFER && - (obj->buffer.length == sizeof(u32) || - obj->buffer.length == sizeof(u64))) { - devices = *((u32 *) obj->buffer.pointer); - } else if (obj->type == ACPI_TYPE_INTEGER) { - devices = (u32) obj->integer.value; - } + if (obj && obj->type == ACPI_TYPE_BUFFER && + (obj->buffer.length == sizeof(u32) || + obj->buffer.length == sizeof(u64))) { + devices = *((u32 *) obj->buffer.pointer); + } else if (obj->type == ACPI_TYPE_INTEGER) { + devices = (u32) obj->integer.value; } else { kfree(out.pointer); return AE_ERROR; @@ -1682,7 +1676,6 @@ static void acer_wmi_notify(u32 value, void *context) acpi_status status; u16 device_state; const struct key_entry *key; - u32 scancode; status = wmi_get_event_data(value, &response); if (status != AE_OK) { @@ -1719,7 +1712,6 @@ static void acer_wmi_notify(u32 value, void *context) pr_warn("Unknown key number - 0x%x\n", return_value.key_num); } else { - scancode = return_value.key_num; switch (key->keycode) { case KEY_WLAN: case KEY_BLUETOOTH: @@ -1733,11 +1725,9 @@ static void acer_wmi_notify(u32 value, void *context) rfkill_set_sw_state(bluetooth_rfkill, !(device_state & ACER_WMID3_GDS_BLUETOOTH)); break; - case KEY_TOUCHPAD_TOGGLE: - scancode = (device_state & ACER_WMID3_GDS_TOUCHPAD) ? - KEY_TOUCHPAD_ON : KEY_TOUCHPAD_OFF; } - sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true); + sparse_keymap_report_entry(acer_wmi_input_dev, key, + 1, true); } break; case WMID_ACCEL_EVENT: @@ -1956,14 +1946,12 @@ static u32 get_wmid_devices(void) return 0; obj = (union acpi_object *) out.pointer; - if (obj) { - if (obj->type == ACPI_TYPE_BUFFER && - (obj->buffer.length == sizeof(u32) || - obj->buffer.length == sizeof(u64))) { - devices = *((u32 *) obj->buffer.pointer); - } else if (obj->type == ACPI_TYPE_INTEGER) { - devices = (u32) obj->integer.value; - } + if (obj && obj->type == ACPI_TYPE_BUFFER && + (obj->buffer.length == sizeof(u32) || + obj->buffer.length == sizeof(u64))) { + devices = *((u32 *) obj->buffer.pointer); + } else if (obj->type == ACPI_TYPE_INTEGER) { + devices = (u32) obj->integer.value; } kfree(out.pointer); diff --git a/trunk/drivers/platform/x86/asus-laptop.c b/trunk/drivers/platform/x86/asus-laptop.c index fcde4e528819..ec1d3bc2dbe2 100644 --- a/trunk/drivers/platform/x86/asus-laptop.c +++ b/trunk/drivers/platform/x86/asus-laptop.c @@ -860,10 +860,8 @@ static ssize_t show_infos(struct device *dev, /* * The HWRS method return informations about the hardware. * 0x80 bit is for WLAN, 0x100 for Bluetooth. - * 0x40 for WWAN, 0x10 for WIMAX. * The significance of others is yet to be found. - * We don't currently use this for device detection, and it - * takes several seconds to run on some systems. + * If we don't find the method, we assume the device are present. */ rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp); if (!ACPI_FAILURE(rv)) @@ -1684,7 +1682,7 @@ static int asus_laptop_get_info(struct asus_laptop *asus) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *model = NULL; - unsigned long long bsts_result; + unsigned long long bsts_result, hwrs_result; char *string = NULL; acpi_status status; @@ -1743,9 +1741,20 @@ static int asus_laptop_get_info(struct asus_laptop *asus) return -ENOMEM; } - if (string) + if (*string) pr_notice(" %s model detected\n", string); + /* + * The HWRS method return informations about the hardware. + * 0x80 bit is for WLAN, 0x100 for Bluetooth, + * 0x40 for WWAN, 0x10 for WIMAX. + * The significance of others is yet to be found. + */ + status = + acpi_evaluate_integer(asus->handle, "HWRS", NULL, &hwrs_result); + if (!ACPI_FAILURE(status)) + pr_notice(" HWRS returned %x", (int)hwrs_result); + if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) asus->have_rsts = true; diff --git a/trunk/drivers/platform/x86/samsung-laptop.c b/trunk/drivers/platform/x86/samsung-laptop.c index 71623a2ff3e8..dd90d15f5210 100644 --- a/trunk/drivers/platform/x86/samsung-laptop.c +++ b/trunk/drivers/platform/x86/samsung-laptop.c @@ -1523,16 +1523,6 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .driver_data = &samsung_broken_acpi_video, }, - { - .callback = samsung_dmi_matched, - .ident = "N250P", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N250P"), - DMI_MATCH(DMI_BOARD_NAME, "N250P"), - }, - .driver_data = &samsung_broken_acpi_video, - }, { }, }; MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); diff --git a/trunk/drivers/platform/x86/sony-laptop.c b/trunk/drivers/platform/x86/sony-laptop.c index b8ad71f7863f..daaddec68def 100644 --- a/trunk/drivers/platform/x86/sony-laptop.c +++ b/trunk/drivers/platform/x86/sony-laptop.c @@ -786,29 +786,28 @@ static int sony_nc_int_call(acpi_handle handle, char *name, int *value, static int sony_nc_buffer_call(acpi_handle handle, char *name, u64 *value, void *buffer, size_t buflen) { - int ret = 0; size_t len = len; union acpi_object *object = __call_snc_method(handle, name, value); if (!object) return -EINVAL; - if (object->type == ACPI_TYPE_BUFFER) { + if (object->type == ACPI_TYPE_BUFFER) len = MIN(buflen, object->buffer.length); - memcpy(buffer, object->buffer.pointer, len); - } else if (object->type == ACPI_TYPE_INTEGER) { + else if (object->type == ACPI_TYPE_INTEGER) len = MIN(buflen, sizeof(object->integer.value)); - memcpy(buffer, &object->integer.value, len); - } else { + else { pr_warn("Invalid acpi_object: expected 0x%x got 0x%x\n", ACPI_TYPE_BUFFER, object->type); - ret = -EINVAL; + kfree(object); + return -EINVAL; } + memcpy(buffer, object->buffer.pointer, len); kfree(object); - return ret; + return 0; } struct sony_nc_handles { diff --git a/trunk/drivers/power/reset/gpio-poweroff.c b/trunk/drivers/power/reset/gpio-poweroff.c index e290d48ddd99..06074248ba7a 100644 --- a/trunk/drivers/power/reset/gpio-poweroff.c +++ b/trunk/drivers/power/reset/gpio-poweroff.c @@ -29,16 +29,15 @@ static int gpio_active_low; static void gpio_poweroff_do_poweroff(void) { - BUG_ON(!gpio_is_valid(gpio_num)); + BUG_ON(gpio_num == -1); - /* drive it active, also inactive->active edge */ + /* drive it active */ gpio_direction_output(gpio_num, !gpio_active_low); mdelay(100); - /* drive inactive, also active->inactive edge */ + /* rising edge or drive inactive */ gpio_set_value(gpio_num, gpio_active_low); mdelay(100); - - /* drive it active, also inactive->active edge */ + /* falling edge */ gpio_set_value(gpio_num, !gpio_active_low); /* give it some time */ @@ -61,12 +60,15 @@ static int gpio_poweroff_probe(struct platform_device *pdev) } gpio_num = of_get_gpio_flags(pdev->dev.of_node, 0, &flags); - if (!gpio_is_valid(gpio_num)) - return gpio_num; - + if (gpio_num < 0) { + pr_err("%s: Could not get GPIO configuration: %d", + __func__, gpio_num); + return -ENODEV; + } gpio_active_low = flags & OF_GPIO_ACTIVE_LOW; - input = of_property_read_bool(pdev->dev.of_node, "input"); + if (of_get_property(pdev->dev.of_node, "input", NULL)) + input = true; ret = gpio_request(gpio_num, "poweroff-gpio"); if (ret) { @@ -96,7 +98,8 @@ static int gpio_poweroff_probe(struct platform_device *pdev) static int gpio_poweroff_remove(struct platform_device *pdev) { - gpio_free(gpio_num); + if (gpio_num != -1) + gpio_free(gpio_num); if (pm_power_off == &gpio_poweroff_do_poweroff) pm_power_off = NULL; @@ -112,15 +115,15 @@ static struct platform_driver gpio_poweroff_driver = { .probe = gpio_poweroff_probe, .remove = gpio_poweroff_remove, .driver = { - .name = "poweroff-gpio", - .owner = THIS_MODULE, - .of_match_table = of_gpio_poweroff_match, - }, + .name = "poweroff-gpio", + .owner = THIS_MODULE, + .of_match_table = of_gpio_poweroff_match, + }, }; module_platform_driver(gpio_poweroff_driver); MODULE_AUTHOR("Jamie Lentin "); MODULE_DESCRIPTION("GPIO poweroff driver"); -MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:poweroff-gpio"); diff --git a/trunk/drivers/rtc/rtc-da9055.c b/trunk/drivers/rtc/rtc-da9055.c index 8f0dcfedb83c..96bafc5c3bf8 100644 --- a/trunk/drivers/rtc/rtc-da9055.c +++ b/trunk/drivers/rtc/rtc-da9055.c @@ -227,7 +227,7 @@ static const struct rtc_class_ops da9055_rtc_ops = { .alarm_irq_enable = da9055_rtc_alarm_irq_enable, }; -static int da9055_rtc_device_init(struct da9055 *da9055, +static int __init da9055_rtc_device_init(struct da9055 *da9055, struct da9055_pdata *pdata) { int ret; diff --git a/trunk/drivers/s390/block/dasd_diag.c b/trunk/drivers/s390/block/dasd_diag.c index 704488d0f819..9bd5da36f99e 100644 --- a/trunk/drivers/s390/block/dasd_diag.c +++ b/trunk/drivers/s390/block/dasd_diag.c @@ -248,7 +248,7 @@ static void dasd_ext_handler(struct ext_code ext_code, default: return; } - inc_irq_stat(IRQEXT_DSD); + kstat_cpu(smp_processor_id()).irqs[EXTINT_DSD]++; if (!ip) { /* no intparm: unsolicited interrupt */ DBF_EVENT(DBF_NOTICE, "%s", "caught unsolicited " "interrupt"); diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index e37bc1620d14..806fe912d6e7 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -4274,7 +4274,7 @@ static struct ccw_driver dasd_eckd_driver = { .thaw = dasd_generic_restore_device, .restore = dasd_generic_restore_device, .uc_handler = dasd_generic_uc_handler, - .int_class = IRQIO_DAS, + .int_class = IOINT_DAS, }; /* diff --git a/trunk/drivers/s390/block/dasd_fba.c b/trunk/drivers/s390/block/dasd_fba.c index 414698584344..eb748507c7fa 100644 --- a/trunk/drivers/s390/block/dasd_fba.c +++ b/trunk/drivers/s390/block/dasd_fba.c @@ -78,7 +78,7 @@ static struct ccw_driver dasd_fba_driver = { .freeze = dasd_generic_pm_freeze, .thaw = dasd_generic_restore_device, .restore = dasd_generic_restore_device, - .int_class = IRQIO_DAS, + .int_class = IOINT_DAS, }; static void diff --git a/trunk/drivers/s390/char/con3215.c b/trunk/drivers/s390/char/con3215.c index 33b7141a182f..40084501c31b 100644 --- a/trunk/drivers/s390/char/con3215.c +++ b/trunk/drivers/s390/char/con3215.c @@ -44,7 +44,6 @@ #define RAW3215_NR_CCWS 3 #define RAW3215_TIMEOUT HZ/10 /* time for delayed output */ -#define RAW3215_FIXED 1 /* 3215 console device is not be freed */ #define RAW3215_WORKING 4 /* set if a request is being worked on */ #define RAW3215_THROTTLED 8 /* set if reading is disabled */ #define RAW3215_STOPPED 16 /* set if writing is disabled */ @@ -631,8 +630,7 @@ static void raw3215_shutdown(struct raw3215_info *raw) DECLARE_WAITQUEUE(wait, current); unsigned long flags; - if (!(raw->port.flags & ASYNC_INITIALIZED) || - (raw->flags & RAW3215_FIXED)) + if (!(raw->port.flags & ASYNC_INITIALIZED)) return; /* Wait for outstanding requests, then free irq */ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); @@ -807,7 +805,7 @@ static struct ccw_driver raw3215_ccw_driver = { .freeze = &raw3215_pm_stop, .thaw = &raw3215_pm_start, .restore = &raw3215_pm_start, - .int_class = IRQIO_C15, + .int_class = IOINT_C15, }; #ifdef CONFIG_TN3215_CONSOLE @@ -929,8 +927,6 @@ static int __init con3215_init(void) dev_set_drvdata(&cdev->dev, raw); cdev->handler = raw3215_irq; - raw->flags |= RAW3215_FIXED; - /* Request the console irq */ if (raw3215_startup(raw) != 0) { raw3215_free_info(raw); diff --git a/trunk/drivers/s390/char/raw3270.c b/trunk/drivers/s390/char/raw3270.c index 9a6c140c5f07..f3b8bb84faf2 100644 --- a/trunk/drivers/s390/char/raw3270.c +++ b/trunk/drivers/s390/char/raw3270.c @@ -1396,7 +1396,7 @@ static struct ccw_driver raw3270_ccw_driver = { .freeze = &raw3270_pm_stop, .thaw = &raw3270_pm_start, .restore = &raw3270_pm_start, - .int_class = IRQIO_C70, + .int_class = IOINT_C70, }; static int diff --git a/trunk/drivers/s390/char/sclp.c b/trunk/drivers/s390/char/sclp.c index 12c16a65dd25..4fa21f7e2308 100644 --- a/trunk/drivers/s390/char/sclp.c +++ b/trunk/drivers/s390/char/sclp.c @@ -400,7 +400,7 @@ static void sclp_interrupt_handler(struct ext_code ext_code, u32 finished_sccb; u32 evbuf_pending; - inc_irq_stat(IRQEXT_SCP); + kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++; spin_lock(&sclp_lock); finished_sccb = param32 & 0xfffffff8; evbuf_pending = param32 & 0x3; @@ -813,7 +813,7 @@ static void sclp_check_handler(struct ext_code ext_code, { u32 finished_sccb; - inc_irq_stat(IRQEXT_SCP); + kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++; finished_sccb = param32 & 0xfffffff8; /* Is this the interrupt we are waiting for? */ if (finished_sccb == 0) diff --git a/trunk/drivers/s390/char/tape_34xx.c b/trunk/drivers/s390/char/tape_34xx.c index 9aa79702b370..6ae929c024ae 100644 --- a/trunk/drivers/s390/char/tape_34xx.c +++ b/trunk/drivers/s390/char/tape_34xx.c @@ -1193,7 +1193,7 @@ static struct ccw_driver tape_34xx_driver = { .set_online = tape_34xx_online, .set_offline = tape_generic_offline, .freeze = tape_generic_pm_suspend, - .int_class = IRQIO_TAP, + .int_class = IOINT_TAP, }; static int diff --git a/trunk/drivers/s390/char/tape_3590.c b/trunk/drivers/s390/char/tape_3590.c index 327cb19ad0b0..1b0eb49f739c 100644 --- a/trunk/drivers/s390/char/tape_3590.c +++ b/trunk/drivers/s390/char/tape_3590.c @@ -1656,7 +1656,7 @@ static struct ccw_driver tape_3590_driver = { .set_offline = tape_generic_offline, .set_online = tape_3590_online, .freeze = tape_generic_pm_suspend, - .int_class = IRQIO_TAP, + .int_class = IOINT_TAP, }; /* diff --git a/trunk/drivers/s390/char/vmur.c b/trunk/drivers/s390/char/vmur.c index 483f72ba030d..73bef0bd394c 100644 --- a/trunk/drivers/s390/char/vmur.c +++ b/trunk/drivers/s390/char/vmur.c @@ -74,7 +74,7 @@ static struct ccw_driver ur_driver = { .set_online = ur_set_online, .set_offline = ur_set_offline, .freeze = ur_pm_suspend, - .int_class = IRQIO_VMR, + .int_class = IOINT_VMR, }; static DEFINE_MUTEX(vmur_mutex); diff --git a/trunk/drivers/s390/cio/chsc_sch.c b/trunk/drivers/s390/cio/chsc_sch.c index facdf809113f..8f9a1a384496 100644 --- a/trunk/drivers/s390/cio/chsc_sch.c +++ b/trunk/drivers/s390/cio/chsc_sch.c @@ -58,7 +58,7 @@ static void chsc_subchannel_irq(struct subchannel *sch) CHSC_LOG(4, "irb"); CHSC_LOG_HEX(4, irb, sizeof(*irb)); - inc_irq_stat(IRQIO_CSC); + kstat_cpu(smp_processor_id()).irqs[IOINT_CSC]++; /* Copy irb to provided request and set done. */ if (!request) { diff --git a/trunk/drivers/s390/cio/cio.c b/trunk/drivers/s390/cio/cio.c index c8faf6230b0f..8e927b9f285f 100644 --- a/trunk/drivers/s390/cio/cio.c +++ b/trunk/drivers/s390/cio/cio.c @@ -611,7 +611,7 @@ void __irq_entry do_IRQ(struct pt_regs *regs) tpi_info = (struct tpi_info *)&S390_lowcore.subchannel_id; irb = (struct irb *)&S390_lowcore.irb; do { - kstat_incr_irqs_this_cpu(IO_INTERRUPT, NULL); + kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++; if (tpi_info->adapter_IO) { do_adapter_IO(tpi_info->isc); continue; @@ -619,7 +619,7 @@ void __irq_entry do_IRQ(struct pt_regs *regs) sch = (struct subchannel *)(unsigned long)tpi_info->intparm; if (!sch) { /* Clear pending interrupt condition. */ - inc_irq_stat(IRQIO_CIO); + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; tsch(tpi_info->schid, irb); continue; } @@ -633,9 +633,9 @@ void __irq_entry do_IRQ(struct pt_regs *regs) if (sch->driver && sch->driver->irq) sch->driver->irq(sch); else - inc_irq_stat(IRQIO_CIO); + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; } else - inc_irq_stat(IRQIO_CIO); + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; spin_unlock(sch->lock); /* * Are more interrupts pending? @@ -678,7 +678,7 @@ static void cio_tsch(struct subchannel *sch) if (sch->driver && sch->driver->irq) sch->driver->irq(sch); else - inc_irq_stat(IRQIO_CIO); + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; if (!irq_context) { irq_exit(); _local_bh_enable(); diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index 7cd5c6812ac7..6995cff44636 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -758,7 +758,7 @@ static int io_subchannel_initialize_dev(struct subchannel *sch, struct ccw_device *cdev) { cdev->private->cdev = cdev; - cdev->private->int_class = IRQIO_CIO; + cdev->private->int_class = IOINT_CIO; atomic_set(&cdev->private->onoff, 0); cdev->dev.parent = &sch->dev; cdev->dev.release = ccw_device_release; @@ -1023,7 +1023,7 @@ static void io_subchannel_irq(struct subchannel *sch) if (cdev) dev_fsm_event(cdev, DEV_EVENT_INTERRUPT); else - inc_irq_stat(IRQIO_CIO); + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; } void io_subchannel_init_config(struct subchannel *sch) @@ -1634,7 +1634,7 @@ ccw_device_probe_console(void) memset(&console_private, 0, sizeof(struct ccw_device_private)); console_cdev.private = &console_private; console_private.cdev = &console_cdev; - console_private.int_class = IRQIO_CIO; + console_private.int_class = IOINT_CIO; ret = ccw_device_console_enable(&console_cdev, sch); if (ret) { cio_release_console(); @@ -1715,13 +1715,13 @@ ccw_device_probe (struct device *dev) if (cdrv->int_class != 0) cdev->private->int_class = cdrv->int_class; else - cdev->private->int_class = IRQIO_CIO; + cdev->private->int_class = IOINT_CIO; ret = cdrv->probe ? cdrv->probe(cdev) : -ENODEV; if (ret) { cdev->drv = NULL; - cdev->private->int_class = IRQIO_CIO; + cdev->private->int_class = IOINT_CIO; return ret; } @@ -1755,7 +1755,7 @@ ccw_device_remove (struct device *dev) } ccw_device_set_timeout(cdev, 0); cdev->drv = NULL; - cdev->private->int_class = IRQIO_CIO; + cdev->private->int_class = IOINT_CIO; return 0; } diff --git a/trunk/drivers/s390/cio/device.h b/trunk/drivers/s390/cio/device.h index 7d4ecb65db00..2e575cff9845 100644 --- a/trunk/drivers/s390/cio/device.h +++ b/trunk/drivers/s390/cio/device.h @@ -61,10 +61,11 @@ dev_fsm_event(struct ccw_device *cdev, enum dev_event dev_event) if (dev_event == DEV_EVENT_INTERRUPT) { if (state == DEV_STATE_ONLINE) - inc_irq_stat(cdev->private->int_class); + kstat_cpu(smp_processor_id()). + irqs[cdev->private->int_class]++; else if (state != DEV_STATE_CMFCHANGE && state != DEV_STATE_CMFUPDATE) - inc_irq_stat(IRQIO_CIO); + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; } dev_jumptable[state][dev_event](cdev, dev_event); } diff --git a/trunk/drivers/s390/cio/eadm_sch.c b/trunk/drivers/s390/cio/eadm_sch.c index d9eddcba7e88..6c9673400464 100644 --- a/trunk/drivers/s390/cio/eadm_sch.c +++ b/trunk/drivers/s390/cio/eadm_sch.c @@ -139,7 +139,7 @@ static void eadm_subchannel_irq(struct subchannel *sch) EADM_LOG(6, "irq"); EADM_LOG_HEX(6, irb, sizeof(*irb)); - inc_irq_stat(IRQIO_ADM); + kstat_cpu(smp_processor_id()).irqs[IOINT_ADM]++; if ((scsw->stctl & (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)) && scsw->eswf == 1 && irb->esw.eadm.erw.r) diff --git a/trunk/drivers/s390/cio/qdio_thinint.c b/trunk/drivers/s390/cio/qdio_thinint.c index bde5255200dc..bdb394b066fc 100644 --- a/trunk/drivers/s390/cio/qdio_thinint.c +++ b/trunk/drivers/s390/cio/qdio_thinint.c @@ -182,7 +182,7 @@ static void tiqdio_thinint_handler(void *alsi, void *data) struct qdio_q *q; last_ai_time = S390_lowcore.int_clock; - inc_irq_stat(IRQIO_QAI); + kstat_cpu(smp_processor_id()).irqs[IOINT_QAI]++; /* protect tiq_list entries, only changed in activate or shutdown */ rcu_read_lock(); diff --git a/trunk/drivers/s390/crypto/ap_bus.c b/trunk/drivers/s390/crypto/ap_bus.c index b8b340ac5332..7b865a7300e6 100644 --- a/trunk/drivers/s390/crypto/ap_bus.c +++ b/trunk/drivers/s390/crypto/ap_bus.c @@ -1272,7 +1272,7 @@ static int ap_probe_device_type(struct ap_device *ap_dev) static void ap_interrupt_handler(void *unused1, void *unused2) { - inc_irq_stat(IRQIO_APB); + kstat_cpu(smp_processor_id()).irqs[IOINT_APB]++; tasklet_schedule(&ap_tasklet); } diff --git a/trunk/drivers/s390/kvm/kvm_virtio.c b/trunk/drivers/s390/kvm/kvm_virtio.c index 8491111aec12..7dabef624da3 100644 --- a/trunk/drivers/s390/kvm/kvm_virtio.c +++ b/trunk/drivers/s390/kvm/kvm_virtio.c @@ -392,7 +392,7 @@ static void kvm_extint_handler(struct ext_code ext_code, if ((ext_code.subcode & 0xff00) != VIRTIO_SUBCODE_64) return; - inc_irq_stat(IRQEXT_VRT); + kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++; /* The LSB might be overloaded, we have to mask it */ vq = (struct virtqueue *)(param64 & ~1UL); diff --git a/trunk/drivers/s390/net/claw.c b/trunk/drivers/s390/net/claw.c index 83bc9c5fa0c1..5c70a6599578 100644 --- a/trunk/drivers/s390/net/claw.c +++ b/trunk/drivers/s390/net/claw.c @@ -282,7 +282,7 @@ static struct ccw_driver claw_ccw_driver = { .ids = claw_ids, .probe = ccwgroup_probe_ccwdev, .remove = ccwgroup_remove_ccwdev, - .int_class = IRQIO_CLW, + .int_class = IOINT_CLW, }; static ssize_t claw_driver_group_store(struct device_driver *ddrv, diff --git a/trunk/drivers/s390/net/ctcm_main.c b/trunk/drivers/s390/net/ctcm_main.c index 676f12049a36..817b68925ddd 100644 --- a/trunk/drivers/s390/net/ctcm_main.c +++ b/trunk/drivers/s390/net/ctcm_main.c @@ -1755,7 +1755,7 @@ static struct ccw_driver ctcm_ccw_driver = { .ids = ctcm_ids, .probe = ccwgroup_probe_ccwdev, .remove = ccwgroup_remove_ccwdev, - .int_class = IRQIO_CTC, + .int_class = IOINT_CTC, }; static struct ccwgroup_driver ctcm_group_driver = { diff --git a/trunk/drivers/s390/net/lcs.c b/trunk/drivers/s390/net/lcs.c index c645dc9e98af..2ca0f1dd7a00 100644 --- a/trunk/drivers/s390/net/lcs.c +++ b/trunk/drivers/s390/net/lcs.c @@ -2384,7 +2384,7 @@ static struct ccw_driver lcs_ccw_driver = { .ids = lcs_ids, .probe = ccwgroup_probe_ccwdev, .remove = ccwgroup_remove_ccwdev, - .int_class = IRQIO_LCS, + .int_class = IOINT_LCS, }; /** diff --git a/trunk/drivers/staging/comedi/Kconfig b/trunk/drivers/staging/comedi/Kconfig index 36eec320569c..7de2a10213bd 100644 --- a/trunk/drivers/staging/comedi/Kconfig +++ b/trunk/drivers/staging/comedi/Kconfig @@ -444,7 +444,6 @@ config COMEDI_ADQ12B config COMEDI_NI_AT_A2150 tristate "NI AT-A2150 ISA card support" - select COMEDI_FC depends on VIRT_TO_BUS ---help--- Enable support for National Instruments AT-A2150 cards diff --git a/trunk/drivers/staging/comedi/comedi_fops.c b/trunk/drivers/staging/comedi/comedi_fops.c index 9b038e4a7e71..b7bba1790a20 100644 --- a/trunk/drivers/staging/comedi/comedi_fops.c +++ b/trunk/drivers/staging/comedi/comedi_fops.c @@ -1549,9 +1549,6 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, if (cmd == COMEDI_DEVCONFIG) { rc = do_devconfig_ioctl(dev, (struct comedi_devconfig __user *)arg); - if (rc == 0) - /* Evade comedi_auto_unconfig(). */ - dev_file_info->hardware_device = NULL; goto done; } diff --git a/trunk/drivers/staging/comedi/drivers/comedi_test.c b/trunk/drivers/staging/comedi/drivers/comedi_test.c index 01de996239f1..fb3d09323ba1 100644 --- a/trunk/drivers/staging/comedi/drivers/comedi_test.c +++ b/trunk/drivers/staging/comedi/drivers/comedi_test.c @@ -345,7 +345,7 @@ static int waveform_ai_cancel(struct comedi_device *dev, struct waveform_private *devpriv = dev->private; devpriv->timer_running = 0; - del_timer_sync(&devpriv->timer); + del_timer(&devpriv->timer); return 0; } diff --git a/trunk/drivers/staging/comedi/drivers/ni_pcimio.c b/trunk/drivers/staging/comedi/drivers/ni_pcimio.c index fd1662b4175d..aaac0b2cc9eb 100644 --- a/trunk/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/trunk/drivers/staging/comedi/drivers/ni_pcimio.c @@ -963,7 +963,7 @@ static const struct ni_board_struct ni_boards[] = { .ao_range_table = &range_ni_M_625x_ao, .reg_type = ni_reg_625x, .ao_unipolar = 0, - .ao_speed = 350, + .ao_speed = 357, .num_p0_dio_channels = 8, .caldac = {caldac_none}, .has_8255 = 0, @@ -982,7 +982,7 @@ static const struct ni_board_struct ni_boards[] = { .ao_range_table = &range_ni_M_625x_ao, .reg_type = ni_reg_625x, .ao_unipolar = 0, - .ao_speed = 350, + .ao_speed = 357, .num_p0_dio_channels = 8, .caldac = {caldac_none}, .has_8255 = 0, @@ -1001,7 +1001,7 @@ static const struct ni_board_struct ni_boards[] = { .ao_range_table = &range_ni_M_625x_ao, .reg_type = ni_reg_625x, .ao_unipolar = 0, - .ao_speed = 350, + .ao_speed = 357, .num_p0_dio_channels = 8, .caldac = {caldac_none}, .has_8255 = 0, @@ -1037,7 +1037,7 @@ static const struct ni_board_struct ni_boards[] = { .ao_range_table = &range_ni_M_625x_ao, .reg_type = ni_reg_625x, .ao_unipolar = 0, - .ao_speed = 350, + .ao_speed = 357, .num_p0_dio_channels = 32, .caldac = {caldac_none}, .has_8255 = 0, @@ -1056,7 +1056,7 @@ static const struct ni_board_struct ni_boards[] = { .ao_range_table = &range_ni_M_625x_ao, .reg_type = ni_reg_625x, .ao_unipolar = 0, - .ao_speed = 350, + .ao_speed = 357, .num_p0_dio_channels = 32, .caldac = {caldac_none}, .has_8255 = 0, @@ -1092,7 +1092,7 @@ static const struct ni_board_struct ni_boards[] = { .ao_range_table = &range_ni_M_628x_ao, .reg_type = ni_reg_628x, .ao_unipolar = 1, - .ao_speed = 350, + .ao_speed = 357, .num_p0_dio_channels = 8, .caldac = {caldac_none}, .has_8255 = 0, @@ -1111,7 +1111,7 @@ static const struct ni_board_struct ni_boards[] = { .ao_range_table = &range_ni_M_628x_ao, .reg_type = ni_reg_628x, .ao_unipolar = 1, - .ao_speed = 350, + .ao_speed = 357, .num_p0_dio_channels = 8, .caldac = {caldac_none}, .has_8255 = 0, @@ -1147,7 +1147,7 @@ static const struct ni_board_struct ni_boards[] = { .ao_range_table = &range_ni_M_628x_ao, .reg_type = ni_reg_628x, .ao_unipolar = 1, - .ao_speed = 350, + .ao_speed = 357, .num_p0_dio_channels = 32, .caldac = {caldac_none}, .has_8255 = 0, diff --git a/trunk/drivers/staging/fwserial/Kconfig b/trunk/drivers/staging/fwserial/Kconfig index b2f8331e4acf..580406cb1808 100644 --- a/trunk/drivers/staging/fwserial/Kconfig +++ b/trunk/drivers/staging/fwserial/Kconfig @@ -3,9 +3,7 @@ config FIREWIRE_SERIAL depends on FIREWIRE help This enables TTY over IEEE 1394, providing high-speed serial - connectivity to cabled peers. This driver implements a - ad-hoc transport protocol and is currently limited to - Linux-to-Linux communication. + connectivity to cabled peers. To compile this driver as a module, say M here: the module will be called firewire-serial. diff --git a/trunk/drivers/staging/fwserial/TODO b/trunk/drivers/staging/fwserial/TODO index 8dae8fb25223..726900548eae 100644 --- a/trunk/drivers/staging/fwserial/TODO +++ b/trunk/drivers/staging/fwserial/TODO @@ -1,5 +1,5 @@ -TODOs prior to this driver moving out of staging ------------------------------------------------- +TODOs +----- 1. Implement retries for RCODE_BUSY, RCODE_NO_ACK and RCODE_SEND_ERROR - I/O is handled asynchronously which presents some issues when error conditions occur. @@ -11,9 +11,17 @@ TODOs prior to this driver moving out of staging -- Issues with firewire stack -- 1. This driver uses the same unregistered vendor id that the firewire core does (0xd00d1e). Perhaps this could be exposed as a define in - firewire.h? + firewire-constants.h? +2. MAX_ASYNC_PAYLOAD needs to be publicly exposed by core/ohci + - otherwise how will this driver know the max size of address window to + open for one packet write? 3. Maybe device_max_receive() and link_speed_to_max_payload() should be taken up by the firewire core? +4. To avoid dropping rx data while still limiting the maximum buffering, + the size of the AR context must be known. How to expose this to drivers? +5. Explore if bigger AR context will reduce RCODE_BUSY responses + (or auto-grow to certain max size -- but this would require major surgery + as the current AR is contiguously mapped) -- Issues with TTY core -- 1. Hack for alternate device name scheme diff --git a/trunk/drivers/staging/fwserial/fwserial.c b/trunk/drivers/staging/fwserial/fwserial.c index d03a7f57e8d4..61ee29083b26 100644 --- a/trunk/drivers/staging/fwserial/fwserial.c +++ b/trunk/drivers/staging/fwserial/fwserial.c @@ -179,7 +179,7 @@ static void dump_profile(struct seq_file *m, struct stats *stats) /* Returns the max receive packet size for the given card */ static inline int device_max_receive(struct fw_device *fw_device) { - return 1 << (clamp_t(int, fw_device->max_rec, 8U, 11U) + 1); + return 1 << (clamp_t(int, fw_device->max_rec, 8U, 13U) + 1); } static void fwtty_log_tx_error(struct fwtty_port *port, int rcode) diff --git a/trunk/drivers/staging/fwserial/fwserial.h b/trunk/drivers/staging/fwserial/fwserial.h index caa1c1ea82d5..8b572edf9563 100644 --- a/trunk/drivers/staging/fwserial/fwserial.h +++ b/trunk/drivers/staging/fwserial/fwserial.h @@ -374,10 +374,10 @@ static inline void fwtty_bind_console(struct fwtty_port *port, */ static inline int link_speed_to_max_payload(unsigned speed) { - static const int max_async[] = { 307, 614, 1229, 2458, }; - BUILD_BUG_ON(ARRAY_SIZE(max_async) - 1 != SCODE_800); + static const int max_async[] = { 307, 614, 1229, 2458, 4916, 9832, }; + BUILD_BUG_ON(ARRAY_SIZE(max_async) - 1 != SCODE_3200); - speed = clamp(speed, (unsigned) SCODE_100, (unsigned) SCODE_800); + speed = clamp(speed, (unsigned) SCODE_100, (unsigned) SCODE_3200); if (limit_bw) return max_async[speed]; else diff --git a/trunk/drivers/staging/iio/gyro/Kconfig b/trunk/drivers/staging/iio/gyro/Kconfig index 87979a0d03a9..ea295b25308c 100644 --- a/trunk/drivers/staging/iio/gyro/Kconfig +++ b/trunk/drivers/staging/iio/gyro/Kconfig @@ -27,8 +27,8 @@ config ADIS16130 config ADIS16260 tristate "Analog Devices ADIS16260 Digital Gyroscope Sensor SPI driver" depends on SPI - select IIO_ADIS_LIB - select IIO_ADIS_LIB_BUFFER if IIO_BUFFER + select IIO_TRIGGER if IIO_BUFFER + select IIO_SW_RING if IIO_BUFFER help Say yes here to build support for Analog Devices ADIS16260 ADIS16265 ADIS16250 ADIS16255 and ADIS16251 programmable digital gyroscope sensors. diff --git a/trunk/drivers/staging/imx-drm/imx-drm-core.c b/trunk/drivers/staging/imx-drm/imx-drm-core.c index cec19f1cf56c..ecf0f44bc70e 100644 --- a/trunk/drivers/staging/imx-drm/imx-drm-core.c +++ b/trunk/drivers/staging/imx-drm/imx-drm-core.c @@ -584,6 +584,7 @@ int imx_drm_add_encoder(struct drm_encoder *encoder, ret = imx_drm_encoder_register(imx_drm_encoder); if (ret) { + kfree(imx_drm_encoder); ret = -ENOMEM; goto err_register; } diff --git a/trunk/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/trunk/drivers/staging/imx-drm/ipu-v3/ipu-common.c index f7059cddd7fd..677e665ca86d 100644 --- a/trunk/drivers/staging/imx-drm/ipu-v3/ipu-common.c +++ b/trunk/drivers/staging/imx-drm/ipu-v3/ipu-common.c @@ -1104,9 +1104,7 @@ static int ipu_probe(struct platform_device *pdev) if (ret) goto out_failed_irq; - ret = ipu_reset(ipu); - if (ret) - goto out_failed_reset; + ipu_reset(ipu); /* Set MCU_T to divide MCU access window into 2 */ ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18), @@ -1131,7 +1129,6 @@ static int ipu_probe(struct platform_device *pdev) ipu_submodules_exit(ipu); failed_submodules_init: ipu_irq_exit(ipu); -out_failed_reset: out_failed_irq: clk_disable_unprepare(ipu->clk); failed_clk_get: diff --git a/trunk/drivers/staging/imx-drm/ipuv3-crtc.c b/trunk/drivers/staging/imx-drm/ipuv3-crtc.c index 4b3a019409b5..1892006526b5 100644 --- a/trunk/drivers/staging/imx-drm/ipuv3-crtc.c +++ b/trunk/drivers/staging/imx-drm/ipuv3-crtc.c @@ -452,7 +452,7 @@ static int ipu_get_resources(struct ipu_crtc *ipu_crtc, int ret; ipu_crtc->ipu_ch = ipu_idmac_get(ipu, pdata->dma[0]); - if (IS_ERR(ipu_crtc->ipu_ch)) { + if (IS_ERR_OR_NULL(ipu_crtc->ipu_ch)) { ret = PTR_ERR(ipu_crtc->ipu_ch); goto err_out; } @@ -472,7 +472,7 @@ static int ipu_get_resources(struct ipu_crtc *ipu_crtc, if (pdata->dp >= 0) { ipu_crtc->dp = ipu_dp_get(ipu, pdata->dp); if (IS_ERR(ipu_crtc->dp)) { - ret = PTR_ERR(ipu_crtc->dp); + ret = PTR_ERR(ipu_crtc->ipu_ch); goto err_out; } } @@ -548,8 +548,6 @@ static int ipu_drm_probe(struct platform_device *pdev) ipu_crtc->dev = &pdev->dev; ret = ipu_crtc_init(ipu_crtc, pdata); - if (ret) - return ret; platform_set_drvdata(pdev, ipu_crtc); diff --git a/trunk/drivers/staging/omapdrm/Makefile b/trunk/drivers/staging/omapdrm/Makefile index d85e058f2845..1ca0e0016de4 100644 --- a/trunk/drivers/staging/omapdrm/Makefile +++ b/trunk/drivers/staging/omapdrm/Makefile @@ -5,7 +5,6 @@ ccflags-y := -Iinclude/drm -Werror omapdrm-y := omap_drv.o \ - omap_irq.o \ omap_debugfs.o \ omap_crtc.o \ omap_plane.o \ diff --git a/trunk/drivers/staging/omapdrm/TODO b/trunk/drivers/staging/omapdrm/TODO index abeeb00aaa12..938c7888ca31 100644 --- a/trunk/drivers/staging/omapdrm/TODO +++ b/trunk/drivers/staging/omapdrm/TODO @@ -17,6 +17,9 @@ TODO . Revisit GEM sync object infrastructure.. TTM has some framework for this already. Possibly this could be refactored out and made more common? There should be some way to do this with less wheel-reinvention. +. Review DSS vs KMS mismatches. The omap_dss_device is sort of part encoder, + part connector. Which results in a bit of duct tape to fwd calls from + encoder to connector. Possibly this could be done a bit better. . Solve PM sequencing on resume. DMM/TILER must be reloaded before any access is made from any component in the system. Which means on suspend CRTC's should be disabled, and on resume the LUT should be reprogrammed diff --git a/trunk/drivers/staging/omapdrm/omap_connector.c b/trunk/drivers/staging/omapdrm/omap_connector.c index 4cc9ee733c5f..91edb3f96972 100644 --- a/trunk/drivers/staging/omapdrm/omap_connector.c +++ b/trunk/drivers/staging/omapdrm/omap_connector.c @@ -31,10 +31,9 @@ struct omap_connector { struct drm_connector base; struct omap_dss_device *dssdev; - struct drm_encoder *encoder; }; -void copy_timings_omap_to_drm(struct drm_display_mode *mode, +static inline void copy_timings_omap_to_drm(struct drm_display_mode *mode, struct omap_video_timings *timings) { mode->clock = timings->pixel_clock; @@ -65,7 +64,7 @@ void copy_timings_omap_to_drm(struct drm_display_mode *mode, mode->flags |= DRM_MODE_FLAG_NVSYNC; } -void copy_timings_drm_to_omap(struct omap_video_timings *timings, +static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings, struct drm_display_mode *mode) { timings->pixel_clock = mode->clock; @@ -97,7 +96,48 @@ void copy_timings_drm_to_omap(struct omap_video_timings *timings, timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; } -static enum drm_connector_status omap_connector_detect( +static void omap_connector_dpms(struct drm_connector *connector, int mode) +{ + struct omap_connector *omap_connector = to_omap_connector(connector); + struct omap_dss_device *dssdev = omap_connector->dssdev; + int old_dpms; + + DBG("%s: %d", dssdev->name, mode); + + old_dpms = connector->dpms; + + /* from off to on, do from crtc to connector */ + if (mode < old_dpms) + drm_helper_connector_dpms(connector, mode); + + if (mode == DRM_MODE_DPMS_ON) { + /* store resume info for suspended displays */ + switch (dssdev->state) { + case OMAP_DSS_DISPLAY_SUSPENDED: + dssdev->activate_after_resume = true; + break; + case OMAP_DSS_DISPLAY_DISABLED: { + int ret = dssdev->driver->enable(dssdev); + if (ret) { + DBG("%s: failed to enable: %d", + dssdev->name, ret); + dssdev->driver->disable(dssdev); + } + break; + } + default: + break; + } + } else { + /* TODO */ + } + + /* from on to off, do from connector to crtc */ + if (mode > old_dpms) + drm_helper_connector_dpms(connector, mode); +} + +enum drm_connector_status omap_connector_detect( struct drm_connector *connector, bool force) { struct omap_connector *omap_connector = to_omap_connector(connector); @@ -124,6 +164,8 @@ static void omap_connector_destroy(struct drm_connector *connector) struct omap_connector *omap_connector = to_omap_connector(connector); struct omap_dss_device *dssdev = omap_connector->dssdev; + dssdev->driver->disable(dssdev); + DBG("%s", omap_connector->dssdev->name); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); @@ -219,12 +261,36 @@ static int omap_connector_mode_valid(struct drm_connector *connector, struct drm_encoder *omap_connector_attached_encoder( struct drm_connector *connector) { + int i; struct omap_connector *omap_connector = to_omap_connector(connector); - return omap_connector->encoder; + + for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { + struct drm_mode_object *obj; + + if (connector->encoder_ids[i] == 0) + break; + + obj = drm_mode_object_find(connector->dev, + connector->encoder_ids[i], + DRM_MODE_OBJECT_ENCODER); + + if (obj) { + struct drm_encoder *encoder = obj_to_encoder(obj); + struct omap_overlay_manager *mgr = + omap_encoder_get_manager(encoder); + DBG("%s: found %s", omap_connector->dssdev->name, + mgr->name); + return encoder; + } + } + + DBG("%s: no encoder", omap_connector->dssdev->name); + + return NULL; } static const struct drm_connector_funcs omap_connector_funcs = { - .dpms = drm_helper_connector_dpms, + .dpms = omap_connector_dpms, .detect = omap_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = omap_connector_destroy, @@ -236,6 +302,34 @@ static const struct drm_connector_helper_funcs omap_connector_helper_funcs = { .best_encoder = omap_connector_attached_encoder, }; +/* called from encoder when mode is set, to propagate settings to the dssdev */ +void omap_connector_mode_set(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct drm_device *dev = connector->dev; + struct omap_connector *omap_connector = to_omap_connector(connector); + struct omap_dss_device *dssdev = omap_connector->dssdev; + struct omap_dss_driver *dssdrv = dssdev->driver; + struct omap_video_timings timings = {0}; + + copy_timings_drm_to_omap(&timings, mode); + + DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", + omap_connector->dssdev->name, + mode->base.id, mode->name, mode->vrefresh, mode->clock, + mode->hdisplay, mode->hsync_start, + mode->hsync_end, mode->htotal, + mode->vdisplay, mode->vsync_start, + mode->vsync_end, mode->vtotal, mode->type, mode->flags); + + if (dssdrv->check_timings(dssdev, &timings)) { + dev_err(dev->dev, "could not set timings\n"); + return; + } + + dssdrv->set_timings(dssdev, &timings); +} + /* flush an area of the framebuffer (in case of manual update display that * is not automatically flushed) */ @@ -250,8 +344,7 @@ void omap_connector_flush(struct drm_connector *connector, /* initialize connector */ struct drm_connector *omap_connector_init(struct drm_device *dev, - int connector_type, struct omap_dss_device *dssdev, - struct drm_encoder *encoder) + int connector_type, struct omap_dss_device *dssdev) { struct drm_connector *connector = NULL; struct omap_connector *omap_connector; @@ -267,8 +360,6 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, } omap_connector->dssdev = dssdev; - omap_connector->encoder = encoder; - connector = &omap_connector->base; drm_connector_init(dev, connector, &omap_connector_funcs, diff --git a/trunk/drivers/staging/omapdrm/omap_crtc.c b/trunk/drivers/staging/omapdrm/omap_crtc.c index 5c6ed6040eff..d87bd84257bd 100644 --- a/trunk/drivers/staging/omapdrm/omap_crtc.c +++ b/trunk/drivers/staging/omapdrm/omap_crtc.c @@ -28,131 +28,19 @@ struct omap_crtc { struct drm_crtc base; struct drm_plane *plane; - const char *name; - int pipe; - enum omap_channel channel; - struct omap_overlay_manager_info info; - - /* - * Temporary: eventually this will go away, but it is needed - * for now to keep the output's happy. (They only need - * mgr->id.) Eventually this will be replaced w/ something - * more common-panel-framework-y - */ - struct omap_overlay_manager mgr; - - struct omap_video_timings timings; - bool enabled; - bool full_update; - - struct omap_drm_apply apply; - - struct omap_drm_irq apply_irq; - struct omap_drm_irq error_irq; - - /* list of in-progress apply's: */ - struct list_head pending_applies; - - /* list of queued apply's: */ - struct list_head queued_applies; - - /* for handling queued and in-progress applies: */ - struct work_struct apply_work; + int id; /* if there is a pending flip, these will be non-null: */ struct drm_pending_vblank_event *event; struct drm_framebuffer *old_fb; - - /* for handling page flips without caring about what - * the callback is called from. Possibly we should just - * make omap_gem always call the cb from the worker so - * we don't have to care about this.. - * - * XXX maybe fold into apply_work?? - */ - struct work_struct page_flip_work; -}; - -/* - * Manager-ops, callbacks from output when they need to configure - * the upstream part of the video pipe. - * - * Most of these we can ignore until we add support for command-mode - * panels.. for video-mode the crtc-helpers already do an adequate - * job of sequencing the setup of the video pipe in the proper order - */ - -/* we can probably ignore these until we support command-mode panels: */ -static void omap_crtc_start_update(struct omap_overlay_manager *mgr) -{ -} - -static int omap_crtc_enable(struct omap_overlay_manager *mgr) -{ - return 0; -} - -static void omap_crtc_disable(struct omap_overlay_manager *mgr) -{ -} - -static void omap_crtc_set_timings(struct omap_overlay_manager *mgr, - const struct omap_video_timings *timings) -{ - struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr); - DBG("%s", omap_crtc->name); - omap_crtc->timings = *timings; - omap_crtc->full_update = true; -} - -static void omap_crtc_set_lcd_config(struct omap_overlay_manager *mgr, - const struct dss_lcd_mgr_config *config) -{ - struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr); - DBG("%s", omap_crtc->name); - dispc_mgr_set_lcd_config(omap_crtc->channel, config); -} - -static int omap_crtc_register_framedone_handler( - struct omap_overlay_manager *mgr, - void (*handler)(void *), void *data) -{ - return 0; -} - -static void omap_crtc_unregister_framedone_handler( - struct omap_overlay_manager *mgr, - void (*handler)(void *), void *data) -{ -} - -static const struct dss_mgr_ops mgr_ops = { - .start_update = omap_crtc_start_update, - .enable = omap_crtc_enable, - .disable = omap_crtc_disable, - .set_timings = omap_crtc_set_timings, - .set_lcd_config = omap_crtc_set_lcd_config, - .register_framedone_handler = omap_crtc_register_framedone_handler, - .unregister_framedone_handler = omap_crtc_unregister_framedone_handler, }; -/* - * CRTC funcs: - */ - static void omap_crtc_destroy(struct drm_crtc *crtc) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - - DBG("%s", omap_crtc->name); - - WARN_ON(omap_crtc->apply_irq.registered); - omap_irq_unregister(crtc->dev, &omap_crtc->error_irq); - omap_crtc->plane->funcs->destroy(omap_crtc->plane); drm_crtc_cleanup(crtc); - kfree(omap_crtc); } @@ -160,25 +48,14 @@ static void omap_crtc_dpms(struct drm_crtc *crtc, int mode) { struct omap_drm_private *priv = crtc->dev->dev_private; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - bool enabled = (mode == DRM_MODE_DPMS_ON); int i; - DBG("%s: %d", omap_crtc->name, mode); - - if (enabled != omap_crtc->enabled) { - omap_crtc->enabled = enabled; - omap_crtc->full_update = true; - omap_crtc_apply(crtc, &omap_crtc->apply); + WARN_ON(omap_plane_dpms(omap_crtc->plane, mode)); - /* also enable our private plane: */ - WARN_ON(omap_plane_dpms(omap_crtc->plane, mode)); - - /* and any attached overlay planes: */ - for (i = 0; i < priv->num_planes; i++) { - struct drm_plane *plane = priv->planes[i]; - if (plane->crtc == crtc) - WARN_ON(omap_plane_dpms(plane, mode)); - } + for (i = 0; i < priv->num_planes; i++) { + struct drm_plane *plane = priv->planes[i]; + if (plane->crtc == crtc) + WARN_ON(omap_plane_dpms(plane, mode)); } } @@ -196,26 +73,12 @@ static int omap_crtc_mode_set(struct drm_crtc *crtc, struct drm_framebuffer *old_fb) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct drm_plane *plane = omap_crtc->plane; - mode = adjusted_mode; - - DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", - omap_crtc->name, mode->base.id, mode->name, - mode->vrefresh, mode->clock, - mode->hdisplay, mode->hsync_start, - mode->hsync_end, mode->htotal, - mode->vdisplay, mode->vsync_start, - mode->vsync_end, mode->vtotal, - mode->type, mode->flags); - - copy_timings_drm_to_omap(&omap_crtc->timings, mode); - omap_crtc->full_update = true; - - return omap_plane_mode_set(omap_crtc->plane, crtc, crtc->fb, + return omap_plane_mode_set(plane, crtc, crtc->fb, 0, 0, mode->hdisplay, mode->vdisplay, x << 16, y << 16, - mode->hdisplay << 16, mode->vdisplay << 16, - NULL, NULL); + mode->hdisplay << 16, mode->vdisplay << 16); } static void omap_crtc_prepare(struct drm_crtc *crtc) @@ -239,11 +102,10 @@ static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct drm_plane *plane = omap_crtc->plane; struct drm_display_mode *mode = &crtc->mode; - return omap_plane_mode_set(plane, crtc, crtc->fb, + return plane->funcs->update_plane(plane, crtc, crtc->fb, 0, 0, mode->hdisplay, mode->vdisplay, x << 16, y << 16, - mode->hdisplay << 16, mode->vdisplay << 16, - NULL, NULL); + mode->hdisplay << 16, mode->vdisplay << 16); } static void omap_crtc_load_lut(struct drm_crtc *crtc) @@ -252,52 +114,61 @@ static void omap_crtc_load_lut(struct drm_crtc *crtc) static void vblank_cb(void *arg) { + static uint32_t sequence; struct drm_crtc *crtc = arg; struct drm_device *dev = crtc->dev; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct drm_pending_vblank_event *event = omap_crtc->event; unsigned long flags; + struct timeval now; - spin_lock_irqsave(&dev->event_lock, flags); - - /* wakeup userspace */ - if (omap_crtc->event) - drm_send_vblank_event(dev, omap_crtc->pipe, omap_crtc->event); + WARN_ON(!event); omap_crtc->event = NULL; - omap_crtc->old_fb = NULL; - spin_unlock_irqrestore(&dev->event_lock, flags); + /* wakeup userspace */ + if (event) { + do_gettimeofday(&now); + + spin_lock_irqsave(&dev->event_lock, flags); + /* TODO: we can't yet use the vblank time accounting, + * because omapdss lower layer is the one that knows + * the irq # and registers the handler, which more or + * less defeats how drm_irq works.. for now just fake + * the sequence number and use gettimeofday.. + * + event->event.sequence = drm_vblank_count_and_time( + dev, omap_crtc->id, &now); + */ + event->event.sequence = sequence++; + event->event.tv_sec = now.tv_sec; + event->event.tv_usec = now.tv_usec; + list_add_tail(&event->base.link, + &event->base.file_priv->event_list); + wake_up_interruptible(&event->base.file_priv->event_wait); + spin_unlock_irqrestore(&dev->event_lock, flags); + } } -static void page_flip_worker(struct work_struct *work) +static void page_flip_cb(void *arg) { - struct omap_crtc *omap_crtc = - container_of(work, struct omap_crtc, page_flip_work); - struct drm_crtc *crtc = &omap_crtc->base; - struct drm_device *dev = crtc->dev; - struct drm_display_mode *mode = &crtc->mode; + struct drm_crtc *crtc = arg; + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct drm_framebuffer *old_fb = omap_crtc->old_fb; struct drm_gem_object *bo; - mutex_lock(&dev->mode_config.mutex); - omap_plane_mode_set(omap_crtc->plane, crtc, crtc->fb, - 0, 0, mode->hdisplay, mode->vdisplay, - crtc->x << 16, crtc->y << 16, - mode->hdisplay << 16, mode->vdisplay << 16, - vblank_cb, crtc); - mutex_unlock(&dev->mode_config.mutex); + omap_crtc->old_fb = NULL; - bo = omap_framebuffer_bo(crtc->fb, 0); - drm_gem_object_unreference_unlocked(bo); -} + omap_crtc_mode_set_base(crtc, crtc->x, crtc->y, old_fb); -static void page_flip_cb(void *arg) -{ - struct drm_crtc *crtc = arg; - struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - struct omap_drm_private *priv = crtc->dev->dev_private; + /* really we'd like to setup the callback atomically w/ setting the + * new scanout buffer to avoid getting stuck waiting an extra vblank + * cycle.. for now go for correctness and later figure out speed.. + */ + omap_plane_on_endwin(omap_crtc->plane, vblank_cb, crtc); - /* avoid assumptions about what ctxt we are called from: */ - queue_work(priv->wq, &omap_crtc->page_flip_work); + bo = omap_framebuffer_bo(crtc->fb, 0); + drm_gem_object_unreference_unlocked(bo); } static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, @@ -308,14 +179,14 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, struct omap_crtc *omap_crtc = to_omap_crtc(crtc); struct drm_gem_object *bo; - DBG("%d -> %d (event=%p)", crtc->fb ? crtc->fb->base.id : -1, - fb->base.id, event); + DBG("%d -> %d", crtc->fb ? crtc->fb->base.id : -1, fb->base.id); - if (omap_crtc->old_fb) { + if (omap_crtc->event) { dev_err(dev->dev, "already a pending flip\n"); return -EINVAL; } + omap_crtc->old_fb = crtc->fb; omap_crtc->event = event; crtc->fb = fb; @@ -363,244 +234,14 @@ static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = { .load_lut = omap_crtc_load_lut, }; -const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc) -{ - struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - return &omap_crtc->timings; -} - -enum omap_channel omap_crtc_channel(struct drm_crtc *crtc) -{ - struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - return omap_crtc->channel; -} - -static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus) -{ - struct omap_crtc *omap_crtc = - container_of(irq, struct omap_crtc, error_irq); - struct drm_crtc *crtc = &omap_crtc->base; - DRM_ERROR("%s: errors: %08x\n", omap_crtc->name, irqstatus); - /* avoid getting in a flood, unregister the irq until next vblank */ - omap_irq_unregister(crtc->dev, &omap_crtc->error_irq); -} - -static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus) -{ - struct omap_crtc *omap_crtc = - container_of(irq, struct omap_crtc, apply_irq); - struct drm_crtc *crtc = &omap_crtc->base; - - if (!omap_crtc->error_irq.registered) - omap_irq_register(crtc->dev, &omap_crtc->error_irq); - - if (!dispc_mgr_go_busy(omap_crtc->channel)) { - struct omap_drm_private *priv = - crtc->dev->dev_private; - DBG("%s: apply done", omap_crtc->name); - omap_irq_unregister(crtc->dev, &omap_crtc->apply_irq); - queue_work(priv->wq, &omap_crtc->apply_work); - } -} - -static void apply_worker(struct work_struct *work) -{ - struct omap_crtc *omap_crtc = - container_of(work, struct omap_crtc, apply_work); - struct drm_crtc *crtc = &omap_crtc->base; - struct drm_device *dev = crtc->dev; - struct omap_drm_apply *apply, *n; - bool need_apply; - - /* - * Synchronize everything on mode_config.mutex, to keep - * the callbacks and list modification all serialized - * with respect to modesetting ioctls from userspace. - */ - mutex_lock(&dev->mode_config.mutex); - dispc_runtime_get(); - - /* - * If we are still pending a previous update, wait.. when the - * pending update completes, we get kicked again. - */ - if (omap_crtc->apply_irq.registered) - goto out; - - /* finish up previous apply's: */ - list_for_each_entry_safe(apply, n, - &omap_crtc->pending_applies, pending_node) { - apply->post_apply(apply); - list_del(&apply->pending_node); - } - - need_apply = !list_empty(&omap_crtc->queued_applies); - - /* then handle the next round of of queued apply's: */ - list_for_each_entry_safe(apply, n, - &omap_crtc->queued_applies, queued_node) { - apply->pre_apply(apply); - list_del(&apply->queued_node); - apply->queued = false; - list_add_tail(&apply->pending_node, - &omap_crtc->pending_applies); - } - - if (need_apply) { - enum omap_channel channel = omap_crtc->channel; - - DBG("%s: GO", omap_crtc->name); - - if (dispc_mgr_is_enabled(channel)) { - omap_irq_register(dev, &omap_crtc->apply_irq); - dispc_mgr_go(channel); - } else { - struct omap_drm_private *priv = dev->dev_private; - queue_work(priv->wq, &omap_crtc->apply_work); - } - } - -out: - dispc_runtime_put(); - mutex_unlock(&dev->mode_config.mutex); -} - -int omap_crtc_apply(struct drm_crtc *crtc, - struct omap_drm_apply *apply) -{ - struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - struct drm_device *dev = crtc->dev; - - WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); - - /* no need to queue it again if it is already queued: */ - if (apply->queued) - return 0; - - apply->queued = true; - list_add_tail(&apply->queued_node, &omap_crtc->queued_applies); - - /* - * If there are no currently pending updates, then go ahead and - * kick the worker immediately, otherwise it will run again when - * the current update finishes. - */ - if (list_empty(&omap_crtc->pending_applies)) { - struct omap_drm_private *priv = crtc->dev->dev_private; - queue_work(priv->wq, &omap_crtc->apply_work); - } - - return 0; -} - -/* called only from apply */ -static void set_enabled(struct drm_crtc *crtc, bool enable) -{ - struct drm_device *dev = crtc->dev; - struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - enum omap_channel channel = omap_crtc->channel; - struct omap_irq_wait *wait = NULL; - - if (dispc_mgr_is_enabled(channel) == enable) - return; - - /* ignore sync-lost irqs during enable/disable */ - omap_irq_unregister(crtc->dev, &omap_crtc->error_irq); - - if (dispc_mgr_get_framedone_irq(channel)) { - if (!enable) { - wait = omap_irq_wait_init(dev, - dispc_mgr_get_framedone_irq(channel), 1); - } - } else { - /* - * When we disable digit output, we need to wait until fields - * are done. Otherwise the DSS is still working, and turning - * off the clocks prevents DSS from going to OFF mode. And when - * enabling, we need to wait for the extra sync losts - */ - wait = omap_irq_wait_init(dev, - dispc_mgr_get_vsync_irq(channel), 2); - } - - dispc_mgr_enable(channel, enable); - - if (wait) { - int ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100)); - if (ret) { - dev_err(dev->dev, "%s: timeout waiting for %s\n", - omap_crtc->name, enable ? "enable" : "disable"); - } - } - - omap_irq_register(crtc->dev, &omap_crtc->error_irq); -} - -static void omap_crtc_pre_apply(struct omap_drm_apply *apply) -{ - struct omap_crtc *omap_crtc = - container_of(apply, struct omap_crtc, apply); - struct drm_crtc *crtc = &omap_crtc->base; - struct drm_encoder *encoder = NULL; - - DBG("%s: enabled=%d, full=%d", omap_crtc->name, - omap_crtc->enabled, omap_crtc->full_update); - - if (omap_crtc->full_update) { - struct omap_drm_private *priv = crtc->dev->dev_private; - int i; - for (i = 0; i < priv->num_encoders; i++) { - if (priv->encoders[i]->crtc == crtc) { - encoder = priv->encoders[i]; - break; - } - } - } - - if (!omap_crtc->enabled) { - set_enabled(&omap_crtc->base, false); - if (encoder) - omap_encoder_set_enabled(encoder, false); - } else { - if (encoder) { - omap_encoder_set_enabled(encoder, false); - omap_encoder_update(encoder, &omap_crtc->mgr, - &omap_crtc->timings); - omap_encoder_set_enabled(encoder, true); - omap_crtc->full_update = false; - } - - dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info); - dispc_mgr_set_timings(omap_crtc->channel, - &omap_crtc->timings); - set_enabled(&omap_crtc->base, true); - } - - omap_crtc->full_update = false; -} - -static void omap_crtc_post_apply(struct omap_drm_apply *apply) -{ - /* nothing needed for post-apply */ -} - -static const char *channel_names[] = { - [OMAP_DSS_CHANNEL_LCD] = "lcd", - [OMAP_DSS_CHANNEL_DIGIT] = "tv", - [OMAP_DSS_CHANNEL_LCD2] = "lcd2", -}; - /* initialize crtc */ struct drm_crtc *omap_crtc_init(struct drm_device *dev, - struct drm_plane *plane, enum omap_channel channel, int id) + struct omap_overlay *ovl, int id) { struct drm_crtc *crtc = NULL; - struct omap_crtc *omap_crtc; - struct omap_overlay_manager_info *info; - - DBG("%s", channel_names[channel]); + struct omap_crtc *omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL); - omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL); + DBG("%s", ovl->name); if (!omap_crtc) { dev_err(dev->dev, "could not allocate CRTC\n"); @@ -609,40 +250,10 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, crtc = &omap_crtc->base; - INIT_WORK(&omap_crtc->page_flip_work, page_flip_worker); - INIT_WORK(&omap_crtc->apply_work, apply_worker); - - INIT_LIST_HEAD(&omap_crtc->pending_applies); - INIT_LIST_HEAD(&omap_crtc->queued_applies); - - omap_crtc->apply.pre_apply = omap_crtc_pre_apply; - omap_crtc->apply.post_apply = omap_crtc_post_apply; - - omap_crtc->apply_irq.irqmask = pipe2vbl(id); - omap_crtc->apply_irq.irq = omap_crtc_apply_irq; - - omap_crtc->error_irq.irqmask = - dispc_mgr_get_sync_lost_irq(channel); - omap_crtc->error_irq.irq = omap_crtc_error_irq; - omap_irq_register(dev, &omap_crtc->error_irq); - - omap_crtc->channel = channel; - omap_crtc->plane = plane; + omap_crtc->plane = omap_plane_init(dev, ovl, (1 << id), true); omap_crtc->plane->crtc = crtc; - omap_crtc->name = channel_names[channel]; - omap_crtc->pipe = id; - - /* temporary: */ - omap_crtc->mgr.id = channel; - - dss_install_mgr_ops(&mgr_ops); - - /* TODO: fix hard-coded setup.. add properties! */ - info = &omap_crtc->info; - info->default_color = 0x00000000; - info->trans_key = 0x00000000; - info->trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST; - info->trans_enabled = false; + omap_crtc->name = ovl->name; + omap_crtc->id = id; drm_crtc_init(dev, crtc, &omap_crtc_funcs); drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs); diff --git a/trunk/drivers/staging/omapdrm/omap_drv.c b/trunk/drivers/staging/omapdrm/omap_drv.c index ae5ecc2efbc7..84943e5ba1d6 100644 --- a/trunk/drivers/staging/omapdrm/omap_drv.c +++ b/trunk/drivers/staging/omapdrm/omap_drv.c @@ -74,99 +74,320 @@ static int get_connector_type(struct omap_dss_device *dssdev) } } -static int omap_modeset_init(struct drm_device *dev) +#if 0 /* enable when dss2 supports hotplug */ +static int omap_drm_notifier(struct notifier_block *nb, + unsigned long evt, void *arg) +{ + switch (evt) { + case OMAP_DSS_SIZE_CHANGE: + case OMAP_DSS_HOTPLUG_CONNECT: + case OMAP_DSS_HOTPLUG_DISCONNECT: { + struct drm_device *dev = drm_device; + DBG("hotplug event: evt=%d, dev=%p", evt, dev); + if (dev) + drm_sysfs_hotplug_event(dev); + + return NOTIFY_OK; + } + default: /* don't care about other events for now */ + return NOTIFY_DONE; + } +} +#endif + +static void dump_video_chains(void) +{ + int i; + + DBG("dumping video chains: "); + for (i = 0; i < omap_dss_get_num_overlays(); i++) { + struct omap_overlay *ovl = omap_dss_get_overlay(i); + struct omap_overlay_manager *mgr = ovl->manager; + struct omap_dss_device *dssdev = mgr ? + mgr->get_device(mgr) : NULL; + if (dssdev) { + DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name, + dssdev->name); + } else if (mgr) { + DBG("%d: %s -> %s", i, ovl->name, mgr->name); + } else { + DBG("%d: %s", i, ovl->name); + } + } +} + +/* create encoders for each manager */ +static int create_encoder(struct drm_device *dev, + struct omap_overlay_manager *mgr) { struct omap_drm_private *priv = dev->dev_private; - struct omap_dss_device *dssdev = NULL; - int num_ovls = dss_feat_get_num_ovls(); - int id; + struct drm_encoder *encoder = omap_encoder_init(dev, mgr); - drm_mode_config_init(dev); + if (!encoder) { + dev_err(dev->dev, "could not create encoder: %s\n", + mgr->name); + return -ENOMEM; + } - omap_drm_irq_install(dev); + BUG_ON(priv->num_encoders >= ARRAY_SIZE(priv->encoders)); - /* - * Create private planes and CRTCs for the last NUM_CRTCs overlay - * plus manager: - */ - for (id = 0; id < min(num_crtc, num_ovls); id++) { - struct drm_plane *plane; - struct drm_crtc *crtc; + priv->encoders[priv->num_encoders++] = encoder; - plane = omap_plane_init(dev, id, true); - crtc = omap_crtc_init(dev, plane, pipe2chan(id), id); + return 0; +} + +/* create connectors for each display device */ +static int create_connector(struct drm_device *dev, + struct omap_dss_device *dssdev) +{ + struct omap_drm_private *priv = dev->dev_private; + static struct notifier_block *notifier; + struct drm_connector *connector; + int j; + + if (!dssdev->driver) { + dev_warn(dev->dev, "%s has no driver.. skipping it\n", + dssdev->name); + return 0; + } + + if (!(dssdev->driver->get_timings || + dssdev->driver->read_edid)) { + dev_warn(dev->dev, "%s driver does not support " + "get_timings or read_edid.. skipping it!\n", + dssdev->name); + return 0; + } + + connector = omap_connector_init(dev, + get_connector_type(dssdev), dssdev); - BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); - priv->crtcs[id] = crtc; - priv->num_crtcs++; + if (!connector) { + dev_err(dev->dev, "could not create connector: %s\n", + dssdev->name); + return -ENOMEM; + } + + BUG_ON(priv->num_connectors >= ARRAY_SIZE(priv->connectors)); + + priv->connectors[priv->num_connectors++] = connector; + +#if 0 /* enable when dss2 supports hotplug */ + notifier = kzalloc(sizeof(struct notifier_block), GFP_KERNEL); + notifier->notifier_call = omap_drm_notifier; + omap_dss_add_notify(dssdev, notifier); +#else + notifier = NULL; +#endif - priv->planes[id] = plane; - priv->num_planes++; + for (j = 0; j < priv->num_encoders; j++) { + struct omap_overlay_manager *mgr = + omap_encoder_get_manager(priv->encoders[j]); + if (mgr->get_device(mgr) == dssdev) { + drm_mode_connector_attach_encoder(connector, + priv->encoders[j]); + } } - /* - * Create normal planes for the remaining overlays: + return 0; +} + +/* create up to max_overlays CRTCs mapping to overlays.. by default, + * connect the overlays to different managers/encoders, giving priority + * to encoders connected to connectors with a detected connection + */ +static int create_crtc(struct drm_device *dev, struct omap_overlay *ovl, + int *j, unsigned int connected_connectors) +{ + struct omap_drm_private *priv = dev->dev_private; + struct omap_overlay_manager *mgr = NULL; + struct drm_crtc *crtc; + + /* find next best connector, ones with detected connection first */ - for (; id < num_ovls; id++) { - struct drm_plane *plane = omap_plane_init(dev, id, false); + while (*j < priv->num_connectors && !mgr) { + if (connected_connectors & (1 << *j)) { + struct drm_encoder *encoder = + omap_connector_attached_encoder( + priv->connectors[*j]); + if (encoder) + mgr = omap_encoder_get_manager(encoder); - BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)); - priv->planes[priv->num_planes++] = plane; + } + (*j)++; } - for_each_dss_dev(dssdev) { - struct drm_connector *connector; - struct drm_encoder *encoder; + /* if we couldn't find another connected connector, lets start + * looking at the unconnected connectors: + * + * note: it might not be immediately apparent, but thanks to + * the !mgr check in both this loop and the one above, the only + * way to enter this loop is with *j == priv->num_connectors, + * so idx can never go negative. + */ + while (*j < 2 * priv->num_connectors && !mgr) { + int idx = *j - priv->num_connectors; + if (!(connected_connectors & (1 << idx))) { + struct drm_encoder *encoder = + omap_connector_attached_encoder( + priv->connectors[idx]); + if (encoder) + mgr = omap_encoder_get_manager(encoder); - if (!dssdev->driver) { - dev_warn(dev->dev, "%s has no driver.. skipping it\n", - dssdev->name); - return 0; } + (*j)++; + } - if (!(dssdev->driver->get_timings || - dssdev->driver->read_edid)) { - dev_warn(dev->dev, "%s driver does not support " - "get_timings or read_edid.. skipping it!\n", - dssdev->name); - return 0; + crtc = omap_crtc_init(dev, ovl, priv->num_crtcs); + + if (!crtc) { + dev_err(dev->dev, "could not create CRTC: %s\n", + ovl->name); + return -ENOMEM; + } + + BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); + + priv->crtcs[priv->num_crtcs++] = crtc; + + return 0; +} + +static int create_plane(struct drm_device *dev, struct omap_overlay *ovl, + unsigned int possible_crtcs) +{ + struct omap_drm_private *priv = dev->dev_private; + struct drm_plane *plane = + omap_plane_init(dev, ovl, possible_crtcs, false); + + if (!plane) { + dev_err(dev->dev, "could not create plane: %s\n", + ovl->name); + return -ENOMEM; + } + + BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)); + + priv->planes[priv->num_planes++] = plane; + + return 0; +} + +static int match_dev_name(struct omap_dss_device *dssdev, void *data) +{ + return !strcmp(dssdev->name, data); +} + +static unsigned int detect_connectors(struct drm_device *dev) +{ + struct omap_drm_private *priv = dev->dev_private; + unsigned int connected_connectors = 0; + int i; + + for (i = 0; i < priv->num_connectors; i++) { + struct drm_connector *connector = priv->connectors[i]; + if (omap_connector_detect(connector, true) == + connector_status_connected) { + connected_connectors |= (1 << i); } + } + + return connected_connectors; +} - encoder = omap_encoder_init(dev, dssdev); +static int omap_modeset_init(struct drm_device *dev) +{ + const struct omap_drm_platform_data *pdata = dev->dev->platform_data; + struct omap_kms_platform_data *kms_pdata = NULL; + struct omap_drm_private *priv = dev->dev_private; + struct omap_dss_device *dssdev = NULL; + int i, j; + unsigned int connected_connectors = 0; - if (!encoder) { - dev_err(dev->dev, "could not create encoder: %s\n", - dssdev->name); - return -ENOMEM; + drm_mode_config_init(dev); + + if (pdata && pdata->kms_pdata) { + kms_pdata = pdata->kms_pdata; + + /* if platform data is provided by the board file, use it to + * control which overlays, managers, and devices we own. + */ + for (i = 0; i < kms_pdata->mgr_cnt; i++) { + struct omap_overlay_manager *mgr = + omap_dss_get_overlay_manager( + kms_pdata->mgr_ids[i]); + create_encoder(dev, mgr); + } + + for (i = 0; i < kms_pdata->dev_cnt; i++) { + struct omap_dss_device *dssdev = + omap_dss_find_device( + (void *)kms_pdata->dev_names[i], + match_dev_name); + if (!dssdev) { + dev_warn(dev->dev, "no such dssdev: %s\n", + kms_pdata->dev_names[i]); + continue; + } + create_connector(dev, dssdev); } - connector = omap_connector_init(dev, - get_connector_type(dssdev), dssdev, encoder); + connected_connectors = detect_connectors(dev); - if (!connector) { - dev_err(dev->dev, "could not create connector: %s\n", - dssdev->name); - return -ENOMEM; + j = 0; + for (i = 0; i < kms_pdata->ovl_cnt; i++) { + struct omap_overlay *ovl = + omap_dss_get_overlay(kms_pdata->ovl_ids[i]); + create_crtc(dev, ovl, &j, connected_connectors); } - BUG_ON(priv->num_encoders >= ARRAY_SIZE(priv->encoders)); - BUG_ON(priv->num_connectors >= ARRAY_SIZE(priv->connectors)); + for (i = 0; i < kms_pdata->pln_cnt; i++) { + struct omap_overlay *ovl = + omap_dss_get_overlay(kms_pdata->pln_ids[i]); + create_plane(dev, ovl, (1 << priv->num_crtcs) - 1); + } + } else { + /* otherwise just grab up to CONFIG_DRM_OMAP_NUM_CRTCS and try + * to make educated guesses about everything else + */ + int max_overlays = min(omap_dss_get_num_overlays(), num_crtc); - priv->encoders[priv->num_encoders++] = encoder; - priv->connectors[priv->num_connectors++] = connector; + for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) + create_encoder(dev, omap_dss_get_overlay_manager(i)); + + for_each_dss_dev(dssdev) { + create_connector(dev, dssdev); + } - drm_mode_connector_attach_encoder(connector, encoder); + connected_connectors = detect_connectors(dev); - /* figure out which crtc's we can connect the encoder to: */ - encoder->possible_crtcs = 0; - for (id = 0; id < priv->num_crtcs; id++) { - enum omap_dss_output_id supported_outputs = - dss_feat_get_supported_outputs(pipe2chan(id)); - if (supported_outputs & dssdev->output->id) - encoder->possible_crtcs |= (1 << id); + j = 0; + for (i = 0; i < max_overlays; i++) { + create_crtc(dev, omap_dss_get_overlay(i), + &j, connected_connectors); + } + + /* use any remaining overlays as drm planes */ + for (; i < omap_dss_get_num_overlays(); i++) { + struct omap_overlay *ovl = omap_dss_get_overlay(i); + create_plane(dev, ovl, (1 << priv->num_crtcs) - 1); } } + /* for now keep the mapping of CRTCs and encoders static.. */ + for (i = 0; i < priv->num_encoders; i++) { + struct drm_encoder *encoder = priv->encoders[i]; + struct omap_overlay_manager *mgr = + omap_encoder_get_manager(encoder); + + encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; + + DBG("%s: possible_crtcs=%08x", mgr->name, + encoder->possible_crtcs); + } + + dump_video_chains(); + dev->mode_config.min_width = 32; dev->mode_config.min_height = 32; @@ -229,7 +450,7 @@ static int ioctl_gem_new(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_omap_gem_new *args = data; - VERB("%p:%p: size=0x%08x, flags=%08x", dev, file_priv, + DBG("%p:%p: size=0x%08x, flags=%08x", dev, file_priv, args->size.bytes, args->flags); return omap_gem_new_handle(dev, file_priv, args->size, args->flags, &args->handle); @@ -289,7 +510,7 @@ static int ioctl_gem_info(struct drm_device *dev, void *data, struct drm_gem_object *obj; int ret = 0; - VERB("%p:%p: handle=%d", dev, file_priv, args->handle); + DBG("%p:%p: handle=%d", dev, file_priv, args->handle); obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (!obj) @@ -344,6 +565,14 @@ static int dev_load(struct drm_device *dev, unsigned long flags) dev->dev_private = priv; + ret = omapdss_compat_init(); + if (ret) { + dev_err(dev->dev, "coult not init omapdss\n"); + dev->dev_private = NULL; + kfree(priv); + return ret; + } + priv->wq = alloc_ordered_workqueue("omapdrm", 0); INIT_LIST_HEAD(&priv->obj_list); @@ -355,13 +584,10 @@ static int dev_load(struct drm_device *dev, unsigned long flags) dev_err(dev->dev, "omap_modeset_init failed: ret=%d\n", ret); dev->dev_private = NULL; kfree(priv); + omapdss_compat_uninit(); return ret; } - ret = drm_vblank_init(dev, priv->num_crtcs); - if (ret) - dev_warn(dev->dev, "could not init vblank\n"); - priv->fbdev = omap_fbdev_init(dev); if (!priv->fbdev) { dev_warn(dev->dev, "omap_fbdev_init failed\n"); @@ -370,6 +596,10 @@ static int dev_load(struct drm_device *dev, unsigned long flags) drm_kms_helper_poll_init(dev); + ret = drm_vblank_init(dev, priv->num_crtcs); + if (ret) + dev_warn(dev->dev, "could not init vblank\n"); + return 0; } @@ -379,9 +609,8 @@ static int dev_unload(struct drm_device *dev) DBG("unload: dev=%p", dev); - drm_kms_helper_poll_fini(dev); drm_vblank_cleanup(dev); - omap_drm_irq_uninstall(dev); + drm_kms_helper_poll_fini(dev); omap_fbdev_free(dev); omap_modeset_free(dev); @@ -390,6 +619,8 @@ static int dev_unload(struct drm_device *dev) flush_workqueue(priv->wq); destroy_workqueue(priv->wq); + omapdss_compat_uninit(); + kfree(dev->dev_private); dev->dev_private = NULL; @@ -449,9 +680,7 @@ static void dev_lastclose(struct drm_device *dev) } } - mutex_lock(&dev->mode_config.mutex); ret = drm_fb_helper_restore_fbdev_mode(priv->fbdev); - mutex_unlock(&dev->mode_config.mutex); if (ret) DBG("failed to restore crtc mode"); } @@ -466,6 +695,60 @@ static void dev_postclose(struct drm_device *dev, struct drm_file *file) DBG("postclose: dev=%p, file=%p", dev, file); } +/** + * enable_vblank - enable vblank interrupt events + * @dev: DRM device + * @crtc: which irq to enable + * + * Enable vblank interrupts for @crtc. If the device doesn't have + * a hardware vblank counter, this routine should be a no-op, since + * interrupts will have to stay on to keep the count accurate. + * + * RETURNS + * Zero on success, appropriate errno if the given @crtc's vblank + * interrupt cannot be enabled. + */ +static int dev_enable_vblank(struct drm_device *dev, int crtc) +{ + DBG("enable_vblank: dev=%p, crtc=%d", dev, crtc); + return 0; +} + +/** + * disable_vblank - disable vblank interrupt events + * @dev: DRM device + * @crtc: which irq to enable + * + * Disable vblank interrupts for @crtc. If the device doesn't have + * a hardware vblank counter, this routine should be a no-op, since + * interrupts will have to stay on to keep the count accurate. + */ +static void dev_disable_vblank(struct drm_device *dev, int crtc) +{ + DBG("disable_vblank: dev=%p, crtc=%d", dev, crtc); +} + +static irqreturn_t dev_irq_handler(DRM_IRQ_ARGS) +{ + return IRQ_HANDLED; +} + +static void dev_irq_preinstall(struct drm_device *dev) +{ + DBG("irq_preinstall: dev=%p", dev); +} + +static int dev_irq_postinstall(struct drm_device *dev) +{ + DBG("irq_postinstall: dev=%p", dev); + return 0; +} + +static void dev_irq_uninstall(struct drm_device *dev) +{ + DBG("irq_uninstall: dev=%p", dev); +} + static const struct vm_operations_struct omap_gem_vm_ops = { .fault = omap_gem_fault, .open = drm_gem_vm_open, @@ -495,12 +778,12 @@ static struct drm_driver omap_drm_driver = { .preclose = dev_preclose, .postclose = dev_postclose, .get_vblank_counter = drm_vblank_count, - .enable_vblank = omap_irq_enable_vblank, - .disable_vblank = omap_irq_disable_vblank, - .irq_preinstall = omap_irq_preinstall, - .irq_postinstall = omap_irq_postinstall, - .irq_uninstall = omap_irq_uninstall, - .irq_handler = omap_irq_handler, + .enable_vblank = dev_enable_vblank, + .disable_vblank = dev_disable_vblank, + .irq_preinstall = dev_irq_preinstall, + .irq_postinstall = dev_irq_postinstall, + .irq_uninstall = dev_irq_uninstall, + .irq_handler = dev_irq_handler, #ifdef CONFIG_DEBUG_FS .debugfs_init = omap_debugfs_init, .debugfs_cleanup = omap_debugfs_cleanup, diff --git a/trunk/drivers/staging/omapdrm/omap_drv.h b/trunk/drivers/staging/omapdrm/omap_drv.h index cd1f22b0b124..1d4aea53b75d 100644 --- a/trunk/drivers/staging/omapdrm/omap_drv.h +++ b/trunk/drivers/staging/omapdrm/omap_drv.h @@ -28,7 +28,6 @@ #include #include "omap_drm.h" - #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) #define VERB(fmt, ...) if (0) DRM_DEBUG(fmt, ##__VA_ARGS__) /* verbose debug */ @@ -40,51 +39,6 @@ */ #define MAX_MAPPERS 2 -/* parameters which describe (unrotated) coordinates of scanout within a fb: */ -struct omap_drm_window { - uint32_t rotation; - int32_t crtc_x, crtc_y; /* signed because can be offscreen */ - uint32_t crtc_w, crtc_h; - uint32_t src_x, src_y; - uint32_t src_w, src_h; -}; - -/* Once GO bit is set, we can't make further updates to shadowed registers - * until the GO bit is cleared. So various parts in the kms code that need - * to update shadowed registers queue up a pair of callbacks, pre_apply - * which is called before setting GO bit, and post_apply that is called - * after GO bit is cleared. The crtc manages the queuing, and everyone - * else goes thru omap_crtc_apply() using these callbacks so that the - * code which has to deal w/ GO bit state is centralized. - */ -struct omap_drm_apply { - struct list_head pending_node, queued_node; - bool queued; - void (*pre_apply)(struct omap_drm_apply *apply); - void (*post_apply)(struct omap_drm_apply *apply); -}; - -/* For transiently registering for different DSS irqs that various parts - * of the KMS code need during setup/configuration. We these are not - * necessarily the same as what drm_vblank_get/put() are requesting, and - * the hysteresis in drm_vblank_put() is not necessarily desirable for - * internal housekeeping related irq usage. - */ -struct omap_drm_irq { - struct list_head node; - uint32_t irqmask; - bool registered; - void (*irq)(struct omap_drm_irq *irq, uint32_t irqstatus); -}; - -/* For KMS code that needs to wait for a certain # of IRQs: - */ -struct omap_irq_wait; -struct omap_irq_wait * omap_irq_wait_init(struct drm_device *dev, - uint32_t irqmask, int count); -int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait, - unsigned long timeout); - struct omap_drm_private { uint32_t omaprev; @@ -104,7 +58,6 @@ struct omap_drm_private { struct workqueue_struct *wq; - /* list of GEM objects: */ struct list_head obj_list; bool has_dmm; @@ -112,11 +65,6 @@ struct omap_drm_private { /* properties: */ struct drm_property *rotation_prop; struct drm_property *zorder_prop; - - /* irq handling: */ - struct list_head irq_list; /* list of omap_drm_irq */ - uint32_t vblank_mask; /* irq bits set for userspace vblank */ - struct omap_drm_irq error_handler; }; /* this should probably be in drm-core to standardize amongst drivers */ @@ -127,6 +75,15 @@ struct omap_drm_private { #define DRM_REFLECT_X 4 #define DRM_REFLECT_Y 5 +/* parameters which describe (unrotated) coordinates of scanout within a fb: */ +struct omap_drm_window { + uint32_t rotation; + int32_t crtc_x, crtc_y; /* signed because can be offscreen */ + uint32_t crtc_w, crtc_h; + uint32_t src_x, src_y; + uint32_t src_w, src_h; +}; + #ifdef CONFIG_DEBUG_FS int omap_debugfs_init(struct drm_minor *minor); void omap_debugfs_cleanup(struct drm_minor *minor); @@ -135,36 +92,23 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m); void omap_gem_describe_objects(struct list_head *list, struct seq_file *m); #endif -int omap_irq_enable_vblank(struct drm_device *dev, int crtc); -void omap_irq_disable_vblank(struct drm_device *dev, int crtc); -irqreturn_t omap_irq_handler(DRM_IRQ_ARGS); -void omap_irq_preinstall(struct drm_device *dev); -int omap_irq_postinstall(struct drm_device *dev); -void omap_irq_uninstall(struct drm_device *dev); -void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq); -void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq); -int omap_drm_irq_uninstall(struct drm_device *dev); -int omap_drm_irq_install(struct drm_device *dev); - struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev); void omap_fbdev_free(struct drm_device *dev); -const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc); -enum omap_channel omap_crtc_channel(struct drm_crtc *crtc); -int omap_crtc_apply(struct drm_crtc *crtc, - struct omap_drm_apply *apply); struct drm_crtc *omap_crtc_init(struct drm_device *dev, - struct drm_plane *plane, enum omap_channel channel, int id); + struct omap_overlay *ovl, int id); struct drm_plane *omap_plane_init(struct drm_device *dev, - int plane_id, bool private_plane); + struct omap_overlay *ovl, unsigned int possible_crtcs, + bool priv); int omap_plane_dpms(struct drm_plane *plane, int mode); int omap_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h, + uint32_t src_w, uint32_t src_h); +void omap_plane_on_endwin(struct drm_plane *plane, void (*fxn)(void *), void *arg); void omap_plane_install_properties(struct drm_plane *plane, struct drm_mode_object *obj); @@ -172,24 +116,20 @@ int omap_plane_set_property(struct drm_plane *plane, struct drm_property *property, uint64_t val); struct drm_encoder *omap_encoder_init(struct drm_device *dev, - struct omap_dss_device *dssdev); -int omap_encoder_set_enabled(struct drm_encoder *encoder, bool enabled); -int omap_encoder_update(struct drm_encoder *encoder, - struct omap_overlay_manager *mgr, - struct omap_video_timings *timings); - -struct drm_connector *omap_connector_init(struct drm_device *dev, - int connector_type, struct omap_dss_device *dssdev, + struct omap_overlay_manager *mgr); +struct omap_overlay_manager *omap_encoder_get_manager( struct drm_encoder *encoder); struct drm_encoder *omap_connector_attached_encoder( struct drm_connector *connector); -void omap_connector_flush(struct drm_connector *connector, - int x, int y, int w, int h); +enum drm_connector_status omap_connector_detect( + struct drm_connector *connector, bool force); -void copy_timings_omap_to_drm(struct drm_display_mode *mode, - struct omap_video_timings *timings); -void copy_timings_drm_to_omap(struct omap_video_timings *timings, +struct drm_connector *omap_connector_init(struct drm_device *dev, + int connector_type, struct omap_dss_device *dssdev); +void omap_connector_mode_set(struct drm_connector *connector, struct drm_display_mode *mode); +void omap_connector_flush(struct drm_connector *connector, + int x, int y, int w, int h); uint32_t omap_framebuffer_get_formats(uint32_t *pixel_formats, uint32_t max_formats, enum omap_color_mode supported_modes); @@ -267,40 +207,6 @@ static inline int align_pitch(int pitch, int width, int bpp) return ALIGN(pitch, 8 * bytespp); } -static inline enum omap_channel pipe2chan(int pipe) -{ - int num_mgrs = dss_feat_get_num_mgrs(); - - /* - * We usually don't want to create a CRTC for each manager, - * at least not until we have a way to expose private planes - * to userspace. Otherwise there would not be enough video - * pipes left for drm planes. The higher #'d managers tend - * to have more features so start in reverse order. - */ - return num_mgrs - pipe - 1; -} - -/* map crtc to vblank mask */ -static inline uint32_t pipe2vbl(int crtc) -{ - enum omap_channel channel = pipe2chan(crtc); - return dispc_mgr_get_vsync_irq(channel); -} - -static inline int crtc2pipe(struct drm_device *dev, struct drm_crtc *crtc) -{ - struct omap_drm_private *priv = dev->dev_private; - int i; - - for (i = 0; i < ARRAY_SIZE(priv->crtcs); i++) - if (priv->crtcs[i] == crtc) - return i; - - BUG(); /* bogus CRTC ptr */ - return -1; -} - /* should these be made into common util helpers? */ diff --git a/trunk/drivers/staging/omapdrm/omap_encoder.c b/trunk/drivers/staging/omapdrm/omap_encoder.c index e053160d2db3..5341d5e3e317 100644 --- a/trunk/drivers/staging/omapdrm/omap_encoder.c +++ b/trunk/drivers/staging/omapdrm/omap_encoder.c @@ -22,56 +22,37 @@ #include "drm_crtc.h" #include "drm_crtc_helper.h" -#include - - /* * encoder funcs */ #define to_omap_encoder(x) container_of(x, struct omap_encoder, base) -/* The encoder and connector both map to same dssdev.. the encoder - * handles the 'active' parts, ie. anything the modifies the state - * of the hw, and the connector handles the 'read-only' parts, like - * detecting connection and reading edid. - */ struct omap_encoder { struct drm_encoder base; - struct omap_dss_device *dssdev; + struct omap_overlay_manager *mgr; }; static void omap_encoder_destroy(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); + DBG("%s", omap_encoder->mgr->name); drm_encoder_cleanup(encoder); kfree(omap_encoder); } -static const struct drm_encoder_funcs omap_encoder_funcs = { - .destroy = omap_encoder_destroy, -}; - -/* - * The CRTC drm_crtc_helper_set_mode() doesn't really give us the right - * order.. the easiest way to work around this for now is to make all - * the encoder-helper's no-op's and have the omap_crtc code take care - * of the sequencing and call us in the right points. - * - * Eventually to handle connecting CRTCs to different encoders properly, - * either the CRTC helpers need to change or we need to replace - * drm_crtc_helper_set_mode(), but lets wait until atomic-modeset for - * that. - */ - static void omap_encoder_dpms(struct drm_encoder *encoder, int mode) { + struct omap_encoder *omap_encoder = to_omap_encoder(encoder); + DBG("%s: %d", omap_encoder->mgr->name, mode); } static bool omap_encoder_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { + struct omap_encoder *omap_encoder = to_omap_encoder(encoder); + DBG("%s", omap_encoder->mgr->name); return true; } @@ -79,16 +60,47 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { + struct omap_encoder *omap_encoder = to_omap_encoder(encoder); + struct drm_device *dev = encoder->dev; + struct omap_drm_private *priv = dev->dev_private; + int i; + + mode = adjusted_mode; + + DBG("%s: set mode: %dx%d", omap_encoder->mgr->name, + mode->hdisplay, mode->vdisplay); + + for (i = 0; i < priv->num_connectors; i++) { + struct drm_connector *connector = priv->connectors[i]; + if (connector->encoder == encoder) + omap_connector_mode_set(connector, mode); + + } } static void omap_encoder_prepare(struct drm_encoder *encoder) { + struct omap_encoder *omap_encoder = to_omap_encoder(encoder); + struct drm_encoder_helper_funcs *encoder_funcs = + encoder->helper_private; + DBG("%s", omap_encoder->mgr->name); + encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); } static void omap_encoder_commit(struct drm_encoder *encoder) { + struct omap_encoder *omap_encoder = to_omap_encoder(encoder); + struct drm_encoder_helper_funcs *encoder_funcs = + encoder->helper_private; + DBG("%s", omap_encoder->mgr->name); + omap_encoder->mgr->apply(omap_encoder->mgr); + encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); } +static const struct drm_encoder_funcs omap_encoder_funcs = { + .destroy = omap_encoder_destroy, +}; + static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = { .dpms = omap_encoder_dpms, .mode_fixup = omap_encoder_mode_fixup, @@ -97,54 +109,23 @@ static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = { .commit = omap_encoder_commit, }; -/* - * Instead of relying on the helpers for modeset, the omap_crtc code - * calls these functions in the proper sequence. - */ - -int omap_encoder_set_enabled(struct drm_encoder *encoder, bool enabled) +struct omap_overlay_manager *omap_encoder_get_manager( + struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); - struct omap_dss_device *dssdev = omap_encoder->dssdev; - struct omap_dss_driver *dssdrv = dssdev->driver; - - if (enabled) { - return dssdrv->enable(dssdev); - } else { - dssdrv->disable(dssdev); - return 0; - } -} - -int omap_encoder_update(struct drm_encoder *encoder, - struct omap_overlay_manager *mgr, - struct omap_video_timings *timings) -{ - struct drm_device *dev = encoder->dev; - struct omap_encoder *omap_encoder = to_omap_encoder(encoder); - struct omap_dss_device *dssdev = omap_encoder->dssdev; - struct omap_dss_driver *dssdrv = dssdev->driver; - int ret; - - dssdev->output->manager = mgr; - - ret = dssdrv->check_timings(dssdev, timings); - if (ret) { - dev_err(dev->dev, "could not set timings: %d\n", ret); - return ret; - } - - dssdrv->set_timings(dssdev, timings); - - return 0; + return omap_encoder->mgr; } /* initialize encoder */ struct drm_encoder *omap_encoder_init(struct drm_device *dev, - struct omap_dss_device *dssdev) + struct omap_overlay_manager *mgr) { struct drm_encoder *encoder = NULL; struct omap_encoder *omap_encoder; + struct omap_overlay_manager_info info; + int ret; + + DBG("%s", mgr->name); omap_encoder = kzalloc(sizeof(*omap_encoder), GFP_KERNEL); if (!omap_encoder) { @@ -152,14 +133,33 @@ struct drm_encoder *omap_encoder_init(struct drm_device *dev, goto fail; } - omap_encoder->dssdev = dssdev; - + omap_encoder->mgr = mgr; encoder = &omap_encoder->base; drm_encoder_init(dev, encoder, &omap_encoder_funcs, DRM_MODE_ENCODER_TMDS); drm_encoder_helper_add(encoder, &omap_encoder_helper_funcs); + mgr->get_manager_info(mgr, &info); + + /* TODO: fix hard-coded setup.. */ + info.default_color = 0x00000000; + info.trans_key = 0x00000000; + info.trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST; + info.trans_enabled = false; + + ret = mgr->set_manager_info(mgr, &info); + if (ret) { + dev_err(dev->dev, "could not set manager info\n"); + goto fail; + } + + ret = mgr->apply(mgr); + if (ret) { + dev_err(dev->dev, "could not apply\n"); + goto fail; + } + return encoder; fail: diff --git a/trunk/drivers/staging/omapdrm/omap_gem_dmabuf.c b/trunk/drivers/staging/omapdrm/omap_gem_dmabuf.c index b6c5b5c6c8c5..9a302062b031 100644 --- a/trunk/drivers/staging/omapdrm/omap_gem_dmabuf.c +++ b/trunk/drivers/staging/omapdrm/omap_gem_dmabuf.c @@ -194,7 +194,7 @@ struct dma_buf_ops omap_dmabuf_ops = { struct dma_buf *omap_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) { - return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, flags); + return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, 0600); } struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev, @@ -207,12 +207,7 @@ struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev, obj = buffer->priv; /* is it from our device? */ if (obj->dev == dev) { - /* - * Importing dmabuf exported from out own gem increases - * refcount on gem itself instead of f_count of dmabuf. - */ drm_gem_object_reference(obj); - dma_buf_put(buffer); return obj; } } diff --git a/trunk/drivers/staging/omapdrm/omap_irq.c b/trunk/drivers/staging/omapdrm/omap_irq.c deleted file mode 100644 index 2629ba7be6c8..000000000000 --- a/trunk/drivers/staging/omapdrm/omap_irq.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * drivers/staging/omapdrm/omap_irq.c - * - * Copyright (C) 2012 Texas Instruments - * Author: Rob Clark - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#include "omap_drv.h" - -static DEFINE_SPINLOCK(list_lock); - -static void omap_irq_error_handler(struct omap_drm_irq *irq, - uint32_t irqstatus) -{ - DRM_ERROR("errors: %08x\n", irqstatus); -} - -/* call with list_lock and dispc runtime held */ -static void omap_irq_update(struct drm_device *dev) -{ - struct omap_drm_private *priv = dev->dev_private; - struct omap_drm_irq *irq; - uint32_t irqmask = priv->vblank_mask; - - BUG_ON(!spin_is_locked(&list_lock)); - - list_for_each_entry(irq, &priv->irq_list, node) - irqmask |= irq->irqmask; - - DBG("irqmask=%08x", irqmask); - - dispc_write_irqenable(irqmask); - dispc_read_irqenable(); /* flush posted write */ -} - -void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq) -{ - struct omap_drm_private *priv = dev->dev_private; - unsigned long flags; - - dispc_runtime_get(); - spin_lock_irqsave(&list_lock, flags); - - if (!WARN_ON(irq->registered)) { - irq->registered = true; - list_add(&irq->node, &priv->irq_list); - omap_irq_update(dev); - } - - spin_unlock_irqrestore(&list_lock, flags); - dispc_runtime_put(); -} - -void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq) -{ - unsigned long flags; - - dispc_runtime_get(); - spin_lock_irqsave(&list_lock, flags); - - if (!WARN_ON(!irq->registered)) { - irq->registered = false; - list_del(&irq->node); - omap_irq_update(dev); - } - - spin_unlock_irqrestore(&list_lock, flags); - dispc_runtime_put(); -} - -struct omap_irq_wait { - struct omap_drm_irq irq; - int count; -}; - -static DECLARE_WAIT_QUEUE_HEAD(wait_event); - -static void wait_irq(struct omap_drm_irq *irq, uint32_t irqstatus) -{ - struct omap_irq_wait *wait = - container_of(irq, struct omap_irq_wait, irq); - wait->count--; - wake_up_all(&wait_event); -} - -struct omap_irq_wait * omap_irq_wait_init(struct drm_device *dev, - uint32_t irqmask, int count) -{ - struct omap_irq_wait *wait = kzalloc(sizeof(*wait), GFP_KERNEL); - wait->irq.irq = wait_irq; - wait->irq.irqmask = irqmask; - wait->count = count; - omap_irq_register(dev, &wait->irq); - return wait; -} - -int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait, - unsigned long timeout) -{ - int ret = wait_event_timeout(wait_event, (wait->count <= 0), timeout); - omap_irq_unregister(dev, &wait->irq); - kfree(wait); - if (ret == 0) - return -1; - return 0; -} - -/** - * enable_vblank - enable vblank interrupt events - * @dev: DRM device - * @crtc: which irq to enable - * - * Enable vblank interrupts for @crtc. If the device doesn't have - * a hardware vblank counter, this routine should be a no-op, since - * interrupts will have to stay on to keep the count accurate. - * - * RETURNS - * Zero on success, appropriate errno if the given @crtc's vblank - * interrupt cannot be enabled. - */ -int omap_irq_enable_vblank(struct drm_device *dev, int crtc) -{ - struct omap_drm_private *priv = dev->dev_private; - unsigned long flags; - - DBG("dev=%p, crtc=%d", dev, crtc); - - dispc_runtime_get(); - spin_lock_irqsave(&list_lock, flags); - priv->vblank_mask |= pipe2vbl(crtc); - omap_irq_update(dev); - spin_unlock_irqrestore(&list_lock, flags); - dispc_runtime_put(); - - return 0; -} - -/** - * disable_vblank - disable vblank interrupt events - * @dev: DRM device - * @crtc: which irq to enable - * - * Disable vblank interrupts for @crtc. If the device doesn't have - * a hardware vblank counter, this routine should be a no-op, since - * interrupts will have to stay on to keep the count accurate. - */ -void omap_irq_disable_vblank(struct drm_device *dev, int crtc) -{ - struct omap_drm_private *priv = dev->dev_private; - unsigned long flags; - - DBG("dev=%p, crtc=%d", dev, crtc); - - dispc_runtime_get(); - spin_lock_irqsave(&list_lock, flags); - priv->vblank_mask &= ~pipe2vbl(crtc); - omap_irq_update(dev); - spin_unlock_irqrestore(&list_lock, flags); - dispc_runtime_put(); -} - -irqreturn_t omap_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - struct omap_drm_private *priv = dev->dev_private; - struct omap_drm_irq *handler, *n; - unsigned long flags; - unsigned int id; - u32 irqstatus; - - irqstatus = dispc_read_irqstatus(); - dispc_clear_irqstatus(irqstatus); - dispc_read_irqstatus(); /* flush posted write */ - - VERB("irqs: %08x", irqstatus); - - for (id = 0; id < priv->num_crtcs; id++) - if (irqstatus & pipe2vbl(id)) - drm_handle_vblank(dev, id); - - spin_lock_irqsave(&list_lock, flags); - list_for_each_entry_safe(handler, n, &priv->irq_list, node) { - if (handler->irqmask & irqstatus) { - spin_unlock_irqrestore(&list_lock, flags); - handler->irq(handler, handler->irqmask & irqstatus); - spin_lock_irqsave(&list_lock, flags); - } - } - spin_unlock_irqrestore(&list_lock, flags); - - return IRQ_HANDLED; -} - -void omap_irq_preinstall(struct drm_device *dev) -{ - DBG("dev=%p", dev); - dispc_runtime_get(); - dispc_clear_irqstatus(0xffffffff); - dispc_runtime_put(); -} - -int omap_irq_postinstall(struct drm_device *dev) -{ - struct omap_drm_private *priv = dev->dev_private; - struct omap_drm_irq *error_handler = &priv->error_handler; - - DBG("dev=%p", dev); - - INIT_LIST_HEAD(&priv->irq_list); - - error_handler->irq = omap_irq_error_handler; - error_handler->irqmask = DISPC_IRQ_OCP_ERR; - - /* for now ignore DISPC_IRQ_SYNC_LOST_DIGIT.. really I think - * we just need to ignore it while enabling tv-out - */ - error_handler->irqmask &= ~DISPC_IRQ_SYNC_LOST_DIGIT; - - omap_irq_register(dev, error_handler); - - return 0; -} - -void omap_irq_uninstall(struct drm_device *dev) -{ - DBG("dev=%p", dev); - // TODO prolly need to call drm_irq_uninstall() somewhere too -} - -/* - * We need a special version, instead of just using drm_irq_install(), - * because we need to register the irq via omapdss. Once omapdss and - * omapdrm are merged together we can assign the dispc hwmod data to - * ourselves and drop these and just use drm_irq_{install,uninstall}() - */ - -int omap_drm_irq_install(struct drm_device *dev) -{ - int ret; - - mutex_lock(&dev->struct_mutex); - - if (dev->irq_enabled) { - mutex_unlock(&dev->struct_mutex); - return -EBUSY; - } - dev->irq_enabled = 1; - mutex_unlock(&dev->struct_mutex); - - /* Before installing handler */ - if (dev->driver->irq_preinstall) - dev->driver->irq_preinstall(dev); - - ret = dispc_request_irq(dev->driver->irq_handler, dev); - - if (ret < 0) { - mutex_lock(&dev->struct_mutex); - dev->irq_enabled = 0; - mutex_unlock(&dev->struct_mutex); - return ret; - } - - /* After installing handler */ - if (dev->driver->irq_postinstall) - ret = dev->driver->irq_postinstall(dev); - - if (ret < 0) { - mutex_lock(&dev->struct_mutex); - dev->irq_enabled = 0; - mutex_unlock(&dev->struct_mutex); - dispc_free_irq(dev); - } - - return ret; -} - -int omap_drm_irq_uninstall(struct drm_device *dev) -{ - unsigned long irqflags; - int irq_enabled, i; - - mutex_lock(&dev->struct_mutex); - irq_enabled = dev->irq_enabled; - dev->irq_enabled = 0; - mutex_unlock(&dev->struct_mutex); - - /* - * Wake up any waiters so they don't hang. - */ - if (dev->num_crtcs) { - spin_lock_irqsave(&dev->vbl_lock, irqflags); - for (i = 0; i < dev->num_crtcs; i++) { - DRM_WAKEUP(&dev->vbl_queue[i]); - dev->vblank_enabled[i] = 0; - dev->last_vblank[i] = - dev->driver->get_vblank_counter(dev, i); - } - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - } - - if (!irq_enabled) - return -EINVAL; - - if (dev->driver->irq_uninstall) - dev->driver->irq_uninstall(dev); - - dispc_free_irq(dev); - - return 0; -} diff --git a/trunk/drivers/staging/omapdrm/omap_plane.c b/trunk/drivers/staging/omapdrm/omap_plane.c index bb989d7f026d..2a8e5bab49c9 100644 --- a/trunk/drivers/staging/omapdrm/omap_plane.c +++ b/trunk/drivers/staging/omapdrm/omap_plane.c @@ -41,14 +41,12 @@ struct callback { struct omap_plane { struct drm_plane base; - int id; /* TODO rename omap_plane -> omap_plane_id in omapdss so I can use the enum */ - const char *name; + struct omap_overlay *ovl; struct omap_overlay_info info; - struct omap_drm_apply apply; /* position/orientation of scanout within the fb: */ struct omap_drm_window win; - bool enabled; + /* last fb that we pinned: */ struct drm_framebuffer *pinned_fb; @@ -56,15 +54,189 @@ struct omap_plane { uint32_t nformats; uint32_t formats[32]; - struct omap_drm_irq error_irq; + /* for synchronizing access to unpins fifo */ + struct mutex unpin_mutex; - /* set of bo's pending unpin until next post_apply() */ + /* set of bo's pending unpin until next END_WIN irq */ DECLARE_KFIFO_PTR(unpin_fifo, struct drm_gem_object *); + int num_unpins, pending_num_unpins; + + /* for deferred unpin when we need to wait for scanout complete irq */ + struct work_struct work; + + /* callback on next endwin irq */ + struct callback endwin; +}; - // XXX maybe get rid of this and handle vblank in crtc too? - struct callback apply_done_cb; +/* map from ovl->id to the irq we are interested in for scanout-done */ +static const uint32_t id2irq[] = { + [OMAP_DSS_GFX] = DISPC_IRQ_GFX_END_WIN, + [OMAP_DSS_VIDEO1] = DISPC_IRQ_VID1_END_WIN, + [OMAP_DSS_VIDEO2] = DISPC_IRQ_VID2_END_WIN, + [OMAP_DSS_VIDEO3] = DISPC_IRQ_VID3_END_WIN, }; +static void dispc_isr(void *arg, uint32_t mask) +{ + struct drm_plane *plane = arg; + struct omap_plane *omap_plane = to_omap_plane(plane); + struct omap_drm_private *priv = plane->dev->dev_private; + + omap_dispc_unregister_isr(dispc_isr, plane, + id2irq[omap_plane->ovl->id]); + + queue_work(priv->wq, &omap_plane->work); +} + +static void unpin_worker(struct work_struct *work) +{ + struct omap_plane *omap_plane = + container_of(work, struct omap_plane, work); + struct callback endwin; + + mutex_lock(&omap_plane->unpin_mutex); + DBG("unpinning %d of %d", omap_plane->num_unpins, + omap_plane->num_unpins + omap_plane->pending_num_unpins); + while (omap_plane->num_unpins > 0) { + struct drm_gem_object *bo = NULL; + int ret = kfifo_get(&omap_plane->unpin_fifo, &bo); + WARN_ON(!ret); + omap_gem_put_paddr(bo); + drm_gem_object_unreference_unlocked(bo); + omap_plane->num_unpins--; + } + endwin = omap_plane->endwin; + omap_plane->endwin.fxn = NULL; + mutex_unlock(&omap_plane->unpin_mutex); + + if (endwin.fxn) + endwin.fxn(endwin.arg); +} + +static void install_irq(struct drm_plane *plane) +{ + struct omap_plane *omap_plane = to_omap_plane(plane); + struct omap_overlay *ovl = omap_plane->ovl; + int ret; + + ret = omap_dispc_register_isr(dispc_isr, plane, id2irq[ovl->id]); + + /* + * omapdss has upper limit on # of registered irq handlers, + * which we shouldn't hit.. but if we do the limit should + * be raised or bad things happen: + */ + WARN_ON(ret == -EBUSY); +} + +/* push changes down to dss2 */ +static int commit(struct drm_plane *plane) +{ + struct drm_device *dev = plane->dev; + struct omap_plane *omap_plane = to_omap_plane(plane); + struct omap_overlay *ovl = omap_plane->ovl; + struct omap_overlay_info *info = &omap_plane->info; + int ret; + + DBG("%s", ovl->name); + DBG("%dx%d -> %dx%d (%d)", info->width, info->height, info->out_width, + info->out_height, info->screen_width); + DBG("%d,%d %08x %08x", info->pos_x, info->pos_y, + info->paddr, info->p_uv_addr); + + /* NOTE: do we want to do this at all here, or just wait + * for dpms(ON) since other CRTC's may not have their mode + * set yet, so fb dimensions may still change.. + */ + ret = ovl->set_overlay_info(ovl, info); + if (ret) { + dev_err(dev->dev, "could not set overlay info\n"); + return ret; + } + + mutex_lock(&omap_plane->unpin_mutex); + omap_plane->num_unpins += omap_plane->pending_num_unpins; + omap_plane->pending_num_unpins = 0; + mutex_unlock(&omap_plane->unpin_mutex); + + /* our encoder doesn't necessarily get a commit() after this, in + * particular in the dpms() and mode_set_base() cases, so force the + * manager to update: + * + * could this be in the encoder somehow? + */ + if (ovl->manager) { + ret = ovl->manager->apply(ovl->manager); + if (ret) { + dev_err(dev->dev, "could not apply settings\n"); + return ret; + } + + /* + * NOTE: really this should be atomic w/ mgr->apply() but + * omapdss does not expose such an API + */ + if (omap_plane->num_unpins > 0) + install_irq(plane); + + } else { + struct omap_drm_private *priv = dev->dev_private; + queue_work(priv->wq, &omap_plane->work); + } + + + if (ovl->is_enabled(ovl)) { + omap_framebuffer_flush(plane->fb, info->pos_x, info->pos_y, + info->out_width, info->out_height); + } + + return 0; +} + +/* when CRTC that we are attached to has potentially changed, this checks + * if we are attached to proper manager, and if necessary updates. + */ +static void update_manager(struct drm_plane *plane) +{ + struct omap_drm_private *priv = plane->dev->dev_private; + struct omap_plane *omap_plane = to_omap_plane(plane); + struct omap_overlay *ovl = omap_plane->ovl; + struct omap_overlay_manager *mgr = NULL; + int i; + + if (plane->crtc) { + for (i = 0; i < priv->num_encoders; i++) { + struct drm_encoder *encoder = priv->encoders[i]; + if (encoder->crtc == plane->crtc) { + mgr = omap_encoder_get_manager(encoder); + break; + } + } + } + + if (ovl->manager != mgr) { + bool enabled = ovl->is_enabled(ovl); + + /* don't switch things around with enabled overlays: */ + if (enabled) + omap_plane_dpms(plane, DRM_MODE_DPMS_OFF); + + if (ovl->manager) { + DBG("disconnecting %s from %s", ovl->name, + ovl->manager->name); + ovl->unset_manager(ovl); + } + + if (mgr) { + DBG("connecting %s to %s", ovl->name, mgr->name); + ovl->set_manager(ovl, mgr); + } + + if (enabled && mgr) + omap_plane_dpms(plane, DRM_MODE_DPMS_ON); + } +} + static void unpin(void *arg, struct drm_gem_object *bo) { struct drm_plane *plane = arg; @@ -72,6 +244,7 @@ static void unpin(void *arg, struct drm_gem_object *bo) if (kfifo_put(&omap_plane->unpin_fifo, (const struct drm_gem_object **)&bo)) { + omap_plane->pending_num_unpins++; /* also hold a ref so it isn't free'd while pinned */ drm_gem_object_reference(bo); } else { @@ -91,19 +264,13 @@ static int update_pin(struct drm_plane *plane, struct drm_framebuffer *fb) DBG("%p -> %p", pinned_fb, fb); - if (fb) - drm_framebuffer_reference(fb); - + mutex_lock(&omap_plane->unpin_mutex); ret = omap_framebuffer_replace(pinned_fb, fb, plane, unpin); - - if (pinned_fb) - drm_framebuffer_unreference(pinned_fb); + mutex_unlock(&omap_plane->unpin_mutex); if (ret) { dev_err(plane->dev->dev, "could not swap %p -> %p\n", omap_plane->pinned_fb, fb); - if (fb) - drm_framebuffer_unreference(fb); omap_plane->pinned_fb = NULL; return ret; } @@ -114,90 +281,31 @@ static int update_pin(struct drm_plane *plane, struct drm_framebuffer *fb) return 0; } -static void omap_plane_pre_apply(struct omap_drm_apply *apply) +/* update parameters that are dependent on the framebuffer dimensions and + * position within the fb that this plane scans out from. This is called + * when framebuffer or x,y base may have changed. + */ +static void update_scanout(struct drm_plane *plane) { - struct omap_plane *omap_plane = - container_of(apply, struct omap_plane, apply); - struct omap_drm_window *win = &omap_plane->win; - struct drm_plane *plane = &omap_plane->base; - struct drm_device *dev = plane->dev; + struct omap_plane *omap_plane = to_omap_plane(plane); struct omap_overlay_info *info = &omap_plane->info; - struct drm_crtc *crtc = plane->crtc; - enum omap_channel channel; - bool enabled = omap_plane->enabled && crtc; - bool ilace, replication; + struct omap_drm_window *win = &omap_plane->win; int ret; - DBG("%s, enabled=%d", omap_plane->name, enabled); - - /* if fb has changed, pin new fb: */ - update_pin(plane, enabled ? plane->fb : NULL); - - if (!enabled) { - dispc_ovl_enable(omap_plane->id, false); + ret = update_pin(plane, plane->fb); + if (ret) { + dev_err(plane->dev->dev, + "could not pin fb: %d\n", ret); + omap_plane_dpms(plane, DRM_MODE_DPMS_OFF); return; } - channel = omap_crtc_channel(crtc); - - /* update scanout: */ omap_framebuffer_update_scanout(plane->fb, win, info); - DBG("%dx%d -> %dx%d (%d)", info->width, info->height, - info->out_width, info->out_height, + DBG("%s: %d,%d: %08x %08x (%d)", omap_plane->ovl->name, + win->src_x, win->src_y, + (u32)info->paddr, (u32)info->p_uv_addr, info->screen_width); - DBG("%d,%d %08x %08x", info->pos_x, info->pos_y, - info->paddr, info->p_uv_addr); - - /* TODO: */ - ilace = false; - replication = false; - - /* and finally, update omapdss: */ - ret = dispc_ovl_setup(omap_plane->id, info, - replication, omap_crtc_timings(crtc), false); - if (ret) { - dev_err(dev->dev, "dispc_ovl_setup failed: %d\n", ret); - return; - } - - dispc_ovl_enable(omap_plane->id, true); - dispc_ovl_set_channel_out(omap_plane->id, channel); -} - -static void omap_plane_post_apply(struct omap_drm_apply *apply) -{ - struct omap_plane *omap_plane = - container_of(apply, struct omap_plane, apply); - struct drm_plane *plane = &omap_plane->base; - struct omap_overlay_info *info = &omap_plane->info; - struct drm_gem_object *bo = NULL; - struct callback cb; - - cb = omap_plane->apply_done_cb; - omap_plane->apply_done_cb.fxn = NULL; - - while (kfifo_get(&omap_plane->unpin_fifo, &bo)) { - omap_gem_put_paddr(bo); - drm_gem_object_unreference_unlocked(bo); - } - - if (cb.fxn) - cb.fxn(cb.arg); - - if (omap_plane->enabled) { - omap_framebuffer_flush(plane->fb, info->pos_x, info->pos_y, - info->out_width, info->out_height); - } -} - -static int apply(struct drm_plane *plane) -{ - if (plane->crtc) { - struct omap_plane *omap_plane = to_omap_plane(plane); - return omap_crtc_apply(plane->crtc, &omap_plane->apply); - } - return 0; } int omap_plane_mode_set(struct drm_plane *plane, @@ -205,8 +313,7 @@ int omap_plane_mode_set(struct drm_plane *plane, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h, - void (*fxn)(void *), void *arg) + uint32_t src_w, uint32_t src_h) { struct omap_plane *omap_plane = to_omap_plane(plane); struct omap_drm_window *win = &omap_plane->win; @@ -222,20 +329,17 @@ int omap_plane_mode_set(struct drm_plane *plane, win->src_w = src_w >> 16; win->src_h = src_h >> 16; - if (fxn) { - /* omap_crtc should ensure that a new page flip - * isn't permitted while there is one pending: - */ - BUG_ON(omap_plane->apply_done_cb.fxn); - - omap_plane->apply_done_cb.fxn = fxn; - omap_plane->apply_done_cb.arg = arg; - } - + /* note: this is done after this fxn returns.. but if we need + * to do a commit/update_scanout, etc before this returns we + * need the current value. + */ plane->fb = fb; plane->crtc = crtc; - return apply(plane); + update_scanout(plane); + update_manager(plane); + + return 0; } static int omap_plane_update(struct drm_plane *plane, @@ -245,12 +349,9 @@ static int omap_plane_update(struct drm_plane *plane, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h) { - struct omap_plane *omap_plane = to_omap_plane(plane); - omap_plane->enabled = true; - return omap_plane_mode_set(plane, crtc, fb, - crtc_x, crtc_y, crtc_w, crtc_h, - src_x, src_y, src_w, src_h, - NULL, NULL); + omap_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h, + src_x, src_y, src_w, src_h); + return omap_plane_dpms(plane, DRM_MODE_DPMS_ON); } static int omap_plane_disable(struct drm_plane *plane) @@ -263,32 +364,48 @@ static int omap_plane_disable(struct drm_plane *plane) static void omap_plane_destroy(struct drm_plane *plane) { struct omap_plane *omap_plane = to_omap_plane(plane); - - DBG("%s", omap_plane->name); - - omap_irq_unregister(plane->dev, &omap_plane->error_irq); - + DBG("%s", omap_plane->ovl->name); omap_plane_disable(plane); drm_plane_cleanup(plane); - - WARN_ON(!kfifo_is_empty(&omap_plane->unpin_fifo)); + WARN_ON(omap_plane->pending_num_unpins + omap_plane->num_unpins > 0); kfifo_free(&omap_plane->unpin_fifo); - kfree(omap_plane); } int omap_plane_dpms(struct drm_plane *plane, int mode) { struct omap_plane *omap_plane = to_omap_plane(plane); - bool enabled = (mode == DRM_MODE_DPMS_ON); - int ret = 0; + struct omap_overlay *ovl = omap_plane->ovl; + int r; - if (enabled != omap_plane->enabled) { - omap_plane->enabled = enabled; - ret = apply(plane); + DBG("%s: %d", omap_plane->ovl->name, mode); + + if (mode == DRM_MODE_DPMS_ON) { + update_scanout(plane); + r = commit(plane); + if (!r) + r = ovl->enable(ovl); + } else { + struct omap_drm_private *priv = plane->dev->dev_private; + r = ovl->disable(ovl); + update_pin(plane, NULL); + queue_work(priv->wq, &omap_plane->work); } - return ret; + return r; +} + +void omap_plane_on_endwin(struct drm_plane *plane, + void (*fxn)(void *), void *arg) +{ + struct omap_plane *omap_plane = to_omap_plane(plane); + + mutex_lock(&omap_plane->unpin_mutex); + omap_plane->endwin.fxn = fxn; + omap_plane->endwin.arg = arg; + mutex_unlock(&omap_plane->unpin_mutex); + + install_irq(plane); } /* helper to install properties which are common to planes and crtcs */ @@ -337,13 +454,25 @@ int omap_plane_set_property(struct drm_plane *plane, int ret = -EINVAL; if (property == priv->rotation_prop) { - DBG("%s: rotation: %02x", omap_plane->name, (uint32_t)val); + struct omap_overlay *ovl = omap_plane->ovl; + + DBG("%s: rotation: %02x", ovl->name, (uint32_t)val); omap_plane->win.rotation = val; - ret = apply(plane); + + if (ovl->is_enabled(ovl)) + ret = omap_plane_dpms(plane, DRM_MODE_DPMS_ON); + else + ret = 0; } else if (property == priv->zorder_prop) { - DBG("%s: zorder: %02x", omap_plane->name, (uint32_t)val); + struct omap_overlay *ovl = omap_plane->ovl; + + DBG("%s: zorder: %d", ovl->name, (uint32_t)val); omap_plane->info.zorder = val; - ret = apply(plane); + + if (ovl->is_enabled(ovl)) + ret = omap_plane_dpms(plane, DRM_MODE_DPMS_ON); + else + ret = 0; } return ret; @@ -356,38 +485,20 @@ static const struct drm_plane_funcs omap_plane_funcs = { .set_property = omap_plane_set_property, }; -static void omap_plane_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus) -{ - struct omap_plane *omap_plane = - container_of(irq, struct omap_plane, error_irq); - DRM_ERROR("%s: errors: %08x\n", omap_plane->name, irqstatus); -} - -static const char *plane_names[] = { - [OMAP_DSS_GFX] = "gfx", - [OMAP_DSS_VIDEO1] = "vid1", - [OMAP_DSS_VIDEO2] = "vid2", - [OMAP_DSS_VIDEO3] = "vid3", -}; - -static const uint32_t error_irqs[] = { - [OMAP_DSS_GFX] = DISPC_IRQ_GFX_FIFO_UNDERFLOW, - [OMAP_DSS_VIDEO1] = DISPC_IRQ_VID1_FIFO_UNDERFLOW, - [OMAP_DSS_VIDEO2] = DISPC_IRQ_VID2_FIFO_UNDERFLOW, - [OMAP_DSS_VIDEO3] = DISPC_IRQ_VID3_FIFO_UNDERFLOW, -}; - /* initialize plane */ struct drm_plane *omap_plane_init(struct drm_device *dev, - int id, bool private_plane) + struct omap_overlay *ovl, unsigned int possible_crtcs, + bool priv) { - struct omap_drm_private *priv = dev->dev_private; struct drm_plane *plane = NULL; struct omap_plane *omap_plane; - struct omap_overlay_info *info; int ret; - DBG("%s: priv=%d", plane_names[id], private_plane); + DBG("%s: possible_crtcs=%08x, priv=%d", ovl->name, + possible_crtcs, priv); + + /* friendly reminder to update table for future hw: */ + WARN_ON(ovl->id >= ARRAY_SIZE(id2irq)); omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL); if (!omap_plane) { @@ -395,50 +506,47 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, goto fail; } + mutex_init(&omap_plane->unpin_mutex); + ret = kfifo_alloc(&omap_plane->unpin_fifo, 16, GFP_KERNEL); if (ret) { dev_err(dev->dev, "could not allocate unpin FIFO\n"); goto fail; } + INIT_WORK(&omap_plane->work, unpin_worker); + omap_plane->nformats = omap_framebuffer_get_formats( omap_plane->formats, ARRAY_SIZE(omap_plane->formats), - dss_feat_get_supported_color_modes(id)); - omap_plane->id = id; - omap_plane->name = plane_names[id]; - + ovl->supported_modes); + omap_plane->ovl = ovl; plane = &omap_plane->base; - omap_plane->apply.pre_apply = omap_plane_pre_apply; - omap_plane->apply.post_apply = omap_plane_post_apply; - - omap_plane->error_irq.irqmask = error_irqs[id]; - omap_plane->error_irq.irq = omap_plane_error_irq; - omap_irq_register(dev, &omap_plane->error_irq); - - drm_plane_init(dev, plane, (1 << priv->num_crtcs) - 1, &omap_plane_funcs, - omap_plane->formats, omap_plane->nformats, private_plane); + drm_plane_init(dev, plane, possible_crtcs, &omap_plane_funcs, + omap_plane->formats, omap_plane->nformats, priv); omap_plane_install_properties(plane, &plane->base); /* get our starting configuration, set defaults for parameters * we don't currently use, etc: */ - info = &omap_plane->info; - info->rotation_type = OMAP_DSS_ROT_DMA; - info->rotation = OMAP_DSS_ROT_0; - info->global_alpha = 0xff; - info->mirror = 0; + ovl->get_overlay_info(ovl, &omap_plane->info); + omap_plane->info.rotation_type = OMAP_DSS_ROT_DMA; + omap_plane->info.rotation = OMAP_DSS_ROT_0; + omap_plane->info.global_alpha = 0xff; + omap_plane->info.mirror = 0; /* Set defaults depending on whether we are a CRTC or overlay * layer. * TODO add ioctl to give userspace an API to change this.. this * will come in a subsequent patch. */ - if (private_plane) + if (priv) omap_plane->info.zorder = 0; else - omap_plane->info.zorder = id; + omap_plane->info.zorder = ovl->id; + + update_manager(plane); return plane; diff --git a/trunk/drivers/staging/rtl8187se/r8180_core.c b/trunk/drivers/staging/rtl8187se/r8180_core.c index d10d75e8a33f..ae38475854b5 100644 --- a/trunk/drivers/staging/rtl8187se/r8180_core.c +++ b/trunk/drivers/staging/rtl8187se/r8180_core.c @@ -937,8 +937,7 @@ short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count) dma_tmp = pci_map_single(pdev, buf, bufsize * sizeof(u8), PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(pdev, dma_tmp)) - return -1; + if (-1 == buffer_add(&(priv->rxbuffer), buf, dma_tmp, &(priv->rxbufferhead))) { DMESGE("Unable to allocate mem RX buf"); diff --git a/trunk/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/trunk/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index a9d78e9651c6..808aab6fa5ef 100644 --- a/trunk/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/trunk/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -1183,8 +1183,6 @@ void rtl8192_tx_fill_desc(struct net_device *dev, struct tx_desc *pdesc, pTxFwInfo->TxRate, cb_desc); - if (pci_dma_mapping_error(priv->pdev, mapping)) - RT_TRACE(COMP_ERR, "DMA Mapping error\n");; if (cb_desc->bAMPDUEnable) { pTxFwInfo->AllowAggregation = 1; pTxFwInfo->RxMF = cb_desc->ampdu_factor; @@ -1282,8 +1280,6 @@ void rtl8192_tx_fill_cmd_desc(struct net_device *dev, dma_addr_t mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(priv->pdev, mapping)) - RT_TRACE(COMP_ERR, "DMA Mapping error\n");; memset(entry, 0, 12); entry->LINIP = cb_desc->bLastIniPkt; entry->FirstSeg = 1; diff --git a/trunk/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/trunk/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 4ebf99b30975..1a70f324552f 100644 --- a/trunk/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/trunk/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -2104,10 +2104,7 @@ static short rtl8192_alloc_rx_desc_ring(struct net_device *dev) skb_tail_pointer_rsl(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(priv->pdev, *mapping)) { - dev_kfree_skb_any(skb); - return -1; - } + entry->BufferAddress = cpu_to_le32(*mapping); entry->Length = priv->rxbuffersize; @@ -2400,11 +2397,7 @@ static void rtl8192_rx_normal(struct net_device *dev) skb_tail_pointer_rsl(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(priv->pdev, - *((dma_addr_t *)skb->cb))) { - dev_kfree_skb_any(skb); - return; - } + } done: pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb)); diff --git a/trunk/drivers/staging/rtl8712/usb_intf.c b/trunk/drivers/staging/rtl8712/usb_intf.c index a96cd06d69dd..6b73843e580a 100644 --- a/trunk/drivers/staging/rtl8712/usb_intf.c +++ b/trunk/drivers/staging/rtl8712/usb_intf.c @@ -63,8 +63,6 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = { {USB_DEVICE(0x0B05, 0x1791)}, /* 11n mode disable */ /* Belkin */ {USB_DEVICE(0x050D, 0x945A)}, - /* ISY IWL - Belkin clone */ - {USB_DEVICE(0x050D, 0x11F1)}, /* Corega */ {USB_DEVICE(0x07AA, 0x0047)}, /* D-Link */ diff --git a/trunk/drivers/staging/sb105x/Kconfig b/trunk/drivers/staging/sb105x/Kconfig index 1facad625554..ac87c5e38dee 100644 --- a/trunk/drivers/staging/sb105x/Kconfig +++ b/trunk/drivers/staging/sb105x/Kconfig @@ -2,7 +2,6 @@ config SB105X tristate "SystemBase PCI Multiport UART" select SERIAL_CORE depends on PCI - depends on X86 help A driver for the SystemBase Multi-2/PCI serial card diff --git a/trunk/drivers/staging/sb105x/sb_pci_mp.c b/trunk/drivers/staging/sb105x/sb_pci_mp.c index 131afd0c460c..edb2a85b9d52 100644 --- a/trunk/drivers/staging/sb105x/sb_pci_mp.c +++ b/trunk/drivers/staging/sb105x/sb_pci_mp.c @@ -3054,7 +3054,6 @@ static int init_mp_dev(struct pci_dev *pcidev, mppcibrd_t brd) sbdev->nr_ports = ((portnum_hex/16)*10) + (portnum_hex % 16); } break; -#ifdef CONFIG_PARPORT case PCI_DEVICE_ID_MP2S1P : sbdev->nr_ports = 2; @@ -3074,7 +3073,6 @@ static int init_mp_dev(struct pci_dev *pcidev, mppcibrd_t brd) /* add PC compatible parallel port */ parport_pc_probe_port(pcidev->resource[2].start, pcidev->resource[3].start, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &pcidev->dev, 0); break; -#endif } ret = request_region(sbdev->uart_access_addr, (8*sbdev->nr_ports), sbdev->name); diff --git a/trunk/drivers/staging/speakup/synth.c b/trunk/drivers/staging/speakup/synth.c index 7616f058a00b..df9533798095 100644 --- a/trunk/drivers/staging/speakup/synth.c +++ b/trunk/drivers/staging/speakup/synth.c @@ -342,7 +342,7 @@ int synth_init(char *synth_name) mutex_lock(&spk_mutex); /* First, check if we already have it loaded. */ - for (i = 0; i < MAXSYNTHS && synths[i] != NULL; i++) + for (i = 0; synths[i] != NULL && i < MAXSYNTHS; i++) if (strcmp(synths[i]->name, synth_name) == 0) synth = synths[i]; @@ -423,7 +423,7 @@ int synth_add(struct spk_synth *in_synth) int i; int status = 0; mutex_lock(&spk_mutex); - for (i = 0; i < MAXSYNTHS && synths[i] != NULL; i++) + for (i = 0; synths[i] != NULL && i < MAXSYNTHS; i++) /* synth_remove() is responsible for rotating the array down */ if (in_synth == synths[i]) { mutex_unlock(&spk_mutex); diff --git a/trunk/drivers/staging/tidspbridge/core/_tiomap.h b/trunk/drivers/staging/tidspbridge/core/_tiomap.h index b783bfa59b1c..543a127c7d4d 100644 --- a/trunk/drivers/staging/tidspbridge/core/_tiomap.h +++ b/trunk/drivers/staging/tidspbridge/core/_tiomap.h @@ -31,7 +31,7 @@ * driver should read or write to PRM/CM registers directly; they * should rely on OMAP core code to do this. */ -#include +#include #include #include #include diff --git a/trunk/drivers/staging/tidspbridge/core/dsp-clock.c b/trunk/drivers/staging/tidspbridge/core/dsp-clock.c index 2f084e181d39..b647207928b1 100644 --- a/trunk/drivers/staging/tidspbridge/core/dsp-clock.c +++ b/trunk/drivers/staging/tidspbridge/core/dsp-clock.c @@ -121,13 +121,9 @@ void dsp_clk_exit(void) for (i = 0; i < DM_TIMER_CLOCKS; i++) omap_dm_timer_free(timer[i]); - clk_unprepare(iva2_clk); clk_put(iva2_clk); - clk_unprepare(ssi.sst_fck); clk_put(ssi.sst_fck); - clk_unprepare(ssi.ssr_fck); clk_put(ssi.ssr_fck); - clk_unprepare(ssi.ick); clk_put(ssi.ick); } @@ -149,21 +145,14 @@ void dsp_clk_init(void) iva2_clk = clk_get(&dspbridge_device.dev, "iva2_ck"); if (IS_ERR(iva2_clk)) dev_err(bridge, "failed to get iva2 clock %p\n", iva2_clk); - else - clk_prepare(iva2_clk); ssi.sst_fck = clk_get(&dspbridge_device.dev, "ssi_sst_fck"); ssi.ssr_fck = clk_get(&dspbridge_device.dev, "ssi_ssr_fck"); ssi.ick = clk_get(&dspbridge_device.dev, "ssi_ick"); - if (IS_ERR(ssi.sst_fck) || IS_ERR(ssi.ssr_fck) || IS_ERR(ssi.ick)) { + if (IS_ERR(ssi.sst_fck) || IS_ERR(ssi.ssr_fck) || IS_ERR(ssi.ick)) dev_err(bridge, "failed to get ssi: sst %p, ssr %p, ick %p\n", ssi.sst_fck, ssi.ssr_fck, ssi.ick); - } else { - clk_prepare(ssi.sst_fck); - clk_prepare(ssi.ssr_fck); - clk_prepare(ssi.ick); - } } /** diff --git a/trunk/drivers/staging/tidspbridge/core/wdt.c b/trunk/drivers/staging/tidspbridge/core/wdt.c index 7ff0e6c98039..1dce36fb828f 100644 --- a/trunk/drivers/staging/tidspbridge/core/wdt.c +++ b/trunk/drivers/staging/tidspbridge/core/wdt.c @@ -63,15 +63,11 @@ int dsp_wdt_init(void) dsp_wdt.fclk = clk_get(NULL, "wdt3_fck"); if (!IS_ERR(dsp_wdt.fclk)) { - clk_prepare(dsp_wdt.fclk); - dsp_wdt.iclk = clk_get(NULL, "wdt3_ick"); if (IS_ERR(dsp_wdt.iclk)) { clk_put(dsp_wdt.fclk); dsp_wdt.fclk = NULL; ret = -EFAULT; - } else { - clk_prepare(dsp_wdt.iclk); } } else ret = -EFAULT; @@ -99,14 +95,10 @@ void dsp_wdt_exit(void) free_irq(INT_34XX_WDT3_IRQ, &dsp_wdt); tasklet_kill(&dsp_wdt.wdt3_tasklet); - if (dsp_wdt.fclk) { - clk_unprepare(dsp_wdt.fclk); + if (dsp_wdt.fclk) clk_put(dsp_wdt.fclk); - } - if (dsp_wdt.iclk) { - clk_unprepare(dsp_wdt.iclk); + if (dsp_wdt.iclk) clk_put(dsp_wdt.iclk); - } dsp_wdt.fclk = NULL; dsp_wdt.iclk = NULL; diff --git a/trunk/drivers/staging/vme/devices/vme_pio2_core.c b/trunk/drivers/staging/vme/devices/vme_pio2_core.c index bf73ba26e88a..0331178ca3b3 100644 --- a/trunk/drivers/staging/vme/devices/vme_pio2_core.c +++ b/trunk/drivers/staging/vme/devices/vme_pio2_core.c @@ -162,9 +162,11 @@ static struct vme_driver pio2_driver = { static int __init pio2_init(void) { + int retval = 0; + if (bus_num == 0) { pr_err("No cards, skipping registration\n"); - return -ENODEV; + goto err_nocard; } if (bus_num > PIO2_CARDS_MAX) { @@ -174,7 +176,15 @@ static int __init pio2_init(void) } /* Register the PIO2 driver */ - return vme_register_driver(&pio2_driver, bus_num); + retval = vme_register_driver(&pio2_driver, bus_num); + if (retval != 0) + goto err_reg; + + return retval; + +err_reg: +err_nocard: + return retval; } static int pio2_match(struct vme_dev *vdev) diff --git a/trunk/drivers/staging/wlan-ng/cfg80211.c b/trunk/drivers/staging/wlan-ng/cfg80211.c index 1d31eab19d16..18c06a59c091 100644 --- a/trunk/drivers/staging/wlan-ng/cfg80211.c +++ b/trunk/drivers/staging/wlan-ng/cfg80211.c @@ -638,8 +638,8 @@ int prism2_leave_ibss(struct wiphy *wiphy, struct net_device *dev) } -int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, - enum nl80211_tx_power_setting type, int mbm) +int prism2_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type, + int mbm) { struct prism2_wiphy_private *priv = wiphy_priv(wiphy); wlandevice_t *wlandev = priv->wlandev; @@ -665,8 +665,7 @@ int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, return err; } -int prism2_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, - int *dbm) +int prism2_get_tx_power(struct wiphy *wiphy, int *dbm) { struct prism2_wiphy_private *priv = wiphy_priv(wiphy); wlandevice_t *wlandev = priv->wlandev; diff --git a/trunk/drivers/staging/zram/zram_drv.c b/trunk/drivers/staging/zram/zram_drv.c index f2a73bd739fb..fb4a7c94aed3 100644 --- a/trunk/drivers/staging/zram/zram_drv.c +++ b/trunk/drivers/staging/zram/zram_drv.c @@ -265,7 +265,7 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, int offset) { - int ret = 0; + int ret; size_t clen; unsigned long handle; struct page *page; @@ -286,8 +286,10 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, goto out; } ret = zram_decompress_page(zram, uncmem, index); - if (ret) + if (ret) { + kfree(uncmem); goto out; + } } /* @@ -300,18 +302,16 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, user_mem = kmap_atomic(page); - if (is_partial_io(bvec)) { + if (is_partial_io(bvec)) memcpy(uncmem + offset, user_mem + bvec->bv_offset, bvec->bv_len); - kunmap_atomic(user_mem); - user_mem = NULL; - } else { + else uncmem = user_mem; - } if (page_zero_filled(uncmem)) { - if (!is_partial_io(bvec)) - kunmap_atomic(user_mem); + kunmap_atomic(user_mem); + if (is_partial_io(bvec)) + kfree(uncmem); zram_stat_inc(&zram->stats.pages_zero); zram_set_flag(zram, index, ZRAM_ZERO); ret = 0; @@ -321,11 +321,9 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen, zram->compress_workmem); - if (!is_partial_io(bvec)) { - kunmap_atomic(user_mem); - user_mem = NULL; - uncmem = NULL; - } + kunmap_atomic(user_mem); + if (is_partial_io(bvec)) + kfree(uncmem); if (unlikely(ret != LZO_E_OK)) { pr_err("Compression failed! err=%d\n", ret); @@ -334,10 +332,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, if (unlikely(clen > max_zpage_size)) { zram_stat_inc(&zram->stats.bad_compress); + src = uncmem; clen = PAGE_SIZE; - src = NULL; - if (is_partial_io(bvec)) - src = uncmem; } handle = zs_malloc(zram->mem_pool, clen); @@ -349,11 +345,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, } cmem = zs_map_object(zram->mem_pool, handle, ZS_MM_WO); - if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) - src = kmap_atomic(page); memcpy(cmem, src, clen); - if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) - kunmap_atomic(src); zs_unmap_object(zram->mem_pool, handle); @@ -366,10 +358,9 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, if (clen <= PAGE_SIZE / 2) zram_stat_inc(&zram->stats.good_compress); -out: - if (is_partial_io(bvec)) - kfree(uncmem); + return 0; +out: if (ret) zram_stat64_inc(zram, &zram->stats.failed_writes); return ret; diff --git a/trunk/drivers/usb/Kconfig b/trunk/drivers/usb/Kconfig index 640ae6c6d2d2..4c90b510d016 100644 --- a/trunk/drivers/usb/Kconfig +++ b/trunk/drivers/usb/Kconfig @@ -37,7 +37,6 @@ config USB_ARCH_HAS_EHCI default y if ARCH_W90X900 default y if ARCH_AT91 default y if ARCH_MXC - default y if ARCH_MXS default y if ARCH_OMAP3 default y if ARCH_CNS3XXX default y if ARCH_VT8500 diff --git a/trunk/drivers/usb/chipidea/host.c b/trunk/drivers/usb/chipidea/host.c index 8e9d31277c43..caecad9213f5 100644 --- a/trunk/drivers/usb/chipidea/host.c +++ b/trunk/drivers/usb/chipidea/host.c @@ -70,9 +70,6 @@ static int host_start(struct ci13xxx *ci) else ci->hcd = hcd; - if (ci->platdata->flags & CI13XXX_DISABLE_STREAMING) - hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS); - return ret; } diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index 2d92cce260d7..8d809a811e16 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -1602,9 +1602,6 @@ static const struct usb_device_id acm_ids[] = { { USB_DEVICE(0x0572, 0x1340), /* Conexant CX93010-2x UCMxx */ .driver_info = NO_UNION_NORMAL, }, - { USB_DEVICE(0x05f9, 0x4002), /* PSC Scanning, Magellan 800i */ - .driver_info = NO_UNION_NORMAL, - }, { USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ }, diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index 957ed2c41482..a815fd2cc5e7 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -877,60 +877,6 @@ static int hub_hub_status(struct usb_hub *hub, return ret; } -static int hub_set_port_link_state(struct usb_hub *hub, int port1, - unsigned int link_status) -{ - return set_port_feature(hub->hdev, - port1 | (link_status << 3), - USB_PORT_FEAT_LINK_STATE); -} - -/* - * If USB 3.0 ports are placed into the Disabled state, they will no longer - * detect any device connects or disconnects. This is generally not what the - * USB core wants, since it expects a disabled port to produce a port status - * change event when a new device connects. - * - * Instead, set the link state to Disabled, wait for the link to settle into - * that state, clear any change bits, and then put the port into the RxDetect - * state. - */ -static int hub_usb3_port_disable(struct usb_hub *hub, int port1) -{ - int ret; - int total_time; - u16 portchange, portstatus; - - if (!hub_is_superspeed(hub->hdev)) - return -EINVAL; - - ret = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_SS_DISABLED); - if (ret) { - dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n", - port1, ret); - return ret; - } - - /* Wait for the link to enter the disabled state. */ - for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) { - ret = hub_port_status(hub, port1, &portstatus, &portchange); - if (ret < 0) - return ret; - - if ((portstatus & USB_PORT_STAT_LINK_STATE) == - USB_SS_PORT_LS_SS_DISABLED) - break; - if (total_time >= HUB_DEBOUNCE_TIMEOUT) - break; - msleep(HUB_DEBOUNCE_STEP); - } - if (total_time >= HUB_DEBOUNCE_TIMEOUT) - dev_warn(hub->intfdev, "Could not disable port %d after %d ms\n", - port1, total_time); - - return hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_RX_DETECT); -} - static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) { struct usb_device *hdev = hub->hdev; @@ -939,13 +885,8 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) if (hub->ports[port1 - 1]->child && set_state) usb_set_device_state(hub->ports[port1 - 1]->child, USB_STATE_NOTATTACHED); - if (!hub->error) { - if (hub_is_superspeed(hub->hdev)) - ret = hub_usb3_port_disable(hub, port1); - else - ret = clear_port_feature(hdev, port1, - USB_PORT_FEAT_ENABLE); - } + if (!hub->error && !hub_is_superspeed(hub->hdev)) + ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE); if (ret) dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n", port1, ret); @@ -2499,7 +2440,7 @@ static unsigned hub_is_wusb(struct usb_hub *hub) #define HUB_SHORT_RESET_TIME 10 #define HUB_BH_RESET_TIME 50 #define HUB_LONG_RESET_TIME 200 -#define HUB_RESET_TIMEOUT 800 +#define HUB_RESET_TIMEOUT 500 static int hub_port_reset(struct usb_hub *hub, int port1, struct usb_device *udev, unsigned int delay, bool warm); @@ -2534,10 +2475,6 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, if (ret < 0) return ret; - /* The port state is unknown until the reset completes. */ - if ((portstatus & USB_PORT_STAT_RESET)) - goto delay; - /* * Some buggy devices require a warm reset to be issued even * when the port appears not to be connected. @@ -2583,7 +2520,11 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, if ((portchange & USB_PORT_STAT_C_CONNECTION)) return -ENOTCONN; - if ((portstatus & USB_PORT_STAT_ENABLE)) { + /* if we`ve finished resetting, then break out of + * the loop + */ + if (!(portstatus & USB_PORT_STAT_RESET) && + (portstatus & USB_PORT_STAT_ENABLE)) { if (hub_is_wusb(hub)) udev->speed = USB_SPEED_WIRELESS; else if (hub_is_superspeed(hub->hdev)) @@ -2597,15 +2538,10 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, return 0; } } else { - if (!(portstatus & USB_PORT_STAT_CONNECTION) || - hub_port_warm_reset_required(hub, - portstatus)) - return -ENOTCONN; - - return 0; + if (portchange & USB_PORT_STAT_C_BH_RESET) + return 0; } -delay: /* switch to the long delay after two short delay failures */ if (delay_time >= 2 * HUB_SHORT_RESET_TIME) delay = HUB_LONG_RESET_TIME; @@ -2629,11 +2565,14 @@ static void hub_port_finish_reset(struct usb_hub *hub, int port1, msleep(10 + 40); update_devnum(udev, 0); hcd = bus_to_hcd(udev->bus); - /* The xHC may think the device is already reset, - * so ignore the status. - */ - if (hcd->driver->reset_device) - hcd->driver->reset_device(hcd, udev); + if (hcd->driver->reset_device) { + *status = hcd->driver->reset_device(hcd, udev); + if (*status < 0) { + dev_err(&udev->dev, "Cannot reset " + "HCD device state\n"); + break; + } + } } /* FALL THROUGH */ case -ENOTCONN: @@ -2641,16 +2580,16 @@ static void hub_port_finish_reset(struct usb_hub *hub, int port1, clear_port_feature(hub->hdev, port1, USB_PORT_FEAT_C_RESET); /* FIXME need disconnect() for NOTATTACHED device */ - if (hub_is_superspeed(hub->hdev)) { + if (warm) { clear_port_feature(hub->hdev, port1, USB_PORT_FEAT_C_BH_PORT_RESET); clear_port_feature(hub->hdev, port1, USB_PORT_FEAT_C_PORT_LINK_STATE); - } - if (!warm) + } else { usb_set_device_state(udev, *status ? USB_STATE_NOTATTACHED : USB_STATE_DEFAULT); + } break; } } @@ -3000,7 +2939,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) static int finish_port_resume(struct usb_device *udev) { int status = 0; - u16 devstatus = 0; + u16 devstatus; /* caller owns the udev device lock */ dev_dbg(&udev->dev, "%s\n", @@ -3045,13 +2984,7 @@ static int finish_port_resume(struct usb_device *udev) if (status) { dev_dbg(&udev->dev, "gone after usb resume? status %d\n", status); - /* - * There are a few quirky devices which violate the standard - * by claiming to have remote wakeup enabled after a reset, - * which crash if the feature is cleared, hence check for - * udev->reset_resume - */ - } else if (udev->actconfig && !udev->reset_resume) { + } else if (udev->actconfig) { le16_to_cpus(&devstatus); if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { status = usb_control_msg(udev, @@ -4705,14 +4638,9 @@ static void hub_events(void) * SS.Inactive state. */ if (hub_port_warm_reset_required(hub, portstatus)) { - int status; - dev_dbg(hub_dev, "warm reset port %d\n", i); - status = hub_port_reset(hub, i, NULL, + hub_port_reset(hub, i, NULL, HUB_BH_RESET_TIME, true); - if (status < 0) - hub_port_disable(hub, i, 1); - connect_change = 0; } if (connect_change) diff --git a/trunk/drivers/usb/core/quirks.c b/trunk/drivers/usb/core/quirks.c index 3113c1d71442..fdefd9c7f7af 100644 --- a/trunk/drivers/usb/core/quirks.c +++ b/trunk/drivers/usb/core/quirks.c @@ -43,9 +43,6 @@ static const struct usb_device_id usb_quirk_list[] = { /* Creative SB Audigy 2 NX */ { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Microsoft LifeCam-VX700 v2.0 */ - { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Quickcam Fusion */ { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME }, diff --git a/trunk/drivers/usb/dwc3/debugfs.c b/trunk/drivers/usb/dwc3/debugfs.c index 5945aadaa1c9..92604b4f9712 100644 --- a/trunk/drivers/usb/dwc3/debugfs.c +++ b/trunk/drivers/usb/dwc3/debugfs.c @@ -56,7 +56,7 @@ #define dump_register(nm) \ { \ .name = __stringify(nm), \ - .offset = DWC3_ ##nm - DWC3_GLOBALS_REGS_START, \ + .offset = DWC3_ ##nm, \ } static const struct debugfs_reg32 dwc3_regs[] = { diff --git a/trunk/drivers/usb/gadget/amd5536udc.c b/trunk/drivers/usb/gadget/amd5536udc.c index d9f6b9372491..fc0ec5e0d58e 100644 --- a/trunk/drivers/usb/gadget/amd5536udc.c +++ b/trunk/drivers/usb/gadget/amd5536udc.c @@ -3231,7 +3231,7 @@ static int udc_pci_probe( } if (!pdev->irq) { - dev_err(&pdev->dev, "irq not set\n"); + dev_err(&dev->pdev->dev, "irq not set\n"); kfree(dev); dev = NULL; retval = -ENODEV; @@ -3250,7 +3250,7 @@ static int udc_pci_probe( dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR); if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) { - dev_dbg(&pdev->dev, "request_irq(%d) fail\n", pdev->irq); + dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq); kfree(dev); dev = NULL; retval = -EBUSY; diff --git a/trunk/drivers/usb/gadget/dummy_hcd.c b/trunk/drivers/usb/gadget/dummy_hcd.c index 8cf0c0f6fa1f..95d584dbed13 100644 --- a/trunk/drivers/usb/gadget/dummy_hcd.c +++ b/trunk/drivers/usb/gadget/dummy_hcd.c @@ -130,7 +130,10 @@ static const char ep0name[] = "ep0"; static const char *const ep_name[] = { ep0name, /* everyone has ep0 */ - /* act like a pxa250: fifteen fixed function endpoints */ + /* act like a net2280: high speed, six configurable endpoints */ + "ep-a", "ep-b", "ep-c", "ep-d", "ep-e", "ep-f", + + /* or like pxa250: fifteen fixed function endpoints */ "ep1in-bulk", "ep2out-bulk", "ep3in-iso", "ep4out-iso", "ep5in-int", "ep6in-bulk", "ep7out-bulk", "ep8in-iso", "ep9out-iso", "ep10in-int", "ep11in-bulk", "ep12out-bulk", "ep13in-iso", "ep14out-iso", @@ -138,10 +141,6 @@ static const char *const ep_name[] = { /* or like sa1100: two fixed function endpoints */ "ep1out-bulk", "ep2in-bulk", - - /* and now some generic EPs so we have enough in multi config */ - "ep3out", "ep4in", "ep5out", "ep6out", "ep7in", "ep8out", "ep9in", - "ep10out", "ep11out", "ep12in", "ep13out", "ep14in", "ep15out", }; #define DUMMY_ENDPOINTS ARRAY_SIZE(ep_name) diff --git a/trunk/drivers/usb/gadget/mv_udc_core.c b/trunk/drivers/usb/gadget/mv_udc_core.c index 6e8b1272ebce..379aac7b82fc 100644 --- a/trunk/drivers/usb/gadget/mv_udc_core.c +++ b/trunk/drivers/usb/gadget/mv_udc_core.c @@ -1012,7 +1012,7 @@ static void udc_clock_enable(struct mv_udc *udc) unsigned int i; for (i = 0; i < udc->clknum; i++) - clk_prepare_enable(udc->clk[i]); + clk_enable(udc->clk[i]); } static void udc_clock_disable(struct mv_udc *udc) @@ -1020,7 +1020,7 @@ static void udc_clock_disable(struct mv_udc *udc) unsigned int i; for (i = 0; i < udc->clknum; i++) - clk_disable_unprepare(udc->clk[i]); + clk_disable(udc->clk[i]); } static void udc_stop(struct mv_udc *udc) diff --git a/trunk/drivers/usb/gadget/s3c-hsotg.c b/trunk/drivers/usb/gadget/s3c-hsotg.c index 439c3f972f8c..141971d9051e 100644 --- a/trunk/drivers/usb/gadget/s3c-hsotg.c +++ b/trunk/drivers/usb/gadget/s3c-hsotg.c @@ -3477,11 +3477,12 @@ static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg) /** * s3c_hsotg_release - release callback for hsotg device * @dev: Device to for which release is called - * - * Nothing to do as the resource is allocated using devm_ API. */ static void s3c_hsotg_release(struct device *dev) { + struct s3c_hsotg *hsotg = dev_get_drvdata(dev); + + kfree(hsotg); } /** diff --git a/trunk/drivers/usb/gadget/tcm_usb_gadget.c b/trunk/drivers/usb/gadget/tcm_usb_gadget.c index 7cacd6ae818e..4f7f76f00c74 100644 --- a/trunk/drivers/usb/gadget/tcm_usb_gadget.c +++ b/trunk/drivers/usb/gadget/tcm_usb_gadget.c @@ -1794,10 +1794,9 @@ static int tcm_usbg_drop_nexus(struct usbg_tpg *tpg) tpg->tpg_nexus = NULL; kfree(tv_nexus); - ret = 0; out: mutex_unlock(&tpg->tpg_mutex); - return ret; + return 0; } static ssize_t tcm_usbg_tpg_store_nexus( diff --git a/trunk/drivers/usb/gadget/u_serial.c b/trunk/drivers/usb/gadget/u_serial.c index 598dcc1212f0..d0f95482f40e 100644 --- a/trunk/drivers/usb/gadget/u_serial.c +++ b/trunk/drivers/usb/gadget/u_serial.c @@ -887,7 +887,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) pr_debug("gs_close: ttyGS%d (%p,%p) done!\n", port->port_num, tty, file); - wake_up(&port->port.close_wait); + wake_up_interruptible(&port->port.close_wait); exit: spin_unlock_irq(&port->port_lock); } diff --git a/trunk/drivers/usb/host/ehci-fsl.c b/trunk/drivers/usb/host/ehci-fsl.c index d81d2fcbff18..fd9b5424b860 100644 --- a/trunk/drivers/usb/host/ehci-fsl.c +++ b/trunk/drivers/usb/host/ehci-fsl.c @@ -230,7 +230,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, switch (phy_mode) { case FSL_USB2_PHY_ULPI: - if (pdata->have_sysif_regs && pdata->controller_ver) { + if (pdata->controller_ver) { /* controller version 1.6 or above */ setbits32(non_ehci + FSL_SOC_USB_CTRL, ULPI_PHY_CLK_SEL); @@ -251,7 +251,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, portsc |= PORT_PTS_PTW; /* fall through */ case FSL_USB2_PHY_UTMI: - if (pdata->have_sysif_regs && pdata->controller_ver) { + if (pdata->controller_ver) { /* controller version 1.6 or above */ setbits32(non_ehci + FSL_SOC_USB_CTRL, UTMI_PHY_EN); mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI PHY CLK to @@ -267,8 +267,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, break; } - if (pdata->have_sysif_regs && pdata->controller_ver && - (phy_mode == FSL_USB2_PHY_ULPI)) { + if (pdata->controller_ver && (phy_mode == FSL_USB2_PHY_ULPI)) { /* check PHY_CLK_VALID to get phy clk valid */ if (!spin_event_timeout(in_be32(non_ehci + FSL_SOC_USB_CTRL) & PHY_CLK_VALID, FSL_USB_PHY_CLK_TIMEOUT, 0)) { @@ -279,7 +278,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); - if (phy_mode != FSL_USB2_PHY_ULPI && pdata->have_sysif_regs) + if (phy_mode != FSL_USB2_PHY_ULPI) setbits32(non_ehci + FSL_SOC_USB_CTRL, USB_CTRL_USB_EN); return 0; diff --git a/trunk/drivers/usb/host/ehci-mv.c b/trunk/drivers/usb/host/ehci-mv.c index 6c56297ea16b..f7bfc0b898b9 100644 --- a/trunk/drivers/usb/host/ehci-mv.c +++ b/trunk/drivers/usb/host/ehci-mv.c @@ -43,7 +43,7 @@ static void ehci_clock_enable(struct ehci_hcd_mv *ehci_mv) unsigned int i; for (i = 0; i < ehci_mv->clknum; i++) - clk_prepare_enable(ehci_mv->clk[i]); + clk_enable(ehci_mv->clk[i]); } static void ehci_clock_disable(struct ehci_hcd_mv *ehci_mv) @@ -51,7 +51,7 @@ static void ehci_clock_disable(struct ehci_hcd_mv *ehci_mv) unsigned int i; for (i = 0; i < ehci_mv->clknum; i++) - clk_disable_unprepare(ehci_mv->clk[i]); + clk_disable(ehci_mv->clk[i]); } static int mv_ehci_enable(struct ehci_hcd_mv *ehci_mv) diff --git a/trunk/drivers/usb/host/ehci-pci.c b/trunk/drivers/usb/host/ehci-pci.c index 170b9399e09f..dabb20494826 100644 --- a/trunk/drivers/usb/host/ehci-pci.c +++ b/trunk/drivers/usb/host/ehci-pci.c @@ -200,26 +200,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) break; } - /* optional debug port, normally in the first BAR */ - temp = pci_find_capability(pdev, PCI_CAP_ID_DBG); - if (temp) { - pci_read_config_dword(pdev, temp, &temp); - temp >>= 16; - if (((temp >> 13) & 7) == 1) { - u32 hcs_params = ehci_readl(ehci, - &ehci->caps->hcs_params); - - temp &= 0x1fff; - ehci->debug = hcd->regs + temp; - temp = ehci_readl(ehci, &ehci->debug->control); - ehci_info(ehci, "debug port %d%s\n", - HCS_DEBUG_PORT(hcs_params), - (temp & DBGP_ENABLED) ? " IN USE" : ""); - if (!(temp & DBGP_ENABLED)) - ehci->debug = NULL; - } - } - retval = ehci_setup(hcd); if (retval) return retval; @@ -248,6 +228,25 @@ static int ehci_pci_setup(struct usb_hcd *hcd) break; } + /* optional debug port, normally in the first BAR */ + temp = pci_find_capability(pdev, 0x0a); + if (temp) { + pci_read_config_dword(pdev, temp, &temp); + temp >>= 16; + if ((temp & (3 << 13)) == (1 << 13)) { + temp &= 0x1fff; + ehci->debug = hcd->regs + temp; + temp = ehci_readl(ehci, &ehci->debug->control); + ehci_info(ehci, "debug port %d%s\n", + HCS_DEBUG_PORT(ehci->hcs_params), + (temp & DBGP_ENABLED) + ? " IN USE" + : ""); + if (!(temp & DBGP_ENABLED)) + ehci->debug = NULL; + } + } + /* at least the Genesys GL880S needs fixup here */ temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); temp &= 0x0f; diff --git a/trunk/drivers/usb/host/fsl-mph-dr-of.c b/trunk/drivers/usb/host/fsl-mph-dr-of.c index 11e0b79ff9d5..5105127c1d4b 100644 --- a/trunk/drivers/usb/host/fsl-mph-dr-of.c +++ b/trunk/drivers/usb/host/fsl-mph-dr-of.c @@ -142,9 +142,6 @@ static int usb_get_ver_info(struct device_node *np) return ver; } - if (of_device_is_compatible(np, "fsl,mpc5121-usb2-dr")) - return FSL_USB_VER_OLD; - if (of_device_is_compatible(np, "fsl-usb2-mph")) { if (of_device_is_compatible(np, "fsl-usb2-mph-v1.6")) ver = FSL_USB_VER_1_6; diff --git a/trunk/drivers/usb/host/imx21-hcd.c b/trunk/drivers/usb/host/imx21-hcd.c index f0ebe8e7c58b..bd6a7447ccc9 100644 --- a/trunk/drivers/usb/host/imx21-hcd.c +++ b/trunk/drivers/usb/host/imx21-hcd.c @@ -58,7 +58,6 @@ #include #include #include -#include #include "imx21-hcd.h" diff --git a/trunk/drivers/usb/host/ohci-tmio.c b/trunk/drivers/usb/host/ohci-tmio.c index 5e3a6deb62b1..d370245a4ee2 100644 --- a/trunk/drivers/usb/host/ohci-tmio.c +++ b/trunk/drivers/usb/host/ohci-tmio.c @@ -128,8 +128,7 @@ static void tmio_start_hc(struct platform_device *dev) tmio_iowrite8(2, tmio->ccr + CCR_INTC); dev_info(&dev->dev, "revision %d @ 0x%08llx, irq %d\n", - tmio_ioread8(tmio->ccr + CCR_REVID), - (u64) hcd->rsrc_start, hcd->irq); + tmio_ioread8(tmio->ccr + CCR_REVID), hcd->rsrc_start, hcd->irq); } static int ohci_tmio_start(struct usb_hcd *hcd) diff --git a/trunk/drivers/usb/host/xhci-hub.c b/trunk/drivers/usb/host/xhci-hub.c index 68914429482f..a686cf4905bb 100644 --- a/trunk/drivers/usb/host/xhci-hub.c +++ b/trunk/drivers/usb/host/xhci-hub.c @@ -761,39 +761,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, break; case USB_PORT_FEAT_LINK_STATE: temp = xhci_readl(xhci, port_array[wIndex]); - - /* Disable port */ - if (link_state == USB_SS_PORT_LS_SS_DISABLED) { - xhci_dbg(xhci, "Disable port %d\n", wIndex); - temp = xhci_port_state_to_neutral(temp); - /* - * Clear all change bits, so that we get a new - * connection event. - */ - temp |= PORT_CSC | PORT_PEC | PORT_WRC | - PORT_OCC | PORT_RC | PORT_PLC | - PORT_CEC; - xhci_writel(xhci, temp | PORT_PE, - port_array[wIndex]); - temp = xhci_readl(xhci, port_array[wIndex]); - break; - } - - /* Put link in RxDetect (enable port) */ - if (link_state == USB_SS_PORT_LS_RX_DETECT) { - xhci_dbg(xhci, "Enable port %d\n", wIndex); - xhci_set_link_state(xhci, port_array, wIndex, - link_state); - temp = xhci_readl(xhci, port_array[wIndex]); - break; - } - /* Software should not attempt to set - * port link state above '3' (U3) and the port + * port link state above '5' (Rx.Detect) and the port * must be enabled. */ if ((temp & PORT_PE) == 0 || - (link_state > USB_SS_PORT_LS_U3)) { + (link_state > USB_SS_PORT_LS_RX_DETECT)) { xhci_warn(xhci, "Cannot set link state.\n"); goto error; } @@ -984,7 +957,6 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) int max_ports; __le32 __iomem **port_array; struct xhci_bus_state *bus_state; - bool reset_change = false; max_ports = xhci_get_ports(hcd, &port_array); bus_state = &xhci->bus_state[hcd_index(hcd)]; @@ -1016,12 +988,6 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) buf[(i + 1) / 8] |= 1 << (i + 1) % 8; status = 1; } - if ((temp & PORT_RC)) - reset_change = true; - } - if (!status && !reset_change) { - xhci_dbg(xhci, "%s: stopping port polling.\n", __func__); - clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); } spin_unlock_irqrestore(&xhci->lock, flags); return status ? retval : 0; diff --git a/trunk/drivers/usb/host/xhci-mem.c b/trunk/drivers/usb/host/xhci-mem.c index 35616ffbe3ae..fb51c7085ad0 100644 --- a/trunk/drivers/usb/host/xhci-mem.c +++ b/trunk/drivers/usb/host/xhci-mem.c @@ -1250,8 +1250,6 @@ static unsigned int xhci_microframes_to_exponent(struct usb_device *udev, static unsigned int xhci_parse_microframe_interval(struct usb_device *udev, struct usb_host_endpoint *ep) { - if (ep->desc.bInterval == 0) - return 0; return xhci_microframes_to_exponent(udev, ep, ep->desc.bInterval, 0, 15); } diff --git a/trunk/drivers/usb/host/xhci-ring.c b/trunk/drivers/usb/host/xhci-ring.c index 59fb5c677dbe..cbb44b7b9d65 100644 --- a/trunk/drivers/usb/host/xhci-ring.c +++ b/trunk/drivers/usb/host/xhci-ring.c @@ -1725,15 +1725,6 @@ static void handle_port_status(struct xhci_hcd *xhci, if (bogus_port_status) return; - /* - * xHCI port-status-change events occur when the "or" of all the - * status-change bits in the portsc register changes from 0 to 1. - * New status changes won't cause an event if any other change - * bits are still set. When an event occurs, switch over to - * polling to avoid losing status changes. - */ - xhci_dbg(xhci, "%s: starting port polling.\n", __func__); - set_bit(HCD_FLAG_POLL_RH, &hcd->flags); spin_unlock(&xhci->lock); /* Pass this up to the core */ usb_hcd_poll_rh_status(hcd); diff --git a/trunk/drivers/usb/host/xhci.c b/trunk/drivers/usb/host/xhci.c index f1f01a834ba7..5c72c431bab1 100644 --- a/trunk/drivers/usb/host/xhci.c +++ b/trunk/drivers/usb/host/xhci.c @@ -884,11 +884,6 @@ int xhci_suspend(struct xhci_hcd *xhci) xhci->shared_hcd->state != HC_STATE_SUSPENDED) return -EINVAL; - /* Don't poll the roothubs on bus suspend. */ - xhci_dbg(xhci, "%s: stopping port polling.\n", __func__); - clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); - del_timer_sync(&hcd->rh_timer); - spin_lock_irq(&xhci->lock); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); @@ -1074,11 +1069,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) if (xhci->quirks & XHCI_COMP_MODE_QUIRK) compliance_mode_recovery_timer_init(xhci); - /* Re-enable port polling. */ - xhci_dbg(xhci, "%s: starting port polling.\n", __func__); - set_bit(HCD_FLAG_POLL_RH, &hcd->flags); - usb_hcd_poll_rh_status(hcd); - return retval; } #endif /* CONFIG_PM */ diff --git a/trunk/drivers/usb/misc/usbtest.c b/trunk/drivers/usb/misc/usbtest.c index 268148de9714..7667b12f2ff5 100644 --- a/trunk/drivers/usb/misc/usbtest.c +++ b/trunk/drivers/usb/misc/usbtest.c @@ -2179,7 +2179,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) if (dev->out_pipe == 0 || !param->length || param->sglen < 4) break; retval = 0; - dev_info(&intf->dev, "TEST 24: unlink from %d queues of " + dev_info(&intf->dev, "TEST 17: unlink from %d queues of " "%d %d-byte writes\n", param->iterations, param->sglen, param->length); for (i = param->iterations; retval == 0 && i > 0; --i) { diff --git a/trunk/drivers/usb/musb/musb_core.c b/trunk/drivers/usb/musb/musb_core.c index fd3486745e64..f1c6c5470b92 100644 --- a/trunk/drivers/usb/musb/musb_core.c +++ b/trunk/drivers/usb/musb/musb_core.c @@ -2298,7 +2298,10 @@ static int __init musb_init(void) if (usb_disabled()) return 0; - pr_info("%s: version " MUSB_VERSION ", ?dma?, otg (peripheral+host)\n", + pr_info("%s: version " MUSB_VERSION ", " + "?dma?" + ", " + "otg (peripheral+host)", musb_driver_name); return platform_driver_register(&musb_driver); } diff --git a/trunk/drivers/usb/musb/musb_dsps.c b/trunk/drivers/usb/musb/musb_dsps.c index f7d764de6fda..e6f2ae8368bb 100644 --- a/trunk/drivers/usb/musb/musb_dsps.c +++ b/trunk/drivers/usb/musb/musb_dsps.c @@ -134,11 +134,6 @@ static const resource_size_t dsps_control_module_phys[] = { DSPS_AM33XX_CONTROL_MODULE_PHYS_1, }; -#define USBPHY_CM_PWRDN (1 << 0) -#define USBPHY_OTG_PWRDN (1 << 1) -#define USBPHY_OTGVDET_EN (1 << 19) -#define USBPHY_OTGSESSEND_EN (1 << 20) - /** * musb_dsps_phy_control - phy on/off * @glue: struct dsps_glue * diff --git a/trunk/drivers/usb/otg/Kconfig b/trunk/drivers/usb/otg/Kconfig index 37962c99ff1e..6223062d5d1b 100644 --- a/trunk/drivers/usb/otg/Kconfig +++ b/trunk/drivers/usb/otg/Kconfig @@ -110,7 +110,7 @@ config AB8500_USB config FSL_USB2_OTG bool "Freescale USB OTG Transceiver Driver" - depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_SUSPEND + depends on USB_EHCI_FSL && USB_GADGET_FSL_USB2 && USB_SUSPEND select USB_OTG select USB_OTG_UTILS help diff --git a/trunk/drivers/usb/otg/mv_otg.c b/trunk/drivers/usb/otg/mv_otg.c index eace975991a8..1dd57504186d 100644 --- a/trunk/drivers/usb/otg/mv_otg.c +++ b/trunk/drivers/usb/otg/mv_otg.c @@ -240,7 +240,7 @@ static void otg_clock_enable(struct mv_otg *mvotg) unsigned int i; for (i = 0; i < mvotg->clknum; i++) - clk_prepare_enable(mvotg->clk[i]); + clk_enable(mvotg->clk[i]); } static void otg_clock_disable(struct mv_otg *mvotg) @@ -248,7 +248,7 @@ static void otg_clock_disable(struct mv_otg *mvotg) unsigned int i; for (i = 0; i < mvotg->clknum; i++) - clk_disable_unprepare(mvotg->clk[i]); + clk_disable(mvotg->clk[i]); } static int mv_otg_enable_internal(struct mv_otg *mvotg) diff --git a/trunk/drivers/usb/renesas_usbhs/mod_gadget.c b/trunk/drivers/usb/renesas_usbhs/mod_gadget.c index f2985cd88021..dd41f61893ef 100644 --- a/trunk/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/trunk/drivers/usb/renesas_usbhs/mod_gadget.c @@ -545,6 +545,15 @@ static int usbhsg_pipe_disable(struct usbhsg_uep *uep) return 0; } +static void usbhsg_uep_init(struct usbhsg_gpriv *gpriv) +{ + int i; + struct usbhsg_uep *uep; + + usbhsg_for_each_uep_with_dcp(uep, gpriv, i) + uep->pipe = NULL; +} + /* * * usb_ep_ops @@ -601,12 +610,7 @@ static int usbhsg_ep_disable(struct usb_ep *ep) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); - usbhsg_pipe_disable(uep); - - uep->pipe->mod_private = NULL; - uep->pipe = NULL; - - return 0; + return usbhsg_pipe_disable(uep); } static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep, @@ -757,8 +761,9 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) usbhs_pipe_init(priv, usbhsg_dma_map_ctrl); usbhs_fifo_init(priv); + usbhsg_uep_init(gpriv); - /* dcp init instead of usbhsg_ep_enable() */ + /* dcp init */ dcp->pipe = usbhs_dcp_malloc(priv); dcp->pipe->mod_private = dcp; usbhs_pipe_config_update(dcp->pipe, 0, 0, 64); @@ -820,7 +825,7 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) usbhs_sys_set_test_mode(priv, 0); usbhs_sys_function_ctrl(priv, 0); - usbhsg_ep_disable(&dcp->ep); + usbhsg_pipe_disable(dcp); dev_dbg(dev, "stop gadget\n"); @@ -993,7 +998,6 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) */ usbhsg_for_each_uep_with_dcp(uep, gpriv, i) { uep->gpriv = gpriv; - uep->pipe = NULL; snprintf(uep->ep_name, EP_NAME_SIZE, "ep%d", i); uep->ep.name = uep->ep_name; diff --git a/trunk/drivers/usb/renesas_usbhs/mod_host.c b/trunk/drivers/usb/renesas_usbhs/mod_host.c index b86815421c8d..3d3cd6ca2689 100644 --- a/trunk/drivers/usb/renesas_usbhs/mod_host.c +++ b/trunk/drivers/usb/renesas_usbhs/mod_host.c @@ -661,10 +661,9 @@ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) status = -ESHUTDOWN; urb->actual_length = pkt->actual; - - usbhsh_endpoint_sequence_save(hpriv, urb, pkt); usbhsh_ureq_free(hpriv, ureq); + usbhsh_endpoint_sequence_save(hpriv, urb, pkt); usbhsh_pipe_detach(hpriv, usbhsh_ep_to_uep(urb->ep)); usb_hcd_unlink_urb_from_ep(hcd, urb); diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index ba68835d06a6..0a373b3ae96a 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -875,8 +875,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) }, - /* Crucible Devices */ - { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/trunk/drivers/usb/serial/ftdi_sio_ids.h b/trunk/drivers/usb/serial/ftdi_sio_ids.h index fa5d56038276..049b6e715fa4 100644 --- a/trunk/drivers/usb/serial/ftdi_sio_ids.h +++ b/trunk/drivers/usb/serial/ftdi_sio_ids.h @@ -1259,9 +1259,3 @@ * ATI command output: Cinterion MC55i */ #define FTDI_CINTERION_MC55I_PID 0xA951 - -/* - * Product: Comet Caller ID decoder - * Manufacturer: Crucible Technologies - */ -#define FTDI_CT_COMET_PID 0x8e08 diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index 478adcfcdf26..e6f87b76c715 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -288,7 +288,6 @@ static void option_instat_callback(struct urb *urb); #define ALCATEL_VENDOR_ID 0x1bbb #define ALCATEL_PRODUCT_X060S_X200 0x0000 #define ALCATEL_PRODUCT_X220_X500D 0x0017 -#define ALCATEL_PRODUCT_L100V 0x011e #define PIRELLI_VENDOR_ID 0x1266 #define PIRELLI_PRODUCT_C100_1 0x1002 @@ -430,12 +429,9 @@ static void option_instat_callback(struct urb *urb); #define MEDIATEK_VENDOR_ID 0x0e8d #define MEDIATEK_PRODUCT_DC_1COM 0x00a0 #define MEDIATEK_PRODUCT_DC_4COM 0x00a5 -#define MEDIATEK_PRODUCT_DC_4COM2 0x00a7 #define MEDIATEK_PRODUCT_DC_5COM 0x00a4 #define MEDIATEK_PRODUCT_7208_1COM 0x7101 #define MEDIATEK_PRODUCT_7208_2COM 0x7102 -#define MEDIATEK_PRODUCT_7103_2COM 0x7103 -#define MEDIATEK_PRODUCT_7106_2COM 0x7106 #define MEDIATEK_PRODUCT_FP_1COM 0x0003 #define MEDIATEK_PRODUCT_FP_2COM 0x0023 #define MEDIATEK_PRODUCT_FPDC_1COM 0x0043 @@ -445,10 +441,6 @@ static void option_instat_callback(struct urb *urb); #define CELLIENT_VENDOR_ID 0x2692 #define CELLIENT_PRODUCT_MEN200 0x9005 -/* Hyundai Petatel Inc. products */ -#define PETATEL_VENDOR_ID 0x1ff4 -#define PETATEL_PRODUCT_NP10T 0x600e - /* some devices interfaces need special handling due to a number of reasons */ enum option_blacklist_reason { OPTION_BLACKLIST_NONE = 0, @@ -931,8 +923,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */ .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0265, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0284, 0xff, 0xff, 0xff), /* ZTE MF880 */ - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0284, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0317, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, @@ -1199,8 +1190,6 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) }, - { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), @@ -1305,12 +1294,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FP_2COM, 0x0a, 0x00, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_1COM, 0x0a, 0x00, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_2COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7103_2COM, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7106_2COM, 0x02, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x00, 0x00) }, { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, - { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/trunk/drivers/video/mxsfb.c b/trunk/drivers/video/mxsfb.c index 755556ca5b2d..a45b37c2e88e 100644 --- a/trunk/drivers/video/mxsfb.c +++ b/trunk/drivers/video/mxsfb.c @@ -369,8 +369,7 @@ static void mxsfb_disable_controller(struct fb_info *fb_info) loop--; } - reg = readl(host->base + LCDC_VDCTRL4); - writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4); + writel(VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4 + REG_CLR); clk_disable_unprepare(host->clk); diff --git a/trunk/drivers/video/ssd1307fb.c b/trunk/drivers/video/ssd1307fb.c index 395cb6a8d8f3..4d99dd7a6831 100644 --- a/trunk/drivers/video/ssd1307fb.c +++ b/trunk/drivers/video/ssd1307fb.c @@ -145,8 +145,8 @@ static void ssd1307fb_update_display(struct ssd1307fb_par *par) u32 page_length = SSD1307FB_WIDTH * i; u32 index = page_length + (SSD1307FB_WIDTH * k + j) / 8; u8 byte = *(vmem + index); - u8 bit = byte & (1 << (j % 8)); - bit = bit >> (j % 8); + u8 bit = byte & (1 << (7 - (j % 8))); + bit = bit >> (7 - (j % 8)); buf |= bit << k; } ssd1307fb_write_data(par->client, buf); diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 7a75c3e0fd58..c017a2dfb909 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -2935,7 +2935,6 @@ static void guard_bh_eod(int rw, struct bio *bio, struct buffer_head *bh) void *kaddr = kmap_atomic(bh->b_page); memset(kaddr + bh_offset(bh) + bytes, 0, bh->b_size - bytes); kunmap_atomic(kaddr); - flush_dcache_page(bh->b_page); } } diff --git a/trunk/fs/debugfs/inode.c b/trunk/fs/debugfs/inode.c index a5f12b7e228d..153bb1e42e63 100644 --- a/trunk/fs/debugfs/inode.c +++ b/trunk/fs/debugfs/inode.c @@ -176,7 +176,7 @@ static int debugfs_parse_options(char *data, struct debugfs_mount_opts *opts) opts->uid = uid; break; case Opt_gid: - if (match_int(&args[0], &option)) + if (match_octal(&args[0], &option)) return -EINVAL; gid = make_kgid(current_user_ns(), option); if (!gid_valid(gid)) diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 20df02c1cc70..18c45cac368f 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -434,9 +434,8 @@ static int count(struct user_arg_ptr argv, int max) if (IS_ERR(p)) return -EFAULT; - if (i >= max) + if (i++ >= max) return -E2BIG; - ++i; if (fatal_signal_pending(current)) return -ERESTARTNOHAND; diff --git a/trunk/fs/seq_file.c b/trunk/fs/seq_file.c index f2bc3dfd0b88..9d863fb501f9 100644 --- a/trunk/fs/seq_file.c +++ b/trunk/fs/seq_file.c @@ -296,7 +296,7 @@ EXPORT_SYMBOL(seq_read); * seq_lseek - ->llseek() method for sequential files. * @file: the file in question * @offset: new position - * @whence: 0 for absolute, 1 for relative position + * @origin: 0 for absolute, 1 for relative position * * Ready-made ->f_op->llseek() */ diff --git a/trunk/include/drm/drm_mm.h b/trunk/include/drm/drm_mm.h index 3527fb3f75bb..0f4a366f6fa6 100644 --- a/trunk/include/drm/drm_mm.h +++ b/trunk/include/drm/drm_mm.h @@ -70,7 +70,7 @@ struct drm_mm { unsigned long scan_color; unsigned long scan_size; unsigned long scan_hit_start; - unsigned long scan_hit_end; + unsigned scan_hit_size; unsigned scanned_blocks; unsigned long scan_start; unsigned long scan_end; diff --git a/trunk/include/drm/exynos_drm.h b/trunk/include/drm/exynos_drm.h index d6aeaf3c6d6c..808dad29607a 100644 --- a/trunk/include/drm/exynos_drm.h +++ b/trunk/include/drm/exynos_drm.h @@ -6,10 +6,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _EXYNOS_DRM_H_ #define _EXYNOS_DRM_H_ diff --git a/trunk/include/linux/audit.h b/trunk/include/linux/audit.h index 5a6d718adf34..bce729afbcf9 100644 --- a/trunk/include/linux/audit.h +++ b/trunk/include/linux/audit.h @@ -24,7 +24,6 @@ #define _LINUX_AUDIT_H_ #include -#include #include struct audit_sig_info { @@ -158,8 +157,7 @@ void audit_core_dumps(long signr); static inline void audit_seccomp(unsigned long syscall, long signr, int code) { - /* Force a record to be reported if a signal was delivered. */ - if (signr || unlikely(!audit_dummy_context())) + if (unlikely(!audit_dummy_context())) __audit_seccomp(syscall, signr, code); } diff --git a/trunk/include/linux/compaction.h b/trunk/include/linux/compaction.h index cc7bddeaf553..6ecb6dc2f303 100644 --- a/trunk/include/linux/compaction.h +++ b/trunk/include/linux/compaction.h @@ -22,7 +22,7 @@ extern int sysctl_extfrag_handler(struct ctl_table *table, int write, extern int fragmentation_index(struct zone *zone, unsigned int order); extern unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *mask, - bool sync, bool *contended); + bool sync, bool *contended, struct page **page); extern int compact_pgdat(pg_data_t *pgdat, int order); extern void reset_isolation_suitable(pg_data_t *pgdat); extern unsigned long compaction_suitable(struct zone *zone, int order); @@ -75,7 +75,7 @@ static inline bool compaction_restarting(struct zone *zone, int order) #else static inline unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *nodemask, - bool sync, bool *contended) + bool sync, bool *contended, struct page **page) { return COMPACT_CONTINUE; } diff --git a/trunk/include/linux/cpu_rmap.h b/trunk/include/linux/cpu_rmap.h index 1739510d8994..ac3bbb5b9502 100644 --- a/trunk/include/linux/cpu_rmap.h +++ b/trunk/include/linux/cpu_rmap.h @@ -13,11 +13,9 @@ #include #include #include -#include /** * struct cpu_rmap - CPU affinity reverse-map - * @refcount: kref for object * @size: Number of objects to be reverse-mapped * @used: Number of objects added * @obj: Pointer to array of object pointers @@ -25,7 +23,6 @@ * based on affinity masks */ struct cpu_rmap { - struct kref refcount; u16 size, used; void **obj; struct { @@ -36,7 +33,15 @@ struct cpu_rmap { #define CPU_RMAP_DIST_INF 0xffff extern struct cpu_rmap *alloc_cpu_rmap(unsigned int size, gfp_t flags); -extern int cpu_rmap_put(struct cpu_rmap *rmap); + +/** + * free_cpu_rmap - free CPU affinity reverse-map + * @rmap: Reverse-map allocated with alloc_cpu_rmap(), or %NULL + */ +static inline void free_cpu_rmap(struct cpu_rmap *rmap) +{ + kfree(rmap); +} extern int cpu_rmap_add(struct cpu_rmap *rmap, void *obj); extern int cpu_rmap_update(struct cpu_rmap *rmap, u16 index, diff --git a/trunk/include/linux/cred.h b/trunk/include/linux/cred.h index 04421e825365..abb2cd50f6b2 100644 --- a/trunk/include/linux/cred.h +++ b/trunk/include/linux/cred.h @@ -128,6 +128,7 @@ struct cred { struct key *process_keyring; /* keyring private to this process */ struct key *thread_keyring; /* keyring private to this thread */ struct key *request_key_auth; /* assumed request_key authority */ + struct thread_group_cred *tgcred; /* thread-group shared credentials */ #endif #ifdef CONFIG_SECURITY void *security; /* subjective LSM security */ diff --git a/trunk/include/linux/init.h b/trunk/include/linux/init.h index 10ed4f436458..a799273714ac 100644 --- a/trunk/include/linux/init.h +++ b/trunk/include/linux/init.h @@ -93,6 +93,14 @@ #define __exit __section(.exit.text) __exitused __cold notrace +/* Used for HOTPLUG, but that is always enabled now, so just make them noops */ +#define __devinit +#define __devinitdata +#define __devinitconst +#define __devexit +#define __devexitdata +#define __devexitconst + /* Used for HOTPLUG_CPU */ #define __cpuinit __section(.cpuinit.text) __cold notrace #define __cpuinitdata __section(.cpuinit.data) @@ -329,6 +337,18 @@ void __init parse_early_options(char *cmdline); #define __INITRODATA_OR_MODULE __INITRODATA #endif /*CONFIG_MODULES*/ +/* Functions marked as __devexit may be discarded at kernel link time, depending + on config options. Newer versions of binutils detect references from + retained sections to discarded sections and flag an error. Pointers to + __devexit functions must use __devexit_p(function_name), the wrapper will + insert either the function_name or NULL, depending on the config options. + */ +#if defined(MODULE) || defined(CONFIG_HOTPLUG) +#define __devexit_p(x) x +#else +#define __devexit_p(x) NULL +#endif + #ifdef MODULE #define __exit_p(x) x #else diff --git a/trunk/include/linux/interrupt.h b/trunk/include/linux/interrupt.h index 5fa5afeeb759..5e4e6170f43a 100644 --- a/trunk/include/linux/interrupt.h +++ b/trunk/include/linux/interrupt.h @@ -268,6 +268,11 @@ struct irq_affinity_notify { extern int irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify); +static inline void irq_run_affinity_notifiers(void) +{ + flush_scheduled_work(); +} + #else /* CONFIG_SMP */ static inline int irq_set_affinity(unsigned int irq, const struct cpumask *m) diff --git a/trunk/include/linux/lockdep.h b/trunk/include/linux/lockdep.h index 2bca44b0893c..00e46376e28f 100644 --- a/trunk/include/linux/lockdep.h +++ b/trunk/include/linux/lockdep.h @@ -524,17 +524,14 @@ static inline void print_irqtrace_events(struct task_struct *curr) #ifdef CONFIG_DEBUG_LOCK_ALLOC # ifdef CONFIG_PROVE_LOCKING # define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i) -# define rwsem_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 2, n, i) # define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 2, NULL, i) # else # define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i) -# define rwsem_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 1, n, i) # define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 1, NULL, i) # endif # define rwsem_release(l, n, i) lock_release(l, n, i) #else # define rwsem_acquire(l, s, t, i) do { } while (0) -# define rwsem_acquire_nest(l, s, t, n, i) do { } while (0) # define rwsem_acquire_read(l, s, t, i) do { } while (0) # define rwsem_release(l, n, i) do { } while (0) #endif diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 66e2f7c61e5c..63204078f72b 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -455,6 +455,7 @@ void put_pages_list(struct list_head *pages); void split_page(struct page *page, unsigned int order); int split_free_page(struct page *page); +int capture_free_page(struct page *page, int alloc_order, int migratetype); /* * Compound pages have a destructor function. Provide a diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 9ef07d0868b6..c599e4782d45 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -60,9 +60,6 @@ struct wireless_dev; #define SET_ETHTOOL_OPS(netdev,ops) \ ( (netdev)->ethtool_ops = (ops) ) -extern void netdev_set_default_ethtool_ops(struct net_device *dev, - const struct ethtool_ops *ops); - /* hardware address assignment types */ #define NET_ADDR_PERM 0 /* address is permanent (default) */ #define NET_ADDR_RANDOM 1 /* address is generated randomly */ diff --git a/trunk/include/linux/rbtree_augmented.h b/trunk/include/linux/rbtree_augmented.h index fea49b5da12a..2ac60c9cf644 100644 --- a/trunk/include/linux/rbtree_augmented.h +++ b/trunk/include/linux/rbtree_augmented.h @@ -123,9 +123,9 @@ __rb_change_child(struct rb_node *old, struct rb_node *new, extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root, void (*augment_rotate)(struct rb_node *old, struct rb_node *new)); -static __always_inline struct rb_node * -__rb_erase_augmented(struct rb_node *node, struct rb_root *root, - const struct rb_augment_callbacks *augment) +static __always_inline void +rb_erase_augmented(struct rb_node *node, struct rb_root *root, + const struct rb_augment_callbacks *augment) { struct rb_node *child = node->rb_right, *tmp = node->rb_left; struct rb_node *parent, *rebalance; @@ -217,14 +217,6 @@ __rb_erase_augmented(struct rb_node *node, struct rb_root *root, } augment->propagate(tmp, NULL); - return rebalance; -} - -static __always_inline void -rb_erase_augmented(struct rb_node *node, struct rb_root *root, - const struct rb_augment_callbacks *augment) -{ - struct rb_node *rebalance = __rb_erase_augmented(node, root, augment); if (rebalance) __rb_erase_color(rebalance, root, augment->rotate); } diff --git a/trunk/include/linux/rwsem.h b/trunk/include/linux/rwsem.h index 413cc11e414a..54bd7cd7ecbd 100644 --- a/trunk/include/linux/rwsem.h +++ b/trunk/include/linux/rwsem.h @@ -125,17 +125,8 @@ extern void downgrade_write(struct rw_semaphore *sem); */ extern void down_read_nested(struct rw_semaphore *sem, int subclass); extern void down_write_nested(struct rw_semaphore *sem, int subclass); -extern void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest_lock); - -# define down_write_nest_lock(sem, nest_lock) \ -do { \ - typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \ - _down_write_nest_lock(sem, &(nest_lock)->dep_map); \ -} while (0); - #else # define down_read_nested(sem, subclass) down_read(sem) -# define down_write_nest_lock(sem, nest_lock) down_read(sem) # define down_write_nested(sem, subclass) down_write(sem) #endif diff --git a/trunk/include/linux/security.h b/trunk/include/linux/security.h index eee7478cda70..0f6afc657f77 100644 --- a/trunk/include/linux/security.h +++ b/trunk/include/linux/security.h @@ -989,29 +989,17 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * tells the LSM to decrement the number of secmark labeling rules loaded * @req_classify_flow: * Sets the flow's sid to the openreq sid. - * @tun_dev_alloc_security: - * This hook allows a module to allocate a security structure for a TUN - * device. - * @security pointer to a security structure pointer. - * Returns a zero on success, negative values on failure. - * @tun_dev_free_security: - * This hook allows a module to free the security structure for a TUN - * device. - * @security pointer to the TUN device's security structure * @tun_dev_create: * Check permissions prior to creating a new TUN device. - * @tun_dev_attach_queue: - * Check permissions prior to attaching to a TUN device queue. - * @security pointer to the TUN device's security structure. + * @tun_dev_post_create: + * This hook allows a module to update or allocate a per-socket security + * structure. + * @sk contains the newly created sock structure. * @tun_dev_attach: - * This hook can be used by the module to update any security state + * Check permissions prior to attaching to a persistent TUN device. This + * hook can also be used by the module to update any security state * associated with the TUN device's sock structure. * @sk contains the existing sock structure. - * @security pointer to the TUN device's security structure. - * @tun_dev_open: - * This hook can be used by the module to update any security state - * associated with the TUN device's security structure. - * @security pointer to the TUN devices's security structure. * * Security hooks for XFRM operations. * @@ -1632,12 +1620,9 @@ struct security_operations { void (*secmark_refcount_inc) (void); void (*secmark_refcount_dec) (void); void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl); - int (*tun_dev_alloc_security) (void **security); - void (*tun_dev_free_security) (void *security); - int (*tun_dev_create) (void); - int (*tun_dev_attach_queue) (void *security); - int (*tun_dev_attach) (struct sock *sk, void *security); - int (*tun_dev_open) (void *security); + int (*tun_dev_create)(void); + void (*tun_dev_post_create)(struct sock *sk); + int (*tun_dev_attach)(struct sock *sk); #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -2581,12 +2566,9 @@ void security_inet_conn_established(struct sock *sk, int security_secmark_relabel_packet(u32 secid); void security_secmark_refcount_inc(void); void security_secmark_refcount_dec(void); -int security_tun_dev_alloc_security(void **security); -void security_tun_dev_free_security(void *security); int security_tun_dev_create(void); -int security_tun_dev_attach_queue(void *security); -int security_tun_dev_attach(struct sock *sk, void *security); -int security_tun_dev_open(void *security); +void security_tun_dev_post_create(struct sock *sk); +int security_tun_dev_attach(struct sock *sk); #else /* CONFIG_SECURITY_NETWORK */ static inline int security_unix_stream_connect(struct sock *sock, @@ -2751,31 +2733,16 @@ static inline void security_secmark_refcount_dec(void) { } -static inline int security_tun_dev_alloc_security(void **security) -{ - return 0; -} - -static inline void security_tun_dev_free_security(void *security) -{ -} - static inline int security_tun_dev_create(void) { return 0; } -static inline int security_tun_dev_attach_queue(void *security) -{ - return 0; -} - -static inline int security_tun_dev_attach(struct sock *sk, void *security) +static inline void security_tun_dev_post_create(struct sock *sk) { - return 0; } -static inline int security_tun_dev_open(void *security) +static inline int security_tun_dev_attach(struct sock *sk) { return 0; } diff --git a/trunk/include/sound/cs4271.h b/trunk/include/sound/cs4271.h index dd8c48d14ed9..6d9e15ed1dcf 100644 --- a/trunk/include/sound/cs4271.h +++ b/trunk/include/sound/cs4271.h @@ -19,7 +19,7 @@ struct cs4271_platform_data { int gpio_nreset; /* GPIO driving Reset pin, if any */ - bool amutec_eq_bmutec; /* flag to enable AMUTEC=BMUTEC */ + int amutec_eq_bmutec:1; /* flag to enable AMUTEC=BMUTEC */ }; #endif /* __CS4271_H */ diff --git a/trunk/include/sound/soc.h b/trunk/include/sound/soc.h index bc56738cb109..769e27c774a3 100644 --- a/trunk/include/sound/soc.h +++ b/trunk/include/sound/soc.h @@ -58,9 +58,8 @@ .info = snd_soc_info_volsw_range, .get = snd_soc_get_volsw_range, \ .put = snd_soc_put_volsw_range, \ .private_value = (unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .rreg = xreg, .shift = xshift, \ - .rshift = xshift, .min = xmin, .max = xmax, \ - .platform_max = xmax, .invert = xinvert} } + {.reg = xreg, .shift = xshift, .min = xmin,\ + .max = xmax, .platform_max = xmax, .invert = xinvert} } #define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ @@ -89,9 +88,8 @@ .info = snd_soc_info_volsw_range, \ .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ .private_value = (unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .rreg = xreg, .shift = xshift, \ - .rshift = xshift, .min = xmin, .max = xmax, \ - .platform_max = xmax, .invert = xinvert} } + {.reg = xreg, .shift = xshift, .min = xmin,\ + .max = xmax, .platform_max = xmax, .invert = xinvert} } #define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ diff --git a/trunk/include/uapi/drm/exynos_drm.h b/trunk/include/uapi/drm/exynos_drm.h index d5844122ff32..e7f52c334005 100644 --- a/trunk/include/uapi/drm/exynos_drm.h +++ b/trunk/include/uapi/drm/exynos_drm.h @@ -6,10 +6,24 @@ * Joonyoung Shim * Seung-Woo Kim * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. */ #ifndef _UAPI_EXYNOS_DRM_H_ @@ -171,8 +185,6 @@ enum drm_exynos_flip { EXYNOS_DRM_FLIP_NONE = (0 << 0), EXYNOS_DRM_FLIP_VERTICAL = (1 << 0), EXYNOS_DRM_FLIP_HORIZONTAL = (1 << 1), - EXYNOS_DRM_FLIP_BOTH = EXYNOS_DRM_FLIP_VERTICAL | - EXYNOS_DRM_FLIP_HORIZONTAL, }; enum drm_exynos_degree { diff --git a/trunk/include/uapi/linux/audit.h b/trunk/include/uapi/linux/audit.h index 9f096f1c0907..76352ac45f24 100644 --- a/trunk/include/uapi/linux/audit.h +++ b/trunk/include/uapi/linux/audit.h @@ -26,6 +26,7 @@ #include #include +#include /* The netlink messages for the audit system is divided into blocks: * 1000 - 1099 are for commanding the audit system @@ -105,7 +106,6 @@ #define AUDIT_MMAP 1323 /* Record showing descriptor and flags in mmap */ #define AUDIT_NETFILTER_PKT 1324 /* Packets traversing netfilter chains */ #define AUDIT_NETFILTER_CFG 1325 /* Netfilter chain modifications */ -#define AUDIT_SECCOMP 1326 /* Secure Computing event */ #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ diff --git a/trunk/kernel/audit.c b/trunk/kernel/audit.c index d596e5355f15..40414e9143db 100644 --- a/trunk/kernel/audit.c +++ b/trunk/kernel/audit.c @@ -272,8 +272,6 @@ static int audit_log_config_change(char *function_name, int new, int old, int rc = 0; ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); - if (unlikely(!ab)) - return rc; audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new, old, from_kuid(&init_user_ns, loginuid), sessionid); if (sid) { @@ -621,8 +619,6 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, } *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); - if (unlikely(!*ab)) - return rc; audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u", task_tgid_vnr(current), from_kuid(&init_user_ns, current_uid()), @@ -1101,23 +1097,6 @@ static inline void audit_get_stamp(struct audit_context *ctx, } } -/* - * Wait for auditd to drain the queue a little - */ -static void wait_for_auditd(unsigned long sleep_time) -{ - DECLARE_WAITQUEUE(wait, current); - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&audit_backlog_wait, &wait); - - if (audit_backlog_limit && - skb_queue_len(&audit_skb_queue) > audit_backlog_limit) - schedule_timeout(sleep_time); - - __set_current_state(TASK_RUNNING); - remove_wait_queue(&audit_backlog_wait, &wait); -} - /* Obtain an audit buffer. This routine does locking to obtain the * audit buffer, but then no locking is required for calls to * audit_log_*format. If the tsk is a task that is currently in a @@ -1163,13 +1142,20 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, while (audit_backlog_limit && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { - if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time) { - unsigned long sleep_time; + if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time + && time_before(jiffies, timeout_start + audit_backlog_wait_time)) { - sleep_time = timeout_start + audit_backlog_wait_time - - jiffies; - if ((long)sleep_time > 0) - wait_for_auditd(sleep_time); + /* Wait for auditd to drain the queue a little */ + DECLARE_WAITQUEUE(wait, current); + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&audit_backlog_wait, &wait); + + if (audit_backlog_limit && + skb_queue_len(&audit_skb_queue) > audit_backlog_limit) + schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies); + + __set_current_state(TASK_RUNNING); + remove_wait_queue(&audit_backlog_wait, &wait); continue; } if (audit_rate_check() && printk_ratelimit()) diff --git a/trunk/kernel/audit_tree.c b/trunk/kernel/audit_tree.c index 642a89c4f3d6..e81175ef25f8 100644 --- a/trunk/kernel/audit_tree.c +++ b/trunk/kernel/audit_tree.c @@ -449,26 +449,11 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) return 0; } -static void audit_log_remove_rule(struct audit_krule *rule) -{ - struct audit_buffer *ab; - - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); - if (unlikely(!ab)) - return; - audit_log_format(ab, "op="); - audit_log_string(ab, "remove rule"); - audit_log_format(ab, " dir="); - audit_log_untrustedstring(ab, rule->tree->pathname); - audit_log_key(ab, rule->filterkey); - audit_log_format(ab, " list=%d res=1", rule->listnr); - audit_log_end(ab); -} - static void kill_rules(struct audit_tree *tree) { struct audit_krule *rule, *next; struct audit_entry *entry; + struct audit_buffer *ab; list_for_each_entry_safe(rule, next, &tree->rules, rlist) { entry = container_of(rule, struct audit_entry, rule); @@ -476,7 +461,14 @@ static void kill_rules(struct audit_tree *tree) list_del_init(&rule->rlist); if (rule->tree) { /* not a half-baked one */ - audit_log_remove_rule(rule); + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); + audit_log_format(ab, "op="); + audit_log_string(ab, "remove rule"); + audit_log_format(ab, " dir="); + audit_log_untrustedstring(ab, rule->tree->pathname); + audit_log_key(ab, rule->filterkey); + audit_log_format(ab, " list=%d res=1", rule->listnr); + audit_log_end(ab); rule->tree = NULL; list_del_rcu(&entry->list); list_del(&entry->rule.list); diff --git a/trunk/kernel/audit_watch.c b/trunk/kernel/audit_watch.c index 22831c4d369c..4a599f699adc 100644 --- a/trunk/kernel/audit_watch.c +++ b/trunk/kernel/audit_watch.c @@ -240,8 +240,6 @@ static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watc if (audit_enabled) { struct audit_buffer *ab; ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE); - if (unlikely(!ab)) - return; audit_log_format(ab, "auid=%u ses=%u op=", from_kuid(&init_user_ns, audit_get_loginuid(current)), audit_get_sessionid(current)); diff --git a/trunk/kernel/auditfilter.c b/trunk/kernel/auditfilter.c index f9fc54bbe06f..7f19f23d38a3 100644 --- a/trunk/kernel/auditfilter.c +++ b/trunk/kernel/auditfilter.c @@ -1144,6 +1144,7 @@ static void audit_log_rule_change(kuid_t loginuid, u32 sessionid, u32 sid, * audit_receive_filter - apply all rules to the specified message type * @type: audit message type * @pid: target pid for netlink audit messages + * @uid: target uid for netlink audit messages * @seq: netlink audit message sequence (serial) number * @data: payload data * @datasz: size of payload data diff --git a/trunk/kernel/auditsc.c b/trunk/kernel/auditsc.c index a371f857a0a9..e37e6a12c5e3 100644 --- a/trunk/kernel/auditsc.c +++ b/trunk/kernel/auditsc.c @@ -1464,14 +1464,14 @@ static void show_special(struct audit_context *context, int *call_panic) audit_log_end(ab); ab = audit_log_start(context, GFP_KERNEL, AUDIT_IPC_SET_PERM); - if (unlikely(!ab)) - return; audit_log_format(ab, "qbytes=%lx ouid=%u ogid=%u mode=%#ho", context->ipc.qbytes, context->ipc.perm_uid, context->ipc.perm_gid, context->ipc.perm_mode); + if (!ab) + return; } break; } case AUDIT_MQ_OPEN: { @@ -2675,7 +2675,7 @@ void __audit_mmap_fd(int fd, int flags) context->type = AUDIT_MMAP; } -static void audit_log_task(struct audit_buffer *ab) +static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) { kuid_t auid, uid; kgid_t gid; @@ -2693,11 +2693,6 @@ static void audit_log_task(struct audit_buffer *ab) audit_log_task_context(ab); audit_log_format(ab, " pid=%d comm=", current->pid); audit_log_untrustedstring(ab, current->comm); -} - -static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) -{ - audit_log_task(ab); audit_log_format(ab, " reason="); audit_log_string(ab, reason); audit_log_format(ab, " sig=%ld", signr); @@ -2720,8 +2715,6 @@ void audit_core_dumps(long signr) return; ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); - if (unlikely(!ab)) - return; audit_log_abend(ab, "memory violation", signr); audit_log_end(ab); } @@ -2730,11 +2723,8 @@ void __audit_seccomp(unsigned long syscall, long signr, int code) { struct audit_buffer *ab; - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_SECCOMP); - if (unlikely(!ab)) - return; - audit_log_task(ab); - audit_log_format(ab, " sig=%ld", signr); + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); + audit_log_abend(ab, "seccomp", signr); audit_log_format(ab, " syscall=%ld", syscall); audit_log_format(ab, " compat=%d", is_compat_task()); audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current)); diff --git a/trunk/kernel/rwsem.c b/trunk/kernel/rwsem.c index b3c6c3fcd847..6850f53e02d8 100644 --- a/trunk/kernel/rwsem.c +++ b/trunk/kernel/rwsem.c @@ -116,16 +116,6 @@ void down_read_nested(struct rw_semaphore *sem, int subclass) EXPORT_SYMBOL(down_read_nested); -void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest) -{ - might_sleep(); - rwsem_acquire_nest(&sem->dep_map, 0, 0, nest, _RET_IP_); - - LOCK_CONTENDED(sem, __down_write_trylock, __down_write); -} - -EXPORT_SYMBOL(_down_write_nest_lock); - void down_write_nested(struct rw_semaphore *sem, int subclass) { might_sleep(); diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c index 1bbfa0446507..e5125677efa0 100644 --- a/trunk/kernel/trace/trace.c +++ b/trunk/kernel/trace/trace.c @@ -2899,8 +2899,6 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, if (copy_from_user(&buf, ubuf, cnt)) return -EFAULT; - buf[cnt] = 0; - trace_set_options(buf); *ppos += cnt; diff --git a/trunk/lib/cpu_rmap.c b/trunk/lib/cpu_rmap.c index 5fbed5caba6e..145dec5267c9 100644 --- a/trunk/lib/cpu_rmap.c +++ b/trunk/lib/cpu_rmap.c @@ -45,7 +45,6 @@ struct cpu_rmap *alloc_cpu_rmap(unsigned int size, gfp_t flags) if (!rmap) return NULL; - kref_init(&rmap->refcount); rmap->obj = (void **)((char *)rmap + obj_offset); /* Initially assign CPUs to objects on a rota, since we have @@ -64,35 +63,6 @@ struct cpu_rmap *alloc_cpu_rmap(unsigned int size, gfp_t flags) } EXPORT_SYMBOL(alloc_cpu_rmap); -/** - * cpu_rmap_release - internal reclaiming helper called from kref_put - * @ref: kref to struct cpu_rmap - */ -static void cpu_rmap_release(struct kref *ref) -{ - struct cpu_rmap *rmap = container_of(ref, struct cpu_rmap, refcount); - kfree(rmap); -} - -/** - * cpu_rmap_get - internal helper to get new ref on a cpu_rmap - * @rmap: reverse-map allocated with alloc_cpu_rmap() - */ -static inline void cpu_rmap_get(struct cpu_rmap *rmap) -{ - kref_get(&rmap->refcount); -} - -/** - * cpu_rmap_put - release ref on a cpu_rmap - * @rmap: reverse-map allocated with alloc_cpu_rmap() - */ -int cpu_rmap_put(struct cpu_rmap *rmap) -{ - return kref_put(&rmap->refcount, cpu_rmap_release); -} -EXPORT_SYMBOL(cpu_rmap_put); - /* Reevaluate nearest object for given CPU, comparing with the given * neighbours at the given distance. */ @@ -227,7 +197,8 @@ struct irq_glue { * free_irq_cpu_rmap - free a CPU affinity reverse-map used for IRQs * @rmap: Reverse-map allocated with alloc_irq_cpu_map(), or %NULL * - * Must be called in process context, before freeing the IRQs. + * Must be called in process context, before freeing the IRQs, and + * without holding any locks required by global workqueue items. */ void free_irq_cpu_rmap(struct cpu_rmap *rmap) { @@ -241,18 +212,12 @@ void free_irq_cpu_rmap(struct cpu_rmap *rmap) glue = rmap->obj[index]; irq_set_affinity_notifier(glue->notify.irq, NULL); } + irq_run_affinity_notifiers(); - cpu_rmap_put(rmap); + kfree(rmap); } EXPORT_SYMBOL(free_irq_cpu_rmap); -/** - * irq_cpu_rmap_notify - callback for IRQ subsystem when IRQ affinity updated - * @notify: struct irq_affinity_notify passed by irq/manage.c - * @mask: cpu mask for new SMP affinity - * - * This is executed in workqueue context. - */ static void irq_cpu_rmap_notify(struct irq_affinity_notify *notify, const cpumask_t *mask) { @@ -265,16 +230,10 @@ irq_cpu_rmap_notify(struct irq_affinity_notify *notify, const cpumask_t *mask) pr_warning("irq_cpu_rmap_notify: update failed: %d\n", rc); } -/** - * irq_cpu_rmap_release - reclaiming callback for IRQ subsystem - * @ref: kref to struct irq_affinity_notify passed by irq/manage.c - */ static void irq_cpu_rmap_release(struct kref *ref) { struct irq_glue *glue = container_of(ref, struct irq_glue, notify.kref); - - cpu_rmap_put(glue->rmap); kfree(glue); } @@ -299,13 +258,10 @@ int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq) glue->notify.notify = irq_cpu_rmap_notify; glue->notify.release = irq_cpu_rmap_release; glue->rmap = rmap; - cpu_rmap_get(rmap); glue->index = cpu_rmap_add(rmap, glue); rc = irq_set_affinity_notifier(irq, &glue->notify); - if (rc) { - cpu_rmap_put(glue->rmap); + if (rc) kfree(glue); - } return rc; } EXPORT_SYMBOL(irq_cpu_rmap_add); diff --git a/trunk/lib/rbtree.c b/trunk/lib/rbtree.c index c0e31fe2fabf..4f56a11d67fa 100644 --- a/trunk/lib/rbtree.c +++ b/trunk/lib/rbtree.c @@ -194,12 +194,8 @@ __rb_insert(struct rb_node *node, struct rb_root *root, } } -/* - * Inline version for rb_erase() use - we want to be able to inline - * and eliminate the dummy_rotate callback there - */ -static __always_inline void -____rb_erase_color(struct rb_node *parent, struct rb_root *root, +__always_inline void +__rb_erase_color(struct rb_node *parent, struct rb_root *root, void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) { struct rb_node *node = NULL, *sibling, *tmp1, *tmp2; @@ -359,13 +355,6 @@ ____rb_erase_color(struct rb_node *parent, struct rb_root *root, } } } - -/* Non-inline version for rb_erase_augmented() use */ -void __rb_erase_color(struct rb_node *parent, struct rb_root *root, - void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) -{ - ____rb_erase_color(parent, root, augment_rotate); -} EXPORT_SYMBOL(__rb_erase_color); /* @@ -391,10 +380,7 @@ EXPORT_SYMBOL(rb_insert_color); void rb_erase(struct rb_node *node, struct rb_root *root) { - struct rb_node *rebalance; - rebalance = __rb_erase_augmented(node, root, &dummy_callbacks); - if (rebalance) - ____rb_erase_color(rebalance, root, dummy_rotate); + rb_erase_augmented(node, root, &dummy_callbacks); } EXPORT_SYMBOL(rb_erase); diff --git a/trunk/mm/bootmem.c b/trunk/mm/bootmem.c index b93376c39b61..1324cd74faec 100644 --- a/trunk/mm/bootmem.c +++ b/trunk/mm/bootmem.c @@ -185,23 +185,10 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) while (start < end) { unsigned long *map, idx, vec; - unsigned shift; map = bdata->node_bootmem_map; idx = start - bdata->node_min_pfn; - shift = idx & (BITS_PER_LONG - 1); - /* - * vec holds at most BITS_PER_LONG map bits, - * bit 0 corresponds to start. - */ vec = ~map[idx / BITS_PER_LONG]; - - if (shift) { - vec >>= shift; - if (end - start >= BITS_PER_LONG) - vec |= ~map[idx / BITS_PER_LONG + 1] << - (BITS_PER_LONG - shift); - } /* * If we have a properly aligned and fully unreserved * BITS_PER_LONG block of pages in front of us, free @@ -214,18 +201,19 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) count += BITS_PER_LONG; start += BITS_PER_LONG; } else { - unsigned long cur = start; + unsigned long off = 0; - start = ALIGN(start + 1, BITS_PER_LONG); - while (vec && cur != start) { + vec >>= start & (BITS_PER_LONG - 1); + while (vec) { if (vec & 1) { - page = pfn_to_page(cur); + page = pfn_to_page(start + off); __free_pages_bootmem(page, 0); count++; } vec >>= 1; - ++cur; + off++; } + start = ALIGN(start + 1, BITS_PER_LONG); } } diff --git a/trunk/mm/compaction.c b/trunk/mm/compaction.c index c62bd063d766..6b807e466497 100644 --- a/trunk/mm/compaction.c +++ b/trunk/mm/compaction.c @@ -816,7 +816,6 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone, static int compact_finished(struct zone *zone, struct compact_control *cc) { - unsigned int order; unsigned long watermark; if (fatal_signal_pending(current)) @@ -851,16 +850,22 @@ static int compact_finished(struct zone *zone, return COMPACT_CONTINUE; /* Direct compactor: Is a suitable page free? */ - for (order = cc->order; order < MAX_ORDER; order++) { - struct free_area *area = &zone->free_area[order]; - - /* Job done if page is free of the right migratetype */ - if (!list_empty(&area->free_list[cc->migratetype])) - return COMPACT_PARTIAL; - - /* Job done if allocation would set block type */ - if (cc->order >= pageblock_order && area->nr_free) + if (cc->page) { + /* Was a suitable page captured? */ + if (*cc->page) return COMPACT_PARTIAL; + } else { + unsigned int order; + for (order = cc->order; order < MAX_ORDER; order++) { + struct free_area *area = &zone->free_area[cc->order]; + /* Job done if page is free of the right migratetype */ + if (!list_empty(&area->free_list[cc->migratetype])) + return COMPACT_PARTIAL; + + /* Job done if allocation would set block type */ + if (cc->order >= pageblock_order && area->nr_free) + return COMPACT_PARTIAL; + } } return COMPACT_CONTINUE; @@ -916,6 +921,60 @@ unsigned long compaction_suitable(struct zone *zone, int order) return COMPACT_CONTINUE; } +static void compact_capture_page(struct compact_control *cc) +{ + unsigned long flags; + int mtype, mtype_low, mtype_high; + + if (!cc->page || *cc->page) + return; + + /* + * For MIGRATE_MOVABLE allocations we capture a suitable page ASAP + * regardless of the migratetype of the freelist is is captured from. + * This is fine because the order for a high-order MIGRATE_MOVABLE + * allocation is typically at least a pageblock size and overall + * fragmentation is not impaired. Other allocation types must + * capture pages from their own migratelist because otherwise they + * could pollute other pageblocks like MIGRATE_MOVABLE with + * difficult to move pages and making fragmentation worse overall. + */ + if (cc->migratetype == MIGRATE_MOVABLE) { + mtype_low = 0; + mtype_high = MIGRATE_PCPTYPES; + } else { + mtype_low = cc->migratetype; + mtype_high = cc->migratetype + 1; + } + + /* Speculatively examine the free lists without zone lock */ + for (mtype = mtype_low; mtype < mtype_high; mtype++) { + int order; + for (order = cc->order; order < MAX_ORDER; order++) { + struct page *page; + struct free_area *area; + area = &(cc->zone->free_area[order]); + if (list_empty(&area->free_list[mtype])) + continue; + + /* Take the lock and attempt capture of the page */ + if (!compact_trylock_irqsave(&cc->zone->lock, &flags, cc)) + return; + if (!list_empty(&area->free_list[mtype])) { + page = list_entry(area->free_list[mtype].next, + struct page, lru); + if (capture_free_page(page, cc->order, mtype)) { + spin_unlock_irqrestore(&cc->zone->lock, + flags); + *cc->page = page; + return; + } + } + spin_unlock_irqrestore(&cc->zone->lock, flags); + } + } +} + static int compact_zone(struct zone *zone, struct compact_control *cc) { int ret; @@ -995,6 +1054,9 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) goto out; } } + + /* Capture a page now if it is a suitable size */ + compact_capture_page(cc); } out: @@ -1007,7 +1069,8 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) static unsigned long compact_zone_order(struct zone *zone, int order, gfp_t gfp_mask, - bool sync, bool *contended) + bool sync, bool *contended, + struct page **page) { unsigned long ret; struct compact_control cc = { @@ -1017,6 +1080,7 @@ static unsigned long compact_zone_order(struct zone *zone, .migratetype = allocflags_to_migratetype(gfp_mask), .zone = zone, .sync = sync, + .page = page, }; INIT_LIST_HEAD(&cc.freepages); INIT_LIST_HEAD(&cc.migratepages); @@ -1046,7 +1110,7 @@ int sysctl_extfrag_threshold = 500; */ unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *nodemask, - bool sync, bool *contended) + bool sync, bool *contended, struct page **page) { enum zone_type high_zoneidx = gfp_zone(gfp_mask); int may_enter_fs = gfp_mask & __GFP_FS; @@ -1072,7 +1136,7 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, int status; status = compact_zone_order(zone, order, gfp_mask, sync, - contended); + contended, page); rc = max(status, rc); /* If a normal allocation would succeed, stop compacting */ @@ -1128,6 +1192,7 @@ int compact_pgdat(pg_data_t *pgdat, int order) struct compact_control cc = { .order = order, .sync = false, + .page = NULL, }; return __compact_pgdat(pgdat, &cc); @@ -1138,13 +1203,14 @@ static int compact_node(int nid) struct compact_control cc = { .order = -1, .sync = true, + .page = NULL, }; return __compact_pgdat(NODE_DATA(nid), &cc); } /* Compact all nodes in the system */ -static void compact_nodes(void) +static int compact_nodes(void) { int nid; @@ -1153,6 +1219,8 @@ static void compact_nodes(void) for_each_online_node(nid) compact_node(nid); + + return COMPACT_COMPLETE; } /* The written value is actually unused, all memory is compacted */ @@ -1163,7 +1231,7 @@ int sysctl_compaction_handler(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) { if (write) - compact_nodes(); + return compact_nodes(); return 0; } diff --git a/trunk/mm/huge_memory.c b/trunk/mm/huge_memory.c index 6001ee6347a9..9e894edc7811 100644 --- a/trunk/mm/huge_memory.c +++ b/trunk/mm/huge_memory.c @@ -1819,19 +1819,9 @@ int split_huge_page(struct page *page) BUG_ON(is_huge_zero_pfn(page_to_pfn(page))); BUG_ON(!PageAnon(page)); - - /* - * The caller does not necessarily hold an mmap_sem that would prevent - * the anon_vma disappearing so we first we take a reference to it - * and then lock the anon_vma for write. This is similar to - * page_lock_anon_vma_read except the write lock is taken to serialise - * against parallel split or collapse operations. - */ - anon_vma = page_get_anon_vma(page); + anon_vma = page_lock_anon_vma_read(page); if (!anon_vma) goto out; - anon_vma_lock_write(anon_vma); - ret = 0; if (!PageCompound(page)) goto out_unlock; @@ -1842,8 +1832,7 @@ int split_huge_page(struct page *page) BUG_ON(PageCompound(page)); out_unlock: - anon_vma_unlock(anon_vma); - put_anon_vma(anon_vma); + page_unlock_anon_vma_read(anon_vma); out: return ret; } diff --git a/trunk/mm/internal.h b/trunk/mm/internal.h index 9ba21100ebf3..d597f94cc205 100644 --- a/trunk/mm/internal.h +++ b/trunk/mm/internal.h @@ -135,6 +135,7 @@ struct compact_control { int migratetype; /* MOVABLE, RECLAIMABLE etc */ struct zone *zone; bool contended; /* True if a lock was contended */ + struct page **page; /* Page captured of requested size */ }; unsigned long diff --git a/trunk/mm/memblock.c b/trunk/mm/memblock.c index 88adc8afb610..625905523c2a 100644 --- a/trunk/mm/memblock.c +++ b/trunk/mm/memblock.c @@ -314,8 +314,7 @@ static void __init_memblock memblock_merge_regions(struct memblock_type *type) } this->size += next->size; - /* move forward from next + 1, index of which is i + 2 */ - memmove(next, next + 1, (type->cnt - (i + 2)) * sizeof(*next)); + memmove(next, next + 1, (type->cnt - (i + 1)) * sizeof(*next)); type->cnt--; } } diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index bb1369f7b9b4..49fb1cf08611 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -3711,14 +3711,6 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, if (pmd_trans_huge(orig_pmd)) { unsigned int dirty = flags & FAULT_FLAG_WRITE; - /* - * If the pmd is splitting, return and retry the - * the fault. Alternative: wait until the split - * is done, and goto retry. - */ - if (pmd_trans_splitting(orig_pmd)) - return 0; - if (pmd_numa(orig_pmd)) return do_huge_pmd_numa_page(mm, vma, address, orig_pmd, pmd); diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index c38778610aa8..3b676b0c5c3e 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -1679,21 +1679,9 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, page_xchg_last_nid(new_page, page_last_nid(page)); isolated = numamigrate_isolate_page(pgdat, page); - - /* - * Failing to isolate or a GUP pin prevents migration. The expected - * page count is 2. 1 for anonymous pages without a mapping and 1 - * for the callers pin. If the page was isolated, the page will - * need to be put back on the LRU. - */ - if (!isolated || page_count(page) != 2) { + if (!isolated) { count_vm_events(PGMIGRATE_FAIL, HPAGE_PMD_NR); put_page(new_page); - if (isolated) { - putback_lru_page(page); - isolated = 0; - goto out; - } goto out_keep_locked; } diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 35730ee9d515..f54b235f29a9 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -2886,7 +2886,7 @@ static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma) * The LSB of head.next can't change from under us * because we hold the mm_all_locks_mutex. */ - down_write_nest_lock(&anon_vma->root->rwsem, &mm->mmap_sem); + down_write(&anon_vma->root->rwsem); /* * We can safely modify head.next after taking the * anon_vma->root->rwsem. If some other vma in this mm shares diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index df2022ff0c8a..bc6cc0e913bd 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -1384,8 +1384,14 @@ void split_page(struct page *page, unsigned int order) set_page_refcounted(page + i); } -static int __isolate_free_page(struct page *page, unsigned int order) +/* + * Similar to the split_page family of functions except that the page + * required at the given order and being isolated now to prevent races + * with parallel allocators + */ +int capture_free_page(struct page *page, int alloc_order, int migratetype) { + unsigned int order; unsigned long watermark; struct zone *zone; int mt; @@ -1393,6 +1399,7 @@ static int __isolate_free_page(struct page *page, unsigned int order) BUG_ON(!PageBuddy(page)); zone = page_zone(page); + order = page_order(page); mt = get_pageblock_migratetype(page); if (mt != MIGRATE_ISOLATE) { @@ -1401,7 +1408,7 @@ static int __isolate_free_page(struct page *page, unsigned int order) if (!zone_watermark_ok(zone, 0, watermark, 0, 0)) return 0; - __mod_zone_freepage_state(zone, -(1UL << order), mt); + __mod_zone_freepage_state(zone, -(1UL << alloc_order), mt); } /* Remove page from free list */ @@ -1409,7 +1416,11 @@ static int __isolate_free_page(struct page *page, unsigned int order) zone->free_area[order].nr_free--; rmv_page_order(page); - /* Set the pageblock if the isolated page is at least a pageblock */ + if (alloc_order != order) + expand(zone, page, alloc_order, order, + &zone->free_area[order], migratetype); + + /* Set the pageblock if the captured page is at least a pageblock */ if (order >= pageblock_order - 1) { struct page *endpage = page + (1 << order) - 1; for (; page < endpage; page += pageblock_nr_pages) { @@ -1420,7 +1431,7 @@ static int __isolate_free_page(struct page *page, unsigned int order) } } - return 1UL << order; + return 1UL << alloc_order; } /* @@ -1438,9 +1449,10 @@ int split_free_page(struct page *page) unsigned int order; int nr_pages; + BUG_ON(!PageBuddy(page)); order = page_order(page); - nr_pages = __isolate_free_page(page, order); + nr_pages = capture_free_page(page, order, 0); if (!nr_pages) return 0; @@ -2124,6 +2136,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, bool *contended_compaction, bool *deferred_compaction, unsigned long *did_some_progress) { + struct page *page = NULL; + if (!order) return NULL; @@ -2135,12 +2149,16 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, current->flags |= PF_MEMALLOC; *did_some_progress = try_to_compact_pages(zonelist, order, gfp_mask, nodemask, sync_migration, - contended_compaction); + contended_compaction, &page); current->flags &= ~PF_MEMALLOC; - if (*did_some_progress != COMPACT_SKIPPED) { - struct page *page; + /* If compaction captured a page, prep and use it */ + if (page) { + prep_new_page(page, order, gfp_mask); + goto got_page; + } + if (*did_some_progress != COMPACT_SKIPPED) { /* Page migration frees to the PCP lists but we want merging */ drain_pages(get_cpu()); put_cpu(); @@ -2150,6 +2168,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, alloc_flags & ~ALLOC_NO_WATERMARKS, preferred_zone, migratetype); if (page) { +got_page: preferred_zone->compact_blockskip_flush = false; preferred_zone->compact_considered = 0; preferred_zone->compact_defer_shift = 0; @@ -5585,7 +5604,7 @@ static inline int pfn_to_bitidx(struct zone *zone, unsigned long pfn) pfn &= (PAGES_PER_SECTION-1); return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS; #else - pfn = pfn - round_down(zone->zone_start_pfn, pageblock_nr_pages); + pfn = pfn - zone->zone_start_pfn; return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS; #endif /* CONFIG_SPARSEMEM */ } diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index f64e439b4a00..515473ee52cb 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -6121,14 +6121,6 @@ struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) static const struct ethtool_ops default_ethtool_ops; -void netdev_set_default_ethtool_ops(struct net_device *dev, - const struct ethtool_ops *ops) -{ - if (dev->ethtool_ops == &default_ethtool_ops) - dev->ethtool_ops = ops; -} -EXPORT_SYMBOL_GPL(netdev_set_default_ethtool_ops); - /** * alloc_netdev_mqs - allocate network device * @sizeof_priv: size of private data to allocate space for diff --git a/trunk/net/core/request_sock.c b/trunk/net/core/request_sock.c index 4425148d2b51..c31d9e8668c3 100644 --- a/trunk/net/core/request_sock.c +++ b/trunk/net/core/request_sock.c @@ -186,6 +186,8 @@ void reqsk_fastopen_remove(struct sock *sk, struct request_sock *req, struct fastopen_queue *fastopenq = inet_csk(lsk)->icsk_accept_queue.fastopenq; + BUG_ON(!spin_is_locked(&sk->sk_lock.slock) && !sock_owned_by_user(sk)); + tcp_sk(sk)->fastopen_rsk = NULL; spin_lock_bh(&fastopenq->lock); fastopenq->qlen--; diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 2aa69c8ae60c..1ca253635f7a 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -1428,12 +1428,12 @@ static void tcp_service_net_dma(struct sock *sk, bool wait) } #endif -static struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) +static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) { struct sk_buff *skb; u32 offset; - while ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) { + skb_queue_walk(&sk->sk_receive_queue, skb) { offset = seq - TCP_SKB_CB(skb)->seq; if (tcp_hdr(skb)->syn) offset--; @@ -1441,11 +1441,6 @@ static struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) *off = offset; return skb; } - /* This looks weird, but this can happen if TCP collapsing - * splitted a fat GRO packet, while we released socket lock - * in skb_splice_bits() - */ - sk_eat_skb(sk, skb, false); } return NULL; } @@ -1487,7 +1482,7 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, break; } used = recv_actor(desc, skb, offset, len); - if (used <= 0) { + if (used < 0) { if (!copied) copied = used; break; @@ -1525,10 +1520,8 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, tcp_rcv_space_adjust(sk); /* Clean up data we have read: This will do ACK frames. */ - if (copied > 0) { - tcp_recv_skb(sk, seq, &offset); + if (copied > 0) tcp_cleanup_rbuf(sk, copied); - } return copied; } EXPORT_SYMBOL(tcp_read_sock); diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 18f97ca76b00..a28e4db8a952 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -5543,7 +5543,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, if (len < (th->doff << 2) || tcp_checksum_complete_user(sk, skb)) goto csum_error; - if (!th->ack && !th->rst) + if (!th->ack) goto discard; /* @@ -5988,7 +5988,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, goto discard; } - if (!th->ack && !th->rst) + if (!th->ack) goto discard; if (!tcp_validate_incoming(sk, skb, th, 0)) diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index 420e56326384..408cac4ae00a 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -154,11 +154,6 @@ static void addrconf_type_change(struct net_device *dev, unsigned long event); static int addrconf_ifdown(struct net_device *dev, int how); -static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, - int plen, - const struct net_device *dev, - u32 flags, u32 noflags); - static void addrconf_dad_start(struct inet6_ifaddr *ifp); static void addrconf_dad_timer(unsigned long data); static void addrconf_dad_completed(struct inet6_ifaddr *ifp); @@ -255,6 +250,12 @@ static inline bool addrconf_qdisc_ok(const struct net_device *dev) return !qdisc_tx_is_noop(dev); } +/* Check if a route is valid prefix route */ +static inline int addrconf_is_prefix_route(const struct rt6_info *rt) +{ + return (rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0; +} + static void addrconf_del_timer(struct inet6_ifaddr *ifp) { if (del_timer(&ifp->timer)) @@ -940,15 +941,17 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) { struct in6_addr prefix; struct rt6_info *rt; + struct net *net = dev_net(ifp->idev->dev); + struct flowi6 fl6 = {}; ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); + fl6.flowi6_oif = ifp->idev->dev->ifindex; + fl6.daddr = prefix; + rt = (struct rt6_info *)ip6_route_lookup(net, &fl6, + RT6_LOOKUP_F_IFACE); - rt = addrconf_get_prefix_route(&prefix, - ifp->prefix_len, - ifp->idev->dev, - 0, RTF_GATEWAY | RTF_DEFAULT); - - if (rt) { + if (rt != net->ipv6.ip6_null_entry && + addrconf_is_prefix_route(rt)) { if (onlink == 0) { ip6_del_rt(rt); rt = NULL; @@ -1874,7 +1877,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, continue; if ((rt->rt6i_flags & flags) != flags) continue; - if ((rt->rt6i_flags & noflags) != 0) + if ((noflags != 0) && ((rt->rt6i_flags & flags) != 0)) continue; dst_hold(&rt->dst); break; diff --git a/trunk/net/iucv/iucv.c b/trunk/net/iucv/iucv.c index df082508362d..3ad1f9db5f8b 100644 --- a/trunk/net/iucv/iucv.c +++ b/trunk/net/iucv/iucv.c @@ -1806,7 +1806,7 @@ static void iucv_external_interrupt(struct ext_code ext_code, struct iucv_irq_data *p; struct iucv_irq_list *work; - inc_irq_stat(IRQEXT_IUC); + kstat_cpu(smp_processor_id()).irqs[EXTINT_IUC]++; p = iucv_irq_data[smp_processor_id()]; if (p->ippathid >= iucv_max_pathid) { WARN_ON(p->ippathid >= iucv_max_pathid); diff --git a/trunk/net/netfilter/xt_CT.c b/trunk/net/netfilter/xt_CT.c index 2a0843081840..bde009ed8d3b 100644 --- a/trunk/net/netfilter/xt_CT.c +++ b/trunk/net/netfilter/xt_CT.c @@ -109,7 +109,7 @@ static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par) struct xt_ct_target_info *info = par->targinfo; struct nf_conntrack_tuple t; struct nf_conn *ct; - int ret; + int ret = -EOPNOTSUPP; if (info->flags & ~XT_CT_NOTRACK) return -EINVAL; @@ -247,7 +247,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) struct xt_ct_target_info_v1 *info = par->targinfo; struct nf_conntrack_tuple t; struct nf_conn *ct; - int ret; + int ret = -EOPNOTSUPP; if (info->flags & ~XT_CT_NOTRACK) return -EINVAL; diff --git a/trunk/net/sunrpc/clnt.c b/trunk/net/sunrpc/clnt.c index 507b5e84fbdb..1915ffe598e3 100644 --- a/trunk/net/sunrpc/clnt.c +++ b/trunk/net/sunrpc/clnt.c @@ -555,7 +555,7 @@ EXPORT_SYMBOL_GPL(rpc_clone_client); * rpc_clone_client_set_auth - Clone an RPC client structure and set its auth * * @clnt: RPC client whose parameters are copied - * @flavor: security flavor for new client + * @auth: security flavor for new client * * Returns a fresh RPC client or an ERR_PTR. */ diff --git a/trunk/net/sunrpc/sched.c b/trunk/net/sunrpc/sched.c index bfa31714581f..b4133bd13915 100644 --- a/trunk/net/sunrpc/sched.c +++ b/trunk/net/sunrpc/sched.c @@ -972,7 +972,8 @@ static void rpc_async_release(struct work_struct *work) static void rpc_release_resources_task(struct rpc_task *task) { - xprt_release(task); + if (task->tk_rqstp) + xprt_release(task); if (task->tk_msg.rpc_cred) { put_rpccred(task->tk_msg.rpc_cred); task->tk_msg.rpc_cred = NULL; diff --git a/trunk/net/sunrpc/xprt.c b/trunk/net/sunrpc/xprt.c index 33811db8788a..bd462a532acf 100644 --- a/trunk/net/sunrpc/xprt.c +++ b/trunk/net/sunrpc/xprt.c @@ -1136,18 +1136,10 @@ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt) void xprt_release(struct rpc_task *task) { struct rpc_xprt *xprt; - struct rpc_rqst *req = task->tk_rqstp; + struct rpc_rqst *req; - if (req == NULL) { - if (task->tk_client) { - rcu_read_lock(); - xprt = rcu_dereference(task->tk_client->cl_xprt); - if (xprt->snd_task == task) - xprt_release_write(xprt, task); - rcu_read_unlock(); - } + if (!(req = task->tk_rqstp)) return; - } xprt = req->rq_xprt; if (task->tk_ops->rpc_count_stats != NULL) diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index b677eab55b68..14d990400354 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -866,7 +866,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, /* allow mac80211 to determine the timeout */ wdev->ps_timeout = -1; - netdev_set_default_ethtool_ops(dev, &cfg80211_ethtool_ops); + if (!dev->ethtool_ops) + dev->ethtool_ops = &cfg80211_ethtool_ops; if ((wdev->iftype == NL80211_IFTYPE_STATION || wdev->iftype == NL80211_IFTYPE_P2P_CLIENT || diff --git a/trunk/security/capability.c b/trunk/security/capability.c index 579775088967..0fe5a026aef8 100644 --- a/trunk/security/capability.c +++ b/trunk/security/capability.c @@ -709,31 +709,16 @@ static void cap_req_classify_flow(const struct request_sock *req, { } -static int cap_tun_dev_alloc_security(void **security) -{ - return 0; -} - -static void cap_tun_dev_free_security(void *security) -{ -} - static int cap_tun_dev_create(void) { return 0; } -static int cap_tun_dev_attach_queue(void *security) -{ - return 0; -} - -static int cap_tun_dev_attach(struct sock *sk, void *security) +static void cap_tun_dev_post_create(struct sock *sk) { - return 0; } -static int cap_tun_dev_open(void *security) +static int cap_tun_dev_attach(struct sock *sk) { return 0; } @@ -1065,11 +1050,8 @@ void __init security_fixup_ops(struct security_operations *ops) set_to_cap_if_null(ops, secmark_refcount_inc); set_to_cap_if_null(ops, secmark_refcount_dec); set_to_cap_if_null(ops, req_classify_flow); - set_to_cap_if_null(ops, tun_dev_alloc_security); - set_to_cap_if_null(ops, tun_dev_free_security); set_to_cap_if_null(ops, tun_dev_create); - set_to_cap_if_null(ops, tun_dev_open); - set_to_cap_if_null(ops, tun_dev_attach_queue); + set_to_cap_if_null(ops, tun_dev_post_create); set_to_cap_if_null(ops, tun_dev_attach); #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM diff --git a/trunk/security/security.c b/trunk/security/security.c index 7b88c6aeaed4..daa97f4ac9d1 100644 --- a/trunk/security/security.c +++ b/trunk/security/security.c @@ -1254,42 +1254,24 @@ void security_secmark_refcount_dec(void) } EXPORT_SYMBOL(security_secmark_refcount_dec); -int security_tun_dev_alloc_security(void **security) -{ - return security_ops->tun_dev_alloc_security(security); -} -EXPORT_SYMBOL(security_tun_dev_alloc_security); - -void security_tun_dev_free_security(void *security) -{ - security_ops->tun_dev_free_security(security); -} -EXPORT_SYMBOL(security_tun_dev_free_security); - int security_tun_dev_create(void) { return security_ops->tun_dev_create(); } EXPORT_SYMBOL(security_tun_dev_create); -int security_tun_dev_attach_queue(void *security) +void security_tun_dev_post_create(struct sock *sk) { - return security_ops->tun_dev_attach_queue(security); + return security_ops->tun_dev_post_create(sk); } -EXPORT_SYMBOL(security_tun_dev_attach_queue); +EXPORT_SYMBOL(security_tun_dev_post_create); -int security_tun_dev_attach(struct sock *sk, void *security) +int security_tun_dev_attach(struct sock *sk) { - return security_ops->tun_dev_attach(sk, security); + return security_ops->tun_dev_attach(sk); } EXPORT_SYMBOL(security_tun_dev_attach); -int security_tun_dev_open(void *security) -{ - return security_ops->tun_dev_open(security); -} -EXPORT_SYMBOL(security_tun_dev_open); - #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index ef26e9611ffb..61a53367d029 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -4399,24 +4399,6 @@ static void selinux_req_classify_flow(const struct request_sock *req, fl->flowi_secid = req->secid; } -static int selinux_tun_dev_alloc_security(void **security) -{ - struct tun_security_struct *tunsec; - - tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL); - if (!tunsec) - return -ENOMEM; - tunsec->sid = current_sid(); - - *security = tunsec; - return 0; -} - -static void selinux_tun_dev_free_security(void *security) -{ - kfree(security); -} - static int selinux_tun_dev_create(void) { u32 sid = current_sid(); @@ -4432,17 +4414,8 @@ static int selinux_tun_dev_create(void) NULL); } -static int selinux_tun_dev_attach_queue(void *security) +static void selinux_tun_dev_post_create(struct sock *sk) { - struct tun_security_struct *tunsec = security; - - return avc_has_perm(current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET, - TUN_SOCKET__ATTACH_QUEUE, NULL); -} - -static int selinux_tun_dev_attach(struct sock *sk, void *security) -{ - struct tun_security_struct *tunsec = security; struct sk_security_struct *sksec = sk->sk_security; /* we don't currently perform any NetLabel based labeling here and it @@ -4452,19 +4425,20 @@ static int selinux_tun_dev_attach(struct sock *sk, void *security) * cause confusion to the TUN user that had no idea network labeling * protocols were being used */ - sksec->sid = tunsec->sid; - sksec->sclass = SECCLASS_TUN_SOCKET; + /* see the comments in selinux_tun_dev_create() about why we don't use + * the sockcreate SID here */ - return 0; + sksec->sid = current_sid(); + sksec->sclass = SECCLASS_TUN_SOCKET; } -static int selinux_tun_dev_open(void *security) +static int selinux_tun_dev_attach(struct sock *sk) { - struct tun_security_struct *tunsec = security; + struct sk_security_struct *sksec = sk->sk_security; u32 sid = current_sid(); int err; - err = avc_has_perm(sid, tunsec->sid, SECCLASS_TUN_SOCKET, + err = avc_has_perm(sid, sksec->sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__RELABELFROM, NULL); if (err) return err; @@ -4472,7 +4446,8 @@ static int selinux_tun_dev_open(void *security) TUN_SOCKET__RELABELTO, NULL); if (err) return err; - tunsec->sid = sid; + + sksec->sid = sid; return 0; } @@ -5667,12 +5642,9 @@ static struct security_operations selinux_ops = { .secmark_refcount_inc = selinux_secmark_refcount_inc, .secmark_refcount_dec = selinux_secmark_refcount_dec, .req_classify_flow = selinux_req_classify_flow, - .tun_dev_alloc_security = selinux_tun_dev_alloc_security, - .tun_dev_free_security = selinux_tun_dev_free_security, .tun_dev_create = selinux_tun_dev_create, - .tun_dev_attach_queue = selinux_tun_dev_attach_queue, + .tun_dev_post_create = selinux_tun_dev_post_create, .tun_dev_attach = selinux_tun_dev_attach, - .tun_dev_open = selinux_tun_dev_open, #ifdef CONFIG_SECURITY_NETWORK_XFRM .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, diff --git a/trunk/security/selinux/include/classmap.h b/trunk/security/selinux/include/classmap.h index 14d04e63b1f0..df2de54a958d 100644 --- a/trunk/security/selinux/include/classmap.h +++ b/trunk/security/selinux/include/classmap.h @@ -150,6 +150,6 @@ struct security_class_mapping secclass_map[] = { NULL } }, { "kernel_service", { "use_as_override", "create_files_as", NULL } }, { "tun_socket", - { COMMON_SOCK_PERMS, "attach_queue", NULL } }, + { COMMON_SOCK_PERMS, NULL } }, { NULL } }; diff --git a/trunk/security/selinux/include/objsec.h b/trunk/security/selinux/include/objsec.h index aa47bcabb5f6..26c7eee1c309 100644 --- a/trunk/security/selinux/include/objsec.h +++ b/trunk/security/selinux/include/objsec.h @@ -110,10 +110,6 @@ struct sk_security_struct { u16 sclass; /* sock security class */ }; -struct tun_security_struct { - u32 sid; /* SID for the tun device sockets */ -}; - struct key_security_struct { u32 sid; /* SID of key */ }; diff --git a/trunk/sound/arm/pxa2xx-ac97-lib.c b/trunk/sound/arm/pxa2xx-ac97-lib.c index fff7753e35c1..6fc0ae90e5b1 100644 --- a/trunk/sound/arm/pxa2xx-ac97-lib.c +++ b/trunk/sound/arm/pxa2xx-ac97-lib.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -149,8 +148,6 @@ static inline void pxa_ac97_warm_pxa27x(void) static inline void pxa_ac97_cold_pxa27x(void) { - unsigned int timeout; - GCR &= GCR_COLD_RST; /* clear everything but nCRST */ GCR &= ~GCR_COLD_RST; /* then assert nCRST */ @@ -160,10 +157,8 @@ static inline void pxa_ac97_cold_pxa27x(void) clk_enable(ac97conf_clk); udelay(5); clk_disable(ac97conf_clk); - GCR = GCR_COLD_RST | GCR_WARM_RST; - timeout = 100; /* wait for the codec-ready bit to be set */ - while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--) - mdelay(1); + GCR = GCR_COLD_RST; + udelay(50); } #endif @@ -345,21 +340,8 @@ int pxa2xx_ac97_hw_probe(struct platform_device *dev) } if (cpu_is_pxa27x()) { - /* - * This gpio is needed for a work-around to a bug in the ac97 - * controller during warm reset. The direction and level is set - * here so that it is an output driven high when switching from - * AC97_nRESET alt function to generic gpio. - */ - ret = gpio_request_one(reset_gpio, GPIOF_OUT_INIT_HIGH, - "pxa27x ac97 reset"); - if (ret < 0) { - pr_err("%s: gpio_request_one() failed: %d\n", - __func__, ret); - goto err_conf; - } + /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa27x_assert_ac97reset(reset_gpio, 0); - ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); if (IS_ERR(ac97conf_clk)) { ret = PTR_ERR(ac97conf_clk); @@ -402,8 +384,6 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe); void pxa2xx_ac97_hw_remove(struct platform_device *dev) { - if (cpu_is_pxa27x()) - gpio_free(reset_gpio); GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); if (ac97conf_clk) { diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index 0b6aebacc56b..cca87277baf0 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -573,12 +573,9 @@ enum { #define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ /* quirks for Intel PCH */ -#define AZX_DCAPS_INTEL_PCH_NOPM \ - (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \ - AZX_DCAPS_COUNT_LPIB_DELAY) - #define AZX_DCAPS_INTEL_PCH \ - (AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_PM_RUNTIME) + (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \ + AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_PM_RUNTIME) /* quirks for ATI SB / AMD Hudson */ #define AZX_DCAPS_PRESET_ATI_SB \ @@ -3589,13 +3586,13 @@ static void azx_remove(struct pci_dev *pci) static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* CPT */ { PCI_DEVICE(0x8086, 0x1c20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* PBG */ { PCI_DEVICE(0x8086, 0x1d20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Panther Point */ { PCI_DEVICE(0x8086, 0x1e20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Lynx Point */ { PCI_DEVICE(0x8086, 0x8c20), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c index dd798c3196ff..60890bfecc19 100644 --- a/trunk/sound/pci/hda/patch_conexant.c +++ b/trunk/sound/pci/hda/patch_conexant.c @@ -558,12 +558,24 @@ static int conexant_build_controls(struct hda_codec *codec) return 0; } +#ifdef CONFIG_PM +static int conexant_suspend(struct hda_codec *codec) +{ + snd_hda_shutup_pins(codec); + return 0; +} +#endif + static const struct hda_codec_ops conexant_patch_ops = { .build_controls = conexant_build_controls, .build_pcms = conexant_build_pcms, .init = conexant_init, .free = conexant_free, .set_power_state = conexant_set_power, +#ifdef CONFIG_PM + .suspend = conexant_suspend, +#endif + .reboot_notify = snd_hda_shutup_pins, }; #ifdef CONFIG_SND_HDA_INPUT_BEEP @@ -4393,6 +4405,10 @@ static const struct hda_codec_ops cx_auto_patch_ops = { .init = cx_auto_init, .free = conexant_free, .unsol_event = snd_hda_jack_unsol_event, +#ifdef CONFIG_PM + .suspend = conexant_suspend, +#endif + .reboot_notify = snd_hda_shutup_pins, }; /* diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index f5196277b6e9..71ae23dd7103 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -5817,9 +5817,6 @@ enum { ALC269_TYPE_ALC269VB, ALC269_TYPE_ALC269VC, ALC269_TYPE_ALC269VD, - ALC269_TYPE_ALC280, - ALC269_TYPE_ALC282, - ALC269_TYPE_ALC284, }; /* @@ -5836,13 +5833,10 @@ static int alc269_parse_auto_config(struct hda_codec *codec) switch (spec->codec_variant) { case ALC269_TYPE_ALC269VA: case ALC269_TYPE_ALC269VC: - case ALC269_TYPE_ALC280: - case ALC269_TYPE_ALC284: ssids = alc269va_ssids; break; case ALC269_TYPE_ALC269VB: case ALC269_TYPE_ALC269VD: - case ALC269_TYPE_ALC282: ssids = alc269_ssids; break; default: @@ -6406,8 +6400,7 @@ static int patch_alc269(struct hda_codec *codec) alc_auto_parse_customize_define(codec); - switch (codec->vendor_id) { - case 0x10ec0269: + if (codec->vendor_id == 0x10ec0269) { spec->codec_variant = ALC269_TYPE_ALC269VA; switch (alc_get_coef0(codec) & 0x00f0) { case 0x0010: @@ -6432,20 +6425,6 @@ static int patch_alc269(struct hda_codec *codec) goto error; spec->init_hook = alc269_fill_coef; alc269_fill_coef(codec); - break; - - case 0x10ec0280: - case 0x10ec0290: - spec->codec_variant = ALC269_TYPE_ALC280; - break; - case 0x10ec0282: - case 0x10ec0283: - spec->codec_variant = ALC269_TYPE_ALC282; - break; - case 0x10ec0284: - case 0x10ec0292: - spec->codec_variant = ALC269_TYPE_ALC284; - break; } /* automatic parse from the BIOS config */ @@ -7150,7 +7129,6 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, - { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", diff --git a/trunk/sound/pci/rme9652/hdspm.c b/trunk/sound/pci/rme9652/hdspm.c index 223c3d9cc69e..6e02e064d7b4 100644 --- a/trunk/sound/pci/rme9652/hdspm.c +++ b/trunk/sound/pci/rme9652/hdspm.c @@ -441,7 +441,6 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); */ /* status */ #define HDSPM_AES32_wcLock 0x0200000 -#define HDSPM_AES32_wcSync 0x0100000 #define HDSPM_AES32_wcFreq_bit 22 /* (status >> HDSPM_AES32_wcFreq_bit) & 0xF gives WC frequency (cf function HDSPM_bit2freq */ @@ -3468,12 +3467,10 @@ static int hdspm_wc_sync_check(struct hdspm *hdspm) switch (hdspm->io_type) { case AES32: status = hdspm_read(hdspm, HDSPM_statusRegister); - if (status & HDSPM_AES32_wcLock) { - if (status & HDSPM_AES32_wcSync) - return 2; - else - return 1; - } + if (status & HDSPM_wcSync) + return 2; + else if (status & HDSPM_wcLock) + return 1; return 0; break; @@ -4661,7 +4658,6 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, unsigned int status; unsigned int status2; unsigned int timecode; - unsigned int wcLock, wcSync; int pref_syncref; char *autosync_ref; int x; @@ -4755,11 +4751,8 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, snd_iprintf(buffer, "--- Status:\n"); - wcLock = status & HDSPM_AES32_wcLock; - wcSync = wcLock && (status & HDSPM_AES32_wcSync); - snd_iprintf(buffer, "Word: %s Frequency: %d\n", - (wcLock) ? (wcSync ? "Sync " : "Lock ") : "No Lock", + (status & HDSPM_AES32_wcLock) ? "Sync " : "No Lock", HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF)); for (x = 0; x < 8; x++) { diff --git a/trunk/sound/soc/codecs/arizona.c b/trunk/sound/soc/codecs/arizona.c index 1d8bb5917594..adf397b9d0e6 100644 --- a/trunk/sound/soc/codecs/arizona.c +++ b/trunk/sound/soc/codecs/arizona.c @@ -446,9 +446,15 @@ static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) case SND_SOC_DAIFMT_DSP_A: mode = 0; break; + case SND_SOC_DAIFMT_DSP_B: + mode = 1; + break; case SND_SOC_DAIFMT_I2S: mode = 2; break; + case SND_SOC_DAIFMT_LEFT_J: + mode = 3; + break; default: arizona_aif_err(dai, "Unsupported DAI format %d\n", fmt & SND_SOC_DAIFMT_FORMAT_MASK); @@ -708,8 +714,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1, ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val); snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL, - ARIZONA_AIF1_RATE_MASK, - 8 << ARIZONA_AIF1_RATE_SHIFT); + ARIZONA_AIF1_RATE_MASK, 8); break; default: arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk); diff --git a/trunk/sound/soc/codecs/arizona.h b/trunk/sound/soc/codecs/arizona.h index 4deebeb07177..41dae1ed3b71 100644 --- a/trunk/sound/soc/codecs/arizona.h +++ b/trunk/sound/soc/codecs/arizona.h @@ -34,15 +34,15 @@ #define ARIZONA_FLL_SRC_MCLK1 0 #define ARIZONA_FLL_SRC_MCLK2 1 -#define ARIZONA_FLL_SRC_SLIMCLK 3 -#define ARIZONA_FLL_SRC_FLL1 4 -#define ARIZONA_FLL_SRC_FLL2 5 -#define ARIZONA_FLL_SRC_AIF1BCLK 8 -#define ARIZONA_FLL_SRC_AIF2BCLK 9 -#define ARIZONA_FLL_SRC_AIF3BCLK 10 -#define ARIZONA_FLL_SRC_AIF1LRCLK 12 -#define ARIZONA_FLL_SRC_AIF2LRCLK 13 -#define ARIZONA_FLL_SRC_AIF3LRCLK 14 +#define ARIZONA_FLL_SRC_SLIMCLK 2 +#define ARIZONA_FLL_SRC_FLL1 3 +#define ARIZONA_FLL_SRC_FLL2 4 +#define ARIZONA_FLL_SRC_AIF1BCLK 5 +#define ARIZONA_FLL_SRC_AIF2BCLK 6 +#define ARIZONA_FLL_SRC_AIF3BCLK 7 +#define ARIZONA_FLL_SRC_AIF1LRCLK 8 +#define ARIZONA_FLL_SRC_AIF2LRCLK 9 +#define ARIZONA_FLL_SRC_AIF3LRCLK 10 #define ARIZONA_MIXER_VOL_MASK 0x00FE #define ARIZONA_MIXER_VOL_SHIFT 1 diff --git a/trunk/sound/soc/codecs/cs4271.c b/trunk/sound/soc/codecs/cs4271.c index ac8742a1f25a..4f1127935fdf 100644 --- a/trunk/sound/soc/codecs/cs4271.c +++ b/trunk/sound/soc/codecs/cs4271.c @@ -474,16 +474,16 @@ static int cs4271_probe(struct snd_soc_codec *codec) struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; int ret; int gpio_nreset = -EINVAL; - bool amutec_eq_bmutec = false; + int amutec_eq_bmutec = 0; #ifdef CONFIG_OF if (of_match_device(cs4271_dt_ids, codec->dev)) { gpio_nreset = of_get_named_gpio(codec->dev->of_node, "reset-gpio", 0); - if (of_get_property(codec->dev->of_node, + if (!of_get_property(codec->dev->of_node, "cirrus,amutec-eq-bmutec", NULL)) - amutec_eq_bmutec = true; + amutec_eq_bmutec = 1; } #endif diff --git a/trunk/sound/soc/codecs/cs42l52.c b/trunk/sound/soc/codecs/cs42l52.c index 9811a5478c87..99bb1c69499e 100644 --- a/trunk/sound/soc/codecs/cs42l52.c +++ b/trunk/sound/soc/codecs/cs42l52.c @@ -737,7 +737,7 @@ static const struct cs42l52_clk_para clk_map_table[] = { static int cs42l52_get_clk(int mclk, int rate) { - int i, ret = -EINVAL; + int i, ret = 0; u_int mclk1, mclk2 = 0; for (i = 0; i < ARRAY_SIZE(clk_map_table); i++) { @@ -749,6 +749,8 @@ static int cs42l52_get_clk(int mclk, int rate) } } } + if (ret > ARRAY_SIZE(clk_map_table)) + return -EINVAL; return ret; } diff --git a/trunk/sound/soc/codecs/lm49453.c b/trunk/sound/soc/codecs/lm49453.c index e19490cfb3a8..d75257d40a49 100644 --- a/trunk/sound/soc/codecs/lm49453.c +++ b/trunk/sound/soc/codecs/lm49453.c @@ -111,9 +111,9 @@ static struct reg_default lm49453_reg_defs[] = { { 101, 0x00 }, { 102, 0x00 }, { 103, 0x01 }, - { 104, 0x01 }, - { 105, 0x00 }, - { 106, 0x01 }, + { 105, 0x01 }, + { 106, 0x00 }, + { 107, 0x01 }, { 107, 0x00 }, { 108, 0x00 }, { 109, 0x00 }, @@ -163,25 +163,56 @@ static struct reg_default lm49453_reg_defs[] = { { 184, 0x00 }, { 185, 0x00 }, { 186, 0x00 }, - { 187, 0x00 }, - { 188, 0x00 }, { 189, 0x00 }, - { 208, 0x06 }, + { 188, 0x00 }, + { 194, 0x00 }, + { 195, 0x00 }, + { 196, 0x00 }, + { 197, 0x00 }, + { 200, 0x00 }, + { 201, 0x00 }, + { 202, 0x00 }, + { 203, 0x00 }, + { 204, 0x00 }, + { 205, 0x00 }, + { 208, 0x00 }, { 209, 0x00 }, - { 210, 0x08 }, - { 211, 0x54 }, - { 212, 0x14 }, - { 213, 0x0d }, - { 214, 0x0d }, - { 215, 0x14 }, - { 216, 0x60 }, + { 210, 0x00 }, + { 211, 0x00 }, + { 213, 0x00 }, + { 214, 0x00 }, + { 215, 0x00 }, + { 216, 0x00 }, + { 217, 0x00 }, + { 218, 0x00 }, + { 219, 0x00 }, { 221, 0x00 }, { 222, 0x00 }, - { 223, 0x00 }, { 224, 0x00 }, + { 225, 0x00 }, + { 226, 0x00 }, + { 227, 0x00 }, + { 228, 0x00 }, + { 229, 0x00 }, + { 230, 0x13 }, + { 231, 0x00 }, + { 232, 0x80 }, + { 233, 0x0C }, + { 234, 0xDD }, + { 235, 0x00 }, + { 236, 0x04 }, + { 237, 0x00 }, + { 238, 0x00 }, + { 239, 0x00 }, + { 240, 0x00 }, + { 241, 0x00 }, + { 242, 0x00 }, + { 243, 0x00 }, + { 244, 0x00 }, + { 245, 0x00 }, { 248, 0x00 }, { 249, 0x00 }, - { 250, 0x00 }, + { 254, 0x00 }, { 255, 0x00 }, }; @@ -494,41 +525,36 @@ SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_PORT2_TX2_REG, 7, 1, 0), }; /* TLV Declarations */ -static const DECLARE_TLV_DB_SCALE(adc_dac_tlv, -7650, 150, 1); -static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 200, 1); -static const DECLARE_TLV_DB_SCALE(port_tlv, -1800, 600, 0); -static const DECLARE_TLV_DB_SCALE(stn_tlv, -7200, 150, 0); +static const DECLARE_TLV_DB_SCALE(digital_tlv, -7650, 150, 1); +static const DECLARE_TLV_DB_SCALE(port_tlv, 0, 600, 0); static const struct snd_kcontrol_new lm49453_sidetone_mixer_controls[] = { /* Sidetone supports mono only */ SOC_DAPM_SINGLE_TLV("Sidetone ADCL Volume", LM49453_P0_STN_VOL_ADCL_REG, - 0, 0x3F, 0, stn_tlv), + 0, 0x3F, 0, digital_tlv), SOC_DAPM_SINGLE_TLV("Sidetone ADCR Volume", LM49453_P0_STN_VOL_ADCR_REG, - 0, 0x3F, 0, stn_tlv), + 0, 0x3F, 0, digital_tlv), SOC_DAPM_SINGLE_TLV("Sidetone DMIC1L Volume", LM49453_P0_STN_VOL_DMIC1L_REG, - 0, 0x3F, 0, stn_tlv), + 0, 0x3F, 0, digital_tlv), SOC_DAPM_SINGLE_TLV("Sidetone DMIC1R Volume", LM49453_P0_STN_VOL_DMIC1R_REG, - 0, 0x3F, 0, stn_tlv), + 0, 0x3F, 0, digital_tlv), SOC_DAPM_SINGLE_TLV("Sidetone DMIC2L Volume", LM49453_P0_STN_VOL_DMIC2L_REG, - 0, 0x3F, 0, stn_tlv), + 0, 0x3F, 0, digital_tlv), SOC_DAPM_SINGLE_TLV("Sidetone DMIC2R Volume", LM49453_P0_STN_VOL_DMIC2R_REG, - 0, 0x3F, 0, stn_tlv), + 0, 0x3F, 0, digital_tlv), }; static const struct snd_kcontrol_new lm49453_snd_controls[] = { /* mic1 and mic2 supports mono only */ - SOC_SINGLE_TLV("Mic1 Volume", LM49453_P0_MICL_REG, 0, 15, 0, mic_tlv), - SOC_SINGLE_TLV("Mic2 Volume", LM49453_P0_MICR_REG, 0, 15, 0, mic_tlv), - - SOC_SINGLE_TLV("ADCL Volume", LM49453_P0_ADC_LEVELL_REG, 0, 63, - 0, adc_dac_tlv), - SOC_SINGLE_TLV("ADCR Volume", LM49453_P0_ADC_LEVELR_REG, 0, 63, - 0, adc_dac_tlv), + SOC_SINGLE_TLV("Mic1 Volume", LM49453_P0_ADC_LEVELL_REG, 0, 6, + 0, digital_tlv), + SOC_SINGLE_TLV("Mic2 Volume", LM49453_P0_ADC_LEVELR_REG, 0, 6, + 0, digital_tlv), SOC_DOUBLE_R_TLV("DMIC1 Volume", LM49453_P0_DMIC1_LEVELL_REG, - LM49453_P0_DMIC1_LEVELR_REG, 0, 63, 0, adc_dac_tlv), + LM49453_P0_DMIC1_LEVELR_REG, 0, 6, 0, digital_tlv), SOC_DOUBLE_R_TLV("DMIC2 Volume", LM49453_P0_DMIC2_LEVELL_REG, - LM49453_P0_DMIC2_LEVELR_REG, 0, 63, 0, adc_dac_tlv), + LM49453_P0_DMIC2_LEVELR_REG, 0, 6, 0, digital_tlv), SOC_DAPM_ENUM("Mic2Mode", lm49453_mic2mode_enum), SOC_DAPM_ENUM("DMIC12 SRC", lm49453_dmic12_cfg_enum), @@ -543,16 +569,16 @@ static const struct snd_kcontrol_new lm49453_snd_controls[] = { 2, 1, 0), SOC_DOUBLE_R_TLV("DAC HP Volume", LM49453_P0_DAC_HP_LEVELL_REG, - LM49453_P0_DAC_HP_LEVELR_REG, 0, 63, 0, adc_dac_tlv), + LM49453_P0_DAC_HP_LEVELR_REG, 0, 6, 0, digital_tlv), SOC_DOUBLE_R_TLV("DAC LO Volume", LM49453_P0_DAC_LO_LEVELL_REG, - LM49453_P0_DAC_LO_LEVELR_REG, 0, 63, 0, adc_dac_tlv), + LM49453_P0_DAC_LO_LEVELR_REG, 0, 6, 0, digital_tlv), SOC_DOUBLE_R_TLV("DAC LS Volume", LM49453_P0_DAC_LS_LEVELL_REG, - LM49453_P0_DAC_LS_LEVELR_REG, 0, 63, 0, adc_dac_tlv), + LM49453_P0_DAC_LS_LEVELR_REG, 0, 6, 0, digital_tlv), SOC_DOUBLE_R_TLV("DAC HA Volume", LM49453_P0_DAC_HA_LEVELL_REG, - LM49453_P0_DAC_HA_LEVELR_REG, 0, 63, 0, adc_dac_tlv), + LM49453_P0_DAC_HA_LEVELR_REG, 0, 6, 0, digital_tlv), SOC_SINGLE_TLV("EP Volume", LM49453_P0_DAC_LS_LEVELL_REG, - 0, 63, 0, adc_dac_tlv), + 0, 6, 0, digital_tlv), SOC_SINGLE_TLV("PORT1_1_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL1_REG, 0, 3, 0, port_tlv), @@ -1192,7 +1218,7 @@ static int lm49453_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) } snd_soc_update_bits(codec, LM49453_P0_AUDIO_PORT1_BASIC_REG, - LM49453_AUDIO_PORT1_BASIC_FMT_MASK|BIT(0)|BIT(5), + LM49453_AUDIO_PORT1_BASIC_FMT_MASK|BIT(1)|BIT(5), (aif_val | mode | clk_phase)); snd_soc_write(codec, LM49453_P0_AUDIO_PORT1_RX_MSB_REG, clk_shift); diff --git a/trunk/sound/soc/codecs/sgtl5000.c b/trunk/sound/soc/codecs/sgtl5000.c index 92bbfec9b107..cb1675cd8e1c 100644 --- a/trunk/sound/soc/codecs/sgtl5000.c +++ b/trunk/sound/soc/codecs/sgtl5000.c @@ -401,7 +401,7 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = { 5, 1, 0), SOC_SINGLE_TLV("Mic Volume", SGTL5000_CHIP_MIC_CTRL, - 0, 3, 0, mic_gain_tlv), + 0, 4, 0, mic_gain_tlv), }; /* mute the codec used by alsa core */ @@ -1344,7 +1344,7 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) SGTL5000_HP_ZCD_EN | SGTL5000_ADC_ZCD_EN); - snd_soc_write(codec, SGTL5000_CHIP_MIC_CTRL, 2); + snd_soc_write(codec, SGTL5000_CHIP_MIC_CTRL, 0); /* * disable DAP diff --git a/trunk/sound/soc/codecs/sta529.c b/trunk/sound/soc/codecs/sta529.c index 40c07be9b581..ab355c4f0b2d 100644 --- a/trunk/sound/soc/codecs/sta529.c +++ b/trunk/sound/soc/codecs/sta529.c @@ -74,10 +74,9 @@ SNDRV_PCM_FMTBIT_S32_LE) #define S2PC_VALUE 0x98 #define CLOCK_OUT 0x60 -#define DATA_FORMAT_MSK 0x0E -#define LEFT_J_DATA_FORMAT 0x00 -#define I2S_DATA_FORMAT 0x02 -#define RIGHT_J_DATA_FORMAT 0x04 +#define LEFT_J_DATA_FORMAT 0x10 +#define I2S_DATA_FORMAT 0x12 +#define RIGHT_J_DATA_FORMAT 0x14 #define CODEC_MUTE_VAL 0x80 #define POWER_CNTLMSAK 0x40 @@ -290,7 +289,7 @@ static int sta529_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt) return -EINVAL; } - snd_soc_update_bits(codec, STA529_S2PCFG0, DATA_FORMAT_MSK, mode); + snd_soc_update_bits(codec, STA529_S2PCFG0, 0x0D, mode); return 0; } diff --git a/trunk/sound/soc/codecs/wm2000.c b/trunk/sound/soc/codecs/wm2000.c index 12bcae63a7f0..1cbe88f01d63 100644 --- a/trunk/sound/soc/codecs/wm2000.c +++ b/trunk/sound/soc/codecs/wm2000.c @@ -209,9 +209,9 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) ret = wm2000_read(i2c, WM2000_REG_SPEECH_CLARITY); if (wm2000->speech_clarity) - ret |= WM2000_SPEECH_CLARITY; - else ret &= ~WM2000_SPEECH_CLARITY; + else + ret |= WM2000_SPEECH_CLARITY; wm2000_write(i2c, WM2000_REG_SPEECH_CLARITY, ret); wm2000_write(i2c, WM2000_REG_SYS_START0, 0x33); diff --git a/trunk/sound/soc/codecs/wm2200.c b/trunk/sound/soc/codecs/wm2200.c index e6cefe1ac677..afcf31df77e0 100644 --- a/trunk/sound/soc/codecs/wm2200.c +++ b/trunk/sound/soc/codecs/wm2200.c @@ -1566,9 +1566,15 @@ static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) case SND_SOC_DAIFMT_DSP_A: fmt_val = 0; break; + case SND_SOC_DAIFMT_DSP_B: + fmt_val = 1; + break; case SND_SOC_DAIFMT_I2S: fmt_val = 2; break; + case SND_SOC_DAIFMT_LEFT_J: + fmt_val = 3; + break; default: dev_err(codec->dev, "Unsupported DAI format %d\n", fmt & SND_SOC_DAIFMT_FORMAT_MASK); @@ -1620,7 +1626,7 @@ static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV, lrclk); snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_5, - WM2200_AIF1_FMT_MASK, fmt_val); + WM2200_AIF1_FMT_MASK << 1, fmt_val << 1); return 0; } diff --git a/trunk/sound/soc/codecs/wm5100.c b/trunk/sound/soc/codecs/wm5100.c index 54397a508073..5a5f36936235 100644 --- a/trunk/sound/soc/codecs/wm5100.c +++ b/trunk/sound/soc/codecs/wm5100.c @@ -1279,9 +1279,15 @@ static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) case SND_SOC_DAIFMT_DSP_A: mask = 0; break; + case SND_SOC_DAIFMT_DSP_B: + mask = 1; + break; case SND_SOC_DAIFMT_I2S: mask = 2; break; + case SND_SOC_DAIFMT_LEFT_J: + mask = 3; + break; default: dev_err(codec->dev, "Unsupported DAI format %d\n", fmt & SND_SOC_DAIFMT_FORMAT_MASK); diff --git a/trunk/sound/soc/codecs/wm5102.c b/trunk/sound/soc/codecs/wm5102.c index 7a9048dad1cd..688ade080589 100644 --- a/trunk/sound/soc/codecs/wm5102.c +++ b/trunk/sound/soc/codecs/wm5102.c @@ -36,9 +36,6 @@ struct wm5102_priv { struct arizona_priv core; struct arizona_fll fll[2]; - - unsigned int spk_ena:2; - unsigned int spk_ena_pending:1; }; static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); @@ -790,47 +787,6 @@ ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), }; -static int wm5102_spk_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = w->codec; - struct arizona *arizona = dev_get_drvdata(codec->dev->parent); - struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec); - - if (arizona->rev < 1) - return 0; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (!wm5102->spk_ena) { - snd_soc_write(codec, 0x4f5, 0x25a); - wm5102->spk_ena_pending = true; - } - break; - case SND_SOC_DAPM_POST_PMU: - if (wm5102->spk_ena_pending) { - msleep(75); - snd_soc_write(codec, 0x4f5, 0xda); - wm5102->spk_ena_pending = false; - wm5102->spk_ena++; - } - break; - case SND_SOC_DAPM_PRE_PMD: - wm5102->spk_ena--; - if (!wm5102->spk_ena) - snd_soc_write(codec, 0x4f5, 0x25a); - break; - case SND_SOC_DAPM_POST_PMD: - if (!wm5102->spk_ena) - snd_soc_write(codec, 0x4f5, 0x0da); - break; - } - - return 0; -} - - ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE); @@ -1078,10 +1034,10 @@ SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev, + ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev, + ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, diff --git a/trunk/sound/soc/codecs/wm_adsp.c b/trunk/sound/soc/codecs/wm_adsp.c index 7b198c38f3ef..ffc89fab96fb 100644 --- a/trunk/sound/soc/codecs/wm_adsp.c +++ b/trunk/sound/soc/codecs/wm_adsp.c @@ -169,7 +169,6 @@ static int wm_adsp_load(struct wm_adsp *dsp) const struct wm_adsp_region *mem; const char *region_name; char *file, *text; - void *buf; unsigned int reg; int regions = 0; int ret, offset, type, sizes; @@ -323,18 +322,8 @@ static int wm_adsp_load(struct wm_adsp *dsp) } if (reg) { - buf = kmemdup(region->data, le32_to_cpu(region->len), - GFP_KERNEL); - if (!buf) { - adsp_err(dsp, "Out of memory\n"); - return -ENOMEM; - } - - ret = regmap_raw_write(regmap, reg, buf, + ret = regmap_raw_write(regmap, reg, region->data, le32_to_cpu(region->len)); - - kfree(buf); - if (ret != 0) { adsp_err(dsp, "%s.%d: Failed to write %d bytes at %d in %s: %d\n", @@ -370,7 +359,6 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) const char *region_name; int ret, pos, blocks, type, offset, reg; char *file; - void *buf; file = kzalloc(PAGE_SIZE, GFP_KERNEL); if (file == NULL) @@ -438,13 +426,6 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) } if (reg) { - buf = kmemdup(blk->data, le32_to_cpu(blk->len), - GFP_KERNEL); - if (!buf) { - adsp_err(dsp, "Out of memory\n"); - return -ENOMEM; - } - ret = regmap_raw_write(regmap, reg, blk->data, le32_to_cpu(blk->len)); if (ret != 0) { @@ -452,8 +433,6 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) "%s.%d: Failed to write to %x in %s\n", file, blocks, reg, region_name); } - - kfree(buf); } pos += le32_to_cpu(blk->len) + sizeof(*blk); diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index 2370063b5824..91d592ff67b7 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -1255,8 +1255,6 @@ static int soc_post_component_init(struct snd_soc_card *card, INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients); ret = device_add(rtd->dev); if (ret < 0) { - /* calling put_device() here to free the rtd->dev */ - put_device(rtd->dev); dev_err(card->dev, "ASoC: failed to register runtime device: %d\n", ret); return ret; @@ -1556,7 +1554,7 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num) /* unregister the rtd device */ if (rtd->dev_registered) { device_remove_file(rtd->dev, &dev_attr_codec_reg); - device_unregister(rtd->dev); + device_del(rtd->dev); rtd->dev_registered = 0; } @@ -2919,7 +2917,7 @@ int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, platform_max = mc->platform_max; uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; + uinfo->count = 1; uinfo->value.integer.min = 0; uinfo->value.integer.max = platform_max - min; @@ -2943,14 +2941,12 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); unsigned int reg = mc->reg; - unsigned int rreg = mc->rreg; unsigned int shift = mc->shift; int min = mc->min; int max = mc->max; unsigned int mask = (1 << fls(max)) - 1; unsigned int invert = mc->invert; unsigned int val, val_mask; - int ret; val = ((ucontrol->value.integer.value[0] + min) & mask); if (invert) @@ -2958,21 +2954,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, val_mask = mask << shift; val = val << shift; - ret = snd_soc_update_bits_locked(codec, reg, val_mask, val); - if (ret != 0) - return ret; - - if (snd_soc_volsw_is_stereo(mc)) { - val = ((ucontrol->value.integer.value[1] + min) & mask); - if (invert) - val = max - val; - val_mask = mask << shift; - val = val << shift; - - ret = snd_soc_update_bits_locked(codec, rreg, val_mask, val); - } - - return ret; + return snd_soc_update_bits_locked(codec, reg, val_mask, val); } EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); @@ -2992,7 +2974,6 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); unsigned int reg = mc->reg; - unsigned int rreg = mc->rreg; unsigned int shift = mc->shift; int min = mc->min; int max = mc->max; @@ -3007,16 +2988,6 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[0] = ucontrol->value.integer.value[0] - min; - if (snd_soc_volsw_is_stereo(mc)) { - ucontrol->value.integer.value[1] = - (snd_soc_read(codec, rreg) >> shift) & mask; - if (invert) - ucontrol->value.integer.value[1] = - max - ucontrol->value.integer.value[1]; - ucontrol->value.integer.value[1] = - ucontrol->value.integer.value[1] - min; - } - return 0; } EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range); diff --git a/trunk/sound/soc/soc-pcm.c b/trunk/sound/soc/soc-pcm.c index cf191e6aebbe..d7711fce119b 100644 --- a/trunk/sound/soc/soc-pcm.c +++ b/trunk/sound/soc/soc-pcm.c @@ -1243,7 +1243,6 @@ static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) && - (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) continue; diff --git a/trunk/sound/usb/mixer_quirks.c b/trunk/sound/usb/mixer_quirks.c index 15520de1df56..0422b1360af3 100644 --- a/trunk/sound/usb/mixer_quirks.c +++ b/trunk/sound/usb/mixer_quirks.c @@ -1206,7 +1206,7 @@ static int snd_c400_create_mixer(struct usb_mixer_interface *mixer) * are valid they presents mono controls as L and R channels of * stereo. So we provide a good mixer here. */ -static struct std_mono_table ebox44_table[] = { +struct std_mono_table ebox44_table[] = { { .unitid = 4, .control = 1, diff --git a/trunk/sound/usb/pcm.c b/trunk/sound/usb/pcm.c index d82e378d37cb..c6593101c049 100644 --- a/trunk/sound/usb/pcm.c +++ b/trunk/sound/usb/pcm.c @@ -511,16 +511,6 @@ static int configure_sync_endpoint(struct snd_usb_substream *subs) struct snd_usb_substream *sync_subs = &subs->stream->substream[subs->direction ^ 1]; - if (subs->sync_endpoint->type != SND_USB_ENDPOINT_TYPE_DATA || - !subs->stream) - return snd_usb_endpoint_set_params(subs->sync_endpoint, - subs->pcm_format, - subs->channels, - subs->period_bytes, - subs->cur_rate, - subs->cur_audiofmt, - NULL); - /* Try to find the best matching audioformat. */ list_for_each_entry(fp, &sync_subs->fmt_list, list) { int score = match_endpoint_audioformats(fp, subs->cur_audiofmt,