Merge branch 'acpi-general'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 4 Dec 2012 12:46:08 +0000 (13:46 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 4 Dec 2012 12:46:08 +0000 (13:46 +0100)
* acpi-general:
  ACPI / PNP: Do not crash due to stale pointer use during system resume
  ACPI / video: Add "Asus UL30VT" to ACPI video detect blacklist
  ACPI: do acpisleep dmi check when CONFIG_ACPI_SLEEP is set

1  2 
drivers/acpi/sleep.c
drivers/pnp/pnpacpi/core.c

diff --combined drivers/acpi/sleep.c
@@@ -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;
  
  /*
@@@ -129,6 -124,180 +129,180 @@@ void __init acpi_old_suspend_ordering(v
        old_suspend_ordering = true;
  }
  
+ static int __init init_old_suspend_ordering(const struct dmi_system_id *d)
+ {
+       acpi_old_suspend_ordering();
+       return 0;
+ }
+ static int __init init_nvs_nosave(const struct dmi_system_id *d)
+ {
+       acpi_nvs_nosave();
+       return 0;
+ }
+ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
+       {
+       .callback = init_old_suspend_ordering,
+       .ident = "Abit KN9 (nForce4 variant)",
+       .matches = {
+               DMI_MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"),
+               DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
+               },
+       },
+       {
+       .callback = init_old_suspend_ordering,
+       .ident = "HP xw4600 Workstation",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
+               },
+       },
+       {
+       .callback = init_old_suspend_ordering,
+       .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)",
+       .matches = {
+               DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."),
+               DMI_MATCH(DMI_BOARD_NAME, "M2N8L"),
+               },
+       },
+       {
+       .callback = init_old_suspend_ordering,
+       .ident = "Panasonic CF51-2L",
+       .matches = {
+               DMI_MATCH(DMI_BOARD_VENDOR,
+                               "Matsushita Electric Industrial Co.,Ltd."),
+               DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VGN-FW21E",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21E"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VPCEB17FX",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VGN-SR11M",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Everex StepNote Series",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VPCEB1Z1E",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VGN-NW130D",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VPCCW29FX",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Averatec AV1020-ED2",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),
+               },
+       },
+       {
+       .callback = init_old_suspend_ordering,
+       .ident = "Asus A8N-SLI DELUXE",
+       .matches = {
+               DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+               DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI DELUXE"),
+               },
+       },
+       {
+       .callback = init_old_suspend_ordering,
+       .ident = "Asus A8N-SLI Premium",
+       .matches = {
+               DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+               DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI Premium"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VGN-SR26GN_P",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR26GN_P"),
+               },
+       },
+       {
+       .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"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW520F"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Asus K54C",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "K54C"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Asus K54HR",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"),
+               },
+       },
+       {},
+ };
+ static void acpi_sleep_dmi_check(void)
+ {
+       dmi_check_system(acpisleep_dmi_table);
+ }
  /**
   * acpi_pm_freeze - Disable the GPEs and suspend EC transactions.
   */
@@@ -244,6 -413,7 +418,7 @@@ static void acpi_pm_end(void
  }
  #else /* !CONFIG_ACPI_SLEEP */
  #define acpi_target_sleep_state       ACPI_STATE_S0
+ static inline void acpi_sleep_dmi_check(void) {}
  #endif /* CONFIG_ACPI_SLEEP */
  
  #ifdef CONFIG_SUSPEND
@@@ -402,175 -572,6 +577,6 @@@ static const struct platform_suspend_op
        .end = acpi_pm_end,
        .recover = acpi_pm_finish,
  };
- static int __init init_old_suspend_ordering(const struct dmi_system_id *d)
- {
-       old_suspend_ordering = true;
-       return 0;
- }
- static int __init init_nvs_nosave(const struct dmi_system_id *d)
- {
-       acpi_nvs_nosave();
-       return 0;
- }
- static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
-       {
-       .callback = init_old_suspend_ordering,
-       .ident = "Abit KN9 (nForce4 variant)",
-       .matches = {
-               DMI_MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"),
-               DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
-               },
-       },
-       {
-       .callback = init_old_suspend_ordering,
-       .ident = "HP xw4600 Workstation",
-       .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
-               },
-       },
-       {
-       .callback = init_old_suspend_ordering,
-       .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)",
-       .matches = {
-               DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."),
-               DMI_MATCH(DMI_BOARD_NAME, "M2N8L"),
-               },
-       },
-       {
-       .callback = init_old_suspend_ordering,
-       .ident = "Panasonic CF51-2L",
-       .matches = {
-               DMI_MATCH(DMI_BOARD_VENDOR,
-                               "Matsushita Electric Industrial Co.,Ltd."),
-               DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
-               },
-       },
-       {
-       .callback = init_nvs_nosave,
-       .ident = "Sony Vaio VGN-FW21E",
-       .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21E"),
-               },
-       },
-       {
-       .callback = init_nvs_nosave,
-       .ident = "Sony Vaio VPCEB17FX",
-       .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"),
-               },
-       },
-       {
-       .callback = init_nvs_nosave,
-       .ident = "Sony Vaio VGN-SR11M",
-       .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"),
-               },
-       },
-       {
-       .callback = init_nvs_nosave,
-       .ident = "Everex StepNote Series",
-       .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."),
-               DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"),
-               },
-       },
-       {
-       .callback = init_nvs_nosave,
-       .ident = "Sony Vaio VPCEB1Z1E",
-       .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
-               },
-       },
-       {
-       .callback = init_nvs_nosave,
-       .ident = "Sony Vaio VGN-NW130D",
-       .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
-               },
-       },
-       {
-       .callback = init_nvs_nosave,
-       .ident = "Sony Vaio VPCCW29FX",
-       .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"),
-               },
-       },
-       {
-       .callback = init_nvs_nosave,
-       .ident = "Averatec AV1020-ED2",
-       .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),
-               },
-       },
-       {
-       .callback = init_old_suspend_ordering,
-       .ident = "Asus A8N-SLI DELUXE",
-       .matches = {
-               DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-               DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI DELUXE"),
-               },
-       },
-       {
-       .callback = init_old_suspend_ordering,
-       .ident = "Asus A8N-SLI Premium",
-       .matches = {
-               DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-               DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI Premium"),
-               },
-       },
-       {
-       .callback = init_nvs_nosave,
-       .ident = "Sony Vaio VGN-SR26GN_P",
-       .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR26GN_P"),
-               },
-       },
-       {
-       .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"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW520F"),
-               },
-       },
-       {
-       .callback = init_nvs_nosave,
-       .ident = "Asus K54C",
-       .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-               DMI_MATCH(DMI_PRODUCT_NAME, "K54C"),
-               },
-       },
-       {
-       .callback = init_nvs_nosave,
-       .ident = "Asus K54HR",
-       .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-               DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"),
-               },
-       },
-       {},
- };
  #endif /* CONFIG_SUSPEND */
  
  #ifdef CONFIG_HIBERNATION
@@@ -709,6 -710,177 +715,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 */
@@@ -730,13 -902,13 +736,13 @@@ int __init acpi_sleep_init(void
        u8 type_a, type_b;
  #ifdef CONFIG_SUSPEND
        int i = 0;
-       dmi_check_system(acpisleep_dmi_table);
  #endif
  
        if (acpi_disabled)
                return 0;
  
+       acpi_sleep_dmi_check();
        sleep_states[ACPI_STATE_S0] = 1;
        printk(KERN_INFO PREFIX "(supports S0");
  
@@@ -95,6 -95,9 +95,9 @@@ static int pnpacpi_set_resources(struc
                return -ENODEV;
        }
  
+       if (WARN_ON_ONCE(acpi_dev != dev->data))
+               dev->data = acpi_dev;
        ret = pnpacpi_build_resource_template(dev, &buffer);
        if (ret)
                return ret;
@@@ -242,10 -245,6 +245,10 @@@ static int __init pnpacpi_add_device(st
        char *pnpid;
        struct acpi_hardware_id *id;
  
 +      /* Skip devices that are already bound */
 +      if (device->physical_node_count)
 +              return 0;
 +
        /*
         * If a PnPacpi device is not present , the device
         * driver should not be loaded.