[linux-yocto] [PATCH 26/30] arm/mach-axxia: Same build for HW and simlation and DDR Retention Reset and clock init.

Charlie Paul cpaul.windriver at gmail.com
Thu May 1 08:29:48 PDT 2014


From: John Jacques <john.jacques at lsi.com>

Added a flush of the L3 cache before initiating a DDR retention
reset.

In some tests, a data synchronization barrier is needed
after turning the L3 cache back on (part of the L3 cache
flush process).  Without the barrier, resets sometimes fail.

Removed local "kill_time" function; now uses udelay().

Removed the config ARCH_AXXIA_SIM, that used to identify builds for simulator.
The same build can now be run on both hardware and simulation platforms, using
different DTBs.

Handle minor difference in clock config in simulator and read hardware.

By default, the simulator only supports 4 cores; the axm55xxsim.dts
device tree now reflects that.  It is not difficult to support all
16 cores; a device tree for that, axm55xxsim16.dts, is provided for
that as well.

Signed-off-by: Anders Berg <anders.berg at lsi.com>
Signed-off-by: Michael Bringmann <michael.bringmann at lsi.com>
Signed-off-by: John Jacques <john.jacques at lsi.com>
---
 arch/arm/Makefile                   |    3 -
 arch/arm/boot/dts/axm-sim.dts       |  403 --------------------------------
 arch/arm/boot/dts/axm55xx.dts       |   11 +
 arch/arm/boot/dts/axm55xxsim.dts    |   94 ++------
 arch/arm/boot/dts/axm55xxsim16.dts  |  439 +++++++++++++++++++++++++++++++++++
 arch/arm/include/asm/spinlock.h     |    2 +-
 arch/arm/mach-axxia/Kconfig         |    3 -
 arch/arm/mach-axxia/axxia.c         |   53 +----
 arch/arm/mach-axxia/axxia.h         |    2 +-
 arch/arm/mach-axxia/clock.c         |  190 +++++----------
 arch/arm/mach-axxia/ddr_retention.c |  301 ++++++++++++++----------
 arch/arm/mach-axxia/platsmp.c       |  155 +++++--------
 arch/arm/mach-axxia/wrappers.c      |   36 ---
 drivers/misc/lsi-smmon.c            |  370 +++++++++++++----------------
 14 files changed, 939 insertions(+), 1123 deletions(-)
 delete mode 100644 arch/arm/boot/dts/axm-sim.dts
 create mode 100644 arch/arm/boot/dts/axm55xxsim16.dts

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 16a0b42..f4e233c 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -132,10 +132,7 @@ endif
 textofs-$(CONFIG_ARCH_MSM7X30) := 0x00208000
 textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
 textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
-
-ifneq ($(CONFIG_ARCH_AXXIA_SIM),y)
 textofs-$(CONFIG_ARCH_AXXIA)   := 0x00408000
-endif
 
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
diff --git a/arch/arm/boot/dts/axm-sim.dts b/arch/arm/boot/dts/axm-sim.dts
deleted file mode 100644
index bb46808..0000000
--- a/arch/arm/boot/dts/axm-sim.dts
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * arch/arm/boot/dts/axm-sim.dts
- *
- * Copyright (C) 2012 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
- */
-
-/dts-v1/;
-
-/ {
-	model = "AXM5516";
-	compatible = "arm", "lsi,axm5516";
-	interrupt-parent = <&gic>;
-	#address-cells = <2>;
-	#size-cells = <2>;
-
-	chosen { };
-
-	aliases {
-		serial0 = &axxia_serial0;
-		serial1 = &axxia_serial1;
-		serial2 = &axxia_serial2;
-		serial3 = &axxia_serial3;
-		timer   = &axxia_timers;
-	};
-
-	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		cpu at 0 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <0>;
-		};
-
-		cpu at 1 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <1>;
-		};
-
-		cpu at 2 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <2>;
-		};
-
-		cpu at 3 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <3>;
-		};
-
-		cpu at 4 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <4>;
-		};
-
-		cpu at 5 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <5>;
-		};
-
-		cpu at 6 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <6>;
-		};
-
-		cpu at 7 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <7>;
-		};
-
-		cpu at 8 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <8>;
-		};
-
-		cpu at 9 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <9>;
-		};
-
-		cpu at 10 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <10>;
-		};
-
-		cpu at 11 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <11>;
-		};
-
-		cpu at 12 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <12>;
-		};
-
-		cpu at 13 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <13>;
-		};
-
-		cpu at 14 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <14>;
-		};
-
-		cpu at 15 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <15>;
-		};
-	};
-
-	memory at 00000000 {
-		device_type = "memory";
-		reg = <0 0x00000000 0 0x40000000>;
-	};
-
-	gic: interrupt-controller at 2001001000 {
-		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
-		#interrupt-cells = <3>;
-		#address-cells = <0>;
-		interrupt-controller;
-		reg = <0x20 0x01001000 0 0x1000>,  /* gic dist base */
-		      <0x20 0x01002000 0 0x100>,   /* gic cpu base */
-		      <0x20 0x10030000 0 0x100>,   /* axm IPI mask reg base */
-		      <0x20 0x10040000 0 0x20000>; /* axm IPI send reg base */
-	};
-
-	timer {
-		compatible = "arm,armv7-timer";
-		interrupts = <1 13 0xf08>,
-			     <1 14 0xf08>;
-	};
-
-
-	gpdma at 2020140000 {
-		compatible = "lsi,dma32";
-		reg = <0x20 0x20140000 0x00 0x1000>;
-		interrupts = <0 60 4>, /* busy */
-			     <0 61 4>; /* error */
-
-		channel0 {
-			interrupts = <0 62 4>;
-		};
-
-		channel1 {
-			interrupts = <0 63 4>;
-		};
-	};
-
-	gpdma at 2020141000 {
-		status = "disabled";
-		compatible = "lsi,dma32";
-		reg = <0x20 0x20141000 0x00 0x1000>;
-		interrupts = <0 64 4>, /* busy */
-			     <0 65 4>; /* error */
-
-		channel0 {
-			interrupts = <0 66 4>;
-		};
-
-		channel1 {
-			interrupts = <0 67 4>;
-		};
-	};
-
-	gpreg at 2010094000  {
-		compatible = "lsi,gpreg";
-		reg = <0x20 0x10094000 0 0x1000>;
-	};
-
-	ethernet at 201100000000 {
-		compatible = "smsc,lan91c111";
-		device_type = "network";
-		reg = <0x20 0x11000000 0 0x10000>;
-		interrupts = <0 1 4>;
-		phy-mode = "mii";
-		reg-io-width = <4>;
-		smsc,irq-active-high;
-		smsc,irq-push-pull;
-	};
-
-        amba {
-		compatible = "arm,amba-bus";
-		#address-cells = <2>;
-		#size-cells = <2>;
-		ranges;
-
-		mmci at 020101E0000 {
-			compatible = "arm,pl180", "arm,primecell";
-			reg = <0x20 0x101E0000 0x00 0x1000>;
-			interrupts = <0 222 4>,
-				     <0 223 4>;
-		};
-
-		axxia_serial0: uart at 2010080000 {
-			compatible = "arm,pl011", "arm,primecell";
-			reg = <0x20 0x10080000 0x00 0x1000>;
-			interrupts = <0 56 4>;
-		};
-
-		axxia_serial1: uart at 2010081000 {
-			compatible = "arm,pl011", "arm,primecell";
-			reg = <0x20 0x10081000 0x00 0x1000>;
-			interrupts = <0 57 4>;
-		};
-
-		axxia_serial2: uart at 2010082000 {
-			compatible = "arm,pl011", "arm,primecell";
-			reg = <0x20 0x10082000 0x00 0x1000>;
-			interrupts = <0 58 4>;
-		};
-
-		axxia_serial3: uart at 2010083000 {
-			compatible = "arm,pl011", "arm,primecell";
-			reg = <0x20 0x10083000 0x00 0x1000>;
-			interrupts = <0 59 4>;
-		};
-
-		axxia_timers: timer at 2010091000 {
-			compatible = "arm,sp804", "arm,primecell";
-			reg = <0x20 0x10091000 0 0x1000>;
-			interrupts = <0 47 4>,
-				     <0 48 4>,
-				     <0 49 4>,
-				     <0 50 4>,
-				     <0 51 4>,
-				     <0 52 4>,
-				     <0 53 4>,
-				     <0 54 4>;
-		};
-
-		gpio at 2010092000 {
-			compatible = "arm,pl061", "arm,primecell";
-			reg = <0x20 0x10092000 0 0x1000>;
-			interrupts = <0 10 4>,
-				     <0 11 4>,
-				     <0 12 4>,
-				     <0 13 4>,
-				     <0 14 4>,
-				     <0 15 4>,
-				     <0 16 4>,
-				     <0 17 4>;
-		};
-
-		gpio at 2010093000 {
-			compatible = "arm,pl061", "arm,primecell";
-			reg = <0x20 0x10093000 0x00 0x1000>;
-			interrupts = <0 18 4>;
-		};
-
-		ssp at 2010088000 {
-			compatible = "arm,pl022", "arm,primecell";
-			reg = <0x20 0x10088000 0x00 0x1000>;
-			interrupts = <0 42 4>;
-		};
-
-	};
-
-    PCIE0: pciex at 0xf0120000 {
-                compatible = "lsi,plb-pciex";
-                device_type = "pci";
-                enabled = <0>;
-                plx = <0>;
-                primary;
-                port = <0>;
-                #interrupt-cells = <1>;
-                #size-cells = <2>;
-                #address-cells = <3>;
-                /* config space access MPAGE7 registers*/
-                reg = < 0x30 0x38000000 0x0 0x01000000
-                0x20 0x20120000 0x0 0x00008000 >;
-                bus-range = <0 0x0f>;
-                /* Outbound ranges */
-                /* < <3-cell PCI addr> <2-cell CPU (PLB) addr> <2-cell size> > *
-/
-                ranges = <0x03000000 0x00000000 0xa0000000
-                          0x30 0x00000000
-                          0x00 0x10000000>;
-                /* Inbound ranges */
-                /* < <3-cell PCI addr> <2-cell CPU addr> <2-cell size> > */
-                dma-ranges = <0x03000000 0x00000000 0xa0000000
-                              0x00 0x00000000
-                              0x00 0x10000000>;
-                    interrupt-parent = <&gic>;
-                interrupts = <29 2>;
-                interrupt-map-mask = <0000 0 0 7>;
-                interrupt-map = <
-                        /* <3-cell dev> <irq#> <prnt> <2-cell prnt IRQ/sense> */
-                        0000 0 0 1 &gic 29 2
-                        0000 0 0 2 &gic 29 2
-                        0000 0 0 3 &gic 29 2
-                        0000 0 0 4 &gic 29 2
-                >;
-        };
-
-        PCIE1: pciex at 0xf0128000 {
-                compatible = "lsi,plb-pciex";
-                device_type = "pci";
-                enabled = <0>;
-                plx = <0>;
-                primary;
-                port = <1>;
-                #interrupt-cells = <1>;
-                #size-cells = <2>;
-                #address-cells = <3>;
-                /* config space access MPAGE7 registers*/
-                reg = <0x30 0x78000000 0x0 0x01000000
-                       0x20 0x20128000 0x0 0x00008000 >;
-                bus-range = <0 0x0f>;
-                /* Outbound ranges */
-                /* < <3-cell PCI addr> <2-cell CPU (PLB) addr> <2-cell size> > */
-                ranges = <0x03000000 0x00000000 0xa0000000
-                          0x30 0x40000000
-                          0x00 0x10000000>;
-                /* Inbound ranges */
-                /* < <3-cell PCI addr> <2-cell CPU addr> <2-cell size> > */
-                dma-ranges = <0x03000000 0x00000000 0xb0000000
-                             0x00 0x00000000
-                              0x00 0x10000000>;
-                interrupt-parent = <&gic>;
-                interrupts = <72 2>;
-                interrupt-map-mask = <0000 0 0 7>;
-                interrupt-map = <
-                        /* <3-cell dev> <irq#> <prnt> <2-cell prnt IRQ/sense> */
-                        0000 0 0 1 &gic 72 2
-                        0000 0 0 2 &gic 72 2
-                        0000 0 0 3 &gic 72 2
-                        0000 0 0 4 &gic 72 2
-                >;
-        };
-
-        PCIE2: pciex at 0xf0130000 {
-                compatible = "lsi,plb-pciex";
-                device_type = "pci";
-                enabled = <0>;
-                plx = <0>;
-                primary;
-                port = <2>;
-                #interrupt-cells = <1>;
-                #size-cells = <2>;
-                #address-cells = <3>;
-                /* config space access MPAGE7 registers*/
-                reg = <0x30 0xb8000000 0x0 0x01000000
-                       0x20 0x20130000 0x0 0x00008000 >;
-                bus-range = <0 0x0f>;
-                /* Outbound ranges */
-                /* < <3-cell PCI addr> <2-cell CPU (PLB) addr> <2-cell size> > */
-                ranges = <0x03000000 0x00000000 0xa0000000
-                          0x30 0x80000000
-                          0x00 0x10000000>;
-                /* Inbound ranges */
-                /* < <3-cell PCI addr> <2-cell CPU addr> <2-cell size> > */
-                dma-ranges = <0x03000000 0x00000000 0xc0000000
-                              0x00 0x00000000
-                              0x00 0x10000000>;
-
-                interrupt-parent = <&gic>;
-                interrupts = <73 2>;
-                interrupt-map-mask = <0000 0 0 7>;
-                interrupt-map = <
-                        /* <3-cell dev> <irq#> <prnt> <2-cell prnt IRQ/sense> */
-                        0000 0 0 1 &gic 73 2
-                        0000 0 0 2 &gic 73 2
-                        0000 0 0 3 &gic 73 2
-                        0000 0 0 4 &gic 73 2
-                >;
-        };
-};
-
-/*
-  Local Variables:
-  mode: C
-  End:
-*/
diff --git a/arch/arm/boot/dts/axm55xx.dts b/arch/arm/boot/dts/axm55xx.dts
index f0b325d..1cba111 100644
--- a/arch/arm/boot/dts/axm55xx.dts
+++ b/arch/arm/boot/dts/axm55xx.dts
@@ -195,6 +195,17 @@
 			     <1 14 0xf08>;
 	};
 
+	sm0 at 00220000 {
+		compatible = "lsi,smmon";
+		reg = <0 0x00220000 0 0x1000>;
+		interrupts = <0 192 4>;
+	};
+
+	sm1 at 00220000 {
+		compatible = "lsi,smmon";
+		reg = <0 0x000f0000 0 0x1000>;
+		interrupts = <0 193 4>;
+	};
 
 	gpdma at 2020140000 {
 		compatible = "lsi,dma32";
diff --git a/arch/arm/boot/dts/axm55xxsim.dts b/arch/arm/boot/dts/axm55xxsim.dts
index 3a812f6..5620dcb 100644
--- a/arch/arm/boot/dts/axm55xxsim.dts
+++ b/arch/arm/boot/dts/axm55xxsim.dts
@@ -20,9 +20,11 @@
 
 /dts-v1/;
 
+/memreserve/ 0x00000000 0x00400000;
+
 / {
 	model = "AXM5516";
-	compatible = "arm", "lsi,axm5516";
+	compatible = "arm", "lsi,axm5516-sim";
 	interrupt-parent = <&gic>;
 	#address-cells = <2>;
 	#size-cells = <2>;
@@ -30,11 +32,9 @@
 	chosen { };
 
 	aliases {
-		serial0 = &axxia_serial0;
-		serial1 = &axxia_serial1;
-		serial2 = &axxia_serial2;
-		serial3 = &axxia_serial3;
-		timer   = &axxia_timers;
+		serial0   = &axxia_serial0;
+		timer	  = &axxia_timers;
+		ethernet0 = &axxia_net0;
 	};
 
 	cpus {
@@ -45,96 +45,45 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a15";
 			reg = <0>;
+			cpu-release-addr = <0x10000020>;
 		};
 
 		cpu at 1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a15";
 			reg = <1>;
+			cpu-release-addr = <0x10000020>;
 		};
 
 		cpu at 2 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a15";
 			reg = <2>;
+			cpu-release-addr = <0x10000020>;
 		};
 
 		cpu at 3 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a15";
 			reg = <3>;
+			cpu-release-addr = <0x10000020>;
 		};
+	};
 
-		cpu at 4 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <4>;
-		};
-
-		cpu at 5 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <5>;
-		};
-
-		cpu at 6 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <6>;
-		};
-
-		cpu at 7 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <7>;
-		};
-
-		cpu at 8 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <8>;
-		};
-
-		cpu at 9 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <9>;
-		};
-
-		cpu at 10 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <10>;
-		};
-
-		cpu at 11 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <11>;
-		};
-
-		cpu at 12 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <12>;
-		};
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <0>;
 
-		cpu at 13 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <13>;
+		cpu {
+			frequency = <1400000000>;
 		};
 
-		cpu at 14 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <14>;
+		peripheral {
+			frequency = <400000000>;
 		};
 
-		cpu at 15 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <15>;
+		emmc {
+			frequency = <25000000>;
 		};
 	};
 
@@ -177,7 +126,6 @@
 	};
 
 	gpdma at 2020141000 {
-		status = "disabled";
 		compatible = "lsi,dma32";
 		reg = <0x20 0x20141000 0x00 0x1000>;
 		interrupts = <0 64 4>, /* busy */
@@ -203,7 +151,7 @@
 		interrupts = <0 45 4>;
 	};
 
-	ethernet at 201100000000 {
+	axxia_net0: ethernet at 201100000000 {
 		compatible = "smsc,lan91c111";
 		device_type = "network";
 		reg = <0x20 0x11000000 0 0x10000>;
diff --git a/arch/arm/boot/dts/axm55xxsim16.dts b/arch/arm/boot/dts/axm55xxsim16.dts
new file mode 100644
index 0000000..0b6277a
--- /dev/null
+++ b/arch/arm/boot/dts/axm55xxsim16.dts
@@ -0,0 +1,439 @@
+/*
+ * arch/arm/boot/dts/axm-sim.dts
+ *
+ * Copyright (C) 2012 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
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x00000000 0x00400000;
+
+/ {
+	model = "AXM5516";
+	compatible = "arm", "lsi,axm5516-sim";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen { };
+
+	aliases {
+		serial0   = &axxia_serial0;
+		timer	  = &axxia_timers;
+		ethernet0 = &axxia_net0;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <1>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <2>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <3>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 4 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <4>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 5 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <5>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 6 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <6>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 7 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <7>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 8 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <8>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 9 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <9>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 10 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <10>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 11 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <11>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 12 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <12>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 13 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <13>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 14 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <14>;
+			cpu-release-addr = <0x10000020>;
+		};
+
+		cpu at 15 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <15>;
+			cpu-release-addr = <0x10000020>;
+		};
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu {
+			frequency = <1400000000>;
+		};
+
+		peripheral {
+			frequency = <400000000>;
+		};
+
+		emmc {
+			frequency = <25000000>;
+		};
+	};
+
+	memory at 00000000 {
+		device_type = "memory";
+		reg = <0 0x00000000 0 0x40000000>;
+	};
+
+	gic: interrupt-controller at 2001001000 {
+		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x20 0x01001000 0 0x1000>,  /* gic dist base */
+		      <0x20 0x01002000 0 0x100>,   /* gic cpu base */
+		      <0x20 0x10030000 0 0x100>,   /* axm IPI mask reg base */
+		      <0x20 0x10040000 0 0x20000>; /* axm IPI send reg base */
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <1 13 0xf08>,
+			     <1 14 0xf08>;
+	};
+
+
+	gpdma at 2020140000 {
+		compatible = "lsi,dma32";
+		reg = <0x20 0x20140000 0x00 0x1000>;
+		interrupts = <0 60 4>, /* busy */
+			     <0 61 4>; /* error */
+
+		channel0 {
+			interrupts = <0 62 4>;
+		};
+
+		channel1 {
+			interrupts = <0 63 4>;
+		};
+	};
+
+	gpdma at 2020141000 {
+		compatible = "lsi,dma32";
+		reg = <0x20 0x20141000 0x00 0x1000>;
+		interrupts = <0 64 4>, /* busy */
+			     <0 65 4>; /* error */
+
+		channel0 {
+			interrupts = <0 66 4>;
+		};
+
+		channel1 {
+			interrupts = <0 67 4>;
+		};
+	};
+
+	gpreg at 2010094000  {
+		compatible = "lsi,gpreg";
+		reg = <0x20 0x10094000 0 0x1000>;
+	};
+
+	mtc at 2010098000 {
+		compatible = "lsi,mtc";
+		reg = <0x20 0x10098000 0 0x3000>;
+		interrupts = <0 45 4>;
+	};
+
+	axxia_net0: ethernet at 201100000000 {
+		compatible = "smsc,lan91c111";
+		device_type = "network";
+		reg = <0x20 0x11000000 0 0x10000>;
+		interrupts = <0 1 4>;
+		phy-mode = "mii";
+		reg-io-width = <4>;
+		smsc,irq-active-high;
+		smsc,irq-push-pull;
+	};
+
+        amba {
+		compatible = "arm,amba-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		mmci at 020101E0000 {
+			compatible = "arm,pl180", "arm,primecell";
+			reg = <0x20 0x101E0000 0x00 0x1000>;
+			interrupts = <0 222 4>,
+				     <0 223 4>;
+		};
+
+		axxia_serial0: uart at 2010080000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0x20 0x10080000 0x00 0x1000>;
+			interrupts = <0 56 4>;
+		};
+
+		axxia_serial1: uart at 2010081000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0x20 0x10081000 0x00 0x1000>;
+			interrupts = <0 57 4>;
+		};
+
+		axxia_serial2: uart at 2010082000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0x20 0x10082000 0x00 0x1000>;
+			interrupts = <0 58 4>;
+		};
+
+		axxia_serial3: uart at 2010083000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0x20 0x10083000 0x00 0x1000>;
+			interrupts = <0 59 4>;
+		};
+
+		axxia_timers: timer at 2010091000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0x20 0x10091000 0 0x1000>;
+			interrupts = <0 46 4>,
+				     <0 47 4>,
+				     <0 48 4>,
+				     <0 49 4>,
+				     <0 50 4>,
+				     <0 51 4>,
+				     <0 52 4>,
+				     <0 53 4>;
+		};
+
+		gpio at 2010092000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0x20 0x10092000 0 0x1000>;
+			interrupts = <0 10 4>,
+				     <0 11 4>,
+				     <0 12 4>,
+				     <0 13 4>,
+				     <0 14 4>,
+				     <0 15 4>,
+				     <0 16 4>,
+				     <0 17 4>;
+		};
+
+		gpio at 2010093000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0x20 0x10093000 0x00 0x1000>;
+			interrupts = <0 18 4>;
+		};
+
+		ssp at 2010088000 {
+			compatible = "arm,pl022", "arm,primecell";
+			reg = <0x20 0x10088000 0x00 0x1000>;
+			interrupts = <0 42 4>;
+		};
+
+	};
+
+    PCIE0: pciex at 0x3000000000 {
+                compatible = "lsi,plb-pciex";
+                device_type = "pci";
+		status = "ok";
+                port = <0>;
+                #interrupt-cells = <1>;
+                #size-cells = <2>;
+                #address-cells = <3>;
+                /* config space access MPAGE7 registers*/
+                reg = < 0x30 0x38000000 0x0 0x01000000
+                0x20 0x20120000 0x0 0x00008000 >;
+                /* Outbound ranges */
+                /* < <3-cell PCI addr> <2-cell CPU (PLB) addr> <2-cell size> >*/
+                ranges = <0x03000000 0x00000000 0xa0000000
+                          0x30 0x00000000
+                          0x00 0x20000000>;
+                /* Inbound ranges */
+                /* < <3-cell PCI addr> <2-cell CPU addr> <2-cell size> > */
+                dma-ranges = <0x03000000 0x00000000 0x00000000
+                              0x00 0x00000000
+                              0x00 0x40000000>;
+	        interrupts = <0 68 4>,
+                             <0 73 4>,
+                             <0 74 4>,
+                             <0 75 4>,
+                             <0 76 4>,
+                             <0 77 4>,
+                             <0 78 4>,
+                             <0 79 4>,
+                             <0 80 4>,
+                             <0 81 4>,
+                             <0 82 4>,
+                             <0 83 4>,
+                             <0 84 4>,
+                             <0 85 4>,
+                             <0 86 4>,
+                             <0 87 4>,
+                             <0 88 4>;
+        };
+
+        PCIE1: pciex at 0x3080000000 {
+                compatible = "lsi,plb-pciex";
+                device_type = "pci";
+		status = "ok";
+                port = <1>;
+                #interrupt-cells = <1>;
+                #size-cells = <2>;
+                #address-cells = <3>;
+                /* config space access MPAGE7 registers*/
+                reg = <0x30 0xb8000000 0x0 0x01000000
+                       0x20 0x20130000 0x0 0x00008000 >;
+                /* Outbound ranges */
+                /* < <3-cell PCI addr> <2-cell CPU (PLB) addr> <2-cell size> > */
+                ranges = <0x03000000 0x00000000 0xa0000000
+                          0x30 0x80000000
+                          0x00 0x20000000>;
+                /* Inbound ranges */
+                /* < <3-cell PCI addr> <2-cell CPU addr> <2-cell size> > */
+                dma-ranges = <0x03000000 0x00000000 0x00000000
+                              0x00 0x00000000
+                              0x00 0x40000000>;
+	        interrupts = <0 70 4>;
+        };
+
+        I2C0: i2c at 0x02010084000 {
+                compatible = "lsi,api2c";
+                device_type = "i2c";
+                enabled = <0>;
+                port = <0>;
+                /* bus_name = "auto"; */
+                /* bus = <2>; */
+                reg = <0x20 0x10084000 0x00 0x1000>;
+		interrupts = <0 19 4>;
+        };
+
+        I2C1: i2c at 0x02010085000 {
+                compatible = "lsi,api2c";
+                device_type = "i2c";
+                enabled = <0>;
+                port = <1>;
+                /* bus_name = "auto"; */
+                /* bus = <3>; */
+                reg = <0x20 0x10085000 0x00 0x1000>;
+		interrupts = <0 20 4>;
+        };
+
+        I2C2: i2c at 0x02010086000 {
+                compatible = "lsi,api2c";
+                device_type = "i2c";
+                enabled = <0>;
+                port = <2>;
+                /* bus_name = "auto"; */
+                /* bus = <4>; */
+                reg = <0x20 0x10086000 0x00 0x1000>;
+		interrupts = <0 21 4>;
+        };
+
+        SMB: i2c at 0x02010087000 {
+                compatible = "lsi,api2c";
+                device_type = "i2c";
+                enabled = <0>;
+                port = <3>;
+                bus_name = "smb";
+                /* bus = <5>; */
+                reg = <0x20 0x10087000 0x00 0x1000>;
+		interrupts = <0 22 4>;
+        };
+};
+
+/*
+  Local Variables:
+  mode: C
+  End:
+*/
diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h
index 022ef90..f7feb1b 100644
--- a/arch/arm/include/asm/spinlock.h
+++ b/arch/arm/include/asm/spinlock.h
@@ -37,7 +37,7 @@
 						\
 	"nop.w"					\
 )
-#elif CONFIG_ARCH_AXXIA || CONFIG_ARCH_AXXIA_SIM
+#elif defined(CONFIG_ARCH_AXXIA)
 /* Disable use of wfe/sev in Axxia. */
 #define SEV
 #define WFE(cond)
diff --git a/arch/arm/mach-axxia/Kconfig b/arch/arm/mach-axxia/Kconfig
index 206c344..4a4922f 100644
--- a/arch/arm/mach-axxia/Kconfig
+++ b/arch/arm/mach-axxia/Kconfig
@@ -28,7 +28,4 @@ config ARCH_AXXIA_DT
 	  If your bootloader supports Flattened Device Tree based booting,
 	  say Y here.
 
-config ARCH_AXXIA_SIM
-       bool "Build for Simulation instead of Emulation or ASIC"
-
 endmenu
diff --git a/arch/arm/mach-axxia/axxia.c b/arch/arm/mach-axxia/axxia.c
index 1c1f20e..526ec98 100644
--- a/arch/arm/mach-axxia/axxia.c
+++ b/arch/arm/mach-axxia/axxia.c
@@ -58,7 +58,8 @@
 extern void axxia_ddr_retention_init(void);
 
 static const char *axxia_dt_match[] __initconst = {
-	"lsi,axm5516",		/* AXM5516 */
+	"lsi,axm5516",
+	"lsi,axm5516-sim",
 	NULL
 };
 
@@ -104,8 +105,11 @@ void __init axxia_dt_timer_init(void)
 	const char *path;
 	struct device_node *node;
 	void __iomem *base;
+	int is_sim;
 
-	axxia_init_clocks();
+	is_sim = of_find_compatible_node(NULL, NULL, "lsi,axm5516-sim") != NULL;
+
+	axxia_init_clocks(is_sim);
 
 #ifdef CONFIG_ARM_ARCH_TIMER
 	{
@@ -275,54 +279,9 @@ static struct spi_board_info spi_devs[] __initdata = {
 };
 
 
-static int
-l3_set_pstate(void __iomem *l3ctrl, unsigned int req, unsigned int act)
-{
-	static const u8 hn_f[] = {
-		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
-	};
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(hn_f); ++i) {
-		/* set state NOL3 */
-		writel(req, l3ctrl + (hn_f[i] << 16) + 0x10);
-	}
-
-	for (i = 0; i < ARRAY_SIZE(hn_f); ++i) {
-		unsigned long status;
-		int retries = 10000;
-
-		do {
-			status = readl(l3ctrl + (hn_f[i] << 16) + 0x18);
-			udelay(1);
-		} while ((0 < --retries) && (act != (status & 0xf)));
-
-		if (0 == retries)
-			return -ENODEV;
-	}
-
-	return 0;
-}
 
 void __init axxia_dt_init(void)
 {
-	void __iomem *l3ctrl;
-	void __iomem *apb2ser3_base;
-	int rc;
-
-	/* Enable L3-cache */
-#ifndef CONFIG_ARCH_AXXIA_SIM
-	l3ctrl = ioremap(0x2000000000ULL, SZ_4M);
-	if (l3ctrl) {
-		rc = l3_set_pstate(l3ctrl, 0x3, 0xc);
-		if (rc < 0)
-			pr_warn("axxia: Failed to intialize L3-cache\n");
-		iounmap(l3ctrl);
-	} else {
-		pr_warn("axxia: Failed to map L3-cache control regs\n");
-	}
-#endif
-
 	of_platform_populate(NULL, of_default_bus_match_table,
 			     axxia_auxdata_lookup, NULL);
 	pm_power_off = NULL; /* TBD */
diff --git a/arch/arm/mach-axxia/axxia.h b/arch/arm/mach-axxia/axxia.h
index 1c8e800..7109c0b 100644
--- a/arch/arm/mach-axxia/axxia.h
+++ b/arch/arm/mach-axxia/axxia.h
@@ -1,5 +1,5 @@
 #ifndef _AXXIA_H
 
-void axxia_init_clocks(void);
+void axxia_init_clocks(int is_sim);
 
 #endif
diff --git a/arch/arm/mach-axxia/clock.c b/arch/arm/mach-axxia/clock.c
index 4232277..c8c28cf 100644
--- a/arch/arm/mach-axxia/clock.c
+++ b/arch/arm/mach-axxia/clock.c
@@ -17,9 +17,6 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 
-#define AXXIA_CPU_CLOCK 1400000000
-#define AXXIA_SYS_CLOCK  450000000
-#define AXXIA_DDR_CLOCK 1866000000
 
 #define clk_register_clkdev(_clk, _conid, _devfmt, ...) \
 	do { \
@@ -28,154 +25,85 @@
 		clkdev_add(cl); \
 	} while (0)
 
-#ifdef CONFIG_ARCH_AXXIA_SIM
+enum clk_ids {
+	clk_cpu,
+	clk_per,
+	clk_mmc,
+	clk_apb,
+	clk_1mhz,
+	NR_CLK_IDS
+};
 
-void __init
-axxia_init_clocks(void)
+static struct dt_clk_lookup {
+	const char  *path;
+	const char  *name;
+	enum clk_ids id;
+	u32          default_freq;
+} dt_clks[] = {
+	{"/clocks/cpu",        "clk_cpu", clk_cpu, 1400000000 },
+	{"/clocks/peripheral", "clk_per", clk_per,  200000000 },
+	{"/clocks/emmc",       "clk_mmc", clk_mmc,  200000000 },
+};
+
+static struct clk *clk[NR_CLK_IDS];
+
+static void axxia_register_clks(void)
 {
-	struct clk *clk;
 	int i;
 
-	/* APB clock dummy */
-	clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL,
-				      CLK_IS_ROOT, AXXIA_SYS_CLOCK/2);
-	clk_register_clkdev(clk, "apb_pclk", NULL);
-
-	/* CPU core clock (1400MHz) from CPU_PLL */
-	clk = clk_register_fixed_rate(NULL, "clk_cpu", NULL,
-				      CLK_IS_ROOT, AXXIA_CPU_CLOCK);
-
-	/* APB and System AXI clock from CPU_PLL */
-	clk = clk_register_fixed_rate(NULL, "clk_pclk", NULL,
-				      CLK_IS_ROOT, AXXIA_CPU_CLOCK/9);
-
-	/* DDR3 (interface 1) clock from SMEM1_PLL */
-	clk = clk_register_fixed_rate(NULL, "clk_smem1_2x", NULL,
-				      CLK_IS_ROOT, AXXIA_DDR_CLOCK);
-
-	/* AXIS slow peripheral clock from SMEM1_PLL. */
-	clk = clk_register_fixed_rate(NULL, "clk_per", NULL,
-				      CLK_IS_ROOT, 24000000);
-	/* PL011 UART0 */
-	clk_register_clkdev(clk, NULL, "2010080000.uart");
-	/* PL011 UART1 */
-	clk_register_clkdev(clk, NULL, "2010081000.uart");
-	/* PL011 UART2 */
-	clk_register_clkdev(clk, NULL, "2010082000.uart");
-	/* PL011 UART3 */
-	clk_register_clkdev(clk, NULL, "2010083000.uart");
-	/* I2C */
-	clk_register_clkdev(clk, NULL, "2010084000.i2c");
-	clk_register_clkdev(clk, NULL, "2010085000.i2c");
-	clk_register_clkdev(clk, NULL, "2010086000.i2c");
-	clk_register_clkdev(clk, NULL, "2010087000.i2c");
-	/* PL022 SSP */
-	clk_register_clkdev(clk, NULL, "ssp");
+	for (i = 0; i < ARRAY_SIZE(dt_clks); ++i) {
+		struct dt_clk_lookup *c = &dt_clks[i];
+		struct device_node *np = of_find_node_by_path(c->path);
+		u32 freq;
+
+		if (!np || of_property_read_u32(np, "frequency", &freq)) {
+			pr_warn("axxia: No 'frequency' in %s\n", c->path);
+			freq = c->default_freq;
+		}
+		clk[c->id] = clk_register_fixed_rate(NULL, c->name, NULL,
+						     CLK_IS_ROOT, freq);
+	}
 
-	/* Timers 1MHz clock */
-	clk = clk_register_fixed_rate(NULL, "clk_1mhz", NULL,
-				      CLK_IS_ROOT, 1000000);
-	/* SP804 timers */
-	clk_register_clkdev(clk, NULL, "sp804");
-	for (i = 0; i < 8; i++)
-		clk_register_clkdev(clk, NULL, "axxia-timer%d", i);
+	/* APB clock dummy */
+	clk[clk_apb] = clk_register_fixed_rate(NULL, "apb_pclk", NULL,
+					       CLK_IS_ROOT, 1000000);
 
-	/* Dummy MMC clk */
-	clk = clk_register_fixed_rate(NULL, "clk_mmci", NULL,
-				      CLK_IS_ROOT, 25000000);
-	/* PL180 MMCI */
-	clk_register_clkdev(clk, NULL, "mmci");
+	clk[clk_1mhz] = clk_register_fixed_rate(NULL, "clk_1mhz", NULL,
+						CLK_IS_ROOT, 1000000);
 }
 
-#else
-
-static struct of_device_id cpu_pll[] __initconst = {
-	{ .name = "/clocks/cpu", },
-	{},
-};
-
-/*
-  --------------------------------------------------------------------
-  axxia_init_clocks
-
-  Clock setup for Emulation/ASIC systems.
-*/
-
 void __init
-axxia_init_clocks(void)
+axxia_init_clocks(int is_sim)
 {
-	struct clk *clk;
 	int i;
-	struct device_node *np;
-	u32 frequency;
 
-	np = of_find_node_by_path("/clocks/cpu");
+	pr_info("axxia: init_clocks: is_sim=%d\n", is_sim);
 
-	if (np) {
-		if (of_property_read_u32(np, "frequency", &frequency))
-			printk(KERN_ERR "%d - Error!", __LINE__);
-	}
+	axxia_register_clks();
 
-	clk = clk_register_fixed_rate(NULL, "clk_cpu", NULL,
-				      CLK_IS_ROOT, frequency);
+	/* PL011 UARTs */
+	clk_register_clkdev(clk[clk_per], NULL, "2010080000.uart");
+	clk_register_clkdev(clk[clk_per], NULL, "2010081000.uart");
+	clk_register_clkdev(clk[clk_per], NULL, "2010082000.uart");
+	clk_register_clkdev(clk[clk_per], NULL, "2010083000.uart");
 
-	np = of_find_node_by_path("/clocks/peripheral");
-
-	if (np) {
-		if (of_property_read_u32(np, "frequency", &frequency))
-			printk(KERN_ERR "%d - Error!", __LINE__);
-	}
-
-	clk = clk_register_fixed_rate(NULL, "clk_per", NULL,
-				      CLK_IS_ROOT, frequency);
-
-	/* PL011 UART0 */
-	clk_register_clkdev(clk, NULL, "2010080000.uart");
-	/* PL011 UART1 */
-	clk_register_clkdev(clk, NULL, "2010081000.uart");
-	/* PL011 UART2 */
-	clk_register_clkdev(clk, NULL, "2010082000.uart");
-	/* PL011 UART3 */
-	clk_register_clkdev(clk, NULL, "2010083000.uart");
 	/* PL022 SSP */
-	clk_register_clkdev(clk, NULL, "ssp");
+	clk_register_clkdev(clk[clk_per], NULL, "ssp");
+
 	/* I2C */
-	clk_register_clkdev(clk, NULL, "2010084000.i2c");
-	clk_register_clkdev(clk, NULL, "2010085000.i2c");
-	clk_register_clkdev(clk, NULL, "2010086000.i2c");
-	clk_register_clkdev(clk, NULL, "2010087000.i2c");
+	clk_register_clkdev(clk[clk_per], NULL, "2010084000.i2c");
+	clk_register_clkdev(clk[clk_per], NULL, "2010085000.i2c");
+	clk_register_clkdev(clk[clk_per], NULL, "2010086000.i2c");
+	clk_register_clkdev(clk[clk_per], NULL, "2010087000.i2c");
+
 	/* SP804 timers */
-	clk_register_clkdev(clk, NULL, "sp804");
+	clk_register_clkdev(clk[is_sim ? clk_1mhz : clk_per], NULL, "sp804");
 	for (i = 0; i < 8; i++)
-		clk_register_clkdev(clk, NULL, "axxia-timer%d", i);
-
-	np = of_find_node_by_path("/clocks/emmc");
-
-	if (np) {
-		if (of_property_read_u32(np, "frequency", &frequency))
-			printk(KERN_ERR "%d - Error!", __LINE__);
-	}
-
-	clk = clk_register_fixed_rate(NULL, "clk_mmci", NULL,
-				      CLK_IS_ROOT, frequency);
+		clk_register_clkdev(clk[is_sim ? clk_1mhz : clk_per],
+				    NULL, "axxia-timer%d", i);
 
 	/* PL180 MMCI */
-	clk_register_clkdev(clk, NULL, "mmci");
-
-	/* APB clock dummy */
-	clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL,
-				      CLK_IS_ROOT, AXXIA_SYS_CLOCK/2);
-	clk_register_clkdev(clk, "apb_pclk", NULL);
-
-	/* APB and System AXI clock from CPU_PLL */
-	clk = clk_register_fixed_rate(NULL, "clk_pclk", NULL,
-				      CLK_IS_ROOT, AXXIA_CPU_CLOCK/9);
+	clk_register_clkdev(clk[clk_mmc], NULL, "mmci");
 
-	/* DDR3 (interface 1) clock from SMEM1_PLL */
-	clk = clk_register_fixed_rate(NULL, "clk_smem1_2x", NULL,
-				      CLK_IS_ROOT, AXXIA_DDR_CLOCK);
-
-	return;
+	clk_register_clkdev(clk[clk_apb], "apb_pclk", NULL);
 }
-
-#endif
diff --git a/arch/arm/mach-axxia/ddr_retention.c b/arch/arm/mach-axxia/ddr_retention.c
index 1e4ba34..a17f970 100644
--- a/arch/arm/mach-axxia/ddr_retention.c
+++ b/arch/arm/mach-axxia/ddr_retention.c
@@ -21,70 +21,123 @@
  */
 
 #include <linux/module.h>
-
-#ifndef CONFIG_ARCH_AXXIA_SIM
-
 #include <linux/cpu.h>
 #include <linux/reboot.h>
 #include <linux/syscore_ops.h>
-
 #include <linux/proc_fs.h>
-
+#include <linux/delay.h>
+#include <linux/of.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
-+#include <mach/ncr.h>
+#include <mach/ncr.h>
 
-extern void flush_l3(void);
-static void __iomem *nca_address;
-static void __iomem *apb_base;
-
-static inline void kill_time(int cnt)
-{
-	while (cnt--)
-		;
-}
+static void __iomem *nca;
+static void __iomem *apb;
+static void __iomem *dickens;
 
 unsigned long ncp_caal_regions_acp55xx[] = {
-	NCP_REGION_ID(0x0b, 0x05),	/* SPPV2   */
-	NCP_REGION_ID(0x0c, 0x05),	/* SED     */
-	NCP_REGION_ID(0x0e, 0x05),	/* DPI_HFA */
-	NCP_REGION_ID(0x14, 0x05),	/* MTM     */
-	NCP_REGION_ID(0x14, 0x0a),	/* MTM2    */
-	NCP_REGION_ID(0x15, 0x00),	/* MME     */
-	NCP_REGION_ID(0x16, 0x05),	/* NCAV2   */
-	NCP_REGION_ID(0x16, 0x10),	/* NCAV22  */
-	NCP_REGION_ID(0x17, 0x05),	/* EIOAM1  */
-	NCP_REGION_ID(0x19, 0x05),	/* TMGR    */
-	NCP_REGION_ID(0x1a, 0x05),	/* MPPY    */
-	NCP_REGION_ID(0x1a, 0x23),	/* MPPY2   */
-	NCP_REGION_ID(0x1a, 0x21),	/* MPPY3   */
-	NCP_REGION_ID(0x1b, 0x05),	/* PIC     */
-	NCP_REGION_ID(0x1c, 0x05),	/* PAB     */
-	NCP_REGION_ID(0x1f, 0x05),	/* EIOAM0  */
-	NCP_REGION_ID(0x31, 0x05),	/* ISB     */
-	NCP_REGION_ID(0x28, 0x05),	/* EIOASM0 */
-	NCP_REGION_ID(0x29, 0x05),	/* EIOASM1 */
-	NCP_REGION_ID(0x2a, 0x05),	/* EIOAS2  */
-	NCP_REGION_ID(0x2b, 0x05),	/* EIOAS3  */
-	NCP_REGION_ID(0x2c, 0x05),	/* EIOAS4  */
-	NCP_REGION_ID(0x2d, 0x05),	/* EIOAS5  */
-	NCP_REGION_ID(0x32, 0x05),	/* ISBS    */
+	NCP_REGION_ID(0x0b, 0x05),      /* SPPV2   */
+	NCP_REGION_ID(0x0c, 0x05),      /* SED     */
+	NCP_REGION_ID(0x0e, 0x05),      /* DPI_HFA */
+	NCP_REGION_ID(0x14, 0x05),      /* MTM     */
+	NCP_REGION_ID(0x14, 0x0a),      /* MTM2    */
+	NCP_REGION_ID(0x15, 0x00),      /* MME     */
+	NCP_REGION_ID(0x16, 0x05),      /* NCAV2   */
+	NCP_REGION_ID(0x16, 0x10),      /* NCAV22  */
+	NCP_REGION_ID(0x17, 0x05),      /* EIOAM1  */
+	NCP_REGION_ID(0x19, 0x05),      /* TMGR    */
+	NCP_REGION_ID(0x1a, 0x05),      /* MPPY    */
+	NCP_REGION_ID(0x1a, 0x23),      /* MPPY2   */
+	NCP_REGION_ID(0x1a, 0x21),      /* MPPY3   */
+	NCP_REGION_ID(0x1b, 0x05),      /* PIC     */
+	NCP_REGION_ID(0x1c, 0x05),      /* PAB     */
+	NCP_REGION_ID(0x1f, 0x05),      /* EIOAM0  */
+	NCP_REGION_ID(0x31, 0x05),      /* ISB     */
+	NCP_REGION_ID(0x28, 0x05),      /* EIOASM0 */
+	NCP_REGION_ID(0x29, 0x05),      /* EIOASM1 */
+	NCP_REGION_ID(0x2a, 0x05),      /* EIOAS2  */
+	NCP_REGION_ID(0x2b, 0x05),      /* EIOAS3  */
+	NCP_REGION_ID(0x2c, 0x05),      /* EIOAS4  */
+	NCP_REGION_ID(0x2d, 0x05),      /* EIOAS5  */
+	NCP_REGION_ID(0x32, 0x05),      /* ISBS    */
 	NCP_REGION_ID(0xff, 0xff)
 };
 
-static void quiesce_vp_engine(void)
+/*
+  ------------------------------------------------------------------------------
+  flush_l3
+
+  This is NOT a general function to flush the L3 cache.  There are a number of
+  assumptions that are not usually true...
+
+  1) All other cores are " quiesced".
+  2) There is no need to worry about preemption or interrupts.
+*/
+
+static void
+flush_l3(void)
 {
-	unsigned long *pCnalRegions = ncp_caal_regions_acp55xx;
-	unsigned long *pRegion;
+
+	unsigned long hnf_offsets[] = {
+		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
+	};
+
+	int i;
+	unsigned long status;
+	int retries;
+
+	for (i = 0; i < (sizeof(hnf_offsets) / sizeof(unsigned long)); ++i)
+		writel(0x0, dickens + (0x10000 * hnf_offsets[i]) + 0x10);
+
+	for (i = 0; i < (sizeof(hnf_offsets) / sizeof(unsigned long)); ++i) {
+		retries = 10000;
+
+		do {
+			status = readl(dickens +
+				       (0x10000 * hnf_offsets[i]) + 0x18);
+			udelay(1);
+		} while ((0 < --retries) && (0x0 != (status & 0xf)));
+
+		if (0 == retries)
+			BUG();
+	}
+
+	for (i = 0; i < (sizeof(hnf_offsets) / sizeof(unsigned long)); ++i)
+		writel(0x3, dickens + (0x10000 * hnf_offsets[i]) + 0x10);
+
+	for (i = 0; i < (sizeof(hnf_offsets) / sizeof(unsigned long)); ++i) {
+		retries = 10000;
+
+		do {
+			status = readl(dickens +
+				       (0x10000 * hnf_offsets[i]) + 0x18);
+			udelay(1);
+		} while ((0 < --retries) && (0xc != (status & 0xf)));
+
+		if (0 == retries)
+			BUG();
+	}
+
+	asm volatile ("dsb" : : : "memory");
+	asm volatile ("dmb" : : : "memory");
+
+	return;
+}
+
+static void
+quiesce_vp_engine(void)
+{
+	unsigned long   *pCnalRegions = ncp_caal_regions_acp55xx;
+	unsigned long     *pRegion;
 	unsigned ort, owt;
-	unsigned long buf = 0;
-	unsigned short node, target;
-	int loop;
+	unsigned long      buf = 0;
+	unsigned short     node, target;
+	int      loop;
 
 	printk(KERN_INFO "quiescing VP engines...\n");
 	pRegion = pCnalRegions;
-	while (*pRegion != NCP_REGION_ID(0xff, 0xff)) {
 
+	while (*pRegion != NCP_REGION_ID(0xff, 0xff)) {
 		/* set read/write transaction limits to zero */
 		ncr_write(*pRegion, 0x8, 4, &buf);
 		ncr_write(*pRegion, 0xc, 4, &buf);
@@ -93,6 +146,7 @@ static void quiesce_vp_engine(void)
 
 	pRegion = pCnalRegions;
 	loop = 0;
+
 	while (*pRegion != NCP_REGION_ID(0xff, 0xff)) {
 		node = (*pRegion & 0xffff0000) >> 16;
 		target = *pRegion & 0x0000ffff;
@@ -102,14 +156,12 @@ static void quiesce_vp_engine(void)
 
 		if ((ort == 0) && (owt == 0)) {
 			/* this engine has been quiesced, move on to the next */
-			printk(KERN_INFO "quiesced region 0x%02x.0x%02x\n",
-				node, target);
+			printk(KERN_INFO "quiesced region 0x%02x.0x%02x\n", node, target);
 			pRegion++;
 		} else {
 			if (loop++ > 10000) {
-				printk(KERN_INFO
-					"Unable to quiesce region 0x%02x.0x%02x ort=0x%x, owt=0x%x\n",
-				     node, target, ort, owt);
+				printk(KERN_INFO "Unable to quiesce region 0x%02x.0x%02x rt=0x%x, owt=0x%x\n",
+						node, target, ort, owt);
 				pRegion++;
 				loop = 0;
 				continue;
@@ -120,13 +172,15 @@ static void quiesce_vp_engine(void)
 	return;
 }
 
-static inline void ncp_ddr_shutdown(void)
+static inline void
+ncp_ddr_shutdown(void)
 {
 	unsigned long value;
 	int loop = 1;
-	unsigned long cdr2[2] = { 0x00002200, 0x00000f00 };
+	unsigned long cdr2[2] = {0x00002200, 0x00000f00};
 	int smId;
 
+
 	/*
 	 * Most of the PIO command has already been set up.
 	 * issue config ring write - enter DDR self-refresh mode
@@ -134,89 +188,98 @@ static inline void ncp_ddr_shutdown(void)
 
 	for (smId = 0; smId < 2; smId++) {
 		/* CDR2 - Node.target */
-		ncr_register_write(cdr2[smId],
-				   (unsigned *)(nca_address + 0xf8));
+		ncr_register_write(cdr2[smId], (unsigned *) (nca + 0xf8));
 		/* CDR0 - */
-		ncr_register_write(0x80050003,
-				   (unsigned *)(nca_address + 0xf0));
+		ncr_register_write(0x80050003, (unsigned *) (nca + 0xf0));
 		do {
-			kill_time(100000);
-			value =
-			    ncr_register_read((unsigned *)(nca_address + 0xf0));
+			value = ncr_register_read((unsigned *)
+						  (nca + 0xf0));
 		} while ((0x80000000UL & value));
 	}
 
 	/* check interrupt status for completion */
 	/* CDR1 - word offset 0x104 (byte offset 0x410) */
-	ncr_register_write(0x00000104, (unsigned *)(nca_address + 0xf4));
+	ncr_register_write(0x00000104, (unsigned *) (nca + 0xf4));
 
 	for (smId = 0; smId < 2; smId++) {
 		/* CDR2 - Node.target */
-		ncr_register_write(cdr2[smId],
-				   (unsigned *)(nca_address + 0xf8));
+		ncr_register_write(cdr2[smId], (unsigned *) (nca + 0xf8));
 		do {
-			ncr_register_write(loop,
-					   (unsigned *)(nca_address + 0x11f0));
+			ncr_register_write(loop, (unsigned *)
+					   (nca + 0x11f0));
 
 			/* issue config ring read */
-			ncr_register_write(0x80040003,
-					   (unsigned *)(nca_address + 0xf0));
+			ncr_register_write(0x80040003, (unsigned *)
+					   (nca + 0xf0));
 			do {
-				kill_time(100000);
-				value =
-				    ncr_register_read((unsigned *)(nca_address +
-								   0xf0));
+				value = ncr_register_read((unsigned *)
+							  (nca + 0xf0));
 			} while ((0x80000000UL & value));
 
-			value =
-			    ncr_register_read((unsigned *)(nca_address +
-							   0x1000));
-			ncr_register_write(value,
-					   (unsigned *)(nca_address + 0x1200));
+			value = ncr_register_read((unsigned *)
+						  (nca + 0x1000));
+			ncr_register_write(value, (unsigned *)
+					   (nca + 0x1200));
 
 			loop++;
 		} while ((value & 0x0200) == 0);
 	}
 
-	/* indicate DDR retention reset */
-	writel(0x00000001, apb_base + 0x300dc);	/* set bit 0 of persist_scratch */
+	/*
+	  Indicate DDR Retention Reset
+	*/
+
+	/* set bit 0 of persist_scratch */
+	writel(0x00000001, apb + 0x300dc);
+
+	/*
+	  Issue Chip Reset
+	*/
 
-	/* issue chip reset */
-	writel(0x00000040, apb_base + 0x31004);	/* Intrnl Boot, 0xffff0000 Target */
-	writel(0x80000000, apb_base + 0x3180c);	/* Set ResetReadDone */
-	writel(0x00080802, apb_base + 0x31008);	/* Chip Reset */
+	/* Intrnl Boot, 0xffff0000 Target */
+	writel(0x00000040, apb + 0x31004);
+	/* Set ResetReadDone */
+	writel(0x80000000, apb + 0x3180c);
+	/* Chip Reset */
+	writel(0x00080802, apb + 0x31008);
 
+	return;
 }
 
-void initiate_retention_reset(void)
+void
+initiate_retention_reset(void)
 {
 	unsigned long ctl_244 = 0;
 	unsigned long value;
+	unsigned long delay;
 
-	if (NULL == nca_address)
-		nca_address = ioremap(0x002020100000ULL, 0x20000);
+	if (NULL == nca || NULL == apb || NULL == dickens)
 		BUG();
 
-	/* send stop message to other CPUs */
-	local_irq_disable();
-	asm volatile ("dsb":::"memory");
-	asm volatile ("dmb":::"memory");
 	system_state = SYSTEM_RESTART;
+	asm volatile ("dsb" : : : "memory");
+	asm volatile ("dmb" : : : "memory");
+	device_shutdown();
+	syscore_shutdown();
 	smp_send_stop();
 
-	kill_time(1000000);
+	for (delay = 0; delay < 10000; ++delay)
+		udelay(1000);
+
+	flush_cache_all();
+	flush_l3();
 
 	/* TODO - quiesce VP engines */
 	quiesce_vp_engine();
 
 	/* disable sysmem interrupts */
-	printk("disabling sysmem interrupts\n");
+	printk(KERN_INFO "disabling sysmem interrupts\n");
 	value = 0;
 	ncr_write(NCP_REGION_ID(34, 0), 0x414, 4, &value);
 	ncr_write(NCP_REGION_ID(15, 0), 0x414, 4, &value);
 
 	/* unlock reset register for later */
-	writel(0x000000ab, apb_base + 0x31000); /* Access Key */
+	writel(0x000000ab, apb + 0x31000); /* Access Key */
 
 	/* prepare to put DDR in self refresh power-down mode */
 	/* first read the CTL_244 register and OR in the LP_CMD value */
@@ -227,61 +290,55 @@ void initiate_retention_reset(void)
 	 * set up for CRBW operation
 	 */
 	/* write register value into CDAR[0] */
-	ncr_register_write(ctl_244, (unsigned *)(nca_address + 0x1000));
+	ncr_register_write(ctl_244, (unsigned *) (nca + 0x1000));
 
 	/* CDR2 - Node.target = 34.0 */
-	ncr_register_write(0x00002200, (unsigned *)(nca_address + 0xf8));
+	ncr_register_write(0x00002200, (unsigned *) (nca + 0xf8));
 
 	/* CDR1 - word offset 0xf4 (byte offset 0x3d0) */
-	ncr_register_write(0x000000f4, (unsigned *)(nca_address + 0xf4));
+	ncr_register_write(0x000000f4, (unsigned *) (nca + 0xf4));
 
 	/*
 	 * issue instruction barrier
 	 * this should cause the next few instructions to be fetched
 	 * into cache
 	 */
-	asm volatile ("dsb":::"memory");
+	asm volatile ("dsb" : : : "memory");
 	prefetch(ncp_ddr_shutdown);
 
 	ncp_ddr_shutdown();
 
+	return;
 }
 EXPORT_SYMBOL(initiate_retention_reset);
 
-static ssize_t axxia_ddr_retention_trigger(struct file *file,
-					   const char __user *buf,
-					   size_t count, loff_t *ppos)
+static ssize_t
+axxia_ddr_retention_trigger(struct file *file, const char __user *buf,
+			    size_t count, loff_t *ppos)
 {
 	initiate_retention_reset();
 	return 0;
 }
 
-static const struct file_operations axxia_ddr_retention_proc_ops = {
-	.write = axxia_ddr_retention_trigger,
-	.llseek = noop_llseek,
+static const struct file_operations proc_ops = {
+	.write      = axxia_ddr_retention_trigger,
+	.llseek     = noop_llseek,
 };
 
-void axxia_ddr_retention_init(void)
-{
-#ifndef CONFIG_ARCH_AXXIA_SIM
-	if (!proc_create("driver/axxia_ddr_retention_reset", S_IWUSR, NULL,
-			 &axxia_ddr_retention_proc_ops))
-		printk(KERN_INFO
-			"Failed to register DDR retention proc interface\n");
-#endif
-
-	apb_base = ioremap(0x2010000000, 0x40000);
-	nca_address = ioremap(0x002020100000ULL, 0x20000);
-
-	printk("ddr_retention: ready\n");
-}
+#define PROC_PATH "driver/axxia_ddr_retention_reset"
 
+void
+axxia_ddr_retention_init(void)
+{
+	if (!of_find_compatible_node(NULL, NULL, "lsi,axm5516"))
+		return;
 
-#else
+	if (!proc_create(PROC_PATH, S_IWUSR, NULL, &proc_ops)) {
+		pr_err("Failed to register DDR retention proc interface\n");
+		return;
+	}
 
-void axxia_ddr_retention_init(void)
-{
-	return;
+	apb = ioremap(0x2010000000, 0x40000);
+	nca = ioremap(0x002020100000ULL, 0x20000);
+	dickens = ioremap(0x2000000000, 0x1000000);
 }
-
-#endif
diff --git a/arch/arm/mach-axxia/platsmp.c b/arch/arm/mach-axxia/platsmp.c
index bad6e67..fb2b8a5 100644
--- a/arch/arm/mach-axxia/platsmp.c
+++ b/arch/arm/mach-axxia/platsmp.c
@@ -127,12 +127,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
 #endif
 
 	/* Wait for so long, then give up if nothing happens ... */
-#ifdef CONFIG_ARCH_AXXIA_SIM
 	timeout = jiffies + (1 * HZ);
-#else
-	timeout = jiffies + (10 * HZ);
-#endif
-
 	while (time_before(jiffies, timeout)) {
 		smp_rmb();
 		if (pen_release == -1)
@@ -181,114 +176,76 @@ void __init smp_init_cpus(void)
 void __init
 platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-#ifdef CONFIG_ARCH_AXXIA_SIM
-	int i;
-
-	/*
-	 * Initialise the present map, which describes the set of CPUs
-	 * actually populated at the present time.
-	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
-
-	/*
-	 * This is the entry point of the routine that the secondary
-	 * cores will execute once they are released from their
-	 * "holding pen".
-	 */
-	*(u32 *)phys_to_virt(0x10000020) =
-		virt_to_phys(axxia_secondary_startup);
-#else
 	int i;
 	void __iomem *apb2_ser3_base;
 	unsigned long resetVal;
 	int phys_cpu, cpu_count = 0;
 	struct device_node *np;
 	unsigned long release_addr[NR_CPUS] = {0};
-	unsigned long release;
+	u32 release;
+
+	for_each_node_by_name(np, "cpu") {
+		if (of_property_read_u32(np, "reg", &phys_cpu))
+			continue;
 
-	if (of_find_compatible_node(NULL, NULL, "lsi,axm5516")) {
-		for_each_node_by_name(np, "cpu") {
-			if (of_property_read_u32(np, "reg", &phys_cpu))
-				continue;
+		if (0 == phys_cpu)
+			continue;
 
-			if (0 == phys_cpu)
-				continue;
+		if (of_property_read_u32(np, "cpu-release-addr",
+					 &release))
+			continue;
 
-			if (of_property_read_u32(np, "cpu-release-addr",
-						 &release))
-				continue;
+		release_addr[phys_cpu] = release;
+	}
 
-			release_addr[phys_cpu] = release;
+	/*
+	* Initialise the present map, which describes the set of CPUs
+	* actually populated at the present time.
+	*/
+
+	apb2_ser3_base = ioremap(APB2_SER3_PHY_ADDR, APB2_SER3_ADDR_SIZE);
+
+	for (i = 0; i < NR_CPUS; i++) {
+		/* check if this is a possible CPU and
+		 * it is within max_cpus range
+		*/
+		if ((cpu_possible(i)) &&
+				(cpu_count < max_cpus) &&
+				(0 != release_addr[i])) {
+			set_cpu_present(cpu_count, true);
+			cpu_count++;
 		}
 
-		/*
-		 * Initialise the present map, which describes the set of CPUs
-		 * actually populated at the present time.
-		 */
-
-		apb2_ser3_base =
-			ioremap(APB2_SER3_PHY_ADDR, APB2_SER3_ADDR_SIZE);
-
-		for (i = 0; i < NR_CPUS; i++) {
-			/* check if this is a possible CPU and
-			   it is within max_cpus range */
-			if ((cpu_possible(i)) &&
-			    (cpu_count < max_cpus) &&
-			    (0 != release_addr[i])) {
-				set_cpu_present(cpu_count, true);
-				cpu_count++;
-			}
-
-			/* Release all physical cpu:s since we might want to
-			 * bring them online later. Also we need to get the
-			 * execution into kernel code (it's currently executing
-			 * in u-boot).
-			 */
-			phys_cpu = cpu_logical_map(i);
-
-			if (phys_cpu != 0) {
-				resetVal = readl(apb2_ser3_base + 0x1010);
-				writel(0xab, apb2_ser3_base+0x1000);
-				resetVal &= ~(1 << phys_cpu);
-				writel(resetVal, apb2_ser3_base+0x1010);
-				udelay(1000);
-			}
+		/* Release all physical cpu:s since we might want to
+		* bring them online later. Also we need to get the
+		* execution into kernel code (it's currently executing
+		* in u-boot).
+		*/
+		phys_cpu = cpu_logical_map(i);
+
+		if (phys_cpu != 0) {
+			resetVal = readl(apb2_ser3_base + 0x1010);
+			writel(0xab, apb2_ser3_base+0x1000);
+			resetVal &= ~(1 << phys_cpu);
+			writel(resetVal, apb2_ser3_base+0x1010);
 		}
+	}
 
-		iounmap(apb2_ser3_base);
-
-		/*
-		 * This is the entry point of the routine that the secondary
-		 * cores will execute once they are released from their
-		 * "holding pen".
-		 */
-		for (i = 0; i < NR_CPUS; i++) {
-			if (release_addr[i] != 0) {
-				u32 *vrel_addr =
-					(u32 *)phys_to_virt(release_addr[i]);
-				*vrel_addr =
-					virt_to_phys(axxia_secondary_startup);
-				smp_wmb();
-				__cpuc_flush_dcache_area(vrel_addr, sizeof(u32));
-			}
+	iounmap(apb2_ser3_base);
+
+	/*
+	 * This is the entry point of the routine that the secondary
+	 * cores will execute once they are released from their
+	 * "holding pen".
+	 */
+	for(i = 0; i < NR_CPUS; i++) {
+		if(release_addr[i] != 0) {
+			u32* vrel_addr =
+				(u32 *)phys_to_virt(release_addr[i]);
+			*vrel_addr =
+				virt_to_phys(axxia_secondary_startup);
+			smp_wmb();
+			__cpuc_flush_dcache_area(vrel_addr, sizeof(u32));
 		}
-	} else if (of_find_compatible_node(NULL, NULL, "lsi,axm5516-sim")) {
-		for (i = 0; i < max_cpus; i++)
-			set_cpu_present(i, true);
-
-		/*
-		 * This is the entry point of the routine that the secondary
-		 * cores will execute once they are released from their
-		 * "holding pen".
-		 */
-		*(u32 *)phys_to_virt(0x10000020) =
-			virt_to_phys(axxia_secondary_startup);
-		smp_wmb();
-		__cpuc_flush_dcache_area((void *)phys_to_virt(0x10000020),
-					 sizeof(u32));
 	}
-
-	return;
-#endif
 }
diff --git a/arch/arm/mach-axxia/wrappers.c b/arch/arm/mach-axxia/wrappers.c
index be5c4b0..4d49825 100644
--- a/arch/arm/mach-axxia/wrappers.c
+++ b/arch/arm/mach-axxia/wrappers.c
@@ -34,42 +34,6 @@
 */
 
 /*
-  These are not wrappers, but are required when loading the RTE in simulation.
-*/
-
-#ifdef CONFIG_ARCH_AXXIA_SIM
-
-/*
-  ------------------------------------------------------------------------------
-  acp_mdio_read
-*/
-
-int
-acp_mdio_read(unsigned long address, unsigned long offset,
-	      unsigned short *value, int clause45)
-{
-	return 0;
-}
-
-EXPORT_SYMBOL(acp_mdio_read);
-
-/*
-  ------------------------------------------------------------------------------
-  acp_mdio_write
-*/
-
-int
-acp_mdio_write(unsigned long address, unsigned long offset,
-	       unsigned short value, int clause45)
-{
-	return 0;
-}
-
-EXPORT_SYMBOL(acp_mdio_write);
-
-#endif	/* CONFIG_ARCH_AXXIA_SIM */
-
-/*
   ==============================================================================
   ==============================================================================
   Platform Device Registration
diff --git a/drivers/misc/lsi-smmon.c b/drivers/misc/lsi-smmon.c
index c73e745..fe0d9e0 100644
--- a/drivers/misc/lsi-smmon.c
+++ b/drivers/misc/lsi-smmon.c
@@ -14,21 +14,18 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/ratelimit.h>
 #include <linux/slab.h>
 
 #include <mach/ncr.h>
 
-#ifndef CONFIG_ARCH_AXXIA
-#error "Only AXM55xx is Supported At Present!"
-#endif
-
 static int log = 1;
-module_param(log, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-MODULE_PARM_DESC(log, "Log each error on the console.");
+module_param(log, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(log, "Log each error to kernel log.");
 
 /*
-  AXM55xx Interrupt Status Bits
+  AXM55xx memory controller interrupt status bits:
 
   Bit [24] = The software-initiated control word write has completed.
   Bit [23] = The user-initiated DLL resync has completed.
@@ -71,235 +68,200 @@ MODULE_PARM_DESC(log, "Log each error on the console.");
 
   Of these, 1, 2, 3, 4, 5, 6, 7, 11, and 19 are of interest.
 */
+#define SM_INT_MASK (0x1f7f701)
+
+enum events {
+	EV_ILLEGAL = 0,
+	EV_MULT_ILLEGAL,
+	EV_CORR_ECC,
+	EV_MULT_CORR_ECC,
+	EV_UNCORR_ECC,
+	EV_MULT_UNCORR_ECC,
+	EV_PORT_ERROR,
+	EV_WRAP_ERROR,
+	EV_PARITY_ERROR,
+	NR_EVENTS
+};
 
-struct smmon_counts {
-	unsigned long illegal_access[2];
-	unsigned long multiple_illegal_access[2];
-	unsigned long correctable_ecc[2];
-	unsigned long multiple_correctable_ecc[2];
-	unsigned long uncorrectable_ecc[2];
-	unsigned long multiple_uncorrectable_ecc[2];
-	unsigned long port_error[2];
-	unsigned long wrap_error[2];
-	unsigned long parity_error[2];
+static const u32 event_mask[NR_EVENTS] = {
+	[EV_ILLEGAL]          = 0x00000002,
+	[EV_MULT_ILLEGAL]     = 0x00000004,
+	[EV_CORR_ECC]         = 0x00000008,
+	[EV_MULT_CORR_ECC]    = 0x00000010,
+	[EV_UNCORR_ECC]       = 0x00000020,
+	[EV_MULT_UNCORR_ECC]  = 0x00000040,
+	[EV_PORT_ERROR]       = 0x00000080,
+	[EV_WRAP_ERROR]       = 0x00000800,
+	[EV_PARITY_ERROR]     = 0x00080000,
 };
 
-static struct smmon_counts counts;
+static const struct event_logging {
+	const char *level;
+	const char *name;
+} event_logging[NR_EVENTS] = {
+	[EV_ILLEGAL]         = {KERN_ERR, "Illegal access"},
+	[EV_MULT_ILLEGAL]    = {KERN_ERR, "Illegal access"},
+	[EV_CORR_ECC]        = {KERN_NOTICE, "Correctable ECC error"},
+	[EV_MULT_CORR_ECC]   = {KERN_NOTICE, "Correctable ECC error"},
+	[EV_UNCORR_ECC]      = {KERN_CRIT, "Uncorrectable ECC error"},
+	[EV_MULT_UNCORR_ECC] = {KERN_CRIT, "Uncorrectable ECC error"},
+	[EV_PORT_ERROR]      = {KERN_CRIT, "Port error"},
+	[EV_WRAP_ERROR]      = {KERN_CRIT, "Wrap error"},
+	[EV_PARITY_ERROR]    = {KERN_CRIT, "Parity error"},
+};
 
-DEFINE_RAW_SPINLOCK(counts_lock);
+struct smmon_attr {
+	struct device_attribute attr;
+	int                     event;
+};
 
-#define SUMMARY_SIZE 512
-static char *summary;
-module_param(summary, charp, S_IRUGO);
-MODULE_PARM_DESC(summary, "A Summary of the Current Error Counts.");
+#define SMMON_ATTR(_name, _event) \
+	{ \
+		.attr = __ATTR(_name, S_IRUGO, smmon_show, NULL), \
+		.event = _event \
+	}
 
-/*
-  ------------------------------------------------------------------------------
-  update_summary
-*/
+struct sm_dev {
+	struct platform_device *pdev;
+	u32 region; /* NCR region address */
+	u32 counter[NR_EVENTS];
+};
 
-static void
-update_summary(void)
+
+static ssize_t
+smmon_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
-	memset(summary, 0, SUMMARY_SIZE);
-	sprintf(summary,
-		"------------ Counts for SM0/SM1 ----------\n"
-		"                   Illegal Access: %lu/%lu\n"
-		"        Multiple Illegal Accesses: %lu/%lu\n"
-		"            Correctable ECC Error: %lu/%lu\n"
-		"  Multiple Correctable ECC Errors: %lu/%lu\n"
-		"          Uncorrectable ECC Error: %lu/%lu\n"
-		"Multiple Uncorrectable ECC Errors: %lu/%lu\n"
-		"                      Port Errors: %lu/%lu\n"
-		"                      Wrap Errors: %lu/%lu\n"
-		"                    Parity Errors: %lu/%lu\n",
-		counts.illegal_access[0],
-		counts.illegal_access[1],
-		counts.multiple_illegal_access[0],
-		counts.multiple_illegal_access[1],
-		counts.correctable_ecc[0],
-		counts.correctable_ecc[1],
-		counts.multiple_correctable_ecc[0],
-		counts.multiple_correctable_ecc[1],
-		counts.uncorrectable_ecc[0],
-		counts.uncorrectable_ecc[1],
-		counts.multiple_uncorrectable_ecc[0],
-		counts.multiple_uncorrectable_ecc[1],
-		counts.port_error[0],
-		counts.port_error[1],
-		counts.wrap_error[0],
-		counts.wrap_error[1],
-		counts.parity_error[0],
-		counts.parity_error[1]);
-
-	return;
+	struct sm_dev *sm = dev_get_drvdata(dev);
+	struct smmon_attr *sma = container_of(attr, struct smmon_attr, attr);
+	return sprintf(buf, "%u", sm->counter[sma->event]);
 }
 
-/*
-  ------------------------------------------------------------------------------
-  smmon_isr
-*/
+static struct smmon_attr smmon_attr_counter[] = {
+	SMMON_ATTR(illegal_access, EV_ILLEGAL),
+	SMMON_ATTR(illegal_access_mult, EV_MULT_ILLEGAL),
+	SMMON_ATTR(correctable_ecc_error, EV_CORR_ECC),
+	SMMON_ATTR(correctable_ecc_error_mult, EV_MULT_CORR_ECC),
+	SMMON_ATTR(uncorrectable_ecc_error, EV_UNCORR_ECC),
+	SMMON_ATTR(uncorrectable_ecc_error_mult, EV_MULT_UNCORR_ECC),
+	SMMON_ATTR(port_error, EV_PORT_ERROR),
+	SMMON_ATTR(wrap_error, EV_WRAP_ERROR),
+	SMMON_ATTR(parity_error, EV_PARITY_ERROR),
+};
 
-static irqreturn_t smmon_isr(int interrupt, void *device)
-{
-	unsigned long status;
-	unsigned long region;
-	int rc;
-	int sm;
-
-	if ((32 + 161) == interrupt) {
-		region = NCP_REGION_ID(0x22, 0);
-		sm = 1;
-	} else if ((32 + 160) == interrupt) {
-		region = NCP_REGION_ID(0xf, 0);
-		sm = 0;
-	} else {
-		return IRQ_NONE;
-	}
+static struct attribute *smmon_attr[] = {
+	&smmon_attr_counter[EV_ILLEGAL].attr.attr,
+	&smmon_attr_counter[EV_MULT_ILLEGAL].attr.attr,
+	&smmon_attr_counter[EV_CORR_ECC].attr.attr,
+	&smmon_attr_counter[EV_MULT_CORR_ECC].attr.attr,
+	&smmon_attr_counter[EV_UNCORR_ECC].attr.attr,
+	&smmon_attr_counter[EV_MULT_UNCORR_ECC].attr.attr,
+	&smmon_attr_counter[EV_PORT_ERROR].attr.attr,
+	&smmon_attr_counter[EV_WRAP_ERROR].attr.attr,
+	&smmon_attr_counter[EV_PARITY_ERROR].attr.attr,
+	NULL
+};
 
-	rc = ncr_read(region, 0x410, 4, &status);
+static struct attribute_group smmon_attr_group = {
+	.name  = "counters",
+	.attrs = smmon_attr
+};
 
-	if (0 != rc) {
-		printk(KERN_ERR
-		       "smmon(%d): Error reading interrupt status!\n", sm);
+static irqreturn_t smmon_isr(int interrupt, void *device)
+{
+	struct sm_dev *sm = device;
+	u32 status;
+	int i;
 
+	if (ncr_read(sm->region, 0x410, 4, &status)) {
+		pr_err("%s: Error reading interrupt status\n",
+				dev_name(&sm->pdev->dev));
 		return IRQ_NONE;
 	}
 
-	raw_spin_lock(&counts_lock);
-
-	if (0 != (0x00000002 & status) || 0 != (0x00000004 & status))
-		printk(KERN_ERR
-		       "smmon(%d): Illegal Access!\n", sm);
-
-	if (0 != (0x00000002 & status))
-		++counts.illegal_access[sm];
-
-	if (0 != (0x00000004 & status))
-		++counts.multiple_illegal_access[sm];
-
-	if ((0 != (0x00000008 & status) ||
-	     0 != (0x00000010 & status)) &&
-	    0 != log)
-		printk(KERN_NOTICE
-		       "smmon(%d): Correctable ECC Error!\n", sm);
-
-	if (0 != (0x00000008 & status))
-		++counts.correctable_ecc[sm];
-
-	if (0 != (0x00000010 & status))
-		++counts.multiple_correctable_ecc[sm];
-
-	if ((0 != (0x00000020 & status) ||
-	     0 != (0x00000040 & status)) &&
-	    0 != log)
-		printk(KERN_CRIT
-		       "smmon(%d): Uncorrectable ECC Error!\n", sm);
-
-	if (0 != (0x00000020 & status))
-		++counts.uncorrectable_ecc[sm];
+	for (i = 0; i < NR_EVENTS; ++i) {
+		if ((status & event_mask[i]) != 0) {
+			++sm->counter[i];
+			if (log)
+				printk_ratelimited("%s%s: %s\n",
+						   event_logging[i].level,
+						   dev_name(&sm->pdev->dev),
+						   event_logging[i].name);
+		}
+	}
 
-	if (0 != (0x00000040 & status))
-		++counts.multiple_uncorrectable_ecc[sm];
+	/* Clear interrupt */
+	ncr_write(sm->region, 0x548, 4, &status);
 
-	if (0 != (0x00000080 & status)) {
-		++counts.port_error[sm];
+	return IRQ_HANDLED;
+}
 
-		if (0 != log)
-			printk(KERN_CRIT
-			       "smmon(%d): Port Error!\n", sm);
+static int
+smmon_probe(struct platform_device *pdev)
+{
+	struct sm_dev *sm;
+	struct resource *io;
+	struct resource *irq;
+	u32 mask = SM_INT_MASK;
+	int rc = 0;
+
+	sm = devm_kzalloc(&pdev->dev, sizeof *sm, GFP_KERNEL);
+	if (!sm) {
+		rc = -ENOMEM;
+		goto out;
 	}
+	sm->pdev = pdev;
 
-	if (0 != (0x00000800 & status)) {
-		++counts.wrap_error[sm];
-
-		if (0 != log)
-			printk(KERN_CRIT
-			       "smmon(%d): Wrap Error!\n", sm);
+	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!io) {
+		rc = -EINVAL;
+		goto out;
 	}
+	sm->region = io->start;
 
-	if (0 != (0x00080000 & status)) {
-		++counts.parity_error[sm];
-
-		if (0 != log)
-			printk(KERN_CRIT
-			       "smmon(%d): Parity Error!\n", sm);
+	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!irq) {
+		rc = -EINVAL;
+		goto out;
 	}
 
-	update_summary();
+	rc = devm_request_irq(&pdev->dev, irq->start, smmon_isr,
+			IRQF_ONESHOT, dev_name(&pdev->dev), pdev);
+	if (rc)
+		goto out;
 
-	raw_spin_unlock(&counts_lock);
+	/* Enable memory controller interrupts */
+	ncr_write(sm->region, 0x414, 4, &mask);
 
-	ncr_write(region, 0x548, 4, &status);
+	rc = sysfs_create_group(&pdev->dev.kobj, &smmon_attr_group);
+	if (rc)
+		goto out;
 
-	return IRQ_HANDLED;
+	dev_set_drvdata(&pdev->dev, sm);
+	pr_info("%s: Memory controller monitor\n", dev_name(&pdev->dev));
+out:
+	return rc;
 }
 
-/*
-  ==============================================================================
-  ==============================================================================
-  Linux Interface
-  ==============================================================================
-  ==============================================================================
-*/
-
-/*
-  ------------------------------------------------------------------------------
-  smmon_init
-*/
-
-static int __init smmon_init(void)
+static int
+smmon_remove(struct platform_device *pdev)
 {
-	int rc;
-	int mask;
-
-	summary = kmalloc(SUMMARY_SIZE, GFP_KERNEL);
-
-	if (NULL == summary)
-		return -ENOMEM;
-
-	update_summary();
-
-	memset(&counts, 0, sizeof(struct smmon_counts));
-
-	/*
-	  Set the interrupt mask for each controller.
-	*/
-
-	mask = 0x1f7f701;
-	ncr_write(NCP_REGION_ID(0x22, 0), 0x414, 4, &mask);
-	ncr_write(NCP_REGION_ID(0xf, 0), 0x414, 4, &mask);
-
-	rc = request_irq(32 + 161, smmon_isr, IRQF_ONESHOT,
-			"smmon_0", NULL);
-	rc |= request_irq(32 + 160, smmon_isr, IRQF_ONESHOT,
-			"smmon_1", NULL);
-
-	if (0 != rc)
-		return -EBUSY;
-
-	printk(KERN_INFO "lsi smmon: Monitoring System Memory\n");
-
+	sysfs_remove_group(&pdev->dev.kobj, &smmon_attr_group);
 	return 0;
 }
 
-module_init(smmon_init);
-
-/*
-  ------------------------------------------------------------------------------
-  smmon_exit
-*/
-
-static void __exit smmon_exit(void)
-{
-	free_irq(32 + 161, NULL);
-	free_irq(32 + 160, NULL);
-
-	kfree(summary);
-
-	printk(KERN_INFO "lsi smmon: Not Monitoring System Memory\n");
-
-	return;
-}
+static const struct of_device_id smmon_id_table[] = {
+	{ .compatible = "lsi,smmon" },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, smmon_id_table);
+
+static struct platform_driver smmon_driver = {
+	.driver = {
+		.name = "lsi-smmon",
+		.of_match_table = smmon_id_table
+	},
+	.probe = smmon_probe,
+	.remove = smmon_remove,
+};
 
-module_exit(smmon_exit);
+module_platform_driver(smmon_driver);
-- 
1.7.9.5



More information about the linux-yocto mailing list