|
@@ -1557,8 +1557,15 @@ err_format:
|
|
|
return -EPROTO;
|
|
|
}
|
|
|
|
|
|
-static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
|
|
|
+static int b43legacy_one_core_attach(struct ssb_device *dev,
|
|
|
+ struct b43legacy_wl *wl);
|
|
|
+static void b43legacy_one_core_detach(struct ssb_device *dev);
|
|
|
+
|
|
|
+static void b43legacy_request_firmware(struct work_struct *work)
|
|
|
{
|
|
|
+ struct b43legacy_wl *wl = container_of(work,
|
|
|
+ struct b43legacy_wl, firmware_load);
|
|
|
+ struct b43legacy_wldev *dev = wl->current_dev;
|
|
|
struct b43legacy_firmware *fw = &dev->fw;
|
|
|
const u8 rev = dev->dev->id.revision;
|
|
|
const char *filename;
|
|
@@ -1624,8 +1631,14 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
|
|
|
if (err)
|
|
|
goto err_load;
|
|
|
}
|
|
|
+ err = ieee80211_register_hw(wl->hw);
|
|
|
+ if (err)
|
|
|
+ goto err_one_core_detach;
|
|
|
+ return;
|
|
|
|
|
|
- return 0;
|
|
|
+err_one_core_detach:
|
|
|
+ b43legacy_one_core_detach(dev->dev);
|
|
|
+ goto error;
|
|
|
|
|
|
err_load:
|
|
|
b43legacy_print_fw_helptext(dev->wl);
|
|
@@ -1639,7 +1652,7 @@ err_no_initvals:
|
|
|
|
|
|
error:
|
|
|
b43legacy_release_firmware(dev);
|
|
|
- return err;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
|
|
@@ -2153,9 +2166,6 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
|
|
|
macctl |= B43legacy_MACCTL_INFRA;
|
|
|
b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
|
|
|
|
|
|
- err = b43legacy_request_firmware(dev);
|
|
|
- if (err)
|
|
|
- goto out;
|
|
|
err = b43legacy_upload_microcode(dev);
|
|
|
if (err)
|
|
|
goto out; /* firmware is released later */
|
|
@@ -3860,17 +3870,13 @@ static int b43legacy_probe(struct ssb_device *dev,
|
|
|
if (err)
|
|
|
goto err_wireless_exit;
|
|
|
|
|
|
- if (first) {
|
|
|
- err = ieee80211_register_hw(wl->hw);
|
|
|
- if (err)
|
|
|
- goto err_one_core_detach;
|
|
|
- }
|
|
|
+ /* setup and start work to load firmware */
|
|
|
+ INIT_WORK(&wl->firmware_load, b43legacy_request_firmware);
|
|
|
+ schedule_work(&wl->firmware_load);
|
|
|
|
|
|
out:
|
|
|
return err;
|
|
|
|
|
|
-err_one_core_detach:
|
|
|
- b43legacy_one_core_detach(dev);
|
|
|
err_wireless_exit:
|
|
|
if (first)
|
|
|
b43legacy_wireless_exit(dev, wl);
|
|
@@ -3885,6 +3891,7 @@ static void b43legacy_remove(struct ssb_device *dev)
|
|
|
/* We must cancel any work here before unregistering from ieee80211,
|
|
|
* as the ieee80211 unreg will destroy the workqueue. */
|
|
|
cancel_work_sync(&wldev->restart_work);
|
|
|
+ cancel_work_sync(&wl->firmware_load);
|
|
|
|
|
|
B43legacy_WARN_ON(!wl);
|
|
|
if (wl->current_dev == wldev)
|