OSDN Git Service

esoc: Add provision to handle shutdown request in userspace
authorArun KS <arunks@codeaurora.org>
Thu, 2 Mar 2017 12:42:54 +0000 (18:12 +0530)
committerArun KS <arunks@codeaurora.org>
Tue, 2 May 2017 04:40:37 +0000 (10:10 +0530)
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 <arunks@codeaurora.org>
Signed-off-by: Srivatsa Vaddagiri <vatsa@codeaurora.org>
Documentation/devicetree/bindings/arm/msm/mdm-modem.txt
drivers/esoc/esoc-mdm-4x.c
drivers/esoc/esoc.h
include/uapi/linux/esoc_ctrl.h

index 86d2268..7d5e8a1 100644 (file)
@@ -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 {
index 7377855..26f69fa 100644 (file)
@@ -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) {
index 6d9d0aa..ee54908 100644 (file)
@@ -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;
 };
 
 /**
index d074379..c0680f3 100644 (file)
@@ -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__