Merge tag 'fixes-for-v3.19-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Jan 2015 00:27:23 +0000 (16:27 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Jan 2015 00:27:23 +0000 (16:27 -0800)
Felipe writes:

usb: fixes for v3.19-rc6

The final set of fixes for v3.19. Two of the fixes are
related to dwc3 scatter/gather implementation when we have
more requests queued than available TRBs, while the other
is a build fix for mv-usb PHY.

Signed-off-by: Felipe Balbi <balbi@ti.com>
91 files changed:
Makefile
arch/arm64/configs/defconfig
arch/arm64/include/asm/dma-mapping.h
arch/arm64/include/asm/pgtable.h
arch/arm64/kernel/suspend.c
arch/parisc/include/asm/ldcw.h
arch/x86/kvm/mmu.c
arch/x86/kvm/vmx.c
drivers/char/agp/ali-agp.c
drivers/char/agp/amd64-agp.c
drivers/char/agp/ati-agp.c
drivers/char/agp/backend.c
drivers/char/agp/intel-agp.c
drivers/char/agp/intel-gtt.c
drivers/char/agp/nvidia-agp.c
drivers/char/agp/via-agp.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/ipmi/ipmi_ssif.c
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
drivers/gpu/drm/amd/amdkfd/kfd_process.c
drivers/gpu/drm/amd/amdkfd/kfd_topology.c
drivers/gpu/drm/amd/include/kgd_kfd_interface.h
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/msm/adreno/adreno_gpu.c
drivers/gpu/drm/msm/hdmi/hdmi_connector.c
drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
drivers/gpu/drm/msm/mdp/mdp_kms.c
drivers/gpu/drm/msm/mdp/mdp_kms.h
drivers/gpu/drm/msm/msm_atomic.c
drivers/gpu/drm/msm/msm_drv.c
drivers/gpu/drm/msm/msm_drv.h
drivers/gpu/drm/msm/msm_fbdev.c
drivers/gpu/drm/msm/msm_gem.c
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nouveau_ttm.c
drivers/gpu/drm/radeon/radeon_gem.c
drivers/gpu/drm/radeon/radeon_kfd.c
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/tegra/dc.c
drivers/gpu/drm/tegra/drm.c
drivers/gpu/drm/tegra/gem.c
drivers/md/dm-thin.c
drivers/md/dm.c
drivers/phy/phy-miphy28lp.c
drivers/phy/phy-omap-control.c
drivers/phy/phy-sun4i-usb.c
drivers/phy/phy-ti-pipe3.c
drivers/staging/lustre/lustre/llite/namei.c
drivers/usb/chipidea/core.c
drivers/usb/chipidea/host.c
drivers/usb/gadget/udc/bdc/bdc_ep.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci.c
drivers/usb/phy/phy.c
drivers/usb/serial/console.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/generic.c
drivers/usb/serial/keyspan.c
drivers/usb/serial/option.c
drivers/usb/serial/qcserial.c
drivers/usb/storage/uas-detect.h
drivers/usb/storage/unusual_uas.h
include/drm/drmP.h
include/drm/drm_gem.h
include/linux/audit.h
include/linux/phy/omap_control_phy.h
kernel/audit.c
kernel/auditfilter.c
kernel/auditsc.c
mm/memory.c
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_priv.h
virt/kvm/kvm_main.c

index b1c3254441f3f3353465ef8b3cf2e563abe70bf4..ef748e17702f5109bf2678fb57f7929ef411d938 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 19
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME = Diseased Newt
 
 # *DOCUMENTATION*
index dd301be89ecccfb6fe9f1d7c02a69bafcfea1559..5376d908eabedbdc496648c1fe2f4316fcd1cbe3 100644 (file)
@@ -1,6 +1,7 @@
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
 CONFIG_AUDIT=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -13,14 +14,12 @@ CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RESOURCE_COUNTERS=y
 CONFIG_MEMCG=y
 CONFIG_MEMCG_SWAP=y
 CONFIG_MEMCG_KMEM=y
 CONFIG_CGROUP_HUGETLB=y
 # CONFIG_UTS_NS is not set
 # CONFIG_IPC_NS is not set
-# CONFIG_PID_NS is not set
 # CONFIG_NET_NS is not set
 CONFIG_SCHED_AUTOGROUP=y
 CONFIG_BLK_DEV_INITRD=y
@@ -92,7 +91,6 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_VIRTIO_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
-# CONFIG_HMC_DRV is not set
 CONFIG_SPI=y
 CONFIG_SPI_PL022=y
 CONFIG_GPIO_PL061=y
@@ -133,6 +131,8 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS=y
 CONFIG_FANOTIFY=y
 CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA=y
+CONFIG_AUTOFS4_FS=y
 CONFIG_FUSE_FS=y
 CONFIG_CUSE=y
 CONFIG_VFAT_FS=y
@@ -152,14 +152,15 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOCKUP_DETECTOR=y
 # CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
 # CONFIG_FTRACE is not set
+CONFIG_KEYS=y
 CONFIG_SECURITY=y
 CONFIG_CRYPTO_ANSI_CPRNG=y
 CONFIG_ARM64_CRYPTO=y
 CONFIG_CRYPTO_SHA1_ARM64_CE=y
 CONFIG_CRYPTO_SHA2_ARM64_CE=y
 CONFIG_CRYPTO_GHASH_ARM64_CE=y
-CONFIG_CRYPTO_AES_ARM64_CE=y
 CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
 CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
 CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
index d34189bceff7760a83b6095339bd3bce7646d4ac..9ce3e680ae1c6f2b78dab11bf5d89384f5366f23 100644 (file)
@@ -52,13 +52,14 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
        dev->archdata.dma_ops = ops;
 }
 
-static inline int set_arch_dma_coherent_ops(struct device *dev)
+static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+                                     struct iommu_ops *iommu, bool coherent)
 {
-       dev->archdata.dma_coherent = true;
-       set_dma_ops(dev, &coherent_swiotlb_dma_ops);
-       return 0;
+       dev->archdata.dma_coherent = coherent;
+       if (coherent)
+               set_dma_ops(dev, &coherent_swiotlb_dma_ops);
 }
-#define set_arch_dma_coherent_ops      set_arch_dma_coherent_ops
+#define arch_setup_dma_ops     arch_setup_dma_ops
 
 /* do not use this function in a driver */
 static inline bool is_device_dma_coherent(struct device *dev)
index df22314f57cfda8972fff87a3071f6b82eb0ad71..210d632aa5ad38b44a6a0b49d876e0c9cab5ca6a 100644 (file)
@@ -298,7 +298,6 @@ void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
 #define pfn_pmd(pfn,prot)      (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
 #define mk_pmd(page,prot)      pfn_pmd(page_to_pfn(page),prot)
 
-#define pmd_page(pmd)           pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
 #define pud_write(pud)         pte_write(pud_pte(pud))
 #define pud_pfn(pud)           (((pud_val(pud) & PUD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
 
@@ -401,7 +400,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
        return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
 }
 
-#define pud_page(pud)           pmd_page(pud_pmd(pud))
+#define pud_page(pud)          pfn_to_page(__phys_to_pfn(pud_val(pud) & PHYS_MASK))
 
 #endif /* CONFIG_ARM64_PGTABLE_LEVELS > 2 */
 
@@ -437,6 +436,8 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long addr)
        return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(addr);
 }
 
+#define pgd_page(pgd)          pfn_to_page(__phys_to_pfn(pgd_val(pgd) & PHYS_MASK))
+
 #endif  /* CONFIG_ARM64_PGTABLE_LEVELS > 3 */
 
 #define pgd_ERROR(pgd)         __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
index 3771b72b6569fbf87acefb6de0741a5af8ec6548..2d6b6065fe7f4ea7ceaf9e728066edb23dae5a0b 100644 (file)
@@ -5,6 +5,7 @@
 #include <asm/debug-monitors.h>
 #include <asm/pgtable.h>
 #include <asm/memory.h>
+#include <asm/mmu_context.h>
 #include <asm/smp_plat.h>
 #include <asm/suspend.h>
 #include <asm/tlbflush.h>
@@ -98,7 +99,18 @@ int __cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
         */
        ret = __cpu_suspend_enter(arg, fn);
        if (ret == 0) {
-               cpu_switch_mm(mm->pgd, mm);
+               /*
+                * We are resuming from reset with TTBR0_EL1 set to the
+                * idmap to enable the MMU; restore the active_mm mappings in
+                * TTBR0_EL1 unless the active_mm == &init_mm, in which case
+                * the thread entered __cpu_suspend with TTBR0_EL1 set to
+                * reserved TTBR0 page tables and should be restored as such.
+                */
+               if (mm == &init_mm)
+                       cpu_set_reserved_ttbr0();
+               else
+                       cpu_switch_mm(mm->pgd, mm);
+
                flush_tlb_all();
 
                /*
index d2d11b7055ba640178817917d04c46364453c069..8121aa6db2ff21ad37510879dd82a3fe7ba7fa29 100644 (file)
 
 #endif /*!CONFIG_PA20*/
 
-/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*.  */
+/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*.
+   We don't explicitly expose that "*a" may be written as reload
+   fails to find a register in class R1_REGS when "a" needs to be
+   reloaded when generating 64-bit PIC code.  Instead, we clobber
+   memory to indicate to the compiler that the assembly code reads
+   or writes to items other than those listed in the input and output
+   operands.  This may pessimize the code somewhat but __ldcw is
+   usually used within code blocks surrounded by memory barriors.  */
 #define __ldcw(a) ({                                           \
        unsigned __ret;                                         \
-       __asm__ __volatile__(__LDCW " 0(%2),%0"                 \
-               : "=r" (__ret), "+m" (*(a)) : "r" (a));         \
+       __asm__ __volatile__(__LDCW " 0(%1),%0"                 \
+               : "=r" (__ret) : "r" (a) : "memory");           \
        __ret;                                                  \
 })
 
index 10fbed126b1121ae5fde2f7ccfbf04133b5f8771..f83fc6c5e0bad6712e9f172acaba931c47cd32cd 100644 (file)
@@ -4448,7 +4448,7 @@ void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm)
         * zap all shadow pages.
         */
        if (unlikely(kvm_current_mmio_generation(kvm) == 0)) {
-               printk_ratelimited(KERN_INFO "kvm: zapping shadow pages for mmio generation wraparound\n");
+               printk_ratelimited(KERN_DEBUG "kvm: zapping shadow pages for mmio generation wraparound\n");
                kvm_mmu_invalidate_zap_all_pages(kvm);
        }
 }
index feb852b04598b63d187b0870db26d008c81a13d8..d4c58d884838d1539cb52e13df3c6893459a98af 100644 (file)
@@ -5840,53 +5840,10 @@ static __init int hardware_setup(void)
        memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE);
        memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE);
 
-       vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
-       vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
-       vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
-       vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
-       vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
-       vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
-       vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true);
-
-       memcpy(vmx_msr_bitmap_legacy_x2apic,
-                       vmx_msr_bitmap_legacy, PAGE_SIZE);
-       memcpy(vmx_msr_bitmap_longmode_x2apic,
-                       vmx_msr_bitmap_longmode, PAGE_SIZE);
-
-       if (enable_apicv) {
-               for (msr = 0x800; msr <= 0x8ff; msr++)
-                       vmx_disable_intercept_msr_read_x2apic(msr);
-
-               /* According SDM, in x2apic mode, the whole id reg is used.
-                * But in KVM, it only use the highest eight bits. Need to
-                * intercept it */
-               vmx_enable_intercept_msr_read_x2apic(0x802);
-               /* TMCCT */
-               vmx_enable_intercept_msr_read_x2apic(0x839);
-               /* TPR */
-               vmx_disable_intercept_msr_write_x2apic(0x808);
-               /* EOI */
-               vmx_disable_intercept_msr_write_x2apic(0x80b);
-               /* SELF-IPI */
-               vmx_disable_intercept_msr_write_x2apic(0x83f);
-       }
-
-       if (enable_ept) {
-               kvm_mmu_set_mask_ptes(0ull,
-                       (enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull,
-                       (enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull,
-                       0ull, VMX_EPT_EXECUTABLE_MASK);
-               ept_set_mmio_spte_mask();
-               kvm_enable_tdp();
-       } else
-               kvm_disable_tdp();
-
-       update_ple_window_actual_max();
-
        if (setup_vmcs_config(&vmcs_config) < 0) {
                r = -EIO;
                goto out7;
-    }
+       }
 
        if (boot_cpu_has(X86_FEATURE_NX))
                kvm_enable_efer_bits(EFER_NX);
@@ -5945,6 +5902,49 @@ static __init int hardware_setup(void)
        if (nested)
                nested_vmx_setup_ctls_msrs();
 
+       vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
+       vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
+       vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
+       vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
+       vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
+       vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
+       vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true);
+
+       memcpy(vmx_msr_bitmap_legacy_x2apic,
+                       vmx_msr_bitmap_legacy, PAGE_SIZE);
+       memcpy(vmx_msr_bitmap_longmode_x2apic,
+                       vmx_msr_bitmap_longmode, PAGE_SIZE);
+
+       if (enable_apicv) {
+               for (msr = 0x800; msr <= 0x8ff; msr++)
+                       vmx_disable_intercept_msr_read_x2apic(msr);
+
+               /* According SDM, in x2apic mode, the whole id reg is used.
+                * But in KVM, it only use the highest eight bits. Need to
+                * intercept it */
+               vmx_enable_intercept_msr_read_x2apic(0x802);
+               /* TMCCT */
+               vmx_enable_intercept_msr_read_x2apic(0x839);
+               /* TPR */
+               vmx_disable_intercept_msr_write_x2apic(0x808);
+               /* EOI */
+               vmx_disable_intercept_msr_write_x2apic(0x80b);
+               /* SELF-IPI */
+               vmx_disable_intercept_msr_write_x2apic(0x83f);
+       }
+
+       if (enable_ept) {
+               kvm_mmu_set_mask_ptes(0ull,
+                       (enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull,
+                       (enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull,
+                       0ull, VMX_EPT_EXECUTABLE_MASK);
+               ept_set_mmio_spte_mask();
+               kvm_enable_tdp();
+       } else
+               kvm_disable_tdp();
+
+       update_ple_window_actual_max();
+
        return alloc_kvm_area();
 
 out7:
index 19db036676505519fb19538299afe2f5c84dd42a..dcbbb4ea3cc1d7040a847799fad2415e44a24e08 100644 (file)
@@ -417,6 +417,6 @@ static void __exit agp_ali_cleanup(void)
 module_init(agp_ali_init);
 module_exit(agp_ali_cleanup);
 
-MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
+MODULE_AUTHOR("Dave Jones");
 MODULE_LICENSE("GPL and additional rights");
 
index 3b47ed0310e1fcbb73eda184cb810c1b3ea2889b..0ef350010766355c933ebe7e48ce41a78656b0ac 100644 (file)
@@ -813,6 +813,6 @@ static void __exit agp_amd64_cleanup(void)
 module_init(agp_amd64_mod_init);
 module_exit(agp_amd64_cleanup);
 
-MODULE_AUTHOR("Dave Jones <davej@redhat.com>, Andi Kleen");
+MODULE_AUTHOR("Dave Jones, Andi Kleen");
 module_param(agp_try_unsupported, bool, 0);
 MODULE_LICENSE("GPL");
index 18a7a6baa304eadfc3968a640f97ac3da590b106..75a9786a77e6307711a74bcde8f4dd7fee8fcae0 100644 (file)
@@ -579,6 +579,6 @@ static void __exit agp_ati_cleanup(void)
 module_init(agp_ati_init);
 module_exit(agp_ati_cleanup);
 
-MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
+MODULE_AUTHOR("Dave Jones");
 MODULE_LICENSE("GPL and additional rights");
 
index 317c28ce8328bb310c892c8bab4aca60cbbbc4f5..38ffb281df97c71eee3dc8980a98e19df3ca24d3 100644 (file)
@@ -356,7 +356,7 @@ static __init int agp_setup(char *s)
 __setup("agp=", agp_setup);
 #endif
 
-MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
+MODULE_AUTHOR("Dave Jones, Jeff Hartmann");
 MODULE_DESCRIPTION("AGP GART driver");
 MODULE_LICENSE("GPL and additional rights");
 MODULE_ALIAS_MISCDEV(AGPGART_MINOR);
index f9b9ca5d31b7946c3b1407ef692db1c2c149c628..0a21daed5b6251edd8136bc014d073ab734a2a0a 100644 (file)
@@ -920,5 +920,5 @@ static void __exit agp_intel_cleanup(void)
 module_init(agp_intel_init);
 module_exit(agp_intel_cleanup);
 
-MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
+MODULE_AUTHOR("Dave Jones, Various @Intel");
 MODULE_LICENSE("GPL and additional rights");
index f3334829e55a3e6ac393a348c6da0e7aef159709..92aa43fa8d70205e621cc3f3fe03e8bbcd94a42f 100644 (file)
@@ -1438,5 +1438,5 @@ void intel_gmch_remove(void)
 }
 EXPORT_SYMBOL(intel_gmch_remove);
 
-MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
+MODULE_AUTHOR("Dave Jones, Various @Intel");
 MODULE_LICENSE("GPL and additional rights");
index a1861b75eb31a9fe433e32105ef623092741052e..6c8d39cb566e32ea4ac14c818f3bd16962823097 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Nvidia AGPGART routines.
  * Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up
- * to work in 2.5 by Dave Jones <davej@redhat.com>
+ * to work in 2.5 by Dave Jones.
  */
 
 #include <linux/module.h>
index 228f20cddc056244711805b20c44d168a4d94493..a4961d35e94046de34896c492e032b9c5e72c1ae 100644 (file)
@@ -595,4 +595,4 @@ module_init(agp_via_init);
 module_exit(agp_via_cleanup);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
+MODULE_AUTHOR("Dave Jones");
index 5fa83f751378fb56ecc7da11a16d2c8386fb6862..6b65fa4e0c5586895df2b26ee499c9e5ad4d8b2c 100644 (file)
@@ -199,18 +199,6 @@ struct bmc_device {
        int                    guid_set;
        char                   name[16];
        struct kref            usecount;
-
-       /* bmc device attributes */
-       struct device_attribute device_id_attr;
-       struct device_attribute provides_dev_sdrs_attr;
-       struct device_attribute revision_attr;
-       struct device_attribute firmware_rev_attr;
-       struct device_attribute version_attr;
-       struct device_attribute add_dev_support_attr;
-       struct device_attribute manufacturer_id_attr;
-       struct device_attribute product_id_attr;
-       struct device_attribute guid_attr;
-       struct device_attribute aux_firmware_rev_attr;
 };
 #define to_bmc_device(x) container_of((x), struct bmc_device, pdev.dev)
 
@@ -2252,7 +2240,7 @@ static ssize_t device_id_show(struct device *dev,
 
        return snprintf(buf, 10, "%u\n", bmc->id.device_id);
 }
-DEVICE_ATTR(device_id, S_IRUGO, device_id_show, NULL);
+static DEVICE_ATTR(device_id, S_IRUGO, device_id_show, NULL);
 
 static ssize_t provides_device_sdrs_show(struct device *dev,
                                         struct device_attribute *attr,
@@ -2263,7 +2251,8 @@ static ssize_t provides_device_sdrs_show(struct device *dev,
        return snprintf(buf, 10, "%u\n",
                        (bmc->id.device_revision & 0x80) >> 7);
 }
-DEVICE_ATTR(provides_device_sdrs, S_IRUGO, provides_device_sdrs_show, NULL);
+static DEVICE_ATTR(provides_device_sdrs, S_IRUGO, provides_device_sdrs_show,
+                  NULL);
 
 static ssize_t revision_show(struct device *dev, struct device_attribute *attr,
                             char *buf)
@@ -2273,7 +2262,7 @@ static ssize_t revision_show(struct device *dev, struct device_attribute *attr,
        return snprintf(buf, 20, "%u\n",
                        bmc->id.device_revision & 0x0F);
 }
-DEVICE_ATTR(revision, S_IRUGO, revision_show, NULL);
+static DEVICE_ATTR(revision, S_IRUGO, revision_show, NULL);
 
 static ssize_t firmware_revision_show(struct device *dev,
                                      struct device_attribute *attr,
@@ -2284,7 +2273,7 @@ static ssize_t firmware_revision_show(struct device *dev,
        return snprintf(buf, 20, "%u.%x\n", bmc->id.firmware_revision_1,
                        bmc->id.firmware_revision_2);
 }
-DEVICE_ATTR(firmware_revision, S_IRUGO, firmware_revision_show, NULL);
+static DEVICE_ATTR(firmware_revision, S_IRUGO, firmware_revision_show, NULL);
 
 static ssize_t ipmi_version_show(struct device *dev,
                                 struct device_attribute *attr,
@@ -2296,7 +2285,7 @@ static ssize_t ipmi_version_show(struct device *dev,
                        ipmi_version_major(&bmc->id),
                        ipmi_version_minor(&bmc->id));
 }
-DEVICE_ATTR(ipmi_version, S_IRUGO, ipmi_version_show, NULL);
+static DEVICE_ATTR(ipmi_version, S_IRUGO, ipmi_version_show, NULL);
 
 static ssize_t add_dev_support_show(struct device *dev,
                                    struct device_attribute *attr,
@@ -2307,7 +2296,8 @@ static ssize_t add_dev_support_show(struct device *dev,
        return snprintf(buf, 10, "0x%02x\n",
                        bmc->id.additional_device_support);
 }
-DEVICE_ATTR(additional_device_support, S_IRUGO, add_dev_support_show, NULL);
+static DEVICE_ATTR(additional_device_support, S_IRUGO, add_dev_support_show,
+                  NULL);
 
 static ssize_t manufacturer_id_show(struct device *dev,
                                    struct device_attribute *attr,
@@ -2317,7 +2307,7 @@ static ssize_t manufacturer_id_show(struct device *dev,
 
        return snprintf(buf, 20, "0x%6.6x\n", bmc->id.manufacturer_id);
 }
-DEVICE_ATTR(manufacturer_id, S_IRUGO, manufacturer_id_show, NULL);
+static DEVICE_ATTR(manufacturer_id, S_IRUGO, manufacturer_id_show, NULL);
 
 static ssize_t product_id_show(struct device *dev,
                               struct device_attribute *attr,
@@ -2327,7 +2317,7 @@ static ssize_t product_id_show(struct device *dev,
 
        return snprintf(buf, 10, "0x%4.4x\n", bmc->id.product_id);
 }
-DEVICE_ATTR(product_id, S_IRUGO, product_id_show, NULL);
+static DEVICE_ATTR(product_id, S_IRUGO, product_id_show, NULL);
 
 static ssize_t aux_firmware_rev_show(struct device *dev,
                                     struct device_attribute *attr,
@@ -2341,7 +2331,7 @@ static ssize_t aux_firmware_rev_show(struct device *dev,
                        bmc->id.aux_firmware_revision[1],
                        bmc->id.aux_firmware_revision[0]);
 }
-DEVICE_ATTR(aux_firmware_revision, S_IRUGO, aux_firmware_rev_show, NULL);
+static DEVICE_ATTR(aux_firmware_revision, S_IRUGO, aux_firmware_rev_show, NULL);
 
 static ssize_t guid_show(struct device *dev, struct device_attribute *attr,
                         char *buf)
@@ -2352,7 +2342,7 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr,
                        (long long) bmc->guid[0],
                        (long long) bmc->guid[8]);
 }
-DEVICE_ATTR(guid, S_IRUGO, guid_show, NULL);
+static DEVICE_ATTR(guid, S_IRUGO, guid_show, NULL);
 
 static struct attribute *bmc_dev_attrs[] = {
        &dev_attr_device_id.attr,
@@ -2392,10 +2382,10 @@ cleanup_bmc_device(struct kref *ref)
 
        if (bmc->id.aux_firmware_revision_set)
                device_remove_file(&bmc->pdev.dev,
-                                  &bmc->aux_firmware_rev_attr);
+                                  &dev_attr_aux_firmware_revision);
        if (bmc->guid_set)
                device_remove_file(&bmc->pdev.dev,
-                                  &bmc->guid_attr);
+                                  &dev_attr_guid);
 
        platform_device_unregister(&bmc->pdev);
 }
@@ -2422,16 +2412,14 @@ static int create_bmc_files(struct bmc_device *bmc)
        int err;
 
        if (bmc->id.aux_firmware_revision_set) {
-               bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
                err = device_create_file(&bmc->pdev.dev,
-                                  &bmc->aux_firmware_rev_attr);
+                                        &dev_attr_aux_firmware_revision);
                if (err)
                        goto out;
        }
        if (bmc->guid_set) {
-               bmc->guid_attr.attr.name = "guid";
                err = device_create_file(&bmc->pdev.dev,
-                                  &bmc->guid_attr);
+                                        &dev_attr_guid);
                if (err)
                        goto out_aux_firm;
        }
@@ -2441,7 +2429,7 @@ static int create_bmc_files(struct bmc_device *bmc)
 out_aux_firm:
        if (bmc->id.aux_firmware_revision_set)
                device_remove_file(&bmc->pdev.dev,
-                                  &bmc->aux_firmware_rev_attr);
+                                  &dev_attr_aux_firmware_revision);
 out:
        return err;
 }
index e178ac27e73c6de46ef48c2d94464cd64b4ca011..fd5a5e85d7dc604e2ebe237ee34ce9355d81d866 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/dmi.h>
 #include <linux/kthread.h>
 #include <linux/acpi.h>
+#include <linux/ctype.h>
 
 #define PFX "ipmi_ssif: "
 #define DEVICE_NAME "ipmi_ssif"
index 4f7b275f2f7b0fdbb488055057c3291a1aab3a70..7d4974b83af7821649c7eff1f75ee4d0b05758e6 100644 (file)
@@ -121,13 +121,9 @@ static int kfd_open(struct inode *inode, struct file *filep)
        if (IS_ERR(process))
                return PTR_ERR(process);
 
-       process->is_32bit_user_mode = is_32bit_user_mode;
-
        dev_dbg(kfd_device, "process %d opened, compat mode (32 bit) - %d\n",
                process->pasid, process->is_32bit_user_mode);
 
-       kfd_init_apertures(process);
-
        return 0;
 }
 
index 66df4da01c29a200d64a6a801d8d250231d7d269..e64aa99e5e416349071f3c0906be347ed42e3e53 100644 (file)
@@ -299,13 +299,13 @@ int kfd_init_apertures(struct kfd_process *process)
        struct kfd_dev *dev;
        struct kfd_process_device *pdd;
 
-       mutex_lock(&process->mutex);
-
        /*Iterating over all devices*/
        while ((dev = kfd_topology_enum_kfd_devices(id)) != NULL &&
                id < NUM_OF_SUPPORTED_GPUS) {
 
                pdd = kfd_get_process_device_data(dev, process, 1);
+               if (!pdd)
+                       return -1;
 
                /*
                 * For 64 bit process aperture will be statically reserved in
@@ -348,8 +348,6 @@ int kfd_init_apertures(struct kfd_process *process)
                id++;
        }
 
-       mutex_unlock(&process->mutex);
-
        return 0;
 }
 
index b85eb0b830b41d5d894efebb2a3e6fab83ca7552..3c76ef05cbcf798483b482ac09b7bc62223d92c5 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/slab.h>
 #include <linux/amd-iommu.h>
 #include <linux/notifier.h>
+#include <linux/compat.h>
+
 struct mm_struct;
 
 #include "kfd_priv.h"
@@ -285,8 +287,15 @@ static struct kfd_process *create_process(const struct task_struct *thread)
        if (err != 0)
                goto err_process_pqm_init;
 
+       /* init process apertures*/
+       process->is_32bit_user_mode = is_compat_task();
+       if (kfd_init_apertures(process) != 0)
+               goto err_init_apretures;
+
        return process;
 
+err_init_apretures:
+       pqm_uninit(&process->pqm);
 err_process_pqm_init:
        hash_del_rcu(&process->kfd_processes);
        synchronize_rcu();
index 5733e2859e8aabbc361ce821f5e337c0008dd6a3..b11792d7e70e2a6fca1fdc15636c4672fb3165dc 100644 (file)
@@ -700,8 +700,6 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
                                dev->node_props.simd_per_cu);
                sysfs_show_32bit_prop(buffer, "max_slots_scratch_cu",
                                dev->node_props.max_slots_scratch_cu);
-               sysfs_show_32bit_prop(buffer, "engine_id",
-                               dev->node_props.engine_id);
                sysfs_show_32bit_prop(buffer, "vendor_id",
                                dev->node_props.vendor_id);
                sysfs_show_32bit_prop(buffer, "device_id",
@@ -715,6 +713,12 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
                                                dev->gpu->kgd));
                        sysfs_show_64bit_prop(buffer, "local_mem_size",
                                        kfd2kgd->get_vmem_size(dev->gpu->kgd));
+
+                       sysfs_show_32bit_prop(buffer, "fw_version",
+                                       kfd2kgd->get_fw_version(
+                                                       dev->gpu->kgd,
+                                                       KGD_ENGINE_MEC1));
+
                }
 
                ret = sysfs_show_32bit_prop(buffer, "max_engine_clk_ccompute",
index 9c729dd8dd50a077d35f77ed3646438fb80d5c86..47b551970a14aed723b24f7d2662293fa8914dff 100644 (file)
@@ -45,6 +45,17 @@ enum kgd_memory_pool {
        KGD_POOL_FRAMEBUFFER = 3,
 };
 
+enum kgd_engine_type {
+       KGD_ENGINE_PFP = 1,
+       KGD_ENGINE_ME,
+       KGD_ENGINE_CE,
+       KGD_ENGINE_MEC1,
+       KGD_ENGINE_MEC2,
+       KGD_ENGINE_RLC,
+       KGD_ENGINE_SDMA,
+       KGD_ENGINE_MAX
+};
+
 struct kgd2kfd_shared_resources {
        /* Bit n == 1 means VMID n is available for KFD. */
        unsigned int compute_vmid_bitmap;
@@ -137,6 +148,8 @@ struct kgd2kfd_calls {
  *
  * @hqd_destroy: Destructs and preempts the queue assigned to that hqd slot.
  *
+ * @get_fw_version: Returns FW versions from the header
+ *
  * This structure contains function pointers to services that the kgd driver
  * provides to amdkfd driver.
  *
@@ -176,6 +189,8 @@ struct kfd2kgd_calls {
        int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type,
                                unsigned int timeout, uint32_t pipe_id,
                                uint32_t queue_id);
+       uint16_t (*get_fw_version)(struct kgd_dev *kgd,
+                               enum kgd_engine_type type);
 };
 
 bool kgd2kfd_init(unsigned interface_version,
index 4a78a773151ce71f464d36cc4d1d6d887eea1619..bbdbe4721573a92667fe3989bbc1e0be8123bc2b 100644 (file)
@@ -61,7 +61,7 @@ drm_atomic_helper_plane_changed(struct drm_atomic_state *state,
        struct drm_crtc_state *crtc_state;
 
        if (plane->state->crtc) {
-               crtc_state = state->crtc_states[drm_crtc_index(plane->crtc)];
+               crtc_state = state->crtc_states[drm_crtc_index(plane->state->crtc)];
 
                if (WARN_ON(!crtc_state))
                        return;
index f5a5f18efa5bf230d810d8c031bb30cfddd0390a..4d79dad9d44fad0ac48b2b81177ffda8430b390b 100644 (file)
@@ -830,6 +830,8 @@ drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
  * vblank events since the system was booted, including lost events due to
  * modesetting activity.
  *
+ * This is the legacy version of drm_crtc_vblank_count().
+ *
  * Returns:
  * The software vblank counter.
  */
@@ -843,6 +845,25 @@ u32 drm_vblank_count(struct drm_device *dev, int crtc)
 }
 EXPORT_SYMBOL(drm_vblank_count);
 
+/**
+ * drm_crtc_vblank_count - retrieve "cooked" vblank counter value
+ * @crtc: which counter to retrieve
+ *
+ * Fetches the "cooked" vblank count value that represents the number of
+ * vblank events since the system was booted, including lost events due to
+ * modesetting activity.
+ *
+ * This is the native KMS version of drm_vblank_count().
+ *
+ * Returns:
+ * The software vblank counter.
+ */
+u32 drm_crtc_vblank_count(struct drm_crtc *crtc)
+{
+       return drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
+}
+EXPORT_SYMBOL(drm_crtc_vblank_count);
+
 /**
  * drm_vblank_count_and_time - retrieve "cooked" vblank counter value
  * and the system timestamp corresponding to that vblank counter value.
@@ -904,6 +925,8 @@ static void send_vblank_event(struct drm_device *dev,
  *
  * Updates sequence # and timestamp on event, and sends it to userspace.
  * Caller must hold event lock.
+ *
+ * This is the legacy version of drm_crtc_send_vblank_event().
  */
 void drm_send_vblank_event(struct drm_device *dev, int crtc,
                struct drm_pending_vblank_event *e)
@@ -922,6 +945,23 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc,
 }
 EXPORT_SYMBOL(drm_send_vblank_event);
 
+/**
+ * drm_crtc_send_vblank_event - helper to send vblank event after pageflip
+ * @crtc: the source CRTC of the vblank event
+ * @e: the event to send
+ *
+ * Updates sequence # and timestamp on event, and sends it to userspace.
+ * Caller must hold event lock.
+ *
+ * This is the native KMS version of drm_send_vblank_event().
+ */
+void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
+                               struct drm_pending_vblank_event *e)
+{
+       drm_send_vblank_event(crtc->dev, drm_crtc_index(crtc), e);
+}
+EXPORT_SYMBOL(drm_crtc_send_vblank_event);
+
 /**
  * drm_vblank_enable - enable the vblank interrupt on a CRTC
  * @dev: DRM device
@@ -1594,6 +1634,8 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc)
  *
  * Drivers should call this routine in their vblank interrupt handlers to
  * update the vblank counter and send any signals that may be pending.
+ *
+ * This is the legacy version of drm_crtc_handle_vblank().
  */
 bool drm_handle_vblank(struct drm_device *dev, int crtc)
 {
@@ -1670,3 +1712,21 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
        return true;
 }
 EXPORT_SYMBOL(drm_handle_vblank);
+
+/**
+ * drm_crtc_handle_vblank - handle a vblank event
+ * @crtc: where this event occurred
+ *
+ * Drivers should call this routine in their vblank interrupt handlers to
+ * update the vblank counter and send any signals that may be pending.
+ *
+ * This is the native KMS version of drm_handle_vblank().
+ *
+ * Returns:
+ * True if the event was successfully handled, false on failure.
+ */
+bool drm_crtc_handle_vblank(struct drm_crtc *crtc)
+{
+       return drm_handle_vblank(crtc->dev, drm_crtc_index(crtc));
+}
+EXPORT_SYMBOL(drm_crtc_handle_vblank);
index f990ab4c3efbfbe1f91f15cc89eda8b5eb0fa64d..574057cd1d0986b6bc96819f67c72ba3f5280891 100644 (file)
@@ -811,6 +811,8 @@ int i915_reset(struct drm_device *dev)
        if (!i915.reset)
                return 0;
 
+       intel_reset_gt_powersave(dev);
+
        mutex_lock(&dev->struct_mutex);
 
        i915_gem_reset(dev);
@@ -880,7 +882,7 @@ int i915_reset(struct drm_device *dev)
                 * of re-init after reset.
                 */
                if (INTEL_INFO(dev)->gen > 5)
-                       intel_reset_gt_powersave(dev);
+                       intel_enable_gt_powersave(dev);
        } else {
                mutex_unlock(&dev->struct_mutex);
        }
@@ -1584,7 +1586,7 @@ static struct drm_driver driver = {
        .gem_prime_import = i915_gem_prime_import,
 
        .dumb_create = i915_gem_dumb_create,
-       .dumb_map_offset = i915_gem_dumb_map_offset,
+       .dumb_map_offset = i915_gem_mmap_gtt,
        .dumb_destroy = drm_gem_dumb_destroy,
        .ioctls = i915_ioctls,
        .fops = &i915_driver_fops,
index 63bcda5541ecad36179cf72491293694154b1a3e..70d0f0f06f1a65ccec340c0882f0481bf66903a5 100644 (file)
@@ -2501,9 +2501,8 @@ void i915_vma_move_to_active(struct i915_vma *vma,
 int i915_gem_dumb_create(struct drm_file *file_priv,
                         struct drm_device *dev,
                         struct drm_mode_create_dumb *args);
-int i915_gem_dumb_map_offset(struct drm_file *file_priv,
-                            struct drm_device *dev, uint32_t handle,
-                            uint64_t *offset);
+int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev,
+                     uint32_t handle, uint64_t *offset);
 /**
  * Returns true if seq1 is later than seq2.
  */
index 4a9faea626dbf64eec08bf257b6d8a68fe7a7513..52adcb680be3a61113630493c6c5b98509965912 100644 (file)
@@ -401,7 +401,6 @@ static int
 i915_gem_create(struct drm_file *file,
                struct drm_device *dev,
                uint64_t size,
-               bool dumb,
                uint32_t *handle_p)
 {
        struct drm_i915_gem_object *obj;
@@ -417,7 +416,6 @@ i915_gem_create(struct drm_file *file,
        if (obj == NULL)
                return -ENOMEM;
 
-       obj->base.dumb = dumb;
        ret = drm_gem_handle_create(file, &obj->base, &handle);
        /* drop reference from allocate - handle holds it now */
        drm_gem_object_unreference_unlocked(&obj->base);
@@ -437,7 +435,7 @@ i915_gem_dumb_create(struct drm_file *file,
        args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64);
        args->size = args->pitch * args->height;
        return i915_gem_create(file, dev,
-                              args->size, true, &args->handle);
+                              args->size, &args->handle);
 }
 
 /**
@@ -450,7 +448,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
        struct drm_i915_gem_create *args = data;
 
        return i915_gem_create(file, dev,
-                              args->size, false, &args->handle);
+                              args->size, &args->handle);
 }
 
 static inline int
@@ -1840,10 +1838,10 @@ static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj)
        drm_gem_free_mmap_offset(&obj->base);
 }
 
-static int
+int
 i915_gem_mmap_gtt(struct drm_file *file,
                  struct drm_device *dev,
-                 uint32_t handle, bool dumb,
+                 uint32_t handle,
                  uint64_t *offset)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1860,13 +1858,6 @@ i915_gem_mmap_gtt(struct drm_file *file,
                goto unlock;
        }
 
-       /*
-        * We don't allow dumb mmaps on objects created using another
-        * interface.
-        */
-       WARN_ONCE(dumb && !(obj->base.dumb || obj->base.import_attach),
-                 "Illegal dumb map of accelerated buffer.\n");
-
        if (obj->base.size > dev_priv->gtt.mappable_end) {
                ret = -E2BIG;
                goto out;
@@ -1891,15 +1882,6 @@ unlock:
        return ret;
 }
 
-int
-i915_gem_dumb_map_offset(struct drm_file *file,
-                        struct drm_device *dev,
-                        uint32_t handle,
-                        uint64_t *offset)
-{
-       return i915_gem_mmap_gtt(file, dev, handle, true, offset);
-}
-
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
@@ -1921,7 +1903,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
 {
        struct drm_i915_gem_mmap_gtt *args = data;
 
-       return i915_gem_mmap_gtt(file, dev, args->handle, false, &args->offset);
+       return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset);
 }
 
 static inline int
index d17ff435f2767fa31c51ed08ef5e3130aa4dddbd..d011ec82ef1ebfbb37b3c903f9d77b7e503a30f0 100644 (file)
@@ -473,7 +473,12 @@ mi_set_context(struct intel_engine_cs *ring,
               u32 hw_flags)
 {
        u32 flags = hw_flags | MI_MM_SPACE_GTT;
-       int ret;
+       const int num_rings =
+               /* Use an extended w/a on ivb+ if signalling from other rings */
+               i915_semaphore_is_enabled(ring->dev) ?
+               hweight32(INTEL_INFO(ring->dev)->ring_mask) - 1 :
+               0;
+       int len, i, ret;
 
        /* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB
         * invalidation prior to MI_SET_CONTEXT. On GEN6 we don't set the value
@@ -490,15 +495,31 @@ mi_set_context(struct intel_engine_cs *ring,
        if (!IS_HASWELL(ring->dev) && INTEL_INFO(ring->dev)->gen < 8)
                flags |= (MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN);
 
-       ret = intel_ring_begin(ring, 6);
+
+       len = 4;
+       if (INTEL_INFO(ring->dev)->gen >= 7)
+               len += 2 + (num_rings ? 4*num_rings + 2 : 0);
+
+       ret = intel_ring_begin(ring, len);
        if (ret)
                return ret;
 
        /* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */
-       if (INTEL_INFO(ring->dev)->gen >= 7)
+       if (INTEL_INFO(ring->dev)->gen >= 7) {
                intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE);
-       else
-               intel_ring_emit(ring, MI_NOOP);
+               if (num_rings) {
+                       struct intel_engine_cs *signaller;
+
+                       intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings));
+                       for_each_ring(signaller, to_i915(ring->dev), i) {
+                               if (signaller == ring)
+                                       continue;
+
+                               intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base));
+                               intel_ring_emit(ring, _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
+                       }
+               }
+       }
 
        intel_ring_emit(ring, MI_NOOP);
        intel_ring_emit(ring, MI_SET_CONTEXT);
@@ -510,10 +531,21 @@ mi_set_context(struct intel_engine_cs *ring,
         */
        intel_ring_emit(ring, MI_NOOP);
 
-       if (INTEL_INFO(ring->dev)->gen >= 7)
+       if (INTEL_INFO(ring->dev)->gen >= 7) {
+               if (num_rings) {
+                       struct intel_engine_cs *signaller;
+
+                       intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings));
+                       for_each_ring(signaller, to_i915(ring->dev), i) {
+                               if (signaller == ring)
+                                       continue;
+
+                               intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base));
+                               intel_ring_emit(ring, _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
+                       }
+               }
                intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE);
-       else
-               intel_ring_emit(ring, MI_NOOP);
+       }
 
        intel_ring_advance(ring);
 
index f06027ba3ee5512a7718deb22112f9fe6e16458b..11738316394af9b16669155dbbec74fde0f22223 100644 (file)
@@ -121,9 +121,6 @@ eb_lookup_vmas(struct eb_vmas *eb,
                        goto err;
                }
 
-               WARN_ONCE(obj->base.dumb,
-                         "GPU use of dumb buffer is illegal.\n");
-
                drm_gem_object_reference(&obj->base);
                list_add_tail(&obj->obj_exec_link, &objects);
        }
index 981834b0f9b6309b4f09911c4406a58fadbe0287..996c2931c49945d86a595c6f38104c475fc32f1b 100644 (file)
@@ -281,10 +281,14 @@ void gen6_enable_rps_interrupts(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
 
        spin_lock_irq(&dev_priv->irq_lock);
+
        WARN_ON(dev_priv->rps.pm_iir);
        WARN_ON(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events);
        dev_priv->rps.interrupts_enabled = true;
+       I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) |
+                               dev_priv->pm_rps_events);
        gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
+
        spin_unlock_irq(&dev_priv->irq_lock);
 }
 
@@ -3307,8 +3311,10 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev)
        GEN5_IRQ_INIT(GT, dev_priv->gt_irq_mask, gt_irqs);
 
        if (INTEL_INFO(dev)->gen >= 6) {
-               pm_irqs |= dev_priv->pm_rps_events;
-
+               /*
+                * RPS interrupts will get enabled/disabled on demand when RPS
+                * itself is enabled/disabled.
+                */
                if (HAS_VEBOX(dev))
                        pm_irqs |= PM_VEBOX_USER_INTERRUPT;
 
@@ -3520,7 +3526,11 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv)
        dev_priv->pm_irq_mask = 0xffffffff;
        GEN8_IRQ_INIT_NDX(GT, 0, ~gt_interrupts[0], gt_interrupts[0]);
        GEN8_IRQ_INIT_NDX(GT, 1, ~gt_interrupts[1], gt_interrupts[1]);
-       GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_irq_mask, dev_priv->pm_rps_events);
+       /*
+        * RPS interrupts will get enabled/disabled on demand when RPS itself
+        * is enabled/disabled.
+        */
+       GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_irq_mask, 0);
        GEN8_IRQ_INIT_NDX(GT, 3, ~gt_interrupts[3], gt_interrupts[3]);
 }
 
@@ -3609,7 +3619,7 @@ static void vlv_display_irq_uninstall(struct drm_i915_private *dev_priv)
 
        vlv_display_irq_reset(dev_priv);
 
-       dev_priv->irq_mask = 0;
+       dev_priv->irq_mask = ~0;
 }
 
 static void valleyview_irq_uninstall(struct drm_device *dev)
index eefdc238f70bd691d584f6d32b5d055f8d1546a5..172de3b3433b20b57d7e57f31ad63d3daa09bba3 100644 (file)
 #define   PIPE_CONTROL_STORE_DATA_INDEX                        (1<<21)
 #define   PIPE_CONTROL_CS_STALL                                (1<<20)
 #define   PIPE_CONTROL_TLB_INVALIDATE                  (1<<18)
+#define   PIPE_CONTROL_MEDIA_STATE_CLEAR               (1<<16)
 #define   PIPE_CONTROL_QW_WRITE                                (1<<14)
 #define   PIPE_CONTROL_POST_SYNC_OP_MASK                (3<<14)
 #define   PIPE_CONTROL_DEPTH_STALL                     (1<<13)
@@ -1128,6 +1129,7 @@ enum punit_power_well {
 #define GEN6_VERSYNC   (RING_SYNC_1(VEBOX_RING_BASE))
 #define GEN6_VEVSYNC   (RING_SYNC_2(VEBOX_RING_BASE))
 #define GEN6_NOSYNC 0
+#define RING_PSMI_CTL(base)    ((base)+0x50)
 #define RING_MAX_IDLE(base)    ((base)+0x54)
 #define RING_HWS_PGA(base)     ((base)+0x80)
 #define RING_HWS_PGA_GEN6(base)        ((base)+0x2080)
@@ -1458,6 +1460,7 @@ enum punit_power_well {
 #define   GEN6_BLITTER_FBC_NOTIFY                      (1<<3)
 
 #define GEN6_RC_SLEEP_PSMI_CONTROL     0x2050
+#define   GEN6_PSMI_SLEEP_MSG_DISABLE  (1 << 0)
 #define   GEN8_RC_SEMA_IDLE_MSG_DISABLE        (1 << 12)
 #define   GEN8_FF_DOP_CLOCK_GATE_DISABLE       (1<<10)
 
index 1f4b56e273c811a7c33149e927985b3f973ac4b3..964b28e3c6303e5db6ecd5458c42b90b27cdd11f 100644 (file)
@@ -6191,6 +6191,20 @@ void intel_cleanup_gt_powersave(struct drm_device *dev)
                valleyview_cleanup_gt_powersave(dev);
 }
 
+static void gen6_suspend_rps(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+       /*
+        * TODO: disable RPS interrupts on GEN9+ too once RPS support
+        * is added for it.
+        */
+       if (INTEL_INFO(dev)->gen < 9)
+               gen6_disable_rps_interrupts(dev);
+}
+
 /**
  * intel_suspend_gt_powersave - suspend PM work and helper threads
  * @dev: drm device
@@ -6206,14 +6220,7 @@ void intel_suspend_gt_powersave(struct drm_device *dev)
        if (INTEL_INFO(dev)->gen < 6)
                return;
 
-       flush_delayed_work(&dev_priv->rps.delayed_resume_work);
-
-       /*
-        * TODO: disable RPS interrupts on GEN9+ too once RPS support
-        * is added for it.
-        */
-       if (INTEL_INFO(dev)->gen < 9)
-               gen6_disable_rps_interrupts(dev);
+       gen6_suspend_rps(dev);
 
        /* Force GPU to min freq during suspend */
        gen6_rps_idle(dev_priv);
@@ -6316,8 +6323,11 @@ void intel_reset_gt_powersave(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
+       if (INTEL_INFO(dev)->gen < 6)
+               return;
+
+       gen6_suspend_rps(dev);
        dev_priv->rps.enabled = false;
-       intel_enable_gt_powersave(dev);
 }
 
 static void ibx_init_clock_gating(struct drm_device *dev)
index 9f445e9a75d1a1788669ab2969a2d769cf7d204e..c7bc93d28d84ec4356c0c5f5c4e4cd67296df709 100644 (file)
@@ -362,12 +362,15 @@ gen7_render_ring_flush(struct intel_engine_cs *ring,
                flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
                flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
                flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_MEDIA_STATE_CLEAR;
                /*
                 * TLB invalidate requires a post-sync write.
                 */
                flags |= PIPE_CONTROL_QW_WRITE;
                flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
 
+               flags |= PIPE_CONTROL_STALL_AT_SCOREBOARD;
+
                /* Workaround: we must issue a pipe_control with CS-stall bit
                 * set before a pipe_control command that has the state cache
                 * invalidate bit set. */
index aa873048308b8e6e3e431152963aed5b04c13f02..94a5bee69fe724c94542bc5181e4309e78b78300 100644 (file)
@@ -386,9 +386,7 @@ void adreno_gpu_cleanup(struct adreno_gpu *gpu)
                        msm_gem_put_iova(gpu->memptrs_bo, gpu->base.id);
                drm_gem_object_unreference(gpu->memptrs_bo);
        }
-       if (gpu->pm4)
-               release_firmware(gpu->pm4);
-       if (gpu->pfp)
-               release_firmware(gpu->pfp);
+       release_firmware(gpu->pm4);
+       release_firmware(gpu->pfp);
        msm_gpu_cleanup(&gpu->base);
 }
index fbebb0405d76d7df217c1772a26cc43e78578b29..b4e70e0e3cfa603b1ee8bbf393dd07402c96fbbb 100644 (file)
@@ -141,6 +141,15 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector)
        uint32_t hpd_ctrl;
        int i, ret;
 
+       for (i = 0; i < config->hpd_reg_cnt; i++) {
+               ret = regulator_enable(hdmi->hpd_regs[i]);
+               if (ret) {
+                       dev_err(dev->dev, "failed to enable hpd regulator: %s (%d)\n",
+                                       config->hpd_reg_names[i], ret);
+                       goto fail;
+               }
+       }
+
        ret = gpio_config(hdmi, true);
        if (ret) {
                dev_err(dev->dev, "failed to configure GPIOs: %d\n", ret);
@@ -164,15 +173,6 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector)
                }
        }
 
-       for (i = 0; i < config->hpd_reg_cnt; i++) {
-               ret = regulator_enable(hdmi->hpd_regs[i]);
-               if (ret) {
-                       dev_err(dev->dev, "failed to enable hpd regulator: %s (%d)\n",
-                                       config->hpd_reg_names[i], ret);
-                       goto fail;
-               }
-       }
-
        hdmi_set_mode(hdmi, false);
        phy->funcs->reset(phy);
        hdmi_set_mode(hdmi, true);
@@ -200,7 +200,7 @@ fail:
        return ret;
 }
 
-static int hdp_disable(struct hdmi_connector *hdmi_connector)
+static void hdp_disable(struct hdmi_connector *hdmi_connector)
 {
        struct hdmi *hdmi = hdmi_connector->hdmi;
        const struct hdmi_platform_config *config = hdmi->config;
@@ -212,28 +212,19 @@ static int hdp_disable(struct hdmi_connector *hdmi_connector)
 
        hdmi_set_mode(hdmi, false);
 
-       for (i = 0; i < config->hpd_reg_cnt; i++) {
-               ret = regulator_disable(hdmi->hpd_regs[i]);
-               if (ret) {
-                       dev_err(dev->dev, "failed to disable hpd regulator: %s (%d)\n",
-                                       config->hpd_reg_names[i], ret);
-                       goto fail;
-               }
-       }
-
        for (i = 0; i < config->hpd_clk_cnt; i++)
                clk_disable_unprepare(hdmi->hpd_clks[i]);
 
        ret = gpio_config(hdmi, false);
-       if (ret) {
-               dev_err(dev->dev, "failed to unconfigure GPIOs: %d\n", ret);
-               goto fail;
-       }
-
-       return 0;
+       if (ret)
+               dev_warn(dev->dev, "failed to unconfigure GPIOs: %d\n", ret);
 
-fail:
-       return ret;
+       for (i = 0; i < config->hpd_reg_cnt; i++) {
+               ret = regulator_disable(hdmi->hpd_regs[i]);
+               if (ret)
+                       dev_warn(dev->dev, "failed to disable hpd regulator: %s (%d)\n",
+                                       config->hpd_reg_names[i], ret);
+       }
 }
 
 static void
@@ -260,11 +251,11 @@ void hdmi_connector_irq(struct drm_connector *connector)
                        (hpd_int_status & HDMI_HPD_INT_STATUS_INT)) {
                bool detected = !!(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED);
 
-               DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl);
-
-               /* ack the irq: */
+               /* ack & disable (temporarily) HPD events: */
                hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
-                               hpd_int_ctrl | HDMI_HPD_INT_CTRL_INT_ACK);
+                       HDMI_HPD_INT_CTRL_INT_ACK);
+
+               DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl);
 
                /* detect disconnect if we are connected or visa versa: */
                hpd_int_ctrl = HDMI_HPD_INT_CTRL_INT_EN;
index a7672e100d8b5bd5f4ac4b782a3b1d0a38197a79..3449213f1e76424f7794754f3009de631b9bd00b 100644 (file)
@@ -331,17 +331,8 @@ static int mdp4_crtc_atomic_check(struct drm_crtc *crtc,
                struct drm_crtc_state *state)
 {
        struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
-       struct drm_device *dev = crtc->dev;
-
        DBG("%s: check", mdp4_crtc->name);
-
-       if (mdp4_crtc->event) {
-               dev_err(dev->dev, "already pending flip!\n");
-               return -EBUSY;
-       }
-
        // TODO anything else to check?
-
        return 0;
 }
 
@@ -357,7 +348,7 @@ static void mdp4_crtc_atomic_flush(struct drm_crtc *crtc)
        struct drm_device *dev = crtc->dev;
        unsigned long flags;
 
-       DBG("%s: flush", mdp4_crtc->name);
+       DBG("%s: event: %p", mdp4_crtc->name, crtc->state->event);
 
        WARN_ON(mdp4_crtc->event);
 
index 0e9a2e3a82d76e1e104fd1e136d8924755706586..f021f960a8a27f7d002fd7be8a01edb722e7323a 100644 (file)
@@ -303,11 +303,6 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
 
        DBG("%s: check", mdp5_crtc->name);
 
-       if (mdp5_crtc->event) {
-               dev_err(dev->dev, "already pending flip!\n");
-               return -EBUSY;
-       }
-
        /* request a free CTL, if none is already allocated for this CRTC */
        if (state->enable && !mdp5_crtc->ctl) {
                mdp5_crtc->ctl = mdp5_ctlm_request(mdp5_kms->ctlm, crtc);
@@ -364,7 +359,7 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc)
        struct drm_device *dev = crtc->dev;
        unsigned long flags;
 
-       DBG("%s: flush", mdp5_crtc->name);
+       DBG("%s: event: %p", mdp5_crtc->name, crtc->state->event);
 
        WARN_ON(mdp5_crtc->event);
 
@@ -460,10 +455,7 @@ void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf,
        /* now that we know what irq's we want: */
        mdp5_crtc->err.irqmask = intf2err(intf);
        mdp5_crtc->vblank.irqmask = intf2vblank(intf);
-
-       /* when called from modeset_init(), skip the rest until later: */
-       if (!mdp5_kms)
-               return;
+       mdp_irq_update(&mdp5_kms->base);
 
        spin_lock_irqsave(&mdp5_kms->resource_lock, flags);
        intf_sel = mdp5_read(mdp5_kms, REG_MDP5_DISP_INTF_SEL);
index a11f1b80c488567d44755ad68eadc4d15dc61375..9f01a4f21af2fa969a58c0dc5e8e74a7346e227d 100644 (file)
@@ -216,17 +216,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
                goto fail;
        }
 
-       /* NOTE: the vsync and error irq's are actually associated with
-        * the INTF/encoder.. the easiest way to deal with this (ie. what
-        * we do now) is assume a fixed relationship between crtc's and
-        * encoders.  I'm not sure if there is ever a need to more freely
-        * assign crtcs to encoders, but if there is then we need to take
-        * care of error and vblank irq's that the crtc has registered,
-        * and also update user-requested vblank_mask.
-        */
-       encoder->possible_crtcs = BIT(0);
-       mdp5_crtc_set_intf(priv->crtcs[0], 3, INTF_HDMI);
-
+       encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;;
        priv->encoders[priv->num_encoders++] = encoder;
 
        /* Construct bridge/connector for HDMI: */
index 03455b64a2458e28fdcdb724c42865f6280001de..2a731722d8407de40be9d2bbd82d6cabb8f8c737 100644 (file)
@@ -42,7 +42,10 @@ static void update_irq(struct mdp_kms *mdp_kms)
        mdp_kms->funcs->set_irqmask(mdp_kms, irqmask);
 }
 
-static void update_irq_unlocked(struct mdp_kms *mdp_kms)
+/* if an mdp_irq's irqmask has changed, such as when mdp5 crtc<->encoder
+ * link changes, this must be called to figure out the new global irqmask
+ */
+void mdp_irq_update(struct mdp_kms *mdp_kms)
 {
        unsigned long flags;
        spin_lock_irqsave(&list_lock, flags);
@@ -122,7 +125,7 @@ void mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq)
        spin_unlock_irqrestore(&list_lock, flags);
 
        if (needs_update)
-               update_irq_unlocked(mdp_kms);
+               mdp_irq_update(mdp_kms);
 }
 
 void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq)
@@ -141,5 +144,5 @@ void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq)
        spin_unlock_irqrestore(&list_lock, flags);
 
        if (needs_update)
-               update_irq_unlocked(mdp_kms);
+               mdp_irq_update(mdp_kms);
 }
index 99557b5ad4fd35bedc3fd70b20571322571e9d76..b268ce95d3946fdf2f348250ce5cafeb15635b68 100644 (file)
@@ -75,7 +75,7 @@ void mdp_update_vblank_mask(struct mdp_kms *mdp_kms, uint32_t mask, bool enable)
 void mdp_irq_wait(struct mdp_kms *mdp_kms, uint32_t irqmask);
 void mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq);
 void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq);
-
+void mdp_irq_update(struct mdp_kms *mdp_kms);
 
 /*
  * pixel format helpers:
index f0de412e13dc78bbc01e9b6dd7482c74358a14e9..191968256c5822ae0a7964db31377e5ba7b0e0ce 100644 (file)
@@ -23,10 +23,41 @@ struct msm_commit {
        struct drm_atomic_state *state;
        uint32_t fence;
        struct msm_fence_cb fence_cb;
+       uint32_t crtc_mask;
 };
 
 static void fence_cb(struct msm_fence_cb *cb);
 
+/* block until specified crtcs are no longer pending update, and
+ * atomically mark them as pending update
+ */
+static int start_atomic(struct msm_drm_private *priv, uint32_t crtc_mask)
+{
+       int ret;
+
+       spin_lock(&priv->pending_crtcs_event.lock);
+       ret = wait_event_interruptible_locked(priv->pending_crtcs_event,
+                       !(priv->pending_crtcs & crtc_mask));
+       if (ret == 0) {
+               DBG("start: %08x", crtc_mask);
+               priv->pending_crtcs |= crtc_mask;
+       }
+       spin_unlock(&priv->pending_crtcs_event.lock);
+
+       return ret;
+}
+
+/* clear specified crtcs (no longer pending update)
+ */
+static void end_atomic(struct msm_drm_private *priv, uint32_t crtc_mask)
+{
+       spin_lock(&priv->pending_crtcs_event.lock);
+       DBG("end: %08x", crtc_mask);
+       priv->pending_crtcs &= ~crtc_mask;
+       wake_up_all_locked(&priv->pending_crtcs_event);
+       spin_unlock(&priv->pending_crtcs_event.lock);
+}
+
 static struct msm_commit *new_commit(struct drm_atomic_state *state)
 {
        struct msm_commit *c = kzalloc(sizeof(*c), GFP_KERNEL);
@@ -58,12 +89,27 @@ static void complete_commit(struct msm_commit *c)
 
        drm_atomic_helper_commit_post_planes(dev, state);
 
+       /* NOTE: _wait_for_vblanks() only waits for vblank on
+        * enabled CRTCs.  So we end up faulting when disabling
+        * due to (potentially) unref'ing the outgoing fb's
+        * before the vblank when the disable has latched.
+        *
+        * But if it did wait on disabled (or newly disabled)
+        * CRTCs, that would be racy (ie. we could have missed
+        * the irq.  We need some way to poll for pipe shut
+        * down.  Or just live with occasionally hitting the
+        * timeout in the CRTC disable path (which really should
+        * not be critical path)
+        */
+
        drm_atomic_helper_wait_for_vblanks(dev, state);
 
        drm_atomic_helper_cleanup_planes(dev, state);
 
        drm_atomic_state_free(state);
 
+       end_atomic(dev->dev_private, c->crtc_mask);
+
        kfree(c);
 }
 
@@ -97,8 +143,9 @@ static void add_fb(struct msm_commit *c, struct drm_framebuffer *fb)
 int msm_atomic_commit(struct drm_device *dev,
                struct drm_atomic_state *state, bool async)
 {
-       struct msm_commit *c;
        int nplanes = dev->mode_config.num_total_plane;
+       int ncrtcs = dev->mode_config.num_crtc;
+       struct msm_commit *c;
        int i, ret;
 
        ret = drm_atomic_helper_prepare_planes(dev, state);
@@ -106,6 +153,18 @@ int msm_atomic_commit(struct drm_device *dev,
                return ret;
 
        c = new_commit(state);
+       if (!c)
+               return -ENOMEM;
+
+       /*
+        * Figure out what crtcs we have:
+        */
+       for (i = 0; i < ncrtcs; i++) {
+               struct drm_crtc *crtc = state->crtcs[i];
+               if (!crtc)
+                       continue;
+               c->crtc_mask |= (1 << drm_crtc_index(crtc));
+       }
 
        /*
         * Figure out what fence to wait for:
@@ -121,6 +180,14 @@ int msm_atomic_commit(struct drm_device *dev,
                        add_fb(c, new_state->fb);
        }
 
+       /*
+        * Wait for pending updates on any of the same crtc's and then
+        * mark our set of crtc's as busy:
+        */
+       ret = start_atomic(dev->dev_private, c->crtc_mask);
+       if (ret)
+               return ret;
+
        /*
         * This is the point of no return - everything below never fails except
         * when the hw goes bonghits. Which means we can commit the new state on
index c795217e1bfcc6051b72afd05cb09cfbbff34c2c..9a61546a0b05276cd313b0877306b02930fa2fa5 100644 (file)
@@ -193,6 +193,7 @@ static int msm_load(struct drm_device *dev, unsigned long flags)
 
        priv->wq = alloc_ordered_workqueue("msm", 0);
        init_waitqueue_head(&priv->fence_event);
+       init_waitqueue_head(&priv->pending_crtcs_event);
 
        INIT_LIST_HEAD(&priv->inactive_list);
        INIT_LIST_HEAD(&priv->fence_cbs);
index 136303818436726004b2f294c6c90d69ccdd2f05..b69ef2d5a26c0a0afa9896ed02a88a087f9cebfe 100644 (file)
@@ -96,6 +96,10 @@ struct msm_drm_private {
        /* callbacks deferred until bo is inactive: */
        struct list_head fence_cbs;
 
+       /* crtcs pending async atomic updates: */
+       uint32_t pending_crtcs;
+       wait_queue_head_t pending_crtcs_event;
+
        /* registered MMUs: */
        unsigned int num_mmus;
        struct msm_mmu *mmus[NUM_DOMAINS];
index 94d55e526b4e0732cba7fcf45a2ce725c2433637..1f3af13ccede96b0aa9ad17a49aca3dbaa358872 100644 (file)
@@ -190,8 +190,7 @@ fail_unlock:
 fail:
 
        if (ret) {
-               if (fbi)
-                       framebuffer_release(fbi);
+               framebuffer_release(fbi);
                if (fb) {
                        drm_framebuffer_unregister_private(fb);
                        drm_framebuffer_remove(fb);
index 4a6f0e49d5b5f0709d586e3dcf4e271a0c99c0f5..49dea4fb55ac5fc0c6aa4efa082326a8c892e08b 100644 (file)
@@ -535,8 +535,7 @@ void msm_gem_free_object(struct drm_gem_object *obj)
                        drm_free_large(msm_obj->pages);
 
        } else {
-               if (msm_obj->vaddr)
-                       vunmap(msm_obj->vaddr);
+               vunmap(msm_obj->vaddr);
                put_pages(obj);
        }
 
index 5d93902a91ab038cfe040197f767c0de05d7931f..f8042433752b440d72fd9306009f55e972c68385 100644 (file)
@@ -876,7 +876,6 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
        if (ret)
                return ret;
 
-       bo->gem.dumb = true;
        ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle);
        drm_gem_object_unreference_unlocked(&bo->gem);
        return ret;
@@ -892,14 +891,6 @@ nouveau_display_dumb_map_offset(struct drm_file *file_priv,
        gem = drm_gem_object_lookup(dev, file_priv, handle);
        if (gem) {
                struct nouveau_bo *bo = nouveau_gem_object(gem);
-
-               /*
-                * We don't allow dumb mmaps on objects created using another
-                * interface.
-                */
-               WARN_ONCE(!(gem->dumb || gem->import_attach),
-                         "Illegal dumb map of accelerated buffer.\n");
-
                *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node);
                drm_gem_object_unreference_unlocked(gem);
                return 0;
index 28d51a22a4bf18b5729f8f4e9cd159c830cbbfca..42c34babc2e5b728959ad5c8135266f8b3c147e2 100644 (file)
@@ -444,9 +444,6 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli,
        list_for_each_entry(nvbo, list, entry) {
                struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index];
 
-               WARN_ONCE(nvbo->gem.dumb,
-                         "GPU use of dumb buffer is illegal.\n");
-
                ret = nouveau_gem_set_domain(&nvbo->gem, b->read_domains,
                                             b->write_domains,
                                             b->valid_domains);
index 753a6def61e7ce474d73b21b9affe84ae8b1a861..3d1cfcb96b6bfd9e7dfa50e282d6e3761009f7e1 100644 (file)
@@ -28,6 +28,7 @@
 #include "nouveau_ttm.h"
 #include "nouveau_gem.h"
 
+#include "drm_legacy.h"
 static int
 nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
 {
@@ -281,7 +282,7 @@ nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma)
        struct nouveau_drm *drm = nouveau_drm(file_priv->minor->dev);
 
        if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET))
-               return -EINVAL;
+               return drm_legacy_mmap(filp, vma);
 
        return ttm_bo_mmap(filp, vma, &drm->ttm.bdev);
 }
index fe48f229043e33720c26bcdd40949d7a8fd41b00..a46f73737994aba3f603aea4dde15ff916a91109 100644 (file)
@@ -394,10 +394,9 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
        return r;
 }
 
-static int radeon_mode_mmap(struct drm_file *filp,
-                           struct drm_device *dev,
-                           uint32_t handle, bool dumb,
-                           uint64_t *offset_p)
+int radeon_mode_dumb_mmap(struct drm_file *filp,
+                         struct drm_device *dev,
+                         uint32_t handle, uint64_t *offset_p)
 {
        struct drm_gem_object *gobj;
        struct radeon_bo *robj;
@@ -406,14 +405,6 @@ static int radeon_mode_mmap(struct drm_file *filp,
        if (gobj == NULL) {
                return -ENOENT;
        }
-
-       /*
-        * We don't allow dumb mmaps on objects created using another
-        * interface.
-        */
-       WARN_ONCE(dumb && !(gobj->dumb || gobj->import_attach),
-               "Illegal dumb map of GPU buffer.\n");
-
        robj = gem_to_radeon_bo(gobj);
        if (radeon_ttm_tt_has_userptr(robj->tbo.ttm)) {
                drm_gem_object_unreference_unlocked(gobj);
@@ -424,20 +415,12 @@ static int radeon_mode_mmap(struct drm_file *filp,
        return 0;
 }
 
-int radeon_mode_dumb_mmap(struct drm_file *filp,
-                         struct drm_device *dev,
-                         uint32_t handle, uint64_t *offset_p)
-{
-       return radeon_mode_mmap(filp, dev, handle, true, offset_p);
-}
-
 int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
                          struct drm_file *filp)
 {
        struct drm_radeon_gem_mmap *args = data;
 
-       return radeon_mode_mmap(filp, dev, args->handle, false,
-                               &args->addr_ptr);
+       return radeon_mode_dumb_mmap(filp, dev, args->handle, &args->addr_ptr);
 }
 
 int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
@@ -763,7 +746,6 @@ int radeon_mode_dumb_create(struct drm_file *file_priv,
                return -ENOMEM;
 
        r = drm_gem_handle_create(file_priv, gobj, &handle);
-       gobj->dumb = true;
        /* drop reference from allocate - handle holds it now */
        drm_gem_object_unreference_unlocked(gobj);
        if (r) {
index 065d02068ec3dc14f576c139e31a0b4bfef1580b..242fd8b1b221d9c49459b67d775aaf3c57fea45f 100644 (file)
@@ -28,6 +28,8 @@
 #include "cikd.h"
 #include "cik_reg.h"
 #include "radeon_kfd.h"
+#include "radeon_ucode.h"
+#include <linux/firmware.h>
 
 #define CIK_PIPE_PER_MEC       (4)
 
@@ -49,6 +51,7 @@ static uint64_t get_vmem_size(struct kgd_dev *kgd);
 static uint64_t get_gpu_clock_counter(struct kgd_dev *kgd);
 
 static uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd);
+static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type);
 
 /*
  * Register access functions
@@ -91,6 +94,7 @@ static const struct kfd2kgd_calls kfd2kgd = {
        .hqd_load = kgd_hqd_load,
        .hqd_is_occupies = kgd_hqd_is_occupies,
        .hqd_destroy = kgd_hqd_destroy,
+       .get_fw_version = get_fw_version
 };
 
 static const struct kgd2kfd_calls *kgd2kfd;
@@ -561,3 +565,52 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
        release_queue(kgd);
        return 0;
 }
+
+static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
+{
+       struct radeon_device *rdev = (struct radeon_device *) kgd;
+       const union radeon_firmware_header *hdr;
+
+       BUG_ON(kgd == NULL || rdev->mec_fw == NULL);
+
+       switch (type) {
+       case KGD_ENGINE_PFP:
+               hdr = (const union radeon_firmware_header *) rdev->pfp_fw->data;
+               break;
+
+       case KGD_ENGINE_ME:
+               hdr = (const union radeon_firmware_header *) rdev->me_fw->data;
+               break;
+
+       case KGD_ENGINE_CE:
+               hdr = (const union radeon_firmware_header *) rdev->ce_fw->data;
+               break;
+
+       case KGD_ENGINE_MEC1:
+               hdr = (const union radeon_firmware_header *) rdev->mec_fw->data;
+               break;
+
+       case KGD_ENGINE_MEC2:
+               hdr = (const union radeon_firmware_header *)
+                                                       rdev->mec2_fw->data;
+               break;
+
+       case KGD_ENGINE_RLC:
+               hdr = (const union radeon_firmware_header *) rdev->rlc_fw->data;
+               break;
+
+       case KGD_ENGINE_SDMA:
+               hdr = (const union radeon_firmware_header *)
+                                                       rdev->sdma_fw->data;
+               break;
+
+       default:
+               return 0;
+       }
+
+       if (hdr == NULL)
+               return 0;
+
+       /* Only 12 bit in use*/
+       return hdr->common.ucode_version;
+}
index 7d68223eb4692a026fbad21b68bbe9362ee6d87a..86fc56434b2875435aaf9b7dab85fdac3e39e7e9 100644 (file)
@@ -529,9 +529,6 @@ int radeon_bo_list_validate(struct radeon_device *rdev,
                        u32 current_domain =
                                radeon_mem_type_to_domain(bo->tbo.mem.mem_type);
 
-                       WARN_ONCE(bo->gem_base.dumb,
-                                 "GPU use of dumb buffer is illegal.\n");
-
                        /* Check if this buffer will be moved and don't move it
                         * if we have moved too many buffers for this IB already.
                         *
index 3367960286a6f162455e0363a54dace2c6882883..978993fa3a360ef426b6dc48a3c287c3eda0cf48 100644 (file)
@@ -168,7 +168,7 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
                                 const struct tegra_dc_window *window)
 {
        unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
-       unsigned long value;
+       unsigned long value, flags;
        bool yuv, planar;
 
        /*
@@ -181,6 +181,8 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
        else
                bpp = planar ? 1 : 2;
 
+       spin_lock_irqsave(&dc->lock, flags);
+
        value = WINDOW_A_SELECT << index;
        tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
 
@@ -273,6 +275,7 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
 
                case TEGRA_BO_TILING_MODE_BLOCK:
                        DRM_ERROR("hardware doesn't support block linear mode\n");
+                       spin_unlock_irqrestore(&dc->lock, flags);
                        return -EINVAL;
                }
 
@@ -331,6 +334,8 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
 
        tegra_dc_window_commit(dc, index);
 
+       spin_unlock_irqrestore(&dc->lock, flags);
+
        return 0;
 }
 
@@ -338,11 +343,14 @@ static int tegra_window_plane_disable(struct drm_plane *plane)
 {
        struct tegra_dc *dc = to_tegra_dc(plane->crtc);
        struct tegra_plane *p = to_tegra_plane(plane);
+       unsigned long flags;
        u32 value;
 
        if (!plane->crtc)
                return 0;
 
+       spin_lock_irqsave(&dc->lock, flags);
+
        value = WINDOW_A_SELECT << p->index;
        tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
 
@@ -352,6 +360,8 @@ static int tegra_window_plane_disable(struct drm_plane *plane)
 
        tegra_dc_window_commit(dc, p->index);
 
+       spin_unlock_irqrestore(&dc->lock, flags);
+
        return 0;
 }
 
@@ -699,14 +709,16 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
        struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
        unsigned int h_offset = 0, v_offset = 0;
        struct tegra_bo_tiling tiling;
+       unsigned long value, flags;
        unsigned int format, swap;
-       unsigned long value;
        int err;
 
        err = tegra_fb_get_tiling(fb, &tiling);
        if (err < 0)
                return err;
 
+       spin_lock_irqsave(&dc->lock, flags);
+
        tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
 
        value = fb->offsets[0] + y * fb->pitches[0] +
@@ -752,6 +764,7 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
 
                case TEGRA_BO_TILING_MODE_BLOCK:
                        DRM_ERROR("hardware doesn't support block linear mode\n");
+                       spin_unlock_irqrestore(&dc->lock, flags);
                        return -EINVAL;
                }
 
@@ -778,6 +791,8 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
        tegra_dc_writel(dc, value << 8, DC_CMD_STATE_CONTROL);
        tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
 
+       spin_unlock_irqrestore(&dc->lock, flags);
+
        return 0;
 }
 
@@ -814,23 +829,32 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
        unsigned long flags, base;
        struct tegra_bo *bo;
 
-       if (!dc->event)
+       spin_lock_irqsave(&drm->event_lock, flags);
+
+       if (!dc->event) {
+               spin_unlock_irqrestore(&drm->event_lock, flags);
                return;
+       }
 
        bo = tegra_fb_get_plane(crtc->primary->fb, 0);
 
+       spin_lock_irqsave(&dc->lock, flags);
+
        /* check if new start address has been latched */
+       tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
        tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS);
        base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR);
        tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS);
 
+       spin_unlock_irqrestore(&dc->lock, flags);
+
        if (base == bo->paddr + crtc->primary->fb->offsets[0]) {
-               spin_lock_irqsave(&drm->event_lock, flags);
-               drm_send_vblank_event(drm, dc->pipe, dc->event);
-               drm_vblank_put(drm, dc->pipe);
+               drm_crtc_send_vblank_event(crtc, dc->event);
+               drm_crtc_vblank_put(crtc);
                dc->event = NULL;
-               spin_unlock_irqrestore(&drm->event_lock, flags);
        }
+
+       spin_unlock_irqrestore(&drm->event_lock, flags);
 }
 
 void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
@@ -843,7 +867,7 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
 
        if (dc->event && dc->event->base.file_priv == file) {
                dc->event->base.destroy(&dc->event->base);
-               drm_vblank_put(drm, dc->pipe);
+               drm_crtc_vblank_put(crtc);
                dc->event = NULL;
        }
 
@@ -853,16 +877,16 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
 static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
                              struct drm_pending_vblank_event *event, uint32_t page_flip_flags)
 {
+       unsigned int pipe = drm_crtc_index(crtc);
        struct tegra_dc *dc = to_tegra_dc(crtc);
-       struct drm_device *drm = crtc->dev;
 
        if (dc->event)
                return -EBUSY;
 
        if (event) {
-               event->pipe = dc->pipe;
+               event->pipe = pipe;
                dc->event = event;
-               drm_vblank_get(drm, dc->pipe);
+               drm_crtc_vblank_get(crtc);
        }
 
        tegra_dc_set_base(dc, 0, 0, fb);
@@ -1127,7 +1151,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
                /*
                dev_dbg(dc->dev, "%s(): vertical blank\n", __func__);
                */
-               drm_handle_vblank(dc->base.dev, dc->pipe);
+               drm_crtc_handle_vblank(&dc->base);
                tegra_dc_finish_page_flip(dc);
        }
 
index e549afeece1ff12c899afc9f21dd52ff5e3e64ff..d4f827593dfa2041a386dba733f9436cbed1d111 100644 (file)
@@ -694,24 +694,28 @@ static const struct file_operations tegra_drm_fops = {
        .llseek = noop_llseek,
 };
 
-static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, int pipe)
+static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm,
+                                            unsigned int pipe)
 {
        struct drm_crtc *crtc;
 
        list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) {
-               struct tegra_dc *dc = to_tegra_dc(crtc);
-
-               if (dc->pipe == pipe)
+               if (pipe == drm_crtc_index(crtc))
                        return crtc;
        }
 
        return NULL;
 }
 
-static u32 tegra_drm_get_vblank_counter(struct drm_device *dev, int crtc)
+static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe)
 {
+       struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe);
+
+       if (!crtc)
+               return 0;
+
        /* TODO: implement real hardware counter using syncpoints */
-       return drm_vblank_count(dev, crtc);
+       return drm_crtc_vblank_count(crtc);
 }
 
 static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe)
index da32086cbeaf28bbe0c0528eeeac4c0bb9fcb326..8777b7f757916a704ceaec670c44d34a0aee813d 100644 (file)
@@ -216,32 +216,58 @@ static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo)
        }
 }
 
-static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo,
-                             size_t size)
+static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
 {
+       struct scatterlist *s;
+       struct sg_table *sgt;
+       unsigned int i;
+
        bo->pages = drm_gem_get_pages(&bo->gem);
        if (IS_ERR(bo->pages))
                return PTR_ERR(bo->pages);
 
-       bo->num_pages = size >> PAGE_SHIFT;
-
-       bo->sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages);
-       if (IS_ERR(bo->sgt)) {
-               drm_gem_put_pages(&bo->gem, bo->pages, false, false);
-               return PTR_ERR(bo->sgt);
+       bo->num_pages = bo->gem.size >> PAGE_SHIFT;
+
+       sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages);
+       if (IS_ERR(sgt))
+               goto put_pages;
+
+       /*
+        * Fake up the SG table so that dma_map_sg() can be used to flush the
+        * pages associated with it. Note that this relies on the fact that
+        * the DMA API doesn't hook into IOMMU on Tegra, therefore mapping is
+        * only cache maintenance.
+        *
+        * TODO: Replace this by drm_clflash_sg() once it can be implemented
+        * without relying on symbols that are not exported.
+        */
+       for_each_sg(sgt->sgl, s, sgt->nents, i)
+               sg_dma_address(s) = sg_phys(s);
+
+       if (dma_map_sg(drm->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE) == 0) {
+               sgt = ERR_PTR(-ENOMEM);
+               goto release_sgt;
        }
 
+       bo->sgt = sgt;
+
        return 0;
+
+release_sgt:
+       sg_free_table(sgt);
+       kfree(sgt);
+put_pages:
+       drm_gem_put_pages(&bo->gem, bo->pages, false, false);
+       return PTR_ERR(sgt);
 }
 
-static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo,
-                         size_t size)
+static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo)
 {
        struct tegra_drm *tegra = drm->dev_private;
        int err;
 
        if (tegra->domain) {
-               err = tegra_bo_get_pages(drm, bo, size);
+               err = tegra_bo_get_pages(drm, bo);
                if (err < 0)
                        return err;
 
@@ -251,6 +277,8 @@ static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo,
                        return err;
                }
        } else {
+               size_t size = bo->gem.size;
+
                bo->vaddr = dma_alloc_writecombine(drm->dev, size, &bo->paddr,
                                                   GFP_KERNEL | __GFP_NOWARN);
                if (!bo->vaddr) {
@@ -274,7 +302,7 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, size_t size,
        if (IS_ERR(bo))
                return bo;
 
-       err = tegra_bo_alloc(drm, bo, size);
+       err = tegra_bo_alloc(drm, bo);
        if (err < 0)
                goto release;
 
index 8735543eacdb9ae0961ed841c3f8e81628100520..493478989dbd4349b23716aa3dbdd92e0d1bc37f 100644 (file)
@@ -1127,6 +1127,24 @@ static void schedule_external_copy(struct thin_c *tc, dm_block_t virt_block,
                schedule_zero(tc, virt_block, data_dest, cell, bio);
 }
 
+static void set_pool_mode(struct pool *pool, enum pool_mode new_mode);
+
+static void check_for_space(struct pool *pool)
+{
+       int r;
+       dm_block_t nr_free;
+
+       if (get_pool_mode(pool) != PM_OUT_OF_DATA_SPACE)
+               return;
+
+       r = dm_pool_get_free_block_count(pool->pmd, &nr_free);
+       if (r)
+               return;
+
+       if (nr_free)
+               set_pool_mode(pool, PM_WRITE);
+}
+
 /*
  * A non-zero return indicates read_only or fail_io mode.
  * Many callers don't care about the return value.
@@ -1141,6 +1159,8 @@ static int commit(struct pool *pool)
        r = dm_pool_commit_metadata(pool->pmd);
        if (r)
                metadata_operation_failed(pool, "dm_pool_commit_metadata", r);
+       else
+               check_for_space(pool);
 
        return r;
 }
@@ -1159,8 +1179,6 @@ static void check_low_water_mark(struct pool *pool, dm_block_t free_blocks)
        }
 }
 
-static void set_pool_mode(struct pool *pool, enum pool_mode new_mode);
-
 static int alloc_data_block(struct thin_c *tc, dm_block_t *result)
 {
        int r;
@@ -2155,7 +2173,7 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode)
                pool->process_cell = process_cell_read_only;
                pool->process_discard_cell = process_discard_cell;
                pool->process_prepared_mapping = process_prepared_mapping;
-               pool->process_prepared_discard = process_prepared_discard_passdown;
+               pool->process_prepared_discard = process_prepared_discard;
 
                if (!pool->pf.error_if_no_space && no_space_timeout)
                        queue_delayed_work(pool->wq, &pool->no_space_timeout, no_space_timeout);
@@ -3814,6 +3832,8 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
                r = -EINVAL;
                goto bad;
        }
+       atomic_set(&tc->refcount, 1);
+       init_completion(&tc->can_destroy);
        list_add_tail_rcu(&tc->list, &tc->pool->active_thins);
        spin_unlock_irqrestore(&tc->pool->lock, flags);
        /*
@@ -3826,9 +3846,6 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
 
        dm_put(pool_md);
 
-       atomic_set(&tc->refcount, 1);
-       init_completion(&tc->can_destroy);
-
        return 0;
 
 bad:
index 4c06585bf1657b076835c073f973b1dc780968d6..b98cd9d84435fe15ea1cb202850508f83b83204b 100644 (file)
@@ -899,7 +899,7 @@ static void disable_write_same(struct mapped_device *md)
 
 static void clone_endio(struct bio *bio, int error)
 {
-       int r = 0;
+       int r = error;
        struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone);
        struct dm_io *io = tio->io;
        struct mapped_device *md = tio->io->md;
index e34da13885e8c422a7fdecc153d6407c0b52999f..27fa62ce613618debb31fadb6bb50a51d9e65893 100644 (file)
@@ -1050,7 +1050,8 @@ static int miphy28lp_init(struct phy *phy)
                ret = miphy28lp_init_usb3(miphy_phy);
                break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
+               break;
        }
 
        mutex_unlock(&miphy_dev->miphy_mutex);
index c96e8183a8ffe061e017976daa40632ac5a22c56..efe724f97e02fbf9eba84c215628993fa3ea1274 100644 (file)
 /**
  * omap_control_pcie_pcs - set the PCS delay count
  * @dev: the control module device
- * @id: index of the pcie PHY (should be 1 or 2)
  * @delay: 8 bit delay value
  */
-void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay)
+void omap_control_pcie_pcs(struct device *dev, u8 delay)
 {
        u32 val;
        struct omap_control_phy *control_phy;
@@ -55,8 +54,8 @@ void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay)
 
        val = readl(control_phy->pcie_pcs);
        val &= ~(OMAP_CTRL_PCIE_PCS_MASK <<
-               (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT));
-       val |= delay << (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT);
+               OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT);
+       val |= (delay << OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT);
        writel(val, control_phy->pcie_pcs);
 }
 EXPORT_SYMBOL_GPL(omap_control_pcie_pcs);
index fb02a67c91811e5291757c8fbb330439c3d95e89..a2b08f3ccb031cbf3a484cb0afab5665c0fb3ad7 100644 (file)
@@ -244,7 +244,8 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
        else
                data->num_phys = 3;
 
-       if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy"))
+       if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy") ||
+           of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy"))
                data->disc_thresh = 3;
        else
                data->disc_thresh = 2;
index 1387b4d4afe376556661f49938bf71bb85572d94..465de2c800f228d7fa4961083e243349f5fbcd33 100644 (file)
@@ -82,7 +82,6 @@ struct ti_pipe3 {
        struct clk              *refclk;
        struct clk              *div_clk;
        struct pipe3_dpll_map   *dpll_map;
-       u8                      id;
 };
 
 static struct pipe3_dpll_map dpll_map_usb[] = {
@@ -217,8 +216,13 @@ static int ti_pipe3_init(struct phy *x)
        u32 val;
        int ret = 0;
 
+       /*
+        * Set pcie_pcs register to 0x96 for proper functioning of phy
+        * as recommended in AM572x TRM SPRUHZ6, section 18.5.2.2, table
+        * 18-1804.
+        */
        if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) {
-               omap_control_pcie_pcs(phy->control_dev, phy->id, 0xF1);
+               omap_control_pcie_pcs(phy->control_dev, 0x96);
                return 0;
        }
 
@@ -347,8 +351,6 @@ static int ti_pipe3_probe(struct platform_device *pdev)
        }
 
        if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) {
-               if (of_property_read_u8(node, "id", &phy->id) < 0)
-                       phy->id = 1;
 
                clk = devm_clk_get(phy->dev, "dpll_ref");
                if (IS_ERR(clk)) {
index 1bf891bd321aa2e0d19bb79e2e217376d31f5e09..4f361b77c749a718621c8767ec97663e43a7c87f 100644 (file)
@@ -264,7 +264,7 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
 
                if ((bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM)) &&
                    inode->i_sb->s_root != NULL &&
-                   is_root_inode(inode))
+                   !is_root_inode(inode))
                        ll_invalidate_aliases(inode);
 
                iput(inode);
index 5b9825a4538a67740a3ccf0d1ceea28d08f5d5c5..a57dc8866fc5ff938641686f7945916074723fe8 100644 (file)
@@ -669,7 +669,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
        if (!ci)
                return -ENOMEM;
 
-       platform_set_drvdata(pdev, ci);
        ci->dev = dev;
        ci->platdata = dev_get_platdata(dev);
        ci->imx28_write_fix = !!(ci->platdata->flags &
@@ -783,6 +782,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
                }
        }
 
+       platform_set_drvdata(pdev, ci);
        ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED,
                        ci->platdata->name, ci);
        if (ret)
index c1694cff1eafd287c600435a45c861a4406e6514..48731d0bab357a75232fdbd7b4063fe29af3ad4e 100644 (file)
@@ -91,6 +91,7 @@ static int host_start(struct ci_hdrc *ci)
        if (!hcd)
                return -ENOMEM;
 
+       dev_set_drvdata(ci->dev, ci);
        hcd->rsrc_start = ci->hw_bank.phys;
        hcd->rsrc_len = ci->hw_bank.size;
        hcd->regs = ci->hw_bank.abs;
index ff67ceac77c410a8f6a9ab27fc63f63afd9dc01b..d4fe8d769bd673c384707fae714944885061911d 100644 (file)
@@ -718,10 +718,11 @@ static int ep_queue(struct bdc_ep *ep, struct bdc_req *req)
        struct bdc *bdc;
        int ret = 0;
 
-       bdc = ep->bdc;
        if (!req || !ep || !ep->usb_ep.desc)
                return -EINVAL;
 
+       bdc = ep->bdc;
+
        req->usb_req.actual = 0;
        req->usb_req.status = -EINPROGRESS;
        req->epnum = ep->ep_num;
index e113fd73aeae7148b0cbcd0d424aebb16d84a694..f9a332775c4781e57faf7bd584d5d58cbf5397e3 100644 (file)
@@ -1581,6 +1581,10 @@ iso_stream_schedule (
        else
                next = (now + 2 + 7) & ~0x07;   /* full frame cache */
 
+       /* If needed, initialize last_iso_frame so that this URB will be seen */
+       if (ehci->isoc_count == 0)
+               ehci->last_iso_frame = now >> 3;
+
        /*
         * Use ehci->last_iso_frame as the base.  There can't be any
         * TDs scheduled for earlier than that.
@@ -1600,11 +1604,11 @@ iso_stream_schedule (
         */
        now2 = (now - base) & (mod - 1);
 
-       /* Is the schedule already full? */
+       /* Is the schedule about to wrap around? */
        if (unlikely(!empty && start < period)) {
-               ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n",
+               ehci_dbg(ehci, "request %p would overflow (%u-%u < %u mod %u)\n",
                                urb, stream->next_uframe, base, period, mod);
-               status = -ENOSPC;
+               status = -EFBIG;
                goto fail;
        }
 
@@ -1671,10 +1675,6 @@ iso_stream_schedule (
        urb->start_frame = start & (mod - 1);
        if (!stream->highspeed)
                urb->start_frame >>= 3;
-
-       /* Make sure scan_isoc() sees these */
-       if (ehci->isoc_count == 0)
-               ehci->last_iso_frame = now >> 3;
        return status;
 
  fail:
index 19a9af1b4d749cd577e1215a200679f9a1c8b37d..ff9af29b4e9f6b0ea4bfa1decd8050fcbede061d 100644 (file)
@@ -451,7 +451,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
 
        u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0);
        if (IS_ERR(u_phy)) {
-               err = PTR_ERR(u_phy);
+               err = -EPROBE_DEFER;
                goto cleanup_clk_en;
        }
        hcd->usb_phy = u_phy;
index dd483c13565bb7bbedc561d6e39fccee1477c279..ce636466edb7a390efb346d3b0f511b9d4eb5404 100644 (file)
@@ -567,7 +567,8 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
 {
        void __iomem *base;
        u32 control;
-       u32 fminterval;
+       u32 fminterval = 0;
+       bool no_fminterval = false;
        int cnt;
 
        if (!mmio_resource_enabled(pdev, 0))
@@ -577,6 +578,13 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
        if (base == NULL)
                return;
 
+       /*
+        * ULi M5237 OHCI controller locks the whole system when accessing
+        * the OHCI_FMINTERVAL offset.
+        */
+       if (pdev->vendor == PCI_VENDOR_ID_AL && pdev->device == 0x5237)
+               no_fminterval = true;
+
        control = readl(base + OHCI_CONTROL);
 
 /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
@@ -615,7 +623,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
        }
 
        /* software reset of the controller, preserving HcFmInterval */
-       fminterval = readl(base + OHCI_FMINTERVAL);
+       if (!no_fminterval)
+               fminterval = readl(base + OHCI_FMINTERVAL);
+
        writel(OHCI_HCR, base + OHCI_CMDSTATUS);
 
        /* reset requires max 10 us delay */
@@ -624,7 +634,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
                        break;
                udelay(1);
        }
-       writel(fminterval, base + OHCI_FMINTERVAL);
+
+       if (!no_fminterval)
+               writel(fminterval, base + OHCI_FMINTERVAL);
 
        /* Now the controller is safely in SUSPEND and nothing can wake it up */
        iounmap(base);
index 142b601f95636fdff622bca8c4fb1a9aef87093b..7f76c8a12f89db425e19c4f3a2a5200de542dbd7 100644 (file)
@@ -82,6 +82,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
                                "must be suspended extra slowly",
                                pdev->revision);
                }
+               if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK)
+                       xhci->quirks |= XHCI_BROKEN_STREAMS;
                /* Fresco Logic confirms: all revisions of this chip do not
                 * support MSI, even though some of them claim to in their PCI
                 * capabilities.
index 01fcbb5eb06e7ec3d03bcd81d90941f889c5654a..c50d8d202618521793b37a8bd57d7b343cd757fd 100644 (file)
@@ -3803,6 +3803,15 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
                return -EINVAL;
        }
 
+       if (setup == SETUP_CONTEXT_ONLY) {
+               slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx);
+               if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) ==
+                   SLOT_STATE_DEFAULT) {
+                       xhci_dbg(xhci, "Slot already in default state\n");
+                       return 0;
+               }
+       }
+
        command = xhci_alloc_command(xhci, false, false, GFP_KERNEL);
        if (!command)
                return -ENOMEM;
index 2f9735b3533891c85dc907d8b1cc95a1e50d2559..ccfdfb24b24017e8eda929fb30fb8363311ab7d2 100644 (file)
@@ -34,7 +34,7 @@ static struct usb_phy *__usb_find_phy(struct list_head *list,
                return phy;
        }
 
-       return ERR_PTR(-ENODEV);
+       return ERR_PTR(-EPROBE_DEFER);
 }
 
 static struct usb_phy *__usb_find_phy_dev(struct device *dev,
index 8d7fc48b1f307efffa1e5ec40a6e3250b852a54c..29fa1c3d0089bee738ed4f54a8b65d4f82dd0c03 100644 (file)
@@ -46,6 +46,8 @@ static struct console usbcons;
  * ------------------------------------------------------------
  */
 
+static const struct tty_operations usb_console_fake_tty_ops = {
+};
 
 /*
  * The parsing of the command line works exactly like the
@@ -137,13 +139,17 @@ static int usb_console_setup(struct console *co, char *options)
                                goto reset_open_count;
                        }
                        kref_init(&tty->kref);
-                       tty_port_tty_set(&port->port, tty);
                        tty->driver = usb_serial_tty_driver;
                        tty->index = co->index;
+                       init_ldsem(&tty->ldisc_sem);
+                       INIT_LIST_HEAD(&tty->tty_files);
+                       kref_get(&tty->driver->kref);
+                       tty->ops = &usb_console_fake_tty_ops;
                        if (tty_init_termios(tty)) {
                                retval = -ENOMEM;
-                               goto free_tty;
+                               goto put_tty;
                        }
+                       tty_port_tty_set(&port->port, tty);
                }
 
                /* only call the device specific open if this
@@ -161,7 +167,7 @@ static int usb_console_setup(struct console *co, char *options)
                        serial->type->set_termios(tty, port, &dummy);
 
                        tty_port_tty_set(&port->port, NULL);
-                       kfree(tty);
+                       tty_kref_put(tty);
                }
                set_bit(ASYNCB_INITIALIZED, &port->port.flags);
        }
@@ -177,8 +183,8 @@ static int usb_console_setup(struct console *co, char *options)
 
  fail:
        tty_port_tty_set(&port->port, NULL);
free_tty:
-       kfree(tty);
put_tty:
+       tty_kref_put(tty);
  reset_open_count:
        port->port.count = 0;
        usb_autopm_put_interface(serial->interface);
index 6c4eb3cf5efd599653641e5d96d20b05610a6ed5..f4c56fc1a9f64dd32fae247c351c1b34e0d6400e 100644 (file)
@@ -120,10 +120,12 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */
        { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */
        { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
-       { USB_DEVICE(0x10C4, 0x8875) }, /* CEL MeshConnect USB Stick */
+       { USB_DEVICE(0x10C4, 0x8856) }, /* CEL EM357 ZigBee USB Stick - LR */
+       { USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */
        { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
        { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */
        { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */
+       { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */
        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
index 1bd192290b08df0fb697fa91f2517b6756680012..ccf1df7c4b80f3f7a596fa3d1d8904eb64a78db6 100644 (file)
@@ -286,7 +286,7 @@ static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port,
 
        res = usb_submit_urb(port->read_urbs[index], mem_flags);
        if (res) {
-               if (res != -EPERM) {
+               if (res != -EPERM && res != -ENODEV) {
                        dev_err(&port->dev,
                                        "%s - usb_submit_urb failed: %d\n",
                                        __func__, res);
@@ -373,7 +373,7 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
                                                        __func__, urb->status);
                return;
        default:
-               dev_err(&port->dev, "%s - nonzero urb status: %d\n",
+               dev_dbg(&port->dev, "%s - nonzero urb status: %d\n",
                                                        __func__, urb->status);
                goto resubmit;
        }
index 077c714f1285171ee3b9e4c418e0df42f60cd42c..e07b15ed58148698d939370ac8bf73b20141669a 100644 (file)
@@ -410,6 +410,8 @@ static void usa26_instat_callback(struct urb *urb)
        }
        port = serial->port[msg->port];
        p_priv = usb_get_serial_port_data(port);
+       if (!p_priv)
+               goto resubmit;
 
        /* Update handshaking pin state information */
        old_dcd_state = p_priv->dcd_state;
@@ -420,7 +422,7 @@ static void usa26_instat_callback(struct urb *urb)
 
        if (old_dcd_state != p_priv->dcd_state)
                tty_port_tty_hangup(&port->port, true);
-
+resubmit:
        /* Resubmit urb so we continue receiving */
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err != 0)
@@ -527,6 +529,8 @@ static void usa28_instat_callback(struct urb *urb)
        }
        port = serial->port[msg->port];
        p_priv = usb_get_serial_port_data(port);
+       if (!p_priv)
+               goto resubmit;
 
        /* Update handshaking pin state information */
        old_dcd_state = p_priv->dcd_state;
@@ -537,7 +541,7 @@ static void usa28_instat_callback(struct urb *urb)
 
        if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
                tty_port_tty_hangup(&port->port, true);
-
+resubmit:
                /* Resubmit urb so we continue receiving */
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err != 0)
@@ -607,6 +611,8 @@ static void usa49_instat_callback(struct urb *urb)
        }
        port = serial->port[msg->portNumber];
        p_priv = usb_get_serial_port_data(port);
+       if (!p_priv)
+               goto resubmit;
 
        /* Update handshaking pin state information */
        old_dcd_state = p_priv->dcd_state;
@@ -617,7 +623,7 @@ static void usa49_instat_callback(struct urb *urb)
 
        if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
                tty_port_tty_hangup(&port->port, true);
-
+resubmit:
        /* Resubmit urb so we continue receiving */
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err != 0)
@@ -855,6 +861,8 @@ static void usa90_instat_callback(struct urb *urb)
 
        port = serial->port[0];
        p_priv = usb_get_serial_port_data(port);
+       if (!p_priv)
+               goto resubmit;
 
        /* Update handshaking pin state information */
        old_dcd_state = p_priv->dcd_state;
@@ -865,7 +873,7 @@ static void usa90_instat_callback(struct urb *urb)
 
        if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
                tty_port_tty_hangup(&port->port, true);
-
+resubmit:
        /* Resubmit urb so we continue receiving */
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err != 0)
@@ -926,6 +934,8 @@ static void usa67_instat_callback(struct urb *urb)
 
        port = serial->port[msg->port];
        p_priv = usb_get_serial_port_data(port);
+       if (!p_priv)
+               goto resubmit;
 
        /* Update handshaking pin state information */
        old_dcd_state = p_priv->dcd_state;
@@ -934,7 +944,7 @@ static void usa67_instat_callback(struct urb *urb)
 
        if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
                tty_port_tty_hangup(&port->port, true);
-
+resubmit:
        /* Resubmit urb so we continue receiving */
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err != 0)
index 7a4c21b4f67613f7bf64839b4cf4faf09804355e..efdcee15b52030e455ce3c6e17d401d4a5e2660d 100644 (file)
@@ -234,6 +234,8 @@ static void option_instat_callback(struct urb *urb);
 
 #define QUALCOMM_VENDOR_ID                     0x05C6
 
+#define SIERRA_VENDOR_ID                       0x1199
+
 #define CMOTECH_VENDOR_ID                      0x16d8
 #define CMOTECH_PRODUCT_6001                   0x6001
 #define CMOTECH_PRODUCT_CMU_300                        0x6002
@@ -512,7 +514,7 @@ enum option_blacklist_reason {
                OPTION_BLACKLIST_RESERVED_IF = 2
 };
 
-#define MAX_BL_NUM  8
+#define MAX_BL_NUM  11
 struct option_blacklist_info {
        /* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */
        const unsigned long sendsetup;
@@ -601,6 +603,11 @@ static const struct option_blacklist_info telit_le920_blacklist = {
        .reserved = BIT(1) | BIT(5),
 };
 
+static const struct option_blacklist_info sierra_mc73xx_blacklist = {
+       .sendsetup = BIT(0) | BIT(2),
+       .reserved = BIT(8) | BIT(10) | BIT(11),
+};
+
 static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -1098,6 +1105,8 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
+       { USB_DEVICE_INTERFACE_CLASS(SIERRA_VENDOR_ID, 0x68c0, 0xff),
+         .driver_info = (kernel_ulong_t)&sierra_mc73xx_blacklist }, /* MC73xx */
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
index cb3e14780a7e0c6182e5f9bf3ad505b61fa75684..9c63897b3a564012ea63f99b9e5e73bc48b93d36 100644 (file)
@@ -142,7 +142,6 @@ static const struct usb_device_id id_table[] = {
        {DEVICE_SWI(0x0f3d, 0x68a2)},   /* Sierra Wireless MC7700 */
        {DEVICE_SWI(0x114f, 0x68a2)},   /* Sierra Wireless MC7750 */
        {DEVICE_SWI(0x1199, 0x68a2)},   /* Sierra Wireless MC7710 */
-       {DEVICE_SWI(0x1199, 0x68c0)},   /* Sierra Wireless MC73xx */
        {DEVICE_SWI(0x1199, 0x901c)},   /* Sierra Wireless EM7700 */
        {DEVICE_SWI(0x1199, 0x901f)},   /* Sierra Wireless EM7355 */
        {DEVICE_SWI(0x1199, 0x9040)},   /* Sierra Wireless Modem */
index 8a6f371ed6e77e3ccdc99632c3cd41ebeb155213..9893d696fc973e9e4183b57b56b3ceb22570942f 100644 (file)
@@ -69,16 +69,39 @@ static int uas_use_uas_driver(struct usb_interface *intf,
                return 0;
 
        /*
-        * ASM1051 and older ASM1053 devices have the same usb-id, and UAS is
-        * broken on the ASM1051, use the number of streams to differentiate.
-        * New ASM1053-s also support 32 streams, but have a different prod-id.
+        * ASMedia has a number of usb3 to sata bridge chips, at the time of
+        * this writing the following versions exist:
+        * ASM1051 - no uas support version
+        * ASM1051 - with broken (*) uas support
+        * ASM1053 - with working uas support
+        * ASM1153 - with working uas support
+        *
+        * Devices with these chips re-use a number of device-ids over the
+        * entire line, so the device-id is useless to determine if we're
+        * dealing with an ASM1051 (which we want to avoid).
+        *
+        * The ASM1153 can be identified by config.MaxPower == 0,
+        * where as the ASM105x models have config.MaxPower == 36.
+        *
+        * Differentiating between the ASM1053 and ASM1051 is trickier, when
+        * connected over USB-3 we can look at the number of streams supported,
+        * ASM1051 supports 32 streams, where as early ASM1053 versions support
+        * 16 streams, newer ASM1053-s also support 32 streams, but have a
+        * different prod-id.
+        *
+        * (*) ASM1051 chips do work with UAS with some disks (with the
+        *     US_FL_NO_REPORT_OPCODES quirk), but are broken with other disks
         */
        if (le16_to_cpu(udev->descriptor.idVendor) == 0x174c &&
-                       le16_to_cpu(udev->descriptor.idProduct) == 0x55aa) {
-               if (udev->speed < USB_SPEED_SUPER) {
+                       (le16_to_cpu(udev->descriptor.idProduct) == 0x5106 ||
+                        le16_to_cpu(udev->descriptor.idProduct) == 0x55aa)) {
+               if (udev->actconfig->desc.bMaxPower == 0) {
+                       /* ASM1153, do nothing */
+               } else if (udev->speed < USB_SPEED_SUPER) {
                        /* No streams info, assume ASM1051 */
                        flags |= US_FL_IGNORE_UAS;
                } else if (usb_ss_max_streams(&eps[1]->ss_ep_comp) == 32) {
+                       /* Possibly an ASM1051, disable uas */
                        flags |= US_FL_IGNORE_UAS;
                }
        }
index 18a283d6de1c8bd18663b57bbf7499510c49fa2d..6df4357d9ee358b36d33961507e8677bd346d432 100644 (file)
  * and don't forget to CC: the USB development list <linux-usb@vger.kernel.org>
  */
 
+/*
+ * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI
+ * commands in UAS mode.  Observed with the 1.28 firmware; are there others?
+ */
+UNUSUAL_DEV(0x0984, 0x0301, 0x0128, 0x0128,
+               "Apricorn",
+               "",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_IGNORE_UAS),
+
 /* https://bugzilla.kernel.org/show_bug.cgi?id=79511 */
 UNUSUAL_DEV(0x0bc2, 0x2312, 0x0000, 0x9999,
                "Seagate",
@@ -68,6 +78,20 @@ UNUSUAL_DEV(0x0bc2, 0xa003, 0x0000, 0x9999,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_NO_ATA_1X),
 
+/* Reported-by: Marcin ZajÄ…czkowski <mszpak@wp.pl> */
+UNUSUAL_DEV(0x0bc2, 0xa013, 0x0000, 0x9999,
+               "Seagate",
+               "Backup Plus",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_NO_ATA_1X),
+
+/* Reported-by: Hans de Goede <hdegoede@redhat.com> */
+UNUSUAL_DEV(0x0bc2, 0xa0a4, 0x0000, 0x9999,
+               "Seagate",
+               "Backup Plus Desk",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_NO_ATA_1X),
+
 /* https://bbs.archlinux.org/viewtopic.php?id=183190 */
 UNUSUAL_DEV(0x0bc2, 0xab20, 0x0000, 0x9999,
                "Seagate",
@@ -82,6 +106,13 @@ UNUSUAL_DEV(0x0bc2, 0xab21, 0x0000, 0x9999,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_NO_ATA_1X),
 
+/* Reported-by: G. Richard Bellamy <rbellamy@pteradigm.com> */
+UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999,
+               "Seagate",
+               "BUP Fast HDD",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_NO_ATA_1X),
+
 /* Reported-by: Claudio Bizzarri <claudio.bizzarri@gmail.com> */
 UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999,
                "JMicron",
@@ -89,14 +120,6 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_NO_REPORT_OPCODES),
 
-/* Most ASM1051 based devices have issues with uas, blacklist them all */
-/* Reported-by: Hans de Goede <hdegoede@redhat.com> */
-UNUSUAL_DEV(0x174c, 0x5106, 0x0000, 0x9999,
-               "ASMedia",
-               "ASM1051",
-               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
-               US_FL_IGNORE_UAS),
-
 /* Reported-by: Hans de Goede <hdegoede@redhat.com> */
 UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999,
                "VIA",
@@ -104,6 +127,13 @@ UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_NO_ATA_1X),
 
+/* Reported-by: Takeo Nakayama <javhera@gmx.com> */
+UNUSUAL_DEV(0x357d, 0x7788, 0x0000, 0x9999,
+               "JMicron",
+               "JMS566",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_NO_REPORT_OPCODES),
+
 /* Reported-by: Hans de Goede <hdegoede@redhat.com> */
 UNUSUAL_DEV(0x4971, 0x1012, 0x0000, 0x9999,
                "Hitachi",
index 8ba35c622e2202a889a3a06706bdc93e035fb841..e1b2e8b98af7cde2c7276e915cd90ea4794b317e 100644 (file)
@@ -901,11 +901,15 @@ extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
 extern int drm_wait_vblank(struct drm_device *dev, void *data,
                           struct drm_file *filp);
 extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
+extern u32 drm_crtc_vblank_count(struct drm_crtc *crtc);
 extern u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc,
                                     struct timeval *vblanktime);
 extern void drm_send_vblank_event(struct drm_device *dev, int crtc,
                                     struct drm_pending_vblank_event *e);
+extern void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
+                                      struct drm_pending_vblank_event *e);
 extern bool drm_handle_vblank(struct drm_device *dev, int crtc);
+extern bool drm_crtc_handle_vblank(struct drm_crtc *crtc);
 extern int drm_vblank_get(struct drm_device *dev, int crtc);
 extern void drm_vblank_put(struct drm_device *dev, int crtc);
 extern int drm_crtc_vblank_get(struct drm_crtc *crtc);
index 780511a459c01e3012efbfe2912ee27dc5996971..1e6ae1458f7ab98ef42cd66ef9834cef8f276718 100644 (file)
@@ -119,13 +119,6 @@ struct drm_gem_object {
         * simply leave it as NULL.
         */
        struct dma_buf_attachment *import_attach;
-
-       /**
-        * dumb - created as dumb buffer
-        * Whether the gem object was created using the dumb buffer interface
-        * as such it may not be used for GPU rendering.
-        */
-       bool dumb;
 };
 
 void drm_gem_object_release(struct drm_gem_object *obj);
index 0c04917c2f1297f0a013e32fe6e3cf380b967d3a..af84234e1f6e2f3741ccb42f1a89e325f17749e8 100644 (file)
@@ -47,6 +47,7 @@ struct sk_buff;
 
 struct audit_krule {
        int                     vers_ops;
+       u32                     pflags;
        u32                     flags;
        u32                     listnr;
        u32                     action;
@@ -64,6 +65,9 @@ struct audit_krule {
        u64                     prio;
 };
 
+/* Flag to indicate legacy AUDIT_LOGINUID unset usage */
+#define AUDIT_LOGINUID_LEGACY          0x1
+
 struct audit_field {
        u32                             type;
        union {
index e9e6cfbfbb589d0393060e2fed0422ec402dd612..eb7d4a135a9ea71364105c0bade762b5f06b67da 100644 (file)
@@ -66,7 +66,7 @@ enum omap_control_usb_mode {
 #define        OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF      0x0
 
 #define        OMAP_CTRL_PCIE_PCS_MASK                 0xff
-#define        OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT    0x8
+#define        OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT    16
 
 #define OMAP_CTRL_USB2_PHY_PD          BIT(28)
 
@@ -79,7 +79,7 @@ enum omap_control_usb_mode {
 void omap_control_phy_power(struct device *dev, int on);
 void omap_control_usb_set_mode(struct device *dev,
                               enum omap_control_usb_mode mode);
-void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay);
+void omap_control_pcie_pcs(struct device *dev, u8 delay);
 #else
 
 static inline void omap_control_phy_power(struct device *dev, int on)
@@ -91,7 +91,7 @@ static inline void omap_control_usb_set_mode(struct device *dev,
 {
 }
 
-static inline void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay)
+static inline void omap_control_pcie_pcs(struct device *dev, u8 delay)
 {
 }
 #endif
index f8f203e8018c5995b546457342d18f262a2565dc..231b7dcb154bae60f16b68d5abc337853d818c77 100644 (file)
@@ -429,7 +429,7 @@ static void kauditd_send_skb(struct sk_buff *skb)
  * This function doesn't consume an skb as might be expected since it has to
  * copy it anyways.
  */
-static void kauditd_send_multicast_skb(struct sk_buff *skb)
+static void kauditd_send_multicast_skb(struct sk_buff *skb, gfp_t gfp_mask)
 {
        struct sk_buff          *copy;
        struct audit_net        *aunet = net_generic(&init_net, audit_net_id);
@@ -448,11 +448,11 @@ static void kauditd_send_multicast_skb(struct sk_buff *skb)
         * no reason for new multicast clients to continue with this
         * non-compliance.
         */
-       copy = skb_copy(skb, GFP_KERNEL);
+       copy = skb_copy(skb, gfp_mask);
        if (!copy)
                return;
 
-       nlmsg_multicast(sock, copy, 0, AUDIT_NLGRP_READLOG, GFP_KERNEL);
+       nlmsg_multicast(sock, copy, 0, AUDIT_NLGRP_READLOG, gfp_mask);
 }
 
 /*
@@ -1940,7 +1940,7 @@ void audit_log_end(struct audit_buffer *ab)
                struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
 
                nlh->nlmsg_len = ab->skb->len;
-               kauditd_send_multicast_skb(ab->skb);
+               kauditd_send_multicast_skb(ab->skb, ab->gfp_mask);
 
                /*
                 * The original kaudit unicast socket sends up messages with
index 3598e13f2a655dbbcfb0df6b6c1bd1afcebd2b8f..4f68a326d92e65883425c3f16f01e78ae55bc255 100644 (file)
@@ -442,19 +442,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
                if ((f->type == AUDIT_LOGINUID) && (f->val == AUDIT_UID_UNSET)) {
                        f->type = AUDIT_LOGINUID_SET;
                        f->val = 0;
-               }
-
-               if ((f->type == AUDIT_PID) || (f->type == AUDIT_PPID)) {
-                       struct pid *pid;
-                       rcu_read_lock();
-                       pid = find_vpid(f->val);
-                       if (!pid) {
-                               rcu_read_unlock();
-                               err = -ESRCH;
-                               goto exit_free;
-                       }
-                       f->val = pid_nr(pid);
-                       rcu_read_unlock();
+                       entry->rule.pflags |= AUDIT_LOGINUID_LEGACY;
                }
 
                err = audit_field_valid(entry, f);
@@ -630,6 +618,13 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
                        data->buflen += data->values[i] =
                                audit_pack_string(&bufp, krule->filterkey);
                        break;
+               case AUDIT_LOGINUID_SET:
+                       if (krule->pflags & AUDIT_LOGINUID_LEGACY && !f->val) {
+                               data->fields[i] = AUDIT_LOGINUID;
+                               data->values[i] = AUDIT_UID_UNSET;
+                               break;
+                       }
+                       /* fallthrough if set */
                default:
                        data->values[i] = f->val;
                }
@@ -646,6 +641,7 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
        int i;
 
        if (a->flags != b->flags ||
+           a->pflags != b->pflags ||
            a->listnr != b->listnr ||
            a->action != b->action ||
            a->field_count != b->field_count)
@@ -764,6 +760,7 @@ struct audit_entry *audit_dupe_rule(struct audit_krule *old)
        new = &entry->rule;
        new->vers_ops = old->vers_ops;
        new->flags = old->flags;
+       new->pflags = old->pflags;
        new->listnr = old->listnr;
        new->action = old->action;
        for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
index c75522a83678d14d542f0e1b25a13180762803ca..37c69ab561dad881c9fd76eaac1ed5b48e5bab52 100644 (file)
@@ -1877,12 +1877,18 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
        }
 
 out_alloc:
-       /* unable to find the name from a previous getname(). Allocate a new
-        * anonymous entry.
-        */
-       n = audit_alloc_name(context, AUDIT_TYPE_NORMAL);
+       /* unable to find an entry with both a matching name and type */
+       n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
        if (!n)
                return;
+       if (name)
+               /* since name is not NULL we know there is already a matching
+                * name record, see audit_getname(), so there must be a type
+                * mismatch; reuse the string path since the original name
+                * record will keep the string valid until we free it in
+                * audit_free_names() */
+               n->name = name;
+
 out:
        if (parent) {
                n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
index 649e7d440bd763fa647d47722abb6471cb75ab79..ca920d1fd314a17c7250d7916bd37403afa96b79 100644 (file)
@@ -2378,12 +2378,12 @@ void unmap_mapping_range(struct address_space *mapping,
                details.last_index = ULONG_MAX;
 
 
-       i_mmap_lock_read(mapping);
+       i_mmap_lock_write(mapping);
        if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap)))
                unmap_mapping_range_tree(&mapping->i_mmap, &details);
        if (unlikely(!list_empty(&mapping->i_mmap_nonlinear)))
                unmap_mapping_range_list(&mapping->i_mmap_nonlinear, &details);
-       i_mmap_unlock_read(mapping);
+       i_mmap_unlock_write(mapping);
 }
 EXPORT_SYMBOL(unmap_mapping_range);
 
index 8276a743e22ef2e1c234dcc291106fa627858b14..0cfc9c8c4b4e811ac6f0b6bbeb0d24377c95232d 100644 (file)
@@ -1922,10 +1922,18 @@ int azx_mixer_create(struct azx *chip)
 EXPORT_SYMBOL_GPL(azx_mixer_create);
 
 
+static bool is_input_stream(struct azx *chip, unsigned char index)
+{
+       return (index >= chip->capture_index_offset &&
+               index < chip->capture_index_offset + chip->capture_streams);
+}
+
 /* initialize SD streams */
 int azx_init_stream(struct azx *chip)
 {
        int i;
+       int in_stream_tag = 0;
+       int out_stream_tag = 0;
 
        /* initialize each stream (aka device)
         * assign the starting bdl address to each stream (device)
@@ -1938,9 +1946,21 @@ int azx_init_stream(struct azx *chip)
                azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80);
                /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */
                azx_dev->sd_int_sta_mask = 1 << i;
-               /* stream tag: must be non-zero and unique */
                azx_dev->index = i;
-               azx_dev->stream_tag = i + 1;
+
+               /* stream tag must be unique throughout
+                * the stream direction group,
+                * valid values 1...15
+                * use separate stream tag if the flag
+                * AZX_DCAPS_SEPARATE_STREAM_TAG is used
+                */
+               if (chip->driver_caps & AZX_DCAPS_SEPARATE_STREAM_TAG)
+                       azx_dev->stream_tag =
+                               is_input_stream(chip, i) ?
+                               ++in_stream_tag :
+                               ++out_stream_tag;
+               else
+                       azx_dev->stream_tag = i + 1;
        }
 
        return 0;
index 2bf0b568e3de40bfcaebd77914371f6800c125da..d426a0bd6a5f7e86adf482c83ad86e3203a8a3ad 100644 (file)
@@ -299,6 +299,9 @@ enum {
         AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL |\
         AZX_DCAPS_SNOOP_TYPE(SCH))
 
+#define AZX_DCAPS_INTEL_SKYLAKE \
+       (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_SEPARATE_STREAM_TAG)
+
 /* quirks for ATI SB / AMD Hudson */
 #define AZX_DCAPS_PRESET_ATI_SB \
        (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB |\
@@ -2027,7 +2030,7 @@ static const struct pci_device_id azx_ids[] = {
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
        /* Sunrise Point-LP */
        { PCI_DEVICE(0x8086, 0x9d70),
-         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
        /* Haswell */
        { PCI_DEVICE(0x8086, 0x0a0c),
          .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
index aa484fdf43389d476742aea16ee95a03318028ae..166e3e84b963875eec1d854e9ef8e2d434df0edb 100644 (file)
@@ -171,6 +171,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 #define AZX_DCAPS_I915_POWERWELL (1 << 27)     /* HSW i915 powerwell support */
 #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28)  /* CORBRP clears itself after reset */
 #define AZX_DCAPS_NO_MSI64      (1 << 29)      /* Stick to 32-bit MSIs */
+#define AZX_DCAPS_SEPARATE_STREAM_TAG  (1 << 30) /* capture and playback use separate stream tag */
 
 enum {
        AZX_SNOOP_TYPE_NONE ,
index f5283438ee05e165b50b693c2d864f248d82a90d..1cc6e2e199827093093e6c48eab72c6531136a13 100644 (file)
@@ -671,6 +671,7 @@ static void update_memslots(struct kvm_memslots *slots,
 
        WARN_ON(mslots[i].id != id);
        if (!new->npages) {
+               WARN_ON(!mslots[i].npages);
                new->base_gfn = 0;
                if (mslots[i].npages)
                        slots->used_slots--;
@@ -687,12 +688,25 @@ static void update_memslots(struct kvm_memslots *slots,
                slots->id_to_index[mslots[i].id] = i;
                i++;
        }
-       while (i > 0 &&
-              new->base_gfn > mslots[i - 1].base_gfn) {
-               mslots[i] = mslots[i - 1];
-               slots->id_to_index[mslots[i].id] = i;
-               i--;
-       }
+
+       /*
+        * The ">=" is needed when creating a slot with base_gfn == 0,
+        * so that it moves before all those with base_gfn == npages == 0.
+        *
+        * On the other hand, if new->npages is zero, the above loop has
+        * already left i pointing to the beginning of the empty part of
+        * mslots, and the ">=" would move the hole backwards in this
+        * case---which is wrong.  So skip the loop when deleting a slot.
+        */
+       if (new->npages) {
+               while (i > 0 &&
+                      new->base_gfn >= mslots[i - 1].base_gfn) {
+                       mslots[i] = mslots[i - 1];
+                       slots->id_to_index[mslots[i].id] = i;
+                       i--;
+               }
+       } else
+               WARN_ON_ONCE(i != slots->used_slots);
 
        mslots[i] = *new;
        slots->id_to_index[mslots[i].id] = i;