From cfb2d73205ede92ba408ee6aca800cbf21374c0e Mon Sep 17 00:00:00 2001
From: Dmitry Shmidt <dimitrysh@google.com>
Date: Tue, 26 Jul 2011 15:00:34 -0700
Subject: [PATCH 510/696] net: wireless: bcmdhd: Fix rfkill cleaning on failure

Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
---
 drivers/net/wireless/bcmdhd/wl_cfg80211.c |   46 +++++++++++++++++++----------
 1 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index d4ccff6..2a4bf36 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -468,7 +468,7 @@ static void wl_debugfs_remove_netdev(struct wl_priv *wl);
 /*
  * rfkill support
  */
-static int wl_setup_rfkill(struct wl_priv *wl);
+static int wl_setup_rfkill(struct wl_priv *wl, bool setup);
 static int wl_rfkill_set(void *data, bool blocked);
 
 /*
@@ -5382,7 +5382,7 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
 		goto cfg80211_attach_out;
 	}
 
-	err = wl_setup_rfkill(wl);
+	err = wl_setup_rfkill(wl, TRUE);
 	if (unlikely(err)) {
 		WL_ERR(("Failed to setup rfkill %d\n", err));
 		goto cfg80211_attach_out;
@@ -5398,7 +5398,7 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
 	return err;
 
 cfg80211_attach_out:
-	err = wl_setup_rfkill(wl);
+	err = wl_setup_rfkill(wl, FALSE);
 	wl_free_wdev(wl);
 	return err;
 }
@@ -5415,8 +5415,7 @@ void wl_cfg80211_detach(void)
 	if (wl_sysctl_hdr)
 		unregister_sysctl_table(wl_sysctl_hdr);
 #endif
-	rfkill_unregister(wl->rfkill);
-	rfkill_destroy(wl->rfkill);
+	wl_setup_rfkill(wl, FALSE);
 	if (wl->p2p_supported)
 		wl_cfgp2p_deinit_priv(wl);
 	wl_deinit_priv(wl);
@@ -6544,29 +6543,44 @@ static int wl_rfkill_set(void *data, bool blocked)
 	WL_DBG(("Enter \n"));
 	WL_DBG(("RF %s\n", blocked ? "blocked" : "unblocked"));
 
+	if (!wl)
+		return -EINVAL;
+
 	wl->rf_blocked = blocked;
 
 	return 0;
 }
 
-static int wl_setup_rfkill(struct wl_priv *wl)
+static int wl_setup_rfkill(struct wl_priv *wl, bool setup)
 {
-	s32 err;
+	s32 err = 0;
 
 	WL_DBG(("Enter \n"));
-	wl->rfkill = rfkill_alloc("brcmfmac-wifi",
-		&wl_cfg80211_get_sdio_func()->dev,
-		RFKILL_TYPE_WLAN, &wl_rfkill_ops, (void *)wl);
+	if (!wl)
+		return -EINVAL;
+	if (setup) {
+		wl->rfkill = rfkill_alloc("brcmfmac-wifi",
+			&wl_cfg80211_get_sdio_func()->dev,
+			RFKILL_TYPE_WLAN, &wl_rfkill_ops, (void *)wl);
+
+		if (!wl->rfkill) {
+			err = -ENOMEM;
+			goto err_out;
+		}
 
-	if (!wl->rfkill) {
-		err =  -ENOMEM;
-		goto err_out;
-	}
+		err = rfkill_register(wl->rfkill);
 
-	err = rfkill_register(wl->rfkill);
+		if (err)
+			rfkill_destroy(wl->rfkill);
+	} else {
+		if (!wl->rfkill) {
+			err = -ENOMEM;
+			goto err_out;
+		}
 
-	if (err)
+		rfkill_unregister(wl->rfkill);
 		rfkill_destroy(wl->rfkill);
+	}
 
 err_out:
 	return err;
-- 
1.7.1

