diff options
| author | Randy Chiu <wchiu@qca.qualcomm.com> | 2014-05-28 14:39:44 +0800 |
|---|---|---|
| committer | Pitani Venkata Rajesh Kumar <c_vpitan@qti.qualcomm.com> | 2014-05-30 19:19:03 +0530 |
| commit | abc26dde5e439fa2df8f8d0702a090861ec29360 (patch) | |
| tree | a0df5cf896ef39a95725171042d6f606798653e1 | |
| parent | e72638d135e493ed514288baf0ffaa2a4252c253 (diff) | |
qcacld: Unload time is too long for ROME USB
It takes a long time to remove cld driver.
Add two methods to speed up.
1.usb_disable_lpm
2.Move __hdd_wlan_exit before usb_deregister
Change-Id: I8b6767e831d12ade1d362f40835593105bcd5cb3
CRs-fixed: 671037
| -rw-r--r-- | CORE/SERVICES/HIF/USB/if_usb.c | 77 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/USB/if_usb.h | 2 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 6 |
3 files changed, 70 insertions, 15 deletions
diff --git a/CORE/SERVICES/HIF/USB/if_usb.c b/CORE/SERVICES/HIF/USB/if_usb.c index 2e86857e3989..b94512aa2d1b 100644 --- a/CORE/SERVICES/HIF/USB/if_usb.c +++ b/CORE/SERVICES/HIF/USB/if_usb.c @@ -55,6 +55,8 @@ unsigned int msienable; module_param(msienable, int, 0644); +struct hif_usb_softc *usb_sc; +static int hif_usb_resume(struct usb_interface *interface); static int hif_usb_configure(struct hif_usb_softc *sc, hif_handle_t *hif_hdl, @@ -105,6 +107,7 @@ hif_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) int vendor_id, product_id; pr_info("hif_usb_probe\n"); + usb_disable_lpm(pdev); usb_get_dev(pdev); vendor_id = le16_to_cpu(pdev->descriptor.idVendor); product_id = le16_to_cpu(pdev->descriptor.idProduct); @@ -116,7 +119,7 @@ hif_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) ret = -ENOMEM; goto err_alloc; } - + usb_sc = sc; OS_MEMZERO(sc, sizeof(*sc)); sc->pdev = (void *)pdev; sc->dev = &pdev->dev; @@ -179,6 +182,7 @@ hif_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) athdiag_procfs_remove(); goto err_config; } + sc->hdd_removed = 0; #ifndef REMOVE_PKT_LOG if (vos_get_conparam() != VOS_FTM_MODE) { /* @@ -226,6 +230,7 @@ static void hif_usb_remove(struct usb_interface *interface) return; HIFDiagWriteWARMRESET(interface, 0, 0); + sc->local_state.event = 0; unregister_reboot_notifier(&sc->reboot_notifier); usb_put_dev(interface_to_usbdev(interface)); @@ -234,13 +239,15 @@ static void hif_usb_remove(struct usb_interface *interface) if (vos_get_conparam() != VOS_FTM_MODE) pktlogmod_exit(scn); #endif - - __hdd_wlan_exit(); + if (usb_sc->hdd_removed == 0) { + __hdd_wlan_exit(); + usb_sc->hdd_removed = 1; + } hif_nointrs(sc); HIF_USBDeviceDetached(interface, 1); A_FREE(scn); A_FREE(sc); - + usb_sc = NULL; pr_info("hif_usb_remove!!!!!!\n"); } @@ -252,12 +259,27 @@ void hdd_suspend_wlan(void (*callback) (void *callbackContext), static int hif_usb_suspend(struct usb_interface *interface, pm_message_t state) { HIF_DEVICE_USB *device = usb_get_intfdata(interface); + struct hif_usb_softc *sc = device->sc; void *vos = vos_get_global_context(VOS_MODULE_ID_HIF, NULL); + v_VOID_t * temp_module; + + if (vos == NULL) + return 0; + /* No need to send WMI_PDEV_SUSPEND_CMDID to FW if WOW is enabled */ + temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos); + if (!temp_module) { + printk("%s: WDA module is NULL\n", __func__); + return (-1); + } + if (wma_check_scan_in_progress(temp_module)) { + printk("%s: Scan in progress. Aborting suspend\n", __func__); + return (-1); + } + sc->local_state = state; /* No need to send WMI_PDEV_SUSPEND_CMDID to FW if WOW is enabled */ - if (wma_is_wow_mode_selected(vos_get_context(VOS_MODULE_ID_WDA, vos))) { - if (wma_enable_wow_in_fw - (vos_get_context(VOS_MODULE_ID_WDA, vos))) { + if (wma_is_wow_mode_selected(temp_module)) { + if (wma_enable_wow_in_fw(temp_module)) { pr_warn("%s[%d]: fail\n", __func__, __LINE__); return -1; } @@ -281,8 +303,24 @@ void hdd_resume_wlan(void); static int hif_usb_resume(struct usb_interface *interface) { HIF_DEVICE_USB *device = usb_get_intfdata(interface); - void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL); + struct hif_usb_softc *sc = device->sc; + void *vos = vos_get_global_context(VOS_MODULE_ID_HIF, NULL); + v_VOID_t * temp_module; + + if (vos == NULL) + return 0; + /* No need to send WMI_PDEV_SUSPEND_CMDID to FW if WOW is enabled */ + temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos); + if (!temp_module) { + printk("%s: WDA module is NULL\n", __func__); + return (-1); + } + if (wma_check_scan_in_progress(temp_module)) { + printk("%s: Scan in progress. Aborting suspend\n", __func__); + return (-1); + } + sc->local_state.event = 0; usb_hif_start_recv_pipes(device); #ifdef USB_HIF_TEST_INTERRUPT_IN @@ -290,11 +328,9 @@ static int hif_usb_resume(struct usb_interface *interface) HIF_USB_RX_BUFFER_SIZE); #endif /* No need to send WMI_PDEV_RESUME_CMDID to FW if WOW is enabled */ - if (!wma_is_wow_mode_selected - (vos_get_context(VOS_MODULE_ID_WDA, vos_context))) { - wma_resume_target(vos_get_context - (VOS_MODULE_ID_WDA, vos_context)); - } else if (wma_disable_wow_in_fw(vos_get_context(VOS_MODULE_ID_WDA, vos_context))) { + if (!wma_is_wow_mode_selected(temp_module)) { + wma_resume_target(temp_module); + } else if (wma_disable_wow_in_fw(temp_module)) { return (-1); } @@ -308,8 +344,8 @@ static int hif_usb_reset_resume(struct usb_interface *intf) HIFDiagWriteAccess(sc->hif_device, (ROME_USB_SOC_RESET_CONTROL_COLD_RST_LSB | - ROME_USB_RTC_SOC_BASE_ADDRESS), - SOC_RESET_CONTROL_COLD_RST_SET(1)); + ROME_USB_RTC_SOC_BASE_ADDRESS), + SOC_RESET_CONTROL_COLD_RST_SET(1)); return 0; } @@ -354,6 +390,17 @@ int hif_register_driver(void) void hif_unregister_driver(void) { if (is_usb_driver_register) { + if (usb_sc != NULL) { + if (usb_sc->local_state.event != 0) { + hif_usb_resume(usb_sc->interface); + usb_sc->local_state.event = 0; + } + + if (usb_sc->hdd_removed == 0) { + __hdd_wlan_exit(); + usb_sc->hdd_removed = 1; + } + } is_usb_driver_register = 0; usb_deregister(&hif_usb_drv_id); } diff --git a/CORE/SERVICES/HIF/USB/if_usb.h b/CORE/SERVICES/HIF/USB/if_usb.h index 05e41f9d321d..cbada95f4902 100644 --- a/CORE/SERVICES/HIF/USB/if_usb.h +++ b/CORE/SERVICES/HIF/USB/if_usb.h @@ -76,6 +76,8 @@ struct hif_usb_softc { struct hostdef_s *hostdef; struct usb_interface *interface; struct notifier_block reboot_notifier; /* default mode before reboot */ + pm_message_t local_state; + int hdd_removed; }; #if defined(CONFIG_ATH_PROCFS_DIAG_SUPPORT) int athdiag_procfs_init(void *scn); diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index a6b6c0bb0775..518c420b523c 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -18085,10 +18085,16 @@ VOS_STATUS wma_stop(v_VOID_t *vos_ctx, tANI_U8 reason) #ifdef QCA_WIFI_ISOC wma_hal_stop_isoc(wma_handle); #else +#ifdef HIF_USB + /* Suspend the target and enable interrupt */ + if (wma_suspend_target(wma_handle, 0)) + WMA_LOGE("Failed to suspend target"); +#else /* Suspend the target and disable interrupt */ if (wma_suspend_target(wma_handle, 1)) WMA_LOGE("Failed to suspend target"); #endif +#endif vos_status = wma_tx_detach(wma_handle); if(vos_status != VOS_STATUS_SUCCESS) { |
