summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Kleine-König <uwe@kleine-koenig.org>2013-02-13 09:43:35 +0100
committerUwe Kleine-König <uwe@kleine-koenig.org>2013-02-13 09:43:35 +0100
commitefb50d0291e1a12975ad60f868dc04b0fe095297 (patch)
tree50785d06650863d79de4ca30b7446a0dda97af97
parentb01df9c847571abd1e79c5db81b0109eb6bdeb3b (diff)
downloadOSELAS.BSP-EnergyMicro-Gecko-efb50d0291e1a12975ad60f868dc04b0fe095297.tar.gz
OSELAS.BSP-EnergyMicro-Gecko-efb50d0291e1a12975ad60f868dc04b0fe095297.tar.xz
platform-energymicro-efm32gg-dk3750: update kernel
- implement gpio driver - correct spelling of "Energy Micro" - minor cleanups
-rw-r--r--kernelconfig-3.8-rc556
-rw-r--r--patches/linux-3.8-rc5/0009-Cortex-M3-Add-base-support-for-Cortex-M3.patch12
-rw-r--r--patches/linux-3.8-rc5/0015-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch27
-rw-r--r--patches/linux-3.8-rc5/0016-ARM-efm32-add-support-for-non-dt-builds-and-add-more.patch2
-rw-r--r--patches/linux-3.8-rc5/0017-gpio-new-driver-for-Energy-Micro-s-GPIO-component.patch386
-rw-r--r--patches/linux-3.8-rc5/0018-efm-board-controller-driver.patch (renamed from patches/linux-3.8-rc5/0017-efm-board-controller-driver.patch)74
-rw-r--r--patches/linux-3.8-rc5/0019-ARM-v7m-add-trivial-suspend-support.patch (renamed from patches/linux-3.8-rc5/0018-ARM-v7m-add-trivial-suspend-support.patch)4
-rw-r--r--patches/linux-3.8-rc5/0020-ARM-efm32-add-trivial-suspend-support.patch (renamed from patches/linux-3.8-rc5/0019-ARM-efm32-add-trivial-suspend-support.patch)28
-rw-r--r--patches/linux-3.8-rc5/0021-HACK-ARM-allow-a-bootloader-to-be-embedded-and-do-it.patch (renamed from patches/linux-3.8-rc5/0020-HACK-ARM-allow-a-bootloader-to-be-embedded-and-do-it.patch)0
-rw-r--r--patches/linux-3.8-rc5/0022-HACK-don-t-reserve-memory-for-device-tree-if-it-s-be.patch (renamed from patches/linux-3.8-rc5/0021-HACK-don-t-reserve-memory-for-device-tree-if-it-s-be.patch)0
-rw-r--r--patches/linux-3.8-rc5/0023-HACK-make-stack-dumps-provoked-by-BUG-a-bit-more-hel.patch (renamed from patches/linux-3.8-rc5/0022-HACK-make-stack-dumps-provoked-by-BUG-a-bit-more-hel.patch)0
-rw-r--r--patches/linux-3.8-rc5/0024-HACK-ARM-increase-TASK_SIZE-for-MMU.patch (renamed from patches/linux-3.8-rc5/0023-HACK-ARM-increase-TASK_SIZE-for-MMU.patch)0
-rw-r--r--patches/linux-3.8-rc5/0025-HACK-work-around-for-big-images.patch (renamed from patches/linux-3.8-rc5/0024-HACK-work-around-for-big-images.patch)0
-rw-r--r--patches/linux-3.8-rc5/series19
14 files changed, 549 insertions, 59 deletions
diff --git a/kernelconfig-3.8-rc5 b/kernelconfig-3.8-rc5
index 4ff9aa5..47eddcd 100644
--- a/kernelconfig-3.8-rc5
+++ b/kernelconfig-3.8-rc5
@@ -4,6 +4,7 @@
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
CONFIG_NO_IOPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -552,6 +553,7 @@ CONFIG_EEPROM_93CX6=y
#
# Texas Instruments shared transport line discipline
#
+# CONFIG_TI_ST is not set
#
# Altera FPGA firmware download module
@@ -666,6 +668,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
# CONFIG_SERIAL_XILINX_PS_UART is not set
CONFIG_SERIAL_EFM32_UART=y
CONFIG_SERIAL_EFM32_UART_CONSOLE=y
@@ -688,6 +691,8 @@ CONFIG_SPI_MASTER=y
# CONFIG_SPI_ALTERA is not set
CONFIG_SPI_BITBANG=y
CONFIG_SPI_EFM32=y
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_OC_TINY is not set
# CONFIG_SPI_PXA2XX_PCI is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_DESIGNWARE is not set
@@ -718,6 +723,47 @@ CONFIG_SPI_EFM32=y
#
# CONFIG_PTP_1588_CLOCK_PCH is not set
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+CONFIG_GPIO_EFM32=y
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_TS5500 is not set
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_POWER_AVS is not set
@@ -733,6 +779,7 @@ CONFIG_HWMON=y
CONFIG_SENSORS_EFM32_ADC=y
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_LM70 is not set
# CONFIG_SENSORS_MAX1111 is not set
@@ -740,6 +787,7 @@ CONFIG_SENSORS_EFM32_ADC=y
# CONFIG_SENSORS_NTC_THERMISTOR is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SHT15 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_SCH56XX_COMMON is not set
@@ -767,8 +815,11 @@ CONFIG_BCMA_POSSIBLE=y
#
CONFIG_MFD_CORE=y
# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_HTC_EGPIO is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TPS65912_SPI is not set
# CONFIG_MFD_STMPE is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_T7L66XB is not set
@@ -991,6 +1042,11 @@ CONFIG_HAVE_ARCH_KGDB=y
CONFIG_ARM_UNWIND=y
# CONFIG_DEBUG_USER is not set
# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_EFM32_USART1 is not set
+# CONFIG_DEBUG_EFM32_UART1 is not set
+# CONFIG_DEBUG_LL_UART_NONE is not set
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_DEBUG_SEMIHOSTING is not set
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
#
diff --git a/patches/linux-3.8-rc5/0009-Cortex-M3-Add-base-support-for-Cortex-M3.patch b/patches/linux-3.8-rc5/0009-Cortex-M3-Add-base-support-for-Cortex-M3.patch
index edd02e3..4af73cc 100644
--- a/patches/linux-3.8-rc5/0009-Cortex-M3-Add-base-support-for-Cortex-M3.patch
+++ b/patches/linux-3.8-rc5/0009-Cortex-M3-Add-base-support-for-Cortex-M3.patch
@@ -27,6 +27,7 @@ id:1358413196-5609-3-git-send-email-u.kleine-koenig@pengutronix.de:
- rebase
- use more named constants
- add comment about setmode being empty
+ - add more (yet unused) v7m register defines
---
arch/arm/include/asm/assembler.h | 17 +++-
arch/arm/include/asm/cputype.h | 12 ++-
@@ -37,7 +38,7 @@ id:1358413196-5609-3-git-send-email-u.kleine-koenig@pengutronix.de:
arch/arm/include/asm/processor.h | 7 ++
arch/arm/include/asm/ptrace.h | 8 ++
arch/arm/include/asm/system_info.h | 1 +
- arch/arm/include/asm/v7m.h | 11 +++
+ arch/arm/include/asm/v7m.h | 14 ++++
arch/arm/include/uapi/asm/ptrace.h | 36 ++++++--
arch/arm/kernel/asm-offsets.c | 3 +
arch/arm/kernel/head-nommu.S | 10 ++-
@@ -45,7 +46,7 @@ id:1358413196-5609-3-git-send-email-u.kleine-koenig@pengutronix.de:
arch/arm/kernel/traps.c | 2 +
arch/arm/mm/nommu.c | 2 +
arch/arm/mm/proc-v7m.S | 162 ++++++++++++++++++++++++++++++++++++
- 17 files changed, 331 insertions(+), 21 deletions(-)
+ 17 files changed, 334 insertions(+), 21 deletions(-)
create mode 100644 arch/arm/include/asm/v7m.h
create mode 100644 arch/arm/mm/proc-v7m.S
@@ -322,16 +323,19 @@ index dfd386d..720ea03 100644
diff --git a/arch/arm/include/asm/v7m.h b/arch/arm/include/asm/v7m.h
new file mode 100644
-index 0000000..350c18f
+index 0000000..94b77ca
--- /dev/null
+++ b/arch/arm/include/asm/v7m.h
-@@ -0,0 +1,11 @@
+@@ -0,0 +1,14 @@
+/*
+ * Common defines for v7m cpus
+ */
+#define V7M_SCS_CPUID IOMEM(0xe000ed00)
+#define V7M_SCS_VTOR IOMEM(0xe000ed08)
+
++#define V7M_SCS_SCR IOMEM(0xe000ed10)
++#define V7M_SCS_SCR_SLEEPDEEP (1 << 2)
++
+#define V7M_SCS_CCR IOMEM(0xe000ed14)
+#define V7M_SCS_CCR_STKALIGN (1 << 9)
+
diff --git a/patches/linux-3.8-rc5/0015-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch b/patches/linux-3.8-rc5/0015-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch
index 7cbce6e..15a4318 100644
--- a/patches/linux-3.8-rc5/0015-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch
+++ b/patches/linux-3.8-rc5/0015-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch
@@ -10,7 +10,7 @@ Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
arch/arm/Kconfig | 13 +-
arch/arm/Kconfig.debug | 16 +++
arch/arm/Makefile | 1 +
- arch/arm/boot/dts/efm32gg-dk3750.dts | 76 +++++++++++
+ arch/arm/boot/dts/efm32gg-dk3750.dts | 87 ++++++++++++
arch/arm/mach-efm32/Makefile | 3 +
arch/arm/mach-efm32/Makefile.boot | 1 +
arch/arm/mach-efm32/clk.c | 38 ++++++
@@ -24,7 +24,7 @@ Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
arch/arm/mach-efm32/include/mach/system.h | 18 +++
arch/arm/mach-efm32/include/mach/timex.h | 7 +
arch/arm/mach-efm32/time.c | 170 ++++++++++++++++++++++++
- 17 files changed, 469 insertions(+), 1 deletion(-)
+ 17 files changed, 480 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
@@ -41,7 +41,7 @@ Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
create mode 100644 arch/arm/mach-efm32/time.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index 9d09a41..029f074 100644
+index 9d09a41..cb2a9f7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -418,6 +418,17 @@ config ARCH_EBSA110
@@ -49,7 +49,7 @@ index 9d09a41..029f074 100644
parallel port.
+config ARCH_EFM32
-+ bool "EnergyMicro Cortex M3 Platform"
++ bool "Energy Micro Cortex M3 Platform"
+ depends on !MMU
+ select ARM_NVIC
+ select CLKSRC_MMIO
@@ -112,10 +112,10 @@ index 69a5955..374e25a 100644
machine-$(CONFIG_ARCH_H720X) += h720x
diff --git a/arch/arm/boot/dts/efm32gg-dk3750.dts b/arch/arm/boot/dts/efm32gg-dk3750.dts
new file mode 100644
-index 0000000..22e058f
+index 0000000..19fcc80
--- /dev/null
+++ b/arch/arm/boot/dts/efm32gg-dk3750.dts
-@@ -0,0 +1,76 @@
+@@ -0,0 +1,87 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
@@ -156,6 +156,17 @@ index 0000000..22e058f
+ status = "ok";
+ };
+
++ gpio: gpio@0x40006000 {
++ compatible = "efm32,gpio";
++ reg = <0x40006000 0x1000>;
++ interrupts = <1 11>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ status = "ok";
++ };
++
+ spi@0x4000c400 { /* USART1 */
+ #address-cells = <1>;
+ #size-cells = <0>;
@@ -185,10 +196,10 @@ index 0000000..22e058f
+ boardfpga: boardfpga@0x80000000 {
+ compatible = "efm32board";
+ reg = <0x80000000 0x400>;
-+ /* this is a lie, gpio_even = 1 */
-+ interrupts = <1>;
++ irq-gpios = <&gpio 64 1>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
++ status = "ok";
+ };
+ };
+};
diff --git a/patches/linux-3.8-rc5/0016-ARM-efm32-add-support-for-non-dt-builds-and-add-more.patch b/patches/linux-3.8-rc5/0016-ARM-efm32-add-support-for-non-dt-builds-and-add-more.patch
index a947a64..98ea864 100644
--- a/patches/linux-3.8-rc5/0016-ARM-efm32-add-support-for-non-dt-builds-and-add-more.patch
+++ b/patches/linux-3.8-rc5/0016-ARM-efm32-add-support-for-non-dt-builds-and-add-more.patch
@@ -40,7 +40,7 @@ Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
create mode 100644 arch/arm/mach-efm32/machines/efm32gg_dk3750.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index 029f074..46a8762 100644
+index cb2a9f7..3e764dc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1041,6 +1041,8 @@ source "arch/arm/mach-davinci/Kconfig"
diff --git a/patches/linux-3.8-rc5/0017-gpio-new-driver-for-Energy-Micro-s-GPIO-component.patch b/patches/linux-3.8-rc5/0017-gpio-new-driver-for-Energy-Micro-s-GPIO-component.patch
new file mode 100644
index 0000000..a473a91
--- /dev/null
+++ b/patches/linux-3.8-rc5/0017-gpio-new-driver-for-Energy-Micro-s-GPIO-component.patch
@@ -0,0 +1,386 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Tue, 12 Feb 2013 23:31:27 +0100
+Subject: [PATCH] gpio: new driver for Energy Micro's GPIO component
+
+---
+ arch/arm/Kconfig | 1 +
+ drivers/gpio/Kconfig | 4 +
+ drivers/gpio/Makefile | 1 +
+ drivers/gpio/gpio-efm32.c | 329 +++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 335 insertions(+)
+ create mode 100644 drivers/gpio/gpio-efm32.c
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 3e764dc..7833c0a 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -421,6 +421,7 @@ config ARCH_EBSA110
+ config ARCH_EFM32
+ bool "Energy Micro Cortex M3 Platform"
+ depends on !MMU
++ select ARCH_REQUIRE_GPIOLIB
+ select ARM_NVIC
+ select CLKSRC_MMIO
+ select CPU_V7M
+diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
+index 682de75..4712e1c 100644
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -122,6 +122,10 @@ config GPIO_IT8761E
+ help
+ Say yes here to support GPIO functionality of IT8761E super I/O chip.
+
++config GPIO_EFM32
++ tristate "Energy Micro EFM32 GPIO support"
++ depends on ARCH_EFM32
++
+ config GPIO_EM
+ tristate "Emma Mobile GPIO"
+ depends on ARM
+diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
+index c5aebd0..fc53fd5 100644
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -22,6 +22,7 @@ obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
+ obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
+ obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o
+ obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o
++obj-$(CONFIG_GPIO_EFM32) += gpio-efm32.o
+ obj-$(CONFIG_GPIO_EM) += gpio-em.o
+ obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
+ obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
+diff --git a/drivers/gpio/gpio-efm32.c b/drivers/gpio/gpio-efm32.c
+new file mode 100644
+index 0000000..648a154
+--- /dev/null
++++ b/drivers/gpio/gpio-efm32.c
+@@ -0,0 +1,329 @@
++#include <linux/platform_device.h>
++#include <linux/device.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_address.h>
++#include <linux/irqdomain.h>
++#include <linux/interrupt.h>
++#include <linux/gfp.h>
++#include <linux/module.h>
++#include <linux/irq.h>
++
++#include <asm/gpio.h>
++#include <asm/io.h>
++
++#define DRIVER_NAME "efm32-gpio"
++
++#define GPIO_Px_MODEL(p) (0x024 * (p) + 0x004)
++#define GPIO_Px_MODEH(p) (0x024 * (p) + 0x008)
++#define GPIO_Px_DOUT(p) (0x024 * (p) + 0x00c)
++#define GPIO_Px_DOUTSET(p) (0x024 * (p) + 0x010)
++#define GPIO_Px_DOUTCLR(p) (0x024 * (p) + 0x014)
++#define GPIO_Px_DIN(p) (0x024 * (p) + 0x01c)
++#define GPIO_EXTIPSELL 0x100
++#define GPIO_EXTIPSELH 0x104
++#define GPIO_IEN 0x110
++#define GPIO_IF 0x114
++#define GPIO_IFC 0x11c
++
++struct efm32_gpio_ddata {
++ void __iomem *base;
++ spinlock_t lock;
++ unsigned int irq_even, irq_odd;
++ struct irq_domain *irq_domain;
++ struct gpio_chip chip;
++ unsigned assigned_irqpins;
++};
++
++#define to_ddata(chip) container_of(chip, struct efm32_gpio_ddata, chip)
++
++static unsigned efm32_gpio_get_mode(struct efm32_gpio_ddata *ddata,
++ unsigned pin, unsigned port)
++{
++ return (readl(ddata->base + (pin < 8 ? GPIO_Px_MODEL(port) : GPIO_Px_MODEH(port))) >> (4 * (pin & 7))) & 0xf;
++
++}
++static int efm32_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
++{
++ struct efm32_gpio_ddata *ddata = to_ddata(chip);
++ unsigned pin = offset % 16;
++ unsigned port = offset / 16;
++ unsigned mode = efm32_gpio_get_mode(ddata, pin, port);
++
++ /*
++ * XXX: don't reconfigure, needs to be resolved in combination with a
++ * pinmux driver
++ */
++ if (mode > 0 && mode < 4)
++ return 0;
++ else
++ return -EIO;
++}
++
++static int efm32_gpio_get(struct gpio_chip *chip, unsigned offset)
++{
++ struct efm32_gpio_ddata *ddata = to_ddata(chip);
++ unsigned pin = offset % 16;
++ unsigned port = offset / 16;
++
++ /* XXX use bitband to simplify? */
++ return readl(ddata->base + GPIO_Px_DIN(port)) & (1 << pin);
++}
++
++static int efm32_gpio_direction_output(struct gpio_chip *chip,
++ unsigned offset, int value)
++{
++ struct efm32_gpio_ddata *ddata = to_ddata(chip);
++ unsigned pin = offset % 16;
++ unsigned port = offset / 16;
++ unsigned mode = efm32_gpio_get_mode(ddata, pin, port);
++
++ /*
++ * XXX: don't reconfigure, needs to be resolved in combination with a
++ * pinmux driver
++ */
++ if (mode >= 4)
++ return 0;
++ else
++ return -EIO;
++}
++
++static void efm32_gpio_set(struct gpio_chip *chip,
++ unsigned offset, int value)
++{
++ struct efm32_gpio_ddata *ddata = to_ddata(chip);
++ unsigned pin = offset % 16;
++ unsigned port = offset / 16;
++
++ writel(1 << pin, ddata->base +
++ (value ? GPIO_Px_DOUTSET(port) : GPIO_Px_DOUTCLR(port)));
++}
++
++static int efm32_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
++{
++ struct efm32_gpio_ddata *ddata = to_ddata(chip);
++ unsigned pin = offset % 16;
++ unsigned port = offset / 16;
++ unsigned extipsel_offset = pin < 8 ? GPIO_EXTIPSELL : GPIO_EXTIPSELH;
++ unsigned extipsel;
++ unsigned extipsel_shift = (pin % 8) * 4;
++
++ spin_lock(&ddata->lock);
++
++ extipsel = readl(ddata->base + extipsel_offset);
++
++ if (ddata->assigned_irqpins & (1 << pin)) {
++ if (((extipsel >> extipsel_shift) & 0x7) != port) {
++ spin_unlock(&ddata->lock);
++ return -EBUSY;
++ }
++ }
++
++ extipsel &= ~(0x7 << extipsel_shift);
++ extipsel |= port << extipsel_shift;
++ ddata->assigned_irqpins |= 1 << pin;
++ writel(extipsel, ddata->base + extipsel_offset);
++
++ spin_unlock(&ddata->lock);
++
++ return irq_create_mapping(ddata->irq_domain, offset % 16);
++}
++
++static irqreturn_t efm32_gpio_handler(struct efm32_gpio_ddata *ddata, unsigned mask)
++{
++ unsigned flag, init_flag;
++ irqreturn_t ret = IRQ_NONE;
++
++ init_flag = flag = readl(ddata->base + GPIO_IF) & mask;
++
++ while (flag) {
++ int line = __fls(flag);
++
++ writel(1 << line, ddata->base + GPIO_IFC);
++ if (generic_handle_irq(irq_create_mapping(ddata->irq_domain, line)))
++ ret = IRQ_HANDLED;
++
++ flag &= ~(1 << line);
++ }
++ return ret;
++}
++
++static irqreturn_t efm32_gpio_handler_even(int irq, void *data)
++{
++ struct efm32_gpio_ddata *ddata = data;
++ return efm32_gpio_handler(ddata, 0x55555555U);
++}
++
++static irqreturn_t efm32_gpio_handler_odd(int irq, void *data)
++{
++ struct efm32_gpio_ddata *ddata = data;
++ return efm32_gpio_handler(ddata, 0xaaaaaaaaU);
++}
++
++static void efm32_gpio_irq_ack(struct irq_data *data)
++{
++ struct efm32_gpio_ddata *ddata = irq_get_chip_data(data->irq);
++ writel(1 << data->hwirq, ddata->base + GPIO_IFC);
++}
++
++static void efm32_gpio_irq_mask(struct irq_data *data)
++{
++ struct efm32_gpio_ddata *ddata = irq_get_chip_data(data->irq);
++ unsigned ien;
++
++ spin_lock(&ddata->lock);
++ ien = readl(ddata->base + GPIO_IEN);
++ ien &= ~(1 << data->hwirq);
++ writel(ien, ddata->base + GPIO_IEN);
++ spin_unlock(&ddata->lock);
++}
++
++static void efm32_gpio_irq_unmask(struct irq_data *data)
++{
++ struct efm32_gpio_ddata *ddata = irq_get_chip_data(data->irq);
++ unsigned ien;
++
++ spin_lock(&ddata->lock);
++ ien = readl(ddata->base + GPIO_IEN);
++ ien |= 1 << data->hwirq;
++ writel(ien, ddata->base + GPIO_IEN);
++ spin_unlock(&ddata->lock);
++}
++
++static struct irq_chip efm32_gpio_irqchip = {
++ .irq_ack = efm32_gpio_irq_ack,
++ .irq_mask = efm32_gpio_irq_mask,
++ .irq_unmask = efm32_gpio_irq_unmask,
++};
++
++static int efm32_gpio_irq_map(struct irq_domain *d, unsigned int virq,
++ irq_hw_number_t hw)
++{
++ struct efm32_gpio_ddata *ddata = d->host_data;
++
++ irq_set_chip_data(virq, ddata);
++ irq_set_chip_and_handler(virq, &efm32_gpio_irqchip, handle_edge_irq);
++
++ set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
++
++ return 0;
++}
++
++static const struct irq_domain_ops efm32_gpio_irq_domain_ops = {
++ .map = efm32_gpio_irq_map,
++};
++
++static int efm32_gpio_probe(struct platform_device *pdev)
++{
++ struct efm32_gpio_ddata *ddata;
++ struct resource *res;
++ int ret = -ENOMEM;
++ int irq_even, irq_odd;
++
++ ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
++ if (!ddata) {
++ dev_err(&pdev->dev, "cannot allocate driver data");
++ return -ENOMEM;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ dev_err(&pdev->dev, "can't get device resources\n");
++ return -ENOENT;
++ }
++
++ irq_even = platform_get_irq(pdev, 0);
++ irq_odd = platform_get_irq(pdev, 1);
++ if (irq_even <= 0 || irq_odd <= 0) {
++ dev_err(&pdev->dev, "can't get irq numbers (%d, %d)\n",
++ irq_even, irq_odd);
++ return -ENOENT;
++ }
++ ddata->irq_even = irq_even;
++ ddata->irq_odd = irq_odd;
++
++ ddata->base = devm_request_and_ioremap(&pdev->dev, res);
++ if (!ddata->base) {
++ dev_err(&pdev->dev,
++ "cannot request and ioremap register set\n");
++ return -EADDRNOTAVAIL;
++ }
++
++ spin_lock_init(&ddata->lock);
++
++ /* disable and clear irqs */
++ writel(0, ddata->base + GPIO_IEN);
++ writel(0xffff, ddata->base + GPIO_IFC);
++
++ ddata->irq_domain = irq_domain_add_linear(pdev->dev.of_node,
++ 16, &efm32_gpio_irq_domain_ops, ddata);
++ if (!ddata->irq_domain) {
++ dev_err(&pdev->dev, "failed to add irq_domain\n");
++ goto err_add_irq_domain;
++ }
++
++ ddata->chip.label = DRIVER_NAME;
++ ddata->chip.dev = &pdev->dev;
++ ddata->chip.owner = THIS_MODULE;
++
++ //ddata->chip.get_direction
++ ddata->chip.direction_input = efm32_gpio_direction_input;
++ ddata->chip.get = efm32_gpio_get;
++ ddata->chip.direction_output = efm32_gpio_direction_output;
++ ddata->chip.set = efm32_gpio_set;
++ ddata->chip.to_irq = efm32_gpio_to_irq;
++ ddata->chip.base = -1;
++ ddata->chip.ngpio = 96;
++ ddata->chip.can_sleep = 0;
++
++ ret = request_irq(ddata->irq_even, efm32_gpio_handler_even,
++ 0, DRIVER_NAME, ddata);
++ if (ret)
++ goto err_request_even_irq;
++
++ ret = request_irq(ddata->irq_odd, efm32_gpio_handler_odd,
++ 0, DRIVER_NAME, ddata);
++ if (ret)
++ goto err_request_odd_irq;
++
++ ret = gpiochip_add(&ddata->chip);
++ if (ret) {
++ free_irq(ddata->irq_odd, ddata);
++err_request_odd_irq:
++
++ free_irq(ddata->irq_even, ddata);
++err_request_even_irq:
++
++ irq_domain_remove(ddata->irq_domain);
++ }
++
++err_add_irq_domain:
++ return ret;
++}
++
++static const struct of_device_id efm32_gpio_dt_ids[] = {
++ {
++ .compatible = "efm32,gpio",
++ }, {
++ /* sentinel */
++ }
++};
++MODULE_DEVICE_TABLE(of, efm32_gpio_dt_ids);
++
++static struct platform_driver efm32_gpio_driver = {
++ .probe = efm32_gpio_probe,
++
++ .driver = {
++ .name = DRIVER_NAME,
++ .owner = THIS_MODULE,
++ .of_match_table = efm32_gpio_dt_ids,
++ },
++};
++
++static int __init efm32_gpio_init(void)
++{
++ return platform_driver_register(&efm32_gpio_driver);
++}
++postcore_initcall(efm32_gpio_init);
++
++MODULE_LICENSE("GPL v2");
diff --git a/patches/linux-3.8-rc5/0017-efm-board-controller-driver.patch b/patches/linux-3.8-rc5/0018-efm-board-controller-driver.patch
index b2b784d..ab4f929 100644
--- a/patches/linux-3.8-rc5/0017-efm-board-controller-driver.patch
+++ b/patches/linux-3.8-rc5/0018-efm-board-controller-driver.patch
@@ -3,10 +3,10 @@ Date: Thu, 7 Feb 2013 09:45:30 +0100
Subject: [PATCH] efm board controller driver
---
- drivers/mfd/Kconfig | 4 ++
+ drivers/mfd/Kconfig | 4 +
drivers/mfd/Makefile | 1 +
- drivers/mfd/efm32board.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 171 insertions(+)
+ drivers/mfd/efm32board.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 197 insertions(+)
create mode 100644 drivers/mfd/efm32board.c
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
@@ -35,14 +35,16 @@ index 8b977f8..cb0556f 100644
+obj-$(CONFIG_MFD_EFM32BOARD) += efm32board.o
diff --git a/drivers/mfd/efm32board.c b/drivers/mfd/efm32board.c
new file mode 100644
-index 0000000..1e1cf35
+index 0000000..fc87ac2
--- /dev/null
+++ b/drivers/mfd/efm32board.c
-@@ -0,0 +1,166 @@
+@@ -0,0 +1,192 @@
+#include <linux/platform_device.h>
+#include <linux/irq.h>
++#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/export.h>
++#include <linux/of_gpio.h>
+#include <asm/io.h>
+
+#define DRIVER_NAME "efm32board"
@@ -63,7 +65,7 @@ index 0000000..1e1cf35
+ struct efm32board_ddata *ddata = irq_get_chip_data(data->irq);
+ unsigned short val;
+
-+ /* XXX: lock */
++ /* XXX: locking */
+ val = readw(ddata->base + INTFLAG);
+ val &= ~(1 << data->hwirq);
+ writew(val, ddata->base + INTFLAG);
@@ -74,10 +76,12 @@ index 0000000..1e1cf35
+ struct efm32board_ddata *ddata = irq_get_chip_data(data->irq);
+ unsigned short val;
+
-+ /* XXX: lock */
-+ val = readw(ddata->base + INTEN);
-+ val &= ~(1 << data->hwirq);
-+ writew(val, ddata->base + INTEN);
++ if (data->hwirq != 2) {
++ /* XXX: locking */
++ val = readw(ddata->base + INTEN);
++ val &= ~(1 << data->hwirq);
++ writew(val, ddata->base + INTEN);
++ }
+}
+
+static void efm32board_irq_unmask(struct irq_data *data)
@@ -85,19 +89,17 @@ index 0000000..1e1cf35
+ struct efm32board_ddata *ddata = irq_get_chip_data(data->irq);
+ unsigned short val;
+
-+ /* XXX: lock */
++ /* XXX: locking */
+ val = readw(ddata->base + INTEN);
+ val |= 1 << data->hwirq;
+ writew(val, ddata->base + INTEN);
+}
+
-+static void efm32board_handler(unsigned int irq, struct irq_desc *desc)
++static irqreturn_t efm32board_handler(unsigned int irq, void *data)
+{
+ unsigned short val;
-+ struct efm32board_ddata *ddata = irq_get_handler_data(irq);
-+
-+ /* ack gpio irq. XXX: this should go into a gpio driver */
-+ writel(1, (void __iomem *)0x4000611c);
++ struct efm32board_ddata *ddata = data;
++ irqreturn_t ret = IRQ_NONE;
+
+ val = readw(ddata->base + INTFLAG);
+ /* ack BC irq */
@@ -106,9 +108,11 @@ index 0000000..1e1cf35
+ while (val) {
+ int line = __fls(val);
+
-+ generic_handle_irq(irq_create_mapping(ddata->domain, line));
++ if (!generic_handle_irq(irq_create_mapping(ddata->domain, line)))
++ ret = IRQ_HANDLED;
+ val &= ~(1 << line);
+ }
++ return ret;
+}
+
+int efm32board_irqdomain_map(struct irq_domain *d, unsigned int virq,
@@ -132,7 +136,7 @@ index 0000000..1e1cf35
+static int efm32board_probe(struct platform_device *pdev)
+{
+ struct resource *res;
-+ int irq;
++ int irq, gpio, ret;
+ struct efm32board_ddata *ddata;
+ unsigned short val;
+
@@ -148,10 +152,28 @@ index 0000000..1e1cf35
+ return -ENOENT;
+ }
+
-+ irq = platform_get_irq(pdev, 0);
++ gpio = of_get_named_gpio_flags(pdev->dev.of_node, "irq-gpios", 0, NULL);
++ if (gpio < 0) {
++ dev_err(&pdev->dev, "can't get irq gpio\n");
++ return gpio;
++ }
++
++ ret = gpio_request(gpio, DRIVER_NAME);
++ if (ret) {
++ dev_err(&pdev->dev, "cannot request irq gpio\n");
++ return ret;
++ }
++
++ ret = gpio_direction_input(gpio);
++ if (ret) {
++ dev_err(&pdev->dev, "cannot configure irq gpio as input\n");
++ return ret;
++ }
++
++ irq = gpio_to_irq(gpio);
+ if (irq <= 0) {
+ dev_err(&pdev->dev, "can't get irq number\n");
-+ return -ENOENT;
++ return irq < 0 ? irq : -ENOENT;
+ }
+ ddata->irq = irq;
+
@@ -179,16 +201,20 @@ index 0000000..1e1cf35
+ ddata->chip.irq_mask = efm32board_irq_mask;
+ ddata->chip.irq_unmask = efm32board_irq_unmask;
+
-+ irq_set_handler_data(irq, ddata);
-+ irq_set_chained_handler(irq, efm32board_handler);
++ ret = request_irq(irq, efm32board_handler, 0, DRIVER_NAME, ddata);
++ if (ret)
++ goto err_request_irq;
+
+ ddata->domain = irq_domain_add_simple(pdev->dev.of_node, 5, 0,
+ &efm32board_irqdomain_ops, ddata);
+ if (!ddata->domain) {
++ ret = -ENOMEM;
+ dev_err(&pdev->dev, "cannot create irq domain\n");
-+ return -ENOMEM;
++
++ free_irq(irq, ddata);
+ }
-+ return 0;
++err_request_irq:
++ return ret;
+}
+
+static const struct of_device_id efm32board_dt_ids[] = {
diff --git a/patches/linux-3.8-rc5/0018-ARM-v7m-add-trivial-suspend-support.patch b/patches/linux-3.8-rc5/0019-ARM-v7m-add-trivial-suspend-support.patch
index deb16a9..fb1236b 100644
--- a/patches/linux-3.8-rc5/0018-ARM-v7m-add-trivial-suspend-support.patch
+++ b/patches/linux-3.8-rc5/0019-ARM-v7m-add-trivial-suspend-support.patch
@@ -13,10 +13,10 @@ Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index 46a8762..09eb7f5 100644
+index 7833c0a..2ef2bf1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
-@@ -2315,7 +2315,7 @@ source "kernel/power/Kconfig"
+@@ -2316,7 +2316,7 @@ source "kernel/power/Kconfig"
config ARCH_SUSPEND_POSSIBLE
depends on !ARCH_S5PC100
depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \
diff --git a/patches/linux-3.8-rc5/0019-ARM-efm32-add-trivial-suspend-support.patch b/patches/linux-3.8-rc5/0020-ARM-efm32-add-trivial-suspend-support.patch
index 7f2ba23..82715f7 100644
--- a/patches/linux-3.8-rc5/0019-ARM-efm32-add-trivial-suspend-support.patch
+++ b/patches/linux-3.8-rc5/0020-ARM-efm32-add-trivial-suspend-support.patch
@@ -8,8 +8,8 @@ Content-Transfer-Encoding: 8bit
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
arch/arm/mach-efm32/Makefile | 1 +
- arch/arm/mach-efm32/pm.c | 40 ++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 41 insertions(+)
+ arch/arm/mach-efm32/pm.c | 46 ++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 47 insertions(+)
create mode 100644 arch/arm/mach-efm32/pm.c
diff --git a/arch/arm/mach-efm32/Makefile b/arch/arm/mach-efm32/Makefile
@@ -25,30 +25,36 @@ index ba4d6ee..0f593e7 100644
obj-$(CONFIG_EFM32_NONDT) += machines/ devices/
diff --git a/arch/arm/mach-efm32/pm.c b/arch/arm/mach-efm32/pm.c
new file mode 100644
-index 0000000..de03941
+index 0000000..4c80906
--- /dev/null
+++ b/arch/arm/mach-efm32/pm.c
-@@ -0,0 +1,40 @@
+@@ -0,0 +1,46 @@
+#include <linux/init.h>
+#include <linux/suspend.h>
+
+#include <asm/io.h>
++#include <asm/v7m.h>
+
+#include "cmu.h"
+
-+static inline void v7m_write_scr(u32 val)
-+{
-+ writel(val, (u32 __iomem *)0xe000ed10);
-+}
-+
+static int efm32_suspend_enter(suspend_state_t state)
+{
+ u32 cmu_status = readl(CMU_STATUS);
+
-+ v7m_write_scr(0x4);
++ /*
++ * setting SLEEPDEEP makes the efm32 enter EM2 or EM3 (iff both
++ * LFACLK and LFBCLK are off).
++ */
++ writel(V7M_SCS_SCR_SLEEPDEEP, V7M_SCS_SCR);
++
+ cpu_do_idle();
-+ v7m_write_scr(0x0);
+
++ writel(0, V7M_SCS_SCR);
++
++ /*
++ * deep sleep disables the HF oscilator, reenable it if it was on
++ * before.
++ */
+ if (cmu_status & CMU_STATUS_HFXOSEL) {
+ writel(CMU_OSCENCMD_HFXOEN, CMU_OSCENCMD);
+ writel(CMU_CMD_HFCLKSEL_HFXO, CMU_CMD);
diff --git a/patches/linux-3.8-rc5/0020-HACK-ARM-allow-a-bootloader-to-be-embedded-and-do-it.patch b/patches/linux-3.8-rc5/0021-HACK-ARM-allow-a-bootloader-to-be-embedded-and-do-it.patch
index f2d0929..f2d0929 100644
--- a/patches/linux-3.8-rc5/0020-HACK-ARM-allow-a-bootloader-to-be-embedded-and-do-it.patch
+++ b/patches/linux-3.8-rc5/0021-HACK-ARM-allow-a-bootloader-to-be-embedded-and-do-it.patch
diff --git a/patches/linux-3.8-rc5/0021-HACK-don-t-reserve-memory-for-device-tree-if-it-s-be.patch b/patches/linux-3.8-rc5/0022-HACK-don-t-reserve-memory-for-device-tree-if-it-s-be.patch
index b7f5680..b7f5680 100644
--- a/patches/linux-3.8-rc5/0021-HACK-don-t-reserve-memory-for-device-tree-if-it-s-be.patch
+++ b/patches/linux-3.8-rc5/0022-HACK-don-t-reserve-memory-for-device-tree-if-it-s-be.patch
diff --git a/patches/linux-3.8-rc5/0022-HACK-make-stack-dumps-provoked-by-BUG-a-bit-more-hel.patch b/patches/linux-3.8-rc5/0023-HACK-make-stack-dumps-provoked-by-BUG-a-bit-more-hel.patch
index b99bcec..b99bcec 100644
--- a/patches/linux-3.8-rc5/0022-HACK-make-stack-dumps-provoked-by-BUG-a-bit-more-hel.patch
+++ b/patches/linux-3.8-rc5/0023-HACK-make-stack-dumps-provoked-by-BUG-a-bit-more-hel.patch
diff --git a/patches/linux-3.8-rc5/0023-HACK-ARM-increase-TASK_SIZE-for-MMU.patch b/patches/linux-3.8-rc5/0024-HACK-ARM-increase-TASK_SIZE-for-MMU.patch
index cdd8d29..cdd8d29 100644
--- a/patches/linux-3.8-rc5/0023-HACK-ARM-increase-TASK_SIZE-for-MMU.patch
+++ b/patches/linux-3.8-rc5/0024-HACK-ARM-increase-TASK_SIZE-for-MMU.patch
diff --git a/patches/linux-3.8-rc5/0024-HACK-work-around-for-big-images.patch b/patches/linux-3.8-rc5/0025-HACK-work-around-for-big-images.patch
index 06691a1..06691a1 100644
--- a/patches/linux-3.8-rc5/0024-HACK-work-around-for-big-images.patch
+++ b/patches/linux-3.8-rc5/0025-HACK-work-around-for-big-images.patch
diff --git a/patches/linux-3.8-rc5/series b/patches/linux-3.8-rc5/series
index ba6a57b..b8be078 100644
--- a/patches/linux-3.8-rc5/series
+++ b/patches/linux-3.8-rc5/series
@@ -16,12 +16,13 @@
0014-Cortex-M3-Allow-the-building-of-Cortex-M3-kernel-por.patch
0015-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch
0016-ARM-efm32-add-support-for-non-dt-builds-and-add-more.patch
-0017-efm-board-controller-driver.patch
-0018-ARM-v7m-add-trivial-suspend-support.patch
-0019-ARM-efm32-add-trivial-suspend-support.patch
-0020-HACK-ARM-allow-a-bootloader-to-be-embedded-and-do-it.patch
-0021-HACK-don-t-reserve-memory-for-device-tree-if-it-s-be.patch
-0022-HACK-make-stack-dumps-provoked-by-BUG-a-bit-more-hel.patch
-0023-HACK-ARM-increase-TASK_SIZE-for-MMU.patch
-0024-HACK-work-around-for-big-images.patch
-# 1659ab9769424059b871ff1ae1310d18 - git-ptx-patches magic
+0017-gpio-new-driver-for-Energy-Micro-s-GPIO-component.patch
+0018-efm-board-controller-driver.patch
+0019-ARM-v7m-add-trivial-suspend-support.patch
+0020-ARM-efm32-add-trivial-suspend-support.patch
+0021-HACK-ARM-allow-a-bootloader-to-be-embedded-and-do-it.patch
+0022-HACK-don-t-reserve-memory-for-device-tree-if-it-s-be.patch
+0023-HACK-make-stack-dumps-provoked-by-BUG-a-bit-more-hel.patch
+0024-HACK-ARM-increase-TASK_SIZE-for-MMU.patch
+0025-HACK-work-around-for-big-images.patch
+# 135b678da0c40f665a17effb4fc8dfd5 - git-ptx-patches magic