]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/wireless/b43/main.c
b43: Split PHY alloc and init
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / b43 / main.c
index fda9492d5884f5fb35ed3a24fdd98d31d5f2a5bb..156e8f3151d544fd1fde7d7ffde0c2721bb532bd 100644 (file)
@@ -1091,8 +1091,12 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
        ssb_read32(dev->dev, SSB_TMSLOW);       /* flush */
        msleep(1);
 
-       /* Turn Analog ON */
-       b43_switch_analog(dev, 1);
+       /* Turn Analog ON, but only if we already know the PHY-type.
+        * This protects against very early setup where we don't know the
+        * PHY-type, yet. wireless_core_reset will be called once again later,
+        * when we know the PHY-type. */
+       if (dev->phy.ops)
+               b43_switch_analog(dev, 1);
 
        macctl = b43_read32(dev, B43_MMIO_MACCTL);
        macctl &= ~B43_MACCTL_GMODE;
@@ -2694,6 +2698,7 @@ static void b43_mgmtframe_txantenna(struct b43_wldev *dev, int antenna)
 /* This is the opposite of b43_chip_init() */
 static void b43_chip_exit(struct b43_wldev *dev)
 {
+       b43_phy_exit(dev);
        b43_gpio_cleanup(dev);
        /* firmware is released later */
 }
@@ -3952,7 +3957,6 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
                dev_kfree_skb_any(dev->wl->current_beacon);
                dev->wl->current_beacon = NULL;
        }
-       b43_phy_exit(dev);
 
        ssb_device_disable(dev->dev, 0);
        ssb_bus_may_powerdown(dev->dev->bus);
@@ -3979,24 +3983,23 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
                b43_wireless_core_reset(dev, tmp);
        }
 
+       /* Reset all data structures. */
        setup_struct_wldev_for_init(dev);
-       err = b43_phy_operations_setup(dev);
-       if (err)
-               goto err_busdown;
+       phy->ops->prepare_structs(dev);
 
        /* Enable IRQ routing to this device. */
        ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev);
 
        b43_imcfglo_timeouts_workaround(dev);
        b43_bluetooth_coext_disable(dev);
-       if (phy->ops->prepare) {
-               err = phy->ops->prepare(dev);
+       if (phy->ops->prepare_hardware) {
+               err = phy->ops->prepare_hardware(dev);
                if (err)
-                       goto err_phy_exit;
+                       goto err_busdown;
        }
        err = b43_chip_init(dev);
        if (err)
-               goto err_phy_exit;
+               goto err_busdown;
        b43_shm_write16(dev, B43_SHM_SHARED,
                        B43_SHM_SH_WLCOREREV, dev->dev->id.revision);
        hf = b43_hf_read(dev);
@@ -4064,8 +4067,6 @@ out:
 
 err_chip_exit:
        b43_chip_exit(dev);
-err_phy_exit:
-       b43_phy_exit(dev);
 err_busdown:
        ssb_bus_may_powerdown(bus);
        B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT);
@@ -4342,6 +4343,7 @@ static void b43_wireless_core_detach(struct b43_wldev *dev)
        /* We release firmware that late to not be required to re-request
         * is all the time when we reinit the core. */
        b43_release_firmware(dev);
+       b43_phy_free(dev);
 }
 
 static int b43_wireless_core_attach(struct b43_wldev *dev)
@@ -4415,16 +4417,20 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
                }
        }
 
+       err = b43_phy_allocate(dev);
+       if (err)
+               goto err_powerdown;
+
        dev->phy.gmode = have_2ghz_phy;
        tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;
        b43_wireless_core_reset(dev, tmp);
 
        err = b43_validate_chipaccess(dev);
        if (err)
-               goto err_powerdown;
+               goto err_phy_free;
        err = b43_setup_bands(dev, have_2ghz_phy, have_5ghz_phy);
        if (err)
-               goto err_powerdown;
+               goto err_phy_free;
 
        /* Now set some default "current_dev" */
        if (!wl->current_dev)
@@ -4438,6 +4444,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
 out:
        return err;
 
+err_phy_free:
+       b43_phy_free(dev);
 err_powerdown:
        ssb_bus_may_powerdown(bus);
        return err;