diff options
Diffstat (limited to 'net/rfkill')
| -rw-r--r-- | net/rfkill/Kconfig | 2 | ||||
| -rw-r--r-- | net/rfkill/core.c | 93 | 
2 files changed, 36 insertions, 59 deletions
| diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig index fd7600d8ab1..eaf76587645 100644 --- a/net/rfkill/Kconfig +++ b/net/rfkill/Kconfig @@ -18,7 +18,7 @@ config RFKILL_LEDS  	default y  config RFKILL_INPUT -	bool "RF switch input support" +	bool "RF switch input support" if EMBEDDED  	depends on RFKILL  	depends on INPUT = y || RFKILL = INPUT  	default y if !EMBEDDED diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 11b7314723d..4e68ab439d5 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c @@ -57,6 +57,7 @@ struct rfkill {  	bool			registered;  	bool			suspended; +	bool			persistent;  	const struct rfkill_ops	*ops;  	void			*data; @@ -116,11 +117,9 @@ MODULE_PARM_DESC(default_state,  		 "Default initial state for all radio types, 0 = radio off");  static struct { -	bool cur, def; +	bool cur, sav;  } rfkill_global_states[NUM_RFKILL_TYPES]; -static unsigned long rfkill_states_default_locked; -  static bool rfkill_epo_lock_active; @@ -392,7 +391,7 @@ void rfkill_epo(void)  		rfkill_set_block(rfkill, true);  	for (i = 0; i < NUM_RFKILL_TYPES; i++) { -		rfkill_global_states[i].def = rfkill_global_states[i].cur; +		rfkill_global_states[i].sav = rfkill_global_states[i].cur;  		rfkill_global_states[i].cur = true;  	} @@ -417,7 +416,7 @@ void rfkill_restore_states(void)  	rfkill_epo_lock_active = false;  	for (i = 0; i < NUM_RFKILL_TYPES; i++) -		__rfkill_switch_all(i, rfkill_global_states[i].def); +		__rfkill_switch_all(i, rfkill_global_states[i].sav);  	mutex_unlock(&rfkill_global_mutex);  } @@ -464,29 +463,6 @@ bool rfkill_get_global_sw_state(const enum rfkill_type type)  }  #endif -void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked) -{ -	BUG_ON(type == RFKILL_TYPE_ALL); - -	mutex_lock(&rfkill_global_mutex); - -	/* don't allow unblock when epo */ -	if (rfkill_epo_lock_active && !blocked) -		goto out; - -	/* too late */ -	if (rfkill_states_default_locked & BIT(type)) -		goto out; - -	rfkill_states_default_locked |= BIT(type); - -	rfkill_global_states[type].cur = blocked; -	rfkill_global_states[type].def = blocked; - out: -	mutex_unlock(&rfkill_global_mutex); -} -EXPORT_SYMBOL(rfkill_set_global_sw_state); -  bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)  { @@ -532,13 +508,14 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)  	blocked = blocked || hwblock;  	spin_unlock_irqrestore(&rfkill->lock, flags); -	if (!rfkill->registered) -		return blocked; - -	if (prev != blocked && !hwblock) -		schedule_work(&rfkill->uevent_work); +	if (!rfkill->registered) { +		rfkill->persistent = true; +	} else { +		if (prev != blocked && !hwblock) +			schedule_work(&rfkill->uevent_work); -	rfkill_led_trigger_event(rfkill); +		rfkill_led_trigger_event(rfkill); +	}  	return blocked;  } @@ -563,13 +540,14 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)  	spin_unlock_irqrestore(&rfkill->lock, flags); -	if (!rfkill->registered) -		return; - -	if (swprev != sw || hwprev != hw) -		schedule_work(&rfkill->uevent_work); +	if (!rfkill->registered) { +		rfkill->persistent = true; +	} else { +		if (swprev != sw || hwprev != hw) +			schedule_work(&rfkill->uevent_work); -	rfkill_led_trigger_event(rfkill); +		rfkill_led_trigger_event(rfkill); +	}  }  EXPORT_SYMBOL(rfkill_set_states); @@ -750,15 +728,11 @@ static int rfkill_resume(struct device *dev)  	struct rfkill *rfkill = to_rfkill(dev);  	bool cur; -	mutex_lock(&rfkill_global_mutex); -	cur = rfkill_global_states[rfkill->type].cur; +	cur = !!(rfkill->state & RFKILL_BLOCK_SW);  	rfkill_set_block(rfkill, cur); -	mutex_unlock(&rfkill_global_mutex);  	rfkill->suspended = false; -	schedule_work(&rfkill->uevent_work); -  	rfkill_resume_polling(rfkill);  	return 0; @@ -888,15 +862,6 @@ int __must_check rfkill_register(struct rfkill *rfkill)  	dev_set_name(dev, "rfkill%lu", rfkill_no);  	rfkill_no++; -	if (!(rfkill_states_default_locked & BIT(rfkill->type))) { -		/* first of its kind */ -		BUILD_BUG_ON(NUM_RFKILL_TYPES > -			sizeof(rfkill_states_default_locked) * 8); -		rfkill_states_default_locked |= BIT(rfkill->type); -		rfkill_global_states[rfkill->type].cur = -			rfkill_global_states[rfkill->type].def; -	} -  	list_add_tail(&rfkill->node, &rfkill_list);  	error = device_add(dev); @@ -916,7 +881,17 @@ int __must_check rfkill_register(struct rfkill *rfkill)  	if (rfkill->ops->poll)  		schedule_delayed_work(&rfkill->poll_work,  			round_jiffies_relative(POLL_INTERVAL)); -	schedule_work(&rfkill->sync_work); + +	if (!rfkill->persistent || rfkill_epo_lock_active) { +		schedule_work(&rfkill->sync_work); +	} else { +#ifdef CONFIG_RFKILL_INPUT +		bool soft_blocked = !!(rfkill->state & RFKILL_BLOCK_SW); + +		if (!atomic_read(&rfkill_input_disabled)) +			__rfkill_switch_all(rfkill->type, soft_blocked); +#endif +	}  	rfkill_send_events(rfkill, RFKILL_OP_ADD); @@ -1134,7 +1109,8 @@ static int rfkill_fop_release(struct inode *inode, struct file *file)  #ifdef CONFIG_RFKILL_INPUT  	if (data->input_handler) -		atomic_dec(&rfkill_input_disabled); +		if (atomic_dec_return(&rfkill_input_disabled) == 0) +			printk(KERN_DEBUG "rfkill: input handler enabled\n");  #endif  	kfree(data); @@ -1157,7 +1133,8 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd,  	mutex_lock(&data->mtx);  	if (!data->input_handler) { -		atomic_inc(&rfkill_input_disabled); +		if (atomic_inc_return(&rfkill_input_disabled) == 1) +			printk(KERN_DEBUG "rfkill: input handler disabled\n");  		data->input_handler = true;  	} @@ -1191,7 +1168,7 @@ static int __init rfkill_init(void)  	int i;  	for (i = 0; i < NUM_RFKILL_TYPES; i++) -		rfkill_global_states[i].def = !rfkill_default_state; +		rfkill_global_states[i].cur = !rfkill_default_state;  	error = class_register(&rfkill_class);  	if (error) | 
