diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2009-01-23 11:04:05 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-01-29 16:01:27 -0500 |
commit | 0712612741e1dccf10353c70ebe90ba8cc60d5fb (patch) | |
tree | 2d4925adce9939e561e267e041c6b8a2b4beed87 /drivers/net/wireless/rt2x00/rt2x00dev.c | |
parent | 9752a7bd7f36557f34283f5d75dfa32578437f08 (diff) |
rt2x00: Simplify suspend/resume handling
With mac80211 handling all open interfaces during
suspend and resume we can simplify suspend/resume
within rt2x00lib.
The only thing rt2x00 needs to do is free up memory
during suspend and bring back the minimal required
components during resume.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 93 |
1 files changed, 5 insertions, 88 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index cd4447502d8b..e1b40545a9be 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -881,23 +881,17 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); | |||
881 | #ifdef CONFIG_PM | 881 | #ifdef CONFIG_PM |
882 | int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) | 882 | int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) |
883 | { | 883 | { |
884 | int retval; | ||
885 | |||
886 | NOTICE(rt2x00dev, "Going to sleep.\n"); | 884 | NOTICE(rt2x00dev, "Going to sleep.\n"); |
887 | 885 | ||
888 | /* | 886 | /* |
889 | * Only continue if mac80211 has open interfaces. | 887 | * Prevent mac80211 from accessing driver while suspended. |
890 | */ | 888 | */ |
891 | if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || | 889 | if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
892 | !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) | 890 | return 0; |
893 | goto exit; | ||
894 | |||
895 | set_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags); | ||
896 | 891 | ||
897 | /* | 892 | /* |
898 | * Disable radio. | 893 | * Cleanup as much as possible. |
899 | */ | 894 | */ |
900 | rt2x00lib_stop(rt2x00dev); | ||
901 | rt2x00lib_uninitialize(rt2x00dev); | 895 | rt2x00lib_uninitialize(rt2x00dev); |
902 | 896 | ||
903 | /* | 897 | /* |
@@ -906,7 +900,6 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) | |||
906 | rt2x00leds_suspend(rt2x00dev); | 900 | rt2x00leds_suspend(rt2x00dev); |
907 | rt2x00debug_deregister(rt2x00dev); | 901 | rt2x00debug_deregister(rt2x00dev); |
908 | 902 | ||
909 | exit: | ||
910 | /* | 903 | /* |
911 | * Set device mode to sleep for power management, | 904 | * Set device mode to sleep for power management, |
912 | * on some hardware this call seems to consistently fail. | 905 | * on some hardware this call seems to consistently fail. |
@@ -918,8 +911,7 @@ exit: | |||
918 | * the radio and the other components already disabled the | 911 | * the radio and the other components already disabled the |
919 | * device is as good as disabled. | 912 | * device is as good as disabled. |
920 | */ | 913 | */ |
921 | retval = rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP); | 914 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP)) |
922 | if (retval) | ||
923 | WARNING(rt2x00dev, "Device failed to enter sleep state, " | 915 | WARNING(rt2x00dev, "Device failed to enter sleep state, " |
924 | "continue suspending.\n"); | 916 | "continue suspending.\n"); |
925 | 917 | ||
@@ -927,34 +919,8 @@ exit: | |||
927 | } | 919 | } |
928 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); | 920 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); |
929 | 921 | ||
930 | static void rt2x00lib_resume_intf(void *data, u8 *mac, | ||
931 | struct ieee80211_vif *vif) | ||
932 | { | ||
933 | struct rt2x00_dev *rt2x00dev = data; | ||
934 | struct rt2x00_intf *intf = vif_to_intf(vif); | ||
935 | |||
936 | spin_lock(&intf->lock); | ||
937 | |||
938 | rt2x00lib_config_intf(rt2x00dev, intf, | ||
939 | vif->type, intf->mac, intf->bssid); | ||
940 | |||
941 | |||
942 | /* | ||
943 | * AP, Ad-hoc, and Mesh Point mode require a new beacon update. | ||
944 | */ | ||
945 | if (vif->type == NL80211_IFTYPE_AP || | ||
946 | vif->type == NL80211_IFTYPE_ADHOC || | ||
947 | vif->type == NL80211_IFTYPE_MESH_POINT || | ||
948 | vif->type == NL80211_IFTYPE_WDS) | ||
949 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; | ||
950 | |||
951 | spin_unlock(&intf->lock); | ||
952 | } | ||
953 | |||
954 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | 922 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) |
955 | { | 923 | { |
956 | int retval; | ||
957 | |||
958 | NOTICE(rt2x00dev, "Waking up.\n"); | 924 | NOTICE(rt2x00dev, "Waking up.\n"); |
959 | 925 | ||
960 | /* | 926 | /* |
@@ -964,60 +930,11 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
964 | rt2x00leds_resume(rt2x00dev); | 930 | rt2x00leds_resume(rt2x00dev); |
965 | 931 | ||
966 | /* | 932 | /* |
967 | * Only continue if mac80211 had open interfaces. | ||
968 | */ | ||
969 | if (!test_and_clear_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags)) | ||
970 | return 0; | ||
971 | |||
972 | /* | ||
973 | * Reinitialize device and all active interfaces. | ||
974 | */ | ||
975 | retval = rt2x00lib_start(rt2x00dev); | ||
976 | if (retval) | ||
977 | goto exit; | ||
978 | |||
979 | /* | ||
980 | * Reconfigure device. | ||
981 | */ | ||
982 | retval = rt2x00mac_config(rt2x00dev->hw, ~0); | ||
983 | if (retval) | ||
984 | goto exit; | ||
985 | |||
986 | /* | ||
987 | * Iterator over each active interface to | ||
988 | * reconfigure the hardware. | ||
989 | */ | ||
990 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | ||
991 | rt2x00lib_resume_intf, rt2x00dev); | ||
992 | |||
993 | /* | ||
994 | * We are ready again to receive requests from mac80211. | 933 | * We are ready again to receive requests from mac80211. |
995 | */ | 934 | */ |
996 | set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); | 935 | set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); |
997 | 936 | ||
998 | /* | ||
999 | * It is possible that during that mac80211 has attempted | ||
1000 | * to send frames while we were suspending or resuming. | ||
1001 | * In that case we have disabled the TX queue and should | ||
1002 | * now enable it again | ||
1003 | */ | ||
1004 | ieee80211_wake_queues(rt2x00dev->hw); | ||
1005 | |||
1006 | /* | ||
1007 | * During interface iteration we might have changed the | ||
1008 | * delayed_flags, time to handles the event by calling | ||
1009 | * the work handler directly. | ||
1010 | */ | ||
1011 | rt2x00lib_intf_scheduled(&rt2x00dev->intf_work); | ||
1012 | |||
1013 | return 0; | 937 | return 0; |
1014 | |||
1015 | exit: | ||
1016 | rt2x00lib_stop(rt2x00dev); | ||
1017 | rt2x00lib_uninitialize(rt2x00dev); | ||
1018 | rt2x00debug_deregister(rt2x00dev); | ||
1019 | |||
1020 | return retval; | ||
1021 | } | 938 | } |
1022 | EXPORT_SYMBOL_GPL(rt2x00lib_resume); | 939 | EXPORT_SYMBOL_GPL(rt2x00lib_resume); |
1023 | #endif /* CONFIG_PM */ | 940 | #endif /* CONFIG_PM */ |