Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a669efc4 authored by Andrew Bresticker's avatar Andrew Bresticker Committed by Ralf Baechle
Browse files

MIPS: Add hook to get C0 performance counter interrupt



The hardware perf event driver and oprofile interpret the global
cp0_perfcount_irq differently: in the hardware perf event driver
it is an offset from MIPS_CPU_IRQ_BASE and in oprofile it is the
actual IRQ number.  This still works most of the time since
MIPS_CPU_IRQ_BASE is usually 0, but is clearly wrong.  Since the
performance counter interrupt may vary from platform to platform
like the C0 timer interrupt, add the optional get_c0_perfcount_int
hook which returns the IRQ number of the performance counter.
The hook should return < 0 if the performance counter interrupt is
shared with the timer.  If the hook is not present, the CPU vector
reported in C0_IntCtl (cp0_perfcount_irq) is used.

Signed-off-by: default avatarAndrew Bresticker <abrestic@chromium.org>
Reviewed-by: default avatarQais Yousef <qais.yousef@imgtec.com>
Tested-by: default avatarQais Yousef <qais.yousef@imgtec.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Bresticker <abrestic@chromium.org>
Cc: Jeffrey Deans <jeffrey.deans@imgtec.com>
Cc: Markos Chandras <markos.chandras@imgtec.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Qais Yousef <qais.yousef@imgtec.com>
Cc: Jonas Gorski <jogo@openwrt.org>
Cc: John Crispin <blogic@openwrt.org>
Cc: David Daney <ddaney.cavm@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/7805/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 079a4601
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -359,7 +359,6 @@ void __init arch_init_irq(void)
		BUG();
	}

	cp0_perfcount_irq = ATH79_MISC_IRQ(5);
	mips_cpu_irq_init();
	ath79_misc_irq_init();

+5 −0
Original line number Diff line number Diff line
@@ -182,6 +182,11 @@ const char *get_system_type(void)
	return ath79_sys_type;
}

int get_c0_perfcount_int(void)
{
	return ATH79_MISC_IRQ(5);
}

unsigned int get_c0_compare_int(void)
{
	return CP0_LEGACY_COMPARE_IRQ;
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ extern unsigned int mips_hpt_frequency;
 * so it lives here.
 */
extern int (*perf_irq)(void);
extern int __weak get_c0_perfcount_int(void);

/*
 * Initialize the calling CPU's compare interrupt as clockevent device
+7 −16
Original line number Diff line number Diff line
@@ -1613,22 +1613,13 @@ init_hw_perf_events(void)
		counters = counters_total_to_per_cpu(counters);
#endif

#ifdef MSC01E_INT_BASE
	if (cpu_has_veic) {
		/*
		 * Using platform specific interrupt controller defines.
		 */
		irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
	} else {
#endif
		if ((cp0_perfcount_irq >= 0) &&
	if (get_c0_perfcount_int)
		irq = get_c0_perfcount_int();
	else if ((cp0_perfcount_irq >= 0) &&
		 (cp0_compare_irq != cp0_perfcount_irq))
		irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
	else
		irq = -1;
#ifdef MSC01E_INT_BASE
	}
#endif

	mipspmu.map_raw_event = mipsxx_pmu_map_raw_event;

+7 −1
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ static struct resource ltq_eiu_irq[MAX_EIU];
static void __iomem *ltq_icu_membase[MAX_IM];
static void __iomem *ltq_eiu_membase;
static struct irq_domain *ltq_domain;
static int ltq_perfcount_irq;

int ltq_eiu_get_irq(int exin)
{
@@ -449,7 +450,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
#endif

	/* tell oprofile which irq to use */
	cp0_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ);
	ltq_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ);

	/*
	 * if the timer irq is not one of the mips irqs we need to
@@ -461,6 +462,11 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
	return 0;
}

int get_c0_perfcount_int(void)
{
	return ltq_perfcount_irq;
}

unsigned int get_c0_compare_int(void)
{
	return MIPS_CPU_TIMER_IRQ;
Loading