/*
 * Copyright (C) 2006 - 2007 Ivo van Doorn
 * Copyright (C) 2007 Dmitry Torokhov
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/workqueue.h>
#include <linux/capability.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/rfkill.h>

/* Get declaration of rfkill_switch_all() to shut up sparse. */
#include "rfkill-input.h"


MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
MODULE_VERSION("1.0");
MODULE_DESCRIPTION("RF switch support");
MODULE_LICENSE("GPL");

static LIST_HEAD(rfkill_list);	/* list of registered rf switches */
static DEFINE_MUTEX(rfkill_global_mutex);

static unsigned int rfkill_default_state = RFKILL_STATE_UNBLOCKED;
module_param_named(default_state, rfkill_default_state, uint, 0444);
MODULE_PARM_DESC(default_state,
		 "Default initial state for all radio types, 0 = radio off");

struct rfkill_gsw_state {
	enum rfkill_state current_state;
	enum rfkill_state default_state;
};

static struct rfkill_gsw_state rfkill_global_states[RFKILL_TYPE_MAX];
static unsigned long rfkill_states_lockdflt[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
static bool rfkill_epo_lock_active;


#ifdef CONFIG_RFKILL_LEDS
static void rfkill_led_trigger(struct rfkill *rfkill,
			       enum rfkill_state state)
{
	struct led_trigger *led = &rfkill->led_trigger;

	if (!led->name)
		return;
	if (state != RFKILL_STATE_UNBLOCKED)
		led_trigger_event(led, LED_OFF);
	else
		led_trigger_event(led, LED_FULL);
}

static void rfkill_led_trigger_activate(struct led_classdev *led)
{
	struct rfkill *rfkill = container_of(led->trigger,
			struct rfkill, led_trigger);

	rfkill_led_trigger(rfkill, rfkill->state);
}
#endif /* CONFIG_RFKILL_LEDS */

static void rfkill_uevent(struct rfkill *rfkill)
{
	kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);
}

static void update_rfkill_state(struct rfkill *rfkill)
{
	enum rfkill_state newstate, oldstate;

	if (rfkill->get_state) {
		mutex_lock(&rfkill->mutex);
		if (!rfkill->get_state(rfkill->data, &newstate)) {
			oldstate = rfkill->state;
			rfkill->state = newstate;
			if (oldstate != newstate)
				rfkill_uevent(rfkill);
		}
		mutex_unlock(&rfkill->mutex);
	}
}

/**
 * rfkill_toggle_radio - wrapper for toggle_radio hook
 * @rfkill: the rfkill struct to use
 * @force: calls toggle_radio even if cache says it is not needed,
 *	and also makes sure notifications of the state will be
 *	sent even if it didn't change
 * @state: the new state to call toggle_radio() with
 *
 * Calls rfkill->toggle_radio, enforcing the API for toggle_radio
 * calls and handling all the red tape such as issuing notifications
 * if the call is successful.
 *
 * Suspended devices are not touched at all, and -EAGAIN is returned.
 *
 * Note that the @force parameter cannot override a (possibly cached)
 * state of RFKILL_STATE_HARD_BLOCKED.  Any device making use of
 * RFKILL_STATE_HARD_BLOCKED implements either get_state() or
 * rfkill_force_state(), so the cache either is bypassed or valid.
 *
 * Note that we do call toggle_radio for RFKILL_STATE_SOFT_BLOCKED
 * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to
 * give the driver a hint that it should double-BLOCK the transmitter.
 *
 * Caller must have acquired rfkill->mutex.
 */
static int rfkill_toggle_radio(struct rfkill *rfkill,
				enum rfkill_state state,
				int force)
{
	int retval = 0;
	enum rfkill_state oldstate, newstate;

	if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP))
		return -EBUSY;

	oldstate = rfkill->state;

	if (rfkill->get_state && !force &&
	    !rfkill->get_state(rfkill->data, &newstate))
		rfkill->state = newstate;

	switch (state) {
	case RFKILL_STATE_HARD_BLOCKED:
		/* typically happens when refreshing hardware state,
		 * such as on resume */
		state = RFKILL_STATE_SOFT_BLOCKED;
		break;
	case RFKILL_STATE_UNBLOCKED:
		/* force can't override this, only rfkill_force_state() can */
		if (rfkill->state == RFKILL_STATE_HARD_BLOCKED)
			return -EPERM;
		break;
	case RFKILL_STATE_SOFT_BLOCKED:
		/* nothing to do, we want to give drivers the hint to double
		 * BLOCK even a transmitter that is already in state
		 * RFKILL_STATE_HARD_BLOCKED */
		break;
	default:
		WARN(1, KERN_WARNING
			"rfkill: illegal state %d passed as parameter "
			"to rfkill_toggle_radio\n", state);
		return -EINVAL;
	}

	if (force || state != rfkill->state) {
		retval = rfkill->toggle_radio(rfkill->data, state);
		/* never allow a HARD->SOFT downgrade! */
		if (!retval && rfkill->state != RFKILL_STATE_HARD_BLOCKED)
			rfkill->state = state;
	}

	if (force || rfkill->state != oldstate)
		rfkill_uevent(rfkill);

	return retval;
}

/**
 * __rfkill_switch_all - Toggle state of all switches of given type
 * @type: type of interfaces to be affected
 * @state: the new state
 *
 * This function toggles the state of all switches of given type,
 * unless a specific switch is claimed by userspace (in which case,
 * that switch is left alone) or suspended.
 *
 * Caller must have acquired rfkill_global_mutex.
 */
static void __rfkill_switch_all(const enum rfkill_type type,
				const enum rfkill_state state)
{
	struct rfkill *rfkill;

	if (WARN((state >= RFKILL_STATE_MAX || type >= RFKILL_TYPE_MAX),
			KERN_WARNING
			"rfkill: illegal state %d or type %d "
			"passed as parameter to __rfkill_switch_all\n",
			state, type))
		return;

	rfkill_global_states[type].current_state = state;
	list_for_each_entry(rfkill, &rfkill_list, node) {
		if ((!rfkill->user_claim) && (rfkill->type == type)) {
			mutex_lock(&rfkill->mutex);
			rfkill_toggle_radio(rfkill, state, 0);
			mutex_unlock(&rfkill->mutex);
		}
	}
}

/**
 * rfkill_switch_all - Toggle state of all switches of given type
 * @type: type of interfaces to be affected
 * @state: the new state
 *
 * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state).
 * Please refer to __rfkill_switch_all() for details.
 *
 * Does nothing if the EPO lock is active.
 */
void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
{
	mutex_lock(&rfkill_global_mutex);
	if (!rfkill_epo_lock_active)
		__rfkill_switch_all(type, state);
	mutex_unlock(&rfkill_global_mutex);
}
EXPORT_SYMBOL(rfkill_switch_all);

/**
 * rfkill_epo - emergency power off all transmitters
 *
 * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED,
 * ignoring everything in its path but rfkill_global_mutex and rfkill->mutex.
 *
 * The global state before the EPO is saved and can be restored later
 * using rfkill_restore_states().
 */
void rfkill_epo(void)
{
	struct rfkill *rfkill;
	int i;

	mutex_lock(&rfkill_global_mutex);

	rfkill_epo_lock_active = true;
	list_for_each_entry(rfkill, &rfkill_list, node) {
		mutex_lock(&rfkill->mutex);
		rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
		mutex_unlock(&rfkill->mutex);
	}
	for (i = 0; i < RFKILL_TYPE_MAX; i++) {
		rfkill_global_states[i].default_state =
				rfkill_global_states[i].current_state;
		rfkill_global_states[i].current_state =
				RFKILL_STATE_SOFT_BLOCKED;
	}
	mutex_unlock(&rfkill_global_mutex);
}
EXPORT_SYMBOL_GPL(rfkill_epo);

/**
 * rfkill_restore_states - restore global states
 *
 * Restore (and sync switches to) the global state from the
 * states in rfkill_default_states.  This can undo the effects of
 * a call to rfkill_epo().
 */
void rfkill_restore_states(void)
{
	int i;

	mutex_lock(&rfkill_global_mutex);

	rfkill_epo_lock_active = false;
	for (i = 0; i < RFKILL_TYPE_MAX; i++)
		__rfkill_switch_all(i, rfkill_global_states[i].default_state);
	mutex_unlock(&rfkill_global_mutex);
}
EXPORT_SYMBOL_GPL(rfkill_restore_states);

/**
 * rfkill_remove_epo_lock - unlock state changes
 *
 * Used by rfkill-input manually unlock state changes, when
 * the EPO switch is deactivated.
 */
void rfkill_remove_epo_lock(void)
{
	mutex_lock(&rfkill_global_mutex);
	rfkill_epo_lock_active = false;
	mutex_unlock(&rfkill_global_mutex);
}
EXPORT_SYMBOL_GPL(rfkill_remove_epo_lock);

/**
 * rfkill_is_epo_lock_active - returns true EPO is active
 *
 * Returns 0 (false) if there is NOT an active EPO contidion,
 * and 1 (true) if there is an active EPO contition, which
 * locks all radios in one of the BLOCKED states.
 *
 * Can be called in atomic context.
 */
bool rfkill_is_epo_lock_active(void)
{
	return rfkill_epo_lock_active;
}
EXPORT_SYMBOL_GPL(rfkill_is_epo_lock_active);

/**
 * rfkill_get_global_state - returns global state for a type
 * @type: the type to get the global state of
 *
 * Returns the current global state for a given wireless
 * device type.
 */
enum rfkill_state rfkill_get_global_state(const enum rfkill_type type)
{
	return rfkill_global_states[type].current_state;
}
EXPORT_SYMBOL_GPL(rfkill_get_global_state);

/**
 * rfkill_force_state - Force the internal rfkill radio state
 * @rfkill: pointer to the rfkill class to modify.
 * @state: the current radio state the class should be forced to.
 *
 * This function updates the internal state of the radio cached
 * by the rfkill class.  It should be used when the driver gets
 * a notification by the firmware/hardware of the current *real*
 * state of the radio rfkill switch.
 *
 * Devices which are subject to external changes on their rfkill
 * state (such as those caused by a hardware rfkill line) MUST
 * have their driver arrange to call rfkill_force_state() as soon
 * as possible after such a change.
 *
 * This function may not be called from an atomic context.
 */
int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
{
	enum rfkill_state oldstate;

	BUG_ON(!rfkill);
	if (WARN((state >= RFKILL_STATE_MAX),
			KERN_WARNING
			"rfkill: illegal state %d passed as parameter "
			"to rfkill_force_state\n", state))
		return -EINVAL;

	mutex_lock(&rfkill->mutex);

	oldstate = rfkill->state;
	rfkill->state = state;

	if (state != oldstate)
		rfkill_uevent(rfkill);

	mutex_unlock(&rfkill->mutex);

	return 0;
}
EXPORT_SYMBOL(rfkill_force_state);

static ssize_t rfkill_name_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	struct rfkill *rfkill = to_rfkill(dev);

	return sprintf(buf, "%s\n", rfkill->name);
}

static const char *rfkill_get_type_str(enum rfkill_type type)
{
	switch (type) {
	case RFKILL_TYPE_WLAN:
		return "wlan";
	case RFKILL_TYPE_BLUETOOTH:
		return "bluetooth";
	case RFKILL_TYPE_UWB:
		return "ultrawideband";
	case RFKILL_TYPE_WIMAX:
		return "wimax";
	case RFKILL_TYPE_WWAN:
		return "wwan";
	default:
		BUG();
	}
}

static ssize_t rfkill_type_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	struct rfkill *rfkill = to_rfkill(dev);

	return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));
}

static ssize_t rfkill_state_show(struct device *dev,
				 struct device_attribute *attr,
				 char *buf)
{
	struct rfkill *rfkill = to_rfkill(dev);

	update_rfkill_state(rfkill);
	return sprintf(buf, "%d\n", rfkill->state);
}

static ssize_t rfkill_state_store(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf, size_t count)
{
	struct rfkill *rfkill = to_rfkill(dev);
	unsigned long state;
	int error;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	error = strict_strtoul(buf, 0, &state);
	if (error)
		return error;

	/* RFKILL_STATE_HARD_BLOCKED is illegal here... */
	if (state != RFKILL_STATE_UNBLOCKED &&
	    state != RFKILL_STATE_SOFT_BLOCKED)
		return -EINVAL;

	error = mutex_lock_killable(&rfkill->mutex);
	if (error)
		return error;

	if (!rfkill_epo_lock_active)
		error = rfkill_toggle_radio(rfkill, state, 0);
	else
		error = -EPERM;

	mutex_unlock(&rfkill->mutex);

	return error ? error : count;
}

static ssize_t rfkill_claim_show(struct device *dev,
				 struct device_attribute *attr,
				 char *buf)
{
	struct rfkill *rfkill = to_rfkill(dev);

	return sprintf(buf, "%d\n", rfkill->user_claim);
}

static ssize_t rfkill_claim_store(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf, size_t count)
{
	struct rfkill *rfkill = to_rfkill(dev);
	unsigned long claim_tmp;
	bool claim;
	int error;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	if (rfkill->user_claim_unsupported)
		return -EOPNOTSUPP;

	error = strict_strtoul(buf, 0, &claim_tmp);
	if (error)
		return error;
	claim = !!claim_tmp;

	/*
	 * Take the global lock to make sure the kernel is not in
	 * the middle of rfkill_switch_all
	 */
	error = mutex_lock_killable(&rfkill_global_mutex);
	if (error)
		return error;

	if (rfkill->user_claim != claim) {
		if (!claim && !rfkill_epo_lock_active) {
			mutex_lock(&rfkill->mutex);
			rfkill_toggle_radio(rfkill,
					rfkill_global_states[rfkill->type].current_state,
					0);
			mutex_unlock(&rfkill->mutex);
		}
		rfkill->user_claim = claim;
	}

	mutex_unlock(&rfkill_global_mutex);

	return error ? error : count;
}

static struct device_attribute rfkill_dev_attrs[] = {
	__ATTR(name, S_IRUGO, rfkill_name_show, NULL),
	__ATTR(type, S_IRUGO, rfkill_type_show, NULL),
	__ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store),
	__ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store),
	__ATTR_NULL
};

static void rfkill_release(struct device *dev)
{
	struct rfkill *rfkill = to_rfkill(dev);

	kfree(rfkill);
	module_put(THIS_MODULE);
}

#ifdef CONFIG_PM
static int rfkill_suspend(struct device *dev, pm_message_t state)
{
	struct rfkill *rfkill = to_rfkill(dev);

	/* mark class device as suspended */
	if (dev->power.power_state.event != state.event)
		dev->power.power_state = state;

	/* store state for the resume handler */
	rfkill->state_for_resume = rfkill->state;

	return 0;
}

static int rfkill_resume(struct device *dev)
{
	struct rfkill *rfkill = to_rfkill(dev);
	enum rfkill_state newstate;

	if (dev->power.power_state.event != PM_EVENT_ON) {
		mutex_lock(&rfkill->mutex);

		dev->power.power_state.event = PM_EVENT_ON;

		/*
		 * rfkill->state could have been modified before we got
		 * called, and won't be updated by rfkill_toggle_radio()
		 * in force mode.  Sync it FIRST.
		 */
		if (rfkill->get_state &&
		    !rfkill->get_state(rfkill->data, &newstate))
			rfkill->state = newstate;

		/*
		 * If we are under EPO, kick transmitter offline,
		 * otherwise restore to pre-suspend state.
		 *
		 * Issue a notification in any case
		 */
		rfkill_toggle_radio(rfkill,
				rfkill_epo_lock_active ?
					RFKILL_STATE_SOFT_BLOCKED :
					rfkill->state_for_resume,
				1);

		mutex_unlock(&rfkill->mutex);
	}

	return 0;
}
#else
#define rfkill_suspend NULL
#define rfkill_resume NULL
#endif

static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
	struct rfkill *rfkill = to_rfkill(dev);
	int error;

	error = add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name);
	if (error)
		return error;
	error = add_uevent_var(env, "RFKILL_TYPE=%s",
				rfkill_get_type_str(rfkill->type));
	if (error)
		return error;
	error = add_uevent_var(env, "RFKILL_STATE=%d", rfkill->state);
	return error;
}

static struct class rfkill_class = {
	.name		= "rfkill",
	.dev_release	= rfkill_release,
	.dev_attrs	= rfkill_dev_attrs,
	.suspend	= rfkill_suspend,
	.resume		= rfkill_resume,
	.dev_uevent	= rfkill_dev_uevent,
};

static int rfkill_check_duplicity(const struct rfkill *rfkill)
{
	struct rfkill *p;
	unsigned long seen[BITS_TO_LONGS(RFKILL_TYPE_MAX)];

	memset(seen, 0, sizeof(seen));

	list_for_each_entry(p, &rfkill_list, node) {
		if (WARN((p == rfkill), KERN_WARNING
				"rfkill: illegal attempt to register "
				"an already registered rfkill struct\n"))
			return -EEXIST;
		set_bit(p->type, seen);
	}

	/* 0: first switch of its kind */
	return (test_bit(rfkill->type, seen)) ? 1 : 0;
}

static int rfkill_add_switch(struct rfkill *rfkill)
{
	int error;

	mutex_lock(&rfkill_global_mutex);

	error = rfkill_check_duplicity(rfkill);
	if (error < 0)
		goto unlock_out;

	if (!error) {
		/* lock default after first use */
		set_bit(rfkill->type, rfkill_states_lockdflt);
		rfkill_global_states[rfkill->type].current_state =
			rfkill_global_states[rfkill->type].default_state;
	}

	rfkill_toggle_radio(rfkill,
			    rfkill_global_states[rfkill->type].current_state,
			    0);

	list_add_tail(&rfkill->node, &rfkill_list);

	error = 0;
unlock_out:
	mutex_unlock(&rfkill_global_mutex);

	return error;
}

static void rfkill_remove_switch(struct rfkill *rfkill)
{
	mutex_lock(&rfkill_global_mutex);
	list_del_init(&rfkill->node);
	mutex_unlock(&rfkill_global_mutex);

	mutex_lock(&rfkill->mutex);
	rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
	mutex_unlock(&rfkill->mutex);
}

/**
 * rfkill_allocate - allocate memory for rfkill structure.
 * @parent: device that has rf switch on it
 * @type: type of the switch (RFKILL_TYPE_*)
 *
 * This function should be called by the network driver when it needs
 * rfkill structure.  Once the structure is allocated the driver should
 * finish its initialization by setting the name, private data, enable_radio
 * and disable_radio methods and then register it with rfkill_register().
 *
 * NOTE: If registration fails the structure shoudl be freed by calling
 * rfkill_free() otherwise rfkill_unregister() should be used.
 */
struct rfkill * __must_check rfkill_allocate(struct device *parent,
					     enum rfkill_type type)
{
	struct rfkill *rfkill;
	struct device *dev;

	if (WARN((type >= RFKILL_TYPE_MAX),
			KERN_WARNING
			"rfkill: illegal type %d passed as parameter "
			"to rfkill_allocate\n", type))
		return NULL;

	rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL);
	if (!rfkill)
		return NULL;

	mutex_init(&rfkill->mutex);
	INIT_LIST_HEAD(&rfkill->node);
	rfkill->type = type;

	dev = &rfkill->dev;
	dev->class = &rfkill_class;
	dev->parent = parent;
	device_initialize(dev);

	__module_get(THIS_MODULE);

	return rfkill;
}
EXPORT_SYMBOL(rfkill_allocate);

/**
 * rfkill_free - Mark rfkill structure for deletion
 * @rfkill: rfkill structure to be destroyed
 *
 * Decrements reference count of the rfkill structure so it is destroyed.
 * Note that rfkill_free() should _not_ be called after rfkill_unregister().
 */
void rfkill_free(struct rfkill *rfkill)
{
	if (rfkill)
		put_device(&rfkill->dev);
}
EXPORT_SYMBOL(rfkill_free);

static void rfkill_led_trigger_register(struct rfkill *rfkill)
{
#ifdef CONFIG_RFKILL_LEDS
	int error;

	if (!rfkill->led_trigger.name)
		rfkill->led_trigger.name = dev_name(&rfkill->dev);
	if (!rfkill->led_trigger.activate)
		rfkill->led_trigger.activate = rfkill_led_trigger_activate;
	error = led_trigger_register(&rfkill->led_trigger);
	if (error)
		rfkill->led_trigger.name = NULL;
#endif /* CONFIG_RFKILL_LEDS */
}

static void rfkill_led_trigger_unregister(struct rfkill *rfkill)
{
#ifdef CONFIG_RFKILL_LEDS
	if (rfkill->led_trigger.name) {
		led_trigger_unregister(&rfkill->led_trigger);
		rfkill->led_trigger.name = NULL;
	}
#endif
}

/**
 * rfkill_register - Register a rfkill structure.
 * @rfkill: rfkill structure to be registered
 *
 * This function should be called by the network driver when the rfkill
 * structure needs to be registered. Immediately from registration the
 * switch driver should be able to service calls to toggle_radio.
 */
int __must_check rfkill_register(struct rfkill *rfkill)
{
	static atomic_t rfkill_no = ATOMIC_INIT(0);
	struct device *dev = &rfkill->dev;
	int error;

	if (WARN((!rfkill || !rfkill->toggle_radio ||
			rfkill->type >= RFKILL_TYPE_MAX ||
			rfkill->state >= RFKILL_STATE_MAX),
			KERN_WARNING
			"rfkill: attempt to register a "
			"badly initialized rfkill struct\n"))
		return -EINVAL;

	dev_set_name(dev, "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1);

	rfkill_led_trigger_register(rfkill);

	error = rfkill_add_switch(rfkill);
	if (error) {
		rfkill_led_trigger_unregister(rfkill);
		return error;
	}

	error = device_add(dev);
	if (error) {
		rfkill_remove_switch(rfkill);
		rfkill_led_trigger_unregister(rfkill);
		return error;
	}

	return 0;
}
EXPORT_SYMBOL(rfkill_register);

/**
 * rfkill_unregister - Unregister a rfkill structure.
 * @rfkill: rfkill structure to be unregistered
 *
 * This function should be called by the network driver during device
 * teardown to destroy rfkill structure. Note that rfkill_free() should
 * _not_ be called after rfkill_unregister().
 */
void rfkill_unregister(struct rfkill *rfkill)
{
	BUG_ON(!rfkill);
	device_del(&rfkill->dev);
	rfkill_remove_switch(rfkill);
	rfkill_led_trigger_unregister(rfkill);
	put_device(&rfkill->dev);
}
EXPORT_SYMBOL(rfkill_unregister);

/**
 * rfkill_set_default - set initial value for a switch type
 * @type - the type of switch to set the default state of
 * @state - the new default state for that group of switches
 *
 * Sets the initial state rfkill should use for a given type.
 * The following initial states are allowed: RFKILL_STATE_SOFT_BLOCKED
 * and RFKILL_STATE_UNBLOCKED.
 *
 * This function is meant to be used by platform drivers for platforms
 * that can save switch state across power down/reboot.
 *
 * The default state for each switch type can be changed exactly once.
 * After a switch of that type is registered, the default state cannot
 * be changed anymore.  This guards against multiple drivers it the
 * same platform trying to set the initial switch default state, which
 * is not allowed.
 *
 * Returns -EPERM if the state has already been set once or is in use,
 * so drivers likely want to either ignore or at most printk(KERN_NOTICE)
 * if this function returns -EPERM.
 *
 * Returns 0 if the new default state was set, or an error if it
 * could not be set.
 */
int rfkill_set_default(enum rfkill_type type, enum rfkill_state state)
{
	int error;

	if (WARN((type >= RFKILL_TYPE_MAX ||
			(state != RFKILL_STATE_SOFT_BLOCKED &&
			 state != RFKILL_STATE_UNBLOCKED)),
			KERN_WARNING
			"rfkill: illegal state %d or type %d passed as "
			"parameter to rfkill_set_default\n", state, type))
		return -EINVAL;

	mutex_lock(&rfkill_global_mutex);

	if (!test_and_set_bit(type, rfkill_states_lockdflt)) {
		rfkill_global_states[type].default_state = state;
		rfkill_global_states[type].current_state = state;
		error = 0;
	} else
		error = -EPERM;

	mutex_unlock(&rfkill_global_mutex);
	return error;
}
EXPORT_SYMBOL_GPL(rfkill_set_default);

/*
 * Rfkill module initialization/deinitialization.
 */
static int __init rfkill_init(void)
{
	int error;
	int i;

	/* RFKILL_STATE_HARD_BLOCKED is illegal here... */
	if (rfkill_default_state != RFKILL_STATE_SOFT_BLOCKED &&
	    rfkill_default_state != RFKILL_STATE_UNBLOCKED)
		return -EINVAL;

	for (i = 0; i < RFKILL_TYPE_MAX; i++)
		rfkill_global_states[i].default_state = rfkill_default_state;

	error = class_register(&rfkill_class);
	if (error) {
		printk(KERN_ERR "rfkill: unable to register rfkill class\n");
		return error;
	}

	return 0;
}

static void __exit rfkill_exit(void)
{
	class_unregister(&rfkill_class);
}

subsys_initcall(rfkill_init);
module_exit(rfkill_exit);
