]> git.openfabrics.org - ~shefty/rdma-dev.git/blobdiff - arch/arm/mach-ebsa110/core.c
Merge branch 'platforms' of git://git.linaro.org/people/rmk/linux-arm
[~shefty/rdma-dev.git] / arch / arm / mach-ebsa110 / core.c
index 6235efb0ccd43d044747924eefb4f461299958cc..e400d75d11aee5eb0e575bf1268e99a79259387f 100644 (file)
@@ -268,8 +268,33 @@ static struct platform_device *ebsa110_devices[] = {
        &am79c961_device,
 };
 
        &am79c961_device,
 };
 
+/*
+ * EBSA110 idling methodology:
+ *
+ * We can not execute the "wait for interrupt" instruction since that
+ * will stop our MCLK signal (which provides the clock for the glue
+ * logic, and therefore the timer interrupt).
+ *
+ * Instead, we spin, polling the IRQ_STAT register for the occurrence
+ * of any interrupt with core clock down to the memory clock.
+ */
+static void ebsa110_idle(void)
+{
+       const char *irq_stat = (char *)0xff000000;
+
+       /* disable clock switching */
+       asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc");
+
+       /* wait for an interrupt to occur */
+       while (!*irq_stat);
+
+       /* enable clock switching */
+       asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc");
+}
+
 static int __init ebsa110_init(void)
 {
 static int __init ebsa110_init(void)
 {
+       arm_pm_idle = ebsa110_idle;
        return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices));
 }
 
        return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices));
 }