diff --git a/net/wireless/core.c b/net/wireless/core.c
index e630648fef79e27064293c02688833a7a6df86a7..35d83bedfe5b16792466f436ae112640437b994c 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -601,8 +601,8 @@ void wiphy_unregister(struct wiphy *wiphy)
 
 	mutex_unlock(&cfg80211_mutex);
 
+	flush_work(&rdev->scan_done_wk);
 	cancel_work_sync(&rdev->conn_work);
-	cancel_work_sync(&rdev->scan_done_wk);
 	kfree(rdev->scan_req);
 	flush_work(&rdev->event_work);
 }
@@ -728,6 +728,13 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
 #endif
 		break;
 	case NETDEV_UNREGISTER:
+		cfg80211_lock_rdev(rdev);
+
+		if (WARN_ON(rdev->scan_req && rdev->scan_req->dev == dev)) {
+			rdev->scan_req->aborted = true;
+			___cfg80211_scan_done(rdev);
+		}
+
 		mutex_lock(&rdev->devlist_mtx);
 		/*
 		 * It is possible to get NETDEV_UNREGISTER
@@ -746,6 +753,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
 #endif
 		}
 		mutex_unlock(&rdev->devlist_mtx);
+		cfg80211_unlock_rdev(rdev);
 		break;
 	case NETDEV_PRE_UP:
 		if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
diff --git a/net/wireless/core.h b/net/wireless/core.h
index f7be3a9b427e712dd86d0cbec5873c676462a09f..c603f528632641acafdf8a8a3fe85e2f4928c038 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -368,6 +368,7 @@ void cfg80211_sme_scan_done(struct net_device *dev);
 void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
 void cfg80211_sme_disassoc(struct net_device *dev, int idx);
 void __cfg80211_scan_done(struct work_struct *wk);
+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev);
 void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
 
 struct ieee80211_channel *
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index e6c1f11595da05ec2e87976475e693bbd89d4022..fe575a24c95c1196d7b8a1fab66d16471193505e 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -18,19 +18,14 @@
 
 #define IEEE80211_SCAN_RESULT_EXPIRE	(15 * HZ)
 
-void __cfg80211_scan_done(struct work_struct *wk)
+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev)
 {
-	struct cfg80211_registered_device *rdev;
 	struct cfg80211_scan_request *request;
 	struct net_device *dev;
 #ifdef CONFIG_WIRELESS_EXT
 	union iwreq_data wrqu;
 #endif
 
-	rdev = container_of(wk, struct cfg80211_registered_device,
-			    scan_done_wk);
-
-	mutex_lock(&rdev->mtx);
 	request = rdev->scan_req;
 
 	dev = request->dev;
@@ -43,9 +38,9 @@ void __cfg80211_scan_done(struct work_struct *wk)
 	cfg80211_sme_scan_done(dev);
 
 	if (request->aborted)
-		nl80211_send_scan_aborted(wiphy_to_dev(request->wiphy), dev);
+		nl80211_send_scan_aborted(rdev, dev);
 	else
-		nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev);
+		nl80211_send_scan_done(rdev, dev);
 
 #ifdef CONFIG_WIRELESS_EXT
 	if (!request->aborted) {
@@ -57,11 +52,22 @@ void __cfg80211_scan_done(struct work_struct *wk)
 
 	dev_put(dev);
 
-	cfg80211_unlock_rdev(rdev);
-	wiphy_to_dev(request->wiphy)->scan_req = NULL;
+	rdev->scan_req = NULL;
 	kfree(request);
 }
 
+void __cfg80211_scan_done(struct work_struct *wk)
+{
+	struct cfg80211_registered_device *rdev;
+
+	rdev = container_of(wk, struct cfg80211_registered_device,
+			    scan_done_wk);
+
+	cfg80211_lock_rdev(rdev);
+	___cfg80211_scan_done(rdev);
+	cfg80211_unlock_rdev(rdev);
+}
+
 void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
 {
 	WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);