Merge remote-tracking branch 'iwlwifi-fixes/master' into NEXT
[sfrench/cifs-2.6.git] / drivers / thermal / int3403_thermal.c
index e93f0253f6ed2070c934570cbe5c62f400bdfcc1..17554eeb3953e2cf3c8a6190675be1a50e5387a7 100644 (file)
 struct int3403_sensor {
        struct thermal_zone_device *tzone;
        unsigned long *thresholds;
+       unsigned long   crit_temp;
+       int             crit_trip_id;
+       unsigned long   psv_temp;
+       int             psv_trip_id;
 };
 
 static int sys_get_curr_temp(struct thermal_zone_device *tzone,
@@ -79,12 +83,18 @@ static int sys_get_trip_temp(struct thermal_zone_device *tzone,
        struct acpi_device *device = tzone->devdata;
        struct int3403_sensor *obj = acpi_driver_data(device);
 
-       /*
-        * get_trip_temp is a mandatory callback but
-        * PATx method doesn't return any value, so return
-        * cached value, which was last set from user space.
-        */
-       *temp = obj->thresholds[trip];
+       if (trip == obj->crit_trip_id)
+               *temp = obj->crit_temp;
+       else if (trip == obj->psv_trip_id)
+               *temp = obj->psv_temp;
+       else {
+               /*
+                * get_trip_temp is a mandatory callback but
+                * PATx method doesn't return any value, so return
+                * cached value, which was last set from user space.
+                */
+               *temp = obj->thresholds[trip];
+       }
 
        return 0;
 }
@@ -92,8 +102,14 @@ static int sys_get_trip_temp(struct thermal_zone_device *tzone,
 static int sys_get_trip_type(struct thermal_zone_device *thermal,
                int trip, enum thermal_trip_type *type)
 {
+       struct acpi_device *device = thermal->devdata;
+       struct int3403_sensor *obj = acpi_driver_data(device);
+
        /* Mandatory callback, may not mean much here */
-       *type = THERMAL_TRIP_PASSIVE;
+       if (trip == obj->crit_trip_id)
+               *type = THERMAL_TRIP_CRITICAL;
+       else
+               *type = THERMAL_TRIP_PASSIVE;
 
        return 0;
 }
@@ -155,6 +171,34 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event)
        }
 }
 
+static int sys_get_trip_crt(struct acpi_device *device, unsigned long *temp)
+{
+       unsigned long long crt;
+       acpi_status status;
+
+       status = acpi_evaluate_integer(device->handle, "_CRT", NULL, &crt);
+       if (ACPI_FAILURE(status))
+               return -EIO;
+
+       *temp = DECI_KELVIN_TO_MILLI_CELSIUS(crt, KELVIN_OFFSET);
+
+       return 0;
+}
+
+static int sys_get_trip_psv(struct acpi_device *device, unsigned long *temp)
+{
+       unsigned long long psv;
+       acpi_status status;
+
+       status = acpi_evaluate_integer(device->handle, "_PSV", NULL, &psv);
+       if (ACPI_FAILURE(status))
+               return -EIO;
+
+       *temp = DECI_KELVIN_TO_MILLI_CELSIUS(psv, KELVIN_OFFSET);
+
+       return 0;
+}
+
 static int acpi_int3403_add(struct acpi_device *device)
 {
        int result = 0;
@@ -194,6 +238,15 @@ static int acpi_int3403_add(struct acpi_device *device)
                        return -ENOMEM;
                trip_mask = BIT(trip_cnt) - 1;
        }
+
+       obj->psv_trip_id = -1;
+       if (!sys_get_trip_psv(device, &obj->psv_temp))
+               obj->psv_trip_id = trip_cnt++;
+
+       obj->crit_trip_id = -1;
+       if (!sys_get_trip_crt(device, &obj->crit_temp))
+               obj->crit_trip_id = trip_cnt++;
+
        obj->tzone = thermal_zone_device_register(acpi_device_bid(device),
                                trip_cnt, trip_mask, device, &tzone_ops,
                                NULL, 0, 0);