From 4a2171cd807c373d6bb8ef78b3187d0b9b4bcffc Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Mon, 25 Apr 2016 13:06:07 -0700 Subject: [PATCH] cnss: Correct boot sequence for WLAN hardware Vote 1.8V IO and XTAL regulators before 3.3V VREG for WLAN hardware to strictly follow the hardware requirement. Make sure 3.3V VREG is voted at least 100us after 1.8V IO. Change-Id: Ifc52c2062349a9913e6c998573b62d111faa5886 CRs-fixed: 1009287 Signed-off-by: Yue Ma --- drivers/net/wireless/cnss/cnss_pci.c | 87 +++++++++++++++------------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/cnss/cnss_pci.c b/drivers/net/wireless/cnss/cnss_pci.c index c9412ca6e794..d150c2dd0f0f 100644 --- a/drivers/net/wireless/cnss/cnss_pci.c +++ b/drivers/net/wireless/cnss/cnss_pci.c @@ -114,6 +114,8 @@ #define WLAN_VREG_SP2T_MIN 2700000 #define POWER_ON_DELAY 2 +#define WLAN_VREG_IO_DELAY_MIN 100 +#define WLAN_VREG_IO_DELAY_MAX 1000 #define WLAN_ENABLE_DELAY 10 #define WLAN_RECOVERY_DELAY 1 #define PCIE_ENABLE_DELAY 100 @@ -304,13 +306,6 @@ static int cnss_wlan_vreg_on(struct cnss_wlan_vreg_info *vreg_info) } } - ret = regulator_enable(vreg_info->wlan_reg); - if (ret) { - pr_err("%s: regulator enable failed for WLAN power\n", - __func__); - goto error_enable; - } - if (vreg_info->wlan_reg_io) { ret = regulator_enable(vreg_info->wlan_reg_io); if (ret) { @@ -318,6 +313,8 @@ static int cnss_wlan_vreg_on(struct cnss_wlan_vreg_info *vreg_info) __func__); goto error_enable_reg_io; } + + usleep_range(WLAN_VREG_IO_DELAY_MIN, WLAN_VREG_IO_DELAY_MAX); } if (vreg_info->wlan_reg_xtal_aon) { @@ -338,6 +335,13 @@ static int cnss_wlan_vreg_on(struct cnss_wlan_vreg_info *vreg_info) } } + ret = regulator_enable(vreg_info->wlan_reg); + if (ret) { + pr_err("%s: regulator enable failed for WLAN power\n", + __func__); + goto error_enable; + } + if (vreg_info->wlan_reg_sp2t) { ret = regulator_enable(vreg_info->wlan_reg_sp2t); if (ret) { @@ -374,6 +378,8 @@ error_enable_ant_switch: if (vreg_info->wlan_reg_sp2t) regulator_disable(vreg_info->wlan_reg_sp2t); error_enable_reg_sp2t: + regulator_disable(vreg_info->wlan_reg); +error_enable: if (vreg_info->wlan_reg_xtal) regulator_disable(vreg_info->wlan_reg_xtal); error_enable_reg_xtal: @@ -383,8 +389,6 @@ error_enable_reg_xtal_aon: if (vreg_info->wlan_reg_io) regulator_disable(vreg_info->wlan_reg_io); error_enable_reg_io: - regulator_disable(vreg_info->wlan_reg); -error_enable: if (vreg_info->wlan_reg_core) regulator_disable(vreg_info->wlan_reg_core); error_enable_reg_core: @@ -422,6 +426,13 @@ static int cnss_wlan_vreg_off(struct cnss_wlan_vreg_info *vreg_info) } } + ret = regulator_disable(vreg_info->wlan_reg); + if (ret) { + pr_err("%s: regulator disable failed for WLAN power\n", + __func__); + goto error_disable; + } + if (vreg_info->wlan_reg_xtal) { ret = regulator_disable(vreg_info->wlan_reg_xtal); if (ret) { @@ -449,13 +460,6 @@ static int cnss_wlan_vreg_off(struct cnss_wlan_vreg_info *vreg_info) } } - ret = regulator_disable(vreg_info->wlan_reg); - if (ret) { - pr_err("%s: regulator disable failed for WLAN power\n", - __func__); - goto error_disable; - } - if (vreg_info->wlan_reg_core) { ret = regulator_disable(vreg_info->wlan_reg_core); if (ret) { @@ -715,24 +719,6 @@ static int cnss_wlan_get_resources(struct platform_device *pdev) } } - vreg_info->wlan_reg = regulator_get(&pdev->dev, WLAN_VREG_NAME); - - if (IS_ERR(vreg_info->wlan_reg)) { - if (PTR_ERR(vreg_info->wlan_reg) == -EPROBE_DEFER) - pr_err("%s: vreg probe defer\n", __func__); - else - pr_err("%s: vreg regulator get failed\n", __func__); - ret = PTR_ERR(vreg_info->wlan_reg); - goto err_reg_get; - } - - ret = regulator_enable(vreg_info->wlan_reg); - - if (ret) { - pr_err("%s: vreg initial vote failed\n", __func__); - goto err_reg_enable; - } - if (of_get_property(pdev->dev.of_node, WLAN_VREG_IO_NAME"-supply", NULL)) { vreg_info->wlan_reg_io = regulator_get(&pdev->dev, @@ -752,12 +738,33 @@ static int cnss_wlan_get_resources(struct platform_device *pdev) __func__); goto err_reg_io_enable; } + + usleep_range(WLAN_VREG_IO_DELAY_MIN, + WLAN_VREG_IO_DELAY_MAX); } } if (cnss_enable_xtal_ldo(pdev)) goto err_reg_xtal_enable; + vreg_info->wlan_reg = regulator_get(&pdev->dev, WLAN_VREG_NAME); + + if (IS_ERR(vreg_info->wlan_reg)) { + if (PTR_ERR(vreg_info->wlan_reg) == -EPROBE_DEFER) + pr_err("%s: vreg probe defer\n", __func__); + else + pr_err("%s: vreg regulator get failed\n", __func__); + ret = PTR_ERR(vreg_info->wlan_reg); + goto err_reg_get; + } + + ret = regulator_enable(vreg_info->wlan_reg); + + if (ret) { + pr_err("%s: vreg initial vote failed\n", __func__); + goto err_reg_enable; + } + if (of_get_property(pdev->dev.of_node, WLAN_VREG_SP2T_NAME"-supply", NULL)) { vreg_info->wlan_reg_sp2t = @@ -926,7 +933,11 @@ err_reg_sp2t_enable: err_reg_sp2t_set: if (vreg_info->wlan_reg_sp2t) regulator_put(vreg_info->wlan_reg_sp2t); + regulator_disable(vreg_info->wlan_reg); +err_reg_enable: + regulator_put(vreg_info->wlan_reg); +err_reg_get: cnss_disable_xtal_ldo(pdev); err_reg_xtal_enable: @@ -937,12 +948,6 @@ err_reg_io_enable: err_reg_io_set: if (vreg_info->wlan_reg_io) regulator_put(vreg_info->wlan_reg_io); - regulator_disable(vreg_info->wlan_reg); - -err_reg_enable: - regulator_put(vreg_info->wlan_reg); - -err_reg_get: if (vreg_info->wlan_reg_core) regulator_disable(vreg_info->wlan_reg_core); @@ -972,13 +977,13 @@ static void cnss_wlan_release_resources(void) regulator_put(vreg_info->ant_switch); if (vreg_info->wlan_reg_sp2t) regulator_put(vreg_info->wlan_reg_sp2t); + regulator_put(vreg_info->wlan_reg); if (vreg_info->wlan_reg_xtal) regulator_put(vreg_info->wlan_reg_xtal); if (vreg_info->wlan_reg_xtal_aon) regulator_put(vreg_info->wlan_reg_xtal_aon); if (vreg_info->wlan_reg_io) regulator_put(vreg_info->wlan_reg_io); - regulator_put(vreg_info->wlan_reg); if (vreg_info->wlan_reg_core) regulator_put(vreg_info->wlan_reg_core); vreg_info->state = VREG_OFF;