aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig12
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/compressed/Makefile4
-rw-r--r--arch/arm/boot/compressed/head-vt8500.S46
-rw-r--r--arch/arm/mach-vt8500/Kconfig73
-rw-r--r--arch/arm/mach-vt8500/Makefile9
-rw-r--r--arch/arm/mach-vt8500/Makefile.boot3
-rw-r--r--arch/arm/mach-vt8500/bv07.c77
-rw-r--r--arch/arm/mach-vt8500/devices-vt8500.c91
-rw-r--r--arch/arm/mach-vt8500/devices-wm8505.c99
-rw-r--r--arch/arm/mach-vt8500/devices.c270
-rw-r--r--arch/arm/mach-vt8500/devices.h88
-rw-r--r--arch/arm/mach-vt8500/gpio.c240
-rw-r--r--arch/arm/mach-vt8500/include/mach/debug-macro.S31
-rw-r--r--arch/arm/mach-vt8500/include/mach/entry-macro.S32
-rw-r--r--arch/arm/mach-vt8500/include/mach/gpio.h6
-rw-r--r--arch/arm/mach-vt8500/include/mach/hardware.h12
-rw-r--r--arch/arm/mach-vt8500/include/mach/i8042.h18
-rw-r--r--arch/arm/mach-vt8500/include/mach/io.h28
-rw-r--r--arch/arm/mach-vt8500/include/mach/irqs.h22
-rw-r--r--arch/arm/mach-vt8500/include/mach/memory.h28
-rw-r--r--arch/arm/mach-vt8500/include/mach/system.h18
-rw-r--r--arch/arm/mach-vt8500/include/mach/timex.h26
-rw-r--r--arch/arm/mach-vt8500/include/mach/uncompress.h37
-rw-r--r--arch/arm/mach-vt8500/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-vt8500/include/mach/vt8500_irqs.h88
-rw-r--r--arch/arm/mach-vt8500/include/mach/vt8500_regs.h79
-rw-r--r--arch/arm/mach-vt8500/include/mach/vt8500fb.h31
-rw-r--r--arch/arm/mach-vt8500/include/mach/wm8505_irqs.h115
-rw-r--r--arch/arm/mach-vt8500/include/mach/wm8505_regs.h78
-rw-r--r--arch/arm/mach-vt8500/irq.c177
-rw-r--r--arch/arm/mach-vt8500/pwm.c265
-rw-r--r--arch/arm/mach-vt8500/timer.c155
-rw-r--r--arch/arm/mach-vt8500/wm8505_7in.c77
34 files changed, 2356 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5cff165b7eb..cab466fc5ae 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -875,6 +875,16 @@ config PLAT_SPEAR
help
Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
+config ARCH_VT8500
+ bool "VIA/WonderMedia 85xx"
+ select CPU_ARM926T
+ select GENERIC_GPIO
+ select ARCH_HAS_CPUFREQ
+ select GENERIC_CLOCKEVENTS
+ select ARCH_REQUIRE_GPIOLIB
+ select HAVE_PWM
+ help
+ Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
endchoice
#
@@ -1007,6 +1017,8 @@ source "arch/arm/mach-versatile/Kconfig"
source "arch/arm/mach-vexpress/Kconfig"
+source "arch/arm/mach-vt8500/Kconfig"
+
source "arch/arm/mach-w90x900/Kconfig"
# Definitions to make life easier
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c22c1adfedd..bd3b13e3717 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -190,6 +190,7 @@ machine-$(CONFIG_ARCH_U300) := u300
machine-$(CONFIG_ARCH_U8500) := ux500
machine-$(CONFIG_ARCH_VERSATILE) := versatile
machine-$(CONFIG_ARCH_VEXPRESS) := vexpress
+machine-$(CONFIG_ARCH_VT8500) := vt8500
machine-$(CONFIG_ARCH_W90X900) := w90x900
machine-$(CONFIG_ARCH_NUC93X) := nuc93x
machine-$(CONFIG_FOOTBRIDGE) := footbridge
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 0a8f748e506..78fe31a4f50 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -29,6 +29,10 @@ ifeq ($(CONFIG_ARCH_SA1100),y)
OBJS += head-sa1100.o
endif
+ifeq ($(CONFIG_ARCH_VT8500),y)
+OBJS += head-vt8500.o
+endif
+
ifeq ($(CONFIG_CPU_XSCALE),y)
OBJS += head-xscale.o
endif
diff --git a/arch/arm/boot/compressed/head-vt8500.S b/arch/arm/boot/compressed/head-vt8500.S
new file mode 100644
index 00000000000..1dc1e21a3be
--- /dev/null
+++ b/arch/arm/boot/compressed/head-vt8500.S
@@ -0,0 +1,46 @@
+/*
+ * linux/arch/arm/boot/compressed/head-vt8500.S
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * VIA VT8500 specific tweaks. This is merged into head.S by the linker.
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/mach-types.h>
+
+ .section ".start", "ax"
+
+__VT8500_start:
+ @ Compare the SCC ID register against a list of known values
+ ldr r1, .SCCID
+ ldr r3, [r1]
+
+ @ VT8500 override
+ ldr r4, .VT8500SCC
+ cmp r3, r4
+ ldreq r7, .ID_BV07
+ beq .Lendvt8500
+
+ @ WM8505 override
+ ldr r4, .WM8505SCC
+ cmp r3, r4
+ ldreq r7, .ID_8505
+ beq .Lendvt8500
+
+ @ Otherwise, leave the bootloader's machine id untouched
+
+.SCCID:
+ .word 0xd8120000
+.VT8500SCC:
+ .word 0x34000102
+.WM8505SCC:
+ .word 0x34260103
+
+.ID_BV07:
+ .word MACH_TYPE_BV07
+.ID_8505:
+ .word MACH_TYPE_WM8505_7IN_NETBOOK
+
+.Lendvt8500:
diff --git a/arch/arm/mach-vt8500/Kconfig b/arch/arm/mach-vt8500/Kconfig
new file mode 100644
index 00000000000..2c20a341c11
--- /dev/null
+++ b/arch/arm/mach-vt8500/Kconfig
@@ -0,0 +1,73 @@
+if ARCH_VT8500
+
+config VTWM_VERSION_VT8500
+ bool
+
+config VTWM_VERSION_WM8505
+ bool
+
+config MACH_BV07
+ bool "Benign BV07-8500 Mini Netbook"
+ depends on ARCH_VT8500
+ select VTWM_VERSION_VT8500
+ help
+ Add support for the inexpensive 7-inch netbooks sold by many
+ Chinese distributors under various names. Note that there are
+ many hardware implementations in identical exterior, make sure
+ that yours is indeed based on a VIA VT8500 chip.
+
+config MACH_WM8505_7IN_NETBOOK
+ bool "WM8505 7-inch generic netbook"
+ depends on ARCH_VT8500
+ select VTWM_VERSION_WM8505
+ help
+ Add support for the inexpensive 7-inch netbooks sold by many
+ Chinese distributors under various names. Note that there are
+ many hardware implementations in identical exterior, make sure
+ that yours is indeed based on a WonderMedia WM8505 chip.
+
+comment "LCD panel size"
+
+config WMT_PANEL_800X480
+ bool "7-inch with 800x480 resolution"
+ depends on (FB_VT8500 || FB_WM8505)
+ default y
+ help
+ These are found in most of the netbooks in generic cases, as
+ well as in Eken M001 tablets and possibly elsewhere.
+
+ To select this panel at runtime, say y here and append
+ 'panel=800x480' to your kernel command line. Otherwise, the
+ largest one available will be used.
+
+config WMT_PANEL_800X600
+ bool "8-inch with 800x600 resolution"
+ depends on (FB_VT8500 || FB_WM8505)
+ help
+ These are found in Eken M003 tablets and possibly elsewhere.
+
+ To select this panel at runtime, say y here and append
+ 'panel=800x600' to your kernel command line. Otherwise, the
+ largest one available will be used.
+
+config WMT_PANEL_1024X576
+ bool "10-inch with 1024x576 resolution"
+ depends on (FB_VT8500 || FB_WM8505)
+ help
+ These are found in CherryPal netbooks and possibly elsewhere.
+
+ To select this panel at runtime, say y here and append
+ 'panel=1024x576' to your kernel command line. Otherwise, the
+ largest one available will be used.
+
+config WMT_PANEL_1024X600
+ bool "10-inch with 1024x600 resolution"
+ depends on (FB_VT8500 || FB_WM8505)
+ help
+ These are found in Eken M006 tablets and possibly elsewhere.
+
+ To select this panel at runtime, say y here and append
+ 'panel=1024x600' to your kernel command line. Otherwise, the
+ largest one available will be used.
+
+endif
diff --git a/arch/arm/mach-vt8500/Makefile b/arch/arm/mach-vt8500/Makefile
new file mode 100644
index 00000000000..81aedb7c893
--- /dev/null
+++ b/arch/arm/mach-vt8500/Makefile
@@ -0,0 +1,9 @@
+obj-y += devices.o gpio.o irq.o timer.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_HAVE_PWM) += pwm.o
diff --git a/arch/arm/mach-vt8500/Makefile.boot b/arch/arm/mach-vt8500/Makefile.boot
new file mode 100644
index 00000000000..a8acc4e2490
--- /dev/null
+++ b/arch/arm/mach-vt8500/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x01000000
diff --git a/arch/arm/mach-vt8500/bv07.c b/arch/arm/mach-vt8500/bv07.c
new file mode 100644
index 00000000000..94a261d86bf
--- /dev/null
+++ b/arch/arm/mach-vt8500/bv07.c
@@ -0,0 +1,77 @@
+/*
+ * 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 "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");
+
+ vt8500_set_resources();
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ vt8500_gpio_init();
+}
+
+MACHINE_START(BV07, "Benign BV07 Mini Netbook")
+ .boot_params = 0x00000100,
+ .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/devices-vt8500.c b/arch/arm/mach-vt8500/devices-vt8500.c
new file mode 100644
index 00000000000..19519aeecf3
--- /dev/null
+++ b/arch/arm/mach-vt8500/devices-vt8500.c
@@ -0,0 +1,91 @@
+/* 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
new file mode 100644
index 00000000000..db4594e029f
--- /dev/null
+++ b/arch/arm/mach-vt8500/devices-wm8505.c
@@ -0,0 +1,99 @@
+/* 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
new file mode 100644
index 00000000000..1fcdc36b358
--- /dev/null
+++ b/arch/arm/mach-vt8500/devices.c
@@ -0,0 +1,270 @@
+/* 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
new file mode 100644
index 00000000000..188d4e17f35
--- /dev/null
+++ b/arch/arm/mach-vt8500/devices.h
@@ -0,0 +1,88 @@
+/* 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
new file mode 100644
index 00000000000..2bcc0ec783d
--- /dev/null
+++ b/arch/arm/mach-vt8500/gpio.c
@@ -0,0 +1,240 @@
+/* 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 ENA