aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-01-31 07:18:06 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-01-31 07:18:06 -0500
commit23b017a623a0bd19c24e6c1c41fe587c644e9dbc (patch)
treebeb477ac919f1a2911bd43681f310354bd0045a8
parent566cf877a1fcb6d6dc0126b076aad062054c2637 (diff)
parent4585fbcb5331fc910b7e553ad3efd0dd7b320d14 (diff)
Merge tag 'pullreq_20170131' of https://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq into pm-devfreq
Pull devfreq changes for v4.11 from MyungJoo Ham. * tag 'pullreq_20170131' of https://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq: PM / devfreq: Modify the device name as devfreq(X) for sysfs PM / devfreq: Simplify the sysfs name of devfreq-event device PM / devfreq: Remove unnecessary separate _remove_devfreq() PM / devfreq: Fix wrong trans_stat of passive devfreq device PM / devfreq: Fix available_governor sysfs PM / devfreq: exynos-ppmu: Show the registred device for ppmu device PM / devfreq: Fix the wrong description for userspace governor PM / devfreq: Fix the checkpatch warnings PM / devfreq: exynos-bus: Print the real clock rate of bus PM / devfreq: exynos-ppmu: Use the regmap interface to handle the registers PM / devfreq: exynos-bus: Add the detailed correlation for Exynos5433 PM / devfreq: Don't delete sysfs group twice
-rw-r--r--Documentation/ABI/testing/sysfs-class-devfreq-event25
-rw-r--r--Documentation/devicetree/bindings/devfreq/exynos-bus.txt14
-rw-r--r--drivers/devfreq/devfreq-event.c4
-rw-r--r--drivers/devfreq/devfreq.c74
-rw-r--r--drivers/devfreq/event/exynos-ppmu.c329
-rw-r--r--drivers/devfreq/exynos-bus.c8
-rw-r--r--drivers/devfreq/governor.h2
-rw-r--r--drivers/devfreq/governor_passive.c6
-rw-r--r--drivers/devfreq/governor_userspace.c11
-rw-r--r--include/linux/devfreq.h3
10 files changed, 350 insertions, 126 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-devfreq-event b/Documentation/ABI/testing/sysfs-class-devfreq-event
new file mode 100644
index 000000000000..ceaf0f686d4a
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-devfreq-event
@@ -0,0 +1,25 @@
1What: /sys/class/devfreq-event/event(x)/
2Date: January 2017
3Contact: Chanwoo Choi <cw00.choi@samsung.com>
4Description:
5 Provide a place in sysfs for the devfreq-event objects.
6 This allows accessing various devfreq-event specific variables.
7 The name of devfreq-event object denoted as 'event(x)' which
8 includes the unique number of 'x' for each devfreq-event object.
9
10What: /sys/class/devfreq-event/event(x)/name
11Date: January 2017
12Contact: Chanwoo Choi <cw00.choi@samsung.com>
13Description:
14 The /sys/class/devfreq-event/event(x)/name attribute contains
15 the name of the devfreq-event object. This attribute is
16 read-only.
17
18What: /sys/class/devfreq-event/event(x)/enable_count
19Date: January 2017
20Contact: Chanwoo Choi <cw00.choi@samsung.com>
21Description:
22 The /sys/class/devfreq-event/event(x)/enable_count attribute
23 contains the reference count to enable the devfreq-event
24 object. If the device is enabled, the value of attribute is
25 greater than zero.
diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
index d3ec8e676b6b..d085ef90d27c 100644
--- a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
+++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
@@ -123,6 +123,20 @@ Detailed correlation between sub-blocks and power line according to Exynos SoC:
123 |--- FSYS 123 |--- FSYS
124 |--- FSYS2 124 |--- FSYS2
125 125
126- In case of Exynos5433, there is VDD_INT power line as following:
127 VDD_INT |--- G2D (parent device)
128 |--- MSCL
129 |--- GSCL
130 |--- JPEG
131 |--- MFC
132 |--- HEVC
133 |--- BUS0
134 |--- BUS1
135 |--- BUS2
136 |--- PERIS (Fixed clock rate)
137 |--- PERIC (Fixed clock rate)
138 |--- FSYS (Fixed clock rate)
139
126Example1: 140Example1:
127 Show the AXI buses of Exynos3250 SoC. Exynos3250 divides the buses to 141 Show the AXI buses of Exynos3250 SoC. Exynos3250 divides the buses to
128 power line (regulator). The MIF (Memory Interface) AXI bus is used to 142 power line (regulator). The MIF (Memory Interface) AXI bus is used to
diff --git a/drivers/devfreq/devfreq-event.c b/drivers/devfreq/devfreq-event.c
index 9aea2c7ecbe6..8648b32ebc89 100644
--- a/drivers/devfreq/devfreq-event.c
+++ b/drivers/devfreq/devfreq-event.c
@@ -306,7 +306,7 @@ struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev,
306 struct devfreq_event_desc *desc) 306 struct devfreq_event_desc *desc)
307{ 307{
308 struct devfreq_event_dev *edev; 308 struct devfreq_event_dev *edev;
309 static atomic_t event_no = ATOMIC_INIT(0); 309 static atomic_t event_no = ATOMIC_INIT(-1);
310 int ret; 310 int ret;
311 311
312 if (!dev || !desc) 312 if (!dev || !desc)
@@ -329,7 +329,7 @@ struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev,
329 edev->dev.class = devfreq_event_class; 329 edev->dev.class = devfreq_event_class;
330 edev->dev.release = devfreq_event_release_edev; 330 edev->dev.release = devfreq_event_release_edev;
331 331
332 dev_set_name(&edev->dev, "event.%d", atomic_inc_return(&event_no) - 1); 332 dev_set_name(&edev->dev, "event%d", atomic_inc_return(&event_no));
333 ret = device_register(&edev->dev); 333 ret = device_register(&edev->dev);
334 if (ret < 0) { 334 if (ret < 0) {
335 put_device(&edev->dev); 335 put_device(&edev->dev);
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 47206a21bb90..4aa72b5ed660 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -130,7 +130,7 @@ static void devfreq_set_freq_table(struct devfreq *devfreq)
130 * @devfreq: the devfreq instance 130 * @devfreq: the devfreq instance
131 * @freq: the update target frequency 131 * @freq: the update target frequency
132 */ 132 */
133static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq) 133int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
134{ 134{
135 int lev, prev_lev, ret = 0; 135 int lev, prev_lev, ret = 0;
136 unsigned long cur_time; 136 unsigned long cur_time;
@@ -166,6 +166,7 @@ out:
166 devfreq->last_stat_updated = cur_time; 166 devfreq->last_stat_updated = cur_time;
167 return ret; 167 return ret;
168} 168}
169EXPORT_SYMBOL(devfreq_update_status);
169 170
170/** 171/**
171 * find_devfreq_governor() - find devfreq governor from name 172 * find_devfreq_governor() - find devfreq governor from name
@@ -474,11 +475,15 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
474} 475}
475 476
476/** 477/**
477 * _remove_devfreq() - Remove devfreq from the list and release its resources. 478 * devfreq_dev_release() - Callback for struct device to release the device.
478 * @devfreq: the devfreq struct 479 * @dev: the devfreq device
480 *
481 * Remove devfreq from the list and release its resources.
479 */ 482 */
480static void _remove_devfreq(struct devfreq *devfreq) 483static void devfreq_dev_release(struct device *dev)
481{ 484{
485 struct devfreq *devfreq = to_devfreq(dev);
486
482 mutex_lock(&devfreq_list_lock); 487 mutex_lock(&devfreq_list_lock);
483 if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) { 488 if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) {
484 mutex_unlock(&devfreq_list_lock); 489 mutex_unlock(&devfreq_list_lock);
@@ -500,19 +505,6 @@ static void _remove_devfreq(struct devfreq *devfreq)
500} 505}
501 506
502/** 507/**
503 * devfreq_dev_release() - Callback for struct device to release the device.
504 * @dev: the devfreq device
505 *
506 * This calls _remove_devfreq() if _remove_devfreq() is not called.
507 */
508static void devfreq_dev_release(struct device *dev)
509{
510 struct devfreq *devfreq = to_devfreq(dev);
511
512 _remove_devfreq(devfreq);
513}
514
515/**
516 * devfreq_add_device() - Add devfreq feature to the device 508 * devfreq_add_device() - Add devfreq feature to the device
517 * @dev: the device to add devfreq feature. 509 * @dev: the device to add devfreq feature.
518 * @profile: device-specific profile to run devfreq. 510 * @profile: device-specific profile to run devfreq.
@@ -527,6 +519,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
527{ 519{
528 struct devfreq *devfreq; 520 struct devfreq *devfreq;
529 struct devfreq_governor *governor; 521 struct devfreq_governor *governor;
522 static atomic_t devfreq_no = ATOMIC_INIT(-1);
530 int err = 0; 523 int err = 0;
531 524
532 if (!dev || !profile || !governor_name) { 525 if (!dev || !profile || !governor_name) {
@@ -538,15 +531,14 @@ struct devfreq *devfreq_add_device(struct device *dev,
538 devfreq = find_device_devfreq(dev); 531 devfreq = find_device_devfreq(dev);
539 mutex_unlock(&devfreq_list_lock); 532 mutex_unlock(&devfreq_list_lock);
540 if (!IS_ERR(devfreq)) { 533 if (!IS_ERR(devfreq)) {
541 dev_err(dev, "%s: Unable to create devfreq for the device. It already has one.\n", __func__); 534 dev_err(dev, "%s: Unable to create devfreq for the device.\n",
535 __func__);
542 err = -EINVAL; 536 err = -EINVAL;
543 goto err_out; 537 goto err_out;
544 } 538 }
545 539
546 devfreq = kzalloc(sizeof(struct devfreq), GFP_KERNEL); 540 devfreq = kzalloc(sizeof(struct devfreq), GFP_KERNEL);
547 if (!devfreq) { 541 if (!devfreq) {
548 dev_err(dev, "%s: Unable to create devfreq for the device\n",
549 __func__);
550 err = -ENOMEM; 542 err = -ENOMEM;
551 goto err_out; 543 goto err_out;
552 } 544 }
@@ -569,18 +561,21 @@ struct devfreq *devfreq_add_device(struct device *dev,
569 mutex_lock(&devfreq->lock); 561 mutex_lock(&devfreq->lock);
570 } 562 }
571 563
572 dev_set_name(&devfreq->dev, "%s", dev_name(dev)); 564 dev_set_name(&devfreq->dev, "devfreq%d",
565 atomic_inc_return(&devfreq_no));
573 err = device_register(&devfreq->dev); 566 err = device_register(&devfreq->dev);
574 if (err) { 567 if (err) {
575 mutex_unlock(&devfreq->lock); 568 mutex_unlock(&devfreq->lock);
576 goto err_out; 569 goto err_out;
577 } 570 }
578 571
579 devfreq->trans_table = devm_kzalloc(&devfreq->dev, sizeof(unsigned int) * 572 devfreq->trans_table = devm_kzalloc(&devfreq->dev,
573 sizeof(unsigned int) *
580 devfreq->profile->max_state * 574 devfreq->profile->max_state *
581 devfreq->profile->max_state, 575 devfreq->profile->max_state,
582 GFP_KERNEL); 576 GFP_KERNEL);
583 devfreq->time_in_state = devm_kzalloc(&devfreq->dev, sizeof(unsigned long) * 577 devfreq->time_in_state = devm_kzalloc(&devfreq->dev,
578 sizeof(unsigned long) *
584 devfreq->profile->max_state, 579 devfreq->profile->max_state,
585 GFP_KERNEL); 580 GFP_KERNEL);
586 devfreq->last_stat_updated = jiffies; 581 devfreq->last_stat_updated = jiffies;
@@ -939,6 +934,9 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
939 if (df->governor == governor) { 934 if (df->governor == governor) {
940 ret = 0; 935 ret = 0;
941 goto out; 936 goto out;
937 } else if (df->governor->immutable || governor->immutable) {
938 ret = -EINVAL;
939 goto out;
942 } 940 }
943 941
944 if (df->governor) { 942 if (df->governor) {
@@ -968,13 +966,33 @@ static ssize_t available_governors_show(struct device *d,
968 struct device_attribute *attr, 966 struct device_attribute *attr,
969 char *buf) 967 char *buf)
970{ 968{
971 struct devfreq_governor *tmp_governor; 969 struct devfreq *df = to_devfreq(d);
972 ssize_t count = 0; 970 ssize_t count = 0;
973 971
974 mutex_lock(&devfreq_list_lock); 972 mutex_lock(&devfreq_list_lock);
975 list_for_each_entry(tmp_governor, &devfreq_governor_list, node) 973
976 count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), 974 /*
977 "%s ", tmp_governor->name); 975 * The devfreq with immutable governor (e.g., passive) shows
976 * only own governor.
977 */
978 if (df->governor->immutable) {
979 count = scnprintf(&buf[count], DEVFREQ_NAME_LEN,
980 "%s ", df->governor_name);
981 /*
982 * The devfreq device shows the registered governor except for
983 * immutable governors such as passive governor .
984 */
985 } else {
986 struct devfreq_governor *governor;
987
988 list_for_each_entry(governor, &devfreq_governor_list, node) {
989 if (governor->immutable)
990 continue;
991 count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
992 "%s ", governor->name);
993 }
994 }
995
978 mutex_unlock(&devfreq_list_lock); 996 mutex_unlock(&devfreq_list_lock);
979 997
980 /* Truncate the trailing space */ 998 /* Truncate the trailing space */
@@ -995,7 +1013,7 @@ static ssize_t cur_freq_show(struct device *dev, struct device_attribute *attr,
995 1013
996 if (devfreq->profile->get_cur_freq && 1014 if (devfreq->profile->get_cur_freq &&
997 !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq)) 1015 !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq))
998 return sprintf(buf, "%lu\n", freq); 1016 return sprintf(buf, "%lu\n", freq);
999 1017
1000 return sprintf(buf, "%lu\n", devfreq->previous_freq); 1018 return sprintf(buf, "%lu\n", devfreq->previous_freq);
1001} 1019}
diff --git a/drivers/devfreq/event/exynos-ppmu.c b/drivers/devfreq/event/exynos-ppmu.c
index 107eb91a9415..9b7350935b73 100644
--- a/drivers/devfreq/event/exynos-ppmu.c
+++ b/drivers/devfreq/event/exynos-ppmu.c
@@ -17,13 +17,13 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/of_address.h> 18#include <linux/of_address.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/regmap.h>
20#include <linux/suspend.h> 21#include <linux/suspend.h>
21#include <linux/devfreq-event.h> 22#include <linux/devfreq-event.h>
22 23
23#include "exynos-ppmu.h" 24#include "exynos-ppmu.h"
24 25
25struct exynos_ppmu_data { 26struct exynos_ppmu_data {
26 void __iomem *base;
27 struct clk *clk; 27 struct clk *clk;
28}; 28};
29 29
@@ -33,6 +33,7 @@ struct exynos_ppmu {
33 unsigned int num_events; 33 unsigned int num_events;
34 34
35 struct device *dev; 35 struct device *dev;
36 struct regmap *regmap;
36 37
37 struct exynos_ppmu_data ppmu; 38 struct exynos_ppmu_data ppmu;
38}; 39};
@@ -107,20 +108,28 @@ static int exynos_ppmu_find_ppmu_id(struct devfreq_event_dev *edev)
107static int exynos_ppmu_disable(struct devfreq_event_dev *edev) 108static int exynos_ppmu_disable(struct devfreq_event_dev *edev)
108{ 109{
109 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); 110 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev);
111 int ret;
110 u32 pmnc; 112 u32 pmnc;
111 113
112 /* Disable all counters */ 114 /* Disable all counters */
113 __raw_writel(PPMU_CCNT_MASK | 115 ret = regmap_write(info->regmap, PPMU_CNTENC,
114 PPMU_PMCNT0_MASK | 116 PPMU_CCNT_MASK |
115 PPMU_PMCNT1_MASK | 117 PPMU_PMCNT0_MASK |
116 PPMU_PMCNT2_MASK | 118 PPMU_PMCNT1_MASK |
117 PPMU_PMCNT3_MASK, 119 PPMU_PMCNT2_MASK |
118 info->ppmu.base + PPMU_CNTENC); 120 PPMU_PMCNT3_MASK);
121 if (ret < 0)
122 return ret;
119 123
120 /* Disable PPMU */ 124 /* Disable PPMU */
121 pmnc = __raw_readl(info->ppmu.base + PPMU_PMNC); 125 ret = regmap_read(info->regmap, PPMU_PMNC, &pmnc);
126 if (ret < 0)
127 return ret;
128
122 pmnc &= ~PPMU_PMNC_ENABLE_MASK; 129 pmnc &= ~PPMU_PMNC_ENABLE_MASK;
123 __raw_writel(pmnc, info->ppmu.base + PPMU_PMNC); 130 ret = regmap_write(info->regmap, PPMU_PMNC, pmnc);
131 if (ret < 0)
132 return ret;
124 133
125 return 0; 134 return 0;
126} 135}
@@ -129,29 +138,42 @@ static int exynos_ppmu_set_event(struct devfreq_event_dev *edev)
129{ 138{
130 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); 139 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev);
131 int id = exynos_ppmu_find_ppmu_id(edev); 140 int id = exynos_ppmu_find_ppmu_id(edev);
141 int ret;
132 u32 pmnc, cntens; 142 u32 pmnc, cntens;
133 143
134 if (id < 0) 144 if (id < 0)
135 return id; 145 return id;
136 146
137 /* Enable specific counter */ 147 /* Enable specific counter */
138 cntens = __raw_readl(info->ppmu.base + PPMU_CNTENS); 148 ret = regmap_read(info->regmap, PPMU_CNTENS, &cntens);
149 if (ret < 0)
150 return ret;
151
139 cntens |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id)); 152 cntens |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id));
140 __raw_writel(cntens, info->ppmu.base + PPMU_CNTENS); 153 ret = regmap_write(info->regmap, PPMU_CNTENS, cntens);
154 if (ret < 0)
155 return ret;
141 156
142 /* Set the event of Read/Write data count */ 157 /* Set the event of Read/Write data count */
143 __raw_writel(PPMU_RO_DATA_CNT | PPMU_WO_DATA_CNT, 158 ret = regmap_write(info->regmap, PPMU_BEVTxSEL(id),
144 info->ppmu.base + PPMU_BEVTxSEL(id)); 159 PPMU_RO_DATA_CNT | PPMU_WO_DATA_CNT);
160 if (ret < 0)
161 return ret;
145 162
146 /* Reset cycle counter/performance counter and enable PPMU */ 163 /* Reset cycle counter/performance counter and enable PPMU */
147 pmnc = __raw_readl(info->ppmu.base + PPMU_PMNC); 164 ret = regmap_read(info->regmap, PPMU_PMNC, &pmnc);
165 if (ret < 0)
166 return ret;
167
148 pmnc &= ~(PPMU_PMNC_ENABLE_MASK 168 pmnc &= ~(PPMU_PMNC_ENABLE_MASK
149 | PPMU_PMNC_COUNTER_RESET_MASK 169 | PPMU_PMNC_COUNTER_RESET_MASK
150 | PPMU_PMNC_CC_RESET_MASK); 170 | PPMU_PMNC_CC_RESET_MASK);
151 pmnc |= (PPMU_ENABLE << PPMU_PMNC_ENABLE_SHIFT); 171 pmnc |= (PPMU_ENABLE << PPMU_PMNC_ENABLE_SHIFT);
152 pmnc |= (PPMU_ENABLE << PPMU_PMNC_COUNTER_RESET_SHIFT); 172 pmnc |= (PPMU_ENABLE << PPMU_PMNC_COUNTER_RESET_SHIFT);
153 pmnc |= (PPMU_ENABLE << PPMU_PMNC_CC_RESET_SHIFT); 173 pmnc |= (PPMU_ENABLE << PPMU_PMNC_CC_RESET_SHIFT);
154 __raw_writel(pmnc, info->ppmu.base + PPMU_PMNC); 174 ret = regmap_write(info->regmap, PPMU_PMNC, pmnc);
175 if (ret < 0)
176 return ret;
155 177
156 return 0; 178 return 0;
157} 179}
@@ -161,40 +183,64 @@ static int exynos_ppmu_get_event(struct devfreq_event_dev *edev,
161{ 183{
162 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); 184 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev);
163 int id = exynos_ppmu_find_ppmu_id(edev); 185 int id = exynos_ppmu_find_ppmu_id(edev);
164 u32 pmnc, cntenc; 186 unsigned int total_count, load_count;
187 unsigned int pmcnt3_high, pmcnt3_low;
188 unsigned int pmnc, cntenc;
189 int ret;
165 190
166 if (id < 0) 191 if (id < 0)
167 return -EINVAL; 192 return -EINVAL;
168 193
169 /* Disable PPMU */ 194 /* Disable PPMU */
170 pmnc = __raw_readl(info->ppmu.base + PPMU_PMNC); 195 ret = regmap_read(info->regmap, PPMU_PMNC, &pmnc);
196 if (ret < 0)
197 return ret;
198
171 pmnc &= ~PPMU_PMNC_ENABLE_MASK; 199 pmnc &= ~PPMU_PMNC_ENABLE_MASK;
172 __raw_writel(pmnc, info->ppmu.base + PPMU_PMNC); 200 ret = regmap_write(info->regmap, PPMU_PMNC, pmnc);
201 if (ret < 0)
202 return ret;
173 203
174 /* Read cycle count */ 204 /* Read cycle count */
175 edata->total_count = __raw_readl(info->ppmu.base + PPMU_CCNT); 205 ret = regmap_read(info->regmap, PPMU_CCNT, &total_count);
206 if (ret < 0)
207 return ret;
208 edata->total_count = total_count;
176 209
177 /* Read performance count */ 210 /* Read performance count */
178 switch (id) { 211 switch (id) {
179 case PPMU_PMNCNT0: 212 case PPMU_PMNCNT0:
180 case PPMU_PMNCNT1: 213 case PPMU_PMNCNT1:
181 case PPMU_PMNCNT2: 214 case PPMU_PMNCNT2:
182 edata->load_count 215 ret = regmap_read(info->regmap, PPMU_PMNCT(id), &load_count);
183 = __raw_readl(info->ppmu.base + PPMU_PMNCT(id)); 216 if (ret < 0)
217 return ret;
218 edata->load_count = load_count;
184 break; 219 break;
185 case PPMU_PMNCNT3: 220 case PPMU_PMNCNT3:
186 edata->load_count = 221 ret = regmap_read(info->regmap, PPMU_PMCNT3_HIGH, &pmcnt3_high);
187 ((__raw_readl(info->ppmu.base + PPMU_PMCNT3_HIGH) << 8) 222 if (ret < 0)
188 | __raw_readl(info->ppmu.base + PPMU_PMCNT3_LOW)); 223 return ret;
224
225 ret = regmap_read(info->regmap, PPMU_PMCNT3_LOW, &pmcnt3_low);
226 if (ret < 0)
227 return ret;
228
229 edata->load_count = ((pmcnt3_high << 8) | pmcnt3_low);
189 break; 230 break;
190 default: 231 default:
191 return -EINVAL; 232 return -EINVAL;
192 } 233 }
193 234
194 /* Disable specific counter */ 235 /* Disable specific counter */
195 cntenc = __raw_readl(info->ppmu.base + PPMU_CNTENC); 236 ret = regmap_read(info->regmap, PPMU_CNTENC, &cntenc);
237 if (ret < 0)
238 return ret;
239
196 cntenc |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id)); 240 cntenc |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id));
197 __raw_writel(cntenc, info->ppmu.base + PPMU_CNTENC); 241 ret = regmap_write(info->regmap, PPMU_CNTENC, cntenc);
242 if (ret < 0)
243 return ret;
198 244
199 dev_dbg(&edev->dev, "%s (event: %ld/%ld)\n", edev->desc->name, 245 dev_dbg(&edev->dev, "%s (event: %ld/%ld)\n", edev->desc->name,
200 edata->load_count, edata->total_count); 246 edata->load_count, edata->total_count);
@@ -214,36 +260,93 @@ static const struct devfreq_event_ops exynos_ppmu_ops = {
214static int exynos_ppmu_v2_disable(struct devfreq_event_dev *edev) 260static int exynos_ppmu_v2_disable(struct devfreq_event_dev *edev)
215{ 261{
216 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); 262 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev);
263 int ret;
217 u32 pmnc, clear; 264 u32 pmnc, clear;
218 265
219 /* Disable all counters */ 266 /* Disable all counters */
220 clear = (PPMU_CCNT_MASK | PPMU_PMCNT0_MASK | PPMU_PMCNT1_MASK 267 clear = (PPMU_CCNT_MASK | PPMU_PMCNT0_MASK | PPMU_PMCNT1_MASK
221 | PPMU_PMCNT2_MASK | PPMU_PMCNT3_MASK); 268 | PPMU_PMCNT2_MASK | PPMU_PMCNT3_MASK);
269 ret = regmap_write(info->regmap, PPMU_V2_FLAG, clear);
270 if (ret < 0)
271 return ret;
272
273 ret = regmap_write(info->regmap, PPMU_V2_INTENC, clear);
274 if (ret < 0)
275 return ret;
276
277 ret = regmap_write(info->regmap, PPMU_V2_CNTENC, clear);
278 if (ret < 0)
279 return ret;
280
281 ret = regmap_write(info->regmap, PPMU_V2_CNT_RESET, clear);
282 if (ret < 0)
283 return ret;
284
285 ret = regmap_write(info->regmap, PPMU_V2_CIG_CFG0, 0x0);
286 if (ret < 0)
287 return ret;
288
289 ret = regmap_write(info->regmap, PPMU_V2_CIG_CFG1, 0x0);
290 if (ret < 0)
291 return ret;
292
293 ret = regmap_write(info->regmap, PPMU_V2_CIG_CFG2, 0x0);
294 if (ret < 0)
295 return ret;
296
297 ret = regmap_write(info->regmap, PPMU_V2_CIG_RESULT, 0x0);
298 if (ret < 0)
299 return ret;
300
301 ret = regmap_write(info->regmap, PPMU_V2_CNT_AUTO, 0x0);
302 if (ret < 0)
303 return ret;
304
305 ret = regmap_write(info->regmap, PPMU_V2_CH_EV0_TYPE, 0x0);
306 if (ret < 0)
307 return ret;
308
309 ret = regmap_write(info->regmap, PPMU_V2_CH_EV1_TYPE, 0x0);
310 if (ret < 0)
311 return ret;
222 312
223 __raw_writel(clear, info->ppmu.base + PPMU_V2_FLAG); 313 ret = regmap_write(info->regmap, PPMU_V2_CH_EV2_TYPE, 0x0);
224 __raw_writel(clear, info->ppmu.base + PPMU_V2_INTENC); 314 if (ret < 0)
225 __raw_writel(clear, info->ppmu.base + PPMU_V2_CNTENC); 315 return ret;
226 __raw_writel(clear, info->ppmu.base + PPMU_V2_CNT_RESET); 316
227 317 ret = regmap_write(info->regmap, PPMU_V2_CH_EV3_TYPE, 0x0);
228 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CIG_CFG0); 318 if (ret < 0)
229 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CIG_CFG1); 319 return ret;
230 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CIG_CFG2); 320
231 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CIG_RESULT); 321 ret = regmap_write(info->regmap, PPMU_V2_SM_ID_V, 0x0);
232 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CNT_AUTO); 322 if (ret < 0)
233 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CH_EV0_TYPE); 323 return ret;
234 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CH_EV1_TYPE); 324
235 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CH_EV2_TYPE); 325 ret = regmap_write(info->regmap, PPMU_V2_SM_ID_A, 0x0);
236 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CH_EV3_TYPE); 326 if (ret < 0)
237 __raw_writel(0x0, info->ppmu.base + PPMU_V2_SM_ID_V); 327 return ret;
238 __raw_writel(0x0, info->ppmu.base + PPMU_V2_SM_ID_A); 328
239 __raw_writel(0x0, info->ppmu.base + PPMU_V2_SM_OTHERS_V); 329 ret = regmap_write(info->regmap, PPMU_V2_SM_OTHERS_V, 0x0);
240 __raw_writel(0x0, info->ppmu.base + PPMU_V2_SM_OTHERS_A); 330 if (ret < 0)
241 __raw_writel(0x0, info->ppmu.base + PPMU_V2_INTERRUPT_RESET); 331 return ret;
332
333 ret = regmap_write(info->regmap, PPMU_V2_SM_OTHERS_A, 0x0);
334 if (ret < 0)
335 return ret;
336
337 ret = regmap_write(info->regmap, PPMU_V2_INTERRUPT_RESET, 0x0);
338 if (ret < 0)
339 return ret;
242 340
243 /* Disable PPMU */ 341 /* Disable PPMU */
244 pmnc = __raw_readl(info->ppmu.base + PPMU_V2_PMNC); 342 ret = regmap_read(info->regmap, PPMU_V2_PMNC, &pmnc);
343 if (ret < 0)
344 return ret;
345
245 pmnc &= ~PPMU_PMNC_ENABLE_MASK; 346 pmnc &= ~PPMU_PMNC_ENABLE_MASK;
246 __raw_writel(pmnc, info->ppmu.base + PPMU_V2_PMNC); 347 ret = regmap_write(info->regmap, PPMU_V2_PMNC, pmnc);
348 if (ret < 0)
349 return ret;
247 350
248 return 0; 351 return 0;
249} 352}
@@ -251,30 +354,43 @@ static int exynos_ppmu_v2_disable(struct devfreq_event_dev *edev)
251static int exynos_ppmu_v2_set_event(struct devfreq_event_dev *edev) 354static int exynos_ppmu_v2_set_event(struct devfreq_event_dev *edev)
252{ 355{
253 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); 356 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev);
357 unsigned int pmnc, cntens;
254 int id = exynos_ppmu_find_ppmu_id(edev); 358 int id = exynos_ppmu_find_ppmu_id(edev);
255 u32 pmnc, cntens; 359 int ret;
256 360
257 /* Enable all counters */ 361 /* Enable all counters */
258 cntens = __raw_readl(info->ppmu.base + PPMU_V2_CNTENS); 362 ret = regmap_read(info->regmap, PPMU_V2_CNTENS, &cntens);
363 if (ret < 0)
364 return ret;
365
259 cntens |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id)); 366 cntens |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id));
260 __raw_writel(cntens, info->ppmu.base + PPMU_V2_CNTENS); 367 ret = regmap_write(info->regmap, PPMU_V2_CNTENS, cntens);
368 if (ret < 0)
369 return ret;
261 370
262 /* Set the event of Read/Write data count */ 371 /* Set the event of Read/Write data count */
263 switch (id) { 372 switch (id) {
264 case PPMU_PMNCNT0: 373 case PPMU_PMNCNT0:
265 case PPMU_PMNCNT1: 374 case PPMU_PMNCNT1:
266 case PPMU_PMNCNT2: 375 case PPMU_PMNCNT2:
267 __raw_writel(PPMU_V2_RO_DATA_CNT | PPMU_V2_WO_DATA_CNT, 376 ret = regmap_write(info->regmap, PPMU_V2_CH_EVx_TYPE(id),
268 info->ppmu.base + PPMU_V2_CH_EVx_TYPE(id)); 377 PPMU_V2_RO_DATA_CNT | PPMU_V2_WO_DATA_CNT);
378 if (ret < 0)
379 return ret;
269 break; 380 break;
270 case PPMU_PMNCNT3: 381 case PPMU_PMNCNT3:
271 __raw_writel(PPMU_V2_EVT3_RW_DATA_CNT, 382 ret = regmap_write(info->regmap, PPMU_V2_CH_EVx_TYPE(id),
272 info->ppmu.base + PPMU_V2_CH_EVx_TYPE(id)); 383 PPMU_V2_EVT3_RW_DATA_CNT);
384 if (ret < 0)
385 return ret;
273 break; 386 break;
274 } 387 }
275 388
276 /* Reset cycle counter/performance counter and enable PPMU */ 389 /* Reset cycle counter/performance counter and enable PPMU */
277 pmnc = __raw_readl(info->ppmu.base + PPMU_V2_PMNC); 390 ret = regmap_read(info->regmap, PPMU_V2_PMNC, &pmnc);
391 if (ret < 0)
392 return ret;
393
278 pmnc &= ~(PPMU_PMNC_ENABLE_MASK 394 pmnc &= ~(PPMU_PMNC_ENABLE_MASK
279 | PPMU_PMNC_COUNTER_RESET_MASK 395 | PPMU_PMNC_COUNTER_RESET_MASK
280 | PPMU_PMNC_CC_RESET_MASK 396 | PPMU_PMNC_CC_RESET_MASK
@@ -284,7 +400,10 @@ static int exynos_ppmu_v2_set_event(struct devfreq_event_dev *edev)
284 pmnc |= (PPMU_ENABLE << PPMU_PMNC_COUNTER_RESET_SHIFT); 400 pmnc |= (PPMU_ENABLE << PPMU_PMNC_COUNTER_RESET_SHIFT);
285 pmnc |= (PPMU_ENABLE << PPMU_PMNC_CC_RESET_SHIFT); 401 pmnc |= (PPMU_ENABLE << PPMU_PMNC_CC_RESET_SHIFT);
286 pmnc |= (PPMU_V2_MODE_MANUAL << PPMU_V2_PMNC_START_MODE_SHIFT); 402 pmnc |= (PPMU_V2_MODE_MANUAL << PPMU_V2_PMNC_START_MODE_SHIFT);
287 __raw_writel(pmnc, info->ppmu.base + PPMU_V2_PMNC); 403
404 ret = regmap_write(info->regmap, PPMU_V2_PMNC, pmnc);
405 if (ret < 0)
406 return ret;
288 407
289 return 0; 408 return 0;
290} 409}
@@ -294,37 +413,61 @@ static int exynos_ppmu_v2_get_event(struct devfreq_event_dev *edev,
294{ 413{
295 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); 414 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev);
296 int id = exynos_ppmu_find_ppmu_id(edev); 415 int id = exynos_ppmu_find_ppmu_id(edev);
297 u32 pmnc, cntenc; 416 int ret;
298 u32 pmcnt_high, pmcnt_low; 417 unsigned int pmnc, cntenc;
299 u64 load_count = 0; 418 unsigned int pmcnt_high, pmcnt_low;
419 unsigned int total_count, count;
420 unsigned long load_count = 0;
300 421
301 /* Disable PPMU */ 422 /* Disable PPMU */
302 pmnc = __raw_readl(info->ppmu.base + PPMU_V2_PMNC); 423 ret = regmap_read(info->regmap, PPMU_V2_PMNC, &pmnc);
424 if (ret < 0)
425 return ret;
426
303 pmnc &= ~PPMU_PMNC_ENABLE_MASK; 427 pmnc &= ~PPMU_PMNC_ENABLE_MASK;
304 __raw_writel(pmnc, info->ppmu.base + PPMU_V2_PMNC); 428 ret = regmap_write(info->regmap, PPMU_V2_PMNC, pmnc);
429 if (ret < 0)
430 return ret;
305 431
306 /* Read cycle count and performance count */ 432 /* Read cycle count and performance count */
307 edata->total_count = __raw_readl(info->ppmu.base + PPMU_V2_CCNT); 433 ret = regmap_read(info->regmap, PPMU_V2_CCNT, &total_count);
434 if (ret < 0)
435 return ret;
436 edata->total_count = total_count;
308 437
309 switch (id) { 438 switch (id) {
310 case PPMU_PMNCNT0: 439 case PPMU_PMNCNT0:
311 case PPMU_PMNCNT1: 440 case PPMU_PMNCNT1:
312 case PPMU_PMNCNT2: 441 case PPMU_PMNCNT2:
313 load_count = __raw_readl(info->ppmu.base + PPMU_V2_PMNCT(id)); 442 ret = regmap_read(info->regmap, PPMU_V2_PMNCT(id), &count);
443 if (ret < 0)
444 return ret;
445 load_count = count;
314 break; 446 break;
315 case PPMU_PMNCNT3: 447 case PPMU_PMNCNT3:
316 pmcnt_high = __raw_readl(info->ppmu.base + PPMU_V2_PMCNT3_HIGH); 448 ret = regmap_read(info->regmap, PPMU_V2_PMCNT3_HIGH,
317 pmcnt_low = __raw_readl(info->ppmu.base + PPMU_V2_PMCNT3_LOW); 449 &pmcnt_high);
318 load_count = ((u64)((pmcnt_high & 0xff)) << 32) 450 if (ret < 0)
319 + (u64)pmcnt_low; 451 return ret;
452
453 ret = regmap_read(info->regmap, PPMU_V2_PMCNT3_LOW, &pmcnt_low);
454 if (ret < 0)
455 return ret;
456
457 load_count = ((u64)((pmcnt_high & 0xff)) << 32)+ (u64)pmcnt_low;
320 break; 458 break;
321 } 459 }
322 edata->load_count = load_count; 460 edata->load_count = load_count;
323 461
324 /* Disable all counters */ 462 /* Disable all counters */
325 cntenc = __raw_readl(info->ppmu.base + PPMU_V2_CNTENC); 463 ret = regmap_read(info->regmap, PPMU_V2_CNTENC, &cntenc);
464 if (ret < 0)
465 return 0;
466
326 cntenc |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id)); 467 cntenc |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id));
327 __raw_writel(cntenc, info->ppmu.base + PPMU_V2_CNTENC); 468 ret = regmap_write(info->regmap, PPMU_V2_CNTENC, cntenc);
469 if (ret < 0)
470 return ret;
328 471
329 dev_dbg(&edev->dev, "%25s (load: %ld / %ld)\n", edev->desc->name, 472 dev_dbg(&edev->dev, "%25s (load: %ld / %ld)\n", edev->desc->name,
330 edata->load_count, edata->total_count); 473 edata->load_count, edata->total_count);
@@ -411,10 +554,19 @@ static int of_get_devfreq_events(struct device_node *np,
411 return 0; 554 return 0;
412} 555}
413 556
414static int exynos_ppmu_parse_dt(struct exynos_ppmu *info) 557static struct regmap_config exynos_ppmu_regmap_config = {
558 .reg_bits = 32,
559 .val_bits = 32,
560 .reg_stride = 4,
561};
562
563static int exynos_ppmu_parse_dt(struct platform_device *pdev,
564 struct exynos_ppmu *info)
415{ 565{
416 struct device *dev = info->dev; 566 struct device *dev = info->dev;
417 struct device_node *np = dev->of_node; 567 struct device_node *np = dev->of_node;
568 struct resource *res;
569 void __iomem *base;
418 int ret = 0; 570 int ret = 0;
419 571
420 if (!np) { 572 if (!np) {
@@ -423,10 +575,17 @@ static int exynos_ppmu_parse_dt(struct exynos_ppmu *info)
423 } 575 }
424 576
425 /* Maps the memory mapped IO to control PPMU register */ 577 /* Maps the memory mapped IO to control PPMU register */
426 info->ppmu.base = of_iomap(np, 0); 578 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
427 if (IS_ERR_OR_NULL(info->ppmu.base)) { 579 base = devm_ioremap_resource(dev, res);
428 dev_err(dev, "failed to map memory region\n"); 580 if (IS_ERR(base))
429 return -ENOMEM; 581 return PTR_ERR(base);
582
583 exynos_ppmu_regmap_config.max_register = resource_size(res) - 4;
584 info->regmap = devm_regmap_init_mmio(dev, base,
585 &exynos_ppmu_regmap_config);
586 if (IS_ERR(info->regmap)) {
587 dev_err(dev, "failed to initialize regmap\n");
588 return PTR_ERR(info->regmap);
430 } 589 }
431 590
432 info->ppmu.clk = devm_clk_get(dev, "ppmu"); 591 info->ppmu.clk = devm_clk_get(dev, "ppmu");
@@ -438,15 +597,10 @@ static int exynos_ppmu_parse_dt(struct exynos_ppmu *info)
438 ret = of_get_devfreq_events(np, info); 597 ret = of_get_devfreq_events(np, info);
439 if (ret < 0) { 598 if (ret < 0) {
440 dev_err(dev, "failed to parse exynos ppmu dt node\n"); 599 dev_err(dev, "failed to parse exynos ppmu dt node\n");
441 goto err; 600 return ret;
442 } 601 }
443 602
444 return 0; 603 return 0;
445
446err:
447 iounmap(info->ppmu.base);
448
449 return ret;
450} 604}
451 605
452static int exynos_ppmu_probe(struct platform_device *pdev) 606static int exynos_ppmu_probe(struct platform_device *pdev)
@@ -463,7 +617,7 @@ static int exynos_ppmu_probe(struct platform_device *pdev)
463 info->dev = &pdev->dev; 617 info->dev = &pdev->dev;
464 618
465 /* Parse dt data to get resource */ 619 /* Parse dt data to get resource */
466 ret = exynos_ppmu_parse_dt(info); 620 ret = exynos_ppmu_parse_dt(pdev, info);
467 if (ret < 0) { 621 if (ret < 0) {
468 dev_err(&pdev->dev, 622 dev_err(&pdev->dev,
469 "failed to parse devicetree for resource\n"); 623 "failed to parse devicetree for resource\n");
@@ -476,8 +630,7 @@ static int exynos_ppmu_probe(struct platform_device *pdev)
476 if (!info->edev) { 630 if (!info->edev) {
477 dev_err(&pdev->dev, 631 dev_err(&pdev->dev,
478 "failed to allocate memory devfreq-event devices\n"); 632 "failed to allocate memory devfreq-event devices\n");
479 ret = -ENOMEM; 633 return -ENOMEM;
480 goto err;
481 } 634 }
482 edev = info->edev; 635 edev = info->edev;
483 platform_set_drvdata(pdev, info); 636 platform_set_drvdata(pdev, info);
@@ -488,17 +641,16 @@ static int exynos_ppmu_probe(struct platform_device *pdev)
488 ret = PTR_ERR(edev[i]); 641 ret = PTR_ERR(edev[i]);
489 dev_err(&pdev->dev, 642 dev_err(&pdev->dev,
490 "failed to add devfreq-event device\n"); 643 "failed to add devfreq-event device\n");
491 goto err; 644 return PTR_ERR(edev[i]);
492 } 645 }
646
647 pr_info("exynos-ppmu: new PPMU device registered %s (%s)\n",
648 dev_name(&pdev->dev), desc[i].name);
493 } 649 }
494 650
495 clk_prepare_enable(info->ppmu.clk); 651 clk_prepare_enable(info->ppmu.clk);
496 652
497 return 0; 653 return 0;
498err:
499 iounmap(info->ppmu.base);
500
501 return ret;
502} 654}
503 655
504static int exynos_ppmu_remove(struct platform_device *pdev) 656static int exynos_ppmu_remove(struct platform_device *pdev)
@@ -506,7 +658,6 @@ static int exynos_ppmu_remove(struct platform_device *pdev)
506 struct exynos_ppmu *info = platform_get_drvdata(pdev); 658 struct exynos_ppmu *info = platform_get_drvdata(pdev);
507 659
508 clk_disable_unprepare(info->ppmu.clk); 660 clk_disable_unprepare(info->ppmu.clk);
509 iounmap(info->ppmu.base);
510 661
511 return 0; 662 return 0;
512} 663}
diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
index 9af86f46fbec..e0d1f4ac1740 100644
--- a/drivers/devfreq/exynos-bus.c
+++ b/drivers/devfreq/exynos-bus.c
@@ -147,8 +147,8 @@ static int exynos_bus_target(struct device *dev, unsigned long *freq, u32 flags)
147 } 147 }
148 bus->curr_freq = new_freq; 148 bus->curr_freq = new_freq;
149 149
150 dev_dbg(dev, "Set the frequency of bus (%lukHz -> %lukHz)\n", 150 dev_dbg(dev, "Set the frequency of bus (%luHz -> %luHz, %luHz)\n",
151 old_freq/1000, new_freq/1000); 151 old_freq, new_freq, clk_get_rate(bus->clk));
152out: 152out:
153 mutex_unlock(&bus->lock); 153 mutex_unlock(&bus->lock);
154 154
@@ -241,8 +241,8 @@ static int exynos_bus_passive_target(struct device *dev, unsigned long *freq,
241 *freq = new_freq; 241 *freq = new_freq;
242 bus->curr_freq = new_freq; 242 bus->curr_freq = new_freq;
243 243
244 dev_dbg(dev, "Set the frequency of bus (%lukHz -> %lukHz)\n", 244 dev_dbg(dev, "Set the frequency of bus (%luHz -> %luHz, %luHz)\n",
245 old_freq/1000, new_freq/1000); 245 old_freq, new_freq, clk_get_rate(bus->clk));
246out: 246out:
247 mutex_unlock(&bus->lock); 247 mutex_unlock(&bus->lock);
248 248
diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
index fad7d6321978..71576b8bdfef 100644
--- a/drivers/devfreq/governor.h
+++ b/drivers/devfreq/governor.h
@@ -38,4 +38,6 @@ extern void devfreq_interval_update(struct devfreq *devfreq,
38extern int devfreq_add_governor(struct devfreq_governor *governor); 38extern int devfreq_add_governor(struct devfreq_governor *governor);
39extern int devfreq_remove_governor(struct devfreq_governor *governor); 39extern int devfreq_remove_governor(struct devfreq_governor *governor);
40 40
41extern int devfreq_update_status(struct devfreq *devfreq, unsigned long freq);
42
41#endif /* _GOVERNOR_H */ 43#endif /* _GOVERNOR_H */
diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c
index 9ef46e2592c4..5be96b2249e7 100644
--- a/drivers/devfreq/governor_passive.c
+++ b/drivers/devfreq/governor_passive.c
@@ -112,6 +112,11 @@ static int update_devfreq_passive(struct devfreq *devfreq, unsigned long freq)
112 if (ret < 0) 112 if (ret < 0)
113 goto out; 113 goto out;
114 114
115 if (devfreq->profile->freq_table
116 && (devfreq_update_status(devfreq, freq)))
117 dev_err(&devfreq->dev,
118 "Couldn't update frequency transition information.\n");
119
115 devfreq->previous_freq = freq; 120 devfreq->previous_freq = freq;
116 121
117out: 122out:
@@ -179,6 +184,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq,
179 184
180static struct devfreq_governor devfreq_passive = { 185static struct devfreq_governor devfreq_passive = {
181 .name = "passive", 186 .name = "passive",
187 .immutable = 1,
182 .get_target_freq = devfreq_passive_get_target_freq, 188 .get_target_freq = devfreq_passive_get_target_freq,
183 .event_handler = devfreq_passive_event_handler, 189 .event_handler = devfreq_passive_event_handler,
184}; 190};
diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c
index 35de6e83c1fe..176976068bcd 100644
--- a/drivers/devfreq/governor_userspace.c
+++ b/drivers/devfreq/governor_userspace.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/devfreq/governor_simpleondemand.c 2 * linux/drivers/devfreq/governor_userspace.c
3 * 3 *
4 * Copyright (C) 2011 Samsung Electronics 4 * Copyright (C) 2011 Samsung Electronics
5 * MyungJoo Ham <myungjoo.ham@samsung.com> 5 * MyungJoo Ham <myungjoo.ham@samsung.com>
@@ -50,7 +50,6 @@ static ssize_t store_freq(struct device *dev, struct device_attribute *attr,
50 unsigned long wanted; 50 unsigned long wanted;
51 int err = 0; 51 int err = 0;
52 52
53
54 mutex_lock(&devfreq->lock); 53 mutex_lock(&devfreq->lock);
55 data = devfreq->data; 54 data = devfreq->data;
56 55
@@ -112,7 +111,13 @@ out:
112 111
113static void userspace_exit(struct devfreq *devfreq) 112static void userspace_exit(struct devfreq *devfreq)
114{ 113{
115 sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group); 114 /*
115 * Remove the sysfs entry, unless this is being called after
116 * device_del(), which should have done this already via kobject_del().
117 */
118 if (devfreq->dev.kobj.sd)
119 sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group);
120
116 kfree(devfreq->data); 121 kfree(devfreq->data);
117 devfreq->data = NULL; 122 devfreq->data = NULL;
118} 123}
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 2de4e2eea180..e0acb0e5243b 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -104,6 +104,8 @@ struct devfreq_dev_profile {
104 * struct devfreq_governor - Devfreq policy governor 104 * struct devfreq_governor - Devfreq policy governor
105 * @node: list node - contains registered devfreq governors 105 * @node: list node - contains registered devfreq governors
106 * @name: Governor's name 106 * @name: Governor's name
107 * @immutable: Immutable flag for governor. If the value is 1,
108 * this govenror is never changeable to other governor.
107 * @get_target_freq: Returns desired operating frequency for the device. 109 * @get_target_freq: Returns desired operating frequency for the device.
108 * Basically, get_target_freq will run 110 * Basically, get_target_freq will run
109 * devfreq_dev_profile.get_dev_status() to get the 111 * devfreq_dev_profile.get_dev_status() to get the
@@ -121,6 +123,7 @@ struct devfreq_governor {
121 struct list_head node; 123 struct list_head node;
122 124
123 const char name[DEVFREQ_NAME_LEN]; 125 const char name[DEVFREQ_NAME_LEN];
126 const unsigned int immutable;
124 int (*get_target_freq)(struct devfreq *this, unsigned long *freq); 127 int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
125 int (*event_handler)(struct devfreq *devfreq, 128 int (*event_handler)(struct devfreq *devfreq,
126 unsigned int event, void *data); 129 unsigned int event, void *data);