Merge tag 'usb-3.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 10 Aug 2013 16:00:21 +0000 (09:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 10 Aug 2013 16:00:21 +0000 (09:00 -0700)
Pull USB fixes from Greg KH:
 "Here are 3 small USB fixes for 3.11-rc5.

  One is a fix that the ChromeOS developers ran into on some Intel
  hardware, one is a build fix, and the last is a MAINTAINERS update to
  help people figure out where to send USB network driver patches.

  All of these have been in linux-next for a while"

* tag 'usb-3.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  MAINTAINERS: Add separate section for USB NETWORKING DRIVERS
  usb: xhci: add missing dma-mapping.h includes
  usb: core: don't try to reset_device() a port that got just disconnected

133 files changed:
Documentation/DocBook/media_api.tmpl
Documentation/devicetree/bindings/regulator/palmas-pmic.txt
MAINTAINERS
arch/arm/boot/dts/msm8960-cdp.dts
arch/arm/boot/dts/omap5-uevm.dts
arch/arm/boot/dts/stih41x.dtsi
arch/arm/boot/dts/tegra20-colibri-512.dtsi
arch/arm/mach-msm/Kconfig
arch/arm/mach-msm/gpiomux-v1.c [deleted file]
arch/arm/mach-msm/gpiomux.h
arch/arm/mach-omap2/dss-common.c
arch/arm/mach-omap2/omap_device.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod.h
arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
arch/arm/mach-omap2/omap_hwmod_33xx_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/omap_hwmod_54xx_data.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-shmobile/board-armadillo800eva.c
arch/arm/mach-shmobile/board-bockw.c
arch/arm/mach-shmobile/board-lager.c
arch/arm/mach-sti/headsmp.S
arch/avr32/boards/atngw100/mrmt.c
arch/mips/include/asm/cpu-features.h
arch/mips/kernel/smp-bmips.c
arch/mips/oprofile/op_model_mipsxx.c
arch/mips/pnx833x/common/platform.c
arch/s390/Kconfig
arch/s390/boot/compressed/Makefile
arch/s390/boot/compressed/misc.c
arch/s390/include/asm/bitops.h
arch/s390/kernel/perf_event.c
arch/s390/kernel/setup.c
arch/s390/mm/init.c
arch/s390/oprofile/init.c
arch/x86/boot/compressed/eboot.c
arch/x86/kernel/early-quirks.c
arch/x86/kernel/i387.c
arch/x86/kernel/microcode_amd.c
drivers/acpi/acpi_processor.c
drivers/acpi/glue.c
drivers/acpi/proc.c
drivers/acpi/video.c
drivers/ata/pata_imx.c
drivers/base/regmap/regcache.c
drivers/char/virtio_console.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_governor.c
drivers/cpufreq/cpufreq_governor.h
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/loongson2_cpufreq.c
drivers/dma/sh/shdma.c
drivers/gpu/drm/ast/ast_ttm.c
drivers/gpu/drm/cirrus/cirrus_ttm.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/mgag200/mgag200_ttm.c
drivers/gpu/drm/radeon/btc_dpm.c
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/cypress_dpm.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_hdmi.c
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/ni_dpm.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_hdmi.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_fence.c
drivers/gpu/drm/radeon/radeon_gart.c
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/radeon_uvd.c
drivers/gpu/drm/radeon/rv6xx_dpm.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/rv770_dpm.c
drivers/gpu/drm/radeon/rv770_dpm.h
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/radeon/si_dpm.c
drivers/hid/hid-logitech-dj.c
drivers/hwmon/adt7470.c
drivers/media/i2c/ml86v7667.c
drivers/media/platform/coda.c
drivers/media/platform/s5p-g2d/g2d.c
drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
drivers/media/usb/em28xx/em28xx-i2c.c
drivers/media/usb/hdpvr/hdpvr-core.c
drivers/media/usb/usbtv/Kconfig
drivers/media/usb/usbtv/usbtv.c
drivers/pci/pci-acpi.c
drivers/s390/block/dasd.c
drivers/scsi/virtio_scsi.c
drivers/spi/spi-davinci.c
drivers/video/mxsfb.c
drivers/video/omap2/displays-new/connector-analog-tv.c
fs/debugfs/inode.c
fs/dlm/user.c
fs/ext4/extents.c
fs/ext4/ialloc.c
fs/ext4/inode.c
fs/ext4/super.c
fs/fcntl.c
fs/namei.c
fs/open.c
fs/reiserfs/procfs.c
fs/reiserfs/super.c
include/acpi/acpi_bus.h
include/linux/ftrace_event.h
include/linux/kernel.h
include/linux/regmap.h
include/linux/user_namespace.h
include/media/v4l2-ctrls.h
kernel/cgroup.c
kernel/printk/braille.c
kernel/ptrace.c
kernel/trace/ftrace.c
kernel/trace/trace.c
kernel/trace/trace_events.c
kernel/trace/trace_events_filter.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_uprobe.c
kernel/user_namespace.c
kernel/workqueue.c
mm/slub.c
security/smack/smack_lsm.c

index 6a8b715..9c92bb8 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-       "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+       "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
 <!ENTITY % media-entities SYSTEM "./media-entities.tmpl"> %media-entities;
 <!ENTITY media-indices SYSTEM "./media-indices.tmpl">
 
index d5a3086..30b0581 100644 (file)
@@ -31,9 +31,8 @@ Optional nodes:
               Optional sub-node properties:
               ti,warm-reset - maintain voltage during warm reset(boolean)
               ti,roof-floor - control voltage selection by pin(boolean)
-              ti,sleep-mode - mode to adopt in pmic sleep 0 - off, 1 - auto,
+              ti,mode-sleep - mode to adopt in pmic sleep 0 - off, 1 - auto,
               2 - eco, 3 - forced pwm
-              ti,tstep - slope control 0 - Jump, 1 10mV/us, 2 5mV/us, 3 2.5mV/us
               ti,smps-range - OTP has the wrong range set for the hardware so override
               0 - low range, 1 - high range.
 
@@ -59,7 +58,6 @@ pmic {
                        ti,warm-reset;
                        ti,roof-floor;
                        ti,mode-sleep = <0>;
-                       ti,tstep = <0>;
                        ti,smps-range = <1>;
                };
 
index 7078e04..7cacc88 100644 (file)
@@ -965,6 +965,12 @@ M: Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
+ARM/TEXAS INSTRUMENT KEYSTONE ARCHITECTURE
+M:     Santosh Shilimkar <santosh.shilimkar@ti.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/mach-keystone/
+
 ARM/LOGICPD PXA270 MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1259,7 +1265,6 @@ F:        drivers/rtc/rtc-coh901331.c
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
 
 ARM/Ux500 ARM ARCHITECTURE
-M:     Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
 M:     Linus Walleij <linus.walleij@linaro.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
index db2060c..9c1167b 100644 (file)
@@ -26,7 +26,7 @@
                cpu-offset = <0x80000>;
        };
 
-       msmgpio: gpio@fd510000 {
+       msmgpio: gpio@800000 {
                compatible = "qcom,msm-gpio";
                gpio-controller;
                #gpio-cells = <2>;
@@ -34,7 +34,7 @@
                interrupts = <0 32 0x4>;
                interrupt-controller;
                #interrupt-cells = <2>;
-               reg = <0xfd510000 0x4000>;
+               reg = <0x800000 0x4000>;
        };
 
        serial@16440000 {
index 08b7267..65d7b60 100644 (file)
 };
 
 &mmc1 {
-       vmmc-supply = <&vmmcsd_fixed>;
+       vmmc-supply = <&ldo9_reg>;
        bus-width = <4>;
 };
 
 
                        regulators {
                                smps123_reg: smps123 {
+                                       /* VDD_OPP_MPU */
                                        regulator-name = "smps123";
                                        regulator-min-microvolt = < 600000>;
                                        regulator-max-microvolt = <1500000>;
                                };
 
                                smps45_reg: smps45 {
+                                       /* VDD_OPP_MM */
                                        regulator-name = "smps45";
                                        regulator-min-microvolt = < 600000>;
                                        regulator-max-microvolt = <1310000>;
                                };
 
                                smps6_reg: smps6 {
+                                       /* VDD_DDR3 - over VDD_SMPS6 */
                                        regulator-name = "smps6";
                                        regulator-min-microvolt = <1200000>;
                                        regulator-max-microvolt = <1200000>;
                                };
 
                                smps7_reg: smps7 {
+                                       /* VDDS_1v8_OMAP over VDDS_1v8_MAIN */
                                        regulator-name = "smps7";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                };
 
                                smps8_reg: smps8 {
+                                       /* VDD_OPP_CORE */
                                        regulator-name = "smps8";
                                        regulator-min-microvolt = < 600000>;
                                        regulator-max-microvolt = <1310000>;
                                };
 
                                smps9_reg: smps9 {
+                                       /* VDDA_2v1_AUD over VDD_2v1 */
                                        regulator-name = "smps9";
                                        regulator-min-microvolt = <2100000>;
                                        regulator-max-microvolt = <2100000>;
-                                       regulator-always-on;
-                                       regulator-boot-on;
                                        ti,smps-range = <0x80>;
                                };
 
                                smps10_reg: smps10 {
+                                       /* VBUS_5V_OTG */
                                        regulator-name = "smps10";
                                        regulator-min-microvolt = <5000000>;
                                        regulator-max-microvolt = <5000000>;
                                };
 
                                ldo1_reg: ldo1 {
+                                       /* VDDAPHY_CAM: vdda_csiport */
                                        regulator-name = "ldo1";
-                                       regulator-min-microvolt = <2800000>;
-                                       regulator-max-microvolt = <2800000>;
-                                       regulator-always-on;
-                                       regulator-boot-on;
+                                       regulator-min-microvolt = <1500000>;
+                                       regulator-max-microvolt = <1800000>;
                                };
 
                                ldo2_reg: ldo2 {
+                                       /* VCC_2V8_DISP: Does not go anywhere */
                                        regulator-name = "ldo2";
-                                       regulator-min-microvolt = <2900000>;
-                                       regulator-max-microvolt = <2900000>;
-                                       regulator-always-on;
-                                       regulator-boot-on;
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       /* Unused */
+                                       status = "disabled";
                                };
 
                                ldo3_reg: ldo3 {
+                                       /* VDDAPHY_MDM: vdda_lli */
                                        regulator-name = "ldo3";
-                                       regulator-min-microvolt = <3000000>;
-                                       regulator-max-microvolt = <3000000>;
-                                       regulator-always-on;
+                                       regulator-min-microvolt = <1500000>;
+                                       regulator-max-microvolt = <1500000>;
                                        regulator-boot-on;
+                                       /* Only if Modem is used */
+                                       status = "disabled";
                                };
 
                                ldo4_reg: ldo4 {
+                                       /* VDDAPHY_DISP: vdda_dsiport/hdmi */
                                        regulator-name = "ldo4";
-                                       regulator-min-microvolt = <2200000>;
-                                       regulator-max-microvolt = <2200000>;
-                                       regulator-always-on;
-                                       regulator-boot-on;
+                                       regulator-min-microvolt = <1500000>;
+                                       regulator-max-microvolt = <1800000>;
                                };
 
                                ldo5_reg: ldo5 {
+                                       /* VDDA_1V8_PHY: usb/sata/hdmi.. */
                                        regulator-name = "ldo5";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                };
 
                                ldo6_reg: ldo6 {
+                                       /* VDDS_1V2_WKUP: hsic/ldo_emu_wkup */
                                        regulator-name = "ldo6";
-                                       regulator-min-microvolt = <1500000>;
-                                       regulator-max-microvolt = <1500000>;
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
                                        regulator-always-on;
                                        regulator-boot-on;
                                };
 
                                ldo7_reg: ldo7 {
+                                       /* VDD_VPP: vpp1 */
                                        regulator-name = "ldo7";
-                                       regulator-min-microvolt = <1500000>;
-                                       regulator-max-microvolt = <1500000>;
-                                       regulator-always-on;
-                                       regulator-boot-on;
+                                       regulator-min-microvolt = <2000000>;
+                                       regulator-max-microvolt = <2000000>;
+                                       /* Only for efuse reprograming! */
+                                       status = "disabled";
                                };
 
                                ldo8_reg: ldo8 {
+                                       /* VDD_3v0: Does not go anywhere */
                                        regulator-name = "ldo8";
-                                       regulator-min-microvolt = <1500000>;
-                                       regulator-max-microvolt = <1500000>;
-                                       regulator-always-on;
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
                                        regulator-boot-on;
+                                       /* Unused */
+                                       status = "disabled";
                                };
 
                                ldo9_reg: ldo9 {
+                                       /* VCC_DV_SDIO: vdds_sdcard */
                                        regulator-name = "ldo9";
                                        regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <3300000>;
-                                       regulator-always-on;
+                                       regulator-max-microvolt = <3000000>;
                                        regulator-boot-on;
                                };
 
                                ldoln_reg: ldoln {
+                                       /* VDDA_1v8_REF: vdds_osc/mm_l4per.. */
                                        regulator-name = "ldoln";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                };
 
                                ldousb_reg: ldousb {
+                                       /* VDDA_3V_USB: VDDA_USBHS33 */
                                        regulator-name = "ldousb";
                                        regulator-min-microvolt = <3250000>;
                                        regulator-max-microvolt = <3250000>;
                                        regulator-always-on;
                                        regulator-boot-on;
                                };
+
+                               regen3_reg: regen3 {
+                                       /* REGEN3 controls LDO9 supply to card */
+                                       regulator-name = "regen3";
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
                        };
                };
        };
index 7321403..f5b9898 100644 (file)
@@ -6,10 +6,12 @@
                #address-cells = <1>;
                #size-cells = <0>;
                cpu@0 {
+                       device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0>;
                };
                cpu@1 {
+                       device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <1>;
                };
index 2fcb3f2..5592be6 100644 (file)
        };
 
        usb-phy@c5004000 {
+               status = "okay";
                nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
                        GPIO_ACTIVE_LOW>;
        };
index 614e41e..905efc8 100644 (file)
@@ -121,8 +121,7 @@ config MSM_SMD
        bool
 
 config MSM_GPIOMUX
-       depends on !(ARCH_MSM8X60 || ARCH_MSM8960)
-       bool "MSM V1 TLMM GPIOMUX architecture"
+       bool
        help
          Support for MSM V1 TLMM GPIOMUX architecture.
 
diff --git a/arch/arm/mach-msm/gpiomux-v1.c b/arch/arm/mach-msm/gpiomux-v1.c
deleted file mode 100644 (file)
index 27de2ab..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-#include <linux/kernel.h>
-#include "gpiomux.h"
-#include "proc_comm.h"
-
-void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
-{
-       unsigned tlmm_config  = (val & ~GPIOMUX_CTL_MASK) |
-                               ((gpio & 0x3ff) << 4);
-       unsigned tlmm_disable = 0;
-       int rc;
-
-       rc = msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX,
-                          &tlmm_config, &tlmm_disable);
-       if (rc)
-               pr_err("%s: unexpected proc_comm failure %d: %08x %08x\n",
-                      __func__, rc, tlmm_config, tlmm_disable);
-}
index 8e82f41..4410d77 100644 (file)
@@ -73,16 +73,6 @@ extern struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS];
 int msm_gpiomux_write(unsigned gpio,
                      gpiomux_config_t active,
                      gpiomux_config_t suspended);
-
-/* Architecture-internal function for use by the framework only.
- * This function can assume the following:
- * - the gpio value has passed a bounds-check
- * - the gpiomux spinlock has been obtained
- *
- * This function is not for public consumption.  External users
- * should use msm_gpiomux_write.
- */
-void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val);
 #else
 static inline int msm_gpiomux_write(unsigned gpio,
                                    gpiomux_config_t active,
index 393aeef..043e570 100644 (file)
@@ -42,7 +42,7 @@
 
 /* Using generic display panel */
 static struct tfp410_platform_data omap4_dvi_panel = {
-       .i2c_bus_num            = 3,
+       .i2c_bus_num            = 2,
        .power_down_gpio        = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
 };
 
index 5cc9287..f99f68e 100644 (file)
@@ -129,6 +129,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
        struct device_node *node = pdev->dev.of_node;
        const char *oh_name;
        int oh_cnt, i, ret = 0;
+       bool device_active = false;
 
        oh_cnt = of_property_count_strings(node, "ti,hwmods");
        if (oh_cnt <= 0) {
@@ -152,6 +153,8 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
                        goto odbfd_exit1;
                }
                hwmods[i] = oh;
+               if (oh->flags & HWMOD_INIT_NO_IDLE)
+                       device_active = true;
        }
 
        od = omap_device_alloc(pdev, hwmods, oh_cnt);
@@ -172,6 +175,11 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
 
        pdev->dev.pm_domain = &omap_device_pm_domain;
 
+       if (device_active) {
+               omap_device_enable(pdev);
+               pm_runtime_set_active(&pdev->dev);
+       }
+
 odbfd_exit1:
        kfree(hwmods);
 odbfd_exit:
@@ -842,6 +850,7 @@ static int __init omap_device_late_idle(struct device *dev, void *data)
 {
        struct platform_device *pdev = to_platform_device(dev);
        struct omap_device *od = to_omap_device(pdev);
+       int i;
 
        if (!od)
                return 0;
@@ -850,6 +859,15 @@ static int __init omap_device_late_idle(struct device *dev, void *data)
         * If omap_device state is enabled, but has no driver bound,
         * idle it.
         */
+
+       /*
+        * Some devices (like memory controllers) are always kept
+        * enabled, and should not be idled even with no drivers.
+        */
+       for (i = 0; i < od->hwmods_cnt; i++)
+               if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE)
+                       return 0;
+
        if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
                if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
                        dev_warn(dev, "%s: enabled but no driver.  Idling\n",
index 7341eff..7f4db12 100644 (file)
@@ -2386,7 +2386,7 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
 
                np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh);
                if (np)
-                       va_start = of_iomap(np, 0);
+                       va_start = of_iomap(np, oh->mpu_rt_idx);
        } else {
                va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
        }
index aab33fd..e1482a9 100644 (file)
@@ -95,6 +95,54 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3;
 #define MODULEMODE_HWCTRL              1
 #define MODULEMODE_SWCTRL              2
 
+#define DEBUG_OMAP2UART1_FLAGS 0
+#define DEBUG_OMAP2UART2_FLAGS 0
+#define DEBUG_OMAP2UART3_FLAGS 0
+#define DEBUG_OMAP3UART3_FLAGS 0
+#define DEBUG_OMAP3UART4_FLAGS 0
+#define DEBUG_OMAP4UART3_FLAGS 0
+#define DEBUG_OMAP4UART4_FLAGS 0
+#define DEBUG_TI81XXUART1_FLAGS        0
+#define DEBUG_TI81XXUART2_FLAGS        0
+#define DEBUG_TI81XXUART3_FLAGS        0
+#define DEBUG_AM33XXUART1_FLAGS        0
+
+#define DEBUG_OMAPUART_FLAGS   (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET)
+
+#if defined(CONFIG_DEBUG_OMAP2UART1)
+#undef DEBUG_OMAP2UART1_FLAGS
+#define DEBUG_OMAP2UART1_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP2UART2)
+#undef DEBUG_OMAP2UART2_FLAGS
+#define DEBUG_OMAP2UART2_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP2UART3)
+#undef DEBUG_OMAP2UART3_FLAGS
+#define DEBUG_OMAP2UART3_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP3UART3)
+#undef DEBUG_OMAP3UART3_FLAGS
+#define DEBUG_OMAP3UART3_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP3UART4)
+#undef DEBUG_OMAP3UART4_FLAGS
+#define DEBUG_OMAP3UART4_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP4UART3)
+#undef DEBUG_OMAP4UART3_FLAGS
+#define DEBUG_OMAP4UART3_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP4UART4)
+#undef DEBUG_OMAP4UART4_FLAGS
+#define DEBUG_OMAP4UART4_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_TI81XXUART1)
+#undef DEBUG_TI81XXUART1_FLAGS
+#define DEBUG_TI81XXUART1_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_TI81XXUART2)
+#undef DEBUG_TI81XXUART2_FLAGS
+#define DEBUG_TI81XXUART2_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_TI81XXUART3)
+#undef DEBUG_TI81XXUART3_FLAGS
+#define DEBUG_TI81XXUART3_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_AM33XXUART1)
+#undef DEBUG_AM33XXUART1_FLAGS
+#define DEBUG_AM33XXUART1_FLAGS DEBUG_OMAPUART_FLAGS
+#endif
 
 /**
  * struct omap_hwmod_mux_info - hwmod specific mux configuration
@@ -568,6 +616,7 @@ struct omap_hwmod_link {
  * @voltdm: pointer to voltage domain (filled in at runtime)
  * @dev_attr: arbitrary device attributes that can be passed to the driver
  * @_sysc_cache: internal-use hwmod flags
+ * @mpu_rt_idx: index of device address space for register target (for DT boot)
  * @_mpu_rt_va: cached register target start address (internal use)
  * @_mpu_port: cached MPU register target slave (internal use)
  * @opt_clks_cnt: number of @opt_clks
@@ -617,6 +666,7 @@ struct omap_hwmod {
        struct list_head                node;
        struct omap_hwmod_ocp_if        *_mpu_port;
        u16                             flags;
+       u8                              mpu_rt_idx;
        u8                              response_lat;
        u8                              rst_lines_cnt;
        u8                              opt_clks_cnt;
index d05fc7b..56cebb0 100644 (file)
@@ -512,7 +512,7 @@ struct omap_hwmod omap2xxx_uart1_hwmod = {
        .mpu_irqs       = omap2_uart1_mpu_irqs,
        .sdma_reqs      = omap2_uart1_sdma_reqs,
        .main_clk       = "uart1_fck",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .flags          = DEBUG_OMAP2UART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = CORE_MOD,
@@ -532,7 +532,7 @@ struct omap_hwmod omap2xxx_uart2_hwmod = {
        .mpu_irqs       = omap2_uart2_mpu_irqs,
        .sdma_reqs      = omap2_uart2_sdma_reqs,
        .main_clk       = "uart2_fck",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .flags          = DEBUG_OMAP2UART2_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = CORE_MOD,
@@ -552,7 +552,7 @@ struct omap_hwmod omap2xxx_uart3_hwmod = {
        .mpu_irqs       = omap2_uart3_mpu_irqs,
        .sdma_reqs      = omap2_uart3_sdma_reqs,
        .main_clk       = "uart3_fck",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .flags          = DEBUG_OMAP2UART3_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = CORE_MOD,
index 28bbd56..eb2f3b9 100644 (file)
@@ -562,6 +562,7 @@ static struct omap_hwmod am33xx_cpgmac0_hwmod = {
        .clkdm_name     = "cpsw_125mhz_clkdm",
        .flags          = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
        .main_clk       = "cpsw_125mhz_gclk",
+       .mpu_rt_idx     = 1,
        .prcm           = {
                .omap4  = {
                        .clkctrl_offs   = AM33XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET,
@@ -1512,7 +1513,7 @@ static struct omap_hwmod am33xx_uart1_hwmod = {
        .name           = "uart1",
        .class          = &uart_class,
        .clkdm_name     = "l4_wkup_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .flags          = DEBUG_AM33XXUART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
        .main_clk       = "dpll_per_m2_div4_wkupdm_ck",
        .prcm           = {
                .omap4  = {
index f7a3df2..0c3a427 100644 (file)
@@ -490,7 +490,7 @@ static struct omap_hwmod omap3xxx_uart1_hwmod = {
        .mpu_irqs       = omap2_uart1_mpu_irqs,
        .sdma_reqs      = omap2_uart1_sdma_reqs,
        .main_clk       = "uart1_fck",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .flags          = DEBUG_TI81XXUART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = CORE_MOD,
@@ -509,7 +509,7 @@ static struct omap_hwmod omap3xxx_uart2_hwmod = {
        .mpu_irqs       = omap2_uart2_mpu_irqs,
        .sdma_reqs      = omap2_uart2_sdma_reqs,
        .main_clk       = "uart2_fck",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .flags          = DEBUG_TI81XXUART2_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = CORE_MOD,
@@ -528,7 +528,8 @@ static struct omap_hwmod omap3xxx_uart3_hwmod = {
        .mpu_irqs       = omap2_uart3_mpu_irqs,
        .sdma_reqs      = omap2_uart3_sdma_reqs,
        .main_clk       = "uart3_fck",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .flags          = DEBUG_OMAP3UART3_FLAGS | DEBUG_TI81XXUART3_FLAGS |
+                               HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = OMAP3430_PER_MOD,
@@ -558,7 +559,7 @@ static struct omap_hwmod omap36xx_uart4_hwmod = {
        .mpu_irqs       = uart4_mpu_irqs,
        .sdma_reqs      = uart4_sdma_reqs,
        .main_clk       = "uart4_fck",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .flags          = DEBUG_OMAP3UART4_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = OMAP3430_PER_MOD,
index d04b5e6..9c3b504 100644 (file)
@@ -2858,8 +2858,7 @@ static struct omap_hwmod omap44xx_uart3_hwmod = {
        .name           = "uart3",
        .class          = &omap44xx_uart_hwmod_class,
        .clkdm_name     = "l4_per_clkdm",
-       .flags          = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
-                               HWMOD_SWSUP_SIDLE_ACT,
+       .flags          = DEBUG_OMAP4UART3_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
        .main_clk       = "func_48m_fclk",
        .prcm = {
                .omap4 = {
@@ -2875,7 +2874,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
        .name           = "uart4",
        .class          = &omap44xx_uart_hwmod_class,
        .clkdm_name     = "l4_per_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .flags          = DEBUG_OMAP4UART4_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
        .main_clk       = "func_48m_fclk",
        .prcm = {
                .omap4 = {
index f37ae96..3c70f5c 100644 (file)
@@ -1375,7 +1375,7 @@ static struct omap_hwmod omap54xx_uart3_hwmod = {
        .name           = "uart3",
        .class          = &omap54xx_uart_hwmod_class,
        .clkdm_name     = "l4per_clkdm",
-       .flags          = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+       .flags          = DEBUG_OMAP4UART3_FLAGS,
        .main_clk       = "func_48m_fclk",
        .prcm = {
                .omap4 = {
@@ -1391,6 +1391,7 @@ static struct omap_hwmod omap54xx_uart4_hwmod = {
        .name           = "uart4",
        .class          = &omap54xx_uart_hwmod_class,
        .clkdm_name     = "l4per_clkdm",
+       .flags          = DEBUG_OMAP4UART4_FLAGS,
        .main_clk       = "func_48m_fclk",
        .prcm = {
                .omap4 = {
index 3a674de..a388f8c 100644 (file)
@@ -208,17 +208,6 @@ static int __init omap_serial_early_init(void)
                                pr_info("%s used as console in debug mode: uart%d clocks will not be gated",
                                        uart_name, uart->num);
                        }
-
-                       /*
-                        * omap-uart can be used for earlyprintk logs
-                        * So if omap-uart is used as console then prevent
-                        * uart reset and idle to get logs from omap-uart
-                        * until uart console driver is available to take
-                        * care for console messages.
-                        * Idling or resetting omap-uart while printing logs
-                        * early boot logs can stall the boot-up.
-                        */
-                       oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
                }
        } while (1);
 
index e115f67..c5be60d 100644 (file)
@@ -1162,9 +1162,6 @@ static void __init eva_init(void)
        gpio_request_one(61, GPIOF_OUT_INIT_HIGH, NULL); /* LCDDON */
        gpio_request_one(202, GPIOF_OUT_INIT_LOW, NULL); /* LCD0_LED_CONT */
 
-       /* Touchscreen */
-       gpio_request_one(166, GPIOF_OUT_INIT_HIGH, NULL); /* TP_RST_B */
-
        /* GETHER */
        gpio_request_one(18, GPIOF_OUT_INIT_HIGH, NULL); /* PHY_RST */
 
index d555464..3354a85 100644 (file)
@@ -167,7 +167,13 @@ static const struct pinctrl_map bockw_pinctrl_map[] = {
                                  "usb1", "usb1"),
        /* SDHI0 */
        PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
-                                 "sdhi0", "sdhi0"),
+                                 "sdhi0_data4", "sdhi0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
+                                 "sdhi0_ctrl", "sdhi0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
+                                 "sdhi0_cd", "sdhi0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
+                                 "sdhi0_wp", "sdhi0"),
 };
 
 #define FPGA   0x18200000
index d73e21d..8d6bd5c 100644 (file)
@@ -59,7 +59,7 @@ static __initdata struct gpio_led_platform_data lager_leds_pdata = {
 #define GPIO_KEY(c, g, d, ...) \
        { .code = c, .gpio = g, .desc = d, .active_low = 1 }
 
-static __initdata struct gpio_keys_button gpio_buttons[] = {
+static struct gpio_keys_button gpio_buttons[] = {
        GPIO_KEY(KEY_4,         RCAR_GP_PIN(1, 28),     "SW2-pin4"),
        GPIO_KEY(KEY_3,         RCAR_GP_PIN(1, 26),     "SW2-pin3"),
        GPIO_KEY(KEY_2,         RCAR_GP_PIN(1, 24),     "SW2-pin2"),
index 78ebc75..4c09bae 100644 (file)
@@ -16,8 +16,6 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
-       __INIT
-
 /*
  * ST specific entry point for secondary CPUs.  This provides
  * a "holding pen" into which all secondary cores are held until we're
index f914319..7de083d 100644 (file)
@@ -150,7 +150,6 @@ static struct ac97c_platform_data __initdata ac97c0_data = {
 static struct platform_device rmt_ts_device = {
        .name   = "ucb1400_ts",
        .id     = -1,
-       }
 };
 #endif
 
index 1dc0860..fa44f3e 100644 (file)
@@ -17,6 +17,8 @@
 #define current_cpu_type()     current_cpu_data.cputype
 #endif
 
+#define boot_cpu_type()                cpu_data[0].cputype
+
 /*
  * SMP assumption: Options of CPU 0 are a superset of all processors.
  * This is true for all known MIPS systems.
index 159abc8..126da74 100644 (file)
@@ -66,6 +66,8 @@ static void __init bmips_smp_setup(void)
        int i, cpu = 1, boot_cpu = 0;
 
 #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
+       int cpu_hw_intr;
+
        /* arbitration priority */
        clear_c0_brcm_cmt_ctrl(0x30);
 
@@ -80,8 +82,12 @@ static void __init bmips_smp_setup(void)
         * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
         * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
         */
-       change_c0_brcm_cmt_intr(0xf8018000,
-                                       (0x02 << 27) | (0x03 << 15));
+       if (boot_cpu == 0)
+               cpu_hw_intr = 0x02;
+       else
+               cpu_hw_intr = 0x1d;
+
+       change_c0_brcm_cmt_intr(0xf8018000, (cpu_hw_intr << 27) | (0x03 << 15));
 
        /* single core, 2 threads (2 pipelines) */
        max_cpus = 2;
index e4b1140..3a2b6e9 100644 (file)
@@ -166,7 +166,7 @@ static void mipsxx_reg_setup(struct op_counter_config *ctr)
                        reg.control[i] |= M_PERFCTL_USER;
                if (ctr[i].exl)
                        reg.control[i] |= M_PERFCTL_EXL;
-               if (current_cpu_type() == CPU_XLR)
+               if (boot_cpu_type() == CPU_XLR)
                        reg.control[i] |= M_PERFCTL_COUNT_ALL_THREADS;
                reg.counter[i] = 0x80000000 - ctr[i].count;
        }
index d22dc0d..2b7e837 100644 (file)
@@ -206,11 +206,13 @@ static struct resource pnx833x_ethernet_resources[] = {
                .end   = PNX8335_IP3902_PORTS_END,
                .flags = IORESOURCE_MEM,
        },
+#ifdef CONFIG_SOC_PNX8335
        [1] = {
                .start = PNX8335_PIC_ETHERNET_INT,
                .end   = PNX8335_PIC_ETHERNET_INT,
                .flags = IORESOURCE_IRQ,
        },
+#endif
 };
 
 static struct platform_device pnx833x_ethernet_device = {
index 22f75b5..8a4cae7 100644 (file)
@@ -118,6 +118,7 @@ config S390
        select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_KERNEL_BZIP2
        select HAVE_KERNEL_GZIP
+       select HAVE_KERNEL_LZ4
        select HAVE_KERNEL_LZMA
        select HAVE_KERNEL_LZO
        select HAVE_KERNEL_XZ
@@ -227,11 +228,12 @@ config MARCH_Z196
          not work on older machines.
 
 config MARCH_ZEC12
-       bool "IBM zEC12"
+       bool "IBM zBC12 and zEC12"
        select HAVE_MARCH_ZEC12_FEATURES if 64BIT
        help
-         Select this to enable optimizations for IBM zEC12 (2827 series). The
-         kernel will be slightly faster but will not work on older machines.
+         Select this to enable optimizations for IBM zBC12 and zEC12 (2828 and
+         2827 series). The kernel will be slightly faster but will not work on
+         older machines.
 
 endchoice
 
@@ -709,6 +711,7 @@ config S390_GUEST
        def_bool y
        prompt "s390 support for virtio devices"
        depends on 64BIT
+       select TTY
        select VIRTUALIZATION
        select VIRTIO
        select VIRTIO_CONSOLE
index 3ad8f61..866ecbe 100644 (file)
@@ -6,9 +6,9 @@
 
 BITS := $(if $(CONFIG_64BIT),64,31)
 
-targets        := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
-          vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo misc.o piggy.o \
-          sizes.h head$(BITS).o
+targets        := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
+targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
+targets += misc.o piggy.o sizes.h head$(BITS).o
 
 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
 KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
@@ -48,6 +48,7 @@ vmlinux.bin.all-y := $(obj)/vmlinux.bin
 
 suffix-$(CONFIG_KERNEL_GZIP)  := gz
 suffix-$(CONFIG_KERNEL_BZIP2) := bz2
+suffix-$(CONFIG_KERNEL_LZ4)  := lz4
 suffix-$(CONFIG_KERNEL_LZMA)  := lzma
 suffix-$(CONFIG_KERNEL_LZO)  := lzo
 suffix-$(CONFIG_KERNEL_XZ)  := xz
@@ -56,6 +57,8 @@ $(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y)
        $(call if_changed,gzip)
 $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y)
        $(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y)
+       $(call if_changed,lz4)
 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y)
        $(call if_changed,lzma)
 $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y)
index c4c6a1c..57cbaff 100644 (file)
@@ -47,6 +47,10 @@ static unsigned long free_mem_end_ptr;
 #include "../../../../lib/decompress_bunzip2.c"
 #endif
 
+#ifdef CONFIG_KERNEL_LZ4
+#include "../../../../lib/decompress_unlz4.c"
+#endif
+
 #ifdef CONFIG_KERNEL_LZMA
 #include "../../../../lib/decompress_unlzma.c"
 #endif
index 4d8604e..7d46767 100644 (file)
@@ -693,7 +693,7 @@ static inline int find_next_bit_left(const unsigned long *addr,
        size -= offset;
        p = addr + offset / BITS_PER_LONG;
        if (bit) {
-               set = __flo_word(0, *p & (~0UL << bit));
+               set = __flo_word(0, *p & (~0UL >> bit));
                if (set >= size)
                        return size + offset;
                if (set < BITS_PER_LONG)
index a6fc037..500aa10 100644 (file)
@@ -52,12 +52,13 @@ static struct kvm_s390_sie_block *sie_block(struct pt_regs *regs)
 
 static bool is_in_guest(struct pt_regs *regs)
 {
-       unsigned long ip = instruction_pointer(regs);
-
        if (user_mode(regs))
                return false;
-
-       return ip == (unsigned long) &sie_exit;
+#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
+       return instruction_pointer(regs) == (unsigned long) &sie_exit;
+#else
+       return false;
+#endif
 }
 
 static unsigned long guest_is_user_mode(struct pt_regs *regs)
index 497451e..aeed8a6 100644 (file)
@@ -994,6 +994,7 @@ static void __init setup_hwcaps(void)
                strcpy(elf_platform, "z196");
                break;
        case 0x2827:
+       case 0x2828:
                strcpy(elf_platform, "zEC12");
                break;
        }
index ce36ea8..ad446b0 100644 (file)
@@ -69,6 +69,7 @@ static void __init setup_zero_pages(void)
                order = 2;
                break;
        case 0x2827:    /* zEC12 */
+       case 0x2828:    /* zEC12 */
        default:
                order = 5;
                break;
index ffeb17c..930783d 100644 (file)
@@ -440,7 +440,7 @@ static int oprofile_hwsampler_init(struct oprofile_operations *ops)
                switch (id.machine) {
                case 0x2097: case 0x2098: ops->cpu_type = "s390/z10"; break;
                case 0x2817: case 0x2818: ops->cpu_type = "s390/z196"; break;
-               case 0x2827:              ops->cpu_type = "s390/zEC12"; break;
+               case 0x2827: case 0x2828: ops->cpu_type = "s390/zEC12"; break;
                default: return -ENODEV;
                }
        }
index d606463..b7388a4 100644 (file)
@@ -225,7 +225,7 @@ static void low_free(unsigned long size, unsigned long addr)
        unsigned long nr_pages;
 
        nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
-       efi_call_phys2(sys_table->boottime->free_pages, addr, size);
+       efi_call_phys2(sys_table->boottime->free_pages, addr, nr_pages);
 }
 
 static void find_bits(unsigned long mask, u8 *pos, u8 *size)
index 94ab6b9..63bdb29 100644 (file)
@@ -196,15 +196,23 @@ static void __init ati_bugs_contd(int num, int slot, int func)
 static void __init intel_remapping_check(int num, int slot, int func)
 {
        u8 revision;
+       u16 device;
 
+       device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID);
        revision = read_pci_config_byte(num, slot, func, PCI_REVISION_ID);
 
        /*
-        * Revision 0x13 of this chipset supports irq remapping
-        * but has an erratum that breaks its behavior, flag it as such
+        * Revision 13 of all triggering devices id in this quirk have
+        * a problem draining interrupts when irq remapping is enabled,
+        * and should be flagged as broken.  Additionally revisions 0x12
+        * and 0x22 of device id 0x3405 has this problem.
         */
        if (revision == 0x13)
                set_irq_remapping_broken();
+       else if ((device == 0x3405) &&
+           ((revision == 0x12) ||
+            (revision == 0x22)))
+               set_irq_remapping_broken();
 
 }
 
@@ -239,6 +247,8 @@ static struct chipset early_qrk[] __initdata = {
          PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd },
        { PCI_VENDOR_ID_INTEL, 0x3403, PCI_CLASS_BRIDGE_HOST,
          PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
+       { PCI_VENDOR_ID_INTEL, 0x3405, PCI_CLASS_BRIDGE_HOST,
+         PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
        { PCI_VENDOR_ID_INTEL, 0x3406, PCI_CLASS_BRIDGE_HOST,
          PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
        {}
index 202d24f..5d576ab 100644 (file)
@@ -116,7 +116,7 @@ static void mxcsr_feature_mask_init(void)
 
        if (cpu_has_fxsr) {
                memset(&fx_scratch, 0, sizeof(struct i387_fxsave_struct));
-               asm volatile("fxsave %0" : : "m" (fx_scratch));
+               asm volatile("fxsave %0" : "+m" (fx_scratch));
                mask = fx_scratch.mxcsr_mask;
                if (mask == 0)
                        mask = 0x0000ffbf;
index 47ebb1d..7a0adb7 100644 (file)
@@ -220,12 +220,13 @@ int apply_microcode_amd(int cpu)
                return 0;
        }
 
-       if (__apply_microcode_amd(mc_amd))
+       if (__apply_microcode_amd(mc_amd)) {
                pr_err("CPU%d: update failed for patch_level=0x%08x\n",
                        cpu, mc_amd->hdr.patch_id);
-       else
-               pr_info("CPU%d: new patch_level=0x%08x\n", cpu,
-                       mc_amd->hdr.patch_id);
+               return -1;
+       }
+       pr_info("CPU%d: new patch_level=0x%08x\n", cpu,
+               mc_amd->hdr.patch_id);
 
        uci->cpu_sig.rev = mc_amd->hdr.patch_id;
        c->microcode = mc_amd->hdr.patch_id;
index fd6c51c..5a74a9c 100644 (file)
@@ -451,7 +451,6 @@ static void acpi_processor_remove(struct acpi_device *device)
        /* Clean up. */
        per_cpu(processor_device_array, pr->id) = NULL;
        per_cpu(processors, pr->id) = NULL;
-       try_offline_node(cpu_to_node(pr->id));
 
        /* Remove the CPU. */
        get_online_cpus();
@@ -459,6 +458,8 @@ static void acpi_processor_remove(struct acpi_device *device)
        acpi_unmap_lsapic(pr->id);
        put_online_cpus();
 
+       try_offline_node(cpu_to_node(pr->id));
+
  out:
        free_cpumask_var(pr->throttling.shared_cpu_map);
        kfree(pr);
index f680957..408f6b2 100644 (file)
@@ -31,6 +31,7 @@ static LIST_HEAD(bus_type_list);
 static DECLARE_RWSEM(bus_type_sem);
 
 #define PHYSICAL_NODE_STRING "physical_node"
+#define PHYSICAL_NODE_NAME_SIZE (sizeof(PHYSICAL_NODE_STRING) + 10)
 
 int register_acpi_bus_type(struct acpi_bus_type *type)
 {
@@ -78,41 +79,108 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
        return ret;
 }
 
-static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used,
-                                     void *addr_p, void **ret_p)
+static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used,
+                                 void *not_used, void **ret_p)
 {
-       unsigned long long addr, sta;
-       acpi_status status;
+       struct acpi_device *adev = NULL;
 
-       status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
-       if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) {
+       acpi_bus_get_device(handle, &adev);
+       if (adev) {
                *ret_p = handle;
-               status = acpi_bus_get_status_handle(handle, &sta);
-               if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_ENABLED))
-                       return AE_CTRL_TERMINATE;
+               return AE_CTRL_TERMINATE;
        }
        return AE_OK;
 }
 
-acpi_handle acpi_get_child(acpi_handle parent, u64 address)
+static bool acpi_extra_checks_passed(acpi_handle handle, bool is_bridge)
 {
-       void *ret = NULL;
+       unsigned long long sta;
+       acpi_status status;
+
+       status = acpi_bus_get_status_handle(handle, &sta);
+       if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED))
+               return false;
+
+       if (is_bridge) {
+               void *test = NULL;
+
+               /* Check if this object has at least one child device. */
+               acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+                                   acpi_dev_present, NULL, NULL, &test);
+               return !!test;
+       }
+       return true;
+}
+
+struct find_child_context {
+       u64 addr;
+       bool is_bridge;
+       acpi_handle ret;
+       bool ret_checked;
+};
+
+static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used,
+                                void *data, void **not_used)
+{
+       struct find_child_context *context = data;
+       unsigned long long addr;
+       acpi_status status;
 
-       if (!parent)
-               return NULL;
+       status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
+       if (ACPI_FAILURE(status) || addr != context->addr)
+               return AE_OK;
 
-       acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, NULL,
-                           do_acpi_find_child, &address, &ret);
-       return (acpi_handle)ret;
+       if (!context->ret) {
+               /* This is the first matching object.  Save its handle. */
+               context->ret = handle;
+               return AE_OK;
+       }
+       /*
+        * There is more than one matching object with the same _ADR value.
+        * That really is unexpected, so we are kind of beyond the scope of the
+        * spec here.  We have to choose which one to return, though.
+        *
+        * First, check if the previously found object is good enough and return
+        * its handle if so.  Second, check the same for the object that we've
+        * just found.
+        */
+       if (!context->ret_checked) {
+               if (acpi_extra_checks_passed(context->ret, context->is_bridge))
+                       return AE_CTRL_TERMINATE;
+               else
+                       context->ret_checked = true;
+       }
+       if (acpi_extra_checks_passed(handle, context->is_bridge)) {
+               context->ret = handle;
+               return AE_CTRL_TERMINATE;
+       }
+       return AE_OK;
 }
-EXPORT_SYMBOL(acpi_get_child);
+
+acpi_handle acpi_find_child(acpi_handle parent, u64 addr, bool is_bridge)
+{
+       if (parent) {
+               struct find_child_context context = {
+                       .addr = addr,
+                       .is_bridge = is_bridge,
+               };
+
+               acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, do_find_child,
+                                   NULL, &context, NULL);
+               return context.ret;
+       }
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(acpi_find_child);
 
 int acpi_bind_one(struct device *dev, acpi_handle handle)
 {
        struct acpi_device *acpi_dev;
        acpi_status status;
        struct acpi_device_physical_node *physical_node, *pn;
-       char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
+       char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
+       struct list_head *physnode_list;
+       unsigned int node_id;
        int retval = -EINVAL;
 
        if (ACPI_HANDLE(dev)) {
@@ -139,25 +207,27 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
 
        mutex_lock(&acpi_dev->physical_node_lock);
 
-       /* Sanity check. */
-       list_for_each_entry(pn, &acpi_dev->physical_node_list, node)
+       /*
+        * Keep the list sorted by node_id so that the IDs of removed nodes can
+        * be recycled easily.
+        */
+       physnode_list = &acpi_dev->physical_node_list;
+       node_id = 0;
+       list_for_each_entry(pn, &acpi_dev->physical_node_list, node) {
+               /* Sanity check. */
                if (pn->dev == dev) {
                        dev_warn(dev, "Already associated with ACPI node\n");
                        goto err_free;
                }
-
-       /* allocate physical node id according to physical_node_id_bitmap */
-       physical_node->node_id =
-               find_first_zero_bit(acpi_dev->physical_node_id_bitmap,
-               ACPI_MAX_PHYSICAL_NODE);
-       if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) {
-               retval = -ENOSPC;
-               goto err_free;
+               if (pn->node_id == node_id) {
+                       physnode_list = &pn->node;
+                       node_id++;
+               }
        }
 
-       set_bit(physical_node->node_id, acpi_dev->physical_node_id_bitmap);
+       physical_node->node_id = node_id;
        physical_node->dev = dev;
-       list_add_tail(&physical_node->node, &acpi_dev->physical_node_list);
+       list_add(&physical_node->node, physnode_list);
        acpi_dev->physical_node_count++;
 
        mutex_unlock(&acpi_dev->physical_node_lock);
@@ -208,7 +278,7 @@ int acpi_unbind_one(struct device *dev)
 
        mutex_lock(&acpi_dev->physical_node_lock);
        list_for_each_safe(node, next, &acpi_dev->physical_node_list) {
-               char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
+               char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
 
                entry = list_entry(node, struct acpi_device_physical_node,
                        node);
@@ -216,7 +286,6 @@ int acpi_unbind_one(struct device *dev)
                        continue;
 
                list_del(node);
-               clear_bit(entry->node_id, acpi_dev->physical_node_id_bitmap);
 
                acpi_dev->physical_node_count--;
 
index aa1227a..04a1378 100644 (file)
@@ -311,6 +311,8 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
                           dev->pnp.bus_id,
                           (u32) dev->wakeup.sleep_state);
 
+               mutex_lock(&dev->physical_node_lock);
+
                if (!dev->physical_node_count) {
                        seq_printf(seq, "%c%-8s\n",
                                dev->wakeup.flags.run_wake ? '*' : ' ',
@@ -338,6 +340,8 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
                                put_device(ldev);
                        }
                }
+
+               mutex_unlock(&dev->physical_node_lock);
        }
        mutex_unlock(&acpi_device_lock);
        return 0;
@@ -347,12 +351,16 @@ static void physical_device_enable_wakeup(struct acpi_device *adev)
 {
        struct acpi_device_physical_node *entry;
 
+       mutex_lock(&adev->physical_node_lock);
+
        list_for_each_entry(entry,
                &adev->physical_node_list, node)
                if (entry->dev && device_can_wakeup(entry->dev)) {
                        bool enable = !device_may_wakeup(entry->dev);
                        device_set_wakeup_enable(entry->dev, enable);
                }
+
+       mutex_unlock(&adev->physical_node_lock);
 }
 
 static ssize_t
index 0ec434d..e1284b8 100644 (file)
@@ -689,7 +689,7 @@ static int acpi_video_bqc_quirk(struct acpi_video_device *device,
         * Some systems always report current brightness level as maximum
         * through _BQC, we need to test another value for them.
         */
-       test_level = current_level == max_level ? br->levels[2] : max_level;
+       test_level = current_level == max_level ? br->levels[3] : max_level;
 
        result = acpi_video_device_lcd_set_level(device, test_level);
        if (result)
index 4ec7c04..26386f0 100644 (file)
@@ -237,6 +237,7 @@ static const struct of_device_id imx_pata_dt_ids[] = {
                /* sentinel */
        }
 };
+MODULE_DEVICE_TABLE(of, imx_pata_dt_ids);
 
 static struct platform_driver pata_imx_driver = {
        .probe          = pata_imx_probe,
index e691026..3455f83 100644 (file)
@@ -719,7 +719,8 @@ static int regcache_sync_block_raw(struct regmap *map, void *block,
                }
        }
 
-       return regcache_sync_block_raw_flush(map, &data, base, regtmp);
+       return regcache_sync_block_raw_flush(map, &data, base, regtmp +
+                       map->reg_stride);
 }
 
 int regcache_sync_block(struct regmap *map, void *block,
index 1b456fe..fc45567 100644 (file)
@@ -272,9 +272,12 @@ static struct port *find_port_by_devt_in_portdev(struct ports_device *portdev,
        unsigned long flags;
 
        spin_lock_irqsave(&portdev->ports_lock, flags);
-       list_for_each_entry(port, &portdev->ports, list)
-               if (port->cdev->dev == dev)
+       list_for_each_entry(port, &portdev->ports, list) {
+               if (port->cdev->dev == dev) {
+                       kref_get(&port->kref);
                        goto out;
+               }
+       }
        port = NULL;
 out:
        spin_unlock_irqrestore(&portdev->ports_lock, flags);
@@ -746,6 +749,10 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf,
 
        port = filp->private_data;
 
+       /* Port is hot-unplugged. */
+       if (!port->guest_connected)
+               return -ENODEV;
+
        if (!port_has_data(port)) {
                /*
                 * If nothing's connected on the host just return 0 in
@@ -762,7 +769,7 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf,
                if (ret < 0)
                        return ret;
        }
-       /* Port got hot-unplugged. */
+       /* Port got hot-unplugged while we were waiting above. */
        if (!port->guest_connected)
                return -ENODEV;
        /*
@@ -932,13 +939,25 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
        if (is_rproc_serial(port->out_vq->vdev))
                return -EINVAL;
 
+       /*
+        * pipe->nrbufs == 0 means there are no data to transfer,
+        * so this returns just 0 for no data.
+        */
+       pipe_lock(pipe);
+       if (!pipe->nrbufs) {
+               ret = 0;
+               goto error_out;
+       }
+
        ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK);
        if (ret < 0)
-               return ret;
+               goto error_out;
 
        buf = alloc_buf(port->out_vq, 0, pipe->nrbufs);
-       if (!buf)
-               return -ENOMEM;
+       if (!buf) {
+               ret = -ENOMEM;
+               goto error_out;
+       }
 
        sgl.n = 0;
        sgl.len = 0;
@@ -946,12 +965,17 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
        sgl.sg = buf->sg;
        sg_init_table(sgl.sg, sgl.size);
        ret = __splice_from_pipe(pipe, &sd, pipe_to_sg);
+       pipe_unlock(pipe);
        if (likely(ret > 0))
                ret = __send_to_port(port, buf->sg, sgl.n, sgl.len, buf, true);
 
        if (unlikely(ret <= 0))
                free_buf(buf, true);
        return ret;
+
+error_out:
+       pipe_unlock(pipe);
+       return ret;
 }
 
 static unsigned int port_fops_poll(struct file *filp, poll_table *wait)
@@ -1019,14 +1043,14 @@ static int port_fops_open(struct inode *inode, struct file *filp)
        struct port *port;
        int ret;
 
+       /* We get the port with a kref here */
        port = find_port_by_devt(cdev->dev);
+       if (!port) {
+               /* Port was unplugged before we could proceed */
+               return -ENXIO;
+       }
        filp->private_data = port;
 
-       /* Prevent against a port getting hot-unplugged at the same time */
-       spin_lock_irq(&port->portdev->ports_lock);
-       kref_get(&port->kref);
-       spin_unlock_irq(&port->portdev->ports_lock);
-
        /*
         * Don't allow opening of console port devices -- that's done
         * via /dev/hvc
@@ -1498,14 +1522,6 @@ static void remove_port(struct kref *kref)
 
        port = container_of(kref, struct port, kref);
 
-       sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
-       device_destroy(pdrvdata.class, port->dev->devt);
-       cdev_del(port->cdev);
-
-       kfree(port->name);
-
-       debugfs_remove(port->debugfs_file);
-
        kfree(port);
 }
 
@@ -1539,12 +1555,14 @@ static void unplug_port(struct port *port)
        spin_unlock_irq(&port->portdev->ports_lock);
 
        if (port->guest_connected) {
+               /* Let the app know the port is going down. */
+               send_sigio_to_port(port);
+
+               /* Do this after sigio is actually sent */
                port->guest_connected = false;
                port->host_connected = false;
-               wake_up_interruptible(&port->waitqueue);
 
-               /* Let the app know the port is going down. */
-               send_sigio_to_port(port);
+               wake_up_interruptible(&port->waitqueue);
        }
 
        if (is_console_port(port)) {
@@ -1563,6 +1581,14 @@ static void unplug_port(struct port *port)
         */
        port->portdev = NULL;
 
+       sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
+       device_destroy(pdrvdata.class, port->dev->devt);
+       cdev_del(port->cdev);
+
+       kfree(port->name);
+
+       debugfs_remove(port->debugfs_file);
+
        /*
         * Locks around here are not necessary - a port can't be
         * opened after we removed the port struct from ports_list
index 0ceb2ef..f97cb3d 100644 (file)
@@ -221,8 +221,8 @@ static ssize_t store_down_threshold(struct dbs_data *dbs_data, const char *buf,
        return count;
 }
 
-static ssize_t store_ignore_nice(struct dbs_data *dbs_data, const char *buf,
-               size_t count)
+static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data,
+               const char *buf, size_t count)
 {
        struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
        unsigned int input, j;
@@ -235,10 +235,10 @@ static ssize_t store_ignore_nice(struct dbs_data *dbs_data, const char *buf,
        if (input > 1)
                input = 1;
 
-       if (input == cs_tuners->ignore_nice) /* nothing to do */
+       if (input == cs_tuners->ignore_nice_load) /* nothing to do */
                return count;
 
-       cs_tuners->ignore_nice = input;
+       cs_tuners->ignore_nice_load = input;
 
        /* we need to re-evaluate prev_cpu_idle */
        for_each_online_cpu(j) {
@@ -246,7 +246,7 @@ static ssize_t store_ignore_nice(struct dbs_data *dbs_data, const char *buf,
                dbs_info = &per_cpu(cs_cpu_dbs_info, j);
                dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j,
                                        &dbs_info->cdbs.prev_cpu_wall, 0);
-               if (cs_tuners->ignore_nice)
+               if (cs_tuners->ignore_nice_load)
                        dbs_info->cdbs.prev_cpu_nice =
                                kcpustat_cpu(j).cpustat[CPUTIME_NICE];
        }
@@ -279,7 +279,7 @@ show_store_one(cs, sampling_rate);
 show_store_one(cs, sampling_down_factor);
 show_store_one(cs, up_threshold);
 show_store_one(cs, down_threshold);
-show_store_one(cs, ignore_nice);
+show_store_one(cs, ignore_nice_load);
 show_store_one(cs, freq_step);
 declare_show_sampling_rate_min(cs);
 
@@ -287,7 +287,7 @@ gov_sys_pol_attr_rw(sampling_rate);
 gov_sys_pol_attr_rw(sampling_down_factor);
 gov_sys_pol_attr_rw(up_threshold);
 gov_sys_pol_attr_rw(down_threshold);
-gov_sys_pol_attr_rw(ignore_nice);
+gov_sys_pol_attr_rw(ignore_nice_load);
 gov_sys_pol_attr_rw(freq_step);
 gov_sys_pol_attr_ro(sampling_rate_min);
 
@@ -297,7 +297,7 @@ static struct attribute *dbs_attributes_gov_sys[] = {
        &sampling_down_factor_gov_sys.attr,
        &up_threshold_gov_sys.attr,
        &down_threshold_gov_sys.attr,
-       &ignore_nice_gov_sys.attr,
+       &ignore_nice_load_gov_sys.attr,
        &freq_step_gov_sys.attr,
        NULL
 };
@@ -313,7 +313,7 @@ static struct attribute *dbs_attributes_gov_pol[] = {
        &sampling_down_factor_gov_pol.attr,
        &up_threshold_gov_pol.attr,
        &down_threshold_gov_pol.attr,
-       &ignore_nice_gov_pol.attr,
+       &ignore_nice_load_gov_pol.attr,
        &freq_step_gov_pol.attr,
        NULL
 };
@@ -338,7 +338,7 @@ static int cs_init(struct dbs_data *dbs_data)
        tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD;
        tuners->down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD;
        tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR;
-       tuners->ignore_nice = 0;
+       tuners->ignore_nice_load = 0;
        tuners->freq_step = DEF_FREQUENCY_STEP;
 
        dbs_data->tuners = tuners;
index 7b839a8..e59afaa 100644 (file)
@@ -47,9 +47,9 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
        unsigned int j;
 
        if (dbs_data->cdata->governor == GOV_ONDEMAND)
-               ignore_nice = od_tuners->ignore_nice;
+               ignore_nice = od_tuners->ignore_nice_load;
        else
-               ignore_nice = cs_tuners->ignore_nice;
+               ignore_nice = cs_tuners->ignore_nice_load;
 
        policy = cdbs->cur_policy;
 
@@ -298,12 +298,12 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                cs_tuners = dbs_data->tuners;
                cs_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu);
                sampling_rate = cs_tuners->sampling_rate;
-               ignore_nice = cs_tuners->ignore_nice;
+               ignore_nice = cs_tuners->ignore_nice_load;
        } else {
                od_tuners = dbs_data->tuners;
                od_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu);
                sampling_rate = od_tuners->sampling_rate;
-               ignore_nice = od_tuners->ignore_nice;
+               ignore_nice = od_tuners->ignore_nice_load;
                od_ops = dbs_data->cdata->gov_ops;
                io_busy = od_tuners->io_is_busy;
        }
index 6663ec3..d5f12b4 100644 (file)
@@ -165,7 +165,7 @@ struct cs_cpu_dbs_info_s {
 
 /* Per policy Governers sysfs tunables */
 struct od_dbs_tuners {
-       unsigned int ignore_nice;
+       unsigned int ignore_nice_load;
        unsigned int sampling_rate;
        unsigned int sampling_down_factor;
        unsigned int up_threshold;
@@ -175,7 +175,7 @@ struct od_dbs_tuners {
 };
 
 struct cs_dbs_tuners {
-       unsigned int ignore_nice;
+       unsigned int ignore_nice_load;
        unsigned int sampling_rate;
        unsigned int sampling_down_factor;
        unsigned int up_threshold;
index 93eb5cb..c087347 100644 (file)
@@ -403,8 +403,8 @@ static ssize_t store_sampling_down_factor(struct dbs_data *dbs_data,
        return count;
 }
 
-static ssize_t store_ignore_nice(struct dbs_data *dbs_data, const char *buf,
-               size_t count)
+static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data,
+               const char *buf, size_t count)
 {
        struct od_dbs_tuners *od_tuners = dbs_data->tuners;
        unsigned int input;
@@ -419,10 +419,10 @@ static ssize_t store_ignore_nice(struct dbs_data *dbs_data, const char *buf,
        if (input > 1)
                input = 1;
 
-       if (input == od_tuners->ignore_nice) { /* nothing to do */
+       if (input == od_tuners->ignore_nice_load) { /* nothing to do */
                return count;
        }
-       od_tuners->ignore_nice = input;
+       od_tuners->ignore_nice_load = input;
 
        /* we need to re-evaluate prev_cpu_idle */
        for_each_online_cpu(j) {
@@ -430,7 +430,7 @@ static ssize_t store_ignore_nice(struct dbs_data *dbs_data, const char *buf,
                dbs_info = &per_cpu(od_cpu_dbs_info, j);
                dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j,
                        &dbs_info->cdbs.prev_cpu_wall, od_tuners->io_is_busy);
-               if (od_tuners->ignore_nice)
+               if (od_tuners->ignore_nice_load)
                        dbs_info->cdbs.prev_cpu_nice =
                                kcpustat_cpu(j).cpustat[CPUTIME_NICE];
 
@@ -461,7 +461,7 @@ show_store_one(od, sampling_rate);
 show_store_one(od, io_is_busy);
 show_store_one(od, up_threshold);
 show_store_one(od, sampling_down_factor);
-show_store_one(od, ignore_nice);
+show_store_one(od, ignore_nice_load);
 show_store_one(od, powersave_bias);
 declare_show_sampling_rate_min(od);
 
@@ -469,7 +469,7 @@ gov_sys_pol_attr_rw(sampling_rate);
 gov_sys_pol_attr_rw(io_is_busy);
 gov_sys_pol_attr_rw(up_threshold);
 gov_sys_pol_attr_rw(sampling_down_factor);
-gov_sys_pol_attr_rw(ignore_nice);
+gov_sys_pol_attr_rw(ignore_nice_load);
 gov_sys_pol_attr_rw(powersave_bias);
 gov_sys_pol_attr_ro(sampling_rate_min);
 
@@ -478,7 +478,7 @@ static struct attribute *dbs_attributes_gov_sys[] = {
        &sampling_rate_gov_sys.attr,
        &up_threshold_gov_sys.attr,
        &sampling_down_factor_gov_sys.attr,
-       &ignore_nice_gov_sys.attr,
+       &ignore_nice_load_gov_sys.attr,
        &powersave_bias_gov_sys.attr,
        &io_is_busy_gov_sys.attr,
        NULL
@@ -494,7 +494,7 @@ static struct attribute *dbs_attributes_gov_pol[] = {
        &sampling_rate_gov_pol.attr,
        &up_threshold_gov_pol.attr,
        &sampling_down_factor_gov_pol.attr,
-       &ignore_nice_gov_pol.attr,
+       &ignore_nice_load_gov_pol.attr,
        &powersave_bias_gov_pol.attr,
        &io_is_busy_gov_pol.attr,
        NULL
@@ -544,7 +544,7 @@ static int od_init(struct dbs_data *dbs_data)
        }
 
        tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR;
-       tuners->ignore_nice = 0;
+       tuners->ignore_nice_load = 0;
        tuners->powersave_bias = default_powersave_bias;
        tuners->io_is_busy = should_io_be_busy();
 
index bb838b9..9536852 100644 (file)
@@ -118,11 +118,6 @@ static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
                clk_put(cpuclk);
                return -EINVAL;
        }
-       ret = clk_set_rate(cpuclk, rate);
-       if (ret) {
-               clk_put(cpuclk);
-               return ret;
-       }
 
        /* clock table init */
        for (i = 2;
@@ -130,6 +125,12 @@ static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
             i++)
                loongson2_clockmod_table[i].frequency = (rate * i) / 8;
 
+       ret = clk_set_rate(cpuclk, rate);
+       if (ret) {
+               clk_put(cpuclk);
+               return ret;
+       }
+
        policy->cur = loongson2_cpufreq_get(policy->cpu);
 
        cpufreq_frequency_table_get_attr(&loongson2_clockmod_table[0],
index b67f45f..5039fbc 100644 (file)
@@ -400,8 +400,8 @@ static size_t sh_dmae_get_partial(struct shdma_chan *schan,
                                                    shdma_chan);
        struct sh_dmae_desc *sh_desc = container_of(sdesc,
                                        struct sh_dmae_desc, shdma_desc);
-       return (sh_desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) <<
-               sh_chan->xmit_shift;
+       return sh_desc->hw.tcr -
+               (sh_dmae_readl(sh_chan, TCR) << sh_chan->xmit_shift);
 }
 
 /* Called from error IRQ or NMI */
index 98d6708..6e8887f 100644 (file)
@@ -323,6 +323,7 @@ int ast_bo_create(struct drm_device *dev, int size, int align,
 
        astbo->gem.driver_private = NULL;
        astbo->bo.bdev = &ast->ttm.bdev;
+       astbo->bo.bdev->dev_mapping = dev->dev_mapping;
 
        ast_ttm_placement(astbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
 
index 0047012..69fd8f1 100644 (file)
@@ -328,6 +328,7 @@ int cirrus_bo_create(struct drm_device *dev, int size, int align,
 
        cirrusbo->gem.driver_private = NULL;
        cirrusbo->bo.bdev = &cirrus->ttm.bdev;
+       cirrusbo->bo.bdev->dev_mapping = dev->dev_mapping;
 
        cirrus_ttm_placement(cirrusbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
 
index 8bcce78..f92da0a 100644 (file)
@@ -708,7 +708,10 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
        /* Subtract time delta from raw timestamp to get final
         * vblank_time timestamp for end of vblank.
         */
-       etime = ktime_sub_ns(etime, delta_ns);
+       if (delta_ns < 0)
+               etime = ktime_add_ns(etime, -delta_ns);
+       else
+               etime = ktime_sub_ns(etime, delta_ns);
        *vblank_time = ktime_to_timeval(etime);
 
        DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n",
index f2326fc..6f51429 100644 (file)
 #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV       (1 << 2)
 
 #define PORT_HOTPLUG_STAT      (dev_priv->info->display_mmio_offset + 0x61114)
-/* HDMI/DP bits are gen4+ */
-#define   PORTB_HOTPLUG_LIVE_STATUS               (1 << 29)
+/*
+ * HDMI/DP bits are gen4+
+ *
+ * WARNING: Bspec for hpd status bits on gen4 seems to be completely confused.
+ * Please check the detailed lore in the commit message for for experimental
+ * evidence.
+ */
+#define   PORTD_HOTPLUG_LIVE_STATUS               (1 << 29)
 #define   PORTC_HOTPLUG_LIVE_STATUS               (1 << 28)
-#define   PORTD_HOTPLUG_LIVE_STATUS               (1 << 27)
+#define   PORTB_HOTPLUG_LIVE_STATUS               (1 << 27)
 #define   PORTD_HOTPLUG_INT_STATUS             (3 << 21)
 #define   PORTC_HOTPLUG_INT_STATUS             (3 << 19)
 #define   PORTB_HOTPLUG_INT_STATUS             (3 << 17)
index 5fb3058..e38b457 100644 (file)
@@ -8269,9 +8269,11 @@ check_crtc_state(struct drm_device *dev)
 
                list_for_each_entry(encoder, &dev->mode_config.encoder_list,
                                    base.head) {
+                       enum pipe pipe;
                        if (encoder->base.crtc != &crtc->base)
                                continue;
-                       if (encoder->get_config)
+                       if (encoder->get_config &&
+                           encoder->get_hw_state(encoder, &pipe))
                                encoder->get_config(encoder, &pipe_config);
                }
 
index 67e2c1f..5950888 100644 (file)
@@ -497,8 +497,11 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max)
                goto out;
        }
 
-       /* scale to hardware */
-       level = level * freq / max;
+       /* scale to hardware, but be careful to not overflow */
+       if (freq < max)
+               level = level * freq / max;
+       else
+               level = freq / max * level;
 
        dev_priv->backlight.level = level;
        if (dev_priv->backlight.device)
@@ -515,6 +518,17 @@ void intel_panel_disable_backlight(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long flags;
 
+       /*
+        * Do not disable backlight on the vgaswitcheroo path. When switching
+        * away from i915, the other client may depend on i915 to handle the
+        * backlight. This will leave the backlight on unnecessarily when
+        * another client is not activated.
+        */
+       if (dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) {
+               DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n");
+               return;
+       }
+
        spin_lock_irqsave(&dev_priv->backlight.lock, flags);
 
        dev_priv->backlight.enabled = false;
index f895d15..b0e4a0b 100644 (file)
@@ -5063,8 +5063,26 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable)
                }
        } else {
                if (enable_requested) {
+                       unsigned long irqflags;
+                       enum pipe p;
+
                        I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
+                       POSTING_READ(HSW_PWR_WELL_DRIVER);
                        DRM_DEBUG_KMS("Requesting to disable the power well\n");
+
+                       /*
+                        * After this, the registers on the pipes that are part
+                        * of the power well will become zero, so we have to
+                        * adjust our counters according to that.
+                        *
+                        * FIXME: Should we do this in general in
+                        * drm_vblank_post_modeset?
+                        */
+                       spin_lock_irqsave(&dev->vbl_lock, irqflags);
+                       for_each_pipe(p)
+                               if (p != PIPE_A)
+                                       dev->last_vblank[p] = 0;
+                       spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
                }
        }
 }
index 13878d5..d70e4a9 100644 (file)
@@ -323,6 +323,7 @@ int mgag200_bo_create(struct drm_device *dev, int size, int align,
 
        mgabo->gem.driver_private = NULL;
        mgabo->bo.bdev = &mdev->ttm.bdev;
+       mgabo->bo.bdev->dev_mapping = dev->dev_mapping;
 
        mgag200_ttm_placement(mgabo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
 
index 0bfd55e..9953e1f 100644 (file)
@@ -2548,9 +2548,6 @@ int btc_dpm_init(struct radeon_device *rdev)
 {
        struct rv7xx_power_info *pi;
        struct evergreen_power_info *eg_pi;
-       int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
-       u16 data_offset, size;
-       u8 frev, crev;
        struct atom_clock_dividers dividers;
        int ret;
 
@@ -2633,16 +2630,7 @@ int btc_dpm_init(struct radeon_device *rdev)
        eg_pi->vddci_control =
                radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
 
-       if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
-                                   &frev, &crev, &data_offset)) {
-               pi->sclk_ss = true;
-               pi->mclk_ss = true;
-               pi->dynamic_ss = true;
-       } else {
-               pi->sclk_ss = false;
-               pi->mclk_ss = false;
-               pi->dynamic_ss = true;
-       }
+       rv770_get_engine_memory_ss(rdev);
 
        pi->asi = RV770_ASI_DFLT;
        pi->pasi = CYPRESS_HASI_DFLT;
@@ -2659,8 +2647,7 @@ int btc_dpm_init(struct radeon_device *rdev)
 
        pi->dynamic_pcie_gen2 = true;
 
-       if (pi->gfx_clock_gating &&
-           (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
+       if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
                pi->thermal_protection = true;
        else
                pi->thermal_protection = false;
index 6dacec4..8928bd1 100644 (file)
@@ -2587,9 +2587,11 @@ u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
        if (rdev->wb.enabled) {
                rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
        } else {
+               mutex_lock(&rdev->srbm_mutex);
                cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
                rptr = RREG32(CP_HQD_PQ_RPTR);
                cik_srbm_select(rdev, 0, 0, 0, 0);
+               mutex_unlock(&rdev->srbm_mutex);
        }
        rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
 
@@ -2604,9 +2606,11 @@ u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
        if (rdev->wb.enabled) {
                wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]);
        } else {
+               mutex_lock(&rdev->srbm_mutex);
                cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
                wptr = RREG32(CP_HQD_PQ_WPTR);
                cik_srbm_select(rdev, 0, 0, 0, 0);
+               mutex_unlock(&rdev->srbm_mutex);
        }
        wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
 
@@ -2897,6 +2901,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
        WREG32(CP_CPF_DEBUG, tmp);
 
        /* init the pipes */
+       mutex_lock(&rdev->srbm_mutex);
        for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); i++) {
                int me = (i < 4) ? 1 : 2;
                int pipe = (i < 4) ? i : (i - 4);
@@ -2919,6 +2924,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
                WREG32(CP_HPD_EOP_CONTROL, tmp);
        }
        cik_srbm_select(rdev, 0, 0, 0, 0);
+       mutex_unlock(&rdev->srbm_mutex);
 
        /* init the queues.  Just two for now. */
        for (i = 0; i < 2; i++) {
@@ -2972,6 +2978,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
                mqd->static_thread_mgmt23[0] = 0xffffffff;
                mqd->static_thread_mgmt23[1] = 0xffffffff;
 
+               mutex_lock(&rdev->srbm_mutex);
                cik_srbm_select(rdev, rdev->ring[idx].me,
                                rdev->ring[idx].pipe,
                                rdev->ring[idx].queue, 0);
@@ -3099,6 +3106,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
                WREG32(CP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active);
 
                cik_srbm_select(rdev, 0, 0, 0, 0);
+               mutex_unlock(&rdev->srbm_mutex);
 
                radeon_bo_kunmap(rdev->ring[idx].mqd_obj);
                radeon_bo_unreserve(rdev->ring[idx].mqd_obj);
@@ -4320,6 +4328,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
 
        /* XXX SH_MEM regs */
        /* where to put LDS, scratch, GPUVM in FSA64 space */
+       mutex_lock(&rdev->srbm_mutex);
        for (i = 0; i < 16; i++) {
                cik_srbm_select(rdev, 0, 0, 0, i);
                /* CP and shaders */
@@ -4335,6 +4344,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
                /* XXX SDMA RLC - todo */
        }
        cik_srbm_select(rdev, 0, 0, 0, 0);
+       mutex_unlock(&rdev->srbm_mutex);
 
        cik_pcie_gart_tlb_flush(rdev);
        DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
@@ -5954,6 +5964,8 @@ static int cik_startup(struct radeon_device *rdev)
        struct radeon_ring *ring;
        int r;
 
+       cik_mc_program(rdev);
+
        if (rdev->flags & RADEON_IS_IGP) {
                if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
                    !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) {
@@ -5985,7 +5997,6 @@ static int cik_startup(struct radeon_device *rdev)
        if (r)
                return r;
 
-       cik_mc_program(rdev);
        r = cik_pcie_gart_enable(rdev);
        if (r)
                return r;
@@ -6194,7 +6205,7 @@ int cik_suspend(struct radeon_device *rdev)
        radeon_vm_manager_fini(rdev);
        cik_cp_enable(rdev, false);
        cik_sdma_enable(rdev, false);
-       r600_uvd_rbc_stop(rdev);
+       r600_uvd_stop(rdev);
        radeon_uvd_suspend(rdev);
        cik_irq_suspend(rdev);
        radeon_wb_disable(rdev);
@@ -6358,6 +6369,7 @@ void cik_fini(struct radeon_device *rdev)
        radeon_vm_manager_fini(rdev);
        radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
+       r600_uvd_stop(rdev);
        radeon_uvd_fini(rdev);
        cik_pcie_gart_fini(rdev);
        r600_vram_scratch_fini(rdev);
@@ -6978,7 +6990,7 @@ int cik_uvd_resume(struct radeon_device *rdev)
 
        /* programm the VCPU memory controller bits 0-27 */
        addr = rdev->uvd.gpu_addr >> 3;
-       size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3;
+       size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
        WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
        WREG32(UVD_VCPU_CACHE_SIZE0, size);
 
index 9bcdd17..7e5d0b5 100644 (file)
@@ -2038,9 +2038,6 @@ int cypress_dpm_init(struct radeon_device *rdev)
 {
        struct rv7xx_power_info *pi;
        struct evergreen_power_info *eg_pi;
-       int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
-       uint16_t data_offset, size;
-       uint8_t frev, crev;
        struct atom_clock_dividers dividers;
        int ret;
 
@@ -2092,16 +2089,7 @@ int cypress_dpm_init(struct radeon_device *rdev)
        eg_pi->vddci_control =
                radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
 
-       if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
-                                   &frev, &crev, &data_offset)) {
-               pi->sclk_ss = true;
-               pi->mclk_ss = true;
-               pi->dynamic_ss = true;
-       } else {
-               pi->sclk_ss = false;
-               pi->mclk_ss = false;
-               pi->dynamic_ss = true;
-       }
+       rv770_get_engine_memory_ss(rdev);
 
        pi->asi = RV770_ASI_DFLT;
        pi->pasi = CYPRESS_HASI_DFLT;
@@ -2122,8 +2110,7 @@ int cypress_dpm_init(struct radeon_device *rdev)
 
        pi->dynamic_pcie_gen2 = true;
 
-       if (pi->gfx_clock_gating &&
-           (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
+       if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
                pi->thermal_protection = true;
        else
                pi->thermal_protection = false;
index 038dcac..d5b49e3 100644 (file)
@@ -5106,6 +5106,8 @@ static int evergreen_startup(struct radeon_device *rdev)
        /* enable aspm */
        evergreen_program_aspm(rdev);
 
+       evergreen_mc_program(rdev);
+
        if (ASIC_IS_DCE5(rdev)) {
                if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
                        r = ni_init_microcode(rdev);
@@ -5133,7 +5135,6 @@ static int evergreen_startup(struct radeon_device *rdev)
        if (r)
                return r;
 
-       evergreen_mc_program(rdev);
        if (rdev->flags & RADEON_IS_AGP) {
                evergreen_agp_enable(rdev);
        } else {
@@ -5291,10 +5292,10 @@ int evergreen_resume(struct radeon_device *rdev)
 int evergreen_suspend(struct radeon_device *rdev)
 {
        r600_audio_fini(rdev);
+       r600_uvd_stop(rdev);
        radeon_uvd_suspend(rdev);
        r700_cp_stop(rdev);
        r600_dma_stop(rdev);
-       r600_uvd_rbc_stop(rdev);
        evergreen_irq_suspend(rdev);
        radeon_wb_disable(rdev);
        evergreen_pcie_gart_disable(rdev);
@@ -5429,6 +5430,7 @@ void evergreen_fini(struct radeon_device *rdev)
        radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        evergreen_pcie_gart_fini(rdev);
+       r600_uvd_stop(rdev);
        radeon_uvd_fini(rdev);
        r600_vram_scratch_fini(rdev);
        radeon_gem_fini(rdev);
index bb9ea36..b0e2800 100644 (file)
@@ -148,18 +148,40 @@ static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock)
        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
        u32 base_rate = 24000;
+       u32 max_ratio = clock / base_rate;
+       u32 dto_phase;
+       u32 dto_modulo = clock;
+       u32 wallclock_ratio;
+       u32 dto_cntl;
 
        if (!dig || !dig->afmt)
                return;
 
+       if (max_ratio >= 8) {
+               dto_phase = 192 * 1000;
+               wallclock_ratio = 3;
+       } else if (max_ratio >= 4) {
+               dto_phase = 96 * 1000;
+               wallclock_ratio = 2;
+       } else if (max_ratio >= 2) {
+               dto_phase = 48 * 1000;
+               wallclock_ratio = 1;
+       } else {
+               dto_phase = 24 * 1000;
+               wallclock_ratio = 0;
+       }
+       dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
+       dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
+       WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl);
+
        /* XXX two dtos; generally use dto0 for hdmi */
        /* Express [24MHz / target pixel clock] as an exact rational
         * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
         * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
         */
        WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id));
-       WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
-       WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
+       WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase);
+       WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo);
 }
 
 
index a7baf67..0d582ac 100644 (file)
 #define DCCG_AUDIO_DTO0_MODULE            0x05b4
 #define DCCG_AUDIO_DTO0_LOAD              0x05b8
 #define DCCG_AUDIO_DTO0_CNTL              0x05bc
+#       define DCCG_AUDIO_DTO_WALLCLOCK_RATIO(x) (((x) & 7) << 0)
+#       define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK 7
+#       define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_SHIFT 0
 
 #define DCCG_AUDIO_DTO1_PHASE             0x05c0
 #define DCCG_AUDIO_DTO1_MODULE            0x05c4
index 56bd4f3..ccb4f8b 100644 (file)
@@ -794,9 +794,13 @@ int ni_init_microcode(struct radeon_device *rdev)
        if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) {
                snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
                err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
-               if (err)
-                       goto out;
-               if (rdev->smc_fw->size != smc_req_size) {
+               if (err) {
+                       printk(KERN_ERR
+                              "smc: error loading firmware \"%s\"\n",
+                              fw_name);
+                       release_firmware(rdev->smc_fw);
+                       rdev->smc_fw = NULL;
+               } else if (rdev->smc_fw->size != smc_req_size) {
                        printk(KERN_ERR
                               "ni_mc: Bogus length %zu in firmware \"%s\"\n",
                               rdev->mc_fw->size, fw_name);
@@ -2079,6 +2083,8 @@ static int cayman_startup(struct radeon_device *rdev)
        /* enable aspm */
        evergreen_program_aspm(rdev);
 
+       evergreen_mc_program(rdev);
+
        if (rdev->flags & RADEON_IS_IGP) {
                if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
                        r = ni_init_microcode(rdev);
@@ -2107,7 +2113,6 @@ static int cayman_startup(struct radeon_device *rdev)
        if (r)
                return r;
 
-       evergreen_mc_program(rdev);
        r = cayman_pcie_gart_enable(rdev);
        if (r)
                return r;
@@ -2286,7 +2291,7 @@ int cayman_suspend(struct radeon_device *rdev)
        radeon_vm_manager_fini(rdev);
        cayman_cp_enable(rdev, false);
        cayman_dma_stop(rdev);
-       r600_uvd_rbc_stop(rdev);
+       r600_uvd_stop(rdev);
        radeon_uvd_suspend(rdev);
        evergreen_irq_suspend(rdev);
        radeon_wb_disable(rdev);
@@ -2418,6 +2423,7 @@ void cayman_fini(struct radeon_device *rdev)
        radeon_vm_manager_fini(rdev);
        radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
+       r600_uvd_stop(rdev);
        radeon_uvd_fini(rdev);
        cayman_pcie_gart_fini(rdev);
        r600_vram_scratch_fini(rdev);
index 4f9b9bc..f0f5f74 100644 (file)
@@ -4067,9 +4067,6 @@ int ni_dpm_init(struct radeon_device *rdev)
        struct rv7xx_power_info *pi;
        struct evergreen_power_info *eg_pi;
        struct ni_power_info *ni_pi;
-       int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
-       u16 data_offset, size;
-       u8 frev, crev;
        struct atom_clock_dividers dividers;
        int ret;
 
@@ -4162,16 +4159,7 @@ int ni_dpm_init(struct radeon_device *rdev)
        eg_pi->vddci_control =
                radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
 
-       if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
-                                   &frev, &crev, &data_offset)) {
-               pi->sclk_ss = true;
-               pi->mclk_ss = true;
-               pi->dynamic_ss = true;
-       } else {
-               pi->sclk_ss = false;
-               pi->mclk_ss = false;
-               pi->dynamic_ss = true;
-       }
+       rv770_get_engine_memory_ss(rdev);
 
        pi->asi = RV770_ASI_DFLT;
        pi->pasi = CYPRESS_HASI_DFLT;
@@ -4188,8 +4176,7 @@ int ni_dpm_init(struct radeon_device *rdev)
 
        pi->dynamic_pcie_gen2 = true;
 
-       if (pi->gfx_clock_gating &&
-           (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
+       if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
                pi->thermal_protection = true;
        else
                pi->thermal_protection = false;
index 10f712e..e66e720 100644 (file)
@@ -2299,9 +2299,13 @@ int r600_init_microcode(struct radeon_device *rdev)
        if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_HEMLOCK)) {
                snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", smc_chip_name);
                err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
-               if (err)
-                       goto out;
-               if (rdev->smc_fw->size != smc_req_size) {
+               if (err) {
+                       printk(KERN_ERR
+                              "smc: error loading firmware \"%s\"\n",
+                              fw_name);
+                       release_firmware(rdev->smc_fw);
+                       rdev->smc_fw = NULL;
+               } else if (rdev->smc_fw->size != smc_req_size) {
                        printk(KERN_ERR
                               "smc: Bogus length %zu in firmware \"%s\"\n",
                               rdev->smc_fw->size, fw_name);
@@ -2697,12 +2701,29 @@ int r600_uvd_rbc_start(struct radeon_device *rdev)
        return 0;
 }
 
-void r600_uvd_rbc_stop(struct radeon_device *rdev)
+void r600_uvd_stop(struct radeon_device *rdev)
 {
        struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 
        /* force RBC into idle state */
        WREG32(UVD_RBC_RB_CNTL, 0x11010101);
+
+       /* Stall UMC and register bus before resetting VCPU */
+       WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
+       WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
+       mdelay(1);
+
+       /* put VCPU into reset */
+       WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
+       mdelay(5);
+
+       /* disable VCPU clock */
+       WREG32(UVD_VCPU_CNTL, 0x0);
+
+       /* Unstall UMC and register bus */
+       WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
+       WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
+
        ring->ready = false;
 }
 
@@ -2722,6 +2743,11 @@ int r600_uvd_init(struct radeon_device *rdev)
        /* disable interupt */
        WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
 
+       /* Stall UMC and register bus before resetting VCPU */
+       WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
+       WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
+       mdelay(1);
+
        /* put LMI, VCPU, RBC etc... into reset */
        WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
               LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
@@ -2751,10 +2777,6 @@ int r600_uvd_init(struct radeon_device *rdev)
        WREG32(UVD_MPC_SET_ALU, 0);
        WREG32(UVD_MPC_SET_MUX, 0x88);
 
-       /* Stall UMC */
-       WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
-       WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
-
        /* take all subblocks out of reset, except VCPU */
        WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
        mdelay(5);
@@ -3312,6 +3334,8 @@ static int r600_startup(struct radeon_device *rdev)
        /* enable pcie gen2 link */
        r600_pcie_gen2_enable(rdev);
 
+       r600_mc_program(rdev);
+
        if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
                r = r600_init_microcode(rdev);
                if (r) {
@@ -3324,7 +3348,6 @@ static int r600_startup(struct radeon_device *rdev)
        if (r)
                return r;
 
-       r600_mc_program(rdev);
        if (rdev->flags & RADEON_IS_AGP) {
                r600_agp_enable(rdev);
        } else {
index f48240b..f264df5 100644 (file)
@@ -226,10 +226,29 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
        u32 base_rate = 24000;
+       u32 max_ratio = clock / base_rate;
+       u32 dto_phase;
+       u32 dto_modulo = clock;
+       u32 wallclock_ratio;
+       u32 dto_cntl;
 
        if (!dig || !dig->afmt)
                return;
 
+       if (max_ratio >= 8) {
+               dto_phase = 192 * 1000;
+               wallclock_ratio = 3;
+       } else if (max_ratio >= 4) {
+               dto_phase = 96 * 1000;
+               wallclock_ratio = 2;
+       } else if (max_ratio >= 2) {
+               dto_phase = 48 * 1000;
+               wallclock_ratio = 1;
+       } else {
+               dto_phase = 24 * 1000;
+               wallclock_ratio = 0;
+       }
+
        /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT.
         * doesn't matter which one you use.  Just use the first one.
         */
@@ -242,9 +261,21 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
                /* according to the reg specs, this should DCE3.2 only, but in
                 * practice it seems to cover DCE3.0 as well.
                 */
-               WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
-               WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
-               WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
+               if (dig->dig_encoder == 0) {
+                       dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
+                       dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
+                       WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl);
+                       WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase);
+                       WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo);
+                       WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
+               } else {
+                       dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
+                       dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
+                       WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl);
+                       WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase);
+                       WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo);
+                       WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
+               }
        } else {
                /* according to the reg specs, this should be DCE2.0 and DCE3.0 */
                WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) |
index 8e3fe81..7c78083 100644 (file)
 #define DCCG_AUDIO_DTO0_LOAD              0x051c
 #       define DTO_LOAD                   (1 << 31)
 #define DCCG_AUDIO_DTO0_CNTL              0x0520
+#       define DCCG_AUDIO_DTO_WALLCLOCK_RATIO(x) (((x) & 7) << 0)
+#       define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK 7
+#       define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_SHIFT 0
 
 #define DCCG_AUDIO_DTO1_PHASE             0x0524
 #define DCCG_AUDIO_DTO1_MODULE            0x0528
index 2f08219..274b8e1 100644 (file)
@@ -1468,7 +1468,6 @@ struct radeon_uvd {
        void                    *cpu_addr;
        uint64_t                gpu_addr;
        void                    *saved_bo;
-       unsigned                fw_size;
        atomic_t                handles[RADEON_MAX_UVD_HANDLES];
        struct drm_file         *filp[RADEON_MAX_UVD_HANDLES];
        struct delayed_work     idle_work;
@@ -2066,6 +2065,7 @@ struct radeon_device {
        const struct firmware *mec_fw;  /* CIK MEC firmware */
        const struct firmware *sdma_fw; /* CIK SDMA firmware */
        const struct firmware *smc_fw;  /* SMC firmware */
+       const struct firmware *uvd_fw;  /* UVD firmware */
        struct r600_blit r600_blit;
        struct r600_vram_scratch vram_scratch;
        int msi_enabled; /* msi enabled */
@@ -2095,6 +2095,8 @@ struct radeon_device {
        /* ACPI interface */
        struct radeon_atif              atif;
        struct radeon_atcs              atcs;
+       /* srbm instance registers */
+       struct mutex                    srbm_mutex;
 };
 
 int radeon_device_init(struct radeon_device *rdev,
index 902479f..3d61d5a 100644 (file)
@@ -441,7 +441,7 @@ void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rde
 /* uvd */
 int r600_uvd_init(struct radeon_device *rdev);
 int r600_uvd_rbc_start(struct radeon_device *rdev);
-void r600_uvd_rbc_stop(struct radeon_device *rdev);
+void r600_uvd_stop(struct radeon_device *rdev);
 int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
 void r600_uvd_fence_emit(struct radeon_device *rdev,
                         struct radeon_fence *fence);
index 82335e3..63398ae 100644 (file)
@@ -1163,6 +1163,7 @@ int radeon_device_init(struct radeon_device *rdev,
        mutex_init(&rdev->gem.mutex);
        mutex_init(&rdev->pm.mutex);
        mutex_init(&rdev->gpu_clock_mutex);
+       mutex_init(&rdev->srbm_mutex);
        init_rwsem(&rdev->pm.mclk_lock);
        init_rwsem(&rdev->exclusive_lock);
        init_waitqueue_head(&rdev->irq.vblank_queue);
@@ -1519,6 +1520,7 @@ int radeon_gpu_reset(struct radeon_device *rdev)
        radeon_save_bios_scratch_regs(rdev);
        /* block TTM */
        resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
+       radeon_pm_suspend(rdev);
        radeon_suspend(rdev);
 
        for (i = 0; i < RADEON_NUM_RINGS; ++i) {
@@ -1564,6 +1566,7 @@ retry:
                }
        }
 
+       radeon_pm_resume(rdev);
        drm_helper_resume_force_mode(rdev->ddev);
 
        ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
index 7ddb0ef..ddb8f8e 100644 (file)
@@ -782,7 +782,7 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring)
 
                } else {
                        /* put fence directly behind firmware */
-                       index = ALIGN(rdev->uvd.fw_size, 8);
+                       index = ALIGN(rdev->uvd_fw->size, 8);
                        rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index;
                        rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index;
                }
index 6a51d94..b990b1a 100644 (file)
@@ -207,7 +207,6 @@ void radeon_gart_table_vram_free(struct radeon_device *rdev)
        if (rdev->gart.robj == NULL) {
                return;
        }
-       radeon_gart_table_vram_unpin(rdev);
        radeon_bo_unref(&rdev->gart.robj);
 }
 
index f374c46..c557850 100644 (file)
@@ -1176,7 +1176,14 @@ int radeon_pm_init(struct radeon_device *rdev)
        case CHIP_VERDE:
        case CHIP_OLAND:
        case CHIP_HAINAN:
-               if (radeon_dpm == 1)
+               /* DPM requires the RLC, RV770+ dGPU requires SMC */
+               if (!rdev->rlc_fw)
+                       rdev->pm.pm_method = PM_METHOD_PROFILE;
+               else if ((rdev->family >= CHIP_RV770) &&
+                        (!(rdev->flags & RADEON_IS_IGP)) &&
+                        (!rdev->smc_fw))
+                       rdev->pm.pm_method = PM_METHOD_PROFILE;
+               else if (radeon_dpm == 1)
                        rdev->pm.pm_method = PM_METHOD_DPM;
                else
                        rdev->pm.pm_method = PM_METHOD_PROFILE;
index 414fd14..f1c1575 100644 (file)
@@ -56,7 +56,6 @@ static void radeon_uvd_idle_work_handler(struct work_struct *work);
 
 int radeon_uvd_init(struct radeon_device *rdev)
 {
-       const struct firmware *fw;
        unsigned long bo_size;
        const char *fw_name;
        int i, r;
@@ -105,14 +104,14 @@ int radeon_uvd_init(struct radeon_device *rdev)
                return -EINVAL;
        }
 
-       r = request_firmware(&fw, fw_name, rdev->dev);
+       r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev);
        if (r) {
                dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n",
                        fw_name);
                return r;
        }
 
-       bo_size = RADEON_GPU_PAGE_ALIGN(fw->size + 8) +
+       bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) +
                  RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE;
        r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true,
                             RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo);
@@ -145,12 +144,6 @@ int radeon_uvd_init(struct radeon_device *rdev)
 
        radeon_bo_unreserve(rdev->uvd.vcpu_bo);
 
-       rdev->uvd.fw_size = fw->size;
-       memset(rdev->uvd.cpu_addr, 0, bo_size);
-       memcpy(rdev->uvd.cpu_addr, fw->data, fw->size);
-
-       release_firmware(fw);
-
        for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
                atomic_set(&rdev->uvd.handles[i], 0);
                rdev->uvd.filp[i] = NULL;
@@ -174,33 +167,60 @@ void radeon_uvd_fini(struct radeon_device *rdev)
        }
 
        radeon_bo_unref(&rdev->uvd.vcpu_bo);
+
+       release_firmware(rdev->uvd_fw);
 }
 
 int radeon_uvd_suspend(struct radeon_device *rdev)
 {
        unsigned size;
+       void *ptr;
+       int i;
 
        if (rdev->uvd.vcpu_bo == NULL)
                return 0;
 
+       for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
+               if (atomic_read(&rdev->uvd.handles[i]))
+                       break;
+
+       if (i == RADEON_MAX_UVD_HANDLES)
+               return 0;
+
        size = radeon_bo_size(rdev->uvd.vcpu_bo);
+       size -= rdev->uvd_fw->size;
+
+       ptr = rdev->uvd.cpu_addr;
+       ptr += rdev->uvd_fw->size;
+
        rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL);
-       memcpy(rdev->uvd.saved_bo, rdev->uvd.cpu_addr, size);
+       memcpy(rdev->uvd.saved_bo, ptr, size);
 
        return 0;
 }
 
 int radeon_uvd_resume(struct radeon_device *rdev)
 {
+       unsigned size;
+       void *ptr;
+
        if (rdev->uvd.vcpu_bo == NULL)
                return -EINVAL;
 
+       memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size);
+
+       size = radeon_bo_size(rdev->uvd.vcpu_bo);
+       size -= rdev->uvd_fw->size;
+
+       ptr = rdev->uvd.cpu_addr;
+       ptr += rdev->uvd_fw->size;
+
        if (rdev->uvd.saved_bo != NULL) {
-               unsigned size = radeon_bo_size(rdev->uvd.vcpu_bo);
-               memcpy(rdev->uvd.cpu_addr, rdev->uvd.saved_bo, size);
+               memcpy(ptr, rdev->uvd.saved_bo, size);
                kfree(rdev->uvd.saved_bo);
                rdev->uvd.saved_bo = NULL;
-       }
+       } else
+               memset(ptr, 0, size);
 
        return 0;
 }
@@ -215,8 +235,8 @@ void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp)
 {
        int i, r;
        for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
-               if (rdev->uvd.filp[i] == filp) {
-                       uint32_t handle = atomic_read(&rdev->uvd.handles[i]);
+               uint32_t handle = atomic_read(&rdev->uvd.handles[i]);
+               if (handle != 0 && rdev->uvd.filp[i] == filp) {
                        struct radeon_fence *fence;
 
                        r = radeon_uvd_get_destroy_msg(rdev,
@@ -337,8 +357,10 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
        }
 
        r = radeon_bo_kmap(bo, &ptr);
-       if (r)
+       if (r) {
+               DRM_ERROR("Failed mapping the UVD message (%d)!\n", r);
                return r;
+       }
 
        msg = ptr + offset;
 
@@ -364,8 +386,14 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
                radeon_bo_kunmap(bo);
                return 0;
        } else {
-               /* it's a create msg, no special handling needed */
                radeon_bo_kunmap(bo);
+
+               if (msg_type != 0) {
+                       DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
+                       return -EINVAL;
+               }
+
+               /* it's a create msg, no special handling needed */
        }
 
        /* create or decode, validate the handle */
@@ -388,7 +416,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
 
 static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
                               int data0, int data1,
-                              unsigned buf_sizes[])
+                              unsigned buf_sizes[], bool *has_msg_cmd)
 {
        struct radeon_cs_chunk *relocs_chunk;
        struct radeon_cs_reloc *reloc;
@@ -417,7 +445,7 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
 
        if (cmd < 0x4) {
                if ((end - start) < buf_sizes[cmd]) {
-                       DRM_ERROR("buffer to small (%d / %d)!\n",
+                       DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd,
                                  (unsigned)(end - start), buf_sizes[cmd]);
                        return -EINVAL;
                }
@@ -442,9 +470,17 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
        }
 
        if (cmd == 0) {
+               if (*has_msg_cmd) {
+                       DRM_ERROR("More than one message in a UVD-IB!\n");
+                       return -EINVAL;
+               }
+               *has_msg_cmd = true;
                r = radeon_uvd_cs_msg(p, reloc->robj, offset, buf_sizes);
                if (r)
                        return r;
+       } else if (!*has_msg_cmd) {
+               DRM_ERROR("Message needed before other commands are send!\n");
+               return -EINVAL;
        }
 
        return 0;
@@ -453,7 +489,8 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
 static int radeon_uvd_cs_reg(struct radeon_cs_parser *p,
                             struct radeon_cs_packet *pkt,
                             int *data0, int *data1,
-                            unsigned buf_sizes[])
+                            unsigned buf_sizes[],
+                            bool *has_msg_cmd)
 {
        int i, r;
 
@@ -467,7 +504,8 @@ static int radeon_uvd_cs_reg(struct radeon_cs_parser *p,
                        *data1 = p->idx;
                        break;
                case UVD_GPCOM_VCPU_CMD:
-                       r = radeon_uvd_cs_reloc(p, *data0, *data1, buf_sizes);
+                       r = radeon_uvd_cs_reloc(p, *data0, *data1,
+                                               buf_sizes, has_msg_cmd);
                        if (r)
                                return r;
                        break;
@@ -488,6 +526,9 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p)
        struct radeon_cs_packet pkt;
        int r, data0 = 0, data1 = 0;
 
+       /* does the IB has a msg command */
+       bool has_msg_cmd = false;
+
        /* minimum buffer sizes */
        unsigned buf_sizes[] = {
                [0x00000000]    =       2048,
@@ -514,8 +555,8 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p)
                        return r;
                switch (pkt.type) {
                case RADEON_PACKET_TYPE0:
-                       r = radeon_uvd_cs_reg(p, &pkt, &data0,
-                                             &data1, buf_sizes);
+                       r = radeon_uvd_cs_reg(p, &pkt, &data0, &data1,
+                                             buf_sizes, &has_msg_cmd);
                        if (r)
                                return r;
                        break;
@@ -527,6 +568,12 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p)
                        return -EINVAL;
                }
        } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
+
+       if (!has_msg_cmd) {
+               DRM_ERROR("UVD-IBs need a msg command!\n");
+               return -EINVAL;
+       }
+
        return 0;
 }
 
index 363018c..bdd888b 100644 (file)
@@ -1944,9 +1944,7 @@ static int rv6xx_parse_power_table(struct radeon_device *rdev)
 
 int rv6xx_dpm_init(struct radeon_device *rdev)
 {
-       int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
-       uint16_t data_offset, size;
-       uint8_t frev, crev;
+       struct radeon_atom_ss ss;
        struct atom_clock_dividers dividers;
        struct rv6xx_power_info *pi;
        int ret;
@@ -1989,16 +1987,18 @@ int rv6xx_dpm_init(struct radeon_device *rdev)
 
        pi->gfx_clock_gating = true;
 
-       if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
-                                   &frev, &crev, &data_offset)) {
-               pi->sclk_ss = true;
-               pi->mclk_ss = true;
+       pi->sclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
+                                                      ASIC_INTERNAL_ENGINE_SS, 0);
+       pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
+                                                      ASIC_INTERNAL_MEMORY_SS, 0);
+
+       /* Disable sclk ss, causes hangs on a lot of systems */
+       pi->sclk_ss = false;
+
+       if (pi->sclk_ss || pi->mclk_ss)
                pi->dynamic_ss = true;
-       } else {
-               pi->sclk_ss = false;
-               pi->mclk_ss = false;
+       else
                pi->dynamic_ss = false;
-       }
 
        pi->dynamic_pcie_gen2 = true;
 
index 30ea14e..bcc68ec 100644 (file)
@@ -813,7 +813,7 @@ int rv770_uvd_resume(struct radeon_device *rdev)
 
        /* programm the VCPU memory controller bits 0-27 */
        addr = rdev->uvd.gpu_addr >> 3;
-       size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3;
+       size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
        WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
        WREG32(UVD_VCPU_CACHE_SIZE0, size);
 
@@ -1829,6 +1829,8 @@ static int rv770_startup(struct radeon_device *rdev)
        /* enable pcie gen2 link */
        rv770_pcie_gen2_enable(rdev);
 
+       rv770_mc_program(rdev);
+
        if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
                r = r600_init_microcode(rdev);
                if (r) {
@@ -1841,7 +1843,6 @@ static int rv770_startup(struct radeon_device *rdev)
        if (r)
                return r;
 
-       rv770_mc_program(rdev);
        if (rdev->flags & RADEON_IS_AGP) {
                rv770_agp_enable(rdev);
        } else {
@@ -1983,6 +1984,7 @@ int rv770_resume(struct radeon_device *rdev)
 int rv770_suspend(struct radeon_device *rdev)
 {
        r600_audio_fini(rdev);
+       r600_uvd_stop(rdev);
        radeon_uvd_suspend(rdev);
        r700_cp_stop(rdev);
        r600_dma_stop(rdev);
@@ -2098,6 +2100,7 @@ void rv770_fini(struct radeon_device *rdev)
        radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        rv770_pcie_gart_fini(rdev);
+       r600_uvd_stop(rdev);
        radeon_uvd_fini(rdev);
        r600_vram_scratch_fini(rdev);
        radeon_gem_fini(rdev);
index 2d34792..094c67a 100644 (file)
@@ -2319,12 +2319,25 @@ int rv7xx_parse_power_table(struct radeon_device *rdev)
        return 0;
 }
 
+void rv770_get_engine_memory_ss(struct radeon_device *rdev)
+{
+       struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+       struct radeon_atom_ss ss;
+
+       pi->sclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
+                                                      ASIC_INTERNAL_ENGINE_SS, 0);
+       pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
+                                                      ASIC_INTERNAL_MEMORY_SS, 0);
+
+       if (pi->sclk_ss || pi->mclk_ss)
+               pi->dynamic_ss = true;
+       else
+               pi->dynamic_ss = false;
+}
+
 int rv770_dpm_init(struct radeon_device *rdev)
 {
        struct rv7xx_power_info *pi;
-       int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
-       uint16_t data_offset, size;
-       uint8_t frev, crev;
        struct atom_clock_dividers dividers;
        int ret;
 
@@ -2369,16 +2382,7 @@ int rv770_dpm_init(struct radeon_device *rdev)
        pi->mvdd_control =
                radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
 
-       if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
-                                   &frev, &crev, &data_offset)) {
-               pi->sclk_ss = true;
-               pi->mclk_ss = true;
-               pi->dynamic_ss = true;
-       } else {
-               pi->sclk_ss = false;
-               pi->mclk_ss = false;
-               pi->dynamic_ss = false;
-       }
+       rv770_get_engine_memory_ss(rdev);
 
        pi->asi = RV770_ASI_DFLT;
        pi->pasi = RV770_HASI_DFLT;
@@ -2393,8 +2397,7 @@ int rv770_dpm_init(struct radeon_device *rdev)
 
        pi->dynamic_pcie_gen2 = true;
 
-       if (pi->gfx_clock_gating &&
-           (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
+       if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
                pi->thermal_protection = true;
        else
                pi->thermal_protection = false;
index 96b1b2a..9244eff 100644 (file)
@@ -275,6 +275,7 @@ void rv770_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
 void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
                                             struct radeon_ps *new_ps,
                                             struct radeon_ps *old_ps);
+void rv770_get_engine_memory_ss(struct radeon_device *rdev);
 
 /* smc */
 int rv770_read_smc_soft_register(struct radeon_device *rdev,
index 6ca9046..daa8d2d 100644 (file)
@@ -1663,9 +1663,13 @@ static int si_init_microcode(struct radeon_device *rdev)
 
        snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
        err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
-       if (err)
-               goto out;
-       if (rdev->smc_fw->size != smc_req_size) {
+       if (err) {
+               printk(KERN_ERR
+                      "smc: error loading firmware \"%s\"\n",
+                      fw_name);
+               release_firmware(rdev->smc_fw);
+               rdev->smc_fw = NULL;
+       } else if (rdev->smc_fw->size != smc_req_size) {
                printk(KERN_ERR
                       "si_smc: Bogus length %zu in firmware \"%s\"\n",
                       rdev->smc_fw->size, fw_name);
@@ -6418,6 +6422,8 @@ static int si_startup(struct radeon_device *rdev)
        /* enable aspm */
        si_program_aspm(rdev);
 
+       si_mc_program(rdev);
+
        if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
            !rdev->rlc_fw || !rdev->mc_fw) {
                r = si_init_microcode(rdev);
@@ -6437,7 +6443,6 @@ static int si_startup(struct radeon_device *rdev)
        if (r)
                return r;
 
-       si_mc_program(rdev);
        r = si_pcie_gart_enable(rdev);
        if (r)
                return r;
@@ -6621,7 +6626,7 @@ int si_suspend(struct radeon_device *rdev)
        si_cp_enable(rdev, false);
        cayman_dma_stop(rdev);
        if (rdev->has_uvd) {
-               r600_uvd_rbc_stop(rdev);
+               r600_uvd_stop(rdev);
                radeon_uvd_suspend(rdev);
        }
        si_irq_suspend(rdev);
@@ -6763,8 +6768,10 @@ void si_fini(struct radeon_device *rdev)
        radeon_vm_manager_fini(rdev);
        radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
-       if (rdev->has_uvd)
+       if (rdev->has_uvd) {
+               r600_uvd_stop(rdev);
                radeon_uvd_fini(rdev);
+       }
        si_pcie_gart_fini(rdev);
        r600_vram_scratch_fini(rdev);
        radeon_gem_fini(rdev);
index 4182557..88699e3 100644 (file)
@@ -2903,7 +2903,8 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
 {
        struct ni_ps *ps = ni_get_ps(rps);
        struct radeon_clock_and_voltage_limits *max_limits;
-       bool disable_mclk_switching;
+       bool disable_mclk_switching = false;
+       bool disable_sclk_switching = false;
        u32 mclk, sclk;
        u16 vddc, vddci;
        int i;
@@ -2911,8 +2912,11 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
        if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
            ni_dpm_vblank_too_short(rdev))
                disable_mclk_switching = true;
-       else
-               disable_mclk_switching = false;
+
+       if (rps->vclk || rps->dclk) {
+               disable_mclk_switching = true;
+               disable_sclk_switching = true;
+       }
 
        if (rdev->pm.dpm.ac_power)
                max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
@@ -2940,27 +2944,43 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
 
        if (disable_mclk_switching) {
                mclk  = ps->performance_levels[ps->performance_level_count - 1].mclk;
-               sclk = ps->performance_levels[0].sclk;
-               vddc = ps->performance_levels[0].vddc;
                vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;
        } else {
-               sclk = ps->performance_levels[0].sclk;
                mclk = ps->performance_levels[0].mclk;
-               vddc = ps->performance_levels[0].vddc;
                vddci = ps->performance_levels[0].vddci;
        }
 
+       if (disable_sclk_switching) {
+               sclk = ps->performance_levels[ps->performance_level_count - 1].sclk;
+               vddc = ps->performance_levels[ps->performance_level_count - 1].vddc;
+       } else {
+               sclk = ps->performance_levels[0].sclk;
+               vddc = ps->performance_levels[0].vddc;
+       }
+
        /* adjusted low state */
        ps->performance_levels[0].sclk = sclk;
        ps->performance_levels[0].mclk = mclk;
        ps->performance_levels[0].vddc = vddc;
        ps->performance_levels[0].vddci = vddci;
 
-       for (i = 1; i < ps->performance_level_count; i++) {
-               if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)
-                       ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;
-               if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)
-                       ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
+       if (disable_sclk_switching) {
+               sclk = ps->performance_levels[0].sclk;
+               for (i = 1; i < ps->performance_level_count; i++) {
+                       if (sclk < ps->performance_levels[i].sclk)
+                               sclk = ps->performance_levels[i].sclk;
+               }
+               for (i = 0; i < ps->performance_level_count; i++) {
+                       ps->performance_levels[i].sclk = sclk;
+                       ps->performance_levels[i].vddc = vddc;
+               }
+       } else {
+               for (i = 1; i < ps->performance_level_count; i++) {
+                       if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)
+                               ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;
+                       if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)
+                               ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
+               }
        }
 
        if (disable_mclk_switching) {
@@ -6253,9 +6273,6 @@ int si_dpm_init(struct radeon_device *rdev)
        struct evergreen_power_info *eg_pi;
        struct ni_power_info *ni_pi;
        struct si_power_info *si_pi;
-       int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
-       u16 data_offset, size;
-       u8 frev, crev;
        struct atom_clock_dividers dividers;
        int ret;
        u32 mask;
@@ -6346,16 +6363,7 @@ int si_dpm_init(struct radeon_device *rdev)
        si_pi->vddc_phase_shed_control =
                radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT);
 
-       if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
-                                   &frev, &crev, &data_offset)) {
-               pi->sclk_ss = true;
-               pi->mclk_ss = true;
-               pi->dynamic_ss = true;
-       } else {
-               pi->sclk_ss = false;
-               pi->mclk_ss = false;
-               pi->dynamic_ss = true;
-       }
+       rv770_get_engine_memory_ss(rdev);
 
        pi->asi = RV770_ASI_DFLT;
        pi->pasi = CYPRESS_HASI_DFLT;
@@ -6366,8 +6374,7 @@ int si_dpm_init(struct radeon_device *rdev)
        eg_pi->sclk_deep_sleep = true;
        si_pi->sclk_deep_sleep_above_low = false;
 
-       if (pi->gfx_clock_gating &&
-           (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
+       if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
                pi->thermal_protection = true;
        else
                pi->thermal_protection = false;
index 7a57648..cd33084 100644 (file)
@@ -488,8 +488,6 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
        if (djrcv_dev->querying_devices)
                return 0;
 
-       djrcv_dev->querying_devices = true;
-
        dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
        if (!dj_report)
                return -ENOMEM;
index 0f34bca..6099f50 100644 (file)
@@ -215,7 +215,7 @@ static inline int adt7470_write_word_data(struct i2c_client *client, u8 reg,
                                          u16 value)
 {
        return i2c_smbus_write_byte_data(client, reg, value & 0xFF)
-              && i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
+              || i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
 }
 
 static void adt7470_init_client(struct i2c_client *client)
index efdc873..a985702 100644 (file)
@@ -117,7 +117,7 @@ static int ml86v7667_s_ctrl(struct v4l2_ctrl *ctrl)
 {
        struct v4l2_subdev *sd = to_sd(ctrl);
        struct i2c_client *client = v4l2_get_subdevdata(sd);
-       int ret;
+       int ret = -EINVAL;
 
        switch (ctrl->id) {
        case V4L2_CID_BRIGHTNESS:
@@ -157,7 +157,7 @@ static int ml86v7667_s_ctrl(struct v4l2_ctrl *ctrl)
                break;
        }
 
-       return 0;
+       return ret;
 }
 
 static int ml86v7667_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
index df4ada8..bd9405d 100644 (file)
@@ -1987,7 +1987,7 @@ MODULE_DEVICE_TABLE(platform, coda_platform_ids);
 
 #ifdef CONFIG_OF
 static const struct of_device_id coda_dt_ids[] = {
-       { .compatible = "fsl,imx27-vpu", .data = &coda_platform_ids[CODA_IMX27] },
+       { .compatible = "fsl,imx27-vpu", .data = &coda_devdata[CODA_IMX27] },
        { .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] },
        { /* sentinel */ }
 };
index 553d87e..fd6289d 100644 (file)
@@ -784,6 +784,7 @@ static int g2d_probe(struct platform_device *pdev)
        }
        *vfd = g2d_videodev;
        vfd->lock = &dev->mutex;
+       vfd->v4l2_dev = &dev->v4l2_dev;
        ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
        if (ret) {
                v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
index 5296385..4f6dd42 100644 (file)
@@ -344,7 +344,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
                pix_mp->num_planes = 2;
                /* Set pixelformat to the format in which MFC
                   outputs the decoded frame */
-               pix_mp->pixelformat = V4L2_PIX_FMT_NV12MT;
+               pix_mp->pixelformat = ctx->dst_fmt->fourcc;
                pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
                pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
                pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
@@ -382,10 +382,16 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
                        mfc_err("Unsupported format for source.\n");
                        return -EINVAL;
                }
-               if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
-                       mfc_err("Not supported format.\n");
+               if (fmt->codec_mode == S5P_FIMV_CODEC_NONE) {
+                       mfc_err("Unknown codec\n");
                        return -EINVAL;
                }
+               if (!IS_MFCV6(dev)) {
+                       if (fmt->fourcc == V4L2_PIX_FMT_VP8) {
+                               mfc_err("Not supported format.\n");
+                               return -EINVAL;
+                       }
+               }
        } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
                fmt = find_format(f, MFC_FMT_RAW);
                if (!fmt) {
@@ -411,7 +417,6 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
        struct s5p_mfc_dev *dev = video_drvdata(file);
        struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
        int ret = 0;
-       struct s5p_mfc_fmt *fmt;
        struct v4l2_pix_format_mplane *pix_mp;
 
        mfc_debug_enter();
@@ -425,54 +430,32 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
                goto out;
        }
        if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               fmt = find_format(f, MFC_FMT_RAW);
-               if (!fmt) {
-                       mfc_err("Unsupported format for source.\n");
-                       return -EINVAL;
-               }
-               if (!IS_MFCV6(dev) && (fmt->fourcc != V4L2_PIX_FMT_NV12MT)) {
-                       mfc_err("Not supported format.\n");
-                       return -EINVAL;
-               } else if (IS_MFCV6(dev) &&
-                               (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
-                       mfc_err("Not supported format.\n");
-                       return -EINVAL;
-               }
-               ctx->dst_fmt = fmt;
-               mfc_debug_leave();
-               return ret;
-       } else if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               mfc_err("Wrong type error for S_FMT : %d", f->type);
-               return -EINVAL;
-       }
-       fmt = find_format(f, MFC_FMT_DEC);
-       if (!fmt || fmt->codec_mode == S5P_MFC_CODEC_NONE) {
-               mfc_err("Unknown codec\n");
-               ret = -EINVAL;
+               /* dst_fmt is validated by call to vidioc_try_fmt */
+               ctx->dst_fmt = find_format(f, MFC_FMT_RAW);
+               ret = 0;
                goto out;
-       }
-       if (fmt->type != MFC_FMT_DEC) {
-               mfc_err("Wrong format selected, you should choose "
-                                       "format for decoding\n");
+       } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               /* src_fmt is validated by call to vidioc_try_fmt */
+               ctx->src_fmt = find_format(f, MFC_FMT_DEC);
+               ctx->codec_mode = ctx->src_fmt->codec_mode;
+               mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
+               pix_mp->height = 0;
+               pix_mp->width = 0;
+               if (pix_mp->plane_fmt[0].sizeimage)
+                       ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage;
+               else
+                       pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size =
+                                                               DEF_CPB_SIZE;
+               pix_mp->plane_fmt[0].bytesperline = 0;
+               ctx->state = MFCINST_INIT;
+               ret = 0;
+               goto out;
+       } else {
+               mfc_err("Wrong type error for S_FMT : %d", f->type);
                ret = -EINVAL;
                goto out;
        }
-       if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
-               mfc_err("Not supported format.\n");
-               return -EINVAL;
-       }
-       ctx->src_fmt = fmt;
-       ctx->codec_mode = fmt->codec_mode;
-       mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
-       pix_mp->height = 0;
-       pix_mp->width = 0;
-       if (pix_mp->plane_fmt[0].sizeimage)
-               ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage;
-       else
-               pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size =
-                                                               DEF_CPB_SIZE;
-       pix_mp->plane_fmt[0].bytesperline = 0;
-       ctx->state = MFCINST_INIT;
+
 out:
        mfc_debug_leave();
        return ret;
index 2549967..59e56f4 100644 (file)
@@ -906,6 +906,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
 
 static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
 {
+       struct s5p_mfc_dev *dev = video_drvdata(file);
        struct s5p_mfc_fmt *fmt;
        struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
 
@@ -930,6 +931,18 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
                        return -EINVAL;
                }
 
+               if (!IS_MFCV6(dev)) {
+                       if (fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) {
+                               mfc_err("Not supported format.\n");
+                               return -EINVAL;
+                       }
+               } else if (IS_MFCV6(dev)) {
+                       if (fmt->fourcc == V4L2_PIX_FMT_NV12MT) {
+                               mfc_err("Not supported format.\n");
+                               return -EINVAL;
+                       }
+               }
+
                if (fmt->num_planes != pix_fmt_mp->num_planes) {
                        mfc_err("failed to try output format\n");
                        return -EINVAL;
@@ -947,7 +960,6 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
 {
        struct s5p_mfc_dev *dev = video_drvdata(file);
        struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
-       struct s5p_mfc_fmt *fmt;
        struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
        int ret = 0;
 
@@ -960,13 +972,9 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
                goto out;
        }
        if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               fmt = find_format(f, MFC_FMT_ENC);
-               if (!fmt) {
-                       mfc_err("failed to set capture format\n");
-                       return -EINVAL;
-               }
+               /* dst_fmt is validated by call to vidioc_try_fmt */
+               ctx->dst_fmt = find_format(f, MFC_FMT_ENC);
                ctx->state = MFCINST_INIT;
-               ctx->dst_fmt = fmt;
                ctx->codec_mode = ctx->dst_fmt->codec_mode;
                ctx->enc_dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage;
                pix_fmt_mp->plane_fmt[0].bytesperline = 0;
@@ -987,28 +995,8 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
                }
                mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
        } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               fmt = find_format(f, MFC_FMT_RAW);
-               if (!fmt) {
-                       mfc_err("failed to set output format\n");
-                       return -EINVAL;
-               }
-
-               if (!IS_MFCV6(dev) &&
-                               (fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16)) {
-                       mfc_err("Not supported format.\n");
-                       return -EINVAL;
-               } else if (IS_MFCV6(dev) &&
-                               (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
-                       mfc_err("Not supported format.\n");
-                       return -EINVAL;
-               }
-
-               if (fmt->num_planes != pix_fmt_mp->num_planes) {
-                       mfc_err("failed to set output format\n");
-                       ret = -EINVAL;
-                       goto out;
-               }
-               ctx->src_fmt = fmt;
+               /* src_fmt is validated by call to vidioc_try_fmt */
+               ctx->src_fmt = find_format(f, MFC_FMT_RAW);
                ctx->img_width = pix_fmt_mp->width;
                ctx->img_height = pix_fmt_mp->height;
                mfc_debug(2, "codec number: %d\n", ctx->src_fmt->codec_mode);
index 4851cc2..c4ff973 100644 (file)
@@ -726,7 +726,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus,
 
        *eedata = data;
        *eedata_len = len;
-       dev_config = (void *)eedata;
+       dev_config = (void *)*eedata;
 
        switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) {
        case 0:
index cb69405..6e50707 100644 (file)
@@ -303,6 +303,11 @@ static int hdpvr_probe(struct usb_interface *interface,
 
        dev->workqueue = 0;
 
+       /* init video transfer queues first of all */
+       /* to prevent oops in hdpvr_delete() on error paths */
+       INIT_LIST_HEAD(&dev->free_buff_list);
+       INIT_LIST_HEAD(&dev->rec_buff_list);
+
        /* register v4l2_device early so it can be used for printks */
        if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
                dev_err(&interface->dev, "v4l2_device_register failed\n");
@@ -325,10 +330,6 @@ static int hdpvr_probe(struct usb_interface *interface,
        if (!dev->workqueue)
                goto error;
 
-       /* init video transfer queues */
-       INIT_LIST_HEAD(&dev->free_buff_list);
-       INIT_LIST_HEAD(&dev->rec_buff_list);
-
        dev->options = hdpvr_default_options;
 
        if (default_video_input < HDPVR_VIDEO_INPUTS)
@@ -405,7 +406,7 @@ static int hdpvr_probe(struct usb_interface *interface,
                                    video_nr[atomic_inc_return(&dev_nr)]);
        if (retval < 0) {
                v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
-               goto error;
+               goto reg_fail;
        }
 
        /* let the user know what node this device is now attached to */
index 8864436..7c5b860 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_USBTV
         tristate "USBTV007 video capture support"
-        depends on VIDEO_DEV
+        depends on VIDEO_V4L2
         select VIDEOBUF2_VMALLOC
 
         ---help---
index bf43f87..9165017 100644 (file)
@@ -57,7 +57,7 @@
 #define USBTV_CHUNK_SIZE       256
 #define USBTV_CHUNK            240
 #define USBTV_CHUNKS           (USBTV_WIDTH * USBTV_HEIGHT \
-                                       / 2 / USBTV_CHUNK)
+                                       / 4 / USBTV_CHUNK)
 
 /* Chunk header. */
 #define USBTV_MAGIC_OK(chunk)  ((be32_to_cpu(chunk[0]) & 0xff000000) \
@@ -89,6 +89,7 @@ struct usbtv {
        /* Number of currently processed frame, useful find
         * out when a new one begins. */
        u32 frame_id;
+       int chunks_done;
 
        int iso_size;
        unsigned int sequence;
@@ -202,6 +203,26 @@ static int usbtv_setup_capture(struct usbtv *usbtv)
        return 0;
 }
 
+/* Copy data from chunk into a frame buffer, deinterlacing the data
+ * into every second line. Unfortunately, they don't align nicely into
+ * 720 pixel lines, as the chunk is 240 words long, which is 480 pixels.
+ * Therefore, we break down the chunk into two halves before copyting,
+ * so that we can interleave a line if needed. */
+static void usbtv_chunk_to_vbuf(u32 *frame, u32 *src, int chunk_no, int odd)
+{
+       int half;
+
+       for (half = 0; half < 2; half++) {
+               int part_no = chunk_no * 2 + half;
+               int line = part_no / 3;
+               int part_index = (line * 2 + !odd) * 3 + (part_no % 3);
+
+               u32 *dst = &frame[part_index * USBTV_CHUNK/2];
+               memcpy(dst, src, USBTV_CHUNK/2 * sizeof(*src));
+               src += USBTV_CHUNK/2;
+       }
+}
+
 /* Called for each 256-byte image chunk.
  * First word identifies the chunk, followed by 240 words of image
  * data and padding. */
@@ -218,17 +239,17 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
        frame_id = USBTV_FRAME_ID(chunk);
        odd = USBTV_ODD(chunk);
        chunk_no = USBTV_CHUNK_NO(chunk);
-
-       /* Deinterlace. TODO: Use interlaced frame format. */
-       chunk_no = (chunk_no - chunk_no % 3) * 2 + chunk_no % 3;
-       chunk_no += !odd * 3;
-
        if (chunk_no >= USBTV_CHUNKS)
                return;
 
        /* Beginning of a frame. */
-       if (chunk_no == 0)
+       if (chunk_no == 0) {
                usbtv->frame_id = frame_id;
+               usbtv->chunks_done = 0;
+       }
+
+       if (usbtv->frame_id != frame_id)
+               return;
 
        spin_lock_irqsave(&usbtv->buflock, flags);
        if (list_empty(&usbtv->bufs)) {
@@ -241,19 +262,23 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
        buf = list_first_entry(&usbtv->bufs, struct usbtv_buf, list);
        frame = vb2_plane_vaddr(&buf->vb, 0);
 
-       /* Copy the chunk. */
-       memcpy(&frame[chunk_no * USBTV_CHUNK], &chunk[1],
-                       USBTV_CHUNK * sizeof(chunk[1]));
+       /* Copy the chunk data. */
+       usbtv_chunk_to_vbuf(frame, &chunk[1], chunk_no, odd);
+       usbtv->chunks_done++;
 
        /* Last chunk in a frame, signalling an end */
-       if (usbtv->frame_id && chunk_no == USBTV_CHUNKS-1) {
+       if (odd && chunk_no == USBTV_CHUNKS-1) {
                int size = vb2_plane_size(&buf->vb, 0);
+               enum vb2_buffer_state state = usbtv->chunks_done ==
+                                               USBTV_CHUNKS ?
+                                               VB2_BUF_STATE_DONE :
+                                               VB2_BUF_STATE_ERROR;
 
                buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
                buf->vb.v4l2_buf.sequence = usbtv->sequence++;
                v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
                vb2_set_plane_payload(&buf->vb, 0, size);
-               vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+               vb2_buffer_done(&buf->vb, state);
                list_del(&buf->list);
        }
 
@@ -518,7 +543,7 @@ static int usbtv_queue_setup(struct vb2_queue *vq,
        if (*nbuffers < 2)
                *nbuffers = 2;
        *nplanes = 1;
-       sizes[0] = USBTV_CHUNK * USBTV_CHUNKS * sizeof(u32);
+       sizes[0] = USBTV_WIDTH * USBTV_HEIGHT / 2 * sizeof(u32);
 
        return 0;
 }
index dbdc5f7..01e264f 100644 (file)
@@ -317,13 +317,20 @@ void acpi_pci_remove_bus(struct pci_bus *bus)
 /* ACPI bus type */
 static int acpi_pci_find_device(struct device *dev, acpi_handle *handle)
 {
-       struct pci_dev * pci_dev;
-       u64     addr;
+       struct pci_dev *pci_dev = to_pci_dev(dev);
+       bool is_bridge;
+       u64 addr;
 
-       pci_dev = to_pci_dev(dev);
+       /*
+        * pci_is_bridge() is not suitable here, because pci_dev->subordinate
+        * is set only after acpi_pci_find_device() has been called for the
+        * given device.
+        */
+       is_bridge = pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE
+                       || pci_dev->hdr_type == PCI_HEADER_TYPE_CARDBUS;
        /* Please ref to ACPI spec for the syntax of _ADR */
        addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
-       *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
+       *handle = acpi_find_child(ACPI_HANDLE(dev->parent), addr, is_bridge);
        if (!*handle)
                return -ENODEV;
        return 0;
index 17150a7..451bf99 100644 (file)
@@ -2392,6 +2392,12 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
                rc = cqr->intrc;
        else
                rc = -EIO;
+
+       /* kick tasklets */
+       dasd_schedule_device_bh(device);
+       if (device->block)
+               dasd_schedule_block_bh(device->block);
+
        return rc;
 }
 
index 2168258..74b88ef 100644 (file)
@@ -751,7 +751,7 @@ static void __virtscsi_set_affinity(struct virtio_scsi *vscsi, bool affinity)
 
                vscsi->affinity_hint_set = true;
        } else {
-               for (i = 0; i < vscsi->num_queues - VIRTIO_SCSI_VQ_BASE; i++)
+               for (i = 0; i < vscsi->num_queues; i++)
                        virtqueue_set_affinity(vscsi->req_vqs[i].vq, -1);
 
                vscsi->affinity_hint_set = false;
index 222d3e3..707966b 100644 (file)
@@ -609,7 +609,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
                else
                        buf = (void *)t->tx_buf;
                t->tx_dma = dma_map_single(&spi->dev, buf,
-                               t->len, DMA_FROM_DEVICE);
+                               t->len, DMA_TO_DEVICE);
                if (!t->tx_dma) {
                        ret = -EFAULT;
                        goto err_tx_map;
index 3ba3771..dc09ebe 100644 (file)
@@ -239,24 +239,6 @@ static const struct fb_bitfield def_rgb565[] = {
        }
 };
 
-static const struct fb_bitfield def_rgb666[] = {
-       [RED] = {
-               .offset = 16,
-               .length = 6,
-       },
-       [GREEN] = {
-               .offset = 8,
-               .length = 6,
-       },
-       [BLUE] = {
-               .offset = 0,
-               .length = 6,
-       },
-       [TRANSP] = {    /* no support for transparency */
-               .length = 0,
-       }
-};
-
 static const struct fb_bitfield def_rgb888[] = {
        [RED] = {
                .offset = 16,
@@ -309,9 +291,6 @@ static int mxsfb_check_var(struct fb_var_screeninfo *var,
                        break;
                case STMLCDIF_16BIT:
                case STMLCDIF_18BIT:
-                       /* 24 bit to 18 bit mapping */
-                       rgb = def_rgb666;
-                       break;
                case STMLCDIF_24BIT:
                        /* real 24 bit */
                        rgb = def_rgb888;
@@ -453,11 +432,6 @@ static int mxsfb_set_par(struct fb_info *fb_info)
                        return -EINVAL;
                case STMLCDIF_16BIT:
                case STMLCDIF_18BIT:
-                       /* 24 bit to 18 bit mapping */
-                       ctrl |= CTRL_DF24; /* ignore the upper 2 bits in
-                                           *  each colour component
-                                           */
-                       break;
                case STMLCDIF_24BIT:
                        /* real 24 bit */
                        break;
index 5338f36..1b60698 100644 (file)
@@ -28,6 +28,20 @@ struct panel_drv_data {
        bool invert_polarity;
 };
 
+static const struct omap_video_timings tvc_pal_timings = {
+       .x_res          = 720,
+       .y_res          = 574,
+       .pixel_clock    = 13500,
+       .hsw            = 64,
+       .hfp            = 12,
+       .hbp            = 68,
+       .vsw            = 5,
+       .vfp            = 5,
+       .vbp            = 41,
+
+       .interlace      = true,
+};
+
 #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
 
 static int tvc_connect(struct omap_dss_device *dssdev)
@@ -212,14 +226,14 @@ static int tvc_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       ddata->timings = omap_dss_pal_timings;
+       ddata->timings = tvc_pal_timings;
 
        dssdev = &ddata->dssdev;
        dssdev->driver = &tvc_driver;
        dssdev->dev = &pdev->dev;
        dssdev->type = OMAP_DISPLAY_TYPE_VENC;
        dssdev->owner = THIS_MODULE;
-       dssdev->panel.timings = omap_dss_pal_timings;
+       dssdev->panel.timings = tvc_pal_timings;
 
        r = omapdss_register_display(dssdev);
        if (r) {
index 4888cb3..c7c83ff 100644 (file)
@@ -533,8 +533,7 @@ EXPORT_SYMBOL_GPL(debugfs_remove);
  */
 void debugfs_remove_recursive(struct dentry *dentry)
 {
-       struct dentry *child;
-       struct dentry *parent;
+       struct dentry *child, *next, *parent;
 
        if (IS_ERR_OR_NULL(dentry))
                return;
@@ -544,61 +543,37 @@ void debugfs_remove_recursive(struct dentry *dentry)
                return;
 
        parent = dentry;
+ down:
        mutex_lock(&parent->d_inode->i_mutex);
+       list_for_each_entry_safe(child, next, &parent->d_subdirs, d_u.d_child) {
+               if (!debugfs_positive(child))
+                       continue;
 
-       while (1) {
-               /*
-                * When all dentries under "parent" has been removed,
-                * walk up the tree until we reach our starting point.
-                */
-               if (list_empty(&parent->d_subdirs)) {
-                       mutex_unlock(&parent->d_inode->i_mutex);
-                       if (parent == dentry)
-                               break;
-                       parent = parent->d_parent;
-                       mutex_lock(&parent->d_inode->i_mutex);
-               }
-               child = list_entry(parent->d_subdirs.next, struct dentry,
-                               d_u.d_child);
- next_sibling:
-
-               /*
-                * If "child" isn't empty, walk down the tree and
-                * remove all its descendants first.
-                */
+               /* perhaps simple_empty(child) makes more sense */
                if (!list_empty(&child->d_subdirs)) {
                        mutex_unlock(&parent->d_inode->i_mutex);
                        parent = child;
-                       mutex_lock(&parent->d_inode->i_mutex);
-                       continue;
+                       goto down;
                }
-               __debugfs_remove(child, parent);
-               if (parent->d_subdirs.next == &child->d_u.d_child) {
-                       /*
-                        * Try the next sibling.
-                        */
-                       if (child->d_u.d_child.next != &parent->d_subdirs) {
-                               child = list_entry(child->d_u.d_child.next,
-                                                  struct dentry,
-                                                  d_u.d_child);
-                               goto next_sibling;
-                       }
-
-                       /*
-                        * Avoid infinite loop if we fail to remove
-                        * one dentry.
-                        */
-                       mutex_unlock(&parent->d_inode->i_mutex);
-                       break;
-               }
-               simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+ up:
+               if (!__debugfs_remove(child, parent))
+                       simple_release_fs(&debugfs_mount, &debugfs_mount_count);
        }
 
-       parent = dentry->d_parent;
+       mutex_unlock(&parent->d_inode->i_mutex);
+       child = parent;
+       parent = parent->d_parent;
        mutex_lock(&parent->d_inode->i_mutex);
-       __debugfs_remove(dentry, parent);
+
+       if (child != dentry) {
+               next = list_entry(child->d_u.d_child.next, struct dentry,
+                                       d_u.d_child);
+               goto up;
+       }
+
+       if (!__debugfs_remove(child, parent))
+               simple_release_fs(&debugfs_mount, &debugfs_mount_count);
        mutex_unlock(&parent->d_inode->i_mutex);
-       simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 }
 EXPORT_SYMBOL_GPL(debugfs_remove_recursive);
 
index 911649a..8121491 100644 (file)
@@ -686,7 +686,6 @@ static int device_close(struct inode *inode, struct file *file)
           device_remove_lockspace() */
 
        sigprocmask(SIG_SETMASK, &tmpsig, NULL);
-       recalc_sigpending();
 
        return 0;
 }
index a618738..72ba470 100644 (file)
@@ -4412,7 +4412,7 @@ void ext4_ext_truncate(handle_t *handle, struct inode *inode)
 retry:
        err = ext4_es_remove_extent(inode, last_block,
                                    EXT_MAX_BLOCKS - last_block);
-       if (err == ENOMEM) {
+       if (err == -ENOMEM) {
                cond_resched();
                congestion_wait(BLK_RW_ASYNC, HZ/50);
                goto retry;
index f03598c..8bf5999 100644 (file)
@@ -734,11 +734,8 @@ repeat_in_this_group:
                ino = ext4_find_next_zero_bit((unsigned long *)
                                              inode_bitmap_bh->b_data,
                                              EXT4_INODES_PER_GROUP(sb), ino);
-               if (ino >= EXT4_INODES_PER_GROUP(sb)) {
-                       if (++group == ngroups)
-                               group = 0;
-                       continue;
-               }
+               if (ino >= EXT4_INODES_PER_GROUP(sb))
+                       goto next_group;
                if (group == 0 && (ino+1) < EXT4_FIRST_INO(sb)) {
                        ext4_error(sb, "reserved inode found cleared - "
                                   "inode=%lu", ino + 1);
@@ -769,6 +766,9 @@ repeat_in_this_group:
                        goto got; /* we grabbed the inode! */
                if (ino < EXT4_INODES_PER_GROUP(sb))
                        goto repeat_in_this_group;
+next_group:
+               if (++group == ngroups)
+                       group = 0;
        }
        err = -ENOSPC;
        goto out;
index ba33c67..dd32a2e 100644 (file)
@@ -555,14 +555,13 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
                int ret;
                unsigned long long status;
 
-#ifdef ES_AGGRESSIVE_TEST
-               if (retval != map->m_len) {
-                       printk("ES len assertion failed for inode: %lu "
-                              "retval %d != map->m_len %d "
-                              "in %s (lookup)\n", inode->i_ino, retval,
-                              map->m_len, __func__);
+               if (unlikely(retval != map->m_len)) {
+                       ext4_warning(inode->i_sb,
+                                    "ES len assertion failed for inode "
+                                    "%lu: retval %d != map->m_len %d",
+                                    inode->i_ino, retval, map->m_len);
+                       WARN_ON(1);
                }
-#endif
 
                status = map->m_flags & EXT4_MAP_UNWRITTEN ?
                                EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
@@ -656,14 +655,13 @@ found:
                int ret;
                unsigned long long status;
 
-#ifdef ES_AGGRESSIVE_TEST
-               if (retval != map->m_len) {
-                       printk("ES len assertion failed for inode: %lu "
-                              "retval %d != map->m_len %d "
-                              "in %s (allocation)\n", inode->i_ino, retval,
-                              map->m_len, __func__);
+               if (unlikely(retval != map->m_len)) {
+                       ext4_warning(inode->i_sb,
+                                    "ES len assertion failed for inode "
+                                    "%lu: retval %d != map->m_len %d",
+                                    inode->i_ino, retval, map->m_len);
+                       WARN_ON(1);
                }
-#endif
 
                /*
                 * If the extent has been zeroed out, we don't need to update
@@ -1637,14 +1635,13 @@ add_delayed:
                int ret;
                unsigned long long status;
 
-#ifdef ES_AGGRESSIVE_TEST
-               if (retval != map->m_len) {
-                       printk("ES len assertion failed for inode: %lu "
-                              "retval %d != map->m_len %d "
-                              "in %s (lookup)\n", inode->i_ino, retval,
-                              map->m_len, __func__);
+               if (unlikely(retval != map->m_len)) {
+                       ext4_warning(inode->i_sb,
+                                    "ES len assertion failed for inode "
+                                    "%lu: retval %d != map->m_len %d",
+                                    inode->i_ino, retval, map->m_len);
+                       WARN_ON(1);
                }
-#endif
 
                status = map->m_flags & EXT4_MAP_UNWRITTEN ?
                                EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
index bca26f3..36b141e 100644 (file)
@@ -5481,6 +5481,7 @@ static void __exit ext4_exit_fs(void)
        kset_unregister(ext4_kset);
        ext4_exit_system_zone();
        ext4_exit_pageio();
+       ext4_exit_es();
 }
 
 MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
index 6599222..65343c3 100644 (file)
@@ -730,14 +730,14 @@ static int __init fcntl_init(void)
         * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
         * is defined as O_NONBLOCK on some platforms and not on others.
         */
-       BUILD_BUG_ON(19 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32(
+       BUILD_BUG_ON(20 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32(
                O_RDONLY        | O_WRONLY      | O_RDWR        |
                O_CREAT         | O_EXCL        | O_NOCTTY      |
                O_TRUNC         | O_APPEND      | /* O_NONBLOCK | */
                __O_SYNC        | O_DSYNC       | FASYNC        |
                O_DIRECT        | O_LARGEFILE   | O_DIRECTORY   |
                O_NOFOLLOW      | O_NOATIME     | O_CLOEXEC     |
-               __FMODE_EXEC    | O_PATH
+               __FMODE_EXEC    | O_PATH        | __O_TMPFILE
                ));
 
        fasync_cache = kmem_cache_create("fasync_cache",
index 8b61d10..89a612e 100644 (file)
@@ -3671,15 +3671,11 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
        if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
                return -EINVAL;
        /*
-        * To use null names we require CAP_DAC_READ_SEARCH
-        * This ensures that not everyone will be able to create
-        * handlink using the passed filedescriptor.
+        * Using empty names is equivalent to using AT_SYMLINK_FOLLOW
+        * on /proc/self/fd/<fd>.
         */
-       if (flags & AT_EMPTY_PATH) {
-               if (!capable(CAP_DAC_READ_SEARCH))
-                       return -ENOENT;
+       if (flags & AT_EMPTY_PATH)
                how = LOOKUP_EMPTY;
-       }
 
        if (flags & AT_SYMLINK_FOLLOW)
                how |= LOOKUP_FOLLOW;
index d53e298..7931f76 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -823,7 +823,7 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
        int lookup_flags = 0;
        int acc_mode;
 
-       if (flags & O_CREAT)
+       if (flags & (O_CREAT | __O_TMPFILE))
                op->mode = (mode & S_IALLUGO) | S_IFREG;
        else
                op->mode = 0;
index 33532f7..a958444 100644 (file)
 /*
  * LOCKING:
  *
- * We rely on new Alexander Viro's super-block locking.
+ * These guys are evicted from procfs as the very first step in ->kill_sb().
  *
  */
 
-static int show_version(struct seq_file *m, struct super_block *sb)
+static int show_version(struct seq_file *m, void *unused)
 {
+       struct super_block *sb = m->private;
        char *format;
 
        if (REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6)) {
@@ -66,8 +67,9 @@ static int show_version(struct seq_file *m, struct super_block *sb)
 #define DJP( x ) le32_to_cpu( jp -> x )
 #define JF( x ) ( r -> s_journal -> x )
 
-static int show_super(struct seq_file *m, struct super_block *sb)
+static int show_super(struct seq_file *m, void *unused)
 {
+       struct super_block *sb = m->private;
        struct reiserfs_sb_info *r = REISERFS_SB(sb);
 
        seq_printf(m, "state: \t%s\n"
@@ -128,8 +130,9 @@ static int show_super(struct seq_file *m, struct super_block *sb)
        return 0;
 }
 
-static int show_per_level(struct seq_file *m, struct super_block *sb)
+static int show_per_level(struct seq_file *m, void *unused)
 {
+       struct super_block *sb = m->private;
        struct reiserfs_sb_info *r = REISERFS_SB(sb);
        int level;
 
@@ -186,8 +189,9 @@ static int show_per_level(struct seq_file *m, struct super_block *sb)
        return 0;
 }
 
-static int show_bitmap(struct seq_file *m, struct super_block *sb)
+static int show_bitmap(struct seq_file *m, void *unused)
 {
+       struct super_block *sb = m->private;
        struct reiserfs_sb_info *r = REISERFS_SB(sb);
 
        seq_printf(m, "free_block: %lu\n"
@@ -218,8 +222,9 @@ static int show_bitmap(struct seq_file *m, struct super_block *sb)
        return 0;
 }
 
-static int show_on_disk_super(struct seq_file *m, struct super_block *sb)
+static int show_on_disk_super(struct seq_file *m, void *unused)
 {
+       struct super_block *sb = m->private;
        struct reiserfs_sb_info *sb_info = REISERFS_SB(sb);
        struct reiserfs_super_block *rs = sb_info->s_rs;
        int hash_code = DFL(s_hash_function_code);
@@ -261,8 +266,9 @@ static int show_on_disk_super(struct seq_file *m, struct super_block *sb)
        return 0;
 }
 
-static int show_oidmap(struct seq_file *m, struct super_block *sb)
+static int show_oidmap(struct seq_file *m, void *unused)
 {
+       struct super_block *sb = m->private;
        struct reiserfs_sb_info *sb_info = REISERFS_SB(sb);
        struct reiserfs_super_block *rs = sb_info->s_rs;
        unsigned int mapsize = le16_to_cpu(rs->s_v1.s_oid_cursize);
@@ -291,8 +297,9 @@ static int show_oidmap(struct seq_file *m, struct super_block *sb)
        return 0;
 }
 
-static int show_journal(struct seq_file *m, struct super_block *sb)
+static int show_journal(struct seq_file *m, void *unused)
 {
+       struct super_block *sb = m->private;
        struct reiserfs_sb_info *r = REISERFS_SB(sb);
        struct reiserfs_super_block *rs = r->s_rs;
        struct journal_params *jp = &rs->s_v1.s_journal;
@@ -383,92 +390,24 @@ static int show_journal(struct seq_file *m, struct super_block *sb)
        return 0;
 }
 
-/* iterator */
-static int test_sb(struct super_block *sb, void *data)
-{
-       return data == sb;
-}
-
-static int set_sb(struct super_block *sb, void *data)
-{
-       return -ENOENT;
-}
-
-struct reiserfs_seq_private {
-       struct super_block *sb;
-       int (*show) (struct seq_file *, struct super_block *);
-};
-
-static void *r_start(struct seq_file *m, loff_t * pos)
-{
-       struct reiserfs_seq_private *priv = m->private;
-       loff_t l = *pos;
-
-       if (l)
-               return NULL;
-
-       if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, 0, priv->sb)))
-               return NULL;
-
-       up_write(&priv->sb->s_umount);
-       return priv->sb;
-}
-
-static void *r_next(struct seq_file *m, void *v, loff_t * pos)
-{
-       ++*pos;
-       if (v)
-               deactivate_super(v);
-       return NULL;
-}
-
-static void r_stop(struct seq_file *m, void *v)
-{
-       if (v)
-               deactivate_super(v);
-}
-
-static int r_show(struct seq_file *m, void *v)
-{
-       struct reiserfs_seq_private *priv = m->private;
-       return priv->show(m, v);
-}
-
-static const struct seq_operations r_ops = {
-       .start = r_start,
-       .next = r_next,
-       .stop = r_stop,
-       .show = r_show,
-};
-
 static int r_open(struct inode *inode, struct file *file)
 {
-       struct reiserfs_seq_private *priv;
-       int ret = seq_open_private(file, &r_ops,
-                                  sizeof(struct reiserfs_seq_private));
-
-       if (!ret) {
-               struct seq_file *m = file->private_data;
-               priv = m->private;
-               priv->sb = proc_get_parent_data(inode);
-               priv->show = PDE_DATA(inode);
-       }
-       return ret;
+       return single_open(file, PDE_DATA(inode), 
+                               proc_get_parent_data(inode));
 }
 
 static const struct file_operations r_file_operations = {
        .open = r_open,
        .read = seq_read,
        .llseek = seq_lseek,
-       .release = seq_release_private,
-       .owner = THIS_MODULE,
+       .release = single_release,
 };
 
 static struct proc_dir_entry *proc_info_root = NULL;
 static const char proc_info_root_name[] = "fs/reiserfs";
 
 static void add_file(struct super_block *sb, char *name,
-                    int (*func) (struct seq_file *, struct super_block *))
+                    int (*func) (struct seq_file *, void *))
 {
        proc_create_data(name, 0, REISERFS_SB(sb)->procdir,
                         &r_file_operations, func);
index f8a23c3..e2e202a 100644 (file)
@@ -499,6 +499,7 @@ int remove_save_link(struct inode *inode, int truncate)
 static void reiserfs_kill_sb(struct super_block *s)
 {
        if (REISERFS_SB(s)) {
+               reiserfs_proc_info_done(s);
                /*
                 * Force any pending inode evictions to occur now. Any
                 * inodes to be removed that have extended attributes
@@ -554,8 +555,6 @@ static void reiserfs_put_super(struct super_block *s)
                                 REISERFS_SB(s)->reserved_blocks);
        }
 
-       reiserfs_proc_info_done(s);
-
        reiserfs_write_unlock(s);
        mutex_destroy(&REISERFS_SB(s)->lock);
        kfree(s->s_fs_info);
index 56e6b68..94383a7 100644 (file)
@@ -274,15 +274,12 @@ struct acpi_device_wakeup {
 };
 
 struct acpi_device_physical_node {
-       u8 node_id;
+       unsigned int node_id;
        struct list_head node;
        struct device *dev;
        bool put_online:1;
 };
 
-/* set maximum of physical nodes to 32 for expansibility */
-#define ACPI_MAX_PHYSICAL_NODE 32
-
 /* Device */
 struct acpi_device {
        int device_type;
@@ -302,10 +299,9 @@ struct acpi_device {
        struct acpi_driver *driver;
        void *driver_data;
        struct device dev;
-       u8 physical_node_count;
+       unsigned int physical_node_count;
        struct list_head physical_node_list;
        struct mutex physical_node_lock;
-       DECLARE_BITMAP(physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE);
        struct list_head power_dependent;
        void (*remove)(struct acpi_device *);
 };
@@ -445,7 +441,11 @@ struct acpi_pci_root {
 };
 
 /* helper */
-acpi_handle acpi_get_child(acpi_handle, u64);
+acpi_handle acpi_find_child(acpi_handle, u64, bool);
+static inline acpi_handle acpi_get_child(acpi_handle handle, u64 addr)
+{
+       return acpi_find_child(handle, addr, false);
+}
 int acpi_is_root_bridge(acpi_handle);
 struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
 #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev))
index 4372658..120d57a 100644 (file)
@@ -78,6 +78,11 @@ struct trace_iterator {
        /* trace_seq for __print_flags() and __print_symbolic() etc. */
        struct trace_seq        tmp_seq;
 
+       cpumask_var_t           started;
+
+       /* it's true when current open file is snapshot */
+       bool                    snapshot;
+
        /* The below is zeroed out in pipe_read */
        struct trace_seq        seq;
        struct trace_entry      *ent;
@@ -90,10 +95,7 @@ struct trace_iterator {
        loff_t                  pos;
        long                    idx;
 
-       cpumask_var_t           started;
-
-       /* it's true when current open file is snapshot */
-       bool                    snapshot;
+       /* All new field here will be zeroed out in pipe_read */
 };
 
 enum trace_iter_flags {
@@ -332,7 +334,7 @@ extern int trace_define_field(struct ftrace_event_call *call, const char *type,
                              const char *name, int offset, int size,
                              int is_signed, int filter_type);
 extern int trace_add_event_call(struct ftrace_event_call *call);
-extern void trace_remove_event_call(struct ftrace_event_call *call);
+extern int trace_remove_event_call(struct ftrace_event_call *call);
 
 #define is_signed_type(type)   (((type)(-1)) < (type)1)
 
index 3bef14c..482ad2d 100644 (file)
@@ -629,7 +629,7 @@ extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode);
 static inline void tracing_start(void) { }
 static inline void tracing_stop(void) { }
 static inline void ftrace_off_permanent(void) { }
-static inline void trace_dump_stack(void) { }
+static inline void trace_dump_stack(int skip) { }
 
 static inline void tracing_on(void) { }
 static inline void tracing_off(void) { }
index 75981d0..580a532 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/list.h>
 #include <linux/rbtree.h>
+#include <linux/err.h>
 
 struct module;
 struct device;
index b6b215f..14105c2 100644 (file)
@@ -23,6 +23,7 @@ struct user_namespace {
        struct uid_gid_map      projid_map;
        atomic_t                count;
        struct user_namespace   *parent;
+       int                     level;
        kuid_t                  owner;
        kgid_t                  group;
        unsigned int            proc_inum;
index 7343a27..47ada23 100644 (file)
@@ -22,6 +22,7 @@
 #define _V4L2_CTRLS_H
 
 #include <linux/list.h>
+#include <linux/mutex.h>
 #include <linux/videodev2.h>
 
 /* forward references */
index 789ec46..781845a 100644 (file)
@@ -4335,8 +4335,10 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
                }
 
                err = percpu_ref_init(&css->refcnt, css_release);
-               if (err)
+               if (err) {
+                       ss->css_free(cgrp);
                        goto err_free_all;
+               }
 
                init_cgroup_css(css, ss, cgrp);
 
index b51087f..276762f 100644 (file)
@@ -19,7 +19,8 @@ char *_braille_console_setup(char **str, char **brl_options)
                        pr_err("need port name after brl=\n");
                else
                        *((*str)++) = 0;
-       }
+       } else
+               return NULL;
 
        return *str;
 }
index 4041f57..a146ee3 100644 (file)
@@ -469,7 +469,6 @@ static int ptrace_detach(struct task_struct *child, unsigned int data)
        /* Architecture-specific hardware disable .. */
        ptrace_disable(child);
        clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-       flush_ptrace_hw_breakpoint(child);
 
        write_lock_irq(&tasklist_lock);
        /*
index 8ce9eef..a6d098c 100644 (file)
@@ -2169,12 +2169,57 @@ static cycle_t          ftrace_update_time;
 static unsigned long   ftrace_update_cnt;
 unsigned long          ftrace_update_tot_cnt;
 
-static int ops_traces_mod(struct ftrace_ops *ops)
+static inline int ops_traces_mod(struct ftrace_ops *ops)
 {
-       struct ftrace_hash *hash;
+       /*
+        * Filter_hash being empty will default to trace module.
+        * But notrace hash requires a test of individual module functions.
+        */
+       return ftrace_hash_empty(ops->filter_hash) &&
+               ftrace_hash_empty(ops->notrace_hash);
+}
+
+/*
+ * Check if the current ops references the record.
+ *
+ * If the ops traces all functions, then it was already accounted for.
+ * If the ops does not trace the current record function, skip it.
+ * If the ops ignores the function via notrace filter, skip it.
+ */
+static inline bool
+ops_references_rec(struct ftrace_ops *ops, struct dyn_ftrace *rec)
+{
+       /* If ops isn't enabled, ignore it */
+       if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
+               return 0;
+
+       /* If ops traces all mods, we already accounted for it */
+       if (ops_traces_mod(ops))
+               return 0;
+
+       /* The function must be in the filter */
+       if (!ftrace_hash_empty(ops->filter_hash) &&
+           !ftrace_lookup_ip(ops->filter_hash, rec->ip))
+               return 0;
+
+       /* If in notrace hash, we ignore it too */
+       if (ftrace_lookup_ip(ops->notrace_hash, rec->ip))
+               return 0;
+
+       return 1;
+}
+
+static int referenced_filters(struct dyn_ftrace *rec)
+{
+       struct ftrace_ops *ops;
+       int cnt = 0;
 
-       hash = ops->filter_hash;
-       return ftrace_hash_empty(hash);
+       for (ops = ftrace_ops_list; ops != &ftrace_list_end; ops = ops->next) {
+               if (ops_references_rec(ops, rec))
+                   cnt++;
+       }
+
+       return cnt;
 }
 
 static int ftrace_update_code(struct module *mod)
@@ -2183,6 +2228,7 @@ static int ftrace_update_code(struct module *mod)
        struct dyn_ftrace *p;
        cycle_t start, stop;
        unsigned long ref = 0;
+       bool test = false;
        int i;
 
        /*
@@ -2196,9 +2242,12 @@ static int ftrace_update_code(struct module *mod)
 
                for (ops = ftrace_ops_list;
                     ops != &ftrace_list_end; ops = ops->next) {
-                       if (ops->flags & FTRACE_OPS_FL_ENABLED &&
-                           ops_traces_mod(ops))
-                               ref++;
+                       if (ops->flags & FTRACE_OPS_FL_ENABLED) {
+                               if (ops_traces_mod(ops))
+                                       ref++;
+                               else
+                                       test = true;
+                       }
                }
        }
 
@@ -2208,12 +2257,16 @@ static int ftrace_update_code(struct module *mod)
        for (pg = ftrace_new_pgs; pg; pg = pg->next) {
 
                for (i = 0; i < pg->index; i++) {
+                       int cnt = ref;
+
                        /* If something went wrong, bail without enabling anything */
                        if (unlikely(ftrace_disabled))
                                return -1;
 
                        p = &pg->records[i];
-                       p->flags = ref;
+                       if (test)
+                               cnt += referenced_filters(p);
+                       p->flags = cnt;
 
                        /*
                         * Do the initial record conversion from mcount jump
@@ -2233,7 +2286,7 @@ static int ftrace_update_code(struct module *mod)
                         * conversion puts the module to the correct state, thus
                         * passing the ftrace_make_call check.
                         */
-                       if (ftrace_start_up && ref) {
+                       if (ftrace_start_up && cnt) {
                                int failed = __ftrace_replace_code(p, 1);
                                if (failed)
                                        ftrace_bug(failed, p->ip);
@@ -3384,6 +3437,12 @@ ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove)
        return add_hash_entry(hash, ip);
 }
 
+static void ftrace_ops_update_code(struct ftrace_ops *ops)
+{
+       if (ops->flags & FTRACE_OPS_FL_ENABLED && ftrace_enabled)
+               ftrace_run_update_code(FTRACE_UPDATE_CALLS);
+}
+
 static int
 ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len,
                unsigned long ip, int remove, int reset, int enable)
@@ -3426,9 +3485,8 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len,
 
        mutex_lock(&ftrace_lock);
        ret = ftrace_hash_move(ops, enable, orig_hash, hash);
-       if (!ret && ops->flags & FTRACE_OPS_FL_ENABLED
-           && ftrace_enabled)
-               ftrace_run_update_code(FTRACE_UPDATE_CALLS);
+       if (!ret)
+               ftrace_ops_update_code(ops);
 
        mutex_unlock(&ftrace_lock);
 
@@ -3655,9 +3713,8 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
                mutex_lock(&ftrace_lock);
                ret = ftrace_hash_move(iter->ops, filter_hash,
                                       orig_hash, iter->hash);
-               if (!ret && (iter->ops->flags & FTRACE_OPS_FL_ENABLED)
-                   && ftrace_enabled)
-                       ftrace_run_update_code(FTRACE_UPDATE_CALLS);
+               if (!ret)
+                       ftrace_ops_update_code(iter->ops);
 
                mutex_unlock(&ftrace_lock);
        }
index 882ec1d..496f94d 100644 (file)
@@ -243,20 +243,25 @@ int filter_current_check_discard(struct ring_buffer *buffer,
 }
 EXPORT_SYMBOL_GPL(filter_current_check_discard);
 
-cycle_t ftrace_now(int cpu)
+cycle_t buffer_ftrace_now(struct trace_buffer *buf, int cpu)
 {
        u64 ts;
 
        /* Early boot up does not have a buffer yet */
-       if (!global_trace.trace_buffer.buffer)
+       if (!buf->buffer)
                return trace_clock_local();
 
-       ts = ring_buffer_time_stamp(global_trace.trace_buffer.buffer, cpu);
-       ring_buffer_normalize_time_stamp(global_trace.trace_buffer.buffer, cpu, &ts);
+       ts = ring_buffer_time_stamp(buf->buffer, cpu);
+       ring_buffer_normalize_time_stamp(buf->buffer, cpu, &ts);
 
        return ts;
 }
 
+cycle_t ftrace_now(int cpu)
+{
+       return buffer_ftrace_now(&global_trace.trace_buffer, cpu);
+}
+
 /**
  * tracing_is_enabled - Show if global_trace has been disabled
  *
@@ -1211,7 +1216,7 @@ void tracing_reset_online_cpus(struct trace_buffer *buf)
        /* Make sure all commits have finished */
        synchronize_sched();
 
-       buf->time_start = ftrace_now(buf->cpu);
+       buf->time_start = buffer_ftrace_now(buf, buf->cpu);
 
        for_each_online_cpu(cpu)
                ring_buffer_reset_cpu(buffer, cpu);
@@ -1219,11 +1224,6 @@ void tracing_reset_online_cpus(struct trace_buffer *buf)
        ring_buffer_record_enable(buffer);
 }
 
-void tracing_reset_current(int cpu)
-{
-       tracing_reset(&global_trace.trace_buffer, cpu);
-}
-
 /* Must have trace_types_lock held */
 void tracing_reset_all_online_cpus(void)
 {
@@ -4151,6 +4151,7 @@ waitagain:
        memset(&iter->seq, 0,
               sizeof(struct trace_iterator) -
               offsetof(struct trace_iterator, seq));
+       cpumask_clear(iter->started);
        iter->pos = -1;
 
        trace_event_read_lock();
@@ -4468,7 +4469,7 @@ tracing_free_buffer_release(struct inode *inode, struct file *filp)
 
        /* disable tracing ? */
        if (trace_flags & TRACE_ITER_STOP_ON_FREE)
-               tracing_off();
+               tracer_tracing_off(tr);
        /* resize the ring buffer to 0 */
        tracing_resize_ring_buffer(tr, 0, RING_BUFFER_ALL_CPUS);
 
@@ -4633,12 +4634,12 @@ static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,
         * New clock may not be consistent with the previous clock.
         * Reset the buffer so that it doesn't have incomparable timestamps.
         */
-       tracing_reset_online_cpus(&global_trace.trace_buffer);
+       tracing_reset_online_cpus(&tr->trace_buffer);
 
 #ifdef CONFIG_TRACER_MAX_TRACE
        if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer)
                ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func);
-       tracing_reset_online_cpus(&global_trace.max_buffer);
+       tracing_reset_online_cpus(&tr->max_buffer);
 #endif
 
        mutex_unlock(&trace_types_lock);
index 898f868..29a7ebc 100644 (file)
@@ -409,33 +409,42 @@ static void put_system(struct ftrace_subsystem_dir *dir)
        mutex_unlock(&event_mutex);
 }
 
-/*
- * Open and update trace_array ref count.
- * Must have the current trace_array passed to it.
- */
-static int tracing_open_generic_file(struct inode *inode, struct file *filp)
+static void remove_subsystem(struct ftrace_subsystem_dir *dir)
 {
-       struct ftrace_event_file *file = inode->i_private;
-       struct trace_array *tr = file->tr;
-       int ret;
+       if (!dir)
+               return;
 
-       if (trace_array_get(tr) < 0)
-               return -ENODEV;
+       if (!--dir->nr_events) {
+               debugfs_remove_recursive(dir->entry);
+               list_del(&dir->list);
+               __put_system_dir(dir);
+       }
+}
 
-       ret = tracing_open_generic(inode, filp);
-       if (ret < 0)
-               trace_array_put(tr);
-       return ret;
+static void *event_file_data(struct file *filp)
+{
+       return ACCESS_ONCE(file_inode(filp)->i_private);
 }
 
-static int tracing_release_generic_file(struct inode *inode, struct file *filp)
+static void remove_event_file_dir(struct ftrace_event_file *file)
 {
-       struct ftrace_event_file *file = inode->i_private;
-       struct trace_array *tr = file->tr;
+       struct dentry *dir = file->dir;
+       struct dentry *child;
 
-       trace_array_put(tr);
+       if (dir) {
+               spin_lock(&dir->d_lock);        /* probably unneeded */
+               list_for_each_entry(child, &dir->d_subdirs, d_u.d_child) {
+                       if (child->d_inode)     /* probably unneeded */
+                               child->d_inode->i_private = NULL;
+               }
+               spin_unlock(&dir->d_lock);
 
-       return 0;
+               debugfs_remove_recursive(dir);
+       }
+
+       list_del(&file->list);
+       remove_subsystem(file->system);
+       kmem_cache_free(file_cachep, file);
 }
 
 /*
@@ -679,15 +688,25 @@ static ssize_t
 event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
                  loff_t *ppos)
 {
-       struct ftrace_event_file *file = filp->private_data;
+       struct ftrace_event_file *file;
+       unsigned long flags;
        char buf[4] = "0";
 
-       if (file->flags & FTRACE_EVENT_FL_ENABLED &&
-           !(file->flags & FTRACE_EVENT_FL_SOFT_DISABLED))
+       mutex_lock(&event_mutex);
+       file = event_file_data(filp);
+       if (likely(file))
+               flags = file->flags;
+       mutex_unlock(&event_mutex);
+
+       if (!file)
+               return -ENODEV;
+
+       if (flags & FTRACE_EVENT_FL_ENABLED &&
+           !(flags & FTRACE_EVENT_FL_SOFT_DISABLED))
                strcpy(buf, "1");
 
-       if (file->flags & FTRACE_EVENT_FL_SOFT_DISABLED ||
-           file->flags & FTRACE_EVENT_FL_SOFT_MODE)
+       if (flags & FTRACE_EVENT_FL_SOFT_DISABLED ||
+           flags & FTRACE_EVENT_FL_SOFT_MODE)
                strcat(buf, "*");
 
        strcat(buf, "\n");
@@ -699,13 +718,10 @@ static ssize_t
 event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
                   loff_t *ppos)
 {
-       struct ftrace_event_file *file = filp->private_data;
+       struct ftrace_event_file *file;
        unsigned long val;
        int ret;
 
-       if (!file)
-               return -EINVAL;
-
        ret = kstrtoul_from_user(ubuf, cnt, 10, &val);
        if (ret)
                return ret;
@@ -717,8 +733,11 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
        switch (val) {
        case 0:
        case 1:
+               ret = -ENODEV;
                mutex_lock(&event_mutex);
-               ret = ftrace_event_enable_disable(file, val);
+               file = event_file_data(filp);
+               if (likely(file))
+                       ret = ftrace_event_enable_disable(file, val);
                mutex_unlock(&event_mutex);
                break;
 
@@ -825,7 +844,7 @@ enum {
 
 static void *f_next(struct seq_file *m, void *v, loff_t *pos)
 {
-       struct ftrace_event_call *call = m->private;
+       struct ftrace_event_call *call = event_file_data(m->private);
        struct list_head *common_head = &ftrace_common_fields;
        struct list_head *head = trace_get_fields(call);
        struct list_head *node = v;
@@ -857,7 +876,7 @@ static void *f_next(struct seq_file *m, void *v, loff_t *pos)
 
 static int f_show(struct seq_file *m, void *v)
 {
-       struct ftrace_event_call *call = m->private;
+       struct ftrace_event_call *call = event_file_data(m->private);
        struct ftrace_event_field *field;
        const char *array_descriptor;
 
@@ -910,6 +929,11 @@ static void *f_start(struct seq_file *m, loff_t *pos)
        void *p = (void *)FORMAT_HEADER;
        loff_t l = 0;
 
+       /* ->stop() is called even if ->start() fails */
+       mutex_lock(&event_mutex);
+       if (!event_file_data(m->private))
+               return ERR_PTR(-ENODEV);
+
        while (l < *pos && p)
                p = f_next(m, p, &l);
 
@@ -918,6 +942,7 @@ static void *f_start(struct seq_file *m, loff_t *pos)
 
 static void f_stop(struct seq_file *m, void *p)
 {
+       mutex_unlock(&event_mutex);
 }
 
 static const struct seq_operations trace_format_seq_ops = {
@@ -929,7 +954,6 @@ static const struct seq_operations trace_format_seq_ops = {
 
 static int trace_format_open(struct inode *inode, struct file *file)
 {
-       struct ftrace_event_call *call = inode->i_private;
        struct seq_file *m;
        int ret;
 
@@ -938,7 +962,7 @@ static int trace_format_open(struct inode *inode, struct file *file)
                return ret;
 
        m = file->private_data;
-       m->private = call;
+       m->private = file;
 
        return 0;
 }
@@ -946,14 +970,18 @@ static int trace_format_open(struct inode *inode, struct file *file)
 static ssize_t
 event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
 {
-       struct ftrace_event_call *call = filp->private_data;
+       int id = (long)event_file_data(filp);
        char buf[32];
        int len;
 
        if (*ppos)
                return 0;
 
-       len = sprintf(buf, "%d\n", call->event.type);
+       if (unlikely(!id))
+               return -ENODEV;
+
+       len = sprintf(buf, "%d\n", id);
+
        return simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
 }
 
@@ -961,21 +989,28 @@ static ssize_t
 event_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
                  loff_t *ppos)
 {
-       struct ftrace_event_call *call = filp->private_data;
+       struct ftrace_event_call *call;
        struct trace_seq *s;
-       int r;
+       int r = -ENODEV;
 
        if (*ppos)
                return 0;
 
        s = kmalloc(sizeof(*s), GFP_KERNEL);
+
        if (!s)
                return -ENOMEM;
 
        trace_seq_init(s);
 
-       print_event_filter(call, s);
-       r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
+       mutex_lock(&event_mutex);
+       call = event_file_data(filp);
+       if (call)
+               print_event_filter(call, s);
+       mutex_unlock(&event_mutex);
+
+       if (call)
+               r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
 
        kfree(s);
 
@@ -986,9 +1021,9 @@ static ssize_t
 event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
                   loff_t *ppos)
 {
-       struct ftrace_event_call *call = filp->private_data;
+       struct ftrace_event_call *call;
        char *buf;
-       int err;
+       int err = -ENODEV;
 
        if (cnt >= PAGE_SIZE)
                return -EINVAL;
@@ -1003,7 +1038,12 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
        }
        buf[cnt] = '\0';
 
-       err = apply_event_filter(call, buf);
+       mutex_lock(&event_mutex);
+       call = event_file_data(filp);
+       if (call)
+               err = apply_event_filter(call, buf);
+       mutex_unlock(&event_mutex);
+
        free_page((unsigned long) buf);
        if (err < 0)
                return err;
@@ -1225,10 +1265,9 @@ static const struct file_operations ftrace_set_event_fops = {
 };
 
 static const struct file_operations ftrace_enable_fops = {
-       .open = tracing_open_generic_file,
+       .open = tracing_open_generic,
        .read = event_enable_read,
        .write = event_enable_write,
-       .release = tracing_release_generic_file,
        .llseek = default_llseek,
 };
 
@@ -1240,7 +1279,6 @@ static const struct file_operations ftrace_event_format_fops = {
 };
 
 static const struct file_operations ftrace_event_id_fops = {
-       .open = tracing_open_generic,
        .read = event_id_read,
        .llseek = default_llseek,
 };
@@ -1488,8 +1526,8 @@ event_create_dir(struct dentry *parent,
 
 #ifdef CONFIG_PERF_EVENTS
        if (call->event.type && call->class->reg)
-               trace_create_file("id", 0444, file->dir, call,
-                                 id);
+               trace_create_file("id", 0444, file->dir,
+                                 (void *)(long)call->event.type, id);
 #endif
 
        /*
@@ -1514,33 +1552,16 @@ event_create_dir(struct dentry *parent,
        return 0;
 }
 
-static void remove_subsystem(struct ftrace_subsystem_dir *dir)
-{
-       if (!dir)
-               return;
-
-       if (!--dir->nr_events) {
-               debugfs_remove_recursive(dir->entry);
-               list_del(&dir->list);
-               __put_system_dir(dir);
-       }
-}
-
 static void remove_event_from_tracers(struct ftrace_event_call *call)
 {
        struct ftrace_event_file *file;
        struct trace_array *tr;
 
        do_for_each_event_file_safe(tr, file) {
-
                if (file->event_call != call)
                        continue;
 
-               list_del(&file->list);
-               debugfs_remove_recursive(file->dir);
-               remove_subsystem(file->system);
-               kmem_cache_free(file_cachep, file);
-
+               remove_event_file_dir(file);
                /*
                 * The do_for_each_event_file_safe() is
                 * a double loop. After finding the call for this
@@ -1692,16 +1713,53 @@ static void __trace_remove_event_call(struct ftrace_event_call *call)
        destroy_preds(call);
 }
 
+static int probe_remove_event_call(struct ftrace_event_call *call)
+{
+       struct trace_array *tr;
+       struct ftrace_event_file *file;
+
+#ifdef CONFIG_PERF_EVENTS
+       if (call->perf_refcount)
+               return -EBUSY;
+#endif
+       do_for_each_event_file(tr, file) {
+               if (file->event_call != call)
+                       continue;
+               /*
+                * We can't rely on ftrace_event_enable_disable(enable => 0)
+                * we are going to do, FTRACE_EVENT_FL_SOFT_MODE can suppress
+                * TRACE_REG_UNREGISTER.
+                */
+               if (file->flags & FTRACE_EVENT_FL_ENABLED)
+                       return -EBUSY;
+               /*
+                * The do_for_each_event_file_safe() is
+                * a double loop. After finding the call for this
+                * trace_array, we use break to jump to the next
+                * trace_array.
+                */
+               break;
+       } while_for_each_event_file();
+
+       __trace_remove_event_call(call);
+
+       return 0;
+}
+
 /* Remove an event_call */
-void trace_remove_event_call(struct ftrace_event_call *call)
+int trace_remove_event_call(struct ftrace_event_call *call)
 {
+       int ret;
+
        mutex_lock(&trace_types_lock);
        mutex_lock(&event_mutex);
        down_write(&trace_event_sem);
-       __trace_remove_event_call(call);
+       ret = probe_remove_event_call(call);
        up_write(&trace_event_sem);
        mutex_unlock(&event_mutex);
        mutex_unlock(&trace_types_lock);
+
+       return ret;
 }
 
 #define for_each_event(event, start, end)                      \
@@ -2270,12 +2328,8 @@ __trace_remove_event_dirs(struct trace_array *tr)
 {
        struct ftrace_event_file *file, *next;
 
-       list_for_each_entry_safe(file, next, &tr->events, list) {
-               list_del(&file->list);
-               debugfs_remove_recursive(file->dir);
-               remove_subsystem(file->system);
-               kmem_cache_free(file_cachep, file);
-       }
+       list_for_each_entry_safe(file, next, &tr->events, list)
+               remove_event_file_dir(file);
 }
 
 static void
index 0c7b75a..97daa8c 100644 (file)
@@ -637,17 +637,15 @@ static void append_filter_err(struct filter_parse_state *ps,
        free_page((unsigned long) buf);
 }
 
+/* caller must hold event_mutex */
 void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s)
 {
-       struct event_filter *filter;
+       struct event_filter *filter = call->filter;
 
-       mutex_lock(&event_mutex);
-       filter = call->filter;
        if (filter && filter->filter_string)
                trace_seq_printf(s, "%s\n", filter->filter_string);
        else
                trace_seq_puts(s, "none\n");
-       mutex_unlock(&event_mutex);
 }
 
 void print_subsystem_event_filter(struct event_subsystem *system,
@@ -1841,23 +1839,22 @@ static int create_system_filter(struct event_subsystem *system,
        return err;
 }
 
+/* caller must hold event_mutex */
 int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
 {
        struct event_filter *filter;
-       int err = 0;
-
-       mutex_lock(&event_mutex);
+       int err;
 
        if (!strcmp(strstrip(filter_string), "0")) {
                filter_disable(call);
                filter = call->filter;
                if (!filter)
-                       goto out_unlock;
+                       return 0;
                RCU_INIT_POINTER(call->filter, NULL);
                /* Make sure the filter is not being used */
                synchronize_sched();
                __free_filter(filter);
-               goto out_unlock;
+               return 0;
        }
 
        err = create_filter(call, filter_string, true, &filter);
@@ -1884,8 +1881,6 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
                        __free_filter(tmp);
                }
        }
-out_unlock:
-       mutex_unlock(&event_mutex);
 
        return err;
 }
index 3811487..243f683 100644 (file)
@@ -95,7 +95,7 @@ static __kprobes bool trace_probe_is_on_module(struct trace_probe *tp)
 }
 
 static int register_probe_event(struct trace_probe *tp);
-static void unregister_probe_event(struct trace_probe *tp);
+static int unregister_probe_event(struct trace_probe *tp);
 
 static DEFINE_MUTEX(probe_lock);
 static LIST_HEAD(probe_list);
@@ -351,9 +351,12 @@ static int unregister_trace_probe(struct trace_probe *tp)
        if (trace_probe_is_enabled(tp))
                return -EBUSY;
 
+       /* Will fail if probe is being used by ftrace or perf */
+       if (unregister_probe_event(tp))
+               return -EBUSY;
+
        __unregister_trace_probe(tp);
        list_del(&tp->list);
-       unregister_probe_event(tp);
 
        return 0;
 }
@@ -632,7 +635,9 @@ static int release_all_trace_probes(void)
        /* TODO: Use batch unregistration */
        while (!list_empty(&probe_list)) {
                tp = list_entry(probe_list.next, struct trace_probe, list);
-               unregister_trace_probe(tp);
+               ret = unregister_trace_probe(tp);
+               if (ret)
+                       goto end;
                free_trace_probe(tp);
        }
 
@@ -1247,11 +1252,15 @@ static int register_probe_event(struct trace_probe *tp)
        return ret;
 }
 
-static void unregister_probe_event(struct trace_probe *tp)
+static int unregister_probe_event(struct trace_probe *tp)
 {
+       int ret;
+
        /* tp->event is unregistered in trace_remove_event_call() */
-       trace_remove_event_call(&tp->call);
-       kfree(tp->call.print_fmt);
+       ret = trace_remove_event_call(&tp->call);
+       if (!ret)
+               kfree(tp->call.print_fmt);
+       return ret;
 }
 
 /* Make a debugfs interface for controlling probe points */
index a23d2d7..272261b 100644 (file)
@@ -70,7 +70,7 @@ struct trace_uprobe {
        (sizeof(struct probe_arg) * (n)))
 
 static int register_uprobe_event(struct trace_uprobe *tu);
-static void unregister_uprobe_event(struct trace_uprobe *tu);
+static int unregister_uprobe_event(struct trace_uprobe *tu);
 
 static DEFINE_MUTEX(uprobe_lock);
 static LIST_HEAD(uprobe_list);
@@ -164,11 +164,17 @@ static struct trace_uprobe *find_probe_event(const char *event, const char *grou
 }
 
 /* Unregister a trace_uprobe and probe_event: call with locking uprobe_lock */
-static void unregister_trace_uprobe(struct trace_uprobe *tu)
+static int unregister_trace_uprobe(struct trace_uprobe *tu)
 {
+       int ret;
+
+       ret = unregister_uprobe_event(tu);
+       if (ret)
+               return ret;
+
        list_del(&tu->list);
-       unregister_uprobe_event(tu);
        free_trace_uprobe(tu);
+       return 0;
 }
 
 /* Register a trace_uprobe and probe_event */
@@ -181,9 +187,12 @@ static int register_trace_uprobe(struct trace_uprobe *tu)
 
        /* register as an event */
        old_tp = find_probe_event(tu->call.name, tu->call.class->system);
-       if (old_tp)
+       if (old_tp) {
                /* delete old event */
-               unregister_trace_uprobe(old_tp);
+               ret = unregister_trace_uprobe(old_tp);
+               if (ret)
+                       goto end;
+       }
 
        ret = register_uprobe_event(tu);
        if (ret) {
@@ -256,6 +265,8 @@ static int create_trace_uprobe(int argc, char **argv)
                group = UPROBE_EVENT_SYSTEM;
 
        if (is_delete) {
+               int ret;
+
                if (!event) {
                        pr_info("Delete command needs an event name.\n");
                        return -EINVAL;
@@ -269,9 +280,9 @@ static int create_trace_uprobe(int argc, char **argv)
                        return -ENOENT;
                }
                /* delete an event */
-               unregister_trace_uprobe(tu);
+               ret = unregister_trace_uprobe(tu);
                mutex_unlock(&uprobe_lock);
-               return 0;
+               return ret;
        }
 
        if (argc < 2) {
@@ -408,16 +419,20 @@ fail_address_parse:
        return ret;
 }
 
-static void cleanup_all_probes(void)
+static int cleanup_all_probes(void)
 {
        struct trace_uprobe *tu;
+       int ret = 0;
 
        mutex_lock(&uprobe_lock);
        while (!list_empty(&uprobe_list)) {
                tu = list_entry(uprobe_list.next, struct trace_uprobe, list);
-               unregister_trace_uprobe(tu);
+               ret = unregister_trace_uprobe(tu);
+               if (ret)
+                       break;
        }
        mutex_unlock(&uprobe_lock);
+       return ret;
 }
 
 /* Probes listing interfaces */
@@ -462,8 +477,13 @@ static const struct seq_operations probes_seq_op = {
 
 static int probes_open(struct inode *inode, struct file *file)
 {
-       if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC))
-               cleanup_all_probes();
+       int ret;
+
+       if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
+               ret = cleanup_all_probes();
+               if (ret)
+                       return ret;
+       }
 
        return seq_open(file, &probes_seq_op);
 }
@@ -968,12 +988,17 @@ static int register_uprobe_event(struct trace_uprobe *tu)
        return ret;
 }
 
-static void unregister_uprobe_event(struct trace_uprobe *tu)
+static int unregister_uprobe_event(struct trace_uprobe *tu)
 {
+       int ret;
+
        /* tu->event is unregistered in trace_remove_event_call() */
-       trace_remove_event_call(&tu->call);
+       ret = trace_remove_event_call(&tu->call);
+       if (ret)
+               return ret;
        kfree(tu->call.print_fmt);
        tu->call.print_fmt = NULL;
+       return 0;
 }
 
 /* Make a trace interface for controling probe points */
index d8c30db..9064b91 100644 (file)
@@ -62,6 +62,9 @@ int create_user_ns(struct cred *new)
        kgid_t group = new->egid;
        int ret;
 
+       if (parent_ns->level > 32)
+               return -EUSERS;
+
        /*
         * Verify that we can not violate the policy of which files
         * may be accessed that is specified by the root directory,
@@ -92,6 +95,7 @@ int create_user_ns(struct cred *new)
        atomic_set(&ns->count, 1);
        /* Leave the new->user_ns reference with the new user namespace. */
        ns->parent = parent_ns;
+       ns->level = parent_ns->level + 1;
        ns->owner = owner;
        ns->group = group;
 
@@ -105,16 +109,21 @@ int create_user_ns(struct cred *new)
 int unshare_userns(unsigned long unshare_flags, struct cred **new_cred)
 {
        struct cred *cred;
+       int err = -ENOMEM;
 
        if (!(unshare_flags & CLONE_NEWUSER))
                return 0;
 
        cred = prepare_creds();
-       if (!cred)
-               return -ENOMEM;
+       if (cred) {
+               err = create_user_ns(cred);
+               if (err)
+                       put_cred(cred);
+               else
+                       *new_cred = cred;
+       }
 
-       *new_cred = cred;
-       return create_user_ns(cred);
+       return err;
 }
 
 void free_user_ns(struct user_namespace *ns)
index 0b72e81..7f5d4be 100644 (file)
@@ -2817,6 +2817,19 @@ already_gone:
        return false;
 }
 
+static bool __flush_work(struct work_struct *work)
+{
+       struct wq_barrier barr;
+
+       if (start_flush_work(work, &barr)) {
+               wait_for_completion(&barr.done);
+               destroy_work_on_stack(&barr.work);
+               return true;
+       } else {
+               return false;
+       }
+}
+
 /**
  * flush_work - wait for a work to finish executing the last queueing instance
  * @work: the work to flush
@@ -2830,18 +2843,10 @@ already_gone:
  */
 bool flush_work(struct work_struct *work)
 {
-       struct wq_barrier barr;
-
        lock_map_acquire(&work->lockdep_map);
        lock_map_release(&work->lockdep_map);
 
-       if (start_flush_work(work, &barr)) {
-               wait_for_completion(&barr.done);
-               destroy_work_on_stack(&barr.work);
-               return true;
-       } else {
-               return false;
-       }
+       return __flush_work(work);
 }
 EXPORT_SYMBOL_GPL(flush_work);
 
@@ -3411,6 +3416,12 @@ static void copy_workqueue_attrs(struct workqueue_attrs *to,
 {
        to->nice = from->nice;
        cpumask_copy(to->cpumask, from->cpumask);
+       /*
+        * Unlike hash and equality test, this function doesn't ignore
+        * ->no_numa as it is used for both pool and wq attrs.  Instead,
+        * get_unbound_pool() explicitly clears ->no_numa after copying.
+        */
+       to->no_numa = from->no_numa;
 }
 
 /* hash value of the content of @attr */
@@ -3578,6 +3589,12 @@ static struct worker_pool *get_unbound_pool(const struct workqueue_attrs *attrs)
        lockdep_set_subclass(&pool->lock, 1);   /* see put_pwq() */
        copy_workqueue_attrs(pool->attrs, attrs);
 
+       /*
+        * no_numa isn't a worker_pool attribute, always clear it.  See
+        * 'struct workqueue_attrs' comments for detail.
+        */
+       pool->attrs->no_numa = false;
+
        /* if cpumask is contained inside a NUMA node, we belong to that node */
        if (wq_numa_enabled) {
                for_each_node(node) {
@@ -4756,7 +4773,14 @@ long work_on_cpu(int cpu, long (*fn)(void *), void *arg)
 
        INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn);
        schedule_work_on(cpu, &wfc.work);
-       flush_work(&wfc.work);
+
+       /*
+        * The work item is on-stack and can't lead to deadlock through
+        * flushing.  Use __flush_work() to avoid spurious lockdep warnings
+        * when work_on_cpu()s are nested.
+        */
+       __flush_work(&wfc.work);
+
        return wfc.ret;
 }
 EXPORT_SYMBOL_GPL(work_on_cpu);
index 2b02d66..e3ba1f2 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1968,9 +1968,6 @@ static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
        int pages;
        int pobjects;
 
-       if (!s->cpu_partial)
-               return;
-
        do {
                pages = 0;
                pobjects = 0;
index 3f7682a..eefbd10 100644 (file)
@@ -1998,12 +1998,11 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
  *
  * Create or update the port list entry
  */
-static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
+static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
                                int act)
 {
        __be16 *bep;
        __be32 *be32p;
-       struct sockaddr_in6 *addr6;
        struct smk_port_label *spp;
        struct socket_smack *ssp = sk->sk_security;
        struct smack_known *skp;
@@ -2025,10 +2024,9 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
        /*
         * Get the IP address and port from the address.
         */
-       addr6 = (struct sockaddr_in6 *)address;
-       port = ntohs(addr6->sin6_port);
-       bep = (__be16 *)(&addr6->sin6_addr);
-       be32p = (__be32 *)(&addr6->sin6_addr);
+       port = ntohs(address->sin6_port);
+       bep = (__be16 *)(&address->sin6_addr);
+       be32p = (__be32 *)(&address->sin6_addr);
 
        /*
         * It's remote, so port lookup does no good.
@@ -2060,9 +2058,9 @@ auditout:
        ad.a.u.net->family = sk->sk_family;
        ad.a.u.net->dport = port;
        if (act == SMK_RECEIVING)
-               ad.a.u.net->v6info.saddr = addr6->sin6_addr;
+               ad.a.u.net->v6info.saddr = address->sin6_addr;
        else
-               ad.a.u.net->v6info.daddr = addr6->sin6_addr;
+               ad.a.u.net->v6info.daddr = address->sin6_addr;
 #endif
        return smk_access(skp, object, MAY_WRITE, &ad);
 }
@@ -2201,7 +2199,8 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
        case PF_INET6:
                if (addrlen < sizeof(struct sockaddr_in6))
                        return -EINVAL;
-               rc = smk_ipv6_port_check(sock->sk, sap, SMK_CONNECTING);
+               rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap,
+                                               SMK_CONNECTING);
                break;
        }
        return rc;
@@ -3034,7 +3033,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
                                int size)
 {
        struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
-       struct sockaddr *sap = (struct sockaddr *) msg->msg_name;
+       struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name;
        int rc = 0;
 
        /*
@@ -3121,9 +3120,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
        return smack_net_ambient;
 }
 
-static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr *sap)
+static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
 {
-       struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
        u8 nexthdr;
        int offset;
        int proto = -EINVAL;
@@ -3181,7 +3179,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
        struct netlbl_lsm_secattr secattr;
        struct socket_smack *ssp = sk->sk_security;
        struct smack_known *skp;
-       struct sockaddr sadd;
+       struct sockaddr_in6 sadd;
        int rc = 0;
        struct smk_audit_info ad;
 #ifdef CONFIG_AUDIT