thermal: hwmon: move hwmon support to single file
[firefly-linux-kernel-4.4.55.git] / drivers / thermal / ti-soc-thermal / ti-thermal-common.c
index e3c5e677eaa5c7a13007354b9fa3d2f99bc4b125..4f8b9af54a5a75d1de884a342920ccb50f9ba869 100644 (file)
@@ -38,6 +38,7 @@
 /* common data structures */
 struct ti_thermal_data {
        struct thermal_zone_device *ti_thermal;
+       struct thermal_zone_device *pcb_tz;
        struct thermal_cooling_device *cool_dev;
        struct ti_bandgap *bgp;
        enum thermal_device_mode mode;
@@ -77,10 +78,12 @@ static inline int ti_thermal_hotspot_temperature(int t, int s, int c)
 static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
                                      unsigned long *temp)
 {
+       struct thermal_zone_device *pcb_tz = NULL;
        struct ti_thermal_data *data = thermal->devdata;
        struct ti_bandgap *bgp;
        const struct ti_temp_sensor *s;
-       int ret, tmp, pcb_temp, slope, constant;
+       int ret, tmp, slope, constant;
+       unsigned long pcb_temp;
 
        if (!data)
                return 0;
@@ -92,16 +95,22 @@ static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
        if (ret)
                return ret;
 
-       pcb_temp = 0;
-       /* TODO: Introduce pcb temperature lookup */
+       /* Default constants */
+       slope = s->slope;
+       constant = s->constant;
+
+       pcb_tz = data->pcb_tz;
        /* In case pcb zone is available, use the extrapolation rule with it */
-       if (pcb_temp) {
-               tmp -= pcb_temp;
-               slope = s->slope_pcb;
-               constant = s->constant_pcb;
-       } else {
-               slope = s->slope;
-               constant = s->constant;
+       if (!IS_ERR(pcb_tz)) {
+               ret = thermal_zone_get_temp(pcb_tz, &pcb_temp);
+               if (!ret) {
+                       tmp -= pcb_temp; /* got a valid PCB temp */
+                       slope = s->slope_pcb;
+                       constant = s->constant_pcb;
+               } else {
+                       dev_err(bgp->dev,
+                               "Failed to read PCB state. Using defaults\n");
+               }
        }
        *temp = ti_thermal_hotspot_temperature(tmp, slope, constant);
 
@@ -115,7 +124,7 @@ static int ti_thermal_bind(struct thermal_zone_device *thermal,
        struct ti_thermal_data *data = thermal->devdata;
        int id;
 
-       if (IS_ERR_OR_NULL(data))
+       if (!data || IS_ERR(data))
                return -ENODEV;
 
        /* check if this is the cooling device we registered */
@@ -137,7 +146,7 @@ static int ti_thermal_unbind(struct thermal_zone_device *thermal,
 {
        struct ti_thermal_data *data = thermal->devdata;
 
-       if (IS_ERR_OR_NULL(data))
+       if (!data || IS_ERR(data))
                return -ENODEV;
 
        /* check if this is the cooling device we registered */
@@ -165,6 +174,9 @@ static int ti_thermal_set_mode(struct thermal_zone_device *thermal,
                               enum thermal_device_mode mode)
 {
        struct ti_thermal_data *data = thermal->devdata;
+       struct ti_bandgap *bgp;
+
+       bgp = data->bgp;
 
        if (!data->ti_thermal) {
                dev_notice(&thermal->device, "thermal zone not registered\n");
@@ -181,6 +193,8 @@ static int ti_thermal_set_mode(struct thermal_zone_device *thermal,
        mutex_unlock(&data->ti_thermal->lock);
 
        data->mode = mode;
+       ti_bandgap_write_update_interval(bgp, data->sensor_id,
+                                       data->ti_thermal->polling_delay);
        thermal_zone_device_update(data->ti_thermal);
        dev_dbg(&thermal->device, "thermal polling set for duration=%d msec\n",
                data->ti_thermal->polling_delay);
@@ -273,6 +287,8 @@ static struct ti_thermal_data
        data->sensor_id = id;
        data->bgp = bgp;
        data->mode = THERMAL_DEVICE_ENABLED;
+       /* pcb_tz will be either valid or PTR_ERR() */
+       data->pcb_tz = thermal_zone_get_zone_by_name("pcb");
        INIT_WORK(&data->thermal_wq, ti_thermal_work);
 
        return data;
@@ -285,7 +301,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
 
        data = ti_bandgap_get_sensor_data(bgp, id);
 
-       if (IS_ERR_OR_NULL(data))
+       if (!data || IS_ERR(data))
                data = ti_thermal_build_data(bgp, id);
 
        if (!data)
@@ -296,12 +312,14 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
                                OMAP_TRIP_NUMBER, 0, data, &ti_thermal_ops,
                                NULL, FAST_TEMP_MONITORING_RATE,
                                FAST_TEMP_MONITORING_RATE);
-       if (IS_ERR_OR_NULL(data->ti_thermal)) {
+       if (IS_ERR(data->ti_thermal)) {
                dev_err(bgp->dev, "thermal zone device is NULL\n");
                return PTR_ERR(data->ti_thermal);
        }
        data->ti_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
        ti_bandgap_set_sensor_data(bgp, id, data);
+       ti_bandgap_write_update_interval(bgp, data->sensor_id,
+                                       data->ti_thermal->polling_delay);
 
        return 0;
 }
@@ -333,7 +351,7 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
        struct ti_thermal_data *data;
 
        data = ti_bandgap_get_sensor_data(bgp, id);
-       if (IS_ERR_OR_NULL(data))
+       if (!data || IS_ERR(data))
                data = ti_thermal_build_data(bgp, id);
 
        if (!data)
@@ -346,7 +364,7 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
 
        /* Register cooling device */
        data->cool_dev = cpufreq_cooling_register(cpu_present_mask);
-       if (IS_ERR_OR_NULL(data->cool_dev)) {
+       if (IS_ERR(data->cool_dev)) {
                dev_err(bgp->dev,
                        "Failed to register cpufreq cooling device\n");
                return PTR_ERR(data->cool_dev);