#define PMUNAME "arm_dsu"
#define DRVNAME PMUNAME "_pmu"
#define pr_fmt(fmt) DRVNAME ": " fmt
#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <linux/cpumask.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/perf_event.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <asm/arm_dsu_pmu.h>
#define DSU_PMU_EVT_CYCLES 0x11
#define DSU_PMU_EVT_CHAIN 0x1e
#define DSU_PMU_MAX_COMMON_EVENTS 0x40
#define DSU_PMU_MAX_HW_CNTRS 32
#define DSU_PMU_HW_COUNTER_MASK (DSU_PMU_MAX_HW_CNTRS - 1)
#define CLUSTERPMCR_E BIT(0)
#define CLUSTERPMCR_P BIT(1)
#define CLUSTERPMCR_C BIT(2)
#define CLUSTERPMCR_N_SHIFT 11
#define CLUSTERPMCR_N_MASK 0x1f
#define CLUSTERPMCR_IDCODE_SHIFT 16
#define CLUSTERPMCR_IDCODE_MASK 0xff
#define CLUSTERPMCR_IMP_SHIFT 24
#define CLUSTERPMCR_IMP_MASK 0xff
#define CLUSTERPMCR_RES_MASK 0x7e8
#define CLUSTERPMCR_RES_VAL 0x40
#define DSU_ACTIVE_CPU_MASK 0x0
#define DSU_ASSOCIATED_CPU_MASK 0x1
#define DSU_PMU_IDX_CYCLE_COUNTER 31
#define DSU_PMU_COUNTER_WIDTH(idx) \
(((idx) == DSU_PMU_IDX_CYCLE_COUNTER) ? 64 : 32)
#define DSU_PMU_COUNTER_MASK(idx) \
GENMASK_ULL((DSU_PMU_COUNTER_WIDTH((idx)) - 1), 0)
#define DSU_EXT_ATTR(_name, _func, _config) \
(&((struct dev_ext_attribute[]) { \
.attr = __ATTR(_name, 0444, _func, NULL), \
#define DSU_EVENT_ATTR(_name, _config) \
DSU_EXT_ATTR(_name, dsu_pmu_sysfs_event_show, (unsigned long)_config)
#define DSU_FORMAT_ATTR(_name, _config) \
DSU_EXT_ATTR(_name, dsu_pmu_sysfs_format_show, (char *)_config)
#define DSU_CPUMASK_ATTR(_name, _config) \