From: Charlie Paul <cpaul.windri...@gmail.com>

These files add power management capabilities to the LSI Axxia 5500
platform.

Signed-off-by: Charlie Paul <cpaul.windri...@gmail.com>
---
 arch/arm/mach-axxia/hotplug.c              |  282 ++++++
 arch/arm/mach-axxia/lsi_power_management.c | 1400 ++++++++++++++++++++++++++++
 arch/arm/mach-axxia/lsi_power_management.h |  192 ++++
 arch/arm/mach-axxia/perf_event_memc.c      |  152 +++
 arch/arm/mach-axxia/perf_event_memc.h      |   67 ++
 arch/arm/mach-axxia/perf_event_pcx.c       |   52 ++
 arch/arm/mach-axxia/perf_event_platform.c  |  275 ++++++
 arch/arm/mach-axxia/perf_event_platform.h  |   10 +
 arch/arm/mach-axxia/perf_event_vp.c        |   53 ++
 arch/arm/mach-axxia/rapidio.c              |  112 +++
 10 files changed, 2595 insertions(+)
 create mode 100644 arch/arm/mach-axxia/hotplug.c
 create mode 100644 arch/arm/mach-axxia/lsi_power_management.c
 create mode 100644 arch/arm/mach-axxia/lsi_power_management.h
 create mode 100644 arch/arm/mach-axxia/perf_event_memc.c
 create mode 100644 arch/arm/mach-axxia/perf_event_memc.h
 create mode 100644 arch/arm/mach-axxia/perf_event_pcx.c
 create mode 100644 arch/arm/mach-axxia/perf_event_platform.c
 create mode 100644 arch/arm/mach-axxia/perf_event_platform.h
 create mode 100644 arch/arm/mach-axxia/perf_event_vp.c
 create mode 100644 arch/arm/mach-axxia/rapidio.c

diff --git a/arch/arm/mach-axxia/hotplug.c b/arch/arm/mach-axxia/hotplug.c
new file mode 100644
index 0000000..998c56c
--- /dev/null
+++ b/arch/arm/mach-axxia/hotplug.c
@@ -0,0 +1,282 @@
+/*
+ *  linux/arch/arm/mach-realview/hotplug.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/of_address.h>
+#include <linux/delay.h>
+
+#include <mach/axxia-gic.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/cp15.h>
+#include "lsi_power_management.h"
+#include "axxia_circular_queue.h"
+extern struct circular_queue_t axxia_circ_q;
+
+extern volatile int pen_release;
+
+static inline void pm_cpu_logical_shutdown(u32 cpu)
+{
+       u32 val;
+
+       asm volatile(
+       "       mrc     p15, 1, %0, c9, c0, 2\n"
+       : "=&r" (val)
+       : "Ir" (0x1)
+       : "cc");
+
+       asm volatile(
+       "       mrc     p15, 0, %0, c1, c0, 0\n"
+       "       bic     %0, %0, %1\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+       : "=&r" (val)
+       : "Ir" (CR_C)
+       : "cc");
+
+       /* Clear and invalidate all date from L1 data cache */
+       flush_cache_all();
+
+       /* Switch the processor over to AMP mode out of SMP */
+       asm volatile(
+                       "       mrc     p15, 0, %0, c1, c0, 1\n"
+                       "       bic     %0, %0, %1\n"
+                       "       mcr     p15, 0, %0, c1, c0, 1\n"
+                       : "=&r" (val)
+                       : "Ir" (0x40)
+                       : "cc");
+
+       isb();
+       dsb();
+
+       wfi();
+
+}
+
+static inline void pm_L2_logical_shutdown(u32 cpu)
+{
+       u32 val;
+
+       asm volatile(
+       "       mrc     p15, 0, %0, c1, c0, 0\n"
+       "       bic     %0, %0, %1\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+       : "=&r" (val)
+       : "Ir" (CR_C)
+       : "cc");
+
+
+       asm volatile(
+                       /*
+                        * Disable L2 prefetch
+                        */
+                       "       mrc     p15, 1, %0, c15, c0, 3\n"
+                       "       orr     %0, %0, %1\n"
+                       "       mcr     p15, 1, %0, c15, c0, 3\n"
+                       : "=&r" (val)
+                       : "Ir" (0x400)
+                       : "cc");
+
+       asm volatile(
+       "       mrc             p15, 1, %0, c15, c0, 4\n"
+       "       orr     %0, %0, %1\n"
+       "       mcr             p15, 1, %0, c15, c0, 4\n"
+       : "=&r" (val)
+       : "Ir" (0x1)
+       : "cc");
+
+       isb();
+       dsb();
+
+       flush_cache_all();
+
+       /* Turn the DBG Double Lock quiet */
+       asm volatile(
+                       /*
+                        * Turn Off the DBGOSDLR.DLK bit
+                        */
+                       "       mrc     p14, 0, %0, c1, c3, 4\n"
+                       "       orr     %0, %0, %1\n"
+                       "       mcr     p14, 0, %0, c1, c3, 4\n"
+                       : "=&r" (val)
+                       : "Ir" (0x1)
+                       : "cc");
+
+       /* Switch the processor over to AMP mode out of SMP */
+       asm volatile(
+                       "       mrc     p15, 0, %0, c1, c0, 1\n"
+                       "       bic     %0, %0, %1\n"
+                       "       mcr     p15, 0, %0, c1, c0, 1\n"
+                       : "=&r" (val)
+                       : "Ir" (0x40)
+                       : "cc");
+
+       isb();
+       dsb();
+
+       wfi();
+}
+
+#ifdef CONFIG_HOTPLUG_CPU_LOW_POWER
+static inline void cpu_enter_lowpower_a15(void)
+{
+       unsigned int v;
+
+       asm volatile(
+                       "       mrc     p15, 0, %0, c1, c0, 0\n"
+                       "       bic     %0, %0, %1\n"
+                       "       mcr     p15, 0, %0, c1, c0, 0\n"
+                       : "=&r" (v)
+                       : "Ir" (CR_C)
+                       : "cc");
+
+       flush_cache_all();
+
+       asm volatile(
+                       /*
+                        * Turn off coherency
+                        */
+                       "       mrc     p15, 0, %0, c1, c0, 1\n"
+                       "       bic     %0, %0, %1\n"
+                       "       mcr     p15, 0, %0, c1, c0, 1\n"
+                       : "=&r" (v)
+                       : "Ir" (0x40)
+                       : "cc");
+
+       isb();
+       dsb();
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+       unsigned int v;
+
+       asm volatile(
+                       "mrc    p15, 0, %0, c1, c0, 0\n"
+                       "       orr     %0, %0, %1\n"
+                       "       mcr     p15, 0, %0, c1, c0, 0\n"
+                       "       mrc     p15, 0, %0, c1, c0, 1\n"
+                       "       orr     %0, %0, %2\n"
+                       "       mcr     p15, 0, %0, c1, c0, 1\n"
+                       : "=&r" (v)
+                       : "Ir" (CR_C), "Ir" (0x40)
+                       : "cc");
+       isb();
+       dsb();
+}
+
+static void __ref platform_do_lowpower(unsigned int cpu, int *spurious)
+{
+       int phys_cpu, cluster;
+
+       /*
+        * there is no power-control hardware on this platform, so all
+        * we can do is put the core into WFI; this is safe as the calling
+        * code will have already disabled interrupts
+        */
+       for (;;) {
+               wfi();
+
+       /*
+       * Convert the "cpu" variable to be compatible with the
+       * ARM MPIDR register format (CLUSTERID and CPUID):
+       *
+       * Bits:   |11 10 9 8|7 6 5 4 3 2|1 0
+       *         | CLUSTER | Reserved  |CPU
+       */
+       phys_cpu = cpu_logical_map(cpu);
+       cluster = (phys_cpu / 4) << 8;
+       phys_cpu = cluster + (phys_cpu % 4);
+
+       if (pen_release == phys_cpu) {
+               /*
+                * OK, proper wakeup, we're done
+                */
+               break;
+       }
+
+       /*
+        * Getting here, means that we have come out of WFI without
+        * having been woken up - this shouldn't happen
+        *
+        * Just note it happening - when we're woken, we can report
+        * its occurrence.
+        */
+       (*spurious)++;
+       }
+}
+#endif
+
+int axxia_platform_cpu_kill(unsigned int cpu)
+{
+
+#ifdef CONFIG_HOTPLUG_CPU_COMPLETE_POWER_DOWN
+       get_cpu();
+       pm_cpu_shutdown(cpu);
+       put_cpu();
+#endif
+       return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+
+void axxia_platform_cpu_die(unsigned int cpu)
+{
+#ifdef CONFIG_HOTPLUG_CPU_COMPLETE_POWER_DOWN
+       bool last_cpu;
+
+       last_cpu = pm_cpu_last_of_cluster(cpu);
+       if (last_cpu)
+               pm_L2_logical_shutdown(cpu);
+       else
+               pm_cpu_logical_shutdown(cpu);
+
+       for (;;)
+               wfi();
+
+#else /* CPU low power mode */
+
+       int spurious = 0;
+
+       /*
+        * we're ready for shutdown now, so do it
+        */
+       cpu_enter_lowpower_a15();
+       pm_in_progress[cpu] = true;
+
+       platform_do_lowpower(cpu, &spurious);
+
+       /*
+        * bring this CPU back into the world of cache
+        * coherency, and then restore interrupts
+        */
+       cpu_leave_lowpower();
+
+       if (spurious)
+               pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+#endif
+
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+
+       /*
+        * we don't allow CPU 0 to be shutdown (it is still too special
+        * e.g. clock tick interrupts)
+        */
+
+       return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-axxia/lsi_power_management.c 
b/arch/arm/mach-axxia/lsi_power_management.c
new file mode 100644
index 0000000..f3ad4f8
--- /dev/null
+++ b/arch/arm/mach-axxia/lsi_power_management.c
@@ -0,0 +1,1400 @@
+/*
+ *  linux/arch/arm/mach-axxia/lsi_power_management.c
+ *
+ *  C *  Created on: Jun 19, 2014
+ *      Author: z8cpaul
+ *  opyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Created on: Jun 19, 2014
+ *      Author: z8cpaul
+ */
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/delay.h>
+#include <linux/of_address.h>
+#include <asm/exception.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/cp15.h>
+
+#include "axxia.h"
+#include <mach/axxia-gic.h>
+#include "lsi_power_management.h"
+
+#undef DEBUG_CPU_PM
+
+#define SYSCON_PHYS_ADDR 0x002010030000ULL
+#define DICKENS_PHYS_ADDR 0x2000000000
+
+#define PM_WAIT_TIME (10000)
+#define MAX_CLUSTER  (4)
+#define IPI_IRQ_MASK (0xFFFF)
+
+#define CHECK_BIT(var, pos) ((var) & (1 << (pos)))
+
+bool pm_in_progress[16];
+bool cluster_power_up[4];
+
+static const u32 cluster_to_node[MAX_CLUSTER] = { DKN_CLUSTER0_NODE,
+DKN_CLUSTER1_NODE,
+DKN_CLUSTER2_NODE,
+DKN_CLUSTER3_NODE };
+
+static const u32 cluster_to_poreset[MAX_CLUSTER] = {
+PORESET_CLUSTER0,
+PORESET_CLUSTER1,
+PORESET_CLUSTER2,
+PORESET_CLUSTER3 };
+
+static const u32 cluster_to_mask[MAX_CLUSTER] = {
+               IPI0_MASK,
+               IPI1_MASK,
+               IPI2_MASK,
+               IPI3_MASK
+};
+
+static const u32 ipi_register[MAX_IPI] = {
+               NCP_SYSCON_MASK_IPI0,
+               NCP_SYSCON_MASK_IPI1,
+               NCP_SYSCON_MASK_IPI2,
+               NCP_SYSCON_MASK_IPI3,
+               NCP_SYSCON_MASK_IPI4,
+               NCP_SYSCON_MASK_IPI5,
+               NCP_SYSCON_MASK_IPI6,
+               NCP_SYSCON_MASK_IPI7,
+               NCP_SYSCON_MASK_IPI8,
+               NCP_SYSCON_MASK_IPI9,
+               NCP_SYSCON_MASK_IPI10,
+               NCP_SYSCON_MASK_IPI11,
+               NCP_SYSCON_MASK_IPI12,
+               NCP_SYSCON_MASK_IPI13,
+               NCP_SYSCON_MASK_IPI14,
+               NCP_SYSCON_MASK_IPI15,
+               NCP_SYSCON_MASK_IPI16,
+               NCP_SYSCON_MASK_IPI17,
+               NCP_SYSCON_MASK_IPI18
+};
+
+enum pm_error_code {
+       PM_ERR_DICKENS_IOREMAP = 200,
+       PM_ERR_DICKENS_SNOOP_DOMAIN,
+       PM_ERR_FAILED_PWR_DWN_RAM,
+       PM_ERR_FAILED_STAGE_1,
+       PM_ERR_ACK1_FAIL,
+       PM_ERR_RAM_ACK_FAIL,
+       PM_ERR_FAIL_L2ACK,
+       PM_ERR_FAIL_L2HSRAM
+};
+static void __iomem *syscon;
+
+u32 pm_cpu_powered_down;
+
+
+/*======================= LOCAL FUNCTIONS ==============================*/
+static void pm_set_bits_syscon_register(u32 reg, u32 data);
+static void pm_or_bits_syscon_register(u32 reg, u32 data);
+static void pm_clear_bits_syscon_register(u32 reg, u32 data);
+static bool pm_test_for_bit_with_timeout(u32 reg, u32 bit);
+static bool pm_wait_for_bit_clear_with_timeout(u32 reg,
+               u32 bit);
+static void pm_dickens_logical_shutdown(u32 cluster);
+static int pm_dickens_logical_powerup(u32 cluster);
+static int pm_cpu_physical_isolation_and_power_down(int cpu);
+static void pm_L2_isolation_and_power_down(int cluster);
+static int pm_cpu_physical_connection_and_power_up(int cpu);
+static int pm_L2_physical_connection_and_power_up(u32 cluster);
+static int pm_L2_logical_powerup(u32 cluster, u32 cpu);
+
+static bool pm_first_cpu_of_cluster(u32 cpu)
+{
+#ifdef CONFIG_HOTPLUG_CPU_L2_POWER_DOWN
+       u32 count = 0;
+
+       switch (cpu) {
+       case (0):
+       case (1):
+       case (2):
+       case (3):
+               /* This will never happen because cpu 0 will never be turned 
off */
+               break;
+       case (4):
+       case (5):
+       case (6):
+       case (7):
+               if (pm_cpu_powered_down & (1 << 4))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 5))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 6))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 7))
+                       count++;
+               if (count == 4)
+                       return true;
+               break;
+       case (8):
+       case (9):
+       case (10):
+       case (11):
+               if (pm_cpu_powered_down & (1 << 8))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 9))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 10))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 11))
+                       count++;
+               if (count == 4)
+                       return true;
+               break;
+       case (12):
+       case (13):
+       case (14):
+       case (15):
+               if (pm_cpu_powered_down & (1 << 12))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 13))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 14))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 15))
+                       count++;
+               if (count == 4)
+                       return true;
+               break;
+       default:
+               pr_err("ERROR: the cpu does not exist: %d - %s:%d\n", cpu, 
__FILE__,
+                               __LINE__);
+               break;
+       }
+#endif
+       return false;
+}
+
+bool pm_cpu_last_of_cluster(u32 cpu)
+{
+#ifdef CONFIG_HOTPLUG_CPU_L2_POWER_DOWN
+
+       u32 count = 0;
+
+       switch (cpu) {
+       case (0):
+       case (1):
+       case (2):
+       case (3):
+               /* This will never happen because cpu 0 will never be turned 
off */
+               break;
+       case (4):
+       case (5):
+       case (6):
+       case (7):
+               if (pm_cpu_powered_down & (1 << 4))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 5))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 6))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 7))
+                       count++;
+               if (count == 3)
+                       return true;
+               break;
+       case (8):
+       case (9):
+       case (10):
+       case (11):
+               if (pm_cpu_powered_down & (1 << 8))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 9))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 10))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 11))
+                       count++;
+               if (count == 3)
+                       return true;
+               break;
+       case (12):
+       case (13):
+       case (14):
+       case (15):
+               if (pm_cpu_powered_down & (1 << 12))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 13))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 14))
+                       count++;
+               if (pm_cpu_powered_down & (1 << 15))
+                       count++;
+               if (count == 3)
+                       return true;
+               break;
+       default:
+               pr_err("ERROR: the cpu does not exist: %d - %s:%d\n", cpu,  
__FILE__,
+                               __LINE__);
+               break;
+       }
+#endif
+       return false;
+}
+
+static void pm_set_bits_syscon_register(u32 reg, u32 data)
+{
+       writel(data, syscon + reg);
+}
+
+static void pm_or_bits_syscon_register(u32 reg, u32 data)
+{
+       u32 tmp;
+
+       tmp = readl(syscon + reg);
+       tmp |= data;
+       writel(tmp, syscon + reg);
+}
+
+
+static void pm_clear_bits_syscon_register(u32 reg, u32 data)
+{
+       u32 tmp;
+
+       tmp = readl(syscon + reg);
+       tmp &= ~(data);
+       writel(tmp, syscon + reg);
+}
+
+static bool pm_test_for_bit_with_timeout(u32 reg, u32 bit)
+{
+
+       u32 tmp = 0;
+       u32 cnt = 0;
+
+       while (cnt < PM_WAIT_TIME) {
+               tmp = readl(syscon + reg);
+               if (CHECK_BIT(tmp, bit))
+                       break;
+               cnt++;
+       }
+       if (cnt == PM_WAIT_TIME) {
+               pr_err("reg=0x%x tmp:=0x%x\n", reg, tmp);
+               return false;
+       }
+       return true;
+}
+
+static bool pm_wait_for_bit_clear_with_timeout(u32 reg, u32 bit)
+{
+       u32 cnt = 0;
+       u32 tmp = 0;
+
+       while (cnt < PM_WAIT_TIME) {
+               tmp = readl(syscon + reg);
+               if (!(CHECK_BIT(tmp, bit)))
+                       break;
+               cnt++;
+       }
+       if (cnt == PM_WAIT_TIME) {
+               pr_err("reg=0x%x tmp:=0x%x\n", reg, tmp);
+               return false;
+       }
+
+       return true;
+}
+static void pm_dickens_logical_shutdown(u32 cluster)
+{
+       int i;
+       int status;
+       u32 bit;
+       u32 bit_pos;
+       int retries;
+       void __iomem *dickens;
+
+       dickens = ioremap(DICKENS_PHYS_ADDR, SZ_4M);
+       if (dickens == NULL) {
+               pr_err("DICKENS: Failed to map the dickens registers\n");
+               return;
+       }
+
+       bit = (0x01 << cluster_to_node[cluster]);
+       bit_pos = cluster_to_node[cluster];
+
+       for (i = 0; i < DKN_HNF_TOTAL_NODES; ++i) {
+               writel(bit,
+                               dickens + (0x10000 * (DKN_HNF_NODE_ID + i))
+                                               + DKN_HNF_SNOOP_DOMAIN_CTL_CLR);
+
+               retries = PM_WAIT_TIME;
+
+               do {
+                       status = readl(
+                                       dickens + (0x10000 * (DKN_HNF_NODE_ID + 
i))
+                                                       + 
DKN_HNF_SNOOP_DOMAIN_CTL);
+                       udelay(1);
+               } while ((0 < --retries) && CHECK_BIT(status, bit_pos));
+
+               if (0 == retries) {
+                       pr_err("DICKENS: Failed to clear the SNOOP main 
control. LOOP:%d reg: 0x%x\n", i, status);
+                       goto dickens_power_down;
+
+               }
+
+       }
+       /* Clear the domain cluster */
+       writel(bit, dickens + (0x10000 * DKN_DVM_DOMAIN_OFFSET) + 
DKN_MN_DVM_DOMAIN_CTL_CLR);
+
+       /* Check for complete */
+       retries = PM_WAIT_TIME;
+
+       do {
+               status = readl(
+                               dickens + (0x10000 * DKN_DVM_DOMAIN_OFFSET)
+                                               + DKN_MN_DVM_DOMAIN_CTL);
+               udelay(1);
+       } while ((0 < --retries) && CHECK_BIT(status, bit_pos));
+
+       if (0 == retries) {
+               pr_err("DICKENS: failed to set DOMAIN OFFSET Reg=0x%x\n", 
status);
+               goto dickens_power_down;
+
+       }
+
+dickens_power_down:
+       iounmap(dickens);
+}
+
+static int pm_dickens_logical_powerup(u32 cluster)
+{
+       int i;
+       u32 status;
+       u32 bit;
+       u32 bit_pos;
+       int retries;
+       int rval = 0;
+
+       void __iomem *dickens = ioremap(DICKENS_PHYS_ADDR, SZ_4M);
+
+       if (dickens == NULL) {
+               pr_err("Failed to map dickens registers\n");
+               return -PM_ERR_DICKENS_IOREMAP;
+       }
+
+       bit = (0x01 << cluster_to_node[cluster]);
+       bit_pos = cluster_to_node[cluster];
+
+       for (i = 0; i < DKN_HNF_TOTAL_NODES; ++i) {
+               writel(bit,
+                               dickens + (0x10000 * (DKN_HNF_NODE_ID + i))
+                                               + DKN_HNF_SNOOP_DOMAIN_CTL_SET);
+
+               retries = PM_WAIT_TIME;
+
+               do {
+                       status = readl(
+                                       dickens + (0x10000 * (DKN_HNF_NODE_ID + 
i))
+                                                       + 
DKN_HNF_SNOOP_DOMAIN_CTL);
+                       udelay(1);
+               } while ((0 < --retries) && !CHECK_BIT(status, bit_pos));
+
+               if (0 == retries) {
+                       pr_err("DICKENS: Failed on the SNOOP DONAIN\n");
+                       rval = -PM_ERR_DICKENS_SNOOP_DOMAIN;
+                       goto dickens_power_up;
+               }
+
+       }
+
+       /* Clear the domain cluster */
+       writel(bit, dickens + (0x10000 * DKN_DVM_DOMAIN_OFFSET) + 
DKN_MN_DVM_DOMAIN_CTL_SET);
+
+       /* Check for complete */
+       retries = PM_WAIT_TIME;
+
+       do {
+               status = readl(
+                               dickens + (0x10000 * DKN_DVM_DOMAIN_OFFSET)
+                                               + DKN_MN_DVM_DOMAIN_CTL);
+               udelay(1);
+       } while ((0 < --retries) && !CHECK_BIT(status, bit_pos));
+
+       if (0 == retries) {
+               pr_err("DICKENS: Failed on the SNOOP DONAIN CTL SET\n");
+               rval = -PM_ERR_DICKENS_SNOOP_DOMAIN;
+               goto dickens_power_up;
+       }
+
+dickens_power_up:
+       iounmap(dickens);
+
+       return rval;
+}
+
+static void pm_disable_ipi_interrupts(u32 cpu)
+{
+       pm_clear_bits_syscon_register(ipi_register[cpu], IPI_IRQ_MASK);
+}
+
+static void pm_enable_ipi_interrupts(u32 cpu)
+{
+
+       u32 i;
+       u32 powered_on_cpu = (~(pm_cpu_powered_down) & IPI_IRQ_MASK);
+
+       pm_set_bits_syscon_register(ipi_register[cpu], powered_on_cpu);
+
+       for (i = 0; i < MAX_CPUS; i++) {
+               if ((1 << i) & powered_on_cpu)
+                       pm_or_bits_syscon_register(ipi_register[i], (1 << cpu));
+       }
+}
+
+void pm_init_syscon(void)
+{
+       syscon = ioremap(SYSCON_PHYS_ADDR, SZ_64K);
+}
+
+bool pm_cpu_active(u32 cpu)
+{
+
+       bool success = false;
+       u32 reg;
+
+       reg = readl(syscon + NCP_SYSCON_PWR_QACTIVE);
+       if (reg & (1 << cpu))
+               success = true;
+
+       return success;
+
+}
+
+void pm_cpu_shutdown(u32 cpu)
+{
+
+       bool success;
+       u32 reqcpu = cpu_logical_map(cpu);
+       u32 cluster = reqcpu / CORES_PER_CLUSTER;
+       u32 cluster_mask = (0x01 << cluster);
+       bool last_cpu;
+       int rval = 0;
+
+       /* Check to see if the cpu is powered up */
+       if (pm_cpu_powered_down & (1 << reqcpu)) {
+               pr_err("CPU %d is already powered off - %s:%d\n", cpu, 
__FILE__, __LINE__);
+               return;
+       }
+
+       pm_init_syscon();
+
+       /*
+        * Is this the last cpu of a cluster then turn off the L2 cache
+        * along with the CPU.
+        */
+       last_cpu = pm_cpu_last_of_cluster(reqcpu);
+       if (last_cpu) {
+
+               /* Disable all the interrupts to the cluster gic */
+               pm_or_bits_syscon_register(NCP_SYSCON_GIC_DISABLE, 
cluster_mask);
+
+               /* Remove the cluster from the Dickens coherency domain */
+               pm_dickens_logical_shutdown(cluster);
+
+               /* Power down the cpu */
+               pm_cpu_physical_isolation_and_power_down(reqcpu);
+
+               pm_clear_bits_syscon_register(NCP_SYSCON_PWR_CSYSREQ_CNT, 
cluster_mask);
+               success = 
pm_wait_for_bit_clear_with_timeout(NCP_SYSCON_PWR_CACTIVE_CNT, cluster);
+               if (!success) {
+                       pr_err(
+                                       "Failed to keep other cluster count 
going on cluster %d: %s-%d\n",
+                                       cluster, __FILE__, __LINE__);
+                       goto pm_shutdown_exit;
+               }
+
+               /* Turn off the ACE */
+               pm_or_bits_syscon_register(NCP_SYSCON_PWR_ACEPWRDNRQ, 
cluster_mask);
+
+               /* Wait for ACE to complete power off */
+               success = 
pm_wait_for_bit_clear_with_timeout(NCP_SYSCON_PWR_NACEPWRDNACK, cluster);
+               if (!success) {
+                       pr_err("Failed to power off ACE on cluster %d: %s-%d\n",
+                                       cluster, __FILE__, __LINE__);
+                       goto pm_shutdown_exit;
+               }
+
+               /* Isolate the cluster */
+               pm_or_bits_syscon_register(NCP_SYSCON_PWR_ISOLATEL2MISC, 
cluster_mask);
+
+               /* Wait for WFI L2 to go to standby */
+               success = 
pm_test_for_bit_with_timeout(NCP_SYSCON_PWR_STANDBYWFIL2, cluster);
+               if (!success) {
+                       pr_err("Failed to enter L2 WFI on cluster %d: %s-%d\n",
+                                       cluster, __FILE__, __LINE__);
+                       goto pm_shutdown_exit;
+               }
+
+               /* Power off the L2 */
+               pm_L2_isolation_and_power_down(cluster);
+               if (rval == 0) {
+                       pr_info("CPU %d is powered down with cluster: %d\n", 
reqcpu, cluster);
+                       pm_cpu_powered_down |= (1 << reqcpu);
+               } else
+                       pr_err("CPU %d failed to power down\n", reqcpu);
+
+
+       } else {
+
+               rval = pm_cpu_physical_isolation_and_power_down(reqcpu);
+               if (rval == 0)
+                       pm_cpu_powered_down |= (1 << reqcpu);
+               else
+                       pr_err("CPU %d failed to power down\n", reqcpu);
+       }
+
+pm_shutdown_exit:
+       iounmap(syscon);
+}
+
+int pm_cpu_powerup(u32 cpu)
+{
+
+       bool first_cpu;
+       int rval = 0;
+       u32 cpu_mask = (0x01 << cpu);
+
+       u32 reqcpu = cpu_logical_map(cpu);
+       u32 cluster = reqcpu / CORES_PER_CLUSTER;
+       u32 cluster_mask = (0x01 << cluster);
+
+       pm_init_syscon();
+
+       /*
+        * Is this the first cpu of a cluster to come back on?
+        * Then power up the L2 cache.
+        */
+       first_cpu = pm_first_cpu_of_cluster(cpu);
+       if (first_cpu) {
+
+               rval = pm_L2_logical_powerup(cluster, cpu);
+               if (rval) {
+                       pr_err("CPU: Failed the logical L2 power up\n");
+                       goto pm_power_up;
+               }
+               cluster_power_up[cluster] = true;
+               pm_clear_bits_syscon_register(NCP_SYSCON_GIC_DISABLE, 
cluster_mask);
+
+
+       } else {
+               /* Set the CPU into reset */
+               pm_set_bits_syscon_register(NCP_SYSCON_KEY, VALID_KEY_VALUE);
+               pm_or_bits_syscon_register(NCP_SYSCON_PWRUP_CPU_RST, cpu_mask);
+
+       }
+
+
+       /*
+        * Power up the CPU
+        */
+       rval = pm_cpu_physical_connection_and_power_up(cpu);
+       if (rval) {
+               pr_err("Failed to power up physical connection of cpu: %d\n", 
cpu);
+               goto pm_power_up;
+       }
+
+       /*
+        * The key value must be written before the CPU RST can be written.
+        */
+       pm_set_bits_syscon_register(NCP_SYSCON_KEY, VALID_KEY_VALUE);
+       pm_clear_bits_syscon_register(NCP_SYSCON_PWRUP_CPU_RST, cpu_mask);
+
+       /*
+        * Clear the powered down mask
+        */
+       pm_cpu_powered_down &= ~(1 << cpu);
+
+       /* Enable the CPU IPI */
+       pm_enable_ipi_interrupts(cpu);
+
+
+
+pm_power_up:
+       iounmap(syscon);
+       return rval;
+}
+
+unsigned long pm_get_powered_down_cpu(void)
+{
+       return pm_cpu_powered_down;
+}
+
+
+inline void pm_cpu_logical_powerup(void)
+{
+       unsigned int v;
+
+       asm volatile(
+       "       mrc     p15, 0, %0, c1, c0, 0\n"
+       "       orr     %0, %0, %1\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+       "       mrc     p15, 0, %0, c1, c0, 0\n"
+       "       orr     %0, %0, %2\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+         : "=&r" (v)
+         : "Ir" (CR_C), "Ir" (CR_I)
+         : "cc");
+
+       /*
+        *  Iniitalize the ACTLR2 register (all cores).
+        */
+
+       asm volatile(
+       "       mrc             p15, 1, %0, c15, c0, 4\n"
+       "       bic     %0, %0, %1\n"
+       "       mcr             p15, 1, %0, c15, c0, 4\n"
+       : "=&r" (v)
+       : "Ir" (0x1)
+       : "cc");
+
+       isb();
+       dsb();
+}
+
+inline void pm_cluster_logical_powerup(void)
+{
+       unsigned int v;
+
+       /*
+        * Initialize the L2CTLR register (primary core in each cluster).
+        */
+       asm volatile(
+       "       mrc     p15, 1, %0, c9, c0, 2\n"
+       "       orr     %0, %0, %1\n"
+       "       orr     %0, %0, %2\n"
+       "       mcr     p15, 1, %0, c9, c0, 2"
+         : "=&r" (v)
+         : "Ir" (0x01), "Ir" (0x1 << 21)
+         : "cc");
+       isb();
+       dsb();
+
+       /*
+        * Initialize the L2ACTLR register (primary core in each cluster).
+        */
+       asm volatile(
+       "       mrc     p15, 1, r0, c15, c0, 0\n"
+       "       orr     %0, %0, %1\n"
+       "       orr     %0, %0, %2\n"
+       "       orr     %0, %0, %3\n"
+       "       orr     %0, %0, %4\n"
+       "       orr     %0, %0, %5\n"
+       "       mcr     p15, 1, %0, c15, c0, 0"
+         : "=&r" (v)
+         : "Ir" (0x1 << 3), "Ir" (0x1 << 7), "Ir" (0x1 << 12), "Ir" (0x1 << 
13), "Ir" (0x1 << 14)
+         : "cc");
+       isb();
+       dsb();
+
+}
+
+static int pm_cpu_physical_isolation_and_power_down(int cpu)
+{
+
+       int rval = 0;
+
+       bool success;
+       u32 mask = (0x01 << cpu);
+
+       /* Disable the CPU IPI */
+       pm_disable_ipi_interrupts(cpu);
+
+       /* Initiate power down of the CPU's HS Rams */
+       pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPCPURAM, mask);
+
+       /* Wait until the RAM power down is complete */
+       success = pm_test_for_bit_with_timeout(NCP_SYSCON_PWR_NPWRUPCPURAM_ACK, 
cpu);
+       if (!success) {
+               rval = -PM_ERR_FAILED_PWR_DWN_RAM;
+               pr_err("CPU: Failed to power down CPU RAM\n");
+               goto power_down_cleanup;
+       }
+
+       /* Activate the CPU's isolation clamps */
+       pm_or_bits_syscon_register(NCP_SYSCON_PWR_ISOLATECPU, mask);
+
+       /* Initiate power down of the CPU logic */
+       pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPCPUSTG2, mask);
+
+       udelay(16);
+
+       /* Continue power down of the CPU logic */
+       pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPCPUSTG1, mask);
+
+       success = 
pm_test_for_bit_with_timeout(NCP_SYSCON_PWR_NPWRUPCPUSTG1_ACK, cpu);
+       if (!success) {
+               rval = -PM_ERR_FAILED_STAGE_1;
+               pr_err("CPU: Failed to power down stage 1 cpu\n");
+               goto power_down_cleanup;
+       }
+
+power_down_cleanup:
+
+       return rval;
+}
+
+static int pm_cpu_physical_connection_and_power_up(int cpu)
+{
+       int rval = 0;
+
+       bool success;
+       u32 mask = (0x01 << cpu);
+
+       /* Initiate power up of the CPU */
+       pm_or_bits_syscon_register(NCP_SYSCON_PWR_PWRUPCPUSTG1, mask);
+
+       /* Wait until CPU logic power is compete */
+       success = 
pm_wait_for_bit_clear_with_timeout(NCP_SYSCON_PWR_NPWRUPCPUSTG1_ACK, cpu);
+       if (!success) {
+               rval = -PM_ERR_ACK1_FAIL;
+               pr_err("CPU: Failed to get ACK from power down stage 1\n");
+               goto power_up_cleanup;
+       }
+
+       /* Continue stage 2 power up of the CPU*/
+       pm_or_bits_syscon_register(NCP_SYSCON_PWR_PWRUPCPUSTG2, mask);
+
+       udelay(16);
+
+       /* Initiate power up of HS Rams */
+       pm_or_bits_syscon_register(NCP_SYSCON_PWR_PWRUPCPURAM, mask);
+
+       /* Wait until the RAM power up is complete */
+       success = 
pm_wait_for_bit_clear_with_timeout(NCP_SYSCON_PWR_NPWRUPCPURAM_ACK, cpu);
+       if (!success) {
+               rval = -PM_ERR_RAM_ACK_FAIL;
+               pr_err("CPU: Failed to get ACK of power power up\n");
+               goto power_up_cleanup;
+       }
+
+       /* Release the CPU's isolation clamps */
+       pm_clear_bits_syscon_register(NCP_SYSCON_PWR_ISOLATECPU, mask);
+
+       udelay(16);
+
+power_up_cleanup:
+
+
+       return rval;
+
+}
+/*========================================== L2 FUNCTIONS 
========================================*/
+
+static void pm_L2_isolation_and_power_down(int cluster)
+{
+
+       u32 mask = (0x1 << cluster);
+
+       /* Enable the chip select for the cluster */
+       pm_or_bits_syscon_register(NCP_SYSCON_PWR_CHIPSELECTEN, mask);
+
+       /* Disable the hsram */
+       pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL2HSRAM, mask);
+
+       switch (cluster) {
+       case (0):
+
+#ifdef PM_POWER_OFF_ONLY_DATARAM
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM1, 
RAM_BANK0_MASK);
+               udelay(20);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM1, 
RAM_BANK1_LS_MASK);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM2, 
RAM_BANK1_MS_MASK);
+               udelay(20);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM2, 
RAM_BANK2_MASK);
+               udelay(20);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM2, 
RAM_BANK3_MASK);
+               udelay(20);
+#else
+               
pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM2, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM1, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM0, 
RAM_ALL_MASK);
+               udelay(20);
+
+#endif
+               break;
+       case (1):
+
+#ifdef PM_POWER_OFF_ONLY_DATARAM
+
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM1, 
RAM_BANK0_MASK);
+               udelay(20);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM1, 
RAM_BANK1_LS_MASK);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM2, 
RAM_BANK1_MS_MASK);
+               udelay(20);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM2, 
RAM_BANK2_MASK);
+               udelay(20);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM2, 
RAM_BANK3_MASK);
+               udelay(20);
+#else
+               
pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM2, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM1, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM0, 
RAM_ALL_MASK);
+               udelay(20);
+#endif
+               break;
+       case (2):
+
+#ifdef PM_POWER_OFF_ONLY_DATARAM
+
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM1, 
RAM_BANK0_MASK);
+               udelay(20);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM1, 
RAM_BANK1_LS_MASK);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM2, 
RAM_BANK1_MS_MASK);
+               udelay(20);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM2, 
RAM_BANK2_MASK);
+               udelay(20);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM2, 
RAM_BANK3_MASK);
+               udelay(20);
+#else
+               
pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM2, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM1, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM0, 
RAM_ALL_MASK);
+               udelay(20);
+#endif
+               break;
+       case (3):
+
+#ifdef PM_POWER_OFF_ONLY_DATARAM
+
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM1, 
RAM_BANK0_MASK);
+               udelay(20);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM1, 
RAM_BANK1_LS_MASK);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM2, 
RAM_BANK1_MS_MASK);
+               udelay(20);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM2, 
RAM_BANK2_MASK);
+               udelay(20);
+               pm_clear_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM2, 
RAM_BANK3_MASK);
+               udelay(20);
+#else
+               
pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM2, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM1, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM0, 
RAM_ALL_MASK);
+               udelay(20);
+#endif
+               break;
+       default:
+               pr_err("Illegal cluster: %d > 3\n", cluster);
+               break;
+       }
+
+       /* Power down stage 2 */
+       pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL2LGCSTG2, mask);
+
+       /* Power down stage 1 */
+       pm_clear_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL2LGCSTG1, mask);
+
+}
+
+static int pm_L2_physical_connection_and_power_up(u32 cluster)
+{
+
+       bool success;
+       u32 mask = (0x1 << cluster);
+       int rval = 0;
+
+       /* Power up stage 1 */
+       pm_or_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL2LGCSTG1, mask);
+
+       /* Wait for the stage 1 power up to complete */
+       success = 
pm_wait_for_bit_clear_with_timeout(NCP_SYSCON_PWR_NPWRUPL2LGCSTG1_ACK, cluster);
+       if (!success) {
+               pr_err("CPU: Failed to ack the L2 Stage 1 Power up\n");
+               rval = -PM_ERR_FAIL_L2ACK;
+               goto power_up_l2_cleanup;
+       }
+
+       /* Power on stage 2 */
+       pm_or_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL2LGCSTG2, mask);
+
+       /* Set the chip select */
+       pm_or_bits_syscon_register(NCP_SYSCON_PWR_CHIPSELECTEN, mask);
+
+       /* Power up the snoop ram */
+       pm_or_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL2HSRAM, mask);
+
+       /* Wait for the stage 1 power up to complete */
+       success = 
pm_wait_for_bit_clear_with_timeout(NCP_SYSCON_PWR_NPWRUPL2HSRAM_ACK, cluster);
+       if (!success) {
+               pr_err("CPU: failed to get the HSRAM power up ACK\n");
+               rval = -PM_ERR_FAIL_L2HSRAM;
+               goto power_up_l2_cleanup;
+       }
+
+       switch (cluster) {
+       case (0):
+
+#ifdef PM_POWER_OFF_ONLY_DATARAM
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM1, 
RAM_BANK0_MASK);
+               udelay(20);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM1, 
RAM_BANK1_LS_MASK);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM2, 
RAM_BANK1_MS_MASK);
+               udelay(20);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM2, 
RAM_BANK2_MASK);
+               udelay(20);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM2, 
RAM_BANK3_MASK);
+               udelay(20);
+#else
+               
pm_set_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM2, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_set_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM1, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_set_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM0, 
RAM_ALL_MASK);
+               udelay(20);
+
+#endif
+               break;
+       case (1):
+
+#ifdef PM_POWER_OFF_ONLY_DATARAM
+
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM1, 
RAM_BANK0_MASK);
+       udelay(20);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM1, 
RAM_BANK1_LS_MASK);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM2, 
RAM_BANK1_MS_MASK);
+               udelay(20);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM2, 
RAM_BANK2_MASK);
+               udelay(20);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM2, 
RAM_BANK3_MASK);
+               udelay(20);
+#else
+               
pm_set_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM2, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_set_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM1, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_set_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM0, 
RAM_ALL_MASK);
+               udelay(20);
+#endif
+               break;
+       case (2):
+
+#ifdef PM_POWER_OFF_ONLY_DATARAM
+
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM1, 
RAM_BANK0_MASK);
+               udelay(20);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM1, 
RAM_BANK1_LS_MASK);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM2, 
RAM_BANK1_MS_MASK);
+               udelay(20);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM2, 
RAM_BANK2_MASK);
+               udelay(20);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM2, 
RAM_BANK3_MASK);
+               udelay(20);
+#else
+               
pm_set_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM2, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_set_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM1, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_set_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM0, 
RAM_ALL_MASK);
+               udelay(20);
+#endif
+               break;
+       case (3):
+
+#ifdef PM_POWER_OFF_ONLY_DATARAM
+
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM1, 
RAM_BANK0_MASK);
+               udelay(20);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM1, 
RAM_BANK1_LS_MASK);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM2, 
RAM_BANK1_MS_MASK);
+               udelay(20);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM2, 
RAM_BANK2_MASK);
+               udelay(20);
+               pm_set_bits_syscon_register(syscon,
+                               NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM2, 
RAM_BANK3_MASK);
+               udelay(20);
+#else
+               
pm_set_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM2, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_set_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM1, 
RAM_ALL_MASK);
+               udelay(20);
+               
pm_set_bits_syscon_register(NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM0, 
RAM_ALL_MASK);
+               udelay(20);
+#endif
+               break;
+       default:
+               pr_err("Illegal cluster: %d > 3\n", cluster);
+               break;
+       }
+
+       /* Clear the chip select */
+       pm_clear_bits_syscon_register(NCP_SYSCON_PWR_CHIPSELECTEN, mask);
+
+       /* Release the isolation clamps */
+       pm_clear_bits_syscon_register(NCP_SYSCON_PWR_ISOLATEL2MISC, mask);
+
+       /* Turn the ACE bridge power on*/
+       pm_clear_bits_syscon_register(NCP_SYSCON_PWR_ACEPWRDNRQ, mask);
+
+power_up_l2_cleanup:
+       return rval;
+}
+
+static int pm_L2_logical_powerup(u32 cluster, u32 cpu)
+{
+
+       u32 mask = (0x1 << cluster);
+       int rval = 0;
+       u32 cluster_mask;
+
+       if (cluster == 0)
+               cluster_mask = 0xe;
+       else
+               cluster_mask = 0xf << (cluster * 4);
+
+       /* put the cluster into a cpu hold */
+       pm_or_bits_syscon_register(NCP_SYSCON_RESET_AXIS,
+                       cluster_to_poreset[cluster]);
+
+       /*
+        * The key value has to be written before the CPU RST can be written.
+        */
+       pm_set_bits_syscon_register(NCP_SYSCON_KEY, VALID_KEY_VALUE);
+       pm_or_bits_syscon_register(NCP_SYSCON_PWRUP_CPU_RST, cluster_mask);
+
+       /* Hold the chip debug cluster */
+       pm_set_bits_syscon_register(NCP_SYSCON_KEY, VALID_KEY_VALUE);
+       pm_or_bits_syscon_register(NCP_SYSCON_HOLD_DBG, mask);
+
+       /* Hold the L2 cluster */
+       pm_set_bits_syscon_register(NCP_SYSCON_KEY, VALID_KEY_VALUE);
+       pm_or_bits_syscon_register(NCP_SYSCON_HOLD_L2, mask);
+
+
+       /* Cluster physical power up */
+       rval = pm_L2_physical_connection_and_power_up(cluster);
+       if (rval)
+               goto exit_pm_L2_logical_powerup;
+
+       udelay(16);
+
+       /* take the cluster out of a cpu hold */
+       pm_clear_bits_syscon_register(NCP_SYSCON_RESET_AXIS,
+                       cluster_to_poreset[cluster]);
+
+       udelay(64);
+
+       /* Enable the system counter */
+       pm_or_bits_syscon_register(NCP_SYSCON_PWR_CSYSREQ_CNT, mask);
+
+       /* Release the L2 cluster */
+       pm_set_bits_syscon_register(NCP_SYSCON_KEY, VALID_KEY_VALUE);
+       pm_clear_bits_syscon_register(NCP_SYSCON_HOLD_L2, mask);
+
+       /* Release the chip debug cluster */
+       pm_set_bits_syscon_register(NCP_SYSCON_KEY, VALID_KEY_VALUE);
+       pm_clear_bits_syscon_register(NCP_SYSCON_HOLD_DBG, mask);
+
+       /* Power up the dickens */
+       rval = pm_dickens_logical_powerup(cluster);
+       if (rval)
+               goto exit_pm_L2_logical_powerup;
+
+       /* start L2 */
+       pm_clear_bits_syscon_register(NCP_SYSCON_PWR_ACINACTM, mask);
+
+exit_pm_L2_logical_powerup:
+
+       return rval;
+
+}
+
+#ifdef DEBUG_CPU_PM
+
+void pm_debug_read_pwr_registers(void)
+{
+       u32 reg;
+
+       reg = readl(syscon + 0x1400);
+       pr_err("NCP_SYSCON_PWR_CLKEN: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_PWR_ACINACTM);
+       pr_err("NCP_SYSCON_PWR_ACINACTM: 0x%x\n", reg);
+       reg = readl(syscon + 0x140c);
+       pr_err("NCP_SYSCON_PWR_CHIPSELECTEN: 0x%x\n", reg);
+       reg = readl(syscon + 0x1410);
+       pr_err("NCP_SYSCON_PWR_CSYSREQ_TS: 0x%x\n", reg);
+       reg = readl(syscon + 0x1414);
+       pr_err("NCP_SYSCON_PWR_CSYSREQ_CNT: 0x%x\n", reg);
+       reg = readl(syscon + 0x1418);
+       pr_err("NCP_SYSCON_PWR_CSYSREQ_ATB: 0x%x\n", reg);
+       reg = readl(syscon + 0x141c);
+       pr_err("NCP_SYSCON_PWR_CSYSREQ_APB: 0x%x\n", reg);
+       reg = readl(syscon + 0x1420);
+       pr_err("NCP_SYSCON_PWR_PWRUPL2LGCSTG1: 0x%x\n", reg);
+       reg = readl(syscon + 0x1424);
+       pr_err("NCP_SYSCON_PWR_PWRUPL2LGCSTG2: 0x%x\n", reg);
+       reg = readl(syscon + 0x1428);
+       pr_err("NCP_SYSCON_PWR_PWRUPL2HSRAM: 0x%x\n", reg);
+       reg = readl(syscon + 0x142c);
+       pr_err("NCP_SYSCON_PWR_ACEPWRDNRQ: 0x%x\n", reg);
+       reg = readl(syscon + 0x1430);
+       pr_err("NCP_SYSCON_PWR_ISOLATEL2MIS: 0x%x\n", reg);
+       reg = readl(syscon + 0x1438);
+       pr_err("NCP_SYSCON_PWR_NPWRUPL2LGCSTG1_ACK: 0x%x\n", reg);
+       reg = readl(syscon + 0x143c);
+       pr_err("NCP_SYSCON_PWR_NPWRUPL2HSRAM_ACK: 0x%x\n", reg);
+       reg = readl(syscon + 0x1440);
+       pr_err("NCP_SYSCON_PWR_STANDBYWFIL2: 0x%x\n", reg);
+       reg = readl(syscon + 0x1444);
+       pr_err("NCP_SYSCON_PWR_CSYSACK_TS: 0x%x\n", reg);
+       reg = readl(syscon + 0x1448);
+       pr_err("NCP_SYSCON_PWR_CACTIVE_TS: 0x%x\n", reg);
+       reg = readl(syscon + 0x144c);
+       pr_err("NCP_SYSCON_PWR_CSYSACK_CNT: 0x%x\n", reg);
+       reg = readl(syscon + 0x1450);
+       pr_err("NCP_SYSCON_PWR_CACTIVE_CNT: 0x%x\n", reg);
+       reg = readl(syscon + 0x1454);
+       pr_err("NCP_SYSCON_PWR_CSYSACK_ATB: 0x%x\n", reg);
+       reg = readl(syscon + 0x1458);
+       pr_err("NCP_SYSCON_PWR_CACTIVE_ATB: 0x%x\n", reg);
+       reg = readl(syscon + 0x145c);
+       pr_err("NCP_SYSCON_PWR_CSYSACK_APB: 0x%x\n", reg);
+       reg = readl(syscon + 0x1460);
+       pr_err("NCP_SYSCON_PWR_CACTIVE_APB: 0x%x\n", reg);
+       reg = readl(syscon + 0x1464);
+       pr_err("NCP_SYSCON_PWR_NACEPWRDNACK: 0x%x\n", reg);
+       reg = readl(syscon + 0x1468);
+       pr_err("NCP_SYSCON_PWR_CACTIVEM_EAGM: 0x%x\n", reg);
+       reg = readl(syscon + 0x146c);
+       pr_err("NCP_SYSCON_PWR_CACTIVEM_EAGS: 0x%x\n", reg);
+       reg = readl(syscon + 0x1470);
+       pr_err("NCP_SYSCON_PWR_CACTIVES_EAGM: 0x%x\n", reg);
+       reg = readl(syscon + 0x1474);
+       pr_err("NCP_SYSCON_PWR_CACTIVES_EAGS: 0x%x\n", reg);
+       reg = readl(syscon + 0x1480);
+       pr_err("NCP_SYSCON_PWR_PWRUPCPUSTG1: 0x%x\n", reg);
+       reg = readl(syscon + 0x1484);
+       pr_err("NCP_SYSCON_PWR_PWRUPCPUSTG2: 0x%x\n", reg);
+       reg = readl(syscon + 0x1488);
+       pr_err("NCP_SYSCON_PWR_PWRUPCPURAM: 0x%x\n", reg);
+       reg = readl(syscon + 0x148c);
+       pr_err("NCP_SYSCON_PWR_ISOLATECPU: 0x%x\n", reg);
+       reg = readl(syscon + 0x1490);
+       pr_err("NCP_SYSCON_PWR_NPWRUPCPUSTG1_ACK: 0x%x\n", reg);
+       reg = readl(syscon + 0x1494);
+       pr_err("NCP_SYSCON_PWR_NPWRUPCPURAM_ACK: 0x%x\n", reg);
+       reg = readl(syscon + 0x1498);
+       pr_err("NCP_SYSCON_PWR_QACTIVE: 0x%x\n", reg);
+       reg = readl(syscon + 0x149C);
+       pr_err("NCP_SYSCON_PWR_STANDBYWFI: 0x%x\n", reg);
+       reg = readl(syscon + 0x14A0);
+       pr_err("NCP_SYSCON_PWR_STANDBYWFE: 0x%x\n", reg);
+       reg = readl(syscon + 0x14A4);
+       pr_err("NCP_SYSCON_PWR_DBGNOPWRDWN: 0x%x\n", reg);
+       reg = readl(syscon + 0x14A8);
+       pr_err("NCP_SYSCON_PWR_DBGPWRUPREQ: 0x%x\n", reg);
+       reg = readl(syscon + 0x1040);
+       pr_err("NCP_SYSCON_RESET_AXIS: 0x%x\n", reg);
+       reg = readl(syscon + 0x1044);
+       pr_err("NCP_SYSCON_RESET_AXIS-WORD1: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_RESET_CPU);
+       pr_err("NCP_SYSCON_RESET_CPU: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_HOLD_DBG);
+       pr_err("NCP_SYSCON_HOLD_DBG: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_HOLD_L2);
+       pr_err("NCP_SYSCON_HOLD_L2: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_HOLD_CPU);
+       pr_err("NCP_SYSCON_HOLD_CPU: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_PWRUP_CPU_RST);
+       pr_err("NCP_SYSCON_PWRUP_CPU_RST: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_RESET_STATUS);
+       pr_err("NCP_SYSCON_RESET_STATUS: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_RESET_CORE_STATUS);
+       pr_err("NCP_SYSCON_RESET_CORE_STATUS: 0x%x\n", reg);
+
+
+#if 0
+       reg = readl(syscon + NCP_SYSCON_MCG_CSW_CPU);
+       pr_err("NCP_SYSCON_MCG_CSW_CPU: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MCG_CSW_SYS);
+       pr_err("NCP_SYSCON_MCG_CSW_SYS: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MCG_DIV_CPU);
+       pr_err("NCP_SYSCON_MCG_DIV_CPU: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MCG_DIV_SYS);
+       pr_err("NCP_SYSCON_MCG_DIV_SYS: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_CLKDEBUG);
+       pr_err("NCP_SYSCON_CLKDEBUG: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_EVENT_ENB);
+       pr_err("NCP_SYSCON_EVENT_ENB: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_CPU_FAST_INT);
+       pr_err("NCP_SYSCON_CPU_FAST_INT: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_GIC_DISABLE);
+       pr_err("NCP_SYSCON_GIC_DISABLE: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_CP15SDISABLE);
+       pr_err("NCP_SYSCON_CP15SDISABLE: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_LDO_CTL);
+       pr_err("NCP_SYSCON_LDO_CTL: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_SHWK_QOS);
+       pr_err("NCP_SYSCON_SHWK_QOS: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_FUSE_RTO);
+       pr_err("NCP_SYSCON_FUSE_RTO: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_PFUSE);
+       pr_err("NCP_SYSCON_PFUSE: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_FUSE_STAT);
+       pr_err("NCP_SYSCON_FUSE_STAT: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_SCRATCH);
+       pr_err("NCP_SYSCON_SCRATCH: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI0);
+       pr_err("NCP_SYSCON_MASK_IPI0: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI1);
+       pr_err("NCP_SYSCON_MASK_IPI1: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI2);
+       pr_err("NCP_SYSCON_MASK_IPI2: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI3);
+       pr_err("NCP_SYSCON_MASK_IPI3: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI4);
+       pr_err("NCP_SYSCON_MASK_IPI4: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI5);
+       pr_err("NCP_SYSCON_MASK_IPI5: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI6);
+       pr_err("NCP_SYSCON_MASK_IPI6: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI7);
+       pr_err("NCP_SYSCON_MASK_IPI7: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI8);
+       pr_err("NCP_SYSCON_MASK_IPI8: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI9);
+       pr_err("NCP_SYSCON_MASK_IPI9: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI10);
+       pr_err("NCP_SYSCON_MASK_IPI10: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI11);
+       pr_err("NCP_SYSCON_MASK_IPI11: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI12);
+       pr_err("NCP_SYSCON_MASK_IPI12: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI13);
+       pr_err("NCP_SYSCON_MASK_IPI13: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI14);
+       pr_err("NCP_SYSCON_MASK_IPI14: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_MASK_IPI15);
+       pr_err("NCP_SYSCON_MASK_IPI15: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_SPARE0);
+       pr_err("NCP_SYSCON_SPARE0: 0x%x\n", reg);
+       reg = readl(syscon + NCP_SYSCON_STOP_CLK_CPU);
+       pr_err("NCP_SYSCON_STOP_CLK_CPU: 0x%x\n", reg);
+#endif
+
+
+}
+
+
+void pm_dump_L2_registers(void)
+{
+       u32 reg;
+
+
+       reg = readl(syscon + 0x1580);
+       pr_err("NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM2: 0x%x\n", reg);
+       reg = readl(syscon + 0x1584);
+       pr_err("NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM1: 0x%x\n", reg);
+       reg = readl(syscon + 0x1588);
+       pr_err("NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM0: 0x%x\n", reg);
+       reg = readl(syscon + 0x158c);
+       pr_err("NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM2: 0x%x\n", reg);
+       reg = readl(syscon + 0x1590);
+       pr_err("NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM1: 0x%x\n", reg);
+       reg = readl(syscon + 0x1594);
+       pr_err("NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM0: 0x%x\n", reg);
+       reg = readl(syscon + 0x1598);
+       pr_err("NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM2: 0x%x\n", reg);
+       reg = readl(syscon + 0x159c);
+       pr_err("NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM1: 0x%x\n", reg);
+       reg = readl(syscon + 0x15a0);
+       pr_err("NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM0: 0x%x\n", reg);
+       reg = readl(syscon + 0x15a4);
+       pr_err("NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM2: 0x%x\n", reg);
+       reg = readl(syscon + 0x15a8);
+       pr_err("NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM1: 0x%x\n", reg);
+       reg = readl(syscon + 0x15ac);
+       pr_err("NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM0: 0x%x\n", reg);
+
+
+
+
+void pm_dump_dickens(void)
+{
+
+       void __iomem *dickens;
+       u32 status;
+       u32 i;
+
+       dickens = ioremap(DICKENS_PHYS_ADDR, SZ_4M);
+       if (dickens == NULL) {
+               pr_err("DICKENS: Failed to map the dickens registers\n");
+               return;
+       }
+
+       for (i = 0; i < DKN_HNF_TOTAL_NODES; ++i) {
+               status = readl(
+                               dickens + (0x10000 * (DKN_HNF_NODE_ID + i))
+                                               + DKN_HNF_SNOOP_DOMAIN_CTL);
+               udelay(1);
+               pr_err("DKN_HNF_SNOOP_DOMAIN_CTL[%d]: 0x%x\n", i, status);
+       }
+
+       status = readl(
+                       dickens + (0x10000 * DKN_DVM_DOMAIN_OFFSET)
+                                       + DKN_MN_DVM_DOMAIN_CTL);
+
+       pr_err("DKN_MN_DVM_DOMAIN_CTL: 0x%x\n", status);
+
+
+
+}
+
+#endif
diff --git a/arch/arm/mach-axxia/lsi_power_management.h 
b/arch/arm/mach-axxia/lsi_power_management.h
new file mode 100644
index 0000000..f967a37
--- /dev/null
+++ b/arch/arm/mach-axxia/lsi_power_management.h
@@ -0,0 +1,192 @@
+/*
+ * lsi_power_management.h
+ *
+ *  Created on: Jun 23, 2014
+ *      Author: z8cpaul
+ */
+
+#ifndef LSI_POWER_MANAGEMENT_H_
+#define LSI_POWER_MANAGEMENT_H_
+
+
+#define     NCP_SYSCON_MCG_CSW_CPU                              (0x00000000)
+#define     NCP_SYSCON_MCG_CSW_SYS                              (0x00000004)
+#define     NCP_SYSCON_MCG_DIV_CPU                              (0x00000008)
+#define     NCP_SYSCON_MCG_DIV_SYS                              (0x0000000c)
+#define     NCP_SYSCON_CLKDEBUG                                 (0x00000010)
+#define     NCP_SYSCON_EVENT_ENB                                (0x00000014)
+#define     NCP_SYSCON_CPU_FAST_INT                             (0x00000018)
+#define     NCP_SYSCON_GIC_DISABLE                              (0x0000001c)
+#define     NCP_SYSCON_CP15SDISABLE                             (0x00000020)
+#define     NCP_SYSCON_LRSTDISABLE                              (0x00000024)
+#define     NCP_SYSCON_LDO_CTL                                  (0x00000028)
+#define     NCP_SYSCON_SHWK_QOS                                 (0x0000002c)
+#define     NCP_SYSCON_FUSE_RTO                                 (0x00000030)
+#define     NCP_SYSCON_PFUSE                                    (0x00000034)
+#define     NCP_SYSCON_FUSE_STAT                                (0x00000038)
+#define     NCP_SYSCON_SCRATCH                                  (0x0000003c)
+#define     NCP_SYSCON_MASK_IPI0                                (0x00000040)
+#define     NCP_SYSCON_MASK_IPI1                                (0x00000044)
+#define     NCP_SYSCON_MASK_IPI2                                (0x00000048)
+#define     NCP_SYSCON_MASK_IPI3                                (0x0000004c)
+#define     NCP_SYSCON_MASK_IPI4                                (0x00000050)
+#define     NCP_SYSCON_MASK_IPI5                                (0x00000054)
+#define     NCP_SYSCON_MASK_IPI6                                (0x00000058)
+#define     NCP_SYSCON_MASK_IPI7                                (0x0000005c)
+#define     NCP_SYSCON_MASK_IPI8                                (0x00000060)
+#define     NCP_SYSCON_MASK_IPI9                                (0x00000064)
+#define     NCP_SYSCON_MASK_IPI10                               (0x00000068)
+#define     NCP_SYSCON_MASK_IPI11                               (0x0000006c)
+#define     NCP_SYSCON_MASK_IPI12                               (0x00000070)
+#define     NCP_SYSCON_MASK_IPI13                               (0x00000074)
+#define     NCP_SYSCON_MASK_IPI14                               (0x00000078)
+#define     NCP_SYSCON_MASK_IPI15                               (0x0000007c)
+#define     NCP_SYSCON_MASK_IPI16                               (0x00000080)
+#define     NCP_SYSCON_MASK_IPI17                               (0x00000084)
+#define     NCP_SYSCON_MASK_IPI18                               (0x00000088)
+#define     NCP_SYSCON_SPARE0                                   (0x0000008c)
+#define     NCP_SYSCON_STOP_CLK_CPU                             (0x00000090)
+
+
+#define     NCP_SYSCON_RESET_STATUS                             (0x00000100)
+#define     NCP_SYSCON_RESET_CORE_STATUS                        (0x00000108)
+
+#define     NCP_SYSCON_KEY                                      (0x00001000)
+#define     NCP_SYSCON_RESET_CTL                                (0x00001008)
+#define     NCP_SYSCON_RESET_CPU                                (0x0000100c)
+#define     NCP_SYSCON_HOLD_CPU                                 (0x00001010)
+#define     NCP_SYSCON_HOLD_PTM                                 (0x00001014)
+#define     NCP_SYSCON_HOLD_L2                                  (0x00001018)
+#define     NCP_SYSCON_HOLD_DBG                                 (0x0000101c)
+
+#define     NCP_SYSCON_PWRUP_CPU_RST                            (0x00001030)
+
+#define     NCP_SYSCON_RESET_AXIS                               (0x00001040)
+#define     NCP_SYSCON_RESET_AXIS_ACCESS_SIZE                   (0x00000008)
+
+#define     NCP_SYSCON_PWR_CLKEN                                (0x00001400)
+#define     NCP_SYSCON_ENABLE_CLKEN_SET                         (0x00001404)
+#define     NCP_SYSCON_PWR_ACINACTM                             (0x00001408)
+#define     NCP_SYSCON_PWR_CHIPSELECTEN                         (0x0000140c)
+#define     NCP_SYSCON_PWR_CSYSREQ_TS                           (0x00001410)
+#define     NCP_SYSCON_PWR_CSYSREQ_CNT                          (0x00001414)
+#define     NCP_SYSCON_PWR_CSYSREQ_ATB                          (0x00001418)
+#define     NCP_SYSCON_PWR_CSYSREQ_APB                          (0x0000141c)
+#define     NCP_SYSCON_PWR_PWRUPL2LGCSTG1                       (0x00001420)
+#define     NCP_SYSCON_PWR_PWRUPL2LGCSTG2                       (0x00001424)
+#define     NCP_SYSCON_PWR_PWRUPL2HSRAM                         (0x00001428)
+#define     NCP_SYSCON_PWR_ACEPWRDNRQ                           (0x0000142c)
+#define     NCP_SYSCON_PWR_ISOLATEL2MISC                        (0x00001430)
+#define     NCP_SYSCON_PWR_NPWRUPL2LGCSTG1_ACK                  (0x00001438)
+#define     NCP_SYSCON_PWR_NPWRUPL2HSRAM_ACK                    (0x0000143c)
+#define     NCP_SYSCON_PWR_STANDBYWFIL2                         (0x00001440)
+#define     NCP_SYSCON_PWR_CSYSACK_TS                           (0x00001444)
+#define     NCP_SYSCON_PWR_CACTIVE_TS                           (0x00001448)
+#define     NCP_SYSCON_PWR_CSYSACK_CNT                          (0x0000144c)
+#define     NCP_SYSCON_PWR_CACTIVE_CNT                          (0x00001450)
+#define     NCP_SYSCON_PWR_CSYSACK_ATB                          (0x00001454)
+#define     NCP_SYSCON_PWR_CACTIVE_ATB                          (0x00001458)
+#define     NCP_SYSCON_PWR_CSYSACK_APB                          (0x0000145c)
+#define     NCP_SYSCON_PWR_CACTIVE_APB                          (0x00001460)
+#define     NCP_SYSCON_PWR_NACEPWRDNACK                         (0x00001464)
+#define     NCP_SYSCON_PWR_CACTIVEM_EAGM                        (0x00001468)
+#define     NCP_SYSCON_PWR_CACTIVEM_EAGS                        (0x0000146c)
+#define     NCP_SYSCON_PWR_CACTIVES_EAGM                        (0x00001470)
+#define     NCP_SYSCON_PWR_CACTIVES_EAGS                        (0x00001474)
+#define     NCP_SYSCON_PWR_PWRUPCPUSTG1                         (0x00001480)
+#define     NCP_SYSCON_PWR_PWRUPCPUSTG2                         (0x00001484)
+#define     NCP_SYSCON_PWR_PWRUPCPURAM                          (0x00001488)
+#define     NCP_SYSCON_PWR_ISOLATECPU                           (0x0000148c)
+#define     NCP_SYSCON_PWR_NPWRUPCPUSTG1_ACK                    (0x00001490)
+#define     NCP_SYSCON_PWR_NPWRUPCPURAM_ACK                     (0x00001494)
+#define     NCP_SYSCON_PWR_QACTIVE                              (0x00001498)
+#define     NCP_SYSCON_PWR_STANDBYWFI                           (0x0000149c)
+#define     NCP_SYSCON_PWR_STANDBYWFE                           (0x000014a0)
+#define     NCP_SYSCON_PWR_DBGNOPWRDWN                          (0x000014a4)
+#define     NCP_SYSCON_PWR_DBGPWRUPREQ                          (0x000014a8)
+#define     NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM2              (0x00001580)
+#define     NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM1              (0x00001584)
+#define     NCP_SYSCON_PWR_PWRUPL20RAM_PWRUPL2RAM0              (0x00001588)
+#define     NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM2              (0x0000158c)
+#define     NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM1              (0x00001590)
+#define     NCP_SYSCON_PWR_PWRUPL21RAM_PWRUPL2RAM0              (0x00001594)
+#define     NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM2              (0x00001598)
+#define     NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM1              (0x0000159c)
+#define     NCP_SYSCON_PWR_PWRUPL22RAM_PWRUPL2RAM0              (0x000015a0)
+#define     NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM2              (0x000015a4)
+#define     NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM1              (0x000015a8)
+#define     NCP_SYSCON_PWR_PWRUPL23RAM_PWRUPL2RAM0              (0x000015ac)
+
+#define                RAM_BANK0_MASK                  (0x0FFF0000)
+#define                RAM_BANK1_LS_MASK               (0xF0000000)
+#define                RAM_BANK1_MS_MASK               (0x000000FF)
+#define                RAM_BANK2_MASK                  (0x000FFF00)
+#define                RAM_BANK3_MASK                  (0xFFF00000)
+#define                RAM_ALL_MASK                    (0xFFFFFFFF)
+
+/* DICKENS REGISTERS (Miscelaneous Node) */
+#define                DKN_MN_NODE_ID                          (0x0)
+#define                DKN_DVM_DOMAIN_OFFSET           (0x0)
+#define                DKN_MN_DVM_DOMAIN_CTL           (0x200)
+#define                DKN_MN_DVM_DOMAIN_CTL_SET       (0x210)
+#define                DKN_MN_DVM_DOMAIN_CTL_CLR       (0x220)
+
+/* DICKENS HN-F (Fully-coherent Home Node) */
+#define                DKN_HNF_NODE_ID                                 (0x20)
+#define                DKN_HNF_TOTAL_NODES                             (0x8)
+#define                DKN_HNF_SNOOP_DOMAIN_CTL                (0x200)
+#define                DKN_HNF_SNOOP_DOMAIN_CTL_SET    (0x210)
+#define                DKN_HNF_SNOOP_DOMAIN_CTL_CLR    (0x220)
+
+/* DICKENS clustid to Node */
+#define                DKN_CLUSTER0_NODE               (1)
+#define                DKN_CLUSTER1_NODE               (9)
+#define                DKN_CLUSTER2_NODE               (11)
+#define                DKN_CLUSTER3_NODE               (19)
+
+/* PO RESET cluster id to bit */
+#define                PORESET_CLUSTER0                (0x10000)
+#define                PORESET_CLUSTER1                (0x20000)
+#define                PORESET_CLUSTER2                (0x40000)
+#define                PORESET_CLUSTER3                (0x80000)
+
+/* IPI Masks */
+#define                IPI0_MASK                               (0x1111)
+#define                IPI1_MASK                               (0x2222)
+#define                IPI2_MASK                               (0x4444)
+#define                IPI3_MASK                               (0x8888)
+
+/* SYSCON KEY Value */
+#define VALID_KEY_VALUE                        (0xAB)
+
+#define MAX_NUM_CLUSTERS    (4)
+#define CORES_PER_CLUSTER   (4)
+#define MAX_IPI                                (19)
+#define MAX_CPUS                       (MAX_NUM_CLUSTERS * CORES_PER_CLUSTER)
+
+typedef struct {
+       u32 cpu;
+       u32 cluster;
+} pm_data;
+
+
+void pm_cpu_shutdown(u32 cpu);
+int pm_cpu_powerup(u32 cpu);
+void pm_debug_read_pwr_registers(void);
+void pm_dump_L2_registers(void);
+int pm_cpu_logical_die(pm_data *pm_request);
+int pm_cpul2_logical_die(pm_data *pm_request);
+unsigned long pm_get_powered_down_cpu(void);
+bool pm_cpu_last_of_cluster(u32 cpu);
+void pm_dump_dickens(void);
+void pm_init_cpu(u32 cpu);
+void pm_cpu_logical_powerup(void);
+void pm_cluster_logical_powerup(void);
+bool pm_cpu_active(u32 cpu);
+void pm_init_syscon(void);
+extern bool pm_in_progress[];
+extern bool cluster_power_up[];
+extern u32 pm_cpu_powered_down;
+
+
+#endif /* LSI_POWER_MANAGEMENT_H_ */
diff --git a/arch/arm/mach-axxia/perf_event_memc.c 
b/arch/arm/mach-axxia/perf_event_memc.c
new file mode 100644
index 0000000..7da5926
--- /dev/null
+++ b/arch/arm/mach-axxia/perf_event_memc.c
@@ -0,0 +1,152 @@
+/*
+ * arch/arm/mach-axxia/perf_event_memc.c
+ * included from arch/arm/mach-axxia/perf_event_platform.c
+ *
+ * Support for the LSI Axxia boards based on ARM cores.
+ *
+ * Copyright (C) 2014 LSI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307        
 USA
+ */
+
+#include "perf_event_memc.h"
+
+static void memc_startup_init(void)
+{
+       uint32_t config;
+
+       smon_init_ncp(&ddrc0_smon, DDRC0, DDRC_PERF, DDRC_SMON);
+       smon_init_ncp(&ddrc1_smon, DDRC1, DDRC_PERF, DDRC_SMON);
+       smon_init_mem(&elm0_smon, ELM0, ELM_SMON);
+       smon_init_mem(&elm1_smon, ELM1, ELM_SMON);
+
+       /* enable SMC SMON registers */
+       ncr_read(NCP_REGION_ID(DDRC0, DDRC_CTRL), CTRL_SMON,
+                REG_SZ, &config);
+       config |= SMON_ENABLE;
+       ncr_write(NCP_REGION_ID(DDRC0, DDRC_CTRL), CTRL_SMON,
+                 REG_SZ, &config);
+
+       ncr_read(NCP_REGION_ID(DDRC1, DDRC_CTRL), CTRL_SMON,
+                REG_SZ, &config);
+       config |= SMON_ENABLE;
+       ncr_write(NCP_REGION_ID(DDRC1, DDRC_CTRL), CTRL_SMON,
+                 REG_SZ, &config);
+}
+
+static uint32_t memc_pmu_event_init(uint32_t event, struct perf_event *pevent)
+{
+       return 0;
+}
+
+static uint32_t memc_pmu_event_add(uint32_t ev, struct perf_event *pevent)
+{
+       uint32_t ret;
+
+       if (ev >= DDRC0_OFFSET && ev <= DDRC0_SMON_MAX) {
+
+               ret = smon_allocate(&ddrc0_smon, ev - DDRC0_OFFSET);
+               if (ret != 0)
+                       return ret;
+
+               ret = smon_start(&ddrc0_smon, ev - DDRC0_OFFSET);
+               if (ret != 0)
+                       return ret;
+       } else if (ev >= DDRC1_OFFSET && ev <= DDRC1_SMON_MAX) {
+
+               ret = smon_allocate(&ddrc1_smon, ev - DDRC1_OFFSET);
+               if (ret != 0)
+                       return ret;
+
+               ret = smon_start(&ddrc1_smon, ev - DDRC1_OFFSET);
+               if (ret != 0)
+                       return ret;
+       } else if (ev >= ELM0_OFFSET && ev <= ELM0_SMON_MAX) {
+
+               ret = smon_allocate(&elm0_smon, ev - ELM0_OFFSET);
+               if (ret != 0)
+                       return ret;
+
+               ret = smon_start(&elm0_smon, ev - ELM0_OFFSET);
+               if (ret != 0)
+                       return ret;
+       } else if (ev >= ELM1_OFFSET && ev <= ELM1_SMON_MAX) {
+
+               ret = smon_allocate(&elm1_smon, ev - ELM1_OFFSET);
+               if (ret != 0)
+                       return ret;
+
+               ret = smon_start(&elm1_smon, ev - ELM1_OFFSET);
+               if (ret != 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+/*
+ * Return counter update.
+ */
+static uint32_t memc_pmu_event_read(uint32_t ev, struct perf_event *pevent,
+               int flags)
+{
+       uint32_t count = 0;
+
+       if (ev >= DDRC0_OFFSET && ev <= DDRC0_SMON_MAX)
+               count = smon_read(&ddrc0_smon, ev - DDRC0_OFFSET);
+       else if (ev >= DDRC1_OFFSET && ev <= DDRC1_SMON_MAX)
+               count = smon_read(&ddrc1_smon, ev - DDRC1_OFFSET);
+       else if (ev >= ELM0_OFFSET && ev <= ELM0_SMON_MAX)
+               count = smon_read(&elm0_smon, ev - ELM0_OFFSET);
+       else if (ev >= ELM1_OFFSET && ev <= ELM1_SMON_MAX)
+               count = smon_read(&elm1_smon, ev - ELM1_OFFSET);
+
+       if (count == -ENOEVENT)
+               count = 0;
+
+       return count;
+}
+
+/*
+ * Remove event and return counter update.
+ */
+static uint32_t memc_pmu_event_del(uint32_t ev, struct perf_event *pevent,
+                                  int flags)
+{
+       uint32_t count = 0;
+
+       if (ev >= DDRC0_OFFSET && ev <= DDRC0_SMON_MAX) {
+               count = smon_read(&ddrc0_smon, ev - DDRC0_OFFSET);
+
+               smon_deallocate(&ddrc0_smon, ev - DDRC0_OFFSET);
+       } else if (ev >= DDRC1_OFFSET && ev <= DDRC1_SMON_MAX) {
+               count = smon_read(&ddrc1_smon, ev - DDRC1_OFFSET);
+
+               smon_deallocate(&ddrc1_smon, ev - DDRC1_OFFSET);
+       } else if (ev >= ELM0_OFFSET && ev <= ELM0_SMON_MAX) {
+               count = smon_read(&elm0_smon, ev - ELM0_OFFSET);
+
+               smon_deallocate(&elm0_smon, ev - ELM0_OFFSET);
+       } else if (ev >= ELM1_OFFSET && ev <= ELM1_SMON_MAX) {
+               count = smon_read(&elm1_smon, ev - ELM1_OFFSET);
+
+               smon_deallocate(&elm1_smon, ev - ELM1_OFFSET);
+       }
+
+       if (count == -ENOEVENT)
+               count = 0;
+
+       return count;
+}
diff --git a/arch/arm/mach-axxia/perf_event_memc.h 
b/arch/arm/mach-axxia/perf_event_memc.h
new file mode 100644
index 0000000..6e9ba519
--- /dev/null
+++ b/arch/arm/mach-axxia/perf_event_memc.h
@@ -0,0 +1,67 @@
+/*
+ * arch/arm/mach-axxia/perf_event_memc.h
+ * included from arch/arm/mach-axxia/perf_event_memc.c
+ *
+ * Support for the LSI Axxia boards based on ARM cores.
+ *
+ * Copyright (C) 2014 LSI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM__ARCH_AXXIA_PERF_EVENT_MEMC_H
+#define __ASM__ARCH_AXXIA_PERF_EVENT_MEMC_H
+
+#define DDRC0_OFFSET 0x00
+#define DDRC0_SMON_MAX (DDRC0_OFFSET + 22)
+#define DDRC1_OFFSET 0x100
+#define DDRC1_SMON_MAX (DDRC1_OFFSET + 22)
+
+#define ELM0_OFFSET 0x200
+#define ELM0_SMON_MAX (ELM0_OFFSET + 15)
+#define ELM1_OFFSET 0x300
+#define ELM1_SMON_MAX (ELM1_OFFSET + 15)
+
+/* Node */
+#define DDRC0 0x0f
+#define DDRC1 0x22
+/* Target */
+#define DDRC_CTRL 0x00
+#define DDRC_PERF 0x02
+/* Address */
+#define CTRL_SMON 0x1fc
+
+#ifdef AXM55XX_R1
+#define DDRC_SMON 0x40
+#endif
+#ifdef AXM55XX_R2
+#define DDRC_SMON 0xA0
+#endif
+
+/* Settings */
+#define SMON_ENABLE 0x20000000
+
+/* Base Address */
+#define ELM0 0x2010060000
+#define ELM1 0x2010070000
+/* SMON Offset */
+#define ELM_SMON (0x300/4)
+
+struct smon_s ddrc0_smon;
+struct smon_s ddrc1_smon;
+struct smon_s elm0_smon;
+struct smon_s elm1_smon;
+
+#endif
diff --git a/arch/arm/mach-axxia/perf_event_pcx.c 
b/arch/arm/mach-axxia/perf_event_pcx.c
new file mode 100644
index 0000000..7896bb9
--- /dev/null
+++ b/arch/arm/mach-axxia/perf_event_pcx.c
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-axxia/perf_event_pcx.c
+ * included from arch/arm/mach-axxia/perf_event_platform.c
+ *
+ * Support for the LSI Axxia boards based on ARM cores.
+ *
+ * Copyright (C) 2014 LSI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * Generic PCX
+ */
+
+static void pcx_startup_init(void)
+{
+}
+
+static uint32_t pcx_pmu_event_init(uint32_t ev, struct perf_event *event)
+{
+       return 0;
+}
+
+static uint32_t pcx_pmu_event_add(uint32_t ev, struct perf_event *event)
+{
+       return 0;
+}
+
+static uint32_t pcx_pmu_event_read(uint32_t ev, struct perf_event *event,
+               int flags)
+{
+       return 0;
+}
+
+static uint32_t pcx_pmu_event_del(uint32_t ev, struct perf_event *event,
+               int flags)
+{
+       return 0;
+}
diff --git a/arch/arm/mach-axxia/perf_event_platform.c 
b/arch/arm/mach-axxia/perf_event_platform.c
new file mode 100644
index 0000000..538fd1a
--- /dev/null
+++ b/arch/arm/mach-axxia/perf_event_platform.c
@@ -0,0 +1,275 @@
+/*
+ * arch/arm/mach-axxia/perf_event_platform.c
+ *
+ * Support for the LSI Axxia boards based on ARM cores.
+ *
+ * Copyright (C) 2014 LSI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/bitmap.h>
+#include <linux/cpu_pm.h>
+#include <linux/export.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <asm/cputype.h>
+#include <asm/irq_regs.h>
+#include <asm/pmu.h>
+
+#include <linux/kthread.h>
+#include <linux/sched.h>
+
+#include <linux/cpu.h>
+#include <linux/reboot.h>
+#include <linux/syscore_ops.h>
+
+#include <linux/proc_fs.h>
+
+#include <linux/io.h>
+#include <asm/cacheflush.h>
+#include <../../../drivers/misc/lsi-ncr.h>
+
+#include "perf_event_platform.h"
+
+#include "smon.h"
+
+/*
+ * Include code for individual block support
+ */
+
+#include "perf_event_pcx.c"
+#include "perf_event_vp.c"
+#include "perf_event_memc.c"
+
+/*
+ * General platform perf code, muxed out to individual blocks
+ */
+
+int platform_pmu_event_idx(struct perf_event *event)
+{
+       return 0;
+}
+
+int platform_pmu_event_init(struct perf_event *event)
+{
+       uint64_t ev = event->attr.config;
+
+       if (event->attr.type != event->pmu->type)
+               return -ENOENT;
+
+       if ((ev < AXM_55XX_PLATFORM_BASE) || (ev > AXM_55XX_PLATFORM_MAX))
+               return -ENOENT;
+
+       event->hw.config = ev - AXM_55XX_PLATFORM_BASE;
+
+       event->hw.idx = -1;
+       event->hw.config_base = 1;
+
+/*
+ if (event->group_leader != event) {
+  printk("This is not the group leader!\n");
+  printk("event->group_leader 0x%x\n", (unsigned int)event->group_leader);
+ }
+*/
+
+       if (event->attr.exclude_user)
+               return -ENOTSUPP;
+       if (event->attr.exclude_kernel)
+               return -ENOTSUPP;
+       if (event->attr.exclude_idle)
+               return -ENOTSUPP;
+
+       event->hw.last_period = event->hw.sample_period;
+       local64_set(&event->hw.period_left, event->hw.last_period);
+/*
+ event->destroy = hw_perf_event_destroy;
+*/
+       local64_set(&event->count, 0);
+
+       if (ev >= AXM_55XX_VP_BASE && ev <= AXM_55XX_VP_MAX)
+               vp_pmu_event_init(ev - AXM_55XX_VP_BASE, event);
+       else if (ev >= AXM_55XX_PCX_BASE && ev <= AXM_55XX_PCX_MAX)
+               pcx_pmu_event_init(ev - AXM_55XX_PCX_BASE, event);
+       else if (ev >= AXM_55XX_MEMC_BASE && ev <= AXM_55XX_MEMC_MAX)
+               memc_pmu_event_init(ev - AXM_55XX_MEMC_BASE, event);
+       else
+               pr_info("Platform perf, undefined event, %llu\n", ev);
+
+       return 0;
+}
+
+static int platform_pmu_event_add(struct perf_event *event, int flags)
+{
+       uint64_t ev = event->attr.config;
+
+       if (ev >= AXM_55XX_VP_BASE && ev <= AXM_55XX_VP_MAX)
+               vp_pmu_event_add(ev - AXM_55XX_VP_BASE, event);
+       else if (ev >= AXM_55XX_PCX_BASE && ev <= AXM_55XX_PCX_MAX)
+               pcx_pmu_event_add(ev - AXM_55XX_PCX_BASE, event);
+       else if (ev >= AXM_55XX_MEMC_BASE && ev <= AXM_55XX_MEMC_MAX)
+               memc_pmu_event_add(ev - AXM_55XX_MEMC_BASE, event);
+
+       return 0;
+}
+
+static void platform_pmu_event_del(struct perf_event *event, int flags)
+{
+       uint64_t ev = event->attr.config;
+       uint32_t n;
+
+       if (ev >= AXM_55XX_VP_BASE && ev <= AXM_55XX_VP_MAX) {
+               n = vp_pmu_event_del(ev - AXM_55XX_VP_BASE, event, flags);
+               local64_add(n, &event->count);
+       } else if (ev >= AXM_55XX_PCX_BASE && ev <= AXM_55XX_PCX_MAX) {
+               n = pcx_pmu_event_del(ev - AXM_55XX_PCX_BASE, event, flags);
+               local64_add(n, &event->count);
+       } else if (ev >= AXM_55XX_MEMC_BASE && ev <= AXM_55XX_MEMC_MAX) {
+               n = memc_pmu_event_del(ev - AXM_55XX_MEMC_BASE, event, flags);
+               local64_add(n, &event->count);
+       } else {
+               local64_set(&event->count, 0);
+       }
+}
+
+static void platform_pmu_event_start(struct perf_event *event, int flags)
+{
+}
+
+static void platform_pmu_event_stop(struct perf_event *event, int flags)
+{
+}
+
+static void platform_pmu_event_read(struct perf_event *event)
+{
+       uint64_t ev = event->attr.config;
+       uint32_t n;
+
+       if (ev >= AXM_55XX_VP_BASE && ev <= AXM_55XX_VP_MAX) {
+               n = vp_pmu_event_read(ev - AXM_55XX_VP_BASE, event, 0);
+               local64_add(n, &event->count);
+       } else if (ev >= AXM_55XX_PCX_BASE && ev <= AXM_55XX_PCX_MAX) {
+               n = pcx_pmu_event_read(ev - AXM_55XX_PCX_BASE, event, 0);
+               local64_add(n, &event->count);
+       } else if (ev >= AXM_55XX_MEMC_BASE && ev <= AXM_55XX_MEMC_MAX) {
+               n = memc_pmu_event_read(ev - AXM_55XX_MEMC_BASE, event, 0);
+               local64_add(n, &event->count);
+       }
+}
+
+/*
+ * Device
+ */
+
+static void axmperf_device_release(struct device *dev)
+{
+       pr_warn("AXM55xxPlatformPerf release device\n");
+}
+
+static struct platform_device axmperf_device = {
+       .name = "AXM55xxPlatformPerf",
+       .id = 0,
+       .dev = {
+               .release = axmperf_device_release,
+               },
+};
+
+/*
+ * Driver
+ */
+
+#define PLATFORM_PMU_NAME_LEN 32
+
+struct lsi_platform_pmu {
+       struct pmu pmu;
+       char name[PLATFORM_PMU_NAME_LEN];
+};
+
+static int axmperf_probe(struct platform_device *dev)
+{
+       int ret;
+       struct lsi_platform_pmu *axm_pmu;
+
+       axm_pmu = kzalloc(sizeof(struct lsi_platform_pmu), GFP_KERNEL);
+       if (!axm_pmu) {
+               pr_warn("Failed platform perf memory alloc!\n");
+               return -ENOMEM;
+       }
+
+       axm_pmu->pmu = (struct pmu) {
+               .attr_groups = 0,
+               .event_init = platform_pmu_event_init,
+               .add = platform_pmu_event_add,
+               .del = platform_pmu_event_del,
+               .start = platform_pmu_event_start,
+               .stop = platform_pmu_event_stop,
+               .read = platform_pmu_event_read,
+               .event_idx = platform_pmu_event_idx,
+       };
+
+       sprintf(axm_pmu->name, "LSI AXM55xx Platform");
+
+       ret = perf_pmu_register(&axm_pmu->pmu, axm_pmu->name, PERF_TYPE_RAW);
+
+       if (ret == 0)
+               pr_info("axxia platform perf enabled\n");
+       else
+               pr_info("axxia platform perf failed\n");
+
+       vp_startup_init();
+       pcx_startup_init();
+       memc_startup_init();
+
+       return ret;
+}
+
+static const struct of_device_id lsi_platformperf_match[] = {
+       { .compatible = "lsi,axm-platformperf", },
+       {},
+};
+
+static struct platform_driver axmperf_driver = {
+       .driver = {
+               .name = "AXM55xxPlatformPerf",
+               .of_match_table = lsi_platformperf_match,
+               .owner = THIS_MODULE,
+               },
+       .probe = axmperf_probe,
+};
+
+static int __init axmperf_init(void)
+{
+       platform_driver_register(&axmperf_driver);
+
+       return 0;
+}
+
+static void __exit axmperf_exit(void)
+{
+       pr_warn("AXM55xx platform perf exit!\n");
+       platform_driver_unregister(&axmperf_driver);
+       platform_device_unregister(&axmperf_device);
+}
+
+module_init(axmperf_init);
+module_exit(axmperf_exit);
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-axxia/perf_event_platform.h 
b/arch/arm/mach-axxia/perf_event_platform.h
new file mode 100644
index 0000000..29698c5
--- /dev/null
+++ b/arch/arm/mach-axxia/perf_event_platform.h
@@ -0,0 +1,10 @@
+#define AXM55XX_R2 "1.1"
+
+#define AXM_55XX_PLATFORM_BASE 0x10000
+#define AXM_55XX_VP_BASE (AXM_55XX_PLATFORM_BASE + 0x00)
+#define AXM_55XX_VP_MAX (AXM_55XX_VP_BASE + 0x1fff)
+#define AXM_55XX_PCX_BASE (AXM_55XX_PLATFORM_BASE + 0x4000)
+#define AXM_55XX_PCX_MAX (AXM_55XX_PCX_BASE + 0x0fff)
+#define AXM_55XX_MEMC_BASE (AXM_55XX_PLATFORM_BASE + 0x8000)
+#define AXM_55XX_MEMC_MAX (AXM_55XX_MEMC_BASE + 0x0fff)
+#define AXM_55XX_PLATFORM_MAX (AXM_55XX_MEMC_MAX)
diff --git a/arch/arm/mach-axxia/perf_event_vp.c 
b/arch/arm/mach-axxia/perf_event_vp.c
new file mode 100644
index 0000000..ebd35b0
--- /dev/null
+++ b/arch/arm/mach-axxia/perf_event_vp.c
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-axxia/perf_event_vp.c
+ * included from arch/arm/mach-axxia/perf_event_platform.c
+ *
+ * Support for the LSI Axxia boards based on ARM cores.
+ *
+ * Copyright (C) 2014 LSI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+/*
+ * Generic VP
+ */
+
+static void vp_startup_init(void)
+{
+}
+
+static uint32_t vp_pmu_event_init(uint32_t event, struct perf_event *pevent)
+{
+       return 0;
+}
+
+static uint32_t vp_pmu_event_add(uint32_t event, struct perf_event *pevent)
+{
+       return 0;
+}
+
+static uint32_t vp_pmu_event_read(uint32_t event, struct perf_event *pevent,
+               int flags)
+{
+       return 0;
+}
+
+static uint32_t vp_pmu_event_del(uint32_t event, struct perf_event *pevent,
+               int flags)
+{
+       return 0;
+}
diff --git a/arch/arm/mach-axxia/rapidio.c b/arch/arm/mach-axxia/rapidio.c
new file mode 100644
index 0000000..3562375
--- /dev/null
+++ b/arch/arm/mach-axxia/rapidio.c
@@ -0,0 +1,112 @@
+/*
+ * linux/arch/arm/mach-axxia/rapidio.c
+ *
+ * Helper module for board specific RAPIDIO bus registration
+ *
+ * Copyright (C) 2013-2014 LSI Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/signal.h>
+
+#include <mach/ncr.h>
+#include <mach/rio.h>
+
+/**
+ * axxia_rapidio_board_init -
+ *   Perform board-/controller-specific initialization to support
+ *   use of RapidIO busses
+ *
+ * @dev:     [IN] RIO platform device
+ * @ndx:     [IN] Which instance of SRIOC driver needs support
+ * @port_ndx: [OUT] Which port to use for the specified controller
+ *
+ * Returns 0 on success or an error code.
+ */
+
+int
+axxia_rapidio_board_init(struct platform_device *dev, int dev_num, int 
*port_ndx)
+{
+       /* Reset the RIO port id to zero for this device */
+       void __iomem *gpreg_base = ioremap(0x2010094000, 0x1000);
+       unsigned long reg = 0;
+
+       if (gpreg_base == NULL)
+               return -EFAULT;
+
+       reg = inl((unsigned long int)(gpreg_base + 0x60));
+
+       reg &= ~(0xf << (dev_num * 4));
+
+       outl_p(reg, (unsigned long int)(gpreg_base + 0x60));
+
+       (*port_ndx) = 0;
+
+       /* Verify that this device is actually enabled */
+       if (NULL !=
+           of_find_compatible_node(NULL, NULL, "lsi,axm5500-amarillo")) {
+               ncr_read(NCP_REGION_ID(0x115, 0), 0x23c, 4, &reg);
+
+               if ((reg & (1 << (21+(dev_num*4)))) == 0) {
+                       dev_dbg(&dev->dev, "%s: SRIO%d link not ready\n",
+                               dev->dev.of_node->full_name, dev_num);
+                       return -ENXIO;
+               }
+       }
+
+       iounmap(gpreg_base);
+
+       return 0;
+}
+
+/**
+ * axxia_rio_fault -
+ *   Intercept SRIO bus faults due to unimplemented register locations.
+ *   Return 0 to keep 'reads' alive.
+ */
+
+static int
+axxia_rio_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+       /* unsigned long pc = instruction_pointer(regs); */
+       /* unsigned long instr = *(unsigned long *)pc; */
+       return 0;
+}
+
+/**
+ * axxia_rapidio_init -
+ *   Perform board-specific initialization to support use of RapidIO busses
+ *
+ * Returns 0 on success or an error code.
+ */
+int __init
+axxia_rapidio_init(void)
+{
+       hook_fault_code(0x11, axxia_rio_fault, SIGBUS, 0,
+                       "asynchronous external abort");
+
+       return 0;
+}
-- 
1.7.9.5

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to