mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
Merge be562a7f7f ("io_uring/kbuf: reject zero sized provided buffers") into android14-6.1-lts
Steps on the way to 6.1.135 Change-Id: Ib8e66ed7eba04bd7590bca067060f5b688b5e034 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -75,6 +75,7 @@
|
||||
#define ARM_CPU_PART_CORTEX_A76 0xD0B
|
||||
#define ARM_CPU_PART_NEOVERSE_N1 0xD0C
|
||||
#define ARM_CPU_PART_CORTEX_A77 0xD0D
|
||||
#define ARM_CPU_PART_CORTEX_A76AE 0xD0E
|
||||
#define ARM_CPU_PART_NEOVERSE_V1 0xD40
|
||||
#define ARM_CPU_PART_CORTEX_A78 0xD41
|
||||
#define ARM_CPU_PART_CORTEX_A78AE 0xD42
|
||||
@@ -152,6 +153,7 @@
|
||||
#define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
|
||||
#define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
|
||||
#define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
|
||||
#define MIDR_CORTEX_A76AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76AE)
|
||||
#define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1)
|
||||
#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
|
||||
#define MIDR_CORTEX_A78AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE)
|
||||
|
||||
@@ -96,7 +96,6 @@ enum mitigation_state arm64_get_meltdown_state(void);
|
||||
|
||||
enum mitigation_state arm64_get_spectre_bhb_state(void);
|
||||
bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
|
||||
u8 spectre_bhb_loop_affected(int scope);
|
||||
void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ASM_SPECTRE_H */
|
||||
|
||||
@@ -857,52 +857,73 @@ static unsigned long system_bhb_mitigations;
|
||||
* This must be called with SCOPE_LOCAL_CPU for each type of CPU, before any
|
||||
* SCOPE_SYSTEM call will give the right answer.
|
||||
*/
|
||||
u8 spectre_bhb_loop_affected(int scope)
|
||||
static bool is_spectre_bhb_safe(int scope)
|
||||
{
|
||||
static const struct midr_range spectre_bhb_safe_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A35),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A53),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A55),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A510),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A520),
|
||||
MIDR_ALL_VERSIONS(MIDR_BRAHMA_B53),
|
||||
MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_2XX_SILVER),
|
||||
MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER),
|
||||
MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_SILVER),
|
||||
{},
|
||||
};
|
||||
static bool all_safe = true;
|
||||
|
||||
if (scope != SCOPE_LOCAL_CPU)
|
||||
return all_safe;
|
||||
|
||||
if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_safe_list))
|
||||
return true;
|
||||
|
||||
all_safe = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static u8 spectre_bhb_loop_affected(void)
|
||||
{
|
||||
u8 k = 0;
|
||||
static u8 max_bhb_k;
|
||||
|
||||
if (scope == SCOPE_LOCAL_CPU) {
|
||||
static const struct midr_range spectre_bhb_k32_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
|
||||
{},
|
||||
};
|
||||
static const struct midr_range spectre_bhb_k24_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
|
||||
{},
|
||||
};
|
||||
static const struct midr_range spectre_bhb_k11_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_AMPERE1),
|
||||
{},
|
||||
};
|
||||
static const struct midr_range spectre_bhb_k8_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
|
||||
{},
|
||||
};
|
||||
static const struct midr_range spectre_bhb_k32_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
|
||||
{},
|
||||
};
|
||||
static const struct midr_range spectre_bhb_k24_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
|
||||
MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_GOLD),
|
||||
{},
|
||||
};
|
||||
static const struct midr_range spectre_bhb_k11_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_AMPERE1),
|
||||
{},
|
||||
};
|
||||
static const struct midr_range spectre_bhb_k8_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
|
||||
{},
|
||||
};
|
||||
|
||||
if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
|
||||
k = 32;
|
||||
else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
|
||||
k = 24;
|
||||
else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
|
||||
k = 11;
|
||||
else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
|
||||
k = 8;
|
||||
|
||||
max_bhb_k = max(max_bhb_k, k);
|
||||
} else {
|
||||
k = max_bhb_k;
|
||||
}
|
||||
if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
|
||||
k = 32;
|
||||
else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
|
||||
k = 24;
|
||||
else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
|
||||
k = 11;
|
||||
else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
|
||||
k = 8;
|
||||
|
||||
return k;
|
||||
}
|
||||
@@ -928,29 +949,13 @@ static enum mitigation_state spectre_bhb_get_cpu_fw_mitigation_state(void)
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_spectre_bhb_fw_affected(int scope)
|
||||
static bool has_spectre_bhb_fw_mitigation(void)
|
||||
{
|
||||
static bool system_affected;
|
||||
enum mitigation_state fw_state;
|
||||
bool has_smccc = arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_NONE;
|
||||
static const struct midr_range spectre_bhb_firmware_mitigated_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
|
||||
{},
|
||||
};
|
||||
bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(),
|
||||
spectre_bhb_firmware_mitigated_list);
|
||||
|
||||
if (scope != SCOPE_LOCAL_CPU)
|
||||
return system_affected;
|
||||
|
||||
fw_state = spectre_bhb_get_cpu_fw_mitigation_state();
|
||||
if (cpu_in_list || (has_smccc && fw_state == SPECTRE_MITIGATED)) {
|
||||
system_affected = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return has_smccc && fw_state == SPECTRE_MITIGATED;
|
||||
}
|
||||
|
||||
static bool supports_ecbhb(int scope)
|
||||
@@ -966,6 +971,8 @@ static bool supports_ecbhb(int scope)
|
||||
ID_AA64MMFR1_EL1_ECBHB_SHIFT);
|
||||
}
|
||||
|
||||
static u8 max_bhb_k;
|
||||
|
||||
bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry,
|
||||
int scope)
|
||||
{
|
||||
@@ -974,16 +981,18 @@ bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry,
|
||||
if (supports_csv2p3(scope))
|
||||
return false;
|
||||
|
||||
if (supports_clearbhb(scope))
|
||||
return true;
|
||||
if (is_spectre_bhb_safe(scope))
|
||||
return false;
|
||||
|
||||
if (spectre_bhb_loop_affected(scope))
|
||||
return true;
|
||||
/*
|
||||
* At this point the core isn't known to be "safe" so we're going to
|
||||
* assume it's vulnerable. We still need to update `max_bhb_k` though,
|
||||
* but only if we aren't mitigating with clearbhb though.
|
||||
*/
|
||||
if (scope == SCOPE_LOCAL_CPU && !supports_clearbhb(SCOPE_LOCAL_CPU))
|
||||
max_bhb_k = max(max_bhb_k, spectre_bhb_loop_affected());
|
||||
|
||||
if (is_spectre_bhb_fw_affected(scope))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot)
|
||||
@@ -1017,7 +1026,7 @@ early_param("nospectre_bhb", parse_spectre_bhb_param);
|
||||
void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
|
||||
{
|
||||
bp_hardening_cb_t cpu_cb;
|
||||
enum mitigation_state fw_state, state = SPECTRE_VULNERABLE;
|
||||
enum mitigation_state state = SPECTRE_VULNERABLE;
|
||||
struct bp_hardening_data *data = this_cpu_ptr(&bp_hardening_data);
|
||||
|
||||
if (!is_spectre_bhb_affected(entry, SCOPE_LOCAL_CPU))
|
||||
@@ -1043,7 +1052,7 @@ void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
|
||||
this_cpu_set_vectors(EL1_VECTOR_BHB_CLEAR_INSN);
|
||||
state = SPECTRE_MITIGATED;
|
||||
set_bit(BHB_INSN, &system_bhb_mitigations);
|
||||
} else if (spectre_bhb_loop_affected(SCOPE_LOCAL_CPU)) {
|
||||
} else if (spectre_bhb_loop_affected()) {
|
||||
/*
|
||||
* Ensure KVM uses the indirect vector which will have the
|
||||
* branchy-loop added. A57/A72-r0 will already have selected
|
||||
@@ -1056,32 +1065,29 @@ void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
|
||||
this_cpu_set_vectors(EL1_VECTOR_BHB_LOOP);
|
||||
state = SPECTRE_MITIGATED;
|
||||
set_bit(BHB_LOOP, &system_bhb_mitigations);
|
||||
} else if (is_spectre_bhb_fw_affected(SCOPE_LOCAL_CPU)) {
|
||||
fw_state = spectre_bhb_get_cpu_fw_mitigation_state();
|
||||
if (fw_state == SPECTRE_MITIGATED) {
|
||||
/*
|
||||
* Ensure KVM uses one of the spectre bp_hardening
|
||||
* vectors. The indirect vector doesn't include the EL3
|
||||
* call, so needs upgrading to
|
||||
* HYP_VECTOR_SPECTRE_INDIRECT.
|
||||
*/
|
||||
if (!data->slot || data->slot == HYP_VECTOR_INDIRECT)
|
||||
data->slot += 1;
|
||||
} else if (has_spectre_bhb_fw_mitigation()) {
|
||||
/*
|
||||
* Ensure KVM uses one of the spectre bp_hardening
|
||||
* vectors. The indirect vector doesn't include the EL3
|
||||
* call, so needs upgrading to
|
||||
* HYP_VECTOR_SPECTRE_INDIRECT.
|
||||
*/
|
||||
if (!data->slot || data->slot == HYP_VECTOR_INDIRECT)
|
||||
data->slot += 1;
|
||||
|
||||
this_cpu_set_vectors(EL1_VECTOR_BHB_FW);
|
||||
this_cpu_set_vectors(EL1_VECTOR_BHB_FW);
|
||||
|
||||
/*
|
||||
* The WA3 call in the vectors supersedes the WA1 call
|
||||
* made during context-switch. Uninstall any firmware
|
||||
* bp_hardening callback.
|
||||
*/
|
||||
cpu_cb = spectre_v2_get_sw_mitigation_cb();
|
||||
if (__this_cpu_read(bp_hardening_data.fn) != cpu_cb)
|
||||
__this_cpu_write(bp_hardening_data.fn, NULL);
|
||||
/*
|
||||
* The WA3 call in the vectors supersedes the WA1 call
|
||||
* made during context-switch. Uninstall any firmware
|
||||
* bp_hardening callback.
|
||||
*/
|
||||
cpu_cb = spectre_v2_get_sw_mitigation_cb();
|
||||
if (__this_cpu_read(bp_hardening_data.fn) != cpu_cb)
|
||||
__this_cpu_write(bp_hardening_data.fn, NULL);
|
||||
|
||||
state = SPECTRE_MITIGATED;
|
||||
set_bit(BHB_FW, &system_bhb_mitigations);
|
||||
}
|
||||
state = SPECTRE_MITIGATED;
|
||||
set_bit(BHB_FW, &system_bhb_mitigations);
|
||||
}
|
||||
|
||||
update_mitigation_state(&spectre_bhb_state, state);
|
||||
@@ -1115,7 +1121,6 @@ void noinstr spectre_bhb_patch_loop_iter(struct alt_instr *alt,
|
||||
{
|
||||
u8 rd;
|
||||
u32 insn;
|
||||
u16 loop_count = spectre_bhb_loop_affected(SCOPE_SYSTEM);
|
||||
|
||||
BUG_ON(nr_inst != 1); /* MOV -> MOV */
|
||||
|
||||
@@ -1124,7 +1129,7 @@ void noinstr spectre_bhb_patch_loop_iter(struct alt_instr *alt,
|
||||
|
||||
insn = le32_to_cpu(*origptr);
|
||||
rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn);
|
||||
insn = aarch64_insn_gen_movewide(rd, loop_count, 0,
|
||||
insn = aarch64_insn_gen_movewide(rd, max_bhb_k, 0,
|
||||
AARCH64_INSN_VARIANT_64BIT,
|
||||
AARCH64_INSN_MOVEWIDE_ZERO);
|
||||
*updptr++ = cpu_to_le32(insn);
|
||||
|
||||
@@ -470,7 +470,11 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return kvm_share_hyp(vcpu, vcpu + 1);
|
||||
err = kvm_share_hyp(vcpu, vcpu + 1);
|
||||
if (err)
|
||||
kvm_vgic_vcpu_destroy(vcpu);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
|
||||
|
||||
@@ -684,6 +684,13 @@ int devres_release_group(struct device *dev, void *id)
|
||||
spin_unlock_irqrestore(&dev->devres_lock, flags);
|
||||
|
||||
release_nodes(dev, &todo);
|
||||
} else if (list_empty(&dev->devres_head)) {
|
||||
/*
|
||||
* dev is probably dying via devres_release_all(): groups
|
||||
* have already been removed and are on the process of
|
||||
* being released - don't touch and don't warn.
|
||||
*/
|
||||
spin_unlock_irqrestore(&dev->devres_lock, flags);
|
||||
} else {
|
||||
WARN_ON(1);
|
||||
spin_unlock_irqrestore(&dev->devres_lock, flags);
|
||||
|
||||
@@ -104,11 +104,10 @@ again:
|
||||
return 0;
|
||||
/* process status changes without irq support */
|
||||
do {
|
||||
usleep_range(priv->timeout_min, priv->timeout_max);
|
||||
status = chip->ops->status(chip);
|
||||
if ((status & mask) == mask)
|
||||
return 0;
|
||||
usleep_range(priv->timeout_min,
|
||||
priv->timeout_max);
|
||||
} while (time_before(jiffies, stop));
|
||||
return -ETIME;
|
||||
}
|
||||
@@ -433,7 +432,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
|
||||
|
||||
if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
|
||||
&priv->int_queue, false) < 0) {
|
||||
rc = -ETIME;
|
||||
if (test_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags))
|
||||
rc = -EAGAIN;
|
||||
else
|
||||
rc = -ETIME;
|
||||
goto out_err;
|
||||
}
|
||||
status = tpm_tis_status(chip);
|
||||
@@ -450,7 +452,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
|
||||
|
||||
if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
|
||||
&priv->int_queue, false) < 0) {
|
||||
rc = -ETIME;
|
||||
if (test_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags))
|
||||
rc = -EAGAIN;
|
||||
else
|
||||
rc = -ETIME;
|
||||
goto out_err;
|
||||
}
|
||||
status = tpm_tis_status(chip);
|
||||
@@ -505,9 +510,11 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
|
||||
if (rc >= 0)
|
||||
/* Data transfer done successfully */
|
||||
break;
|
||||
else if (rc != -EIO)
|
||||
else if (rc != -EAGAIN && rc != -EIO)
|
||||
/* Data transfer failed, not recoverable */
|
||||
return rc;
|
||||
|
||||
usleep_range(priv->timeout_min, priv->timeout_max);
|
||||
}
|
||||
|
||||
rc = tpm_tis_verify_crc(priv, len, buf);
|
||||
@@ -1044,6 +1051,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
|
||||
priv->timeout_max = TIS_TIMEOUT_MAX_ATML;
|
||||
}
|
||||
|
||||
if (priv->manufacturer_id == TPM_VID_IFX)
|
||||
set_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags);
|
||||
|
||||
if (is_bsw()) {
|
||||
priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR,
|
||||
ILB_REMAP_SIZE);
|
||||
|
||||
@@ -88,6 +88,7 @@ enum tpm_tis_flags {
|
||||
TPM_TIS_INVALID_STATUS = 1,
|
||||
TPM_TIS_DEFAULT_CANCELLATION = 2,
|
||||
TPM_TIS_IRQ_TESTED = 3,
|
||||
TPM_TIS_STATUS_VALID_RETRY = 4,
|
||||
};
|
||||
|
||||
struct tpm_tis_data {
|
||||
|
||||
@@ -168,9 +168,7 @@ static int stm32_clkevent_lp_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
if (of_property_read_bool(pdev->dev.parent->of_node, "wakeup-source")) {
|
||||
ret = device_init_wakeup(&pdev->dev, true);
|
||||
if (ret)
|
||||
goto out_clk_disable;
|
||||
device_set_wakeup_capable(&pdev->dev, true);
|
||||
|
||||
ret = dev_pm_set_wake_irq(&pdev->dev, irq);
|
||||
if (ret)
|
||||
|
||||
@@ -6186,6 +6186,7 @@ struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev,
|
||||
{
|
||||
struct dma_fence *old = NULL;
|
||||
|
||||
dma_fence_get(gang);
|
||||
do {
|
||||
dma_fence_put(old);
|
||||
rcu_read_lock();
|
||||
@@ -6195,12 +6196,19 @@ struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev,
|
||||
if (old == gang)
|
||||
break;
|
||||
|
||||
if (!dma_fence_is_signaled(old))
|
||||
if (!dma_fence_is_signaled(old)) {
|
||||
dma_fence_put(gang);
|
||||
return old;
|
||||
}
|
||||
|
||||
} while (cmpxchg((struct dma_fence __force **)&adev->gang_submit,
|
||||
old, gang) != old);
|
||||
|
||||
/*
|
||||
* Drop it once for the exchanged reference in adev and once for the
|
||||
* thread local reference acquired in amdgpu_device_get_gang().
|
||||
*/
|
||||
dma_fence_put(old);
|
||||
dma_fence_put(old);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -208,6 +208,11 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (args->ring_size < KFD_MIN_QUEUE_RING_SIZE) {
|
||||
args->ring_size = KFD_MIN_QUEUE_RING_SIZE;
|
||||
pr_debug("Size lower. clamped to KFD_MIN_QUEUE_RING_SIZE");
|
||||
}
|
||||
|
||||
if (!access_ok((const void __user *) args->read_pointer_address,
|
||||
sizeof(uint32_t))) {
|
||||
pr_err("Can't access read pointer\n");
|
||||
@@ -464,6 +469,11 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (args->ring_size < KFD_MIN_QUEUE_RING_SIZE) {
|
||||
args->ring_size = KFD_MIN_QUEUE_RING_SIZE;
|
||||
pr_debug("Size lower. clamped to KFD_MIN_QUEUE_RING_SIZE");
|
||||
}
|
||||
|
||||
properties.queue_address = args->ring_base_address;
|
||||
properties.queue_size = args->ring_size;
|
||||
properties.queue_percent = args->queue_percentage;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include "amdgpu_amdkfd.h"
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_reset.h"
|
||||
|
||||
struct mm_struct;
|
||||
|
||||
@@ -1114,6 +1115,17 @@ static void kfd_process_remove_sysfs(struct kfd_process *p)
|
||||
p->kobj = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* If any GPU is ongoing reset, wait for reset complete.
|
||||
*/
|
||||
static void kfd_process_wait_gpu_reset_complete(struct kfd_process *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < p->n_pdds; i++)
|
||||
flush_workqueue(p->pdds[i]->dev->adev->reset_domain->wq);
|
||||
}
|
||||
|
||||
/* No process locking is needed in this function, because the process
|
||||
* is not findable any more. We must assume that no other thread is
|
||||
* using it any more, otherwise we couldn't safely free the process
|
||||
@@ -1127,6 +1139,11 @@ static void kfd_process_wq_release(struct work_struct *work)
|
||||
kfd_process_dequeue_from_all_devices(p);
|
||||
pqm_uninit(&p->pqm);
|
||||
|
||||
/*
|
||||
* If GPU in reset, user queues may still running, wait for reset complete.
|
||||
*/
|
||||
kfd_process_wait_gpu_reset_complete(p);
|
||||
|
||||
/* Signal the eviction fence after user mode queues are
|
||||
* destroyed. This allows any BOs to be freed without
|
||||
* triggering pointless evictions or waiting for fences.
|
||||
|
||||
@@ -429,7 +429,7 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
|
||||
pr_err("Pasid 0x%x destroy queue %d failed, ret %d\n",
|
||||
pqm->process->pasid,
|
||||
pqn->q->properties.queue_id, retval);
|
||||
if (retval != -ETIME)
|
||||
if (retval != -ETIME && retval != -EIO)
|
||||
goto err_destroy_queue;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,11 @@ static int amd_powerplay_create(struct amdgpu_device *adev)
|
||||
hwmgr->adev = adev;
|
||||
hwmgr->not_vf = !amdgpu_sriov_vf(adev);
|
||||
hwmgr->device = amdgpu_cgs_create_device(adev);
|
||||
if (!hwmgr->device) {
|
||||
kfree(hwmgr);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mutex_init(&hwmgr->msg_lock);
|
||||
hwmgr->chip_family = adev->family;
|
||||
hwmgr->chip_id = adev->asic_type;
|
||||
|
||||
@@ -49,7 +49,7 @@ static LIST_HEAD(panel_list);
|
||||
* @dev: parent device of the panel
|
||||
* @funcs: panel operations
|
||||
* @connector_type: the connector type (DRM_MODE_CONNECTOR_*) corresponding to
|
||||
* the panel interface
|
||||
* the panel interface (must NOT be DRM_MODE_CONNECTOR_Unknown)
|
||||
*
|
||||
* Initialize the panel structure for subsequent registration with
|
||||
* drm_panel_add().
|
||||
@@ -57,6 +57,9 @@ static LIST_HEAD(panel_list);
|
||||
void drm_panel_init(struct drm_panel *panel, struct device *dev,
|
||||
const struct drm_panel_funcs *funcs, int connector_type)
|
||||
{
|
||||
if (connector_type == DRM_MODE_CONNECTOR_Unknown)
|
||||
DRM_WARN("%s: %s: a valid connector type is required!\n", __func__, dev_name(dev));
|
||||
|
||||
INIT_LIST_HEAD(&panel->list);
|
||||
panel->dev = dev;
|
||||
panel->funcs = funcs;
|
||||
|
||||
@@ -93,6 +93,12 @@ static const struct drm_dmi_panel_orientation_data onegx1_pro = {
|
||||
.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
|
||||
};
|
||||
|
||||
static const struct drm_dmi_panel_orientation_data lcd640x960_leftside_up = {
|
||||
.width = 640,
|
||||
.height = 960,
|
||||
.orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
|
||||
};
|
||||
|
||||
static const struct drm_dmi_panel_orientation_data lcd720x1280_rightside_up = {
|
||||
.width = 720,
|
||||
.height = 1280,
|
||||
@@ -123,6 +129,12 @@ static const struct drm_dmi_panel_orientation_data lcd1080x1920_rightside_up = {
|
||||
.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
|
||||
};
|
||||
|
||||
static const struct drm_dmi_panel_orientation_data lcd1200x1920_leftside_up = {
|
||||
.width = 1200,
|
||||
.height = 1920,
|
||||
.orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
|
||||
};
|
||||
|
||||
static const struct drm_dmi_panel_orientation_data lcd1200x1920_rightside_up = {
|
||||
.width = 1200,
|
||||
.height = 1920,
|
||||
@@ -184,10 +196,10 @@ static const struct dmi_system_id orientation_data[] = {
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T103HAF"),
|
||||
},
|
||||
.driver_data = (void *)&lcd800x1280_rightside_up,
|
||||
}, { /* AYA NEO AYANEO 2 */
|
||||
}, { /* AYA NEO AYANEO 2/2S */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYANEO 2"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "AYANEO 2"),
|
||||
},
|
||||
.driver_data = (void *)&lcd1200x1920_rightside_up,
|
||||
}, { /* AYA NEO 2021 */
|
||||
@@ -202,6 +214,18 @@ static const struct dmi_system_id orientation_data[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "AIR"),
|
||||
},
|
||||
.driver_data = (void *)&lcd1080x1920_leftside_up,
|
||||
}, { /* AYA NEO Flip DS Bottom Screen */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "FLIP DS"),
|
||||
},
|
||||
.driver_data = (void *)&lcd640x960_leftside_up,
|
||||
}, { /* AYA NEO Flip KB/DS Top Screen */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "FLIP"),
|
||||
},
|
||||
.driver_data = (void *)&lcd1080x1920_leftside_up,
|
||||
}, { /* AYA NEO Founder */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYA NEO"),
|
||||
@@ -226,6 +250,12 @@ static const struct dmi_system_id orientation_data[] = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "KUN"),
|
||||
},
|
||||
.driver_data = (void *)&lcd1600x2560_rightside_up,
|
||||
}, { /* AYA NEO SLIDE */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "SLIDE"),
|
||||
},
|
||||
.driver_data = (void *)&lcd1080x1920_leftside_up,
|
||||
}, { /* AYN Loki Max */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ayn"),
|
||||
@@ -315,6 +345,12 @@ static const struct dmi_system_id orientation_data[] = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
|
||||
},
|
||||
.driver_data = (void *)&gpd_win2,
|
||||
}, { /* GPD Win 2 (correct DMI strings) */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "WIN2")
|
||||
},
|
||||
.driver_data = (void *)&lcd720x1280_rightside_up,
|
||||
}, { /* GPD Win 3 */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"),
|
||||
@@ -443,6 +479,12 @@ static const struct dmi_system_id orientation_data[] = {
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ONE XPLAYER"),
|
||||
},
|
||||
.driver_data = (void *)&lcd1600x2560_leftside_up,
|
||||
}, { /* OneXPlayer Mini (Intel) */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ONE-NETBOOK TECHNOLOGY CO., LTD."),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ONE XPLAYER"),
|
||||
},
|
||||
.driver_data = (void *)&lcd1200x1920_leftside_up,
|
||||
}, { /* OrangePi Neo */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "OrangePi"),
|
||||
|
||||
@@ -125,14 +125,14 @@ struct mtk_dpi_yc_limit {
|
||||
* @is_ck_de_pol: Support CK/DE polarity.
|
||||
* @swap_input_support: Support input swap function.
|
||||
* @support_direct_pin: IP supports direct connection to dpi panels.
|
||||
* @input_2pixel: Input pixel of dp_intf is 2 pixel per round, so enable this
|
||||
* config to enable this feature.
|
||||
* @dimension_mask: Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
|
||||
* (no shift).
|
||||
* @hvsize_mask: Mask of HSIZE and VSIZE mask (no shift).
|
||||
* @channel_swap_shift: Shift value of channel swap.
|
||||
* @yuv422_en_bit: Enable bit of yuv422.
|
||||
* @csc_enable_bit: Enable bit of CSC.
|
||||
* @input_2p_en_bit: Enable bit for input two pixel per round feature.
|
||||
* If present, implies that the feature must be enabled.
|
||||
* @pixels_per_iter: Quantity of transferred pixels per iteration.
|
||||
*/
|
||||
struct mtk_dpi_conf {
|
||||
@@ -145,12 +145,12 @@ struct mtk_dpi_conf {
|
||||
bool is_ck_de_pol;
|
||||
bool swap_input_support;
|
||||
bool support_direct_pin;
|
||||
bool input_2pixel;
|
||||
u32 dimension_mask;
|
||||
u32 hvsize_mask;
|
||||
u32 channel_swap_shift;
|
||||
u32 yuv422_en_bit;
|
||||
u32 csc_enable_bit;
|
||||
u32 input_2p_en_bit;
|
||||
u32 pixels_per_iter;
|
||||
};
|
||||
|
||||
@@ -463,6 +463,7 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
|
||||
|
||||
mtk_dpi_disable(dpi);
|
||||
clk_disable_unprepare(dpi->pixel_clk);
|
||||
clk_disable_unprepare(dpi->tvd_clk);
|
||||
clk_disable_unprepare(dpi->engine_clk);
|
||||
}
|
||||
|
||||
@@ -479,6 +480,12 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
|
||||
goto err_refcount;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dpi->tvd_clk);
|
||||
if (ret) {
|
||||
dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
|
||||
goto err_engine;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dpi->pixel_clk);
|
||||
if (ret) {
|
||||
dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
|
||||
@@ -488,6 +495,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
|
||||
return 0;
|
||||
|
||||
err_pixel:
|
||||
clk_disable_unprepare(dpi->tvd_clk);
|
||||
err_engine:
|
||||
clk_disable_unprepare(dpi->engine_clk);
|
||||
err_refcount:
|
||||
dpi->refcount--;
|
||||
@@ -602,9 +611,9 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
|
||||
mtk_dpi_dual_edge(dpi);
|
||||
mtk_dpi_config_disable_edge(dpi);
|
||||
}
|
||||
if (dpi->conf->input_2pixel) {
|
||||
mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
|
||||
DPINTF_INPUT_2P_EN);
|
||||
if (dpi->conf->input_2p_en_bit) {
|
||||
mtk_dpi_mask(dpi, DPI_CON, dpi->conf->input_2p_en_bit,
|
||||
dpi->conf->input_2p_en_bit);
|
||||
}
|
||||
mtk_dpi_sw_reset(dpi, false);
|
||||
|
||||
@@ -952,12 +961,12 @@ static const struct mtk_dpi_conf mt8195_dpintf_conf = {
|
||||
.output_fmts = mt8195_output_fmts,
|
||||
.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
|
||||
.pixels_per_iter = 4,
|
||||
.input_2pixel = true,
|
||||
.dimension_mask = DPINTF_HPW_MASK,
|
||||
.hvsize_mask = DPINTF_HSIZE_MASK,
|
||||
.channel_swap_shift = DPINTF_CH_SWAP,
|
||||
.yuv422_en_bit = DPINTF_YUV422_EN,
|
||||
.csc_enable_bit = DPINTF_CSC_ENABLE,
|
||||
.input_2p_en_bit = DPINTF_INPUT_2P_EN,
|
||||
};
|
||||
|
||||
static int mtk_dpi_probe(struct platform_device *pdev)
|
||||
|
||||
@@ -1243,6 +1243,8 @@ static int __init smsdvb_module_init(void)
|
||||
smsdvb_debugfs_register();
|
||||
|
||||
rc = smscore_register_hotplug(smsdvb_hotplug);
|
||||
if (rc)
|
||||
smsdvb_debugfs_unregister();
|
||||
|
||||
pr_debug("\n");
|
||||
|
||||
|
||||
@@ -322,7 +322,7 @@ struct adv748x_state {
|
||||
|
||||
/* Free run pattern select */
|
||||
#define ADV748X_SDP_FRP 0x14
|
||||
#define ADV748X_SDP_FRP_MASK GENMASK(3, 1)
|
||||
#define ADV748X_SDP_FRP_MASK GENMASK(2, 0)
|
||||
|
||||
/* Saturation */
|
||||
#define ADV748X_SDP_SD_SAT_U 0xe3 /* user_map_rw_reg_e3 */
|
||||
|
||||
@@ -3642,6 +3642,7 @@ static int ccs_probe(struct i2c_client *client)
|
||||
out_disable_runtime_pm:
|
||||
pm_runtime_put_noidle(&client->dev);
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
|
||||
out_media_entity_cleanup:
|
||||
media_entity_cleanup(&sensor->src->sd.entity);
|
||||
@@ -3674,9 +3675,10 @@ static void ccs_remove(struct i2c_client *client)
|
||||
v4l2_async_unregister_subdev(subdev);
|
||||
|
||||
pm_runtime_disable(&client->dev);
|
||||
if (!pm_runtime_status_suspended(&client->dev))
|
||||
if (!pm_runtime_status_suspended(&client->dev)) {
|
||||
ccs_power_off(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
}
|
||||
|
||||
for (i = 0; i < sensor->ssds_used; i++) {
|
||||
v4l2_device_unregister_subdev(&sensor->ssds[i].sd);
|
||||
|
||||
@@ -922,6 +922,8 @@ static int ov7251_set_power_on(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
usleep_range(1000, 1100);
|
||||
|
||||
gpiod_set_value_cansleep(ov7251->enable_gpio, 1);
|
||||
|
||||
/* wait at least 65536 external clock cycles */
|
||||
@@ -1675,7 +1677,7 @@ static int ov7251_probe(struct i2c_client *client)
|
||||
return PTR_ERR(ov7251->analog_regulator);
|
||||
}
|
||||
|
||||
ov7251->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
|
||||
ov7251->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(ov7251->enable_gpio)) {
|
||||
dev_err(dev, "cannot get enable gpio\n");
|
||||
return PTR_ERR(ov7251->enable_gpio);
|
||||
|
||||
@@ -19,6 +19,8 @@ static void init_codecs(struct venus_core *core)
|
||||
struct hfi_plat_caps *caps = core->caps, *cap;
|
||||
unsigned long bit;
|
||||
|
||||
core->codecs_count = 0;
|
||||
|
||||
if (hweight_long(core->dec_codecs) + hweight_long(core->enc_codecs) > MAX_CODEC_NUM)
|
||||
return;
|
||||
|
||||
@@ -62,7 +64,7 @@ fill_buf_mode(struct hfi_plat_caps *cap, const void *data, unsigned int num)
|
||||
cap->cap_bufs_mode_dynamic = true;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data)
|
||||
{
|
||||
struct hfi_buffer_alloc_mode_supported *mode = data;
|
||||
@@ -70,7 +72,7 @@ parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data)
|
||||
u32 *type;
|
||||
|
||||
if (num_entries > MAX_ALLOC_MODE_ENTRIES)
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
type = mode->data;
|
||||
|
||||
@@ -82,6 +84,8 @@ parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data)
|
||||
|
||||
type++;
|
||||
}
|
||||
|
||||
return sizeof(*mode);
|
||||
}
|
||||
|
||||
static void fill_profile_level(struct hfi_plat_caps *cap, const void *data,
|
||||
@@ -96,7 +100,7 @@ static void fill_profile_level(struct hfi_plat_caps *cap, const void *data,
|
||||
cap->num_pl += num;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
parse_profile_level(struct venus_core *core, u32 codecs, u32 domain, void *data)
|
||||
{
|
||||
struct hfi_profile_level_supported *pl = data;
|
||||
@@ -104,12 +108,14 @@ parse_profile_level(struct venus_core *core, u32 codecs, u32 domain, void *data)
|
||||
struct hfi_profile_level pl_arr[HFI_MAX_PROFILE_COUNT] = {};
|
||||
|
||||
if (pl->profile_count > HFI_MAX_PROFILE_COUNT)
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(pl_arr, proflevel, pl->profile_count * sizeof(*proflevel));
|
||||
|
||||
for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain,
|
||||
fill_profile_level, pl_arr, pl->profile_count);
|
||||
|
||||
return pl->profile_count * sizeof(*proflevel) + sizeof(u32);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -124,7 +130,7 @@ fill_caps(struct hfi_plat_caps *cap, const void *data, unsigned int num)
|
||||
cap->num_caps += num;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
parse_caps(struct venus_core *core, u32 codecs, u32 domain, void *data)
|
||||
{
|
||||
struct hfi_capabilities *caps = data;
|
||||
@@ -133,12 +139,14 @@ parse_caps(struct venus_core *core, u32 codecs, u32 domain, void *data)
|
||||
struct hfi_capability caps_arr[MAX_CAP_ENTRIES] = {};
|
||||
|
||||
if (num_caps > MAX_CAP_ENTRIES)
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(caps_arr, cap, num_caps * sizeof(*cap));
|
||||
|
||||
for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain,
|
||||
fill_caps, caps_arr, num_caps);
|
||||
|
||||
return sizeof(*caps);
|
||||
}
|
||||
|
||||
static void fill_raw_fmts(struct hfi_plat_caps *cap, const void *fmts,
|
||||
@@ -153,7 +161,7 @@ static void fill_raw_fmts(struct hfi_plat_caps *cap, const void *fmts,
|
||||
cap->num_fmts += num_fmts;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
|
||||
{
|
||||
struct hfi_uncompressed_format_supported *fmt = data;
|
||||
@@ -162,7 +170,8 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
|
||||
struct raw_formats rawfmts[MAX_FMT_ENTRIES] = {};
|
||||
u32 entries = fmt->format_entries;
|
||||
unsigned int i = 0;
|
||||
u32 num_planes;
|
||||
u32 num_planes = 0;
|
||||
u32 size;
|
||||
|
||||
while (entries) {
|
||||
num_planes = pinfo->num_planes;
|
||||
@@ -172,7 +181,7 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
|
||||
i++;
|
||||
|
||||
if (i >= MAX_FMT_ENTRIES)
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
if (pinfo->num_planes > MAX_PLANES)
|
||||
break;
|
||||
@@ -184,9 +193,13 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
|
||||
|
||||
for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain,
|
||||
fill_raw_fmts, rawfmts, i);
|
||||
size = fmt->format_entries * (sizeof(*constr) * num_planes + 2 * sizeof(u32))
|
||||
+ 2 * sizeof(u32);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static void parse_codecs(struct venus_core *core, void *data)
|
||||
static int parse_codecs(struct venus_core *core, void *data)
|
||||
{
|
||||
struct hfi_codec_supported *codecs = data;
|
||||
|
||||
@@ -198,21 +211,27 @@ static void parse_codecs(struct venus_core *core, void *data)
|
||||
core->dec_codecs &= ~HFI_VIDEO_CODEC_SPARK;
|
||||
core->enc_codecs &= ~HFI_VIDEO_CODEC_HEVC;
|
||||
}
|
||||
|
||||
return sizeof(*codecs);
|
||||
}
|
||||
|
||||
static void parse_max_sessions(struct venus_core *core, const void *data)
|
||||
static int parse_max_sessions(struct venus_core *core, const void *data)
|
||||
{
|
||||
const struct hfi_max_sessions_supported *sessions = data;
|
||||
|
||||
core->max_sessions_supported = sessions->max_sessions;
|
||||
|
||||
return sizeof(*sessions);
|
||||
}
|
||||
|
||||
static void parse_codecs_mask(u32 *codecs, u32 *domain, void *data)
|
||||
static int parse_codecs_mask(u32 *codecs, u32 *domain, void *data)
|
||||
{
|
||||
struct hfi_codec_mask_supported *mask = data;
|
||||
|
||||
*codecs = mask->codecs;
|
||||
*domain = mask->video_domains;
|
||||
|
||||
return sizeof(*mask);
|
||||
}
|
||||
|
||||
static void parser_init(struct venus_inst *inst, u32 *codecs, u32 *domain)
|
||||
@@ -281,8 +300,9 @@ static int hfi_platform_parser(struct venus_core *core, struct venus_inst *inst)
|
||||
u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf,
|
||||
u32 size)
|
||||
{
|
||||
unsigned int words_count = size >> 2;
|
||||
u32 *word = buf, *data, codecs = 0, domain = 0;
|
||||
u32 *words = buf, *payload, codecs = 0, domain = 0;
|
||||
u32 *frame_size = buf + size;
|
||||
u32 rem_bytes = size;
|
||||
int ret;
|
||||
|
||||
ret = hfi_platform_parser(core, inst);
|
||||
@@ -299,38 +319,66 @@ u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf,
|
||||
memset(core->caps, 0, sizeof(core->caps));
|
||||
}
|
||||
|
||||
while (words_count) {
|
||||
data = word + 1;
|
||||
while (words < frame_size) {
|
||||
payload = words + 1;
|
||||
|
||||
switch (*word) {
|
||||
switch (*words) {
|
||||
case HFI_PROPERTY_PARAM_CODEC_SUPPORTED:
|
||||
parse_codecs(core, data);
|
||||
if (rem_bytes <= sizeof(struct hfi_codec_supported))
|
||||
return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
ret = parse_codecs(core, payload);
|
||||
if (ret < 0)
|
||||
return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
init_codecs(core);
|
||||
break;
|
||||
case HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED:
|
||||
parse_max_sessions(core, data);
|
||||
if (rem_bytes <= sizeof(struct hfi_max_sessions_supported))
|
||||
return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
ret = parse_max_sessions(core, payload);
|
||||
break;
|
||||
case HFI_PROPERTY_PARAM_CODEC_MASK_SUPPORTED:
|
||||
parse_codecs_mask(&codecs, &domain, data);
|
||||
if (rem_bytes <= sizeof(struct hfi_codec_mask_supported))
|
||||
return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
ret = parse_codecs_mask(&codecs, &domain, payload);
|
||||
break;
|
||||
case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
|
||||
parse_raw_formats(core, codecs, domain, data);
|
||||
if (rem_bytes <= sizeof(struct hfi_uncompressed_format_supported))
|
||||
return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
ret = parse_raw_formats(core, codecs, domain, payload);
|
||||
break;
|
||||
case HFI_PROPERTY_PARAM_CAPABILITY_SUPPORTED:
|
||||
parse_caps(core, codecs, domain, data);
|
||||
if (rem_bytes <= sizeof(struct hfi_capabilities))
|
||||
return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
ret = parse_caps(core, codecs, domain, payload);
|
||||
break;
|
||||
case HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED:
|
||||
parse_profile_level(core, codecs, domain, data);
|
||||
if (rem_bytes <= sizeof(struct hfi_profile_level_supported))
|
||||
return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
ret = parse_profile_level(core, codecs, domain, payload);
|
||||
break;
|
||||
case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE_SUPPORTED:
|
||||
parse_alloc_mode(core, codecs, domain, data);
|
||||
if (rem_bytes <= sizeof(struct hfi_buffer_alloc_mode_supported))
|
||||
return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
ret = parse_alloc_mode(core, codecs, domain, payload);
|
||||
break;
|
||||
default:
|
||||
ret = sizeof(u32);
|
||||
break;
|
||||
}
|
||||
|
||||
word++;
|
||||
words_count--;
|
||||
if (ret < 0)
|
||||
return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
words += ret / sizeof(u32);
|
||||
rem_bytes -= ret;
|
||||
}
|
||||
|
||||
if (!core->max_sessions_supported)
|
||||
|
||||
@@ -187,6 +187,9 @@ static int venus_write_queue(struct venus_hfi_device *hdev,
|
||||
/* ensure rd/wr indices's are read from memory */
|
||||
rmb();
|
||||
|
||||
if (qsize > IFACEQ_QUEUE_SIZE / 4)
|
||||
return -EINVAL;
|
||||
|
||||
if (wr_idx >= rd_idx)
|
||||
empty_space = qsize - (wr_idx - rd_idx);
|
||||
else
|
||||
@@ -255,6 +258,9 @@ static int venus_read_queue(struct venus_hfi_device *hdev,
|
||||
wr_idx = qhdr->write_idx;
|
||||
qsize = qhdr->q_size;
|
||||
|
||||
if (qsize > IFACEQ_QUEUE_SIZE / 4)
|
||||
return -EINVAL;
|
||||
|
||||
/* make sure data is valid before using it */
|
||||
rmb();
|
||||
|
||||
@@ -1053,18 +1059,26 @@ static void venus_sfr_print(struct venus_hfi_device *hdev)
|
||||
{
|
||||
struct device *dev = hdev->core->dev;
|
||||
struct hfi_sfr *sfr = hdev->sfr.kva;
|
||||
u32 size;
|
||||
void *p;
|
||||
|
||||
if (!sfr)
|
||||
return;
|
||||
|
||||
p = memchr(sfr->data, '\0', sfr->buf_size);
|
||||
size = sfr->buf_size;
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
if (size > ALIGNED_SFR_SIZE)
|
||||
size = ALIGNED_SFR_SIZE;
|
||||
|
||||
p = memchr(sfr->data, '\0', size);
|
||||
/*
|
||||
* SFR isn't guaranteed to be NULL terminated since SYS_ERROR indicates
|
||||
* that Venus is in the process of crashing.
|
||||
*/
|
||||
if (!p)
|
||||
sfr->data[sfr->buf_size - 1] = '\0';
|
||||
sfr->data[size - 1] = '\0';
|
||||
|
||||
dev_err_ratelimited(dev, "SFR message from FW: %s\n", sfr->data);
|
||||
}
|
||||
|
||||
@@ -492,7 +492,8 @@ static void device_run(void *prv)
|
||||
dst->sequence = frm_cap->sequence++;
|
||||
v4l2_m2m_buf_copy_metadata(src, dst, true);
|
||||
|
||||
clk_enable(dev->gate);
|
||||
if (clk_enable(dev->gate))
|
||||
goto end;
|
||||
|
||||
dma2d_config_fg(dev, frm_out,
|
||||
vb2_dma_contig_plane_dma_addr(&src->vb2_buf, 0));
|
||||
|
||||
@@ -138,39 +138,10 @@ static void sz_push_half_space(struct streamzap_ir *sz,
|
||||
sz_push_full_space(sz, value & SZ_SPACE_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* streamzap_callback - usb IRQ handler callback
|
||||
*
|
||||
* This procedure is invoked on reception of data from
|
||||
* the usb remote.
|
||||
*/
|
||||
static void streamzap_callback(struct urb *urb)
|
||||
static void sz_process_ir_data(struct streamzap_ir *sz, int len)
|
||||
{
|
||||
struct streamzap_ir *sz;
|
||||
unsigned int i;
|
||||
int len;
|
||||
|
||||
if (!urb)
|
||||
return;
|
||||
|
||||
sz = urb->context;
|
||||
len = urb->actual_length;
|
||||
|
||||
switch (urb->status) {
|
||||
case -ECONNRESET:
|
||||
case -ENOENT:
|
||||
case -ESHUTDOWN:
|
||||
/*
|
||||
* this urb is terminated, clean up.
|
||||
* sz might already be invalid at this point
|
||||
*/
|
||||
dev_err(sz->dev, "urb terminated, status: %d\n", urb->status);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
|
||||
for (i = 0; i < len; i++) {
|
||||
dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n",
|
||||
i, (unsigned char)sz->buf_in[i]);
|
||||
@@ -219,6 +190,43 @@ static void streamzap_callback(struct urb *urb)
|
||||
}
|
||||
|
||||
ir_raw_event_handle(sz->rdev);
|
||||
}
|
||||
|
||||
/*
|
||||
* streamzap_callback - usb IRQ handler callback
|
||||
*
|
||||
* This procedure is invoked on reception of data from
|
||||
* the usb remote.
|
||||
*/
|
||||
static void streamzap_callback(struct urb *urb)
|
||||
{
|
||||
struct streamzap_ir *sz;
|
||||
int len;
|
||||
|
||||
if (!urb)
|
||||
return;
|
||||
|
||||
sz = urb->context;
|
||||
len = urb->actual_length;
|
||||
|
||||
switch (urb->status) {
|
||||
case 0:
|
||||
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
|
||||
sz_process_ir_data(sz, len);
|
||||
break;
|
||||
case -ECONNRESET:
|
||||
case -ENOENT:
|
||||
case -ESHUTDOWN:
|
||||
/*
|
||||
* this urb is terminated, clean up.
|
||||
* sz might already be invalid at this point
|
||||
*/
|
||||
dev_err(sz->dev, "urb terminated, status: %d\n", urb->status);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
usb_submit_urb(urb, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
|
||||
@@ -1316,9 +1316,6 @@ static int vim2m_probe(struct platform_device *pdev)
|
||||
vfd->v4l2_dev = &dev->v4l2_dev;
|
||||
|
||||
video_set_drvdata(vfd, dev);
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
"Device registered as /dev/video%d\n", vfd->num);
|
||||
|
||||
platform_set_drvdata(pdev, dev);
|
||||
|
||||
dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
|
||||
@@ -1345,6 +1342,9 @@ static int vim2m_probe(struct platform_device *pdev)
|
||||
goto error_m2m;
|
||||
}
|
||||
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
"Device registered as /dev/video%d\n", vfd->num);
|
||||
|
||||
#ifdef CONFIG_MEDIA_CONTROLLER
|
||||
ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd,
|
||||
MEDIA_ENT_F_PROC_VIDEO_SCALER);
|
||||
|
||||
@@ -764,7 +764,7 @@ bool v4l2_detect_gtf(unsigned int frame_height,
|
||||
u64 num;
|
||||
u32 den;
|
||||
|
||||
num = ((image_width * GTF_D_C_PRIME * (u64)hfreq) -
|
||||
num = (((u64)image_width * GTF_D_C_PRIME * hfreq) -
|
||||
((u64)image_width * GTF_D_M_PRIME * 1000));
|
||||
den = (hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000) *
|
||||
(2 * GTF_CELL_GRAN);
|
||||
@@ -774,7 +774,7 @@ bool v4l2_detect_gtf(unsigned int frame_height,
|
||||
u64 num;
|
||||
u32 den;
|
||||
|
||||
num = ((image_width * GTF_S_C_PRIME * (u64)hfreq) -
|
||||
num = (((u64)image_width * GTF_S_C_PRIME * hfreq) -
|
||||
((u64)image_width * GTF_S_M_PRIME * 1000));
|
||||
den = (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000) *
|
||||
(2 * GTF_CELL_GRAN);
|
||||
|
||||
@@ -417,11 +417,14 @@ static void mtdpstore_notify_add(struct mtd_info *mtd)
|
||||
}
|
||||
|
||||
longcnt = BITS_TO_LONGS(div_u64(mtd->size, info->kmsg_size));
|
||||
cxt->rmmap = kcalloc(longcnt, sizeof(long), GFP_KERNEL);
|
||||
cxt->usedmap = kcalloc(longcnt, sizeof(long), GFP_KERNEL);
|
||||
cxt->rmmap = devm_kcalloc(&mtd->dev, longcnt, sizeof(long), GFP_KERNEL);
|
||||
cxt->usedmap = devm_kcalloc(&mtd->dev, longcnt, sizeof(long), GFP_KERNEL);
|
||||
|
||||
longcnt = BITS_TO_LONGS(div_u64(mtd->size, mtd->erasesize));
|
||||
cxt->badmap = kcalloc(longcnt, sizeof(long), GFP_KERNEL);
|
||||
cxt->badmap = devm_kcalloc(&mtd->dev, longcnt, sizeof(long), GFP_KERNEL);
|
||||
|
||||
if (!cxt->rmmap || !cxt->usedmap || !cxt->badmap)
|
||||
return;
|
||||
|
||||
/* just support dmesg right now */
|
||||
cxt->dev.flags = PSTORE_FLAGS_DMESG;
|
||||
@@ -527,9 +530,6 @@ static void mtdpstore_notify_remove(struct mtd_info *mtd)
|
||||
mtdpstore_flush_removed(cxt);
|
||||
|
||||
unregister_pstore_device(&cxt->dev);
|
||||
kfree(cxt->badmap);
|
||||
kfree(cxt->usedmap);
|
||||
kfree(cxt->rmmap);
|
||||
cxt->mtd = NULL;
|
||||
cxt->index = -1;
|
||||
}
|
||||
|
||||
@@ -2968,7 +2968,7 @@ static int brcmnand_resume(struct device *dev)
|
||||
brcmnand_save_restore_cs_config(host, 1);
|
||||
|
||||
/* Reset the chip, required by some chips after power-up */
|
||||
nand_reset_op(chip);
|
||||
nand_reset(chip, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -3694,6 +3694,21 @@ static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip)
|
||||
return mv88e6xxx_g1_stats_clear(chip);
|
||||
}
|
||||
|
||||
static int mv88e6320_setup_errata(struct mv88e6xxx_chip *chip)
|
||||
{
|
||||
u16 dummy;
|
||||
int err;
|
||||
|
||||
/* Workaround for erratum
|
||||
* 3.3 RGMII timing may be out of spec when transmit delay is enabled
|
||||
*/
|
||||
err = mv88e6xxx_port_hidden_write(chip, 0, 0xf, 0x7, 0xe000);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return mv88e6xxx_port_hidden_read(chip, 0, 0xf, 0x7, &dummy);
|
||||
}
|
||||
|
||||
/* Check if the errata has already been applied. */
|
||||
static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip)
|
||||
{
|
||||
@@ -5110,6 +5125,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6320_ops = {
|
||||
/* MV88E6XXX_FAMILY_6320 */
|
||||
.setup_errata = mv88e6320_setup_errata,
|
||||
.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
|
||||
.ip_pri_map = mv88e6085_g1_ip_pri_map,
|
||||
.irl_init_all = mv88e6352_g2_irl_init_all,
|
||||
@@ -5157,6 +5173,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6321_ops = {
|
||||
/* MV88E6XXX_FAMILY_6320 */
|
||||
.setup_errata = mv88e6320_setup_errata,
|
||||
.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
|
||||
.ip_pri_map = mv88e6085_g1_ip_pri_map,
|
||||
.irl_init_all = mv88e6352_g2_irl_init_all,
|
||||
|
||||
@@ -90,6 +90,10 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len)
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
dev->test_mtd.name = devm_kstrdup(dev->dev, part, GFP_KERNEL);
|
||||
if (!dev->test_mtd.name) {
|
||||
ret = -ENOMEM;
|
||||
goto out_put_node;
|
||||
}
|
||||
dev->test_mtd.offset = offset;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ struct vmd_irq_list {
|
||||
struct vmd_dev {
|
||||
struct pci_dev *dev;
|
||||
|
||||
spinlock_t cfg_lock;
|
||||
raw_spinlock_t cfg_lock;
|
||||
void __iomem *cfgbar;
|
||||
|
||||
int msix_count;
|
||||
@@ -387,7 +387,7 @@ static int vmd_pci_read(struct pci_bus *bus, unsigned int devfn, int reg,
|
||||
if (!addr)
|
||||
return -EFAULT;
|
||||
|
||||
spin_lock_irqsave(&vmd->cfg_lock, flags);
|
||||
raw_spin_lock_irqsave(&vmd->cfg_lock, flags);
|
||||
switch (len) {
|
||||
case 1:
|
||||
*value = readb(addr);
|
||||
@@ -402,7 +402,7 @@ static int vmd_pci_read(struct pci_bus *bus, unsigned int devfn, int reg,
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&vmd->cfg_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&vmd->cfg_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -422,7 +422,7 @@ static int vmd_pci_write(struct pci_bus *bus, unsigned int devfn, int reg,
|
||||
if (!addr)
|
||||
return -EFAULT;
|
||||
|
||||
spin_lock_irqsave(&vmd->cfg_lock, flags);
|
||||
raw_spin_lock_irqsave(&vmd->cfg_lock, flags);
|
||||
switch (len) {
|
||||
case 1:
|
||||
writeb(value, addr);
|
||||
@@ -440,7 +440,7 @@ static int vmd_pci_write(struct pci_bus *bus, unsigned int devfn, int reg,
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&vmd->cfg_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&vmd->cfg_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -958,7 +958,7 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
if (features & VMD_FEAT_OFFSET_FIRST_VECTOR)
|
||||
vmd->first_vec = 1;
|
||||
|
||||
spin_lock_init(&vmd->cfg_lock);
|
||||
raw_spin_lock_init(&vmd->cfg_lock);
|
||||
pci_set_drvdata(dev, vmd);
|
||||
err = vmd_enable_domain(vmd, features);
|
||||
if (err)
|
||||
|
||||
@@ -123,6 +123,9 @@ static unsigned int fsl_pwm_ticks_to_ns(struct fsl_pwm_chip *fpc,
|
||||
unsigned long long exval;
|
||||
|
||||
rate = clk_get_rate(fpc->clk[fpc->period.clk_select]);
|
||||
if (rate >> fpc->period.clk_ps == 0)
|
||||
return 0;
|
||||
|
||||
exval = ticks;
|
||||
exval *= 1000000000UL;
|
||||
do_div(exval, rate >> fpc->period.clk_ps);
|
||||
@@ -195,6 +198,9 @@ static unsigned int fsl_pwm_calculate_duty(struct fsl_pwm_chip *fpc,
|
||||
unsigned int period = fpc->period.mod_period + 1;
|
||||
unsigned int period_ns = fsl_pwm_ticks_to_ns(fpc, period);
|
||||
|
||||
if (!period_ns)
|
||||
return 0;
|
||||
|
||||
duty = (unsigned long long)duty_ns * period;
|
||||
do_div(duty, period_ns);
|
||||
|
||||
|
||||
@@ -120,21 +120,25 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip);
|
||||
u32 clkdiv = 0, cnt_period, cnt_duty, reg_width = PWMDWIDTH,
|
||||
reg_thres = PWMTHRES;
|
||||
unsigned long clk_rate;
|
||||
u64 resolution;
|
||||
int ret;
|
||||
|
||||
ret = pwm_mediatek_clk_enable(chip, pwm);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
clk_rate = clk_get_rate(pc->clk_pwms[pwm->hwpwm]);
|
||||
if (!clk_rate)
|
||||
return -EINVAL;
|
||||
|
||||
/* Make sure we use the bus clock and not the 26MHz clock */
|
||||
if (pc->soc->has_ck_26m_sel)
|
||||
writel(0, pc->regs + PWM_CK_26M_SEL);
|
||||
|
||||
/* Using resolution in picosecond gets accuracy higher */
|
||||
resolution = (u64)NSEC_PER_SEC * 1000;
|
||||
do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm]));
|
||||
do_div(resolution, clk_rate);
|
||||
|
||||
cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution);
|
||||
while (cnt_period > 8191) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* - The hardware cannot generate a 0% duty cycle.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
@@ -103,23 +104,24 @@ static void rcar_pwm_set_clock_control(struct rcar_pwm_chip *rp,
|
||||
rcar_pwm_write(rp, value, RCAR_PWMCR);
|
||||
}
|
||||
|
||||
static int rcar_pwm_set_counter(struct rcar_pwm_chip *rp, int div, int duty_ns,
|
||||
int period_ns)
|
||||
static int rcar_pwm_set_counter(struct rcar_pwm_chip *rp, int div, u64 duty_ns,
|
||||
u64 period_ns)
|
||||
{
|
||||
unsigned long long one_cycle, tmp; /* 0.01 nanoseconds */
|
||||
unsigned long long tmp;
|
||||
unsigned long clk_rate = clk_get_rate(rp->clk);
|
||||
u32 cyc, ph;
|
||||
|
||||
one_cycle = NSEC_PER_SEC * 100ULL << div;
|
||||
do_div(one_cycle, clk_rate);
|
||||
/* div <= 24 == RCAR_PWM_MAX_DIVISION, so the shift doesn't overflow. */
|
||||
tmp = mul_u64_u64_div_u64(period_ns, clk_rate, (u64)NSEC_PER_SEC << div);
|
||||
if (tmp > FIELD_MAX(RCAR_PWMCNT_CYC0_MASK))
|
||||
tmp = FIELD_MAX(RCAR_PWMCNT_CYC0_MASK);
|
||||
|
||||
tmp = period_ns * 100ULL;
|
||||
do_div(tmp, one_cycle);
|
||||
cyc = (tmp << RCAR_PWMCNT_CYC0_SHIFT) & RCAR_PWMCNT_CYC0_MASK;
|
||||
cyc = FIELD_PREP(RCAR_PWMCNT_CYC0_MASK, tmp);
|
||||
|
||||
tmp = duty_ns * 100ULL;
|
||||
do_div(tmp, one_cycle);
|
||||
ph = tmp & RCAR_PWMCNT_PH0_MASK;
|
||||
tmp = mul_u64_u64_div_u64(duty_ns, clk_rate, (u64)NSEC_PER_SEC << div);
|
||||
if (tmp > FIELD_MAX(RCAR_PWMCNT_PH0_MASK))
|
||||
tmp = FIELD_MAX(RCAR_PWMCNT_PH0_MASK);
|
||||
ph = FIELD_PREP(RCAR_PWMCNT_PH0_MASK, tmp);
|
||||
|
||||
/* Avoid prohibited setting */
|
||||
if (cyc == 0 || ph == 0)
|
||||
|
||||
@@ -1509,6 +1509,12 @@ static int cqspi_request_mmap_dma(struct cqspi_st *cqspi)
|
||||
int ret = PTR_ERR(cqspi->rx_chan);
|
||||
|
||||
cqspi->rx_chan = NULL;
|
||||
if (ret == -ENODEV) {
|
||||
/* DMA support is not mandatory */
|
||||
dev_info(&cqspi->pdev->dev, "No Rx DMA available\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return dev_err_probe(&cqspi->pdev->dev, ret, "No Rx DMA available\n");
|
||||
}
|
||||
init_completion(&cqspi->rx_dma_complete);
|
||||
|
||||
@@ -2749,9 +2749,13 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
|
||||
bool mem_to_mem)
|
||||
{
|
||||
int r;
|
||||
enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane);
|
||||
enum omap_overlay_caps caps;
|
||||
enum omap_channel channel;
|
||||
|
||||
if (plane == OMAP_DSS_WB)
|
||||
return -EINVAL;
|
||||
|
||||
caps = dss_feat_get_overlay_caps(plane);
|
||||
channel = dispc_ovl_get_channel_out(plane);
|
||||
|
||||
DSSDBG("dispc_ovl_setup %d, pa %pad, pa_uv %pad, sw %d, %d,%d, %dx%d ->"
|
||||
|
||||
@@ -48,7 +48,7 @@ static int xensyms_next_sym(struct xensyms *xs)
|
||||
return -ENOMEM;
|
||||
|
||||
set_xen_guest_handle(symdata->name, xs->name);
|
||||
symdata->symnum--; /* Rewind */
|
||||
symdata->symnum = symnum; /* Rewind */
|
||||
|
||||
ret = HYPERVISOR_platform_op(&xs->op);
|
||||
if (ret < 0)
|
||||
@@ -78,7 +78,7 @@ static void *xensyms_next(struct seq_file *m, void *p, loff_t *pos)
|
||||
{
|
||||
struct xensyms *xs = (struct xensyms *)m->private;
|
||||
|
||||
xs->op.u.symdata.symnum = ++(*pos);
|
||||
*pos = xs->op.u.symdata.symnum;
|
||||
|
||||
if (xensyms_next_sym(xs))
|
||||
return NULL;
|
||||
|
||||
@@ -4778,22 +4778,43 @@ static inline void ext4_inode_set_iversion_queried(struct inode *inode, u64 val)
|
||||
inode_set_iversion_queried(inode, val);
|
||||
}
|
||||
|
||||
static const char *check_igot_inode(struct inode *inode, ext4_iget_flags flags)
|
||||
|
||||
static int check_igot_inode(struct inode *inode, ext4_iget_flags flags,
|
||||
const char *function, unsigned int line)
|
||||
{
|
||||
const char *err_str;
|
||||
|
||||
if (flags & EXT4_IGET_EA_INODE) {
|
||||
if (!(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL))
|
||||
return "missing EA_INODE flag";
|
||||
if (!(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) {
|
||||
err_str = "missing EA_INODE flag";
|
||||
goto error;
|
||||
}
|
||||
if (ext4_test_inode_state(inode, EXT4_STATE_XATTR) ||
|
||||
EXT4_I(inode)->i_file_acl)
|
||||
return "ea_inode with extended attributes";
|
||||
EXT4_I(inode)->i_file_acl) {
|
||||
err_str = "ea_inode with extended attributes";
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
if ((EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL))
|
||||
return "unexpected EA_INODE flag";
|
||||
if ((EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) {
|
||||
/*
|
||||
* open_by_handle_at() could provide an old inode number
|
||||
* that has since been reused for an ea_inode; this does
|
||||
* not indicate filesystem corruption
|
||||
*/
|
||||
if (flags & EXT4_IGET_HANDLE)
|
||||
return -ESTALE;
|
||||
err_str = "unexpected EA_INODE flag";
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (is_bad_inode(inode) && !(flags & EXT4_IGET_BAD))
|
||||
return "unexpected bad inode w/o EXT4_IGET_BAD";
|
||||
return NULL;
|
||||
if (is_bad_inode(inode) && !(flags & EXT4_IGET_BAD)) {
|
||||
err_str = "unexpected bad inode w/o EXT4_IGET_BAD";
|
||||
goto error;
|
||||
}
|
||||
return 0;
|
||||
|
||||
error:
|
||||
ext4_error_inode(inode, function, line, 0, err_str);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
|
||||
@@ -4805,7 +4826,6 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
|
||||
struct ext4_inode_info *ei;
|
||||
struct ext4_super_block *es = EXT4_SB(sb)->s_es;
|
||||
struct inode *inode;
|
||||
const char *err_str;
|
||||
journal_t *journal = EXT4_SB(sb)->s_journal;
|
||||
long ret;
|
||||
loff_t size;
|
||||
@@ -4834,10 +4854,10 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
|
||||
if (!inode)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
if (!(inode->i_state & I_NEW)) {
|
||||
if ((err_str = check_igot_inode(inode, flags)) != NULL) {
|
||||
ext4_error_inode(inode, function, line, 0, err_str);
|
||||
ret = check_igot_inode(inode, flags, function, line);
|
||||
if (ret) {
|
||||
iput(inode);
|
||||
return ERR_PTR(-EFSCORRUPTED);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
return inode;
|
||||
}
|
||||
@@ -5109,13 +5129,21 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
|
||||
ret = -EFSCORRUPTED;
|
||||
goto bad_inode;
|
||||
}
|
||||
if ((err_str = check_igot_inode(inode, flags)) != NULL) {
|
||||
ext4_error_inode(inode, function, line, 0, err_str);
|
||||
ret = -EFSCORRUPTED;
|
||||
goto bad_inode;
|
||||
ret = check_igot_inode(inode, flags, function, line);
|
||||
/*
|
||||
* -ESTALE here means there is nothing inherently wrong with the inode,
|
||||
* it's just not an inode we can return for an fhandle lookup.
|
||||
*/
|
||||
if (ret == -ESTALE) {
|
||||
brelse(iloc.bh);
|
||||
unlock_new_inode(inode);
|
||||
iput(inode);
|
||||
return ERR_PTR(-ESTALE);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto bad_inode;
|
||||
brelse(iloc.bh);
|
||||
|
||||
unlock_new_inode(inode);
|
||||
return inode;
|
||||
|
||||
|
||||
@@ -271,6 +271,7 @@ enum tpm2_cc_attrs {
|
||||
#define TPM_VID_WINBOND 0x1050
|
||||
#define TPM_VID_STM 0x104A
|
||||
#define TPM_VID_ATML 0x1114
|
||||
#define TPM_VID_IFX 0x15D1
|
||||
|
||||
enum tpm_chip_flags {
|
||||
TPM_CHIP_FLAG_BOOTSTRAPPED = BIT(0),
|
||||
|
||||
@@ -55,6 +55,8 @@ struct kfd_ioctl_get_version_args {
|
||||
#define KFD_MAX_QUEUE_PERCENTAGE 100
|
||||
#define KFD_MAX_QUEUE_PRIORITY 15
|
||||
|
||||
#define KFD_MIN_QUEUE_RING_SIZE 1024
|
||||
|
||||
struct kfd_ioctl_create_queue_args {
|
||||
__u64 ring_base_address; /* to KFD */
|
||||
__u64 write_pointer_address; /* from KFD */
|
||||
|
||||
@@ -336,6 +336,8 @@ int io_provide_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe
|
||||
p->nbufs = tmp;
|
||||
p->addr = READ_ONCE(sqe->addr);
|
||||
p->len = READ_ONCE(sqe->len);
|
||||
if (!p->len)
|
||||
return -EINVAL;
|
||||
|
||||
if (check_mul_overflow((unsigned long)p->len, (unsigned long)p->nbufs,
|
||||
&size))
|
||||
|
||||
@@ -365,6 +365,12 @@ u32 airtime_link_metric_get(struct ieee80211_local *local,
|
||||
return (u32)result;
|
||||
}
|
||||
|
||||
/* Check that the first metric is at least 10% better than the second one */
|
||||
static bool is_metric_better(u32 x, u32 y)
|
||||
{
|
||||
return (x < y) && (x < (y - x / 10));
|
||||
}
|
||||
|
||||
/**
|
||||
* hwmp_route_info_get - Update routing info to originator and transmitter
|
||||
*
|
||||
@@ -455,8 +461,8 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
|
||||
(mpath->sn == orig_sn &&
|
||||
(rcu_access_pointer(mpath->next_hop) !=
|
||||
sta ?
|
||||
mult_frac(new_metric, 10, 9) :
|
||||
new_metric) >= mpath->metric)) {
|
||||
!is_metric_better(new_metric, mpath->metric) :
|
||||
new_metric >= mpath->metric))) {
|
||||
process = false;
|
||||
fresh_info = false;
|
||||
}
|
||||
@@ -526,8 +532,8 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
|
||||
if ((mpath->flags & MESH_PATH_FIXED) ||
|
||||
((mpath->flags & MESH_PATH_ACTIVE) &&
|
||||
((rcu_access_pointer(mpath->next_hop) != sta ?
|
||||
mult_frac(last_hop_metric, 10, 9) :
|
||||
last_hop_metric) > mpath->metric)))
|
||||
!is_metric_better(last_hop_metric, mpath->metric) :
|
||||
last_hop_metric > mpath->metric))))
|
||||
fresh_info = false;
|
||||
} else {
|
||||
mpath = mesh_path_add(sdata, ta);
|
||||
|
||||
@@ -1271,6 +1271,20 @@ static int mptcp_getsockopt_v4(struct mptcp_sock *msk, int optname,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int mptcp_getsockopt_v6(struct mptcp_sock *msk, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
{
|
||||
struct sock *sk = (void *)msk;
|
||||
|
||||
switch (optname) {
|
||||
case IPV6_V6ONLY:
|
||||
return mptcp_put_int_option(msk, optval, optlen,
|
||||
sk->sk_ipv6only);
|
||||
}
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int mptcp_getsockopt_sol_mptcp(struct mptcp_sock *msk, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
{
|
||||
@@ -1308,6 +1322,8 @@ int mptcp_getsockopt(struct sock *sk, int level, int optname,
|
||||
|
||||
if (level == SOL_IP)
|
||||
return mptcp_getsockopt_v4(msk, optname, optval, option);
|
||||
if (level == SOL_IPV6)
|
||||
return mptcp_getsockopt_v6(msk, optname, optval, option);
|
||||
if (level == SOL_TCP)
|
||||
return mptcp_getsockopt_sol_tcp(msk, optname, optval, option);
|
||||
if (level == SOL_MPTCP)
|
||||
|
||||
@@ -4282,6 +4282,14 @@ if (defined($opt{"LOG_FILE"})) {
|
||||
if ($opt{"CLEAR_LOG"}) {
|
||||
unlink $opt{"LOG_FILE"};
|
||||
}
|
||||
|
||||
if (! -e $opt{"LOG_FILE"} && $opt{"LOG_FILE"} =~ m,^(.*/),) {
|
||||
my $dir = $1;
|
||||
if (! -d $dir) {
|
||||
mkpath($dir) or die "Failed to create directories '$dir': $!";
|
||||
print "\nThe log directory $dir did not exist, so it was created.\n";
|
||||
}
|
||||
}
|
||||
open(LOG, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
|
||||
LOG->autoflush(1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user