}
 }
 
+static int acpi_dev_pm_explicit_get(struct acpi_device *device, int *state)
+{
+       unsigned long long psc;
+       acpi_status status;
+
+       status = acpi_evaluate_integer(device->handle, "_PSC", NULL, &psc);
+       if (ACPI_FAILURE(status))
+               return -ENODEV;
+
+       *state = psc;
+       return 0;
+}
+
 /**
  * acpi_device_get_power - Get power state of an ACPI device.
  * @device: Device to get the power state of.
 int acpi_device_get_power(struct acpi_device *device, int *state)
 {
        int result = ACPI_STATE_UNKNOWN;
+       int error;
 
        if (!device || !state)
                return -EINVAL;
         * if available.
         */
        if (device->power.flags.power_resources) {
-               int error = acpi_power_get_inferred_state(device, &result);
+               error = acpi_power_get_inferred_state(device, &result);
                if (error)
                        return error;
        }
        if (device->power.flags.explicit_get) {
-               acpi_handle handle = device->handle;
-               unsigned long long psc;
-               acpi_status status;
+               int psc;
 
-               status = acpi_evaluate_integer(handle, "_PSC", NULL, &psc);
-               if (ACPI_FAILURE(status))
-                       return -ENODEV;
+               error = acpi_dev_pm_explicit_get(device, &psc);
+               if (error)
+                       return error;
 
                /*
                 * The power resources settings may indicate a power state
 
        /* Make sure this is a valid target state */
 
-       if (state == device->power.state) {
+       /* There is a special case for D0 addressed below. */
+       if (state > ACPI_STATE_D0 && state == device->power.state) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already in %s\n",
                                  device->pnp.bus_id,
                                  acpi_power_state_string(state)));
                        if (result)
                                goto end;
                }
+
+               if (device->power.state == ACPI_STATE_D0) {
+                       int psc;
+
+                       /* Nothing to do here if _PSC is not present. */
+                       if (!device->power.flags.explicit_get)
+                               return 0;
+
+                       /*
+                        * The power state of the device was set to D0 last
+                        * time, but that might have happened before a
+                        * system-wide transition involving the platform
+                        * firmware, so it may be necessary to evaluate _PS0
+                        * for the device here.  However, use extra care here
+                        * and evaluate _PSC to check the device's current power
+                        * state, and only invoke _PS0 if the evaluation of _PSC
+                        * is successful and it returns a power state different
+                        * from D0.
+                        */
+                       result = acpi_dev_pm_explicit_get(device, &psc);
+                       if (result || psc == ACPI_STATE_D0)
+                               return 0;
+               }
+
                result = acpi_dev_pm_explicit_set(device, ACPI_STATE_D0);
        }