USB-serial fixes for v3.18-rc5
Here are a few fixes for reported problems including a possible null-deref on probe with keyspan, a misbehaving modem, and a couple of issues with the USB console. Some new device IDs are also added. Signed-off-by: Johan Hovold <johan@kernel.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJUtivAAAoJEEEN5E/e4bSV6eEQALGHzwqFXAZvWQRuAIA6yEYy 7KFDtU2bPBLorm6vDFPc9J3Q8Nh8cSwoMneJrrdKZiXoEoRrK5R9Mj34ENTrNNCX HwbjHx0QS3OysG3L09uciMxZbtHBZvr72s08QEJrLM9jgzKWdOBJORNeuUihw6vr YnxbAvpM4XPmb2PZ3GcvtP9tY12Kbh6Gb8kViaxn9jXFrLyjdsZq9TBqFlmFpwzs rk1wSIyo3dnQ41umKcalwqqni03pmdh+JMhXsWUXtFYExknvxQIpvzivUPHjX9pp OA1y8AX5l2MAUH2DVPSmPPwjDu4AMT3MLkdzonPNPSmvRPPoygEINaAVY6yxhImj nnXUCQKz4YEPBw9YGh4lsYLJlTthV+oit2QS65aJf/itBJYo0lGZUKFX9luHBQZD dQ7xYwT9fAmpUZVhNSZDVf6uDCv6fOn3Q5/R5ivTRdLjlTys6xS7FTDVgqzAB0tL ztM2P8ujexUt4CYMT28lqy8JbLsTqCRjoyKuuDeiIa1/QaanxIRXeUfj6TUYR9Rz 9LT+a0V05fWakzzCgyKFD6ul8l1KLzu2pV2Xk35JB+0oyRFr495wcGqS+la85djS KXG664RNOtXrsmbjKQFTsJ3MdShcbbyS9gOubLWlp74lNsMVKl5MLACUAyOWuB6o HYYC0VCVce1rJKI08s3P =umHr -----END PGP SIGNATURE----- Merge tag 'usb-serial-3.19-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial into usb-linus Johan writes: USB-serial fixes for v3.18-rc5 Here are a few fixes for reported problems including a possible null-deref on probe with keyspan, a misbehaving modem, and a couple of issues with the USB console. Some new device IDs are also added. Signed-off-by: Johan Hovold <johan@kernel.org>
This commit is contained in:
Коммит
919ba4ee1b
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 19
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION = -rc2
|
||||
NAME = Diseased Newt
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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();
|
||||
|
||||
/*
|
||||
|
|
|
@ -33,11 +33,18 @@
|
|||
|
||||
#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; \
|
||||
})
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -395,6 +395,7 @@
|
|||
#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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
if (ret)
|
||||
dev_warn(dev->dev, "failed to unconfigure GPIOs: %d\n", 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);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
return 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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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: */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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->num_pages = bo->gem.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);
|
||||
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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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 ,
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче