aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAlan Jenkins <alan-jenkins@tuffmail.co.uk>2009-06-16 10:39:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-06-19 11:50:17 -0400
commit06d5caf47ef4fbd9efdceae33293c42778cb7b0c (patch)
tree51bce5f2f9f7aef903c464ac68c80da6f83e2c53 /net
parent7fa20a7f60df0afceafbb8197b5d110507f42c72 (diff)
rfkill: don't restore software blocked state on persistent devices
The setting of the "persistent" flag is also made more explicit using a new rfkill_init_sw_state() function, instead of special-casing rfkill_set_sw_state() when it is called before registration. Suspend is a bit of a corner case so we try to get away without adding another hack to rfkill-input - it's going to be removed soon. If the state does change over suspend, users will simply have to prod rfkill-input twice in order to toggle the state. Userspace policy agents will be able to implement a more consistent user experience. For example, they can avoid the above problem if they toggle devices individually. Then there would be no "global state" to get out of sync. Currently there are only two rfkill drivers with persistent soft-blocked state. thinkpad-acpi already checks the software state on resume. eeepc-laptop will require modification. Signed-off-by: Alan Jenkins <alan-jenkins@tuffmail.co.uk> CC: Marcel Holtmann <marcel@holtmann.org> Acked-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/rfkill/core.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 868d79f8ac1d..dcf8df7c573c 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -56,7 +56,6 @@ struct rfkill {
56 u32 idx; 56 u32 idx;
57 57
58 bool registered; 58 bool registered;
59 bool suspended;
60 bool persistent; 59 bool persistent;
61 60
62 const struct rfkill_ops *ops; 61 const struct rfkill_ops *ops;
@@ -224,7 +223,7 @@ static void rfkill_send_events(struct rfkill *rfkill, enum rfkill_operation op)
224 223
225static void rfkill_event(struct rfkill *rfkill) 224static void rfkill_event(struct rfkill *rfkill)
226{ 225{
227 if (!rfkill->registered || rfkill->suspended) 226 if (!rfkill->registered)
228 return; 227 return;
229 228
230 kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE); 229 kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);
@@ -508,19 +507,32 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)
508 blocked = blocked || hwblock; 507 blocked = blocked || hwblock;
509 spin_unlock_irqrestore(&rfkill->lock, flags); 508 spin_unlock_irqrestore(&rfkill->lock, flags);
510 509
511 if (!rfkill->registered) { 510 if (!rfkill->registered)
512 rfkill->persistent = true; 511 return blocked;
513 } else {
514 if (prev != blocked && !hwblock)
515 schedule_work(&rfkill->uevent_work);
516 512
517 rfkill_led_trigger_event(rfkill); 513 if (prev != blocked && !hwblock)
518 } 514 schedule_work(&rfkill->uevent_work);
515
516 rfkill_led_trigger_event(rfkill);
519 517
520 return blocked; 518 return blocked;
521} 519}
522EXPORT_SYMBOL(rfkill_set_sw_state); 520EXPORT_SYMBOL(rfkill_set_sw_state);
523 521
522void rfkill_init_sw_state(struct rfkill *rfkill, bool blocked)
523{
524 unsigned long flags;
525
526 BUG_ON(!rfkill);
527 BUG_ON(rfkill->registered);
528
529 spin_lock_irqsave(&rfkill->lock, flags);
530 __rfkill_set_sw_state(rfkill, blocked);
531 rfkill->persistent = true;
532 spin_unlock_irqrestore(&rfkill->lock, flags);
533}
534EXPORT_SYMBOL(rfkill_init_sw_state);
535
524void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) 536void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)
525{ 537{
526 unsigned long flags; 538 unsigned long flags;
@@ -718,8 +730,6 @@ static int rfkill_suspend(struct device *dev, pm_message_t state)
718 730
719 rfkill_pause_polling(rfkill); 731 rfkill_pause_polling(rfkill);
720 732
721 rfkill->suspended = true;
722
723 return 0; 733 return 0;
724} 734}
725 735
@@ -728,10 +738,10 @@ static int rfkill_resume(struct device *dev)
728 struct rfkill *rfkill = to_rfkill(dev); 738 struct rfkill *rfkill = to_rfkill(dev);
729 bool cur; 739 bool cur;
730 740
731 cur = !!(rfkill->state & RFKILL_BLOCK_SW); 741 if (!rfkill->persistent) {
732 rfkill_set_block(rfkill, cur); 742 cur = !!(rfkill->state & RFKILL_BLOCK_SW);
733 743 rfkill_set_block(rfkill, cur);
734 rfkill->suspended = false; 744 }
735 745
736 rfkill_resume_polling(rfkill); 746 rfkill_resume_polling(rfkill);
737 747