Merge fba396b799 ("sparc/mm: avoid calling arch_enter/leave_lazy_mmu() in set_ptes") into android16-6.12-lts

Steps on the way to 6.12.24

Change-Id: I10efdb86ef7942f71b14841ff3628b4eaa3ae1e9
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2025-05-09 07:26:27 +00:00
101 changed files with 1096 additions and 576 deletions

View File

@@ -71,7 +71,7 @@ properties:
description:
Any lane can be inverted or not.
minItems: 1
maxItems: 2
maxItems: 3
required:
- data-lanes

View File

@@ -1451,6 +1451,7 @@
/* TODO: update once support for this CMU exists */
clocks = <0>;
clock-names = "pclk";
status = "disabled";
};
cmu_top: clock-controller@1e080000 {

View File

@@ -1255,8 +1255,7 @@
};
pwm0: pwm@1401e000 {
compatible = "mediatek,mt8173-disp-pwm",
"mediatek,mt6595-disp-pwm";
compatible = "mediatek,mt8173-disp-pwm";
reg = <0 0x1401e000 0 0x1000>;
#pwm-cells = <2>;
clocks = <&mmsys CLK_MM_DISP_PWM026M>,
@@ -1266,8 +1265,7 @@
};
pwm1: pwm@1401f000 {
compatible = "mediatek,mt8173-disp-pwm",
"mediatek,mt6595-disp-pwm";
compatible = "mediatek,mt8173-disp-pwm";
reg = <0 0x1401f000 0 0x1000>;
#pwm-cells = <2>;
clocks = <&mmsys CLK_MM_DISP_PWM126M>,

View File

@@ -227,13 +227,6 @@
wakeup-event-action = <EV_ACT_ASSERTED>;
wakeup-source;
};
key-suspend {
label = "Suspend";
gpios = <&gpio TEGRA234_MAIN_GPIO(G, 2) GPIO_ACTIVE_LOW>;
linux,input-type = <EV_KEY>;
linux,code = <KEY_SLEEP>;
};
};
fan: pwm-fan {

View File

@@ -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
@@ -159,6 +160,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)

View File

@@ -97,7 +97,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);
bool try_emulate_el1_ssbs(struct pt_regs *regs, u32 instr);

View File

@@ -845,52 +845,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;
}
@@ -916,29 +937,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)
@@ -954,6 +959,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)
{
@@ -962,16 +969,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)
@@ -1002,7 +1011,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))
@@ -1028,7 +1037,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
@@ -1041,32 +1050,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);
@@ -1100,7 +1106,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 */
@@ -1109,7 +1114,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);

View File

@@ -1361,7 +1361,8 @@ int arch_add_memory(int nid, u64 start, u64 size,
__remove_pgd_mapping(swapper_pg_dir,
__phys_to_virt(start), size);
else {
max_pfn = PFN_UP(start + size);
/* Address of hotplugged memory can be smaller */
max_pfn = max(max_pfn, PFN_UP(start + size));
max_low_pfn = max_pfn;
}

View File

@@ -936,7 +936,6 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, unsigned int nr)
{
arch_enter_lazy_mmu_mode();
for (;;) {
__set_pte_at(mm, addr, ptep, pte, 0);
if (--nr == 0)
@@ -945,7 +944,6 @@ static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
pte_val(pte) += PAGE_SIZE;
addr += PAGE_SIZE;
}
arch_leave_lazy_mmu_mode();
}
#define set_ptes set_ptes

View File

@@ -52,8 +52,10 @@ out:
void arch_enter_lazy_mmu_mode(void)
{
struct tlb_batch *tb = this_cpu_ptr(&tlb_batch);
struct tlb_batch *tb;
preempt_disable();
tb = this_cpu_ptr(&tlb_batch);
tb->active = 1;
}
@@ -64,6 +66,7 @@ void arch_leave_lazy_mmu_mode(void)
if (tb->tlb_nr)
flush_tlb_pending();
tb->active = 0;
preempt_enable();
}
static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,

View File

@@ -331,7 +331,7 @@ ivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t si
return -EINVAL;
ret = ivpu_rpm_get(vdev);
if (ret)
if (ret < 0)
return ret;
ivpu_pm_trigger_recovery(vdev, "debugfs");
@@ -408,7 +408,7 @@ static int dct_active_set(void *data, u64 active_percent)
return -EINVAL;
ret = ivpu_rpm_get(vdev);
if (ret)
if (ret < 0)
return ret;
if (active_percent)

View File

@@ -299,7 +299,8 @@ ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req
struct ivpu_ipc_consumer cons;
int ret;
drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev));
drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev) &&
pm_runtime_enabled(vdev->drm.dev));
ivpu_ipc_consumer_add(vdev, &cons, channel, NULL);

View File

@@ -4,6 +4,7 @@
*/
#include <drm/drm_file.h>
#include <linux/pm_runtime.h>
#include "ivpu_drv.h"
#include "ivpu_gem.h"
@@ -44,6 +45,10 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
args->sampling_period_ns < MS_MIN_SAMPLE_PERIOD_NS)
return -EINVAL;
ret = ivpu_rpm_get(vdev);
if (ret < 0)
return ret;
mutex_lock(&file_priv->ms_lock);
if (get_instance_by_mask(file_priv, args->metric_group_mask)) {
@@ -96,6 +101,8 @@ err_free_ms:
kfree(ms);
unlock:
mutex_unlock(&file_priv->ms_lock);
ivpu_rpm_put(vdev);
return ret;
}
@@ -160,6 +167,10 @@ int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file *
if (!args->metric_group_mask)
return -EINVAL;
ret = ivpu_rpm_get(vdev);
if (ret < 0)
return ret;
mutex_lock(&file_priv->ms_lock);
ms = get_instance_by_mask(file_priv, args->metric_group_mask);
@@ -187,6 +198,7 @@ int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file *
unlock:
mutex_unlock(&file_priv->ms_lock);
ivpu_rpm_put(vdev);
return ret;
}
@@ -204,11 +216,17 @@ int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file
{
struct ivpu_file_priv *file_priv = file->driver_priv;
struct drm_ivpu_metric_streamer_stop *args = data;
struct ivpu_device *vdev = file_priv->vdev;
struct ivpu_ms_instance *ms;
int ret;
if (!args->metric_group_mask)
return -EINVAL;
ret = ivpu_rpm_get(vdev);
if (ret < 0)
return ret;
mutex_lock(&file_priv->ms_lock);
ms = get_instance_by_mask(file_priv, args->metric_group_mask);
@@ -217,6 +235,7 @@ int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file
mutex_unlock(&file_priv->ms_lock);
ivpu_rpm_put(vdev);
return ms ? 0 : -EINVAL;
}
@@ -281,6 +300,9 @@ unlock:
void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv)
{
struct ivpu_ms_instance *ms, *tmp;
struct ivpu_device *vdev = file_priv->vdev;
pm_runtime_get_sync(vdev->drm.dev);
mutex_lock(&file_priv->ms_lock);
@@ -293,6 +315,8 @@ void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv)
free_instance(file_priv, ms);
mutex_unlock(&file_priv->ms_lock);
pm_runtime_put_autosuspend(vdev->drm.dev);
}
void ivpu_ms_cleanup_all(struct ivpu_device *vdev)

View File

@@ -313,7 +313,7 @@ static int hd44780_probe(struct platform_device *pdev)
fail3:
kfree(hd);
fail2:
kfree(lcd);
charlcd_free(lcd);
fail1:
kfree(hdc);
return ret;
@@ -328,7 +328,7 @@ static void hd44780_remove(struct platform_device *pdev)
kfree(hdc->hd44780);
kfree(lcd->drvdata);
kfree(lcd);
charlcd_free(lcd);
}
static const struct of_device_id hd44780_of_match[] = {

View File

@@ -1207,11 +1207,16 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,
struct mhi_ring_element *mhi_tre;
struct mhi_buf_info *buf_info;
int eot, eob, chain, bei;
int ret;
int ret = 0;
/* Protect accesses for reading and incrementing WP */
write_lock_bh(&mhi_chan->lock);
if (mhi_chan->ch_state != MHI_CH_STATE_ENABLED) {
ret = -ENODEV;
goto out;
}
buf_ring = &mhi_chan->buf_ring;
tre_ring = &mhi_chan->tre_ring;
@@ -1229,10 +1234,8 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,
if (!info->pre_mapped) {
ret = mhi_cntrl->map_single(mhi_cntrl, buf_info);
if (ret) {
write_unlock_bh(&mhi_chan->lock);
return ret;
}
if (ret)
goto out;
}
eob = !!(flags & MHI_EOB);
@@ -1250,9 +1253,10 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,
mhi_add_ring_element(mhi_cntrl, tre_ring);
mhi_add_ring_element(mhi_cntrl, buf_ring);
out:
write_unlock_bh(&mhi_chan->lock);
return 0;
return ret;
}
int mhi_queue_buf(struct mhi_device *mhi_dev, enum dma_data_direction dir,

View File

@@ -168,6 +168,11 @@ int tpm_try_get_ops(struct tpm_chip *chip)
goto out_ops;
mutex_lock(&chip->tpm_mutex);
/* tmp_chip_start may issue IO that is denied while suspended */
if (chip->flags & TPM_CHIP_FLAG_SUSPENDED)
goto out_lock;
rc = tpm_chip_start(chip);
if (rc)
goto out_lock;

View File

@@ -445,18 +445,11 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max)
if (!chip)
return -ENODEV;
/* Give back zero bytes, as TPM chip has not yet fully resumed: */
if (chip->flags & TPM_CHIP_FLAG_SUSPENDED) {
rc = 0;
goto out;
}
if (chip->flags & TPM_CHIP_FLAG_TPM2)
rc = tpm2_get_random(chip, out, max);
else
rc = tpm1_get_random(chip, out, max);
out:
tpm_put_ops(chip);
return rc;
}

View File

@@ -114,11 +114,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;
}

View File

@@ -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)

View File

@@ -190,6 +190,12 @@
#define USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT 0x8102
#define USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY 0x8302
#define USB_VENDOR_ID_ASETEK 0x2433
#define USB_DEVICE_ID_ASETEK_INVICTA 0xf300
#define USB_DEVICE_ID_ASETEK_FORTE 0xf301
#define USB_DEVICE_ID_ASETEK_LA_PRIMA 0xf303
#define USB_DEVICE_ID_ASETEK_TONY_KANAAN 0xf306
#define USB_VENDOR_ID_ASUS 0x0486
#define USB_DEVICE_ID_ASUS_T91MT 0x0185
#define USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO 0x0186

View File

@@ -4,7 +4,7 @@
* hid-pidff wrapper for PID-enabled devices
* Handles device reports, quirks and extends usable button range
*
* Copyright (c) 2024, 2025 Makarenko Oleg
* Copyright (c) 2024, 2025 Oleg Makarenko
* Copyright (c) 2024, 2025 Tomasz Pakuła
*/
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/input-event-codes.h>
#include "hid-ids.h"
#include "usbhid/hid-pidff.h"
#define JOY_RANGE (BTN_DEAD - BTN_JOYSTICK + 1)
@@ -89,7 +90,7 @@ static int universal_pidff_probe(struct hid_device *hdev,
}
/* Check if HID_PID support is enabled */
int (*init_function)(struct hid_device *, __u32);
int (*init_function)(struct hid_device *, u32);
init_function = hid_pidff_init_with_quirks;
if (!init_function) {
@@ -103,7 +104,7 @@ static int universal_pidff_probe(struct hid_device *hdev,
goto err;
}
hid_info(hdev, "Universal pidff driver loaded sucesfully!");
hid_info(hdev, "Universal pidff driver loaded sucessfully!");
return 0;
err:
@@ -178,6 +179,10 @@ static const struct hid_device_id universal_pidff_devices[] = {
.driver_data = HID_PIDFF_QUIRK_PERIODIC_SINE_ONLY },
{ HID_USB_DEVICE(USB_VENDOR_ID_LITE_STAR, USB_DEVICE_LITE_STAR_GT987_FF),
.driver_data = HID_PIDFF_QUIRK_PERIODIC_SINE_ONLY },
{ HID_USB_DEVICE(USB_VENDOR_ID_ASETEK, USB_DEVICE_ID_ASETEK_INVICTA) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ASETEK, USB_DEVICE_ID_ASETEK_FORTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ASETEK, USB_DEVICE_ID_ASETEK_LA_PRIMA) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ASETEK, USB_DEVICE_ID_ASETEK_TONY_KANAAN) },
{ }
};
MODULE_DEVICE_TABLE(hid, universal_pidff_devices);
@@ -193,5 +198,5 @@ module_hid_driver(universal_pidff);
MODULE_DESCRIPTION("Universal driver for USB PID Force Feedback devices");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Makarenko Oleg <oleg@makarenk.ooo>");
MODULE_AUTHOR("Oleg Makarenko <oleg@makarenk.ooo>");
MODULE_AUTHOR("Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>");

View File

@@ -35,6 +35,7 @@
#include <linux/hid-debug.h>
#include <linux/hidraw.h>
#include "usbhid.h"
#include "hid-pidff.h"
/*
* Version Information

View File

@@ -3,28 +3,27 @@
* Force feedback driver for USB HID PID compliant devices
*
* Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.com>
* Upgraded 2025 by Oleg Makarenko and Tomasz Pakuła
*/
/*
*/
/* #define DEBUG */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include "hid-pidff.h"
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/hid.h>
#include <linux/minmax.h>
#include "usbhid.h"
#define PID_EFFECTS_MAX 64
#define PID_INFINITE 0xffff
#define PID_INFINITE U16_MAX
/* Linux Force Feedback API uses miliseconds as time unit */
#define FF_TIME_EXPONENT -3
#define FF_INFINITE 0
/* Report usage table used to put reports into an array */
#define PID_SET_EFFECT 0
#define PID_EFFECT_OPERATION 1
#define PID_DEVICE_GAIN 2
@@ -45,12 +44,19 @@ static const u8 pidff_reports[] = {
0x21, 0x77, 0x7d, 0x7f, 0x89, 0x90, 0x96, 0xab,
0x5a, 0x5f, 0x6e, 0x73, 0x74
};
/*
* device_control is really 0x95, but 0x96 specified
* as it is the usage of the only field in that report.
*/
/* device_control is really 0x95, but 0x96 specified as it is the usage of
the only field in that report */
/* PID special fields */
#define PID_EFFECT_TYPE 0x25
#define PID_DIRECTION 0x57
#define PID_EFFECT_OPERATION_ARRAY 0x78
#define PID_BLOCK_LOAD_STATUS 0x8b
#define PID_DEVICE_CONTROL_ARRAY 0x96
/* Value usage tables used to put fields and values into arrays */
#define PID_EFFECT_BLOCK_INDEX 0
#define PID_DURATION 1
@@ -108,10 +114,13 @@ static const u8 pidff_device_gain[] = { 0x7e };
static const u8 pidff_pool[] = { 0x80, 0x83, 0xa9 };
/* Special field key tables used to put special field keys into arrays */
#define PID_ENABLE_ACTUATORS 0
#define PID_RESET 1
static const u8 pidff_device_control[] = { 0x97, 0x9a };
#define PID_DISABLE_ACTUATORS 1
#define PID_STOP_ALL_EFFECTS 2
#define PID_RESET 3
#define PID_PAUSE 4
#define PID_CONTINUE 5
static const u8 pidff_device_control[] = { 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c };
#define PID_CONSTANT 0
#define PID_RAMP 1
@@ -131,13 +140,14 @@ static const u8 pidff_effect_types[] = {
#define PID_BLOCK_LOAD_SUCCESS 0
#define PID_BLOCK_LOAD_FULL 1
static const u8 pidff_block_load_status[] = { 0x8c, 0x8d };
#define PID_BLOCK_LOAD_ERROR 2
static const u8 pidff_block_load_status[] = { 0x8c, 0x8d, 0x8e};
#define PID_EFFECT_START 0
#define PID_EFFECT_STOP 1
static const u8 pidff_effect_operation_status[] = { 0x79, 0x7b };
/* Polar direction 90 degrees (North) */
/* Polar direction 90 degrees (East) */
#define PIDFF_FIXED_WHEEL_DIRECTION 0x4000
struct pidff_usage {
@@ -163,8 +173,10 @@ struct pidff_device {
struct pidff_usage effect_operation[sizeof(pidff_effect_operation)];
struct pidff_usage block_free[sizeof(pidff_block_free)];
/* Special field is a field that is not composed of
usage<->value pairs that pidff_usage values are */
/*
* Special field is a field that is not composed of
* usage<->value pairs that pidff_usage values are
*/
/* Special field in create_new_effect */
struct hid_field *create_new_effect_type;
@@ -190,30 +202,59 @@ struct pidff_device {
int pid_id[PID_EFFECTS_MAX];
u32 quirks;
u8 effect_count;
};
/*
* Clamp value for a given field
*/
static s32 pidff_clamp(s32 i, struct hid_field *field)
{
s32 clamped = clamp(i, field->logical_minimum, field->logical_maximum);
pr_debug("clamped from %d to %d", i, clamped);
return clamped;
}
/*
* Scale an unsigned value with range 0..max for the given field
*/
static int pidff_rescale(int i, int max, struct hid_field *field)
{
return i * (field->logical_maximum - field->logical_minimum) / max +
field->logical_minimum;
field->logical_minimum;
}
/*
* Scale a signed value in range -0x8000..0x7fff for the given field
* Scale a signed value in range S16_MIN..S16_MAX for the given field
*/
static int pidff_rescale_signed(int i, struct hid_field *field)
{
return i == 0 ? 0 : i >
0 ? i * field->logical_maximum / 0x7fff : i *
field->logical_minimum / -0x8000;
if (i > 0) return i * field->logical_maximum / S16_MAX;
if (i < 0) return i * field->logical_minimum / S16_MIN;
return 0;
}
/*
* Scale time value from Linux default (ms) to field units
*/
static u32 pidff_rescale_time(u16 time, struct hid_field *field)
{
u32 scaled_time = time;
int exponent = field->unit_exponent;
pr_debug("time field exponent: %d\n", exponent);
for (;exponent < FF_TIME_EXPONENT; exponent++)
scaled_time *= 10;
for (;exponent > FF_TIME_EXPONENT; exponent--)
scaled_time /= 10;
pr_debug("time calculated from %d to %d\n", time, scaled_time);
return scaled_time;
}
static void pidff_set(struct pidff_usage *usage, u16 value)
{
usage->value[0] = pidff_rescale(value, 0xffff, usage->field);
usage->value[0] = pidff_rescale(value, U16_MAX, usage->field);
pr_debug("calculated from %d to %d\n", value, usage->value[0]);
}
@@ -224,14 +265,35 @@ static void pidff_set_signed(struct pidff_usage *usage, s16 value)
else {
if (value < 0)
usage->value[0] =
pidff_rescale(-value, 0x8000, usage->field);
pidff_rescale(-value, -S16_MIN, usage->field);
else
usage->value[0] =
pidff_rescale(value, 0x7fff, usage->field);
pidff_rescale(value, S16_MAX, usage->field);
}
pr_debug("calculated from %d to %d\n", value, usage->value[0]);
}
static void pidff_set_time(struct pidff_usage *usage, u16 time)
{
u32 modified_time = pidff_rescale_time(time, usage->field);
usage->value[0] = pidff_clamp(modified_time, usage->field);
}
static void pidff_set_duration(struct pidff_usage *usage, u16 duration)
{
/* Infinite value conversion from Linux API -> PID */
if (duration == FF_INFINITE)
duration = PID_INFINITE;
/* PID defines INFINITE as the max possible value for duration field */
if (duration == PID_INFINITE) {
usage->value[0] = (1U << usage->field->report_size) - 1;
return;
}
pidff_set_time(usage, duration);
}
/*
* Send envelope report to the device
*/
@@ -239,19 +301,21 @@ static void pidff_set_envelope_report(struct pidff_device *pidff,
struct ff_envelope *envelope)
{
pidff->set_envelope[PID_EFFECT_BLOCK_INDEX].value[0] =
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
pidff->set_envelope[PID_ATTACK_LEVEL].value[0] =
pidff_rescale(envelope->attack_level >
0x7fff ? 0x7fff : envelope->attack_level, 0x7fff,
pidff->set_envelope[PID_ATTACK_LEVEL].field);
pidff_rescale(envelope->attack_level >
S16_MAX ? S16_MAX : envelope->attack_level, S16_MAX,
pidff->set_envelope[PID_ATTACK_LEVEL].field);
pidff->set_envelope[PID_FADE_LEVEL].value[0] =
pidff_rescale(envelope->fade_level >
0x7fff ? 0x7fff : envelope->fade_level, 0x7fff,
pidff->set_envelope[PID_FADE_LEVEL].field);
pidff_rescale(envelope->fade_level >
S16_MAX ? S16_MAX : envelope->fade_level, S16_MAX,
pidff->set_envelope[PID_FADE_LEVEL].field);
pidff->set_envelope[PID_ATTACK_TIME].value[0] = envelope->attack_length;
pidff->set_envelope[PID_FADE_TIME].value[0] = envelope->fade_length;
pidff_set_time(&pidff->set_envelope[PID_ATTACK_TIME],
envelope->attack_length);
pidff_set_time(&pidff->set_envelope[PID_FADE_TIME],
envelope->fade_length);
hid_dbg(pidff->hid, "attack %u => %d\n",
envelope->attack_level,
@@ -320,14 +384,12 @@ static void pidff_set_effect_report(struct pidff_device *pidff,
pidff->set_effect_type->value[0] =
pidff->create_new_effect_type->value[0];
/* Convert infinite length from Linux API (0)
to PID standard (NULL) if needed */
pidff->set_effect[PID_DURATION].value[0] =
effect->replay.length == 0 ? PID_INFINITE : effect->replay.length;
pidff_set_duration(&pidff->set_effect[PID_DURATION],
effect->replay.length);
pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = effect->trigger.button;
pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] =
effect->trigger.interval;
pidff_set_time(&pidff->set_effect[PID_TRIGGER_REPEAT_INT],
effect->trigger.interval);
pidff->set_effect[PID_GAIN].value[0] =
pidff->set_effect[PID_GAIN].field->logical_maximum;
pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
@@ -336,11 +398,12 @@ static void pidff_set_effect_report(struct pidff_device *pidff,
pidff->effect_direction->value[0] = pidff_rescale(
pidff->quirks & HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION ?
PIDFF_FIXED_WHEEL_DIRECTION : effect->direction,
0xffff, pidff->effect_direction);
U16_MAX, pidff->effect_direction);
/* Omit setting delay field if it's missing */
if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_DELAY))
pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay;
pidff_set_time(&pidff->set_effect[PID_START_DELAY],
effect->replay.delay);
hid_hw_request(pidff->hid, pidff->reports[PID_SET_EFFECT],
HID_REQ_SET_REPORT);
@@ -372,11 +435,11 @@ static void pidff_set_periodic_report(struct pidff_device *pidff,
pidff_set_signed(&pidff->set_periodic[PID_OFFSET],
effect->u.periodic.offset);
pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase);
pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period;
pidff_set_time(&pidff->set_periodic[PID_PERIOD],
effect->u.periodic.period);
hid_hw_request(pidff->hid, pidff->reports[PID_SET_PERIODIC],
HID_REQ_SET_REPORT);
}
/*
@@ -476,9 +539,104 @@ static int pidff_needs_set_ramp(struct ff_effect *effect, struct ff_effect *old)
effect->u.ramp.end_level != old->u.ramp.end_level;
}
/*
* Set device gain
*/
static void pidff_set_gain_report(struct pidff_device *pidff, u16 gain)
{
if (!pidff->device_gain[PID_DEVICE_GAIN_FIELD].field)
return;
pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain);
hid_hw_request(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
HID_REQ_SET_REPORT);
}
/*
* Send device control report to the device
*/
static void pidff_set_device_control(struct pidff_device *pidff, int field)
{
int i, index;
int field_index = pidff->control_id[field];
if (field_index < 1)
return;
/* Detect if the field is a bitmask variable or an array */
if (pidff->device_control->flags & HID_MAIN_ITEM_VARIABLE) {
hid_dbg(pidff->hid, "DEVICE_CONTROL is a bitmask\n");
/* Clear current bitmask */
for(i = 0; i < sizeof(pidff_device_control); i++) {
index = pidff->control_id[i];
if (index < 1)
continue;
pidff->device_control->value[index - 1] = 0;
}
pidff->device_control->value[field_index - 1] = 1;
} else {
hid_dbg(pidff->hid, "DEVICE_CONTROL is an array\n");
pidff->device_control->value[0] = field_index;
}
hid_hw_request(pidff->hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
hid_hw_wait(pidff->hid);
}
/*
* Modify actuators state
*/
static void pidff_set_actuators(struct pidff_device *pidff, bool enable)
{
hid_dbg(pidff->hid, "%s actuators\n", enable ? "Enable" : "Disable");
pidff_set_device_control(pidff,
enable ? PID_ENABLE_ACTUATORS : PID_DISABLE_ACTUATORS);
}
/*
* Reset the device, stop all effects, enable actuators
*/
static void pidff_reset(struct pidff_device *pidff)
{
/* We reset twice as sometimes hid_wait_io isn't waiting long enough */
pidff_set_device_control(pidff, PID_RESET);
pidff_set_device_control(pidff, PID_RESET);
pidff->effect_count = 0;
pidff_set_device_control(pidff, PID_STOP_ALL_EFFECTS);
pidff_set_actuators(pidff, 1);
}
/*
* Fetch pool report
*/
static void pidff_fetch_pool(struct pidff_device *pidff)
{
int i;
struct hid_device *hid = pidff->hid;
/* Repeat if PID_SIMULTANEOUS_MAX < 2 to make sure it's correct */
for(i = 0; i < 20; i++) {
hid_hw_request(hid, pidff->reports[PID_POOL], HID_REQ_GET_REPORT);
hid_hw_wait(hid);
if (!pidff->pool[PID_SIMULTANEOUS_MAX].value)
return;
if (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] >= 2)
return;
}
hid_warn(hid, "device reports %d simultaneous effects\n",
pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
}
/*
* Send a request for effect upload to the device
*
* Reset and enable actuators if no effects were present on the device
*
* Returns 0 if device reported success, -ENOSPC if the device reported memory
* is full. Upon unknown response the function will retry for 60 times, if
* still unsuccessful -EIO is returned.
@@ -487,6 +645,9 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
{
int j;
if (!pidff->effect_count)
pidff_reset(pidff);
pidff->create_new_effect_type->value[0] = efnum;
hid_hw_request(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT],
HID_REQ_SET_REPORT);
@@ -506,6 +667,8 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
hid_dbg(pidff->hid, "device reported free memory: %d bytes\n",
pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
pidff->effect_count++;
return 0;
}
if (pidff->block_load_status->value[0] ==
@@ -515,6 +678,11 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
return -ENOSPC;
}
if (pidff->block_load_status->value[0] ==
pidff->status_id[PID_BLOCK_LOAD_ERROR]) {
hid_dbg(pidff->hid, "device error during effect creation\n");
return -EREMOTEIO;
}
}
hid_err(pidff->hid, "pid_block_load failed 60 times\n");
return -EIO;
@@ -533,7 +701,8 @@ static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n)
} else {
pidff->effect_operation_status->value[0] =
pidff->operation_id[PID_EFFECT_START];
pidff->effect_operation[PID_LOOP_COUNT].value[0] = n;
pidff->effect_operation[PID_LOOP_COUNT].value[0] =
pidff_clamp(n, pidff->effect_operation[PID_LOOP_COUNT].field);
}
hid_hw_request(pidff->hid, pidff->reports[PID_EFFECT_OPERATION],
@@ -546,20 +715,22 @@ static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n)
static int pidff_playback(struct input_dev *dev, int effect_id, int value)
{
struct pidff_device *pidff = dev->ff->private;
pidff_playback_pid(pidff, pidff->pid_id[effect_id], value);
return 0;
}
/*
* Erase effect with PID id
* Decrease the device effect counter
*/
static void pidff_erase_pid(struct pidff_device *pidff, int pid_id)
{
pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
hid_hw_request(pidff->hid, pidff->reports[PID_BLOCK_FREE],
HID_REQ_SET_REPORT);
if (pidff->effect_count > 0)
pidff->effect_count--;
}
/*
@@ -572,8 +743,11 @@ static int pidff_erase_effect(struct input_dev *dev, int effect_id)
hid_dbg(pidff->hid, "starting to erase %d/%d\n",
effect_id, pidff->pid_id[effect_id]);
/* Wait for the queue to clear. We do not want a full fifo to
prevent the effect removal. */
/*
* Wait for the queue to clear. We do not want
* a full fifo to prevent the effect removal.
*/
hid_hw_wait(pidff->hid);
pidff_playback_pid(pidff, pid_id, 0);
pidff_erase_pid(pidff, pid_id);
@@ -671,48 +845,26 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
break;
case FF_SPRING:
if (!old) {
error = pidff_request_effect_upload(pidff,
pidff->type_id[PID_SPRING]);
if (error)
return error;
}
if (!old || pidff_needs_set_effect(effect, old))
pidff_set_effect_report(pidff, effect);
if (!old || pidff_needs_set_condition(effect, old))
pidff_set_condition_report(pidff, effect);
break;
case FF_DAMPER:
case FF_INERTIA:
case FF_FRICTION:
if (!old) {
switch(effect->type) {
case FF_SPRING:
type_id = PID_SPRING;
break;
case FF_DAMPER:
type_id = PID_DAMPER;
break;
case FF_INERTIA:
type_id = PID_INERTIA;
break;
case FF_FRICTION:
type_id = PID_FRICTION;
break;
}
error = pidff_request_effect_upload(pidff,
pidff->type_id[PID_FRICTION]);
if (error)
return error;
}
if (!old || pidff_needs_set_effect(effect, old))
pidff_set_effect_report(pidff, effect);
if (!old || pidff_needs_set_condition(effect, old))
pidff_set_condition_report(pidff, effect);
break;
case FF_DAMPER:
if (!old) {
error = pidff_request_effect_upload(pidff,
pidff->type_id[PID_DAMPER]);
if (error)
return error;
}
if (!old || pidff_needs_set_effect(effect, old))
pidff_set_effect_report(pidff, effect);
if (!old || pidff_needs_set_condition(effect, old))
pidff_set_condition_report(pidff, effect);
break;
case FF_INERTIA:
if (!old) {
error = pidff_request_effect_upload(pidff,
pidff->type_id[PID_INERTIA]);
pidff->type_id[type_id]);
if (error)
return error;
}
@@ -741,11 +893,7 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
*/
static void pidff_set_gain(struct input_dev *dev, u16 gain)
{
struct pidff_device *pidff = dev->ff->private;
pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain);
hid_hw_request(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
HID_REQ_SET_REPORT);
pidff_set_gain_report(dev->ff->private, gain);
}
static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
@@ -782,9 +930,7 @@ static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
*/
static void pidff_set_autocenter(struct input_dev *dev, u16 magnitude)
{
struct pidff_device *pidff = dev->ff->private;
pidff_autocenter(pidff, magnitude);
pidff_autocenter(dev->ff->private, magnitude);
}
/*
@@ -979,23 +1125,24 @@ static int pidff_find_special_fields(struct pidff_device *pidff)
pidff->create_new_effect_type =
pidff_find_special_field(pidff->reports[PID_CREATE_NEW_EFFECT],
0x25, 1);
PID_EFFECT_TYPE, 1);
pidff->set_effect_type =
pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
0x25, 1);
PID_EFFECT_TYPE, 1);
pidff->effect_direction =
pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
0x57, 0);
PID_DIRECTION, 0);
pidff->device_control =
pidff_find_special_field(pidff->reports[PID_DEVICE_CONTROL],
0x96, !(pidff->quirks & HID_PIDFF_QUIRK_PERMISSIVE_CONTROL));
PID_DEVICE_CONTROL_ARRAY,
!(pidff->quirks & HID_PIDFF_QUIRK_PERMISSIVE_CONTROL));
pidff->block_load_status =
pidff_find_special_field(pidff->reports[PID_BLOCK_LOAD],
0x8b, 1);
PID_BLOCK_LOAD_STATUS, 1);
pidff->effect_operation_status =
pidff_find_special_field(pidff->reports[PID_EFFECT_OPERATION],
0x78, 1);
PID_EFFECT_OPERATION_ARRAY, 1);
hid_dbg(pidff->hid, "search done\n");
@@ -1024,10 +1171,6 @@ static int pidff_find_special_fields(struct pidff_device *pidff)
return -1;
}
pidff_find_special_keys(pidff->control_id, pidff->device_control,
pidff_device_control,
sizeof(pidff_device_control));
PIDFF_FIND_SPECIAL_KEYS(control_id, device_control, device_control);
if (!PIDFF_FIND_SPECIAL_KEYS(type_id, create_new_effect_type,
@@ -1106,7 +1249,6 @@ static int pidff_find_effects(struct pidff_device *pidff,
set_bit(FF_FRICTION, dev->ffbit);
return 0;
}
#define PIDFF_FIND_FIELDS(name, report, strict) \
@@ -1207,46 +1349,6 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev)
return 0;
}
/*
* Reset the device
*/
static void pidff_reset(struct pidff_device *pidff)
{
struct hid_device *hid = pidff->hid;
int i = 0;
pidff->device_control->value[0] = pidff->control_id[PID_RESET];
/* We reset twice as sometimes hid_wait_io isn't waiting long enough */
hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
hid_hw_wait(hid);
hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
hid_hw_wait(hid);
pidff->device_control->value[0] =
pidff->control_id[PID_ENABLE_ACTUATORS];
hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
hid_hw_wait(hid);
/* pool report is sometimes messed up, refetch it */
hid_hw_request(hid, pidff->reports[PID_POOL], HID_REQ_GET_REPORT);
hid_hw_wait(hid);
if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) {
if (i++ > 20) {
hid_warn(pidff->hid,
"device reports %d simultaneous effects\n",
pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
break;
}
hid_dbg(pidff->hid, "pid_pool requested again\n");
hid_hw_request(hid, pidff->reports[PID_POOL],
HID_REQ_GET_REPORT);
hid_hw_wait(hid);
}
}
}
/*
* Test if autocenter modification is using the supported method
*/
@@ -1271,25 +1373,23 @@ static int pidff_check_autocenter(struct pidff_device *pidff,
if (pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] ==
pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum + 1) {
pidff_autocenter(pidff, 0xffff);
pidff_autocenter(pidff, U16_MAX);
set_bit(FF_AUTOCENTER, dev->ffbit);
} else {
hid_notice(pidff->hid,
"device has unknown autocenter control method\n");
}
pidff_erase_pid(pidff,
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]);
return 0;
}
/*
* Check if the device is PID and initialize it
* Set initial quirks
*/
int hid_pidff_init_with_quirks(struct hid_device *hid, __u32 initial_quirks)
int hid_pidff_init_with_quirks(struct hid_device *hid, u32 initial_quirks)
{
struct pidff_device *pidff;
struct hid_input *hidinput = list_entry(hid->inputs.next,
@@ -1312,6 +1412,7 @@ int hid_pidff_init_with_quirks(struct hid_device *hid, __u32 initial_quirks)
pidff->hid = hid;
pidff->quirks = initial_quirks;
pidff->effect_count = 0;
hid_device_io_start(hid);
@@ -1328,14 +1429,9 @@ int hid_pidff_init_with_quirks(struct hid_device *hid, __u32 initial_quirks)
if (error)
goto fail;
pidff_reset(pidff);
if (test_bit(FF_GAIN, dev->ffbit)) {
pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff);
hid_hw_request(hid, pidff->reports[PID_DEVICE_GAIN],
HID_REQ_SET_REPORT);
}
/* pool report is sometimes messed up, refetch it */
pidff_fetch_pool(pidff);
pidff_set_gain_report(pidff, U16_MAX);
error = pidff_check_autocenter(pidff, dev);
if (error)
goto fail;

View File

@@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef __HID_PIDFF_H
#define __HID_PIDFF_H
#include <linux/hid.h>
/* HID PIDFF quirks */
/* Delay field (0xA7) missing. Skip it during set effect report upload */
#define HID_PIDFF_QUIRK_MISSING_DELAY BIT(0)
/* Missing Paramter block offset (0x23). Skip it during SET_CONDITION
report upload */
#define HID_PIDFF_QUIRK_MISSING_PBO BIT(1)
/* Initialise device control field even if logical_minimum != 1 */
#define HID_PIDFF_QUIRK_PERMISSIVE_CONTROL BIT(2)
/* Use fixed 0x4000 direction during SET_EFFECT report upload */
#define HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION BIT(3)
/* Force all periodic effects to be uploaded as SINE */
#define HID_PIDFF_QUIRK_PERIODIC_SINE_ONLY BIT(4)
#ifdef CONFIG_HID_PID
int hid_pidff_init(struct hid_device *hid);
int hid_pidff_init_with_quirks(struct hid_device *hid, u32 initial_quirks);
#else
#define hid_pidff_init NULL
#define hid_pidff_init_with_quirks NULL
#endif
#endif

View File

@@ -2553,6 +2553,9 @@ static void i3c_master_unregister_i3c_devs(struct i3c_master_controller *master)
*/
void i3c_master_queue_ibi(struct i3c_dev_desc *dev, struct i3c_ibi_slot *slot)
{
if (!dev->ibi || !slot)
return;
atomic_inc(&dev->ibi->pending_ibis);
queue_work(dev->ibi->wq, &slot->work);
}

View File

@@ -378,7 +378,7 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master,
slot->len < SVC_I3C_FIFO_SIZE) {
mdatactrl = readl(master->regs + SVC_I3C_MDATACTRL);
count = SVC_I3C_MDATACTRL_RXCOUNT(mdatactrl);
readsl(master->regs + SVC_I3C_MRDATAB, buf, count);
readsb(master->regs + SVC_I3C_MRDATAB, buf, count);
slot->len += count;
buf += count;
}

View File

@@ -487,17 +487,6 @@ static int tegra241_cmdqv_hw_reset(struct arm_smmu_device *smmu)
/* VCMDQ Resource Helpers */
static void tegra241_vcmdq_free_smmu_cmdq(struct tegra241_vcmdq *vcmdq)
{
struct arm_smmu_queue *q = &vcmdq->cmdq.q;
size_t nents = 1 << q->llq.max_n_shift;
size_t qsz = nents << CMDQ_ENT_SZ_SHIFT;
if (!q->base)
return;
dmam_free_coherent(vcmdq->cmdqv->smmu.dev, qsz, q->base, q->base_dma);
}
static int tegra241_vcmdq_alloc_smmu_cmdq(struct tegra241_vcmdq *vcmdq)
{
struct arm_smmu_device *smmu = &vcmdq->cmdqv->smmu;
@@ -560,7 +549,8 @@ static void tegra241_vintf_free_lvcmdq(struct tegra241_vintf *vintf, u16 lidx)
struct tegra241_vcmdq *vcmdq = vintf->lvcmdqs[lidx];
char header[64];
tegra241_vcmdq_free_smmu_cmdq(vcmdq);
/* Note that the lvcmdq queue memory space is managed by devres */
tegra241_vintf_deinit_lvcmdq(vintf, lidx);
dev_dbg(vintf->cmdqv->dev,
@@ -768,13 +758,13 @@ static int tegra241_cmdqv_init_structures(struct arm_smmu_device *smmu)
vintf = kzalloc(sizeof(*vintf), GFP_KERNEL);
if (!vintf)
goto out_fallback;
return -ENOMEM;
/* Init VINTF0 for in-kernel use */
ret = tegra241_cmdqv_init_vintf(cmdqv, 0, vintf);
if (ret) {
dev_err(cmdqv->dev, "failed to init vintf0: %d\n", ret);
goto free_vintf;
return ret;
}
/* Preallocate logical VCMDQs to VINTF0 */
@@ -783,24 +773,12 @@ static int tegra241_cmdqv_init_structures(struct arm_smmu_device *smmu)
vcmdq = tegra241_vintf_alloc_lvcmdq(vintf, lidx);
if (IS_ERR(vcmdq))
goto free_lvcmdq;
return PTR_ERR(vcmdq);
}
/* Now, we are ready to run all the impl ops */
smmu->impl_ops = &tegra241_cmdqv_impl_ops;
return 0;
free_lvcmdq:
for (lidx--; lidx >= 0; lidx--)
tegra241_vintf_free_lvcmdq(vintf, lidx);
tegra241_cmdqv_deinit_vintf(cmdqv, vintf->idx);
free_vintf:
kfree(vintf);
out_fallback:
dev_info(smmu->impl_dev, "Falling back to standard SMMU CMDQ\n");
smmu->options &= ~ARM_SMMU_OPT_TEGRA241_CMDQV;
tegra241_cmdqv_remove(smmu);
return 0;
}
#ifdef CONFIG_IOMMU_DEBUGFS

View File

@@ -3174,6 +3174,7 @@ static int __init probe_acpi_namespace_devices(void)
if (dev->bus != &acpi_bus_type)
continue;
up_read(&dmar_global_lock);
adev = to_acpi_device(dev);
mutex_lock(&adev->physical_node_lock);
list_for_each_entry(pn,
@@ -3183,6 +3184,7 @@ static int __init probe_acpi_namespace_devices(void)
break;
}
mutex_unlock(&adev->physical_node_lock);
down_read(&dmar_global_lock);
if (ret)
return ret;

View File

@@ -26,11 +26,6 @@
#include "../iommu-pages.h"
#include "cap_audit.h"
enum irq_mode {
IRQ_REMAPPING,
IRQ_POSTING,
};
struct ioapic_scope {
struct intel_iommu *iommu;
unsigned int id;
@@ -50,8 +45,8 @@ struct irq_2_iommu {
u16 irte_index;
u16 sub_handle;
u8 irte_mask;
enum irq_mode mode;
bool posted_msi;
bool posted_vcpu;
};
struct intel_ir_data {
@@ -139,7 +134,6 @@ static int alloc_irte(struct intel_iommu *iommu,
irq_iommu->irte_index = index;
irq_iommu->sub_handle = 0;
irq_iommu->irte_mask = mask;
irq_iommu->mode = IRQ_REMAPPING;
}
raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);
@@ -194,8 +188,6 @@ static int modify_irte(struct irq_2_iommu *irq_iommu,
rc = qi_flush_iec(iommu, index, 0);
/* Update iommu mode according to the IRTE mode */
irq_iommu->mode = irte->pst ? IRQ_POSTING : IRQ_REMAPPING;
raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return rc;
@@ -1173,7 +1165,26 @@ static void intel_ir_reconfigure_irte_posted(struct irq_data *irqd)
static inline void intel_ir_reconfigure_irte_posted(struct irq_data *irqd) {}
#endif
static void intel_ir_reconfigure_irte(struct irq_data *irqd, bool force)
static void __intel_ir_reconfigure_irte(struct irq_data *irqd, bool force_host)
{
struct intel_ir_data *ir_data = irqd->chip_data;
/*
* Don't modify IRTEs for IRQs that are being posted to vCPUs if the
* host CPU affinity changes.
*/
if (ir_data->irq_2_iommu.posted_vcpu && !force_host)
return;
ir_data->irq_2_iommu.posted_vcpu = false;
if (ir_data->irq_2_iommu.posted_msi)
intel_ir_reconfigure_irte_posted(irqd);
else
modify_irte(&ir_data->irq_2_iommu, &ir_data->irte_entry);
}
static void intel_ir_reconfigure_irte(struct irq_data *irqd, bool force_host)
{
struct intel_ir_data *ir_data = irqd->chip_data;
struct irte *irte = &ir_data->irte_entry;
@@ -1186,10 +1197,7 @@ static void intel_ir_reconfigure_irte(struct irq_data *irqd, bool force)
irte->vector = cfg->vector;
irte->dest_id = IRTE_DEST(cfg->dest_apicid);
if (ir_data->irq_2_iommu.posted_msi)
intel_ir_reconfigure_irte_posted(irqd);
else if (force || ir_data->irq_2_iommu.mode == IRQ_REMAPPING)
modify_irte(&ir_data->irq_2_iommu, irte);
__intel_ir_reconfigure_irte(irqd, force_host);
}
/*
@@ -1244,7 +1252,7 @@ static int intel_ir_set_vcpu_affinity(struct irq_data *data, void *info)
/* stop posting interrupts, back to the default mode */
if (!vcpu_pi_info) {
modify_irte(&ir_data->irq_2_iommu, &ir_data->irte_entry);
__intel_ir_reconfigure_irte(data, true);
} else {
struct irte irte_pi;
@@ -1267,6 +1275,7 @@ static int intel_ir_set_vcpu_affinity(struct irq_data *data, void *info)
irte_pi.pda_h = (vcpu_pi_info->pi_desc_addr >> 32) &
~(-1UL << PDA_HIGH_BIT);
ir_data->irq_2_iommu.posted_vcpu = true;
modify_irte(&ir_data->irq_2_iommu, &irte_pi);
}
@@ -1282,43 +1291,44 @@ static struct irq_chip intel_ir_chip = {
};
/*
* With posted MSIs, all vectors are multiplexed into a single notification
* vector. Devices MSIs are then dispatched in a demux loop where
* EOIs can be coalesced as well.
* With posted MSIs, the MSI vectors are multiplexed into a single notification
* vector, and only the notification vector is sent to the APIC IRR. Device
* MSIs are then dispatched in a demux loop that harvests the MSIs from the
* CPU's Posted Interrupt Request bitmap. I.e. Posted MSIs never get sent to
* the APIC IRR, and thus do not need an EOI. The notification handler instead
* performs a single EOI after processing the PIR.
*
* "INTEL-IR-POST" IRQ chip does not do EOI on ACK, thus the dummy irq_ack()
* function. Instead EOI is performed by the posted interrupt notification
* handler.
* Note! Pending SMP/CPU affinity changes, which are per MSI, must still be
* honored, only the APIC EOI is omitted.
*
* For the example below, 3 MSIs are coalesced into one CPU notification. Only
* one apic_eoi() is needed.
* one apic_eoi() is needed, but each MSI needs to process pending changes to
* its CPU affinity.
*
* __sysvec_posted_msi_notification()
* irq_enter();
* handle_edge_irq()
* irq_chip_ack_parent()
* dummy(); // No EOI
* irq_move_irq(); // No EOI
* handle_irq_event()
* driver_handler()
* handle_edge_irq()
* irq_chip_ack_parent()
* dummy(); // No EOI
* irq_move_irq(); // No EOI
* handle_irq_event()
* driver_handler()
* handle_edge_irq()
* irq_chip_ack_parent()
* dummy(); // No EOI
* irq_move_irq(); // No EOI
* handle_irq_event()
* driver_handler()
* apic_eoi()
* irq_exit()
*
*/
static void dummy_ack(struct irq_data *d) { }
static struct irq_chip intel_ir_chip_post_msi = {
.name = "INTEL-IR-POST",
.irq_ack = dummy_ack,
.irq_ack = irq_move_irq,
.irq_set_affinity = intel_ir_set_affinity,
.irq_compose_msi_msg = intel_ir_compose_msi_msg,
.irq_set_vcpu_affinity = intel_ir_set_vcpu_affinity,
@@ -1494,6 +1504,9 @@ static void intel_irq_remapping_deactivate(struct irq_domain *domain,
struct intel_ir_data *data = irq_data->chip_data;
struct irte entry;
WARN_ON_ONCE(data->irq_2_iommu.posted_vcpu);
data->irq_2_iommu.posted_vcpu = false;
memset(&entry, 0, sizeof(entry));
modify_irte(&data->irq_2_iommu, &entry);
}

View File

@@ -1127,7 +1127,7 @@ int iommufd_access_rw(struct iommufd_access *access, unsigned long iova,
struct io_pagetable *iopt;
struct iopt_area *area;
unsigned long last_iova;
int rc;
int rc = -EINVAL;
if (!length)
return -EINVAL;

View File

@@ -461,7 +461,7 @@ static int lpg_calc_freq(struct lpg_channel *chan, uint64_t period)
max_res = LPG_RESOLUTION_9BIT;
}
min_period = div64_u64((u64)NSEC_PER_SEC * (1 << pwm_resolution_arr[0]),
min_period = div64_u64((u64)NSEC_PER_SEC * ((1 << pwm_resolution_arr[0]) - 1),
clk_rate_arr[clk_len - 1]);
if (period <= min_period)
return -EINVAL;
@@ -482,7 +482,7 @@ static int lpg_calc_freq(struct lpg_channel *chan, uint64_t period)
*/
for (i = 0; i < pwm_resolution_count; i++) {
resolution = 1 << pwm_resolution_arr[i];
resolution = (1 << pwm_resolution_arr[i]) - 1;
for (clk_sel = 1; clk_sel < clk_len; clk_sel++) {
u64 numerator = period * clk_rate_arr[clk_sel];
@@ -529,7 +529,7 @@ static void lpg_calc_duty(struct lpg_channel *chan, uint64_t duty)
unsigned int clk_rate;
if (chan->subtype == LPG_SUBTYPE_HI_RES_PWM) {
max = LPG_RESOLUTION_15BIT - 1;
max = BIT(lpg_pwm_resolution_hi_res[chan->pwm_resolution_sel]) - 1;
clk_rate = lpg_clk_rates_hi_res[chan->clk_sel];
} else {
max = LPG_RESOLUTION_9BIT - 1;
@@ -1291,7 +1291,7 @@ static int lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
if (ret)
return ret;
state->period = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * (1 << resolution) *
state->period = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * ((1 << resolution) - 1) *
pre_div * (1 << m), refclk);
state->duty_cycle = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * pwm_value * pre_div * (1 << m), refclk);
} else {

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2023, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2016-2025, NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/delay.h>
@@ -28,12 +28,6 @@
#define HSP_INT_FULL_MASK 0xff
#define HSP_INT_DIMENSIONING 0x380
#define HSP_nSM_SHIFT 0
#define HSP_nSS_SHIFT 4
#define HSP_nAS_SHIFT 8
#define HSP_nDB_SHIFT 12
#define HSP_nSI_SHIFT 16
#define HSP_nINT_MASK 0xf
#define HSP_DB_TRIGGER 0x0
#define HSP_DB_ENABLE 0x4
@@ -97,6 +91,20 @@ struct tegra_hsp_soc {
bool has_per_mb_ie;
bool has_128_bit_mb;
unsigned int reg_stride;
/* Shifts for dimensioning register. */
unsigned int si_shift;
unsigned int db_shift;
unsigned int as_shift;
unsigned int ss_shift;
unsigned int sm_shift;
/* Masks for dimensioning register. */
unsigned int si_mask;
unsigned int db_mask;
unsigned int as_mask;
unsigned int ss_mask;
unsigned int sm_mask;
};
struct tegra_hsp {
@@ -747,11 +755,11 @@ static int tegra_hsp_probe(struct platform_device *pdev)
return PTR_ERR(hsp->regs);
value = tegra_hsp_readl(hsp, HSP_INT_DIMENSIONING);
hsp->num_sm = (value >> HSP_nSM_SHIFT) & HSP_nINT_MASK;
hsp->num_ss = (value >> HSP_nSS_SHIFT) & HSP_nINT_MASK;
hsp->num_as = (value >> HSP_nAS_SHIFT) & HSP_nINT_MASK;
hsp->num_db = (value >> HSP_nDB_SHIFT) & HSP_nINT_MASK;
hsp->num_si = (value >> HSP_nSI_SHIFT) & HSP_nINT_MASK;
hsp->num_sm = (value >> hsp->soc->sm_shift) & hsp->soc->sm_mask;
hsp->num_ss = (value >> hsp->soc->ss_shift) & hsp->soc->ss_mask;
hsp->num_as = (value >> hsp->soc->as_shift) & hsp->soc->as_mask;
hsp->num_db = (value >> hsp->soc->db_shift) & hsp->soc->db_mask;
hsp->num_si = (value >> hsp->soc->si_shift) & hsp->soc->si_mask;
err = platform_get_irq_byname_optional(pdev, "doorbell");
if (err >= 0)
@@ -915,6 +923,16 @@ static const struct tegra_hsp_soc tegra186_hsp_soc = {
.has_per_mb_ie = false,
.has_128_bit_mb = false,
.reg_stride = 0x100,
.si_shift = 16,
.db_shift = 12,
.as_shift = 8,
.ss_shift = 4,
.sm_shift = 0,
.si_mask = 0xf,
.db_mask = 0xf,
.as_mask = 0xf,
.ss_mask = 0xf,
.sm_mask = 0xf,
};
static const struct tegra_hsp_soc tegra194_hsp_soc = {
@@ -922,6 +940,16 @@ static const struct tegra_hsp_soc tegra194_hsp_soc = {
.has_per_mb_ie = true,
.has_128_bit_mb = false,
.reg_stride = 0x100,
.si_shift = 16,
.db_shift = 12,
.as_shift = 8,
.ss_shift = 4,
.sm_shift = 0,
.si_mask = 0xf,
.db_mask = 0xf,
.as_mask = 0xf,
.ss_mask = 0xf,
.sm_mask = 0xf,
};
static const struct tegra_hsp_soc tegra234_hsp_soc = {
@@ -929,6 +957,16 @@ static const struct tegra_hsp_soc tegra234_hsp_soc = {
.has_per_mb_ie = false,
.has_128_bit_mb = true,
.reg_stride = 0x100,
.si_shift = 16,
.db_shift = 12,
.as_shift = 8,
.ss_shift = 4,
.sm_shift = 0,
.si_mask = 0xf,
.db_mask = 0xf,
.as_mask = 0xf,
.ss_mask = 0xf,
.sm_mask = 0xf,
};
static const struct tegra_hsp_soc tegra264_hsp_soc = {
@@ -936,6 +974,16 @@ static const struct tegra_hsp_soc tegra264_hsp_soc = {
.has_per_mb_ie = false,
.has_128_bit_mb = true,
.reg_stride = 0x1000,
.si_shift = 17,
.db_shift = 12,
.as_shift = 8,
.ss_shift = 4,
.sm_shift = 0,
.si_mask = 0x1f,
.db_mask = 0x1f,
.as_mask = 0xf,
.ss_mask = 0xf,
.sm_mask = 0xf,
};
static const struct of_device_id tegra_hsp_match[] = {

View File

@@ -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");

View File

@@ -320,7 +320,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 */

View File

@@ -3562,6 +3562,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_cleanup:
ccs_cleanup(sensor);
@@ -3591,9 +3592,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);

View File

@@ -1230,12 +1230,13 @@ static int hi556_check_hwcfg(struct device *dev)
ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
if (ret) {
dev_err(dev, "can't get clock frequency");
return ret;
goto check_hwcfg_error;
}
if (mclk != HI556_MCLK) {
dev_err(dev, "external clock %d is not supported", mclk);
return -EINVAL;
ret = -EINVAL;
goto check_hwcfg_error;
}
if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {

View File

@@ -1077,10 +1077,6 @@ static int imx214_probe(struct i2c_client *client)
*/
imx214_power_on(imx214->dev);
pm_runtime_set_active(imx214->dev);
pm_runtime_enable(imx214->dev);
pm_runtime_idle(imx214->dev);
ret = imx214_ctrls_init(imx214);
if (ret < 0)
goto error_power_off;
@@ -1101,22 +1097,30 @@ static int imx214_probe(struct i2c_client *client)
imx214_entity_init_state(&imx214->sd, NULL);
pm_runtime_set_active(imx214->dev);
pm_runtime_enable(imx214->dev);
ret = v4l2_async_register_subdev_sensor(&imx214->sd);
if (ret < 0) {
dev_err(dev, "could not register v4l2 device\n");
goto free_entity;
}
pm_runtime_idle(imx214->dev);
return 0;
free_entity:
pm_runtime_disable(imx214->dev);
pm_runtime_set_suspended(&client->dev);
media_entity_cleanup(&imx214->sd.entity);
free_ctrl:
mutex_destroy(&imx214->mutex);
v4l2_ctrl_handler_free(&imx214->ctrls);
error_power_off:
pm_runtime_disable(imx214->dev);
regulator_bulk_disable(IMX214_NUM_SUPPLIES, imx214->supplies);
imx214_power_off(imx214->dev);
return ret;
}
@@ -1129,11 +1133,12 @@ static void imx214_remove(struct i2c_client *client)
v4l2_async_unregister_subdev(&imx214->sd);
media_entity_cleanup(&imx214->sd.entity);
v4l2_ctrl_handler_free(&imx214->ctrls);
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
mutex_destroy(&imx214->mutex);
pm_runtime_disable(&client->dev);
if (!pm_runtime_status_suspended(&client->dev)) {
imx214_power_off(imx214->dev);
pm_runtime_set_suspended(&client->dev);
}
}
static const struct of_device_id imx214_of_match[] = {

View File

@@ -134,10 +134,11 @@
/* Pixel rate is fixed for all the modes */
#define IMX219_PIXEL_RATE 182400000
#define IMX219_PIXEL_RATE_4LANE 280800000
#define IMX219_PIXEL_RATE_4LANE 281600000
#define IMX219_DEFAULT_LINK_FREQ 456000000
#define IMX219_DEFAULT_LINK_FREQ_4LANE 363000000
#define IMX219_DEFAULT_LINK_FREQ_4LANE_UNSUPPORTED 363000000
#define IMX219_DEFAULT_LINK_FREQ_4LANE 364000000
/* IMX219 native and active pixel array size. */
#define IMX219_NATIVE_WIDTH 3296U
@@ -169,15 +170,6 @@ static const struct cci_reg_sequence imx219_common_regs[] = {
{ CCI_REG8(0x30eb), 0x05 },
{ CCI_REG8(0x30eb), 0x09 },
/* PLL Clock Table */
{ IMX219_REG_VTPXCK_DIV, 5 },
{ IMX219_REG_VTSYCK_DIV, 1 },
{ IMX219_REG_PREPLLCK_VT_DIV, 3 }, /* 0x03 = AUTO set */
{ IMX219_REG_PREPLLCK_OP_DIV, 3 }, /* 0x03 = AUTO set */
{ IMX219_REG_PLL_VT_MPY, 57 },
{ IMX219_REG_OPSYCK_DIV, 1 },
{ IMX219_REG_PLL_OP_MPY, 114 },
/* Undocumented registers */
{ CCI_REG8(0x455e), 0x00 },
{ CCI_REG8(0x471e), 0x4b },
@@ -202,12 +194,45 @@ static const struct cci_reg_sequence imx219_common_regs[] = {
{ IMX219_REG_EXCK_FREQ, IMX219_EXCK_FREQ(IMX219_XCLK_FREQ / 1000000) },
};
static const struct cci_reg_sequence imx219_2lane_regs[] = {
/* PLL Clock Table */
{ IMX219_REG_VTPXCK_DIV, 5 },
{ IMX219_REG_VTSYCK_DIV, 1 },
{ IMX219_REG_PREPLLCK_VT_DIV, 3 }, /* 0x03 = AUTO set */
{ IMX219_REG_PREPLLCK_OP_DIV, 3 }, /* 0x03 = AUTO set */
{ IMX219_REG_PLL_VT_MPY, 57 },
{ IMX219_REG_OPSYCK_DIV, 1 },
{ IMX219_REG_PLL_OP_MPY, 114 },
/* 2-Lane CSI Mode */
{ IMX219_REG_CSI_LANE_MODE, IMX219_CSI_2_LANE_MODE },
};
static const struct cci_reg_sequence imx219_4lane_regs[] = {
/* PLL Clock Table */
{ IMX219_REG_VTPXCK_DIV, 5 },
{ IMX219_REG_VTSYCK_DIV, 1 },
{ IMX219_REG_PREPLLCK_VT_DIV, 3 }, /* 0x03 = AUTO set */
{ IMX219_REG_PREPLLCK_OP_DIV, 3 }, /* 0x03 = AUTO set */
{ IMX219_REG_PLL_VT_MPY, 88 },
{ IMX219_REG_OPSYCK_DIV, 1 },
{ IMX219_REG_PLL_OP_MPY, 91 },
/* 4-Lane CSI Mode */
{ IMX219_REG_CSI_LANE_MODE, IMX219_CSI_4_LANE_MODE },
};
static const s64 imx219_link_freq_menu[] = {
IMX219_DEFAULT_LINK_FREQ,
};
static const s64 imx219_link_freq_4lane_menu[] = {
IMX219_DEFAULT_LINK_FREQ_4LANE,
/*
* This will never be advertised to userspace, but will be used for
* v4l2_link_freq_to_bitmap
*/
IMX219_DEFAULT_LINK_FREQ_4LANE_UNSUPPORTED,
};
static const char * const imx219_test_pattern_menu[] = {
@@ -663,9 +688,11 @@ static int imx219_set_framefmt(struct imx219 *imx219,
static int imx219_configure_lanes(struct imx219 *imx219)
{
return cci_write(imx219->regmap, IMX219_REG_CSI_LANE_MODE,
imx219->lanes == 2 ? IMX219_CSI_2_LANE_MODE :
IMX219_CSI_4_LANE_MODE, NULL);
/* Write the appropriate PLL settings for the number of MIPI lanes */
return cci_multi_reg_write(imx219->regmap,
imx219->lanes == 2 ? imx219_2lane_regs : imx219_4lane_regs,
imx219->lanes == 2 ? ARRAY_SIZE(imx219_2lane_regs) :
ARRAY_SIZE(imx219_4lane_regs), NULL);
};
static int imx219_start_streaming(struct imx219 *imx219,
@@ -1042,6 +1069,7 @@ static int imx219_check_hwcfg(struct device *dev, struct imx219 *imx219)
struct v4l2_fwnode_endpoint ep_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
unsigned long link_freq_bitmap;
int ret = -EINVAL;
endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
@@ -1063,23 +1091,40 @@ static int imx219_check_hwcfg(struct device *dev, struct imx219 *imx219)
imx219->lanes = ep_cfg.bus.mipi_csi2.num_data_lanes;
/* Check the link frequency set in device tree */
if (!ep_cfg.nr_of_link_frequencies) {
dev_err_probe(dev, -EINVAL,
"link-frequency property not found in DT\n");
goto error_out;
switch (imx219->lanes) {
case 2:
ret = v4l2_link_freq_to_bitmap(dev,
ep_cfg.link_frequencies,
ep_cfg.nr_of_link_frequencies,
imx219_link_freq_menu,
ARRAY_SIZE(imx219_link_freq_menu),
&link_freq_bitmap);
break;
case 4:
ret = v4l2_link_freq_to_bitmap(dev,
ep_cfg.link_frequencies,
ep_cfg.nr_of_link_frequencies,
imx219_link_freq_4lane_menu,
ARRAY_SIZE(imx219_link_freq_4lane_menu),
&link_freq_bitmap);
if (!ret && (link_freq_bitmap & BIT(1))) {
dev_warn(dev, "Link frequency of %d not supported, but has been incorrectly advertised previously\n",
IMX219_DEFAULT_LINK_FREQ_4LANE_UNSUPPORTED);
dev_warn(dev, "Using link frequency of %d\n",
IMX219_DEFAULT_LINK_FREQ_4LANE);
link_freq_bitmap |= BIT(0);
}
break;
}
if (ep_cfg.nr_of_link_frequencies != 1 ||
(ep_cfg.link_frequencies[0] != ((imx219->lanes == 2) ?
IMX219_DEFAULT_LINK_FREQ : IMX219_DEFAULT_LINK_FREQ_4LANE))) {
if (ret || !(link_freq_bitmap & BIT(0))) {
ret = -EINVAL;
dev_err_probe(dev, -EINVAL,
"Link frequency not supported: %lld\n",
ep_cfg.link_frequencies[0]);
goto error_out;
}
ret = 0;
error_out:
v4l2_fwnode_endpoint_free(&ep_cfg);
fwnode_handle_put(endpoint);
@@ -1186,6 +1231,9 @@ static int imx219_probe(struct i2c_client *client)
goto error_media_entity;
}
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
ret = v4l2_async_register_subdev_sensor(&imx219->sd);
if (ret < 0) {
dev_err_probe(dev, ret,
@@ -1193,15 +1241,14 @@ static int imx219_probe(struct i2c_client *client)
goto error_subdev_cleanup;
}
/* Enable runtime PM and turn off the device */
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
pm_runtime_idle(dev);
return 0;
error_subdev_cleanup:
v4l2_subdev_cleanup(&imx219->sd);
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
error_media_entity:
media_entity_cleanup(&imx219->sd.entity);
@@ -1226,9 +1273,10 @@ static void imx219_remove(struct i2c_client *client)
imx219_free_controls(imx219);
pm_runtime_disable(&client->dev);
if (!pm_runtime_status_suspended(&client->dev))
if (!pm_runtime_status_suspended(&client->dev)) {
imx219_power_off(&client->dev);
pm_runtime_set_suspended(&client->dev);
pm_runtime_set_suspended(&client->dev);
}
}
static const struct of_device_id imx219_dt_ids[] = {

View File

@@ -2442,17 +2442,19 @@ static int imx319_probe(struct i2c_client *client)
if (full_power)
pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
ret = v4l2_async_register_subdev_sensor(&imx319->sd);
if (ret < 0)
goto error_media_entity_pm;
pm_runtime_idle(&client->dev);
return 0;
error_media_entity_pm:
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
if (full_power)
pm_runtime_set_suspended(&client->dev);
media_entity_cleanup(&imx319->sd.entity);
error_handler_free:
@@ -2474,7 +2476,8 @@ static void imx319_remove(struct i2c_client *client)
v4l2_ctrl_handler_free(sd->ctrl_handler);
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
if (!pm_runtime_status_suspended(&client->dev))
pm_runtime_set_suspended(&client->dev);
mutex_destroy(&imx319->mutex);
}

View File

@@ -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 */
@@ -1696,7 +1698,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);

View File

@@ -1296,6 +1296,7 @@ int ipu6_isys_video_init(struct ipu6_isys_video *av)
av->vdev.release = video_device_release_empty;
av->vdev.fops = &isys_fops;
av->vdev.v4l2_dev = &av->isys->v4l2_dev;
av->vdev.dev_parent = &av->isys->adev->isp->pdev->dev;
if (!av->vdev.ioctl_ops)
av->vdev.ioctl_ops = &ipu6_v4l2_ioctl_ops;
av->vdev.queue = &av->aq.vbq;

View File

@@ -135,8 +135,8 @@ static const u16 cmt_vals_out[][15] = {
};
static const u16 cmt_vals_in[][13] = {
{0x1082, 0x0000, 0x5104, 0x0000, 0x11C7, 0x0000, 0x1041, 0x02BC, 0x7C01, 0xFFE9, 0x9900, 0x9908, 0x8100},
{0x1104, 0x0000, 0x9208, 0x0000, 0x138E, 0x0000, 0x1041, 0x015E, 0x7C01, 0xFFE9, 0x0100, 0x0908, 0x1000},
{0x1082, 0x0000, 0x5104, 0x0000, 0x11C7, 0x0000, 0x1041, 0x02BC, 0x7C01, 0xFFE9, 0x9900, 0x9908, 0x8100},
};
static const u32 cmt_addrs_out[][15] = {
@@ -206,10 +206,11 @@ u32 mgb4_cmt_set_vout_freq(struct mgb4_vout_dev *voutdev, unsigned int freq)
mgb4_write_reg(video, regs->config, 0x1 | (config & ~0x3));
mgb4_mask_reg(video, regs->config, 0x100, 0x100);
for (i = 0; i < ARRAY_SIZE(cmt_addrs_out[0]); i++)
mgb4_write_reg(&voutdev->mgbdev->cmt, addr[i], reg_set[i]);
mgb4_mask_reg(video, regs->config, 0x100, 0x100);
mgb4_mask_reg(video, regs->config, 0x100, 0x0);
mgb4_write_reg(video, regs->config, config & ~0x1);
@@ -236,10 +237,11 @@ void mgb4_cmt_set_vin_freq_range(struct mgb4_vin_dev *vindev,
mgb4_write_reg(video, regs->config, 0x1 | (config & ~0x3));
mgb4_mask_reg(video, regs->config, 0x1000, 0x1000);
for (i = 0; i < ARRAY_SIZE(cmt_addrs_in[0]); i++)
mgb4_write_reg(&vindev->mgbdev->cmt, addr[i], reg_set[i]);
mgb4_mask_reg(video, regs->config, 0x1000, 0x1000);
mgb4_mask_reg(video, regs->config, 0x1000, 0x0);
mgb4_write_reg(video, regs->config, config & ~0x1);

View File

@@ -576,7 +576,7 @@ int wave5_vpu_build_up_dec_param(struct vpu_instance *inst,
vpu_write_reg(inst->dev, W5_CMD_NUM_CQ_DEPTH_M1,
WAVE521_COMMAND_QUEUE_DEPTH - 1);
}
vpu_write_reg(inst->dev, W5_CMD_ERR_CONCEAL, 0);
ret = send_firmware_command(inst, W5_CREATE_INSTANCE, true, NULL, NULL);
if (ret) {
wave5_vdi_free_dma_memory(vpu_dev, &p_dec_info->vb_work);

View File

@@ -1424,10 +1424,24 @@ static int wave5_vpu_dec_start_streaming(struct vb2_queue *q, unsigned int count
if (ret)
goto free_bitstream_vbuf;
} else if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
struct dec_initial_info *initial_info =
&inst->codec_info->dec_info.initial_info;
if (inst->state == VPU_INST_STATE_STOP)
ret = switch_state(inst, VPU_INST_STATE_INIT_SEQ);
if (ret)
goto return_buffers;
if (inst->state == VPU_INST_STATE_INIT_SEQ &&
inst->dev->product_code == WAVE521C_CODE) {
if (initial_info->luma_bitdepth != 8) {
dev_info(inst->dev->dev, "%s: no support for %d bit depth",
__func__, initial_info->luma_bitdepth);
ret = -EINVAL;
goto return_buffers;
}
}
}
return ret;
@@ -1446,6 +1460,16 @@ static int streamoff_output(struct vb2_queue *q)
struct vb2_v4l2_buffer *buf;
int ret;
dma_addr_t new_rd_ptr;
struct dec_output_info dec_info;
unsigned int i;
for (i = 0; i < v4l2_m2m_num_dst_bufs_ready(m2m_ctx); i++) {
ret = wave5_vpu_dec_set_disp_flag(inst, i);
if (ret)
dev_dbg(inst->dev->dev,
"%s: Setting display flag of buf index: %u, fail: %d\n",
__func__, i, ret);
}
while ((buf = v4l2_m2m_src_buf_remove(m2m_ctx))) {
dev_dbg(inst->dev->dev, "%s: (Multiplanar) buf type %4u | index %4u\n",
@@ -1453,6 +1477,11 @@ static int streamoff_output(struct vb2_queue *q)
v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR);
}
while (wave5_vpu_dec_get_output_info(inst, &dec_info) == 0) {
if (dec_info.index_frame_display >= 0)
wave5_vpu_dec_set_disp_flag(inst, dec_info.index_frame_display);
}
ret = wave5_vpu_flush_instance(inst);
if (ret)
return ret;
@@ -1535,7 +1564,7 @@ static void wave5_vpu_dec_stop_streaming(struct vb2_queue *q)
break;
if (wave5_vpu_dec_get_output_info(inst, &dec_output_info))
dev_dbg(inst->dev->dev, "Getting decoding results from fw, fail\n");
dev_dbg(inst->dev->dev, "there is no output info\n");
}
v4l2_m2m_update_stop_streaming_state(m2m_ctx, q);

View File

@@ -54,12 +54,12 @@ static void wave5_vpu_handle_irq(void *dev_id)
struct vpu_device *dev = dev_id;
irq_reason = wave5_vdi_read_register(dev, W5_VPU_VINT_REASON);
seq_done = wave5_vdi_read_register(dev, W5_RET_SEQ_DONE_INSTANCE_INFO);
cmd_done = wave5_vdi_read_register(dev, W5_RET_QUEUE_CMD_DONE_INST);
wave5_vdi_write_register(dev, W5_VPU_VINT_REASON_CLR, irq_reason);
wave5_vdi_write_register(dev, W5_VPU_VINT_CLEAR, 0x1);
list_for_each_entry(inst, &dev->instances, list) {
seq_done = wave5_vdi_read_register(dev, W5_RET_SEQ_DONE_INSTANCE_INFO);
cmd_done = wave5_vdi_read_register(dev, W5_RET_QUEUE_CMD_DONE_INST);
if (irq_reason & BIT(INT_WAVE5_INIT_SEQ) ||
irq_reason & BIT(INT_WAVE5_ENC_SET_PARAM)) {

View File

@@ -73,6 +73,16 @@ int wave5_vpu_flush_instance(struct vpu_instance *inst)
inst->type == VPU_INST_TYPE_DEC ? "DECODER" : "ENCODER", inst->id);
mutex_unlock(&inst->dev->hw_lock);
return -ETIMEDOUT;
} else if (ret == -EBUSY) {
struct dec_output_info dec_info;
mutex_unlock(&inst->dev->hw_lock);
wave5_vpu_dec_get_output_info(inst, &dec_info);
ret = mutex_lock_interruptible(&inst->dev->hw_lock);
if (ret)
return ret;
if (dec_info.index_frame_display > 0)
wave5_vpu_dec_set_disp_flag(inst, dec_info.index_frame_display);
}
} while (ret != 0);
mutex_unlock(&inst->dev->hw_lock);

View File

@@ -79,8 +79,11 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(void *priv, enum mtk_vcodec_fw_use
}
fw = devm_kzalloc(&plat_dev->dev, sizeof(*fw), GFP_KERNEL);
if (!fw)
if (!fw) {
scp_put(scp);
return ERR_PTR(-ENOMEM);
}
fw->type = SCP;
fw->ops = &mtk_vcodec_rproc_msg;
fw->scp = scp;

View File

@@ -594,7 +594,11 @@ static int h264_enc_init(struct mtk_vcodec_enc_ctx *ctx)
inst->ctx = ctx;
inst->vpu_inst.ctx = ctx;
inst->vpu_inst.id = is_ext ? SCP_IPI_VENC_H264 : IPI_VENC_H264;
if (is_ext)
inst->vpu_inst.id = SCP_IPI_VENC_H264;
else
inst->vpu_inst.id = IPI_VENC_H264;
inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx->dev->reg_base, VENC_SYS);
ret = vpu_enc_init(&inst->vpu_inst);

View File

@@ -1650,8 +1650,8 @@ rel_ctrl_handler:
static int npcm_video_ece_init(struct npcm_video *video)
{
struct device_node *ece_node __free(device_node) = NULL;
struct device *dev = video->dev;
struct device_node *ece_node;
struct platform_device *ece_pdev;
void __iomem *regs;
@@ -1671,7 +1671,7 @@ static int npcm_video_ece_init(struct npcm_video *video)
dev_err(dev, "Failed to find ECE device\n");
return -ENODEV;
}
of_node_put(ece_node);
struct device *ece_dev __free(put_device) = &ece_pdev->dev;
regs = devm_platform_ioremap_resource(ece_pdev, 0);
if (IS_ERR(regs)) {
@@ -1686,7 +1686,7 @@ static int npcm_video_ece_init(struct npcm_video *video)
return PTR_ERR(video->ece.regmap);
}
video->ece.reset = devm_reset_control_get(&ece_pdev->dev, NULL);
video->ece.reset = devm_reset_control_get(ece_dev, NULL);
if (IS_ERR(video->ece.reset)) {
dev_err(dev, "Failed to get ECE reset control in DTS\n");
return PTR_ERR(video->ece.reset);

View File

@@ -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();

View File

@@ -376,7 +376,7 @@ static void rga_cmd_set_dst_info(struct rga_ctx *ctx,
* Configure the dest framebuffer base address with pixel offset.
*/
offsets = rga_get_addr_offset(&ctx->out, offset, dst_x, dst_y, dst_w, dst_h);
dst_offset = rga_lookup_draw_pos(&offsets, mir_mode, rot_mode);
dst_offset = rga_lookup_draw_pos(&offsets, rot_mode, mir_mode);
dest[(RGA_DST_Y_RGB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] =
dst_offset->y_off;

View File

@@ -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));

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -161,9 +161,15 @@ static const struct visl_ctrl_desc visl_h264_ctrl_descs[] = {
},
{
.cfg.id = V4L2_CID_STATELESS_H264_DECODE_MODE,
.cfg.min = V4L2_STATELESS_H264_DECODE_MODE_SLICE_BASED,
.cfg.max = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
.cfg.def = V4L2_STATELESS_H264_DECODE_MODE_SLICE_BASED,
},
{
.cfg.id = V4L2_CID_STATELESS_H264_START_CODE,
.cfg.min = V4L2_STATELESS_H264_START_CODE_NONE,
.cfg.max = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
.cfg.def = V4L2_STATELESS_H264_START_CODE_NONE,
},
{
.cfg.id = V4L2_CID_STATELESS_H264_SLICE_PARAMS,
@@ -198,9 +204,15 @@ static const struct visl_ctrl_desc visl_hevc_ctrl_descs[] = {
},
{
.cfg.id = V4L2_CID_STATELESS_HEVC_DECODE_MODE,
.cfg.min = V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED,
.cfg.max = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
.cfg.def = V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED,
},
{
.cfg.id = V4L2_CID_STATELESS_HEVC_START_CODE,
.cfg.min = V4L2_STATELESS_HEVC_START_CODE_NONE,
.cfg.max = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
.cfg.def = V4L2_STATELESS_HEVC_START_CODE_NONE,
},
{
.cfg.id = V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS,

View File

@@ -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);

View File

@@ -162,7 +162,7 @@ static int kb3930_probe(struct i2c_client *client)
devm_gpiod_get_array_optional(dev, "off", GPIOD_IN);
if (IS_ERR(ddata->off_gpios))
return PTR_ERR(ddata->off_gpios);
if (ddata->off_gpios->ndescs < 2) {
if (ddata->off_gpios && ddata->off_gpios->ndescs < 2) {
dev_err(dev, "invalid off-gpios property\n");
return -EINVAL;
}

View File

@@ -482,10 +482,11 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
silly = MAX_LOOPS;
while (thisEUN <= inftl->lastEUN) {
inftl_read_oob(mtd, (thisEUN * inftl->EraseSize) +
blockofs, 8, &retlen, (char *)&bci);
status = bci.Status | bci.Status1;
if (inftl_read_oob(mtd, (thisEUN * inftl->EraseSize) +
blockofs, 8, &retlen, (char *)&bci) < 0)
status = SECTOR_IGNORE;
else
status = bci.Status | bci.Status1;
pr_debug("INFTL: status of block %d in EUN %d is %x\n",
block , writeEUN, status);

View File

@@ -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;
}

View File

@@ -3008,7 +3008,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;

View File

@@ -387,6 +387,9 @@ static int r852_wait(struct nand_chip *chip)
static int r852_ready(struct nand_chip *chip)
{
struct r852_device *dev = r852_get_dev(nand_to_mtd(chip));
if (dev->card_unstable)
return 0;
return !(r852_read_reg(dev, R852_CARD_STA) & R852_CARD_STA_BUSY);
}

View File

@@ -3691,6 +3691,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)
{
@@ -5144,6 +5159,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,
@@ -5193,6 +5209,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,
@@ -6154,7 +6171,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
.num_internal_phys = 2,
.internal_phys_offset = 3,
.num_gpio = 15,
.max_vid = 4095,
.max_sid = 63,
@@ -6348,7 +6366,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
.num_internal_phys = 2,
.internal_phys_offset = 3,
.num_gpio = 15,
.max_vid = 4095,
.max_sid = 63,

View File

@@ -95,6 +95,10 @@ int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int l
#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

View File

@@ -755,6 +755,7 @@ struct mt76_testmode_data {
struct mt76_vif {
u8 idx;
u8 link_idx;
u8 omac_idx;
u8 band_idx;
u8 wmm_idx;

View File

@@ -1164,7 +1164,7 @@ int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
.tag = cpu_to_le16(DEV_INFO_ACTIVE),
.len = cpu_to_le16(sizeof(struct req_tlv)),
.active = enable,
.link_idx = mvif->idx,
.link_idx = mvif->link_idx,
},
};
struct {
@@ -1187,7 +1187,7 @@ int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
.bmc_tx_wlan_idx = cpu_to_le16(wcid->idx),
.sta_idx = cpu_to_le16(wcid->idx),
.conn_state = 1,
.link_idx = mvif->idx,
.link_idx = mvif->link_idx,
},
};
int err, idx, cmd, len;

View File

@@ -256,7 +256,7 @@ int mt7925_init_mlo_caps(struct mt792x_phy *phy)
ext_capab[0].eml_capabilities = phy->eml_cap;
ext_capab[0].mld_capa_and_ops =
u16_encode_bits(1, IEEE80211_MLD_CAP_OP_MAX_SIMUL_LINKS);
u16_encode_bits(0, IEEE80211_MLD_CAP_OP_MAX_SIMUL_LINKS);
wiphy->flags |= WIPHY_FLAG_SUPPORTS_MLO;
wiphy->iftype_ext_capab = ext_capab;
@@ -356,10 +356,15 @@ static int mt7925_mac_link_bss_add(struct mt792x_dev *dev,
struct mt76_txq *mtxq;
int idx, ret = 0;
mconf->mt76.idx = __ffs64(~dev->mt76.vif_mask);
if (mconf->mt76.idx >= MT792x_MAX_INTERFACES) {
ret = -ENOSPC;
goto out;
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
mconf->mt76.idx = MT792x_MAX_INTERFACES;
} else {
mconf->mt76.idx = __ffs64(~dev->mt76.vif_mask);
if (mconf->mt76.idx >= MT792x_MAX_INTERFACES) {
ret = -ENOSPC;
goto out;
}
}
mconf->mt76.omac_idx = ieee80211_vif_is_mld(vif) ?
@@ -367,6 +372,7 @@ static int mt7925_mac_link_bss_add(struct mt792x_dev *dev,
mconf->mt76.band_idx = 0xff;
mconf->mt76.wmm_idx = ieee80211_vif_is_mld(vif) ?
0 : mconf->mt76.idx % MT76_CONNAC_MAX_WMM_SETS;
mconf->mt76.link_idx = hweight16(mvif->valid_links);
if (mvif->phy->mt76->chandef.chan->band != NL80211_BAND_2GHZ)
mconf->mt76.basic_rates_idx = MT792x_BASIC_RATES_TBL + 4;

View File

@@ -3119,13 +3119,14 @@ __mt7925_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,
.env = env_cap,
};
int ret, valid_cnt = 0;
u8 i, *pos;
u8 *pos, *last_pos;
if (!clc)
return 0;
pos = clc->data + sizeof(*seg) * clc->nr_seg;
for (i = 0; i < clc->nr_country; i++) {
last_pos = clc->data + le32_to_cpu(*(__le32 *)(clc->data + 4));
while (pos < last_pos) {
struct mt7925_clc_rule *rule = (struct mt7925_clc_rule *)pos;
pos += sizeof(*rule);

View File

@@ -566,8 +566,8 @@ struct mt7925_wow_pattern_tlv {
u8 offset;
u8 mask[MT76_CONNAC_WOW_MASK_MAX_LEN];
u8 pattern[MT76_CONNAC_WOW_PATTEN_MAX_LEN];
u8 rsv[7];
} __packed;
u8 rsv[4];
};
struct roc_acquire_tlv {
__le16 tag;

View File

@@ -131,6 +131,8 @@ static int exynos_chipid_probe(struct platform_device *pdev)
soc_dev_attr->revision = devm_kasprintf(&pdev->dev, GFP_KERNEL,
"%x", soc_info.revision);
if (!soc_dev_attr->revision)
return -ENOMEM;
soc_dev_attr->soc_id = product_id_to_soc_id(soc_info.product_id);
if (!soc_dev_attr->soc_id) {
pr_err("Unknown SoC\n");

View File

@@ -1634,6 +1634,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);

View File

@@ -190,9 +190,12 @@ again:
klm->bcount = cpu_to_be32(klm_bcount(dmr->end - dmr->start));
preve = dmr->end;
} else {
u64 bcount = min_t(u64, dmr->start - preve, MAX_KLM_SIZE);
klm->key = cpu_to_be32(mvdev->res.null_mkey);
klm->bcount = cpu_to_be32(klm_bcount(dmr->start - preve));
preve = dmr->start;
klm->bcount = cpu_to_be32(klm_bcount(bcount));
preve += bcount;
goto again;
}
}

View File

@@ -229,8 +229,11 @@ static void led_bl_remove(struct platform_device *pdev)
backlight_device_unregister(bl);
led_bl_power_off(priv);
for (i = 0; i < priv->nb_leds; i++)
for (i = 0; i < priv->nb_leds; i++) {
mutex_lock(&priv->leds[i]->led_access);
led_sysfs_enable(priv->leds[i]);
mutex_unlock(&priv->leds[i]->led_access);
}
}
static const struct of_device_id led_bl_of_match[] = {

View File

@@ -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 = m->private;
xs->op.u.symdata.symnum = ++(*pos);
*pos = xs->op.u.symdata.symnum;
if (xensyms_next_sym(xs))
return NULL;

View File

@@ -4274,6 +4274,18 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)
*/
btrfs_flush_workqueue(fs_info->delalloc_workers);
/*
* When finishing a compressed write bio we schedule a work queue item
* to finish an ordered extent - btrfs_finish_compressed_write_work()
* calls btrfs_finish_ordered_extent() which in turns does a call to
* btrfs_queue_ordered_fn(), and that queues the ordered extent
* completion either in the endio_write_workers work queue or in the
* fs_info->endio_freespace_worker work queue. We flush those queues
* below, so before we flush them we must flush this queue for the
* workers of compressed writes.
*/
flush_workqueue(fs_info->compressed_write_workers);
/*
* After we parked the cleaner kthread, ordered extents may have
* completed and created new delayed iputs. If one of the async reclaim

View File

@@ -1045,6 +1045,7 @@ static int test_rmap_block(struct btrfs_fs_info *fs_info,
ret = btrfs_add_chunk_map(fs_info, map);
if (ret) {
test_err("error adding chunk map to mapping tree");
btrfs_free_chunk_map(map);
goto out_free;
}

View File

@@ -2107,6 +2107,9 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group)
physical = map->stripes[i].physical;
zinfo = device->zone_info;
if (!device->bdev)
continue;
if (zinfo->max_active_zones == 0)
continue;
@@ -2268,6 +2271,9 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
struct btrfs_zoned_device_info *zinfo = device->zone_info;
unsigned int nofs_flags;
if (!device->bdev)
continue;
if (zinfo->max_active_zones == 0)
continue;

View File

@@ -1995,7 +1995,7 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
* split it in half by count; each resulting block will have at least
* half the space free.
*/
if (i > 0)
if (i >= 0)
split = count - move;
else
split = count/2;

View File

@@ -1884,7 +1884,6 @@ int jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid,
/* Log is no longer empty */
write_lock(&journal->j_state_lock);
WARN_ON(!sb->s_sequence);
journal->j_flags &= ~JBD2_FLUSHED;
write_unlock(&journal->j_state_lock);

View File

@@ -2474,6 +2474,8 @@ static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
return 0;
if (tcon->nodelete != ctx->nodelete)
return 0;
if (tcon->posix_extensions != ctx->linux_ext)
return 0;
return 1;
}

View File

@@ -810,6 +810,7 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map)
}
map->oflags = UDF_BLK_MAPPED;
map->pblk = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
ret = 0;
goto out_free;
}

View File

@@ -1221,21 +1221,6 @@ unsigned long hid_lookup_quirk(const struct hid_device *hdev);
int hid_quirks_init(char **quirks_param, __u16 bus, int count);
void hid_quirks_exit(__u16 bus);
#ifdef CONFIG_HID_PID
int hid_pidff_init(struct hid_device *hid);
int hid_pidff_init_with_quirks(struct hid_device *hid, __u32 initial_quirks);
#else
#define hid_pidff_init NULL
#define hid_pidff_init_with_quirks NULL
#endif
/* HID PIDFF quirks */
#define HID_PIDFF_QUIRK_MISSING_DELAY BIT(0)
#define HID_PIDFF_QUIRK_MISSING_PBO BIT(1)
#define HID_PIDFF_QUIRK_PERMISSIVE_CONTROL BIT(2)
#define HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION BIT(3)
#define HID_PIDFF_QUIRK_PERIODIC_SINE_ONLY BIT(4)
#define dbg_hid(fmt, ...) pr_debug("%s: " fmt, __FILE__, ##__VA_ARGS__)
#define hid_err(hid, fmt, ...) \

View File

@@ -457,6 +457,7 @@ enum {
REQ_F_SKIP_LINK_CQES_BIT,
REQ_F_SINGLE_POLL_BIT,
REQ_F_DOUBLE_POLL_BIT,
REQ_F_MULTISHOT_BIT,
REQ_F_APOLL_MULTISHOT_BIT,
REQ_F_CLEAR_POLLIN_BIT,
REQ_F_HASH_LOCKED_BIT,
@@ -530,6 +531,8 @@ enum {
REQ_F_SINGLE_POLL = IO_REQ_FLAG(REQ_F_SINGLE_POLL_BIT),
/* double poll may active */
REQ_F_DOUBLE_POLL = IO_REQ_FLAG(REQ_F_DOUBLE_POLL_BIT),
/* request posts multiple completions, should be set at prep time */
REQ_F_MULTISHOT = IO_REQ_FLAG(REQ_F_MULTISHOT_BIT),
/* fast poll multishot mode */
REQ_F_APOLL_MULTISHOT = IO_REQ_FLAG(REQ_F_APOLL_MULTISHOT_BIT),
/* recvmsg special flag, clear EPOLLIN */

View File

@@ -1528,7 +1528,7 @@ enum rksip1_ext_param_buffer_version {
* The expected memory layout of the parameters buffer is::
*
* +-------------------- struct rkisp1_ext_params_cfg -------------------+
* | version = RKISP_EXT_PARAMS_BUFFER_V1; |
* | version = RKISP1_EXT_PARAM_BUFFER_V1; |
* | data_size = sizeof(struct rkisp1_ext_params_bls_config) |
* | + sizeof(struct rkisp1_ext_params_dpcc_config); |
* | +------------------------- data ---------------------------------+ |

View File

@@ -1821,7 +1821,7 @@ fail:
* Don't allow any multishot execution from io-wq. It's more restrictive
* than necessary and also cleaner.
*/
if (req->flags & REQ_F_APOLL_MULTISHOT) {
if (req->flags & (REQ_F_MULTISHOT|REQ_F_APOLL_MULTISHOT)) {
err = -EBADFD;
if (!io_file_can_poll(req))
goto fail;
@@ -1832,7 +1832,7 @@ fail:
goto fail;
return;
} else {
req->flags &= ~REQ_F_APOLL_MULTISHOT;
req->flags &= ~(REQ_F_APOLL_MULTISHOT|REQ_F_MULTISHOT);
}
}

View File

@@ -484,6 +484,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))

View File

@@ -435,6 +435,7 @@ int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
sr->msg_flags |= MSG_WAITALL;
sr->buf_group = req->buf_index;
req->buf_list = NULL;
req->flags |= REQ_F_MULTISHOT;
}
#ifdef CONFIG_COMPAT
@@ -1616,6 +1617,8 @@ retry:
}
io_req_set_res(req, ret, cflags);
if (!(issue_flags & IO_URING_F_MULTISHOT))
return IOU_OK;
return IOU_STOP_MULTISHOT;
}

View File

@@ -6223,6 +6223,9 @@ static void zap_class(struct pending_free *pf, struct lock_class *class)
hlist_del_rcu(&class->hash_entry);
WRITE_ONCE(class->key, NULL);
WRITE_ONCE(class->name, NULL);
/* Class allocated but not used, -1 in nr_unused_locks */
if (class->usage_mask == 0)
debug_atomic_dec(nr_unused_locks);
nr_lock_classes--;
__clear_bit(class - lock_classes, lock_classes_in_use);
if (class - lock_classes == max_lock_class_idx)

View File

@@ -88,8 +88,6 @@ static void sg_split_phys(struct sg_splitter *splitters, const int nb_splits)
if (!j) {
out_sg->offset += split->skip_sg0;
out_sg->length -= split->skip_sg0;
} else {
out_sg->offset = 0;
}
sg_dma_address(out_sg) = 0;
sg_dma_len(out_sg) = 0;

View File

@@ -367,6 +367,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
*
@@ -458,8 +464,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;
}
@@ -533,8 +539,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);

View File

@@ -1419,6 +1419,12 @@ static int mptcp_getsockopt_v4(struct mptcp_sock *msk, int optname,
switch (optname) {
case IP_TOS:
return mptcp_put_int_option(msk, optval, optlen, READ_ONCE(inet_sk(sk)->tos));
case IP_FREEBIND:
return mptcp_put_int_option(msk, optval, optlen,
inet_test_bit(FREEBIND, sk));
case IP_TRANSPARENT:
return mptcp_put_int_option(msk, optval, optlen,
inet_test_bit(TRANSPARENT, sk));
case IP_BIND_ADDRESS_NO_PORT:
return mptcp_put_int_option(msk, optval, optlen,
inet_test_bit(BIND_ADDRESS_NO_PORT, sk));
@@ -1430,6 +1436,26 @@ 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);
case IPV6_TRANSPARENT:
return mptcp_put_int_option(msk, optval, optlen,
inet_test_bit(TRANSPARENT, sk));
case IPV6_FREEBIND:
return mptcp_put_int_option(msk, optval, optlen,
inet_test_bit(FREEBIND, sk));
}
return -EOPNOTSUPP;
}
static int mptcp_getsockopt_sol_mptcp(struct mptcp_sock *msk, int optname,
char __user *optval, int __user *optlen)
{
@@ -1469,6 +1495,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)

View File

@@ -754,8 +754,6 @@ static bool subflow_hmac_valid(const struct request_sock *req,
subflow_req = mptcp_subflow_rsk(req);
msk = subflow_req->msk;
if (!msk)
return false;
subflow_generate_hmac(READ_ONCE(msk->remote_key),
READ_ONCE(msk->local_key),
@@ -853,12 +851,8 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
} else if (subflow_req->mp_join) {
mptcp_get_options(skb, &mp_opt);
if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK) ||
!subflow_hmac_valid(req, &mp_opt) ||
!mptcp_can_accept_new_subflow(subflow_req->msk)) {
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK))
fallback = true;
}
}
create_child:
@@ -908,6 +902,17 @@ create_child:
goto dispose_child;
}
if (!subflow_hmac_valid(req, &mp_opt)) {
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
goto dispose_child;
}
if (!mptcp_can_accept_new_subflow(owner)) {
subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
goto dispose_child;
}
/* move the msk reference ownership to the subflow */
subflow_req->msk = NULL;
ctx->conn = (struct sock *)owner;

View File

@@ -621,7 +621,8 @@ static void __svc_rdma_free(struct work_struct *work)
/* Destroy the CM ID */
rdma_destroy_id(rdma->sc_cm_id);
rpcrdma_rn_unregister(device, &rdma->sc_rn);
if (!test_bit(XPT_LISTENER, &rdma->sc_xprt.xpt_flags))
rpcrdma_rn_unregister(device, &rdma->sc_rn);
kfree(rdma);
}

View File

@@ -282,6 +282,11 @@ ARGIND == 2 && !anchor && NF == 2 && $1 ~ /^0x/ && $2 !~ /^0x/ {
# section.
#
ARGIND == 2 && sect && NF == 4 && /^ [^ \*]/ && !($1 in sect_addend) {
# There are a few sections with constant data (without symbols) that
# can get resized during linking, so it is best to ignore them.
if ($1 ~ /^\.rodata\.(cst|str)[0-9]/)
next;
if (!($1 in sect_base)) {
sect_base[$1] = base;

View File

@@ -181,7 +181,8 @@ struct ima_kexec_hdr {
#define IMA_UPDATE_XATTR 1
#define IMA_CHANGE_ATTR 2
#define IMA_DIGSIG 3
#define IMA_MUST_MEASURE 4
#define IMA_MAY_EMIT_TOMTOU 4
#define IMA_EMITTED_OPENWRITERS 5
/* IMA integrity metadata associated with an inode */
struct ima_iint_cache {

View File

@@ -129,16 +129,22 @@ static void ima_rdwr_violation_check(struct file *file,
if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) {
if (!iint)
iint = ima_iint_find(inode);
/* IMA_MEASURE is set from reader side */
if (iint && test_bit(IMA_MUST_MEASURE,
&iint->atomic_flags))
if (iint && test_and_clear_bit(IMA_MAY_EMIT_TOMTOU,
&iint->atomic_flags))
send_tomtou = true;
}
} else {
if (must_measure)
set_bit(IMA_MUST_MEASURE, &iint->atomic_flags);
if (inode_is_open_for_write(inode) && must_measure)
send_writers = true;
set_bit(IMA_MAY_EMIT_TOMTOU, &iint->atomic_flags);
/* Limit number of open_writers violations */
if (inode_is_open_for_write(inode) && must_measure) {
if (!test_and_set_bit(IMA_EMITTED_OPENWRITERS,
&iint->atomic_flags))
send_writers = true;
}
}
if (!send_tomtou && !send_writers)
@@ -167,6 +173,8 @@ static void ima_check_last_writer(struct ima_iint_cache *iint,
if (atomic_read(&inode->i_writecount) == 1) {
struct kstat stat;
clear_bit(IMA_EMITTED_OPENWRITERS, &iint->atomic_flags);
update = test_and_clear_bit(IMA_UPDATE_XATTR,
&iint->atomic_flags);
if ((iint->flags & IMA_NEW_FILE) ||

View File

@@ -4744,6 +4744,22 @@ static void alc245_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
}
}
static void alc245_fixup_hp_mute_led_v1_coefbit(struct hda_codec *codec,
const struct hda_fixup *fix,
int action)
{
struct alc_spec *spec = codec->spec;
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
spec->mute_led_polarity = 0;
spec->mute_led_coef.idx = 0x0b;
spec->mute_led_coef.mask = 1 << 3;
spec->mute_led_coef.on = 1 << 3;
spec->mute_led_coef.off = 0;
snd_hda_gen_add_mute_led_cdev(codec, coef_mute_led_set);
}
}
/* turn on/off mic-mute LED per capture hook by coef bit */
static int coef_micmute_led_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
@@ -7851,6 +7867,7 @@ enum {
ALC287_FIXUP_TAS2781_I2C,
ALC287_FIXUP_YOGA7_14ARB7_I2C,
ALC245_FIXUP_HP_MUTE_LED_COEFBIT,
ALC245_FIXUP_HP_MUTE_LED_V1_COEFBIT,
ALC245_FIXUP_HP_X360_MUTE_LEDS,
ALC287_FIXUP_THINKPAD_I2S_SPK,
ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD,
@@ -10084,6 +10101,10 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc245_fixup_hp_mute_led_coefbit,
},
[ALC245_FIXUP_HP_MUTE_LED_V1_COEFBIT] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc245_fixup_hp_mute_led_v1_coefbit,
},
[ALC245_FIXUP_HP_X360_MUTE_LEDS] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc245_fixup_hp_mute_led_coefbit,
@@ -10569,6 +10590,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8b97, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
SND_PCI_QUIRK(0x103c, 0x8bb3, "HP Slim OMEN", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8bb4, "HP Slim OMEN", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8bcd, "HP Omen 16-xd0xxx", ALC245_FIXUP_HP_MUTE_LED_V1_COEFBIT),
SND_PCI_QUIRK(0x103c, 0x8bdd, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8bde, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8bdf, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),

View File

@@ -2564,6 +2564,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component)
ARRAY_SIZE(wcd9375_dapm_widgets));
if (ret < 0) {
dev_err(component->dev, "Failed to add snd_ctls\n");
wcd_clsh_ctrl_free(wcd937x->clsh_info);
return ret;
}
@@ -2571,6 +2572,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component)
ARRAY_SIZE(wcd9375_audio_map));
if (ret < 0) {
dev_err(component->dev, "Failed to add routes\n");
wcd_clsh_ctrl_free(wcd937x->clsh_info);
return ret;
}
}

View File

@@ -24,8 +24,8 @@
#define PLAYBACK_MIN_PERIOD_SIZE 128
#define CAPTURE_MIN_NUM_PERIODS 2
#define CAPTURE_MAX_NUM_PERIODS 8
#define CAPTURE_MAX_PERIOD_SIZE 4096
#define CAPTURE_MIN_PERIOD_SIZE 320
#define CAPTURE_MAX_PERIOD_SIZE 65536
#define CAPTURE_MIN_PERIOD_SIZE 6144
#define BUFFER_BYTES_MAX (PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE)
#define BUFFER_BYTES_MIN (PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE)
#define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024)
@@ -64,12 +64,12 @@ struct q6apm_dai_rtd {
phys_addr_t phys;
unsigned int pcm_size;
unsigned int pcm_count;
unsigned int pos; /* Buffer position */
unsigned int periods;
unsigned int bytes_sent;
unsigned int bytes_received;
unsigned int copied_total;
uint16_t bits_per_sample;
snd_pcm_uframes_t queue_ptr;
bool next_track;
enum stream_state state;
struct q6apm_graph *graph;
@@ -123,25 +123,16 @@ static void event_handler(uint32_t opcode, uint32_t token, void *payload, void *
{
struct q6apm_dai_rtd *prtd = priv;
struct snd_pcm_substream *substream = prtd->substream;
unsigned long flags;
switch (opcode) {
case APM_CLIENT_EVENT_CMD_EOS_DONE:
prtd->state = Q6APM_STREAM_STOPPED;
break;
case APM_CLIENT_EVENT_DATA_WRITE_DONE:
spin_lock_irqsave(&prtd->lock, flags);
prtd->pos += prtd->pcm_count;
spin_unlock_irqrestore(&prtd->lock, flags);
snd_pcm_period_elapsed(substream);
if (prtd->state == Q6APM_STREAM_RUNNING)
q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, 0);
break;
case APM_CLIENT_EVENT_DATA_READ_DONE:
spin_lock_irqsave(&prtd->lock, flags);
prtd->pos += prtd->pcm_count;
spin_unlock_irqrestore(&prtd->lock, flags);
snd_pcm_period_elapsed(substream);
if (prtd->state == Q6APM_STREAM_RUNNING)
q6apm_read(prtd->graph);
@@ -248,7 +239,6 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
}
prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
prtd->pos = 0;
/* rate and channels are sent to audio driver */
ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg);
if (ret < 0) {
@@ -294,6 +284,27 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
return 0;
}
static int q6apm_dai_ack(struct snd_soc_component *component, struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct q6apm_dai_rtd *prtd = runtime->private_data;
int i, ret = 0, avail_periods;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
avail_periods = (runtime->control->appl_ptr - prtd->queue_ptr)/runtime->period_size;
for (i = 0; i < avail_periods; i++) {
ret = q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, NO_TIMESTAMP);
if (ret < 0) {
dev_err(component->dev, "Error queuing playback buffer %d\n", ret);
return ret;
}
prtd->queue_ptr += runtime->period_size;
}
}
return ret;
}
static int q6apm_dai_trigger(struct snd_soc_component *component,
struct snd_pcm_substream *substream, int cmd)
{
@@ -305,9 +316,6 @@ static int q6apm_dai_trigger(struct snd_soc_component *component,
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
/* start writing buffers for playback only as we already queued capture buffers */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
ret = q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, 0);
break;
case SNDRV_PCM_TRIGGER_STOP:
/* TODO support be handled via SoftPause Module */
@@ -377,13 +385,14 @@ static int q6apm_dai_open(struct snd_soc_component *component,
}
}
ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
/* setup 10ms latency to accommodate DSP restrictions */
ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 480);
if (ret < 0) {
dev_err(dev, "constraint for period bytes step ret = %d\n", ret);
goto err;
}
ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 480);
if (ret < 0) {
dev_err(dev, "constraint for buffer bytes step ret = %d\n", ret);
goto err;
@@ -428,16 +437,12 @@ static snd_pcm_uframes_t q6apm_dai_pointer(struct snd_soc_component *component,
struct snd_pcm_runtime *runtime = substream->runtime;
struct q6apm_dai_rtd *prtd = runtime->private_data;
snd_pcm_uframes_t ptr;
unsigned long flags;
spin_lock_irqsave(&prtd->lock, flags);
if (prtd->pos == prtd->pcm_size)
prtd->pos = 0;
ptr = q6apm_get_hw_pointer(prtd->graph, substream->stream) * runtime->period_size;
if (ptr)
return ptr - 1;
ptr = bytes_to_frames(runtime, prtd->pos);
spin_unlock_irqrestore(&prtd->lock, flags);
return ptr;
return 0;
}
static int q6apm_dai_hw_params(struct snd_soc_component *component,
@@ -652,8 +657,6 @@ static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
prtd->pcm_size = runtime->fragments * runtime->fragment_size;
prtd->bits_per_sample = 16;
prtd->pos = 0;
if (prtd->next_track != true) {
memcpy(&prtd->codec, codec, sizeof(*codec));
@@ -836,6 +839,7 @@ static const struct snd_soc_component_driver q6apm_fe_dai_component = {
.hw_params = q6apm_dai_hw_params,
.pointer = q6apm_dai_pointer,
.trigger = q6apm_dai_trigger,
.ack = q6apm_dai_ack,
.compress_ops = &q6apm_dai_compress_ops,
.use_dai_pcm_id = true,
};

View File

@@ -494,6 +494,19 @@ int q6apm_read(struct q6apm_graph *graph)
}
EXPORT_SYMBOL_GPL(q6apm_read);
int q6apm_get_hw_pointer(struct q6apm_graph *graph, int dir)
{
struct audioreach_graph_data *data;
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
data = &graph->rx_data;
else
data = &graph->tx_data;
return (int)atomic_read(&data->hw_ptr);
}
EXPORT_SYMBOL_GPL(q6apm_get_hw_pointer);
static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op)
{
struct data_cmd_rsp_rd_sh_mem_ep_data_buffer_done_v2 *rd_done;
@@ -520,7 +533,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op)
done = data->payload;
phys = graph->rx_data.buf[token].phys;
mutex_unlock(&graph->lock);
/* token numbering starts at 0 */
atomic_set(&graph->rx_data.hw_ptr, token + 1);
if (lower_32_bits(phys) == done->buf_addr_lsw &&
upper_32_bits(phys) == done->buf_addr_msw) {
graph->result.opcode = hdr->opcode;
@@ -553,6 +567,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op)
rd_done = data->payload;
phys = graph->tx_data.buf[hdr->token].phys;
mutex_unlock(&graph->lock);
/* token numbering starts at 0 */
atomic_set(&graph->tx_data.hw_ptr, hdr->token + 1);
if (upper_32_bits(phys) == rd_done->buf_addr_msw &&
lower_32_bits(phys) == rd_done->buf_addr_lsw) {

View File

@@ -2,6 +2,7 @@
#ifndef __Q6APM_H__
#define __Q6APM_H__
#include <linux/types.h>
#include <linux/atomic.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/kernel.h>
@@ -77,6 +78,7 @@ struct audioreach_graph_data {
uint32_t num_periods;
uint32_t dsp_buf;
uint32_t mem_map_handle;
atomic_t hw_ptr;
};
struct audioreach_graph {
@@ -150,4 +152,5 @@ int q6apm_enable_compress_module(struct device *dev, struct q6apm_graph *graph,
int q6apm_remove_initial_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples);
int q6apm_remove_trailing_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples);
int q6apm_set_real_module_id(struct device *dev, struct q6apm_graph *graph, uint32_t codec_id);
int q6apm_get_hw_pointer(struct q6apm_graph *graph, int dir);
#endif /* __APM_GRAPH_ */

Some files were not shown because too many files have changed in this diff Show More