All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/7] Add support for NXP LPC18xx family
@ 2015-05-07 16:48 Joachim Eastwood
  2015-05-07 16:48 ` [PATCH v3 1/7] ARM: lpc18xx: add basic support for NXP LPC18xx/43xx SoCs Joachim Eastwood
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Joachim Eastwood @ 2015-05-07 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

This patch set adds minimal support for the LPC18xx/43xx family of
Cortex-M3/4 MCUs from NXP.

Patch set is based on Linus master v4.1-rc1. I would be great if
these patches could go into 4.1.

To keep the amount of dependencies down the PLL1 clock has been hard
coded in the lpc18xx.dtsi file. The clock system of LPC18xx is quite
advanced for a MCU and requires two clk drivers to work. A patch set
with these drivers and update to the dtsi files will be posted
separately.

Drivers for pinctrl, gpio and reset are already upstream now.

Drivers for ethernet, i2c, rtc and emc (external memories) are also
coming for LPC18xx.  Right now these can found on:
https://github.com/manabian/linux-lpc

Sucessfuly tested on Embedded Artist LPC4357 Developers Kit.

ARM SoC maintainers: How would like to pick this series up?
Could you pick up the patches on the mail list or would you prefer a
pull request?


Changes since v2:
 - use pr_fmt in time-lpc32xx.c
 - use request_irq instead of setup_irq in time-lpc32xx.c
 - remove default on DEBUG_UART_8250 in Kconfig.debug
 - update defconfig slightly

Changes since v1:
 - use generic soc match strings in board-dt
 - remove armv7m reset in board-dt (this wasn't working and a proper
   reset driver is coming)
 - move dt aliases to board files
 - add support for Hitex LPC4350 eval board from Ariel D'Alessandro
 - rename lpc3250-timer to lpc3220-timer to match lpc32xx.dtsi
 - add ea (and hitex) to vendor-prefixes
 - rename lpc4357-ea4357 to lpc4357-ea4357-devkit
 - add lpc32xx_read_sched_clock from Ezequiel Garcia
 - use named clk in lpc3220 clocksource driver
 - rebase on 4.1-rc1

Ariel D'Alessandro (1):
  ARM: dts: Add DT for Hitex LPC4350 Evaluation Board

Joachim Eastwood (6):
  ARM: lpc18xx: add basic support for NXP LPC18xx/43xx SoCs
  clocksource: add lpc32xx timer driver
  doc: dt: add documentation for lpc3220-timer
  ARM: dts: Add base DT for NXP LPC18xx
  ARM: dts: Add DT for Embedded Artists LPC4357 Developers Kit
  ARM: lpc18xx: add kernel config

 .../bindings/timer/nxp,lpc3220-timer.txt           |  26 +++
 .../devicetree/bindings/vendor-prefixes.txt        |   2 +
 arch/arm/Kconfig                                   |  20 ++
 arch/arm/Kconfig.debug                             |   3 +-
 arch/arm/Makefile                                  |   1 +
 arch/arm/boot/dts/Makefile                         |   3 +
 arch/arm/boot/dts/lpc18xx.dtsi                     | 114 +++++++++
 arch/arm/boot/dts/lpc4350-hitex-eval.dts           |  45 ++++
 arch/arm/boot/dts/lpc4350.dtsi                     |  39 ++++
 arch/arm/boot/dts/lpc4357-ea4357-devkit.dts        |  41 ++++
 arch/arm/boot/dts/lpc4357.dtsi                     |  39 ++++
 arch/arm/configs/lpc18xx_defconfig                 | 151 ++++++++++++
 arch/arm/mach-lpc18xx/Makefile                     |   1 +
 arch/arm/mach-lpc18xx/Makefile.boot                |   3 +
 arch/arm/mach-lpc18xx/board-dt.c                   |  22 ++
 drivers/clocksource/Kconfig                        |  10 +
 drivers/clocksource/Makefile                       |   1 +
 drivers/clocksource/time-lpc32xx.c                 | 259 +++++++++++++++++++++
 18 files changed, 779 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/timer/nxp,lpc3220-timer.txt
 create mode 100644 arch/arm/boot/dts/lpc18xx.dtsi
 create mode 100644 arch/arm/boot/dts/lpc4350-hitex-eval.dts
 create mode 100644 arch/arm/boot/dts/lpc4350.dtsi
 create mode 100644 arch/arm/boot/dts/lpc4357-ea4357-devkit.dts
 create mode 100644 arch/arm/boot/dts/lpc4357.dtsi
 create mode 100644 arch/arm/configs/lpc18xx_defconfig
 create mode 100644 arch/arm/mach-lpc18xx/Makefile
 create mode 100644 arch/arm/mach-lpc18xx/Makefile.boot
 create mode 100644 arch/arm/mach-lpc18xx/board-dt.c
 create mode 100644 drivers/clocksource/time-lpc32xx.c

-- 
1.8.0

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

* [PATCH v3 1/7] ARM: lpc18xx: add basic support for NXP LPC18xx/43xx SoCs
  2015-05-07 16:48 [PATCH v3 0/7] Add support for NXP LPC18xx family Joachim Eastwood
@ 2015-05-07 16:48 ` Joachim Eastwood
  2015-05-07 16:48 ` [PATCH v3 2/7] clocksource: add lpc32xx timer driver Joachim Eastwood
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Joachim Eastwood @ 2015-05-07 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for NXP's LPC18xx (Cortex-M3) and LPC43xx (Cortex-M4)
SoCs. These SoCs are NXP's high preformance MCU line and can run at
clock speeds up to 180 MHz for LPC18xx and 204 MHz for LPC43xx.

LPC43xx is more or less a LPC18xx with a Cortex-M4F core and a few
extra peripherals. The LPC43xx series also features one or two
Cortex-M0 cores that can be used to offload the main M4 core.

Signed-off-by: Joachim Eastwood <manabian@gmail.com>
Reviewed-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
---
 arch/arm/Kconfig                    | 20 ++++++++++++++++++++
 arch/arm/Kconfig.debug              |  3 ++-
 arch/arm/Makefile                   |  1 +
 arch/arm/mach-lpc18xx/Makefile      |  1 +
 arch/arm/mach-lpc18xx/Makefile.boot |  3 +++
 arch/arm/mach-lpc18xx/board-dt.c    | 22 ++++++++++++++++++++++
 6 files changed, 49 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-lpc18xx/Makefile
 create mode 100644 arch/arm/mach-lpc18xx/Makefile.boot
 create mode 100644 arch/arm/mach-lpc18xx/board-dt.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 45df48ba0b12..fba149165229 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -586,6 +586,26 @@ config ARCH_W90X900
 	  <http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/
 		ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller>
 
+config ARCH_LPC18XX
+	bool "NXP LPC18xx/LPC43xx"
+	depends on !MMU
+	select ARCH_HAS_RESET_CONTROLLER
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_AMBA
+	select ARM_NVIC
+	select AUTO_ZRELADDR
+	select CLKSRC_OF
+	select COMMON_CLK
+	select CPU_V7M
+	select GENERIC_CLOCKEVENTS
+	select NO_IOPORT_MAP
+	select PINCTRL
+	select SPARSE_IRQ
+	select USE_OF
+	help
+	  Support for NXP's LPC18xx Cortex-M3 and LPC43xx Cortex-M4
+	  high performance microcontrollers.
+
 config ARCH_LPC32XX
 	bool "NXP LPC32XX"
 	select ARCH_REQUIRE_GPIOLIB
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 0c12ffb155a2..b3b6469350c1 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -1359,6 +1359,7 @@ config DEBUG_UART_PHYS
 	default 0x20201000 if DEBUG_BCM2835
 	default 0x3e000000 if DEBUG_BCM_KONA_UART
 	default 0x4000e400 if DEBUG_LL_UART_EFM32
+	default 0x40081000 if ARCH_LPC18XX
 	default 0x40090000 if ARCH_LPC32XX
 	default 0x40100000 if DEBUG_PXA_UART1
 	default 0x42000000 if ARCH_GEMINI
@@ -1562,7 +1563,7 @@ config UNCOMPRESS_INCLUDE
 	string
 	default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM || \
 					PLAT_SAMSUNG || ARCH_EFM32 || \
-					ARCH_SHMOBILE_LEGACY
+					ARCH_SHMOBILE_LEGACY || ARCH_LPC18XX
 	default "mach/uncompress.h"
 
 config EARLY_PRINTK
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 985227cbbd1b..90ddf851aece 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -167,6 +167,7 @@ machine-$(CONFIG_ARCH_IOP33X)		+= iop33x
 machine-$(CONFIG_ARCH_IXP4XX)		+= ixp4xx
 machine-$(CONFIG_ARCH_KEYSTONE)		+= keystone
 machine-$(CONFIG_ARCH_KS8695)		+= ks8695
+machine-$(CONFIG_ARCH_LPC18XX)		+= lpc18xx
 machine-$(CONFIG_ARCH_LPC32XX)		+= lpc32xx
 machine-$(CONFIG_ARCH_MESON)		+= meson
 machine-$(CONFIG_ARCH_MMP)		+= mmp
diff --git a/arch/arm/mach-lpc18xx/Makefile b/arch/arm/mach-lpc18xx/Makefile
new file mode 100644
index 000000000000..bd0b7b5d6e9d
--- /dev/null
+++ b/arch/arm/mach-lpc18xx/Makefile
@@ -0,0 +1 @@
+obj-y += board-dt.o
diff --git a/arch/arm/mach-lpc18xx/Makefile.boot b/arch/arm/mach-lpc18xx/Makefile.boot
new file mode 100644
index 000000000000..eacfc3f5c33e
--- /dev/null
+++ b/arch/arm/mach-lpc18xx/Makefile.boot
@@ -0,0 +1,3 @@
+# Empty file waiting for deletion once Makefile.boot isn't needed any more.
+# Patch waits for application at
+# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 .
diff --git a/arch/arm/mach-lpc18xx/board-dt.c b/arch/arm/mach-lpc18xx/board-dt.c
new file mode 100644
index 000000000000..fdcee78d1bc4
--- /dev/null
+++ b/arch/arm/mach-lpc18xx/board-dt.c
@@ -0,0 +1,22 @@
+/*
+ * Device Tree board file for NXP LPC18xx/43xx
+ *
+ * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
+ *
+ * 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 <asm/mach/arch.h>
+
+static const char *const lpc18xx_43xx_compat[] __initconst = {
+	"nxp,lpc1850",
+	"nxp,lpc4350",
+	"nxp,lpc4370",
+	NULL
+};
+
+DT_MACHINE_START(LPC18XXDT, "NXP LPC18xx/43xx (Device Tree)")
+	.dt_compat = lpc18xx_43xx_compat,
+MACHINE_END
-- 
1.8.0

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

* [PATCH v3 2/7] clocksource: add lpc32xx timer driver
  2015-05-07 16:48 [PATCH v3 0/7] Add support for NXP LPC18xx family Joachim Eastwood
  2015-05-07 16:48 ` [PATCH v3 1/7] ARM: lpc18xx: add basic support for NXP LPC18xx/43xx SoCs Joachim Eastwood
@ 2015-05-07 16:48 ` Joachim Eastwood
  2015-05-11 11:05   ` Daniel Lezcano
  2015-05-07 16:48 ` [PATCH v3 3/7] doc: dt: add documentation for lpc3220-timer Joachim Eastwood
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Joachim Eastwood @ 2015-05-07 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for using the NXP LPC timer as clocksource and
clock event. These timers are present on many NXP devices
including LPC32xx, LPC17xx, LPC18xx and LPC43xx.

Signed-off-by: Joachim Eastwood <manabian@gmail.com>
---
 drivers/clocksource/Kconfig        |  10 ++
 drivers/clocksource/Makefile       |   1 +
 drivers/clocksource/time-lpc32xx.c | 259 +++++++++++++++++++++++++++++++++++++
 3 files changed, 270 insertions(+)
 create mode 100644 drivers/clocksource/time-lpc32xx.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 51d7865fdddb..71c532314f1d 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -106,6 +106,16 @@ config CLKSRC_EFM32
 	  Support to use the timers of EFM32 SoCs as clock source and clock
 	  event device.
 
+config CLKSRC_LPC32XX
+	bool "Clocksource for NXP's LPC SoC series" if !ARCH_LPC18XX
+	depends on OF && ARM && (ARCH_LPC18XX || COMPILE_TEST)
+	select CLKSRC_MMIO
+	default ARCH_LPC18XX
+	help
+	  Support to use the timers of LPC SoCs as clock source and clock
+	  event device. These timers are present on many NXP devices
+	  including LPC32xx, LPC17xx, LPC18xx and LPC43xx.
+
 config ARM_ARCH_TIMER
 	bool
 	select CLKSRC_OF if OF
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 5b85f6adb258..5928e35cb64d 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_ARCH_BCM_MOBILE)	+= bcm_kona_timer.o
 obj-$(CONFIG_CADENCE_TTC_TIMER)	+= cadence_ttc_timer.o
 obj-$(CONFIG_CLKSRC_EFM32)	+= time-efm32.o
 obj-$(CONFIG_CLKSRC_EXYNOS_MCT)	+= exynos_mct.o
+obj-$(CONFIG_CLKSRC_LPC32XX)	+= time-lpc32xx.o
 obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)	+= samsung_pwm_timer.o
 obj-$(CONFIG_FSL_FTM_TIMER)	+= fsl_ftm_timer.o
 obj-$(CONFIG_VF_PIT_TIMER)	+= vf_pit_timer.o
diff --git a/drivers/clocksource/time-lpc32xx.c b/drivers/clocksource/time-lpc32xx.c
new file mode 100644
index 000000000000..bb94409cf89c
--- /dev/null
+++ b/drivers/clocksource/time-lpc32xx.c
@@ -0,0 +1,259 @@
+/*
+ * Clocksource driver for NXP LPC32xx/18xx/43xx timer
+ *
+ * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
+ *
+ * Based on:
+ * time-efm32 Copyright (C) 2013 Pengutronix
+ * mach-lpc32xx/timer.c Copyright (C) 2009 - 2010 NXP Semiconductors
+ *
+ * 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.
+ *
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sched_clock.h>
+
+#define LPC32XX_TIMER_IR		0x000
+#define  LPC32XX_TIMER_IR_MR0INT	BIT(0)
+#define LPC32XX_TIMER_TCR		0x004
+#define  LPC32XX_TIMER_TCR_CEN		BIT(0)
+#define  LPC32XX_TIMER_TCR_CRST		BIT(1)
+#define LPC32XX_TIMER_TC		0x008
+#define LPC32XX_TIMER_PR		0x00c
+#define LPC32XX_TIMER_MCR		0x014
+#define  LPC32XX_TIMER_MCR_MR0I		BIT(0)
+#define  LPC32XX_TIMER_MCR_MR0R		BIT(1)
+#define  LPC32XX_TIMER_MCR_MR0S		BIT(2)
+#define LPC32XX_TIMER_MR0		0x018
+
+struct lpc32xx_clock_event_ddata {
+	struct clock_event_device evtdev;
+	void __iomem *base;
+};
+
+/* Needed for the sched clock */
+static void __iomem *clocksource_timer_counter;
+
+static u64 notrace lpc32xx_read_sched_clock(void)
+{
+	return readl(clocksource_timer_counter);
+}
+
+static int lpc32xx_clkevt_next_event(unsigned long delta,
+				     struct clock_event_device *evtdev)
+{
+	struct lpc32xx_clock_event_ddata *ddata =
+		container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev);
+
+	writel_relaxed(LPC32XX_TIMER_TCR_CRST, ddata->base + LPC32XX_TIMER_TCR);
+	writel_relaxed(delta, ddata->base + LPC32XX_TIMER_PR);
+	writel_relaxed(LPC32XX_TIMER_TCR_CEN, ddata->base + LPC32XX_TIMER_TCR);
+
+	return 0;
+}
+
+static void lpc32xx_clkevt_mode(enum clock_event_mode mode,
+				struct clock_event_device *evtdev)
+{
+	struct lpc32xx_clock_event_ddata *ddata =
+		container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		WARN_ON(1);
+		break;
+
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		/*
+		 * Disable the timer. When using oneshot, we must also
+		 * disable the timer to wait for the first call to
+		 * set_next_event().
+		 */
+		writel_relaxed(0, ddata->base + LPC32XX_TIMER_TCR);
+		break;
+
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_RESUME:
+		break;
+	}
+}
+
+static irqreturn_t lpc32xx_clock_event_handler(int irq, void *dev_id)
+{
+	struct lpc32xx_clock_event_ddata *ddata = dev_id;
+
+	/* Clear match */
+	writel_relaxed(LPC32XX_TIMER_IR_MR0INT, ddata->base + LPC32XX_TIMER_IR);
+
+	ddata->evtdev.event_handler(&ddata->evtdev);
+
+	return IRQ_HANDLED;
+}
+
+static struct lpc32xx_clock_event_ddata lpc32xx_clk_event_ddata = {
+	.evtdev = {
+		.name           = "lpc3220 clockevent",
+		.features       = CLOCK_EVT_FEAT_ONESHOT,
+		.rating         = 300,
+		.set_next_event = lpc32xx_clkevt_next_event,
+		.set_mode       = lpc32xx_clkevt_mode,
+	},
+};
+
+static int __init lpc32xx_clocksource_init(struct device_node *np)
+{
+	void __iomem *base;
+	unsigned long rate;
+	struct clk *clk;
+	int ret;
+
+	clk = of_clk_get_by_name(np, "timerclk");
+	if (IS_ERR(clk)) {
+		pr_err("clock get failed (%lu)\n", PTR_ERR(clk));
+		return PTR_ERR(clk);
+	}
+
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		pr_err("clock enable failed (%d)\n", ret);
+		goto err_clk_enable;
+	}
+
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_err("unable to map registers\n");
+		ret = -EADDRNOTAVAIL;
+		goto err_iomap;
+	}
+
+	writel_relaxed(LPC32XX_TIMER_TCR_CRST, base + LPC32XX_TIMER_TCR);
+	writel_relaxed(0, base + LPC32XX_TIMER_PR);
+	writel_relaxed(0, base + LPC32XX_TIMER_MCR);
+	writel_relaxed(LPC32XX_TIMER_TCR_CEN, base + LPC32XX_TIMER_TCR);
+
+	rate = clk_get_rate(clk);
+	ret = clocksource_mmio_init(base + LPC32XX_TIMER_TC, "lpc3220 timer",
+				    rate, 300, 32, clocksource_mmio_readl_up);
+	if (ret) {
+		pr_err("failed to init clocksource (%d)\n", ret);
+		goto err_clocksource_init;
+	}
+
+	clocksource_timer_counter = base + LPC32XX_TIMER_TC;
+	sched_clock_register(lpc32xx_read_sched_clock, 32, rate);
+
+	return 0;
+
+err_clocksource_init:
+	iounmap(base);
+err_iomap:
+	clk_disable_unprepare(clk);
+err_clk_enable:
+	clk_put(clk);
+	return ret;
+}
+
+static int __init lpc32xx_clockevent_init(struct device_node *np)
+{
+	void __iomem *base;
+	unsigned long rate;
+	struct clk *clk;
+	int ret, irq;
+
+	clk = of_clk_get_by_name(np, "timerclk");
+	if (IS_ERR(clk)) {
+		pr_err("clock get failed (%lu)\n", PTR_ERR(clk));
+		return PTR_ERR(clk);
+	}
+
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		pr_err("clock enable failed (%d)\n", ret);
+		goto err_clk_enable;
+	}
+
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_err("unable to map registers\n");
+		ret = -EADDRNOTAVAIL;
+		goto err_iomap;
+	}
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (!irq) {
+		pr_err("get irq failed\n");
+		ret = -ENOENT;
+		goto err_irq;
+	}
+
+	/* Initial timer setup */
+	writel_relaxed(0, base + LPC32XX_TIMER_TCR);
+	writel_relaxed(LPC32XX_TIMER_IR_MR0INT, base + LPC32XX_TIMER_IR);
+	writel_relaxed(1, base + LPC32XX_TIMER_MR0);
+	writel_relaxed(LPC32XX_TIMER_MCR_MR0I | LPC32XX_TIMER_MCR_MR0R |
+		       LPC32XX_TIMER_MCR_MR0S, base + LPC32XX_TIMER_MCR);
+
+	rate = clk_get_rate(clk);
+	lpc32xx_clk_event_ddata.base = base;
+	clockevents_config_and_register(&lpc32xx_clk_event_ddata.evtdev,
+					rate, 1, -1);
+
+	ret = request_irq(irq, lpc32xx_clock_event_handler,
+			  IRQF_TIMER | IRQF_IRQPOLL, "lpc3220 clockevent",
+			  &lpc32xx_clk_event_ddata);
+	if (ret) {
+		pr_err("request irq failed\n");
+		goto err_irq;
+	}
+
+	return 0;
+
+err_irq:
+	iounmap(base);
+err_iomap:
+	clk_disable_unprepare(clk);
+err_clk_enable:
+	clk_put(clk);
+	return ret;
+}
+
+/*
+ * This function asserts that we have exactly one clocksource and one
+ * clock_event_device in the end.
+ */
+static void __init lpc32xx_timer_init(struct device_node *np)
+{
+	static int has_clocksource, has_clockevent;
+	int ret;
+
+	if (!has_clocksource) {
+		ret = lpc32xx_clocksource_init(np);
+		if (!ret) {
+			has_clocksource = 1;
+			return;
+		}
+	}
+
+	if (!has_clockevent) {
+		ret = lpc32xx_clockevent_init(np);
+		if (!ret) {
+			has_clockevent = 1;
+			return;
+		}
+	}
+}
+CLOCKSOURCE_OF_DECLARE(lpc32xx_timer, "nxp,lpc3220-timer", lpc32xx_timer_init);
-- 
1.8.0

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

* [PATCH v3 3/7] doc: dt: add documentation for lpc3220-timer
  2015-05-07 16:48 [PATCH v3 0/7] Add support for NXP LPC18xx family Joachim Eastwood
  2015-05-07 16:48 ` [PATCH v3 1/7] ARM: lpc18xx: add basic support for NXP LPC18xx/43xx SoCs Joachim Eastwood
  2015-05-07 16:48 ` [PATCH v3 2/7] clocksource: add lpc32xx timer driver Joachim Eastwood
@ 2015-05-07 16:48 ` Joachim Eastwood
  2015-05-07 16:48 ` [PATCH v3 4/7] ARM: dts: Add base DT for NXP LPC18xx Joachim Eastwood
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Joachim Eastwood @ 2015-05-07 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

Add DT bindings documentation for lpc3220-timer. This timer is
used as clocksource on many NXP platforms.

Signed-off-by: Joachim Eastwood <manabian@gmail.com>
---
 .../bindings/timer/nxp,lpc3220-timer.txt           | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/nxp,lpc3220-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/nxp,lpc3220-timer.txt b/Documentation/devicetree/bindings/timer/nxp,lpc3220-timer.txt
new file mode 100644
index 000000000000..51b05a0e70d1
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nxp,lpc3220-timer.txt
@@ -0,0 +1,26 @@
+* NXP LPC3220 timer
+
+The NXP LPC3220 timer is used on a wide range of NXP SoCs. This
+includes LPC32xx, LPC178x, LPC18xx and LPC43xx parts.
+
+Required properties:
+- compatible:
+	Should be "nxp,lpc3220-timer".
+- reg:
+	Address and length of the register set.
+- interrupts:
+	Reference to the timer interrupt
+- clocks:
+	Should contain a reference to timer clock.
+- clock-names:
+	Should contain "timerclk".
+
+Example:
+
+timer1: timer at 40085000 {
+	compatible = "nxp,lpc3220-timer";
+	reg = <0x40085000 0x1000>;
+	interrupts = <13>;
+	clocks = <&ccu1 CLK_CPU_TIMER1>;
+	clock-names = "timerclk";
+};
-- 
1.8.0

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

* [PATCH v3 4/7] ARM: dts: Add base DT for NXP LPC18xx
  2015-05-07 16:48 [PATCH v3 0/7] Add support for NXP LPC18xx family Joachim Eastwood
                   ` (2 preceding siblings ...)
  2015-05-07 16:48 ` [PATCH v3 3/7] doc: dt: add documentation for lpc3220-timer Joachim Eastwood
@ 2015-05-07 16:48 ` Joachim Eastwood
  2015-05-07 16:48 ` [PATCH v3 5/7] ARM: dts: Add DT for Embedded Artists LPC4357 Developers Kit Joachim Eastwood
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Joachim Eastwood @ 2015-05-07 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

NXP LPC18xx/43xx SoCs are very similar devices and should be able to
share a common base (lpc18xx.dtsi). Diffences between the devices are
put in a dtsi which is specific to that device.

Signed-off-by: Joachim Eastwood <manabian@gmail.com>
---
 arch/arm/boot/dts/lpc18xx.dtsi | 114 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)
 create mode 100644 arch/arm/boot/dts/lpc18xx.dtsi

diff --git a/arch/arm/boot/dts/lpc18xx.dtsi b/arch/arm/boot/dts/lpc18xx.dtsi
new file mode 100644
index 000000000000..204da5b52ef9
--- /dev/null
+++ b/arch/arm/boot/dts/lpc18xx.dtsi
@@ -0,0 +1,114 @@
+/*
+ * Common base for NXP LPC18xx and LPC43xx devices.
+ *
+ * Copyright 2015 Joachim Eastwood <manabian@gmail.com>
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ *
+ */
+
+#include "armv7-m.dtsi"
+
+/ {
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			compatible = "arm,cortex-m3";
+			device_type = "cpu";
+			reg = <0x0>;
+		};
+	};
+
+	clocks {
+		xtal: xtal {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <12000000>;
+		};
+
+		/* Temporary hardcode PLL1 until clk drivers are merged */
+		pll1: pll1 {
+			compatible = "fixed-factor-clock";
+			clocks = <&xtal>;
+			#clock-cells = <0>;
+			clock-div = <1>;
+			clock-mult = <12>;
+		};
+	};
+
+	soc {
+		uart0: serial at 40081000 {
+			compatible = "ns16550a";
+			reg = <0x40081000 0x1000>;
+			reg-shift = <2>;
+			interrupts = <24>;
+			clocks = <&pll1>;
+			status = "disabled";
+		};
+
+		uart1: serial at 40082000 {
+			compatible = "ns16550a";
+			reg = <0x40082000 0x1000>;
+			reg-shift = <2>;
+			interrupts = <25>;
+			clocks = <&pll1>;
+			status = "disabled";
+		};
+
+		timer0: timer at 40084000 {
+			compatible = "nxp,lpc3220-timer";
+			reg = <0x40084000 0x1000>;
+			interrupts = <12>;
+			clocks = <&pll1>;
+			clock-names = "timerclk";
+		};
+
+		timer1: timer at 40085000 {
+			compatible = "nxp,lpc3220-timer";
+			reg = <0x40085000 0x1000>;
+			interrupts = <13>;
+			clocks = <&pll1>;
+			clock-names = "timerclk";
+		};
+
+		uart2: serial at 400c1000 {
+			compatible = "ns16550a";
+			reg = <0x400c1000 0x1000>;
+			reg-shift = <2>;
+			interrupts = <26>;
+			clocks = <&pll1>;
+			status = "disabled";
+		};
+
+		uart3: serial at 400c2000 {
+			compatible = "ns16550a";
+			reg = <0x400c2000 0x1000>;
+			reg-shift = <2>;
+			interrupts = <27>;
+			clocks = <&pll1>;
+			status = "disabled";
+		};
+
+		timer2: timer at 400c3000 {
+			compatible = "nxp,lpc3220-timer";
+			reg = <0x400c3000 0x1000>;
+			interrupts = <14>;
+			clocks = <&pll1>;
+			clock-names = "timerclk";
+		};
+
+		timer3: timer at 400c4000 {
+			compatible = "nxp,lpc3220-timer";
+			reg = <0x400c4000 0x1000>;
+			interrupts = <15>;
+			clocks = <&pll1>;
+			clock-names = "timerclk";
+		};
+	};
+};
-- 
1.8.0

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

* [PATCH v3 5/7] ARM: dts: Add DT for Embedded Artists LPC4357 Developers Kit
  2015-05-07 16:48 [PATCH v3 0/7] Add support for NXP LPC18xx family Joachim Eastwood
                   ` (3 preceding siblings ...)
  2015-05-07 16:48 ` [PATCH v3 4/7] ARM: dts: Add base DT for NXP LPC18xx Joachim Eastwood
@ 2015-05-07 16:48 ` Joachim Eastwood
  2015-05-07 16:48 ` [PATCH v3 6/7] ARM: dts: Add DT for Hitex LPC4350 Evaluation Board Joachim Eastwood
  2015-05-07 16:48 ` [PATCH v3 7/7] ARM: lpc18xx: add kernel config Joachim Eastwood
  6 siblings, 0 replies; 14+ messages in thread
From: Joachim Eastwood @ 2015-05-07 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

Adds basic support for Embedded Artists' LPC4357 Developer's Kit. Board
features a LPC4357 Soc, 32 MB SDRAM, 128 MB NAND Flash, 16 MB SPI
Flash, USB and Ethernet.

More information can be found on:
http://www.embeddedartists.com/products/kits/lpc4357_kit.php

Signed-off-by: Joachim Eastwood <manabian@gmail.com>
---
 .../devicetree/bindings/vendor-prefixes.txt        |  1 +
 arch/arm/boot/dts/Makefile                         |  2 ++
 arch/arm/boot/dts/lpc4357-ea4357-devkit.dts        | 41 ++++++++++++++++++++++
 arch/arm/boot/dts/lpc4357.dtsi                     | 39 ++++++++++++++++++++
 4 files changed, 83 insertions(+)
 create mode 100644 arch/arm/boot/dts/lpc4357-ea4357-devkit.dts
 create mode 100644 arch/arm/boot/dts/lpc4357.dtsi

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 80339192c93e..ae3460c0e5fd 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -60,6 +60,7 @@ digilent	Diglent, Inc.
 dlg	Dialog Semiconductor
 dlink	D-Link Corporation
 dmo	Data Modul AG
+ea	Embedded Artists AB
 ebv	EBV Elektronik
 edt	Emerging Display Technologies
 elan	Elan Microelectronic Corp.
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 86217db2937a..b95d8a6a1e36 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -201,6 +201,8 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \
 	kirkwood-ts219-6282.dtb \
 	kirkwood-ts419-6281.dtb \
 	kirkwood-ts419-6282.dtb
+dtb-$(CONFIG_ARCH_LPC18XX) += \
+	lpc4357-ea4357-devkit.dtb
 dtb-$(CONFIG_ARCH_LPC32XX) += \
 	ea3250.dtb phy3250.dtb
 dtb-$(CONFIG_MACH_MESON6) += \
diff --git a/arch/arm/boot/dts/lpc4357-ea4357-devkit.dts b/arch/arm/boot/dts/lpc4357-ea4357-devkit.dts
new file mode 100644
index 000000000000..08a6f757f924
--- /dev/null
+++ b/arch/arm/boot/dts/lpc4357-ea4357-devkit.dts
@@ -0,0 +1,41 @@
+/*
+ * Embedded Artist LPC4357 Developer's Kit
+ *
+ * Copyright 2015 Joachim Eastwood <manabian@gmail.com>
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ *
+ */
+/dts-v1/;
+
+#include "lpc18xx.dtsi"
+#include "lpc4357.dtsi"
+
+/ {
+	model = "Embedded Artists' LPC4357 Developer's Kit";
+	compatible = "ea,lpc4357-developers-kit", "nxp,lpc4357", "nxp,lpc4350";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+	};
+
+	chosen {
+		stdout-path = &uart0;
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x28000000 0x2000000>; /* 32 MB */
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/lpc4357.dtsi b/arch/arm/boot/dts/lpc4357.dtsi
new file mode 100644
index 000000000000..fb9ecc754e8d
--- /dev/null
+++ b/arch/arm/boot/dts/lpc4357.dtsi
@@ -0,0 +1,39 @@
+/*
+ * NXP LPC435x, LPC433x, LPC4327, LPC4325, LPC4317 and LPC4315 SoC
+ *
+ * Copyright 2015 Joachim Eastwood <manabian@gmail.com>
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ *
+ */
+
+/ {
+	compatible = "nxp,lpc4357";
+
+	cpus {
+		cpu at 0 {
+			compatible = "arm,cortex-m4";
+		};
+	};
+
+	soc {
+		sram0: sram at 10000000 {
+			compatible = "mmio-sram";
+			reg = <0x10000000 0x8000>; /* 32 KiB local SRAM */
+		};
+
+		sram1: sram at 10080000 {
+			compatible = "mmio-sram";
+			reg = <0x10080000 0xa000>; /* 32 + 8 KiB local SRAM */
+		};
+
+		sram2: sram at 20000000 {
+			compatible = "mmio-sram";
+			reg = <0x20000000 0x10000>; /* 4 x 16 KiB AHB SRAM */
+		};
+	};
+};
-- 
1.8.0

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

* [PATCH v3 6/7] ARM: dts: Add DT for Hitex LPC4350 Evaluation Board
  2015-05-07 16:48 [PATCH v3 0/7] Add support for NXP LPC18xx family Joachim Eastwood
                   ` (4 preceding siblings ...)
  2015-05-07 16:48 ` [PATCH v3 5/7] ARM: dts: Add DT for Embedded Artists LPC4357 Developers Kit Joachim Eastwood
@ 2015-05-07 16:48 ` Joachim Eastwood
  2015-05-07 16:48 ` [PATCH v3 7/7] ARM: lpc18xx: add kernel config Joachim Eastwood
  6 siblings, 0 replies; 14+ messages in thread
From: Joachim Eastwood @ 2015-05-07 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

From: Ariel D'Alessandro <ariel.dalessandro@gmail.com>

Add basic support for Hitex LPC4350 Evaluation Board. Board
features a LPC4350 Soc, 8 MB SDRAM, 8 MB SPI Flash, USB and
Ethernet.

More information can be found on:
http://www.hitex.com/index.php?id=3212

Signed-off-by: Ariel D'Alessandro <ariel.dalessandro@gmail.com>
Signed-off-by: Joachim Eastwood <manabian@gmail.com>
---
 .../devicetree/bindings/vendor-prefixes.txt        |  1 +
 arch/arm/boot/dts/Makefile                         |  1 +
 arch/arm/boot/dts/lpc4350-hitex-eval.dts           | 45 ++++++++++++++++++++++
 arch/arm/boot/dts/lpc4350.dtsi                     | 39 +++++++++++++++++++
 4 files changed, 86 insertions(+)
 create mode 100644 arch/arm/boot/dts/lpc4350-hitex-eval.dts
 create mode 100644 arch/arm/boot/dts/lpc4350.dtsi

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index ae3460c0e5fd..7e7d7a7cae2c 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -94,6 +94,7 @@ haoyu	Haoyu Microelectronic Co. Ltd.
 himax	Himax Technologies, Inc.
 hisilicon	Hisilicon Limited.
 hit	Hitachi Ltd.
+hitex	Hitex Development Tools
 honeywell	Honeywell
 hp	Hewlett Packard
 i2se	I2SE GmbH
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b95d8a6a1e36..1e5b2ea02aad 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -202,6 +202,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \
 	kirkwood-ts419-6281.dtb \
 	kirkwood-ts419-6282.dtb
 dtb-$(CONFIG_ARCH_LPC18XX) += \
+	lpc4350-hitex-eval.dtb \
 	lpc4357-ea4357-devkit.dtb
 dtb-$(CONFIG_ARCH_LPC32XX) += \
 	ea3250.dtb phy3250.dtb
diff --git a/arch/arm/boot/dts/lpc4350-hitex-eval.dts b/arch/arm/boot/dts/lpc4350-hitex-eval.dts
new file mode 100644
index 000000000000..d04072f40817
--- /dev/null
+++ b/arch/arm/boot/dts/lpc4350-hitex-eval.dts
@@ -0,0 +1,45 @@
+/*
+ * Hitex LPC4350 Evaluation Board
+ *
+ * Copyright 2015 Ariel D'Alessandro <ariel.dalessandro@gmail.com>
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ *
+ */
+/dts-v1/;
+
+#include "lpc18xx.dtsi"
+#include "lpc4350.dtsi"
+
+/ {
+	model = "Hitex LPC4350 Evaluation Board";
+	compatible = "hitex,lpc4350-eval-board", "nxp,lpc4350";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+	};
+
+	chosen {
+		stdout-path = &uart0;
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x28000000 0x800000>; /* 8 MB */
+	};
+};
+
+&pll1 {
+	clock-mult = <15>;
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/lpc4350.dtsi b/arch/arm/boot/dts/lpc4350.dtsi
new file mode 100644
index 000000000000..c4422f587055
--- /dev/null
+++ b/arch/arm/boot/dts/lpc4350.dtsi
@@ -0,0 +1,39 @@
+/*
+ * NXP LPC4350 and LPC4330 SoC
+ *
+ * Copyright 2015 Ariel D'Alessandro <ariel.dalessandro@gmail.com>
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ *
+ */
+
+/ {
+	compatible = "nxp,lpc4350", "nxp,lpc4330";
+
+	cpus {
+		cpu at 0 {
+			compatible = "arm,cortex-m4";
+		};
+	};
+
+	soc {
+		sram0: sram at 10000000 {
+			compatible = "mmio-sram";
+			reg = <0x10000000 0x20000>; /* 96 + 32 KiB local SRAM */
+		};
+
+		sram1: sram at 10080000 {
+			compatible = "mmio-sram";
+			reg = <0x10080000 0x12000>; /* 64 + 8 KiB local SRAM */
+		};
+
+		sram2: sram at 20000000 {
+			compatible = "mmio-sram";
+			reg = <0x20000000 0x10000>; /* 4 x 16 KiB AHB SRAM */
+		};
+	};
+};
-- 
1.8.0

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

* [PATCH v3 7/7] ARM: lpc18xx: add kernel config
  2015-05-07 16:48 [PATCH v3 0/7] Add support for NXP LPC18xx family Joachim Eastwood
                   ` (5 preceding siblings ...)
  2015-05-07 16:48 ` [PATCH v3 6/7] ARM: dts: Add DT for Hitex LPC4350 Evaluation Board Joachim Eastwood
@ 2015-05-07 16:48 ` Joachim Eastwood
  6 siblings, 0 replies; 14+ messages in thread
From: Joachim Eastwood @ 2015-05-07 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

Kernel configuration for NXP LPC18xx and LPC43xx devices.

Signed-off-by: Joachim Eastwood <manabian@gmail.com>
---
 arch/arm/configs/lpc18xx_defconfig | 151 +++++++++++++++++++++++++++++++++++++
 1 file changed, 151 insertions(+)
 create mode 100644 arch/arm/configs/lpc18xx_defconfig

diff --git a/arch/arm/configs/lpc18xx_defconfig b/arch/arm/configs/lpc18xx_defconfig
new file mode 100644
index 000000000000..caf7b5248943
--- /dev/null
+++ b/arch/arm/configs/lpc18xx_defconfig
@@ -0,0 +1,151 @@
+CONFIG_CROSS_COMPILE="arm-linux-gnueabihf-"
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_UID16 is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_MMU is not set
+CONFIG_ARCH_LPC18XX=y
+CONFIG_SET_MEM_PARAM=y
+CONFIG_DRAM_BASE=0x28000000
+CONFIG_DRAM_SIZE=0x02000000
+CONFIG_FLASH_MEM_BASE=0x1b000000
+CONFIG_FLASH_SIZE=0x00080000
+CONFIG_PREEMPT=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+CONFIG_BINFMT_SHARED_FLAT=y
+# CONFIG_COREDUMP is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=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_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_SRAM=y
+CONFIG_EEPROM_AT24=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_USB_NET_DRIVERS is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_GPIO_POLLED=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_74XX_MMIO=y
+CONFIG_SENSORS_LM75=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_MMC=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_IDMAC=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_PCA9532=y
+CONFIG_LEDS_PCA9532_GPIO=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_AMBA_PL08X=y
+CONFIG_EXT2_FS=y
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_RCU_CPU_STALL_INFO is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC7=y
-- 
1.8.0

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

* [PATCH v3 2/7] clocksource: add lpc32xx timer driver
  2015-05-07 16:48 ` [PATCH v3 2/7] clocksource: add lpc32xx timer driver Joachim Eastwood
@ 2015-05-11 11:05   ` Daniel Lezcano
  2015-05-11 11:30     ` Joachim Eastwood
  0 siblings, 1 reply; 14+ messages in thread
From: Daniel Lezcano @ 2015-05-11 11:05 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/07/2015 06:48 PM, Joachim Eastwood wrote:
> Add support for using the NXP LPC timer as clocksource and
> clock event. These timers are present on many NXP devices
> including LPC32xx, LPC17xx, LPC18xx and LPC43xx.

A brief description of the hardware would be nice.

Some comments below.

Thanks !

   -- Daniel

> Signed-off-by: Joachim Eastwood <manabian@gmail.com>
> ---
>   drivers/clocksource/Kconfig        |  10 ++
>   drivers/clocksource/Makefile       |   1 +
>   drivers/clocksource/time-lpc32xx.c | 259 +++++++++++++++++++++++++++++++++++++
>   3 files changed, 270 insertions(+)
>   create mode 100644 drivers/clocksource/time-lpc32xx.c
>
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 51d7865fdddb..71c532314f1d 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -106,6 +106,16 @@ config CLKSRC_EFM32
>   	  Support to use the timers of EFM32 SoCs as clock source and clock
>   	  event device.
>
> +config CLKSRC_LPC32XX
> +	bool "Clocksource for NXP's LPC SoC series" if !ARCH_LPC18XX

Except you have a really good reason, the timers are not prompted. It is 
up to the platform's config to select the driver.

> +	depends on OF && ARM && (ARCH_LPC18XX || COMPILE_TEST)
> +	select CLKSRC_MMIO
> +	default ARCH_LPC18XX
> +	help
> +	  Support to use the timers of LPC SoCs as clock source and clock
> +	  event device. These timers are present on many NXP devices
> +	  including LPC32xx, LPC17xx, LPC18xx and LPC43xx.
> +
>   config ARM_ARCH_TIMER
>   	bool
>   	select CLKSRC_OF if OF
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index 5b85f6adb258..5928e35cb64d 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -37,6 +37,7 @@ obj-$(CONFIG_ARCH_BCM_MOBILE)	+= bcm_kona_timer.o
>   obj-$(CONFIG_CADENCE_TTC_TIMER)	+= cadence_ttc_timer.o
>   obj-$(CONFIG_CLKSRC_EFM32)	+= time-efm32.o
>   obj-$(CONFIG_CLKSRC_EXYNOS_MCT)	+= exynos_mct.o
> +obj-$(CONFIG_CLKSRC_LPC32XX)	+= time-lpc32xx.o
>   obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)	+= samsung_pwm_timer.o
>   obj-$(CONFIG_FSL_FTM_TIMER)	+= fsl_ftm_timer.o
>   obj-$(CONFIG_VF_PIT_TIMER)	+= vf_pit_timer.o
> diff --git a/drivers/clocksource/time-lpc32xx.c b/drivers/clocksource/time-lpc32xx.c
> new file mode 100644
> index 000000000000..bb94409cf89c
> --- /dev/null
> +++ b/drivers/clocksource/time-lpc32xx.c
> @@ -0,0 +1,259 @@
> +/*
> + * Clocksource driver for NXP LPC32xx/18xx/43xx timer
> + *
> + * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
> + *
> + * Based on:
> + * time-efm32 Copyright (C) 2013 Pengutronix
> + * mach-lpc32xx/timer.c Copyright (C) 2009 - 2010 NXP Semiconductors
> + *
> + * 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.
> + *
> + */
> +
> +#define pr_fmt(fmt) "%s: " fmt, __func__
> +
> +#include <linux/clk.h>
> +#include <linux/clockchips.h>
> +#include <linux/clocksource.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/kernel.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/sched_clock.h>
> +
> +#define LPC32XX_TIMER_IR		0x000
> +#define  LPC32XX_TIMER_IR_MR0INT	BIT(0)
> +#define LPC32XX_TIMER_TCR		0x004
> +#define  LPC32XX_TIMER_TCR_CEN		BIT(0)
> +#define  LPC32XX_TIMER_TCR_CRST		BIT(1)
> +#define LPC32XX_TIMER_TC		0x008
> +#define LPC32XX_TIMER_PR		0x00c
> +#define LPC32XX_TIMER_MCR		0x014
> +#define  LPC32XX_TIMER_MCR_MR0I		BIT(0)
> +#define  LPC32XX_TIMER_MCR_MR0R		BIT(1)
> +#define  LPC32XX_TIMER_MCR_MR0S		BIT(2)
> +#define LPC32XX_TIMER_MR0		0x018
> +
> +struct lpc32xx_clock_event_ddata {
> +	struct clock_event_device evtdev;
> +	void __iomem *base;
> +};
> +
> +/* Needed for the sched clock */
> +static void __iomem *clocksource_timer_counter;
> +
> +static u64 notrace lpc32xx_read_sched_clock(void)
> +{
> +	return readl(clocksource_timer_counter);
> +}
> +
> +static int lpc32xx_clkevt_next_event(unsigned long delta,
> +				     struct clock_event_device *evtdev)
> +{
> +	struct lpc32xx_clock_event_ddata *ddata =
> +		container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev);
> +
> +	writel_relaxed(LPC32XX_TIMER_TCR_CRST, ddata->base + LPC32XX_TIMER_TCR);
> +	writel_relaxed(delta, ddata->base + LPC32XX_TIMER_PR);
> +	writel_relaxed(LPC32XX_TIMER_TCR_CEN, ddata->base + LPC32XX_TIMER_TCR);
> +
> +	return 0;
> +}
> +
> +static void lpc32xx_clkevt_mode(enum clock_event_mode mode,
> +				struct clock_event_device *evtdev)

See below.

> +{
> +	struct lpc32xx_clock_event_ddata *ddata =
> +		container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev);
> +
> +	switch (mode) {
> +	case CLOCK_EVT_MODE_PERIODIC:
> +		WARN_ON(1);
> +		break;
> +
> +	case CLOCK_EVT_MODE_ONESHOT:
> +	case CLOCK_EVT_MODE_SHUTDOWN:
> +		/*
> +		 * Disable the timer. When using oneshot, we must also
> +		 * disable the timer to wait for the first call to
> +		 * set_next_event().
> +		 */
> +		writel_relaxed(0, ddata->base + LPC32XX_TIMER_TCR);
> +		break;
> +
> +	case CLOCK_EVT_MODE_UNUSED:
> +	case CLOCK_EVT_MODE_RESUME:
> +		break;
> +	}
> +}
> +
> +static irqreturn_t lpc32xx_clock_event_handler(int irq, void *dev_id)
> +{
> +	struct lpc32xx_clock_event_ddata *ddata = dev_id;
> +
> +	/* Clear match */
> +	writel_relaxed(LPC32XX_TIMER_IR_MR0INT, ddata->base + LPC32XX_TIMER_IR);
> +
> +	ddata->evtdev.event_handler(&ddata->evtdev);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static struct lpc32xx_clock_event_ddata lpc32xx_clk_event_ddata = {
> +	.evtdev = {
> +		.name           = "lpc3220 clockevent",
> +		.features       = CLOCK_EVT_FEAT_ONESHOT,
> +		.rating         = 300,
> +		.set_next_event = lpc32xx_clkevt_next_event,
> +		.set_mode       = lpc32xx_clkevt_mode,

Please take the opportunity to switch to the new API (see commit 77e32c89).

> +	},
> +};
> +
> +static int __init lpc32xx_clocksource_init(struct device_node *np)
> +{
> +	void __iomem *base;
> +	unsigned long rate;
> +	struct clk *clk;
> +	int ret;
> +
> +	clk = of_clk_get_by_name(np, "timerclk");
> +	if (IS_ERR(clk)) {
> +		pr_err("clock get failed (%lu)\n", PTR_ERR(clk));
> +		return PTR_ERR(clk);
> +	}
> +
> +	ret = clk_prepare_enable(clk);
> +	if (ret) {
> +		pr_err("clock enable failed (%d)\n", ret);
> +		goto err_clk_enable;
> +	}
> +
> +	base = of_iomap(np, 0);
> +	if (!base) {
> +		pr_err("unable to map registers\n");
> +		ret = -EADDRNOTAVAIL;
> +		goto err_iomap;
> +	}
> +
> +	writel_relaxed(LPC32XX_TIMER_TCR_CRST, base + LPC32XX_TIMER_TCR);
> +	writel_relaxed(0, base + LPC32XX_TIMER_PR);
> +	writel_relaxed(0, base + LPC32XX_TIMER_MCR);
> +	writel_relaxed(LPC32XX_TIMER_TCR_CEN, base + LPC32XX_TIMER_TCR);

Please add a detailed comment about those 4 lines. Perhaps also group 
them in a function.

> +
> +	rate = clk_get_rate(clk);
> +	ret = clocksource_mmio_init(base + LPC32XX_TIMER_TC, "lpc3220 timer",
> +				    rate, 300, 32, clocksource_mmio_readl_up);
> +	if (ret) {
> +		pr_err("failed to init clocksource (%d)\n", ret);
> +		goto err_clocksource_init;
> +	}
> +
> +	clocksource_timer_counter = base + LPC32XX_TIMER_TC;
> +	sched_clock_register(lpc32xx_read_sched_clock, 32, rate);
> +
> +	return 0;
> +
> +err_clocksource_init:
> +	iounmap(base);
> +err_iomap:
> +	clk_disable_unprepare(clk);
> +err_clk_enable:
> +	clk_put(clk);
> +	return ret;
> +}
> +
> +static int __init lpc32xx_clockevent_init(struct device_node *np)
> +{
> +	void __iomem *base;
> +	unsigned long rate;
> +	struct clk *clk;
> +	int ret, irq;
> +
> +	clk = of_clk_get_by_name(np, "timerclk");
> +	if (IS_ERR(clk)) {
> +		pr_err("clock get failed (%lu)\n", PTR_ERR(clk));
> +		return PTR_ERR(clk);
> +	}
> +
> +	ret = clk_prepare_enable(clk);
> +	if (ret) {
> +		pr_err("clock enable failed (%d)\n", ret);
> +		goto err_clk_enable;
> +	}
> +
> +	base = of_iomap(np, 0);
> +	if (!base) {
> +		pr_err("unable to map registers\n");
> +		ret = -EADDRNOTAVAIL;
> +		goto err_iomap;
> +	}
> +
> +	irq = irq_of_parse_and_map(np, 0);
> +	if (!irq) {
> +		pr_err("get irq failed\n");
> +		ret = -ENOENT;
> +		goto err_irq;
> +	}
> +
> +	/* Initial timer setup */
> +	writel_relaxed(0, base + LPC32XX_TIMER_TCR);
> +	writel_relaxed(LPC32XX_TIMER_IR_MR0INT, base + LPC32XX_TIMER_IR);
> +	writel_relaxed(1, base + LPC32XX_TIMER_MR0);
> +	writel_relaxed(LPC32XX_TIMER_MCR_MR0I | LPC32XX_TIMER_MCR_MR0R |
> +		       LPC32XX_TIMER_MCR_MR0S, base + LPC32XX_TIMER_MCR);

Ditto.

> +	rate = clk_get_rate(clk);
> +	lpc32xx_clk_event_ddata.base = base;
> +	clockevents_config_and_register(&lpc32xx_clk_event_ddata.evtdev,
> +					rate, 1, -1);
> +
> +	ret = request_irq(irq, lpc32xx_clock_event_handler,
> +			  IRQF_TIMER | IRQF_IRQPOLL, "lpc3220 clockevent",
> +			  &lpc32xx_clk_event_ddata);
> +	if (ret) {
> +		pr_err("request irq failed\n");
> +		goto err_irq;
> +	}
> +
> +	return 0;
> +
> +err_irq:
> +	iounmap(base);
> +err_iomap:
> +	clk_disable_unprepare(clk);
> +err_clk_enable:
> +	clk_put(clk);
> +	return ret;
> +}
> +
> +/*
> + * This function asserts that we have exactly one clocksource and one
> + * clock_event_device in the end.
> + */
> +static void __init lpc32xx_timer_init(struct device_node *np)
> +{
> +	static int has_clocksource, has_clockevent;
> +	int ret;
> +
> +	if (!has_clocksource) {
> +		ret = lpc32xx_clocksource_init(np);
> +		if (!ret) {
> +			has_clocksource = 1;
> +			return;
> +		}
> +	}
> +
> +	if (!has_clockevent) {
> +		ret = lpc32xx_clockevent_init(np);
> +		if (!ret) {
> +			has_clockevent = 1;
> +			return;
> +		}
> +	}
> +}
> +CLOCKSOURCE_OF_DECLARE(lpc32xx_timer, "nxp,lpc3220-timer", lpc32xx_timer_init);
>


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

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

* [PATCH v3 2/7] clocksource: add lpc32xx timer driver
  2015-05-11 11:05   ` Daniel Lezcano
@ 2015-05-11 11:30     ` Joachim Eastwood
  2015-05-11 11:37       ` Daniel Lezcano
  0 siblings, 1 reply; 14+ messages in thread
From: Joachim Eastwood @ 2015-05-11 11:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Daniel,

On 11 May 2015 at 13:05, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
> On 05/07/2015 06:48 PM, Joachim Eastwood wrote:
>>
>> Add support for using the NXP LPC timer as clocksource and
>> clock event. These timers are present on many NXP devices
>> including LPC32xx, LPC17xx, LPC18xx and LPC43xx.
>
>
> A brief description of the hardware would be nice.

I'll see what I can come up with.

> Some comments below.
>
> Thanks !
>
>   -- Daniel
>
>> Signed-off-by: Joachim Eastwood <manabian@gmail.com>
>> ---
>>   drivers/clocksource/Kconfig        |  10 ++
>>   drivers/clocksource/Makefile       |   1 +
>>   drivers/clocksource/time-lpc32xx.c | 259
>> +++++++++++++++++++++++++++++++++++++
>>   3 files changed, 270 insertions(+)
>>   create mode 100644 drivers/clocksource/time-lpc32xx.c
>>
>> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
>> index 51d7865fdddb..71c532314f1d 100644
>> --- a/drivers/clocksource/Kconfig
>> +++ b/drivers/clocksource/Kconfig
>> @@ -106,6 +106,16 @@ config CLKSRC_EFM32
>>           Support to use the timers of EFM32 SoCs as clock source and
>> clock
>>           event device.
>>
>> +config CLKSRC_LPC32XX
>> +       bool "Clocksource for NXP's LPC SoC series" if !ARCH_LPC18XX
>
>
> Except you have a really good reason, the timers are not prompted. It is up
> to the platform's config to select the driver.

I only copied the CLKSRC_EFM32 entry so I don't have any good reasons.

Would something simple like this be okay?
config  CLKSRC_LPC32XX
        bool
        select CLKSRC_MMIO
        select CLKSRC_OF

And then of course update platform Kconfig to select this symbol.

>> +       depends on OF && ARM && (ARCH_LPC18XX || COMPILE_TEST)
>> +       select CLKSRC_MMIO
>> +       default ARCH_LPC18XX
>> +       help
>> +         Support to use the timers of LPC SoCs as clock source and clock
>> +         event device. These timers are present on many NXP devices
>> +         including LPC32xx, LPC17xx, LPC18xx and LPC43xx.
>> +
>>   config ARM_ARCH_TIMER
>>         bool
>>         select CLKSRC_OF if OF
>> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
>> index 5b85f6adb258..5928e35cb64d 100644
>> --- a/drivers/clocksource/Makefile
>> +++ b/drivers/clocksource/Makefile
>> @@ -37,6 +37,7 @@ obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm_kona_timer.o
>>   obj-$(CONFIG_CADENCE_TTC_TIMER)       += cadence_ttc_timer.o
>>   obj-$(CONFIG_CLKSRC_EFM32)    += time-efm32.o
>>   obj-$(CONFIG_CLKSRC_EXYNOS_MCT)       += exynos_mct.o
>> +obj-$(CONFIG_CLKSRC_LPC32XX)   += time-lpc32xx.o
>>   obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)      += samsung_pwm_timer.o
>>   obj-$(CONFIG_FSL_FTM_TIMER)   += fsl_ftm_timer.o
>>   obj-$(CONFIG_VF_PIT_TIMER)    += vf_pit_timer.o
>> diff --git a/drivers/clocksource/time-lpc32xx.c
>> b/drivers/clocksource/time-lpc32xx.c
>> new file mode 100644
>> index 000000000000..bb94409cf89c
>> --- /dev/null
>> +++ b/drivers/clocksource/time-lpc32xx.c
>> @@ -0,0 +1,259 @@
>> +/*
>> + * Clocksource driver for NXP LPC32xx/18xx/43xx timer
>> + *
>> + * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
>> + *
>> + * Based on:
>> + * time-efm32 Copyright (C) 2013 Pengutronix
>> + * mach-lpc32xx/timer.c Copyright (C) 2009 - 2010 NXP Semiconductors
>> + *
>> + * 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.
>> + *
>> + */
>> +
>> +#define pr_fmt(fmt) "%s: " fmt, __func__
>> +
>> +#include <linux/clk.h>
>> +#include <linux/clockchips.h>
>> +#include <linux/clocksource.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/irq.h>
>> +#include <linux/kernel.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_irq.h>
>> +#include <linux/sched_clock.h>
>> +
>> +#define LPC32XX_TIMER_IR               0x000
>> +#define  LPC32XX_TIMER_IR_MR0INT       BIT(0)
>> +#define LPC32XX_TIMER_TCR              0x004
>> +#define  LPC32XX_TIMER_TCR_CEN         BIT(0)
>> +#define  LPC32XX_TIMER_TCR_CRST                BIT(1)
>> +#define LPC32XX_TIMER_TC               0x008
>> +#define LPC32XX_TIMER_PR               0x00c
>> +#define LPC32XX_TIMER_MCR              0x014
>> +#define  LPC32XX_TIMER_MCR_MR0I                BIT(0)
>> +#define  LPC32XX_TIMER_MCR_MR0R                BIT(1)
>> +#define  LPC32XX_TIMER_MCR_MR0S                BIT(2)
>> +#define LPC32XX_TIMER_MR0              0x018
>> +
>> +struct lpc32xx_clock_event_ddata {
>> +       struct clock_event_device evtdev;
>> +       void __iomem *base;
>> +};
>> +
>> +/* Needed for the sched clock */
>> +static void __iomem *clocksource_timer_counter;
>> +
>> +static u64 notrace lpc32xx_read_sched_clock(void)
>> +{
>> +       return readl(clocksource_timer_counter);
>> +}
>> +
>> +static int lpc32xx_clkevt_next_event(unsigned long delta,
>> +                                    struct clock_event_device *evtdev)
>> +{
>> +       struct lpc32xx_clock_event_ddata *ddata =
>> +               container_of(evtdev, struct lpc32xx_clock_event_ddata,
>> evtdev);
>> +
>> +       writel_relaxed(LPC32XX_TIMER_TCR_CRST, ddata->base +
>> LPC32XX_TIMER_TCR);
>> +       writel_relaxed(delta, ddata->base + LPC32XX_TIMER_PR);
>> +       writel_relaxed(LPC32XX_TIMER_TCR_CEN, ddata->base +
>> LPC32XX_TIMER_TCR);
>> +
>> +       return 0;
>> +}
>> +
>> +static void lpc32xx_clkevt_mode(enum clock_event_mode mode,
>> +                               struct clock_event_device *evtdev)
>
>
> See below.
>
>
>> +{
>> +       struct lpc32xx_clock_event_ddata *ddata =
>> +               container_of(evtdev, struct lpc32xx_clock_event_ddata,
>> evtdev);
>> +
>> +       switch (mode) {
>> +       case CLOCK_EVT_MODE_PERIODIC:
>> +               WARN_ON(1);
>> +               break;
>> +
>> +       case CLOCK_EVT_MODE_ONESHOT:
>> +       case CLOCK_EVT_MODE_SHUTDOWN:
>> +               /*
>> +                * Disable the timer. When using oneshot, we must also
>> +                * disable the timer to wait for the first call to
>> +                * set_next_event().
>> +                */
>> +               writel_relaxed(0, ddata->base + LPC32XX_TIMER_TCR);
>> +               break;
>> +
>> +       case CLOCK_EVT_MODE_UNUSED:
>> +       case CLOCK_EVT_MODE_RESUME:
>> +               break;
>> +       }
>> +}
>> +
>> +static irqreturn_t lpc32xx_clock_event_handler(int irq, void *dev_id)
>> +{
>> +       struct lpc32xx_clock_event_ddata *ddata = dev_id;
>> +
>> +       /* Clear match */
>> +       writel_relaxed(LPC32XX_TIMER_IR_MR0INT, ddata->base +
>> LPC32XX_TIMER_IR);
>> +
>> +       ddata->evtdev.event_handler(&ddata->evtdev);
>> +
>> +       return IRQ_HANDLED;
>> +}
>> +
>> +static struct lpc32xx_clock_event_ddata lpc32xx_clk_event_ddata = {
>> +       .evtdev = {
>> +               .name           = "lpc3220 clockevent",
>> +               .features       = CLOCK_EVT_FEAT_ONESHOT,
>> +               .rating         = 300,
>> +               .set_next_event = lpc32xx_clkevt_next_event,
>> +               .set_mode       = lpc32xx_clkevt_mode,
>
>
> Please take the opportunity to switch to the new API (see commit 77e32c89).

oh, I was not aware of the new API. I'll adapt the driver.

Has any other drivers been switched over that I could take a look at?

>> +       },
>> +};
>> +
>> +static int __init lpc32xx_clocksource_init(struct device_node *np)
>> +{
>> +       void __iomem *base;
>> +       unsigned long rate;
>> +       struct clk *clk;
>> +       int ret;
>> +
>> +       clk = of_clk_get_by_name(np, "timerclk");
>> +       if (IS_ERR(clk)) {
>> +               pr_err("clock get failed (%lu)\n", PTR_ERR(clk));
>> +               return PTR_ERR(clk);
>> +       }
>> +
>> +       ret = clk_prepare_enable(clk);
>> +       if (ret) {
>> +               pr_err("clock enable failed (%d)\n", ret);
>> +               goto err_clk_enable;
>> +       }
>> +
>> +       base = of_iomap(np, 0);
>> +       if (!base) {
>> +               pr_err("unable to map registers\n");
>> +               ret = -EADDRNOTAVAIL;
>> +               goto err_iomap;
>> +       }
>> +
>> +       writel_relaxed(LPC32XX_TIMER_TCR_CRST, base + LPC32XX_TIMER_TCR);
>> +       writel_relaxed(0, base + LPC32XX_TIMER_PR);
>> +       writel_relaxed(0, base + LPC32XX_TIMER_MCR);
>> +       writel_relaxed(LPC32XX_TIMER_TCR_CEN, base + LPC32XX_TIMER_TCR);
>
>
> Please add a detailed comment about those 4 lines. Perhaps also group them
> in a function.

Sure.

>> +
>> +       rate = clk_get_rate(clk);
>> +       ret = clocksource_mmio_init(base + LPC32XX_TIMER_TC, "lpc3220
>> timer",
>> +                                   rate, 300, 32,
>> clocksource_mmio_readl_up);
>> +       if (ret) {
>> +               pr_err("failed to init clocksource (%d)\n", ret);
>> +               goto err_clocksource_init;
>> +       }
>> +
>> +       clocksource_timer_counter = base + LPC32XX_TIMER_TC;
>> +       sched_clock_register(lpc32xx_read_sched_clock, 32, rate);
>> +
>> +       return 0;
>> +
>> +err_clocksource_init:
>> +       iounmap(base);
>> +err_iomap:
>> +       clk_disable_unprepare(clk);
>> +err_clk_enable:
>> +       clk_put(clk);
>> +       return ret;
>> +}
>> +
>> +static int __init lpc32xx_clockevent_init(struct device_node *np)
>> +{
>> +       void __iomem *base;
>> +       unsigned long rate;
>> +       struct clk *clk;
>> +       int ret, irq;
>> +
>> +       clk = of_clk_get_by_name(np, "timerclk");
>> +       if (IS_ERR(clk)) {
>> +               pr_err("clock get failed (%lu)\n", PTR_ERR(clk));
>> +               return PTR_ERR(clk);
>> +       }
>> +
>> +       ret = clk_prepare_enable(clk);
>> +       if (ret) {
>> +               pr_err("clock enable failed (%d)\n", ret);
>> +               goto err_clk_enable;
>> +       }
>> +
>> +       base = of_iomap(np, 0);
>> +       if (!base) {
>> +               pr_err("unable to map registers\n");
>> +               ret = -EADDRNOTAVAIL;
>> +               goto err_iomap;
>> +       }
>> +
>> +       irq = irq_of_parse_and_map(np, 0);
>> +       if (!irq) {
>> +               pr_err("get irq failed\n");
>> +               ret = -ENOENT;
>> +               goto err_irq;
>> +       }
>> +
>> +       /* Initial timer setup */
>> +       writel_relaxed(0, base + LPC32XX_TIMER_TCR);
>> +       writel_relaxed(LPC32XX_TIMER_IR_MR0INT, base + LPC32XX_TIMER_IR);
>> +       writel_relaxed(1, base + LPC32XX_TIMER_MR0);
>> +       writel_relaxed(LPC32XX_TIMER_MCR_MR0I | LPC32XX_TIMER_MCR_MR0R |
>> +                      LPC32XX_TIMER_MCR_MR0S, base + LPC32XX_TIMER_MCR);
>
>
> Ditto.

Sure.


Thanks for the review, Daniel. I'll make the changes and send a v4.


regards,
Joachim Eastwood

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

* [PATCH v3 2/7] clocksource: add lpc32xx timer driver
  2015-05-11 11:30     ` Joachim Eastwood
@ 2015-05-11 11:37       ` Daniel Lezcano
  2015-05-11 11:42         ` Viresh Kumar
  0 siblings, 1 reply; 14+ messages in thread
From: Daniel Lezcano @ 2015-05-11 11:37 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/11/2015 01:30 PM, Joachim Eastwood wrote:
> Hi Daniel,
>
> On 11 May 2015 at 13:05, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
>> On 05/07/2015 06:48 PM, Joachim Eastwood wrote:
>>>
>>> Add support for using the NXP LPC timer as clocksource and
>>> clock event. These timers are present on many NXP devices
>>> including LPC32xx, LPC17xx, LPC18xx and LPC43xx.
>>
>>
>> A brief description of the hardware would be nice.
>
> I'll see what I can come up with.
>
>> Some comments below.
>>
>> Thanks !
>>
>>    -- Daniel
>>
>>> Signed-off-by: Joachim Eastwood <manabian@gmail.com>
>>> ---
>>>    drivers/clocksource/Kconfig        |  10 ++
>>>    drivers/clocksource/Makefile       |   1 +
>>>    drivers/clocksource/time-lpc32xx.c | 259
>>> +++++++++++++++++++++++++++++++++++++
>>>    3 files changed, 270 insertions(+)
>>>    create mode 100644 drivers/clocksource/time-lpc32xx.c
>>>
>>> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
>>> index 51d7865fdddb..71c532314f1d 100644
>>> --- a/drivers/clocksource/Kconfig
>>> +++ b/drivers/clocksource/Kconfig
>>> @@ -106,6 +106,16 @@ config CLKSRC_EFM32
>>>            Support to use the timers of EFM32 SoCs as clock source and
>>> clock
>>>            event device.
>>>
>>> +config CLKSRC_LPC32XX
>>> +       bool "Clocksource for NXP's LPC SoC series" if !ARCH_LPC18XX
>>
>>
>> Except you have a really good reason, the timers are not prompted. It is up
>> to the platform's config to select the driver.
>
> I only copied the CLKSRC_EFM32 entry so I don't have any good reasons.
>
> Would something simple like this be okay?
> config  CLKSRC_LPC32XX
>          bool
>          select CLKSRC_MMIO
>          select CLKSRC_OF
>
> And then of course update platform Kconfig to select this symbol.

That will be fine.

>>> +       depends on OF && ARM && (ARCH_LPC18XX || COMPILE_TEST)
>>> +       select CLKSRC_MMIO
>>> +       default ARCH_LPC18XX
>>> +       help
>>> +         Support to use the timers of LPC SoCs as clock source and clock
>>> +         event device. These timers are present on many NXP devices
>>> +         including LPC32xx, LPC17xx, LPC18xx and LPC43xx.
>>> +
>>>    config ARM_ARCH_TIMER
>>>          bool
>>>          select CLKSRC_OF if OF
>>> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
>>> index 5b85f6adb258..5928e35cb64d 100644
>>> --- a/drivers/clocksource/Makefile
>>> +++ b/drivers/clocksource/Makefile
>>> @@ -37,6 +37,7 @@ obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm_kona_timer.o
>>>    obj-$(CONFIG_CADENCE_TTC_TIMER)       += cadence_ttc_timer.o
>>>    obj-$(CONFIG_CLKSRC_EFM32)    += time-efm32.o
>>>    obj-$(CONFIG_CLKSRC_EXYNOS_MCT)       += exynos_mct.o
>>> +obj-$(CONFIG_CLKSRC_LPC32XX)   += time-lpc32xx.o
>>>    obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)      += samsung_pwm_timer.o
>>>    obj-$(CONFIG_FSL_FTM_TIMER)   += fsl_ftm_timer.o
>>>    obj-$(CONFIG_VF_PIT_TIMER)    += vf_pit_timer.o
>>> diff --git a/drivers/clocksource/time-lpc32xx.c
>>> b/drivers/clocksource/time-lpc32xx.c
>>> new file mode 100644
>>> index 000000000000..bb94409cf89c
>>> --- /dev/null
>>> +++ b/drivers/clocksource/time-lpc32xx.c
>>> @@ -0,0 +1,259 @@
>>> +/*
>>> + * Clocksource driver for NXP LPC32xx/18xx/43xx timer
>>> + *
>>> + * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
>>> + *
>>> + * Based on:
>>> + * time-efm32 Copyright (C) 2013 Pengutronix
>>> + * mach-lpc32xx/timer.c Copyright (C) 2009 - 2010 NXP Semiconductors
>>> + *
>>> + * 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.
>>> + *
>>> + */
>>> +
>>> +#define pr_fmt(fmt) "%s: " fmt, __func__
>>> +
>>> +#include <linux/clk.h>
>>> +#include <linux/clockchips.h>
>>> +#include <linux/clocksource.h>
>>> +#include <linux/interrupt.h>
>>> +#include <linux/irq.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/of.h>
>>> +#include <linux/of_address.h>
>>> +#include <linux/of_irq.h>
>>> +#include <linux/sched_clock.h>
>>> +
>>> +#define LPC32XX_TIMER_IR               0x000
>>> +#define  LPC32XX_TIMER_IR_MR0INT       BIT(0)
>>> +#define LPC32XX_TIMER_TCR              0x004
>>> +#define  LPC32XX_TIMER_TCR_CEN         BIT(0)
>>> +#define  LPC32XX_TIMER_TCR_CRST                BIT(1)
>>> +#define LPC32XX_TIMER_TC               0x008
>>> +#define LPC32XX_TIMER_PR               0x00c
>>> +#define LPC32XX_TIMER_MCR              0x014
>>> +#define  LPC32XX_TIMER_MCR_MR0I                BIT(0)
>>> +#define  LPC32XX_TIMER_MCR_MR0R                BIT(1)
>>> +#define  LPC32XX_TIMER_MCR_MR0S                BIT(2)
>>> +#define LPC32XX_TIMER_MR0              0x018
>>> +
>>> +struct lpc32xx_clock_event_ddata {
>>> +       struct clock_event_device evtdev;
>>> +       void __iomem *base;
>>> +};
>>> +
>>> +/* Needed for the sched clock */
>>> +static void __iomem *clocksource_timer_counter;
>>> +
>>> +static u64 notrace lpc32xx_read_sched_clock(void)
>>> +{
>>> +       return readl(clocksource_timer_counter);
>>> +}
>>> +
>>> +static int lpc32xx_clkevt_next_event(unsigned long delta,
>>> +                                    struct clock_event_device *evtdev)
>>> +{
>>> +       struct lpc32xx_clock_event_ddata *ddata =
>>> +               container_of(evtdev, struct lpc32xx_clock_event_ddata,
>>> evtdev);
>>> +
>>> +       writel_relaxed(LPC32XX_TIMER_TCR_CRST, ddata->base +
>>> LPC32XX_TIMER_TCR);
>>> +       writel_relaxed(delta, ddata->base + LPC32XX_TIMER_PR);
>>> +       writel_relaxed(LPC32XX_TIMER_TCR_CEN, ddata->base +
>>> LPC32XX_TIMER_TCR);
>>> +
>>> +       return 0;
>>> +}
>>> +
>>> +static void lpc32xx_clkevt_mode(enum clock_event_mode mode,
>>> +                               struct clock_event_device *evtdev)
>>
>>
>> See below.
>>
>>
>>> +{
>>> +       struct lpc32xx_clock_event_ddata *ddata =
>>> +               container_of(evtdev, struct lpc32xx_clock_event_ddata,
>>> evtdev);
>>> +
>>> +       switch (mode) {
>>> +       case CLOCK_EVT_MODE_PERIODIC:
>>> +               WARN_ON(1);
>>> +               break;
>>> +
>>> +       case CLOCK_EVT_MODE_ONESHOT:
>>> +       case CLOCK_EVT_MODE_SHUTDOWN:
>>> +               /*
>>> +                * Disable the timer. When using oneshot, we must also
>>> +                * disable the timer to wait for the first call to
>>> +                * set_next_event().
>>> +                */
>>> +               writel_relaxed(0, ddata->base + LPC32XX_TIMER_TCR);
>>> +               break;
>>> +
>>> +       case CLOCK_EVT_MODE_UNUSED:
>>> +       case CLOCK_EVT_MODE_RESUME:
>>> +               break;
>>> +       }
>>> +}
>>> +
>>> +static irqreturn_t lpc32xx_clock_event_handler(int irq, void *dev_id)
>>> +{
>>> +       struct lpc32xx_clock_event_ddata *ddata = dev_id;
>>> +
>>> +       /* Clear match */
>>> +       writel_relaxed(LPC32XX_TIMER_IR_MR0INT, ddata->base +
>>> LPC32XX_TIMER_IR);
>>> +
>>> +       ddata->evtdev.event_handler(&ddata->evtdev);
>>> +
>>> +       return IRQ_HANDLED;
>>> +}
>>> +
>>> +static struct lpc32xx_clock_event_ddata lpc32xx_clk_event_ddata = {
>>> +       .evtdev = {
>>> +               .name           = "lpc3220 clockevent",
>>> +               .features       = CLOCK_EVT_FEAT_ONESHOT,
>>> +               .rating         = 300,
>>> +               .set_next_event = lpc32xx_clkevt_next_event,
>>> +               .set_mode       = lpc32xx_clkevt_mode,
>>
>>
>> Please take the opportunity to switch to the new API (see commit 77e32c89).
>
> oh, I was not aware of the new API. I'll adapt the driver.
>
> Has any other drivers been switched over that I could take a look at?

Not I am aware of. Viresh [Cc'ed] has a bunch of driver changes in its 
log to send, may be he can send you one you can look at.

Thanks !

   -- Daniel


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

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

* [PATCH v3 2/7] clocksource: add lpc32xx timer driver
  2015-05-11 11:37       ` Daniel Lezcano
@ 2015-05-11 11:42         ` Viresh Kumar
  2015-05-11 11:54           ` Joachim Eastwood
  0 siblings, 1 reply; 14+ messages in thread
From: Viresh Kumar @ 2015-05-11 11:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 11-05-15, 13:37, Daniel Lezcano wrote:
> On 05/11/2015 01:30 PM, Joachim Eastwood wrote:
> >Has any other drivers been switched over that I could take a look at?
> 
> Not I am aware of. Viresh [Cc'ed] has a bunch of driver changes in
> its log to send, may be he can send you one you can look at.

git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/linux.git	clkevt/migrate-to-new-per-state-api

NOTE: I haven't tried to upstream any of this yet. Waiting for some other
changes to get merged first.

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

* [PATCH v3 2/7] clocksource: add lpc32xx timer driver
  2015-05-11 11:42         ` Viresh Kumar
@ 2015-05-11 11:54           ` Joachim Eastwood
  2015-05-11 12:52             ` Viresh Kumar
  0 siblings, 1 reply; 14+ messages in thread
From: Joachim Eastwood @ 2015-05-11 11:54 UTC (permalink / raw)
  To: linux-arm-kernel

On 11 May 2015 at 13:42, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> On 11-05-15, 13:37, Daniel Lezcano wrote:
>> On 05/11/2015 01:30 PM, Joachim Eastwood wrote:
>> >Has any other drivers been switched over that I could take a look at?
>>
>> Not I am aware of. Viresh [Cc'ed] has a bunch of driver changes in
>> its log to send, may be he can send you one you can look at.
>
> git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/linux.git clkevt/migrate-to-new-per-state-api

Thanks. The changes look quite simple to make.

> NOTE: I haven't tried to upstream any of this yet. Waiting for some other
> changes to get merged first.

I see. Should I switch the API in my clocksource driver now or should
that also wait?


regards,
Joachim Eastwood

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

* [PATCH v3 2/7] clocksource: add lpc32xx timer driver
  2015-05-11 11:54           ` Joachim Eastwood
@ 2015-05-11 12:52             ` Viresh Kumar
  0 siblings, 0 replies; 14+ messages in thread
From: Viresh Kumar @ 2015-05-11 12:52 UTC (permalink / raw)
  To: linux-arm-kernel

On 11-05-15, 13:54, Joachim Eastwood wrote:
> I see. Should I switch the API in my clocksource driver now or should
> that also wait?

You don't have to wait.

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

end of thread, other threads:[~2015-05-11 12:52 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-07 16:48 [PATCH v3 0/7] Add support for NXP LPC18xx family Joachim Eastwood
2015-05-07 16:48 ` [PATCH v3 1/7] ARM: lpc18xx: add basic support for NXP LPC18xx/43xx SoCs Joachim Eastwood
2015-05-07 16:48 ` [PATCH v3 2/7] clocksource: add lpc32xx timer driver Joachim Eastwood
2015-05-11 11:05   ` Daniel Lezcano
2015-05-11 11:30     ` Joachim Eastwood
2015-05-11 11:37       ` Daniel Lezcano
2015-05-11 11:42         ` Viresh Kumar
2015-05-11 11:54           ` Joachim Eastwood
2015-05-11 12:52             ` Viresh Kumar
2015-05-07 16:48 ` [PATCH v3 3/7] doc: dt: add documentation for lpc3220-timer Joachim Eastwood
2015-05-07 16:48 ` [PATCH v3 4/7] ARM: dts: Add base DT for NXP LPC18xx Joachim Eastwood
2015-05-07 16:48 ` [PATCH v3 5/7] ARM: dts: Add DT for Embedded Artists LPC4357 Developers Kit Joachim Eastwood
2015-05-07 16:48 ` [PATCH v3 6/7] ARM: dts: Add DT for Hitex LPC4350 Evaluation Board Joachim Eastwood
2015-05-07 16:48 ` [PATCH v3 7/7] ARM: lpc18xx: add kernel config Joachim Eastwood

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.