Merge tag 'LA.UM.9.14.r1-25800-LAHAINA.QSSI15.0' of https://git.codelinaro.org/clo/la/kernel/msm-5.4 into android13-5.4-lahaina
"LA.UM.9.14.r1-25800-LAHAINA.QSSI15.0" * tag 'LA.UM.9.14.r1-25800-LAHAINA.QSSI15.0' of https://git.codelinaro.org/clo/la/kernel/msm-5.4: msm: eva: Validating the SFR buffer size before accessing msm: eva: Copy back the validated size to avoid security issue msm: npu: Fix use after free issue USB: dwc3: gadget: Add stop transfer request for isoc transfers arm64: defconfig: Enable uvc for QCM6490 IOT target firmware: qcom_scm: do not clear dump mode from shutdown msm: virtio_npu: Fix use-after-free issue in unmap_buf msm: virtio_npu: Fix use-after-free issue in virt_npu_map_buf i2c: i2c-master-msm-geni: add null pointer check in event call back firmware: qcom_scm: handle echo b > /proc/sysrq-trigger scripts: mod: replace with a safe function msm: ep_pcie: Disable hot reset and ignore linkdown coresight-tmc: Replace deprecated function USB: dwc3: gadget: Queue data for 16 micro frames ahead in future power: reset: Disable support of dynamic download mode (ramdump) Conflicts: arch/arm64/boot/dts/vendor/bindings/sound/rt5645.txt Change-Id: I57c063465c2804c77c5a6f62acb6c7987a38bc7f
This commit is contained in:
commit
b964d75b7e
19 changed files with 44962 additions and 44764 deletions
|
|
@ -1 +1 @@
|
|||
LTS_5.4.274_564901bd7f5d
|
||||
LTS_5.4.281_d62984adb112
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -216,7 +216,14 @@ CONFIG_HID_WIIMOTE=y
|
|||
CONFIG_USB_DUMMY_HCD=y
|
||||
CONFIG_USB_CONFIGFS_ACM=y
|
||||
# CONFIG_USB_CONFIGFS_RNDIS is not set
|
||||
CONFIG_USB_CONFIGFS_F_UVC=y
|
||||
CONFIG_USB_CONFIGFS_F_HID=y
|
||||
CONFIG_USB_LIBCOMPOSITE=y
|
||||
CONFIG_VIDEOBUF2_VMALLOC=y
|
||||
CONFIG_USB_F_UVC=y
|
||||
CONFIG_USB_G_WEBCAM=m
|
||||
CONFIG_USB_CONFIGFS=y
|
||||
CONFIG_USB_CONFIGFS_F_UVC=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EROFS_FS=y
|
||||
# CONFIG_SERIAL_MSM_GENI_EARLY_CONSOLE is not set
|
||||
|
|
|
|||
|
|
@ -1248,8 +1248,6 @@ static void qcom_scm_shutdown(struct platform_device *pdev)
|
|||
{
|
||||
qcom_scm_disable_sdi();
|
||||
qcom_scm_halt_spmi_pmic_arbiter();
|
||||
/* Clean shutdown, disable download mode to allow normal restart */
|
||||
qcom_scm_set_download_mode(QCOM_DOWNLOAD_NODUMP, 0);
|
||||
}
|
||||
|
||||
static const struct of_device_id qcom_scm_dt_match[] = {
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ static ssize_t trigger_cntr_show(struct device *dev,
|
|||
struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
|
||||
unsigned long val = drvdata->trigger_cntr;
|
||||
|
||||
return sprintf(buf, "%#lx\n", val);
|
||||
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
|
||||
}
|
||||
|
||||
static ssize_t trigger_cntr_store(struct device *dev,
|
||||
|
|
@ -329,7 +329,7 @@ static ssize_t buffer_size_show(struct device *dev,
|
|||
{
|
||||
struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
|
||||
|
||||
return sprintf(buf, "%#x\n", drvdata->size);
|
||||
return scnprintf(buf, PAGE_SIZE, "%#x\n", drvdata->size);
|
||||
}
|
||||
|
||||
static ssize_t buffer_size_store(struct device *dev,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
|
|
@ -452,8 +452,16 @@ irqret:
|
|||
static void gi2c_ev_cb(struct dma_chan *ch, struct msm_gpi_cb const *cb_str,
|
||||
void *ptr)
|
||||
{
|
||||
struct geni_i2c_dev *gi2c = ptr;
|
||||
u32 m_stat = cb_str->status;
|
||||
struct geni_i2c_dev *gi2c;
|
||||
u32 m_stat;
|
||||
|
||||
if (!ptr || !cb_str) {
|
||||
pr_err("%s: Invalid ev_cb buffer\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
gi2c = (struct geni_i2c_dev *)ptr;
|
||||
m_stat = cb_str->status;
|
||||
|
||||
switch (cb_str->cb_event) {
|
||||
case MSM_GPI_QUP_ERROR:
|
||||
|
|
|
|||
|
|
@ -717,7 +717,7 @@ static int __read_queue(struct cvp_iface_q_info *qinfo, u8 *packet,
|
|||
u32 *read_ptr;
|
||||
u32 receive_request = 0;
|
||||
u32 read_idx, write_idx;
|
||||
int rc = 0;
|
||||
int rc = 0;
|
||||
|
||||
if (!qinfo || !packet || !pb_tx_req_is_set) {
|
||||
dprintk(CVP_ERR, "Invalid Params\n");
|
||||
|
|
@ -807,6 +807,12 @@ static int __read_queue(struct cvp_iface_q_info *qinfo, u8 *packet,
|
|||
(u8 *)qinfo->q_array.align_virtual_addr,
|
||||
new_read_idx << 2);
|
||||
}
|
||||
/*
|
||||
* Copy back the validated size to avoid security issue. As we are reading
|
||||
* the packet from a shared queue, there is a possibility to get the
|
||||
* packet->size data corrupted of shared queue by mallicious FW.
|
||||
*/
|
||||
*((u32 *) packet) = packet_size_in_words << 2;
|
||||
} else {
|
||||
dprintk(CVP_WARN,
|
||||
"BAD packet received, read_idx: %#x, pkt_size: %d\n",
|
||||
|
|
@ -2757,17 +2763,19 @@ skip_power_off:
|
|||
static void __process_sys_error(struct iris_hfi_device *device)
|
||||
{
|
||||
struct cvp_hfi_sfr_struct *vsfr = NULL;
|
||||
u32 sfr_buf_size = 0;
|
||||
|
||||
vsfr = (struct cvp_hfi_sfr_struct *)device->sfr.align_virtual_addr;
|
||||
if (vsfr) {
|
||||
void *p = memchr(vsfr->rg_data, '\0', vsfr->bufSize);
|
||||
sfr_buf_size = vsfr->bufSize;
|
||||
if (vsfr && sfr_buf_size < ALIGNED_SFR_SIZE) {
|
||||
void *p = memchr(vsfr->rg_data, '\0', sfr_buf_size);
|
||||
/*
|
||||
* SFR isn't guaranteed to be NULL terminated
|
||||
* since SYS_ERROR indicates that Iris is in the
|
||||
* process of crashing.
|
||||
*/
|
||||
if (p == NULL)
|
||||
vsfr->rg_data[vsfr->bufSize - 1] = '\0';
|
||||
vsfr->rg_data[sfr_buf_size - 1] = '\0';
|
||||
|
||||
dprintk(CVP_ERR, "SFR Message from FW: %s\n",
|
||||
vsfr->rg_data);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
|
@ -1552,7 +1553,6 @@ static int npu_set_fw_state(struct npu_client *client, uint32_t enable)
|
|||
|
||||
if (host_ctx->network_num > 0) {
|
||||
pr_err("Need to unload network first\n");
|
||||
mutex_unlock(&npu_dev->dev_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
|
@ -1593,6 +1594,13 @@ int32_t npu_host_unload_network(struct npu_client *client,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (network->is_unloading) {
|
||||
pr_err("network is unloading\n");
|
||||
network_put(network);
|
||||
mutex_unlock(&host_ctx->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!network->is_active) {
|
||||
pr_err("network is not active\n");
|
||||
network_put(network);
|
||||
|
|
@ -1600,10 +1608,18 @@ int32_t npu_host_unload_network(struct npu_client *client,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (network->is_executing) {
|
||||
pr_err("network is in execution\n");
|
||||
network_put(network);
|
||||
mutex_unlock(&host_ctx->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (network->fw_error) {
|
||||
pr_err("fw in error state, skip unload network in fw\n");
|
||||
goto free_network;
|
||||
}
|
||||
network->is_unloading = true;
|
||||
|
||||
pr_debug("Unload network %lld\n", network->id);
|
||||
/* prepare IPC packet for UNLOAD */
|
||||
|
|
@ -1832,12 +1848,24 @@ int32_t npu_host_exec_network_v2(struct npu_client *client,
|
|||
if (atomic_inc_return(&host_ctx->network_execute_cnt) == 1)
|
||||
npu_notify_cdsprm_cxlimit_activity(npu_dev, true);
|
||||
|
||||
if (network->is_unloading) {
|
||||
pr_err("network is unloading\n");
|
||||
ret = -EINVAL;
|
||||
goto exec_v2_done;
|
||||
}
|
||||
|
||||
if (!network->is_active) {
|
||||
pr_err("network is not active\n");
|
||||
ret = -EINVAL;
|
||||
goto exec_v2_done;
|
||||
}
|
||||
|
||||
if (network->is_executing) {
|
||||
pr_err("network is already in execution\n");
|
||||
ret = -EINVAL;
|
||||
goto exec_v2_done;
|
||||
}
|
||||
|
||||
if (network->fw_error) {
|
||||
pr_err("fw is in error state\n");
|
||||
ret = -EIO;
|
||||
|
|
@ -1855,6 +1883,7 @@ int32_t npu_host_exec_network_v2(struct npu_client *client,
|
|||
goto exec_v2_done;
|
||||
}
|
||||
|
||||
network->is_executing = true;
|
||||
for (i = 0; i < num_patch_params; i++) {
|
||||
exec_packet->patch_params[i].id = patch_buf_info[i].buf_id;
|
||||
pr_debug("%d: patch_id: %x\n", i,
|
||||
|
|
@ -1936,6 +1965,7 @@ int32_t npu_host_exec_network_v2(struct npu_client *client,
|
|||
|
||||
free_exec_packet:
|
||||
kfree(exec_packet);
|
||||
network->is_executing = false;
|
||||
exec_v2_done:
|
||||
network_put(network);
|
||||
mutex_unlock(&host_ctx->lock);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _NPU_MGR_H
|
||||
|
|
@ -52,6 +53,8 @@ struct npu_network {
|
|||
atomic_t ref_cnt;
|
||||
bool is_valid;
|
||||
bool is_active;
|
||||
bool is_unloading;
|
||||
bool is_executing;
|
||||
bool fw_error;
|
||||
bool cmd_pending;
|
||||
bool cmd_async;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/cdev.h>
|
||||
|
|
@ -668,8 +669,10 @@ fail:
|
|||
static int32_t virt_npu_unmap_buf(struct npu_client *client,
|
||||
int buf_hdl, uint64_t iova)
|
||||
{
|
||||
struct npu_device *npu_dev = client->npu_dev;
|
||||
struct npu_ion_buf *ion_buf;
|
||||
|
||||
mutex_lock(&npu_dev->lock);
|
||||
/* clear entry and retrieve the corresponding buffer */
|
||||
ion_buf = npu_get_npu_ion_buffer(client, buf_hdl);
|
||||
if (!ion_buf) {
|
||||
|
|
@ -694,6 +697,7 @@ static int32_t virt_npu_unmap_buf(struct npu_client *client,
|
|||
NPU_DBG("unmapped mem addr:0x%llx size:0x%x\n", ion_buf->iova,
|
||||
ion_buf->size);
|
||||
npu_free_npu_ion_buffer(client, buf_hdl);
|
||||
mutex_unlock(&npu_dev->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -814,6 +818,7 @@ static int32_t virt_npu_map_buf(struct npu_client *client,
|
|||
struct npu_ion_buf *ion_buf = NULL;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&npu_dev->lock);
|
||||
ion_buf = npu_alloc_npu_ion_buffer(client, buf_hdl, size);
|
||||
if (!ion_buf) {
|
||||
NPU_ERR("fail to alloc npu_ion_buffer\n");
|
||||
|
|
@ -853,6 +858,7 @@ static int32_t virt_npu_map_buf(struct npu_client *client,
|
|||
|
||||
rc = virt_npu_mmap(client, 0, ion_buf->table->sgl,
|
||||
ion_buf->table->nents, size, &ion_buf->iova);
|
||||
mutex_unlock(&npu_dev->lock);
|
||||
|
||||
map_end:
|
||||
if (rc)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.*/
|
||||
/* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.*/
|
||||
|
||||
#ifndef __EP_PCIE_COM_H
|
||||
#define __EP_PCIE_COM_H
|
||||
|
|
@ -429,6 +430,7 @@ struct ep_pcie_dev_t {
|
|||
struct clk *pipe_clk_mux;
|
||||
struct clk *pipe_clk_ext_src;
|
||||
struct clk *ref_clk_src;
|
||||
u32 tcsr_hot_reset_en_offset;
|
||||
};
|
||||
|
||||
extern struct ep_pcie_dev_t ep_pcie_dev;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.*/
|
||||
/* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.*/
|
||||
|
||||
/*
|
||||
* MSM PCIe endpoint core driver.
|
||||
|
|
@ -37,6 +38,7 @@
|
|||
#define PCIE_MHI_STATUS(n) ((n) + 0x148)
|
||||
#define TCSR_PERST_SEPARATION_ENABLE 0x270
|
||||
#define TCSR_PCIE_RST_SEPARATION 0x3F8
|
||||
#define TCSR_HOT_RESET_EN 0x3e8
|
||||
#define PCIE_ISSUE_WAKE 1
|
||||
#define PCIE_MHI_FWD_STATUS_MIN 5000
|
||||
#define PCIE_MHI_FWD_STATUS_MAX 5100
|
||||
|
|
@ -1815,6 +1817,13 @@ int ep_pcie_core_enable_endpoint(enum ep_pcie_options opt)
|
|||
*/
|
||||
writel_relaxed(0, dev->tcsr_perst_en +
|
||||
TCSR_PERST_SEPARATION_ENABLE);
|
||||
|
||||
/*
|
||||
* Re-enable hot reset before link up since we disable it
|
||||
* in pm_turnoff irq.
|
||||
*/
|
||||
ep_pcie_write_reg_field(dev->tcsr_perst_en,
|
||||
ep_pcie_dev.tcsr_hot_reset_en_offset, BIT(0), BIT(0));
|
||||
}
|
||||
|
||||
/* check link status during initial bootup */
|
||||
|
|
@ -2280,6 +2289,10 @@ static irqreturn_t ep_pcie_handle_linkdown_irq(int irq, void *data)
|
|||
EP_PCIE_DBG(dev,
|
||||
"PCIe V%d:Linkdown IRQ happened when the link is suspending\n",
|
||||
dev->rev);
|
||||
} else if (dev->link_status == EP_PCIE_LINK_IN_L23READY) {
|
||||
EP_PCIE_DBG(dev,
|
||||
"PCIe V%d:Linkdown IRQ happened when link goes to l23ready\n",
|
||||
dev->rev);
|
||||
} else {
|
||||
dev->link_status = EP_PCIE_LINK_DISABLED;
|
||||
EP_PCIE_ERR(dev, "PCIe V%d:PCIe link is down for %ld times\n",
|
||||
|
|
@ -2320,13 +2333,29 @@ static irqreturn_t ep_pcie_handle_pm_turnoff_irq(int irq, void *data)
|
|||
|
||||
spin_lock_irqsave(&dev->isr_lock, irqsave_flags);
|
||||
|
||||
if (!dev->tcsr_not_supported)
|
||||
/*
|
||||
* Some hosts will try to recovery link if it doesn't receive PM_L23_Enter
|
||||
* within 10ms after sending PME turn off, in which case if Hot reset is
|
||||
* enabled, PERST# timeout circuit will start to work. If it measures that
|
||||
* the link doesn't enter L0 within a predetermined time, device will crash
|
||||
* with PERST_TIMEOUT_RESET_STATUS set to 1.
|
||||
*
|
||||
* Note that PERST# timeout circuit monitors the Detect to L0 transition and
|
||||
* it gets activated in two scenario:
|
||||
* 1) When PERST# gets de-asserted and perst-separation is enabled.
|
||||
* 2) When hot-reset is enabled and link training is initiated.
|
||||
*/
|
||||
ep_pcie_write_reg_field(dev->tcsr_perst_en,
|
||||
ep_pcie_dev.tcsr_hot_reset_en_offset, BIT(0), 0);
|
||||
|
||||
dev->pm_to_counter++;
|
||||
EP_PCIE_DBG2(dev,
|
||||
"PCIe V%d: No. %ld PM_TURNOFF is received\n",
|
||||
dev->rev, dev->pm_to_counter);
|
||||
EP_PCIE_DBG2(dev, "PCIe V%d: Put the link into L23\n", dev->rev);
|
||||
ep_pcie_write_mask(dev->parf + PCIE20_PARF_PM_CTRL, 0, BIT(2));
|
||||
|
||||
dev->link_status = EP_PCIE_LINK_IN_L23READY;
|
||||
spin_unlock_irqrestore(&dev->isr_lock, irqsave_flags);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
|
@ -2943,6 +2972,11 @@ enum ep_pcie_link_status ep_pcie_core_get_linkstatus(void)
|
|||
return EP_PCIE_LINK_DISABLED;
|
||||
}
|
||||
|
||||
if (dev->link_status == EP_PCIE_LINK_IN_L23READY) {
|
||||
EP_PCIE_DBG(dev, "PCIe V%d: PCIe endpoint has sent PM_ENTER_L23\n", dev->rev);
|
||||
return EP_PCIE_LINK_IN_L23READY;
|
||||
}
|
||||
|
||||
bme = readl_relaxed(dev->dm_core +
|
||||
PCIE20_COMMAND_STATUS) & BIT(2);
|
||||
if (bme) {
|
||||
|
|
@ -3505,6 +3539,21 @@ static int ep_pcie_probe(struct platform_device *pdev)
|
|||
EP_PCIE_DBG(&ep_pcie_dev,
|
||||
"PCIe V%d: tcsr pcie perst is %s supported\n",
|
||||
ep_pcie_dev.rev, ep_pcie_dev.tcsr_not_supported ? "not" : "");
|
||||
if (!ep_pcie_dev.tcsr_not_supported) {
|
||||
|
||||
ret = of_property_read_u32((&pdev->dev)->of_node, "qcom,tcsr-hot-reset-en-offset",
|
||||
&ep_pcie_dev.tcsr_hot_reset_en_offset);
|
||||
if (ret) {
|
||||
EP_PCIE_DBG(&ep_pcie_dev,
|
||||
"PCIe V%d: TCSR Hot Reset Enable Offset is not supplied from DT",
|
||||
ep_pcie_dev.rev);
|
||||
ep_pcie_dev.tcsr_hot_reset_en_offset = TCSR_HOT_RESET_EN;
|
||||
}
|
||||
|
||||
EP_PCIE_DBG(&ep_pcie_dev,
|
||||
"PCIe V%d: TCSR Hot Reset Enable Offset: 0x%x\n",
|
||||
ep_pcie_dev.rev, ep_pcie_dev.tcsr_hot_reset_en_offset);
|
||||
}
|
||||
|
||||
ep_pcie_dev.aoss_rst_clear = of_property_read_bool
|
||||
((&pdev->dev)->of_node,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
|
@ -24,10 +25,12 @@ enum qcom_download_dest {
|
|||
|
||||
struct qcom_dload {
|
||||
struct notifier_block panic_nb;
|
||||
struct notifier_block reboot_nb;
|
||||
struct notifier_block restart_nb;
|
||||
struct kobject kobj;
|
||||
|
||||
bool in_panic;
|
||||
bool in_reboot;
|
||||
void __iomem *dload_dest_addr;
|
||||
};
|
||||
|
||||
|
|
@ -99,7 +102,9 @@ static int param_set_download_mode(const char *val,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
msm_enable_dump_mode(true);
|
||||
msm_enable_dump_mode(enable_dump);
|
||||
if (!enable_dump)
|
||||
qcom_scm_disable_sdi();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -280,16 +285,40 @@ static int qcom_dload_panic(struct notifier_block *this, unsigned long event,
|
|||
static int qcom_dload_restart(struct notifier_block *this, unsigned long event,
|
||||
void *ptr)
|
||||
{
|
||||
char *cmd = ptr;
|
||||
|
||||
if (cmd && !strcmp(cmd, "edl")) {
|
||||
set_download_mode(QCOM_DOWNLOAD_EDL);
|
||||
reboot_mode = REBOOT_WARM;
|
||||
struct qcom_dload *poweroff = container_of(this, struct qcom_dload,
|
||||
restart_nb);
|
||||
|
||||
if (!poweroff->in_panic && !poweroff->in_reboot) {
|
||||
qcom_scm_disable_sdi();
|
||||
set_download_mode(QCOM_DOWNLOAD_NODUMP);
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int qcom_dload_reboot(struct notifier_block *this, unsigned long event,
|
||||
void *ptr)
|
||||
{
|
||||
char *cmd = ptr;
|
||||
struct qcom_dload *poweroff = container_of(this, struct qcom_dload,
|
||||
reboot_nb);
|
||||
|
||||
poweroff->in_reboot = true;
|
||||
set_download_mode(QCOM_DOWNLOAD_NODUMP);
|
||||
if (cmd) {
|
||||
if (!strcmp(cmd, "edl"))
|
||||
set_download_mode(QCOM_DOWNLOAD_EDL);
|
||||
else if (!strcmp(cmd, "qcom_dload"))
|
||||
msm_enable_dump_mode(true);
|
||||
}
|
||||
|
||||
if (current_download_mode != QCOM_DOWNLOAD_NODUMP)
|
||||
reboot_mode = REBOOT_WARM;
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static void __iomem *map_prop_mem(const char *propname)
|
||||
{
|
||||
struct device_node *np = of_find_compatible_node(NULL, NULL, propname);
|
||||
|
|
@ -394,13 +423,17 @@ static int qcom_dload_probe(struct platform_device *pdev)
|
|||
atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&poweroff->panic_nb);
|
||||
|
||||
poweroff->reboot_nb.notifier_call = qcom_dload_reboot;
|
||||
poweroff->reboot_nb.priority = 255;
|
||||
register_reboot_notifier(&poweroff->reboot_nb);
|
||||
|
||||
poweroff->restart_nb.notifier_call = qcom_dload_restart;
|
||||
/* Here, Restart handler priority should be higher than
|
||||
* of restart handler present in scm driver so that
|
||||
* reboot_mode set by this handler seen by SCM's one
|
||||
* for EDL mode.
|
||||
*/
|
||||
poweroff->restart_nb.priority = 131;
|
||||
poweroff->restart_nb.priority = 201;
|
||||
register_restart_handler(&poweroff->restart_nb);
|
||||
|
||||
platform_set_drvdata(pdev, poweroff);
|
||||
|
|
@ -414,7 +447,9 @@ static int qcom_dload_remove(struct platform_device *pdev)
|
|||
|
||||
atomic_notifier_chain_unregister(&panic_notifier_list,
|
||||
&poweroff->panic_nb);
|
||||
|
||||
unregister_restart_handler(&poweroff->restart_nb);
|
||||
unregister_reboot_notifier(&poweroff->reboot_nb);
|
||||
|
||||
if (poweroff->dload_dest_addr)
|
||||
iounmap(poweroff->dload_dest_addr);
|
||||
|
|
|
|||
|
|
@ -735,6 +735,7 @@ struct dwc3_ep_events {
|
|||
* @desc: usb_endpoint_descriptor pointer
|
||||
* @dwc: pointer to DWC controller
|
||||
* @saved_state: ep state saved during hibernation
|
||||
* @missed_isoc_packets: counter for missed packets sent
|
||||
* @flags: endpoint flags (wedged, stalled, ...)
|
||||
* @number: endpoint number (1 - 15)
|
||||
* @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK
|
||||
|
|
@ -768,6 +769,7 @@ struct dwc3_ep {
|
|||
struct dwc3 *dwc;
|
||||
|
||||
u32 saved_state;
|
||||
u32 missed_isoc_packets;
|
||||
unsigned flags;
|
||||
#define DWC3_EP_ENABLED BIT(0)
|
||||
#define DWC3_EP_STALL BIT(1)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
|
|
@ -150,10 +151,11 @@ void dwc3_dbg_dma_unmap(struct dwc3 *dwc, u8 ep_num, struct dwc3_request *req)
|
|||
req->trb->ctrl & DWC3_TRB_CTRL_HWO);
|
||||
} else {
|
||||
ipc_log_string(dwc->dwc_dma_ipc_log_ctxt,
|
||||
"%02X-%-3.3s %-25.25s 0x%pK 0x%lx %u 0x%lx %d",
|
||||
"%02X-%-3.3s %-25.25s 0x%pK 0x%lx %u 0x%lx %d %u",
|
||||
ep_num >> 1, ep_num & 1 ? "IN":"OUT", "UNMAP",
|
||||
&req->request, req->request.dma, req->request.length,
|
||||
req->trb_dma, req->trb->ctrl & DWC3_TRB_CTRL_HWO);
|
||||
req->trb_dma, req->trb->ctrl & DWC3_TRB_CTRL_HWO,
|
||||
req->request.actual);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
#define DWC3_ALIGN_FRAME(d, n) (((d)->frame_number + ((d)->interval * (n))) \
|
||||
& ~((d)->interval - 1))
|
||||
|
||||
#define DWC3_FRAME_WRAP_AROUND_MASK (BIT(14) | BIT(15))
|
||||
|
||||
static int __dwc3_gadget_start(struct dwc3 *dwc);
|
||||
static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc);
|
||||
static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc, bool remote_wakeup);
|
||||
|
|
@ -228,6 +230,11 @@ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc, struct dwc3_ep *dep)
|
|||
&& dwc3_is_usb31(dwc))
|
||||
mult = 6;
|
||||
|
||||
if ((dep->endpoint.maxburst > 6) &&
|
||||
usb_endpoint_xfer_isoc(dep->endpoint.desc))
|
||||
mult = 6;
|
||||
|
||||
|
||||
tmp = ((max_packet + mdwidth) * mult) + mdwidth;
|
||||
fifo_size = DIV_ROUND_UP(tmp, mdwidth);
|
||||
dep->fifo_depth = fifo_size;
|
||||
|
|
@ -309,6 +316,12 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
|||
dwc3_gadget_del_and_unmap_request(dep, req, status);
|
||||
req->status = DWC3_REQUEST_STATUS_COMPLETED;
|
||||
|
||||
if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
|
||||
(list_empty(&dep->started_list))) {
|
||||
dep->flags |= DWC3_EP_PENDING_REQUEST;
|
||||
dbg_event(dep->number, "STARTEDLISTEMPTY", 0);
|
||||
}
|
||||
|
||||
spin_unlock(&dwc->lock);
|
||||
usb_gadget_giveback_request(&dep->endpoint, &req->request);
|
||||
spin_lock(&dwc->lock);
|
||||
|
|
@ -984,6 +997,8 @@ static int dwc3_gadget_ep_disable(struct usb_ep *ep)
|
|||
spin_lock_irqsave(&dwc->lock, flags);
|
||||
ret = __dwc3_gadget_ep_disable(dep);
|
||||
dbg_event(dep->number, "DISABLE", ret);
|
||||
dbg_event(dep->number, "MISSEDISOCPKTS", dep->missed_isoc_packets);
|
||||
dep->missed_isoc_packets = 0;
|
||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||
|
||||
return ret;
|
||||
|
|
@ -1647,7 +1662,7 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep)
|
|||
{
|
||||
struct dwc3 *dwc = dep->dwc;
|
||||
int ret;
|
||||
int i;
|
||||
u16 wraparound_bits, uf;
|
||||
|
||||
if (list_empty(&dep->pending_list)) {
|
||||
dep->flags |= DWC3_EP_PENDING_REQUEST;
|
||||
|
|
@ -1664,12 +1679,36 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep)
|
|||
return dwc3_gadget_start_isoc_quirk(dep);
|
||||
}
|
||||
|
||||
for (i = 0; i < DWC3_ISOC_MAX_RETRIES; i++) {
|
||||
dep->frame_number = DWC3_ALIGN_FRAME(dep, i + 1);
|
||||
wraparound_bits = dep->frame_number & DWC3_FRAME_WRAP_AROUND_MASK;
|
||||
uf = dep->frame_number & ~DWC3_FRAME_WRAP_AROUND_MASK;
|
||||
|
||||
ret = __dwc3_gadget_kick_transfer(dep);
|
||||
if (ret != -EAGAIN)
|
||||
break;
|
||||
/* if frame wrapped-around update wrap-around bits to reflect that */
|
||||
if (__dwc3_gadget_get_frame(dep->dwc) < uf)
|
||||
wraparound_bits += BIT(14);
|
||||
|
||||
uf = __dwc3_gadget_get_frame(dep->dwc) + max_t(u32, 16, 2 * dep->interval);
|
||||
|
||||
/* align frame number to ep interval */
|
||||
dep->frame_number = (wraparound_bits + uf) & ~(dep->interval - 1);
|
||||
|
||||
ret = __dwc3_gadget_kick_transfer(dep);
|
||||
|
||||
if (ret == -EAGAIN) {
|
||||
struct dwc3_gadget_ep_cmd_params params;
|
||||
u32 cmd;
|
||||
|
||||
dwc3_gadget_ep_get_transfer_index(dep);
|
||||
dep->flags |= DWC3_EP_PENDING_REQUEST;
|
||||
cmd = DWC3_DEPCMD_ENDTRANSFER |
|
||||
DWC3_DEPCMD_CMDIOC |
|
||||
DWC3_DEPCMD_PARAM(dep->resource_index);
|
||||
|
||||
dep->resource_index = 0;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
|
||||
if (!ret)
|
||||
dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -1731,8 +1770,10 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
|
|||
|
||||
if ((dep->flags & DWC3_EP_PENDING_REQUEST)) {
|
||||
if (!(dep->flags & DWC3_EP_TRANSFER_STARTED)) {
|
||||
dep->flags &= ~DWC3_EP_PENDING_REQUEST;
|
||||
return __dwc3_gadget_start_isoc(dep);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3402,14 +3443,19 @@ static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep,
|
|||
if (event->status & DEPEVT_STATUS_BUSERR)
|
||||
status = -ECONNRESET;
|
||||
|
||||
dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);
|
||||
|
||||
if (event->status & DEPEVT_STATUS_MISSED_ISOC) {
|
||||
status = -EXDEV;
|
||||
|
||||
if (list_empty(&dep->started_list))
|
||||
stop = true;
|
||||
dep->missed_isoc_packets++;
|
||||
dbg_event(dep->number, "MISSEDISOC", dep->missed_isoc_packets);
|
||||
}
|
||||
|
||||
dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);
|
||||
if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
|
||||
(list_empty(&dep->started_list))) {
|
||||
stop = true;
|
||||
dbg_event(dep->number, "STOPXFER", dep->frame_number);
|
||||
}
|
||||
|
||||
if (dep->flags & DWC3_EP_END_TRANSFER_PENDING)
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ enum ep_pcie_link_status {
|
|||
EP_PCIE_LINK_DISABLED,
|
||||
EP_PCIE_LINK_UP,
|
||||
EP_PCIE_LINK_ENABLED,
|
||||
EP_PCIE_LINK_IN_L23READY,
|
||||
};
|
||||
|
||||
enum ep_pcie_event {
|
||||
|
|
|
|||
|
|
@ -2577,7 +2577,7 @@ static void write_namespace_deps_files(void)
|
|||
if (ns_deps_buf.pos == 0)
|
||||
continue;
|
||||
|
||||
sprintf(fname, "%s.ns_deps", mod->name);
|
||||
snprintf(fname, PATH_MAX, "%s.ns_deps", mod->name);
|
||||
write_if_changed(&ns_deps_buf, fname);
|
||||
}
|
||||
}
|
||||
|
|
@ -2689,7 +2689,7 @@ int main(int argc, char **argv)
|
|||
add_moddevtable(&buf, mod);
|
||||
add_srcversion(&buf, mod);
|
||||
|
||||
sprintf(fname, "%s.mod.c", mod->name);
|
||||
snprintf(fname, PATH_MAX, "%s.mod.c", mod->name);
|
||||
write_if_changed(&buf, fname);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue