Loading drivers/net/wireless/cnss2/main.h +1 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ struct cnss_pinctrl_info { struct pinctrl_state *wlan_en_active; struct pinctrl_state *wlan_en_sleep; int bt_en_gpio; int xo_clk_gpio; /*qca6490 only */ }; #if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART) Loading drivers/net/wireless/cnss2/power.c +49 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ static struct cnss_clk_cfg cnss_clk_list[] = { #define BOOTSTRAP_ACTIVE "bootstrap_active" #define WLAN_EN_GPIO "wlan-en-gpio" #define BT_EN_GPIO "qcom,bt-en-gpio" #define XO_CLK_GPIO "qcom,xo-clk-gpio" #define WLAN_EN_ACTIVE "wlan_en_active" #define WLAN_EN_SLEEP "wlan_en_sleep" Loading Loading @@ -711,11 +712,57 @@ int cnss_get_pinctrl(struct cnss_plat_data *plat_priv) pinctrl_info->bt_en_gpio = -EINVAL; } /* Added for QCA6490 to minimize XO CLK selection leakage prevention */ if (of_find_property(dev->of_node, XO_CLK_GPIO, NULL)) { pinctrl_info->xo_clk_gpio = of_get_named_gpio(dev->of_node, XO_CLK_GPIO, 0); cnss_pr_dbg("QCA6490 XO_CLK GPIO: %d\n", pinctrl_info->xo_clk_gpio); } else { pinctrl_info->xo_clk_gpio = -EINVAL; } return 0; out: return ret; } #define CNSS_XO_CLK_RETRY_COUNT_MAX 5 static void cnss_set_xo_clk_gpio_state(struct cnss_plat_data *plat_priv, bool enable) { int xo_clk_gpio = plat_priv->pinctrl_info.xo_clk_gpio, retry = 0, ret; if (xo_clk_gpio < 0 || plat_priv->device_id != QCA6490_DEVICE_ID) return; retry_gpio_req: ret = gpio_request(xo_clk_gpio, "XO_CLK_GPIO"); if (ret) { if (retry++ < CNSS_XO_CLK_RETRY_COUNT_MAX) { /* wait for ~(10 - 20) ms */ usleep_range(10000, 20000); goto retry_gpio_req; } } if (ret) { cnss_pr_err("QCA6490 XO CLK Gpio request failed\n"); return; } if (enable) { gpio_direction_output(xo_clk_gpio, 1); /*XO CLK must be asserted for some time before WLAN_EN */ usleep_range(100, 200); } else { /* Assert XO CLK ~(2-5)ms before off for valid latch in HW */ usleep_range(2000, 5000); gpio_direction_output(xo_clk_gpio, 0); } gpio_free(xo_clk_gpio); } static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv, bool state) { Loading @@ -742,7 +789,7 @@ static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv, } udelay(BOOTSTRAP_DELAY); } cnss_set_xo_clk_gpio_state(plat_priv, true); if (!IS_ERR_OR_NULL(pinctrl_info->wlan_en_active)) { ret = pinctrl_select_state (pinctrl_info->pinctrl, Loading @@ -754,6 +801,7 @@ static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv, } udelay(WLAN_ENABLE_DELAY); } cnss_set_xo_clk_gpio_state(plat_priv, false); } else { if (!IS_ERR_OR_NULL(pinctrl_info->wlan_en_sleep)) { ret = pinctrl_select_state(pinctrl_info->pinctrl, Loading Loading
drivers/net/wireless/cnss2/main.h +1 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ struct cnss_pinctrl_info { struct pinctrl_state *wlan_en_active; struct pinctrl_state *wlan_en_sleep; int bt_en_gpio; int xo_clk_gpio; /*qca6490 only */ }; #if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART) Loading
drivers/net/wireless/cnss2/power.c +49 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ static struct cnss_clk_cfg cnss_clk_list[] = { #define BOOTSTRAP_ACTIVE "bootstrap_active" #define WLAN_EN_GPIO "wlan-en-gpio" #define BT_EN_GPIO "qcom,bt-en-gpio" #define XO_CLK_GPIO "qcom,xo-clk-gpio" #define WLAN_EN_ACTIVE "wlan_en_active" #define WLAN_EN_SLEEP "wlan_en_sleep" Loading Loading @@ -711,11 +712,57 @@ int cnss_get_pinctrl(struct cnss_plat_data *plat_priv) pinctrl_info->bt_en_gpio = -EINVAL; } /* Added for QCA6490 to minimize XO CLK selection leakage prevention */ if (of_find_property(dev->of_node, XO_CLK_GPIO, NULL)) { pinctrl_info->xo_clk_gpio = of_get_named_gpio(dev->of_node, XO_CLK_GPIO, 0); cnss_pr_dbg("QCA6490 XO_CLK GPIO: %d\n", pinctrl_info->xo_clk_gpio); } else { pinctrl_info->xo_clk_gpio = -EINVAL; } return 0; out: return ret; } #define CNSS_XO_CLK_RETRY_COUNT_MAX 5 static void cnss_set_xo_clk_gpio_state(struct cnss_plat_data *plat_priv, bool enable) { int xo_clk_gpio = plat_priv->pinctrl_info.xo_clk_gpio, retry = 0, ret; if (xo_clk_gpio < 0 || plat_priv->device_id != QCA6490_DEVICE_ID) return; retry_gpio_req: ret = gpio_request(xo_clk_gpio, "XO_CLK_GPIO"); if (ret) { if (retry++ < CNSS_XO_CLK_RETRY_COUNT_MAX) { /* wait for ~(10 - 20) ms */ usleep_range(10000, 20000); goto retry_gpio_req; } } if (ret) { cnss_pr_err("QCA6490 XO CLK Gpio request failed\n"); return; } if (enable) { gpio_direction_output(xo_clk_gpio, 1); /*XO CLK must be asserted for some time before WLAN_EN */ usleep_range(100, 200); } else { /* Assert XO CLK ~(2-5)ms before off for valid latch in HW */ usleep_range(2000, 5000); gpio_direction_output(xo_clk_gpio, 0); } gpio_free(xo_clk_gpio); } static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv, bool state) { Loading @@ -742,7 +789,7 @@ static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv, } udelay(BOOTSTRAP_DELAY); } cnss_set_xo_clk_gpio_state(plat_priv, true); if (!IS_ERR_OR_NULL(pinctrl_info->wlan_en_active)) { ret = pinctrl_select_state (pinctrl_info->pinctrl, Loading @@ -754,6 +801,7 @@ static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv, } udelay(WLAN_ENABLE_DELAY); } cnss_set_xo_clk_gpio_state(plat_priv, false); } else { if (!IS_ERR_OR_NULL(pinctrl_info->wlan_en_sleep)) { ret = pinctrl_select_state(pinctrl_info->pinctrl, Loading