1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * exynos_ppmu.c - Exynos PPMU (Platform Performance Monitoring Unit) support 4 * 5 * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd. 6 * Author : Chanwoo Choi <cw00.choi@samsung.com> 7 * 8 * This driver is based on drivers/devfreq/exynos/exynos_ppmu.c 9 */ 10 11 #include <linux/clk.h> 12 #include <linux/io.h> 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/of_address.h> 16 #include <linux/of_device.h> 17 #include <linux/platform_device.h> 18 #include <linux/regmap.h> 19 #include <linux/suspend.h> 20 #include <linux/devfreq-event.h> 21 22 #include "exynos-ppmu.h" 23 24 enum exynos_ppmu_type { 25 EXYNOS_TYPE_PPMU, 26 EXYNOS_TYPE_PPMU_V2, 27 }; 28 29 struct exynos_ppmu_data { 30 struct clk *clk; 31 }; 32 33 struct exynos_ppmu { 34 struct devfreq_event_dev **edev; 35 struct devfreq_event_desc *desc; 36 unsigned int num_events; 37 38 struct device *dev; 39 struct regmap *regmap; 40 41 struct exynos_ppmu_data ppmu; 42 enum exynos_ppmu_type ppmu_type; 43 }; 44 45 #define PPMU_EVENT(name) \ 46 { "ppmu-event0-"#name, PPMU_PMNCNT0 }, \ 47 { "ppmu-event1-"#name, PPMU_PMNCNT1 }, \ 48 { "ppmu-event2-"#name, PPMU_PMNCNT2 }, \ 49 { "ppmu-event3-"#name, PPMU_PMNCNT3 } 50 51 static struct __exynos_ppmu_events { 52 char *name; 53 int id; 54 } ppmu_events[] = { 55 /* For Exynos3250, Exynos4 and Exynos5260 */ 56 PPMU_EVENT(g3d), 57 PPMU_EVENT(fsys), 58 59 /* For Exynos4 SoCs and Exynos3250 */ 60 PPMU_EVENT(dmc0), 61 PPMU_EVENT(dmc1), 62 PPMU_EVENT(cpu), 63 PPMU_EVENT(rightbus), 64 PPMU_EVENT(leftbus), 65 PPMU_EVENT(lcd0), 66 PPMU_EVENT(camif), 67 68 /* Only for Exynos3250 and Exynos5260 */ 69 PPMU_EVENT(mfc), 70 71 /* Only for Exynos4 SoCs */ 72 PPMU_EVENT(mfc-left), 73 PPMU_EVENT(mfc-right), 74 75 /* Only for Exynos5260 SoCs */ 76 PPMU_EVENT(drex0-s0), 77 PPMU_EVENT(drex0-s1), 78 PPMU_EVENT(drex1-s0), 79 PPMU_EVENT(drex1-s1), 80 PPMU_EVENT(eagle), 81 PPMU_EVENT(kfc), 82 PPMU_EVENT(isp), 83 PPMU_EVENT(fimc), 84 PPMU_EVENT(gscl), 85 PPMU_EVENT(mscl), 86 PPMU_EVENT(fimd0x), 87 PPMU_EVENT(fimd1x), 88 89 /* Only for Exynos5433 SoCs */ 90 PPMU_EVENT(d0-cpu), 91 PPMU_EVENT(d0-general), 92 PPMU_EVENT(d0-rt), 93 PPMU_EVENT(d1-cpu), 94 PPMU_EVENT(d1-general), 95 PPMU_EVENT(d1-rt), 96 97 /* For Exynos5422 SoC, deprecated (backwards compatible) */ 98 PPMU_EVENT(dmc0_0), 99 PPMU_EVENT(dmc0_1), 100 PPMU_EVENT(dmc1_0), 101 PPMU_EVENT(dmc1_1), 102 /* For Exynos5422 SoC */ 103 PPMU_EVENT(dmc0-0), 104 PPMU_EVENT(dmc0-1), 105 PPMU_EVENT(dmc1-0), 106 PPMU_EVENT(dmc1-1), 107 }; 108 109 static int __exynos_ppmu_find_ppmu_id(const char *edev_name) 110 { 111 int i; 112 113 for (i = 0; i < ARRAY_SIZE(ppmu_events); i++) 114 if (!strcmp(edev_name, ppmu_events[i].name)) 115 return ppmu_events[i].id; 116 117 return -EINVAL; 118 } 119 120 static int exynos_ppmu_find_ppmu_id(struct devfreq_event_dev *edev) 121 { 122 return __exynos_ppmu_find_ppmu_id(edev->desc->name); 123 } 124 125 /* 126 * The devfreq-event ops structure for PPMU v1.1 127 */ 128 static int exynos_ppmu_disable(struct devfreq_event_dev *edev) 129 { 130 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); 131 int ret; 132 u32 pmnc; 133 134 /* Disable all counters */ 135 ret = regmap_write(info->regmap, PPMU_CNTENC, 136 PPMU_CCNT_MASK | 137 PPMU_PMCNT0_MASK | 138 PPMU_PMCNT1_MASK | 139 PPMU_PMCNT2_MASK | 140 PPMU_PMCNT3_MASK); 141 if (ret < 0) 142 return ret; 143 144 /* Disable PPMU */ 145 ret = regmap_read(info->regmap, PPMU_PMNC, &pmnc); 146 if (ret < 0) 147 return ret; 148 149 pmnc &= ~PPMU_PMNC_ENABLE_MASK; 150 ret = regmap_write(info->regmap, PPMU_PMNC, pmnc); 151 if (ret < 0) 152 return ret; 153 154 return 0; 155 } 156 157 static int exynos_ppmu_set_event(struct devfreq_event_dev *edev) 158 { 159 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); 160 int id = exynos_ppmu_find_ppmu_id(edev); 161 int ret; 162 u32 pmnc, cntens; 163 164 if (id < 0) 165 return id; 166 167 /* Enable specific counter */ 168 ret = regmap_read(info->regmap, PPMU_CNTENS, &cntens); 169 if (ret < 0) 170 return ret; 171 172 cntens |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id)); 173 ret = regmap_write(info->regmap, PPMU_CNTENS, cntens); 174 if (ret < 0) 175 return ret; 176 177 /* Set the event of proper data type monitoring */ 178 ret = regmap_write(info->regmap, PPMU_BEVTxSEL(id), 179 edev->desc->event_type); 180 if (ret < 0) 181 return ret; 182 183 /* Reset cycle counter/performance counter and enable PPMU */ 184 ret = regmap_read(info->regmap, PPMU_PMNC, &pmnc); 185 if (ret < 0) 186 return ret; 187 188 pmnc &= ~(PPMU_PMNC_ENABLE_MASK 189 | PPMU_PMNC_COUNTER_RESET_MASK 190 | PPMU_PMNC_CC_RESET_MASK); 191 pmnc |= (PPMU_ENABLE << PPMU_PMNC_ENABLE_SHIFT); 192 pmnc |= (PPMU_ENABLE << PPMU_PMNC_COUNTER_RESET_SHIFT); 193 pmnc |= (PPMU_ENABLE << PPMU_PMNC_CC_RESET_SHIFT); 194 ret = regmap_write(info->regmap, PPMU_PMNC, pmnc); 195 if (ret < 0) 196 return ret; 197 198 return 0; 199 } 200 201 static int exynos_ppmu_get_event(struct devfreq_event_dev *edev, 202 struct devfreq_event_data *edata) 203 { 204 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); 205 int id = exynos_ppmu_find_ppmu_id(edev); 206 unsigned int total_count, load_count; 207 unsigned int pmcnt3_high, pmcnt3_low; 208 unsigned int pmnc, cntenc; 209 int ret; 210 211 if (id < 0) 212 return -EINVAL; 213 214 /* Disable PPMU */ 215 ret = regmap_read(info->regmap, PPMU_PMNC, &pmnc); 216 if (ret < 0) 217 return ret; 218 219 pmnc &= ~PPMU_PMNC_ENABLE_MASK; 220 ret = regmap_write(info->regmap, PPMU_PMNC, pmnc); 221 if (ret < 0) 222 return ret; 223 224 /* Read cycle count */ 225 ret = regmap_read(info->regmap, PPMU_CCNT, &total_count); 226 if (ret < 0) 227 return ret; 228 edata->total_count = total_count; 229 230 /* Read performance count */ 231 switch (id) { 232 case PPMU_PMNCNT0: 233 case PPMU_PMNCNT1: 234 case PPMU_PMNCNT2: 235 ret = regmap_read(info->regmap, PPMU_PMNCT(id), &load_count); 236 if (ret < 0) 237 return ret; 238 edata->load_count = load_count; 239 break; 240 case PPMU_PMNCNT3: 241 ret = regmap_read(info->regmap, PPMU_PMCNT3_HIGH, &pmcnt3_high); 242 if (ret < 0) 243 return ret; 244 245 ret = regmap_read(info->regmap, PPMU_PMCNT3_LOW, &pmcnt3_low); 246 if (ret < 0) 247 return ret; 248 249 edata->load_count = ((pmcnt3_high << 8) | pmcnt3_low); 250 break; 251 default: 252 return -EINVAL; 253 } 254 255 /* Disable specific counter */ 256 ret = regmap_read(info->regmap, PPMU_CNTENC, &cntenc); 257 if (ret < 0) 258 return ret; 259 260 cntenc |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id)); 261 ret = regmap_write(info->regmap, PPMU_CNTENC, cntenc); 262 if (ret < 0) 263 return ret; 264 265 dev_dbg(&edev->dev, "%s (event: %ld/%ld)\n", edev->desc->name, 266 edata->load_count, edata->total_count); 267 268 return 0; 269 } 270 271 static const struct devfreq_event_ops exynos_ppmu_ops = { 272 .disable = exynos_ppmu_disable, 273 .set_event = exynos_ppmu_set_event, 274 .get_event = exynos_ppmu_get_event, 275 }; 276 277 /* 278 * The devfreq-event ops structure for PPMU v2.0 279 */ 280 static int exynos_ppmu_v2_disable(struct devfreq_event_dev *edev) 281 { 282 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); 283 int ret; 284 u32 pmnc, clear; 285 286 /* Disable all counters */ 287 clear = (PPMU_CCNT_MASK | PPMU_PMCNT0_MASK | PPMU_PMCNT1_MASK 288 | PPMU_PMCNT2_MASK | PPMU_PMCNT3_MASK); 289 ret = regmap_write(info->regmap, PPMU_V2_FLAG, clear); 290 if (ret < 0) 291 return ret; 292 293 ret = regmap_write(info->regmap, PPMU_V2_INTENC, clear); 294 if (ret < 0) 295 return ret; 296 297 ret = regmap_write(info->regmap, PPMU_V2_CNTENC, clear); 298 if (ret < 0) 299 return ret; 300 301 ret = regmap_write(info->regmap, PPMU_V2_CNT_RESET, clear); 302 if (ret < 0) 303 return ret; 304 305 ret = regmap_write(info->regmap, PPMU_V2_CIG_CFG0, 0x0); 306 if (ret < 0) 307 return ret; 308 309 ret = regmap_write(info->regmap, PPMU_V2_CIG_CFG1, 0x0); 310 if (ret < 0) 311 return ret; 312 313 ret = regmap_write(info->regmap, PPMU_V2_CIG_CFG2, 0x0); 314 if (ret < 0) 315 return ret; 316 317 ret = regmap_write(info->regmap, PPMU_V2_CIG_RESULT, 0x0); 318 if (ret < 0) 319 return ret; 320 321 ret = regmap_write(info->regmap, PPMU_V2_CNT_AUTO, 0x0); 322 if (ret < 0) 323 return ret; 324 325 ret = regmap_write(info->regmap, PPMU_V2_CH_EV0_TYPE, 0x0); 326 if (ret < 0) 327 return ret; 328 329 ret = regmap_write(info->regmap, PPMU_V2_CH_EV1_TYPE, 0x0); 330 if (ret < 0) 331 return ret; 332 333 ret = regmap_write(info->regmap, PPMU_V2_CH_EV2_TYPE, 0x0); 334 if (ret < 0) 335 return ret; 336 337 ret = regmap_write(info->regmap, PPMU_V2_CH_EV3_TYPE, 0x0); 338 if (ret < 0) 339 return ret; 340 341 ret = regmap_write(info->regmap, PPMU_V2_SM_ID_V, 0x0); 342 if (ret < 0) 343 return ret; 344 345 ret = regmap_write(info->regmap, PPMU_V2_SM_ID_A, 0x0); 346 if (ret < 0) 347 return ret; 348 349 ret = regmap_write(info->regmap, PPMU_V2_SM_OTHERS_V, 0x0); 350 if (ret < 0) 351 return ret; 352 353 ret = regmap_write(info->regmap, PPMU_V2_SM_OTHERS_A, 0x0); 354 if (ret < 0) 355 return ret; 356 357 ret = regmap_write(info->regmap, PPMU_V2_INTERRUPT_RESET, 0x0); 358 if (ret < 0) 359 return ret; 360 361 /* Disable PPMU */ 362 ret = regmap_read(info->regmap, PPMU_V2_PMNC, &pmnc); 363 if (ret < 0) 364 return ret; 365 366 pmnc &= ~PPMU_PMNC_ENABLE_MASK; 367 ret = regmap_write(info->regmap, PPMU_V2_PMNC, pmnc); 368 if (ret < 0) 369 return ret; 370 371 return 0; 372 } 373 374 static int exynos_ppmu_v2_set_event(struct devfreq_event_dev *edev) 375 { 376 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); 377 unsigned int pmnc, cntens; 378 int id = exynos_ppmu_find_ppmu_id(edev); 379 int ret; 380 381 /* Enable all counters */ 382 ret = regmap_read(info->regmap, PPMU_V2_CNTENS, &cntens); 383 if (ret < 0) 384 return ret; 385 386 cntens |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id)); 387 ret = regmap_write(info->regmap, PPMU_V2_CNTENS, cntens); 388 if (ret < 0) 389 return ret; 390 391 /* Set the event of proper data type monitoring */ 392 ret = regmap_write(info->regmap, PPMU_V2_CH_EVx_TYPE(id), 393 edev->desc->event_type); 394 if (ret < 0) 395 return ret; 396 397 /* Reset cycle counter/performance counter and enable PPMU */ 398 ret = regmap_read(info->regmap, PPMU_V2_PMNC, &pmnc); 399 if (ret < 0) 400 return ret; 401 402 pmnc &= ~(PPMU_PMNC_ENABLE_MASK 403 | PPMU_PMNC_COUNTER_RESET_MASK 404 | PPMU_PMNC_CC_RESET_MASK 405 | PPMU_PMNC_CC_DIVIDER_MASK 406 | PPMU_V2_PMNC_START_MODE_MASK); 407 pmnc |= (PPMU_ENABLE << PPMU_PMNC_ENABLE_SHIFT); 408 pmnc |= (PPMU_ENABLE << PPMU_PMNC_COUNTER_RESET_SHIFT); 409 pmnc |= (PPMU_ENABLE << PPMU_PMNC_CC_RESET_SHIFT); 410 pmnc |= (PPMU_V2_MODE_MANUAL << PPMU_V2_PMNC_START_MODE_SHIFT); 411 412 ret = regmap_write(info->regmap, PPMU_V2_PMNC, pmnc); 413 if (ret < 0) 414 return ret; 415 416 return 0; 417 } 418 419 static int exynos_ppmu_v2_get_event(struct devfreq_event_dev *edev, 420 struct devfreq_event_data *edata) 421 { 422 struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); 423 int id = exynos_ppmu_find_ppmu_id(edev); 424 int ret; 425 unsigned int pmnc, cntenc; 426 unsigned int pmcnt_high, pmcnt_low; 427 unsigned int total_count, count; 428 unsigned long load_count = 0; 429 430 /* Disable PPMU */ 431 ret = regmap_read(info->regmap, PPMU_V2_PMNC, &pmnc); 432 if (ret < 0) 433 return ret; 434 435 pmnc &= ~PPMU_PMNC_ENABLE_MASK; 436 ret = regmap_write(info->regmap, PPMU_V2_PMNC, pmnc); 437 if (ret < 0) 438 return ret; 439 440 /* Read cycle count and performance count */ 441 ret = regmap_read(info->regmap, PPMU_V2_CCNT, &total_count); 442 if (ret < 0) 443 return ret; 444 edata->total_count = total_count; 445 446 switch (id) { 447 case PPMU_PMNCNT0: 448 case PPMU_PMNCNT1: 449 case PPMU_PMNCNT2: 450 ret = regmap_read(info->regmap, PPMU_V2_PMNCT(id), &count); 451 if (ret < 0) 452 return ret; 453 load_count = count; 454 break; 455 case PPMU_PMNCNT3: 456 ret = regmap_read(info->regmap, PPMU_V2_PMCNT3_HIGH, 457 &pmcnt_high); 458 if (ret < 0) 459 return ret; 460 461 ret = regmap_read(info->regmap, PPMU_V2_PMCNT3_LOW, &pmcnt_low); 462 if (ret < 0) 463 return ret; 464 465 load_count = ((u64)((pmcnt_high & 0xff)) << 32)+ (u64)pmcnt_low; 466 break; 467 } 468 edata->load_count = load_count; 469 470 /* Disable all counters */ 471 ret = regmap_read(info->regmap, PPMU_V2_CNTENC, &cntenc); 472 if (ret < 0) 473 return 0; 474 475 cntenc |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id)); 476 ret = regmap_write(info->regmap, PPMU_V2_CNTENC, cntenc); 477 if (ret < 0) 478 return ret; 479 480 dev_dbg(&edev->dev, "%25s (load: %ld / %ld)\n", edev->desc->name, 481 edata->load_count, edata->total_count); 482 return 0; 483 } 484 485 static const struct devfreq_event_ops exynos_ppmu_v2_ops = { 486 .disable = exynos_ppmu_v2_disable, 487 .set_event = exynos_ppmu_v2_set_event, 488 .get_event = exynos_ppmu_v2_get_event, 489 }; 490 491 static const struct of_device_id exynos_ppmu_id_match[] = { 492 { 493 .compatible = "samsung,exynos-ppmu", 494 .data = (void *)EXYNOS_TYPE_PPMU, 495 }, { 496 .compatible = "samsung,exynos-ppmu-v2", 497 .data = (void *)EXYNOS_TYPE_PPMU_V2, 498 }, 499 { /* sentinel */ }, 500 }; 501 MODULE_DEVICE_TABLE(of, exynos_ppmu_id_match); 502 503 static int of_get_devfreq_events(struct device_node *np, 504 struct exynos_ppmu *info) 505 { 506 struct devfreq_event_desc *desc; 507 struct device *dev = info->dev; 508 struct device_node *events_np, *node; 509 int i, j, count; 510 const struct of_device_id *of_id; 511 int ret; 512 513 events_np = of_get_child_by_name(np, "events"); 514 if (!events_np) { 515 dev_err(dev, 516 "failed to get child node of devfreq-event devices\n"); 517 return -EINVAL; 518 } 519 520 count = of_get_child_count(events_np); 521 desc = devm_kcalloc(dev, count, sizeof(*desc), GFP_KERNEL); 522 if (!desc) { 523 of_node_put(events_np); 524 return -ENOMEM; 525 } 526 info->num_events = count; 527 528 of_id = of_match_device(exynos_ppmu_id_match, dev); 529 if (of_id) 530 info->ppmu_type = (enum exynos_ppmu_type)of_id->data; 531 else { 532 of_node_put(events_np); 533 return -EINVAL; 534 } 535 536 j = 0; 537 for_each_child_of_node(events_np, node) { 538 for (i = 0; i < ARRAY_SIZE(ppmu_events); i++) { 539 if (!ppmu_events[i].name) 540 continue; 541 542 if (of_node_name_eq(node, ppmu_events[i].name)) 543 break; 544 } 545 546 if (i == ARRAY_SIZE(ppmu_events)) { 547 dev_warn(dev, 548 "don't know how to configure events : %pOFn\n", 549 node); 550 continue; 551 } 552 553 switch (info->ppmu_type) { 554 case EXYNOS_TYPE_PPMU: 555 desc[j].ops = &exynos_ppmu_ops; 556 break; 557 case EXYNOS_TYPE_PPMU_V2: 558 desc[j].ops = &exynos_ppmu_v2_ops; 559 break; 560 } 561 562 desc[j].driver_data = info; 563 564 of_property_read_string(node, "event-name", &desc[j].name); 565 ret = of_property_read_u32(node, "event-data-type", 566 &desc[j].event_type); 567 if (ret) { 568 /* Set the event of proper data type counting. 569 * Check if the data type has been defined in DT, 570 * use default if not. 571 */ 572 if (info->ppmu_type == EXYNOS_TYPE_PPMU_V2) { 573 /* Not all registers take the same value for 574 * read+write data count. 575 */ 576 switch (ppmu_events[i].id) { 577 case PPMU_PMNCNT0: 578 case PPMU_PMNCNT1: 579 case PPMU_PMNCNT2: 580 desc[j].event_type = PPMU_V2_RO_DATA_CNT 581 | PPMU_V2_WO_DATA_CNT; 582 break; 583 case PPMU_PMNCNT3: 584 desc[j].event_type = 585 PPMU_V2_EVT3_RW_DATA_CNT; 586 break; 587 } 588 } else { 589 desc[j].event_type = PPMU_RO_DATA_CNT | 590 PPMU_WO_DATA_CNT; 591 } 592 } 593 594 j++; 595 } 596 info->desc = desc; 597 598 of_node_put(events_np); 599 600 return 0; 601 } 602 603 static struct regmap_config exynos_ppmu_regmap_config = { 604 .reg_bits = 32, 605 .val_bits = 32, 606 .reg_stride = 4, 607 }; 608 609 static int exynos_ppmu_parse_dt(struct platform_device *pdev, 610 struct exynos_ppmu *info) 611 { 612 struct device *dev = info->dev; 613 struct device_node *np = dev->of_node; 614 struct resource *res; 615 void __iomem *base; 616 int ret = 0; 617 618 if (!np) { 619 dev_err(dev, "failed to find devicetree node\n"); 620 return -EINVAL; 621 } 622 623 /* Maps the memory mapped IO to control PPMU register */ 624 base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 625 if (IS_ERR(base)) 626 return PTR_ERR(base); 627 628 exynos_ppmu_regmap_config.max_register = resource_size(res) - 4; 629 info->regmap = devm_regmap_init_mmio(dev, base, 630 &exynos_ppmu_regmap_config); 631 if (IS_ERR(info->regmap)) { 632 dev_err(dev, "failed to initialize regmap\n"); 633 return PTR_ERR(info->regmap); 634 } 635 636 info->ppmu.clk = devm_clk_get(dev, "ppmu"); 637 if (IS_ERR(info->ppmu.clk)) { 638 info->ppmu.clk = NULL; 639 dev_warn(dev, "cannot get PPMU clock\n"); 640 } 641 642 ret = of_get_devfreq_events(np, info); 643 if (ret < 0) { 644 dev_err(dev, "failed to parse exynos ppmu dt node\n"); 645 return ret; 646 } 647 648 return 0; 649 } 650 651 static int exynos_ppmu_probe(struct platform_device *pdev) 652 { 653 struct exynos_ppmu *info; 654 struct devfreq_event_dev **edev; 655 struct devfreq_event_desc *desc; 656 int i, ret = 0, size; 657 658 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 659 if (!info) 660 return -ENOMEM; 661 662 info->dev = &pdev->dev; 663 664 /* Parse dt data to get resource */ 665 ret = exynos_ppmu_parse_dt(pdev, info); 666 if (ret < 0) { 667 dev_err(&pdev->dev, 668 "failed to parse devicetree for resource\n"); 669 return ret; 670 } 671 desc = info->desc; 672 673 size = sizeof(struct devfreq_event_dev *) * info->num_events; 674 info->edev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); 675 if (!info->edev) 676 return -ENOMEM; 677 678 edev = info->edev; 679 platform_set_drvdata(pdev, info); 680 681 for (i = 0; i < info->num_events; i++) { 682 edev[i] = devm_devfreq_event_add_edev(&pdev->dev, &desc[i]); 683 if (IS_ERR(edev[i])) { 684 dev_err(&pdev->dev, 685 "failed to add devfreq-event device\n"); 686 return PTR_ERR(edev[i]); 687 } 688 689 pr_info("exynos-ppmu: new PPMU device registered %s (%s)\n", 690 dev_name(&pdev->dev), desc[i].name); 691 } 692 693 ret = clk_prepare_enable(info->ppmu.clk); 694 if (ret) { 695 dev_err(&pdev->dev, "failed to prepare ppmu clock\n"); 696 return ret; 697 } 698 699 return 0; 700 } 701 702 static int exynos_ppmu_remove(struct platform_device *pdev) 703 { 704 struct exynos_ppmu *info = platform_get_drvdata(pdev); 705 706 clk_disable_unprepare(info->ppmu.clk); 707 708 return 0; 709 } 710 711 static struct platform_driver exynos_ppmu_driver = { 712 .probe = exynos_ppmu_probe, 713 .remove = exynos_ppmu_remove, 714 .driver = { 715 .name = "exynos-ppmu", 716 .of_match_table = exynos_ppmu_id_match, 717 }, 718 }; 719 module_platform_driver(exynos_ppmu_driver); 720 721 MODULE_DESCRIPTION("Exynos PPMU(Platform Performance Monitoring Unit) driver"); 722 MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); 723 MODULE_LICENSE("GPL"); 724