aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2011-01-21 07:36:44 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-01-22 09:32:22 -0500
commit4032ec639af9b735fdd903fab09de567bd73eaa0 (patch)
treee6f4360b7969706aa3ae5d7e2057b3cb6138376f /drivers
parentd062d44a8386c82c06e483f0c0d1124ba3cab2c8 (diff)
staging: brcm80211: fix suspend/resume issue in brcmsmac
PCI PM suspend callback took down the interface and resume brought it back up. In the mac80211 context this is done in subsequent calls. Rework implementation so that suspend only stores config, and sets PCI power state. The resume return to full power state (D0), restores the config, and brings hardware back up. Full bringup is done by subsequent mac80211 calls. Reviewed-by: Brett Rudley <brudley@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/brcm80211/sys/wl_mac80211.c45
1 files changed, 23 insertions, 22 deletions
diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c
index bdd629d72a75..f1235884cc5d 100644
--- a/drivers/staging/brcm80211/sys/wl_mac80211.c
+++ b/drivers/staging/brcm80211/sys/wl_mac80211.c
@@ -209,11 +209,8 @@ static void wl_ops_stop(struct ieee80211_hw *hw)
209 struct wl_info *wl = hw->priv; 209 struct wl_info *wl = hw->priv;
210 ASSERT(wl); 210 ASSERT(wl);
211 WL_LOCK(wl); 211 WL_LOCK(wl);
212 wl_down(wl);
213 ieee80211_stop_queues(hw); 212 ieee80211_stop_queues(hw);
214 WL_UNLOCK(wl); 213 WL_UNLOCK(wl);
215
216 return;
217} 214}
218 215
219static int 216static int
@@ -246,7 +243,14 @@ wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
246static void 243static void
247wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 244wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
248{ 245{
249 return; 246 struct wl_info *wl;
247
248 wl = HW_TO_WL(hw);
249
250 /* put driver in down state */
251 WL_LOCK(wl);
252 wl_down(wl);
253 WL_UNLOCK(wl);
250} 254}
251 255
252static int 256static int
@@ -779,7 +783,7 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs,
779 wl_found++; 783 wl_found++;
780 return wl; 784 return wl;
781 785
782 fail: 786fail:
783 wl_free(wl); 787 wl_free(wl);
784fail1: 788fail1:
785 return NULL; 789 return NULL;
@@ -1090,7 +1094,6 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1090 return 0; 1094 return 0;
1091} 1095}
1092 1096
1093#ifdef LINUXSTA_PS
1094static int wl_suspend(struct pci_dev *pdev, pm_message_t state) 1097static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
1095{ 1098{
1096 struct wl_info *wl; 1099 struct wl_info *wl;
@@ -1105,11 +1108,12 @@ static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
1105 return -ENODEV; 1108 return -ENODEV;
1106 } 1109 }
1107 1110
1111 /* only need to flag hw is down for proper resume */
1108 WL_LOCK(wl); 1112 WL_LOCK(wl);
1109 wl_down(wl);
1110 wl->pub->hw_up = false; 1113 wl->pub->hw_up = false;
1111 WL_UNLOCK(wl); 1114 WL_UNLOCK(wl);
1112 pci_save_state(pdev, wl->pci_psstate); 1115
1116 pci_save_state(pdev);
1113 pci_disable_device(pdev); 1117 pci_disable_device(pdev);
1114 return pci_set_power_state(pdev, PCI_D3hot); 1118 return pci_set_power_state(pdev, PCI_D3hot);
1115} 1119}
@@ -1133,7 +1137,7 @@ static int wl_resume(struct pci_dev *pdev)
1133 if (err) 1137 if (err)
1134 return err; 1138 return err;
1135 1139
1136 pci_restore_state(pdev, wl->pci_psstate); 1140 pci_restore_state(pdev);
1137 1141
1138 err = pci_enable_device(pdev); 1142 err = pci_enable_device(pdev);
1139 if (err) 1143 if (err)
@@ -1145,13 +1149,12 @@ static int wl_resume(struct pci_dev *pdev)
1145 if ((val & 0x0000ff00) != 0) 1149 if ((val & 0x0000ff00) != 0)
1146 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); 1150 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1147 1151
1148 WL_LOCK(wl); 1152 /*
1149 err = wl_up(wl); 1153 * done. driver will be put in up state
1150 WL_UNLOCK(wl); 1154 * in wl_ops_add_interface() call.
1151 1155 */
1152 return err; 1156 return err;
1153} 1157}
1154#endif /* LINUXSTA_PS */
1155 1158
1156static void wl_remove(struct pci_dev *pdev) 1159static void wl_remove(struct pci_dev *pdev)
1157{ 1160{
@@ -1184,14 +1187,12 @@ static void wl_remove(struct pci_dev *pdev)
1184} 1187}
1185 1188
1186static struct pci_driver wl_pci_driver = { 1189static struct pci_driver wl_pci_driver = {
1187 .name = "brcm80211", 1190 .name = "brcm80211",
1188 .probe = wl_pci_probe, 1191 .probe = wl_pci_probe,
1189#ifdef LINUXSTA_PS 1192 .suspend = wl_suspend,
1190 .suspend = wl_suspend, 1193 .resume = wl_resume,
1191 .resume = wl_resume, 1194 .remove = __devexit_p(wl_remove),
1192#endif /* LINUXSTA_PS */ 1195 .id_table = wl_id_table,
1193 .remove = __devexit_p(wl_remove),
1194 .id_table = wl_id_table,
1195}; 1196};
1196 1197
1197/** 1198/**