void wifi_ctrlfunc_unregister_drv(void) { struct device *dev1, *dev2; dev1 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME, wifi_platdev_match); dev2 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME2, wifi_platdev_match); if (!dts_enabled) if (dev1 == NULL && dev2 == NULL) return; DHD_ERROR(("unregister wifi platform drivers\n")); if (dev1) platform_driver_unregister(&wifi_platform_dev_driver); if (dev2) platform_driver_unregister(&wifi_platform_dev_driver_legacy); if (dts_enabled) { wifi_adapter_info_t *adapter; adapter = &dhd_wifi_platdata->adapters[0]; if (is_power_on) { wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); wifi_platform_bus_enumerate(adapter, FALSE); } } kfree(dhd_wifi_platdata->adapters); dhd_wifi_platdata->adapters = NULL; dhd_wifi_platdata->num_adapters = 0; kfree(dhd_wifi_platdata); dhd_wifi_platdata = NULL; }
static int bcmdhd_wifi_plat_dev_drv_remove(struct platform_device *pdev) { int i; wifi_adapter_info_t *adapter; ASSERT(dhd_wifi_platdata != NULL); /* power down all adapters */ for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) { adapter = &dhd_wifi_platdata->adapters[i]; wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); wifi_platform_bus_enumerate(adapter, FALSE); } return 0; }
static int wifi_plat_dev_drv_remove(struct platform_device *pdev) { wifi_adapter_info_t *adapter; /* Android style wifi platform data device ("bcmdhd_wlan" or "bcm4329_wlan") * is kept for backward compatibility and supports only 1 adapter */ ASSERT(dhd_wifi_platdata != NULL); ASSERT(dhd_wifi_platdata->num_adapters == 1); adapter = &dhd_wifi_platdata->adapters[0]; if (is_power_on) { #ifdef BCMPCIE wifi_platform_bus_enumerate(adapter, FALSE); OSL_SLEEP(100); wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); #else wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); wifi_platform_bus_enumerate(adapter, FALSE); #endif /* BCMPCIE */ } return 0; }
static int dhd_wifi_platform_load() { int err = 0; /* As chipset is power down after the register_netdev(), * there is a race condition where an app can trigger a dhd_open() * before the end power down done sequence. * Use a semaphore to handle this race condtion */ dhd_wifi_platform_load_lock(); wl_android_init(); if ((err = dhd_wifi_platform_load_usb())) goto end; else if ((err = dhd_wifi_platform_load_sdio())) goto end; else err = dhd_wifi_platform_load_pcie(); end: if (err) wl_android_exit(); else wl_android_post_init(); if (!dhd_download_fw_on_driverload) { wifi_adapter_info_t *adapter; adapter = &dhd_wifi_platdata->adapters[0]; if (is_power_on) { wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); wifi_platform_bus_enumerate(adapter, FALSE); } } dhd_wifi_platform_load_unlock(); return err; }
void wifi_ctrlfunc_unregister_drv(void) { #if defined(CONFIG_DTS) && !defined(CUSTOMER_HW) DHD_ERROR(("unregister wifi platform drivers\n")); platform_driver_unregister(&wifi_platform_dev_driver); #else #ifndef CUSTOMER_HW struct device *dev1, *dev2; dev1 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME, wifi_platdev_match); dev2 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME2, wifi_platdev_match); if (!dts_enabled) if (dev1 == NULL && dev2 == NULL) return; #endif DHD_ERROR(("unregister wifi platform drivers\n")); #ifndef CUSTOMER_HW if (dev1) platform_driver_unregister(&wifi_platform_dev_driver); if (dev2) platform_driver_unregister(&wifi_platform_dev_driver_legacy); #endif if (dts_enabled) { wifi_adapter_info_t *adapter; adapter = &dhd_wifi_platdata->adapters[0]; if (is_power_on) { wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); } wifi_platform_bus_enumerate(adapter, FALSE); } #endif /* !defined(CONFIG_DTS) */ kfree(dhd_wifi_platdata->adapters); dhd_wifi_platdata->adapters = NULL; dhd_wifi_platdata->num_adapters = 0; kfree(dhd_wifi_platdata); dhd_wifi_platdata = NULL; }
static int dhd_wifi_platform_load_sdio(void) { int i; int err = 0; wifi_adapter_info_t *adapter; BCM_REFERENCE(i); BCM_REFERENCE(adapter); /* Sanity check on the module parameters * - Both watchdog and DPC as tasklets are ok * - If both watchdog and DPC are threads, TX must be deferred */ if (!(dhd_watchdog_prio < 0 && dhd_dpc_prio < 0) && !(dhd_watchdog_prio >= 0 && dhd_dpc_prio >= 0 && dhd_deferred_tx)) return -EINVAL; #if defined(BCMLXSDMMC) if (dhd_wifi_platdata == NULL) { DHD_ERROR(("DHD wifi platform data is required for Android build\n")); return -EINVAL; } sema_init(&dhd_registration_sem, 0); /* power up all adapters */ for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) { bool chip_up = FALSE; int retry = POWERUP_MAX_RETRY; struct semaphore dhd_chipup_sem; adapter = &dhd_wifi_platdata->adapters[i]; DHD_ERROR(("Power-up adapter '%s'\n", adapter->name)); DHD_INFO((" - irq %d [flags %d], firmware: %s, nvram: %s\n", adapter->irq_num, adapter->intr_flags, adapter->fw_path, adapter->nv_path)); DHD_INFO((" - bus type %d, bus num %d, slot num %d\n\n", adapter->bus_type, adapter->bus_num, adapter->slot_num)); do { sema_init(&dhd_chipup_sem, 0); err = dhd_bus_reg_sdio_notify(&dhd_chipup_sem); if (err) { DHD_ERROR(("%s dhd_bus_reg_sdio_notify fail(%d)\n\n", __FUNCTION__, err)); return err; } err = wifi_platform_set_power(adapter, TRUE, WIFI_TURNON_DELAY); if (err) { /* WL_REG_ON state unknown, Power off forcely */ wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); continue; } else { wifi_platform_bus_enumerate(adapter, TRUE); err = 0; } if (down_timeout(&dhd_chipup_sem, msecs_to_jiffies(POWERUP_WAIT_MS)) == 0) { dhd_bus_unreg_sdio_notify(); chip_up = TRUE; break; } DHD_ERROR(("failed to power up %s, %d retry left\n", adapter->name, retry)); dhd_bus_unreg_sdio_notify(); wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); wifi_platform_bus_enumerate(adapter, FALSE); } while (retry--); if (!chip_up) { DHD_ERROR(("failed to power up %s, max retry reached**\n", adapter->name)); return -ENODEV; } } err = dhd_bus_register(); if (err) { DHD_ERROR(("%s: sdio_register_driver failed\n", __FUNCTION__)); goto fail; } /* * Wait till MMC sdio_register_driver callback called and made driver attach. * It's needed to make sync up exit from dhd insmod and * Kernel MMC sdio device callback registration */ err = down_timeout(&dhd_registration_sem, msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT)); if (err) { DHD_ERROR(("%s: sdio_register_driver timeout or error \n", __FUNCTION__)); dhd_bus_unregister(); goto fail; } return err; fail: /* power down all adapters */ for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) { adapter = &dhd_wifi_platdata->adapters[i]; wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); wifi_platform_bus_enumerate(adapter, FALSE); } #else /* x86 bring-up PC needs no power-up operations */ err = dhd_bus_register(); #endif return err; }
static int dhd_wifi_platform_load_pcie(void) { int err = 0; int i; wifi_adapter_info_t *adapter; BCM_REFERENCE(i); BCM_REFERENCE(adapter); if (dhd_wifi_platdata == NULL) { err = dhd_bus_register(); } else { if (dhd_download_fw_on_driverload) { /* power up all adapters */ for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) { int retry = POWERUP_MAX_RETRY; adapter = &dhd_wifi_platdata->adapters[i]; DHD_ERROR(("Power-up adapter '%s'\n", adapter->name)); DHD_INFO((" - irq %d [flags %d], firmware: %s, nvram: %s\n", adapter->irq_num, adapter->intr_flags, adapter->fw_path, adapter->nv_path)); DHD_INFO((" - bus type %d, bus num %d, slot num %d\n\n", adapter->bus_type, adapter->bus_num, adapter->slot_num)); do { err = wifi_platform_set_power(adapter, TRUE, WIFI_TURNON_DELAY); if (err) { DHD_ERROR(("failed to power up %s," " %d retry left\n", adapter->name, retry)); /* WL_REG_ON state unknown, Power off forcely */ wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); continue; } else { err = wifi_platform_bus_enumerate(adapter, TRUE); if (err) { DHD_ERROR(("failed to enumerate bus %s, " "%d retry left\n", adapter->name, retry)); wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); } else { break; } } } while (retry--); if (!retry) { DHD_ERROR(("failed to power up %s, max retry reached**\n", adapter->name)); return -ENODEV; } } } err = dhd_bus_register(); if (err) { DHD_ERROR(("%s: pcie_register_driver failed\n", __FUNCTION__)); if (dhd_download_fw_on_driverload) { /* power down all adapters */ for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) { adapter = &dhd_wifi_platdata->adapters[i]; wifi_platform_bus_enumerate(adapter, FALSE); wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); } } } } return err; }