All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Oprofile-for-Cell prereqs: New routines for managing PMU interrupts
@ 2006-11-15 15:56 Kevin Corry
  0 siblings, 0 replies; only message in thread
From: Kevin Corry @ 2006-11-15 15:56 UTC (permalink / raw)
  To: cbe-oss-dev, linuxppc-dev, oprofile-list, linux-kernel

Add routines for managing the Cell PMU interrupts.

The following routines are added to arch/powerpc/platforms/cell/pmu.c:
 cbe_clear_pm_interrupts()
 cbe_enable_pm_interrupts()
 cbe_disable_pm_interrupts()
 cbe_query_pm_interrupts()
 cbe_pm_irq()
 cbe_init_pm_irq()

This also adds a routine in arch/powerpc/platforms/cell/interrupt.c and
some macros in cbe_regs.h to manipulate the IIC_IR register:
 iic_set_interrupt_routing()

Signed-off-by: Kevin Corry <kevcorry@us.ibm.com>
Signed-off-by: Carl Love <carll@us.ibm.com>

Index: linux-2.6.18-arnd6/arch/powerpc/platforms/cell/pmu.c
===================================================================
--- linux-2.6.18-arnd6.orig/arch/powerpc/platforms/cell/pmu.c
+++ linux-2.6.18-arnd6/arch/powerpc/platforms/cell/pmu.c
@@ -22,9 +22,11 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/interrupt.h>
 #include <linux/types.h>
 #include <asm/io.h>
 #include <asm/machdep.h>
+#include <asm/pmc.h>
 #include <asm/reg.h>
 #include <asm/spu.h>
 
@@ -338,3 +340,71 @@ void cbe_read_trace_buffer(u32 cpu, u64 
 }
 EXPORT_SYMBOL_GPL(cbe_read_trace_buffer);
 
+/*
+ * Enabling/disabling interrupts for the entire performance monitoring unit.
+ */
+
+u32 cbe_query_pm_interrupts(u32 cpu)
+{
+	return cbe_read_pm(cpu, pm_status);
+}
+EXPORT_SYMBOL_GPL(cbe_query_pm_interrupts);
+
+u32 cbe_clear_pm_interrupts(u32 cpu)
+{
+	/* Reading pm_status clears the interrupt bits. */
+	return cbe_query_pm_interrupts(cpu);
+}
+EXPORT_SYMBOL_GPL(cbe_clear_pm_interrupts);
+
+void cbe_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask)
+{
+	/* Set which node and thread will handle the next interrupt. */
+	iic_set_interrupt_routing(cpu, thread, 0);
+
+	/* Enable the interrupt bits in the pm_status register. */
+	if (mask)
+		cbe_write_pm(cpu, pm_status, mask);
+}
+EXPORT_SYMBOL_GPL(cbe_enable_pm_interrupts);
+
+void cbe_disable_pm_interrupts(u32 cpu)
+{
+	cbe_clear_pm_interrupts(cpu);
+	cbe_write_pm(cpu, pm_status, 0);
+}
+EXPORT_SYMBOL_GPL(cbe_disable_pm_interrupts);
+
+static irqreturn_t cbe_pm_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	perf_irq(regs);
+	return IRQ_HANDLED;
+}
+
+int __init cbe_init_pm_irq(void)
+{
+	unsigned int irq;
+	int rc, node;
+
+	for_each_node(node) {
+		irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI |
+					       (node << IIC_IRQ_NODE_SHIFT));
+		if (irq == NO_IRQ) {
+			printk("ERROR: Unable to allocate irq for node %d\n",
+			       node);
+			return -EINVAL;
+		}
+
+		rc = request_irq(irq, cbe_pm_irq,
+				 IRQF_DISABLED, "cbe-pmu-0", NULL);
+		if (rc) {
+			printk("ERROR: Request for irq on node %d failed\n",
+			       node);
+			return rc;
+		}
+	}
+
+	return 0;
+}
+arch_initcall(cbe_init_pm_irq);
+
Index: linux-2.6.18-arnd6/arch/powerpc/platforms/cell/interrupt.c
===================================================================
--- linux-2.6.18-arnd6.orig/arch/powerpc/platforms/cell/interrupt.c
+++ linux-2.6.18-arnd6/arch/powerpc/platforms/cell/interrupt.c
@@ -397,3 +397,19 @@ void __init iic_init_IRQ(void)
 	/* Enable on current CPU */
 	iic_setup_cpu();
 }
+
+void iic_set_interrupt_routing(int cpu, int thread, int priority)
+{
+	struct cbe_iic_regs __iomem *iic_regs = cbe_get_cpu_iic_regs(cpu);
+	u64 iic_ir = 0;
+	int node = cpu >> 1;
+
+	/* Set which node and thread will handle the next interrupt */
+	iic_ir |= CBE_IIC_IR_PRIO(priority) |
+		  CBE_IIC_IR_DEST_NODE(node);
+	if (thread == 0)
+		iic_ir |= CBE_IIC_IR_DEST_UNIT(CBE_IIC_IR_PT_0);
+	else
+		iic_ir |= CBE_IIC_IR_DEST_UNIT(CBE_IIC_IR_PT_1);
+	out_be64(&iic_regs->iic_ir, iic_ir);
+}
Index: linux-2.6.18-arnd6/arch/powerpc/platforms/cell/interrupt.h
===================================================================
--- linux-2.6.18-arnd6.orig/arch/powerpc/platforms/cell/interrupt.h
+++ linux-2.6.18-arnd6/arch/powerpc/platforms/cell/interrupt.h
@@ -83,5 +83,7 @@ extern u8 iic_get_target_id(int cpu);
 
 extern void spider_init_IRQ(void);
 
+extern void iic_set_interrupt_routing(int cpu, int thread, int priority);
+
 #endif
 #endif /* ASM_CELL_PIC_H */
Index: linux-2.6.18-arnd6/include/asm-powerpc/cell-pmu.h
===================================================================
--- linux-2.6.18-arnd6.orig/include/asm-powerpc/cell-pmu.h
+++ linux-2.6.18-arnd6/include/asm-powerpc/cell-pmu.h
@@ -87,4 +87,9 @@ extern void cbe_disable_pm(u32 cpu);
 
 extern void cbe_read_trace_buffer(u32 cpu, u64 *buf);
 
+extern void cbe_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask);
+extern void cbe_disable_pm_interrupts(u32 cpu);
+extern u32  cbe_query_pm_interrupts(u32 cpu);
+extern u32  cbe_clear_pm_interrupts(u32 cpu);
+
 #endif /* __ASM_CELL_PMU_H__ */
Index: linux-2.6.18-arnd6/arch/powerpc/platforms/cell/cbe_regs.h
===================================================================
--- linux-2.6.18-arnd6.orig/arch/powerpc/platforms/cell/cbe_regs.h
+++ linux-2.6.18-arnd6/arch/powerpc/platforms/cell/cbe_regs.h
@@ -185,6 +185,14 @@ struct cbe_iic_regs {
 	struct	cbe_iic_thread_regs thread[2];			/* 0x0400 */
 
 	u64	iic_ir;						/* 0x0440 */
+#define CBE_IIC_IR_PRIO(x)      (((x) & 0xf) << 12)
+#define CBE_IIC_IR_DEST_NODE(x) (((x) & 0xf) << 4)
+#define CBE_IIC_IR_DEST_UNIT(x) ((x) & 0xf)
+#define CBE_IIC_IR_IOC_0        0x0
+#define CBE_IIC_IR_IOC_1S       0xb
+#define CBE_IIC_IR_PT_0         0xe
+#define CBE_IIC_IR_PT_1         0xf
+
 	u64	iic_is;						/* 0x0448 */
 #define CBE_IIC_IS_PMI		0x2
 

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2006-11-15 15:56 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-15 15:56 [PATCH] Oprofile-for-Cell prereqs: New routines for managing PMU interrupts Kevin Corry

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.