// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2022-2024 Arm Limited
// NI-700 Network-on-Chip PMU driver

#include <linux/acpi.h>
#include <linux/bitfield.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/perf_event.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

/* Common registers */
#define NI_NODE_TYPE		0x000
#define NI_NODE_TYPE_NODE_ID	GENMASK(31, 16)
#define NI_NODE_TYPE_NODE_TYPE	GENMASK(15, 0)

#define NI_CHILD_NODE_INFO	0x004
#define NI_CHILD_PTR(n)		(0x008 + (n) * 4)

#define NI700_PMUSELA		0x00c

/* Config node */
#define NI_PERIPHERAL_ID0	0xfe0
#define NI_PIDR0_PART_7_0	GENMASK(7, 0)
#define NI_PERIPHERAL_ID1	0xfe4
#define NI_PIDR1_PART_11_8	GENMASK(3, 0)
#define NI_PERIPHERAL_ID2	0xfe8
#define NI_PIDR2_VERSION	GENMASK(7, 4)

/* PMU node */
#define NI_PMEVCNTR(n)		(0x008 + (n) * 8)
#define NI_PMCCNTR_L		0x0f8
#define NI_PMCCNTR_U		0x0fc
#define NI_PMEVTYPER(n)		(0x400 + (n) * 4)
#define NI_PMEVTYPER_NODE_TYPE	GENMASK(12, 9)
#define NI_PMEVTYPER_NODE_ID	GENMASK(8, 0)
#define NI_PMCNTENSET		0xc00
#define NI_PMCNTENCLR		0xc20
#define NI_PMINTENSET		0xc40
#define NI_PMINTENCLR		0xc60
#define NI_PMOVSCLR		0xc80
#define NI_PMOVSSET		0xcc0
#define NI_PMCFGR		0xe00
#define NI_PMCR			0xe04
#define NI_PMCR_RESET_CCNT	BIT(2)
#define NI_PMCR_RESET_EVCNT	BIT(1)
#define NI_PMCR_ENABLE		BIT(0)

#define NI_NUM_COUNTERS		8
#define NI_CCNT_IDX		31

/* Event attributes */
#define NI_CONFIG_TYPE		GENMASK_ULL(15, 0)
#define NI_CONFIG_NODEID	GENMASK_ULL(31, 16)
#define NI_CONFIG_EVENTID	GENMASK_ULL(47, 32)

#define NI_EVENT_TYPE(event)	FIELD_GET(NI_CONFIG_TYPE, (event)->attr.config)
#define NI_EVENT_NODEID(event)	FIELD_GET(NI_CONFIG_NODEID, (event)->attr.config)
#define NI_EVENT_EVENTID(event)	FIELD_GET(NI_CONFIG_EVENTID, (event)->attr.config)

enum ni_part {
	PART_NI_700 = 0x43b,
	PART_NI_710AE = 0x43d,
};

enum ni_node_type {
	NI_GLOBAL,
	NI_VOLTAGE,
	NI_POWER,
	NI_CLOCK,
	NI_ASNI,
	NI_AMNI,
	NI_PMU,
	NI_HSNI,
	NI_HMNI,
	NI_PMNI,
};

struct arm_ni_node {
	void __iomem *base;
	enum ni_node_type type;
	u16 id;
	u32 num_components;
};

struct arm_ni_unit {
	void __iomem *pmusela;
	enum ni_node_type type;
	u16 id;
	bool ns;
	union {
		__le64 pmusel;
		u8 event[8];
	};
};

struct arm_ni_cd {
	void __iomem *pmu_base;
	u16 id;
	int num_units;
	int irq;
	int cpu;
	struct hlist_node cpuhp_node;
	struct pmu pmu;
	struct arm_ni_unit *units;
	struct perf_event *evcnt[NI_NUM_COUNTERS];
	struct perf_event *ccnt;
};

struct arm_ni {
	struct device *dev;
	void __iomem *base;
	enum ni_part part;
	int id;
	int num_cds;
	struct arm_ni_cd cds[] __counted_by(num_cds);
};

#define cd_to_ni(cd) container_of((cd), struct arm_ni, cds[(cd)->id])
#define pmu_to_cd(p) container_of((p), struct arm_ni_cd, pmu)

#define cd_for_each_unit(cd, u) \
	for (struct arm_ni_unit *u = cd->units; u < cd->units + cd->num_units; u++)

static int arm_ni_hp_state;

struct arm_ni_event_attr {
	struct device_attribute attr;
	enum ni_node_type type;
};

#define NI_EVENT_ATTR(_name, _type)					\
	(&((struct arm_ni_event_attr[]) {{				\
		.attr = __ATTR(_name, 0444, arm_ni_event_show, NULL),	\
		.type = _type,						\
	}})[0].attr.attr)

static ssize_t arm_ni_event_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
{
	struct arm_ni_event_attr *eattr = container_of(attr, typeof(*eattr), attr);

	if (eattr->type == NI_PMU)
		return sysfs_emit(buf, "type=0x%x\n", eattr->type);

	return sysfs_emit(buf, "type=0x%x,eventid=?,nodeid=?\n", eattr->type);
}

static umode_t arm_ni_event_attr_is_visible(struct kobject *kobj,
					    struct attribute *attr, int unused)
{
	struct device *dev = kobj_to_dev(kobj);
	struct arm_ni_cd *cd = pmu_to_cd(dev_get_drvdata(dev));
	struct arm_ni_event_attr *eattr;

	eattr = container_of(attr, typeof(*eattr), attr.attr);

	cd_for_each_unit(cd, unit) {
		if (unit->type == eattr->type && unit->ns)
			return attr->mode;
	}

	return 0;
}

static struct attribute *arm_ni_event_attrs[] = {
	NI_EVENT_ATTR(asni, NI_ASNI),
	NI_EVENT_ATTR(amni, NI_AMNI),
	NI_EVENT_ATTR(cycles, NI_PMU),
	NI_EVENT_ATTR(hsni, NI_HSNI),
	NI_EVENT_ATTR(hmni, NI_HMNI),
	NI_EVENT_ATTR(pmni, NI_PMNI),
	NULL
};

static const struct attribute_group arm_ni_event_attrs_group = {
	.name = "events",
	.attrs = arm_ni_event_attrs,
	.is_visible = arm_ni_event_attr_is_visible,
};

struct arm_ni_format_attr {
	struct device_attribute attr;
	u64 field;
};

#define NI_FORMAT_ATTR(_name, _fld)					\
	(&((struct arm_ni_format_attr[]) {{				\
		.attr = __ATTR(_name, 0444, arm_ni_format_show, NULL),	\
		.field = _fld,						\
	}})[0].attr.attr)

static ssize_t arm_ni_format_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
{
	struct arm_ni_format_attr *fmt = container_of(attr, typeof(*fmt), attr);

	return sysfs_emit(buf, "config:%*pbl\n", 64, &fmt->field);
}

static struct attribute *arm_ni_format_attrs[] = {
	NI_FORMAT_ATTR(type, NI_CONFIG_TYPE),
	NI_FORMAT_ATTR(nodeid, NI_CONFIG_NODEID),
	NI_FORMAT_ATTR(eventid, NI_CONFIG_EVENTID),
	NULL
};

static const struct attribute_group arm_ni_format_attrs_group = {
	.name = "format",
	.attrs = arm_ni_format_attrs,
};

static ssize_t arm_ni_cpumask_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	struct arm_ni_cd *cd = pmu_to_cd(dev_get_drvdata(dev));

	return cpumap_print_to_pagebuf(true, buf, cpumask_of(cd->cpu));
}

static struct device_attribute arm_ni_cpumask_attr =
		__ATTR(cpumask, 0444, arm_ni_cpumask_show, NULL);

static ssize_t arm_ni_identifier_show(struct device *dev,
				      struct device_attribute *attr, char *buf)
{
	struct arm_ni *ni = cd_to_ni(pmu_to_cd(dev_get_drvdata(dev)));
	u32 reg = readl_relaxed(ni->base + NI_PERIPHERAL_ID2);
	int version = FIELD_GET(NI_PIDR2_VERSION, reg);

	return sysfs_emit(buf, "%03x%02x\n", ni->part, version);
}

static struct device_attribute arm_ni_identifier_attr =
		__ATTR(identifier, 0444, arm_ni_identifier_show, NULL);

static struct attribute *arm_ni_other_attrs[] = {
	&arm_ni_cpumask_attr.attr,
	&arm_ni_identifier_attr.attr,
	NULL
};

static const struct attribute_group arm_ni_other_attr_group = {
	.attrs = arm_ni_other_attrs,
	NULL
};

static const struct attribute_group *arm_ni_attr_groups[] = {
	&arm_ni_event_attrs_group,
	&arm_ni_format_attrs_group,
	&arm_ni_other_attr_group,
	NULL
};

static void arm_ni_pmu_enable(struct pmu *pmu)
{
	writel_relaxed(NI_PMCR_ENABLE, pmu_to_cd(pmu)->pmu_base + NI_PMCR);
}

static void arm_ni_pmu_disable(struct pmu *pmu)
{
	writel_relaxed(0, pmu_to_cd(pmu)->pmu_base + NI_PMCR);
}

struct arm_ni_val {
	unsigned int evcnt;
	unsigned int ccnt;
};

static bool arm_ni_val_count_event(struct perf_event *evt, struct arm_ni_val *val)
{
	if (is_software_event(evt))
		return true;

	if (NI_EVENT_TYPE(evt) == NI_PMU) {
		val->ccnt++;
		return val->ccnt <= 1;
	}

	val->evcnt++;
	return val->evcnt <= NI_NUM_COUNTERS;
}

static int arm_ni_validate_group(struct perf_event *event)
{
	struct perf_event *sibling, *leader = event->group_leader;
	struct arm_ni_val val = { 0 };

	if (leader == event)
		return 0;

	arm_ni_val_count_event(event, &val);
	if (!arm_ni_val_count_event(leader, &val))
		return -EINVAL;

	for_each_sibling_event(sibling, leader) {
		if (!arm_ni_val_count_event(sibling, &val))
			return -EINVAL;
	}
	return 0;
}

static int arm_ni_event_init(struct perf_event *event)
{
	struct arm_ni_cd *cd = pmu_to_cd(event->pmu);

	if (event->attr.type != event->pmu->type)
		return -ENOENT;

	if (is_sampling_event(event))
		return -EINVAL;

	event->cpu = cd->cpu;
	if (NI_EVENT_TYPE(event) == NI_PMU)
		return arm_ni_validate_group(event);

	cd_for_each_unit(cd, unit) {
		if (unit->type == NI_EVENT_TYPE(event) &&
		    unit->id == NI_EVENT_NODEID(event) && unit->ns) {
			event->hw.config_base = (unsigned long)unit;
			return arm_ni_validate_group(event);
		}
	}
	return -EINVAL;
}

static u64 arm_ni_read_ccnt(struct arm_ni_cd *cd)
{
	u64 l, u_old, u_new;
	int retries = 3; /* 1st time unlucky, 2nd improbable, 3rd just broken */

	u_new = readl_relaxed(cd->pmu_base + NI_PMCCNTR_U);
	do {
		u_old = u_new;
		l = readl_relaxed(cd->pmu_base + NI_PMCCNTR_L);
		u_new = readl_relaxed(cd->pmu_base + NI_PMCCNTR_U);
	} while (u_new != u_old && --retries);
	WARN_ON(!retries);

	return (u_new << 32) | l;
}

static void arm_ni_event_read(struct perf_event *event)
{
	struct arm_ni_cd *cd = pmu_to_cd(event->pmu);
	struct hw_perf_event *hw = &event->hw;
	u64 count, prev;
	bool ccnt = hw->idx == NI_CCNT_IDX;

	do {
		prev = local64_read(&hw->prev_count);
		if (ccnt)
			count = arm_ni_read_ccnt(cd);
		else
			count = readl_relaxed(cd->pmu_base + NI_PMEVCNTR(hw->idx));
	} while (local64_cmpxchg(&hw->prev_count, prev, count) != prev);

	count -= prev;
	if (!ccnt)
		count = (u32)count;
	local64_add(count, &event->count);
}

static void arm_ni_event_start(struct perf_event *event, int flags)
{
	struct arm_ni_cd *cd = pmu_to_cd(event->pmu);

	writel_relaxed(1U << event->hw.idx, cd->pmu_base + NI_PMCNTENSET);
}

static void arm_ni_event_stop(struct perf_event *event, int flags)
{
	struct arm_ni_cd *cd = pmu_to_cd(event->pmu);

	writel_relaxed(1U << event->hw.idx, cd->pmu_base + NI_PMCNTENCLR);
	if (flags & PERF_EF_UPDATE)
		arm_ni_event_read(event);
}

static void arm_ni_init_ccnt(struct arm_ni_cd *cd)
{
	local64_set(&cd->ccnt->hw.prev_count, S64_MIN);
	lo_hi_writeq_relaxed(S64_MIN, cd->pmu_base + NI_PMCCNTR_L);
}

static void arm_ni_init_evcnt(struct arm_ni_cd *cd, int idx)
{
	local64_set(&cd->evcnt[idx]->hw.prev_count, S32_MIN);
	writel_relaxed(S32_MIN, cd->pmu_base + NI_PMEVCNTR(idx));
}

static int arm_ni_event_add(struct perf_event *event, int flags)
{
	struct arm_ni_cd *cd = pmu_to_cd(event->pmu);
	struct hw_perf_event *hw = &event->hw;
	struct arm_ni_unit *unit;
	enum ni_node_type type = NI_EVENT_TYPE(event);
	u32 reg;

	if (type == NI_PMU) {
		if (cd->ccnt)
			return -ENOSPC;
		hw->idx = NI_CCNT_IDX;
		cd->ccnt = event;
		arm_ni_init_ccnt(cd);
	} else {
		hw->idx = 0;
		while (cd->evcnt[hw->idx]) {
			if (++hw->idx == NI_NUM_COUNTERS)
				return -ENOSPC;
		}
		cd->evcnt[hw->idx] = event;
		unit = (void *)hw->config_base;
		unit->event[hw->idx] = NI_EVENT_EVENTID(event);
		arm_ni_init_evcnt(cd, hw->idx);
		lo_hi_writeq_relaxed(le64_to_cpu(unit->pmusel), unit->pmusela);

		reg = FIELD_PREP(NI_PMEVTYPER_NODE_TYPE, type) |
		      FIELD_PREP(NI_PMEVTYPER_NODE_ID, NI_EVENT_NODEID(event));
		writel_relaxed(reg, cd->pmu_base + NI_PMEVTYPER(hw->idx));
	}
	if (flags & PERF_EF_START)
		arm_ni_event_start(event, 0);
	return 0;
}

static void arm_ni_event_del(struct perf_event *event, int flags)
{
	struct arm_ni_cd *cd = pmu_to_cd(event->pmu);
	struct hw_perf_event *hw = &event->hw;

	arm_ni_event_stop(event, PERF_EF_UPDATE);

	if (hw->idx == NI_CCNT_IDX)
		cd->ccnt = NULL;
	else
		cd->evcnt[hw->idx] = NULL;
}

static irqreturn_t arm_ni_handle_irq(int irq, void *dev_id)
{
	struct arm_ni_cd *cd = dev_id;
	irqreturn_t ret = IRQ_NONE;
	u32 reg = readl_relaxed(cd->pmu_base + NI_PMOVSCLR);

	if (reg & (1U << NI_CCNT_IDX)) {
		ret = IRQ_HANDLED;
		if (!(WARN_ON(!cd->ccnt))) {
			arm_ni_event_read(cd->ccnt);
			arm_ni_init_ccnt(cd);
		}
	}
	for (int i = 0; i < NI_NUM_COUNTERS; i++) {
		if (!(reg & (1U << i)))
			continue;
		ret = IRQ_HANDLED;
		if (!(WARN_ON(!cd->evcnt[i]))) {
			arm_ni_event_read(cd->evcnt[i]);
			arm_ni_init_evcnt(cd, i);
		}
	}
	writel_relaxed(reg, cd->pmu_base + NI_PMOVSCLR);
	return ret;
}

static int arm_ni_init_cd(struct arm_ni *ni, struct arm_ni_node *node, u64 res_start)
{
	struct arm_ni_cd *cd = ni->cds + node->id;
	const char *name;
	int err;

	cd->id = node->id;
	cd->num_units = node->num_components;
	cd->units = devm_kcalloc(ni->dev, cd->num_units, sizeof(*(cd->units)), GFP_KERNEL);
	if (!cd->units)
		return -ENOMEM;

	for (int i = 0; i < cd->num_units; i++) {
		u32 reg = readl_relaxed(node->base + NI_CHILD_PTR(i));
		void __iomem *unit_base = ni->base + reg;
		struct arm_ni_unit *unit = cd->units + i;

		reg = readl_relaxed(unit_base + NI_NODE_TYPE);
		unit->type = FIELD_GET(NI_NODE_TYPE_NODE_TYPE, reg);
		unit->id = FIELD_GET(NI_NODE_TYPE_NODE_ID, reg);

		switch (unit->type) {
		case NI_PMU:
			reg = readl_relaxed(unit_base + NI_PMCFGR);
			if (!reg) {
				dev_info(ni->dev, "No access to PMU %d\n", cd->id);
				devm_kfree(ni->dev, cd->units);
				return 0;
			}
			unit->ns = true;
			cd->pmu_base = unit_base;
			break;
		case NI_ASNI:
		case NI_AMNI:
		case NI_HSNI:
		case NI_HMNI:
		case NI_PMNI:
			unit->pmusela = unit_base + NI700_PMUSELA;
			writel_relaxed(1, unit->pmusela);
			if (readl_relaxed(unit->pmusela) != 1)
				dev_info(ni->dev, "No access to node 0x%04x%04x\n", unit->id, unit->type);
			else
				unit->ns = true;
			break;
		default:
			/*
			 * e.g. FMU - thankfully bits 3:2 of FMU_ERR_FR0 are RES0 so
			 * can't alias any of the leaf node types we're looking for.
			 */
			dev_dbg(ni->dev, "Mystery node 0x%04x%04x\n", unit->id, unit->type);
			break;
		}
	}

	res_start += cd->pmu_base - ni->base;
	if (!devm_request_mem_region(ni->dev, res_start, SZ_4K, dev_name(ni->dev))) {
		dev_err(ni->dev, "Failed to request PMU region 0x%llx\n", res_start);
		return -EBUSY;
	}

	writel_relaxed(NI_PMCR_RESET_CCNT | NI_PMCR_RESET_EVCNT,
		       cd->pmu_base + NI_PMCR);
	writel_relaxed(U32_MAX, cd->pmu_base + NI_PMCNTENCLR);
	writel_relaxed(U32_MAX, cd->pmu_base + NI_PMOVSCLR);
	writel_relaxed(U32_MAX, cd->pmu_base + NI_PMINTENSET);

	cd->irq = platform_get_irq(to_platform_device(ni->dev), cd->id);
	if (cd->irq < 0)
		return cd->irq;

	err = devm_request_irq(ni->dev, cd->irq, arm_ni_handle_irq,
			       IRQF_NOBALANCING | IRQF_NO_THREAD,
			       dev_name(ni->dev), cd);
	if (err)
		return err;

	cd->cpu = cpumask_local_spread(0, dev_to_node(ni->dev));
	cd->pmu = (struct pmu) {
		.module = THIS_MODULE,
		.parent = ni->dev,
		.attr_groups = arm_ni_attr_groups,
		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
		.task_ctx_nr = perf_invalid_context,
		.pmu_enable = arm_ni_pmu_enable,
		.pmu_disable = arm_ni_pmu_disable,
		.event_init = arm_ni_event_init,
		.add = arm_ni_event_add,
		.del = arm_ni_event_del,
		.start = arm_ni_event_start,
		.stop = arm_ni_event_stop,
		.read = arm_ni_event_read,
	};

	name = devm_kasprintf(ni->dev, GFP_KERNEL, "arm_ni_%d_cd_%d", ni->id, cd->id);
	if (!name)
		return -ENOMEM;

	err = cpuhp_state_add_instance_nocalls(arm_ni_hp_state, &cd->cpuhp_node);
	if (err)
		return err;

	err = perf_pmu_register(&cd->pmu, name, -1);
	if (err)
		cpuhp_state_remove_instance_nocalls(arm_ni_hp_state, &cd->cpuhp_node);

	return err;
}

static void arm_ni_probe_domain(void __iomem *base, struct arm_ni_node *node)
{
	u32 reg = readl_relaxed(base + NI_NODE_TYPE);

	node->base = base;
	node->type = FIELD_GET(NI_NODE_TYPE_NODE_TYPE, reg);
	node->id = FIELD_GET(NI_NODE_TYPE_NODE_ID, reg);
	node->num_components = readl_relaxed(base + NI_CHILD_NODE_INFO);
}

static int arm_ni_probe(struct platform_device *pdev)
{
	struct arm_ni_node cfg, vd, pd, cd;
	struct arm_ni *ni;
	struct resource *res;
	void __iomem *base;
	static atomic_t id;
	int num_cds;
	u32 reg, part;

	/*
	 * We want to map the whole configuration space for ease of discovery,
	 * but the PMU pages are the only ones for which we can honestly claim
	 * exclusive ownership, so we'll request them explicitly once found.
	 */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (!base)
		return -ENOMEM;

	arm_ni_probe_domain(base, &cfg);
	if (cfg.type != NI_GLOBAL)
		return -ENODEV;

	reg = readl_relaxed(cfg.base + NI_PERIPHERAL_ID0);
	part = FIELD_GET(NI_PIDR0_PART_7_0, reg);
	reg = readl_relaxed(cfg.base + NI_PERIPHERAL_ID1);
	part |= FIELD_GET(NI_PIDR1_PART_11_8, reg) << 8;

	switch (part) {
	case PART_NI_700:
	case PART_NI_710AE:
		break;
	default:
		dev_WARN(&pdev->dev, "Unknown part number: 0x%03x, this may go badly\n", part);
		break;
	}

	num_cds = 0;
	for (int v = 0; v < cfg.num_components; v++) {
		reg = readl_relaxed(cfg.base + NI_CHILD_PTR(v));
		arm_ni_probe_domain(base + reg, &vd);
		for (int p = 0; p < vd.num_components; p++) {
			reg = readl_relaxed(vd.base + NI_CHILD_PTR(p));
			arm_ni_probe_domain(base + reg, &pd);
			num_cds += pd.num_components;
		}
	}

	ni = devm_kzalloc(&pdev->dev, struct_size(ni, cds, num_cds), GFP_KERNEL);
	if (!ni)
		return -ENOMEM;

	ni->dev = &pdev->dev;
	ni->base = base;
	ni->num_cds = num_cds;
	ni->part = part;
	ni->id = atomic_fetch_inc(&id);

	for (int v = 0; v < cfg.num_components; v++) {
		reg = readl_relaxed(cfg.base + NI_CHILD_PTR(v));
		arm_ni_probe_domain(base + reg, &vd);
		for (int p = 0; p < vd.num_components; p++) {
			reg = readl_relaxed(vd.base + NI_CHILD_PTR(p));
			arm_ni_probe_domain(base + reg, &pd);
			for (int c = 0; c < pd.num_components; c++) {
				int ret;

				reg = readl_relaxed(pd.base + NI_CHILD_PTR(c));
				arm_ni_probe_domain(base + reg, &cd);
				ret = arm_ni_init_cd(ni, &cd, res->start);
				if (ret)
					return ret;
			}
		}
	}

	return 0;
}

static void arm_ni_remove(struct platform_device *pdev)
{
	struct arm_ni *ni = platform_get_drvdata(pdev);

	for (int i = 0; i < ni->num_cds; i++) {
		struct arm_ni_cd *cd = ni->cds + i;

		if (!cd->pmu_base)
			continue;

		writel_relaxed(0, cd->pmu_base + NI_PMCR);
		writel_relaxed(U32_MAX, cd->pmu_base + NI_PMINTENCLR);
		perf_pmu_unregister(&cd->pmu);
		cpuhp_state_remove_instance_nocalls(arm_ni_hp_state, &cd->cpuhp_node);
	}
}

#ifdef CONFIG_OF
static const struct of_device_id arm_ni_of_match[] = {
	{ .compatible = "arm,ni-700" },
	{}
};
MODULE_DEVICE_TABLE(of, arm_ni_of_match);
#endif

#ifdef CONFIG_ACPI
static const struct acpi_device_id arm_ni_acpi_match[] = {
	{ "ARMHCB70" },
	{}
};
MODULE_DEVICE_TABLE(acpi, arm_ni_acpi_match);
#endif

static struct platform_driver arm_ni_driver = {
	.driver = {
		.name = "arm-ni",
		.of_match_table = of_match_ptr(arm_ni_of_match),
		.acpi_match_table = ACPI_PTR(arm_ni_acpi_match),
	},
	.probe = arm_ni_probe,
	.remove = arm_ni_remove,
};

static void arm_ni_pmu_migrate(struct arm_ni_cd *cd, unsigned int cpu)
{
	perf_pmu_migrate_context(&cd->pmu, cd->cpu, cpu);
	irq_set_affinity(cd->irq, cpumask_of(cpu));
	cd->cpu = cpu;
}

static int arm_ni_pmu_online_cpu(unsigned int cpu, struct hlist_node *cpuhp_node)
{
	struct arm_ni_cd *cd;
	int node;

	cd = hlist_entry_safe(cpuhp_node, struct arm_ni_cd, cpuhp_node);
	node = dev_to_node(cd_to_ni(cd)->dev);
	if (cpu_to_node(cd->cpu) != node && cpu_to_node(cpu) == node)
		arm_ni_pmu_migrate(cd, cpu);
	return 0;
}

static int arm_ni_pmu_offline_cpu(unsigned int cpu, struct hlist_node *cpuhp_node)
{
	struct arm_ni_cd *cd;
	unsigned int target;
	int node;

	cd = hlist_entry_safe(cpuhp_node, struct arm_ni_cd, cpuhp_node);
	if (cpu != cd->cpu)
		return 0;

	node = dev_to_node(cd_to_ni(cd)->dev);
	target = cpumask_any_and_but(cpumask_of_node(node), cpu_online_mask, cpu);
	if (target >= nr_cpu_ids)
		target = cpumask_any_but(cpu_online_mask, cpu);

	if (target < nr_cpu_ids)
		arm_ni_pmu_migrate(cd, target);
	return 0;
}

static int __init arm_ni_init(void)
{
	int ret;

	ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
				      "perf/arm/ni:online",
				      arm_ni_pmu_online_cpu,
				      arm_ni_pmu_offline_cpu);
	if (ret < 0)
		return ret;

	arm_ni_hp_state = ret;

	ret = platform_driver_register(&arm_ni_driver);
	if (ret)
		cpuhp_remove_multi_state(arm_ni_hp_state);
	return ret;
}

static void __exit arm_ni_exit(void)
{
	platform_driver_unregister(&arm_ni_driver);
	cpuhp_remove_multi_state(arm_ni_hp_state);
}

module_init(arm_ni_init);
module_exit(arm_ni_exit);

MODULE_AUTHOR("Robin Murphy <robin.murphy@arm.com>");
MODULE_DESCRIPTION("Arm NI-700 PMU driver");
MODULE_LICENSE("GPL v2");
