greybus: arche-platform: Introduce FW_FLASHING state
authorVaibhav Hiremath <vaibhav.hiremath@linaro.org>
Fri, 12 Feb 2016 20:34:08 +0000 (02:04 +0530)
committerGreg Kroah-Hartman <gregkh@google.com>
Mon, 15 Feb 2016 21:18:40 +0000 (13:18 -0800)
Introduce FW_FLASHING state to arche-platform driver, to enable
user space to flash/upgrade SVC firmware.

Command to enter into flashing state:

  # echo fw_flashing > /sys/devices/arche_platform.*/state

Testing Done: Tested on EVT1.2 and DB3.5 platform.

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/arche-platform.c
drivers/staging/greybus/arche_platform.h

index 1dd2b08225c45d89860f765220bd34542b2886b5..3e6432f0f1bc029be7473cdf68eb58820f5baf42 100644 (file)
@@ -134,6 +134,23 @@ static int arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdat
        return 0;
 }
 
+static void arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata)
+{
+       dev_info(arche_pdata->dev, "Switching to FW flashing state\n");
+
+       svc_reset_onoff(arche_pdata->svc_reset_gpio,
+                       arche_pdata->is_reset_act_hi);
+
+       gpio_set_value(arche_pdata->svc_sysboot_gpio, 1);
+
+       usleep_range(100, 200);
+       svc_reset_onoff(arche_pdata->svc_reset_gpio,
+                       !arche_pdata->is_reset_act_hi);
+
+       arche_pdata->state = ARCHE_PLATFORM_STATE_FW_FLASHING;
+
+}
+
 static void arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pdata)
 {
        /* Send disconnect/detach event to SVC */
@@ -170,6 +187,14 @@ static ssize_t state_store(struct device *dev,
                        return count;
 
                dev_warn(arche_pdata->dev, "standby state not supported\n");
+       } else if (sysfs_streq(buf, "fw_flashing")) {
+               if (arche_pdata->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
+                       return count;
+
+               /* First we want to make sure we power off everything
+                * and then enter FW flashing state */
+               arche_platform_poweroff_seq(arche_pdata);
+               arche_platform_fw_flashing_seq(arche_pdata);
        } else {
                dev_err(arche_pdata->dev, "unknown state\n");
                ret = -EINVAL;
@@ -190,6 +215,8 @@ static ssize_t state_show(struct device *dev,
                return sprintf(buf, "active\n");
        case ARCHE_PLATFORM_STATE_STANDBY:
                return sprintf(buf, "standby\n");
+       case ARCHE_PLATFORM_STATE_FW_FLASHING:
+               return sprintf(buf, "fw_flashing\n");
        default:
                return sprintf(buf, "unknown state\n");
        }
index 33c4bb8bca934cccdb112fe8a0f99162b49a8876..27deeb7cd1579a91c2c2c18f3abd072a8245418b 100644 (file)
@@ -14,6 +14,7 @@ enum arche_platform_state {
        ARCHE_PLATFORM_STATE_OFF,
        ARCHE_PLATFORM_STATE_ACTIVE,
        ARCHE_PLATFORM_STATE_STANDBY,
+       ARCHE_PLATFORM_STATE_FW_FLASHING,
 };
 
 int arche_apb_ctrl_probe(struct platform_device *pdev);