These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / thermal / ti-soc-thermal / ti-bandgap.c
index bc14dc8..1e34a1e 100644 (file)
@@ -43,6 +43,8 @@
 
 #include "ti-bandgap.h"
 
+static int ti_bandgap_force_single_read(struct ti_bandgap *bgp, int id);
+
 /***   Helper functions to access registers and their bitfields   ***/
 
 /**
@@ -103,19 +105,15 @@ do {                                                              \
  */
 static int ti_bandgap_power(struct ti_bandgap *bgp, bool on)
 {
-       int i, ret = 0;
+       int i;
 
-       if (!TI_BANDGAP_HAS(bgp, POWER_SWITCH)) {
-               ret = -ENOTSUPP;
-               goto exit;
-       }
+       if (!TI_BANDGAP_HAS(bgp, POWER_SWITCH))
+               return -ENOTSUPP;
 
        for (i = 0; i < bgp->conf->sensor_count; i++)
                /* active on 0 */
                RMW_BITS(bgp, i, temp_sensor_ctrl, bgap_tempsoff_mask, !on);
-
-exit:
-       return ret;
+       return 0;
 }
 
 /**
@@ -298,18 +296,13 @@ static
 int ti_bandgap_adc_to_mcelsius(struct ti_bandgap *bgp, int adc_val, int *t)
 {
        const struct ti_bandgap_data *conf = bgp->conf;
-       int ret = 0;
 
        /* look up for temperature in the table and return the temperature */
-       if (adc_val < conf->adc_start_val || adc_val > conf->adc_end_val) {
-               ret = -ERANGE;
-               goto exit;
-       }
+       if (adc_val < conf->adc_start_val || adc_val > conf->adc_end_val)
+               return -ERANGE;
 
        *t = bgp->conf->conv_table[adc_val - conf->adc_start_val];
-
-exit:
-       return ret;
+       return 0;
 }
 
 /**
@@ -330,16 +323,14 @@ int ti_bandgap_mcelsius_to_adc(struct ti_bandgap *bgp, long temp, int *adc)
 {
        const struct ti_bandgap_data *conf = bgp->conf;
        const int *conv_table = bgp->conf->conv_table;
-       int high, low, mid, ret = 0;
+       int high, low, mid;
 
        low = 0;
        high = conf->adc_end_val - conf->adc_start_val;
        mid = (high + low) / 2;
 
-       if (temp < conv_table[low] || temp > conv_table[high]) {
-               ret = -ERANGE;
-               goto exit;
-       }
+       if (temp < conv_table[low] || temp > conv_table[high])
+               return -ERANGE;
 
        while (low < high) {
                if (temp < conv_table[mid])
@@ -350,9 +341,7 @@ int ti_bandgap_mcelsius_to_adc(struct ti_bandgap *bgp, long temp, int *adc)
        }
 
        *adc = conf->adc_start_val + low;
-
-exit:
-       return ret;
+       return 0;
 }
 
 /**
@@ -378,13 +367,11 @@ int ti_bandgap_add_hyst(struct ti_bandgap *bgp, int adc_val, int hyst_val,
         */
        ret = ti_bandgap_adc_to_mcelsius(bgp, adc_val, &temp);
        if (ret < 0)
-               goto exit;
+               return ret;
 
        temp += hyst_val;
 
        ret = ti_bandgap_mcelsius_to_adc(bgp, temp, sum);
-
-exit:
        return ret;
 }
 
@@ -542,22 +529,18 @@ exit:
  */
 static inline int ti_bandgap_validate(struct ti_bandgap *bgp, int id)
 {
-       int ret = 0;
-
        if (!bgp || IS_ERR(bgp)) {
                pr_err("%s: invalid bandgap pointer\n", __func__);
-               ret = -EINVAL;
-               goto exit;
+               return -EINVAL;
        }
 
        if ((id < 0) || (id >= bgp->conf->sensor_count)) {
                dev_err(bgp->dev, "%s: sensor id out of range (%d)\n",
                        __func__, id);
-               ret = -ERANGE;
+               return -ERANGE;
        }
 
-exit:
-       return ret;
+       return 0;
 }
 
 /**
@@ -585,12 +568,10 @@ static int _ti_bandgap_write_threshold(struct ti_bandgap *bgp, int id, int val,
 
        ret = ti_bandgap_validate(bgp, id);
        if (ret)
-               goto exit;
+               return ret;
 
-       if (!TI_BANDGAP_HAS(bgp, TALERT)) {
-               ret = -ENOTSUPP;
-               goto exit;
-       }
+       if (!TI_BANDGAP_HAS(bgp, TALERT))
+               return -ENOTSUPP;
 
        ts_data = bgp->conf->sensors[id].ts_data;
        tsr = bgp->conf->sensors[id].registers;
@@ -603,17 +584,15 @@ static int _ti_bandgap_write_threshold(struct ti_bandgap *bgp, int id, int val,
        }
 
        if (ret)
-               goto exit;
+               return ret;
 
        ret = ti_bandgap_mcelsius_to_adc(bgp, val, &adc_val);
        if (ret < 0)
-               goto exit;
+               return ret;
 
        spin_lock(&bgp->lock);
        ret = ti_bandgap_update_alert_threshold(bgp, id, adc_val, hot);
        spin_unlock(&bgp->lock);
-
-exit:
        return ret;
 }
 
@@ -656,7 +635,7 @@ static int _ti_bandgap_read_threshold(struct ti_bandgap *bgp, int id,
 
        temp = ti_bandgap_readl(bgp, tsr->bgap_threshold);
        temp = (temp & mask) >> __ffs(mask);
-       ret |= ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
+       ret = ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
        if (ret) {
                dev_err(bgp->dev, "failed to read thot\n");
                ret = -EIO;
@@ -926,11 +905,17 @@ int ti_bandgap_read_temperature(struct ti_bandgap *bgp, int id,
        if (ret)
                return ret;
 
+       if (!TI_BANDGAP_HAS(bgp, MODE_CONFIG)) {
+               ret = ti_bandgap_force_single_read(bgp, id);
+               if (ret)
+                       return ret;
+       }
+
        spin_lock(&bgp->lock);
        temp = ti_bandgap_read_temp(bgp, id);
        spin_unlock(&bgp->lock);
 
-       ret |= ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
+       ret = ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
        if (ret)
                return -EIO;
 
@@ -991,7 +976,8 @@ void *ti_bandgap_get_sensor_data(struct ti_bandgap *bgp, int id)
 static int
 ti_bandgap_force_single_read(struct ti_bandgap *bgp, int id)
 {
-       u32 temp = 0, counter = 1000;
+       u32 counter = 1000;
+       struct temp_sensor_registers *tsr;
 
        /* Select single conversion mode */
        if (TI_BANDGAP_HAS(bgp, MODE_CONFIG))
@@ -999,16 +985,27 @@ ti_bandgap_force_single_read(struct ti_bandgap *bgp, int id)
 
        /* Start of Conversion = 1 */
        RMW_BITS(bgp, id, temp_sensor_ctrl, bgap_soc_mask, 1);
-       /* Wait until DTEMP is updated */
-       temp = ti_bandgap_read_temp(bgp, id);
 
-       while ((temp == 0) && --counter)
-               temp = ti_bandgap_read_temp(bgp, id);
-       /* REVISIT: Check correct condition for end of conversion */
+       /* Wait for EOCZ going up */
+       tsr = bgp->conf->sensors[id].registers;
+
+       while (--counter) {
+               if (ti_bandgap_readl(bgp, tsr->temp_sensor_ctrl) &
+                   tsr->bgap_eocz_mask)
+                       break;
+       }
 
        /* Start of Conversion = 0 */
        RMW_BITS(bgp, id, temp_sensor_ctrl, bgap_soc_mask, 0);
 
+       /* Wait for EOCZ going down */
+       counter = 1000;
+       while (--counter) {
+               if (!(ti_bandgap_readl(bgp, tsr->temp_sensor_ctrl) &
+                     tsr->bgap_eocz_mask))
+                       break;
+       }
+
        return 0;
 }
 
@@ -1277,6 +1274,10 @@ int ti_bandgap_probe(struct platform_device *pdev)
        }
        bgp->dev = &pdev->dev;
 
+       if (TI_BANDGAP_HAS(bgp, UNRELIABLE))
+               dev_warn(&pdev->dev,
+                        "This OMAP thermal sensor is unreliable. You've been warned\n");
+
        if (TI_BANDGAP_HAS(bgp, TSHUT)) {
                ret = ti_bandgap_tshut_init(bgp, pdev);
                if (ret) {
@@ -1294,11 +1295,10 @@ int ti_bandgap_probe(struct platform_device *pdev)
                goto free_irqs;
        }
 
-       bgp->div_clk = clk_get(NULL,  bgp->conf->div_ck_name);
+       bgp->div_clk = clk_get(NULL, bgp->conf->div_ck_name);
        ret = IS_ERR(bgp->div_clk);
        if (ret) {
-               dev_err(&pdev->dev,
-                       "failed to request div_ts_ck clock ref\n");
+               dev_err(&pdev->dev, "failed to request div_ts_ck clock ref\n");
                ret = PTR_ERR(bgp->div_clk);
                goto free_irqs;
        }
@@ -1583,6 +1583,16 @@ static SIMPLE_DEV_PM_OPS(ti_bandgap_dev_pm_ops, ti_bandgap_suspend,
 #endif
 
 static const struct of_device_id of_ti_bandgap_match[] = {
+#ifdef CONFIG_OMAP3_THERMAL
+       {
+               .compatible = "ti,omap34xx-bandgap",
+               .data = (void *)&omap34xx_data,
+       },
+       {
+               .compatible = "ti,omap36xx-bandgap",
+               .data = (void *)&omap36xx_data,
+       },
+#endif
 #ifdef CONFIG_OMAP4_THERMAL
        {
                .compatible = "ti,omap4430-bandgap",