]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'bjorn-notify' into release
authorLen Brown <len.brown@intel.com>
Wed, 24 Jun 2009 05:22:20 +0000 (01:22 -0400)
committerLen Brown <len.brown@intel.com>
Wed, 24 Jun 2009 05:22:20 +0000 (01:22 -0400)
Conflicts:
drivers/platform/x86/eeepc-laptop.c

Signed-off-by: Len Brown <len.brown@intel.com>
1  2 
drivers/platform/x86/eeepc-laptop.c
include/acpi/acpi_bus.h

index 8153b3e5918967bb1662c44523d1ab7eab233d69,1e28413060b26416c9332aefeb840bf5a64a63d7..46b5aa5e85f041214d4611a34b2282c516ec5f0e
@@@ -180,7 -180,7 +180,8 @@@ static struct key_entry eeepc_keymap[] 
   */
  static int eeepc_hotk_add(struct acpi_device *device);
  static int eeepc_hotk_remove(struct acpi_device *device, int type);
 +static int eeepc_hotk_resume(struct acpi_device *device);
+ static void eeepc_hotk_notify(struct acpi_device *device, u32 event);
  
  static const struct acpi_device_id eeepc_device_ids[] = {
        {EEEPC_HOTK_HID, 0},
@@@ -192,10 -192,11 +193,12 @@@ static struct acpi_driver eeepc_hotk_dr
        .name = EEEPC_HOTK_NAME,
        .class = EEEPC_HOTK_CLASS,
        .ids = eeepc_device_ids,
+       .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
        .ops = {
                .add = eeepc_hotk_add,
                .remove = eeepc_hotk_remove,
 +              .resume = eeepc_hotk_resume,
+               .notify = eeepc_hotk_notify,
        },
  };
  
@@@ -301,22 -302,39 +304,22 @@@ static int update_bl_status(struct back
   * Rfkill helpers
   */
  
 -static int eeepc_wlan_rfkill_set(void *data, enum rfkill_state state)
 -{
 -      if (state == RFKILL_STATE_SOFT_BLOCKED)
 -              return set_acpi(CM_ASL_WLAN, 0);
 -      else
 -              return set_acpi(CM_ASL_WLAN, 1);
 -}
 -
 -static int eeepc_wlan_rfkill_state(void *data, enum rfkill_state *state)
 +static bool eeepc_wlan_rfkill_blocked(void)
  {
        if (get_acpi(CM_ASL_WLAN) == 1)
 -              *state = RFKILL_STATE_UNBLOCKED;
 -      else
 -              *state = RFKILL_STATE_SOFT_BLOCKED;
 -      return 0;
 +              return false;
 +      return true;
  }
  
 -static int eeepc_bluetooth_rfkill_set(void *data, enum rfkill_state state)
 +static int eeepc_rfkill_set(void *data, bool blocked)
  {
 -      if (state == RFKILL_STATE_SOFT_BLOCKED)
 -              return set_acpi(CM_ASL_BLUETOOTH, 0);
 -      else
 -              return set_acpi(CM_ASL_BLUETOOTH, 1);
 +      unsigned long asl = (unsigned long)data;
 +      return set_acpi(asl, !blocked);
  }
  
 -static int eeepc_bluetooth_rfkill_state(void *data, enum rfkill_state *state)
 -{
 -      if (get_acpi(CM_ASL_BLUETOOTH) == 1)
 -              *state = RFKILL_STATE_UNBLOCKED;
 -      else
 -              *state = RFKILL_STATE_SOFT_BLOCKED;
 -      return 0;
 -}
 +static const struct rfkill_ops eeepc_rfkill_ops = {
 +      .set_block = eeepc_rfkill_set,
 +};
  
  /*
   * Sys helpers
@@@ -514,19 -532,23 +517,19 @@@ static int notify_brn(void
        return -1;
  }
  
 -static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
 +static void eeepc_rfkill_hotplug(void)
  {
 -      enum rfkill_state state;
        struct pci_dev *dev;
        struct pci_bus *bus = pci_find_bus(0, 1);
 -
 -      if (event != ACPI_NOTIFY_BUS_CHECK)
 -              return;
 +      bool blocked;
  
        if (!bus) {
                printk(EEEPC_WARNING "Unable to find PCI bus 1?\n");
                return;
        }
  
 -      eeepc_wlan_rfkill_state(ehotk->eeepc_wlan_rfkill, &state);
 -
 -      if (state == RFKILL_STATE_UNBLOCKED) {
 +      blocked = eeepc_wlan_rfkill_blocked();
 +      if (!blocked) {
                dev = pci_get_slot(bus, 0);
                if (dev) {
                        /* Device already present */
                }
        }
  
 -      rfkill_force_state(ehotk->eeepc_wlan_rfkill, state);
 +      rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked);
 +}
 +
 +static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
 +{
 +      if (event != ACPI_NOTIFY_BUS_CHECK)
 +              return;
 +
 +      eeepc_rfkill_hotplug();
  }
  
- static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
+ static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
  {
        static struct key_entry *key;
        u16 count;
  
        if (!ehotk)
                return;
+       if (event > ACPI_MAX_SYS_NOTIFY)
+               return;
        if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
                brn = notify_brn();
        count = ehotk->event_count[event % 128]++;
@@@ -646,7 -662,6 +651,6 @@@ static void eeepc_unregister_rfkill_not
  
  static int eeepc_hotk_add(struct acpi_device *device)
  {
-       acpi_status status = AE_OK;
        int result;
  
        if (!device)
        result = eeepc_hotk_check();
        if (result)
                goto ehotk_fail;
-       status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
-                                            eeepc_hotk_notify, ehotk);
-       if (ACPI_FAILURE(status))
-               printk(EEEPC_ERR "Error installing notify handler\n");
  
        eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
        eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
  
        if (get_acpi(CM_ASL_WLAN) != -1) {
 -              ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev,
 -                                                         RFKILL_TYPE_WLAN);
 +              ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan",
 +                                                      &device->dev,
 +                                                      RFKILL_TYPE_WLAN,
 +                                                      &eeepc_rfkill_ops,
 +                                                      (void *)CM_ASL_WLAN);
  
                if (!ehotk->eeepc_wlan_rfkill)
                        goto wlan_fail;
  
 -              ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan";
 -              ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set;
 -              ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state;
 -              if (get_acpi(CM_ASL_WLAN) == 1) {
 -                      ehotk->eeepc_wlan_rfkill->state =
 -                              RFKILL_STATE_UNBLOCKED;
 -                      rfkill_set_default(RFKILL_TYPE_WLAN,
 -                                         RFKILL_STATE_UNBLOCKED);
 -              } else {
 -                      ehotk->eeepc_wlan_rfkill->state =
 -                              RFKILL_STATE_SOFT_BLOCKED;
 -                      rfkill_set_default(RFKILL_TYPE_WLAN,
 -                                         RFKILL_STATE_SOFT_BLOCKED);
 -              }
 +              rfkill_init_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 (get_acpi(CM_ASL_BLUETOOTH) != -1) {
                ehotk->eeepc_bluetooth_rfkill =
 -                      rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH);
 +                      rfkill_alloc("eeepc-bluetooth",
 +                                   &device->dev,
 +                                   RFKILL_TYPE_BLUETOOTH,
 +                                   &eeepc_rfkill_ops,
 +                                   (void *)CM_ASL_BLUETOOTH);
  
                if (!ehotk->eeepc_bluetooth_rfkill)
                        goto bluetooth_fail;
  
 -              ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth";
 -              ehotk->eeepc_bluetooth_rfkill->toggle_radio =
 -                      eeepc_bluetooth_rfkill_set;
 -              ehotk->eeepc_bluetooth_rfkill->get_state =
 -                      eeepc_bluetooth_rfkill_state;
 -              if (get_acpi(CM_ASL_BLUETOOTH) == 1) {
 -                      ehotk->eeepc_bluetooth_rfkill->state =
 -                              RFKILL_STATE_UNBLOCKED;
 -                      rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
 -                                         RFKILL_STATE_UNBLOCKED);
 -              } else {
 -                      ehotk->eeepc_bluetooth_rfkill->state =
 -                              RFKILL_STATE_SOFT_BLOCKED;
 -                      rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
 -                                         RFKILL_STATE_SOFT_BLOCKED);
 -              }
 -
 +              rfkill_init_sw_state(ehotk->eeepc_bluetooth_rfkill,
 +                                   get_acpi(CM_ASL_BLUETOOTH) != 1);
                result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
                if (result)
                        goto bluetooth_fail;
        return 0;
  
   bluetooth_fail:
 -      if (ehotk->eeepc_bluetooth_rfkill)
 -              rfkill_free(ehotk->eeepc_bluetooth_rfkill);
 +      rfkill_destroy(ehotk->eeepc_bluetooth_rfkill);
        rfkill_unregister(ehotk->eeepc_wlan_rfkill);
 -      ehotk->eeepc_wlan_rfkill = NULL;
   wlan_fail:
 -      if (ehotk->eeepc_wlan_rfkill)
 -              rfkill_free(ehotk->eeepc_wlan_rfkill);
 +      rfkill_destroy(ehotk->eeepc_wlan_rfkill);
        eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
        eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
   ehotk_fail:
  
  static int eeepc_hotk_remove(struct acpi_device *device, int type)
  {
-       acpi_status status = 0;
        if (!device || !acpi_driver_data(device))
                 return -EINVAL;
-       status = acpi_remove_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
-                                           eeepc_hotk_notify);
-       if (ACPI_FAILURE(status))
-               printk(EEEPC_ERR "Error removing notify handler\n");
  
        eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
        eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
        return 0;
  }
  
 +static int eeepc_hotk_resume(struct acpi_device *device)
 +{
 +      if (ehotk->eeepc_wlan_rfkill) {
 +              bool wlan;
 +
 +              /* Workaround - it seems that _PTS disables the wireless
 +                 without notification or changing the value read by WLAN.
 +                 Normally this is fine because the correct value is restored
 +                 from the non-volatile storage on resume, but we need to do
 +                 it ourself if case suspend is aborted, or we lose wireless.
 +               */
 +              wlan = get_acpi(CM_ASL_WLAN);
 +              set_acpi(CM_ASL_WLAN, wlan);
 +
 +              rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill,
 +                                  wlan != 1);
 +
 +              eeepc_rfkill_hotplug();
 +      }
 +
 +      if (ehotk->eeepc_bluetooth_rfkill)
 +              rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill,
 +                                  get_acpi(CM_ASL_BLUETOOTH) != 1);
 +
 +      return 0;
 +}
 +
  /*
   * Hwmon
   */
diff --combined include/acpi/acpi_bus.h
index bf1f43bd9016f244b90b3adf8c42422165e3f9cc,84e35d5646a102ef8205880320ae7550979a75ad..c65e4ce6c3afa38e41ada87bfac5fd5d29c27f36
@@@ -114,10 -114,13 +114,13 @@@ struct acpi_device_ops 
        acpi_op_notify notify;
  };
  
+ #define ACPI_DRIVER_ALL_NOTIFY_EVENTS 0x1     /* system AND device events */
  struct acpi_driver {
        char name[80];
        char class[80];
        const struct acpi_device_id *ids; /* Supported Hardware IDs */
+       unsigned int flags;
        struct acpi_device_ops ops;
        struct device_driver drv;
        struct module *owner;
@@@ -168,7 -171,7 +171,7 @@@ struct acpi_device_dir 
  
  /* Plug and Play */
  
 -typedef char acpi_bus_id[5];
 +typedef char acpi_bus_id[8];
  typedef unsigned long acpi_bus_address;
  typedef char acpi_hardware_id[15];
  typedef char acpi_unique_id[9];
@@@ -365,10 -368,10 +368,10 @@@ struct acpi_bus_type 
  int register_acpi_bus_type(struct acpi_bus_type *);
  int unregister_acpi_bus_type(struct acpi_bus_type *);
  struct device *acpi_get_physical_device(acpi_handle);
 -struct device *acpi_get_physical_pci_device(acpi_handle);
  
  /* helper */
  acpi_handle acpi_get_child(acpi_handle, acpi_integer);
 +int acpi_is_root_bridge(acpi_handle);
  acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
  #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle))