Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / drivers / acpi / scan.c
index 653c6d2..6ad4656 100644 (file)
@@ -889,7 +889,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
        /*
         * Enumerate supported power management states
         */
-       for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
+       for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
                struct acpi_device_power_state *ps = &device->power.states[i];
                char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
 
@@ -900,7 +900,6 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
                        int j;
 
                        device->power.flags.power_resources = 1;
-                       ps->flags.valid = 1;
                        for (j = 0; j < ps->resources.count; j++)
                                acpi_bus_add_power_resource(ps->resources.handles[j]);
                }
@@ -908,13 +907,15 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
                /* Evaluate "_PSx" to see if we can do explicit sets */
                object_name[2] = 'S';
                status = acpi_get_handle(device->handle, object_name, &handle);
-               if (ACPI_SUCCESS(status)) {
+               if (ACPI_SUCCESS(status))
                        ps->flags.explicit_set = 1;
-                       ps->flags.valid = 1;
-               }
 
-               /* State is valid if we have some power control */
-               if (ps->resources.count || ps->flags.explicit_set)
+               /*
+                * State is valid if there are means to put the device into it.
+                * D3hot is only valid if _PR3 present.
+                */
+               if (ps->resources.count ||
+                   (ps->flags.explicit_set && i < ACPI_STATE_D3_HOT))
                        ps->flags.valid = 1;
 
                ps->power = -1; /* Unknown - driver assigned */
@@ -927,6 +928,10 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
        device->power.states[ACPI_STATE_D3].flags.valid = 1;
        device->power.states[ACPI_STATE_D3].power = 0;
 
+       /* Set D3cold's explicit_set flag if _PS3 exists. */
+       if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set)
+               device->power.states[ACPI_STATE_D3_COLD].flags.explicit_set = 1;
+
        acpi_bus_init_power(device);
 
        return 0;
@@ -1082,13 +1087,12 @@ static void acpi_add_id(struct acpi_device *device, const char *dev_id)
        if (!id)
                return;
 
-       id->id = kmalloc(strlen(dev_id) + 1, GFP_KERNEL);
+       id->id = kstrdup(dev_id, GFP_KERNEL);
        if (!id->id) {
                kfree(id);
                return;
        }
 
-       strcpy(id->id, dev_id);
        list_add_tail(&id->list, &device->pnp.ids);
 }