]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/acpi/thermal.c
Merge branch 'for-upstream/acpi-test' of git://repo.or.cz/linux-2.6/linux-acpi-2...
[linux-2.6-omap-h63xx.git] / drivers / acpi / thermal.c
index 504385b1f2116614bd8e53e598b5c093414b2841..9adfd180df6ae6f74f450f4fa7049782868a183e 100644 (file)
@@ -364,10 +364,17 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
        if (flag & ACPI_TRIPS_CRITICAL) {
                status = acpi_evaluate_integer(tz->device->handle,
                                "_CRT", NULL, &tz->trips.critical.temperature);
-               if (ACPI_FAILURE(status)) {
+               /*
+                * Treat freezing temperatures as invalid as well; some
+                * BIOSes return really low values and cause reboots at startup.
+                * Below zero (Celcius) values clearly aren't right for sure..
+                * ... so lets discard those as invalid.
+                */
+               if (ACPI_FAILURE(status) ||
+                               tz->trips.critical.temperature <= 2732) {
                        tz->trips.critical.flags.valid = 0;
                        ACPI_EXCEPTION((AE_INFO, status,
-                                       "No critical threshold"));
+                                       "No or invalid critical threshold"));
                        return -ENODEV;
                } else {
                        tz->trips.critical.flags.valid = 1;
@@ -762,6 +769,47 @@ static void acpi_thermal_run(unsigned long data)
                acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data);
 }
 
+static void acpi_thermal_active_off(void *data)
+{
+       int result = 0;
+       struct acpi_thermal *tz = data;
+       int i = 0;
+       int j = 0;
+       struct acpi_thermal_active *active = NULL;
+
+       if (!tz) {
+               printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
+               return;
+       }
+
+       result = acpi_thermal_get_temperature(tz);
+       if (result)
+               return;
+
+       for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
+               active = &(tz->trips.active[i]);
+               if (!active || !active->flags.valid)
+                       break;
+               if (tz->temperature >= active->temperature) {
+                       /*
+                        * If the thermal temperature is greater than the
+                        * active threshod, unnecessary to turn off the
+                        * the active cooling device.
+                        */
+                       continue;
+               }
+               /*
+                * Below Threshold?
+                * ----------------
+                * Turn OFF all cooling devices associated with this
+                * threshold.
+                */
+               for (j = 0; j < active->devices.count; j++)
+                       result = acpi_bus_set_power(active->devices.handles[j],
+                                                   ACPI_STATE_D3);
+       }
+}
+
 static void acpi_thermal_check(void *data)
 {
        int result = 0;
@@ -1617,6 +1665,8 @@ static int acpi_thermal_add(struct acpi_device *device)
 
        init_timer(&tz->timer);
 
+       acpi_thermal_active_off(tz);
+
        acpi_thermal_check(tz);
 
        status = acpi_install_notify_handler(device->handle,