aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChanwoo Choi <cw00.choi@samsung.com>2016-11-19 11:48:14 -0500
committerMyungJoo Ham <myungjoo.ham@samsung.com>2017-01-31 00:12:19 -0500
commit2a3ea6478912a6d6739042bac25a7aa7d0342093 (patch)
tree92f653b46248b493d044481b90af5f3e02921fb3 /drivers
parentb513652443fc515ec90202d005230f2afee457ad (diff)
PM / devfreq: exynos-ppmu: Use the regmap interface to handle the registers
This patch uses the regmap interface to read and write the registers for exynos PPMU device instead of the legacy memory map functions. Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/devfreq/event/exynos-ppmu.c326
1 files changed, 237 insertions, 89 deletions
diff --git a/drivers/devfreq/event/exynos-ppmu.c b/drivers/devfreq/event/exynos-ppmu.c
index 107eb91a9415..fb3706faf5bd 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;
222 276
223 __raw_writel(clear, info->ppmu.base + PPMU_V2_FLAG); 277 ret = regmap_write(info->regmap, PPMU_V2_CNTENC, clear);
224 __raw_writel(clear, info->ppmu.base + PPMU_V2_INTENC); 278 if (ret < 0)
225 __raw_writel(clear, info->ppmu.base + PPMU_V2_CNTENC); 279 return ret;
226 __raw_writel(clear, info->ppmu.base + PPMU_V2_CNT_RESET); 280
227 281 ret = regmap_write(info->regmap, PPMU_V2_CNT_RESET, clear);
228 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CIG_CFG0); 282 if (ret < 0)
229 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CIG_CFG1); 283 return ret;
230 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CIG_CFG2); 284
231 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CIG_RESULT); 285 ret = regmap_write(info->regmap, PPMU_V2_CIG_CFG0, 0x0);
232 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CNT_AUTO); 286 if (ret < 0)
233 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CH_EV0_TYPE); 287 return ret;
234 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CH_EV1_TYPE); 288
235 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CH_EV2_TYPE); 289 ret = regmap_write(info->regmap, PPMU_V2_CIG_CFG1, 0x0);
236 __raw_writel(0x0, info->ppmu.base + PPMU_V2_CH_EV3_TYPE); 290 if (ret < 0)
237 __raw_writel(0x0, info->ppmu.base + PPMU_V2_SM_ID_V); 291 return ret;
238 __raw_writel(0x0, info->ppmu.base + PPMU_V2_SM_ID_A); 292
239 __raw_writel(0x0, info->ppmu.base + PPMU_V2_SM_OTHERS_V); 293 ret = regmap_write(info->regmap, PPMU_V2_CIG_CFG2, 0x0);
240 __raw_writel(0x0, info->ppmu.base + PPMU_V2_SM_OTHERS_A); 294 if (ret < 0)
241 __raw_writel(0x0, info->ppmu.base + PPMU_V2_INTERRUPT_RESET); 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;
312
313 ret = regmap_write(info->regmap, PPMU_V2_CH_EV2_TYPE, 0x0);
314 if (ret < 0)
315 return ret;
316
317 ret = regmap_write(info->regmap, PPMU_V2_CH_EV3_TYPE, 0x0);
318 if (ret < 0)
319 return ret;
320
321 ret = regmap_write(info->regmap, PPMU_V2_SM_ID_V, 0x0);
322 if (ret < 0)
323 return ret;
324
325 ret = regmap_write(info->regmap, PPMU_V2_SM_ID_A, 0x0);
326 if (ret < 0)
327 return ret;
328
329 ret = regmap_write(info->regmap, PPMU_V2_SM_OTHERS_V, 0x0);
330 if (ret < 0)
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,13 @@ 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 }
493 } 646 }
494 647
495 clk_prepare_enable(info->ppmu.clk); 648 clk_prepare_enable(info->ppmu.clk);
496 649
497 return 0; 650 return 0;
498err:
499 iounmap(info->ppmu.base);
500
501 return ret;
502} 651}
503 652
504static int exynos_ppmu_remove(struct platform_device *pdev) 653static int exynos_ppmu_remove(struct platform_device *pdev)
@@ -506,7 +655,6 @@ static int exynos_ppmu_remove(struct platform_device *pdev)
506 struct exynos_ppmu *info = platform_get_drvdata(pdev); 655 struct exynos_ppmu *info = platform_get_drvdata(pdev);
507 656
508 clk_disable_unprepare(info->ppmu.clk); 657 clk_disable_unprepare(info->ppmu.clk);
509 iounmap(info->ppmu.base);
510 658
511 return 0; 659 return 0;
512} 660}