mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
Merge branch 'linux-linaro-lsk-v4.9' into amlogic-4.9-dev
This commit is contained in:
@@ -42,24 +42,26 @@ file acts as a registry of software workarounds in the Linux Kernel and
|
||||
will be updated when new workarounds are committed and backported to
|
||||
stable kernels.
|
||||
|
||||
| Implementor | Component | Erratum ID | Kconfig |
|
||||
+----------------+-----------------+-----------------+-------------------------+
|
||||
| ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 |
|
||||
| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 |
|
||||
| ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 |
|
||||
| ARM | Cortex-A53 | #819472 | ARM64_ERRATUM_819472 |
|
||||
| ARM | Cortex-A53 | #845719 | ARM64_ERRATUM_845719 |
|
||||
| ARM | Cortex-A53 | #843419 | ARM64_ERRATUM_843419 |
|
||||
| ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 |
|
||||
| ARM | Cortex-A57 | #852523 | N/A |
|
||||
| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 |
|
||||
| ARM | Cortex-A72 | #853709 | N/A |
|
||||
| ARM | MMU-500 | #841119,#826419 | N/A |
|
||||
| | | | |
|
||||
| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
|
||||
| Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 |
|
||||
| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 |
|
||||
| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 |
|
||||
| Cavium | ThunderX SMMUv2 | #27704 | N/A |
|
||||
| | | | |
|
||||
| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
|
||||
| Implementor | Component | Erratum ID | Kconfig |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 |
|
||||
| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 |
|
||||
| ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 |
|
||||
| ARM | Cortex-A53 | #819472 | ARM64_ERRATUM_819472 |
|
||||
| ARM | Cortex-A53 | #845719 | ARM64_ERRATUM_845719 |
|
||||
| ARM | Cortex-A53 | #843419 | ARM64_ERRATUM_843419 |
|
||||
| ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 |
|
||||
| ARM | Cortex-A57 | #852523 | N/A |
|
||||
| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 |
|
||||
| ARM | Cortex-A72 | #853709 | N/A |
|
||||
| ARM | MMU-500 | #841119,#826419 | N/A |
|
||||
| | | | |
|
||||
| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
|
||||
| Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 |
|
||||
| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 |
|
||||
| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 |
|
||||
| Cavium | ThunderX SMMUv2 | #27704 | N/A |
|
||||
| | | | |
|
||||
| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
|
||||
| | | | |
|
||||
| Qualcomm Tech. | QDF2400 ITS | E0065 | QCOM_QDF2400_ERRATUM_0065 |
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 13
|
||||
SUBLEVEL = 17
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -148,6 +148,8 @@
|
||||
uart1: serial@f8020000 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_uart1_default>;
|
||||
atmel,use-dma-rx;
|
||||
atmel,use-dma-tx;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -110,6 +110,8 @@
|
||||
};
|
||||
|
||||
usart3: serial@fc00c000 {
|
||||
atmel,use-dma-rx;
|
||||
atmel,use-dma-tx;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -150,18 +150,12 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
|
||||
* and iterate over the range.
|
||||
*/
|
||||
|
||||
bool need_flush = !vcpu_has_cache_enabled(vcpu) || ipa_uncached;
|
||||
|
||||
VM_BUG_ON(size & ~PAGE_MASK);
|
||||
|
||||
if (!need_flush && !icache_is_pipt())
|
||||
goto vipt_cache;
|
||||
|
||||
while (size) {
|
||||
void *va = kmap_atomic_pfn(pfn);
|
||||
|
||||
if (need_flush)
|
||||
kvm_flush_dcache_to_poc(va, PAGE_SIZE);
|
||||
kvm_flush_dcache_to_poc(va, PAGE_SIZE);
|
||||
|
||||
if (icache_is_pipt())
|
||||
__cpuc_coherent_user_range((unsigned long)va,
|
||||
@@ -173,7 +167,6 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
|
||||
kunmap_atomic(va);
|
||||
}
|
||||
|
||||
vipt_cache:
|
||||
if (!icache_is_pipt() && !icache_is_vivt_asid_tagged()) {
|
||||
/* any kind of VIPT cache */
|
||||
__flush_icache_all();
|
||||
|
||||
@@ -474,6 +474,16 @@ config CAVIUM_ERRATUM_27456
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config QCOM_QDF2400_ERRATUM_0065
|
||||
bool "QDF2400 E0065: Incorrect GITS_TYPER.ITT_Entry_size"
|
||||
default y
|
||||
help
|
||||
On Qualcomm Datacenter Technologies QDF2400 SoC, ITS hardware reports
|
||||
ITE size incorrectly. The GITS_TYPER.ITT_Entry_size field should have
|
||||
been indicated as 16Bytes (0xf), not 8Bytes (0x7).
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
endmenu
|
||||
|
||||
|
||||
|
||||
@@ -241,8 +241,7 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
|
||||
{
|
||||
void *va = page_address(pfn_to_page(pfn));
|
||||
|
||||
if (!vcpu_has_cache_enabled(vcpu) || ipa_uncached)
|
||||
kvm_flush_dcache_to_poc(va, size);
|
||||
kvm_flush_dcache_to_poc(va, size);
|
||||
|
||||
if (!icache_is_aliasing()) { /* PIPT */
|
||||
flush_icache_range((unsigned long)va,
|
||||
|
||||
@@ -654,15 +654,15 @@ static u64 __raw_read_system_reg(u32 sys_id)
|
||||
case SYS_ID_ISAR2_EL1: return read_cpuid(ID_ISAR2_EL1);
|
||||
case SYS_ID_ISAR3_EL1: return read_cpuid(ID_ISAR3_EL1);
|
||||
case SYS_ID_ISAR4_EL1: return read_cpuid(ID_ISAR4_EL1);
|
||||
case SYS_ID_ISAR5_EL1: return read_cpuid(ID_ISAR4_EL1);
|
||||
case SYS_ID_ISAR5_EL1: return read_cpuid(ID_ISAR5_EL1);
|
||||
case SYS_MVFR0_EL1: return read_cpuid(MVFR0_EL1);
|
||||
case SYS_MVFR1_EL1: return read_cpuid(MVFR1_EL1);
|
||||
case SYS_MVFR2_EL1: return read_cpuid(MVFR2_EL1);
|
||||
|
||||
case SYS_ID_AA64PFR0_EL1: return read_cpuid(ID_AA64PFR0_EL1);
|
||||
case SYS_ID_AA64PFR1_EL1: return read_cpuid(ID_AA64PFR0_EL1);
|
||||
case SYS_ID_AA64PFR1_EL1: return read_cpuid(ID_AA64PFR1_EL1);
|
||||
case SYS_ID_AA64DFR0_EL1: return read_cpuid(ID_AA64DFR0_EL1);
|
||||
case SYS_ID_AA64DFR1_EL1: return read_cpuid(ID_AA64DFR0_EL1);
|
||||
case SYS_ID_AA64DFR1_EL1: return read_cpuid(ID_AA64DFR1_EL1);
|
||||
case SYS_ID_AA64MMFR0_EL1: return read_cpuid(ID_AA64MMFR0_EL1);
|
||||
case SYS_ID_AA64MMFR1_EL1: return read_cpuid(ID_AA64MMFR1_EL1);
|
||||
case SYS_ID_AA64MMFR2_EL1: return read_cpuid(ID_AA64MMFR2_EL1);
|
||||
|
||||
@@ -17,14 +17,62 @@
|
||||
|
||||
#include <asm/kvm_hyp.h>
|
||||
|
||||
static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm)
|
||||
{
|
||||
u64 val;
|
||||
|
||||
/*
|
||||
* With VHE enabled, we have HCR_EL2.{E2H,TGE} = {1,1}, and
|
||||
* most TLB operations target EL2/EL0. In order to affect the
|
||||
* guest TLBs (EL1/EL0), we need to change one of these two
|
||||
* bits. Changing E2H is impossible (goodbye TTBR1_EL2), so
|
||||
* let's flip TGE before executing the TLB operation.
|
||||
*/
|
||||
write_sysreg(kvm->arch.vttbr, vttbr_el2);
|
||||
val = read_sysreg(hcr_el2);
|
||||
val &= ~HCR_TGE;
|
||||
write_sysreg(val, hcr_el2);
|
||||
isb();
|
||||
}
|
||||
|
||||
static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm)
|
||||
{
|
||||
write_sysreg(kvm->arch.vttbr, vttbr_el2);
|
||||
isb();
|
||||
}
|
||||
|
||||
static hyp_alternate_select(__tlb_switch_to_guest,
|
||||
__tlb_switch_to_guest_nvhe,
|
||||
__tlb_switch_to_guest_vhe,
|
||||
ARM64_HAS_VIRT_HOST_EXTN);
|
||||
|
||||
static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm)
|
||||
{
|
||||
/*
|
||||
* We're done with the TLB operation, let's restore the host's
|
||||
* view of HCR_EL2.
|
||||
*/
|
||||
write_sysreg(0, vttbr_el2);
|
||||
write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
|
||||
}
|
||||
|
||||
static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm)
|
||||
{
|
||||
write_sysreg(0, vttbr_el2);
|
||||
}
|
||||
|
||||
static hyp_alternate_select(__tlb_switch_to_host,
|
||||
__tlb_switch_to_host_nvhe,
|
||||
__tlb_switch_to_host_vhe,
|
||||
ARM64_HAS_VIRT_HOST_EXTN);
|
||||
|
||||
void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
|
||||
{
|
||||
dsb(ishst);
|
||||
|
||||
/* Switch to requested VMID */
|
||||
kvm = kern_hyp_va(kvm);
|
||||
write_sysreg(kvm->arch.vttbr, vttbr_el2);
|
||||
isb();
|
||||
__tlb_switch_to_guest()(kvm);
|
||||
|
||||
/*
|
||||
* We could do so much better if we had the VA as well.
|
||||
@@ -45,7 +93,7 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
|
||||
dsb(ish);
|
||||
isb();
|
||||
|
||||
write_sysreg(0, vttbr_el2);
|
||||
__tlb_switch_to_host()(kvm);
|
||||
}
|
||||
|
||||
void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
|
||||
@@ -54,14 +102,13 @@ void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
|
||||
|
||||
/* Switch to requested VMID */
|
||||
kvm = kern_hyp_va(kvm);
|
||||
write_sysreg(kvm->arch.vttbr, vttbr_el2);
|
||||
isb();
|
||||
__tlb_switch_to_guest()(kvm);
|
||||
|
||||
asm volatile("tlbi vmalls12e1is" : : );
|
||||
dsb(ish);
|
||||
isb();
|
||||
|
||||
write_sysreg(0, vttbr_el2);
|
||||
__tlb_switch_to_host()(kvm);
|
||||
}
|
||||
|
||||
void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
|
||||
@@ -69,14 +116,13 @@ void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
|
||||
struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm);
|
||||
|
||||
/* Switch to requested VMID */
|
||||
write_sysreg(kvm->arch.vttbr, vttbr_el2);
|
||||
isb();
|
||||
__tlb_switch_to_guest()(kvm);
|
||||
|
||||
asm volatile("tlbi vmalle1" : : );
|
||||
dsb(nsh);
|
||||
isb();
|
||||
|
||||
write_sysreg(0, vttbr_el2);
|
||||
__tlb_switch_to_host()(kvm);
|
||||
}
|
||||
|
||||
void __hyp_text __kvm_flush_vm_context(void)
|
||||
|
||||
@@ -352,6 +352,13 @@ static int __swiotlb_dma_supported(struct device *hwdev, u64 mask)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t addr)
|
||||
{
|
||||
if (swiotlb)
|
||||
return swiotlb_dma_mapping_error(hwdev, addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dma_map_ops swiotlb_dma_ops = {
|
||||
.alloc = __dma_alloc,
|
||||
.free = __dma_free,
|
||||
@@ -366,7 +373,7 @@ static struct dma_map_ops swiotlb_dma_ops = {
|
||||
.sync_sg_for_cpu = __swiotlb_sync_sg_for_cpu,
|
||||
.sync_sg_for_device = __swiotlb_sync_sg_for_device,
|
||||
.dma_supported = __swiotlb_dma_supported,
|
||||
.mapping_error = swiotlb_dma_mapping_error,
|
||||
.mapping_error = __swiotlb_dma_mapping_error,
|
||||
};
|
||||
|
||||
static int __init atomic_pool_init(void)
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
.active_low = 1, \
|
||||
}
|
||||
|
||||
#define BCM47XX_GPIO_KEY_H(_gpio, _code) \
|
||||
{ \
|
||||
.code = _code, \
|
||||
.gpio = _gpio, \
|
||||
}
|
||||
|
||||
/* Asus */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
@@ -79,8 +85,8 @@ bcm47xx_buttons_asus_wl500gpv2[] __initconst = {
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wl500w[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(7, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY_H(6, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY_H(7, KEY_WPS_BUTTON),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
|
||||
@@ -208,18 +208,18 @@ EXC( STORE t2, UNIT(6)(dst), s_exc_p10u)
|
||||
ADD src, src, 16*NBYTES
|
||||
EXC( STORE t3, UNIT(7)(dst), s_exc_p9u)
|
||||
ADD dst, dst, 16*NBYTES
|
||||
EXC( LOAD t0, UNIT(-8)(src), l_exc_copy)
|
||||
EXC( LOAD t1, UNIT(-7)(src), l_exc_copy)
|
||||
EXC( LOAD t2, UNIT(-6)(src), l_exc_copy)
|
||||
EXC( LOAD t3, UNIT(-5)(src), l_exc_copy)
|
||||
EXC( LOAD t0, UNIT(-8)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t1, UNIT(-7)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t2, UNIT(-6)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t3, UNIT(-5)(src), l_exc_copy_rewind16)
|
||||
EXC( STORE t0, UNIT(-8)(dst), s_exc_p8u)
|
||||
EXC( STORE t1, UNIT(-7)(dst), s_exc_p7u)
|
||||
EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u)
|
||||
EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u)
|
||||
EXC( LOAD t0, UNIT(-4)(src), l_exc_copy)
|
||||
EXC( LOAD t1, UNIT(-3)(src), l_exc_copy)
|
||||
EXC( LOAD t2, UNIT(-2)(src), l_exc_copy)
|
||||
EXC( LOAD t3, UNIT(-1)(src), l_exc_copy)
|
||||
EXC( LOAD t0, UNIT(-4)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t1, UNIT(-3)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t2, UNIT(-2)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t3, UNIT(-1)(src), l_exc_copy_rewind16)
|
||||
EXC( STORE t0, UNIT(-4)(dst), s_exc_p4u)
|
||||
EXC( STORE t1, UNIT(-3)(dst), s_exc_p3u)
|
||||
EXC( STORE t2, UNIT(-2)(dst), s_exc_p2u)
|
||||
@@ -383,6 +383,10 @@ done:
|
||||
nop
|
||||
END(memcpy)
|
||||
|
||||
l_exc_copy_rewind16:
|
||||
/* Rewind src and dst by 16*NBYTES for l_exc_copy */
|
||||
SUB src, src, 16*NBYTES
|
||||
SUB dst, dst, 16*NBYTES
|
||||
l_exc_copy:
|
||||
/*
|
||||
* Copy bytes from src until faulting load address (or until a
|
||||
|
||||
@@ -67,8 +67,8 @@ CONFIG_NETFILTER_NETLINK_QUEUE=m
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_DCCP=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -133,7 +133,7 @@ CONFIG_LIBFC=m
|
||||
CONFIG_SCSI_QLOGIC_1280=y
|
||||
CONFIG_SCSI_PMCRAID=m
|
||||
CONFIG_SCSI_BFA_FC=m
|
||||
CONFIG_SCSI_DH=m
|
||||
CONFIG_SCSI_DH=y
|
||||
CONFIG_SCSI_DH_RDAC=m
|
||||
CONFIG_SCSI_DH_HP_SW=m
|
||||
CONFIG_SCSI_DH_EMC=m
|
||||
@@ -205,7 +205,6 @@ CONFIG_MLX4_EN=m
|
||||
# CONFIG_MLX4_DEBUG is not set
|
||||
CONFIG_TEHUTI=m
|
||||
CONFIG_BNX2X=m
|
||||
CONFIG_QLGE=m
|
||||
CONFIG_SFC=m
|
||||
CONFIG_BE2NET=m
|
||||
CONFIG_LIBERTAS_THINFIRM=m
|
||||
|
||||
@@ -39,7 +39,7 @@ CONFIG_HIBERNATION=y
|
||||
CONFIG_PM_STD_PARTITION="/dev/hda3"
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_DEBUG=y
|
||||
CONFIG_CPU_FREQ_STAT=m
|
||||
CONFIG_CPU_FREQ_STAT=y
|
||||
CONFIG_CPU_FREQ_STAT_DETAILS=y
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
|
||||
|
||||
@@ -59,8 +59,8 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_DCCP=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -60,8 +60,8 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_DCCP=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -59,8 +59,8 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_DCCP=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -61,8 +61,8 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_DCCP=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -110,7 +110,7 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -90,7 +90,7 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -186,7 +186,9 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
" daddu %0, %4 \n"
|
||||
" dsll32 $1, %0, 0 \n"
|
||||
" daddu %0, $1 \n"
|
||||
" sltu $1, %0, $1 \n"
|
||||
" dsra32 %0, %0, 0 \n"
|
||||
" addu %0, $1 \n"
|
||||
#endif
|
||||
" .set pop"
|
||||
: "=r" (sum)
|
||||
|
||||
@@ -12,14 +12,16 @@
|
||||
|
||||
/*
|
||||
* IP27 uses the R10000's uncached attribute feature. Attribute 3 selects
|
||||
* uncached memory addressing.
|
||||
* uncached memory addressing. Hide the definitions on 32-bit compilation
|
||||
* of the compat-vdso code.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define HSPEC_BASE 0x9000000000000000
|
||||
#define IO_BASE 0x9200000000000000
|
||||
#define MSPEC_BASE 0x9400000000000000
|
||||
#define UNCAC_BASE 0x9600000000000000
|
||||
#define CAC_BASE 0xa800000000000000
|
||||
#endif
|
||||
|
||||
#define TO_MSPEC(x) (MSPEC_BASE | ((x) & TO_PHYS_MASK))
|
||||
#define TO_HSPEC(x) (HSPEC_BASE | ((x) & TO_PHYS_MASK))
|
||||
|
||||
@@ -195,11 +195,9 @@ struct mips_frame_info {
|
||||
#define J_TARGET(pc,target) \
|
||||
(((unsigned long)(pc) & 0xf0000000) | ((target) << 2))
|
||||
|
||||
static inline int is_ra_save_ins(union mips_instruction *ip)
|
||||
static inline int is_ra_save_ins(union mips_instruction *ip, int *poff)
|
||||
{
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
union mips_instruction mmi;
|
||||
|
||||
/*
|
||||
* swsp ra,offset
|
||||
* swm16 reglist,offset(sp)
|
||||
@@ -209,29 +207,71 @@ static inline int is_ra_save_ins(union mips_instruction *ip)
|
||||
*
|
||||
* microMIPS is way more fun...
|
||||
*/
|
||||
if (mm_insn_16bit(ip->halfword[0])) {
|
||||
mmi.word = (ip->halfword[0] << 16);
|
||||
return (mmi.mm16_r5_format.opcode == mm_swsp16_op &&
|
||||
mmi.mm16_r5_format.rt == 31) ||
|
||||
(mmi.mm16_m_format.opcode == mm_pool16c_op &&
|
||||
mmi.mm16_m_format.func == mm_swm16_op);
|
||||
if (mm_insn_16bit(ip->halfword[1])) {
|
||||
switch (ip->mm16_r5_format.opcode) {
|
||||
case mm_swsp16_op:
|
||||
if (ip->mm16_r5_format.rt != 31)
|
||||
return 0;
|
||||
|
||||
*poff = ip->mm16_r5_format.simmediate;
|
||||
*poff = (*poff << 2) / sizeof(ulong);
|
||||
return 1;
|
||||
|
||||
case mm_pool16c_op:
|
||||
switch (ip->mm16_m_format.func) {
|
||||
case mm_swm16_op:
|
||||
*poff = ip->mm16_m_format.imm;
|
||||
*poff += 1 + ip->mm16_m_format.rlist;
|
||||
*poff = (*poff << 2) / sizeof(ulong);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mmi.halfword[0] = ip->halfword[1];
|
||||
mmi.halfword[1] = ip->halfword[0];
|
||||
return (mmi.mm_m_format.opcode == mm_pool32b_op &&
|
||||
mmi.mm_m_format.rd > 9 &&
|
||||
mmi.mm_m_format.base == 29 &&
|
||||
mmi.mm_m_format.func == mm_swm32_func) ||
|
||||
(mmi.i_format.opcode == mm_sw32_op &&
|
||||
mmi.i_format.rs == 29 &&
|
||||
mmi.i_format.rt == 31);
|
||||
|
||||
switch (ip->i_format.opcode) {
|
||||
case mm_sw32_op:
|
||||
if (ip->i_format.rs != 29)
|
||||
return 0;
|
||||
if (ip->i_format.rt != 31)
|
||||
return 0;
|
||||
|
||||
*poff = ip->i_format.simmediate / sizeof(ulong);
|
||||
return 1;
|
||||
|
||||
case mm_pool32b_op:
|
||||
switch (ip->mm_m_format.func) {
|
||||
case mm_swm32_func:
|
||||
if (ip->mm_m_format.rd < 0x10)
|
||||
return 0;
|
||||
if (ip->mm_m_format.base != 29)
|
||||
return 0;
|
||||
|
||||
*poff = ip->mm_m_format.simmediate;
|
||||
*poff += (ip->mm_m_format.rd & 0xf) * sizeof(u32);
|
||||
*poff /= sizeof(ulong);
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
/* sw / sd $ra, offset($sp) */
|
||||
return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
|
||||
ip->i_format.rs == 29 &&
|
||||
ip->i_format.rt == 31;
|
||||
if ((ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
|
||||
ip->i_format.rs == 29 && ip->i_format.rt == 31) {
|
||||
*poff = ip->i_format.simmediate / sizeof(ulong);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -246,13 +286,16 @@ static inline int is_jump_ins(union mips_instruction *ip)
|
||||
*
|
||||
* microMIPS is kind of more fun...
|
||||
*/
|
||||
union mips_instruction mmi;
|
||||
if (mm_insn_16bit(ip->halfword[1])) {
|
||||
if ((ip->mm16_r5_format.opcode == mm_pool16c_op &&
|
||||
(ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mmi.word = (ip->halfword[0] << 16);
|
||||
|
||||
if ((mmi.mm16_r5_format.opcode == mm_pool16c_op &&
|
||||
(mmi.mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) ||
|
||||
ip->j_format.opcode == mm_jal32_op)
|
||||
if (ip->j_format.opcode == mm_j32_op)
|
||||
return 1;
|
||||
if (ip->j_format.opcode == mm_jal32_op)
|
||||
return 1;
|
||||
if (ip->r_format.opcode != mm_pool32a_op ||
|
||||
ip->r_format.func != mm_pool32axf_op)
|
||||
@@ -280,15 +323,13 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
|
||||
*
|
||||
* microMIPS is not more fun...
|
||||
*/
|
||||
if (mm_insn_16bit(ip->halfword[0])) {
|
||||
union mips_instruction mmi;
|
||||
|
||||
mmi.word = (ip->halfword[0] << 16);
|
||||
return (mmi.mm16_r3_format.opcode == mm_pool16d_op &&
|
||||
mmi.mm16_r3_format.simmediate && mm_addiusp_func) ||
|
||||
(mmi.mm16_r5_format.opcode == mm_pool16d_op &&
|
||||
mmi.mm16_r5_format.rt == 29);
|
||||
if (mm_insn_16bit(ip->halfword[1])) {
|
||||
return (ip->mm16_r3_format.opcode == mm_pool16d_op &&
|
||||
ip->mm16_r3_format.simmediate && mm_addiusp_func) ||
|
||||
(ip->mm16_r5_format.opcode == mm_pool16d_op &&
|
||||
ip->mm16_r5_format.rt == 29);
|
||||
}
|
||||
|
||||
return ip->mm_i_format.opcode == mm_addiu32_op &&
|
||||
ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29;
|
||||
#else
|
||||
@@ -303,30 +344,36 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
|
||||
|
||||
static int get_frame_info(struct mips_frame_info *info)
|
||||
{
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
union mips_instruction *ip = (void *) (((char *) info->func) - 1);
|
||||
#else
|
||||
union mips_instruction *ip = info->func;
|
||||
#endif
|
||||
unsigned max_insns = info->func_size / sizeof(union mips_instruction);
|
||||
unsigned i;
|
||||
bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS);
|
||||
union mips_instruction insn, *ip, *ip_end;
|
||||
const unsigned int max_insns = 128;
|
||||
unsigned int i;
|
||||
|
||||
info->pc_offset = -1;
|
||||
info->frame_size = 0;
|
||||
|
||||
ip = (void *)msk_isa16_mode((ulong)info->func);
|
||||
if (!ip)
|
||||
goto err;
|
||||
|
||||
if (max_insns == 0)
|
||||
max_insns = 128U; /* unknown function size */
|
||||
max_insns = min(128U, max_insns);
|
||||
ip_end = (void *)ip + info->func_size;
|
||||
|
||||
for (i = 0; i < max_insns; i++, ip++) {
|
||||
for (i = 0; i < max_insns && ip < ip_end; i++, ip++) {
|
||||
if (is_mmips && mm_insn_16bit(ip->halfword[0])) {
|
||||
insn.halfword[0] = 0;
|
||||
insn.halfword[1] = ip->halfword[0];
|
||||
} else if (is_mmips) {
|
||||
insn.halfword[0] = ip->halfword[1];
|
||||
insn.halfword[1] = ip->halfword[0];
|
||||
} else {
|
||||
insn.word = ip->word;
|
||||
}
|
||||
|
||||
if (is_jump_ins(ip))
|
||||
if (is_jump_ins(&insn))
|
||||
break;
|
||||
|
||||
if (!info->frame_size) {
|
||||
if (is_sp_move_ins(ip))
|
||||
if (is_sp_move_ins(&insn))
|
||||
{
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
if (mm_insn_16bit(ip->halfword[0]))
|
||||
@@ -349,11 +396,9 @@ static int get_frame_info(struct mips_frame_info *info)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (info->pc_offset == -1 && is_ra_save_ins(ip)) {
|
||||
info->pc_offset =
|
||||
ip->i_format.simmediate / sizeof(long);
|
||||
if (info->pc_offset == -1 &&
|
||||
is_ra_save_ins(&insn, &info->pc_offset))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (info->frame_size && info->pc_offset >= 0) /* nested */
|
||||
return 0;
|
||||
|
||||
@@ -545,7 +545,7 @@ void __init ltq_soc_init(void)
|
||||
clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI);
|
||||
clkdev_add_pmu("1a800000.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI);
|
||||
clkdev_add_pmu("1a800000.pcie", "ctl", 1, 1, PMU1_PCIE2_CTL);
|
||||
clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH | PMU_PPE_DP);
|
||||
clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP);
|
||||
clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
|
||||
clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
|
||||
} else if (of_machine_is_compatible("lantiq,ar10")) {
|
||||
@@ -553,7 +553,7 @@ void __init ltq_soc_init(void)
|
||||
ltq_ar10_fpi_hz(), ltq_ar10_pp32_hz());
|
||||
clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
|
||||
clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1);
|
||||
clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH |
|
||||
clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH |
|
||||
PMU_PPE_DP | PMU_PPE_TC);
|
||||
clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
|
||||
clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY);
|
||||
@@ -575,11 +575,11 @@ void __init ltq_soc_init(void)
|
||||
clkdev_add_pmu(NULL, "ahb", 1, 0, PMU_AHBM | PMU_AHBS);
|
||||
|
||||
clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
|
||||
clkdev_add_pmu("1e108000.eth", NULL, 1, 0,
|
||||
clkdev_add_pmu("1e108000.eth", NULL, 0, 0,
|
||||
PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
|
||||
PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
|
||||
PMU_PPE_QSB | PMU_PPE_TOP);
|
||||
clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY);
|
||||
clkdev_add_pmu("1f203000.rcu", "gphy", 0, 0, PMU_GPHY);
|
||||
clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
|
||||
clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
|
||||
clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
|
||||
|
||||
@@ -31,26 +31,40 @@ static inline void indy_sc_wipe(unsigned long first, unsigned long last)
|
||||
unsigned long tmp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".set\tpush\t\t\t# indy_sc_wipe\n\t"
|
||||
".set\tnoreorder\n\t"
|
||||
".set\tmips3\n\t"
|
||||
".set\tnoat\n\t"
|
||||
"mfc0\t%2, $12\n\t"
|
||||
"li\t$1, 0x80\t\t\t# Go 64 bit\n\t"
|
||||
"mtc0\t$1, $12\n\t"
|
||||
|
||||
"dli\t$1, 0x9000000080000000\n\t"
|
||||
"or\t%0, $1\t\t\t# first line to flush\n\t"
|
||||
"or\t%1, $1\t\t\t# last line to flush\n\t"
|
||||
".set\tat\n\t"
|
||||
|
||||
"1:\tsw\t$0, 0(%0)\n\t"
|
||||
"bne\t%0, %1, 1b\n\t"
|
||||
" daddu\t%0, 32\n\t"
|
||||
|
||||
"mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t"
|
||||
"nop; nop; nop; nop;\n\t"
|
||||
".set\tpop"
|
||||
" .set push # indy_sc_wipe \n"
|
||||
" .set noreorder \n"
|
||||
" .set mips3 \n"
|
||||
" .set noat \n"
|
||||
" mfc0 %2, $12 \n"
|
||||
" li $1, 0x80 # Go 64 bit \n"
|
||||
" mtc0 $1, $12 \n"
|
||||
" \n"
|
||||
" # \n"
|
||||
" # Open code a dli $1, 0x9000000080000000 \n"
|
||||
" # \n"
|
||||
" # Required because binutils 2.25 will happily accept \n"
|
||||
" # 64 bit instructions in .set mips3 mode but puke on \n"
|
||||
" # 64 bit constants when generating 32 bit ELF \n"
|
||||
" # \n"
|
||||
" lui $1,0x9000 \n"
|
||||
" dsll $1,$1,0x10 \n"
|
||||
" ori $1,$1,0x8000 \n"
|
||||
" dsll $1,$1,0x10 \n"
|
||||
" \n"
|
||||
" or %0, $1 # first line to flush \n"
|
||||
" or %1, $1 # last line to flush \n"
|
||||
" .set at \n"
|
||||
" \n"
|
||||
"1: sw $0, 0(%0) \n"
|
||||
" bne %0, %1, 1b \n"
|
||||
" daddu %0, 32 \n"
|
||||
" \n"
|
||||
" mtc0 %2, $12 # Back to 32 bit \n"
|
||||
" nop # pipeline hazard \n"
|
||||
" nop \n"
|
||||
" nop \n"
|
||||
" nop \n"
|
||||
" .set pop \n"
|
||||
: "=r" (first), "=r" (last), "=&r" (tmp)
|
||||
: "0" (first), "1" (last));
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
# Joshua Henderson, <joshua.henderson@microchip.com>
|
||||
# Copyright (C) 2015 Microchip Technology, Inc. All rights reserved.
|
||||
#
|
||||
obj-y := init.o time.o config.o
|
||||
obj-y := config.o early_clk.o init.o time.o
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_console.o \
|
||||
early_pin.o \
|
||||
early_clk.o
|
||||
early_pin.o
|
||||
|
||||
@@ -30,8 +30,10 @@ const char *get_system_type(void)
|
||||
return soc_info.sys_type;
|
||||
}
|
||||
|
||||
static __init void prom_init_cmdline(int argc, char **argv)
|
||||
static __init void prom_init_cmdline(void)
|
||||
{
|
||||
int argc;
|
||||
char **argv;
|
||||
int i;
|
||||
|
||||
pr_debug("prom: fw_arg0=%08x fw_arg1=%08x fw_arg2=%08x fw_arg3=%08x\n",
|
||||
@@ -60,14 +62,11 @@ static __init void prom_init_cmdline(int argc, char **argv)
|
||||
|
||||
void __init prom_init(void)
|
||||
{
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
prom_soc_init(&soc_info);
|
||||
|
||||
pr_info("SoC Type: %s\n", get_system_type());
|
||||
|
||||
prom_init_cmdline(argc, argv);
|
||||
prom_init_cmdline();
|
||||
}
|
||||
|
||||
void __init prom_free_prom_memory(void)
|
||||
|
||||
@@ -40,16 +40,6 @@ static struct rt2880_pmx_group rt2880_pinmux_data_act[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void rt288x_wdt_reset(void)
|
||||
{
|
||||
u32 t;
|
||||
|
||||
/* enable WDT reset output on pin SRAM_CS_N */
|
||||
t = rt_sysc_r32(SYSC_REG_CLKCFG);
|
||||
t |= CLKCFG_SRAM_CS_N_WDT;
|
||||
rt_sysc_w32(t, SYSC_REG_CLKCFG);
|
||||
}
|
||||
|
||||
void __init ralink_clk_init(void)
|
||||
{
|
||||
unsigned long cpu_rate, wmac_rate = 40000000;
|
||||
|
||||
@@ -89,17 +89,6 @@ static struct rt2880_pmx_group rt5350_pinmux_data[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void rt305x_wdt_reset(void)
|
||||
{
|
||||
u32 t;
|
||||
|
||||
/* enable WDT reset output on pin SRAM_CS_N */
|
||||
t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
|
||||
t |= RT305X_SYSCFG_SRAM_CS0_MODE_WDT <<
|
||||
RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT;
|
||||
rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG);
|
||||
}
|
||||
|
||||
static unsigned long rt5350_get_mem_size(void)
|
||||
{
|
||||
void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE);
|
||||
|
||||
@@ -63,16 +63,6 @@ static struct rt2880_pmx_group rt3883_pinmux_data[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void rt3883_wdt_reset(void)
|
||||
{
|
||||
u32 t;
|
||||
|
||||
/* enable WDT reset output on GPIO 2 */
|
||||
t = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1);
|
||||
t |= RT3883_SYSCFG1_GPIO2_AS_WDT_OUT;
|
||||
rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1);
|
||||
}
|
||||
|
||||
void __init ralink_clk_init(void)
|
||||
{
|
||||
unsigned long cpu_rate, sys_rate;
|
||||
|
||||
@@ -71,11 +71,6 @@ static int rt_timer_request(struct rt_timer *rt)
|
||||
return err;
|
||||
}
|
||||
|
||||
static void rt_timer_free(struct rt_timer *rt)
|
||||
{
|
||||
free_irq(rt->irq, rt);
|
||||
}
|
||||
|
||||
static int rt_timer_config(struct rt_timer *rt, unsigned long divisor)
|
||||
{
|
||||
if (rt->timer_freq < divisor)
|
||||
@@ -101,15 +96,6 @@ static int rt_timer_enable(struct rt_timer *rt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rt_timer_disable(struct rt_timer *rt)
|
||||
{
|
||||
u32 t;
|
||||
|
||||
t = rt_timer_r32(rt, TIMER_REG_TMR0CTL);
|
||||
t &= ~TMR0CTL_ENABLE;
|
||||
rt_timer_w32(rt, TIMER_REG_TMR0CTL, t);
|
||||
}
|
||||
|
||||
static int rt_timer_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
@@ -25,7 +25,7 @@ endif
|
||||
# Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys
|
||||
#
|
||||
ifdef CONFIG_SGI_IP28
|
||||
ifeq ($(call cc-option-yn,-mr10k-cache-barrier=store), n)
|
||||
ifeq ($(call cc-option-yn,-march=r10000 -mr10k-cache-barrier=store), n)
|
||||
$(error gcc doesn't support needed option -mr10k-cache-barrier=store)
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -52,7 +52,7 @@ static int crc32c_vpmsum_cra_init(struct crypto_tfm *tfm)
|
||||
{
|
||||
u32 *key = crypto_tfm_ctx(tfm);
|
||||
|
||||
*key = 0;
|
||||
*key = ~0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -136,6 +136,7 @@ enum {
|
||||
MMU_FTR_NO_SLBIE_B | MMU_FTR_16M_PAGE | MMU_FTR_TLBIEL |
|
||||
MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_CI_LARGE_PAGE |
|
||||
MMU_FTR_1T_SEGMENT | MMU_FTR_TLBIE_CROP_VA |
|
||||
MMU_FTR_KERNEL_RO |
|
||||
#ifdef CONFIG_PPC_RADIX_MMU
|
||||
MMU_FTR_TYPE_RADIX |
|
||||
#endif
|
||||
|
||||
@@ -19,16 +19,18 @@ extern void destroy_context(struct mm_struct *mm);
|
||||
struct mm_iommu_table_group_mem_t;
|
||||
|
||||
extern int isolate_lru_page(struct page *page); /* from internal.h */
|
||||
extern bool mm_iommu_preregistered(void);
|
||||
extern long mm_iommu_get(unsigned long ua, unsigned long entries,
|
||||
extern bool mm_iommu_preregistered(struct mm_struct *mm);
|
||||
extern long mm_iommu_get(struct mm_struct *mm,
|
||||
unsigned long ua, unsigned long entries,
|
||||
struct mm_iommu_table_group_mem_t **pmem);
|
||||
extern long mm_iommu_put(struct mm_iommu_table_group_mem_t *mem);
|
||||
extern void mm_iommu_init(mm_context_t *ctx);
|
||||
extern void mm_iommu_cleanup(mm_context_t *ctx);
|
||||
extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup(unsigned long ua,
|
||||
unsigned long size);
|
||||
extern struct mm_iommu_table_group_mem_t *mm_iommu_find(unsigned long ua,
|
||||
unsigned long entries);
|
||||
extern long mm_iommu_put(struct mm_struct *mm,
|
||||
struct mm_iommu_table_group_mem_t *mem);
|
||||
extern void mm_iommu_init(struct mm_struct *mm);
|
||||
extern void mm_iommu_cleanup(struct mm_struct *mm);
|
||||
extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup(struct mm_struct *mm,
|
||||
unsigned long ua, unsigned long size);
|
||||
extern struct mm_iommu_table_group_mem_t *mm_iommu_find(struct mm_struct *mm,
|
||||
unsigned long ua, unsigned long entries);
|
||||
extern long mm_iommu_ua_to_hpa(struct mm_iommu_table_group_mem_t *mem,
|
||||
unsigned long ua, unsigned long *hpa);
|
||||
extern long mm_iommu_mapped_inc(struct mm_iommu_table_group_mem_t *mem);
|
||||
|
||||
@@ -100,6 +100,8 @@ _GLOBAL(__setup_cpu_power9)
|
||||
mfspr r3,SPRN_LPCR
|
||||
LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
|
||||
or r3, r3, r4
|
||||
LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR)
|
||||
andc r3, r3, r4
|
||||
bl __init_LPCR
|
||||
bl __init_HFSCR
|
||||
bl __init_tlb_power9
|
||||
@@ -120,6 +122,8 @@ _GLOBAL(__restore_cpu_power9)
|
||||
mfspr r3,SPRN_LPCR
|
||||
LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
|
||||
or r3, r3, r4
|
||||
LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR)
|
||||
andc r3, r3, r4
|
||||
bl __init_LPCR
|
||||
bl __init_HFSCR
|
||||
bl __init_tlb_power9
|
||||
|
||||
@@ -228,8 +228,10 @@ int hw_breakpoint_handler(struct die_args *args)
|
||||
rcu_read_lock();
|
||||
|
||||
bp = __this_cpu_read(bp_per_reg);
|
||||
if (!bp)
|
||||
if (!bp) {
|
||||
rc = NOTIFY_DONE;
|
||||
goto out;
|
||||
}
|
||||
info = counter_arch_bp(bp);
|
||||
|
||||
/*
|
||||
|
||||
@@ -915,7 +915,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
init_mm.context.pte_frag = NULL;
|
||||
#endif
|
||||
#ifdef CONFIG_SPAPR_TCE_IOMMU
|
||||
mm_iommu_init(&init_mm.context);
|
||||
mm_iommu_init(&init_mm);
|
||||
#endif
|
||||
irqstack_early_init();
|
||||
exc_lvl_early_init();
|
||||
|
||||
@@ -1807,8 +1807,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
goto instr_done;
|
||||
|
||||
case LARX:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
if (op.ea & (size - 1))
|
||||
break; /* can't handle misaligned */
|
||||
err = -EFAULT;
|
||||
@@ -1832,8 +1830,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
goto ldst_done;
|
||||
|
||||
case STCX:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
if (op.ea & (size - 1))
|
||||
break; /* can't handle misaligned */
|
||||
err = -EFAULT;
|
||||
@@ -1859,8 +1855,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
goto ldst_done;
|
||||
|
||||
case LOAD:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
err = read_mem(®s->gpr[op.reg], op.ea, size, regs);
|
||||
if (!err) {
|
||||
if (op.type & SIGNEXT)
|
||||
@@ -1872,8 +1866,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
|
||||
#ifdef CONFIG_PPC_FPU
|
||||
case LOAD_FP:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
if (size == 4)
|
||||
err = do_fp_load(op.reg, do_lfs, op.ea, size, regs);
|
||||
else
|
||||
@@ -1882,15 +1874,11 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
#endif
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
case LOAD_VMX:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
err = do_vec_load(op.reg, do_lvx, op.ea & ~0xfUL, regs);
|
||||
goto ldst_done;
|
||||
#endif
|
||||
#ifdef CONFIG_VSX
|
||||
case LOAD_VSX:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
err = do_vsx_load(op.reg, do_lxvd2x, op.ea, regs);
|
||||
goto ldst_done;
|
||||
#endif
|
||||
@@ -1913,8 +1901,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
goto instr_done;
|
||||
|
||||
case STORE:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
if ((op.type & UPDATE) && size == sizeof(long) &&
|
||||
op.reg == 1 && op.update_reg == 1 &&
|
||||
!(regs->msr & MSR_PR) &&
|
||||
@@ -1927,8 +1913,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
|
||||
#ifdef CONFIG_PPC_FPU
|
||||
case STORE_FP:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
if (size == 4)
|
||||
err = do_fp_store(op.reg, do_stfs, op.ea, size, regs);
|
||||
else
|
||||
@@ -1937,15 +1921,11 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
#endif
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
case STORE_VMX:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
err = do_vec_store(op.reg, do_stvx, op.ea & ~0xfUL, regs);
|
||||
goto ldst_done;
|
||||
#endif
|
||||
#ifdef CONFIG_VSX
|
||||
case STORE_VSX:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
err = do_vsx_store(op.reg, do_stxvd2x, op.ea, regs);
|
||||
goto ldst_done;
|
||||
#endif
|
||||
|
||||
@@ -115,7 +115,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
|
||||
mm->context.pte_frag = NULL;
|
||||
#endif
|
||||
#ifdef CONFIG_SPAPR_TCE_IOMMU
|
||||
mm_iommu_init(&mm->context);
|
||||
mm_iommu_init(mm);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -156,13 +156,11 @@ static inline void destroy_pagetable_page(struct mm_struct *mm)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void destroy_context(struct mm_struct *mm)
|
||||
{
|
||||
#ifdef CONFIG_SPAPR_TCE_IOMMU
|
||||
mm_iommu_cleanup(&mm->context);
|
||||
WARN_ON_ONCE(!list_empty(&mm->context.iommu_group_mem_list));
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC_ICSWX
|
||||
drop_cop(mm->context.acop, mm);
|
||||
kfree(mm->context.cop_lockp);
|
||||
|
||||
@@ -56,7 +56,7 @@ static long mm_iommu_adjust_locked_vm(struct mm_struct *mm,
|
||||
}
|
||||
|
||||
pr_debug("[%d] RLIMIT_MEMLOCK HASH64 %c%ld %ld/%ld\n",
|
||||
current->pid,
|
||||
current ? current->pid : 0,
|
||||
incr ? '+' : '-',
|
||||
npages << PAGE_SHIFT,
|
||||
mm->locked_vm << PAGE_SHIFT,
|
||||
@@ -66,12 +66,9 @@ static long mm_iommu_adjust_locked_vm(struct mm_struct *mm,
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool mm_iommu_preregistered(void)
|
||||
bool mm_iommu_preregistered(struct mm_struct *mm)
|
||||
{
|
||||
if (!current || !current->mm)
|
||||
return false;
|
||||
|
||||
return !list_empty(¤t->mm->context.iommu_group_mem_list);
|
||||
return !list_empty(&mm->context.iommu_group_mem_list);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mm_iommu_preregistered);
|
||||
|
||||
@@ -124,19 +121,16 @@ static int mm_iommu_move_page_from_cma(struct page *page)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long mm_iommu_get(unsigned long ua, unsigned long entries,
|
||||
long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries,
|
||||
struct mm_iommu_table_group_mem_t **pmem)
|
||||
{
|
||||
struct mm_iommu_table_group_mem_t *mem;
|
||||
long i, j, ret = 0, locked_entries = 0;
|
||||
struct page *page = NULL;
|
||||
|
||||
if (!current || !current->mm)
|
||||
return -ESRCH; /* process exited */
|
||||
|
||||
mutex_lock(&mem_list_mutex);
|
||||
|
||||
list_for_each_entry_rcu(mem, ¤t->mm->context.iommu_group_mem_list,
|
||||
list_for_each_entry_rcu(mem, &mm->context.iommu_group_mem_list,
|
||||
next) {
|
||||
if ((mem->ua == ua) && (mem->entries == entries)) {
|
||||
++mem->used;
|
||||
@@ -154,7 +148,7 @@ long mm_iommu_get(unsigned long ua, unsigned long entries,
|
||||
|
||||
}
|
||||
|
||||
ret = mm_iommu_adjust_locked_vm(current->mm, entries, true);
|
||||
ret = mm_iommu_adjust_locked_vm(mm, entries, true);
|
||||
if (ret)
|
||||
goto unlock_exit;
|
||||
|
||||
@@ -190,7 +184,7 @@ long mm_iommu_get(unsigned long ua, unsigned long entries,
|
||||
* of the CMA zone if possible. NOTE: faulting in + migration
|
||||
* can be expensive. Batching can be considered later
|
||||
*/
|
||||
if (get_pageblock_migratetype(page) == MIGRATE_CMA) {
|
||||
if (is_migrate_cma_page(page)) {
|
||||
if (mm_iommu_move_page_from_cma(page))
|
||||
goto populate;
|
||||
if (1 != get_user_pages_fast(ua + (i << PAGE_SHIFT),
|
||||
@@ -215,11 +209,11 @@ populate:
|
||||
mem->entries = entries;
|
||||
*pmem = mem;
|
||||
|
||||
list_add_rcu(&mem->next, ¤t->mm->context.iommu_group_mem_list);
|
||||
list_add_rcu(&mem->next, &mm->context.iommu_group_mem_list);
|
||||
|
||||
unlock_exit:
|
||||
if (locked_entries && ret)
|
||||
mm_iommu_adjust_locked_vm(current->mm, locked_entries, false);
|
||||
mm_iommu_adjust_locked_vm(mm, locked_entries, false);
|
||||
|
||||
mutex_unlock(&mem_list_mutex);
|
||||
|
||||
@@ -264,17 +258,13 @@ static void mm_iommu_free(struct rcu_head *head)
|
||||
static void mm_iommu_release(struct mm_iommu_table_group_mem_t *mem)
|
||||
{
|
||||
list_del_rcu(&mem->next);
|
||||
mm_iommu_adjust_locked_vm(current->mm, mem->entries, false);
|
||||
call_rcu(&mem->rcu, mm_iommu_free);
|
||||
}
|
||||
|
||||
long mm_iommu_put(struct mm_iommu_table_group_mem_t *mem)
|
||||
long mm_iommu_put(struct mm_struct *mm, struct mm_iommu_table_group_mem_t *mem)
|
||||
{
|
||||
long ret = 0;
|
||||
|
||||
if (!current || !current->mm)
|
||||
return -ESRCH; /* process exited */
|
||||
|
||||
mutex_lock(&mem_list_mutex);
|
||||
|
||||
if (mem->used == 0) {
|
||||
@@ -297,6 +287,8 @@ long mm_iommu_put(struct mm_iommu_table_group_mem_t *mem)
|
||||
/* @mapped became 0 so now mappings are disabled, release the region */
|
||||
mm_iommu_release(mem);
|
||||
|
||||
mm_iommu_adjust_locked_vm(mm, mem->entries, false);
|
||||
|
||||
unlock_exit:
|
||||
mutex_unlock(&mem_list_mutex);
|
||||
|
||||
@@ -304,14 +296,12 @@ unlock_exit:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mm_iommu_put);
|
||||
|
||||
struct mm_iommu_table_group_mem_t *mm_iommu_lookup(unsigned long ua,
|
||||
unsigned long size)
|
||||
struct mm_iommu_table_group_mem_t *mm_iommu_lookup(struct mm_struct *mm,
|
||||
unsigned long ua, unsigned long size)
|
||||
{
|
||||
struct mm_iommu_table_group_mem_t *mem, *ret = NULL;
|
||||
|
||||
list_for_each_entry_rcu(mem,
|
||||
¤t->mm->context.iommu_group_mem_list,
|
||||
next) {
|
||||
list_for_each_entry_rcu(mem, &mm->context.iommu_group_mem_list, next) {
|
||||
if ((mem->ua <= ua) &&
|
||||
(ua + size <= mem->ua +
|
||||
(mem->entries << PAGE_SHIFT))) {
|
||||
@@ -324,14 +314,12 @@ struct mm_iommu_table_group_mem_t *mm_iommu_lookup(unsigned long ua,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mm_iommu_lookup);
|
||||
|
||||
struct mm_iommu_table_group_mem_t *mm_iommu_find(unsigned long ua,
|
||||
unsigned long entries)
|
||||
struct mm_iommu_table_group_mem_t *mm_iommu_find(struct mm_struct *mm,
|
||||
unsigned long ua, unsigned long entries)
|
||||
{
|
||||
struct mm_iommu_table_group_mem_t *mem, *ret = NULL;
|
||||
|
||||
list_for_each_entry_rcu(mem,
|
||||
¤t->mm->context.iommu_group_mem_list,
|
||||
next) {
|
||||
list_for_each_entry_rcu(mem, &mm->context.iommu_group_mem_list, next) {
|
||||
if ((mem->ua == ua) && (mem->entries == entries)) {
|
||||
ret = mem;
|
||||
break;
|
||||
@@ -373,17 +361,7 @@ void mm_iommu_mapped_dec(struct mm_iommu_table_group_mem_t *mem)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mm_iommu_mapped_dec);
|
||||
|
||||
void mm_iommu_init(mm_context_t *ctx)
|
||||
void mm_iommu_init(struct mm_struct *mm)
|
||||
{
|
||||
INIT_LIST_HEAD_RCU(&ctx->iommu_group_mem_list);
|
||||
}
|
||||
|
||||
void mm_iommu_cleanup(mm_context_t *ctx)
|
||||
{
|
||||
struct mm_iommu_table_group_mem_t *mem, *tmp;
|
||||
|
||||
list_for_each_entry_safe(mem, tmp, &ctx->iommu_group_mem_list, next) {
|
||||
list_del_rcu(&mem->next);
|
||||
mm_iommu_do_free(mem);
|
||||
}
|
||||
INIT_LIST_HEAD_RCU(&mm->context.iommu_group_mem_list);
|
||||
}
|
||||
|
||||
@@ -91,6 +91,16 @@ static unsigned int icp_opal_get_irq(void)
|
||||
|
||||
static void icp_opal_set_cpu_priority(unsigned char cppr)
|
||||
{
|
||||
/*
|
||||
* Here be dragons. The caller has asked to allow only IPI's and not
|
||||
* external interrupts. But OPAL XIVE doesn't support that. So instead
|
||||
* of allowing no interrupts allow all. That's still not right, but
|
||||
* currently the only caller who does this is xics_migrate_irqs_away()
|
||||
* and it works in that case.
|
||||
*/
|
||||
if (cppr >= DEFAULT_PRIORITY)
|
||||
cppr = LOWEST_PRIORITY;
|
||||
|
||||
xics_set_base_cppr(cppr);
|
||||
opal_int_set_cppr(cppr);
|
||||
iosync();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/prom.h>
|
||||
#include <asm/io.h>
|
||||
@@ -198,9 +199,6 @@ void xics_migrate_irqs_away(void)
|
||||
/* Remove ourselves from the global interrupt queue */
|
||||
xics_set_cpu_giq(xics_default_distrib_server, 0);
|
||||
|
||||
/* Allow IPIs again... */
|
||||
icp_ops->set_priority(DEFAULT_PRIORITY);
|
||||
|
||||
for_each_irq_desc(virq, desc) {
|
||||
struct irq_chip *chip;
|
||||
long server;
|
||||
@@ -255,6 +253,19 @@ void xics_migrate_irqs_away(void)
|
||||
unlock:
|
||||
raw_spin_unlock_irqrestore(&desc->lock, flags);
|
||||
}
|
||||
|
||||
/* Allow "sufficient" time to drop any inflight IRQ's */
|
||||
mdelay(5);
|
||||
|
||||
/*
|
||||
* Allow IPIs again. This is done at the very end, after migrating all
|
||||
* interrupts, the expectation is that we'll only get woken up by an IPI
|
||||
* interrupt beyond this point, but leave externals masked just to be
|
||||
* safe. If we're using icp-opal this may actually allow all
|
||||
* interrupts anyway, but that should be OK.
|
||||
*/
|
||||
icp_ops->set_priority(DEFAULT_PRIORITY);
|
||||
|
||||
}
|
||||
#endif /* CONFIG_HOTPLUG_CPU */
|
||||
|
||||
|
||||
@@ -89,7 +89,8 @@ extern void execve_tail(void);
|
||||
* User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit.
|
||||
*/
|
||||
|
||||
#define TASK_SIZE_OF(tsk) ((tsk)->mm->context.asce_limit)
|
||||
#define TASK_SIZE_OF(tsk) ((tsk)->mm ? \
|
||||
(tsk)->mm->context.asce_limit : TASK_MAX_SIZE)
|
||||
#define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \
|
||||
(1UL << 30) : (1UL << 41))
|
||||
#define TASK_SIZE TASK_SIZE_OF(current)
|
||||
|
||||
@@ -329,7 +329,11 @@ static void *nt_init_name(void *buf, Elf64_Word type, void *desc, int d_len,
|
||||
|
||||
static inline void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len)
|
||||
{
|
||||
return nt_init_name(buf, type, desc, d_len, KEXEC_CORE_NOTE_NAME);
|
||||
const char *note_name = "LINUX";
|
||||
|
||||
if (type == NT_PRPSINFO || type == NT_PRSTATUS || type == NT_PRFPREG)
|
||||
note_name = KEXEC_CORE_NOTE_NAME;
|
||||
return nt_init_name(buf, type, desc, d_len, note_name);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -819,10 +819,10 @@ static void __init setup_randomness(void)
|
||||
{
|
||||
struct sysinfo_3_2_2 *vmms;
|
||||
|
||||
vmms = (struct sysinfo_3_2_2 *) alloc_page(GFP_KERNEL);
|
||||
if (vmms && stsi(vmms, 3, 2, 2) == 0 && vmms->count)
|
||||
add_device_randomness(&vmms, vmms->count);
|
||||
free_page((unsigned long) vmms);
|
||||
vmms = (struct sysinfo_3_2_2 *) memblock_alloc(PAGE_SIZE, PAGE_SIZE);
|
||||
if (stsi(vmms, 3, 2, 2) == 0 && vmms->count)
|
||||
add_device_randomness(&vmms->vm, sizeof(vmms->vm[0]) * vmms->count);
|
||||
memblock_free((unsigned long) vmms, PAGE_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -442,6 +442,9 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
|
||||
struct kvm_memory_slot *memslot;
|
||||
int is_dirty = 0;
|
||||
|
||||
if (kvm_is_ucontrol(kvm))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&kvm->slots_lock);
|
||||
|
||||
r = -EINVAL;
|
||||
|
||||
@@ -606,12 +606,29 @@ void ptep_zap_key(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
|
||||
bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long addr)
|
||||
{
|
||||
spinlock_t *ptl;
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pgste_t pgste;
|
||||
pte_t *ptep;
|
||||
pte_t pte;
|
||||
bool dirty;
|
||||
|
||||
ptep = get_locked_pte(mm, addr, &ptl);
|
||||
pgd = pgd_offset(mm, addr);
|
||||
pud = pud_alloc(mm, pgd, addr);
|
||||
if (!pud)
|
||||
return false;
|
||||
pmd = pmd_alloc(mm, pud, addr);
|
||||
if (!pmd)
|
||||
return false;
|
||||
/* We can't run guests backed by huge pages, but userspace can
|
||||
* still set them up and then try to migrate them without any
|
||||
* migration support.
|
||||
*/
|
||||
if (pmd_large(*pmd))
|
||||
return true;
|
||||
|
||||
ptep = pte_alloc_map_lock(mm, pmd, addr, &ptl);
|
||||
if (unlikely(!ptep))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -2096,8 +2096,8 @@ static int x86_pmu_event_init(struct perf_event *event)
|
||||
|
||||
static void refresh_pce(void *ignored)
|
||||
{
|
||||
if (current->mm)
|
||||
load_mm_cr4(current->mm);
|
||||
if (current->active_mm)
|
||||
load_mm_cr4(current->active_mm);
|
||||
}
|
||||
|
||||
static void x86_pmu_event_mapped(struct perf_event *event)
|
||||
|
||||
@@ -46,6 +46,15 @@ extern int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
|
||||
static inline
|
||||
bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey)
|
||||
{
|
||||
/*
|
||||
* "Allocated" pkeys are those that have been returned
|
||||
* from pkey_alloc(). pkey 0 is special, and never
|
||||
* returned from pkey_alloc().
|
||||
*/
|
||||
if (pkey <= 0)
|
||||
return false;
|
||||
if (pkey >= arch_max_pkey())
|
||||
return false;
|
||||
return mm_pkey_allocation_map(mm) & (1U << pkey);
|
||||
}
|
||||
|
||||
@@ -82,12 +91,6 @@ int mm_pkey_alloc(struct mm_struct *mm)
|
||||
static inline
|
||||
int mm_pkey_free(struct mm_struct *mm, int pkey)
|
||||
{
|
||||
/*
|
||||
* pkey 0 is special, always allocated and can never
|
||||
* be freed.
|
||||
*/
|
||||
if (!pkey)
|
||||
return -EINVAL;
|
||||
if (!mm_pkey_is_allocated(mm, pkey))
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ static inline void __native_flush_tlb_single(unsigned long addr)
|
||||
|
||||
static inline void __flush_tlb_all(void)
|
||||
{
|
||||
if (static_cpu_has(X86_FEATURE_PGE))
|
||||
if (boot_cpu_has(X86_FEATURE_PGE))
|
||||
__flush_tlb_global();
|
||||
else
|
||||
__flush_tlb();
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <asm/apic.h>
|
||||
#include <asm/timer.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/nmi.h>
|
||||
|
||||
struct ms_hyperv_info ms_hyperv;
|
||||
EXPORT_SYMBOL_GPL(ms_hyperv);
|
||||
@@ -158,6 +159,26 @@ static unsigned char hv_get_nmi_reason(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
/*
|
||||
* Prior to WS2016 Debug-VM sends NMIs to all CPUs which makes
|
||||
* it dificult to process CHANNELMSG_UNLOAD in case of crash. Handle
|
||||
* unknown NMI on the first CPU which gets it.
|
||||
*/
|
||||
static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs)
|
||||
{
|
||||
static atomic_t nmi_cpu = ATOMIC_INIT(-1);
|
||||
|
||||
if (!unknown_nmi_panic)
|
||||
return NMI_DONE;
|
||||
|
||||
if (atomic_cmpxchg(&nmi_cpu, -1, raw_smp_processor_id()) != -1)
|
||||
return NMI_HANDLED;
|
||||
|
||||
return NMI_DONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __init ms_hyperv_init_platform(void)
|
||||
{
|
||||
/*
|
||||
@@ -183,6 +204,9 @@ static void __init ms_hyperv_init_platform(void)
|
||||
pr_info("HyperV: LAPIC Timer Frequency: %#x\n",
|
||||
lapic_timer_frequency);
|
||||
}
|
||||
|
||||
register_nmi_handler(NMI_UNKNOWN, hv_nmi_unknown, NMI_FLAG_FIRST,
|
||||
"hv_nmi_unknown");
|
||||
#endif
|
||||
|
||||
if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
|
||||
*/
|
||||
|
||||
#define DISABLE_BRANCH_PROFILING
|
||||
#include <linux/init.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
@@ -1287,6 +1287,8 @@ static int __init init_tsc_clocksource(void)
|
||||
* exporting a reliable TSC.
|
||||
*/
|
||||
if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
|
||||
if (boot_cpu_has(X86_FEATURE_ART))
|
||||
art_related_clocksource = &clocksource_tsc;
|
||||
clocksource_register_khz(&clocksource_tsc, tsc_khz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3693,7 +3693,7 @@ static void fix_rmode_seg(int seg, struct kvm_segment *save)
|
||||
}
|
||||
|
||||
vmcs_write16(sf->selector, var.selector);
|
||||
vmcs_write32(sf->base, var.base);
|
||||
vmcs_writel(sf->base, var.base);
|
||||
vmcs_write32(sf->limit, var.limit);
|
||||
vmcs_write32(sf->ar_bytes, vmx_segment_access_rights(&var));
|
||||
}
|
||||
@@ -8202,7 +8202,7 @@ static void kvm_flush_pml_buffers(struct kvm *kvm)
|
||||
static void vmx_dump_sel(char *name, uint32_t sel)
|
||||
{
|
||||
pr_err("%s sel=0x%04x, attr=0x%05x, limit=0x%08x, base=0x%016lx\n",
|
||||
name, vmcs_read32(sel),
|
||||
name, vmcs_read16(sel),
|
||||
vmcs_read32(sel + GUEST_ES_AR_BYTES - GUEST_ES_SELECTOR),
|
||||
vmcs_read32(sel + GUEST_ES_LIMIT - GUEST_ES_SELECTOR),
|
||||
vmcs_readl(sel + GUEST_ES_BASE - GUEST_ES_SELECTOR));
|
||||
|
||||
@@ -120,6 +120,11 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pte_allows_gup(pte_val(pte), write)) {
|
||||
pte_unmap(ptep);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pte_devmap(pte)) {
|
||||
pgmap = get_dev_pagemap(pte_pfn(pte), pgmap);
|
||||
if (unlikely(!pgmap)) {
|
||||
@@ -127,8 +132,7 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
|
||||
pte_unmap(ptep);
|
||||
return 0;
|
||||
}
|
||||
} else if (!pte_allows_gup(pte_val(pte), write) ||
|
||||
pte_special(pte)) {
|
||||
} else if (pte_special(pte)) {
|
||||
pte_unmap(ptep);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#define DISABLE_BRANCH_PROFILING
|
||||
#define pr_fmt(fmt) "kasan: " fmt
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/kasan.h>
|
||||
|
||||
@@ -234,23 +234,14 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
||||
return 1;
|
||||
|
||||
for_each_pci_msi_entry(msidesc, dev) {
|
||||
__pci_read_msi_msg(msidesc, &msg);
|
||||
pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
|
||||
((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
|
||||
if (msg.data != XEN_PIRQ_MSI_DATA ||
|
||||
xen_irq_from_pirq(pirq) < 0) {
|
||||
pirq = xen_allocate_pirq_msi(dev, msidesc);
|
||||
if (pirq < 0) {
|
||||
irq = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
xen_msi_compose_msg(dev, pirq, &msg);
|
||||
__pci_write_msi_msg(msidesc, &msg);
|
||||
dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq);
|
||||
} else {
|
||||
dev_dbg(&dev->dev,
|
||||
"xen: msi already bound to pirq=%d\n", pirq);
|
||||
pirq = xen_allocate_pirq_msi(dev, msidesc);
|
||||
if (pirq < 0) {
|
||||
irq = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
xen_msi_compose_msg(dev, pirq, &msg);
|
||||
__pci_write_msi_msg(msidesc, &msg);
|
||||
dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq);
|
||||
irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq,
|
||||
(type == PCI_CAP_ID_MSI) ? nvec : 1,
|
||||
(type == PCI_CAP_ID_MSIX) ?
|
||||
|
||||
@@ -133,6 +133,8 @@ static int __init parse_tag_initrd(const bp_tag_t* tag)
|
||||
|
||||
__tagtable(BP_TAG_INITRD, parse_tag_initrd);
|
||||
|
||||
#endif /* CONFIG_BLK_DEV_INITRD */
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
||||
static int __init parse_tag_fdt(const bp_tag_t *tag)
|
||||
@@ -145,8 +147,6 @@ __tagtable(BP_TAG_FDT, parse_tag_fdt);
|
||||
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
#endif /* CONFIG_BLK_DEV_INITRD */
|
||||
|
||||
static int __init parse_tag_cmdline(const bp_tag_t* tag)
|
||||
{
|
||||
strlcpy(command_line, (char *)(tag->data), COMMAND_LINE_SIZE);
|
||||
|
||||
@@ -182,6 +182,9 @@ static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter)
|
||||
__set_bit(WRITE_16, filter->write_ok);
|
||||
__set_bit(WRITE_LONG, filter->write_ok);
|
||||
__set_bit(WRITE_LONG_2, filter->write_ok);
|
||||
__set_bit(WRITE_SAME, filter->write_ok);
|
||||
__set_bit(WRITE_SAME_16, filter->write_ok);
|
||||
__set_bit(WRITE_SAME_32, filter->write_ok);
|
||||
__set_bit(ERASE, filter->write_ok);
|
||||
__set_bit(GPCMD_MODE_SELECT_10, filter->write_ok);
|
||||
__set_bit(MODE_SELECT, filter->write_ok);
|
||||
|
||||
@@ -71,6 +71,7 @@ obj-$(CONFIG_CRYPTO_SHA256) += sha256_generic.o
|
||||
obj-$(CONFIG_CRYPTO_SHA512) += sha512_generic.o
|
||||
obj-$(CONFIG_CRYPTO_SHA3) += sha3_generic.o
|
||||
obj-$(CONFIG_CRYPTO_WP512) += wp512.o
|
||||
CFLAGS_wp512.o := $(call cc-option,-fno-schedule-insns) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149
|
||||
obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o
|
||||
obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o
|
||||
obj-$(CONFIG_CRYPTO_ECB) += ecb.o
|
||||
@@ -94,6 +95,7 @@ obj-$(CONFIG_CRYPTO_BLOWFISH_COMMON) += blowfish_common.o
|
||||
obj-$(CONFIG_CRYPTO_TWOFISH) += twofish_generic.o
|
||||
obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o
|
||||
obj-$(CONFIG_CRYPTO_SERPENT) += serpent_generic.o
|
||||
CFLAGS_serpent_generic.o := $(call cc-option,-fsched-pressure) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149
|
||||
obj-$(CONFIG_CRYPTO_AES) += aes_generic.o
|
||||
obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia_generic.o
|
||||
obj-$(CONFIG_CRYPTO_CAST_COMMON) += cast_common.o
|
||||
|
||||
@@ -22813,7 +22813,7 @@ static struct aead_testvec aes_ccm_enc_tv_template[] = {
|
||||
"\x09\x75\x9a\x9b\x3c\x9b\x27\x39",
|
||||
.klen = 32,
|
||||
.iv = "\x03\xf9\xd9\x4e\x63\xb5\x3d\x9d"
|
||||
"\x43\xf6\x1e\x50",
|
||||
"\x43\xf6\x1e\x50\0\0\0\0",
|
||||
.assoc = "\x57\xf5\x6b\x8b\x57\x5c\x3d\x3b"
|
||||
"\x13\x02\x01\x0c\x83\x4c\x96\x35"
|
||||
"\x8e\xd6\x39\xcf\x7d\x14\x9b\x94"
|
||||
|
||||
@@ -160,6 +160,34 @@ static struct dmi_system_id acpi_rev_dmi_table[] __initdata = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = dmi_enable_rev_override,
|
||||
.ident = "DELL Precision 5520",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Precision 5520"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = dmi_enable_rev_override,
|
||||
.ident = "DELL Precision 3520",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3520"),
|
||||
},
|
||||
},
|
||||
/*
|
||||
* Resolves a quirk with the Dell Latitude 3350 that
|
||||
* causes the ethernet adapter to not function.
|
||||
*/
|
||||
{
|
||||
.callback = dmi_enable_rev_override,
|
||||
.ident = "DELL Latitude 3350",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 3350"),
|
||||
},
|
||||
},
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -1603,7 +1603,7 @@ static size_t sizeof_nfit_set_info(int num_mappings)
|
||||
+ num_mappings * sizeof(struct nfit_set_info_map);
|
||||
}
|
||||
|
||||
static int cmp_map(const void *m0, const void *m1)
|
||||
static int cmp_map_compat(const void *m0, const void *m1)
|
||||
{
|
||||
const struct nfit_set_info_map *map0 = m0;
|
||||
const struct nfit_set_info_map *map1 = m1;
|
||||
@@ -1612,6 +1612,14 @@ static int cmp_map(const void *m0, const void *m1)
|
||||
sizeof(u64));
|
||||
}
|
||||
|
||||
static int cmp_map(const void *m0, const void *m1)
|
||||
{
|
||||
const struct nfit_set_info_map *map0 = m0;
|
||||
const struct nfit_set_info_map *map1 = m1;
|
||||
|
||||
return map0->region_offset - map1->region_offset;
|
||||
}
|
||||
|
||||
/* Retrieve the nth entry referencing this spa */
|
||||
static struct acpi_nfit_memory_map *memdev_from_spa(
|
||||
struct acpi_nfit_desc *acpi_desc, u16 range_index, int n)
|
||||
@@ -1667,6 +1675,12 @@ static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc *acpi_desc,
|
||||
sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map),
|
||||
cmp_map, NULL);
|
||||
nd_set->cookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
|
||||
|
||||
/* support namespaces created with the wrong sort order */
|
||||
sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map),
|
||||
cmp_map_compat, NULL);
|
||||
nd_set->altcookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
|
||||
|
||||
ndr_desc->nd_set = nd_set;
|
||||
devm_kfree(dev, info);
|
||||
|
||||
|
||||
@@ -633,8 +633,11 @@ static int bcma_device_probe(struct device *dev)
|
||||
drv);
|
||||
int err = 0;
|
||||
|
||||
get_device(dev);
|
||||
if (adrv->probe)
|
||||
err = adrv->probe(core);
|
||||
if (err)
|
||||
put_device(dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -647,6 +650,7 @@ static int bcma_device_remove(struct device *dev)
|
||||
|
||||
if (adrv->remove)
|
||||
adrv->remove(core);
|
||||
put_device(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1097,9 +1097,12 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
/* I/O need to be drained during transfer transition */
|
||||
blk_mq_freeze_queue(lo->lo_queue);
|
||||
|
||||
err = loop_release_xfer(lo);
|
||||
if (err)
|
||||
return err;
|
||||
goto exit;
|
||||
|
||||
if (info->lo_encrypt_type) {
|
||||
unsigned int type = info->lo_encrypt_type;
|
||||
@@ -1114,12 +1117,14 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
|
||||
err = loop_init_xfer(lo, xfer, info);
|
||||
if (err)
|
||||
return err;
|
||||
goto exit;
|
||||
|
||||
if (lo->lo_offset != info->lo_offset ||
|
||||
lo->lo_sizelimit != info->lo_sizelimit)
|
||||
if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit))
|
||||
return -EFBIG;
|
||||
if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) {
|
||||
err = -EFBIG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
loop_config_discard(lo);
|
||||
|
||||
@@ -1137,13 +1142,6 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
(info->lo_flags & LO_FLAGS_AUTOCLEAR))
|
||||
lo->lo_flags ^= LO_FLAGS_AUTOCLEAR;
|
||||
|
||||
if ((info->lo_flags & LO_FLAGS_PARTSCAN) &&
|
||||
!(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
|
||||
lo->lo_flags |= LO_FLAGS_PARTSCAN;
|
||||
lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
|
||||
loop_reread_partitions(lo, lo->lo_device);
|
||||
}
|
||||
|
||||
lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
|
||||
lo->lo_init[0] = info->lo_init[0];
|
||||
lo->lo_init[1] = info->lo_init[1];
|
||||
@@ -1156,7 +1154,17 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
/* update dio if lo_offset or transfer is changed */
|
||||
__loop_update_dio(lo, lo->use_dio);
|
||||
|
||||
return 0;
|
||||
exit:
|
||||
blk_mq_unfreeze_queue(lo->lo_queue);
|
||||
|
||||
if (!err && (info->lo_flags & LO_FLAGS_PARTSCAN) &&
|
||||
!(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
|
||||
lo->lo_flags |= LO_FLAGS_PARTSCAN;
|
||||
lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
|
||||
loop_reread_partitions(lo, lo->lo_device);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -94,6 +94,7 @@ static const struct usb_device_id ath3k_table[] = {
|
||||
{ USB_DEVICE(0x04CA, 0x300f) },
|
||||
{ USB_DEVICE(0x04CA, 0x3010) },
|
||||
{ USB_DEVICE(0x04CA, 0x3014) },
|
||||
{ USB_DEVICE(0x04CA, 0x3018) },
|
||||
{ USB_DEVICE(0x0930, 0x0219) },
|
||||
{ USB_DEVICE(0x0930, 0x021c) },
|
||||
{ USB_DEVICE(0x0930, 0x0220) },
|
||||
@@ -162,6 +163,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
|
||||
{ USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3018), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
@@ -209,6 +209,7 @@ static const struct usb_device_id blacklist_table[] = {
|
||||
{ USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3018), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
@@ -421,7 +421,7 @@ err_pnp:
|
||||
acpi_bus_unregister_driver(&tis_acpi_driver);
|
||||
err_acpi:
|
||||
#endif
|
||||
platform_device_unregister(force_pdev);
|
||||
platform_driver_unregister(&tis_drv);
|
||||
err_platform:
|
||||
if (force_pdev)
|
||||
platform_device_unregister(force_pdev);
|
||||
|
||||
@@ -1598,7 +1598,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
|
||||
.a2w_reg = A2W_PLLH_AUX,
|
||||
.load_mask = CM_PLLH_LOADAUX,
|
||||
.hold_mask = 0,
|
||||
.fixed_divider = 10),
|
||||
.fixed_divider = 1),
|
||||
[BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(
|
||||
.name = "pllh_pix",
|
||||
.source_pll = "pllh",
|
||||
|
||||
@@ -130,7 +130,7 @@ static void devfreq_set_freq_table(struct devfreq *devfreq)
|
||||
* @devfreq: the devfreq instance
|
||||
* @freq: the update target frequency
|
||||
*/
|
||||
static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
|
||||
int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
|
||||
{
|
||||
int lev, prev_lev, ret = 0;
|
||||
unsigned long cur_time;
|
||||
@@ -166,6 +166,7 @@ out:
|
||||
devfreq->last_stat_updated = cur_time;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(devfreq_update_status);
|
||||
|
||||
/**
|
||||
* find_devfreq_governor() - find devfreq governor from name
|
||||
@@ -939,6 +940,9 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
|
||||
if (df->governor == governor) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
} else if (df->governor->immutable || governor->immutable) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (df->governor) {
|
||||
@@ -968,13 +972,33 @@ static ssize_t available_governors_show(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct devfreq_governor *tmp_governor;
|
||||
struct devfreq *df = to_devfreq(d);
|
||||
ssize_t count = 0;
|
||||
|
||||
mutex_lock(&devfreq_list_lock);
|
||||
list_for_each_entry(tmp_governor, &devfreq_governor_list, node)
|
||||
count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
|
||||
"%s ", tmp_governor->name);
|
||||
|
||||
/*
|
||||
* The devfreq with immutable governor (e.g., passive) shows
|
||||
* only own governor.
|
||||
*/
|
||||
if (df->governor->immutable) {
|
||||
count = scnprintf(&buf[count], DEVFREQ_NAME_LEN,
|
||||
"%s ", df->governor_name);
|
||||
/*
|
||||
* The devfreq device shows the registered governor except for
|
||||
* immutable governors such as passive governor .
|
||||
*/
|
||||
} else {
|
||||
struct devfreq_governor *governor;
|
||||
|
||||
list_for_each_entry(governor, &devfreq_governor_list, node) {
|
||||
if (governor->immutable)
|
||||
continue;
|
||||
count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
|
||||
"%s ", governor->name);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&devfreq_list_lock);
|
||||
|
||||
/* Truncate the trailing space */
|
||||
|
||||
@@ -38,4 +38,6 @@ extern void devfreq_interval_update(struct devfreq *devfreq,
|
||||
extern int devfreq_add_governor(struct devfreq_governor *governor);
|
||||
extern int devfreq_remove_governor(struct devfreq_governor *governor);
|
||||
|
||||
extern int devfreq_update_status(struct devfreq *devfreq, unsigned long freq);
|
||||
|
||||
#endif /* _GOVERNOR_H */
|
||||
|
||||
@@ -112,6 +112,11 @@ static int update_devfreq_passive(struct devfreq *devfreq, unsigned long freq)
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (devfreq->profile->freq_table
|
||||
&& (devfreq_update_status(devfreq, freq)))
|
||||
dev_err(&devfreq->dev,
|
||||
"Couldn't update frequency transition information.\n");
|
||||
|
||||
devfreq->previous_freq = freq;
|
||||
|
||||
out:
|
||||
@@ -179,6 +184,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq,
|
||||
|
||||
static struct devfreq_governor devfreq_passive = {
|
||||
.name = "passive",
|
||||
.immutable = 1,
|
||||
.get_target_freq = devfreq_passive_get_target_freq,
|
||||
.event_handler = devfreq_passive_event_handler,
|
||||
};
|
||||
|
||||
@@ -298,6 +298,7 @@ struct sdma_engine;
|
||||
* @event_id1 for channels that use 2 events
|
||||
* @word_size peripheral access size
|
||||
* @buf_tail ID of the buffer that was processed
|
||||
* @buf_ptail ID of the previous buffer that was processed
|
||||
* @num_bd max NUM_BD. number of descriptors currently handling
|
||||
*/
|
||||
struct sdma_channel {
|
||||
@@ -309,6 +310,7 @@ struct sdma_channel {
|
||||
unsigned int event_id1;
|
||||
enum dma_slave_buswidth word_size;
|
||||
unsigned int buf_tail;
|
||||
unsigned int buf_ptail;
|
||||
unsigned int num_bd;
|
||||
unsigned int period_len;
|
||||
struct sdma_buffer_descriptor *bd;
|
||||
@@ -700,6 +702,8 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
|
||||
sdmac->chn_real_count = bd->mode.count;
|
||||
bd->mode.status |= BD_DONE;
|
||||
bd->mode.count = sdmac->period_len;
|
||||
sdmac->buf_ptail = sdmac->buf_tail;
|
||||
sdmac->buf_tail = (sdmac->buf_tail + 1) % sdmac->num_bd;
|
||||
|
||||
/*
|
||||
* The callback is called from the interrupt context in order
|
||||
@@ -710,9 +714,6 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
|
||||
|
||||
dmaengine_desc_get_callback_invoke(&sdmac->desc, NULL);
|
||||
|
||||
sdmac->buf_tail++;
|
||||
sdmac->buf_tail %= sdmac->num_bd;
|
||||
|
||||
if (error)
|
||||
sdmac->status = old_status;
|
||||
}
|
||||
@@ -1186,6 +1187,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
|
||||
sdmac->flags = 0;
|
||||
|
||||
sdmac->buf_tail = 0;
|
||||
sdmac->buf_ptail = 0;
|
||||
sdmac->chn_real_count = 0;
|
||||
|
||||
dev_dbg(sdma->dev, "setting up %d entries for channel %d.\n",
|
||||
sg_len, channel);
|
||||
@@ -1288,6 +1291,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
|
||||
sdmac->status = DMA_IN_PROGRESS;
|
||||
|
||||
sdmac->buf_tail = 0;
|
||||
sdmac->buf_ptail = 0;
|
||||
sdmac->chn_real_count = 0;
|
||||
sdmac->period_len = period_len;
|
||||
|
||||
sdmac->flags |= IMX_DMA_SG_LOOP;
|
||||
@@ -1385,7 +1390,7 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
|
||||
u32 residue;
|
||||
|
||||
if (sdmac->flags & IMX_DMA_SG_LOOP)
|
||||
residue = (sdmac->num_bd - sdmac->buf_tail) *
|
||||
residue = (sdmac->num_bd - sdmac->buf_ptail) *
|
||||
sdmac->period_len - sdmac->chn_real_count;
|
||||
else
|
||||
residue = sdmac->chn_count - sdmac->chn_real_count;
|
||||
|
||||
@@ -691,7 +691,7 @@ static int ioat_alloc_chan_resources(struct dma_chan *c)
|
||||
/* doing 2 32bit writes to mmio since 1 64b write doesn't work */
|
||||
ioat_chan->completion =
|
||||
dma_pool_zalloc(ioat_chan->ioat_dma->completion_pool,
|
||||
GFP_KERNEL, &ioat_chan->completion_dma);
|
||||
GFP_NOWAIT, &ioat_chan->completion_dma);
|
||||
if (!ioat_chan->completion)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -701,7 +701,7 @@ static int ioat_alloc_chan_resources(struct dma_chan *c)
|
||||
ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH);
|
||||
|
||||
order = IOAT_MAX_ORDER;
|
||||
ring = ioat_alloc_ring(c, order, GFP_KERNEL);
|
||||
ring = ioat_alloc_ring(c, order, GFP_NOWAIT);
|
||||
if (!ring)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -272,7 +272,7 @@ static void ipu_irq_handler(struct irq_desc *desc)
|
||||
u32 status;
|
||||
int i, line;
|
||||
|
||||
for (i = IPU_IRQ_NR_FN_BANKS; i < IPU_IRQ_NR_BANKS; i++) {
|
||||
for (i = 0; i < IPU_IRQ_NR_BANKS; i++) {
|
||||
struct ipu_irq_bank *bank = irq_bank + i;
|
||||
|
||||
raw_spin_lock(&bank_lock);
|
||||
|
||||
@@ -65,6 +65,7 @@ static bool __init efi_virtmap_init(void)
|
||||
bool systab_found;
|
||||
|
||||
efi_mm.pgd = pgd_alloc(&efi_mm);
|
||||
mm_init_cpumask(&efi_mm);
|
||||
init_new_context(NULL, &efi_mm);
|
||||
|
||||
systab_found = false;
|
||||
|
||||
@@ -3814,9 +3814,15 @@ static void dce_v11_0_encoder_add(struct amdgpu_device *adev,
|
||||
default:
|
||||
encoder->possible_crtcs = 0x3;
|
||||
break;
|
||||
case 3:
|
||||
encoder->possible_crtcs = 0x7;
|
||||
break;
|
||||
case 4:
|
||||
encoder->possible_crtcs = 0xf;
|
||||
break;
|
||||
case 5:
|
||||
encoder->possible_crtcs = 0x1f;
|
||||
break;
|
||||
case 6:
|
||||
encoder->possible_crtcs = 0x3f;
|
||||
break;
|
||||
|
||||
@@ -58,13 +58,9 @@ bool ast_is_vga_enabled(struct drm_device *dev)
|
||||
/* TODO 1180 */
|
||||
} else {
|
||||
ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT);
|
||||
if (ch) {
|
||||
ast_open_key(ast);
|
||||
ch = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff);
|
||||
return ch & 0x04;
|
||||
}
|
||||
return !!(ch & 0x01);
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff };
|
||||
@@ -375,8 +371,8 @@ void ast_post_gpu(struct drm_device *dev)
|
||||
pci_write_config_dword(ast->dev->pdev, 0x04, reg);
|
||||
|
||||
ast_enable_vga(dev);
|
||||
ast_enable_mmio(dev);
|
||||
ast_open_key(ast);
|
||||
ast_enable_mmio(dev);
|
||||
ast_set_def_ext_reg(dev);
|
||||
|
||||
if (ast->chip == AST2300 || ast->chip == AST2400)
|
||||
@@ -1630,12 +1626,44 @@ static void ast_init_dram_2300(struct drm_device *dev)
|
||||
temp |= 0x73;
|
||||
ast_write32(ast, 0x12008, temp);
|
||||
|
||||
param.dram_freq = 396;
|
||||
param.dram_type = AST_DDR3;
|
||||
temp = ast_mindwm(ast, 0x1e6e2070);
|
||||
if (temp & 0x01000000)
|
||||
param.dram_type = AST_DDR2;
|
||||
param.dram_chipid = ast->dram_type;
|
||||
param.dram_freq = ast->mclk;
|
||||
param.vram_size = ast->vram_size;
|
||||
switch (temp & 0x18000000) {
|
||||
case 0:
|
||||
param.dram_chipid = AST_DRAM_512Mx16;
|
||||
break;
|
||||
default:
|
||||
case 0x08000000:
|
||||
param.dram_chipid = AST_DRAM_1Gx16;
|
||||
break;
|
||||
case 0x10000000:
|
||||
param.dram_chipid = AST_DRAM_2Gx16;
|
||||
break;
|
||||
case 0x18000000:
|
||||
param.dram_chipid = AST_DRAM_4Gx16;
|
||||
break;
|
||||
}
|
||||
switch (temp & 0x0c) {
|
||||
default:
|
||||
case 0x00:
|
||||
param.vram_size = AST_VIDMEM_SIZE_8M;
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
param.vram_size = AST_VIDMEM_SIZE_16M;
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
param.vram_size = AST_VIDMEM_SIZE_32M;
|
||||
break;
|
||||
|
||||
case 0x0c:
|
||||
param.vram_size = AST_VIDMEM_SIZE_64M;
|
||||
break;
|
||||
}
|
||||
|
||||
if (param.dram_type == AST_DDR3) {
|
||||
get_ddr3_info(ast, ¶m);
|
||||
|
||||
@@ -362,7 +362,7 @@ mode_fixup(struct drm_atomic_state *state)
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_state *conn_state;
|
||||
int i;
|
||||
bool ret;
|
||||
int ret;
|
||||
|
||||
for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
if (!crtc_state->mode_changed &&
|
||||
|
||||
@@ -145,6 +145,9 @@ static struct edid_quirk {
|
||||
|
||||
/* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */
|
||||
{ "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC },
|
||||
|
||||
/* Rotel RSX-1058 forwards sink's EDID but only does HDMI 1.1*/
|
||||
{ "ETR", 13896, EDID_QUIRK_FORCE_8BPC },
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -848,6 +848,9 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
|
||||
if (!drm_fbdev_emulation)
|
||||
return;
|
||||
|
||||
cancel_work_sync(&fb_helper->resume_work);
|
||||
cancel_work_sync(&fb_helper->dirty_work);
|
||||
|
||||
if (!list_empty(&fb_helper->kernel_fb_list)) {
|
||||
list_del(&fb_helper->kernel_fb_list);
|
||||
if (list_empty(&kernel_fb_helper_list)) {
|
||||
|
||||
@@ -415,6 +415,11 @@ int i915_gem_init_stolen(struct drm_device *dev)
|
||||
|
||||
mutex_init(&dev_priv->mm.stolen_lock);
|
||||
|
||||
if (intel_vgpu_active(dev_priv)) {
|
||||
DRM_INFO("iGVT-g active, disabling use of stolen memory\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INTEL_IOMMU
|
||||
if (intel_iommu_gfx_mapped && INTEL_INFO(dev)->gen < 8) {
|
||||
DRM_INFO("DMAR active, disabling use of stolen memory\n");
|
||||
|
||||
@@ -2832,6 +2832,9 @@ static void vlv_detach_power_sequencer(struct intel_dp *intel_dp)
|
||||
enum pipe pipe = intel_dp->pps_pipe;
|
||||
i915_reg_t pp_on_reg = PP_ON_DELAYS(pipe);
|
||||
|
||||
if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
|
||||
return;
|
||||
|
||||
edp_panel_vdd_off_sync(intel_dp);
|
||||
|
||||
/*
|
||||
@@ -2859,9 +2862,6 @@ static void vlv_steal_power_sequencer(struct drm_device *dev,
|
||||
|
||||
lockdep_assert_held(&dev_priv->pps_mutex);
|
||||
|
||||
if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
|
||||
return;
|
||||
|
||||
for_each_intel_encoder(dev, encoder) {
|
||||
struct intel_dp *intel_dp;
|
||||
enum port port;
|
||||
|
||||
@@ -1031,7 +1031,18 @@ int intel_opregion_setup(struct drm_i915_private *dev_priv)
|
||||
opregion->vbt_size = vbt_size;
|
||||
} else {
|
||||
vbt = base + OPREGION_VBT_OFFSET;
|
||||
vbt_size = OPREGION_ASLE_EXT_OFFSET - OPREGION_VBT_OFFSET;
|
||||
/*
|
||||
* The VBT specification says that if the ASLE ext
|
||||
* mailbox is not used its area is reserved, but
|
||||
* on some CHT boards the VBT extends into the
|
||||
* ASLE ext area. Allow this even though it is
|
||||
* against the spec, so we do not end up rejecting
|
||||
* the VBT on those boards (and end up not finding the
|
||||
* LCD panel because of this).
|
||||
*/
|
||||
vbt_size = (mboxes & MBOX_ASLE_EXT) ?
|
||||
OPREGION_ASLE_EXT_OFFSET : OPREGION_SIZE;
|
||||
vbt_size -= OPREGION_VBT_OFFSET;
|
||||
if (intel_bios_is_valid_vbt(vbt, vbt_size)) {
|
||||
DRM_DEBUG_KMS("Found valid VBT in ACPI OpRegion (Mailbox #4)\n");
|
||||
opregion->vbt = vbt;
|
||||
|
||||
@@ -98,6 +98,8 @@
|
||||
/* TVE_TST_MODE_REG */
|
||||
#define TVE_TVDAC_TEST_MODE_MASK (0x7 << 0)
|
||||
|
||||
#define IMX_TVE_DAC_VOLTAGE 2750000
|
||||
|
||||
enum {
|
||||
TVE_MODE_TVOUT,
|
||||
TVE_MODE_VGA,
|
||||
@@ -628,9 +630,8 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data)
|
||||
|
||||
tve->dac_reg = devm_regulator_get(dev, "dac");
|
||||
if (!IS_ERR(tve->dac_reg)) {
|
||||
ret = regulator_set_voltage(tve->dac_reg, 2750000, 2750000);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (regulator_get_voltage(tve->dac_reg) != IMX_TVE_DAC_VOLTAGE)
|
||||
dev_warn(dev, "dac voltage is not %d uV\n", IMX_TVE_DAC_VOLTAGE);
|
||||
ret = regulator_enable(tve->dac_reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -95,9 +95,11 @@ nvkm-y += nvkm/engine/disp/cursg84.o
|
||||
nvkm-y += nvkm/engine/disp/cursgt215.o
|
||||
nvkm-y += nvkm/engine/disp/cursgf119.o
|
||||
nvkm-y += nvkm/engine/disp/cursgk104.o
|
||||
nvkm-y += nvkm/engine/disp/cursgp102.o
|
||||
|
||||
nvkm-y += nvkm/engine/disp/oimmnv50.o
|
||||
nvkm-y += nvkm/engine/disp/oimmg84.o
|
||||
nvkm-y += nvkm/engine/disp/oimmgt215.o
|
||||
nvkm-y += nvkm/engine/disp/oimmgf119.o
|
||||
nvkm-y += nvkm/engine/disp/oimmgk104.o
|
||||
nvkm-y += nvkm/engine/disp/oimmgp102.o
|
||||
|
||||
@@ -82,7 +82,7 @@ nv50_disp_chan_mthd(struct nv50_disp_chan *chan, int debug)
|
||||
|
||||
if (mthd->addr) {
|
||||
snprintf(cname_, sizeof(cname_), "%s %d",
|
||||
mthd->name, chan->chid);
|
||||
mthd->name, chan->chid.user);
|
||||
cname = cname_;
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ nv50_disp_chan_uevent_ctor(struct nvkm_object *object, void *data, u32 size,
|
||||
if (!(ret = nvif_unvers(ret, &data, &size, args->none))) {
|
||||
notify->size = sizeof(struct nvif_notify_uevent_rep);
|
||||
notify->types = 1;
|
||||
notify->index = chan->chid;
|
||||
notify->index = chan->chid.user;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data)
|
||||
struct nv50_disp_chan *chan = nv50_disp_chan(object);
|
||||
struct nv50_disp *disp = chan->root->disp;
|
||||
struct nvkm_device *device = disp->base.engine.subdev.device;
|
||||
*data = nvkm_rd32(device, 0x640000 + (chan->chid * 0x1000) + addr);
|
||||
*data = nvkm_rd32(device, 0x640000 + (chan->chid.user * 0x1000) + addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ nv50_disp_chan_wr32(struct nvkm_object *object, u64 addr, u32 data)
|
||||
struct nv50_disp_chan *chan = nv50_disp_chan(object);
|
||||
struct nv50_disp *disp = chan->root->disp;
|
||||
struct nvkm_device *device = disp->base.engine.subdev.device;
|
||||
nvkm_wr32(device, 0x640000 + (chan->chid * 0x1000) + addr, data);
|
||||
nvkm_wr32(device, 0x640000 + (chan->chid.user * 0x1000) + addr, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ nv50_disp_chan_map(struct nvkm_object *object, u64 *addr, u32 *size)
|
||||
struct nv50_disp *disp = chan->root->disp;
|
||||
struct nvkm_device *device = disp->base.engine.subdev.device;
|
||||
*addr = device->func->resource_addr(device, 0) +
|
||||
0x640000 + (chan->chid * 0x1000);
|
||||
0x640000 + (chan->chid.user * 0x1000);
|
||||
*size = 0x001000;
|
||||
return 0;
|
||||
}
|
||||
@@ -243,8 +243,8 @@ nv50_disp_chan_dtor(struct nvkm_object *object)
|
||||
{
|
||||
struct nv50_disp_chan *chan = nv50_disp_chan(object);
|
||||
struct nv50_disp *disp = chan->root->disp;
|
||||
if (chan->chid >= 0)
|
||||
disp->chan[chan->chid] = NULL;
|
||||
if (chan->chid.user >= 0)
|
||||
disp->chan[chan->chid.user] = NULL;
|
||||
return chan->func->dtor ? chan->func->dtor(chan) : chan;
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ nv50_disp_chan = {
|
||||
int
|
||||
nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func,
|
||||
const struct nv50_disp_chan_mthd *mthd,
|
||||
struct nv50_disp_root *root, int chid, int head,
|
||||
struct nv50_disp_root *root, int ctrl, int user, int head,
|
||||
const struct nvkm_oclass *oclass,
|
||||
struct nv50_disp_chan *chan)
|
||||
{
|
||||
@@ -273,21 +273,22 @@ nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func,
|
||||
chan->func = func;
|
||||
chan->mthd = mthd;
|
||||
chan->root = root;
|
||||
chan->chid = chid;
|
||||
chan->chid.ctrl = ctrl;
|
||||
chan->chid.user = user;
|
||||
chan->head = head;
|
||||
|
||||
if (disp->chan[chan->chid]) {
|
||||
chan->chid = -1;
|
||||
if (disp->chan[chan->chid.user]) {
|
||||
chan->chid.user = -1;
|
||||
return -EBUSY;
|
||||
}
|
||||
disp->chan[chan->chid] = chan;
|
||||
disp->chan[chan->chid.user] = chan;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nv50_disp_chan_new_(const struct nv50_disp_chan_func *func,
|
||||
const struct nv50_disp_chan_mthd *mthd,
|
||||
struct nv50_disp_root *root, int chid, int head,
|
||||
struct nv50_disp_root *root, int ctrl, int user, int head,
|
||||
const struct nvkm_oclass *oclass,
|
||||
struct nvkm_object **pobject)
|
||||
{
|
||||
@@ -297,5 +298,6 @@ nv50_disp_chan_new_(const struct nv50_disp_chan_func *func,
|
||||
return -ENOMEM;
|
||||
*pobject = &chan->object;
|
||||
|
||||
return nv50_disp_chan_ctor(func, mthd, root, chid, head, oclass, chan);
|
||||
return nv50_disp_chan_ctor(func, mthd, root, ctrl, user,
|
||||
head, oclass, chan);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,11 @@ struct nv50_disp_chan {
|
||||
const struct nv50_disp_chan_func *func;
|
||||
const struct nv50_disp_chan_mthd *mthd;
|
||||
struct nv50_disp_root *root;
|
||||
int chid;
|
||||
|
||||
struct {
|
||||
int ctrl;
|
||||
int user;
|
||||
} chid;
|
||||
int head;
|
||||
|
||||
struct nvkm_object object;
|
||||
@@ -25,11 +29,11 @@ struct nv50_disp_chan_func {
|
||||
|
||||
int nv50_disp_chan_ctor(const struct nv50_disp_chan_func *,
|
||||
const struct nv50_disp_chan_mthd *,
|
||||
struct nv50_disp_root *, int chid, int head,
|
||||
struct nv50_disp_root *, int ctrl, int user, int head,
|
||||
const struct nvkm_oclass *, struct nv50_disp_chan *);
|
||||
int nv50_disp_chan_new_(const struct nv50_disp_chan_func *,
|
||||
const struct nv50_disp_chan_mthd *,
|
||||
struct nv50_disp_root *, int chid, int head,
|
||||
struct nv50_disp_root *, int ctrl, int user, int head,
|
||||
const struct nvkm_oclass *, struct nvkm_object **);
|
||||
|
||||
extern const struct nv50_disp_chan_func nv50_disp_pioc_func;
|
||||
@@ -90,13 +94,16 @@ extern const struct nv50_disp_chan_mthd gk104_disp_ovly_chan_mthd;
|
||||
struct nv50_disp_pioc_oclass {
|
||||
int (*ctor)(const struct nv50_disp_chan_func *,
|
||||
const struct nv50_disp_chan_mthd *,
|
||||
struct nv50_disp_root *, int chid,
|
||||
struct nv50_disp_root *, int ctrl, int user,
|
||||
const struct nvkm_oclass *, void *data, u32 size,
|
||||
struct nvkm_object **);
|
||||
struct nvkm_sclass base;
|
||||
const struct nv50_disp_chan_func *func;
|
||||
const struct nv50_disp_chan_mthd *mthd;
|
||||
int chid;
|
||||
struct {
|
||||
int ctrl;
|
||||
int user;
|
||||
} chid;
|
||||
};
|
||||
|
||||
extern const struct nv50_disp_pioc_oclass nv50_disp_oimm_oclass;
|
||||
@@ -114,15 +121,17 @@ extern const struct nv50_disp_pioc_oclass gf119_disp_curs_oclass;
|
||||
extern const struct nv50_disp_pioc_oclass gk104_disp_oimm_oclass;
|
||||
extern const struct nv50_disp_pioc_oclass gk104_disp_curs_oclass;
|
||||
|
||||
extern const struct nv50_disp_pioc_oclass gp102_disp_oimm_oclass;
|
||||
extern const struct nv50_disp_pioc_oclass gp102_disp_curs_oclass;
|
||||
|
||||
int nv50_disp_curs_new(const struct nv50_disp_chan_func *,
|
||||
const struct nv50_disp_chan_mthd *,
|
||||
struct nv50_disp_root *, int chid,
|
||||
struct nv50_disp_root *, int ctrl, int user,
|
||||
const struct nvkm_oclass *, void *data, u32 size,
|
||||
struct nvkm_object **);
|
||||
int nv50_disp_oimm_new(const struct nv50_disp_chan_func *,
|
||||
const struct nv50_disp_chan_mthd *,
|
||||
struct nv50_disp_root *, int chid,
|
||||
struct nv50_disp_root *, int ctrl, int user,
|
||||
const struct nvkm_oclass *, void *data, u32 size,
|
||||
struct nvkm_object **);
|
||||
#endif
|
||||
|
||||
@@ -33,5 +33,5 @@ g84_disp_curs_oclass = {
|
||||
.base.maxver = 0,
|
||||
.ctor = nv50_disp_curs_new,
|
||||
.func = &nv50_disp_pioc_func,
|
||||
.chid = 7,
|
||||
.chid = { 7, 7 },
|
||||
};
|
||||
|
||||
@@ -33,5 +33,5 @@ gf119_disp_curs_oclass = {
|
||||
.base.maxver = 0,
|
||||
.ctor = nv50_disp_curs_new,
|
||||
.func = &gf119_disp_pioc_func,
|
||||
.chid = 13,
|
||||
.chid = { 13, 13 },
|
||||
};
|
||||
|
||||
@@ -33,5 +33,5 @@ gk104_disp_curs_oclass = {
|
||||
.base.maxver = 0,
|
||||
.ctor = nv50_disp_curs_new,
|
||||
.func = &gf119_disp_pioc_func,
|
||||
.chid = 13,
|
||||
.chid = { 13, 13 },
|
||||
};
|
||||
|
||||
37
drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c
Normal file
37
drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2016 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Ben Skeggs <bskeggs@redhat.com>
|
||||
*/
|
||||
#include "channv50.h"
|
||||
#include "rootnv50.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
const struct nv50_disp_pioc_oclass
|
||||
gp102_disp_curs_oclass = {
|
||||
.base.oclass = GK104_DISP_CURSOR,
|
||||
.base.minver = 0,
|
||||
.base.maxver = 0,
|
||||
.ctor = nv50_disp_curs_new,
|
||||
.func = &gf119_disp_pioc_func,
|
||||
.chid = { 13, 17 },
|
||||
};
|
||||
@@ -33,5 +33,5 @@ gt215_disp_curs_oclass = {
|
||||
.base.maxver = 0,
|
||||
.ctor = nv50_disp_curs_new,
|
||||
.func = &nv50_disp_pioc_func,
|
||||
.chid = 7,
|
||||
.chid = { 7, 7 },
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
int
|
||||
nv50_disp_curs_new(const struct nv50_disp_chan_func *func,
|
||||
const struct nv50_disp_chan_mthd *mthd,
|
||||
struct nv50_disp_root *root, int chid,
|
||||
struct nv50_disp_root *root, int ctrl, int user,
|
||||
const struct nvkm_oclass *oclass, void *data, u32 size,
|
||||
struct nvkm_object **pobject)
|
||||
{
|
||||
@@ -54,7 +54,7 @@ nv50_disp_curs_new(const struct nv50_disp_chan_func *func,
|
||||
} else
|
||||
return ret;
|
||||
|
||||
return nv50_disp_chan_new_(func, mthd, root, chid + head,
|
||||
return nv50_disp_chan_new_(func, mthd, root, ctrl + head, user + head,
|
||||
head, oclass, pobject);
|
||||
}
|
||||
|
||||
@@ -65,5 +65,5 @@ nv50_disp_curs_oclass = {
|
||||
.base.maxver = 0,
|
||||
.ctor = nv50_disp_curs_new,
|
||||
.func = &nv50_disp_pioc_func,
|
||||
.chid = 7,
|
||||
.chid = { 7, 7 },
|
||||
};
|
||||
|
||||
@@ -32,8 +32,8 @@ gf119_disp_dmac_bind(struct nv50_disp_dmac *chan,
|
||||
struct nvkm_object *object, u32 handle)
|
||||
{
|
||||
return nvkm_ramht_insert(chan->base.root->ramht, object,
|
||||
chan->base.chid, -9, handle,
|
||||
chan->base.chid << 27 | 0x00000001);
|
||||
chan->base.chid.user, -9, handle,
|
||||
chan->base.chid.user << 27 | 0x00000001);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -42,22 +42,23 @@ gf119_disp_dmac_fini(struct nv50_disp_dmac *chan)
|
||||
struct nv50_disp *disp = chan->base.root->disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
int chid = chan->base.chid;
|
||||
int ctrl = chan->base.chid.ctrl;
|
||||
int user = chan->base.chid.user;
|
||||
|
||||
/* deactivate channel */
|
||||
nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00001010, 0x00001000);
|
||||
nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00000003, 0x00000000);
|
||||
nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00001010, 0x00001000);
|
||||
nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000003, 0x00000000);
|
||||
if (nvkm_msec(device, 2000,
|
||||
if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x001e0000))
|
||||
if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x001e0000))
|
||||
break;
|
||||
) < 0) {
|
||||
nvkm_error(subdev, "ch %d fini: %08x\n", chid,
|
||||
nvkm_rd32(device, 0x610490 + (chid * 0x10)));
|
||||
nvkm_error(subdev, "ch %d fini: %08x\n", user,
|
||||
nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
|
||||
}
|
||||
|
||||
/* disable error reporting and completion notification */
|
||||
nvkm_mask(device, 0x610090, 0x00000001 << chid, 0x00000000);
|
||||
nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000000);
|
||||
nvkm_mask(device, 0x610090, 0x00000001 << user, 0x00000000);
|
||||
nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000000);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -66,26 +67,27 @@ gf119_disp_dmac_init(struct nv50_disp_dmac *chan)
|
||||
struct nv50_disp *disp = chan->base.root->disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
int chid = chan->base.chid;
|
||||
int ctrl = chan->base.chid.ctrl;
|
||||
int user = chan->base.chid.user;
|
||||
|
||||
/* enable error reporting */
|
||||
nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid);
|
||||
nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);
|
||||
|
||||
/* initialise channel for dma command submission */
|
||||
nvkm_wr32(device, 0x610494 + (chid * 0x0010), chan->push);
|
||||
nvkm_wr32(device, 0x610498 + (chid * 0x0010), 0x00010000);
|
||||
nvkm_wr32(device, 0x61049c + (chid * 0x0010), 0x00000001);
|
||||
nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00000010, 0x00000010);
|
||||
nvkm_wr32(device, 0x640000 + (chid * 0x1000), 0x00000000);
|
||||
nvkm_wr32(device, 0x610490 + (chid * 0x0010), 0x00000013);
|
||||
nvkm_wr32(device, 0x610494 + (ctrl * 0x0010), chan->push);
|
||||
nvkm_wr32(device, 0x610498 + (ctrl * 0x0010), 0x00010000);
|
||||
nvkm_wr32(device, 0x61049c + (ctrl * 0x0010), 0x00000001);
|
||||
nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000010, 0x00000010);
|
||||
nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), 0x00000000);
|
||||
nvkm_wr32(device, 0x610490 + (ctrl * 0x0010), 0x00000013);
|
||||
|
||||
/* wait for it to go inactive */
|
||||
if (nvkm_msec(device, 2000,
|
||||
if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x80000000))
|
||||
if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x80000000))
|
||||
break;
|
||||
) < 0) {
|
||||
nvkm_error(subdev, "ch %d init: %08x\n", chid,
|
||||
nvkm_rd32(device, 0x610490 + (chid * 0x10)));
|
||||
nvkm_error(subdev, "ch %d init: %08x\n", user,
|
||||
nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,26 +32,27 @@ gp104_disp_dmac_init(struct nv50_disp_dmac *chan)
|
||||
struct nv50_disp *disp = chan->base.root->disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
int chid = chan->base.chid;
|
||||
int ctrl = chan->base.chid.ctrl;
|
||||
int user = chan->base.chid.user;
|
||||
|
||||
/* enable error reporting */
|
||||
nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid);
|
||||
nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);
|
||||
|
||||
/* initialise channel for dma command submission */
|
||||
nvkm_wr32(device, 0x611494 + (chid * 0x0010), chan->push);
|
||||
nvkm_wr32(device, 0x611498 + (chid * 0x0010), 0x00010000);
|
||||
nvkm_wr32(device, 0x61149c + (chid * 0x0010), 0x00000001);
|
||||
nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00000010, 0x00000010);
|
||||
nvkm_wr32(device, 0x640000 + (chid * 0x1000), 0x00000000);
|
||||
nvkm_wr32(device, 0x610490 + (chid * 0x0010), 0x00000013);
|
||||
nvkm_wr32(device, 0x611494 + (ctrl * 0x0010), chan->push);
|
||||
nvkm_wr32(device, 0x611498 + (ctrl * 0x0010), 0x00010000);
|
||||
nvkm_wr32(device, 0x61149c + (ctrl * 0x0010), 0x00000001);
|
||||
nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000010, 0x00000010);
|
||||
nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), 0x00000000);
|
||||
nvkm_wr32(device, 0x610490 + (ctrl * 0x0010), 0x00000013);
|
||||
|
||||
/* wait for it to go inactive */
|
||||
if (nvkm_msec(device, 2000,
|
||||
if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x80000000))
|
||||
if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x80000000))
|
||||
break;
|
||||
) < 0) {
|
||||
nvkm_error(subdev, "ch %d init: %08x\n", chid,
|
||||
nvkm_rd32(device, 0x610490 + (chid * 0x10)));
|
||||
nvkm_error(subdev, "ch %d init: %08x\n", user,
|
||||
nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *func,
|
||||
chan->func = func;
|
||||
|
||||
ret = nv50_disp_chan_ctor(&nv50_disp_dmac_func_, mthd, root,
|
||||
chid, head, oclass, &chan->base);
|
||||
chid, chid, head, oclass, &chan->base);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -179,9 +179,9 @@ nv50_disp_dmac_bind(struct nv50_disp_dmac *chan,
|
||||
struct nvkm_object *object, u32 handle)
|
||||
{
|
||||
return nvkm_ramht_insert(chan->base.root->ramht, object,
|
||||
chan->base.chid, -10, handle,
|
||||
chan->base.chid << 28 |
|
||||
chan->base.chid);
|
||||
chan->base.chid.user, -10, handle,
|
||||
chan->base.chid.user << 28 |
|
||||
chan->base.chid.user);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -190,21 +190,22 @@ nv50_disp_dmac_fini(struct nv50_disp_dmac *chan)
|
||||
struct nv50_disp *disp = chan->base.root->disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
int chid = chan->base.chid;
|
||||
int ctrl = chan->base.chid.ctrl;
|
||||
int user = chan->base.chid.user;
|
||||
|
||||
/* deactivate channel */
|
||||
nvkm_mask(device, 0x610200 + (chid * 0x0010), 0x00001010, 0x00001000);
|
||||
nvkm_mask(device, 0x610200 + (chid * 0x0010), 0x00000003, 0x00000000);
|
||||
nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00001010, 0x00001000);
|
||||
nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00000003, 0x00000000);
|
||||
if (nvkm_msec(device, 2000,
|
||||
if (!(nvkm_rd32(device, 0x610200 + (chid * 0x10)) & 0x001e0000))
|
||||
if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x001e0000))
|
||||
break;
|
||||
) < 0) {
|
||||
nvkm_error(subdev, "ch %d fini timeout, %08x\n", chid,
|
||||
nvkm_rd32(device, 0x610200 + (chid * 0x10)));
|
||||
nvkm_error(subdev, "ch %d fini timeout, %08x\n", user,
|
||||
nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
|
||||
}
|
||||
|
||||
/* disable error reporting and completion notifications */
|
||||
nvkm_mask(device, 0x610028, 0x00010001 << chid, 0x00000000 << chid);
|
||||
nvkm_mask(device, 0x610028, 0x00010001 << user, 0x00000000 << user);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -213,26 +214,27 @@ nv50_disp_dmac_init(struct nv50_disp_dmac *chan)
|
||||
struct nv50_disp *disp = chan->base.root->disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
int chid = chan->base.chid;
|
||||
int ctrl = chan->base.chid.ctrl;
|
||||
int user = chan->base.chid.user;
|
||||
|
||||
/* enable error reporting */
|
||||
nvkm_mask(device, 0x610028, 0x00010000 << chid, 0x00010000 << chid);
|
||||
nvkm_mask(device, 0x610028, 0x00010000 << user, 0x00010000 << user);
|
||||
|
||||
/* initialise channel for dma command submission */
|
||||
nvkm_wr32(device, 0x610204 + (chid * 0x0010), chan->push);
|
||||
nvkm_wr32(device, 0x610208 + (chid * 0x0010), 0x00010000);
|
||||
nvkm_wr32(device, 0x61020c + (chid * 0x0010), chid);
|
||||
nvkm_mask(device, 0x610200 + (chid * 0x0010), 0x00000010, 0x00000010);
|
||||
nvkm_wr32(device, 0x640000 + (chid * 0x1000), 0x00000000);
|
||||
nvkm_wr32(device, 0x610200 + (chid * 0x0010), 0x00000013);
|
||||
nvkm_wr32(device, 0x610204 + (ctrl * 0x0010), chan->push);
|
||||
nvkm_wr32(device, 0x610208 + (ctrl * 0x0010), 0x00010000);
|
||||
nvkm_wr32(device, 0x61020c + (ctrl * 0x0010), ctrl);
|
||||
nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00000010, 0x00000010);
|
||||
nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), 0x00000000);
|
||||
nvkm_wr32(device, 0x610200 + (ctrl * 0x0010), 0x00000013);
|
||||
|
||||
/* wait for it to go inactive */
|
||||
if (nvkm_msec(device, 2000,
|
||||
if (!(nvkm_rd32(device, 0x610200 + (chid * 0x10)) & 0x80000000))
|
||||
if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x80000000))
|
||||
break;
|
||||
) < 0) {
|
||||
nvkm_error(subdev, "ch %d init timeout, %08x\n", chid,
|
||||
nvkm_rd32(device, 0x610200 + (chid * 0x10)));
|
||||
nvkm_error(subdev, "ch %d init timeout, %08x\n", user,
|
||||
nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,5 +33,5 @@ g84_disp_oimm_oclass = {
|
||||
.base.maxver = 0,
|
||||
.ctor = nv50_disp_oimm_new,
|
||||
.func = &nv50_disp_pioc_func,
|
||||
.chid = 5,
|
||||
.chid = { 5, 5 },
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user