]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/rfkill/rfkill-input.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[linux-2.6-omap-h63xx.git] / net / rfkill / rfkill-input.c
index 8aa82273014516a14a8184bd44cdcdff70f972af..e5b69556bb5b270f5d0b1250d5c01825ba27ea43 100644 (file)
@@ -109,6 +109,25 @@ static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB);
 static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
 static DEFINE_RFKILL_TASK(rfkill_wwan, RFKILL_TYPE_WWAN);
 
+static void rfkill_schedule_evsw_rfkillall(int state)
+{
+       /* EVERY radio type. state != 0 means radios ON */
+       /* handle EPO (emergency power off) through shortcut */
+       if (state) {
+               rfkill_schedule_set(&rfkill_wwan,
+                                   RFKILL_STATE_UNBLOCKED);
+               rfkill_schedule_set(&rfkill_wimax,
+                                   RFKILL_STATE_UNBLOCKED);
+               rfkill_schedule_set(&rfkill_uwb,
+                                   RFKILL_STATE_UNBLOCKED);
+               rfkill_schedule_set(&rfkill_bt,
+                                   RFKILL_STATE_UNBLOCKED);
+               rfkill_schedule_set(&rfkill_wlan,
+                                   RFKILL_STATE_UNBLOCKED);
+       } else
+               rfkill_schedule_epo();
+}
+
 static void rfkill_event(struct input_handle *handle, unsigned int type,
                        unsigned int code, int data)
 {
@@ -132,21 +151,7 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
        } else if (type == EV_SW) {
                switch (code) {
                case SW_RFKILL_ALL:
-                       /* EVERY radio type. data != 0 means radios ON */
-                       /* handle EPO (emergency power off) through shortcut */
-                       if (data) {
-                               rfkill_schedule_set(&rfkill_wwan,
-                                                   RFKILL_STATE_UNBLOCKED);
-                               rfkill_schedule_set(&rfkill_wimax,
-                                                   RFKILL_STATE_UNBLOCKED);
-                               rfkill_schedule_set(&rfkill_uwb,
-                                                   RFKILL_STATE_UNBLOCKED);
-                               rfkill_schedule_set(&rfkill_bt,
-                                                   RFKILL_STATE_UNBLOCKED);
-                               rfkill_schedule_set(&rfkill_wlan,
-                                                   RFKILL_STATE_UNBLOCKED);
-                       } else
-                               rfkill_schedule_epo();
+                       rfkill_schedule_evsw_rfkillall(data);
                        break;
                default:
                        break;
@@ -168,6 +173,7 @@ static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
        handle->handler = handler;
        handle->name = "rfkill";
 
+       /* causes rfkill_start() to be called */
        error = input_register_handle(handle);
        if (error)
                goto err_free_handle;
@@ -185,6 +191,23 @@ static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
        return error;
 }
 
+static void rfkill_start(struct input_handle *handle)
+{
+       /* Take event_lock to guard against configuration changes, we
+        * should be able to deal with concurrency with rfkill_event()
+        * just fine (which event_lock will also avoid). */
+       spin_lock_irq(&handle->dev->event_lock);
+
+       if (test_bit(EV_SW, handle->dev->evbit)) {
+               if (test_bit(SW_RFKILL_ALL, handle->dev->swbit))
+                       rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL,
+                                                       handle->dev->sw));
+               /* add resync for further EV_SW events here */
+       }
+
+       spin_unlock_irq(&handle->dev->event_lock);
+}
+
 static void rfkill_disconnect(struct input_handle *handle)
 {
        input_close_device(handle);
@@ -225,6 +248,7 @@ static struct input_handler rfkill_handler = {
        .event =        rfkill_event,
        .connect =      rfkill_connect,
        .disconnect =   rfkill_disconnect,
+       .start =        rfkill_start,
        .name =         "rfkill",
        .id_table =     rfkill_ids,
 };