cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

exynos-ppmu.c (17060B)


      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
     24enum exynos_ppmu_type {
     25	EXYNOS_TYPE_PPMU,
     26	EXYNOS_TYPE_PPMU_V2,
     27};
     28
     29struct exynos_ppmu_data {
     30	struct clk *clk;
     31};
     32
     33struct 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
     51static 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
    109static 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
    120static 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 */
    128static 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
    157static 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
    201static 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
    271static 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 */
    280static 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
    374static 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
    419static 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
    485static 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
    491static 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};
    501MODULE_DEVICE_TABLE(of, exynos_ppmu_id_match);
    502
    503static 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
    603static struct regmap_config exynos_ppmu_regmap_config = {
    604	.reg_bits = 32,
    605	.val_bits = 32,
    606	.reg_stride = 4,
    607};
    608
    609static 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	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    625	base = devm_ioremap_resource(dev, res);
    626	if (IS_ERR(base))
    627		return PTR_ERR(base);
    628
    629	exynos_ppmu_regmap_config.max_register = resource_size(res) - 4;
    630	info->regmap = devm_regmap_init_mmio(dev, base,
    631					&exynos_ppmu_regmap_config);
    632	if (IS_ERR(info->regmap)) {
    633		dev_err(dev, "failed to initialize regmap\n");
    634		return PTR_ERR(info->regmap);
    635	}
    636
    637	info->ppmu.clk = devm_clk_get(dev, "ppmu");
    638	if (IS_ERR(info->ppmu.clk)) {
    639		info->ppmu.clk = NULL;
    640		dev_warn(dev, "cannot get PPMU clock\n");
    641	}
    642
    643	ret = of_get_devfreq_events(np, info);
    644	if (ret < 0) {
    645		dev_err(dev, "failed to parse exynos ppmu dt node\n");
    646		return ret;
    647	}
    648
    649	return 0;
    650}
    651
    652static int exynos_ppmu_probe(struct platform_device *pdev)
    653{
    654	struct exynos_ppmu *info;
    655	struct devfreq_event_dev **edev;
    656	struct devfreq_event_desc *desc;
    657	int i, ret = 0, size;
    658
    659	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
    660	if (!info)
    661		return -ENOMEM;
    662
    663	info->dev = &pdev->dev;
    664
    665	/* Parse dt data to get resource */
    666	ret = exynos_ppmu_parse_dt(pdev, info);
    667	if (ret < 0) {
    668		dev_err(&pdev->dev,
    669			"failed to parse devicetree for resource\n");
    670		return ret;
    671	}
    672	desc = info->desc;
    673
    674	size = sizeof(struct devfreq_event_dev *) * info->num_events;
    675	info->edev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
    676	if (!info->edev)
    677		return -ENOMEM;
    678
    679	edev = info->edev;
    680	platform_set_drvdata(pdev, info);
    681
    682	for (i = 0; i < info->num_events; i++) {
    683		edev[i] = devm_devfreq_event_add_edev(&pdev->dev, &desc[i]);
    684		if (IS_ERR(edev[i])) {
    685			dev_err(&pdev->dev,
    686				"failed to add devfreq-event device\n");
    687			return PTR_ERR(edev[i]);
    688		}
    689
    690		pr_info("exynos-ppmu: new PPMU device registered %s (%s)\n",
    691			dev_name(&pdev->dev), desc[i].name);
    692	}
    693
    694	ret = clk_prepare_enable(info->ppmu.clk);
    695	if (ret) {
    696		dev_err(&pdev->dev, "failed to prepare ppmu clock\n");
    697		return ret;
    698	}
    699
    700	return 0;
    701}
    702
    703static int exynos_ppmu_remove(struct platform_device *pdev)
    704{
    705	struct exynos_ppmu *info = platform_get_drvdata(pdev);
    706
    707	clk_disable_unprepare(info->ppmu.clk);
    708
    709	return 0;
    710}
    711
    712static struct platform_driver exynos_ppmu_driver = {
    713	.probe	= exynos_ppmu_probe,
    714	.remove	= exynos_ppmu_remove,
    715	.driver = {
    716		.name	= "exynos-ppmu",
    717		.of_match_table = exynos_ppmu_id_match,
    718	},
    719};
    720module_platform_driver(exynos_ppmu_driver);
    721
    722MODULE_DESCRIPTION("Exynos PPMU(Platform Performance Monitoring Unit) driver");
    723MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
    724MODULE_LICENSE("GPL");