};
static const struct file_operations acpi_thermal_state_fops = {
+ .owner = THIS_MODULE,
.open = acpi_thermal_state_open_fs,
.read = seq_read,
.llseek = seq_lseek,
};
static const struct file_operations acpi_thermal_temp_fops = {
+ .owner = THIS_MODULE,
.open = acpi_thermal_temp_open_fs,
.read = seq_read,
.llseek = seq_lseek,
};
static const struct file_operations acpi_thermal_trip_fops = {
+ .owner = THIS_MODULE,
.open = acpi_thermal_trip_open_fs,
.read = seq_read,
.llseek = seq_lseek,
};
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,
};
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,
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;
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) {
} 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,
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) {
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;
}
}
/* 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";
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--;
}
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--;
}
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,
{
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;
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;
+ }
}
}
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:
.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)
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,
}
/* '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;
}
return AE_OK;
}
-#ifdef CONFIG_DMI
static int thermal_act(const struct dmi_system_id *d) {
if (act == 0) {
},
{}
};
-#endif /* CONFIG_DMI */
static int __init acpi_thermal_init(void)
{