]> Pileus Git - ~andy/linux/blobdiff - drivers/acpi/thermal.c
Merge remote-tracking branch 'asoc/topic/jz4740' into asoc-next
[~andy/linux] / drivers / acpi / thermal.c
index 9fe90e9fecb56ada8629a55c472c67653bbd02f5..804204d41999d0af951086f25b37a2f7ee783a90 100644 (file)
@@ -106,7 +106,9 @@ static const struct acpi_device_id  thermal_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, thermal_device_ids);
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_thermal_resume(struct device *dev);
+#endif
 static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume);
 
 static struct acpi_driver acpi_thermal_driver = {
@@ -706,6 +708,40 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
                return -EINVAL;
 }
 
+static int thermal_get_trend(struct thermal_zone_device *thermal,
+                               int trip, enum thermal_trend *trend)
+{
+       struct acpi_thermal *tz = thermal->devdata;
+       enum thermal_trip_type type;
+       int i;
+
+       if (thermal_get_trip_type(thermal, trip, &type))
+               return -EINVAL;
+
+       if (type == THERMAL_TRIP_ACTIVE) {
+               /* aggressive active cooling */
+               *trend = THERMAL_TREND_RAISING;
+               return 0;
+       }
+
+       /*
+        * tz->temperature has already been updated by generic thermal layer,
+        * before this callback being invoked
+        */
+       i = (tz->trips.passive.tc1 * (tz->temperature - tz->last_temperature))
+               + (tz->trips.passive.tc2
+               * (tz->temperature - tz->trips.passive.temperature));
+
+       if (i > 0)
+               *trend = THERMAL_TREND_RAISING;
+       else if (i < 0)
+               *trend = THERMAL_TREND_DROPPING;
+       else
+               *trend = THERMAL_TREND_STABLE;
+       return 0;
+}
+
+
 static int thermal_notify(struct thermal_zone_device *thermal, int trip,
                           enum thermal_trip_type trip_type)
 {
@@ -729,11 +765,9 @@ static int thermal_notify(struct thermal_zone_device *thermal, int trip,
        return 0;
 }
 
-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 thermal_cooling_device *cdev,
-                                       cb action)
+                                       bool bind)
 {
        struct acpi_device *device = cdev->devdata;
        struct acpi_thermal *tz = thermal->devdata;
@@ -757,11 +791,19 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
                    i++) {
                        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;
-                       }
+                       if (ACPI_FAILURE(status) || dev != device)
+                               continue;
+                       if (bind)
+                               result =
+                                       thermal_zone_bind_cooling_device
+                                       (thermal, trip, cdev,
+                                        THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
+                       else
+                               result =
+                                       thermal_zone_unbind_cooling_device
+                                       (thermal, trip, cdev);
+                       if (result)
+                               goto failed;
                }
        }
 
@@ -774,11 +816,17 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
                    j++) {
                        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;
-                       }
+                       if (ACPI_FAILURE(status) || dev != device)
+                               continue;
+                       if (bind)
+                               result = thermal_zone_bind_cooling_device
+                                       (thermal, trip, cdev,
+                                        THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
+                       else
+                               result = thermal_zone_unbind_cooling_device
+                                       (thermal, trip, cdev);
+                       if (result)
+                               goto failed;
                }
        }
 
@@ -786,7 +834,14 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
                handle = tz->devices.handles[i];
                status = acpi_bus_get_device(handle, &dev);
                if (ACPI_SUCCESS(status) && (dev == device)) {
-                       result = action(thermal, -1, cdev);
+                       if (bind)
+                               result = thermal_zone_bind_cooling_device
+                                               (thermal, -1, cdev,
+                                                THERMAL_NO_LIMIT,
+                                                THERMAL_NO_LIMIT);
+                       else
+                               result = thermal_zone_unbind_cooling_device
+                                               (thermal, -1, cdev);
                        if (result)
                                goto failed;
                }
@@ -800,16 +855,14 @@ static int
 acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal,
                                        struct thermal_cooling_device *cdev)
 {
-       return acpi_thermal_cooling_device_cb(thermal, cdev,
-                               thermal_zone_bind_cooling_device);
+       return acpi_thermal_cooling_device_cb(thermal, cdev, true);
 }
 
 static int
 acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal,
                                        struct thermal_cooling_device *cdev)
 {
-       return acpi_thermal_cooling_device_cb(thermal, cdev,
-                               thermal_zone_unbind_cooling_device);
+       return acpi_thermal_cooling_device_cb(thermal, cdev, false);
 }
 
 static const struct thermal_zone_device_ops acpi_thermal_zone_ops = {
@@ -821,6 +874,7 @@ static const struct thermal_zone_device_ops acpi_thermal_zone_ops = {
        .get_trip_type = thermal_get_trip_type,
        .get_trip_temp = thermal_get_trip_temp,
        .get_crit_temp = thermal_get_crit_temp,
+       .get_trend = thermal_get_trend,
        .notify = thermal_notify,
 };
 
@@ -847,15 +901,12 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
                tz->thermal_zone =
                        thermal_zone_device_register("acpitz", trips, 0, tz,
                                                     &acpi_thermal_zone_ops,
-                                                    tz->trips.passive.tc1,
-                                                    tz->trips.passive.tc2,
                                                     tz->trips.passive.tsp*100,
                                                     tz->polling_frequency*100);
        else
                tz->thermal_zone =
                        thermal_zone_device_register("acpitz", trips, 0, tz,
-                                                    &acpi_thermal_zone_ops,
-                                                    0, 0, 0,
+                                                    &acpi_thermal_zone_ops, 0,
                                                     tz->polling_frequency*100);
        if (IS_ERR(tz->thermal_zone))
                return -ENODEV;
@@ -1041,6 +1092,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_thermal_resume(struct device *dev)
 {
        struct acpi_thermal *tz;
@@ -1075,6 +1127,7 @@ static int acpi_thermal_resume(struct device *dev)
 
        return AE_OK;
 }
+#endif
 
 static int thermal_act(const struct dmi_system_id *d) {