+ struct rfkill_task *task =
+ container_of(work, struct rfkill_task, work);
+ bool doit = true;
+
+ mutex_lock(&task->mutex);
+
+ spin_lock_irq(&task->lock);
+ while (doit) {
+ if (task->global_op_pending) {
+ enum rfkill_global_sched_op op = task->op;
+ task->global_op_pending = false;
+ memset(task->sw_pending, 0, sizeof(task->sw_pending));
+ spin_unlock_irq(&task->lock);
+
+ __rfkill_handle_global_op(op);
+
+ /* make sure we do at least one pass with
+ * !task->global_op_pending */
+ spin_lock_irq(&task->lock);
+ continue;
+ } else if (!rfkill_is_epo_lock_active()) {
+ unsigned int i = 0;
+
+ while (!task->global_op_pending &&
+ i < RFKILL_TYPE_MAX) {
+ if (test_and_clear_bit(i, task->sw_pending)) {
+ bool c;
+#ifdef RFKILL_NEED_SWSET
+ bool sp, s;
+ sp = test_and_clear_bit(i,
+ task->sw_setpending);
+ s = test_bit(i, task->sw_newstate);
+#endif
+ c = test_and_clear_bit(i,
+ task->sw_togglestate);
+ spin_unlock_irq(&task->lock);
+
+#ifdef RFKILL_NEED_SWSET
+ __rfkill_handle_normal_op(i, sp, s, c);
+#else
+ __rfkill_handle_normal_op(i, c);
+#endif
+
+ spin_lock_irq(&task->lock);
+ }
+ i++;
+ }
+ }
+ doit = task->global_op_pending;
+ }
+ spin_unlock_irq(&task->lock);
+
+ mutex_unlock(&task->mutex);