Merge branch 'for-linus2' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 28 Dec 2015 18:35:19 +0000 (10:35 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 28 Dec 2015 18:35:19 +0000 (10:35 -0800)
Pull key handling bugfix from James Morris:
 "Fix a race between keyctl_read() and keyctl_revoke()"

* 'for-linus2' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
  KEYS: Fix race between read and revoke

202 files changed:
Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
Documentation/devicetree/bindings/mtd/partition.txt
MAINTAINERS
Makefile
arch/arc/Kconfig
arch/arc/Makefile
arch/arc/boot/dts/axs10x_mb.dtsi
arch/arc/boot/dts/nsim_hs.dts
arch/arc/include/asm/cache.h
arch/arc/include/asm/mach_desc.h
arch/arc/include/asm/smp.h
arch/arc/include/asm/unwind.h
arch/arc/kernel/intc-arcv2.c
arch/arc/kernel/irq.c
arch/arc/kernel/mcip.c
arch/arc/kernel/perf_event.c
arch/arc/kernel/setup.c
arch/arc/kernel/smp.c
arch/arc/kernel/unwind.c
arch/arc/mm/highmem.c
arch/arc/mm/init.c
arch/arm/boot/dts/imx6q-gw5400-a.dts
arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
arch/arm/boot/dts/omap4-duovero-parlor.dts
arch/arm/boot/dts/sun6i-a31s-primo81.dts
arch/arm/boot/dts/tegra124-nyan.dtsi
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/timer.c
arch/mips/include/asm/uaccess.h
arch/mips/kernel/cps-vec.S
arch/mips/kernel/mips_ksyms.c
arch/mips/lib/memset.S
arch/mips/pci/pci-rt2880.c
arch/mips/pmcs-msp71xx/msp_setup.c
arch/mips/sni/reset.c
arch/mips/vdso/Makefile
arch/parisc/kernel/signal.c
arch/powerpc/include/asm/systbl.h
arch/powerpc/include/uapi/asm/unistd.h
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/platforms/powernv/opal-irqchip.c
arch/powerpc/platforms/powernv/opal.c
arch/s390/kernel/dis.c
arch/sparc/include/asm/elf_64.h
arch/sparc/include/uapi/asm/unistd.h
arch/sparc/kernel/head_64.S
arch/sparc/kernel/perf_event.c
arch/sparc/kernel/rtrap_64.S
arch/sparc/kernel/setup_64.c
arch/sparc/kernel/systbls_32.S
arch/sparc/kernel/systbls_64.S
arch/sparc/lib/NG2copy_from_user.S
arch/sparc/lib/NG2copy_to_user.S
arch/sparc/lib/NG2memcpy.S
arch/sparc/lib/NG4copy_from_user.S
arch/sparc/lib/NG4copy_to_user.S
arch/sparc/lib/NG4memcpy.S
arch/sparc/lib/U1copy_from_user.S
arch/sparc/lib/U1copy_to_user.S
arch/sparc/lib/U1memcpy.S
arch/sparc/lib/U3copy_from_user.S
arch/sparc/lib/U3copy_to_user.S
arch/sparc/lib/U3memcpy.S
arch/x86/kvm/cpuid.h
arch/x86/kvm/mtrr.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/um/signal.c
arch/x86/xen/mmu.c
arch/x86/xen/suspend.c
block/blk-core.c
drivers/acpi/processor_driver.c
drivers/base/power/domain.c
drivers/block/null_blk.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/common.h
drivers/bus/sunxi-rsb.c
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/scpi-cpufreq.c
drivers/gpio/gpio-ath79.c
drivers/gpio/gpio-generic.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_gem_stolen.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/nouveau/nvkm/subdev/bios/fan.c
drivers/hwmon/Kconfig
drivers/hwmon/tmp102.c
drivers/i2c/busses/i2c-davinci.c
drivers/i2c/busses/i2c-designware-core.c
drivers/i2c/busses/i2c-designware-core.h
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-rcar.c
drivers/i2c/busses/i2c-rk3x.c
drivers/i2c/busses/i2c-st.c
drivers/input/joystick/db9.c
drivers/input/joystick/gamecon.c
drivers/input/joystick/turbografx.c
drivers/input/joystick/walkera0701.c
drivers/input/misc/arizona-haptics.c
drivers/input/mouse/elan_i2c_core.c
drivers/input/serio/parkbd.c
drivers/input/tablet/aiptek.c
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/input/touchscreen/elants_i2c.c
drivers/iommu/amd_iommu_v2.c
drivers/iommu/intel-svm.c
drivers/md/md.c
drivers/md/md.h
drivers/md/raid10.c
drivers/media/pci/ivtv/ivtv-driver.c
drivers/media/usb/airspy/airspy.c
drivers/media/usb/hackrf/hackrf.c
drivers/memory/fsl_ifc.c
drivers/mtd/ofpart.c
drivers/mtd/ubi/debug.c
drivers/mtd/ubi/io.c
drivers/mtd/ubi/wl.c
drivers/net/xen-netback/netback.c
drivers/nvme/host/pci.c
drivers/phy/Kconfig
drivers/phy/phy-bcm-cygnus-pcie.c
drivers/phy/phy-berlin-sata.c
drivers/phy/phy-brcmstb-sata.c
drivers/phy/phy-core.c
drivers/phy/phy-miphy28lp.c
drivers/phy/phy-miphy365x.c
drivers/phy/phy-mt65xx-usb3.c
drivers/phy/phy-rockchip-usb.c
drivers/pinctrl/bcm/pinctrl-bcm2835.c
drivers/pinctrl/freescale/pinctrl-vf610.c
drivers/pinctrl/intel/pinctrl-broxton.c
drivers/pinctrl/intel/pinctrl-intel.c
drivers/pinctrl/intel/pinctrl-intel.h
drivers/pinctrl/intel/pinctrl-sunrisepoint.c
drivers/powercap/intel_rapl.c
drivers/rtc/rtc-da9063.c
drivers/rtc/rtc-rk808.c
drivers/s390/crypto/ap_bus.c
drivers/s390/virtio/virtio_ccw.c
drivers/scsi/scsi_pm.c
drivers/scsi/ses.c
drivers/spi/spi-fsl-dspi.c
drivers/spi/spi.c
drivers/spi/spidev.c
drivers/tty/n_tty.c
drivers/tty/serial/8250/8250_uniphier.c
drivers/tty/serial/earlycon.c
drivers/tty/serial/sh-sci.c
drivers/tty/serial/sunhv.c
drivers/tty/tty_buffer.c
drivers/usb/core/hub.c
drivers/usb/serial/ipaq.c
drivers/xen/events/events_fifo.c
drivers/xen/xen-pciback/pciback.h
drivers/xen/xen-pciback/pciback_ops.c
drivers/xen/xen-pciback/xenbus.c
drivers/xen/xen-scsiback.c
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/free-space-cache.c
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/btrfs/volumes.c
fs/nfsd/nfs4layouts.c
fs/proc/base.c
include/linux/enclosure.h
include/linux/mmdebug.h
include/xen/interface/io/ring.h
mm/zswap.c
scripts/recordmcount.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/es8328.c
sound/soc/codecs/es8328.h
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/wm8974.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/fsl/fsl_sai.c
sound/soc/rockchip/rockchip_spdif.c
sound/soc/rockchip/rockchip_spdif.h
sound/usb/mixer.c
sound/usb/mixer_maps.c
sound/usb/mixer_quirks.c
sound/usb/mixer_quirks.h
sound/usb/quirks.c
virt/kvm/arm/vgic.c

index b9c32f6fd687b04a3737c871bcf5c694665d3b84..4357e498ef0422d5fdc2715e3daf065ac80e41f4 100644 (file)
@@ -12,7 +12,7 @@ Each key is represented as a sub-node of "allwinner,sun4i-a10-lradc-keys":
 Required subnode-properties:
        - label: Descriptive name of the key.
        - linux,code: Keycode to emit.
-       - channel: Channel this key is attached to, mut be 0 or 1.
+       - channel: Channel this key is attached to, must be 0 or 1.
        - voltage: Voltage in ÂµV at lradc input when this key is pressed.
 
 Example:
index f1e2a02381a498a8f94e379870a8dcb1d2dec4ca..1c63e40659fcaada93e54ec81e8a12f62dca1f83 100644 (file)
@@ -6,7 +6,9 @@ used for what purposes, but which don't use an on-flash partition table such
 as RedBoot.
 
 The partition table should be a subnode of the mtd node and should be named
-'partitions'. Partitions are defined in subnodes of the partitions node.
+'partitions'. This node should have the following property:
+- compatible : (required) must be "fixed-partitions"
+Partitions are then defined in subnodes of the partitions node.
 
 For backwards compatibility partitions as direct subnodes of the mtd device are
 supported. This use is discouraged.
@@ -36,6 +38,7 @@ Examples:
 
 flash@0 {
        partitions {
+               compatible = "fixed-partitions";
                #address-cells = <1>;
                #size-cells = <1>;
 
@@ -53,6 +56,7 @@ flash@0 {
 
 flash@1 {
        partitions {
+               compatible = "fixed-partitions";
                #address-cells = <1>;
                #size-cells = <2>;
 
@@ -66,6 +70,7 @@ flash@1 {
 
 flash@2 {
        partitions {
+               compatible = "fixed-partitions";
                #address-cells = <2>;
                #size-cells = <2>;
 
index 6889a6dbb42ddfb19531cc7687eae048346b9244..233f83464814f138c4c68f0815d2dbeace552ef6 100644 (file)
@@ -8380,6 +8380,14 @@ L:       linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 S:     Maintained
 F:     drivers/pinctrl/samsung/
 
+PIN CONTROLLER - SINGLE
+M:     Tony Lindgren <tony@atomide.com>
+M:     Haojian Zhuang <haojian.zhuang@linaro.org>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:     linux-omap@vger.kernel.org
+S:     Maintained
+F:     drivers/pinctrl/pinctrl-single.c
+
 PIN CONTROLLER - ST SPEAR
 M:     Viresh Kumar <vireshk@kernel.org>
 L:     spear-devel@list.st.com
index bc0165d0f5cf30ea0faa7325fe96fd1b99b428fa..1122433a5cd54566578e3d71d3ad357fe52064f3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc7
 NAME = Blurry Fish Butt
 
 # *DOCUMENTATION*
index 2c2ac3f3ff80370bd6bad9fffc9dfb8c8f6931e8..6312f607932fd2241782827cce2ec7968ea3c8b6 100644 (file)
@@ -445,6 +445,7 @@ config LINUX_LINK_BASE
          However some customers have peripherals mapped at this addr, so
          Linux needs to be scooted a bit.
          If you don't know what the above means, leave this setting alone.
+         This needs to match memory start address specified in Device Tree
 
 config HIGHMEM
        bool "High Memory Support"
index cf0cf34eeb24b14ef070735e83d25b0f7f6aecec..aeb19021099e315967ba95524e9528c48da0d159 100644 (file)
@@ -81,7 +81,7 @@ endif
 LIBGCC := $(shell $(CC) $(cflags-y) --print-libgcc-file-name)
 
 # Modules with short calls might break for calls into builtin-kernel
-KBUILD_CFLAGS_MODULE   += -mlong-calls
+KBUILD_CFLAGS_MODULE   += -mlong-calls -mno-millicode
 
 # Finally dump eveything into kernel build system
 KBUILD_CFLAGS  += $(cflags-y)
index f3db32154973718268c1998e9f16bb03d1af7e7f..44a578c10732cd1ab79558415e3c66f6825c98bd 100644 (file)
@@ -46,6 +46,7 @@
                        snps,pbl = < 32 >;
                        clocks = <&apbclk>;
                        clock-names = "stmmaceth";
+                       max-speed = <100>;
                };
 
                ehci@0x40000 {
index b0eb0e7fe21d8a66b1d0ef5267f24dd6a1f8f254..fc81879bc1f5800e5efe8eb43395eb2c5509f481 100644 (file)
@@ -17,7 +17,8 @@
 
        memory {
                device_type = "memory";
-               reg = <0x0 0x80000000 0x0 0x40000000    /* 1 GB low mem */
+               /* CONFIG_LINUX_LINK_BASE needs to match low mem start */
+               reg = <0x0 0x80000000 0x0 0x20000000    /* 512 MB low mem */
                       0x1 0x00000000 0x0 0x40000000>;  /* 1 GB highmem */
        };
 
index abf06e81c9290f6eafc441b563061e3389032922..210ef3e7233224b099bd40e85106d2d864e70987 100644 (file)
@@ -62,9 +62,7 @@ extern int ioc_exists;
 #define ARC_REG_IC_IVIC                0x10
 #define ARC_REG_IC_CTRL                0x11
 #define ARC_REG_IC_IVIL                0x19
-#if defined(CONFIG_ARC_MMU_V3) || defined(CONFIG_ARC_MMU_V4)
 #define ARC_REG_IC_PTAG                0x1E
-#endif
 #define ARC_REG_IC_PTAG_HI     0x1F
 
 /* Bit val in IC_CTRL */
index 6ff657a904b61e700421b60423991273df93e1e1..c28e6c347b4900217ad48053c69679bb3da8b607 100644 (file)
@@ -23,7 +23,7 @@
  * @dt_compat:         Array of device tree 'compatible' strings
  *                     (XXX: although only 1st entry is looked at)
  * @init_early:                Very early callback [called from setup_arch()]
- * @init_cpu_smp:      for each CPU as it is coming up (SMP as well as UP)
+ * @init_per_cpu:      for each CPU as it is coming up (SMP as well as UP)
  *                     [(M):init_IRQ(), (o):start_kernel_secondary()]
  * @init_machine:      arch initcall level callback (e.g. populate static
  *                     platform devices or parse Devicetree)
@@ -35,7 +35,7 @@ struct machine_desc {
        const char              **dt_compat;
        void                    (*init_early)(void);
 #ifdef CONFIG_SMP
-       void                    (*init_cpu_smp)(unsigned int);
+       void                    (*init_per_cpu)(unsigned int);
 #endif
        void                    (*init_machine)(void);
        void                    (*init_late)(void);
index 133c867d15af0a627576d9faf89c0569220a6f47..991380438d6bfd6af03e6fff4748b8c5342b6a70 100644 (file)
@@ -48,7 +48,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
  * @init_early_smp:    A SMP specific h/w block can init itself
  *                     Could be common across platforms so not covered by
  *                     mach_desc->init_early()
- * @init_irq_cpu:      Called for each core so SMP h/w block driver can do
+ * @init_per_cpu:      Called for each core so SMP h/w block driver can do
  *                     any needed setup per cpu (e.g. IPI request)
  * @cpu_kick:          For Master to kickstart a cpu (optionally at a PC)
  * @ipi_send:          To send IPI to a @cpu
@@ -57,7 +57,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
 struct plat_smp_ops {
        const char      *info;
        void            (*init_early_smp)(void);
-       void            (*init_irq_cpu)(int cpu);
+       void            (*init_per_cpu)(int cpu);
        void            (*cpu_kick)(int cpu, unsigned long pc);
        void            (*ipi_send)(int cpu);
        void            (*ipi_clear)(int irq);
index 7ca628b6ee2aa6d1e02f6ad01363990439ec10b7..c11a25bb8158dee7f60a5f00ca8ec0addaf54b56 100644 (file)
@@ -112,7 +112,6 @@ struct unwind_frame_info {
 
 extern int arc_unwind(struct unwind_frame_info *frame);
 extern void arc_unwind_init(void);
-extern void arc_unwind_setup(void);
 extern void *unwind_add_table(struct module *module, const void *table_start,
                              unsigned long table_size);
 extern void unwind_remove_table(void *handle, int init_only);
@@ -152,9 +151,6 @@ static inline void arc_unwind_init(void)
 {
 }
 
-static inline void arc_unwind_setup(void)
-{
-}
 #define unwind_add_table(a, b, c)
 #define unwind_remove_table(a, b)
 
index 26c15682747960d3b5b1c412f76dff3c2ebc7780..0394f9f61b466dea018af3ec371c65a8dbc17acb 100644 (file)
@@ -106,10 +106,21 @@ static struct irq_chip arcv2_irq_chip = {
 static int arcv2_irq_map(struct irq_domain *d, unsigned int irq,
                         irq_hw_number_t hw)
 {
-       if (irq == TIMER0_IRQ || irq == IPI_IRQ)
+       /*
+        * core intc IRQs [16, 23]:
+        * Statically assigned always private-per-core (Timers, WDT, IPI, PCT)
+        */
+       if (hw < 24) {
+               /*
+                * A subsequent request_percpu_irq() fails if percpu_devid is
+                * not set. That in turns sets NOAUTOEN, meaning each core needs
+                * to call enable_percpu_irq()
+                */
+               irq_set_percpu_devid(irq);
                irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_percpu_irq);
-       else
+       } else {
                irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_level_irq);
+       }
 
        return 0;
 }
index 2ee226546c6a821f739a079326ed92ad52fe16b8..ba17f85285cfe85c53ba6c93db08d620c7109fb9 100644 (file)
@@ -29,11 +29,11 @@ void __init init_IRQ(void)
 
 #ifdef CONFIG_SMP
        /* a SMP H/w block could do IPI IRQ request here */
-       if (plat_smp_ops.init_irq_cpu)
-               plat_smp_ops.init_irq_cpu(smp_processor_id());
+       if (plat_smp_ops.init_per_cpu)
+               plat_smp_ops.init_per_cpu(smp_processor_id());
 
-       if (machine_desc->init_cpu_smp)
-               machine_desc->init_cpu_smp(smp_processor_id());
+       if (machine_desc->init_per_cpu)
+               machine_desc->init_per_cpu(smp_processor_id());
 #endif
 }
 
@@ -51,6 +51,18 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
        set_irq_regs(old_regs);
 }
 
+/*
+ * API called for requesting percpu interrupts - called by each CPU
+ *  - For boot CPU, actually request the IRQ with genirq core + enables
+ *  - For subsequent callers only enable called locally
+ *
+ * Relies on being called by boot cpu first (i.e. request called ahead) of
+ * any enable as expected by genirq. Hence Suitable only for TIMER, IPI
+ * which are guaranteed to be setup on boot core first.
+ * Late probed peripherals such as perf can't use this as there no guarantee
+ * of being called on boot CPU first.
+ */
+
 void arc_request_percpu_irq(int irq, int cpu,
                             irqreturn_t (*isr)(int irq, void *dev),
                             const char *irq_nm,
@@ -60,14 +72,17 @@ void arc_request_percpu_irq(int irq, int cpu,
        if (!cpu) {
                int rc;
 
+#ifdef CONFIG_ISA_ARCOMPACT
                /*
-                * These 2 calls are essential to making percpu IRQ APIs work
-                * Ideally these details could be hidden in irq chip map function
-                * but the issue is IPIs IRQs being static (non-DT) and platform
-                * specific, so we can't identify them there.
+                * A subsequent request_percpu_irq() fails if percpu_devid is
+                * not set. That in turns sets NOAUTOEN, meaning each core needs
+                * to call enable_percpu_irq()
+                *
+                * For ARCv2, this is done in irq map function since we know
+                * which irqs are strictly per cpu
                 */
                irq_set_percpu_devid(irq);
-               irq_modify_status(irq, IRQ_NOAUTOEN, 0);  /* @irq, @clr, @set */
+#endif
 
                rc = request_percpu_irq(irq, isr, irq_nm, percpu_dev);
                if (rc)
index 74a9b074ac3e4e64d97ef8e069f73a9104531682..bd237acdf4f2f9601efbf4c25c45067ddd2b69d9 100644 (file)
@@ -132,7 +132,7 @@ static void mcip_probe_n_setup(void)
 struct plat_smp_ops plat_smp_ops = {
        .info           = smp_cpuinfo_buf,
        .init_early_smp = mcip_probe_n_setup,
-       .init_irq_cpu   = mcip_setup_per_cpu,
+       .init_per_cpu   = mcip_setup_per_cpu,
        .ipi_send       = mcip_ipi_send,
        .ipi_clear      = mcip_ipi_clear,
 };
index 0c08bb1ce15aab114c344609879eaa86bfa59a9d..8b134cfe5e1f11023b559639497f7e1a35d2ee79 100644 (file)
@@ -428,12 +428,11 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev)
 
 #endif /* CONFIG_ISA_ARCV2 */
 
-void arc_cpu_pmu_irq_init(void)
+static void arc_cpu_pmu_irq_init(void *data)
 {
-       struct arc_pmu_cpu *pmu_cpu = this_cpu_ptr(&arc_pmu_cpu);
+       int irq = *(int *)data;
 
-       arc_request_percpu_irq(arc_pmu->irq, smp_processor_id(), arc_pmu_intr,
-                              "ARC perf counters", pmu_cpu);
+       enable_percpu_irq(irq, IRQ_TYPE_NONE);
 
        /* Clear all pending interrupt flags */
        write_aux_reg(ARC_REG_PCT_INT_ACT, 0xffffffff);
@@ -515,7 +514,6 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
 
        if (has_interrupts) {
                int irq = platform_get_irq(pdev, 0);
-               unsigned long flags;
 
                if (irq < 0) {
                        pr_err("Cannot get IRQ number for the platform\n");
@@ -524,24 +522,12 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
 
                arc_pmu->irq = irq;
 
-               /*
-                * arc_cpu_pmu_irq_init() needs to be called on all cores for
-                * their respective local PMU.
-                * However we use opencoded on_each_cpu() to ensure it is called
-                * on core0 first, so that arc_request_percpu_irq() sets up
-                * AUTOEN etc. Otherwise enable_percpu_irq() fails to enable
-                * perf IRQ on non master cores.
-                * see arc_request_percpu_irq()
-                */
-               preempt_disable();
-               local_irq_save(flags);
-               arc_cpu_pmu_irq_init();
-               local_irq_restore(flags);
-               smp_call_function((smp_call_func_t)arc_cpu_pmu_irq_init, 0, 1);
-               preempt_enable();
-
-               /* Clean all pending interrupt flags */
-               write_aux_reg(ARC_REG_PCT_INT_ACT, 0xffffffff);
+               /* intc map function ensures irq_set_percpu_devid() called */
+               request_percpu_irq(irq, arc_pmu_intr, "ARC perf counters",
+                                  this_cpu_ptr(&arc_pmu_cpu));
+
+               on_each_cpu(arc_cpu_pmu_irq_init, &irq, 1);
+
        } else
                arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
 
index c33e77c0ad3e9eb60367b6c2510c4e35c60d3b52..e1b87444ea9a0740b9651ad6b68fd39f701121a0 100644 (file)
@@ -429,7 +429,6 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
        arc_unwind_init();
-       arc_unwind_setup();
 }
 
 static int __init customize_machine(void)
index 580587805fa302d0d28f7adc89434b920b3be651..ef6e9e15b82abf72d946ab45c3e20096854605c5 100644 (file)
@@ -132,11 +132,11 @@ void start_kernel_secondary(void)
        pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
 
        /* Some SMP H/w setup - for each cpu */
-       if (plat_smp_ops.init_irq_cpu)
-               plat_smp_ops.init_irq_cpu(cpu);
+       if (plat_smp_ops.init_per_cpu)
+               plat_smp_ops.init_per_cpu(cpu);
 
-       if (machine_desc->init_cpu_smp)
-               machine_desc->init_cpu_smp(cpu);
+       if (machine_desc->init_per_cpu)
+               machine_desc->init_per_cpu(cpu);
 
        arc_local_timer_setup();
 
index 7352475451f6c3798885c97b04c11ddd53146990..5eb707640e9c48c9939c3fcfd0022f8cfc897684 100644 (file)
@@ -170,6 +170,23 @@ static struct unwind_table *find_table(unsigned long pc)
 
 static unsigned long read_pointer(const u8 **pLoc,
                                  const void *end, signed ptrType);
+static void init_unwind_hdr(struct unwind_table *table,
+                           void *(*alloc) (unsigned long));
+
+/*
+ * wrappers for header alloc (vs. calling one vs. other at call site)
+ * to elide section mismatches warnings
+ */
+static void *__init unw_hdr_alloc_early(unsigned long sz)
+{
+       return __alloc_bootmem_nopanic(sz, sizeof(unsigned int),
+                                      MAX_DMA_ADDRESS);
+}
+
+static void *unw_hdr_alloc(unsigned long sz)
+{
+       return kmalloc(sz, GFP_KERNEL);
+}
 
 static void init_unwind_table(struct unwind_table *table, const char *name,
                              const void *core_start, unsigned long core_size,
@@ -209,6 +226,8 @@ void __init arc_unwind_init(void)
                          __start_unwind, __end_unwind - __start_unwind,
                          NULL, 0);
          /*__start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);*/
+
+       init_unwind_hdr(&root_table, unw_hdr_alloc_early);
 }
 
 static const u32 bad_cie, not_fde;
@@ -241,8 +260,8 @@ static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
        e2->fde = v;
 }
 
-static void __init setup_unwind_table(struct unwind_table *table,
-                                     void *(*alloc) (unsigned long))
+static void init_unwind_hdr(struct unwind_table *table,
+                           void *(*alloc) (unsigned long))
 {
        const u8 *ptr;
        unsigned long tableSize = table->size, hdrSize;
@@ -277,10 +296,10 @@ static void __init setup_unwind_table(struct unwind_table *table,
                if (cie == &not_fde)
                        continue;
                if (cie == NULL || cie == &bad_cie)
-                       return;
+                       goto ret_err;
                ptrType = fde_pointer_type(cie);
                if (ptrType < 0)
-                       return;
+                       goto ret_err;
 
                ptr = (const u8 *)(fde + 2);
                if (!read_pointer(&ptr, (const u8 *)(fde + 1) + *fde,
@@ -296,13 +315,15 @@ static void __init setup_unwind_table(struct unwind_table *table,
        }
 
        if (tableSize || !n)
-               return;
+               goto ret_err;
 
        hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
            + 2 * n * sizeof(unsigned long);
+
        header = alloc(hdrSize);
        if (!header)
-               return;
+               goto ret_err;
+
        header->version = 1;
        header->eh_frame_ptr_enc = DW_EH_PE_abs | DW_EH_PE_native;
        header->fde_count_enc = DW_EH_PE_abs | DW_EH_PE_data4;
@@ -340,18 +361,10 @@ static void __init setup_unwind_table(struct unwind_table *table,
        table->hdrsz = hdrSize;
        smp_wmb();
        table->header = (const void *)header;
-}
-
-static void *__init balloc(unsigned long sz)
-{
-       return __alloc_bootmem_nopanic(sz,
-                                      sizeof(unsigned int),
-                                      __pa(MAX_DMA_ADDRESS));
-}
+       return;
 
-void __init arc_unwind_setup(void)
-{
-       setup_unwind_table(&root_table, balloc);
+ret_err:
+       panic("Attention !!! Dwarf FDE parsing errors\n");;
 }
 
 #ifdef CONFIG_MODULES
@@ -377,6 +390,8 @@ void *unwind_add_table(struct module *module, const void *table_start,
                          table_start, table_size,
                          NULL, 0);
 
+       init_unwind_hdr(table, unw_hdr_alloc);
+
 #ifdef UNWIND_DEBUG
        unw_debug("Table added for [%s] %lx %lx\n",
                module->name, table->core.pc, table->core.range);
@@ -439,6 +454,7 @@ void unwind_remove_table(void *handle, int init_only)
        info.init_only = init_only;
 
        unlink_table(&info); /* XXX: SMP */
+       kfree(table->header);
        kfree(table);
 }
 
@@ -588,9 +604,6 @@ static signed fde_pointer_type(const u32 *cie)
        const u8 *ptr = (const u8 *)(cie + 2);
        unsigned version = *ptr;
 
-       if (version != 1)
-               return -1;      /* unsupported */
-
        if (*++ptr) {
                const char *aug;
                const u8 *end = (const u8 *)(cie + 1) + *cie;
@@ -1002,9 +1015,7 @@ int arc_unwind(struct unwind_frame_info *frame)
                ptr = (const u8 *)(cie + 2);
                end = (const u8 *)(cie + 1) + *cie;
                frame->call_frame = 1;
-               if ((state.version = *ptr) != 1)
-                       cie = NULL;     /* unsupported version */
-               else if (*++ptr) {
+               if (*++ptr) {
                        /* check if augmentation size is first (thus present) */
                        if (*ptr == 'z') {
                                while (++ptr < end && *ptr) {
index 065ee6bfa82a2463ee60c790f08c5b60382715f3..92dd92cad7f92db32f9ecc1b73992e1ea0a5f74d 100644 (file)
@@ -111,7 +111,7 @@ void __kunmap_atomic(void *kv)
 }
 EXPORT_SYMBOL(__kunmap_atomic);
 
-noinline pte_t *alloc_kmap_pgtable(unsigned long kvaddr)
+static noinline pte_t * __init alloc_kmap_pgtable(unsigned long kvaddr)
 {
        pgd_t *pgd_k;
        pud_t *pud_k;
@@ -127,7 +127,7 @@ noinline pte_t *alloc_kmap_pgtable(unsigned long kvaddr)
        return pte_k;
 }
 
-void kmap_init(void)
+void __init kmap_init(void)
 {
        /* Due to recursive include hell, we can't do this in processor.h */
        BUILD_BUG_ON(PAGE_OFFSET < (VMALLOC_END + FIXMAP_SIZE + PKMAP_SIZE));
index a9305b5a2cd4ba091f7ae18914f6ef5e64d5236c..7d2c4fbf4f22eb1402bc666c077c652c40f38361 100644 (file)
@@ -51,7 +51,9 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
        int in_use = 0;
 
        if (!low_mem_sz) {
-               BUG_ON(base != low_mem_start);
+               if (base != low_mem_start)
+                       panic("CONFIG_LINUX_LINK_BASE != DT memory { }");
+
                low_mem_sz = size;
                in_use = 1;
        } else {
index 58adf176425a69fc48d16731973f93827b080bab..a51834e1dd2789ed0bfeed69b2dbddc08aa946fc 100644 (file)
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
-       phy-mode = "rgmii";
+       phy-mode = "rgmii-id";
        phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
        status = "okay";
 };
index 7b31fdb79ced5cbac2eecff792fa8d56b1a9a010..dc0cebfe22d7b9a8f0500e1313c67ede2718234d 100644 (file)
@@ -94,7 +94,7 @@
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
-       phy-mode = "rgmii";
+       phy-mode = "rgmii-id";
        phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
index 1b66328a84987a1040b0406e1b4dfe29a87707ed..18cd4114a23e85a82f724c3b8773c04399826129 100644 (file)
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
-       phy-mode = "rgmii";
+       phy-mode = "rgmii-id";
        phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
index 7c51839ff93467d209e0f3809b3ed9e8bc541c54..eea90f37bbb8c236ebc97e2e1c90b439e4aed2ed 100644 (file)
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
-       phy-mode = "rgmii";
+       phy-mode = "rgmii-id";
        phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
index 929e0b37bd9e542e252be1159e6e588dd34b94e1..6c11a2ae35ef98b0f2adcb218d20543cead8f399 100644 (file)
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
-       phy-mode = "rgmii";
+       phy-mode = "rgmii-id";
        phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
index 8263fc18a7d95ff88b470ae57fd5e2e89036f99f..d354d406954da437071db41de61e349a48644802 100644 (file)
 &clks {
        assigned-clocks = <&clks IMX6QDL_PLL4_BYPASS_SRC>,
                          <&clks IMX6QDL_PLL4_BYPASS>,
-                         <&clks IMX6QDL_CLK_PLL4_POST_DIV>,
                          <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
-                         <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+                         <&clks IMX6QDL_CLK_LDB_DI1_SEL>,
+                         <&clks IMX6QDL_CLK_PLL4_POST_DIV>;
        assigned-clock-parents = <&clks IMX6QDL_CLK_LVDS2_IN>,
                                 <&clks IMX6QDL_PLL4_BYPASS_SRC>,
                                 <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
                                 <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
-       assigned-clock-rates = <0>, <0>, <24576000>;
+       assigned-clock-rates = <0>, <0>, <0>, <0>, <24576000>;
 };
 
 &ecspi1 {
index 1a78f013f37ab8e2ee4de5361dc16bdeec2b2516..b75f7b2b7c4ac9e0aca7c4c44e3f1b8e2bd09c28 100644 (file)
        };
 };
 
+&uart3 {
+       interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
+                              &omap4_pmx_core OMAP4_UART3_RX>;
+};
index 2d4250b1faf80040e3e6c3477fe64b7431141627..68b479b8772c6f3eadc16f2ad6c3d33e35d39c5f 100644 (file)
@@ -83,6 +83,7 @@
                reg = <0x5d>;
                interrupt-parent = <&pio>;
                interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>; /* PA3 */
+               touchscreen-swapped-x-y;
        };
 };
 
index 40c23a0b7cfc2adf8517e28ac51b0078423a0c61..ec1aa64ded681a1a4f834343b3fc45d0c4946819 100644 (file)
 
        /* CPU DFLL clock */
        clock@0,70110000 {
-               status = "okay";
+               status = "disabled";
                vdd-cpu-supply = <&vdd_cpu>;
                nvidia,i2c-fs-rate = <400000>;
        };
index 4b4371db5799cc8c5d726281e0834277304404f5..0517f0c1581a71091539c5c1abe47473f4b789ef 100644 (file)
@@ -65,6 +65,8 @@ config SOC_AM43XX
        select MACH_OMAP_GENERIC
        select MIGHT_HAVE_CACHE_L2X0
        select HAVE_ARM_SCU
+       select GENERIC_CLOCKEVENTS_BROADCAST
+       select HAVE_ARM_TWD
 
 config SOC_DRA7XX
        bool "TI DRA7XX"
index b18ebbefae09577e20b19e53167aca5ef11b8d86..f86692dbcfd56efce7250b3a659891ad57a45725 100644 (file)
@@ -320,6 +320,12 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
        return r;
 }
 
+#if !defined(CONFIG_SMP) && defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
+void tick_broadcast(const struct cpumask *mask)
+{
+}
+#endif
+
 static void __init omap2_gp_clockevent_init(int gptimer_id,
                                                const char *fck_source,
                                                const char *property)
index 5305d694ffe52010f19a110fd072341a44e4ae85..095ecafe6bd3525444c27812937e2d085bf69b2a 100644 (file)
@@ -599,7 +599,7 @@ extern void __put_user_unknown(void);
  * On error, the variable @x is set to zero.
  */
 #define __get_user_unaligned(x,ptr) \
-       __get_user__unalignednocheck((x),(ptr),sizeof(*(ptr)))
+       __get_user_unaligned_nocheck((x),(ptr),sizeof(*(ptr)))
 
 /*
  * Yuck.  We need two variants, one for 64bit operation and one
@@ -620,8 +620,8 @@ extern void __get_user_unaligned_unknown(void);
 do {                                                                   \
        switch (size) {                                                 \
        case 1: __get_data_asm(val, "lb", ptr); break;                  \
-       case 2: __get_user_unaligned_asm(val, "ulh", ptr); break;       \
-       case 4: __get_user_unaligned_asm(val, "ulw", ptr); break;       \
+       case 2: __get_data_unaligned_asm(val, "ulh", ptr); break;       \
+       case 4: __get_data_unaligned_asm(val, "ulw", ptr); break;       \
        case 8: __GET_USER_UNALIGNED_DW(val, ptr); break;               \
        default: __get_user_unaligned_unknown(); break;                 \
        }                                                               \
@@ -1122,9 +1122,15 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n);
        __cu_to = (to);                                                 \
        __cu_from = (from);                                             \
        __cu_len = (n);                                                 \
-       might_fault();                                                  \
-       __cu_len = __invoke_copy_from_user(__cu_to, __cu_from,          \
-                                          __cu_len);                   \
+       if (eva_kernel_access()) {                                      \
+               __cu_len = __invoke_copy_from_kernel(__cu_to,           \
+                                                    __cu_from,         \
+                                                    __cu_len);         \
+       } else {                                                        \
+               might_fault();                                          \
+               __cu_len = __invoke_copy_from_user(__cu_to, __cu_from,  \
+                                                  __cu_len);           \
+       }                                                               \
        __cu_len;                                                       \
 })
 
@@ -1229,16 +1235,28 @@ __clear_user(void __user *addr, __kernel_size_t size)
 {
        __kernel_size_t res;
 
-       might_fault();
-       __asm__ __volatile__(
-               "move\t$4, %1\n\t"
-               "move\t$5, $0\n\t"
-               "move\t$6, %2\n\t"
-               __MODULE_JAL(__bzero)
-               "move\t%0, $6"
-               : "=r" (res)
-               : "r" (addr), "r" (size)
-               : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+       if (eva_kernel_access()) {
+               __asm__ __volatile__(
+                       "move\t$4, %1\n\t"
+                       "move\t$5, $0\n\t"
+                       "move\t$6, %2\n\t"
+                       __MODULE_JAL(__bzero_kernel)
+                       "move\t%0, $6"
+                       : "=r" (res)
+                       : "r" (addr), "r" (size)
+                       : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+       } else {
+               might_fault();
+               __asm__ __volatile__(
+                       "move\t$4, %1\n\t"
+                       "move\t$5, $0\n\t"
+                       "move\t$6, %2\n\t"
+                       __MODULE_JAL(__bzero)
+                       "move\t%0, $6"
+                       : "=r" (res)
+                       : "r" (addr), "r" (size)
+                       : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+       }
 
        return res;
 }
@@ -1384,7 +1402,7 @@ static inline long strlen_user(const char __user *s)
                might_fault();
                __asm__ __volatile__(
                        "move\t$4, %1\n\t"
-                       __MODULE_JAL(__strlen_kernel_asm)
+                       __MODULE_JAL(__strlen_user_asm)
                        "move\t%0, $2"
                        : "=r" (res)
                        : "r" (s)
index 8fd5a276cad23493f6500d0f4b01515ee20062f5..ac81edd44563119dbf6cf6fa0c9154afb9c47b98 100644 (file)
@@ -257,7 +257,6 @@ LEAF(mips_cps_core_init)
        has_mt  t0, 3f
 
        .set    push
-       .set    mips64r2
        .set    mt
 
        /* Only allow 1 TC per VPE to execute... */
@@ -376,7 +375,6 @@ LEAF(mips_cps_boot_vpes)
         nop
 
        .set    push
-       .set    mips64r2
        .set    mt
 
 1:     /* Enter VPE configuration state */
index 291af0b5c4828adaa22ff0fc065f37c6a094fd85..e2b6ab74643dba93b403dbba2dcfb4eced3e6d9e 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/fpu.h>
 #include <asm/msa.h>
 
+extern void *__bzero_kernel(void *__s, size_t __count);
 extern void *__bzero(void *__s, size_t __count);
 extern long __strncpy_from_kernel_nocheck_asm(char *__to,
                                              const char *__from, long __len);
@@ -64,6 +65,7 @@ EXPORT_SYMBOL(__copy_from_user_eva);
 EXPORT_SYMBOL(__copy_in_user_eva);
 EXPORT_SYMBOL(__copy_to_user_eva);
 EXPORT_SYMBOL(__copy_user_inatomic_eva);
+EXPORT_SYMBOL(__bzero_kernel);
 #endif
 EXPORT_SYMBOL(__bzero);
 EXPORT_SYMBOL(__strncpy_from_kernel_nocheck_asm);
index b8e63fd0037547cb9939907696da7ae55d699a95..8f0019a2e5c84bcd4f439559dad479b44903269a 100644 (file)
@@ -283,6 +283,8 @@ LEAF(memset)
 1:
 #ifndef CONFIG_EVA
 FEXPORT(__bzero)
+#else
+FEXPORT(__bzero_kernel)
 #endif
        __BUILD_BZERO LEGACY_MODE
 
index dbbeccc3d714add203aae3ebb5b3a0cd1522f0ae..a245cad4372a4a84094b88eed05ba3080a146190 100644 (file)
@@ -221,7 +221,6 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 static int rt288x_pci_probe(struct platform_device *pdev)
 {
        void __iomem *io_map_base;
-       int i;
 
        rt2880_pci_base = ioremap_nocache(RT2880_PCI_BASE, PAGE_SIZE);
 
index 78b2ef49dbc7a45adc720264f66cc9922453ceb2..9d293b3e9130152af49f964e530ece27e482fd7b 100644 (file)
@@ -39,7 +39,6 @@ extern void msp_serial_setup(void);
 void msp7120_reset(void)
 {
        void *start, *end, *iptr;
-       register int i;
 
        /* Diasble all interrupts */
        local_irq_disable();
index db8f88b6a3af9cb52dcb2a2a23df94a49cc0eccd..6afa34346b8148040a84e0a54ecd7af8d7ac608c 100644 (file)
@@ -26,7 +26,7 @@ static inline void kb_wait(void)
 /* XXX This ends up at the ARC firmware prompt ...  */
 void sni_machine_restart(char *command)
 {
-       int i, j;
+       int i;
 
        /* This does a normal via the keyboard controller like a PC.
           We can do that easier ...  */
index ef5f348f386a1ec4c5aef0a566a334a40e8f763b..018f8c7b94f2ac9f7db90646317dc07e7c9d3d48 100644 (file)
@@ -26,8 +26,8 @@ aflags-vdso := $(ccflags-vdso) \
 # the comments on that file.
 #
 ifndef CONFIG_CPU_MIPSR6
-  ifeq ($(call ld-ifversion, -gt, 22400000, y),)
-    $(warning MIPS VDSO requires binutils > 2.24)
+  ifeq ($(call ld-ifversion, -lt, 22500000, y),)
+    $(warning MIPS VDSO requires binutils >= 2.25)
     obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y))
     ccflags-vdso += -DDISABLE_MIPS_VDSO
   endif
index dc1ea796fd605c257c7ce1196a63773a3e3e7987..2264f68f3c2f9716030cb8fab53487f6db22e667 100644 (file)
@@ -435,6 +435,55 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall)
                regs->gr[28]);
 }
 
+/*
+ * Check how the syscall number gets loaded into %r20 within
+ * the delay branch in userspace and adjust as needed.
+ */
+
+static void check_syscallno_in_delay_branch(struct pt_regs *regs)
+{
+       u32 opcode, source_reg;
+       u32 __user *uaddr;
+       int err;
+
+       /* Usually we don't have to restore %r20 (the system call number)
+        * because it gets loaded in the delay slot of the branch external
+        * instruction via the ldi instruction.
+        * In some cases a register-to-register copy instruction might have
+        * been used instead, in which case we need to copy the syscall
+        * number into the source register before returning to userspace.
+        */
+
+       /* A syscall is just a branch, so all we have to do is fiddle the
+        * return pointer so that the ble instruction gets executed again.
+        */
+       regs->gr[31] -= 8; /* delayed branching */
+
+       /* Get assembler opcode of code in delay branch */
+       uaddr = (unsigned int *) ((regs->gr[31] & ~3) + 4);
+       err = get_user(opcode, uaddr);
+       if (err)
+               return;
+
+       /* Check if delay branch uses "ldi int,%r20" */
+       if ((opcode & 0xffff0000) == 0x34140000)
+               return; /* everything ok, just return */
+
+       /* Check if delay branch uses "nop" */
+       if (opcode == INSN_NOP)
+               return;
+
+       /* Check if delay branch uses "copy %rX,%r20" */
+       if ((opcode & 0xffe0ffff) == 0x08000254) {
+               source_reg = (opcode >> 16) & 31;
+               regs->gr[source_reg] = regs->gr[20];
+               return;
+       }
+
+       pr_warn("syscall restart: %s (pid %d): unexpected opcode 0x%08x\n",
+               current->comm, task_pid_nr(current), opcode);
+}
+
 static inline void
 syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
 {
@@ -457,10 +506,7 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
                }
                /* fallthrough */
        case -ERESTARTNOINTR:
-               /* A syscall is just a branch, so all
-                * we have to do is fiddle the return pointer.
-                */
-               regs->gr[31] -= 8; /* delayed branching */
+               check_syscallno_in_delay_branch(regs);
                break;
        }
 }
@@ -510,15 +556,9 @@ insert_restart_trampoline(struct pt_regs *regs)
        }
        case -ERESTARTNOHAND:
        case -ERESTARTSYS:
-       case -ERESTARTNOINTR: {
-               /* Hooray for delayed branching.  We don't
-                * have to restore %r20 (the system call
-                * number) because it gets loaded in the delay
-                * slot of the branch external instruction.
-                */
-               regs->gr[31] -= 8;
+       case -ERESTARTNOINTR:
+               check_syscallno_in_delay_branch(regs);
                return;
-       }
        default:
                break;
        }
index f2b0b1b0c72acf49373310288fcb330d726740e7..5654ece02c0db5ee41da441c30d8a2c5f1cdcbc4 100644 (file)
@@ -370,16 +370,16 @@ COMPAT_SYS(execveat)
 PPC64ONLY(switch_endian)
 SYSCALL_SPU(userfaultfd)
 SYSCALL_SPU(membarrier)
-SYSCALL(semop)
-SYSCALL(semget)
-COMPAT_SYS(semctl)
-COMPAT_SYS(semtimedop)
-COMPAT_SYS(msgsnd)
-COMPAT_SYS(msgrcv)
-SYSCALL(msgget)
-COMPAT_SYS(msgctl)
-COMPAT_SYS(shmat)
-SYSCALL(shmdt)
-SYSCALL(shmget)
-COMPAT_SYS(shmctl)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
 SYSCALL(mlock2)
index 1effea5193d6861cb0074a5c682965b4e4f6a13e..12a05652377a28799a89ae59e3d38a7ddeaade92 100644 (file)
 #define __NR_switch_endian     363
 #define __NR_userfaultfd       364
 #define __NR_membarrier                365
-#define __NR_semop             366
-#define __NR_semget            367
-#define __NR_semctl            368
-#define __NR_semtimedop                369
-#define __NR_msgsnd            370
-#define __NR_msgrcv            371
-#define __NR_msgget            372
-#define __NR_msgctl            373
-#define __NR_shmat             374
-#define __NR_shmdt             375
-#define __NR_shmget            376
-#define __NR_shmctl            377
 #define __NR_mlock2            378
 
 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
index 54b45b73195f912688ec4afe8e9fb4c9c3d5723c..a7352b59e6f9b5c74f37556e6858c9ac9c5bb30b 100644 (file)
@@ -224,6 +224,12 @@ static void kvmppc_core_vcpu_put_hv(struct kvm_vcpu *vcpu)
 
 static void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr)
 {
+       /*
+        * Check for illegal transactional state bit combination
+        * and if we find it, force the TS field to a safe state.
+        */
+       if ((msr & MSR_TS_MASK) == MSR_TS_MASK)
+               msr &= ~MSR_TS_MASK;
        vcpu->arch.shregs.msr = msr;
        kvmppc_end_cede(vcpu);
 }
index 0a00e2aed3935ca48052565d784317bda8edbf1f..e505223b4ec5ed2d82bcb08b2e718a6b64601f18 100644 (file)
@@ -83,7 +83,19 @@ static void opal_event_unmask(struct irq_data *d)
        set_bit(d->hwirq, &opal_event_irqchip.mask);
 
        opal_poll_events(&events);
-       opal_handle_events(be64_to_cpu(events));
+       last_outstanding_events = be64_to_cpu(events);
+
+       /*
+        * We can't just handle the events now with opal_handle_events().
+        * If we did we would deadlock when opal_event_unmask() is called from
+        * handle_level_irq() with the irq descriptor lock held, because
+        * calling opal_handle_events() would call generic_handle_irq() and
+        * then handle_level_irq() which would try to take the descriptor lock
+        * again. Instead queue the events for later.
+        */
+       if (last_outstanding_events & opal_event_irqchip.mask)
+               /* Need to retrigger the interrupt */
+               irq_work_queue(&opal_event_irq_work);
 }
 
 static int opal_event_set_type(struct irq_data *d, unsigned int flow_type)
index 4296d55e88f30afa7cb91fd54d06e6b2a532d577..57cffb80bc36a85d975dc993235c02efda1d7be8 100644 (file)
@@ -278,7 +278,7 @@ static void opal_handle_message(void)
 
        /* Sanity check */
        if (type >= OPAL_MSG_TYPE_MAX) {
-               pr_warning("%s: Unknown message type: %u\n", __func__, type);
+               pr_warn_once("%s: Unknown message type: %u\n", __func__, type);
                return;
        }
        opal_message_do_notify(type, (void *)&msg);
index 8140d10c67850902d9f60c967000dff7bdcd26a7..6e72961608f0d42f800a4f57b15d08c8456a38ab 100644 (file)
@@ -1920,16 +1920,23 @@ static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
                        }
                        if (separator)
                                ptr += sprintf(ptr, "%c", separator);
+                       /*
+                        * Use four '%' characters below because of the
+                        * following two conversions:
+                        *
+                        *  1) sprintf: %%%%r -> %%r
+                        *  2) printk : %%r   -> %r
+                        */
                        if (operand->flags & OPERAND_GPR)
-                               ptr += sprintf(ptr, "%%r%i", value);
+                               ptr += sprintf(ptr, "%%%%r%i", value);
                        else if (operand->flags & OPERAND_FPR)
-                               ptr += sprintf(ptr, "%%f%i", value);
+                               ptr += sprintf(ptr, "%%%%f%i", value);
                        else if (operand->flags & OPERAND_AR)
-                               ptr += sprintf(ptr, "%%a%i", value);
+                               ptr += sprintf(ptr, "%%%%a%i", value);
                        else if (operand->flags & OPERAND_CR)
-                               ptr += sprintf(ptr, "%%c%i", value);
+                               ptr += sprintf(ptr, "%%%%c%i", value);
                        else if (operand->flags & OPERAND_VR)
-                               ptr += sprintf(ptr, "%%v%i", value);
+                               ptr += sprintf(ptr, "%%%%v%i", value);
                        else if (operand->flags & OPERAND_PCREL)
                                ptr += sprintf(ptr, "%lx", (signed int) value
                                                                      + addr);
index 370ca1e71ffbc8dc2fb4cd9567b44f95cf61eee6..93310837c2dfaa27ce384a32d2e7cec3c75c15fa 100644 (file)
@@ -95,6 +95,7 @@
  * really available.  So we simply advertise only "crypto" support.
  */
 #define HWCAP_SPARC_CRYPTO     0x04000000 /* CRYPTO insns available */
+#define HWCAP_SPARC_ADI                0x08000000 /* ADI available */
 
 #define CORE_DUMP_USE_REGSET
 
index efe9479f837bb50d289106cd22128292dd19ef5f..f31a124a84975938648feb14302ee1e62dd46dee 100644 (file)
 #define __NR_bpf               349
 #define __NR_execveat          350
 #define __NR_membarrier                351
+#define __NR_userfaultfd       352
 
-#define NR_syscalls            352
+#define NR_syscalls            353
 
 /* Bitmask values returned from kern_features system call.  */
 #define KERN_FEATURE_MIXED_MODE_STACK  0x00000001
index 3d61fcae7ee38beaabe1b6f66bbdd781c43f1353..f2d30cab5b3f388fa9b446cf5b12afda92fa0a9d 100644 (file)
@@ -946,6 +946,12 @@ ENTRY(__retl_one)
         mov    1, %o0
 ENDPROC(__retl_one)
 
+ENTRY(__retl_one_fp)
+       VISExitHalf
+       retl
+        mov    1, %o0
+ENDPROC(__retl_one_fp)
+
 ENTRY(__ret_one_asi)
        wr      %g0, ASI_AIUS, %asi
        ret
@@ -958,6 +964,13 @@ ENTRY(__retl_one_asi)
         mov    1, %o0
 ENDPROC(__retl_one_asi)
 
+ENTRY(__retl_one_asi_fp)
+       wr      %g0, ASI_AIUS, %asi
+       VISExitHalf
+       retl
+        mov    1, %o0
+ENDPROC(__retl_one_asi_fp)
+
 ENTRY(__retl_o1)
        retl
         mov    %o1, %o0
index 3091267c5cc3d30dba854f152ff8d9bbc06c65a2..6596f66ce1126fa487b7ce8eec19ef17dc4912e7 100644 (file)
@@ -1828,11 +1828,18 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry,
 void
 perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
 {
+       u64 saved_fault_address = current_thread_info()->fault_address;
+       u8 saved_fault_code = get_thread_fault_code();
+       mm_segment_t old_fs;
+
        perf_callchain_store(entry, regs->tpc);
 
        if (!current->mm)
                return;
 
+       old_fs = get_fs();
+       set_fs(USER_DS);
+
        flushw_user();
 
        pagefault_disable();
@@ -1843,4 +1850,8 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
                perf_callchain_user_64(entry, regs);
 
        pagefault_enable();
+
+       set_fs(old_fs);
+       set_thread_fault_code(saved_fault_code);
+       current_thread_info()->fault_address = saved_fault_address;
 }
index 39f0c662f4c81dcdf3050926a5a9525d352933a3..d08bdaffdbfccbafc9b3d67c30267fe397eb917f 100644 (file)
@@ -73,7 +73,13 @@ rtrap_nmi:   ldx                     [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
                andn                    %l1, %l4, %l1
                srl                     %l4, 20, %l4
                ba,pt                   %xcc, rtrap_no_irq_enable
-                wrpr                   %l4, %pil
+               nop
+               /* Do not actually set the %pil here.  We will do that
+                * below after we clear PSTATE_IE in the %pstate register.
+                * If we re-enable interrupts here, we can recurse down
+                * the hardirq stack potentially endlessly, causing a
+                * stack overflow.
+                */
 
                .align                  64
                .globl                  rtrap_irq, rtrap, irqsz_patchme, rtrap_xcall
index f7b261749383b4992300ba4418b1d16ef7251360..f3185e2b028b86886a2a185faee9d99fa5c5c47f 100644 (file)
@@ -380,7 +380,8 @@ static const char *hwcaps[] = {
         */
        "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2",
        "ASIBlkInit", "fmaf", "vis3", "hpc", "random", "trans", "fjfmau",
-       "ima", "cspare", "pause", "cbcond",
+       "ima", "cspare", "pause", "cbcond", NULL /*reserved for crypto */,
+       "adp",
 };
 
 static const char *crypto_hwcaps[] = {
@@ -396,7 +397,7 @@ void cpucap_info(struct seq_file *m)
        seq_puts(m, "cpucaps\t\t: ");
        for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
                unsigned long bit = 1UL << i;
-               if (caps & bit) {
+               if (hwcaps[i] && (caps & bit)) {
                        seq_printf(m, "%s%s",
                                   printed ? "," : "", hwcaps[i]);
                        printed++;
@@ -450,7 +451,7 @@ static void __init report_hwcaps(unsigned long caps)
 
        for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
                unsigned long bit = 1UL << i;
-               if (caps & bit)
+               if (hwcaps[i] && (caps & bit))
                        report_one_hwcap(&printed, hwcaps[i]);
        }
        if (caps & HWCAP_SPARC_CRYPTO)
@@ -485,7 +486,7 @@ static unsigned long __init mdesc_cpu_hwcap_list(void)
                for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
                        unsigned long bit = 1UL << i;
 
-                       if (!strcmp(prop, hwcaps[i])) {
+                       if (hwcaps[i] && !strcmp(prop, hwcaps[i])) {
                                caps |= bit;
                                break;
                        }
index cc23b62b6e38a858c7e077c6b2c0757a63803b3d..78e80293cb6dff900aac7acc8d1d2b38de01ea26 100644 (file)
@@ -87,4 +87,4 @@ sys_call_table:
 /*335*/        .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
 /*340*/        .long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
 /*345*/        .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
-/*350*/        .long sys_execveat, sys_membarrier
+/*350*/        .long sys_execveat, sys_membarrier, sys_userfaultfd
index f229468a747975ea7eb0dac89886747efb52f773..2549c2c3ec2f5d2cd745b1c8c0736d722320f42d 100644 (file)
@@ -88,7 +88,7 @@ sys_call_table32:
        .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev
 /*340*/        .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
        .word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
-/*350*/        .word sys32_execveat, sys_membarrier
+/*350*/        .word sys32_execveat, sys_membarrier, sys_userfaultfd
 
 #endif /* CONFIG_COMPAT */
 
@@ -168,4 +168,4 @@ sys_call_table:
        .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
 /*340*/        .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
        .word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
-/*350*/        .word sys64_execveat, sys_membarrier
+/*350*/        .word sys64_execveat, sys_membarrier, sys_userfaultfd
index 119ccb9a54f49e2ac2724650060eb7a1d70e8d9e..d5242b8c4f9495fe4241ee39de01255364e877af 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_LD_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_asi_fp;\
+       .text;                  \
+       .align 4;
+
 #ifndef ASI_AIUS
 #define ASI_AIUS       0x11
 #endif
index 7fe1ccefd9d056a104407c8d1595095c7fc5add8..4e962d993b10cdff7677f8d51e61ad877901facc 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_ST_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_asi_fp;\
+       .text;                  \
+       .align 4;
+
 #ifndef ASI_AIUS
 #define ASI_AIUS       0x11
 #endif
index 30eee6e8a81b2d45797aab304914b10571573b1a..d5f585df2f3fc345c87f04fb1a420fa766816cb5 100644 (file)
 #ifndef EX_LD
 #define EX_LD(x)       x
 #endif
+#ifndef EX_LD_FP
+#define EX_LD_FP(x)    x
+#endif
 
 #ifndef EX_ST
 #define EX_ST(x)       x
 #endif
+#ifndef EX_ST_FP
+#define EX_ST_FP(x)    x
+#endif
 
 #ifndef EX_RETVAL
 #define EX_RETVAL(x)   x
        fsrc2           %x6, %f12; \
        fsrc2           %x7, %f14;
 #define FREG_LOAD_1(base, x0) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0))
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0))
 #define FREG_LOAD_2(base, x0, x1) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0)); \
-       EX_LD(LOAD(ldd, base + 0x08, %x1));
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+       EX_LD_FP(LOAD(ldd, base + 0x08, %x1));
 #define FREG_LOAD_3(base, x0, x1, x2) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0)); \
-       EX_LD(LOAD(ldd, base + 0x08, %x1)); \
-       EX_LD(LOAD(ldd, base + 0x10, %x2));
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+       EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+       EX_LD_FP(LOAD(ldd, base + 0x10, %x2));
 #define FREG_LOAD_4(base, x0, x1, x2, x3) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0)); \
-       EX_LD(LOAD(ldd, base + 0x08, %x1)); \
-       EX_LD(LOAD(ldd, base + 0x10, %x2)); \
-       EX_LD(LOAD(ldd, base + 0x18, %x3));
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+       EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+       EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+       EX_LD_FP(LOAD(ldd, base + 0x18, %x3));
 #define FREG_LOAD_5(base, x0, x1, x2, x3, x4) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0)); \
-       EX_LD(LOAD(ldd, base + 0x08, %x1)); \
-       EX_LD(LOAD(ldd, base + 0x10, %x2)); \
-       EX_LD(LOAD(ldd, base + 0x18, %x3)); \
-       EX_LD(LOAD(ldd, base + 0x20, %x4));
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+       EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+       EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+       EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \
+       EX_LD_FP(LOAD(ldd, base + 0x20, %x4));
 #define FREG_LOAD_6(base, x0, x1, x2, x3, x4, x5) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0)); \
-       EX_LD(LOAD(ldd, base + 0x08, %x1)); \
-       EX_LD(LOAD(ldd, base + 0x10, %x2)); \
-       EX_LD(LOAD(ldd, base + 0x18, %x3)); \
-       EX_LD(LOAD(ldd, base + 0x20, %x4)); \
-       EX_LD(LOAD(ldd, base + 0x28, %x5));
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+       EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+       EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+       EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \
+       EX_LD_FP(LOAD(ldd, base + 0x20, %x4)); \
+       EX_LD_FP(LOAD(ldd, base + 0x28, %x5));
 #define FREG_LOAD_7(base, x0, x1, x2, x3, x4, x5, x6) \
-       EX_LD(LOAD(ldd, base + 0x00, %x0)); \
-       EX_LD(LOAD(ldd, base + 0x08, %x1)); \
-       EX_LD(LOAD(ldd, base + 0x10, %x2)); \
-       EX_LD(LOAD(ldd, base + 0x18, %x3)); \
-       EX_LD(LOAD(ldd, base + 0x20, %x4)); \
-       EX_LD(LOAD(ldd, base + 0x28, %x5)); \
-       EX_LD(LOAD(ldd, base + 0x30, %x6));
+       EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+       EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+       EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+       EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \
+       EX_LD_FP(LOAD(ldd, base + 0x20, %x4)); \
+       EX_LD_FP(LOAD(ldd, base + 0x28, %x5)); \
+       EX_LD_FP(LOAD(ldd, base + 0x30, %x6));
 
        .register       %g2,#scratch
        .register       %g3,#scratch
@@ -275,11 +281,11 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
         nop
        /* fall through for 0 < low bits < 8 */
 110:   sub             %o4, 64, %g2
-       EX_LD(LOAD_BLK(%g2, %f0))
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+       EX_LD_FP(LOAD_BLK(%g2, %f0))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f14, f16)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_8(f16, f18, f20, f22, f24, f26, f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -290,10 +296,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 120:   sub             %o4, 56, %g2
        FREG_LOAD_7(%g2, f0, f2, f4, f6, f8, f10, f12)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f16, f18)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_7(f18, f20, f22, f24, f26, f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -304,10 +310,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 130:   sub             %o4, 48, %g2
        FREG_LOAD_6(%g2, f0, f2, f4, f6, f8, f10)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f4, f6, f8, f10, f16, f18, f20)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_6(f20, f22, f24, f26, f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -318,10 +324,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 140:   sub             %o4, 40, %g2
        FREG_LOAD_5(%g2, f0, f2, f4, f6, f8)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f4, f6, f8, f16, f18, f20, f22)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_5(f22, f24, f26, f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -332,10 +338,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 150:   sub             %o4, 32, %g2
        FREG_LOAD_4(%g2, f0, f2, f4, f6)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f4, f6, f16, f18, f20, f22, f24)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_4(f24, f26, f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -346,10 +352,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 160:   sub             %o4, 24, %g2
        FREG_LOAD_3(%g2, f0, f2, f4)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f4, f16, f18, f20, f22, f24, f26)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_3(f26, f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -360,10 +366,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 170:   sub             %o4, 16, %g2
        FREG_LOAD_2(%g2, f0, f2)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f2, f16, f18, f20, f22, f24, f26, f28)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_2(f28, f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -374,10 +380,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
 180:   sub             %o4, 8, %g2
        FREG_LOAD_1(%g2, f0)
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
-       EX_LD(LOAD_BLK(%o4, %f16))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f16))
        FREG_FROB(f0, f16, f18, f20, f22, f24, f26, f28, f30)
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        FREG_MOVE_1(f30)
        subcc           %g1, 64, %g1
        add             %o4, 64, %o4
@@ -387,10 +393,10 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
         nop
 
 190:
-1:     EX_ST(STORE_INIT(%g0, %o4 + %g3))
+1:     EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
        subcc           %g1, 64, %g1
-       EX_LD(LOAD_BLK(%o4, %f0))
-       EX_ST(STORE_BLK(%f0, %o4 + %g3))
+       EX_LD_FP(LOAD_BLK(%o4, %f0))
+       EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
        add             %o4, 64, %o4
        bne,pt          %xcc, 1b
         LOAD(prefetch, %o4 + 64, #one_read)
index fd9f903ffa3269713dcec781a0ed93a77ae70c1b..2e8ee7ad07a9ce06129cd63c4129ccade674ab77 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_LD_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_asi_fp;\
+       .text;                  \
+       .align 4;
+
 #ifndef ASI_AIUS
 #define ASI_AIUS       0x11
 #endif
index 9744c4540a8d99f6010a859aa1ef1510f7b70827..be0bf4590df8971ddf29a81153f05de7c0ef30da 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_ST_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_asi_fp;\
+       .text;                  \
+       .align 4;
+
 #ifndef ASI_AIUS
 #define ASI_AIUS       0x11
 #endif
index 83aeeb1dffdb3b4c29293d5924cd5259e2269ce5..8e13ee1f4454ea2b6478d302a9a1048bfeb60aff 100644 (file)
 #ifndef EX_LD
 #define EX_LD(x)       x
 #endif
+#ifndef EX_LD_FP
+#define EX_LD_FP(x)    x
+#endif
 
 #ifndef EX_ST
 #define EX_ST(x)       x
 #endif
+#ifndef EX_ST_FP
+#define EX_ST_FP(x)    x
+#endif
 
 #ifndef EX_RETVAL
 #define EX_RETVAL(x)   x
@@ -210,17 +216,17 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
        sub             %o2, %o4, %o2
        alignaddr       %o1, %g0, %g1
        add             %o1, %o4, %o1
-       EX_LD(LOAD(ldd, %g1 + 0x00, %f0))
-1:     EX_LD(LOAD(ldd, %g1 + 0x08, %f2))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x00, %f0))
+1:     EX_LD_FP(LOAD(ldd, %g1 + 0x08, %f2))
        subcc           %o4, 0x40, %o4
-       EX_LD(LOAD(ldd, %g1 + 0x10, %f4))
-       EX_LD(LOAD(ldd, %g1 + 0x18, %f6))
-       EX_LD(LOAD(ldd, %g1 + 0x20, %f8))
-       EX_LD(LOAD(ldd, %g1 + 0x28, %f10))
-       EX_LD(LOAD(ldd, %g1 + 0x30, %f12))
-       EX_LD(LOAD(ldd, %g1 + 0x38, %f14))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x10, %f4))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x18, %f6))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x20, %f8))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x28, %f10))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x30, %f12))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x38, %f14))
        faligndata      %f0, %f2, %f16
-       EX_LD(LOAD(ldd, %g1 + 0x40, %f0))
+       EX_LD_FP(LOAD(ldd, %g1 + 0x40, %f0))
        faligndata      %f2, %f4, %f18
        add             %g1, 0x40, %g1
        faligndata      %f4, %f6, %f20
@@ -229,14 +235,14 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
        faligndata      %f10, %f12, %f26
        faligndata      %f12, %f14, %f28
        faligndata      %f14, %f0, %f30
-       EX_ST(STORE(std, %f16, %o0 + 0x00))
-       EX_ST(STORE(std, %f18, %o0 + 0x08))
-       EX_ST(STORE(std, %f20, %o0 + 0x10))
-       EX_ST(STORE(std, %f22, %o0 + 0x18))
-       EX_ST(STORE(std, %f24, %o0 + 0x20))
-       EX_ST(STORE(std, %f26, %o0 + 0x28))
-       EX_ST(STORE(std, %f28, %o0 + 0x30))
-       EX_ST(STORE(std, %f30, %o0 + 0x38))
+       EX_ST_FP(STORE(std, %f16, %o0 + 0x00))
+       EX_ST_FP(STORE(std, %f18, %o0 + 0x08))
+       EX_ST_FP(STORE(std, %f20, %o0 + 0x10))
+       EX_ST_FP(STORE(std, %f22, %o0 + 0x18))
+       EX_ST_FP(STORE(std, %f24, %o0 + 0x20))
+       EX_ST_FP(STORE(std, %f26, %o0 + 0x28))
+       EX_ST_FP(STORE(std, %f28, %o0 + 0x30))
+       EX_ST_FP(STORE(std, %f30, %o0 + 0x38))
        add             %o0, 0x40, %o0
        bne,pt          %icc, 1b
         LOAD(prefetch, %g1 + 0x200, #n_reads_strong)
index a6ae2ea04bf5dfbffda2884a6a46b051ae2ac2a8..ecc5692fa2b49a3acfc6a6592c6c247835417b4c 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_LD_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_fp;\
+       .text;                  \
+       .align 4;
+
 #define FUNC_NAME              ___copy_from_user
 #define LOAD(type,addr,dest)   type##a [addr] %asi, dest
 #define LOAD_BLK(addr,dest)    ldda [addr] ASI_BLK_AIUS, dest
index f4b970eeb485f838ce23dc5507a5bccd6defd348..9eea392e44d471679ba85c22867a9767b34912a5 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_ST_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_fp;\
+       .text;                  \
+       .align 4;
+
 #define FUNC_NAME              ___copy_to_user
 #define STORE(type,src,addr)   type##a src, [addr] ASI_AIUS
 #define STORE_BLK(src,addr)    stda src, [addr] ASI_BLK_AIUS
index b67142b7768e50e20fb28d5c4ed562435ab145f5..3e6209ebb7d7865fd62bb21df56dabda07fe4f5f 100644 (file)
 #ifndef EX_LD
 #define EX_LD(x)       x
 #endif
+#ifndef EX_LD_FP
+#define EX_LD_FP(x)    x
+#endif
 
 #ifndef EX_ST
 #define EX_ST(x)       x
 #endif
+#ifndef EX_ST_FP
+#define EX_ST_FP(x)    x
+#endif
 
 #ifndef EX_RETVAL
 #define EX_RETVAL(x)   x
@@ -73,8 +79,8 @@
        faligndata              %f8, %f9, %f62;
 
 #define MAIN_LOOP_CHUNK(src, dest, fdest, fsrc, len, jmptgt)   \
-       EX_LD(LOAD_BLK(%src, %fdest));                          \
-       EX_ST(STORE_BLK(%fsrc, %dest));                         \
+       EX_LD_FP(LOAD_BLK(%src, %fdest));                               \
+       EX_ST_FP(STORE_BLK(%fsrc, %dest));                              \
        add                     %src, 0x40, %src;               \
        subcc                   %len, 0x40, %len;               \
        be,pn                   %xcc, jmptgt;                   \
 
 #define DO_SYNC                        membar  #Sync;
 #define STORE_SYNC(dest, fsrc)                         \
-       EX_ST(STORE_BLK(%fsrc, %dest));                 \
+       EX_ST_FP(STORE_BLK(%fsrc, %dest));                      \
        add                     %dest, 0x40, %dest;     \
        DO_SYNC
 
 #define STORE_JUMP(dest, fsrc, target)                 \
-       EX_ST(STORE_BLK(%fsrc, %dest));                 \
+       EX_ST_FP(STORE_BLK(%fsrc, %dest));                      \
        add                     %dest, 0x40, %dest;     \
        ba,pt                   %xcc, target;           \
         nop;
        subcc                   %left, 8, %left;\
        bl,pn                   %xcc, 95f;      \
         faligndata             %f0, %f1, %f48; \
-       EX_ST(STORE(std, %f48, %dest));         \
+       EX_ST_FP(STORE(std, %f48, %dest));              \
        add                     %dest, 8, %dest;
 
 #define UNEVEN_VISCHUNK_LAST(dest, f0, f1, left)       \
@@ -160,8 +166,8 @@ FUNC_NAME:          /* %o0=dst, %o1=src, %o2=len */
         and            %g2, 0x38, %g2
 
 1:     subcc           %g1, 0x1, %g1
-       EX_LD(LOAD(ldub, %o1 + 0x00, %o3))
-       EX_ST(STORE(stb, %o3, %o1 + %GLOBAL_SPARE))
+       EX_LD_FP(LOAD(ldub, %o1 + 0x00, %o3))
+       EX_ST_FP(STORE(stb, %o3, %o1 + %GLOBAL_SPARE))
        bgu,pt          %XCC, 1b
         add            %o1, 0x1, %o1
 
@@ -172,20 +178,20 @@ FUNC_NAME:                /* %o0=dst, %o1=src, %o2=len */
        be,pt           %icc, 3f
         alignaddr      %o1, %g0, %o1
 
-       EX_LD(LOAD(ldd, %o1, %f4))
-1:     EX_LD(LOAD(ldd, %o1 + 0x8, %f6))
+       EX_LD_FP(LOAD(ldd, %o1, %f4))
+1:     EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f6))
        add             %o1, 0x8, %o1
        subcc           %g2, 0x8, %g2
        faligndata      %f4, %f6, %f0
-       EX_ST(STORE(std, %f0, %o0))
+       EX_ST_FP(STORE(std, %f0, %o0))
        be,pn           %icc, 3f
         add            %o0, 0x8, %o0
 
-       EX_LD(LOAD(ldd, %o1 + 0x8, %f4))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f4))
        add             %o1, 0x8, %o1
        subcc           %g2, 0x8, %g2
        faligndata      %f6, %f4, %f0
-       EX_ST(STORE(std, %f0, %o0))
+       EX_ST_FP(STORE(std, %f0, %o0))
        bne,pt          %icc, 1b
         add            %o0, 0x8, %o0
 
@@ -208,13 +214,13 @@ FUNC_NAME:                /* %o0=dst, %o1=src, %o2=len */
        add             %g1, %GLOBAL_SPARE, %g1
        subcc           %o2, %g3, %o2
 
-       EX_LD(LOAD_BLK(%o1, %f0))
+       EX_LD_FP(LOAD_BLK(%o1, %f0))
        add             %o1, 0x40, %o1
        add             %g1, %g3, %g1
-       EX_LD(LOAD_BLK(%o1, %f16))
+       EX_LD_FP(LOAD_BLK(%o1, %f16))
        add             %o1, 0x40, %o1
        sub             %GLOBAL_SPARE, 0x80, %GLOBAL_SPARE
-       EX_LD(LOAD_BLK(%o1, %f32))
+       EX_LD_FP(LOAD_BLK(%o1, %f32))
        add             %o1, 0x40, %o1
 
        /* There are 8 instances of the unrolled loop,
@@ -426,28 +432,28 @@ FUNC_NAME:                /* %o0=dst, %o1=src, %o2=len */
 62:    FINISH_VISCHUNK(o0, f44, f46, g3)
 63:    UNEVEN_VISCHUNK_LAST(o0, f46, f0,  g3)
 
-93:    EX_LD(LOAD(ldd, %o1, %f2))
+93:    EX_LD_FP(LOAD(ldd, %o1, %f2))
        add             %o1, 8, %o1
        subcc           %g3, 8, %g3
        faligndata      %f0, %f2, %f8
-       EX_ST(STORE(std, %f8, %o0))
+       EX_ST_FP(STORE(std, %f8, %o0))
        bl,pn           %xcc, 95f
         add            %o0, 8, %o0
-       EX_LD(LOAD(ldd, %o1, %f0))
+       EX_LD_FP(LOAD(ldd, %o1, %f0))
        add             %o1, 8, %o1
        subcc           %g3, 8, %g3
        faligndata      %f2, %f0, %f8
-       EX_ST(STORE(std, %f8, %o0))
+       EX_ST_FP(STORE(std, %f8, %o0))
        bge,pt          %xcc, 93b
         add            %o0, 8, %o0
 
 95:    brz,pt          %o2, 2f
         mov            %g1, %o1
 
-1:     EX_LD(LOAD(ldub, %o1, %o3))
+1:     EX_LD_FP(LOAD(ldub, %o1, %o3))
        add             %o1, 1, %o1
        subcc           %o2, 1, %o2
-       EX_ST(STORE(stb, %o3, %o0))
+       EX_ST_FP(STORE(stb, %o3, %o0))
        bne,pt          %xcc, 1b
         add            %o0, 1, %o0
 
index b1acd1331c338fce1a70e6a13f597509b28501a7..88ad73d86fe44b64c2313483e7490cc8ae0ee438 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_LD_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_fp;\
+       .text;                  \
+       .align 4;
+
 #define FUNC_NAME              U3copy_from_user
 #define LOAD(type,addr,dest)   type##a [addr] %asi, dest
 #define EX_RETVAL(x)           0
index ef1e493afdfa900a1b32863c2bf2995560cbe0cd..845139d7553720ce5fe98d6e30bcb11215f71e2f 100644 (file)
        .text;                  \
        .align 4;
 
+#define EX_ST_FP(x)            \
+98:    x;                      \
+       .section __ex_table,"a";\
+       .align 4;               \
+       .word 98b, __retl_one_fp;\
+       .text;                  \
+       .align 4;
+
 #define FUNC_NAME              U3copy_to_user
 #define STORE(type,src,addr)   type##a src, [addr] ASI_AIUS
 #define STORE_BLK(src,addr)    stda src, [addr] ASI_BLK_AIUS
index 7cae9cc6a204a46e535c8c651176ccc873778700..491ee69e49951fc2040640e77b896552872c8a0a 100644 (file)
 #ifndef EX_LD
 #define EX_LD(x)       x
 #endif
+#ifndef EX_LD_FP
+#define EX_LD_FP(x)    x
+#endif
 
 #ifndef EX_ST
 #define EX_ST(x)       x
 #endif
+#ifndef EX_ST_FP
+#define EX_ST_FP(x)    x
+#endif
 
 #ifndef EX_RETVAL
 #define EX_RETVAL(x)   x
@@ -120,8 +126,8 @@ FUNC_NAME:  /* %o0=dst, %o1=src, %o2=len */
         and            %g2, 0x38, %g2
 
 1:     subcc           %g1, 0x1, %g1
-       EX_LD(LOAD(ldub, %o1 + 0x00, %o3))
-       EX_ST(STORE(stb, %o3, %o1 + GLOBAL_SPARE))
+       EX_LD_FP(LOAD(ldub, %o1 + 0x00, %o3))
+       EX_ST_FP(STORE(stb, %o3, %o1 + GLOBAL_SPARE))
        bgu,pt          %XCC, 1b
         add            %o1, 0x1, %o1
 
@@ -132,20 +138,20 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
        be,pt           %icc, 3f
         alignaddr      %o1, %g0, %o1
 
-       EX_LD(LOAD(ldd, %o1, %f4))
-1:     EX_LD(LOAD(ldd, %o1 + 0x8, %f6))
+       EX_LD_FP(LOAD(ldd, %o1, %f4))
+1:     EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f6))
        add             %o1, 0x8, %o1
        subcc           %g2, 0x8, %g2
        faligndata      %f4, %f6, %f0
-       EX_ST(STORE(std, %f0, %o0))
+       EX_ST_FP(STORE(std, %f0, %o0))
        be,pn           %icc, 3f
         add            %o0, 0x8, %o0
 
-       EX_LD(LOAD(ldd, %o1 + 0x8, %f4))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f4))
        add             %o1, 0x8, %o1
        subcc           %g2, 0x8, %g2
        faligndata      %f6, %f4, %f2
-       EX_ST(STORE(std, %f2, %o0))
+       EX_ST_FP(STORE(std, %f2, %o0))
        bne,pt          %icc, 1b
         add            %o0, 0x8, %o0
 
@@ -155,25 +161,25 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
        LOAD(prefetch, %o1 + 0x080, #one_read)
        LOAD(prefetch, %o1 + 0x0c0, #one_read)
        LOAD(prefetch, %o1 + 0x100, #one_read)
-       EX_LD(LOAD(ldd, %o1 + 0x000, %f0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x000, %f0))
        LOAD(prefetch, %o1 + 0x140, #one_read)
-       EX_LD(LOAD(ldd, %o1 + 0x008, %f2))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2))
        LOAD(prefetch, %o1 + 0x180, #one_read)
-       EX_LD(LOAD(ldd, %o1 + 0x010, %f4))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4))
        LOAD(prefetch, %o1 + 0x1c0, #one_read)
        faligndata      %f0, %f2, %f16
-       EX_LD(LOAD(ldd, %o1 + 0x018, %f6))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6))
        faligndata      %f2, %f4, %f18
-       EX_LD(LOAD(ldd, %o1 + 0x020, %f8))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8))
        faligndata      %f4, %f6, %f20
-       EX_LD(LOAD(ldd, %o1 + 0x028, %f10))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10))
        faligndata      %f6, %f8, %f22
 
-       EX_LD(LOAD(ldd, %o1 + 0x030, %f12))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12))
        faligndata      %f8, %f10, %f24
-       EX_LD(LOAD(ldd, %o1 + 0x038, %f14))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14))
        faligndata      %f10, %f12, %f26
-       EX_LD(LOAD(ldd, %o1 + 0x040, %f0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0))
 
        subcc           GLOBAL_SPARE, 0x80, GLOBAL_SPARE
        add             %o1, 0x40, %o1
@@ -184,26 +190,26 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
        .align          64
 1:
-       EX_LD(LOAD(ldd, %o1 + 0x008, %f2))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2))
        faligndata      %f12, %f14, %f28
-       EX_LD(LOAD(ldd, %o1 + 0x010, %f4))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4))
        faligndata      %f14, %f0, %f30
-       EX_ST(STORE_BLK(%f16, %o0))
-       EX_LD(LOAD(ldd, %o1 + 0x018, %f6))
+       EX_ST_FP(STORE_BLK(%f16, %o0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6))
        faligndata      %f0, %f2, %f16
        add             %o0, 0x40, %o0
 
-       EX_LD(LOAD(ldd, %o1 + 0x020, %f8))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8))
        faligndata      %f2, %f4, %f18
-       EX_LD(LOAD(ldd, %o1 + 0x028, %f10))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10))
        faligndata      %f4, %f6, %f20
-       EX_LD(LOAD(ldd, %o1 + 0x030, %f12))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12))
        subcc           %o3, 0x01, %o3
        faligndata      %f6, %f8, %f22
-       EX_LD(LOAD(ldd, %o1 + 0x038, %f14))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14))
 
        faligndata      %f8, %f10, %f24
-       EX_LD(LOAD(ldd, %o1 + 0x040, %f0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0))
        LOAD(prefetch, %o1 + 0x1c0, #one_read)
        faligndata      %f10, %f12, %f26
        bg,pt           %XCC, 1b
@@ -211,29 +217,29 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
        /* Finally we copy the last full 64-byte block. */
 2:
-       EX_LD(LOAD(ldd, %o1 + 0x008, %f2))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2))
        faligndata      %f12, %f14, %f28
-       EX_LD(LOAD(ldd, %o1 + 0x010, %f4))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4))
        faligndata      %f14, %f0, %f30
-       EX_ST(STORE_BLK(%f16, %o0))
-       EX_LD(LOAD(ldd, %o1 + 0x018, %f6))
+       EX_ST_FP(STORE_BLK(%f16, %o0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6))
        faligndata      %f0, %f2, %f16
-       EX_LD(LOAD(ldd, %o1 + 0x020, %f8))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8))
        faligndata      %f2, %f4, %f18
-       EX_LD(LOAD(ldd, %o1 + 0x028, %f10))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10))
        faligndata      %f4, %f6, %f20
-       EX_LD(LOAD(ldd, %o1 + 0x030, %f12))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12))
        faligndata      %f6, %f8, %f22
-       EX_LD(LOAD(ldd, %o1 + 0x038, %f14))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14))
        faligndata      %f8, %f10, %f24
        cmp             %g1, 0
        be,pt           %XCC, 1f
         add            %o0, 0x40, %o0
-       EX_LD(LOAD(ldd, %o1 + 0x040, %f0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0))
 1:     faligndata      %f10, %f12, %f26
        faligndata      %f12, %f14, %f28
        faligndata      %f14, %f0, %f30
-       EX_ST(STORE_BLK(%f16, %o0))
+       EX_ST_FP(STORE_BLK(%f16, %o0))
        add             %o0, 0x40, %o0
        add             %o1, 0x40, %o1
        membar          #Sync
@@ -253,20 +259,20 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 
        sub             %o2, %g2, %o2
        be,a,pt         %XCC, 1f
-        EX_LD(LOAD(ldd, %o1 + 0x00, %f0))
+        EX_LD_FP(LOAD(ldd, %o1 + 0x00, %f0))
 
-1:     EX_LD(LOAD(ldd, %o1 + 0x08, %f2))
+1:     EX_LD_FP(LOAD(ldd, %o1 + 0x08, %f2))
        add             %o1, 0x8, %o1
        subcc           %g2, 0x8, %g2
        faligndata      %f0, %f2, %f8
-       EX_ST(STORE(std, %f8, %o0))
+       EX_ST_FP(STORE(std, %f8, %o0))
        be,pn           %XCC, 2f
         add            %o0, 0x8, %o0
-       EX_LD(LOAD(ldd, %o1 + 0x08, %f0))
+       EX_LD_FP(LOAD(ldd, %o1 + 0x08, %f0))
        add             %o1, 0x8, %o1
        subcc           %g2, 0x8, %g2
        faligndata      %f2, %f0, %f8
-       EX_ST(STORE(std, %f8, %o0))
+       EX_ST_FP(STORE(std, %f8, %o0))
        bne,pn          %XCC, 1b
         add            %o0, 0x8, %o0
 
index 06332cb7e7d1d79c5af04eba698ad8642c2762b5..3f5c48ddba453064ff6dbe91731d1d0c7776be53 100644 (file)
@@ -38,6 +38,14 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu)
        return best && (best->ecx & bit(X86_FEATURE_XSAVE));
 }
 
+static inline bool guest_cpuid_has_mtrr(struct kvm_vcpu *vcpu)
+{
+       struct kvm_cpuid_entry2 *best;
+
+       best = kvm_find_cpuid_entry(vcpu, 1, 0);
+       return best && (best->edx & bit(X86_FEATURE_MTRR));
+}
+
 static inline bool guest_cpuid_has_tsc_adjust(struct kvm_vcpu *vcpu)
 {
        struct kvm_cpuid_entry2 *best;
index 9e8bf13572e6dc3f95d33d24f079d63e256a3a7a..3f8c732117eccf73140fded817e1b155dfa76073 100644 (file)
@@ -120,14 +120,22 @@ static u8 mtrr_default_type(struct kvm_mtrr *mtrr_state)
        return mtrr_state->deftype & IA32_MTRR_DEF_TYPE_TYPE_MASK;
 }
 
-static u8 mtrr_disabled_type(void)
+static u8 mtrr_disabled_type(struct kvm_vcpu *vcpu)
 {
        /*
         * Intel SDM 11.11.2.2: all MTRRs are disabled when
         * IA32_MTRR_DEF_TYPE.E bit is cleared, and the UC
         * memory type is applied to all of physical memory.
+        *
+        * However, virtual machines can be run with CPUID such that
+        * there are no MTRRs.  In that case, the firmware will never
+        * enable MTRRs and it is obviously undesirable to run the
+        * guest entirely with UC memory and we use WB.
         */
-       return MTRR_TYPE_UNCACHABLE;
+       if (guest_cpuid_has_mtrr(vcpu))
+               return MTRR_TYPE_UNCACHABLE;
+       else
+               return MTRR_TYPE_WRBACK;
 }
 
 /*
@@ -267,7 +275,7 @@ static int fixed_mtrr_addr_to_seg(u64 addr)
 
        for (seg = 0; seg < seg_num; seg++) {
                mtrr_seg = &fixed_seg_table[seg];
-               if (mtrr_seg->start >= addr && addr < mtrr_seg->end)
+               if (mtrr_seg->start <= addr && addr < mtrr_seg->end)
                        return seg;
        }
 
@@ -300,7 +308,6 @@ static void var_mtrr_range(struct kvm_mtrr_range *range, u64 *start, u64 *end)
        *start = range->base & PAGE_MASK;
 
        mask = range->mask & PAGE_MASK;
-       mask |= ~0ULL << boot_cpu_data.x86_phys_bits;
 
        /* This cannot overflow because writing to the reserved bits of
         * variable MTRRs causes a #GP.
@@ -356,10 +363,14 @@ static void set_var_mtrr_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
        if (var_mtrr_range_is_valid(cur))
                list_del(&mtrr_state->var_ranges[index].node);
 
+       /* Extend the mask with all 1 bits to the left, since those
+        * bits must implicitly be 0.  The bits are then cleared
+        * when reading them.
+        */
        if (!is_mtrr_mask)
                cur->base = data;
        else
-               cur->mask = data;
+               cur->mask = data | (-1LL << cpuid_maxphyaddr(vcpu));
 
        /* add it to the list if it's enabled. */
        if (var_mtrr_range_is_valid(cur)) {
@@ -426,6 +437,8 @@ int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
                        *pdata = vcpu->arch.mtrr_state.var_ranges[index].base;
                else
                        *pdata = vcpu->arch.mtrr_state.var_ranges[index].mask;
+
+               *pdata &= (1ULL << cpuid_maxphyaddr(vcpu)) - 1;
        }
 
        return 0;
@@ -670,7 +683,7 @@ u8 kvm_mtrr_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn)
        }
 
        if (iter.mtrr_disabled)
-               return mtrr_disabled_type();
+               return mtrr_disabled_type(vcpu);
 
        /* not contained in any MTRRs. */
        if (type == -1)
index 83a1c643f9a50fd3fa0ffc041c40d9f4d25aa5b5..899c40f826dd9a5f10c57e0758153cdbb1d9f1a6 100644 (file)
@@ -3422,6 +3422,8 @@ static int handle_exit(struct kvm_vcpu *vcpu)
        struct kvm_run *kvm_run = vcpu->run;
        u32 exit_code = svm->vmcb->control.exit_code;
 
+       trace_kvm_exit(exit_code, vcpu, KVM_ISA_SVM);
+
        if (!is_cr_intercept(svm, INTERCEPT_CR0_WRITE))
                vcpu->arch.cr0 = svm->vmcb->save.cr0;
        if (npt_enabled)
@@ -3892,8 +3894,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
        vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
        vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
 
-       trace_kvm_exit(svm->vmcb->control.exit_code, vcpu, KVM_ISA_SVM);
-
        if (unlikely(svm->vmcb->control.exit_code == SVM_EXIT_NMI))
                kvm_before_handle_nmi(&svm->vcpu);
 
index af823a388c1994ba244e3ef0098f1a578408101e..44976a596fa65d2ca90421a7f7f06cfb2d0b17be 100644 (file)
@@ -2803,7 +2803,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                msr_info->data = vcpu->arch.ia32_xss;
                break;
        case MSR_TSC_AUX:
-               if (!guest_cpuid_has_rdtscp(vcpu))
+               if (!guest_cpuid_has_rdtscp(vcpu) && !msr_info->host_initiated)
                        return 1;
                /* Otherwise falls through */
        default:
@@ -2909,7 +2909,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                        clear_atomic_switch_msr(vmx, MSR_IA32_XSS);
                break;
        case MSR_TSC_AUX:
-               if (!guest_cpuid_has_rdtscp(vcpu))
+               if (!guest_cpuid_has_rdtscp(vcpu) && !msr_info->host_initiated)
                        return 1;
                /* Check reserved bit, higher 32 bits should be zero */
                if ((data >> 32) != 0)
@@ -8042,6 +8042,8 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
        u32 exit_reason = vmx->exit_reason;
        u32 vectoring_info = vmx->idt_vectoring_info;
 
+       trace_kvm_exit(exit_reason, vcpu, KVM_ISA_VMX);
+
        /*
         * Flush logged GPAs PML buffer, this will make dirty_bitmap more
         * updated. Another good is, in kvm_vm_ioctl_get_dirty_log, before
@@ -8668,7 +8670,6 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
        vmx->loaded_vmcs->launched = 1;
 
        vmx->exit_reason = vmcs_read32(VM_EXIT_REASON);
-       trace_kvm_exit(vmx->exit_reason, vcpu, KVM_ISA_VMX);
 
        /*
         * the KVM_REQ_EVENT optimization bit is only on for one entry, and if
index eed32283d22cc0cafbff75e8f2a246887d4cbb5f..7ffc224bbe4127a90ef7741f09ae94f75e17feec 100644 (file)
@@ -3572,9 +3572,11 @@ static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps)
 
 static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
 {
+       int i;
        mutex_lock(&kvm->arch.vpit->pit_state.lock);
        memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state));
-       kvm_pit_load_count(kvm, 0, ps->channels[0].count, 0);
+       for (i = 0; i < 3; i++)
+               kvm_pit_load_count(kvm, i, ps->channels[i].count, 0);
        mutex_unlock(&kvm->arch.vpit->pit_state.lock);
        return 0;
 }
@@ -3593,6 +3595,7 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
 static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
 {
        int start = 0;
+       int i;
        u32 prev_legacy, cur_legacy;
        mutex_lock(&kvm->arch.vpit->pit_state.lock);
        prev_legacy = kvm->arch.vpit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY;
@@ -3602,7 +3605,8 @@ static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
        memcpy(&kvm->arch.vpit->pit_state.channels, &ps->channels,
               sizeof(kvm->arch.vpit->pit_state.channels));
        kvm->arch.vpit->pit_state.flags = ps->flags;
-       kvm_pit_load_count(kvm, 0, kvm->arch.vpit->pit_state.channels[0].count, start);
+       for (i = 0; i < 3; i++)
+               kvm_pit_load_count(kvm, i, kvm->arch.vpit->pit_state.channels[i].count, start);
        mutex_unlock(&kvm->arch.vpit->pit_state.lock);
        return 0;
 }
@@ -6515,6 +6519,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
        if (req_immediate_exit)
                smp_send_reschedule(vcpu->cpu);
 
+       trace_kvm_entry(vcpu->vcpu_id);
+       wait_lapic_expire(vcpu);
        __kvm_guest_enter();
 
        if (unlikely(vcpu->arch.switch_db_regs)) {
@@ -6527,8 +6533,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
                vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD;
        }
 
-       trace_kvm_entry(vcpu->vcpu_id);
-       wait_lapic_expire(vcpu);
        kvm_x86_ops->run(vcpu);
 
        /*
index e5f854ce2d72404237067031a09297c8f0d3f424..14fcd01ed99293c162582438b4755a47fff59f43 100644 (file)
@@ -470,7 +470,7 @@ long sys_sigreturn(void)
        struct sigcontext __user *sc = &frame->sc;
        int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
 
-       if (copy_from_user(&set.sig[0], (void *)sc->oldmask, sizeof(set.sig[0])) ||
+       if (copy_from_user(&set.sig[0], &sc->oldmask, sizeof(set.sig[0])) ||
            copy_from_user(&set.sig[1], frame->extramask, sig_size))
                goto segfault;
 
index ac161db633885872fdebdce976d05b978e1235da..cb5e266a8bf752297eaf6fc0d822c9398239fadf 100644 (file)
@@ -2495,14 +2495,9 @@ void __init xen_init_mmu_ops(void)
 {
        x86_init.paging.pagetable_init = xen_pagetable_init;
 
-       /* Optimization - we can use the HVM one but it has no idea which
-        * VCPUs are descheduled - which means that it will needlessly IPI
-        * them. Xen knows so let it do the job.
-        */
-       if (xen_feature(XENFEAT_auto_translated_physmap)) {
-               pv_mmu_ops.flush_tlb_others = xen_flush_tlb_others;
+       if (xen_feature(XENFEAT_auto_translated_physmap))
                return;
-       }
+
        pv_mmu_ops = xen_mmu_ops;
 
        memset(dummy_mapping, 0xff, PAGE_SIZE);
index feddabdab4488c54784aa5a64067d09b50b3cb22..3705eabd7e22ee68d22c1b66d4cb1661bb108f41 100644 (file)
@@ -68,26 +68,16 @@ static void xen_pv_post_suspend(int suspend_cancelled)
 
 void xen_arch_pre_suspend(void)
 {
-       int cpu;
-
-       for_each_online_cpu(cpu)
-               xen_pmu_finish(cpu);
-
        if (xen_pv_domain())
                xen_pv_pre_suspend();
 }
 
 void xen_arch_post_suspend(int cancelled)
 {
-       int cpu;
-
        if (xen_pv_domain())
                xen_pv_post_suspend(cancelled);
        else
                xen_hvm_post_suspend(cancelled);
-
-       for_each_online_cpu(cpu)
-               xen_pmu_init(cpu);
 }
 
 static void xen_vcpu_notify_restore(void *data)
@@ -106,10 +96,20 @@ static void xen_vcpu_notify_suspend(void *data)
 
 void xen_arch_resume(void)
 {
+       int cpu;
+
        on_each_cpu(xen_vcpu_notify_restore, NULL, 1);
+
+       for_each_online_cpu(cpu)
+               xen_pmu_init(cpu);
 }
 
 void xen_arch_suspend(void)
 {
+       int cpu;
+
+       for_each_online_cpu(cpu)
+               xen_pmu_finish(cpu);
+
        on_each_cpu(xen_vcpu_notify_suspend, NULL, 1);
 }
index 3636be469fa2edfef939985135654a394d639a9b..c487b94c59e3052074f5e40c99680d0cb709b517 100644 (file)
@@ -1689,8 +1689,6 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
        struct request *req;
        unsigned int request_count = 0;
 
-       blk_queue_split(q, &bio, q->bio_split);
-
        /*
         * low level driver can indicate that it wants pages above a
         * certain limit bounced to low memory (ie for highmem, or even
@@ -1698,6 +1696,8 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
         */
        blk_queue_bounce(q, &bio);
 
+       blk_queue_split(q, &bio, q->bio_split);
+
        if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
                bio->bi_error = -EIO;
                bio_endio(bio);
index f4e02ae93f585fbb8de42c09d4d0fb32d2751887..11154a330f075dc04c0fec99299d6f5000e901be 100644 (file)
@@ -200,7 +200,8 @@ static int acpi_pss_perf_init(struct acpi_processor *pr,
                goto err_remove_sysfs_thermal;
        }
 
-       sysfs_remove_link(&pr->cdev->device.kobj, "device");
+       return 0;
+
  err_remove_sysfs_thermal:
        sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
  err_thermal_unregister:
index 167418e73445a4f69b372f9205f65ca43f525c9d..65f50eccd49b0aa4b6801912fd8d21a73f79a7b9 100644 (file)
@@ -390,6 +390,7 @@ static int pm_genpd_runtime_suspend(struct device *dev)
        struct generic_pm_domain *genpd;
        bool (*stop_ok)(struct device *__dev);
        struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
+       bool runtime_pm = pm_runtime_enabled(dev);
        ktime_t time_start;
        s64 elapsed_ns;
        int ret;
@@ -400,12 +401,19 @@ static int pm_genpd_runtime_suspend(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
+       /*
+        * A runtime PM centric subsystem/driver may re-use the runtime PM
+        * callbacks for other purposes than runtime PM. In those scenarios
+        * runtime PM is disabled. Under these circumstances, we shall skip
+        * validating/measuring the PM QoS latency.
+        */
        stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL;
-       if (stop_ok && !stop_ok(dev))
+       if (runtime_pm && stop_ok && !stop_ok(dev))
                return -EBUSY;
 
        /* Measure suspend latency. */
-       time_start = ktime_get();
+       if (runtime_pm)
+               time_start = ktime_get();
 
        ret = genpd_save_dev(genpd, dev);
        if (ret)
@@ -418,13 +426,15 @@ static int pm_genpd_runtime_suspend(struct device *dev)
        }
 
        /* Update suspend latency value if the measured time exceeds it. */
-       elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
-       if (elapsed_ns > td->suspend_latency_ns) {
-               td->suspend_latency_ns = elapsed_ns;
-               dev_dbg(dev, "suspend latency exceeded, %lld ns\n",
-                       elapsed_ns);
-               genpd->max_off_time_changed = true;
-               td->constraint_changed = true;
+       if (runtime_pm) {
+               elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
+               if (elapsed_ns > td->suspend_latency_ns) {
+                       td->suspend_latency_ns = elapsed_ns;
+                       dev_dbg(dev, "suspend latency exceeded, %lld ns\n",
+                               elapsed_ns);
+                       genpd->max_off_time_changed = true;
+                       td->constraint_changed = true;
+               }
        }
 
        /*
@@ -453,6 +463,7 @@ static int pm_genpd_runtime_resume(struct device *dev)
 {
        struct generic_pm_domain *genpd;
        struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
+       bool runtime_pm = pm_runtime_enabled(dev);
        ktime_t time_start;
        s64 elapsed_ns;
        int ret;
@@ -479,14 +490,14 @@ static int pm_genpd_runtime_resume(struct device *dev)
 
  out:
        /* Measure resume latency. */
-       if (timed)
+       if (timed && runtime_pm)
                time_start = ktime_get();
 
        genpd_start_dev(genpd, dev);
        genpd_restore_dev(genpd, dev);
 
        /* Update resume latency value if the measured time exceeds it. */
-       if (timed) {
+       if (timed && runtime_pm) {
                elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
                if (elapsed_ns > td->resume_latency_ns) {
                        td->resume_latency_ns = elapsed_ns;
index 8162475d96b55471befacf889acf8dfa28e274ea..a428e4ef71fd74ce2d569b9cfd407a7f6b0e3eb0 100644 (file)
@@ -219,6 +219,9 @@ static void end_cmd(struct nullb_cmd *cmd)
 {
        struct request_queue *q = NULL;
 
+       if (cmd->rq)
+               q = cmd->rq->q;
+
        switch (queue_mode)  {
        case NULL_Q_MQ:
                blk_mq_end_request(cmd->rq, 0);
@@ -232,9 +235,6 @@ static void end_cmd(struct nullb_cmd *cmd)
                goto free_cmd;
        }
 
-       if (cmd->rq)
-               q = cmd->rq->q;
-
        /* Restart queue if needed, as we are freeing a tag */
        if (q && !q->mq_ops && blk_queue_stopped(q)) {
                unsigned long flags;
index f9099940c2720f95874e6621b4c7e5e1e798fe2c..41fb1a917b172dc9446495d84357060847c2b569 100644 (file)
@@ -950,6 +950,8 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
                goto unmap;
 
        for (n = 0, i = 0; n < nseg; n++) {
+               uint8_t first_sect, last_sect;
+
                if ((n % SEGS_PER_INDIRECT_FRAME) == 0) {
                        /* Map indirect segments */
                        if (segments)
@@ -957,15 +959,18 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
                        segments = kmap_atomic(pages[n/SEGS_PER_INDIRECT_FRAME]->page);
                }
                i = n % SEGS_PER_INDIRECT_FRAME;
+
                pending_req->segments[n]->gref = segments[i].gref;
-               seg[n].nsec = segments[i].last_sect -
-                       segments[i].first_sect + 1;
-               seg[n].offset = (segments[i].first_sect << 9);
-               if ((segments[i].last_sect >= (XEN_PAGE_SIZE >> 9)) ||
-                   (segments[i].last_sect < segments[i].first_sect)) {
+
+               first_sect = READ_ONCE(segments[i].first_sect);
+               last_sect = READ_ONCE(segments[i].last_sect);
+               if (last_sect >= (XEN_PAGE_SIZE >> 9) || last_sect < first_sect) {
                        rc = -EINVAL;
                        goto unmap;
                }
+
+               seg[n].nsec = last_sect - first_sect + 1;
+               seg[n].offset = first_sect << 9;
                preq->nr_sects += seg[n].nsec;
        }
 
index 68e87a037b992df8c64d6894719b5b390ef1d10a..c929ae22764c9dd4345195a1542df997c5a8e29b 100644 (file)
@@ -408,8 +408,8 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst,
                                        struct blkif_x86_32_request *src)
 {
        int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
-       dst->operation = src->operation;
-       switch (src->operation) {
+       dst->operation = READ_ONCE(src->operation);
+       switch (dst->operation) {
        case BLKIF_OP_READ:
        case BLKIF_OP_WRITE:
        case BLKIF_OP_WRITE_BARRIER:
@@ -456,8 +456,8 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst,
                                        struct blkif_x86_64_request *src)
 {
        int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
-       dst->operation = src->operation;
-       switch (src->operation) {
+       dst->operation = READ_ONCE(src->operation);
+       switch (dst->operation) {
        case BLKIF_OP_READ:
        case BLKIF_OP_WRITE:
        case BLKIF_OP_WRITE_BARRIER:
index 846bc29c157dcca1bde81f288a5d323476042295..25996e2561105ac615cf4cc99c468f7a8db0f3df 100644 (file)
@@ -342,13 +342,13 @@ static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr,
 
        ret = _sunxi_rsb_run_xfer(rsb);
        if (ret)
-               goto out;
+               goto unlock;
 
        *buf = readl(rsb->regs + RSB_DATA);
 
+unlock:
        mutex_unlock(&rsb->lock);
 
-out:
        return ret;
 }
 
@@ -527,9 +527,9 @@ static int sunxi_rsb_init_device_mode(struct sunxi_rsb *rsb)
  */
 
 static const struct sunxi_rsb_addr_map sunxi_rsb_addr_maps[] = {
-       { 0x3e3, 0x2d }, /* Primary PMIC: AXP223, AXP809, AXP81X, ... */
+       { 0x3a3, 0x2d }, /* Primary PMIC: AXP223, AXP809, AXP81X, ... */
        { 0x745, 0x3a }, /* Secondary PMIC: AXP806, ... */
-       { 0xe89, 0x45 }, /* Peripheral IC: AC100, ... */
+       { 0xe89, 0x4e }, /* Peripheral IC: AC100, ... */
 };
 
 static u8 sunxi_rsb_get_rtaddr(u16 hwaddr)
index 235a1ba73d92d577bbf605f5dab9d737fe246797..b1f8a73e5a943e8fc692dfcba7f28d1e08dba4f2 100644 (file)
@@ -226,7 +226,7 @@ config ARM_TEGRA20_CPUFREQ
 
 config ARM_TEGRA124_CPUFREQ
        tristate "Tegra124 CPUFreq support"
-       depends on ARCH_TEGRA && CPUFREQ_DT
+       depends on ARCH_TEGRA && CPUFREQ_DT && REGULATOR
        default y
        help
          This adds the CPUFreq driver support for Tegra124 SOCs.
index 4d07cbd2b23cfb80ddc40fc0822ce37464991498..98fb8821382d8fc145c6bf9227b62236fdabedb1 100644 (file)
@@ -1123,7 +1123,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
                                   limits->max_sysfs_pct);
        limits->max_perf_pct = max(limits->min_policy_pct,
                                   limits->max_perf_pct);
-       limits->max_perf = round_up(limits->max_perf, 8);
+       limits->max_perf = round_up(limits->max_perf, FRAC_BITS);
 
        /* Make sure min_perf_pct <= max_perf_pct */
        limits->min_perf_pct = min(limits->max_perf_pct, limits->min_perf_pct);
index 2c3b16fd3a01fc1c521f8201bd698dab2d6d1215..de5e89b2eaaa3db13413eec5762620c21623738c 100644 (file)
@@ -31,7 +31,7 @@ static struct scpi_ops *scpi_ops;
 
 static struct scpi_dvfs_info *scpi_get_dvfs_info(struct device *cpu_dev)
 {
-       u8 domain = topology_physical_package_id(cpu_dev->id);
+       int domain = topology_physical_package_id(cpu_dev->id);
 
        if (domain < 0)
                return ERR_PTR(-EINVAL);
index e5827a56ff3b5eda451202849c41b2d8b0e54f31..5eaea8b812cf39515c3e7132d90d4f3d7e0fba17 100644 (file)
@@ -113,7 +113,7 @@ static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
                __raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR);
 
        __raw_writel(
-               __raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & BIT(offset),
+               __raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset),
                ctrl->base + AR71XX_GPIO_REG_OE);
 
        spin_unlock_irqrestore(&ctrl->lock, flags);
index bd5193c67a9c272cb0bebf779ce3277d22aac479..88ae70ddb1274b11f31bad5dcb344d3a57f9c6e3 100644 (file)
@@ -141,9 +141,9 @@ static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio)
        unsigned long pinmask = bgc->pin2mask(bgc, gpio);
 
        if (bgc->dir & pinmask)
-               return bgc->read_reg(bgc->reg_set) & pinmask;
+               return !!(bgc->read_reg(bgc->reg_set) & pinmask);
        else
-               return bgc->read_reg(bgc->reg_dat) & pinmask;
+               return !!(bgc->read_reg(bgc->reg_dat) & pinmask);
 }
 
 static int bgpio_get(struct gpio_chip *gc, unsigned int gpio)
index 2a91f3287e3b7e52f2f6e16d108af07d4343be0b..4e4c3083ae567f02db4ff15444ec173ac53ebe0c 100644 (file)
@@ -1279,7 +1279,13 @@ static int _gpiod_get_raw_value(const struct gpio_desc *desc)
        chip = desc->chip;
        offset = gpio_chip_hwgpio(desc);
        value = chip->get ? chip->get(chip, offset) : -EIO;
-       value = value < 0 ? value : !!value;
+       /*
+        * FIXME: fix all drivers to clamp to [0,1] or return negative,
+        * then change this to:
+        * value = value < 0 ? value : !!value;
+        * so we can properly propagate error codes.
+        */
+       value = !!value;
        trace_gpio_value(desc_to_gpio(desc), 1, value);
        return value;
 }
index 5a5f04d0902d662548ebae9f82525e1363e8457c..048cfe073dae6a1e89112b219c6a130b3d513be9 100644 (file)
@@ -1264,7 +1264,8 @@ struct amdgpu_cs_parser {
        struct ww_acquire_ctx   ticket;
 
        /* user fence */
-       struct amdgpu_user_fence uf;
+       struct amdgpu_user_fence        uf;
+       struct amdgpu_bo_list_entry     uf_entry;
 };
 
 struct amdgpu_job {
index 4f352ec9dec4e2fb7c3bb5bd062e674291fc8d5a..25a3e2485cc2e9572943638d1975f678fbc26e38 100644 (file)
@@ -127,6 +127,37 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type,
        return 0;
 }
 
+static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
+                                     struct drm_amdgpu_cs_chunk_fence *fence_data)
+{
+       struct drm_gem_object *gobj;
+       uint32_t handle;
+
+       handle = fence_data->handle;
+       gobj = drm_gem_object_lookup(p->adev->ddev, p->filp,
+                                    fence_data->handle);
+       if (gobj == NULL)
+               return -EINVAL;
+
+       p->uf.bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));
+       p->uf.offset = fence_data->offset;
+
+       if (amdgpu_ttm_tt_has_userptr(p->uf.bo->tbo.ttm)) {
+               drm_gem_object_unreference_unlocked(gobj);
+               return -EINVAL;
+       }
+
+       p->uf_entry.robj = amdgpu_bo_ref(p->uf.bo);
+       p->uf_entry.prefered_domains = AMDGPU_GEM_DOMAIN_GTT;
+       p->uf_entry.allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
+       p->uf_entry.priority = 0;
+       p->uf_entry.tv.bo = &p->uf_entry.robj->tbo;
+       p->uf_entry.tv.shared = true;
+
+       drm_gem_object_unreference_unlocked(gobj);
+       return 0;
+}
+
 int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
 {
        union drm_amdgpu_cs *cs = data;
@@ -207,28 +238,15 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
 
                case AMDGPU_CHUNK_ID_FENCE:
                        size = sizeof(struct drm_amdgpu_cs_chunk_fence);
-                       if (p->chunks[i].length_dw * sizeof(uint32_t) >= size) {
-                               uint32_t handle;
-                               struct drm_gem_object *gobj;
-                               struct drm_amdgpu_cs_chunk_fence *fence_data;
-
-                               fence_data = (void *)p->chunks[i].kdata;
-                               handle = fence_data->handle;
-                               gobj = drm_gem_object_lookup(p->adev->ddev,
-                                                            p->filp, handle);
-                               if (gobj == NULL) {
-                                       ret = -EINVAL;
-                                       goto free_partial_kdata;
-                               }
-
-                               p->uf.bo = gem_to_amdgpu_bo(gobj);
-                               amdgpu_bo_ref(p->uf.bo);
-                               drm_gem_object_unreference_unlocked(gobj);
-                               p->uf.offset = fence_data->offset;
-                       } else {
+                       if (p->chunks[i].length_dw * sizeof(uint32_t) < size) {
                                ret = -EINVAL;
                                goto free_partial_kdata;
                        }
+
+                       ret = amdgpu_cs_user_fence_chunk(p, (void *)p->chunks[i].kdata);
+                       if (ret)
+                               goto free_partial_kdata;
+
                        break;
 
                case AMDGPU_CHUNK_ID_DEPENDENCIES:
@@ -391,6 +409,9 @@ static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p)
        p->vm_bos = amdgpu_vm_get_bos(p->adev, &fpriv->vm,
                                      &p->validated);
 
+       if (p->uf.bo)
+               list_add(&p->uf_entry.tv.head, &p->validated);
+
        if (need_mmap_lock)
                down_read(&current->mm->mmap_sem);
 
@@ -488,8 +509,8 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo
                for (i = 0; i < parser->num_ibs; i++)
                        amdgpu_ib_free(parser->adev, &parser->ibs[i]);
        kfree(parser->ibs);
-       if (parser->uf.bo)
-               amdgpu_bo_unref(&parser->uf.bo);
+       amdgpu_bo_unref(&parser->uf.bo);
+       amdgpu_bo_unref(&parser->uf_entry.robj);
 }
 
 static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p,
index b3ba27fd9a6bc880d7e061039e61ca42babc148f..e69357172ffb56d2e5f5e86ff551b599196079ba 100644 (file)
@@ -55,6 +55,9 @@ static int exynos_crtc_atomic_check(struct drm_crtc *crtc,
 {
        struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
 
+       if (!state->enable)
+               return 0;
+
        if (exynos_crtc->ops->atomic_check)
                return exynos_crtc->ops->atomic_check(exynos_crtc, state);
 
index a01e51581c4c466a000e2aa6b22f42e97ec31b85..f4af19a0d5696324c307617adfb0c86a3fdfed38 100644 (file)
@@ -2193,8 +2193,17 @@ struct drm_i915_gem_request {
        struct drm_i915_private *i915;
        struct intel_engine_cs *ring;
 
-       /** GEM sequence number associated with this request. */
-       uint32_t seqno;
+        /** GEM sequence number associated with the previous request,
+         * when the HWS breadcrumb is equal to this the GPU is processing
+         * this request.
+         */
+       u32 previous_seqno;
+
+        /** GEM sequence number associated with this request,
+         * when the HWS breadcrumb is equal or greater than this the GPU
+         * has finished processing this request.
+         */
+       u32 seqno;
 
        /** Position in the ringbuffer of the start of the request */
        u32 head;
@@ -2839,6 +2848,7 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
 
 int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
                  u32 flags);
+void __i915_vma_set_map_and_fenceable(struct i915_vma *vma);
 int __must_check i915_vma_unbind(struct i915_vma *vma);
 /*
  * BEWARE: Do not use the function below unless you can _absolutely_
@@ -2910,15 +2920,17 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
        return (int32_t)(seq1 - seq2) >= 0;
 }
 
+static inline bool i915_gem_request_started(struct drm_i915_gem_request *req,
+                                          bool lazy_coherency)
+{
+       u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
+       return i915_seqno_passed(seqno, req->previous_seqno);
+}
+
 static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
                                              bool lazy_coherency)
 {
-       u32 seqno;
-
-       BUG_ON(req == NULL);
-
-       seqno = req->ring->get_seqno(req->ring, lazy_coherency);
-
+       u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
        return i915_seqno_passed(seqno, req->seqno);
 }
 
index 32e6aade62238be511237c9ffad1933e18e561cb..f56af0aaafde511c1add59ce5f89fe2fa9be5c42 100644 (file)
@@ -1146,23 +1146,74 @@ static bool missed_irq(struct drm_i915_private *dev_priv,
        return test_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings);
 }
 
-static int __i915_spin_request(struct drm_i915_gem_request *req)
+static unsigned long local_clock_us(unsigned *cpu)
+{
+       unsigned long t;
+
+       /* Cheaply and approximately convert from nanoseconds to microseconds.
+        * The result and subsequent calculations are also defined in the same
+        * approximate microseconds units. The principal source of timing
+        * error here is from the simple truncation.
+        *
+        * Note that local_clock() is only defined wrt to the current CPU;
+        * the comparisons are no longer valid if we switch CPUs. Instead of
+        * blocking preemption for the entire busywait, we can detect the CPU
+        * switch and use that as indicator of system load and a reason to
+        * stop busywaiting, see busywait_stop().
+        */
+       *cpu = get_cpu();
+       t = local_clock() >> 10;
+       put_cpu();
+
+       return t;
+}
+
+static bool busywait_stop(unsigned long timeout, unsigned cpu)
+{
+       unsigned this_cpu;
+
+       if (time_after(local_clock_us(&this_cpu), timeout))
+               return true;
+
+       return this_cpu != cpu;
+}
+
+static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
 {
        unsigned long timeout;
+       unsigned cpu;
+
+       /* When waiting for high frequency requests, e.g. during synchronous
+        * rendering split between the CPU and GPU, the finite amount of time
+        * required to set up the irq and wait upon it limits the response
+        * rate. By busywaiting on the request completion for a short while we
+        * can service the high frequency waits as quick as possible. However,
+        * if it is a slow request, we want to sleep as quickly as possible.
+        * The tradeoff between waiting and sleeping is roughly the time it
+        * takes to sleep on a request, on the order of a microsecond.
+        */
 
-       if (i915_gem_request_get_ring(req)->irq_refcount)
+       if (req->ring->irq_refcount)
                return -EBUSY;
 
-       timeout = jiffies + 1;
+       /* Only spin if we know the GPU is processing this request */
+       if (!i915_gem_request_started(req, true))
+               return -EAGAIN;
+
+       timeout = local_clock_us(&cpu) + 5;
        while (!need_resched()) {
                if (i915_gem_request_completed(req, true))
                        return 0;
 
-               if (time_after_eq(jiffies, timeout))
+               if (signal_pending_state(state, current))
+                       break;
+
+               if (busywait_stop(timeout, cpu))
                        break;
 
                cpu_relax_lowlatency();
        }
+
        if (i915_gem_request_completed(req, false))
                return 0;
 
@@ -1197,6 +1248,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
        struct drm_i915_private *dev_priv = dev->dev_private;
        const bool irq_test_in_progress =
                ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(ring);
+       int state = interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
        DEFINE_WAIT(wait);
        unsigned long timeout_expire;
        s64 before, now;
@@ -1229,7 +1281,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
        before = ktime_get_raw_ns();
 
        /* Optimistic spin for the next jiffie before touching IRQs */
-       ret = __i915_spin_request(req);
+       ret = __i915_spin_request(req, state);
        if (ret == 0)
                goto out;
 
@@ -1241,8 +1293,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
        for (;;) {
                struct timer_list timer;
 
-               prepare_to_wait(&ring->irq_queue, &wait,
-                               interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+               prepare_to_wait(&ring->irq_queue, &wait, state);
 
                /* We need to check whether any gpu reset happened in between
                 * the caller grabbing the seqno and now ... */
@@ -1260,7 +1311,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
                        break;
                }
 
-               if (interruptible && signal_pending(current)) {
+               if (signal_pending_state(state, current)) {
                        ret = -ERESTARTSYS;
                        break;
                }
@@ -2554,6 +2605,7 @@ void __i915_add_request(struct drm_i915_gem_request *request,
        request->batch_obj = obj;
 
        request->emitted_jiffies = jiffies;
+       request->previous_seqno = ring->last_submitted_seqno;
        ring->last_submitted_seqno = request->seqno;
        list_add_tail(&request->list, &ring->request_list);
 
@@ -4080,6 +4132,29 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags)
        return false;
 }
 
+void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
+{
+       struct drm_i915_gem_object *obj = vma->obj;
+       bool mappable, fenceable;
+       u32 fence_size, fence_alignment;
+
+       fence_size = i915_gem_get_gtt_size(obj->base.dev,
+                                          obj->base.size,
+                                          obj->tiling_mode);
+       fence_alignment = i915_gem_get_gtt_alignment(obj->base.dev,
+                                                    obj->base.size,
+                                                    obj->tiling_mode,
+                                                    true);
+
+       fenceable = (vma->node.size == fence_size &&
+                    (vma->node.start & (fence_alignment - 1)) == 0);
+
+       mappable = (vma->node.start + fence_size <=
+                   to_i915(obj->base.dev)->gtt.mappable_end);
+
+       obj->map_and_fenceable = mappable && fenceable;
+}
+
 static int
 i915_gem_object_do_pin(struct drm_i915_gem_object *obj,
                       struct i915_address_space *vm,
@@ -4147,25 +4222,7 @@ i915_gem_object_do_pin(struct drm_i915_gem_object *obj,
 
        if (ggtt_view && ggtt_view->type == I915_GGTT_VIEW_NORMAL &&
            (bound ^ vma->bound) & GLOBAL_BIND) {
-               bool mappable, fenceable;
-               u32 fence_size, fence_alignment;
-
-               fence_size = i915_gem_get_gtt_size(obj->base.dev,
-                                                  obj->base.size,
-                                                  obj->tiling_mode);
-               fence_alignment = i915_gem_get_gtt_alignment(obj->base.dev,
-                                                            obj->base.size,
-                                                            obj->tiling_mode,
-                                                            true);
-
-               fenceable = (vma->node.size == fence_size &&
-                            (vma->node.start & (fence_alignment - 1)) == 0);
-
-               mappable = (vma->node.start + fence_size <=
-                           dev_priv->gtt.mappable_end);
-
-               obj->map_and_fenceable = mappable && fenceable;
-
+               __i915_vma_set_map_and_fenceable(vma);
                WARN_ON(flags & PIN_MAPPABLE && !obj->map_and_fenceable);
        }
 
index 43f35d12b677606d43b96cedc3cae476067946ab..86c7500454b4d1b3928dc41f37ab9aa6917fd557 100644 (file)
@@ -2676,6 +2676,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
                        return ret;
                }
                vma->bound |= GLOBAL_BIND;
+               __i915_vma_set_map_and_fenceable(vma);
                list_add_tail(&vma->mm_list, &ggtt_vm->inactive_list);
        }
 
index cdacf3f5b77a571086024deae067bf32edc3a988..87e919a06b277fea6cfade79445a165bac925056 100644 (file)
@@ -687,6 +687,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
                }
 
                vma->bound |= GLOBAL_BIND;
+               __i915_vma_set_map_and_fenceable(vma);
                list_add_tail(&vma->mm_list, &ggtt->inactive_list);
        }
 
index 62211abe492265ce33cc5e04fbfdef71de398b8f..beb0374a19f199d23c73116dcfcd08c3d500dde0 100644 (file)
@@ -116,6 +116,7 @@ static void skylake_pfit_enable(struct intel_crtc *crtc);
 static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force);
 static void ironlake_pfit_enable(struct intel_crtc *crtc);
 static void intel_modeset_setup_hw_state(struct drm_device *dev);
+static void intel_pre_disable_primary(struct drm_crtc *crtc);
 
 typedef struct {
        int     min, max;
@@ -2607,6 +2608,8 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
        struct drm_i915_gem_object *obj;
        struct drm_plane *primary = intel_crtc->base.primary;
        struct drm_plane_state *plane_state = primary->state;
+       struct drm_crtc_state *crtc_state = intel_crtc->base.state;
+       struct intel_plane *intel_plane = to_intel_plane(primary);
        struct drm_framebuffer *fb;
 
        if (!plane_config->fb)
@@ -2643,6 +2646,18 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
                }
        }
 
+       /*
+        * We've failed to reconstruct the BIOS FB.  Current display state
+        * indicates that the primary plane is visible, but has a NULL FB,
+        * which will lead to problems later if we don't fix it up.  The
+        * simplest solution is to just disable the primary plane now and
+        * pretend the BIOS never had it enabled.
+        */
+       to_intel_plane_state(plane_state)->visible = false;
+       crtc_state->plane_mask &= ~(1 << drm_plane_index(primary));
+       intel_pre_disable_primary(&intel_crtc->base);
+       intel_plane->disable_plane(primary, &intel_crtc->base);
+
        return;
 
 valid_fb:
@@ -9910,14 +9925,14 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
        return true;
 }
 
-static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
+static void i845_update_cursor(struct drm_crtc *crtc, u32 base, bool on)
 {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        uint32_t cntl = 0, size = 0;
 
-       if (base) {
+       if (on) {
                unsigned int width = intel_crtc->base.cursor->state->crtc_w;
                unsigned int height = intel_crtc->base.cursor->state->crtc_h;
                unsigned int stride = roundup_pow_of_two(width) * 4;
@@ -9972,16 +9987,15 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
        }
 }
 
-static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
+static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base, bool on)
 {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
-       uint32_t cntl;
+       uint32_t cntl = 0;
 
-       cntl = 0;
-       if (base) {
+       if (on) {
                cntl = MCURSOR_GAMMA_ENABLE;
                switch (intel_crtc->base.cursor->state->crtc_w) {
                        case 64:
@@ -10032,18 +10046,17 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
        int y = cursor_state->crtc_y;
        u32 base = 0, pos = 0;
 
-       if (on)
-               base = intel_crtc->cursor_addr;
+       base = intel_crtc->cursor_addr;
 
        if (x >= intel_crtc->config->pipe_src_w)
-               base = 0;
+               on = false;
 
        if (y >= intel_crtc->config->pipe_src_h)
-               base = 0;
+               on = false;
 
        if (x < 0) {
                if (x + cursor_state->crtc_w <= 0)
-                       base = 0;
+                       on = false;
 
                pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
                x = -x;
@@ -10052,16 +10065,13 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
 
        if (y < 0) {
                if (y + cursor_state->crtc_h <= 0)
-                       base = 0;
+                       on = false;
 
                pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
                y = -y;
        }
        pos |= y << CURSOR_Y_SHIFT;
 
-       if (base == 0 && intel_crtc->cursor_base == 0)
-               return;
-
        I915_WRITE(CURPOS(pipe), pos);
 
        /* ILK+ do this automagically */
@@ -10072,9 +10082,9 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
        }
 
        if (IS_845G(dev) || IS_I865G(dev))
-               i845_update_cursor(crtc, base);
+               i845_update_cursor(crtc, base, on);
        else
-               i9xx_update_cursor(crtc, base);
+               i9xx_update_cursor(crtc, base, on);
 }
 
 static bool cursor_size_ok(struct drm_device *dev,
@@ -13718,6 +13728,7 @@ intel_check_cursor_plane(struct drm_plane *plane,
        struct drm_crtc *crtc = crtc_state->base.crtc;
        struct drm_framebuffer *fb = state->base.fb;
        struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+       enum pipe pipe = to_intel_plane(plane)->pipe;
        unsigned stride;
        int ret;
 
@@ -13751,6 +13762,22 @@ intel_check_cursor_plane(struct drm_plane *plane,
                return -EINVAL;
        }
 
+       /*
+        * There's something wrong with the cursor on CHV pipe C.
+        * If it straddles the left edge of the screen then
+        * moving it away from the edge or disabling it often
+        * results in a pipe underrun, and often that can lead to
+        * dead pipe (constant underrun reported, and it scans
+        * out just a solid color). To recover from that, the
+        * display power well must be turned off and on again.
+        * Refuse the put the cursor into that compromised position.
+        */
+       if (IS_CHERRYVIEW(plane->dev) && pipe == PIPE_C &&
+           state->visible && state->base.crtc_x < 0) {
+               DRM_DEBUG_KMS("CHV cursor C not allowed to straddle the left screen edge\n");
+               return -EINVAL;
+       }
+
        return 0;
 }
 
@@ -13774,9 +13801,6 @@ intel_commit_cursor_plane(struct drm_plane *plane,
        crtc = crtc ? crtc : plane->crtc;
        intel_crtc = to_intel_crtc(crtc);
 
-       if (intel_crtc->cursor_bo == obj)
-               goto update;
-
        if (!obj)
                addr = 0;
        else if (!INTEL_INFO(dev)->cursor_needs_physical)
@@ -13785,9 +13809,7 @@ intel_commit_cursor_plane(struct drm_plane *plane,
                addr = obj->phys_handle->busaddr;
 
        intel_crtc->cursor_addr = addr;
-       intel_crtc->cursor_bo = obj;
 
-update:
        if (crtc->state->active)
                intel_crtc_update_cursor(crtc, state->visible);
 }
index f2a1142bff34310a40abd262a59106bffdecba6f..0d00f07b7163c90c10d8e994b037b7b24b508d34 100644 (file)
@@ -550,7 +550,6 @@ struct intel_crtc {
        int adjusted_x;
        int adjusted_y;
 
-       struct drm_i915_gem_object *cursor_bo;
        uint32_t cursor_addr;
        uint32_t cursor_cntl;
        uint32_t cursor_size;
index 81cdd9ff38922397171e91558136ae0765229106..64086f2d4e26c7a46144a2e1eebea8ef7154a06a 100644 (file)
@@ -1374,17 +1374,18 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
        struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
        struct drm_i915_private *dev_priv = to_i915(connector->dev);
        bool live_status = false;
-       unsigned int retry = 3;
+       unsigned int try;
 
        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
                      connector->base.id, connector->name);
 
        intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
 
-       while (!live_status && --retry) {
+       for (try = 0; !live_status && try < 4; try++) {
+               if (try)
+                       msleep(10);
                live_status = intel_digital_port_connected(dev_priv,
                                hdmi_to_dig_port(intel_hdmi));
-               mdelay(10);
        }
 
        if (!live_status)
index 43006db6fd58252830842c02543ca1659ae23df2..80fed7e78dcbe0bc1e7df6a864c3efb475c2733a 100644 (file)
@@ -83,6 +83,7 @@ nvbios_fan_parse(struct nvkm_bios *bios, struct nvbios_therm_fan *fan)
                        fan->type = NVBIOS_THERM_FAN_UNK;
                }
 
+               fan->fan_mode = NVBIOS_THERM_FAN_LINEAR;
                fan->min_duty = nvbios_rd08(bios, data + 0x02);
                fan->max_duty = nvbios_rd08(bios, data + 0x03);
 
index 8f59f057cdf4a336cf29cd32803dff2b50143be2..80a73bfc1a65807db6fc276e3027f11500d2f96b 100644 (file)
@@ -1217,6 +1217,7 @@ config SENSORS_PWM_FAN
 config SENSORS_SHT15
        tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
        depends on GPIOLIB || COMPILE_TEST
+       select BITREVERSE
        help
          If you say yes here you get support for the Sensiron SHT10, SHT11,
          SHT15, SHT71, SHT75 humidity and temperature sensors.
index 65482624ea2c81a2ef2b5487d6a0470cc90fead7..5289aa0980a8fac074822ddb412f35e7a9380bd5 100644 (file)
@@ -58,6 +58,7 @@ struct tmp102 {
        u16 config_orig;
        unsigned long last_update;
        int temp[3];
+       bool first_time;
 };
 
 /* convert left adjusted 13-bit TMP102 register value to milliCelsius */
@@ -93,6 +94,7 @@ static struct tmp102 *tmp102_update_device(struct device *dev)
                                tmp102->temp[i] = tmp102_reg_to_mC(status);
                }
                tmp102->last_update = jiffies;
+               tmp102->first_time = false;
        }
        mutex_unlock(&tmp102->lock);
        return tmp102;
@@ -102,6 +104,12 @@ static int tmp102_read_temp(void *dev, int *temp)
 {
        struct tmp102 *tmp102 = tmp102_update_device(dev);
 
+       /* Is it too early even to return a conversion? */
+       if (tmp102->first_time) {
+               dev_dbg(dev, "%s: Conversion not ready yet..\n", __func__);
+               return -EAGAIN;
+       }
+
        *temp = tmp102->temp[0];
 
        return 0;
@@ -114,6 +122,10 @@ static ssize_t tmp102_show_temp(struct device *dev,
        struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
        struct tmp102 *tmp102 = tmp102_update_device(dev);
 
+       /* Is it too early even to return a read? */
+       if (tmp102->first_time)
+               return -EAGAIN;
+
        return sprintf(buf, "%d\n", tmp102->temp[sda->index]);
 }
 
@@ -207,7 +219,9 @@ static int tmp102_probe(struct i2c_client *client,
                status = -ENODEV;
                goto fail_restore_config;
        }
-       tmp102->last_update = jiffies - HZ;
+       tmp102->last_update = jiffies;
+       /* Mark that we are not ready with data until conversion is complete */
+       tmp102->first_time = true;
        mutex_init(&tmp102->lock);
 
        hwmon_dev = hwmon_device_register_with_groups(dev, client->name,
index c5628a42170acf83d0a2c5d2dffa6a50e6572c59..a8bdcb5292f5b30a925c40f28c8d193395b443c6 100644 (file)
@@ -202,8 +202,15 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
         * d is always 6 on Keystone I2C controller
         */
 
-       /* get minimum of 7 MHz clock, but max of 12 MHz */
-       psc = (input_clock / 7000000) - 1;
+       /*
+        * Both Davinci and current Keystone User Guides recommend a value
+        * between 7MHz and 12MHz. In reality 7MHz module clock doesn't
+        * always produce enough margin between SDA and SCL transitions.
+        * Measurements show that the higher the module clock is, the
+        * bigger is the margin, providing more reliable communication.
+        * So we better target for 12MHz.
+        */
+       psc = (input_clock / 12000000) - 1;
        if ((input_clock / (psc + 1)) > 12000000)
                psc++;  /* better to run under spec than over */
        d = (psc >= 2) ? 5 : 7 - psc;
index 8c48b27ba05975e51a40ddaab979e7b23302e3e0..de7fbbb374cd34fce1cc8fffb11c45b21755bead 100644 (file)
@@ -813,6 +813,12 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
 tx_aborted:
        if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err)
                complete(&dev->cmd_complete);
+       else if (unlikely(dev->accessor_flags & ACCESS_INTR_MASK)) {
+               /* workaround to trigger pending interrupt */
+               stat = dw_readl(dev, DW_IC_INTR_MASK);
+               i2c_dw_disable_int(dev);
+               dw_writel(dev, stat, DW_IC_INTR_MASK);
+       }
 
        return IRQ_HANDLED;
 }
index 1d50898e7b2403868c239f2ebc236a240a755bc7..9ffb63a60f95454ebbaf43f6a12bbe922de66179 100644 (file)
@@ -111,6 +111,7 @@ struct dw_i2c_dev {
 
 #define ACCESS_SWAP            0x00000001
 #define ACCESS_16BIT           0x00000002
+#define ACCESS_INTR_MASK       0x00000004
 
 extern int i2c_dw_init(struct dw_i2c_dev *dev);
 extern void i2c_dw_disable(struct dw_i2c_dev *dev);
index 809579ecb5a44fed6745af1274ed46864763651c..6b00061c37469b98613880ffe71d26118c76d92a 100644 (file)
@@ -93,6 +93,7 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
 static int dw_i2c_acpi_configure(struct platform_device *pdev)
 {
        struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
+       const struct acpi_device_id *id;
 
        dev->adapter.nr = -1;
        dev->tx_fifo_depth = 32;
@@ -106,6 +107,10 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
        dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
                           &dev->sda_hold_time);
 
+       id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
+       if (id && id->driver_data)
+               dev->accessor_flags |= (u32)id->driver_data;
+
        return 0;
 }
 
@@ -116,7 +121,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
        { "INT3433", 0 },
        { "80860F41", 0 },
        { "808622C1", 0 },
-       { "AMD0010", 0 },
+       { "AMD0010", ACCESS_INTR_MASK },
        { }
 };
 MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
@@ -240,12 +245,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
        }
 
        r = i2c_dw_probe(dev);
-       if (r) {
+       if (r && !dev->pm_runtime_disabled)
                pm_runtime_disable(&pdev->dev);
-               return r;
-       }
 
-       return 0;
+       return r;
 }
 
 static int dw_i2c_plat_remove(struct platform_device *pdev)
@@ -260,7 +263,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
 
        pm_runtime_dont_use_autosuspend(&pdev->dev);
        pm_runtime_put_sync(&pdev->dev);
-       pm_runtime_disable(&pdev->dev);
+       if (!dev->pm_runtime_disabled)
+               pm_runtime_disable(&pdev->dev);
 
        return 0;
 }
index 9bb0b056b25f235085df0e994c7c6584581a5a6d..d4d853680ae47881151effb56269e4e660d522e1 100644 (file)
@@ -1119,6 +1119,8 @@ static int i2c_imx_probe(struct platform_device *pdev)
                        i2c_imx, IMX_I2C_I2CR);
        imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
 
+       i2c_imx_init_recovery_info(i2c_imx, pdev);
+
        /* Add I2C adapter */
        ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
        if (ret < 0) {
@@ -1126,8 +1128,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
                goto clk_disable;
        }
 
-       i2c_imx_init_recovery_info(i2c_imx, pdev);
-
        /* Set up platform driver data */
        platform_set_drvdata(pdev, i2c_imx);
        clk_disable_unprepare(i2c_imx->clk);
index 5801227b97ab089022f90608f6fc425ebd13cd87..43207f52e5a3733f5d405da921fb5d32b331321f 100644 (file)
@@ -146,6 +146,8 @@ struct mv64xxx_i2c_data {
        bool                    errata_delay;
        struct reset_control    *rstc;
        bool                    irq_clear_inverted;
+       /* Clk div is 2 to the power n, not 2 to the power n + 1 */
+       bool                    clk_n_base_0;
 };
 
 static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
@@ -757,25 +759,29 @@ MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
 #ifdef CONFIG_OF
 #ifdef CONFIG_HAVE_CLK
 static int
-mv64xxx_calc_freq(const int tclk, const int n, const int m)
+mv64xxx_calc_freq(struct mv64xxx_i2c_data *drv_data,
+                 const int tclk, const int n, const int m)
 {
-       return tclk / (10 * (m + 1) * (2 << n));
+       if (drv_data->clk_n_base_0)
+               return tclk / (10 * (m + 1) * (1 << n));
+       else
+               return tclk / (10 * (m + 1) * (2 << n));
 }
 
 static bool
-mv64xxx_find_baud_factors(const u32 req_freq, const u32 tclk, u32 *best_n,
-                         u32 *best_m)
+mv64xxx_find_baud_factors(struct mv64xxx_i2c_data *drv_data,
+                         const u32 req_freq, const u32 tclk)
 {
        int freq, delta, best_delta = INT_MAX;
        int m, n;
 
        for (n = 0; n <= 7; n++)
                for (m = 0; m <= 15; m++) {
-                       freq = mv64xxx_calc_freq(tclk, n, m);
+                       freq = mv64xxx_calc_freq(drv_data, tclk, n, m);
                        delta = req_freq - freq;
                        if (delta >= 0 && delta < best_delta) {
-                               *best_m = m;
-                               *best_n = n;
+                               drv_data->freq_m = m;
+                               drv_data->freq_n = n;
                                best_delta = delta;
                        }
                        if (best_delta == 0)
@@ -813,8 +819,11 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
        if (of_property_read_u32(np, "clock-frequency", &bus_freq))
                bus_freq = 100000; /* 100kHz by default */
 
-       if (!mv64xxx_find_baud_factors(bus_freq, tclk,
-                                      &drv_data->freq_n, &drv_data->freq_m)) {
+       if (of_device_is_compatible(np, "allwinner,sun4i-a10-i2c") ||
+           of_device_is_compatible(np, "allwinner,sun6i-a31-i2c"))
+               drv_data->clk_n_base_0 = true;
+
+       if (!mv64xxx_find_baud_factors(drv_data, bus_freq, tclk)) {
                rc = -EINVAL;
                goto out;
        }
index b0ae560b38c308335229f0f9b2317f0361b6b8a3..599c0d7bd906d19afc89417afc74d939e6985252 100644 (file)
@@ -576,7 +576,7 @@ static int rcar_reg_slave(struct i2c_client *slave)
        if (slave->flags & I2C_CLIENT_TEN)
                return -EAFNOSUPPORT;
 
-       pm_runtime_forbid(rcar_i2c_priv_to_dev(priv));
+       pm_runtime_get_sync(rcar_i2c_priv_to_dev(priv));
 
        priv->slave = slave;
        rcar_i2c_write(priv, ICSAR, slave->addr);
@@ -598,7 +598,7 @@ static int rcar_unreg_slave(struct i2c_client *slave)
 
        priv->slave = NULL;
 
-       pm_runtime_allow(rcar_i2c_priv_to_dev(priv));
+       pm_runtime_put(rcar_i2c_priv_to_dev(priv));
 
        return 0;
 }
index c1935ebd6a9c38971b6539cc1d1ae03dfc276d17..9096d17beb5bb002d914010a77f156a3f3f97f32 100644 (file)
@@ -908,7 +908,7 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
                                 &i2c->scl_fall_ns))
                i2c->scl_fall_ns = 300;
        if (of_property_read_u32(pdev->dev.of_node, "i2c-sda-falling-time-ns",
-                                &i2c->scl_fall_ns))
+                                &i2c->sda_fall_ns))
                i2c->sda_fall_ns = i2c->scl_fall_ns;
 
        strlcpy(i2c->adap.name, "rk3x-i2c", sizeof(i2c->adap.name));
index ea72dca32fdfde83cfdd223525a915a5721d6816..25020ec777c9783bf5c62853051707bace5c4483 100644 (file)
@@ -822,7 +822,7 @@ static int st_i2c_probe(struct platform_device *pdev)
 
        adap = &i2c_dev->adap;
        i2c_set_adapdata(adap, i2c_dev);
-       snprintf(adap->name, sizeof(adap->name), "ST I2C(0x%pa)", &res->start);
+       snprintf(adap->name, sizeof(adap->name), "ST I2C(%pa)", &res->start);
        adap->owner = THIS_MODULE;
        adap->timeout = 2 * HZ;
        adap->retries = 0;
index 932d07307454bd47441da61ff06e3ef03ea93cd4..da326090c2b0e7f07ab4de5668012b1a4d5e92f3 100644 (file)
@@ -592,6 +592,7 @@ static void db9_attach(struct parport *pp)
                return;
        }
 
+       memset(&db9_parport_cb, 0, sizeof(db9_parport_cb));
        db9_parport_cb.flags = PARPORT_FLAG_EXCL;
 
        pd = parport_register_dev_model(pp, "db9", &db9_parport_cb, port_idx);
index 5a672dcac0d8174a151254ac31b591f0189f9d91..eae14d512353aae4902f3ce482c1cf87cba736b6 100644 (file)
@@ -951,6 +951,7 @@ static void gc_attach(struct parport *pp)
        pads = gc_cfg[port_idx].args + 1;
        n_pads = gc_cfg[port_idx].nargs - 1;
 
+       memset(&gc_parport_cb, 0, sizeof(gc_parport_cb));
        gc_parport_cb.flags = PARPORT_FLAG_EXCL;
 
        pd = parport_register_dev_model(pp, "gamecon", &gc_parport_cb,
index 9f5bca26bd2fb85a90ed4fd91bbdcf1a83e84162..77f575dd0901ff2732f47a62ebb7af37b826b608 100644 (file)
@@ -181,6 +181,7 @@ static void tgfx_attach(struct parport *pp)
        n_buttons = tgfx_cfg[port_idx].args + 1;
        n_devs = tgfx_cfg[port_idx].nargs - 1;
 
+       memset(&tgfx_parport_cb, 0, sizeof(tgfx_parport_cb));
        tgfx_parport_cb.flags = PARPORT_FLAG_EXCL;
 
        pd = parport_register_dev_model(pp, "turbografx", &tgfx_parport_cb,
index 9c07fe911075f3e1dba089f07d7d60d10ac327ba..70a893a17467608a103a81546eb7cce4cdf44010 100644 (file)
@@ -218,6 +218,7 @@ static void walkera0701_attach(struct parport *pp)
 
        w->parport = pp;
 
+       memset(&walkera0701_parport_cb, 0, sizeof(walkera0701_parport_cb));
        walkera0701_parport_cb.flags = PARPORT_FLAG_EXCL;
        walkera0701_parport_cb.irq_func = walkera0701_irq_handler;
        walkera0701_parport_cb.private = w;
index 4bf678541496e5971a3aa88cf9ded8e89558786a..d5994a745ffa5b5f4d1b411fec76f0a447a60f94 100644 (file)
@@ -97,8 +97,7 @@ static void arizona_haptics_work(struct work_struct *work)
 
                ret = regmap_update_bits(arizona->regmap,
                                         ARIZONA_HAPTICS_CONTROL_1,
-                                        ARIZONA_HAP_CTRL_MASK,
-                                        1 << ARIZONA_HAP_CTRL_SHIFT);
+                                        ARIZONA_HAP_CTRL_MASK, 0);
                if (ret != 0) {
                        dev_err(arizona->dev, "Failed to stop haptics: %d\n",
                                ret);
index 5e1665bbaa0baca86e2c865ba88162be2f209d2e..2f589857a0395d8c48f685f47bd1c9ceb8445213 100644 (file)
@@ -41,6 +41,7 @@
 
 #define DRIVER_NAME            "elan_i2c"
 #define ELAN_DRIVER_VERSION    "1.6.1"
+#define ELAN_VENDOR_ID         0x04f3
 #define ETP_MAX_PRESSURE       255
 #define ETP_FWIDTH_REDUCE      90
 #define ETP_FINGER_WIDTH       15
@@ -914,6 +915,8 @@ static int elan_setup_input_device(struct elan_tp_data *data)
 
        input->name = "Elan Touchpad";
        input->id.bustype = BUS_I2C;
+       input->id.vendor = ELAN_VENDOR_ID;
+       input->id.product = data->product_id;
        input_set_drvdata(input, data);
 
        error = input_mt_init_slots(input, ETP_MAX_FINGERS,
index 92c31b8f8fb489c317013f1cf77f133993fcc321..1edfac78d4ac742a8fe6d6183660c45652381804 100644 (file)
@@ -145,6 +145,7 @@ static int parkbd_getport(struct parport *pp)
 {
        struct pardev_cb parkbd_parport_cb;
 
+       memset(&parkbd_parport_cb, 0, sizeof(parkbd_parport_cb));
        parkbd_parport_cb.irq_func = parkbd_interrupt;
        parkbd_parport_cb.flags = PARPORT_FLAG_EXCL;
 
index e7f966da6efa318f1901ce912e4e0dd65b5c70f7..78ca44840d60cac1467c90cb563cedf2a05fcaab 100644 (file)
@@ -1819,6 +1819,14 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
        input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
        input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);
 
+       /* Verify that a device really has an endpoint */
+       if (intf->altsetting[0].desc.bNumEndpoints < 1) {
+               dev_err(&intf->dev,
+                       "interface has %d endpoints, but must have minimum 1\n",
+                       intf->altsetting[0].desc.bNumEndpoints);
+               err = -EINVAL;
+               goto fail3;
+       }
        endpoint = &intf->altsetting[0].endpoint[0].desc;
 
        /* Go set up our URB, which is called when the tablet receives
@@ -1861,6 +1869,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
        if (i == ARRAY_SIZE(speeds)) {
                dev_info(&intf->dev,
                         "Aiptek tried all speeds, no sane response\n");
+               err = -EINVAL;
                goto fail3;
        }
 
index c5622058c22bba77b14ed336b764dc7b1ac6c617..2d5794ec338b72a1cea0367bccdaf9654db025d4 100644 (file)
@@ -2487,6 +2487,31 @@ static struct mxt_acpi_platform_data samus_platform_data[] = {
        { }
 };
 
+static unsigned int chromebook_tp_buttons[] = {
+       KEY_RESERVED,
+       KEY_RESERVED,
+       KEY_RESERVED,
+       KEY_RESERVED,
+       KEY_RESERVED,
+       BTN_LEFT
+};
+
+static struct mxt_acpi_platform_data chromebook_platform_data[] = {
+       {
+               /* Touchpad */
+               .hid    = "ATML0000",
+               .pdata  = {
+                       .t19_num_keys   = ARRAY_SIZE(chromebook_tp_buttons),
+                       .t19_keymap     = chromebook_tp_buttons,
+               },
+       },
+       {
+               /* Touchscreen */
+               .hid    = "ATML0001",
+       },
+       { }
+};
+
 static const struct dmi_system_id mxt_dmi_table[] = {
        {
                /* 2015 Google Pixel */
@@ -2497,6 +2522,14 @@ static const struct dmi_system_id mxt_dmi_table[] = {
                },
                .driver_data = samus_platform_data,
        },
+       {
+               /* Other Google Chromebooks */
+               .ident = "Chromebook",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
+               },
+               .driver_data = chromebook_platform_data,
+       },
        { }
 };
 
@@ -2701,6 +2734,7 @@ static const struct i2c_device_id mxt_id[] = {
        { "qt602240_ts", 0 },
        { "atmel_mxt_ts", 0 },
        { "atmel_mxt_tp", 0 },
+       { "maxtouch", 0 },
        { "mXT224", 0 },
        { }
 };
index 17cc20ef4923bdb2fb2edcf770d7c303be9d6af5..ac09855fa435d7fc2d87fb801fb277bb55f086ba 100644 (file)
@@ -1316,7 +1316,13 @@ static int __maybe_unused elants_i2c_suspend(struct device *dev)
 
        disable_irq(client->irq);
 
-       if (device_may_wakeup(dev) || ts->keep_power_in_suspend) {
+       if (device_may_wakeup(dev)) {
+               /*
+                * The device will automatically enter idle mode
+                * that has reduced power consumption.
+                */
+               ts->wake_irq_enabled = (enable_irq_wake(client->irq) == 0);
+       } else if (ts->keep_power_in_suspend) {
                for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
                        error = elants_i2c_send(client, set_sleep_cmd,
                                                sizeof(set_sleep_cmd));
@@ -1326,10 +1332,6 @@ static int __maybe_unused elants_i2c_suspend(struct device *dev)
                        dev_err(&client->dev,
                                "suspend command failed: %d\n", error);
                }
-
-               if (device_may_wakeup(dev))
-                       ts->wake_irq_enabled =
-                                       (enable_irq_wake(client->irq) == 0);
        } else {
                elants_i2c_power_off(ts);
        }
@@ -1345,10 +1347,11 @@ static int __maybe_unused elants_i2c_resume(struct device *dev)
        int retry_cnt;
        int error;
 
-       if (device_may_wakeup(dev) && ts->wake_irq_enabled)
-               disable_irq_wake(client->irq);
-
-       if (ts->keep_power_in_suspend) {
+       if (device_may_wakeup(dev)) {
+               if (ts->wake_irq_enabled)
+                       disable_irq_wake(client->irq);
+               elants_i2c_sw_reset(client);
+       } else if (ts->keep_power_in_suspend) {
                for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
                        error = elants_i2c_send(client, set_active_cmd,
                                                sizeof(set_active_cmd));
index d21d4edf7236abac49072c086290b76d2ae201b5..7caf2fa237f22bd7a3b0932c6387ed52e0b26424 100644 (file)
@@ -494,6 +494,22 @@ static void handle_fault_error(struct fault *fault)
        }
 }
 
+static bool access_error(struct vm_area_struct *vma, struct fault *fault)
+{
+       unsigned long requested = 0;
+
+       if (fault->flags & PPR_FAULT_EXEC)
+               requested |= VM_EXEC;
+
+       if (fault->flags & PPR_FAULT_READ)
+               requested |= VM_READ;
+
+       if (fault->flags & PPR_FAULT_WRITE)
+               requested |= VM_WRITE;
+
+       return (requested & ~vma->vm_flags) != 0;
+}
+
 static void do_fault(struct work_struct *work)
 {
        struct fault *fault = container_of(work, struct fault, work);
@@ -516,8 +532,8 @@ static void do_fault(struct work_struct *work)
                goto out;
        }
 
-       if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) {
-               /* handle_mm_fault would BUG_ON() */
+       /* Check if we have the right permissions on the vma */
+       if (access_error(vma, fault)) {
                up_read(&mm->mmap_sem);
                handle_fault_error(fault);
                goto out;
index c69e3f9ec9586bca0cd2ef712a3cf9fc25f4689f..50464833d0b84732a4d397cee8b73ed43a721712 100644 (file)
@@ -484,6 +484,23 @@ struct page_req_dsc {
 };
 
 #define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x10)
+
+static bool access_error(struct vm_area_struct *vma, struct page_req_dsc *req)
+{
+       unsigned long requested = 0;
+
+       if (req->exe_req)
+               requested |= VM_EXEC;
+
+       if (req->rd_req)
+               requested |= VM_READ;
+
+       if (req->wr_req)
+               requested |= VM_WRITE;
+
+       return (requested & ~vma->vm_flags) != 0;
+}
+
 static irqreturn_t prq_event_thread(int irq, void *d)
 {
        struct intel_iommu *iommu = d;
@@ -539,6 +556,9 @@ static irqreturn_t prq_event_thread(int irq, void *d)
                if (!vma || address < vma->vm_start)
                        goto invalid;
 
+               if (access_error(vma, req))
+                       goto invalid;
+
                ret = handle_mm_fault(svm->mm, vma, address,
                                      req->wr_req ? FAULT_FLAG_WRITE : 0);
                if (ret & VM_FAULT_ERROR)
index 807095f4c793bb4f1d4119f81abf2653b83240cb..61aacab424cf1860dbb5651f5a4fc6c9f7188027 100644 (file)
@@ -314,8 +314,8 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio)
  */
 void mddev_suspend(struct mddev *mddev)
 {
-       BUG_ON(mddev->suspended);
-       mddev->suspended = 1;
+       if (mddev->suspended++)
+               return;
        synchronize_rcu();
        wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
        mddev->pers->quiesce(mddev, 1);
@@ -326,7 +326,8 @@ EXPORT_SYMBOL_GPL(mddev_suspend);
 
 void mddev_resume(struct mddev *mddev)
 {
-       mddev->suspended = 0;
+       if (--mddev->suspended)
+               return;
        wake_up(&mddev->sb_wait);
        mddev->pers->quiesce(mddev, 0);
 
@@ -1652,7 +1653,7 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev)
                        rdev->journal_tail = le64_to_cpu(sb->journal_tail);
                        if (mddev->recovery_cp == MaxSector)
                                set_bit(MD_JOURNAL_CLEAN, &mddev->flags);
-                       rdev->raid_disk = mddev->raid_disks;
+                       rdev->raid_disk = 0;
                        break;
                default:
                        rdev->saved_raid_disk = role;
@@ -2773,6 +2774,7 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len)
                /* Activating a spare .. or possibly reactivating
                 * if we ever get bitmaps working here.
                 */
+               int err;
 
                if (rdev->raid_disk != -1)
                        return -EBUSY;
@@ -2794,9 +2796,15 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len)
                        rdev->saved_raid_disk = -1;
                clear_bit(In_sync, &rdev->flags);
                clear_bit(Bitmap_sync, &rdev->flags);
-               remove_and_add_spares(rdev->mddev, rdev);
-               if (rdev->raid_disk == -1)
-                       return -EBUSY;
+               err = rdev->mddev->pers->
+                       hot_add_disk(rdev->mddev, rdev);
+               if (err) {
+                       rdev->raid_disk = -1;
+                       return err;
+               } else
+                       sysfs_notify_dirent_safe(rdev->sysfs_state);
+               if (sysfs_link_rdev(rdev->mddev, rdev))
+                       /* failure here is OK */;
                /* don't wakeup anyone, leave that to userspace. */
        } else {
                if (slot >= rdev->mddev->raid_disks &&
@@ -4318,8 +4326,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
                        }
                        mddev_unlock(mddev);
                }
-       } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
-                  test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
+       } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
                return -EBUSY;
        else if (cmd_match(page, "resync"))
                clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
@@ -4332,8 +4339,12 @@ action_store(struct mddev *mddev, const char *page, size_t len)
                        return -EINVAL;
                err = mddev_lock(mddev);
                if (!err) {
-                       clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
-                       err = mddev->pers->start_reshape(mddev);
+                       if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
+                               err =  -EBUSY;
+                       else {
+                               clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+                               err = mddev->pers->start_reshape(mddev);
+                       }
                        mddev_unlock(mddev);
                }
                if (err)
index 2bea51edfab707645a6d6b8a5b6c79bb0c6dde64..ca0b643fe3c18070b417a66daedb571457b440ca 100644 (file)
@@ -566,7 +566,9 @@ static inline char * mdname (struct mddev * mddev)
 static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev)
 {
        char nm[20];
-       if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) {
+       if (!test_bit(Replacement, &rdev->flags) &&
+           !test_bit(Journal, &rdev->flags) &&
+           mddev->kobj.sd) {
                sprintf(nm, "rd%d", rdev->raid_disk);
                return sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
        } else
@@ -576,7 +578,9 @@ static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev)
 static inline void sysfs_unlink_rdev(struct mddev *mddev, struct md_rdev *rdev)
 {
        char nm[20];
-       if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) {
+       if (!test_bit(Replacement, &rdev->flags) &&
+           !test_bit(Journal, &rdev->flags) &&
+           mddev->kobj.sd) {
                sprintf(nm, "rd%d", rdev->raid_disk);
                sysfs_remove_link(&mddev->kobj, nm);
        }
index 41d70bc9ba2f879a2549868861afb74471140525..84e597e1c4890cd911243c511d1a65e39232e98e 100644 (file)
@@ -1946,6 +1946,8 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
 
        first = i;
        fbio = r10_bio->devs[i].bio;
+       fbio->bi_iter.bi_size = r10_bio->sectors << 9;
+       fbio->bi_iter.bi_idx = 0;
 
        vcnt = (r10_bio->sectors + (PAGE_SIZE >> 9) - 1) >> (PAGE_SHIFT - 9);
        /* now find blocks with errors */
@@ -1989,7 +1991,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
                bio_reset(tbio);
 
                tbio->bi_vcnt = vcnt;
-               tbio->bi_iter.bi_size = r10_bio->sectors << 9;
+               tbio->bi_iter.bi_size = fbio->bi_iter.bi_size;
                tbio->bi_rw = WRITE;
                tbio->bi_private = r10_bio;
                tbio->bi_iter.bi_sector = r10_bio->devs[i].addr;
index 8616fa8193bca06bb806dc48b14d4e7dc6e21aef..c2e60b4f292d1d8d9791b5c44b0fa76c0ffd854b 100644 (file)
@@ -805,11 +805,11 @@ static void ivtv_init_struct2(struct ivtv *itv)
 {
        int i;
 
-       for (i = 0; i < IVTV_CARD_MAX_VIDEO_INPUTS - 1; i++)
+       for (i = 0; i < IVTV_CARD_MAX_VIDEO_INPUTS; i++)
                if (itv->card->video_inputs[i].video_type == 0)
                        break;
        itv->nof_inputs = i;
-       for (i = 0; i < IVTV_CARD_MAX_AUDIO_INPUTS - 1; i++)
+       for (i = 0; i < IVTV_CARD_MAX_AUDIO_INPUTS; i++)
                if (itv->card->audio_inputs[i].audio_type == 0)
                        break;
        itv->nof_audio_inputs = i;
index fcbb49757614487aa0a88e2740bc0dcd4ff73236..565a59310747680858bb2bf30543e05becd579a0 100644 (file)
@@ -134,7 +134,7 @@ struct airspy {
        int            urbs_submitted;
 
        /* USB control message buffer */
-       #define BUF_SIZE 24
+       #define BUF_SIZE 128
        u8 buf[BUF_SIZE];
 
        /* Current configuration */
index e05bfec90f4608b0d8ebce199351dfe89db11994..0fe5cb2c260c2f771484d99bf25809cc23943ffb 100644 (file)
 #include <media/videobuf2-v4l2.h>
 #include <media/videobuf2-vmalloc.h>
 
+/*
+ * Used Avago MGA-81563 RF amplifier could be destroyed pretty easily with too
+ * strong signal or transmitting to bad antenna.
+ * Set RF gain control to 'grabbed' state by default for sure.
+ */
+static bool hackrf_enable_rf_gain_ctrl;
+module_param_named(enable_rf_gain_ctrl, hackrf_enable_rf_gain_ctrl, bool, 0644);
+MODULE_PARM_DESC(enable_rf_gain_ctrl, "enable RX/TX RF amplifier control (warn: could damage amplifier)");
+
 /* HackRF USB API commands (from HackRF Library) */
 enum {
        CMD_SET_TRANSCEIVER_MODE           = 0x01,
@@ -1451,6 +1460,7 @@ static int hackrf_probe(struct usb_interface *intf,
                dev_err(dev->dev, "Could not initialize controls\n");
                goto err_v4l2_ctrl_handler_free_rx;
        }
+       v4l2_ctrl_grab(dev->rx_rf_gain, !hackrf_enable_rf_gain_ctrl);
        v4l2_ctrl_handler_setup(&dev->rx_ctrl_handler);
 
        /* Register controls for transmitter */
@@ -1471,6 +1481,7 @@ static int hackrf_probe(struct usb_interface *intf,
                dev_err(dev->dev, "Could not initialize controls\n");
                goto err_v4l2_ctrl_handler_free_tx;
        }
+       v4l2_ctrl_grab(dev->tx_rf_gain, !hackrf_enable_rf_gain_ctrl);
        v4l2_ctrl_handler_setup(&dev->tx_ctrl_handler);
 
        /* Register the v4l2_device structure */
@@ -1530,7 +1541,7 @@ err_v4l2_ctrl_handler_free_rx:
 err_kfree:
        kfree(dev);
 err:
-       dev_dbg(dev->dev, "failed=%d\n", ret);
+       dev_dbg(&intf->dev, "failed=%d\n", ret);
        return ret;
 }
 
index e87459f6d686d011d6d11f902b78053f083e1b7a..acd1460cf7871c4ef4cffb0f0e196f41083aae36 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/compiler.h>
+#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/slab.h>
index 669c3452f278fb0e365570872893855c9ce21e2c..9ed6038e47d210df74ec678de7cf8220797bf815 100644 (file)
@@ -46,10 +46,18 @@ static int parse_ofpart_partitions(struct mtd_info *master,
 
        ofpart_node = of_get_child_by_name(mtd_node, "partitions");
        if (!ofpart_node) {
-               pr_warn("%s: 'partitions' subnode not found on %s. Trying to parse direct subnodes as partitions.\n",
-                       master->name, mtd_node->full_name);
+               /*
+                * We might get here even when ofpart isn't used at all (e.g.,
+                * when using another parser), so don't be louder than
+                * KERN_DEBUG
+                */
+               pr_debug("%s: 'partitions' subnode not found on %s. Trying to parse direct subnodes as partitions.\n",
+                        master->name, mtd_node->full_name);
                ofpart_node = mtd_node;
                dedicated = false;
+       } else if (!of_device_is_compatible(ofpart_node, "fixed-partitions")) {
+               /* The 'partitions' subnode might be used by another parser */
+               return 0;
        }
 
        /* First count the subnodes */
index b077e43b5ba913b2ba208ed54673c3fe291afc66..c4cb15a3098c0933f607e4f0cba170e978f910ff 100644 (file)
@@ -236,7 +236,7 @@ int ubi_debugfs_init(void)
 
        dfs_rootdir = debugfs_create_dir("ubi", NULL);
        if (IS_ERR_OR_NULL(dfs_rootdir)) {
-               int err = dfs_rootdir ? -ENODEV : PTR_ERR(dfs_rootdir);
+               int err = dfs_rootdir ? PTR_ERR(dfs_rootdir) : -ENODEV;
 
                pr_err("UBI error: cannot create \"ubi\" debugfs directory, error %d\n",
                       err);
index 1fc23e48fe8e49fc947c972cca179399a60a37ec..10cf3b549959ce46f9c517b77fbcdd84e274a3d2 100644 (file)
@@ -1299,7 +1299,7 @@ static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
        if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err))
                goto exit;
 
-       crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC);
+       crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC);
        hdr_crc = be32_to_cpu(vid_hdr->hdr_crc);
        if (hdr_crc != crc) {
                ubi_err(ubi, "bad VID header CRC at PEB %d, calculated %#08x, read %#08x",
index eb4489f9082fe84345d2ec68b0f8723888e5c177..56065632a5b85ebf50022f883e1edc968a069f93 100644 (file)
@@ -603,6 +603,7 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
        return 0;
 }
 
+static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk);
 /**
  * do_sync_erase - run the erase worker synchronously.
  * @ubi: UBI device description object
@@ -615,20 +616,16 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
 static int do_sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
                         int vol_id, int lnum, int torture)
 {
-       struct ubi_work *wl_wrk;
+       struct ubi_work wl_wrk;
 
        dbg_wl("sync erase of PEB %i", e->pnum);
 
-       wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS);
-       if (!wl_wrk)
-               return -ENOMEM;
-
-       wl_wrk->e = e;
-       wl_wrk->vol_id = vol_id;
-       wl_wrk->lnum = lnum;
-       wl_wrk->torture = torture;
+       wl_wrk.e = e;
+       wl_wrk.vol_id = vol_id;
+       wl_wrk.lnum = lnum;
+       wl_wrk.torture = torture;
 
-       return erase_worker(ubi, wl_wrk, 0);
+       return __erase_worker(ubi, &wl_wrk);
 }
 
 /**
@@ -1014,7 +1011,7 @@ out_unlock:
 }
 
 /**
- * erase_worker - physical eraseblock erase worker function.
+ * __erase_worker - physical eraseblock erase worker function.
  * @ubi: UBI device description object
  * @wl_wrk: the work object
  * @shutdown: non-zero if the worker has to free memory and exit
@@ -1025,8 +1022,7 @@ out_unlock:
  * needed. Returns zero in case of success and a negative error code in case of
  * failure.
  */
-static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
-                       int shutdown)
+static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
 {
        struct ubi_wl_entry *e = wl_wrk->e;
        int pnum = e->pnum;
@@ -1034,21 +1030,11 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
        int lnum = wl_wrk->lnum;
        int err, available_consumed = 0;
 
-       if (shutdown) {
-               dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec);
-               kfree(wl_wrk);
-               wl_entry_destroy(ubi, e);
-               return 0;
-       }
-
        dbg_wl("erase PEB %d EC %d LEB %d:%d",
               pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum);
 
        err = sync_erase(ubi, e, wl_wrk->torture);
        if (!err) {
-               /* Fine, we've erased it successfully */
-               kfree(wl_wrk);
-
                spin_lock(&ubi->wl_lock);
                wl_tree_add(e, &ubi->free);
                ubi->free_count++;
@@ -1066,7 +1052,6 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
        }
 
        ubi_err(ubi, "failed to erase PEB %d, error %d", pnum, err);
-       kfree(wl_wrk);
 
        if (err == -EINTR || err == -ENOMEM || err == -EAGAIN ||
            err == -EBUSY) {
@@ -1075,6 +1060,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
                /* Re-schedule the LEB for erasure */
                err1 = schedule_erase(ubi, e, vol_id, lnum, 0);
                if (err1) {
+                       wl_entry_destroy(ubi, e);
                        err = err1;
                        goto out_ro;
                }
@@ -1150,6 +1136,25 @@ out_ro:
        return err;
 }
 
+static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
+                         int shutdown)
+{
+       int ret;
+
+       if (shutdown) {
+               struct ubi_wl_entry *e = wl_wrk->e;
+
+               dbg_wl("cancel erasure of PEB %d EC %d", e->pnum, e->ec);
+               kfree(wl_wrk);
+               wl_entry_destroy(ubi, e);
+               return 0;
+       }
+
+       ret = __erase_worker(ubi, wl_wrk);
+       kfree(wl_wrk);
+       return ret;
+}
+
 /**
  * ubi_wl_put_peb - return a PEB to the wear-leveling sub-system.
  * @ubi: UBI device description object
index e481f3710bd38a330d00501c8bd4afadff9de8ff..1049c34e7d430fab13e8d36e54af1b049eb02a03 100644 (file)
@@ -258,18 +258,18 @@ static struct xenvif_rx_meta *get_next_rx_buffer(struct xenvif_queue *queue,
                                                 struct netrx_pending_operations *npo)
 {
        struct xenvif_rx_meta *meta;
-       struct xen_netif_rx_request *req;
+       struct xen_netif_rx_request req;
 
-       req = RING_GET_REQUEST(&queue->rx, queue->rx.req_cons++);
+       RING_COPY_REQUEST(&queue->rx, queue->rx.req_cons++, &req);
 
        meta = npo->meta + npo->meta_prod++;
        meta->gso_type = XEN_NETIF_GSO_TYPE_NONE;
        meta->gso_size = 0;
        meta->size = 0;
-       meta->id = req->id;
+       meta->id = req.id;
 
        npo->copy_off = 0;
-       npo->copy_gref = req->gref;
+       npo->copy_gref = req.gref;
 
        return meta;
 }
@@ -424,7 +424,7 @@ static int xenvif_gop_skb(struct sk_buff *skb,
        struct xenvif *vif = netdev_priv(skb->dev);
        int nr_frags = skb_shinfo(skb)->nr_frags;
        int i;
-       struct xen_netif_rx_request *req;
+       struct xen_netif_rx_request req;
        struct xenvif_rx_meta *meta;
        unsigned char *data;
        int head = 1;
@@ -443,15 +443,15 @@ static int xenvif_gop_skb(struct sk_buff *skb,
 
        /* Set up a GSO prefix descriptor, if necessary */
        if ((1 << gso_type) & vif->gso_prefix_mask) {
-               req = RING_GET_REQUEST(&queue->rx, queue->rx.req_cons++);
+               RING_COPY_REQUEST(&queue->rx, queue->rx.req_cons++, &req);
                meta = npo->meta + npo->meta_prod++;
                meta->gso_type = gso_type;
                meta->gso_size = skb_shinfo(skb)->gso_size;
                meta->size = 0;
-               meta->id = req->id;
+               meta->id = req.id;
        }
 
-       req = RING_GET_REQUEST(&queue->rx, queue->rx.req_cons++);
+       RING_COPY_REQUEST(&queue->rx, queue->rx.req_cons++, &req);
        meta = npo->meta + npo->meta_prod++;
 
        if ((1 << gso_type) & vif->gso_mask) {
@@ -463,9 +463,9 @@ static int xenvif_gop_skb(struct sk_buff *skb,
        }
 
        meta->size = 0;
-       meta->id = req->id;
+       meta->id = req.id;
        npo->copy_off = 0;
-       npo->copy_gref = req->gref;
+       npo->copy_gref = req.gref;
 
        data = skb->data;
        while (data < skb_tail_pointer(skb)) {
@@ -679,9 +679,7 @@ static void tx_add_credit(struct xenvif_queue *queue)
         * Allow a burst big enough to transmit a jumbo packet of up to 128kB.
         * Otherwise the interface can seize up due to insufficient credit.
         */
-       max_burst = RING_GET_REQUEST(&queue->tx, queue->tx.req_cons)->size;
-       max_burst = min(max_burst, 131072UL);
-       max_burst = max(max_burst, queue->credit_bytes);
+       max_burst = max(131072UL, queue->credit_bytes);
 
        /* Take care that adding a new chunk of credit doesn't wrap to zero. */
        max_credit = queue->remaining_credit + queue->credit_bytes;
@@ -711,7 +709,7 @@ static void xenvif_tx_err(struct xenvif_queue *queue,
                spin_unlock_irqrestore(&queue->response_lock, flags);
                if (cons == end)
                        break;
-               txp = RING_GET_REQUEST(&queue->tx, cons++);
+               RING_COPY_REQUEST(&queue->tx, cons++, txp);
        } while (1);
        queue->tx.req_cons = cons;
 }
@@ -778,8 +776,7 @@ static int xenvif_count_requests(struct xenvif_queue *queue,
                if (drop_err)
                        txp = &dropped_tx;
 
-               memcpy(txp, RING_GET_REQUEST(&queue->tx, cons + slots),
-                      sizeof(*txp));
+               RING_COPY_REQUEST(&queue->tx, cons + slots, txp);
 
                /* If the guest submitted a frame >= 64 KiB then
                 * first->size overflowed and following slots will
@@ -1112,8 +1109,7 @@ static int xenvif_get_extras(struct xenvif_queue *queue,
                        return -EBADR;
                }
 
-               memcpy(&extra, RING_GET_REQUEST(&queue->tx, cons),
-                      sizeof(extra));
+               RING_COPY_REQUEST(&queue->tx, cons, &extra);
                if (unlikely(!extra.type ||
                             extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
                        queue->tx.req_cons = ++cons;
@@ -1322,7 +1318,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
 
                idx = queue->tx.req_cons;
                rmb(); /* Ensure that we see the request before we copy it. */
-               memcpy(&txreq, RING_GET_REQUEST(&queue->tx, idx), sizeof(txreq));
+               RING_COPY_REQUEST(&queue->tx, idx, &txreq);
 
                /* Credit-based scheduling. */
                if (txreq.size > queue->remaining_credit &&
index 9e294ff4e652a2bb8daa9e3f4a94cc09e8bb8b88..0c67b57be83c4630a89c670acbbd150b65ec667f 100644 (file)
@@ -2540,8 +2540,17 @@ static void nvme_ns_remove(struct nvme_ns *ns)
 {
        bool kill = nvme_io_incapable(ns->dev) && !blk_queue_dying(ns->queue);
 
-       if (kill)
+       if (kill) {
                blk_set_queue_dying(ns->queue);
+
+               /*
+                * The controller was shutdown first if we got here through
+                * device removal. The shutdown may requeue outstanding
+                * requests. These need to be aborted immediately so
+                * del_gendisk doesn't block indefinitely for their completion.
+                */
+               blk_mq_abort_requeue_list(ns->queue);
+       }
        if (ns->disk->flags & GENHD_FL_UP)
                del_gendisk(ns->disk);
        if (kill || !blk_queue_dying(ns->queue)) {
@@ -2977,6 +2986,15 @@ static void nvme_dev_remove(struct nvme_dev *dev)
 {
        struct nvme_ns *ns, *next;
 
+       if (nvme_io_incapable(dev)) {
+               /*
+                * If the device is not capable of IO (surprise hot-removal,
+                * for example), we need to quiesce prior to deleting the
+                * namespaces. This will end outstanding requests and prevent
+                * attempts to sync dirty data.
+                */
+               nvme_dev_shutdown(dev);
+       }
        list_for_each_entry_safe(ns, next, &dev->namespaces, list)
                nvme_ns_remove(ns);
 }
index 7eb5859dd035fefabea842f40722580cfcdfe64a..03cb3ea2d2c035b32254022b1506fcf52d770655 100644 (file)
@@ -233,6 +233,7 @@ config PHY_SUN9I_USB
        tristate "Allwinner sun9i SoC USB PHY driver"
        depends on ARCH_SUNXI && HAS_IOMEM && OF
        depends on RESET_CONTROLLER
+       depends on USB_COMMON
        select GENERIC_PHY
        help
          Enable this to support the transceiver that is part of Allwinner
index 7ad72b7d2b981b6ff4ae59011fdd5e6c5538ef51..082c03f6438f796af868cb83127f1ce9ca56f83b 100644 (file)
@@ -128,6 +128,7 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev)
        struct phy_provider *provider;
        struct resource *res;
        unsigned cnt = 0;
+       int ret;
 
        if (of_get_child_count(node) == 0) {
                dev_err(dev, "PHY no child node\n");
@@ -154,24 +155,28 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev)
                if (of_property_read_u32(child, "reg", &id)) {
                        dev_err(dev, "missing reg property for %s\n",
                                child->name);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                if (id >= MAX_NUM_PHYS) {
                        dev_err(dev, "invalid PHY id: %u\n", id);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                if (core->phys[id].phy) {
                        dev_err(dev, "duplicated PHY id: %u\n", id);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                p = &core->phys[id];
                p->phy = devm_phy_create(dev, child, &cygnus_pcie_phy_ops);
                if (IS_ERR(p->phy)) {
                        dev_err(dev, "failed to create PHY\n");
-                       return PTR_ERR(p->phy);
+                       ret = PTR_ERR(p->phy);
+                       goto put_child;
                }
 
                p->core = core;
@@ -191,6 +196,9 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev)
        dev_dbg(dev, "registered %u PCIe PHY(s)\n", cnt);
 
        return 0;
+put_child:
+       of_node_put(child);
+       return ret;
 }
 
 static const struct of_device_id cygnus_pcie_phy_match_table[] = {
index 77a2e054fdea0f46ccd3d2841f5f837f80a985e1..f84a33a1bdd935c5a6c171929d172b1a1a67840c 100644 (file)
@@ -195,7 +195,7 @@ static int phy_berlin_sata_probe(struct platform_device *pdev)
        struct phy_provider *phy_provider;
        struct phy_berlin_priv *priv;
        struct resource *res;
-       int i = 0;
+       int ret, i = 0;
        u32 phy_id;
 
        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -237,22 +237,27 @@ static int phy_berlin_sata_probe(struct platform_device *pdev)
                if (of_property_read_u32(child, "reg", &phy_id)) {
                        dev_err(dev, "missing reg property in node %s\n",
                                child->name);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                if (phy_id >= ARRAY_SIZE(phy_berlin_power_down_bits)) {
                        dev_err(dev, "invalid reg in node %s\n", child->name);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                phy_desc = devm_kzalloc(dev, sizeof(*phy_desc), GFP_KERNEL);
-               if (!phy_desc)
-                       return -ENOMEM;
+               if (!phy_desc) {
+                       ret = -ENOMEM;
+                       goto put_child;
+               }
 
                phy = devm_phy_create(dev, NULL, &phy_berlin_sata_ops);
                if (IS_ERR(phy)) {
                        dev_err(dev, "failed to create PHY %d\n", phy_id);
-                       return PTR_ERR(phy);
+                       ret = PTR_ERR(phy);
+                       goto put_child;
                }
 
                phy_desc->phy = phy;
@@ -269,6 +274,9 @@ static int phy_berlin_sata_probe(struct platform_device *pdev)
        phy_provider =
                devm_of_phy_provider_register(dev, phy_berlin_sata_phy_xlate);
        return PTR_ERR_OR_ZERO(phy_provider);
+put_child:
+       of_node_put(child);
+       return ret;
 }
 
 static const struct of_device_id phy_berlin_sata_of_match[] = {
index 8a2cb16a1937d20e88b045868beec28db966be5c..cd9dba8205668d98665d938b13a5e254b74bdb17 100644 (file)
@@ -140,7 +140,7 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
        struct brcm_sata_phy *priv;
        struct resource *res;
        struct phy_provider *provider;
-       int count = 0;
+       int ret, count = 0;
 
        if (of_get_child_count(dn) == 0)
                return -ENODEV;
@@ -163,16 +163,19 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
                if (of_property_read_u32(child, "reg", &id)) {
                        dev_err(dev, "missing reg property in node %s\n",
                                        child->name);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                if (id >= MAX_PORTS) {
                        dev_err(dev, "invalid reg: %u\n", id);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
                if (priv->phys[id].phy) {
                        dev_err(dev, "already registered port %u\n", id);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto put_child;
                }
 
                port = &priv->phys[id];
@@ -182,7 +185,8 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
                port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc");
                if (IS_ERR(port->phy)) {
                        dev_err(dev, "failed to create PHY\n");
-                       return PTR_ERR(port->phy);
+                       ret = PTR_ERR(port->phy);
+                       goto put_child;
                }
 
                phy_set_drvdata(port->phy, port);
@@ -198,6 +202,9 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
        dev_info(dev, "registered %d port(s)\n", count);
 
        return 0;
+put_child:
+       of_node_put(child);
+       return ret;
 }
 
 static struct platform_driver brcm_sata_phy_driver = {
index fc48fac003a62ba124bd7c6820f24d5d040fcbf7..8c7f27db6ad352260f8ad8675758ed365b6390a6 100644 (file)
@@ -636,8 +636,9 @@ EXPORT_SYMBOL_GPL(devm_of_phy_get);
  * @np: node containing the phy
  * @index: index of the phy
  *
- * Gets the phy using _of_phy_get(), and associates a device with it using
- * devres. On driver detach, release function is invoked on the devres data,
+ * Gets the phy using _of_phy_get(), then gets a refcount to it,
+ * and associates a device with it using devres. On driver detach,
+ * release function is invoked on the devres data,
  * then, devres data is freed.
  *
  */
@@ -651,13 +652,21 @@ struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np,
                return ERR_PTR(-ENOMEM);
 
        phy = _of_phy_get(np, index);
-       if (!IS_ERR(phy)) {
-               *ptr = phy;
-               devres_add(dev, ptr);
-       } else {
+       if (IS_ERR(phy)) {
                devres_free(ptr);
+               return phy;
        }
 
+       if (!try_module_get(phy->ops->owner)) {
+               devres_free(ptr);
+               return ERR_PTR(-EPROBE_DEFER);
+       }
+
+       get_device(&phy->dev);
+
+       *ptr = phy;
+       devres_add(dev, ptr);
+
        return phy;
 }
 EXPORT_SYMBOL_GPL(devm_of_phy_get_by_index);
index c47b56b4a2b8892810f00179a53e9eceba7c612c..3acd2a1808dfbf9ccfa5d58467b6defdb793c2bb 100644 (file)
@@ -1226,15 +1226,18 @@ static int miphy28lp_probe(struct platform_device *pdev)
 
                miphy_phy = devm_kzalloc(&pdev->dev, sizeof(*miphy_phy),
                                         GFP_KERNEL);
-               if (!miphy_phy)
-                       return -ENOMEM;
+               if (!miphy_phy) {
+                       ret = -ENOMEM;
+                       goto put_child;
+               }
 
                miphy_dev->phys[port] = miphy_phy;
 
                phy = devm_phy_create(&pdev->dev, child, &miphy28lp_ops);
                if (IS_ERR(phy)) {
                        dev_err(&pdev->dev, "failed to create PHY\n");
-                       return PTR_ERR(phy);
+                       ret = PTR_ERR(phy);
+                       goto put_child;
                }
 
                miphy_dev->phys[port]->phy = phy;
@@ -1242,11 +1245,11 @@ static int miphy28lp_probe(struct platform_device *pdev)
 
                ret = miphy28lp_of_probe(child, miphy_phy);
                if (ret)
-                       return ret;
+                       goto put_child;
 
                ret = miphy28lp_probe_resets(child, miphy_dev->phys[port]);
                if (ret)
-                       return ret;
+                       goto put_child;
 
                phy_set_drvdata(phy, miphy_dev->phys[port]);
                port++;
@@ -1255,6 +1258,9 @@ static int miphy28lp_probe(struct platform_device *pdev)
 
        provider = devm_of_phy_provider_register(&pdev->dev, miphy28lp_xlate);
        return PTR_ERR_OR_ZERO(provider);
+put_child:
+       of_node_put(child);
+       return ret;
 }
 
 static const struct of_device_id miphy28lp_of_match[] = {
index 00a686a073ed6ee804ea96ebcdb0ef3813482a85..e661f3b36eaa0cdf992cde8f88d92644ff585c5e 100644 (file)
@@ -566,22 +566,25 @@ static int miphy365x_probe(struct platform_device *pdev)
 
                miphy_phy = devm_kzalloc(&pdev->dev, sizeof(*miphy_phy),
                                         GFP_KERNEL);
-               if (!miphy_phy)
-                       return -ENOMEM;
+               if (!miphy_phy) {
+                       ret = -ENOMEM;
+                       goto put_child;
+               }
 
                miphy_dev->phys[port] = miphy_phy;
 
                phy = devm_phy_create(&pdev->dev, child, &miphy365x_ops);
                if (IS_ERR(phy)) {
                        dev_err(&pdev->dev, "failed to create PHY\n");
-                       return PTR_ERR(phy);
+                       ret = PTR_ERR(phy);
+                       goto put_child;
                }
 
                miphy_dev->phys[port]->phy = phy;
 
                ret = miphy365x_of_probe(child, miphy_phy);
                if (ret)
-                       return ret;
+                       goto put_child;
 
                phy_set_drvdata(phy, miphy_dev->phys[port]);
 
@@ -591,12 +594,15 @@ static int miphy365x_probe(struct platform_device *pdev)
                                        &miphy_phy->ctrlreg);
                if (ret) {
                        dev_err(&pdev->dev, "No sysconfig offset found\n");
-                       return ret;
+                       goto put_child;
                }
        }
 
        provider = devm_of_phy_provider_register(&pdev->dev, miphy365x_xlate);
        return PTR_ERR_OR_ZERO(provider);
+put_child:
+       of_node_put(child);
+       return ret;
 }
 
 static const struct of_device_id miphy365x_of_match[] = {
index f30b28bd41fe7b11a8cce95e889ae894fef20518..e427c3b788ff35e23a49808116936f0d5f39ffa4 100644 (file)
@@ -415,7 +415,7 @@ static int mt65xx_u3phy_probe(struct platform_device *pdev)
        struct resource *sif_res;
        struct mt65xx_u3phy *u3phy;
        struct resource res;
-       int port;
+       int port, retval;
 
        u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
        if (!u3phy)
@@ -447,31 +447,34 @@ static int mt65xx_u3phy_probe(struct platform_device *pdev)
        for_each_child_of_node(np, child_np) {
                struct mt65xx_phy_instance *instance;
                struct phy *phy;
-               int retval;
 
                instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
-               if (!instance)
-                       return -ENOMEM;
+               if (!instance) {
+                       retval = -ENOMEM;
+                       goto put_child;
+               }
 
                u3phy->phys[port] = instance;
 
                phy = devm_phy_create(dev, child_np, &mt65xx_u3phy_ops);
                if (IS_ERR(phy)) {
                        dev_err(dev, "failed to create phy\n");
-                       return PTR_ERR(phy);
+                       retval = PTR_ERR(phy);
+                       goto put_child;
                }
 
                retval = of_address_to_resource(child_np, 0, &res);
                if (retval) {
                        dev_err(dev, "failed to get address resource(id-%d)\n",
                                port);
-                       return retval;
+                       goto put_child;
                }
 
                instance->port_base = devm_ioremap_resource(&phy->dev, &res);
                if (IS_ERR(instance->port_base)) {
                        dev_err(dev, "failed to remap phy regs\n");
-                       return PTR_ERR(instance->port_base);
+                       retval = PTR_ERR(instance->port_base);
+                       goto put_child;
                }
 
                instance->phy = phy;
@@ -483,6 +486,9 @@ static int mt65xx_u3phy_probe(struct platform_device *pdev)
        provider = devm_of_phy_provider_register(dev, mt65xx_phy_xlate);
 
        return PTR_ERR_OR_ZERO(provider);
+put_child:
+       of_node_put(child_np);
+       return retval;
 }
 
 static const struct of_device_id mt65xx_u3phy_id_table[] = {
index 91d6f342c56596fc2e3fcff18213dba004546c3e..62c43c435194313e7d5ea7049d568cb673857da9 100644 (file)
@@ -108,13 +108,16 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
 
        for_each_available_child_of_node(dev->of_node, child) {
                rk_phy = devm_kzalloc(dev, sizeof(*rk_phy), GFP_KERNEL);
-               if (!rk_phy)
-                       return -ENOMEM;
+               if (!rk_phy) {
+                       err = -ENOMEM;
+                       goto put_child;
+               }
 
                if (of_property_read_u32(child, "reg", &reg_offset)) {
                        dev_err(dev, "missing reg property in node %s\n",
                                child->name);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto put_child;
                }
 
                rk_phy->reg_offset = reg_offset;
@@ -127,18 +130,22 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
                rk_phy->phy = devm_phy_create(dev, child, &ops);
                if (IS_ERR(rk_phy->phy)) {
                        dev_err(dev, "failed to create PHY\n");
-                       return PTR_ERR(rk_phy->phy);
+                       err = PTR_ERR(rk_phy->phy);
+                       goto put_child;
                }
                phy_set_drvdata(rk_phy->phy, rk_phy);
 
                /* only power up usb phy when it use, so disable it when init*/
                err = rockchip_usb_phy_power(rk_phy, 1);
                if (err)
-                       return err;
+                       goto put_child;
        }
 
        phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
        return PTR_ERR_OR_ZERO(phy_provider);
+put_child:
+       of_node_put(child);
+       return err;
 }
 
 static const struct of_device_id rockchip_usb_phy_dt_ids[] = {
index a1ea565fcd46490e58d48e4363318c2ce6970ebc..2e6ca69635aa001531d2b9aca128d001b97d9aca 100644 (file)
@@ -342,12 +342,6 @@ static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset)
        return bcm2835_gpio_get_bit(pc, GPLEV0, offset);
 }
 
-static int bcm2835_gpio_direction_output(struct gpio_chip *chip,
-               unsigned offset, int value)
-{
-       return pinctrl_gpio_direction_output(chip->base + offset);
-}
-
 static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
        struct bcm2835_pinctrl *pc = dev_get_drvdata(chip->dev);
@@ -355,6 +349,13 @@ static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
        bcm2835_gpio_set_bit(pc, value ? GPSET0 : GPCLR0, offset);
 }
 
+static int bcm2835_gpio_direction_output(struct gpio_chip *chip,
+               unsigned offset, int value)
+{
+       bcm2835_gpio_set(chip, offset, value);
+       return pinctrl_gpio_direction_output(chip->base + offset);
+}
+
 static int bcm2835_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 {
        struct bcm2835_pinctrl *pc = dev_get_drvdata(chip->dev);
index 37a037543d299115a09e6a4106f1592acc9566a9..587d1ff6210efb62341b792d0318b412c0a4d046 100644 (file)
@@ -299,7 +299,7 @@ static const struct pinctrl_pin_desc vf610_pinctrl_pads[] = {
 static struct imx_pinctrl_soc_info vf610_pinctrl_info = {
        .pins = vf610_pinctrl_pads,
        .npins = ARRAY_SIZE(vf610_pinctrl_pads),
-       .flags = SHARE_MUX_CONF_REG,
+       .flags = SHARE_MUX_CONF_REG | ZERO_OFFSET_VALID,
 };
 
 static const struct of_device_id vf610_pinctrl_of_match[] = {
index e42d5d4183f57ff0dc0d942254f5925dabd3c07a..5979d38c46b254965e8a7782de9a6c902894ce9a 100644 (file)
@@ -28,6 +28,7 @@
                .padcfglock_offset = BXT_PADCFGLOCK,    \
                .hostown_offset = BXT_HOSTSW_OWN,       \
                .ie_offset = BXT_GPI_IE,                \
+               .gpp_size = 32,                         \
                .pin_base = (s),                        \
                .npins = ((e) - (s) + 1),               \
        }
index 392e28d3f48d0bee1a4087154e904c7dfdc0faa7..26f6b6ffea5b23fac04224d9772996db12bc6176 100644 (file)
@@ -25,9 +25,6 @@
 
 #include "pinctrl-intel.h"
 
-/* Maximum number of pads in each group */
-#define NPADS_IN_GPP                   24
-
 /* Offset from regs */
 #define PADBAR                         0x00c
 #define GPI_IS                         0x100
@@ -37,6 +34,7 @@
 #define PADOWN_BITS                    4
 #define PADOWN_SHIFT(p)                        ((p) % 8 * PADOWN_BITS)
 #define PADOWN_MASK(p)                 (0xf << PADOWN_SHIFT(p))
+#define PADOWN_GPP(p)                  ((p) / 8)
 
 /* Offset from pad_regs */
 #define PADCFG0                                0x000
@@ -142,7 +140,7 @@ static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl, unsigned pin,
 static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned pin)
 {
        const struct intel_community *community;
-       unsigned padno, gpp, gpp_offset, offset;
+       unsigned padno, gpp, offset, group;
        void __iomem *padown;
 
        community = intel_get_community(pctrl, pin);
@@ -152,9 +150,9 @@ static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned pin)
                return true;
 
        padno = pin_to_padno(community, pin);
-       gpp = padno / NPADS_IN_GPP;
-       gpp_offset = padno % NPADS_IN_GPP;
-       offset = community->padown_offset + gpp * 16 + (gpp_offset / 8) * 4;
+       group = padno / community->gpp_size;
+       gpp = PADOWN_GPP(padno % community->gpp_size);
+       offset = community->padown_offset + 0x10 * group + gpp * 4;
        padown = community->regs + offset;
 
        return !(readl(padown) & PADOWN_MASK(padno));
@@ -173,11 +171,11 @@ static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned pin)
                return false;
 
        padno = pin_to_padno(community, pin);
-       gpp = padno / NPADS_IN_GPP;
+       gpp = padno / community->gpp_size;
        offset = community->hostown_offset + gpp * 4;
        hostown = community->regs + offset;
 
-       return !(readl(hostown) & BIT(padno % NPADS_IN_GPP));
+       return !(readl(hostown) & BIT(padno % community->gpp_size));
 }
 
 static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
@@ -193,7 +191,7 @@ static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
                return false;
 
        padno = pin_to_padno(community, pin);
-       gpp = padno / NPADS_IN_GPP;
+       gpp = padno / community->gpp_size;
 
        /*
         * If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad,
@@ -202,12 +200,12 @@ static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
         */
        offset = community->padcfglock_offset + gpp * 8;
        value = readl(community->regs + offset);
-       if (value & BIT(pin % NPADS_IN_GPP))
+       if (value & BIT(pin % community->gpp_size))
                return true;
 
        offset = community->padcfglock_offset + 4 + gpp * 8;
        value = readl(community->regs + offset);
-       if (value & BIT(pin % NPADS_IN_GPP))
+       if (value & BIT(pin % community->gpp_size))
                return true;
 
        return false;
@@ -663,8 +661,8 @@ static void intel_gpio_irq_ack(struct irq_data *d)
        community = intel_get_community(pctrl, pin);
        if (community) {
                unsigned padno = pin_to_padno(community, pin);
-               unsigned gpp_offset = padno % NPADS_IN_GPP;
-               unsigned gpp = padno / NPADS_IN_GPP;
+               unsigned gpp_offset = padno % community->gpp_size;
+               unsigned gpp = padno / community->gpp_size;
 
                writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
        }
@@ -685,8 +683,8 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
        community = intel_get_community(pctrl, pin);
        if (community) {
                unsigned padno = pin_to_padno(community, pin);
-               unsigned gpp_offset = padno % NPADS_IN_GPP;
-               unsigned gpp = padno / NPADS_IN_GPP;
+               unsigned gpp_offset = padno % community->gpp_size;
+               unsigned gpp = padno / community->gpp_size;
                void __iomem *reg;
                u32 value;
 
@@ -780,8 +778,8 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
                return -EINVAL;
 
        padno = pin_to_padno(community, pin);
-       gpp = padno / NPADS_IN_GPP;
-       gpp_offset = padno % NPADS_IN_GPP;
+       gpp = padno / community->gpp_size;
+       gpp_offset = padno % community->gpp_size;
 
        /* Clear the existing wake status */
        writel(BIT(gpp_offset), community->regs + GPI_GPE_STS + gpp * 4);
@@ -819,14 +817,14 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
                /* Only interrupts that are enabled */
                pending &= enabled;
 
-               for_each_set_bit(gpp_offset, &pending, NPADS_IN_GPP) {
+               for_each_set_bit(gpp_offset, &pending, community->gpp_size) {
                        unsigned padno, irq;
 
                        /*
                         * The last group in community can have less pins
                         * than NPADS_IN_GPP.
                         */
-                       padno = gpp_offset + gpp * NPADS_IN_GPP;
+                       padno = gpp_offset + gpp * community->gpp_size;
                        if (padno >= community->npins)
                                break;
 
@@ -1002,7 +1000,8 @@ int intel_pinctrl_probe(struct platform_device *pdev,
 
                community->regs = regs;
                community->pad_regs = regs + padbar;
-               community->ngpps = DIV_ROUND_UP(community->npins, NPADS_IN_GPP);
+               community->ngpps = DIV_ROUND_UP(community->npins,
+                                               community->gpp_size);
        }
 
        irq = platform_get_irq(pdev, 0);
index 4ec8b572a288fbc337f5b40affdfbd012634a028..b60215793017bb95b42d39692020aa2f4c41ac0d 100644 (file)
@@ -55,6 +55,8 @@ struct intel_function {
  *                  ACPI).
  * @ie_offset: Register offset of GPI_IE from @regs.
  * @pin_base: Starting pin of pins in this community
+ * @gpp_size: Maximum number of pads in each group, such as PADCFGLOCK,
+ *            HOSTSW_OWN,  GPI_IS, GPI_IE, etc.
  * @npins: Number of pins in this community
  * @regs: Community specific common registers (reserved for core driver)
  * @pad_regs: Community specific pad registers (reserved for core driver)
@@ -68,6 +70,7 @@ struct intel_community {
        unsigned hostown_offset;
        unsigned ie_offset;
        unsigned pin_base;
+       unsigned gpp_size;
        size_t npins;
        void __iomem *regs;
        void __iomem *pad_regs;
index 1de9ae5010db285b53c01d7e67dec2bde7ce5233..c725a5313b4e692df92630535237e4b8374658a7 100644 (file)
@@ -30,6 +30,7 @@
                .padcfglock_offset = SPT_PADCFGLOCK,    \
                .hostown_offset = SPT_HOSTSW_OWN,       \
                .ie_offset = SPT_GPI_IE,                \
+               .gpp_size = 24,                         \
                .pin_base = (s),                        \
                .npins = ((e) - (s) + 1),               \
        }
index cc97f0869791d371c85f7e21c0ca04e1e595ac23..48747c28a43d4ac2fc1bed10f29cd1224ddd10f0 100644 (file)
@@ -1341,10 +1341,13 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu)
 
        for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
                /* check if the domain is locked by BIOS */
-               if (rapl_read_data_raw(rd, FW_LOCK, false, &locked)) {
+               ret = rapl_read_data_raw(rd, FW_LOCK, false, &locked);
+               if (ret)
+                       return ret;
+               if (locked) {
                        pr_info("RAPL package %d domain %s locked by BIOS\n",
                                rp->id, rd->name);
-                               rd->state |= DOMAIN_STATE_BIOS_LOCKED;
+                       rd->state |= DOMAIN_STATE_BIOS_LOCKED;
                }
        }
 
index 284b587da65c5fb20f6e96b8c843e52c0b420415..d6c853bbfa9fcbe0fee8968dda872041c6c8545a 100644 (file)
@@ -483,24 +483,23 @@ static int da9063_rtc_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, rtc);
 
+       rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, DA9063_DRVNAME_RTC,
+                                          &da9063_rtc_ops, THIS_MODULE);
+       if (IS_ERR(rtc->rtc_dev))
+               return PTR_ERR(rtc->rtc_dev);
+
+       da9063_data_to_tm(data, &rtc->alarm_time, rtc);
+       rtc->rtc_sync = false;
+
        irq_alarm = platform_get_irq_byname(pdev, "ALARM");
        ret = devm_request_threaded_irq(&pdev->dev, irq_alarm, NULL,
                                        da9063_alarm_event,
                                        IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                        "ALARM", rtc);
-       if (ret) {
+       if (ret)
                dev_err(&pdev->dev, "Failed to request ALARM IRQ %d: %d\n",
                        irq_alarm, ret);
-               return ret;
-       }
-
-       rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, DA9063_DRVNAME_RTC,
-                                          &da9063_rtc_ops, THIS_MODULE);
-       if (IS_ERR(rtc->rtc_dev))
-               return PTR_ERR(rtc->rtc_dev);
 
-       da9063_data_to_tm(data, &rtc->alarm_time, rtc);
-       rtc->rtc_sync = false;
        return ret;
 }
 
index 91ca0bc1b484b4af1120b3e1701a931a4e1ff6fc..35c9aada07c8ef3a19f44cf8d4a3e8811f484e3f 100644 (file)
@@ -56,6 +56,42 @@ struct rk808_rtc {
        int irq;
 };
 
+/*
+ * The Rockchip calendar used by the RK808 counts November with 31 days. We use
+ * these translation functions to convert its dates to/from the Gregorian
+ * calendar used by the rest of the world. We arbitrarily define Jan 1st, 2016
+ * as the day when both calendars were in sync, and treat all other dates
+ * relative to that.
+ * NOTE: Other system software (e.g. firmware) that reads the same hardware must
+ * implement this exact same conversion algorithm, with the same anchor date.
+ */
+static time64_t nov2dec_transitions(struct rtc_time *tm)
+{
+       return (tm->tm_year + 1900) - 2016 + (tm->tm_mon + 1 > 11 ? 1 : 0);
+}
+
+static void rockchip_to_gregorian(struct rtc_time *tm)
+{
+       /* If it's Nov 31st, rtc_tm_to_time64() will count that like Dec 1st */
+       time64_t time = rtc_tm_to_time64(tm);
+       rtc_time64_to_tm(time + nov2dec_transitions(tm) * 86400, tm);
+}
+
+static void gregorian_to_rockchip(struct rtc_time *tm)
+{
+       time64_t extra_days = nov2dec_transitions(tm);
+       time64_t time = rtc_tm_to_time64(tm);
+       rtc_time64_to_tm(time - extra_days * 86400, tm);
+
+       /* Compensate if we went back over Nov 31st (will work up to 2381) */
+       if (nov2dec_transitions(tm) < extra_days) {
+               if (tm->tm_mon + 1 == 11)
+                       tm->tm_mday++;  /* This may result in 31! */
+               else
+                       rtc_time64_to_tm(time - (extra_days - 1) * 86400, tm);
+       }
+}
+
 /* Read current time and date in RTC */
 static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 {
@@ -101,9 +137,10 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
        tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK)) - 1;
        tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 100;
        tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK);
+       rockchip_to_gregorian(tm);
        dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
                1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
-               tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec);
+               tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
 
        return ret;
 }
@@ -116,6 +153,10 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
        u8 rtc_data[NUM_TIME_REGS];
        int ret;
 
+       dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+               1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
+               tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+       gregorian_to_rockchip(tm);
        rtc_data[0] = bin2bcd(tm->tm_sec);
        rtc_data[1] = bin2bcd(tm->tm_min);
        rtc_data[2] = bin2bcd(tm->tm_hour);
@@ -123,9 +164,6 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
        rtc_data[4] = bin2bcd(tm->tm_mon + 1);
        rtc_data[5] = bin2bcd(tm->tm_year - 100);
        rtc_data[6] = bin2bcd(tm->tm_wday);
-       dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
-               1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
-               tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec);
 
        /* Stop RTC while updating the RTC registers */
        ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
@@ -170,6 +208,7 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
        alrm->time.tm_mday = bcd2bin(alrm_data[3] & DAYS_REG_MSK);
        alrm->time.tm_mon = (bcd2bin(alrm_data[4] & MONTHS_REG_MSK)) - 1;
        alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100;
+       rockchip_to_gregorian(&alrm->time);
 
        ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg);
        if (ret) {
@@ -227,6 +266,7 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
                alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
                alrm->time.tm_min, alrm->time.tm_sec);
 
+       gregorian_to_rockchip(&alrm->time);
        alrm_data[0] = bin2bcd(alrm->time.tm_sec);
        alrm_data[1] = bin2bcd(alrm->time.tm_min);
        alrm_data[2] = bin2bcd(alrm->time.tm_hour);
index 61f768518a34b0e963cd6b569610045a3f65188b..24ec282e15d8ae436e7dab130a4696708e34be9e 100644 (file)
@@ -599,8 +599,10 @@ static enum ap_wait ap_sm_read(struct ap_device *ap_dev)
        status = ap_sm_recv(ap_dev);
        switch (status.response_code) {
        case AP_RESPONSE_NORMAL:
-               if (ap_dev->queue_count > 0)
+               if (ap_dev->queue_count > 0) {
+                       ap_dev->state = AP_STATE_WORKING;
                        return AP_WAIT_AGAIN;
+               }
                ap_dev->state = AP_STATE_IDLE;
                return AP_WAIT_NONE;
        case AP_RESPONSE_NO_PENDING_REPLY:
index b2a1a81e6fc8f048c202b7eca54b2b0b6c22b368..1b831598df7c6544057f23ef69da5ea54bbafcdd 100644 (file)
@@ -984,6 +984,36 @@ static struct virtqueue *virtio_ccw_vq_by_ind(struct virtio_ccw_device *vcdev,
        return vq;
 }
 
+static void virtio_ccw_check_activity(struct virtio_ccw_device *vcdev,
+                                     __u32 activity)
+{
+       if (vcdev->curr_io & activity) {
+               switch (activity) {
+               case VIRTIO_CCW_DOING_READ_FEAT:
+               case VIRTIO_CCW_DOING_WRITE_FEAT:
+               case VIRTIO_CCW_DOING_READ_CONFIG:
+               case VIRTIO_CCW_DOING_WRITE_CONFIG:
+               case VIRTIO_CCW_DOING_WRITE_STATUS:
+               case VIRTIO_CCW_DOING_SET_VQ:
+               case VIRTIO_CCW_DOING_SET_IND:
+               case VIRTIO_CCW_DOING_SET_CONF_IND:
+               case VIRTIO_CCW_DOING_RESET:
+               case VIRTIO_CCW_DOING_READ_VQ_CONF:
+               case VIRTIO_CCW_DOING_SET_IND_ADAPTER:
+               case VIRTIO_CCW_DOING_SET_VIRTIO_REV:
+                       vcdev->curr_io &= ~activity;
+                       wake_up(&vcdev->wait_q);
+                       break;
+               default:
+                       /* don't know what to do... */
+                       dev_warn(&vcdev->cdev->dev,
+                                "Suspicious activity '%08x'\n", activity);
+                       WARN_ON(1);
+                       break;
+               }
+       }
+}
+
 static void virtio_ccw_int_handler(struct ccw_device *cdev,
                                   unsigned long intparm,
                                   struct irb *irb)
@@ -995,6 +1025,12 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
 
        if (!vcdev)
                return;
+       if (IS_ERR(irb)) {
+               vcdev->err = PTR_ERR(irb);
+               virtio_ccw_check_activity(vcdev, activity);
+               /* Don't poke around indicators, something's wrong. */
+               return;
+       }
        /* Check if it's a notification from the host. */
        if ((intparm == 0) &&
            (scsw_stctl(&irb->scsw) ==
@@ -1010,31 +1046,7 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
                        /* Map everything else to -EIO. */
                        vcdev->err = -EIO;
        }
-       if (vcdev->curr_io & activity) {
-               switch (activity) {
-               case VIRTIO_CCW_DOING_READ_FEAT:
-               case VIRTIO_CCW_DOING_WRITE_FEAT:
-               case VIRTIO_CCW_DOING_READ_CONFIG:
-               case VIRTIO_CCW_DOING_WRITE_CONFIG:
-               case VIRTIO_CCW_DOING_WRITE_STATUS:
-               case VIRTIO_CCW_DOING_SET_VQ:
-               case VIRTIO_CCW_DOING_SET_IND:
-               case VIRTIO_CCW_DOING_SET_CONF_IND:
-               case VIRTIO_CCW_DOING_RESET:
-               case VIRTIO_CCW_DOING_READ_VQ_CONF:
-               case VIRTIO_CCW_DOING_SET_IND_ADAPTER:
-               case VIRTIO_CCW_DOING_SET_VIRTIO_REV:
-                       vcdev->curr_io &= ~activity;
-                       wake_up(&vcdev->wait_q);
-                       break;
-               default:
-                       /* don't know what to do... */
-                       dev_warn(&cdev->dev, "Suspicious activity '%08x'\n",
-                                activity);
-                       WARN_ON(1);
-                       break;
-               }
-       }
+       virtio_ccw_check_activity(vcdev, activity);
        for_each_set_bit(i, &vcdev->indicators,
                         sizeof(vcdev->indicators) * BITS_PER_BYTE) {
                /* The bit clear must happen before the vring kick. */
index e4b7998379485454d26e39f6a5a91917a155ffbb..459abe1dcc87a6dfc1beca5672dc3d59d88bdbd2 100644 (file)
@@ -219,13 +219,13 @@ static int sdev_runtime_suspend(struct device *dev)
        struct scsi_device *sdev = to_scsi_device(dev);
        int err = 0;
 
-       if (pm && pm->runtime_suspend) {
-               err = blk_pre_runtime_suspend(sdev->request_queue);
-               if (err)
-                       return err;
+       err = blk_pre_runtime_suspend(sdev->request_queue);
+       if (err)
+               return err;
+       if (pm && pm->runtime_suspend)
                err = pm->runtime_suspend(dev);
-               blk_post_runtime_suspend(sdev->request_queue, err);
-       }
+       blk_post_runtime_suspend(sdev->request_queue, err);
+
        return err;
 }
 
@@ -248,11 +248,11 @@ static int sdev_runtime_resume(struct device *dev)
        const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
        int err = 0;
 
-       if (pm && pm->runtime_resume) {
-               blk_pre_runtime_resume(sdev->request_queue);
+       blk_pre_runtime_resume(sdev->request_queue);
+       if (pm && pm->runtime_resume)
                err = pm->runtime_resume(dev);
-               blk_post_runtime_resume(sdev->request_queue, err);
-       }
+       blk_post_runtime_resume(sdev->request_queue, err);
+
        return err;
 }
 
index dcb0d76d7312847d37809df1f5763206567d5daf..044d06410d4c86c0dc88071bb0de668dd91bb0e2 100644 (file)
@@ -84,6 +84,7 @@ static void init_device_slot_control(unsigned char *dest_desc,
 static int ses_recv_diag(struct scsi_device *sdev, int page_code,
                         void *buf, int bufflen)
 {
+       int ret;
        unsigned char cmd[] = {
                RECEIVE_DIAGNOSTIC,
                1,              /* Set PCV bit */
@@ -92,9 +93,26 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code,
                bufflen & 0xff,
                0
        };
+       unsigned char recv_page_code;
 
-       return scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
+       ret =  scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
                                NULL, SES_TIMEOUT, SES_RETRIES, NULL);
+       if (unlikely(!ret))
+               return ret;
+
+       recv_page_code = ((unsigned char *)buf)[0];
+
+       if (likely(recv_page_code == page_code))
+               return ret;
+
+       /* successful diagnostic but wrong page code.  This happens to some
+        * USB devices, just print a message and pretend there was an error */
+
+       sdev_printk(KERN_ERR, sdev,
+                   "Wrong diagnostic page; asked for %d got %u\n",
+                   page_code, recv_page_code);
+
+       return -EINVAL;
 }
 
 static int ses_send_diag(struct scsi_device *sdev, int page_code,
@@ -541,7 +559,15 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
                        if (desc_ptr)
                                desc_ptr += len;
 
-                       if (addl_desc_ptr)
+                       if (addl_desc_ptr &&
+                           /* only find additional descriptions for specific devices */
+                           (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
+                            type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE ||
+                            type_ptr[0] == ENCLOSURE_COMPONENT_SAS_EXPANDER ||
+                            /* these elements are optional */
+                            type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT ||
+                            type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT ||
+                            type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS))
                                addl_desc_ptr += addl_desc_ptr[1] + 2;
 
                }
index 59a11437db7090f9c8464f8ca0584c789be2e997..39412c9097c6a240466c51c941ec890a4612542e 100644 (file)
@@ -167,7 +167,7 @@ static inline int is_double_byte_mode(struct fsl_dspi *dspi)
 {
        unsigned int val;
 
-       regmap_read(dspi->regmap, SPI_CTAR(dspi->cs), &val);
+       regmap_read(dspi->regmap, SPI_CTAR(0), &val);
 
        return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1;
 }
@@ -257,7 +257,7 @@ static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word)
 
        return  SPI_PUSHR_TXDATA(d16) |
                SPI_PUSHR_PCS(dspi->cs) |
-               SPI_PUSHR_CTAS(dspi->cs) |
+               SPI_PUSHR_CTAS(0) |
                SPI_PUSHR_CONT;
 }
 
@@ -290,7 +290,7 @@ static int dspi_eoq_write(struct fsl_dspi *dspi)
                 */
                if (tx_word && (dspi->len == 1)) {
                        dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM;
-                       regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs),
+                       regmap_update_bits(dspi->regmap, SPI_CTAR(0),
                                        SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8));
                        tx_word = 0;
                }
@@ -339,7 +339,7 @@ static int dspi_tcfq_write(struct fsl_dspi *dspi)
 
        if (tx_word && (dspi->len == 1)) {
                dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM;
-               regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs),
+               regmap_update_bits(dspi->regmap, SPI_CTAR(0),
                                SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8));
                tx_word = 0;
        }
@@ -407,7 +407,7 @@ static int dspi_transfer_one_message(struct spi_master *master,
                regmap_update_bits(dspi->regmap, SPI_MCR,
                                SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF,
                                SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF);
-               regmap_write(dspi->regmap, SPI_CTAR(dspi->cs),
+               regmap_write(dspi->regmap, SPI_CTAR(0),
                                dspi->cur_chip->ctar_val);
 
                trans_mode = dspi->devtype_data->trans_mode;
@@ -566,7 +566,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)
                if (!dspi->len) {
                        if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) {
                                regmap_update_bits(dspi->regmap,
-                                                  SPI_CTAR(dspi->cs),
+                                                  SPI_CTAR(0),
                                                   SPI_FRAME_BITS_MASK,
                                                   SPI_FRAME_BITS(16));
                                dspi->dataflags &= ~TRAN_STATE_WORD_ODD_NUM;
index 2b0a8ec3affb87333f8bdb2e9a2d9ad95855d4c1..dee1cb87d24f4aaca1fd3d2e43b8101d3bf6e246 100644 (file)
@@ -1705,7 +1705,7 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
        master->bus_num = -1;
        master->num_chipselect = 1;
        master->dev.class = &spi_master_class;
-       master->dev.parent = get_device(dev);
+       master->dev.parent = dev;
        spi_master_set_devdata(master, &master[1]);
 
        return master;
index 91a0fcd72423080900c6c733f6aeb7e800a85538..d0e7dfc647cf21a729696cbe499f7fc6dbf53b02 100644 (file)
@@ -651,11 +651,11 @@ static int spidev_release(struct inode *inode, struct file *filp)
                kfree(spidev->rx_buffer);
                spidev->rx_buffer = NULL;
 
+               spin_lock_irq(&spidev->spi_lock);
                if (spidev->spi)
                        spidev->speed_hz = spidev->spi->max_speed_hz;
 
                /* ... after we unbound from the underlying device? */
-               spin_lock_irq(&spidev->spi_lock);
                dofree = (spidev->spi == NULL);
                spin_unlock_irq(&spidev->spi_lock);
 
index ed776149261ea1022fc0586ce3be200967ec4c0b..e49c2bce551d31db115b97f0a12807339258b69b 100644 (file)
@@ -2054,13 +2054,13 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
        size_t eol;
        size_t tail;
        int ret, found = 0;
-       bool eof_push = 0;
 
        /* N.B. avoid overrun if nr == 0 */
-       n = min(*nr, smp_load_acquire(&ldata->canon_head) - ldata->read_tail);
-       if (!n)
+       if (!*nr)
                return 0;
 
+       n = min(*nr + 1, smp_load_acquire(&ldata->canon_head) - ldata->read_tail);
+
        tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
        size = min_t(size_t, tail + n, N_TTY_BUF_SIZE);
 
@@ -2081,12 +2081,11 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
        n = eol - tail;
        if (n > N_TTY_BUF_SIZE)
                n += N_TTY_BUF_SIZE;
-       n += found;
-       c = n;
+       c = n + found;
 
-       if (found && !ldata->push && read_buf(ldata, eol) == __DISABLED_CHAR) {
-               n--;
-               eof_push = !n && ldata->read_tail != ldata->line_start;
+       if (!found || read_buf(ldata, eol) != __DISABLED_CHAR) {
+               c = min(*nr, c);
+               n = c;
        }
 
        n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu size:%zu more:%zu\n",
@@ -2116,7 +2115,7 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
                        ldata->push = 0;
                tty_audit_push(tty);
        }
-       return eof_push ? -EAGAIN : 0;
+       return 0;
 }
 
 extern ssize_t redirected_tty_write(struct file *, const char __user *,
@@ -2273,10 +2272,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
 
                if (ldata->icanon && !L_EXTPROC(tty)) {
                        retval = canon_copy_from_read_buf(tty, &b, &nr);
-                       if (retval == -EAGAIN) {
-                               retval = 0;
-                               continue;
-                       } else if (retval)
+                       if (retval)
                                break;
                } else {
                        int uncopied;
index d11621e2cf1df083ca4c58309ef610df6c9c70fa..245edbb68d4ba5fe98e6e8fa915bf518cc4f28a5 100644 (file)
@@ -115,12 +115,16 @@ static void uniphier_serial_out(struct uart_port *p, int offset, int value)
  */
 static int uniphier_serial_dl_read(struct uart_8250_port *up)
 {
-       return readl(up->port.membase + UNIPHIER_UART_DLR);
+       int offset = UNIPHIER_UART_DLR << up->port.regshift;
+
+       return readl(up->port.membase + offset);
 }
 
 static void uniphier_serial_dl_write(struct uart_8250_port *up, int value)
 {
-       writel(value, up->port.membase + UNIPHIER_UART_DLR);
+       int offset = UNIPHIER_UART_DLR << up->port.regshift;
+
+       writel(value, up->port.membase + offset);
 }
 
 static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port,
index f09636083426d5fc2fdb18a65a2a1af49a0093b7..b5b2f2be6be7c613b5c051c0d9730d3fa3b5e177 100644 (file)
@@ -115,6 +115,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match)
        if (buf && !parse_options(&early_console_dev, buf))
                buf = NULL;
 
+       spin_lock_init(&port->lock);
        port->uartclk = BASE_BAUD * 16;
        if (port->mapbase)
                port->membase = earlycon_map(port->mapbase, 64);
@@ -202,6 +203,7 @@ int __init of_setup_earlycon(unsigned long addr,
        int err;
        struct uart_port *port = &early_console_dev.port;
 
+       spin_lock_init(&port->lock);
        port->iotype = UPIO_MEM;
        port->mapbase = addr;
        port->uartclk = BASE_BAUD * 16;
index 960e50a97558cff52a1fb9eb8ed8879a5238991c..51c7507b0444957bcbc9c2c832bd6048a5f3b596 100644 (file)
@@ -1437,7 +1437,7 @@ static void sci_request_dma(struct uart_port *port)
                        sg_init_table(sg, 1);
                        s->rx_buf[i] = buf;
                        sg_dma_address(sg) = dma;
-                       sg->length = s->buf_len_rx;
+                       sg_dma_len(sg) = s->buf_len_rx;
 
                        buf += s->buf_len_rx;
                        dma += s->buf_len_rx;
index 064031870ba0d1b0bf09fd3bcb299d17dcaf76d5..ca0d3802f2af45fb8be9cad11d9763fb615e516a 100644 (file)
@@ -148,8 +148,10 @@ static int receive_chars_read(struct uart_port *port)
                        uart_handle_dcd_change(port, 1);
                }
 
-               for (i = 0; i < bytes_read; i++)
-                       uart_handle_sysrq_char(port, con_read_page[i]);
+               if (port->sysrq != 0 &&  *con_read_page) {
+                       for (i = 0; i < bytes_read; i++)
+                               uart_handle_sysrq_char(port, con_read_page[i]);
+               }
 
                if (port->state == NULL)
                        continue;
@@ -168,17 +170,17 @@ struct sunhv_ops {
        int (*receive_chars)(struct uart_port *port);
 };
 
-static struct sunhv_ops bychar_ops = {
+static const struct sunhv_ops bychar_ops = {
        .transmit_chars = transmit_chars_putchar,
        .receive_chars = receive_chars_getchar,
 };
 
-static struct sunhv_ops bywrite_ops = {
+static const struct sunhv_ops bywrite_ops = {
        .transmit_chars = transmit_chars_write,
        .receive_chars = receive_chars_read,
 };
 
-static struct sunhv_ops *sunhv_ops = &bychar_ops;
+static const struct sunhv_ops *sunhv_ops = &bychar_ops;
 
 static struct tty_port *receive_chars(struct uart_port *port)
 {
index 9a479e61791a2a80cd0ae3fd5c93c6d0873d6998..3cd31e0d4bd9545b5357cda0ffa14373d181e670 100644 (file)
@@ -450,7 +450,7 @@ receive_buf(struct tty_struct *tty, struct tty_buffer *head, int count)
                count = disc->ops->receive_buf2(tty, p, f, count);
        else {
                count = min_t(int, count, tty->receive_room);
-               if (count)
+               if (count && disc->ops->receive_buf)
                        disc->ops->receive_buf(tty, p, f, count);
        }
        return count;
index a5cc032ef77a8da22b86d9b29e4090e897d0bcc1..ddbf32d599cba4e51aeb81eea8519500a8bbea01 100644 (file)
@@ -1035,10 +1035,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
        unsigned delay;
 
        /* Continue a partial initialization */
-       if (type == HUB_INIT2)
-               goto init2;
-       if (type == HUB_INIT3)
+       if (type == HUB_INIT2 || type == HUB_INIT3) {
+               device_lock(hub->intfdev);
+
+               /* Was the hub disconnected while we were waiting? */
+               if (hub->disconnected) {
+                       device_unlock(hub->intfdev);
+                       kref_put(&hub->kref, hub_release);
+                       return;
+               }
+               if (type == HUB_INIT2)
+                       goto init2;
                goto init3;
+       }
+       kref_get(&hub->kref);
 
        /* The superspeed hub except for root hub has to use Hub Depth
         * value as an offset into the route string to locate the bits
@@ -1236,6 +1246,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
                        queue_delayed_work(system_power_efficient_wq,
                                        &hub->init_work,
                                        msecs_to_jiffies(delay));
+                       device_unlock(hub->intfdev);
                        return;         /* Continues at init3: below */
                } else {
                        msleep(delay);
@@ -1257,6 +1268,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
        /* Allow autosuspend if it was suppressed */
        if (type <= HUB_INIT3)
                usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
+
+       if (type == HUB_INIT2 || type == HUB_INIT3)
+               device_unlock(hub->intfdev);
+
+       kref_put(&hub->kref, hub_release);
 }
 
 /* Implement the continuations for the delays above */
index f51a5d52c0edab01b9c9fbd91b8c1d7389d00f78..ec1b8f2c11837fecd39468c1e053880d72da9f94 100644 (file)
@@ -531,7 +531,8 @@ static int ipaq_open(struct tty_struct *tty,
         * through. Since this has a reasonably high failure rate, we retry
         * several times.
         */
-       while (retries--) {
+       while (retries) {
+               retries--;
                result = usb_control_msg(serial->dev,
                                usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,
                                0x1, 0, NULL, 0, 100);
index e3e9e3d46d1bf55028cf4a7902fa72b494fb3ce6..96a1b8da53715e7501d09369ee9ef375f421e936 100644 (file)
@@ -281,7 +281,8 @@ static void handle_irq_for_port(unsigned port)
 
 static void consume_one_event(unsigned cpu,
                              struct evtchn_fifo_control_block *control_block,
-                             unsigned priority, unsigned long *ready)
+                             unsigned priority, unsigned long *ready,
+                             bool drop)
 {
        struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu);
        uint32_t head;
@@ -313,13 +314,17 @@ static void consume_one_event(unsigned cpu,
        if (head == 0)
                clear_bit(priority, ready);
 
-       if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port))
-               handle_irq_for_port(port);
+       if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port)) {
+               if (unlikely(drop))
+                       pr_warn("Dropping pending event for port %u\n", port);
+               else
+                       handle_irq_for_port(port);
+       }
 
        q->head[priority] = head;
 }
 
-static void evtchn_fifo_handle_events(unsigned cpu)
+static void __evtchn_fifo_handle_events(unsigned cpu, bool drop)
 {
        struct evtchn_fifo_control_block *control_block;
        unsigned long ready;
@@ -331,11 +336,16 @@ static void evtchn_fifo_handle_events(unsigned cpu)
 
        while (ready) {
                q = find_first_bit(&ready, EVTCHN_FIFO_MAX_QUEUES);
-               consume_one_event(cpu, control_block, q, &ready);
+               consume_one_event(cpu, control_block, q, &ready, drop);
                ready |= xchg(&control_block->ready, 0);
        }
 }
 
+static void evtchn_fifo_handle_events(unsigned cpu)
+{
+       __evtchn_fifo_handle_events(cpu, false);
+}
+
 static void evtchn_fifo_resume(void)
 {
        unsigned cpu;
@@ -420,6 +430,9 @@ static int evtchn_fifo_cpu_notification(struct notifier_block *self,
                if (!per_cpu(cpu_control_block, cpu))
                        ret = evtchn_fifo_alloc_control_block(cpu);
                break;
+       case CPU_DEAD:
+               __evtchn_fifo_handle_events(cpu, true);
+               break;
        default:
                break;
        }
index 58e38d586f524fd6b78b18594cbf2de593c1119e..4d529f3e40df93941c99f6fffee06da540f28ca2 100644 (file)
@@ -37,6 +37,7 @@ struct xen_pcibk_device {
        struct xen_pci_sharedinfo *sh_info;
        unsigned long flags;
        struct work_struct op_work;
+       struct xen_pci_op op;
 };
 
 struct xen_pcibk_dev_data {
index c4a0666de6f5e08a17edf4fcbcb001478d0e303b..73dafdc494aa8322e037f1d4a9ad4ec5530c5743 100644 (file)
@@ -70,6 +70,13 @@ static void xen_pcibk_control_isr(struct pci_dev *dev, int reset)
                enable ? "enable" : "disable");
 
        if (enable) {
+               /*
+                * The MSI or MSI-X should not have an IRQ handler. Otherwise
+                * if the guest terminates we BUG_ON in free_msi_irqs.
+                */
+               if (dev->msi_enabled || dev->msix_enabled)
+                       goto out;
+
                rc = request_irq(dev_data->irq,
                                xen_pcibk_guest_interrupt, IRQF_SHARED,
                                dev_data->irq_name, dev);
@@ -144,7 +151,12 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev,
        if (unlikely(verbose_request))
                printk(KERN_DEBUG DRV_NAME ": %s: enable MSI\n", pci_name(dev));
 
-       status = pci_enable_msi(dev);
+       if (dev->msi_enabled)
+               status = -EALREADY;
+       else if (dev->msix_enabled)
+               status = -ENXIO;
+       else
+               status = pci_enable_msi(dev);
 
        if (status) {
                pr_warn_ratelimited("%s: error enabling MSI for guest %u: err %d\n",
@@ -173,20 +185,23 @@ static
 int xen_pcibk_disable_msi(struct xen_pcibk_device *pdev,
                          struct pci_dev *dev, struct xen_pci_op *op)
 {
-       struct xen_pcibk_dev_data *dev_data;
-
        if (unlikely(verbose_request))
                printk(KERN_DEBUG DRV_NAME ": %s: disable MSI\n",
                       pci_name(dev));
-       pci_disable_msi(dev);
 
+       if (dev->msi_enabled) {
+               struct xen_pcibk_dev_data *dev_data;
+
+               pci_disable_msi(dev);
+
+               dev_data = pci_get_drvdata(dev);
+               if (dev_data)
+                       dev_data->ack_intr = 1;
+       }
        op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
        if (unlikely(verbose_request))
                printk(KERN_DEBUG DRV_NAME ": %s: MSI: %d\n", pci_name(dev),
                        op->value);
-       dev_data = pci_get_drvdata(dev);
-       if (dev_data)
-               dev_data->ack_intr = 1;
        return 0;
 }
 
@@ -197,13 +212,26 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
        struct xen_pcibk_dev_data *dev_data;
        int i, result;
        struct msix_entry *entries;
+       u16 cmd;
 
        if (unlikely(verbose_request))
                printk(KERN_DEBUG DRV_NAME ": %s: enable MSI-X\n",
                       pci_name(dev));
+
        if (op->value > SH_INFO_MAX_VEC)
                return -EINVAL;
 
+       if (dev->msix_enabled)
+               return -EALREADY;
+
+       /*
+        * PCI_COMMAND_MEMORY must be enabled, otherwise we may not be able
+        * to access the BARs where the MSI-X entries reside.
+        */
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+       if (dev->msi_enabled || !(cmd & PCI_COMMAND_MEMORY))
+               return -ENXIO;
+
        entries = kmalloc(op->value * sizeof(*entries), GFP_KERNEL);
        if (entries == NULL)
                return -ENOMEM;
@@ -245,23 +273,27 @@ static
 int xen_pcibk_disable_msix(struct xen_pcibk_device *pdev,
                           struct pci_dev *dev, struct xen_pci_op *op)
 {
-       struct xen_pcibk_dev_data *dev_data;
        if (unlikely(verbose_request))
                printk(KERN_DEBUG DRV_NAME ": %s: disable MSI-X\n",
                        pci_name(dev));
-       pci_disable_msix(dev);
 
+       if (dev->msix_enabled) {
+               struct xen_pcibk_dev_data *dev_data;
+
+               pci_disable_msix(dev);
+
+               dev_data = pci_get_drvdata(dev);
+               if (dev_data)
+                       dev_data->ack_intr = 1;
+       }
        /*
         * SR-IOV devices (which don't have any legacy IRQ) have
         * an undefined IRQ value of zero.
         */
        op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
        if (unlikely(verbose_request))
-               printk(KERN_DEBUG DRV_NAME ": %s: MSI-X: %d\n", pci_name(dev),
-                       op->value);
-       dev_data = pci_get_drvdata(dev);
-       if (dev_data)
-               dev_data->ack_intr = 1;
+               printk(KERN_DEBUG DRV_NAME ": %s: MSI-X: %d\n",
+                      pci_name(dev), op->value);
        return 0;
 }
 #endif
@@ -298,9 +330,11 @@ void xen_pcibk_do_op(struct work_struct *data)
                container_of(data, struct xen_pcibk_device, op_work);
        struct pci_dev *dev;
        struct xen_pcibk_dev_data *dev_data = NULL;
-       struct xen_pci_op *op = &pdev->sh_info->op;
+       struct xen_pci_op *op = &pdev->op;
        int test_intx = 0;
 
+       *op = pdev->sh_info->op;
+       barrier();
        dev = xen_pcibk_get_pci_dev(pdev, op->domain, op->bus, op->devfn);
 
        if (dev == NULL)
@@ -342,6 +376,17 @@ void xen_pcibk_do_op(struct work_struct *data)
                if ((dev_data->enable_intx != test_intx))
                        xen_pcibk_control_isr(dev, 0 /* no reset */);
        }
+       pdev->sh_info->op.err = op->err;
+       pdev->sh_info->op.value = op->value;
+#ifdef CONFIG_PCI_MSI
+       if (op->cmd == XEN_PCI_OP_enable_msix && op->err == 0) {
+               unsigned int i;
+
+               for (i = 0; i < op->value; i++)
+                       pdev->sh_info->op.msix_entries[i].vector =
+                               op->msix_entries[i].vector;
+       }
+#endif
        /* Tell the driver domain that we're done. */
        wmb();
        clear_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
index 98bc345f296ef866eaf0e3b1ffffad12ca35fb7e..4843741e703a336da72162af91165392f0560490 100644 (file)
@@ -44,7 +44,6 @@ static struct xen_pcibk_device *alloc_pdev(struct xenbus_device *xdev)
        dev_dbg(&xdev->dev, "allocated pdev @ 0x%p\n", pdev);
 
        pdev->xdev = xdev;
-       dev_set_drvdata(&xdev->dev, pdev);
 
        mutex_init(&pdev->dev_lock);
 
@@ -58,6 +57,9 @@ static struct xen_pcibk_device *alloc_pdev(struct xenbus_device *xdev)
                kfree(pdev);
                pdev = NULL;
        }
+
+       dev_set_drvdata(&xdev->dev, pdev);
+
 out:
        return pdev;
 }
index 43bcae852546ad2e5021b4a1d326dda375ae4023..ad4eb1024d1ffb7663db4e770fdd4c5c2663e821 100644 (file)
@@ -726,7 +726,7 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info)
                if (!pending_req)
                        return 1;
 
-               ring_req = *RING_GET_REQUEST(ring, rc);
+               RING_COPY_REQUEST(ring, rc, &ring_req);
                ring->req_cons = ++rc;
 
                err = prepare_pending_reqs(info, &ring_req, pending_req);
index 4b89680a192338c7a70a4c909e3c4374abe41284..c4661db2b72ae4c412adaaecb7cbc236fbe1e7cf 100644 (file)
@@ -10480,11 +10480,15 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
                 * until transaction commit to do the actual discard.
                 */
                if (trimming) {
-                       WARN_ON(!list_empty(&block_group->bg_list));
-                       spin_lock(&trans->transaction->deleted_bgs_lock);
+                       spin_lock(&fs_info->unused_bgs_lock);
+                       /*
+                        * A concurrent scrub might have added us to the list
+                        * fs_info->unused_bgs, so use a list_move operation
+                        * to add the block group to the deleted_bgs list.
+                        */
                        list_move(&block_group->bg_list,
                                  &trans->transaction->deleted_bgs);
-                       spin_unlock(&trans->transaction->deleted_bgs_lock);
+                       spin_unlock(&fs_info->unused_bgs_lock);
                        btrfs_get_block_group(block_group);
                }
 end_trans:
index 72e73461c0643bbf128504c93a9c47dd377784aa..0f09526aa7d9d2017bb229eb4310f777c4b3b578 100644 (file)
@@ -1291,7 +1291,8 @@ out:
  * on error we return an unlocked page and the error value
  * on success we return a locked page and 0
  */
-static int prepare_uptodate_page(struct page *page, u64 pos,
+static int prepare_uptodate_page(struct inode *inode,
+                                struct page *page, u64 pos,
                                 bool force_uptodate)
 {
        int ret = 0;
@@ -1306,6 +1307,10 @@ static int prepare_uptodate_page(struct page *page, u64 pos,
                        unlock_page(page);
                        return -EIO;
                }
+               if (page->mapping != inode->i_mapping) {
+                       unlock_page(page);
+                       return -EAGAIN;
+               }
        }
        return 0;
 }
@@ -1324,6 +1329,7 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages,
        int faili;
 
        for (i = 0; i < num_pages; i++) {
+again:
                pages[i] = find_or_create_page(inode->i_mapping, index + i,
                                               mask | __GFP_WRITE);
                if (!pages[i]) {
@@ -1333,13 +1339,17 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages,
                }
 
                if (i == 0)
-                       err = prepare_uptodate_page(pages[i], pos,
+                       err = prepare_uptodate_page(inode, pages[i], pos,
                                                    force_uptodate);
-               if (i == num_pages - 1)
-                       err = prepare_uptodate_page(pages[i],
+               if (!err && i == num_pages - 1)
+                       err = prepare_uptodate_page(inode, pages[i],
                                                    pos + write_bytes, false);
                if (err) {
                        page_cache_release(pages[i]);
+                       if (err == -EAGAIN) {
+                               err = 0;
+                               goto again;
+                       }
                        faili = i - 1;
                        goto fail;
                }
index 85a1f8621b51f09f0893abae9ffab90382efdcfc..cfe99bec49dedd723e2a7fff04ace299be37ef87 100644 (file)
@@ -891,7 +891,7 @@ out:
                spin_unlock(&block_group->lock);
                ret = 0;
 
-               btrfs_warn(fs_info, "failed to load free space cache for block group %llu, rebuild it now",
+               btrfs_warn(fs_info, "failed to load free space cache for block group %llu, rebuilding it now",
                        block_group->key.objectid);
        }
 
@@ -2972,7 +2972,7 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,
                     u64 cont1_bytes, u64 min_bytes)
 {
        struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
-       struct btrfs_free_space *entry;
+       struct btrfs_free_space *entry = NULL;
        int ret = -ENOSPC;
        u64 bitmap_offset = offset_to_bitmap(ctl, offset);
 
@@ -2983,8 +2983,10 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,
         * The bitmap that covers offset won't be in the list unless offset
         * is just its start offset.
         */
-       entry = list_first_entry(bitmaps, struct btrfs_free_space, list);
-       if (entry->offset != bitmap_offset) {
+       if (!list_empty(bitmaps))
+               entry = list_first_entry(bitmaps, struct btrfs_free_space, list);
+
+       if (!entry || entry->offset != bitmap_offset) {
                entry = tree_search_offset(ctl, bitmap_offset, 1, 0);
                if (entry && list_empty(&entry->list))
                        list_add(&entry->list, bitmaps);
index 3367a3c6f214f5ca248a79fff36c6404a49fbf4f..be8eae80ff6572608a478610f9c2b16f3bcb1871 100644 (file)
@@ -274,7 +274,6 @@ loop:
        cur_trans->num_dirty_bgs = 0;
        spin_lock_init(&cur_trans->dirty_bgs_lock);
        INIT_LIST_HEAD(&cur_trans->deleted_bgs);
-       spin_lock_init(&cur_trans->deleted_bgs_lock);
        spin_lock_init(&cur_trans->dropped_roots_lock);
        list_add_tail(&cur_trans->list, &fs_info->trans_list);
        extent_io_tree_init(&cur_trans->dirty_pages,
index 0da21ca9b3fb312a7ec77b4e8314a9e4b3410075..64c8221b6165bb7a6b786ac74e1833f2b93a197b 100644 (file)
@@ -77,8 +77,8 @@ struct btrfs_transaction {
         */
        struct mutex cache_write_mutex;
        spinlock_t dirty_bgs_lock;
+       /* Protected by spin lock fs_info->unused_bgs_lock. */
        struct list_head deleted_bgs;
-       spinlock_t deleted_bgs_lock;
        spinlock_t dropped_roots_lock;
        struct btrfs_delayed_ref_root delayed_refs;
        int aborted;
index 45645220660996773b1f76cd1d526d4aeae33dac..a23399e8e3aba2f63d4c0cee90932d073d3bd113 100644 (file)
@@ -3548,12 +3548,11 @@ again:
 
                        ret = btrfs_force_chunk_alloc(trans, chunk_root,
                                                      BTRFS_BLOCK_GROUP_DATA);
+                       btrfs_end_transaction(trans, chunk_root);
                        if (ret < 0) {
                                mutex_unlock(&fs_info->delete_unused_bgs_mutex);
                                goto error;
                        }
-
-                       btrfs_end_transaction(trans, chunk_root);
                        chunk_reserved = 1;
                }
 
index 9ffef06b30d51e2acb2ae1a6570f14c2c47eac59..c9d6c715c0fb7e3187ffd1f2105f9527aa32259b 100644 (file)
@@ -616,6 +616,7 @@ nfsd4_cb_layout_prepare(struct nfsd4_callback *cb)
 
        mutex_lock(&ls->ls_mutex);
        nfs4_inc_and_copy_stateid(&ls->ls_recall_sid, &ls->ls_stid);
+       mutex_unlock(&ls->ls_mutex);
 }
 
 static int
@@ -659,7 +660,6 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb)
 
        trace_layout_recall_release(&ls->ls_stid.sc_stateid);
 
-       mutex_unlock(&ls->ls_mutex);
        nfsd4_return_all_layouts(ls, &reaplist);
        nfsd4_free_layouts(&reaplist);
        nfs4_put_stid(&ls->ls_stid);
index bd3e9e68125b8933b2e32a4fea2e2282397dc1cd..4bd5d3118acd4b152d6e6f17b38b0a03b0f723d6 100644 (file)
@@ -2494,6 +2494,7 @@ static ssize_t proc_coredump_filter_write(struct file *file,
        mm = get_task_mm(task);
        if (!mm)
                goto out_no_mm;
+       ret = 0;
 
        for (i = 0, mask = 1; i < MMF_DUMP_FILTER_BITS; i++, mask <<= 1) {
                if (val & mask)
index 7be22da321f38eb1327bbbcaabddd6cbca131d44..a4cf57cd0f7512d66b15a036cb76114d5bf633e0 100644 (file)
 /* A few generic types ... taken from ses-2 */
 enum enclosure_component_type {
        ENCLOSURE_COMPONENT_DEVICE = 0x01,
+       ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS = 0x07,
+       ENCLOSURE_COMPONENT_SCSI_TARGET_PORT = 0x14,
+       ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT = 0x15,
        ENCLOSURE_COMPONENT_ARRAY_DEVICE = 0x17,
+       ENCLOSURE_COMPONENT_SAS_EXPANDER = 0x18,
 };
 
 /* ses-2 common element status */
index 877ef226f90fb3b945831c7e8f9edbabba1e9775..772362adf4713b77be041b6232097c97a7f5aad7 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef LINUX_MM_DEBUG_H
 #define LINUX_MM_DEBUG_H 1
 
+#include <linux/bug.h>
 #include <linux/stringify.h>
 
 struct page;
index 7d28aff605c7eb600c4c3bfe93b8b5f1edbaebfe..7dc685b4057d33ad227d861a2a3115a5ca55cd3e 100644 (file)
@@ -181,6 +181,20 @@ struct __name##_back_ring {                                                \
 #define RING_GET_REQUEST(_r, _idx)                                     \
     (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
 
+/*
+ * Get a local copy of a request.
+ *
+ * Use this in preference to RING_GET_REQUEST() so all processing is
+ * done on a local copy that cannot be modified by the other end.
+ *
+ * Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 may cause this
+ * to be ineffective where _req is a struct which consists of only bitfields.
+ */
+#define RING_COPY_REQUEST(_r, _idx, _req) do {                         \
+       /* Use volatile to force the copy into _req. */                 \
+       *(_req) = *(volatile typeof(_req))RING_GET_REQUEST(_r, _idx);   \
+} while (0)
+
 #define RING_GET_RESPONSE(_r, _idx)                                    \
     (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
 
index 025f8dc723dedf60da7d2d9d580ac208e75cd8f6..bf14508afd64573d8310a5a3e12b99b629fc8c02 100644 (file)
@@ -541,6 +541,7 @@ static struct zswap_pool *zswap_pool_last_get(void)
        return last;
 }
 
+/* type and compressor must be null-terminated */
 static struct zswap_pool *zswap_pool_find_get(char *type, char *compressor)
 {
        struct zswap_pool *pool;
@@ -548,10 +549,9 @@ static struct zswap_pool *zswap_pool_find_get(char *type, char *compressor)
        assert_spin_locked(&zswap_pools_lock);
 
        list_for_each_entry_rcu(pool, &zswap_pools, list) {
-               if (strncmp(pool->tfm_name, compressor, sizeof(pool->tfm_name)))
+               if (strcmp(pool->tfm_name, compressor))
                        continue;
-               if (strncmp(zpool_get_type(pool->zpool), type,
-                           sizeof(zswap_zpool_type)))
+               if (strcmp(zpool_get_type(pool->zpool), type))
                        continue;
                /* if we can't get it, it's about to be destroyed */
                if (!zswap_pool_get(pool))
index 698768bdc5815021b61814ddabc408d4310c3c0e..301d70b0174f3b3ff3aaea7a721ffdd905a576f9 100644 (file)
 
 static int fd_map;     /* File descriptor for file being modified. */
 static int mmap_failed; /* Boolean flag. */
-static void *ehdr_curr; /* current ElfXX_Ehdr *  for resource cleanup */
 static char gpfx;      /* prefix for global symbol name (sometimes '_') */
 static struct stat sb; /* Remember .st_size, etc. */
 static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */
 static const char *altmcount;  /* alternate mcount symbol name */
 static int warn_on_notrace_sect; /* warn when section has mcount not being recorded */
+static void *file_map; /* pointer of the mapped file */
+static void *file_end; /* pointer to the end of the mapped file */
+static int file_updated; /* flag to state file was changed */
+static void *file_ptr; /* current file pointer location */
+static void *file_append; /* added to the end of the file */
+static size_t file_append_size; /* how much is added to end of file */
 
 /* setjmp() return values */
 enum {
@@ -67,10 +72,14 @@ static void
 cleanup(void)
 {
        if (!mmap_failed)
-               munmap(ehdr_curr, sb.st_size);
+               munmap(file_map, sb.st_size);
        else
-               free(ehdr_curr);
-       close(fd_map);
+               free(file_map);
+       file_map = NULL;
+       free(file_append);
+       file_append = NULL;
+       file_append_size = 0;
+       file_updated = 0;
 }
 
 static void __attribute__((noreturn))
@@ -92,12 +101,22 @@ succeed_file(void)
 static off_t
 ulseek(int const fd, off_t const offset, int const whence)
 {
-       off_t const w = lseek(fd, offset, whence);
-       if (w == (off_t)-1) {
-               perror("lseek");
+       switch (whence) {
+       case SEEK_SET:
+               file_ptr = file_map + offset;
+               break;
+       case SEEK_CUR:
+               file_ptr += offset;
+               break;
+       case SEEK_END:
+               file_ptr = file_map + (sb.st_size - offset);
+               break;
+       }
+       if (file_ptr < file_map) {
+               fprintf(stderr, "lseek: seek before file\n");
                fail_file();
        }
-       return w;
+       return file_ptr - file_map;
 }
 
 static size_t
@@ -114,12 +133,38 @@ uread(int const fd, void *const buf, size_t const count)
 static size_t
 uwrite(int const fd, void const *const buf, size_t const count)
 {
-       size_t const n = write(fd, buf, count);
-       if (n != count) {
-               perror("write");
-               fail_file();
+       size_t cnt = count;
+       off_t idx = 0;
+
+       file_updated = 1;
+
+       if (file_ptr + count >= file_end) {
+               off_t aoffset = (file_ptr + count) - file_end;
+
+               if (aoffset > file_append_size) {
+                       file_append = realloc(file_append, aoffset);
+                       file_append_size = aoffset;
+               }
+               if (!file_append) {
+                       perror("write");
+                       fail_file();
+               }
+               if (file_ptr < file_end) {
+                       cnt = file_end - file_ptr;
+               } else {
+                       cnt = 0;
+                       idx = aoffset - count;
+               }
        }
-       return n;
+
+       if (cnt)
+               memcpy(file_ptr, buf, cnt);
+
+       if (cnt < count)
+               memcpy(file_append + idx, buf + cnt, count - cnt);
+
+       file_ptr += count;
+       return count;
 }
 
 static void *
@@ -192,9 +237,7 @@ static int make_nop_arm64(void *map, size_t const offset)
  */
 static void *mmap_file(char const *fname)
 {
-       void *addr;
-
-       fd_map = open(fname, O_RDWR);
+       fd_map = open(fname, O_RDONLY);
        if (fd_map < 0 || fstat(fd_map, &sb) < 0) {
                perror(fname);
                fail_file();
@@ -203,15 +246,58 @@ static void *mmap_file(char const *fname)
                fprintf(stderr, "not a regular file: %s\n", fname);
                fail_file();
        }
-       addr = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
-                   fd_map, 0);
+       file_map = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
+                       fd_map, 0);
        mmap_failed = 0;
-       if (addr == MAP_FAILED) {
+       if (file_map == MAP_FAILED) {
                mmap_failed = 1;
-               addr = umalloc(sb.st_size);
-               uread(fd_map, addr, sb.st_size);
+               file_map = umalloc(sb.st_size);
+               uread(fd_map, file_map, sb.st_size);
+       }
+       close(fd_map);
+
+       file_end = file_map + sb.st_size;
+
+       return file_map;
+}
+
+static void write_file(const char *fname)
+{
+       char tmp_file[strlen(fname) + 4];
+       size_t n;
+
+       if (!file_updated)
+               return;
+
+       sprintf(tmp_file, "%s.rc", fname);
+
+       /*
+        * After reading the entire file into memory, delete it
+        * and write it back, to prevent weird side effects of modifying
+        * an object file in place.
+        */
+       fd_map = open(tmp_file, O_WRONLY | O_TRUNC | O_CREAT, sb.st_mode);
+       if (fd_map < 0) {
+               perror(fname);
+               fail_file();
+       }
+       n = write(fd_map, file_map, sb.st_size);
+       if (n != sb.st_size) {
+               perror("write");
+               fail_file();
+       }
+       if (file_append_size) {
+               n = write(fd_map, file_append, file_append_size);
+               if (n != file_append_size) {
+                       perror("write");
+                       fail_file();
+               }
+       }
+       close(fd_map);
+       if (rename(tmp_file, fname) < 0) {
+               perror(fname);
+               fail_file();
        }
-       return addr;
 }
 
 /* w8rev, w8nat, ...: Handle endianness. */
@@ -318,7 +404,6 @@ do_file(char const *const fname)
        Elf32_Ehdr *const ehdr = mmap_file(fname);
        unsigned int reltype = 0;
 
-       ehdr_curr = ehdr;
        w = w4nat;
        w2 = w2nat;
        w8 = w8nat;
@@ -441,6 +526,7 @@ do_file(char const *const fname)
        }
        }  /* end switch */
 
+       write_file(fname);
        cleanup();
 }
 
@@ -493,11 +579,14 @@ main(int argc, char *argv[])
                case SJ_SETJMP:    /* normal sequence */
                        /* Avoid problems if early cleanup() */
                        fd_map = -1;
-                       ehdr_curr = NULL;
                        mmap_failed = 1;
+                       file_map = NULL;
+                       file_ptr = NULL;
+                       file_updated = 0;
                        do_file(file);
                        break;
                case SJ_FAIL:    /* error in do_file or below */
+                       sprintf("%s: failed\n", file);
                        ++n_error;
                        break;
                case SJ_SUCCEED:    /* premature success */
index bff5c8b329d13b4be930a66585933a902e9cb977..3b36582970702219f0e1b28f16093b4de6425b48 100644 (file)
@@ -954,6 +954,36 @@ static int azx_resume(struct device *dev)
 }
 #endif /* CONFIG_PM_SLEEP || SUPPORT_VGA_SWITCHEROO */
 
+#ifdef CONFIG_PM_SLEEP
+/* put codec down to D3 at hibernation for Intel SKL+;
+ * otherwise BIOS may still access the codec and screw up the driver
+ */
+#define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
+#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
+#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
+#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))
+
+static int azx_freeze_noirq(struct device *dev)
+{
+       struct pci_dev *pci = to_pci_dev(dev);
+
+       if (IS_SKL_PLUS(pci))
+               pci_set_power_state(pci, PCI_D3hot);
+
+       return 0;
+}
+
+static int azx_thaw_noirq(struct device *dev)
+{
+       struct pci_dev *pci = to_pci_dev(dev);
+
+       if (IS_SKL_PLUS(pci))
+               pci_set_power_state(pci, PCI_D0);
+
+       return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
 #ifdef CONFIG_PM
 static int azx_runtime_suspend(struct device *dev)
 {
@@ -1063,6 +1093,10 @@ static int azx_runtime_idle(struct device *dev)
 
 static const struct dev_pm_ops azx_pm = {
        SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
+#ifdef CONFIG_PM_SLEEP
+       .freeze_noirq = azx_freeze_noirq,
+       .thaw_noirq = azx_thaw_noirq,
+#endif
        SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle)
 };
 
index 8dd2ac13b3af19ce79fdf5e5e35943ff1f5dfef8..fe96428aa40343f362237121f246e67b734c0446 100644 (file)
@@ -111,6 +111,7 @@ struct alc_spec {
        void (*power_hook)(struct hda_codec *codec);
 #endif
        void (*shutup)(struct hda_codec *codec);
+       void (*reboot_notify)(struct hda_codec *codec);
 
        int init_amp;
        int codec_variant;      /* flag for other variants */
@@ -773,6 +774,25 @@ static inline void alc_shutup(struct hda_codec *codec)
                snd_hda_shutup_pins(codec);
 }
 
+static void alc_reboot_notify(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+
+       if (spec && spec->reboot_notify)
+               spec->reboot_notify(codec);
+       else
+               alc_shutup(codec);
+}
+
+/* power down codec to D3 at reboot/shutdown; set as reboot_notify ops */
+static void alc_d3_at_reboot(struct hda_codec *codec)
+{
+       snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3);
+       snd_hda_codec_write(codec, codec->core.afg, 0,
+                           AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+       msleep(10);
+}
+
 #define alc_free       snd_hda_gen_free
 
 #ifdef CONFIG_PM
@@ -818,7 +838,7 @@ static const struct hda_codec_ops alc_patch_ops = {
        .suspend = alc_suspend,
        .check_power_status = snd_hda_gen_check_power_status,
 #endif
-       .reboot_notify = alc_shutup,
+       .reboot_notify = alc_reboot_notify,
 };
 
 
@@ -1755,6 +1775,7 @@ enum {
        ALC889_FIXUP_MBA11_VREF,
        ALC889_FIXUP_MBA21_VREF,
        ALC889_FIXUP_MP11_VREF,
+       ALC889_FIXUP_MP41_VREF,
        ALC882_FIXUP_INV_DMIC,
        ALC882_FIXUP_NO_PRIMARY_HP,
        ALC887_FIXUP_ASUS_BASS,
@@ -1843,7 +1864,7 @@ static void alc889_fixup_mbp_vref(struct hda_codec *codec,
                                  const struct hda_fixup *fix, int action)
 {
        struct alc_spec *spec = codec->spec;
-       static hda_nid_t nids[2] = { 0x14, 0x15 };
+       static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
        int i;
 
        if (action != HDA_FIXUP_ACT_INIT)
@@ -2133,6 +2154,12 @@ static const struct hda_fixup alc882_fixups[] = {
                .chained = true,
                .chain_id = ALC885_FIXUP_MACPRO_GPIO,
        },
+       [ALC889_FIXUP_MP41_VREF] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc889_fixup_mbp_vref,
+               .chained = true,
+               .chain_id = ALC885_FIXUP_MACPRO_GPIO,
+       },
        [ALC882_FIXUP_INV_DMIC] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_inv_dmic,
@@ -2215,7 +2242,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
        SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
        SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
        SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
-       SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
+       SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
        SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
        SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
        SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
@@ -4198,24 +4225,14 @@ static void alc_fixup_tpt440_dock(struct hda_codec *codec,
        struct alc_spec *spec = codec->spec;
 
        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+               spec->shutup = alc_no_shutup; /* reduce click noise */
+               spec->reboot_notify = alc_d3_at_reboot; /* reduce noise */
                spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
                codec->power_save_node = 0; /* avoid click noises */
                snd_hda_apply_pincfgs(codec, pincfgs);
        }
 }
 
-/* additional fixup for Thinkpad T440s noise problem */
-static void alc_fixup_tpt440(struct hda_codec *codec,
-                                 const struct hda_fixup *fix, int action)
-{
-       struct alc_spec *spec = codec->spec;
-
-       if (action == HDA_FIXUP_ACT_PRE_PROBE) {
-               spec->shutup = alc_no_shutup; /* reduce click noise */
-               spec->gen.mixer_nid = 0; /* reduce background noise */
-       }
-}
-
 static void alc_shutup_dell_xps13(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -4606,6 +4623,7 @@ enum {
        ALC288_FIXUP_DISABLE_AAMIX,
        ALC292_FIXUP_DELL_E7X,
        ALC292_FIXUP_DISABLE_AAMIX,
+       ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
        ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
        ALC275_FIXUP_DELL_XPS,
        ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
@@ -5066,7 +5084,7 @@ static const struct hda_fixup alc269_fixups[] = {
        },
        [ALC292_FIXUP_TPT440] = {
                .type = HDA_FIXUP_FUNC,
-               .v.func = alc_fixup_tpt440,
+               .v.func = alc_fixup_disable_aamix,
                .chained = true,
                .chain_id = ALC292_FIXUP_TPT440_DOCK,
        },
@@ -5169,6 +5187,12 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
        },
+       [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_disable_aamix,
+               .chained = true,
+               .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
+       },
        [ALC292_FIXUP_DELL_E7X] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_dell_xps13,
@@ -5247,11 +5271,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
-       SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
-       SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
-       SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
-       SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
-       SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
+       SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+       SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+       SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+       SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+       SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
        SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
        SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
@@ -5358,6 +5382,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+       SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
index 84f5eb07a91b1d27274f595cf595d97f36663484..afa6c5db9dccc9b00f049f8421b04e3091a1bcfc 100644 (file)
@@ -85,7 +85,15 @@ static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0);
 static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
 static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 300, 0);
 
-static const int deemph_settings[] = { 0, 32000, 44100, 48000 };
+static const struct {
+       int rate;
+       unsigned int val;
+} deemph_settings[] = {
+       { 0,     ES8328_DACCONTROL6_DEEMPH_OFF },
+       { 32000, ES8328_DACCONTROL6_DEEMPH_32k },
+       { 44100, ES8328_DACCONTROL6_DEEMPH_44_1k },
+       { 48000, ES8328_DACCONTROL6_DEEMPH_48k },
+};
 
 static int es8328_set_deemph(struct snd_soc_codec *codec)
 {
@@ -97,21 +105,22 @@ static int es8328_set_deemph(struct snd_soc_codec *codec)
         * rate.
         */
        if (es8328->deemph) {
-               best = 1;
-               for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
-                       if (abs(deemph_settings[i] - es8328->playback_fs) <
-                           abs(deemph_settings[best] - es8328->playback_fs))
+               best = 0;
+               for (i = 1; i < ARRAY_SIZE(deemph_settings); i++) {
+                       if (abs(deemph_settings[i].rate - es8328->playback_fs) <
+                           abs(deemph_settings[best].rate - es8328->playback_fs))
                                best = i;
                }
 
-               val = best << 1;
+               val = deemph_settings[best].val;
        } else {
-               val = 0;
+               val = ES8328_DACCONTROL6_DEEMPH_OFF;
        }
 
        dev_dbg(codec->dev, "Set deemphasis %d\n", val);
 
-       return snd_soc_update_bits(codec, ES8328_DACCONTROL6, 0x6, val);
+       return snd_soc_update_bits(codec, ES8328_DACCONTROL6,
+                       ES8328_DACCONTROL6_DEEMPH_MASK, val);
 }
 
 static int es8328_get_deemph(struct snd_kcontrol *kcontrol,
index cb36afe10c0ecdf0b51183bea6eb8446e01271d3..156c748c89c7e55d86421b27522b22f9b16d6f76 100644 (file)
@@ -153,6 +153,7 @@ int es8328_probe(struct device *dev, struct regmap *regmap);
 #define ES8328_DACCONTROL6_CLICKFREE (1 << 3)
 #define ES8328_DACCONTROL6_DAC_INVR (1 << 4)
 #define ES8328_DACCONTROL6_DAC_INVL (1 << 5)
+#define ES8328_DACCONTROL6_DEEMPH_MASK (3 << 6)
 #define ES8328_DACCONTROL6_DEEMPH_OFF (0 << 6)
 #define ES8328_DACCONTROL6_DEEMPH_32k (1 << 6)
 #define ES8328_DACCONTROL6_DEEMPH_44_1k (2 << 6)
index f540f82b1f271ec4833d9ea43aa7f4567c0df712..08b40460663c2f28bd450261889cd365116f0bf9 100644 (file)
@@ -189,6 +189,7 @@ static int power_vag_event(struct snd_soc_dapm_widget *w,
        case SND_SOC_DAPM_POST_PMU:
                snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
                        SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
+               msleep(400);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
index 0a60677397b3dedb0b9652e112137e9b3c03f3d4..4c29bd2ae75cf987b34e28e28298ab026bb8c40e 100644 (file)
@@ -574,6 +574,7 @@ static const struct regmap_config wm8974_regmap = {
        .max_register = WM8974_MONOMIX,
        .reg_defaults = wm8974_reg_defaults,
        .num_reg_defaults = ARRAY_SIZE(wm8974_reg_defaults),
+       .cache_type = REGCACHE_FLAT,
 };
 
 static int wm8974_probe(struct snd_soc_codec *codec)
index c1c9c2e3525bf88f8cf6de409fcc9370320dd3b2..2ccb8bccc9d4cc4a79c6a94abe4dfb1566872737 100644 (file)
@@ -223,8 +223,8 @@ static void mcasp_start_tx(struct davinci_mcasp *mcasp)
 
        /* wait for XDATA to be cleared */
        cnt = 0;
-       while (!(mcasp_get_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG) &
-                ~XRDATA) && (cnt < 100000))
+       while ((mcasp_get_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG) & XRDATA) &&
+              (cnt < 100000))
                cnt++;
 
        /* Release TX state machine */
index ffd5f9acc849ffb3d8152bdfa1e5c13a26342668..08b460ba06efc28906fe1094e9e68b7c4e1e66cf 100644 (file)
@@ -505,6 +505,24 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
                                           FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
                        regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
                                           FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
+
+                       /*
+                        * For sai master mode, after several open/close sai,
+                        * there will be no frame clock, and can't recover
+                        * anymore. Add software reset to fix this issue.
+                        * This is a hardware bug, and will be fix in the
+                        * next sai version.
+                        */
+                       if (!sai->is_slave_mode) {
+                               /* Software Reset for both Tx and Rx */
+                               regmap_write(sai->regmap,
+                                            FSL_SAI_TCSR, FSL_SAI_CSR_SR);
+                               regmap_write(sai->regmap,
+                                            FSL_SAI_RCSR, FSL_SAI_CSR_SR);
+                               /* Clear SR bit to finish the reset */
+                               regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
+                               regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
+                       }
                }
                break;
        default:
index ac72ff5055bbce626550c4fd277a96c351321b25..5a806da89f42b49967ea52d15eac0f3348b7b873 100644 (file)
@@ -152,8 +152,10 @@ static int rk_spdif_trigger(struct snd_pcm_substream *substream,
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
                ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
-                                  SPDIF_DMACR_TDE_ENABLE,
-                                  SPDIF_DMACR_TDE_ENABLE);
+                                  SPDIF_DMACR_TDE_ENABLE |
+                                  SPDIF_DMACR_TDL_MASK,
+                                  SPDIF_DMACR_TDE_ENABLE |
+                                  SPDIF_DMACR_TDL(16));
 
                if (ret != 0)
                        return ret;
index 921b4095fb92c98d7b09fb8d7ec8bbea7f9139bb..3ef12770ae124d705d59b1916e5c400210aa0bf5 100644 (file)
@@ -42,7 +42,7 @@
 
 #define SPDIF_DMACR_TDL_SHIFT  0
 #define SPDIF_DMACR_TDL(x)     ((x) << SPDIF_DMACR_TDL_SHIFT)
-#define SPDIF_DMACR_TDL_MASK   (0x1f << SDPIF_DMACR_TDL_SHIFT)
+#define SPDIF_DMACR_TDL_MASK   (0x1f << SPDIF_DMACR_TDL_SHIFT)
 
 /*
  * XFER
index f494dced3c11e3a662b93d95df9ea53ff2767dfc..4f85757009b3e44e2246cc21f4387d0948056da3 100644 (file)
@@ -1354,6 +1354,8 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
                }
        }
 
+       snd_usb_mixer_fu_apply_quirk(state->mixer, cval, unitid, kctl);
+
        range = (cval->max - cval->min) / cval->res;
        /*
         * Are there devices with volume range more than 255? I use a bit more
index 6a803eff87f71110049d9c39cb07025d2c64d828..ddca6547399b0103b37abbdf73cfa5c9e710a7fd 100644 (file)
@@ -348,13 +348,6 @@ static struct usbmix_name_map bose_companion5_map[] = {
        { 0 }   /* terminator */
 };
 
-/* Dragonfly DAC 1.2, the dB conversion factor is 1 instead of 256 */
-static struct usbmix_dB_map dragonfly_1_2_dB = {0, 5000};
-static struct usbmix_name_map dragonfly_1_2_map[] = {
-       { 7, NULL, .dB = &dragonfly_1_2_dB },
-       { 0 }   /* terminator */
-};
-
 /*
  * Control map entries
  */
@@ -470,11 +463,6 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
                .id = USB_ID(0x05a7, 0x1020),
                .map = bose_companion5_map,
        },
-       {
-               /* Dragonfly DAC 1.2 */
-               .id = USB_ID(0x21b4, 0x0081),
-               .map = dragonfly_1_2_map,
-       },
        { 0 } /* terminator */
 };
 
index fe91184ce83247d8b0360bab09e94c8f7cb720d8..0ce888dceed0ea24db7b677eeb93b05c728ab40a 100644 (file)
@@ -37,6 +37,7 @@
 #include <sound/control.h>
 #include <sound/hwdep.h>
 #include <sound/info.h>
+#include <sound/tlv.h>
 
 #include "usbaudio.h"
 #include "mixer.h"
@@ -1825,3 +1826,39 @@ void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
        }
 }
 
+static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
+                                        struct snd_kcontrol *kctl)
+{
+       /* Approximation using 10 ranges based on output measurement on hw v1.2.
+        * This seems close to the cubic mapping e.g. alsamixer uses. */
+       static const DECLARE_TLV_DB_RANGE(scale,
+                0,  1, TLV_DB_MINMAX_ITEM(-5300, -4970),
+                2,  5, TLV_DB_MINMAX_ITEM(-4710, -4160),
+                6,  7, TLV_DB_MINMAX_ITEM(-3884, -3710),
+                8, 14, TLV_DB_MINMAX_ITEM(-3443, -2560),
+               15, 16, TLV_DB_MINMAX_ITEM(-2475, -2324),
+               17, 19, TLV_DB_MINMAX_ITEM(-2228, -2031),
+               20, 26, TLV_DB_MINMAX_ITEM(-1910, -1393),
+               27, 31, TLV_DB_MINMAX_ITEM(-1322, -1032),
+               32, 40, TLV_DB_MINMAX_ITEM(-968, -490),
+               41, 50, TLV_DB_MINMAX_ITEM(-441, 0),
+       );
+
+       usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk\n");
+       kctl->tlv.p = scale;
+       kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
+       kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
+}
+
+void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
+                                 struct usb_mixer_elem_info *cval, int unitid,
+                                 struct snd_kcontrol *kctl)
+{
+       switch (mixer->chip->usb_id) {
+       case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
+               if (unitid == 7 && cval->min == 0 && cval->max == 50)
+                       snd_dragonfly_quirk_db_scale(mixer, kctl);
+               break;
+       }
+}
+
index bdbfab093816a59772353635fd38eae79ddb3b38..177c329cd4ddb792e144f4ecd945976e6ab9b1a4 100644 (file)
@@ -9,5 +9,9 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
 void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
                                    int unitid);
 
+void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
+                                 struct usb_mixer_elem_info *cval, int unitid,
+                                 struct snd_kcontrol *kctl);
+
 #endif /* SND_USB_MIXER_QUIRKS_H */
 
index 7016ad8981873ca046000d631ac112c12ed62dc1..b6c0c8e3b450c5f0dd41ea308f61efe15b3446b8 100644 (file)
@@ -1125,6 +1125,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
        case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */
        case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */
        case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
+       case USB_ID(0x21B4, 0x0081): /* AudioQuest DragonFly */
                return true;
        }
        return false;
index 65461f821a75a7ffd3d0bdab471052e7061c8824..7a2f449bd85d02d7f6571fa4f5b3091df81a04d9 100644 (file)
@@ -1114,7 +1114,7 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, struct irq_phys_map *map)
                        return true;
        }
 
-       return dist_active_irq(vcpu);
+       return vgic_irq_is_active(vcpu, map->virt_irq);
 }
 
 /*