Merge branch 'drm-reorg' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[safe/jmp/linux-2.6] / drivers / acpi / thermal.c
index aee371f..84c795f 100644 (file)
@@ -198,6 +198,7 @@ struct acpi_thermal {
 };
 
 static const struct file_operations acpi_thermal_state_fops = {
+       .owner = THIS_MODULE,
        .open = acpi_thermal_state_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
@@ -205,6 +206,7 @@ static const struct file_operations acpi_thermal_state_fops = {
 };
 
 static const struct file_operations acpi_thermal_temp_fops = {
+       .owner = THIS_MODULE,
        .open = acpi_thermal_temp_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
@@ -212,6 +214,7 @@ static const struct file_operations acpi_thermal_temp_fops = {
 };
 
 static const struct file_operations acpi_thermal_trip_fops = {
+       .owner = THIS_MODULE,
        .open = acpi_thermal_trip_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
@@ -219,6 +222,7 @@ static const struct file_operations acpi_thermal_trip_fops = {
 };
 
 static const struct file_operations acpi_thermal_cooling_fops = {
+       .owner = THIS_MODULE,
        .open = acpi_thermal_cooling_open_fs,
        .read = seq_read,
        .write = acpi_thermal_write_cooling_mode,
@@ -227,6 +231,7 @@ static const struct file_operations acpi_thermal_cooling_fops = {
 };
 
 static const struct file_operations acpi_thermal_polling_fops = {
+       .owner = THIS_MODULE,
        .open = acpi_thermal_polling_open_fs,
        .read = seq_read,
        .write = acpi_thermal_write_polling,
@@ -359,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;
@@ -539,7 +551,7 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
 
 static int acpi_thermal_critical(struct acpi_thermal *tz)
 {
-       if (!tz || !tz->trips.critical.flags.valid || nocrt)
+       if (!tz || !tz->trips.critical.flags.valid)
                return -EINVAL;
 
        if (tz->temperature >= tz->trips.critical.temperature) {
@@ -548,9 +560,6 @@ static int acpi_thermal_critical(struct acpi_thermal *tz)
        } else if (tz->trips.critical.flags.enabled)
                tz->trips.critical.flags.enabled = 0;
 
-       printk(KERN_EMERG
-              "Critical temperature reached (%ld C), shutting down.\n",
-              KELVIN_TO_CELSIUS(tz->temperature));
        acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
                                tz->trips.critical.flags.enabled);
        acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
@@ -558,14 +567,20 @@ static int acpi_thermal_critical(struct acpi_thermal *tz)
                                          ACPI_THERMAL_NOTIFY_CRITICAL,
                                          tz->trips.critical.flags.enabled);
 
-       orderly_poweroff(true);
+       /* take no action if nocrt is set */
+       if(!nocrt) {
+               printk(KERN_EMERG
+                       "Critical temperature reached (%ld C), shutting down.\n",
+                       KELVIN_TO_CELSIUS(tz->temperature));
+               orderly_poweroff(true);
+       }
 
        return 0;
 }
 
 static int acpi_thermal_hot(struct acpi_thermal *tz)
 {
-       if (!tz || !tz->trips.hot.flags.valid || nocrt)
+       if (!tz || !tz->trips.hot.flags.valid)
                return -EINVAL;
 
        if (tz->temperature >= tz->trips.hot.temperature) {
@@ -581,7 +596,7 @@ static int acpi_thermal_hot(struct acpi_thermal *tz)
                                          ACPI_THERMAL_NOTIFY_HOT,
                                          tz->trips.hot.flags.enabled);
 
-       /* TBD: Call user-mode "sleep(S4)" function */
+       /* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */
 
        return 0;
 }
@@ -876,14 +891,21 @@ static void acpi_thermal_check(void *data)
 }
 
 /* sys I/F for generic thermal sysfs support */
+#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
+
 static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
 {
        struct acpi_thermal *tz = thermal->devdata;
+       int result;
 
        if (!tz)
                return -EINVAL;
 
-       return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(tz->temperature));
+       result = acpi_thermal_get_temperature(tz);
+       if (result)
+               return result;
+
+       return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
 }
 
 static const char enabled[] = "kernel";
@@ -977,21 +999,21 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
 
        if (tz->trips.critical.flags.valid) {
                if (!trip)
-                       return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(
+                       return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
                                tz->trips.critical.temperature));
                trip--;
        }
 
        if (tz->trips.hot.flags.valid) {
                if (!trip)
-                       return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(
+                       return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
                                        tz->trips.hot.temperature));
                trip--;
        }
 
        if (tz->trips.passive.flags.valid) {
                if (!trip)
-                       return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(
+                       return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
                                        tz->trips.passive.temperature));
                trip--;
        }
@@ -999,7 +1021,7 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
        for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
                tz->trips.active[i].flags.valid; i++) {
                if (!trip)
-                       return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(
+                       return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
                                        tz->trips.active[i].temperature));
                trip--;
        }
@@ -1007,6 +1029,18 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
        return -EINVAL;
 }
 
+static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
+                               unsigned long *temperature) {
+       struct acpi_thermal *tz = thermal->devdata;
+
+       if (tz->trips.critical.flags.valid) {
+               *temperature = KELVIN_TO_MILLICELSIUS(
+                               tz->trips.critical.temperature);
+               return 0;
+       } else
+               return -EINVAL;
+}
+
 typedef int (*cb)(struct thermal_zone_device *, int,
                  struct thermal_cooling_device *);
 static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
@@ -1015,7 +1049,9 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
 {
        struct acpi_device *device = cdev->devdata;
        struct acpi_thermal *tz = thermal->devdata;
-       acpi_handle handle = device->handle;
+       struct acpi_device *dev;
+       acpi_status status;
+       acpi_handle handle;
        int i;
        int j;
        int trip = -1;
@@ -1031,12 +1067,13 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
                trip++;
                for (i = 0; i < tz->trips.passive.devices.count;
                    i++) {
-                       if (tz->trips.passive.devices.handles[i] !=
-                               handle)
-                               continue;
-                       result = action(thermal, trip, cdev);
-                       if (result)
-                               goto failed;
+                       handle = tz->trips.passive.devices.handles[i];
+                       status = acpi_bus_get_device(handle, &dev);
+                       if (ACPI_SUCCESS(status) && (dev == device)) {
+                               result = action(thermal, trip, cdev);
+                               if (result)
+                                       goto failed;
+                       }
                }
        }
 
@@ -1047,21 +1084,24 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
                for (j = 0;
                    j < tz->trips.active[i].devices.count;
                    j++) {
-                       if (tz->trips.active[i].devices.
-                                               handles[j] != handle)
-                               continue;
-                       result = action(thermal, trip, cdev);
-                       if (result)
-                               goto failed;
+                       handle = tz->trips.active[i].devices.handles[j];
+                       status = acpi_bus_get_device(handle, &dev);
+                       if (ACPI_SUCCESS(status) && (dev == device)) {
+                               result = action(thermal, trip, cdev);
+                               if (result)
+                                       goto failed;
+                       }
                }
        }
 
        for (i = 0; i < tz->devices.count; i++) {
-               if (tz->devices.handles[i] != handle)
-                       continue;
-               result = action(thermal, -1, cdev);
-               if (result)
-                       goto failed;
+               handle = tz->devices.handles[i];
+               status = acpi_bus_get_device(handle, &dev);
+               if (ACPI_SUCCESS(status) && (dev == device)) {
+                       result = action(thermal, -1, cdev);
+                       if (result)
+                               goto failed;
+               }
        }
 
 failed:
@@ -1092,6 +1132,7 @@ static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
        .set_mode = thermal_set_mode,
        .get_trip_type = thermal_get_trip_type,
        .get_trip_temp = thermal_get_trip_temp,
+       .get_crit_temp = thermal_get_crit_temp,
 };
 
 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
@@ -1112,9 +1153,9 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
 
        for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
                        tz->trips.active[i].flags.valid; i++, trips++);
-       tz->thermal_zone = thermal_zone_device_register("ACPI thermal zone",
+       tz->thermal_zone = thermal_zone_device_register("acpitz",
                                        trips, tz, &acpi_thermal_zone_ops);
-       if (!tz->thermal_zone)
+       if (IS_ERR(tz->thermal_zone))
                return -ENODEV;
 
        result = sysfs_create_link(&tz->device->dev.kobj,
@@ -1408,63 +1449,47 @@ static int acpi_thermal_add_fs(struct acpi_device *device)
        }
 
        /* 'state' [R] */
-       entry = create_proc_entry(ACPI_THERMAL_FILE_STATE,
-                                 S_IRUGO, acpi_device_dir(device));
+       entry = proc_create_data(ACPI_THERMAL_FILE_STATE,
+                                S_IRUGO, acpi_device_dir(device),
+                                &acpi_thermal_state_fops,
+                                acpi_driver_data(device));
        if (!entry)
                return -ENODEV;
-       else {
-               entry->proc_fops = &acpi_thermal_state_fops;
-               entry->data = acpi_driver_data(device);
-               entry->owner = THIS_MODULE;
-       }
 
        /* 'temperature' [R] */
-       entry = create_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,
-                                 S_IRUGO, acpi_device_dir(device));
+       entry = proc_create_data(ACPI_THERMAL_FILE_TEMPERATURE,
+                                S_IRUGO, acpi_device_dir(device),
+                                &acpi_thermal_temp_fops,
+                                acpi_driver_data(device));
        if (!entry)
                return -ENODEV;
-       else {
-               entry->proc_fops = &acpi_thermal_temp_fops;
-               entry->data = acpi_driver_data(device);
-               entry->owner = THIS_MODULE;
-       }
 
        /* 'trip_points' [R] */
-       entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
-                                 S_IRUGO,
-                                 acpi_device_dir(device));
+       entry = proc_create_data(ACPI_THERMAL_FILE_TRIP_POINTS,
+                                S_IRUGO,
+                                acpi_device_dir(device),
+                                &acpi_thermal_trip_fops,
+                                acpi_driver_data(device));
        if (!entry)
                return -ENODEV;
-       else {
-               entry->proc_fops = &acpi_thermal_trip_fops;
-               entry->data = acpi_driver_data(device);
-               entry->owner = THIS_MODULE;
-       }
 
        /* 'cooling_mode' [R/W] */
-       entry = create_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,
-                                 S_IFREG | S_IRUGO | S_IWUSR,
-                                 acpi_device_dir(device));
+       entry = proc_create_data(ACPI_THERMAL_FILE_COOLING_MODE,
+                                S_IFREG | S_IRUGO | S_IWUSR,
+                                acpi_device_dir(device),
+                                &acpi_thermal_cooling_fops,
+                                acpi_driver_data(device));
        if (!entry)
                return -ENODEV;
-       else {
-               entry->proc_fops = &acpi_thermal_cooling_fops;
-               entry->data = acpi_driver_data(device);
-               entry->owner = THIS_MODULE;
-       }
 
        /* 'polling_frequency' [R/W] */
-       entry = create_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,
-                                 S_IFREG | S_IRUGO | S_IWUSR,
-                                 acpi_device_dir(device));
+       entry = proc_create_data(ACPI_THERMAL_FILE_POLLING_FREQ,
+                                S_IFREG | S_IRUGO | S_IWUSR,
+                                acpi_device_dir(device),
+                                &acpi_thermal_polling_fops,
+                                acpi_driver_data(device));
        if (!entry)
                return -ENODEV;
-       else {
-               entry->proc_fops = &acpi_thermal_polling_fops;
-               entry->data = acpi_driver_data(device);
-               entry->owner = THIS_MODULE;
-       }
-
        return 0;
 }
 
@@ -1699,7 +1724,6 @@ static int acpi_thermal_resume(struct acpi_device *device)
        return AE_OK;
 }
 
-#ifdef CONFIG_DMI
 static int thermal_act(const struct dmi_system_id *d) {
 
        if (act == 0) {
@@ -1774,7 +1798,6 @@ static struct dmi_system_id thermal_dmi_table[] __initdata = {
        },
        {}
 };
-#endif /* CONFIG_DMI */
 
 static int __init acpi_thermal_init(void)
 {