From b1da6f22252a9aa5481b98e5773772085c2ce7e1 Mon Sep 17 00:00:00 2001 From: Arun KS Date: Mon, 6 Mar 2017 13:25:56 +0530 Subject: [PATCH 1/2] esoc: Update SSR driver with crash status During an unexpected reset or error fatal, update the crash status to SSR. This is important for the drivers listening at SSR related kernel notifier calls, where crash status is also passed as a data payload. Change-Id: Ide0634d0139a84b5988fa87e709877f3028029ef Signed-off-by: Arun KS --- drivers/esoc/esoc-mdm-4x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/esoc/esoc-mdm-4x.c b/drivers/esoc/esoc-mdm-4x.c index 618ceb957c65..7377855e8e6b 100644 --- a/drivers/esoc/esoc-mdm-4x.c +++ b/drivers/esoc/esoc-mdm-4x.c @@ -446,6 +446,7 @@ static irqreturn_t mdm_errfatal(int irq, void *dev_id) esoc = mdm->esoc; dev_err(dev, "%s: mdm sent errfatal interrupt\n", __func__); + subsys_set_crash_status(esoc->subsys_dev, true); /* disable irq ?*/ esoc_clink_evt_notify(ESOC_ERR_FATAL, esoc); return IRQ_HANDLED; @@ -476,6 +477,7 @@ static irqreturn_t mdm_status_change(int irq, void *dev_id) value = gpio_get_value(MDM_GPIO(mdm, MDM2AP_STATUS)); if (value == 0 && mdm->ready) { dev_err(dev, "unexpected reset external modem\n"); + subsys_set_crash_status(esoc->subsys_dev, true); esoc_clink_evt_notify(ESOC_UNEXPECTED_RESET, esoc); } else if (value == 1) { /* From e704eb52754a399c4b873b7e25c7ad0af3b431b0 Mon Sep 17 00:00:00 2001 From: Arun KS Date: Thu, 2 Mar 2017 18:12:54 +0530 Subject: [PATCH 2/2] esoc: Add provision to handle shutdown request in userspace In certain scenarios, modem shutdown requests are handled in userspace. Enhance request engine of esoc driver to send shutdown requests to userspace. Also, during a shutdown, avoid setting status to 0, if line is not a power source. There can be multiple mdms monitoring status line. This can otherwise be misinterpreted as an unexpected reset by other mdms. Change-Id: I9c20a86e76f892cc61dbfb814202b26e5cce3e96 Signed-off-by: Arun KS Signed-off-by: Srivatsa Vaddagiri --- .../devicetree/bindings/arm/msm/mdm-modem.txt | 4 +++ drivers/esoc/esoc-mdm-4x.c | 27 +++++++++++++------ drivers/esoc/esoc.h | 5 ++++ include/uapi/linux/esoc_ctrl.h | 2 ++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/msm/mdm-modem.txt b/Documentation/devicetree/bindings/arm/msm/mdm-modem.txt index 86d2268c8b53..7d5e8a1c910a 100644 --- a/Documentation/devicetree/bindings/arm/msm/mdm-modem.txt +++ b/Documentation/devicetree/bindings/arm/msm/mdm-modem.txt @@ -110,6 +110,10 @@ Optional driver parameters: on behalf of the subsystem driver. - qcom,mdm-link-info: a string indicating additional info about the physical link. For example: "devID_domain.bus.slot" in case of PCIe. +- qcom,mdm-auto-boot: Boolean. To indicate this instance of esoc boots independently. +- qcom,mdm-statusline-not-a-powersource: Boolean. If set, status line to esoc device is not a + power source. +- qcom,mdm-userspace-handle-shutdown: Boolean. If set, userspace handles shutdown requests. Example: mdm0: qcom,mdm0 { diff --git a/drivers/esoc/esoc-mdm-4x.c b/drivers/esoc/esoc-mdm-4x.c index 7377855e8e6b..26f69fa61ba1 100644 --- a/drivers/esoc/esoc-mdm-4x.c +++ b/drivers/esoc/esoc-mdm-4x.c @@ -211,12 +211,16 @@ static int mdm_cmd_exe(enum esoc_cmd cmd, struct esoc_clink *esoc) if (esoc->primary) break; graceful_shutdown = true; - ret = sysmon_send_shutdown(&esoc->subsys); - if (ret) { - dev_err(mdm->dev, "sysmon shutdown fail, ret = %d\n", - ret); - graceful_shutdown = false; - goto force_poff; + if (!esoc->userspace_handle_shutdown) { + ret = sysmon_send_shutdown(&esoc->subsys); + if (ret) { + dev_err(mdm->dev, + "sysmon shutdown fail, ret = %d\n", ret); + graceful_shutdown = false; + goto force_poff; + } + } else { + esoc_clink_queue_request(ESOC_REQ_SEND_SHUTDOWN, esoc); } dev_dbg(mdm->dev, "Waiting for status gpio go low\n"); status_down = false; @@ -251,9 +255,12 @@ force_poff: /* * Force a shutdown of the mdm. This is required in order * to prevent the mdm from immediately powering back on - * after the shutdown + * after the shutdown. Avoid setting status to 0, if line is + * monitored by multiple mdms(might be wrongly interpreted as + * a primary crash). */ - gpio_set_value(MDM_GPIO(mdm, AP2MDM_STATUS), 0); + if (esoc->statusline_not_a_powersource == false) + gpio_set_value(MDM_GPIO(mdm, AP2MDM_STATUS), 0); esoc_clink_queue_request(ESOC_REQ_SHUTDOWN, esoc); mdm_power_down(mdm); mdm_update_gpio_configs(mdm, GPIO_UPDATE_BOOTING_CONFIG); @@ -1001,6 +1008,10 @@ static int mdm9x45_setup_hw(struct mdm_ctrl *mdm, esoc->auto_boot = of_property_read_bool(esoc->np, "qcom,mdm-auto-boot"); + esoc->statusline_not_a_powersource = of_property_read_bool(esoc->np, + "qcom,mdm-statusline-not-a-powersource"); + esoc->userspace_handle_shutdown = of_property_read_bool(esoc->np, + "qcom,mdm-userspace-handle-shutdown"); set_esoc_clink_data(esoc, mdm); ret = esoc_clink_register(esoc); if (ret) { diff --git a/drivers/esoc/esoc.h b/drivers/esoc/esoc.h index 6d9d0aa3272f..ee54908ce486 100644 --- a/drivers/esoc/esoc.h +++ b/drivers/esoc/esoc.h @@ -63,6 +63,9 @@ struct esoc_eng { * @auto_boot: boots independently. * @primary: primary esoc controls(reset/poweroff) all secondary * esocs, but not otherway around. + * @statusline_not_a_powersource: True if status line to esoc is not a + * power source. + * @userspace_handle_shutdown: True if user space handles shutdown requests. */ struct esoc_clink { const char *name; @@ -84,6 +87,8 @@ struct esoc_clink { struct device_node *np; bool auto_boot; bool primary; + bool statusline_not_a_powersource; + bool userspace_handle_shutdown; }; /** diff --git a/include/uapi/linux/esoc_ctrl.h b/include/uapi/linux/esoc_ctrl.h index d0743790e09c..c0680f327073 100644 --- a/include/uapi/linux/esoc_ctrl.h +++ b/include/uapi/linux/esoc_ctrl.h @@ -16,6 +16,7 @@ #define HSIC "HSIC" #define HSICPCIe "HSIC+PCIe" #define PCIe "PCIe" +#define ESOC_REQ_SEND_SHUTDOWN ESOC_REQ_SEND_SHUTDOWN enum esoc_evt { ESOC_RUN_STATE = 0x1, @@ -56,6 +57,7 @@ enum esoc_req { ESOC_REQ_IMG = 1, ESOC_REQ_DEBUG, ESOC_REQ_SHUTDOWN, + ESOC_REQ_SEND_SHUTDOWN, }; #ifdef __KERNEL__