diff --git a/drivers/soc/qcom/pil-q6v5-mss.c b/drivers/soc/qcom/pil-q6v5-mss.c index 45712457de73..1177cac25ffa 100644 --- a/drivers/soc/qcom/pil-q6v5-mss.c +++ b/drivers/soc/qcom/pil-q6v5-mss.c @@ -41,6 +41,7 @@ #define PROXY_TIMEOUT_MS 10000 #define MAX_SSR_REASON_LEN 130U #define STOP_ACK_TIMEOUT_MS 1000 +#define QDSP6SS_NMI_STATUS 0x44 #define subsys_to_drv(d) container_of(d, struct modem_data, subsys_desc) @@ -77,12 +78,17 @@ static void restart_modem(struct modem_data *drv) static irqreturn_t modem_err_fatal_intr_handler(int irq, void *dev_id) { struct modem_data *drv = subsys_to_drv(dev_id); + u32 nmi_status = readl_relaxed(drv->q6->reg_base + QDSP6SS_NMI_STATUS); /* Ignore if we're the one that set the force stop GPIO */ if (drv->crash_shutdown) return IRQ_HANDLED; - pr_err("Fatal error on the modem.\n"); + if (nmi_status & 0x04) + pr_err("%s: Fatal error on the modem due to TZ NMI\n", + __func__); + else + pr_err("%s: Fatal error on the modem\n", __func__); subsys_set_crash_status(drv->subsys, CRASH_STATUS_ERR_FATAL); restart_modem(drv); return IRQ_HANDLED; diff --git a/drivers/soc/qcom/subsys-pil-tz.c b/drivers/soc/qcom/subsys-pil-tz.c index 8bf5f8eb64ad..73b194b1dec2 100644 --- a/drivers/soc/qcom/subsys-pil-tz.c +++ b/drivers/soc/qcom/subsys-pil-tz.c @@ -43,6 +43,7 @@ #define ERR_READY 0 #define PBL_DONE 1 +#define NMI_STATUS_REGISTER 0x44 #define desc_to_data(d) container_of(d, struct pil_tz_data, desc) #define subsys_to_data(d) container_of(d, struct pil_tz_data, subsys_desc) @@ -110,6 +111,7 @@ struct pil_tz_data { void __iomem *irq_mask; void __iomem *err_status; void __iomem *err_status_spare; + void __iomem *reg_base; u32 bits_arr[2]; }; @@ -874,8 +876,19 @@ static void subsys_crash_shutdown(const struct subsys_desc *subsys) static irqreturn_t subsys_err_fatal_intr_handler (int irq, void *dev_id) { struct pil_tz_data *d = subsys_to_data(dev_id); + u32 nmi_status = 0; + + if (d->reg_base) + nmi_status = readl_relaxed(d->reg_base + + NMI_STATUS_REGISTER); + + if (nmi_status & 0x04) + pr_err("%s: Fatal error on the %s due to TZ NMI\n", + __func__, d->subsys_desc.name); + else + pr_err("%s Fatal error on the %s\n", + __func__, d->subsys_desc.name); - pr_err("Fatal error on %s!\n", d->subsys_desc.name); if (subsys_get_crash_status(d->subsys)) { pr_err("%s: Ignoring error fatal, restart in progress\n", d->subsys_desc.name); @@ -1011,6 +1024,13 @@ static int pil_tz_driver_probe(struct platform_device *pdev) d->keep_proxy_regs_on = of_property_read_bool(pdev->dev.of_node, "qcom,keep-proxy-regs-on"); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base_reg"); + d->reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(d->reg_base)) { + dev_err(&pdev->dev, "Failed to iomap base register\n"); + d->reg_base = NULL; + } + rc = of_property_read_string(pdev->dev.of_node, "qcom,firmware-name", &d->desc.name); if (rc)