All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/8] initial suport for Alpscale ASM9260
@ 2014-09-21 18:41 Oleksij Rempel
  2014-09-21 18:41 ` [PATCH v2 1/8] ARM: add mach-asm9260 Oleksij Rempel
                   ` (5 more replies)
  0 siblings, 6 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-21 18:41 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset provide initial support for Alpscale ASM9260,
ARM based SoC.

Oleksij Rempel (8):
  ARM: add mach-asm9260
  add include/debug/asm9260.S
  add alphascale,asm9260.h binding
  ARM: dts: add DT for Alphascale ASM9260 SoC
  clk: add clk-asm9260 driver
  clocksource: add asm9260_timer driver
  irqchip: add irq-asm9260 driver
  tty/serial: add asm9260-serial driver

 arch/arm/Kconfig                                |   14 +
 arch/arm/Kconfig.debug                          |   33 +-
 arch/arm/Makefile                               |    1 +
 arch/arm/boot/dts/Makefile                      |    2 +
 arch/arm/boot/dts/alphascale-asm9260-devkit.dts |   15 +
 arch/arm/boot/dts/alphascale-asm9260.dtsi       |  166 +++
 arch/arm/include/debug/asm9260.S                |   31 +
 arch/arm/mach-asm9260/Makefile                  |   11 +
 arch/arm/mach-asm9260/Makefile.boot             |    2 +
 arch/arm/mach-asm9260/core.c                    |   77 ++
 drivers/clk/Makefile                            |    1 +
 drivers/clk/clk-asm9260.c                       |  350 ++++++
 drivers/clocksource/Makefile                    |    1 +
 drivers/clocksource/asm9260_timer.c             |  244 ++++
 drivers/irqchip/Makefile                        |    1 +
 drivers/irqchip/irq-asm9260.c                   |  257 ++++
 drivers/tty/serial/Kconfig                      |   17 +
 drivers/tty/serial/Makefile                     |    1 +
 drivers/tty/serial/asm9260_serial.c             | 1485 +++++++++++++++++++++++
 include/dt-bindings/clock/alphascale,asm9260.h  |   97 ++
 include/uapi/linux/serial_core.h                |    2 +
 21 files changed, 2805 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/boot/dts/alphascale-asm9260-devkit.dts
 create mode 100644 arch/arm/boot/dts/alphascale-asm9260.dtsi
 create mode 100644 arch/arm/include/debug/asm9260.S
 create mode 100644 arch/arm/mach-asm9260/Makefile
 create mode 100644 arch/arm/mach-asm9260/Makefile.boot
 create mode 100644 arch/arm/mach-asm9260/core.c
 create mode 100644 drivers/clk/clk-asm9260.c
 create mode 100644 drivers/clocksource/asm9260_timer.c
 create mode 100644 drivers/irqchip/irq-asm9260.c
 create mode 100644 drivers/tty/serial/asm9260_serial.c
 create mode 100644 include/dt-bindings/clock/alphascale,asm9260.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 1/8] ARM: add mach-asm9260
  2014-09-21 18:41 [PATCH v2 0/8] initial suport for Alpscale ASM9260 Oleksij Rempel
@ 2014-09-21 18:41 ` Oleksij Rempel
  2014-09-22 15:08   ` Arnd Bergmann
  2014-09-21 18:41 ` [PATCH v2 2/8] add include/debug/asm9260.S Oleksij Rempel
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-21 18:41 UTC (permalink / raw)
  To: linux-arm-kernel

it is low cost (?) SoC targeted for market in China and India which
trying to compete with AT91SAM9G25.

Here is some info:
http://www.alphascale.com/index.asp?ics/615.html

One of products:
http://www.aliexpress.com/store/product/2014-hot-sales-FREE-SHIPPING-new-Purple-core-ARM9-development-board-ASM9260T-SDRAM-power-line/433637_1931495721.html

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 arch/arm/Kconfig                    | 14 +++++++
 arch/arm/Makefile                   |  1 +
 arch/arm/mach-asm9260/Makefile      | 11 ++++++
 arch/arm/mach-asm9260/Makefile.boot |  2 +
 arch/arm/mach-asm9260/core.c        | 77 +++++++++++++++++++++++++++++++++++++
 5 files changed, 105 insertions(+)
 create mode 100644 arch/arm/mach-asm9260/Makefile
 create mode 100644 arch/arm/mach-asm9260/Makefile.boot
 create mode 100644 arch/arm/mach-asm9260/core.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5918d40..1a71feb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -379,6 +379,20 @@ config ARCH_AT91
 	  This enables support for systems based on Atmel
 	  AT91RM9200 and AT91SAM9* processors.
 
+config MACH_ASM9260
+	bool "Alphascale ASM9260"
+	select ARCH_REQUIRE_GPIOLIB
+	select COMMON_CLK
+	select IRQ_DOMAIN
+	select SPARSE_IRQ
+	select MULTI_IRQ_HANDLER
+	select GENERIC_IRQ_CHIP
+	select GENERIC_CLOCKEVENTS
+	select CLKSRC_MMIO
+	select CPU_ARM926T
+	help
+	  Support for Alpascale ASM9260 based platform.
+
 config ARCH_CLPS711X
 	bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
 	select ARCH_REQUIRE_GPIOLIB
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 0ce9d0f..dda8f6d 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -146,6 +146,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
 machine-$(CONFIG_ARCH_AT91)		+= at91
+machine-$(CONFIG_MACH_ASM9260)		+= asm9260
 machine-$(CONFIG_ARCH_AXXIA)		+= axxia
 machine-$(CONFIG_ARCH_BCM)		+= bcm
 machine-$(CONFIG_ARCH_BERLIN)		+= berlin
diff --git a/arch/arm/mach-asm9260/Makefile b/arch/arm/mach-asm9260/Makefile
new file mode 100644
index 0000000..4bd8ebd
--- /dev/null
+++ b/arch/arm/mach-asm9260/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y			:= core.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
diff --git a/arch/arm/mach-asm9260/Makefile.boot b/arch/arm/mach-asm9260/Makefile.boot
new file mode 100644
index 0000000..c57b3b4
--- /dev/null
+++ b/arch/arm/mach-asm9260/Makefile.boot
@@ -0,0 +1,2 @@
+zreladdr-y	:= 0x20008000
+
diff --git a/arch/arm/mach-asm9260/core.c b/arch/arm/mach-asm9260/core.c
new file mode 100644
index 0000000..331af96
--- /dev/null
+++ b/arch/arm/mach-asm9260/core.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *  Co-author: Du Huanpeng <u74147@gmail.com>
+ * map_desc based on:
+ *  linux/arch/arm/mach-asm9260/core.c
+ *  Copyright (C) 2011-2014 Alphascale
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+static struct map_desc asm9260_io_desc[] __initdata = {
+	{	/* IO space */
+		.virtual	= (unsigned long)0xf0000000,
+		.pfn		= __phys_to_pfn(0x80000000),
+		.length		= 0x00800000,
+		.type		= MT_DEVICE
+	},
+	{	/* LCD IO space	*/
+		.virtual	= (unsigned long)0xf0a00000,
+		.pfn		= __phys_to_pfn(0x80800000),
+		.length		= 0x00009000,
+		.type		= MT_DEVICE
+	},
+	{	/* GPIO IO space */
+		.virtual	= (unsigned long)0xf0800000,
+		.pfn		= __phys_to_pfn(0x50000000),
+		.length		= 0x00100000,
+		.type		= MT_DEVICE
+	},
+	{	/* SRAM space Cacheable */
+		.virtual	= (unsigned long)0xd0000000,
+		.pfn		= __phys_to_pfn(0x40000000),
+		.length		= 0x00100000,
+#ifdef CONFIG_SRAM_MEM_CACHED
+		.type		= MT_MEMORY
+#else
+		.type		= MT_DEVICE
+#endif
+	},
+};
+
+static void __init asm9260_map_io(void)
+{
+	iotable_init(asm9260_io_desc, ARRAY_SIZE(asm9260_io_desc));
+}
+
+static void __init asm9260_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char * const asm9260_dt_board_compat[] __initconst = {
+	"alphascale,asm9260",
+	NULL
+};
+
+DT_MACHINE_START(ASM9260, "Alphascale ASM9260 (Device Tree Support)")
+	.map_io		= asm9260_map_io,
+	.init_machine	= asm9260_init,
+	.dt_compat	= asm9260_dt_board_compat,
+MACHINE_END
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v2 2/8] add include/debug/asm9260.S
  2014-09-21 18:41 [PATCH v2 0/8] initial suport for Alpscale ASM9260 Oleksij Rempel
  2014-09-21 18:41 ` [PATCH v2 1/8] ARM: add mach-asm9260 Oleksij Rempel
@ 2014-09-21 18:41 ` Oleksij Rempel
  2014-09-21 18:45 ` Oleksij Rempel
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-21 18:41 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 arch/arm/Kconfig.debug           | 33 ++++++++++++++++++++++++++++++---
 arch/arm/include/debug/asm9260.S | 31 +++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/include/debug/asm9260.S

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index b11ad54..6902a57 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -953,6 +953,27 @@ choice
 		  options; the platform specific options are deprecated
 		  and will be soon removed.
 
+	config DEBUG_ASM9260_UART
+		bool "Kernel low-level debugging via asm9260 UART"
+		depends on MACH_ASM9260
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to an UART or USART port on asm9260 based
+		  machines.
+
+		    DEBUG_UART_PHYS | DEBUG_UART_VIRT
+
+		    0x80000000      | 0xf0000000     | UART0
+		    0x80004000      | 0xf0004000     | UART1
+		    0x80008000      | 0xf0008000     | UART2
+		    0x8000c000      | 0xf000c000     | UART3
+		    0x80010000      | 0xf0010000     | UART4
+		    0x80014000      | 0xf0014000     | UART5
+		    0x80018000      | 0xf0018000     | UART6
+		    0x8001c000      | 0xf001c000     | UART7
+		    0x80020000      | 0xf0020000     | UART8
+		    0x80024000      | 0xf0024000     | UART9
+
 endchoice
 
 config DEBUG_EXYNOS_UART
@@ -1038,6 +1059,7 @@ config DEBUG_LL_INCLUDE
 	default "debug/vf.S" if DEBUG_VF_UART
 	default "debug/vt8500.S" if DEBUG_VT8500_UART0
 	default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1
+	default "debug/asm9260.S" if DEBUG_ASM9260_UART
 	default "mach/debug-macro.S"
 
 # Compatibility options for PL01x
@@ -1094,6 +1116,7 @@ config DEBUG_UART_PHYS
 	default 0x50008000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART2 || \
 				DEBUG_S3C2410_UART2)
 	default 0x7c0003f8 if FOOTBRIDGE
+	default 0x80010000 if DEBUG_ASM9260_UART
 	default 0x80070000 if DEBUG_IMX23_UART
 	default 0x80074000 if DEBUG_IMX28_UART
 	default 0x80230000 if DEBUG_PICOXCELL_UART
@@ -1126,7 +1149,8 @@ config DEBUG_UART_PHYS
 	depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
 		DEBUG_LL_UART_EFM32 || \
 		DEBUG_UART_8250 || DEBUG_UART_PL01X || \
-		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART
+		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || \
+		DEBUG_S3C24XX_UART || DEBUG_ASM9260_UART
 
 config DEBUG_UART_VIRT
 	hex "Virtual base address of debug UART"
@@ -1134,6 +1158,7 @@ config DEBUG_UART_VIRT
 	default 0xe1000000 if DEBUG_MSM_UART
 	default 0xf0000be0 if ARCH_EBSA110
 	default 0xf0009000 if DEBUG_CNS3XXX
+	default 0xf0010000 if DEBUG_ASM9260_UART
 	default 0xf01fb000 if DEBUG_NOMADIK_UART
 	default 0xf0201000 if DEBUG_BCM2835
 	default 0xf1000300 if DEBUG_BCM_5301X
@@ -1194,7 +1219,8 @@ config DEBUG_UART_VIRT
 	default DEBUG_UART_PHYS if !MMU
 	depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
 		DEBUG_UART_8250 || DEBUG_UART_PL01X || \
-		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART
+		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || \
+		DEBUG_S3C24XX_UART || DEBUG_ASM9260_UART
 
 config DEBUG_UART_8250_SHIFT
 	int "Register offset shift for the 8250 debug UART"
@@ -1236,7 +1262,8 @@ config DEBUG_UNCOMPRESS
 config UNCOMPRESS_INCLUDE
 	string
 	default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM || \
-					PLAT_SAMSUNG || ARCH_EFM32
+					PLAT_SAMSUNG || ARCH_EFM32 || \
+					MACH_ASM9260
 	default "mach/uncompress.h"
 
 config EARLY_PRINTK
diff --git a/arch/arm/include/debug/asm9260.S b/arch/arm/include/debug/asm9260.S
new file mode 100644
index 0000000..c70d51f
--- /dev/null
+++ b/arch/arm/include/debug/asm9260.S
@@ -0,0 +1,31 @@
+/* arch/arm/mach-imx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *  Modified for ASM9260 by Oleksij Remepl <linux@rempel-privat.de>
+ *
+ * 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.
+ *
+ */
+
+		.macro	addruart, rp, rv, tmp
+		ldr	\rp, = CONFIG_DEBUG_UART_PHYS
+		ldr	\rv, = CONFIG_DEBUG_UART_VIRT
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x50]	@ TXDATA
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldr	\rd, [\rx, #0x60]	@ STAT
+		tst	\rd, #1 << 27		@ TXEMPTY
+		beq	1002b			@ wait until transmit done
+		.endm
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v2 2/8] add include/debug/asm9260.S
  2014-09-21 18:41 [PATCH v2 0/8] initial suport for Alpscale ASM9260 Oleksij Rempel
  2014-09-21 18:41 ` [PATCH v2 1/8] ARM: add mach-asm9260 Oleksij Rempel
  2014-09-21 18:41 ` [PATCH v2 2/8] add include/debug/asm9260.S Oleksij Rempel
@ 2014-09-21 18:45 ` Oleksij Rempel
  2014-09-21 18:45   ` [PATCH v2 3/8] add alphascale,asm9260.h binding Oleksij Rempel
                     ` (5 more replies)
  2014-09-23 11:32 ` [PATCH v2 0/8] initial suport for Alpscale ASM9260 Arnd Bergmann
                   ` (2 subsequent siblings)
  5 siblings, 6 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-21 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 arch/arm/Kconfig.debug           | 33 ++++++++++++++++++++++++++++++---
 arch/arm/include/debug/asm9260.S | 31 +++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/include/debug/asm9260.S

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index b11ad54..6902a57 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -953,6 +953,27 @@ choice
 		  options; the platform specific options are deprecated
 		  and will be soon removed.
 
+	config DEBUG_ASM9260_UART
+		bool "Kernel low-level debugging via asm9260 UART"
+		depends on MACH_ASM9260
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to an UART or USART port on asm9260 based
+		  machines.
+
+		    DEBUG_UART_PHYS | DEBUG_UART_VIRT
+
+		    0x80000000      | 0xf0000000     | UART0
+		    0x80004000      | 0xf0004000     | UART1
+		    0x80008000      | 0xf0008000     | UART2
+		    0x8000c000      | 0xf000c000     | UART3
+		    0x80010000      | 0xf0010000     | UART4
+		    0x80014000      | 0xf0014000     | UART5
+		    0x80018000      | 0xf0018000     | UART6
+		    0x8001c000      | 0xf001c000     | UART7
+		    0x80020000      | 0xf0020000     | UART8
+		    0x80024000      | 0xf0024000     | UART9
+
 endchoice
 
 config DEBUG_EXYNOS_UART
@@ -1038,6 +1059,7 @@ config DEBUG_LL_INCLUDE
 	default "debug/vf.S" if DEBUG_VF_UART
 	default "debug/vt8500.S" if DEBUG_VT8500_UART0
 	default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1
+	default "debug/asm9260.S" if DEBUG_ASM9260_UART
 	default "mach/debug-macro.S"
 
 # Compatibility options for PL01x
@@ -1094,6 +1116,7 @@ config DEBUG_UART_PHYS
 	default 0x50008000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART2 || \
 				DEBUG_S3C2410_UART2)
 	default 0x7c0003f8 if FOOTBRIDGE
+	default 0x80010000 if DEBUG_ASM9260_UART
 	default 0x80070000 if DEBUG_IMX23_UART
 	default 0x80074000 if DEBUG_IMX28_UART
 	default 0x80230000 if DEBUG_PICOXCELL_UART
@@ -1126,7 +1149,8 @@ config DEBUG_UART_PHYS
 	depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
 		DEBUG_LL_UART_EFM32 || \
 		DEBUG_UART_8250 || DEBUG_UART_PL01X || \
-		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART
+		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || \
+		DEBUG_S3C24XX_UART || DEBUG_ASM9260_UART
 
 config DEBUG_UART_VIRT
 	hex "Virtual base address of debug UART"
@@ -1134,6 +1158,7 @@ config DEBUG_UART_VIRT
 	default 0xe1000000 if DEBUG_MSM_UART
 	default 0xf0000be0 if ARCH_EBSA110
 	default 0xf0009000 if DEBUG_CNS3XXX
+	default 0xf0010000 if DEBUG_ASM9260_UART
 	default 0xf01fb000 if DEBUG_NOMADIK_UART
 	default 0xf0201000 if DEBUG_BCM2835
 	default 0xf1000300 if DEBUG_BCM_5301X
@@ -1194,7 +1219,8 @@ config DEBUG_UART_VIRT
 	default DEBUG_UART_PHYS if !MMU
 	depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
 		DEBUG_UART_8250 || DEBUG_UART_PL01X || \
-		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART
+		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || \
+		DEBUG_S3C24XX_UART || DEBUG_ASM9260_UART
 
 config DEBUG_UART_8250_SHIFT
 	int "Register offset shift for the 8250 debug UART"
@@ -1236,7 +1262,8 @@ config DEBUG_UNCOMPRESS
 config UNCOMPRESS_INCLUDE
 	string
 	default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM || \
-					PLAT_SAMSUNG || ARCH_EFM32
+					PLAT_SAMSUNG || ARCH_EFM32 || \
+					MACH_ASM9260
 	default "mach/uncompress.h"
 
 config EARLY_PRINTK
diff --git a/arch/arm/include/debug/asm9260.S b/arch/arm/include/debug/asm9260.S
new file mode 100644
index 0000000..c70d51f
--- /dev/null
+++ b/arch/arm/include/debug/asm9260.S
@@ -0,0 +1,31 @@
+/* arch/arm/mach-imx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *  Modified for ASM9260 by Oleksij Remepl <linux@rempel-privat.de>
+ *
+ * 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.
+ *
+ */
+
+		.macro	addruart, rp, rv, tmp
+		ldr	\rp, = CONFIG_DEBUG_UART_PHYS
+		ldr	\rv, = CONFIG_DEBUG_UART_VIRT
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x50]	@ TXDATA
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldr	\rd, [\rx, #0x60]	@ STAT
+		tst	\rd, #1 << 27		@ TXEMPTY
+		beq	1002b			@ wait until transmit done
+		.endm
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v2 3/8] add alphascale,asm9260.h binding
  2014-09-21 18:45 ` Oleksij Rempel
@ 2014-09-21 18:45   ` Oleksij Rempel
  2014-09-24 10:15     ` Mark Rutland
  2014-09-21 18:45   ` [PATCH v2 4/8] ARM: dts: add DT for Alphascale ASM9260 SoC Oleksij Rempel
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-21 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 include/dt-bindings/clock/alphascale,asm9260.h | 97 ++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)
 create mode 100644 include/dt-bindings/clock/alphascale,asm9260.h

diff --git a/include/dt-bindings/clock/alphascale,asm9260.h b/include/dt-bindings/clock/alphascale,asm9260.h
new file mode 100644
index 0000000..04e8db2
--- /dev/null
+++ b/include/dt-bindings/clock/alphascale,asm9260.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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 _DT_BINDINGS_CLK_ASM9260_H
+#define _DT_BINDINGS_CLK_ASM9260_H
+
+/* ahb gate */
+#define CLKID_AHB_ROM		0
+#define CLKID_AHB_RAM		1
+#define CLKID_AHB_GPIO		2
+#define CLKID_AHB_MAC		3
+#define CLKID_AHB_EMI		4
+#define CLKID_AHB_USB0		5
+#define CLKID_AHB_USB1		6
+#define CLKID_AHB_DMA0		7
+#define CLKID_AHB_DMA1		8
+#define CLKID_AHB_UART0		9
+#define CLKID_AHB_UART1		10
+#define CLKID_AHB_UART2		11
+#define CLKID_AHB_UART3		12
+#define CLKID_AHB_UART4		13
+#define CLKID_AHB_UART5		14
+#define CLKID_AHB_UART6		15
+#define CLKID_AHB_UART7		16
+#define CLKID_AHB_UART8		17
+#define CLKID_AHB_UART9		18
+#define CLKID_AHB_I2S0		19
+#define CLKID_AHB_I2C0		20
+#define CLKID_AHB_I2C1		21
+#define CLKID_AHB_SSP0		22
+#define CLKID_AHB_IOCONFIG	23
+#define CLKID_AHB_WDT		24
+#define CLKID_AHB_CAN0		25
+#define CLKID_AHB_CAN1		26
+#define CLKID_AHB_MPWM		27
+#define CLKID_AHB_SPI0		28
+#define CLKID_AHB_SPI1		29
+#define CLKID_AHB_QEI		30
+#define CLKID_AHB_QUADSPI0	31
+#define CLKID_AHB_CAMIF		32
+#define CLKID_AHB_LCDIF		33
+#define CLKID_AHB_TIMER0	34
+#define CLKID_AHB_TIMER1	35
+#define CLKID_AHB_TIMER2	36
+#define CLKID_AHB_TIMER3	37
+#define CLKID_AHB_IRQ		38
+#define CLKID_AHB_RTC		39
+#define CLKID_AHB_NAND		40
+#define CLKID_AHB_ADC0		41
+#define CLKID_AHB_LED		42
+#define CLKID_AHB_DAC0		43
+#define CLKID_AHB_LCD		44
+#define CLKID_AHB_I2S1		45
+#define CLKID_AHB_MAC1		46
+
+/* devider */
+#define CLKID_SYS_CPU		47
+#define CLKID_SYS_AHB		48
+#define CLKID_SYS_I2S0M		49
+#define CLKID_SYS_I2S0S		50
+#define CLKID_SYS_I2S1M		51
+#define CLKID_SYS_I2S1S		52
+#define CLKID_SYS_UART0		53
+#define CLKID_SYS_UART1		54
+#define CLKID_SYS_UART2		55
+#define CLKID_SYS_UART3		56
+#define CLKID_SYS_UART4		56
+#define CLKID_SYS_UART5		57
+#define CLKID_SYS_UART6		58
+#define CLKID_SYS_UART7		59
+#define CLKID_SYS_UART8		60
+#define CLKID_SYS_UART9		61
+#define CLKID_SYS_SPI0		62
+#define CLKID_SYS_SPI1		63
+#define CLKID_SYS_QUADSPI	64
+#define CLKID_SYS_SSP0		65
+#define CLKID_SYS_NAND		66
+#define CLKID_SYS_TRACE		67
+#define CLKID_SYS_CAMM		68
+#define CLKID_SYS_WDT		69
+#define CLKID_SYS_CLKOUT	70
+#define CLKID_SYS_MAC		71
+#define CLKID_SYS_LCD		72
+#define CLKID_SYS_ADCANA	73
+
+#define MAX_CLKS		74
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v2 4/8] ARM: dts: add DT for Alphascale ASM9260 SoC
  2014-09-21 18:45 ` Oleksij Rempel
  2014-09-21 18:45   ` [PATCH v2 3/8] add alphascale,asm9260.h binding Oleksij Rempel
@ 2014-09-21 18:45   ` Oleksij Rempel
  2014-09-22 15:14     ` Arnd Bergmann
  2014-09-24 10:11     ` Mark Rutland
  2014-09-21 18:45   ` [PATCH v2 5/8] clk: add clk-asm9260 driver Oleksij Rempel
                     ` (3 subsequent siblings)
  5 siblings, 2 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-21 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 arch/arm/boot/dts/Makefile                      |   2 +
 arch/arm/boot/dts/alphascale-asm9260-devkit.dts |  15 +++
 arch/arm/boot/dts/alphascale-asm9260.dtsi       | 166 ++++++++++++++++++++++++
 3 files changed, 183 insertions(+)
 create mode 100644 arch/arm/boot/dts/alphascale-asm9260-devkit.dts
 create mode 100644 arch/arm/boot/dts/alphascale-asm9260.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b8c5cd3..8943d72 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -492,6 +492,8 @@ dtb-$(CONFIG_MACH_DOVE) += dove-cm-a510.dtb \
 	dove-d3plug.dtb \
 	dove-dove-db.dtb
 
+dtb-$(CONFIG_MACH_ASM9260) += alphascale-asm9260-devkit.dtb
+
 targets += dtbs dtbs_install
 targets += $(dtb-y)
 endif
diff --git a/arch/arm/boot/dts/alphascale-asm9260-devkit.dts b/arch/arm/boot/dts/alphascale-asm9260-devkit.dts
new file mode 100644
index 0000000..5d178f2
--- /dev/null
+++ b/arch/arm/boot/dts/alphascale-asm9260-devkit.dts
@@ -0,0 +1,15 @@
+/dts-v1/;
+#include "alphascale-asm9260.dtsi"
+
+/ {
+	model = "Alphascale asm9260 Development Kit";
+	compatible = "alphascale,asm9260devkit", "alphascale,asm9260";
+
+	chosen {
+		bootargs = "mem=32M earlyprintk=serial console=ttyS4,115200n8 root=/dev/mtdblock1 init=/linuxrc mtdparts=NAND:4M at 10M(logo)ro,60M at 14M(root)ro";
+	};
+
+};
+&uart4 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/alphascale-asm9260.dtsi b/arch/arm/boot/dts/alphascale-asm9260.dtsi
new file mode 100644
index 0000000..3ea4e03
--- /dev/null
+++ b/arch/arm/boot/dts/alphascale-asm9260.dtsi
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/alphascale,asm9260.h>
+
+/ {
+	interrupt-parent = <&icoll>;
+
+        aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+		serial5 = &uart5;
+		serial6 = &uart6;
+		serial7 = &uart7;
+		serial8 = &uart8;
+		serial9 = &uart9;
+        };
+
+	cpus {
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			compatible = "arm,arm926ej-s";
+			device_type = "cpu";
+			clocks = <&acc CLKID_SYS_CPU>;
+		};
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		osc24m: oscillator {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <24000000>;
+			clock-accuracy = <30000>;
+		};
+
+		i2s0_mclk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <24000000>;
+			clock-accuracy = <30000>;
+		};
+
+		i2s1_mclk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <24000000>;
+			clock-accuracy = <30000>;
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+                ranges;
+
+		acc: clock-controller at 80040000 {
+			compatible = "alphascale,asm9260-clock-controller";
+			#clock-cells = <1>;
+			clocks = <&osc24m>;
+			reg = <0x80040000 0x500>;
+		};
+
+		icoll: interrupt-controller at 80054000 {
+			compatible = "alphascale,asm9260-icall";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			reg = <0x80054000 0x200>;
+		};
+
+		uart0: serial at 80000000 {
+			compatible = "alphascale,asm9260-uart";
+			reg = <0x80000000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART0>, <&acc CLKID_AHB_UART0>;
+			interrupts = <15>;
+			status = "disabled";
+		};
+		uart1: serial at 80004000 {
+			compatible = "alphascale,asm9260-uart";
+			reg = <0x80004000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART1>, <&acc CLKID_AHB_UART1>;
+			interrupts = <16>;
+			status = "disabled";
+		};
+		uart2: serial at 80008000 {
+			compatible = "alphascale,asm9260-uart";
+			reg = <0x80008000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART2>, <&acc CLKID_AHB_UART2>;
+			interrupts = <17>;
+			status = "disabled";
+		};
+		uart3: serial at 8000c000 {
+			compatible = "alphascale,asm9260-uart";
+			reg = <0x8000c000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART3>, <&acc CLKID_AHB_UART3>;
+			interrupts = <18>;
+			status = "disabled";
+		};
+		uart4: serial at 80010000 {
+			compatible = "alphascale,asm9260-uart";
+			reg = <0x80010000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART4>, <&acc CLKID_AHB_UART4>;
+			interrupts = <19>;
+			status = "disabled";
+		};
+		uart5: serial at 80014000 {
+			compatible = "alphascale,asm9260-uart";
+			reg = <0x80014000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART5>, <&acc CLKID_AHB_UART5>;
+			interrupts = <20>;
+			status = "disabled";
+		};
+		uart6: serial at 80018000 {
+			compatible = "alphascale,asm9260-uart";
+			reg = <0x80018000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART6>, <&acc CLKID_AHB_UART6>;
+			interrupts = <21>;
+			status = "disabled";
+		};
+		uart7: serial at 8001c000 {
+			compatible = "alphascale,asm9260-uart";
+			reg = <0x8001c000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART7>, <&acc CLKID_AHB_UART7>;
+			interrupts = <22>;
+			status = "disabled";
+		};
+		uart8: serial at 80020000 {
+			compatible = "alphascale,asm9260-uart";
+			reg = <0x80020000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART8>, <&acc CLKID_AHB_UART8>;
+			interrupts = <23>;
+			status = "disabled";
+		};
+		uart9: serial at 80024000 {
+			compatible = "alphascale,asm9260-uart";
+			reg = <0x80024000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART9>, <&acc CLKID_AHB_UART9>;
+			interrupts = <24>;
+			status = "disabled";
+		};
+
+		timer0: timer at 80088000 {
+			compatible = "alphascale,asm9260-timer";
+			reg = <0x80088000 0x4000>;
+			clocks = <&acc CLKID_AHB_TIMER0>;
+			interrupts = <29>;
+		};
+	};
+};
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v2 5/8] clk: add clk-asm9260 driver
  2014-09-21 18:45 ` Oleksij Rempel
  2014-09-21 18:45   ` [PATCH v2 3/8] add alphascale,asm9260.h binding Oleksij Rempel
  2014-09-21 18:45   ` [PATCH v2 4/8] ARM: dts: add DT for Alphascale ASM9260 SoC Oleksij Rempel
@ 2014-09-21 18:45   ` Oleksij Rempel
  2014-09-21 18:45   ` [PATCH v2 6/8] clocksource: add asm9260_timer driver Oleksij Rempel
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-21 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/clk/Makefile      |   1 +
 drivers/clk/clk-asm9260.c | 350 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 351 insertions(+)
 create mode 100644 drivers/clk/clk-asm9260.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f537a0b..45bbf22 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_ARCH_HI3xxx)		+= hisilicon/
 obj-$(CONFIG_ARCH_HIP04)		+= hisilicon/
 obj-$(CONFIG_ARCH_HIX5HD2)		+= hisilicon/
 obj-$(CONFIG_COMMON_CLK_KEYSTONE)	+= keystone/
+obj-$(CONFIG_MACH_ASM9260)		+= clk-asm9260.o
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)			+= mmp/
 endif
diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c
new file mode 100644
index 0000000..0799cc0
--- /dev/null
+++ b/drivers/clk/clk-asm9260.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2014 Oleksij Rempel <linux@rempel-privat.de>.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <dt-bindings/clock/alphascale,asm9260.h>
+
+#define HW_AHBCLKCTRL0		0x0020
+#define HW_AHBCLKCTRL1		0x0030
+#define HW_SYSPLLCTRL		0x0100
+#define HW_MAINCLKSEL		0x0120
+#define HW_MAINCLKUEN		0x0124
+#define HW_UARTCLKSEL		0x0128
+#define HW_UARTCLKUEN		0x012c
+#define HW_I2S0CLKSEL		0x0130
+#define HW_I2S0CLKUEN		0x0134
+#define HW_I2S1CLKSEL		0x0138
+#define HW_I2S1CLKUEN		0x013c
+#define HW_WDTCLKSEL		0x0160
+#define HW_WDTCLKUEN		0x0164
+#define HW_CLKOUTCLKSEL		0x0170
+#define HW_CLKOUTCLKUEN		0x0174
+#define HW_CPUCLKDIV		0x017c
+#define HW_SYSAHBCLKDIV		0x0180
+#define HW_I2S0MCLKDIV		0x0190
+#define HW_I2S0SCLKDIV		0x0194
+#define HW_I2S1MCLKDIV		0x0188
+#define HW_I2S1SCLKDIV		0x018c
+#define HW_UART0CLKDIV		0x0198
+#define HW_UART1CLKDIV		0x019c
+#define HW_UART2CLKDIV		0x01a0
+#define HW_UART3CLKDIV		0x01a4
+#define HW_UART4CLKDIV		0x01a8
+#define HW_UART5CLKDIV		0x01ac
+#define HW_UART6CLKDIV		0x01b0
+#define HW_UART7CLKDIV		0x01b4
+#define HW_UART8CLKDIV		0x01b8
+#define HW_UART9CLKDIV		0x01bc
+#define HW_SPI0CLKDIV		0x01c0
+#define HW_SPI1CLKDIV		0x01c4
+#define HW_QUADSPICLKDIV	0x01c8
+#define HW_SSP0CLKDIV		0x01d0
+#define HW_NANDCLKDIV		0x01d4
+#define HW_TRACECLKDIV		0x01e0
+#define HW_CAMMCLKDIV		0x01e8
+#define HW_WDTCLKDIV		0x01ec
+#define HW_CLKOUTCLKDIV		0x01f4
+#define HW_MACCLKDIV		0x01f8
+#define HW_LCDCLKDIV		0x01fc
+#define HW_ADCANACLKDIV		0x0200
+
+static struct clk *clks[MAX_CLKS];
+static struct clk_onecell_data clk_data;
+static DEFINE_SPINLOCK(asm9260_clk_lock);
+
+struct asm9260_div_clk {
+	unsigned int idx;
+	const char *name;
+	const char *parent_name;
+	u32 reg;
+};
+
+struct asm9260_gate_data {
+	unsigned int idx;
+	const char *name;
+	const char *parent_name;
+	u32 reg;
+	u8 bit_idx;
+	unsigned long flags;
+};
+
+struct asm9260_mux_clock {
+	u8			mask;
+	u32			*table;
+	const char		*name;
+	const char		**parent_names;
+	u8			num_parents;
+	unsigned long		offset;
+	unsigned long		flags;
+};
+
+static void __iomem *base;
+
+enum {
+	REFCLK, SYSPLL, I2S0_MCLK, I2S1_MCLK, RTC_OSC, USB_PLL,
+};
+
+static const char *clk_names[] = {
+	[REFCLK]	= "oscillator",
+	[SYSPLL]	= "pll",
+	[I2S0_MCLK]	= "i2s0_mclk",
+	[I2S1_MCLK]	= "i2s1_mclk",
+	[RTC_OSC]	= "rtc_osc",
+	[USB_PLL]	= "usb_pll",
+};
+
+static const struct asm9260_div_clk asm9260_div_clks[] __initconst = {
+	{ CLKID_SYS_CPU,	"cpu_div", "main_gate", HW_CPUCLKDIV },
+	{ CLKID_SYS_AHB,	"ahb_div", "cpu_div", HW_SYSAHBCLKDIV },
+
+	/* i2s has two deviders: one for only external mclk and internal
+	 * devider for all clks. */
+	{ CLKID_SYS_I2S0M,	"i2s0m_div", "i2s0_mclk",  HW_I2S0MCLKDIV },
+	{ CLKID_SYS_I2S1M,	"i2s1m_div", "i2s1_mclk",  HW_I2S1MCLKDIV },
+	{ CLKID_SYS_I2S0S,	"i2s0s_div", "i2s0_gate",  HW_I2S0SCLKDIV },
+	{ CLKID_SYS_I2S1S,	"i2s1s_div", "i2s0_gate",  HW_I2S1SCLKDIV },
+
+	{ CLKID_SYS_UART0,	"uart0_div", "uart_gate", HW_UART0CLKDIV },
+	{ CLKID_SYS_UART1,	"uart1_div", "uart_gate", HW_UART1CLKDIV },
+	{ CLKID_SYS_UART2,	"uart2_div", "uart_gate", HW_UART2CLKDIV },
+	{ CLKID_SYS_UART3,	"uart3_div", "uart_gate", HW_UART3CLKDIV },
+	{ CLKID_SYS_UART4,	"uart4_div", "uart_gate", HW_UART4CLKDIV },
+	{ CLKID_SYS_UART5,	"uart5_div", "uart_gate", HW_UART5CLKDIV },
+	{ CLKID_SYS_UART6,	"uart6_div", "uart_gate", HW_UART6CLKDIV },
+	{ CLKID_SYS_UART7,	"uart7_div", "uart_gate", HW_UART7CLKDIV },
+	{ CLKID_SYS_UART8,	"uart8_div", "uart_gate", HW_UART8CLKDIV },
+	{ CLKID_SYS_UART9,	"uart9_div", "uart_gate", HW_UART9CLKDIV },
+};
+
+static const struct asm9260_gate_data asm9260_mux_gates[] __initconst = {
+	{ 0, "main_gate",	"main_mux",	HW_MAINCLKUEN,	0 },
+	{ 0, "uart_gate",	"uart_mux",	HW_UARTCLKUEN,	0 },
+	{ 0, "i2s0_gate",	"i2s0_mux",	HW_I2S0CLKUEN,	0 },
+	{ 0, "i2s1_gate",	"i2s1_mux",	HW_I2S1CLKUEN,	0 },
+	{ 0, "wdt_gate",	"wdt_mux",	HW_WDTCLKUEN,	0 },
+	{ 0, "clkout_gate",	"clkout_mux",	HW_CLKOUTCLKUEN, 0 },
+};
+static const struct asm9260_gate_data asm9260_ahb_gates[] __initconst = {
+	/* ahb gates */
+	{ CLKID_AHB_ROM,	"rom",		"ahb_div",
+		HW_AHBCLKCTRL0,	1, CLK_IGNORE_UNUSED},
+	{ CLKID_AHB_RAM,	"ram",		"ahb_div",
+		HW_AHBCLKCTRL0,	2, CLK_IGNORE_UNUSED},
+	{ CLKID_AHB_GPIO,	"gpio",		"ahb_div",
+		HW_AHBCLKCTRL0,	4 },
+	{ CLKID_AHB_MAC,	"mac",		"ahb_div",
+		HW_AHBCLKCTRL0,	5 },
+	{ CLKID_AHB_EMI,	"emi",		"ahb_div",
+		HW_AHBCLKCTRL0,	6, CLK_IGNORE_UNUSED},
+	{ CLKID_AHB_USB0,	"usb0",		"ahb_div",
+		HW_AHBCLKCTRL0,	7 },
+	{ CLKID_AHB_USB1,	"usb1",		"ahb_div",
+		HW_AHBCLKCTRL0,	8 },
+	{ CLKID_AHB_DMA0,	"dma0",		"ahb_div",
+		HW_AHBCLKCTRL0,	9 },
+	{ CLKID_AHB_DMA1,	"dma1",		"ahb_div",
+		HW_AHBCLKCTRL0,	10 },
+	{ CLKID_AHB_UART0,	"uart0",	"ahb_div",
+		HW_AHBCLKCTRL0,	11 },
+	{ CLKID_AHB_UART1,	"uart1",	"ahb_div",
+		HW_AHBCLKCTRL0,	12 },
+	{ CLKID_AHB_UART2,	"uart2",	"ahb_div",
+		HW_AHBCLKCTRL0,	13 },
+	{ CLKID_AHB_UART3,	"uart3",	"ahb_div",
+		HW_AHBCLKCTRL0,	14 },
+	{ CLKID_AHB_UART4,	"uart4",	"ahb_div",
+		HW_AHBCLKCTRL0,	15 },
+	{ CLKID_AHB_UART5,	"uart5",	"ahb_div",
+		HW_AHBCLKCTRL0,	16 },
+	{ CLKID_AHB_UART6,	"uart6",	"ahb_div",
+		HW_AHBCLKCTRL0,	17 },
+	{ CLKID_AHB_UART7,	"uart7",	"ahb_div",
+		HW_AHBCLKCTRL0,	18 },
+	{ CLKID_AHB_UART8,	"uart8",	"ahb_div",
+		HW_AHBCLKCTRL0,	19 },
+	{ CLKID_AHB_UART9,	"uart9",	"ahb_div",
+		HW_AHBCLKCTRL0,	20 },
+	{ CLKID_AHB_I2S0,	"i2s0",		"ahb_div",
+		HW_AHBCLKCTRL0,	21 },
+	{ CLKID_AHB_I2C0,	"i2c0",		"ahb_div",
+		HW_AHBCLKCTRL0,	22 },
+	{ CLKID_AHB_I2C1,	"i2c1",		"ahb_div",
+		HW_AHBCLKCTRL0,	23 },
+	{ CLKID_AHB_SSP0,	"ssp0",		"ahb_div",
+		HW_AHBCLKCTRL0,	24 },
+	{ CLKID_AHB_IOCONFIG,	"ioconf",	"ahb_div",
+		HW_AHBCLKCTRL0,	25 },
+	{ CLKID_AHB_WDT,	"wdt",		"ahb_div",
+		HW_AHBCLKCTRL0,	26 },
+	{ CLKID_AHB_CAN0,	"can0",		"ahb_div",
+		HW_AHBCLKCTRL0,	27 },
+	{ CLKID_AHB_CAN1,	"can1",		"ahb_div",
+		HW_AHBCLKCTRL0,	28 },
+	{ CLKID_AHB_MPWM,	"mpwm",		"ahb_div",
+		HW_AHBCLKCTRL0,	29 },
+	{ CLKID_AHB_SPI0,	"spi0",		"ahb_div",
+		HW_AHBCLKCTRL0,	30 },
+	{ CLKID_AHB_SPI1,	"spi1",		"ahb_div",
+		HW_AHBCLKCTRL0,	31 },
+
+	{ CLKID_AHB_QEI,	"qei",		"ahb_div",
+		HW_AHBCLKCTRL1,	0 },
+	{ CLKID_AHB_QUADSPI0,	"quadspi0",	"ahb_div",
+		HW_AHBCLKCTRL1,	1 },
+	{ CLKID_AHB_CAMIF,	"capmif",	"ahb_div",
+		HW_AHBCLKCTRL1,	2 },
+	{ CLKID_AHB_LCDIF,	"lcdif",	"ahb_div",
+		HW_AHBCLKCTRL1,	3 },
+	{ CLKID_AHB_TIMER0,	"timer0",	"ahb_div",
+		HW_AHBCLKCTRL1,	4 },
+	{ CLKID_AHB_TIMER1,	"timer1",	"ahb_div",
+		HW_AHBCLKCTRL1,	5 },
+	{ CLKID_AHB_TIMER2,	"timer2",	"ahb_div",
+		HW_AHBCLKCTRL1,	6 },
+	{ CLKID_AHB_TIMER3,	"timer3",	"ahb_div",
+		HW_AHBCLKCTRL1,	7 },
+	{ CLKID_AHB_IRQ,	"irq",		"ahb_div",
+		HW_AHBCLKCTRL1,	8, CLK_IGNORE_UNUSED},
+	{ CLKID_AHB_RTC,	"rtc",		"ahb_div",
+		HW_AHBCLKCTRL1,	9 },
+	{ CLKID_AHB_NAND,	"nand",		"ahb_div",
+		HW_AHBCLKCTRL1,	10 },
+	{ CLKID_AHB_ADC0,	"adc0",		"ahb_div",
+		HW_AHBCLKCTRL1,	11 },
+	{ CLKID_AHB_LED,	"led",		"ahb_div",
+		HW_AHBCLKCTRL1,	12 },
+	{ CLKID_AHB_DAC0,	"dac0",		"ahb_div",
+		HW_AHBCLKCTRL1,	13 },
+	{ CLKID_AHB_LCD,	"lcd",		"ahb_div",
+		HW_AHBCLKCTRL1,	14 },
+	{ CLKID_AHB_I2S1,	"i2s1",		"ahb_div",
+		HW_AHBCLKCTRL1,	15 },
+	{ CLKID_AHB_MAC1,	"mac1",		"ahb_div",
+		HW_AHBCLKCTRL1,	16 },
+};
+
+static const char __initdata *main_mux_p[] = {"oscillator", "pll"};
+static const char __initdata *i2s0_mux_p[] = {"oscillator", "pll", "i2s0m_div"};
+static const char __initdata *i2s1_mux_p[] = {"oscillator", "pll", "i2s1m_div"};
+static const char __initdata *clkout_mux_p[] = {"oscillator", "pll", "rtc"};
+static u32 three_mux_table[] = {0, 1, 3};
+
+static struct asm9260_mux_clock asm9260_mux_clks[] __initdata = {
+	{ 1, three_mux_table, "main_mux",	main_mux_p,
+		ARRAY_SIZE(main_mux_p), HW_MAINCLKSEL, },
+	{ 1, three_mux_table, "uart_mux",	main_mux_p,
+		ARRAY_SIZE(main_mux_p), HW_UARTCLKSEL, },
+	{ 1, three_mux_table, "wdt_mux",	main_mux_p,
+		ARRAY_SIZE(main_mux_p), HW_WDTCLKSEL, },
+	{ 3, three_mux_table, "i2s0_mux",	i2s0_mux_p,
+		ARRAY_SIZE(i2s0_mux_p), HW_I2S0CLKSEL, },
+	{ 3, three_mux_table, "i2s1_mux",	i2s1_mux_p,
+		ARRAY_SIZE(i2s1_mux_p), HW_I2S1CLKSEL, },
+	{ 3, three_mux_table, "clkout_mux",	clkout_mux_p,
+		ARRAY_SIZE(clkout_mux_p), HW_CLKOUTCLKSEL, },
+};
+
+static void __init asm9260_acc_init(struct device_node *np)
+{
+	struct clk *clk;
+	struct resource res;
+	u32 rate;
+	int n;
+	u32 accuracy = 0;
+
+	of_address_to_resource(np, 0, &res);
+	if (!request_mem_region(res.start, resource_size(&res), "asm9260-clk"))
+		panic("%s: unable to request mem region", np->name);
+
+	base = ioremap_nocache(res.start, resource_size(&res));
+	if (!base)
+		panic("%s: unable to map resource", np->name);
+
+
+	/* register pll */
+	rate = (ioread32(base + HW_SYSPLLCTRL) & 0xffff) * 1000000;
+
+	clk_names[REFCLK] = of_clk_get_parent_name(np, 0);
+	accuracy = clk_get_accuracy(__clk_lookup(clk_names[REFCLK]));
+	clk = clk_register_fixed_rate_with_accuracy(NULL, clk_names[SYSPLL],
+			clk_names[REFCLK], 0, rate, accuracy);
+
+	if (IS_ERR(clk))
+		panic("%s: can't register REFCLK. Check DT!", np->name);
+
+	for (n = 0; n < ARRAY_SIZE(asm9260_mux_clks); n++) {
+		const struct asm9260_mux_clock *mc = &asm9260_mux_clks[n];
+
+		mc->parent_names[0] = clk_names[REFCLK];
+		clk = clk_register_mux_table(NULL, mc->name, mc->parent_names,
+				mc->num_parents, mc->flags, base + mc->offset,
+				0, mc->mask, 0, mc->table, &asm9260_clk_lock);
+	}
+
+	/* clock mux gate cells */
+	for (n = 0; n < ARRAY_SIZE(asm9260_mux_gates); n++) {
+		const struct asm9260_gate_data *gd = &asm9260_mux_gates[n];
+
+		clk = clk_register_gate(NULL, gd->name,
+			gd->parent_name, gd->flags | CLK_SET_RATE_PARENT,
+			base + gd->reg, gd->bit_idx, 0, &asm9260_clk_lock);
+	}
+
+	/* clock div cells */
+	for (n = 0; n < ARRAY_SIZE(asm9260_div_clks); n++) {
+		const struct asm9260_div_clk *dc = &asm9260_div_clks[n];
+
+		clks[dc->idx] = clk_register_divider(NULL, dc->name,
+				dc->parent_name, CLK_SET_RATE_PARENT,
+				base + dc->reg, 0, 8, CLK_DIVIDER_ONE_BASED,
+				&asm9260_clk_lock);
+	}
+
+	/* clock ahb gate cells */
+	for (n = 0; n < ARRAY_SIZE(asm9260_ahb_gates); n++) {
+		const struct asm9260_gate_data *gd = &asm9260_ahb_gates[n];
+
+		clks[gd->idx] = clk_register_gate(NULL, gd->name,
+				gd->parent_name, gd->flags, base + gd->reg,
+				gd->bit_idx, 0, &asm9260_clk_lock);
+	}
+
+	/* check for errors on leaf clocks */
+	for (n = 0; n < MAX_CLKS; n++) {
+		if (!IS_ERR(clks[n]))
+			continue;
+
+		pr_err("%s: Unable to register leaf clock %d\n",
+				np->full_name, n);
+		goto fail;
+	}
+
+	/* register clk-provider */
+	clk_data.clks = clks;
+	clk_data.clk_num = MAX_CLKS;
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+fail:
+	iounmap(base);
+}
+CLK_OF_DECLARE(asm9260_acc, "alphascale,asm9260-clock-controller",
+		asm9260_acc_init);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v2 6/8] clocksource: add asm9260_timer driver
  2014-09-21 18:45 ` Oleksij Rempel
                     ` (2 preceding siblings ...)
  2014-09-21 18:45   ` [PATCH v2 5/8] clk: add clk-asm9260 driver Oleksij Rempel
@ 2014-09-21 18:45   ` Oleksij Rempel
  2014-09-21 18:45   ` [PATCH v2 7/8] irqchip: add irq-asm9260 driver Oleksij Rempel
  2014-09-21 18:45   ` [PATCH v2 8/8] tty/serial: add asm9260-serial driver Oleksij Rempel
  5 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-21 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/clocksource/Makefile        |   1 +
 drivers/clocksource/asm9260_timer.c | 244 ++++++++++++++++++++++++++++++++++++
 2 files changed, 245 insertions(+)
 create mode 100644 drivers/clocksource/asm9260_timer.c

diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 7fd9fd1..19211c5 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -44,3 +44,4 @@ obj-$(CONFIG_CLKSRC_METAG_GENERIC)	+= metag_generic.o
 obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST)	+= dummy_timer.o
 obj-$(CONFIG_ARCH_KEYSTONE)		+= timer-keystone.o
 obj-$(CONFIG_CLKSRC_VERSATILE)		+= versatile.o
+obj-$(CONFIG_MACH_ASM9260)		+= asm9260_timer.o
diff --git a/drivers/clocksource/asm9260_timer.c b/drivers/clocksource/asm9260_timer.c
new file mode 100644
index 0000000..bcc8204
--- /dev/null
+++ b/drivers/clocksource/asm9260_timer.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/clk.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/bitops.h>
+
+
+/*
+ * this device provide 4 offsets for each register:
+ * 0x0 - plain read write mode
+ * 0x4 - set mode, OR logic.
+ * 0x8 - clr mode, XOR logic.
+ * 0xc - togle mode.
+ */
+#define SET_REG 4
+#define CLR_REG 8
+
+#define HW_IR           0x0000 /* RW. Interrupt */
+#define BM_IR_CR0	BIT(4)
+#define BM_IR_MR3	BIT(3)
+#define BM_IR_MR2	BIT(2)
+#define BM_IR_MR1	BIT(1)
+#define BM_IR_MR0	BIT(0)
+
+#define HW_TCR		0x0010 /* RW. Timer controller */
+/* BM_C*_RST
+ * Timer Counter and the Prescale Counter are synchronously reset on the
+ * next positive edge of PCLK. The counters remain reset until TCR[1] is
+ * returned to zero. */
+#define BM_C3_RST	BIT(7)
+#define BM_C2_RST	BIT(6)
+#define BM_C1_RST	BIT(5)
+#define BM_C0_RST	BIT(4)
+/* BM_C*_EN
+ * 1 - Timer Counter and Prescale Counter are enabled for counting
+ * 0 - counters are disabled */
+#define BM_C3_EN	BIT(3)
+#define BM_C2_EN	BIT(2)
+#define BM_C1_EN	BIT(1)
+#define BM_C0_EN	BIT(0)
+
+#define HW_DIR		0x0020 /* RW. Direction? */
+/* 00 - count up
+ * 01 - count down
+ * 10 - ?? 2^n/2 */
+#define BM_DIR0_SHIFT	0
+#define BM_DIR1_SHIFT	4
+#define BM_DIR2_SHIFT	8
+#define BM_DIR3_SHIFT	12
+
+#define HW_TC0		0x0030 /* RO. Timer counter 0 */
+/* HW_TC*. Timer counter owerflow (0xffff.ffff to 0x0000.0000) do not generate
+ * interrupt. This registers can be used to detect overflow */
+#define HW_TC1          0x0040
+#define HW_TC2		0x0050
+#define HW_TC3		0x0060
+
+#define HW_PR		0x0070 /* RW. prescaler */
+#define HW_PC		0x0080 /* RO. Prescaler counter */
+#define HW_MCR		0x0090 /* RW. Match control */
+/* enable interrupt on match */
+#define BM_MCR_INT_EN(n)	(1 << (n * 3 + 0))
+/* enable TC reset on match */
+#define BM_MCR_RES_EN(n)	(1 << (n * 3 + 1))
+/* enable stop TC on match */
+#define BM_MCR_STOP_EN(n)	(1 << (n * 3 + 2))
+
+#define HW_MR0		0x00a0 /* RW. Match reg */
+#define HW_MR1		0x00b0
+#define HW_MR2		0x00C0
+#define HW_MR3		0x00D0
+#define HW_CCR		0x00E0 /* RW. Capture control */
+#define HW_CR0		0x00F0 /* RO. Capture reg */
+#define HW_CR1		0x0100
+#define HW_CR2		0x0110
+#define HW_CR3		0x0120
+#define HW_EMR		0x0130 /* RW. External Match */
+#define HW_PWMTH0	0x0140 /* RW. PWM width */
+#define HW_PWMTH1	0x0150
+#define HW_PWMTH2	0x0160
+#define HW_PWMTH3	0x0170
+#define HW_CTCR		0x0180 /* Counter control */
+#define HW_PWMC		0x0190 /* PWM control */
+
+static void __iomem *base;
+static unsigned long ticks_per_jiffy;
+
+static int asm9260_timer_set_next_event(unsigned long delta,
+					 struct clock_event_device *dev)
+{
+	/* configure match count for TC0 */
+	writel_relaxed(delta, base + HW_MR0);
+	/* enable TC0 */
+	writel_relaxed(BM_C0_EN, base + HW_TCR + SET_REG);
+	return 0;
+}
+
+static void asm9260_timer_set_mode(enum clock_event_mode mode,
+				    struct clock_event_device *evt)
+{
+	/* stop timer0 */
+	writel_relaxed(BM_C0_EN, base + HW_TCR + CLR_REG);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		/* disable reset and stop on match */
+		writel_relaxed(BM_MCR_RES_EN(0) | BM_MCR_STOP_EN(0),
+				base + HW_MCR + CLR_REG);
+		/* configure match count for TC0 */
+		writel_relaxed(ticks_per_jiffy, base + HW_MR0);
+		/* enable TC0 */
+		writel_relaxed(BM_C0_EN, base + HW_TCR + SET_REG);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* enable reset and stop on match */
+		writel_relaxed(BM_MCR_RES_EN(0) | BM_MCR_STOP_EN(0),
+				base + HW_MCR + SET_REG);
+		break;
+	default:
+		break;
+	}
+}
+
+static struct clock_event_device asm9260_clockevent_device = {
+	.name		= "asm9260-clockevent-dev",
+	.rating		= 200,
+	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_next_event	= asm9260_timer_set_next_event,
+	.set_mode	= asm9260_timer_set_mode,
+};
+
+static irqreturn_t asm9260_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &asm9260_clockevent_device;
+
+	evt->event_handler(evt);
+
+	writel_relaxed(BM_IR_MR0, base + HW_IR);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction asm9260_timer_irq = {
+	.name		= "asm9260-clockevent-dev",
+	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= asm9260_timer_interrupt,
+};
+
+/*
+ * ---------------------------------------------------------------------------
+ * Timer initialization
+ * ---------------------------------------------------------------------------
+ */
+
+static void __init asm9260_clockevent_init(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk);
+
+	ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ);
+	asm9260_clockevent_device.cpumask = cpumask_of(0);
+	clockevents_config_and_register(&asm9260_clockevent_device,
+					rate, 0x2c00, 0xfffffffe);
+}
+
+static void __init asm9260_clocksource_init(struct clk *clk)
+{
+	unsigned long hz = clk_get_rate(clk);
+
+	clocksource_mmio_init(base + HW_TC1,
+			"asm9260-clocksource", hz,
+			200, 32, clocksource_mmio_readl_up);
+
+	/* Seems like we can't use counter without match register even if
+	 * actions for MR are disabled. */
+	writel_relaxed(0xffffffff, base + HW_MR1);
+	/* enable TC1 */
+	writel_relaxed(BM_C1_EN, base + HW_TCR + SET_REG);
+}
+
+static void __init asm9260_timer_init(struct device_node *np)
+{
+	int irq;
+	struct clk *clk;
+	struct resource res;
+	int ret;
+
+	of_address_to_resource(np, 0, &res);
+	if (!request_mem_region(res.start, resource_size(&res),
+				"asm9260-timer"))
+		panic("%s: unable to request mem region", np->name);
+
+	base = ioremap_nocache(res.start, resource_size(&res));
+	if (!base)
+		panic("%s: unable to map resource", np->name);
+
+	clk = of_clk_get(np, 0);
+
+	ret = clk_prepare_enable(clk);
+	if (ret)
+		panic("Failed to enable clk!\n");
+
+	irq = irq_of_parse_and_map(np, 0);
+	setup_irq(irq, &asm9260_timer_irq);
+
+	/* set all timers for count-up */
+	writel_relaxed(0, base + HW_DIR);
+	/* disable divider */
+	writel_relaxed(0, base + HW_PR);
+	/* make sure all timers use every rising PCLK edge. */
+	writel_relaxed(0, base + HW_CTCR);
+	/* enable interrupt for TC0 and clean setting for all other lines */
+	writel_relaxed(BM_MCR_INT_EN(0) , base + HW_MCR);
+
+	asm9260_clocksource_init(clk);
+	asm9260_clockevent_init(clk);
+}
+CLOCKSOURCE_OF_DECLARE(asm9260_timer, "alphascale,asm9260-timer",
+		asm9260_timer_init);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v2 7/8] irqchip: add irq-asm9260 driver
  2014-09-21 18:45 ` Oleksij Rempel
                     ` (3 preceding siblings ...)
  2014-09-21 18:45   ` [PATCH v2 6/8] clocksource: add asm9260_timer driver Oleksij Rempel
@ 2014-09-21 18:45   ` Oleksij Rempel
  2014-09-22 15:22     ` Arnd Bergmann
  2014-09-21 18:45   ` [PATCH v2 8/8] tty/serial: add asm9260-serial driver Oleksij Rempel
  5 siblings, 1 reply; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-21 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/irqchip/Makefile      |   1 +
 drivers/irqchip/irq-asm9260.c | 257 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 258 insertions(+)
 create mode 100644 drivers/irqchip/irq-asm9260.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 73052ba..538fb83 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -34,3 +34,4 @@ obj-$(CONFIG_XTENSA)			+= irq-xtensa-pic.o
 obj-$(CONFIG_XTENSA_MX)			+= irq-xtensa-mx.o
 obj-$(CONFIG_IRQ_CROSSBAR)		+= irq-crossbar.o
 obj-$(CONFIG_BRCMSTB_L2_IRQ)		+= irq-brcmstb-l2.o
+obj-$(CONFIG_MACH_ASM9260)		+= irq-asm9260.o
diff --git a/drivers/irqchip/irq-asm9260.c b/drivers/irqchip/irq-asm9260.c
new file mode 100644
index 0000000..b90ea7a
--- /dev/null
+++ b/drivers/irqchip/irq-asm9260.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <asm/exception.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+
+#include "irqchip.h"
+
+/*
+ * this device provide 4 offsets for each register:
+ * 0x0 - plain read write mode
+ * 0x4 - set mode, OR logic.
+ * 0x8 - clr mode, XOR logic.
+ * 0xc - togle mode.
+ */
+#define SET_REG 4
+#define CLR_REG 8
+
+#define HW_ICOLL_VECTOR				0x0000
+/*
+ * bits 31:2
+ * This register presents the vector address for the interrupt currently
+ * active on the CPU IRQ input. Writing to this register notifies the
+ * interrupt collector that the interrupt service routine for the current
+ * interrupt has been entered.
+ * The exception trap should have a LDPC instruction from this address:
+ * LDPC HW_ICOLL_VECTOR_ADDR; IRQ exception at 0xffff0018
+ */
+
+/*
+ * The Interrupt Collector Level Acknowledge Register is used by software to
+ * indicate the completion of an interrupt on a specific level.
+ * This register is written at the very end of an interrupt service routine. If
+ * nesting is used then the CPU irq must be turned on before writing to this
+ * register to avoid a race condition in the CPU interrupt hardware.
+ */
+#define HW_ICOLL_LEVELACK			0x0010
+#define BM_LEVELn(nr)				BIT(nr)
+
+#define HW_ICOLL_CTRL				0x0020
+/* BM_CTRL_SFTRST and BM_CTRL_CLKGATE are not available on asm9260. */
+#define BM_CTRL_SFTRST				BIT(31)
+#define BM_CTRL_CLKGATE				BIT(30)
+/* disable interrupt level nesting */
+#define BM_CTRL_NO_NESTING			BIT(19)
+/*
+ * Set this bit to one enable the RISC32-style read side effect associated with
+ * the vector address register. In this mode, interrupt in-service is signaled
+ * by the read of the HW_ICOLL_VECTOR register to acquire the interrupt vector
+ * address. Set this bit to zero for normal operation, in which the ISR signals
+ * in-service explicitly by means of a write to the HW_ICOLL_VECTOR register.
+ * 0 - Must Write to Vector register to go in-service.
+ * 1 - Go in-service as a read side effect
+ */
+#define BM_CTRL_ARM_RSE_MODE			BIT(18)
+#define BM_CTRL_IRQ_ENABLE			BIT(16)
+
+#define HW_ICOLL_STAT_OFFSET			0x0030
+/*
+ * bits 5:0
+ * Vector number of current interrupt. Multiply by 4 and add to vector base
+ * address to obtain the value in HW_ICOLL_VECTOR.
+ */
+
+/*
+ * RAW0 and RAW1 provides a read-only view of the raw interrupt request lines
+ * coming from various parts of the chip. Its purpose is to improve diagnostic
+ * observability.
+ */
+#define HW_ICOLL_RAW0				0x0040
+#define HW_ICOLL_RAW1				0x0050
+
+#define	HW_ICOLL_INTERRUPT0			0x0060
+#define	HW_ICOLL_INTERRUPTn(n)			(0x0060 + ((n) >> 2) * 0x10)
+#define	HW_ICOLL_INTERRUPTn_SET(n)		(HW_ICOLL_INTERRUPTn(n) \
+		+ SET_REG)
+#define	HW_ICOLL_INTERRUPTn_CLR(n)		(HW_ICOLL_INTERRUPTn(n) \
+		+ CLR_REG)
+/*
+ * WARNING: Modifying the priority of an enabled interrupt may result in
+ * undefined behavior.
+ */
+#define BM_INT_PRIORITY_MASK			0x3
+#define BM_INT_ENABLE				BIT(2)
+#define BM_INT_SOFTIRQ				BIT(3)
+
+#define BM_ICOLL_INTERRUPTn_SHIFT(n)		(((n) & 0x3) << 3)
+#define BM_ICOLL_INTERRUPTn_ENABLE(n)		(1 << (2 + \
+			BM_ICOLL_INTERRUPTn_SHIFT(n)))
+
+#define HW_ICOLL_VBASE				0x0160
+/*
+ * bits 31:2
+ * This bitfield holds the upper 30 bits of the base address of the vector
+ * table.
+ */
+
+#define HW_ICOLL_CLEAR0				0x01d0
+#define	HW_ICOLL_CLEAR1				0x01e0
+#define HW_ICOLL_CLEARn(n)			(0x01d0 + ((n >> 5) * 0x10) \
+							+ SET_REG)
+#define BM_CLEAR_BIT(n)				BIT(n & 0x1f)
+
+#define HW_ICOLL_UNDEF_VECTOR			0x01f0
+/* Scratchpad */
+
+#define ICOLL_NUM_IRQS		64
+
+static void __iomem *icoll_base;
+static struct irq_domain *icoll_domain;
+static int use_cached_level = 1;
+static u8 level_cache[ICOLL_NUM_IRQS];
+static DEFINE_MUTEX(icoll_lock);
+
+static unsigned int irq_get_level(struct irq_data *d)
+{
+	unsigned int tmp;
+
+	if (use_cached_level)
+		return level_cache[d->hwirq];
+
+	tmp = readl_relaxed(icoll_base + HW_ICOLL_INTERRUPTn_SET(d->hwirq));
+	return (tmp >> BM_ICOLL_INTERRUPTn_SHIFT(d->hwirq)) & 0x3;
+}
+
+static void irq_set_level(int hwirq, int level)
+{
+	if (unlikely(level < 0 || level > 3)) {
+		pr_err("%s Wrong level (%i) for irq (%i)!", __func__, level,
+				hwirq);
+		return;
+	}
+	if (use_cached_level)
+		level_cache[hwirq] = level;
+
+	writel_relaxed(level << BM_ICOLL_INTERRUPTn_SHIFT(hwirq),
+			icoll_base + HW_ICOLL_INTERRUPTn(hwirq));
+}
+
+static void icoll_ack_irq(struct irq_data *d)
+{
+	readl_relaxed(icoll_base + HW_ICOLL_VECTOR);
+}
+
+static void icoll_mask_irq(struct irq_data *d)
+{
+	writel_relaxed(BM_ICOLL_INTERRUPTn_ENABLE(d->hwirq),
+			icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->hwirq));
+}
+
+static void icoll_unmask_irq(struct irq_data *d)
+{
+	u32 level = irq_get_level(d);
+
+	mutex_lock(&icoll_lock);
+	writel_relaxed(BM_CLEAR_BIT(d->hwirq),
+			icoll_base + HW_ICOLL_CLEARn(d->hwirq));
+
+	writel_relaxed(BM_LEVELn(level), icoll_base + HW_ICOLL_LEVELACK);
+
+	writel_relaxed(BM_ICOLL_INTERRUPTn_ENABLE(d->hwirq),
+			icoll_base + HW_ICOLL_INTERRUPTn_SET(d->hwirq));
+	mutex_unlock(&icoll_lock);
+}
+
+static struct irq_chip asm9260_icoll_chip = {
+	.irq_ack = icoll_ack_irq,
+	.irq_mask = icoll_mask_irq,
+	.irq_unmask = icoll_unmask_irq,
+};
+
+asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
+{
+	u32 hwirq;
+
+	hwirq = readl_relaxed(icoll_base + HW_ICOLL_STAT_OFFSET);
+
+	handle_domain_irq(icoll_domain, hwirq, regs);
+}
+
+static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
+				irq_hw_number_t hw)
+{
+	irq_set_chip_and_handler(virq, &asm9260_icoll_chip, handle_level_irq);
+	set_irq_flags(virq, IRQF_VALID);
+
+	return 0;
+}
+
+static struct irq_domain_ops icoll_irq_domain_ops = {
+	.map = icoll_irq_domain_map,
+	.xlate = irq_domain_xlate_onecell,
+};
+
+static int __init icoll_of_init(struct device_node *np,
+			  struct device_node *interrupt_parent)
+{
+	struct resource res;
+	int i;
+
+	if (of_address_to_resource(np, 0, &res))
+		panic("%s: unable to get resource", np->full_name);
+
+	if (!request_mem_region(res.start, resource_size(&res), np->name))
+		panic("%s: unable to request mem region", np->full_name);
+
+	icoll_base = ioremap_nocache(res.start, resource_size(&res));
+	if (!icoll_base)
+		panic("%s: unable to map resource", np->full_name);
+
+	/* enable IRQ controller */
+	writel_relaxed(BM_CTRL_ARM_RSE_MODE | BM_CTRL_IRQ_ENABLE,
+			icoll_base + HW_ICOLL_CTRL);
+
+	/*
+	 * This ICOLL has no reset option. So, set all priorities
+	 * manually to 0.
+	 */
+	for (i = 0; i < 16 * 0x10; i += 0x10)
+		writel(0, icoll_base + HW_ICOLL_INTERRUPT0 + i);
+
+	icoll_domain = irq_domain_add_linear(np, ICOLL_NUM_IRQS,
+					     &icoll_irq_domain_ops, NULL);
+	if (!icoll_domain)
+		panic("%s: unable add irq domain", np->full_name);
+
+	irq_set_default_host(icoll_domain);
+
+	set_handle_irq(icoll_handle_irq);
+
+	return icoll_domain ? 0 : -ENODEV;
+}
+IRQCHIP_DECLARE(asm9260, "alphascale,asm9260-icall", icoll_of_init);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v2 8/8] tty/serial: add asm9260-serial driver
  2014-09-21 18:45 ` Oleksij Rempel
                     ` (4 preceding siblings ...)
  2014-09-21 18:45   ` [PATCH v2 7/8] irqchip: add irq-asm9260 driver Oleksij Rempel
@ 2014-09-21 18:45   ` Oleksij Rempel
  2014-09-22 15:26     ` Arnd Bergmann
  5 siblings, 1 reply; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-21 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/tty/serial/Kconfig          |   17 +
 drivers/tty/serial/Makefile         |    1 +
 drivers/tty/serial/asm9260_serial.c | 1485 +++++++++++++++++++++++++++++++++++
 include/uapi/linux/serial_core.h    |    2 +
 4 files changed, 1505 insertions(+)
 create mode 100644 drivers/tty/serial/asm9260_serial.c

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 26cec64..9d80268 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1552,6 +1552,23 @@ config SERIAL_MEN_Z135
 	  This driver can also be build as a module. If so, the module will be called
 	  men_z135_uart.ko
 
+config SERIAL_ASM9260
+	tristate "ASM9260 controller serial support"
+	depends on MACH_ASM9260
+	select SERIAL_CORE
+	help
+		If you have an asm9260 based Base IO card
+		and wish to use the serial ports on this card, say Y.
+		Otherwise, say N.
+
+config SERIAL_ASM9260_CONSOLE
+	bool "ASM9260 console support"
+	depends on SERIAL_ASM9260
+	select SERIAL_CORE_CONSOLE
+	help
+		If you want to support serial console on borad asm9260
+		say Y. Otherwise, say N.
+
 endmenu
 
 config SERIAL_MCTRL_GPIO
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 0080cc3..80940d4 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -95,3 +95,4 @@ obj-$(CONFIG_SERIAL_MEN_Z135)	+= men_z135_uart.o
 
 # GPIOLIB helpers for modem control lines
 obj-$(CONFIG_SERIAL_MCTRL_GPIO)	+= serial_mctrl_gpio.o
+obj-$(CONFIG_SERIAL_ASM9260) += asm9260_serial.o
diff --git a/drivers/tty/serial/asm9260_serial.c b/drivers/tty/serial/asm9260_serial.c
new file mode 100644
index 0000000..dc95478
--- /dev/null
+++ b/drivers/tty/serial/asm9260_serial.c
@@ -0,0 +1,1485 @@
+/*
+ * asm9260_serial.c Alphascale ASM9260 UART driver
+ *
+ * Mostly rewritten with irq_thread, clk and DT suppor:
+ * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ *		 2014 Cleaned up by Du Huanpeng <u74147@gmail.com>
+ *
+ * Copyright (C) 2013, Alphascale Tech. Co., Ltd.
+ * Initial code has been inspired/copied from atmel_serial.c (kernel v2.4) and
+ * adopted for asm9260 (kernel v2.4) by Chen Dongdong.
+ *
+ * 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.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * Note: This driver was tested and written for Alphascale ASM9260T. Since
+ * documentation for this SoC currently available only in Chinese, parts of it
+ * was recovered from similar devices. For example Alphascale ASAP1826 ? which
+ * has identical offsets, but no support for RS485 and autoboud. And NXP
+ * Semiconductors LPC13xx (UM10375) ? with identical registers and mostly
+ * identical functionality but different offsets.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/serial_core.h>
+#include <linux/tty_flip.h>
+
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+
+#define SERIAL_ASM9260_MAJOR		204
+#define MINOR_START			64
+#define ASM9260_DEVICENAME		"ttyS"
+#define DRIVER_NAME			"asm9260_uart"
+#define ASM9260_UART_FIFOSIZE		16
+#define ASM9260_BUS_RATE		100000000
+#define ASM9260_MAX_UART		10
+
+#define UART_BAUD_DIVINT_MASK		((unsigned int)0x003FFFC0)
+#define UART_BAUD_DIVFRAC_MASK		((unsigned int)0x0000003F)
+#define	UART_BAUD_DIV_MAX		0x3FFFFF
+
+/*
+ * this device provide 4 offsets for each register:
+ * 0x0 - plain read write mode
+ * 0x4 - set mode, OR logic.
+ * 0x8 - clr mode, XOR logic.
+ * 0xc - togle mode.
+ */
+#define SET_REG				0x4
+#define CLR_REG				0x8
+
+/* RX ctrl register */
+#define HW_CTRL0			0x0000
+/* RW. Set to zero for normal operation. */
+#define BM_CTRL0_SFTRST			BIT(31)
+/*
+ * RW. 0 for normal operation; 1 gates all of the block level clocks off for
+ * miniminizing AC energy consumption.
+ */
+#define BM_CTRL0_CLKGATE		BIT(30)
+/*
+ * RW. Tell the UART to execute the RX DMA Command. The
+ * UART will clear this bit at the end of receive execution.
+ */
+#define BM_CTRL0_RXDMA_RUN		BIT(28)
+/* RW. 0 use FIFO for status register; 1 use DMA */
+#define BM_CTRL0_RXTO_SOURCE_STATUS	BIT(25)
+/*
+ * RW. RX TIMEOUT Enable. Valid for FIFO and DMA.
+ * Warning: If this bit is set to 0, the RX timeout will not affect receive DMA
+ * operation. If this bit is set to 1, a receive timeout will cause the receive
+ * DMA logic to terminate by filling the remaining DMA bytes with garbage data.
+ */
+#define BM_CTRL0_RXTO_ENABLE		BIT(24)
+/*
+ * RW. Receive Timeout Counter Value: number of 8-bit-time to wait before
+ * asserting timeout on the RX input. If the RXFIFO is not empty and the RX
+ * input is idle, then the watchdog counter will decrement each bit-time. Note
+ * 7-bit-time is added to the programmed value, so a value of zero will set
+ * the counter to 7-bit-time, a value of 0x1 gives 15-bit-time and so on. Also
+ * note that the counter is reloaded at the end of each frame, so if the frame
+ * is 10 bits long and the timeout counter value is zero, then timeout will
+ * occur (when FIFO is not empty) even if the RX input is not idle. The default
+ * value is 0x3 (31 bit-time).
+ */
+#define BM_CTRL0_RXTO_MASK		(0xff<<16)
+/* TIMEOUT = (100*7+1)*(1/BAUD) */
+#define BM_CTRL0_DEFAULT_RXTIMEOUT	(20<<16)
+/* RW. Number of bytes to receive. This must be a multiple of 4 */
+#define BM_CTRL0_RXDMA_COUNT_MASK	(0xffff<<0)
+
+/* TX ctrl register */
+#define HW_CTRL1			0x0010
+/*
+ * RW. Tell the UART to execute the TX DMA Command. The
+ * UART will clear this bit at the end of transmit execution.
+ */
+#define BM_CTRL1_TXDMA_RUN		BIT(28)
+/* RW. Number of bytes to transmit. */
+#define BM_CTRL1_TXDMA_COUNT_MASK	(0xffff << 0)
+
+#define HW_CTRL2			0x0020
+/*
+ * RW. Receive dma will terminate on error. (Cmd_end signal may not be asserted
+ * when this occurs.)
+ */
+#define BM_CTRL2_DMAONERROR		BIT(26)
+/*
+ * RW. Transmit DMA Enable. Data Register can be loaded with up to 4 bytes per
+ * write. TXFIFO must be enabled in TXDMA mode.
+ */
+#define BM_CTRL2_TXDMAE			BIT(25)
+/*
+ * RW. Receive DMA Enable. Data Register can be contain up to 4 bytes per read.
+ * RXFIFO must be enabled in RXDMA mode.
+ */
+#define BM_CTRL2_RXDMAE			BIT(24)
+/*
+ * RW. Receive Interrupt FIFO Level Select.
+ * The trigger points for the receive interrupt are as follows:
+ * ONE_EIGHTHS = 0x0 Trigger on FIFO full to at least 2 of 16 entries.
+ * ONE_QUARTER = 0x1 Trigger on FIFO full to at least 4 of 16 entries.
+ * ONE_HALF = 0x2 Trigger on FIFO full to at least 8 of 16 entries.
+ * THREE_QUARTERS = 0x3 Trigger on FIFO full to at least 12 of 16 entries.
+ * SEVEN_EIGHTHS = 0x4 Trigger on FIFO full to at least 14 of 16 entries.
+ */
+#define BM_CTRL2_RXIFLSEL		(7<<20)
+#define BM_CTRL2_DEFAULT_RXIFLSEL	(3<<20)
+/* RW. Same as RXIFLSEL */
+#define BM_CTRL2_TXIFLSEL		(7<<16)
+#define BM_CTRL2_DEFAULT_TXIFLSEL	(2<<16)
+/* RW. CTS Enable */
+#define BM_CTRL2_CTSE			BIT(15)
+/* RW. RTS Enable */
+#define BM_CTRL2_RTSE			BIT(14)
+/*
+ * RW. Manually trigger RTS. Works only if BM_CTRL2_RTSE = 0.
+ * When this bit is 1, the output is 0.
+ */
+#define BM_CTRL2_RTS			BIT(11)
+/* RW. Set DTR. When this bit is 1, the output is 0. */
+#define BM_CTRL2_DTR			BIT(10)
+/* RW. RX Enable */
+#define BM_CTRL2_RXE			BIT(9)
+/* RW. TX Enable */
+#define BM_CTRL2_TXE			BIT(8)
+/* RW. Loop Back Enable */
+#define BM_CTRL2_LBE			BIT(7)
+#define BM_CTRL2_PORT_ENABLE		BIT(0)
+
+#define HW_LINECTRL			0x0030
+#define BM_LCTRL_BAUD_DIVINT		(0xFFFF<<16)
+#define BM_LCTRL_BAUD_DIVFRA		(0x3F<<8)
+/*
+ * RW. Stick Parity Select. When bits 1, 2, and 7 of this register are set, the
+ * parity bit is transmitted and checked as a 0. When bits 1 and 7 are set,
+ * and bit 2 is 0, the parity bit is transmitted and checked as a 1. When this
+ * bit is cleared stick parity is disabled.
+ */
+#define BM_LCTRL_SPS			BIT(7)
+/* RW. Word length */
+#define BM_LCTRL_WLEN			(3<<5)
+#define BM_LCTRL_CHRL_5			(0<<5)
+#define BM_LCTRL_CHRL_6			(1<<5)
+#define BM_LCTRL_CHRL_7			(2<<5)
+#define BM_LCTRL_CHRL_8			(3<<5)
+/*
+ * RW. Enable FIFOs. If this bit is set to 1, transmit and receive FIFO buffers
+ * are enabled (FIFO mode). When cleared to 0, the FIFOs are disabled (character
+ * mode); that is, the FIFOs become 1-byte-deep holding registers.
+ */
+#define BM_LCTRL_FEN			BIT(4)
+/*
+ * RW. Two Stop Bits Select. If this bit is set to 1, two stop bits are
+ * transmitted at the end of the frame. The receive logic does not check for
+ * two stop bits being received.
+ */
+#define BM_LCTRL_STP2			BIT(3)
+#define BM_LCTRL_NBSTOP_1		(0<<3)
+#define BM_LCTRL_NBSTOP_2		(1<<3)
+/* RW. Even Parity Select. If disabled, then odd parity is performed. */
+#define BM_LCTRL_EPS			BIT(2)
+/* Parity Enable. */
+#define BM_LCTRL_PEN			BIT(1)
+#define BM_LCTRL_PAR_MARK		((3<<1) | (1<<7))
+#define BM_LCTRL_PAR_SPACE		((1<<1) | (1<<7))
+#define BM_LCTRL_PAR_ODD		((1<<1) | (0<<7))
+#define BM_LCTRL_PAR_EVEN		((3<<1) | (0<<7))
+#define BM_LCTRL_PAR_NONE		(0<<1)
+/*
+ * RW. Send Break. If this bit is set to 1, a low-level is continually output on
+ * the UARTTXD output, after completing transmission of the current character.
+ * For the proper execution of the break command, the software must set this bit
+ * for@least two complete frames. For normal use, this bit must be cleared
+ * to 0.
+ */
+#define BM_LCTRL_BREAK			BIT(0)
+
+/*
+ * Interrupt register.
+ * contains the interrupt enables and the interrupt status bits
+ */
+#define HW_INTR				0x0040
+/* Tx FIFO EMPTY Raw Interrupt enable */
+#define BM_INTR_TFEIEN			BIT(27)
+/* Overrun Error Interrupt Enable. */
+#define BM_INTR_OEIEN			BIT(26)
+/* Break Error Interrupt Enable. */
+#define BM_INTR_BEIEN			BIT(25)
+/* Parity Error Interrupt Enable. */
+#define BM_INTR_PEIEN			BIT(24)
+/* Framing Error Interrupt Enable. */
+#define BM_INTR_FEIEN			BIT(23)
+/*
+ * RW. Receive Timeout Interrupt Enable.
+ * If not set and FIFO is enabled, then RX will be triggered only
+ * if FIFO is full.
+ */
+#define BM_INTR_RTIEN			BIT(22)
+/* Transmit Interrupt Enable. */
+#define BM_INTR_TXIEN			BIT(21)
+/* Receive Interrupt Enable. */
+#define BM_INTR_RXIEN			BIT(20)
+/* nUARTDSR Modem Interrupt Enable. */
+#define BM_INTR_DSRMIEN			BIT(19)
+/* nUARTDCD Modem Interrupt Enable. */
+#define BM_INTR_DCDMIEN			BIT(18)
+/* nUARTCTS Modem Interrupt Enable. */
+#define BM_INTR_CTSMIEN			BIT(17)
+/* nUARTRI Modem Interrupt Enable. */
+#define BM_INTR_RIMIEN			BIT(16)
+/* Auto-Boud Timeout */
+#define BM_INTR_ABTO			BIT(13)
+#define BM_INTR_ABEO			BIT(12)
+/* Tx FIFO EMPTY Raw Interrupt state */
+#define BM_INTR_TFEIS			BIT(11)
+/* Overrun Error */
+#define BM_INTR_OEIS			BIT(10)
+/* Break Error */
+#define BM_INTR_BEIS			BIT(9)
+/* Parity Error */
+#define BM_INTR_PEIS			BIT(8)
+/* Framing Error */
+#define BM_INTR_FEIS			BIT(7)
+/* Receive Timeout */
+#define BM_INTR_RTIS			BIT(6)
+/* Transmit done */
+#define BM_INTR_TXIS			BIT(5)
+/* Receive done */
+#define BM_INTR_RXIS			BIT(4)
+#define BM_INTR_DSRMIS			BIT(3)
+#define BM_INTR_DCDMIS			BIT(2)
+#define BM_INTR_CTSMIS			BIT(1)
+#define BM_INTR_RIMIS			BIT(0)
+#define BM_INTR_DEF_MASK	(BM_INTR_RXIEN | BM_INTR_TXIEN | BM_INTR_RTIEN \
+		| BM_INTR_FEIEN | BM_INTR_PEIEN | BM_INTR_BEIEN | BM_INTR_OEIEN)
+#define BM_INTR_DEF_IS_MASK		(BM_INTR_DEF_MASK >> 16)
+#define BM_INTR_EN_MASK			(0x3fff0000)
+#define BM_INTR_IS_MASK			(0x00003fff)
+
+/*
+ * RW. In DMA mode, up to 4 Received/Transmit characters can be accessed at a
+ * time. In PIO mode, only one character can be accessed at a time. The status
+ * register contains the receive data flags and valid bits.
+ */
+#define HW_DATA				0x0050
+
+#define HW_STAT				0x0060
+/* RO. If 1, UARTAPP is present in this product. */
+#define BM_STAT_PRESENT			BIT(31)
+/* RO. If 1, HISPEED is present in this product. */
+#define BM_STAT_HISPEED			BIT(30)
+/* RO. UART Busy. */
+#define BM_STAT_BUSY			BIT(29)
+/* RO. Clear To Send. */
+#define BM_STAT_CTS			BIT(28)
+/* RO. Transmit FIFO/PIO Empty */
+#define BM_STAT_TXEMPTY			BIT(27)
+/* RO. Receive FIFO Full. */
+#define BM_STAT_RXFULL			BIT(26)
+/* RO. Transmit FIFO Full. */
+#define BM_STAT_TXFULL			BIT(25)
+/* RO. Receive FIFO Empty. */
+#define BM_STAT_RXEMPTY			BIT(24)
+/*
+ * RW. The invalid state of the last read of Receive Data. Each
+ * bit corresponds to one byte of the RX data. (1 = invalid.)
+ */
+#define BM_STAT_RXBYTE_INVALID_MASK	(0xf<<20)
+/*
+ * RO. Overrun Error. This bit is set to 1 if data is received and the FIFO is
+ * already full. This bit is cleared to 0 by any write to the Status Register.
+ * The FIFO contents remain valid since no further data is written when the
+ * FIFO is full; only the contents of the shift register are overwritten. The
+ * CPU must now read the data in order to empty the FIFO.
+ */
+#define BM_STAT_OVERRUNERR		BIT(19)
+/*
+ * RW. Break Error. For PIO mode, this is for the last character read from the
+ * data register. For DMA mode, it will be set to 1 if any received character
+ * for a particular RXDMA command had a Break Error. To clear this bit, write a
+ * zero to it. Note that clearing this bit does not affect the interrupt status,
+ * which must be cleared by writing the interrupt register.
+ */
+#define BM_STAT_BREAKERR		BIT(18)
+/* RW. Parity Error. Same as BREAKERR. */
+#define BM_STAT_PARITYERR		BIT(17)
+/* RW. Framing Erro. Same as BREAKERR. */
+#define BM_STAT_FRAMEERR		BIT(16)
+/* RO. Number of bytes received during a Receive DMA command. */
+#define BM_STAT_RXCOUNT_MASK		(0xffff<<0)
+
+/* RO. The UART Debug Register contains the state of the DMA signals. */
+#define HW_DEBUG			0x0070
+/* DMA Command Run Status */
+#define BM_DEBUG_TXDMARUN		BIT(5)
+#define BM_DEBUG_RXDMARUN		BIT(4)
+/* DMA Command End Status */
+#define BM_DEBUG_TXCMDEND		BIT(3)
+#define BM_DEBUG_RXCMDEND		BIT(2)
+/* DMA Request Status */
+#define BM_DEBUG_TXDMARQ		BIT(1)
+#define BM_DEBUG_RXDMARQ		BIT(0)
+
+#define HW_ILPR				0x0080
+
+#define HW_RS485CTRL			0x0090
+/*
+ * RW. This bit reverses the polarity of the direction control signal on the RTS
+ * (or DTR) pin.
+ * If 0, The direction control pin will be driven to logic ?0? when the
+ * transmitter has data to be sent. It will be driven to logic ?1? after the
+ * last bit of data has been transmitted.
+ */
+#define	BM_RS485CTRL_ONIV		BIT(5)
+/* RW. Enable Auto Direction Control. */
+#define	BM_RS485CTRL_DIR_CTRL		BIT(4)
+/*
+ * RW. If 0 and DIR_CTRL = 1, pin RTS is used for direction control.
+ * If 1 and DIR_CTRL = 1, pin DTR is used for direction control.
+ */
+#define	BM_RS485CTRL_PINSEL		BIT(3)
+/* RW. Enable Auto Address Detect (AAD). */
+#define	BM_RS485CTRL_AADEN		BIT(2)
+/* RW. Disable receiver. */
+#define	BM_RS485CTRL_RXDIS		BIT(1)
+/* RW. Enable RS-485/EIA-485 Normal Multidrop Mode (NMM) */
+#define	BM_RS485CTRL_RS485EN		BIT(0)
+
+#define HW_RS485ADRMATCH		0x00a0
+/* Contains the address match value. */
+#define BM_RS485ADRMATCH_MASK		(0xff<<0)
+
+#define HW_RS485DLY			0x00b0
+/*
+ * RW. Contains the direction control (RTS or DTR) delay value. This delay time
+ * is in periods of the baud clock.
+ */
+#define BM_RS485DLY_MASK		(0xff<<0)
+
+#define HW_AUTOBAUD			0x00c0
+/* WO. Auto-baud time-out interrupt clear bit. */
+#define BM_AUTOBAUD_ABTOIntClr		BIT(9)
+/* WO. End of auto-baud interrupt clear bit. */
+#define BM_AUTOBAUD_ABEOIntClr		BIT(8)
+/* Restart in case of timeout (counter restarts@next UART Rx falling edge) */
+#define BM_AUTOBAUD_AUTORESTART		BIT(2)
+/* Auto-baud mode select bit. 0 - Mode 0, 1 - Mode 1. */
+#define BM_AUTOBAUD_MODE		BIT(1)
+/*
+ * Auto-baud start (auto-baud is running). Auto-baud run bit. This bit is
+ * automatically cleared after auto-baud completion.
+ */
+#define BM_AUTOBAUD_START		BIT(0)
+
+#define HW_CTRL3			0x00d0
+#define BM_CTRL3_OUTCLK_DIV_MASK	(0xffff<<16)
+/*
+ * RW. Provide clk over OUTCLK pin. In case of asm9260 it can be configured on
+ * pins 137 and 144.
+ */
+#define BM_CTRL3_MASTERMODE		BIT(6)
+/* RW. Baud Rate Mode: 1 - Enable sync mode. 0 - async mode. */
+#define BM_CTRL3_SYNCMODE		BIT(4)
+/* RW. 1 - MSB bit send frist; 0 - LSB bit frist. */
+#define BM_CTRL3_MSBF			BIT(2)
+/* RW. 1 - sample rate = 8 x Baudrate; 0 - sample rate = 16 x Baudrate. */
+#define BM_CTRL3_BAUD8			BIT(1)
+/* RW. 1 - Set word lenght to 9bit. 0 - use BM_LCTRL_WLEN */
+#define BM_CTRL3_9BIT			BIT(0)
+
+#define HW_ISO7816_CTRL			0x00e0
+/* RW. Enable High Speed mode. */
+#define BM_ISO7816CTRL_HS		BIT(12)
+/* Disable Successive Receive NACK */
+#define BM_ISO7816CTRL_DS_NACK		BIT(8)
+#define BM_ISO7816CTRL_MAX_ITER_MASK	(0xff<<4)
+/* Receive NACK Inhibit */
+#define BM_ISO7816CTRL_INACK		BIT(3)
+#define BM_ISO7816CTRL_NEG_DATA		BIT(2)
+/* RW. 1 - ISO7816 mode; 0 - USART mode */
+#define BM_ISO7816CTRL_ENABLE		BIT(0)
+
+#define HW_ISO7816_ERRCNT		0x00f0
+/* Parity error counter. Will be cleared after reading */
+#define BM_ISO7816_NB_ERRORS_MASK	(0xff<<0)
+
+#define HW_ISO7816_STATUS		0x0100
+/* Max number of Repetitions Reached */
+#define BM_ISO7816_STAT_ITERATION	BIT(0)
+
+/*
+ * We wrap our port structure around the generic uart_port.
+ */
+struct asm9260_uart_port {
+	struct clk		*clk;		/* uart clock */
+	struct clk		*clk_ahb;
+	int			clk_on;
+	int			init_ok;
+	struct uart_port	uart;		/* uart */
+	struct serial_rs485	rs485;		/* rs485 settings */
+};
+
+static struct asm9260_uart_port *asm9260_ports;
+static int asm9260_ports_num;
+
+static void asm9260_start_rx(struct uart_port *uport);
+static void asm9260_tx_chars(struct uart_port *uport);
+static int asm9260_get_of_clks(struct asm9260_uart_port *port,
+		struct device_node *np);
+static void asm9260_enable_clks(struct asm9260_uart_port *port);
+static void asm9260_uart_of_enumerate(void);
+
+static inline struct asm9260_uart_port *
+to_asm9260_uart_port(struct uart_port *uart)
+{
+	return container_of(uart, struct asm9260_uart_port, uart);
+}
+
+static inline void asm9260_intr_mask(struct uart_port *uport)
+{
+	iowrite32(BM_INTR_DEF_MASK,
+			uport->membase + HW_INTR + CLR_REG);
+}
+
+static inline void asm9260_intr_unmask(struct uart_port *uport)
+{
+	iowrite32(BM_INTR_DEF_MASK,
+			uport->membase + HW_INTR + SET_REG);
+}
+
+/*
+ * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty.
+ */
+static u_int asm9260_tx_empty(struct uart_port *uport)
+{
+	return (ioread32(uport->membase + HW_STAT)
+			& BM_STAT_TXEMPTY) ? TIOCSER_TEMT : 0;
+}
+
+static void asm9260_set_mctrl(struct uart_port *uport, u_int mctrl)
+{
+}
+
+static u_int asm9260_get_mctrl(struct uart_port *uport)
+{
+	return 0;
+}
+
+/*
+ * Stop transmitting.
+ */
+static void asm9260_stop_tx(struct uart_port *uport)
+{
+	struct asm9260_uart_port *asm9260_port = to_asm9260_uart_port(uport);
+
+	/* seems like it was take over from atmel_serial.c
+	 * do we need it too? */
+	if ((asm9260_port->rs485.flags & SER_RS485_ENABLED) &&
+	    !(asm9260_port->rs485.flags & SER_RS485_RX_DURING_TX))
+		asm9260_start_rx(uport);
+}
+
+static void asm9260_start_tx(struct uart_port *uport)
+{
+	asm9260_tx_chars(uport);
+}
+
+static void asm9260_start_rx(struct uart_port *uport)
+{
+	/* enable receive */
+	iowrite32(BM_CTRL2_RXE,
+			uport->membase + HW_CTRL2 + SET_REG);
+}
+
+static void asm9260_stop_rx(struct uart_port *uport)
+{
+	/* disable receive */
+	iowrite32(BM_CTRL2_RXE,
+			uport->membase + HW_CTRL2 + CLR_REG);
+}
+
+static void asm9260_enable_ms(struct uart_port *uport)
+{
+}
+
+/*
+ * Control the transmission of a break signal
+ */
+static void asm9260_break_ctl(struct uart_port *uport, int break_state)
+{
+	if (break_state != 0)
+		iowrite32(BM_LCTRL_BREAK,
+				uport->membase + HW_LINECTRL + SET_REG);
+	else
+		iowrite32(BM_LCTRL_BREAK,
+				uport->membase + HW_LINECTRL + CLR_REG);
+}
+
+static void asm9260_rx_chars(struct uart_port *uport, unsigned int intr)
+{
+	unsigned int status, ch;
+
+	status = ioread32(uport->membase + HW_STAT);
+	while (!(status & BM_STAT_RXEMPTY)) {
+		unsigned int flg;
+
+		ch = ioread32(uport->membase + HW_DATA);
+
+		uport->icount.rx++;
+		flg = TTY_NORMAL;
+
+		if (unlikely(intr & (BM_INTR_PEIS | BM_INTR_FEIS
+				       | BM_INTR_OEIS | BM_INTR_BEIS))) {
+
+			/* clear error */
+			iowrite32(0, uport->membase + HW_STAT);
+
+			if (intr & BM_INTR_BEIS) {
+				uport->icount.brk++;
+				if (uart_handle_break(uport))
+					continue;
+			} else if (intr & BM_INTR_PEIS)
+				uport->icount.parity++;
+			else if (intr & BM_INTR_FEIS)
+				uport->icount.frame++;
+
+			if (intr & BM_INTR_OEIS)
+				uport->icount.overrun++;
+
+			intr &= uport->read_status_mask;
+
+			if (intr & BM_INTR_BEIS)
+				flg = TTY_BREAK;
+			else if (intr & BM_INTR_PEIS)
+				flg = TTY_PARITY;
+			else if (intr & BM_INTR_FEIS)
+				flg = TTY_FRAME;
+
+		}
+
+		if (uart_handle_sysrq_char(uport, ch))
+			continue;
+
+		uart_insert_char(uport, intr, BM_INTR_OEIS, ch, flg);
+		status = ioread32(uport->membase + HW_STAT);
+	}
+
+	tty_flip_buffer_push(&uport->state->port);
+}
+
+static void asm9260_tx_chars(struct uart_port *uport)
+{
+	struct circ_buf *xmit = &uport->state->xmit;
+
+	if (uport->x_char && !(ioread32(uport->membase + HW_STAT)
+				& BM_STAT_TXFULL)) {
+		iowrite32(uport->x_char, uport->membase + HW_DATA);
+		uport->icount.tx++;
+		uport->x_char = 0;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(uport))
+		return;
+
+	while (!uart_circ_empty(xmit)) {
+		if (ioread32(uport->membase + HW_STAT)
+				& BM_STAT_TXFULL)
+			break;
+
+		iowrite32(xmit->buf[xmit->tail],
+				uport->membase + HW_DATA);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		uport->icount.tx++;
+	}
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(uport);
+}
+
+static void
+asm9260_handle_receive(struct uart_port *uport, unsigned int pending)
+{
+	/* Interrupt receive */
+	if ((pending & BM_INTR_RXIS) || (pending & BM_INTR_RTIS))
+		asm9260_rx_chars(uport, pending);
+	else if (pending & BM_INTR_BEIS) {
+		/*
+		 * End of break detected. If it came along with a
+		 * character, asm9260_rx_chars will handle it.
+		 */
+		iowrite32(0, uport->membase + HW_STAT);
+	}
+}
+
+static void
+asm9260_handle_transmit(struct uart_port *uport, unsigned int pending)
+{
+	if (pending & BM_INTR_TXIS)
+		asm9260_tx_chars(uport);
+}
+
+/*
+ * Interrupt handler
+ */
+static irqreturn_t asm9260_interrupt(int irq, void *dev_id)
+{
+	struct uart_port *uport = dev_id;
+	unsigned int status;
+
+	status = ioread32(uport->membase + HW_INTR);
+	status &= BM_INTR_DEF_IS_MASK;
+
+	asm9260_handle_receive(uport, status);
+	asm9260_handle_transmit(uport, status);
+
+	iowrite32(status,
+			uport->membase + HW_INTR + CLR_REG);
+
+	asm9260_intr_unmask(uport);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t asm9260_fast_int(int irq, void *dev_id)
+{
+	struct uart_port *uport = dev_id;
+	unsigned int status;
+
+	status = ioread32(uport->membase + HW_INTR);
+	if (!(status & BM_INTR_DEF_IS_MASK))
+		return IRQ_NONE;
+
+	asm9260_intr_mask(uport);
+	return IRQ_WAKE_THREAD;
+}
+
+/*
+ * Perform initialization and enable port for reception
+ */
+static int asm9260_startup(struct uart_port *uport)
+{
+	int retval;
+
+	/*
+	 * Ensure that no interrupts are enabled otherwise when
+	 * request_irq() is called we could get stuck trying to
+	 * handle an unexpected interrupt
+	 */
+	iowrite32(0, uport->membase + HW_INTR);
+
+	retval = devm_request_threaded_irq(uport->dev, uport->irq,
+			asm9260_fast_int, asm9260_interrupt, IRQF_SHARED,
+			dev_name(uport->dev), uport);
+	if (retval) {
+		dev_err(uport->dev, "Can't get irq\n");
+		return retval;
+	}
+
+	/* enable rx timeout */
+	iowrite32(BM_CTRL0_RXTO_MASK | BM_CTRL0_RXTO_SOURCE_STATUS,
+			uport->membase + HW_CTRL0 + CLR_REG);
+	iowrite32(BM_CTRL0_DEFAULT_RXTIMEOUT | BM_CTRL0_RXTO_ENABLE,
+			uport->membase + HW_CTRL0 + SET_REG);
+
+
+	/*
+	 * Finally, enable the serial port
+	 * enable tx & rx
+	 */
+	iowrite32(BM_CTRL2_RXIFLSEL | BM_CTRL2_TXIFLSEL,
+			uport->membase + HW_CTRL2 + CLR_REG);
+	iowrite32(BM_CTRL2_PORT_ENABLE | BM_CTRL2_TXE | BM_CTRL2_RXE |
+			BM_CTRL2_DEFAULT_TXIFLSEL |
+			BM_CTRL2_DEFAULT_RXIFLSEL,
+			uport->membase + HW_CTRL2);
+
+	asm9260_intr_unmask(uport);
+	return 0;
+}
+
+/*
+ * Disable the port
+ */
+static void asm9260_shutdown(struct uart_port *uport)
+{
+	int timeout = 10000;
+
+	/*wait for controller finish tx*/
+	while (!(ioread32(uport->membase + HW_STAT)
+				& BM_STAT_TXEMPTY)) {
+		if (--timeout < 0)
+			break;
+	}
+
+	/*
+	 * Ensure everything is stopped.
+	 */
+	asm9260_stop_tx(uport);
+	asm9260_stop_rx(uport);
+}
+
+/*
+ * Flush any TX data submitted for DMA. Called when the TX circular
+ * buffer is reset.
+ */
+static void asm9260_flush_buffer(struct uart_port *uport)
+{
+}
+
+/*
+ * Power / Clock management.
+ */
+static void asm9260_serial_pm(struct uart_port *uport, unsigned int state,
+			    unsigned int oldstate)
+{
+}
+
+static void asm9260_set_rs485(struct uart_port *uport)
+{
+	struct asm9260_uart_port *port = to_asm9260_uart_port(uport);
+	unsigned int rs485_ctrl;
+	/* set RS485 */
+	rs485_ctrl = ioread32(uport->membase + HW_RS485CTRL);
+
+	/* Resetting serial mode to RS232 (0x0) */
+	rs485_ctrl &= ~BM_RS485CTRL_RS485EN;
+
+	if (port->rs485.flags & SER_RS485_ENABLED) {
+		dev_dbg(uport->dev, "Setting UART to RS485\n");
+		if ((port->rs485.delay_rts_after_send) > 0) {
+			/*
+			 * delay is (rs485conf->delay_rts_after_send *
+			 *  Bit Period * 1/16)
+			 */
+			iowrite32(port->rs485.delay_rts_after_send,
+					uport->membase + HW_RS485DLY);
+		}
+
+		if ((port->rs485.flags & SER_RS485_RTS_ON_SEND) &&
+			!(port->rs485.flags & SER_RS485_RTS_AFTER_SEND)) {
+			/*
+			 * Set logical level for RTS pin equal to 1 when
+			 * sending, and set logical level for RTS pin equal
+			 * to 0 after sending
+			 */
+			rs485_ctrl |= BM_RS485CTRL_ONIV;
+		} else if (!(port->rs485.flags & SER_RS485_RTS_ON_SEND) &&
+			(port->rs485.flags & SER_RS485_RTS_AFTER_SEND)) {
+			/*
+			 * Set logical level for RTS pin equal to 0 when
+			 * sending, and set logical level for RTS pin equal
+			 * to 1 after sending
+			 */
+			rs485_ctrl &= ~BM_RS485CTRL_ONIV;
+		} else
+			dev_info(uport->dev,
+					"Please view RS485CTRL register in datasheet for more details.\n");
+
+		/*
+		 * Enable RS485 and RTS is used to control direction
+		 * automatically,
+		 */
+		rs485_ctrl |= BM_RS485CTRL_RS485EN | BM_RS485CTRL_DIR_CTRL;
+		rs485_ctrl &= ~BM_RS485CTRL_PINSEL;
+
+		if (port->rs485.flags & SER_RS485_RX_DURING_TX)
+			dev_dbg(uport->dev, "hardware should support SER_RS485_RX_DURING_TX.\n");
+	} else
+		dev_dbg(uport->dev, "Setting UART to RS232\n");
+
+	iowrite32(rs485_ctrl, uport->membase + HW_RS485CTRL);
+}
+/*
+ * Change the port parameters
+ */
+static void asm9260_set_termios(struct uart_port *uport,
+		struct ktermios *termios, struct ktermios *old)
+{
+	unsigned int mode, baud;
+	unsigned int bauddivint, bauddivfrac;
+
+
+	asm9260_intr_mask(uport);
+
+	/*
+	 * We don't support modem control lines.
+	*/
+	termios->c_cflag &= ~(HUPCL | CMSPAR);
+	termios->c_cflag |= CLOCAL;
+
+	/* Get current mode register */
+	mode = ioread32(uport->membase + HW_LINECTRL);
+	mode &= ~(BM_LCTRL_PEN | BM_LCTRL_EPS
+			| BM_LCTRL_STP2 | BM_LCTRL_FEN
+			| BM_LCTRL_WLEN | BM_LCTRL_SPS
+			| BM_LCTRL_BAUD_DIVFRA | BM_LCTRL_BAUD_DIVINT);
+
+	baud = uart_get_baud_rate(uport, termios, old,
+			uport->uartclk * 4 / UART_BAUD_DIV_MAX,
+			uport->uartclk / 16);
+	bauddivint =
+		(((uport->uartclk << 2) / baud) & UART_BAUD_DIVINT_MASK) << 10;
+	bauddivfrac =
+		(((uport->uartclk << 2) / baud) & UART_BAUD_DIVFRAC_MASK) << 8;
+	/* byte size */
+	switch (termios->c_cflag & CSIZE) {
+	case CS5:
+		mode |= BM_LCTRL_CHRL_5;
+		break;
+	case CS6:
+		mode |= BM_LCTRL_CHRL_6;
+		break;
+	case CS7:
+		mode |= BM_LCTRL_CHRL_7;
+		break;
+	default:
+		mode |= BM_LCTRL_CHRL_8;
+		break;
+	}
+
+	/* enable fifo */
+	mode |= BM_LCTRL_FEN;
+
+	/* stop bits */
+	if (termios->c_cflag & CSTOPB)
+		mode |= BM_LCTRL_NBSTOP_2;
+	else
+		mode |= BM_LCTRL_NBSTOP_1;
+
+	/* parity */
+	if (termios->c_cflag & PARENB) {
+		/* Mark or Space parity */
+		if (termios->c_cflag & CMSPAR) {
+			if (termios->c_cflag & PARODD)
+				mode |= BM_LCTRL_PAR_MARK;
+			else
+				mode |= BM_LCTRL_PAR_SPACE;
+		} else if (termios->c_cflag & PARODD)
+			mode |= BM_LCTRL_PAR_ODD;
+		else
+			mode |= BM_LCTRL_PAR_EVEN;
+	} else
+		mode |= BM_LCTRL_PAR_NONE;
+
+	spin_lock(&uport->lock);
+
+	uport->read_status_mask = BM_INTR_OEIS;
+	if (termios->c_iflag & INPCK)
+		uport->read_status_mask |= (BM_INTR_FEIS | BM_INTR_PEIS);
+	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
+		uport->read_status_mask |= BM_INTR_BEIS;
+
+	/*
+	 * Characters to ignore
+	 */
+	uport->ignore_status_mask = 0;
+	if (termios->c_iflag & IGNPAR)
+		uport->ignore_status_mask |=
+			(BM_INTR_FEIS  | BM_INTR_PEIS);
+	if (termios->c_iflag & IGNBRK) {
+		uport->ignore_status_mask |= BM_INTR_BEIS;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (termios->c_iflag & IGNPAR)
+			uport->ignore_status_mask |= BM_INTR_OEIS;
+	}
+
+	/* update the per-port timeout */
+	uart_update_timeout(uport, termios->c_cflag, baud);
+
+	/* drain transmitter */
+	while (!(ioread32(uport->membase + HW_STAT)
+				& BM_STAT_TXEMPTY))
+		cpu_relax();
+
+	while (!(ioread32(uport->membase + HW_STAT)
+				& BM_STAT_RXEMPTY))
+		ioread32(uport->membase + HW_DATA);
+
+	asm9260_set_rs485(uport);
+
+	/* set hardware flow control */
+	if (termios->c_cflag & CRTSCTS)
+		iowrite32(BM_CTRL2_CTSE | BM_CTRL2_RTSE,
+				uport->membase + HW_CTRL2 + SET_REG);
+	else
+		iowrite32(BM_CTRL2_CTSE | BM_CTRL2_RTSE,
+				uport->membase + HW_CTRL2 + CLR_REG);
+
+	/* set the parity, stop bits, data size and baud rate*/
+	iowrite32(mode | bauddivint | bauddivfrac,
+			uport->membase + HW_LINECTRL);
+
+	/* CTS flow-control and modem-status interrupts */
+	if (UART_ENABLE_MS(uport, termios->c_cflag))
+		uport->ops->enable_ms(uport);
+
+	spin_unlock(&uport->lock);
+
+	dev_dbg(uport->dev,
+			"mode:0x%x, baud:%d, bauddivint:0x%x, bauddivfrac:0x%x, ctrl2:0x%x\n",
+			mode, baud, bauddivint, bauddivfrac,
+			ioread32(uport->membase + HW_CTRL2));
+
+	asm9260_intr_unmask(uport);
+}
+
+/*
+ * Return string describing the specified port
+ */
+static const char *asm9260_type(struct uart_port *uport)
+{
+	return (uport->type == PORT_ASM9260) ? DRIVER_NAME : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'.
+ */
+static void asm9260_release_port(struct uart_port *uport)
+{
+}
+
+/*
+ * Request the memory region(s) being used by 'port'.
+ */
+static int asm9260_request_port(struct uart_port *uport)
+{
+	return 0;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void asm9260_config_port(struct uart_port *uport, int flags)
+{
+	if (flags & UART_CONFIG_TYPE) {
+		uport->type = PORT_ASM9260;
+		asm9260_request_port(uport);
+	}
+}
+
+/*
+ * Verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int asm9260_verify_port(struct uart_port *uport,
+		struct serial_struct *ser)
+{
+	int ret = 0;
+
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_ASM9260)
+		ret = -EINVAL;
+	if (uport->irq != ser->irq)
+		ret = -EINVAL;
+	if (ser->io_type != SERIAL_IO_MEM)
+		ret = -EINVAL;
+	if (uport->uartclk / 16 != ser->baud_base)
+		ret = -EINVAL;
+	if ((void *)uport->mapbase != ser->iomem_base)
+		ret = -EINVAL;
+	if (uport->iobase != ser->port)
+		ret = -EINVAL;
+	if (ser->hub6 != 0)
+		ret = -EINVAL;
+	return ret;
+}
+
+/* Enable or disable the rs485 support */
+void asm9260_config_rs485(struct uart_port *uport,
+		struct serial_rs485 *rs485conf)
+{
+	struct asm9260_uart_port *port = to_asm9260_uart_port(uport);
+
+	asm9260_intr_mask(uport);
+	spin_lock(&uport->lock);
+
+	/* Disable interrupts */
+
+	port->rs485 = *rs485conf;
+
+	asm9260_set_rs485(uport);
+
+	/* Enable tx interrupts */
+	spin_unlock(&uport->lock);
+	asm9260_intr_unmask(uport);
+
+}
+
+static int asm9260_ioctl(struct uart_port *uport,
+		unsigned int cmd, unsigned long arg)
+{
+	struct serial_rs485 rs485conf;
+
+	switch (cmd) {
+	case TIOCSRS485:
+		if (copy_from_user(&rs485conf, (struct serial_rs485 *) arg,
+					sizeof(rs485conf)))
+			return -EFAULT;
+
+		asm9260_config_rs485(uport, &rs485conf);
+		break;
+
+	case TIOCGRS485:
+		if (copy_to_user((struct serial_rs485 *) arg,
+					&(to_asm9260_uart_port(uport)->rs485),
+					sizeof(rs485conf)))
+			return -EFAULT;
+		break;
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static struct uart_ops asm9260_pops = {
+	.tx_empty	= asm9260_tx_empty,
+	.set_mctrl	= asm9260_set_mctrl,
+	.get_mctrl	= asm9260_get_mctrl,
+	.stop_tx	= asm9260_stop_tx,
+	.start_tx	= asm9260_start_tx,
+	.stop_rx	= asm9260_stop_rx,
+	.enable_ms	= asm9260_enable_ms,
+	.break_ctl	= asm9260_break_ctl,
+	.startup	= asm9260_startup,
+	.shutdown	= asm9260_shutdown,
+	.flush_buffer	= asm9260_flush_buffer,
+	.set_termios	= asm9260_set_termios,
+	.type		= asm9260_type,
+	.release_port	= asm9260_release_port,
+	.request_port	= asm9260_request_port,
+	.config_port	= asm9260_config_port,
+	.verify_port	= asm9260_verify_port,
+	.pm		= asm9260_serial_pm,
+	.ioctl	= asm9260_ioctl,
+};
+
+#ifdef CONFIG_SERIAL_ASM9260_CONSOLE
+
+static struct asm9260_uart_port *get_asm9260_uart_port(int line);
+static struct console asm9260_console;
+
+static void asm9260_console_putchar(struct uart_port *uport, int ch)
+{
+	while (ioread32(uport->membase + HW_STAT)
+			& BM_STAT_TXFULL)
+		cpu_relax();
+	iowrite32(ch, uport->membase + HW_DATA);
+}
+
+/*
+ * Interrupts are disabled on entering
+ */
+static void asm9260_console_write(struct console *co, const char *s,
+		u_int count)
+{
+	struct uart_port *uport;
+	struct asm9260_uart_port *port;
+	unsigned int status;
+	int locked = 1;
+
+	port = get_asm9260_uart_port(co->index);
+	uport = &port->uart;
+
+	asm9260_intr_mask(uport);
+
+	if (oops_in_progress)
+		locked = spin_trylock(&uport->lock);
+	else
+		spin_lock(&uport->lock);
+
+
+	uart_console_write(uport, s, count, asm9260_console_putchar);
+
+	/*
+	 * Finally, wait for transmitter to become empty
+	 * and restore IMR
+	 */
+	do {
+		status = ioread32(uport->membase + HW_STAT);
+	} while (!(status & BM_STAT_TXEMPTY));
+
+	if (locked)
+		spin_unlock(&uport->lock);
+
+	asm9260_intr_unmask(uport);
+}
+
+/*
+ * If the port was already initialised (eg, by a boot loader),
+ * try to determine the current setup.
+ */
+static void __init asm9260_console_get_options(struct uart_port *port,
+		int *baud, int *parity, int *bits)
+{
+	unsigned int mr, quot, linectrl, bauddivint, bauddivfrc;
+
+	/*
+	 * If the baud rate generator isn't running, the port wasn't
+	 * initialized by the boot loader.
+	 */
+	linectrl = ioread32(port->membase + HW_LINECTRL);
+	bauddivint = (linectrl & BM_LCTRL_BAUD_DIVINT) >> 16;
+	bauddivfrc = (linectrl & BM_LCTRL_BAUD_DIVFRA) >> 8;
+	quot = (bauddivint << 6) | bauddivfrc;
+
+	if (!quot)
+		return;
+
+	mr = linectrl & BM_LCTRL_WLEN;
+	if (mr == BM_LCTRL_CHRL_8)
+		*bits = 8;
+	else
+		*bits = 7;
+
+	mr = linectrl &
+		(BM_LCTRL_PEN | BM_LCTRL_EPS | BM_LCTRL_SPS);
+	if (mr == BM_LCTRL_PAR_EVEN)
+		*parity = 'e';
+	else if (mr == BM_LCTRL_PAR_ODD)
+		*parity = 'o';
+
+	/*
+	 * The serial core only rounds down when matching this to a
+	 * supported baud rate. Make sure we don't end up slightly
+	 * lower than one of those, as it would make us fall through
+	 * to a much lower baud rate than we really want.
+	 */
+	*baud = (port->uartclk * 4) / quot;
+}
+
+static int __init asm9260_console_setup(struct console *co, char *options)
+{
+	struct uart_port *uport;
+	struct asm9260_uart_port *port;
+	int baud = 115200;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	asm9260_uart_of_enumerate();
+
+	port = get_asm9260_uart_port(co->index);
+	uport = &port->uart;
+
+	asm9260_enable_clks(port);
+
+	iowrite32(BM_CTRL2_TXE | BM_CTRL2_RXE | BM_CTRL2_PORT_ENABLE,
+			uport->membase + HW_CTRL2 + SET_REG);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		asm9260_console_get_options(uport, &baud, &parity, &bits);
+
+	return uart_set_options(uport, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver asm9260_uart;
+
+static struct console asm9260_console = {
+	.name		= ASM9260_DEVICENAME,
+	.write		= asm9260_console_write,
+	.device		= uart_console_device,
+	.setup		= asm9260_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+	.data		= &asm9260_uart,
+};
+
+#define ASM9260_CONSOLE_DEVICE	(&asm9260_console)
+
+/*
+ * Early console initialization (before VM subsystem initialized).
+ */
+static int __init asm9260_console_init(void)
+{
+	register_console(&asm9260_console);
+	return 0;
+}
+
+console_initcall(asm9260_console_init);
+#else
+#define ASM9260_CONSOLE_DEVICE	NULL
+#endif
+
+static struct uart_driver asm9260_uart = {
+	.owner			= THIS_MODULE,
+	.driver_name		= DRIVER_NAME,
+	.dev_name		= ASM9260_DEVICENAME,
+	.nr			= ASM9260_MAX_UART,
+	.cons			= ASM9260_CONSOLE_DEVICE,
+};
+
+/* Match table for of_platform binding */
+static struct of_device_id asm9260_of_match[] = {
+	{ .compatible = "alphascale,asm9260-uart", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, asm9260_of_match);
+
+static void asm9260_enable_clks(struct asm9260_uart_port *port)
+{
+	struct uart_port *uport = &port->uart;
+	int err;
+
+	if (port->clk_on)
+		return;
+
+	err = clk_set_rate(port->clk, ASM9260_BUS_RATE);
+	if (err)
+		dev_err(uport->dev, "Failed to set rate!\n");
+
+	err = clk_prepare_enable(port->clk);
+	if (err)
+		dev_err(uport->dev, "Failed to enable clk!\n");
+
+	err = clk_prepare_enable(port->clk_ahb);
+	if (err)
+		dev_err(uport->dev, "Failed to enable ahb_clk!\n");
+
+	uport->uartclk = clk_get_rate(port->clk);
+	port->clk_on = 1;
+}
+
+
+/* get devicetree clocks, if some thing wrong, warn about it */
+static int asm9260_get_of_clks(struct asm9260_uart_port *port,
+		struct device_node *np)
+{
+	int clk_idx = 0;
+
+	port->clk = of_clk_get(np, clk_idx);
+	if (IS_ERR(port->clk))
+		goto out_err;
+
+	/* configure AHB clock */
+	clk_idx = 1;
+	port->clk_ahb = of_clk_get(np, clk_idx);
+	if (IS_ERR(port->clk_ahb))
+		goto out_err;
+
+	return 0;
+out_err:
+	pr_err("%s: Failed to get clk (%i)\n", __func__, clk_idx);
+	return 1;
+}
+
+static int asm9260_get_count_of_nodes(const struct of_device_id *matches)
+{
+	int count = 0;
+	struct device_node *np;
+
+	for_each_matching_node(np, matches)
+		count++;
+
+	return count;
+}
+
+static struct asm9260_uart_port *get_asm9260_uart_port(int line)
+{
+	if (line >= asm9260_ports_num) {
+		pr_err("%s: Line number overflow. Check DeviceTree!!",
+				__func__);
+		return NULL;
+	}
+
+	return &asm9260_ports[line];
+}
+
+static void asm9260_uart_of_enumerate(void)
+{
+	static int enum_done;
+	struct device_node *np;
+
+	if (enum_done)
+		return;
+
+	asm9260_ports_num = asm9260_get_count_of_nodes(asm9260_of_match);
+	asm9260_ports = kcalloc(asm9260_ports_num,
+				sizeof(struct asm9260_uart_port), GFP_KERNEL);
+
+	for_each_matching_node(np, asm9260_of_match) {
+		struct uart_port *uport;
+		struct asm9260_uart_port *port;
+		int line;
+
+		line = of_alias_get_id(np, "serial");
+		if (line < 0) {
+			pr_err("Error! Devicetree has no \"serial\" aliases\n");
+			continue;
+		}
+
+		port = get_asm9260_uart_port(line);
+		if (!port)
+			continue;
+
+		uport = &port->uart;
+		if (asm9260_get_of_clks(port, np))
+			return;
+
+		uport->iotype	= UPIO_MEM;
+		uport->flags	= UPF_BOOT_AUTOCONF;
+		uport->ops	= &asm9260_pops;
+		uport->fifosize	= ASM9260_UART_FIFOSIZE;
+		uport->line	= line;
+
+		/* Since of_map don't do actual request of memory region,
+		 * it is save to use it for all, enabled and disabled uarts. */
+		uport->membase = of_iomap(np, 0);
+		if (!uport->membase) {
+			pr_err("Unable to map registers\n");
+			continue;
+		}
+		port->init_ok = 1;
+	}
+
+	enum_done = 1;
+}
+
+/*
+ * Configure the port from the platform device resource info.
+ */
+static void asm9260_init_port(struct asm9260_uart_port *asm9260_port,
+				      struct platform_device *pdev)
+{
+	struct uart_port *uport = &asm9260_port->uart;
+	struct device_node *np = pdev->dev.of_node;
+	struct resource res;
+
+	uport->dev = &pdev->dev;
+
+	uport->irq = irq_of_parse_and_map(np, 0);
+
+	of_address_to_resource(np, 0, &res);
+	if (!devm_request_mem_region(uport->dev, res.start,
+				resource_size(&res), dev_name(uport->dev)))
+		dev_err(uport->dev, "unable to request mem region\n");
+
+	uport->mapbase	= res.start;
+
+	asm9260_enable_clks(asm9260_port);
+}
+
+static int asm9260_serial_probe(struct platform_device *pdev)
+{
+	struct asm9260_uart_port *port;
+	struct device_node *np = pdev->dev.of_node;
+	int ret, line;
+
+	asm9260_uart_of_enumerate();
+
+	if (!np) {
+		dev_err(&pdev->dev, "Error! We support only DeviceTree!\n");
+		return -EPERM;
+	}
+
+	line = of_alias_get_id(np, "serial");
+	if (line < 0) {
+		dev_err(&pdev->dev,
+				"Error! Devicetree has no \"serial\" aliases\n");
+		return -EPERM;
+	}
+
+	port = get_asm9260_uart_port(line);
+
+	if (!port->init_ok)
+		dev_err(&pdev->dev, "Bad init!\n");
+
+	asm9260_init_port(port, pdev);
+
+	ret = uart_add_one_port(&asm9260_uart, &port->uart);
+	if (ret) {
+		dev_err(&pdev->dev, "Filed to add uart port\n");
+		goto err_add_port;
+	}
+
+	platform_set_drvdata(pdev, port);
+
+	return 0;
+
+err_add_port:
+	if (!uart_console(&port->uart)) {
+		clk_put(port->clk);
+		port->clk = NULL;
+	}
+	dev_err(&pdev->dev, "Filed to probe device\n");
+	return ret;
+}
+
+static int asm9260_serial_remove(struct platform_device *pdev)
+{
+	struct uart_port *port = platform_get_drvdata(pdev);
+	struct asm9260_uart_port *asm9260_port = to_asm9260_uart_port(port);
+	int ret = 0;
+
+	uart_remove_one_port(&asm9260_uart, port);
+	uart_unregister_driver(&asm9260_uart);
+
+	/* TODO: how should we handle clks here */
+	clk_put(asm9260_port->clk);
+
+	return ret;
+}
+
+static struct platform_driver asm9260_serial_driver = {
+	.driver		= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(asm9260_of_match),
+	},
+	.probe		= asm9260_serial_probe,
+	.remove		= asm9260_serial_remove,
+};
+
+static int __init asm9260_serial_init(void)
+{
+	int ret;
+
+	ret = uart_register_driver(&asm9260_uart);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&asm9260_serial_driver);
+	if (ret)
+		uart_unregister_driver(&asm9260_uart);
+
+	return ret;
+}
+
+static void __exit asm9260_serial_exit(void)
+{
+	platform_driver_unregister(&asm9260_serial_driver);
+	uart_unregister_driver(&asm9260_uart);
+}
+
+module_init(asm9260_serial_init);
+module_exit(asm9260_serial_exit);
+
+MODULE_DESCRIPTION("ASM9260 serial port driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index 5820269..ed68009 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -244,4 +244,6 @@
 /* SC16IS74xx */
 #define PORT_SC16IS7XX   108
 
+/* Alpscale ASM9260 */
+#define PORT_ASM9260	109
 #endif /* _UAPILINUX_SERIAL_CORE_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v2 1/8] ARM: add mach-asm9260
  2014-09-21 18:41 ` [PATCH v2 1/8] ARM: add mach-asm9260 Oleksij Rempel
@ 2014-09-22 15:08   ` Arnd Bergmann
  2014-09-23  9:00     ` Oleksij Rempel
  0 siblings, 1 reply; 43+ messages in thread
From: Arnd Bergmann @ 2014-09-22 15:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 21 September 2014 20:41:37 Oleksij Rempel wrote:
> it is low cost (?) SoC targeted for market in China and India which
> trying to compete with AT91SAM9G25.
> 
> Here is some info:
> http://www.alphascale.com/index.asp?ics/615.html
> 
> One of products:
> http://www.aliexpress.com/store/product/2014-hot-sales-FREE-SHIPPING-new-Purple-core-ARM9-development-board-ASM9260T-SDRAM-power-line/433637_1931495721.html
> 
> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>

Thanks for the submission! It looks pretty good, but has one main mistake
in being incompatible with ARCH_MULTIPLATFORM. I think that should be easy
to fix. There are also a few minor issues that can be improved.

> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 5918d40..1a71feb 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -379,6 +379,20 @@ config ARCH_AT91
>  	  This enables support for systems based on Atmel
>  	  AT91RM9200 and AT91SAM9* processors.
>  
> +config MACH_ASM9260
> +	bool "Alphascale ASM9260"
> +	select ARCH_REQUIRE_GPIOLIB
> +	select COMMON_CLK
> +	select IRQ_DOMAIN
> +	select SPARSE_IRQ
> +	select MULTI_IRQ_HANDLER
> +	select GENERIC_IRQ_CHIP
> +	select GENERIC_CLOCKEVENTS
> +	select CLKSRC_MMIO
> +	select CPU_ARM926T
> +	help
> +	  Support for Alpascale ASM9260 based platform.

To enable multiplatform support, please move this to its own
arch/arm/mach-asm9260/Kconfig file and make it depend on ARCH_MULTI_V5,
then remove all 'select' statements that are implicitly enabled there
already (most of the above).

> diff --git a/arch/arm/mach-asm9260/Makefile b/arch/arm/mach-asm9260/Makefile
> new file mode 100644
> index 0000000..4bd8ebd
> --- /dev/null
> +++ b/arch/arm/mach-asm9260/Makefile
> @@ -0,0 +1,11 @@
> +#
> +# Makefile for the linux kernel.
> +#
> +
> +# Object file lists.
> +
> +obj-y			:= core.o
> +obj-m			:=
> +obj-n			:=
> +obj-			:=

You can remove most of these and just leave the one line.

> diff --git a/arch/arm/mach-asm9260/Makefile.boot b/arch/arm/mach-asm9260/Makefile.boot
> new file mode 100644
> index 0000000..c57b3b4
> --- /dev/null
> +++ b/arch/arm/mach-asm9260/Makefile.boot
> @@ -0,0 +1,2 @@
> +zreladdr-y	:= 0x20008000

This file should be removed, nowadays we use AUTO_ZRELADDR, which is
implied by multiplatform.

> +static struct map_desc asm9260_io_desc[] __initdata = {
> +	{	/* IO space */
> +		.virtual	= (unsigned long)0xf0000000,
> +		.pfn		= __phys_to_pfn(0x80000000),
> +		.length		= 0x00800000,
> +		.type		= MT_DEVICE
> +	},
> +	{	/* LCD IO space	*/
> +		.virtual	= (unsigned long)0xf0a00000,
> +		.pfn		= __phys_to_pfn(0x80800000),
> +		.length		= 0x00009000,
> +		.type		= MT_DEVICE
> +	},
> +	{	/* GPIO IO space */
> +		.virtual	= (unsigned long)0xf0800000,
> +		.pfn		= __phys_to_pfn(0x50000000),
> +		.length		= 0x00100000,
> +		.type		= MT_DEVICE
> +	},
> +	{	/* SRAM space Cacheable */
> +		.virtual	= (unsigned long)0xd0000000,
> +		.pfn		= __phys_to_pfn(0x40000000),
> +		.length		= 0x00100000,
> +#ifdef CONFIG_SRAM_MEM_CACHED
> +		.type		= MT_MEMORY
> +#else
> +		.type		= MT_DEVICE
> +#endif
> +	},
> +};

This should not be necessary, as all drivers are supposed to
ioremap their own device registers. For large register ranges
that are used a lot, you could use these as an optimization to
get 1 MB sections mapped using a large TLB entry, but usually
the benefit is very small.

> +static void __init asm9260_init(void)
> +{
> +	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> +}

When you don't do anything else in the init_machine callback, you can
remove it entirely.

	Arnd

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 4/8] ARM: dts: add DT for Alphascale ASM9260 SoC
  2014-09-21 18:45   ` [PATCH v2 4/8] ARM: dts: add DT for Alphascale ASM9260 SoC Oleksij Rempel
@ 2014-09-22 15:14     ` Arnd Bergmann
  2014-09-24 10:11     ` Mark Rutland
  1 sibling, 0 replies; 43+ messages in thread
From: Arnd Bergmann @ 2014-09-22 15:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 21 September 2014 20:45:47 Oleksij Rempel wrote:
> +
> +       chosen {
> +               bootargs = "mem=32M earlyprintk=serial console=ttyS4,115200n8 root=/dev/mtdblock1 init=/linuxrc mtdparts=NAND:4M at 10M(logo)ro,60M at 14M(root)ro";
> +       };

The command line should normally be set by the boot loader, and the individual
arguments don't make much sense here:

the memory size and the flash partitions should be listed in their own DT nodes,
the init program is a user-selected option and the serial port settings
can be derived from DT for the most part too.

> +};
> +&uart4 {
> +       status = "okay";
> +};
> diff --git a/arch/arm/boot/dts/alphascale-asm9260.dtsi b/arch/arm/boot/dts/alphascale-asm9260.dtsi
> new file mode 100644
> index 0000000..3ea4e03
> --- /dev/null
> +++ b/arch/arm/boot/dts/alphascale-asm9260.dtsi
> @@ -0,0 +1,166 @@
> +/*
> + * Copyright 2014 Oleksij Rempel <linux@rempel-privat.de>
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */

We have started moving towards using dual GPL+X11 or GPL+BSD licenses
for the dts files, it would be best if you do the same here.

> +#include "skeleton.dtsi"
> +#include <dt-bindings/clock/alphascale,asm9260.h>
> +
> +/ {
> +       interrupt-parent = <&icoll>;
> +
> +        aliases {
> +               serial0 = &uart0;
> +               serial1 = &uart1;
> +               serial2 = &uart2;
> +               serial3 = &uart3;
> +               serial4 = &uart4;
> +               serial5 = &uart5;
> +               serial6 = &uart6;
> +               serial7 = &uart7;
> +               serial8 = &uart8;
> +               serial9 = &uart9;
> +        };

The aliases for the serial ports are board specific, so you
should probably move those into the first file. Only one of
them is enabled there, so you probably want

aliases {
	serial0 = &uart4;
};

so it shows up as ttyX0.

	Arnd

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 7/8] irqchip: add irq-asm9260 driver
  2014-09-21 18:45   ` [PATCH v2 7/8] irqchip: add irq-asm9260 driver Oleksij Rempel
@ 2014-09-22 15:22     ` Arnd Bergmann
  0 siblings, 0 replies; 43+ messages in thread
From: Arnd Bergmann @ 2014-09-22 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 21 September 2014 20:45:50 Oleksij Rempel wrote:
> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
> ---
>  drivers/irqchip/Makefile      |   1 +
>  drivers/irqchip/irq-asm9260.c | 257 ++++++++++++++++++++++++++++++++++++++++++

This driver seems to be closely related to drivers/irqchip/irq-mxs.c.
Are you perhaps able to share some or all of the code?

	Arnd

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 8/8] tty/serial: add asm9260-serial driver
  2014-09-21 18:45   ` [PATCH v2 8/8] tty/serial: add asm9260-serial driver Oleksij Rempel
@ 2014-09-22 15:26     ` Arnd Bergmann
  2014-09-22 16:04       ` Oleksij Rempel
  2014-09-24  9:24       ` Oleksij Rempel
  0 siblings, 2 replies; 43+ messages in thread
From: Arnd Bergmann @ 2014-09-22 15:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 21 September 2014 20:45:51 Oleksij Rempel wrote:
> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
> ---
>  drivers/tty/serial/Kconfig          |   17 +
>  drivers/tty/serial/Makefile         |    1 +
>  drivers/tty/serial/asm9260_serial.c | 1485 +++++++++++++++++++++++++++++++++++
>  include/uapi/linux/serial_core.h    |    2 +
>  4 files changed, 1505 insertions(+)
>  create mode 100644 drivers/tty/serial/asm9260_serial.c
> 

Similar to the irqchip driver, this one in turns seems to be a duplicate
of drivers/tty/serial/mxs-auart.c. Please see if you can make that one
work instead of adding a new copy.

	Arnd

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 8/8] tty/serial: add asm9260-serial driver
  2014-09-22 15:26     ` Arnd Bergmann
@ 2014-09-22 16:04       ` Oleksij Rempel
  2014-09-24  9:24       ` Oleksij Rempel
  1 sibling, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-22 16:04 UTC (permalink / raw)
  To: linux-arm-kernel

Am 22.09.2014 um 17:26 schrieb Arnd Bergmann:
> On Sunday 21 September 2014 20:45:51 Oleksij Rempel wrote:
>> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
>> ---
>>  drivers/tty/serial/Kconfig          |   17 +
>>  drivers/tty/serial/Makefile         |    1 +
>>  drivers/tty/serial/asm9260_serial.c | 1485 +++++++++++++++++++++++++++++++++++
>>  include/uapi/linux/serial_core.h    |    2 +
>>  4 files changed, 1505 insertions(+)
>>  create mode 100644 drivers/tty/serial/asm9260_serial.c
>>
> 
> Similar to the irqchip driver, this one in turns seems to be a duplicate
> of drivers/tty/serial/mxs-auart.c. Please see if you can make that one
> work instead of adding a new copy.

Ok, thank you for reviewing :)


-- 
Regards,
Oleksij

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 213 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140922/a732849b/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 1/8] ARM: add mach-asm9260
  2014-09-22 15:08   ` Arnd Bergmann
@ 2014-09-23  9:00     ` Oleksij Rempel
  2014-09-23 10:19       ` Arnd Bergmann
  0 siblings, 1 reply; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-23  9:00 UTC (permalink / raw)
  To: linux-arm-kernel

Am 22.09.2014 um 17:08 schrieb Arnd Bergmann:
> On Sunday 21 September 2014 20:41:37 Oleksij Rempel wrote:
>> it is low cost (?) SoC targeted for market in China and India which
>> trying to compete with AT91SAM9G25.
>>
>> Here is some info:
>> http://www.alphascale.com/index.asp?ics/615.html
>>
>> One of products:
>> http://www.aliexpress.com/store/product/2014-hot-sales-FREE-SHIPPING-new-Purple-core-ARM9-development-board-ASM9260T-SDRAM-power-line/433637_1931495721.html
>>
>> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
> 
> Thanks for the submission! It looks pretty good, but has one main mistake
> in being incompatible with ARCH_MULTIPLATFORM. I think that should be easy
> to fix. There are also a few minor issues that can be improved.
> 
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index 5918d40..1a71feb 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -379,6 +379,20 @@ config ARCH_AT91
>>  	  This enables support for systems based on Atmel
>>  	  AT91RM9200 and AT91SAM9* processors.
>>  
>> +config MACH_ASM9260
>> +	bool "Alphascale ASM9260"
>> +	select ARCH_REQUIRE_GPIOLIB
>> +	select COMMON_CLK
>> +	select IRQ_DOMAIN
>> +	select SPARSE_IRQ
>> +	select MULTI_IRQ_HANDLER
>> +	select GENERIC_IRQ_CHIP
>> +	select GENERIC_CLOCKEVENTS
>> +	select CLKSRC_MMIO
>> +	select CPU_ARM926T
>> +	help
>> +	  Support for Alpascale ASM9260 based platform.
> 
> To enable multiplatform support, please move this to its own
> arch/arm/mach-asm9260/Kconfig file and make it depend on ARCH_MULTI_V5,
> then remove all 'select' statements that are implicitly enabled there
> already (most of the above).

Should they be only in defconfig or selected by driver?


>> diff --git a/arch/arm/mach-asm9260/Makefile b/arch/arm/mach-asm9260/Makefile
>> new file mode 100644
>> index 0000000..4bd8ebd
>> --- /dev/null
>> +++ b/arch/arm/mach-asm9260/Makefile
>> @@ -0,0 +1,11 @@
>> +#
>> +# Makefile for the linux kernel.
>> +#
>> +
>> +# Object file lists.
>> +
>> +obj-y			:= core.o
>> +obj-m			:=
>> +obj-n			:=
>> +obj-			:=
> 
> You can remove most of these and just leave the one line.
> 
>> diff --git a/arch/arm/mach-asm9260/Makefile.boot b/arch/arm/mach-asm9260/Makefile.boot
>> new file mode 100644
>> index 0000000..c57b3b4
>> --- /dev/null
>> +++ b/arch/arm/mach-asm9260/Makefile.boot
>> @@ -0,0 +1,2 @@
>> +zreladdr-y	:= 0x20008000
> 
> This file should be removed, nowadays we use AUTO_ZRELADDR, which is
> implied by multiplatform.
> 
>> +static struct map_desc asm9260_io_desc[] __initdata = {
>> +	{	/* IO space */
>> +		.virtual	= (unsigned long)0xf0000000,
>> +		.pfn		= __phys_to_pfn(0x80000000),
>> +		.length		= 0x00800000,
>> +		.type		= MT_DEVICE
>> +	},
>> +	{	/* LCD IO space	*/
>> +		.virtual	= (unsigned long)0xf0a00000,
>> +		.pfn		= __phys_to_pfn(0x80800000),
>> +		.length		= 0x00009000,
>> +		.type		= MT_DEVICE
>> +	},
>> +	{	/* GPIO IO space */
>> +		.virtual	= (unsigned long)0xf0800000,
>> +		.pfn		= __phys_to_pfn(0x50000000),
>> +		.length		= 0x00100000,
>> +		.type		= MT_DEVICE
>> +	},
>> +	{	/* SRAM space Cacheable */
>> +		.virtual	= (unsigned long)0xd0000000,
>> +		.pfn		= __phys_to_pfn(0x40000000),
>> +		.length		= 0x00100000,
>> +#ifdef CONFIG_SRAM_MEM_CACHED
>> +		.type		= MT_MEMORY
>> +#else
>> +		.type		= MT_DEVICE
>> +#endif
>> +	},
>> +};
>
> This should not be necessary, as all drivers are supposed to
> ioremap their own device registers. For large register ranges
> that are used a lot, you could use these as an optimization to
> get 1 MB sections mapped using a large TLB entry, but usually
> the benefit is very small.

Do you mean only "SRAM space Cacheable" section?


>> +static void __init asm9260_init(void)
>> +{
>> +	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
>> +}
> 
> When you don't do anything else in the init_machine callback, you can
> remove it entirely.
> 
> 	Arnd
> 


-- 
Regards,
Oleksij

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 213 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140923/206fb525/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 1/8] ARM: add mach-asm9260
  2014-09-23  9:00     ` Oleksij Rempel
@ 2014-09-23 10:19       ` Arnd Bergmann
  2014-09-24  8:00         ` Oleksij Rempel
  0 siblings, 1 reply; 43+ messages in thread
From: Arnd Bergmann @ 2014-09-23 10:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 23 September 2014 11:00:32 Oleksij Rempel wrote:
> Am 22.09.2014 um 17:08 schrieb Arnd Bergmann:
> > On Sunday 21 September 2014 20:41:37 Oleksij Rempel wrote:
> >> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> >> index 5918d40..1a71feb 100644
> >> --- a/arch/arm/Kconfig
> >> +++ b/arch/arm/Kconfig
> >> @@ -379,6 +379,20 @@ config ARCH_AT91
> >>  	  This enables support for systems based on Atmel
> >>  	  AT91RM9200 and AT91SAM9* processors.
> >>  
> >> +config MACH_ASM9260
> >> +	bool "Alphascale ASM9260"
> >> +	select ARCH_REQUIRE_GPIOLIB
> >> +	select COMMON_CLK
> >> +	select IRQ_DOMAIN
> >> +	select SPARSE_IRQ
> >> +	select MULTI_IRQ_HANDLER
> >> +	select GENERIC_IRQ_CHIP
> >> +	select GENERIC_CLOCKEVENTS
> >> +	select CLKSRC_MMIO
> >> +	select CPU_ARM926T
> >> +	help
> >> +	  Support for Alpascale ASM9260 based platform.
> > 
> > To enable multiplatform support, please move this to its own
> > arch/arm/mach-asm9260/Kconfig file and make it depend on ARCH_MULTI_V5,
> > then remove all 'select' statements that are implicitly enabled there
> > already (most of the above).
> 
> Should they be only in defconfig or selected by driver?

The dependencies should match whatever the platform requires. Anything
that is optional and user-selectable better goes into the defconfig.

> >> +static struct map_desc asm9260_io_desc[] __initdata = {
> >> +	{	/* IO space */
> >> +		.virtual	= (unsigned long)0xf0000000,
> >> +		.pfn		= __phys_to_pfn(0x80000000),
> >> +		.length		= 0x00800000,
> >> +		.type		= MT_DEVICE
> >> +	},
> >> +	{	/* LCD IO space	*/
> >> +		.virtual	= (unsigned long)0xf0a00000,
> >> +		.pfn		= __phys_to_pfn(0x80800000),
> >> +		.length		= 0x00009000,
> >> +		.type		= MT_DEVICE
> >> +	},
> >> +	{	/* GPIO IO space */
> >> +		.virtual	= (unsigned long)0xf0800000,
> >> +		.pfn		= __phys_to_pfn(0x50000000),
> >> +		.length		= 0x00100000,
> >> +		.type		= MT_DEVICE
> >> +	},
> >> +	{	/* SRAM space Cacheable */
> >> +		.virtual	= (unsigned long)0xd0000000,
> >> +		.pfn		= __phys_to_pfn(0x40000000),
> >> +		.length		= 0x00100000,
> >> +#ifdef CONFIG_SRAM_MEM_CACHED
> >> +		.type		= MT_MEMORY
> >> +#else
> >> +		.type		= MT_DEVICE
> >> +#endif
> >> +	},
> >> +};
> >
> > This should not be necessary, as all drivers are supposed to
> > ioremap their own device registers. For large register ranges
> > that are used a lot, you could use these as an optimization to
> > get 1 MB sections mapped using a large TLB entry, but usually
> > the benefit is very small.
> 
> Do you mean only "SRAM space Cacheable" section?

No, all of them.


	Arnd

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 0/8] initial suport for Alpscale ASM9260
  2014-09-21 18:41 [PATCH v2 0/8] initial suport for Alpscale ASM9260 Oleksij Rempel
                   ` (2 preceding siblings ...)
  2014-09-21 18:45 ` Oleksij Rempel
@ 2014-09-23 11:32 ` Arnd Bergmann
  2014-09-24 10:13 ` Mark Rutland
  2014-10-07  8:55 ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
  5 siblings, 0 replies; 43+ messages in thread
From: Arnd Bergmann @ 2014-09-23 11:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 21 September 2014 20:41:36 Oleksij Rempel wrote:
> This patchset provide initial support for Alpscale ASM9260,
> ARM based SoC.
> 
> Oleksij Rempel (8):
>   ARM: add mach-asm9260
>   add include/debug/asm9260.S
>   add alphascale,asm9260.h binding
>   ARM: dts: add DT for Alphascale ASM9260 SoC
>   clk: add clk-asm9260 driver
>   clocksource: add asm9260_timer driver
>   irqchip: add irq-asm9260 driver
>   tty/serial: add asm9260-serial driver
> 

One more general comment: given the similarities between ASM9260
and the Sigmatel/Freescale chips, I wonder if it makes sense to
move the platform code into arch/arm/mach-mxs. I don't know the
exact relationship between the designs, so it's possible that they
are not actually that closely related, you'd have to find out
for yourselves.

In any case, I think any new driver should probably use the
reset interface and macros from include/linux/stmp_device.h

	Arnd

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 1/8] ARM: add mach-asm9260
  2014-09-23 10:19       ` Arnd Bergmann
@ 2014-09-24  8:00         ` Oleksij Rempel
  2014-09-24  9:43           ` Russell King - ARM Linux
  0 siblings, 1 reply; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-24  8:00 UTC (permalink / raw)
  To: linux-arm-kernel

Am 23.09.2014 um 12:19 schrieb Arnd Bergmann:
> On Tuesday 23 September 2014 11:00:32 Oleksij Rempel wrote:
>> Am 22.09.2014 um 17:08 schrieb Arnd Bergmann:
>>> On Sunday 21 September 2014 20:41:37 Oleksij Rempel wrote:
>>>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>>>> index 5918d40..1a71feb 100644
>>>> --- a/arch/arm/Kconfig
>>>> +++ b/arch/arm/Kconfig
>>>> @@ -379,6 +379,20 @@ config ARCH_AT91
>>>>  	  This enables support for systems based on Atmel
>>>>  	  AT91RM9200 and AT91SAM9* processors.
>>>>  
>>>> +config MACH_ASM9260
>>>> +	bool "Alphascale ASM9260"
>>>> +	select ARCH_REQUIRE_GPIOLIB
>>>> +	select COMMON_CLK
>>>> +	select IRQ_DOMAIN
>>>> +	select SPARSE_IRQ
>>>> +	select MULTI_IRQ_HANDLER
>>>> +	select GENERIC_IRQ_CHIP
>>>> +	select GENERIC_CLOCKEVENTS
>>>> +	select CLKSRC_MMIO
>>>> +	select CPU_ARM926T
>>>> +	help
>>>> +	  Support for Alpascale ASM9260 based platform.
>>>
>>> To enable multiplatform support, please move this to its own
>>> arch/arm/mach-asm9260/Kconfig file and make it depend on ARCH_MULTI_V5,
>>> then remove all 'select' statements that are implicitly enabled there
>>> already (most of the above).
>>
>> Should they be only in defconfig or selected by driver?
> 
> The dependencies should match whatever the platform requires. Anything
> that is optional and user-selectable better goes into the defconfig.
> 
>>>> +static struct map_desc asm9260_io_desc[] __initdata = {
>>>> +	{	/* IO space */
>>>> +		.virtual	= (unsigned long)0xf0000000,
>>>> +		.pfn		= __phys_to_pfn(0x80000000),
>>>> +		.length		= 0x00800000,
>>>> +		.type		= MT_DEVICE
>>>> +	},
>>>> +	{	/* LCD IO space	*/
>>>> +		.virtual	= (unsigned long)0xf0a00000,
>>>> +		.pfn		= __phys_to_pfn(0x80800000),
>>>> +		.length		= 0x00009000,
>>>> +		.type		= MT_DEVICE
>>>> +	},
>>>> +	{	/* GPIO IO space */
>>>> +		.virtual	= (unsigned long)0xf0800000,
>>>> +		.pfn		= __phys_to_pfn(0x50000000),
>>>> +		.length		= 0x00100000,
>>>> +		.type		= MT_DEVICE
>>>> +	},
>>>> +	{	/* SRAM space Cacheable */
>>>> +		.virtual	= (unsigned long)0xd0000000,
>>>> +		.pfn		= __phys_to_pfn(0x40000000),
>>>> +		.length		= 0x00100000,
>>>> +#ifdef CONFIG_SRAM_MEM_CACHED
>>>> +		.type		= MT_MEMORY
>>>> +#else
>>>> +		.type		= MT_DEVICE
>>>> +#endif
>>>> +	},
>>>> +};
>>>
>>> This should not be necessary, as all drivers are supposed to
>>> ioremap their own device registers. For large register ranges
>>> that are used a lot, you could use these as an optimization to
>>> get 1 MB sections mapped using a large TLB entry, but usually
>>> the benefit is very small.
>>
>> Do you mean only "SRAM space Cacheable" section?
> 
> No, all of them.

By removing it i triggered one error which i don't really understand. It
will be great if you can help me.

By defaul kernel will do fallowing remapping, which will trigger:
"Unable to handle kernel paging request at virtual address c2802174"

phys addr     ioremap        range size
=======================================
0x80054000 -> c2800000 size: 0x200
0x80040000 -> c2802000 size: 0x204
0x80088000 -> c2808000 size: 0x4000


But if change second range from 0x204 to 0x4000, then it works fine.
0x80054000 -> c2800000 size: 0x200
0x80040000 -> c2808000 size: 0x4000
0x80088000 -> c2810000 size: 0x4000

Why?
-- 
Regards,
Oleksij

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 213 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140924/94c5ab2e/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 8/8] tty/serial: add asm9260-serial driver
  2014-09-22 15:26     ` Arnd Bergmann
  2014-09-22 16:04       ` Oleksij Rempel
@ 2014-09-24  9:24       ` Oleksij Rempel
  2014-09-24 10:20         ` Arnd Bergmann
  1 sibling, 1 reply; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-24  9:24 UTC (permalink / raw)
  To: linux-arm-kernel

Am 22.09.2014 um 17:26 schrieb Arnd Bergmann:
> On Sunday 21 September 2014 20:45:51 Oleksij Rempel wrote:
>> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
>> ---
>>  drivers/tty/serial/Kconfig          |   17 +
>>  drivers/tty/serial/Makefile         |    1 +
>>  drivers/tty/serial/asm9260_serial.c | 1485 +++++++++++++++++++++++++++++++++++
>>  include/uapi/linux/serial_core.h    |    2 +
>>  4 files changed, 1505 insertions(+)
>>  create mode 100644 drivers/tty/serial/asm9260_serial.c
>>
> 
> Similar to the irqchip driver, this one in turns seems to be a duplicate
> of drivers/tty/serial/mxs-auart.c. Please see if you can make that one
> work instead of adding a new copy.

Hmmm.... they are identical in some parts, but have some different
offsets, and in some cases different bitmask. I think it will look
messy. Asm9260 has some more extras: RS485, CTRL3, ISO7816. Should it be
moved to one file? Or may be better to create some common-dma.c and
common-pio.c libs?

-- 
Regards,
Oleksij

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 213 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140924/f49b6a8c/attachment.sig>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 1/8] ARM: add mach-asm9260
  2014-09-24  8:00         ` Oleksij Rempel
@ 2014-09-24  9:43           ` Russell King - ARM Linux
  2014-09-24  9:56             ` Oleksij Rempel
  0 siblings, 1 reply; 43+ messages in thread
From: Russell King - ARM Linux @ 2014-09-24  9:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 24, 2014 at 10:00:48AM +0200, Oleksij Rempel wrote:
> Am 23.09.2014 um 12:19 schrieb Arnd Bergmann:
> > No, all of them.
> 
> By removing it i triggered one error which i don't really understand. It
> will be great if you can help me.
> 
> By defaul kernel will do fallowing remapping, which will trigger:
> "Unable to handle kernel paging request at virtual address c2802174"
> 
> phys addr     ioremap        range size
> =======================================
> 0x80054000 -> c2800000 size: 0x200
> 0x80040000 -> c2802000 size: 0x204
> 0x80088000 -> c2808000 size: 0x4000
> 
> 
> But if change second range from 0x204 to 0x4000, then it works fine.
> 0x80054000 -> c2800000 size: 0x200
> 0x80040000 -> c2808000 size: 0x4000
> 0x80088000 -> c2810000 size: 0x4000
> 
> Why?

The "why" is in the text from your oops dump.  That's precisely /why/ we
print that text - so that we know /why/ the fault happened.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 1/8] ARM: add mach-asm9260
  2014-09-24  9:43           ` Russell King - ARM Linux
@ 2014-09-24  9:56             ` Oleksij Rempel
  2014-09-24 10:25               ` Russell King - ARM Linux
  0 siblings, 1 reply; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-24  9:56 UTC (permalink / raw)
  To: linux-arm-kernel

Am 24.09.2014 um 11:43 schrieb Russell King - ARM Linux:
> On Wed, Sep 24, 2014 at 10:00:48AM +0200, Oleksij Rempel wrote:
>> Am 23.09.2014 um 12:19 schrieb Arnd Bergmann:
>>> No, all of them.
>>
>> By removing it i triggered one error which i don't really understand. It
>> will be great if you can help me.
>>
>> By defaul kernel will do fallowing remapping, which will trigger:
>> "Unable to handle kernel paging request at virtual address c2802174"
>>
>> phys addr     ioremap        range size
>> =======================================
>> 0x80054000 -> c2800000 size: 0x200
>> 0x80040000 -> c2802000 size: 0x204
>> 0x80088000 -> c2808000 size: 0x4000
>>
>>
>> But if change second range from 0x204 to 0x4000, then it works fine.
>> 0x80054000 -> c2800000 size: 0x200
>> 0x80040000 -> c2808000 size: 0x4000
>> 0x80088000 -> c2810000 size: 0x4000
>>
>> Why?
> 
> The "why" is in the text from your oops dump.  That's precisely /why/ we
> print that text - so that we know /why/ the fault happened.
> 

Here is oops message:
http://pastebin.com/qYWeAyfV

i can avoid this oops by setting size at least 0x2000 per register
range. Do it mean my TLB supports only 8 KiB pages?

-- 
Regards,
Oleksij

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 213 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140924/52b58f5f/attachment.sig>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 4/8] ARM: dts: add DT for Alphascale ASM9260 SoC
  2014-09-21 18:45   ` [PATCH v2 4/8] ARM: dts: add DT for Alphascale ASM9260 SoC Oleksij Rempel
  2014-09-22 15:14     ` Arnd Bergmann
@ 2014-09-24 10:11     ` Mark Rutland
  1 sibling, 0 replies; 43+ messages in thread
From: Mark Rutland @ 2014-09-24 10:11 UTC (permalink / raw)
  To: linux-arm-kernel

[...]

> +	clocks {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		osc24m: oscillator {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <24000000>;
> +			clock-accuracy = <30000>;
> +		};
> +
> +		i2s0_mclk {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <24000000>;
> +			clock-accuracy = <30000>;
> +		};
> +
> +		i2s1_mclk {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <24000000>;
> +			clock-accuracy = <30000>;
> +		};
> +	};

Please just get rid of the clocks node and put these clocks either under
the soc node (if they are part of the SoC) or directly under the root
node.

There is nothing special about a clocks node and its arguably an abuse
of Linux implementaiton details w.r.t. clock probing. The
#address-cells and #size-cells are meaningless (as no children have reg
entries, there's no ranges, and this isn't a simple-bus).

Mark.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 0/8] initial suport for Alpscale ASM9260
  2014-09-21 18:41 [PATCH v2 0/8] initial suport for Alpscale ASM9260 Oleksij Rempel
                   ` (3 preceding siblings ...)
  2014-09-23 11:32 ` [PATCH v2 0/8] initial suport for Alpscale ASM9260 Arnd Bergmann
@ 2014-09-24 10:13 ` Mark Rutland
  2014-10-07  8:55 ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
  5 siblings, 0 replies; 43+ messages in thread
From: Mark Rutland @ 2014-09-24 10:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Sep 21, 2014 at 07:41:36PM +0100, Oleksij Rempel wrote:
> This patchset provide initial support for Alpscale ASM9260,
> ARM based SoC.
> 
> Oleksij Rempel (8):
>   ARM: add mach-asm9260
>   add include/debug/asm9260.S
>   add alphascale,asm9260.h binding
>   ARM: dts: add DT for Alphascale ASM9260 SoC
>   clk: add clk-asm9260 driver
>   clocksource: add asm9260_timer driver
>   irqchip: add irq-asm9260 driver
>   tty/serial: add asm9260-serial driver

Several of these add new bindings, but no documentation (just a single
header).

Please document your device tree bindings.

Mark.

> 
>  arch/arm/Kconfig                                |   14 +
>  arch/arm/Kconfig.debug                          |   33 +-
>  arch/arm/Makefile                               |    1 +
>  arch/arm/boot/dts/Makefile                      |    2 +
>  arch/arm/boot/dts/alphascale-asm9260-devkit.dts |   15 +
>  arch/arm/boot/dts/alphascale-asm9260.dtsi       |  166 +++
>  arch/arm/include/debug/asm9260.S                |   31 +
>  arch/arm/mach-asm9260/Makefile                  |   11 +
>  arch/arm/mach-asm9260/Makefile.boot             |    2 +
>  arch/arm/mach-asm9260/core.c                    |   77 ++
>  drivers/clk/Makefile                            |    1 +
>  drivers/clk/clk-asm9260.c                       |  350 ++++++
>  drivers/clocksource/Makefile                    |    1 +
>  drivers/clocksource/asm9260_timer.c             |  244 ++++
>  drivers/irqchip/Makefile                        |    1 +
>  drivers/irqchip/irq-asm9260.c                   |  257 ++++
>  drivers/tty/serial/Kconfig                      |   17 +
>  drivers/tty/serial/Makefile                     |    1 +
>  drivers/tty/serial/asm9260_serial.c             | 1485 +++++++++++++++++++++++
>  include/dt-bindings/clock/alphascale,asm9260.h  |   97 ++
>  include/uapi/linux/serial_core.h                |    2 +
>  21 files changed, 2805 insertions(+), 3 deletions(-)
>  create mode 100644 arch/arm/boot/dts/alphascale-asm9260-devkit.dts
>  create mode 100644 arch/arm/boot/dts/alphascale-asm9260.dtsi
>  create mode 100644 arch/arm/include/debug/asm9260.S
>  create mode 100644 arch/arm/mach-asm9260/Makefile
>  create mode 100644 arch/arm/mach-asm9260/Makefile.boot
>  create mode 100644 arch/arm/mach-asm9260/core.c
>  create mode 100644 drivers/clk/clk-asm9260.c
>  create mode 100644 drivers/clocksource/asm9260_timer.c
>  create mode 100644 drivers/irqchip/irq-asm9260.c
>  create mode 100644 drivers/tty/serial/asm9260_serial.c
>  create mode 100644 include/dt-bindings/clock/alphascale,asm9260.h
> 
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 3/8] add alphascale,asm9260.h binding
  2014-09-21 18:45   ` [PATCH v2 3/8] add alphascale,asm9260.h binding Oleksij Rempel
@ 2014-09-24 10:15     ` Mark Rutland
  0 siblings, 0 replies; 43+ messages in thread
From: Mark Rutland @ 2014-09-24 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Sep 21, 2014 at 07:45:46PM +0100, Oleksij Rempel wrote:
> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>


This is a set of constants, which alone does not consistute a binding.
Please write a document desciribing the binding. There are plenty of
example in Documentation/devicetree/bindings/clock/

Additionally, please have a more comprehensive commit message (e.g. what
an "alphascale,asm9260" is).

> ---
>  include/dt-bindings/clock/alphascale,asm9260.h | 97 ++++++++++++++++++++++++++
>  1 file changed, 97 insertions(+)
>  create mode 100644 include/dt-bindings/clock/alphascale,asm9260.h
> 
> diff --git a/include/dt-bindings/clock/alphascale,asm9260.h b/include/dt-bindings/clock/alphascale,asm9260.h
> new file mode 100644
> index 0000000..04e8db2
> --- /dev/null
> +++ b/include/dt-bindings/clock/alphascale,asm9260.h
> @@ -0,0 +1,97 @@
> +/*
> + * Copyright 2014 Oleksij Rempel <linux@rempel-privat.de>
> + *
> + * 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 _DT_BINDINGS_CLK_ASM9260_H
> +#define _DT_BINDINGS_CLK_ASM9260_H
> +
> +/* ahb gate */
> +#define CLKID_AHB_ROM		0
> +#define CLKID_AHB_RAM		1
> +#define CLKID_AHB_GPIO		2
> +#define CLKID_AHB_MAC		3
> +#define CLKID_AHB_EMI		4
> +#define CLKID_AHB_USB0		5
> +#define CLKID_AHB_USB1		6
> +#define CLKID_AHB_DMA0		7
> +#define CLKID_AHB_DMA1		8
> +#define CLKID_AHB_UART0		9
> +#define CLKID_AHB_UART1		10
> +#define CLKID_AHB_UART2		11
> +#define CLKID_AHB_UART3		12
> +#define CLKID_AHB_UART4		13
> +#define CLKID_AHB_UART5		14
> +#define CLKID_AHB_UART6		15
> +#define CLKID_AHB_UART7		16
> +#define CLKID_AHB_UART8		17
> +#define CLKID_AHB_UART9		18
> +#define CLKID_AHB_I2S0		19
> +#define CLKID_AHB_I2C0		20
> +#define CLKID_AHB_I2C1		21
> +#define CLKID_AHB_SSP0		22
> +#define CLKID_AHB_IOCONFIG	23
> +#define CLKID_AHB_WDT		24
> +#define CLKID_AHB_CAN0		25
> +#define CLKID_AHB_CAN1		26
> +#define CLKID_AHB_MPWM		27
> +#define CLKID_AHB_SPI0		28
> +#define CLKID_AHB_SPI1		29
> +#define CLKID_AHB_QEI		30
> +#define CLKID_AHB_QUADSPI0	31
> +#define CLKID_AHB_CAMIF		32
> +#define CLKID_AHB_LCDIF		33
> +#define CLKID_AHB_TIMER0	34
> +#define CLKID_AHB_TIMER1	35
> +#define CLKID_AHB_TIMER2	36
> +#define CLKID_AHB_TIMER3	37
> +#define CLKID_AHB_IRQ		38
> +#define CLKID_AHB_RTC		39
> +#define CLKID_AHB_NAND		40
> +#define CLKID_AHB_ADC0		41
> +#define CLKID_AHB_LED		42
> +#define CLKID_AHB_DAC0		43
> +#define CLKID_AHB_LCD		44
> +#define CLKID_AHB_I2S1		45
> +#define CLKID_AHB_MAC1		46
> +
> +/* devider */

s/devider/divider/ presumably?

Mark.

> +#define CLKID_SYS_CPU		47
> +#define CLKID_SYS_AHB		48
> +#define CLKID_SYS_I2S0M		49
> +#define CLKID_SYS_I2S0S		50
> +#define CLKID_SYS_I2S1M		51
> +#define CLKID_SYS_I2S1S		52
> +#define CLKID_SYS_UART0		53
> +#define CLKID_SYS_UART1		54
> +#define CLKID_SYS_UART2		55
> +#define CLKID_SYS_UART3		56
> +#define CLKID_SYS_UART4		56
> +#define CLKID_SYS_UART5		57
> +#define CLKID_SYS_UART6		58
> +#define CLKID_SYS_UART7		59
> +#define CLKID_SYS_UART8		60
> +#define CLKID_SYS_UART9		61
> +#define CLKID_SYS_SPI0		62
> +#define CLKID_SYS_SPI1		63
> +#define CLKID_SYS_QUADSPI	64
> +#define CLKID_SYS_SSP0		65
> +#define CLKID_SYS_NAND		66
> +#define CLKID_SYS_TRACE		67
> +#define CLKID_SYS_CAMM		68
> +#define CLKID_SYS_WDT		69
> +#define CLKID_SYS_CLKOUT	70
> +#define CLKID_SYS_MAC		71
> +#define CLKID_SYS_LCD		72
> +#define CLKID_SYS_ADCANA	73
> +
> +#define MAX_CLKS		74
> +#endif
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 8/8] tty/serial: add asm9260-serial driver
  2014-09-24  9:24       ` Oleksij Rempel
@ 2014-09-24 10:20         ` Arnd Bergmann
  0 siblings, 0 replies; 43+ messages in thread
From: Arnd Bergmann @ 2014-09-24 10:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 24 September 2014 11:24:37 Oleksij Rempel wrote:
> m 22.09.2014 um 17:26 schrieb Arnd Bergmann:
> > On Sunday 21 September 2014 20:45:51 Oleksij Rempel wrote:
> >> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
> >> ---
> >>  drivers/tty/serial/Kconfig          |   17 +
> >>  drivers/tty/serial/Makefile         |    1 +
> >>  drivers/tty/serial/asm9260_serial.c | 1485 +++++++++++++++++++++++++++++++++++
> >>  include/uapi/linux/serial_core.h    |    2 +
> >>  4 files changed, 1505 insertions(+)
> >>  create mode 100644 drivers/tty/serial/asm9260_serial.c
> >>
> > 
> > Similar to the irqchip driver, this one in turns seems to be a duplicate
> > of drivers/tty/serial/mxs-auart.c. Please see if you can make that one
> > work instead of adding a new copy.
> 
> Hmmm.... they are identical in some parts, but have some different
> offsets, and in some cases different bitmask. 

It really depends on how much is different.

> I think it will look
> messy. Asm9260 has some more extras: RS485, CTRL3, ISO7816.

None of these are used in your driver though. It's possible that
mxs has the same registers but the driver author did not document
them.

> Should it be moved to one file? Or may be better to create some
> common-dma.c and common-pio.c libs?

I'd suggest trying to do it in one file first, only splitting things
out if it gets too messy.
You will probably have to replace the .driver_data in mxs_auart_devtype
with a structure that has all the differences, either using function
pointers for accessing the registers that are not identical, or using
some data that can be used to look up the the actual registers.

	Arnd

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 1/8] ARM: add mach-asm9260
  2014-09-24  9:56             ` Oleksij Rempel
@ 2014-09-24 10:25               ` Russell King - ARM Linux
  2014-09-24 10:33                 ` Arnd Bergmann
  0 siblings, 1 reply; 43+ messages in thread
From: Russell King - ARM Linux @ 2014-09-24 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 24, 2014 at 11:56:03AM +0200, Oleksij Rempel wrote:
> Am 24.09.2014 um 11:43 schrieb Russell King - ARM Linux:
> > The "why" is in the text from your oops dump.  That's precisely /why/ we
> > print that text - so that we know /why/ the fault happened.
> 
> Here is oops message:
> http://pastebin.com/qYWeAyfV
> 
> i can avoid this oops by setting size at least 0x2000 per register
> range. Do it mean my TLB supports only 8 KiB pages?

No, it has nothing to do with the TLB.

Unable to handle kernel paging request at virtual address c2802174
pgd = c0004000
[c2802174] *pgd=21805811, *pte=00000000, *ppte=00000000
Internal error: Oops: 7 [#1] PREEMPT ARM

The number after the Oops: is the FSR value, which means "page translation
fault", and sure enough, the pgd/pte values show that there is no page
table entry at the faulting address.

That's odd, because ioremap() aligns the size of the requested mapping up
to a multiple of the page size, and inserts page table entries according
to the rounded size.

Where are you calling ioremap(), iounmap() etc?  IOW, please show your
code for this.

I also notice that the unwinder failed to unwind the complete backtrace:

[<c02bcb38>] (clk_gate_is_enabled) from [<c02b9a0c>] (clk_disable_unused_subtree+)
[<c02b9a0c>] (clk_disable_unused_subtree) from [<c02b99c8>] (clk_disable_unused_s)

which is really annoying.  Maybe turning frame pointers on will get is a
proper backtrace, though I don't think it's that important to this bug.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 1/8] ARM: add mach-asm9260
  2014-09-24 10:25               ` Russell King - ARM Linux
@ 2014-09-24 10:33                 ` Arnd Bergmann
  2014-09-24 11:30                   ` Oleksij Rempel
  0 siblings, 1 reply; 43+ messages in thread
From: Arnd Bergmann @ 2014-09-24 10:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 24 September 2014 11:25:42 Russell King - ARM Linux wrote:
> On Wed, Sep 24, 2014 at 11:56:03AM +0200, Oleksij Rempel wrote:
> > Am 24.09.2014 um 11:43 schrieb Russell King - ARM Linux:
> > > The "why" is in the text from your oops dump.  That's precisely /why/ we
> > > print that text - so that we know /why/ the fault happened.
> > 
> > Here is oops message:
> > http://pastebin.com/qYWeAyfV
> > 
> > i can avoid this oops by setting size at least 0x2000 per register
> > range. Do it mean my TLB supports only 8 KiB pages?
> 
> No, it has nothing to do with the TLB.
> 
> Unable to handle kernel paging request at virtual address c2802174
> pgd = c0004000
> [c2802174] *pgd=21805811, *pte=00000000, *ppte=00000000
> Internal error: Oops: 7 [#1] PREEMPT ARM
> 
> The number after the Oops: is the FSR value, which means "page translation
> fault", and sure enough, the pgd/pte values show that there is no page
> table entry at the faulting address.
> 
> That's odd, because ioremap() aligns the size of the requested mapping up
> to a multiple of the page size, and inserts page table entries according
> to the rounded size.
> 
> Where are you calling ioremap(), iounmap() etc?  IOW, please show your
> code for this.

It's the clock driver from patch 5. It starts out with an ioremap of
the clock controller node:

+               acc: clock-controller at 80040000 {
+                       compatible = "alphascale,asm9260-clock-controller";
+                       #clock-cells = <1>;
+                       clocks = <&osc24m>;
+                       reg = <0x80040000 0x500>;
+               };

Oh, and there is the bug:

+       /* check for errors on leaf clocks */
+       for (n = 0; n < MAX_CLKS; n++) {
+               if (!IS_ERR(clks[n]))
+                       continue;
+
+               pr_err("%s: Unable to register leaf clock %d\n",
+                               np->full_name, n);
+               goto fail;
+       }
+
+       /* register clk-provider */
+       clk_data.clks = clks;
+       clk_data.clk_num = MAX_CLKS;
+       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+fail:
+       iounmap(base);
+}

There should be a 'return' in front of the 'fail:', otherwise it
get unmapped unconditionally.

	Arnd

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 1/8] ARM: add mach-asm9260
  2014-09-24 10:33                 ` Arnd Bergmann
@ 2014-09-24 11:30                   ` Oleksij Rempel
  0 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-09-24 11:30 UTC (permalink / raw)
  To: linux-arm-kernel

Am 24.09.2014 um 12:33 schrieb Arnd Bergmann:
> On Wednesday 24 September 2014 11:25:42 Russell King - ARM Linux wrote:
>> On Wed, Sep 24, 2014 at 11:56:03AM +0200, Oleksij Rempel wrote:
>>> Am 24.09.2014 um 11:43 schrieb Russell King - ARM Linux:
>>>> The "why" is in the text from your oops dump.  That's precisely /why/ we
>>>> print that text - so that we know /why/ the fault happened.
>>>
>>> Here is oops message:
>>> http://pastebin.com/qYWeAyfV
>>>
>>> i can avoid this oops by setting size at least 0x2000 per register
>>> range. Do it mean my TLB supports only 8 KiB pages?
>>
>> No, it has nothing to do with the TLB.
>>
>> Unable to handle kernel paging request at virtual address c2802174
>> pgd = c0004000
>> [c2802174] *pgd=21805811, *pte=00000000, *ppte=00000000
>> Internal error: Oops: 7 [#1] PREEMPT ARM
>>
>> The number after the Oops: is the FSR value, which means "page translation
>> fault", and sure enough, the pgd/pte values show that there is no page
>> table entry at the faulting address.
>>
>> That's odd, because ioremap() aligns the size of the requested mapping up
>> to a multiple of the page size, and inserts page table entries according
>> to the rounded size.
>>
>> Where are you calling ioremap(), iounmap() etc?  IOW, please show your
>> code for this.
> 
> It's the clock driver from patch 5. It starts out with an ioremap of
> the clock controller node:
> 
> +               acc: clock-controller at 80040000 {
> +                       compatible = "alphascale,asm9260-clock-controller";
> +                       #clock-cells = <1>;
> +                       clocks = <&osc24m>;
> +                       reg = <0x80040000 0x500>;
> +               };
> 
> Oh, and there is the bug:
> 
> +       /* check for errors on leaf clocks */
> +       for (n = 0; n < MAX_CLKS; n++) {
> +               if (!IS_ERR(clks[n]))
> +                       continue;
> +
> +               pr_err("%s: Unable to register leaf clock %d\n",
> +                               np->full_name, n);
> +               goto fail;
> +       }
> +
> +       /* register clk-provider */
> +       clk_data.clks = clks;
> +       clk_data.clk_num = MAX_CLKS;
> +       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
> +fail:
> +       iounmap(base);
> +}
> 
> There should be a 'return' in front of the 'fail:', otherwise it
> get unmapped unconditionally.

Ouch... thank you!!!
Still weird why it was not always oopsing.

-- 
Regards,
Oleksij

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 213 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140924/6ed577a2/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v3 0/9] initial suport for Alphascale ASM9260
  2014-09-21 18:41 [PATCH v2 0/8] initial suport for Alpscale ASM9260 Oleksij Rempel
                   ` (4 preceding siblings ...)
  2014-09-24 10:13 ` Mark Rutland
@ 2014-10-07  8:55 ` Oleksij Rempel
  2014-10-07  8:55   ` [PATCH v3 1/9] ARM: add mach-asm9260 Oleksij Rempel
                     ` (9 more replies)
  5 siblings, 10 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-10-07  8:55 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset provide initial support for Alpascale ASM9260,
ARM based SoC.

Oleksij Rempel (9):
  ARM: add mach-asm9260
  arm: add lolevel debug support for asm9260
  ARM: dts: add DT for Alphascale ASM9260 SoC
  ARM: add alphascale,acc.txt bindings documentation
  ARM: clk: add clk-asm9260 driver
  clocksource: add asm9260_timer driver
  irqchip/irq-mxs.c: add asm9260 support
  tty/serial/mxs-auart.c: add initial Alphascale ASM9260 support
  add Alphascale to vendor-prefixes.txt

 .../devicetree/bindings/clock/alphascale,acc.txt   | 113 +++++++
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 arch/arm/Kconfig                                   |   2 +
 arch/arm/Kconfig.debug                             |  33 +-
 arch/arm/Makefile                                  |   1 +
 arch/arm/boot/dts/Makefile                         |   2 +
 arch/arm/boot/dts/alphascale-asm9260-devkit.dts    |  21 ++
 arch/arm/boot/dts/alphascale-asm9260.dtsi          | 134 ++++++++
 arch/arm/include/debug/asm9260.S                   |  31 ++
 arch/arm/mach-asm9260/Kconfig                      |   8 +
 arch/arm/mach-asm9260/Makefile                     |   1 +
 arch/arm/mach-asm9260/core.c                       |  20 ++
 drivers/clk/Makefile                               |   1 +
 drivers/clk/clk-asm9260.c                          | 351 +++++++++++++++++++
 drivers/clocksource/Kconfig                        |   4 +
 drivers/clocksource/Makefile                       |   1 +
 drivers/clocksource/asm9260_timer.c                | 234 +++++++++++++
 drivers/irqchip/Kconfig                            |   5 +
 drivers/irqchip/Makefile                           |   2 +-
 drivers/irqchip/alphascale,asm9260-icoll.h         | 109 ++++++
 drivers/irqchip/irq-mxs.c                          | 142 +++++++-
 drivers/tty/serial/Kconfig                         |   5 +-
 drivers/tty/serial/alphascale,asm9260_serial.h     | 373 +++++++++++++++++++++
 drivers/tty/serial/mxs-auart.c                     | 344 ++++++++++++-------
 include/dt-bindings/clock/alphascale,asm9260.h     |  97 ++++++
 25 files changed, 1892 insertions(+), 143 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/alphascale,acc.txt
 create mode 100644 arch/arm/boot/dts/alphascale-asm9260-devkit.dts
 create mode 100644 arch/arm/boot/dts/alphascale-asm9260.dtsi
 create mode 100644 arch/arm/include/debug/asm9260.S
 create mode 100644 arch/arm/mach-asm9260/Kconfig
 create mode 100644 arch/arm/mach-asm9260/Makefile
 create mode 100644 arch/arm/mach-asm9260/core.c
 create mode 100644 drivers/clk/clk-asm9260.c
 create mode 100644 drivers/clocksource/asm9260_timer.c
 create mode 100644 drivers/irqchip/alphascale,asm9260-icoll.h
 create mode 100644 drivers/tty/serial/alphascale,asm9260_serial.h
 create mode 100644 include/dt-bindings/clock/alphascale,asm9260.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v3 1/9] ARM: add mach-asm9260
  2014-10-07  8:55 ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
@ 2014-10-07  8:55   ` Oleksij Rempel
  2014-10-07  8:55   ` [PATCH v3 2/9] arm: add lolevel debug support for asm9260 Oleksij Rempel
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-10-07  8:55 UTC (permalink / raw)
  To: linux-arm-kernel

it is low cost (?) SoC targeted for market in China and India which
trying to compete with AT91SAM9G25.

Here is some info:
http://www.alphascale.com/index.asp?ics/615.html

One of products:
http://www.aliexpress.com/store/product/2014-hot-sales-FREE-SHIPPING-new-Purple-core-ARM9-development-board-ASM9260T-SDRAM-power-line/433637_1931495721.html

In some cases this SoC looks similar to iMX23/iMX28. But currently it makes no
sense to merge mach code of this devices. Especially because most differences
are already collected mach-mxs folder.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 arch/arm/Kconfig               |  2 ++
 arch/arm/Makefile              |  1 +
 arch/arm/mach-asm9260/Kconfig  |  8 ++++++++
 arch/arm/mach-asm9260/Makefile |  1 +
 arch/arm/mach-asm9260/core.c   | 20 ++++++++++++++++++++
 5 files changed, 32 insertions(+)
 create mode 100644 arch/arm/mach-asm9260/Kconfig
 create mode 100644 arch/arm/mach-asm9260/Makefile
 create mode 100644 arch/arm/mach-asm9260/core.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5918d40..87373da 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -968,6 +968,8 @@ source "arch/arm/mach-w90x900/Kconfig"
 
 source "arch/arm/mach-zynq/Kconfig"
 
+source "arch/arm/mach-asm9260/Kconfig"
+
 # Definitions to make life easier
 config ARCH_ACORN
 	bool
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 0ce9d0f..dda8f6d 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -146,6 +146,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
 machine-$(CONFIG_ARCH_AT91)		+= at91
+machine-$(CONFIG_MACH_ASM9260)		+= asm9260
 machine-$(CONFIG_ARCH_AXXIA)		+= axxia
 machine-$(CONFIG_ARCH_BCM)		+= bcm
 machine-$(CONFIG_ARCH_BERLIN)		+= berlin
diff --git a/arch/arm/mach-asm9260/Kconfig b/arch/arm/mach-asm9260/Kconfig
new file mode 100644
index 0000000..eef90d9
--- /dev/null
+++ b/arch/arm/mach-asm9260/Kconfig
@@ -0,0 +1,8 @@
+config MACH_ASM9260
+	bool "Alphascale ASM9260"
+	depends on ARCH_MULTI_V5
+	select IRQ_MXS
+	select ASM9260_TIMER
+	select CPU_ARM926T
+	help
+	  Support for Alpascale ASM9260 based platform.
diff --git a/arch/arm/mach-asm9260/Makefile b/arch/arm/mach-asm9260/Makefile
new file mode 100644
index 0000000..3f774e4
--- /dev/null
+++ b/arch/arm/mach-asm9260/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MACH_ASM9260) += core.o
diff --git a/arch/arm/mach-asm9260/core.c b/arch/arm/mach-asm9260/core.c
new file mode 100644
index 0000000..d1b9006
--- /dev/null
+++ b/arch/arm/mach-asm9260/core.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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.
+ */
+
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+
+static const char * const asm9260_dt_board_compat[] __initconst = {
+	"alphascale,asm9260",
+	NULL
+};
+
+DT_MACHINE_START(ASM9260, "Alphascale ASM9260 (Device Tree Support)")
+	.dt_compat	= asm9260_dt_board_compat,
+MACHINE_END
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 2/9] arm: add lolevel debug support for asm9260
  2014-10-07  8:55 ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
  2014-10-07  8:55   ` [PATCH v3 1/9] ARM: add mach-asm9260 Oleksij Rempel
@ 2014-10-07  8:55   ` Oleksij Rempel
  2014-10-07  8:55   ` [PATCH v3 3/9] ARM: dts: add DT for Alphascale ASM9260 SoC Oleksij Rempel
                     ` (7 subsequent siblings)
  9 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-10-07  8:55 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 arch/arm/Kconfig.debug           | 33 ++++++++++++++++++++++++++++++---
 arch/arm/include/debug/asm9260.S | 31 +++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/include/debug/asm9260.S

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index b11ad54..6902a57 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -953,6 +953,27 @@ choice
 		  options; the platform specific options are deprecated
 		  and will be soon removed.
 
+	config DEBUG_ASM9260_UART
+		bool "Kernel low-level debugging via asm9260 UART"
+		depends on MACH_ASM9260
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to an UART or USART port on asm9260 based
+		  machines.
+
+		    DEBUG_UART_PHYS | DEBUG_UART_VIRT
+
+		    0x80000000      | 0xf0000000     | UART0
+		    0x80004000      | 0xf0004000     | UART1
+		    0x80008000      | 0xf0008000     | UART2
+		    0x8000c000      | 0xf000c000     | UART3
+		    0x80010000      | 0xf0010000     | UART4
+		    0x80014000      | 0xf0014000     | UART5
+		    0x80018000      | 0xf0018000     | UART6
+		    0x8001c000      | 0xf001c000     | UART7
+		    0x80020000      | 0xf0020000     | UART8
+		    0x80024000      | 0xf0024000     | UART9
+
 endchoice
 
 config DEBUG_EXYNOS_UART
@@ -1038,6 +1059,7 @@ config DEBUG_LL_INCLUDE
 	default "debug/vf.S" if DEBUG_VF_UART
 	default "debug/vt8500.S" if DEBUG_VT8500_UART0
 	default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1
+	default "debug/asm9260.S" if DEBUG_ASM9260_UART
 	default "mach/debug-macro.S"
 
 # Compatibility options for PL01x
@@ -1094,6 +1116,7 @@ config DEBUG_UART_PHYS
 	default 0x50008000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART2 || \
 				DEBUG_S3C2410_UART2)
 	default 0x7c0003f8 if FOOTBRIDGE
+	default 0x80010000 if DEBUG_ASM9260_UART
 	default 0x80070000 if DEBUG_IMX23_UART
 	default 0x80074000 if DEBUG_IMX28_UART
 	default 0x80230000 if DEBUG_PICOXCELL_UART
@@ -1126,7 +1149,8 @@ config DEBUG_UART_PHYS
 	depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
 		DEBUG_LL_UART_EFM32 || \
 		DEBUG_UART_8250 || DEBUG_UART_PL01X || \
-		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART
+		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || \
+		DEBUG_S3C24XX_UART || DEBUG_ASM9260_UART
 
 config DEBUG_UART_VIRT
 	hex "Virtual base address of debug UART"
@@ -1134,6 +1158,7 @@ config DEBUG_UART_VIRT
 	default 0xe1000000 if DEBUG_MSM_UART
 	default 0xf0000be0 if ARCH_EBSA110
 	default 0xf0009000 if DEBUG_CNS3XXX
+	default 0xf0010000 if DEBUG_ASM9260_UART
 	default 0xf01fb000 if DEBUG_NOMADIK_UART
 	default 0xf0201000 if DEBUG_BCM2835
 	default 0xf1000300 if DEBUG_BCM_5301X
@@ -1194,7 +1219,8 @@ config DEBUG_UART_VIRT
 	default DEBUG_UART_PHYS if !MMU
 	depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
 		DEBUG_UART_8250 || DEBUG_UART_PL01X || \
-		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART
+		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || \
+		DEBUG_S3C24XX_UART || DEBUG_ASM9260_UART
 
 config DEBUG_UART_8250_SHIFT
 	int "Register offset shift for the 8250 debug UART"
@@ -1236,7 +1262,8 @@ config DEBUG_UNCOMPRESS
 config UNCOMPRESS_INCLUDE
 	string
 	default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM || \
-					PLAT_SAMSUNG || ARCH_EFM32
+					PLAT_SAMSUNG || ARCH_EFM32 || \
+					MACH_ASM9260
 	default "mach/uncompress.h"
 
 config EARLY_PRINTK
diff --git a/arch/arm/include/debug/asm9260.S b/arch/arm/include/debug/asm9260.S
new file mode 100644
index 0000000..c70d51f
--- /dev/null
+++ b/arch/arm/include/debug/asm9260.S
@@ -0,0 +1,31 @@
+/* arch/arm/mach-imx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *  Modified for ASM9260 by Oleksij Remepl <linux@rempel-privat.de>
+ *
+ * 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.
+ *
+ */
+
+		.macro	addruart, rp, rv, tmp
+		ldr	\rp, = CONFIG_DEBUG_UART_PHYS
+		ldr	\rv, = CONFIG_DEBUG_UART_VIRT
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x50]	@ TXDATA
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldr	\rd, [\rx, #0x60]	@ STAT
+		tst	\rd, #1 << 27		@ TXEMPTY
+		beq	1002b			@ wait until transmit done
+		.endm
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 3/9] ARM: dts: add DT for Alphascale ASM9260 SoC
  2014-10-07  8:55 ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
  2014-10-07  8:55   ` [PATCH v3 1/9] ARM: add mach-asm9260 Oleksij Rempel
  2014-10-07  8:55   ` [PATCH v3 2/9] arm: add lolevel debug support for asm9260 Oleksij Rempel
@ 2014-10-07  8:55   ` Oleksij Rempel
  2014-10-07  8:55   ` [PATCH v3 4/9] ARM: add alphascale,acc.txt bindings documentation Oleksij Rempel
                     ` (6 subsequent siblings)
  9 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-10-07  8:55 UTC (permalink / raw)
  To: linux-arm-kernel

for now it is wary basic SoC description with most important IPs needed
to make this device work

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 arch/arm/boot/dts/Makefile                      |   2 +
 arch/arm/boot/dts/alphascale-asm9260-devkit.dts |  21 ++++
 arch/arm/boot/dts/alphascale-asm9260.dtsi       | 134 ++++++++++++++++++++++++
 include/dt-bindings/clock/alphascale,asm9260.h  |  97 +++++++++++++++++
 4 files changed, 254 insertions(+)
 create mode 100644 arch/arm/boot/dts/alphascale-asm9260-devkit.dts
 create mode 100644 arch/arm/boot/dts/alphascale-asm9260.dtsi
 create mode 100644 include/dt-bindings/clock/alphascale,asm9260.h

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b8c5cd3..8943d72 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -492,6 +492,8 @@ dtb-$(CONFIG_MACH_DOVE) += dove-cm-a510.dtb \
 	dove-d3plug.dtb \
 	dove-dove-db.dtb
 
+dtb-$(CONFIG_MACH_ASM9260) += alphascale-asm9260-devkit.dtb
+
 targets += dtbs dtbs_install
 targets += $(dtb-y)
 endif
diff --git a/arch/arm/boot/dts/alphascale-asm9260-devkit.dts b/arch/arm/boot/dts/alphascale-asm9260-devkit.dts
new file mode 100644
index 0000000..bf63dd2
--- /dev/null
+++ b/arch/arm/boot/dts/alphascale-asm9260-devkit.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * Licensed under the X11 license or the GPL v2 (or later)
+ */
+
+/dts-v1/;
+#include "alphascale-asm9260.dtsi"
+
+/ {
+	model = "Alphascale asm9260 Development Kit";
+	compatible = "alphascale,asm9260devkit", "alphascale,asm9260";
+
+	aliases {
+		serial0 = &uart4;
+	};
+};
+
+&uart4 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/alphascale-asm9260.dtsi b/arch/arm/boot/dts/alphascale-asm9260.dtsi
new file mode 100644
index 0000000..d147612
--- /dev/null
+++ b/arch/arm/boot/dts/alphascale-asm9260.dtsi
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * Licensed under the X11 license or the GPL v2 (or later)
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/alphascale,asm9260.h>
+
+/ {
+	interrupt-parent = <&icoll>;
+
+	memory {
+		device_type = "memory";
+		reg = <0x20000000 0x2000000>;
+	};
+
+	cpus {
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			compatible = "arm,arm926ej-s";
+			device_type = "cpu";
+			clocks = <&acc CLKID_SYS_CPU>;
+		};
+	};
+
+	osc24m: oscillator {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-accuracy = <30000>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+                ranges;
+
+		acc: clock-controller at 80040000 {
+			compatible = "alphascale,asm9260-clock-controller";
+			#clock-cells = <1>;
+			clocks = <&osc24m>;
+			reg = <0x80040000 0x204>;
+		};
+
+		icoll: interrupt-controller at 80054000 {
+			compatible = "alphascale,asm9260-icoll";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			reg = <0x80054000 0x200>;
+		};
+
+		uart0: serial at 80000000 {
+			compatible = "alphascale,asm9260-auart";
+			reg = <0x80000000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART0>, <&acc CLKID_AHB_UART0>;
+			interrupts = <15>;
+			status = "disabled";
+		};
+		uart1: serial at 80004000 {
+			compatible = "alphascale,asm9260-auart";
+			reg = <0x80004000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART1>, <&acc CLKID_AHB_UART1>;
+			interrupts = <16>;
+			status = "disabled";
+		};
+		uart2: serial at 80008000 {
+			compatible = "alphascale,asm9260-auart";
+			reg = <0x80008000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART2>, <&acc CLKID_AHB_UART2>;
+			interrupts = <17>;
+			status = "disabled";
+		};
+		uart3: serial at 8000c000 {
+			compatible = "alphascale,asm9260-auart";
+			reg = <0x8000c000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART3>, <&acc CLKID_AHB_UART3>;
+			interrupts = <18>;
+			status = "disabled";
+		};
+		uart4: serial at 80010000 {
+			compatible = "alphascale,asm9260-auart";
+			reg = <0x80010000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART4>, <&acc CLKID_AHB_UART4>;
+			interrupts = <19>;
+			status = "disabled";
+		};
+		uart5: serial at 80014000 {
+			compatible = "alphascale,asm9260-auart";
+			reg = <0x80014000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART5>, <&acc CLKID_AHB_UART5>;
+			interrupts = <20>;
+			status = "disabled";
+		};
+		uart6: serial at 80018000 {
+			compatible = "alphascale,asm9260-auart";
+			reg = <0x80018000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART6>, <&acc CLKID_AHB_UART6>;
+			interrupts = <21>;
+			status = "disabled";
+		};
+		uart7: serial at 8001c000 {
+			compatible = "alphascale,asm9260-auart";
+			reg = <0x8001c000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART7>, <&acc CLKID_AHB_UART7>;
+			interrupts = <22>;
+			status = "disabled";
+		};
+		uart8: serial at 80020000 {
+			compatible = "alphascale,asm9260-auart";
+			reg = <0x80020000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART8>, <&acc CLKID_AHB_UART8>;
+			interrupts = <23>;
+			status = "disabled";
+		};
+		uart9: serial at 80024000 {
+			compatible = "alphascale,asm9260-auart";
+			reg = <0x80024000 0x4000>;
+			clocks = <&acc CLKID_SYS_UART9>, <&acc CLKID_AHB_UART9>;
+			interrupts = <24>;
+			status = "disabled";
+		};
+
+		timer0: timer at 80088000 {
+			compatible = "alphascale,asm9260-timer";
+			reg = <0x80088000 0x4000>;
+			clocks = <&acc CLKID_AHB_TIMER0>;
+			interrupts = <29>;
+		};
+	};
+};
diff --git a/include/dt-bindings/clock/alphascale,asm9260.h b/include/dt-bindings/clock/alphascale,asm9260.h
new file mode 100644
index 0000000..04e8db2
--- /dev/null
+++ b/include/dt-bindings/clock/alphascale,asm9260.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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 _DT_BINDINGS_CLK_ASM9260_H
+#define _DT_BINDINGS_CLK_ASM9260_H
+
+/* ahb gate */
+#define CLKID_AHB_ROM		0
+#define CLKID_AHB_RAM		1
+#define CLKID_AHB_GPIO		2
+#define CLKID_AHB_MAC		3
+#define CLKID_AHB_EMI		4
+#define CLKID_AHB_USB0		5
+#define CLKID_AHB_USB1		6
+#define CLKID_AHB_DMA0		7
+#define CLKID_AHB_DMA1		8
+#define CLKID_AHB_UART0		9
+#define CLKID_AHB_UART1		10
+#define CLKID_AHB_UART2		11
+#define CLKID_AHB_UART3		12
+#define CLKID_AHB_UART4		13
+#define CLKID_AHB_UART5		14
+#define CLKID_AHB_UART6		15
+#define CLKID_AHB_UART7		16
+#define CLKID_AHB_UART8		17
+#define CLKID_AHB_UART9		18
+#define CLKID_AHB_I2S0		19
+#define CLKID_AHB_I2C0		20
+#define CLKID_AHB_I2C1		21
+#define CLKID_AHB_SSP0		22
+#define CLKID_AHB_IOCONFIG	23
+#define CLKID_AHB_WDT		24
+#define CLKID_AHB_CAN0		25
+#define CLKID_AHB_CAN1		26
+#define CLKID_AHB_MPWM		27
+#define CLKID_AHB_SPI0		28
+#define CLKID_AHB_SPI1		29
+#define CLKID_AHB_QEI		30
+#define CLKID_AHB_QUADSPI0	31
+#define CLKID_AHB_CAMIF		32
+#define CLKID_AHB_LCDIF		33
+#define CLKID_AHB_TIMER0	34
+#define CLKID_AHB_TIMER1	35
+#define CLKID_AHB_TIMER2	36
+#define CLKID_AHB_TIMER3	37
+#define CLKID_AHB_IRQ		38
+#define CLKID_AHB_RTC		39
+#define CLKID_AHB_NAND		40
+#define CLKID_AHB_ADC0		41
+#define CLKID_AHB_LED		42
+#define CLKID_AHB_DAC0		43
+#define CLKID_AHB_LCD		44
+#define CLKID_AHB_I2S1		45
+#define CLKID_AHB_MAC1		46
+
+/* devider */
+#define CLKID_SYS_CPU		47
+#define CLKID_SYS_AHB		48
+#define CLKID_SYS_I2S0M		49
+#define CLKID_SYS_I2S0S		50
+#define CLKID_SYS_I2S1M		51
+#define CLKID_SYS_I2S1S		52
+#define CLKID_SYS_UART0		53
+#define CLKID_SYS_UART1		54
+#define CLKID_SYS_UART2		55
+#define CLKID_SYS_UART3		56
+#define CLKID_SYS_UART4		56
+#define CLKID_SYS_UART5		57
+#define CLKID_SYS_UART6		58
+#define CLKID_SYS_UART7		59
+#define CLKID_SYS_UART8		60
+#define CLKID_SYS_UART9		61
+#define CLKID_SYS_SPI0		62
+#define CLKID_SYS_SPI1		63
+#define CLKID_SYS_QUADSPI	64
+#define CLKID_SYS_SSP0		65
+#define CLKID_SYS_NAND		66
+#define CLKID_SYS_TRACE		67
+#define CLKID_SYS_CAMM		68
+#define CLKID_SYS_WDT		69
+#define CLKID_SYS_CLKOUT	70
+#define CLKID_SYS_MAC		71
+#define CLKID_SYS_LCD		72
+#define CLKID_SYS_ADCANA	73
+
+#define MAX_CLKS		74
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 4/9] ARM: add alphascale,acc.txt bindings documentation
  2014-10-07  8:55 ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
                     ` (2 preceding siblings ...)
  2014-10-07  8:55   ` [PATCH v3 3/9] ARM: dts: add DT for Alphascale ASM9260 SoC Oleksij Rempel
@ 2014-10-07  8:55   ` Oleksij Rempel
  2014-10-07  8:55   ` [PATCH v3 5/9] ARM: clk: add clk-asm9260 driver Oleksij Rempel
                     ` (5 subsequent siblings)
  9 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-10-07  8:55 UTC (permalink / raw)
  To: linux-arm-kernel

ACC is for AlphaScale Clock Controller.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 .../devicetree/bindings/clock/alphascale,acc.txt   | 113 +++++++++++++++++++++
 1 file changed, 113 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/alphascale,acc.txt

diff --git a/Documentation/devicetree/bindings/clock/alphascale,acc.txt b/Documentation/devicetree/bindings/clock/alphascale,acc.txt
new file mode 100644
index 0000000..92a03a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/alphascale,acc.txt
@@ -0,0 +1,113 @@
+Alphascale Clock Controller
+
+The ACC (Alphascale Clock Controller) is responsible of choising proper
+clock source, setting deviders and clock gates.
+
+Required properties for the ACC node:
+- compatible: must be "alphascale,asm9260-clock-controller"
+- reg: must contain the ACC register base and size
+
+ACC allow peripheral clocks to be gated to save some power. The clock consumer
+should specify the desired clock by having the clock ID in it
+"clocks" phandle cell. It is encouraged to use dt-binding for clock ID
+definitions. SoC specific dt-binding should be included to the device tree
+descriptor. For example Alphascale ASM9260:
+#include <dt-bindings/clock/alphascale,asm9260.h>
+
+This binding contains two types of clock sinks: _AHB_ sink - a peripheral
+gate; _SYS_ sink - an adjustable clock source. Not all clock consumer
+have _SYS_ sink. All sink details can be found in the SoC documentation.
+CLKID_AHB_ROM		0
+CLKID_AHB_RAM		1
+CLKID_AHB_GPIO		2
+CLKID_AHB_MAC		3
+CLKID_AHB_EMI		4
+CLKID_AHB_USB0		5
+CLKID_AHB_USB1		6
+CLKID_AHB_DMA0		7
+CLKID_AHB_DMA1		8
+CLKID_AHB_UART0		9
+CLKID_AHB_UART1		10
+CLKID_AHB_UART2		11
+CLKID_AHB_UART3		12
+CLKID_AHB_UART4		13
+CLKID_AHB_UART5		14
+CLKID_AHB_UART6		15
+CLKID_AHB_UART7		16
+CLKID_AHB_UART8		17
+CLKID_AHB_UART9		18
+CLKID_AHB_I2S0		19
+CLKID_AHB_I2C0		20
+CLKID_AHB_I2C1		21
+CLKID_AHB_SSP0		22
+CLKID_AHB_IOCONFIG	23
+CLKID_AHB_WDT		24
+CLKID_AHB_CAN0		25
+CLKID_AHB_CAN1		26
+CLKID_AHB_MPWM		27
+CLKID_AHB_SPI0		28
+CLKID_AHB_SPI1		29
+CLKID_AHB_QEI		30
+CLKID_AHB_QUADSPI0	31
+CLKID_AHB_CAMIF		32
+CLKID_AHB_LCDIF		33
+CLKID_AHB_TIMER0	34
+CLKID_AHB_TIMER1	35
+CLKID_AHB_TIMER2	36
+CLKID_AHB_TIMER3	37
+CLKID_AHB_IRQ		38
+CLKID_AHB_RTC		39
+CLKID_AHB_NAND		40
+CLKID_AHB_ADC0		41
+CLKID_AHB_LED		42
+CLKID_AHB_DAC0		43
+CLKID_AHB_LCD		44
+CLKID_AHB_I2S1		45
+CLKID_AHB_MAC1		46
+
+CLKID_SYS_CPU		47
+CLKID_SYS_AHB		48
+CLKID_SYS_I2S0M		49
+CLKID_SYS_I2S0S		50
+CLKID_SYS_I2S1M		51
+CLKID_SYS_I2S1S		52
+CLKID_SYS_UART0		53
+CLKID_SYS_UART1		54
+CLKID_SYS_UART2		55
+CLKID_SYS_UART3		56
+CLKID_SYS_UART4		56
+CLKID_SYS_UART5		57
+CLKID_SYS_UART6		58
+CLKID_SYS_UART7		59
+CLKID_SYS_UART8		60
+CLKID_SYS_UART9		61
+CLKID_SYS_SPI0		62
+CLKID_SYS_SPI1		63
+CLKID_SYS_QUADSPI	64
+CLKID_SYS_SSP0		65
+CLKID_SYS_NAND		66
+CLKID_SYS_TRACE		67
+CLKID_SYS_CAMM		68
+CLKID_SYS_WDT		69
+CLKID_SYS_CLKOUT	70
+CLKID_SYS_MAC		71
+CLKID_SYS_LCD		72
+CLKID_SYS_ADCANA	73
+
+Example of clock consumer with _SYS_ and _AHB_ sinks.
+uart4: serial at 80010000 {
+	compatible = "alphascale,asm9260-uart";
+	reg = <0x80010000 0x4000>;
+	clocks = <&acc CLKID_SYS_UART4>, <&acc CLKID_AHB_UART4>;
+	interrupts = <19>;
+	status = "disabled";
+};
+
+Clock consumer with only one, _AHB_ sink.
+timer0: timer at 80088000 {
+	compatible = "alphascale,asm9260-timer";
+	reg = <0x80088000 0x4000>;
+	clocks = <&acc CLKID_AHB_TIMER0>;
+	interrupts = <29>;
+};
+
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 5/9] ARM: clk: add clk-asm9260 driver
  2014-10-07  8:55 ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
                     ` (3 preceding siblings ...)
  2014-10-07  8:55   ` [PATCH v3 4/9] ARM: add alphascale,acc.txt bindings documentation Oleksij Rempel
@ 2014-10-07  8:55   ` Oleksij Rempel
  2014-10-07  8:55   ` [PATCH v3 6/9] clocksource: add asm9260_timer driver Oleksij Rempel
                     ` (4 subsequent siblings)
  9 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-10-07  8:55 UTC (permalink / raw)
  To: linux-arm-kernel

Provide CLK support for Alphascale ASM9260 SoC.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/clk/Makefile      |   1 +
 drivers/clk/clk-asm9260.c | 351 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 352 insertions(+)
 create mode 100644 drivers/clk/clk-asm9260.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f537a0b..45bbf22 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_ARCH_HI3xxx)		+= hisilicon/
 obj-$(CONFIG_ARCH_HIP04)		+= hisilicon/
 obj-$(CONFIG_ARCH_HIX5HD2)		+= hisilicon/
 obj-$(CONFIG_COMMON_CLK_KEYSTONE)	+= keystone/
+obj-$(CONFIG_MACH_ASM9260)		+= clk-asm9260.o
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)			+= mmp/
 endif
diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c
new file mode 100644
index 0000000..9ef4e8d
--- /dev/null
+++ b/drivers/clk/clk-asm9260.c
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2014 Oleksij Rempel <linux@rempel-privat.de>.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <dt-bindings/clock/alphascale,asm9260.h>
+
+#define HW_AHBCLKCTRL0		0x0020
+#define HW_AHBCLKCTRL1		0x0030
+#define HW_SYSPLLCTRL		0x0100
+#define HW_MAINCLKSEL		0x0120
+#define HW_MAINCLKUEN		0x0124
+#define HW_UARTCLKSEL		0x0128
+#define HW_UARTCLKUEN		0x012c
+#define HW_I2S0CLKSEL		0x0130
+#define HW_I2S0CLKUEN		0x0134
+#define HW_I2S1CLKSEL		0x0138
+#define HW_I2S1CLKUEN		0x013c
+#define HW_WDTCLKSEL		0x0160
+#define HW_WDTCLKUEN		0x0164
+#define HW_CLKOUTCLKSEL		0x0170
+#define HW_CLKOUTCLKUEN		0x0174
+#define HW_CPUCLKDIV		0x017c
+#define HW_SYSAHBCLKDIV		0x0180
+#define HW_I2S0MCLKDIV		0x0190
+#define HW_I2S0SCLKDIV		0x0194
+#define HW_I2S1MCLKDIV		0x0188
+#define HW_I2S1SCLKDIV		0x018c
+#define HW_UART0CLKDIV		0x0198
+#define HW_UART1CLKDIV		0x019c
+#define HW_UART2CLKDIV		0x01a0
+#define HW_UART3CLKDIV		0x01a4
+#define HW_UART4CLKDIV		0x01a8
+#define HW_UART5CLKDIV		0x01ac
+#define HW_UART6CLKDIV		0x01b0
+#define HW_UART7CLKDIV		0x01b4
+#define HW_UART8CLKDIV		0x01b8
+#define HW_UART9CLKDIV		0x01bc
+#define HW_SPI0CLKDIV		0x01c0
+#define HW_SPI1CLKDIV		0x01c4
+#define HW_QUADSPICLKDIV	0x01c8
+#define HW_SSP0CLKDIV		0x01d0
+#define HW_NANDCLKDIV		0x01d4
+#define HW_TRACECLKDIV		0x01e0
+#define HW_CAMMCLKDIV		0x01e8
+#define HW_WDTCLKDIV		0x01ec
+#define HW_CLKOUTCLKDIV		0x01f4
+#define HW_MACCLKDIV		0x01f8
+#define HW_LCDCLKDIV		0x01fc
+#define HW_ADCANACLKDIV		0x0200
+
+static struct clk *clks[MAX_CLKS];
+static struct clk_onecell_data clk_data;
+static DEFINE_SPINLOCK(asm9260_clk_lock);
+
+struct asm9260_div_clk {
+	unsigned int idx;
+	const char *name;
+	const char *parent_name;
+	u32 reg;
+};
+
+struct asm9260_gate_data {
+	unsigned int idx;
+	const char *name;
+	const char *parent_name;
+	u32 reg;
+	u8 bit_idx;
+	unsigned long flags;
+};
+
+struct asm9260_mux_clock {
+	u8			mask;
+	u32			*table;
+	const char		*name;
+	const char		**parent_names;
+	u8			num_parents;
+	unsigned long		offset;
+	unsigned long		flags;
+};
+
+static void __iomem *base;
+
+enum {
+	REFCLK, SYSPLL, I2S0_MCLK, I2S1_MCLK, RTC_OSC, USB_PLL,
+};
+
+static const char *clk_names[] = {
+	[REFCLK]	= "oscillator",
+	[SYSPLL]	= "pll",
+	[I2S0_MCLK]	= "i2s0_mclk",
+	[I2S1_MCLK]	= "i2s1_mclk",
+	[RTC_OSC]	= "rtc_osc",
+	[USB_PLL]	= "usb_pll",
+};
+
+static const struct asm9260_div_clk asm9260_div_clks[] __initconst = {
+	{ CLKID_SYS_CPU,	"cpu_div", "main_gate", HW_CPUCLKDIV },
+	{ CLKID_SYS_AHB,	"ahb_div", "cpu_div", HW_SYSAHBCLKDIV },
+
+	/* i2s has two deviders: one for only external mclk and internal
+	 * devider for all clks. */
+	{ CLKID_SYS_I2S0M,	"i2s0m_div", "i2s0_mclk",  HW_I2S0MCLKDIV },
+	{ CLKID_SYS_I2S1M,	"i2s1m_div", "i2s1_mclk",  HW_I2S1MCLKDIV },
+	{ CLKID_SYS_I2S0S,	"i2s0s_div", "i2s0_gate",  HW_I2S0SCLKDIV },
+	{ CLKID_SYS_I2S1S,	"i2s1s_div", "i2s0_gate",  HW_I2S1SCLKDIV },
+
+	{ CLKID_SYS_UART0,	"uart0_div", "uart_gate", HW_UART0CLKDIV },
+	{ CLKID_SYS_UART1,	"uart1_div", "uart_gate", HW_UART1CLKDIV },
+	{ CLKID_SYS_UART2,	"uart2_div", "uart_gate", HW_UART2CLKDIV },
+	{ CLKID_SYS_UART3,	"uart3_div", "uart_gate", HW_UART3CLKDIV },
+	{ CLKID_SYS_UART4,	"uart4_div", "uart_gate", HW_UART4CLKDIV },
+	{ CLKID_SYS_UART5,	"uart5_div", "uart_gate", HW_UART5CLKDIV },
+	{ CLKID_SYS_UART6,	"uart6_div", "uart_gate", HW_UART6CLKDIV },
+	{ CLKID_SYS_UART7,	"uart7_div", "uart_gate", HW_UART7CLKDIV },
+	{ CLKID_SYS_UART8,	"uart8_div", "uart_gate", HW_UART8CLKDIV },
+	{ CLKID_SYS_UART9,	"uart9_div", "uart_gate", HW_UART9CLKDIV },
+};
+
+static const struct asm9260_gate_data asm9260_mux_gates[] __initconst = {
+	{ 0, "main_gate",	"main_mux",	HW_MAINCLKUEN,	0 },
+	{ 0, "uart_gate",	"uart_mux",	HW_UARTCLKUEN,	0 },
+	{ 0, "i2s0_gate",	"i2s0_mux",	HW_I2S0CLKUEN,	0 },
+	{ 0, "i2s1_gate",	"i2s1_mux",	HW_I2S1CLKUEN,	0 },
+	{ 0, "wdt_gate",	"wdt_mux",	HW_WDTCLKUEN,	0 },
+	{ 0, "clkout_gate",	"clkout_mux",	HW_CLKOUTCLKUEN, 0 },
+};
+static const struct asm9260_gate_data asm9260_ahb_gates[] __initconst = {
+	/* ahb gates */
+	{ CLKID_AHB_ROM,	"rom",		"ahb_div",
+		HW_AHBCLKCTRL0,	1, CLK_IGNORE_UNUSED},
+	{ CLKID_AHB_RAM,	"ram",		"ahb_div",
+		HW_AHBCLKCTRL0,	2, CLK_IGNORE_UNUSED},
+	{ CLKID_AHB_GPIO,	"gpio",		"ahb_div",
+		HW_AHBCLKCTRL0,	4 },
+	{ CLKID_AHB_MAC,	"mac",		"ahb_div",
+		HW_AHBCLKCTRL0,	5 },
+	{ CLKID_AHB_EMI,	"emi",		"ahb_div",
+		HW_AHBCLKCTRL0,	6, CLK_IGNORE_UNUSED},
+	{ CLKID_AHB_USB0,	"usb0",		"ahb_div",
+		HW_AHBCLKCTRL0,	7 },
+	{ CLKID_AHB_USB1,	"usb1",		"ahb_div",
+		HW_AHBCLKCTRL0,	8 },
+	{ CLKID_AHB_DMA0,	"dma0",		"ahb_div",
+		HW_AHBCLKCTRL0,	9 },
+	{ CLKID_AHB_DMA1,	"dma1",		"ahb_div",
+		HW_AHBCLKCTRL0,	10 },
+	{ CLKID_AHB_UART0,	"uart0",	"ahb_div",
+		HW_AHBCLKCTRL0,	11 },
+	{ CLKID_AHB_UART1,	"uart1",	"ahb_div",
+		HW_AHBCLKCTRL0,	12 },
+	{ CLKID_AHB_UART2,	"uart2",	"ahb_div",
+		HW_AHBCLKCTRL0,	13 },
+	{ CLKID_AHB_UART3,	"uart3",	"ahb_div",
+		HW_AHBCLKCTRL0,	14 },
+	{ CLKID_AHB_UART4,	"uart4",	"ahb_div",
+		HW_AHBCLKCTRL0,	15 },
+	{ CLKID_AHB_UART5,	"uart5",	"ahb_div",
+		HW_AHBCLKCTRL0,	16 },
+	{ CLKID_AHB_UART6,	"uart6",	"ahb_div",
+		HW_AHBCLKCTRL0,	17 },
+	{ CLKID_AHB_UART7,	"uart7",	"ahb_div",
+		HW_AHBCLKCTRL0,	18 },
+	{ CLKID_AHB_UART8,	"uart8",	"ahb_div",
+		HW_AHBCLKCTRL0,	19 },
+	{ CLKID_AHB_UART9,	"uart9",	"ahb_div",
+		HW_AHBCLKCTRL0,	20 },
+	{ CLKID_AHB_I2S0,	"i2s0",		"ahb_div",
+		HW_AHBCLKCTRL0,	21 },
+	{ CLKID_AHB_I2C0,	"i2c0",		"ahb_div",
+		HW_AHBCLKCTRL0,	22 },
+	{ CLKID_AHB_I2C1,	"i2c1",		"ahb_div",
+		HW_AHBCLKCTRL0,	23 },
+	{ CLKID_AHB_SSP0,	"ssp0",		"ahb_div",
+		HW_AHBCLKCTRL0,	24 },
+	{ CLKID_AHB_IOCONFIG,	"ioconf",	"ahb_div",
+		HW_AHBCLKCTRL0,	25 },
+	{ CLKID_AHB_WDT,	"wdt",		"ahb_div",
+		HW_AHBCLKCTRL0,	26 },
+	{ CLKID_AHB_CAN0,	"can0",		"ahb_div",
+		HW_AHBCLKCTRL0,	27 },
+	{ CLKID_AHB_CAN1,	"can1",		"ahb_div",
+		HW_AHBCLKCTRL0,	28 },
+	{ CLKID_AHB_MPWM,	"mpwm",		"ahb_div",
+		HW_AHBCLKCTRL0,	29 },
+	{ CLKID_AHB_SPI0,	"spi0",		"ahb_div",
+		HW_AHBCLKCTRL0,	30 },
+	{ CLKID_AHB_SPI1,	"spi1",		"ahb_div",
+		HW_AHBCLKCTRL0,	31 },
+
+	{ CLKID_AHB_QEI,	"qei",		"ahb_div",
+		HW_AHBCLKCTRL1,	0 },
+	{ CLKID_AHB_QUADSPI0,	"quadspi0",	"ahb_div",
+		HW_AHBCLKCTRL1,	1 },
+	{ CLKID_AHB_CAMIF,	"capmif",	"ahb_div",
+		HW_AHBCLKCTRL1,	2 },
+	{ CLKID_AHB_LCDIF,	"lcdif",	"ahb_div",
+		HW_AHBCLKCTRL1,	3 },
+	{ CLKID_AHB_TIMER0,	"timer0",	"ahb_div",
+		HW_AHBCLKCTRL1,	4 },
+	{ CLKID_AHB_TIMER1,	"timer1",	"ahb_div",
+		HW_AHBCLKCTRL1,	5 },
+	{ CLKID_AHB_TIMER2,	"timer2",	"ahb_div",
+		HW_AHBCLKCTRL1,	6 },
+	{ CLKID_AHB_TIMER3,	"timer3",	"ahb_div",
+		HW_AHBCLKCTRL1,	7 },
+	{ CLKID_AHB_IRQ,	"irq",		"ahb_div",
+		HW_AHBCLKCTRL1,	8, CLK_IGNORE_UNUSED},
+	{ CLKID_AHB_RTC,	"rtc",		"ahb_div",
+		HW_AHBCLKCTRL1,	9 },
+	{ CLKID_AHB_NAND,	"nand",		"ahb_div",
+		HW_AHBCLKCTRL1,	10 },
+	{ CLKID_AHB_ADC0,	"adc0",		"ahb_div",
+		HW_AHBCLKCTRL1,	11 },
+	{ CLKID_AHB_LED,	"led",		"ahb_div",
+		HW_AHBCLKCTRL1,	12 },
+	{ CLKID_AHB_DAC0,	"dac0",		"ahb_div",
+		HW_AHBCLKCTRL1,	13 },
+	{ CLKID_AHB_LCD,	"lcd",		"ahb_div",
+		HW_AHBCLKCTRL1,	14 },
+	{ CLKID_AHB_I2S1,	"i2s1",		"ahb_div",
+		HW_AHBCLKCTRL1,	15 },
+	{ CLKID_AHB_MAC1,	"mac1",		"ahb_div",
+		HW_AHBCLKCTRL1,	16 },
+};
+
+static const char __initdata *main_mux_p[] = {"oscillator", "pll"};
+static const char __initdata *i2s0_mux_p[] = {"oscillator", "pll", "i2s0m_div"};
+static const char __initdata *i2s1_mux_p[] = {"oscillator", "pll", "i2s1m_div"};
+static const char __initdata *clkout_mux_p[] = {"oscillator", "pll", "rtc"};
+static u32 three_mux_table[] = {0, 1, 3};
+
+static struct asm9260_mux_clock asm9260_mux_clks[] __initdata = {
+	{ 1, three_mux_table, "main_mux",	main_mux_p,
+		ARRAY_SIZE(main_mux_p), HW_MAINCLKSEL, },
+	{ 1, three_mux_table, "uart_mux",	main_mux_p,
+		ARRAY_SIZE(main_mux_p), HW_UARTCLKSEL, },
+	{ 1, three_mux_table, "wdt_mux",	main_mux_p,
+		ARRAY_SIZE(main_mux_p), HW_WDTCLKSEL, },
+	{ 3, three_mux_table, "i2s0_mux",	i2s0_mux_p,
+		ARRAY_SIZE(i2s0_mux_p), HW_I2S0CLKSEL, },
+	{ 3, three_mux_table, "i2s1_mux",	i2s1_mux_p,
+		ARRAY_SIZE(i2s1_mux_p), HW_I2S1CLKSEL, },
+	{ 3, three_mux_table, "clkout_mux",	clkout_mux_p,
+		ARRAY_SIZE(clkout_mux_p), HW_CLKOUTCLKSEL, },
+};
+
+static void __init asm9260_acc_init(struct device_node *np)
+{
+	struct clk *clk;
+	struct resource res;
+	u32 rate;
+	int n;
+	u32 accuracy = 0;
+
+	of_address_to_resource(np, 0, &res);
+	if (!request_mem_region(res.start, resource_size(&res), np->name))
+		panic("%s: unable to request mem region", np->name);
+
+	base = ioremap_nocache(res.start, resource_size(&res));
+	if (!base)
+		panic("%s: unable to map resource", np->name);
+
+
+	/* register pll */
+	rate = (ioread32(base + HW_SYSPLLCTRL) & 0xffff) * 1000000;
+
+	clk_names[REFCLK] = of_clk_get_parent_name(np, 0);
+	accuracy = clk_get_accuracy(__clk_lookup(clk_names[REFCLK]));
+	clk = clk_register_fixed_rate_with_accuracy(NULL, clk_names[SYSPLL],
+			clk_names[REFCLK], 0, rate, accuracy);
+
+	if (IS_ERR(clk))
+		panic("%s: can't register REFCLK. Check DT!", np->name);
+
+	for (n = 0; n < ARRAY_SIZE(asm9260_mux_clks); n++) {
+		const struct asm9260_mux_clock *mc = &asm9260_mux_clks[n];
+
+		mc->parent_names[0] = clk_names[REFCLK];
+		clk = clk_register_mux_table(NULL, mc->name, mc->parent_names,
+				mc->num_parents, mc->flags, base + mc->offset,
+				0, mc->mask, 0, mc->table, &asm9260_clk_lock);
+	}
+
+	/* clock mux gate cells */
+	for (n = 0; n < ARRAY_SIZE(asm9260_mux_gates); n++) {
+		const struct asm9260_gate_data *gd = &asm9260_mux_gates[n];
+
+		clk = clk_register_gate(NULL, gd->name,
+			gd->parent_name, gd->flags | CLK_SET_RATE_PARENT,
+			base + gd->reg, gd->bit_idx, 0, &asm9260_clk_lock);
+	}
+
+	/* clock div cells */
+	for (n = 0; n < ARRAY_SIZE(asm9260_div_clks); n++) {
+		const struct asm9260_div_clk *dc = &asm9260_div_clks[n];
+
+		clks[dc->idx] = clk_register_divider(NULL, dc->name,
+				dc->parent_name, CLK_SET_RATE_PARENT,
+				base + dc->reg, 0, 8, CLK_DIVIDER_ONE_BASED,
+				&asm9260_clk_lock);
+	}
+
+	/* clock ahb gate cells */
+	for (n = 0; n < ARRAY_SIZE(asm9260_ahb_gates); n++) {
+		const struct asm9260_gate_data *gd = &asm9260_ahb_gates[n];
+
+		clks[gd->idx] = clk_register_gate(NULL, gd->name,
+				gd->parent_name, gd->flags, base + gd->reg,
+				gd->bit_idx, 0, &asm9260_clk_lock);
+	}
+
+	/* check for errors on leaf clocks */
+	for (n = 0; n < MAX_CLKS; n++) {
+		if (!IS_ERR(clks[n]))
+			continue;
+
+		pr_err("%s: Unable to register leaf clock %d\n",
+				np->full_name, n);
+		goto fail;
+	}
+
+	/* register clk-provider */
+	clk_data.clks = clks;
+	clk_data.clk_num = MAX_CLKS;
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+	return;
+fail:
+	iounmap(base);
+}
+CLK_OF_DECLARE(asm9260_acc, "alphascale,asm9260-clock-controller",
+		asm9260_acc_init);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 6/9] clocksource: add asm9260_timer driver
  2014-10-07  8:55 ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
                     ` (4 preceding siblings ...)
  2014-10-07  8:55   ` [PATCH v3 5/9] ARM: clk: add clk-asm9260 driver Oleksij Rempel
@ 2014-10-07  8:55   ` Oleksij Rempel
  2014-10-07  8:55   ` [PATCH v3 7/9] irqchip/irq-mxs.c: add asm9260 support Oleksij Rempel
                     ` (3 subsequent siblings)
  9 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-10-07  8:55 UTC (permalink / raw)
  To: linux-arm-kernel

In some cases asm9260 looks similar to iMX2x. One of exceptions is
timer controller. So this patch introduces new driver for this special case.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/clocksource/Kconfig         |   4 +
 drivers/clocksource/Makefile        |   1 +
 drivers/clocksource/asm9260_timer.c | 234 ++++++++++++++++++++++++++++++++++++
 3 files changed, 239 insertions(+)
 create mode 100644 drivers/clocksource/asm9260_timer.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cfd6519..6a03d34 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -216,4 +216,8 @@ config CLKSRC_VERSATILE
 	  ARM Versatile, RealView and Versatile Express reference
 	  platforms.
 
+config ASM9260_TIMER
+	select CLKSRC_MMIO
+	bool
+
 endmenu
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 7fd9fd1..fc93854 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -44,3 +44,4 @@ obj-$(CONFIG_CLKSRC_METAG_GENERIC)	+= metag_generic.o
 obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST)	+= dummy_timer.o
 obj-$(CONFIG_ARCH_KEYSTONE)		+= timer-keystone.o
 obj-$(CONFIG_CLKSRC_VERSATILE)		+= versatile.o
+obj-$(CONFIG_ASM9260_TIMER)		+= asm9260_timer.o
diff --git a/drivers/clocksource/asm9260_timer.c b/drivers/clocksource/asm9260_timer.c
new file mode 100644
index 0000000..1b16e00
--- /dev/null
+++ b/drivers/clocksource/asm9260_timer.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/clk.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/bitops.h>
+
+
+/*
+ * this device provide 4 offsets for each register:
+ * 0x0 - plain read write mode
+ * 0x4 - set mode, OR logic.
+ * 0x8 - clr mode, XOR logic.
+ * 0xc - togle mode.
+ */
+#define SET_REG 4
+#define CLR_REG 8
+
+#define HW_IR           0x0000 /* RW. Interrupt */
+#define BM_IR_CR0	BIT(4)
+#define BM_IR_MR3	BIT(3)
+#define BM_IR_MR2	BIT(2)
+#define BM_IR_MR1	BIT(1)
+#define BM_IR_MR0	BIT(0)
+
+#define HW_TCR		0x0010 /* RW. Timer controller */
+/* BM_C*_RST
+ * Timer Counter and the Prescale Counter are synchronously reset on the
+ * next positive edge of PCLK. The counters remain reset until TCR[1] is
+ * returned to zero. */
+#define BM_C3_RST	BIT(7)
+#define BM_C2_RST	BIT(6)
+#define BM_C1_RST	BIT(5)
+#define BM_C0_RST	BIT(4)
+/* BM_C*_EN
+ * 1 - Timer Counter and Prescale Counter are enabled for counting
+ * 0 - counters are disabled */
+#define BM_C3_EN	BIT(3)
+#define BM_C2_EN	BIT(2)
+#define BM_C1_EN	BIT(1)
+#define BM_C0_EN	BIT(0)
+
+#define HW_DIR		0x0020 /* RW. Direction? */
+/* 00 - count up
+ * 01 - count down
+ * 10 - ?? 2^n/2 */
+#define BM_DIR0_SHIFT	0
+#define BM_DIR1_SHIFT	4
+#define BM_DIR2_SHIFT	8
+#define BM_DIR3_SHIFT	12
+
+#define HW_TC0		0x0030 /* RO. Timer counter 0 */
+/* HW_TC*. Timer counter owerflow (0xffff.ffff to 0x0000.0000) do not generate
+ * interrupt. This registers can be used to detect overflow */
+#define HW_TC1          0x0040
+#define HW_TC2		0x0050
+#define HW_TC3		0x0060
+
+#define HW_PR		0x0070 /* RW. prescaler */
+#define HW_PC		0x0080 /* RO. Prescaler counter */
+#define HW_MCR		0x0090 /* RW. Match control */
+/* enable interrupt on match */
+#define BM_MCR_INT_EN(n)	(1 << (n * 3 + 0))
+/* enable TC reset on match */
+#define BM_MCR_RES_EN(n)	(1 << (n * 3 + 1))
+/* enable stop TC on match */
+#define BM_MCR_STOP_EN(n)	(1 << (n * 3 + 2))
+
+#define HW_MR0		0x00a0 /* RW. Match reg */
+#define HW_MR1		0x00b0
+#define HW_MR2		0x00C0
+#define HW_MR3		0x00D0
+#define HW_CCR		0x00E0 /* RW. Capture control */
+#define HW_CR0		0x00F0 /* RO. Capture reg */
+#define HW_CR1		0x0100
+#define HW_CR2		0x0110
+#define HW_CR3		0x0120
+#define HW_EMR		0x0130 /* RW. External Match */
+#define HW_PWMTH0	0x0140 /* RW. PWM width */
+#define HW_PWMTH1	0x0150
+#define HW_PWMTH2	0x0160
+#define HW_PWMTH3	0x0170
+#define HW_CTCR		0x0180 /* Counter control */
+#define HW_PWMC		0x0190 /* PWM control */
+
+static void __iomem *base;
+static unsigned long ticks_per_jiffy;
+
+static int asm9260_timer_set_next_event(unsigned long delta,
+					 struct clock_event_device *dev)
+{
+	/* configure match count for TC0 */
+	writel_relaxed(delta, base + HW_MR0);
+	/* enable TC0 */
+	writel_relaxed(BM_C0_EN, base + HW_TCR + SET_REG);
+	return 0;
+}
+
+static void asm9260_timer_set_mode(enum clock_event_mode mode,
+				    struct clock_event_device *evt)
+{
+	/* stop timer0 */
+	writel_relaxed(BM_C0_EN, base + HW_TCR + CLR_REG);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		/* disable reset and stop on match */
+		writel_relaxed(BM_MCR_RES_EN(0) | BM_MCR_STOP_EN(0),
+				base + HW_MCR + CLR_REG);
+		/* configure match count for TC0 */
+		writel_relaxed(ticks_per_jiffy, base + HW_MR0);
+		/* enable TC0 */
+		writel_relaxed(BM_C0_EN, base + HW_TCR + SET_REG);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* enable reset and stop on match */
+		writel_relaxed(BM_MCR_RES_EN(0) | BM_MCR_STOP_EN(0),
+				base + HW_MCR + SET_REG);
+		break;
+	default:
+		break;
+	}
+}
+
+static struct clock_event_device asm9260_clockevent_device = {
+	.name		= "asm9260-clockevent-dev",
+	.rating		= 200,
+	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_next_event	= asm9260_timer_set_next_event,
+	.set_mode	= asm9260_timer_set_mode,
+};
+
+static irqreturn_t asm9260_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &asm9260_clockevent_device;
+
+	evt->event_handler(evt);
+
+	writel_relaxed(BM_IR_MR0, base + HW_IR);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction asm9260_timer_irq = {
+	.name		= "asm9260-clockevent-dev",
+	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= asm9260_timer_interrupt,
+};
+
+/*
+ * ---------------------------------------------------------------------------
+ * Timer initialization
+ * ---------------------------------------------------------------------------
+ */
+
+static void __init asm9260_clockevent_init(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk);
+
+	ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ);
+	asm9260_clockevent_device.cpumask = cpumask_of(0);
+	clockevents_config_and_register(&asm9260_clockevent_device,
+					rate, 0x2c00, 0xfffffffe);
+}
+
+static void __init asm9260_clocksource_init(struct clk *clk)
+{
+	unsigned long hz = clk_get_rate(clk);
+
+	clocksource_mmio_init(base + HW_TC1,
+			"asm9260-clocksource", hz,
+			200, 32, clocksource_mmio_readl_up);
+
+	/* Seems like we can't use counter without match register even if
+	 * actions for MR are disabled. */
+	writel_relaxed(0xffffffff, base + HW_MR1);
+	/* enable TC1 */
+	writel_relaxed(BM_C1_EN, base + HW_TCR + SET_REG);
+}
+
+static void __init asm9260_timer_init(struct device_node *np)
+{
+	int irq;
+	struct clk *clk;
+	struct resource res;
+	int ret;
+
+	of_address_to_resource(np, 0, &res);
+	if (!request_mem_region(res.start, resource_size(&res),
+				"asm9260-timer"))
+		panic("%s: unable to request mem region", np->name);
+
+	base = ioremap_nocache(res.start, resource_size(&res));
+	if (!base)
+		panic("%s: unable to map resource", np->name);
+
+	clk = of_clk_get(np, 0);
+
+	ret = clk_prepare_enable(clk);
+	if (ret)
+		panic("Failed to enable clk!\n");
+
+	irq = irq_of_parse_and_map(np, 0);
+	setup_irq(irq, &asm9260_timer_irq);
+
+	/* set all timers for count-up */
+	writel_relaxed(0, base + HW_DIR);
+	/* disable divider */
+	writel_relaxed(0, base + HW_PR);
+	/* make sure all timers use every rising PCLK edge. */
+	writel_relaxed(0, base + HW_CTCR);
+	/* enable interrupt for TC0 and clean setting for all other lines */
+	writel_relaxed(BM_MCR_INT_EN(0) , base + HW_MCR);
+
+	asm9260_clocksource_init(clk);
+	asm9260_clockevent_init(clk);
+}
+CLOCKSOURCE_OF_DECLARE(asm9260_timer, "alphascale,asm9260-timer",
+		asm9260_timer_init);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 7/9] irqchip/irq-mxs.c: add asm9260 support
  2014-10-07  8:55 ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
                     ` (5 preceding siblings ...)
  2014-10-07  8:55   ` [PATCH v3 6/9] clocksource: add asm9260_timer driver Oleksij Rempel
@ 2014-10-07  8:55   ` Oleksij Rempel
  2014-10-08  7:45     ` Thomas Gleixner
  2014-10-07  8:55   ` [PATCH v3 8/9] tty/serial/mxs-auart.c: add initial Alphascale " Oleksij Rempel
                     ` (2 subsequent siblings)
  9 siblings, 1 reply; 43+ messages in thread
From: Oleksij Rempel @ 2014-10-07  8:55 UTC (permalink / raw)
  To: linux-arm-kernel

iMX23/iMX28 have similar but not identical interrupt collector with asm9260.
This patch provide some changes to reuse same code for both controller types.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/irqchip/Kconfig                    |   5 +
 drivers/irqchip/Makefile                   |   2 +-
 drivers/irqchip/alphascale,asm9260-icoll.h | 109 ++++++++++++++++++++++
 drivers/irqchip/irq-mxs.c                  | 142 +++++++++++++++++++++++++----
 4 files changed, 241 insertions(+), 17 deletions(-)
 create mode 100644 drivers/irqchip/alphascale,asm9260-icoll.h

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index b8632bf..2ee202f 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -113,3 +113,8 @@ config IRQ_CROSSBAR
 	  The primary irqchip invokes the crossbar's callback which inturn allocates
 	  a free irq and configures the IP. Thus the peripheral interrupts are
 	  routed to one of the free irqchip interrupt lines.
+
+config IRQ_MXS
+	bool
+	select IRQ_DOMAIN
+	select STMP_DEVICE
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 73052ba..89c7042 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -4,7 +4,7 @@ obj-$(CONFIG_ARCH_BCM2835)		+= irq-bcm2835.o
 obj-$(CONFIG_ARCH_EXYNOS)		+= exynos-combiner.o
 obj-$(CONFIG_ARCH_MMP)			+= irq-mmp.o
 obj-$(CONFIG_ARCH_MVEBU)		+= irq-armada-370-xp.o
-obj-$(CONFIG_ARCH_MXS)			+= irq-mxs.o
+obj-$(CONFIG_IRQ_MXS)			+= irq-mxs.o
 obj-$(CONFIG_ARCH_S3C24XX)		+= irq-s3c24xx.o
 obj-$(CONFIG_DW_APB_ICTL)		+= irq-dw-apb-ictl.o
 obj-$(CONFIG_METAG)			+= irq-metag-ext.o
diff --git a/drivers/irqchip/alphascale,asm9260-icoll.h b/drivers/irqchip/alphascale,asm9260-icoll.h
new file mode 100644
index 0000000..5cec108
--- /dev/null
+++ b/drivers/irqchip/alphascale,asm9260-icoll.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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.
+ */
+
+#ifndef _ALPHASCALE_ASM9260_ICOLL_H
+#define _ALPHASCALE_ASM9260_ICOLL_H
+
+#define ASM9260_NUM_IRQS		64
+/*
+ * this device provide 4 offsets for each register:
+ * 0x0 - plain read write mode
+ * 0x4 - set mode, OR logic.
+ * 0x8 - clr mode, XOR logic.
+ * 0xc - togle mode.
+ */
+
+#define ASM9260_HW_ICOLL_VECTOR				0x0000
+/*
+ * bits 31:2
+ * This register presents the vector address for the interrupt currently
+ * active on the CPU IRQ input. Writing to this register notifies the
+ * interrupt collector that the interrupt service routine for the current
+ * interrupt has been entered.
+ * The exception trap should have a LDPC instruction from this address:
+ * LDPC ASM9260_HW_ICOLL_VECTOR_ADDR; IRQ exception at 0xffff0018
+ */
+
+/*
+ * The Interrupt Collector Level Acknowledge Register is used by software to
+ * indicate the completion of an interrupt on a specific level.
+ * This register is written at the very end of an interrupt service routine. If
+ * nesting is used then the CPU irq must be turned on before writing to this
+ * register to avoid a race condition in the CPU interrupt hardware.
+ */
+#define ASM9260_HW_ICOLL_LEVELACK			0x0010
+#define ASM9260_BM_LEVELn(nr)				BIT(nr)
+
+#define ASM9260_HW_ICOLL_CTRL				0x0020
+/*
+ * ASM9260_BM_CTRL_SFTRST and ASM9260_BM_CTRL_CLKGATE are not available on
+ * asm9260.
+ */
+#define ASM9260_BM_CTRL_SFTRST				BIT(31)
+#define ASM9260_BM_CTRL_CLKGATE				BIT(30)
+/* disable interrupt level nesting */
+#define ASM9260_BM_CTRL_NO_NESTING			BIT(19)
+/*
+ * Set this bit to one enable the RISC32-style read side effect associated with
+ * the vector address register. In this mode, interrupt in-service is signaled
+ * by the read of the ASM9260_HW_ICOLL_VECTOR register to acquire the interrupt
+ * vector address. Set this bit to zero for normal operation, in which the ISR
+ * signals in-service explicitly by means of a write to the
+ * ASM9260_HW_ICOLL_VECTOR register.
+ * 0 - Must Write to Vector register to go in-service.
+ * 1 - Go in-service as a read side effect
+ */
+#define ASM9260_BM_CTRL_ARM_RSE_MODE			BIT(18)
+#define ASM9260_BM_CTRL_IRQ_ENABLE			BIT(16)
+
+#define ASM9260_HW_ICOLL_STAT_OFFSET			0x0030
+/*
+ * bits 5:0
+ * Vector number of current interrupt. Multiply by 4 and add to vector base
+ * address to obtain the value in ASM9260_HW_ICOLL_VECTOR.
+ */
+
+/*
+ * RAW0 and RAW1 provides a read-only view of the raw interrupt request lines
+ * coming from various parts of the chip. Its purpose is to improve diagnostic
+ * observability.
+ */
+#define ASM9260_HW_ICOLL_RAW0				0x0040
+#define ASM9260_HW_ICOLL_RAW1				0x0050
+
+#define ASM9260_HW_ICOLL_INTERRUPT0			0x0060
+#define ASM9260_HW_ICOLL_INTERRUPTn(n)		(0x0060 + ((n) >> 2) * 0x10)
+/*
+ * WARNING: Modifying the priority of an enabled interrupt may result in
+ * undefined behavior.
+ */
+#define ASM9260_BM_INT_PRIORITY_MASK			0x3
+#define ASM9260_BM_INT_ENABLE				BIT(2)
+#define ASM9260_BM_INT_SOFTIRQ				BIT(3)
+
+#define ASM9260_BM_ICOLL_INTERRUPTn_SHIFT(n)		(((n) & 0x3) << 3)
+#define ASM9260_BM_ICOLL_INTERRUPTn_ENABLE(n)		(1 << (2 + \
+			ASM9260_BM_ICOLL_INTERRUPTn_SHIFT(n)))
+
+#define ASM9260_HW_ICOLL_VBASE				0x0160
+/*
+ * bits 31:2
+ * This bitfield holds the upper 30 bits of the base address of the vector
+ * table.
+ */
+
+#define ASM9260_HW_ICOLL_CLEAR0				0x01d0
+#define ASM9260_HW_ICOLL_CLEAR1				0x01e0
+#define ASM9260_HW_ICOLL_CLEARn(n)			(((n >> 5) * 0x10) \
+							+ SET_REG)
+#define ASM9260_BM_CLEAR_BIT(n)				BIT(n & 0x1f)
+
+/* Scratchpad */
+#define ASM9260_HW_ICOLL_UNDEF_VECTOR			0x01f0
+#endif
diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c
index e4acf1e..b5e0358 100644
--- a/drivers/irqchip/irq-mxs.c
+++ b/drivers/irqchip/irq-mxs.c
@@ -1,5 +1,7 @@
 /*
  * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *	Add Alphascale ASM9260 support.
  *
  * 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
@@ -18,6 +20,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/err.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/io.h>
@@ -28,21 +31,55 @@
 #include <asm/exception.h>
 
 #include "irqchip.h"
+#include "alphascale,asm9260-icoll.h"
+
+/*
+ * this device provide 4 offsets for each register:
+ * 0x0 - plain read write mode
+ * 0x4 - set mode, OR logic.
+ * 0x8 - clr mode, XOR logic.
+ * 0xc - togle mode.
+ */
+#define SET_REG 4
+#define CLR_REG 8
 
 #define HW_ICOLL_VECTOR				0x0000
 #define HW_ICOLL_LEVELACK			0x0010
 #define HW_ICOLL_CTRL				0x0020
 #define HW_ICOLL_STAT_OFFSET			0x0070
-#define HW_ICOLL_INTERRUPTn_SET(n)		(0x0124 + (n) * 0x10)
-#define HW_ICOLL_INTERRUPTn_CLR(n)		(0x0128 + (n) * 0x10)
-#define BM_ICOLL_INTERRUPTn_ENABLE		0x00000004
+#define HW_ICOLL_INTERRUPT0			0x0120
+#define HW_ICOLL_INTERRUPTn(n)			((n) * 0x10)
+#define BM_ICOLL_INTR_ENABLE			BIT(2)
 #define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0	0x1
 
 #define ICOLL_NUM_IRQS		128
 
-static void __iomem *icoll_base;
+struct icoll_priv {
+	void __iomem *vector;
+	void __iomem *levelack;
+	void __iomem *ctrl;
+	void __iomem *stat;
+	void __iomem *intr;
+	/* number of interrupts per register */
+	int intr_reg_num;
+	void __iomem *clear;
+};
+
+struct icoll_priv icoll_priv;
 static struct irq_domain *icoll_domain;
 
+static u32 icoll_intr_bitshift(struct irq_data *d, u32 bit)
+{
+	int n = icoll_priv.intr_reg_num - 1;
+	return bit << ((d->hwirq & n) << n);
+}
+
+static void __iomem *icoll_intr_reg(struct irq_data *d)
+{
+	int n = icoll_priv.intr_reg_num;
+	return icoll_priv.intr + ((d->hwirq / n) * 0x10);
+}
+
 static void icoll_ack_irq(struct irq_data *d)
 {
 	/*
@@ -51,19 +88,25 @@ static void icoll_ack_irq(struct irq_data *d)
 	 * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.
 	 */
 	__raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
-			icoll_base + HW_ICOLL_LEVELACK);
+			icoll_priv.levelack);
 }
 
 static void icoll_mask_irq(struct irq_data *d)
 {
-	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
-			icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->hwirq));
+	__raw_writel(icoll_intr_bitshift(d, BM_ICOLL_INTR_ENABLE),
+			icoll_intr_reg(d) + CLR_REG);
 }
 
 static void icoll_unmask_irq(struct irq_data *d)
 {
-	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
-			icoll_base + HW_ICOLL_INTERRUPTn_SET(d->hwirq));
+	if (!IS_ERR(icoll_priv.clear)) {
+		__raw_writel(ASM9260_BM_CLEAR_BIT(d->hwirq),
+				icoll_priv.clear +
+				ASM9260_HW_ICOLL_CLEARn(d->hwirq));
+	}
+
+	__raw_writel(icoll_intr_bitshift(d, BM_ICOLL_INTR_ENABLE),
+			icoll_intr_reg(d) + SET_REG);
 }
 
 static struct irq_chip mxs_icoll_chip = {
@@ -76,8 +119,8 @@ asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
 {
 	u32 irqnr;
 
-	irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET);
-	__raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR);
+	irqnr = __raw_readl(icoll_priv.stat);
+	__raw_writel(irqnr, icoll_priv.vector);
 	handle_domain_irq(icoll_domain, irqnr, regs);
 }
 
@@ -95,20 +138,87 @@ static struct irq_domain_ops icoll_irq_domain_ops = {
 	.xlate = irq_domain_xlate_onecell,
 };
 
+static void __init icoll_add_domain(struct device_node *np,
+			  int num)
+{
+	icoll_domain = irq_domain_add_linear(np, num,
+					     &icoll_irq_domain_ops, NULL);
+
+	if (!icoll_domain)
+		panic("%s: unable add irq domain", np->full_name);
+	irq_set_default_host(icoll_domain);
+	set_handle_irq(icoll_handle_irq);
+}
+
+static void __iomem * __init icoll_init_iobase(struct device_node *np)
+{
+	struct resource res;
+	void __iomem *icoll_base;
+
+	if (of_address_to_resource(np, 0, &res))
+		panic("%s: unable to get resource", np->full_name);
+
+	if (!request_mem_region(res.start, resource_size(&res), np->name))
+		panic("%s: unable to request mem region", np->full_name);
+
+	icoll_base = ioremap_nocache(res.start, resource_size(&res));
+	if (!icoll_base)
+		panic("%s: unable to map resource", np->full_name);
+	return icoll_base;
+}
+
 static int __init icoll_of_init(struct device_node *np,
 			  struct device_node *interrupt_parent)
 {
-	icoll_base = of_iomap(np, 0);
-	WARN_ON(!icoll_base);
+	void __iomem *icoll_base;
+
+	icoll_base		= icoll_init_iobase(np);
+	icoll_priv.vector	= icoll_base + HW_ICOLL_VECTOR;
+	icoll_priv.levelack	= icoll_base + HW_ICOLL_LEVELACK;
+	icoll_priv.ctrl		= icoll_base + HW_ICOLL_CTRL;
+	icoll_priv.stat		= icoll_base + HW_ICOLL_STAT_OFFSET;
+	icoll_priv.intr		= icoll_base + HW_ICOLL_INTERRUPT0;
+	icoll_priv.intr_reg_num	= 1;
+	icoll_priv.clear	= ERR_PTR(-ENODEV);
 
 	/*
 	 * Interrupt Collector reset, which initializes the priority
 	 * for each irq to level 0.
 	 */
-	stmp_reset_block(icoll_base + HW_ICOLL_CTRL);
+	stmp_reset_block(icoll_priv.ctrl);
+
+	icoll_add_domain(np, ICOLL_NUM_IRQS);
 
-	icoll_domain = irq_domain_add_linear(np, ICOLL_NUM_IRQS,
-					     &icoll_irq_domain_ops, NULL);
 	return icoll_domain ? 0 : -ENODEV;
 }
 IRQCHIP_DECLARE(mxs, "fsl,icoll", icoll_of_init);
+
+static int __init asm9260_of_init(struct device_node *np,
+			  struct device_node *interrupt_parent)
+{
+	void __iomem *icoll_base;
+	int i;
+
+	icoll_base = icoll_init_iobase(np);
+	icoll_priv.vector	= icoll_base + ASM9260_HW_ICOLL_VECTOR;
+	icoll_priv.levelack	= icoll_base + ASM9260_HW_ICOLL_LEVELACK;
+	icoll_priv.ctrl		= icoll_base + ASM9260_HW_ICOLL_CTRL;
+	icoll_priv.stat		= icoll_base + ASM9260_HW_ICOLL_STAT_OFFSET;
+	icoll_priv.intr		= icoll_base + ASM9260_HW_ICOLL_INTERRUPT0;
+	icoll_priv.intr_reg_num	= 4;
+	icoll_priv.clear	= icoll_base + ASM9260_HW_ICOLL_CLEAR0;
+
+	writel_relaxed(ASM9260_BM_CTRL_IRQ_ENABLE,
+			icoll_priv.ctrl);
+	/*
+	 * ASM9260 don't provide reset bit. So, we need to set level 0
+	 * manually.
+	 */
+	for (i = 0; i < 16 * 0x10; i += 0x10)
+		writel(0, icoll_priv.intr + i);
+
+	icoll_add_domain(np, ASM9260_NUM_IRQS);
+
+	return icoll_domain ? 0 : -ENODEV;
+}
+IRQCHIP_DECLARE(asm9260, "alphascale,asm9260-icoll", asm9260_of_init);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 8/9] tty/serial/mxs-auart.c: add initial Alphascale ASM9260 support
  2014-10-07  8:55 ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
                     ` (6 preceding siblings ...)
  2014-10-07  8:55   ` [PATCH v3 7/9] irqchip/irq-mxs.c: add asm9260 support Oleksij Rempel
@ 2014-10-07  8:55   ` Oleksij Rempel
  2014-10-07  8:55   ` [PATCH v3 9/9] add Alphascale to vendor-prefixes.txt Oleksij Rempel
  2014-10-10  5:38   ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
  9 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-10-07  8:55 UTC (permalink / raw)
  To: linux-arm-kernel

Alphascale ASM9260 uart IP has some common registers with
Freescale STMP37XX. This patch provide initial changes which
allow to reuse mxs-auart.c code for ASM9260.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/tty/serial/Kconfig                     |   5 +-
 drivers/tty/serial/alphascale,asm9260_serial.h | 373 +++++++++++++++++++++++++
 drivers/tty/serial/mxs-auart.c                 | 344 +++++++++++++++--------
 3 files changed, 599 insertions(+), 123 deletions(-)
 create mode 100644 drivers/tty/serial/alphascale,asm9260_serial.h

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 26cec64..11bbb76 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1385,11 +1385,12 @@ config SERIAL_MSM_SMD
 	  ports via tty device interface for MSM chipset.
 
 config SERIAL_MXS_AUART
-	depends on ARCH_MXS
+	depends on ARCH_MXS || MACH_ASM9260
 	tristate "MXS AUART support"
 	select SERIAL_CORE
 	help
-	  This driver supports the MXS Application UART (AUART) port.
+	  This driver supports the MXS and Alphascale ASM9260 Application
+	  UART (AUART) port.
 
 config SERIAL_MXS_AUART_CONSOLE
 	bool "MXS AUART console support"
diff --git a/drivers/tty/serial/alphascale,asm9260_serial.h b/drivers/tty/serial/alphascale,asm9260_serial.h
new file mode 100644
index 0000000..eeed9c4
--- /dev/null
+++ b/drivers/tty/serial/alphascale,asm9260_serial.h
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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.
+ */
+
+#ifndef _ALPHASCALE_ASM9260_SERIAL_H
+#define _ALPHASCALE_ASM9260_SERIAL_H
+
+/* RX ctrl register */
+#define ASM9260_HW_CTRL0			0x0000
+/* RW. Set to zero for normal operation. */
+#define ASM9260_BM_CTRL0_SFTRST			BIT(31)
+/*
+ * RW. 0 for normal operation; 1 gates all of the block level clocks off for
+ * miniminizing AC energy consumption.
+ */
+#define ASM9260_BM_CTRL0_CLKGATE		BIT(30)
+/*
+ * RW. Tell the UART to execute the RX DMA Command. The
+ * UART will clear this bit at the end of receive execution.
+ */
+#define ASM9260_BM_CTRL0_RXDMA_RUN		BIT(28)
+/* RW. 0 use FIFO for status register; 1 use DMA */
+#define ASM9260_BM_CTRL0_RXTO_SOURCE_STATUS	BIT(25)
+/*
+ * RW. RX TIMEOUT Enable. Valid for FIFO and DMA.
+ * Warning: If this bit is set to 0, the RX timeout will not affect receive DMA
+ * operation. If this bit is set to 1, a receive timeout will cause the receive
+ * DMA logic to terminate by filling the remaining DMA bytes with garbage data.
+ */
+#define ASM9260_BM_CTRL0_RXTO_ENABLE		BIT(24)
+/*
+ * RW. Receive Timeout Counter Value: number of 8-bit-time to wait before
+ * asserting timeout on the RX input. If the RXFIFO is not empty and the RX
+ * input is idle, then the watchdog counter will decrement each bit-time. Note
+ * 7-bit-time is added to the programmed value, so a value of zero will set
+ * the counter to 7-bit-time, a value of 0x1 gives 15-bit-time and so on. Also
+ * note that the counter is reloaded at the end of each frame, so if the frame
+ * is 10 bits long and the timeout counter value is zero, then timeout will
+ * occur (when FIFO is not empty) even if the RX input is not idle. The default
+ * value is 0x3 (31 bit-time).
+ */
+#define ASM9260_BM_CTRL0_RXTO_MASK		(0xff<<16)
+/* TIMEOUT = (100*7+1)*(1/BAUD) */
+#define ASM9260_BM_CTRL0_DEFAULT_RXTIMEOUT	(20<<16)
+/* RW. Number of bytes to receive. This must be a multiple of 4 */
+#define ASM9260_BM_CTRL0_RXDMA_COUNT_MASK	(0xffff<<0)
+
+/* TX ctrl register */
+#define ASM9260_HW_CTRL1			0x0010
+/*
+ * RW. Tell the UART to execute the TX DMA Command. The
+ * UART will clear this bit at the end of transmit execution.
+ */
+#define ASM9260_BM_CTRL1_TXDMA_RUN		BIT(28)
+/* RW. Number of bytes to transmit. */
+#define ASM9260_BM_CTRL1_TXDMA_COUNT_MASK	(0xffff << 0)
+
+#define ASM9260_HW_CTRL2			0x0020
+/*
+ * RW. Receive dma will terminate on error. (Cmd_end signal may not be asserted
+ * when this occurs.)
+ */
+#define ASM9260_BM_CTRL2_DMAONERROR		BIT(26)
+/*
+ * RW. Transmit DMA Enable. Data Register can be loaded with up to 4 bytes per
+ * write. TXFIFO must be enabled in TXDMA mode.
+ */
+#define ASM9260_BM_CTRL2_TXDMAE			BIT(25)
+/*
+ * RW. Receive DMA Enable. Data Register can be contain up to 4 bytes per read.
+ * RXFIFO must be enabled in RXDMA mode.
+ */
+#define ASM9260_BM_CTRL2_RXDMAE			BIT(24)
+/*
+ * RW. Receive Interrupt FIFO Level Select.
+ * The trigger points for the receive interrupt are as follows:
+ * ONE_EIGHTHS = 0x0 Trigger on FIFO full to at least 2 of 16 entries.
+ * ONE_QUARTER = 0x1 Trigger on FIFO full to at least 4 of 16 entries.
+ * ONE_HALF = 0x2 Trigger on FIFO full to at least 8 of 16 entries.
+ * THREE_QUARTERS = 0x3 Trigger on FIFO full to at least 12 of 16 entries.
+ * SEVEN_EIGHTHS = 0x4 Trigger on FIFO full to at least 14 of 16 entries.
+ */
+#define ASM9260_BM_CTRL2_RXIFLSEL		(7<<20)
+#define ASM9260_BM_CTRL2_DEFAULT_RXIFLSEL	(3<<20)
+/* RW. Same as RXIFLSEL */
+#define ASM9260_BM_CTRL2_TXIFLSEL		(7<<16)
+#define ASM9260_BM_CTRL2_DEFAULT_TXIFLSEL	(2<<16)
+/* RW. CTS Enable */
+#define ASM9260_BM_CTRL2_CTSE			BIT(15)
+/* RW. RTS Enable */
+#define ASM9260_BM_CTRL2_RTSE			BIT(14)
+/*
+ * RW. Manually trigger RTS. Works only if ASM9260_BM_CTRL2_RTSE = 0.
+ * When this bit is 1, the output is 0.
+ */
+#define ASM9260_BM_CTRL2_RTS			BIT(11)
+/* RW. Set DTR. When this bit is 1, the output is 0. */
+#define ASM9260_BM_CTRL2_DTR			BIT(10)
+/* RW. RX Enable */
+#define ASM9260_BM_CTRL2_RXE			BIT(9)
+/* RW. TX Enable */
+#define ASM9260_BM_CTRL2_TXE			BIT(8)
+/* RW. Loop Back Enable */
+#define ASM9260_BM_CTRL2_LBE			BIT(7)
+#define ASM9260_BM_CTRL2_PORT_ENABLE		BIT(0)
+
+#define ASM9260_HW_LINECTRL			0x0030
+#define ASM9260_BM_LCTRL_BAUD_DIVINT		(0xFFFF<<16)
+#define ASM9260_BM_LCTRL_BAUD_DIVFRA		(0x3F<<8)
+/*
+ * RW. Stick Parity Select. When bits 1, 2, and 7 of this register are set, the
+ * parity bit is transmitted and checked as a 0. When bits 1 and 7 are set,
+ * and bit 2 is 0, the parity bit is transmitted and checked as a 1. When this
+ * bit is cleared stick parity is disabled.
+ */
+#define ASM9260_BM_LCTRL_SPS			BIT(7)
+/* RW. Word length */
+#define ASM9260_BM_LCTRL_WLEN			(3<<5)
+#define ASM9260_BM_LCTRL_CHRL_5			(0<<5)
+#define ASM9260_BM_LCTRL_CHRL_6			(1<<5)
+#define ASM9260_BM_LCTRL_CHRL_7			(2<<5)
+#define ASM9260_BM_LCTRL_CHRL_8			(3<<5)
+/*
+ * RW. Enable FIFOs. If this bit is set to 1, transmit and receive FIFO buffers
+ * are enabled (FIFO mode). When cleared to 0, the FIFOs are disabled (character
+ * mode); that is, the FIFOs become 1-byte-deep holding registers.
+ */
+#define ASM9260_BM_LCTRL_FEN			BIT(4)
+/*
+ * RW. Two Stop Bits Select. If this bit is set to 1, two stop bits are
+ * transmitted at the end of the frame. The receive logic does not check for
+ * two stop bits being received.
+ */
+#define ASM9260_BM_LCTRL_STP2			BIT(3)
+#define ASM9260_BM_LCTRL_NBSTOP_1		(0<<3)
+#define ASM9260_BM_LCTRL_NBSTOP_2		(1<<3)
+/* RW. Even Parity Select. If disabled, then odd parity is performed. */
+#define ASM9260_BM_LCTRL_EPS			BIT(2)
+/* Parity Enable. */
+#define ASM9260_BM_LCTRL_PEN			BIT(1)
+#define ASM9260_BM_LCTRL_PAR_MARK		((3<<1) | (1<<7))
+#define ASM9260_BM_LCTRL_PAR_SPACE		((1<<1) | (1<<7))
+#define ASM9260_BM_LCTRL_PAR_ODD		((1<<1) | (0<<7))
+#define ASM9260_BM_LCTRL_PAR_EVEN		((3<<1) | (0<<7))
+#define ASM9260_BM_LCTRL_PAR_NONE		(0<<1)
+/*
+ * RW. Send Break. If this bit is set to 1, a low-level is continually output on
+ * the UARTTXD output, after completing transmission of the current character.
+ * For the proper execution of the break command, the software must set this bit
+ * for@least two complete frames. For normal use, this bit must be cleared
+ * to 0.
+ */
+#define ASM9260_BM_LCTRL_BREAK			BIT(0)
+
+/*
+ * Interrupt register.
+ * contains the interrupt enables and the interrupt status bits
+ */
+#define ASM9260_HW_INTR				0x0040
+/* Tx FIFO EMPTY Raw Interrupt enable */
+#define ASM9260_BM_INTR_TFEIEN			BIT(27)
+/* Overrun Error Interrupt Enable. */
+#define ASM9260_BM_INTR_OEIEN			BIT(26)
+/* Break Error Interrupt Enable. */
+#define ASM9260_BM_INTR_BEIEN			BIT(25)
+/* Parity Error Interrupt Enable. */
+#define ASM9260_BM_INTR_PEIEN			BIT(24)
+/* Framing Error Interrupt Enable. */
+#define ASM9260_BM_INTR_FEIEN			BIT(23)
+/*
+ * RW. Receive Timeout Interrupt Enable.
+ * If not set and FIFO is enabled, then RX will be triggered only
+ * if FIFO is full.
+ */
+#define ASM9260_BM_INTR_RTIEN			BIT(22)
+/* Transmit Interrupt Enable. */
+#define ASM9260_BM_INTR_TXIEN			BIT(21)
+/* Receive Interrupt Enable. */
+#define ASM9260_BM_INTR_RXIEN			BIT(20)
+/* nUARTDSR Modem Interrupt Enable. */
+#define ASM9260_BM_INTR_DSRMIEN			BIT(19)
+/* nUARTDCD Modem Interrupt Enable. */
+#define ASM9260_BM_INTR_DCDMIEN			BIT(18)
+/* nUARTCTS Modem Interrupt Enable. */
+#define ASM9260_BM_INTR_CTSMIEN			BIT(17)
+/* nUARTRI Modem Interrupt Enable. */
+#define ASM9260_BM_INTR_RIMIEN			BIT(16)
+/* Auto-Boud Timeout */
+#define ASM9260_BM_INTR_ABTO			BIT(13)
+#define ASM9260_BM_INTR_ABEO			BIT(12)
+/* Tx FIFO EMPTY Raw Interrupt state */
+#define ASM9260_BM_INTR_TFEIS			BIT(11)
+/* Overrun Error */
+#define ASM9260_BM_INTR_OEIS			BIT(10)
+/* Break Error */
+#define ASM9260_BM_INTR_BEIS			BIT(9)
+/* Parity Error */
+#define ASM9260_BM_INTR_PEIS			BIT(8)
+/* Framing Error */
+#define ASM9260_BM_INTR_FEIS			BIT(7)
+/* Receive Timeout */
+#define ASM9260_BM_INTR_RTIS			BIT(6)
+/* Transmit done */
+#define ASM9260_BM_INTR_TXIS			BIT(5)
+/* Receive done */
+#define ASM9260_BM_INTR_RXIS			BIT(4)
+#define ASM9260_BM_INTR_DSRMIS			BIT(3)
+#define ASM9260_BM_INTR_DCDMIS			BIT(2)
+#define ASM9260_BM_INTR_CTSMIS			BIT(1)
+#define ASM9260_BM_INTR_RIMIS			BIT(0)
+#define ASM9260_BM_INTR_DEF_MASK	(ASM9260_BM_INTR_RXIEN \
+		| ASM9260_BM_INTR_TXIEN | ASM9260_BM_INTR_RTIEN \
+		| ASM9260_BM_INTR_FEIEN | ASM9260_BM_INTR_PEIEN \
+		| ASM9260_BM_INTR_BEIEN | ASM9260_BM_INTR_OEIEN)
+#define ASM9260_BM_INTR_DEF_IS_MASK		(BM_INTR_DEF_MASK >> 16)
+#define ASM9260_BM_INTR_EN_MASK			(0x3fff0000)
+#define ASM9260_BM_INTR_IS_MASK			(0x00003fff)
+
+/*
+ * RW. In DMA mode, up to 4 Received/Transmit characters can be accessed at a
+ * time. In PIO mode, only one character can be accessed at a time. The status
+ * register contains the receive data flags and valid bits.
+ */
+#define ASM9260_HW_DATA				0x0050
+
+#define ASM9260_HW_STAT				0x0060
+/* RO. If 1, UARTAPP is present in this product. */
+#define ASM9260_BM_STAT_PRESENT			BIT(31)
+/* RO. If 1, HISPEED is present in this product. */
+#define ASM9260_BM_STAT_HISPEED			BIT(30)
+/* RO. UART Busy. */
+#define ASM9260_BM_STAT_BUSY			BIT(29)
+/* RO. Clear To Send. */
+#define ASM9260_BM_STAT_CTS			BIT(28)
+/* RO. Transmit FIFO/PIO Empty */
+#define ASM9260_BM_STAT_TXEMPTY			BIT(27)
+/* RO. Receive FIFO Full. */
+#define ASM9260_BM_STAT_RXFULL			BIT(26)
+/* RO. Transmit FIFO Full. */
+#define ASM9260_BM_STAT_TXFULL			BIT(25)
+/* RO. Receive FIFO Empty. */
+#define ASM9260_BM_STAT_RXEMPTY			BIT(24)
+/*
+ * RW. The invalid state of the last read of Receive Data. Each
+ * bit corresponds to one byte of the RX data. (1 = invalid.)
+ */
+#define ASM9260_BM_STAT_RXBYTE_INVALID_MASK	(0xf<<20)
+/*
+ * RO. Overrun Error. This bit is set to 1 if data is received and the FIFO is
+ * already full. This bit is cleared to 0 by any write to the Status Register.
+ * The FIFO contents remain valid since no further data is written when the
+ * FIFO is full; only the contents of the shift register are overwritten. The
+ * CPU must now read the data in order to empty the FIFO.
+ */
+#define ASM9260_BM_STAT_OVERRUNERR		BIT(19)
+/*
+ * RW. Break Error. For PIO mode, this is for the last character read from the
+ * data register. For DMA mode, it will be set to 1 if any received character
+ * for a particular RXDMA command had a Break Error. To clear this bit, write a
+ * zero to it. Note that clearing this bit does not affect the interrupt status,
+ * which must be cleared by writing the interrupt register.
+ */
+#define ASM9260_BM_STAT_BREAKERR		BIT(18)
+/* RW. Parity Error. Same as BREAKERR. */
+#define ASM9260_BM_STAT_PARITYERR		BIT(17)
+/* RW. Framing Erro. Same as BREAKERR. */
+#define ASM9260_BM_STAT_FRAMEERR		BIT(16)
+/* RO. Number of bytes received during a Receive DMA command. */
+#define ASM9260_BM_STAT_RXCOUNT_MASK		(0xffff<<0)
+
+/* RO. The UART Debug Register contains the state of the DMA signals. */
+#define ASM9260_HW_DEBUG			0x0070
+/* DMA Command Run Status */
+#define ASM9260_BM_DEBUG_TXDMARUN		BIT(5)
+#define ASM9260_BM_DEBUG_RXDMARUN		BIT(4)
+/* DMA Command End Status */
+#define ASM9260_BM_DEBUG_TXCMDEND		BIT(3)
+#define ASM9260_BM_DEBUG_RXCMDEND		BIT(2)
+/* DMA Request Status */
+#define ASM9260_BM_DEBUG_TXDMARQ		BIT(1)
+#define ASM9260_BM_DEBUG_RXDMARQ		BIT(0)
+
+#define ASM9260_HW_ILPR				0x0080
+
+#define ASM9260_HW_RS485CTRL			0x0090
+/*
+ * RW. This bit reverses the polarity of the direction control signal on the RTS
+ * (or DTR) pin.
+ * If 0, The direction control pin will be driven to logic ?0? when the
+ * transmitter has data to be sent. It will be driven to logic ?1? after the
+ * last bit of data has been transmitted.
+ */
+#define ASM9260_BM_RS485CTRL_ONIV		BIT(5)
+/* RW. Enable Auto Direction Control. */
+#define ASM9260_BM_RS485CTRL_DIR_CTRL		BIT(4)
+/*
+ * RW. If 0 and DIR_CTRL = 1, pin RTS is used for direction control.
+ * If 1 and DIR_CTRL = 1, pin DTR is used for direction control.
+ */
+#define ASM9260_BM_RS485CTRL_PINSEL		BIT(3)
+/* RW. Enable Auto Address Detect (AAD). */
+#define ASM9260_BM_RS485CTRL_AADEN		BIT(2)
+/* RW. Disable receiver. */
+#define ASM9260_BM_RS485CTRL_RXDIS		BIT(1)
+/* RW. Enable RS-485/EIA-485 Normal Multidrop Mode (NMM) */
+#define ASM9260_BM_RS485CTRL_RS485EN		BIT(0)
+
+#define ASM9260_HW_RS485ADRMATCH		0x00a0
+/* Contains the address match value. */
+#define ASM9260_BM_RS485ADRMATCH_MASK		(0xff<<0)
+
+#define ASM9260_HW_RS485DLY			0x00b0
+/*
+ * RW. Contains the direction control (RTS or DTR) delay value. This delay time
+ * is in periods of the baud clock.
+ */
+#define ASM9260_BM_RS485DLY_MASK		(0xff<<0)
+
+#define ASM9260_HW_AUTOBAUD			0x00c0
+/* WO. Auto-baud time-out interrupt clear bit. */
+#define ASM9260_BM_AUTOBAUD_ABTOIntClr		BIT(9)
+/* WO. End of auto-baud interrupt clear bit. */
+#define ASM9260_BM_AUTOBAUD_ABEOIntClr		BIT(8)
+/* Restart in case of timeout (counter restarts at next UART Rx falling edge) */
+#define ASM9260_BM_AUTOBAUD_AUTORESTART		BIT(2)
+/* Auto-baud mode select bit. 0 - Mode 0, 1 - Mode 1. */
+#define ASM9260_BM_AUTOBAUD_MODE		BIT(1)
+/*
+ * Auto-baud start (auto-baud is running). Auto-baud run bit. This bit is
+ * automatically cleared after auto-baud completion.
+ */
+#define ASM9260_BM_AUTOBAUD_START		BIT(0)
+
+#define ASM9260_HW_CTRL3			0x00d0
+#define ASM9260_BM_CTRL3_OUTCLK_DIV_MASK	(0xffff<<16)
+/*
+ * RW. Provide clk over OUTCLK pin. In case of asm9260 it can be configured on
+ * pins 137 and 144.
+ */
+#define ASM9260_BM_CTRL3_MASTERMODE		BIT(6)
+/* RW. Baud Rate Mode: 1 - Enable sync mode. 0 - async mode. */
+#define ASM9260_BM_CTRL3_SYNCMODE		BIT(4)
+/* RW. 1 - MSB bit send frist; 0 - LSB bit frist. */
+#define ASM9260_BM_CTRL3_MSBF			BIT(2)
+/* RW. 1 - sample rate = 8 x Baudrate; 0 - sample rate = 16 x Baudrate. */
+#define ASM9260_BM_CTRL3_BAUD8			BIT(1)
+/* RW. 1 - Set word lenght to 9bit. 0 - use ASM9260_BM_LCTRL_WLEN */
+#define ASM9260_BM_CTRL3_9BIT			BIT(0)
+
+#define ASM9260_HW_ISO7816_CTRL			0x00e0
+/* RW. Enable High Speed mode. */
+#define ASM9260_BM_ISO7816CTRL_HS		BIT(12)
+/* Disable Successive Receive NACK */
+#define ASM9260_BM_ISO7816CTRL_DS_NACK		BIT(8)
+#define ASM9260_BM_ISO7816CTRL_MAX_ITER_MASK	(0xff<<4)
+/* Receive NACK Inhibit */
+#define ASM9260_BM_ISO7816CTRL_INACK		BIT(3)
+#define ASM9260_BM_ISO7816CTRL_NEG_DATA		BIT(2)
+/* RW. 1 - ISO7816 mode; 0 - USART mode */
+#define ASM9260_BM_ISO7816CTRL_ENABLE		BIT(0)
+
+#define ASM9260_HW_ISO7816_ERRCNT		0x00f0
+/* Parity error counter. Will be cleared after reading */
+#define ASM9260_BM_ISO7816_NB_ERRORS_MASK	(0xff<<0)
+
+#define ASM9260_HW_ISO7816_STATUS		0x0100
+/* Max number of Repetitions Reached */
+#define ASM9260_BM_ISO7816_STAT_ITERATION	BIT(0)
+#endif
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index b5c3292..b5a1455 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -1,17 +1,18 @@
 /*
- * Freescale STMP37XX/STMP378X Application UART driver
+ * Application UART driver for:
+ *	Freescale STMP37XX/STMP378X
+ *	Alphascale ASM9260
  *
  * Author: dmitry pervushin <dimka@embeddedalley.com>
  *
+ * Copyright 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *	Provide Alphascale ASM9260 support.
  * Copyright 2008-2010 Freescale Semiconductor, Inc.
  * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
  *
  * The code contained herein is licensed under the GNU General Public
  * License. You may obtain a copy of the GNU General Public License
  * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
  */
 
 #include <linux/kernel.h>
@@ -37,34 +38,23 @@
 #include <linux/dmaengine.h>
 
 #include <asm/cacheflush.h>
+#include "alphascale,asm9260_serial.h"
 
 #define MXS_AUART_PORTS 5
 #define MXS_AUART_FIFO_SIZE		16
+#define MXS_DEVICENAME			"ttyAPP"
+#define DRIVER_NAME			"mxs-auart"
+
+#define SET_REG				0x4
+#define CLR_REG				0x8
+#define TOG_REG				0xc
 
 #define AUART_CTRL0			0x00000000
-#define AUART_CTRL0_SET			0x00000004
-#define AUART_CTRL0_CLR			0x00000008
-#define AUART_CTRL0_TOG			0x0000000c
 #define AUART_CTRL1			0x00000010
-#define AUART_CTRL1_SET			0x00000014
-#define AUART_CTRL1_CLR			0x00000018
-#define AUART_CTRL1_TOG			0x0000001c
 #define AUART_CTRL2			0x00000020
-#define AUART_CTRL2_SET			0x00000024
-#define AUART_CTRL2_CLR			0x00000028
-#define AUART_CTRL2_TOG			0x0000002c
 #define AUART_LINECTRL			0x00000030
-#define AUART_LINECTRL_SET		0x00000034
-#define AUART_LINECTRL_CLR		0x00000038
-#define AUART_LINECTRL_TOG		0x0000003c
 #define AUART_LINECTRL2			0x00000040
-#define AUART_LINECTRL2_SET		0x00000044
-#define AUART_LINECTRL2_CLR		0x00000048
-#define AUART_LINECTRL2_TOG		0x0000004c
 #define AUART_INTR			0x00000050
-#define AUART_INTR_SET			0x00000054
-#define AUART_INTR_CLR			0x00000058
-#define AUART_INTR_TOG			0x0000005c
 #define AUART_DATA			0x00000060
 #define AUART_STAT			0x00000070
 #define AUART_DEBUG			0x00000080
@@ -129,6 +119,17 @@ static struct uart_driver auart_driver;
 enum mxs_auart_type {
 	IMX23_AUART,
 	IMX28_AUART,
+	ASM9260_AUART,
+};
+
+struct mxs_auart_regs {
+	void __iomem *ctrl0;
+	void __iomem *ctrl1;
+	void __iomem *ctrl2;
+	void __iomem *linectrl;
+	void __iomem *intr;
+	void __iomem *data;
+	void __iomem *stat;
 };
 
 struct mxs_auart_port {
@@ -142,9 +143,11 @@ struct mxs_auart_port {
 	unsigned int ctrl;
 	enum mxs_auart_type devtype;
 
+	struct mxs_auart_regs regs;
 	unsigned int irq;
 
 	struct clk *clk;
+	struct clk *clk_ahb;
 	struct device *dev;
 
 	/* for DMA */
@@ -160,6 +163,7 @@ struct mxs_auart_port {
 static struct platform_device_id mxs_auart_devtype[] = {
 	{ .name = "mxs-auart-imx23", .driver_data = IMX23_AUART },
 	{ .name = "mxs-auart-imx28", .driver_data = IMX28_AUART },
+	{ .name = "as-auart-asm9260", .driver_data = ASM9260_AUART },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(platform, mxs_auart_devtype);
@@ -171,7 +175,11 @@ static struct of_device_id mxs_auart_dt_ids[] = {
 	}, {
 		.compatible = "fsl,imx23-auart",
 		.data = &mxs_auart_devtype[IMX23_AUART]
+	}, {
+		.compatible = "alphascale,asm9260-auart",
+		.data = &mxs_auart_devtype[ASM9260_AUART]
 	}, { /* sentinel */ }
+
 };
 MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids);
 
@@ -180,6 +188,11 @@ static inline int is_imx28_auart(struct mxs_auart_port *s)
 	return s->devtype == IMX28_AUART;
 }
 
+static inline int is_asm9260_auart(struct mxs_auart_port *s)
+{
+	return s->devtype == ASM9260_AUART;
+}
+
 static inline bool auart_dma_enabled(struct mxs_auart_port *s)
 {
 	return s->flags & MXS_AUART_DMA_ENABLED;
@@ -281,19 +294,19 @@ static void mxs_auart_tx_chars(struct mxs_auart_port *s)
 	}
 
 
-	while (!(readl(s->port.membase + AUART_STAT) &
+	while (!(readl(s->regs.stat) &
 		 AUART_STAT_TXFF)) {
 		if (s->port.x_char) {
 			s->port.icount.tx++;
 			writel(s->port.x_char,
-				     s->port.membase + AUART_DATA);
+				     s->regs.data);
 			s->port.x_char = 0;
 			continue;
 		}
 		if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) {
 			s->port.icount.tx++;
 			writel(xmit->buf[xmit->tail],
-				     s->port.membase + AUART_DATA);
+				     s->regs.data);
 			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 		} else
 			break;
@@ -303,10 +316,10 @@ static void mxs_auart_tx_chars(struct mxs_auart_port *s)
 
 	if (uart_circ_empty(&(s->port.state->xmit)))
 		writel(AUART_INTR_TXIEN,
-			     s->port.membase + AUART_INTR_CLR);
+			     s->regs.intr + CLR_REG);
 	else
 		writel(AUART_INTR_TXIEN,
-			     s->port.membase + AUART_INTR_SET);
+			     s->regs.intr + SET_REG);
 
 	if (uart_tx_stopped(&s->port))
 		mxs_auart_stop_tx(&s->port);
@@ -318,8 +331,8 @@ static void mxs_auart_rx_char(struct mxs_auart_port *s)
 	u32 stat;
 	u8 c;
 
-	c = readl(s->port.membase + AUART_DATA);
-	stat = readl(s->port.membase + AUART_STAT);
+	c = readl(s->regs.data);
+	stat = readl(s->regs.stat);
 
 	flag = TTY_NORMAL;
 	s->port.icount.rx++;
@@ -354,7 +367,7 @@ static void mxs_auart_rx_char(struct mxs_auart_port *s)
 
 	uart_insert_char(&s->port, stat, AUART_STAT_OERR, c, flag);
 out:
-	writel(stat, s->port.membase + AUART_STAT);
+	writel(stat, s->regs.stat);
 }
 
 static void mxs_auart_rx_chars(struct mxs_auart_port *s)
@@ -362,13 +375,13 @@ static void mxs_auart_rx_chars(struct mxs_auart_port *s)
 	u32 stat = 0;
 
 	for (;;) {
-		stat = readl(s->port.membase + AUART_STAT);
+		stat = readl(s->regs.stat);
 		if (stat & AUART_STAT_RXFE)
 			break;
 		mxs_auart_rx_char(s);
 	}
 
-	writel(stat, s->port.membase + AUART_STAT);
+	writel(stat, s->regs.stat);
 	tty_flip_buffer_push(&s->port.state->port);
 }
 
@@ -404,7 +417,7 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl)
 {
 	struct mxs_auart_port *s = to_auart_port(u);
 
-	u32 ctrl = readl(u->membase + AUART_CTRL2);
+	u32 ctrl = readl(s->regs.ctrl2);
 
 	ctrl &= ~(AUART_CTRL2_RTSEN | AUART_CTRL2_RTS);
 	if (mctrl & TIOCM_RTS) {
@@ -415,14 +428,14 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl)
 	}
 
 	s->ctrl = mctrl;
-	writel(ctrl, u->membase + AUART_CTRL2);
+	writel(ctrl, s->regs.ctrl2);
 }
 
 static u32 mxs_auart_get_mctrl(struct uart_port *u)
 {
 	struct mxs_auart_port *s = to_auart_port(u);
-	u32 stat = readl(u->membase + AUART_STAT);
-	int ctrl2 = readl(u->membase + AUART_CTRL2);
+	u32 stat = readl(s->regs.stat);
+	int ctrl2 = readl(s->regs.ctrl2);
 	u32 mctrl = s->ctrl;
 
 	mctrl &= ~TIOCM_CTS;
@@ -445,14 +458,14 @@ static void dma_rx_callback(void *arg)
 
 	dma_unmap_sg(s->dev, &s->rx_sgl, 1, DMA_FROM_DEVICE);
 
-	stat = readl(s->port.membase + AUART_STAT);
+	stat = readl(s->regs.stat);
 	stat &= ~(AUART_STAT_OERR | AUART_STAT_BERR |
 			AUART_STAT_PERR | AUART_STAT_FERR);
 
 	count = stat & AUART_STAT_RXCOUNT_MASK;
 	tty_insert_flip_string(port, s->rx_dma_buf, count);
 
-	writel(stat, s->port.membase + AUART_STAT);
+	writel(stat, s->regs.stat);
 	tty_flip_buffer_push(port);
 
 	/* start the next DMA for RX. */
@@ -506,8 +519,8 @@ static void mxs_auart_dma_exit_channel(struct mxs_auart_port *s)
 		s->rx_dma_chan = NULL;
 	}
 
-	kfree(s->tx_dma_buf);
-	kfree(s->rx_dma_buf);
+	devm_kfree(s->dev, s->tx_dma_buf);
+	devm_kfree(s->dev, s->rx_dma_buf);
 	s->tx_dma_buf = NULL;
 	s->rx_dma_buf = NULL;
 }
@@ -516,7 +529,7 @@ static void mxs_auart_dma_exit(struct mxs_auart_port *s)
 {
 
 	writel(AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE | AUART_CTRL2_DMAONERR,
-		s->port.membase + AUART_CTRL2_CLR);
+		s->regs.ctrl2 + CLR_REG);
 
 	mxs_auart_dma_exit_channel(s);
 	s->flags &= ~MXS_AUART_DMA_ENABLED;
@@ -533,7 +546,8 @@ static int mxs_auart_dma_init(struct mxs_auart_port *s)
 	s->rx_dma_chan = dma_request_slave_channel(s->dev, "rx");
 	if (!s->rx_dma_chan)
 		goto err_out;
-	s->rx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
+	s->rx_dma_buf = devm_kzalloc(s->dev,
+			UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
 	if (!s->rx_dma_buf)
 		goto err_out;
 
@@ -541,7 +555,8 @@ static int mxs_auart_dma_init(struct mxs_auart_port *s)
 	s->tx_dma_chan = dma_request_slave_channel(s->dev, "tx");
 	if (!s->tx_dma_chan)
 		goto err_out;
-	s->tx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
+	s->tx_dma_buf = devm_kzalloc(s->dev,
+			UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
 	if (!s->tx_dma_buf)
 		goto err_out;
 
@@ -571,7 +586,7 @@ static void mxs_auart_settermios(struct uart_port *u,
 	cflag = termios->c_cflag;
 
 	ctrl = AUART_LINECTRL_FEN;
-	ctrl2 = readl(u->membase + AUART_CTRL2);
+	ctrl2 = readl(s->regs.ctrl2);
 
 	/* byte size */
 	switch (cflag & CSIZE) {
@@ -656,13 +671,21 @@ static void mxs_auart_settermios(struct uart_port *u,
 	}
 
 	/* set baud rate */
-	baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk);
-	div = u->uartclk * 32 / baud;
+	if (is_asm9260_auart(s)) {
+		baud = uart_get_baud_rate(u, termios, old,
+				u->uartclk * 4 / 0x3FFFFF,
+				u->uartclk / 16);
+		div = u->uartclk * 4 / baud;
+	} else {
+		baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk);
+		div = u->uartclk * 32 / baud;
+	}
+
 	ctrl |= AUART_LINECTRL_BAUD_DIVFRAC(div & 0x3F);
 	ctrl |= AUART_LINECTRL_BAUD_DIVINT(div >> 6);
+	writel(ctrl, s->regs.linectrl);
 
-	writel(ctrl, u->membase + AUART_LINECTRL);
-	writel(ctrl2, u->membase + AUART_CTRL2);
+	writel(ctrl2, s->regs.ctrl2);
 
 	uart_update_timeout(u, termios->c_cflag, baud);
 
@@ -672,7 +695,7 @@ static void mxs_auart_settermios(struct uart_port *u,
 		if (!mxs_auart_dma_prep_rx(s)) {
 			/* Disable the normal RX interrupt. */
 			writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN,
-					u->membase + AUART_INTR_CLR);
+					s->regs.intr + CLR_REG);
 		} else {
 			mxs_auart_dma_exit(s);
 			dev_err(s->dev, "We can not start up the DMA.\n");
@@ -684,21 +707,21 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
 {
 	u32 istat;
 	struct mxs_auart_port *s = context;
-	u32 stat = readl(s->port.membase + AUART_STAT);
+	u32 stat = readl(s->regs.stat);
 
-	istat = readl(s->port.membase + AUART_INTR);
+	istat = readl(s->regs.intr);
 
 	/* ack irq */
 	writel(istat & (AUART_INTR_RTIS
 		| AUART_INTR_TXIS
 		| AUART_INTR_RXIS
 		| AUART_INTR_CTSMIS),
-			s->port.membase + AUART_INTR_CLR);
+			s->regs.intr + CLR_REG);
 
 	if (istat & AUART_INTR_CTSMIS) {
 		uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS);
 		writel(AUART_INTR_CTSMIS,
-				s->port.membase + AUART_INTR_CLR);
+				s->regs.intr + CLR_REG);
 		istat &= ~AUART_INTR_CTSMIS;
 	}
 
@@ -716,20 +739,20 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
 	return IRQ_HANDLED;
 }
 
-static void mxs_auart_reset(struct uart_port *u)
+static void mxs_auart_reset(struct mxs_auart_port *s)
 {
 	int i;
 	unsigned int reg;
 
-	writel(AUART_CTRL0_SFTRST, u->membase + AUART_CTRL0_CLR);
+	writel(AUART_CTRL0_SFTRST, s->regs.ctrl0 + CLR_REG);
 
 	for (i = 0; i < 10000; i++) {
-		reg = readl(u->membase + AUART_CTRL0);
+		reg = readl(s->regs.ctrl0);
 		if (!(reg & AUART_CTRL0_SFTRST))
 			break;
 		udelay(3);
 	}
-	writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
+	writel(AUART_CTRL0_CLKGATE, s->regs.ctrl0 + CLR_REG);
 }
 
 static int mxs_auart_startup(struct uart_port *u)
@@ -741,12 +764,12 @@ static int mxs_auart_startup(struct uart_port *u)
 	if (ret)
 		return ret;
 
-	writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
+	writel(AUART_CTRL0_CLKGATE, s->regs.ctrl0 + CLR_REG);
 
-	writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_SET);
+	writel(AUART_CTRL2_UARTEN, s->regs.ctrl2 + SET_REG);
 
 	writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
-			u->membase + AUART_INTR);
+			s->regs.intr);
 
 	/* Reset FIFO size (it could have changed if DMA was enabled) */
 	u->fifosize = MXS_AUART_FIFO_SIZE;
@@ -755,7 +778,7 @@ static int mxs_auart_startup(struct uart_port *u)
 	 * Enable fifo so all four bytes of a DMA word are written to
 	 * output (otherwise, only the LSB is written, ie. 1 in 4 bytes)
 	 */
-	writel(AUART_LINECTRL_FEN, u->membase + AUART_LINECTRL_SET);
+	writel(AUART_LINECTRL_FEN, s->regs.linectrl + SET_REG);
 
 	return 0;
 }
@@ -767,19 +790,21 @@ static void mxs_auart_shutdown(struct uart_port *u)
 	if (auart_dma_enabled(s))
 		mxs_auart_dma_exit(s);
 
-	writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR);
+	writel(AUART_CTRL2_UARTEN, s->regs.ctrl2 + CLR_REG);
 
 	writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
-			u->membase + AUART_INTR_CLR);
+			s->regs.intr + CLR_REG);
 
-	writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET);
+	writel(AUART_CTRL0_CLKGATE, s->regs.ctrl0 + SET_REG);
 
 	clk_disable_unprepare(s->clk);
 }
 
 static unsigned int mxs_auart_tx_empty(struct uart_port *u)
 {
-	if (readl(u->membase + AUART_STAT) & AUART_STAT_TXFE)
+	struct mxs_auart_port *s = to_auart_port(u);
+
+	if (readl(s->regs.stat) & AUART_STAT_TXFE)
 		return TIOCSER_TEMT;
 	else
 		return 0;
@@ -790,29 +815,35 @@ static void mxs_auart_start_tx(struct uart_port *u)
 	struct mxs_auart_port *s = to_auart_port(u);
 
 	/* enable transmitter */
-	writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_SET);
+	writel(AUART_CTRL2_TXE, s->regs.ctrl2 + SET_REG);
 
 	mxs_auart_tx_chars(s);
 }
 
 static void mxs_auart_stop_tx(struct uart_port *u)
 {
-	writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_CLR);
+	struct mxs_auart_port *s = to_auart_port(u);
+
+	writel(AUART_CTRL2_TXE, s->regs.ctrl2 + CLR_REG);
 }
 
 static void mxs_auart_stop_rx(struct uart_port *u)
 {
-	writel(AUART_CTRL2_RXE, u->membase + AUART_CTRL2_CLR);
+	struct mxs_auart_port *s = to_auart_port(u);
+
+	writel(AUART_CTRL2_RXE, s->regs.ctrl2 + CLR_REG);
 }
 
 static void mxs_auart_break_ctl(struct uart_port *u, int ctl)
 {
+	struct mxs_auart_port *s = to_auart_port(u);
+
 	if (ctl)
 		writel(AUART_LINECTRL_BRK,
-			     u->membase + AUART_LINECTRL_SET);
+			     s->regs.linectrl + SET_REG);
 	else
 		writel(AUART_LINECTRL_BRK,
-			     u->membase + AUART_LINECTRL_CLR);
+			     s->regs.linectrl + CLR_REG);
 }
 
 static struct uart_ops mxs_auart_ops = {
@@ -838,15 +869,16 @@ static struct mxs_auart_port *auart_port[MXS_AUART_PORTS];
 #ifdef CONFIG_SERIAL_MXS_AUART_CONSOLE
 static void mxs_auart_console_putchar(struct uart_port *port, int ch)
 {
+	struct mxs_auart_port *s = to_auart_port(port);
 	unsigned int to = 1000;
 
-	while (readl(port->membase + AUART_STAT) & AUART_STAT_TXFF) {
+	while (readl(s->regs.stat) & AUART_STAT_TXFF) {
 		if (!to--)
 			break;
 		udelay(1);
 	}
 
-	writel(ch, port->membase + AUART_DATA);
+	writel(ch, s->regs.data);
 }
 
 static void
@@ -866,18 +898,18 @@ auart_console_write(struct console *co, const char *str, unsigned int count)
 	clk_enable(s->clk);
 
 	/* First save the CR then disable the interrupts */
-	old_ctrl2 = readl(port->membase + AUART_CTRL2);
-	old_ctrl0 = readl(port->membase + AUART_CTRL0);
+	old_ctrl2 = readl(s->regs.ctrl2);
+	old_ctrl0 = readl(s->regs.ctrl0);
 
 	writel(AUART_CTRL0_CLKGATE,
-		     port->membase + AUART_CTRL0_CLR);
+		     s->regs.ctrl0 + CLR_REG);
 	writel(AUART_CTRL2_UARTEN | AUART_CTRL2_TXE,
-		     port->membase + AUART_CTRL2_SET);
+		     s->regs.ctrl2 + SET_REG);
 
 	uart_console_write(port, str, count, mxs_auart_console_putchar);
 
 	/* Finally, wait for transmitter to become empty ... */
-	while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) {
+	while (readl(s->regs.stat) & AUART_STAT_BUSY) {
 		udelay(1);
 		if (!to--)
 			break;
@@ -889,24 +921,25 @@ auart_console_write(struct console *co, const char *str, unsigned int count)
 	 * unused, but that is better than to disable it while it is still
 	 * transmitting.
 	 */
-	if (!(readl(port->membase + AUART_STAT) & AUART_STAT_BUSY)) {
-		writel(old_ctrl0, port->membase + AUART_CTRL0);
-		writel(old_ctrl2, port->membase + AUART_CTRL2);
+	if (!(readl(s->regs.stat) & AUART_STAT_BUSY)) {
+		writel(old_ctrl0, s->regs.ctrl0);
+		writel(old_ctrl2, s->regs.ctrl2);
 	}
 
 	clk_disable(s->clk);
 }
 
 static void __init
-auart_console_get_options(struct uart_port *port, int *baud,
+auart_console_get_options(struct mxs_auart_port *s, int *baud,
 			  int *parity, int *bits)
 {
+	struct uart_port *port = &s->port;
 	unsigned int lcr_h, quot;
 
-	if (!(readl(port->membase + AUART_CTRL2) & AUART_CTRL2_UARTEN))
+	if (!(readl(s->regs.ctrl2) & AUART_CTRL2_UARTEN))
 		return;
 
-	lcr_h = readl(port->membase + AUART_LINECTRL);
+	lcr_h = readl(s->regs.linectrl);
 
 	*parity = 'n';
 	if (lcr_h & AUART_LINECTRL_PEN) {
@@ -921,10 +954,10 @@ auart_console_get_options(struct uart_port *port, int *baud,
 	else
 		*bits = 8;
 
-	quot = ((readl(port->membase + AUART_LINECTRL)
+	quot = ((readl(s->regs.linectrl)
 			& AUART_LINECTRL_BAUD_DIVINT_MASK))
 			    >> (AUART_LINECTRL_BAUD_DIVINT_SHIFT - 6);
-	quot |= ((readl(port->membase + AUART_LINECTRL)
+	quot |= ((readl(s->regs.linectrl)
 			& AUART_LINECTRL_BAUD_DIVFRAC_MASK))
 				>> AUART_LINECTRL_BAUD_DIVFRAC_SHIFT;
 	if (quot == 0)
@@ -950,6 +983,7 @@ auart_console_setup(struct console *co, char *options)
 	 */
 	if (co->index == -1 || co->index >= ARRAY_SIZE(auart_port))
 		co->index = 0;
+
 	s = auart_port[co->index];
 	if (!s)
 		return -ENODEV;
@@ -961,7 +995,7 @@ auart_console_setup(struct console *co, char *options)
 	if (options)
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
 	else
-		auart_console_get_options(&s->port, &baud, &parity, &bits);
+		auart_console_get_options(s, &baud, &parity, &bits);
 
 	ret = uart_set_options(&s->port, co, baud, parity, bits, flow);
 
@@ -971,7 +1005,7 @@ auart_console_setup(struct console *co, char *options)
 }
 
 static struct console auart_console = {
-	.name		= "ttyAPP",
+	.name		= MXS_DEVICENAME,
 	.write		= auart_console_write,
 	.device		= uart_console_device,
 	.setup		= auart_console_setup,
@@ -983,8 +1017,8 @@ static struct console auart_console = {
 
 static struct uart_driver auart_driver = {
 	.owner		= THIS_MODULE,
-	.driver_name	= "ttyAPP",
-	.dev_name	= "ttyAPP",
+	.driver_name	= MXS_DEVICENAME,
+	.dev_name	= MXS_DEVICENAME,
 	.major		= 0,
 	.minor		= 0,
 	.nr		= MXS_AUART_PORTS,
@@ -993,6 +1027,58 @@ static struct uart_driver auart_driver = {
 #endif
 };
 
+static void mxs_init_regs(struct mxs_auart_port *s)
+{
+	s->regs.ctrl0	= s->port.membase + AUART_CTRL0;
+	s->regs.ctrl1	= s->port.membase + AUART_CTRL1;
+	s->regs.ctrl2	= s->port.membase + AUART_CTRL2;
+	s->regs.linectrl	= s->port.membase + AUART_LINECTRL;
+
+	if (is_asm9260_auart(s)) {
+		s->regs.intr	= s->port.membase + ASM9260_HW_INTR;
+		s->regs.data	= s->port.membase + ASM9260_HW_DATA;
+		s->regs.stat	= s->port.membase + ASM9260_HW_STAT;
+	} else {
+		s->regs.intr	= s->port.membase + AUART_INTR;
+		s->regs.data	= s->port.membase + AUART_DATA;
+		s->regs.stat	= s->port.membase + AUART_STAT;
+	}
+}
+
+static int mxs_get_dt_clks(struct mxs_auart_port *s,
+		struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	int clk_idx = 0, err;
+
+	s->clk = of_clk_get(np, clk_idx);
+	if (IS_ERR(s->clk))
+		goto out_err;
+
+	/* configure AHB clock */
+	clk_idx = 1;
+	s->clk_ahb = of_clk_get(np, clk_idx);
+	if (IS_ERR(s->clk_ahb))
+		goto out_err;
+
+	err = clk_prepare_enable(s->clk_ahb);
+	if (err)
+		dev_err(s->dev, "Failed to enable ahb_clk!\n");
+
+	err = clk_set_rate(s->clk, clk_get_rate(s->clk_ahb));
+	if (err)
+		dev_err(s->dev, "Failed to set rate!\n");
+
+	err = clk_prepare_enable(s->clk);
+	if (err)
+		dev_err(s->dev, "Failed to enable clk!\n");
+
+	return 0;
+out_err:
+	dev_err(s->dev, "%s: Failed to get clk (%i)\n", __func__, clk_idx);
+	return 1;
+}
+
 /*
  * This function returns 1 if pdev isn't a device instatiated by dt, 0 if it
  * could successfully get all information from dt or a negative errno.
@@ -1029,77 +1115,98 @@ static int mxs_auart_probe(struct platform_device *pdev)
 	int ret = 0;
 	struct resource *r;
 
-	s = kzalloc(sizeof(struct mxs_auart_port), GFP_KERNEL);
+	s = devm_kzalloc(&pdev->dev,
+			sizeof(struct mxs_auart_port), GFP_KERNEL);
 	if (!s) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
+	s->port.dev = s->dev = &pdev->dev;
+
 	ret = serial_mxs_probe_dt(s, pdev);
 	if (ret > 0)
 		s->port.line = pdev->id < 0 ? 0 : pdev->id;
 	else if (ret < 0)
-		goto out_free;
+		return ret;
 
 	if (of_id) {
 		pdev->id_entry = of_id->data;
 		s->devtype = pdev->id_entry->driver_data;
 	}
 
-	s->clk = clk_get(&pdev->dev, NULL);
-	if (IS_ERR(s->clk)) {
-		ret = PTR_ERR(s->clk);
-		goto out_free;
+	if (is_asm9260_auart(s)) {
+		if (mxs_get_dt_clks(s, pdev))
+			return -ENODEV;
+	} else {
+		s->clk = devm_clk_get(&pdev->dev, NULL);
+		if (IS_ERR(s->clk))
+			return PTR_ERR(s->clk);
 	}
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!r) {
-		ret = -ENXIO;
-		goto out_free_clk;
+		dev_err(s->dev, "platform_get_resource filed!\n");
+		return -ENXIO;
+	}
+
+	if (!devm_request_mem_region(s->dev, r->start, resource_size(r),
+				dev_name(s->dev))) {
+		dev_err(s->dev, "request_mem_region filed!\n");
+		return -ENXIO;
+	}
+
+	s->port.membase = devm_ioremap_nocache(s->dev, r->start,
+			resource_size(r));
+	if (!s->port.membase) {
+		dev_err(s->dev, "ioremap filed!\n");
+		return -ENXIO;
 	}
 
 	s->port.mapbase = r->start;
-	s->port.membase = ioremap(r->start, resource_size(r));
 	s->port.ops = &mxs_auart_ops;
 	s->port.iotype = UPIO_MEM;
 	s->port.fifosize = MXS_AUART_FIFO_SIZE;
 	s->port.uartclk = clk_get_rate(s->clk);
 	s->port.type = PORT_IMX;
-	s->port.dev = s->dev = &pdev->dev;
+
+	mxs_init_regs(s);
 
 	s->ctrl = 0;
 
 	s->irq = platform_get_irq(pdev, 0);
 	s->port.irq = s->irq;
-	ret = request_irq(s->irq, mxs_auart_irq_handle, 0, dev_name(&pdev->dev), s);
+	ret = devm_request_threaded_irq(s->dev, s->irq, NULL,
+			mxs_auart_irq_handle, IRQF_ONESHOT,
+			dev_name(&pdev->dev), s);
 	if (ret)
-		goto out_free_clk;
+		return ret;
 
 	platform_set_drvdata(pdev, s);
 
 	auart_port[s->port.line] = s;
 
-	mxs_auart_reset(&s->port);
+	mxs_auart_reset(s);
 
 	ret = uart_add_one_port(&auart_driver, &s->port);
 	if (ret)
-		goto out_free_irq;
+		goto out;
+
 
-	version = readl(s->port.membase + AUART_VERSION);
-	dev_info(&pdev->dev, "Found APPUART %d.%d.%d\n",
-	       (version >> 24) & 0xff,
-	       (version >> 16) & 0xff, version & 0xffff);
+	/* ASM9260 don't have version reg */
+	if (is_asm9260_auart(s))
+		dev_info(&pdev->dev, "Found APPUART ASM9260\n");
+	else {
+		version = readl(s->port.membase + AUART_VERSION);
+		dev_info(&pdev->dev, "Found APPUART %d.%d.%d\n",
+			 (version >> 24) & 0xff,
+			 (version >> 16) & 0xff, version & 0xffff);
+	}
 
 	return 0;
 
-out_free_irq:
-	auart_port[pdev->id] = NULL;
-	free_irq(s->irq, s);
-out_free_clk:
-	clk_put(s->clk);
-out_free:
-	kfree(s);
 out:
+	auart_port[pdev->id] = NULL;
 	return ret;
 }
 
@@ -1110,11 +1217,6 @@ static int mxs_auart_remove(struct platform_device *pdev)
 	uart_remove_one_port(&auart_driver, &s->port);
 
 	auart_port[pdev->id] = NULL;
-
-	clk_put(s->clk);
-	free_irq(s->irq, s);
-	kfree(s);
-
 	return 0;
 }
 
@@ -1122,7 +1224,7 @@ static struct platform_driver mxs_auart_driver = {
 	.probe = mxs_auart_probe,
 	.remove = mxs_auart_remove,
 	.driver = {
-		.name = "mxs-auart",
+		.name = DRIVER_NAME,
 		.owner = THIS_MODULE,
 		.of_match_table = mxs_auart_dt_ids,
 	},
@@ -1157,4 +1259,4 @@ module_init(mxs_auart_init);
 module_exit(mxs_auart_exit);
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Freescale MXS application uart driver");
-MODULE_ALIAS("platform:mxs-auart");
+MODULE_ALIAS("platform:" DRIVER_NAME);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 9/9] add Alphascale to vendor-prefixes.txt
  2014-10-07  8:55 ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
                     ` (7 preceding siblings ...)
  2014-10-07  8:55   ` [PATCH v3 8/9] tty/serial/mxs-auart.c: add initial Alphascale " Oleksij Rempel
@ 2014-10-07  8:55   ` Oleksij Rempel
  2014-10-10  5:38   ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
  9 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-10-07  8:55 UTC (permalink / raw)
  To: linux-arm-kernel

this company already provided some products, so it make sense to add
them to vendor-prefixes.txt list

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index ac7269f..23c862f 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -11,6 +11,7 @@ adi	Analog Devices, Inc.
 aeroflexgaisler	Aeroflex Gaisler AB
 ak	Asahi Kasei Corp.
 allwinner	Allwinner Technology Co., Ltd.
+alphascale	AlphaScale Integrated Circuits Systems, Inc.
 altr	Altera Corp.
 amcc	Applied Micro Circuits Corporation (APM, formally AMCC)
 amd	Advanced Micro Devices (AMD), Inc.
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 7/9] irqchip/irq-mxs.c: add asm9260 support
  2014-10-07  8:55   ` [PATCH v3 7/9] irqchip/irq-mxs.c: add asm9260 support Oleksij Rempel
@ 2014-10-08  7:45     ` Thomas Gleixner
  2014-10-08 12:11       ` [PATCH v4 1/2] irqchip: mxs: prepare driver for HW with different offsets Oleksij Rempel
  0 siblings, 1 reply; 43+ messages in thread
From: Thomas Gleixner @ 2014-10-08  7:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 7 Oct 2014, Oleksij Rempel wrote:
> --- /dev/null
> +++ b/drivers/irqchip/alphascale,asm9260-icoll.h

Eew. We really can do without the comma in the filename.

> +struct icoll_priv {
> +	void __iomem *vector;
> +	void __iomem *levelack;
> +	void __iomem *ctrl;
> +	void __iomem *stat;
> +	void __iomem *intr;
> +	/* number of interrupts per register */
> +	int intr_reg_num;

So why on earth can't you find a name for this variable which reflects
its meaning? intr_per_reg would be pretty clear, but intr_reg_num is
just confusing as hell.

> +	void __iomem *clear;
> +};
> +
> +struct icoll_priv icoll_priv;

Why is this global?

>  static struct irq_domain *icoll_domain;
>  
> +static u32 icoll_intr_bitshift(struct irq_data *d, u32 bit)
> +{
> +	int n = icoll_priv.intr_reg_num - 1;

Newline between declaration and code.

> +	return bit << ((d->hwirq & n) << n);

I really had to twist my brain around this. A comment would be helpful
for the casual reader/reviewer.

> +}
> +
> +static void __iomem *icoll_intr_reg(struct irq_data *d)
> +{
> +	int n = icoll_priv.intr_reg_num;
> +	return icoll_priv.intr + ((d->hwirq / n) * 0x10);

See above. And aside of that, this should be implemented with a shift
to avoid a divide in the hot path.

> +}
> +
>  static void icoll_ack_irq(struct irq_data *d)
>  {
>  	/*
> @@ -51,19 +88,25 @@ static void icoll_ack_irq(struct irq_data *d)
>  	 * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.
>  	 */
>  	__raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
> -			icoll_base + HW_ICOLL_LEVELACK);
> +			icoll_priv.levelack);

The icoll_priv conversion of that code wants to be a separate
patch. First change existing code then add new functionality.

>  static void icoll_unmask_irq(struct irq_data *d)
>  {
> -	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
> -			icoll_base + HW_ICOLL_INTERRUPTn_SET(d->hwirq));
> +	if (!IS_ERR(icoll_priv.clear)) {

This is a horrible construct. Why isn't it sufficient to do

     if (icoll_priv.clear)

and initialize it to NULL for the IMX case?

> +	icoll_priv.clear	= ERR_PTR(-ENODEV);

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v4 1/2] irqchip: mxs: prepare driver for HW with different offsets
  2014-10-08  7:45     ` Thomas Gleixner
@ 2014-10-08 12:11       ` Oleksij Rempel
  2014-10-08 12:11         ` [PATCH v4 2/2] irqchip: mxs: add Alpascale ASM9260 support Oleksij Rempel
  0 siblings, 1 reply; 43+ messages in thread
From: Oleksij Rempel @ 2014-10-08 12:11 UTC (permalink / raw)
  To: linux-arm-kernel

Some HW has similar functionality but different register offsets.
Make sure we can change offsets dynamically.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/irqchip/irq-mxs.c | 55 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 42 insertions(+), 13 deletions(-)

diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c
index e4acf1e..681125d 100644
--- a/drivers/irqchip/irq-mxs.c
+++ b/drivers/irqchip/irq-mxs.c
@@ -29,18 +29,39 @@
 
 #include "irqchip.h"
 
+/*
+ * this device provide 4 offsets for each register:
+ * 0x0 - plain read write mode
+ * 0x4 - set mode, OR logic.
+ * 0x8 - clr mode, XOR logic.
+ * 0xc - togle mode.
+ */
+#define SET_REG 4
+#define CLR_REG 8
+
 #define HW_ICOLL_VECTOR				0x0000
 #define HW_ICOLL_LEVELACK			0x0010
 #define HW_ICOLL_CTRL				0x0020
 #define HW_ICOLL_STAT_OFFSET			0x0070
-#define HW_ICOLL_INTERRUPTn_SET(n)		(0x0124 + (n) * 0x10)
-#define HW_ICOLL_INTERRUPTn_CLR(n)		(0x0128 + (n) * 0x10)
-#define BM_ICOLL_INTERRUPTn_ENABLE		0x00000004
+#define HW_ICOLL_INTERRUPT0			0x0120
+#define HW_ICOLL_INTERRUPTn(n)			((n) * 0x10)
+#define BM_ICOLL_INTR_ENABLE			BIT(2)
 #define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0	0x1
 
 #define ICOLL_NUM_IRQS		128
 
-static void __iomem *icoll_base;
+struct icoll_priv {
+	void __iomem *vector;
+	void __iomem *levelack;
+	void __iomem *ctrl;
+	void __iomem *stat;
+	void __iomem *intr;
+	/* number of interrupts per register */
+	int intr_per_reg;
+	void __iomem *clear;
+};
+
+static struct icoll_priv icoll_priv;
 static struct irq_domain *icoll_domain;
 
 static void icoll_ack_irq(struct irq_data *d)
@@ -51,19 +72,19 @@ static void icoll_ack_irq(struct irq_data *d)
 	 * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.
 	 */
 	__raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
-			icoll_base + HW_ICOLL_LEVELACK);
+			icoll_priv.levelack);
 }
 
 static void icoll_mask_irq(struct irq_data *d)
 {
-	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
-			icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->hwirq));
+	__raw_writel(BM_ICOLL_INTR_ENABLE,
+			icoll_priv.intr + CLR_REG + HW_ICOLL_INTERRUPTn(d->hwirq));
 }
 
 static void icoll_unmask_irq(struct irq_data *d)
 {
-	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
-			icoll_base + HW_ICOLL_INTERRUPTn_SET(d->hwirq));
+	__raw_writel(BM_ICOLL_INTR_ENABLE,
+			icoll_priv.intr + SET_REG + HW_ICOLL_INTERRUPTn(d->hwirq));
 }
 
 static struct irq_chip mxs_icoll_chip = {
@@ -76,8 +97,8 @@ asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
 {
 	u32 irqnr;
 
-	irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET);
-	__raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR);
+	irqnr = __raw_readl(icoll_priv.stat);
+	__raw_writel(irqnr, icoll_priv.vector);
 	handle_domain_irq(icoll_domain, irqnr, regs);
 }
 
@@ -98,14 +119,22 @@ static struct irq_domain_ops icoll_irq_domain_ops = {
 static int __init icoll_of_init(struct device_node *np,
 			  struct device_node *interrupt_parent)
 {
-	icoll_base = of_iomap(np, 0);
+	void __iomem *icoll_base = of_iomap(np, 0);
 	WARN_ON(!icoll_base);
 
+	icoll_priv.vector	= icoll_base + HW_ICOLL_VECTOR;
+	icoll_priv.levelack	= icoll_base + HW_ICOLL_LEVELACK;
+	icoll_priv.ctrl		= icoll_base + HW_ICOLL_CTRL;
+	icoll_priv.stat		= icoll_base + HW_ICOLL_STAT_OFFSET;
+	icoll_priv.intr		= icoll_base + HW_ICOLL_INTERRUPT0;
+	icoll_priv.intr_per_reg	= 1;
+	icoll_priv.clear	= NULL;
+
 	/*
 	 * Interrupt Collector reset, which initializes the priority
 	 * for each irq to level 0.
 	 */
-	stmp_reset_block(icoll_base + HW_ICOLL_CTRL);
+	stmp_reset_block(icoll_priv.ctrl);
 
 	icoll_domain = irq_domain_add_linear(np, ICOLL_NUM_IRQS,
 					     &icoll_irq_domain_ops, NULL);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v4 2/2] irqchip: mxs: add Alpascale ASM9260 support
  2014-10-08 12:11       ` [PATCH v4 1/2] irqchip: mxs: prepare driver for HW with different offsets Oleksij Rempel
@ 2014-10-08 12:11         ` Oleksij Rempel
  0 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-10-08 12:11 UTC (permalink / raw)
  To: linux-arm-kernel

Freescale iMX23/iMX28 and Alphascale ASM9260 have similar
interrupt collectors. It makes easy to reuse irq-mxs code for ASM9260.
Differences between this devices are fallowing:
- different register offsets
- different count of intterupt lines per register
- ASM9260 don't provide reset bit
- ASM9260 don't support FIQ.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/irqchip/Kconfig                    |   5 ++
 drivers/irqchip/Makefile                   |   2 +-
 drivers/irqchip/alphascale_asm9260-icoll.h | 109 ++++++++++++++++++++++++++++
 drivers/irqchip/irq-mxs.c                  | 112 ++++++++++++++++++++++++++---
 4 files changed, 219 insertions(+), 9 deletions(-)
 create mode 100644 drivers/irqchip/alphascale_asm9260-icoll.h

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index b8632bf..2ee202f 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -113,3 +113,8 @@ config IRQ_CROSSBAR
 	  The primary irqchip invokes the crossbar's callback which inturn allocates
 	  a free irq and configures the IP. Thus the peripheral interrupts are
 	  routed to one of the free irqchip interrupt lines.
+
+config IRQ_MXS
+	bool
+	select IRQ_DOMAIN
+	select STMP_DEVICE
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 73052ba..89c7042 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -4,7 +4,7 @@ obj-$(CONFIG_ARCH_BCM2835)		+= irq-bcm2835.o
 obj-$(CONFIG_ARCH_EXYNOS)		+= exynos-combiner.o
 obj-$(CONFIG_ARCH_MMP)			+= irq-mmp.o
 obj-$(CONFIG_ARCH_MVEBU)		+= irq-armada-370-xp.o
-obj-$(CONFIG_ARCH_MXS)			+= irq-mxs.o
+obj-$(CONFIG_IRQ_MXS)			+= irq-mxs.o
 obj-$(CONFIG_ARCH_S3C24XX)		+= irq-s3c24xx.o
 obj-$(CONFIG_DW_APB_ICTL)		+= irq-dw-apb-ictl.o
 obj-$(CONFIG_METAG)			+= irq-metag-ext.o
diff --git a/drivers/irqchip/alphascale_asm9260-icoll.h b/drivers/irqchip/alphascale_asm9260-icoll.h
new file mode 100644
index 0000000..5cec108
--- /dev/null
+++ b/drivers/irqchip/alphascale_asm9260-icoll.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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.
+ */
+
+#ifndef _ALPHASCALE_ASM9260_ICOLL_H
+#define _ALPHASCALE_ASM9260_ICOLL_H
+
+#define ASM9260_NUM_IRQS		64
+/*
+ * this device provide 4 offsets for each register:
+ * 0x0 - plain read write mode
+ * 0x4 - set mode, OR logic.
+ * 0x8 - clr mode, XOR logic.
+ * 0xc - togle mode.
+ */
+
+#define ASM9260_HW_ICOLL_VECTOR				0x0000
+/*
+ * bits 31:2
+ * This register presents the vector address for the interrupt currently
+ * active on the CPU IRQ input. Writing to this register notifies the
+ * interrupt collector that the interrupt service routine for the current
+ * interrupt has been entered.
+ * The exception trap should have a LDPC instruction from this address:
+ * LDPC ASM9260_HW_ICOLL_VECTOR_ADDR; IRQ exception at 0xffff0018
+ */
+
+/*
+ * The Interrupt Collector Level Acknowledge Register is used by software to
+ * indicate the completion of an interrupt on a specific level.
+ * This register is written at the very end of an interrupt service routine. If
+ * nesting is used then the CPU irq must be turned on before writing to this
+ * register to avoid a race condition in the CPU interrupt hardware.
+ */
+#define ASM9260_HW_ICOLL_LEVELACK			0x0010
+#define ASM9260_BM_LEVELn(nr)				BIT(nr)
+
+#define ASM9260_HW_ICOLL_CTRL				0x0020
+/*
+ * ASM9260_BM_CTRL_SFTRST and ASM9260_BM_CTRL_CLKGATE are not available on
+ * asm9260.
+ */
+#define ASM9260_BM_CTRL_SFTRST				BIT(31)
+#define ASM9260_BM_CTRL_CLKGATE				BIT(30)
+/* disable interrupt level nesting */
+#define ASM9260_BM_CTRL_NO_NESTING			BIT(19)
+/*
+ * Set this bit to one enable the RISC32-style read side effect associated with
+ * the vector address register. In this mode, interrupt in-service is signaled
+ * by the read of the ASM9260_HW_ICOLL_VECTOR register to acquire the interrupt
+ * vector address. Set this bit to zero for normal operation, in which the ISR
+ * signals in-service explicitly by means of a write to the
+ * ASM9260_HW_ICOLL_VECTOR register.
+ * 0 - Must Write to Vector register to go in-service.
+ * 1 - Go in-service as a read side effect
+ */
+#define ASM9260_BM_CTRL_ARM_RSE_MODE			BIT(18)
+#define ASM9260_BM_CTRL_IRQ_ENABLE			BIT(16)
+
+#define ASM9260_HW_ICOLL_STAT_OFFSET			0x0030
+/*
+ * bits 5:0
+ * Vector number of current interrupt. Multiply by 4 and add to vector base
+ * address to obtain the value in ASM9260_HW_ICOLL_VECTOR.
+ */
+
+/*
+ * RAW0 and RAW1 provides a read-only view of the raw interrupt request lines
+ * coming from various parts of the chip. Its purpose is to improve diagnostic
+ * observability.
+ */
+#define ASM9260_HW_ICOLL_RAW0				0x0040
+#define ASM9260_HW_ICOLL_RAW1				0x0050
+
+#define ASM9260_HW_ICOLL_INTERRUPT0			0x0060
+#define ASM9260_HW_ICOLL_INTERRUPTn(n)		(0x0060 + ((n) >> 2) * 0x10)
+/*
+ * WARNING: Modifying the priority of an enabled interrupt may result in
+ * undefined behavior.
+ */
+#define ASM9260_BM_INT_PRIORITY_MASK			0x3
+#define ASM9260_BM_INT_ENABLE				BIT(2)
+#define ASM9260_BM_INT_SOFTIRQ				BIT(3)
+
+#define ASM9260_BM_ICOLL_INTERRUPTn_SHIFT(n)		(((n) & 0x3) << 3)
+#define ASM9260_BM_ICOLL_INTERRUPTn_ENABLE(n)		(1 << (2 + \
+			ASM9260_BM_ICOLL_INTERRUPTn_SHIFT(n)))
+
+#define ASM9260_HW_ICOLL_VBASE				0x0160
+/*
+ * bits 31:2
+ * This bitfield holds the upper 30 bits of the base address of the vector
+ * table.
+ */
+
+#define ASM9260_HW_ICOLL_CLEAR0				0x01d0
+#define ASM9260_HW_ICOLL_CLEAR1				0x01e0
+#define ASM9260_HW_ICOLL_CLEARn(n)			(((n >> 5) * 0x10) \
+							+ SET_REG)
+#define ASM9260_BM_CLEAR_BIT(n)				BIT(n & 0x1f)
+
+/* Scratchpad */
+#define ASM9260_HW_ICOLL_UNDEF_VECTOR			0x01f0
+#endif
diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c
index 681125d..8397c73 100644
--- a/drivers/irqchip/irq-mxs.c
+++ b/drivers/irqchip/irq-mxs.c
@@ -1,5 +1,7 @@
 /*
  * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *	Add Alphascale ASM9260 support.
  *
  * 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
@@ -28,6 +30,7 @@
 #include <asm/exception.h>
 
 #include "irqchip.h"
+#include "alphascale_asm9260-icoll.h"
 
 /*
  * this device provide 4 offsets for each register:
@@ -63,6 +66,33 @@ struct icoll_priv {
 
 static struct icoll_priv icoll_priv;
 static struct irq_domain *icoll_domain;
+static DEFINE_MUTEX(icoll_lock);
+
+/* calculate bit offset depending on number of intterupt per register */
+static u32 icoll_intr_bitshift(struct irq_data *d, u32 bit)
+{
+	/*
+	 * We expect intr_per_reg to be 4 or 1, it means
+	 * "n" will be 3 or 0.
+	 */
+	int n = icoll_priv.intr_per_reg - 1;
+
+	/*
+	 * If n = 0, "bit" is never shifted.
+	 * If n = 3, mask lower part of hwirq to convert it
+	 * in 0, 1, 2 or 3 and then multiply it by 8 (or shift by 3)
+	 */
+	return bit << ((d->hwirq & n) << n);
+}
+
+/* calculate mem offset depending on number of intterupt per register */
+static void __iomem *icoll_intr_reg(struct irq_data *d)
+{
+	int n = icoll_priv.intr_per_reg >> 1;
+
+	/* offset = hwirq / intr_per_reg * 0x10 */
+	return icoll_priv.intr + ((d->hwirq >> n) * 0x10);
+}
 
 static void icoll_ack_irq(struct irq_data *d)
 {
@@ -77,14 +107,21 @@ static void icoll_ack_irq(struct irq_data *d)
 
 static void icoll_mask_irq(struct irq_data *d)
 {
-	__raw_writel(BM_ICOLL_INTR_ENABLE,
-			icoll_priv.intr + CLR_REG + HW_ICOLL_INTERRUPTn(d->hwirq));
+	__raw_writel(icoll_intr_bitshift(d, BM_ICOLL_INTR_ENABLE),
+			icoll_intr_reg(d) + CLR_REG);
 }
 
 static void icoll_unmask_irq(struct irq_data *d)
 {
-	__raw_writel(BM_ICOLL_INTR_ENABLE,
-			icoll_priv.intr + SET_REG + HW_ICOLL_INTERRUPTn(d->hwirq));
+	mutex_lock(&icoll_lock);
+	if (icoll_priv.clear)
+		__raw_writel(ASM9260_BM_CLEAR_BIT(d->hwirq),
+				icoll_priv.clear +
+				ASM9260_HW_ICOLL_CLEARn(d->hwirq));
+
+	__raw_writel(icoll_intr_bitshift(d, BM_ICOLL_INTR_ENABLE),
+			icoll_intr_reg(d) + SET_REG);
+	mutex_unlock(&icoll_lock);
 }
 
 static struct irq_chip mxs_icoll_chip = {
@@ -116,12 +153,41 @@ static struct irq_domain_ops icoll_irq_domain_ops = {
 	.xlate = irq_domain_xlate_onecell,
 };
 
+static void __init icoll_add_domain(struct device_node *np,
+			  int num)
+{
+	icoll_domain = irq_domain_add_linear(np, num,
+					     &icoll_irq_domain_ops, NULL);
+
+	if (!icoll_domain)
+		panic("%s: unable add irq domain", np->full_name);
+	irq_set_default_host(icoll_domain);
+	set_handle_irq(icoll_handle_irq);
+}
+
+static void __iomem * __init icoll_init_iobase(struct device_node *np)
+{
+	struct resource res;
+	void __iomem *icoll_base;
+
+	if (of_address_to_resource(np, 0, &res))
+		panic("%s: unable to get resource", np->full_name);
+
+	if (!request_mem_region(res.start, resource_size(&res), np->name))
+		panic("%s: unable to request mem region", np->full_name);
+
+	icoll_base = ioremap_nocache(res.start, resource_size(&res));
+	if (!icoll_base)
+		panic("%s: unable to map resource", np->full_name);
+	return icoll_base;
+}
+
 static int __init icoll_of_init(struct device_node *np,
 			  struct device_node *interrupt_parent)
 {
-	void __iomem *icoll_base = of_iomap(np, 0);
-	WARN_ON(!icoll_base);
+	void __iomem *icoll_base;
 
+	icoll_base		= icoll_init_iobase(np);
 	icoll_priv.vector	= icoll_base + HW_ICOLL_VECTOR;
 	icoll_priv.levelack	= icoll_base + HW_ICOLL_LEVELACK;
 	icoll_priv.ctrl		= icoll_base + HW_ICOLL_CTRL;
@@ -136,8 +202,38 @@ static int __init icoll_of_init(struct device_node *np,
 	 */
 	stmp_reset_block(icoll_priv.ctrl);
 
-	icoll_domain = irq_domain_add_linear(np, ICOLL_NUM_IRQS,
-					     &icoll_irq_domain_ops, NULL);
+	icoll_add_domain(np, ICOLL_NUM_IRQS);
+
 	return icoll_domain ? 0 : -ENODEV;
 }
 IRQCHIP_DECLARE(mxs, "fsl,icoll", icoll_of_init);
+
+static int __init asm9260_of_init(struct device_node *np,
+			  struct device_node *interrupt_parent)
+{
+	void __iomem *icoll_base;
+	int i;
+
+	icoll_base = icoll_init_iobase(np);
+	icoll_priv.vector	= icoll_base + ASM9260_HW_ICOLL_VECTOR;
+	icoll_priv.levelack	= icoll_base + ASM9260_HW_ICOLL_LEVELACK;
+	icoll_priv.ctrl		= icoll_base + ASM9260_HW_ICOLL_CTRL;
+	icoll_priv.stat		= icoll_base + ASM9260_HW_ICOLL_STAT_OFFSET;
+	icoll_priv.intr		= icoll_base + ASM9260_HW_ICOLL_INTERRUPT0;
+	icoll_priv.intr_per_reg	= 4;
+	icoll_priv.clear	= icoll_base + ASM9260_HW_ICOLL_CLEAR0;
+
+	writel_relaxed(ASM9260_BM_CTRL_IRQ_ENABLE,
+			icoll_priv.ctrl);
+	/*
+	 * ASM9260 don't provide reset bit. So, we need to set level 0
+	 * manually.
+	 */
+	for (i = 0; i < 16 * 0x10; i += 0x10)
+		writel(0, icoll_priv.intr + i);
+
+	icoll_add_domain(np, ASM9260_NUM_IRQS);
+
+	return icoll_domain ? 0 : -ENODEV;
+}
+IRQCHIP_DECLARE(asm9260, "alphascale,asm9260-icoll", asm9260_of_init);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 0/9] initial suport for Alphascale ASM9260
  2014-10-07  8:55 ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
                     ` (8 preceding siblings ...)
  2014-10-07  8:55   ` [PATCH v3 9/9] add Alphascale to vendor-prefixes.txt Oleksij Rempel
@ 2014-10-10  5:38   ` Oleksij Rempel
  9 siblings, 0 replies; 43+ messages in thread
From: Oleksij Rempel @ 2014-10-10  5:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hello all,

if there are no more comments, i will resend this patch set including
updates for irq-mxs driver.

Am 07.10.2014 um 10:55 schrieb Oleksij Rempel:
> This patchset provide initial support for Alpascale ASM9260,
> ARM based SoC.
> 
> Oleksij Rempel (9):
>   ARM: add mach-asm9260
>   arm: add lolevel debug support for asm9260
>   ARM: dts: add DT for Alphascale ASM9260 SoC
>   ARM: add alphascale,acc.txt bindings documentation
>   ARM: clk: add clk-asm9260 driver
>   clocksource: add asm9260_timer driver
>   irqchip/irq-mxs.c: add asm9260 support
>   tty/serial/mxs-auart.c: add initial Alphascale ASM9260 support
>   add Alphascale to vendor-prefixes.txt
> 
>  .../devicetree/bindings/clock/alphascale,acc.txt   | 113 +++++++
>  .../devicetree/bindings/vendor-prefixes.txt        |   1 +
>  arch/arm/Kconfig                                   |   2 +
>  arch/arm/Kconfig.debug                             |  33 +-
>  arch/arm/Makefile                                  |   1 +
>  arch/arm/boot/dts/Makefile                         |   2 +
>  arch/arm/boot/dts/alphascale-asm9260-devkit.dts    |  21 ++
>  arch/arm/boot/dts/alphascale-asm9260.dtsi          | 134 ++++++++
>  arch/arm/include/debug/asm9260.S                   |  31 ++
>  arch/arm/mach-asm9260/Kconfig                      |   8 +
>  arch/arm/mach-asm9260/Makefile                     |   1 +
>  arch/arm/mach-asm9260/core.c                       |  20 ++
>  drivers/clk/Makefile                               |   1 +
>  drivers/clk/clk-asm9260.c                          | 351 +++++++++++++++++++
>  drivers/clocksource/Kconfig                        |   4 +
>  drivers/clocksource/Makefile                       |   1 +
>  drivers/clocksource/asm9260_timer.c                | 234 +++++++++++++
>  drivers/irqchip/Kconfig                            |   5 +
>  drivers/irqchip/Makefile                           |   2 +-
>  drivers/irqchip/alphascale,asm9260-icoll.h         | 109 ++++++
>  drivers/irqchip/irq-mxs.c                          | 142 +++++++-
>  drivers/tty/serial/Kconfig                         |   5 +-
>  drivers/tty/serial/alphascale,asm9260_serial.h     | 373 +++++++++++++++++++++
>  drivers/tty/serial/mxs-auart.c                     | 344 ++++++++++++-------
>  include/dt-bindings/clock/alphascale,asm9260.h     |  97 ++++++
>  25 files changed, 1892 insertions(+), 143 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/clock/alphascale,acc.txt
>  create mode 100644 arch/arm/boot/dts/alphascale-asm9260-devkit.dts
>  create mode 100644 arch/arm/boot/dts/alphascale-asm9260.dtsi
>  create mode 100644 arch/arm/include/debug/asm9260.S
>  create mode 100644 arch/arm/mach-asm9260/Kconfig
>  create mode 100644 arch/arm/mach-asm9260/Makefile
>  create mode 100644 arch/arm/mach-asm9260/core.c
>  create mode 100644 drivers/clk/clk-asm9260.c
>  create mode 100644 drivers/clocksource/asm9260_timer.c
>  create mode 100644 drivers/irqchip/alphascale,asm9260-icoll.h
>  create mode 100644 drivers/tty/serial/alphascale,asm9260_serial.h
>  create mode 100644 include/dt-bindings/clock/alphascale,asm9260.h
> 


-- 
Regards,
Oleksij

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 213 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141010/50bb47b5/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2014-10-10  5:38 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-21 18:41 [PATCH v2 0/8] initial suport for Alpscale ASM9260 Oleksij Rempel
2014-09-21 18:41 ` [PATCH v2 1/8] ARM: add mach-asm9260 Oleksij Rempel
2014-09-22 15:08   ` Arnd Bergmann
2014-09-23  9:00     ` Oleksij Rempel
2014-09-23 10:19       ` Arnd Bergmann
2014-09-24  8:00         ` Oleksij Rempel
2014-09-24  9:43           ` Russell King - ARM Linux
2014-09-24  9:56             ` Oleksij Rempel
2014-09-24 10:25               ` Russell King - ARM Linux
2014-09-24 10:33                 ` Arnd Bergmann
2014-09-24 11:30                   ` Oleksij Rempel
2014-09-21 18:41 ` [PATCH v2 2/8] add include/debug/asm9260.S Oleksij Rempel
2014-09-21 18:45 ` Oleksij Rempel
2014-09-21 18:45   ` [PATCH v2 3/8] add alphascale,asm9260.h binding Oleksij Rempel
2014-09-24 10:15     ` Mark Rutland
2014-09-21 18:45   ` [PATCH v2 4/8] ARM: dts: add DT for Alphascale ASM9260 SoC Oleksij Rempel
2014-09-22 15:14     ` Arnd Bergmann
2014-09-24 10:11     ` Mark Rutland
2014-09-21 18:45   ` [PATCH v2 5/8] clk: add clk-asm9260 driver Oleksij Rempel
2014-09-21 18:45   ` [PATCH v2 6/8] clocksource: add asm9260_timer driver Oleksij Rempel
2014-09-21 18:45   ` [PATCH v2 7/8] irqchip: add irq-asm9260 driver Oleksij Rempel
2014-09-22 15:22     ` Arnd Bergmann
2014-09-21 18:45   ` [PATCH v2 8/8] tty/serial: add asm9260-serial driver Oleksij Rempel
2014-09-22 15:26     ` Arnd Bergmann
2014-09-22 16:04       ` Oleksij Rempel
2014-09-24  9:24       ` Oleksij Rempel
2014-09-24 10:20         ` Arnd Bergmann
2014-09-23 11:32 ` [PATCH v2 0/8] initial suport for Alpscale ASM9260 Arnd Bergmann
2014-09-24 10:13 ` Mark Rutland
2014-10-07  8:55 ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel
2014-10-07  8:55   ` [PATCH v3 1/9] ARM: add mach-asm9260 Oleksij Rempel
2014-10-07  8:55   ` [PATCH v3 2/9] arm: add lolevel debug support for asm9260 Oleksij Rempel
2014-10-07  8:55   ` [PATCH v3 3/9] ARM: dts: add DT for Alphascale ASM9260 SoC Oleksij Rempel
2014-10-07  8:55   ` [PATCH v3 4/9] ARM: add alphascale,acc.txt bindings documentation Oleksij Rempel
2014-10-07  8:55   ` [PATCH v3 5/9] ARM: clk: add clk-asm9260 driver Oleksij Rempel
2014-10-07  8:55   ` [PATCH v3 6/9] clocksource: add asm9260_timer driver Oleksij Rempel
2014-10-07  8:55   ` [PATCH v3 7/9] irqchip/irq-mxs.c: add asm9260 support Oleksij Rempel
2014-10-08  7:45     ` Thomas Gleixner
2014-10-08 12:11       ` [PATCH v4 1/2] irqchip: mxs: prepare driver for HW with different offsets Oleksij Rempel
2014-10-08 12:11         ` [PATCH v4 2/2] irqchip: mxs: add Alpascale ASM9260 support Oleksij Rempel
2014-10-07  8:55   ` [PATCH v3 8/9] tty/serial/mxs-auart.c: add initial Alphascale " Oleksij Rempel
2014-10-07  8:55   ` [PATCH v3 9/9] add Alphascale to vendor-prefixes.txt Oleksij Rempel
2014-10-10  5:38   ` [PATCH v3 0/9] initial suport for Alphascale ASM9260 Oleksij Rempel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.