@ -744,32 +744,6 @@ out:
return ret ;
}
static void wl1271_fetch_nvs ( struct wl1271 * wl )
{
const struct firmware * fw ;
int ret ;
ret = request_firmware ( & fw , WL12XX_NVS_NAME , wl - > dev ) ;
if ( ret < 0 ) {
wl1271_debug ( DEBUG_BOOT , " could not get nvs file %s: %d " ,
WL12XX_NVS_NAME , ret ) ;
return ;
}
wl - > nvs = kmemdup ( fw - > data , fw - > size , GFP_KERNEL ) ;
if ( ! wl - > nvs ) {
wl1271_error ( " could not allocate memory for the nvs file " ) ;
goto out ;
}
wl - > nvs_len = fw - > size ;
out :
release_firmware ( fw ) ;
}
void wl12xx_queue_recovery_work ( struct wl1271 * wl )
{
WARN_ON ( ! test_bit ( WL1271_FLAG_INTENDED_FW_RECOVERY , & wl - > flags ) ) ;
@ -5153,8 +5127,7 @@ static int wl1271_register_hw(struct wl1271 *wl)
if ( wl - > mac80211_registered )
return 0 ;
wl1271_fetch_nvs ( wl ) ;
if ( wl - > nvs ! = NULL ) {
if ( wl - > nvs_len > = 12 ) {
/* NOTE: The wl->nvs->nvs element must be first, in
* order to simplify the casting , we assume it is at
* the beginning of the wl - > nvs structure .
@ -5419,6 +5392,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size)
wl - > fw_type = WL12XX_FW_TYPE_NONE ;
mutex_init ( & wl - > mutex ) ;
mutex_init ( & wl - > flush_mutex ) ;
init_completion ( & wl - > nvs_loading_complete ) ;
order = get_order ( aggr_buf_size ) ;
wl - > aggr_buf = ( u8 * ) __get_free_pages ( GFP_KERNEL , order ) ;
@ -5539,24 +5513,31 @@ static irqreturn_t wl12xx_hardirq(int irq, void *cookie)
return IRQ_WAKE_THREAD ;
}
int __devinit wlcore_probe ( struct wl1271 * wl , struct platform_device * pdev )
static void wlcore_nvs_cb ( const struct firmware * fw , void * context )
{
struct wl1271 * wl = context ;
struct platform_device * pdev = wl - > pdev ;
struct wl12xx_platform_data * pdata = pdev - > dev . platform_data ;
unsigned long irqflags ;
int ret ;
if ( ! wl - > ops | | ! wl - > ptable ) {
ret = - EINVAL ;
goto out ;
if ( fw ) {
wl - > nvs = kmemdup ( fw - > data , fw - > size , GFP_KERNEL ) ;
if ( ! wl - > nvs ) {
wl1271_error ( " Could not allocate nvs data " ) ;
goto out ;
}
wl - > nvs_len = fw - > size ;
} else {
wl1271_debug ( DEBUG_BOOT , " Could not get nvs file %s " ,
WL12XX_NVS_NAME ) ;
wl - > nvs = NULL ;
wl - > nvs_len = 0 ;
}
wl - > dev = & pdev - > dev ;
wl - > pdev = pdev ;
platform_set_drvdata ( pdev , wl ) ;
ret = wl - > ops - > setup ( wl ) ;
if ( ret < 0 )
goto out ;
goto out_free_nvs ;
BUG_ON ( wl - > num_tx_desc > WLCORE_MAX_TX_DESCRIPTORS ) ;
@ -5578,7 +5559,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
pdev - > name , wl ) ;
if ( ret < 0 ) {
wl1271_error ( " request_irq() failed: %d " , ret ) ;
goto out ;
goto out_free_nvs ;
}
# ifdef CONFIG_PM
@ -5637,6 +5618,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
goto out_hw_pg_ver ;
}
wl - > initialized = true ;
goto out ;
out_hw_pg_ver :
@ -5651,7 +5633,33 @@ out_unreg:
out_irq :
free_irq ( wl - > irq , wl ) ;
out_free_nvs :
kfree ( wl - > nvs ) ;
out :
release_firmware ( fw ) ;
complete_all ( & wl - > nvs_loading_complete ) ;
}
int __devinit wlcore_probe ( struct wl1271 * wl , struct platform_device * pdev )
{
int ret ;
if ( ! wl - > ops | | ! wl - > ptable )
return - EINVAL ;
wl - > dev = & pdev - > dev ;
wl - > pdev = pdev ;
platform_set_drvdata ( pdev , wl ) ;
ret = request_firmware_nowait ( THIS_MODULE , FW_ACTION_HOTPLUG ,
WL12XX_NVS_NAME , & pdev - > dev , GFP_KERNEL ,
wl , wlcore_nvs_cb ) ;
if ( ret < 0 ) {
wl1271_error ( " request_firmware_nowait failed: %d " , ret ) ;
complete_all ( & wl - > nvs_loading_complete ) ;
}
return ret ;
}
EXPORT_SYMBOL_GPL ( wlcore_probe ) ;
@ -5660,6 +5668,10 @@ int __devexit wlcore_remove(struct platform_device *pdev)
{
struct wl1271 * wl = platform_get_drvdata ( pdev ) ;
wait_for_completion ( & wl - > nvs_loading_complete ) ;
if ( ! wl - > initialized )
return 0 ;
if ( wl - > irq_wake_enabled ) {
device_init_wakeup ( wl - > dev , 0 ) ;
disable_irq_wake ( wl - > irq ) ;