From: Vaibhav Hiremath Date: Fri, 12 Feb 2016 20:34:14 +0000 (+0530) Subject: greybus: arche-apb-ctrl: Introduce ara,init-disable property for APB X-Git-Tag: v4.9-rc1~119^2~378^2~21^2~698 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=af3aae10f16f05acba27294bc1ae234f3cb61a61;p=karo-tx-linux.git 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 --- diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c index e4fd34ddf465..04ba8365f7bf 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);