b43: Rewrite suspend/resume code
PATCH 1/1 b43: Rewrite suspend/resume code
This removes most of the b43 suspend/resume code (it's handled by mac80211) and moves the registration of devices to the attachment phase. This is required, because we must not register/unregister devices on suspend/resume.
Signed-off-by Michael Buesch <[email protected]>
---
Nobody replied to my RFT request, so I guess it's OK.
John, this patch needs to be applied in front of some other patches that I already sent. See this series file, if you have problems applying the patches: http://bu3sch.de/patches/wireless-testing/20090911-2143/patches/series
drivers/net/wireless/b43/main.c +20 -80
@@ -3006,14 +3006,18 @@ static void b43_security_init(struct b43static int b43_rng_read (struct hwrng *rng,u32 *data) {struct b43_wl *wl = (struct b43_wl *)rng->priv; +struct b43_wldev *dev; +int count = -ENODEV ; -/* FIXME: We need to take wl->mutex here to make sure the device -* is not going away from under our ass. However it could deadlock -* with hwrng internal locking. */ - - *data =b43_read16 (wl->current_dev,B43_MMIO_RNG ); +mutex_lock (&wl->mutex); + dev = wl->current_dev; +if (likely (dev &&b43_status (dev) >=B43_STAT_INITIALIZED )) { + *data =b43_read16 (dev,B43_MMIO_RNG ); + count =sizeof (u16); + } +mutex_unlock (&wl->mutex); -return (sizeof (u16)); +return count; }#endif /* CONFIG_B43_HWRNG */
@@ -3855,6 +3859,7 @@ redo:b43_mac_suspend (dev);free_irq (dev->dev->irq, dev); +b43_leds_exit (dev);b43dbg (wl,"Wireless interface stopped\n" );return dev;
@@ -3886,8 +3891,10 @@ static int b43_wireless_core_start(struc/* Start maintainance work */ b43_periodic_tasks_setup (dev); +b43_leds_init (dev); +b43dbg (dev->wl,"Wireless interface started\n" ); - out: +out:return err; }
@@ -4164,10 +4171,6 @@ static void b43_wireless_core_exit(struc macctl |=B43_MACCTL_PSM_JMP0 ;b43_write32 (dev,B43_MMIO_MACCTL , macctl); -if (!dev->suspend_in_progress) { -b43_leds_exit (dev); -b43_rng_exit (dev->wl); - }b43_dma_free (dev);b43_pio_free (dev);b43_chip_exit (dev);
@@ -4184,7 +4187,6 @@ static void b43_wireless_core_exit(struc/* Initialize a wireless core */ static int b43_wireless_core_init (struct b43_wldev *dev) { -struct b43_wl *wl = dev->wl;struct ssb_bus *bus = dev->dev->bus;struct ssb_sprom *sprom = &bus->sprom;struct b43_phy *phy = &dev->phy;
@@ -4284,13 +4286,9 @@ static int b43_wireless_core_init(structssb_bus_powerup (bus, !(sprom->boardflags_lo &B43_BFL_XTAL_NOSLOW ));b43_upload_card_macaddress (dev);b43_security_init (dev); -if (!dev->suspend_in_progress) -b43_rng_init (wl);b43_set_status (dev,B43_STAT_INITIALIZED ); -if (!dev->suspend_in_progress) -b43_leds_init (dev); out:return err;
@@ -4839,7 +4837,6 @@ static int b43_wireless_init(struct ssb_/* Initialize struct b43_wl */ wl->hw = hw; -spin_lock_init (&wl->leds_lock);mutex_init (&wl->mutex);spin_lock_init (&wl->hardirq_lock);INIT_LIST_HEAD (&wl->devlist);
@@ -4880,6 +4877,8 @@ static int b43_probe(struct ssb_device * err =ieee80211_register_hw (wl->hw);if (err) goto err_one_core_detach; +b43_leds_register (wl->current_dev); +b43_rng_init (wl); } out:
@@ -4908,12 +4907,16 @@ static void b43_remove(struct ssb_device* might have modified it. Restoring is important, so the networking * stack can properly free resources. */ wl->hw->queues = wl->mac80211_initially_registered_queues; + wl->current_dev =NULL ; +cancel_work_sync (&wl->leds.work);ieee80211_unregister_hw (wl->hw); }b43_one_core_detach (dev);if (list_empty (&wl->devlist)) { +b43_rng_exit (wl); +b43_leds_unregister (wldev);/* Last core on the chip unregistered. * We can destroy common struct b43_wl. */
@@ -4931,74 +4934,11 @@ void b43_controller_restart(struct b43_wieee80211_queue_work (dev->wl->hw, &dev->restart_work); } -#ifdef CONFIG_PM - -static int b43_suspend (struct ssb_device *dev,pm_message_t state) -{ -struct b43_wldev *wldev =ssb_get_drvdata (dev); -struct b43_wl *wl = wldev->wl; - -b43dbg (wl,"Suspending...\n" ); - -mutex_lock (&wl->mutex); - wldev->suspend_in_progress = true; - wldev->suspend_init_status =b43_status (wldev); -if (wldev->suspend_init_status >=B43_STAT_STARTED ) - wldev =b43_wireless_core_stop (wldev); -if (wldev && wldev->suspend_init_status >=B43_STAT_INITIALIZED ) -b43_wireless_core_exit (wldev); -mutex_unlock (&wl->mutex); - -b43dbg (wl,"Device suspended.\n" ); - -return 0 ; -} - -static int b43_resume (struct ssb_device *dev) -{ -struct b43_wldev *wldev =ssb_get_drvdata (dev); -struct b43_wl *wl = wldev->wl; -int err =0 ; - -b43dbg (wl,"Resuming...\n" ); - -mutex_lock (&wl->mutex); -if (wldev->suspend_init_status >=B43_STAT_INITIALIZED ) { - err =b43_wireless_core_init (wldev); -if (err) { -b43err (wl,"Resume failed at core init\n" ); - goto out; - } - } -if (wldev->suspend_init_status >=B43_STAT_STARTED ) { - err =b43_wireless_core_start (wldev); -if (err) { -b43_leds_exit (wldev); -b43_rng_exit (wldev->wl); -b43_wireless_core_exit (wldev); -b43err (wl,"Resume failed at core start\n" ); - goto out; - } - } -b43dbg (wl,"Device resumed.\n" ); - out: - wldev->suspend_in_progress = false; -mutex_unlock (&wl->mutex); -return err; -} - -#else /* CONFIG_PM */ -# define b43_suspend NULL -# define b43_resume NULL -#endif /* CONFIG_PM */ -static struct ssb_driver b43_ssb_driver = { .name =KBUILD_MODNAME , .id_table = b43_ssb_tbl, .probe = b43_probe, .remove = b43_remove, - .suspend = b43_suspend, - .resume = b43_resume, };static void b43_print_driverinfo (void )
drivers/net/wireless/b43/b43.h +3 -16
@@ -629,13 +629,6 @@ struct b43_wl {* from the mac80211 subsystem. */ u16 mac80211_initially_registered_queues; -/* R/W lock for data transmission. -* Transmissions on 2+ queues can run concurrently, but somebody else -* might sync with TX by write_lock_irqsave()'ing. */ -rwlock_t tx_lock; -/* Lock for LEDs access. */ -spinlock_t leds_lock; -/* We can only have one operating interface (802.11 core) * at a time. General information about this interface follows. */
@@ -686,6 +679,9 @@ struct b43_wl {struct work_struct tx_work;/* Queue of packets to be transmitted. */ struct sk_buff_head tx_queue; + +/* The device LEDs. */ +struct b43_leds leds; };/* The type of the firmware file. */
@@ -768,13 +764,10 @@ struct b43_wldev {/* The device initialization status. * Use b43_status() to query. */ atomic_t __init_status; -/* Saved init status for handling suspend. */ -int suspend_init_status;bool bad_frames_preempt;/* Use "Bad Frames Preemption" (default off) */ bool dfq_valid;/* Directed frame queue valid (IBSS PS mode, ATIM) */ bool radio_hw_enable;/* saved state of radio hardware enabled state */ -bool suspend_in_progress;/* TRUE, if we are in a suspend/resume cycle */ bool qos_enabled;/* TRUE, if QoS is used. */ bool hwcrypto_enabled;/* TRUE, if HW crypto acceleration is enabled. */
@@ -794,12 +787,6 @@ struct b43_wldev {/* Various statistics about the physical device. */ struct b43_stats stats; -/* The device LEDs. */ -struct b43_led led_tx; -struct b43_led led_rx; -struct b43_led led_assoc; -struct b43_led led_radio; -/* Reason code of the last interrupt. */ u32 irq_reason;u32 dma_reason[6 ];
drivers/net/wireless/b43/leds.c +184 -75
375 lines not on this page · raw message
drivers/net/wireless/b43/leds.h +26 -2
@@ -7,12 +7,13 @@ struct b43_wldev;#include <linux/types.h> #include <linux/leds.h> +#include <linux/workqueue.h> #define B43_LED_MAX_NAME_LEN 31struct b43_led { -struct b43_wldev *dev; +struct b43_wl *wl;/* The LED class device */ struct led_classdev led_dev;/* The index number of the LED. */
@@ -22,8 +23,23 @@ struct b43_led {bool activelow;/* The unique name string for this LED device. */ char name[B43_LED_MAX_NAME_LEN +1 ]; +/* The current status of the LED. This is updated locklessly. */ +atomic_t state; +/* The active state in hardware. */ +bool hw_state; }; +struct b43_leds { +struct b43_led led_tx; +struct b43_led led_rx; +struct b43_led led_radio; +struct b43_led led_assoc; + +struct work_struct work; +}; + +#define B43_MAX_NR_LEDS 4 +#define B43_LED_BEHAVIOUR 0x7F#define B43_LED_ACTIVELOW 0x80/* LED behaviour values */
@@ -42,6 +58,8 @@ enum b43_led_behaviour { B43_LED_INACTIVE, }; +void b43_leds_register (struct b43_wldev *dev); +void b43_leds_unregister (struct b43_wldev *dev);void b43_leds_init (struct b43_wldev *dev);void b43_leds_exit (struct b43_wldev *dev);
@@ -49,10 +67,16 @@ void b43_leds_exit(struct b43_wldev *dev#else /* CONFIG_B43_LEDS */ /* LED support disabled */ -struct b43_led { +struct b43_leds {/* empty */ }; +static inline void b43_leds_register (struct b43_wldev *dev) +{ +} +static inline void b43_leds_unregister (struct b43_wldev *dev) +{ +}static inline void b43_leds_init (struct b43_wldev *dev) { }
Signature · 1 line
Greetings, Michael.