The sequence of operations that needs to be done in wiphy_suspend is identical for the case where there is no wowlan configured, and for the case that it is but the driver refused to do wowlan (by returning 1 from rdev_suspend). The current code duplicates this set of operations for each one of the cases. In particular, next patch will change the locking of cfg80211_leave_all to not hold the wiphy lock, which will be easier to do if it is not called twice. Change the code to handle first the case that wowlan is configured, and then handle both cases (driver refused to do wowlan and no wowlan configured) in one place. Note that this changes the behaviour to set suspended=true also when we were not registered yet, but that makes sense anyway, as wiphy works can be queued also before registration. Signed-off-by: Miri Korenblit --- net/wireless/sysfs.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index 8d142856e385..77762938edb8 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c @@ -99,26 +99,31 @@ static int wiphy_suspend(struct device *dev) rdev->suspend_at = ktime_get_boottime_seconds(); rtnl_lock(); + if (!rdev->wiphy.registered) + goto out_unlock_rtnl; + wiphy_lock(&rdev->wiphy); - if (rdev->wiphy.registered) { - if (!rdev->wiphy.wowlan_config) { - cfg80211_leave_all(rdev); - cfg80211_process_rdev_events(rdev); - } + if (rdev->wiphy.wowlan_config) { cfg80211_process_wiphy_works(rdev, NULL); if (rdev->ops->suspend) ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config); - if (ret == 1) { - /* Driver refuse to configure wowlan */ - cfg80211_leave_all(rdev); - cfg80211_process_rdev_events(rdev); - cfg80211_process_wiphy_works(rdev, NULL); - ret = rdev_suspend(rdev, NULL); - } - if (ret == 0) - rdev->suspended = true; + if (ret <= 0) + goto out_unlock_wiphy; } + + /* Driver refused to configure wowlan (ret = 1) or no wowlan */ + + cfg80211_leave_all(rdev); + cfg80211_process_rdev_events(rdev); + cfg80211_process_wiphy_works(rdev, NULL); + if (rdev->ops->suspend) + ret = rdev_suspend(rdev, NULL); + +out_unlock_wiphy: wiphy_unlock(&rdev->wiphy); +out_unlock_rtnl: + if (ret == 0) + rdev->suspended = true; rtnl_unlock(); return ret; -- 2.34.1