diff options
| author | wzedlare <vedatak01@gmail.com> | 2017-06-18 16:38:26 +0000 |
|---|---|---|
| committer | wzedlare <vedatak01@gmail.com> | 2017-06-19 16:57:11 +0000 |
| commit | c7d4e3fd588e3ba3d3fa4d5cfa224aa54bc288bf (patch) | |
| tree | b8b64cb9deb6832c1e41f58f0f143514beafc709 /drivers/net | |
| parent | 28c99c87b881bb664c44bb26e80a681f87d54e60 (diff) | |
Change-Id: Ia4c94f09e29843b1af34d466243378a357e97b70
Diffstat (limited to 'drivers/net')
| -rw-r--r-- | drivers/net/ethernet/msm/rndis_ipa_trace.h | 2 | ||||
| -rw-r--r-- | drivers/net/ppp/ppp_generic.c | 4 | ||||
| -rw-r--r-- | drivers/net/usb/cdc_ncm.c | 23 | ||||
| -rw-r--r-- | drivers/net/wireless/cnss/cnss_common.h | 1 | ||||
| -rw-r--r-- | drivers/net/wireless/cnss/cnss_pci.c | 466 | ||||
| -rw-r--r-- | drivers/net/wireless/wcnss/wcnss_wlan.c | 45 |
6 files changed, 309 insertions, 232 deletions
diff --git a/drivers/net/ethernet/msm/rndis_ipa_trace.h b/drivers/net/ethernet/msm/rndis_ipa_trace.h index c0fc5737..bd9ab5b3 100644 --- a/drivers/net/ethernet/msm/rndis_ipa_trace.h +++ b/drivers/net/ethernet/msm/rndis_ipa_trace.h @@ -77,5 +77,5 @@ TRACE_EVENT( /* This part must be outside protection */ #undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_PATH ../../drivers/net/ethernet/msm #include <trace/define_trace.h> diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index fc7b3d76..7efc451a 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -2242,7 +2242,7 @@ int ppp_register_net_channel(struct net *net, struct ppp_channel *chan) pch->ppp = NULL; pch->chan = chan; - pch->chan_net = net; + pch->chan_net = get_net(net); chan->ppp = pch; init_ppp_file(&pch->file, CHANNEL); pch->file.hdrlen = chan->hdrlen; @@ -2339,6 +2339,8 @@ ppp_unregister_channel(struct ppp_channel *chan) spin_lock_bh(&pn->all_channels_lock); list_del(&pch->list); spin_unlock_bh(&pn->all_channels_lock); + put_net(pch->chan_net); + pch->chan_net = NULL; pch->file.dead = 1; wake_up_interruptible(&pch->file.rwait); diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 8067b8fb..ba31ecde 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -948,23 +948,15 @@ EXPORT_SYMBOL_GPL(cdc_ncm_select_altsetting); static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) { - int ret; - /* MBIM backwards compatible function? */ if (cdc_ncm_select_altsetting(intf) != CDC_NCM_COMM_ALTSETTING_NCM) return -ENODEV; - /* The NCM data altsetting is fixed */ - ret = cdc_ncm_bind_common(dev, intf, CDC_NCM_DATA_ALTSETTING_NCM); - - /* - * We should get an event when network connection is "connected" or - * "disconnected". Set network connection in "disconnected" state - * (carrier is OFF) during attach, so the IP network stack does not - * start IPv6 negotiation and more. + /* The NCM data altsetting is fixed, so we hard-coded it. + * Additionally, generic NCM devices are assumed to accept arbitrarily + * placed NDP. */ - usbnet_link_change(dev, 0, 0); - return ret; + return cdc_ncm_bind_common(dev, intf, CDC_NCM_DATA_ALTSETTING_NCM); } static void cdc_ncm_align_tail(struct sk_buff *skb, size_t modulus, size_t remainder, size_t max) @@ -1506,7 +1498,8 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) static const struct driver_info cdc_ncm_info = { .description = "CDC NCM", - .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET, + .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET + | FLAG_LINK_INTR, .bind = cdc_ncm_bind, .unbind = cdc_ncm_unbind, .manage_power = usbnet_manage_power, @@ -1519,7 +1512,7 @@ static const struct driver_info cdc_ncm_info = { static const struct driver_info wwan_info = { .description = "Mobile Broadband Network Device", .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET - | FLAG_WWAN, + | FLAG_LINK_INTR | FLAG_WWAN, .bind = cdc_ncm_bind, .unbind = cdc_ncm_unbind, .manage_power = usbnet_manage_power, @@ -1532,7 +1525,7 @@ static const struct driver_info wwan_info = { static const struct driver_info wwan_noarp_info = { .description = "Mobile Broadband Network Device (NO ARP)", .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET - | FLAG_WWAN | FLAG_NOARP, + | FLAG_LINK_INTR | FLAG_WWAN | FLAG_NOARP, .bind = cdc_ncm_bind, .unbind = cdc_ncm_unbind, .manage_power = usbnet_manage_power, diff --git a/drivers/net/wireless/cnss/cnss_common.h b/drivers/net/wireless/cnss/cnss_common.h index 07ef9844..eb6796fc 100644 --- a/drivers/net/wireless/cnss/cnss_common.h +++ b/drivers/net/wireless/cnss/cnss_common.h @@ -13,7 +13,6 @@ #ifndef _NET_CNSS_COMMON_H_ #define _NET_CNSS_COMMON_H_ -#define MAX_FIRMWARE_SIZE (1 * 1024 * 1024) /* max 20mhz channel count */ #define CNSS_MAX_CH_NUM 45 diff --git a/drivers/net/wireless/cnss/cnss_pci.c b/drivers/net/wireless/cnss/cnss_pci.c index f55eab39..d12f48a1 100644 --- a/drivers/net/wireless/cnss/cnss_pci.c +++ b/drivers/net/wireless/cnss/cnss_pci.c @@ -21,6 +21,8 @@ #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/regulator/consumer.h> +#include <linux/gpio.h> +#include <linux/of_gpio.h> #include <linux/pm.h> #include <linux/pm_wakeup.h> #include <linux/sched.h> @@ -56,8 +58,12 @@ #define VREG_ON 1 #define VREG_OFF 0 +#define WLAN_EN_HIGH 1 +#define WLAN_EN_LOW 0 #define PCIE_LINK_UP 1 #define PCIE_LINK_DOWN 0 +#define WLAN_BOOTSTRAP_HIGH 1 +#define WLAN_BOOTSTRAP_LOW 0 #define CNSS_DUMP_FORMAT_VER 0x11 #define CNSS_DUMP_MAGIC_VER_V2 0x42445953 #define CNSS_DUMP_NAME "CNSS_WLAN" @@ -86,6 +92,8 @@ #define WLAN_VREG_SP2T_NAME "vdd-wlan-sp2t" #define WLAN_SWREG_NAME "wlan-soc-swreg" #define WLAN_ANT_SWITCH_NAME "wlan-ant-switch" +#define WLAN_EN_GPIO_NAME "wlan-en-gpio" +#define WLAN_BOOTSTRAP_GPIO_NAME "wlan-bootstrap-gpio" #define PM_OPTIONS 0 #define PM_OPTIONS_SUSPEND_LINK_DOWN \ (MSM_PCIE_CONFIG_NO_CFG_RESTORE | MSM_PCIE_CONFIG_LINKDOWN) @@ -114,12 +122,7 @@ #define PCIE_ENABLE_DELAY 100 #define WLAN_BOOTSTRAP_DELAY 10 #define EVICT_BIN_MAX_SIZE (512*1024) - -/*wlan enable and bootstrap pinctrl state */ -#define WLAN_EN_ACTIVE "wlan_en_active" -#define WLAN_EN_SLEEP "wlan_en_sleep" -#define BOOTSTRAP_ACTIVE "bootstrap_active" -#define BOOTSTRAP_SLEEP "bootstrap_sleep" +#define CNSS_PINCTRL_STATE_ACTIVE "default" static DEFINE_SPINLOCK(pci_link_down_lock); @@ -143,13 +146,14 @@ static DEFINE_SPINLOCK(pci_link_down_lock); #define BMI_TEST_SETUP (0x09) -struct cnss_wlan_pinctrl { - bool bootstrap_enable; +struct cnss_wlan_gpio_info { + char *name; + u32 num; + bool state; + bool init; + bool prop; struct pinctrl *pinctrl; - struct pinctrl_state *wlan_en_active; - struct pinctrl_state *wlan_en_sleep; - struct pinctrl_state *bootstrap_active; - struct pinctrl_state *bootstrap_sleep; + struct pinctrl_state *gpio_state_default; }; struct cnss_wlan_vreg_info { @@ -236,8 +240,8 @@ static struct cnss_data { dma_addr_t smmu_iova_start; size_t smmu_iova_len; struct cnss_wlan_vreg_info vreg_info; - struct cnss_wlan_pinctrl cnss_pinctrl; bool wlan_en_vreg_support; + struct cnss_wlan_gpio_info gpio_info; bool pcie_link_state; bool pcie_link_down_ind; bool pci_register_again; @@ -279,6 +283,7 @@ static struct cnss_data { u32 bdata_dma_size; u32 bdata_seg_count; struct segment_memory bdata_seg_mem[MAX_NUM_OF_SEGMENTS]; + int wlan_bootstrap_gpio; atomic_t auto_suspended; bool monitor_wake_intr; struct cnss_dual_wifi dual_wifi_info; @@ -289,6 +294,17 @@ module_param(pcie_link_down_panic, uint, S_IRUSR | S_IWUSR); MODULE_PARM_DESC(pcie_link_down_panic, "Trigger kernel panic when PCIe link down is detected"); +static void cnss_put_wlan_enable_gpio(void) +{ + struct cnss_wlan_gpio_info *gpio_info = &penv->gpio_info; + struct cnss_wlan_vreg_info *vreg_info = &penv->vreg_info; + + if (penv->wlan_en_vreg_support) + regulator_put(vreg_info->wlan_en_reg); + else + gpio_free(gpio_info->num); +} + static int cnss_wlan_vreg_on(struct cnss_wlan_vreg_info *vreg_info) { int ret; @@ -495,130 +511,127 @@ out: return ret; } -static int cnss_wlan_enable_pin_set_state( - struct cnss_wlan_pinctrl *cnss_pinctrl, - struct cnss_wlan_vreg_info *vreg_info, - bool state) +static int cnss_wlan_gpio_init(struct cnss_wlan_gpio_info *info) { - int ret; + int ret = 0; - if (state) - goto set_wlan_pin_active; + ret = gpio_request(info->num, info->name); - if (penv->wlan_en_vreg_support) - ret = regulator_disable(vreg_info->wlan_en_reg); - else - ret = pinctrl_select_state( - cnss_pinctrl->pinctrl, cnss_pinctrl->wlan_en_sleep); - msleep(WLAN_ENABLE_DELAY); + if (ret) { + pr_err("can't get gpio %s ret %d\n", info->name, ret); + goto err_gpio_req; + } + + ret = gpio_direction_output(info->num, info->init); + + if (ret) { + pr_err("can't set gpio direction %s ret %d\n", info->name, ret); + goto err_gpio_dir; + } + info->state = info->init; return ret; -set_wlan_pin_active: +err_gpio_dir: + gpio_free(info->num); - if (penv->wlan_en_vreg_support) - ret = regulator_enable(vreg_info->wlan_en_reg); - else - ret = pinctrl_select_state( - cnss_pinctrl->pinctrl, cnss_pinctrl->wlan_en_active); - msleep(WLAN_ENABLE_DELAY); +err_gpio_req: return ret; } -static int cnss_select_pinctrl_active( - struct cnss_wlan_pinctrl *cnss_pinctrl, bool active) +static int cnss_wlan_bootstrap_gpio_init(void) { - int ret; - struct cnss_wlan_vreg_info *vreg_info = &penv->vreg_info; - - if (!active) - goto select_sleep_state; + int ret = 0; - if (cnss_pinctrl->bootstrap_enable) { - ret = pinctrl_select_state( - cnss_pinctrl->pinctrl, cnss_pinctrl->bootstrap_active); - msleep(WLAN_BOOTSTRAP_DELAY); + ret = gpio_request(penv->wlan_bootstrap_gpio, WLAN_BOOTSTRAP_GPIO_NAME); + if (ret) { + pr_err("%s: Can't get GPIO %s, ret = %d\n", + __func__, WLAN_BOOTSTRAP_GPIO_NAME, ret); + goto out; } - ret = cnss_wlan_enable_pin_set_state(cnss_pinctrl, vreg_info, true); - return ret; - -select_sleep_state: - if (cnss_pinctrl->bootstrap_enable) { - ret = pinctrl_select_state( - cnss_pinctrl->pinctrl, cnss_pinctrl->bootstrap_sleep); - msleep(WLAN_BOOTSTRAP_DELAY); + ret = gpio_direction_output(penv->wlan_bootstrap_gpio, + WLAN_BOOTSTRAP_HIGH); + if (ret) { + pr_err("%s: Can't set GPIO %s direction, ret = %d\n", + __func__, WLAN_BOOTSTRAP_GPIO_NAME, ret); + gpio_free(penv->wlan_bootstrap_gpio); + goto out; } - ret = cnss_wlan_enable_pin_set_state(cnss_pinctrl, vreg_info, false); + msleep(WLAN_BOOTSTRAP_DELAY); +out: return ret; } -static int cnss_pinctrl_init( - struct cnss_wlan_pinctrl *cnss_pinctrl, - struct device *dev) +static void cnss_wlan_gpio_set(struct cnss_wlan_gpio_info *info, bool state) { - int ret = 0; - struct device_node *node = dev->of_node; + if (!info->prop) + return; - cnss_pinctrl->pinctrl = devm_pinctrl_get(dev); - if (IS_ERR_OR_NULL(cnss_pinctrl->pinctrl)) { - pr_err("%s:Failed to get pinctrl!\n", __func__); - return PTR_ERR(cnss_pinctrl->pinctrl); + if (info->state == state) { + pr_debug("Already %s gpio is %s\n", + info->name, state ? "high" : "low"); + return; } - if (penv->wlan_en_vreg_support) - goto skip_wlan_enable_pin_config; - - cnss_pinctrl->wlan_en_active = - pinctrl_lookup_state(cnss_pinctrl->pinctrl, WLAN_EN_ACTIVE); - if (IS_ERR_OR_NULL(cnss_pinctrl->wlan_en_active)) { - pr_err("%s:Failed to get wlan_en active state!\n", __func__); - return PTR_ERR(cnss_pinctrl->wlan_en_active); + if (state == WLAN_EN_LOW && penv->dual_wifi_info.is_dual_wifi_enabled) { + pr_debug("%s Dual WiFi enabled\n", __func__); + return; } - cnss_pinctrl->wlan_en_sleep = - pinctrl_lookup_state(cnss_pinctrl->pinctrl, WLAN_EN_SLEEP); - if (IS_ERR_OR_NULL(cnss_pinctrl->wlan_en_sleep)) { - pr_err("%s:Failed to get wlan_en sleep state!\n", __func__); - return PTR_ERR(cnss_pinctrl->wlan_en_sleep); + gpio_set_value(info->num, state); + info->state = state; + + pr_debug("%s: %s gpio is now %s\n", __func__, + info->name, info->state ? "enabled" : "disabled"); +} + +static int cnss_configure_wlan_en_gpio(bool state) +{ + int ret = 0; + struct cnss_wlan_gpio_info *gpio_info = &penv->gpio_info; + struct cnss_wlan_vreg_info *vreg_info = &penv->vreg_info; + + if (penv->wlan_en_vreg_support) { + if (state) + ret = regulator_enable(vreg_info->wlan_en_reg); + else + ret = regulator_disable(vreg_info->wlan_en_reg); + } else { + cnss_wlan_gpio_set(gpio_info, state); } - ret = pinctrl_select_state( - cnss_pinctrl->pinctrl, cnss_pinctrl->wlan_en_active); msleep(WLAN_ENABLE_DELAY); + return ret; +} -skip_wlan_enable_pin_config: - cnss_pinctrl->bootstrap_enable = - of_property_read_bool(node, "qcom,enable-bootstrap-gpio"); - - if (!cnss_pinctrl->bootstrap_enable) - goto end; +static int cnss_pinctrl_init(struct cnss_wlan_gpio_info *gpio_info, + struct platform_device *pdev) +{ + int ret; - cnss_pinctrl->bootstrap_active = - pinctrl_lookup_state(cnss_pinctrl->pinctrl, BOOTSTRAP_ACTIVE); - if (IS_ERR_OR_NULL(cnss_pinctrl->bootstrap_active)) { - pr_err("%s:Failed to get bootstrap active state!\n", __func__); - return PTR_ERR(cnss_pinctrl->bootstrap_active); + gpio_info->pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR_OR_NULL(gpio_info->pinctrl)) { + pr_err("%s: Failed to get pinctrl!\n", __func__); + return PTR_ERR(gpio_info->pinctrl); } - cnss_pinctrl->bootstrap_sleep = - pinctrl_lookup_state(cnss_pinctrl->pinctrl, BOOTSTRAP_SLEEP); - if (IS_ERR_OR_NULL(cnss_pinctrl->bootstrap_sleep)) { - pr_err("%s:Failed to get bootstrap sleep state!\n", __func__); - return PTR_ERR(cnss_pinctrl->bootstrap_sleep); + gpio_info->gpio_state_default = pinctrl_lookup_state(gpio_info->pinctrl, + CNSS_PINCTRL_STATE_ACTIVE); + if (IS_ERR_OR_NULL(gpio_info->gpio_state_default)) { + pr_err("%s: Can not get active pin state!\n", __func__); + return PTR_ERR(gpio_info->gpio_state_default); } - ret = pinctrl_select_state( - cnss_pinctrl->pinctrl, cnss_pinctrl->bootstrap_active); - msleep(WLAN_BOOTSTRAP_DELAY); + ret = pinctrl_select_state(gpio_info->pinctrl, + gpio_info->gpio_state_default); -end: return ret; } -static void cnss_disable_xtal_ldo(void) +static void cnss_disable_xtal_ldo(struct platform_device *pdev) { struct cnss_wlan_vreg_info *info = &penv->vreg_info; @@ -633,16 +646,17 @@ static void cnss_disable_xtal_ldo(void) } } -static int cnss_enable_xtal_ldo(struct device *dev) +static int cnss_enable_xtal_ldo(struct platform_device *pdev) { int ret = 0; struct cnss_wlan_vreg_info *info = &penv->vreg_info; - struct device_node *node = dev->of_node; - if (!of_get_property(node, WLAN_VREG_XTAL_AON_NAME "-supply", NULL)) + if (!of_get_property(pdev->dev.of_node, + WLAN_VREG_XTAL_AON_NAME "-supply", NULL)) goto enable_xtal; - info->wlan_reg_xtal_aon = regulator_get(dev, WLAN_VREG_XTAL_AON_NAME); + info->wlan_reg_xtal_aon = regulator_get(&pdev->dev, + WLAN_VREG_XTAL_AON_NAME); if (IS_ERR(info->wlan_reg_xtal_aon)) { ret = PTR_ERR(info->wlan_reg_xtal_aon); pr_err("%s: XTAL AON Regulator get failed err:%d\n", __func__, @@ -658,10 +672,11 @@ static int cnss_enable_xtal_ldo(struct device *dev) enable_xtal: - if (!of_get_property(node, WLAN_VREG_XTAL_NAME "-supply", NULL)) + if (!of_get_property(pdev->dev.of_node, + WLAN_VREG_XTAL_NAME "-supply", NULL)) goto out_disable_xtal_aon; - info->wlan_reg_xtal = regulator_get(dev, WLAN_VREG_XTAL_NAME); + info->wlan_reg_xtal = regulator_get(&pdev->dev, WLAN_VREG_XTAL_NAME); if (IS_ERR(info->wlan_reg_xtal)) { ret = PTR_ERR(info->wlan_reg_xtal); @@ -699,15 +714,73 @@ end: return ret; } -static int cnss_wlan_enable_vreg_regulators(struct device *dev) +static int cnss_get_wlan_enable_gpio( + struct cnss_wlan_gpio_info *gpio_info, + struct platform_device *pdev) +{ + int ret = 0; + struct device *dev = &pdev->dev; + + if (!of_find_property(dev->of_node, gpio_info->name, NULL)) { + gpio_info->prop = false; + return -ENODEV; + } + + gpio_info->prop = true; + ret = of_get_named_gpio(dev->of_node, gpio_info->name, 0); + if (ret >= 0) { + gpio_info->num = ret; + } else { + if (ret == -EPROBE_DEFER) + pr_debug("get WLAN_EN GPIO probe defer\n"); + else + pr_err( + "can't get gpio %s ret %d", gpio_info->name, ret); + } + + ret = cnss_pinctrl_init(gpio_info, pdev); + if (ret) + pr_debug("%s: pinctrl init failed!\n", __func__); + + ret = cnss_wlan_gpio_init(gpio_info); + if (ret) + pr_err("gpio init failed\n"); + + return ret; +} + +static int cnss_get_wlan_bootstrap_gpio(struct platform_device *pdev) { int ret = 0; + struct device_node *node = (&pdev->dev)->of_node; + + if (!of_find_property(node, WLAN_BOOTSTRAP_GPIO_NAME, NULL)) + return ret; + + penv->wlan_bootstrap_gpio = + of_get_named_gpio(node, WLAN_BOOTSTRAP_GPIO_NAME, 0); + if (penv->wlan_bootstrap_gpio > 0) { + ret = cnss_wlan_bootstrap_gpio_init(); + } else { + ret = penv->wlan_bootstrap_gpio; + pr_err( + "%s: Can't get GPIO %s, ret = %d", + __func__, WLAN_BOOTSTRAP_GPIO_NAME, ret); + } + + return ret; +} + +static int cnss_wlan_get_resources(struct platform_device *pdev) +{ + int ret = 0; + struct cnss_wlan_gpio_info *gpio_info = &penv->gpio_info; struct cnss_wlan_vreg_info *vreg_info = &penv->vreg_info; - struct device_node *node = dev->of_node; + struct device_node *node = pdev->dev.of_node; if (of_get_property(node, WLAN_VREG_CORE_NAME "-supply", NULL)) { - vreg_info->wlan_reg_core = - regulator_get(dev, WLAN_VREG_CORE_NAME); + vreg_info->wlan_reg_core = regulator_get(&pdev->dev, + WLAN_VREG_CORE_NAME); if (IS_ERR(vreg_info->wlan_reg_core)) { ret = PTR_ERR(vreg_info->wlan_reg_core); @@ -736,7 +809,8 @@ static int cnss_wlan_enable_vreg_regulators(struct device *dev) } if (of_get_property(node, WLAN_VREG_IO_NAME "-supply", NULL)) { - vreg_info->wlan_reg_io = regulator_get(dev, WLAN_VREG_IO_NAME); + vreg_info->wlan_reg_io = regulator_get(&pdev->dev, + WLAN_VREG_IO_NAME); if (!IS_ERR(vreg_info->wlan_reg_io)) { ret = regulator_set_voltage(vreg_info->wlan_reg_io, WLAN_VREG_IO_MIN, WLAN_VREG_IO_MAX); @@ -758,10 +832,10 @@ static int cnss_wlan_enable_vreg_regulators(struct device *dev) } } - if (cnss_enable_xtal_ldo(dev)) + if (cnss_enable_xtal_ldo(pdev)) goto err_reg_xtal_enable; - vreg_info->wlan_reg = regulator_get(dev, WLAN_VREG_NAME); + 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) @@ -781,7 +855,7 @@ static int cnss_wlan_enable_vreg_regulators(struct device *dev) if (of_get_property(node, WLAN_VREG_SP2T_NAME "-supply", NULL)) { vreg_info->wlan_reg_sp2t = - regulator_get(dev, WLAN_VREG_SP2T_NAME); + regulator_get(&pdev->dev, WLAN_VREG_SP2T_NAME); if (!IS_ERR(vreg_info->wlan_reg_sp2t)) { ret = regulator_set_voltage(vreg_info->wlan_reg_sp2t, WLAN_VREG_SP2T_MIN, WLAN_VREG_SP2T_MAX); @@ -802,7 +876,7 @@ static int cnss_wlan_enable_vreg_regulators(struct device *dev) if (of_get_property(node, WLAN_ANT_SWITCH_NAME "-supply", NULL)) { vreg_info->ant_switch = - regulator_get(dev, WLAN_ANT_SWITCH_NAME); + regulator_get(&pdev->dev, WLAN_ANT_SWITCH_NAME); if (!IS_ERR(vreg_info->ant_switch)) { ret = regulator_set_voltage(vreg_info->ant_switch, WLAN_ANT_SWITCH_VOLT_MIN, @@ -834,7 +908,8 @@ static int cnss_wlan_enable_vreg_regulators(struct device *dev) penv->cap.cap_flag |= CNSS_HAS_UART_ACCESS; if (of_get_property(node, WLAN_SWREG_NAME "-supply", NULL)) { - vreg_info->soc_swreg = regulator_get(dev, WLAN_SWREG_NAME); + vreg_info->soc_swreg = regulator_get(&pdev->dev, + WLAN_SWREG_NAME); if (IS_ERR(vreg_info->soc_swreg)) { pr_err("%s: soc-swreg node not found\n", __func__); @@ -858,19 +933,36 @@ static int cnss_wlan_enable_vreg_regulators(struct device *dev) penv->wlan_en_vreg_support = of_property_read_bool(node, "qcom,wlan-en-vreg-support"); if (penv->wlan_en_vreg_support) { - vreg_info->wlan_en_reg = regulator_get(dev, WLAN_EN_VREG_NAME); + vreg_info->wlan_en_reg = + regulator_get(&pdev->dev, WLAN_EN_VREG_NAME); if (IS_ERR(vreg_info->wlan_en_reg)) { pr_err("%s:wlan_en vreg get failed\n", __func__); ret = PTR_ERR(vreg_info->wlan_en_reg); goto err_wlan_en_reg_get; } - - ret = regulator_enable(vreg_info->wlan_en_reg); } + if (!penv->wlan_en_vreg_support) { + ret = cnss_get_wlan_enable_gpio(gpio_info, pdev); + if (ret) { + pr_err( + "%s:Failed to config the WLAN_EN gpio\n", __func__); + goto err_gpio_wlan_en; + } + } vreg_info->state = VREG_ON; + + ret = cnss_get_wlan_bootstrap_gpio(pdev); + if (ret) { + pr_err("%s: Failed to enable wlan bootstrap gpio\n", __func__); + goto err_gpio_wlan_bootstrap; + } + return ret; +err_gpio_wlan_bootstrap: + cnss_put_wlan_enable_gpio(); +err_gpio_wlan_en: err_wlan_en_reg_get: vreg_info->wlan_en_reg = NULL; if (vreg_info->soc_swreg) @@ -902,7 +994,7 @@ err_reg_sp2t_set: err_reg_enable: regulator_put(vreg_info->wlan_reg); err_reg_get: - cnss_disable_xtal_ldo(); + cnss_disable_xtal_ldo(pdev); err_reg_xtal_enable: if (vreg_info->wlan_reg_io) @@ -926,15 +1018,15 @@ err_reg_core_get: static void cnss_wlan_release_resources(void) { + struct cnss_wlan_gpio_info *gpio_info = &penv->gpio_info; struct cnss_wlan_vreg_info *vreg_info = &penv->vreg_info; + if (penv->wlan_bootstrap_gpio > 0) + gpio_free(penv->wlan_bootstrap_gpio); + cnss_put_wlan_enable_gpio(); + gpio_info->state = WLAN_EN_LOW; + gpio_info->prop = false; cnss_wlan_vreg_set(vreg_info, VREG_OFF); - if (penv->wlan_en_vreg_support) { - if (vreg_info->wlan_en_reg) { - regulator_disable(vreg_info->wlan_en_reg); - regulator_put(vreg_info->wlan_en_reg); - } - } if (vreg_info->soc_swreg) regulator_put(vreg_info->soc_swreg); if (vreg_info->ant_switch) @@ -953,31 +1045,6 @@ static void cnss_wlan_release_resources(void) vreg_info->state = VREG_OFF; } -static int cnss_wlan_get_resources(struct platform_device *pdev) -{ - int ret = 0; - struct device *dev = &pdev->dev; - struct cnss_wlan_pinctrl *cnss_pinctrl = &penv->cnss_pinctrl; - - ret = cnss_wlan_enable_vreg_regulators(dev); - if (ret) { - pr_err("%s: failed to enable the vreg_regulators\n", __func__); - return ret; - } - - ret = cnss_pinctrl_init(cnss_pinctrl, dev); - if (ret) { - pr_err("%s: pinctrl init failed!\n", __func__); - goto err_pinctrl_init; - } - - return ret; - -err_pinctrl_init: - cnss_wlan_release_resources(); - return ret; -} - static u8 cnss_get_pci_dev_bus_number(struct pci_dev *pdev) { return pdev->bus->number; @@ -1550,7 +1617,6 @@ static int cnss_wlan_pci_probe(struct pci_dev *pdev, { int ret = 0; struct cnss_wlan_vreg_info *vreg_info = &penv->vreg_info; - struct cnss_wlan_pinctrl *cnss_pinctrl = &penv->cnss_pinctrl; void *cpu_addr; dma_addr_t dma_handle; struct codeswap_codeseg_info *cnss_seg_info = NULL; @@ -1609,13 +1675,9 @@ static int cnss_wlan_pci_probe(struct pci_dev *pdev, penv->pcie_link_state = PCIE_LINK_DOWN; } - ret = cnss_select_pinctrl_active(cnss_pinctrl, false); - if (ret) { - pr_err("%s:Failed to enable wlan_en pin\n", __func__); - goto err_pcie_suspend; - } - + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); ret = cnss_wlan_vreg_set(vreg_info, VREG_OFF); + if (ret) { pr_err("can't turn off wlan vreg\n"); goto err_pcie_suspend; @@ -2206,7 +2268,7 @@ int cnss_wlan_register_driver(struct cnss_wlan_driver *driver) int probe_again = 0; struct cnss_wlan_driver *wdrv; struct cnss_wlan_vreg_info *vreg_info; - struct cnss_wlan_pinctrl *cnss_pinctrl; + struct cnss_wlan_gpio_info *gpio_info; struct pci_dev *pdev; if (!penv) @@ -2214,7 +2276,7 @@ int cnss_wlan_register_driver(struct cnss_wlan_driver *driver) wdrv = penv->driver; vreg_info = &penv->vreg_info; - cnss_pinctrl = &penv->cnss_pinctrl; + gpio_info = &penv->gpio_info; pdev = penv->pdev; if (!wdrv) { @@ -2230,11 +2292,15 @@ again: pr_err("wlan vreg ON failed\n"); goto err_wlan_vreg_on; } + msleep(POWER_ON_DELAY); - ret = cnss_select_pinctrl_active(cnss_pinctrl, true); - if (ret) - pr_err("%s:Failed to set cnss pin active state\n", __func__); + if (penv->wlan_bootstrap_gpio > 0) { + gpio_set_value(penv->wlan_bootstrap_gpio, WLAN_BOOTSTRAP_HIGH); + msleep(WLAN_BOOTSTRAP_DELAY); + } + + cnss_configure_wlan_en_gpio(WLAN_EN_HIGH); if (!pdev) { pr_debug("%s: invalid pdev. register pci device\n", __func__); @@ -2317,8 +2383,7 @@ again: cnss_get_pci_dev_bus_number(pdev), pdev, PM_OPTIONS); penv->pcie_link_state = PCIE_LINK_DOWN; - ret = cnss_select_pinctrl_active(cnss_pinctrl, false); - msleep(WLAN_ENABLE_DELAY); + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); cnss_wlan_vreg_set(vreg_info, VREG_OFF); msleep(POWER_ON_DELAY); probe_again++; @@ -2345,7 +2410,7 @@ err_pcie_link_up: } err_pcie_reg: - ret = cnss_select_pinctrl_active(cnss_pinctrl, false); + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); cnss_wlan_vreg_set(vreg_info, VREG_OFF); if (penv->pdev) { pr_err("%d: Unregistering PCI device\n", __LINE__); @@ -2365,7 +2430,7 @@ void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver) { struct cnss_wlan_driver *wdrv; struct cnss_wlan_vreg_info *vreg_info; - struct cnss_wlan_pinctrl *cnss_pinctrl; + struct cnss_wlan_gpio_info *gpio_info; struct pci_dev *pdev; if (!penv) @@ -2373,7 +2438,7 @@ void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver) wdrv = penv->driver; vreg_info = &penv->vreg_info; - cnss_pinctrl = &penv->cnss_pinctrl; + gpio_info = &penv->gpio_info; pdev = penv->pdev; if (!wdrv) { @@ -2425,8 +2490,8 @@ void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver) cut_power: penv->driver = NULL; - if (cnss_select_pinctrl_active(cnss_pinctrl, false)) - pr_err("%s: Failed disable the wlan_en pin\n", __func__); + + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); if (cnss_wlan_vreg_set(vreg_info, VREG_OFF)) pr_err("wlan vreg OFF failed\n"); } @@ -2506,7 +2571,7 @@ static int cnss_shutdown(const struct subsys_desc *subsys, bool force_stop) struct cnss_wlan_driver *wdrv; struct pci_dev *pdev; struct cnss_wlan_vreg_info *vreg_info; - struct cnss_wlan_pinctrl *cnss_pinctrl; + struct cnss_wlan_gpio_info *gpio_info; int ret = 0; if (!penv) @@ -2516,7 +2581,7 @@ static int cnss_shutdown(const struct subsys_desc *subsys, bool force_stop) wdrv = penv->driver; pdev = penv->pdev; vreg_info = &penv->vreg_info; - cnss_pinctrl = &penv->cnss_pinctrl; + gpio_info = &penv->gpio_info; if (!pdev) { ret = -EINVAL; @@ -2538,10 +2603,7 @@ static int cnss_shutdown(const struct subsys_desc *subsys, bool force_stop) } cut_power: - ret = cnss_select_pinctrl_active(cnss_pinctrl, false); - if (ret) - pr_err("%s:Failed to disable the wlan_en pin\n", __func__); - + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); if (cnss_wlan_vreg_set(vreg_info, VREG_OFF)) pr_err("cnss: Failed to set WLAN VREG_OFF!\n"); @@ -2553,7 +2615,7 @@ static int cnss_powerup(const struct subsys_desc *subsys) struct cnss_wlan_driver *wdrv; struct pci_dev *pdev; struct cnss_wlan_vreg_info *vreg_info; - struct cnss_wlan_pinctrl *cnss_pinctrl; + struct cnss_wlan_gpio_info *gpio_info; int ret = 0; if (!penv) @@ -2565,7 +2627,7 @@ static int cnss_powerup(const struct subsys_desc *subsys) wdrv = penv->driver; pdev = penv->pdev; vreg_info = &penv->vreg_info; - cnss_pinctrl = &penv->cnss_pinctrl; + gpio_info = &penv->gpio_info; ret = cnss_wlan_vreg_set(vreg_info, VREG_ON); if (ret) { @@ -2574,11 +2636,7 @@ static int cnss_powerup(const struct subsys_desc *subsys) } msleep(POWER_ON_DELAY); - ret = cnss_select_pinctrl_active(cnss_pinctrl, true); - if (ret) { - pr_err("%s: Failed to enable wlan_en pin\n", __func__); - goto err_wlan_en_pin_set; - } + cnss_configure_wlan_en_gpio(WLAN_EN_HIGH); if (!pdev) { pr_err("%d: invalid pdev\n", __LINE__); @@ -2637,9 +2695,8 @@ err_wlan_reinit: pdev, PM_OPTIONS); penv->pcie_link_state = PCIE_LINK_DOWN; -err_wlan_en_pin_set: err_pcie_link_up: - ret = cnss_select_pinctrl_active(cnss_pinctrl, false); + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); cnss_wlan_vreg_set(vreg_info, VREG_OFF); if (penv->pdev) { pr_err("%d: Unregistering pci device\n", __LINE__); @@ -2813,6 +2870,11 @@ static int cnss_probe(struct platform_device *pdev) penv->pldev = pdev; penv->esoc_desc = NULL; + penv->gpio_info.name = WLAN_EN_GPIO_NAME; + penv->gpio_info.num = 0; + penv->gpio_info.state = WLAN_EN_LOW; + penv->gpio_info.init = WLAN_EN_LOW; + penv->gpio_info.prop = false; penv->vreg_info.wlan_reg = NULL; penv->vreg_info.state = VREG_OFF; penv->pci_register_again = false; @@ -2821,6 +2883,12 @@ static int cnss_probe(struct platform_device *pdev) if (ret) goto err_get_wlan_res; + ret = cnss_configure_wlan_en_gpio(WLAN_EN_HIGH); + if (ret) { + pr_err("%s: Failed to enable WLAN enable gpio\n", __func__); + goto err_get_rc; + } + ret = of_property_read_u32(dev->of_node, "qcom,wlan-rc-num", &rc_num); if (ret) { pr_err("%s: Failed to find PCIe RC number!\n", __func__); @@ -3014,7 +3082,7 @@ err_subsys_reg: err_esoc_reg: err_pcie_enumerate: err_get_rc: - ret = cnss_select_pinctrl_active(&penv->cnss_pinctrl, false); + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); cnss_wlan_release_resources(); err_get_wlan_res: @@ -3045,7 +3113,9 @@ static int cnss_remove(struct platform_device *pdev) } } - cnss_select_pinctrl_active(&penv->cnss_pinctrl, false); + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); + if (penv->wlan_bootstrap_gpio > 0) + gpio_set_value(penv->wlan_bootstrap_gpio, WLAN_BOOTSTRAP_LOW); cnss_wlan_release_resources(); return 0; @@ -3519,11 +3589,11 @@ static struct pci_dev *__cnss_get_pcie_dev(struct device *dev) static int __cnss_pcie_power_up(struct device *dev) { struct cnss_wlan_vreg_info *vreg_info; - struct cnss_wlan_pinctrl *cnss_pinctrl; + struct cnss_wlan_gpio_info *gpio_info; int ret; vreg_info = &penv->vreg_info; - cnss_pinctrl = &penv->cnss_pinctrl; + gpio_info = &penv->gpio_info; ret = cnss_wlan_vreg_set(vreg_info, VREG_ON); if (ret) { @@ -3533,27 +3603,27 @@ static int __cnss_pcie_power_up(struct device *dev) msleep(POWER_ON_DELAY); - ret = cnss_select_pinctrl_active(cnss_pinctrl, true); - if (ret) - pr_err("%s: Failed to select the default state\n", __func__); + if (penv->wlan_bootstrap_gpio > 0) { + gpio_set_value(penv->wlan_bootstrap_gpio, WLAN_BOOTSTRAP_HIGH); + msleep(WLAN_BOOTSTRAP_DELAY); + } - return ret; + cnss_configure_wlan_en_gpio(WLAN_EN_HIGH); + return 0; } static int __cnss_pcie_power_down(struct device *dev) { struct cnss_wlan_vreg_info *vreg_info; - struct cnss_wlan_pinctrl *cnss_pinctrl; + struct cnss_wlan_gpio_info *gpio_info; int ret; vreg_info = &penv->vreg_info; - cnss_pinctrl = &penv->cnss_pinctrl; + gpio_info = &penv->gpio_info; - ret = cnss_select_pinctrl_active(cnss_pinctrl, false); - if (ret) { - pr_err("%s: Failed to select the default state\n", __func__); - return ret; - } + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); + if (penv->wlan_bootstrap_gpio > 0) + gpio_set_value(penv->wlan_bootstrap_gpio, WLAN_BOOTSTRAP_LOW); ret = cnss_wlan_vreg_set(vreg_info, VREG_OFF); if (ret) diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c index 3f9eeabc..f32e5d2a 100644 --- a/drivers/net/wireless/wcnss/wcnss_wlan.c +++ b/drivers/net/wireless/wcnss/wcnss_wlan.c @@ -2123,10 +2123,8 @@ exit: return; } - -static void wcnssctrl_rx_handler(struct work_struct *worker) +static void wcnss_process_smd_msg(int len) { - int len = 0; int rc = 0; unsigned char buf[sizeof(struct wcnss_version)]; unsigned char build[WCNSS_MAX_BUILD_VER_LEN+1]; @@ -2136,17 +2134,6 @@ static void wcnssctrl_rx_handler(struct work_struct *worker) int hw_type; unsigned char fw_status = 0; - len = smd_read_avail(penv->smd_ch); - if (len > WCNSS_MAX_FRAME_SIZE) { - pr_err("wcnss: frame larger than the allowed size\n"); - smd_read(penv->smd_ch, NULL, len); - return; - } - if (len < sizeof(struct smd_msg_hdr)) { - pr_err("wcnss: incomplete header available len = %d\n", len); - return; - } - rc = smd_read(penv->smd_ch, buf, sizeof(struct smd_msg_hdr)); if (rc < sizeof(struct smd_msg_hdr)) { pr_err("wcnss: incomplete header read from smd\n"); @@ -2213,7 +2200,7 @@ static void wcnssctrl_rx_handler(struct work_struct *worker) case WCNSS_BUILD_VER_RSP: if (len > WCNSS_MAX_BUILD_VER_LEN) { pr_err("wcnss: invalid build version data from wcnss %d\n", - len); + len); return; } rc = smd_read(penv->smd_ch, build, len); @@ -2245,7 +2232,6 @@ static void wcnssctrl_rx_handler(struct work_struct *worker) penv->is_cbc_done = 1; pr_debug("wcnss: received WCNSS_CBC_COMPLETE_IND from FW\n"); break; - case WCNSS_CALDATA_UPLD_REQ: extract_cal_data(len); break; @@ -2256,6 +2242,33 @@ static void wcnssctrl_rx_handler(struct work_struct *worker) return; } +static void wcnssctrl_rx_handler(struct work_struct *worker) +{ + int len; + + while (1) { + len = smd_read_avail(penv->smd_ch); + if (0 == len) { + pr_debug("wcnss: No more data to be read\n"); + return; + } + + if (len > WCNSS_MAX_FRAME_SIZE) { + pr_err("wcnss: frame larger than the allowed size\n"); + smd_read(penv->smd_ch, NULL, len); + return; + } + + if (len < sizeof(struct smd_msg_hdr)) { + pr_err("wcnss: incomplete header available len = %d\n", + len); + return; + } + + wcnss_process_smd_msg(len); + } +} + static void wcnss_send_version_req(struct work_struct *worker) { struct smd_msg_hdr smd_msg; |
