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