summaryrefslogtreecommitdiffstats
path: root/configs/platform-energymicro-efm32gg-dk3750/patches/linux-3.11-rc1/0004-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'configs/platform-energymicro-efm32gg-dk3750/patches/linux-3.11-rc1/0004-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch')
-rw-r--r--configs/platform-energymicro-efm32gg-dk3750/patches/linux-3.11-rc1/0004-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch843
1 files changed, 0 insertions, 843 deletions
diff --git a/configs/platform-energymicro-efm32gg-dk3750/patches/linux-3.11-rc1/0004-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch b/configs/platform-energymicro-efm32gg-dk3750/patches/linux-3.11-rc1/0004-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch
deleted file mode 100644
index 3e161f6..0000000
--- a/configs/platform-energymicro-efm32gg-dk3750/patches/linux-3.11-rc1/0004-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch
+++ /dev/null
@@ -1,843 +0,0 @@
-From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
-Date: Thu, 17 Nov 2011 14:36:23 +0100
-Subject: [PATCH] ARM: new platform for Energy Micro's EFM32 Cortex-M3 SoCs
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
----
- arch/arm/Kconfig | 15 +-
- arch/arm/Kconfig.debug | 16 ++
- arch/arm/Makefile | 1 +
- arch/arm/boot/dts/efm32gg-dk3750.dts | 126 +++++++++++
- arch/arm/mach-efm32/Makefile | 1 +
- arch/arm/mach-efm32/Makefile.boot | 1 +
- arch/arm/mach-efm32/clk.c | 88 ++++++++
- arch/arm/mach-efm32/cmu.h | 15 ++
- arch/arm/mach-efm32/common.h | 3 +
- arch/arm/mach-efm32/dtmachine.c | 28 +++
- arch/arm/mach-efm32/include/mach/debug-macro.S | 48 ++++
- arch/arm/mach-efm32/include/mach/entry-macro.S | 9 +
- arch/arm/mach-efm32/include/mach/io.h | 6 +
- arch/arm/mach-efm32/include/mach/irqs.h | 6 +
- arch/arm/mach-efm32/include/mach/system.h | 18 ++
- arch/arm/mach-efm32/include/mach/timex.h | 7 +
- arch/arm/mach-efm32/time.c | 289 +++++++++++++++++++++++++
- 17 files changed, 676 insertions(+), 1 deletion(-)
- create mode 100644 arch/arm/boot/dts/efm32gg-dk3750.dts
- create mode 100644 arch/arm/mach-efm32/Makefile
- create mode 100644 arch/arm/mach-efm32/Makefile.boot
- create mode 100644 arch/arm/mach-efm32/clk.c
- create mode 100644 arch/arm/mach-efm32/cmu.h
- create mode 100644 arch/arm/mach-efm32/common.h
- create mode 100644 arch/arm/mach-efm32/dtmachine.c
- create mode 100644 arch/arm/mach-efm32/include/mach/debug-macro.S
- create mode 100644 arch/arm/mach-efm32/include/mach/entry-macro.S
- create mode 100644 arch/arm/mach-efm32/include/mach/io.h
- create mode 100644 arch/arm/mach-efm32/include/mach/irqs.h
- create mode 100644 arch/arm/mach-efm32/include/mach/system.h
- create mode 100644 arch/arm/mach-efm32/include/mach/timex.h
- create mode 100644 arch/arm/mach-efm32/time.c
-
-diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index ba412e0..b8196cc 100644
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -404,6 +404,19 @@ config ARCH_EBSA110
- Ethernet interface, two PCMCIA sockets, two serial ports and a
- parallel port.
-
-+config ARCH_EFM32
-+ bool "Energy Micro Cortex M3 Platform"
-+ depends on !MMU
-+ select ARM_NVIC
-+ select CLKSRC_MMIO
-+ select COMMON_CLK
-+ select CPU_V7M
-+ select GENERIC_CLOCKEVENTS
-+ select HAVE_CLK
-+ select NO_DMA
-+ select NO_IOPORT
-+ select USE_OF
-+
- config ARCH_EP93XX
- bool "EP93xx-based"
- select ARCH_HAS_HOLES_MEMORYMODEL
-@@ -1763,7 +1776,7 @@ config FORCE_MAX_ZONEORDER
- int "Maximum zone order" if ARCH_SHMOBILE
- range 11 64 if ARCH_SHMOBILE
- default "12" if SOC_AM33XX
-- default "9" if SA1111
-+ default "9" if SA1111 || ARCH_EFM32
- default "11"
- help
- The kernel memory allocator divides physically contiguous memory
-diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
-index e401a76..9f1b304 100644
---- a/arch/arm/Kconfig.debug
-+++ b/arch/arm/Kconfig.debug
-@@ -167,6 +167,22 @@ choice
- Say Y here if you want the debug print routines to direct
- their output to the serial port in the DC21285 (Footbridge).
-
-+ config DEBUG_EFM32_USART1
-+ bool "Kernel low-level debugging messages via USART1"
-+ depends on ARCH_EFM32
-+ help
-+ Say Y here if you want the debug print routines to direct
-+ their output to the second USART port on efm32 based
-+ machines.
-+
-+ config DEBUG_EFM32_UART1
-+ bool "Kernel low-level debugging messages via UART1"
-+ depends on ARCH_EFM32
-+ help
-+ Say Y here if you want the debug print routines to direct
-+ their output to the second UART port on efm32 based
-+ machines.
-+
- config DEBUG_FOOTBRIDGE_COM1
- bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1"
- depends on FOOTBRIDGE
-diff --git a/arch/arm/Makefile b/arch/arm/Makefile
-index c0ac0f5..c632e2a 100644
---- a/arch/arm/Makefile
-+++ b/arch/arm/Makefile
-@@ -152,6 +152,7 @@ machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx
- machine-$(CONFIG_ARCH_DAVINCI) += davinci
- machine-$(CONFIG_ARCH_DOVE) += dove
- machine-$(CONFIG_ARCH_EBSA110) += ebsa110
-+machine-$(CONFIG_ARCH_EFM32) += efm32
- machine-$(CONFIG_ARCH_EP93XX) += ep93xx
- machine-$(CONFIG_ARCH_GEMINI) += gemini
- machine-$(CONFIG_ARCH_HIGHBANK) += highbank
-diff --git a/arch/arm/boot/dts/efm32gg-dk3750.dts b/arch/arm/boot/dts/efm32gg-dk3750.dts
-new file mode 100644
-index 0000000..10e8d94
---- /dev/null
-+++ b/arch/arm/boot/dts/efm32gg-dk3750.dts
-@@ -0,0 +1,126 @@
-+/dts-v1/;
-+/include/ "skeleton.dtsi"
-+
-+/ {
-+ model = "Energy Micro Giant Gecko Development Kit";
-+ compatible = "efm32,dk3750";
-+
-+ aliases {
-+ serial4 = &uart4;
-+ };
-+
-+ nvic: nv-interrupt-controller@0xe0000000 {
-+ compatible = "arm,armv7m-nvic";
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ reg = <0xe000e100 0xc00>;
-+ };
-+
-+ chosen {
-+ bootargs = "console=ttyefm4,115200 init=/linuxrc ignore_loglevel ihash_entries=64 dhash_entries=64 earlyprintk uclinux.physaddr=0x8c400000 root=/dev/mtdblock0";
-+ };
-+
-+ memory {
-+ reg = <0x88000000 0x400000>;
-+ };
-+
-+ soc {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ compatible = "simple-bus";
-+ interrupt-parent = <&nvic>;
-+ ranges;
-+
-+ adc@0x40002000 {
-+ compatible = "efm32,adc";
-+ reg = <0x40002000 0x400>;
-+ interrupts = <7>;
-+ status = "ok";
-+ };
-+
-+ gpio: gpio@0x40006000 {
-+ compatible = "efm32,gpio";
-+ reg = <0x40006000 0x1000>;
-+ interrupts = <1 11>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ clocks = <&cmu 32>;
-+ status = "ok";
-+ };
-+
-+ spi@0x4000c400 { /* USART1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "efm32,spi";
-+ reg = <0x4000c400 0x400>;
-+ interrupts = <15 16>;
-+ clocks = <&cmu 20>;
-+ cs-gpios = <&gpio 51 1>; // D3
-+ status = "ok";
-+
-+ ks8851@0 {
-+ compatible = "ks8851";
-+ spi-max-frequency = <6000000>;
-+ reg = <0>;
-+ interrupt-parent = <&boardfpga>;
-+ interrupts = <4>;
-+ status = "ok";
-+ };
-+ };
-+
-+ uart4: uart@0x4000e400 { /* UART1 */
-+ compatible = "efm32,uart";
-+ reg = <0x4000e400 0x400>;
-+ interrupts = <22 23>;
-+ clocks = <&cmu 23>;
-+ location = <2>;
-+ status = "ok";
-+ };
-+
-+ timer0: timer@40010000 {
-+ compatible = "efm32,timer";
-+ reg = <0x40010000 0x400>;
-+ interrupts = <2>;
-+ clocks = <&cmu 24>;
-+ };
-+
-+ timer1: timer@40010400 {
-+ compatible = "efm32,timer";
-+ reg = <0x40010400 0x400>;
-+ interrupts = <12>;
-+ clocks = <&cmu 25>;
-+ };
-+
-+ timer2: timer@40010800 {
-+ compatible = "efm32,timer";
-+ reg = <0x40010800 0x400>;
-+ interrupts = <13>;
-+ clocks = <&cmu 26>;
-+ };
-+
-+ timer3: timer@40010c00 {
-+ compatible = "efm32,timer";
-+ reg = <0x40010c00 0x400>;
-+ interrupts = <14>;
-+ clocks = <&cmu 27>;
-+ };
-+
-+ cmu: cmu@400c8000 {
-+ compatible = "efm32,cmu";
-+ reg = <0x400c8000 0x400>;
-+ interrupts = <32>;
-+ #clock-cells = <1>;
-+ };
-+
-+ boardfpga: boardfpga@0x80000000 {
-+ compatible = "efm32board";
-+ reg = <0x80000000 0x400>;
-+ irq-gpios = <&gpio 64 1>;
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ status = "ok";
-+ };
-+ };
-+};
-diff --git a/arch/arm/mach-efm32/Makefile b/arch/arm/mach-efm32/Makefile
-new file mode 100644
-index 0000000..c6786a0
---- /dev/null
-+++ b/arch/arm/mach-efm32/Makefile
-@@ -0,0 +1 @@
-+obj-y += clk.o dtmachine.o time.o
-diff --git a/arch/arm/mach-efm32/Makefile.boot b/arch/arm/mach-efm32/Makefile.boot
-new file mode 100644
-index 0000000..385e93a
---- /dev/null
-+++ b/arch/arm/mach-efm32/Makefile.boot
-@@ -0,0 +1 @@
-+dtb-$(CONFIG_MACH_EFM32GG_DK3750) += efm32gg-dk3750.dtb
-diff --git a/arch/arm/mach-efm32/clk.c b/arch/arm/mach-efm32/clk.c
-new file mode 100644
-index 0000000..f99719a
---- /dev/null
-+++ b/arch/arm/mach-efm32/clk.c
-@@ -0,0 +1,88 @@
-+#include <linux/clk.h>
-+#include <linux/io.h>
-+#include <linux/clk-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+
-+#include "cmu.h"
-+
-+enum efm32_clks {
-+ /* 0 */ hfxo, hfrco, lfxo, lfrco, ulfrco, auxhfrco, hfclknodiv, hfclk,
-+ /* 8 */ hfperclk, hfcoreclk, lfaclk, lfbclk, wdogclk, hfcoreclkdma,
-+ /* 14 */ hfcoreclkaes, hfcoreclkusbc, hfcoreclkusb, hfcoreclkle,
-+ /* 18 */ hfcoreclkebi, hfperclkusart0, hfperclkusart1, hfperclkusart2,
-+ /* 22 */ hfperclkuart0, hfperclkuart1, hfperclktimer0, hfperclktimer1,
-+ /* 26 */ hfperclktimer2, hfperclktimer3, hfperclkacmp0, hfperclkacmp1,
-+ /* 30 */ hfperclki2c0, hfperclki2c1, hfperclkgpio, hfperclkvcmp,
-+ /* 34 */ hfperclkprs, hfperclkadc0, hfperclkdac0, clk_max
-+};
-+
-+static struct clk *clk[clk_max];
-+static struct clk_onecell_data clk_data = {
-+ .clks = clk,
-+ .clk_num = ARRAY_SIZE(clk),
-+};
-+
-+void __init efm32_clk_init(void)
-+{
-+ int i;
-+ struct device_node *np;
-+ void __iomem *base;
-+
-+ for (i = 0; i < clk_max; ++i)
-+ clk[i] = ERR_PTR(-ENOENT);
-+
-+ np = of_find_compatible_node(NULL, NULL, "efm32,cmu");
-+ if (!np) {
-+ pr_warn("failed to find cmu node in device tree\n");
-+ return;
-+ }
-+
-+ base = of_iomap(np, 0);
-+ if (!base) {
-+ pr_warn("failed to map cmu\n");
-+ return;
-+ }
-+
-+ clk[hfxo] = clk_register_fixed_rate(NULL, "HFXO", NULL,
-+ CLK_IS_ROOT, 48000000);
-+
-+ clk[hfperclkusart0] = clk_register_gate(NULL, "HFPERCLK.USART0", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 0, 0, NULL);
-+ clk[hfperclkusart1] = clk_register_gate(NULL, "HFPERCLK.USART1", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 1, 0, NULL);
-+ clk[hfperclkusart2] = clk_register_gate(NULL, "HFPERCLK.USART2", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 2, 0, NULL);
-+ clk[hfperclkuart0] = clk_register_gate(NULL, "HFPERCLK.UART0", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 3, 0, NULL);
-+ clk[hfperclkuart1] = clk_register_gate(NULL, "HFPERCLK.UART1", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 4, 0, NULL);
-+ clk[hfperclktimer0] = clk_register_gate(NULL, "HFPERCLK.TIMER0", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 5, 0, NULL);
-+ clk[hfperclktimer1] = clk_register_gate(NULL, "HFPERCLK.TIMER1", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 6, 0, NULL);
-+ clk[hfperclktimer2] = clk_register_gate(NULL, "HFPERCLK.TIMER2", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 7, 0, NULL);
-+ clk[hfperclktimer3] = clk_register_gate(NULL, "HFPERCLK.TIMER3", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 8, 0, NULL);
-+ clk[hfperclkacmp0] = clk_register_gate(NULL, "HFPERCLK.ACMP0", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 9, 0, NULL);
-+ clk[hfperclkacmp1] = clk_register_gate(NULL, "HFPERCLK.ACMP1", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 10, 0, NULL);
-+ clk[hfperclki2c0] = clk_register_gate(NULL, "HFPERCLK.I2C0", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 11, 0, NULL);
-+ clk[hfperclki2c1] = clk_register_gate(NULL, "HFPERCLK.I2C1", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 12, 0, NULL);
-+ clk[hfperclkgpio] = clk_register_gate(NULL, "HFPERCLK.GPIO", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 13, 0, NULL);
-+ clk[hfperclkvcmp] = clk_register_gate(NULL, "HFPERCLK.VCMP", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 14, 0, NULL);
-+ clk[hfperclkprs] = clk_register_gate(NULL, "HFPERCLK.PRS", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 15, 0, NULL);
-+ clk[hfperclkadc0] = clk_register_gate(NULL, "HFPERCLK.ADC0", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 16, 0, NULL);
-+ clk[hfperclkdac0] = clk_register_gate(NULL, "HFPERCLK.DAC0", "HFXO",
-+ 0, base + CMU_HFPERCLKEN0, 17, 0, NULL);
-+
-+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
-+}
-diff --git a/arch/arm/mach-efm32/cmu.h b/arch/arm/mach-efm32/cmu.h
-new file mode 100644
-index 0000000..a7e5741
---- /dev/null
-+++ b/arch/arm/mach-efm32/cmu.h
-@@ -0,0 +1,15 @@
-+/*
-+ * Register definition for efm32's CMU component
-+ */
-+
-+#define CMU_OSCENCMD 0x20
-+#define CMU_OSCENCMD_HFXOEN 0x00000004
-+
-+#define CMU_CMD 0x24
-+#define CMU_CMD_HFCLKSEL_HFXO 0x00000002
-+
-+#define CMU_STATUS 0x2c
-+#define CMU_STATUS_HFRCOSEL 0x00000400
-+#define CMU_STATUS_HFXOSEL 0x00000800
-+
-+#define CMU_HFPERCLKEN0 0x44
-diff --git a/arch/arm/mach-efm32/common.h b/arch/arm/mach-efm32/common.h
-new file mode 100644
-index 0000000..8b04c19
---- /dev/null
-+++ b/arch/arm/mach-efm32/common.h
-@@ -0,0 +1,3 @@
-+void efm32_timer_init(void);
-+
-+void efm32_clk_init(void);
-diff --git a/arch/arm/mach-efm32/dtmachine.c b/arch/arm/mach-efm32/dtmachine.c
-new file mode 100644
-index 0000000..30fce6d
---- /dev/null
-+++ b/arch/arm/mach-efm32/dtmachine.c
-@@ -0,0 +1,28 @@
-+#include <linux/kernel.h>
-+#include <linux/pinctrl/machine.h>
-+#include <linux/irqdomain.h>
-+#include <linux/of_platform.h>
-+#include <linux/of_irq.h>
-+#include <linux/irqchip.h>
-+
-+#include <asm/mach/arch.h>
-+#include <asm/mach/time.h>
-+
-+#include "common.h"
-+
-+static void __init efm32_init(void)
-+{
-+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-+}
-+
-+static const char *const efm32gg_compat[] __initconst = {
-+ "efm32,dk3750",
-+ NULL
-+};
-+
-+DT_MACHINE_START(EFM32DT, "EFM32 (Device Tree Support)")
-+ .init_irq = irqchip_init,
-+ .init_time = efm32_timer_init,
-+ .init_machine = efm32_init,
-+ .dt_compat = efm32gg_compat,
-+MACHINE_END
-diff --git a/arch/arm/mach-efm32/include/mach/debug-macro.S b/arch/arm/mach-efm32/include/mach/debug-macro.S
-new file mode 100644
-index 0000000..c58915c
---- /dev/null
-+++ b/arch/arm/mach-efm32/include/mach/debug-macro.S
-@@ -0,0 +1,48 @@
-+/*
-+ * 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.
-+ */
-+
-+#define UARTn_CMD 0x000c
-+#define UARTn_CMD_TXEN 0x0004
-+
-+#define UARTn_STATUS 0x0010
-+#define UARTn_STATUS_TXC 0x0020
-+#define UARTn_STATUS_TXBL 0x0040
-+
-+#define UARTn_TXDATA 0x0034
-+
-+ .macro addruart, rx, tmp
-+#if defined(CONFIG_DEBUG_EFM32_USART1)
-+ ldr \rx, =(0x4000c400) /* USART1 */
-+#elif defined(CONFIG_DEBUG_EFM32_UART1)
-+ ldr \rx, =(0x4000e400) /* UART1 */
-+#else
-+#error "No debug port configured"
-+#endif
-+ /*
-+ * enable TX. The driver might disable that to save energy. We
-+ * don't care about disabling at the end as during debug power
-+ * consumption isn't that important.
-+ */
-+ ldr \tmp, =(UARTn_CMD_TXEN)
-+ str \tmp, [\rx, #UARTn_CMD]
-+ .endm
-+
-+
-+ .macro senduart,rd,rx
-+ strb \rd, [\rx, #UARTn_TXDATA]
-+ .endm
-+
-+ .macro waituart,rd,rx
-+1001: ldr \rd, [\rx, #UARTn_STATUS]
-+ tst \rd, #UARTn_STATUS_TXBL
-+ beq 1001b
-+ .endm
-+
-+ .macro busyuart,rd,rx
-+1001: ldr \rd, [\rx, UARTn_STATUS]
-+ tst \rd, #UARTn_STATUS_TXC
-+ bne 1001b
-+ .endm
-diff --git a/arch/arm/mach-efm32/include/mach/entry-macro.S b/arch/arm/mach-efm32/include/mach/entry-macro.S
-new file mode 100644
-index 0000000..547f7b1
---- /dev/null
-+++ b/arch/arm/mach-efm32/include/mach/entry-macro.S
-@@ -0,0 +1,9 @@
-+/*
-+ *
-+ */
-+
-+ .macro get_irqnr_preamble, base, tmp
-+ .endm
-+
-+ .macro arch_ret_to_user, tmp1, tmp2
-+ .endm
-diff --git a/arch/arm/mach-efm32/include/mach/io.h b/arch/arm/mach-efm32/include/mach/io.h
-new file mode 100644
-index 0000000..bc3519b
---- /dev/null
-+++ b/arch/arm/mach-efm32/include/mach/io.h
-@@ -0,0 +1,6 @@
-+#ifndef __MACH_IO_H__
-+#define __MACH_IO_H__
-+
-+#define __mem_pci(a) (a)
-+
-+#endif /* __MACH_IO_H__ */
-diff --git a/arch/arm/mach-efm32/include/mach/irqs.h b/arch/arm/mach-efm32/include/mach/irqs.h
-new file mode 100644
-index 0000000..e33ed12
---- /dev/null
-+++ b/arch/arm/mach-efm32/include/mach/irqs.h
-@@ -0,0 +1,6 @@
-+#ifndef __MACH_IRQS_H__
-+#define __MACH_IRQS_H__
-+
-+#define NR_IRQS 82
-+
-+#endif /* __MACH_IRQS_H__ */
-diff --git a/arch/arm/mach-efm32/include/mach/system.h b/arch/arm/mach-efm32/include/mach/system.h
-new file mode 100644
-index 0000000..619222c
---- /dev/null
-+++ b/arch/arm/mach-efm32/include/mach/system.h
-@@ -0,0 +1,18 @@
-+#ifndef __MACH_SYSTEM_H__
-+#define __MACH_SYSTEM_H__
-+
-+#include <asm/io.h>
-+
-+static inline void arch_idle(void)
-+{
-+ cpu_do_idle();
-+}
-+
-+static inline void arch_reset(char mode, const char *cmd)
-+{
-+ /* XXX: move this to (say) cpuv7m_reset */
-+ dsb();
-+ __raw_writel(0x05fa0004, (void __iomem *)0xe000ed0c);
-+ dsb();
-+}
-+#endif /* __MACH_SYSTEM_H__ */
-diff --git a/arch/arm/mach-efm32/include/mach/timex.h b/arch/arm/mach-efm32/include/mach/timex.h
-new file mode 100644
-index 0000000..b408dce
---- /dev/null
-+++ b/arch/arm/mach-efm32/include/mach/timex.h
-@@ -0,0 +1,7 @@
-+#ifndef __MACH_TIMEX_H__
-+#define __MACH_TIMEX_H__
-+
-+/* just a bogus value */
-+#define CLOCK_TICK_RATE 12345678
-+
-+#endif /* __MACH_TIMEX_H__ */
-diff --git a/arch/arm/mach-efm32/time.c b/arch/arm/mach-efm32/time.c
-new file mode 100644
-index 0000000..1181bf2
---- /dev/null
-+++ b/arch/arm/mach-efm32/time.c
-@@ -0,0 +1,289 @@
-+#define DEBUG
-+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-+
-+#include <linux/kernel.h>
-+#include <linux/clocksource.h>
-+#include <linux/clockchips.h>
-+#include <linux/irq.h>
-+#include <linux/interrupt.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+#include <linux/clk.h>
-+
-+#include <asm/mach/time.h>
-+
-+#include "common.h"
-+
-+#define BASEADDR_TIMER(n) IOMEM(0x40010000 + (n) * 0x400)
-+
-+#define TIMERn_CTRL 0x00
-+#define TIMERn_CTRL_PRESC(val) (((val) & 0xf) << 24)
-+#define TIMERn_CTRL_PRESC_1024 TIMERn_CTRL_PRESC(10)
-+#define TIMERn_CTRL_CLKSEL(val) (((val) & 0x3) << 16)
-+#define TIMERn_CTRL_CLKSEL_PRESCHFPERCLK TIMERn_CTRL_CLKSEL(0)
-+#define TIMERn_CTRL_OSMEN 0x00000010
-+#define TIMERn_CTRL_MODE(val) (((val) & 0x3) << 0)
-+#define TIMERn_CTRL_MODE_UP TIMERn_CTRL_MODE(0)
-+#define TIMERn_CTRL_MODE_DOWN TIMERn_CTRL_MODE(1)
-+
-+#define TIMERn_CMD 0x04
-+#define TIMERn_CMD_START 0x1
-+#define TIMERn_CMD_STOP 0x2
-+
-+#define TIMERn_IEN 0x0c
-+#define TIMERn_IF 0x10
-+#define TIMERn_IFS 0x14
-+#define TIMERn_IFC 0x18
-+#define TIMERn_IRQ_UF 0x2
-+#define TIMERn_IRQ_OF 0x1
-+
-+#define TIMERn_TOP 0x1c
-+#define TIMERn_CNT 0x24
-+
-+#define TIMER_CLOCKSOURCE 0
-+#define TIMER_CLOCKEVENT 1
-+
-+struct efm32_clock_event_ddata {
-+ struct clock_event_device evtdev;
-+ void __iomem *base;
-+};
-+
-+static void efm32_clock_event_set_mode(enum clock_event_mode mode,
-+ struct clock_event_device *evtdev)
-+{
-+ struct efm32_clock_event_ddata *ddata =
-+ container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
-+
-+ switch (mode) {
-+ case CLOCK_EVT_MODE_PERIODIC:
-+ writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
-+ writel_relaxed(137 /* XXX: magic constant */, ddata->base + TIMERn_TOP);
-+ writel_relaxed(TIMERn_CTRL_PRESC_1024 |
-+ TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
-+ TIMERn_CTRL_MODE_DOWN,
-+ ddata->base + TIMERn_CTRL);
-+ writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD);
-+ break;
-+
-+ case CLOCK_EVT_MODE_ONESHOT:
-+ writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
-+ writel_relaxed(TIMERn_CTRL_PRESC_1024 |
-+ TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
-+ TIMERn_CTRL_OSMEN |
-+ TIMERn_CTRL_MODE_DOWN,
-+ ddata->base + TIMERn_CTRL);
-+ break;
-+
-+ case CLOCK_EVT_MODE_UNUSED:
-+ case CLOCK_EVT_MODE_SHUTDOWN:
-+ writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
-+ break;
-+
-+ case CLOCK_EVT_MODE_RESUME:
-+ break;
-+ }
-+}
-+
-+static int efm32_clock_event_set_next_event(unsigned long evt,
-+ struct clock_event_device *evtdev)
-+{
-+ struct efm32_clock_event_ddata *ddata =
-+ container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
-+
-+ writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
-+ writel_relaxed(evt, ddata->base + TIMERn_CNT);
-+ writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD);
-+
-+ return 0;
-+}
-+
-+static irqreturn_t efm32_clock_event_handler(int irq, void *dev_id)
-+{
-+ struct efm32_clock_event_ddata *ddata = dev_id;
-+
-+ writel_relaxed(TIMERn_IRQ_UF, ddata->base + TIMERn_IFC);
-+
-+ ddata->evtdev.event_handler(&ddata->evtdev);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static struct efm32_clock_event_ddata clock_event_ddata = {
-+ .evtdev = {
-+ .name = "efm32 clockevent",
-+ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_MODE_PERIODIC,
-+ .set_mode = efm32_clock_event_set_mode,
-+ .set_next_event = efm32_clock_event_set_next_event,
-+ .rating = 200,
-+ },
-+};
-+
-+static struct irqaction efm32_clock_event_irq = {
-+ .name = "efm32 clockevent",
-+ .flags = IRQF_TIMER,
-+ .handler = efm32_clock_event_handler,
-+ .dev_id = &clock_event_ddata,
-+};
-+
-+/*
-+ * XXX: use clk_ API to get frequency and enabling of the clocks used.
-+ * Here the reset defaults are used:
-+ * - freq_{HFPERCLK} = freq_{HFCLK}
-+ * (CMU_HFPERCLKDIV_HFPERCLKDIV = 0x0)
-+ * - freq_{HFCLK} = freq_{HFRCO}
-+ * (CMU_CTRL_HFCLKDIV = 0x0, CMU_STATUS_HFRCOSEL = 0x1)
-+ * - freq_{HFRCO} = 14MHz
-+ * (CMU_HFRCOCTRL_BAND = 0x3)
-+ *
-+ * So the HFPERCLK runs at 14MHz. The timer has an additional prescaler
-+ * programmed to /1024. This make the timer run at
-+ *
-+ * 14 MHz / 1024 = 13671.875 Hz
-+ *
-+ * When HFXO is used HFPERCLK runs at 48 MHz, so the timer runs at
-+ *
-+ * 48 MHz / 1024 = 46875 Hz
-+ *
-+ */
-+
-+static int efm32_timer_clocksource_init(struct device_node *np)
-+{
-+ struct clk *clk;
-+ void __iomem *base;
-+ unsigned long rate;
-+ int ret;
-+
-+ clk = of_clk_get(np, 0);
-+ if (IS_ERR(clk)) {
-+ pr_err("failed to get clock for clocksource\n");
-+ ret = PTR_ERR(clk);
-+ goto err_clk_get;
-+ }
-+
-+ ret = clk_prepare_enable(clk);
-+ if (ret) {
-+ pr_err("failed to enable timer clock for clocksource\n");
-+ goto err_clk_enable;
-+ }
-+ rate = clk_get_rate(clk);
-+
-+ base = of_iomap(np, 0);
-+ if (!base) {
-+ pr_err("failed to map registers for clocksource\n");
-+ goto err_iomap;
-+ }
-+
-+ writel_relaxed(TIMERn_CTRL_PRESC_1024 |
-+ TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
-+ TIMERn_CTRL_MODE_UP, base + TIMERn_CTRL);
-+ writel_relaxed(TIMERn_CMD_START, base + TIMERn_CMD);
-+
-+ return clocksource_mmio_init(base + TIMERn_CNT,
-+ "efm32 timer", rate / 1024, 200, 16,
-+ clocksource_mmio_readl_up);
-+
-+ iounmap(base);
-+err_iomap:
-+
-+ clk_disable_unprepare(clk);
-+err_clk_enable:
-+
-+ clk_put(clk);
-+err_clk_get:
-+
-+ return ret;
-+}
-+
-+int __init efm32_clockevent_init(struct device_node *np)
-+{
-+ struct clk *clk;
-+ void __iomem *base;
-+ unsigned long rate;
-+ int irq;
-+ int ret;
-+
-+ clk = of_clk_get(np, 0);
-+ if (IS_ERR(clk)) {
-+ pr_err("failed to get clock for clocksource\n");
-+ ret = PTR_ERR(clk);
-+ goto err_clk_get;
-+ }
-+
-+ ret = clk_prepare_enable(clk);
-+ if (ret) {
-+ pr_err("failed to enable timer clock for clocksource\n");
-+ goto err_clk_enable;
-+ }
-+ rate = clk_get_rate(clk);
-+
-+ base = of_iomap(np, 0);
-+ if (!base) {
-+ pr_err("failed to map registers for clocksource\n");
-+ goto err_iomap;
-+ }
-+
-+ irq = irq_of_parse_and_map(np, 0);
-+ if (!irq) {
-+ pr_err("failed to get irq\n");
-+ goto err_get_irq;
-+ }
-+
-+ writel_relaxed(TIMERn_IRQ_UF, base + TIMERn_IEN);
-+
-+ clock_event_ddata.base = base;
-+
-+ setup_irq(irq, &efm32_clock_event_irq);
-+
-+ /* XXX: tune min_delta */
-+ clockevents_config_and_register(&clock_event_ddata.evtdev,
-+ rate / 1024, 0xf, 0xffff);
-+
-+ return 0;
-+
-+err_get_irq:
-+
-+ iounmap(base);
-+err_iomap:
-+
-+ clk_disable_unprepare(clk);
-+err_clk_enable:
-+
-+ clk_put(clk);
-+err_clk_get:
-+
-+ return ret;
-+}
-+
-+void __init efm32_timer_init(void)
-+{
-+ struct device_node *np;
-+
-+ efm32_clk_init();
-+
-+ /*
-+ * enable CMU_HFPERCLKEN0_TIMERn for clocksource via bit-band;
-+ * XXX: drop this when clock framework is not a stub anymore.
-+ */
-+ __raw_writel(1, IOMEM(0x43900894 + 4 * TIMER_CLOCKSOURCE));
-+ /* enable CMU_HFPERCLKEN0_TIMERn for clockevent via bit-band */
-+ __raw_writel(1, IOMEM(0x43900894 + 4 * TIMER_CLOCKEVENT));
-+
-+ np = of_find_compatible_node(NULL, NULL, "efm32,timer");
-+ if (!np) {
-+ pr_err("failed to find timer node for clocksource\n");
-+ return;
-+ }
-+
-+ efm32_timer_clocksource_init(np);
-+
-+ np = of_find_compatible_node(np, NULL, "efm32,timer");
-+ if (!np) {
-+ pr_err("failed to find timer node for clock events\n");
-+ return;
-+ }
-+
-+ efm32_clockevent_init(np);
-+
-+ of_node_put(np);
-+}