All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-15 14:49 ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: olof, devicetree-discuss, Florian Fainelli, arnd

Hi all,

This patchset adds basic support for Mocship MCS814x, and in particular
MCS8140, and allows one booting to user space. Two off-the-shelf boards
are support: Tigal/Robotech RBT-832 and Devolo dLAN USB Extender.

Support for other on-board peripherals will obviously be contributed later
once the basic SoC support has been accepted.

Florian Fainelli (8):
  ARM: support for Moschip MCS814x SoCs
  ARM: MCS814x: add Device Tree based MCS8140 board support
  ARM: MCS814x: add Device Tree bindings documentation
  ARM: MCS814X: add DTS file for Tigal/Robotech RBT-832
  ARM: MCS814x: add DTS file for Devolo dLAN USB Extender
  ARM: MCS814x: provide a sample defconfig file
  ARM: MSC814X: add Kconfig and Makefile to arch/arm
  ARM: MSC814x: add MAINTAINERS entry

 .../bindings/arm/mcs814x/mcs814x-intc.txt          |   18 +
 .../bindings/arm/mcs814x/mcs814x-pci.txt           |   16 +
 .../bindings/arm/mcs814x/mcs814x-timer.txt         |   16 +
 .../devicetree/bindings/arm/mcs814x/mcs814x.txt    |   13 +
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 MAINTAINERS                                        |    6 +
 arch/arm/Kconfig                                   |   28 ++
 arch/arm/Makefile                                  |    1 +
 arch/arm/boot/dts/dlan-usb-extender.dts            |   68 +++
 arch/arm/boot/dts/mcs8140.dtsi                     |  207 +++++++++
 arch/arm/boot/dts/rbt-832.dts                      |   83 ++++
 arch/arm/configs/mcs814x_defconfig                 |  174 ++++++++
 arch/arm/mach-mcs814x/Kconfig                      |   29 ++
 arch/arm/mach-mcs814x/Makefile                     |    6 +
 arch/arm/mach-mcs814x/Makefile.boot                |    6 +
 arch/arm/mach-mcs814x/board-mcs8140-dt.c           |   46 ++
 arch/arm/mach-mcs814x/clock.c                      |  271 ++++++++++++
 arch/arm/mach-mcs814x/common.c                     |   97 +++++
 arch/arm/mach-mcs814x/common.h                     |   15 +
 arch/arm/mach-mcs814x/include/mach/cpu.h           |   16 +
 arch/arm/mach-mcs814x/include/mach/debug-macro.S   |   11 +
 arch/arm/mach-mcs814x/include/mach/entry-macro.S   |   29 ++
 arch/arm/mach-mcs814x/include/mach/gpio.h          |    1 +
 arch/arm/mach-mcs814x/include/mach/hardware.h      |   16 +
 arch/arm/mach-mcs814x/include/mach/irqs.h          |   22 +
 arch/arm/mach-mcs814x/include/mach/mcs814x.h       |   53 +++
 arch/arm/mach-mcs814x/include/mach/memory.h        |   16 +
 arch/arm/mach-mcs814x/include/mach/timex.h         |   18 +
 arch/arm/mach-mcs814x/include/mach/uncompress.h    |   41 ++
 arch/arm/mach-mcs814x/irq.c                        |   69 +++
 arch/arm/mach-mcs814x/pci.c                        |  446 ++++++++++++++++++++
 arch/arm/mach-mcs814x/timer.c                      |  133 ++++++
 32 files changed, 1972 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x-intc.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x-timer.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x.txt
 create mode 100644 arch/arm/boot/dts/dlan-usb-extender.dts
 create mode 100644 arch/arm/boot/dts/mcs8140.dtsi
 create mode 100644 arch/arm/boot/dts/rbt-832.dts
 create mode 100644 arch/arm/configs/mcs814x_defconfig
 create mode 100644 arch/arm/mach-mcs814x/Kconfig
 create mode 100644 arch/arm/mach-mcs814x/Makefile
 create mode 100644 arch/arm/mach-mcs814x/Makefile.boot
 create mode 100644 arch/arm/mach-mcs814x/board-mcs8140-dt.c
 create mode 100644 arch/arm/mach-mcs814x/clock.c
 create mode 100644 arch/arm/mach-mcs814x/common.c
 create mode 100644 arch/arm/mach-mcs814x/common.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/cpu.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-mcs814x/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-mcs814x/include/mach/gpio.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/hardware.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/irqs.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/mcs814x.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/memory.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/timex.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-mcs814x/irq.c
 create mode 100644 arch/arm/mach-mcs814x/pci.c
 create mode 100644 arch/arm/mach-mcs814x/timer.c

-- 
1.7.10.4

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

* [PATCH 0/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-15 14:49 ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

This patchset adds basic support for Mocship MCS814x, and in particular
MCS8140, and allows one booting to user space. Two off-the-shelf boards
are support: Tigal/Robotech RBT-832 and Devolo dLAN USB Extender.

Support for other on-board peripherals will obviously be contributed later
once the basic SoC support has been accepted.

Florian Fainelli (8):
  ARM: support for Moschip MCS814x SoCs
  ARM: MCS814x: add Device Tree based MCS8140 board support
  ARM: MCS814x: add Device Tree bindings documentation
  ARM: MCS814X: add DTS file for Tigal/Robotech RBT-832
  ARM: MCS814x: add DTS file for Devolo dLAN USB Extender
  ARM: MCS814x: provide a sample defconfig file
  ARM: MSC814X: add Kconfig and Makefile to arch/arm
  ARM: MSC814x: add MAINTAINERS entry

 .../bindings/arm/mcs814x/mcs814x-intc.txt          |   18 +
 .../bindings/arm/mcs814x/mcs814x-pci.txt           |   16 +
 .../bindings/arm/mcs814x/mcs814x-timer.txt         |   16 +
 .../devicetree/bindings/arm/mcs814x/mcs814x.txt    |   13 +
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 MAINTAINERS                                        |    6 +
 arch/arm/Kconfig                                   |   28 ++
 arch/arm/Makefile                                  |    1 +
 arch/arm/boot/dts/dlan-usb-extender.dts            |   68 +++
 arch/arm/boot/dts/mcs8140.dtsi                     |  207 +++++++++
 arch/arm/boot/dts/rbt-832.dts                      |   83 ++++
 arch/arm/configs/mcs814x_defconfig                 |  174 ++++++++
 arch/arm/mach-mcs814x/Kconfig                      |   29 ++
 arch/arm/mach-mcs814x/Makefile                     |    6 +
 arch/arm/mach-mcs814x/Makefile.boot                |    6 +
 arch/arm/mach-mcs814x/board-mcs8140-dt.c           |   46 ++
 arch/arm/mach-mcs814x/clock.c                      |  271 ++++++++++++
 arch/arm/mach-mcs814x/common.c                     |   97 +++++
 arch/arm/mach-mcs814x/common.h                     |   15 +
 arch/arm/mach-mcs814x/include/mach/cpu.h           |   16 +
 arch/arm/mach-mcs814x/include/mach/debug-macro.S   |   11 +
 arch/arm/mach-mcs814x/include/mach/entry-macro.S   |   29 ++
 arch/arm/mach-mcs814x/include/mach/gpio.h          |    1 +
 arch/arm/mach-mcs814x/include/mach/hardware.h      |   16 +
 arch/arm/mach-mcs814x/include/mach/irqs.h          |   22 +
 arch/arm/mach-mcs814x/include/mach/mcs814x.h       |   53 +++
 arch/arm/mach-mcs814x/include/mach/memory.h        |   16 +
 arch/arm/mach-mcs814x/include/mach/timex.h         |   18 +
 arch/arm/mach-mcs814x/include/mach/uncompress.h    |   41 ++
 arch/arm/mach-mcs814x/irq.c                        |   69 +++
 arch/arm/mach-mcs814x/pci.c                        |  446 ++++++++++++++++++++
 arch/arm/mach-mcs814x/timer.c                      |  133 ++++++
 32 files changed, 1972 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x-intc.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x-timer.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x.txt
 create mode 100644 arch/arm/boot/dts/dlan-usb-extender.dts
 create mode 100644 arch/arm/boot/dts/mcs8140.dtsi
 create mode 100644 arch/arm/boot/dts/rbt-832.dts
 create mode 100644 arch/arm/configs/mcs814x_defconfig
 create mode 100644 arch/arm/mach-mcs814x/Kconfig
 create mode 100644 arch/arm/mach-mcs814x/Makefile
 create mode 100644 arch/arm/mach-mcs814x/Makefile.boot
 create mode 100644 arch/arm/mach-mcs814x/board-mcs8140-dt.c
 create mode 100644 arch/arm/mach-mcs814x/clock.c
 create mode 100644 arch/arm/mach-mcs814x/common.c
 create mode 100644 arch/arm/mach-mcs814x/common.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/cpu.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-mcs814x/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-mcs814x/include/mach/gpio.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/hardware.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/irqs.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/mcs814x.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/memory.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/timex.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-mcs814x/irq.c
 create mode 100644 arch/arm/mach-mcs814x/pci.c
 create mode 100644 arch/arm/mach-mcs814x/timer.c

-- 
1.7.10.4

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-15 14:49 ` Florian Fainelli
@ 2012-07-15 14:49   ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: olof, devicetree-discuss, Florian Fainelli, arnd

This patch adds support for Moschip's MCS814x SoCs, and in particular
MCS8140. This SoC has the following characteristics:

- uses an ARM926EJS CPU core with an AHB/VCI64 interconnect
- simple clocking scheme and clock gating
- strap registers defining CPU, SDRAM and Timer frequency
- various on-chip peripherals:
	* 2x OHCI controller
	* 1x EHCI controller
	* IPsec unit
	* Watchdog
	* Random number generator
	* 10/100 Ethernet MAC w/ TCP offloading and checksumming
	* I2S
	* 4 + 20 GPIOs
	* PCI master interface

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 arch/arm/mach-mcs814x/Kconfig                    |   11 +
 arch/arm/mach-mcs814x/Makefile                   |    6 +
 arch/arm/mach-mcs814x/Makefile.boot              |    3 +
 arch/arm/mach-mcs814x/clock.c                    |  271 +++++++++++++
 arch/arm/mach-mcs814x/common.c                   |   97 +++++
 arch/arm/mach-mcs814x/common.h                   |   15 +
 arch/arm/mach-mcs814x/include/mach/cpu.h         |   16 +
 arch/arm/mach-mcs814x/include/mach/debug-macro.S |   11 +
 arch/arm/mach-mcs814x/include/mach/entry-macro.S |   29 ++
 arch/arm/mach-mcs814x/include/mach/gpio.h        |    1 +
 arch/arm/mach-mcs814x/include/mach/hardware.h    |   16 +
 arch/arm/mach-mcs814x/include/mach/irqs.h        |   22 ++
 arch/arm/mach-mcs814x/include/mach/mcs814x.h     |   53 +++
 arch/arm/mach-mcs814x/include/mach/memory.h      |   16 +
 arch/arm/mach-mcs814x/include/mach/timex.h       |   18 +
 arch/arm/mach-mcs814x/include/mach/uncompress.h  |   41 ++
 arch/arm/mach-mcs814x/irq.c                      |   69 ++++
 arch/arm/mach-mcs814x/pci.c                      |  446 ++++++++++++++++++++++
 arch/arm/mach-mcs814x/timer.c                    |  133 +++++++
 19 files changed, 1274 insertions(+)
 create mode 100644 arch/arm/mach-mcs814x/Kconfig
 create mode 100644 arch/arm/mach-mcs814x/Makefile
 create mode 100644 arch/arm/mach-mcs814x/Makefile.boot
 create mode 100644 arch/arm/mach-mcs814x/clock.c
 create mode 100644 arch/arm/mach-mcs814x/common.c
 create mode 100644 arch/arm/mach-mcs814x/common.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/cpu.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-mcs814x/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-mcs814x/include/mach/gpio.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/hardware.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/irqs.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/mcs814x.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/memory.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/timex.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-mcs814x/irq.c
 create mode 100644 arch/arm/mach-mcs814x/pci.c
 create mode 100644 arch/arm/mach-mcs814x/timer.c

diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
new file mode 100644
index 0000000..c89422f
--- /dev/null
+++ b/arch/arm/mach-mcs814x/Kconfig
@@ -0,0 +1,11 @@
+if ARCH_MCS814X
+
+config MCS8140
+	select CPU_ARM926T
+	bool
+
+menu "Moschip MCS8140 boards"
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-mcs814x/Makefile b/arch/arm/mach-mcs814x/Makefile
new file mode 100644
index 0000000..bad95cc
--- /dev/null
+++ b/arch/arm/mach-mcs814x/Makefile
@@ -0,0 +1,6 @@
+obj-y += clock.o
+obj-y += common.o
+obj-y += irq.o
+obj-y += timer.o
+obj-y += board-mcs8140-dt.o
+obj-$(CONFIG_PCI)       += pci.o
diff --git a/arch/arm/mach-mcs814x/Makefile.boot b/arch/arm/mach-mcs814x/Makefile.boot
new file mode 100644
index 0000000..414db8b
--- /dev/null
+++ b/arch/arm/mach-mcs814x/Makefile.boot
@@ -0,0 +1,3 @@
+    zreladdr-y := 0x00008000
+ params_phys-y := 0x00000008
+ initrd_phys-y := 0x00400000
diff --git a/arch/arm/mach-mcs814x/clock.c b/arch/arm/mach-mcs814x/clock.c
new file mode 100644
index 0000000..eb30ae2
--- /dev/null
+++ b/arch/arm/mach-mcs814x/clock.c
@@ -0,0 +1,271 @@
+/*
+ * Moschip MCS814x clock routines
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under GPLv2
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/export.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+
+#include <mach/mcs814x.h>
+
+#include "common.h"
+
+#define KHZ	1000
+#define MHZ	(KHZ * KHZ)
+
+struct clk_ops {
+	unsigned long (*get_rate)(struct clk *clk);
+	int (*set_rate)(struct clk *clk, unsigned long rate);
+	struct clk *(*get_parent)(struct clk *clk);
+	int (*enable)(struct clk *clk, int enable);
+};
+
+struct clk {
+	struct clk *parent;		/* parent clk */
+	unsigned long rate;		/* clock rate in Hz */
+	unsigned long divider;		/* clock divider */
+	u32 usecount;			/* reference count */
+	struct clk_ops *ops;		/* clock operation */
+	u32 enable_reg;			/* clock enable register */
+	u32 enable_mask;		/* clock enable mask */
+};
+
+static unsigned long clk_divide_parent(struct clk *clk)
+{
+	if (clk->parent && clk->divider)
+		return clk_get_rate(clk->parent) / clk->divider;
+	else
+		return 0;
+}
+
+static int clk_local_onoff_enable(struct clk *clk, int enable)
+{
+	u32 tmp;
+
+	/* no enable_reg means the clock is always enabled */
+	if (!clk->enable_reg)
+		return 0;
+
+	tmp = __raw_readl(mcs814x_sysdbg_base + clk->enable_reg);
+	if (!enable)
+		tmp &= ~clk->enable_mask;
+	else
+		tmp |= clk->enable_mask;
+
+	__raw_writel(tmp, mcs814x_sysdbg_base + clk->enable_reg);
+
+	return 0;
+}
+
+static struct clk_ops default_clk_ops = {
+	.get_rate	= clk_divide_parent,
+	.enable		= clk_local_onoff_enable,
+};
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+static const unsigned long cpu_freq_table[] = {
+	175000,
+	300000,
+	125000,
+	137500,
+	212500,
+	250000,
+	162500,
+	187500,
+	162500,
+	150000,
+	225000,
+	237500,
+	200000,
+	262500,
+	275000,
+	287500
+};
+
+static struct clk clk_cpu;
+
+/* System clock is fixed at 50Mhz */
+static struct clk clk_sys = {
+	.rate	= 50 * MHZ,
+};
+
+static struct clk clk_sdram;
+
+static struct clk clk_timer0 = {
+	.parent	= &clk_sdram,
+	.divider = 2,
+	.ops	= &default_clk_ops,
+};
+
+static struct clk clk_timer1_2 = {
+	.parent	= &clk_sys,
+};
+
+/* Watchdog clock is system clock / 128 */
+static struct clk clk_wdt = {
+	.parent	= &clk_sys,
+	.divider = 128,
+	.ops	= &default_clk_ops,
+};
+
+static struct clk clk_emac = {
+	.ops		= &default_clk_ops,
+	.enable_reg	= SYSDBG_SYSCTL,
+	.enable_mask	= SYSCTL_EMAC,
+};
+
+static struct clk clk_ephy = {
+	.ops		= &default_clk_ops,
+	.enable_reg	= SYSDBG_PLL_CTL,
+	.enable_mask	= ~SYSCTL_EPHY,	/* active low */
+};
+
+static struct clk clk_cipher = {
+	.ops		= &default_clk_ops,
+	.enable_reg	= SYSDBG_SYSCTL,
+	.enable_mask	= SYSCTL_CIPHER,
+};
+
+#define CLK(_dev, _con, _clk)	\
+{ .dev_id = (_dev), .con_id = (_con), .clk = (_clk) },
+
+static struct clk_lookup mcs814x_chip_clks[] = {
+	CLK("cpu", NULL, &clk_cpu)
+	CLK("sys", NULL, &clk_sys)
+	CLK("sdram", NULL, &clk_sdram)
+	/* 32-bits timer0 */
+	CLK("timer0", NULL, &clk_timer0)
+	/* 16-bits timer1 */
+	CLK("timer1", NULL, &clk_timer1_2)
+	/* 64-bits timer2, same as timer 1 */
+	CLK("timer2", NULL, &clk_timer1_2)
+	CLK(NULL, "wdt", &clk_wdt)
+	CLK(NULL, "emac", &clk_emac)
+	CLK(NULL, "ephy", &clk_ephy)
+	CLK(NULL, "cipher", &clk_cipher)
+};
+
+static void local_clk_disable(struct clk *clk)
+{
+	WARN_ON(!clk->usecount);
+
+	if (clk->usecount > 0) {
+		clk->usecount--;
+
+		if ((clk->usecount == 0) && (clk->ops->enable))
+			clk->ops->enable(clk, 0);
+
+		if (clk->parent)
+			local_clk_disable(clk->parent);
+	}
+}
+
+static int local_clk_enable(struct clk *clk)
+{
+	int ret = 0;
+
+	if (clk->parent)
+		ret = local_clk_enable(clk->parent);
+
+	if (ret)
+		return ret;
+
+	if ((clk->usecount == 0) && (clk->ops->enable))
+		ret = clk->ops->enable(clk, 1);
+
+	if (!ret)
+		clk->usecount++;
+	else if (clk->parent && clk->parent->ops->enable)
+		local_clk_disable(clk->parent);
+
+	return ret;
+}
+
+int clk_enable(struct clk *clk)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	ret = local_clk_enable(clk);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	local_clk_disable(clk);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (unlikely(IS_ERR_OR_NULL(clk)))
+		return 0;
+
+	if (clk->rate)
+		return clk->rate;
+
+	if (clk->ops && clk->ops->get_rate)
+		return clk->ops->get_rate(clk);
+
+	return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+	unsigned long flags;
+
+	if (unlikely(IS_ERR_OR_NULL(clk)))
+		return NULL;
+
+	if (!clk->ops || !clk->ops->get_parent)
+		return clk->parent;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	clk->parent = clk->ops->get_parent(clk);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+
+	return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+void __init mcs814x_clk_init(void)
+{
+	u32 bs1;
+	u8 cpu_freq;
+
+	clkdev_add_table(mcs814x_chip_clks, ARRAY_SIZE(mcs814x_chip_clks));
+
+	/* read the bootstrap registers to know the exact clocking scheme */
+	bs1 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS1);
+	cpu_freq = (bs1 >> CPU_FREQ_SHIFT) & CPU_FREQ_MASK;
+
+	pr_info("CPU frequency: %lu (kHz)\n", cpu_freq_table[cpu_freq]);
+	clk_cpu.rate = cpu_freq * KHZ;
+
+	/* read SDRAM frequency */
+	if (bs1 & SDRAM_FREQ_BIT)
+		clk_sdram.rate = 100 * MHZ;
+	else
+		clk_sdram.rate = 133 * MHZ;
+
+	pr_info("SDRAM frequency: %lu (MHz)\n", clk_sdram.rate / MHZ);
+}
+
diff --git a/arch/arm/mach-mcs814x/common.c b/arch/arm/mach-mcs814x/common.c
new file mode 100644
index 0000000..0652633
--- /dev/null
+++ b/arch/arm/mach-mcs814x/common.c
@@ -0,0 +1,97 @@
+/*
+ * arch/arm/mach-mcs814x/common.c
+ *
+ * Core functions for Moschip MCS814x SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/mcs814x.h>
+#include <mach/cpu.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+void __iomem *mcs814x_sysdbg_base;
+
+static struct map_desc mcs814x_io_desc[] __initdata = {
+	{
+		.virtual	= MCS814X_IO_BASE,
+		.pfn		= __phys_to_pfn(MCS814X_IO_START),
+		.length		= MCS814X_IO_SIZE,
+		.type		= MT_DEVICE
+	},
+};
+
+struct cpu_mode {
+	const char *name;
+	int gpio_start;
+	int gpio_end;
+};
+
+static const struct cpu_mode cpu_modes[] = {
+	{
+		.name		= "I2S",
+		.gpio_start	= 4,
+		.gpio_end	= 8,
+	},
+	{
+		.name		= "UART",
+		.gpio_start	= 4,
+		.gpio_end	= 9,
+	},
+	{
+		.name		= "External MII",
+		.gpio_start	= 0,
+		.gpio_end	= 16,
+	},
+	{
+		.name		= "Normal",
+		.gpio_start	= -1,
+		.gpio_end	= -1,
+	},
+};
+
+void __init mcs814x_init_machine(void)
+{
+	u32 bs2, cpu_mode;
+	int gpio;
+
+	bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
+	cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
+
+	pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
+
+	/* request the gpios since the pins are muxed for functionnality */
+	for (gpio = cpu_modes[cpu_mode].gpio_start;
+		gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
+		if (gpio != -1)
+			gpio_request(gpio, cpu_modes[cpu_mode].name);
+	}
+}
+
+void __init mcs814x_map_io(void)
+{
+	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
+
+	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
+					MCS814X_SYSDBG_SIZE);
+	if (!mcs814x_sysdbg_base)
+		panic("unable to remap sysdbg base");
+}
+
+void mcs814x_restart(char mode, const char *cmd)
+{
+	__raw_writel(~(1 << 31), mcs814x_sysdbg_base);
+}
diff --git a/arch/arm/mach-mcs814x/common.h b/arch/arm/mach-mcs814x/common.h
new file mode 100644
index 0000000..e523abe
--- /dev/null
+++ b/arch/arm/mach-mcs814x/common.h
@@ -0,0 +1,15 @@
+#ifndef __ARCH_MCS814X_COMMON_H
+#define __ARCH_MCS814X_COMMON_H
+
+#include <asm/mach/time.h>
+
+void mcs814x_map_io(void);
+void mcs814x_clk_init(void);
+void mcs814x_of_irq_init(void);
+void mcs814x_init_machine(void);
+void mcs814x_handle_irq(struct pt_regs *regs);
+void mcs814x_restart(char mode, const char *cmd);
+extern struct sys_timer mcs814x_timer;
+extern void __iomem *mcs814x_sysdbg_base;
+
+#endif /* __ARCH_MCS814X_COMMON_H */
diff --git a/arch/arm/mach-mcs814x/include/mach/cpu.h b/arch/arm/mach-mcs814x/include/mach/cpu.h
new file mode 100644
index 0000000..1ef3c4a
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/cpu.h
@@ -0,0 +1,16 @@
+#ifndef __ASM_ARCH_CPU_H__
+#define __ASM_ARCH_CPU_H__
+
+#include <asm/cputype.h>
+
+#define MCS8140_ID	0x41069260	/* ARM926EJ-S */
+#define MCS814X_MASK	0xff0ffff0
+
+#ifdef CONFIG_MCS8140
+/* Moschip MCS8140 is based on an ARM926EJ-S core */
+#define soc_is_mcs8140()	((read_cpuid_id() & MCS814X_MASK) == MCS8140_ID)
+#else
+#define soc_is_mcs8140()	(0)
+#endif /* !CONFIG_MCS8140 */
+
+#endif /* __ASM_ARCH_CPU_H__ */
diff --git a/arch/arm/mach-mcs814x/include/mach/debug-macro.S b/arch/arm/mach-mcs814x/include/mach/debug-macro.S
new file mode 100644
index 0000000..93ecea4
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/debug-macro.S
@@ -0,0 +1,11 @@
+#include <mach/mcs814x.h>
+
+                .macro  addruart, rp, rv, tmp
+		ldr	\rp, =MCS814X_PHYS_BASE
+		ldr	\rv, =MCS814X_VIRT_BASE
+		orr	\rp, \rp, #MCS814X_UART
+		orr	\rv, \rv, #MCS814X_UART
+                .endm
+
+#define UART_SHIFT	2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-mcs814x/include/mach/entry-macro.S b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
new file mode 100644
index 0000000..cbad566
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
@@ -0,0 +1,29 @@
+#include <mach/mcs814x.h>
+                .macro  disable_fiq
+                .endm
+
+		.macro arch_ret_to_user, tmp1, tmp2
+		.endm
+
+		.macro  get_irqnr_preamble, base, tmp
+		ldr	\base, =mcs814x_intc_base@ base virtual address of INTC
+		ldr	\base, [\base]
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	\tmp, #MCS814X_IRQ_STS0	 @ load tmp with STS0 register offset
+		ldr	\irqstat, [\base, \tmp]	 @ load value at base + tmp
+		tst	\irqstat, \irqstat       @ test if no active IRQ's
+		beq	1002f                    @ if no active irqs return with status 0
+		mov	\irqnr, #0               @ start from irq zero
+		mov	\tmp,   #1               @ the mask initially 1
+1001:
+		tst     \irqstat, \tmp           @ and with mask
+		addeq   \irqnr, \irqnr, #1       @ if  zero then add one to nr
+		moveq   \tmp,   \tmp, lsl #1     @ shift mask one to left
+		beq     1001b                    @ if  zero then loop again
+		mov     \irqstat, \tmp           @ save the return mask
+		mov	\tmp, #MCS814X_IRQ_STS0  @ load tmp with ICR offset
+		str     \irqstat,  [\base, \tmp] @ clear irq with selected mask
+1002:
+                .endm
diff --git a/arch/arm/mach-mcs814x/include/mach/gpio.h b/arch/arm/mach-mcs814x/include/mach/gpio.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/gpio.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/arm/mach-mcs814x/include/mach/hardware.h b/arch/arm/mach-mcs814x/include/mach/hardware.h
new file mode 100644
index 0000000..529f648
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/hardware.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2003 Artec Design Ltd.
+ *
+ * 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 __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include "mcs814x.h"
+
+#endif
+
diff --git a/arch/arm/mach-mcs814x/include/mach/irqs.h b/arch/arm/mach-mcs814x/include/mach/irqs.h
new file mode 100644
index 0000000..78021d1
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/irqs.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2003 Artec Design Ltd.
+ *
+ * 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 __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define FIQ_START	0
+
+#define NR_IRQS		32
+
+#define IRQ_PCI_INTA            22
+#define IRQ_PCI_INTB            23
+#define IRQ_PCI_INTC            24
+#define IRQ_PCI_INTD            26
+
+#endif
diff --git a/arch/arm/mach-mcs814x/include/mach/mcs814x.h b/arch/arm/mach-mcs814x/include/mach/mcs814x.h
new file mode 100644
index 0000000..a4a369e
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/mcs814x.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2003 Artec Design Ltd.
+ *
+ * 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 __ASM_ARCH_MCS814X_H
+#define __ASM_ARCH_MCS814X_H
+
+#define MCS814X_IO_BASE		0xF0000000
+#define MCS814X_IO_START	0x40000000
+#define MCS814X_IO_SIZE		0x00100000
+
+/* IRQ controller register offset */
+#define MCS814X_IRQ_ICR		0x00
+#define MCS814X_IRQ_ISR		0x04
+#define MCS814X_IRQ_MASK	0x20
+#define MCS814X_IRQ_STS0	0x40
+
+#define MCS814X_PHYS_BASE	0x40000000
+#define MCS814X_VIRT_BASE	MCS814X_IO_BASE
+
+#define MCS814X_UART		0x000DC000
+#define MCS814X_DBGLED		0x000EC000
+#define MCS814X_SYSDBG		0x000F8000
+#define MCS814X_SYSDBG_SIZE	0x50
+
+/* System configuration and bootstrap registers */
+#define SYSDBG_BS1		0x00
+#define  CPU_FREQ_SHIFT		27
+#define  CPU_FREQ_MASK		0x0F
+#define  SDRAM_FREQ_BIT		(1 << 22)
+
+#define SYSDBG_BS2		0x04
+#define  LED_CFG_MASK		0x03
+#define  CPU_MODE_SHIFT		23
+#define  CPU_MODE_MASK		0x03
+
+#define SYSDBG_SYSCTL_MAC	0x1d
+#define  BUF_SHIFT_BIT		(1 << 0)
+
+#define SYSDBG_SYSCTL		0x08
+#define  SYSCTL_EMAC		(1 << 0)
+#define  SYSCTL_EPHY		(1 << 0) /* active low */
+#define  SYSCTL_CIPHER		(1 << 16)
+
+#define SYSDBG_PLL_CTL		0x3C
+
+#endif /* __ASM_ARCH_MCS814X_H */
+
diff --git a/arch/arm/mach-mcs814x/include/mach/memory.h b/arch/arm/mach-mcs814x/include/mach/memory.h
new file mode 100644
index 0000000..ad87c7b
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/memory.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2003 Artec Design Ltd.
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET		UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-mcs814x/include/mach/timex.h b/arch/arm/mach-mcs814x/include/mach/timex.h
new file mode 100644
index 0000000..f05c8ee
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/timex.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2003 Artec Design Ltd.
+ *
+ * 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 __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/*
+ * Timex specification for MCS814X
+ */
+#define CLOCK_TICK_RATE		100
+
+#endif
diff --git a/arch/arm/mach-mcs814x/include/mach/uncompress.h b/arch/arm/mach-mcs814x/include/mach/uncompress.h
new file mode 100644
index 0000000..21b9821
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/uncompress.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * 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 __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <linux/serial_reg.h>
+#include <asm/io.h>
+#include <mach/mcs814x.h>
+#include <mach/cpu.h>
+
+#define UART_SHIFT	(2)
+
+/* cannot be static because the code will be inlined */
+void __iomem *uart_base;
+
+static inline void putc(int c)
+{
+	while (!(__raw_readb(uart_base + (UART_LSR << UART_SHIFT)) & UART_LSR_TEMT))
+		;
+	__raw_writeb(c, uart_base + (UART_TX << UART_SHIFT));
+}
+
+static inline void flush(void)
+{
+}
+
+static inline void arch_decomp_setup(void)
+{
+	if (soc_is_mcs8140())
+		uart_base = (void __iomem *)(MCS814X_PHYS_BASE + MCS814X_UART);
+}
+
+#define arch_decomp_wdog()
+
+#endif
diff --git a/arch/arm/mach-mcs814x/irq.c b/arch/arm/mach-mcs814x/irq.c
new file mode 100644
index 0000000..089937b
--- /dev/null
+++ b/arch/arm/mach-mcs814x/irq.c
@@ -0,0 +1,69 @@
+/*
+ * Moschip MCS814x generic interrupt controller routines
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under the GPLv2
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+#include <asm/mach/irq.h>
+#include <mach/mcs814x.h>
+
+void __iomem *mcs814x_intc_base;
+
+static void __init mcs814x_alloc_gc(void __iomem *base, unsigned int irq_start,
+					unsigned int num)
+{
+	struct irq_chip_generic *gc;
+	struct irq_chip_type *ct;
+
+	gc = irq_alloc_generic_chip("mcs814x-intc", 1,
+			irq_start, base, handle_level_irq);
+	if (!gc)
+		panic("unable to allocate generic irq chip");
+
+	ct = gc->chip_types;
+	ct->chip.irq_ack = irq_gc_unmask_enable_reg;
+	ct->chip.irq_mask = irq_gc_mask_clr_bit;
+	ct->chip.irq_unmask = irq_gc_mask_set_bit;
+	ct->regs.mask = MCS814X_IRQ_MASK;
+	ct->regs.enable = MCS814X_IRQ_ICR;
+
+	irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
+		IRQ_NOREQUEST, 0);
+
+	/* Clear all interrupts */
+	__raw_writel(0xffffffff, base + MCS814X_IRQ_ICR);
+}
+
+static const struct of_device_id mcs814x_intc_ids[] = {
+	{ .compatible = "moschip,mcs814x-intc" },
+	{ /* sentinel */ },
+};
+
+void __init mcs814x_of_irq_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_matching_node(NULL, mcs814x_intc_ids);
+	if (!np)
+		panic("unable to find compatible intc node in dtb\n");
+
+	mcs814x_intc_base = of_iomap(np, 0);
+	if (!mcs814x_intc_base)
+		panic("unable to map intc cpu registers\n");
+
+	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
+
+	of_node_put(np);
+
+	mcs814x_alloc_gc(mcs814x_intc_base, 0, 32);
+}
+
diff --git a/arch/arm/mach-mcs814x/pci.c b/arch/arm/mach-mcs814x/pci.c
new file mode 100644
index 0000000..a75bfe6
--- /dev/null
+++ b/arch/arm/mach-mcs814x/pci.c
@@ -0,0 +1,446 @@
+/*
+ * Moschip MCS8140 PCI support
+ *
+ * Copyright (C) 2003 Moschip Semiconductors Ltd.
+ * Copyright (C) 2003 Artec Design Ltd.
+ * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/map.h>
+#include <mach/mcs814x.h>
+#include <mach/irqs.h>
+
+#define MCS8140_PCI_CONFIG_SIZE		SZ_64M
+#define MCS8140_PCI_IOMISC_SIZE		SZ_64M
+
+#define MCS8140_PCI_HOST_BASE           0x80000000
+#define MCS8140_PCI_IOMISC_BASE         0x00000000
+#define MCS8140_PCI_PRE_BASE            0x10000000
+#define MCS8140_PCI_NONPRE_BASE         0x30000000
+
+#define MCS8140_PCI_CFG_BASE		(MCS8140_PCI_HOST_BASE + 0x04000000)
+#define MCS8140_PCI_IO_BASE		(MCS8140_PCI_HOST_BASE)
+
+#define MCS8140_PCI_IO_VIRT_BASE	(MCS814X_IO_BASE - \
+					 MCS8140_PCI_CONFIG_SIZE - \
+					 MCS8140_PCI_IOMISC_SIZE)
+#define MCS8140_PCI_CFG_VIRT_BASE	(MCS814X_IO_BASE - \
+					 MCS8140_PCI_CONFIG_SIZE)
+
+#define PCI_FATAL_ERROR			1
+#define EXTERNAL_ABORT_NON_LINE_FETCH	8
+#define EPRM_DONE			0x80
+#define EPRM_SDRAM_FUNC0		0xAC
+#define PCI_INTD			4
+#define MCS8140_PCI_DEVICE_ID		0xA0009710
+#define MCS8140_PCI_CLASS_ID		0x02000011  /* Host-Class id :0x0600 */
+#define PCI_IF_CONFIG			0x200
+
+static void __iomem *mcs8140_pci_master_base;
+static void __iomem *mcs8140_eeprom_emu_base;
+
+static unsigned long __pci_addr(struct pci_bus *bus,
+				unsigned int devfn, int offset)
+{
+	unsigned int busnr = bus->number;
+	unsigned int slot;
+
+	/* we only support bus 0 */
+	if (busnr != 0)
+		return 0;
+
+	/*
+	 * Trap out illegal values
+	 */
+	BUG_ON(devfn > 255 || busnr > 255 || devfn > 255);
+
+	/* Scan 3 slots */
+	slot = PCI_SLOT(devfn);
+	switch (slot) {
+	case 1:
+	case 2:
+	case 3:
+		if (PCI_FUNC(devfn) >= 4)
+			return 0;
+
+		return MCS8140_PCI_CFG_VIRT_BASE | (PCI_SLOT(devfn) << 11) |
+			(PCI_FUNC(devfn) << 8) | offset;
+	default:
+		pr_warn("Ignoring: PCI Slot is %x\n", PCI_SLOT(devfn));
+		return 0;
+	}
+}
+
+static int mcs8140_pci_host_status(void)
+{
+	u32 host_status;
+
+	host_status = __raw_readl(mcs8140_pci_master_base + PCI_IF_CONFIG);
+	if (host_status & PCI_FATAL_ERROR) {
+		__raw_writel(host_status & 0xfffffff0,
+			mcs8140_pci_master_base + PCI_IF_CONFIG);
+		/* flush write */
+		host_status =
+			__raw_readl(mcs8140_pci_master_base + PCI_IF_CONFIG);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int mcs8140_pci_read_config(struct pci_bus *bus,
+					unsigned int devfn, int where,
+					int size, u32 *val)
+{
+	unsigned long v = 0xFFFFFFFF;
+	unsigned long addr = __pci_addr(bus, devfn, where);
+
+	if (addr != 0) {
+		switch (size) {
+		case 1:
+			v = __raw_readb(addr);
+			break;
+		case 2:
+			addr &= ~1;
+			v = __raw_readw(addr);
+			break;
+		default:
+			addr &= ~3;
+			v = __raw_readl(addr);
+			break;
+		}
+	} else
+		v = 0xffffffff;
+
+	if (mcs8140_pci_host_status())
+		v = 0xffffffff;
+
+	*val = v;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static void mcs8140_eeprom_emu_init(void)
+{
+	__raw_writel(0x0000000F, mcs8140_eeprom_emu_base + EPRM_SDRAM_FUNC0);
+	__raw_writel(0x08000000, MCS8140_PCI_CFG_VIRT_BASE + 0x10);
+	/* Set the DONE bit of the EEPROM emulator */
+	__raw_writel(0x01, mcs8140_eeprom_emu_base + EPRM_DONE);
+}
+
+static int mcs8140_pci_write_config(struct pci_bus *bus,
+					unsigned int devfn, int where,
+					int size, u32 val)
+{
+	unsigned long addr = __pci_addr(bus, devfn, where);
+
+	if (addr != 0) {
+		switch (size) {
+		case 1:
+			__raw_writeb((u8)val, addr);
+			break;
+		case 2:
+			__raw_writew((u16)val, addr);
+			break;
+		case 4:
+			__raw_writel(val, addr);
+			break;
+		}
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_mcs8140_ops = {
+	.read	= mcs8140_pci_read_config,
+	.write	= mcs8140_pci_write_config,
+};
+
+
+static struct resource io_mem = {
+	.name	= "PCI I/O space",
+	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE,
+	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE + SZ_64M,
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource pre_mem = {
+	.name	= "PCI prefetchable",
+	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_PRE_BASE,
+	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_PRE_BASE + SZ_512M,
+	.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,
+};
+
+static struct resource non_mem = {
+	.name	= "PCI non-prefetchable",
+	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_NONPRE_BASE,
+	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_NONPRE_BASE + SZ_256M,
+	.flags	= IORESOURCE_MEM,
+};
+
+int __init pci_mcs8140_setup_resources(struct pci_sys_data *sys)
+{
+	int ret = 0;
+
+	ret = request_resource(&iomem_resource, &io_mem);
+	if (ret)
+		goto out;
+
+	ret = request_resource(&iomem_resource, &non_mem);
+	if (ret)
+		goto release_io_mem;
+
+	ret = request_resource(&iomem_resource, &pre_mem);
+	if (ret)
+		goto release_non_mem;
+
+	mcs8140_eeprom_emu_init();
+
+	pci_add_resource(&sys->resources, &io_mem);
+	pci_add_resource(&sys->resources, &non_mem);
+	pci_add_resource(&sys->resources, &pre_mem);
+
+	return ret;
+
+release_non_mem:
+	release_resource(&non_mem);
+release_io_mem:
+	release_resource(&io_mem);
+out:
+	return ret;
+}
+
+struct pci_bus *pci_mcs8140_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	return pci_scan_bus(sys->busnr, &pci_mcs8140_ops, sys);
+}
+
+
+int __init pci_mcs8140_setup(int nr, struct pci_sys_data *sys)
+{
+	int ret = 0;
+	u32 val;
+
+	if (nr > 0)
+		return 0;
+
+	sys->mem_offset = MCS8140_PCI_IO_VIRT_BASE - MCS8140_PCI_IO_BASE;
+	sys->io_offset = 0;
+
+	ret = pci_mcs8140_setup_resources(sys);
+	if (ret < 0) {
+		pr_err("unable to setup mcs8140 resources\n");
+		goto out;
+	}
+
+	val = __raw_readl(MCS8140_PCI_CFG_VIRT_BASE);
+	if (val != MCS8140_PCI_DEVICE_ID) {
+		pr_err("cannot find MCS8140 PCI Core: %08x\n", val);
+		ret = -EIO;
+		goto out;
+	}
+
+	pr_info("MCS8140 PCI core found\n");
+
+	val = __raw_readl(MCS8140_PCI_CFG_VIRT_BASE + PCI_COMMAND);
+	/* Added to support wireless cards */
+	__raw_writel(0, MCS8140_PCI_CFG_VIRT_BASE + 0x40);
+	__raw_writel(val | 0x147, MCS8140_PCI_CFG_VIRT_BASE + PCI_COMMAND);
+	val = __raw_readl(MCS8140_PCI_CFG_VIRT_BASE + PCI_COMMAND);
+	ret = 1;
+out:
+	return ret;
+}
+
+
+static int __init mcs8140_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int line = IRQ_PCI_INTA;
+
+	if (pin != 0) {
+		/* IRQ_PCIA - 22 */
+		if (pin == PCI_INTD)
+			line = IRQ_PCI_INTA + pin; /* IRQ_PCIA - 22 */
+		else
+			line = IRQ_PCI_INTA + pin - 1; /* IRQ_PCIA - 22 */
+	}
+
+	pr_info("PCI: Map interrupt slot 0x%02x pin 0x%02x line 0x%02x\n",
+		slot, pin, line);
+
+	return line;
+}
+
+static irqreturn_t mcs8140_pci_abort_interrupt(int irq, void *dummy)
+{
+	u32 word;
+
+	word = __raw_readl(mcs8140_pci_master_base + PCI_IF_CONFIG);
+	if (!(word & (1 << 24)))
+		return IRQ_NONE;
+
+	__raw_writel(word & 0xfffffff0,
+		mcs8140_pci_master_base + PCI_IF_CONFIG);
+	/* flush write */
+	word = __raw_readl(mcs8140_pci_master_base + PCI_IF_CONFIG);
+
+	return IRQ_HANDLED;
+}
+
+static int mcs8140_pci_abort_irq_init(int irq)
+{
+	u32 word;
+
+	/* Enable Interrupt in PCI Master Core */
+	word = __raw_readl(mcs8140_pci_master_base + PCI_IF_CONFIG);
+	word |= (1 << 24);
+	__raw_writel(word, mcs8140_pci_master_base + PCI_IF_CONFIG);
+
+	/* flush write */
+	word = __raw_readl(mcs8140_pci_master_base + PCI_IF_CONFIG);
+
+	return request_irq(irq, mcs8140_pci_abort_interrupt, 0,
+			"PCI abort", NULL);
+}
+
+static int mcs8140_pci_host_abort(unsigned long addr,
+				unsigned int fsr, struct pt_regs *regs)
+{
+	pr_warn("PCI Data abort: address = 0x%08lx fsr = 0x%03x "
+		"PC = 0x%08lx LR = 0x%08lx\n",
+		addr, fsr, regs->ARM_pc, regs->ARM_lr);
+
+	/*
+	 * If it was an imprecise abort, then we need to correct the
+	 * return address to be _after_ the instruction.
+	 */
+	if (fsr & (1 << 10) || mcs8140_pci_host_status())
+		regs->ARM_pc += 4;
+
+	return 0;
+}
+
+static void mcs8140_data_abort_init(void)
+{
+	hook_fault_code(EXTERNAL_ABORT_NON_LINE_FETCH,
+		mcs8140_pci_host_abort, SIGBUS,
+		0, "external abort on non-line fetch");
+}
+
+static struct hw_pci mcs8140_pci __initdata = {
+	.map_irq		= mcs8140_map_irq,
+	.nr_controllers		= 1,
+	.setup			= pci_mcs8140_setup,
+	.scan			= pci_mcs8140_scan_bus,
+};
+
+static struct map_desc mcs8140_pci_io_desc[] __initdata = {
+	{
+		.virtual	= MCS8140_PCI_CFG_VIRT_BASE,
+		.pfn		= __phys_to_pfn(MCS8140_PCI_CFG_BASE),
+		.length		= MCS8140_PCI_CONFIG_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= MCS8140_PCI_IO_VIRT_BASE,
+		.pfn		= __phys_to_pfn(MCS8140_PCI_IO_BASE),
+		.length		= MCS8140_PCI_IOMISC_SIZE,
+		.type		= MT_DEVICE
+	},
+};
+
+static int __devinit mcs8140_pci_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	int ret, irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get mem resource 0\n");
+		return -ENODEV;
+	}
+
+	mcs8140_pci_master_base = devm_ioremap(&pdev->dev, res->start,
+					resource_size(res));
+	if (!mcs8140_pci_master_base) {
+		dev_err(&pdev->dev, "failed to remap PCI master regs\n");
+		return -ENODEV;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get mem resource 1\n");
+		return -ENOMEM;
+	}
+
+	mcs8140_eeprom_emu_base = devm_ioremap(&pdev->dev, res->start,
+					resource_size(res));
+	if (!mcs8140_eeprom_emu_base) {
+		dev_err(&pdev->dev, "failed to remap EEPROM regs\n");
+		return -ENOMEM;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "failed to get pci abort irq\n");
+		return -ENODEV;
+	}
+
+	/* Setup static mappins for PCI CFG space */
+	iotable_init(mcs8140_pci_io_desc, ARRAY_SIZE(mcs8140_pci_io_desc));
+
+	pcibios_min_io = MCS8140_PCI_HOST_BASE;
+	pcibios_min_mem = MCS8140_PCI_HOST_BASE + MCS8140_PCI_PRE_BASE;
+
+	mcs8140_data_abort_init();
+	ret = mcs8140_pci_abort_irq_init(irq);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to setup abort irq\n");
+		return ret;
+	}
+
+	pci_common_init(&mcs8140_pci);
+
+	return 0;
+}
+
+static struct of_device_id mcs8140_of_ids[] __devinitdata = {
+	{ .compatible = "moschip,mcs8140-pci" },
+	{ .compatible = "moschip,mcs814x-pci" },
+	{ /* sentinel */ },
+};
+
+static struct platform_driver mcs8140_pci_driver = {
+	.driver	= {
+		.name	= "mcs8140-pci",
+		.of_match_table = mcs8140_of_ids,
+	},
+	.probe	= mcs8140_pci_probe,
+};
+
+static int __init mcs8140_pci_init(void)
+{
+	return platform_driver_register(&mcs8140_pci_driver);
+}
+subsys_initcall(mcs8140_pci_init);
+
diff --git a/arch/arm/mach-mcs814x/timer.c b/arch/arm/mach-mcs814x/timer.c
new file mode 100644
index 0000000..e8408e4
--- /dev/null
+++ b/arch/arm/mach-mcs814x/timer.c
@@ -0,0 +1,133 @@
+/*
+ * Moschip MCS814x timer routines
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under GPLv2
+ */
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/mach/time.h>
+#include <mach/mcs814x.h>
+
+/* Timer block registers */
+#define TIMER_VAL	0x00
+#define TIMER_CTL	0x04
+
+static u32 last_reload;
+static u32 timer_correct;
+static u32 clock_rate;
+static u32 timer_reload_value;
+static void __iomem *mcs814x_timer_base;
+
+static inline unsigned long ticks2usecs(u32 x)
+{
+	return x / (clock_rate / 1000000);
+}
+
+/*
+ * Returns number of ms since last clock interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long mcs814x_gettimeoffset(void)
+{
+	u32 ticks = __raw_readl(mcs814x_timer_base + TIMER_VAL);
+
+	if (ticks < last_reload)
+		return ticks2usecs(ticks + (u32)(0xffffffff - last_reload));
+	else
+		return ticks2usecs(ticks - last_reload);
+}
+
+
+static irqreturn_t mcs814x_timer_interrupt(int irq, void *dev_id)
+{
+	u32 count = __raw_readl(mcs814x_timer_base + TIMER_VAL);
+
+	/* take into account delay up to this moment */
+	last_reload = count + timer_correct + timer_reload_value;
+
+	if (last_reload < timer_reload_value)
+		last_reload = timer_reload_value;
+	else if (timer_correct == 0)
+		timer_correct = __raw_readl(mcs814x_timer_base + TIMER_VAL) -
+					count;
+
+	__raw_writel(last_reload, mcs814x_timer_base + TIMER_VAL);
+
+	timer_tick();
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction mcs814x_timer_irq = {
+	.name		= "mcs814x-timer",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= mcs814x_timer_interrupt,
+};
+
+static struct of_device_id mcs814x_timer_ids[] = {
+	{ .compatible = "moschip,mcs814x-timer" },
+	{ /* sentinel */ },
+};
+
+static void __init mcs814x_of_timer_init(void)
+{
+	struct device_node *np;
+	const unsigned int *intspec;
+
+	np = of_find_matching_node(NULL, mcs814x_timer_ids);
+	if (!np)
+		panic("unable to find compatible timer node in dtb");
+
+	mcs814x_timer_base = of_iomap(np, 0);
+	if (!mcs814x_timer_base)
+		panic("unable to remap timer cpu registers");
+
+	intspec = of_get_property(np, "interrupts", NULL);
+	if (!intspec)
+		panic("no interrupts property for timer");
+
+	mcs814x_timer_irq.irq = be32_to_cpup(intspec);
+}
+
+static void __init mcs814x_timer_init(void)
+{
+	struct clk *clk;
+
+	clk = clk_get_sys("timer0", NULL);
+	if (IS_ERR_OR_NULL(clk))
+		panic("unable to get timer0 clock");
+
+	clock_rate = clk_get_rate(clk);
+	clk_put(clk);
+
+	mcs814x_of_timer_init();
+
+	pr_info("Timer frequency: %d (kHz)\n", clock_rate / 1000);
+
+	timer_reload_value = 0xffffffff - (clock_rate / HZ);
+
+	/* disable timer */
+	__raw_writel(0, mcs814x_timer_base + TIMER_CTL);
+	__raw_writel(timer_reload_value, mcs814x_timer_base + TIMER_VAL);
+	last_reload = timer_reload_value;
+
+	setup_irq(mcs814x_timer_irq.irq, &mcs814x_timer_irq);
+	/* enable timer, stop timer in debug mode */
+	__raw_writel(0x03, mcs814x_timer_base + TIMER_CTL);
+}
+
+struct sys_timer mcs814x_timer = {
+	.init	= mcs814x_timer_init,
+	.offset	= mcs814x_gettimeoffset,
+};
-- 
1.7.10.4

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-15 14:49   ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support for Moschip's MCS814x SoCs, and in particular
MCS8140. This SoC has the following characteristics:

- uses an ARM926EJS CPU core with an AHB/VCI64 interconnect
- simple clocking scheme and clock gating
- strap registers defining CPU, SDRAM and Timer frequency
- various on-chip peripherals:
	* 2x OHCI controller
	* 1x EHCI controller
	* IPsec unit
	* Watchdog
	* Random number generator
	* 10/100 Ethernet MAC w/ TCP offloading and checksumming
	* I2S
	* 4 + 20 GPIOs
	* PCI master interface

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 arch/arm/mach-mcs814x/Kconfig                    |   11 +
 arch/arm/mach-mcs814x/Makefile                   |    6 +
 arch/arm/mach-mcs814x/Makefile.boot              |    3 +
 arch/arm/mach-mcs814x/clock.c                    |  271 +++++++++++++
 arch/arm/mach-mcs814x/common.c                   |   97 +++++
 arch/arm/mach-mcs814x/common.h                   |   15 +
 arch/arm/mach-mcs814x/include/mach/cpu.h         |   16 +
 arch/arm/mach-mcs814x/include/mach/debug-macro.S |   11 +
 arch/arm/mach-mcs814x/include/mach/entry-macro.S |   29 ++
 arch/arm/mach-mcs814x/include/mach/gpio.h        |    1 +
 arch/arm/mach-mcs814x/include/mach/hardware.h    |   16 +
 arch/arm/mach-mcs814x/include/mach/irqs.h        |   22 ++
 arch/arm/mach-mcs814x/include/mach/mcs814x.h     |   53 +++
 arch/arm/mach-mcs814x/include/mach/memory.h      |   16 +
 arch/arm/mach-mcs814x/include/mach/timex.h       |   18 +
 arch/arm/mach-mcs814x/include/mach/uncompress.h  |   41 ++
 arch/arm/mach-mcs814x/irq.c                      |   69 ++++
 arch/arm/mach-mcs814x/pci.c                      |  446 ++++++++++++++++++++++
 arch/arm/mach-mcs814x/timer.c                    |  133 +++++++
 19 files changed, 1274 insertions(+)
 create mode 100644 arch/arm/mach-mcs814x/Kconfig
 create mode 100644 arch/arm/mach-mcs814x/Makefile
 create mode 100644 arch/arm/mach-mcs814x/Makefile.boot
 create mode 100644 arch/arm/mach-mcs814x/clock.c
 create mode 100644 arch/arm/mach-mcs814x/common.c
 create mode 100644 arch/arm/mach-mcs814x/common.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/cpu.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-mcs814x/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-mcs814x/include/mach/gpio.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/hardware.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/irqs.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/mcs814x.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/memory.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/timex.h
 create mode 100644 arch/arm/mach-mcs814x/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-mcs814x/irq.c
 create mode 100644 arch/arm/mach-mcs814x/pci.c
 create mode 100644 arch/arm/mach-mcs814x/timer.c

diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
new file mode 100644
index 0000000..c89422f
--- /dev/null
+++ b/arch/arm/mach-mcs814x/Kconfig
@@ -0,0 +1,11 @@
+if ARCH_MCS814X
+
+config MCS8140
+	select CPU_ARM926T
+	bool
+
+menu "Moschip MCS8140 boards"
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-mcs814x/Makefile b/arch/arm/mach-mcs814x/Makefile
new file mode 100644
index 0000000..bad95cc
--- /dev/null
+++ b/arch/arm/mach-mcs814x/Makefile
@@ -0,0 +1,6 @@
+obj-y += clock.o
+obj-y += common.o
+obj-y += irq.o
+obj-y += timer.o
+obj-y += board-mcs8140-dt.o
+obj-$(CONFIG_PCI)       += pci.o
diff --git a/arch/arm/mach-mcs814x/Makefile.boot b/arch/arm/mach-mcs814x/Makefile.boot
new file mode 100644
index 0000000..414db8b
--- /dev/null
+++ b/arch/arm/mach-mcs814x/Makefile.boot
@@ -0,0 +1,3 @@
+    zreladdr-y := 0x00008000
+ params_phys-y := 0x00000008
+ initrd_phys-y := 0x00400000
diff --git a/arch/arm/mach-mcs814x/clock.c b/arch/arm/mach-mcs814x/clock.c
new file mode 100644
index 0000000..eb30ae2
--- /dev/null
+++ b/arch/arm/mach-mcs814x/clock.c
@@ -0,0 +1,271 @@
+/*
+ * Moschip MCS814x clock routines
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under GPLv2
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/export.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+
+#include <mach/mcs814x.h>
+
+#include "common.h"
+
+#define KHZ	1000
+#define MHZ	(KHZ * KHZ)
+
+struct clk_ops {
+	unsigned long (*get_rate)(struct clk *clk);
+	int (*set_rate)(struct clk *clk, unsigned long rate);
+	struct clk *(*get_parent)(struct clk *clk);
+	int (*enable)(struct clk *clk, int enable);
+};
+
+struct clk {
+	struct clk *parent;		/* parent clk */
+	unsigned long rate;		/* clock rate in Hz */
+	unsigned long divider;		/* clock divider */
+	u32 usecount;			/* reference count */
+	struct clk_ops *ops;		/* clock operation */
+	u32 enable_reg;			/* clock enable register */
+	u32 enable_mask;		/* clock enable mask */
+};
+
+static unsigned long clk_divide_parent(struct clk *clk)
+{
+	if (clk->parent && clk->divider)
+		return clk_get_rate(clk->parent) / clk->divider;
+	else
+		return 0;
+}
+
+static int clk_local_onoff_enable(struct clk *clk, int enable)
+{
+	u32 tmp;
+
+	/* no enable_reg means the clock is always enabled */
+	if (!clk->enable_reg)
+		return 0;
+
+	tmp = __raw_readl(mcs814x_sysdbg_base + clk->enable_reg);
+	if (!enable)
+		tmp &= ~clk->enable_mask;
+	else
+		tmp |= clk->enable_mask;
+
+	__raw_writel(tmp, mcs814x_sysdbg_base + clk->enable_reg);
+
+	return 0;
+}
+
+static struct clk_ops default_clk_ops = {
+	.get_rate	= clk_divide_parent,
+	.enable		= clk_local_onoff_enable,
+};
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+static const unsigned long cpu_freq_table[] = {
+	175000,
+	300000,
+	125000,
+	137500,
+	212500,
+	250000,
+	162500,
+	187500,
+	162500,
+	150000,
+	225000,
+	237500,
+	200000,
+	262500,
+	275000,
+	287500
+};
+
+static struct clk clk_cpu;
+
+/* System clock is fixed at 50Mhz */
+static struct clk clk_sys = {
+	.rate	= 50 * MHZ,
+};
+
+static struct clk clk_sdram;
+
+static struct clk clk_timer0 = {
+	.parent	= &clk_sdram,
+	.divider = 2,
+	.ops	= &default_clk_ops,
+};
+
+static struct clk clk_timer1_2 = {
+	.parent	= &clk_sys,
+};
+
+/* Watchdog clock is system clock / 128 */
+static struct clk clk_wdt = {
+	.parent	= &clk_sys,
+	.divider = 128,
+	.ops	= &default_clk_ops,
+};
+
+static struct clk clk_emac = {
+	.ops		= &default_clk_ops,
+	.enable_reg	= SYSDBG_SYSCTL,
+	.enable_mask	= SYSCTL_EMAC,
+};
+
+static struct clk clk_ephy = {
+	.ops		= &default_clk_ops,
+	.enable_reg	= SYSDBG_PLL_CTL,
+	.enable_mask	= ~SYSCTL_EPHY,	/* active low */
+};
+
+static struct clk clk_cipher = {
+	.ops		= &default_clk_ops,
+	.enable_reg	= SYSDBG_SYSCTL,
+	.enable_mask	= SYSCTL_CIPHER,
+};
+
+#define CLK(_dev, _con, _clk)	\
+{ .dev_id = (_dev), .con_id = (_con), .clk = (_clk) },
+
+static struct clk_lookup mcs814x_chip_clks[] = {
+	CLK("cpu", NULL, &clk_cpu)
+	CLK("sys", NULL, &clk_sys)
+	CLK("sdram", NULL, &clk_sdram)
+	/* 32-bits timer0 */
+	CLK("timer0", NULL, &clk_timer0)
+	/* 16-bits timer1 */
+	CLK("timer1", NULL, &clk_timer1_2)
+	/* 64-bits timer2, same as timer 1 */
+	CLK("timer2", NULL, &clk_timer1_2)
+	CLK(NULL, "wdt", &clk_wdt)
+	CLK(NULL, "emac", &clk_emac)
+	CLK(NULL, "ephy", &clk_ephy)
+	CLK(NULL, "cipher", &clk_cipher)
+};
+
+static void local_clk_disable(struct clk *clk)
+{
+	WARN_ON(!clk->usecount);
+
+	if (clk->usecount > 0) {
+		clk->usecount--;
+
+		if ((clk->usecount == 0) && (clk->ops->enable))
+			clk->ops->enable(clk, 0);
+
+		if (clk->parent)
+			local_clk_disable(clk->parent);
+	}
+}
+
+static int local_clk_enable(struct clk *clk)
+{
+	int ret = 0;
+
+	if (clk->parent)
+		ret = local_clk_enable(clk->parent);
+
+	if (ret)
+		return ret;
+
+	if ((clk->usecount == 0) && (clk->ops->enable))
+		ret = clk->ops->enable(clk, 1);
+
+	if (!ret)
+		clk->usecount++;
+	else if (clk->parent && clk->parent->ops->enable)
+		local_clk_disable(clk->parent);
+
+	return ret;
+}
+
+int clk_enable(struct clk *clk)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	ret = local_clk_enable(clk);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	local_clk_disable(clk);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (unlikely(IS_ERR_OR_NULL(clk)))
+		return 0;
+
+	if (clk->rate)
+		return clk->rate;
+
+	if (clk->ops && clk->ops->get_rate)
+		return clk->ops->get_rate(clk);
+
+	return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+	unsigned long flags;
+
+	if (unlikely(IS_ERR_OR_NULL(clk)))
+		return NULL;
+
+	if (!clk->ops || !clk->ops->get_parent)
+		return clk->parent;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	clk->parent = clk->ops->get_parent(clk);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+
+	return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+void __init mcs814x_clk_init(void)
+{
+	u32 bs1;
+	u8 cpu_freq;
+
+	clkdev_add_table(mcs814x_chip_clks, ARRAY_SIZE(mcs814x_chip_clks));
+
+	/* read the bootstrap registers to know the exact clocking scheme */
+	bs1 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS1);
+	cpu_freq = (bs1 >> CPU_FREQ_SHIFT) & CPU_FREQ_MASK;
+
+	pr_info("CPU frequency: %lu (kHz)\n", cpu_freq_table[cpu_freq]);
+	clk_cpu.rate = cpu_freq * KHZ;
+
+	/* read SDRAM frequency */
+	if (bs1 & SDRAM_FREQ_BIT)
+		clk_sdram.rate = 100 * MHZ;
+	else
+		clk_sdram.rate = 133 * MHZ;
+
+	pr_info("SDRAM frequency: %lu (MHz)\n", clk_sdram.rate / MHZ);
+}
+
diff --git a/arch/arm/mach-mcs814x/common.c b/arch/arm/mach-mcs814x/common.c
new file mode 100644
index 0000000..0652633
--- /dev/null
+++ b/arch/arm/mach-mcs814x/common.c
@@ -0,0 +1,97 @@
+/*
+ * arch/arm/mach-mcs814x/common.c
+ *
+ * Core functions for Moschip MCS814x SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/mcs814x.h>
+#include <mach/cpu.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+void __iomem *mcs814x_sysdbg_base;
+
+static struct map_desc mcs814x_io_desc[] __initdata = {
+	{
+		.virtual	= MCS814X_IO_BASE,
+		.pfn		= __phys_to_pfn(MCS814X_IO_START),
+		.length		= MCS814X_IO_SIZE,
+		.type		= MT_DEVICE
+	},
+};
+
+struct cpu_mode {
+	const char *name;
+	int gpio_start;
+	int gpio_end;
+};
+
+static const struct cpu_mode cpu_modes[] = {
+	{
+		.name		= "I2S",
+		.gpio_start	= 4,
+		.gpio_end	= 8,
+	},
+	{
+		.name		= "UART",
+		.gpio_start	= 4,
+		.gpio_end	= 9,
+	},
+	{
+		.name		= "External MII",
+		.gpio_start	= 0,
+		.gpio_end	= 16,
+	},
+	{
+		.name		= "Normal",
+		.gpio_start	= -1,
+		.gpio_end	= -1,
+	},
+};
+
+void __init mcs814x_init_machine(void)
+{
+	u32 bs2, cpu_mode;
+	int gpio;
+
+	bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
+	cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
+
+	pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
+
+	/* request the gpios since the pins are muxed for functionnality */
+	for (gpio = cpu_modes[cpu_mode].gpio_start;
+		gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
+		if (gpio != -1)
+			gpio_request(gpio, cpu_modes[cpu_mode].name);
+	}
+}
+
+void __init mcs814x_map_io(void)
+{
+	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
+
+	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
+					MCS814X_SYSDBG_SIZE);
+	if (!mcs814x_sysdbg_base)
+		panic("unable to remap sysdbg base");
+}
+
+void mcs814x_restart(char mode, const char *cmd)
+{
+	__raw_writel(~(1 << 31), mcs814x_sysdbg_base);
+}
diff --git a/arch/arm/mach-mcs814x/common.h b/arch/arm/mach-mcs814x/common.h
new file mode 100644
index 0000000..e523abe
--- /dev/null
+++ b/arch/arm/mach-mcs814x/common.h
@@ -0,0 +1,15 @@
+#ifndef __ARCH_MCS814X_COMMON_H
+#define __ARCH_MCS814X_COMMON_H
+
+#include <asm/mach/time.h>
+
+void mcs814x_map_io(void);
+void mcs814x_clk_init(void);
+void mcs814x_of_irq_init(void);
+void mcs814x_init_machine(void);
+void mcs814x_handle_irq(struct pt_regs *regs);
+void mcs814x_restart(char mode, const char *cmd);
+extern struct sys_timer mcs814x_timer;
+extern void __iomem *mcs814x_sysdbg_base;
+
+#endif /* __ARCH_MCS814X_COMMON_H */
diff --git a/arch/arm/mach-mcs814x/include/mach/cpu.h b/arch/arm/mach-mcs814x/include/mach/cpu.h
new file mode 100644
index 0000000..1ef3c4a
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/cpu.h
@@ -0,0 +1,16 @@
+#ifndef __ASM_ARCH_CPU_H__
+#define __ASM_ARCH_CPU_H__
+
+#include <asm/cputype.h>
+
+#define MCS8140_ID	0x41069260	/* ARM926EJ-S */
+#define MCS814X_MASK	0xff0ffff0
+
+#ifdef CONFIG_MCS8140
+/* Moschip MCS8140 is based on an ARM926EJ-S core */
+#define soc_is_mcs8140()	((read_cpuid_id() & MCS814X_MASK) == MCS8140_ID)
+#else
+#define soc_is_mcs8140()	(0)
+#endif /* !CONFIG_MCS8140 */
+
+#endif /* __ASM_ARCH_CPU_H__ */
diff --git a/arch/arm/mach-mcs814x/include/mach/debug-macro.S b/arch/arm/mach-mcs814x/include/mach/debug-macro.S
new file mode 100644
index 0000000..93ecea4
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/debug-macro.S
@@ -0,0 +1,11 @@
+#include <mach/mcs814x.h>
+
+                .macro  addruart, rp, rv, tmp
+		ldr	\rp, =MCS814X_PHYS_BASE
+		ldr	\rv, =MCS814X_VIRT_BASE
+		orr	\rp, \rp, #MCS814X_UART
+		orr	\rv, \rv, #MCS814X_UART
+                .endm
+
+#define UART_SHIFT	2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-mcs814x/include/mach/entry-macro.S b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
new file mode 100644
index 0000000..cbad566
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
@@ -0,0 +1,29 @@
+#include <mach/mcs814x.h>
+                .macro  disable_fiq
+                .endm
+
+		.macro arch_ret_to_user, tmp1, tmp2
+		.endm
+
+		.macro  get_irqnr_preamble, base, tmp
+		ldr	\base, =mcs814x_intc_base@ base virtual address of INTC
+		ldr	\base, [\base]
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	\tmp, #MCS814X_IRQ_STS0	 @ load tmp with STS0 register offset
+		ldr	\irqstat, [\base, \tmp]	 @ load value at base + tmp
+		tst	\irqstat, \irqstat       @ test if no active IRQ's
+		beq	1002f                    @ if no active irqs return with status 0
+		mov	\irqnr, #0               @ start from irq zero
+		mov	\tmp,   #1               @ the mask initially 1
+1001:
+		tst     \irqstat, \tmp           @ and with mask
+		addeq   \irqnr, \irqnr, #1       @ if  zero then add one to nr
+		moveq   \tmp,   \tmp, lsl #1     @ shift mask one to left
+		beq     1001b                    @ if  zero then loop again
+		mov     \irqstat, \tmp           @ save the return mask
+		mov	\tmp, #MCS814X_IRQ_STS0  @ load tmp with ICR offset
+		str     \irqstat,  [\base, \tmp] @ clear irq with selected mask
+1002:
+                .endm
diff --git a/arch/arm/mach-mcs814x/include/mach/gpio.h b/arch/arm/mach-mcs814x/include/mach/gpio.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/gpio.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/arm/mach-mcs814x/include/mach/hardware.h b/arch/arm/mach-mcs814x/include/mach/hardware.h
new file mode 100644
index 0000000..529f648
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/hardware.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2003 Artec Design Ltd.
+ *
+ * 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 __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include "mcs814x.h"
+
+#endif
+
diff --git a/arch/arm/mach-mcs814x/include/mach/irqs.h b/arch/arm/mach-mcs814x/include/mach/irqs.h
new file mode 100644
index 0000000..78021d1
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/irqs.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2003 Artec Design Ltd.
+ *
+ * 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 __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define FIQ_START	0
+
+#define NR_IRQS		32
+
+#define IRQ_PCI_INTA            22
+#define IRQ_PCI_INTB            23
+#define IRQ_PCI_INTC            24
+#define IRQ_PCI_INTD            26
+
+#endif
diff --git a/arch/arm/mach-mcs814x/include/mach/mcs814x.h b/arch/arm/mach-mcs814x/include/mach/mcs814x.h
new file mode 100644
index 0000000..a4a369e
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/mcs814x.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2003 Artec Design Ltd.
+ *
+ * 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 __ASM_ARCH_MCS814X_H
+#define __ASM_ARCH_MCS814X_H
+
+#define MCS814X_IO_BASE		0xF0000000
+#define MCS814X_IO_START	0x40000000
+#define MCS814X_IO_SIZE		0x00100000
+
+/* IRQ controller register offset */
+#define MCS814X_IRQ_ICR		0x00
+#define MCS814X_IRQ_ISR		0x04
+#define MCS814X_IRQ_MASK	0x20
+#define MCS814X_IRQ_STS0	0x40
+
+#define MCS814X_PHYS_BASE	0x40000000
+#define MCS814X_VIRT_BASE	MCS814X_IO_BASE
+
+#define MCS814X_UART		0x000DC000
+#define MCS814X_DBGLED		0x000EC000
+#define MCS814X_SYSDBG		0x000F8000
+#define MCS814X_SYSDBG_SIZE	0x50
+
+/* System configuration and bootstrap registers */
+#define SYSDBG_BS1		0x00
+#define  CPU_FREQ_SHIFT		27
+#define  CPU_FREQ_MASK		0x0F
+#define  SDRAM_FREQ_BIT		(1 << 22)
+
+#define SYSDBG_BS2		0x04
+#define  LED_CFG_MASK		0x03
+#define  CPU_MODE_SHIFT		23
+#define  CPU_MODE_MASK		0x03
+
+#define SYSDBG_SYSCTL_MAC	0x1d
+#define  BUF_SHIFT_BIT		(1 << 0)
+
+#define SYSDBG_SYSCTL		0x08
+#define  SYSCTL_EMAC		(1 << 0)
+#define  SYSCTL_EPHY		(1 << 0) /* active low */
+#define  SYSCTL_CIPHER		(1 << 16)
+
+#define SYSDBG_PLL_CTL		0x3C
+
+#endif /* __ASM_ARCH_MCS814X_H */
+
diff --git a/arch/arm/mach-mcs814x/include/mach/memory.h b/arch/arm/mach-mcs814x/include/mach/memory.h
new file mode 100644
index 0000000..ad87c7b
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/memory.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2003 Artec Design Ltd.
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET		UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-mcs814x/include/mach/timex.h b/arch/arm/mach-mcs814x/include/mach/timex.h
new file mode 100644
index 0000000..f05c8ee
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/timex.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2003 Artec Design Ltd.
+ *
+ * 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 __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/*
+ * Timex specification for MCS814X
+ */
+#define CLOCK_TICK_RATE		100
+
+#endif
diff --git a/arch/arm/mach-mcs814x/include/mach/uncompress.h b/arch/arm/mach-mcs814x/include/mach/uncompress.h
new file mode 100644
index 0000000..21b9821
--- /dev/null
+++ b/arch/arm/mach-mcs814x/include/mach/uncompress.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * 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 __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <linux/serial_reg.h>
+#include <asm/io.h>
+#include <mach/mcs814x.h>
+#include <mach/cpu.h>
+
+#define UART_SHIFT	(2)
+
+/* cannot be static because the code will be inlined */
+void __iomem *uart_base;
+
+static inline void putc(int c)
+{
+	while (!(__raw_readb(uart_base + (UART_LSR << UART_SHIFT)) & UART_LSR_TEMT))
+		;
+	__raw_writeb(c, uart_base + (UART_TX << UART_SHIFT));
+}
+
+static inline void flush(void)
+{
+}
+
+static inline void arch_decomp_setup(void)
+{
+	if (soc_is_mcs8140())
+		uart_base = (void __iomem *)(MCS814X_PHYS_BASE + MCS814X_UART);
+}
+
+#define arch_decomp_wdog()
+
+#endif
diff --git a/arch/arm/mach-mcs814x/irq.c b/arch/arm/mach-mcs814x/irq.c
new file mode 100644
index 0000000..089937b
--- /dev/null
+++ b/arch/arm/mach-mcs814x/irq.c
@@ -0,0 +1,69 @@
+/*
+ * Moschip MCS814x generic interrupt controller routines
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under the GPLv2
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+#include <asm/mach/irq.h>
+#include <mach/mcs814x.h>
+
+void __iomem *mcs814x_intc_base;
+
+static void __init mcs814x_alloc_gc(void __iomem *base, unsigned int irq_start,
+					unsigned int num)
+{
+	struct irq_chip_generic *gc;
+	struct irq_chip_type *ct;
+
+	gc = irq_alloc_generic_chip("mcs814x-intc", 1,
+			irq_start, base, handle_level_irq);
+	if (!gc)
+		panic("unable to allocate generic irq chip");
+
+	ct = gc->chip_types;
+	ct->chip.irq_ack = irq_gc_unmask_enable_reg;
+	ct->chip.irq_mask = irq_gc_mask_clr_bit;
+	ct->chip.irq_unmask = irq_gc_mask_set_bit;
+	ct->regs.mask = MCS814X_IRQ_MASK;
+	ct->regs.enable = MCS814X_IRQ_ICR;
+
+	irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
+		IRQ_NOREQUEST, 0);
+
+	/* Clear all interrupts */
+	__raw_writel(0xffffffff, base + MCS814X_IRQ_ICR);
+}
+
+static const struct of_device_id mcs814x_intc_ids[] = {
+	{ .compatible = "moschip,mcs814x-intc" },
+	{ /* sentinel */ },
+};
+
+void __init mcs814x_of_irq_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_matching_node(NULL, mcs814x_intc_ids);
+	if (!np)
+		panic("unable to find compatible intc node in dtb\n");
+
+	mcs814x_intc_base = of_iomap(np, 0);
+	if (!mcs814x_intc_base)
+		panic("unable to map intc cpu registers\n");
+
+	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
+
+	of_node_put(np);
+
+	mcs814x_alloc_gc(mcs814x_intc_base, 0, 32);
+}
+
diff --git a/arch/arm/mach-mcs814x/pci.c b/arch/arm/mach-mcs814x/pci.c
new file mode 100644
index 0000000..a75bfe6
--- /dev/null
+++ b/arch/arm/mach-mcs814x/pci.c
@@ -0,0 +1,446 @@
+/*
+ * Moschip MCS8140 PCI support
+ *
+ * Copyright (C) 2003 Moschip Semiconductors Ltd.
+ * Copyright (C) 2003 Artec Design Ltd.
+ * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/map.h>
+#include <mach/mcs814x.h>
+#include <mach/irqs.h>
+
+#define MCS8140_PCI_CONFIG_SIZE		SZ_64M
+#define MCS8140_PCI_IOMISC_SIZE		SZ_64M
+
+#define MCS8140_PCI_HOST_BASE           0x80000000
+#define MCS8140_PCI_IOMISC_BASE         0x00000000
+#define MCS8140_PCI_PRE_BASE            0x10000000
+#define MCS8140_PCI_NONPRE_BASE         0x30000000
+
+#define MCS8140_PCI_CFG_BASE		(MCS8140_PCI_HOST_BASE + 0x04000000)
+#define MCS8140_PCI_IO_BASE		(MCS8140_PCI_HOST_BASE)
+
+#define MCS8140_PCI_IO_VIRT_BASE	(MCS814X_IO_BASE - \
+					 MCS8140_PCI_CONFIG_SIZE - \
+					 MCS8140_PCI_IOMISC_SIZE)
+#define MCS8140_PCI_CFG_VIRT_BASE	(MCS814X_IO_BASE - \
+					 MCS8140_PCI_CONFIG_SIZE)
+
+#define PCI_FATAL_ERROR			1
+#define EXTERNAL_ABORT_NON_LINE_FETCH	8
+#define EPRM_DONE			0x80
+#define EPRM_SDRAM_FUNC0		0xAC
+#define PCI_INTD			4
+#define MCS8140_PCI_DEVICE_ID		0xA0009710
+#define MCS8140_PCI_CLASS_ID		0x02000011  /* Host-Class id :0x0600 */
+#define PCI_IF_CONFIG			0x200
+
+static void __iomem *mcs8140_pci_master_base;
+static void __iomem *mcs8140_eeprom_emu_base;
+
+static unsigned long __pci_addr(struct pci_bus *bus,
+				unsigned int devfn, int offset)
+{
+	unsigned int busnr = bus->number;
+	unsigned int slot;
+
+	/* we only support bus 0 */
+	if (busnr != 0)
+		return 0;
+
+	/*
+	 * Trap out illegal values
+	 */
+	BUG_ON(devfn > 255 || busnr > 255 || devfn > 255);
+
+	/* Scan 3 slots */
+	slot = PCI_SLOT(devfn);
+	switch (slot) {
+	case 1:
+	case 2:
+	case 3:
+		if (PCI_FUNC(devfn) >= 4)
+			return 0;
+
+		return MCS8140_PCI_CFG_VIRT_BASE | (PCI_SLOT(devfn) << 11) |
+			(PCI_FUNC(devfn) << 8) | offset;
+	default:
+		pr_warn("Ignoring: PCI Slot is %x\n", PCI_SLOT(devfn));
+		return 0;
+	}
+}
+
+static int mcs8140_pci_host_status(void)
+{
+	u32 host_status;
+
+	host_status = __raw_readl(mcs8140_pci_master_base + PCI_IF_CONFIG);
+	if (host_status & PCI_FATAL_ERROR) {
+		__raw_writel(host_status & 0xfffffff0,
+			mcs8140_pci_master_base + PCI_IF_CONFIG);
+		/* flush write */
+		host_status =
+			__raw_readl(mcs8140_pci_master_base + PCI_IF_CONFIG);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int mcs8140_pci_read_config(struct pci_bus *bus,
+					unsigned int devfn, int where,
+					int size, u32 *val)
+{
+	unsigned long v = 0xFFFFFFFF;
+	unsigned long addr = __pci_addr(bus, devfn, where);
+
+	if (addr != 0) {
+		switch (size) {
+		case 1:
+			v = __raw_readb(addr);
+			break;
+		case 2:
+			addr &= ~1;
+			v = __raw_readw(addr);
+			break;
+		default:
+			addr &= ~3;
+			v = __raw_readl(addr);
+			break;
+		}
+	} else
+		v = 0xffffffff;
+
+	if (mcs8140_pci_host_status())
+		v = 0xffffffff;
+
+	*val = v;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static void mcs8140_eeprom_emu_init(void)
+{
+	__raw_writel(0x0000000F, mcs8140_eeprom_emu_base + EPRM_SDRAM_FUNC0);
+	__raw_writel(0x08000000, MCS8140_PCI_CFG_VIRT_BASE + 0x10);
+	/* Set the DONE bit of the EEPROM emulator */
+	__raw_writel(0x01, mcs8140_eeprom_emu_base + EPRM_DONE);
+}
+
+static int mcs8140_pci_write_config(struct pci_bus *bus,
+					unsigned int devfn, int where,
+					int size, u32 val)
+{
+	unsigned long addr = __pci_addr(bus, devfn, where);
+
+	if (addr != 0) {
+		switch (size) {
+		case 1:
+			__raw_writeb((u8)val, addr);
+			break;
+		case 2:
+			__raw_writew((u16)val, addr);
+			break;
+		case 4:
+			__raw_writel(val, addr);
+			break;
+		}
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_mcs8140_ops = {
+	.read	= mcs8140_pci_read_config,
+	.write	= mcs8140_pci_write_config,
+};
+
+
+static struct resource io_mem = {
+	.name	= "PCI I/O space",
+	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE,
+	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE + SZ_64M,
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource pre_mem = {
+	.name	= "PCI prefetchable",
+	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_PRE_BASE,
+	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_PRE_BASE + SZ_512M,
+	.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,
+};
+
+static struct resource non_mem = {
+	.name	= "PCI non-prefetchable",
+	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_NONPRE_BASE,
+	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_NONPRE_BASE + SZ_256M,
+	.flags	= IORESOURCE_MEM,
+};
+
+int __init pci_mcs8140_setup_resources(struct pci_sys_data *sys)
+{
+	int ret = 0;
+
+	ret = request_resource(&iomem_resource, &io_mem);
+	if (ret)
+		goto out;
+
+	ret = request_resource(&iomem_resource, &non_mem);
+	if (ret)
+		goto release_io_mem;
+
+	ret = request_resource(&iomem_resource, &pre_mem);
+	if (ret)
+		goto release_non_mem;
+
+	mcs8140_eeprom_emu_init();
+
+	pci_add_resource(&sys->resources, &io_mem);
+	pci_add_resource(&sys->resources, &non_mem);
+	pci_add_resource(&sys->resources, &pre_mem);
+
+	return ret;
+
+release_non_mem:
+	release_resource(&non_mem);
+release_io_mem:
+	release_resource(&io_mem);
+out:
+	return ret;
+}
+
+struct pci_bus *pci_mcs8140_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	return pci_scan_bus(sys->busnr, &pci_mcs8140_ops, sys);
+}
+
+
+int __init pci_mcs8140_setup(int nr, struct pci_sys_data *sys)
+{
+	int ret = 0;
+	u32 val;
+
+	if (nr > 0)
+		return 0;
+
+	sys->mem_offset = MCS8140_PCI_IO_VIRT_BASE - MCS8140_PCI_IO_BASE;
+	sys->io_offset = 0;
+
+	ret = pci_mcs8140_setup_resources(sys);
+	if (ret < 0) {
+		pr_err("unable to setup mcs8140 resources\n");
+		goto out;
+	}
+
+	val = __raw_readl(MCS8140_PCI_CFG_VIRT_BASE);
+	if (val != MCS8140_PCI_DEVICE_ID) {
+		pr_err("cannot find MCS8140 PCI Core: %08x\n", val);
+		ret = -EIO;
+		goto out;
+	}
+
+	pr_info("MCS8140 PCI core found\n");
+
+	val = __raw_readl(MCS8140_PCI_CFG_VIRT_BASE + PCI_COMMAND);
+	/* Added to support wireless cards */
+	__raw_writel(0, MCS8140_PCI_CFG_VIRT_BASE + 0x40);
+	__raw_writel(val | 0x147, MCS8140_PCI_CFG_VIRT_BASE + PCI_COMMAND);
+	val = __raw_readl(MCS8140_PCI_CFG_VIRT_BASE + PCI_COMMAND);
+	ret = 1;
+out:
+	return ret;
+}
+
+
+static int __init mcs8140_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int line = IRQ_PCI_INTA;
+
+	if (pin != 0) {
+		/* IRQ_PCIA - 22 */
+		if (pin == PCI_INTD)
+			line = IRQ_PCI_INTA + pin; /* IRQ_PCIA - 22 */
+		else
+			line = IRQ_PCI_INTA + pin - 1; /* IRQ_PCIA - 22 */
+	}
+
+	pr_info("PCI: Map interrupt slot 0x%02x pin 0x%02x line 0x%02x\n",
+		slot, pin, line);
+
+	return line;
+}
+
+static irqreturn_t mcs8140_pci_abort_interrupt(int irq, void *dummy)
+{
+	u32 word;
+
+	word = __raw_readl(mcs8140_pci_master_base + PCI_IF_CONFIG);
+	if (!(word & (1 << 24)))
+		return IRQ_NONE;
+
+	__raw_writel(word & 0xfffffff0,
+		mcs8140_pci_master_base + PCI_IF_CONFIG);
+	/* flush write */
+	word = __raw_readl(mcs8140_pci_master_base + PCI_IF_CONFIG);
+
+	return IRQ_HANDLED;
+}
+
+static int mcs8140_pci_abort_irq_init(int irq)
+{
+	u32 word;
+
+	/* Enable Interrupt in PCI Master Core */
+	word = __raw_readl(mcs8140_pci_master_base + PCI_IF_CONFIG);
+	word |= (1 << 24);
+	__raw_writel(word, mcs8140_pci_master_base + PCI_IF_CONFIG);
+
+	/* flush write */
+	word = __raw_readl(mcs8140_pci_master_base + PCI_IF_CONFIG);
+
+	return request_irq(irq, mcs8140_pci_abort_interrupt, 0,
+			"PCI abort", NULL);
+}
+
+static int mcs8140_pci_host_abort(unsigned long addr,
+				unsigned int fsr, struct pt_regs *regs)
+{
+	pr_warn("PCI Data abort: address = 0x%08lx fsr = 0x%03x "
+		"PC = 0x%08lx LR = 0x%08lx\n",
+		addr, fsr, regs->ARM_pc, regs->ARM_lr);
+
+	/*
+	 * If it was an imprecise abort, then we need to correct the
+	 * return address to be _after_ the instruction.
+	 */
+	if (fsr & (1 << 10) || mcs8140_pci_host_status())
+		regs->ARM_pc += 4;
+
+	return 0;
+}
+
+static void mcs8140_data_abort_init(void)
+{
+	hook_fault_code(EXTERNAL_ABORT_NON_LINE_FETCH,
+		mcs8140_pci_host_abort, SIGBUS,
+		0, "external abort on non-line fetch");
+}
+
+static struct hw_pci mcs8140_pci __initdata = {
+	.map_irq		= mcs8140_map_irq,
+	.nr_controllers		= 1,
+	.setup			= pci_mcs8140_setup,
+	.scan			= pci_mcs8140_scan_bus,
+};
+
+static struct map_desc mcs8140_pci_io_desc[] __initdata = {
+	{
+		.virtual	= MCS8140_PCI_CFG_VIRT_BASE,
+		.pfn		= __phys_to_pfn(MCS8140_PCI_CFG_BASE),
+		.length		= MCS8140_PCI_CONFIG_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= MCS8140_PCI_IO_VIRT_BASE,
+		.pfn		= __phys_to_pfn(MCS8140_PCI_IO_BASE),
+		.length		= MCS8140_PCI_IOMISC_SIZE,
+		.type		= MT_DEVICE
+	},
+};
+
+static int __devinit mcs8140_pci_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	int ret, irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get mem resource 0\n");
+		return -ENODEV;
+	}
+
+	mcs8140_pci_master_base = devm_ioremap(&pdev->dev, res->start,
+					resource_size(res));
+	if (!mcs8140_pci_master_base) {
+		dev_err(&pdev->dev, "failed to remap PCI master regs\n");
+		return -ENODEV;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get mem resource 1\n");
+		return -ENOMEM;
+	}
+
+	mcs8140_eeprom_emu_base = devm_ioremap(&pdev->dev, res->start,
+					resource_size(res));
+	if (!mcs8140_eeprom_emu_base) {
+		dev_err(&pdev->dev, "failed to remap EEPROM regs\n");
+		return -ENOMEM;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "failed to get pci abort irq\n");
+		return -ENODEV;
+	}
+
+	/* Setup static mappins for PCI CFG space */
+	iotable_init(mcs8140_pci_io_desc, ARRAY_SIZE(mcs8140_pci_io_desc));
+
+	pcibios_min_io = MCS8140_PCI_HOST_BASE;
+	pcibios_min_mem = MCS8140_PCI_HOST_BASE + MCS8140_PCI_PRE_BASE;
+
+	mcs8140_data_abort_init();
+	ret = mcs8140_pci_abort_irq_init(irq);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to setup abort irq\n");
+		return ret;
+	}
+
+	pci_common_init(&mcs8140_pci);
+
+	return 0;
+}
+
+static struct of_device_id mcs8140_of_ids[] __devinitdata = {
+	{ .compatible = "moschip,mcs8140-pci" },
+	{ .compatible = "moschip,mcs814x-pci" },
+	{ /* sentinel */ },
+};
+
+static struct platform_driver mcs8140_pci_driver = {
+	.driver	= {
+		.name	= "mcs8140-pci",
+		.of_match_table = mcs8140_of_ids,
+	},
+	.probe	= mcs8140_pci_probe,
+};
+
+static int __init mcs8140_pci_init(void)
+{
+	return platform_driver_register(&mcs8140_pci_driver);
+}
+subsys_initcall(mcs8140_pci_init);
+
diff --git a/arch/arm/mach-mcs814x/timer.c b/arch/arm/mach-mcs814x/timer.c
new file mode 100644
index 0000000..e8408e4
--- /dev/null
+++ b/arch/arm/mach-mcs814x/timer.c
@@ -0,0 +1,133 @@
+/*
+ * Moschip MCS814x timer routines
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under GPLv2
+ */
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/mach/time.h>
+#include <mach/mcs814x.h>
+
+/* Timer block registers */
+#define TIMER_VAL	0x00
+#define TIMER_CTL	0x04
+
+static u32 last_reload;
+static u32 timer_correct;
+static u32 clock_rate;
+static u32 timer_reload_value;
+static void __iomem *mcs814x_timer_base;
+
+static inline unsigned long ticks2usecs(u32 x)
+{
+	return x / (clock_rate / 1000000);
+}
+
+/*
+ * Returns number of ms since last clock interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long mcs814x_gettimeoffset(void)
+{
+	u32 ticks = __raw_readl(mcs814x_timer_base + TIMER_VAL);
+
+	if (ticks < last_reload)
+		return ticks2usecs(ticks + (u32)(0xffffffff - last_reload));
+	else
+		return ticks2usecs(ticks - last_reload);
+}
+
+
+static irqreturn_t mcs814x_timer_interrupt(int irq, void *dev_id)
+{
+	u32 count = __raw_readl(mcs814x_timer_base + TIMER_VAL);
+
+	/* take into account delay up to this moment */
+	last_reload = count + timer_correct + timer_reload_value;
+
+	if (last_reload < timer_reload_value)
+		last_reload = timer_reload_value;
+	else if (timer_correct == 0)
+		timer_correct = __raw_readl(mcs814x_timer_base + TIMER_VAL) -
+					count;
+
+	__raw_writel(last_reload, mcs814x_timer_base + TIMER_VAL);
+
+	timer_tick();
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction mcs814x_timer_irq = {
+	.name		= "mcs814x-timer",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= mcs814x_timer_interrupt,
+};
+
+static struct of_device_id mcs814x_timer_ids[] = {
+	{ .compatible = "moschip,mcs814x-timer" },
+	{ /* sentinel */ },
+};
+
+static void __init mcs814x_of_timer_init(void)
+{
+	struct device_node *np;
+	const unsigned int *intspec;
+
+	np = of_find_matching_node(NULL, mcs814x_timer_ids);
+	if (!np)
+		panic("unable to find compatible timer node in dtb");
+
+	mcs814x_timer_base = of_iomap(np, 0);
+	if (!mcs814x_timer_base)
+		panic("unable to remap timer cpu registers");
+
+	intspec = of_get_property(np, "interrupts", NULL);
+	if (!intspec)
+		panic("no interrupts property for timer");
+
+	mcs814x_timer_irq.irq = be32_to_cpup(intspec);
+}
+
+static void __init mcs814x_timer_init(void)
+{
+	struct clk *clk;
+
+	clk = clk_get_sys("timer0", NULL);
+	if (IS_ERR_OR_NULL(clk))
+		panic("unable to get timer0 clock");
+
+	clock_rate = clk_get_rate(clk);
+	clk_put(clk);
+
+	mcs814x_of_timer_init();
+
+	pr_info("Timer frequency: %d (kHz)\n", clock_rate / 1000);
+
+	timer_reload_value = 0xffffffff - (clock_rate / HZ);
+
+	/* disable timer */
+	__raw_writel(0, mcs814x_timer_base + TIMER_CTL);
+	__raw_writel(timer_reload_value, mcs814x_timer_base + TIMER_VAL);
+	last_reload = timer_reload_value;
+
+	setup_irq(mcs814x_timer_irq.irq, &mcs814x_timer_irq);
+	/* enable timer, stop timer in debug mode */
+	__raw_writel(0x03, mcs814x_timer_base + TIMER_CTL);
+}
+
+struct sys_timer mcs814x_timer = {
+	.init	= mcs814x_timer_init,
+	.offset	= mcs814x_gettimeoffset,
+};
-- 
1.7.10.4

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

* [PATCH 2/8] ARM: MCS814x: add Device Tree based MCS8140 board support
  2012-07-15 14:49 ` Florian Fainelli
@ 2012-07-15 14:49   ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: olof, devicetree-discuss, Florian Fainelli, arnd

This patch adds a generic MCS8140-based device tree registration
board along with the corresponding mcs8140.dtsi file.

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 arch/arm/boot/dts/mcs8140.dtsi           |  207 ++++++++++++++++++++++++++++++
 arch/arm/mach-mcs814x/board-mcs8140-dt.c |   44 +++++++
 2 files changed, 251 insertions(+)
 create mode 100644 arch/arm/boot/dts/mcs8140.dtsi
 create mode 100644 arch/arm/mach-mcs814x/board-mcs8140-dt.c

diff --git a/arch/arm/boot/dts/mcs8140.dtsi b/arch/arm/boot/dts/mcs8140.dtsi
new file mode 100644
index 0000000..7888026
--- /dev/null
+++ b/arch/arm/boot/dts/mcs8140.dtsi
@@ -0,0 +1,207 @@
+/*
+ * mcs8140.dtsi - Device Tree Include file for Moschip MCS8140 family SoC
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under GPLv2.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	model = "Moschip MCS8140 family SoC";
+	compatible = "moschip,mcs8140";
+	interrupt-parent = <&intc>;
+
+	aliases {
+		serial0 = &uart0;
+		eth0 = &eth0;
+	};
+
+	cpus {
+		cpu@0 {
+			compatible = "arm,arm926ejs";
+		};
+	};
+
+	ahb {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		vci {
+			compatible = "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			eth0: ethernet@40084000 {
+				compatible = "moschip,nuport-mac";
+				reg = <0x40084000 0xd8		// mac
+					0x40080000 0x58>;	// dma channels
+				interrupts = <4 5 29>;	/* tx, rx, link */
+				nuport-mac,buffer-shifting;
+				nuport-mac,link-activity = <0>;
+			};
+
+			tso@40088000 {
+				reg = <0x40088000 0x1c>;
+				interrupts = <7>;
+			};
+
+			i2s@4008c000 {
+				compatible = "moschip,mcs814x-i2s";
+				reg = <0x4008c000 0x18>;
+				interrupts = <8>;
+			};
+
+			ipsec@40094000 {
+				compatible = "moschip,mcs814x-ipsec";
+				reg = <0x40094000 0x1d8>;
+				interrupts = <16>;
+			};
+
+			rng@4009c000 {
+				compatible = "moschip,mcs814x-rng";
+				reg = <0x4009c000 0x8>;
+			};
+
+			memc@400a8000 {
+				reg = <0x400a8000 0x58>;
+			};
+
+			list-proc@400ac0c0 {
+				reg = <0x400ac0c0 0x38>;
+				interrupts = <19 27>;		// done, error
+			};
+
+			pci@400b0000 {
+				compatible = "moschip,mcs814x-pci";
+				reg = <0x400b0000 0x44		// PCI master
+					0x400d8000 0xe4>;	// EEPROM emulator
+				interrupts = <25>;		// abort interrupt
+				status = "disabled";
+				#address-cells = <3>;
+				#size-cells = <2>;
+
+				ranges = <0x01000000 0 0x80000000 0x80000000 0 0x04000000   // IO
+					  0x42000000 0 0x90000000 0x90000000 0 0x20000000   // non-prefetch
+					  0x02000000 0 0xb0000000 0xb0000000 0 0x10000000>; // prefecth
+
+				#interrupt-cells = <1>;
+				interrupt-map-mask = <>;
+				interrupt-map = <0 0 0 1 &intc 22 0
+						 0 0 0 2 &intc 23 0
+						 0 0 0 3 &intc 24 0
+						 0 0 0 4 &intc 26 0>;
+			};
+
+			gpio: gpio@400d0000 {
+				compatible = "moschip,mcs814x-gpio";
+				reg = <0x400d0000 0x670>;
+				interrupts = <10>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				num-gpios = <20>;
+			};
+
+			eepio: gpio@400d4000 {
+				compatible = "moschip,mcs814x-gpio";
+				reg = <0x400d4000 0x470>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				num-gpios = <4>;
+			};
+
+			uart0: serial@400dc000 {
+				compatible = "ns16550";
+				reg = <0x400dc000 0x20>;
+				clock-frequency = <50000000>;
+				reg-shift = <2>;
+				interrupts = <21>;
+				status = "okay";
+			};
+
+			intc: interrupt-controller@400e4000 {
+				#interrupt-cells = <1>;
+				compatible = "moschip,mcs814x-intc";
+				interrupt-controller;
+				interrupt-parent;
+				reg = <0x400e4000 0x48>;
+			};
+
+			m2m@400e8000 {
+				reg = <0x400e8000 0x24>;
+				interrupts = <17>;
+			};
+
+			eth-filters@400ec000 {
+				reg = <0x400ec000 0x80>;
+			};
+
+			timer: timer@400f800c {
+				compatible = "moschip,mcs814x-timer";
+				interrupts = <0>;
+				reg = <0x400f800c 0x8>;
+			};
+
+			watchdog@400f8014 {
+				compatible = "moschip,mcs814x-wdt";
+				reg = <0x400f8014 0x8>;
+			};
+
+			adc {
+				compatible = "simple-bus";
+				#address-cells = <2>;
+				#size-cells = <1>;
+				// 8 64MB chip-selects
+				ranges = <0 0 0x00000000 0x4000000	// sdram
+					  1 0 0x04000000 0x4000000	// sdram
+					  2 0 0x08000000 0x4000000	// reserved
+					  3 0 0x0c000000 0x4000000	// flash/localbus
+					  4 0 0x10000000 0x4000000	// flash/localbus
+					  5 0 0x14000000 0x4000000	// flash/localbus
+					  6 0 0x18000000 0x4000000	// flash/localbus
+					  7 0 0x1c000000 0x4000000>;	// flash/localbus
+
+				sdram: memory@0,0 {
+					reg = <0 0 0>;
+				};
+
+				nor: flash@7,0 {
+					reg = <7 0 0x4000000>;
+					compatible = "cfi-flash";
+					bank-width = <1>;		// 8-bit external flash
+					#address-cells = <1>;
+					#size-cells = <1>;
+                                };
+                        };
+
+			usb0: ehci@400fc000 {
+				compatible = "moschip,mcs814x-ehci", "usb-ehci";
+				reg = <0x400fc000 0x74>;
+				interrupts = <2>;
+			};
+
+			usb1: ohci@400fd000 {
+				compatible = "moschip,mcs814x-ohci", "ohci-le";
+				reg = <0x400fd000 0x74>;
+				interrupts = <11>;
+			};
+
+			usb2: ohci@400fe000 {
+				compatible = "moschip,mcs814x-ohci", "ohci-le";
+				reg = <0x400fe000 0x74>;
+				interrupts = <12>;
+			};
+
+			usb3: otg@400ff000 {
+				compatible = "moschip,msc814x-otg", "usb-otg";
+				reg = <0x400ff000 0x1000>;
+				interrupts = <13>;
+			};
+		};
+
+	};
+};
diff --git a/arch/arm/mach-mcs814x/board-mcs8140-dt.c b/arch/arm/mach-mcs814x/board-mcs8140-dt.c
new file mode 100644
index 0000000..5d13283
--- /dev/null
+++ b/arch/arm/mach-mcs814x/board-mcs8140-dt.c
@@ -0,0 +1,44 @@
+/*
+ * Setup code for Moschip MCS8140-based board using Device Tree
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under GPLv2.
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/irqdomain.h>
+#include <linux/of_platform.h>
+
+#include "common.h"
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+static void __init mcs814x_dt_device_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+	mcs814x_init_machine();
+}
+
+static const char *mcs8140_dt_board_compat[] __initdata = {
+	"moschip,mcs8140",
+	NULL,	/* sentinel */
+};
+
+DT_MACHINE_START(mcs8140_dt, "Moschip MCS8140 board")
+	/* Maintainer: Florian Fainelli <florian@openwrt.org> */
+	.timer		= &mcs814x_timer,
+	.map_io		= mcs814x_map_io,
+	.init_early	= mcs814x_clk_init,
+	.init_irq	= mcs814x_of_irq_init,
+	.init_machine	= mcs814x_dt_device_init,
+	.restart	= mcs814x_restart,
+	.dt_compat	= mcs8140_dt_board_compat,
+MACHINE_END
+
-- 
1.7.10.4

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

* [PATCH 2/8] ARM: MCS814x: add Device Tree based MCS8140 board support
@ 2012-07-15 14:49   ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds a generic MCS8140-based device tree registration
board along with the corresponding mcs8140.dtsi file.

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 arch/arm/boot/dts/mcs8140.dtsi           |  207 ++++++++++++++++++++++++++++++
 arch/arm/mach-mcs814x/board-mcs8140-dt.c |   44 +++++++
 2 files changed, 251 insertions(+)
 create mode 100644 arch/arm/boot/dts/mcs8140.dtsi
 create mode 100644 arch/arm/mach-mcs814x/board-mcs8140-dt.c

diff --git a/arch/arm/boot/dts/mcs8140.dtsi b/arch/arm/boot/dts/mcs8140.dtsi
new file mode 100644
index 0000000..7888026
--- /dev/null
+++ b/arch/arm/boot/dts/mcs8140.dtsi
@@ -0,0 +1,207 @@
+/*
+ * mcs8140.dtsi - Device Tree Include file for Moschip MCS8140 family SoC
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under GPLv2.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	model = "Moschip MCS8140 family SoC";
+	compatible = "moschip,mcs8140";
+	interrupt-parent = <&intc>;
+
+	aliases {
+		serial0 = &uart0;
+		eth0 = &eth0;
+	};
+
+	cpus {
+		cpu at 0 {
+			compatible = "arm,arm926ejs";
+		};
+	};
+
+	ahb {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		vci {
+			compatible = "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			eth0: ethernet at 40084000 {
+				compatible = "moschip,nuport-mac";
+				reg = <0x40084000 0xd8		// mac
+					0x40080000 0x58>;	// dma channels
+				interrupts = <4 5 29>;	/* tx, rx, link */
+				nuport-mac,buffer-shifting;
+				nuport-mac,link-activity = <0>;
+			};
+
+			tso at 40088000 {
+				reg = <0x40088000 0x1c>;
+				interrupts = <7>;
+			};
+
+			i2s at 4008c000 {
+				compatible = "moschip,mcs814x-i2s";
+				reg = <0x4008c000 0x18>;
+				interrupts = <8>;
+			};
+
+			ipsec at 40094000 {
+				compatible = "moschip,mcs814x-ipsec";
+				reg = <0x40094000 0x1d8>;
+				interrupts = <16>;
+			};
+
+			rng at 4009c000 {
+				compatible = "moschip,mcs814x-rng";
+				reg = <0x4009c000 0x8>;
+			};
+
+			memc at 400a8000 {
+				reg = <0x400a8000 0x58>;
+			};
+
+			list-proc at 400ac0c0 {
+				reg = <0x400ac0c0 0x38>;
+				interrupts = <19 27>;		// done, error
+			};
+
+			pci at 400b0000 {
+				compatible = "moschip,mcs814x-pci";
+				reg = <0x400b0000 0x44		// PCI master
+					0x400d8000 0xe4>;	// EEPROM emulator
+				interrupts = <25>;		// abort interrupt
+				status = "disabled";
+				#address-cells = <3>;
+				#size-cells = <2>;
+
+				ranges = <0x01000000 0 0x80000000 0x80000000 0 0x04000000   // IO
+					  0x42000000 0 0x90000000 0x90000000 0 0x20000000   // non-prefetch
+					  0x02000000 0 0xb0000000 0xb0000000 0 0x10000000>; // prefecth
+
+				#interrupt-cells = <1>;
+				interrupt-map-mask = <>;
+				interrupt-map = <0 0 0 1 &intc 22 0
+						 0 0 0 2 &intc 23 0
+						 0 0 0 3 &intc 24 0
+						 0 0 0 4 &intc 26 0>;
+			};
+
+			gpio: gpio at 400d0000 {
+				compatible = "moschip,mcs814x-gpio";
+				reg = <0x400d0000 0x670>;
+				interrupts = <10>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				num-gpios = <20>;
+			};
+
+			eepio: gpio at 400d4000 {
+				compatible = "moschip,mcs814x-gpio";
+				reg = <0x400d4000 0x470>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				num-gpios = <4>;
+			};
+
+			uart0: serial at 400dc000 {
+				compatible = "ns16550";
+				reg = <0x400dc000 0x20>;
+				clock-frequency = <50000000>;
+				reg-shift = <2>;
+				interrupts = <21>;
+				status = "okay";
+			};
+
+			intc: interrupt-controller at 400e4000 {
+				#interrupt-cells = <1>;
+				compatible = "moschip,mcs814x-intc";
+				interrupt-controller;
+				interrupt-parent;
+				reg = <0x400e4000 0x48>;
+			};
+
+			m2m at 400e8000 {
+				reg = <0x400e8000 0x24>;
+				interrupts = <17>;
+			};
+
+			eth-filters at 400ec000 {
+				reg = <0x400ec000 0x80>;
+			};
+
+			timer: timer at 400f800c {
+				compatible = "moschip,mcs814x-timer";
+				interrupts = <0>;
+				reg = <0x400f800c 0x8>;
+			};
+
+			watchdog at 400f8014 {
+				compatible = "moschip,mcs814x-wdt";
+				reg = <0x400f8014 0x8>;
+			};
+
+			adc {
+				compatible = "simple-bus";
+				#address-cells = <2>;
+				#size-cells = <1>;
+				// 8 64MB chip-selects
+				ranges = <0 0 0x00000000 0x4000000	// sdram
+					  1 0 0x04000000 0x4000000	// sdram
+					  2 0 0x08000000 0x4000000	// reserved
+					  3 0 0x0c000000 0x4000000	// flash/localbus
+					  4 0 0x10000000 0x4000000	// flash/localbus
+					  5 0 0x14000000 0x4000000	// flash/localbus
+					  6 0 0x18000000 0x4000000	// flash/localbus
+					  7 0 0x1c000000 0x4000000>;	// flash/localbus
+
+				sdram: memory at 0,0 {
+					reg = <0 0 0>;
+				};
+
+				nor: flash at 7,0 {
+					reg = <7 0 0x4000000>;
+					compatible = "cfi-flash";
+					bank-width = <1>;		// 8-bit external flash
+					#address-cells = <1>;
+					#size-cells = <1>;
+                                };
+                        };
+
+			usb0: ehci at 400fc000 {
+				compatible = "moschip,mcs814x-ehci", "usb-ehci";
+				reg = <0x400fc000 0x74>;
+				interrupts = <2>;
+			};
+
+			usb1: ohci at 400fd000 {
+				compatible = "moschip,mcs814x-ohci", "ohci-le";
+				reg = <0x400fd000 0x74>;
+				interrupts = <11>;
+			};
+
+			usb2: ohci at 400fe000 {
+				compatible = "moschip,mcs814x-ohci", "ohci-le";
+				reg = <0x400fe000 0x74>;
+				interrupts = <12>;
+			};
+
+			usb3: otg at 400ff000 {
+				compatible = "moschip,msc814x-otg", "usb-otg";
+				reg = <0x400ff000 0x1000>;
+				interrupts = <13>;
+			};
+		};
+
+	};
+};
diff --git a/arch/arm/mach-mcs814x/board-mcs8140-dt.c b/arch/arm/mach-mcs814x/board-mcs8140-dt.c
new file mode 100644
index 0000000..5d13283
--- /dev/null
+++ b/arch/arm/mach-mcs814x/board-mcs8140-dt.c
@@ -0,0 +1,44 @@
+/*
+ * Setup code for Moschip MCS8140-based board using Device Tree
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under GPLv2.
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/irqdomain.h>
+#include <linux/of_platform.h>
+
+#include "common.h"
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+static void __init mcs814x_dt_device_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+	mcs814x_init_machine();
+}
+
+static const char *mcs8140_dt_board_compat[] __initdata = {
+	"moschip,mcs8140",
+	NULL,	/* sentinel */
+};
+
+DT_MACHINE_START(mcs8140_dt, "Moschip MCS8140 board")
+	/* Maintainer: Florian Fainelli <florian@openwrt.org> */
+	.timer		= &mcs814x_timer,
+	.map_io		= mcs814x_map_io,
+	.init_early	= mcs814x_clk_init,
+	.init_irq	= mcs814x_of_irq_init,
+	.init_machine	= mcs814x_dt_device_init,
+	.restart	= mcs814x_restart,
+	.dt_compat	= mcs8140_dt_board_compat,
+MACHINE_END
+
-- 
1.7.10.4

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

* [PATCH 3/8] ARM: MCS814x: add Device Tree bindings documentation
  2012-07-15 14:49 ` Florian Fainelli
@ 2012-07-15 14:49   ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: olof, devicetree-discuss, Florian Fainelli, arnd

This patch adds the device tree bindings documentation for the basic
Moschip MCS814x bindings that we support:
- soc
- interrupt controller
- timer
- pci controller

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 .../devicetree/bindings/arm/mcs814x/mcs814x-intc.txt |   18 ++++++++++++++++++
 .../devicetree/bindings/arm/mcs814x/mcs814x-pci.txt  |   16 ++++++++++++++++
 .../bindings/arm/mcs814x/mcs814x-timer.txt           |   16 ++++++++++++++++
 .../devicetree/bindings/arm/mcs814x/mcs814x.txt      |   13 +++++++++++++
 .../devicetree/bindings/vendor-prefixes.txt          |    1 +
 5 files changed, 64 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x-intc.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x-timer.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x.txt

diff --git a/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-intc.txt b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-intc.txt
new file mode 100644
index 0000000..2bf0c47
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-intc.txt
@@ -0,0 +1,18 @@
+Moschip MCS814x interrupt controller bindings
+----------------------------------------------
+
+Required properties:
+- compatible: should be "moschip,mcs814x-intc"
+- interrupt-controller: identifies the node as an interrupt controller
+- #interrupt-cells: the number of cells to define the interrupts. Should be 1.
+The cells are the IRQ number
+- reg: contains the base address register and length, there should be only 1
+  cell
+
+Example:
+	intc: interrupt-controller@400e4000 {
+		compatible = "moschip,mcs814x-intc";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		reg = <0x400e4000 0x48>;
+	};
diff --git a/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
new file mode 100644
index 0000000..de59b04
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
@@ -0,0 +1,16 @@
+Moschip MCS814x PCI controller bindings
+---------------------------------------
+
+Required properties:
+- compatible: should be "moschip,mcs814x-pci"
+- reg: should contain the base register address and length of the PCI controller
+  configuration register as well as the base register address and length of the
+  PCI eeprom emulator
+- interrupts: should contain the interrupt line of the abort interrupt
+- #address-cells: should be 3
+- #size-cells: should be 2
+- ranges: should contain the properly encoded PCI ranges of the IO, non-prefetchable
+  and prefetchable memory regions
+- #interrupt-cells: should be 1
+- interrupt-map-mask: should be 0
+- interrupt-map: should be the properly encoded PCI slot/pin to interrupt line
diff --git a/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-timer.txt b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-timer.txt
new file mode 100644
index 0000000..0bf22d1
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-timer.txt
@@ -0,0 +1,16 @@
+MMoschip MCS814x timer bindings
+-------------------------------
+
+Required properties:
+- compatible: should be "moschip,mcs814x-timer"
+- interrupts: should be the physical interrupt number
+- reg: contains the base address register and length, there should be only 1
+  cell
+
+Example:
+	timer: timer@400f800c {
+		compatible = "moschip,mcs814x-timer";
+		interrupts = <0>;
+		reg = <0x400f800c 0x8>;
+	};
+
diff --git a/Documentation/devicetree/bindings/arm/mcs814x/mcs814x.txt b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x.txt
new file mode 100644
index 0000000..503c234
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x.txt
@@ -0,0 +1,13 @@
+MMoschip MCS814x SoC bindings
+
+-----------------------------
+
+Boards including a Moschip MCS814x SoC should include the following properties
+
+Required root node property:
+- compatible: must contain "moschip,mcs814x"
+
+Boards including a Moschip MCS8140 should also include the following property.
+
+Required root node property:
+- compatible: must contain "moschip,mcs8140"
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 6eab917..943e4f3 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -28,6 +28,7 @@ linux	Linux-specific binding
 marvell	Marvell Technology Group Ltd.
 maxim	Maxim Integrated Products
 mosaixtech	Mosaix Technologies, Inc.
+moschp		Moschip Semiconductors
 national	National Semiconductor
 nintendo	Nintendo
 nvidia	NVIDIA
-- 
1.7.10.4

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

* [PATCH 3/8] ARM: MCS814x: add Device Tree bindings documentation
@ 2012-07-15 14:49   ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the device tree bindings documentation for the basic
Moschip MCS814x bindings that we support:
- soc
- interrupt controller
- timer
- pci controller

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 .../devicetree/bindings/arm/mcs814x/mcs814x-intc.txt |   18 ++++++++++++++++++
 .../devicetree/bindings/arm/mcs814x/mcs814x-pci.txt  |   16 ++++++++++++++++
 .../bindings/arm/mcs814x/mcs814x-timer.txt           |   16 ++++++++++++++++
 .../devicetree/bindings/arm/mcs814x/mcs814x.txt      |   13 +++++++++++++
 .../devicetree/bindings/vendor-prefixes.txt          |    1 +
 5 files changed, 64 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x-intc.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x-timer.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mcs814x/mcs814x.txt

diff --git a/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-intc.txt b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-intc.txt
new file mode 100644
index 0000000..2bf0c47
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-intc.txt
@@ -0,0 +1,18 @@
+Moschip MCS814x interrupt controller bindings
+----------------------------------------------
+
+Required properties:
+- compatible: should be "moschip,mcs814x-intc"
+- interrupt-controller: identifies the node as an interrupt controller
+- #interrupt-cells: the number of cells to define the interrupts. Should be 1.
+The cells are the IRQ number
+- reg: contains the base address register and length, there should be only 1
+  cell
+
+Example:
+	intc: interrupt-controller at 400e4000 {
+		compatible = "moschip,mcs814x-intc";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		reg = <0x400e4000 0x48>;
+	};
diff --git a/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
new file mode 100644
index 0000000..de59b04
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
@@ -0,0 +1,16 @@
+Moschip MCS814x PCI controller bindings
+---------------------------------------
+
+Required properties:
+- compatible: should be "moschip,mcs814x-pci"
+- reg: should contain the base register address and length of the PCI controller
+  configuration register as well as the base register address and length of the
+  PCI eeprom emulator
+- interrupts: should contain the interrupt line of the abort interrupt
+- #address-cells: should be 3
+- #size-cells: should be 2
+- ranges: should contain the properly encoded PCI ranges of the IO, non-prefetchable
+  and prefetchable memory regions
+- #interrupt-cells: should be 1
+- interrupt-map-mask: should be 0
+- interrupt-map: should be the properly encoded PCI slot/pin to interrupt line
diff --git a/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-timer.txt b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-timer.txt
new file mode 100644
index 0000000..0bf22d1
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-timer.txt
@@ -0,0 +1,16 @@
+MMoschip MCS814x timer bindings
+-------------------------------
+
+Required properties:
+- compatible: should be "moschip,mcs814x-timer"
+- interrupts: should be the physical interrupt number
+- reg: contains the base address register and length, there should be only 1
+  cell
+
+Example:
+	timer: timer at 400f800c {
+		compatible = "moschip,mcs814x-timer";
+		interrupts = <0>;
+		reg = <0x400f800c 0x8>;
+	};
+
diff --git a/Documentation/devicetree/bindings/arm/mcs814x/mcs814x.txt b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x.txt
new file mode 100644
index 0000000..503c234
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x.txt
@@ -0,0 +1,13 @@
+MMoschip MCS814x SoC bindings
+
+-----------------------------
+
+Boards including a Moschip MCS814x SoC should include the following properties
+
+Required root node property:
+- compatible: must contain "moschip,mcs814x"
+
+Boards including a Moschip MCS8140 should also include the following property.
+
+Required root node property:
+- compatible: must contain "moschip,mcs8140"
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 6eab917..943e4f3 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -28,6 +28,7 @@ linux	Linux-specific binding
 marvell	Marvell Technology Group Ltd.
 maxim	Maxim Integrated Products
 mosaixtech	Mosaix Technologies, Inc.
+moschp		Moschip Semiconductors
 national	National Semiconductor
 nintendo	Nintendo
 nvidia	NVIDIA
-- 
1.7.10.4

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

* [PATCH 4/8] ARM: MCS814X: add DTS file for Tigal/Robotech RBT-832
  2012-07-15 14:49 ` Florian Fainelli
@ 2012-07-15 14:49   ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: olof, devicetree-discuss, Florian Fainelli, arnd

This DTS files defines the following specifities:
- 32MB of RAM
- 5 GPIO controlled LEDs
- LED activity for the Ethernet port
- MTD partitions

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 arch/arm/boot/dts/rbt-832.dts            |   83 ++++++++++++++++++++++++++++++
 arch/arm/mach-mcs814x/Kconfig            |    9 ++++
 arch/arm/mach-mcs814x/Makefile.boot      |    2 +
 arch/arm/mach-mcs814x/board-mcs8140-dt.c |    1 +
 4 files changed, 95 insertions(+)
 create mode 100644 arch/arm/boot/dts/rbt-832.dts

diff --git a/arch/arm/boot/dts/rbt-832.dts b/arch/arm/boot/dts/rbt-832.dts
new file mode 100644
index 0000000..cc7fab8
--- /dev/null
+++ b/arch/arm/boot/dts/rbt-832.dts
@@ -0,0 +1,83 @@
+/*
+ * rbt-832.dts - Device Tree file for Tigal RBT-832
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under GPLv2
+ */
+
+/dts-v1/;
+/include/ "mcs8140.dtsi"
+
+/ {
+	model = "Tigal RBT-832";
+	compatible = "tigal,rbt-832", "moschip,mcs8140", "moschip,mcs814x";
+
+	chosen {
+		bootargs = "mem=32M console=ttyS0,115200 earlyprintk";
+	};
+
+	ahb {
+		vci {
+			eth0: ethernet@40084000 {
+				nuport-mac,link-activity = <0x01>;
+			};
+
+			adc {
+				sdram: memory@0,0 {
+					reg = <0 0 0x2000000>;
+				};
+
+				nor: flash@7,0 {
+
+					partition@0 {
+						label = "ArmBoot";
+						reg = <0 0x40000>;
+					};
+					partition@30000 {
+						label = "Enviroment";
+						reg = <0x40000 0x20000>;
+					};
+					partition@50000 {
+						label = "bZimage";
+						reg = <0x60000 0x1a0000>;
+					};
+					partition@150000 {
+						label = "UserFS";
+						reg = <0x200000 0x600000>;
+					};
+				};
+			};
+
+			leds {
+				compatible = "gpio-leds";
+
+				ethernet {
+					label = "rbt-832:red:ethernet";
+					gpios = <&gpio 0 0>;	// gpio 0 active high
+				};
+
+				usb0 {
+					label = "rbt-832:red:usb0";
+					gpios = <&gpio 4 0>;	// gpio 4 active high
+				};
+
+				usb1 {
+					label = "rbt-832:red:usb1";
+					gpios = <&gpio 3 0>;	// gpio 3 active high
+				};
+
+				usb2 {
+					label = "rbt-832:red:usb2";
+					gpios = <&gpio 2 0>;	// gpio 2 active high
+				};
+
+				usb3 {
+					label = "rbt-832:red:usb3";
+					gpios = <&gpio 1 0>;	// gpio 1 active high
+				};
+			};
+		};
+	};
+};
+
diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
index c89422f..604537b 100644
--- a/arch/arm/mach-mcs814x/Kconfig
+++ b/arch/arm/mach-mcs814x/Kconfig
@@ -6,6 +6,15 @@ config MCS8140
 
 menu "Moschip MCS8140 boards"
 
+config MACH_RBT_832
+	bool "Tigal RBT-832"
+	select MCS8140
+	select NEW_LEDS
+	select LEDS_CLASS
+	select LEDS_GPIO
+	help
+	  Machine support for the Tigal RBT-832 board
+
 endmenu
 
 endif
diff --git a/arch/arm/mach-mcs814x/Makefile.boot b/arch/arm/mach-mcs814x/Makefile.boot
index 414db8b..3153a7c 100644
--- a/arch/arm/mach-mcs814x/Makefile.boot
+++ b/arch/arm/mach-mcs814x/Makefile.boot
@@ -1,3 +1,5 @@
     zreladdr-y := 0x00008000
  params_phys-y := 0x00000008
  initrd_phys-y := 0x00400000
+
+dtb-$(CONFIG_MACH_RBT_832) += rbt-832.dtb
diff --git a/arch/arm/mach-mcs814x/board-mcs8140-dt.c b/arch/arm/mach-mcs814x/board-mcs8140-dt.c
index 5d13283..6f0804d 100644
--- a/arch/arm/mach-mcs814x/board-mcs8140-dt.c
+++ b/arch/arm/mach-mcs814x/board-mcs8140-dt.c
@@ -27,6 +27,7 @@ static void __init mcs814x_dt_device_init(void)
 }
 
 static const char *mcs8140_dt_board_compat[] __initdata = {
+	"tigal,rbt-832",
 	"moschip,mcs8140",
 	NULL,	/* sentinel */
 };
-- 
1.7.10.4

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

* [PATCH 4/8] ARM: MCS814X: add DTS file for Tigal/Robotech RBT-832
@ 2012-07-15 14:49   ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

This DTS files defines the following specifities:
- 32MB of RAM
- 5 GPIO controlled LEDs
- LED activity for the Ethernet port
- MTD partitions

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 arch/arm/boot/dts/rbt-832.dts            |   83 ++++++++++++++++++++++++++++++
 arch/arm/mach-mcs814x/Kconfig            |    9 ++++
 arch/arm/mach-mcs814x/Makefile.boot      |    2 +
 arch/arm/mach-mcs814x/board-mcs8140-dt.c |    1 +
 4 files changed, 95 insertions(+)
 create mode 100644 arch/arm/boot/dts/rbt-832.dts

diff --git a/arch/arm/boot/dts/rbt-832.dts b/arch/arm/boot/dts/rbt-832.dts
new file mode 100644
index 0000000..cc7fab8
--- /dev/null
+++ b/arch/arm/boot/dts/rbt-832.dts
@@ -0,0 +1,83 @@
+/*
+ * rbt-832.dts - Device Tree file for Tigal RBT-832
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under GPLv2
+ */
+
+/dts-v1/;
+/include/ "mcs8140.dtsi"
+
+/ {
+	model = "Tigal RBT-832";
+	compatible = "tigal,rbt-832", "moschip,mcs8140", "moschip,mcs814x";
+
+	chosen {
+		bootargs = "mem=32M console=ttyS0,115200 earlyprintk";
+	};
+
+	ahb {
+		vci {
+			eth0: ethernet at 40084000 {
+				nuport-mac,link-activity = <0x01>;
+			};
+
+			adc {
+				sdram: memory at 0,0 {
+					reg = <0 0 0x2000000>;
+				};
+
+				nor: flash at 7,0 {
+
+					partition at 0 {
+						label = "ArmBoot";
+						reg = <0 0x40000>;
+					};
+					partition at 30000 {
+						label = "Enviroment";
+						reg = <0x40000 0x20000>;
+					};
+					partition at 50000 {
+						label = "bZimage";
+						reg = <0x60000 0x1a0000>;
+					};
+					partition at 150000 {
+						label = "UserFS";
+						reg = <0x200000 0x600000>;
+					};
+				};
+			};
+
+			leds {
+				compatible = "gpio-leds";
+
+				ethernet {
+					label = "rbt-832:red:ethernet";
+					gpios = <&gpio 0 0>;	// gpio 0 active high
+				};
+
+				usb0 {
+					label = "rbt-832:red:usb0";
+					gpios = <&gpio 4 0>;	// gpio 4 active high
+				};
+
+				usb1 {
+					label = "rbt-832:red:usb1";
+					gpios = <&gpio 3 0>;	// gpio 3 active high
+				};
+
+				usb2 {
+					label = "rbt-832:red:usb2";
+					gpios = <&gpio 2 0>;	// gpio 2 active high
+				};
+
+				usb3 {
+					label = "rbt-832:red:usb3";
+					gpios = <&gpio 1 0>;	// gpio 1 active high
+				};
+			};
+		};
+	};
+};
+
diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
index c89422f..604537b 100644
--- a/arch/arm/mach-mcs814x/Kconfig
+++ b/arch/arm/mach-mcs814x/Kconfig
@@ -6,6 +6,15 @@ config MCS8140
 
 menu "Moschip MCS8140 boards"
 
+config MACH_RBT_832
+	bool "Tigal RBT-832"
+	select MCS8140
+	select NEW_LEDS
+	select LEDS_CLASS
+	select LEDS_GPIO
+	help
+	  Machine support for the Tigal RBT-832 board
+
 endmenu
 
 endif
diff --git a/arch/arm/mach-mcs814x/Makefile.boot b/arch/arm/mach-mcs814x/Makefile.boot
index 414db8b..3153a7c 100644
--- a/arch/arm/mach-mcs814x/Makefile.boot
+++ b/arch/arm/mach-mcs814x/Makefile.boot
@@ -1,3 +1,5 @@
     zreladdr-y := 0x00008000
  params_phys-y := 0x00000008
  initrd_phys-y := 0x00400000
+
+dtb-$(CONFIG_MACH_RBT_832) += rbt-832.dtb
diff --git a/arch/arm/mach-mcs814x/board-mcs8140-dt.c b/arch/arm/mach-mcs814x/board-mcs8140-dt.c
index 5d13283..6f0804d 100644
--- a/arch/arm/mach-mcs814x/board-mcs8140-dt.c
+++ b/arch/arm/mach-mcs814x/board-mcs8140-dt.c
@@ -27,6 +27,7 @@ static void __init mcs814x_dt_device_init(void)
 }
 
 static const char *mcs8140_dt_board_compat[] __initdata = {
+	"tigal,rbt-832",
 	"moschip,mcs8140",
 	NULL,	/* sentinel */
 };
-- 
1.7.10.4

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

* [PATCH 5/8] ARM: MCS814x: add DTS file for Devolo dLAN USB Extender
  2012-07-15 14:49 ` Florian Fainelli
@ 2012-07-15 14:49   ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: olof, devicetree-discuss, Florian Fainelli, arnd

This patch adds support for Devolo's dLAN USB Extender board:
- 16MB of SDRAM available
- GPIO for the USB port activity
- MTD partition map

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 arch/arm/boot/dts/dlan-usb-extender.dts  |   68 ++++++++++++++++++++++++++++++
 arch/arm/mach-mcs814x/Kconfig            |    9 ++++
 arch/arm/mach-mcs814x/Makefile.boot      |    1 +
 arch/arm/mach-mcs814x/board-mcs8140-dt.c |    1 +
 4 files changed, 79 insertions(+)
 create mode 100644 arch/arm/boot/dts/dlan-usb-extender.dts

diff --git a/arch/arm/boot/dts/dlan-usb-extender.dts b/arch/arm/boot/dts/dlan-usb-extender.dts
new file mode 100644
index 0000000..4adfaa3
--- /dev/null
+++ b/arch/arm/boot/dts/dlan-usb-extender.dts
@@ -0,0 +1,68 @@
+/*
+ * dlan-usb-extender.dts - Device Tree file for Devolo dLAN USB Extender
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under GPLv2
+ */
+
+/dts-v1/;
+/include/ "mcs8140.dtsi"
+
+/ {
+	model = "Devolo dLAN USB Extender";
+	compatible = "devolo,dlan-usb-extender", "moschip,mcs8140", "moschip,mcs814x";
+
+	chosen {
+		bootargs = "mem=16M console=ttyS0,57600 earlyprintk";
+	};
+
+	ahb {
+		vci {
+
+			adc {
+				sdram: memory@0,0 {
+					reg = <0 0 0x1000000>;
+				};
+
+				nor: flash@7,0 {
+
+					partition@0 {
+						label = "ArmBoot";
+						reg = <0 0x30000>;
+					};
+					partition@30000 {
+						label = "Config1";
+						reg = <0x30000 0x10000>;
+					};
+					partition@40000 {
+						label = "Config2";
+						reg = <0x40000 0x10000>;
+					};
+					partition@50000 {
+						label = "bZimage";
+						reg = <0x50000 0x100000>;
+					};
+					partition@150000 {
+						label = "UserFS";
+						reg = <0x150000 0x3C0000>;
+					};
+					partition@50001 {
+						label = "Combined";
+						reg = <0x50000 0x4C0000>;
+					};
+				};
+			};
+
+			leds {
+				compatible = "gpio-leds";
+
+				usb {
+					label = "dlan-usb-extender:green:usb";
+					gpios = <&gpio 19 0>;	// gpio 19 active high
+				};
+			};
+		};
+	};
+};
+
diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
index 604537b..aa312d1 100644
--- a/arch/arm/mach-mcs814x/Kconfig
+++ b/arch/arm/mach-mcs814x/Kconfig
@@ -6,6 +6,15 @@ config MCS8140
 
 menu "Moschip MCS8140 boards"
 
+config MACH_DLAN_USB_EXT
+	bool "Devolo dLAN USB Extender"
+	select MCS8140
+	select NEW_LEDS
+	select LEDS_CLASS
+	select LEDS_GPIO
+	help
+	  Machine support for the Devolo dLAN USB Extender
+
 config MACH_RBT_832
 	bool "Tigal RBT-832"
 	select MCS8140
diff --git a/arch/arm/mach-mcs814x/Makefile.boot b/arch/arm/mach-mcs814x/Makefile.boot
index 3153a7c..60dfcf6 100644
--- a/arch/arm/mach-mcs814x/Makefile.boot
+++ b/arch/arm/mach-mcs814x/Makefile.boot
@@ -2,4 +2,5 @@
  params_phys-y := 0x00000008
  initrd_phys-y := 0x00400000
 
+dtb-$(CONFIG_MACH_DLAN_USB_EXT) += dlan-usb-extender.dtb
 dtb-$(CONFIG_MACH_RBT_832) += rbt-832.dtb
diff --git a/arch/arm/mach-mcs814x/board-mcs8140-dt.c b/arch/arm/mach-mcs814x/board-mcs8140-dt.c
index 6f0804d..766166b 100644
--- a/arch/arm/mach-mcs814x/board-mcs8140-dt.c
+++ b/arch/arm/mach-mcs814x/board-mcs8140-dt.c
@@ -27,6 +27,7 @@ static void __init mcs814x_dt_device_init(void)
 }
 
 static const char *mcs8140_dt_board_compat[] __initdata = {
+	"devolo,dlan-usb-extender",
 	"tigal,rbt-832",
 	"moschip,mcs8140",
 	NULL,	/* sentinel */
-- 
1.7.10.4

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

* [PATCH 5/8] ARM: MCS814x: add DTS file for Devolo dLAN USB Extender
@ 2012-07-15 14:49   ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support for Devolo's dLAN USB Extender board:
- 16MB of SDRAM available
- GPIO for the USB port activity
- MTD partition map

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 arch/arm/boot/dts/dlan-usb-extender.dts  |   68 ++++++++++++++++++++++++++++++
 arch/arm/mach-mcs814x/Kconfig            |    9 ++++
 arch/arm/mach-mcs814x/Makefile.boot      |    1 +
 arch/arm/mach-mcs814x/board-mcs8140-dt.c |    1 +
 4 files changed, 79 insertions(+)
 create mode 100644 arch/arm/boot/dts/dlan-usb-extender.dts

diff --git a/arch/arm/boot/dts/dlan-usb-extender.dts b/arch/arm/boot/dts/dlan-usb-extender.dts
new file mode 100644
index 0000000..4adfaa3
--- /dev/null
+++ b/arch/arm/boot/dts/dlan-usb-extender.dts
@@ -0,0 +1,68 @@
+/*
+ * dlan-usb-extender.dts - Device Tree file for Devolo dLAN USB Extender
+ *
+ * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
+ *
+ * Licensed under GPLv2
+ */
+
+/dts-v1/;
+/include/ "mcs8140.dtsi"
+
+/ {
+	model = "Devolo dLAN USB Extender";
+	compatible = "devolo,dlan-usb-extender", "moschip,mcs8140", "moschip,mcs814x";
+
+	chosen {
+		bootargs = "mem=16M console=ttyS0,57600 earlyprintk";
+	};
+
+	ahb {
+		vci {
+
+			adc {
+				sdram: memory at 0,0 {
+					reg = <0 0 0x1000000>;
+				};
+
+				nor: flash at 7,0 {
+
+					partition at 0 {
+						label = "ArmBoot";
+						reg = <0 0x30000>;
+					};
+					partition at 30000 {
+						label = "Config1";
+						reg = <0x30000 0x10000>;
+					};
+					partition at 40000 {
+						label = "Config2";
+						reg = <0x40000 0x10000>;
+					};
+					partition at 50000 {
+						label = "bZimage";
+						reg = <0x50000 0x100000>;
+					};
+					partition at 150000 {
+						label = "UserFS";
+						reg = <0x150000 0x3C0000>;
+					};
+					partition at 50001 {
+						label = "Combined";
+						reg = <0x50000 0x4C0000>;
+					};
+				};
+			};
+
+			leds {
+				compatible = "gpio-leds";
+
+				usb {
+					label = "dlan-usb-extender:green:usb";
+					gpios = <&gpio 19 0>;	// gpio 19 active high
+				};
+			};
+		};
+	};
+};
+
diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
index 604537b..aa312d1 100644
--- a/arch/arm/mach-mcs814x/Kconfig
+++ b/arch/arm/mach-mcs814x/Kconfig
@@ -6,6 +6,15 @@ config MCS8140
 
 menu "Moschip MCS8140 boards"
 
+config MACH_DLAN_USB_EXT
+	bool "Devolo dLAN USB Extender"
+	select MCS8140
+	select NEW_LEDS
+	select LEDS_CLASS
+	select LEDS_GPIO
+	help
+	  Machine support for the Devolo dLAN USB Extender
+
 config MACH_RBT_832
 	bool "Tigal RBT-832"
 	select MCS8140
diff --git a/arch/arm/mach-mcs814x/Makefile.boot b/arch/arm/mach-mcs814x/Makefile.boot
index 3153a7c..60dfcf6 100644
--- a/arch/arm/mach-mcs814x/Makefile.boot
+++ b/arch/arm/mach-mcs814x/Makefile.boot
@@ -2,4 +2,5 @@
  params_phys-y := 0x00000008
  initrd_phys-y := 0x00400000
 
+dtb-$(CONFIG_MACH_DLAN_USB_EXT) += dlan-usb-extender.dtb
 dtb-$(CONFIG_MACH_RBT_832) += rbt-832.dtb
diff --git a/arch/arm/mach-mcs814x/board-mcs8140-dt.c b/arch/arm/mach-mcs814x/board-mcs8140-dt.c
index 6f0804d..766166b 100644
--- a/arch/arm/mach-mcs814x/board-mcs8140-dt.c
+++ b/arch/arm/mach-mcs814x/board-mcs8140-dt.c
@@ -27,6 +27,7 @@ static void __init mcs814x_dt_device_init(void)
 }
 
 static const char *mcs8140_dt_board_compat[] __initdata = {
+	"devolo,dlan-usb-extender",
 	"tigal,rbt-832",
 	"moschip,mcs8140",
 	NULL,	/* sentinel */
-- 
1.7.10.4

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

* [PATCH 6/8] ARM: MCS814x: provide a sample defconfig file
  2012-07-15 14:49 ` Florian Fainelli
@ 2012-07-15 14:49   ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: olof, devicetree-discuss, Florian Fainelli, arnd

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 arch/arm/configs/mcs814x_defconfig |  174 ++++++++++++++++++++++++++++++++++++
 1 file changed, 174 insertions(+)
 create mode 100644 arch/arm/configs/mcs814x_defconfig

diff --git a/arch/arm/configs/mcs814x_defconfig b/arch/arm/configs/mcs814x_defconfig
new file mode 100644
index 0000000..7fa3dd6
--- /dev/null
+++ b/arch/arm/configs/mcs814x_defconfig
@@ -0,0 +1,174 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MCS814X=y
+CONFIG_MACH_DLAN_USB_EXT=y
+CONFIG_MACH_RBT_832=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PCI_DEBUG=y
+CONFIG_AEABI=y
+CONFIG_USE_OF=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_CMDLINE="earlyprintk"
+CONFIG_CMDLINE_EXTEND=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_MISC=y
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_TCP_CONG_WESTWOOD is not set
+CONFIG_TCP_CONG_HTCP=y
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_BLK_DEV is not set
+CONFIG_SCSI=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_HP is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+CONFIG_PHYLIB=y
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_HW_RANDOM=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+# CONFIG_VGA_ARB is not set
+CONFIG_USB=m
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_STORAGE=m
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_STAGING=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT4_FS=m
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_VFAT_FS=m
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_XATTR=y
+# CONFIG_JFFS2_FS_POSIX_ACL is not set
+# CONFIG_JFFS2_FS_SECURITY is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_ZLIB is not set
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-15"
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_PRINTK_TIME=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_ITU_T=y
+CONFIG_LIBCRC32C=y
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+# CONFIG_XZ_DEC_ARM is not set
+# CONFIG_XZ_DEC_ARMTHUMB is not set
+# CONFIG_XZ_DEC_SPARC is not set
-- 
1.7.10.4

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

* [PATCH 6/8] ARM: MCS814x: provide a sample defconfig file
@ 2012-07-15 14:49   ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 arch/arm/configs/mcs814x_defconfig |  174 ++++++++++++++++++++++++++++++++++++
 1 file changed, 174 insertions(+)
 create mode 100644 arch/arm/configs/mcs814x_defconfig

diff --git a/arch/arm/configs/mcs814x_defconfig b/arch/arm/configs/mcs814x_defconfig
new file mode 100644
index 0000000..7fa3dd6
--- /dev/null
+++ b/arch/arm/configs/mcs814x_defconfig
@@ -0,0 +1,174 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MCS814X=y
+CONFIG_MACH_DLAN_USB_EXT=y
+CONFIG_MACH_RBT_832=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PCI_DEBUG=y
+CONFIG_AEABI=y
+CONFIG_USE_OF=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_CMDLINE="earlyprintk"
+CONFIG_CMDLINE_EXTEND=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_MISC=y
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_TCP_CONG_WESTWOOD is not set
+CONFIG_TCP_CONG_HTCP=y
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_BLK_DEV is not set
+CONFIG_SCSI=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_HP is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+CONFIG_PHYLIB=y
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_HW_RANDOM=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+# CONFIG_VGA_ARB is not set
+CONFIG_USB=m
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_STORAGE=m
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_STAGING=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT4_FS=m
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_VFAT_FS=m
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_XATTR=y
+# CONFIG_JFFS2_FS_POSIX_ACL is not set
+# CONFIG_JFFS2_FS_SECURITY is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_ZLIB is not set
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-15"
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_PRINTK_TIME=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_ITU_T=y
+CONFIG_LIBCRC32C=y
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+# CONFIG_XZ_DEC_ARM is not set
+# CONFIG_XZ_DEC_ARMTHUMB is not set
+# CONFIG_XZ_DEC_SPARC is not set
-- 
1.7.10.4

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

* [PATCH 7/8] ARM: MSC814X: add Kconfig and Makefile to arch/arm
  2012-07-15 14:49 ` Florian Fainelli
@ 2012-07-15 14:49   ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: olof, devicetree-discuss, Florian Fainelli, arnd

This patch makes arch/arm/{Kconfig,Makefile} reference the MCS814x
machine code that we can now select and build it.

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 arch/arm/Kconfig  |   15 +++++++++++++++
 arch/arm/Makefile |    1 +
 2 files changed, 16 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 84449dd..ec7e340 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -618,6 +618,19 @@ config ARCH_KS8695
 	  Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
 	  System-on-Chip devices.
 
+config ARCH_MCS814X
+	bool "Moschip MCS814x"
+	select PCI
+	select FIQ
+	select GENERIC_IRQ_CHIP
+	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
+	select CLKDEV_LOOKUP
+	select ARCH_USES_GETTIMEOFFSET
+	select NEED_MACH_MEMORY_H
+	help
+	  Support for Moschip MCS814x SoCs (MCS8140 currently).
+
 config ARCH_W90X900
 	bool "Nuvoton W90X900 CPU"
 	select CPU_ARM926T
@@ -1054,6 +1067,8 @@ source "arch/arm/mach-sa1100/Kconfig"
 source "arch/arm/plat-samsung/Kconfig"
 source "arch/arm/plat-s3c24xx/Kconfig"
 
+source "arch/arm/mach-mcs814x/Kconfig"
+
 source "arch/arm/plat-spear/Kconfig"
 
 source "arch/arm/mach-s3c24xx/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 0298b00..1d9f377 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -151,6 +151,7 @@ machine-$(CONFIG_ARCH_IXP4XX)		:= ixp4xx
 machine-$(CONFIG_ARCH_KIRKWOOD)		:= kirkwood
 machine-$(CONFIG_ARCH_KS8695)		:= ks8695
 machine-$(CONFIG_ARCH_LPC32XX)		:= lpc32xx
+machine-$(CONFIG_ARCH_MCS814X)		:= mcs814x
 machine-$(CONFIG_ARCH_MMP)		:= mmp
 machine-$(CONFIG_ARCH_MSM)		:= msm
 machine-$(CONFIG_ARCH_MV78XX0)		:= mv78xx0
-- 
1.7.10.4

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

* [PATCH 7/8] ARM: MSC814X: add Kconfig and Makefile to arch/arm
@ 2012-07-15 14:49   ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

This patch makes arch/arm/{Kconfig,Makefile} reference the MCS814x
machine code that we can now select and build it.

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 arch/arm/Kconfig  |   15 +++++++++++++++
 arch/arm/Makefile |    1 +
 2 files changed, 16 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 84449dd..ec7e340 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -618,6 +618,19 @@ config ARCH_KS8695
 	  Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
 	  System-on-Chip devices.
 
+config ARCH_MCS814X
+	bool "Moschip MCS814x"
+	select PCI
+	select FIQ
+	select GENERIC_IRQ_CHIP
+	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
+	select CLKDEV_LOOKUP
+	select ARCH_USES_GETTIMEOFFSET
+	select NEED_MACH_MEMORY_H
+	help
+	  Support for Moschip MCS814x SoCs (MCS8140 currently).
+
 config ARCH_W90X900
 	bool "Nuvoton W90X900 CPU"
 	select CPU_ARM926T
@@ -1054,6 +1067,8 @@ source "arch/arm/mach-sa1100/Kconfig"
 source "arch/arm/plat-samsung/Kconfig"
 source "arch/arm/plat-s3c24xx/Kconfig"
 
+source "arch/arm/mach-mcs814x/Kconfig"
+
 source "arch/arm/plat-spear/Kconfig"
 
 source "arch/arm/mach-s3c24xx/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 0298b00..1d9f377 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -151,6 +151,7 @@ machine-$(CONFIG_ARCH_IXP4XX)		:= ixp4xx
 machine-$(CONFIG_ARCH_KIRKWOOD)		:= kirkwood
 machine-$(CONFIG_ARCH_KS8695)		:= ks8695
 machine-$(CONFIG_ARCH_LPC32XX)		:= lpc32xx
+machine-$(CONFIG_ARCH_MCS814X)		:= mcs814x
 machine-$(CONFIG_ARCH_MMP)		:= mmp
 machine-$(CONFIG_ARCH_MSM)		:= msm
 machine-$(CONFIG_ARCH_MV78XX0)		:= mv78xx0
-- 
1.7.10.4

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

* [PATCH 8/8] ARM: MSC814x: add MAINTAINERS entry
  2012-07-15 14:49 ` Florian Fainelli
@ 2012-07-15 14:49   ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: olof, devicetree-discuss, Florian Fainelli, arnd

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 MAINTAINERS |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3e30a3a..593ca15 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -918,6 +918,12 @@ L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 F:	arch/arm/mach-pxa/mioa701.c
 S:	Maintained
 
+ARM/MOSCHIP MCS814X SUPPORT
+M:	Florian Fainelli <florian@openwrt.org>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+F:	arch/arm/mach-mcs814x
+S:	Maintained
+
 ARM/NEC MOBILEPRO 900/c MACHINE SUPPORT
 M:	Michael Petchkovsky <mkpetch@internode.on.net>
 S:	Maintained
-- 
1.7.10.4

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

* [PATCH 8/8] ARM: MSC814x: add MAINTAINERS entry
@ 2012-07-15 14:49   ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-15 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 MAINTAINERS |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3e30a3a..593ca15 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -918,6 +918,12 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 F:	arch/arm/mach-pxa/mioa701.c
 S:	Maintained
 
+ARM/MOSCHIP MCS814X SUPPORT
+M:	Florian Fainelli <florian@openwrt.org>
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+F:	arch/arm/mach-mcs814x
+S:	Maintained
+
 ARM/NEC MOBILEPRO 900/c MACHINE SUPPORT
 M:	Michael Petchkovsky <mkpetch@internode.on.net>
 S:	Maintained
-- 
1.7.10.4

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

* Re: [PATCH 0/8] ARM: support for Moschip MCS814x SoCs
  2012-07-15 14:49 ` Florian Fainelli
@ 2012-07-15 19:59     ` Arnd Bergmann
  -1 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-15 19:59 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Sunday 15 July 2012, Florian Fainelli wrote:
> This patchset adds basic support for Mocship MCS814x, and in particular
> MCS8140, and allows one booting to user space. Two off-the-shelf boards
> are support: Tigal/Robotech RBT-832 and Devolo dLAN USB Extender.
> 
> Support for other on-board peripherals will obviously be contributed later
> once the basic SoC support has been accepted.

Hi Florian,

This looks quite nice at first sight, but I have to say that your timing
is rather unfortunate. We're getting rather close to the 3.6 merge window,
so there is not much time to review the platform thoroughly before that
and I'd feel more comfortable about putting it into 3.7. I'll let others
weigh in, too. At least there is no risk of regressions for a new platform
getting added, so if other people think we should take it for 3.5, I might
get convinced.

I'll follow up with more detailed feedback on the individual patches.

	Arnd

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

* [PATCH 0/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-15 19:59     ` Arnd Bergmann
  0 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-15 19:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 15 July 2012, Florian Fainelli wrote:
> This patchset adds basic support for Mocship MCS814x, and in particular
> MCS8140, and allows one booting to user space. Two off-the-shelf boards
> are support: Tigal/Robotech RBT-832 and Devolo dLAN USB Extender.
> 
> Support for other on-board peripherals will obviously be contributed later
> once the basic SoC support has been accepted.

Hi Florian,

This looks quite nice at first sight, but I have to say that your timing
is rather unfortunate. We're getting rather close to the 3.6 merge window,
so there is not much time to review the platform thoroughly before that
and I'd feel more comfortable about putting it into 3.7. I'll let others
weigh in, too. At least there is no risk of regressions for a new platform
getting added, so if other people think we should take it for 3.5, I might
get convinced.

I'll follow up with more detailed feedback on the individual patches.

	Arnd

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

* Re: [PATCH 0/8] ARM: support for Moschip MCS814x SoCs
  2012-07-15 19:59     ` Arnd Bergmann
@ 2012-07-16  8:16       ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-16  8:16 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: olof, devicetree-discuss, Arnd Bergmann

Hello Arnd,

On Sunday 15 July 2012 19:59:19 Arnd Bergmann wrote:
> On Sunday 15 July 2012, Florian Fainelli wrote:
> > This patchset adds basic support for Mocship MCS814x, and in particular
> > MCS8140, and allows one booting to user space. Two off-the-shelf boards
> > are support: Tigal/Robotech RBT-832 and Devolo dLAN USB Extender.
> > 
> > Support for other on-board peripherals will obviously be contributed later
> > once the basic SoC support has been accepted.
> 
> Hi Florian,
> 
> This looks quite nice at first sight, but I have to say that your timing
> is rather unfortunate. We're getting rather close to the 3.6 merge window,
> so there is not much time to review the platform thoroughly before that
> and I'd feel more comfortable about putting it into 3.7. I'll let others
> weigh in, too. At least there is no risk of regressions for a new platform
> getting added, so if other people think we should take it for 3.5, I might
> get convinced.

I am not in a hurry getting this merged during the 3.6 merge window, so this 
really is not a big deal for me, I just wanted this out so that people can 
comment on it.

> 
> I'll follow up with more detailed feedback on the individual patches.

Thank you!
--
Florian

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

* [PATCH 0/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-16  8:16       ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-16  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Arnd,

On Sunday 15 July 2012 19:59:19 Arnd Bergmann wrote:
> On Sunday 15 July 2012, Florian Fainelli wrote:
> > This patchset adds basic support for Mocship MCS814x, and in particular
> > MCS8140, and allows one booting to user space. Two off-the-shelf boards
> > are support: Tigal/Robotech RBT-832 and Devolo dLAN USB Extender.
> > 
> > Support for other on-board peripherals will obviously be contributed later
> > once the basic SoC support has been accepted.
> 
> Hi Florian,
> 
> This looks quite nice at first sight, but I have to say that your timing
> is rather unfortunate. We're getting rather close to the 3.6 merge window,
> so there is not much time to review the platform thoroughly before that
> and I'd feel more comfortable about putting it into 3.7. I'll let others
> weigh in, too. At least there is no risk of regressions for a new platform
> getting added, so if other people think we should take it for 3.5, I might
> get convinced.

I am not in a hurry getting this merged during the 3.6 merge window, so this 
really is not a big deal for me, I just wanted this out so that people can 
comment on it.

> 
> I'll follow up with more detailed feedback on the individual patches.

Thank you!
--
Florian

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-15 14:49   ` Florian Fainelli
@ 2012-07-16 12:29     ` Thomas Petazzoni
  -1 siblings, 0 replies; 80+ messages in thread
From: Thomas Petazzoni @ 2012-07-16 12:29 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: olof, devicetree-discuss, arnd, linux-arm-kernel

Hello Florian,

Le Sun, 15 Jul 2012 16:49:07 +0200,
Florian Fainelli <florian@openwrt.org> a écrit :

> diff --git a/arch/arm/mach-mcs814x/Makefile.boot b/arch/arm/mach-mcs814x/Makefile.boot
> new file mode 100644
> index 0000000..414db8b
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/Makefile.boot
> @@ -0,0 +1,3 @@
> +    zreladdr-y := 0x00008000
> + params_phys-y := 0x00000008
> + initrd_phys-y := 0x00400000

params_phys-y and initrd_phys-y are useless for DT-based platforms, if
I'm correct.

> diff --git a/arch/arm/mach-mcs814x/clock.c b/arch/arm/mach-mcs814x/clock.c
> new file mode 100644
> index 0000000..eb30ae2
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/clock.c
> @@ -0,0 +1,271 @@
> +/*
> + * Moschip MCS814x clock routines
> + *
> + * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
> + *
> + * Licensed under GPLv2
> + */
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/export.h>
> +#include <linux/spinlock.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk.h>
> +
> +#include <mach/mcs814x.h>
> +
> +#include "common.h"
> +
> +#define KHZ	1000
> +#define MHZ	(KHZ * KHZ)
> +
> +struct clk_ops {
> +	unsigned long (*get_rate)(struct clk *clk);
> +	int (*set_rate)(struct clk *clk, unsigned long rate);
> +	struct clk *(*get_parent)(struct clk *clk);
> +	int (*enable)(struct clk *clk, int enable);
> +};
> +
> +struct clk {
> +	struct clk *parent;		/* parent clk */
> +	unsigned long rate;		/* clock rate in Hz */
> +	unsigned long divider;		/* clock divider */
> +	u32 usecount;			/* reference count */
> +	struct clk_ops *ops;		/* clock operation */
> +	u32 enable_reg;			/* clock enable register */
> +	u32 enable_mask;		/* clock enable mask */
> +};
> +
> +static unsigned long clk_divide_parent(struct clk *clk)
> +{
> +	if (clk->parent && clk->divider)
> +		return clk_get_rate(clk->parent) / clk->divider;
> +	else
> +		return 0;
> +}
> +
> +static int clk_local_onoff_enable(struct clk *clk, int enable)
> +{
> +	u32 tmp;
> +
> +	/* no enable_reg means the clock is always enabled */
> +	if (!clk->enable_reg)
> +		return 0;
> +
> +	tmp = __raw_readl(mcs814x_sysdbg_base + clk->enable_reg);
> +	if (!enable)
> +		tmp &= ~clk->enable_mask;
> +	else
> +		tmp |= clk->enable_mask;
> +
> +	__raw_writel(tmp, mcs814x_sysdbg_base + clk->enable_reg);
> +
> +	return 0;
> +}
> +
> +static struct clk_ops default_clk_ops = {
> +	.get_rate	= clk_divide_parent,
> +	.enable		= clk_local_onoff_enable,
> +};
> +
> +static DEFINE_SPINLOCK(clocks_lock);
> +
> +static const unsigned long cpu_freq_table[] = {
> +	175000,
> +	300000,
> +	125000,
> +	137500,
> +	212500,
> +	250000,
> +	162500,
> +	187500,
> +	162500,
> +	150000,
> +	225000,
> +	237500,
> +	200000,
> +	262500,
> +	275000,
> +	287500
> +};
> +
> +static struct clk clk_cpu;
> +
> +/* System clock is fixed at 50Mhz */
> +static struct clk clk_sys = {
> +	.rate	= 50 * MHZ,
> +};
> +
> +static struct clk clk_sdram;
> +
> +static struct clk clk_timer0 = {
> +	.parent	= &clk_sdram,
> +	.divider = 2,
> +	.ops	= &default_clk_ops,
> +};
> +
> +static struct clk clk_timer1_2 = {
> +	.parent	= &clk_sys,
> +};
> +
> +/* Watchdog clock is system clock / 128 */
> +static struct clk clk_wdt = {
> +	.parent	= &clk_sys,
> +	.divider = 128,
> +	.ops	= &default_clk_ops,
> +};
> +
> +static struct clk clk_emac = {
> +	.ops		= &default_clk_ops,
> +	.enable_reg	= SYSDBG_SYSCTL,
> +	.enable_mask	= SYSCTL_EMAC,
> +};
> +
> +static struct clk clk_ephy = {
> +	.ops		= &default_clk_ops,
> +	.enable_reg	= SYSDBG_PLL_CTL,
> +	.enable_mask	= ~SYSCTL_EPHY,	/* active low */
> +};
> +
> +static struct clk clk_cipher = {
> +	.ops		= &default_clk_ops,
> +	.enable_reg	= SYSDBG_SYSCTL,
> +	.enable_mask	= SYSCTL_CIPHER,
> +};
> +
> +#define CLK(_dev, _con, _clk)	\
> +{ .dev_id = (_dev), .con_id = (_con), .clk = (_clk) },
> +
> +static struct clk_lookup mcs814x_chip_clks[] = {
> +	CLK("cpu", NULL, &clk_cpu)
> +	CLK("sys", NULL, &clk_sys)
> +	CLK("sdram", NULL, &clk_sdram)
> +	/* 32-bits timer0 */
> +	CLK("timer0", NULL, &clk_timer0)
> +	/* 16-bits timer1 */
> +	CLK("timer1", NULL, &clk_timer1_2)
> +	/* 64-bits timer2, same as timer 1 */
> +	CLK("timer2", NULL, &clk_timer1_2)
> +	CLK(NULL, "wdt", &clk_wdt)
> +	CLK(NULL, "emac", &clk_emac)
> +	CLK(NULL, "ephy", &clk_ephy)
> +	CLK(NULL, "cipher", &clk_cipher)
> +};
> +
> +static void local_clk_disable(struct clk *clk)
> +{
> +	WARN_ON(!clk->usecount);
> +
> +	if (clk->usecount > 0) {
> +		clk->usecount--;
> +
> +		if ((clk->usecount == 0) && (clk->ops->enable))
> +			clk->ops->enable(clk, 0);
> +
> +		if (clk->parent)
> +			local_clk_disable(clk->parent);
> +	}
> +}
> +
> +static int local_clk_enable(struct clk *clk)
> +{
> +	int ret = 0;
> +
> +	if (clk->parent)
> +		ret = local_clk_enable(clk->parent);
> +
> +	if (ret)
> +		return ret;
> +
> +	if ((clk->usecount == 0) && (clk->ops->enable))
> +		ret = clk->ops->enable(clk, 1);
> +
> +	if (!ret)
> +		clk->usecount++;
> +	else if (clk->parent && clk->parent->ops->enable)
> +		local_clk_disable(clk->parent);
> +
> +	return ret;
> +}
> +
> +int clk_enable(struct clk *clk)
> +{
> +	int ret;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&clocks_lock, flags);
> +	ret = local_clk_enable(clk);
> +	spin_unlock_irqrestore(&clocks_lock, flags);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(clk_enable);
> +
> +void clk_disable(struct clk *clk)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&clocks_lock, flags);
> +	local_clk_disable(clk);
> +	spin_unlock_irqrestore(&clocks_lock, flags);
> +}
> +EXPORT_SYMBOL(clk_disable);
> +
> +unsigned long clk_get_rate(struct clk *clk)
> +{
> +	if (unlikely(IS_ERR_OR_NULL(clk)))
> +		return 0;
> +
> +	if (clk->rate)
> +		return clk->rate;
> +
> +	if (clk->ops && clk->ops->get_rate)
> +		return clk->ops->get_rate(clk);
> +
> +	return clk_get_rate(clk->parent);
> +}
> +EXPORT_SYMBOL(clk_get_rate);
> +
> +struct clk *clk_get_parent(struct clk *clk)
> +{
> +	unsigned long flags;
> +
> +	if (unlikely(IS_ERR_OR_NULL(clk)))
> +		return NULL;
> +
> +	if (!clk->ops || !clk->ops->get_parent)
> +		return clk->parent;
> +
> +	spin_lock_irqsave(&clocks_lock, flags);
> +	clk->parent = clk->ops->get_parent(clk);
> +	spin_unlock_irqrestore(&clocks_lock, flags);
> +
> +	return clk->parent;
> +}
> +EXPORT_SYMBOL(clk_get_parent);

You should rather use the new clock framework instead of providing your
own implementation of the clk_*() API. And therefore your clock driver
should be in drivers/clk/ instead.

> +struct cpu_mode {
> +	const char *name;
> +	int gpio_start;
> +	int gpio_end;
> +};
> +
> +static const struct cpu_mode cpu_modes[] = {
> +	{
> +		.name		= "I2S",
> +		.gpio_start	= 4,
> +		.gpio_end	= 8,
> +	},
> +	{
> +		.name		= "UART",
> +		.gpio_start	= 4,
> +		.gpio_end	= 9,
> +	},
> +	{
> +		.name		= "External MII",
> +		.gpio_start	= 0,
> +		.gpio_end	= 16,
> +	},
> +	{
> +		.name		= "Normal",
> +		.gpio_start	= -1,
> +		.gpio_end	= -1,
> +	},
> +};
> +
> +void __init mcs814x_init_machine(void)
> +{
> +	u32 bs2, cpu_mode;
> +	int gpio;
> +
> +	bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
> +	cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
> +
> +	pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
> +
> +	/* request the gpios since the pins are muxed for functionnality */
> +	for (gpio = cpu_modes[cpu_mode].gpio_start;
> +		gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
> +		if (gpio != -1)
> +			gpio_request(gpio, cpu_modes[cpu_mode].name);

I am not sure here, but shouldn't this be done with the pinctrl
subsystem instead?

> +void __init mcs814x_map_io(void)
> +{
> +	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
> +
> +	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
> +					MCS814X_SYSDBG_SIZE);
> +	if (!mcs814x_sysdbg_base)
> +		panic("unable to remap sysdbg base");

Any reason to have a static mapping initialized with iotable_init() and
then a dynamic mapping initialized with ioremap() ? I thought that
ioremap() wasn't ready at the ->map_io() time, and it was therefore the
reason we had static mappings.

> diff --git a/arch/arm/mach-mcs814x/include/mach/entry-macro.S b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
> new file mode 100644
> index 0000000..cbad566
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
> @@ -0,0 +1,29 @@
> +#include <mach/mcs814x.h>
> +                .macro  disable_fiq
> +                .endm
> +
> +		.macro arch_ret_to_user, tmp1, tmp2
> +		.endm
> +
> +		.macro  get_irqnr_preamble, base, tmp
> +		ldr	\base, =mcs814x_intc_base@ base virtual address of INTC
> +		ldr	\base, [\base]
> +		.endm
> +
> +		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
> +		mov	\tmp, #MCS814X_IRQ_STS0	 @ load tmp with STS0 register offset
> +		ldr	\irqstat, [\base, \tmp]	 @ load value at base + tmp
> +		tst	\irqstat, \irqstat       @ test if no active IRQ's
> +		beq	1002f                    @ if no active irqs return with status 0
> +		mov	\irqnr, #0               @ start from irq zero
> +		mov	\tmp,   #1               @ the mask initially 1
> +1001:
> +		tst     \irqstat, \tmp           @ and with mask
> +		addeq   \irqnr, \irqnr, #1       @ if  zero then add one to nr
> +		moveq   \tmp,   \tmp, lsl #1     @ shift mask one to left
> +		beq     1001b                    @ if  zero then loop again
> +		mov     \irqstat, \tmp           @ save the return mask
> +		mov	\tmp, #MCS814X_IRQ_STS0  @ load tmp with ICR offset
> +		str     \irqstat,  [\base, \tmp] @ clear irq with selected mask
> +1002:
> +                .endm

Hum, you should instead use the MULTI_IRQ_HANDLER feature so that this
can be written in C.

> diff --git a/arch/arm/mach-mcs814x/include/mach/hardware.h b/arch/arm/mach-mcs814x/include/mach/hardware.h
> new file mode 100644
> index 0000000..529f648
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/hardware.h
> @@ -0,0 +1,16 @@
> +/*
> + * Copyright (C) 2003 Artec Design Ltd.
> + *
> + * 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 __ASM_ARCH_HARDWARE_H
> +#define __ASM_ARCH_HARDWARE_H

This #define name no longer looks consistent with where the file is
located.

> +#include "mcs814x.h"
> +
> +#endif
> +
> diff --git a/arch/arm/mach-mcs814x/include/mach/irqs.h b/arch/arm/mach-mcs814x/include/mach/irqs.h
> new file mode 100644
> index 0000000..78021d1
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/irqs.h
> @@ -0,0 +1,22 @@
> +/*
> + * Copyright (C) 2003 Artec Design Ltd.
> + *
> + * 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 __ASM_ARCH_IRQS_H
> +#define __ASM_ARCH_IRQS_H
> +
> +#define FIQ_START	0
> +
> +#define NR_IRQS		32

I think this shouldn't be needed if you use SPARSE_IRQ support.

> +#define IRQ_PCI_INTA            22
> +#define IRQ_PCI_INTB            23
> +#define IRQ_PCI_INTC            24
> +#define IRQ_PCI_INTD            26

And these probably belong to the DT somehow?

> diff --git a/arch/arm/mach-mcs814x/timer.c b/arch/arm/mach-mcs814x/timer.c
> new file mode 100644
> index 0000000..e8408e4
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/timer.c
> @@ -0,0 +1,133 @@
> +/*
> + * Moschip MCS814x timer routines
> + *
> + * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
> + *
> + * Licensed under GPLv2
> + */
> +#include <linux/kernel.h>
> +#include <linux/interrupt.h>
> +#include <linux/time.h>
> +#include <linux/timex.h>
> +#include <linux/irq.h>
> +#include <linux/err.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +
> +#include <asm/mach/time.h>
> +#include <mach/mcs814x.h>
> +
> +/* Timer block registers */
> +#define TIMER_VAL	0x00
> +#define TIMER_CTL	0x04
> +
> +static u32 last_reload;
> +static u32 timer_correct;
> +static u32 clock_rate;
> +static u32 timer_reload_value;
> +static void __iomem *mcs814x_timer_base;
> +
> +static inline unsigned long ticks2usecs(u32 x)
> +{
> +	return x / (clock_rate / 1000000);
> +}
> +
> +/*
> + * Returns number of ms since last clock interrupt.  Note that interrupts
> + * will have been disabled by do_gettimeoffset()
> + */
> +static unsigned long mcs814x_gettimeoffset(void)
> +{
> +	u32 ticks = __raw_readl(mcs814x_timer_base + TIMER_VAL);
> +
> +	if (ticks < last_reload)
> +		return ticks2usecs(ticks + (u32)(0xffffffff - last_reload));
> +	else
> +		return ticks2usecs(ticks - last_reload);
> +}
> +
> +
> +static irqreturn_t mcs814x_timer_interrupt(int irq, void *dev_id)
> +{
> +	u32 count = __raw_readl(mcs814x_timer_base + TIMER_VAL);
> +
> +	/* take into account delay up to this moment */
> +	last_reload = count + timer_correct + timer_reload_value;
> +
> +	if (last_reload < timer_reload_value)
> +		last_reload = timer_reload_value;
> +	else if (timer_correct == 0)
> +		timer_correct = __raw_readl(mcs814x_timer_base + TIMER_VAL) -
> +					count;
> +
> +	__raw_writel(last_reload, mcs814x_timer_base + TIMER_VAL);
> +
> +	timer_tick();
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static struct irqaction mcs814x_timer_irq = {
> +	.name		= "mcs814x-timer",
> +	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
> +	.handler	= mcs814x_timer_interrupt,
> +};
> +
> +static struct of_device_id mcs814x_timer_ids[] = {
> +	{ .compatible = "moschip,mcs814x-timer" },
> +	{ /* sentinel */ },
> +};
> +
> +static void __init mcs814x_of_timer_init(void)
> +{
> +	struct device_node *np;
> +	const unsigned int *intspec;
> +
> +	np = of_find_matching_node(NULL, mcs814x_timer_ids);
> +	if (!np)
> +		panic("unable to find compatible timer node in dtb");
> +
> +	mcs814x_timer_base = of_iomap(np, 0);
> +	if (!mcs814x_timer_base)
> +		panic("unable to remap timer cpu registers");
> +
> +	intspec = of_get_property(np, "interrupts", NULL);
> +	if (!intspec)
> +		panic("no interrupts property for timer");
> +
> +	mcs814x_timer_irq.irq = be32_to_cpup(intspec);
> +}
> +
> +static void __init mcs814x_timer_init(void)
> +{
> +	struct clk *clk;
> +
> +	clk = clk_get_sys("timer0", NULL);
> +	if (IS_ERR_OR_NULL(clk))
> +		panic("unable to get timer0 clock");
> +
> +	clock_rate = clk_get_rate(clk);
> +	clk_put(clk);
> +
> +	mcs814x_of_timer_init();
> +
> +	pr_info("Timer frequency: %d (kHz)\n", clock_rate / 1000);
> +
> +	timer_reload_value = 0xffffffff - (clock_rate / HZ);
> +
> +	/* disable timer */
> +	__raw_writel(0, mcs814x_timer_base + TIMER_CTL);
> +	__raw_writel(timer_reload_value, mcs814x_timer_base + TIMER_VAL);
> +	last_reload = timer_reload_value;
> +
> +	setup_irq(mcs814x_timer_irq.irq, &mcs814x_timer_irq);
> +	/* enable timer, stop timer in debug mode */
> +	__raw_writel(0x03, mcs814x_timer_base + TIMER_CTL);
> +}
> +
> +struct sys_timer mcs814x_timer = {
> +	.init	= mcs814x_timer_init,
> +	.offset	= mcs814x_gettimeoffset,
> +};

I am surprised that this doesn't use the clocksource and clockevents
infrastructure. It probably should, and be implemented in
drivers/clocksource/.

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-16 12:29     ` Thomas Petazzoni
  0 siblings, 0 replies; 80+ messages in thread
From: Thomas Petazzoni @ 2012-07-16 12:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Florian,

Le Sun, 15 Jul 2012 16:49:07 +0200,
Florian Fainelli <florian@openwrt.org> a ?crit :

> diff --git a/arch/arm/mach-mcs814x/Makefile.boot b/arch/arm/mach-mcs814x/Makefile.boot
> new file mode 100644
> index 0000000..414db8b
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/Makefile.boot
> @@ -0,0 +1,3 @@
> +    zreladdr-y := 0x00008000
> + params_phys-y := 0x00000008
> + initrd_phys-y := 0x00400000

params_phys-y and initrd_phys-y are useless for DT-based platforms, if
I'm correct.

> diff --git a/arch/arm/mach-mcs814x/clock.c b/arch/arm/mach-mcs814x/clock.c
> new file mode 100644
> index 0000000..eb30ae2
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/clock.c
> @@ -0,0 +1,271 @@
> +/*
> + * Moschip MCS814x clock routines
> + *
> + * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
> + *
> + * Licensed under GPLv2
> + */
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/export.h>
> +#include <linux/spinlock.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk.h>
> +
> +#include <mach/mcs814x.h>
> +
> +#include "common.h"
> +
> +#define KHZ	1000
> +#define MHZ	(KHZ * KHZ)
> +
> +struct clk_ops {
> +	unsigned long (*get_rate)(struct clk *clk);
> +	int (*set_rate)(struct clk *clk, unsigned long rate);
> +	struct clk *(*get_parent)(struct clk *clk);
> +	int (*enable)(struct clk *clk, int enable);
> +};
> +
> +struct clk {
> +	struct clk *parent;		/* parent clk */
> +	unsigned long rate;		/* clock rate in Hz */
> +	unsigned long divider;		/* clock divider */
> +	u32 usecount;			/* reference count */
> +	struct clk_ops *ops;		/* clock operation */
> +	u32 enable_reg;			/* clock enable register */
> +	u32 enable_mask;		/* clock enable mask */
> +};
> +
> +static unsigned long clk_divide_parent(struct clk *clk)
> +{
> +	if (clk->parent && clk->divider)
> +		return clk_get_rate(clk->parent) / clk->divider;
> +	else
> +		return 0;
> +}
> +
> +static int clk_local_onoff_enable(struct clk *clk, int enable)
> +{
> +	u32 tmp;
> +
> +	/* no enable_reg means the clock is always enabled */
> +	if (!clk->enable_reg)
> +		return 0;
> +
> +	tmp = __raw_readl(mcs814x_sysdbg_base + clk->enable_reg);
> +	if (!enable)
> +		tmp &= ~clk->enable_mask;
> +	else
> +		tmp |= clk->enable_mask;
> +
> +	__raw_writel(tmp, mcs814x_sysdbg_base + clk->enable_reg);
> +
> +	return 0;
> +}
> +
> +static struct clk_ops default_clk_ops = {
> +	.get_rate	= clk_divide_parent,
> +	.enable		= clk_local_onoff_enable,
> +};
> +
> +static DEFINE_SPINLOCK(clocks_lock);
> +
> +static const unsigned long cpu_freq_table[] = {
> +	175000,
> +	300000,
> +	125000,
> +	137500,
> +	212500,
> +	250000,
> +	162500,
> +	187500,
> +	162500,
> +	150000,
> +	225000,
> +	237500,
> +	200000,
> +	262500,
> +	275000,
> +	287500
> +};
> +
> +static struct clk clk_cpu;
> +
> +/* System clock is fixed at 50Mhz */
> +static struct clk clk_sys = {
> +	.rate	= 50 * MHZ,
> +};
> +
> +static struct clk clk_sdram;
> +
> +static struct clk clk_timer0 = {
> +	.parent	= &clk_sdram,
> +	.divider = 2,
> +	.ops	= &default_clk_ops,
> +};
> +
> +static struct clk clk_timer1_2 = {
> +	.parent	= &clk_sys,
> +};
> +
> +/* Watchdog clock is system clock / 128 */
> +static struct clk clk_wdt = {
> +	.parent	= &clk_sys,
> +	.divider = 128,
> +	.ops	= &default_clk_ops,
> +};
> +
> +static struct clk clk_emac = {
> +	.ops		= &default_clk_ops,
> +	.enable_reg	= SYSDBG_SYSCTL,
> +	.enable_mask	= SYSCTL_EMAC,
> +};
> +
> +static struct clk clk_ephy = {
> +	.ops		= &default_clk_ops,
> +	.enable_reg	= SYSDBG_PLL_CTL,
> +	.enable_mask	= ~SYSCTL_EPHY,	/* active low */
> +};
> +
> +static struct clk clk_cipher = {
> +	.ops		= &default_clk_ops,
> +	.enable_reg	= SYSDBG_SYSCTL,
> +	.enable_mask	= SYSCTL_CIPHER,
> +};
> +
> +#define CLK(_dev, _con, _clk)	\
> +{ .dev_id = (_dev), .con_id = (_con), .clk = (_clk) },
> +
> +static struct clk_lookup mcs814x_chip_clks[] = {
> +	CLK("cpu", NULL, &clk_cpu)
> +	CLK("sys", NULL, &clk_sys)
> +	CLK("sdram", NULL, &clk_sdram)
> +	/* 32-bits timer0 */
> +	CLK("timer0", NULL, &clk_timer0)
> +	/* 16-bits timer1 */
> +	CLK("timer1", NULL, &clk_timer1_2)
> +	/* 64-bits timer2, same as timer 1 */
> +	CLK("timer2", NULL, &clk_timer1_2)
> +	CLK(NULL, "wdt", &clk_wdt)
> +	CLK(NULL, "emac", &clk_emac)
> +	CLK(NULL, "ephy", &clk_ephy)
> +	CLK(NULL, "cipher", &clk_cipher)
> +};
> +
> +static void local_clk_disable(struct clk *clk)
> +{
> +	WARN_ON(!clk->usecount);
> +
> +	if (clk->usecount > 0) {
> +		clk->usecount--;
> +
> +		if ((clk->usecount == 0) && (clk->ops->enable))
> +			clk->ops->enable(clk, 0);
> +
> +		if (clk->parent)
> +			local_clk_disable(clk->parent);
> +	}
> +}
> +
> +static int local_clk_enable(struct clk *clk)
> +{
> +	int ret = 0;
> +
> +	if (clk->parent)
> +		ret = local_clk_enable(clk->parent);
> +
> +	if (ret)
> +		return ret;
> +
> +	if ((clk->usecount == 0) && (clk->ops->enable))
> +		ret = clk->ops->enable(clk, 1);
> +
> +	if (!ret)
> +		clk->usecount++;
> +	else if (clk->parent && clk->parent->ops->enable)
> +		local_clk_disable(clk->parent);
> +
> +	return ret;
> +}
> +
> +int clk_enable(struct clk *clk)
> +{
> +	int ret;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&clocks_lock, flags);
> +	ret = local_clk_enable(clk);
> +	spin_unlock_irqrestore(&clocks_lock, flags);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(clk_enable);
> +
> +void clk_disable(struct clk *clk)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&clocks_lock, flags);
> +	local_clk_disable(clk);
> +	spin_unlock_irqrestore(&clocks_lock, flags);
> +}
> +EXPORT_SYMBOL(clk_disable);
> +
> +unsigned long clk_get_rate(struct clk *clk)
> +{
> +	if (unlikely(IS_ERR_OR_NULL(clk)))
> +		return 0;
> +
> +	if (clk->rate)
> +		return clk->rate;
> +
> +	if (clk->ops && clk->ops->get_rate)
> +		return clk->ops->get_rate(clk);
> +
> +	return clk_get_rate(clk->parent);
> +}
> +EXPORT_SYMBOL(clk_get_rate);
> +
> +struct clk *clk_get_parent(struct clk *clk)
> +{
> +	unsigned long flags;
> +
> +	if (unlikely(IS_ERR_OR_NULL(clk)))
> +		return NULL;
> +
> +	if (!clk->ops || !clk->ops->get_parent)
> +		return clk->parent;
> +
> +	spin_lock_irqsave(&clocks_lock, flags);
> +	clk->parent = clk->ops->get_parent(clk);
> +	spin_unlock_irqrestore(&clocks_lock, flags);
> +
> +	return clk->parent;
> +}
> +EXPORT_SYMBOL(clk_get_parent);

You should rather use the new clock framework instead of providing your
own implementation of the clk_*() API. And therefore your clock driver
should be in drivers/clk/ instead.

> +struct cpu_mode {
> +	const char *name;
> +	int gpio_start;
> +	int gpio_end;
> +};
> +
> +static const struct cpu_mode cpu_modes[] = {
> +	{
> +		.name		= "I2S",
> +		.gpio_start	= 4,
> +		.gpio_end	= 8,
> +	},
> +	{
> +		.name		= "UART",
> +		.gpio_start	= 4,
> +		.gpio_end	= 9,
> +	},
> +	{
> +		.name		= "External MII",
> +		.gpio_start	= 0,
> +		.gpio_end	= 16,
> +	},
> +	{
> +		.name		= "Normal",
> +		.gpio_start	= -1,
> +		.gpio_end	= -1,
> +	},
> +};
> +
> +void __init mcs814x_init_machine(void)
> +{
> +	u32 bs2, cpu_mode;
> +	int gpio;
> +
> +	bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
> +	cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
> +
> +	pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
> +
> +	/* request the gpios since the pins are muxed for functionnality */
> +	for (gpio = cpu_modes[cpu_mode].gpio_start;
> +		gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
> +		if (gpio != -1)
> +			gpio_request(gpio, cpu_modes[cpu_mode].name);

I am not sure here, but shouldn't this be done with the pinctrl
subsystem instead?

> +void __init mcs814x_map_io(void)
> +{
> +	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
> +
> +	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
> +					MCS814X_SYSDBG_SIZE);
> +	if (!mcs814x_sysdbg_base)
> +		panic("unable to remap sysdbg base");

Any reason to have a static mapping initialized with iotable_init() and
then a dynamic mapping initialized with ioremap() ? I thought that
ioremap() wasn't ready at the ->map_io() time, and it was therefore the
reason we had static mappings.

> diff --git a/arch/arm/mach-mcs814x/include/mach/entry-macro.S b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
> new file mode 100644
> index 0000000..cbad566
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
> @@ -0,0 +1,29 @@
> +#include <mach/mcs814x.h>
> +                .macro  disable_fiq
> +                .endm
> +
> +		.macro arch_ret_to_user, tmp1, tmp2
> +		.endm
> +
> +		.macro  get_irqnr_preamble, base, tmp
> +		ldr	\base, =mcs814x_intc_base@ base virtual address of INTC
> +		ldr	\base, [\base]
> +		.endm
> +
> +		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
> +		mov	\tmp, #MCS814X_IRQ_STS0	 @ load tmp with STS0 register offset
> +		ldr	\irqstat, [\base, \tmp]	 @ load value at base + tmp
> +		tst	\irqstat, \irqstat       @ test if no active IRQ's
> +		beq	1002f                    @ if no active irqs return with status 0
> +		mov	\irqnr, #0               @ start from irq zero
> +		mov	\tmp,   #1               @ the mask initially 1
> +1001:
> +		tst     \irqstat, \tmp           @ and with mask
> +		addeq   \irqnr, \irqnr, #1       @ if  zero then add one to nr
> +		moveq   \tmp,   \tmp, lsl #1     @ shift mask one to left
> +		beq     1001b                    @ if  zero then loop again
> +		mov     \irqstat, \tmp           @ save the return mask
> +		mov	\tmp, #MCS814X_IRQ_STS0  @ load tmp with ICR offset
> +		str     \irqstat,  [\base, \tmp] @ clear irq with selected mask
> +1002:
> +                .endm

Hum, you should instead use the MULTI_IRQ_HANDLER feature so that this
can be written in C.

> diff --git a/arch/arm/mach-mcs814x/include/mach/hardware.h b/arch/arm/mach-mcs814x/include/mach/hardware.h
> new file mode 100644
> index 0000000..529f648
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/hardware.h
> @@ -0,0 +1,16 @@
> +/*
> + * Copyright (C) 2003 Artec Design Ltd.
> + *
> + * 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 __ASM_ARCH_HARDWARE_H
> +#define __ASM_ARCH_HARDWARE_H

This #define name no longer looks consistent with where the file is
located.

> +#include "mcs814x.h"
> +
> +#endif
> +
> diff --git a/arch/arm/mach-mcs814x/include/mach/irqs.h b/arch/arm/mach-mcs814x/include/mach/irqs.h
> new file mode 100644
> index 0000000..78021d1
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/irqs.h
> @@ -0,0 +1,22 @@
> +/*
> + * Copyright (C) 2003 Artec Design Ltd.
> + *
> + * 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 __ASM_ARCH_IRQS_H
> +#define __ASM_ARCH_IRQS_H
> +
> +#define FIQ_START	0
> +
> +#define NR_IRQS		32

I think this shouldn't be needed if you use SPARSE_IRQ support.

> +#define IRQ_PCI_INTA            22
> +#define IRQ_PCI_INTB            23
> +#define IRQ_PCI_INTC            24
> +#define IRQ_PCI_INTD            26

And these probably belong to the DT somehow?

> diff --git a/arch/arm/mach-mcs814x/timer.c b/arch/arm/mach-mcs814x/timer.c
> new file mode 100644
> index 0000000..e8408e4
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/timer.c
> @@ -0,0 +1,133 @@
> +/*
> + * Moschip MCS814x timer routines
> + *
> + * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
> + *
> + * Licensed under GPLv2
> + */
> +#include <linux/kernel.h>
> +#include <linux/interrupt.h>
> +#include <linux/time.h>
> +#include <linux/timex.h>
> +#include <linux/irq.h>
> +#include <linux/err.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +
> +#include <asm/mach/time.h>
> +#include <mach/mcs814x.h>
> +
> +/* Timer block registers */
> +#define TIMER_VAL	0x00
> +#define TIMER_CTL	0x04
> +
> +static u32 last_reload;
> +static u32 timer_correct;
> +static u32 clock_rate;
> +static u32 timer_reload_value;
> +static void __iomem *mcs814x_timer_base;
> +
> +static inline unsigned long ticks2usecs(u32 x)
> +{
> +	return x / (clock_rate / 1000000);
> +}
> +
> +/*
> + * Returns number of ms since last clock interrupt.  Note that interrupts
> + * will have been disabled by do_gettimeoffset()
> + */
> +static unsigned long mcs814x_gettimeoffset(void)
> +{
> +	u32 ticks = __raw_readl(mcs814x_timer_base + TIMER_VAL);
> +
> +	if (ticks < last_reload)
> +		return ticks2usecs(ticks + (u32)(0xffffffff - last_reload));
> +	else
> +		return ticks2usecs(ticks - last_reload);
> +}
> +
> +
> +static irqreturn_t mcs814x_timer_interrupt(int irq, void *dev_id)
> +{
> +	u32 count = __raw_readl(mcs814x_timer_base + TIMER_VAL);
> +
> +	/* take into account delay up to this moment */
> +	last_reload = count + timer_correct + timer_reload_value;
> +
> +	if (last_reload < timer_reload_value)
> +		last_reload = timer_reload_value;
> +	else if (timer_correct == 0)
> +		timer_correct = __raw_readl(mcs814x_timer_base + TIMER_VAL) -
> +					count;
> +
> +	__raw_writel(last_reload, mcs814x_timer_base + TIMER_VAL);
> +
> +	timer_tick();
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static struct irqaction mcs814x_timer_irq = {
> +	.name		= "mcs814x-timer",
> +	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
> +	.handler	= mcs814x_timer_interrupt,
> +};
> +
> +static struct of_device_id mcs814x_timer_ids[] = {
> +	{ .compatible = "moschip,mcs814x-timer" },
> +	{ /* sentinel */ },
> +};
> +
> +static void __init mcs814x_of_timer_init(void)
> +{
> +	struct device_node *np;
> +	const unsigned int *intspec;
> +
> +	np = of_find_matching_node(NULL, mcs814x_timer_ids);
> +	if (!np)
> +		panic("unable to find compatible timer node in dtb");
> +
> +	mcs814x_timer_base = of_iomap(np, 0);
> +	if (!mcs814x_timer_base)
> +		panic("unable to remap timer cpu registers");
> +
> +	intspec = of_get_property(np, "interrupts", NULL);
> +	if (!intspec)
> +		panic("no interrupts property for timer");
> +
> +	mcs814x_timer_irq.irq = be32_to_cpup(intspec);
> +}
> +
> +static void __init mcs814x_timer_init(void)
> +{
> +	struct clk *clk;
> +
> +	clk = clk_get_sys("timer0", NULL);
> +	if (IS_ERR_OR_NULL(clk))
> +		panic("unable to get timer0 clock");
> +
> +	clock_rate = clk_get_rate(clk);
> +	clk_put(clk);
> +
> +	mcs814x_of_timer_init();
> +
> +	pr_info("Timer frequency: %d (kHz)\n", clock_rate / 1000);
> +
> +	timer_reload_value = 0xffffffff - (clock_rate / HZ);
> +
> +	/* disable timer */
> +	__raw_writel(0, mcs814x_timer_base + TIMER_CTL);
> +	__raw_writel(timer_reload_value, mcs814x_timer_base + TIMER_VAL);
> +	last_reload = timer_reload_value;
> +
> +	setup_irq(mcs814x_timer_irq.irq, &mcs814x_timer_irq);
> +	/* enable timer, stop timer in debug mode */
> +	__raw_writel(0x03, mcs814x_timer_base + TIMER_CTL);
> +}
> +
> +struct sys_timer mcs814x_timer = {
> +	.init	= mcs814x_timer_init,
> +	.offset	= mcs814x_gettimeoffset,
> +};

I am surprised that this doesn't use the clocksource and clockevents
infrastructure. It probably should, and be implemented in
drivers/clocksource/.

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-16 12:29     ` Thomas Petazzoni
@ 2012-07-16 12:43       ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-16 12:43 UTC (permalink / raw)
  To: Thomas Petazzoni; +Cc: olof, devicetree-discuss, arnd, linux-arm-kernel

Hi Thomas,

On Monday 16 July 2012 14:29:41 Thomas Petazzoni wrote:
> Hello Florian,
> 
> Le Sun, 15 Jul 2012 16:49:07 +0200,
> Florian Fainelli <florian@openwrt.org> a écrit :
> 
> > diff --git a/arch/arm/mach-mcs814x/Makefile.boot b/arch/arm/mach-
mcs814x/Makefile.boot
> > new file mode 100644
> > index 0000000..414db8b
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/Makefile.boot
> > @@ -0,0 +1,3 @@
> > +    zreladdr-y := 0x00008000
> > + params_phys-y := 0x00000008
> > + initrd_phys-y := 0x00400000
> 
> params_phys-y and initrd_phys-y are useless for DT-based platforms, if
> I'm correct.

Indeed, only zreladdr is actually required.

> 
> > diff --git a/arch/arm/mach-mcs814x/clock.c b/arch/arm/mach-mcs814x/clock.c
> > new file mode 100644
> > index 0000000..eb30ae2
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/clock.c
[snip]
> 
> You should rather use the new clock framework instead of providing your
> own implementation of the clk_*() API. And therefore your clock driver
> should be in drivers/clk/ instead.

Since I was targetting 3.6 initially I more or less used what was existing by 
the time I wrote the patches, but I will do this.

> 
> > +struct cpu_mode {
> > +	const char *name;
> > +	int gpio_start;
> > +	int gpio_end;
> > +};
> > +
> > +static const struct cpu_mode cpu_modes[] = {
> > +	{
> > +		.name		= "I2S",
> > +		.gpio_start	= 4,
> > +		.gpio_end	= 8,
> > +	},
> > +	{
> > +		.name		= "UART",
> > +		.gpio_start	= 4,
> > +		.gpio_end	= 9,
> > +	},
> > +	{
> > +		.name		= "External MII",
> > +		.gpio_start	= 0,
> > +		.gpio_end	= 16,
> > +	},
> > +	{
> > +		.name		= "Normal",
> > +		.gpio_start	= -1,
> > +		.gpio_end	= -1,
> > +	},
> > +};
> > +
> > +void __init mcs814x_init_machine(void)
> > +{
> > +	u32 bs2, cpu_mode;
> > +	int gpio;
> > +
> > +	bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
> > +	cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
> > +
> > +	pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
> > +
> > +	/* request the gpios since the pins are muxed for functionnality */
> > +	for (gpio = cpu_modes[cpu_mode].gpio_start;
> > +		gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
> > +		if (gpio != -1)
> > +			gpio_request(gpio, cpu_modes[cpu_mode].name);
> 
> I am not sure here, but shouldn't this be done with the pinctrl
> subsystem instead?

This muxing is actually hardwired with the bootstrap register setting. I could 
also even remove this because the underlying hardware block actually does not 
need to use the GPIOs, they will be configured as pins for the corresponding 
functions directly. This is also not runtime modifiable. I just thought that 
marking these GPIOs as reserved by the corresponding functionnality could help 
the user figuring out what is happening with them.

> 
> > +void __init mcs814x_map_io(void)
> > +{
> > +	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
> > +
> > +	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
> > +					MCS814X_SYSDBG_SIZE);
> > +	if (!mcs814x_sysdbg_base)
> > +		panic("unable to remap sysdbg base");
> 
> Any reason to have a static mapping initialized with iotable_init() and
> then a dynamic mapping initialized with ioremap() ? I thought that
> ioremap() wasn't ready at the ->map_io() time, and it was therefore the
> reason we had static mappings.

There are no particular reasons, I could use the the define for the virtual 
address directly.

> 
> > diff --git a/arch/arm/mach-mcs814x/include/mach/entry-macro.S 
b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
> > new file mode 100644
> > index 0000000..cbad566
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
> > @@ -0,0 +1,29 @@
> > +#include <mach/mcs814x.h>
> > +                .macro  disable_fiq
> > +                .endm
> > +
> > +		.macro arch_ret_to_user, tmp1, tmp2
> > +		.endm
> > +
> > +		.macro  get_irqnr_preamble, base, tmp
> > +		ldr	\base, =mcs814x_intc_base@ base virtual address of INTC
> > +		ldr	\base, [\base]
> > +		.endm
> > +
> > +		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
> > +		mov	\tmp, #MCS814X_IRQ_STS0	 @ load tmp with STS0 register 
offset
> > +		ldr	\irqstat, [\base, \tmp]	 @ load value at base + tmp
> > +		tst	\irqstat, \irqstat       @ test if no active IRQ's
> > +		beq	1002f                    @ if no active irqs return with 
status 0
> > +		mov	\irqnr, #0               @ start from irq zero
> > +		mov	\tmp,   #1               @ the mask initially 1
> > +1001:
> > +		tst     \irqstat, \tmp           @ and with mask
> > +		addeq   \irqnr, \irqnr, #1       @ if  zero then add one to nr
> > +		moveq   \tmp,   \tmp, lsl #1     @ shift mask one to left
> > +		beq     1001b                    @ if  zero then loop again
> > +		mov     \irqstat, \tmp           @ save the return mask
> > +		mov	\tmp, #MCS814X_IRQ_STS0  @ load tmp with ICR offset
> > +		str     \irqstat,  [\base, \tmp] @ clear irq with selected 
mask
> > +1002:
> > +                .endm
> 
> Hum, you should instead use the MULTI_IRQ_HANDLER feature so that this
> can be written in C.

Last I did this, I managed to get interrupt handling issues with Ethernet, but 
I will try to address this. So far, since we support only MCS8140 this is not 
a problem, MCS8142 also has the same interrupt controller.

> 
> > diff --git a/arch/arm/mach-mcs814x/include/mach/hardware.h b/arch/arm/mach-
mcs814x/include/mach/hardware.h
> > new file mode 100644
> > index 0000000..529f648
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/hardware.h
> > @@ -0,0 +1,16 @@
> > +/*
> > + * Copyright (C) 2003 Artec Design Ltd.
> > + *
> > + * 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 __ASM_ARCH_HARDWARE_H
> > +#define __ASM_ARCH_HARDWARE_H
> 
> This #define name no longer looks consistent with where the file is
> located.

Right, thanks!

> 
> > +#include "mcs814x.h"
> > +
> > +#endif
> > +
> > diff --git a/arch/arm/mach-mcs814x/include/mach/irqs.h b/arch/arm/mach-
mcs814x/include/mach/irqs.h
> > new file mode 100644
> > index 0000000..78021d1
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/irqs.h
> > @@ -0,0 +1,22 @@
> > +/*
> > + * Copyright (C) 2003 Artec Design Ltd.
> > + *
> > + * 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 __ASM_ARCH_IRQS_H
> > +#define __ASM_ARCH_IRQS_H
> > +
> > +#define FIQ_START	0
> > +
> > +#define NR_IRQS		32
> 
> I think this shouldn't be needed if you use SPARSE_IRQ support.
> 
> > +#define IRQ_PCI_INTA            22
> > +#define IRQ_PCI_INTB            23
> > +#define IRQ_PCI_INTC            24
> > +#define IRQ_PCI_INTD            26
> 
> And these probably belong to the DT somehow?

This would need a complete PCI irq mapping representation, so far we have the 
DT properties, but not the corresponding code to parse them. I would not 
qualify this as a major blocker.

> 
> > diff --git a/arch/arm/mach-mcs814x/timer.c b/arch/arm/mach-mcs814x/timer.c
> > new file mode 100644
> > index 0000000..e8408e4

[snip]

> > +
> > +static void __init mcs814x_timer_init(void)
> > +{
> > +	struct clk *clk;
> > +
> > +	clk = clk_get_sys("timer0", NULL);
> > +	if (IS_ERR_OR_NULL(clk))
> > +		panic("unable to get timer0 clock");
> > +
> > +	clock_rate = clk_get_rate(clk);
> > +	clk_put(clk);
> > +
> > +	mcs814x_of_timer_init();
> > +
> > +	pr_info("Timer frequency: %d (kHz)\n", clock_rate / 1000);
> > +
> > +	timer_reload_value = 0xffffffff - (clock_rate / HZ);
> > +
> > +	/* disable timer */
> > +	__raw_writel(0, mcs814x_timer_base + TIMER_CTL);
> > +	__raw_writel(timer_reload_value, mcs814x_timer_base + TIMER_VAL);
> > +	last_reload = timer_reload_value;
> > +
> > +	setup_irq(mcs814x_timer_irq.irq, &mcs814x_timer_irq);
> > +	/* enable timer, stop timer in debug mode */
> > +	__raw_writel(0x03, mcs814x_timer_base + TIMER_CTL);
> > +}
> > +
> > +struct sys_timer mcs814x_timer = {
> > +	.init	= mcs814x_timer_init,
> > +	.offset	= mcs814x_gettimeoffset,
> > +};
> 
> I am surprised that this doesn't use the clocksource and clockevents
> infrastructure. It probably should, and be implemented in
> drivers/clocksource/.

I will look into this, considering that we still have 2 timers left available 
(64-bits and 16-bits) this should be doable.

Thank you for your comments, I will wait a little more for other people to 
come up before coming up with a patch respin.
--
Florian

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-16 12:43       ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-16 12:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,

On Monday 16 July 2012 14:29:41 Thomas Petazzoni wrote:
> Hello Florian,
> 
> Le Sun, 15 Jul 2012 16:49:07 +0200,
> Florian Fainelli <florian@openwrt.org> a ?crit :
> 
> > diff --git a/arch/arm/mach-mcs814x/Makefile.boot b/arch/arm/mach-
mcs814x/Makefile.boot
> > new file mode 100644
> > index 0000000..414db8b
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/Makefile.boot
> > @@ -0,0 +1,3 @@
> > +    zreladdr-y := 0x00008000
> > + params_phys-y := 0x00000008
> > + initrd_phys-y := 0x00400000
> 
> params_phys-y and initrd_phys-y are useless for DT-based platforms, if
> I'm correct.

Indeed, only zreladdr is actually required.

> 
> > diff --git a/arch/arm/mach-mcs814x/clock.c b/arch/arm/mach-mcs814x/clock.c
> > new file mode 100644
> > index 0000000..eb30ae2
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/clock.c
[snip]
> 
> You should rather use the new clock framework instead of providing your
> own implementation of the clk_*() API. And therefore your clock driver
> should be in drivers/clk/ instead.

Since I was targetting 3.6 initially I more or less used what was existing by 
the time I wrote the patches, but I will do this.

> 
> > +struct cpu_mode {
> > +	const char *name;
> > +	int gpio_start;
> > +	int gpio_end;
> > +};
> > +
> > +static const struct cpu_mode cpu_modes[] = {
> > +	{
> > +		.name		= "I2S",
> > +		.gpio_start	= 4,
> > +		.gpio_end	= 8,
> > +	},
> > +	{
> > +		.name		= "UART",
> > +		.gpio_start	= 4,
> > +		.gpio_end	= 9,
> > +	},
> > +	{
> > +		.name		= "External MII",
> > +		.gpio_start	= 0,
> > +		.gpio_end	= 16,
> > +	},
> > +	{
> > +		.name		= "Normal",
> > +		.gpio_start	= -1,
> > +		.gpio_end	= -1,
> > +	},
> > +};
> > +
> > +void __init mcs814x_init_machine(void)
> > +{
> > +	u32 bs2, cpu_mode;
> > +	int gpio;
> > +
> > +	bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
> > +	cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
> > +
> > +	pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
> > +
> > +	/* request the gpios since the pins are muxed for functionnality */
> > +	for (gpio = cpu_modes[cpu_mode].gpio_start;
> > +		gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
> > +		if (gpio != -1)
> > +			gpio_request(gpio, cpu_modes[cpu_mode].name);
> 
> I am not sure here, but shouldn't this be done with the pinctrl
> subsystem instead?

This muxing is actually hardwired with the bootstrap register setting. I could 
also even remove this because the underlying hardware block actually does not 
need to use the GPIOs, they will be configured as pins for the corresponding 
functions directly. This is also not runtime modifiable. I just thought that 
marking these GPIOs as reserved by the corresponding functionnality could help 
the user figuring out what is happening with them.

> 
> > +void __init mcs814x_map_io(void)
> > +{
> > +	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
> > +
> > +	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
> > +					MCS814X_SYSDBG_SIZE);
> > +	if (!mcs814x_sysdbg_base)
> > +		panic("unable to remap sysdbg base");
> 
> Any reason to have a static mapping initialized with iotable_init() and
> then a dynamic mapping initialized with ioremap() ? I thought that
> ioremap() wasn't ready at the ->map_io() time, and it was therefore the
> reason we had static mappings.

There are no particular reasons, I could use the the define for the virtual 
address directly.

> 
> > diff --git a/arch/arm/mach-mcs814x/include/mach/entry-macro.S 
b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
> > new file mode 100644
> > index 0000000..cbad566
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
> > @@ -0,0 +1,29 @@
> > +#include <mach/mcs814x.h>
> > +                .macro  disable_fiq
> > +                .endm
> > +
> > +		.macro arch_ret_to_user, tmp1, tmp2
> > +		.endm
> > +
> > +		.macro  get_irqnr_preamble, base, tmp
> > +		ldr	\base, =mcs814x_intc_base@ base virtual address of INTC
> > +		ldr	\base, [\base]
> > +		.endm
> > +
> > +		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
> > +		mov	\tmp, #MCS814X_IRQ_STS0	 @ load tmp with STS0 register 
offset
> > +		ldr	\irqstat, [\base, \tmp]	 @ load value at base + tmp
> > +		tst	\irqstat, \irqstat       @ test if no active IRQ's
> > +		beq	1002f                    @ if no active irqs return with 
status 0
> > +		mov	\irqnr, #0               @ start from irq zero
> > +		mov	\tmp,   #1               @ the mask initially 1
> > +1001:
> > +		tst     \irqstat, \tmp           @ and with mask
> > +		addeq   \irqnr, \irqnr, #1       @ if  zero then add one to nr
> > +		moveq   \tmp,   \tmp, lsl #1     @ shift mask one to left
> > +		beq     1001b                    @ if  zero then loop again
> > +		mov     \irqstat, \tmp           @ save the return mask
> > +		mov	\tmp, #MCS814X_IRQ_STS0  @ load tmp with ICR offset
> > +		str     \irqstat,  [\base, \tmp] @ clear irq with selected 
mask
> > +1002:
> > +                .endm
> 
> Hum, you should instead use the MULTI_IRQ_HANDLER feature so that this
> can be written in C.

Last I did this, I managed to get interrupt handling issues with Ethernet, but 
I will try to address this. So far, since we support only MCS8140 this is not 
a problem, MCS8142 also has the same interrupt controller.

> 
> > diff --git a/arch/arm/mach-mcs814x/include/mach/hardware.h b/arch/arm/mach-
mcs814x/include/mach/hardware.h
> > new file mode 100644
> > index 0000000..529f648
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/hardware.h
> > @@ -0,0 +1,16 @@
> > +/*
> > + * Copyright (C) 2003 Artec Design Ltd.
> > + *
> > + * 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 __ASM_ARCH_HARDWARE_H
> > +#define __ASM_ARCH_HARDWARE_H
> 
> This #define name no longer looks consistent with where the file is
> located.

Right, thanks!

> 
> > +#include "mcs814x.h"
> > +
> > +#endif
> > +
> > diff --git a/arch/arm/mach-mcs814x/include/mach/irqs.h b/arch/arm/mach-
mcs814x/include/mach/irqs.h
> > new file mode 100644
> > index 0000000..78021d1
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/irqs.h
> > @@ -0,0 +1,22 @@
> > +/*
> > + * Copyright (C) 2003 Artec Design Ltd.
> > + *
> > + * 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 __ASM_ARCH_IRQS_H
> > +#define __ASM_ARCH_IRQS_H
> > +
> > +#define FIQ_START	0
> > +
> > +#define NR_IRQS		32
> 
> I think this shouldn't be needed if you use SPARSE_IRQ support.
> 
> > +#define IRQ_PCI_INTA            22
> > +#define IRQ_PCI_INTB            23
> > +#define IRQ_PCI_INTC            24
> > +#define IRQ_PCI_INTD            26
> 
> And these probably belong to the DT somehow?

This would need a complete PCI irq mapping representation, so far we have the 
DT properties, but not the corresponding code to parse them. I would not 
qualify this as a major blocker.

> 
> > diff --git a/arch/arm/mach-mcs814x/timer.c b/arch/arm/mach-mcs814x/timer.c
> > new file mode 100644
> > index 0000000..e8408e4

[snip]

> > +
> > +static void __init mcs814x_timer_init(void)
> > +{
> > +	struct clk *clk;
> > +
> > +	clk = clk_get_sys("timer0", NULL);
> > +	if (IS_ERR_OR_NULL(clk))
> > +		panic("unable to get timer0 clock");
> > +
> > +	clock_rate = clk_get_rate(clk);
> > +	clk_put(clk);
> > +
> > +	mcs814x_of_timer_init();
> > +
> > +	pr_info("Timer frequency: %d (kHz)\n", clock_rate / 1000);
> > +
> > +	timer_reload_value = 0xffffffff - (clock_rate / HZ);
> > +
> > +	/* disable timer */
> > +	__raw_writel(0, mcs814x_timer_base + TIMER_CTL);
> > +	__raw_writel(timer_reload_value, mcs814x_timer_base + TIMER_VAL);
> > +	last_reload = timer_reload_value;
> > +
> > +	setup_irq(mcs814x_timer_irq.irq, &mcs814x_timer_irq);
> > +	/* enable timer, stop timer in debug mode */
> > +	__raw_writel(0x03, mcs814x_timer_base + TIMER_CTL);
> > +}
> > +
> > +struct sys_timer mcs814x_timer = {
> > +	.init	= mcs814x_timer_init,
> > +	.offset	= mcs814x_gettimeoffset,
> > +};
> 
> I am surprised that this doesn't use the clocksource and clockevents
> infrastructure. It probably should, and be implemented in
> drivers/clocksource/.

I will look into this, considering that we still have 2 timers left available 
(64-bits and 16-bits) this should be doable.

Thank you for your comments, I will wait a little more for other people to 
come up before coming up with a patch respin.
--
Florian

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-15 14:49   ` Florian Fainelli
@ 2012-07-16 15:54       ` Arnd Bergmann
  -1 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-16 15:54 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Mike Turquette, Linus Walleij
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Florian Fainelli

On Sunday 15 July 2012, Florian Fainelli wrote:

> diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
> new file mode 100644
> index 0000000..c89422f
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/Kconfig
> @@ -0,0 +1,11 @@
> +if ARCH_MCS814X
> +
> +config MCS8140
> +	select CPU_ARM926T
> +	bool
> +
> +menu "Moschip MCS8140 boards"
> +
> +endmenu
> +
> +endif

What values does the Kconfig file actually provide? I see that you are
adding the boards here later, but I think it would be nice to just 
make the new platform a single Kconfig option with no individual
board selection.

> +struct clk {
> +	struct clk *parent;		/* parent clk */
> +	unsigned long rate;		/* clock rate in Hz */
> +	unsigned long divider;		/* clock divider */
> +	u32 usecount;			/* reference count */
> +	struct clk_ops *ops;		/* clock operation */
> +	u32 enable_reg;			/* clock enable register */
> +	u32 enable_mask;		/* clock enable mask */
> +};

Platforms are now converting to the common clock framework in drivers/clk.
Mike Turquette as the subsystem maintainer can probably judge better whether
we should still be allowing new platforms with their own implementation
of clk, but my feeling is that you should use the subsystem instead
and add a driver in a subdirectory of drivers/clk instead of in the
platform.

> +void __iomem *mcs814x_sysdbg_base;

Does this have to be globally visible? I would recommend making it static.

> +
> +struct cpu_mode {
> +	const char *name;
> +	int gpio_start;
> +	int gpio_end;
> +};
> +
> +static const struct cpu_mode cpu_modes[] = {
> +	{
> +		.name		= "I2S",
> +		.gpio_start	= 4,
> +		.gpio_end	= 8,
> +	},
> +	{
> +		.name		= "UART",
> +		.gpio_start	= 4,
> +		.gpio_end	= 9,
> +	},
> +	{
> +		.name		= "External MII",
> +		.gpio_start	= 0,
> +		.gpio_end	= 16,
> +	},
> +	{
> +		.name		= "Normal",
> +		.gpio_start	= -1,
> +		.gpio_end	= -1,
> +	},
> +};
> +
> +void __init mcs814x_init_machine(void)
> +{
> +	u32 bs2, cpu_mode;
> +	int gpio;
> +
> +	bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
> +	cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
> +
> +	pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
> +
> +	/* request the gpios since the pins are muxed for functionnality */
> +	for (gpio = cpu_modes[cpu_mode].gpio_start;
> +		gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
> +		if (gpio != -1)
> +			gpio_request(gpio, cpu_modes[cpu_mode].name);
> +	}
> +}

This looks like a very simple instance of a pinmux driver. I wonder
if it's worth doing an actual pinctrl driver that knows about these
modes and about the gpio handling of the platform. Maybe Linus Walleij
can comment on that.

How is the cpu mode managed? Is it hardwired through something like
strapping pins, or could you have a system that sets it dynamically
based on what hardware is being plugged in?

> +void __init mcs814x_map_io(void)
> +{
> +	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
> +
> +	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
> +					MCS814X_SYSDBG_SIZE);
> +	if (!mcs814x_sysdbg_base)
> +		panic("unable to remap sysdbg base");
> +}
> +
> +void mcs814x_restart(char mode, const char *cmd)
> +{
> +	__raw_writel(~(1 << 31), mcs814x_sysdbg_base);
> +}

You should generally avoid using __raw_readl etc. and instead use
readl/write or readl_relaxed/writel_relaxed.

> diff --git a/arch/arm/mach-mcs814x/common.h b/arch/arm/mach-mcs814x/common.h
> new file mode 100644
> index 0000000..e523abe
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/common.h
> @@ -0,0 +1,15 @@
> +#ifndef __ARCH_MCS814X_COMMON_H
> +#define __ARCH_MCS814X_COMMON_H
> +
> +#include <asm/mach/time.h>
> +
> +void mcs814x_map_io(void);
> +void mcs814x_clk_init(void);
> +void mcs814x_of_irq_init(void);
> +void mcs814x_init_machine(void);
> +void mcs814x_handle_irq(struct pt_regs *regs);
> +void mcs814x_restart(char mode, const char *cmd);
> +extern struct sys_timer mcs814x_timer;
> +extern void __iomem *mcs814x_sysdbg_base;
> +
> +#endif /* __ARCH_MCS814X_COMMON_H */

I think a lot of these don't actually need to be global if you combine some
of the files.


> diff --git a/arch/arm/mach-mcs814x/include/mach/cpu.h b/arch/arm/mach-mcs814x/include/mach/cpu.h
> new file mode 100644
> index 0000000..1ef3c4a
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/cpu.h
> @@ -0,0 +1,16 @@
> +#ifndef __ASM_ARCH_CPU_H__
> +#define __ASM_ARCH_CPU_H__
> +
> +#include <asm/cputype.h>
> +
> +#define MCS8140_ID	0x41069260	/* ARM926EJ-S */
> +#define MCS814X_MASK	0xff0ffff0
> +
> +#ifdef CONFIG_MCS8140
> +/* Moschip MCS8140 is based on an ARM926EJ-S core */
> +#define soc_is_mcs8140()	((read_cpuid_id() & MCS814X_MASK) == MCS8140_ID)
> +#else
> +#define soc_is_mcs8140()	(0)
> +#endif /* !CONFIG_MCS8140 */
> +
> +#endif /* __ASM_ARCH_CPU_H__ */

Can you explain what this is used for? Are there other SoCs in the same
platform that will get added later?

> diff --git a/arch/arm/mach-mcs814x/include/mach/hardware.h b/arch/arm/mach-mcs814x/include/mach/hardware.h
> new file mode 100644
> index 0000000..529f648
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/hardware.h
> @@ -0,0 +1,16 @@
> +/*
> + * Copyright (C) 2003 Artec Design Ltd.
> + *
> + * 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 __ASM_ARCH_HARDWARE_H
> +#define __ASM_ARCH_HARDWARE_H
> +
> +#include "mcs814x.h"
> +
> +#endif

I'd just make this an empty file, like gpio.h. That will let us kill off
these files more easily in the future.

> diff --git a/arch/arm/mach-mcs814x/include/mach/irqs.h b/arch/arm/mach-mcs814x/include/mach/irqs.h
> new file mode 100644
> index 0000000..78021d1
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/irqs.h
> @@ -0,0 +1,22 @@
> +/*
> + * Copyright (C) 2003 Artec Design Ltd.
> + *
> + * 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 __ASM_ARCH_IRQS_H
> +#define __ASM_ARCH_IRQS_H
> +
> +#define FIQ_START	0

Why do you need the FIQ_START macro here?

> +#define NR_IRQS		32
> +
> +#define IRQ_PCI_INTA            22
> +#define IRQ_PCI_INTB            23
> +#define IRQ_PCI_INTC            24
> +#define IRQ_PCI_INTD            26

The PCI interrupts should come from the device tree.

You should also select CONFIG_SPARSE_IRQ unconditionally and use IRQ domains
so that you no longer need to set NR_IRQS.

> diff --git a/arch/arm/mach-mcs814x/include/mach/mcs814x.h b/arch/arm/mach-mcs814x/include/mach/mcs814x.h
> new file mode 100644
> index 0000000..a4a369e
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/mcs814x.h
> @@ -0,0 +1,53 @@
> +/*
> + * Copyright (C) 2003 Artec Design Ltd.
> + *
> + * 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 __ASM_ARCH_MCS814X_H
> +#define __ASM_ARCH_MCS814X_H
> +
> +#define MCS814X_IO_BASE		0xF0000000
> +#define MCS814X_IO_START	0x40000000
> +#define MCS814X_IO_SIZE		0x00100000

What are these required for in the global space? Can you move them into
a single .c file?

> +/* IRQ controller register offset */
> +#define MCS814X_IRQ_ICR		0x00
> +#define MCS814X_IRQ_ISR		0x04
> +#define MCS814X_IRQ_MASK	0x20
> +#define MCS814X_IRQ_STS0	0x40

I'm pretty sure these can be in irq.c

> +#define MCS814X_PHYS_BASE	0x40000000
> +#define MCS814X_VIRT_BASE	MCS814X_IO_BASE
> +
> +#define MCS814X_UART		0x000DC000
> +#define MCS814X_DBGLED		0x000EC000
> +#define MCS814X_SYSDBG		0x000F8000
> +#define MCS814X_SYSDBG_SIZE	0x50
> +
> +/* System configuration and bootstrap registers */
> +#define SYSDBG_BS1		0x00
> +#define  CPU_FREQ_SHIFT		27
> +#define  CPU_FREQ_MASK		0x0F
> +#define  SDRAM_FREQ_BIT		(1 << 22)
> +
> +#define SYSDBG_BS2		0x04
> +#define  LED_CFG_MASK		0x03
> +#define  CPU_MODE_SHIFT		23
> +#define  CPU_MODE_MASK		0x03
> +
> +#define SYSDBG_SYSCTL_MAC	0x1d
> +#define  BUF_SHIFT_BIT		(1 << 0)
> +
> +#define SYSDBG_SYSCTL		0x08
> +#define  SYSCTL_EMAC		(1 << 0)
> +#define  SYSCTL_EPHY		(1 << 0) /* active low */
> +#define  SYSCTL_CIPHER		(1 << 16)
> +
> +#define SYSDBG_PLL_CTL		0x3C

The sysdbg stuff can probably go into a file that deals
with the sysdbg registers and exports a high-level interface.

> +
> +void __iomem *mcs814x_intc_base;

static?

> +#define MCS8140_PCI_HOST_BASE           0x80000000
> +#define MCS8140_PCI_IOMISC_BASE         0x00000000
> +#define MCS8140_PCI_PRE_BASE            0x10000000
> +#define MCS8140_PCI_NONPRE_BASE         0x30000000
> +
> +#define MCS8140_PCI_CFG_BASE		(MCS8140_PCI_HOST_BASE + 0x04000000)
> +#define MCS8140_PCI_IO_BASE		(MCS8140_PCI_HOST_BASE)
> +
> +#define MCS8140_PCI_IO_VIRT_BASE	(MCS814X_IO_BASE - \
> +					 MCS8140_PCI_CONFIG_SIZE - \
> +					 MCS8140_PCI_IOMISC_SIZE)
> +#define MCS8140_PCI_CFG_VIRT_BASE	(MCS814X_IO_BASE - \
> +					 MCS8140_PCI_CONFIG_SIZE)


> +static unsigned long __pci_addr(struct pci_bus *bus,
> +				unsigned int devfn, int offset)
> +{
> +	unsigned int busnr = bus->number;
> +	unsigned int slot;
> +
> +	/* we only support bus 0 */
> +	if (busnr != 0)
> +		return 0;

Why? A lot of devices have bridges on them and they should just
work if you take out this check.

> +	/*
> +	 * Trap out illegal values
> +	 */
> +	BUG_ON(devfn > 255 || busnr > 255 || devfn > 255);

You're checking devfn twice...

> +	/* Scan 3 slots */
> +	slot = PCI_SLOT(devfn);
> +	switch (slot) {
> +	case 1:
> +	case 2:
> +	case 3:
> +		if (PCI_FUNC(devfn) >= 4)
> +			return 0;

This also looks bogus. Why limit it to three devices?

> +static int mcs8140_pci_read_config(struct pci_bus *bus,
> +					unsigned int devfn, int where,
> +					int size, u32 *val)
> +{
> +	unsigned long v = 0xFFFFFFFF;
> +	unsigned long addr = __pci_addr(bus, devfn, where);
> +
> +	if (addr != 0) {
> +		switch (size) {
> +		case 1:
> +			v = __raw_readb(addr);
> +			break;
> +		case 2:
> +			addr &= ~1;
> +			v = __raw_readw(addr);
> +			break;
> +		default:
> +			addr &= ~3;
> +			v = __raw_readl(addr);
> +			break;
> +		}
> +	} else
> +		v = 0xffffffff;

This is just mmconfig, right? Don't we have a generic implementation for that?

> +
> +static struct resource io_mem = {
> +	.name	= "PCI I/O space",
> +	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE,
> +	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE + SZ_64M,
> +	.flags	= IORESOURCE_IO,
> +};

This is wrong: MCS8140_PCI_HOST_BASE is an address in IORESOURCE_MEM space.
You probably also mean SZ_64K instead of SZ_64M.

> +int __init pci_mcs8140_setup(int nr, struct pci_sys_data *sys)
> +{
> +	int ret = 0;
> +	u32 val;
> +
> +	if (nr > 0)
> +		return 0;
> +
> +	sys->mem_offset = MCS8140_PCI_IO_VIRT_BASE - MCS8140_PCI_IO_BASE;

Your address spaces are very confusing (or confused). So you have defined
#define MCS8140_PCI_IO_VIRT_BASE       (MCS814X_IO_BASE - \
                                        MCS8140_PCI_CONFIG_SIZE - \
                                        MCS8140_PCI_IOMISC_SIZE)
#define MCS8140_PCI_CFG_VIRT_BASE      (MCS814X_IO_BASE - \
                                        MCS8140_PCI_CONFIG_SIZE)


which means you mem_offset is (MCS814X_IO_BASE - MCS8140_PCI_CONFIG_SIZE -
MCS8140_PCI_IOMISC_SIZE) - (MCS814X_IO_BASE - MCS8140_PCI_CONFIG_SIZE)
which is (-MCS8140_PCI_IOMISC_SIZE), which in turn evaluates to
-SZ_64M or 0xfc000000. If that is the correct value, I'm sure it's
just coincidence ;-)

> +static int __init mcs8140_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> +{
> +	int line = IRQ_PCI_INTA;
> +
> +	if (pin != 0) {
> +		/* IRQ_PCIA - 22 */
> +		if (pin == PCI_INTD)
> +			line = IRQ_PCI_INTA + pin; /* IRQ_PCIA - 22 */
> +		else
> +			line = IRQ_PCI_INTA + pin - 1; /* IRQ_PCIA - 22 */
> +	}
> +
> +	pr_info("PCI: Map interrupt slot 0x%02x pin 0x%02x line 0x%02x\n",
> +		slot, pin, line);
> +
> +	return line;
> +}

This looks like a very unusual mapping. Maybe it's just wrong and that
explains why you don't support child buses or additional slots?

In any case, you should use an "interrupt-map" in the device tree that
describes how the IRQs are mapped to the slots. I think we have generic
code to deal with that already.

> +static struct map_desc mcs8140_pci_io_desc[] __initdata = {
> +	{
> +		.virtual	= MCS8140_PCI_CFG_VIRT_BASE,
> +		.pfn		= __phys_to_pfn(MCS8140_PCI_CFG_BASE),
> +		.length		= MCS8140_PCI_CONFIG_SIZE,
> +		.type		= MT_DEVICE
> +	},
> +	{
> +		.virtual	= MCS8140_PCI_IO_VIRT_BASE,
> +		.pfn		= __phys_to_pfn(MCS8140_PCI_IO_BASE),
> +		.length		= MCS8140_PCI_IOMISC_SIZE,
> +		.type		= MT_DEVICE
> +	},
> +};

Please have a look at the latest patches from Rob Herring about
mapping the I/O space. I don't think you need to map the config
space early because you don't rely on a fixed location for that.
Just use of_iomap() to find that and store the pointer to the
config space somewhere.

> +	pcibios_min_io = MCS8140_PCI_HOST_BASE;

Leave this one at the default of 0x1000. MCS8140_PCI_HOST_BASE is the
address from the CPU's point of view, not from the bus. You just need
to stay out of the range of possible legacy ISA devices.

It's probably a good idea to keep the PCI support as a separate patch
for reviewing purposes.

	Arnd

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-16 15:54       ` Arnd Bergmann
  0 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-16 15:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 15 July 2012, Florian Fainelli wrote:

> diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
> new file mode 100644
> index 0000000..c89422f
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/Kconfig
> @@ -0,0 +1,11 @@
> +if ARCH_MCS814X
> +
> +config MCS8140
> +	select CPU_ARM926T
> +	bool
> +
> +menu "Moschip MCS8140 boards"
> +
> +endmenu
> +
> +endif

What values does the Kconfig file actually provide? I see that you are
adding the boards here later, but I think it would be nice to just 
make the new platform a single Kconfig option with no individual
board selection.

> +struct clk {
> +	struct clk *parent;		/* parent clk */
> +	unsigned long rate;		/* clock rate in Hz */
> +	unsigned long divider;		/* clock divider */
> +	u32 usecount;			/* reference count */
> +	struct clk_ops *ops;		/* clock operation */
> +	u32 enable_reg;			/* clock enable register */
> +	u32 enable_mask;		/* clock enable mask */
> +};

Platforms are now converting to the common clock framework in drivers/clk.
Mike Turquette as the subsystem maintainer can probably judge better whether
we should still be allowing new platforms with their own implementation
of clk, but my feeling is that you should use the subsystem instead
and add a driver in a subdirectory of drivers/clk instead of in the
platform.

> +void __iomem *mcs814x_sysdbg_base;

Does this have to be globally visible? I would recommend making it static.

> +
> +struct cpu_mode {
> +	const char *name;
> +	int gpio_start;
> +	int gpio_end;
> +};
> +
> +static const struct cpu_mode cpu_modes[] = {
> +	{
> +		.name		= "I2S",
> +		.gpio_start	= 4,
> +		.gpio_end	= 8,
> +	},
> +	{
> +		.name		= "UART",
> +		.gpio_start	= 4,
> +		.gpio_end	= 9,
> +	},
> +	{
> +		.name		= "External MII",
> +		.gpio_start	= 0,
> +		.gpio_end	= 16,
> +	},
> +	{
> +		.name		= "Normal",
> +		.gpio_start	= -1,
> +		.gpio_end	= -1,
> +	},
> +};
> +
> +void __init mcs814x_init_machine(void)
> +{
> +	u32 bs2, cpu_mode;
> +	int gpio;
> +
> +	bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
> +	cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
> +
> +	pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
> +
> +	/* request the gpios since the pins are muxed for functionnality */
> +	for (gpio = cpu_modes[cpu_mode].gpio_start;
> +		gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
> +		if (gpio != -1)
> +			gpio_request(gpio, cpu_modes[cpu_mode].name);
> +	}
> +}

This looks like a very simple instance of a pinmux driver. I wonder
if it's worth doing an actual pinctrl driver that knows about these
modes and about the gpio handling of the platform. Maybe Linus Walleij
can comment on that.

How is the cpu mode managed? Is it hardwired through something like
strapping pins, or could you have a system that sets it dynamically
based on what hardware is being plugged in?

> +void __init mcs814x_map_io(void)
> +{
> +	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
> +
> +	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
> +					MCS814X_SYSDBG_SIZE);
> +	if (!mcs814x_sysdbg_base)
> +		panic("unable to remap sysdbg base");
> +}
> +
> +void mcs814x_restart(char mode, const char *cmd)
> +{
> +	__raw_writel(~(1 << 31), mcs814x_sysdbg_base);
> +}

You should generally avoid using __raw_readl etc. and instead use
readl/write or readl_relaxed/writel_relaxed.

> diff --git a/arch/arm/mach-mcs814x/common.h b/arch/arm/mach-mcs814x/common.h
> new file mode 100644
> index 0000000..e523abe
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/common.h
> @@ -0,0 +1,15 @@
> +#ifndef __ARCH_MCS814X_COMMON_H
> +#define __ARCH_MCS814X_COMMON_H
> +
> +#include <asm/mach/time.h>
> +
> +void mcs814x_map_io(void);
> +void mcs814x_clk_init(void);
> +void mcs814x_of_irq_init(void);
> +void mcs814x_init_machine(void);
> +void mcs814x_handle_irq(struct pt_regs *regs);
> +void mcs814x_restart(char mode, const char *cmd);
> +extern struct sys_timer mcs814x_timer;
> +extern void __iomem *mcs814x_sysdbg_base;
> +
> +#endif /* __ARCH_MCS814X_COMMON_H */

I think a lot of these don't actually need to be global if you combine some
of the files.


> diff --git a/arch/arm/mach-mcs814x/include/mach/cpu.h b/arch/arm/mach-mcs814x/include/mach/cpu.h
> new file mode 100644
> index 0000000..1ef3c4a
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/cpu.h
> @@ -0,0 +1,16 @@
> +#ifndef __ASM_ARCH_CPU_H__
> +#define __ASM_ARCH_CPU_H__
> +
> +#include <asm/cputype.h>
> +
> +#define MCS8140_ID	0x41069260	/* ARM926EJ-S */
> +#define MCS814X_MASK	0xff0ffff0
> +
> +#ifdef CONFIG_MCS8140
> +/* Moschip MCS8140 is based on an ARM926EJ-S core */
> +#define soc_is_mcs8140()	((read_cpuid_id() & MCS814X_MASK) == MCS8140_ID)
> +#else
> +#define soc_is_mcs8140()	(0)
> +#endif /* !CONFIG_MCS8140 */
> +
> +#endif /* __ASM_ARCH_CPU_H__ */

Can you explain what this is used for? Are there other SoCs in the same
platform that will get added later?

> diff --git a/arch/arm/mach-mcs814x/include/mach/hardware.h b/arch/arm/mach-mcs814x/include/mach/hardware.h
> new file mode 100644
> index 0000000..529f648
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/hardware.h
> @@ -0,0 +1,16 @@
> +/*
> + * Copyright (C) 2003 Artec Design Ltd.
> + *
> + * 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 __ASM_ARCH_HARDWARE_H
> +#define __ASM_ARCH_HARDWARE_H
> +
> +#include "mcs814x.h"
> +
> +#endif

I'd just make this an empty file, like gpio.h. That will let us kill off
these files more easily in the future.

> diff --git a/arch/arm/mach-mcs814x/include/mach/irqs.h b/arch/arm/mach-mcs814x/include/mach/irqs.h
> new file mode 100644
> index 0000000..78021d1
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/irqs.h
> @@ -0,0 +1,22 @@
> +/*
> + * Copyright (C) 2003 Artec Design Ltd.
> + *
> + * 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 __ASM_ARCH_IRQS_H
> +#define __ASM_ARCH_IRQS_H
> +
> +#define FIQ_START	0

Why do you need the FIQ_START macro here?

> +#define NR_IRQS		32
> +
> +#define IRQ_PCI_INTA            22
> +#define IRQ_PCI_INTB            23
> +#define IRQ_PCI_INTC            24
> +#define IRQ_PCI_INTD            26

The PCI interrupts should come from the device tree.

You should also select CONFIG_SPARSE_IRQ unconditionally and use IRQ domains
so that you no longer need to set NR_IRQS.

> diff --git a/arch/arm/mach-mcs814x/include/mach/mcs814x.h b/arch/arm/mach-mcs814x/include/mach/mcs814x.h
> new file mode 100644
> index 0000000..a4a369e
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/mcs814x.h
> @@ -0,0 +1,53 @@
> +/*
> + * Copyright (C) 2003 Artec Design Ltd.
> + *
> + * 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 __ASM_ARCH_MCS814X_H
> +#define __ASM_ARCH_MCS814X_H
> +
> +#define MCS814X_IO_BASE		0xF0000000
> +#define MCS814X_IO_START	0x40000000
> +#define MCS814X_IO_SIZE		0x00100000

What are these required for in the global space? Can you move them into
a single .c file?

> +/* IRQ controller register offset */
> +#define MCS814X_IRQ_ICR		0x00
> +#define MCS814X_IRQ_ISR		0x04
> +#define MCS814X_IRQ_MASK	0x20
> +#define MCS814X_IRQ_STS0	0x40

I'm pretty sure these can be in irq.c

> +#define MCS814X_PHYS_BASE	0x40000000
> +#define MCS814X_VIRT_BASE	MCS814X_IO_BASE
> +
> +#define MCS814X_UART		0x000DC000
> +#define MCS814X_DBGLED		0x000EC000
> +#define MCS814X_SYSDBG		0x000F8000
> +#define MCS814X_SYSDBG_SIZE	0x50
> +
> +/* System configuration and bootstrap registers */
> +#define SYSDBG_BS1		0x00
> +#define  CPU_FREQ_SHIFT		27
> +#define  CPU_FREQ_MASK		0x0F
> +#define  SDRAM_FREQ_BIT		(1 << 22)
> +
> +#define SYSDBG_BS2		0x04
> +#define  LED_CFG_MASK		0x03
> +#define  CPU_MODE_SHIFT		23
> +#define  CPU_MODE_MASK		0x03
> +
> +#define SYSDBG_SYSCTL_MAC	0x1d
> +#define  BUF_SHIFT_BIT		(1 << 0)
> +
> +#define SYSDBG_SYSCTL		0x08
> +#define  SYSCTL_EMAC		(1 << 0)
> +#define  SYSCTL_EPHY		(1 << 0) /* active low */
> +#define  SYSCTL_CIPHER		(1 << 16)
> +
> +#define SYSDBG_PLL_CTL		0x3C

The sysdbg stuff can probably go into a file that deals
with the sysdbg registers and exports a high-level interface.

> +
> +void __iomem *mcs814x_intc_base;

static?

> +#define MCS8140_PCI_HOST_BASE           0x80000000
> +#define MCS8140_PCI_IOMISC_BASE         0x00000000
> +#define MCS8140_PCI_PRE_BASE            0x10000000
> +#define MCS8140_PCI_NONPRE_BASE         0x30000000
> +
> +#define MCS8140_PCI_CFG_BASE		(MCS8140_PCI_HOST_BASE + 0x04000000)
> +#define MCS8140_PCI_IO_BASE		(MCS8140_PCI_HOST_BASE)
> +
> +#define MCS8140_PCI_IO_VIRT_BASE	(MCS814X_IO_BASE - \
> +					 MCS8140_PCI_CONFIG_SIZE - \
> +					 MCS8140_PCI_IOMISC_SIZE)
> +#define MCS8140_PCI_CFG_VIRT_BASE	(MCS814X_IO_BASE - \
> +					 MCS8140_PCI_CONFIG_SIZE)


> +static unsigned long __pci_addr(struct pci_bus *bus,
> +				unsigned int devfn, int offset)
> +{
> +	unsigned int busnr = bus->number;
> +	unsigned int slot;
> +
> +	/* we only support bus 0 */
> +	if (busnr != 0)
> +		return 0;

Why? A lot of devices have bridges on them and they should just
work if you take out this check.

> +	/*
> +	 * Trap out illegal values
> +	 */
> +	BUG_ON(devfn > 255 || busnr > 255 || devfn > 255);

You're checking devfn twice...

> +	/* Scan 3 slots */
> +	slot = PCI_SLOT(devfn);
> +	switch (slot) {
> +	case 1:
> +	case 2:
> +	case 3:
> +		if (PCI_FUNC(devfn) >= 4)
> +			return 0;

This also looks bogus. Why limit it to three devices?

> +static int mcs8140_pci_read_config(struct pci_bus *bus,
> +					unsigned int devfn, int where,
> +					int size, u32 *val)
> +{
> +	unsigned long v = 0xFFFFFFFF;
> +	unsigned long addr = __pci_addr(bus, devfn, where);
> +
> +	if (addr != 0) {
> +		switch (size) {
> +		case 1:
> +			v = __raw_readb(addr);
> +			break;
> +		case 2:
> +			addr &= ~1;
> +			v = __raw_readw(addr);
> +			break;
> +		default:
> +			addr &= ~3;
> +			v = __raw_readl(addr);
> +			break;
> +		}
> +	} else
> +		v = 0xffffffff;

This is just mmconfig, right? Don't we have a generic implementation for that?

> +
> +static struct resource io_mem = {
> +	.name	= "PCI I/O space",
> +	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE,
> +	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE + SZ_64M,
> +	.flags	= IORESOURCE_IO,
> +};

This is wrong: MCS8140_PCI_HOST_BASE is an address in IORESOURCE_MEM space.
You probably also mean SZ_64K instead of SZ_64M.

> +int __init pci_mcs8140_setup(int nr, struct pci_sys_data *sys)
> +{
> +	int ret = 0;
> +	u32 val;
> +
> +	if (nr > 0)
> +		return 0;
> +
> +	sys->mem_offset = MCS8140_PCI_IO_VIRT_BASE - MCS8140_PCI_IO_BASE;

Your address spaces are very confusing (or confused). So you have defined
#define MCS8140_PCI_IO_VIRT_BASE       (MCS814X_IO_BASE - \
                                        MCS8140_PCI_CONFIG_SIZE - \
                                        MCS8140_PCI_IOMISC_SIZE)
#define MCS8140_PCI_CFG_VIRT_BASE      (MCS814X_IO_BASE - \
                                        MCS8140_PCI_CONFIG_SIZE)


which means you mem_offset is (MCS814X_IO_BASE - MCS8140_PCI_CONFIG_SIZE -
MCS8140_PCI_IOMISC_SIZE) - (MCS814X_IO_BASE - MCS8140_PCI_CONFIG_SIZE)
which is (-MCS8140_PCI_IOMISC_SIZE), which in turn evaluates to
-SZ_64M or 0xfc000000. If that is the correct value, I'm sure it's
just coincidence ;-)

> +static int __init mcs8140_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> +{
> +	int line = IRQ_PCI_INTA;
> +
> +	if (pin != 0) {
> +		/* IRQ_PCIA - 22 */
> +		if (pin == PCI_INTD)
> +			line = IRQ_PCI_INTA + pin; /* IRQ_PCIA - 22 */
> +		else
> +			line = IRQ_PCI_INTA + pin - 1; /* IRQ_PCIA - 22 */
> +	}
> +
> +	pr_info("PCI: Map interrupt slot 0x%02x pin 0x%02x line 0x%02x\n",
> +		slot, pin, line);
> +
> +	return line;
> +}

This looks like a very unusual mapping. Maybe it's just wrong and that
explains why you don't support child buses or additional slots?

In any case, you should use an "interrupt-map" in the device tree that
describes how the IRQs are mapped to the slots. I think we have generic
code to deal with that already.

> +static struct map_desc mcs8140_pci_io_desc[] __initdata = {
> +	{
> +		.virtual	= MCS8140_PCI_CFG_VIRT_BASE,
> +		.pfn		= __phys_to_pfn(MCS8140_PCI_CFG_BASE),
> +		.length		= MCS8140_PCI_CONFIG_SIZE,
> +		.type		= MT_DEVICE
> +	},
> +	{
> +		.virtual	= MCS8140_PCI_IO_VIRT_BASE,
> +		.pfn		= __phys_to_pfn(MCS8140_PCI_IO_BASE),
> +		.length		= MCS8140_PCI_IOMISC_SIZE,
> +		.type		= MT_DEVICE
> +	},
> +};

Please have a look at the latest patches from Rob Herring about
mapping the I/O space. I don't think you need to map the config
space early because you don't rely on a fixed location for that.
Just use of_iomap() to find that and store the pointer to the
config space somewhere.

> +	pcibios_min_io = MCS8140_PCI_HOST_BASE;

Leave this one at the default of 0x1000. MCS8140_PCI_HOST_BASE is the
address from the CPU's point of view, not from the bus. You just need
to stay out of the range of possible legacy ISA devices.

It's probably a good idea to keep the PCI support as a separate patch
for reviewing purposes.

	Arnd

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-16 12:43       ` Florian Fainelli
@ 2012-07-16 15:55         ` Arnd Bergmann
  -1 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-16 15:55 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Thomas Petazzoni, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Monday 16 July 2012, Florian Fainelli wrote:
> > 
> > > +#define IRQ_PCI_INTA            22
> > > +#define IRQ_PCI_INTB            23
> > > +#define IRQ_PCI_INTC            24
> > > +#define IRQ_PCI_INTD            26
> > 
> > And these probably belong to the DT somehow?
> 
> This would need a complete PCI irq mapping representation, so far we have the 
> DT properties, but not the corresponding code to parse them. I would not 
> qualify this as a major blocker.

Your map_irq function looks broken for anything but the PCI cards
you actually tested, so I think it's better to use the common code
for parsing the DT here.

	Arnd

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-16 15:55         ` Arnd Bergmann
  0 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-16 15:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 16 July 2012, Florian Fainelli wrote:
> > 
> > > +#define IRQ_PCI_INTA            22
> > > +#define IRQ_PCI_INTB            23
> > > +#define IRQ_PCI_INTC            24
> > > +#define IRQ_PCI_INTD            26
> > 
> > And these probably belong to the DT somehow?
> 
> This would need a complete PCI irq mapping representation, so far we have the 
> DT properties, but not the corresponding code to parse them. I would not 
> qualify this as a major blocker.

Your map_irq function looks broken for anything but the PCI cards
you actually tested, so I think it's better to use the common code
for parsing the DT here.

	Arnd

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-16 12:43       ` Florian Fainelli
@ 2012-07-16 17:57         ` Nicolas Pitre
  -1 siblings, 0 replies; 80+ messages in thread
From: Nicolas Pitre @ 2012-07-16 17:57 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Thomas Petazzoni, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

[-- Attachment #1: Type: TEXT/PLAIN, Size: 875 bytes --]

On Mon, 16 Jul 2012, Florian Fainelli wrote:

> Hi Thomas,
> 
> On Monday 16 July 2012 14:29:41 Thomas Petazzoni wrote:
> > Hello Florian,
> > 
> > Le Sun, 15 Jul 2012 16:49:07 +0200,
> > Florian Fainelli <florian-p3rKhJxN3npAfugRpC6u6w@public.gmane.org> a écrit :
> > 
> > > diff --git a/arch/arm/mach-mcs814x/Makefile.boot b/arch/arm/mach-
> mcs814x/Makefile.boot
> > > new file mode 100644
> > > index 0000000..414db8b
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mcs814x/Makefile.boot
> > > @@ -0,0 +1,3 @@
> > > +    zreladdr-y := 0x00008000
> > > + params_phys-y := 0x00000008
> > > + initrd_phys-y := 0x00400000
> > 
> > params_phys-y and initrd_phys-y are useless for DT-based platforms, if
> > I'm correct.
> 
> Indeed, only zreladdr is actually required.

If you use CONFIG_AUTO_ZRELADDR then even zreladdr-y isn't needed.


Nicolas

[-- Attachment #2: Type: text/plain, Size: 192 bytes --]

_______________________________________________
devicetree-discuss mailing list
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-16 17:57         ` Nicolas Pitre
  0 siblings, 0 replies; 80+ messages in thread
From: Nicolas Pitre @ 2012-07-16 17:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 16 Jul 2012, Florian Fainelli wrote:

> Hi Thomas,
> 
> On Monday 16 July 2012 14:29:41 Thomas Petazzoni wrote:
> > Hello Florian,
> > 
> > Le Sun, 15 Jul 2012 16:49:07 +0200,
> > Florian Fainelli <florian@openwrt.org> a ?crit :
> > 
> > > diff --git a/arch/arm/mach-mcs814x/Makefile.boot b/arch/arm/mach-
> mcs814x/Makefile.boot
> > > new file mode 100644
> > > index 0000000..414db8b
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mcs814x/Makefile.boot
> > > @@ -0,0 +1,3 @@
> > > +    zreladdr-y := 0x00008000
> > > + params_phys-y := 0x00000008
> > > + initrd_phys-y := 0x00400000
> > 
> > params_phys-y and initrd_phys-y are useless for DT-based platforms, if
> > I'm correct.
> 
> Indeed, only zreladdr is actually required.

If you use CONFIG_AUTO_ZRELADDR then even zreladdr-y isn't needed.


Nicolas

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

* Re: [PATCH 0/8] ARM: support for Moschip MCS814x SoCs
  2012-07-15 19:59     ` Arnd Bergmann
@ 2012-07-16 18:09         ` Nicolas Pitre
  -1 siblings, 0 replies; 80+ messages in thread
From: Nicolas Pitre @ 2012-07-16 18:09 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Florian Fainelli,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Sun, 15 Jul 2012, Arnd Bergmann wrote:

> On Sunday 15 July 2012, Florian Fainelli wrote:
> > This patchset adds basic support for Mocship MCS814x, and in particular
> > MCS8140, and allows one booting to user space. Two off-the-shelf boards
> > are support: Tigal/Robotech RBT-832 and Devolo dLAN USB Extender.
> > 
> > Support for other on-board peripherals will obviously be contributed later
> > once the basic SoC support has been accepted.
> 
> Hi Florian,
> 
> This looks quite nice at first sight, but I have to say that your timing
> is rather unfortunate. We're getting rather close to the 3.6 merge window,
> so there is not much time to review the platform thoroughly before that
> and I'd feel more comfortable about putting it into 3.7. I'll let others
> weigh in, too. At least there is no risk of regressions for a new platform
> getting added, so if other people think we should take it for 3.5, I might
> get convinced.

You should take it if no apparent issues are found.  As you say, this 
might even be broken and no one else would be affected.  The only 
reasons I would not push it upstream are about the code i.e if the code 
causes merge conflicts, isn't up to date with the latest kernel 
infrastructures or has coding style issues, etc.


Nicolas

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

* [PATCH 0/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-16 18:09         ` Nicolas Pitre
  0 siblings, 0 replies; 80+ messages in thread
From: Nicolas Pitre @ 2012-07-16 18:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, 15 Jul 2012, Arnd Bergmann wrote:

> On Sunday 15 July 2012, Florian Fainelli wrote:
> > This patchset adds basic support for Mocship MCS814x, and in particular
> > MCS8140, and allows one booting to user space. Two off-the-shelf boards
> > are support: Tigal/Robotech RBT-832 and Devolo dLAN USB Extender.
> > 
> > Support for other on-board peripherals will obviously be contributed later
> > once the basic SoC support has been accepted.
> 
> Hi Florian,
> 
> This looks quite nice at first sight, but I have to say that your timing
> is rather unfortunate. We're getting rather close to the 3.6 merge window,
> so there is not much time to review the platform thoroughly before that
> and I'd feel more comfortable about putting it into 3.7. I'll let others
> weigh in, too. At least there is no risk of regressions for a new platform
> getting added, so if other people think we should take it for 3.5, I might
> get convinced.

You should take it if no apparent issues are found.  As you say, this 
might even be broken and no one else would be affected.  The only 
reasons I would not push it upstream are about the code i.e if the code 
causes merge conflicts, isn't up to date with the latest kernel 
infrastructures or has coding style issues, etc.


Nicolas

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-16 15:54       ` Arnd Bergmann
@ 2012-07-16 20:47           ` Turquette, Mike
  -1 siblings, 0 replies; 80+ messages in thread
From: Turquette, Mike @ 2012-07-16 20:47 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Florian Fainelli

On Mon, Jul 16, 2012 at 8:54 AM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Sunday 15 July 2012, Florian Fainelli wrote:
>
>> diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
>> new file mode 100644
>> index 0000000..c89422f
>> --- /dev/null
>> +++ b/arch/arm/mach-mcs814x/Kconfig
>> @@ -0,0 +1,11 @@
>> +if ARCH_MCS814X
>> +
>> +config MCS8140
>> +     select CPU_ARM926T
>> +     bool
>> +
>> +menu "Moschip MCS8140 boards"
>> +
>> +endmenu
>> +
>> +endif
>
> What values does the Kconfig file actually provide? I see that you are
> adding the boards here later, but I think it would be nice to just
> make the new platform a single Kconfig option with no individual
> board selection.
>
>> +struct clk {
>> +     struct clk *parent;             /* parent clk */
>> +     unsigned long rate;             /* clock rate in Hz */
>> +     unsigned long divider;          /* clock divider */
>> +     u32 usecount;                   /* reference count */
>> +     struct clk_ops *ops;            /* clock operation */
>> +     u32 enable_reg;                 /* clock enable register */
>> +     u32 enable_mask;                /* clock enable mask */
>> +};
>
> Platforms are now converting to the common clock framework in drivers/clk.
> Mike Turquette as the subsystem maintainer can probably judge better whether
> we should still be allowing new platforms with their own implementation
> of clk, but my feeling is that you should use the subsystem instead
> and add a driver in a subdirectory of drivers/clk instead of in the
> platform.

Hi Florian & Arnd,

Adopting the new clock framework is highly preferable, especially if
MCS814x support is being delayed until 3.7.  There is also a push to
put clock drivers into drivers/clk and I would like to continue that
trend, but I'm less strict on that measure if it proves very difficult
for your platform immediately (e.g. duplicating headers across
platform and generic code, etc).  Migrating code from arch/arm to
drivers/clk can always be done in a future series.

This platform also seems to be making use of DT so it would be very
nice if we use MCS814x to push the state of clk DT bindings and
adoption forward a bit.  There are not a lot of folks using the
patches from Rob/Grant today.  Hopefully delaying these patches by
another merge cycle means that these requests are not asking too much
:-)

Regards,
Mike

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-16 20:47           ` Turquette, Mike
  0 siblings, 0 replies; 80+ messages in thread
From: Turquette, Mike @ 2012-07-16 20:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 16, 2012 at 8:54 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Sunday 15 July 2012, Florian Fainelli wrote:
>
>> diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
>> new file mode 100644
>> index 0000000..c89422f
>> --- /dev/null
>> +++ b/arch/arm/mach-mcs814x/Kconfig
>> @@ -0,0 +1,11 @@
>> +if ARCH_MCS814X
>> +
>> +config MCS8140
>> +     select CPU_ARM926T
>> +     bool
>> +
>> +menu "Moschip MCS8140 boards"
>> +
>> +endmenu
>> +
>> +endif
>
> What values does the Kconfig file actually provide? I see that you are
> adding the boards here later, but I think it would be nice to just
> make the new platform a single Kconfig option with no individual
> board selection.
>
>> +struct clk {
>> +     struct clk *parent;             /* parent clk */
>> +     unsigned long rate;             /* clock rate in Hz */
>> +     unsigned long divider;          /* clock divider */
>> +     u32 usecount;                   /* reference count */
>> +     struct clk_ops *ops;            /* clock operation */
>> +     u32 enable_reg;                 /* clock enable register */
>> +     u32 enable_mask;                /* clock enable mask */
>> +};
>
> Platforms are now converting to the common clock framework in drivers/clk.
> Mike Turquette as the subsystem maintainer can probably judge better whether
> we should still be allowing new platforms with their own implementation
> of clk, but my feeling is that you should use the subsystem instead
> and add a driver in a subdirectory of drivers/clk instead of in the
> platform.

Hi Florian & Arnd,

Adopting the new clock framework is highly preferable, especially if
MCS814x support is being delayed until 3.7.  There is also a push to
put clock drivers into drivers/clk and I would like to continue that
trend, but I'm less strict on that measure if it proves very difficult
for your platform immediately (e.g. duplicating headers across
platform and generic code, etc).  Migrating code from arch/arm to
drivers/clk can always be done in a future series.

This platform also seems to be making use of DT so it would be very
nice if we use MCS814x to push the state of clk DT bindings and
adoption forward a bit.  There are not a lot of folks using the
patches from Rob/Grant today.  Hopefully delaying these patches by
another merge cycle means that these requests are not asking too much
:-)

Regards,
Mike

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-15 14:49   ` Florian Fainelli
@ 2012-07-16 22:06       ` Linus Walleij
  -1 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-07-16 22:06 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, John Stultz,
	Thomas Gleixner,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Mike Turquette

On Sun, Jul 15, 2012 at 4:49 PM, Florian Fainelli <florian-p3rKhJxN3npAfugRpC6u6w@public.gmane.org> wrote:

> diff --git a/arch/arm/mach-mcs814x/clock.c b/arch/arm/mach-mcs814x/clock.c

As mentioned by other reviewers, move this to the new common
clock framework. I just migrated the Integrator, Nomadik and U300
for the v3.7 merge window, we need to get rid of these
implementations, not make more of them.

> diff --git a/arch/arm/mach-mcs814x/common.c b/arch/arm/mach-mcs814x/common.c

Usually this kind of file is called "core.c".

> +void __init mcs814x_init_machine(void)
> +{
> +       u32 bs2, cpu_mode;
> +       int gpio;
> +
> +       bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
> +       cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
> +
> +       pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
> +
> +       /* request the gpios since the pins are muxed for functionnality */
> +       for (gpio = cpu_modes[cpu_mode].gpio_start;
> +               gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
> +               if (gpio != -1)
> +                       gpio_request(gpio, cpu_modes[cpu_mode].name);
> +       }
> +}

What is this? It is looking very suspiciouly much like a pin multiplexer,
which means it should have a driver in drivers/pinctrl/pinctrl-foo.c not
in arch/arm/*.

I do understand it is just a small hack to make things work, but I fear
it is going to grow and then it sets a bad example.

This version looks like switching some I2S, GPIO and UART and that's
all, but I highly suspect that is not the whole story, is it? Better
to get it in right shape from the start.

> diff --git a/arch/arm/mach-mcs814x/irq.c b/arch/arm/mach-mcs814x/irq.c
> new file mode 100644
> index 0000000..089937b
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/irq.c
(...)
> +       /* Clear all interrupts */
> +       __raw_writel(0xffffffff, base + MCS814X_IRQ_ICR);

Consider writel_relaxed()

> diff --git a/arch/arm/mach-mcs814x/include/mach/entry-macro.S b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
> new file mode 100644
> index 0000000..cbad566
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
> @@ -0,0 +1,29 @@
> +#include <mach/mcs814x.h>
> +                .macro  disable_fiq
> +                .endm
> +
> +               .macro arch_ret_to_user, tmp1, tmp2
> +               .endm
> +
> +               .macro  get_irqnr_preamble, base, tmp
> +               ldr     \base, =mcs814x_intc_base@ base virtual address of INTC
> +               ldr     \base, [\base]
> +               .endm
> +
> +               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
> +               mov     \tmp, #MCS814X_IRQ_STS0  @ load tmp with STS0 register offset
> +               ldr     \irqstat, [\base, \tmp]  @ load value at base + tmp
> +               tst     \irqstat, \irqstat       @ test if no active IRQ's
> +               beq     1002f                    @ if no active irqs return with status 0
> +               mov     \irqnr, #0               @ start from irq zero
> +               mov     \tmp,   #1               @ the mask initially 1
> +1001:
> +               tst     \irqstat, \tmp           @ and with mask
> +               addeq   \irqnr, \irqnr, #1       @ if  zero then add one to nr
> +               moveq   \tmp,   \tmp, lsl #1     @ shift mask one to left
> +               beq     1001b                    @ if  zero then loop again
> +               mov     \irqstat, \tmp           @ save the return mask
> +               mov     \tmp, #MCS814X_IRQ_STS0  @ load tmp with ICR offset
> +               str     \irqstat,  [\base, \tmp] @ clear irq with selected mask
> +1002:
> +                .endm

Don't do this. Delete this file.

Let your platform select MULTI_IRQ_HANDLER
Then let your platform MACHINE_START (or DT_MACHINE_START)
have a .handle_irq member, calling a function from your interrupt controller
driver to handle the IRQs.

Add some
asmlinkage void __exception_irq_entry foo_handle_irq(struct pt_regs *regs)

And rewrite the entry handler in plain C.

Refer to for example the rewrite I do of the FPGA IRQ controller in commit
3108e6ab21a9b9dbd88f0b2ff99f73e95b8b1580 or directly to
arch/arm/plat-versatile/fpga-irq.c or
arch/arm/common/vic.c for an example.

> diff --git a/arch/arm/mach-mcs814x/timer.c b/arch/arm/mach-mcs814x/timer.c

A timer driver not #including <linux/clockchips.h> and <linux/clocksource.h>
is a real bad idea.

(...)
> +static inline unsigned long ticks2usecs(u32 x)
> +{
> +       return x / (clock_rate / 1000000);
> +}
> +
> +/*
> + * Returns number of ms since last clock interrupt.  Note that interrupts
> + * will have been disabled by do_gettimeoffset()
> + */
> +static unsigned long mcs814x_gettimeoffset(void)
> +{
> +       u32 ticks = __raw_readl(mcs814x_timer_base + TIMER_VAL);
> +
> +       if (ticks < last_reload)
> +               return ticks2usecs(ticks + (u32)(0xffffffff - last_reload));
> +       else
> +               return ticks2usecs(ticks - last_reload);
> +}

This is not looking good. Don't handle ticks -> usec conversion in the
driver.

> +static irqreturn_t mcs814x_timer_interrupt(int irq, void *dev_id)
> +{
> +       u32 count = __raw_readl(mcs814x_timer_base + TIMER_VAL);
> +
> +       /* take into account delay up to this moment */
> +       last_reload = count + timer_correct + timer_reload_value;
> +
> +       if (last_reload < timer_reload_value)
> +               last_reload = timer_reload_value;
> +       else if (timer_correct == 0)
> +               timer_correct = __raw_readl(mcs814x_timer_base + TIMER_VAL) -
> +                                       count;

Don't do this. Let the timer infrastructure take care of these
things.

> +       __raw_writel(last_reload, mcs814x_timer_base + TIMER_VAL);
> +
> +       timer_tick();

Only archaic and bad example platforms call timer_tick() directly.
Use the clockevent API.

> +
> +       return IRQ_HANDLED;
> +}
> +
> +static struct irqaction mcs814x_timer_irq = {
> +       .name           = "mcs814x-timer",
> +       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
> +       .handler        = mcs814x_timer_interrupt,
> +};
> +
> +static struct of_device_id mcs814x_timer_ids[] = {
> +       { .compatible = "moschip,mcs814x-timer" },
> +       { /* sentinel */ },
> +};
> +
> +static void __init mcs814x_of_timer_init(void)
> +{
> +       struct device_node *np;
> +       const unsigned int *intspec;
> +
> +       np = of_find_matching_node(NULL, mcs814x_timer_ids);
> +       if (!np)
> +               panic("unable to find compatible timer node in dtb");
> +
> +       mcs814x_timer_base = of_iomap(np, 0);
> +       if (!mcs814x_timer_base)
> +               panic("unable to remap timer cpu registers");
> +
> +       intspec = of_get_property(np, "interrupts", NULL);
> +       if (!intspec)
> +               panic("no interrupts property for timer");
> +
> +       mcs814x_timer_irq.irq = be32_to_cpup(intspec);

Why are you getting and converting this from bigendian?

What is wrong with using irq_of_parse_and_map(np, 0) for this, this
just looks dangerous.

> +}
> +
> +static void __init mcs814x_timer_init(void)
> +{
> +       struct clk *clk;
> +
> +       clk = clk_get_sys("timer0", NULL);
> +       if (IS_ERR_OR_NULL(clk))
> +               panic("unable to get timer0 clock");

clk_prepare_enable() is needed at this point.

> +
> +       clock_rate = clk_get_rate(clk);
> +       clk_put(clk);

Don't put the clock here, you're using it, perpetually. If you
put() it the clock framework can disable it at as unused.

> +
> +       mcs814x_of_timer_init();
> +
> +       pr_info("Timer frequency: %d (kHz)\n", clock_rate / 1000);
> +
> +       timer_reload_value = 0xffffffff - (clock_rate / HZ);
> +
> +       /* disable timer */
> +       __raw_writel(0, mcs814x_timer_base + TIMER_CTL);
> +       __raw_writel(timer_reload_value, mcs814x_timer_base + TIMER_VAL);
> +       last_reload = timer_reload_value;
> +
> +       setup_irq(mcs814x_timer_irq.irq, &mcs814x_timer_irq);
> +       /* enable timer, stop timer in debug mode */
> +       __raw_writel(0x03, mcs814x_timer_base + TIMER_CTL);
> +}
> +
> +struct sys_timer mcs814x_timer = {
> +       .init   = mcs814x_timer_init,
> +       .offset = mcs814x_gettimeoffset,
> +};

No .offset and rewrite this to register a clock source+clock event
and use that instead.

Please look at arch/arm/common/timer-sp.c for a good example
of how a timer driver should look.

You will feel it's much more elegant afterwards :-)

What might be complicated is that it appears you have only one
single timer in your system, is that reallty the case? Usually
Linux fires one timer to just "run free" to be used as cycle counter
(clock source) and another one to "shoot events" (clock event)

I've never seen one and the same timer being used for both
clock source and clock events but if you really have only one
timer I think that is also feasible, but will need some serious
hacking.

Yours,
Linus Walleij

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-16 22:06       ` Linus Walleij
  0 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-07-16 22:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jul 15, 2012 at 4:49 PM, Florian Fainelli <florian@openwrt.org> wrote:

> diff --git a/arch/arm/mach-mcs814x/clock.c b/arch/arm/mach-mcs814x/clock.c

As mentioned by other reviewers, move this to the new common
clock framework. I just migrated the Integrator, Nomadik and U300
for the v3.7 merge window, we need to get rid of these
implementations, not make more of them.

> diff --git a/arch/arm/mach-mcs814x/common.c b/arch/arm/mach-mcs814x/common.c

Usually this kind of file is called "core.c".

> +void __init mcs814x_init_machine(void)
> +{
> +       u32 bs2, cpu_mode;
> +       int gpio;
> +
> +       bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
> +       cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
> +
> +       pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
> +
> +       /* request the gpios since the pins are muxed for functionnality */
> +       for (gpio = cpu_modes[cpu_mode].gpio_start;
> +               gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
> +               if (gpio != -1)
> +                       gpio_request(gpio, cpu_modes[cpu_mode].name);
> +       }
> +}

What is this? It is looking very suspiciouly much like a pin multiplexer,
which means it should have a driver in drivers/pinctrl/pinctrl-foo.c not
in arch/arm/*.

I do understand it is just a small hack to make things work, but I fear
it is going to grow and then it sets a bad example.

This version looks like switching some I2S, GPIO and UART and that's
all, but I highly suspect that is not the whole story, is it? Better
to get it in right shape from the start.

> diff --git a/arch/arm/mach-mcs814x/irq.c b/arch/arm/mach-mcs814x/irq.c
> new file mode 100644
> index 0000000..089937b
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/irq.c
(...)
> +       /* Clear all interrupts */
> +       __raw_writel(0xffffffff, base + MCS814X_IRQ_ICR);

Consider writel_relaxed()

> diff --git a/arch/arm/mach-mcs814x/include/mach/entry-macro.S b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
> new file mode 100644
> index 0000000..cbad566
> --- /dev/null
> +++ b/arch/arm/mach-mcs814x/include/mach/entry-macro.S
> @@ -0,0 +1,29 @@
> +#include <mach/mcs814x.h>
> +                .macro  disable_fiq
> +                .endm
> +
> +               .macro arch_ret_to_user, tmp1, tmp2
> +               .endm
> +
> +               .macro  get_irqnr_preamble, base, tmp
> +               ldr     \base, =mcs814x_intc_base@ base virtual address of INTC
> +               ldr     \base, [\base]
> +               .endm
> +
> +               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
> +               mov     \tmp, #MCS814X_IRQ_STS0  @ load tmp with STS0 register offset
> +               ldr     \irqstat, [\base, \tmp]  @ load value at base + tmp
> +               tst     \irqstat, \irqstat       @ test if no active IRQ's
> +               beq     1002f                    @ if no active irqs return with status 0
> +               mov     \irqnr, #0               @ start from irq zero
> +               mov     \tmp,   #1               @ the mask initially 1
> +1001:
> +               tst     \irqstat, \tmp           @ and with mask
> +               addeq   \irqnr, \irqnr, #1       @ if  zero then add one to nr
> +               moveq   \tmp,   \tmp, lsl #1     @ shift mask one to left
> +               beq     1001b                    @ if  zero then loop again
> +               mov     \irqstat, \tmp           @ save the return mask
> +               mov     \tmp, #MCS814X_IRQ_STS0  @ load tmp with ICR offset
> +               str     \irqstat,  [\base, \tmp] @ clear irq with selected mask
> +1002:
> +                .endm

Don't do this. Delete this file.

Let your platform select MULTI_IRQ_HANDLER
Then let your platform MACHINE_START (or DT_MACHINE_START)
have a .handle_irq member, calling a function from your interrupt controller
driver to handle the IRQs.

Add some
asmlinkage void __exception_irq_entry foo_handle_irq(struct pt_regs *regs)

And rewrite the entry handler in plain C.

Refer to for example the rewrite I do of the FPGA IRQ controller in commit
3108e6ab21a9b9dbd88f0b2ff99f73e95b8b1580 or directly to
arch/arm/plat-versatile/fpga-irq.c or
arch/arm/common/vic.c for an example.

> diff --git a/arch/arm/mach-mcs814x/timer.c b/arch/arm/mach-mcs814x/timer.c

A timer driver not #including <linux/clockchips.h> and <linux/clocksource.h>
is a real bad idea.

(...)
> +static inline unsigned long ticks2usecs(u32 x)
> +{
> +       return x / (clock_rate / 1000000);
> +}
> +
> +/*
> + * Returns number of ms since last clock interrupt.  Note that interrupts
> + * will have been disabled by do_gettimeoffset()
> + */
> +static unsigned long mcs814x_gettimeoffset(void)
> +{
> +       u32 ticks = __raw_readl(mcs814x_timer_base + TIMER_VAL);
> +
> +       if (ticks < last_reload)
> +               return ticks2usecs(ticks + (u32)(0xffffffff - last_reload));
> +       else
> +               return ticks2usecs(ticks - last_reload);
> +}

This is not looking good. Don't handle ticks -> usec conversion in the
driver.

> +static irqreturn_t mcs814x_timer_interrupt(int irq, void *dev_id)
> +{
> +       u32 count = __raw_readl(mcs814x_timer_base + TIMER_VAL);
> +
> +       /* take into account delay up to this moment */
> +       last_reload = count + timer_correct + timer_reload_value;
> +
> +       if (last_reload < timer_reload_value)
> +               last_reload = timer_reload_value;
> +       else if (timer_correct == 0)
> +               timer_correct = __raw_readl(mcs814x_timer_base + TIMER_VAL) -
> +                                       count;

Don't do this. Let the timer infrastructure take care of these
things.

> +       __raw_writel(last_reload, mcs814x_timer_base + TIMER_VAL);
> +
> +       timer_tick();

Only archaic and bad example platforms call timer_tick() directly.
Use the clockevent API.

> +
> +       return IRQ_HANDLED;
> +}
> +
> +static struct irqaction mcs814x_timer_irq = {
> +       .name           = "mcs814x-timer",
> +       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
> +       .handler        = mcs814x_timer_interrupt,
> +};
> +
> +static struct of_device_id mcs814x_timer_ids[] = {
> +       { .compatible = "moschip,mcs814x-timer" },
> +       { /* sentinel */ },
> +};
> +
> +static void __init mcs814x_of_timer_init(void)
> +{
> +       struct device_node *np;
> +       const unsigned int *intspec;
> +
> +       np = of_find_matching_node(NULL, mcs814x_timer_ids);
> +       if (!np)
> +               panic("unable to find compatible timer node in dtb");
> +
> +       mcs814x_timer_base = of_iomap(np, 0);
> +       if (!mcs814x_timer_base)
> +               panic("unable to remap timer cpu registers");
> +
> +       intspec = of_get_property(np, "interrupts", NULL);
> +       if (!intspec)
> +               panic("no interrupts property for timer");
> +
> +       mcs814x_timer_irq.irq = be32_to_cpup(intspec);

Why are you getting and converting this from bigendian?

What is wrong with using irq_of_parse_and_map(np, 0) for this, this
just looks dangerous.

> +}
> +
> +static void __init mcs814x_timer_init(void)
> +{
> +       struct clk *clk;
> +
> +       clk = clk_get_sys("timer0", NULL);
> +       if (IS_ERR_OR_NULL(clk))
> +               panic("unable to get timer0 clock");

clk_prepare_enable() is needed at this point.

> +
> +       clock_rate = clk_get_rate(clk);
> +       clk_put(clk);

Don't put the clock here, you're using it, perpetually. If you
put() it the clock framework can disable it at as unused.

> +
> +       mcs814x_of_timer_init();
> +
> +       pr_info("Timer frequency: %d (kHz)\n", clock_rate / 1000);
> +
> +       timer_reload_value = 0xffffffff - (clock_rate / HZ);
> +
> +       /* disable timer */
> +       __raw_writel(0, mcs814x_timer_base + TIMER_CTL);
> +       __raw_writel(timer_reload_value, mcs814x_timer_base + TIMER_VAL);
> +       last_reload = timer_reload_value;
> +
> +       setup_irq(mcs814x_timer_irq.irq, &mcs814x_timer_irq);
> +       /* enable timer, stop timer in debug mode */
> +       __raw_writel(0x03, mcs814x_timer_base + TIMER_CTL);
> +}
> +
> +struct sys_timer mcs814x_timer = {
> +       .init   = mcs814x_timer_init,
> +       .offset = mcs814x_gettimeoffset,
> +};

No .offset and rewrite this to register a clock source+clock event
and use that instead.

Please look at arch/arm/common/timer-sp.c for a good example
of how a timer driver should look.

You will feel it's much more elegant afterwards :-)

What might be complicated is that it appears you have only one
single timer in your system, is that reallty the case? Usually
Linux fires one timer to just "run free" to be used as cycle counter
(clock source) and another one to "shoot events" (clock event)

I've never seen one and the same timer being used for both
clock source and clock events but if you really have only one
timer I think that is also feasible, but will need some serious
hacking.

Yours,
Linus Walleij

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-16 15:54       ` Arnd Bergmann
@ 2012-07-16 22:12           ` Linus Walleij
  -1 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-07-16 22:12 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Mike Turquette,
	Florian Fainelli,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Mon, Jul 16, 2012 at 5:54 PM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:

>> +static const struct cpu_mode cpu_modes[] = {
>> +     {
>> +             .name           = "I2S",
>> +             .gpio_start     = 4,
>> +             .gpio_end       = 8,
>> +     },
>> +     {
>> +             .name           = "UART",
>> +             .gpio_start     = 4,
>> +             .gpio_end       = 9,
>> +     },
>> +     {
>> +             .name           = "External MII",
>> +             .gpio_start     = 0,
>> +             .gpio_end       = 16,
>> +     },
>> +     {
>> +             .name           = "Normal",
>> +             .gpio_start     = -1,
>> +             .gpio_end       = -1,
>> +     },
>> +};
>> +
>> +void __init mcs814x_init_machine(void)
>> +{
>> +     u32 bs2, cpu_mode;
>> +     int gpio;
>> +
>> +     bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
>> +     cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
>> +
>> +     pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
>> +
>> +     /* request the gpios since the pins are muxed for functionnality */
>> +     for (gpio = cpu_modes[cpu_mode].gpio_start;
>> +             gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
>> +             if (gpio != -1)
>> +                     gpio_request(gpio, cpu_modes[cpu_mode].name);
>> +     }
>> +}
>
> This looks like a very simple instance of a pinmux driver. I wonder
> if it's worth doing an actual pinctrl driver that knows about these
> modes and about the gpio handling of the platform. Maybe Linus Walleij
> can comment on that.

It is worth, because usually it is not simple at all but these are,
as I highly suspect, the first few entries to get the platform up and
running. Then it's going to need to add another one, and then
another one, and then break it into a separate file, and then it's a
custom pin controller implementation all over again

Nothing is forbidding a simple pin controller implementation
in drivers/pinctrl, just a few tens of lines is perfectly OK
with me.

Documentation/pinctrl.txt is the friend at all times.
arch/arm/mach-u300/core.c shows how a simple set-up
at boot time can be achieved using so-called pinctrl
hogs.

Yours,
Linus Walleij

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-16 22:12           ` Linus Walleij
  0 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-07-16 22:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 16, 2012 at 5:54 PM, Arnd Bergmann <arnd@arndb.de> wrote:

>> +static const struct cpu_mode cpu_modes[] = {
>> +     {
>> +             .name           = "I2S",
>> +             .gpio_start     = 4,
>> +             .gpio_end       = 8,
>> +     },
>> +     {
>> +             .name           = "UART",
>> +             .gpio_start     = 4,
>> +             .gpio_end       = 9,
>> +     },
>> +     {
>> +             .name           = "External MII",
>> +             .gpio_start     = 0,
>> +             .gpio_end       = 16,
>> +     },
>> +     {
>> +             .name           = "Normal",
>> +             .gpio_start     = -1,
>> +             .gpio_end       = -1,
>> +     },
>> +};
>> +
>> +void __init mcs814x_init_machine(void)
>> +{
>> +     u32 bs2, cpu_mode;
>> +     int gpio;
>> +
>> +     bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
>> +     cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
>> +
>> +     pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
>> +
>> +     /* request the gpios since the pins are muxed for functionnality */
>> +     for (gpio = cpu_modes[cpu_mode].gpio_start;
>> +             gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
>> +             if (gpio != -1)
>> +                     gpio_request(gpio, cpu_modes[cpu_mode].name);
>> +     }
>> +}
>
> This looks like a very simple instance of a pinmux driver. I wonder
> if it's worth doing an actual pinctrl driver that knows about these
> modes and about the gpio handling of the platform. Maybe Linus Walleij
> can comment on that.

It is worth, because usually it is not simple at all but these are,
as I highly suspect, the first few entries to get the platform up and
running. Then it's going to need to add another one, and then
another one, and then break it into a separate file, and then it's a
custom pin controller implementation all over again

Nothing is forbidding a simple pin controller implementation
in drivers/pinctrl, just a few tens of lines is perfectly OK
with me.

Documentation/pinctrl.txt is the friend at all times.
arch/arm/mach-u300/core.c shows how a simple set-up
at boot time can be achieved using so-called pinctrl
hogs.

Yours,
Linus Walleij

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-16 15:54       ` Arnd Bergmann
@ 2012-07-17  9:34         ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17  9:34 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: olof, Linus Walleij, Mike Turquette, devicetree-discuss,
	linux-arm-kernel

Hi Arnd,

On Monday 16 July 2012 15:54:04 Arnd Bergmann wrote:
> On Sunday 15 July 2012, Florian Fainelli wrote:
> 
> > diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
> > new file mode 100644
> > index 0000000..c89422f
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/Kconfig
> > @@ -0,0 +1,11 @@
> > +if ARCH_MCS814X
> > +
> > +config MCS8140
> > +	select CPU_ARM926T
> > +	bool
> > +
> > +menu "Moschip MCS8140 boards"
> > +
> > +endmenu
> > +
> > +endif
> 
> What values does the Kconfig file actually provide? I see that you are
> adding the boards here later, but I think it would be nice to just 
> make the new platform a single Kconfig option with no individual
> board selection.

I plan on adding support for MCS8142 later on, thus I thought it would be nice 
to be able to selectively compile board support for MCS8140 or some later 
chip.

> 
> > +struct clk {
> > +	struct clk *parent;		/* parent clk */
> > +	unsigned long rate;		/* clock rate in Hz */
> > +	unsigned long divider;		/* clock divider */
> > +	u32 usecount;			/* reference count */
> > +	struct clk_ops *ops;		/* clock operation */
> > +	u32 enable_reg;			/* clock enable register */
> > +	u32 enable_mask;		/* clock enable mask */
> > +};
> 
> Platforms are now converting to the common clock framework in drivers/clk.
> Mike Turquette as the subsystem maintainer can probably judge better whether
> we should still be allowing new platforms with their own implementation
> of clk, but my feeling is that you should use the subsystem instead
> and add a driver in a subdirectory of drivers/clk instead of in the
> platform.
> 
> > +void __iomem *mcs814x_sysdbg_base;
> 
> Does this have to be globally visible? I would recommend making it static.

Yes, since it is used both by clock.c and common.c

> 
> > +
> > +struct cpu_mode {
> > +	const char *name;
> > +	int gpio_start;
> > +	int gpio_end;
> > +};
> > +
> > +static const struct cpu_mode cpu_modes[] = {
> > +	{
> > +		.name		= "I2S",
> > +		.gpio_start	= 4,
> > +		.gpio_end	= 8,
> > +	},
> > +	{
> > +		.name		= "UART",
> > +		.gpio_start	= 4,
> > +		.gpio_end	= 9,
> > +	},
> > +	{
> > +		.name		= "External MII",
> > +		.gpio_start	= 0,
> > +		.gpio_end	= 16,
> > +	},
> > +	{
> > +		.name		= "Normal",
> > +		.gpio_start	= -1,
> > +		.gpio_end	= -1,
> > +	},
> > +};
> > +
> > +void __init mcs814x_init_machine(void)
> > +{
> > +	u32 bs2, cpu_mode;
> > +	int gpio;
> > +
> > +	bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
> > +	cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
> > +
> > +	pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
> > +
> > +	/* request the gpios since the pins are muxed for functionnality */
> > +	for (gpio = cpu_modes[cpu_mode].gpio_start;
> > +		gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
> > +		if (gpio != -1)
> > +			gpio_request(gpio, cpu_modes[cpu_mode].name);
> > +	}
> > +}
> 
> This looks like a very simple instance of a pinmux driver. I wonder
> if it's worth doing an actual pinctrl driver that knows about these
> modes and about the gpio handling of the platform. Maybe Linus Walleij
> can comment on that.
> 
> How is the cpu mode managed? Is it hardwired through something like
> strapping pins, or could you have a system that sets it dynamically
> based on what hardware is being plugged in?

Like I replied to Thomas, these settings are actually hardwired through 
bootstrap registers, so I should not even bother to request these GPIOs.

> 
> > +void __init mcs814x_map_io(void)
> > +{
> > +	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
> > +
> > +	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
> > +					MCS814X_SYSDBG_SIZE);
> > +	if (!mcs814x_sysdbg_base)
> > +		panic("unable to remap sysdbg base");
> > +}
> > +
> > +void mcs814x_restart(char mode, const char *cmd)
> > +{
> > +	__raw_writel(~(1 << 31), mcs814x_sysdbg_base);
> > +}
> 
> You should generally avoid using __raw_readl etc. and instead use
> readl/write or readl_relaxed/writel_relaxed.

Allright, even on an ARM926-EJS-based system?

> 
> > diff --git a/arch/arm/mach-mcs814x/common.h b/arch/arm/mach-
mcs814x/common.h
> > new file mode 100644
> > index 0000000..e523abe
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/common.h
> > @@ -0,0 +1,15 @@
> > +#ifndef __ARCH_MCS814X_COMMON_H
> > +#define __ARCH_MCS814X_COMMON_H
> > +
> > +#include <asm/mach/time.h>
> > +
> > +void mcs814x_map_io(void);
> > +void mcs814x_clk_init(void);
> > +void mcs814x_of_irq_init(void);
> > +void mcs814x_init_machine(void);
> > +void mcs814x_handle_irq(struct pt_regs *regs);
> > +void mcs814x_restart(char mode, const char *cmd);
> > +extern struct sys_timer mcs814x_timer;
> > +extern void __iomem *mcs814x_sysdbg_base;
> > +
> > +#endif /* __ARCH_MCS814X_COMMON_H */
> 
> I think a lot of these don't actually need to be global if you combine some
> of the files.
> 
> 
> > diff --git a/arch/arm/mach-mcs814x/include/mach/cpu.h b/arch/arm/mach-
mcs814x/include/mach/cpu.h
> > new file mode 100644
> > index 0000000..1ef3c4a
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/cpu.h
> > @@ -0,0 +1,16 @@
> > +#ifndef __ASM_ARCH_CPU_H__
> > +#define __ASM_ARCH_CPU_H__
> > +
> > +#include <asm/cputype.h>
> > +
> > +#define MCS8140_ID	0x41069260	/* ARM926EJ-S */
> > +#define MCS814X_MASK	0xff0ffff0
> > +
> > +#ifdef CONFIG_MCS8140
> > +/* Moschip MCS8140 is based on an ARM926EJ-S core */
> > +#define soc_is_mcs8140()	((read_cpuid_id() & MCS814X_MASK) == MCS8140_ID)
> > +#else
> > +#define soc_is_mcs8140()	(0)
> > +#endif /* !CONFIG_MCS8140 */
> > +
> > +#endif /* __ASM_ARCH_CPU_H__ */
> 
> Can you explain what this is used for? Are there other SoCs in the same
> platform that will get added later?

Yes, that's the plan.

> 
> > diff --git a/arch/arm/mach-mcs814x/include/mach/hardware.h b/arch/arm/mach-
mcs814x/include/mach/hardware.h
> > new file mode 100644
> > index 0000000..529f648
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/hardware.h
> > @@ -0,0 +1,16 @@
> > +/*
> > + * Copyright (C) 2003 Artec Design Ltd.
> > + *
> > + * 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 __ASM_ARCH_HARDWARE_H
> > +#define __ASM_ARCH_HARDWARE_H
> > +
> > +#include "mcs814x.h"
> > +
> > +#endif
> 
> I'd just make this an empty file, like gpio.h. That will let us kill off
> these files more easily in the future.

Ok.

> 
> > diff --git a/arch/arm/mach-mcs814x/include/mach/irqs.h b/arch/arm/mach-
mcs814x/include/mach/irqs.h
> > new file mode 100644
> > index 0000000..78021d1
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/irqs.h
> > @@ -0,0 +1,22 @@
> > +/*
> > + * Copyright (C) 2003 Artec Design Ltd.
> > + *
> > + * 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 __ASM_ARCH_IRQS_H
> > +#define __ASM_ARCH_IRQS_H
> > +
> > +#define FIQ_START	0
> 
> Why do you need the FIQ_START macro here?

I don't think I need this anymore.

> 
> > +#define NR_IRQS		32
> > +
> > +#define IRQ_PCI_INTA            22
> > +#define IRQ_PCI_INTB            23
> > +#define IRQ_PCI_INTC            24
> > +#define IRQ_PCI_INTD            26
> 
> The PCI interrupts should come from the device tree.
> 
> You should also select CONFIG_SPARSE_IRQ unconditionally and use IRQ domains
> so that you no longer need to set NR_IRQS.

Ok.

> 
> > diff --git a/arch/arm/mach-mcs814x/include/mach/mcs814x.h b/arch/arm/mach-
mcs814x/include/mach/mcs814x.h
> > new file mode 100644
> > index 0000000..a4a369e
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/mcs814x.h
> > @@ -0,0 +1,53 @@
> > +/*
> > + * Copyright (C) 2003 Artec Design Ltd.
> > + *
> > + * 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 __ASM_ARCH_MCS814X_H
> > +#define __ASM_ARCH_MCS814X_H
> > +
> > +#define MCS814X_IO_BASE		0xF0000000
> > +#define MCS814X_IO_START	0x40000000
> > +#define MCS814X_IO_SIZE		0x00100000
> 
> What are these required for in the global space? Can you move them into
> a single .c file?

I can certainly do this.

> 
> > +/* IRQ controller register offset */
> > +#define MCS814X_IRQ_ICR		0x00
> > +#define MCS814X_IRQ_ISR		0x04
> > +#define MCS814X_IRQ_MASK	0x20
> > +#define MCS814X_IRQ_STS0	0x40
> 
> I'm pretty sure these can be in irq.c

Not unless I switch to MULTI_IRQ_HANDLER.

> 
> > +#define MCS814X_PHYS_BASE	0x40000000
> > +#define MCS814X_VIRT_BASE	MCS814X_IO_BASE
> > +
> > +#define MCS814X_UART		0x000DC000
> > +#define MCS814X_DBGLED		0x000EC000
> > +#define MCS814X_SYSDBG		0x000F8000
> > +#define MCS814X_SYSDBG_SIZE	0x50
> > +
> > +/* System configuration and bootstrap registers */
> > +#define SYSDBG_BS1		0x00
> > +#define  CPU_FREQ_SHIFT		27
> > +#define  CPU_FREQ_MASK		0x0F
> > +#define  SDRAM_FREQ_BIT		(1 << 22)
> > +
> > +#define SYSDBG_BS2		0x04
> > +#define  LED_CFG_MASK		0x03
> > +#define  CPU_MODE_SHIFT		23
> > +#define  CPU_MODE_MASK		0x03
> > +
> > +#define SYSDBG_SYSCTL_MAC	0x1d
> > +#define  BUF_SHIFT_BIT		(1 << 0)
> > +
> > +#define SYSDBG_SYSCTL		0x08
> > +#define  SYSCTL_EMAC		(1 << 0)
> > +#define  SYSCTL_EPHY		(1 << 0) /* active low */
> > +#define  SYSCTL_CIPHER		(1 << 16)
> > +
> > +#define SYSDBG_PLL_CTL		0x3C
> 
> The sysdbg stuff can probably go into a file that deals
> with the sysdbg registers and exports a high-level interface.
> 
> > +
> > +void __iomem *mcs814x_intc_base;
> 
> static?

Since I am not yet using MULTI_IRQ_HANDLER, this is used by the entry-macro.S 
file too.

> 
> > +#define MCS8140_PCI_HOST_BASE           0x80000000
> > +#define MCS8140_PCI_IOMISC_BASE         0x00000000
> > +#define MCS8140_PCI_PRE_BASE            0x10000000
> > +#define MCS8140_PCI_NONPRE_BASE         0x30000000
> > +
> > +#define MCS8140_PCI_CFG_BASE		(MCS8140_PCI_HOST_BASE + 
0x04000000)
> > +#define MCS8140_PCI_IO_BASE		(MCS8140_PCI_HOST_BASE)
> > +
> > +#define MCS8140_PCI_IO_VIRT_BASE	(MCS814X_IO_BASE - \
> > +					 MCS8140_PCI_CONFIG_SIZE - \
> > +					 MCS8140_PCI_IOMISC_SIZE)
> > +#define MCS8140_PCI_CFG_VIRT_BASE	(MCS814X_IO_BASE - \
> > +					 MCS8140_PCI_CONFIG_SIZE)
> 
> 
> > +static unsigned long __pci_addr(struct pci_bus *bus,
> > +				unsigned int devfn, int offset)
> > +{
> > +	unsigned int busnr = bus->number;
> > +	unsigned int slot;
> > +
> > +	/* we only support bus 0 */
> > +	if (busnr != 0)
> > +		return 0;
> 
> Why? A lot of devices have bridges on them and they should just
> work if you take out this check.
> 
> > +	/*
> > +	 * Trap out illegal values
> > +	 */
> > +	BUG_ON(devfn > 255 || busnr > 255 || devfn > 255);
> 
> You're checking devfn twice...
> 
> > +	/* Scan 3 slots */
> > +	slot = PCI_SLOT(devfn);
> > +	switch (slot) {
> > +	case 1:
> > +	case 2:
> > +	case 3:
> > +		if (PCI_FUNC(devfn) >= 4)
> > +			return 0;
> 
> This also looks bogus. Why limit it to three devices?
> 
> > +static int mcs8140_pci_read_config(struct pci_bus *bus,
> > +					unsigned int devfn, int where,
> > +					int size, u32 *val)
> > +{
> > +	unsigned long v = 0xFFFFFFFF;
> > +	unsigned long addr = __pci_addr(bus, devfn, where);
> > +
> > +	if (addr != 0) {
> > +		switch (size) {
> > +		case 1:
> > +			v = __raw_readb(addr);
> > +			break;
> > +		case 2:
> > +			addr &= ~1;
> > +			v = __raw_readw(addr);
> > +			break;
> > +		default:
> > +			addr &= ~3;
> > +			v = __raw_readl(addr);
> > +			break;
> > +		}
> > +	} else
> > +		v = 0xffffffff;
> 
> This is just mmconfig, right? Don't we have a generic implementation for 
that?
> 
> > +
> > +static struct resource io_mem = {
> > +	.name	= "PCI I/O space",
> > +	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE,
> > +	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE + SZ_64M,
> > +	.flags	= IORESOURCE_IO,
> > +};
> 
> This is wrong: MCS8140_PCI_HOST_BASE is an address in IORESOURCE_MEM space.
> You probably also mean SZ_64K instead of SZ_64M.

I will double check with the hardware manual, but I really think it is 
64MBytes.

> 
> > +int __init pci_mcs8140_setup(int nr, struct pci_sys_data *sys)
> > +{
> > +	int ret = 0;
> > +	u32 val;
> > +
> > +	if (nr > 0)
> > +		return 0;
> > +
> > +	sys->mem_offset = MCS8140_PCI_IO_VIRT_BASE - MCS8140_PCI_IO_BASE;
> 
> Your address spaces are very confusing (or confused). So you have defined
> #define MCS8140_PCI_IO_VIRT_BASE       (MCS814X_IO_BASE - \
>                                         MCS8140_PCI_CONFIG_SIZE - \
>                                         MCS8140_PCI_IOMISC_SIZE)
> #define MCS8140_PCI_CFG_VIRT_BASE      (MCS814X_IO_BASE - \
>                                         MCS8140_PCI_CONFIG_SIZE)
> 
> 
> which means you mem_offset is (MCS814X_IO_BASE - MCS8140_PCI_CONFIG_SIZE -
> MCS8140_PCI_IOMISC_SIZE) - (MCS814X_IO_BASE - MCS8140_PCI_CONFIG_SIZE)
> which is (-MCS8140_PCI_IOMISC_SIZE), which in turn evaluates to
> -SZ_64M or 0xfc000000. If that is the correct value, I'm sure it's
> just coincidence ;-)
> 
> > +static int __init mcs8140_map_irq(const struct pci_dev *dev, u8 slot, u8 
pin)
> > +{
> > +	int line = IRQ_PCI_INTA;
> > +
> > +	if (pin != 0) {
> > +		/* IRQ_PCIA - 22 */
> > +		if (pin == PCI_INTD)
> > +			line = IRQ_PCI_INTA + pin; /* IRQ_PCIA - 22 */
> > +		else
> > +			line = IRQ_PCI_INTA + pin - 1; /* IRQ_PCIA - 22 */
> > +	}
> > +
> > +	pr_info("PCI: Map interrupt slot 0x%02x pin 0x%02x line 0x%02x\n",
> > +		slot, pin, line);
> > +
> > +	return line;
> > +}
> 
> This looks like a very unusual mapping. Maybe it's just wrong and that
> explains why you don't support child buses or additional slots?
> 
> In any case, you should use an "interrupt-map" in the device tree that
> describes how the IRQs are mapped to the slots. I think we have generic
> code to deal with that already.
> 
> > +static struct map_desc mcs8140_pci_io_desc[] __initdata = {
> > +	{
> > +		.virtual	= MCS8140_PCI_CFG_VIRT_BASE,
> > +		.pfn		= __phys_to_pfn(MCS8140_PCI_CFG_BASE),
> > +		.length		= MCS8140_PCI_CONFIG_SIZE,
> > +		.type		= MT_DEVICE
> > +	},
> > +	{
> > +		.virtual	= MCS8140_PCI_IO_VIRT_BASE,
> > +		.pfn		= __phys_to_pfn(MCS8140_PCI_IO_BASE),
> > +		.length		= MCS8140_PCI_IOMISC_SIZE,
> > +		.type		= MT_DEVICE
> > +	},
> > +};
> 
> Please have a look at the latest patches from Rob Herring about
> mapping the I/O space. I don't think you need to map the config
> space early because you don't rely on a fixed location for that.
> Just use of_iomap() to find that and store the pointer to the
> config space somewhere.
> 
> > +	pcibios_min_io = MCS8140_PCI_HOST_BASE;
> 
> Leave this one at the default of 0x1000. MCS8140_PCI_HOST_BASE is the
> address from the CPU's point of view, not from the bus. You just need
> to stay out of the range of possible legacy ISA devices.
> 
> It's probably a good idea to keep the PCI support as a separate patch
> for reviewing purposes.

Good idea, I will do that. Note that none of the boards I have actually have 
PCI, so the code is just there in case someone needs it. I could also go along 
and remove it, since I cannot test it, which explains why there are so many 
inconsistencies with it.

> 
> 	Arnd

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-17  9:34         ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17  9:34 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,

On Monday 16 July 2012 15:54:04 Arnd Bergmann wrote:
> On Sunday 15 July 2012, Florian Fainelli wrote:
> 
> > diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
> > new file mode 100644
> > index 0000000..c89422f
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/Kconfig
> > @@ -0,0 +1,11 @@
> > +if ARCH_MCS814X
> > +
> > +config MCS8140
> > +	select CPU_ARM926T
> > +	bool
> > +
> > +menu "Moschip MCS8140 boards"
> > +
> > +endmenu
> > +
> > +endif
> 
> What values does the Kconfig file actually provide? I see that you are
> adding the boards here later, but I think it would be nice to just 
> make the new platform a single Kconfig option with no individual
> board selection.

I plan on adding support for MCS8142 later on, thus I thought it would be nice 
to be able to selectively compile board support for MCS8140 or some later 
chip.

> 
> > +struct clk {
> > +	struct clk *parent;		/* parent clk */
> > +	unsigned long rate;		/* clock rate in Hz */
> > +	unsigned long divider;		/* clock divider */
> > +	u32 usecount;			/* reference count */
> > +	struct clk_ops *ops;		/* clock operation */
> > +	u32 enable_reg;			/* clock enable register */
> > +	u32 enable_mask;		/* clock enable mask */
> > +};
> 
> Platforms are now converting to the common clock framework in drivers/clk.
> Mike Turquette as the subsystem maintainer can probably judge better whether
> we should still be allowing new platforms with their own implementation
> of clk, but my feeling is that you should use the subsystem instead
> and add a driver in a subdirectory of drivers/clk instead of in the
> platform.
> 
> > +void __iomem *mcs814x_sysdbg_base;
> 
> Does this have to be globally visible? I would recommend making it static.

Yes, since it is used both by clock.c and common.c

> 
> > +
> > +struct cpu_mode {
> > +	const char *name;
> > +	int gpio_start;
> > +	int gpio_end;
> > +};
> > +
> > +static const struct cpu_mode cpu_modes[] = {
> > +	{
> > +		.name		= "I2S",
> > +		.gpio_start	= 4,
> > +		.gpio_end	= 8,
> > +	},
> > +	{
> > +		.name		= "UART",
> > +		.gpio_start	= 4,
> > +		.gpio_end	= 9,
> > +	},
> > +	{
> > +		.name		= "External MII",
> > +		.gpio_start	= 0,
> > +		.gpio_end	= 16,
> > +	},
> > +	{
> > +		.name		= "Normal",
> > +		.gpio_start	= -1,
> > +		.gpio_end	= -1,
> > +	},
> > +};
> > +
> > +void __init mcs814x_init_machine(void)
> > +{
> > +	u32 bs2, cpu_mode;
> > +	int gpio;
> > +
> > +	bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
> > +	cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
> > +
> > +	pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
> > +
> > +	/* request the gpios since the pins are muxed for functionnality */
> > +	for (gpio = cpu_modes[cpu_mode].gpio_start;
> > +		gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
> > +		if (gpio != -1)
> > +			gpio_request(gpio, cpu_modes[cpu_mode].name);
> > +	}
> > +}
> 
> This looks like a very simple instance of a pinmux driver. I wonder
> if it's worth doing an actual pinctrl driver that knows about these
> modes and about the gpio handling of the platform. Maybe Linus Walleij
> can comment on that.
> 
> How is the cpu mode managed? Is it hardwired through something like
> strapping pins, or could you have a system that sets it dynamically
> based on what hardware is being plugged in?

Like I replied to Thomas, these settings are actually hardwired through 
bootstrap registers, so I should not even bother to request these GPIOs.

> 
> > +void __init mcs814x_map_io(void)
> > +{
> > +	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
> > +
> > +	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
> > +					MCS814X_SYSDBG_SIZE);
> > +	if (!mcs814x_sysdbg_base)
> > +		panic("unable to remap sysdbg base");
> > +}
> > +
> > +void mcs814x_restart(char mode, const char *cmd)
> > +{
> > +	__raw_writel(~(1 << 31), mcs814x_sysdbg_base);
> > +}
> 
> You should generally avoid using __raw_readl etc. and instead use
> readl/write or readl_relaxed/writel_relaxed.

Allright, even on an ARM926-EJS-based system?

> 
> > diff --git a/arch/arm/mach-mcs814x/common.h b/arch/arm/mach-
mcs814x/common.h
> > new file mode 100644
> > index 0000000..e523abe
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/common.h
> > @@ -0,0 +1,15 @@
> > +#ifndef __ARCH_MCS814X_COMMON_H
> > +#define __ARCH_MCS814X_COMMON_H
> > +
> > +#include <asm/mach/time.h>
> > +
> > +void mcs814x_map_io(void);
> > +void mcs814x_clk_init(void);
> > +void mcs814x_of_irq_init(void);
> > +void mcs814x_init_machine(void);
> > +void mcs814x_handle_irq(struct pt_regs *regs);
> > +void mcs814x_restart(char mode, const char *cmd);
> > +extern struct sys_timer mcs814x_timer;
> > +extern void __iomem *mcs814x_sysdbg_base;
> > +
> > +#endif /* __ARCH_MCS814X_COMMON_H */
> 
> I think a lot of these don't actually need to be global if you combine some
> of the files.
> 
> 
> > diff --git a/arch/arm/mach-mcs814x/include/mach/cpu.h b/arch/arm/mach-
mcs814x/include/mach/cpu.h
> > new file mode 100644
> > index 0000000..1ef3c4a
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/cpu.h
> > @@ -0,0 +1,16 @@
> > +#ifndef __ASM_ARCH_CPU_H__
> > +#define __ASM_ARCH_CPU_H__
> > +
> > +#include <asm/cputype.h>
> > +
> > +#define MCS8140_ID	0x41069260	/* ARM926EJ-S */
> > +#define MCS814X_MASK	0xff0ffff0
> > +
> > +#ifdef CONFIG_MCS8140
> > +/* Moschip MCS8140 is based on an ARM926EJ-S core */
> > +#define soc_is_mcs8140()	((read_cpuid_id() & MCS814X_MASK) == MCS8140_ID)
> > +#else
> > +#define soc_is_mcs8140()	(0)
> > +#endif /* !CONFIG_MCS8140 */
> > +
> > +#endif /* __ASM_ARCH_CPU_H__ */
> 
> Can you explain what this is used for? Are there other SoCs in the same
> platform that will get added later?

Yes, that's the plan.

> 
> > diff --git a/arch/arm/mach-mcs814x/include/mach/hardware.h b/arch/arm/mach-
mcs814x/include/mach/hardware.h
> > new file mode 100644
> > index 0000000..529f648
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/hardware.h
> > @@ -0,0 +1,16 @@
> > +/*
> > + * Copyright (C) 2003 Artec Design Ltd.
> > + *
> > + * 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 __ASM_ARCH_HARDWARE_H
> > +#define __ASM_ARCH_HARDWARE_H
> > +
> > +#include "mcs814x.h"
> > +
> > +#endif
> 
> I'd just make this an empty file, like gpio.h. That will let us kill off
> these files more easily in the future.

Ok.

> 
> > diff --git a/arch/arm/mach-mcs814x/include/mach/irqs.h b/arch/arm/mach-
mcs814x/include/mach/irqs.h
> > new file mode 100644
> > index 0000000..78021d1
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/irqs.h
> > @@ -0,0 +1,22 @@
> > +/*
> > + * Copyright (C) 2003 Artec Design Ltd.
> > + *
> > + * 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 __ASM_ARCH_IRQS_H
> > +#define __ASM_ARCH_IRQS_H
> > +
> > +#define FIQ_START	0
> 
> Why do you need the FIQ_START macro here?

I don't think I need this anymore.

> 
> > +#define NR_IRQS		32
> > +
> > +#define IRQ_PCI_INTA            22
> > +#define IRQ_PCI_INTB            23
> > +#define IRQ_PCI_INTC            24
> > +#define IRQ_PCI_INTD            26
> 
> The PCI interrupts should come from the device tree.
> 
> You should also select CONFIG_SPARSE_IRQ unconditionally and use IRQ domains
> so that you no longer need to set NR_IRQS.

Ok.

> 
> > diff --git a/arch/arm/mach-mcs814x/include/mach/mcs814x.h b/arch/arm/mach-
mcs814x/include/mach/mcs814x.h
> > new file mode 100644
> > index 0000000..a4a369e
> > --- /dev/null
> > +++ b/arch/arm/mach-mcs814x/include/mach/mcs814x.h
> > @@ -0,0 +1,53 @@
> > +/*
> > + * Copyright (C) 2003 Artec Design Ltd.
> > + *
> > + * 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 __ASM_ARCH_MCS814X_H
> > +#define __ASM_ARCH_MCS814X_H
> > +
> > +#define MCS814X_IO_BASE		0xF0000000
> > +#define MCS814X_IO_START	0x40000000
> > +#define MCS814X_IO_SIZE		0x00100000
> 
> What are these required for in the global space? Can you move them into
> a single .c file?

I can certainly do this.

> 
> > +/* IRQ controller register offset */
> > +#define MCS814X_IRQ_ICR		0x00
> > +#define MCS814X_IRQ_ISR		0x04
> > +#define MCS814X_IRQ_MASK	0x20
> > +#define MCS814X_IRQ_STS0	0x40
> 
> I'm pretty sure these can be in irq.c

Not unless I switch to MULTI_IRQ_HANDLER.

> 
> > +#define MCS814X_PHYS_BASE	0x40000000
> > +#define MCS814X_VIRT_BASE	MCS814X_IO_BASE
> > +
> > +#define MCS814X_UART		0x000DC000
> > +#define MCS814X_DBGLED		0x000EC000
> > +#define MCS814X_SYSDBG		0x000F8000
> > +#define MCS814X_SYSDBG_SIZE	0x50
> > +
> > +/* System configuration and bootstrap registers */
> > +#define SYSDBG_BS1		0x00
> > +#define  CPU_FREQ_SHIFT		27
> > +#define  CPU_FREQ_MASK		0x0F
> > +#define  SDRAM_FREQ_BIT		(1 << 22)
> > +
> > +#define SYSDBG_BS2		0x04
> > +#define  LED_CFG_MASK		0x03
> > +#define  CPU_MODE_SHIFT		23
> > +#define  CPU_MODE_MASK		0x03
> > +
> > +#define SYSDBG_SYSCTL_MAC	0x1d
> > +#define  BUF_SHIFT_BIT		(1 << 0)
> > +
> > +#define SYSDBG_SYSCTL		0x08
> > +#define  SYSCTL_EMAC		(1 << 0)
> > +#define  SYSCTL_EPHY		(1 << 0) /* active low */
> > +#define  SYSCTL_CIPHER		(1 << 16)
> > +
> > +#define SYSDBG_PLL_CTL		0x3C
> 
> The sysdbg stuff can probably go into a file that deals
> with the sysdbg registers and exports a high-level interface.
> 
> > +
> > +void __iomem *mcs814x_intc_base;
> 
> static?

Since I am not yet using MULTI_IRQ_HANDLER, this is used by the entry-macro.S 
file too.

> 
> > +#define MCS8140_PCI_HOST_BASE           0x80000000
> > +#define MCS8140_PCI_IOMISC_BASE         0x00000000
> > +#define MCS8140_PCI_PRE_BASE            0x10000000
> > +#define MCS8140_PCI_NONPRE_BASE         0x30000000
> > +
> > +#define MCS8140_PCI_CFG_BASE		(MCS8140_PCI_HOST_BASE + 
0x04000000)
> > +#define MCS8140_PCI_IO_BASE		(MCS8140_PCI_HOST_BASE)
> > +
> > +#define MCS8140_PCI_IO_VIRT_BASE	(MCS814X_IO_BASE - \
> > +					 MCS8140_PCI_CONFIG_SIZE - \
> > +					 MCS8140_PCI_IOMISC_SIZE)
> > +#define MCS8140_PCI_CFG_VIRT_BASE	(MCS814X_IO_BASE - \
> > +					 MCS8140_PCI_CONFIG_SIZE)
> 
> 
> > +static unsigned long __pci_addr(struct pci_bus *bus,
> > +				unsigned int devfn, int offset)
> > +{
> > +	unsigned int busnr = bus->number;
> > +	unsigned int slot;
> > +
> > +	/* we only support bus 0 */
> > +	if (busnr != 0)
> > +		return 0;
> 
> Why? A lot of devices have bridges on them and they should just
> work if you take out this check.
> 
> > +	/*
> > +	 * Trap out illegal values
> > +	 */
> > +	BUG_ON(devfn > 255 || busnr > 255 || devfn > 255);
> 
> You're checking devfn twice...
> 
> > +	/* Scan 3 slots */
> > +	slot = PCI_SLOT(devfn);
> > +	switch (slot) {
> > +	case 1:
> > +	case 2:
> > +	case 3:
> > +		if (PCI_FUNC(devfn) >= 4)
> > +			return 0;
> 
> This also looks bogus. Why limit it to three devices?
> 
> > +static int mcs8140_pci_read_config(struct pci_bus *bus,
> > +					unsigned int devfn, int where,
> > +					int size, u32 *val)
> > +{
> > +	unsigned long v = 0xFFFFFFFF;
> > +	unsigned long addr = __pci_addr(bus, devfn, where);
> > +
> > +	if (addr != 0) {
> > +		switch (size) {
> > +		case 1:
> > +			v = __raw_readb(addr);
> > +			break;
> > +		case 2:
> > +			addr &= ~1;
> > +			v = __raw_readw(addr);
> > +			break;
> > +		default:
> > +			addr &= ~3;
> > +			v = __raw_readl(addr);
> > +			break;
> > +		}
> > +	} else
> > +		v = 0xffffffff;
> 
> This is just mmconfig, right? Don't we have a generic implementation for 
that?
> 
> > +
> > +static struct resource io_mem = {
> > +	.name	= "PCI I/O space",
> > +	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE,
> > +	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE + SZ_64M,
> > +	.flags	= IORESOURCE_IO,
> > +};
> 
> This is wrong: MCS8140_PCI_HOST_BASE is an address in IORESOURCE_MEM space.
> You probably also mean SZ_64K instead of SZ_64M.

I will double check with the hardware manual, but I really think it is 
64MBytes.

> 
> > +int __init pci_mcs8140_setup(int nr, struct pci_sys_data *sys)
> > +{
> > +	int ret = 0;
> > +	u32 val;
> > +
> > +	if (nr > 0)
> > +		return 0;
> > +
> > +	sys->mem_offset = MCS8140_PCI_IO_VIRT_BASE - MCS8140_PCI_IO_BASE;
> 
> Your address spaces are very confusing (or confused). So you have defined
> #define MCS8140_PCI_IO_VIRT_BASE       (MCS814X_IO_BASE - \
>                                         MCS8140_PCI_CONFIG_SIZE - \
>                                         MCS8140_PCI_IOMISC_SIZE)
> #define MCS8140_PCI_CFG_VIRT_BASE      (MCS814X_IO_BASE - \
>                                         MCS8140_PCI_CONFIG_SIZE)
> 
> 
> which means you mem_offset is (MCS814X_IO_BASE - MCS8140_PCI_CONFIG_SIZE -
> MCS8140_PCI_IOMISC_SIZE) - (MCS814X_IO_BASE - MCS8140_PCI_CONFIG_SIZE)
> which is (-MCS8140_PCI_IOMISC_SIZE), which in turn evaluates to
> -SZ_64M or 0xfc000000. If that is the correct value, I'm sure it's
> just coincidence ;-)
> 
> > +static int __init mcs8140_map_irq(const struct pci_dev *dev, u8 slot, u8 
pin)
> > +{
> > +	int line = IRQ_PCI_INTA;
> > +
> > +	if (pin != 0) {
> > +		/* IRQ_PCIA - 22 */
> > +		if (pin == PCI_INTD)
> > +			line = IRQ_PCI_INTA + pin; /* IRQ_PCIA - 22 */
> > +		else
> > +			line = IRQ_PCI_INTA + pin - 1; /* IRQ_PCIA - 22 */
> > +	}
> > +
> > +	pr_info("PCI: Map interrupt slot 0x%02x pin 0x%02x line 0x%02x\n",
> > +		slot, pin, line);
> > +
> > +	return line;
> > +}
> 
> This looks like a very unusual mapping. Maybe it's just wrong and that
> explains why you don't support child buses or additional slots?
> 
> In any case, you should use an "interrupt-map" in the device tree that
> describes how the IRQs are mapped to the slots. I think we have generic
> code to deal with that already.
> 
> > +static struct map_desc mcs8140_pci_io_desc[] __initdata = {
> > +	{
> > +		.virtual	= MCS8140_PCI_CFG_VIRT_BASE,
> > +		.pfn		= __phys_to_pfn(MCS8140_PCI_CFG_BASE),
> > +		.length		= MCS8140_PCI_CONFIG_SIZE,
> > +		.type		= MT_DEVICE
> > +	},
> > +	{
> > +		.virtual	= MCS8140_PCI_IO_VIRT_BASE,
> > +		.pfn		= __phys_to_pfn(MCS8140_PCI_IO_BASE),
> > +		.length		= MCS8140_PCI_IOMISC_SIZE,
> > +		.type		= MT_DEVICE
> > +	},
> > +};
> 
> Please have a look at the latest patches from Rob Herring about
> mapping the I/O space. I don't think you need to map the config
> space early because you don't rely on a fixed location for that.
> Just use of_iomap() to find that and store the pointer to the
> config space somewhere.
> 
> > +	pcibios_min_io = MCS8140_PCI_HOST_BASE;
> 
> Leave this one at the default of 0x1000. MCS8140_PCI_HOST_BASE is the
> address from the CPU's point of view, not from the bus. You just need
> to stay out of the range of possible legacy ISA devices.
> 
> It's probably a good idea to keep the PCI support as a separate patch
> for reviewing purposes.

Good idea, I will do that. Note that none of the boards I have actually have 
PCI, so the code is just there in case someone needs it. I could also go along 
and remove it, since I cannot test it, which explains why there are so many 
inconsistencies with it.

> 
> 	Arnd

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-16 22:12           ` Linus Walleij
@ 2012-07-17  9:35             ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17  9:35 UTC (permalink / raw)
  To: Linus Walleij
  Cc: olof, devicetree-discuss, Mike Turquette, linux-arm-kernel,
	Arnd Bergmann

On Tuesday 17 July 2012 00:12:01 Linus Walleij wrote:
> On Mon, Jul 16, 2012 at 5:54 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> 
> >> +static const struct cpu_mode cpu_modes[] = {
> >> +     {
> >> +             .name           = "I2S",
> >> +             .gpio_start     = 4,
> >> +             .gpio_end       = 8,
> >> +     },
> >> +     {
> >> +             .name           = "UART",
> >> +             .gpio_start     = 4,
> >> +             .gpio_end       = 9,
> >> +     },
> >> +     {
> >> +             .name           = "External MII",
> >> +             .gpio_start     = 0,
> >> +             .gpio_end       = 16,
> >> +     },
> >> +     {
> >> +             .name           = "Normal",
> >> +             .gpio_start     = -1,
> >> +             .gpio_end       = -1,
> >> +     },
> >> +};
> >> +
> >> +void __init mcs814x_init_machine(void)
> >> +{
> >> +     u32 bs2, cpu_mode;
> >> +     int gpio;
> >> +
> >> +     bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
> >> +     cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
> >> +
> >> +     pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
> >> +
> >> +     /* request the gpios since the pins are muxed for functionnality */
> >> +     for (gpio = cpu_modes[cpu_mode].gpio_start;
> >> +             gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
> >> +             if (gpio != -1)
> >> +                     gpio_request(gpio, cpu_modes[cpu_mode].name);
> >> +     }
> >> +}
> >
> > This looks like a very simple instance of a pinmux driver. I wonder
> > if it's worth doing an actual pinctrl driver that knows about these
> > modes and about the gpio handling of the platform. Maybe Linus Walleij
> > can comment on that.
> 
> It is worth, because usually it is not simple at all but these are,
> as I highly suspect, the first few entries to get the platform up and
> running. Then it's going to need to add another one, and then
> another one, and then break it into a separate file, and then it's a
> custom pin controller implementation all over again
> 
> Nothing is forbidding a simple pin controller implementation
> in drivers/pinctrl, just a few tens of lines is perfectly OK
> with me.

In this particular case, I do not think it is even worth having a pinctrl 
driver since the settings are hardwired using bootstrap registers, so we 
cannot runtime change them afterwards.

> 
> Documentation/pinctrl.txt is the friend at all times.
> arch/arm/mach-u300/core.c shows how a simple set-up
> at boot time can be achieved using so-called pinctrl
> hogs.
> 
> Yours,
> Linus Walleij

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-17  9:35             ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17  9:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 17 July 2012 00:12:01 Linus Walleij wrote:
> On Mon, Jul 16, 2012 at 5:54 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> 
> >> +static const struct cpu_mode cpu_modes[] = {
> >> +     {
> >> +             .name           = "I2S",
> >> +             .gpio_start     = 4,
> >> +             .gpio_end       = 8,
> >> +     },
> >> +     {
> >> +             .name           = "UART",
> >> +             .gpio_start     = 4,
> >> +             .gpio_end       = 9,
> >> +     },
> >> +     {
> >> +             .name           = "External MII",
> >> +             .gpio_start     = 0,
> >> +             .gpio_end       = 16,
> >> +     },
> >> +     {
> >> +             .name           = "Normal",
> >> +             .gpio_start     = -1,
> >> +             .gpio_end       = -1,
> >> +     },
> >> +};
> >> +
> >> +void __init mcs814x_init_machine(void)
> >> +{
> >> +     u32 bs2, cpu_mode;
> >> +     int gpio;
> >> +
> >> +     bs2 = __raw_readl(mcs814x_sysdbg_base + SYSDBG_BS2);
> >> +     cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
> >> +
> >> +     pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
> >> +
> >> +     /* request the gpios since the pins are muxed for functionnality */
> >> +     for (gpio = cpu_modes[cpu_mode].gpio_start;
> >> +             gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
> >> +             if (gpio != -1)
> >> +                     gpio_request(gpio, cpu_modes[cpu_mode].name);
> >> +     }
> >> +}
> >
> > This looks like a very simple instance of a pinmux driver. I wonder
> > if it's worth doing an actual pinctrl driver that knows about these
> > modes and about the gpio handling of the platform. Maybe Linus Walleij
> > can comment on that.
> 
> It is worth, because usually it is not simple at all but these are,
> as I highly suspect, the first few entries to get the platform up and
> running. Then it's going to need to add another one, and then
> another one, and then break it into a separate file, and then it's a
> custom pin controller implementation all over again
> 
> Nothing is forbidding a simple pin controller implementation
> in drivers/pinctrl, just a few tens of lines is perfectly OK
> with me.

In this particular case, I do not think it is even worth having a pinctrl 
driver since the settings are hardwired using bootstrap registers, so we 
cannot runtime change them afterwards.

> 
> Documentation/pinctrl.txt is the friend at all times.
> arch/arm/mach-u300/core.c shows how a simple set-up
> at boot time can be achieved using so-called pinctrl
> hogs.
> 
> Yours,
> Linus Walleij

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-16 20:47           ` Turquette, Mike
@ 2012-07-17  9:41             ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17  9:41 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: olof, Linus Walleij, devicetree-discuss, Arnd Bergmann, Turquette, Mike

Hi Mike,

On Monday 16 July 2012 13:47:01 Turquette, Mike wrote:
> On Mon, Jul 16, 2012 at 8:54 AM, Arnd Bergmann <arnd@arndb.de> wrote:
[snip]
> > board selection.
> >
> >> +struct clk {
> >> +     struct clk *parent;             /* parent clk */
> >> +     unsigned long rate;             /* clock rate in Hz */
> >> +     unsigned long divider;          /* clock divider */
> >> +     u32 usecount;                   /* reference count */
> >> +     struct clk_ops *ops;            /* clock operation */
> >> +     u32 enable_reg;                 /* clock enable register */
> >> +     u32 enable_mask;                /* clock enable mask */
> >> +};
> >
> > Platforms are now converting to the common clock framework in drivers/clk.
> > Mike Turquette as the subsystem maintainer can probably judge better 
whether
> > we should still be allowing new platforms with their own implementation
> > of clk, but my feeling is that you should use the subsystem instead
> > and add a driver in a subdirectory of drivers/clk instead of in the
> > platform.
> 
> Hi Florian & Arnd,
> 
> Adopting the new clock framework is highly preferable, especially if
> MCS814x support is being delayed until 3.7.  There is also a push to
> put clock drivers into drivers/clk and I would like to continue that
> trend, but I'm less strict on that measure if it proves very difficult
> for your platform immediately (e.g. duplicating headers across
> platform and generic code, etc).  Migrating code from arch/arm to
> drivers/clk can always be done in a future series.

Since we are now targetting 3.7, I would rather come up with proper DT clock 
bindings, which should make the mcs814x clock driver much nicer.

> 
> This platform also seems to be making use of DT so it would be very
> nice if we use MCS814x to push the state of clk DT bindings and
> adoption forward a bit.  There are not a lot of folks using the
> patches from Rob/Grant today.  Hopefully delaying these patches by
> another merge cycle means that these requests are not asking too much
> :-)

If we could get them merged during 3.6 that would allow me, and other ARM-soc 
maintainers to get their stuff fully migrated to DT. Are there any blockers to 
these patches?
--
Florian

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-17  9:41             ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17  9:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mike,

On Monday 16 July 2012 13:47:01 Turquette, Mike wrote:
> On Mon, Jul 16, 2012 at 8:54 AM, Arnd Bergmann <arnd@arndb.de> wrote:
[snip]
> > board selection.
> >
> >> +struct clk {
> >> +     struct clk *parent;             /* parent clk */
> >> +     unsigned long rate;             /* clock rate in Hz */
> >> +     unsigned long divider;          /* clock divider */
> >> +     u32 usecount;                   /* reference count */
> >> +     struct clk_ops *ops;            /* clock operation */
> >> +     u32 enable_reg;                 /* clock enable register */
> >> +     u32 enable_mask;                /* clock enable mask */
> >> +};
> >
> > Platforms are now converting to the common clock framework in drivers/clk.
> > Mike Turquette as the subsystem maintainer can probably judge better 
whether
> > we should still be allowing new platforms with their own implementation
> > of clk, but my feeling is that you should use the subsystem instead
> > and add a driver in a subdirectory of drivers/clk instead of in the
> > platform.
> 
> Hi Florian & Arnd,
> 
> Adopting the new clock framework is highly preferable, especially if
> MCS814x support is being delayed until 3.7.  There is also a push to
> put clock drivers into drivers/clk and I would like to continue that
> trend, but I'm less strict on that measure if it proves very difficult
> for your platform immediately (e.g. duplicating headers across
> platform and generic code, etc).  Migrating code from arch/arm to
> drivers/clk can always be done in a future series.

Since we are now targetting 3.7, I would rather come up with proper DT clock 
bindings, which should make the mcs814x clock driver much nicer.

> 
> This platform also seems to be making use of DT so it would be very
> nice if we use MCS814x to push the state of clk DT bindings and
> adoption forward a bit.  There are not a lot of folks using the
> patches from Rob/Grant today.  Hopefully delaying these patches by
> another merge cycle means that these requests are not asking too much
> :-)

If we could get them merged during 3.6 that would allow me, and other ARM-soc 
maintainers to get their stuff fully migrated to DT. Are there any blockers to 
these patches?
--
Florian

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-16 15:54       ` Arnd Bergmann
@ 2012-07-17 10:16         ` Thomas Petazzoni
  -1 siblings, 0 replies; 80+ messages in thread
From: Thomas Petazzoni @ 2012-07-17 10:16 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Mike Turquette, Linus Walleij, Florian Fainelli, olof,
	devicetree-discuss, linux-arm-kernel

Le Mon, 16 Jul 2012 15:54:04 +0000,
Arnd Bergmann <arnd@arndb.de> a écrit :

> > +void mcs814x_restart(char mode, const char *cmd)
> > +{
> > +	__raw_writel(~(1 << 31), mcs814x_sysdbg_base);
> > +}
> 
> You should generally avoid using __raw_readl etc. and instead use
> readl/write or readl_relaxed/writel_relaxed.

I thought that readl/writel and readl_relaxed/writel_relaxed were used
for PCI-style access, for which these macros/functions do automatically
a conversion from the CPU-endianness to the PCI-endianness
(little-endian). Here of course, this the SoC is used little-endian, it
will just work because readl/writel will not do any endianness
conversion, but if we were on a big-endian machine?

My understanding until now was that __raw_readl/__raw_writel should be
used for accesses with native endianness, but apparently, it's more
subtle than this. Would you mind expanding a bit on this?

Best regards,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-17 10:16         ` Thomas Petazzoni
  0 siblings, 0 replies; 80+ messages in thread
From: Thomas Petazzoni @ 2012-07-17 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

Le Mon, 16 Jul 2012 15:54:04 +0000,
Arnd Bergmann <arnd@arndb.de> a ?crit :

> > +void mcs814x_restart(char mode, const char *cmd)
> > +{
> > +	__raw_writel(~(1 << 31), mcs814x_sysdbg_base);
> > +}
> 
> You should generally avoid using __raw_readl etc. and instead use
> readl/write or readl_relaxed/writel_relaxed.

I thought that readl/writel and readl_relaxed/writel_relaxed were used
for PCI-style access, for which these macros/functions do automatically
a conversion from the CPU-endianness to the PCI-endianness
(little-endian). Here of course, this the SoC is used little-endian, it
will just work because readl/writel will not do any endianness
conversion, but if we were on a big-endian machine?

My understanding until now was that __raw_readl/__raw_writel should be
used for accesses with native endianness, but apparently, it's more
subtle than this. Would you mind expanding a bit on this?

Best regards,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-16 20:47           ` Turquette, Mike
@ 2012-07-17 10:47             ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17 10:47 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: olof, Linus Walleij, devicetree-discuss, Arnd Bergmann, Turquette, Mike

Hi Mike,

On Monday 16 July 2012 13:47:01 Turquette, Mike wrote:
> On Mon, Jul 16, 2012 at 8:54 AM, Arnd Bergmann <arnd@arndb.de> wrote:
[snip]
> > board selection.
> >
> >> +struct clk {
> >> +     struct clk *parent;             /* parent clk */
> >> +     unsigned long rate;             /* clock rate in Hz */
> >> +     unsigned long divider;          /* clock divider */
> >> +     u32 usecount;                   /* reference count */
> >> +     struct clk_ops *ops;            /* clock operation */
> >> +     u32 enable_reg;                 /* clock enable register */
> >> +     u32 enable_mask;                /* clock enable mask */
> >> +};
> >
> > Platforms are now converting to the common clock framework in drivers/clk.
> > Mike Turquette as the subsystem maintainer can probably judge better 
whether
> > we should still be allowing new platforms with their own implementation
> > of clk, but my feeling is that you should use the subsystem instead
> > and add a driver in a subdirectory of drivers/clk instead of in the
> > platform.
> 
> Hi Florian & Arnd,
> 
> Adopting the new clock framework is highly preferable, especially if
> MCS814x support is being delayed until 3.7.  There is also a push to
> put clock drivers into drivers/clk and I would like to continue that
> trend, but I'm less strict on that measure if it proves very difficult
> for your platform immediately (e.g. duplicating headers across
> platform and generic code, etc).  Migrating code from arch/arm to
> drivers/clk can always be done in a future series.

Since we are now targetting 3.7, I would rather come up with proper DT clock 
bindings, which should make the mcs814x clock driver much nicer.

> 
> This platform also seems to be making use of DT so it would be very
> nice if we use MCS814x to push the state of clk DT bindings and
> adoption forward a bit.  There are not a lot of folks using the
> patches from Rob/Grant today.  Hopefully delaying these patches by
> another merge cycle means that these requests are not asking too much
> :-)

If we could get them merged during 3.6 that would allow me, and other ARM-soc 
maintainers to get their stuff fully migrated to DT. Are there any blockers to 
these patches?
--
Florian

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-17 10:47             ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17 10:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mike,

On Monday 16 July 2012 13:47:01 Turquette, Mike wrote:
> On Mon, Jul 16, 2012 at 8:54 AM, Arnd Bergmann <arnd@arndb.de> wrote:
[snip]
> > board selection.
> >
> >> +struct clk {
> >> +     struct clk *parent;             /* parent clk */
> >> +     unsigned long rate;             /* clock rate in Hz */
> >> +     unsigned long divider;          /* clock divider */
> >> +     u32 usecount;                   /* reference count */
> >> +     struct clk_ops *ops;            /* clock operation */
> >> +     u32 enable_reg;                 /* clock enable register */
> >> +     u32 enable_mask;                /* clock enable mask */
> >> +};
> >
> > Platforms are now converting to the common clock framework in drivers/clk.
> > Mike Turquette as the subsystem maintainer can probably judge better 
whether
> > we should still be allowing new platforms with their own implementation
> > of clk, but my feeling is that you should use the subsystem instead
> > and add a driver in a subdirectory of drivers/clk instead of in the
> > platform.
> 
> Hi Florian & Arnd,
> 
> Adopting the new clock framework is highly preferable, especially if
> MCS814x support is being delayed until 3.7.  There is also a push to
> put clock drivers into drivers/clk and I would like to continue that
> trend, but I'm less strict on that measure if it proves very difficult
> for your platform immediately (e.g. duplicating headers across
> platform and generic code, etc).  Migrating code from arch/arm to
> drivers/clk can always be done in a future series.

Since we are now targetting 3.7, I would rather come up with proper DT clock 
bindings, which should make the mcs814x clock driver much nicer.

> 
> This platform also seems to be making use of DT so it would be very
> nice if we use MCS814x to push the state of clk DT bindings and
> adoption forward a bit.  There are not a lot of folks using the
> patches from Rob/Grant today.  Hopefully delaying these patches by
> another merge cycle means that these requests are not asking too much
> :-)

If we could get them merged during 3.6 that would allow me, and other ARM-soc 
maintainers to get their stuff fully migrated to DT. Are there any blockers to 
these patches?
--
Florian

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-17  9:34         ` Florian Fainelli
@ 2012-07-17 13:07           ` Arnd Bergmann
  -1 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:07 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Mike Turquette, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tuesday 17 July 2012, Florian Fainelli wrote:
> On Monday 16 July 2012 15:54:04 Arnd Bergmann wrote:
> > On Sunday 15 July 2012, Florian Fainelli wrote:
> > 
> > > diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
> > > new file mode 100644
> > > index 0000000..c89422f
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mcs814x/Kconfig
> > > @@ -0,0 +1,11 @@
> > > +if ARCH_MCS814X
> > > +
> > > +config MCS8140
> > > +	select CPU_ARM926T
> > > +	bool
> > > +
> > > +menu "Moschip MCS8140 boards"
> > > +
> > > +endmenu
> > > +
> > > +endif
> > 
> > What values does the Kconfig file actually provide? I see that you are
> > adding the boards here later, but I think it would be nice to just 
> > make the new platform a single Kconfig option with no individual
> > board selection.
> 
> I plan on adding support for MCS8142 later on, thus I thought it would be nice 
> to be able to selectively compile board support for MCS8140 or some later 
> chip.

But is there much difference between the two? How much code would
actually get built for one chip but not the other? If all the
differences can be run-time detected from the device tree, I
think it's better to not have different compile-time options at
all.

> > Platforms are now converting to the common clock framework in drivers/clk.
> > Mike Turquette as the subsystem maintainer can probably judge better whether
> > we should still be allowing new platforms with their own implementation
> > of clk, but my feeling is that you should use the subsystem instead
> > and add a driver in a subdirectory of drivers/clk instead of in the
> > platform.
> > 
> > > +void __iomem *mcs814x_sysdbg_base;
> > 
> > Does this have to be globally visible? I would recommend making it static.
> 
> Yes, since it is used both by clock.c and common.c

Ok. How about converting this to an global function in common.c that is
called from clk_local_onoff_enable instead?

> > > +void __init mcs814x_map_io(void)
> > > +{
> > > +	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
> > > +
> > > +	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
> > > +					MCS814X_SYSDBG_SIZE);
> > > +	if (!mcs814x_sysdbg_base)
> > > +		panic("unable to remap sysdbg base");
> > > +}
> > > +
> > > +void mcs814x_restart(char mode, const char *cmd)
> > > +{
> > > +	__raw_writel(~(1 << 31), mcs814x_sysdbg_base);
> > > +}
> > 
> > You should generally avoid using __raw_readl etc. and instead use
> > readl/write or readl_relaxed/writel_relaxed.
> 
> Allright, even on an ARM926-EJS-based system?

Yes, there is no practical difference in the way they are defined at
the moment, but the __raw_ versions are still wrong, you should
really never be using them from driver code.

> > > diff --git a/arch/arm/mach-mcs814x/include/mach/cpu.h b/arch/arm/mach-
> mcs814x/include/mach/cpu.h
> > > new file mode 100644
> > > index 0000000..1ef3c4a
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mcs814x/include/mach/cpu.h
> > > @@ -0,0 +1,16 @@
> > > +#ifndef __ASM_ARCH_CPU_H__
> > > +#define __ASM_ARCH_CPU_H__
> > > +
> > > +#include <asm/cputype.h>
> > > +
> > > +#define MCS8140_ID	0x41069260	/* ARM926EJ-S */
> > > +#define MCS814X_MASK	0xff0ffff0
> > > +
> > > +#ifdef CONFIG_MCS8140
> > > +/* Moschip MCS8140 is based on an ARM926EJ-S core */
> > > +#define soc_is_mcs8140()	((read_cpuid_id() & MCS814X_MASK) == MCS8140_ID)
> > > +#else
> > > +#define soc_is_mcs8140()	(0)
> > > +#endif /* !CONFIG_MCS8140 */
> > > +
> > > +#endif /* __ASM_ARCH_CPU_H__ */
> > 
> > Can you explain what this is used for? Are there other SoCs in the same
> > platform that will get added later?
> 
> Yes, that's the plan.

Ok. But why do you need to know the soc type? If it's only for the
uncompress.h code, it should probably stay local to that file.

> > > +/* IRQ controller register offset */
> > > +#define MCS814X_IRQ_ICR		0x00
> > > +#define MCS814X_IRQ_ISR		0x04
> > > +#define MCS814X_IRQ_MASK	0x20
> > > +#define MCS814X_IRQ_STS0	0x40
> > 
> > I'm pretty sure these can be in irq.c
> 
> Not unless I switch to MULTI_IRQ_HANDLER.

I think you should do that, too. Forgot to mention it.

> > > +
> > > +static struct resource io_mem = {
> > > +	.name	= "PCI I/O space",
> > > +	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE,
> > > +	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE + SZ_64M,
> > > +	.flags	= IORESOURCE_IO,
> > > +};
> > 
> > This is wrong: MCS8140_PCI_HOST_BASE is an address in IORESOURCE_MEM space.
> > You probably also mean SZ_64K instead of SZ_64M.
> 
> I will double check with the hardware manual, but I really think it is 
> 64MBytes.

Are there any devices hardwired to your PCI bus that require more than a few
bytes of I/O space? If not, I think it should be 64KB. No known add-on
cards require more than that, and it would just waste virtual address space,
and prevents us from using the new common PCI I/O space helpers.

> > 
> > Leave this one at the default of 0x1000. MCS8140_PCI_HOST_BASE is the
> > address from the CPU's point of view, not from the bus. You just need
> > to stay out of the range of possible legacy ISA devices.
> > 
> > It's probably a good idea to keep the PCI support as a separate patch
> > for reviewing purposes.
> 
> Good idea, I will do that. Note that none of the boards I have actually have 
> PCI, so the code is just there in case someone needs it. I could also go along 
> and remove it, since I cannot test it, which explains why there are so many 
> inconsistencies with it.

Fair enough. Best drop it for now then. The PCI code is currently undergoing
some changes, and when someone wants to get this to work, they should can
probably better start from scratch with an independent bus driver that will
end up looking much simpler than what you have today.

	Arnd

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-17 13:07           ` Arnd Bergmann
  0 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 17 July 2012, Florian Fainelli wrote:
> On Monday 16 July 2012 15:54:04 Arnd Bergmann wrote:
> > On Sunday 15 July 2012, Florian Fainelli wrote:
> > 
> > > diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
> > > new file mode 100644
> > > index 0000000..c89422f
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mcs814x/Kconfig
> > > @@ -0,0 +1,11 @@
> > > +if ARCH_MCS814X
> > > +
> > > +config MCS8140
> > > +	select CPU_ARM926T
> > > +	bool
> > > +
> > > +menu "Moschip MCS8140 boards"
> > > +
> > > +endmenu
> > > +
> > > +endif
> > 
> > What values does the Kconfig file actually provide? I see that you are
> > adding the boards here later, but I think it would be nice to just 
> > make the new platform a single Kconfig option with no individual
> > board selection.
> 
> I plan on adding support for MCS8142 later on, thus I thought it would be nice 
> to be able to selectively compile board support for MCS8140 or some later 
> chip.

But is there much difference between the two? How much code would
actually get built for one chip but not the other? If all the
differences can be run-time detected from the device tree, I
think it's better to not have different compile-time options at
all.

> > Platforms are now converting to the common clock framework in drivers/clk.
> > Mike Turquette as the subsystem maintainer can probably judge better whether
> > we should still be allowing new platforms with their own implementation
> > of clk, but my feeling is that you should use the subsystem instead
> > and add a driver in a subdirectory of drivers/clk instead of in the
> > platform.
> > 
> > > +void __iomem *mcs814x_sysdbg_base;
> > 
> > Does this have to be globally visible? I would recommend making it static.
> 
> Yes, since it is used both by clock.c and common.c

Ok. How about converting this to an global function in common.c that is
called from clk_local_onoff_enable instead?

> > > +void __init mcs814x_map_io(void)
> > > +{
> > > +	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
> > > +
> > > +	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
> > > +					MCS814X_SYSDBG_SIZE);
> > > +	if (!mcs814x_sysdbg_base)
> > > +		panic("unable to remap sysdbg base");
> > > +}
> > > +
> > > +void mcs814x_restart(char mode, const char *cmd)
> > > +{
> > > +	__raw_writel(~(1 << 31), mcs814x_sysdbg_base);
> > > +}
> > 
> > You should generally avoid using __raw_readl etc. and instead use
> > readl/write or readl_relaxed/writel_relaxed.
> 
> Allright, even on an ARM926-EJS-based system?

Yes, there is no practical difference in the way they are defined at
the moment, but the __raw_ versions are still wrong, you should
really never be using them from driver code.

> > > diff --git a/arch/arm/mach-mcs814x/include/mach/cpu.h b/arch/arm/mach-
> mcs814x/include/mach/cpu.h
> > > new file mode 100644
> > > index 0000000..1ef3c4a
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mcs814x/include/mach/cpu.h
> > > @@ -0,0 +1,16 @@
> > > +#ifndef __ASM_ARCH_CPU_H__
> > > +#define __ASM_ARCH_CPU_H__
> > > +
> > > +#include <asm/cputype.h>
> > > +
> > > +#define MCS8140_ID	0x41069260	/* ARM926EJ-S */
> > > +#define MCS814X_MASK	0xff0ffff0
> > > +
> > > +#ifdef CONFIG_MCS8140
> > > +/* Moschip MCS8140 is based on an ARM926EJ-S core */
> > > +#define soc_is_mcs8140()	((read_cpuid_id() & MCS814X_MASK) == MCS8140_ID)
> > > +#else
> > > +#define soc_is_mcs8140()	(0)
> > > +#endif /* !CONFIG_MCS8140 */
> > > +
> > > +#endif /* __ASM_ARCH_CPU_H__ */
> > 
> > Can you explain what this is used for? Are there other SoCs in the same
> > platform that will get added later?
> 
> Yes, that's the plan.

Ok. But why do you need to know the soc type? If it's only for the
uncompress.h code, it should probably stay local to that file.

> > > +/* IRQ controller register offset */
> > > +#define MCS814X_IRQ_ICR		0x00
> > > +#define MCS814X_IRQ_ISR		0x04
> > > +#define MCS814X_IRQ_MASK	0x20
> > > +#define MCS814X_IRQ_STS0	0x40
> > 
> > I'm pretty sure these can be in irq.c
> 
> Not unless I switch to MULTI_IRQ_HANDLER.

I think you should do that, too. Forgot to mention it.

> > > +
> > > +static struct resource io_mem = {
> > > +	.name	= "PCI I/O space",
> > > +	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE,
> > > +	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE + SZ_64M,
> > > +	.flags	= IORESOURCE_IO,
> > > +};
> > 
> > This is wrong: MCS8140_PCI_HOST_BASE is an address in IORESOURCE_MEM space.
> > You probably also mean SZ_64K instead of SZ_64M.
> 
> I will double check with the hardware manual, but I really think it is 
> 64MBytes.

Are there any devices hardwired to your PCI bus that require more than a few
bytes of I/O space? If not, I think it should be 64KB. No known add-on
cards require more than that, and it would just waste virtual address space,
and prevents us from using the new common PCI I/O space helpers.

> > 
> > Leave this one at the default of 0x1000. MCS8140_PCI_HOST_BASE is the
> > address from the CPU's point of view, not from the bus. You just need
> > to stay out of the range of possible legacy ISA devices.
> > 
> > It's probably a good idea to keep the PCI support as a separate patch
> > for reviewing purposes.
> 
> Good idea, I will do that. Note that none of the boards I have actually have 
> PCI, so the code is just there in case someone needs it. I could also go along 
> and remove it, since I cannot test it, which explains why there are so many 
> inconsistencies with it.

Fair enough. Best drop it for now then. The PCI code is currently undergoing
some changes, and when someone wants to get this to work, they should can
probably better start from scratch with an independent bus driver that will
end up looking much simpler than what you have today.

	Arnd

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-17 10:16         ` Thomas Petazzoni
@ 2012-07-17 13:12           ` Arnd Bergmann
  -1 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:12 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Mike Turquette, Florian Fainelli,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tuesday 17 July 2012, Thomas Petazzoni wrote:
> Le Mon, 16 Jul 2012 15:54:04 +0000,
> Arnd Bergmann <arnd@arndb.de> a écrit :
> 
> > > +void mcs814x_restart(char mode, const char *cmd)
> > > +{
> > > +   __raw_writel(~(1 << 31), mcs814x_sysdbg_base);
> > > +}
> > 
> > You should generally avoid using __raw_readl etc. and instead use
> > readl/write or readl_relaxed/writel_relaxed.
> 
> I thought that readl/writel and readl_relaxed/writel_relaxed were used
> for PCI-style access, for which these macros/functions do automatically
> a conversion from the CPU-endianness to the PCI-endianness
> (little-endian). Here of course, this the SoC is used little-endian, it
> will just work because readl/writel will not do any endianness
> conversion, but if we were on a big-endian machine?
> 
> My understanding until now was that __raw_readl/__raw_writel should be
> used for accesses with native endianness, but apparently, it's more
> subtle than this. Would you mind expanding a bit on this?

The __raw_* versions are basically only valid if you access a memory
buffer, such as a video framebuffer. They do the conversion of an
__iomem pointer into something that can be accessed by the compiler.

The non-raw versions have fixed endianess, guarantee that the access
is done atomically (could be byte-wise otherwise) and that all the
necessary barriers are used to synchronize against DMA and out-of-order
execution.

We don't actually have accessors that are CPU-endian and guarantee that
you can access an MMIO register properly.

On powerpc, the convention is that readl/writel should only be used
to access PCI, but that is for the enhanced error handling, not for
endianess.

	Arnd
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-17 13:12           ` Arnd Bergmann
  0 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 17 July 2012, Thomas Petazzoni wrote:
> Le Mon, 16 Jul 2012 15:54:04 +0000,
> Arnd Bergmann <arnd@arndb.de> a ?crit :
> 
> > > +void mcs814x_restart(char mode, const char *cmd)
> > > +{
> > > +   __raw_writel(~(1 << 31), mcs814x_sysdbg_base);
> > > +}
> > 
> > You should generally avoid using __raw_readl etc. and instead use
> > readl/write or readl_relaxed/writel_relaxed.
> 
> I thought that readl/writel and readl_relaxed/writel_relaxed were used
> for PCI-style access, for which these macros/functions do automatically
> a conversion from the CPU-endianness to the PCI-endianness
> (little-endian). Here of course, this the SoC is used little-endian, it
> will just work because readl/writel will not do any endianness
> conversion, but if we were on a big-endian machine?
> 
> My understanding until now was that __raw_readl/__raw_writel should be
> used for accesses with native endianness, but apparently, it's more
> subtle than this. Would you mind expanding a bit on this?

The __raw_* versions are basically only valid if you access a memory
buffer, such as a video framebuffer. They do the conversion of an
__iomem pointer into something that can be accessed by the compiler.

The non-raw versions have fixed endianess, guarantee that the access
is done atomically (could be byte-wise otherwise) and that all the
necessary barriers are used to synchronize against DMA and out-of-order
execution.

We don't actually have accessors that are CPU-endian and guarantee that
you can access an MMIO register properly.

On powerpc, the convention is that readl/writel should only be used
to access PCI, but that is for the enhanced error handling, not for
endianess.

	Arnd

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

* Re: [PATCH 2/8] ARM: MCS814x: add Device Tree based MCS8140 board support
  2012-07-15 14:49   ` Florian Fainelli
@ 2012-07-17 13:19       ` Arnd Bergmann
  -1 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:19 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Sunday 15 July 2012, Florian Fainelli wrote:

> +
> +			uart0: serial@400dc000 {
> +				compatible = "ns16550";
> +				reg = <0x400dc000 0x20>;
> +				clock-frequency = <50000000>;
> +				reg-shift = <2>;
> +				interrupts = <21>;
> +				status = "okay";
> +			};

We often mark stuff like the uart as status="disabled" in the .dtsi file
and only enable it in the board specific .dts file when it's actually
connected. For components that are always present and usable, that's
of course not necessary.

> +
> +			adc {
> +				compatible = "simple-bus";
> +				#address-cells = <2>;
> +				#size-cells = <1>;
> +				// 8 64MB chip-selects
> +				ranges = <0 0 0x00000000 0x4000000	// sdram
> +					  1 0 0x04000000 0x4000000	// sdram
> +					  2 0 0x08000000 0x4000000	// reserved
> +					  3 0 0x0c000000 0x4000000	// flash/localbus
> +					  4 0 0x10000000 0x4000000	// flash/localbus
> +					  5 0 0x14000000 0x4000000	// flash/localbus
> +					  6 0 0x18000000 0x4000000	// flash/localbus
> +					  7 0 0x1c000000 0x4000000>;	// flash/localbus
> +
> +				sdram: memory@0,0 {
> +					reg = <0 0 0>;
> +				};
> +
> +				nor: flash@7,0 {
> +					reg = <7 0 0x4000000>;
> +					compatible = "cfi-flash";
> +					bank-width = <1>;		// 8-bit external flash
> +					#address-cells = <1>;
> +					#size-cells = <1>;
> +                                };
> +                        };

Nice representation of the external buses. It does seem however that at
least the nor flash entry is board specific and should be moved into the
board .dts file.
I would probably do the same for the memory node, but that one is less
obvious as it seems that there is not much choice here.

> +			usb0: ehci@400fc000 {
> +				compatible = "moschip,mcs814x-ehci", "usb-ehci";
> +				reg = <0x400fc000 0x74>;
> +				interrupts = <2>;
> +			};
> +
> +			usb1: ohci@400fd000 {
> +				compatible = "moschip,mcs814x-ohci", "ohci-le";
> +				reg = <0x400fd000 0x74>;
> +				interrupts = <11>;
> +			};
> +
> +			usb2: ohci@400fe000 {
> +				compatible = "moschip,mcs814x-ohci", "ohci-le";
> +				reg = <0x400fe000 0x74>;
> +				interrupts = <12>;
> +			};
> +
> +			usb3: otg@400ff000 {
> +				compatible = "moschip,msc814x-otg", "usb-otg";
> +				reg = <0x400ff000 0x1000>;
> +				interrupts = <13>;
> +			};

same comment as for the uart, I would mark these as disabled and only
enable the ones that are connected on a give board.

> +
> +static void __init mcs814x_dt_device_init(void)
> +{
> +	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> +	mcs814x_init_machine();
> +}
> +
> +static const char *mcs8140_dt_board_compat[] __initdata = {
> +	"moschip,mcs8140",
> +	NULL,	/* sentinel */
> +};
> +
> +DT_MACHINE_START(mcs8140_dt, "Moschip MCS8140 board")
> +	/* Maintainer: Florian Fainelli <florian-p3rKhJxN3npAfugRpC6u6w@public.gmane.org> */
> +	.timer		= &mcs814x_timer,
> +	.map_io		= mcs814x_map_io,
> +	.init_early	= mcs814x_clk_init,
> +	.init_irq	= mcs814x_of_irq_init,
> +	.init_machine	= mcs814x_dt_device_init,
> +	.restart	= mcs814x_restart,
> +	.dt_compat	= mcs8140_dt_board_compat,
> +MACHINE_END

Not much to see here. Just move this into the common.c file. There is no
need to have a separate board file when all boards use the same one.

	Arnd

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

* [PATCH 2/8] ARM: MCS814x: add Device Tree based MCS8140 board support
@ 2012-07-17 13:19       ` Arnd Bergmann
  0 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 15 July 2012, Florian Fainelli wrote:

> +
> +			uart0: serial at 400dc000 {
> +				compatible = "ns16550";
> +				reg = <0x400dc000 0x20>;
> +				clock-frequency = <50000000>;
> +				reg-shift = <2>;
> +				interrupts = <21>;
> +				status = "okay";
> +			};

We often mark stuff like the uart as status="disabled" in the .dtsi file
and only enable it in the board specific .dts file when it's actually
connected. For components that are always present and usable, that's
of course not necessary.

> +
> +			adc {
> +				compatible = "simple-bus";
> +				#address-cells = <2>;
> +				#size-cells = <1>;
> +				// 8 64MB chip-selects
> +				ranges = <0 0 0x00000000 0x4000000	// sdram
> +					  1 0 0x04000000 0x4000000	// sdram
> +					  2 0 0x08000000 0x4000000	// reserved
> +					  3 0 0x0c000000 0x4000000	// flash/localbus
> +					  4 0 0x10000000 0x4000000	// flash/localbus
> +					  5 0 0x14000000 0x4000000	// flash/localbus
> +					  6 0 0x18000000 0x4000000	// flash/localbus
> +					  7 0 0x1c000000 0x4000000>;	// flash/localbus
> +
> +				sdram: memory at 0,0 {
> +					reg = <0 0 0>;
> +				};
> +
> +				nor: flash at 7,0 {
> +					reg = <7 0 0x4000000>;
> +					compatible = "cfi-flash";
> +					bank-width = <1>;		// 8-bit external flash
> +					#address-cells = <1>;
> +					#size-cells = <1>;
> +                                };
> +                        };

Nice representation of the external buses. It does seem however that at
least the nor flash entry is board specific and should be moved into the
board .dts file.
I would probably do the same for the memory node, but that one is less
obvious as it seems that there is not much choice here.

> +			usb0: ehci at 400fc000 {
> +				compatible = "moschip,mcs814x-ehci", "usb-ehci";
> +				reg = <0x400fc000 0x74>;
> +				interrupts = <2>;
> +			};
> +
> +			usb1: ohci at 400fd000 {
> +				compatible = "moschip,mcs814x-ohci", "ohci-le";
> +				reg = <0x400fd000 0x74>;
> +				interrupts = <11>;
> +			};
> +
> +			usb2: ohci at 400fe000 {
> +				compatible = "moschip,mcs814x-ohci", "ohci-le";
> +				reg = <0x400fe000 0x74>;
> +				interrupts = <12>;
> +			};
> +
> +			usb3: otg at 400ff000 {
> +				compatible = "moschip,msc814x-otg", "usb-otg";
> +				reg = <0x400ff000 0x1000>;
> +				interrupts = <13>;
> +			};

same comment as for the uart, I would mark these as disabled and only
enable the ones that are connected on a give board.

> +
> +static void __init mcs814x_dt_device_init(void)
> +{
> +	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> +	mcs814x_init_machine();
> +}
> +
> +static const char *mcs8140_dt_board_compat[] __initdata = {
> +	"moschip,mcs8140",
> +	NULL,	/* sentinel */
> +};
> +
> +DT_MACHINE_START(mcs8140_dt, "Moschip MCS8140 board")
> +	/* Maintainer: Florian Fainelli <florian@openwrt.org> */
> +	.timer		= &mcs814x_timer,
> +	.map_io		= mcs814x_map_io,
> +	.init_early	= mcs814x_clk_init,
> +	.init_irq	= mcs814x_of_irq_init,
> +	.init_machine	= mcs814x_dt_device_init,
> +	.restart	= mcs814x_restart,
> +	.dt_compat	= mcs8140_dt_board_compat,
> +MACHINE_END

Not much to see here. Just move this into the common.c file. There is no
need to have a separate board file when all boards use the same one.

	Arnd

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

* Re: [PATCH 3/8] ARM: MCS814x: add Device Tree bindings documentation
  2012-07-15 14:49   ` Florian Fainelli
@ 2012-07-17 13:24       ` Arnd Bergmann
  -1 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:24 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Sunday 15 July 2012, Florian Fainelli wrote:

> diff --git a/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
> new file mode 100644
> index 0000000..de59b04
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
> @@ -0,0 +1,16 @@
> +Moschip MCS814x PCI controller bindings
> +---------------------------------------
> +
> +Required properties:
> +- compatible: should be "moschip,mcs814x-pci"
> +- reg: should contain the base register address and length of the PCI controller
> +  configuration register as well as the base register address and length of the
> +  PCI eeprom emulator
> +- interrupts: should contain the interrupt line of the abort interrupt
> +- #address-cells: should be 3
> +- #size-cells: should be 2
> +- ranges: should contain the properly encoded PCI ranges of the IO, non-prefetchable
> +  and prefetchable memory regions
> +- #interrupt-cells: should be 1
> +- interrupt-map-mask: should be 0
> +- interrupt-map: should be the properly encoded PCI slot/pin to interrupt line

interrupt-map-mask of 0 implies that all devices are wired to the
same IRQ lines, which is rather unusual. Better leave that open
so the interrupt-map can be written to work on any board.

> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
> index 6eab917..943e4f3 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> @@ -28,6 +28,7 @@ linux	Linux-specific binding
>  marvell	Marvell Technology Group Ltd.
>  maxim	Maxim Integrated Products
>  mosaixtech	Mosaix Technologies, Inc.
> +moschp		Moschip Semiconductors
>  national	National Semiconductor
>  nintendo	Nintendo
>  nvidia	NVIDIA

This string does not match what you use everywhere else. Please fix
either the documentation here or every other instance. The stock
ticker symbol is MOSCHIP.BO, so using "moschip" is probably better
than "moschp".

	Arnd

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

* [PATCH 3/8] ARM: MCS814x: add Device Tree bindings documentation
@ 2012-07-17 13:24       ` Arnd Bergmann
  0 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 15 July 2012, Florian Fainelli wrote:

> diff --git a/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
> new file mode 100644
> index 0000000..de59b04
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
> @@ -0,0 +1,16 @@
> +Moschip MCS814x PCI controller bindings
> +---------------------------------------
> +
> +Required properties:
> +- compatible: should be "moschip,mcs814x-pci"
> +- reg: should contain the base register address and length of the PCI controller
> +  configuration register as well as the base register address and length of the
> +  PCI eeprom emulator
> +- interrupts: should contain the interrupt line of the abort interrupt
> +- #address-cells: should be 3
> +- #size-cells: should be 2
> +- ranges: should contain the properly encoded PCI ranges of the IO, non-prefetchable
> +  and prefetchable memory regions
> +- #interrupt-cells: should be 1
> +- interrupt-map-mask: should be 0
> +- interrupt-map: should be the properly encoded PCI slot/pin to interrupt line

interrupt-map-mask of 0 implies that all devices are wired to the
same IRQ lines, which is rather unusual. Better leave that open
so the interrupt-map can be written to work on any board.

> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
> index 6eab917..943e4f3 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> @@ -28,6 +28,7 @@ linux	Linux-specific binding
>  marvell	Marvell Technology Group Ltd.
>  maxim	Maxim Integrated Products
>  mosaixtech	Mosaix Technologies, Inc.
> +moschp		Moschip Semiconductors
>  national	National Semiconductor
>  nintendo	Nintendo
>  nvidia	NVIDIA

This string does not match what you use everywhere else. Please fix
either the documentation here or every other instance. The stock
ticker symbol is MOSCHIP.BO, so using "moschip" is probably better
than "moschp".

	Arnd

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

* Re: [PATCH 4/8] ARM: MCS814X: add DTS file for Tigal/Robotech RBT-832
  2012-07-15 14:49   ` Florian Fainelli
@ 2012-07-17 13:27       ` Arnd Bergmann
  -1 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:27 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Sunday 15 July 2012, Florian Fainelli wrote:

> +	model = "Tigal RBT-832";
> +	compatible = "tigal,rbt-832", "moschip,mcs8140", "moschip,mcs814x";
> +
> +	chosen {
> +		bootargs = "mem=32M console=ttyS0,115200 earlyprintk";
> +	};

I think the mem=32M doesn't belong here, it's already specified in the memory
node.

> diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
> index c89422f..604537b 100644
> --- a/arch/arm/mach-mcs814x/Kconfig
> +++ b/arch/arm/mach-mcs814x/Kconfig
> @@ -6,6 +6,15 @@ config MCS8140
>  
>  menu "Moschip MCS8140 boards"
>  
> +config MACH_RBT_832
> +	bool "Tigal RBT-832"
> +	select MCS8140
> +	select NEW_LEDS
> +	select LEDS_CLASS
> +	select LEDS_GPIO
> +	help
> +	  Machine support for the Tigal RBT-832 board
> +
>  endmenu
>  
>  endif

I would prefer not to have any additional symbols selected by the board.
It's better to put those into the defconfig.

> @@ -27,6 +27,7 @@ static void __init mcs814x_dt_device_init(void)
>  }
>  
>  static const char *mcs8140_dt_board_compat[] __initdata = {
> +	"tigal,rbt-832",
>  	"moschip,mcs8140",
>  	NULL,	/* sentinel */
>  };

I'm not sure what the normal practice is these days regarding the 
board compatible table. I thought that we just put the soc name
in there for new platforms that are already DT-only. Your .dts
file contains both, so it works either way.

	Arnd

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

* [PATCH 4/8] ARM: MCS814X: add DTS file for Tigal/Robotech RBT-832
@ 2012-07-17 13:27       ` Arnd Bergmann
  0 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 15 July 2012, Florian Fainelli wrote:

> +	model = "Tigal RBT-832";
> +	compatible = "tigal,rbt-832", "moschip,mcs8140", "moschip,mcs814x";
> +
> +	chosen {
> +		bootargs = "mem=32M console=ttyS0,115200 earlyprintk";
> +	};

I think the mem=32M doesn't belong here, it's already specified in the memory
node.

> diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-mcs814x/Kconfig
> index c89422f..604537b 100644
> --- a/arch/arm/mach-mcs814x/Kconfig
> +++ b/arch/arm/mach-mcs814x/Kconfig
> @@ -6,6 +6,15 @@ config MCS8140
>  
>  menu "Moschip MCS8140 boards"
>  
> +config MACH_RBT_832
> +	bool "Tigal RBT-832"
> +	select MCS8140
> +	select NEW_LEDS
> +	select LEDS_CLASS
> +	select LEDS_GPIO
> +	help
> +	  Machine support for the Tigal RBT-832 board
> +
>  endmenu
>  
>  endif

I would prefer not to have any additional symbols selected by the board.
It's better to put those into the defconfig.

> @@ -27,6 +27,7 @@ static void __init mcs814x_dt_device_init(void)
>  }
>  
>  static const char *mcs8140_dt_board_compat[] __initdata = {
> +	"tigal,rbt-832",
>  	"moschip,mcs8140",
>  	NULL,	/* sentinel */
>  };

I'm not sure what the normal practice is these days regarding the 
board compatible table. I thought that we just put the soc name
in there for new platforms that are already DT-only. Your .dts
file contains both, so it works either way.

	Arnd

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-17 13:12           ` Arnd Bergmann
@ 2012-07-17 13:28             ` Thomas Petazzoni
  -1 siblings, 0 replies; 80+ messages in thread
From: Thomas Petazzoni @ 2012-07-17 13:28 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Mike Turquette, Linus Walleij, Florian Fainelli, olof,
	devicetree-discuss, linux-arm-kernel

Hello,

Thanks a lot for those details.

Le Tue, 17 Jul 2012 13:12:06 +0000,
Arnd Bergmann <arnd@arndb.de> a écrit :

> > My understanding until now was that __raw_readl/__raw_writel should
> > be used for accesses with native endianness, but apparently, it's
> > more subtle than this. Would you mind expanding a bit on this?
> 
> The __raw_* versions are basically only valid if you access a memory
> buffer, such as a video framebuffer. They do the conversion of an
> __iomem pointer into something that can be accessed by the compiler.
> 
> The non-raw versions have fixed endianess, guarantee that the access
> is done atomically (could be byte-wise otherwise) and that all the
> necessary barriers are used to synchronize against DMA and
> out-of-order execution.
> 
> We don't actually have accessors that are CPU-endian and guarantee
> that you can access an MMIO register properly.
> 
> On powerpc, the convention is that readl/writel should only be used
> to access PCI, but that is for the enhanced error handling, not for
> endianess.

And then, on PowerPC, which accessors do you use to access
SoC-peripherals that are not on the PCI bus?

For example, drivers/tty/serial/mpsc.c uses writel/readl, so a
conversion to/from little-endian is done when writing/reading
registers. Are those memory-mapped devices little-endian even though
they are used on big-endian PowerPCs?

I apologize for the silly questions, but I'm trying to make some sense
out of these numerous I/O and memory accessors.

Thanks,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-17 13:28             ` Thomas Petazzoni
  0 siblings, 0 replies; 80+ messages in thread
From: Thomas Petazzoni @ 2012-07-17 13:28 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

Thanks a lot for those details.

Le Tue, 17 Jul 2012 13:12:06 +0000,
Arnd Bergmann <arnd@arndb.de> a ?crit :

> > My understanding until now was that __raw_readl/__raw_writel should
> > be used for accesses with native endianness, but apparently, it's
> > more subtle than this. Would you mind expanding a bit on this?
> 
> The __raw_* versions are basically only valid if you access a memory
> buffer, such as a video framebuffer. They do the conversion of an
> __iomem pointer into something that can be accessed by the compiler.
> 
> The non-raw versions have fixed endianess, guarantee that the access
> is done atomically (could be byte-wise otherwise) and that all the
> necessary barriers are used to synchronize against DMA and
> out-of-order execution.
> 
> We don't actually have accessors that are CPU-endian and guarantee
> that you can access an MMIO register properly.
> 
> On powerpc, the convention is that readl/writel should only be used
> to access PCI, but that is for the enhanced error handling, not for
> endianess.

And then, on PowerPC, which accessors do you use to access
SoC-peripherals that are not on the PCI bus?

For example, drivers/tty/serial/mpsc.c uses writel/readl, so a
conversion to/from little-endian is done when writing/reading
registers. Are those memory-mapped devices little-endian even though
they are used on big-endian PowerPCs?

I apologize for the silly questions, but I'm trying to make some sense
out of these numerous I/O and memory accessors.

Thanks,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-17 13:07           ` Arnd Bergmann
@ 2012-07-17 13:32             ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17 13:32 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: olof, Linus Walleij, Mike Turquette, devicetree-discuss,
	linux-arm-kernel

On Tuesday 17 July 2012 13:07:23 Arnd Bergmann wrote:
> On Tuesday 17 July 2012, Florian Fainelli wrote:
> > On Monday 16 July 2012 15:54:04 Arnd Bergmann wrote:
> > > On Sunday 15 July 2012, Florian Fainelli wrote:
> > > 
> > > > diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-
mcs814x/Kconfig
> > > > new file mode 100644
> > > > index 0000000..c89422f
> > > > --- /dev/null
> > > > +++ b/arch/arm/mach-mcs814x/Kconfig
> > > > @@ -0,0 +1,11 @@
> > > > +if ARCH_MCS814X
> > > > +
> > > > +config MCS8140
> > > > +	select CPU_ARM926T
> > > > +	bool
> > > > +
> > > > +menu "Moschip MCS8140 boards"
> > > > +
> > > > +endmenu
> > > > +
> > > > +endif
> > > 
> > > What values does the Kconfig file actually provide? I see that you are
> > > adding the boards here later, but I think it would be nice to just 
> > > make the new platform a single Kconfig option with no individual
> > > board selection.
> > 
> > I plan on adding support for MCS8142 later on, thus I thought it would be 
nice 
> > to be able to selectively compile board support for MCS8140 or some later 
> > chip.
> 
> But is there much difference between the two? How much code would
> actually get built for one chip but not the other? If all the
> differences can be run-time detected from the device tree, I
> think it's better to not have different compile-time options at
> all.

The big difference between the two is actually the CPU core, for MCS8140 they 
used a genuine ARM926EJS and for MCS8142 they actually use a FA526 core.

> 
> > > Platforms are now converting to the common clock framework in 
drivers/clk.
> > > Mike Turquette as the subsystem maintainer can probably judge better 
whether
> > > we should still be allowing new platforms with their own implementation
> > > of clk, but my feeling is that you should use the subsystem instead
> > > and add a driver in a subdirectory of drivers/clk instead of in the
> > > platform.
> > > 
> > > > +void __iomem *mcs814x_sysdbg_base;
> > > 
> > > Does this have to be globally visible? I would recommend making it 
static.
> > 
> > Yes, since it is used both by clock.c and common.c
> 
> Ok. How about converting this to an global function in common.c that is
> called from clk_local_onoff_enable instead?

Sounds good.

> 
> > > > +void __init mcs814x_map_io(void)
> > > > +{
> > > > +	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
> > > > +
> > > > +	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
> > > > +					MCS814X_SYSDBG_SIZE);
> > > > +	if (!mcs814x_sysdbg_base)
> > > > +		panic("unable to remap sysdbg base");
> > > > +}
> > > > +
> > > > +void mcs814x_restart(char mode, const char *cmd)
> > > > +{
> > > > +	__raw_writel(~(1 << 31), mcs814x_sysdbg_base);
> > > > +}
> > > 
> > > You should generally avoid using __raw_readl etc. and instead use
> > > readl/write or readl_relaxed/writel_relaxed.
> > 
> > Allright, even on an ARM926-EJS-based system?
> 
> Yes, there is no practical difference in the way they are defined at
> the moment, but the __raw_ versions are still wrong, you should
> really never be using them from driver code.
> 
> > > > diff --git a/arch/arm/mach-mcs814x/include/mach/cpu.h b/arch/arm/mach-
> > mcs814x/include/mach/cpu.h
> > > > new file mode 100644
> > > > index 0000000..1ef3c4a
> > > > --- /dev/null
> > > > +++ b/arch/arm/mach-mcs814x/include/mach/cpu.h
> > > > @@ -0,0 +1,16 @@
> > > > +#ifndef __ASM_ARCH_CPU_H__
> > > > +#define __ASM_ARCH_CPU_H__
> > > > +
> > > > +#include <asm/cputype.h>
> > > > +
> > > > +#define MCS8140_ID	0x41069260	/* ARM926EJ-S */
> > > > +#define MCS814X_MASK	0xff0ffff0
> > > > +
> > > > +#ifdef CONFIG_MCS8140
> > > > +/* Moschip MCS8140 is based on an ARM926EJ-S core */
> > > > +#define soc_is_mcs8140()	((read_cpuid_id() & MCS814X_MASK) == 
MCS8140_ID)
> > > > +#else
> > > > +#define soc_is_mcs8140()	(0)
> > > > +#endif /* !CONFIG_MCS8140 */
> > > > +
> > > > +#endif /* __ASM_ARCH_CPU_H__ */
> > > 
> > > Can you explain what this is used for? Are there other SoCs in the same
> > > platform that will get added later?
> > 
> > Yes, that's the plan.
> 
> Ok. But why do you need to know the soc type? If it's only for the
> uncompress.h code, it should probably stay local to that file.



> 
> > > > +/* IRQ controller register offset */
> > > > +#define MCS814X_IRQ_ICR		0x00
> > > > +#define MCS814X_IRQ_ISR		0x04
> > > > +#define MCS814X_IRQ_MASK	0x20
> > > > +#define MCS814X_IRQ_STS0	0x40
> > > 
> > > I'm pretty sure these can be in irq.c
> > 
> > Not unless I switch to MULTI_IRQ_HANDLER.
> 
> I think you should do that, too. Forgot to mention it.
> 
> > > > +
> > > > +static struct resource io_mem = {
> > > > +	.name	= "PCI I/O space",
> > > > +	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE,
> > > > +	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE + SZ_64M,
> > > > +	.flags	= IORESOURCE_IO,
> > > > +};
> > > 
> > > This is wrong: MCS8140_PCI_HOST_BASE is an address in IORESOURCE_MEM 
space.
> > > You probably also mean SZ_64K instead of SZ_64M.
> > 
> > I will double check with the hardware manual, but I really think it is 
> > 64MBytes.
> 
> Are there any devices hardwired to your PCI bus that require more than a few
> bytes of I/O space? If not, I think it should be 64KB. No known add-on
> cards require more than that, and it would just waste virtual address space,
> and prevents us from using the new common PCI I/O space helpers.

Ok.

> 
> > > 
> > > Leave this one at the default of 0x1000. MCS8140_PCI_HOST_BASE is the
> > > address from the CPU's point of view, not from the bus. You just need
> > > to stay out of the range of possible legacy ISA devices.
> > > 
> > > It's probably a good idea to keep the PCI support as a separate patch
> > > for reviewing purposes.
> > 
> > Good idea, I will do that. Note that none of the boards I have actually 
have 
> > PCI, so the code is just there in case someone needs it. I could also go 
along 
> > and remove it, since I cannot test it, which explains why there are so 
many 
> > inconsistencies with it.
> 
> Fair enough. Best drop it for now then. The PCI code is currently undergoing
> some changes, and when someone wants to get this to work, they should can
> probably better start from scratch with an independent bus driver that will
> end up looking much simpler than what you have today.

Yeah, I like that :)

> 
> 	Arnd

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-17 13:32             ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 17 July 2012 13:07:23 Arnd Bergmann wrote:
> On Tuesday 17 July 2012, Florian Fainelli wrote:
> > On Monday 16 July 2012 15:54:04 Arnd Bergmann wrote:
> > > On Sunday 15 July 2012, Florian Fainelli wrote:
> > > 
> > > > diff --git a/arch/arm/mach-mcs814x/Kconfig b/arch/arm/mach-
mcs814x/Kconfig
> > > > new file mode 100644
> > > > index 0000000..c89422f
> > > > --- /dev/null
> > > > +++ b/arch/arm/mach-mcs814x/Kconfig
> > > > @@ -0,0 +1,11 @@
> > > > +if ARCH_MCS814X
> > > > +
> > > > +config MCS8140
> > > > +	select CPU_ARM926T
> > > > +	bool
> > > > +
> > > > +menu "Moschip MCS8140 boards"
> > > > +
> > > > +endmenu
> > > > +
> > > > +endif
> > > 
> > > What values does the Kconfig file actually provide? I see that you are
> > > adding the boards here later, but I think it would be nice to just 
> > > make the new platform a single Kconfig option with no individual
> > > board selection.
> > 
> > I plan on adding support for MCS8142 later on, thus I thought it would be 
nice 
> > to be able to selectively compile board support for MCS8140 or some later 
> > chip.
> 
> But is there much difference between the two? How much code would
> actually get built for one chip but not the other? If all the
> differences can be run-time detected from the device tree, I
> think it's better to not have different compile-time options at
> all.

The big difference between the two is actually the CPU core, for MCS8140 they 
used a genuine ARM926EJS and for MCS8142 they actually use a FA526 core.

> 
> > > Platforms are now converting to the common clock framework in 
drivers/clk.
> > > Mike Turquette as the subsystem maintainer can probably judge better 
whether
> > > we should still be allowing new platforms with their own implementation
> > > of clk, but my feeling is that you should use the subsystem instead
> > > and add a driver in a subdirectory of drivers/clk instead of in the
> > > platform.
> > > 
> > > > +void __iomem *mcs814x_sysdbg_base;
> > > 
> > > Does this have to be globally visible? I would recommend making it 
static.
> > 
> > Yes, since it is used both by clock.c and common.c
> 
> Ok. How about converting this to an global function in common.c that is
> called from clk_local_onoff_enable instead?

Sounds good.

> 
> > > > +void __init mcs814x_map_io(void)
> > > > +{
> > > > +	iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
> > > > +
> > > > +	mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
> > > > +					MCS814X_SYSDBG_SIZE);
> > > > +	if (!mcs814x_sysdbg_base)
> > > > +		panic("unable to remap sysdbg base");
> > > > +}
> > > > +
> > > > +void mcs814x_restart(char mode, const char *cmd)
> > > > +{
> > > > +	__raw_writel(~(1 << 31), mcs814x_sysdbg_base);
> > > > +}
> > > 
> > > You should generally avoid using __raw_readl etc. and instead use
> > > readl/write or readl_relaxed/writel_relaxed.
> > 
> > Allright, even on an ARM926-EJS-based system?
> 
> Yes, there is no practical difference in the way they are defined at
> the moment, but the __raw_ versions are still wrong, you should
> really never be using them from driver code.
> 
> > > > diff --git a/arch/arm/mach-mcs814x/include/mach/cpu.h b/arch/arm/mach-
> > mcs814x/include/mach/cpu.h
> > > > new file mode 100644
> > > > index 0000000..1ef3c4a
> > > > --- /dev/null
> > > > +++ b/arch/arm/mach-mcs814x/include/mach/cpu.h
> > > > @@ -0,0 +1,16 @@
> > > > +#ifndef __ASM_ARCH_CPU_H__
> > > > +#define __ASM_ARCH_CPU_H__
> > > > +
> > > > +#include <asm/cputype.h>
> > > > +
> > > > +#define MCS8140_ID	0x41069260	/* ARM926EJ-S */
> > > > +#define MCS814X_MASK	0xff0ffff0
> > > > +
> > > > +#ifdef CONFIG_MCS8140
> > > > +/* Moschip MCS8140 is based on an ARM926EJ-S core */
> > > > +#define soc_is_mcs8140()	((read_cpuid_id() & MCS814X_MASK) == 
MCS8140_ID)
> > > > +#else
> > > > +#define soc_is_mcs8140()	(0)
> > > > +#endif /* !CONFIG_MCS8140 */
> > > > +
> > > > +#endif /* __ASM_ARCH_CPU_H__ */
> > > 
> > > Can you explain what this is used for? Are there other SoCs in the same
> > > platform that will get added later?
> > 
> > Yes, that's the plan.
> 
> Ok. But why do you need to know the soc type? If it's only for the
> uncompress.h code, it should probably stay local to that file.



> 
> > > > +/* IRQ controller register offset */
> > > > +#define MCS814X_IRQ_ICR		0x00
> > > > +#define MCS814X_IRQ_ISR		0x04
> > > > +#define MCS814X_IRQ_MASK	0x20
> > > > +#define MCS814X_IRQ_STS0	0x40
> > > 
> > > I'm pretty sure these can be in irq.c
> > 
> > Not unless I switch to MULTI_IRQ_HANDLER.
> 
> I think you should do that, too. Forgot to mention it.
> 
> > > > +
> > > > +static struct resource io_mem = {
> > > > +	.name	= "PCI I/O space",
> > > > +	.start	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE,
> > > > +	.end	= MCS8140_PCI_HOST_BASE + MCS8140_PCI_IOMISC_BASE + SZ_64M,
> > > > +	.flags	= IORESOURCE_IO,
> > > > +};
> > > 
> > > This is wrong: MCS8140_PCI_HOST_BASE is an address in IORESOURCE_MEM 
space.
> > > You probably also mean SZ_64K instead of SZ_64M.
> > 
> > I will double check with the hardware manual, but I really think it is 
> > 64MBytes.
> 
> Are there any devices hardwired to your PCI bus that require more than a few
> bytes of I/O space? If not, I think it should be 64KB. No known add-on
> cards require more than that, and it would just waste virtual address space,
> and prevents us from using the new common PCI I/O space helpers.

Ok.

> 
> > > 
> > > Leave this one at the default of 0x1000. MCS8140_PCI_HOST_BASE is the
> > > address from the CPU's point of view, not from the bus. You just need
> > > to stay out of the range of possible legacy ISA devices.
> > > 
> > > It's probably a good idea to keep the PCI support as a separate patch
> > > for reviewing purposes.
> > 
> > Good idea, I will do that. Note that none of the boards I have actually 
have 
> > PCI, so the code is just there in case someone needs it. I could also go 
along 
> > and remove it, since I cannot test it, which explains why there are so 
many 
> > inconsistencies with it.
> 
> Fair enough. Best drop it for now then. The PCI code is currently undergoing
> some changes, and when someone wants to get this to work, they should can
> probably better start from scratch with an independent bus driver that will
> end up looking much simpler than what you have today.

Yeah, I like that :)

> 
> 	Arnd

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

* Re: [PATCH 2/8] ARM: MCS814x: add Device Tree based MCS8140 board support
  2012-07-17 13:19       ` Arnd Bergmann
@ 2012-07-17 13:34         ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17 13:34 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: olof, devicetree-discuss, linux-arm-kernel

On Tuesday 17 July 2012 13:19:43 Arnd Bergmann wrote:
> On Sunday 15 July 2012, Florian Fainelli wrote:
> 
> > +
> > +			uart0: serial@400dc000 {
> > +				compatible = "ns16550";
> > +				reg = <0x400dc000 0x20>;
> > +				clock-frequency = <50000000>;
> > +				reg-shift = <2>;
> > +				interrupts = <21>;
> > +				status = "okay";
> > +			};
> 
> We often mark stuff like the uart as status="disabled" in the .dtsi file
> and only enable it in the board specific .dts file when it's actually
> connected. For components that are always present and usable, that's
> of course not necessary.

Ok, I thought it could be handy to have the uart enabled by default to avoid 
mixing with the status property, I don't mind setting it to "disabled" by 
default.

> 
> > +
> > +			adc {
> > +				compatible = "simple-bus";
> > +				#address-cells = <2>;
> > +				#size-cells = <1>;
> > +				// 8 64MB chip-selects
> > +				ranges = <0 0 0x00000000 0x4000000	// sdram
> > +					  1 0 0x04000000 0x4000000	// sdram
> > +					  2 0 0x08000000 0x4000000	// reserved
> > +					  3 0 0x0c000000 0x4000000	// 
flash/localbus
> > +					  4 0 0x10000000 0x4000000	// 
flash/localbus
> > +					  5 0 0x14000000 0x4000000	// 
flash/localbus
> > +					  6 0 0x18000000 0x4000000	// 
flash/localbus
> > +					  7 0 0x1c000000 0x4000000>;	// 
flash/localbus
> > +
> > +				sdram: memory@0,0 {
> > +					reg = <0 0 0>;
> > +				};
> > +
> > +				nor: flash@7,0 {
> > +					reg = <7 0 0x4000000>;
> > +					compatible = "cfi-flash";
> > +					bank-width = <1>;		// 8-bit external 
flash
> > +					#address-cells = <1>;
> > +					#size-cells = <1>;
> > +                                };
> > +                        };
> 
> Nice representation of the external buses. It does seem however that at
> least the nor flash entry is board specific and should be moved into the
> board .dts file.

In fact, MCS8140 only supports 8-bit CFI Flash chips, so this really is the 
common point of all MCS8140-based boards. As you can see in the following 
board-specific DTS patches, only the partition layout is different.

> I would probably do the same for the memory node, but that one is less
> obvious as it seems that there is not much choice here.

The memory node is also overridden by the board-specific DTS files in subsequent 
patches.

> 
> > +			usb0: ehci@400fc000 {
> > +				compatible = "moschip,mcs814x-ehci", "usb-ehci";
> > +				reg = <0x400fc000 0x74>;
> > +				interrupts = <2>;
> > +			};
> > +
> > +			usb1: ohci@400fd000 {
> > +				compatible = "moschip,mcs814x-ohci", "ohci-le";
> > +				reg = <0x400fd000 0x74>;
> > +				interrupts = <11>;
> > +			};
> > +
> > +			usb2: ohci@400fe000 {
> > +				compatible = "moschip,mcs814x-ohci", "ohci-le";
> > +				reg = <0x400fe000 0x74>;
> > +				interrupts = <12>;
> > +			};
> > +
> > +			usb3: otg@400ff000 {
> > +				compatible = "moschip,msc814x-otg", "usb-otg";
> > +				reg = <0x400ff000 0x1000>;
> > +				interrupts = <13>;
> > +			};
> 
> same comment as for the uart, I would mark these as disabled and only
> enable the ones that are connected on a give board.
> 
> > +
> > +static void __init mcs814x_dt_device_init(void)
> > +{
> > +	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> > +	mcs814x_init_machine();
> > +}
> > +
> > +static const char *mcs8140_dt_board_compat[] __initdata = {
> > +	"moschip,mcs8140",
> > +	NULL,	/* sentinel */
> > +};
> > +
> > +DT_MACHINE_START(mcs8140_dt, "Moschip MCS8140 board")
> > +	/* Maintainer: Florian Fainelli <florian@openwrt.org> */
> > +	.timer		= &mcs814x_timer,
> > +	.map_io		= mcs814x_map_io,
> > +	.init_early	= mcs814x_clk_init,
> > +	.init_irq	= mcs814x_of_irq_init,
> > +	.init_machine	= mcs814x_dt_device_init,
> > +	.restart	= mcs814x_restart,
> > +	.dt_compat	= mcs8140_dt_board_compat,
> > +MACHINE_END
> 
> Not much to see here. Just move this into the common.c file. There is no
> need to have a separate board file when all boards use the same one.

Allright.

> 
> 	Arnd

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

* [PATCH 2/8] ARM: MCS814x: add Device Tree based MCS8140 board support
@ 2012-07-17 13:34         ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17 13:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 17 July 2012 13:19:43 Arnd Bergmann wrote:
> On Sunday 15 July 2012, Florian Fainelli wrote:
> 
> > +
> > +			uart0: serial at 400dc000 {
> > +				compatible = "ns16550";
> > +				reg = <0x400dc000 0x20>;
> > +				clock-frequency = <50000000>;
> > +				reg-shift = <2>;
> > +				interrupts = <21>;
> > +				status = "okay";
> > +			};
> 
> We often mark stuff like the uart as status="disabled" in the .dtsi file
> and only enable it in the board specific .dts file when it's actually
> connected. For components that are always present and usable, that's
> of course not necessary.

Ok, I thought it could be handy to have the uart enabled by default to avoid 
mixing with the status property, I don't mind setting it to "disabled" by 
default.

> 
> > +
> > +			adc {
> > +				compatible = "simple-bus";
> > +				#address-cells = <2>;
> > +				#size-cells = <1>;
> > +				// 8 64MB chip-selects
> > +				ranges = <0 0 0x00000000 0x4000000	// sdram
> > +					  1 0 0x04000000 0x4000000	// sdram
> > +					  2 0 0x08000000 0x4000000	// reserved
> > +					  3 0 0x0c000000 0x4000000	// 
flash/localbus
> > +					  4 0 0x10000000 0x4000000	// 
flash/localbus
> > +					  5 0 0x14000000 0x4000000	// 
flash/localbus
> > +					  6 0 0x18000000 0x4000000	// 
flash/localbus
> > +					  7 0 0x1c000000 0x4000000>;	// 
flash/localbus
> > +
> > +				sdram: memory at 0,0 {
> > +					reg = <0 0 0>;
> > +				};
> > +
> > +				nor: flash at 7,0 {
> > +					reg = <7 0 0x4000000>;
> > +					compatible = "cfi-flash";
> > +					bank-width = <1>;		// 8-bit external 
flash
> > +					#address-cells = <1>;
> > +					#size-cells = <1>;
> > +                                };
> > +                        };
> 
> Nice representation of the external buses. It does seem however that at
> least the nor flash entry is board specific and should be moved into the
> board .dts file.

In fact, MCS8140 only supports 8-bit CFI Flash chips, so this really is the 
common point of all MCS8140-based boards. As you can see in the following 
board-specific DTS patches, only the partition layout is different.

> I would probably do the same for the memory node, but that one is less
> obvious as it seems that there is not much choice here.

The memory node is also overridden by the board-specific DTS files in subsequent 
patches.

> 
> > +			usb0: ehci at 400fc000 {
> > +				compatible = "moschip,mcs814x-ehci", "usb-ehci";
> > +				reg = <0x400fc000 0x74>;
> > +				interrupts = <2>;
> > +			};
> > +
> > +			usb1: ohci at 400fd000 {
> > +				compatible = "moschip,mcs814x-ohci", "ohci-le";
> > +				reg = <0x400fd000 0x74>;
> > +				interrupts = <11>;
> > +			};
> > +
> > +			usb2: ohci at 400fe000 {
> > +				compatible = "moschip,mcs814x-ohci", "ohci-le";
> > +				reg = <0x400fe000 0x74>;
> > +				interrupts = <12>;
> > +			};
> > +
> > +			usb3: otg at 400ff000 {
> > +				compatible = "moschip,msc814x-otg", "usb-otg";
> > +				reg = <0x400ff000 0x1000>;
> > +				interrupts = <13>;
> > +			};
> 
> same comment as for the uart, I would mark these as disabled and only
> enable the ones that are connected on a give board.
> 
> > +
> > +static void __init mcs814x_dt_device_init(void)
> > +{
> > +	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> > +	mcs814x_init_machine();
> > +}
> > +
> > +static const char *mcs8140_dt_board_compat[] __initdata = {
> > +	"moschip,mcs8140",
> > +	NULL,	/* sentinel */
> > +};
> > +
> > +DT_MACHINE_START(mcs8140_dt, "Moschip MCS8140 board")
> > +	/* Maintainer: Florian Fainelli <florian@openwrt.org> */
> > +	.timer		= &mcs814x_timer,
> > +	.map_io		= mcs814x_map_io,
> > +	.init_early	= mcs814x_clk_init,
> > +	.init_irq	= mcs814x_of_irq_init,
> > +	.init_machine	= mcs814x_dt_device_init,
> > +	.restart	= mcs814x_restart,
> > +	.dt_compat	= mcs8140_dt_board_compat,
> > +MACHINE_END
> 
> Not much to see here. Just move this into the common.c file. There is no
> need to have a separate board file when all boards use the same one.

Allright.

> 
> 	Arnd

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

* Re: [PATCH 3/8] ARM: MCS814x: add Device Tree bindings documentation
  2012-07-17 13:24       ` Arnd Bergmann
@ 2012-07-17 13:35         ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17 13:35 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: olof, devicetree-discuss, linux-arm-kernel

On Tuesday 17 July 2012 13:24:10 Arnd Bergmann wrote:
> On Sunday 15 July 2012, Florian Fainelli wrote:
> 
> > diff --git a/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt 
b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
> > new file mode 100644
> > index 0000000..de59b04
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
> > @@ -0,0 +1,16 @@
> > +Moschip MCS814x PCI controller bindings
> > +---------------------------------------
> > +
> > +Required properties:
> > +- compatible: should be "moschip,mcs814x-pci"
> > +- reg: should contain the base register address and length of the PCI 
controller
> > +  configuration register as well as the base register address and length 
of the
> > +  PCI eeprom emulator
> > +- interrupts: should contain the interrupt line of the abort interrupt
> > +- #address-cells: should be 3
> > +- #size-cells: should be 2
> > +- ranges: should contain the properly encoded PCI ranges of the IO, non-
prefetchable
> > +  and prefetchable memory regions
> > +- #interrupt-cells: should be 1
> > +- interrupt-map-mask: should be 0
> > +- interrupt-map: should be the properly encoded PCI slot/pin to interrupt 
line
> 
> interrupt-map-mask of 0 implies that all devices are wired to the
> same IRQ lines, which is rather unusual. Better leave that open
> so the interrupt-map can be written to work on any board.
> 
> > diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt 
b/Documentation/devicetree/bindings/vendor-prefixes.txt
> > index 6eab917..943e4f3 100644
> > --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> > +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> > @@ -28,6 +28,7 @@ linux	Linux-specific binding
> >  marvell	Marvell Technology Group Ltd.
> >  maxim	Maxim Integrated Products
> >  mosaixtech	Mosaix Technologies, Inc.
> > +moschp		Moschip Semiconductors
> >  national	National Semiconductor
> >  nintendo	Nintendo
> >  nvidia	NVIDIA
> 
> This string does not match what you use everywhere else. Please fix
> either the documentation here or every other instance. The stock
> ticker symbol is MOSCHIP.BO, so using "moschip" is probably better
> than "moschp".

This was actually a typo, I meant to type "moschip" instead of "moschp", I 
will fix that of course.
--
Florian

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

* [PATCH 3/8] ARM: MCS814x: add Device Tree bindings documentation
@ 2012-07-17 13:35         ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17 13:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 17 July 2012 13:24:10 Arnd Bergmann wrote:
> On Sunday 15 July 2012, Florian Fainelli wrote:
> 
> > diff --git a/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt 
b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
> > new file mode 100644
> > index 0000000..de59b04
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/arm/mcs814x/mcs814x-pci.txt
> > @@ -0,0 +1,16 @@
> > +Moschip MCS814x PCI controller bindings
> > +---------------------------------------
> > +
> > +Required properties:
> > +- compatible: should be "moschip,mcs814x-pci"
> > +- reg: should contain the base register address and length of the PCI 
controller
> > +  configuration register as well as the base register address and length 
of the
> > +  PCI eeprom emulator
> > +- interrupts: should contain the interrupt line of the abort interrupt
> > +- #address-cells: should be 3
> > +- #size-cells: should be 2
> > +- ranges: should contain the properly encoded PCI ranges of the IO, non-
prefetchable
> > +  and prefetchable memory regions
> > +- #interrupt-cells: should be 1
> > +- interrupt-map-mask: should be 0
> > +- interrupt-map: should be the properly encoded PCI slot/pin to interrupt 
line
> 
> interrupt-map-mask of 0 implies that all devices are wired to the
> same IRQ lines, which is rather unusual. Better leave that open
> so the interrupt-map can be written to work on any board.
> 
> > diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt 
b/Documentation/devicetree/bindings/vendor-prefixes.txt
> > index 6eab917..943e4f3 100644
> > --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> > +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> > @@ -28,6 +28,7 @@ linux	Linux-specific binding
> >  marvell	Marvell Technology Group Ltd.
> >  maxim	Maxim Integrated Products
> >  mosaixtech	Mosaix Technologies, Inc.
> > +moschp		Moschip Semiconductors
> >  national	National Semiconductor
> >  nintendo	Nintendo
> >  nvidia	NVIDIA
> 
> This string does not match what you use everywhere else. Please fix
> either the documentation here or every other instance. The stock
> ticker symbol is MOSCHIP.BO, so using "moschip" is probably better
> than "moschp".

This was actually a typo, I meant to type "moschip" instead of "moschp", I 
will fix that of course.
--
Florian

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-17 13:32             ` Florian Fainelli
@ 2012-07-17 13:45               ` Arnd Bergmann
  -1 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:45 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Mike Turquette, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tuesday 17 July 2012, Florian Fainelli wrote:
> On Tuesday 17 July 2012 13:07:23 Arnd Bergmann wrote:

> > But is there much difference between the two? How much code would
> > actually get built for one chip but not the other? If all the
> > differences can be run-time detected from the device tree, I
> > think it's better to not have different compile-time options at
> > all.
> 
> The big difference between the two is actually the CPU core, for MCS8140 they 
> used a genuine ARM926EJS and for MCS8142 they actually use a FA526 core.

Ok, I see. That probably is enough difference to justify separate Kconfig
statements, especially since building a combined ARMv4/v5 kernel has some
overhead compared to supporting just one of the two.

	Arnd

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-17 13:45               ` Arnd Bergmann
  0 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 17 July 2012, Florian Fainelli wrote:
> On Tuesday 17 July 2012 13:07:23 Arnd Bergmann wrote:

> > But is there much difference between the two? How much code would
> > actually get built for one chip but not the other? If all the
> > differences can be run-time detected from the device tree, I
> > think it's better to not have different compile-time options at
> > all.
> 
> The big difference between the two is actually the CPU core, for MCS8140 they 
> used a genuine ARM926EJS and for MCS8142 they actually use a FA526 core.

Ok, I see. That probably is enough difference to justify separate Kconfig
statements, especially since building a combined ARMv4/v5 kernel has some
overhead compared to supporting just one of the two.

	Arnd

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-17 13:28             ` Thomas Petazzoni
@ 2012-07-17 13:51               ` Arnd Bergmann
  -1 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:51 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Mike Turquette, Florian Fainelli,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tuesday 17 July 2012, Thomas Petazzoni wrote:
> And then, on PowerPC, which accessors do you use to access
> SoC-peripherals that are not on the PCI bus?

PowerPC has in_le32/out_le32 and variants of those, which unfortunately
are not defined for most other architectures, so you cannot use them
in portable code. They are the same as readl/writel, but without the
PCI error handling.

> For example, drivers/tty/serial/mpsc.c uses writel/readl, so a
> conversion to/from little-endian is done when writing/reading
> registers. Are those memory-mapped devices little-endian even though
> they are used on big-endian PowerPCs?
> 
> I apologize for the silly questions, but I'm trying to make some sense
> out of these numerous I/O and memory accessors.

All combinations of little/big endian CPUs and peripherals have been
done in the past, including peripherals that switch their endianess
dynamically when you change the mode of the CPU, and those that come
with an extra register to add byte-swapping for operating systems
that don't deal with it.

It's all a big mess and there is no good solution that anyone has
managed to come with to cover all possibilities. My recommendation
is generally to use the little-endian accessors when they work,
and have your bus-specific or driver-specific wrapper around those
when the endianess is not always the same.

	Arnd

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-17 13:51               ` Arnd Bergmann
  0 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 17 July 2012, Thomas Petazzoni wrote:
> And then, on PowerPC, which accessors do you use to access
> SoC-peripherals that are not on the PCI bus?

PowerPC has in_le32/out_le32 and variants of those, which unfortunately
are not defined for most other architectures, so you cannot use them
in portable code. They are the same as readl/writel, but without the
PCI error handling.

> For example, drivers/tty/serial/mpsc.c uses writel/readl, so a
> conversion to/from little-endian is done when writing/reading
> registers. Are those memory-mapped devices little-endian even though
> they are used on big-endian PowerPCs?
> 
> I apologize for the silly questions, but I'm trying to make some sense
> out of these numerous I/O and memory accessors.

All combinations of little/big endian CPUs and peripherals have been
done in the past, including peripherals that switch their endianess
dynamically when you change the mode of the CPU, and those that come
with an extra register to add byte-swapping for operating systems
that don't deal with it.

It's all a big mess and there is no good solution that anyone has
managed to come with to cover all possibilities. My recommendation
is generally to use the little-endian accessors when they work,
and have your bus-specific or driver-specific wrapper around those
when the endianess is not always the same.

	Arnd

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

* Re: [PATCH 2/8] ARM: MCS814x: add Device Tree based MCS8140 board support
  2012-07-17 13:34         ` Florian Fainelli
@ 2012-07-17 13:53           ` Arnd Bergmann
  -1 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:53 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tuesday 17 July 2012, Florian Fainelli wrote:
> On Tuesday 17 July 2012 13:19:43 Arnd Bergmann wrote:
> > On Sunday 15 July 2012, Florian Fainelli wrote:

> > > +			adc {
> > > +				compatible = "simple-bus";
> > > +				#address-cells = <2>;
> > > +				#size-cells = <1>;
> > > +				// 8 64MB chip-selects
> > > +				ranges = <0 0 0x00000000 0x4000000	// sdram
> > > +					  1 0 0x04000000 0x4000000	// sdram
> > > +					  2 0 0x08000000 0x4000000	// reserved
> > > +					  3 0 0x0c000000 0x4000000	// 
> flash/localbus
> > > +					  4 0 0x10000000 0x4000000	// 
> flash/localbus
> > > +					  5 0 0x14000000 0x4000000	// 
> flash/localbus
> > > +					  6 0 0x18000000 0x4000000	// 
> flash/localbus
> > > +					  7 0 0x1c000000 0x4000000>;	// 
> flash/localbus
> > > +
> > > +				sdram: memory@0,0 {
> > > +					reg = <0 0 0>;
> > > +				};
> > > +
> > > +				nor: flash@7,0 {
> > > +					reg = <7 0 0x4000000>;
> > > +					compatible = "cfi-flash";
> > > +					bank-width = <1>;		// 8-bit external 
> flash
> > > +					#address-cells = <1>;
> > > +					#size-cells = <1>;
> > > +                                };
> > > +                        };
> > 
> > Nice representation of the external buses. It does seem however that at
> > least the nor flash entry is board specific and should be moved into the
> > board .dts file.
> 
> In fact, MCS8140 only supports 8-bit CFI Flash chips, so this really is the 
> common point of all MCS8140-based boards. As you can see in the following 
> board-specific DTS patches, only the partition layout is different.

But is the flash always connected to bank 7? It looks like you could easily have
a NIC on that one and the flash on a different bank.

	Arnd

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

* [PATCH 2/8] ARM: MCS814x: add Device Tree based MCS8140 board support
@ 2012-07-17 13:53           ` Arnd Bergmann
  0 siblings, 0 replies; 80+ messages in thread
From: Arnd Bergmann @ 2012-07-17 13:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 17 July 2012, Florian Fainelli wrote:
> On Tuesday 17 July 2012 13:19:43 Arnd Bergmann wrote:
> > On Sunday 15 July 2012, Florian Fainelli wrote:

> > > +			adc {
> > > +				compatible = "simple-bus";
> > > +				#address-cells = <2>;
> > > +				#size-cells = <1>;
> > > +				// 8 64MB chip-selects
> > > +				ranges = <0 0 0x00000000 0x4000000	// sdram
> > > +					  1 0 0x04000000 0x4000000	// sdram
> > > +					  2 0 0x08000000 0x4000000	// reserved
> > > +					  3 0 0x0c000000 0x4000000	// 
> flash/localbus
> > > +					  4 0 0x10000000 0x4000000	// 
> flash/localbus
> > > +					  5 0 0x14000000 0x4000000	// 
> flash/localbus
> > > +					  6 0 0x18000000 0x4000000	// 
> flash/localbus
> > > +					  7 0 0x1c000000 0x4000000>;	// 
> flash/localbus
> > > +
> > > +				sdram: memory at 0,0 {
> > > +					reg = <0 0 0>;
> > > +				};
> > > +
> > > +				nor: flash at 7,0 {
> > > +					reg = <7 0 0x4000000>;
> > > +					compatible = "cfi-flash";
> > > +					bank-width = <1>;		// 8-bit external 
> flash
> > > +					#address-cells = <1>;
> > > +					#size-cells = <1>;
> > > +                                };
> > > +                        };
> > 
> > Nice representation of the external buses. It does seem however that at
> > least the nor flash entry is board specific and should be moved into the
> > board .dts file.
> 
> In fact, MCS8140 only supports 8-bit CFI Flash chips, so this really is the 
> common point of all MCS8140-based boards. As you can see in the following 
> board-specific DTS patches, only the partition layout is different.

But is the flash always connected to bank 7? It looks like you could easily have
a NIC on that one and the flash on a different bank.

	Arnd

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

* Re: [PATCH 2/8] ARM: MCS814x: add Device Tree based MCS8140 board support
  2012-07-17 13:53           ` Arnd Bergmann
@ 2012-07-17 13:57             ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17 13:57 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: olof, devicetree-discuss, linux-arm-kernel

On Tuesday 17 July 2012 13:53:13 Arnd Bergmann wrote:
> On Tuesday 17 July 2012, Florian Fainelli wrote:
> > On Tuesday 17 July 2012 13:19:43 Arnd Bergmann wrote:
> > > On Sunday 15 July 2012, Florian Fainelli wrote:
> 
> > > > +			adc {
> > > > +				compatible = "simple-bus";
> > > > +				#address-cells = <2>;
> > > > +				#size-cells = <1>;
> > > > +				// 8 64MB chip-selects
> > > > +				ranges = <0 0 0x00000000 0x4000000	// sdram
> > > > +					  1 0 0x04000000 0x4000000	// sdram
> > > > +					  2 0 0x08000000 0x4000000	// reserved
> > > > +					  3 0 0x0c000000 0x4000000	// 
> > flash/localbus
> > > > +					  4 0 0x10000000 0x4000000	// 
> > flash/localbus
> > > > +					  5 0 0x14000000 0x4000000	// 
> > flash/localbus
> > > > +					  6 0 0x18000000 0x4000000	// 
> > flash/localbus
> > > > +					  7 0 0x1c000000 0x4000000>;	// 
> > flash/localbus
> > > > +
> > > > +				sdram: memory@0,0 {
> > > > +					reg = <0 0 0>;
> > > > +				};
> > > > +
> > > > +				nor: flash@7,0 {
> > > > +					reg = <7 0 0x4000000>;
> > > > +					compatible = "cfi-flash";
> > > > +					bank-width = <1>;		// 8-bit external 
> > flash
> > > > +					#address-cells = <1>;
> > > > +					#size-cells = <1>;
> > > > +                                };
> > > > +                        };
> > > 
> > > Nice representation of the external buses. It does seem however that at
> > > least the nor flash entry is board specific and should be moved into the
> > > board .dts file.
> > 
> > In fact, MCS8140 only supports 8-bit CFI Flash chips, so this really is 
the 
> > common point of all MCS8140-based boards. As you can see in the following 
> > board-specific DTS patches, only the partition layout is different.
> 
> But is the flash always connected to bank 7? It looks like you could easily 
have
> a NIC on that one and the flash on a different bank.

In fact, the only constraint is that bank7 is the only one which can be used 
for an external boot flash. I do not have any problem moving this to the per-
board DTS file.
--
Florian

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

* [PATCH 2/8] ARM: MCS814x: add Device Tree based MCS8140 board support
@ 2012-07-17 13:57             ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-17 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 17 July 2012 13:53:13 Arnd Bergmann wrote:
> On Tuesday 17 July 2012, Florian Fainelli wrote:
> > On Tuesday 17 July 2012 13:19:43 Arnd Bergmann wrote:
> > > On Sunday 15 July 2012, Florian Fainelli wrote:
> 
> > > > +			adc {
> > > > +				compatible = "simple-bus";
> > > > +				#address-cells = <2>;
> > > > +				#size-cells = <1>;
> > > > +				// 8 64MB chip-selects
> > > > +				ranges = <0 0 0x00000000 0x4000000	// sdram
> > > > +					  1 0 0x04000000 0x4000000	// sdram
> > > > +					  2 0 0x08000000 0x4000000	// reserved
> > > > +					  3 0 0x0c000000 0x4000000	// 
> > flash/localbus
> > > > +					  4 0 0x10000000 0x4000000	// 
> > flash/localbus
> > > > +					  5 0 0x14000000 0x4000000	// 
> > flash/localbus
> > > > +					  6 0 0x18000000 0x4000000	// 
> > flash/localbus
> > > > +					  7 0 0x1c000000 0x4000000>;	// 
> > flash/localbus
> > > > +
> > > > +				sdram: memory at 0,0 {
> > > > +					reg = <0 0 0>;
> > > > +				};
> > > > +
> > > > +				nor: flash at 7,0 {
> > > > +					reg = <7 0 0x4000000>;
> > > > +					compatible = "cfi-flash";
> > > > +					bank-width = <1>;		// 8-bit external 
> > flash
> > > > +					#address-cells = <1>;
> > > > +					#size-cells = <1>;
> > > > +                                };
> > > > +                        };
> > > 
> > > Nice representation of the external buses. It does seem however that at
> > > least the nor flash entry is board specific and should be moved into the
> > > board .dts file.
> > 
> > In fact, MCS8140 only supports 8-bit CFI Flash chips, so this really is 
the 
> > common point of all MCS8140-based boards. As you can see in the following 
> > board-specific DTS patches, only the partition layout is different.
> 
> But is the flash always connected to bank 7? It looks like you could easily 
have
> a NIC on that one and the flash on a different bank.

In fact, the only constraint is that bank7 is the only one which can be used 
for an external boot flash. I do not have any problem moving this to the per-
board DTS file.
--
Florian

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-16 12:29     ` Thomas Petazzoni
@ 2012-07-23 19:11       ` Florian Fainelli
  -1 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-23 19:11 UTC (permalink / raw)
  To: Thomas Petazzoni; +Cc: olof, devicetree-discuss, arnd, linux-arm-kernel

Hello Thomas,

On Monday 16 July 2012 14:29:41 Thomas Petazzoni wrote:
> Hello Florian,
> 
[snip]
> > +static void __init mcs814x_of_timer_init(void)
> > +{
> > +	struct device_node *np;
> > +	const unsigned int *intspec;
> > +
> > +	np = of_find_matching_node(NULL, mcs814x_timer_ids);
> > +	if (!np)
> > +		panic("unable to find compatible timer node in dtb");
> > +
> > +	mcs814x_timer_base = of_iomap(np, 0);
> > +	if (!mcs814x_timer_base)
> > +		panic("unable to remap timer cpu registers");
> > +
> > +	intspec = of_get_property(np, "interrupts", NULL);
> > +	if (!intspec)
> > +		panic("no interrupts property for timer");
> > +
> > +	mcs814x_timer_irq.irq = be32_to_cpup(intspec);
> > +}
> > +
> > +static void __init mcs814x_timer_init(void)
> > +{
> > +	struct clk *clk;
> > +
> > +	clk = clk_get_sys("timer0", NULL);
> > +	if (IS_ERR_OR_NULL(clk))
> > +		panic("unable to get timer0 clock");
> > +
> > +	clock_rate = clk_get_rate(clk);
> > +	clk_put(clk);
> > +
> > +	mcs814x_of_timer_init();
> > +
> > +	pr_info("Timer frequency: %d (kHz)\n", clock_rate / 1000);
> > +
> > +	timer_reload_value = 0xffffffff - (clock_rate / HZ);
> > +
> > +	/* disable timer */
> > +	__raw_writel(0, mcs814x_timer_base + TIMER_CTL);
> > +	__raw_writel(timer_reload_value, mcs814x_timer_base + TIMER_VAL);
> > +	last_reload = timer_reload_value;
> > +
> > +	setup_irq(mcs814x_timer_irq.irq, &mcs814x_timer_irq);
> > +	/* enable timer, stop timer in debug mode */
> > +	__raw_writel(0x03, mcs814x_timer_base + TIMER_CTL);
> > +}
> > +
> > +struct sys_timer mcs814x_timer = {
> > +	.init	= mcs814x_timer_init,
> > +	.offset	= mcs814x_gettimeoffset,
> > +};
> 
> I am surprised that this doesn't use the clocksource and clockevents
> infrastructure. It probably should, and be implemented in
> drivers/clocksource/.

This may sound like a stupid question, but the big constraint with this SoC is 
that the timers do not reload themselves, and so far, I did not find out how I 
can handle this properly with a clocksource. I suppose that it should not be a 
big problem for the clockevent device however.

Has anyone any example of such particular case?
-- 
Florian

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-23 19:11       ` Florian Fainelli
  0 siblings, 0 replies; 80+ messages in thread
From: Florian Fainelli @ 2012-07-23 19:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Thomas,

On Monday 16 July 2012 14:29:41 Thomas Petazzoni wrote:
> Hello Florian,
> 
[snip]
> > +static void __init mcs814x_of_timer_init(void)
> > +{
> > +	struct device_node *np;
> > +	const unsigned int *intspec;
> > +
> > +	np = of_find_matching_node(NULL, mcs814x_timer_ids);
> > +	if (!np)
> > +		panic("unable to find compatible timer node in dtb");
> > +
> > +	mcs814x_timer_base = of_iomap(np, 0);
> > +	if (!mcs814x_timer_base)
> > +		panic("unable to remap timer cpu registers");
> > +
> > +	intspec = of_get_property(np, "interrupts", NULL);
> > +	if (!intspec)
> > +		panic("no interrupts property for timer");
> > +
> > +	mcs814x_timer_irq.irq = be32_to_cpup(intspec);
> > +}
> > +
> > +static void __init mcs814x_timer_init(void)
> > +{
> > +	struct clk *clk;
> > +
> > +	clk = clk_get_sys("timer0", NULL);
> > +	if (IS_ERR_OR_NULL(clk))
> > +		panic("unable to get timer0 clock");
> > +
> > +	clock_rate = clk_get_rate(clk);
> > +	clk_put(clk);
> > +
> > +	mcs814x_of_timer_init();
> > +
> > +	pr_info("Timer frequency: %d (kHz)\n", clock_rate / 1000);
> > +
> > +	timer_reload_value = 0xffffffff - (clock_rate / HZ);
> > +
> > +	/* disable timer */
> > +	__raw_writel(0, mcs814x_timer_base + TIMER_CTL);
> > +	__raw_writel(timer_reload_value, mcs814x_timer_base + TIMER_VAL);
> > +	last_reload = timer_reload_value;
> > +
> > +	setup_irq(mcs814x_timer_irq.irq, &mcs814x_timer_irq);
> > +	/* enable timer, stop timer in debug mode */
> > +	__raw_writel(0x03, mcs814x_timer_base + TIMER_CTL);
> > +}
> > +
> > +struct sys_timer mcs814x_timer = {
> > +	.init	= mcs814x_timer_init,
> > +	.offset	= mcs814x_gettimeoffset,
> > +};
> 
> I am surprised that this doesn't use the clocksource and clockevents
> infrastructure. It probably should, and be implemented in
> drivers/clocksource/.

This may sound like a stupid question, but the big constraint with this SoC is 
that the timers do not reload themselves, and so far, I did not find out how I 
can handle this properly with a clocksource. I suppose that it should not be a 
big problem for the clockevent device however.

Has anyone any example of such particular case?
-- 
Florian

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

* Re: [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
  2012-07-23 19:11       ` Florian Fainelli
@ 2012-07-27 22:42         ` Linus Walleij
  -1 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-07-27 22:42 UTC (permalink / raw)
  To: Florian Fainelli, Thomas Gleixner
  Cc: Thomas Petazzoni, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Mon, Jul 23, 2012 at 9:11 PM, Florian Fainelli <florian-p3rKhJxN3npAfugRpC6u6w@public.gmane.org> wrote:

> [Thomas P]
>> I am surprised that this doesn't use the clocksource and clockevents
>> infrastructure. It probably should, and be implemented in
>> drivers/clocksource/.
>
> This may sound like a stupid question, but the big constraint with this SoC is
> that the timers do not reload themselves, and so far, I did not find out how I
> can handle this properly with a clocksource. I suppose that it should not be a
> big problem for the clockevent device however.
>
> Has anyone any example of such particular case?

Gah what horror.

So you don't have *anything* in your platform which is really
continous and sufficiently fast?

Then try to get an IRQ to rearm and retrigger the timer to fire
itself whenever it reloads and pray this doesn't add a skew too much.
Bonus if you can use the NMI for this :-/

Yours,
Linus Walleij

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

* [PATCH 1/8] ARM: support for Moschip MCS814x SoCs
@ 2012-07-27 22:42         ` Linus Walleij
  0 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-07-27 22:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 23, 2012 at 9:11 PM, Florian Fainelli <florian@openwrt.org> wrote:

> [Thomas P]
>> I am surprised that this doesn't use the clocksource and clockevents
>> infrastructure. It probably should, and be implemented in
>> drivers/clocksource/.
>
> This may sound like a stupid question, but the big constraint with this SoC is
> that the timers do not reload themselves, and so far, I did not find out how I
> can handle this properly with a clocksource. I suppose that it should not be a
> big problem for the clockevent device however.
>
> Has anyone any example of such particular case?

Gah what horror.

So you don't have *anything* in your platform which is really
continous and sufficiently fast?

Then try to get an IRQ to rearm and retrigger the timer to fire
itself whenever it reloads and pray this doesn't add a skew too much.
Bonus if you can use the NMI for this :-/

Yours,
Linus Walleij

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

end of thread, other threads:[~2012-07-27 22:42 UTC | newest]

Thread overview: 80+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-15 14:49 [PATCH 0/8] ARM: support for Moschip MCS814x SoCs Florian Fainelli
2012-07-15 14:49 ` Florian Fainelli
2012-07-15 14:49 ` [PATCH 1/8] " Florian Fainelli
2012-07-15 14:49   ` Florian Fainelli
2012-07-16 12:29   ` Thomas Petazzoni
2012-07-16 12:29     ` Thomas Petazzoni
2012-07-16 12:43     ` Florian Fainelli
2012-07-16 12:43       ` Florian Fainelli
2012-07-16 15:55       ` Arnd Bergmann
2012-07-16 15:55         ` Arnd Bergmann
2012-07-16 17:57       ` Nicolas Pitre
2012-07-16 17:57         ` Nicolas Pitre
2012-07-23 19:11     ` Florian Fainelli
2012-07-23 19:11       ` Florian Fainelli
2012-07-27 22:42       ` Linus Walleij
2012-07-27 22:42         ` Linus Walleij
     [not found]   ` <1342363754-30808-2-git-send-email-florian-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
2012-07-16 15:54     ` Arnd Bergmann
2012-07-16 15:54       ` Arnd Bergmann
     [not found]       ` <201207161554.04812.arnd-r2nGTMty4D4@public.gmane.org>
2012-07-16 20:47         ` Turquette, Mike
2012-07-16 20:47           ` Turquette, Mike
2012-07-17  9:41           ` Florian Fainelli
2012-07-17  9:41             ` Florian Fainelli
2012-07-17 10:47           ` Florian Fainelli
2012-07-17 10:47             ` Florian Fainelli
2012-07-16 22:12         ` Linus Walleij
2012-07-16 22:12           ` Linus Walleij
2012-07-17  9:35           ` Florian Fainelli
2012-07-17  9:35             ` Florian Fainelli
2012-07-17  9:34       ` Florian Fainelli
2012-07-17  9:34         ` Florian Fainelli
2012-07-17 13:07         ` Arnd Bergmann
2012-07-17 13:07           ` Arnd Bergmann
2012-07-17 13:32           ` Florian Fainelli
2012-07-17 13:32             ` Florian Fainelli
2012-07-17 13:45             ` Arnd Bergmann
2012-07-17 13:45               ` Arnd Bergmann
2012-07-17 10:16       ` Thomas Petazzoni
2012-07-17 10:16         ` Thomas Petazzoni
2012-07-17 13:12         ` Arnd Bergmann
2012-07-17 13:12           ` Arnd Bergmann
2012-07-17 13:28           ` Thomas Petazzoni
2012-07-17 13:28             ` Thomas Petazzoni
2012-07-17 13:51             ` Arnd Bergmann
2012-07-17 13:51               ` Arnd Bergmann
2012-07-16 22:06     ` Linus Walleij
2012-07-16 22:06       ` Linus Walleij
2012-07-15 14:49 ` [PATCH 2/8] ARM: MCS814x: add Device Tree based MCS8140 board support Florian Fainelli
2012-07-15 14:49   ` Florian Fainelli
     [not found]   ` <1342363754-30808-3-git-send-email-florian-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
2012-07-17 13:19     ` Arnd Bergmann
2012-07-17 13:19       ` Arnd Bergmann
2012-07-17 13:34       ` Florian Fainelli
2012-07-17 13:34         ` Florian Fainelli
2012-07-17 13:53         ` Arnd Bergmann
2012-07-17 13:53           ` Arnd Bergmann
2012-07-17 13:57           ` Florian Fainelli
2012-07-17 13:57             ` Florian Fainelli
2012-07-15 14:49 ` [PATCH 3/8] ARM: MCS814x: add Device Tree bindings documentation Florian Fainelli
2012-07-15 14:49   ` Florian Fainelli
     [not found]   ` <1342363754-30808-4-git-send-email-florian-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
2012-07-17 13:24     ` Arnd Bergmann
2012-07-17 13:24       ` Arnd Bergmann
2012-07-17 13:35       ` Florian Fainelli
2012-07-17 13:35         ` Florian Fainelli
2012-07-15 14:49 ` [PATCH 4/8] ARM: MCS814X: add DTS file for Tigal/Robotech RBT-832 Florian Fainelli
2012-07-15 14:49   ` Florian Fainelli
     [not found]   ` <1342363754-30808-5-git-send-email-florian-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
2012-07-17 13:27     ` Arnd Bergmann
2012-07-17 13:27       ` Arnd Bergmann
2012-07-15 14:49 ` [PATCH 5/8] ARM: MCS814x: add DTS file for Devolo dLAN USB Extender Florian Fainelli
2012-07-15 14:49   ` Florian Fainelli
2012-07-15 14:49 ` [PATCH 6/8] ARM: MCS814x: provide a sample defconfig file Florian Fainelli
2012-07-15 14:49   ` Florian Fainelli
2012-07-15 14:49 ` [PATCH 7/8] ARM: MSC814X: add Kconfig and Makefile to arch/arm Florian Fainelli
2012-07-15 14:49   ` Florian Fainelli
2012-07-15 14:49 ` [PATCH 8/8] ARM: MSC814x: add MAINTAINERS entry Florian Fainelli
2012-07-15 14:49   ` Florian Fainelli
     [not found] ` <1342363754-30808-1-git-send-email-florian-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
2012-07-15 19:59   ` [PATCH 0/8] ARM: support for Moschip MCS814x SoCs Arnd Bergmann
2012-07-15 19:59     ` Arnd Bergmann
2012-07-16  8:16     ` Florian Fainelli
2012-07-16  8:16       ` Florian Fainelli
     [not found]     ` <201207151959.19620.arnd-r2nGTMty4D4@public.gmane.org>
2012-07-16 18:09       ` Nicolas Pitre
2012-07-16 18:09         ` Nicolas Pitre

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.