]> git.openfabrics.org - ~shefty/rdma-dev.git/commitdiff
Merge branch 'acpi-general'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 29 Nov 2012 20:43:06 +0000 (21:43 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 29 Nov 2012 20:43:06 +0000 (21:43 +0100)
* acpi-general: (38 commits)
  ACPI / thermal: _TMP and _CRT/_HOT/_PSV/_ACx dependency fix
  ACPI: drop unnecessary local variable from acpi_system_write_wakeup_device()
  ACPI: Fix logging when no pci_irq is allocated
  ACPI: Update Dock hotplug error messages
  ACPI: Update Container hotplug error messages
  ACPI: Update Memory hotplug error messages
  ACPI: Update CPU hotplug error messages
  ACPI: Add acpi_handle_<level>() interfaces
  ACPI: remove use of __devexit
  ACPI / PM: Add Sony Vaio VPCEB1S1E to nonvs blacklist.
  ACPI / battery: Correct battery capacity values on Thinkpads
  Revert "ACPI / x86: Add quirk for "CheckPoint P-20-00" to not use bridge _CRS_ info"
  ACPI: create _SUN sysfs file
  ACPI / memhotplug: bind the memory device when the driver is being loaded
  ACPI / memhotplug: don't allow to eject the memory device if it is being used
  ACPI / memhotplug: free memory device if acpi_memory_enable_device() failed
  ACPI / memhotplug: fix memory leak when memory device is unbound from acpi_memhotplug
  ACPI / memhotplug: deal with eject request in hotplug queue
  ACPI / memory-hotplug: add memory offline code to acpi_memory_device_remove()
  ACPI / memory-hotplug: call acpi_bus_trim() to remove memory device
  ...

Conflicts:
include/linux/acpi.h (two additions at the end of the same file)

1  2 
drivers/acpi/internal.h
drivers/acpi/pci_irq.c
drivers/acpi/scan.c
drivers/acpi/sleep.c
include/acpi/acpi_bus.h
include/linux/acpi.h

diff --combined drivers/acpi/internal.h
index 57d41f6e1441b7e522929511d5e582bb4528fd93,509dcaa17555c38cc3d0c622c343a68e82472fd6..3c407cdc1ec1ce95acd5b6ce071e41f12d2344d2
@@@ -58,11 -58,11 +58,11 @@@ struct acpi_ec 
        unsigned long data_addr;
        unsigned long global_lock;
        unsigned long flags;
-       struct mutex lock;
+       struct mutex mutex;
        wait_queue_head_t wait;
        struct list_head list;
        struct transaction *curr;
-       spinlock_t curr_lock;
+       spinlock_t lock;
  };
  
  extern struct acpi_ec *first_ec;
@@@ -93,11 -93,4 +93,11 @@@ static inline int suspend_nvs_save(void
  static inline void suspend_nvs_restore(void) {}
  #endif
  
 +/*--------------------------------------------------------------------------
 +                              Platform bus support
 +  -------------------------------------------------------------------------- */
 +struct platform_device;
 +
 +struct platform_device *acpi_create_platform_device(struct acpi_device *adev);
 +
  #endif /* _ACPI_INTERNAL_H_ */
diff --combined drivers/acpi/pci_irq.c
index 1be25a590dce60d4104611910e9ca70a117aad95,f2c3d74af23ee8b41cc6ddb1d9409edc3ec0a3bf..23a0324901307b9f0c930f7be00beeff45dbbec0
@@@ -459,19 -459,19 +459,19 @@@ int acpi_pci_irq_enable(struct pci_dev 
         */
        if (gsi < 0) {
                u32 dev_gsi;
-               dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin));
                /* Interrupt Line values above 0xF are forbidden */
                if (dev->irq > 0 && (dev->irq <= 0xF) &&
                    (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) {
-                       printk(" - using ISA IRQ %d\n", dev->irq);
+                       dev_warn(&dev->dev, "PCI INT %c: no GSI - using ISA IRQ %d\n",
+                                pin_name(pin), dev->irq);
                        acpi_register_gsi(&dev->dev, dev_gsi,
                                          ACPI_LEVEL_SENSITIVE,
                                          ACPI_ACTIVE_LOW);
-                       return 0;
                } else {
-                       printk("\n");
-                       return 0;
+                       dev_warn(&dev->dev, "PCI INT %c: no GSI\n",
+                                pin_name(pin));
                }
+               return 0;
        }
  
        rc = acpi_register_gsi(&dev->dev, gsi, triggering, polarity);
        return 0;
  }
  
 -/* FIXME: implement x86/x86_64 version */
 -void __attribute__ ((weak)) acpi_unregister_gsi(u32 i)
 -{
 -}
 -
  void acpi_pci_irq_disable(struct pci_dev *dev)
  {
        struct acpi_prt_entry *entry;
diff --combined drivers/acpi/scan.c
index 2976058e6e8e6ff24cd40ecd79bed332bba166b0,d0b38ab47ab5a98c691d71338b7923ac0dc9ed7b..67a7fa638f7f628cd76fd7ed8b71f2e7ebb69d23
@@@ -29,17 -29,6 +29,17 @@@ extern struct acpi_device *acpi_root
  
  static const char *dummy_hid = "device";
  
 +/*
 + * The following ACPI IDs are known to be suitable for representing as
 + * platform devices.
 + */
 +static const struct acpi_device_id acpi_platform_device_ids[] = {
 +
 +      { "PNP0D40" },
 +
 +      { }
 +};
 +
  static LIST_HEAD(acpi_device_list);
  static LIST_HEAD(acpi_bus_id_list);
  DEFINE_MUTEX(acpi_device_lock);
@@@ -108,6 -97,7 +108,7 @@@ void acpi_bus_hot_remove_device(void *c
        struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context;
        struct acpi_device *device;
        acpi_handle handle = ej_event->handle;
+       acpi_handle temp;
        struct acpi_object_list arg_list;
        union acpi_object arg;
        acpi_status status = AE_OK;
                goto err_out;
        }
  
+       /* device has been freed */
+       device = NULL;
        /* power off device */
        status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
        if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
                printk(KERN_WARNING PREFIX
                                "Power-off device failed\n");
  
-       if (device->flags.lockable) {
+       if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) {
                arg_list.count = 1;
                arg_list.pointer = &arg;
                arg.type = ACPI_TYPE_INTEGER;
@@@ -168,6 -161,7 +172,7 @@@ err_out
        kfree(context);
        return;
  }
+ EXPORT_SYMBOL(acpi_bus_hot_remove_device);
  
  static ssize_t
  acpi_eject_store(struct device *d, struct device_attribute *attr,
@@@ -227,6 -221,25 +232,25 @@@ acpi_device_hid_show(struct device *dev
  }
  static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL);
  
+ static ssize_t acpi_device_uid_show(struct device *dev,
+                                   struct device_attribute *attr, char *buf)
+ {
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
+       return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id);
+ }
+ static DEVICE_ATTR(uid, 0444, acpi_device_uid_show, NULL);
+ static ssize_t acpi_device_adr_show(struct device *dev,
+                                   struct device_attribute *attr, char *buf)
+ {
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
+       return sprintf(buf, "0x%08x\n",
+                      (unsigned int)(acpi_dev->pnp.bus_address));
+ }
+ static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL);
  static ssize_t
  acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) {
        struct acpi_device *acpi_dev = to_acpi_device(dev);
@@@ -270,11 -283,21 +294,21 @@@ static ssize_t description_show(struct 
  }
  static DEVICE_ATTR(description, 0444, description_show, NULL);
  
+ static ssize_t
+ acpi_device_sun_show(struct device *dev, struct device_attribute *attr,
+                    char *buf) {
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
+       return sprintf(buf, "%lu\n", acpi_dev->pnp.sun);
+ }
+ static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL);
  static int acpi_device_setup_files(struct acpi_device *dev)
  {
        struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
        acpi_status status;
        acpi_handle temp;
+       unsigned long long sun;
        int result = 0;
  
        /*
                        goto end;
        }
  
+       if (dev->flags.bus_address)
+               result = device_create_file(&dev->dev, &dev_attr_adr);
+       if (dev->pnp.unique_id)
+               result = device_create_file(&dev->dev, &dev_attr_uid);
+       status = acpi_evaluate_integer(dev->handle, "_SUN", NULL, &sun);
+       if (ACPI_SUCCESS(status)) {
+               dev->pnp.sun = (unsigned long)sun;
+               result = device_create_file(&dev->dev, &dev_attr_sun);
+               if (result)
+                       goto end;
+       } else {
+               dev->pnp.sun = (unsigned long)-1;
+       }
          /*
           * If device has _EJ0, 'eject' file is created that is used to trigger
           * hot-removal function from userland.
@@@ -342,6 -380,14 +391,14 @@@ static void acpi_device_remove_files(st
        if (ACPI_SUCCESS(status))
                device_remove_file(&dev->dev, &dev_attr_eject);
  
+       status = acpi_get_handle(dev->handle, "_SUN", &temp);
+       if (ACPI_SUCCESS(status))
+               device_remove_file(&dev->dev, &dev_attr_sun);
+       if (dev->pnp.unique_id)
+               device_remove_file(&dev->dev, &dev_attr_uid);
+       if (dev->flags.bus_address)
+               device_remove_file(&dev->dev, &dev_attr_adr);
        device_remove_file(&dev->dev, &dev_attr_modalias);
        device_remove_file(&dev->dev, &dev_attr_hid);
        if (dev->handle)
                        ACPI Bus operations
     -------------------------------------------------------------------------- */
  
 -int acpi_match_device_ids(struct acpi_device *device,
 -                        const struct acpi_device_id *ids)
 +static const struct acpi_device_id *__acpi_match_device(
 +      struct acpi_device *device, const struct acpi_device_id *ids)
  {
        const struct acpi_device_id *id;
        struct acpi_hardware_id *hwid;
         * driver for it.
         */
        if (!device->status.present)
 -              return -ENODEV;
 +              return NULL;
  
        for (id = ids; id->id[0]; id++)
                list_for_each_entry(hwid, &device->pnp.ids, list)
                        if (!strcmp((char *) id->id, hwid->id))
 -                              return 0;
 +                              return id;
 +
 +      return NULL;
 +}
 +
 +/**
 + * acpi_match_device - Match a struct device against a given list of ACPI IDs
 + * @ids: Array of struct acpi_device_id object to match against.
 + * @dev: The device structure to match.
 + *
 + * Check if @dev has a valid ACPI handle and if there is a struct acpi_device
 + * object for that handle and use that object to match against a given list of
 + * device IDs.
 + *
 + * Return a pointer to the first matching ID on success or %NULL on failure.
 + */
 +const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
 +                                             const struct device *dev)
 +{
 +      struct acpi_device *adev;
  
 -      return -ENOENT;
 +      if (!ids || !ACPI_HANDLE(dev)
 +          || ACPI_FAILURE(acpi_bus_get_device(ACPI_HANDLE(dev), &adev)))
 +              return NULL;
 +
 +      return __acpi_match_device(adev, ids);
 +}
 +EXPORT_SYMBOL_GPL(acpi_match_device);
 +
 +int acpi_match_device_ids(struct acpi_device *device,
 +                        const struct acpi_device_id *ids)
 +{
 +      return __acpi_match_device(device, ids) ? 0 : -ENOENT;
  }
  EXPORT_SYMBOL(acpi_match_device_ids);
  
@@@ -418,6 -434,7 +475,7 @@@ static void acpi_device_release(struct 
        struct acpi_device *acpi_dev = to_acpi_device(dev);
  
        acpi_free_ids(acpi_dev);
+       kfree(acpi_dev->pnp.unique_id);
        kfree(acpi_dev);
  }
  
@@@ -1006,10 -1023,8 +1064,10 @@@ static int acpi_bus_get_power_flags(str
                 * D3hot is only valid if _PR3 present.
                 */
                if (ps->resources.count ||
 -                  (ps->flags.explicit_set && i < ACPI_STATE_D3_HOT))
 +                  (ps->flags.explicit_set && i < ACPI_STATE_D3_HOT)) {
                        ps->flags.valid = 1;
 +                      ps->flags.os_accessible = 1;
 +              }
  
                ps->power = -1; /* Unknown - driver assigned */
                ps->latency = -1;       /* Unknown - driver assigned */
        if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set)
                device->power.states[ACPI_STATE_D3_COLD].flags.explicit_set = 1;
  
 +      /* Presence of _PS3 or _PRx means we can put the device into D3 cold */
 +      if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set ||
 +                      device->power.flags.power_resources)
 +              device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1;
 +
        acpi_bus_init_power(device);
  
        return 0;
@@@ -1061,11 -1071,6 +1119,6 @@@ static int acpi_bus_get_flags(struct ac
                        device->flags.ejectable = 1;
        }
  
-       /* Presence of _LCK indicates 'lockable' */
-       status = acpi_get_handle(device->handle, "_LCK", &temp);
-       if (ACPI_SUCCESS(status))
-               device->flags.lockable = 1;
        /* Power resources cannot be power manageable. */
        if (device->device_type == ACPI_BUS_TYPE_POWER)
                return 0;
@@@ -1233,7 -1238,7 +1286,7 @@@ static void acpi_device_set_id(struct a
  {
        acpi_status status;
        struct acpi_device_info *info;
 -      struct acpica_device_id_list *cid_list;
 +      struct acpi_pnp_device_id_list *cid_list;
        int i;
  
        switch (device->device_type) {
                        device->pnp.bus_address = info->address;
                        device->flags.bus_address = 1;
                }
+               if (info->valid & ACPI_VALID_UID)
+                       device->pnp.unique_id = kstrdup(info->unique_id.string,
+                                                       GFP_KERNEL);
  
                kfree(info);
  
@@@ -1531,13 -1539,8 +1587,13 @@@ static acpi_status acpi_bus_check_add(a
         */
        device = NULL;
        acpi_bus_get_device(handle, &device);
 -      if (ops->acpi_op_add && !device)
 +      if (ops->acpi_op_add && !device) {
                acpi_add_single_object(&device, handle, type, sta, ops);
 +              /* Is the device a known good platform device? */
 +              if (device
 +                  && !acpi_match_device_ids(device, acpi_platform_device_ids))
 +                      acpi_create_platform_device(device);
 +      }
  
        if (!device)
                return AE_CTRL_DEPTH;
diff --combined drivers/acpi/sleep.c
index 13a285dffaca752226f904e89bb73387bdd233aa,1463c56092c4ad59fdd1cca2938beb27f4af7cad..1e25319164f1b107c4a4239690ea61d61e011902
@@@ -18,6 -18,7 +18,6 @@@
  #include <linux/reboot.h>
  #include <linux/acpi.h>
  #include <linux/module.h>
 -#include <linux/pm_runtime.h>
  
  #include <asm/io.h>
  
@@@ -80,12 -81,6 +80,12 @@@ static int acpi_sleep_prepare(u32 acpi_
  
  #ifdef CONFIG_ACPI_SLEEP
  static u32 acpi_target_sleep_state = ACPI_STATE_S0;
 +
 +u32 acpi_target_system_state(void)
 +{
 +      return acpi_target_sleep_state;
 +}
 +
  static bool pwr_btn_event_pending;
  
  /*
@@@ -102,6 -97,21 +102,21 @@@ void __init acpi_nvs_nosave(void
        nvs_nosave = true;
  }
  
+ /*
+  * The ACPI specification wants us to save NVS memory regions during hibernation
+  * but says nothing about saving NVS during S3.  Not all versions of Windows
+  * save NVS on S3 suspend either, and it is clear that not all systems need
+  * NVS to be saved at S3 time.  To improve suspend/resume time, allow the
+  * user to disable saving NVS on S3 if their system does not require it, but
+  * continue to save/restore NVS for S4 as specified.
+  */
+ static bool nvs_nosave_s3;
+ void __init acpi_nvs_nosave_s3(void)
+ {
+       nvs_nosave_s3 = true;
+ }
  /*
   * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
   * user to request that behavior by using the 'acpi_old_suspend_ordering'
@@@ -248,7 -258,7 +263,7 @@@ static int acpi_suspend_begin(suspend_s
        u32 acpi_state = acpi_suspend_states[pm_state];
        int error = 0;
  
-       error = nvs_nosave ? 0 : suspend_nvs_alloc();
+       error = (nvs_nosave || nvs_nosave_s3) ? 0 : suspend_nvs_alloc();
        if (error)
                return error;
  
@@@ -524,6 -534,14 +539,14 @@@ static struct dmi_system_id __initdata 
        },
        {
        .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VPCEB1S1E",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1S1E"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
        .ident = "Sony Vaio VGN-FW520F",
        .matches = {
                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
@@@ -686,6 -704,177 +709,6 @@@ int acpi_suspend(u32 acpi_state
        return -EINVAL;
  }
  
 -#ifdef CONFIG_PM
 -/**
 - *    acpi_pm_device_sleep_state - return preferred power state of ACPI device
 - *            in the system sleep state given by %acpi_target_sleep_state
 - *    @dev: device to examine; its driver model wakeup flags control
 - *            whether it should be able to wake up the system
 - *    @d_min_p: used to store the upper limit of allowed states range
 - *    @d_max_in: specify the lowest allowed states
 - *    Return value: preferred power state of the device on success, -ENODEV
 - *    (ie. if there's no 'struct acpi_device' for @dev) or -EINVAL on failure
 - *
 - *    Find the lowest power (highest number) ACPI device power state that
 - *    device @dev can be in while the system is in the sleep state represented
 - *    by %acpi_target_sleep_state.  If @wake is nonzero, the device should be
 - *    able to wake up the system from this sleep state.  If @d_min_p is set,
 - *    the highest power (lowest number) device power state of @dev allowed
 - *    in this system sleep state is stored at the location pointed to by it.
 - *
 - *    The caller must ensure that @dev is valid before using this function.
 - *    The caller is also responsible for figuring out if the device is
 - *    supposed to be able to wake up the system and passing this information
 - *    via @wake.
 - */
 -
 -int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
 -{
 -      acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
 -      struct acpi_device *adev;
 -      char acpi_method[] = "_SxD";
 -      unsigned long long d_min, d_max;
 -
 -      if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3)
 -              return -EINVAL;
 -      if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
 -              printk(KERN_DEBUG "ACPI handle has no context!\n");
 -              return -ENODEV;
 -      }
 -
 -      acpi_method[2] = '0' + acpi_target_sleep_state;
 -      /*
 -       * If the sleep state is S0, the lowest limit from ACPI is D3,
 -       * but if the device has _S0W, we will use the value from _S0W
 -       * as the lowest limit from ACPI.  Finally, we will constrain
 -       * the lowest limit with the specified one.
 -       */
 -      d_min = ACPI_STATE_D0;
 -      d_max = ACPI_STATE_D3;
 -
 -      /*
 -       * If present, _SxD methods return the minimum D-state (highest power
 -       * state) we can use for the corresponding S-states.  Otherwise, the
 -       * minimum D-state is D0 (ACPI 3.x).
 -       *
 -       * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer
 -       * provided -- that's our fault recovery, we ignore retval.
 -       */
 -      if (acpi_target_sleep_state > ACPI_STATE_S0)
 -              acpi_evaluate_integer(handle, acpi_method, NULL, &d_min);
 -
 -      /*
 -       * If _PRW says we can wake up the system from the target sleep state,
 -       * the D-state returned by _SxD is sufficient for that (we assume a
 -       * wakeup-aware driver if wake is set).  Still, if _SxW exists
 -       * (ACPI 3.x), it should return the maximum (lowest power) D-state that
 -       * can wake the system.  _S0W may be valid, too.
 -       */
 -      if (acpi_target_sleep_state == ACPI_STATE_S0 ||
 -          (device_may_wakeup(dev) && adev->wakeup.flags.valid &&
 -           adev->wakeup.sleep_state >= acpi_target_sleep_state)) {
 -              acpi_status status;
 -
 -              acpi_method[3] = 'W';
 -              status = acpi_evaluate_integer(handle, acpi_method, NULL,
 -                                              &d_max);
 -              if (ACPI_FAILURE(status)) {
 -                      if (acpi_target_sleep_state != ACPI_STATE_S0 ||
 -                          status != AE_NOT_FOUND)
 -                              d_max = d_min;
 -              } else if (d_max < d_min) {
 -                      /* Warn the user of the broken DSDT */
 -                      printk(KERN_WARNING "ACPI: Wrong value from %s\n",
 -                              acpi_method);
 -                      /* Sanitize it */
 -                      d_min = d_max;
 -              }
 -      }
 -
 -      if (d_max_in < d_min)
 -              return -EINVAL;
 -      if (d_min_p)
 -              *d_min_p = d_min;
 -      /* constrain d_max with specified lowest limit (max number) */
 -      if (d_max > d_max_in) {
 -              for (d_max = d_max_in; d_max > d_min; d_max--) {
 -                      if (adev->power.states[d_max].flags.valid)
 -                              break;
 -              }
 -      }
 -      return d_max;
 -}
 -EXPORT_SYMBOL(acpi_pm_device_sleep_state);
 -#endif /* CONFIG_PM */
 -
 -#ifdef CONFIG_PM_SLEEP
 -/**
 - * acpi_pm_device_run_wake - Enable/disable wake-up for given device.
 - * @phys_dev: Device to enable/disable the platform to wake-up the system for.
 - * @enable: Whether enable or disable the wake-up functionality.
 - *
 - * Find the ACPI device object corresponding to @pci_dev and try to
 - * enable/disable the GPE associated with it.
 - */
 -int acpi_pm_device_run_wake(struct device *phys_dev, bool enable)
 -{
 -      struct acpi_device *dev;
 -      acpi_handle handle;
 -
 -      if (!device_run_wake(phys_dev))
 -              return -EINVAL;
 -
 -      handle = DEVICE_ACPI_HANDLE(phys_dev);
 -      if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) {
 -              dev_dbg(phys_dev, "ACPI handle has no context in %s!\n",
 -                      __func__);
 -              return -ENODEV;
 -      }
 -
 -      if (enable) {
 -              acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0);
 -              acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
 -      } else {
 -              acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
 -              acpi_disable_wakeup_device_power(dev);
 -      }
 -
 -      return 0;
 -}
 -EXPORT_SYMBOL(acpi_pm_device_run_wake);
 -
 -/**
 - *    acpi_pm_device_sleep_wake - enable or disable the system wake-up
 - *                                  capability of given device
 - *    @dev: device to handle
 - *    @enable: 'true' - enable, 'false' - disable the wake-up capability
 - */
 -int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
 -{
 -      acpi_handle handle;
 -      struct acpi_device *adev;
 -      int error;
 -
 -      if (!device_can_wakeup(dev))
 -              return -EINVAL;
 -
 -      handle = DEVICE_ACPI_HANDLE(dev);
 -      if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
 -              dev_dbg(dev, "ACPI handle has no context in %s!\n", __func__);
 -              return -ENODEV;
 -      }
 -
 -      error = enable ?
 -              acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) :
 -              acpi_disable_wakeup_device_power(adev);
 -      if (!error)
 -              dev_info(dev, "wake-up capability %s by ACPI\n",
 -                              enable ? "enabled" : "disabled");
 -
 -      return error;
 -}
 -#endif  /* CONFIG_PM_SLEEP */
 -
  static void acpi_power_off_prepare(void)
  {
        /* Prepare to power off the system */
diff --combined include/acpi/acpi_bus.h
index c4ed4c2389c786c9b60643130eb87cdb71e18b42,6f385e5909dbdc995d1049e35c4dd90269c5d1b3..7ced5dc20dd3b98adbfb990bd5962b6d4ee94237
@@@ -144,12 -144,11 +144,11 @@@ struct acpi_device_flags 
        u32 bus_address:1;
        u32 removable:1;
        u32 ejectable:1;
-       u32 lockable:1;
        u32 suprise_removal_ok:1;
        u32 power_manageable:1;
        u32 performance_manageable:1;
        u32 eject_pending:1;
-       u32 reserved:23;
+       u32 reserved:24;
  };
  
  /* File System */
@@@ -180,6 -179,7 +179,7 @@@ struct acpi_device_pnp 
        acpi_device_name device_name;   /* Driver-determined */
        acpi_device_class device_class; /*        "          */
        union acpi_object *str_obj;     /* unicode string for _STR method */
+       unsigned long sun;              /* _SUN */
  };
  
  #define acpi_device_bid(d)    ((d)->pnp.bus_id)
@@@ -201,7 -201,6 +201,7 @@@ struct acpi_device_power_flags 
  struct acpi_device_power_state {
        struct {
                u8 valid:1;
 +              u8 os_accessible:1;
                u8 explicit_set:1;      /* _PSx present? */
                u8 reserved:6;
        } flags;
@@@ -340,7 -339,6 +340,7 @@@ acpi_status acpi_bus_get_status_handle(
                                       unsigned long long *sta);
  int acpi_bus_get_status(struct acpi_device *device);
  int acpi_bus_set_power(acpi_handle handle, int state);
 +int acpi_device_set_power(struct acpi_device *device, int state);
  int acpi_bus_update_power(acpi_handle handle, int *state_p);
  bool acpi_bus_power_manageable(acpi_handle handle);
  bool acpi_bus_can_wakeup(acpi_handle handle);
@@@ -412,100 -410,36 +412,100 @@@ acpi_handle acpi_get_child(acpi_handle
  int acpi_is_root_bridge(acpi_handle);
  acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
  struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
 -#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle))
 +#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev))
  
  int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state);
  int acpi_disable_wakeup_device_power(struct acpi_device *dev);
  
  #ifdef CONFIG_PM
 +acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
 +                               acpi_notify_handler handler, void *context);
 +acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
 +                                  acpi_notify_handler handler);
 +int acpi_device_power_state(struct device *dev, struct acpi_device *adev,
 +                          u32 target_state, int d_max_in, int *d_min_p);
  int acpi_pm_device_sleep_state(struct device *, int *, int);
  #else
 -static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
 +static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
 +                                             acpi_notify_handler handler,
 +                                             void *context)
 +{
 +      return AE_SUPPORT;
 +}
 +static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
 +                                                acpi_notify_handler handler)
 +{
 +      return AE_SUPPORT;
 +}
 +static inline int __acpi_device_power_state(int m, int *p)
  {
        if (p)
                *p = ACPI_STATE_D0;
        return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3) ? m : ACPI_STATE_D0;
  }
 +static inline int acpi_device_power_state(struct device *dev,
 +                                        struct acpi_device *adev,
 +                                        u32 target_state, int d_max_in,
 +                                        int *d_min_p)
 +{
 +      return __acpi_device_power_state(d_max_in, d_min_p);
 +}
 +static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
 +{
 +      return __acpi_device_power_state(m, p);
 +}
  #endif
  
 -#ifdef CONFIG_PM_SLEEP
 +#ifdef CONFIG_PM_RUNTIME
 +int __acpi_device_run_wake(struct acpi_device *, bool);
  int acpi_pm_device_run_wake(struct device *, bool);
 -int acpi_pm_device_sleep_wake(struct device *, bool);
  #else
 +static inline int __acpi_device_run_wake(struct acpi_device *adev, bool en)
 +{
 +      return -ENODEV;
 +}
  static inline int acpi_pm_device_run_wake(struct device *dev, bool enable)
  {
        return -ENODEV;
  }
 +#endif
 +
 +#ifdef CONFIG_PM_SLEEP
 +int __acpi_device_sleep_wake(struct acpi_device *, u32, bool);
 +int acpi_pm_device_sleep_wake(struct device *, bool);
 +#else
 +static inline int __acpi_device_sleep_wake(struct acpi_device *adev,
 +                                         u32 target_state, bool enable)
 +{
 +      return -ENODEV;
 +}
  static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
  {
        return -ENODEV;
  }
  #endif
  
 +#ifdef CONFIG_ACPI_SLEEP
 +u32 acpi_target_system_state(void);
 +#else
 +static inline u32 acpi_target_system_state(void) { return ACPI_STATE_S0; }
 +#endif
 +
 +static inline bool acpi_device_power_manageable(struct acpi_device *adev)
 +{
 +      return adev->flags.power_manageable;
 +}
 +
 +static inline bool acpi_device_can_wakeup(struct acpi_device *adev)
 +{
 +      return adev->wakeup.flags.valid;
 +}
 +
 +static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
 +{
 +      return adev->power.states[ACPI_STATE_D3_COLD].flags.os_accessible;
 +}
 +
  #else /* CONFIG_ACPI */
  
  static inline int register_acpi_bus_type(void *bus) { return 0; }
diff --combined include/linux/acpi.h
index 3574e4a2bf148362ac7399110d430388c87d25c7,9201ac1f051193e448475e7e7935b655d97e6c98..0f8022baf3fd34490b056b8468b257d9e1afe0d2
@@@ -25,9 -25,7 +25,9 @@@
  #ifndef _LINUX_ACPI_H
  #define _LINUX_ACPI_H
  
 +#include <linux/errno.h>
  #include <linux/ioport.h>     /* for struct resource */
 +#include <linux/device.h>
  
  #ifdef        CONFIG_ACPI
  
@@@ -252,26 -250,6 +252,26 @@@ extern int pnpacpi_disabled
  
  #define PXM_INVAL     (-1)
  
 +bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res);
 +bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res);
 +bool acpi_dev_resource_address_space(struct acpi_resource *ares,
 +                                   struct resource *res);
 +bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
 +                                       struct resource *res);
 +unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable);
 +bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 +                               struct resource *res);
 +
 +struct resource_list_entry {
 +      struct list_head node;
 +      struct resource res;
 +};
 +
 +void acpi_dev_free_resource_list(struct list_head *list);
 +int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
 +                         int (*preproc)(struct acpi_resource *, void *),
 +                         void *preproc_data);
 +
  int acpi_check_resource_conflict(const struct resource *res);
  
  int acpi_check_region(resource_size_t start, resource_size_t n,
  
  int acpi_resources_are_enforced(void);
  
- #ifdef CONFIG_PM_SLEEP
+ #ifdef CONFIG_HIBERNATION
  void __init acpi_no_s4_hw_signature(void);
+ #endif
+ #ifdef CONFIG_PM_SLEEP
  void __init acpi_old_suspend_ordering(void);
  void __init acpi_nvs_nosave(void);
+ void __init acpi_nvs_nosave_s3(void);
  #endif /* CONFIG_PM_SLEEP */
  
  struct acpi_osc_context {
@@@ -386,17 -368,6 +390,17 @@@ extern int acpi_nvs_register(__u64 star
  extern int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
                                    void *data);
  
 +const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
 +                                             const struct device *dev);
 +
 +static inline bool acpi_driver_match_device(struct device *dev,
 +                                          const struct device_driver *drv)
 +{
 +      return !!acpi_match_device(drv->acpi_match_table, dev);
 +}
 +
 +#define ACPI_PTR(_ptr)        (_ptr)
 +
  #else /* !CONFIG_ACPI */
  
  #define acpi_disabled 1
@@@ -451,22 -422,6 +455,22 @@@ static inline int acpi_nvs_for_each_reg
        return 0;
  }
  
 +struct acpi_device_id;
 +
 +static inline const struct acpi_device_id *acpi_match_device(
 +      const struct acpi_device_id *ids, const struct device *dev)
 +{
 +      return NULL;
 +}
 +
 +static inline bool acpi_driver_match_device(struct device *dev,
 +                                          const struct device_driver *drv)
 +{
 +      return false;
 +}
 +
 +#define ACPI_PTR(_ptr)        (NULL)
 +
  #endif        /* !CONFIG_ACPI */
  
  #ifdef CONFIG_ACPI
@@@ -479,41 -434,47 +483,84 @@@ acpi_status acpi_os_prepare_sleep(u8 sl
  #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
  #endif
  
 +#if defined(CONFIG_ACPI) && defined(CONFIG_PM_RUNTIME)
 +int acpi_dev_runtime_suspend(struct device *dev);
 +int acpi_dev_runtime_resume(struct device *dev);
 +int acpi_subsys_runtime_suspend(struct device *dev);
 +int acpi_subsys_runtime_resume(struct device *dev);
 +#else
 +static inline int acpi_dev_runtime_suspend(struct device *dev) { return 0; }
 +static inline int acpi_dev_runtime_resume(struct device *dev) { return 0; }
 +static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; }
 +static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; }
 +#endif
 +
 +#ifdef CONFIG_ACPI_SLEEP
 +int acpi_dev_suspend_late(struct device *dev);
 +int acpi_dev_resume_early(struct device *dev);
 +int acpi_subsys_prepare(struct device *dev);
 +int acpi_subsys_suspend_late(struct device *dev);
 +int acpi_subsys_resume_early(struct device *dev);
 +#else
 +static inline int acpi_dev_suspend_late(struct device *dev) { return 0; }
 +static inline int acpi_dev_resume_early(struct device *dev) { return 0; }
 +static inline int acpi_subsys_prepare(struct device *dev) { return 0; }
 +static inline int acpi_subsys_suspend_late(struct device *dev) { return 0; }
 +static inline int acpi_subsys_resume_early(struct device *dev) { return 0; }
 +#endif
 +
 +#if defined(CONFIG_ACPI) && defined(CONFIG_PM)
 +int acpi_dev_pm_attach(struct device *dev, bool power_on);
 +int acpi_dev_pm_detach(struct device *dev, bool power_off);
 +#else
 +static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
 +{
 +      return -ENODEV;
 +}
 +static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
 +#endif
 +
+ #ifdef CONFIG_ACPI
+ __printf(3, 4)
+ void acpi_handle_printk(const char *level, acpi_handle handle,
+                       const char *fmt, ...);
+ #else /* !CONFIG_ACPI */
+ static inline __printf(3, 4) void
+ acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {}
+ #endif        /* !CONFIG_ACPI */
+ /*
+  * acpi_handle_<level>: Print message with ACPI prefix and object path
+  *
+  * These interfaces acquire the global namespace mutex to obtain an object
+  * path.  In interrupt context, it shows the object path as <n/a>.
+  */
+ #define acpi_handle_emerg(handle, fmt, ...)                           \
+       acpi_handle_printk(KERN_EMERG, handle, fmt, ##__VA_ARGS__)
+ #define acpi_handle_alert(handle, fmt, ...)                           \
+       acpi_handle_printk(KERN_ALERT, handle, fmt, ##__VA_ARGS__)
+ #define acpi_handle_crit(handle, fmt, ...)                            \
+       acpi_handle_printk(KERN_CRIT, handle, fmt, ##__VA_ARGS__)
+ #define acpi_handle_err(handle, fmt, ...)                             \
+       acpi_handle_printk(KERN_ERR, handle, fmt, ##__VA_ARGS__)
+ #define acpi_handle_warn(handle, fmt, ...)                            \
+       acpi_handle_printk(KERN_WARNING, handle, fmt, ##__VA_ARGS__)
+ #define acpi_handle_notice(handle, fmt, ...)                          \
+       acpi_handle_printk(KERN_NOTICE, handle, fmt, ##__VA_ARGS__)
+ #define acpi_handle_info(handle, fmt, ...)                            \
+       acpi_handle_printk(KERN_INFO, handle, fmt, ##__VA_ARGS__)
+ /* REVISIT: Support CONFIG_DYNAMIC_DEBUG when necessary */
+ #if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+ #define acpi_handle_debug(handle, fmt, ...)                           \
+       acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__)
+ #else
+ #define acpi_handle_debug(handle, fmt, ...)                           \
+ ({                                                                    \
+       if (0)                                                          \
+               acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__); \
+       0;                                                              \
+ })
+ #endif
  #endif        /*_LINUX_ACPI_H*/