char *name, u32 cap)
 {
        int err;
-       u32 state;
        struct rfkill *rfkill_dev;
 
        rfkill_dev = rfkill_alloc(name, dev, type,
                                  (void *)(unsigned long)cap);
        if (!rfkill_dev)
                return ERR_PTR(-ENOMEM);
-       get_u32(&state, cap);
-       rfkill_set_sw_state(rfkill_dev, !state);
 
        err = rfkill_register(rfkill_dev);
        if (err) {
 
                if (!ehotk->eeepc_wlan_rfkill)
                        goto wlan_fail;
 
-               rfkill_set_global_sw_state(RFKILL_TYPE_WLAN,
-                                          get_acpi(CM_ASL_WLAN) != 1);
+               rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill,
+                                   get_acpi(CM_ASL_WLAN) != 1);
                result = rfkill_register(ehotk->eeepc_wlan_rfkill);
                if (result)
                        goto wlan_fail;
                if (!ehotk->eeepc_bluetooth_rfkill)
                        goto bluetooth_fail;
 
-               rfkill_set_global_sw_state(RFKILL_TYPE_BLUETOOTH,
-                                          get_acpi(CM_ASL_BLUETOOTH) != 1);
+               rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill,
+                                   get_acpi(CM_ASL_BLUETOOTH) != 1);
                result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
                if (result)
                        goto bluetooth_fail;
 
                                           RFKILL_TYPE_WLAN,
                                           &hp_wmi_rfkill_ops,
                                           (void *) 0);
-               rfkill_set_sw_state(wifi_rfkill, hp_wmi_wifi_state());
                err = rfkill_register(wifi_rfkill);
                if (err)
                        goto register_wifi_error;
                                                RFKILL_TYPE_BLUETOOTH,
                                                &hp_wmi_rfkill_ops,
                                                (void *) 1);
-               rfkill_set_sw_state(bluetooth_rfkill,
-                                   hp_wmi_bluetooth_state());
                err = rfkill_register(bluetooth_rfkill);
                if (err)
                        goto register_bluetooth_error;
                                           RFKILL_TYPE_WWAN,
                                           &hp_wmi_rfkill_ops,
                                           (void *) 2);
-               rfkill_set_sw_state(wwan_rfkill, hp_wmi_wwan_state());
                err = rfkill_register(wwan_rfkill);
                if (err)
                        goto register_wwan_err;
 
 
        BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]);
 
-       initial_sw_status = (tp_rfkops->get_status)();
-       if (initial_sw_status < 0) {
-               printk(TPACPI_ERR
-                       "failed to read initial state for %s, error %d; "
-                       "will turn radio off\n", name, initial_sw_status);
-       } else {
-               initial_sw_state = (initial_sw_status == TPACPI_RFK_RADIO_OFF);
-               if (set_default) {
-                       /* try to set the initial state as the default for the
-                        * rfkill type, since we ask the firmware to preserve
-                        * it across S5 in NVRAM */
-                       rfkill_set_global_sw_state(rfktype, initial_sw_state);
-               }
-       }
-
        atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL);
        if (atp_rfk)
                atp_rfk->rfkill = rfkill_alloc(name,
        atp_rfk->id = id;
        atp_rfk->ops = tp_rfkops;
 
-       rfkill_set_states(atp_rfk->rfkill, initial_sw_state,
-                               tpacpi_rfk_check_hwblock_state());
+       initial_sw_status = (tp_rfkops->get_status)();
+       if (initial_sw_status < 0) {
+               printk(TPACPI_ERR
+                       "failed to read initial state for %s, error %d\n",
+                       name, initial_sw_status);
+       } else {
+               initial_sw_state = (initial_sw_status == TPACPI_RFK_RADIO_OFF);
+               if (set_default) {
+                       /* try to keep the initial state, since we ask the
+                        * firmware to preserve it across S5 in NVRAM */
+                       rfkill_set_sw_state(atp_rfk->rfkill, initial_sw_state);
+               }
+       }
+       rfkill_set_hw_state(atp_rfk->rfkill, tpacpi_rfk_check_hwblock_state());
 
        res = rfkill_register(atp_rfk->rfkill);
        if (res < 0) {
 
  * @rfkill: rfkill structure to be registered
  *
  * This function should be called by the transmitter driver to register
- * the rfkill structure needs to be registered. Before calling this function
- * the driver needs to be ready to service method calls from rfkill.
+ * the rfkill structure. Before calling this function the driver needs
+ * to be ready to service method calls from rfkill.
+ *
+ * If the software blocked state is not set before registration,
+ * set_block will be called to initialize it to a default value.
+ *
+ * If the hardware blocked state is not set before registration,
+ * it is assumed to be unblocked.
  */
 int __must_check rfkill_register(struct rfkill *rfkill);
 
  */
 void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw);
 
-/**
- * rfkill_set_global_sw_state - set global sw block default
- * @type: rfkill type to set default for
- * @blocked: default to set
- *
- * This function sets the global default -- use at boot if your platform has
- * an rfkill switch. If not early enough this call may be ignored.
- *
- * XXX: instead of ignoring -- how about just updating all currently
- *     registered drivers?
- */
-void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked);
-
 /**
  * rfkill_blocked - query rfkill block
  *
 {
 }
 
-static inline void rfkill_set_global_sw_state(const enum rfkill_type type,
-                                             bool blocked)
-{
-}
-
 static inline bool rfkill_blocked(struct rfkill *rfkill)
 {
        return false;
 
 
        bool                    registered;
        bool                    suspended;
+       bool                    persistent;
 
        const struct rfkill_ops *ops;
        void                    *data;
                 "Default initial state for all radio types, 0 = radio off");
 
 static struct {
-       bool cur, def;
+       bool cur, sav;
 } rfkill_global_states[NUM_RFKILL_TYPES];
 
-static unsigned long rfkill_states_default_locked;
-
 static bool rfkill_epo_lock_active;
 
 
                rfkill_set_block(rfkill, true);
 
        for (i = 0; i < NUM_RFKILL_TYPES; i++) {
-               rfkill_global_states[i].def = rfkill_global_states[i].cur;
+               rfkill_global_states[i].sav = rfkill_global_states[i].cur;
                rfkill_global_states[i].cur = true;
        }
 
 
        rfkill_epo_lock_active = false;
        for (i = 0; i < NUM_RFKILL_TYPES; i++)
-               __rfkill_switch_all(i, rfkill_global_states[i].def);
+               __rfkill_switch_all(i, rfkill_global_states[i].sav);
        mutex_unlock(&rfkill_global_mutex);
 }
 
 }
 #endif
 
-void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked)
-{
-       BUG_ON(type == RFKILL_TYPE_ALL);
-
-       mutex_lock(&rfkill_global_mutex);
-
-       /* don't allow unblock when epo */
-       if (rfkill_epo_lock_active && !blocked)
-               goto out;
-
-       /* too late */
-       if (rfkill_states_default_locked & BIT(type))
-               goto out;
-
-       rfkill_states_default_locked |= BIT(type);
-
-       rfkill_global_states[type].cur = blocked;
-       rfkill_global_states[type].def = blocked;
- out:
-       mutex_unlock(&rfkill_global_mutex);
-}
-EXPORT_SYMBOL(rfkill_set_global_sw_state);
-
 
 bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
 {
        blocked = blocked || hwblock;
        spin_unlock_irqrestore(&rfkill->lock, flags);
 
-       if (!rfkill->registered)
-               return blocked;
+       if (!rfkill->registered) {
+               rfkill->persistent = true;
+       } else {
+               if (prev != blocked && !hwblock)
+                       schedule_work(&rfkill->uevent_work);
 
-       if (prev != blocked && !hwblock)
-               schedule_work(&rfkill->uevent_work);
-
-       rfkill_led_trigger_event(rfkill);
+               rfkill_led_trigger_event(rfkill);
+       }
 
        return blocked;
 }
 
        spin_unlock_irqrestore(&rfkill->lock, flags);
 
-       if (!rfkill->registered)
-               return;
-
-       if (swprev != sw || hwprev != hw)
-               schedule_work(&rfkill->uevent_work);
+       if (!rfkill->registered) {
+               rfkill->persistent = true;
+       } else {
+               if (swprev != sw || hwprev != hw)
+                       schedule_work(&rfkill->uevent_work);
 
-       rfkill_led_trigger_event(rfkill);
+               rfkill_led_trigger_event(rfkill);
+       }
 }
 EXPORT_SYMBOL(rfkill_set_states);
 
        dev_set_name(dev, "rfkill%lu", rfkill_no);
        rfkill_no++;
 
-       if (!(rfkill_states_default_locked & BIT(rfkill->type))) {
-               /* first of its kind */
-               BUILD_BUG_ON(NUM_RFKILL_TYPES >
-                       sizeof(rfkill_states_default_locked) * 8);
-               rfkill_states_default_locked |= BIT(rfkill->type);
-               rfkill_global_states[rfkill->type].cur =
-                       rfkill_global_states[rfkill->type].def;
-       }
-
        list_add_tail(&rfkill->node, &rfkill_list);
 
        error = device_add(dev);
        if (rfkill->ops->poll)
                schedule_delayed_work(&rfkill->poll_work,
                        round_jiffies_relative(POLL_INTERVAL));
-       schedule_work(&rfkill->sync_work);
+
+       if (!rfkill->persistent || rfkill_epo_lock_active) {
+               schedule_work(&rfkill->sync_work);
+       } else {
+#ifdef CONFIG_RFKILL_INPUT
+               bool soft_blocked = !!(rfkill->state & RFKILL_BLOCK_SW);
+
+               if (!atomic_read(&rfkill_input_disabled))
+                       __rfkill_switch_all(rfkill->type, soft_blocked);
+#endif
+       }
 
        rfkill_send_events(rfkill, RFKILL_OP_ADD);
 
        int i;
 
        for (i = 0; i < NUM_RFKILL_TYPES; i++)
-               rfkill_global_states[i].def = !rfkill_default_state;
+               rfkill_global_states[i].cur = !rfkill_default_state;
 
        error = class_register(&rfkill_class);
        if (error)