/*
 * Meta performance counter support.
 *  Copyright (C) 2012 Imagination Technologies Ltd
 *
 * This code is based on the sh pmu code:
 *  Copyright (C) 2009 Paul Mundt
 *
 * and on the arm pmu code:
 *  Copyright (C) 2009 picoChip Designs, Ltd., James Iles
 *  Copyright (C) 2010 ARM Ltd., Will Deacon <will.deacon@arm.com>
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */

#include <linux/atomic.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/irqchip/metag.h>
#include <linux/perf_event.h>
#include <linux/slab.h>

#include <asm/core_reg.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/processor.h>

#include "perf_event.h"

static int _hw_perf_event_init(struct perf_event *);
static void _hw_perf_event_destroy(struct perf_event *);

/* Determines which core type we are */
static struct metag_pmu *metag_pmu __read_mostly;

/* Processor specific data */
static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);

/* PMU admin */
const char *perf_pmu_name(void)
{
	if (!metag_pmu)
		return NULL;

	return metag_pmu->name;
}
EXPORT_SYMBOL_GPL(perf_pmu_name);

int perf_num_counters(void)
{
	if (metag_pmu)
		return metag_pmu->max_events;

	return 0;
}
EXPORT_SYMBOL_GPL(perf_num_counters);

static inline int metag_pmu_initialised(void)
{
	return !!metag_pmu;
}

static void release_pmu_hardware(void)
{
	int irq;
	unsigned int version = (metag_pmu->version &
			(METAC_ID_MINOR_BITS | METAC_ID_REV_BITS)) >>
			METAC_ID_REV_S;

	/* Early cores don't have overflow interrupts */
	if (version < 0x0104)
		return;

	irq = internal_irq_map(17);
	if (irq >= 0)
		free_irq(irq, (void *)1);

	irq = internal_irq_map(16);
	if (irq >= 0)
		free_irq(irq, (void *)0);
}

static int reserve_pmu_hardware(void)
{
	int err = 0, irq[2];
	unsigned int version = (metag_pmu->version &
			(METAC_ID_MINOR_BITS | METAC_ID_REV_BITS)) >>
			METAC_ID_REV_S;

	/* Early cores don't have overflow interrupts */
	if (version < 0x0104)
		goto out;

	/*
	 * Bit 16 on HWSTATMETA is the interrupt for performance counter 0;
	 * similarly, 17 is the interrupt for performance counter 1.
	 * We can't (yet) interrupt on the cycle counter, because it's a
	 * register, however it holds a 32-bit value as opposed to 24-bit.
	 */
	irq[0] = internal_irq_map(16);
	if (irq[0] < 0) {
		pr_err("unable to map internal IRQ %d\n", 16);
		goto out;
	}
	err = request_irq(irq[0], metag_pmu->handle_irq, IRQF_NOBALANCING,
			"metagpmu0", (void *)0);
	if (err) {
		pr_err("unable to request IRQ%d for metag PMU counters\n",
				irq[0]);
		goto out;
	}

	irq[1] = internal_irq_map(17);
	if (irq[1] < 0) {
		pr_err("unable to map internal IRQ %d\n", 17);
		goto out_irq1;
	}
	err = request_irq(irq[1], metag_pmu->handle_irq, IRQF_NOBALANCING,
			"metagpmu1", (void *)1);
	if (err) {
		pr_err("unable to request IRQ%d for metag PMU counters\n",
				irq[1]);
		goto out_irq1;
	}

	return 0;

out_irq1:
	free_irq(irq[0], (void *)0);
out:
	return err;
}

/* PMU operations */
static void metag_pmu_enable(struct pmu *pmu)
{
}

static void metag_pmu_disable(struct pmu *pmu)
{
}

static int metag_pmu_event_init(struct perf_event *event)
{
	int err = 0;
	atomic_t *active_events = &metag_pmu->active_events;

	if (!metag_pmu_initialised()) {
		err = -ENODEV;
		goto out;
	}

	if (has_branch_stack(event))
		return -EOPNOTSUPP;

	event->destroy = _hw_perf_event_destroy;

	if (!atomic_inc_not_zero(active_events)) {
		mutex_lock(&metag_pmu->reserve_mutex);
		if (atomic_read(active_events) == 0)
			err = reserve_pmu_hardware();

		if (!err)
			atomic_inc(active_events);

		mutex_unlock(&metag_pmu->reserve_mutex);
	}

	/* Hardware and caches counters */
	switch (event->attr.type) {
	case PERF_TYPE_HARDWARE:
	case PERF_TYPE_HW_CACHE:
	case PERF_TYPE_RAW:
		err = _hw_perf_event_init(event);
		break;

	default:
		return -ENOENT;
	}

	if (err)
		event->destroy(event);

out:
	return err;
}

void metag_pmu_event_update(struct perf_event *event,
		struct hw_perf_event *hwc, int idx)
{
	u64 prev_raw_count, new_raw_count;
	s64 delta;

	/*
	 * If this counter is chained, it may be that the previous counter
	 * value has been changed beneath us.
	 *
	 * To get around this, we read and exchange the new raw count, then
	 * add the delta (new - prev) to the generic counter atomically.
	 *
	 * Without interrupts, this is the simplest approach.
	 */
again:
	prev_raw_count = local64_read(&hwc->prev_count);
	new_raw_count = metag_pmu->read(idx);

	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
			new_raw_count) != prev_raw_count)
		goto again;

	/*
	 * Calculate the delta and add it to the counter.
	 */
	delta = (new_raw_count - prev_raw_count) & MAX_PERIOD;

	local64_add(delta, &event->count);
	local64_sub(delta, &hwc->period_left);
}

int metag_pmu_event_set_period(struct perf_event *event,
		struct hw_perf_event *hwc, int idx)
{
	s64 left = local64_read(&hwc->period_left);
	s64 period = hwc->sample_period;
	int ret = 0;

	/* The period may have been changed */
	if (unlikely(period != hwc->last_period))
		left += period - hwc->last_period;

	if (unlikely(left <= -period)) {
		left = period;
		local64_set(&hwc->period_left, left);
		hwc->last_period = period;
		ret = 1;
	}

	if (unlikely(left <= 0)) {
		left += period;
		local64_set(&hwc->period_left, left);
		hwc->last_period = period;
		ret = 1;
	}

	if (left > (s64)metag_pmu->max_period)
		left = metag_pmu->max_period;

	if (metag_pmu->write) {
		local64_set(&hwc->prev_count, -(s32)left);
		metag_pmu->write(idx, -left & MAX_PERIOD);
	}

	perf_event_update_userpage(event);

	return ret;
}

static void metag_pmu_start(struct perf_event *event, int flags)
{
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
	struct hw_perf_event *hwc = &event->hw;
	int idx = hwc->idx;

	if (WARN_ON_ONCE(idx == -1))
		return;

	/*
	 * We always have to reprogram the period, so ignore PERF_EF_RELOAD.
	 */
	if (flags & PERF_EF_RELOAD)
		WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));

	hwc->state = 0;

	/*
	 * Reset the period.
	 * Some counters can't be stopped (i.e. are core global), so when the
	 * counter was 'stopped' we merely disabled the IRQ. If we don't reset
	 * the period, then we'll either: a) get an overflow too soon;
	 * or b) too late if the overflow happened since disabling.
	 * Obviously, this has little bearing on cores without the overflow
	 * interrupt, as the performance counter resets to zero on write
	 * anyway.
	 */
	if (metag_pmu->max_period)
		metag_pmu_event_set_period(event, hwc, hwc->idx);
	cpuc->events[idx] = event;
	metag_pmu->enable(hwc, idx);
}

static void metag_pmu_stop(struct perf_event *event, int flags)
{
	struct hw_perf_event *hwc = &event->hw;

	/*
	 * We should always update the counter on stop; see comment above
	 * why.
	 */
	if (!(hwc->state & PERF_HES_STOPPED)) {
		metag_pmu_event_update(event, hwc, hwc->idx);
		metag_pmu->disable(hwc, hwc->idx);
		hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
	}
}

static int metag_pmu_add(struct perf_event *event, int flags)
{
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
	struct hw_perf_event *hwc = &event->hw;
	int idx = 0, ret = 0;

	perf_pmu_disable(event->pmu);

	/* check whether we're counting instructions */
	if (hwc->config == 0x100) {
		if (__test_and_set_bit(METAG_INST_COUNTER,
				cpuc->used_mask)) {
			ret = -EAGAIN;
			goto out;
		}
		idx = METAG_INST_COUNTER;
	} else {
		/* Check whether we have a spare counter */
		idx = find_first_zero_bit(cpuc->used_mask,
				atomic_read(&metag_pmu->active_events));
		if (idx >= METAG_INST_COUNTER) {
			ret = -EAGAIN;
			goto out;
		}

		__set_bit(idx, cpuc->used_mask);
	}
	hwc->idx = idx;

	/* Make sure the counter is disabled */
	metag_pmu->disable(hwc, idx);

	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
	if (flags & PERF_EF_START)
		metag_pmu_start(event, PERF_EF_RELOAD);

	perf_event_update_userpage(event);
out:
	perf_pmu_enable(event->pmu);
	return ret;
}

static void metag_pmu_del(struct perf_event *event, int flags)
{
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
	struct hw_perf_event *hwc = &event->hw;
	int idx = hwc->idx;

	WARN_ON(idx < 0);
	metag_pmu_stop(event, PERF_EF_UPDATE);
	cpuc->events[idx] = NULL;
	__clear_bit(idx, cpuc->used_mask);

	perf_event_update_userpage(event);
}

static void metag_pmu_read(struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;

	/* Don't read disabled counters! */
	if (hwc->idx < 0)
		return;

	metag_pmu_event_update(event, hwc, hwc->idx);
}

static struct pmu pmu = {
	.pmu_enable	= metag_pmu_enable,
	.pmu_disable	= metag_pmu_disable,

	.event_init	= metag_pmu_event_init,

	.add		= metag_pmu_add,
	.del		= metag_pmu_del,
	.start		= metag_pmu_start,
	.stop		= metag_pmu_stop,
	.read		= metag_pmu_read,
};

/* Core counter specific functions */
static const int metag_general_events[] = {
	[PERF_COUNT_HW_CPU_CYCLES] = 0x03,
	[PERF_COUNT_HW_INSTRUCTIONS] = 0x100,
	[PERF_COUNT_HW_CACHE_REFERENCES] = -1,
	[PERF_COUNT_HW_CACHE_MISSES] = -1,
	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = -1,
	[PERF_COUNT_HW_BRANCH_MISSES] = -1,
	[PERF_COUNT_HW_BUS_CYCLES] = -1,
	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = -1,
	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = -1,
	[PERF_COUNT_HW_REF_CPU_CYCLES] = -1,
};

static const int metag_pmu_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
	[C(L1D)] = {
		[C(OP_READ)] = {
			[C(RESULT_ACCESS)] = 0x08,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
		[C(OP_WRITE)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
		[C(OP_PREFETCH)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
	},
	[C(L1I)] = {
		[C(OP_READ)] = {
			[C(RESULT_ACCESS)] = 0x09,
			[C(RESULT_MISS)] = 0x0a,
		},
		[C(OP_WRITE)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
		[C(OP_PREFETCH)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
	},
	[C(LL)] = {
		[C(OP_READ)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
		[C(OP_WRITE)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
		[C(OP_PREFETCH)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
	},
	[C(DTLB)] = {
		[C(OP_READ)] = {
			[C(RESULT_ACCESS)] = 0xd0,
			[C(RESULT_MISS)] = 0xd2,
		},
		[C(OP_WRITE)] = {
			[C(RESULT_ACCESS)] = 0xd4,
			[C(RESULT_MISS)] = 0xd5,
		},
		[C(OP_PREFETCH)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
	},
	[C(ITLB)] = {
		[C(OP_READ)] = {
			[C(RESULT_ACCESS)] = 0xd1,
			[C(RESULT_MISS)] = 0xd3,
		},
		[C(OP_WRITE)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
		[C(OP_PREFETCH)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
	},
	[C(BPU)] = {
		[C(OP_READ)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
		[C(OP_WRITE)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
		[C(OP_PREFETCH)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
	},
	[C(NODE)] = {
		[C(OP_READ)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
		[C(OP_WRITE)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
		[C(OP_PREFETCH)] = {
			[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
			[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
		},
	},
};


static void _hw_perf_event_destroy(struct perf_event *event)
{
	atomic_t *active_events = &metag_pmu->active_events;
	struct mutex *pmu_mutex = &metag_pmu->reserve_mutex;

	if (atomic_dec_and_mutex_lock(active_events, pmu_mutex)) {
		release_pmu_hardware();
		mutex_unlock(pmu_mutex);
	}
}

static int _hw_perf_cache_event(int config, int *evp)
{
	unsigned long type, op, result;
	int ev;

	if (!metag_pmu->cache_events)
		return -EINVAL;

	/* Unpack config */
	type = config & 0xff;
	op = (config >> 8) & 0xff;
	result = (config >> 16) & 0xff;

	if (type >= PERF_COUNT_HW_CACHE_MAX ||
			op >= PERF_COUNT_HW_CACHE_OP_MAX ||
			result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
		return -EINVAL;

	ev = (*metag_pmu->cache_events)[type][op][result];
	if (ev == 0)
		return -EOPNOTSUPP;
	if (ev == -1)
		return -EINVAL;
	*evp = ev;
	return 0;
}

static int _hw_perf_event_init(struct perf_event *event)
{
	struct perf_event_attr *attr = &event->attr;
	struct hw_perf_event *hwc = &event->hw;
	int mapping = 0, err;

	switch (attr->type) {
	case PERF_TYPE_HARDWARE:
		if (attr->config >= PERF_COUNT_HW_MAX)
			return -EINVAL;

		mapping = metag_pmu->event_map(attr->config);
		break;

	case PERF_TYPE_HW_CACHE:
		err = _hw_perf_cache_event(attr->config, &mapping);
		if (err)
			return err;
		break;

	case PERF_TYPE_RAW:
		mapping = attr->config;
		break;
	}

	/* Return early if the event is unsupported */
	if (mapping == -1)
		return -EINVAL;

	/*
	 * Don't assign an index until the event is placed into the hardware.
	 * -1 signifies that we're still deciding where to put it. On SMP
	 * systems each core has its own set of counters, so we can't do any
	 * constraint checking yet.
	 */
	hwc->idx = -1;

	/* Store the event encoding */
	hwc->config |= (unsigned long)mapping;

	/*
	 * For non-sampling runs, limit the sample_period to half of the
	 * counter width. This way, the new counter value should be less
	 * likely to overtake the previous one (unless there are IRQ latency
	 * issues...)
	 */
	if (metag_pmu->max_period) {
		if (!hwc->sample_period) {
			hwc->sample_period = metag_pmu->max_period >> 1;
			hwc->last_period = hwc->sample_period;
			local64_set(&hwc->period_left, hwc->sample_period);
		}
	}

	return 0;
}

static void metag_pmu_enable_counter(struct hw_perf_event *event, int idx)
{
	struct cpu_hw_events *events = this_cpu_ptr(&cpu_hw_events);
	unsigned int config = event->config;
	unsigned int tmp = config & 0xf0;
	unsigned long flags;

	raw_spin_lock_irqsave(&events->pmu_lock, flags);

	/*
	 * Check if we're enabling the instruction counter (index of
	 * MAX_HWEVENTS - 1)
	 */
	if (METAG_INST_COUNTER == idx) {
		WARN_ONCE((config != 0x100),
			"invalid configuration (%d) for counter (%d)\n",
			config, idx);
		local64_set(&event->prev_count, __core_reg_get(TXTACTCYC));
		goto unlock;
	}

	/* Check for a core internal or performance channel event. */
	if (tmp) {
		/* PERF_ICORE/PERF_CHAN only exist since Meta2 */
#ifdef METAC_2_1
		void *perf_addr;

		/*
		 * Anything other than a cycle count will write the low-
		 * nibble to the correct counter register.
		 */
		switch (tmp) {
		case 0xd0:
			perf_addr = (void *)PERF_ICORE(idx);
			break;

		case 0xf0:
			perf_addr = (void *)PERF_CHAN(idx);
			break;

		default:
			perf_addr = NULL;
			break;
		}

		if (perf_addr)
			metag_out32((config & 0x0f), perf_addr);
#endif

		/*
		 * Now we use the high nibble as the performance event to
		 * to count.
		 */
		config = tmp >> 4;
	}

	tmp = ((config & 0xf) << 28) |
			((1 << 24) << hard_processor_id());
	if (metag_pmu->max_period)
		/*
		 * Cores supporting overflow interrupts may have had the counter
		 * set to a specific value that needs preserving.
		 */
		tmp |= metag_in32(PERF_COUNT(idx)) & 0x00ffffff;
	else
		/*
		 * Older cores reset the counter on write, so prev_count needs
		 * resetting too so we can calculate a correct delta.
		 */
		local64_set(&event->prev_count, 0);

	metag_out32(tmp, PERF_COUNT(idx));
unlock:
	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}

static void metag_pmu_disable_counter(struct hw_perf_event *event, int idx)
{
	struct cpu_hw_events *events = this_cpu_ptr(&cpu_hw_events);
	unsigned int tmp = 0;
	unsigned long flags;

	/*
	 * The cycle counter can't be disabled per se, as it's a hardware
	 * thread register which is always counting. We merely return if this
	 * is the counter we're attempting to disable.
	 */
	if (METAG_INST_COUNTER == idx)
		return;

	/*
	 * The counter value _should_ have been read prior to disabling,
	 * as if we're running on an early core then the value gets reset to
	 * 0, and any read after that would be useless. On the newer cores,
	 * however, it's better to read-modify-update this for purposes of
	 * the overflow interrupt.
	 * Here we remove the thread id AND the event nibble (there are at
	 * least two events that count events that are core global and ignore
	 * the thread id mask). This only works because we don't mix thread
	 * performance counts, and event 0x00 requires a thread id mask!
	 */
	raw_spin_lock_irqsave(&events->pmu_lock, flags);

	tmp = metag_in32(PERF_COUNT(idx));
	tmp &= 0x00ffffff;
	metag_out32(tmp, PERF_COUNT(idx));

	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}

static u64 metag_pmu_read_counter(int idx)
{
	u32 tmp = 0;

	if (METAG_INST_COUNTER == idx) {
		tmp = __core_reg_get(TXTACTCYC);
		goto out;
	}

	tmp = metag_in32(PERF_COUNT(idx)) & 0x00ffffff;
out:
	return tmp;
}

static void metag_pmu_write_counter(int idx, u32 val)
{
	struct cpu_hw_events *events = this_cpu_ptr(&cpu_hw_events);
	u32 tmp = 0;
	unsigned long flags;

	/*
	 * This _shouldn't_ happen, but if it does, then we can just
	 * ignore the write, as the register is read-only and clear-on-write.
	 */
	if (METAG_INST_COUNTER == idx)
		return;

	/*
	 * We'll keep the thread mask and event id, and just update the
	 * counter itself. Also , we should bound the value to 24-bits.
	 */
	raw_spin_lock_irqsave(&events->pmu_lock, flags);

	val &= 0x00ffffff;
	tmp = metag_in32(PERF_COUNT(idx)) & 0xff000000;
	val |= tmp;
	metag_out32(val, PERF_COUNT(idx));

	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}

static int metag_pmu_event_map(int idx)
{
	return metag_general_events[idx];
}

static irqreturn_t metag_pmu_counter_overflow(int irq, void *dev)
{
	int idx = (int)dev;
	struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
	struct perf_event *event = cpuhw->events[idx];
	struct hw_perf_event *hwc = &event->hw;
	struct pt_regs *regs = get_irq_regs();
	struct perf_sample_data sampledata;
	unsigned long flags;
	u32 counter = 0;

	/*
	 * We need to stop the core temporarily from generating another
	 * interrupt while we disable this counter. However, we don't want
	 * to flag the counter as free
	 */
	__global_lock2(flags);
	counter = metag_in32(PERF_COUNT(idx));
	metag_out32((counter & 0x00ffffff), PERF_COUNT(idx));
	__global_unlock2(flags);

	/* Update the counts and reset the sample period */
	metag_pmu_event_update(event, hwc, idx);
	perf_sample_data_init(&sampledata, 0, hwc->last_period);
	metag_pmu_event_set_period(event, hwc, idx);

	/*
	 * Enable the counter again once core overflow processing has
	 * completed. Note the counter value may have been modified while it was
	 * inactive to set it up ready for the next interrupt.
	 */
	if (!perf_event_overflow(event, &sampledata, regs)) {
		__global_lock2(flags);
		counter = (counter & 0xff000000) |
			  (metag_in32(PERF_COUNT(idx)) & 0x00ffffff);
		metag_out32(counter, PERF_COUNT(idx));
		__global_unlock2(flags);
	}

	return IRQ_HANDLED;
}

static struct metag_pmu _metag_pmu = {
	.handle_irq	= metag_pmu_counter_overflow,
	.enable		= metag_pmu_enable_counter,
	.disable	= metag_pmu_disable_counter,
	.read		= metag_pmu_read_counter,
	.write		= metag_pmu_write_counter,
	.event_map	= metag_pmu_event_map,
	.cache_events	= &metag_pmu_cache_events,
	.max_period	= MAX_PERIOD,
	.max_events	= MAX_HWEVENTS,
};

/* PMU CPU hotplug notifier */
static int metag_pmu_starting_cpu(unsigned int cpu)
{
	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);

	memset(cpuc, 0, sizeof(struct cpu_hw_events));
	raw_spin_lock_init(&cpuc->pmu_lock);

	return 0;
}

/* PMU Initialisation */
static int __init init_hw_perf_events(void)
{
	int ret = 0, cpu;
	u32 version = *(u32 *)METAC_ID;
	int major = (version & METAC_ID_MAJOR_BITS) >> METAC_ID_MAJOR_S;
	int min_rev = (version & (METAC_ID_MINOR_BITS | METAC_ID_REV_BITS))
			>> METAC_ID_REV_S;

	/* Not a Meta 2 core, then not supported */
	if (0x02 > major) {
		pr_info("no hardware counter support available\n");
		goto out;
	} else if (0x02 == major) {
		metag_pmu = &_metag_pmu;

		if (min_rev < 0x0104) {
			/*
			 * A core without overflow interrupts, and clear-on-
			 * write counters.
			 */
			metag_pmu->handle_irq = NULL;
			metag_pmu->write = NULL;
			metag_pmu->max_period = 0;
		}

		metag_pmu->name = "meta2";
		metag_pmu->version = version;
		metag_pmu->pmu = pmu;
	}

	pr_info("enabled with %s PMU driver, %d counters available\n",
			metag_pmu->name, metag_pmu->max_events);

	/*
	 * Early cores have "limited" counters - they have no overflow
	 * interrupts - and so are unable to do sampling without extra work
	 * and timer assistance.
	 */
	if (metag_pmu->max_period == 0) {
		metag_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
	}

	/* Initialise the active events and reservation mutex */
	atomic_set(&metag_pmu->active_events, 0);
	mutex_init(&metag_pmu->reserve_mutex);

	/* Clear the counters */
	metag_out32(0, PERF_COUNT(0));
	metag_out32(0, PERF_COUNT(1));

	cpuhp_setup_state(CPUHP_AP_PERF_METAG_STARTING,
			  "perf/metag:starting", metag_pmu_starting_cpu,
			  NULL);

	ret = perf_pmu_register(&pmu, metag_pmu->name, PERF_TYPE_RAW);
	if (ret)
		cpuhp_remove_state_nocalls(CPUHP_AP_PERF_METAG_STARTING);
	return ret;
}
early_initcall(init_hw_perf_events);
