From 7691fed20e7301bd89b04d38f88262c83279817a Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Sat, 13 Feb 2016 02:04:08 +0530 Subject: [PATCH] greybus: arche-platform: Introduce FW_FLASHING state 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 Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/arche-platform.c | 27 ++++++++++++++++++++++++ drivers/staging/greybus/arche_platform.h | 1 + 2 files changed, 28 insertions(+) diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c index 1dd2b08225c4..3e6432f0f1bc 100644 --- a/drivers/staging/greybus/arche-platform.c +++ b/drivers/staging/greybus/arche-platform.c @@ -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"); } diff --git a/drivers/staging/greybus/arche_platform.h b/drivers/staging/greybus/arche_platform.h index 33c4bb8bca93..27deeb7cd157 100644 --- a/drivers/staging/greybus/arche_platform.h +++ b/drivers/staging/greybus/arche_platform.h @@ -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); -- 2.39.5