diff options
Diffstat (limited to 'drivers/net')
22 files changed, 195 insertions, 400 deletions
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 837135f0390..5ddd8c4f901 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2481,10 +2481,10 @@ static int add_net_device(struct hso_device *hso_dev)  	return 0;  } -static int hso_radio_toggle(void *data, enum rfkill_state state) +static int hso_rfkill_set_block(void *data, bool blocked)  {  	struct hso_device *hso_dev = data; -	int enabled = (state == RFKILL_STATE_UNBLOCKED); +	int enabled = !blocked;  	int rv;  	mutex_lock(&hso_dev->mutex); @@ -2498,6 +2498,10 @@ static int hso_radio_toggle(void *data, enum rfkill_state state)  	return rv;  } +static const struct rfkill_ops hso_rfkill_ops = { +	.set_block = hso_rfkill_set_block, +}; +  /* Creates and sets up everything for rfkill */  static void hso_create_rfkill(struct hso_device *hso_dev,  			     struct usb_interface *interface) @@ -2506,29 +2510,25 @@ static void hso_create_rfkill(struct hso_device *hso_dev,  	struct device *dev = &hso_net->net->dev;  	char *rfkn; -	hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev, -				 RFKILL_TYPE_WWAN); -	if (!hso_net->rfkill) { -		dev_err(dev, "%s - Out of memory\n", __func__); -		return; -	}  	rfkn = kzalloc(20, GFP_KERNEL); -	if (!rfkn) { -		rfkill_free(hso_net->rfkill); -		hso_net->rfkill = NULL; +	if (!rfkn)  		dev_err(dev, "%s - Out of memory\n", __func__); -		return; -	} +  	snprintf(rfkn, 20, "hso-%d",  		 interface->altsetting->desc.bInterfaceNumber); -	hso_net->rfkill->name = rfkn; -	hso_net->rfkill->state = RFKILL_STATE_UNBLOCKED; -	hso_net->rfkill->data = hso_dev; -	hso_net->rfkill->toggle_radio = hso_radio_toggle; + +	hso_net->rfkill = rfkill_alloc(rfkn, +				       &interface_to_usbdev(interface)->dev, +				       RFKILL_TYPE_WWAN, +				       &hso_rfkill_ops, hso_dev); +	if (!hso_net->rfkill) { +		dev_err(dev, "%s - Out of memory\n", __func__); +		kfree(rfkn); +		return; +	}  	if (rfkill_register(hso_net->rfkill) < 0) { +		rfkill_destroy(hso_net->rfkill);  		kfree(rfkn); -		hso_net->rfkill->name = NULL; -		rfkill_free(hso_net->rfkill);  		hso_net->rfkill = NULL;  		dev_err(dev, "%s - Failed to register rfkill\n", __func__);  		return; @@ -3165,8 +3165,10 @@ static void hso_free_interface(struct usb_interface *interface)  			hso_stop_net_device(network_table[i]);  			cancel_work_sync(&network_table[i]->async_put_intf);  			cancel_work_sync(&network_table[i]->async_get_intf); -			if (rfk) +			if (rfk) {  				rfkill_unregister(rfk); +				rfkill_destroy(rfk); +			}  			hso_free_net_device(network_table[i]);  		}  	} diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 796a3adffea..515880aa211 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -460,12 +460,9 @@ struct ath_led {  	bool registered;  }; -/* Rfkill */ -#define ATH_RFKILL_POLL_INTERVAL	2000 /* msecs */ -  struct ath_rfkill {  	struct rfkill *rfkill; -	struct delayed_work rfkill_poll; +	struct rfkill_ops ops;  	char rfkill_name[32];  }; @@ -509,8 +506,6 @@ struct ath_rfkill {  #define SC_OP_RXFLUSH           BIT(7)  #define SC_OP_LED_ASSOCIATED    BIT(8)  #define SC_OP_RFKILL_REGISTERED BIT(9) -#define SC_OP_RFKILL_SW_BLOCKED BIT(10) -#define SC_OP_RFKILL_HW_BLOCKED BIT(11)  #define SC_OP_WAIT_FOR_BEACON   BIT(12)  #define SC_OP_LED_ON            BIT(13)  #define SC_OP_SCANNING          BIT(14) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 61da08a1648..f7baa406918 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1192,120 +1192,69 @@ static bool ath_is_rfkill_set(struct ath_softc *sc)  				  ah->rfkill_polarity;  } -/* h/w rfkill poll function */ -static void ath_rfkill_poll(struct work_struct *work) +/* s/w rfkill handlers */ +static int ath_rfkill_set_block(void *data, bool blocked)  { -	struct ath_softc *sc = container_of(work, struct ath_softc, -					    rf_kill.rfkill_poll.work); -	bool radio_on; - -	if (sc->sc_flags & SC_OP_INVALID) -		return; - -	radio_on = !ath_is_rfkill_set(sc); - -	/* -	 * enable/disable radio only when there is a -	 * state change in RF switch -	 */ -	if (radio_on == !!(sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED)) { -		enum rfkill_state state; - -		if (sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED) { -			state = radio_on ? RFKILL_STATE_SOFT_BLOCKED -				: RFKILL_STATE_HARD_BLOCKED; -		} else if (radio_on) { -			ath_radio_enable(sc); -			state = RFKILL_STATE_UNBLOCKED; -		} else { -			ath_radio_disable(sc); -			state = RFKILL_STATE_HARD_BLOCKED; -		} - -		if (state == RFKILL_STATE_HARD_BLOCKED) -			sc->sc_flags |= SC_OP_RFKILL_HW_BLOCKED; -		else -			sc->sc_flags &= ~SC_OP_RFKILL_HW_BLOCKED; +	struct ath_softc *sc = data; -		rfkill_force_state(sc->rf_kill.rfkill, state); -	} +	if (blocked) +		ath_radio_disable(sc); +	else +		ath_radio_enable(sc); -	queue_delayed_work(sc->hw->workqueue, &sc->rf_kill.rfkill_poll, -			   msecs_to_jiffies(ATH_RFKILL_POLL_INTERVAL)); +	return 0;  } -/* s/w rfkill handler */ -static int ath_sw_toggle_radio(void *data, enum rfkill_state state) +static void ath_rfkill_poll_state(struct rfkill *rfkill, void *data)  {  	struct ath_softc *sc = data; +	bool blocked = !!ath_is_rfkill_set(sc); -	switch (state) { -	case RFKILL_STATE_SOFT_BLOCKED: -		if (!(sc->sc_flags & (SC_OP_RFKILL_HW_BLOCKED | -		    SC_OP_RFKILL_SW_BLOCKED))) -			ath_radio_disable(sc); -		sc->sc_flags |= SC_OP_RFKILL_SW_BLOCKED; -		return 0; -	case RFKILL_STATE_UNBLOCKED: -		if ((sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED)) { -			sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED; -			if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) { -				DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the" -					"radio as it is disabled by h/w\n"); -				return -EPERM; -			} -			ath_radio_enable(sc); -		} -		return 0; -	default: -		return -EINVAL; -	} +	if (rfkill_set_hw_state(rfkill, blocked)) +		ath_radio_disable(sc); +	else +		ath_radio_enable(sc);  }  /* Init s/w rfkill */  static int ath_init_sw_rfkill(struct ath_softc *sc)  { -	sc->rf_kill.rfkill = rfkill_allocate(wiphy_dev(sc->hw->wiphy), -					     RFKILL_TYPE_WLAN); +	sc->rf_kill.ops.set_block = ath_rfkill_set_block; +	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) +		sc->rf_kill.ops.poll = ath_rfkill_poll_state; + +	snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name), +		"ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy)); + +	sc->rf_kill.rfkill = rfkill_alloc(sc->rf_kill.rfkill_name, +					  wiphy_dev(sc->hw->wiphy), +					  RFKILL_TYPE_WLAN, +					  &sc->rf_kill.ops, sc);  	if (!sc->rf_kill.rfkill) {  		DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n");  		return -ENOMEM;  	} -	snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name), -		"ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy)); -	sc->rf_kill.rfkill->name = sc->rf_kill.rfkill_name; -	sc->rf_kill.rfkill->data = sc; -	sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio; -	sc->rf_kill.rfkill->state = RFKILL_STATE_UNBLOCKED; -  	return 0;  }  /* Deinitialize rfkill */  static void ath_deinit_rfkill(struct ath_softc *sc)  { -	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) -		cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); -  	if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) {  		rfkill_unregister(sc->rf_kill.rfkill); +		rfkill_destroy(sc->rf_kill.rfkill);  		sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED; -		sc->rf_kill.rfkill = NULL;  	}  }  static int ath_start_rfkill_poll(struct ath_softc *sc)  { -	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) -		queue_delayed_work(sc->hw->workqueue, -				   &sc->rf_kill.rfkill_poll, 0); -  	if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) {  		if (rfkill_register(sc->rf_kill.rfkill)) {  			DPRINTF(sc, ATH_DBG_FATAL,  				"Unable to register rfkill\n"); -			rfkill_free(sc->rf_kill.rfkill); +			rfkill_destroy(sc->rf_kill.rfkill);  			/* Deinitialize the device */  			ath_cleanup(sc); @@ -1678,10 +1627,6 @@ int ath_attach(u16 devid, struct ath_softc *sc)  		goto error_attach;  #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) -	/* Initialze h/w Rfkill */ -	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) -		INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll); -  	/* Initialize s/w rfkill */  	error = ath_init_sw_rfkill(sc);  	if (error) @@ -2214,10 +2159,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)  	} else  		sc->rx.rxlink = NULL; -#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) -	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) -		cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); -#endif +	rfkill_pause_polling(sc->rf_kill.rfkill); +  	/* disable HAL and put h/w to sleep */  	ath9k_hw_disable(sc->sc_ah);  	ath9k_hw_configpcipowersave(sc->sc_ah, 1); diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 168411d322a..ccdf20a2e9b 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -227,11 +227,6 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)  	ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); -#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) -	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) -		cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); -#endif -  	pci_save_state(pdev);  	pci_disable_device(pdev);  	pci_set_power_state(pdev, PCI_D3hot); @@ -256,16 +251,6 @@ static int ath_pci_resume(struct pci_dev *pdev)  			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);  	ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); -#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) -	/* -	 * check the h/w rfkill state on resume -	 * and start the rfkill poll timer -	 */ -	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) -		queue_delayed_work(sc->hw->workqueue, -				   &sc->rf_kill.rfkill_poll, 0); -#endif -  	return 0;  } diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 21572e40b79..07a99e3faf9 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -102,7 +102,7 @@ config B43_LEDS  # if it's possible.  config B43_RFKILL  	bool -	depends on B43 && (RFKILL = y || RFKILL = B43) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43) +	depends on B43 && (RFKILL = y || RFKILL = B43)  	default y  # This config option automatically enables b43 HW-RNG support, diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index 76f4c7bad8b..9a498d3fc65 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c @@ -87,7 +87,7 @@ static void b43_led_brightness_set(struct led_classdev *led_dev,  }  static int b43_register_led(struct b43_wldev *dev, struct b43_led *led, -			    const char *name, char *default_trigger, +			    const char *name, const char *default_trigger,  			    u8 led_index, bool activelow)  {  	int err; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index cb4a8712946..1d3e40095ad 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -3470,7 +3470,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)  	if (!!conf->radio_enabled != phy->radio_on) {  		if (conf->radio_enabled) { -			b43_software_rfkill(dev, RFKILL_STATE_UNBLOCKED); +			b43_software_rfkill(dev, false);  			b43info(dev->wl, "Radio turned on by software\n");  			if (!dev->radio_hw_enable) {  				b43info(dev->wl, "The hardware RF-kill button " @@ -3478,7 +3478,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)  					"Press the button to turn it on.\n");  			}  		} else { -			b43_software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED); +			b43_software_rfkill(dev, true);  			b43info(dev->wl, "Radio turned off by software\n");  		}  	} diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c index c836c077d51..816e028a262 100644 --- a/drivers/net/wireless/b43/phy_a.c +++ b/drivers/net/wireless/b43/phy_a.c @@ -480,11 +480,11 @@ static bool b43_aphy_op_supports_hwpctl(struct b43_wldev *dev)  }  static void b43_aphy_op_software_rfkill(struct b43_wldev *dev, -					enum rfkill_state state) +					bool blocked)  {  	struct b43_phy *phy = &dev->phy; -	if (state == RFKILL_STATE_UNBLOCKED) { +	if (!blocked) {  		if (phy->radio_on)  			return;  		b43_radio_write16(dev, 0x0004, 0x00C0); diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index e176b6e0d9c..6d241622210 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -84,7 +84,7 @@ int b43_phy_init(struct b43_wldev *dev)  	phy->channel = ops->get_default_chan(dev); -	ops->software_rfkill(dev, RFKILL_STATE_UNBLOCKED); +	ops->software_rfkill(dev, false);  	err = ops->init(dev);  	if (err) {  		b43err(dev->wl, "PHY init failed\n"); @@ -104,7 +104,7 @@ err_phy_exit:  	if (ops->exit)  		ops->exit(dev);  err_block_rf: -	ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED); +	ops->software_rfkill(dev, true);  	return err;  } @@ -113,7 +113,7 @@ void b43_phy_exit(struct b43_wldev *dev)  {  	const struct b43_phy_operations *ops = dev->phy.ops; -	ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED); +	ops->software_rfkill(dev, true);  	if (ops->exit)  		ops->exit(dev);  } @@ -295,18 +295,13 @@ err_restore_cookie:  	return err;  } -void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state) +void b43_software_rfkill(struct b43_wldev *dev, bool blocked)  {  	struct b43_phy *phy = &dev->phy; -	if (state == RFKILL_STATE_HARD_BLOCKED) { -		/* We cannot hardware-block the device */ -		state = RFKILL_STATE_SOFT_BLOCKED; -	} -  	b43_mac_suspend(dev); -	phy->ops->software_rfkill(dev, state); -	phy->radio_on = (state == RFKILL_STATE_UNBLOCKED); +	phy->ops->software_rfkill(dev, blocked); +	phy->radio_on = !blocked;  	b43_mac_enable(dev);  } diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index b2d99101947..f4c2d79cbc8 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h @@ -159,7 +159,7 @@ struct b43_phy_operations {  	/* Radio */  	bool (*supports_hwpctl)(struct b43_wldev *dev); -	void (*software_rfkill)(struct b43_wldev *dev, enum rfkill_state state); +	void (*software_rfkill)(struct b43_wldev *dev, bool blocked);  	void (*switch_analog)(struct b43_wldev *dev, bool on);  	int (*switch_channel)(struct b43_wldev *dev, unsigned int new_channel);  	unsigned int (*get_default_chan)(struct b43_wldev *dev); @@ -364,7 +364,7 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);  /**   * b43_software_rfkill - Turn the radio ON or OFF in software.   */ -void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state); +void b43_software_rfkill(struct b43_wldev *dev, bool blocked);  /**   * b43_phy_txpower_check - Check TX power output. diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index e7b98f013b0..5300232449f 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c @@ -2592,7 +2592,7 @@ static bool b43_gphy_op_supports_hwpctl(struct b43_wldev *dev)  }  static void b43_gphy_op_software_rfkill(struct b43_wldev *dev, -					enum rfkill_state state) +					bool blocked)  {  	struct b43_phy *phy = &dev->phy;  	struct b43_phy_g *gphy = phy->g; @@ -2600,7 +2600,7 @@ static void b43_gphy_op_software_rfkill(struct b43_wldev *dev,  	might_sleep(); -	if (state == RFKILL_STATE_UNBLOCKED) { +	if (!blocked) {  		/* Turn radio ON */  		if (phy->radio_on)  			return; diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index 58e319d6b1e..ea0d3a3a6a6 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c @@ -488,7 +488,7 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)  }  static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev, -					 enum rfkill_state state) +					 bool blocked)  {  	//TODO  } diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 8bcfda5f3f0..be7b5604947 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -579,7 +579,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)  }  static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, -					enum rfkill_state state) +					bool blocked)  {//TODO  } diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 9e1d00bc24d..96047843cd5 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c @@ -45,12 +45,11 @@ static bool b43_is_hw_radio_enabled(struct b43_wldev *dev)  }  /* The poll callback for the hardware button. */ -static void b43_rfkill_poll(struct input_polled_dev *poll_dev) +static void b43_rfkill_poll(struct rfkill *rfkill, void *data)  { -	struct b43_wldev *dev = poll_dev->private; +	struct b43_wldev *dev = data;  	struct b43_wl *wl = dev->wl;  	bool enabled; -	bool report_change = 0;  	mutex_lock(&wl->mutex);  	if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { @@ -60,68 +59,55 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev)  	enabled = b43_is_hw_radio_enabled(dev);  	if (unlikely(enabled != dev->radio_hw_enable)) {  		dev->radio_hw_enable = enabled; -		report_change = 1;  		b43info(wl, "Radio hardware status changed to %s\n",  			enabled ? "ENABLED" : "DISABLED"); +		enabled = !rfkill_set_hw_state(rfkill, !enabled); +		if (enabled != dev->phy.radio_on) +			b43_software_rfkill(dev, !enabled);  	}  	mutex_unlock(&wl->mutex); - -	/* send the radio switch event to the system - note both a key press -	 * and a release are required */ -	if (unlikely(report_change)) { -		input_report_key(poll_dev->input, KEY_WLAN, 1); -		input_report_key(poll_dev->input, KEY_WLAN, 0); -	}  }  /* Called when the RFKILL toggled in software. */ -static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) +static int b43_rfkill_soft_set(void *data, bool blocked)  {  	struct b43_wldev *dev = data;  	struct b43_wl *wl = dev->wl; -	int err = -EBUSY; +	int err = -EINVAL; -	if (!wl->rfkill.registered) -		return 0; +	if (WARN_ON(!wl->rfkill.registered)) +		return -EINVAL;  	mutex_lock(&wl->mutex); +  	if (b43_status(dev) < B43_STAT_INITIALIZED)  		goto out_unlock; + +	if (!dev->radio_hw_enable) +		goto out_unlock; + +	if (!blocked != dev->phy.radio_on) +		b43_software_rfkill(dev, blocked);  	err = 0; -	switch (state) { -	case RFKILL_STATE_UNBLOCKED: -		if (!dev->radio_hw_enable) { -			/* No luck. We can't toggle the hardware RF-kill -			 * button from software. */ -			err = -EBUSY; -			goto out_unlock; -		} -		if (!dev->phy.radio_on) -			b43_software_rfkill(dev, state); -		break; -	case RFKILL_STATE_SOFT_BLOCKED: -		if (dev->phy.radio_on) -			b43_software_rfkill(dev, state); -		break; -	default: -		b43warn(wl, "Received unexpected rfkill state %d.\n", state); -		break; -	}  out_unlock:  	mutex_unlock(&wl->mutex); -  	return err;  } -char *b43_rfkill_led_name(struct b43_wldev *dev) +const char *b43_rfkill_led_name(struct b43_wldev *dev)  {  	struct b43_rfkill *rfk = &(dev->wl->rfkill);  	if (!rfk->registered)  		return NULL; -	return rfkill_get_led_name(rfk->rfkill); +	return rfkill_get_led_trigger_name(rfk->rfkill);  } +static const struct rfkill_ops b43_rfkill_ops = { +	.set_block = b43_rfkill_soft_set, +	.poll = b43_rfkill_poll, +}; +  void b43_rfkill_init(struct b43_wldev *dev)  {  	struct b43_wl *wl = dev->wl; @@ -130,65 +116,26 @@ void b43_rfkill_init(struct b43_wldev *dev)  	rfk->registered = 0; -	rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN); -	if (!rfk->rfkill) -		goto out_error;  	snprintf(rfk->name, sizeof(rfk->name),  		 "b43-%s", wiphy_name(wl->hw->wiphy)); -	rfk->rfkill->name = rfk->name; -	rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; -	rfk->rfkill->data = dev; -	rfk->rfkill->toggle_radio = b43_rfkill_soft_toggle; -	rfk->poll_dev = input_allocate_polled_device(); -	if (!rfk->poll_dev) { -		rfkill_free(rfk->rfkill); -		goto err_freed_rfk; -	} - -	rfk->poll_dev->private = dev; -	rfk->poll_dev->poll = b43_rfkill_poll; -	rfk->poll_dev->poll_interval = 1000; /* msecs */ - -	rfk->poll_dev->input->name = rfk->name; -	rfk->poll_dev->input->id.bustype = BUS_HOST; -	rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor; -	rfk->poll_dev->input->evbit[0] = BIT(EV_KEY); -	set_bit(KEY_WLAN, rfk->poll_dev->input->keybit); +	rfk->rfkill = rfkill_alloc(rfk->name, +				   dev->dev->dev, +				   RFKILL_TYPE_WLAN, +				   &b43_rfkill_ops, dev); +	if (!rfk->rfkill) +		goto out_error;  	err = rfkill_register(rfk->rfkill);  	if (err) -		goto err_free_polldev; - -#ifdef CONFIG_RFKILL_INPUT_MODULE -	/* B43 RF-kill isn't useful without the rfkill-input subsystem. -	 * Try to load the module. */ -	err = request_module("rfkill-input"); -	if (err) -		b43warn(wl, "Failed to load the rfkill-input module. " -			"The built-in radio LED will not work.\n"); -#endif /* CONFIG_RFKILL_INPUT */ - -#if !defined(CONFIG_RFKILL_INPUT) && !defined(CONFIG_RFKILL_INPUT_MODULE) -	b43warn(wl, "The rfkill-input subsystem is not available. " -		"The built-in radio LED will not work.\n"); -#endif - -	err = input_register_polled_device(rfk->poll_dev); -	if (err) -		goto err_unreg_rfk; +		goto err_free;  	rfk->registered = 1;  	return; -err_unreg_rfk: -	rfkill_unregister(rfk->rfkill); -err_free_polldev: -	input_free_polled_device(rfk->poll_dev); -	rfk->poll_dev = NULL; -err_freed_rfk: -	rfk->rfkill = NULL; -out_error: + err_free: +	rfkill_destroy(rfk->rfkill); + out_error:  	rfk->registered = 0;  	b43warn(wl, "RF-kill button init failed\n");  } @@ -201,9 +148,7 @@ void b43_rfkill_exit(struct b43_wldev *dev)  		return;  	rfk->registered = 0; -	input_unregister_polled_device(rfk->poll_dev);  	rfkill_unregister(rfk->rfkill); -	input_free_polled_device(rfk->poll_dev); -	rfk->poll_dev = NULL; +	rfkill_destroy(rfk->rfkill);  	rfk->rfkill = NULL;  } diff --git a/drivers/net/wireless/b43/rfkill.h b/drivers/net/wireless/b43/rfkill.h index adacf936d81..da497e01bbb 100644 --- a/drivers/net/wireless/b43/rfkill.h +++ b/drivers/net/wireless/b43/rfkill.h @@ -7,14 +7,11 @@ struct b43_wldev;  #ifdef CONFIG_B43_RFKILL  #include <linux/rfkill.h> -#include <linux/input-polldev.h>  struct b43_rfkill {  	/* The RFKILL subsystem data structure */  	struct rfkill *rfkill; -	/* The poll device for the RFKILL input button */ -	struct input_polled_dev *poll_dev;  	/* Did initialization succeed? Used for freeing. */  	bool registered;  	/* The unique name of this rfkill switch */ @@ -26,7 +23,7 @@ struct b43_rfkill {  void b43_rfkill_init(struct b43_wldev *dev);  void b43_rfkill_exit(struct b43_wldev *dev); -char * b43_rfkill_led_name(struct b43_wldev *dev); +const char *b43_rfkill_led_name(struct b43_wldev *dev);  #else /* CONFIG_B43_RFKILL */ diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig index d4f628a74bb..6893f439df7 100644 --- a/drivers/net/wireless/b43legacy/Kconfig +++ b/drivers/net/wireless/b43legacy/Kconfig @@ -47,7 +47,7 @@ config B43LEGACY_LEDS  # if it's possible.  config B43LEGACY_RFKILL  	bool -	depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43LEGACY) +	depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY)  	default y  # This config option automatically enables b43 HW-RNG support, diff --git a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c index 3ea55b18c70..538d3117594 100644 --- a/drivers/net/wireless/b43legacy/leds.c +++ b/drivers/net/wireless/b43legacy/leds.c @@ -86,7 +86,8 @@ static void b43legacy_led_brightness_set(struct led_classdev *led_dev,  static int b43legacy_register_led(struct b43legacy_wldev *dev,  				  struct b43legacy_led *led, -				  const char *name, char *default_trigger, +				  const char *name, +				  const char *default_trigger,  				  u8 led_index, bool activelow)  {  	int err; diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index 4b0c7d27a51..c6230a64505 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c @@ -45,12 +45,11 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)  }  /* The poll callback for the hardware button. */ -static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) +static void b43legacy_rfkill_poll(struct rfkill *rfkill, void *data)  { -	struct b43legacy_wldev *dev = poll_dev->private; +	struct b43legacy_wldev *dev = data;  	struct b43legacy_wl *wl = dev->wl;  	bool enabled; -	bool report_change = 0;  	mutex_lock(&wl->mutex);  	if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { @@ -60,71 +59,64 @@ static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev)  	enabled = b43legacy_is_hw_radio_enabled(dev);  	if (unlikely(enabled != dev->radio_hw_enable)) {  		dev->radio_hw_enable = enabled; -		report_change = 1;  		b43legacyinfo(wl, "Radio hardware status changed to %s\n",  			enabled ? "ENABLED" : "DISABLED"); +		enabled = !rfkill_set_hw_state(rfkill, !enabled); +		if (enabled != dev->phy.radio_on) { +			if (enabled) +				b43legacy_radio_turn_on(dev); +			else +				b43legacy_radio_turn_off(dev, 0); +		}  	}  	mutex_unlock(&wl->mutex); - -	/* send the radio switch event to the system - note both a key press -	 * and a release are required */ -	if (unlikely(report_change)) { -		input_report_key(poll_dev->input, KEY_WLAN, 1); -		input_report_key(poll_dev->input, KEY_WLAN, 0); -	}  }  /* Called when the RFKILL toggled in software.   * This is called without locking. */ -static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) +static int b43legacy_rfkill_soft_set(void *data, bool blocked)  {  	struct b43legacy_wldev *dev = data;  	struct b43legacy_wl *wl = dev->wl; -	int err = -EBUSY; +	int ret = -EINVAL;  	if (!wl->rfkill.registered) -		return 0; +		return -EINVAL;  	mutex_lock(&wl->mutex);  	if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)  		goto out_unlock; -	err = 0; -	switch (state) { -	case RFKILL_STATE_UNBLOCKED: -		if (!dev->radio_hw_enable) { -			/* No luck. We can't toggle the hardware RF-kill -			 * button from software. */ -			err = -EBUSY; -			goto out_unlock; -		} -		if (!dev->phy.radio_on) + +	if (!dev->radio_hw_enable) +		goto out_unlock; + +	if (!blocked != dev->phy.radio_on) { +		if (!blocked)  			b43legacy_radio_turn_on(dev); -		break; -	case RFKILL_STATE_SOFT_BLOCKED: -		if (dev->phy.radio_on) +		else  			b43legacy_radio_turn_off(dev, 0); -		break; -	default: -		b43legacywarn(wl, "Received unexpected rfkill state %d.\n", -			      state); -		break;  	} +	ret = 0;  out_unlock:  	mutex_unlock(&wl->mutex); - -	return err; +	return ret;  } -char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) +const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev)  {  	struct b43legacy_rfkill *rfk = &(dev->wl->rfkill);  	if (!rfk->registered)  		return NULL; -	return rfkill_get_led_name(rfk->rfkill); +	return rfkill_get_led_trigger_name(rfk->rfkill);  } +static const struct rfkill_ops b43legacy_rfkill_ops = { +	.set_block = b43legacy_rfkill_soft_set, +	.poll = b43legacy_rfkill_poll, +}; +  void b43legacy_rfkill_init(struct b43legacy_wldev *dev)  {  	struct b43legacy_wl *wl = dev->wl; @@ -133,60 +125,25 @@ void b43legacy_rfkill_init(struct b43legacy_wldev *dev)  	rfk->registered = 0; -	rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN); -	if (!rfk->rfkill) -		goto out_error;  	snprintf(rfk->name, sizeof(rfk->name),  		 "b43legacy-%s", wiphy_name(wl->hw->wiphy)); -	rfk->rfkill->name = rfk->name; -	rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; -	rfk->rfkill->data = dev; -	rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle; - -	rfk->poll_dev = input_allocate_polled_device(); -	if (!rfk->poll_dev) { -		rfkill_free(rfk->rfkill); -		goto err_freed_rfk; -	} - -	rfk->poll_dev->private = dev; -	rfk->poll_dev->poll = b43legacy_rfkill_poll; -	rfk->poll_dev->poll_interval = 1000; /* msecs */ - -	rfk->poll_dev->input->name = rfk->name; -	rfk->poll_dev->input->id.bustype = BUS_HOST; -	rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor; -	rfk->poll_dev->input->evbit[0] = BIT(EV_KEY); -	set_bit(KEY_WLAN, rfk->poll_dev->input->keybit); +	rfk->rfkill = rfkill_alloc(rfk->name, +				   dev->dev->dev, +				   RFKILL_TYPE_WLAN, +				   &b43legacy_rfkill_ops, dev); +	if (!rfk->rfkill) +		goto out_error;  	err = rfkill_register(rfk->rfkill);  	if (err) -		goto err_free_polldev; - -#ifdef CONFIG_RFKILL_INPUT_MODULE -	/* B43legacy RF-kill isn't useful without the rfkill-input subsystem. -	 * Try to load the module. */ -	err = request_module("rfkill-input"); -	if (err) -		b43legacywarn(wl, "Failed to load the rfkill-input module." -			"The built-in radio LED will not work.\n"); -#endif /* CONFIG_RFKILL_INPUT */ - -	err = input_register_polled_device(rfk->poll_dev); -	if (err) -		goto err_unreg_rfk; +		goto err_free;  	rfk->registered = 1;  	return; -err_unreg_rfk: -	rfkill_unregister(rfk->rfkill); -err_free_polldev: -	input_free_polled_device(rfk->poll_dev); -	rfk->poll_dev = NULL; -err_freed_rfk: -	rfk->rfkill = NULL; -out_error: + err_free: +	rfkill_destroy(rfk->rfkill); + out_error:  	rfk->registered = 0;  	b43legacywarn(wl, "RF-kill button init failed\n");  } @@ -199,10 +156,8 @@ void b43legacy_rfkill_exit(struct b43legacy_wldev *dev)  		return;  	rfk->registered = 0; -	input_unregister_polled_device(rfk->poll_dev);  	rfkill_unregister(rfk->rfkill); -	input_free_polled_device(rfk->poll_dev); -	rfk->poll_dev = NULL; +	rfkill_destroy(rfk->rfkill);  	rfk->rfkill = NULL;  } diff --git a/drivers/net/wireless/b43legacy/rfkill.h b/drivers/net/wireless/b43legacy/rfkill.h index 11150a8032f..adffc503a6a 100644 --- a/drivers/net/wireless/b43legacy/rfkill.h +++ b/drivers/net/wireless/b43legacy/rfkill.h @@ -6,16 +6,12 @@ struct b43legacy_wldev;  #ifdef CONFIG_B43LEGACY_RFKILL  #include <linux/rfkill.h> -#include <linux/workqueue.h> -#include <linux/input-polldev.h>  struct b43legacy_rfkill {  	/* The RFKILL subsystem data structure */  	struct rfkill *rfkill; -	/* The poll device for the RFKILL input button */ -	struct input_polled_dev *poll_dev;  	/* Did initialization succeed? Used for freeing. */  	bool registered;  	/* The unique name of this rfkill switch */ @@ -27,7 +23,7 @@ struct b43legacy_rfkill {  void b43legacy_rfkill_init(struct b43legacy_wldev *dev);  void b43legacy_rfkill_exit(struct b43legacy_wldev *dev); -char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev); +const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev);  #else /* CONFIG_B43LEGACY_RFKILL */ diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 8304f6406a1..6fe259fcfb8 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -5,15 +5,14 @@ config IWLWIFI  	select FW_LOADER  	select MAC80211_LEDS if IWLWIFI_LEDS  	select LEDS_CLASS if IWLWIFI_LEDS -	select RFKILL if IWLWIFI_RFKILL  config IWLWIFI_LEDS  	bool "Enable LED support in iwlagn and iwl3945 drivers"  	depends on IWLWIFI  config IWLWIFI_RFKILL -	bool "Enable RF kill support in iwlagn and iwl3945 drivers" -	depends on IWLWIFI +	def_bool y +	depends on IWLWIFI && RFKILL  config IWLWIFI_SPECTRUM_MEASUREMENT  	bool "Enable Spectrum Measurement in iwlagn driver" diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c index 65605ad44e4..13149936fd2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c @@ -36,42 +36,37 @@  #include "iwl-core.h"  /* software rf-kill from user */ -static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) +static int iwl_rfkill_soft_rf_kill(void *data, bool blocked)  {  	struct iwl_priv *priv = data; -	int err = 0;  	if (!priv->rfkill) -		return 0; +		return -EINVAL;  	if (test_bit(STATUS_EXIT_PENDING, &priv->status))  		return 0; -	IWL_DEBUG_RF_KILL(priv, "we received soft RFKILL set to state %d\n", state); +	IWL_DEBUG_RF_KILL(priv, "received soft RFKILL: block=%d\n", blocked); +  	mutex_lock(&priv->mutex); -	switch (state) { -	case RFKILL_STATE_UNBLOCKED: -		if (iwl_is_rfkill_hw(priv)) { -			err = -EBUSY; -			goto out_unlock; -		} +	if (iwl_is_rfkill_hw(priv)) +		goto out_unlock; + +	if (!blocked)  		iwl_radio_kill_sw_enable_radio(priv); -		break; -	case RFKILL_STATE_SOFT_BLOCKED: +	else  		iwl_radio_kill_sw_disable_radio(priv); -		break; -	default: -		IWL_WARN(priv, "we received unexpected RFKILL state %d\n", -			state); -		break; -	} +  out_unlock:  	mutex_unlock(&priv->mutex); - -	return err; +	return 0;  } +static const struct rfkill_ops iwl_rfkill_ops = { +	.set_block = iwl_rfkill_soft_rf_kill, +}; +  int iwl_rfkill_init(struct iwl_priv *priv)  {  	struct device *device = wiphy_dev(priv->hw->wiphy); @@ -80,21 +75,16 @@ int iwl_rfkill_init(struct iwl_priv *priv)  	BUG_ON(device == NULL);  	IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n"); -	priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); +	priv->rfkill = rfkill_alloc(priv->cfg->name, +				    device, +				    RFKILL_TYPE_WLAN, +				    &iwl_rfkill_ops, priv);  	if (!priv->rfkill) {  		IWL_ERR(priv, "Unable to allocate RFKILL device.\n");  		ret = -ENOMEM;  		goto error;  	} -	priv->rfkill->name = priv->cfg->name; -	priv->rfkill->data = priv; -	priv->rfkill->state = RFKILL_STATE_UNBLOCKED; -	priv->rfkill->toggle_radio = iwl_rfkill_soft_rf_kill; - -	priv->rfkill->dev.class->suspend = NULL; -	priv->rfkill->dev.class->resume = NULL; -  	ret = rfkill_register(priv->rfkill);  	if (ret) {  		IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret); @@ -102,11 +92,10 @@ int iwl_rfkill_init(struct iwl_priv *priv)  	}  	IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n"); -	return ret; +	return 0;  free_rfkill: -	if (priv->rfkill != NULL) -		rfkill_free(priv->rfkill); +	rfkill_destroy(priv->rfkill);  	priv->rfkill = NULL;  error: @@ -118,8 +107,10 @@ EXPORT_SYMBOL(iwl_rfkill_init);  void iwl_rfkill_unregister(struct iwl_priv *priv)  { -	if (priv->rfkill) +	if (priv->rfkill) {  		rfkill_unregister(priv->rfkill); +		rfkill_destroy(priv->rfkill); +	}  	priv->rfkill = NULL;  } @@ -131,14 +122,10 @@ void iwl_rfkill_set_hw_state(struct iwl_priv *priv)  	if (!priv->rfkill)  		return; -	if (iwl_is_rfkill_hw(priv)) { -		rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED); -		return; -	} - -	if (!iwl_is_rfkill_sw(priv)) -		rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED); +	if (rfkill_set_hw_state(priv->rfkill, +				!!iwl_is_rfkill_hw(priv))) +		iwl_radio_kill_sw_disable_radio(priv);  	else -		rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED); +		iwl_radio_kill_sw_enable_radio(priv);  }  EXPORT_SYMBOL(iwl_rfkill_set_hw_state); diff --git a/drivers/net/wireless/iwmc3200wifi/rfkill.c b/drivers/net/wireless/iwmc3200wifi/rfkill.c index 4ca8b495f82..8ee2c3c09a0 100644 --- a/drivers/net/wireless/iwmc3200wifi/rfkill.c +++ b/drivers/net/wireless/iwmc3200wifi/rfkill.c @@ -25,47 +25,42 @@  #include "iwm.h" -static int iwm_rfkill_soft_toggle(void *data, enum rfkill_state state) +static int iwm_rfkill_set_block(void *data, bool blocked)  {  	struct iwm_priv *iwm = data; -	switch (state) { -	case RFKILL_STATE_UNBLOCKED: +	if (!blocked) {  		if (test_bit(IWM_RADIO_RFKILL_HW, &iwm->radio))  			return -EBUSY;  		if (test_and_clear_bit(IWM_RADIO_RFKILL_SW, &iwm->radio) &&  		    (iwm_to_ndev(iwm)->flags & IFF_UP)) -			iwm_up(iwm); - -		break; -	case RFKILL_STATE_SOFT_BLOCKED: +			return iwm_up(iwm); +	} else {  		if (!test_and_set_bit(IWM_RADIO_RFKILL_SW, &iwm->radio)) -			iwm_down(iwm); - -		break; -	default: -		break; +			return iwm_down(iwm);  	}  	return 0;  } +static const struct rfkill_ops iwm_rfkill_ops = { +	.set_block = iwm_rfkill_set_block, +}; +  int iwm_rfkill_init(struct iwm_priv *iwm)  {  	int ret; -	iwm->rfkill = rfkill_allocate(iwm_to_dev(iwm), RFKILL_TYPE_WLAN); +	iwm->rfkill = rfkill_alloc(KBUILD_MODNAME, +				   iwm_to_dev(iwm), +				   RFKILL_TYPE_WLAN, +				   &iwm_rfkill_ops, iwm);  	if (!iwm->rfkill) {  		IWM_ERR(iwm, "Unable to allocate rfkill device\n");  		return -ENOMEM;  	} -	iwm->rfkill->name = KBUILD_MODNAME; -	iwm->rfkill->data = iwm; -	iwm->rfkill->state = RFKILL_STATE_UNBLOCKED; -	iwm->rfkill->toggle_radio = iwm_rfkill_soft_toggle; -  	ret = rfkill_register(iwm->rfkill);  	if (ret) {  		IWM_ERR(iwm, "Failed to register rfkill device\n"); @@ -74,15 +69,15 @@ int iwm_rfkill_init(struct iwm_priv *iwm)  	return 0;   fail: -	rfkill_free(iwm->rfkill); +	rfkill_destroy(iwm->rfkill);  	return ret;  }  void iwm_rfkill_exit(struct iwm_priv *iwm)  { -	if (iwm->rfkill) +	if (iwm->rfkill) {  		rfkill_unregister(iwm->rfkill); - -	rfkill_free(iwm->rfkill); +		rfkill_destroy(iwm->rfkill); +	}  	iwm->rfkill = NULL;  }  |