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