Based on reading the A20 user manual, it looks like the same
single PLE/PERFMU IRQ is supposed to be used for the CPU
performance counters as on Allwinner A10. This is already suspicious,
because normally each CPU core in a dual-core system should have
its own performance monitoring unit IRQ as explained in:
    http://thread.gmane.org/gmane.linux.ports.arm.kernel/181392/focus=181597
Still assuming that this is the case and borrowing the code
from db8500 does not work. No interrupts are arriving at all.

Is there anything special needed to make sure that the performance
monitoring unit interrupts are routed correctly on Allwinner A20?

Now that Cortex-A7 and GIC are both ARM IP, one might assume that
they perhaps should be able to play nicely together without
involving anything that is Allwinner specific.

Any ideas? The perf/oprofile tools are very useful for identifying
performance bottlenecks and optimizing software. They work nicely
on Allwinner A10. It would be great if Allwinner A20 could be
supported too.
---
 arch/arm/plat-sunxi/devices.c | 36 ++++++++++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/arch/arm/plat-sunxi/devices.c b/arch/arm/plat-sunxi/devices.c
index fdddc56..f5ecff7 100644
--- a/arch/arm/plat-sunxi/devices.c
+++ b/arch/arm/plat-sunxi/devices.c
@@ -113,7 +113,35 @@ struct platform_device sw_pdev_nand =
        .dev = {}
 };
 
-#ifndef CONFIG_ARCH_SUN7I
+#ifdef CONFIG_ARCH_SUN7I
+/*
+ * The PMU IRQ lines of two cores are wired together into a single interrupt.
+ * Bounce the interrupt to the other core if it's not ours.
+ *
+ * This code is borrowed from db8500_pmu_handler as advised by:
+ * http://thread.gmane.org/gmane.linux.ports.arm.kernel/181392/focus=181597
+ */
+static irqreturn_t sun7i_pmu_handler(int irq, void *dev, irq_handler_t handler)
+{
+       irqreturn_t ret = handler(irq, dev);
+       int other = !smp_processor_id();
+
+       if (ret == IRQ_NONE && cpu_online(other))
+               irq_set_affinity(irq, cpumask_of(other));
+
+       /*
+        * We should be able to get away with the amount of IRQ_NONEs we give,
+        * while still having the spurious IRQ detection code kick in if the
+        * interrupt really starts hitting spuriously.
+        */
+       return ret;
+}
+
+static struct arm_pmu_platdata sun7i_pmu_platdata = {
+       .handle_irq     = sun7i_pmu_handler,
+};
+#endif
+
 static struct resource sunxi_pmu_resources[] = {
        {
                .start  = SW_INT_IRQNO_PLE_PFM,
@@ -127,8 +155,10 @@ struct platform_device sunxi_pmu_device = {
        .id             = ARM_PMU_DEVICE_CPU,
        .resource       = sunxi_pmu_resources,
        .num_resources  = ARRAY_SIZE(sunxi_pmu_resources),
-};
+#ifdef CONFIG_ARCH_SUN7I
+       .dev.platform_data = &sun7i_pmu_platdata,
 #endif
+};
 
 #if defined(CONFIG_MALI_DRM) || defined(CONFIG_MALI_DRM_MODULE)
 static struct platform_device sunxi_device_mali_drm = {
@@ -143,9 +173,7 @@ static struct platform_device *sw_pdevs[] __initdata = {
 #endif
        &sw_pdev_dmac,
        &sw_pdev_nand,
-#ifndef CONFIG_ARCH_SUN7I
        &sunxi_pmu_device,
-#endif
 #if defined(CONFIG_MALI_DRM) || defined(CONFIG_MALI_DRM_MODULE)
        &sunxi_device_mali_drm,
 #endif
-- 
1.8.3.2

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to