Merge branch 'pm-em'
[linux-2.6-microblaze.git] / drivers / thermal / devfreq_cooling.c
index 262e62a..50dec24 100644 (file)
@@ -87,6 +87,7 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
        struct devfreq_cooling_device *dfc = cdev->devdata;
        struct devfreq *df = dfc->devfreq;
        struct device *dev = df->dev.parent;
+       struct em_perf_state *table;
        unsigned long freq;
        int perf_idx;
 
@@ -100,7 +101,11 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
 
        if (dfc->em_pd) {
                perf_idx = dfc->max_state - state;
-               freq = dfc->em_pd->table[perf_idx].frequency * 1000;
+
+               rcu_read_lock();
+               table = em_perf_state_from_pd(dfc->em_pd);
+               freq = table[perf_idx].frequency * 1000;
+               rcu_read_unlock();
        } else {
                freq = dfc->freq_table[state];
        }
@@ -123,14 +128,21 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
  */
 static int get_perf_idx(struct em_perf_domain *em_pd, unsigned long freq)
 {
-       int i;
+       struct em_perf_state *table;
+       int i, idx = -EINVAL;
 
+       rcu_read_lock();
+       table = em_perf_state_from_pd(em_pd);
        for (i = 0; i < em_pd->nr_perf_states; i++) {
-               if (em_pd->table[i].frequency == freq)
-                       return i;
+               if (table[i].frequency != freq)
+                       continue;
+
+               idx = i;
+               break;
        }
+       rcu_read_unlock();
 
-       return -EINVAL;
+       return idx;
 }
 
 static unsigned long get_voltage(struct devfreq *df, unsigned long freq)
@@ -181,6 +193,7 @@ static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cd
        struct devfreq_cooling_device *dfc = cdev->devdata;
        struct devfreq *df = dfc->devfreq;
        struct devfreq_dev_status status;
+       struct em_perf_state *table;
        unsigned long state;
        unsigned long freq;
        unsigned long voltage;
@@ -204,7 +217,11 @@ static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cd
                        state = dfc->capped_state;
 
                        /* Convert EM power into milli-Watts first */
-                       dfc->res_util = dfc->em_pd->table[state].power;
+                       rcu_read_lock();
+                       table = em_perf_state_from_pd(dfc->em_pd);
+                       dfc->res_util = table[state].power;
+                       rcu_read_unlock();
+
                        dfc->res_util /= MICROWATT_PER_MILLIWATT;
 
                        dfc->res_util *= SCALE_ERROR_MITIGATION;
@@ -225,7 +242,11 @@ static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cd
                _normalize_load(&status);
 
                /* Convert EM power into milli-Watts first */
-               *power = dfc->em_pd->table[perf_idx].power;
+               rcu_read_lock();
+               table = em_perf_state_from_pd(dfc->em_pd);
+               *power = table[perf_idx].power;
+               rcu_read_unlock();
+
                *power /= MICROWATT_PER_MILLIWATT;
                /* Scale power for utilization */
                *power *= status.busy_time;
@@ -245,13 +266,19 @@ static int devfreq_cooling_state2power(struct thermal_cooling_device *cdev,
                                       unsigned long state, u32 *power)
 {
        struct devfreq_cooling_device *dfc = cdev->devdata;
+       struct em_perf_state *table;
        int perf_idx;
 
        if (state > dfc->max_state)
                return -EINVAL;
 
        perf_idx = dfc->max_state - state;
-       *power = dfc->em_pd->table[perf_idx].power;
+
+       rcu_read_lock();
+       table = em_perf_state_from_pd(dfc->em_pd);
+       *power = table[perf_idx].power;
+       rcu_read_unlock();
+
        *power /= MICROWATT_PER_MILLIWATT;
 
        return 0;
@@ -264,6 +291,7 @@ static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev,
        struct devfreq *df = dfc->devfreq;
        struct devfreq_dev_status status;
        unsigned long freq, em_power_mw;
+       struct em_perf_state *table;
        s32 est_power;
        int i;
 
@@ -288,13 +316,16 @@ static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev,
         * Find the first cooling state that is within the power
         * budget. The EM power table is sorted ascending.
         */
+       rcu_read_lock();
+       table = em_perf_state_from_pd(dfc->em_pd);
        for (i = dfc->max_state; i > 0; i--) {
                /* Convert EM power to milli-Watts to make safe comparison */
-               em_power_mw = dfc->em_pd->table[i].power;
+               em_power_mw = table[i].power;
                em_power_mw /= MICROWATT_PER_MILLIWATT;
                if (est_power >= em_power_mw)
                        break;
        }
+       rcu_read_unlock();
 
        *state = dfc->max_state - i;
        dfc->capped_state = *state;