aboutsummaryrefslogtreecommitdiffstats
path: root/net/rfkill/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rfkill/core.c')
-rw-r--r--net/rfkill/core.c93
1 files changed, 35 insertions, 58 deletions
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 11b7314723df..4e68ab439d5d 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -57,6 +57,7 @@ struct rfkill {
57 57
58 bool registered; 58 bool registered;
59 bool suspended; 59 bool suspended;
60 bool persistent;
60 61
61 const struct rfkill_ops *ops; 62 const struct rfkill_ops *ops;
62 void *data; 63 void *data;
@@ -116,11 +117,9 @@ MODULE_PARM_DESC(default_state,
116 "Default initial state for all radio types, 0 = radio off"); 117 "Default initial state for all radio types, 0 = radio off");
117 118
118static struct { 119static struct {
119 bool cur, def; 120 bool cur, sav;
120} rfkill_global_states[NUM_RFKILL_TYPES]; 121} rfkill_global_states[NUM_RFKILL_TYPES];
121 122
122static unsigned long rfkill_states_default_locked;
123
124static bool rfkill_epo_lock_active; 123static bool rfkill_epo_lock_active;
125 124
126 125
@@ -392,7 +391,7 @@ void rfkill_epo(void)
392 rfkill_set_block(rfkill, true); 391 rfkill_set_block(rfkill, true);
393 392
394 for (i = 0; i < NUM_RFKILL_TYPES; i++) { 393 for (i = 0; i < NUM_RFKILL_TYPES; i++) {
395 rfkill_global_states[i].def = rfkill_global_states[i].cur; 394 rfkill_global_states[i].sav = rfkill_global_states[i].cur;
396 rfkill_global_states[i].cur = true; 395 rfkill_global_states[i].cur = true;
397 } 396 }
398 397
@@ -417,7 +416,7 @@ void rfkill_restore_states(void)
417 416
418 rfkill_epo_lock_active = false; 417 rfkill_epo_lock_active = false;
419 for (i = 0; i < NUM_RFKILL_TYPES; i++) 418 for (i = 0; i < NUM_RFKILL_TYPES; i++)
420 __rfkill_switch_all(i, rfkill_global_states[i].def); 419 __rfkill_switch_all(i, rfkill_global_states[i].sav);
421 mutex_unlock(&rfkill_global_mutex); 420 mutex_unlock(&rfkill_global_mutex);
422} 421}
423 422
@@ -464,29 +463,6 @@ bool rfkill_get_global_sw_state(const enum rfkill_type type)
464} 463}
465#endif 464#endif
466 465
467void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked)
468{
469 BUG_ON(type == RFKILL_TYPE_ALL);
470
471 mutex_lock(&rfkill_global_mutex);
472
473 /* don't allow unblock when epo */
474 if (rfkill_epo_lock_active && !blocked)
475 goto out;
476
477 /* too late */
478 if (rfkill_states_default_locked & BIT(type))
479 goto out;
480
481 rfkill_states_default_locked |= BIT(type);
482
483 rfkill_global_states[type].cur = blocked;
484 rfkill_global_states[type].def = blocked;
485 out:
486 mutex_unlock(&rfkill_global_mutex);
487}
488EXPORT_SYMBOL(rfkill_set_global_sw_state);
489
490 466
491bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) 467bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
492{ 468{
@@ -532,13 +508,14 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)
532 blocked = blocked || hwblock; 508 blocked = blocked || hwblock;
533 spin_unlock_irqrestore(&rfkill->lock, flags); 509 spin_unlock_irqrestore(&rfkill->lock, flags);
534 510
535 if (!rfkill->registered) 511 if (!rfkill->registered) {
536 return blocked; 512 rfkill->persistent = true;
537 513 } else {
538 if (prev != blocked && !hwblock) 514 if (prev != blocked && !hwblock)
539 schedule_work(&rfkill->uevent_work); 515 schedule_work(&rfkill->uevent_work);
540 516
541 rfkill_led_trigger_event(rfkill); 517 rfkill_led_trigger_event(rfkill);
518 }
542 519
543 return blocked; 520 return blocked;
544} 521}
@@ -563,13 +540,14 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)
563 540
564 spin_unlock_irqrestore(&rfkill->lock, flags); 541 spin_unlock_irqrestore(&rfkill->lock, flags);
565 542
566 if (!rfkill->registered) 543 if (!rfkill->registered) {
567 return; 544 rfkill->persistent = true;
568 545 } else {
569 if (swprev != sw || hwprev != hw) 546 if (swprev != sw || hwprev != hw)
570 schedule_work(&rfkill->uevent_work); 547 schedule_work(&rfkill->uevent_work);
571 548
572 rfkill_led_trigger_event(rfkill); 549 rfkill_led_trigger_event(rfkill);
550 }
573} 551}
574EXPORT_SYMBOL(rfkill_set_states); 552EXPORT_SYMBOL(rfkill_set_states);
575 553
@@ -750,15 +728,11 @@ static int rfkill_resume(struct device *dev)
750 struct rfkill *rfkill = to_rfkill(dev); 728 struct rfkill *rfkill = to_rfkill(dev);
751 bool cur; 729 bool cur;
752 730
753 mutex_lock(&rfkill_global_mutex); 731 cur = !!(rfkill->state & RFKILL_BLOCK_SW);
754 cur = rfkill_global_states[rfkill->type].cur;
755 rfkill_set_block(rfkill, cur); 732 rfkill_set_block(rfkill, cur);
756 mutex_unlock(&rfkill_global_mutex);
757 733
758 rfkill->suspended = false; 734 rfkill->suspended = false;
759 735
760 schedule_work(&rfkill->uevent_work);
761
762 rfkill_resume_polling(rfkill); 736 rfkill_resume_polling(rfkill);
763 737
764 return 0; 738 return 0;
@@ -888,15 +862,6 @@ int __must_check rfkill_register(struct rfkill *rfkill)
888 dev_set_name(dev, "rfkill%lu", rfkill_no); 862 dev_set_name(dev, "rfkill%lu", rfkill_no);
889 rfkill_no++; 863 rfkill_no++;
890 864
891 if (!(rfkill_states_default_locked & BIT(rfkill->type))) {
892 /* first of its kind */
893 BUILD_BUG_ON(NUM_RFKILL_TYPES >
894 sizeof(rfkill_states_default_locked) * 8);
895 rfkill_states_default_locked |= BIT(rfkill->type);
896 rfkill_global_states[rfkill->type].cur =
897 rfkill_global_states[rfkill->type].def;
898 }
899
900 list_add_tail(&rfkill->node, &rfkill_list); 865 list_add_tail(&rfkill->node, &rfkill_list);
901 866
902 error = device_add(dev); 867 error = device_add(dev);
@@ -916,7 +881,17 @@ int __must_check rfkill_register(struct rfkill *rfkill)
916 if (rfkill->ops->poll) 881 if (rfkill->ops->poll)
917 schedule_delayed_work(&rfkill->poll_work, 882 schedule_delayed_work(&rfkill->poll_work,
918 round_jiffies_relative(POLL_INTERVAL)); 883 round_jiffies_relative(POLL_INTERVAL));
919 schedule_work(&rfkill->sync_work); 884
885 if (!rfkill->persistent || rfkill_epo_lock_active) {
886 schedule_work(&rfkill->sync_work);
887 } else {
888#ifdef CONFIG_RFKILL_INPUT
889 bool soft_blocked = !!(rfkill->state & RFKILL_BLOCK_SW);
890
891 if (!atomic_read(&rfkill_input_disabled))
892 __rfkill_switch_all(rfkill->type, soft_blocked);
893#endif
894 }
920 895
921 rfkill_send_events(rfkill, RFKILL_OP_ADD); 896 rfkill_send_events(rfkill, RFKILL_OP_ADD);
922 897
@@ -1134,7 +1109,8 @@ static int rfkill_fop_release(struct inode *inode, struct file *file)
1134 1109
1135#ifdef CONFIG_RFKILL_INPUT 1110#ifdef CONFIG_RFKILL_INPUT
1136 if (data->input_handler) 1111 if (data->input_handler)
1137 atomic_dec(&rfkill_input_disabled); 1112 if (atomic_dec_return(&rfkill_input_disabled) == 0)
1113 printk(KERN_DEBUG "rfkill: input handler enabled\n");
1138#endif 1114#endif
1139 1115
1140 kfree(data); 1116 kfree(data);
@@ -1157,7 +1133,8 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd,
1157 mutex_lock(&data->mtx); 1133 mutex_lock(&data->mtx);
1158 1134
1159 if (!data->input_handler) { 1135 if (!data->input_handler) {
1160 atomic_inc(&rfkill_input_disabled); 1136 if (atomic_inc_return(&rfkill_input_disabled) == 1)
1137 printk(KERN_DEBUG "rfkill: input handler disabled\n");
1161 data->input_handler = true; 1138 data->input_handler = true;
1162 } 1139 }
1163 1140
@@ -1191,7 +1168,7 @@ static int __init rfkill_init(void)
1191 int i; 1168 int i;
1192 1169
1193 for (i = 0; i < NUM_RFKILL_TYPES; i++) 1170 for (i = 0; i < NUM_RFKILL_TYPES; i++)
1194 rfkill_global_states[i].def = !rfkill_default_state; 1171 rfkill_global_states[i].cur = !rfkill_default_state;
1195 1172
1196 error = class_register(&rfkill_class); 1173 error = class_register(&rfkill_class);
1197 if (error) 1174 if (error)