From bb76f075ca4ba2721019401b0ed809b82876126c Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Mon, 9 Sep 2024 18:37:24 +0800 Subject: [PATCH 1/5] coresight-tmc: Replace deprecated function Use 'scnprintf' to replace deprecated function 'sprintf'. Change-Id: Ic258e7dfe719f1f871f9c9eb5988609a5f3b6284 Signed-off-by: Yuanfang Zhang --- drivers/hwtracing/coresight/coresight-tmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 05a7cbfd63ec..3e606171d1dd 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -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, From 32de0804b1379d126033893ef70955fbbb77eb91 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 12 Mar 2024 20:27:22 -0700 Subject: [PATCH 2/5] msm: ep_pcie: Disable hot reset and ignore linkdown Intel host tends to retrain the link if device doesn't send PM_Enter_L23 in time, leading to linkdown and hot reset in device side. The hot reset here even results to PERST# timeout and device crash to PBL, which is not expected. Since we are in the entry of shutdown the link when linkdown happen, it makes sense to ignore the linkdown. To avoid device crash because of PERST# timeout, disable hot reset in pm_turnoff irq and reenable it when we do linktrain again. Change-Id: I87961faaae2a14c9a5e7d24543b416914076dd2e Signed-off-by: Qiang Yu Signed-off-by: Sai Chaitanya Kaveti --- drivers/platform/msm/ep_pcie/ep_pcie_com.h | 2 + drivers/platform/msm/ep_pcie/ep_pcie_core.c | 51 ++++++++++++++++++++- include/linux/msm_ep_pcie.h | 1 + 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_com.h b/drivers/platform/msm/ep_pcie/ep_pcie_com.h index 34b7a56b2217..5e3d8a02279b 100644 --- a/drivers/platform/msm/ep_pcie/ep_pcie_com.h +++ b/drivers/platform/msm/ep_pcie/ep_pcie_com.h @@ -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; diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_core.c b/drivers/platform/msm/ep_pcie/ep_pcie_core.c index d0b8e3f386a3..591f7cb47d38 100644 --- a/drivers/platform/msm/ep_pcie/ep_pcie_core.c +++ b/drivers/platform/msm/ep_pcie/ep_pcie_core.c @@ -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) { @@ -3499,6 +3533,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, diff --git a/include/linux/msm_ep_pcie.h b/include/linux/msm_ep_pcie.h index d98ed7b13984..82da45762bfc 100644 --- a/include/linux/msm_ep_pcie.h +++ b/include/linux/msm_ep_pcie.h @@ -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 { From f1d1549d8e9a17dddb7a128955d28bc96eaeca38 Mon Sep 17 00:00:00 2001 From: Vishnu Teja Date: Tue, 21 Nov 2023 17:24:23 +0530 Subject: [PATCH 3/5] scripts: mod: replace with a safe function Add safe function vsnprintf instead of sprintf by passing size as argument. Change-Id: Ibd21a0c7d9039543dee32c1297035ed9984ed748 Signed-off-by: Vishnu Teja --- scripts/mod/modpost.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 5ca626d0de92..0ac6bf1d14c4 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -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); } From b2af2b5f9f4ed3e43ea4a227783e9f62ac645cd2 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Fri, 29 Mar 2024 14:37:42 +0530 Subject: [PATCH 4/5] firmware: qcom_scm: handle echo b > /proc/sysrq-trigger Introduce restart handler to handle "echo b > /proc/sysrq-trigger". One special thing with 'b' kind of reboot is, it does not call reboot notifiers and call restart handler right a way and that does not seems to work for blair SoC and it goes to dump mode. Keep this restart handler priority to 201 greater than 200 which is the priority for msm-poweroff to make reboot work cleaner. Change-Id: I42f8c0fde29af402096d760c37ec2d8b3a85439a Signed-off-by: Mukesh Ojha Signed-off-by: Sayan Dey --- drivers/power/reset/qcom-dload-mode.c | 43 +++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/power/reset/qcom-dload-mode.c b/drivers/power/reset/qcom-dload-mode.c index 5298b80921c9..71e77259625a 100644 --- a/drivers/power/reset/qcom-dload-mode.c +++ b/drivers/power/reset/qcom-dload-mode.c @@ -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 @@ -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; }; @@ -280,16 +283,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 +421,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 +445,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); From c5539fb1c23b4a10d45fc9b878b7e2f51d1e981c Mon Sep 17 00:00:00 2001 From: Anil Veshala Veshala Date: Mon, 1 Jul 2024 02:39:57 -0700 Subject: [PATCH 5/5] i2c: i2c-master-msm-geni: add null pointer check in event call back Currently i2c geni driver doesn't have null pointer check condition in event call back function. If any invalid event is coming from GSI, i2c geni driver accessing null pointer which is causing crash. To solve this added null pointer checks in event call back functions. Change-Id: Ie14a40eee846c0ea29bec512d6320e9548c509b5 Signed-off-by: Anil Veshala Veshala --- drivers/i2c/busses/i2c-msm-geni.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-msm-geni.c b/drivers/i2c/busses/i2c-msm-geni.c index 473ff18b0f2e..e29a96949536 100644 --- a/drivers/i2c/busses/i2c-msm-geni.c +++ b/drivers/i2c/busses/i2c-msm-geni.c @@ -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 @@ -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: