summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/cell/pmu.c
diff options
context:
space:
mode:
authorKevin Corry <kevcorry@us.ibm.com>2006-11-20 18:45:15 +0100
committerPaul Mackerras <paulus@samba.org>2006-12-04 20:40:12 +1100
commit0443bbd3d8496f9c2bc3e8c9d1833c6638722743 (patch)
tree7166aeb19de3d4cc538c7153843e009a5a33f32b /arch/powerpc/platforms/cell/pmu.c
parente4f6948cfc8b9626022db0f93e7cf2ce5c0998cd (diff)
[POWERPC] cell: Add routines for managing 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> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/pmu.c')
-rw-r--r--arch/powerpc/platforms/cell/pmu.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c
index ae6fd1c12d4e..f28abf2fc273 100644
--- a/arch/powerpc/platforms/cell/pmu.c
+++ b/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 *buf)
}
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);
+