aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChanwoo Choi <cw00.choi@samsung.com>2015-11-18 00:49:02 -0500
committerMyungJoo Ham <myungjoo.ham@samsung.com>2016-01-13 03:30:32 -0500
commit0ec09ac2cebe9769491a470c33edff0f873ff79d (patch)
treeb6e558e0e0c6007eeb1b94a21c213cddd762018c
parent3104fa3081126c9bda35793af5f335d0ee0d5818 (diff)
PM / devfreq: Set the freq_table of devfreq device
This patch initialize the freq_table array of each devfreq device by using the devfreq_set_freq_table(). If freq_table is NULL, the devfreq framework is not able to support the frequency transtion information through sysfs. The OPP core uses the integer type for the number of opps in the opp list and uses the 'unsigned long' type for each frequency. So, this patch modifies the type of some variable as following: - the type of freq_table : unsigned int -> unsigned long - the type of max_state : unsigned int -> int - Corrected types, format strings, mutex usages by MyungJoo Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
-rw-r--r--drivers/devfreq/devfreq.c50
-rw-r--r--include/linux/devfreq.h2
2 files changed, 49 insertions, 3 deletions
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 49fc7dcf664c..f3ee2388bf6e 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -85,6 +85,46 @@ static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq)
85} 85}
86 86
87/** 87/**
88 * devfreq_set_freq_table() - Initialize freq_table for the frequency
89 * @devfreq: the devfreq instance
90 */
91static void devfreq_set_freq_table(struct devfreq *devfreq)
92{
93 struct devfreq_dev_profile *profile = devfreq->profile;
94 struct dev_pm_opp *opp;
95 unsigned long freq;
96 int i, count;
97
98 /* Initialize the freq_table from OPP table */
99 count = dev_pm_opp_get_opp_count(devfreq->dev.parent);
100 if (count <= 0)
101 return;
102
103 profile->max_state = count;
104 profile->freq_table = devm_kcalloc(devfreq->dev.parent,
105 profile->max_state,
106 sizeof(*profile->freq_table),
107 GFP_KERNEL);
108 if (!profile->freq_table) {
109 profile->max_state = 0;
110 return;
111 }
112
113 rcu_read_lock();
114 for (i = 0, freq = 0; i < profile->max_state; i++, freq++) {
115 opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &freq);
116 if (IS_ERR(opp)) {
117 devm_kfree(devfreq->dev.parent, profile->freq_table);
118 profile->max_state = 0;
119 rcu_read_unlock();
120 return;
121 }
122 profile->freq_table[i] = freq;
123 }
124 rcu_read_unlock();
125}
126
127/**
88 * devfreq_update_status() - Update statistics of devfreq behavior 128 * devfreq_update_status() - Update statistics of devfreq behavior
89 * @devfreq: the devfreq instance 129 * @devfreq: the devfreq instance
90 * @freq: the update target frequency 130 * @freq: the update target frequency
@@ -478,6 +518,12 @@ struct devfreq *devfreq_add_device(struct device *dev,
478 devfreq->data = data; 518 devfreq->data = data;
479 devfreq->nb.notifier_call = devfreq_notifier_call; 519 devfreq->nb.notifier_call = devfreq_notifier_call;
480 520
521 if (!devfreq->profile->max_state && !devfreq->profile->freq_table) {
522 mutex_unlock(&devfreq->lock);
523 devfreq_set_freq_table(devfreq);
524 mutex_lock(&devfreq->lock);
525 }
526
481 devfreq->trans_table = devm_kzalloc(dev, sizeof(unsigned int) * 527 devfreq->trans_table = devm_kzalloc(dev, sizeof(unsigned int) *
482 devfreq->profile->max_state * 528 devfreq->profile->max_state *
483 devfreq->profile->max_state, 529 devfreq->profile->max_state,
@@ -1007,7 +1053,7 @@ static ssize_t trans_stat_show(struct device *dev,
1007 len = sprintf(buf, " From : To\n"); 1053 len = sprintf(buf, " From : To\n");
1008 len += sprintf(buf + len, " :"); 1054 len += sprintf(buf + len, " :");
1009 for (i = 0; i < max_state; i++) 1055 for (i = 0; i < max_state; i++)
1010 len += sprintf(buf + len, "%8u", 1056 len += sprintf(buf + len, "%8lu",
1011 devfreq->profile->freq_table[i]); 1057 devfreq->profile->freq_table[i]);
1012 1058
1013 len += sprintf(buf + len, " time(ms)\n"); 1059 len += sprintf(buf + len, " time(ms)\n");
@@ -1019,7 +1065,7 @@ static ssize_t trans_stat_show(struct device *dev,
1019 } else { 1065 } else {
1020 len += sprintf(buf + len, " "); 1066 len += sprintf(buf + len, " ");
1021 } 1067 }
1022 len += sprintf(buf + len, "%8u:", 1068 len += sprintf(buf + len, "%8lu:",
1023 devfreq->profile->freq_table[i]); 1069 devfreq->profile->freq_table[i]);
1024 for (j = 0; j < max_state; j++) 1070 for (j = 0; j < max_state; j++)
1025 len += sprintf(buf + len, "%8u", 1071 len += sprintf(buf + len, "%8u",
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 68030e22af35..6fa02a20eb63 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -89,7 +89,7 @@ struct devfreq_dev_profile {
89 int (*get_cur_freq)(struct device *dev, unsigned long *freq); 89 int (*get_cur_freq)(struct device *dev, unsigned long *freq);
90 void (*exit)(struct device *dev); 90 void (*exit)(struct device *dev);
91 91
92 unsigned int *freq_table; 92 unsigned long *freq_table;
93 unsigned int max_state; 93 unsigned int max_state;
94}; 94};
95 95