]> Pileus Git - ~andy/linux/commitdiff
Merge branches 'acpi-processor', 'acpi-hotplug', 'acpi-init', 'acpi-pm' and 'acpica'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 29 Jan 2014 10:47:18 +0000 (11:47 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 29 Jan 2014 10:47:18 +0000 (11:47 +0100)
* acpi-processor:
  ACPI / scan: reduce log level of "ACPI: \_PR_.CPU4: failed to get CPU APIC ID"
  ACPI / processor: Return specific error value when mapping lapic id

* acpi-hotplug:
  ACPI / scan: Clear match_driver flag in acpi_bus_trim()

* acpi-init:
  ACPI / init: Flag use of ACPI and ACPI idioms for power supplies to regulator API

* acpi-pm:
  ACPI / PM: Use ACPI_COMPANION() to get ACPI companions of devices

* acpica:
  ACPICA: Remove bool usage from ACPICA.

1  2  3  4  5  6 
drivers/acpi/acpi_processor.c
drivers/acpi/bus.c
drivers/acpi/device_pm.c
drivers/acpi/processor_core.c
drivers/acpi/scan.c
drivers/acpi/sysfs.c

index c9311be29a64991ee56563c5c2262e541302ebd7,21c0856daad7fbe1d8f32ede9fb1a06afa186f7a,d58a2aba09308a31fd6f80355bba51fb6df6724f,3c1d6b0c09a4b7d1eeeb9347a7c743d1c7487988,3c1d6b0c09a4b7d1eeeb9347a7c743d1c7487988,3c1d6b0c09a4b7d1eeeb9347a7c743d1c7487988..c29c2c3ec0ad8ffc2c6427393593dbf147899d1b
@@@@@@@ -212,7 -212,7 -212,7 -212,7 -212,7 -212,7 +212,7 @@@@@@@ static int acpi_processor_get_info(stru
        union acpi_object object = { 0 };
        struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
        struct acpi_processor *pr = acpi_driver_data(device);
  ----  int cpu_index, device_declaration = 0;
  ++++  int apic_id, cpu_index, device_declaration = 0;
        acpi_status status = AE_OK;
        static int cpu0_initialized;
        unsigned long long value;
                device_declaration = 1;
                pr->acpi_id = value;
        }
  ----  pr->apic_id = acpi_get_apicid(pr->handle, device_declaration,
  ----                                  pr->acpi_id);
  ----  cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id);
      
  ----  /* Handle UP system running SMP kernel, with no LAPIC in MADT */
  ----  if (!cpu0_initialized && (cpu_index == -1) &&
  ----      (num_online_cpus() == 1)) {
  ----          cpu_index = 0;
  ++++  apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id);
  ++++  if (apic_id < 0) {
-               acpi_handle_err(pr->handle, "failed to get CPU APIC ID.\n");
+ ++++          acpi_handle_debug(pr->handle, "failed to get CPU APIC ID.\n");
  ++++          return -ENODEV;
        }
  ++++  pr->apic_id = apic_id;
      
  ----  cpu0_initialized = 1;
  ----
  ++++  cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id);
  ++++  if (!cpu0_initialized) {
  ++++          cpu0_initialized = 1;
  ++++          /* Handle UP system running SMP kernel, with no LAPIC in MADT */
  ++++          if ((cpu_index == -1) && (num_online_cpus() == 1))
  ++++                  cpu_index = 0;
  ++++  }
        pr->id = cpu_index;
      
        /*
                if (ret)
                        return ret;
        }
  ++++
        /*
         * On some boxes several processors use the same processor bus id.
         * But they are located in different scope. For example:
@@@@@@@ -399,7 -399,7 -395,7 -395,7 -395,7 -395,7 +399,7 @@@@@@@ static int acpi_processor_add(struct ac
                goto err;
        }
      
 - ---  result = acpi_bind_one(dev, pr->handle);
 + +++  result = acpi_bind_one(dev, device);
        if (result)
                goto err;
      
diff --combined drivers/acpi/bus.c
index 384da5ab595573a0daf9faf22fa3815889fadcb8,0710004055c809f3059cde2337373503666fd96f,384da5ab595573a0daf9faf22fa3815889fadcb8,296bec89f4a1fb1cc1e213a30ccbdaf8c239ba49,0710004055c809f3059cde2337373503666fd96f,0710004055c809f3059cde2337373503666fd96f..fcb59c21c68d5c53696a29749d88792f58bc4a64
      #include <linux/proc_fs.h>
      #include <linux/acpi.h>
      #include <linux/slab.h>
+++ ++#include <linux/regulator/machine.h>
      #ifdef CONFIG_X86
      #include <asm/mpspec.h>
      #endif
      #include <linux/pci.h>
 - ---#include <acpi/acpi_bus.h>
 - ---#include <acpi/acpi_drivers.h>
      #include <acpi/apei.h>
      #include <linux/dmi.h>
      #include <linux/suspend.h>
@@@@@@@ -50,6 -52,9 -50,6 -53,9 -52,9 -52,9 +51,6 @@@@@@@ struct acpi_device *acpi_root
      struct proc_dir_entry *acpi_root_dir;
      EXPORT_SYMBOL(acpi_root_dir);
      
 - ---#define STRUCT_TO_INT(s)  (*((int*)&s))
 - ---
 - ---
      #ifdef CONFIG_X86
      static int set_copy_dsdt(const struct dmi_system_id *id)
      {
@@@@@@@ -110,16 -115,18 -110,16 -116,18 -115,18 -115,18 +111,16 @@@@@@@ int acpi_bus_get_status(struct acpi_dev
        if (ACPI_FAILURE(status))
                return -ENODEV;
      
 - ---  STRUCT_TO_INT(device->status) = (int) sta;
 + +++  acpi_set_device_status(device, sta);
      
        if (device->status.functional && !device->status.present) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
                       "functional but not present;\n",
 - ---                  device->pnp.bus_id,
 - ---                  (u32) STRUCT_TO_INT(device->status)));
 + +++                  device->pnp.bus_id, (u32)sta));
        }
      
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
 - ---                    device->pnp.bus_id,
 - ---                    (u32) STRUCT_TO_INT(device->status)));
 + +++                    device->pnp.bus_id, (u32)sta));
        return 0;
      }
      EXPORT_SYMBOL(acpi_bus_get_status);
@@@@@@@ -332,6 -339,58 -332,6 -340,58 -339,58 -339,58 +333,6 @@@@@@@ static void acpi_bus_osc_support(void
                                   Notification Handling
         -------------------------------------------------------------------------- */
      
 - ---static void acpi_bus_check_device(acpi_handle handle)
 - ---{
 - ---  struct acpi_device *device;
 - ---  acpi_status status;
 - ---  struct acpi_device_status old_status;
 - ---
 - ---  if (acpi_bus_get_device(handle, &device))
 - ---          return;
 - ---  if (!device)
 - ---          return;
 - ---
 - ---  old_status = device->status;
 - ---
 - ---  /*
 - ---   * Make sure this device's parent is present before we go about
 - ---   * messing with the device.
 - ---   */
 - ---  if (device->parent && !device->parent->status.present) {
 - ---          device->status = device->parent->status;
 - ---          return;
 - ---  }
 - ---
 - ---  status = acpi_bus_get_status(device);
 - ---  if (ACPI_FAILURE(status))
 - ---          return;
 - ---
 - ---  if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status))
 - ---          return;
 - ---
 - ---  /*
 - ---   * Device Insertion/Removal
 - ---   */
 - ---  if ((device->status.present) && !(old_status.present)) {
 - ---          ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n"));
 - ---          /* TBD: Handle device insertion */
 - ---  } else if (!(device->status.present) && (old_status.present)) {
 - ---          ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n"));
 - ---          /* TBD: Handle device removal */
 - ---  }
 - ---}
 - ---
 - ---static void acpi_bus_check_scope(acpi_handle handle)
 - ---{
 - ---  /* Status Change? */
 - ---  acpi_bus_check_device(handle);
 - ---
 - ---  /*
 - ---   * TBD: Enumerate child devices within this device's scope and
 - ---   *       run acpi_bus_check_device()'s on them.
 - ---   */
 - ---}
 - ---
      /**
       * acpi_bus_notify
       * ---------------
@@@@@@@ -348,11 -407,19 -348,11 -408,19 -407,19 -407,19 +349,11 @@@@@@@ static void acpi_bus_notify(acpi_handl
        switch (type) {
      
        case ACPI_NOTIFY_BUS_CHECK:
 - ---          acpi_bus_check_scope(handle);
 - ---          /*
 - ---           * TBD: We'll need to outsource certain events to non-ACPI
 - ---           *      drivers via the device manager (device.c).
 - ---           */
 + +++          /* TBD */
                break;
      
        case ACPI_NOTIFY_DEVICE_CHECK:
 - ---          acpi_bus_check_device(handle);
 - ---          /*
 - ---           * TBD: We'll need to outsource certain events to non-ACPI
 - ---           *      drivers via the device manager (device.c).
 - ---           */
 + +++          /* TBD */
                break;
      
        case ACPI_NOTIFY_DEVICE_WAKE:
@@@@@@@ -509,6 -576,6 -509,6 -577,14 -576,6 -576,6 +510,14 @@@@@@@ void __init acpi_early_init(void
                goto error0;
        }
      
+++ ++  /*
+++ ++   * If the system is using ACPI then we can be reasonably
+++ ++   * confident that any regulators are managed by the firmware
+++ ++   * so tell the regulator core it has everything it needs to
+++ ++   * know.
+++ ++   */
+++ ++  regulator_has_full_constraints();
+++ ++
        return;
      
            error0:
diff --combined drivers/acpi/device_pm.c
index d49f1e46470370908d72b6efb7677d70f80ded98,b3480cf7db1a1d1eba0e8d884cb456f92b76b660,d49f1e46470370908d72b6efb7677d70f80ded98,b3480cf7db1a1d1eba0e8d884cb456f92b76b660,c14aa9a8a1b9e29d3ff9219de38f717ba624cea6,b3480cf7db1a1d1eba0e8d884cb456f92b76b660..c14a00d3dca61e5d943c41d5fe11fb90669550a6
@@@@@@@ -256,8 -256,6 -256,8 -256,6 -256,6 -256,6 +256,8 @@@@@@@ int acpi_bus_init_power(struct acpi_dev
                return -EINVAL;
      
        device->power.state = ACPI_STATE_UNKNOWN;
 + +++  if (!acpi_device_is_present(device))
 + +++          return 0;
      
        result = acpi_device_get_power(device, &state);
        if (result)
@@@@@@@ -304,18 -302,15 -304,18 -302,15 -302,15 -302,15 +304,18 @@@@@@@ int acpi_device_fix_up_power(struct acp
        return ret;
      }
      
 - ---int acpi_bus_update_power(acpi_handle handle, int *state_p)
 + +++int acpi_device_update_power(struct acpi_device *device, int *state_p)
      {
 - ---  struct acpi_device *device;
        int state;
        int result;
      
 - ---  result = acpi_bus_get_device(handle, &device);
 - ---  if (result)
 + +++  if (device->power.state == ACPI_STATE_UNKNOWN) {
 + +++          result = acpi_bus_init_power(device);
 + +++          if (!result && state_p)
 + +++                  *state_p = device->power.state;
 + +++
                return result;
 + +++  }
      
        result = acpi_device_get_power(device, &state);
        if (result)
      
        return 0;
      }
 + +++
 + +++int acpi_bus_update_power(acpi_handle handle, int *state_p)
 + +++{
 + +++  struct acpi_device *device;
 + +++  int result;
 + +++
 + +++  result = acpi_bus_get_device(handle, &device);
 + +++  return result ? result : acpi_device_update_power(device, state_p);
 + +++}
      EXPORT_SYMBOL_GPL(acpi_bus_update_power);
      
      bool acpi_bus_power_manageable(acpi_handle handle)
@@@@@@@ -726,18 -712,18 -726,18 -712,18 -712,6 -712,18 +726,6 @@@@@@@ int acpi_pm_device_sleep_wake(struct de
      }
      #endif /* CONFIG_PM_SLEEP */
      
---- -/**
---- - * acpi_dev_pm_get_node - Get ACPI device node for the given physical device.
---- - * @dev: Device to get the ACPI node for.
---- - */
---- -struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
---- -{
---- -  acpi_handle handle = ACPI_HANDLE(dev);
---- -  struct acpi_device *adev;
---- -
---- -  return handle && !acpi_bus_get_device(handle, &adev) ? adev : NULL;
---- -}
---- -
      /**
       * acpi_dev_pm_low_power - Put ACPI device into a low-power state.
       * @dev: Device to put into a low-power state.
@@@@@@@ -778,7 -764,7 -778,7 -764,7 -752,7 -764,7 +766,7 @@@@@@@ static int acpi_dev_pm_full_power(struc
       */
      int acpi_dev_runtime_suspend(struct device *dev)
      {
---- -  struct acpi_device *adev = acpi_dev_pm_get_node(dev);
++++ +  struct acpi_device *adev = ACPI_COMPANION(dev);
        bool remote_wakeup;
        int error;
      
@@@@@@@ -809,7 -795,7 -809,7 -795,7 -783,7 -795,7 +797,7 @@@@@@@ EXPORT_SYMBOL_GPL(acpi_dev_runtime_susp
       */
      int acpi_dev_runtime_resume(struct device *dev)
      {
---- -  struct acpi_device *adev = acpi_dev_pm_get_node(dev);
++++ +  struct acpi_device *adev = ACPI_COMPANION(dev);
        int error;
      
        if (!adev)
@@@@@@@ -862,7 -848,7 -862,7 -848,7 -836,7 -848,7 +850,7 @@@@@@@ EXPORT_SYMBOL_GPL(acpi_subsys_runtime_r
       */
      int acpi_dev_suspend_late(struct device *dev)
      {
---- -  struct acpi_device *adev = acpi_dev_pm_get_node(dev);
++++ +  struct acpi_device *adev = ACPI_COMPANION(dev);
        u32 target_state;
        bool wakeup;
        int error;
@@@@@@@ -894,7 -880,7 -894,7 -880,7 -868,7 -880,7 +882,7 @@@@@@@ EXPORT_SYMBOL_GPL(acpi_dev_suspend_late
       */
      int acpi_dev_resume_early(struct device *dev)
      {
---- -  struct acpi_device *adev = acpi_dev_pm_get_node(dev);
++++ +  struct acpi_device *adev = ACPI_COMPANION(dev);
        int error;
      
        if (!adev)
@@@@@@@ -985,7 -971,7 -985,7 -971,7 -959,7 -971,7 +973,7 @@@@@@@ static struct dev_pm_domain acpi_genera
       */
      int acpi_dev_pm_attach(struct device *dev, bool power_on)
      {
---- -  struct acpi_device *adev = acpi_dev_pm_get_node(dev);
++++ +  struct acpi_device *adev = ACPI_COMPANION(dev);
      
        if (!adev)
                return -ENODEV;
@@@@@@@ -1017,7 -1003,7 -1017,7 -1003,7 -991,7 -1003,7 +1005,7 @@@@@@@ EXPORT_SYMBOL_GPL(acpi_dev_pm_attach)
       */
      void acpi_dev_pm_detach(struct device *dev, bool power_off)
      {
---- -  struct acpi_device *adev = acpi_dev_pm_get_node(dev);
++++ +  struct acpi_device *adev = ACPI_COMPANION(dev);
      
        if (adev && dev->pm_domain == &acpi_general_pm_domain) {
                dev->pm_domain = NULL;
index 34e7b3c6a08de157c6c962bd0643ddb67176bd5e,24c87efbc1cf9b06ecaf53e096f3546561fc1947,34e7b3c6a08de157c6c962bd0643ddb67176bd5e,b3171f30b319c1244007e686a0b516833443191d,b3171f30b319c1244007e686a0b516833443191d,b3171f30b319c1244007e686a0b516833443191d..a4eea9a508d3efd977fe97563b967b776a49a084
      #include <linux/export.h>
      #include <linux/dmi.h>
      #include <linux/slab.h>
 - ---
 - ---#include <acpi/acpi_drivers.h>
 + +++#include <linux/acpi.h>
      #include <acpi/processor.h>
      
      #include "internal.h"
@@@@@@@ -44,13 -45,13 -44,13 -45,13 -45,13 -45,13 +44,13 @@@@@@@ static int map_lapic_id(struct acpi_sub
                (struct acpi_madt_local_apic *)entry;
      
        if (!(lapic->lapic_flags & ACPI_MADT_ENABLED))
- ----          return 0;
+ ++++          return -ENODEV;
      
        if (lapic->processor_id != acpi_id)
- ----          return 0;
+ ++++          return -EINVAL;
      
        *apic_id = lapic->id;
- ----  return 1;
+ ++++  return 0;
      }
      
      static int map_x2apic_id(struct acpi_subtable_header *entry,
                (struct acpi_madt_local_x2apic *)entry;
      
        if (!(apic->lapic_flags & ACPI_MADT_ENABLED))
- ----          return 0;
+ ++++          return -ENODEV;
      
        if (device_declaration && (apic->uid == acpi_id)) {
                *apic_id = apic->local_apic_id;
- ----          return 1;
+ ++++          return 0;
        }
      
- ----  return 0;
+ ++++  return -EINVAL;
      }
      
      static int map_lsapic_id(struct acpi_subtable_header *entry,
                (struct acpi_madt_local_sapic *)entry;
      
        if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))
- ----          return 0;
+ ++++          return -ENODEV;
      
        if (device_declaration) {
                if ((entry->length < 16) || (lsapic->uid != acpi_id))
- ----                  return 0;
+ ++++                  return -EINVAL;
        } else if (lsapic->processor_id != acpi_id)
- ----          return 0;
+ ++++          return -EINVAL;
      
        *apic_id = (lsapic->id << 8) | lsapic->eid;
- ----  return 1;
+ ++++  return 0;
      }
      
      static int map_madt_entry(int type, u32 acpi_id)
                struct acpi_subtable_header *header =
                        (struct acpi_subtable_header *)entry;
                if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
- ----                  if (map_lapic_id(header, acpi_id, &apic_id))
+ ++++                  if (!map_lapic_id(header, acpi_id, &apic_id))
                                break;
                } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
- ----                  if (map_x2apic_id(header, type, acpi_id, &apic_id))
+ ++++                  if (!map_x2apic_id(header, type, acpi_id, &apic_id))
                                break;
                } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
- ----                  if (map_lsapic_id(header, type, acpi_id, &apic_id))
+ ++++                  if (!map_lsapic_id(header, type, acpi_id, &apic_id))
                                break;
                }
                entry += header->length;
diff --combined drivers/acpi/scan.c
index e00365ccb89750e8e1dcd1987ad800de65f9bbed,fd39459926b1564c2faa3d367a4dbbf05aa60031,089dc403c43bb1485a56316e18b6f97c59d93b4d,fd39459926b1564c2faa3d367a4dbbf05aa60031,fd39459926b1564c2faa3d367a4dbbf05aa60031,fd39459926b1564c2faa3d367a4dbbf05aa60031..7384158c7f8770ddc4cd78d1570171a4cce9aae9
      #include <linux/dmi.h>
      #include <linux/nls.h>
      
 - ---#include <acpi/acpi_drivers.h>
 + +++#include <asm/pgtable.h>
      
      #include "internal.h"
      
      #define _COMPONENT                ACPI_BUS_COMPONENT
      ACPI_MODULE_NAME("scan");
 - ---#define STRUCT_TO_INT(s)  (*((int*)&s))
      extern struct acpi_device *acpi_root;
      
      #define ACPI_BUS_CLASS                    "system_bus"
      
      #define ACPI_IS_ROOT_DEVICE(device)    (!(device)->parent)
      
 + +++#define INVALID_ACPI_HANDLE       ((acpi_handle)empty_zero_page)
 + +++
      /*
       * If set, devices will be hot-removed even if they cannot be put offline
       * gracefully (from the kernel's standpoint).
@@@@@@@ -86,9 -85,6 -86,6 -85,6 -85,6 -85,6 +86,9 @@@@@@@ int acpi_scan_add_handler_with_hotplug(
       * Creates hid/cid(s) string needed for modalias and uevent
       * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
       * char *modalias: "acpi:IBM0001:ACPI0001"
 +++++ * Return: 0: no _HID and no _CID
 +++++ *         -EINVAL: output error
 +++++ *         -ENOMEM: output is truncated
      */
      static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
                           int size)
      
        list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
                count = snprintf(&modalias[len], size, "%s:", id->id);
 -----          if (count < 0 || count >= size)
 -----                  return -EINVAL;
 +++++          if (count < 0)
 +++++                  return EINVAL;
 +++++          if (count >= size)
 +++++                  return -ENOMEM;
                len += count;
                size -= count;
        }
        return len;
      }
      
 +++++/*
 +++++ * Creates uevent modalias field for ACPI enumerated devices.
 +++++ * Because the other buses does not support ACPI HIDs & CIDs.
 +++++ * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
 +++++ * "acpi:IBM0001:ACPI0001"
 +++++ */
 +++++int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
 +++++{
 +++++  struct acpi_device *acpi_dev;
 +++++  int len;
 +++++
 +++++  acpi_dev = ACPI_COMPANION(dev);
 +++++  if (!acpi_dev)
 +++++          return -ENODEV;
 +++++
 +++++  /* Fall back to bus specific way of modalias exporting */
 +++++  if (list_empty(&acpi_dev->pnp.ids))
 +++++          return -ENODEV;
 +++++
 +++++  if (add_uevent_var(env, "MODALIAS="))
 +++++          return -ENOMEM;
 +++++  len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
 +++++                          sizeof(env->buf) - env->buflen);
 +++++  if (len <= 0)
 +++++          return len;
 +++++  env->buflen += len;
 +++++  return 0;
 +++++}
 +++++EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias);
 +++++
 +++++/*
 +++++ * Creates modalias sysfs attribute for ACPI enumerated devices.
 +++++ * Because the other buses does not support ACPI HIDs & CIDs.
 +++++ * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
 +++++ * "acpi:IBM0001:ACPI0001"
 +++++ */
 +++++int acpi_device_modalias(struct device *dev, char *buf, int size)
 +++++{
 +++++  struct acpi_device *acpi_dev;
 +++++  int len;
 +++++
 +++++  acpi_dev = ACPI_COMPANION(dev);
 +++++  if (!acpi_dev)
 +++++          return -ENODEV;
 +++++
 +++++  /* Fall back to bus specific way of modalias exporting */
 +++++  if (list_empty(&acpi_dev->pnp.ids))
 +++++          return -ENODEV;
 +++++
 +++++  len = create_modalias(acpi_dev, buf, size -1);
 +++++  if (len <= 0)
 +++++          return len;
 +++++  buf[len++] = '\n';
 +++++  return len;
 +++++}
 +++++EXPORT_SYMBOL_GPL(acpi_device_modalias);
 +++++
      static ssize_t
      acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) {
        struct acpi_device *acpi_dev = to_acpi_device(dev);
        int len;
      
 -----  /* Device has no HID and no CID or string is >1024 */
        len = create_modalias(acpi_dev, buf, 1024);
        if (len <= 0)
 -----          return 0;
 +++++          return len;
        buf[len++] = '\n';
        return len;
      }
      static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
      
 + +++bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent)
 + +++{
 + +++  struct acpi_device_physical_node *pn;
 + +++  bool offline = true;
 + +++
 + +++  mutex_lock(&adev->physical_node_lock);
 + +++
 + +++  list_for_each_entry(pn, &adev->physical_node_list, node)
 + +++          if (device_supports_offline(pn->dev) && !pn->dev->offline) {
 + +++                  if (uevent)
 + +++                          kobject_uevent(&pn->dev->kobj, KOBJ_CHANGE);
 + +++
 + +++                  offline = false;
 + +++                  break;
 + +++          }
 + +++
 + +++  mutex_unlock(&adev->physical_node_lock);
 + +++  return offline;
 + +++}
 + +++
      static acpi_status acpi_bus_offline(acpi_handle handle, u32 lvl, void *data,
                                    void **ret_p)
      {
@@@@@@@ -277,11 -195,19 -216,11 -195,19 -195,19 -195,19 +277,11 @@@@@@@ static acpi_status acpi_bus_online(acpi
        return AE_OK;
      }
      
 - ---static int acpi_scan_hot_remove(struct acpi_device *device)
 + +++static int acpi_scan_try_to_offline(struct acpi_device *device)
      {
        acpi_handle handle = device->handle;
 - ---  struct device *errdev;
 + +++  struct device *errdev = NULL;
        acpi_status status;
 - ---  unsigned long long sta;
 - ---
 - ---  /* If there is no handle, the device node has been unregistered. */
 - ---  if (!handle) {
 - ---          dev_dbg(&device->dev, "ACPI handle missing\n");
 - ---          put_device(&device->dev);
 - ---          return -EINVAL;
 - ---  }
      
        /*
         * Carry out two passes here and ignore errors in the first pass,
         *
         * If the first pass is successful, the second one isn't needed, though.
         */
 - ---  errdev = NULL;
        status = acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
                                     NULL, acpi_bus_offline, (void *)false,
                                     (void **)&errdev);
                dev_warn(errdev, "Offline disabled.\n");
                acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
                                    acpi_bus_online, NULL, NULL, NULL);
 - ---          put_device(&device->dev);
                return -EPERM;
        }
        acpi_bus_offline(handle, 0, (void *)false, (void **)&errdev);
                        acpi_walk_namespace(ACPI_TYPE_ANY, handle,
                                            ACPI_UINT32_MAX, acpi_bus_online,
                                            NULL, NULL, NULL);
 - ---                  put_device(&device->dev);
                        return -EBUSY;
                }
        }
 + +++  return 0;
 + +++}
 + +++
 + +++static int acpi_scan_hot_remove(struct acpi_device *device)
 + +++{
 + +++  acpi_handle handle = device->handle;
 + +++  unsigned long long sta;
 + +++  acpi_status status;
 + +++
 + +++  if (device->handler->hotplug.demand_offline && !acpi_force_hot_remove) {
 + +++          if (!acpi_scan_is_offline(device, true))
 + +++                  return -EBUSY;
 + +++  } else {
 + +++          int error = acpi_scan_try_to_offline(device);
 + +++          if (error)
 + +++                  return error;
 + +++  }
      
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                "Hot-removing device %s...\n", dev_name(&device->dev)));
      
        acpi_bus_trim(device);
      
 - ---  /* Device node has been unregistered. */
 - ---  put_device(&device->dev);
 - ---  device = NULL;
 - ---
        acpi_evaluate_lck(handle, 0);
        /*
         * TBD: _EJD support.
        return 0;
      }
      
 - ---void acpi_bus_device_eject(void *data, u32 ost_src)
 + +++static int acpi_scan_device_not_present(struct acpi_device *adev)
      {
 - ---  struct acpi_device *device = data;
 - ---  acpi_handle handle = device->handle;
 - ---  u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
 - ---  int error;
 + +++  if (!acpi_device_enumerated(adev)) {
 + +++          dev_warn(&adev->dev, "Still not present\n");
 + +++          return -EALREADY;
 + +++  }
 + +++  acpi_bus_trim(adev);
 + +++  return 0;
 + +++}
      
 - ---  lock_device_hotplug();
 - ---  mutex_lock(&acpi_scan_lock);
 + +++static int acpi_scan_device_check(struct acpi_device *adev)
 + +++{
 + +++  int error;
      
 - ---  if (ost_src == ACPI_NOTIFY_EJECT_REQUEST)
 - ---          acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST,
 - ---                                    ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
 + +++  acpi_bus_get_status(adev);
 + +++  if (adev->status.present || adev->status.functional) {
 + +++          /*
 + +++           * This function is only called for device objects for which
 + +++           * matching scan handlers exist.  The only situation in which
 + +++           * the scan handler is not attached to this device object yet
 + +++           * is when the device has just appeared (either it wasn't
 + +++           * present at all before or it was removed and then added
 + +++           * again).
 + +++           */
 + +++          if (adev->handler) {
 + +++                  dev_warn(&adev->dev, "Already enumerated\n");
 + +++                  return -EALREADY;
 + +++          }
 + +++          error = acpi_bus_scan(adev->handle);
 + +++          if (error) {
 + +++                  dev_warn(&adev->dev, "Namespace scan failure\n");
 + +++                  return error;
 + +++          }
 + +++          if (!adev->handler) {
 + +++                  dev_warn(&adev->dev, "Enumeration failure\n");
 + +++                  error = -ENODEV;
 + +++          }
 + +++  } else {
 + +++          error = acpi_scan_device_not_present(adev);
 + +++  }
 + +++  return error;
 + +++}
      
 - ---  if (device->handler && device->handler->hotplug.mode == AHM_CONTAINER)
 - ---          kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
 + +++static int acpi_scan_bus_check(struct acpi_device *adev)
 + +++{
 + +++  struct acpi_scan_handler *handler = adev->handler;
 + +++  struct acpi_device *child;
 + +++  int error;
      
 - ---  error = acpi_scan_hot_remove(device);
 - ---  if (error == -EPERM) {
 - ---          goto err_support;
 - ---  } else if (error) {
 - ---          goto err_out;
 + +++  acpi_bus_get_status(adev);
 + +++  if (!(adev->status.present || adev->status.functional)) {
 + +++          acpi_scan_device_not_present(adev);
 + +++          return 0;
        }
 + +++  if (handler && handler->hotplug.scan_dependent)
 + +++          return handler->hotplug.scan_dependent(adev);
      
 - --- out:
 - ---  mutex_unlock(&acpi_scan_lock);
 - ---  unlock_device_hotplug();
 - ---  return;
 - ---
 - --- err_support:
 - ---  ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
 - --- err_out:
 - ---  acpi_evaluate_hotplug_ost(handle, ost_src, ost_code, NULL);
 - ---  goto out;
 + +++  error = acpi_bus_scan(adev->handle);
 + +++  if (error) {
 + +++          dev_warn(&adev->dev, "Namespace scan failure\n");
 + +++          return error;
 + +++  }
 + +++  list_for_each_entry(child, &adev->children, node) {
 + +++          error = acpi_scan_bus_check(child);
 + +++          if (error)
 + +++                  return error;
 + +++  }
 + +++  return 0;
      }
      
 - ---static void acpi_scan_bus_device_check(void *data, u32 ost_source)
 + +++static void acpi_device_hotplug(void *data, u32 src)
      {
 - ---  acpi_handle handle = data;
 - ---  struct acpi_device *device = NULL;
        u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
 + +++  struct acpi_device *adev = data;
        int error;
      
        lock_device_hotplug();
        mutex_lock(&acpi_scan_lock);
      
 - ---  if (ost_source != ACPI_NOTIFY_BUS_CHECK) {
 - ---          acpi_bus_get_device(handle, &device);
 - ---          if (device) {
 - ---                  dev_warn(&device->dev, "Attempt to re-insert\n");
 - ---                  goto out;
 - ---          }
 - ---  }
 - ---  error = acpi_bus_scan(handle);
 - ---  if (error) {
 - ---          acpi_handle_warn(handle, "Namespace scan failure\n");
 - ---          goto out;
 - ---  }
 - ---  error = acpi_bus_get_device(handle, &device);
 - ---  if (error) {
 - ---          acpi_handle_warn(handle, "Missing device node object\n");
 + +++  /*
 + +++   * The device object's ACPI handle cannot become invalid as long as we
 + +++   * are holding acpi_scan_lock, but it may have become invalid before
 + +++   * that lock was acquired.
 + +++   */
 + +++  if (adev->handle == INVALID_ACPI_HANDLE)
                goto out;
 - ---  }
 - ---  ost_code = ACPI_OST_SC_SUCCESS;
 - ---  if (device->handler && device->handler->hotplug.mode == AHM_CONTAINER)
 - ---          kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
      
 - --- out:
 - ---  acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL);
 - ---  mutex_unlock(&acpi_scan_lock);
 - ---  unlock_device_hotplug();
 - ---}
 - ---
 - ---static void acpi_hotplug_unsupported(acpi_handle handle, u32 type)
 - ---{
 - ---  u32 ost_status;
 - ---
 - ---  switch (type) {
 + +++  switch (src) {
        case ACPI_NOTIFY_BUS_CHECK:
 - ---          acpi_handle_debug(handle,
 - ---                  "ACPI_NOTIFY_BUS_CHECK event: unsupported\n");
 - ---          ost_status = ACPI_OST_SC_INSERT_NOT_SUPPORTED;
 + +++          error = acpi_scan_bus_check(adev);
                break;
        case ACPI_NOTIFY_DEVICE_CHECK:
 - ---          acpi_handle_debug(handle,
 - ---                  "ACPI_NOTIFY_DEVICE_CHECK event: unsupported\n");
 - ---          ost_status = ACPI_OST_SC_INSERT_NOT_SUPPORTED;
 + +++          error = acpi_scan_device_check(adev);
                break;
        case ACPI_NOTIFY_EJECT_REQUEST:
 - ---          acpi_handle_debug(handle,
 - ---                  "ACPI_NOTIFY_EJECT_REQUEST event: unsupported\n");
 - ---          ost_status = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
 + +++  case ACPI_OST_EC_OSPM_EJECT:
 + +++          error = acpi_scan_hot_remove(adev);
                break;
        default:
 - ---          /* non-hotplug event; possibly handled by other handler */
 - ---          return;
 + +++          error = -EINVAL;
 + +++          break;
        }
 + +++  if (!error)
 + +++          ost_code = ACPI_OST_SC_SUCCESS;
      
 - ---  acpi_evaluate_hotplug_ost(handle, type, ost_status, NULL);
 + +++ out:
 + +++  acpi_evaluate_hotplug_ost(adev->handle, src, ost_code, NULL);
 + +++  put_device(&adev->dev);
 + +++  mutex_unlock(&acpi_scan_lock);
 + +++  unlock_device_hotplug();
      }
      
      static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
      {
 + +++  u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
        struct acpi_scan_handler *handler = data;
        struct acpi_device *adev;
        acpi_status status;
      
 - ---  if (!handler->hotplug.enabled)
 - ---          return acpi_hotplug_unsupported(handle, type);
 + +++  if (acpi_bus_get_device(handle, &adev))
 + +++          goto err_out;
      
        switch (type) {
        case ACPI_NOTIFY_BUS_CHECK:
                break;
        case ACPI_NOTIFY_EJECT_REQUEST:
                acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n");
 - ---          if (acpi_bus_get_device(handle, &adev))
 + +++          if (!handler->hotplug.enabled) {
 + +++                  acpi_handle_err(handle, "Eject disabled\n");
 + +++                  ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
                        goto err_out;
 - ---
 - ---          get_device(&adev->dev);
 - ---          status = acpi_hotplug_execute(acpi_bus_device_eject, adev, type);
 - ---          if (ACPI_SUCCESS(status))
 - ---                  return;
 - ---
 - ---          put_device(&adev->dev);
 - ---          goto err_out;
 + +++          }
 + +++          acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST,
 + +++                                    ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
 + +++          break;
        default:
                /* non-hotplug event; possibly handled by other handler */
                return;
        }
 - ---  status = acpi_hotplug_execute(acpi_scan_bus_device_check, handle, type);
 + +++  get_device(&adev->dev);
 + +++  status = acpi_hotplug_execute(acpi_device_hotplug, adev, type);
        if (ACPI_SUCCESS(status))
                return;
      
 + +++  put_device(&adev->dev);
 + +++
       err_out:
 - ---  acpi_evaluate_hotplug_ost(handle, type,
 - ---                            ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL);
 + +++  acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
      }
      
      static ssize_t real_power_state_show(struct device *dev,
@@@@@@@ -571,7 -475,7 -510,7 -475,7 -475,7 -475,7 +571,7 @@@@@@@ acpi_eject_store(struct device *d, stru
        acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT,
                                  ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
        get_device(&acpi_device->dev);
 - ---  status = acpi_hotplug_execute(acpi_bus_device_eject, acpi_device,
 + +++  status = acpi_hotplug_execute(acpi_device_hotplug, acpi_device,
                                      ACPI_OST_EC_OSPM_EJECT);
        if (ACPI_SUCCESS(status))
                return count;
@@@@@@@ -663,20 -567,6 -602,20 -567,6 -567,6 -567,6 +663,20 @@@@@@@ acpi_device_sun_show(struct device *dev
      }
      static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL);
      
 + +++static ssize_t status_show(struct device *dev, struct device_attribute *attr,
 + +++                          char *buf) {
 + +++  struct acpi_device *acpi_dev = to_acpi_device(dev);
 + +++  acpi_status status;
 + +++  unsigned long long sta;
 + +++
 + +++  status = acpi_evaluate_integer(acpi_dev->handle, "_STA", NULL, &sta);
 + +++  if (ACPI_FAILURE(status))
 + +++          return -ENODEV;
 + +++
 + +++  return sprintf(buf, "%llu\n", sta);
 + +++}
 + +++static DEVICE_ATTR_RO(status);
 + +++
      static int acpi_device_setup_files(struct acpi_device *dev)
      {
        struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
                dev->pnp.sun = (unsigned long)-1;
        }
      
 + +++  if (acpi_has_method(dev->handle, "_STA")) {
 + +++          result = device_create_file(&dev->dev, &dev_attr_status);
 + +++          if (result)
 + +++                  goto end;
 + +++  }
 + +++
              /*
               * If device has _EJ0, 'eject' file is created that is used to trigger
               * hot-removal function from userland.
@@@@@@@ -793,8 -677,6 -732,8 -677,6 -677,6 -677,6 +793,8 @@@@@@@ static void acpi_device_remove_files(st
                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 (acpi_has_method(dev->handle, "_STA"))
 + +++          device_remove_file(&dev->dev, &dev_attr_status);
        if (dev->handle)
                device_remove_file(&dev->dev, &dev_attr_path);
      }
@@@@@@@ -900,8 -782,8 -839,8 -782,8 -782,8 -782,8 +900,8 @@@@@@@ static int acpi_device_uevent(struct de
                return -ENOMEM;
        len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
                              sizeof(env->buf) - env->buflen);
 -----  if (len >= (sizeof(env->buf) - env->buflen))
 -----          return -ENOMEM;
 +++++  if (len <= 0)
 +++++          return len;
        env->buflen += len;
        return 0;
      }
@@@@@@@ -1025,91 -907,9 -964,91 -907,9 -907,9 -907,9 +1025,91 @@@@@@@ struct bus_type acpi_bus_type = 
        .uevent         = acpi_device_uevent,
      };
      
 - ---static void acpi_bus_data_handler(acpi_handle handle, void *context)
 + +++static void acpi_device_del(struct acpi_device *device)
 + +++{
 + +++  mutex_lock(&acpi_device_lock);
 + +++  if (device->parent)
 + +++          list_del(&device->node);
 + +++
 + +++  list_del(&device->wakeup_list);
 + +++  mutex_unlock(&acpi_device_lock);
 + +++
 + +++  acpi_power_add_remove_device(device, false);
 + +++  acpi_device_remove_files(device);
 + +++  if (device->remove)
 + +++          device->remove(device);
 + +++
 + +++  device_del(&device->dev);
 + +++}
 + +++
 + +++static LIST_HEAD(acpi_device_del_list);
 + +++static DEFINE_MUTEX(acpi_device_del_lock);
 + +++
 + +++static void acpi_device_del_work_fn(struct work_struct *work_not_used)
 + +++{
 + +++  for (;;) {
 + +++          struct acpi_device *adev;
 + +++
 + +++          mutex_lock(&acpi_device_del_lock);
 + +++
 + +++          if (list_empty(&acpi_device_del_list)) {
 + +++                  mutex_unlock(&acpi_device_del_lock);
 + +++                  break;
 + +++          }
 + +++          adev = list_first_entry(&acpi_device_del_list,
 + +++                                  struct acpi_device, del_list);
 + +++          list_del(&adev->del_list);
 + +++
 + +++          mutex_unlock(&acpi_device_del_lock);
 + +++
 + +++          acpi_device_del(adev);
 + +++          /*
 + +++           * Drop references to all power resources that might have been
 + +++           * used by the device.
 + +++           */
 + +++          acpi_power_transition(adev, ACPI_STATE_D3_COLD);
 + +++          put_device(&adev->dev);
 + +++  }
 + +++}
 + +++
 + +++/**
 + +++ * acpi_scan_drop_device - Drop an ACPI device object.
 + +++ * @handle: Handle of an ACPI namespace node, not used.
 + +++ * @context: Address of the ACPI device object to drop.
 + +++ *
 + +++ * This is invoked by acpi_ns_delete_node() during the removal of the ACPI
 + +++ * namespace node the device object pointed to by @context is attached to.
 + +++ *
 + +++ * The unregistration is carried out asynchronously to avoid running
 + +++ * acpi_device_del() under the ACPICA's namespace mutex and the list is used to
 + +++ * ensure the correct ordering (the device objects must be unregistered in the
 + +++ * same order in which the corresponding namespace nodes are deleted).
 + +++ */
 + +++static void acpi_scan_drop_device(acpi_handle handle, void *context)
      {
 - ---  /* Intentionally empty. */
 + +++  static DECLARE_WORK(work, acpi_device_del_work_fn);
 + +++  struct acpi_device *adev = context;
 + +++
 + +++  mutex_lock(&acpi_device_del_lock);
 + +++
 + +++  /*
 + +++   * Use the ACPI hotplug workqueue which is ordered, so this work item
 + +++   * won't run after any hotplug work items submitted subsequently.  That
 + +++   * prevents attempts to register device objects identical to those being
 + +++   * deleted from happening concurrently (such attempts result from
 + +++   * hotplug events handled via the ACPI hotplug workqueue).  It also will
 + +++   * run after all of the work items submitted previosuly, which helps
 + +++   * those work items to ensure that they are not accessing stale device
 + +++   * objects.
 + +++   */
 + +++  if (list_empty(&acpi_device_del_list))
 + +++          acpi_queue_hotplug_work(&work);
 + +++
 + +++  list_add_tail(&adev->del_list, &acpi_device_del_list);
 + +++  /* Make acpi_ns_validate_handle() return NULL for this handle. */
 + +++  adev->handle = INVALID_ACPI_HANDLE;
 + +++
 + +++  mutex_unlock(&acpi_device_del_lock);
      }
      
      int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
        if (!device)
                return -EINVAL;
      
 - ---  status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device);
 + +++  status = acpi_get_data(handle, acpi_scan_drop_device, (void **)device);
        if (ACPI_FAILURE(status) || !*device) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n",
                                  handle));
@@@@@@@ -1139,7 -939,7 -1078,7 -939,7 -939,7 -939,7 +1139,7 @@@@@@@ int acpi_device_add(struct acpi_device 
        if (device->handle) {
                acpi_status status;
      
 - ---          status = acpi_attach_data(device->handle, acpi_bus_data_handler,
 + +++          status = acpi_attach_data(device->handle, acpi_scan_drop_device,
                                          device);
                if (ACPI_FAILURE(status)) {
                        acpi_handle_err(device->handle,
        INIT_LIST_HEAD(&device->node);
        INIT_LIST_HEAD(&device->wakeup_list);
        INIT_LIST_HEAD(&device->physical_node_list);
 + +++  INIT_LIST_HEAD(&device->del_list);
        mutex_init(&device->physical_node_lock);
      
        new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
        mutex_unlock(&acpi_device_lock);
      
       err_detach:
 - ---  acpi_detach_data(device->handle, acpi_bus_data_handler);
 + +++  acpi_detach_data(device->handle, acpi_scan_drop_device);
        return result;
      }
      
 - ---static void acpi_device_unregister(struct acpi_device *device)
 - ---{
 - ---  mutex_lock(&acpi_device_lock);
 - ---  if (device->parent)
 - ---          list_del(&device->node);
 - ---
 - ---  list_del(&device->wakeup_list);
 - ---  mutex_unlock(&acpi_device_lock);
 - ---
 - ---  acpi_detach_data(device->handle, acpi_bus_data_handler);
 - ---
 - ---  acpi_power_add_remove_device(device, false);
 - ---  acpi_device_remove_files(device);
 - ---  if (device->remove)
 - ---          device->remove(device);
 - ---
 - ---  device_del(&device->dev);
 - ---  /*
 - ---   * Transition the device to D3cold to drop the reference counts of all
 - ---   * power resources the device depends on and turn off the ones that have
 - ---   * no more references.
 - ---   */
 - ---  acpi_device_set_power(device, ACPI_STATE_D3_COLD);
 - ---  device->handle = NULL;
 - ---  put_device(&device->dev);
 - ---}
 - ---
      /* --------------------------------------------------------------------------
                                       Driver Management
         -------------------------------------------------------------------------- */
@@@@@@@ -1798,13 -1624,11 -1737,13 -1624,11 -1624,11 -1624,11 +1798,13 @@@@@@@ void acpi_init_device_object(struct acp
        device->device_type = type;
        device->handle = handle;
        device->parent = acpi_bus_get_parent(handle);
 - ---  STRUCT_TO_INT(device->status) = sta;
 + +++  acpi_set_device_status(device, sta);
        acpi_device_get_busid(device);
        acpi_set_pnp_ids(handle, &device->pnp, type);
        acpi_bus_get_flags(device);
        device->flags.match_driver = false;
 + +++  device->flags.initialized = true;
 + +++  device->flags.visited = false;
        device_initialize(&device->dev);
        dev_set_uevent_suppress(&device->dev, true);
      }
@@@@@@@ -1889,15 -1713,6 -1828,15 -1713,6 -1713,6 -1713,6 +1889,15 @@@@@@@ static int acpi_bus_type_and_status(acp
        return 0;
      }
      
 + +++bool acpi_device_is_present(struct acpi_device *adev)
 + +++{
 + +++  if (adev->status.present || adev->status.functional)
 + +++          return true;
 + +++
 + +++  adev->flags.initialized = false;
 + +++  return false;
 + +++}
 + +++
      static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
                                       char *idstr,
                                       const struct acpi_device_id **matchid)
@@@@@@@ -1957,7 -1772,7 -1896,7 -1772,7 -1772,7 -1772,7 +1957,7 @@@@@@@ static void acpi_scan_init_hotplug(acpi
         */
        list_for_each_entry(hwid, &pnp.ids, list) {
                handler = acpi_scan_match_handler(hwid->id, NULL);
 - ---          if (handler && !handler->hotplug.ignore) {
 + +++          if (handler) {
                        acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
                                        acpi_hotplug_notify_cb, handler);
                        break;
@@@@@@@ -1991,6 -1806,18 -1930,6 -1806,18 -1806,18 -1806,18 +1991,6 @@@@@@@ static acpi_status acpi_bus_check_add(a
      
        acpi_scan_init_hotplug(handle, type);
      
 - ---  if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
 - ---      !(sta & ACPI_STA_DEVICE_FUNCTIONING)) {
 - ---          struct acpi_device_wakeup wakeup;
 - ---
 - ---          if (acpi_has_method(handle, "_PRW")) {
 - ---                  acpi_bus_extract_wakeup_device_power_package(handle,
 - ---                                                               &wakeup);
 - ---                  acpi_power_resources_list_free(&wakeup.resources);
 - ---          }
 - ---          return AE_CTRL_DEPTH;
 - ---  }
 - ---
        acpi_add_single_object(&device, handle, type, sta);
        if (!device)
                return AE_CTRL_DEPTH;
@@@@@@@ -2025,40 -1852,36 -1964,40 -1852,36 -1852,36 -1852,36 +2025,40 @@@@@@@ static int acpi_scan_attach_handler(str
        return ret;
      }
      
 - ---static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used,
 - ---                                    void *not_used, void **ret_not_used)
 + +++static void acpi_bus_attach(struct acpi_device *device)
      {
 - ---  struct acpi_device *device;
 - ---  unsigned long long sta_not_used;
 + +++  struct acpi_device *child;
        int ret;
      
 - ---  /*
 - ---   * Ignore errors ignored by acpi_bus_check_add() to avoid terminating
 - ---   * namespace walks prematurely.
 - ---   */
 - ---  if (acpi_bus_type_and_status(handle, &ret, &sta_not_used))
 - ---          return AE_OK;
 - ---
 - ---  if (acpi_bus_get_device(handle, &device))
 - ---          return AE_CTRL_DEPTH;
 - ---
 + +++  acpi_bus_get_status(device);
 + +++  /* Skip devices that are not present. */
 + +++  if (!acpi_device_is_present(device)) {
 + +++          device->flags.visited = false;
 + +++          return;
 + +++  }
        if (device->handler)
 - ---          return AE_OK;
 + +++          goto ok;
      
 + +++  if (!device->flags.initialized) {
 + +++          acpi_bus_update_power(device, NULL);
 + +++          device->flags.initialized = true;
 + +++  }
 + +++  device->flags.visited = false;
        ret = acpi_scan_attach_handler(device);
        if (ret < 0)
 - ---          return AE_CTRL_DEPTH;
 + +++          return;
      
        device->flags.match_driver = true;
 - ---  if (ret > 0)
 - ---          return AE_OK;
 + +++  if (!ret) {
 + +++          ret = device_attach(&device->dev);
 + +++          if (ret < 0)
 + +++                  return;
 + +++  }
 + +++  device->flags.visited = true;
      
 - ---  ret = device_attach(&device->dev);
 - ---  return ret >= 0 ? AE_OK : AE_CTRL_DEPTH;
 + +++ ok:
 + +++  list_for_each_entry(child, &device->children, node)
 + +++          acpi_bus_attach(child);
      }
      
      /**
      int acpi_bus_scan(acpi_handle handle)
      {
        void *device = NULL;
 - ---  int error = 0;
      
        if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device)))
                acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
                                    acpi_bus_check_add, NULL, NULL, &device);
      
 - ---  if (!device)
 - ---          error = -ENODEV;
 - ---  else if (ACPI_SUCCESS(acpi_bus_device_attach(handle, 0, NULL, NULL)))
 - ---          acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
 - ---                              acpi_bus_device_attach, NULL, NULL, NULL);
 - ---
 - ---  return error;
 - ---}
 - ---EXPORT_SYMBOL(acpi_bus_scan);
 - ---
 - ---static acpi_status acpi_bus_device_detach(acpi_handle handle, u32 lvl_not_used,
 - ---                                    void *not_used, void **ret_not_used)
 - ---{
 - ---  struct acpi_device *device = NULL;
 - ---
 - ---  if (!acpi_bus_get_device(handle, &device)) {
 - ---          struct acpi_scan_handler *dev_handler = device->handler;
 - ---
 - ---          if (dev_handler) {
 - ---                  if (dev_handler->detach)
 - ---                          dev_handler->detach(device);
 - ---
 - ---                  device->handler = NULL;
 - ---          } else {
 - ---                  device_release_driver(&device->dev);
 - ---          }
 + +++  if (device) {
 + +++          acpi_bus_attach(device);
 + +++          return 0;
        }
 - ---  return AE_OK;
 - ---}
 - ---
 - ---static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used,
 - ---                             void *not_used, void **ret_not_used)
 - ---{
 - ---  struct acpi_device *device = NULL;
 - ---
 - ---  if (!acpi_bus_get_device(handle, &device))
 - ---          acpi_device_unregister(device);
 - ---
 - ---  return AE_OK;
 + +++  return -ENODEV;
      }
 + +++EXPORT_SYMBOL(acpi_bus_scan);
      
      /**
 - --- * acpi_bus_trim - Remove ACPI device node and all of its descendants
 - --- * @start: Root of the ACPI device nodes subtree to remove.
 + +++ * acpi_bus_trim - Detach scan handlers and drivers from ACPI device objects.
 + +++ * @adev: Root of the ACPI namespace scope to walk.
       *
       * Must be called under acpi_scan_lock.
       */
 - ---void acpi_bus_trim(struct acpi_device *start)
 + +++void acpi_bus_trim(struct acpi_device *adev)
      {
 + +++  struct acpi_scan_handler *handler = adev->handler;
 + +++  struct acpi_device *child;
 + +++
 + +++  list_for_each_entry_reverse(child, &adev->children, node)
 + +++          acpi_bus_trim(child);
 + +++
++ +++  adev->flags.match_driver = false;
 + +++  if (handler) {
 + +++          if (handler->detach)
 + +++                  handler->detach(adev);
 + +++
 + +++          adev->handler = NULL;
 + +++  } else {
 + +++          device_release_driver(&adev->dev);
 + +++  }
        /*
 - ---   * Execute acpi_bus_device_detach() as a post-order callback to detach
 - ---   * all ACPI drivers from the device nodes being removed.
 - ---   */
 - ---  acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL,
 - ---                      acpi_bus_device_detach, NULL, NULL);
 - ---  acpi_bus_device_detach(start->handle, 0, NULL, NULL);
 - ---  /*
 - ---   * Execute acpi_bus_remove() as a post-order callback to remove device
 - ---   * nodes in the given namespace scope.
 + +++   * Most likely, the device is going away, so put it into D3cold before
 + +++   * that.
         */
 - ---  acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL,
 - ---                      acpi_bus_remove, NULL, NULL);
 - ---  acpi_bus_remove(start->handle, 0, NULL, NULL);
 + +++  acpi_device_set_power(adev, ACPI_STATE_D3_COLD);
 + +++  adev->flags.initialized = false;
 + +++  adev->flags.visited = false;
      }
      EXPORT_SYMBOL_GPL(acpi_bus_trim);
      
@@@@@@@ -2197,14 -2047,14 -2137,14 -2047,14 -2047,14 -2047,14 +2198,14 @@@@@@@ int __init acpi_scan_init(void
      
        result = acpi_bus_scan_fixed();
        if (result) {
 - ---          acpi_device_unregister(acpi_root);
 + +++          acpi_detach_data(acpi_root->handle, acpi_scan_drop_device);
 + +++          acpi_device_del(acpi_root);
 + +++          put_device(&acpi_root->dev);
                goto out;
        }
      
        acpi_update_all_gpes();
      
 - ---  acpi_pci_root_hp_init();
 - ---
       out:
        mutex_unlock(&acpi_scan_lock);
        return result;
diff --combined drivers/acpi/sysfs.c
index 443dc9366052f623b14b6ce278a2bafff81e15ac,6dbc3ca45223a1ba30f995f016ecd965dd4861f7,ba07d9a927ab3bd2137a19db38809f092677b3f8,6dbc3ca45223a1ba30f995f016ecd965dd4861f7,6dbc3ca45223a1ba30f995f016ecd965dd4861f7,3e0b54fb075b7f4cf2e85da95ddaafb524c360b4..91a32cefb11f6098fbea62d9744ed61ed864c4a9
@@@@@@@ -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 +5,7 @@@@@@@
      #include <linux/init.h>
      #include <linux/kernel.h>
      #include <linux/moduleparam.h>
 - ---#include <acpi/acpi_drivers.h>
 + +++#include <linux/acpi.h>
      
      #include "internal.h"
      
@@@@@@@ -226,7 -226,7 -226,7 -226,7 -226,7 -226,7 +226,7 @@@@@@@ module_param_call(trace_state, param_se
      /* /sys/modules/acpi/parameters/aml_debug_output */
      
      module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object,
-----              bool, 0644);
+++++              byte, 0644);
      MODULE_PARM_DESC(aml_debug_output,
                 "To enable/disable the ACPI Debug Object output.");
      
@@@@@@@ -309,7 -309,7 -309,7 -309,7 -309,7 -309,7 +309,7 @@@@@@@ static void acpi_table_attr_init(struc
                sprintf(table_attr->name + ACPI_NAME_SIZE, "%d",
                        table_attr->instance);
      
  -     table_attr->attr.size = 0;
  +     table_attr->attr.size = table_header->length;
        table_attr->attr.read = acpi_table_show;
        table_attr->attr.attr.name = table_attr->name;
        table_attr->attr.attr.mode = 0400;
@@@@@@@ -354,9 -354,9 -354,8 -354,9 -354,9 -354,9 +354,9 @@@@@@@ static int acpi_tables_sysfs_init(void
      {
        struct acpi_table_attr *table_attr;
        struct acpi_table_header *table_header = NULL;
  -     int table_index = 0;
  -     int result;
  +     int table_index;
  +     acpi_status status;
  +     int ret;
      
        tables_kobj = kobject_create_and_add("tables", acpi_kobj);
        if (!tables_kobj)
        if (!dynamic_tables_kobj)
                goto err_dynamic_tables;
      
  -     do {
  -             result = acpi_get_table_by_index(table_index, &table_header);
  -             if (!result) {
  -                     table_index++;
  -                     table_attr = NULL;
  -                     table_attr =
  -                         kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
  -                     if (!table_attr)
  -                             return -ENOMEM;
  -   
  -                     acpi_table_attr_init(table_attr, table_header);
  -                     result =
  -                         sysfs_create_bin_file(tables_kobj,
  -                                               &table_attr->attr);
  -                     if (result) {
  -                             kfree(table_attr);
  -                             return result;
  -                     } else
  -                             list_add_tail(&table_attr->node,
  -                                           &acpi_table_attr_list);
  +     for (table_index = 0;; table_index++) {
  +             status = acpi_get_table_by_index(table_index, &table_header);
  +   
  +             if (status == AE_BAD_PARAMETER)
  +                     break;
  +   
  +             if (ACPI_FAILURE(status))
  +                     continue;
  +   
  +             table_attr = NULL;
  +             table_attr = kzalloc(sizeof(*table_attr), GFP_KERNEL);
  +             if (!table_attr)
  +                     return -ENOMEM;
  +   
  +             acpi_table_attr_init(table_attr, table_header);
  +             ret = sysfs_create_bin_file(tables_kobj, &table_attr->attr);
  +             if (ret) {
  +                     kfree(table_attr);
  +                     return ret;
                }
  -     } while (!result);
  +             list_add_tail(&table_attr->node, &acpi_table_attr_list);
  +     }
  +   
        kobject_uevent(tables_kobj, KOBJ_ADD);
        kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
  -     result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
  +     status = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
      
  -     return result == AE_OK ? 0 : -EINVAL;
  +     return ACPI_FAILURE(status) ? -EINVAL : 0;
      err_dynamic_tables:
        kobject_put(tables_kobj);
      err: