From af3aae10f16f05acba27294bc1ae234f3cb61a61 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Sat, 13 Feb 2016 02:04:14 +0530 Subject: [PATCH] greybus: arche-apb-ctrl: Introduce ara,init-disable property for APB New DT property "ara,init-disable" will allow user to disable APB1 or APB2 during boot and enable it only when needed through command prompt via sysfs interface. - To disable APB2 during boot, specify "ara,init-disable" property in respective APB node. - How to check the state # cat /sys/devices/arche_platform.*/apb*/state It should be 'off', if 'ara,init-disable' enabled in DT. - During runtime if user/developer desired to enable APB2 (strictly and only for development purpose) then respective APB can be enabled through, # echo active > /sys/devices/arche_platform.*/apb*/state Note: - If APB device is in 'off,disabled' state, then no state transitions are permitted. - User/developer must first activate APB device # echo active > /sys/devices/arche_platform.*/apb*/state This will clear the 'init-disable' flag and allow state transition from here onwards. Note that, 'off,disabled' is only indicative state and is only applicable during init/boot. 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-apb-ctrl.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c index e4fd34d..04ba836 100644 --- a/drivers/staging/greybus/arche-apb-ctrl.c +++ b/drivers/staging/greybus/arche-apb-ctrl.c @@ -32,6 +32,7 @@ struct arche_apb_ctrl_drvdata { int pwrdn_gpio; enum arche_platform_state state; + bool init_disabled; struct regulator *vcore; struct regulator *vio; @@ -77,6 +78,9 @@ static int apb_ctrl_coldboot_seq(struct platform_device *pdev) struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); int ret; + if (apb->init_disabled) + return 0; + /* Hold APB in reset state */ assert_reset(apb->resetn_gpio); @@ -119,6 +123,9 @@ static int apb_ctrl_fw_flashing_seq(struct platform_device *pdev) struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); int ret; + if (apb->init_disabled) + return 0; + ret = regulator_enable(apb->vcore); if (ret) { dev_err(dev, "failed to enable core regulator\n"); @@ -142,6 +149,9 @@ static int apb_ctrl_standby_boot_seq(struct platform_device *pdev) { struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); + if (apb->init_disabled) + return 0; + /* If it is in OFF state, then we do not want to change the state */ if (apb->state == ARCHE_PLATFORM_STATE_OFF) return 0; @@ -163,6 +173,9 @@ static void apb_ctrl_poweroff_seq(struct platform_device *pdev) { struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); + if (apb->init_disabled) + return; + /* disable the clock */ if (gpio_is_valid(apb->clk_en_gpio)) gpio_set_value(apb->clk_en_gpio, 0); @@ -186,6 +199,7 @@ static ssize_t state_store(struct device *dev, struct platform_device *pdev = to_platform_device(dev); struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); int ret = 0; + bool is_disabled; if (sysfs_streq(buf, "off")) { if (apb->state == ARCHE_PLATFORM_STATE_OFF) @@ -197,7 +211,11 @@ static ssize_t state_store(struct device *dev, return count; apb_ctrl_poweroff_seq(pdev); + is_disabled = apb->init_disabled; + apb->init_disabled = false; ret = apb_ctrl_coldboot_seq(pdev); + if (ret) + apb->init_disabled = is_disabled; } else if (sysfs_streq(buf, "standby")) { if (apb->state == ARCHE_PLATFORM_STATE_STANDBY) return count; @@ -226,7 +244,8 @@ static ssize_t state_show(struct device *dev, switch (apb->state) { case ARCHE_PLATFORM_STATE_OFF: - return sprintf(buf, "off\n"); + return sprintf(buf, "off%s\n", + apb->init_disabled ? ",disabled" : ""); case ARCHE_PLATFORM_STATE_ACTIVE: return sprintf(buf, "active\n"); case ARCHE_PLATFORM_STATE_STANDBY: @@ -346,6 +365,9 @@ int arche_apb_ctrl_probe(struct platform_device *pdev) /* Initially set APB to OFF state */ apb->state = ARCHE_PLATFORM_STATE_OFF; + /* Check whether device needs to be enabled on boot */ + if (of_property_read_bool(pdev->dev.of_node, "ara,init-disable")) + apb->init_disabled = true; platform_set_drvdata(pdev, apb); -- 2.7.4