]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
devfreq: Account only powered time in trans_stat
authorArto Merilainen <amerilainen@nvidia.com>
Mon, 7 Jul 2014 12:50:21 +0000 (15:50 +0300)
committerMandar Padmawar <mpadmawar@nvidia.com>
Thu, 10 Jul 2014 12:32:41 +0000 (05:32 -0700)
This patch modifies devfreq to account only the time a device is
powered in trans_stat. In addition, this patch also fixes a race
in trans_stat maintenance in cases where the node is readed at
the same time the transition table is being updated by frequency
re-estimation.

Change-Id: I6e4341317b6dda88d69028c9f67785400e5a7a65
Signed-off-by: Arto Merilainen <amerilainen@nvidia.com>
Reviewed-on: http://git-master/r/435174
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com>
Reviewed-by: Prajakta Gudadhe <pgudadhe@nvidia.com>
Reviewed-by: Samuel Russell <samuelr@nvidia.com>
Tested-by: Samuel Russell <samuelr@nvidia.com>
Reviewed-by: Ilan Aelion <iaelion@nvidia.com>
drivers/devfreq/devfreq.c
include/linux/devfreq.h

index 177b5fd51abacf7bdede47d5265b860ed2ac5432..bf5477cfe259fa1404a0e627ac8078fb53668fa4 100644 (file)
@@ -111,6 +111,9 @@ static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
        int lev, prev_lev;
        unsigned long cur_time;
 
+       if (devfreq->suspended)
+               return 0;
+
        lev = devfreq_get_freq_level(devfreq, freq);
        if (lev < 0)
                return lev;
@@ -558,6 +561,12 @@ int devfreq_suspend_device(struct devfreq *devfreq)
        if (!devfreq)
                return -EINVAL;
 
+       /* Last update before suspend */
+       mutex_lock(&devfreq->lock);
+       devfreq_update_status(devfreq, devfreq->previous_freq);
+       devfreq->suspended = true;
+       mutex_unlock(&devfreq->lock);
+
        if (!devfreq->governor)
                return 0;
 
@@ -575,6 +584,12 @@ int devfreq_resume_device(struct devfreq *devfreq)
        if (!devfreq)
                return -EINVAL;
 
+       /* Update the timestamp before resuming */
+       mutex_lock(&devfreq->lock);
+       devfreq->last_stat_updated = jiffies;
+       devfreq->suspended = false;
+       mutex_unlock(&devfreq->lock);
+
        if (!devfreq->governor)
                return 0;
 
@@ -941,9 +956,11 @@ static ssize_t show_trans_table(struct device *dev, struct device_attribute *att
        int prev_freq_level;
        unsigned long prev_freq;
 
+       mutex_lock(&devfreq->lock);
        err = devfreq_update_status(devfreq, devfreq->previous_freq);
        if (err)
                return 0;
+       mutex_unlock(&devfreq->lock);
 
        /* round the current frequency */
        prev_freq_level = devfreq_get_freq_level(devfreq,
@@ -963,7 +980,8 @@ static ssize_t show_trans_table(struct device *dev, struct device_attribute *att
        len += sprintf(buf + len, "   time(ms)\n");
 
        for (i = 0; i < max_state; i++) {
-               if (devfreq->profile->freq_table[i] == prev_freq) {
+               if (devfreq->profile->freq_table[i] == prev_freq &&
+                   !devfreq->suspended) {
                        len += sprintf(buf + len, "*");
                } else {
                        len += sprintf(buf + len, " ");
index 83cd456573fcd30ee543f505e15084e7eb1d93dc..1f2e3651f7342cb1bd009e5e886332c091f2bf85 100644 (file)
@@ -177,6 +177,7 @@ struct devfreq {
        unsigned int *trans_table;
        unsigned long *time_in_state;
        unsigned long last_stat_updated;
+       bool suspended;
 };
 
 #if defined(CONFIG_PM_DEVFREQ)