Merge tag 'vt8500-for-next' of git://git.code.sf.net/p/linuxwmt/code into next/dt
authorOlof Johansson <olof@lixom.net>
Mon, 24 Sep 2012 04:51:39 +0000 (21:51 -0700)
committerOlof Johansson <olof@lixom.net>
Mon, 24 Sep 2012 04:51:39 +0000 (21:51 -0700)
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>
51 files changed:
Documentation/devicetree/bindings/arm/vt8500.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/vt8500/via,vt8500-intc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/vt8500/via,vt8500-pmc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/vt8500/via,vt8500-timer.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/vt8500.txt [new file with mode: 0644]
Documentation/devicetree/bindings/gpio/gpio-vt8500.txt [new file with mode: 0644]
Documentation/devicetree/bindings/rtc/via,vt8500-rtc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/tty/serial/via,vt8500-uart.txt [new file with mode: 0644]
Documentation/devicetree/bindings/usb/platform-uhci.txt [new file with mode: 0644]
Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt [new file with mode: 0644]
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/devicetree/bindings/video/via,vt8500-fb.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/wm,prizm-ge-rops.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/wm,wm8505-fb.txt [new file with mode: 0644]
arch/arm/Kconfig
arch/arm/boot/dts/vt8500-bv07.dts [new file with mode: 0644]
arch/arm/boot/dts/vt8500.dtsi [new file with mode: 0644]
arch/arm/boot/dts/wm8505-ref.dts [new file with mode: 0644]
arch/arm/boot/dts/wm8505.dtsi [new file with mode: 0644]
arch/arm/boot/dts/wm8650-mid.dts [new file with mode: 0644]
arch/arm/boot/dts/wm8650.dtsi [new file with mode: 0644]
arch/arm/mach-vt8500/Kconfig [deleted file]
arch/arm/mach-vt8500/Makefile
arch/arm/mach-vt8500/bv07.c [deleted file]
arch/arm/mach-vt8500/common.h [new file with mode: 0644]
arch/arm/mach-vt8500/devices-vt8500.c [deleted file]
arch/arm/mach-vt8500/devices-wm8505.c [deleted file]
arch/arm/mach-vt8500/devices.c [deleted file]
arch/arm/mach-vt8500/devices.h [deleted file]
arch/arm/mach-vt8500/gpio.c [deleted file]
arch/arm/mach-vt8500/include/mach/restart.h
arch/arm/mach-vt8500/include/mach/vt8500_irqs.h [deleted file]
arch/arm/mach-vt8500/include/mach/vt8500_regs.h [deleted file]
arch/arm/mach-vt8500/include/mach/wm8505_irqs.h [deleted file]
arch/arm/mach-vt8500/include/mach/wm8505_regs.h [deleted file]
arch/arm/mach-vt8500/irq.c
arch/arm/mach-vt8500/restart.c [deleted file]
arch/arm/mach-vt8500/timer.c
arch/arm/mach-vt8500/vt8500.c [new file with mode: 0644]
arch/arm/mach-vt8500/wm8505_7in.c [deleted file]
drivers/clk/Makefile
drivers/clk/clk-vt8500.c [new file with mode: 0644]
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-vt8500.c [new file with mode: 0644]
drivers/rtc/rtc-vt8500.c
drivers/tty/serial/vt8500_serial.c
drivers/video/Kconfig
drivers/video/vt8500lcdfb.c
drivers/video/wm8505fb.c
drivers/video/wmt_ge_rops.c

diff --git a/Documentation/devicetree/bindings/arm/vt8500.txt b/Documentation/devicetree/bindings/arm/vt8500.txt
new file mode 100644 (file)
index 0000000..d657832
--- /dev/null
@@ -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 (file)
index 0000000..0a4ce10
--- /dev/null
@@ -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 (file)
index 0000000..521b9c7
--- /dev/null
@@ -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 (file)
index 0000000..901c73f
--- /dev/null
@@ -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 (file)
index 0000000..a880c70
--- /dev/null
@@ -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 (file)
index 0000000..f4dc523
--- /dev/null
@@ -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 (file)
index 0000000..3c0484c
--- /dev/null
@@ -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 (file)
index 0000000..5feef1e
--- /dev/null
@@ -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 (file)
index 0000000..a4fb071
--- /dev/null
@@ -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 (file)
index 0000000..17b3ad1
--- /dev/null
@@ -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>;
+       };
index db4d3af3643c407ffad6e4ead2dd81d8c4ab36cf..5c63da29aa0590ff6c9d09ccb5f3fc766cabae67 100644 (file)
@@ -47,5 +47,7 @@ sirf  SiRF Technology, Inc.
 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 (file)
index 0000000..c870b64
--- /dev/null
@@ -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 (file)
index 0000000..a850fa0
--- /dev/null
@@ -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 (file)
index 0000000..3d325e1
--- /dev/null
@@ -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>;
+       };
index de325f4615bd0ae6a76b9ba82b828a928cfdcbd6..1fd9bcd25b4d70c663b1863d3d3f139e4317d339 100644 (file)
@@ -1004,6 +1004,10 @@ config ARCH_VT8500
        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-versatile/Kconfig"
 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 @@ config ARCH_NR_GPIO
        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 (file)
index 0000000..567cf4e
--- /dev/null
@@ -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 (file)
index 0000000..d8645e9
--- /dev/null
@@ -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 (file)
index 0000000..fd4e248
--- /dev/null
@@ -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 (file)
index 0000000..b459691
--- /dev/null
@@ -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 (file)
index 0000000..cefd938
--- /dev/null
@@ -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 (file)
index 0000000..83b9467
--- /dev/null
@@ -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 (file)
index 2c20a34..0000000
+++ /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
index 7ce51767c99c3843091a86fc06b1660b84fd9f3a..e035251cda489c1b5ed8901449f539fcf514d151 100644 (file)
@@ -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 (file)
index f9fbeb2..0000000
+++ /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 (file)
index 0000000..2b24196
--- /dev/null
@@ -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 (file)
index 19519ae..0000000
+++ /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 (file)
index db4594e..0000000
+++ /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 (file)
index 1fcdc36..0000000
+++ /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 (file)
index 188d4e1..0000000
+++ /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 (file)
index 2bcc0ec..0000000
+++ /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);
-}
index 89f9b787d2a064c96255d9a23b1968275c43eef3..738979518acb0fb50b3d9a74fab12ba0afe1ad1c 100644 (file)
@@ -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 (file)
index ecfee91..0000000
+++ /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 (file)
index 29c63ec..0000000
+++ /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 (file)
index 6128627..0000000
+++ /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 (file)
index df15509..0000000
+++ /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
index 642de0408f25731eb6081958cafa67beb793c4ab..f8f9ab9bc56eb06e3e85b80fd3dfed94b6db3d4b 100644 (file)
@@ -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
  * 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 @@ static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type)
                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 @@ static struct irq_chip vt8500_irq_chip = {
        .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 < 64; i++) {
+               /* Disable all interrupts and route them to IRQ */
+               writeb(VT8500_INT_DISABLE | ICDC_IRQ,
+                                               base + VT8500_ICDC + i);
+       }
+}
 
-               for (i = 0; i < wmt_nr_irqs; i++) {
-                       /* Disable all interrupts and route them to IRQ */
-                       writeb(0x00, ic_regbase + VT8500_IC_DCTR + i);
+static int vt8500_irq_map(struct irq_domain *h, unsigned int virq,
+                                                       irq_hw_number_t hw)
+{
+       irq_set_chip_and_handler(virq, &vt8500_irq_chip, handle_level_irq);
+       set_irq_flags(virq, IRQF_VALID);
 
-                       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;
 }
 
-void __init wm8505_init_irq(void)
+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)
 {
-       unsigned int i;
+       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);
 
-       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);
+       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;
                }
-       } else {
-               printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n");
+
+               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 (file)
index 497e89a..0000000
+++ /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);
-}
index d5376c592ab6fcc6480ec7cf1b65baf58bbcc08c..050e1833f2d0078ed62134a0305cc71bc0378b8b 100644 (file)
@@ -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
  * 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 @@ static cycle_t vt8500_timer_read(struct clocksource *cs)
        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 @@ static void vt8500_timer_set_mode(enum clock_event_mode mode,
        }
 }
 
-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 @@ static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id)
        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 @@ static void __init vt8500_timer_init(void)
        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 (file)
index 0000000..4494993
--- /dev/null
@@ -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 (file)
index db19886..0000000
+++ /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
index 6327536b4900ae5e06d8da313af721c9dc4b9c4a..e48e0da5a88467cd4d9fa45600355f15f10caf1a 100644 (file)
@@ -16,6 +16,7 @@ obj-$(CONFIG_ARCH_MMP)                += mmp/
 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 (file)
index 0000000..a885600
--- /dev/null
@@ -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);
+}
index ba7926f5c0996ea78f571ab5e87de2a3aa2c490e..a00b828b1643ddfbcd90f219525a93fe15efc5af 100644 (file)
@@ -183,6 +183,12 @@ config GPIO_STA2X11
          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
index 153caceeb0530df7a7e5932421b7f2d48fee3780..a288142ad99879fd1da7484bcca4f4fd5586e567 100644 (file)
@@ -69,6 +69,7 @@ obj-$(CONFIG_GPIO_TPS65912)   += gpio-tps65912.o
 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 (file)
index 0000000..bcd8e4a
--- /dev/null
@@ -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);
index 9e94fb147c26afcffe92ad7175cb011051ca5fb8..07bf19364a74732baf2f34dfa3c1fdb984e8cb8a 100644 (file)
@@ -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 @@ static int __devexit vt8500_rtc_remove(struct platform_device *pdev)
        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_platform_driver(vt8500_rtc_driver);
 
 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");
index 2be006fb3da0d3d1ff0ad7dd2aa3c1da8d49ae82..205d4cf4a063bf404e126b97bcfb71c3d3ed3d87 100644 (file)
@@ -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 @@ struct vt8500_port {
        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 @@ static int vt8500_verify_port(struct uart_port *port,
        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 @@ static int __devinit vt8500_serial_probe(struct platform_device *pdev)
 {
        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 @@ static int __devinit vt8500_serial_probe(struct platform_device *pdev)
        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 @@ static int __devinit vt8500_serial_probe(struct platform_device *pdev)
                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 @@ static int __devexit vt8500_serial_remove(struct platform_device *pdev)
        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_exit(vt8500_serial_exit);
 
 MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>");
 MODULE_DESCRIPTION("Driver for vt8500 serial device");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index 0217f7415ef5d6997dd82de449066a2c9643b096..b66d951b8e32beb355ce367b3d61500d53de0940 100644 (file)
@@ -1788,7 +1788,7 @@ config FB_AU1200
 
 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_VT8500
 
 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"
index 2a5fe6ede845a96dcfdf40c6e48c5295c11ba756..d24595cd0c9b1601ce72e6ad67adf00f3f2313f5 100644 (file)
 #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 @@ static int __devinit vt8500lcd_probe(struct platform_device *pdev)
 {
        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 @@ static int __devinit vt8500lcd_probe(struct platform_device *pdev)
                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 @@ static int __devinit vt8500lcd_probe(struct platform_device *pdev)
                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 @@ static int __devexit vt8500lcd_remove(struct platform_device *pdev)
        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_platform_driver(vt8500lcd_driver);
 
 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);
index c8703bd61b74f6c2a9a77c8e7ebdb1aadcfa63d0..ec4742442103c7c8f31ce1e8adc8bb32277d871d 100644 (file)
@@ -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 @@ static int wm8505fb_init_hw(struct fb_info *info)
        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 @@ static int wm8505fb_set_par(struct fb_info *info)
                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 @@ static int __devinit wm8505fb_probe(struct platform_device *pdev)
        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 @@ static int __devinit wm8505fb_probe(struct platform_device *pdev)
                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 @@ static int __devexit wm8505fb_remove(struct platform_device *pdev)
        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_platform_driver(wm8505fb_driver);
 
 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);
index 55be3865015bd103aabd9a1bdb1d7837c6c0530d..ba025b4c7d095b562cf5fae84a16914b9473aa37 100644 (file)
@@ -158,12 +158,18 @@ static int __devexit wmt_ge_rops_remove(struct platform_device *pdev)
        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_platform_driver(wmt_ge_rops_driver);
 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);
This page took 0.081564 seconds and 5 git commands to generate.