Merge tag 'vt8500-for-next' of git://git.code.sf.net/p/linuxwmt/code into next/dt

From Tony Prisk:

Update arch-vt8500 and drivers to device tree and
remove existing non-dt code.

* tag 'vt8500-for-next' of git://git.code.sf.net/p/linuxwmt/code:
  arm: vt8500: Update arch-vt8500 to devicetree support.
  arm: vt8500: gpio: Devicetree support for arch-vt8500
  arm: vt8500: doc: Add device tree bindings for arch-vt8500 devices
  arm: vt8500: clk: Add Common Clock Framework support
  video: vt8500: Add devicetree support for vt8500-fb and wm8505-fb
  serial: vt8500: Add devicetree support for vt8500-serial
  rtc: vt8500: Add devicetree support for vt8500-rtc
  arm: vt8500: Add device tree files for VIA/Wondermedia SoC's

Resolved add/change conflict in drivers/clk/Makefile.

Signed-off-by: Olof Johansson <olof@lixom.net>
diff --git a/Documentation/devicetree/bindings/arm/vt8500.txt b/Documentation/devicetree/bindings/arm/vt8500.txt
new file mode 100644
index 0000000..d657832
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/vt8500.txt
@@ -0,0 +1,14 @@
+VIA/Wondermedia VT8500 Platforms Device Tree Bindings
+---------------------------------------
+
+Boards with the VIA VT8500 SoC shall have the following properties:
+Required root node property:
+compatible = "via,vt8500";
+
+Boards with the Wondermedia WM8505 SoC shall have the following properties:
+Required root node property:
+compatible = "wm,wm8505";
+
+Boards with the Wondermedia WM8650 SoC shall have the following properties:
+Required root node property:
+compatible = "wm,wm8650";
diff --git a/Documentation/devicetree/bindings/arm/vt8500/via,vt8500-intc.txt b/Documentation/devicetree/bindings/arm/vt8500/via,vt8500-intc.txt
new file mode 100644
index 0000000..0a4ce10
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/vt8500/via,vt8500-intc.txt
@@ -0,0 +1,16 @@
+VIA/Wondermedia VT8500 Interrupt Controller
+-----------------------------------------------------
+
+Required properties:
+- compatible : "via,vt8500-intc"
+- reg : Should contain 1 register ranges(address and length)
+- #interrupt-cells : should be <1>
+
+Example:
+
+	intc: interrupt-controller@d8140000 {
+		compatible = "via,vt8500-intc";
+		interrupt-controller;
+		reg = <0xd8140000 0x10000>;
+		#interrupt-cells = <1>;
+	};
diff --git a/Documentation/devicetree/bindings/arm/vt8500/via,vt8500-pmc.txt b/Documentation/devicetree/bindings/arm/vt8500/via,vt8500-pmc.txt
new file mode 100644
index 0000000..521b9c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/vt8500/via,vt8500-pmc.txt
@@ -0,0 +1,13 @@
+VIA/Wondermedia VT8500 Power Management Controller
+-----------------------------------------------------
+
+Required properties:
+- compatible : "via,vt8500-pmc"
+- reg : Should contain 1 register ranges(address and length)
+
+Example:
+
+	pmc@d8130000 {
+		compatible = "via,vt8500-pmc";
+		reg = <0xd8130000 0x1000>;
+	};
diff --git a/Documentation/devicetree/bindings/arm/vt8500/via,vt8500-timer.txt b/Documentation/devicetree/bindings/arm/vt8500/via,vt8500-timer.txt
new file mode 100644
index 0000000..901c73f
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/vt8500/via,vt8500-timer.txt
@@ -0,0 +1,15 @@
+VIA/Wondermedia VT8500 Timer
+-----------------------------------------------------
+
+Required properties:
+- compatible : "via,vt8500-timer"
+- reg : Should contain 1 register ranges(address and length)
+- interrupts : interrupt for the timer
+
+Example:
+
+	timer@d8130100 {
+		compatible = "via,vt8500-timer";
+		reg = <0xd8130100 0x28>;
+		interrupts = <36>;
+	};
diff --git a/Documentation/devicetree/bindings/clock/vt8500.txt b/Documentation/devicetree/bindings/clock/vt8500.txt
new file mode 100644
index 0000000..a880c70
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/vt8500.txt
@@ -0,0 +1,72 @@
+Device Tree Clock bindings for arch-vt8500
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be one of the following:
+	"via,vt8500-pll-clock" - for a VT8500/WM8505 PLL clock
+	"wm,wm8650-pll-clock" - for a WM8650 PLL clock
+	"via,vt8500-device-clock" - for a VT/WM device clock
+
+Required properties for PLL clocks:
+- reg : shall be the control register offset from PMC base for the pll clock.
+- clocks : shall be the input parent clock phandle for the clock. This should
+	be the reference clock.
+- #clock-cells : from common clock binding; shall be set to 0.
+
+Required properties for device clocks:
+- clocks : shall be the input parent clock phandle for the clock. This should
+	be a pll output.
+- #clock-cells : from common clock binding; shall be set to 0.
+
+
+Device Clocks
+
+Device clocks are required to have one or both of the following sets of
+properties:
+
+
+Gated device clocks:
+
+Required properties:
+- enable-reg : shall be the register offset from PMC base for the enable
+	register.
+- enable-bit : shall be the bit within enable-reg to enable/disable the clock.
+
+
+Divisor device clocks:
+
+Required property:
+- divisor-reg : shall be the register offset from PMC base for the divisor
+	register.
+Optional property:
+- divisor-mask : shall be the mask for the divisor register. Defaults to 0x1f
+	if not specified.
+
+
+For example:
+
+ref25: ref25M {
+	#clock-cells = <0>;
+	compatible = "fixed-clock";
+	clock-frequency = <25000000>;
+};
+
+plla: plla {
+	#clock-cells = <0>;
+	compatible = "wm,wm8650-pll-clock";
+	clocks = <&ref25>;
+	reg = <0x200>;
+};
+
+sdhc: sdhc {
+	#clock-cells = <0>;
+	compatible = "via,vt8500-device-clock";
+	clocks = <&pllb>;
+	divisor-reg = <0x328>;
+	divisor-mask = <0x3f>;
+	enable-reg = <0x254>;
+	enable-bit = <18>;
+};
diff --git a/Documentation/devicetree/bindings/gpio/gpio-vt8500.txt b/Documentation/devicetree/bindings/gpio/gpio-vt8500.txt
new file mode 100644
index 0000000..f4dc523
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-vt8500.txt
@@ -0,0 +1,24 @@
+VIA/Wondermedia VT8500 GPIO Controller
+-----------------------------------------------------
+
+Required properties:
+- compatible : "via,vt8500-gpio", "wm,wm8505-gpio"
+	or "wm,wm8650-gpio" depending on your SoC
+- reg : Should contain 1 register range (address and length)
+- #gpio-cells : should be <3>.
+	1) bank
+	2) pin number
+	3) flags - should be 0
+
+Example:
+
+	gpio: gpio-controller@d8110000 {
+		compatible = "via,vt8500-gpio";
+		gpio-controller;
+		reg = <0xd8110000 0x10000>;
+		#gpio-cells = <3>;
+	};
+
+	vibrate {
+		gpios = <&gpio 0 1 0>; /* Bank 0, Pin 1, No flags */
+	};
diff --git a/Documentation/devicetree/bindings/rtc/via,vt8500-rtc.txt b/Documentation/devicetree/bindings/rtc/via,vt8500-rtc.txt
new file mode 100644
index 0000000..3c0484c
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/via,vt8500-rtc.txt
@@ -0,0 +1,15 @@
+VIA/Wondermedia VT8500 Realtime Clock Controller
+-----------------------------------------------------
+
+Required properties:
+- compatible : "via,vt8500-rtc"
+- reg : Should contain 1 register ranges(address and length)
+- interrupts : alarm interrupt
+
+Example:
+
+	rtc@d8100000 {
+		compatible = "via,vt8500-rtc";
+		reg = <0xd8100000 0x10000>;
+		interrupts = <48>;
+	};
diff --git a/Documentation/devicetree/bindings/tty/serial/via,vt8500-uart.txt b/Documentation/devicetree/bindings/tty/serial/via,vt8500-uart.txt
new file mode 100644
index 0000000..5feef1e
--- /dev/null
+++ b/Documentation/devicetree/bindings/tty/serial/via,vt8500-uart.txt
@@ -0,0 +1,17 @@
+VIA/Wondermedia VT8500 UART Controller
+-----------------------------------------------------
+
+Required properties:
+- compatible : "via,vt8500-uart"
+- reg : Should contain 1 register ranges(address and length)
+- interrupts : UART interrupt
+- clocks : phandle to the uart source clock (usually a 24Mhz fixed clock)
+
+Example:
+
+	uart@d8210000 {
+		compatible = "via,vt8500-uart";
+		reg = <0xd8210000 0x1040>;
+		interrupts = <47>;
+		clocks = <&ref24>;
+	};
diff --git a/Documentation/devicetree/bindings/usb/platform-uhci.txt b/Documentation/devicetree/bindings/usb/platform-uhci.txt
new file mode 100644
index 0000000..a4fb071
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/platform-uhci.txt
@@ -0,0 +1,15 @@
+Generic Platform UHCI Controller
+-----------------------------------------------------
+
+Required properties:
+- compatible : "platform-uhci"
+- reg : Should contain 1 register ranges(address and length)
+- interrupts : UHCI controller interrupt
+
+Example:
+
+	uhci@d8007b00 {
+		compatible = "platform-uhci";
+		reg = <0xd8007b00 0x200>;
+		interrupts = <43>;
+	};
diff --git a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt b/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
new file mode 100644
index 0000000..17b3ad1
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
@@ -0,0 +1,15 @@
+VIA/Wondermedia VT8500 EHCI Controller
+-----------------------------------------------------
+
+Required properties:
+- compatible : "via,vt8500-ehci"
+- reg : Should contain 1 register ranges(address and length)
+- interrupts : ehci controller interrupt
+
+Example:
+
+	ehci@d8007900 {
+		compatible = "via,vt8500-ehci";
+		reg = <0xd8007900 0x200>;
+		interrupts = <43>;
+	};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index db4d3af..5c63da2 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -47,5 +47,7 @@
 st	STMicroelectronics
 stericsson	ST-Ericsson
 ti	Texas Instruments
+via	VIA Technologies, Inc.
 wlf	Wolfson Microelectronics
+wm	Wondermedia Technologies, Inc.
 xlnx	Xilinx
diff --git a/Documentation/devicetree/bindings/video/via,vt8500-fb.txt b/Documentation/devicetree/bindings/video/via,vt8500-fb.txt
new file mode 100644
index 0000000..c870b64
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/via,vt8500-fb.txt
@@ -0,0 +1,62 @@
+VIA VT8500 Framebuffer
+-----------------------------------------------------
+
+Required properties:
+- compatible : "via,vt8500-fb"
+- reg : Should contain 1 register ranges(address and length)
+- interrupts : framebuffer controller interrupt
+- display: a phandle pointing to the display node
+
+Required nodes:
+- display: a display node is required to initialize the lcd panel
+	This should be in the board dts.
+- default-mode: a videomode within the display with timing parameters
+	as specified below.
+
+Example:
+
+	fb@d800e400 {
+		compatible = "via,vt8500-fb";
+		reg = <0xd800e400 0x400>;
+		interrupts = <12>;
+		display = <&display>;
+		default-mode = <&mode0>;
+	};
+
+VIA VT8500 Display
+-----------------------------------------------------
+Required properties (as per of_videomode_helper):
+
+ - hactive, vactive: Display resolution
+ - hfront-porch, hback-porch, hsync-len: Horizontal Display timing parameters
+   in pixels
+   vfront-porch, vback-porch, vsync-len: Vertical display timing parameters in
+   lines
+ - clock: displayclock in Hz
+ - bpp: lcd panel bit-depth.
+	<16> for RGB565, <32> for RGB888
+
+Optional properties (as per of_videomode_helper):
+ - width-mm, height-mm: Display dimensions in mm
+ - hsync-active-high (bool): Hsync pulse is active high
+ - vsync-active-high (bool): Vsync pulse is active high
+ - interlaced (bool): This is an interlaced mode
+ - doublescan (bool): This is a doublescan mode
+
+Example:
+	display: display@0 {
+		modes {
+			mode0: mode@0 {
+				hactive = <800>;
+				vactive = <480>;
+				hback-porch = <88>;
+				hfront-porch = <40>;
+				hsync-len = <0>;
+				vback-porch = <32>;
+				vfront-porch = <11>;
+				vsync-len = <1>;
+				clock = <0>;	/* unused but required */
+				bpp = <16>;	/* non-standard but required */
+			};
+		};
+	};
diff --git a/Documentation/devicetree/bindings/video/wm,prizm-ge-rops.txt b/Documentation/devicetree/bindings/video/wm,prizm-ge-rops.txt
new file mode 100644
index 0000000..a850fa0
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/wm,prizm-ge-rops.txt
@@ -0,0 +1,13 @@
+VIA/Wondermedia Graphics Engine Controller
+-----------------------------------------------------
+
+Required properties:
+- compatible : "wm,prizm-ge-rops"
+- reg : Should contain 1 register ranges(address and length)
+
+Example:
+
+	ge_rops@d8050400 {
+		compatible = "wm,prizm-ge-rops";
+		reg = <0xd8050400 0x100>;
+	};
diff --git a/Documentation/devicetree/bindings/video/wm,wm8505-fb.txt b/Documentation/devicetree/bindings/video/wm,wm8505-fb.txt
new file mode 100644
index 0000000..3d325e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/wm,wm8505-fb.txt
@@ -0,0 +1,23 @@
+Wondermedia WM8505 Framebuffer
+-----------------------------------------------------
+
+Required properties:
+- compatible : "wm,wm8505-fb"
+- reg : Should contain 1 register ranges(address and length)
+- via,display: a phandle pointing to the display node
+
+Required nodes:
+- display: a display node is required to initialize the lcd panel
+	This should be in the board dts. See definition in
+	Documentation/devicetree/bindings/video/via,vt8500-fb.txt
+- default-mode: a videomode node as specified in
+	Documentation/devicetree/bindings/video/via,vt8500-fb.txt
+
+Example:
+
+	fb@d8050800 {
+		compatible = "wm,wm8505-fb";
+		reg = <0xd8050800 0x200>;
+		display = <&display>;
+		default-mode = <&mode0>;
+	};
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index de325f4..1fd9bcd 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1004,6 +1004,10 @@
 	select ARCH_HAS_CPUFREQ
 	select GENERIC_CLOCKEVENTS
 	select ARCH_REQUIRE_GPIOLIB
+	select USE_OF
+	select COMMON_CLK
+	select HAVE_CLK
+	select CLKDEV_LOOKUP
 	help
 	  Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
 
@@ -1128,8 +1132,6 @@
 source "arch/arm/mach-vexpress/Kconfig"
 source "arch/arm/plat-versatile/Kconfig"
 
-source "arch/arm/mach-vt8500/Kconfig"
-
 source "arch/arm/mach-w90x900/Kconfig"
 
 # Definitions to make life easier
@@ -1622,6 +1624,7 @@
 	default 355 if ARCH_U8500
 	default 264 if MACH_H4700
 	default 512 if SOC_OMAP5
+	default 288 if ARCH_VT8500
 	default 0
 	help
 	  Maximum number of GPIOs in the system.
diff --git a/arch/arm/boot/dts/vt8500-bv07.dts b/arch/arm/boot/dts/vt8500-bv07.dts
new file mode 100644
index 0000000..567cf4e
--- /dev/null
+++ b/arch/arm/boot/dts/vt8500-bv07.dts
@@ -0,0 +1,36 @@
+/*
+ * vt8500-bv07.dts - Device tree file for Benign BV07 Netbook
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/dts-v1/;
+/include/ "vt8500.dtsi"
+
+/ {
+	model = "Benign BV07 Netbook";
+
+	/*
+	 * Display node is based on Sascha Hauer's patch on dri-devel.
+	 * Added a bpp property to calculate the size of the framebuffer
+	 * until the binding is formalized.
+	 */
+	display: display@0 {
+		modes {
+			mode0: mode@0 {
+				hactive = <800>;
+				vactive = <480>;
+				hback-porch = <88>;
+				hfront-porch = <40>;
+				hsync-len = <0>;
+				vback-porch = <32>;
+				vfront-porch = <11>;
+				vsync-len = <1>;
+				clock = <0>;	/* unused but required */
+				bpp = <16>;	/* non-standard but required */
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/vt8500.dtsi b/arch/arm/boot/dts/vt8500.dtsi
new file mode 100644
index 0000000..d8645e9
--- /dev/null
+++ b/arch/arm/boot/dts/vt8500.dtsi
@@ -0,0 +1,116 @@
+/*
+ * vt8500.dtsi - Device tree file for VIA VT8500 SoC
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "via,vt8500";
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges;
+		interrupt-parent = <&intc>;
+
+		intc: interrupt-controller@d8140000 {
+			compatible = "via,vt8500-intc";
+			interrupt-controller;
+			reg = <0xd8140000 0x10000>;
+			#interrupt-cells = <1>;
+		};
+
+		gpio: gpio-controller@d8110000 {
+			compatible = "via,vt8500-gpio";
+			gpio-controller;
+			reg = <0xd8110000 0x10000>;
+			#gpio-cells = <3>;
+		};
+
+		pmc@d8130000 {
+			compatible = "via,vt8500-pmc";
+			reg = <0xd8130000 0x1000>;
+
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				ref24: ref24M {
+					#clock-cells = <0>;
+					compatible = "fixed-clock";
+					clock-frequency = <24000000>;
+				};
+			};
+		};
+
+		timer@d8130100 {
+			compatible = "via,vt8500-timer";
+			reg = <0xd8130100 0x28>;
+			interrupts = <36>;
+		};
+
+		ehci@d8007900 {
+			compatible = "via,vt8500-ehci";
+			reg = <0xd8007900 0x200>;
+			interrupts = <43>;
+		};
+
+		uhci@d8007b00 {
+			compatible = "platform-uhci";
+			reg = <0xd8007b00 0x200>;
+			interrupts = <43>;
+		};
+
+		fb@d800e400 {
+			compatible = "via,vt8500-fb";
+			reg = <0xd800e400 0x400>;
+			interrupts = <12>;
+			display = <&display>;
+			default-mode = <&mode0>;
+		};
+
+		ge_rops@d8050400 {
+			compatible = "wm,prizm-ge-rops";
+			reg = <0xd8050400 0x100>;
+		};
+
+		uart@d8200000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd8200000 0x1040>;
+			interrupts = <32>;
+			clocks = <&ref24>;
+		};
+
+		uart@d82b0000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd82b0000 0x1040>;
+			interrupts = <33>;
+			clocks = <&ref24>;
+		};
+
+		uart@d8210000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd8210000 0x1040>;
+			interrupts = <47>;
+			clocks = <&ref24>;
+		};
+
+		uart@d82c0000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd82c0000 0x1040>;
+			interrupts = <50>;
+			clocks = <&ref24>;
+		};
+
+		rtc@d8100000 {
+			compatible = "via,vt8500-rtc";
+			reg = <0xd8100000 0x10000>;
+			interrupts = <48>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/wm8505-ref.dts b/arch/arm/boot/dts/wm8505-ref.dts
new file mode 100644
index 0000000..fd4e248
--- /dev/null
+++ b/arch/arm/boot/dts/wm8505-ref.dts
@@ -0,0 +1,36 @@
+/*
+ * wm8505-ref.dts - Device tree file for Wondermedia WM8505 reference netbook
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/dts-v1/;
+/include/ "wm8505.dtsi"
+
+/ {
+	model = "Wondermedia WM8505 Netbook";
+
+	/*
+	 * Display node is based on Sascha Hauer's patch on dri-devel.
+	 * Added a bpp property to calculate the size of the framebuffer
+	 * until the binding is formalized.
+	 */
+	display: display@0 {
+		modes {
+			mode0: mode@0 {
+				hactive = <800>;
+				vactive = <480>;
+				hback-porch = <88>;
+				hfront-porch = <40>;
+				hsync-len = <0>;
+				vback-porch = <32>;
+				vfront-porch = <11>;
+				vsync-len = <1>;
+				clock = <0>;	/* unused but required */
+				bpp = <32>;	/* non-standard but required */
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/wm8505.dtsi b/arch/arm/boot/dts/wm8505.dtsi
new file mode 100644
index 0000000..b459691
--- /dev/null
+++ b/arch/arm/boot/dts/wm8505.dtsi
@@ -0,0 +1,143 @@
+/*
+ * wm8505.dtsi - Device tree file for Wondermedia WM8505 SoC
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "wm,wm8505";
+
+	cpus {
+		cpu@0 {
+			compatible = "arm,arm926ejs";
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges;
+		interrupt-parent = <&intc0>;
+
+		intc0: interrupt-controller@d8140000 {
+			compatible = "via,vt8500-intc";
+			interrupt-controller;
+			reg = <0xd8140000 0x10000>;
+			#interrupt-cells = <1>;
+		};
+
+		/* Secondary IC cascaded to intc0 */
+		intc1: interrupt-controller@d8150000 {
+			compatible = "via,vt8500-intc";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			reg = <0xD8150000 0x10000>;
+			interrupts = <56 57 58 59 60 61 62 63>;
+		};
+
+		gpio: gpio-controller@d8110000 {
+			compatible = "wm,wm8505-gpio";
+			gpio-controller;
+			reg = <0xd8110000 0x10000>;
+			#gpio-cells = <3>;
+		};
+
+		pmc@d8130000 {
+			compatible = "via,vt8500-pmc";
+			reg = <0xd8130000 0x1000>;
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				ref24: ref24M {
+					#clock-cells = <0>;
+					compatible = "fixed-clock";
+					clock-frequency = <24000000>;
+				};
+			};
+		};
+
+		timer@d8130100 {
+			compatible = "via,vt8500-timer";
+			reg = <0xd8130100 0x28>;
+			interrupts = <36>;
+		};
+
+		ehci@d8007100 {
+			compatible = "via,vt8500-ehci";
+			reg = <0xd8007100 0x200>;
+			interrupts = <43>;
+		};
+
+		uhci@d8007300 {
+			compatible = "platform-uhci";
+			reg = <0xd8007300 0x200>;
+			interrupts = <43>;
+		};
+
+		fb@d8050800 {
+			compatible = "wm,wm8505-fb";
+			reg = <0xd8050800 0x200>;
+			display = <&display>;
+			default-mode = <&mode0>;
+		};
+
+		ge_rops@d8050400 {
+			compatible = "wm,prizm-ge-rops";
+			reg = <0xd8050400 0x100>;
+		};
+
+		uart@d8200000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd8200000 0x1040>;
+			interrupts = <32>;
+			clocks = <&ref24>;
+		};
+
+		uart@d82b0000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd82b0000 0x1040>;
+			interrupts = <33>;
+			clocks = <&ref24>;
+		};
+
+		uart@d8210000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd8210000 0x1040>;
+			interrupts = <47>;
+			clocks = <&ref24>;
+		};
+
+		uart@d82c0000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd82c0000 0x1040>;
+			interrupts = <50>;
+			clocks = <&ref24>;
+		};
+
+		uart@d8370000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd8370000 0x1040>;
+			interrupts = <31>;
+			clocks = <&ref24>;
+		};
+
+		uart@d8380000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd8380000 0x1040>;
+			interrupts = <30>;
+			clocks = <&ref24>;
+		};
+
+		rtc@d8100000 {
+			compatible = "via,vt8500-rtc";
+			reg = <0xd8100000 0x10000>;
+			interrupts = <48>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/wm8650-mid.dts b/arch/arm/boot/dts/wm8650-mid.dts
new file mode 100644
index 0000000..cefd938
--- /dev/null
+++ b/arch/arm/boot/dts/wm8650-mid.dts
@@ -0,0 +1,36 @@
+/*
+ * wm8650-mid.dts - Device tree file for Wondermedia WM8650-MID Tablet
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/dts-v1/;
+/include/ "wm8650.dtsi"
+
+/ {
+	model = "Wondermedia WM8650-MID Tablet";
+
+	/*
+	 * Display node is based on Sascha Hauer's patch on dri-devel.
+	 * Added a bpp property to calculate the size of the framebuffer
+	 * until the binding is formalized.
+	 */
+	display: display@0 {
+		modes {
+			mode0: mode@0 {
+				hactive = <800>;
+				vactive = <480>;
+				hback-porch = <88>;
+				hfront-porch = <40>;
+				hsync-len = <0>;
+				vback-porch = <32>;
+				vfront-porch = <11>;
+				vsync-len = <1>;
+				clock = <0>;	/* unused but required */
+				bpp = <16>;	/* non-standard but required */
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/wm8650.dtsi b/arch/arm/boot/dts/wm8650.dtsi
new file mode 100644
index 0000000..83b9467
--- /dev/null
+++ b/arch/arm/boot/dts/wm8650.dtsi
@@ -0,0 +1,147 @@
+/*
+ * wm8650.dtsi - Device tree file for Wondermedia WM8650 SoC
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "wm,wm8650";
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges;
+		interrupt-parent = <&intc0>;
+
+		intc0: interrupt-controller@d8140000 {
+			compatible = "via,vt8500-intc";
+			interrupt-controller;
+			reg = <0xd8140000 0x10000>;
+			#interrupt-cells = <1>;
+		};
+
+		/* Secondary IC cascaded to intc0 */
+		intc1: interrupt-controller@d8150000 {
+			compatible = "via,vt8500-intc";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			reg = <0xD8150000 0x10000>;
+			interrupts = <56 57 58 59 60 61 62 63>;
+		};
+
+		gpio: gpio-controller@d8110000 {
+			compatible = "wm,wm8650-gpio";
+			gpio-controller;
+			reg = <0xd8110000 0x10000>;
+			#gpio-cells = <3>;
+		};
+
+		pmc@d8130000 {
+			compatible = "via,vt8500-pmc";
+			reg = <0xd8130000 0x1000>;
+
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				ref25: ref25M {
+					#clock-cells = <0>;
+					compatible = "fixed-clock";
+					clock-frequency = <25000000>;
+				};
+
+				ref24: ref24M {
+					#clock-cells = <0>;
+					compatible = "fixed-clock";
+					clock-frequency = <24000000>;
+				};
+
+				plla: plla {
+					#clock-cells = <0>;
+					compatible = "wm,wm8650-pll-clock";
+					clocks = <&ref25>;
+					reg = <0x200>;
+				};
+
+				pllb: pllb {
+					#clock-cells = <0>;
+					compatible = "wm,wm8650-pll-clock";
+					clocks = <&ref25>;
+					reg = <0x204>;
+				};
+
+				arm: arm {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&plla>;
+					divisor-reg = <0x300>;
+				};
+
+				sdhc: sdhc {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&pllb>;
+					divisor-reg = <0x328>;
+					divisor-mask = <0x3f>;
+					enable-reg = <0x254>;
+					enable-bit = <18>;
+				};
+			};
+		};
+
+		timer@d8130100 {
+			compatible = "via,vt8500-timer";
+			reg = <0xd8130100 0x28>;
+			interrupts = <36>;
+		};
+
+		ehci@d8007900 {
+			compatible = "via,vt8500-ehci";
+			reg = <0xd8007900 0x200>;
+			interrupts = <43>;
+		};
+
+		uhci@d8007b00 {
+			compatible = "platform-uhci";
+			reg = <0xd8007b00 0x200>;
+			interrupts = <43>;
+		};
+
+		fb@d8050800 {
+			compatible = "wm,wm8505-fb";
+			reg = <0xd8050800 0x200>;
+			display = <&display>;
+			default-mode = <&mode0>;
+		};
+
+		ge_rops@d8050400 {
+			compatible = "wm,prizm-ge-rops";
+			reg = <0xd8050400 0x100>;
+		};
+
+		uart@d8200000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd8200000 0x1040>;
+			interrupts = <32>;
+			clocks = <&ref24>;
+		};
+
+		uart@d82b0000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd82b0000 0x1040>;
+			interrupts = <33>;
+			clocks = <&ref24>;
+		};
+
+		rtc@d8100000 {
+			compatible = "via,vt8500-rtc";
+			reg = <0xd8100000 0x10000>;
+			interrupts = <48>;
+		};
+	};
+};
diff --git a/arch/arm/mach-vt8500/Kconfig b/arch/arm/mach-vt8500/Kconfig
deleted file mode 100644
index 2c20a34..0000000
--- a/arch/arm/mach-vt8500/Kconfig
+++ /dev/null
@@ -1,73 +0,0 @@
-if ARCH_VT8500
-
-config VTWM_VERSION_VT8500
-	bool
-
-config VTWM_VERSION_WM8505
-	bool
-
-config MACH_BV07
-	bool "Benign BV07-8500 Mini Netbook"
-	depends on ARCH_VT8500
-	select VTWM_VERSION_VT8500
-	help
-	  Add support for the inexpensive 7-inch netbooks sold by many
-	  Chinese distributors under various names. Note that there are
-	  many hardware implementations in identical exterior, make sure
-	  that yours is indeed based on a VIA VT8500 chip.
-
-config MACH_WM8505_7IN_NETBOOK
-	bool "WM8505 7-inch generic netbook"
-	depends on ARCH_VT8500
-	select VTWM_VERSION_WM8505
-	help
-	  Add support for the inexpensive 7-inch netbooks sold by many
-	  Chinese distributors under various names. Note that there are
-	  many hardware implementations in identical exterior, make sure
-	  that yours is indeed based on a WonderMedia WM8505 chip.
-
-comment "LCD panel size"
-
-config WMT_PANEL_800X480
-	bool "7-inch with 800x480 resolution"
-	depends on (FB_VT8500 || FB_WM8505)
-	default y
-	help
-	  These are found in most of the netbooks in generic cases, as
-	  well as in Eken M001 tablets and possibly elsewhere.
-
-	  To select this panel at runtime, say y here and append
-	  'panel=800x480' to your kernel command line. Otherwise, the
-	  largest one available will be used.
-
-config WMT_PANEL_800X600
-	bool "8-inch with 800x600 resolution"
-	depends on (FB_VT8500 || FB_WM8505)
-	help
-	  These are found in Eken M003 tablets and possibly elsewhere.
-
-	  To select this panel at runtime, say y here and append
-	  'panel=800x600' to your kernel command line. Otherwise, the
-	  largest one available will be used.
-
-config WMT_PANEL_1024X576
-	bool "10-inch with 1024x576 resolution"
-	depends on (FB_VT8500 || FB_WM8505)
-	help
-	  These are found in CherryPal netbooks and possibly elsewhere.
-
-	  To select this panel at runtime, say y here and append
-	  'panel=1024x576' to your kernel command line. Otherwise, the
-	  largest one available will be used.
-
-config WMT_PANEL_1024X600
-	bool "10-inch with 1024x600 resolution"
-	depends on (FB_VT8500 || FB_WM8505)
-	help
-	  These are found in Eken M006 tablets and possibly elsewhere.
-
-	  To select this panel at runtime, say y here and append
-	  'panel=1024x600' to your kernel command line. Otherwise, the
-	  largest one available will be used.
-
-endif
diff --git a/arch/arm/mach-vt8500/Makefile b/arch/arm/mach-vt8500/Makefile
index 7ce5176..e035251 100644
--- a/arch/arm/mach-vt8500/Makefile
+++ b/arch/arm/mach-vt8500/Makefile
@@ -1,7 +1 @@
-obj-y += devices.o gpio.o irq.o timer.o restart.o
-
-obj-$(CONFIG_VTWM_VERSION_VT8500) += devices-vt8500.o
-obj-$(CONFIG_VTWM_VERSION_WM8505) += devices-wm8505.o
-
-obj-$(CONFIG_MACH_BV07) += bv07.o
-obj-$(CONFIG_MACH_WM8505_7IN_NETBOOK) += wm8505_7in.o
+obj-$(CONFIG_ARCH_VT8500) += irq.o timer.o vt8500.o
diff --git a/arch/arm/mach-vt8500/bv07.c b/arch/arm/mach-vt8500/bv07.c
deleted file mode 100644
index f9fbeb2..0000000
--- a/arch/arm/mach-vt8500/bv07.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *  arch/arm/mach-vt8500/bv07.c
- *
- *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * 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/io.h>
-#include <linux/pm.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <mach/restart.h>
-
-#include "devices.h"
-
-static void __iomem *pmc_hiber;
-
-static struct platform_device *devices[] __initdata = {
-	&vt8500_device_uart0,
-	&vt8500_device_lcdc,
-	&vt8500_device_ehci,
-	&vt8500_device_ge_rops,
-	&vt8500_device_pwm,
-	&vt8500_device_pwmbl,
-	&vt8500_device_rtc,
-};
-
-static void vt8500_power_off(void)
-{
-	local_irq_disable();
-	writew(5, pmc_hiber);
-	asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0));
-}
-
-void __init bv07_init(void)
-{
-#ifdef CONFIG_FB_VT8500
-	void __iomem *gpio_mux_reg = ioremap(wmt_gpio_base + 0x200, 4);
-	if (gpio_mux_reg) {
-		writel(readl(gpio_mux_reg) | 1, gpio_mux_reg);
-		iounmap(gpio_mux_reg);
-	} else {
-		printk(KERN_ERR "Could not remap the GPIO mux register, display may not work properly!\n");
-	}
-#endif
-	pmc_hiber = ioremap(wmt_pmc_base + 0x12, 2);
-	if (pmc_hiber)
-		pm_power_off = &vt8500_power_off;
-	else
-		printk(KERN_ERR "PMC Hibernation register could not be remapped, not enabling power off!\n");
-
-	wmt_setup_restart();
-	vt8500_set_resources();
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-	vt8500_gpio_init();
-}
-
-MACHINE_START(BV07, "Benign BV07 Mini Netbook")
-	.atag_offset	= 0x100,
-	.restart	= wmt_restart,
-	.reserve	= vt8500_reserve_mem,
-	.map_io		= vt8500_map_io,
-	.init_irq	= vt8500_init_irq,
-	.timer		= &vt8500_timer,
-	.init_machine	= bv07_init,
-MACHINE_END
diff --git a/arch/arm/mach-vt8500/common.h b/arch/arm/mach-vt8500/common.h
new file mode 100644
index 0000000..2b24196
--- /dev/null
+++ b/arch/arm/mach-vt8500/common.h
@@ -0,0 +1,28 @@
+/* linux/arch/arm/mach-vt8500/dt_common.h
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_VT8500_DT_COMMON_H
+#define __ARCH_ARM_MACH_VT8500_DT_COMMON_H
+
+#include <linux/of.h>
+
+void __init vt8500_timer_init(void);
+int __init vt8500_irq_init(struct device_node *node,
+				struct device_node *parent);
+
+/* defined in drivers/clk/clk-vt8500.c */
+void __init vtwm_clk_init(void __iomem *pmc_base);
+
+#endif
diff --git a/arch/arm/mach-vt8500/devices-vt8500.c b/arch/arm/mach-vt8500/devices-vt8500.c
deleted file mode 100644
index 19519ae..0000000
--- a/arch/arm/mach-vt8500/devices-vt8500.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* linux/arch/arm/mach-vt8500/devices-vt8500.c
- *
- * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/platform_device.h>
-
-#include <mach/vt8500_regs.h>
-#include <mach/vt8500_irqs.h>
-#include <mach/i8042.h>
-#include "devices.h"
-
-void __init vt8500_set_resources(void)
-{
-	struct resource tmp[3];
-
-	tmp[0] = wmt_mmio_res(VT8500_LCDC_BASE, SZ_1K);
-	tmp[1] = wmt_irq_res(IRQ_LCDC);
-	wmt_res_add(&vt8500_device_lcdc, tmp, 2);
-
-	tmp[0] = wmt_mmio_res(VT8500_UART0_BASE, 0x1040);
-	tmp[1] = wmt_irq_res(IRQ_UART0);
-	wmt_res_add(&vt8500_device_uart0, tmp, 2);
-
-	tmp[0] = wmt_mmio_res(VT8500_UART1_BASE, 0x1040);
-	tmp[1] = wmt_irq_res(IRQ_UART1);
-	wmt_res_add(&vt8500_device_uart1, tmp, 2);
-
-	tmp[0] = wmt_mmio_res(VT8500_UART2_BASE, 0x1040);
-	tmp[1] = wmt_irq_res(IRQ_UART2);
-	wmt_res_add(&vt8500_device_uart2, tmp, 2);
-
-	tmp[0] = wmt_mmio_res(VT8500_UART3_BASE, 0x1040);
-	tmp[1] = wmt_irq_res(IRQ_UART3);
-	wmt_res_add(&vt8500_device_uart3, tmp, 2);
-
-	tmp[0] = wmt_mmio_res(VT8500_EHCI_BASE, SZ_512);
-	tmp[1] = wmt_irq_res(IRQ_EHCI);
-	wmt_res_add(&vt8500_device_ehci, tmp, 2);
-
-	tmp[0] = wmt_mmio_res(VT8500_GEGEA_BASE, SZ_256);
-	wmt_res_add(&vt8500_device_ge_rops, tmp, 1);
-
-	tmp[0] = wmt_mmio_res(VT8500_PWM_BASE, 0x44);
-	wmt_res_add(&vt8500_device_pwm, tmp, 1);
-
-	tmp[0] = wmt_mmio_res(VT8500_RTC_BASE, 0x2c);
-	tmp[1] = wmt_irq_res(IRQ_RTC);
-	tmp[2] = wmt_irq_res(IRQ_RTCSM);
-	wmt_res_add(&vt8500_device_rtc, tmp, 3);
-}
-
-static void __init vt8500_set_externs(void)
-{
-	/* Non-resource-aware stuff */
-	wmt_ic_base = VT8500_IC_BASE;
-	wmt_gpio_base = VT8500_GPIO_BASE;
-	wmt_pmc_base = VT8500_PMC_BASE;
-	wmt_i8042_base = VT8500_PS2_BASE;
-
-	wmt_nr_irqs = VT8500_NR_IRQS;
-	wmt_timer_irq = IRQ_PMCOS0;
-	wmt_gpio_ext_irq[0] = IRQ_EXT0;
-	wmt_gpio_ext_irq[1] = IRQ_EXT1;
-	wmt_gpio_ext_irq[2] = IRQ_EXT2;
-	wmt_gpio_ext_irq[3] = IRQ_EXT3;
-	wmt_gpio_ext_irq[4] = IRQ_EXT4;
-	wmt_gpio_ext_irq[5] = IRQ_EXT5;
-	wmt_gpio_ext_irq[6] = IRQ_EXT6;
-	wmt_gpio_ext_irq[7] = IRQ_EXT7;
-	wmt_i8042_kbd_irq = IRQ_PS2KBD;
-	wmt_i8042_aux_irq = IRQ_PS2MOUSE;
-}
-
-void __init vt8500_map_io(void)
-{
-	iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc));
-
-	/* Should be done before interrupts and timers are initialized */
-	vt8500_set_externs();
-}
diff --git a/arch/arm/mach-vt8500/devices-wm8505.c b/arch/arm/mach-vt8500/devices-wm8505.c
deleted file mode 100644
index db4594e..0000000
--- a/arch/arm/mach-vt8500/devices-wm8505.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/* linux/arch/arm/mach-vt8500/devices-wm8505.c
- *
- * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/platform_device.h>
-
-#include <mach/wm8505_regs.h>
-#include <mach/wm8505_irqs.h>
-#include <mach/i8042.h>
-#include "devices.h"
-
-void __init wm8505_set_resources(void)
-{
-	struct resource tmp[3];
-
-	tmp[0] = wmt_mmio_res(WM8505_GOVR_BASE, SZ_512);
-	wmt_res_add(&vt8500_device_wm8505_fb, tmp, 1);
-
-	tmp[0] = wmt_mmio_res(WM8505_UART0_BASE, 0x1040);
-	tmp[1] = wmt_irq_res(IRQ_UART0);
-	wmt_res_add(&vt8500_device_uart0, tmp, 2);
-
-	tmp[0] = wmt_mmio_res(WM8505_UART1_BASE, 0x1040);
-	tmp[1] = wmt_irq_res(IRQ_UART1);
-	wmt_res_add(&vt8500_device_uart1, tmp, 2);
-
-	tmp[0] = wmt_mmio_res(WM8505_UART2_BASE, 0x1040);
-	tmp[1] = wmt_irq_res(IRQ_UART2);
-	wmt_res_add(&vt8500_device_uart2, tmp, 2);
-
-	tmp[0] = wmt_mmio_res(WM8505_UART3_BASE, 0x1040);
-	tmp[1] = wmt_irq_res(IRQ_UART3);
-	wmt_res_add(&vt8500_device_uart3, tmp, 2);
-
-	tmp[0] = wmt_mmio_res(WM8505_UART4_BASE, 0x1040);
-	tmp[1] = wmt_irq_res(IRQ_UART4);
-	wmt_res_add(&vt8500_device_uart4, tmp, 2);
-
-	tmp[0] = wmt_mmio_res(WM8505_UART5_BASE, 0x1040);
-	tmp[1] = wmt_irq_res(IRQ_UART5);
-	wmt_res_add(&vt8500_device_uart5, tmp, 2);
-
-	tmp[0] = wmt_mmio_res(WM8505_EHCI_BASE, SZ_512);
-	tmp[1] = wmt_irq_res(IRQ_EHCI);
-	wmt_res_add(&vt8500_device_ehci, tmp, 2);
-
-	tmp[0] = wmt_mmio_res(WM8505_GEGEA_BASE, SZ_256);
-	wmt_res_add(&vt8500_device_ge_rops, tmp, 1);
-
-	tmp[0] = wmt_mmio_res(WM8505_PWM_BASE, 0x44);
-	wmt_res_add(&vt8500_device_pwm, tmp, 1);
-
-	tmp[0] = wmt_mmio_res(WM8505_RTC_BASE, 0x2c);
-	tmp[1] = wmt_irq_res(IRQ_RTC);
-	tmp[2] = wmt_irq_res(IRQ_RTCSM);
-	wmt_res_add(&vt8500_device_rtc, tmp, 3);
-}
-
-static void __init wm8505_set_externs(void)
-{
-	/* Non-resource-aware stuff */
-	wmt_ic_base = WM8505_IC_BASE;
-	wmt_sic_base = WM8505_SIC_BASE;
-	wmt_gpio_base = WM8505_GPIO_BASE;
-	wmt_pmc_base = WM8505_PMC_BASE;
-	wmt_i8042_base = WM8505_PS2_BASE;
-
-	wmt_nr_irqs = WM8505_NR_IRQS;
-	wmt_timer_irq = IRQ_PMCOS0;
-	wmt_gpio_ext_irq[0] = IRQ_EXT0;
-	wmt_gpio_ext_irq[1] = IRQ_EXT1;
-	wmt_gpio_ext_irq[2] = IRQ_EXT2;
-	wmt_gpio_ext_irq[3] = IRQ_EXT3;
-	wmt_gpio_ext_irq[4] = IRQ_EXT4;
-	wmt_gpio_ext_irq[5] = IRQ_EXT5;
-	wmt_gpio_ext_irq[6] = IRQ_EXT6;
-	wmt_gpio_ext_irq[7] = IRQ_EXT7;
-	wmt_i8042_kbd_irq = IRQ_PS2KBD;
-	wmt_i8042_aux_irq = IRQ_PS2MOUSE;
-}
-
-void __init wm8505_map_io(void)
-{
-	iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc));
-
-	/* Should be done before interrupts and timers are initialized */
-	wm8505_set_externs();
-}
diff --git a/arch/arm/mach-vt8500/devices.c b/arch/arm/mach-vt8500/devices.c
deleted file mode 100644
index 1fcdc36..0000000
--- a/arch/arm/mach-vt8500/devices.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* linux/arch/arm/mach-vt8500/devices.c
- *
- * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/pwm_backlight.h>
-#include <linux/memblock.h>
-
-#include <asm/mach/arch.h>
-
-#include <mach/vt8500fb.h>
-#include <mach/i8042.h>
-#include "devices.h"
-
-/* These can't use resources currently */
-unsigned long wmt_ic_base __initdata;
-unsigned long wmt_sic_base __initdata;
-unsigned long wmt_gpio_base __initdata;
-unsigned long wmt_pmc_base __initdata;
-unsigned long wmt_i8042_base __initdata;
-
-int wmt_nr_irqs __initdata;
-int wmt_timer_irq __initdata;
-int wmt_gpio_ext_irq[8] __initdata;
-
-/* Should remain accessible after init.
- * i8042 driver desperately calls for attention...
- */
-int wmt_i8042_kbd_irq;
-int wmt_i8042_aux_irq;
-
-static u64 fb_dma_mask = DMA_BIT_MASK(32);
-
-struct platform_device vt8500_device_lcdc = {
-	.name           = "vt8500-lcd",
-	.id             = 0,
-	.dev		= {
-		.dma_mask	= &fb_dma_mask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-};
-
-struct platform_device vt8500_device_wm8505_fb = {
-	.name           = "wm8505-fb",
-	.id             = 0,
-};
-
-/* Smallest to largest */
-static struct vt8500fb_platform_data panels[] = {
-#ifdef CONFIG_WMT_PANEL_800X480
-{
-	.xres_virtual	= 800,
-	.yres_virtual	= 480 * 2,
-	.mode		= {
-		.name		= "800x480",
-		.xres		= 800,
-		.yres		= 480,
-		.left_margin	= 88,
-		.right_margin	= 40,
-		.upper_margin	= 32,
-		.lower_margin	= 11,
-		.hsync_len	= 0,
-		.vsync_len	= 1,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-},
-#endif
-#ifdef CONFIG_WMT_PANEL_800X600
-{
-	.xres_virtual	= 800,
-	.yres_virtual	= 600 * 2,
-	.mode		= {
-		.name		= "800x600",
-		.xres		= 800,
-		.yres		= 600,
-		.left_margin	= 88,
-		.right_margin	= 40,
-		.upper_margin	= 32,
-		.lower_margin	= 11,
-		.hsync_len	= 0,
-		.vsync_len	= 1,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-},
-#endif
-#ifdef CONFIG_WMT_PANEL_1024X576
-{
-	.xres_virtual	= 1024,
-	.yres_virtual	= 576 * 2,
-	.mode		= {
-		.name		= "1024x576",
-		.xres		= 1024,
-		.yres		= 576,
-		.left_margin	= 40,
-		.right_margin	= 24,
-		.upper_margin	= 32,
-		.lower_margin	= 11,
-		.hsync_len	= 96,
-		.vsync_len	= 2,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-},
-#endif
-#ifdef CONFIG_WMT_PANEL_1024X600
-{
-	.xres_virtual	= 1024,
-	.yres_virtual	= 600 * 2,
-	.mode		= {
-		.name		= "1024x600",
-		.xres		= 1024,
-		.yres		= 600,
-		.left_margin	= 66,
-		.right_margin	= 2,
-		.upper_margin	= 19,
-		.lower_margin	= 1,
-		.hsync_len	= 23,
-		.vsync_len	= 8,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-},
-#endif
-};
-
-static int current_panel_idx __initdata = ARRAY_SIZE(panels) - 1;
-
-static int __init panel_setup(char *str)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(panels); i++) {
-		if (strcmp(panels[i].mode.name, str) == 0) {
-			current_panel_idx = i;
-			break;
-		}
-	}
-	return 0;
-}
-
-early_param("panel", panel_setup);
-
-static inline void preallocate_fb(struct vt8500fb_platform_data *p,
-				  unsigned long align) {
-	p->video_mem_len = (p->xres_virtual * p->yres_virtual * 4) >>
-			(p->bpp > 16 ? 0 : (p->bpp > 8 ? 1 :
-					(8 / p->bpp) + 1));
-	p->video_mem_phys = (unsigned long)memblock_alloc(p->video_mem_len,
-							  align);
-	p->video_mem_virt = phys_to_virt(p->video_mem_phys);
-}
-
-struct platform_device vt8500_device_uart0 = {
-	.name		= "vt8500_serial",
-	.id		= 0,
-};
-
-struct platform_device vt8500_device_uart1 = {
-	.name		= "vt8500_serial",
-	.id		= 1,
-};
-
-struct platform_device vt8500_device_uart2 = {
-	.name		= "vt8500_serial",
-	.id		= 2,
-};
-
-struct platform_device vt8500_device_uart3 = {
-	.name		= "vt8500_serial",
-	.id		= 3,
-};
-
-struct platform_device vt8500_device_uart4 = {
-	.name		= "vt8500_serial",
-	.id		= 4,
-};
-
-struct platform_device vt8500_device_uart5 = {
-	.name		= "vt8500_serial",
-	.id		= 5,
-};
-
-static u64 ehci_dma_mask = DMA_BIT_MASK(32);
-
-struct platform_device vt8500_device_ehci = {
-	.name		= "vt8500-ehci",
-	.id		= 0,
-	.dev		= {
-		.dma_mask	= &ehci_dma_mask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-};
-
-struct platform_device vt8500_device_ge_rops = {
-	.name		= "wmt_ge_rops",
-	.id		= -1,
-};
-
-struct platform_device vt8500_device_pwm = {
-	.name		= "vt8500-pwm",
-	.id		= 0,
-};
-
-static struct platform_pwm_backlight_data vt8500_pwmbl_data = {
-	.pwm_id		= 0,
-	.max_brightness	= 128,
-	.dft_brightness = 70,
-	.pwm_period_ns	= 250000, /* revisit when clocks are implemented */
-};
-
-struct platform_device vt8500_device_pwmbl = {
-	.name		= "pwm-backlight",
-	.id		= 0,
-	.dev		= {
-		.platform_data = &vt8500_pwmbl_data,
-	},
-};
-
-struct platform_device vt8500_device_rtc = {
-	.name		= "vt8500-rtc",
-	.id		= 0,
-};
-
-struct map_desc wmt_io_desc[] __initdata = {
-	/* SoC MMIO registers */
-	[0] = {
-		.virtual	= 0xf8000000,
-		.pfn		= __phys_to_pfn(0xd8000000),
-		.length		= 0x00390000, /* max of all chip variants */
-		.type		= MT_DEVICE
-	},
-	/* PCI I/O space, numbers tied to those in <mach/io.h> */
-	[1] = {
-		.virtual	= 0xf0000000,
-		.pfn		= __phys_to_pfn(0xc0000000),
-		.length		= SZ_64K,
-		.type		= MT_DEVICE
-	},
-};
-
-void __init vt8500_reserve_mem(void)
-{
-#ifdef CONFIG_FB_VT8500
-	panels[current_panel_idx].bpp = 16; /* Always use RGB565 */
-	preallocate_fb(&panels[current_panel_idx], SZ_4M);
-	vt8500_device_lcdc.dev.platform_data = &panels[current_panel_idx];
-#endif
-}
-
-void __init wm8505_reserve_mem(void)
-{
-#if defined CONFIG_FB_WM8505
-	panels[current_panel_idx].bpp = 32; /* Always use RGB888 */
-	preallocate_fb(&panels[current_panel_idx], 32);
-	vt8500_device_wm8505_fb.dev.platform_data = &panels[current_panel_idx];
-#endif
-}
diff --git a/arch/arm/mach-vt8500/devices.h b/arch/arm/mach-vt8500/devices.h
deleted file mode 100644
index 188d4e1..0000000
--- a/arch/arm/mach-vt8500/devices.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* linux/arch/arm/mach-vt8500/devices.h
- *
- * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef __ARCH_ARM_MACH_VT8500_DEVICES_H
-#define __ARCH_ARM_MACH_VT8500_DEVICES_H
-
-#include <linux/platform_device.h>
-#include <asm/mach/map.h>
-
-void __init vt8500_init_irq(void);
-void __init wm8505_init_irq(void);
-void __init vt8500_map_io(void);
-void __init wm8505_map_io(void);
-void __init vt8500_reserve_mem(void);
-void __init wm8505_reserve_mem(void);
-void __init vt8500_gpio_init(void);
-void __init vt8500_set_resources(void);
-void __init wm8505_set_resources(void);
-
-extern unsigned long wmt_ic_base __initdata;
-extern unsigned long wmt_sic_base __initdata;
-extern unsigned long wmt_gpio_base __initdata;
-extern unsigned long wmt_pmc_base __initdata;
-
-extern int wmt_nr_irqs __initdata;
-extern int wmt_timer_irq __initdata;
-extern int wmt_gpio_ext_irq[8] __initdata;
-
-extern struct map_desc wmt_io_desc[2] __initdata;
-
-static inline struct resource wmt_mmio_res(u32 start, u32 size)
-{
-	struct resource tmp = {
-		.flags = IORESOURCE_MEM,
-		.start = start,
-		.end = start + size - 1,
-	};
-
-	return tmp;
-}
-
-static inline struct resource wmt_irq_res(int irq)
-{
-	struct resource tmp = {
-		.flags = IORESOURCE_IRQ,
-		.start = irq,
-		.end = irq,
-	};
-
-	return tmp;
-}
-
-static inline void wmt_res_add(struct platform_device *pdev,
-			       const struct resource *res, unsigned int num)
-{
-	if (unlikely(platform_device_add_resources(pdev, res, num)))
-		pr_err("Failed to assign resources\n");
-}
-
-extern struct sys_timer vt8500_timer;
-
-extern struct platform_device vt8500_device_uart0;
-extern struct platform_device vt8500_device_uart1;
-extern struct platform_device vt8500_device_uart2;
-extern struct platform_device vt8500_device_uart3;
-extern struct platform_device vt8500_device_uart4;
-extern struct platform_device vt8500_device_uart5;
-
-extern struct platform_device vt8500_device_lcdc;
-extern struct platform_device vt8500_device_wm8505_fb;
-extern struct platform_device vt8500_device_ehci;
-extern struct platform_device vt8500_device_ge_rops;
-extern struct platform_device vt8500_device_pwm;
-extern struct platform_device vt8500_device_pwmbl;
-extern struct platform_device vt8500_device_rtc;
-#endif
diff --git a/arch/arm/mach-vt8500/gpio.c b/arch/arm/mach-vt8500/gpio.c
deleted file mode 100644
index 2bcc0ec..0000000
--- a/arch/arm/mach-vt8500/gpio.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/* linux/arch/arm/mach-vt8500/gpio.c
- *
- * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include "devices.h"
-
-#define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip)
-
-#define ENABLE_REGS	0x0
-#define DIRECTION_REGS	0x20
-#define OUTVALUE_REGS	0x40
-#define INVALUE_REGS	0x60
-
-#define EXT_REGOFF	0x1c
-
-static void __iomem *regbase;
-
-struct vt8500_gpio_chip {
-	struct gpio_chip	chip;
-	unsigned int		shift;
-	unsigned int		regoff;
-};
-
-static int gpio_to_irq_map[8];
-
-static int vt8500_muxed_gpio_request(struct gpio_chip *chip,
-				     unsigned offset)
-{
-	struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
-	unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff);
-
-	val |= (1 << vt8500_chip->shift << offset);
-	writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff);
-
-	return 0;
-}
-
-static void vt8500_muxed_gpio_free(struct gpio_chip *chip,
-				   unsigned offset)
-{
-	struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
-	unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff);
-
-	val &= ~(1 << vt8500_chip->shift << offset);
-	writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff);
-}
-
-static int vt8500_muxed_gpio_direction_input(struct gpio_chip *chip,
-				       unsigned offset)
-{
-	struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
-	unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff);
-
-	val &= ~(1 << vt8500_chip->shift << offset);
-	writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff);
-
-	return 0;
-}
-
-static int vt8500_muxed_gpio_direction_output(struct gpio_chip *chip,
-					unsigned offset, int value)
-{
-	struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
-	unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff);
-
-	val |= (1 << vt8500_chip->shift << offset);
-	writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff);
-
-	if (value) {
-		val = readl(regbase + OUTVALUE_REGS + vt8500_chip->regoff);
-		val |= (1 << vt8500_chip->shift << offset);
-		writel(val, regbase + OUTVALUE_REGS + vt8500_chip->regoff);
-	}
-	return 0;
-}
-
-static int vt8500_muxed_gpio_get_value(struct gpio_chip *chip,
-				       unsigned offset)
-{
-	struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
-
-	return (readl(regbase + INVALUE_REGS + vt8500_chip->regoff)
-		>> vt8500_chip->shift >> offset) & 1;
-}
-
-static void vt8500_muxed_gpio_set_value(struct gpio_chip *chip,
-					unsigned offset, int value)
-{
-	struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
-	unsigned val = readl(regbase + INVALUE_REGS + vt8500_chip->regoff);
-
-	if (value)
-		val |= (1 << vt8500_chip->shift << offset);
-	else
-		val &= ~(1 << vt8500_chip->shift << offset);
-
-	writel(val, regbase + INVALUE_REGS + vt8500_chip->regoff);
-}
-
-#define VT8500_GPIO_BANK(__name, __shift, __off, __base, __num)		\
-{									\
-	.chip = {							\
-		.label			= __name,			\
-		.request		= vt8500_muxed_gpio_request,	\
-		.free			= vt8500_muxed_gpio_free,	\
-		.direction_input  = vt8500_muxed_gpio_direction_input,	\
-		.direction_output = vt8500_muxed_gpio_direction_output,	\
-		.get			= vt8500_muxed_gpio_get_value,	\
-		.set			= vt8500_muxed_gpio_set_value,	\
-		.can_sleep		= 0,				\
-		.base			= __base,			\
-		.ngpio			= __num,			\
-	},								\
-	.shift		= __shift,					\
-	.regoff		= __off,					\
-}
-
-static struct vt8500_gpio_chip vt8500_muxed_gpios[] = {
-	VT8500_GPIO_BANK("uart0",	0,	0x0,	8,	4),
-	VT8500_GPIO_BANK("uart1",	4,	0x0,	12,	4),
-	VT8500_GPIO_BANK("spi0",	8,	0x0,	16,	4),
-	VT8500_GPIO_BANK("spi1",	12,	0x0,	20,	4),
-	VT8500_GPIO_BANK("spi2",	16,	0x0,	24,	4),
-	VT8500_GPIO_BANK("pwmout",	24,	0x0,	28,	2),
-
-	VT8500_GPIO_BANK("sdmmc",	0,	0x4,	30,	11),
-	VT8500_GPIO_BANK("ms",		16,	0x4,	41,	7),
-	VT8500_GPIO_BANK("i2c0",	24,	0x4,	48,	2),
-	VT8500_GPIO_BANK("i2c1",	26,	0x4,	50,	2),
-
-	VT8500_GPIO_BANK("mii",		0,	0x8,	52,	20),
-	VT8500_GPIO_BANK("see",		20,	0x8,	72,	4),
-	VT8500_GPIO_BANK("ide",		24,	0x8,	76,	7),
-
-	VT8500_GPIO_BANK("ccir",	0,	0xc,	83,	19),
-
-	VT8500_GPIO_BANK("ts",		8,	0x10,	102,	11),
-
-	VT8500_GPIO_BANK("lcd",		0,	0x14,	113,	23),
-};
-
-static int vt8500_gpio_direction_input(struct gpio_chip *chip,
-				       unsigned offset)
-{
-	unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF);
-
-	val &= ~(1 << offset);
-	writel(val, regbase + DIRECTION_REGS + EXT_REGOFF);
-	return 0;
-}
-
-static int vt8500_gpio_direction_output(struct gpio_chip *chip,
-					unsigned offset, int value)
-{
-	unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF);
-
-	val |= (1 << offset);
-	writel(val, regbase + DIRECTION_REGS + EXT_REGOFF);
-
-	if (value) {
-		val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF);
-		val |= (1 << offset);
-		writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF);
-	}
-	return 0;
-}
-
-static int vt8500_gpio_get_value(struct gpio_chip *chip,
-				       unsigned offset)
-{
-	return (readl(regbase + INVALUE_REGS + EXT_REGOFF) >> offset) & 1;
-}
-
-static void vt8500_gpio_set_value(struct gpio_chip *chip,
-					unsigned offset, int value)
-{
-	unsigned val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF);
-
-	if (value)
-		val |= (1 << offset);
-	else
-		val &= ~(1 << offset);
-
-	writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF);
-}
-
-static int vt8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-	if (offset > 7)
-		return -EINVAL;
-
-	return gpio_to_irq_map[offset];
-}
-
-static struct gpio_chip vt8500_external_gpios = {
-	.label			= "extgpio",
-	.direction_input	= vt8500_gpio_direction_input,
-	.direction_output	= vt8500_gpio_direction_output,
-	.get			= vt8500_gpio_get_value,
-	.set			= vt8500_gpio_set_value,
-	.to_irq			= vt8500_gpio_to_irq,
-	.can_sleep		= 0,
-	.base			= 0,
-	.ngpio			= 8,
-};
-
-void __init vt8500_gpio_init(void)
-{
-	int i;
-
-	for (i = 0; i < 8; i++)
-		gpio_to_irq_map[i] = wmt_gpio_ext_irq[i];
-
-	regbase = ioremap(wmt_gpio_base, SZ_64K);
-	if (!regbase) {
-		printk(KERN_ERR "Failed to map MMIO registers for GPIO\n");
-		return;
-	}
-
-	gpiochip_add(&vt8500_external_gpios);
-
-	for (i = 0; i < ARRAY_SIZE(vt8500_muxed_gpios); i++)
-		gpiochip_add(&vt8500_muxed_gpios[i].chip);
-}
diff --git a/arch/arm/mach-vt8500/include/mach/restart.h b/arch/arm/mach-vt8500/include/mach/restart.h
index 89f9b78..7389795 100644
--- a/arch/arm/mach-vt8500/include/mach/restart.h
+++ b/arch/arm/mach-vt8500/include/mach/restart.h
@@ -13,5 +13,5 @@
  *
  */
 
-void wmt_setup_restart(void);
-void wmt_restart(char mode, const char *cmd);
+void vt8500_setup_restart(void);
+void vt8500_restart(char mode, const char *cmd);
diff --git a/arch/arm/mach-vt8500/include/mach/vt8500_irqs.h b/arch/arm/mach-vt8500/include/mach/vt8500_irqs.h
deleted file mode 100644
index ecfee912..0000000
--- a/arch/arm/mach-vt8500/include/mach/vt8500_irqs.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  arch/arm/mach-vt8500/include/mach/vt8500_irqs.h
- *
- *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * 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
- */
-
-/* VT8500 Interrupt Sources */
-
-#define IRQ_JPEGENC	0	/* JPEG Encoder */
-#define IRQ_JPEGDEC	1	/* JPEG Decoder */
-				/* Reserved */
-#define IRQ_PATA	3	/* PATA Controller */
-				/* Reserved */
-#define IRQ_DMA		5	/* DMA Controller */
-#define IRQ_EXT0	6	/* External Interrupt 0 */
-#define IRQ_EXT1	7	/* External Interrupt 1 */
-#define IRQ_GE		8	/* Graphic Engine */
-#define IRQ_GOV		9	/* Graphic Overlay Engine */
-#define IRQ_ETHER	10	/* Ethernet MAC */
-#define IRQ_MPEGTS	11	/* Transport Stream Interface */
-#define IRQ_LCDC	12	/* LCD Controller */
-#define IRQ_EXT2	13	/* External Interrupt 2 */
-#define IRQ_EXT3	14	/* External Interrupt 3 */
-#define IRQ_EXT4	15	/* External Interrupt 4 */
-#define IRQ_CIPHER	16	/* Cipher */
-#define IRQ_VPP		17	/* Video Post-Processor */
-#define IRQ_I2C1	18	/* I2C 1 */
-#define IRQ_I2C0	19	/* I2C 0 */
-#define IRQ_SDMMC	20	/* SD/MMC Controller */
-#define IRQ_SDMMC_DMA	21	/* SD/MMC Controller DMA */
-#define IRQ_PMC_WU	22	/* Power Management Controller Wakeup */
-				/* Reserved */
-#define IRQ_SPI0	24	/* SPI 0 */
-#define IRQ_SPI1	25	/* SPI 1 */
-#define IRQ_SPI2	26	/* SPI 2 */
-#define IRQ_LCDDF	27	/* LCD Data Formatter */
-#define IRQ_NAND	28	/* NAND Flash Controller */
-#define IRQ_NAND_DMA	29	/* NAND Flash Controller DMA */
-#define IRQ_MS		30	/* MemoryStick Controller */
-#define IRQ_MS_DMA	31	/* MemoryStick Controller DMA */
-#define IRQ_UART0	32	/* UART 0 */
-#define IRQ_UART1	33	/* UART 1 */
-#define IRQ_I2S		34	/* I2S */
-#define IRQ_PCM		35	/* PCM */
-#define IRQ_PMCOS0	36	/* PMC OS Timer 0 */
-#define IRQ_PMCOS1	37	/* PMC OS Timer 1 */
-#define IRQ_PMCOS2	38	/* PMC OS Timer 2 */
-#define IRQ_PMCOS3	39	/* PMC OS Timer 3 */
-#define IRQ_VPU		40	/* Video Processing Unit */
-#define IRQ_VID		41	/* Video Digital Input Interface */
-#define IRQ_AC97	42	/* AC97 Interface */
-#define IRQ_EHCI	43	/* USB */
-#define IRQ_NOR		44	/* NOR Flash Controller */
-#define IRQ_PS2MOUSE	45	/* PS/2 Mouse */
-#define IRQ_PS2KBD	46	/* PS/2 Keyboard */
-#define IRQ_UART2	47	/* UART 2 */
-#define IRQ_RTC		48	/* RTC Interrupt */
-#define IRQ_RTCSM	49	/* RTC Second/Minute Update Interrupt */
-#define IRQ_UART3	50	/* UART 3 */
-#define IRQ_ADC		51	/* ADC */
-#define IRQ_EXT5	52	/* External Interrupt 5 */
-#define IRQ_EXT6	53	/* External Interrupt 6 */
-#define IRQ_EXT7	54	/* External Interrupt 7 */
-#define IRQ_CIR		55	/* CIR */
-#define IRQ_DMA0	56	/* DMA Channel 0 */
-#define IRQ_DMA1	57	/* DMA Channel 1 */
-#define IRQ_DMA2	58	/* DMA Channel 2 */
-#define IRQ_DMA3	59	/* DMA Channel 3 */
-#define IRQ_DMA4	60	/* DMA Channel 4 */
-#define IRQ_DMA5	61	/* DMA Channel 5 */
-#define IRQ_DMA6	62	/* DMA Channel 6 */
-#define IRQ_DMA7	63	/* DMA Channel 7 */
-
-#define VT8500_NR_IRQS		64
diff --git a/arch/arm/mach-vt8500/include/mach/vt8500_regs.h b/arch/arm/mach-vt8500/include/mach/vt8500_regs.h
deleted file mode 100644
index 29c63ec..0000000
--- a/arch/arm/mach-vt8500/include/mach/vt8500_regs.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  arch/arm/mach-vt8500/include/mach/vt8500_regs.h
- *
- *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * 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_ARM_ARCH_VT8500_REGS_H
-#define __ASM_ARM_ARCH_VT8500_REGS_H
-
-/* VT8500 Registers Map */
-
-#define VT8500_REGS_START_PHYS	0xd8000000	/* Start of MMIO registers */
-#define VT8500_REGS_START_VIRT	0xf8000000	/* Virtual mapping start */
-
-#define VT8500_DDR_BASE		0xd8000000	/* 1k	DDR/DDR2 Memory
-							Controller */
-#define VT8500_DMA_BASE		0xd8001000	/* 1k	DMA Controller */
-#define VT8500_SFLASH_BASE	0xd8002000	/* 1k	Serial Flash Memory
-							Controller */
-#define VT8500_ETHER_BASE	0xd8004000	/* 1k	Ethernet MAC 0 */
-#define VT8500_CIPHER_BASE	0xd8006000	/* 4k	Cipher */
-#define VT8500_USB_BASE		0xd8007800	/* 2k	USB OTG */
-# define VT8500_EHCI_BASE	0xd8007900	/*	EHCI */
-# define VT8500_UHCI_BASE	0xd8007b01	/*	UHCI */
-#define VT8500_PATA_BASE	0xd8008000	/* 512	PATA */
-#define VT8500_PS2_BASE		0xd8008800	/* 1k	PS/2 */
-#define VT8500_NAND_BASE	0xd8009000	/* 1k	NAND Controller */
-#define VT8500_NOR_BASE		0xd8009400	/* 1k	NOR Controller */
-#define VT8500_SDMMC_BASE	0xd800a000	/* 1k	SD/MMC Controller */
-#define VT8500_MS_BASE		0xd800b000	/* 1k	MS/MSPRO Controller */
-#define VT8500_LCDC_BASE	0xd800e400	/* 1k	LCD Controller */
-#define VT8500_VPU_BASE		0xd8050000	/* 256	VPU */
-#define VT8500_GOV_BASE		0xd8050300	/* 256	GOV */
-#define VT8500_GEGEA_BASE	0xd8050400	/* 768	GE/GE Alpha Mixing */
-#define VT8500_LCDF_BASE	0xd8050900	/* 256	LCD Formatter */
-#define VT8500_VID_BASE		0xd8050a00	/* 256	VID */
-#define VT8500_VPP_BASE		0xd8050b00	/* 256	VPP */
-#define VT8500_TSBK_BASE	0xd80f4000	/* 4k	TSBK */
-#define VT8500_JPEGDEC_BASE	0xd80fe000	/* 4k	JPEG Decoder */
-#define VT8500_JPEGENC_BASE	0xd80ff000	/* 4k	JPEG Encoder */
-#define VT8500_RTC_BASE		0xd8100000	/* 64k	RTC */
-#define VT8500_GPIO_BASE	0xd8110000	/* 64k	GPIO Configuration */
-#define VT8500_SCC_BASE		0xd8120000	/* 64k	System Configuration*/
-#define VT8500_PMC_BASE		0xd8130000	/* 64k	PMC Configuration */
-#define VT8500_IC_BASE		0xd8140000	/* 64k	Interrupt Controller*/
-#define VT8500_UART0_BASE	0xd8200000	/* 64k	UART 0 */
-#define VT8500_UART2_BASE	0xd8210000	/* 64k	UART 2 */
-#define VT8500_PWM_BASE		0xd8220000	/* 64k	PWM Configuration */
-#define VT8500_SPI0_BASE	0xd8240000	/* 64k	SPI 0 */
-#define VT8500_SPI1_BASE	0xd8250000	/* 64k	SPI 1 */
-#define VT8500_CIR_BASE		0xd8270000	/* 64k	CIR */
-#define VT8500_I2C0_BASE	0xd8280000	/* 64k	I2C 0 */
-#define VT8500_AC97_BASE	0xd8290000	/* 64k	AC97 */
-#define VT8500_SPI2_BASE	0xd82a0000	/* 64k	SPI 2 */
-#define VT8500_UART1_BASE	0xd82b0000	/* 64k	UART 1 */
-#define VT8500_UART3_BASE	0xd82c0000	/* 64k	UART 3 */
-#define VT8500_PCM_BASE		0xd82d0000	/* 64k	PCM */
-#define VT8500_I2C1_BASE	0xd8320000	/* 64k	I2C 1 */
-#define VT8500_I2S_BASE		0xd8330000	/* 64k	I2S */
-#define VT8500_ADC_BASE		0xd8340000	/* 64k	ADC */
-
-#define VT8500_REGS_END_PHYS	0xd834ffff	/* End of MMIO registers */
-#define VT8500_REGS_LENGTH	(VT8500_REGS_END_PHYS \
-				- VT8500_REGS_START_PHYS + 1)
-
-#endif
diff --git a/arch/arm/mach-vt8500/include/mach/wm8505_irqs.h b/arch/arm/mach-vt8500/include/mach/wm8505_irqs.h
deleted file mode 100644
index 6128627..0000000
--- a/arch/arm/mach-vt8500/include/mach/wm8505_irqs.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- *  arch/arm/mach-vt8500/include/mach/wm8505_irqs.h
- *
- *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * 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
- */
-
-/* WM8505 Interrupt Sources */
-
-#define IRQ_UHCI	0	/* UHC FS (UHCI?) */
-#define IRQ_EHCI	1	/* UHC HS */
-#define IRQ_UDCDMA	2	/* UDC DMA */
-				/* Reserved */
-#define IRQ_PS2MOUSE	4	/* PS/2 Mouse */
-#define IRQ_UDC		5	/* UDC */
-#define IRQ_EXT0	6	/* External Interrupt 0 */
-#define IRQ_EXT1	7	/* External Interrupt 1 */
-#define IRQ_KEYPAD	8	/* Keypad */
-#define IRQ_DMA		9	/* DMA Controller */
-#define IRQ_ETHER	10	/* Ethernet MAC */
-				/* Reserved */
-				/* Reserved */
-#define IRQ_EXT2	13	/* External Interrupt 2 */
-#define IRQ_EXT3	14	/* External Interrupt 3 */
-#define IRQ_EXT4	15	/* External Interrupt 4 */
-#define IRQ_APB		16	/* APB Bridge */
-#define IRQ_DMA0	17	/* DMA Channel 0 */
-#define IRQ_I2C1	18	/* I2C 1 */
-#define IRQ_I2C0	19	/* I2C 0 */
-#define IRQ_SDMMC	20	/* SD/MMC Controller */
-#define IRQ_SDMMC_DMA	21	/* SD/MMC Controller DMA */
-#define IRQ_PMC_WU	22	/* Power Management Controller Wakeup */
-#define IRQ_PS2KBD	23	/* PS/2 Keyboard */
-#define IRQ_SPI0	24	/* SPI 0 */
-#define IRQ_SPI1	25	/* SPI 1 */
-#define IRQ_SPI2	26	/* SPI 2 */
-#define IRQ_DMA1	27	/* DMA Channel 1 */
-#define IRQ_NAND	28	/* NAND Flash Controller */
-#define IRQ_NAND_DMA	29	/* NAND Flash Controller DMA */
-#define IRQ_UART5	30	/* UART 5 */
-#define IRQ_UART4	31	/* UART 4 */
-#define IRQ_UART0	32	/* UART 0 */
-#define IRQ_UART1	33	/* UART 1 */
-#define IRQ_DMA2	34	/* DMA Channel 2 */
-#define IRQ_I2S		35	/* I2S */
-#define IRQ_PMCOS0	36	/* PMC OS Timer 0 */
-#define IRQ_PMCOS1	37	/* PMC OS Timer 1 */
-#define IRQ_PMCOS2	38	/* PMC OS Timer 2 */
-#define IRQ_PMCOS3	39	/* PMC OS Timer 3 */
-#define IRQ_DMA3	40	/* DMA Channel 3 */
-#define IRQ_DMA4	41	/* DMA Channel 4 */
-#define IRQ_AC97	42	/* AC97 Interface */
-				/* Reserved */
-#define IRQ_NOR		44	/* NOR Flash Controller */
-#define IRQ_DMA5	45	/* DMA Channel 5 */
-#define IRQ_DMA6	46	/* DMA Channel 6 */
-#define IRQ_UART2	47	/* UART 2 */
-#define IRQ_RTC		48	/* RTC Interrupt */
-#define IRQ_RTCSM	49	/* RTC Second/Minute Update Interrupt */
-#define IRQ_UART3	50	/* UART 3 */
-#define IRQ_DMA7	51	/* DMA Channel 7 */
-#define IRQ_EXT5	52	/* External Interrupt 5 */
-#define IRQ_EXT6	53	/* External Interrupt 6 */
-#define IRQ_EXT7	54	/* External Interrupt 7 */
-#define IRQ_CIR		55	/* CIR */
-#define IRQ_SIC0	56	/* SIC IRQ0 */
-#define IRQ_SIC1	57	/* SIC IRQ1 */
-#define IRQ_SIC2	58	/* SIC IRQ2 */
-#define IRQ_SIC3	59	/* SIC IRQ3 */
-#define IRQ_SIC4	60	/* SIC IRQ4 */
-#define IRQ_SIC5	61	/* SIC IRQ5 */
-#define IRQ_SIC6	62	/* SIC IRQ6 */
-#define IRQ_SIC7	63	/* SIC IRQ7 */
-				/* Reserved */
-#define IRQ_JPEGDEC	65	/* JPEG Decoder */
-#define IRQ_SAE		66	/* SAE (?) */
-				/* Reserved */
-#define IRQ_VPU		79	/* Video Processing Unit */
-#define IRQ_VPP		80	/* Video Post-Processor */
-#define IRQ_VID		81	/* Video Digital Input Interface */
-#define IRQ_SPU		82	/* SPU (?) */
-#define IRQ_PIP		83	/* PIP Error */
-#define IRQ_GE		84	/* Graphic Engine */
-#define IRQ_GOV		85	/* Graphic Overlay Engine */
-#define IRQ_DVO		86	/* Digital Video Output */
-				/* Reserved */
-#define IRQ_DMA8	92	/* DMA Channel 8 */
-#define IRQ_DMA9	93	/* DMA Channel 9 */
-#define IRQ_DMA10	94	/* DMA Channel 10 */
-#define IRQ_DMA11	95	/* DMA Channel 11 */
-#define IRQ_DMA12	96	/* DMA Channel 12 */
-#define IRQ_DMA13	97	/* DMA Channel 13 */
-#define IRQ_DMA14	98	/* DMA Channel 14 */
-#define IRQ_DMA15	99	/* DMA Channel 15 */
-				/* Reserved */
-#define IRQ_GOVW	111	/* GOVW (?) */
-#define IRQ_GOVRSDSCD	112	/* GOVR SDSCD (?) */
-#define IRQ_GOVRSDMIF	113	/* GOVR SDMIF (?) */
-#define IRQ_GOVRHDSCD	114	/* GOVR HDSCD (?) */
-#define IRQ_GOVRHDMIF	115	/* GOVR HDMIF (?) */
-
-#define WM8505_NR_IRQS		116
diff --git a/arch/arm/mach-vt8500/include/mach/wm8505_regs.h b/arch/arm/mach-vt8500/include/mach/wm8505_regs.h
deleted file mode 100644
index df155094..0000000
--- a/arch/arm/mach-vt8500/include/mach/wm8505_regs.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  arch/arm/mach-vt8500/include/mach/wm8505_regs.h
- *
- *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * 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_ARM_ARCH_WM8505_REGS_H
-#define __ASM_ARM_ARCH_WM8505_REGS_H
-
-/* WM8505 Registers Map */
-
-#define WM8505_REGS_START_PHYS	0xd8000000	/* Start of MMIO registers */
-#define WM8505_REGS_START_VIRT	0xf8000000	/* Virtual mapping start */
-
-#define WM8505_DDR_BASE		0xd8000400	/* 1k	DDR/DDR2 Memory
-							Controller */
-#define WM8505_DMA_BASE		0xd8001800	/* 1k	DMA Controller */
-#define WM8505_VDMA_BASE	0xd8001c00	/* 1k	VDMA */
-#define WM8505_SFLASH_BASE	0xd8002000	/* 1k	Serial Flash Memory
-							Controller */
-#define WM8505_ETHER_BASE	0xd8004000	/* 1k	Ethernet MAC 0 */
-#define WM8505_CIPHER_BASE	0xd8006000	/* 4k	Cipher */
-#define WM8505_USB_BASE		0xd8007000	/* 2k	USB 2.0 Host */
-# define WM8505_EHCI_BASE	0xd8007100	/*	EHCI */
-# define WM8505_UHCI_BASE	0xd8007301	/*	UHCI */
-#define WM8505_PS2_BASE		0xd8008800	/* 1k	PS/2 */
-#define WM8505_NAND_BASE	0xd8009000	/* 1k	NAND Controller */
-#define WM8505_NOR_BASE		0xd8009400	/* 1k	NOR Controller */
-#define WM8505_SDMMC_BASE	0xd800a000	/* 1k	SD/MMC Controller */
-#define WM8505_VPU_BASE		0xd8050000	/* 256	VPU */
-#define WM8505_GOV_BASE		0xd8050300	/* 256	GOV */
-#define WM8505_GEGEA_BASE	0xd8050400	/* 768	GE/GE Alpha Mixing */
-#define WM8505_GOVR_BASE	0xd8050800	/* 512	GOVR (frambuffer) */
-#define WM8505_VID_BASE		0xd8050a00	/* 256	VID */
-#define WM8505_SCL_BASE		0xd8050d00	/* 256	SCL */
-#define WM8505_VPP_BASE		0xd8050f00	/* 256	VPP */
-#define WM8505_JPEGDEC_BASE	0xd80fe000	/* 4k	JPEG Decoder */
-#define WM8505_RTC_BASE		0xd8100000	/* 64k	RTC */
-#define WM8505_GPIO_BASE	0xd8110000	/* 64k	GPIO Configuration */
-#define WM8505_SCC_BASE		0xd8120000	/* 64k	System Configuration*/
-#define WM8505_PMC_BASE		0xd8130000	/* 64k	PMC Configuration */
-#define WM8505_IC_BASE		0xd8140000	/* 64k	Interrupt Controller*/
-#define WM8505_SIC_BASE		0xd8150000	/* 64k	Secondary IC */
-#define WM8505_UART0_BASE	0xd8200000	/* 64k	UART 0 */
-#define WM8505_UART2_BASE	0xd8210000	/* 64k	UART 2 */
-#define WM8505_PWM_BASE		0xd8220000	/* 64k	PWM Configuration */
-#define WM8505_SPI0_BASE	0xd8240000	/* 64k	SPI 0 */
-#define WM8505_SPI1_BASE	0xd8250000	/* 64k	SPI 1 */
-#define WM8505_KEYPAD_BASE	0xd8260000	/* 64k	Keypad control */
-#define WM8505_CIR_BASE		0xd8270000	/* 64k	CIR */
-#define WM8505_I2C0_BASE	0xd8280000	/* 64k	I2C 0 */
-#define WM8505_AC97_BASE	0xd8290000	/* 64k	AC97 */
-#define WM8505_SPI2_BASE	0xd82a0000	/* 64k	SPI 2 */
-#define WM8505_UART1_BASE	0xd82b0000	/* 64k	UART 1 */
-#define WM8505_UART3_BASE	0xd82c0000	/* 64k	UART 3 */
-#define WM8505_I2C1_BASE	0xd8320000	/* 64k	I2C 1 */
-#define WM8505_I2S_BASE		0xd8330000	/* 64k	I2S */
-#define WM8505_UART4_BASE	0xd8370000	/* 64k	UART 4 */
-#define WM8505_UART5_BASE	0xd8380000	/* 64k	UART 5 */
-
-#define WM8505_REGS_END_PHYS	0xd838ffff	/* End of MMIO registers */
-#define WM8505_REGS_LENGTH	(WM8505_REGS_END_PHYS \
-				- WM8505_REGS_START_PHYS + 1)
-
-#endif
diff --git a/arch/arm/mach-vt8500/irq.c b/arch/arm/mach-vt8500/irq.c
index 642de04..f8f9ab9 100644
--- a/arch/arm/mach-vt8500/irq.c
+++ b/arch/arm/mach-vt8500/irq.c
@@ -1,6 +1,7 @@
 /*
  *  arch/arm/mach-vt8500/irq.c
  *
+ *  Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
  *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -18,81 +19,102 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/*
+ * This file is copied and modified from the original irq.c provided by
+ * Alexey Charkov. Minor changes have been made for Device Tree Support.
+ */
+
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/interrupt.h>
+#include <linux/bitops.h>
+
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
 
 #include <asm/irq.h>
 
-#include "devices.h"
 
-#define VT8500_IC_DCTR		0x40		/* Destination control
-						register, 64*u8 */
-#define VT8500_INT_ENABLE	(1 << 3)
-#define VT8500_TRIGGER_HIGH	(0 << 4)
-#define VT8500_TRIGGER_RISING	(1 << 4)
-#define VT8500_TRIGGER_FALLING	(2 << 4)
+#define VT8500_ICPC_IRQ		0x20
+#define VT8500_ICPC_FIQ		0x24
+#define VT8500_ICDC		0x40		/* Destination Control 64*u32 */
+#define VT8500_ICIS		0x80		/* Interrupt status, 16*u32 */
+
+/* ICPC */
+#define ICPC_MASK		0x3F
+#define ICPC_ROTATE		BIT(6)
+
+/* IC_DCTR */
+#define ICDC_IRQ		0x00
+#define ICDC_FIQ		0x01
+#define ICDC_DSS0		0x02
+#define ICDC_DSS1		0x03
+#define ICDC_DSS2		0x04
+#define ICDC_DSS3		0x05
+#define ICDC_DSS4		0x06
+#define ICDC_DSS5		0x07
+
+#define VT8500_INT_DISABLE	0
+#define VT8500_INT_ENABLE	BIT(3)
+
+#define VT8500_TRIGGER_HIGH	0
+#define VT8500_TRIGGER_RISING	BIT(5)
+#define VT8500_TRIGGER_FALLING	BIT(6)
 #define VT8500_EDGE		( VT8500_TRIGGER_RISING \
 				| VT8500_TRIGGER_FALLING)
-#define VT8500_IC_STATUS	0x80		/* Interrupt status, 2*u32 */
 
-static void __iomem *ic_regbase;
-static void __iomem *sic_regbase;
+static int irq_cnt;
+
+struct vt8500_irq_priv {
+	void __iomem *base;
+};
 
 static void vt8500_irq_mask(struct irq_data *d)
 {
-	void __iomem *base = ic_regbase;
-	unsigned irq = d->irq;
+	struct vt8500_irq_priv *priv =
+			(struct vt8500_irq_priv *)(d->domain->host_data);
+	void __iomem *base = priv->base;
 	u8 edge;
 
-	if (irq >= 64) {
-		base = sic_regbase;
-		irq -= 64;
-	}
-	edge = readb(base + VT8500_IC_DCTR + irq) & VT8500_EDGE;
+	edge = readb(base + VT8500_ICDC + d->hwirq) & VT8500_EDGE;
 	if (edge) {
-		void __iomem *stat_reg = base + VT8500_IC_STATUS
-						+ (irq < 32 ? 0 : 4);
+		void __iomem *stat_reg = base + VT8500_ICIS
+						+ (d->hwirq < 32 ? 0 : 4);
 		unsigned status = readl(stat_reg);
 
-		status |= (1 << (irq & 0x1f));
+		status |= (1 << (d->hwirq & 0x1f));
 		writel(status, stat_reg);
 	} else {
-		u8 dctr = readb(base + VT8500_IC_DCTR + irq);
+		u8 dctr = readb(base + VT8500_ICDC + d->hwirq);
 
 		dctr &= ~VT8500_INT_ENABLE;
-		writeb(dctr, base + VT8500_IC_DCTR + irq);
+		writeb(dctr, base + VT8500_ICDC + d->hwirq);
 	}
 }
 
 static void vt8500_irq_unmask(struct irq_data *d)
 {
-	void __iomem *base = ic_regbase;
-	unsigned irq = d->irq;
+	struct vt8500_irq_priv *priv =
+			(struct vt8500_irq_priv *)(d->domain->host_data);
+	void __iomem *base = priv->base;
 	u8 dctr;
 
-	if (irq >= 64) {
-		base = sic_regbase;
-		irq -= 64;
-	}
-	dctr = readb(base + VT8500_IC_DCTR + irq);
+	dctr = readb(base + VT8500_ICDC + d->hwirq);
 	dctr |= VT8500_INT_ENABLE;
-	writeb(dctr, base + VT8500_IC_DCTR + irq);
+	writeb(dctr, base + VT8500_ICDC + d->hwirq);
 }
 
 static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type)
 {
-	void __iomem *base = ic_regbase;
-	unsigned irq = d->irq;
-	unsigned orig_irq = irq;
+	struct vt8500_irq_priv *priv =
+			(struct vt8500_irq_priv *)(d->domain->host_data);
+	void __iomem *base = priv->base;
 	u8 dctr;
 
-	if (irq >= 64) {
-		base = sic_regbase;
-		irq -= 64;
-	}
-
-	dctr = readb(base + VT8500_IC_DCTR + irq);
+	dctr = readb(base + VT8500_ICDC + d->hwirq);
 	dctr &= ~VT8500_EDGE;
 
 	switch (flow_type) {
@@ -100,18 +122,18 @@
 		return -EINVAL;
 	case IRQF_TRIGGER_HIGH:
 		dctr |= VT8500_TRIGGER_HIGH;
-		__irq_set_handler_locked(orig_irq, handle_level_irq);
+		__irq_set_handler_locked(d->irq, handle_level_irq);
 		break;
 	case IRQF_TRIGGER_FALLING:
 		dctr |= VT8500_TRIGGER_FALLING;
-		__irq_set_handler_locked(orig_irq, handle_edge_irq);
+		__irq_set_handler_locked(d->irq, handle_edge_irq);
 		break;
 	case IRQF_TRIGGER_RISING:
 		dctr |= VT8500_TRIGGER_RISING;
-		__irq_set_handler_locked(orig_irq, handle_edge_irq);
+		__irq_set_handler_locked(d->irq, handle_edge_irq);
 		break;
 	}
-	writeb(dctr, base + VT8500_IC_DCTR + irq);
+	writeb(dctr, base + VT8500_ICDC + d->hwirq);
 
 	return 0;
 }
@@ -124,57 +146,76 @@
 	.irq_set_type = vt8500_irq_set_type,
 };
 
-void __init vt8500_init_irq(void)
+static void __init vt8500_init_irq_hw(void __iomem *base)
 {
 	unsigned int i;
 
-	ic_regbase = ioremap(wmt_ic_base, SZ_64K);
+	/* Enable rotating priority for IRQ */
+	writel(ICPC_ROTATE, base + VT8500_ICPC_IRQ);
+	writel(0x00, base + VT8500_ICPC_FIQ);
 
-	if (ic_regbase) {
-		/* Enable rotating priority for IRQ */
-		writel((1 << 6), ic_regbase + 0x20);
-		writel(0, ic_regbase + 0x24);
-
-		for (i = 0; i < wmt_nr_irqs; i++) {
-			/* Disable all interrupts and route them to IRQ */
-			writeb(0x00, ic_regbase + VT8500_IC_DCTR + i);
-
-			irq_set_chip_and_handler(i, &vt8500_irq_chip,
-						 handle_level_irq);
-			set_irq_flags(i, IRQF_VALID);
-		}
-	} else {
-		printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n");
+	for (i = 0; i < 64; i++) {
+		/* Disable all interrupts and route them to IRQ */
+		writeb(VT8500_INT_DISABLE | ICDC_IRQ,
+						base + VT8500_ICDC + i);
 	}
 }
 
-void __init wm8505_init_irq(void)
+static int vt8500_irq_map(struct irq_domain *h, unsigned int virq,
+							irq_hw_number_t hw)
 {
-	unsigned int i;
+	irq_set_chip_and_handler(virq, &vt8500_irq_chip, handle_level_irq);
+	set_irq_flags(virq, IRQF_VALID);
 
-	ic_regbase = ioremap(wmt_ic_base, SZ_64K);
-	sic_regbase = ioremap(wmt_sic_base, SZ_64K);
-
-	if (ic_regbase && sic_regbase) {
-		/* Enable rotating priority for IRQ */
-		writel((1 << 6), ic_regbase + 0x20);
-		writel(0, ic_regbase + 0x24);
-		writel((1 << 6), sic_regbase + 0x20);
-		writel(0, sic_regbase + 0x24);
-
-		for (i = 0; i < wmt_nr_irqs; i++) {
-			/* Disable all interrupts and route them to IRQ */
-			if (i < 64)
-				writeb(0x00, ic_regbase + VT8500_IC_DCTR + i);
-			else
-				writeb(0x00, sic_regbase + VT8500_IC_DCTR
-								+ i - 64);
-
-			irq_set_chip_and_handler(i, &vt8500_irq_chip,
-						 handle_level_irq);
-			set_irq_flags(i, IRQF_VALID);
-		}
-	} else {
-		printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n");
-	}
+	return 0;
 }
+
+static struct irq_domain_ops vt8500_irq_domain_ops = {
+	.map = vt8500_irq_map,
+	.xlate = irq_domain_xlate_onecell,
+};
+
+int __init vt8500_irq_init(struct device_node *node, struct device_node *parent)
+{
+	struct irq_domain *vt8500_irq_domain;
+	struct vt8500_irq_priv *priv;
+	int irq, i;
+	struct device_node *np = node;
+
+	priv = kzalloc(sizeof(struct vt8500_irq_priv), GFP_KERNEL);
+	priv->base = of_iomap(np, 0);
+
+	vt8500_irq_domain = irq_domain_add_legacy(node, 64, irq_cnt, 0,
+				&vt8500_irq_domain_ops, priv);
+	if (!vt8500_irq_domain)
+		pr_err("%s: Unable to add wmt irq domain!\n", __func__);
+
+	irq_set_default_host(vt8500_irq_domain);
+
+	vt8500_init_irq_hw(priv->base);
+
+	pr_info("Added IRQ Controller @ %x [virq_base = %d]\n",
+						(u32)(priv->base), irq_cnt);
+
+	/* check if this is a slaved controller */
+	if (of_irq_count(np) != 0) {
+		/* check that we have the correct number of interrupts */
+		if (of_irq_count(np) != 8) {
+			pr_err("%s: Incorrect IRQ map for slave controller\n",
+					__func__);
+			return -EINVAL;
+		}
+
+		for (i = 0; i < 8; i++) {
+			irq = irq_of_parse_and_map(np, i);
+			enable_irq(irq);
+		}
+
+		pr_info("vt8500-irq: Enabled slave->parent interrupts\n");
+	}
+
+	irq_cnt += 64;
+
+	return 0;
+}
+
diff --git a/arch/arm/mach-vt8500/restart.c b/arch/arm/mach-vt8500/restart.c
deleted file mode 100644
index 497e89a..0000000
--- a/arch/arm/mach-vt8500/restart.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* linux/arch/arm/mach-vt8500/restart.c
- *
- * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-#include <asm/io.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-
-#define LEGACY_PMC_BASE		0xD8130000
-#define WMT_PRIZM_PMSR_REG	0x60
-
-static void __iomem *pmc_base;
-
-void wmt_setup_restart(void)
-{
-	struct device_node *np;
-
-	/*
-	 * Check if Power Mgmt Controller node is present in device tree. If no
-	 * device tree node, use the legacy PMSR value (valid for all current
-	 * SoCs).
-	 */
-	np = of_find_compatible_node(NULL, NULL, "wmt,prizm-pmc");
-	if (np) {
-		pmc_base = of_iomap(np, 0);
-
-		if (!pmc_base)
-			pr_err("%s:of_iomap(pmc) failed\n", __func__);
-
-		of_node_put(np);
-	} else {
-		pmc_base = ioremap(LEGACY_PMC_BASE, 0x1000);
-		if (!pmc_base) {
-			pr_err("%s:ioremap(rstc) failed\n", __func__);
-			return;
-		}
-	}
-}
-
-void wmt_restart(char mode, const char *cmd)
-{
-	if (pmc_base)
-		writel(1, pmc_base + WMT_PRIZM_PMSR_REG);
-}
diff --git a/arch/arm/mach-vt8500/timer.c b/arch/arm/mach-vt8500/timer.c
index d5376c5..050e183 100644
--- a/arch/arm/mach-vt8500/timer.c
+++ b/arch/arm/mach-vt8500/timer.c
@@ -1,6 +1,7 @@
 /*
- *  arch/arm/mach-vt8500/timer.c
+ *  arch/arm/mach-vt8500/timer_dt.c
  *
+ *  Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
  *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -18,18 +19,25 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/*
+ * This file is copied and modified from the original timer.c provided by
+ * Alexey Charkov. Minor changes have been made for Device Tree Support.
+ */
+
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/delay.h>
-
 #include <asm/mach/time.h>
 
-#include "devices.h"
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 
 #define VT8500_TIMER_OFFSET	0x0100
+#define VT8500_TIMER_HZ		3000000
 #define TIMER_MATCH_VAL		0x0000
 #define TIMER_COUNT_VAL		0x0010
 #define TIMER_STATUS_VAL	0x0014
@@ -39,7 +47,6 @@
 #define TIMER_COUNT_R_ACTIVE	(1 << 5)	/* not ready for read */
 #define TIMER_COUNT_W_ACTIVE	(1 << 4)	/* not ready for write */
 #define TIMER_MATCH_W_ACTIVE	(1 << 0)	/* not ready for write */
-#define VT8500_TIMER_HZ		3000000
 
 #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
 
@@ -55,7 +62,7 @@
 	return readl(regbase + TIMER_COUNT_VAL);
 }
 
-struct clocksource clocksource = {
+static struct clocksource clocksource = {
 	.name           = "vt8500_timer",
 	.rating         = 200,
 	.read           = vt8500_timer_read,
@@ -98,7 +105,7 @@
 	}
 }
 
-struct clock_event_device clockevent = {
+static struct clock_event_device clockevent = {
 	.name           = "vt8500_timer",
 	.features       = CLOCK_EVT_FEAT_ONESHOT,
 	.rating         = 200,
@@ -115,26 +122,51 @@
 	return IRQ_HANDLED;
 }
 
-struct irqaction irq = {
+static struct irqaction irq = {
 	.name    = "vt8500_timer",
 	.flags   = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
 	.handler = vt8500_timer_interrupt,
 	.dev_id  = &clockevent,
 };
 
-static void __init vt8500_timer_init(void)
+static struct of_device_id vt8500_timer_ids[] = {
+	{ .compatible = "via,vt8500-timer" },
+	{ }
+};
+
+void __init vt8500_timer_init(void)
 {
-	regbase = ioremap(wmt_pmc_base + VT8500_TIMER_OFFSET, 0x28);
-	if (!regbase)
-		printk(KERN_ERR "vt8500_timer_init: failed to map MMIO registers\n");
+	struct device_node *np;
+	int timer_irq;
+
+	np = of_find_matching_node(NULL, vt8500_timer_ids);
+	if (!np) {
+		pr_err("%s: Timer description missing from Device Tree\n",
+								__func__);
+		return;
+	}
+	regbase = of_iomap(np, 0);
+	if (!regbase) {
+		pr_err("%s: Missing iobase description in Device Tree\n",
+								__func__);
+		of_node_put(np);
+		return;
+	}
+	timer_irq = irq_of_parse_and_map(np, 0);
+	if (!timer_irq) {
+		pr_err("%s: Missing irq description in Device Tree\n",
+								__func__);
+		of_node_put(np);
+		return;
+	}
 
 	writel(1, regbase + TIMER_CTRL_VAL);
 	writel(0xf, regbase + TIMER_STATUS_VAL);
 	writel(~0, regbase + TIMER_MATCH_VAL);
 
 	if (clocksource_register_hz(&clocksource, VT8500_TIMER_HZ))
-		printk(KERN_ERR "vt8500_timer_init: clocksource_register failed for %s\n",
-					clocksource.name);
+		pr_err("%s: vt8500_timer_init: clocksource_register failed for %s\n",
+					__func__, clocksource.name);
 
 	clockevents_calc_mult_shift(&clockevent, VT8500_TIMER_HZ, 4);
 
@@ -144,12 +176,9 @@
 	clockevent.min_delta_ns = clockevent_delta2ns(4, &clockevent);
 	clockevent.cpumask = cpumask_of(0);
 
-	if (setup_irq(wmt_timer_irq, &irq))
-		printk(KERN_ERR "vt8500_timer_init: setup_irq failed for %s\n",
-					clockevent.name);
+	if (setup_irq(timer_irq, &irq))
+		pr_err("%s: setup_irq failed for %s\n", __func__,
+							clockevent.name);
 	clockevents_register_device(&clockevent);
 }
 
-struct sys_timer vt8500_timer = {
-	.init = vt8500_timer_init
-};
diff --git a/arch/arm/mach-vt8500/vt8500.c b/arch/arm/mach-vt8500/vt8500.c
new file mode 100644
index 0000000..4494993
--- /dev/null
+++ b/arch/arm/mach-vt8500/vt8500.c
@@ -0,0 +1,196 @@
+/*
+ *  arch/arm/mach-vt8500/vt8500.c
+ *
+ *  Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * 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/io.h>
+#include <linux/pm.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+#include <mach/restart.h>
+#include <mach/gpio.h>
+
+#include "common.h"
+
+#define LEGACY_GPIO_BASE	0xD8110000
+#define LEGACY_PMC_BASE		0xD8130000
+
+/* Registers in GPIO Controller */
+#define VT8500_GPIO_MUX_REG	0x200
+
+/* Registers in Power Management Controller */
+#define VT8500_HCR_REG		0x12
+#define VT8500_PMSR_REG		0x60
+
+static void __iomem *pmc_base;
+
+void vt8500_restart(char mode, const char *cmd)
+{
+	if (pmc_base)
+		writel(1, pmc_base + VT8500_PMSR_REG);
+}
+
+static struct map_desc vt8500_io_desc[] __initdata = {
+	/* SoC MMIO registers */
+	[0] = {
+		.virtual	= 0xf8000000,
+		.pfn		= __phys_to_pfn(0xd8000000),
+		.length		= 0x00390000, /* max of all chip variants */
+		.type		= MT_DEVICE
+	},
+};
+
+void __init vt8500_map_io(void)
+{
+	iotable_init(vt8500_io_desc, ARRAY_SIZE(vt8500_io_desc));
+}
+
+static void vt8500_power_off(void)
+{
+	local_irq_disable();
+	writew(5, pmc_base + VT8500_HCR_REG);
+	asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0));
+}
+
+void __init vt8500_init(void)
+{
+	struct device_node *np, *fb;
+	void __iomem *gpio_base;
+
+#ifdef CONFIG_FB_VT8500
+	fb = of_find_compatible_node(NULL, NULL, "via,vt8500-fb");
+	if (fb) {
+		np = of_find_compatible_node(NULL, NULL, "via,vt8500-gpio");
+		if (np) {
+			gpio_base = of_iomap(np, 0);
+
+			if (!gpio_base)
+				pr_err("%s: of_iomap(gpio_mux) failed\n",
+								__func__);
+
+			of_node_put(np);
+		} else {
+			gpio_base = ioremap(LEGACY_GPIO_BASE, 0x1000);
+			if (!gpio_base)
+				pr_err("%s: ioremap(legacy_gpio_mux) failed\n",
+								__func__);
+		}
+		if (gpio_base) {
+			writel(readl(gpio_base + VT8500_GPIO_MUX_REG) | 1,
+				gpio_base + VT8500_GPIO_MUX_REG);
+			iounmap(gpio_base);
+		} else
+			pr_err("%s: Could not remap GPIO mux\n", __func__);
+
+		of_node_put(fb);
+	}
+#endif
+
+#ifdef CONFIG_FB_WM8505
+	fb = of_find_compatible_node(NULL, NULL, "wm,wm8505-fb");
+	if (fb) {
+		np = of_find_compatible_node(NULL, NULL, "wm,wm8505-gpio");
+		if (!np)
+			np = of_find_compatible_node(NULL, NULL,
+							"wm,wm8650-gpio");
+		if (np) {
+			gpio_base = of_iomap(np, 0);
+
+			if (!gpio_base)
+				pr_err("%s: of_iomap(gpio_mux) failed\n",
+								__func__);
+
+			of_node_put(np);
+		} else {
+			gpio_base = ioremap(LEGACY_GPIO_BASE, 0x1000);
+			if (!gpio_base)
+				pr_err("%s: ioremap(legacy_gpio_mux) failed\n",
+								__func__);
+		}
+		if (gpio_base) {
+			writel(readl(gpio_base + VT8500_GPIO_MUX_REG) |
+				0x80000000, gpio_base + VT8500_GPIO_MUX_REG);
+			iounmap(gpio_base);
+		} else
+			pr_err("%s: Could not remap GPIO mux\n", __func__);
+
+		of_node_put(fb);
+	}
+#endif
+
+	np = of_find_compatible_node(NULL, NULL, "via,vt8500-pmc");
+	if (np) {
+		pmc_base = of_iomap(np, 0);
+
+		if (!pmc_base)
+			pr_err("%s:of_iomap(pmc) failed\n", __func__);
+
+		of_node_put(np);
+	} else {
+		pmc_base = ioremap(LEGACY_PMC_BASE, 0x1000);
+		if (!pmc_base)
+			pr_err("%s:ioremap(power_off) failed\n", __func__);
+	}
+	if (pmc_base)
+		pm_power_off = &vt8500_power_off;
+	else
+		pr_err("%s: PMC Hibernation register could not be remapped, not enabling power off!\n", __func__);
+
+	vtwm_clk_init(pmc_base);
+
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const struct of_device_id vt8500_irq_match[] __initconst = {
+	{ .compatible = "via,vt8500-intc", .data = vt8500_irq_init, },
+	{ /* sentinel */ },
+};
+
+static void __init vt8500_init_irq(void)
+{
+	of_irq_init(vt8500_irq_match);
+};
+
+static struct sys_timer vt8500_timer = {
+	.init = vt8500_timer_init,
+};
+
+static const char * const vt8500_dt_compat[] = {
+	"via,vt8500",
+	"wm,wm8650",
+	"wm,wm8505",
+};
+
+DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)")
+	.dt_compat	= vt8500_dt_compat,
+	.map_io		= vt8500_map_io,
+	.init_irq	= vt8500_init_irq,
+	.timer		= &vt8500_timer,
+	.init_machine	= vt8500_init,
+	.restart	= vt8500_restart,
+MACHINE_END
+
diff --git a/arch/arm/mach-vt8500/wm8505_7in.c b/arch/arm/mach-vt8500/wm8505_7in.c
deleted file mode 100644
index db19886..0000000
--- a/arch/arm/mach-vt8500/wm8505_7in.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  arch/arm/mach-vt8500/wm8505_7in.c
- *
- *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * 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/io.h>
-#include <linux/pm.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <mach/restart.h>
-
-#include "devices.h"
-
-static void __iomem *pmc_hiber;
-
-static struct platform_device *devices[] __initdata = {
-	&vt8500_device_uart0,
-	&vt8500_device_ehci,
-	&vt8500_device_wm8505_fb,
-	&vt8500_device_ge_rops,
-	&vt8500_device_pwm,
-	&vt8500_device_pwmbl,
-	&vt8500_device_rtc,
-};
-
-static void vt8500_power_off(void)
-{
-	local_irq_disable();
-	writew(5, pmc_hiber);
-	asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0));
-}
-
-void __init wm8505_7in_init(void)
-{
-#ifdef CONFIG_FB_WM8505
-	void __iomem *gpio_mux_reg = ioremap(wmt_gpio_base + 0x200, 4);
-	if (gpio_mux_reg) {
-		writel(readl(gpio_mux_reg) | 0x80000000, gpio_mux_reg);
-		iounmap(gpio_mux_reg);
-	} else {
-		printk(KERN_ERR "Could not remap the GPIO mux register, display may not work properly!\n");
-	}
-#endif
-	pmc_hiber = ioremap(wmt_pmc_base + 0x12, 2);
-	if (pmc_hiber)
-		pm_power_off = &vt8500_power_off;
-	else
-		printk(KERN_ERR "PMC Hibernation register could not be remapped, not enabling power off!\n");
-	wmt_setup_restart();
-	wm8505_set_resources();
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-	vt8500_gpio_init();
-}
-
-MACHINE_START(WM8505_7IN_NETBOOK, "WM8505 7-inch generic netbook")
-	.atag_offset	= 0x100,
-	.restart	= wmt_restart,
-	.reserve	= wm8505_reserve_mem,
-	.map_io		= wm8505_map_io,
-	.init_irq	= wm8505_init_irq,
-	.timer		= &vt8500_timer,
-	.init_machine	= wm8505_7in_init,
-MACHINE_END
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 6327536..e48e0da 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -16,6 +16,7 @@
 endif
 obj-$(CONFIG_MACH_LOONGSON1)	+= clk-ls1x.o
 obj-$(CONFIG_ARCH_U8500)	+= ux500/
+obj-$(CONFIG_ARCH_VT8500)	+= clk-vt8500.o
 
 # Chip specific
 obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c
new file mode 100644
index 0000000..a885600
--- /dev/null
+++ b/drivers/clk/clk-vt8500.c
@@ -0,0 +1,510 @@
+/*
+ * Clock implementation for VIA/Wondermedia SoC's
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/bitops.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+
+/* All clocks share the same lock as none can be changed concurrently */
+static DEFINE_SPINLOCK(_lock);
+
+struct clk_device {
+	struct clk_hw	hw;
+	void __iomem	*div_reg;
+	unsigned int	div_mask;
+	void __iomem	*en_reg;
+	int		en_bit;
+	spinlock_t	*lock;
+};
+
+/*
+ * Add new PLL_TYPE_x definitions here as required. Use the first known model
+ * to support the new type as the name.
+ * Add case statements to vtwm_pll_recalc_rate(), vtwm_pll_round_round() and
+ * vtwm_pll_set_rate() to handle the new PLL_TYPE_x
+ */
+
+#define PLL_TYPE_VT8500		0
+#define PLL_TYPE_WM8650		1
+
+struct clk_pll {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	spinlock_t	*lock;
+	int		type;
+};
+
+static void __iomem *pmc_base;
+
+#define to_clk_device(_hw) container_of(_hw, struct clk_device, hw)
+
+#define VT8500_PMC_BUSY_MASK		0x18
+
+static void vt8500_pmc_wait_busy(void)
+{
+	while (readl(pmc_base) & VT8500_PMC_BUSY_MASK)
+		cpu_relax();
+}
+
+static int vt8500_dclk_enable(struct clk_hw *hw)
+{
+	struct clk_device *cdev = to_clk_device(hw);
+	u32 en_val;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(cdev->lock, flags);
+
+	en_val = readl(cdev->en_reg);
+	en_val |= BIT(cdev->en_bit);
+	writel(en_val, cdev->en_reg);
+
+	spin_unlock_irqrestore(cdev->lock, flags);
+	return 0;
+}
+
+static void vt8500_dclk_disable(struct clk_hw *hw)
+{
+	struct clk_device *cdev = to_clk_device(hw);
+	u32 en_val;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(cdev->lock, flags);
+
+	en_val = readl(cdev->en_reg);
+	en_val &= ~BIT(cdev->en_bit);
+	writel(en_val, cdev->en_reg);
+
+	spin_unlock_irqrestore(cdev->lock, flags);
+}
+
+static int vt8500_dclk_is_enabled(struct clk_hw *hw)
+{
+	struct clk_device *cdev = to_clk_device(hw);
+	u32 en_val = (readl(cdev->en_reg) & BIT(cdev->en_bit));
+
+	return en_val ? 1 : 0;
+}
+
+static unsigned long vt8500_dclk_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct clk_device *cdev = to_clk_device(hw);
+	u32 div = readl(cdev->div_reg) & cdev->div_mask;
+
+	/* Special case for SDMMC devices */
+	if ((cdev->div_mask == 0x3F) && (div & BIT(5)))
+		div = 64 * (div & 0x1f);
+
+	/* div == 0 is actually the highest divisor */
+	if (div == 0)
+		div = (cdev->div_mask + 1);
+
+	return parent_rate / div;
+}
+
+static long vt8500_dclk_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *prate)
+{
+	u32 divisor = *prate / rate;
+
+	return *prate / divisor;
+}
+
+static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct clk_device *cdev = to_clk_device(hw);
+	u32 divisor = parent_rate / rate;
+	unsigned long flags = 0;
+
+	if (divisor == cdev->div_mask + 1)
+		divisor = 0;
+
+	if (divisor > cdev->div_mask) {
+		pr_err("%s: invalid divisor for clock\n", __func__);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(cdev->lock, flags);
+
+	vt8500_pmc_wait_busy();
+	writel(divisor, cdev->div_reg);
+	vt8500_pmc_wait_busy();
+
+	spin_lock_irqsave(cdev->lock, flags);
+
+	return 0;
+}
+
+
+static const struct clk_ops vt8500_gated_clk_ops = {
+	.enable = vt8500_dclk_enable,
+	.disable = vt8500_dclk_disable,
+	.is_enabled = vt8500_dclk_is_enabled,
+};
+
+static const struct clk_ops vt8500_divisor_clk_ops = {
+	.round_rate = vt8500_dclk_round_rate,
+	.set_rate = vt8500_dclk_set_rate,
+	.recalc_rate = vt8500_dclk_recalc_rate,
+};
+
+static const struct clk_ops vt8500_gated_divisor_clk_ops = {
+	.enable = vt8500_dclk_enable,
+	.disable = vt8500_dclk_disable,
+	.is_enabled = vt8500_dclk_is_enabled,
+	.round_rate = vt8500_dclk_round_rate,
+	.set_rate = vt8500_dclk_set_rate,
+	.recalc_rate = vt8500_dclk_recalc_rate,
+};
+
+#define CLK_INIT_GATED			BIT(0)
+#define CLK_INIT_DIVISOR		BIT(1)
+#define CLK_INIT_GATED_DIVISOR		(CLK_INIT_DIVISOR | CLK_INIT_GATED)
+
+static __init void vtwm_device_clk_init(struct device_node *node)
+{
+	u32 en_reg, div_reg;
+	struct clk *clk;
+	struct clk_device *dev_clk;
+	const char *clk_name = node->name;
+	const char *parent_name;
+	struct clk_init_data init;
+	int rc;
+	int clk_init_flags = 0;
+
+	dev_clk = kzalloc(sizeof(*dev_clk), GFP_KERNEL);
+	if (WARN_ON(!dev_clk))
+		return;
+
+	dev_clk->lock = &_lock;
+
+	rc = of_property_read_u32(node, "enable-reg", &en_reg);
+	if (!rc) {
+		dev_clk->en_reg = pmc_base + en_reg;
+		rc = of_property_read_u32(node, "enable-bit", &dev_clk->en_bit);
+		if (rc) {
+			pr_err("%s: enable-bit property required for gated clock\n",
+								__func__);
+			return;
+		}
+		clk_init_flags |= CLK_INIT_GATED;
+	}
+
+	rc = of_property_read_u32(node, "divisor-reg", &div_reg);
+	if (!rc) {
+		dev_clk->div_reg = pmc_base + div_reg;
+		/*
+		 * use 0x1f as the default mask since it covers
+		 * almost all the clocks and reduces dts properties
+		 */
+		dev_clk->div_mask = 0x1f;
+
+		of_property_read_u32(node, "divisor-mask", &dev_clk->div_mask);
+		clk_init_flags |= CLK_INIT_DIVISOR;
+	}
+
+	of_property_read_string(node, "clock-output-names", &clk_name);
+
+	switch (clk_init_flags) {
+	case CLK_INIT_GATED:
+		init.ops = &vt8500_gated_clk_ops;
+		break;
+	case CLK_INIT_DIVISOR:
+		init.ops = &vt8500_divisor_clk_ops;
+		break;
+	case CLK_INIT_GATED_DIVISOR:
+		init.ops = &vt8500_gated_divisor_clk_ops;
+		break;
+	default:
+		pr_err("%s: Invalid clock description in device tree\n",
+								__func__);
+		kfree(dev_clk);
+		return;
+	}
+
+	init.name = clk_name;
+	init.flags = 0;
+	parent_name = of_clk_get_parent_name(node, 0);
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	dev_clk->hw.init = &init;
+
+	clk = clk_register(NULL, &dev_clk->hw);
+	if (WARN_ON(IS_ERR(clk))) {
+		kfree(dev_clk);
+		return;
+	}
+	rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	clk_register_clkdev(clk, clk_name, NULL);
+}
+
+
+/* PLL clock related functions */
+
+#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
+
+/* Helper macros for PLL_VT8500 */
+#define VT8500_PLL_MUL(x)	((x & 0x1F) << 1)
+#define VT8500_PLL_DIV(x)	((x & 0x100) ? 1 : 2)
+
+#define VT8500_BITS_TO_FREQ(r, m, d)					\
+				((r / d) * m)
+
+#define VT8500_BITS_TO_VAL(m, d)					\
+				((d == 2 ? 0 : 0x100) | ((m >> 1) & 0x1F))
+
+/* Helper macros for PLL_WM8650 */
+#define WM8650_PLL_MUL(x)	(x & 0x3FF)
+#define WM8650_PLL_DIV(x)	(((x >> 10) & 7) * (1 << ((x >> 13) & 3)))
+
+#define WM8650_BITS_TO_FREQ(r, m, d1, d2)				\
+				(r * m / (d1 * (1 << d2)))
+
+#define WM8650_BITS_TO_VAL(m, d1, d2)					\
+				((d2 << 13) | (d1 << 10) | (m & 0x3FF))
+
+
+static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
+				u32 *multiplier, u32 *prediv)
+{
+	unsigned long tclk;
+
+	/* sanity check */
+	if ((rate < parent_rate * 4) || (rate > parent_rate * 62)) {
+		pr_err("%s: requested rate out of range\n", __func__);
+		*multiplier = 0;
+		*prediv = 1;
+		return;
+	}
+	if (rate <= parent_rate * 31)
+		/* use the prediv to double the resolution */
+		*prediv = 2;
+	else
+		*prediv = 1;
+
+	*multiplier = rate / (parent_rate / *prediv);
+	tclk = (parent_rate / *prediv) * *multiplier;
+
+	if (tclk != rate)
+		pr_warn("%s: requested rate %lu, found rate %lu\n", __func__,
+								rate, tclk);
+}
+
+static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
+				u32 *multiplier, u32 *divisor1, u32 *divisor2)
+{
+	u32 mul, div1, div2;
+	u32 best_mul, best_div1, best_div2;
+	unsigned long tclk, rate_err, best_err;
+
+	best_err = (unsigned long)-1;
+
+	/* Find the closest match (lower or equal to requested) */
+	for (div1 = 5; div1 >= 3; div1--)
+		for (div2 = 3; div2 >= 0; div2--)
+			for (mul = 3; mul <= 1023; mul++) {
+				tclk = parent_rate * mul / (div1 * (1 << div2));
+				if (tclk > rate)
+					continue;
+				/* error will always be +ve */
+				rate_err = rate - tclk;
+				if (rate_err == 0) {
+					*multiplier = mul;
+					*divisor1 = div1;
+					*divisor2 = div2;
+					return;
+				}
+
+				if (rate_err < best_err) {
+					best_err = rate_err;
+					best_mul = mul;
+					best_div1 = div1;
+					best_div2 = div2;
+				}
+			}
+
+	/* if we got here, it wasn't an exact match */
+	pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
+							rate - best_err);
+	*multiplier = mul;
+	*divisor1 = div1;
+	*divisor2 = div2;
+}
+
+static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct clk_pll *pll = to_clk_pll(hw);
+	u32 mul, div1, div2;
+	u32 pll_val;
+	unsigned long flags = 0;
+
+	/* sanity check */
+
+	switch (pll->type) {
+	case PLL_TYPE_VT8500:
+		vt8500_find_pll_bits(rate, parent_rate, &mul, &div1);
+		pll_val = VT8500_BITS_TO_VAL(mul, div1);
+		break;
+	case PLL_TYPE_WM8650:
+		wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
+		pll_val = WM8650_BITS_TO_VAL(mul, div1, div2);
+		break;
+	default:
+		pr_err("%s: invalid pll type\n", __func__);
+		return 0;
+	}
+
+	spin_lock_irqsave(pll->lock, flags);
+
+	vt8500_pmc_wait_busy();
+	writel(pll_val, pll->reg);
+	vt8500_pmc_wait_busy();
+
+	spin_unlock_irqrestore(pll->lock, flags);
+
+	return 0;
+}
+
+static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *prate)
+{
+	struct clk_pll *pll = to_clk_pll(hw);
+	u32 mul, div1, div2;
+	long round_rate;
+
+	switch (pll->type) {
+	case PLL_TYPE_VT8500:
+		vt8500_find_pll_bits(rate, *prate, &mul, &div1);
+		round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1);
+		break;
+	case PLL_TYPE_WM8650:
+		wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2);
+		round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2);
+		break;
+	default:
+		round_rate = 0;
+	}
+
+	return round_rate;
+}
+
+static unsigned long vtwm_pll_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct clk_pll *pll = to_clk_pll(hw);
+	u32 pll_val = readl(pll->reg);
+	unsigned long pll_freq;
+
+	switch (pll->type) {
+	case PLL_TYPE_VT8500:
+		pll_freq = parent_rate * VT8500_PLL_MUL(pll_val);
+		pll_freq /= VT8500_PLL_DIV(pll_val);
+		break;
+	case PLL_TYPE_WM8650:
+		pll_freq = parent_rate * WM8650_PLL_MUL(pll_val);
+		pll_freq /= WM8650_PLL_DIV(pll_val);
+		break;
+	default:
+		pll_freq = 0;
+	}
+
+	return pll_freq;
+}
+
+const struct clk_ops vtwm_pll_ops = {
+	.round_rate = vtwm_pll_round_rate,
+	.set_rate = vtwm_pll_set_rate,
+	.recalc_rate = vtwm_pll_recalc_rate,
+};
+
+static __init void vtwm_pll_clk_init(struct device_node *node, int pll_type)
+{
+	u32 reg;
+	struct clk *clk;
+	struct clk_pll *pll_clk;
+	const char *clk_name = node->name;
+	const char *parent_name;
+	struct clk_init_data init;
+	int rc;
+
+	rc = of_property_read_u32(node, "reg", &reg);
+	if (WARN_ON(rc))
+		return;
+
+	pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
+	if (WARN_ON(!pll_clk))
+		return;
+
+	pll_clk->reg = pmc_base + reg;
+	pll_clk->lock = &_lock;
+	pll_clk->type = pll_type;
+
+	of_property_read_string(node, "clock-output-names", &clk_name);
+
+	init.name = clk_name;
+	init.ops = &vtwm_pll_ops;
+	init.flags = 0;
+	parent_name = of_clk_get_parent_name(node, 0);
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	pll_clk->hw.init = &init;
+
+	clk = clk_register(NULL, &pll_clk->hw);
+	if (WARN_ON(IS_ERR(clk))) {
+		kfree(pll_clk);
+		return;
+	}
+	rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	clk_register_clkdev(clk, clk_name, NULL);
+}
+
+
+/* Wrappers for initialization functions */
+
+static void __init vt8500_pll_init(struct device_node *node)
+{
+	vtwm_pll_clk_init(node, PLL_TYPE_VT8500);
+}
+
+static void __init wm8650_pll_init(struct device_node *node)
+{
+	vtwm_pll_clk_init(node, PLL_TYPE_WM8650);
+}
+
+static const __initconst struct of_device_id clk_match[] = {
+	{ .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
+	{ .compatible = "via,vt8500-pll-clock", .data = vt8500_pll_init, },
+	{ .compatible = "wm,wm8650-pll-clock", .data = wm8650_pll_init, },
+	{ .compatible = "via,vt8500-device-clock",
+					.data = vtwm_device_clk_init, },
+	{ /* sentinel */ }
+};
+
+void __init vtwm_clk_init(void __iomem *base)
+{
+	if (!base)
+		return;
+
+	pmc_base = base;
+
+	of_clk_init(clk_match);
+}
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ba7926f5..a00b828 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -183,6 +183,12 @@
 	  Say yes here to support the STA2x11/ConneXt GPIO device.
 	  The GPIO module has 128 GPIO pins with alternate functions.
 
+config GPIO_VT8500
+	bool "VIA/Wondermedia SoC GPIO Support"
+	depends on ARCH_VT8500
+	help
+	  Say yes here to support the VT8500/WM8505/WM8650 GPIO controller.
+
 config GPIO_XILINX
 	bool "Xilinx GPIO support"
 	depends on PPC_OF || MICROBLAZE
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 153cace..a288142 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -69,6 +69,7 @@
 obj-$(CONFIG_GPIO_TWL4030)	+= gpio-twl4030.o
 obj-$(CONFIG_GPIO_UCB1400)	+= gpio-ucb1400.o
 obj-$(CONFIG_GPIO_VR41XX)	+= gpio-vr41xx.o
+obj-$(CONFIG_GPIO_VT8500)	+= gpio-vt8500.o
 obj-$(CONFIG_GPIO_VX855)	+= gpio-vx855.o
 obj-$(CONFIG_GPIO_WM831X)	+= gpio-wm831x.o
 obj-$(CONFIG_GPIO_WM8350)	+= gpio-wm8350.o
diff --git a/drivers/gpio/gpio-vt8500.c b/drivers/gpio/gpio-vt8500.c
new file mode 100644
index 0000000..bcd8e4a
--- /dev/null
+++ b/drivers/gpio/gpio-vt8500.c
@@ -0,0 +1,316 @@
+/* drivers/gpio/gpio-vt8500.c
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ * Based on arch/arm/mach-vt8500/gpio.c:
+ * - Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/bitops.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_device.h>
+
+/*
+	We handle GPIOs by bank, each bank containing up to 32 GPIOs covered
+	by one set of registers (although not all may be valid).
+
+	Because different SoC's have different register offsets, we pass the
+	register offsets as data in vt8500_gpio_dt_ids[].
+
+	A value of NO_REG is used to indicate that this register is not
+	supported. Only used for ->en at the moment.
+*/
+
+#define NO_REG	0xFFFF
+
+/*
+ * struct vt8500_gpio_bank_regoffsets
+ * @en: offset to enable register of the bank
+ * @dir: offset to direction register of the bank
+ * @data_out: offset to the data out register of the bank
+ * @data_in: offset to the data in register of the bank
+ * @ngpio: highest valid pin in this bank
+ */
+
+struct vt8500_gpio_bank_regoffsets {
+	unsigned int	en;
+	unsigned int	dir;
+	unsigned int	data_out;
+	unsigned int	data_in;
+	unsigned char	ngpio;
+};
+
+struct vt8500_gpio_data {
+	unsigned int				num_banks;
+	struct vt8500_gpio_bank_regoffsets	banks[];
+};
+
+#define VT8500_BANK(__en, __dir, __out, __in, __ngpio)		\
+{								\
+	.en = __en,						\
+	.dir = __dir,						\
+	.data_out = __out,					\
+	.data_in = __in,					\
+	.ngpio = __ngpio,					\
+}
+
+static struct vt8500_gpio_data vt8500_data = {
+	.num_banks	= 7,
+	.banks	= {
+		VT8500_BANK(0x00, 0x20, 0x40, 0x60, 26),
+		VT8500_BANK(0x04, 0x24, 0x44, 0x64, 28),
+		VT8500_BANK(0x08, 0x28, 0x48, 0x68, 31),
+		VT8500_BANK(0x0C, 0x2C, 0x4C, 0x6C, 19),
+		VT8500_BANK(0x10, 0x30, 0x50, 0x70, 19),
+		VT8500_BANK(0x14, 0x34, 0x54, 0x74, 23),
+		VT8500_BANK(NO_REG, 0x3C, 0x5C, 0x7C, 9),
+	},
+};
+
+static struct vt8500_gpio_data wm8505_data = {
+	.num_banks	= 10,
+	.banks	= {
+		VT8500_BANK(0x40, 0x68, 0x90, 0xB8, 8),
+		VT8500_BANK(0x44, 0x6C, 0x94, 0xBC, 32),
+		VT8500_BANK(0x48, 0x70, 0x98, 0xC0, 6),
+		VT8500_BANK(0x4C, 0x74, 0x9C, 0xC4, 16),
+		VT8500_BANK(0x50, 0x78, 0xA0, 0xC8, 25),
+		VT8500_BANK(0x54, 0x7C, 0xA4, 0xCC, 5),
+		VT8500_BANK(0x58, 0x80, 0xA8, 0xD0, 5),
+		VT8500_BANK(0x5C, 0x84, 0xAC, 0xD4, 12),
+		VT8500_BANK(0x60, 0x88, 0xB0, 0xD8, 16),
+		VT8500_BANK(0x64, 0x8C, 0xB4, 0xDC, 22),
+	},
+};
+
+/*
+ * No information about which bits are valid so we just make
+ * them all available until its figured out.
+ */
+static struct vt8500_gpio_data wm8650_data = {
+	.num_banks	= 9,
+	.banks	= {
+		VT8500_BANK(0x40, 0x80, 0xC0, 0x00, 32),
+		VT8500_BANK(0x44, 0x84, 0xC4, 0x04, 32),
+		VT8500_BANK(0x48, 0x88, 0xC8, 0x08, 32),
+		VT8500_BANK(0x4C, 0x8C, 0xCC, 0x0C, 32),
+		VT8500_BANK(0x50, 0x90, 0xD0, 0x10, 32),
+		VT8500_BANK(0x54, 0x94, 0xD4, 0x14, 32),
+		VT8500_BANK(0x58, 0x98, 0xD8, 0x18, 32),
+		VT8500_BANK(0x5C, 0x9C, 0xDC, 0x1C, 32),
+		VT8500_BANK(0x7C, 0xBC, 0xFC, 0x3C, 32),
+	},
+};
+
+struct vt8500_gpio_chip {
+	struct gpio_chip		chip;
+
+	const struct vt8500_gpio_bank_regoffsets *regs;
+	void __iomem	*base;
+};
+
+
+#define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip)
+
+static int vt8500_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	u32 val;
+	struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+
+	if (vt8500_chip->regs->en == NO_REG)
+		return 0;
+
+	val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->en);
+	val |= BIT(offset);
+	writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->en);
+
+	return 0;
+}
+
+static void vt8500_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+	u32 val;
+
+	if (vt8500_chip->regs->en == NO_REG)
+		return;
+
+	val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->en);
+	val &= ~BIT(offset);
+	writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->en);
+}
+
+static int vt8500_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+
+	u32 val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->dir);
+	val &= ~BIT(offset);
+	writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->dir);
+
+	return 0;
+}
+
+static int vt8500_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+								int value)
+{
+	struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+
+	u32 val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->dir);
+	val |= BIT(offset);
+	writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->dir);
+
+	if (value) {
+		val = readl_relaxed(vt8500_chip->base +
+						vt8500_chip->regs->data_out);
+		val |= BIT(offset);
+		writel_relaxed(val, vt8500_chip->base +
+						vt8500_chip->regs->data_out);
+	}
+	return 0;
+}
+
+static int vt8500_gpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+	struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+
+	return (readl_relaxed(vt8500_chip->base + vt8500_chip->regs->data_in) >>
+								offset) & 1;
+}
+
+static void vt8500_gpio_set_value(struct gpio_chip *chip, unsigned offset,
+								int value)
+{
+	struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+
+	u32 val = readl_relaxed(vt8500_chip->base +
+						vt8500_chip->regs->data_out);
+	if (value)
+		val |= BIT(offset);
+	else
+		val &= ~BIT(offset);
+
+	writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->data_out);
+}
+
+static int vt8500_of_xlate(struct gpio_chip *gc,
+			    const struct of_phandle_args *gpiospec, u32 *flags)
+{
+	/* bank if specificed in gpiospec->args[0] */
+	if (flags)
+		*flags = gpiospec->args[2];
+
+	return gpiospec->args[1];
+}
+
+static int vt8500_add_chips(struct platform_device *pdev, void __iomem *base,
+				const struct vt8500_gpio_data *data)
+{
+	struct vt8500_gpio_chip *vtchip;
+	struct gpio_chip *chip;
+	int i;
+	int pin_cnt = 0;
+
+	vtchip = devm_kzalloc(&pdev->dev,
+			sizeof(struct vt8500_gpio_chip) * data->num_banks,
+			GFP_KERNEL);
+	if (!vtchip) {
+		pr_err("%s: failed to allocate chip memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < data->num_banks; i++) {
+		vtchip[i].base = base;
+		vtchip[i].regs = &data->banks[i];
+
+		chip = &vtchip[i].chip;
+
+		chip->of_xlate = vt8500_of_xlate;
+		chip->of_gpio_n_cells = 3;
+		chip->of_node = pdev->dev.of_node;
+
+		chip->request = vt8500_gpio_request;
+		chip->free = vt8500_gpio_free;
+		chip->direction_input = vt8500_gpio_direction_input;
+		chip->direction_output = vt8500_gpio_direction_output;
+		chip->get = vt8500_gpio_get_value;
+		chip->set = vt8500_gpio_set_value;
+		chip->can_sleep = 0;
+		chip->base = pin_cnt;
+		chip->ngpio = data->banks[i].ngpio;
+
+		pin_cnt += data->banks[i].ngpio;
+
+		gpiochip_add(chip);
+	}
+	return 0;
+}
+
+static struct of_device_id vt8500_gpio_dt_ids[] = {
+	{ .compatible = "via,vt8500-gpio", .data = &vt8500_data, },
+	{ .compatible = "wm,wm8505-gpio", .data = &wm8505_data, },
+	{ .compatible = "wm,wm8650-gpio", .data = &wm8650_data, },
+	{ /* Sentinel */ },
+};
+
+static int __devinit vt8500_gpio_probe(struct platform_device *pdev)
+{
+	void __iomem *gpio_base;
+	struct device_node *np;
+	const struct of_device_id *of_id =
+				of_match_device(vt8500_gpio_dt_ids, &pdev->dev);
+
+	if (!of_id) {
+		dev_err(&pdev->dev, "Failed to find gpio controller\n");
+		return -ENODEV;
+	}
+
+	np = pdev->dev.of_node;
+	if (!np) {
+		dev_err(&pdev->dev, "Missing GPIO description in devicetree\n");
+		return -EFAULT;
+	}
+
+	gpio_base = of_iomap(np, 0);
+	if (!gpio_base) {
+		dev_err(&pdev->dev, "Unable to map GPIO registers\n");
+		of_node_put(np);
+		return -ENOMEM;
+	}
+
+	vt8500_add_chips(pdev, gpio_base, of_id->data);
+
+	return 0;
+}
+
+static struct platform_driver vt8500_gpio_driver = {
+	.probe		= vt8500_gpio_probe,
+	.driver		= {
+		.name	= "vt8500-gpio",
+		.owner	= THIS_MODULE,
+		.of_match_table = vt8500_gpio_dt_ids,
+	},
+};
+
+module_platform_driver(vt8500_gpio_driver);
+
+MODULE_DESCRIPTION("VT8500 GPIO Driver");
+MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, vt8500_gpio_dt_ids);
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c
index 9e94fb1..07bf193 100644
--- a/drivers/rtc/rtc-vt8500.c
+++ b/drivers/rtc/rtc-vt8500.c
@@ -23,6 +23,7 @@
 #include <linux/bcd.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/of.h>
 
 /*
  * Register definitions
@@ -302,12 +303,18 @@
 	return 0;
 }
 
+static const struct of_device_id wmt_dt_ids[] = {
+	{ .compatible = "via,vt8500-rtc", },
+	{}
+};
+
 static struct platform_driver vt8500_rtc_driver = {
 	.probe		= vt8500_rtc_probe,
 	.remove		= __devexit_p(vt8500_rtc_remove),
 	.driver		= {
 		.name	= "vt8500-rtc",
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(wmt_dt_ids),
 	},
 };
 
@@ -315,5 +322,5 @@
 
 MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>");
 MODULE_DESCRIPTION("VIA VT8500 SoC Realtime Clock Driver (RTC)");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:vt8500-rtc");
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c
index 2be006f..205d4cf 100644
--- a/drivers/tty/serial/vt8500_serial.c
+++ b/drivers/tty/serial/vt8500_serial.c
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 
 /*
  * UART Register offsets
@@ -76,6 +77,8 @@
 #define RX_FIFO_INTS	(RXFAF | RXFF | RXOVER | PER | FER | RXTOUT)
 #define TX_FIFO_INTS	(TXFAE | TXFE | TXUDR)
 
+#define VT8500_MAX_PORTS	6
+
 struct vt8500_port {
 	struct uart_port	uart;
 	char			name[16];
@@ -83,6 +86,13 @@
 	unsigned int		ier;
 };
 
+/*
+ * we use this variable to keep track of which ports
+ * have been allocated as we can't use pdev->id in
+ * devicetree
+ */
+static unsigned long vt8500_ports_in_use;
+
 static inline void vt8500_write(struct uart_port *port, unsigned int val,
 			     unsigned int off)
 {
@@ -431,7 +441,7 @@
 	return 0;
 }
 
-static struct vt8500_port *vt8500_uart_ports[4];
+static struct vt8500_port *vt8500_uart_ports[VT8500_MAX_PORTS];
 static struct uart_driver vt8500_uart_driver;
 
 #ifdef CONFIG_SERIAL_VT8500_CONSOLE
@@ -548,7 +558,9 @@
 {
 	struct vt8500_port *vt8500_port;
 	struct resource *mmres, *irqres;
+	struct device_node *np = pdev->dev.of_node;
 	int ret;
+	int port;
 
 	mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -559,16 +571,46 @@
 	if (!vt8500_port)
 		return -ENOMEM;
 
+	if (np)
+		port = of_alias_get_id(np, "serial");
+		if (port > VT8500_MAX_PORTS)
+			port = -1;
+	else
+		port = -1;
+
+	if (port < 0) {
+		/* calculate the port id */
+		port = find_first_zero_bit(&vt8500_ports_in_use,
+					sizeof(vt8500_ports_in_use));
+	}
+
+	if (port > VT8500_MAX_PORTS)
+		return -ENODEV;
+
+	/* reserve the port id */
+	if (test_and_set_bit(port, &vt8500_ports_in_use)) {
+		/* port already in use - shouldn't really happen */
+		return -EBUSY;
+	}
+
 	vt8500_port->uart.type = PORT_VT8500;
 	vt8500_port->uart.iotype = UPIO_MEM;
 	vt8500_port->uart.mapbase = mmres->start;
 	vt8500_port->uart.irq = irqres->start;
 	vt8500_port->uart.fifosize = 16;
 	vt8500_port->uart.ops = &vt8500_uart_pops;
-	vt8500_port->uart.line = pdev->id;
+	vt8500_port->uart.line = port;
 	vt8500_port->uart.dev = &pdev->dev;
 	vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
-	vt8500_port->uart.uartclk = 24000000;
+
+	vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0);
+	if (vt8500_port->clk) {
+		vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);
+	} else {
+		/* use the default of 24Mhz if not specified and warn */
+		pr_warn("%s: serial clock source not specified\n", __func__);
+		vt8500_port->uart.uartclk = 24000000;
+	}
 
 	snprintf(vt8500_port->name, sizeof(vt8500_port->name),
 		 "VT8500 UART%d", pdev->id);
@@ -579,7 +621,7 @@
 		goto err;
 	}
 
-	vt8500_uart_ports[pdev->id] = vt8500_port;
+	vt8500_uart_ports[port] = vt8500_port;
 
 	uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart);
 
@@ -603,12 +645,18 @@
 	return 0;
 }
 
+static const struct of_device_id wmt_dt_ids[] = {
+	{ .compatible = "via,vt8500-uart", },
+	{}
+};
+
 static struct platform_driver vt8500_platform_driver = {
 	.probe  = vt8500_serial_probe,
 	.remove = __devexit_p(vt8500_serial_remove),
 	.driver = {
 		.name = "vt8500_serial",
 		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(wmt_dt_ids),
 	},
 };
 
@@ -642,4 +690,4 @@
 
 MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>");
 MODULE_DESCRIPTION("Driver for vt8500 serial device");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 0217f74..b66d951 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1788,7 +1788,7 @@
 
 config FB_VT8500
 	bool "VT8500 LCD Driver"
-	depends on (FB = y) && ARM && ARCH_VT8500 && VTWM_VERSION_VT8500
+	depends on (FB = y) && ARM && ARCH_VT8500
 	select FB_WMT_GE_ROPS
 	select FB_SYS_IMAGEBLIT
 	help
@@ -1797,11 +1797,11 @@
 
 config FB_WM8505
 	bool "WM8505 frame buffer support"
-	depends on (FB = y) && ARM && ARCH_VT8500 && VTWM_VERSION_WM8505
+	depends on (FB = y) && ARM && ARCH_VT8500
 	select FB_WMT_GE_ROPS
 	select FB_SYS_IMAGEBLIT
 	help
-	  This is the framebuffer driver for WonderMedia WM8505
+	  This is the framebuffer driver for WonderMedia WM8505/WM8650
 	  integrated LCD controller.
 
 source "drivers/video/geode/Kconfig"
diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/vt8500lcdfb.c
index 2a5fe6e..d24595c 100644
--- a/drivers/video/vt8500lcdfb.c
+++ b/drivers/video/vt8500lcdfb.c
@@ -35,6 +35,13 @@
 #include "vt8500lcdfb.h"
 #include "wmt_ge_rops.h"
 
+#ifdef CONFIG_OF
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/memblock.h>
+#endif
+
+
 #define to_vt8500lcd_info(__info) container_of(__info, \
 						struct vt8500lcd_info, fb)
 
@@ -270,15 +277,21 @@
 {
 	struct vt8500lcd_info *fbi;
 	struct resource *res;
-	struct vt8500fb_platform_data *pdata = pdev->dev.platform_data;
 	void *addr;
 	int irq, ret;
 
+	struct fb_videomode	of_mode;
+	struct device_node	*np;
+	u32			bpp;
+	dma_addr_t fb_mem_phys;
+	unsigned long fb_mem_len;
+	void *fb_mem_virt;
+
 	ret = -ENOMEM;
 	fbi = NULL;
 
-	fbi = kzalloc(sizeof(struct vt8500lcd_info) + sizeof(u32) * 16,
-							GFP_KERNEL);
+	fbi = devm_kzalloc(&pdev->dev, sizeof(struct vt8500lcd_info)
+			+ sizeof(u32) * 16, GFP_KERNEL);
 	if (!fbi) {
 		dev_err(&pdev->dev, "Failed to initialize framebuffer device\n");
 		ret = -ENOMEM;
@@ -333,9 +346,45 @@
 		goto failed_free_res;
 	}
 
-	fbi->fb.fix.smem_start	= pdata->video_mem_phys;
-	fbi->fb.fix.smem_len	= pdata->video_mem_len;
-	fbi->fb.screen_base	= pdata->video_mem_virt;
+	np = of_parse_phandle(pdev->dev.of_node, "default-mode", 0);
+	if (!np) {
+		pr_err("%s: No display description in Device Tree\n", __func__);
+		ret = -EINVAL;
+		goto failed_free_res;
+	}
+
+	/*
+	 * This code is copied from Sascha Hauer's of_videomode helper
+	 * and can be replaced with a call to the helper once mainlined
+	 */
+	ret = 0;
+	ret |= of_property_read_u32(np, "hactive", &of_mode.xres);
+	ret |= of_property_read_u32(np, "vactive", &of_mode.yres);
+	ret |= of_property_read_u32(np, "hback-porch", &of_mode.left_margin);
+	ret |= of_property_read_u32(np, "hfront-porch", &of_mode.right_margin);
+	ret |= of_property_read_u32(np, "hsync-len", &of_mode.hsync_len);
+	ret |= of_property_read_u32(np, "vback-porch", &of_mode.upper_margin);
+	ret |= of_property_read_u32(np, "vfront-porch", &of_mode.lower_margin);
+	ret |= of_property_read_u32(np, "vsync-len", &of_mode.vsync_len);
+	ret |= of_property_read_u32(np, "bpp", &bpp);
+	if (ret) {
+		pr_err("%s: Unable to read display properties\n", __func__);
+		goto failed_free_res;
+	}
+	of_mode.vmode = FB_VMODE_NONINTERLACED;
+
+	/* try allocating the framebuffer */
+	fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8);
+	fb_mem_virt = dma_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys,
+				GFP_KERNEL);
+	if (!fb_mem_virt) {
+		pr_err("%s: Failed to allocate framebuffer\n", __func__);
+		return -ENOMEM;
+	};
+
+	fbi->fb.fix.smem_start	= fb_mem_phys;
+	fbi->fb.fix.smem_len	= fb_mem_len;
+	fbi->fb.screen_base	= fb_mem_virt;
 
 	fbi->palette_size	= PAGE_ALIGN(512);
 	fbi->palette_cpu	= dma_alloc_coherent(&pdev->dev,
@@ -370,10 +419,11 @@
 		goto failed_free_irq;
 	}
 
-	fb_videomode_to_var(&fbi->fb.var, &pdata->mode);
-	fbi->fb.var.bits_per_pixel	= pdata->bpp;
-	fbi->fb.var.xres_virtual	= pdata->xres_virtual;
-	fbi->fb.var.yres_virtual	= pdata->yres_virtual;
+	fb_videomode_to_var(&fbi->fb.var, &of_mode);
+
+	fbi->fb.var.xres_virtual	= of_mode.xres;
+	fbi->fb.var.yres_virtual	= of_mode.yres * 2;
+	fbi->fb.var.bits_per_pixel	= bpp;
 
 	ret = vt8500lcd_set_par(&fbi->fb);
 	if (ret) {
@@ -448,12 +498,18 @@
 	return 0;
 }
 
+static const struct of_device_id via_dt_ids[] = {
+	{ .compatible = "via,vt8500-fb", },
+	{}
+};
+
 static struct platform_driver vt8500lcd_driver = {
 	.probe		= vt8500lcd_probe,
 	.remove		= __devexit_p(vt8500lcd_remove),
 	.driver		= {
 		.owner	= THIS_MODULE,
 		.name	= "vt8500-lcd",
+		.of_match_table = of_match_ptr(via_dt_ids),
 	},
 };
 
@@ -461,4 +517,5 @@
 
 MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>");
 MODULE_DESCRIPTION("LCD controller driver for VIA VT8500");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, via_dt_ids);
diff --git a/drivers/video/wm8505fb.c b/drivers/video/wm8505fb.c
index c8703bd..ec47424 100644
--- a/drivers/video/wm8505fb.c
+++ b/drivers/video/wm8505fb.c
@@ -28,6 +28,9 @@
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/wait.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/memblock.h>
 
 #include <mach/vt8500fb.h>
 
@@ -59,8 +62,12 @@
 	writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR);
 	writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR1);
 
-	/* Set in-memory picture format to RGB 32bpp */
-	writel(0x1c,		       fbi->regbase + WMT_GOVR_COLORSPACE);
+	/*
+	 * Set in-memory picture format to RGB
+	 * 0x31C sets the correct color mode (RGB565) for WM8650
+	 * Bit 8+9 (0x300) are ignored on WM8505 as reserved
+	 */
+	writel(0x31c,		       fbi->regbase + WMT_GOVR_COLORSPACE);
 	writel(1,		       fbi->regbase + WMT_GOVR_COLORSPACE1);
 
 	/* Virtual buffer size */
@@ -127,6 +134,18 @@
 		info->var.blue.msb_right = 0;
 		info->fix.visual = FB_VISUAL_TRUECOLOR;
 		info->fix.line_length = info->var.xres_virtual << 2;
+	} else if (info->var.bits_per_pixel == 16) {
+		info->var.red.offset = 11;
+		info->var.red.length = 5;
+		info->var.red.msb_right = 0;
+		info->var.green.offset = 5;
+		info->var.green.length = 6;
+		info->var.green.msb_right = 0;
+		info->var.blue.offset = 0;
+		info->var.blue.length = 5;
+		info->var.blue.msb_right = 0;
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+		info->fix.line_length = info->var.xres_virtual << 1;
 	}
 
 	wm8505fb_set_timing(info);
@@ -246,16 +265,20 @@
 	struct wm8505fb_info	*fbi;
 	struct resource		*res;
 	void			*addr;
-	struct vt8500fb_platform_data *pdata;
 	int ret;
 
-	pdata = pdev->dev.platform_data;
+	struct fb_videomode	of_mode;
+	struct device_node	*np;
+	u32			bpp;
+	dma_addr_t fb_mem_phys;
+	unsigned long fb_mem_len;
+	void *fb_mem_virt;
 
 	ret = -ENOMEM;
 	fbi = NULL;
 
-	fbi = kzalloc(sizeof(struct wm8505fb_info) + sizeof(u32) * 16,
-							GFP_KERNEL);
+	fbi = devm_kzalloc(&pdev->dev, sizeof(struct wm8505fb_info) +
+			sizeof(u32) * 16, GFP_KERNEL);
 	if (!fbi) {
 		dev_err(&pdev->dev, "Failed to initialize framebuffer device\n");
 		ret = -ENOMEM;
@@ -305,21 +328,58 @@
 		goto failed_free_res;
 	}
 
-	fb_videomode_to_var(&fbi->fb.var, &pdata->mode);
+	np = of_parse_phandle(pdev->dev.of_node, "default-mode", 0);
+	if (!np) {
+		pr_err("%s: No display description in Device Tree\n", __func__);
+		ret = -EINVAL;
+		goto failed_free_res;
+	}
+
+	/*
+	 * This code is copied from Sascha Hauer's of_videomode helper
+	 * and can be replaced with a call to the helper once mainlined
+	 */
+	ret = 0;
+	ret |= of_property_read_u32(np, "hactive", &of_mode.xres);
+	ret |= of_property_read_u32(np, "vactive", &of_mode.yres);
+	ret |= of_property_read_u32(np, "hback-porch", &of_mode.left_margin);
+	ret |= of_property_read_u32(np, "hfront-porch", &of_mode.right_margin);
+	ret |= of_property_read_u32(np, "hsync-len", &of_mode.hsync_len);
+	ret |= of_property_read_u32(np, "vback-porch", &of_mode.upper_margin);
+	ret |= of_property_read_u32(np, "vfront-porch", &of_mode.lower_margin);
+	ret |= of_property_read_u32(np, "vsync-len", &of_mode.vsync_len);
+	ret |= of_property_read_u32(np, "bpp", &bpp);
+	if (ret) {
+		pr_err("%s: Unable to read display properties\n", __func__);
+		goto failed_free_res;
+	}
+
+	of_mode.vmode = FB_VMODE_NONINTERLACED;
+	fb_videomode_to_var(&fbi->fb.var, &of_mode);
 
 	fbi->fb.var.nonstd		= 0;
 	fbi->fb.var.activate		= FB_ACTIVATE_NOW;
 
 	fbi->fb.var.height		= -1;
 	fbi->fb.var.width		= -1;
-	fbi->fb.var.xres_virtual	= pdata->xres_virtual;
-	fbi->fb.var.yres_virtual	= pdata->yres_virtual;
-	fbi->fb.var.bits_per_pixel	= pdata->bpp;
 
-	fbi->fb.fix.smem_start	= pdata->video_mem_phys;
-	fbi->fb.fix.smem_len	= pdata->video_mem_len;
-	fbi->fb.screen_base	= pdata->video_mem_virt;
-	fbi->fb.screen_size	= pdata->video_mem_len;
+	/* try allocating the framebuffer */
+	fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8);
+	fb_mem_virt = dma_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys,
+				GFP_KERNEL);
+	if (!fb_mem_virt) {
+		pr_err("%s: Failed to allocate framebuffer\n", __func__);
+		return -ENOMEM;
+	};
+
+	fbi->fb.var.xres_virtual	= of_mode.xres;
+	fbi->fb.var.yres_virtual	= of_mode.yres * 2;
+	fbi->fb.var.bits_per_pixel	= bpp;
+
+	fbi->fb.fix.smem_start		= fb_mem_phys;
+	fbi->fb.fix.smem_len		= fb_mem_len;
+	fbi->fb.screen_base		= fb_mem_virt;
+	fbi->fb.screen_size		= fb_mem_len;
 
 	if (fb_alloc_cmap(&fbi->fb.cmap, 256, 0) < 0) {
 		dev_err(&pdev->dev, "Failed to allocate color map\n");
@@ -395,12 +455,18 @@
 	return 0;
 }
 
+static const struct of_device_id wmt_dt_ids[] = {
+	{ .compatible = "wm,wm8505-fb", },
+	{}
+};
+
 static struct platform_driver wm8505fb_driver = {
 	.probe		= wm8505fb_probe,
 	.remove		= __devexit_p(wm8505fb_remove),
 	.driver		= {
 		.owner	= THIS_MODULE,
 		.name	= DRIVER_NAME,
+		.of_match_table = of_match_ptr(wmt_dt_ids),
 	},
 };
 
@@ -408,4 +474,5 @@
 
 MODULE_AUTHOR("Ed Spiridonov <edo.rus@gmail.com>");
 MODULE_DESCRIPTION("Framebuffer driver for WMT WM8505");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, wmt_dt_ids);
diff --git a/drivers/video/wmt_ge_rops.c b/drivers/video/wmt_ge_rops.c
index 55be386..ba025b4 100644
--- a/drivers/video/wmt_ge_rops.c
+++ b/drivers/video/wmt_ge_rops.c
@@ -158,12 +158,18 @@
 	return 0;
 }
 
+static const struct of_device_id wmt_dt_ids[] = {
+	{ .compatible = "wm,prizm-ge-rops", },
+	{ /* sentinel */ }
+};
+
 static struct platform_driver wmt_ge_rops_driver = {
 	.probe		= wmt_ge_rops_probe,
 	.remove		= __devexit_p(wmt_ge_rops_remove),
 	.driver		= {
 		.owner	= THIS_MODULE,
 		.name	= "wmt_ge_rops",
+		.of_match_table = of_match_ptr(wmt_dt_ids),
 	},
 };
 
@@ -172,4 +178,5 @@
 MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com");
 MODULE_DESCRIPTION("Accelerators for raster operations using "
 		   "WonderMedia Graphics Engine");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, wmt_dt_ids);