From a669efc4a3b49de9226b280bb683f5b1d5a5d143 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:12 -0700 Subject: 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: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jason Cooper Cc: Andrew Bresticker Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Qais Yousef Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7805/ Signed-off-by: Ralf Baechle --- arch/mips/ralink/irq.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch/mips/ralink/irq.c') diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c index 0495011a19df..7634dcd88766 100644 --- a/arch/mips/ralink/irq.c +++ b/arch/mips/ralink/irq.c @@ -45,6 +45,7 @@ #define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9) static void __iomem *rt_intc_membase; +static int rt_perfcount_irq; static inline void rt_intc_w32(u32 val, unsigned reg) { @@ -73,6 +74,11 @@ static struct irq_chip ralink_intc_irq_chip = { .irq_mask_ack = ralink_intc_irq_mask, }; +int get_c0_perfcount_int(void) +{ + return rt_perfcount_irq; +} + unsigned int get_c0_compare_int(void) { return CP0_LEGACY_COMPARE_IRQ; @@ -167,7 +173,7 @@ static int __init intc_of_init(struct device_node *node, irq_set_handler_data(irq, domain); /* tell the kernel which irq is used for performance monitoring */ - cp0_perfcount_irq = irq_create_mapping(domain, 9); + rt_perfcount_irq = irq_create_mapping(domain, 9); return 0; } -- cgit