aboutsummaryrefslogtreecommitdiffstats
path: root/net/rfkill
diff options
context:
space:
mode:
Diffstat (limited to 'net/rfkill')
-rw-r--r--net/rfkill/core.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 4e68ab439d5d..79693fe2001e 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);
@@ -270,6 +269,9 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked)
270 unsigned long flags; 269 unsigned long flags;
271 int err; 270 int err;
272 271
272 if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP))
273 return;
274
273 /* 275 /*
274 * Some platforms (...!) generate input events which affect the 276 * Some platforms (...!) generate input events which affect the
275 * _hard_ kill state -- whenever something tries to change the 277 * _hard_ kill state -- whenever something tries to change the
@@ -292,9 +294,6 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked)
292 rfkill->state |= RFKILL_BLOCK_SW_SETCALL; 294 rfkill->state |= RFKILL_BLOCK_SW_SETCALL;
293 spin_unlock_irqrestore(&rfkill->lock, flags); 295 spin_unlock_irqrestore(&rfkill->lock, flags);
294 296
295 if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP))
296 return;
297
298 err = rfkill->ops->set_block(rfkill->data, blocked); 297 err = rfkill->ops->set_block(rfkill->data, blocked);
299 298
300 spin_lock_irqsave(&rfkill->lock, flags); 299 spin_lock_irqsave(&rfkill->lock, flags);
@@ -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;
@@ -598,6 +610,15 @@ static ssize_t rfkill_idx_show(struct device *dev,
598 return sprintf(buf, "%d\n", rfkill->idx); 610 return sprintf(buf, "%d\n", rfkill->idx);
599} 611}
600 612
613static ssize_t rfkill_persistent_show(struct device *dev,
614 struct device_attribute *attr,
615 char *buf)
616{
617 struct rfkill *rfkill = to_rfkill(dev);
618
619 return sprintf(buf, "%d\n", rfkill->persistent);
620}
621
601static u8 user_state_from_blocked(unsigned long state) 622static u8 user_state_from_blocked(unsigned long state)
602{ 623{
603 if (state & RFKILL_BLOCK_HW) 624 if (state & RFKILL_BLOCK_HW)
@@ -656,6 +677,7 @@ static struct device_attribute rfkill_dev_attrs[] = {
656 __ATTR(name, S_IRUGO, rfkill_name_show, NULL), 677 __ATTR(name, S_IRUGO, rfkill_name_show, NULL),
657 __ATTR(type, S_IRUGO, rfkill_type_show, NULL), 678 __ATTR(type, S_IRUGO, rfkill_type_show, NULL),
658 __ATTR(index, S_IRUGO, rfkill_idx_show, NULL), 679 __ATTR(index, S_IRUGO, rfkill_idx_show, NULL),
680 __ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL),
659 __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store), 681 __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store),
660 __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store), 682 __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store),
661 __ATTR_NULL 683 __ATTR_NULL
@@ -718,8 +740,6 @@ static int rfkill_suspend(struct device *dev, pm_message_t state)
718 740
719 rfkill_pause_polling(rfkill); 741 rfkill_pause_polling(rfkill);
720 742
721 rfkill->suspended = true;
722
723 return 0; 743 return 0;
724} 744}
725 745
@@ -728,10 +748,10 @@ static int rfkill_resume(struct device *dev)
728 struct rfkill *rfkill = to_rfkill(dev); 748 struct rfkill *rfkill = to_rfkill(dev);
729 bool cur; 749 bool cur;
730 750
731 cur = !!(rfkill->state & RFKILL_BLOCK_SW); 751 if (!rfkill->persistent) {
732 rfkill_set_block(rfkill, cur); 752 cur = !!(rfkill->state & RFKILL_BLOCK_SW);
733 753 rfkill_set_block(rfkill, cur);
734 rfkill->suspended = false; 754 }
735 755
736 rfkill_resume_polling(rfkill); 756 rfkill_resume_polling(rfkill);
737 757