[PATCH][RFC] arm: Add basic support for VIA/WonderMedia SoC's
Marek Vasut
marek.vasut at gmail.com
Mon Jul 12 13:06:52 EDT 2010
Dne Po 12. července 2010 18:50:25 Alexey Charkov napsal(a):
> This adds basic support for machine initialization, interrupts, timers and
> serial console on VIA/WonderMedia VT8500 and WM8505 Systems-on-Chip.
>
> Signed-off-by: Alexey Charkov <alchark at gmail.com>
> ---
>
> These SoC's are used in quite many netbooks and tablets produced in China
> and sold online at relatively low prices (typically below 100 USD).
>
> Support for WM8505 is known incomplete, while VT8500 is tested by me on the
> hardware and at least prints kernel messages to the serial console with
> timing information.
>
> The code relies on recent additions to arch/arm/tools/mach-types not yet
> pulled in from the machine registry, a corresponding section is included in
> the following patch.
>
> Please comment on the code, I'm eager to improve wherever possible.
>
> The patch is based on Linus' master branch at commit 589643be6693c46fbc
>
> Best regards,
> Alexey
>
DISCLAIMER: I lack sleep (30 hours straight).
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 98922f7..0e171be 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -794,6 +794,17 @@ 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_TIME
> + select GENERIC_CLOCKEVENTS
> + select ARCH_WANT_OPTIONAL_GPIOLIB
> + select HAVE_CLK
> + help
> + Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
> endchoice
>
> #
> @@ -877,6 +888,8 @@ source "arch/arm/mach-realview/Kconfig"
>
> source "arch/arm/mach-sa1100/Kconfig"
>
> +source "arch/arm/mach-vt8500/Kconfig"
> +
Possibly keep this sorted?
> source "arch/arm/plat-samsung/Kconfig"
> source "arch/arm/plat-s3c24xx/Kconfig"
> source "arch/arm/plat-s5p/Kconfig"
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 64ba313..dcb5b64 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -179,6 +179,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 53faa90..4f67531 100644
> --- a/arch/arm/boot/compressed/Makefile
> +++ b/arch/arm/boot/compressed/Makefile
> @@ -32,6 +32,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 0000000..2faa7d6
> --- /dev/null
> +++ b/arch/arm/boot/compressed/head-vt8500.S
> @@ -0,0 +1,23 @@
> +/*
> + * linux/arch/arm/boot/compressed/head-vt8500.S
> + *
> + * Copyright (C) 2010 Alexey Charkov <alchark at 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:
> + /* Override the obscure machine id from bootloader */
> +#ifdef CONFIG_MACH_BV07
> + mov r7, #(MACH_TYPE_BV07 & ~0xf)
> + orr r7, r7, #(MACH_TYPE_BV07 & 0xf)
> +#elif defined CONFIG_MACH_WM8505_7IN_NETBOOK
> + mov r7, #(MACH_TYPE_WM8505_7IN_NETBOOK & ~0xf)
> + orr r7, r7, #(MACH_TYPE_WM8505_7IN_NETBOOK & 0xf)
> +#endif
Can't you replace the bootloader ?
> diff --git a/arch/arm/mach-vt8500/Kconfig b/arch/arm/mach-vt8500/Kconfig
> new file mode 100644
> index 0000000..bd75043
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/Kconfig
> @@ -0,0 +1,33 @@
> +if ARCH_VT8500
> +
> +choice
> + prompt "VIA/WonderMedia System Type"
> + default VTWM_VERSION_VT8500
> +
> +config VTWM_VERSION_VT8500
> + bool "VIA VT8500"
> +
> +config VTWM_VERSION_WM8505
> + bool "WonderMedia WM8505"
> +
> +endchoice
> +
> +config MACH_BV07
> + bool "Benign BV07-8500 Mini Netbook"
> + depends on ARCH_VT8500 && 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 && 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.
> +
> +endif
> diff --git a/arch/arm/mach-vt8500/Makefile b/arch/arm/mach-vt8500/Makefile
> new file mode 100644
> index 0000000..948f3c8
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/Makefile
> @@ -0,0 +1,3 @@
> +obj-y += devices.o irq.o timer.o
> +
> +obj-$(CONFIG_MACH_BV07) += bv07.o
> diff --git a/arch/arm/mach-vt8500/Makefile.boot
> b/arch/arm/mach-vt8500/Makefile.boot new file mode 100644
> index 0000000..a8acc4e
> --- /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 0000000..b0f374c
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/bv07.c
> @@ -0,0 +1,43 @@
> +/*
> + * arch/arm/mach-vt8500/bv07.c
> + *
> + * Copyright (C) 2010 Alexey Charkov <alchark at 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 <asm/mach-types.h>
> +#include <asm/mach/arch.h>
> +
> +#include "devices.h"
> +
> +static struct platform_device *devices[] __initdata = {
> + &vt8500_device_uart0,
> +};
> +
> +void __init bv07_init(void)
> +{
> + platform_add_devices(devices, ARRAY_SIZE(devices));
> +}
> +
> +MACHINE_START(BV07, "Benign BV07 Mini Netbook")
> + .phys_io = 0xd8000000,
> + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
> + .boot_params = 0x00000100,
> + .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.c
> b/arch/arm/mach-vt8500/devices.c new file mode 100644
> index 0000000..30bf8b5
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/devices.c
> @@ -0,0 +1,149 @@
> +/* linux/arch/arm/mach-vt8500/devices.c
> + *
> + * Copyright (C) 2010 Alexey Charkov <alchark at 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/platform_device.h>
> +
> +#include <asm/mach/arch.h>
> +#include <asm/mach/map.h>
> +
> +#include <mach/irqs.h>
> +#include <mach/hardware.h>
> +#include <mach/vt8500.h>
> +#include "devices.h"
> +
> +static struct map_desc vt8500_io_desc[] __initdata = {
> + {
> + .virtual = IO_ADDRESS(VT8500_DDR_BASE),
> + .pfn = __phys_to_pfn(VT8500_DDR_BASE),
> + .length = SZ_16M,
> + .type = MT_DEVICE
> + },
> +};
> +
> +void __init vt8500_map_io(void)
> +{
> + iotable_init(vt8500_io_desc, ARRAY_SIZE(vt8500_io_desc));
> +}
> +
> +static struct resource resources_uart0[] = {
> + {
> + .start = IRQ_UART0,
> + .end = IRQ_UART0,
> + .flags = IORESOURCE_IRQ,
> + },
> + {
> + .start = VT8500_UART0_BASE,
> + .end = VT8500_UART0_BASE + VT8500_UART_SIZE - 1,
> + .flags = IORESOURCE_MEM,
> + },
> +};
> +
> +static struct resource resources_uart1[] = {
> + {
> + .start = IRQ_UART1,
> + .end = IRQ_UART1,
> + .flags = IORESOURCE_IRQ,
> + },
> + {
> + .start = VT8500_UART1_BASE,
> + .end = VT8500_UART1_BASE + VT8500_UART_SIZE - 1,
> + .flags = IORESOURCE_MEM,
> + },
> +};
> +
> +static struct resource resources_uart2[] = {
> + {
> + .start = IRQ_UART2,
> + .end = IRQ_UART2,
> + .flags = IORESOURCE_IRQ,
> + },
> + {
> + .start = VT8500_UART2_BASE,
> + .end = VT8500_UART2_BASE + VT8500_UART_SIZE - 1,
> + .flags = IORESOURCE_MEM,
> + },
> +};
> +
> +static struct resource resources_uart3[] = {
> + {
> + .start = IRQ_UART3,
> + .end = IRQ_UART3,
> + .flags = IORESOURCE_IRQ,
> + },
> + {
> + .start = VT8500_UART3_BASE,
> + .end = VT8500_UART3_BASE + VT8500_UART_SIZE - 1,
> + .flags = IORESOURCE_MEM,
> + },
> +};
> +
> +#ifdef CONFIG_VTWM_VERSION_WM8505
> +static struct resource resources_uart4[] = {
> + {
> + .start = IRQ_UART4,
> + .end = IRQ_UART4,
> + .flags = IORESOURCE_IRQ,
> + },
> + {
> + .start = VT8500_UART4_BASE,
> + .end = VT8500_UART4_BASE + VT8500_UART_SIZE - 1,
> + .flags = IORESOURCE_MEM,
> + },
> +};
> +
> +static struct resource resources_uart5[] = {
> + {
> + .start = IRQ_UART5,
> + .end = IRQ_UART5,
> + .flags = IORESOURCE_IRQ,
> + },
> + {
> + .start = VT8500_UART5_BASE,
> + .end = VT8500_UART5_BASE + VT8500_UART_SIZE - 1,
> + .flags = IORESOURCE_MEM,
> + },
> +};
> +#endif
> +
> +struct platform_device vt8500_device_uart0 = {
> + .name = "vt8500_serial",
> + .id = 0,
> + .num_resources = ARRAY_SIZE(resources_uart0),
> + .resource = resources_uart0,
> +};
> +
> +struct platform_device vt8500_device_uart1 = {
> + .name = "vt8500_serial",
> + .id = 1,
> + .num_resources = ARRAY_SIZE(resources_uart1),
> + .resource = resources_uart1,
> +};
> +
> +struct platform_device vt8500_device_uart2 = {
> + .name = "vt8500_serial",
> + .id = 2,
> + .num_resources = ARRAY_SIZE(resources_uart2),
> + .resource = resources_uart2,
> +};
> +
> +struct platform_device vt8500_device_uart3 = {
> + .name = "vt8500_serial",
> + .id = 3,
> + .num_resources = ARRAY_SIZE(resources_uart3),
> + .resource = resources_uart3,
> +};
> diff --git a/arch/arm/mach-vt8500/devices.h
> b/arch/arm/mach-vt8500/devices.h new file mode 100644
> index 0000000..243ed0a
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/devices.h
> @@ -0,0 +1,34 @@
> +/* linux/arch/arm/mach-vt8500/devices.h
> + *
> + * Copyright (C) 2010 Alexey Charkov <alchark at 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>
> +
> +void __init vt8500_init_irq(void);
> +void __init vt8500_map_io(void);
> +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;
> +#ifdef CONFIG_VTWM_VERSION_WM8505
> +extern struct platform_device vt8500_device_uart4;
> +extern struct platform_device vt8500_device_uart5;
> +#endif
> +
> +#endif
> diff --git a/arch/arm/mach-vt8500/include/mach/debug-macro.S
> b/arch/arm/mach-vt8500/include/mach/debug-macro.S new file mode 100644
> index 0000000..264e0be
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/include/mach/debug-macro.S
> @@ -0,0 +1,35 @@
> +/*
> + * arch/arm/mach-vt8500/include/mach/debug-macro.S
> + *
> + * Copyright (C) 2010 Alexey Charkov <alchark at gmail.com>
> + *
> + * Debugging macro include header
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> +*/
> +
> +#include <mach/vt8500.h>
> +
> + .macro addruart, rx, tmp
> + mrc p15, 0, \rx, c1, c0
> + tst \rx, #1 @ MMU enabled?
> + moveq \rx, #0xd8000000
> + movne \rx, #0xf8000000 @ virtual base
> + orr \rx, \rx, #0x00200000
> + .endm
> +
> + .macro senduart,rd,rx
> + strb \rd, [\rx, #0]
> + .endm
> +
> + .macro busyuart,rd,rx
> +1001: ldr \rd, [\rx, #0x1c]
> + ands \rd, \rd, #0x2
> + bne 1001b
> + .endm
> +
> + .macro waituart,rd,rx
> + .endm
> diff --git a/arch/arm/mach-vt8500/include/mach/entry-macro.S
> b/arch/arm/mach-vt8500/include/mach/entry-macro.S new file mode 100644
> index 0000000..6b8a04e
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/include/mach/entry-macro.S
> @@ -0,0 +1,41 @@
> +/*
> + * arch/arm/mach-vt8500/include/mach/entry-macro.S
> + *
> + * Low-level IRQ helper macros for VIA VT8500
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> + .macro disable_fiq
> + .endm
> +
> + .macro get_irqnr_preamble, base, tmp
> + @ physical 0xd8140000 is virtual 0xf8140000
> + mov \base, #0xf8000000
> + orr \base, \base, #0x00140000
> + .endm
> +
> + .macro arch_ret_to_user, tmp1, tmp2
> + .endm
> +
> + /* Reserved interrupts, to be masked off: 2, 4, 23 */
> + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
> + @ check low interrupts
> + ldr \irqstat, [\base, #0x80]
> + mov \tmp, #0x800000 @ 1 << 23
> + orr \tmp, \tmp, #0x14 @ (1 << 4) + (1 << 2)
> + mov \irqnr, #31
> + bics \irqstat, \irqstat, \tmp
> +
> + @ if no low interrupts set, check high interrupts
> + ldreq \irqstat, [\base, #0x84]
> + moveq \irqnr, #63
> + cmpeq \irqstat, #0
> +
> + @ find first active interrupt source
> + clzne \irqstat, \irqstat
> + subne \irqnr, \irqnr, \irqstat
> + .endm
> +
> diff --git a/arch/arm/mach-vt8500/include/mach/gpio.h
> b/arch/arm/mach-vt8500/include/mach/gpio.h new file mode 100644
> index 0000000..94ff276
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/include/mach/gpio.h
> @@ -0,0 +1,6 @@
> +#include <asm-generic/gpio.h>
> +
> +#define gpio_get_value __gpio_get_value
> +#define gpio_set_value __gpio_set_value
> +#define gpio_cansleep __gpio_cansleep
> +#define gpio_to_irq __gpio_to_irq
> diff --git a/arch/arm/mach-vt8500/include/mach/hardware.h
> b/arch/arm/mach-vt8500/include/mach/hardware.h new file mode 100644
> index 0000000..4aae7d2
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/include/mach/hardware.h
> @@ -0,0 +1,19 @@
> +/* arch/arm/mach-vt8500/include/mach/hardware.h
> + *
> + * 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.
> + *
> + */
> +
> +#ifdef CONFIG_MMU
> +/* macro to get at IO space when running virtually */
> +#define IO_ADDRESS(x) ((x) | 0xf0000000)
> +#else
> +#define IO_ADDRESS(x) (x)
> +#endif
> diff --git a/arch/arm/mach-vt8500/include/mach/io.h
> b/arch/arm/mach-vt8500/include/mach/io.h new file mode 100644
> index 0000000..dc2181a
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/include/mach/io.h
> @@ -0,0 +1,28 @@
> +/*
> + * arch/arm/mach-vt8500/include/mach/io.h
> + *
> + * Copyright (C) 2003 ARM Limited
Really? You just copied it ?
> + *
> + * 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_IO_H
> +#define __ASM_ARM_ARCH_IO_H
> +
> +#define IO_SPACE_LIMIT 0xffffffff
> +
> +#define __io(a) __typesafe_io(a)
> +#define __mem_pci(a) (a)
> +
> +#endif
> diff --git a/arch/arm/mach-vt8500/include/mach/irqs.h
> b/arch/arm/mach-vt8500/include/mach/irqs.h new file mode 100644
> index 0000000..4bfd673
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/include/mach/irqs.h
> @@ -0,0 +1,87 @@
> +/*
> + * arch/arm/mach-vt8500/include/mach/irqs.h
> + *
> + * Copyright (C) 2010 Alexey Charkov <alchark at 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 + */
> +
> +#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_GRAPH 8 /* Graphic Engine */
> +#define IRQ_GRAPH_OVER 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_VDI 41 /* Video Digital Input Interface */
> +#define IRQ_AC97 42 /* AC97 Interface */
> +#define IRQ_USB 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 NR_IRQS 64
> diff --git a/arch/arm/mach-vt8500/include/mach/memory.h
> b/arch/arm/mach-vt8500/include/mach/memory.h new file mode 100644
> index 0000000..175f914
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/include/mach/memory.h
> @@ -0,0 +1,28 @@
> +/*
> + * arch/arm/mach-vt8500/include/mach/memory.h
> + *
> + * Copyright (C) 2003 ARM Limited
DTTO ?
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
> USA + */
> +#ifndef __ASM_ARCH_MEMORY_H
> +#define __ASM_ARCH_MEMORY_H
> +
> +/*
> + * Physical DRAM offset.
> + */
> +#define PHYS_OFFSET UL(0x00000000)
> +
> +#endif
> diff --git a/arch/arm/mach-vt8500/include/mach/system.h
> b/arch/arm/mach-vt8500/include/mach/system.h new file mode 100644
> index 0000000..f3fac00
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/include/mach/system.h
> @@ -0,0 +1,15 @@
> +/*
> + * arch/arm/mach-vt8500/include/mach/system.h
> + *
> + */
> +#include <mach/hardware.h>
> +
> +static inline void arch_idle(void)
> +{
> + cpu_do_idle();
> +}
> +
> +static inline void arch_reset(char mode, const char *cmd)
> +{
> + cpu_reset(0);
> +}
> diff --git a/arch/arm/mach-vt8500/include/mach/timex.h
> b/arch/arm/mach-vt8500/include/mach/timex.h new file mode 100644
> index 0000000..ff209d8
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/include/mach/timex.h
> @@ -0,0 +1,21 @@
> +/*
> + * arch/arm/mach-vt8500/include/mach/timex.h
> + *
> + * Copyright (C) 2010 Alexey Charkov <alchark at 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 MACH_TIMEX
#define MACH_TIMEX
> +#define CLOCK_TICK_RATE (3000000)
#endif
Maybe ?
> diff --git a/arch/arm/mach-vt8500/include/mach/uncompress.h
> b/arch/arm/mach-vt8500/include/mach/uncompress.h new file mode 100644
> index 0000000..3f14bf1
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/include/mach/uncompress.h
> @@ -0,0 +1,46 @@
> +/* arch/arm/mach-vt8500/include/mach/uncompress.h
> + *
> + * Copyright (C) 2010 Alexey Charkov <alchark at gmail.com>
> + *
> + * Based on arch/arm/mach-dove/include/mach/uncompress.h
> + *
> + * 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 <mach/vt8500.h>
> +
> +#define UART_THR ((volatile unsigned char *)(VT8500_UART0_BASE + 0x0))
> +#define UART_LSR ((volatile unsigned char *)(VT8500_UART0_BASE + 0x24))
Can't you use some better accessors here ?
> +
> +#define LSR_THRE 0x1f
> +
> +static void putc(const char c)
> +{
> + int i;
> +
> + for (i = 0; i < 0x1000; i++) {
> + /* Transmit fifo not full? */
> + if (*UART_LSR & LSR_THRE)
> + break;
> + }
> +
> + *UART_THR = c;
> +}
> +
> +static void flush(void)
> +{
> +}
> +
> +/*
> + * nothing to do
> + */
> +#define arch_decomp_setup()
> +#define arch_decomp_wdog()
> diff --git a/arch/arm/mach-vt8500/include/mach/vmalloc.h
> b/arch/arm/mach-vt8500/include/mach/vmalloc.h new file mode 100644
> index 0000000..75a6912
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/include/mach/vmalloc.h
> @@ -0,0 +1,20 @@
> +/*
> + * arch/arm/mach-vt8500/include/mach/vmalloc.h
> + *
> + * Copyright (C) 2000 Russell King.
> + *
> + * 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 + */
> +#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
> diff --git a/arch/arm/mach-vt8500/include/mach/vt8500.h
> b/arch/arm/mach-vt8500/include/mach/vt8500.h new file mode 100644
> index 0000000..f419ab6
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/include/mach/vt8500.h
> @@ -0,0 +1,145 @@
> +/*
> + * arch/arm/mach-vt8500/include/mach/vt8500.h
> + *
> + * Copyright (C) 2010 Alexey Charkov <alchark at 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_H
> +#define __ASM_ARM_ARCH_VT8500_H
> +
> +#ifdef CONFIG_VTWM_VERSION_VT8500
> +/* VT8500 Registers Map */
> +
> +#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_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 */
> +
> +#elif defined CONFIG_VTWM_VERSION_WM8505
> +/* WM8500 Registers Map */
> +/* To be confirmed! */
> +
> +#define VT8500_DDR_BASE 0xd8000400 /* 1k DDR/DDR2 Memory
> + Controller */
> +#define VT8500_DMA_BASE 0xd8001800 /* 1k DMA Controller
*/
> +#define VT8500_VDMA_BASE 0xd8001c00 /* 1k VDMA */
> +#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 0xd8007000 /* 2k USB 2.0 Host */
> +#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_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_SIC_BASE 0xd8150000 /* 64k Secondary IC */
> +#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_UART1_BASE 0xd8370000 /* 64k UART 4 */
> +#define VT8500_UART3_BASE 0xd8380000 /* 64k UART 5 */
> +
> +#endif
> +
> +/*
> + * UART Register offsets
> + */
> +
> +#define VT8500_URTDR 0x0000 /* Transmit data */
> +#define VT8500_URRDR 0x0004 /* Receive data */
> +#define VT8500_URDIV 0x0008 /* Clock/Baud rate divisor */
> +#define VT8500_URLCR 0x000C /* Line control */
> +#define VT8500_URICR 0x0010 /* IrDA control */
> +#define VT8500_URIER 0x0014 /* Interrupt enable */
> +#define VT8500_URISR 0x0018 /* Interrupt status */
> +#define VT8500_URUSR 0x001c /* UART status */
> +#define VT8500_URFCR 0x0020 /* FIFO control */
> +#define VT8500_URFIDX 0x0024 /* FIFO index */
> +#define VT8500_URBKR 0x0028 /* Break signal count */
> +#define VT8500_URTOD 0x002c /* Time out divisor */
> +#define VT8500_TXFIFO 0x1000 /* Transmit FIFO (16x8) */
> +#define VT8500_RXFIFO 0x1020 /* Receive FIFO (16x10) */
> +
> +#define VT8500_UART_SIZE 0x1040
> +
> +#endif
> diff --git a/arch/arm/mach-vt8500/irq.c b/arch/arm/mach-vt8500/irq.c
> new file mode 100644
> index 0000000..9299693
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/irq.c
> @@ -0,0 +1,122 @@
> +/*
> + * arch/arm/mach-vt8500/irq.c
> + *
> + * Copyright (C) 2010 Alexey Charkov <alchark at 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/irq.h>
> +#include <linux/interrupt.h>
> +
> +#include <asm/irq.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/irqs.h>
> +#include <mach/vt8500.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_IC_STATUS 0x80 /* Interrupt status, 2*u32 */
> +
> +static void vt8500_irq_mask(unsigned int irq)
> +{
> + u8 edge = readb(IO_ADDRESS(VT8500_IC_BASE)
> + + VT8500_IC_DCTR + irq) & (3 << 4);
> + if (edge)
> + writel(readl(IO_ADDRESS(VT8500_IC_BASE)
> + + VT8500_IC_STATUS + (irq < 32 ? 0 : 4))
> + | (1 << (irq & 0x1f)), IO_ADDRESS(VT8500_IC_BASE)
> + + VT8500_IC_STATUS + (irq & 0x20 ? 4 : 0));
> + else
> + writeb(readb(IO_ADDRESS(VT8500_IC_BASE)
> + + VT8500_IC_DCTR + irq) & ~VT8500_INT_ENABLE,
> + IO_ADDRESS(VT8500_IC_BASE) + VT8500_IC_DCTR + irq);
> +}
> +
> +static void vt8500_irq_unmask(unsigned int irq)
> +{
> + writeb(readb(IO_ADDRESS(VT8500_IC_BASE)
> + + VT8500_IC_DCTR + irq) | VT8500_INT_ENABLE,
> + IO_ADDRESS(VT8500_IC_BASE) + VT8500_IC_DCTR + irq);
> +}
> +
> +static int vt8500_irq_set_wake(unsigned int irq, unsigned int on)
> +{
> + return -EINVAL;
> +}
> +
> +static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type)
> +{
> + switch (flow_type) {
> + case IRQF_TRIGGER_LOW:
> + return -EINVAL;
> + case IRQF_TRIGGER_HIGH:
> + writeb((readb(IO_ADDRESS(VT8500_IC_BASE)
> + + VT8500_IC_DCTR + irq) & ~(3 << 4))
> + | VT8500_TRIGGER_HIGH, IO_ADDRESS(VT8500_IC_BASE)
> + + VT8500_IC_DCTR + irq);
> + set_irq_handler(irq, handle_level_irq);
> + break;
> + case IRQF_TRIGGER_FALLING:
> + writeb((readb(IO_ADDRESS(VT8500_IC_BASE)
> + + VT8500_IC_DCTR + irq) & ~(3 << 4))
> + | VT8500_TRIGGER_FALLING, IO_ADDRESS(VT8500_IC_BASE)
> + + VT8500_IC_DCTR + irq);
> + set_irq_handler(irq, handle_edge_irq);
> + break;
> + case IRQF_TRIGGER_RISING:
> + writeb((readb(IO_ADDRESS(VT8500_IC_BASE)
> + + VT8500_IC_DCTR + irq) & ~(3 << 4))
> + | VT8500_TRIGGER_RISING, IO_ADDRESS(VT8500_IC_BASE)
> + + VT8500_IC_DCTR + irq);
> + set_irq_handler(irq, handle_edge_irq);
> + break;
> + }
> +
> + return 0;
> +}
> +
> +static struct irq_chip vt8500_irq_chip = {
> + .name = "vt8500",
> + .ack = vt8500_irq_mask,
> + .mask = vt8500_irq_mask,
> + .unmask = vt8500_irq_unmask,
> + .set_wake = vt8500_irq_set_wake,
> + .set_type = vt8500_irq_set_type,
> +};
> +
> +void __init vt8500_init_irq(void)
> +{
> + unsigned int i;
> +
> + /* Enable rotating priority for IRQ */
> + writel((1 << 6), IO_ADDRESS(VT8500_IC_BASE) + 0x20);
> + writel(0, IO_ADDRESS(VT8500_IC_BASE) + 0x24);
> +
> + for (i = 0; i < NR_IRQS; i++) {
> + /* Disable all interrupts and route them to IRQ */
> + writeb(0x00, IO_ADDRESS(VT8500_IC_BASE) + VT8500_IC_DCTR + i);
> +
> + set_irq_chip(i, &vt8500_irq_chip);
> + set_irq_handler(i, handle_level_irq);
> + set_irq_flags(i, IRQF_VALID);
> + }
> +}
> diff --git a/arch/arm/mach-vt8500/timer.c b/arch/arm/mach-vt8500/timer.c
> new file mode 100644
> index 0000000..817edc8
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/timer.c
> @@ -0,0 +1,185 @@
> +/*
> + * arch/arm/mach-vt8500/timer.c
> + *
> + * Copyright (C) 2010 Alexey Charkov <alchark at 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/irq.h>
> +#include <linux/interrupt.h>
> +#include <linux/clocksource.h>
> +#include <linux/clockchips.h>
> +#include <linux/cnt32_to_63.h>
> +
> +#include <asm/mach/time.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/irqs.h>
> +#include <mach/vt8500.h>
> +
> +#define VT8500_TIMER_OFFSET 0x0100
> +#define TIMER_MATCH_VAL 0x0000
> +#define TIMER_COUNT_VAL 0x0010
> +#define TIMER_STATUS_VAL 0x0014
> +#define TIMER_IER_VAL 0x001c /* interrupt enable */
> +#define TIMER_CTRL_VAL 0x0020
> +#define TIMER_AS_VAL 0x0024 /* access status */
> +#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
> +void __iomem* regbase = (void __iomem *)(IO_ADDRESS(VT8500_PMC_BASE)
> + + VT8500_TIMER_OFFSET);
> +
> +unsigned long long sched_clock(void)
> +{
> + unsigned long long v;
> +
> + writel(0x3, regbase + TIMER_CTRL_VAL);
> + while (readl(regbase + TIMER_AS_VAL) & TIMER_COUNT_R_ACTIVE)
> + /* wait and poll */;
> +
> + v = cnt32_to_63(readl(regbase + TIMER_COUNT_VAL));
> +
> + /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn*/
> + v *= 1000<<1; /* 3MHz timer tick implies 333ns resolution */
> + do_div(v, 3<<1);
Did you run checkpatch here ... or on this patch ?
> +
> + return v;
> +}
> +
> +static int vt8500_timer_set_next_event(unsigned long cycles,
> + struct clock_event_device *evt)
> +{
> + unsigned long now, alarm;
> + int late;
> +
> + writel(3, regbase + TIMER_CTRL_VAL);
> + while (readl(regbase + TIMER_AS_VAL) & TIMER_COUNT_R_ACTIVE)
> + /* wait and poll */;
> + now = readl(regbase + TIMER_COUNT_VAL);
> + alarm = now + cycles;
> + while (readl(regbase + TIMER_AS_VAL) & TIMER_MATCH_W_ACTIVE)
> + /* wait and poll */;
> + writel(alarm, regbase + TIMER_MATCH_VAL);
> +
> + writel(3, regbase + TIMER_CTRL_VAL);
> + while (readl(regbase + TIMER_AS_VAL) & TIMER_COUNT_R_ACTIVE)
> + /* wait and poll */;
> + now = readl(regbase + TIMER_COUNT_VAL);
> + late = now - alarm;
> + if (late >= (-2) && late < VT8500_TIMER_HZ*5)
> + return -ETIME;
> +
> + writel(1, regbase + TIMER_IER_VAL);
> +
> + return 0;
> +}
> +
> +static void vt8500_timer_set_mode(enum clock_event_mode mode,
> + struct clock_event_device *evt)
> +{
> + switch (mode) {
> + case CLOCK_EVT_MODE_RESUME:
> + case CLOCK_EVT_MODE_PERIODIC:
> + break;
> + case CLOCK_EVT_MODE_ONESHOT:
> + writel(readl(regbase + TIMER_CTRL_VAL) | 1,
> + regbase + TIMER_CTRL_VAL);
> + writel(0, regbase + TIMER_IER_VAL);
> + break;
> + case CLOCK_EVT_MODE_UNUSED:
> + case CLOCK_EVT_MODE_SHUTDOWN:
> + writel(readl(regbase + TIMER_CTRL_VAL) & ~1,
> + regbase + TIMER_CTRL_VAL);
> + break;
> + }
> +}
> +
> +struct clock_event_device clockevent = {
> + .name = "vt8500_timer",
> + .features = CLOCK_EVT_FEAT_ONESHOT,
> + .rating = 200,
> + .set_next_event = vt8500_timer_set_next_event,
> + .set_mode = vt8500_timer_set_mode,
> +};
> +
> +static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id)
> +{
> + struct clock_event_device *evt = dev_id;
> + evt->event_handler(evt);
> + writel(0xf, regbase + TIMER_STATUS_VAL);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static cycle_t vt8500_timer_read(struct clocksource *cs)
> +{
> + writel(3, regbase + TIMER_CTRL_VAL);
> + while (readl((regbase + TIMER_AS_VAL)) & TIMER_COUNT_R_ACTIVE)
> + /* wait and poll */;
> + return readl(regbase + TIMER_COUNT_VAL);
> +}
> +
> +struct clocksource clocksource = {
> + .name = "vt8500_timer",
> + .rating = 200,
> + .read = vt8500_timer_read,
> + .mask = CLOCKSOURCE_MASK(32),
> + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +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)
> +{
> + int res;
> +
> + struct clock_event_device *ce = &clockevent;
> + struct clocksource *cs = &clocksource;
> + writel(1, regbase + TIMER_CTRL_VAL);
> + writel(0xf, regbase + TIMER_STATUS_VAL);
> + writel(~0, regbase + TIMER_MATCH_VAL);
> +
> + clockevents_calc_mult_shift(ce, VT8500_TIMER_HZ, 4);
> + clocksource_calc_mult_shift(cs, VT8500_TIMER_HZ, 4);
> +
> + /* copy-pasted from mach-msm; no idea */
> + ce->max_delta_ns =
> + clockevent_delta2ns(0xf0000000, ce);
> + ce->min_delta_ns = clockevent_delta2ns(4, ce);
> + ce->cpumask = cpumask_of(0);
> +
> + res = clocksource_register(cs);
> + if (res)
> + printk(KERN_ERR "vt8500_timer_init: clocksource_register "
> + "failed for %s\n", cs->name);
> +
> + res = setup_irq(IRQ_PMCOS0, &irq);
> +
> + if (res)
> + printk(KERN_ERR "vt8500_timer_init: setup_irq "
> + "failed for %s\n", cs->name);
> + clockevents_register_device(ce);
> +}
> +
> +struct sys_timer vt8500_timer = {
> + .init = vt8500_timer_init
> +};
> diff --git a/arch/arm/mach-vt8500/wm8505_7in.c
> b/arch/arm/mach-vt8500/wm8505_7in.c new file mode 100644
> index 0000000..71a0071
> --- /dev/null
> +++ b/arch/arm/mach-vt8500/wm8505_7in.c
> @@ -0,0 +1,43 @@
> +/*
> + * arch/arm/mach-vt8500/wm8505_7in.c
> + *
> + * Copyright (C) 2010 Alexey Charkov <alchark at 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 <asm/mach-types.h>
> +#include <asm/mach/arch.h>
> +
> +#include "devices.h"
> +
> +static struct platform_device *devices[] __initdata = {
> + &vt8500_device_uart0,
> +};
> +
> +void __init wm8505_7in_init(void)
> +{
> + platform_add_devices(devices, ARRAY_SIZE(devices));
> +}
> +
> +MACHINE_START(WM8505_7IN_NETBOOK, "WM8505 7-inch generic netbook")
> + .phys_io = 0xd8000000,
> + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
> + .boot_params = 0x00000100,
> + .map_io = vt8500_map_io,
> + .init_irq = vt8500_init_irq,
> + .timer = &vt8500_timer,
> + .init_machine = wm8505_7in_init,
> +MACHINE_END
> diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
> index 8f10d24..f5745d1 100644
> --- a/arch/arm/tools/mach-types
> +++ b/arch/arm/tools/mach-types
> @@ -12,7 +12,7 @@
> #
> # http://www.arm.linux.org.uk/developer/machines/?action=new
> #
> -# Last update: Sat May 1 10:36:42 2010
> +# Last update: Sat Jun 19 13:07:40 2010
> #
> # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
> #
> @@ -1319,7 +1319,7 @@ mistral MACH_MISTRAL MISTRAL
1315
> msm MACH_MSM MSM 1316
> ct5910 MACH_CT5910 CT5910
1317
> ct5912 MACH_CT5912 CT5912
1318
> -hynet_ine MACH_HYNET_INE HYNET_INE 1319
> +argonst_foundation MACH_HYNET_INE HYNET_INE 1319
> hynet_app MACH_HYNET_APP HYNET_APP 1320
> msm7200 MACH_MSM7200 MSM7200
1321
> msm7600 MACH_MSM7600 MSM7600
1322
> @@ -1777,7 +1777,7 @@ wdg002 MACH_WDG002 WDG002
1785
> sg560adsl MACH_SG560ADSL SG560ADSL 1786
> nextio_n2800_ica MACH_NEXTIO_N2800_ICA NEXTIO_N2800_ICA 1787
> dove_db MACH_DOVE_DB DOVE_DB
1788
> -marvell_newdb MACH_MARVELL_NEWDB MARVELL_NEWDB
1789
> +dove_avng MACH_MARVELL_NEWDB MARVELL_NEWDB 1789
> vandihud MACH_VANDIHUD VANDIHUD 1790
> magx_e8 MACH_MAGX_E8 MAGX_E8
1791
> magx_z6 MACH_MAGX_Z6 MAGX_Z6
1792
> @@ -2308,7 +2308,7 @@ ecac2378 MACH_ECAC2378 ECAC2378
2319
> tazkiosk MACH_TAZKIOSK TAZKIOSK 2320
> whiterabbit_mch MACH_WHITERABBIT_MCH WHITERABBIT_MCH
2321
> sbox9263 MACH_SBOX9263 SBOX9263 2322
> -oreo MACH_OREO OREO 2323
> +oreo_camera MACH_OREO OREO 2323
> smdk6442 MACH_SMDK6442 SMDK6442 2324
> openrd_base MACH_OPENRD_BASE OPENRD_BASE 2325
> incredible MACH_INCREDIBLE INCREDIBLE 2326
> @@ -2374,7 +2374,7 @@ sch_m490 MACH_SCH_M490 SCH_M490
2386
> rbl01 MACH_RBL01 RBL01
2387
> omnifi MACH_OMNIFI OMNIFI
2388
> otavalo MACH_OTAVALO OTAVALO
2389
> -sienna MACH_SIENNA SIENNA
2390
> +siena MACH_SIENNA SIENNA
2390
> htc_excalibur_s620 MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620 2391
> htc_opal MACH_HTC_OPAL HTC_OPAL 2392
> touchbook MACH_TOUCHBOOK TOUCHBOOK 2393
> @@ -2498,7 +2498,7 @@ hiram MACH_HIRAM HIRAM
2510
> phy3250 MACH_PHY3250 PHY3250
2511
> ea3250 MACH_EA3250 EA3250
2512
> fdi3250 MACH_FDI3250 FDI3250
2513
> -whitestone MACH_WHITESTONE WHITESTONE 2514
> +htcwhitestone MACH_WHITESTONE WHITESTONE
2514
> at91sam9263nit MACH_AT91SAM9263NIT AT91SAM9263NIT
2515
> ccmx51 MACH_CCMX51 CCMX51
2516
> ccmx51js MACH_CCMX51JS CCMX51JS 2517
> @@ -2582,7 +2582,7 @@ omap3_bulldog MACH_OMAP3_BULLDOG
OMAP3_BULLDOG 2594
> pca101 MACH_PCA101 PCA101
2595
> buzzc MACH_BUZZC BUZZC
2596
> sasie2 MACH_SASIE2 SASIE2
2597
> -davinci_cio MACH_DAVINCI_CIO DAVINCI_CIO 2598
> +davinci_dm6467_cio MACH_DAVINCI_CIO DAVINCI_CIO 2598
> smartmeter_dl MACH_SMARTMETER_DL SMARTMETER_DL
2599
> wzl6410 MACH_WZL6410 WZL6410
2600
> wzl6410m MACH_WZL6410M WZL6410M 2601
> @@ -2609,7 +2609,7 @@
> fujitsu_tvstbsoc1 MACH_FUJITSU_TVSTBSOC1 FUJITSU_TVSTBSOC1 2621
> lexikon MACH_LEXIKON LEXIKON
2622
> mini2440v2 MACH_MINI2440V2 MINI2440V2 2623
> icontrol MACH_ICONTROL ICONTROL 2624
> -sheevad MACH_SHEEVAD SHEEVAD
2625
> +gplugd MACH_SHEEVAD SHEEVAD
2625
> qsd8x50a_st1_1 MACH_QSD8X50A_ST1_1 QSD8X50A_ST1_1
2626
> qsd8x50a_st1_5 MACH_QSD8X50A_ST1_5 QSD8X50A_ST1_5
2627
> bee MACH_BEE BEE 2628
> @@ -2750,7 +2750,7 @@ h6053 MACH_H6053 H6053
2762
> smint01 MACH_SMINT01 SMINT01
2763
> prtlvt2 MACH_PRTLVT2 PRTLVT2
2764
> ap420 MACH_AP420 AP420
2765
> -htcshift MACH_HTCSHIFT HTCSHIFT 2766
> +htcclio MACH_HTCSHIFT HTCSHIFT
2766
> davinci_dm365_fc MACH_DAVINCI_DM365_FC DAVINCI_DM365_FC 2767
> msm8x55_surf MACH_MSM8X55_SURF MSM8X55_SURF 2768
> msm8x55_ffa MACH_MSM8X55_FFA MSM8X55_FFA 2769
> @@ -2761,7 +2761,7 @@
> oreo_controller MACH_OREO_CONTROLLER OREO_CONTROLLER
2773
> kopin_models MACH_KOPIN_MODELS KOPIN_MODELS 2774
> ttc_vision2 MACH_TTC_VISION2 TTC_VISION2 2775
> cns3420vb MACH_CNS3420VB CNS3420VB 2776
> -lpc2 MACH_LPC2 LPC2 2777
> +lpc_evo MACH_LPC2 LPC2
2777
> olympus MACH_OLYMPUS OLYMPUS
2778
> vortex MACH_VORTEX VORTEX
2779
> s5pc200 MACH_S5PC200 S5PC200
2780
> @@ -2788,7 +2788,7 @@ ti8168evm MACH_TI8168EVM
TI8168EVM 2800
> neocoreomap MACH_NEOCOREOMAP NEOCOREOMAP 2801
> withings_wbp MACH_WITHINGS_WBP WITHINGS_WBP 2802
> dbps MACH_DBPS DBPS 2803
> -sbc9261 MACH_SBC9261 SBC9261
2804
> +at91sam9261 MACH_SBC9261 SBC9261 2804
> pcbfp0001 MACH_PCBFP0001 PCBFP0001 2805
> speedy MACH_SPEEDY SPEEDY
2806
> chrysaor MACH_CHRYSAOR CHRYSAOR 2807
> @@ -2804,3 +2804,112 @@ teton_bga MACH_TETON_BGA
TETON_BGA 2816
> snapper9g45 MACH_SNAPPER9G45 SNAPPER9G45 2817
> tam3517 MACH_TAM3517 TAM3517
2818
> pdc100 MACH_PDC100 PDC100
2819
> +eukrea_cpuimx25sd MACH_EUKREA_CPUIMX25 EUKREA_CPUIMX25 2820
> +eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35 EUKREA_CPUIMX35 2821
> +eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822
> +eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51
2823
> +p565 MACH_P565 P565 2824
> +acer_a4 MACH_ACER_A4 ACER_A4
2825
> +davinci_dm368_bip MACH_DAVINCI_DM368_BIP DAVINCI_DM368_BIP 2826
> +eshare MACH_ESHARE ESHARE
2827
> +hw_omapl138_europa MACH_HW_OMAPL138_EUROPA HW_OMAPL138_EUROPA 2828
> +wlbargn MACH_WLBARGN WLBARGN
2829
> +bm170 MACH_BM170 BM170
2830
> +netspace_mini_v2 MACH_NETSPACE_MINI_V2 NETSPACE_MINI_V2 2831
> +netspace_plug_v2 MACH_NETSPACE_PLUG_V2 NETSPACE_PLUG_V2 2832
> +siemens_l1 MACH_SIEMENS_L1 SIEMENS_L1 2833
> +elv_lcu1 MACH_ELV_LCU1 ELV_LCU1 2834
> +mcu1 MACH_MCU1 MCU1 2835
> +omap3_tao3530 MACH_OMAP3_TAO3530 OMAP3_TAO3530
2836
> +omap3_pcutouch MACH_OMAP3_PCUTOUCH OMAP3_PCUTOUCH
2837
> +smdkc210 MACH_SMDKC210 SMDKC210 2838
> +omap3_braillo MACH_OMAP3_BRAILLO OMAP3_BRAILLO
2839
> +spyplug MACH_SPYPLUG SPYPLUG
2840
> +ginger MACH_GINGER GINGER
2841
> +tny_t3530 MACH_TNY_T3530 TNY_T3530 2842
> +pca102 MACH_PCA102 PCA102
2843
> +spade MACH_SPADE SPADE
2844
> +mxc25_topaz MACH_MXC25_TOPAZ MXC25_TOPAZ 2845
> +t5325 MACH_T5325 T5325
2846
> +gw2361 MACH_GW2361 GW2361
2847
> +elog MACH_ELOG ELOG 2848
> +income MACH_INCOME INCOME
2849
> +bcm589x MACH_BCM589X BCM589X
2850
> +etna MACH_ETNA ETNA 2851
> +hawks MACH_HAWKS HAWKS
2852
> +meson MACH_MESON MESON
2853
> +xsbase255 MACH_XSBASE255 XSBASE255 2854
> +pvm2030 MACH_PVM2030 PVM2030
2855
> +mioa502 MACH_MIOA502 MIOA502
2856
> +vvbox_sdorig2 MACH_VVBOX_SDORIG2 VVBOX_SDORIG2
2857
> +vvbox_sdlite2 MACH_VVBOX_SDLITE2 VVBOX_SDLITE2
2858
> +vvbox_sdpro4 MACH_VVBOX_SDPRO4 VVBOX_SDPRO4 2859
> +htc_spv_m700 MACH_HTC_SPV_M700 HTC_SPV_M700 2860
> +mx257sx MACH_MX257SX MX257SX
2861
> +goni MACH_GONI GONI 2862
> +msm8x55_svlte_ffa MACH_MSM8X55_SVLTE_FFA MSM8X55_SVLTE_FFA 2863
> +msm8x55_svlte_surf MACH_MSM8X55_SVLTE_SURF MSM8X55_SVLTE_SURF 2864
> +quickstep MACH_QUICKSTEP QUICKSTEP 2865
> +dmw96 MACH_DMW96 DMW96
2866
> +hammerhead MACH_HAMMERHEAD HAMMERHEAD 2867
> +trident MACH_TRIDENT TRIDENT
2868
> +lightning MACH_LIGHTNING LIGHTNING 2869
> +iconnect MACH_ICONNECT ICONNECT 2870
> +autobot MACH_AUTOBOT AUTOBOT
2871
> +coconut MACH_COCONUT COCONUT
2872
> +durian MACH_DURIAN DURIAN
2873
> +cayenne MACH_CAYENNE CAYENNE
2874
> +fuji MACH_FUJI FUJI 2875
> +synology_6282 MACH_SYNOLOGY_6282 SYNOLOGY_6282
2876
> +em1sy MACH_EM1SY EM1SY
2877
> +m502 MACH_M502 M502 2878
> +matrix518 MACH_MATRIX518 MATRIX518 2879
> +tiny_gurnard MACH_TINY_GURNARD TINY_GURNARD 2880
> +spear1310 MACH_SPEAR1310 SPEAR1310 2881
> +bv07 MACH_BV07 BV07 2882
> +mxt_td61 MACH_MXT_TD61 MXT_TD61 2883
> +openrd_ultimate MACH_OPENRD_ULTIMATE OPENRD_ULTIMATE
2884
> +devixp MACH_DEVIXP DEVIXP
2885
> +miccpt MACH_MICCPT MICCPT
2886
> +mic256 MACH_MIC256 MIC256
2887
> +as1167 MACH_AS1167 AS1167
2888
> +omap3_ibiza MACH_OMAP3_IBIZA OMAP3_IBIZA 2889
> +u5500 MACH_U5500 U5500
2890
> +davinci_picto MACH_DAVINCI_PICTO DAVINCI_PICTO
2891
> +mecha MACH_MECHA MECHA
2892
> +bubba3 MACH_BUBBA3 BUBBA3
2893
> +pupitre MACH_PUPITRE PUPITRE
2894
> +tegra_harmony MACH_TEGRA_HARMONY TEGRA_HARMONY
2895
> +tegra_vogue MACH_TEGRA_VOGUE TEGRA_VOGUE 2896
> +tegra_e1165 MACH_TEGRA_E1165 TEGRA_E1165 2897
> +simplenet MACH_SIMPLENET SIMPLENET 2898
> +ec4350tbm MACH_EC4350TBM EC4350TBM 2899
> +pec_tc MACH_PEC_TC PEC_TC
2900
> +pec_hc2 MACH_PEC_HC2 PEC_HC2
2901
> +esl_mobilis_a MACH_ESL_MOBILIS_A ESL_MOBILIS_A
2902
> +esl_mobilis_b MACH_ESL_MOBILIS_B ESL_MOBILIS_B
2903
> +esl_wave_a MACH_ESL_WAVE_A ESL_WAVE_A 2904
> +esl_wave_b MACH_ESL_WAVE_B ESL_WAVE_B 2905
> +unisense_mmm MACH_UNISENSE_MMM UNISENSE_MMM 2906
> +blueshark MACH_BLUESHARK BLUESHARK 2907
> +e10 MACH_E10 E10 2908
> +app3k_robin MACH_APP3K_ROBIN APP3K_ROBIN 2909
> +pov15hd MACH_POV15HD POV15HD
2910
> +stella MACH_STELLA STELLA
2911
> +htc_iolite MACH_MACH_HTC_IOLITE MACH_HTC_IOLITE 2912
> +linkstation_lschl MACH_LINKSTATION_LSCHL LINKSTATION_LSCHL 2913
> +netwalker MACH_NETWALKER NETWALKER 2914
> +acsx106 MACH_ACSX106 ACSX106
2915
> +atlas5_c1 MACH_ATLAS5_C1 ATLAS5_C1 2916
> +nsb3ast MACH_NSB3AST NSB3AST
2917
> +gnet_slc MACH_GNET_SLC GNET_SLC 2918
> +af4000 MACH_AF4000 AF4000
2919
> +ark9431 MACH_ARK9431 ARK9431
2920
> +fs_s5pc100 MACH_FS_S5PC100 FS_S5PC100 2921
> +omap3505nova8 MACH_OMAP3505NOVA8 OMAP3505NOVA8
2922
> +omap3621_edp1 MACH_OMAP3621_EDP1 OMAP3621_EDP1
2923
> +oratisaes MACH_ORATISAES ORATISAES 2924
> +smdkv310 MACH_SMDKV310 SMDKV310 2925
> +siemens_l0 MACH_SIEMENS_L0 SIEMENS_L0 2926
> +ventana MACH_VENTANA VENTANA
2927
> +wm8505_7in_netbook MACH_WM8505_7IN_NETBOOK WM8505_7IN_NETBOOK 2928
This should be dropped but you probably know that :)
> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
> index 8b23165..5993659 100644
> --- a/drivers/serial/Kconfig
> +++ b/drivers/serial/Kconfig
> @@ -1351,6 +1351,16 @@ config SERIAL_MSM_CONSOLE
> depends on SERIAL_MSM=y
> select SERIAL_CORE_CONSOLE
>
> +config SERIAL_VT8500
> + bool "VIA VT8500 on-chip serial port support"
> + depends on ARM && ARCH_VT8500
> + select SERIAL_CORE
> +
> +config SERIAL_VT8500_CONSOLE
> + bool "VIA VT8500 serial console support"
> + depends on SERIAL_VT8500=y
> + select SERIAL_CORE_CONSOLE
> +
> config SERIAL_NETX
> tristate "NetX serial port support"
> depends on ARM && ARCH_NETX
> diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
> index 208a855..0e8f7b0 100644
> --- a/drivers/serial/Makefile
> +++ b/drivers/serial/Makefile
> @@ -84,3 +84,4 @@ obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o
> obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o
> obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o
> obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
> +obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o
Possibly move the serial driver into another patch ... split this into patch
series :)
> diff --git a/drivers/serial/vt8500_serial.c
> b/drivers/serial/vt8500_serial.c new file mode 100644
> index 0000000..21e0462
> --- /dev/null
> +++ b/drivers/serial/vt8500_serial.c
> @@ -0,0 +1,612 @@
> +/*
> + * drivers/serial/vt8500_serial.c
> + *
> + * Copyright (C) 2010 Alexey Charkov <alchark at gmail.com>
> + *
> + * Based on msm_serial.c, which is:
> + * Copyright (C) 2007 Google, Inc.
> + * Author: Robert Love <rlove at google.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.
> + */
> +
> +#if defined(CONFIG_SERIAL_VT8500_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
> +# define SUPPORT_SYSRQ
> +#endif
> +
> +#include <linux/hrtimer.h>
> +#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/ioport.h>
> +#include <linux/irq.h>
> +#include <linux/init.h>
> +#include <linux/console.h>
> +#include <linux/tty.h>
> +#include <linux/tty_flip.h>
> +#include <linux/serial_core.h>
> +#include <linux/serial.h>
> +#include <linux/clk.h>
> +#include <linux/platform_device.h>
> +
> +#include <mach/vt8500.h>
> +
> +struct vt8500_port {
> + struct uart_port uart;
> + char name[16];
> + struct clk *clk;
> + unsigned int ier;
> +};
> +
> +#define UART_TO_VT8500(uart_port) ((struct vt8500_port *) uart_port)
> +
> +static inline void vt8500_write(struct uart_port *port, unsigned int val,
> + unsigned int off)
> +{
> + __raw_writel(val, port->membase + off);
> +}
> +
> +static inline unsigned int vt8500_read(struct uart_port *port, unsigned
> int off) +{
> + return __raw_readl(port->membase + off);
> +}
> +
> +static void vt8500_stop_tx(struct uart_port *port)
> +{
> + struct vt8500_port *vt8500_port = UART_TO_VT8500(port);
> +
> + vt8500_port->ier &= ~1;
> + vt8500_write(port, vt8500_port->ier, VT8500_URIER);
> +}
> +
> +static void vt8500_start_tx(struct uart_port *port)
> +{
> + struct vt8500_port *vt8500_port = UART_TO_VT8500(port);
> +
> + vt8500_port->ier |= 1;
> + vt8500_write(port, vt8500_port->ier, VT8500_URIER);
> +}
> +
> +static void vt8500_stop_rx(struct uart_port *port)
> +{
> + struct vt8500_port *vt8500_port = UART_TO_VT8500(port);
> +
> + vt8500_port->ier &= ~2;
> + vt8500_write(port, vt8500_port->ier, VT8500_URIER);
> +}
> +
> +static void vt8500_enable_ms(struct uart_port *port)
> +{
> + struct vt8500_port *vt8500_port = UART_TO_VT8500(port);
> +
> + vt8500_port->ier |= (1 << 10);
> + vt8500_write(port, vt8500_port->ier, VT8500_URIER);
> +}
Won't "inline" help here performance-wise?
> +
> +static void handle_rx(struct uart_port *port)
> +{
> + struct tty_struct *tty = port->state->port.tty;
> +
> + /*
> + * Handle overrun
> + */
> + if ((vt8500_read(port, VT8500_URISR) & (1 << 7))) {
> + port->icount.overrun++;
> + tty_insert_flip_char(tty, 0, TTY_OVERRUN);
> + }
> +
> + /* and now the main RX loop */
> + while (vt8500_read(port, VT8500_URUSR) & (1 << 3)) {
> + unsigned int c;
> + char flag = TTY_NORMAL;
> +
> + c = vt8500_read(port, VT8500_URRDR);
> +
> + /* Mask conditions we're ignorning. */
> + c &= ~port->read_status_mask;
> +
> + if (c & (1 << 9)) {
> + port->icount.frame++;
> + flag = TTY_FRAME;
> + } else if (c & (1 << 8)) {
> + port->icount.parity++;
> + flag = TTY_PARITY;
> + } else
> + port->icount.rx++;
> +
> + if (!uart_handle_sysrq_char(port, c))
> + tty_insert_flip_char(tty, c, flag);
> + }
> +
> + tty_flip_buffer_push(tty);
> +}
> +
> +static void handle_tx(struct uart_port *port)
> +{
> + struct circ_buf *xmit = &port->state->xmit;
> + struct vt8500_port *vt8500_port = UART_TO_VT8500(port);
> + int sent_tx;
> +
> + if (port->x_char) {
> + vt8500_write(port, port->x_char, VT8500_URTDR);
> + port->icount.tx++;
> + port->x_char = 0;
> + }
> +
> + while (!(vt8500_read(port, VT8500_URUSR) & 2)) {
> + if (uart_circ_empty(xmit)) {
> + /* disable tx interrupts */
> + vt8500_port->ier &= ~1;
> + vt8500_write(port, vt8500_port->ier, VT8500_URIER);
> + break;
> + }
> +
> + vt8500_write(port, xmit->buf[xmit->tail], VT8500_URTDR);
> +
> + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
> + port->icount.tx++;
> + sent_tx = 1;
> + }
> +
> + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
> + uart_write_wakeup(port);
> +}
> +
> +static void handle_delta_cts(struct uart_port *port)
> +{
> + port->icount.cts++;
> + wake_up_interruptible(&port->state->port.delta_msr_wait);
> +}
> +
> +static irqreturn_t vt8500_irq(int irq, void *dev_id)
> +{
> + struct uart_port *port = dev_id;
> + struct vt8500_port *vt8500_port = UART_TO_VT8500(port);
> + unsigned int isr;
> +
> + spin_lock(&port->lock);
> + isr = vt8500_read(port, VT8500_URISR);
> + vt8500_write(port, 0, VT8500_URIER); /* disable interrupt */
> +
> + if (isr & 2)
> + handle_rx(port);
> + if (isr & 1)
> + handle_tx(port);
> + if (isr & (1 << 10))
> + handle_delta_cts(port);
> +
> + /* restore interrupt */
> + vt8500_write(port, vt8500_port->ier, VT8500_URIER);
> + spin_unlock(&port->lock);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static unsigned int vt8500_tx_empty(struct uart_port *port)
> +{
> + return (vt8500_read(port, VT8500_URUSR) & 2) ? 0 : TIOCSER_TEMT;
> +}
> +
> +static unsigned int vt8500_get_mctrl(struct uart_port *port)
> +{
> + return TIOCM_CTS | TIOCM_RTS;
> +}
> +
> +static void vt8500_set_mctrl(struct uart_port *port, unsigned int mctrl)
> +{
> + unsigned int lcr;
> +
> + lcr = vt8500_read(port, VT8500_URLCR);
> +
> + if (!(mctrl & TIOCM_RTS)) {
> + lcr &= ~(1 << 6);
> + vt8500_write(port, lcr, VT8500_URLCR);
> + } else {
> + lcr |= (1 << 6);
> + vt8500_write(port, lcr, VT8500_URLCR);
> + }
> +}
> +
> +static void vt8500_break_ctl(struct uart_port *port, int break_ctl)
> +{
> + if (break_ctl)
> + vt8500_write(port, vt8500_read(port, VT8500_URLCR) | (1 << 9),
> + VT8500_URLCR);
> +}
> +
> +static int vt8500_set_baud_rate(struct uart_port *port, unsigned int baud)
> +{
> + unsigned int div = vt8500_read(port, VT8500_URDIV) & ~(0x3ff);
> +
> + if (unlikely((baud < 900) || (baud > 921600)))
> + div |= 7;
> + else
> + div |= (921600 / baud) - 1;
> +
> + while (vt8500_read(port, VT8500_URUSR) & (1 << 5))
> + ;
> + vt8500_write(port, div, VT8500_URDIV);
> +
> + return baud;
> +}
> +
> +static int vt8500_startup(struct uart_port *port)
> +{
> + struct vt8500_port *vt8500_port = UART_TO_VT8500(port);
> + int ret;
> +
> + snprintf(vt8500_port->name, sizeof(vt8500_port->name),
> + "vt8500_serial%d", port->line);
> +
> + ret = request_irq(port->irq, vt8500_irq, IRQF_TRIGGER_HIGH,
> + vt8500_port->name, port);
> + if (unlikely(ret))
> + return ret;
> +
> + vt8500_write(port, 0x03, VT8500_URLCR); /* enable TX & RX */
> +
> + /* turn on RX and CTS interrupts */
> + vt8500_port->ier = (2) | (1 << 10);
> + vt8500_write(port, vt8500_port->ier, VT8500_URIER);
> +
> + return 0;
> +}
> +
> +static void vt8500_shutdown(struct uart_port *port)
> +{
> + struct vt8500_port *vt8500_port = UART_TO_VT8500(port);
> +
> + vt8500_port->ier = 0;
> + vt8500_write(port, 0, VT8500_URIER); /* disable interrupts */
> +
> + free_irq(port->irq, port);
> +}
> +
> +static void vt8500_set_termios(struct uart_port *port, struct ktermios
> *termios, + struct ktermios *old)
> +{
> + unsigned long flags;
> + unsigned int baud, lcr;
> +
> + spin_lock_irqsave(&port->lock, flags);
> +
> + /* calculate and set baud rate */
> + baud = uart_get_baud_rate(port, termios, old, 900, 921600);
> + baud = vt8500_set_baud_rate(port, baud);
> + if (tty_termios_baud_rate(termios))
> + tty_termios_encode_baud_rate(termios, baud, baud);
> +
> + /* calculate parity */
> + lcr = vt8500_read(port, VT8500_URLCR);
> + lcr &= ~((1 << 5) | (1 << 4));
> + if (termios->c_cflag & PARENB) {
> + lcr |= (1 << 4);
> + if (termios->c_cflag & PARODD)
> + lcr |= (1 << 5);
> + }
> +
> + /* calculate bits per char */
> + lcr &= ~(1 << 2);
> + switch (termios->c_cflag & CSIZE) {
> + case CS7:
> + break;
> + case CS8:
> + default:
> + lcr |= (1 << 2);
> + break;
> + }
> +
> + /* calculate stop bits */
> + lcr &= ~(1 << 3);
> + if (termios->c_cflag & CSTOPB)
> + lcr |= (1 << 3);
> +
> + /* set parity, bits per char, and stop bit */
> + vt8500_write(port, lcr, VT8500_URLCR);
> +
> + /* Configure status bits to ignore based on termio flags. */
> + port->read_status_mask = 0;
> + if (termios->c_iflag & INPCK)
> + port->read_status_mask |= (1 << 9) | (1 << 8);
> +
> + uart_update_timeout(port, termios->c_cflag, baud);
> +
> + spin_unlock_irqrestore(&port->lock, flags);
> +}
> +
> +static const char *vt8500_type(struct uart_port *port)
> +{
> + return "VT8500";
> +}
> +
> +static void vt8500_release_port(struct uart_port *port)
> +{
> + struct platform_device *pdev = to_platform_device(port->dev);
> + struct resource *resource;
> + resource_size_t size;
> +
> + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (unlikely(!resource))
> + return;
> + size = resource->end - resource->start + 1;
> +
> + release_mem_region(port->mapbase, size);
> + iounmap(port->membase);
> + port->membase = NULL;
> +}
> +
> +static int vt8500_request_port(struct uart_port *port)
> +{
> + struct platform_device *pdev = to_platform_device(port->dev);
> + struct resource *resource;
> + resource_size_t size;
> +
> + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (unlikely(!resource))
> + return -ENXIO;
> + size = resource->end - resource->start + 1;
> +
> + if (unlikely(!request_mem_region(port->mapbase, size, "vt8500_serial")))
> + return -EBUSY;
> +
> + port->membase = ioremap(port->mapbase, size);
> + if (!port->membase) {
> + release_mem_region(port->mapbase, size);
> + return -EBUSY;
> + }
> +
> + return 0;
> +}
> +
> +static void vt8500_config_port(struct uart_port *port, int flags)
> +{
> + if (flags & UART_CONFIG_TYPE) {
> + port->type = PORT_VT8500;
> + vt8500_request_port(port);
> + }
> +}
> +
> +static int vt8500_verify_port(struct uart_port *port, struct serial_struct
> *ser) +{
> + if (unlikely(ser->type != PORT_UNKNOWN && ser->type != PORT_VT8500))
> + return -EINVAL;
> + if (unlikely(port->irq != ser->irq))
> + return -EINVAL;
> + return 0;
> +}
> +
> +static struct uart_ops vt8500_uart_pops = {
> + .tx_empty = vt8500_tx_empty,
> + .set_mctrl = vt8500_set_mctrl,
> + .get_mctrl = vt8500_get_mctrl,
> + .stop_tx = vt8500_stop_tx,
> + .start_tx = vt8500_start_tx,
> + .stop_rx = vt8500_stop_rx,
> + .enable_ms = vt8500_enable_ms,
> + .break_ctl = vt8500_break_ctl,
> + .startup = vt8500_startup,
> + .shutdown = vt8500_shutdown,
> + .set_termios = vt8500_set_termios,
> + .type = vt8500_type,
> + .release_port = vt8500_release_port,
> + .request_port = vt8500_request_port,
> + .config_port = vt8500_config_port,
> + .verify_port = vt8500_verify_port,
> +};
> +
> +static struct vt8500_port vt8500_uart_ports[] = {
> + {
> + .uart = {
> + .iotype = UPIO_MEM,
> + .ops = &vt8500_uart_pops,
> + .flags = UPF_BOOT_AUTOCONF,
> + .fifosize = 16,
> + .line = 0,
> + },
> + },
> + {
> + .uart = {
> + .iotype = UPIO_MEM,
> + .ops = &vt8500_uart_pops,
> + .flags = UPF_BOOT_AUTOCONF,
> + .fifosize = 16,
> + .line = 1,
> + },
> + },
> + {
> + .uart = {
> + .iotype = UPIO_MEM,
> + .ops = &vt8500_uart_pops,
> + .flags = UPF_BOOT_AUTOCONF,
> + .fifosize = 16,
> + .line = 2,
> + },
> + },
> + {
> + .uart = {
> + .iotype = UPIO_MEM,
> + .ops = &vt8500_uart_pops,
> + .flags = UPF_BOOT_AUTOCONF,
> + .fifosize = 16,
> + .line = 3,
> + },
> + },
> +};
> +
> +#define UART_NR ARRAY_SIZE(vt8500_uart_ports)
> +
> +static inline struct uart_port *get_port_from_line(unsigned int line)
> +{
> + return &vt8500_uart_ports[line].uart;
> +}
> +
> +#ifdef CONFIG_SERIAL_VT8500_CONSOLE
> +
> +static void vt8500_console_putchar(struct uart_port *port, int c)
> +{
> + while (vt8500_read(port, VT8500_URUSR) & 2) /* Transmitter busy */
> + ;
> + vt8500_write(port, c, VT8500_URTDR);
> +}
> +
> +static void vt8500_console_write(struct console *co, const char *s,
> + unsigned int count)
> +{
> + struct uart_port *port;
> + struct vt8500_port *vt8500_port;
> +
> + BUG_ON(co->index < 0 || co->index >= UART_NR);
> +
> + port = get_port_from_line(co->index);
> + vt8500_port = UART_TO_VT8500(port);
> +
> + spin_lock(&port->lock);
> + uart_console_write(port, s, count, vt8500_console_putchar);
> + spin_unlock(&port->lock);
> +}
> +
> +static int __init vt8500_console_setup(struct console *co, char *options)
> +{
> + struct uart_port *port;
> + int baud, flow, bits, parity;
> + unsigned int tmp;
> +
> + if (unlikely(co->index >= UART_NR || co->index < 0))
> + return -ENXIO;
> +
> + port = get_port_from_line(co->index);
> +
> + if (unlikely(!port->membase))
> + return -ENXIO;
> +
> + port->cons = co;
> +
> + if (options)
> + uart_parse_options(options, &baud, &parity, &bits, &flow);
> +
> + bits = 8;
> + parity = 'n';
> + flow = 'n';
> + tmp = vt8500_read(port, VT8500_URLCR) & ~((1 << 5) | (1 << 4));
> + vt8500_write(port, tmp, VT8500_URLCR); /* 8N1 */
> +
> + if (baud < 28800 || baud > 921600)
> + baud = 115200;
> + vt8500_set_baud_rate(port, baud);
> +
> + printk(KERN_INFO "vt8500_serial: console setup on port #%d\n",
> + port->line);
> +
> + return uart_set_options(port, co, baud, parity, bits, flow);
> +}
> +
> +static struct uart_driver vt8500_uart_driver;
> +
> +static struct console vt8500_console = {
> + .name = "ttyS",
> + .write = vt8500_console_write,
> + .device = uart_console_device,
> + .setup = vt8500_console_setup,
> + .flags = CON_PRINTBUFFER,
> + .index = -1,
> + .data = &vt8500_uart_driver,
> +};
> +
> +#define VT8500_CONSOLE (&vt8500_console)
> +
> +#else
> +#define VT8500_CONSOLE NULL
> +#endif
> +
> +static struct uart_driver vt8500_uart_driver = {
> + .owner = THIS_MODULE,
> + .driver_name = "vt8500_serial",
> + .dev_name = "ttyS",
> + .nr = UART_NR,
> + .cons = VT8500_CONSOLE,
> +};
> +
> +static int __init vt8500_serial_probe(struct platform_device *pdev)
> +{
> + struct vt8500_port *vt8500_port;
> + struct resource *resource;
> + struct uart_port *port;
> + int irq;
> +
> + if (unlikely(pdev->id < 0 || pdev->id >= UART_NR))
> + return -ENXIO;
> +
> + printk(KERN_INFO "vt8500_serial: detected port #%d\n", pdev->id);
> +
> + port = get_port_from_line(pdev->id);
> + port->dev = &pdev->dev;
> + vt8500_port = UART_TO_VT8500(port);
> +
> + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (unlikely(!resource))
> + return -ENXIO;
> + port->mapbase = resource->start;
> +
> + irq = platform_get_irq(pdev, 0);
> + if (unlikely(irq < 0))
> + return -ENXIO;
> + port->irq = irq;
> +
> + platform_set_drvdata(pdev, port);
> +
> + return uart_add_one_port(&vt8500_uart_driver, port);
> +}
> +
> +static int __devexit vt8500_serial_remove(struct platform_device *pdev)
> +{
> + return 0;
> +}
> +
> +static struct platform_driver vt8500_platform_driver = {
> + .remove = vt8500_serial_remove,
> + .driver = {
> + .name = "vt8500_serial",
> + .owner = THIS_MODULE,
> + },
> +};
> +
> +static int __init vt8500_serial_init(void)
> +{
> + int ret;
> +
> + ret = uart_register_driver(&vt8500_uart_driver);
> + if (unlikely(ret))
> + return ret;
> +
> + ret = platform_driver_probe(&vt8500_platform_driver,
> + vt8500_serial_probe);
> +
> + if (unlikely(ret))
> + uart_unregister_driver(&vt8500_uart_driver);
> +
> + printk(KERN_INFO "vt8500_serial: driver initialized\n");
> +
> + return ret;
> +}
> +
> +static void __exit vt8500_serial_exit(void)
> +{
> +#ifdef CONFIG_SERIAL_VT8500_CONSOLE
> + unregister_console(&vt8500_console);
> +#endif
> + platform_driver_unregister(&vt8500_platform_driver);
> + uart_unregister_driver(&vt8500_uart_driver);
> +}
> +
> +module_init(vt8500_serial_init);
> +module_exit(vt8500_serial_exit);
> +
> +MODULE_AUTHOR("Alexey Charkov <alchark at gmail.com>");
> +MODULE_DESCRIPTION("Driver for vt8500 serial device");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> index f10db6e..20ba8c3 100644
> --- a/include/linux/serial_core.h
> +++ b/include/linux/serial_core.h
> @@ -186,6 +186,9 @@
> #define PORT_ALTERA_JTAGUART 91
> #define PORT_ALTERA_UART 92
>
> +/* VIA VT8500 SoC */
> +#define PORT_VT8500 93
> +
> #ifdef __KERNEL__
>
> #include <linux/compiler.h>
This patch looks very good otherwise, good night ! :)
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
More information about the linux-arm-kernel
mailing list