aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-12-05 13:27:17 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-12-05 13:27:17 -0800
commitc48dcb2fc9ea301e7ee0e67048d4195eb3897ec6 (patch)
treede75f5b27a76e9f0bca8fbf5a8a54aa325694df6
parent05c35b6543cd64cb71ecac7ce4231645b6cd40b2 (diff)
downloadltsi-kernel-c48dcb2fc9ea301e7ee0e67048d4195eb3897ec6.tar.gz
kzm9d board support added
-rw-r--r--patches.kzm9d/arm-mach-shmobile-fix-build-when-smp-is-enabled-and-emev2-is-not-enabled.patch60
-rw-r--r--patches.kzm9d/arm-mach-shmobile-kzm9d-add-defconfig.patch122
-rw-r--r--patches.kzm9d/clockevents-make-clockevents_config-a-global-symbol.patch63
-rw-r--r--patches.kzm9d/clocksource-em_sti-add-dt-support.patch56
-rw-r--r--patches.kzm9d/clocksource-em_sti-emma-mobile-sti-driver.patch468
-rw-r--r--patches.kzm9d/gpio-emma-mobile-gpio-driver-v2.patch499
-rw-r--r--patches.kzm9d/mach-shmobile-emma-mobile-ev2-dt-support-v3.patch194
-rw-r--r--patches.kzm9d/mach-shmobile-emma-mobile-ev2-gpio-support-v3.patch286
-rw-r--r--patches.kzm9d/mach-shmobile-emma-mobile-ev2-smp-support-v3.patch340
-rw-r--r--patches.kzm9d/mach-shmobile-emma-mobile-ev2-soc-base-support-v3.patch495
-rw-r--r--patches.kzm9d/mach-shmobile-kzm9d-board-ethernet-support-v3.patch93
-rw-r--r--patches.kzm9d/mach-shmobile-kzm9d-board-support-v3.patch92
-rw-r--r--patches.kzm9d/mach-shmobile-use-dt_machine-for-kzm9d-v3.patch103
-rw-r--r--patches.kzm9d/serial-8250_pci-clear-fifos-for-intel-me-serial-over-lan-device-on-bi.patch136
-rw-r--r--patches.kzm9d/serial-8250_pci-fix-suspend-resume-vs-init-exit-quirks.patch85
-rw-r--r--patches.kzm9d/serial8250-add-dl_read-dl_write-callbacks.patch206
-rw-r--r--patches.kzm9d/serial8250-clean-up-default-map-and-dl-code.patch140
-rw-r--r--patches.kzm9d/serial8250-em-add-dt-support.patch47
-rw-r--r--patches.kzm9d/serial8250-em-clk_get-is_err-error-handling-fix.patch44
-rw-r--r--patches.kzm9d/serial8250-em-emma-mobile-uart-driver-v2.patch256
-rw-r--r--patches.kzm9d/serial8250-introduce-serial8250_register_8250_port.patch176
-rw-r--r--patches.kzm9d/serial8250-use-dl_read-dl_write-on-alchemy.patch144
-rw-r--r--patches.kzm9d/serial8250-use-dl_read-dl_write-on-rm9k.patch145
-rw-r--r--patches.kzm9d/tegra-serial8250-add-handle_break-uart_port-op.patch330
-rw-r--r--series27
25 files changed, 4607 insertions, 0 deletions
diff --git a/patches.kzm9d/arm-mach-shmobile-fix-build-when-smp-is-enabled-and-emev2-is-not-enabled.patch b/patches.kzm9d/arm-mach-shmobile-fix-build-when-smp-is-enabled-and-emev2-is-not-enabled.patch
new file mode 100644
index 00000000000000..5c4105ed426e10
--- /dev/null
+++ b/patches.kzm9d/arm-mach-shmobile-fix-build-when-smp-is-enabled-and-emev2-is-not-enabled.patch
@@ -0,0 +1,60 @@
+From koba@kmckk.co.jp Wed Oct 3 04:30:37 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:18 +0900
+Subject: [PATCH 26/26] ARM: mach-shmobile: Fix build when SMP is enabled and EMEV2 is not enabled
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>, "Rafael J. Wysocki" <rjw@sisk.pl>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-27-git-send-email-koba@kmckk.co.jp>
+
+
+From: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+
+Build failed, when SMP is enabled and EMEV2 is not enabled.
+
+arch/arm/mach-shmobile/built-in.o: In function `shmobile_platform_cpu_kill':
+/home/iwamatsu/work/kernel/sh-2.6-devel/arch/arm/mach-shmobile/platsmp.c:62: undefined reference to `emev2_platform_cpu_kill'
+arch/arm/mach-shmobile/built-in.o: In function `shmobile_smp_get_core_count':
+/home/iwamatsu/work/kernel/sh-2.6-devel/arch/arm/mach-shmobile/platsmp.c:39: undefined reference to `emev2_get_core_count'
+arch/arm/mach-shmobile/built-in.o: In function `shmobile_smp_prepare_cpus':
+/home/iwamatsu/work/kernel/sh-2.6-devel/arch/arm/mach-shmobile/platsmp.c:53: undefined reference to `emev2_smp_prepare_cpus'
+arch/arm/mach-shmobile/built-in.o: In function `platform_secondary_init':
+/home/iwamatsu/work/kernel/sh-2.6-devel/arch/arm/mach-shmobile/platsmp.c:78: undefined reference to `emev2_secondary_init'
+arch/arm/mach-shmobile/built-in.o: In function `boot_secondary':
+/home/iwamatsu/work/kernel/sh-2.6-devel/arch/arm/mach-shmobile/platsmp.c:90: undefined reference to `emev2_boot_secondary
+
+This is the cause by when EMEV2 is disabled, that the check by OF of EMEV2 is
+performed in platsmp.c.
+This patch revise what the function about EMEV2 may not be used in this file,
+when EMEV2 is not enabled.
+
+Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+Acked-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 6ae42bb22b40254e6488bbfe47f970620ab6d433)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ arch/arm/mach-shmobile/platsmp.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
+index 5f1a59b..fde0d23 100644
+--- a/arch/arm/mach-shmobile/platsmp.c
++++ b/arch/arm/mach-shmobile/platsmp.c
+@@ -30,7 +30,12 @@
+ #endif
+
+ #define is_r8a7779() machine_is_marzen()
++
++#ifdef CONFIG_ARCH_EMEV2
+ #define is_emev2() of_machine_is_compatible("renesas,emev2")
++#else
++#define is_emev2() (0)
++#endif
+
+ static unsigned int __init shmobile_smp_get_core_count(void)
+ {
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/arm-mach-shmobile-kzm9d-add-defconfig.patch b/patches.kzm9d/arm-mach-shmobile-kzm9d-add-defconfig.patch
new file mode 100644
index 00000000000000..fa9f6e43127236
--- /dev/null
+++ b/patches.kzm9d/arm-mach-shmobile-kzm9d-add-defconfig.patch
@@ -0,0 +1,122 @@
+From koba@kmckk.co.jp Wed Oct 3 04:30:14 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:15 +0900
+Subject: [PATCH 23/26] ARM: mach-shmobile: kzm9d: Add defconfig
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, "Rafael J. Wysocki" <rjw@sisk.pl>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-24-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+Original work by Magnus Damm, tested and tweaked by Simon Horman
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit d252f644789188743b55339f5756a8bcc86fbaa5)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ arch/arm/configs/kzm9d_defconfig | 89 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 89 insertions(+)
+ create mode 100644 arch/arm/configs/kzm9d_defconfig
+
+diff --git a/arch/arm/configs/kzm9d_defconfig b/arch/arm/configs/kzm9d_defconfig
+new file mode 100644
+index 0000000..26146ff
+--- /dev/null
++++ b/arch/arm/configs/kzm9d_defconfig
+@@ -0,0 +1,89 @@
++# CONFIG_ARM_PATCH_PHYS_VIRT is not set
++CONFIG_EXPERIMENTAL=y
++CONFIG_SYSVIPC=y
++CONFIG_NO_HZ=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_EMBEDDED=y
++CONFIG_SLAB=y
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_IOSCHED_DEADLINE is not set
++# CONFIG_IOSCHED_CFQ is not set
++CONFIG_ARCH_SHMOBILE=y
++CONFIG_ARCH_EMEV2=y
++CONFIG_MACH_KZM9D=y
++CONFIG_MEMORY_START=0x40000000
++CONFIG_MEMORY_SIZE=0x10000000
++# CONFIG_SH_TIMER_TMU is not set
++# CONFIG_SWP_EMULATE is not set
++# CONFIG_CACHE_L2X0 is not set
++CONFIG_SMP=y
++CONFIG_NR_CPUS=2
++CONFIG_HOTPLUG_CPU=y
++# CONFIG_LOCAL_TIMERS is not set
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_CROSS_MEMORY_ATTACH is not set
++CONFIG_FORCE_MAX_ZONEORDER=13
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_ARM_APPENDED_DTB=y
++CONFIG_CMDLINE="console=tty0 console=ttyS1,115200n81 earlyprintk=serial8250-em.1,115200n81 mem=128M@0x40000000 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096"
++CONFIG_CMDLINE_FORCE=y
++CONFIG_VFP=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++# CONFIG_SUSPEND is not set
++CONFIG_NET=y
++CONFIG_PACKET=y
++CONFIG_UNIX=y
++CONFIG_INET=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=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_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_BLK_DEV is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NET_VENDOR_BROADCOM is not set
++# CONFIG_NET_VENDOR_CHELSIO is not set
++# CONFIG_NET_VENDOR_CIRRUS is not set
++# CONFIG_NET_VENDOR_FARADAY 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_NATSEMI is not set
++# CONFIG_NET_VENDOR_SEEQ is not set
++CONFIG_SMSC911X=y
++# CONFIG_NET_VENDOR_STMICRO is not set
++# CONFIG_NET_VENDOR_WIZNET is not set
++# CONFIG_WLAN is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_SERIO is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_DEVKMEM is not set
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_EM=y
++# CONFIG_HW_RANDOM is not set
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_EM=y
++# CONFIG_HWMON is not set
++# CONFIG_HID_SUPPORT is not set
++# CONFIG_USB_SUPPORT is not set
++# CONFIG_IOMMU_SUPPORT is not set
++# CONFIG_DNOTIFY is not set
++CONFIG_TMPFS=y
++# CONFIG_MISC_FILESYSTEMS is not set
++CONFIG_NFS_FS=y
++CONFIG_ROOT_NFS=y
++# CONFIG_FTRACE is not set
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/clockevents-make-clockevents_config-a-global-symbol.patch b/patches.kzm9d/clockevents-make-clockevents_config-a-global-symbol.patch
new file mode 100644
index 00000000000000..6d696a43c1a413
--- /dev/null
+++ b/patches.kzm9d/clockevents-make-clockevents_config-a-global-symbol.patch
@@ -0,0 +1,63 @@
+From koba@kmckk.co.jp Wed Oct 3 04:27:56 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:04 +0900
+Subject: [PATCH 12/26] clockevents: Make clockevents_config() a global symbol
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Magnus Damm <magnus.damm@gmail.com>, arnd@arndb.de, johnstul@us.ibm.com, rjw@sisk.pl, lethal@linux-sh.org, gregkh@linuxfoundation.org, olof@lixom.net, Thomas Gleixner <tglx@linutronix.de>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-13-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <magnus.damm@gmail.com>
+
+Make clockevents_config() into a global symbol to allow it to be used
+by compiled-in clockevent drivers. This is needed by drivers that want
+to update the timer frequency after registration time.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Tested-by: Simon Horman <horms@verge.net.au>
+Cc: arnd@arndb.de
+Cc: johnstul@us.ibm.com
+Cc: rjw@sisk.pl
+Cc: lethal@linux-sh.org
+Cc: gregkh@linuxfoundation.org
+Cc: olof@lixom.net
+Cc: Magnus Damm <magnus.damm@gmail.com>
+Link: http://lkml.kernel.org/r/20120509143934.27521.46553.sendpatchset@w520
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+(cherry picked from commit e5400321a6f15ce0fe77c8455954f213ef7dcc54)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ include/linux/clockchips.h | 1 +
+ kernel/time/clockevents.c | 3 +--
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
+index 81e803e..acba8943 100644
+--- a/include/linux/clockchips.h
++++ b/include/linux/clockchips.h
+@@ -132,6 +132,7 @@ extern u64 clockevent_delta2ns(unsigned long latch,
+ struct clock_event_device *evt);
+ extern void clockevents_register_device(struct clock_event_device *dev);
+
++extern void clockevents_config(struct clock_event_device *dev, u32 freq);
+ extern void clockevents_config_and_register(struct clock_event_device *dev,
+ u32 freq, unsigned long min_delta,
+ unsigned long max_delta);
+diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
+index 9cd928f..7e1ce01 100644
+--- a/kernel/time/clockevents.c
++++ b/kernel/time/clockevents.c
+@@ -297,8 +297,7 @@ void clockevents_register_device(struct clock_event_device *dev)
+ }
+ EXPORT_SYMBOL_GPL(clockevents_register_device);
+
+-static void clockevents_config(struct clock_event_device *dev,
+- u32 freq)
++void clockevents_config(struct clock_event_device *dev, u32 freq)
+ {
+ u64 sec;
+
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/clocksource-em_sti-add-dt-support.patch b/patches.kzm9d/clocksource-em_sti-add-dt-support.patch
new file mode 100644
index 00000000000000..cc718d26d94d19
--- /dev/null
+++ b/patches.kzm9d/clocksource-em_sti-add-dt-support.patch
@@ -0,0 +1,56 @@
+From koba@kmckk.co.jp Wed Oct 3 04:28:36 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:06 +0900
+Subject: [PATCH 14/26] clocksource: em_sti: Add DT support
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Magnus Damm <magnus.damm@gmail.com>, arnd@arndb.de, johnstul@us.ibm.com, rjw@sisk.pl, lethal@linux-sh.org, gregkh@linuxfoundation.org, olof@lixom.net, Thomas Gleixner <tglx@linutronix.de>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-15-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <magnus.damm@gmail.com>
+
+Update the em-sti driver to support DT.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Cc: arnd@arndb.de
+Cc: horms@verge.net.au
+Cc: johnstul@us.ibm.com
+Cc: rjw@sisk.pl
+Cc: lethal@linux-sh.org
+Cc: gregkh@linuxfoundation.org
+Cc: olof@lixom.net
+Link: http://lkml.kernel.org/r/20120509143950.27521.7949.sendpatchset@w520
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+(cherry picked from commit fc0830fe017d02b7b4995b5c402b484b65d9dfc6)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ drivers/clocksource/em_sti.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c
+index 719584a..372051d 100644
+--- a/drivers/clocksource/em_sti.c
++++ b/drivers/clocksource/em_sti.c
+@@ -384,11 +384,18 @@ static int __devexit em_sti_remove(struct platform_device *pdev)
+ return -EBUSY; /* cannot unregister clockevent and clocksource */
+ }
+
++static const struct of_device_id em_sti_dt_ids[] __devinitconst = {
++ { .compatible = "renesas,em-sti", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, em_sti_dt_ids);
++
+ static struct platform_driver em_sti_device_driver = {
+ .probe = em_sti_probe,
+ .remove = __devexit_p(em_sti_remove),
+ .driver = {
+ .name = "em_sti",
++ .of_match_table = em_sti_dt_ids,
+ }
+ };
+
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/clocksource-em_sti-emma-mobile-sti-driver.patch b/patches.kzm9d/clocksource-em_sti-emma-mobile-sti-driver.patch
new file mode 100644
index 00000000000000..cb2092803c489e
--- /dev/null
+++ b/patches.kzm9d/clocksource-em_sti-emma-mobile-sti-driver.patch
@@ -0,0 +1,468 @@
+From koba@kmckk.co.jp Wed Oct 3 04:28:15 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:05 +0900
+Subject: [PATCH 13/26] clocksource: em_sti: Emma Mobile STI driver
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Magnus Damm <magnus.damm@gmail.com>, arnd@arndb.de, johnstul@us.ibm.com, rjw@sisk.pl, lethal@linux-sh.org, gregkh@linuxfoundation.org, olof@lixom.net, Thomas Gleixner <tglx@linutronix.de>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-14-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <magnus.damm@gmail.com>
+
+The STI hardware is based on a single 48-bit 32kHz
+counter that together with two individual compare
+registers can generate interrupts. There are no
+timer operating modes selectable which means that
+the timer can not clear on match.
+
+This driver is providing clocksource support for the
+48-bit counter. Clockevents are also supported using
+the same timer in oneshot mode.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Cc: horms@verge.net.au
+Cc: arnd@arndb.de
+Cc: johnstul@us.ibm.com
+Cc: rjw@sisk.pl
+Cc: lethal@linux-sh.org
+Cc: gregkh@linuxfoundation.org
+Cc: olof@lixom.net
+Link: http://lkml.kernel.org/r/20120525070344.23443.69756.sendpatchset@w520
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+(cherry picked from commit b9dbf9517784084ee9496f9f17f9754c1d021a9e)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ arch/arm/mach-shmobile/Kconfig | 6
+ drivers/clocksource/Makefile | 1
+ drivers/clocksource/em_sti.c | 399 +++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 406 insertions(+)
+ create mode 100644 drivers/clocksource/em_sti.c
+
+--- a/arch/arm/mach-shmobile/Kconfig
++++ b/arch/arm/mach-shmobile/Kconfig
+@@ -177,6 +177,12 @@ config SH_TIMER_TMU
+ help
+ This enables build of the TMU timer driver.
+
++config EM_TIMER_STI
++ bool "STI timer driver"
++ default y
++ help
++ This enables build of the STI timer driver.
++
+ endmenu
+
+ config SH_CLK_CPG
+--- a/drivers/clocksource/Makefile
++++ b/drivers/clocksource/Makefile
+@@ -6,6 +6,7 @@ obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) +=
+ obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o
+ obj-$(CONFIG_SH_TIMER_MTU2) += sh_mtu2.o
+ obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o
++obj-$(CONFIG_EM_TIMER_STI) += em_sti.o
+ obj-$(CONFIG_CLKBLD_I8253) += i8253.o
+ obj-$(CONFIG_CLKSRC_MMIO) += mmio.o
+ obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o
+--- /dev/null
++++ b/drivers/clocksource/em_sti.c
+@@ -0,0 +1,399 @@
++/*
++ * Emma Mobile Timer Support - STI
++ *
++ * Copyright (C) 2012 Magnus Damm
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++#include <linux/interrupt.h>
++#include <linux/ioport.h>
++#include <linux/io.h>
++#include <linux/clk.h>
++#include <linux/irq.h>
++#include <linux/err.h>
++#include <linux/delay.h>
++#include <linux/clocksource.h>
++#include <linux/clockchips.h>
++#include <linux/slab.h>
++#include <linux/module.h>
++
++enum { USER_CLOCKSOURCE, USER_CLOCKEVENT, USER_NR };
++
++struct em_sti_priv {
++ void __iomem *base;
++ struct clk *clk;
++ struct platform_device *pdev;
++ unsigned int active[USER_NR];
++ unsigned long rate;
++ raw_spinlock_t lock;
++ struct clock_event_device ced;
++ struct clocksource cs;
++};
++
++#define STI_CONTROL 0x00
++#define STI_COMPA_H 0x10
++#define STI_COMPA_L 0x14
++#define STI_COMPB_H 0x18
++#define STI_COMPB_L 0x1c
++#define STI_COUNT_H 0x20
++#define STI_COUNT_L 0x24
++#define STI_COUNT_RAW_H 0x28
++#define STI_COUNT_RAW_L 0x2c
++#define STI_SET_H 0x30
++#define STI_SET_L 0x34
++#define STI_INTSTATUS 0x40
++#define STI_INTRAWSTATUS 0x44
++#define STI_INTENSET 0x48
++#define STI_INTENCLR 0x4c
++#define STI_INTFFCLR 0x50
++
++static inline unsigned long em_sti_read(struct em_sti_priv *p, int offs)
++{
++ return ioread32(p->base + offs);
++}
++
++static inline void em_sti_write(struct em_sti_priv *p, int offs,
++ unsigned long value)
++{
++ iowrite32(value, p->base + offs);
++}
++
++static int em_sti_enable(struct em_sti_priv *p)
++{
++ int ret;
++
++ /* enable clock */
++ ret = clk_enable(p->clk);
++ if (ret) {
++ dev_err(&p->pdev->dev, "cannot enable clock\n");
++ return ret;
++ }
++
++ /* configure channel, periodic mode and maximum timeout */
++ p->rate = clk_get_rate(p->clk);
++
++ /* reset the counter */
++ em_sti_write(p, STI_SET_H, 0x40000000);
++ em_sti_write(p, STI_SET_L, 0x00000000);
++
++ /* mask and clear pending interrupts */
++ em_sti_write(p, STI_INTENCLR, 3);
++ em_sti_write(p, STI_INTFFCLR, 3);
++
++ /* enable updates of counter registers */
++ em_sti_write(p, STI_CONTROL, 1);
++
++ return 0;
++}
++
++static void em_sti_disable(struct em_sti_priv *p)
++{
++ /* mask interrupts */
++ em_sti_write(p, STI_INTENCLR, 3);
++
++ /* stop clock */
++ clk_disable(p->clk);
++}
++
++static cycle_t em_sti_count(struct em_sti_priv *p)
++{
++ cycle_t ticks;
++ unsigned long flags;
++
++ /* the STI hardware buffers the 48-bit count, but to
++ * break it out into two 32-bit access the registers
++ * must be accessed in a certain order.
++ * Always read STI_COUNT_H before STI_COUNT_L.
++ */
++ raw_spin_lock_irqsave(&p->lock, flags);
++ ticks = (cycle_t)(em_sti_read(p, STI_COUNT_H) & 0xffff) << 32;
++ ticks |= em_sti_read(p, STI_COUNT_L);
++ raw_spin_unlock_irqrestore(&p->lock, flags);
++
++ return ticks;
++}
++
++static cycle_t em_sti_set_next(struct em_sti_priv *p, cycle_t next)
++{
++ unsigned long flags;
++
++ raw_spin_lock_irqsave(&p->lock, flags);
++
++ /* mask compare A interrupt */
++ em_sti_write(p, STI_INTENCLR, 1);
++
++ /* update compare A value */
++ em_sti_write(p, STI_COMPA_H, next >> 32);
++ em_sti_write(p, STI_COMPA_L, next & 0xffffffff);
++
++ /* clear compare A interrupt source */
++ em_sti_write(p, STI_INTFFCLR, 1);
++
++ /* unmask compare A interrupt */
++ em_sti_write(p, STI_INTENSET, 1);
++
++ raw_spin_unlock_irqrestore(&p->lock, flags);
++
++ return next;
++}
++
++static irqreturn_t em_sti_interrupt(int irq, void *dev_id)
++{
++ struct em_sti_priv *p = dev_id;
++
++ p->ced.event_handler(&p->ced);
++ return IRQ_HANDLED;
++}
++
++static int em_sti_start(struct em_sti_priv *p, unsigned int user)
++{
++ unsigned long flags;
++ int used_before;
++ int ret = 0;
++
++ raw_spin_lock_irqsave(&p->lock, flags);
++ used_before = p->active[USER_CLOCKSOURCE] | p->active[USER_CLOCKEVENT];
++ if (!used_before)
++ ret = em_sti_enable(p);
++
++ if (!ret)
++ p->active[user] = 1;
++ raw_spin_unlock_irqrestore(&p->lock, flags);
++
++ return ret;
++}
++
++static void em_sti_stop(struct em_sti_priv *p, unsigned int user)
++{
++ unsigned long flags;
++ int used_before, used_after;
++
++ raw_spin_lock_irqsave(&p->lock, flags);
++ used_before = p->active[USER_CLOCKSOURCE] | p->active[USER_CLOCKEVENT];
++ p->active[user] = 0;
++ used_after = p->active[USER_CLOCKSOURCE] | p->active[USER_CLOCKEVENT];
++
++ if (used_before && !used_after)
++ em_sti_disable(p);
++ raw_spin_unlock_irqrestore(&p->lock, flags);
++}
++
++static struct em_sti_priv *cs_to_em_sti(struct clocksource *cs)
++{
++ return container_of(cs, struct em_sti_priv, cs);
++}
++
++static cycle_t em_sti_clocksource_read(struct clocksource *cs)
++{
++ return em_sti_count(cs_to_em_sti(cs));
++}
++
++static int em_sti_clocksource_enable(struct clocksource *cs)
++{
++ int ret;
++ struct em_sti_priv *p = cs_to_em_sti(cs);
++
++ ret = em_sti_start(p, USER_CLOCKSOURCE);
++ if (!ret)
++ __clocksource_updatefreq_hz(cs, p->rate);
++ return ret;
++}
++
++static void em_sti_clocksource_disable(struct clocksource *cs)
++{
++ em_sti_stop(cs_to_em_sti(cs), USER_CLOCKSOURCE);
++}
++
++static void em_sti_clocksource_resume(struct clocksource *cs)
++{
++ em_sti_clocksource_enable(cs);
++}
++
++static int em_sti_register_clocksource(struct em_sti_priv *p)
++{
++ struct clocksource *cs = &p->cs;
++
++ memset(cs, 0, sizeof(*cs));
++ cs->name = dev_name(&p->pdev->dev);
++ cs->rating = 200;
++ cs->read = em_sti_clocksource_read;
++ cs->enable = em_sti_clocksource_enable;
++ cs->disable = em_sti_clocksource_disable;
++ cs->suspend = em_sti_clocksource_disable;
++ cs->resume = em_sti_clocksource_resume;
++ cs->mask = CLOCKSOURCE_MASK(48);
++ cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
++
++ dev_info(&p->pdev->dev, "used as clock source\n");
++
++ /* Register with dummy 1 Hz value, gets updated in ->enable() */
++ clocksource_register_hz(cs, 1);
++ return 0;
++}
++
++static struct em_sti_priv *ced_to_em_sti(struct clock_event_device *ced)
++{
++ return container_of(ced, struct em_sti_priv, ced);
++}
++
++static void em_sti_clock_event_mode(enum clock_event_mode mode,
++ struct clock_event_device *ced)
++{
++ struct em_sti_priv *p = ced_to_em_sti(ced);
++
++ /* deal with old setting first */
++ switch (ced->mode) {
++ case CLOCK_EVT_MODE_ONESHOT:
++ em_sti_stop(p, USER_CLOCKEVENT);
++ break;
++ default:
++ break;
++ }
++
++ switch (mode) {
++ case CLOCK_EVT_MODE_ONESHOT:
++ dev_info(&p->pdev->dev, "used for oneshot clock events\n");
++ em_sti_start(p, USER_CLOCKEVENT);
++ clockevents_config(&p->ced, p->rate);
++ break;
++ case CLOCK_EVT_MODE_SHUTDOWN:
++ case CLOCK_EVT_MODE_UNUSED:
++ em_sti_stop(p, USER_CLOCKEVENT);
++ break;
++ default:
++ break;
++ }
++}
++
++static int em_sti_clock_event_next(unsigned long delta,
++ struct clock_event_device *ced)
++{
++ struct em_sti_priv *p = ced_to_em_sti(ced);
++ cycle_t next;
++ int safe;
++
++ next = em_sti_set_next(p, em_sti_count(p) + delta);
++ safe = em_sti_count(p) < (next - 1);
++
++ return !safe;
++}
++
++static void em_sti_register_clockevent(struct em_sti_priv *p)
++{
++ struct clock_event_device *ced = &p->ced;
++
++ memset(ced, 0, sizeof(*ced));
++ ced->name = dev_name(&p->pdev->dev);
++ ced->features = CLOCK_EVT_FEAT_ONESHOT;
++ ced->rating = 200;
++ ced->cpumask = cpumask_of(0);
++ ced->set_next_event = em_sti_clock_event_next;
++ ced->set_mode = em_sti_clock_event_mode;
++
++ dev_info(&p->pdev->dev, "used for clock events\n");
++
++ /* Register with dummy 1 Hz value, gets updated in ->set_mode() */
++ clockevents_config_and_register(ced, 1, 2, 0xffffffff);
++}
++
++static int __devinit em_sti_probe(struct platform_device *pdev)
++{
++ struct em_sti_priv *p;
++ struct resource *res;
++ int irq, ret;
++
++ p = kzalloc(sizeof(*p), GFP_KERNEL);
++ if (p == NULL) {
++ dev_err(&pdev->dev, "failed to allocate driver data\n");
++ ret = -ENOMEM;
++ goto err0;
++ }
++
++ p->pdev = pdev;
++ platform_set_drvdata(pdev, p);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ dev_err(&pdev->dev, "failed to get I/O memory\n");
++ ret = -EINVAL;
++ goto err0;
++ }
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0) {
++ dev_err(&pdev->dev, "failed to get irq\n");
++ ret = -EINVAL;
++ goto err0;
++ }
++
++ /* map memory, let base point to the STI instance */
++ p->base = ioremap_nocache(res->start, resource_size(res));
++ if (p->base == NULL) {
++ dev_err(&pdev->dev, "failed to remap I/O memory\n");
++ ret = -ENXIO;
++ goto err0;
++ }
++
++ /* get hold of clock */
++ p->clk = clk_get(&pdev->dev, "sclk");
++ if (IS_ERR(p->clk)) {
++ dev_err(&pdev->dev, "cannot get clock\n");
++ ret = PTR_ERR(p->clk);
++ goto err1;
++ }
++
++ if (request_irq(irq, em_sti_interrupt,
++ IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
++ dev_name(&pdev->dev), p)) {
++ dev_err(&pdev->dev, "failed to request low IRQ\n");
++ ret = -ENOENT;
++ goto err2;
++ }
++
++ raw_spin_lock_init(&p->lock);
++ em_sti_register_clockevent(p);
++ em_sti_register_clocksource(p);
++ return 0;
++
++err2:
++ clk_put(p->clk);
++err1:
++ iounmap(p->base);
++err0:
++ kfree(p);
++ return ret;
++}
++
++static int __devexit em_sti_remove(struct platform_device *pdev)
++{
++ return -EBUSY; /* cannot unregister clockevent and clocksource */
++}
++
++static struct platform_driver em_sti_device_driver = {
++ .probe = em_sti_probe,
++ .remove = __devexit_p(em_sti_remove),
++ .driver = {
++ .name = "em_sti",
++ }
++};
++
++module_platform_driver(em_sti_device_driver);
++
++MODULE_AUTHOR("Magnus Damm");
++MODULE_DESCRIPTION("Renesas Emma Mobile STI Timer Driver");
++MODULE_LICENSE("GPL v2");
diff --git a/patches.kzm9d/gpio-emma-mobile-gpio-driver-v2.patch b/patches.kzm9d/gpio-emma-mobile-gpio-driver-v2.patch
new file mode 100644
index 00000000000000..fa0b501fd36e9a
--- /dev/null
+++ b/patches.kzm9d/gpio-emma-mobile-gpio-driver-v2.patch
@@ -0,0 +1,499 @@
+From koba@kmckk.co.jp Wed Oct 3 04:29:20 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:09 +0900
+Subject: [PATCH 17/26] gpio: Emma Mobile GPIO driver V2
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, "Rafael J. Wysocki" <rjw@sisk.pl>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-18-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+This patch is V2 of the Emma Mobile GPIO driver. This
+driver is designed to be reusable between multiple SoCs
+that share the same basic building block, but so far it
+has only been used on Emma Mobile EV2.
+
+Each driver instance handles 32 GPIOs with individually
+maskable IRQs. The driver operates on two I/O memory
+ranges and the 32 GPIOs are hooked up to two interrupts.
+
+In the case of Emma Mobile EV2 this GPIO building block
+is used as main external interrupt controller hooking up
+159 GPIOS as 159 interrupts via 5 driver instances and
+10 interrupts to the GIC and the Cortex-A9 Dual.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit a07e103ef08c6907d695a06467d7ee950796fccf)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ drivers/gpio/Kconfig | 6
+ drivers/gpio/Makefile | 1
+ drivers/gpio/gpio-em.c | 418 ++++++++++++++++++++++++++++++++++
+ include/linux/platform_data/gpio-em.h | 10
+ 4 files changed, 435 insertions(+)
+ create mode 100644 drivers/gpio/gpio-em.c
+ create mode 100644 include/linux/platform_data/gpio-em.h
+
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -91,6 +91,12 @@ config GPIO_IT8761E
+ help
+ Say yes here to support GPIO functionality of IT8761E super I/O chip.
+
++config GPIO_EM
++ tristate "Emma Mobile GPIO"
++ depends on ARM
++ help
++ Say yes here to support GPIO on Renesas Emma Mobile SoCs.
++
+ config GPIO_EP93XX
+ def_bool y
+ depends on ARCH_EP93XX
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -15,6 +15,7 @@ obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
+ obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
+ obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
+ obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o
++obj-$(CONFIG_GPIO_EM) += gpio-em.o
+ obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
+ obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
+ obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o
+--- /dev/null
++++ b/drivers/gpio/gpio-em.c
+@@ -0,0 +1,418 @@
++/*
++ * Emma Mobile GPIO Support - GIO
++ *
++ * Copyright (C) 2012 Magnus Damm
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++#include <linux/interrupt.h>
++#include <linux/ioport.h>
++#include <linux/io.h>
++#include <linux/irq.h>
++#include <linux/irqdomain.h>
++#include <linux/bitops.h>
++#include <linux/err.h>
++#include <linux/gpio.h>
++#include <linux/slab.h>
++#include <linux/module.h>
++#include <linux/platform_data/gpio-em.h>
++
++struct em_gio_priv {
++ void __iomem *base0;
++ void __iomem *base1;
++ unsigned int irq_base;
++ spinlock_t sense_lock;
++ struct platform_device *pdev;
++ struct gpio_chip gpio_chip;
++ struct irq_chip irq_chip;
++ struct irq_domain *irq_domain;
++};
++
++#define GIO_E1 0x00
++#define GIO_E0 0x04
++#define GIO_EM 0x04
++#define GIO_OL 0x08
++#define GIO_OH 0x0c
++#define GIO_I 0x10
++#define GIO_IIA 0x14
++#define GIO_IEN 0x18
++#define GIO_IDS 0x1c
++#define GIO_IIM 0x1c
++#define GIO_RAW 0x20
++#define GIO_MST 0x24
++#define GIO_IIR 0x28
++
++#define GIO_IDT0 0x40
++#define GIO_IDT1 0x44
++#define GIO_IDT2 0x48
++#define GIO_IDT3 0x4c
++#define GIO_RAWBL 0x50
++#define GIO_RAWBH 0x54
++#define GIO_IRBL 0x58
++#define GIO_IRBH 0x5c
++
++#define GIO_IDT(n) (GIO_IDT0 + ((n) * 4))
++
++static inline unsigned long em_gio_read(struct em_gio_priv *p, int offs)
++{
++ if (offs < GIO_IDT0)
++ return ioread32(p->base0 + offs);
++ else
++ return ioread32(p->base1 + (offs - GIO_IDT0));
++}
++
++static inline void em_gio_write(struct em_gio_priv *p, int offs,
++ unsigned long value)
++{
++ if (offs < GIO_IDT0)
++ iowrite32(value, p->base0 + offs);
++ else
++ iowrite32(value, p->base1 + (offs - GIO_IDT0));
++}
++
++static inline struct em_gio_priv *irq_to_priv(struct irq_data *d)
++{
++ struct irq_chip *chip = irq_data_get_irq_chip(d);
++ return container_of(chip, struct em_gio_priv, irq_chip);
++}
++
++static void em_gio_irq_disable(struct irq_data *d)
++{
++ struct em_gio_priv *p = irq_to_priv(d);
++
++ em_gio_write(p, GIO_IDS, BIT(irqd_to_hwirq(d)));
++}
++
++static void em_gio_irq_enable(struct irq_data *d)
++{
++ struct em_gio_priv *p = irq_to_priv(d);
++
++ em_gio_write(p, GIO_IEN, BIT(irqd_to_hwirq(d)));
++}
++
++#define GIO_ASYNC(x) (x + 8)
++
++static unsigned char em_gio_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
++ [IRQ_TYPE_EDGE_RISING] = GIO_ASYNC(0x00),
++ [IRQ_TYPE_EDGE_FALLING] = GIO_ASYNC(0x01),
++ [IRQ_TYPE_LEVEL_HIGH] = GIO_ASYNC(0x02),
++ [IRQ_TYPE_LEVEL_LOW] = GIO_ASYNC(0x03),
++ [IRQ_TYPE_EDGE_BOTH] = GIO_ASYNC(0x04),
++};
++
++static int em_gio_irq_set_type(struct irq_data *d, unsigned int type)
++{
++ unsigned char value = em_gio_sense_table[type & IRQ_TYPE_SENSE_MASK];
++ struct em_gio_priv *p = irq_to_priv(d);
++ unsigned int reg, offset, shift;
++ unsigned long flags;
++ unsigned long tmp;
++
++ if (!value)
++ return -EINVAL;
++
++ offset = irqd_to_hwirq(d);
++
++ pr_debug("gio: sense irq = %d, mode = %d\n", offset, value);
++
++ /* 8 x 4 bit fields in 4 IDT registers */
++ reg = GIO_IDT(offset >> 3);
++ shift = (offset & 0x07) << 4;
++
++ spin_lock_irqsave(&p->sense_lock, flags);
++
++ /* disable the interrupt in IIA */
++ tmp = em_gio_read(p, GIO_IIA);
++ tmp &= ~BIT(offset);
++ em_gio_write(p, GIO_IIA, tmp);
++
++ /* change the sense setting in IDT */
++ tmp = em_gio_read(p, reg);
++ tmp &= ~(0xf << shift);
++ tmp |= value << shift;
++ em_gio_write(p, reg, tmp);
++
++ /* clear pending interrupts */
++ em_gio_write(p, GIO_IIR, BIT(offset));
++
++ /* enable the interrupt in IIA */
++ tmp = em_gio_read(p, GIO_IIA);
++ tmp |= BIT(offset);
++ em_gio_write(p, GIO_IIA, tmp);
++
++ spin_unlock_irqrestore(&p->sense_lock, flags);
++
++ return 0;
++}
++
++static irqreturn_t em_gio_irq_handler(int irq, void *dev_id)
++{
++ struct em_gio_priv *p = dev_id;
++ unsigned long pending;
++ unsigned int offset, irqs_handled = 0;
++
++ while ((pending = em_gio_read(p, GIO_MST))) {
++ offset = __ffs(pending);
++ em_gio_write(p, GIO_IIR, BIT(offset));
++ generic_handle_irq(irq_find_mapping(p->irq_domain, offset));
++ irqs_handled++;
++ }
++
++ return irqs_handled ? IRQ_HANDLED : IRQ_NONE;
++}
++
++static inline struct em_gio_priv *gpio_to_priv(struct gpio_chip *chip)
++{
++ return container_of(chip, struct em_gio_priv, gpio_chip);
++}
++
++static int em_gio_direction_input(struct gpio_chip *chip, unsigned offset)
++{
++ em_gio_write(gpio_to_priv(chip), GIO_E0, BIT(offset));
++ return 0;
++}
++
++static int em_gio_get(struct gpio_chip *chip, unsigned offset)
++{
++ return (int)(em_gio_read(gpio_to_priv(chip), GIO_I) & BIT(offset));
++}
++
++static void __em_gio_set(struct gpio_chip *chip, unsigned int reg,
++ unsigned shift, int value)
++{
++ /* upper 16 bits contains mask and lower 16 actual value */
++ em_gio_write(gpio_to_priv(chip), reg,
++ (1 << (shift + 16)) | (value << shift));
++}
++
++static void em_gio_set(struct gpio_chip *chip, unsigned offset, int value)
++{
++ /* output is split into two registers */
++ if (offset < 16)
++ __em_gio_set(chip, GIO_OL, offset, value);
++ else
++ __em_gio_set(chip, GIO_OH, offset - 16, value);
++}
++
++static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset,
++ int value)
++{
++ /* write GPIO value to output before selecting output mode of pin */
++ em_gio_set(chip, offset, value);
++ em_gio_write(gpio_to_priv(chip), GIO_E1, BIT(offset));
++ return 0;
++}
++
++static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset)
++{
++ return irq_find_mapping(gpio_to_priv(chip)->irq_domain, offset);
++}
++
++static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq,
++ irq_hw_number_t hw)
++{
++ struct em_gio_priv *p = h->host_data;
++
++ pr_debug("gio: map hw irq = %d, virq = %d\n", (int)hw, virq);
++
++ irq_set_chip_data(virq, h->host_data);
++ irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq);
++ set_irq_flags(virq, IRQF_VALID); /* kill me now */
++ return 0;
++}
++
++static struct irq_domain_ops em_gio_irq_domain_ops = {
++ .map = em_gio_irq_domain_map,
++};
++
++static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p)
++{
++ struct platform_device *pdev = p->pdev;
++ struct gpio_em_config *pdata = pdev->dev.platform_data;
++
++ p->irq_base = irq_alloc_descs(pdata->irq_base, 0,
++ pdata->number_of_pins, numa_node_id());
++ if (IS_ERR_VALUE(p->irq_base)) {
++ dev_err(&pdev->dev, "cannot get irq_desc\n");
++ return -ENXIO;
++ }
++ pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n",
++ pdata->gpio_base, pdata->number_of_pins, p->irq_base);
++
++ p->irq_domain = irq_domain_add_legacy(pdev->dev.of_node,
++ pdata->number_of_pins,
++ p->irq_base, 0,
++ &em_gio_irq_domain_ops, p);
++ if (!p->irq_domain) {
++ irq_free_descs(p->irq_base, pdata->number_of_pins);
++ return -ENXIO;
++ }
++
++ return 0;
++}
++
++static void __devexit em_gio_irq_domain_cleanup(struct em_gio_priv *p)
++{
++ struct gpio_em_config *pdata = p->pdev->dev.platform_data;
++
++ irq_free_descs(p->irq_base, pdata->number_of_pins);
++ /* FIXME: irq domain wants to be freed! */
++}
++
++static int __devinit em_gio_probe(struct platform_device *pdev)
++{
++ struct gpio_em_config *pdata = pdev->dev.platform_data;
++ struct em_gio_priv *p;
++ struct resource *io[2], *irq[2];
++ struct gpio_chip *gpio_chip;
++ struct irq_chip *irq_chip;
++ const char *name = dev_name(&pdev->dev);
++ int ret;
++
++ p = kzalloc(sizeof(*p), GFP_KERNEL);
++ if (!p) {
++ dev_err(&pdev->dev, "failed to allocate driver data\n");
++ ret = -ENOMEM;
++ goto err0;
++ }
++
++ p->pdev = pdev;
++ platform_set_drvdata(pdev, p);
++ spin_lock_init(&p->sense_lock);
++
++ io[0] = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ io[1] = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ irq[0] = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++ irq[1] = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
++
++ if (!io[0] || !io[1] || !irq[0] || !irq[1] || !pdata) {
++ dev_err(&pdev->dev, "missing IRQ, IOMEM or configuration\n");
++ ret = -EINVAL;
++ goto err1;
++ }
++
++ p->base0 = ioremap_nocache(io[0]->start, resource_size(io[0]));
++ if (!p->base0) {
++ dev_err(&pdev->dev, "failed to remap low I/O memory\n");
++ ret = -ENXIO;
++ goto err1;
++ }
++
++ p->base1 = ioremap_nocache(io[1]->start, resource_size(io[1]));
++ if (!p->base1) {
++ dev_err(&pdev->dev, "failed to remap high I/O memory\n");
++ ret = -ENXIO;
++ goto err2;
++ }
++
++ gpio_chip = &p->gpio_chip;
++ gpio_chip->direction_input = em_gio_direction_input;
++ gpio_chip->get = em_gio_get;
++ gpio_chip->direction_output = em_gio_direction_output;
++ gpio_chip->set = em_gio_set;
++ gpio_chip->to_irq = em_gio_to_irq;
++ gpio_chip->label = name;
++ gpio_chip->owner = THIS_MODULE;
++ gpio_chip->base = pdata->gpio_base;
++ gpio_chip->ngpio = pdata->number_of_pins;
++
++ irq_chip = &p->irq_chip;
++ irq_chip->name = name;
++ irq_chip->irq_mask = em_gio_irq_disable;
++ irq_chip->irq_unmask = em_gio_irq_enable;
++ irq_chip->irq_enable = em_gio_irq_enable;
++ irq_chip->irq_disable = em_gio_irq_disable;
++ irq_chip->irq_set_type = em_gio_irq_set_type;
++ irq_chip->flags = IRQCHIP_SKIP_SET_WAKE;
++
++ ret = em_gio_irq_domain_init(p);
++ if (ret) {
++ dev_err(&pdev->dev, "cannot initialize irq domain\n");
++ goto err3;
++ }
++
++ if (request_irq(irq[0]->start, em_gio_irq_handler, 0, name, p)) {
++ dev_err(&pdev->dev, "failed to request low IRQ\n");
++ ret = -ENOENT;
++ goto err4;
++ }
++
++ if (request_irq(irq[1]->start, em_gio_irq_handler, 0, name, p)) {
++ dev_err(&pdev->dev, "failed to request high IRQ\n");
++ ret = -ENOENT;
++ goto err5;
++ }
++
++ ret = gpiochip_add(gpio_chip);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to add GPIO controller\n");
++ goto err6;
++ }
++ return 0;
++
++err6:
++ free_irq(irq[1]->start, pdev);
++err5:
++ free_irq(irq[0]->start, pdev);
++err4:
++ em_gio_irq_domain_cleanup(p);
++err3:
++ iounmap(p->base1);
++err2:
++ iounmap(p->base0);
++err1:
++ kfree(p);
++err0:
++ return ret;
++}
++
++static int __devexit em_gio_remove(struct platform_device *pdev)
++{
++ struct em_gio_priv *p = platform_get_drvdata(pdev);
++ struct resource *irq[2];
++ int ret;
++
++ ret = gpiochip_remove(&p->gpio_chip);
++ if (ret)
++ return ret;
++
++ irq[0] = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++ irq[1] = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
++
++ free_irq(irq[1]->start, pdev);
++ free_irq(irq[0]->start, pdev);
++ em_gio_irq_domain_cleanup(p);
++ iounmap(p->base1);
++ iounmap(p->base0);
++ kfree(p);
++ return 0;
++}
++
++static struct platform_driver em_gio_device_driver = {
++ .probe = em_gio_probe,
++ .remove = __devexit_p(em_gio_remove),
++ .driver = {
++ .name = "em_gio",
++ }
++};
++
++module_platform_driver(em_gio_device_driver);
++
++MODULE_AUTHOR("Magnus Damm");
++MODULE_DESCRIPTION("Renesas Emma Mobile GIO Driver");
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/include/linux/platform_data/gpio-em.h
+@@ -0,0 +1,10 @@
++#ifndef __GPIO_EM_H__
++#define __GPIO_EM_H__
++
++struct gpio_em_config {
++ unsigned int gpio_base;
++ unsigned int irq_base;
++ unsigned int number_of_pins;
++};
++
++#endif /* __GPIO_EM_H__ */
diff --git a/patches.kzm9d/mach-shmobile-emma-mobile-ev2-dt-support-v3.patch b/patches.kzm9d/mach-shmobile-emma-mobile-ev2-dt-support-v3.patch
new file mode 100644
index 00000000000000..42e526f1e98c28
--- /dev/null
+++ b/patches.kzm9d/mach-shmobile-emma-mobile-ev2-dt-support-v3.patch
@@ -0,0 +1,194 @@
+From koba@kmckk.co.jp Wed Oct 3 04:30:22 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:16 +0900
+Subject: [PATCH 24/26] mach-shmobile: Emma Mobile EV2 DT support V3
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, "Rafael J. Wysocki" <rjw@sisk.pl>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-25-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+This is EMEV2 DT support V3. The support is limited to
+whatever devices that are complied in the kernel. At this
+point we have UARTs handled by "em-uart" and a timer
+handled by "em-sti". Clocks and SMP are not supported.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 3d5de27174955702bc874302ba9e72d71d5acd58)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ arch/arm/boot/dts/emev2.dtsi | 63 ++++++++++++++++++++++++++++++++++
+ arch/arm/mach-shmobile/clock-emev2.c | 5 +++
+ arch/arm/mach-shmobile/setup-emev2.c | 47 ++++++++++++++++++++++++-
+ 3 files changed, 114 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/boot/dts/emev2.dtsi
+
+diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi
+new file mode 100644
+index 0000000..eb504a6
+--- /dev/null
++++ b/arch/arm/boot/dts/emev2.dtsi
+@@ -0,0 +1,63 @@
++/*
++ * Device Tree Source for the EMEV2 SoC
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ *
++ * 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/ "skeleton.dtsi"
++
++/ {
++ compatible = "renesas,emev2";
++ interrupt-parent = <&gic>;
++
++ cpus {
++ cpu@0 {
++ compatible = "arm,cortex-a9";
++ };
++ cpu@1 {
++ compatible = "arm,cortex-a9";
++ };
++ };
++
++ gic: interrupt-controller@e0020000 {
++ compatible = "arm,cortex-a9-gic";
++ interrupt-controller;
++ #interrupt-cells = <3>;
++ reg = <0xe0028000 0x1000>,
++ <0xe0020000 0x0100>;
++ };
++
++ sti@e0180000 {
++ compatible = "renesas,em-sti";
++ reg = <0xe0180000 0x54>;
++ interrupts = <0 125 0>;
++ };
++
++ uart@e1020000 {
++ compatible = "renesas,em-uart";
++ reg = <0xe1020000 0x38>;
++ interrupts = <0 8 0>;
++ };
++
++ uart@e1030000 {
++ compatible = "renesas,em-uart";
++ reg = <0xe1030000 0x38>;
++ interrupts = <0 9 0>;
++ };
++
++ uart@e1040000 {
++ compatible = "renesas,em-uart";
++ reg = <0xe1040000 0x38>;
++ interrupts = <0 10 0>;
++ };
++
++ uart@e1050000 {
++ compatible = "renesas,em-uart";
++ reg = <0xe1050000 0x38>;
++ interrupts = <0 11 0>;
++ };
++};
+diff --git a/arch/arm/mach-shmobile/clock-emev2.c b/arch/arm/mach-shmobile/clock-emev2.c
+index 5bc97de..4710f18 100644
+--- a/arch/arm/mach-shmobile/clock-emev2.c
++++ b/arch/arm/mach-shmobile/clock-emev2.c
+@@ -191,10 +191,15 @@ static int __init emev2_sclkdiv_register(struct clk *clks, int nr)
+
+ static struct clk_lookup lookups[] = {
+ CLKDEV_DEV_ID("serial8250-em.0", &gclk_clks[GCLK_USIAU0_SCLK]),
++ CLKDEV_DEV_ID("e1020000.uart", &gclk_clks[GCLK_USIAU0_SCLK]),
+ CLKDEV_DEV_ID("serial8250-em.1", &gclk_clks[GCLK_USIBU1_SCLK]),
++ CLKDEV_DEV_ID("e1030000.uart", &gclk_clks[GCLK_USIBU1_SCLK]),
+ CLKDEV_DEV_ID("serial8250-em.2", &gclk_clks[GCLK_USIBU2_SCLK]),
++ CLKDEV_DEV_ID("e1040000.uart", &gclk_clks[GCLK_USIBU2_SCLK]),
+ CLKDEV_DEV_ID("serial8250-em.3", &gclk_clks[GCLK_USIBU3_SCLK]),
++ CLKDEV_DEV_ID("e1050000.uart", &gclk_clks[GCLK_USIBU3_SCLK]),
+ CLKDEV_DEV_ID("em_sti.0", &gclk_clks[GCLK_STI_SCLK]),
++ CLKDEV_DEV_ID("e0180000.sti", &gclk_clks[GCLK_STI_SCLK]),
+ };
+
+ void __init emev2_clock_init(void)
+diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c
+index d40fede..dae9aa6 100644
+--- a/arch/arm/mach-shmobile/setup-emev2.c
++++ b/arch/arm/mach-shmobile/setup-emev2.c
+@@ -22,9 +22,11 @@
+ #include <linux/irq.h>
+ #include <linux/platform_device.h>
+ #include <linux/platform_data/gpio-em.h>
++#include <linux/of_platform.h>
+ #include <linux/delay.h>
+ #include <linux/input.h>
+ #include <linux/io.h>
++#include <linux/of_irq.h>
+ #include <mach/hardware.h>
+ #include <mach/common.h>
+ #include <mach/emev2.h>
+@@ -381,9 +383,14 @@ void __init emev2_add_standard_devices(void)
+ ARRAY_SIZE(emev2_late_devices));
+ }
+
+-void __init emev2_add_early_devices(void)
++void __init emev2_init_delay(void)
+ {
+ shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */
++}
++
++void __init emev2_add_early_devices(void)
++{
++ emev2_init_delay();
+
+ early_platform_add_devices(emev2_early_devices,
+ ARRAY_SIZE(emev2_early_devices));
+@@ -405,3 +412,41 @@ void __init emev2_init_irq(void)
+ /* Use GIC to handle interrupts */
+ gic_init(0, 29, gic_dist_base, gic_cpu_base);
+ }
++
++#ifdef CONFIG_USE_OF
++static const struct of_dev_auxdata emev2_auxdata_lookup[] __initconst = {
++ { }
++};
++
++void __init emev2_add_standard_devices_dt(void)
++{
++ of_platform_populate(NULL, of_default_bus_match_table,
++ emev2_auxdata_lookup, NULL);
++}
++
++static const struct of_device_id emev2_dt_irq_match[] = {
++ { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
++ {},
++};
++
++static const char *emev2_boards_compat_dt[] __initdata = {
++ "renesas,emev2",
++ NULL,
++};
++
++void __init emev2_init_irq_dt(void)
++{
++ of_irq_init(emev2_dt_irq_match);
++}
++
++DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)")
++ .init_early = emev2_init_delay,
++ .nr_irqs = NR_IRQS_LEGACY,
++ .init_irq = emev2_init_irq_dt,
++ .handle_irq = gic_handle_irq,
++ .init_machine = emev2_add_standard_devices_dt,
++ .timer = &shmobile_timer,
++ .dt_compat = emev2_boards_compat_dt,
++MACHINE_END
++
++#endif /* CONFIG_USE_OF */
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/mach-shmobile-emma-mobile-ev2-gpio-support-v3.patch b/patches.kzm9d/mach-shmobile-emma-mobile-ev2-gpio-support-v3.patch
new file mode 100644
index 00000000000000..5e9e9227636e06
--- /dev/null
+++ b/patches.kzm9d/mach-shmobile-emma-mobile-ev2-gpio-support-v3.patch
@@ -0,0 +1,286 @@
+From koba@kmckk.co.jp Wed Oct 3 04:30:00 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:13 +0900
+Subject: [PATCH 21/26] mach-shmobile: Emma Mobile EV2 GPIO support V3
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, "Rafael J. Wysocki" <rjw@sisk.pl>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-22-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+Tie in the Emma Mobile GPIO driver "em-gio" to
+support the GPIOs on Emma Mobile EV2.
+
+A static IRQ range is used to allow boards to
+hook up their platform devices to the GPIOs.
+
+DT support is still on the TODO for the GPIO driver,
+so only platform device support is included here.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 088efd9273b5076a0aead479aa31f1066d182b3e)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ arch/arm/mach-shmobile/Kconfig | 1 +
+ arch/arm/mach-shmobile/include/mach/emev2.h | 3 +
+ arch/arm/mach-shmobile/setup-emev2.c | 203 +++++++++++++++++++++++++++
+ 3 files changed, 207 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
+index 577fbad..95ecfad 100644
+--- a/arch/arm/mach-shmobile/Kconfig
++++ b/arch/arm/mach-shmobile/Kconfig
+@@ -45,6 +45,7 @@ config ARCH_EMEV2
+ bool "Emma Mobile EV2"
+ select CPU_V7
+ select ARM_GIC
++ select ARCH_WANT_OPTIONAL_GPIOLIB
+
+ comment "SH-Mobile Board Type"
+
+diff --git a/arch/arm/mach-shmobile/include/mach/emev2.h b/arch/arm/mach-shmobile/include/mach/emev2.h
+index 3fc7184..e6b0c1b 100644
+--- a/arch/arm/mach-shmobile/include/mach/emev2.h
++++ b/arch/arm/mach-shmobile/include/mach/emev2.h
+@@ -13,4 +13,7 @@ extern void emev2_secondary_init(unsigned int cpu);
+ extern int emev2_boot_secondary(unsigned int cpu);
+ extern void emev2_smp_prepare_cpus(void);
+
++#define EMEV2_GPIO_BASE 200
++#define EMEV2_GPIO_IRQ(n) (EMEV2_GPIO_BASE + (n))
++
+ #endif /* __ASM_EMEV2_H__ */
+diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c
+index 2a03a78..d40fede 100644
+--- a/arch/arm/mach-shmobile/setup-emev2.c
++++ b/arch/arm/mach-shmobile/setup-emev2.c
+@@ -21,6 +21,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
+ #include <linux/platform_device.h>
++#include <linux/platform_data/gpio-em.h>
+ #include <linux/delay.h>
+ #include <linux/input.h>
+ #include <linux/io.h>
+@@ -156,6 +157,203 @@ static struct platform_device sti_device = {
+ .num_resources = ARRAY_SIZE(sti_resources),
+ };
+
++
++/* GIO */
++static struct gpio_em_config gio0_config = {
++ .gpio_base = 0,
++ .irq_base = EMEV2_GPIO_IRQ(0),
++ .number_of_pins = 32,
++};
++
++static struct resource gio0_resources[] = {
++ [0] = {
++ .name = "GIO_000",
++ .start = 0xe0050000,
++ .end = 0xe005002b,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .name = "GIO_000",
++ .start = 0xe0050040,
++ .end = 0xe005005f,
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .start = 99,
++ .flags = IORESOURCE_IRQ,
++ },
++ [3] = {
++ .start = 100,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device gio0_device = {
++ .name = "em_gio",
++ .id = 0,
++ .resource = gio0_resources,
++ .num_resources = ARRAY_SIZE(gio0_resources),
++ .dev = {
++ .platform_data = &gio0_config,
++ },
++};
++
++static struct gpio_em_config gio1_config = {
++ .gpio_base = 32,
++ .irq_base = EMEV2_GPIO_IRQ(32),
++ .number_of_pins = 32,
++};
++
++static struct resource gio1_resources[] = {
++ [0] = {
++ .name = "GIO_032",
++ .start = 0xe0050080,
++ .end = 0xe00500ab,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .name = "GIO_032",
++ .start = 0xe00500c0,
++ .end = 0xe00500df,
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .start = 101,
++ .flags = IORESOURCE_IRQ,
++ },
++ [3] = {
++ .start = 102,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device gio1_device = {
++ .name = "em_gio",
++ .id = 1,
++ .resource = gio1_resources,
++ .num_resources = ARRAY_SIZE(gio1_resources),
++ .dev = {
++ .platform_data = &gio1_config,
++ },
++};
++
++static struct gpio_em_config gio2_config = {
++ .gpio_base = 64,
++ .irq_base = EMEV2_GPIO_IRQ(64),
++ .number_of_pins = 32,
++};
++
++static struct resource gio2_resources[] = {
++ [0] = {
++ .name = "GIO_064",
++ .start = 0xe0050100,
++ .end = 0xe005012b,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .name = "GIO_064",
++ .start = 0xe0050140,
++ .end = 0xe005015f,
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .start = 103,
++ .flags = IORESOURCE_IRQ,
++ },
++ [3] = {
++ .start = 104,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device gio2_device = {
++ .name = "em_gio",
++ .id = 2,
++ .resource = gio2_resources,
++ .num_resources = ARRAY_SIZE(gio2_resources),
++ .dev = {
++ .platform_data = &gio2_config,
++ },
++};
++
++static struct gpio_em_config gio3_config = {
++ .gpio_base = 96,
++ .irq_base = EMEV2_GPIO_IRQ(96),
++ .number_of_pins = 32,
++};
++
++static struct resource gio3_resources[] = {
++ [0] = {
++ .name = "GIO_096",
++ .start = 0xe0050100,
++ .end = 0xe005012b,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .name = "GIO_096",
++ .start = 0xe0050140,
++ .end = 0xe005015f,
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .start = 105,
++ .flags = IORESOURCE_IRQ,
++ },
++ [3] = {
++ .start = 106,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device gio3_device = {
++ .name = "em_gio",
++ .id = 3,
++ .resource = gio3_resources,
++ .num_resources = ARRAY_SIZE(gio3_resources),
++ .dev = {
++ .platform_data = &gio3_config,
++ },
++};
++
++static struct gpio_em_config gio4_config = {
++ .gpio_base = 128,
++ .irq_base = EMEV2_GPIO_IRQ(128),
++ .number_of_pins = 31,
++};
++
++static struct resource gio4_resources[] = {
++ [0] = {
++ .name = "GIO_128",
++ .start = 0xe0050200,
++ .end = 0xe005022b,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .name = "GIO_128",
++ .start = 0xe0050240,
++ .end = 0xe005025f,
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .start = 107,
++ .flags = IORESOURCE_IRQ,
++ },
++ [3] = {
++ .start = 108,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device gio4_device = {
++ .name = "em_gio",
++ .id = 4,
++ .resource = gio4_resources,
++ .num_resources = ARRAY_SIZE(gio4_resources),
++ .dev = {
++ .platform_data = &gio4_config,
++ },
++};
++
+ static struct platform_device *emev2_early_devices[] __initdata = {
+ &uart0_device,
+ &uart1_device,
+@@ -165,6 +363,11 @@ static struct platform_device *emev2_early_devices[] __initdata = {
+
+ static struct platform_device *emev2_late_devices[] __initdata = {
+ &sti_device,
++ &gio0_device,
++ &gio1_device,
++ &gio2_device,
++ &gio3_device,
++ &gio4_device,
+ };
+
+ void __init emev2_add_standard_devices(void)
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/mach-shmobile-emma-mobile-ev2-smp-support-v3.patch b/patches.kzm9d/mach-shmobile-emma-mobile-ev2-smp-support-v3.patch
new file mode 100644
index 00000000000000..edaa931cc8ed4a
--- /dev/null
+++ b/patches.kzm9d/mach-shmobile-emma-mobile-ev2-smp-support-v3.patch
@@ -0,0 +1,340 @@
+From koba@kmckk.co.jp Wed Oct 3 04:29:51 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:12 +0900
+Subject: [PATCH 20/26] mach-shmobile: Emma Mobile EV2 SMP support V3
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, "Rafael J. Wysocki" <rjw@sisk.pl>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-21-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+This is V3 of Emma Mobile EV2 SMP support.
+
+At this point only the most basic form of SMP operation
+is supported. TWD and CPU Hotplug support is excluded.
+
+Tied to both the Emma Mobile EV2 and the KZM9D board
+due to the need to switch on board in platsmp.c and
+the newly introduced need for static mappings.
+
+The static mappings are needed to allow hardware
+acces early during boot when SMP is initialized.
+This early requirement forces us to also map in
+the SMU registers.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit bd5a875d90c878be4d23f54ea565253734ae2377)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ arch/arm/mach-shmobile/Makefile | 1 +
+ arch/arm/mach-shmobile/board-kzm9d.c | 1 +
+ arch/arm/mach-shmobile/clock-emev2.c | 18 +++++
+ arch/arm/mach-shmobile/include/mach/emev2.h | 7 ++
+ arch/arm/mach-shmobile/platsmp.c | 17 +++++
+ arch/arm/mach-shmobile/setup-emev2.c | 24 +++++++
+ arch/arm/mach-shmobile/smp-emev2.c | 97 +++++++++++++++++++++++++++
+ 7 files changed, 165 insertions(+)
+ create mode 100644 arch/arm/mach-shmobile/smp-emev2.c
+
+diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
+index 2e6ff96..a93bcf0 100644
+--- a/arch/arm/mach-shmobile/Makefile
++++ b/arch/arm/mach-shmobile/Makefile
+@@ -19,6 +19,7 @@ smp-y := platsmp.o headsmp.o
+ smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+ smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o
+ smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o
++smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o
+
+ # Pinmux setup
+ pfc-y :=
+diff --git a/arch/arm/mach-shmobile/board-kzm9d.c b/arch/arm/mach-shmobile/board-kzm9d.c
+index e743f90..42fc479 100644
+--- a/arch/arm/mach-shmobile/board-kzm9d.c
++++ b/arch/arm/mach-shmobile/board-kzm9d.c
+@@ -27,6 +27,7 @@
+ #include <asm/hardware/gic.h>
+
+ MACHINE_START(KZM9D, "kzm9d")
++ .map_io = emev2_map_io,
+ .init_early = emev2_add_early_devices,
+ .nr_irqs = NR_IRQS_LEGACY,
+ .init_irq = emev2_init_irq,
+diff --git a/arch/arm/mach-shmobile/clock-emev2.c b/arch/arm/mach-shmobile/clock-emev2.c
+index 73a1216..5bc97de 100644
+--- a/arch/arm/mach-shmobile/clock-emev2.c
++++ b/arch/arm/mach-shmobile/clock-emev2.c
+@@ -40,6 +40,7 @@
+ #define USIB2SCLKDIV 0x65c
+ #define USIB3SCLKDIV 0x660
+ #define STI_CLKSEL 0x688
++#define SMU_GENERAL_REG0 0x7c0
+
+ /* not pretty, but hey */
+ static void __iomem *smu_base;
+@@ -50,6 +51,11 @@ static void emev2_smu_write(unsigned long value, int offs)
+ iowrite32(value, smu_base + offs);
+ }
+
++void emev2_set_boot_vector(unsigned long value)
++{
++ emev2_smu_write(value, SMU_GENERAL_REG0);
++}
++
+ static struct clk_mapping smu_mapping = {
+ .phys = EMEV2_SMU_BASE,
+ .len = PAGE_SIZE,
+@@ -194,6 +200,18 @@ static struct clk_lookup lookups[] = {
+ void __init emev2_clock_init(void)
+ {
+ int k, ret = 0;
++ static int is_setup;
++
++ /* yuck, this is ugly as hell, but the non-smp case of clocks
++ * code is now designed to rely on ioremap() instead of static
++ * entity maps. in the case of smp we need access to the SMU
++ * register earlier than ioremap() is actually working without
++ * any static maps. to enable SMP in ugly but with dynamic
++ * mappings we have to call emev2_clock_init() from different
++ * places depending on UP and SMP...
++ */
++ if (is_setup++)
++ return;
+
+ smu_base = ioremap(EMEV2_SMU_BASE, PAGE_SIZE);
+ BUG_ON(!smu_base);
+diff --git a/arch/arm/mach-shmobile/include/mach/emev2.h b/arch/arm/mach-shmobile/include/mach/emev2.h
+index 92646c1..3fc7184 100644
+--- a/arch/arm/mach-shmobile/include/mach/emev2.h
++++ b/arch/arm/mach-shmobile/include/mach/emev2.h
+@@ -1,9 +1,16 @@
+ #ifndef __ASM_EMEV2_H__
+ #define __ASM_EMEV2_H__
+
++extern void emev2_map_io(void);
+ extern void emev2_init_irq(void);
+ extern void emev2_add_early_devices(void);
+ extern void emev2_add_standard_devices(void);
+ extern void emev2_clock_init(void);
++extern void emev2_set_boot_vector(unsigned long value);
++extern unsigned int emev2_get_core_count(void);
++extern int emev2_platform_cpu_kill(unsigned int cpu);
++extern void emev2_secondary_init(unsigned int cpu);
++extern int emev2_boot_secondary(unsigned int cpu);
++extern void emev2_smp_prepare_cpus(void);
+
+ #endif /* __ASM_EMEV2_H__ */
+diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
+index 932ac8f..af24bbd 100644
+--- a/arch/arm/mach-shmobile/platsmp.c
++++ b/arch/arm/mach-shmobile/platsmp.c
+@@ -20,6 +20,7 @@
+ #include <asm/hardware/gic.h>
+ #include <asm/mach-types.h>
+ #include <mach/common.h>
++#include <mach/emev2.h>
+
+ #ifdef CONFIG_ARCH_SH73A0
+ #define is_sh73a0() (machine_is_ag5evm() || machine_is_kota2() || \
+@@ -29,6 +30,7 @@
+ #endif
+
+ #define is_r8a7779() machine_is_marzen()
++#define is_emev2() machine_is_kzm9d()
+
+ static unsigned int __init shmobile_smp_get_core_count(void)
+ {
+@@ -38,6 +40,9 @@ static unsigned int __init shmobile_smp_get_core_count(void)
+ if (is_r8a7779())
+ return r8a7779_get_core_count();
+
++ if (is_emev2())
++ return emev2_get_core_count();
++
+ return 1;
+ }
+
+@@ -48,6 +53,9 @@ static void __init shmobile_smp_prepare_cpus(void)
+
+ if (is_r8a7779())
+ r8a7779_smp_prepare_cpus();
++
++ if (is_emev2())
++ emev2_smp_prepare_cpus();
+ }
+
+ int shmobile_platform_cpu_kill(unsigned int cpu)
+@@ -55,6 +63,9 @@ int shmobile_platform_cpu_kill(unsigned int cpu)
+ if (is_r8a7779())
+ return r8a7779_platform_cpu_kill(cpu);
+
++ if (is_emev2())
++ return emev2_platform_cpu_kill(cpu);
++
+ return 1;
+ }
+
+@@ -67,6 +78,9 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
+
+ if (is_r8a7779())
+ r8a7779_secondary_init(cpu);
++
++ if (is_emev2())
++ emev2_secondary_init(cpu);
+ }
+
+ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+@@ -77,6 +91,9 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+ if (is_r8a7779())
+ return r8a7779_boot_secondary(cpu);
+
++ if (is_emev2())
++ return emev2_boot_secondary(cpu);
++
+ return -ENOSYS;
+ }
+
+diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c
+index 9fff623..2a03a78 100644
+--- a/arch/arm/mach-shmobile/setup-emev2.c
++++ b/arch/arm/mach-shmobile/setup-emev2.c
+@@ -34,6 +34,30 @@
+ #include <asm/mach/time.h>
+ #include <asm/hardware/gic.h>
+
++static struct map_desc emev2_io_desc[] __initdata = {
++#ifdef CONFIG_SMP
++ /* 128K entity map for 0xe0100000 (SMU) */
++ {
++ .virtual = 0xe0100000,
++ .pfn = __phys_to_pfn(0xe0100000),
++ .length = SZ_128K,
++ .type = MT_DEVICE
++ },
++ /* 2M mapping for SCU + L2 controller */
++ {
++ .virtual = 0xf0000000,
++ .pfn = __phys_to_pfn(0x1e000000),
++ .length = SZ_2M,
++ .type = MT_DEVICE
++ },
++#endif
++};
++
++void __init emev2_map_io(void)
++{
++ iotable_init(emev2_io_desc, ARRAY_SIZE(emev2_io_desc));
++}
++
+ /* UART */
+ static struct resource uart0_resources[] = {
+ [0] = {
+diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c
+new file mode 100644
+index 0000000..6a35c4a
+--- /dev/null
++++ b/arch/arm/mach-shmobile/smp-emev2.c
+@@ -0,0 +1,97 @@
++/*
++ * SMP support for Emma Mobile EV2
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ * Copyright (C) 2012 Magnus Damm
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/smp.h>
++#include <linux/spinlock.h>
++#include <linux/io.h>
++#include <linux/delay.h>
++#include <mach/common.h>
++#include <mach/emev2.h>
++#include <asm/smp_plat.h>
++#include <asm/smp_scu.h>
++#include <asm/hardware/gic.h>
++#include <asm/cacheflush.h>
++
++#define EMEV2_SCU_BASE 0x1e000000
++
++static DEFINE_SPINLOCK(scu_lock);
++static void __iomem *scu_base;
++
++static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
++{
++ unsigned long tmp;
++
++ /* we assume this code is running on a different cpu
++ * than the one that is changing coherency setting */
++ spin_lock(&scu_lock);
++ tmp = readl(scu_base + 8);
++ tmp &= ~clr;
++ tmp |= set;
++ writel(tmp, scu_base + 8);
++ spin_unlock(&scu_lock);
++
++}
++
++unsigned int __init emev2_get_core_count(void)
++{
++ if (!scu_base) {
++ scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE);
++ emev2_clock_init(); /* need ioremapped SMU */
++ }
++
++ WARN_ON_ONCE(!scu_base);
++
++ return scu_base ? scu_get_core_count(scu_base) : 1;
++}
++
++int emev2_platform_cpu_kill(unsigned int cpu)
++{
++ return 0; /* not supported yet */
++}
++
++void __cpuinit emev2_secondary_init(unsigned int cpu)
++{
++ gic_secondary_init(0);
++}
++
++int __cpuinit emev2_boot_secondary(unsigned int cpu)
++{
++ cpu = cpu_logical_map(cpu);
++
++ /* enable cache coherency */
++ modify_scu_cpu_psr(0, 3 << (cpu * 8));
++
++ /* Tell ROM loader about our vector (in headsmp.S) */
++ emev2_set_boot_vector(__pa(shmobile_secondary_vector));
++
++ gic_raise_softirq(cpumask_of(cpu), 1);
++ return 0;
++}
++
++void __init emev2_smp_prepare_cpus(void)
++{
++ int cpu = cpu_logical_map(0);
++
++ scu_enable(scu_base);
++
++ /* enable cache coherency on CPU0 */
++ modify_scu_cpu_psr(0, 3 << (cpu * 8));
++}
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/mach-shmobile-emma-mobile-ev2-soc-base-support-v3.patch b/patches.kzm9d/mach-shmobile-emma-mobile-ev2-soc-base-support-v3.patch
new file mode 100644
index 00000000000000..5e5996ce333fd0
--- /dev/null
+++ b/patches.kzm9d/mach-shmobile-emma-mobile-ev2-soc-base-support-v3.patch
@@ -0,0 +1,495 @@
+From koba@kmckk.co.jp Wed Oct 3 04:29:27 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:10 +0900
+Subject: [PATCH 18/26] mach-shmobile: Emma Mobile EV2 SoC base support V3
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, "Rafael J. Wysocki" <rjw@sisk.pl>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-19-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+This is V3 of the Emma Mobile EV2 SoC support.
+Included here is support for serial and timer
+devices which is just about enough to boot a kernel.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 7f627f0380cb5ba3e05bcaac31ecf40c1f508ec1)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ arch/arm/mach-shmobile/Kconfig | 5 +
+ arch/arm/mach-shmobile/Makefile | 1 +
+ arch/arm/mach-shmobile/clock-emev2.c | 226 +++++++++++++++++++++++++++
+ arch/arm/mach-shmobile/include/mach/emev2.h | 9 ++
+ arch/arm/mach-shmobile/setup-emev2.c | 180 +++++++++++++++++++++
+ 5 files changed, 421 insertions(+)
+ create mode 100644 arch/arm/mach-shmobile/clock-emev2.c
+ create mode 100644 arch/arm/mach-shmobile/include/mach/emev2.h
+ create mode 100644 arch/arm/mach-shmobile/setup-emev2.c
+
+diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
+index 80b64c5..3031ff8 100644
+--- a/arch/arm/mach-shmobile/Kconfig
++++ b/arch/arm/mach-shmobile/Kconfig
+@@ -41,6 +41,11 @@ config ARCH_R8A7779
+ select ARM_GIC
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+
++config ARCH_EMEV2
++ bool "Emma Mobile EV2"
++ select CPU_V7
++ select ARM_GIC
++
+ comment "SH-Mobile Board Type"
+
+ config MACH_G3EVM
+diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
+index 015c2d4..91f4470 100644
+--- a/arch/arm/mach-shmobile/Makefile
++++ b/arch/arm/mach-shmobile/Makefile
+@@ -12,6 +12,7 @@ obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o
+ obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o clock-sh73a0.o intc-sh73a0.o
+ obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o clock-r8a7740.o intc-r8a7740.o
+ obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o clock-r8a7779.o intc-r8a7779.o
++obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o clock-emev2.o
+
+ # SMP objects
+ smp-y := platsmp.o headsmp.o
+diff --git a/arch/arm/mach-shmobile/clock-emev2.c b/arch/arm/mach-shmobile/clock-emev2.c
+new file mode 100644
+index 0000000..73a1216
+--- /dev/null
++++ b/arch/arm/mach-shmobile/clock-emev2.c
+@@ -0,0 +1,226 @@
++/*
++ * Emma Mobile EV2 clock framework support
++ *
++ * Copyright (C) 2012 Magnus Damm
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/io.h>
++#include <linux/sh_clk.h>
++#include <linux/clkdev.h>
++#include <mach/common.h>
++
++#define EMEV2_SMU_BASE 0xe0110000
++
++/* EMEV2 SMU registers */
++#define USIAU0_RSTCTRL 0x094
++#define USIBU1_RSTCTRL 0x0ac
++#define USIBU2_RSTCTRL 0x0b0
++#define USIBU3_RSTCTRL 0x0b4
++#define STI_RSTCTRL 0x124
++#define USIAU0GCLKCTRL 0x4a0
++#define USIBU1GCLKCTRL 0x4b8
++#define USIBU2GCLKCTRL 0x4bc
++#define USIBU3GCLKCTRL 0x04c0
++#define STIGCLKCTRL 0x528
++#define USIAU0SCLKDIV 0x61c
++#define USIB2SCLKDIV 0x65c
++#define USIB3SCLKDIV 0x660
++#define STI_CLKSEL 0x688
++
++/* not pretty, but hey */
++static void __iomem *smu_base;
++
++static void emev2_smu_write(unsigned long value, int offs)
++{
++ BUG_ON(!smu_base || (offs >= PAGE_SIZE));
++ iowrite32(value, smu_base + offs);
++}
++
++static struct clk_mapping smu_mapping = {
++ .phys = EMEV2_SMU_BASE,
++ .len = PAGE_SIZE,
++};
++
++/* Fixed 32 KHz root clock from C32K pin */
++static struct clk c32k_clk = {
++ .rate = 32768,
++ .mapping = &smu_mapping,
++};
++
++/* PLL3 multiplies C32K with 7000 */
++static unsigned long pll3_recalc(struct clk *clk)
++{
++ return clk->parent->rate * 7000;
++}
++
++static struct sh_clk_ops pll3_clk_ops = {
++ .recalc = pll3_recalc,
++};
++
++static struct clk pll3_clk = {
++ .ops = &pll3_clk_ops,
++ .parent = &c32k_clk,
++};
++
++static struct clk *main_clks[] = {
++ &c32k_clk,
++ &pll3_clk,
++};
++
++enum { SCLKDIV_USIAU0, SCLKDIV_USIBU2, SCLKDIV_USIBU1, SCLKDIV_USIBU3,
++ SCLKDIV_NR };
++
++#define SCLKDIV(_reg, _shift) \
++{ \
++ .parent = &pll3_clk, \
++ .enable_reg = IOMEM(EMEV2_SMU_BASE + (_reg)), \
++ .enable_bit = _shift, \
++}
++
++static struct clk sclkdiv_clks[SCLKDIV_NR] = {
++ [SCLKDIV_USIAU0] = SCLKDIV(USIAU0SCLKDIV, 0),
++ [SCLKDIV_USIBU2] = SCLKDIV(USIB2SCLKDIV, 16),
++ [SCLKDIV_USIBU1] = SCLKDIV(USIB2SCLKDIV, 0),
++ [SCLKDIV_USIBU3] = SCLKDIV(USIB3SCLKDIV, 0),
++};
++
++enum { GCLK_USIAU0_SCLK, GCLK_USIBU1_SCLK, GCLK_USIBU2_SCLK, GCLK_USIBU3_SCLK,
++ GCLK_STI_SCLK,
++ GCLK_NR };
++
++#define GCLK_SCLK(_parent, _reg) \
++{ \
++ .parent = _parent, \
++ .enable_reg = IOMEM(EMEV2_SMU_BASE + (_reg)), \
++ .enable_bit = 1, /* SCLK_GCC */ \
++}
++
++static struct clk gclk_clks[GCLK_NR] = {
++ [GCLK_USIAU0_SCLK] = GCLK_SCLK(&sclkdiv_clks[SCLKDIV_USIAU0],
++ USIAU0GCLKCTRL),
++ [GCLK_USIBU1_SCLK] = GCLK_SCLK(&sclkdiv_clks[SCLKDIV_USIBU1],
++ USIBU1GCLKCTRL),
++ [GCLK_USIBU2_SCLK] = GCLK_SCLK(&sclkdiv_clks[SCLKDIV_USIBU2],
++ USIBU2GCLKCTRL),
++ [GCLK_USIBU3_SCLK] = GCLK_SCLK(&sclkdiv_clks[SCLKDIV_USIBU3],
++ USIBU3GCLKCTRL),
++ [GCLK_STI_SCLK] = GCLK_SCLK(&c32k_clk, STIGCLKCTRL),
++};
++
++static int emev2_gclk_enable(struct clk *clk)
++{
++ iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit),
++ clk->mapped_reg);
++ return 0;
++}
++
++static void emev2_gclk_disable(struct clk *clk)
++{
++ iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
++ clk->mapped_reg);
++}
++
++static struct sh_clk_ops emev2_gclk_clk_ops = {
++ .enable = emev2_gclk_enable,
++ .disable = emev2_gclk_disable,
++ .recalc = followparent_recalc,
++};
++
++static int __init emev2_gclk_register(struct clk *clks, int nr)
++{
++ struct clk *clkp;
++ int ret = 0;
++ int k;
++
++ for (k = 0; !ret && (k < nr); k++) {
++ clkp = clks + k;
++ clkp->ops = &emev2_gclk_clk_ops;
++ ret |= clk_register(clkp);
++ }
++
++ return ret;
++}
++
++static unsigned long emev2_sclkdiv_recalc(struct clk *clk)
++{
++ unsigned int sclk_div;
++
++ sclk_div = (ioread32(clk->mapped_reg) >> clk->enable_bit) & 0xff;
++
++ return clk->parent->rate / (sclk_div + 1);
++}
++
++static struct sh_clk_ops emev2_sclkdiv_clk_ops = {
++ .recalc = emev2_sclkdiv_recalc,
++};
++
++static int __init emev2_sclkdiv_register(struct clk *clks, int nr)
++{
++ struct clk *clkp;
++ int ret = 0;
++ int k;
++
++ for (k = 0; !ret && (k < nr); k++) {
++ clkp = clks + k;
++ clkp->ops = &emev2_sclkdiv_clk_ops;
++ ret |= clk_register(clkp);
++ }
++
++ return ret;
++}
++
++static struct clk_lookup lookups[] = {
++ CLKDEV_DEV_ID("serial8250-em.0", &gclk_clks[GCLK_USIAU0_SCLK]),
++ CLKDEV_DEV_ID("serial8250-em.1", &gclk_clks[GCLK_USIBU1_SCLK]),
++ CLKDEV_DEV_ID("serial8250-em.2", &gclk_clks[GCLK_USIBU2_SCLK]),
++ CLKDEV_DEV_ID("serial8250-em.3", &gclk_clks[GCLK_USIBU3_SCLK]),
++ CLKDEV_DEV_ID("em_sti.0", &gclk_clks[GCLK_STI_SCLK]),
++};
++
++void __init emev2_clock_init(void)
++{
++ int k, ret = 0;
++
++ smu_base = ioremap(EMEV2_SMU_BASE, PAGE_SIZE);
++ BUG_ON(!smu_base);
++
++ /* setup STI timer to run on 37.768 kHz and deassert reset */
++ emev2_smu_write(0, STI_CLKSEL);
++ emev2_smu_write(1, STI_RSTCTRL);
++
++ /* deassert reset for UART0->UART3 */
++ emev2_smu_write(2, USIAU0_RSTCTRL);
++ emev2_smu_write(2, USIBU1_RSTCTRL);
++ emev2_smu_write(2, USIBU2_RSTCTRL);
++ emev2_smu_write(2, USIBU3_RSTCTRL);
++
++ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
++ ret = clk_register(main_clks[k]);
++
++ if (!ret)
++ ret = emev2_sclkdiv_register(sclkdiv_clks, SCLKDIV_NR);
++
++ if (!ret)
++ ret = emev2_gclk_register(gclk_clks, GCLK_NR);
++
++ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
++
++ if (!ret)
++ shmobile_clk_init();
++ else
++ panic("failed to setup emev2 clocks\n");
++}
+diff --git a/arch/arm/mach-shmobile/include/mach/emev2.h b/arch/arm/mach-shmobile/include/mach/emev2.h
+new file mode 100644
+index 0000000..92646c1
+--- /dev/null
++++ b/arch/arm/mach-shmobile/include/mach/emev2.h
+@@ -0,0 +1,9 @@
++#ifndef __ASM_EMEV2_H__
++#define __ASM_EMEV2_H__
++
++extern void emev2_init_irq(void);
++extern void emev2_add_early_devices(void);
++extern void emev2_add_standard_devices(void);
++extern void emev2_clock_init(void);
++
++#endif /* __ASM_EMEV2_H__ */
+diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c
+new file mode 100644
+index 0000000..9fff623
+--- /dev/null
++++ b/arch/arm/mach-shmobile/setup-emev2.c
+@@ -0,0 +1,180 @@
++/*
++ * Emma Mobile EV2 processor support
++ *
++ * Copyright (C) 2012 Magnus Damm
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/input.h>
++#include <linux/io.h>
++#include <mach/hardware.h>
++#include <mach/common.h>
++#include <mach/emev2.h>
++#include <mach/irqs.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <asm/mach/time.h>
++#include <asm/hardware/gic.h>
++
++/* UART */
++static struct resource uart0_resources[] = {
++ [0] = {
++ .start = 0xe1020000,
++ .end = 0xe1020037,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = 40,
++ .flags = IORESOURCE_IRQ,
++ }
++};
++
++static struct platform_device uart0_device = {
++ .name = "serial8250-em",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(uart0_resources),
++ .resource = uart0_resources,
++};
++
++static struct resource uart1_resources[] = {
++ [0] = {
++ .start = 0xe1030000,
++ .end = 0xe1030037,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = 41,
++ .flags = IORESOURCE_IRQ,
++ }
++};
++
++static struct platform_device uart1_device = {
++ .name = "serial8250-em",
++ .id = 1,
++ .num_resources = ARRAY_SIZE(uart1_resources),
++ .resource = uart1_resources,
++};
++
++static struct resource uart2_resources[] = {
++ [0] = {
++ .start = 0xe1040000,
++ .end = 0xe1040037,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = 42,
++ .flags = IORESOURCE_IRQ,
++ }
++};
++
++static struct platform_device uart2_device = {
++ .name = "serial8250-em",
++ .id = 2,
++ .num_resources = ARRAY_SIZE(uart2_resources),
++ .resource = uart2_resources,
++};
++
++static struct resource uart3_resources[] = {
++ [0] = {
++ .start = 0xe1050000,
++ .end = 0xe1050037,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = 43,
++ .flags = IORESOURCE_IRQ,
++ }
++};
++
++static struct platform_device uart3_device = {
++ .name = "serial8250-em",
++ .id = 3,
++ .num_resources = ARRAY_SIZE(uart3_resources),
++ .resource = uart3_resources,
++};
++
++/* STI */
++static struct resource sti_resources[] = {
++ [0] = {
++ .name = "STI",
++ .start = 0xe0180000,
++ .end = 0xe0180053,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = 157,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device sti_device = {
++ .name = "em_sti",
++ .id = 0,
++ .resource = sti_resources,
++ .num_resources = ARRAY_SIZE(sti_resources),
++};
++
++static struct platform_device *emev2_early_devices[] __initdata = {
++ &uart0_device,
++ &uart1_device,
++ &uart2_device,
++ &uart3_device,
++};
++
++static struct platform_device *emev2_late_devices[] __initdata = {
++ &sti_device,
++};
++
++void __init emev2_add_standard_devices(void)
++{
++ emev2_clock_init();
++
++ platform_add_devices(emev2_early_devices,
++ ARRAY_SIZE(emev2_early_devices));
++
++ platform_add_devices(emev2_late_devices,
++ ARRAY_SIZE(emev2_late_devices));
++}
++
++void __init emev2_add_early_devices(void)
++{
++ shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */
++
++ early_platform_add_devices(emev2_early_devices,
++ ARRAY_SIZE(emev2_early_devices));
++
++ /* setup early console here as well */
++ shmobile_setup_console();
++}
++
++void __init emev2_init_irq(void)
++{
++ void __iomem *gic_dist_base;
++ void __iomem *gic_cpu_base;
++
++ /* Static mappings, never released */
++ gic_dist_base = ioremap(0xe0028000, PAGE_SIZE);
++ gic_cpu_base = ioremap(0xe0020000, PAGE_SIZE);
++ BUG_ON(!gic_dist_base || !gic_cpu_base);
++
++ /* Use GIC to handle interrupts */
++ gic_init(0, 29, gic_dist_base, gic_cpu_base);
++}
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/mach-shmobile-kzm9d-board-ethernet-support-v3.patch b/patches.kzm9d/mach-shmobile-kzm9d-board-ethernet-support-v3.patch
new file mode 100644
index 00000000000000..848f59f860aacd
--- /dev/null
+++ b/patches.kzm9d/mach-shmobile-kzm9d-board-ethernet-support-v3.patch
@@ -0,0 +1,93 @@
+From koba@kmckk.co.jp Wed Oct 3 04:30:07 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:14 +0900
+Subject: [PATCH 22/26] mach-shmobile: KZM9D board Ethernet support V3
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, "Rafael J. Wysocki" <rjw@sisk.pl>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-23-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+Tie in the on-board Ethernet controller on KZM9D
+and make use of the GPIO controller for external
+IRQ pin support.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 0c73f7bc124e1657a583d9dfb0d168a69005e2d3)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ arch/arm/mach-shmobile/board-kzm9d.c | 44 +++++++++++++++++++++++++++++++++-
+ 1 file changed, 43 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/board-kzm9d.c b/arch/arm/mach-shmobile/board-kzm9d.c
+index 42fc479..be81f0f 100644
+--- a/arch/arm/mach-shmobile/board-kzm9d.c
++++ b/arch/arm/mach-shmobile/board-kzm9d.c
+@@ -20,18 +20,60 @@
+
+ #include <linux/kernel.h>
+ #include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/smsc911x.h>
+ #include <mach/common.h>
+ #include <mach/emev2.h>
+ #include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
+ #include <asm/hardware/gic.h>
+
++/* Ether */
++static struct resource smsc911x_resources[] = {
++ [0] = {
++ .start = 0x20000000,
++ .end = 0x2000ffff,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = EMEV2_GPIO_IRQ(1),
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ },
++};
++
++static struct smsc911x_platform_config smsc911x_platdata = {
++ .flags = SMSC911X_USE_32BIT,
++ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
++ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
++};
++
++static struct platform_device smsc91x_device = {
++ .name = "smsc911x",
++ .id = 0,
++ .dev = {
++ .platform_data = &smsc911x_platdata,
++ },
++ .num_resources = ARRAY_SIZE(smsc911x_resources),
++ .resource = smsc911x_resources,
++};
++
++static struct platform_device *kzm9d_devices[] __initdata = {
++ &smsc91x_device,
++};
++
++void __init kzm9d_add_standard_devices(void)
++{
++ emev2_add_standard_devices();
++
++ platform_add_devices(kzm9d_devices, ARRAY_SIZE(kzm9d_devices));
++}
++
+ MACHINE_START(KZM9D, "kzm9d")
+ .map_io = emev2_map_io,
+ .init_early = emev2_add_early_devices,
+ .nr_irqs = NR_IRQS_LEGACY,
+ .init_irq = emev2_init_irq,
+ .handle_irq = gic_handle_irq,
+- .init_machine = emev2_add_standard_devices,
++ .init_machine = kzm9d_add_standard_devices,
+ .timer = &shmobile_timer,
+ MACHINE_END
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/mach-shmobile-kzm9d-board-support-v3.patch b/patches.kzm9d/mach-shmobile-kzm9d-board-support-v3.patch
new file mode 100644
index 00000000000000..74dd54724f6aa2
--- /dev/null
+++ b/patches.kzm9d/mach-shmobile-kzm9d-board-support-v3.patch
@@ -0,0 +1,92 @@
+From koba@kmckk.co.jp Wed Oct 3 04:29:37 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:11 +0900
+Subject: [PATCH 19/26] mach-shmobile: KZM9D board support V3
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, "Rafael J. Wysocki" <rjw@sisk.pl>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-20-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+V3 of basic KZM9D board support. At this point a quite
+thin layer that makes use of the Emma Mobile EV2 SoC code.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit c050fb10c425cf189da5ca9b84e948ec2fc99049)
+
+Conflicts:
+
+ arch/arm/mach-shmobile/Kconfig
+ arch/arm/mach-shmobile/Makefile
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ arch/arm/mach-shmobile/Kconfig | 4 +++
+ arch/arm/mach-shmobile/Makefile | 1
+ arch/arm/mach-shmobile/board-kzm9d.c | 36 +++++++++++++++++++++++++++++++++++
+ 3 files changed, 41 insertions(+)
+ create mode 100644 arch/arm/mach-shmobile/board-kzm9d.c
+
+--- a/arch/arm/mach-shmobile/Kconfig
++++ b/arch/arm/mach-shmobile/Kconfig
+@@ -112,6 +112,10 @@ config MACH_MARZEN
+ depends on ARCH_R8A7779
+ select ARCH_REQUIRE_GPIOLIB
+
++config MACH_KZM9D
++ bool "KZM9D board"
++ depends on ARCH_EMEV2
++
+ config MACH_KZM9G
+ bool "KZM-A9-GT board"
+ depends on ARCH_SH73A0
+--- a/arch/arm/mach-shmobile/Makefile
++++ b/arch/arm/mach-shmobile/Makefile
+@@ -53,6 +53,7 @@ obj-$(CONFIG_MACH_KOTA2) += board-kota2.
+ obj-$(CONFIG_MACH_BONITO) += board-bonito.o
+ obj-$(CONFIG_MACH_MARZEN) += board-marzen.o
+ obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o
++obj-$(CONFIG_MACH_KZM9D) += board-kzm9d.o
+ obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o
+
+ # Framework support
+--- /dev/null
++++ b/arch/arm/mach-shmobile/board-kzm9d.c
+@@ -0,0 +1,36 @@
++/*
++ * kzm9d board support
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ * Copyright (C) 2012 Magnus Damm
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <mach/common.h>
++#include <mach/emev2.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/hardware/gic.h>
++
++MACHINE_START(KZM9D, "kzm9d")
++ .init_early = emev2_add_early_devices,
++ .nr_irqs = NR_IRQS_LEGACY,
++ .init_irq = emev2_init_irq,
++ .handle_irq = gic_handle_irq,
++ .init_machine = emev2_add_standard_devices,
++ .timer = &shmobile_timer,
++MACHINE_END
diff --git a/patches.kzm9d/mach-shmobile-use-dt_machine-for-kzm9d-v3.patch b/patches.kzm9d/mach-shmobile-use-dt_machine-for-kzm9d-v3.patch
new file mode 100644
index 00000000000000..b126c0364650da
--- /dev/null
+++ b/patches.kzm9d/mach-shmobile-use-dt_machine-for-kzm9d-v3.patch
@@ -0,0 +1,103 @@
+From koba@kmckk.co.jp Wed Oct 3 04:30:29 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:17 +0900
+Subject: [PATCH 25/26] mach-shmobile: Use DT_MACHINE for KZM9D V3
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, "Rafael J. Wysocki" <rjw@sisk.pl>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-26-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+Use DT_MACHINE_START() on the emev2 based KZM9D board.
+
+Also include a tiny DTS file to describe the board and
+update the Kconfig dependencies to select CONFIG_USE_OF.
+
+Update the SMP glue code to use OF for matching.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 450cca47d65b7500ba05d56770adbf8c758dc87d)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ arch/arm/boot/dts/emev2-kzm9d.dts | 26 ++++++++++++++++++++++++++
+ arch/arm/mach-shmobile/Kconfig | 1 +
+ arch/arm/mach-shmobile/board-kzm9d.c | 8 +++++++-
+ arch/arm/mach-shmobile/platsmp.c | 2 +-
+ 4 files changed, 35 insertions(+), 2 deletions(-)
+ create mode 100644 arch/arm/boot/dts/emev2-kzm9d.dts
+
+--- /dev/null
++++ b/arch/arm/boot/dts/emev2-kzm9d.dts
+@@ -0,0 +1,26 @@
++/*
++ * Device Tree Source for the KZM9D board
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ *
++ * 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.
++ */
++/dts-v1/;
++
++/include/ "emev2.dtsi"
++
++/ {
++ model = "EMEV2 KZM9D Board";
++ compatible = "renesas,kzm9d", "renesas,emev2";
++
++ memory {
++ device_type = "memory";
++ reg = <0x40000000 0x8000000>;
++ };
++
++ chosen {
++ bootargs = "console=ttyS1,115200n81";
++ };
++};
+--- a/arch/arm/mach-shmobile/Kconfig
++++ b/arch/arm/mach-shmobile/Kconfig
+@@ -116,6 +116,7 @@ config MACH_MARZEN
+ config MACH_KZM9D
+ bool "KZM9D board"
+ depends on ARCH_EMEV2
++ select USE_OF
+
+ config MACH_KZM9G
+ bool "KZM-A9-GT board"
+--- a/arch/arm/mach-shmobile/board-kzm9d.c
++++ b/arch/arm/mach-shmobile/board-kzm9d.c
+@@ -68,7 +68,12 @@ void __init kzm9d_add_standard_devices(v
+ platform_add_devices(kzm9d_devices, ARRAY_SIZE(kzm9d_devices));
+ }
+
+-MACHINE_START(KZM9D, "kzm9d")
++static const char *kzm9d_boards_compat_dt[] __initdata = {
++ "renesas,kzm9d",
++ NULL,
++};
++
++DT_MACHINE_START(KZM9D_DT, "kzm9d")
+ .map_io = emev2_map_io,
+ .init_early = emev2_add_early_devices,
+ .nr_irqs = NR_IRQS_LEGACY,
+@@ -76,4 +81,5 @@ MACHINE_START(KZM9D, "kzm9d")
+ .handle_irq = gic_handle_irq,
+ .init_machine = kzm9d_add_standard_devices,
+ .timer = &shmobile_timer,
++ .dt_compat = kzm9d_boards_compat_dt,
+ MACHINE_END
+--- a/arch/arm/mach-shmobile/platsmp.c
++++ b/arch/arm/mach-shmobile/platsmp.c
+@@ -30,7 +30,7 @@
+ #endif
+
+ #define is_r8a7779() machine_is_marzen()
+-#define is_emev2() machine_is_kzm9d()
++#define is_emev2() of_machine_is_compatible("renesas,emev2")
+
+ static unsigned int __init shmobile_smp_get_core_count(void)
+ {
diff --git a/patches.kzm9d/serial-8250_pci-clear-fifos-for-intel-me-serial-over-lan-device-on-bi.patch b/patches.kzm9d/serial-8250_pci-clear-fifos-for-intel-me-serial-over-lan-device-on-bi.patch
new file mode 100644
index 00000000000000..60bbd30b0225bc
--- /dev/null
+++ b/patches.kzm9d/serial-8250_pci-clear-fifos-for-intel-me-serial-over-lan-device-on-bi.patch
@@ -0,0 +1,136 @@
+From koba@kmckk.co.jp Wed Oct 3 04:26:23 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:22:54 +0900
+Subject: [PATCH 02/26] serial/8250_pci: Clear FIFOs for Intel ME Serial Over Lan device on BI
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Sudhakar Mamillapalli <sudhakar@fb.com>, Nhan H Mai <nhan.h.mai@intel.com>, Dan Williams <dan.j.williams@intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-3-git-send-email-koba@kmckk.co.jp>
+
+
+From: Sudhakar Mamillapalli <sudhakar@fb.com>
+
+When using Serial Over Lan (SOL) over the virtual serial port in a Intel
+management engine (ME) device, on device reset the serial FIFOs need to
+be cleared to keep the FIFO indexes in-sync between the host and the
+engine.
+
+On a reset the serial device assertes BI, so using that as a cue FIFOs
+are cleared. So for this purpose a new handle_break callback has been
+added. One other problem is that the serial registers might temporarily
+go to 0 on reset of this device. So instead of using the IER register
+read, if 0 returned use the ier value in uart_8250_port. This is hidden
+under a custom serial_in.
+
+Cc: Nhan H Mai <nhan.h.mai@intel.com>
+Signed-off-by: Sudhakar Mamillapalli <sudhakar@fb.com>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+(cherry picked from commit 0ad372b962d109323d18ac2aa118b2ad100eb8dd)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ drivers/tty/serial/8250/8250.c | 10 +++++++++
+ drivers/tty/serial/8250/8250.h | 2 ++
+ drivers/tty/serial/8250/8250_pci.c | 39 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 51 insertions(+)
+
+diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
+index aed9363..c9ac4ea 100644
+--- a/drivers/tty/serial/8250/8250.c
++++ b/drivers/tty/serial/8250/8250.c
+@@ -568,6 +568,16 @@ static void serial8250_clear_fifos(struct uart_8250_port *p)
+ }
+ }
+
++void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p)
++{
++ unsigned char fcr;
++
++ serial8250_clear_fifos(p);
++ fcr = uart_config[p->port.type].fcr;
++ serial_out(p, UART_FCR, fcr);
++}
++EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos);
++
+ /*
+ * IER sleep support. UARTs which have EFRs need the "extended
+ * capability" bit enabled. Note that on XR16C850s, we need to
+diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
+index 2868a1d..c9d0ebe 100644
+--- a/drivers/tty/serial/8250/8250.h
++++ b/drivers/tty/serial/8250/8250.h
+@@ -96,6 +96,8 @@ static inline void serial_out(struct uart_8250_port *up, int offset, int value)
+ up->port.serial_out(&up->port, offset, value);
+ }
+
++void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p);
++
+ #if defined(__alpha__) && !defined(CONFIG_PCI)
+ /*
+ * Digital did something really horribly wrong with the OUT1 and OUT2
+diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
+index 3614973..5a4de9a 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -17,6 +17,7 @@
+ #include <linux/slab.h>
+ #include <linux/delay.h>
+ #include <linux/tty.h>
++#include <linux/serial_reg.h>
+ #include <linux/serial_core.h>
+ #include <linux/8250_pci.h>
+ #include <linux/bitops.h>
+@@ -1092,11 +1093,49 @@ static int skip_tx_en_setup(struct serial_private *priv,
+ return pci_default_setup(priv, board, port, idx);
+ }
+
++static void kt_handle_break(struct uart_port *p)
++{
++ struct uart_8250_port *up =
++ container_of(p, struct uart_8250_port, port);
++ /*
++ * On receipt of a BI, serial device in Intel ME (Intel
++ * management engine) needs to have its fifos cleared for sane
++ * SOL (Serial Over Lan) output.
++ */
++ serial8250_clear_and_reinit_fifos(up);
++}
++
++static unsigned int kt_serial_in(struct uart_port *p, int offset)
++{
++ struct uart_8250_port *up =
++ container_of(p, struct uart_8250_port, port);
++ unsigned int val;
++
++ /*
++ * When the Intel ME (management engine) gets reset its serial
++ * port registers could return 0 momentarily. Functions like
++ * serial8250_console_write, read and save the IER, perform
++ * some operation and then restore it. In order to avoid
++ * setting IER register inadvertently to 0, if the value read
++ * is 0, double check with ier value in uart_8250_port and use
++ * that instead. up->ier should be the same value as what is
++ * currently configured.
++ */
++ val = inb(p->iobase + offset);
++ if (offset == UART_IER) {
++ if (val == 0)
++ val = up->ier;
++ }
++ return val;
++}
++
+ static int kt_serial_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_port *port, int idx)
+ {
+ port->flags |= UPF_BUG_THRE;
++ port->serial_in = kt_serial_in;
++ port->handle_break = kt_handle_break;
+ return skip_tx_en_setup(priv, board, port, idx);
+ }
+
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/serial-8250_pci-fix-suspend-resume-vs-init-exit-quirks.patch b/patches.kzm9d/serial-8250_pci-fix-suspend-resume-vs-init-exit-quirks.patch
new file mode 100644
index 00000000000000..5b6e0aa2d36175
--- /dev/null
+++ b/patches.kzm9d/serial-8250_pci-fix-suspend-resume-vs-init-exit-quirks.patch
@@ -0,0 +1,85 @@
+From koba@kmckk.co.jp Wed Oct 3 04:26:47 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:22:55 +0900
+Subject: [PATCH 03/26] serial/8250_pci: fix suspend/resume vs init/exit quirks
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Dan Williams <dan.j.williams@intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-4-git-send-email-koba@kmckk.co.jp>
+
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+Commit e86ff4a6 "serial/8250_pci: init-quirk msi support for kt serial
+controller" introduced a regression in suspend/resume by causing msi's
+to be enabled twice without an intervening disable.
+
+00:16.3 Serial controller: Intel Corporation Patsburg KT Controller (rev 05) (prog-if 02 [16550])
+ Subsystem: Intel Corporation Device 7270
+ Flags: bus master, 66MHz, fast devsel, latency 0, IRQ 72
+ I/O ports at 4080 [size=8]
+ Memory at d1c30000 (32-bit, non-prefetchable) [size=4K]
+ Capabilities: [c8] Power Management version 3
+ Capabilities: [d0] MSI: Enable+ Count=1/1 Maskable- 64bit+
+ Kernel driver in use: serial
+
+[ 365.250523] sysfs: cannot create duplicate filename '/devices/pci0000:00/0000:00:16.3/msi_irqs'
+[ 365.250525] Modules linked in: nls_utf8 ipv6 uinput sg iTCO_wdt
+ iTCO_vendor_support ioatdma dca i2c_i801 i2c_core wmi sd_mod ahci libahci isci
+ libsas libata scsi_transport_sas [last unloaded: scsi_wait_scan]
+[ 365.250540] Pid: 9030, comm: kworker/u:1 Tainted: G W 3.3.0-isci-3.0.213+ #1
+[ 365.250542] Call Trace:
+[ 365.250545] [<ffffffff8115e955>] ? sysfs_add_one+0x99/0xad
+[ 365.250548] [<ffffffff8102db8b>] warn_slowpath_common+0x85/0x9e
+[ 365.250551] [<ffffffff8102dc96>] warn_slowpath_fmt+0x6e/0x70
+[ 365.250555] [<ffffffff8115e8fa>] ? sysfs_add_one+0x3e/0xad
+[ 365.250558] [<ffffffff8115e8b4>] ? sysfs_pathname+0x3c/0x44
+[ 365.250561] [<ffffffff8115e8b4>] ? sysfs_pathname+0x3c/0x44
+[ 365.250564] [<ffffffff8115e8b4>] ? sysfs_pathname+0x3c/0x44
+[ 365.250567] [<ffffffff8115e8b4>] ? sysfs_pathname+0x3c/0x44
+[ 365.250570] [<ffffffff8115e955>] sysfs_add_one+0x99/0xad
+[ 365.250573] [<ffffffff8115f031>] create_dir+0x72/0xa5
+[ 365.250577] [<ffffffff8115f194>] sysfs_create_dir+0xa2/0xbe
+[ 365.250581] [<ffffffff81262463>] kobject_add_internal+0x126/0x1f8
+[ 365.250585] [<ffffffff8126255b>] kset_register+0x26/0x3f
+[ 365.250588] [<ffffffff8126275a>] kset_create_and_add+0x62/0x7c
+[ 365.250592] [<ffffffff81293619>] populate_msi_sysfs+0x34/0x103
+[ 365.250595] [<ffffffff81293e1c>] pci_enable_msi_block+0x1b3/0x216
+[ 365.250599] [<ffffffff81303f7c>] try_enable_msi+0x13/0x17
+[ 365.250603] [<ffffffff81303fb3>] pciserial_resume_ports+0x21/0x42
+[ 365.250607] [<ffffffff81304041>] pciserial_resume_one+0x50/0x57
+[ 365.250610] [<ffffffff81283e1a>] pci_legacy_resume+0x38/0x47
+[ 365.250613] [<ffffffff81283e7d>] pci_pm_restore+0x54/0x87
+[ 365.250616] [<ffffffff81283e29>] ? pci_legacy_resume+0x47/0x47
+[ 365.250619] [<ffffffff8131e9e8>] dpm_run_callback+0x48/0x7b
+[ 365.250623] [<ffffffff8131f39a>] device_resume+0x342/0x394
+[ 365.250626] [<ffffffff8131f5b7>] async_resume+0x21/0x49
+
+That patch has since been reverted, but by inspection it seems that
+pciserial_suspend_ports() should be invoking .exit() quirks to release
+resources acquired during .init().
+
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+(cherry picked from commit 5f1a38952b7e932a1c169c28917b9a831f641bcc)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ drivers/tty/serial/8250/8250_pci.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -2834,6 +2834,12 @@ void pciserial_suspend_ports(struct seri
+ for (i = 0; i < priv->nr; i++)
+ if (priv->line[i] >= 0)
+ serial8250_suspend_port(priv->line[i]);
++
++ /*
++ * Ensure that every init quirk is properly torn down
++ */
++ if (priv->quirk->exit)
++ priv->quirk->exit(priv->dev);
+ }
+ EXPORT_SYMBOL_GPL(pciserial_suspend_ports);
+
diff --git a/patches.kzm9d/serial8250-add-dl_read-dl_write-callbacks.patch b/patches.kzm9d/serial8250-add-dl_read-dl_write-callbacks.patch
new file mode 100644
index 00000000000000..fb35a611b766ed
--- /dev/null
+++ b/patches.kzm9d/serial8250-add-dl_read-dl_write-callbacks.patch
@@ -0,0 +1,206 @@
+From koba@kmckk.co.jp Wed Oct 3 04:26:58 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:22:56 +0900
+Subject: [PATCH 04/26] serial8250: Add dl_read()/dl_write() callbacks
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-5-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+Convert serial_dl_read() and serial_dl_write() from macro
+to 8250 specific callbacks. This change makes it easier to
+support 8250 hardware with non-standard DLL and DLM register
+configurations such as Alchemy, RM9K and upcoming Emma Mobile
+UART hardware.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+(cherry picked from commit cc419fa0d38c425e4ea7bffeed931b07b0a3e461)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ drivers/tty/serial/8250/8250.c | 117 ++++++++++++++++++++++------------------
+ drivers/tty/serial/8250/8250.h | 14 +++++
+ 2 files changed, 78 insertions(+), 53 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
+index c9ac4ea..590ee85 100644
+--- a/drivers/tty/serial/8250/8250.c
++++ b/drivers/tty/serial/8250/8250.c
+@@ -284,6 +284,66 @@ static const struct serial8250_config uart_config[] = {
+ },
+ };
+
++/* Uart divisor latch read */
++static int default_dl_read(struct uart_8250_port *up)
++{
++ return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8;
++}
++
++/* Uart divisor latch write */
++static void default_dl_write(struct uart_8250_port *up, int value)
++{
++ serial_out(up, UART_DLL, value & 0xff);
++ serial_out(up, UART_DLM, value >> 8 & 0xff);
++}
++
++#if defined(CONFIG_MIPS_ALCHEMY)
++/* Au1x00 haven't got a standard divisor latch */
++static int _serial_dl_read(struct uart_8250_port *up)
++{
++ if (up->port.iotype == UPIO_AU)
++ return __raw_readl(up->port.membase + 0x28);
++ else
++ return default_dl_read(up);
++}
++
++static void _serial_dl_write(struct uart_8250_port *up, int value)
++{
++ if (up->port.iotype == UPIO_AU)
++ __raw_writel(value, up->port.membase + 0x28);
++ else
++ default_dl_write(up, value);
++}
++#elif defined(CONFIG_SERIAL_8250_RM9K)
++static int _serial_dl_read(struct uart_8250_port *up)
++{
++ return (up->port.iotype == UPIO_RM9000) ?
++ (((__raw_readl(up->port.membase + 0x10) << 8) |
++ (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
++ default_dl_read(up);
++}
++
++static void _serial_dl_write(struct uart_8250_port *up, int value)
++{
++ if (up->port.iotype == UPIO_RM9000) {
++ __raw_writel(value, up->port.membase + 0x08);
++ __raw_writel(value >> 8, up->port.membase + 0x10);
++ } else {
++ default_dl_write(up, value);
++ }
++}
++#else
++static int _serial_dl_read(struct uart_8250_port *up)
++{
++ return default_dl_read(up);
++}
++
++static void _serial_dl_write(struct uart_8250_port *up, int value)
++{
++ default_dl_write(up, value);
++}
++#endif
++
+ #if defined(CONFIG_MIPS_ALCHEMY)
+
+ /* Au1x00 UART hardware has a weird register layout */
+@@ -434,6 +494,10 @@ static void set_io_from_upio(struct uart_port *p)
+ {
+ struct uart_8250_port *up =
+ container_of(p, struct uart_8250_port, port);
++
++ up->dl_read = _serial_dl_read;
++ up->dl_write = _serial_dl_write;
++
+ switch (p->iotype) {
+ case UPIO_HUB6:
+ p->serial_in = hub6_serial_in;
+@@ -481,59 +545,6 @@ serial_port_out_sync(struct uart_port *p, int offset, int value)
+ }
+ }
+
+-/* Uart divisor latch read */
+-static inline int _serial_dl_read(struct uart_8250_port *up)
+-{
+- return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8;
+-}
+-
+-/* Uart divisor latch write */
+-static inline void _serial_dl_write(struct uart_8250_port *up, int value)
+-{
+- serial_out(up, UART_DLL, value & 0xff);
+- serial_out(up, UART_DLM, value >> 8 & 0xff);
+-}
+-
+-#if defined(CONFIG_MIPS_ALCHEMY)
+-/* Au1x00 haven't got a standard divisor latch */
+-static int serial_dl_read(struct uart_8250_port *up)
+-{
+- if (up->port.iotype == UPIO_AU)
+- return __raw_readl(up->port.membase + 0x28);
+- else
+- return _serial_dl_read(up);
+-}
+-
+-static void serial_dl_write(struct uart_8250_port *up, int value)
+-{
+- if (up->port.iotype == UPIO_AU)
+- __raw_writel(value, up->port.membase + 0x28);
+- else
+- _serial_dl_write(up, value);
+-}
+-#elif defined(CONFIG_SERIAL_8250_RM9K)
+-static int serial_dl_read(struct uart_8250_port *up)
+-{
+- return (up->port.iotype == UPIO_RM9000) ?
+- (((__raw_readl(up->port.membase + 0x10) << 8) |
+- (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
+- _serial_dl_read(up);
+-}
+-
+-static void serial_dl_write(struct uart_8250_port *up, int value)
+-{
+- if (up->port.iotype == UPIO_RM9000) {
+- __raw_writel(value, up->port.membase + 0x08);
+- __raw_writel(value >> 8, up->port.membase + 0x10);
+- } else {
+- _serial_dl_write(up, value);
+- }
+-}
+-#else
+-#define serial_dl_read(up) _serial_dl_read(up)
+-#define serial_dl_write(up, value) _serial_dl_write(up, value)
+-#endif
+-
+ /*
+ * For the 16C950
+ */
+diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
+index c9d0ebe..f9719d1 100644
+--- a/drivers/tty/serial/8250/8250.h
++++ b/drivers/tty/serial/8250/8250.h
+@@ -37,6 +37,10 @@ struct uart_8250_port {
+ unsigned char lsr_saved_flags;
+ #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
+ unsigned char msr_saved_flags;
++
++ /* 8250 specific callbacks */
++ int (*dl_read)(struct uart_8250_port *);
++ void (*dl_write)(struct uart_8250_port *, int);
+ };
+
+ struct old_serial_port {
+@@ -98,6 +102,16 @@ static inline void serial_out(struct uart_8250_port *up, int offset, int value)
+
+ void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p);
+
++static inline int serial_dl_read(struct uart_8250_port *up)
++{
++ return up->dl_read(up);
++}
++
++static inline void serial_dl_write(struct uart_8250_port *up, int value)
++{
++ up->dl_write(up, value);
++}
++
+ #if defined(__alpha__) && !defined(CONFIG_PCI)
+ /*
+ * Digital did something really horribly wrong with the OUT1 and OUT2
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/serial8250-clean-up-default-map-and-dl-code.patch b/patches.kzm9d/serial8250-clean-up-default-map-and-dl-code.patch
new file mode 100644
index 00000000000000..f1cbc6536d77fe
--- /dev/null
+++ b/patches.kzm9d/serial8250-clean-up-default-map-and-dl-code.patch
@@ -0,0 +1,140 @@
+From koba@kmckk.co.jp Wed Oct 3 04:27:25 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:22:59 +0900
+Subject: [PATCH 07/26] serial8250: Clean up default map and dl code
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-8-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+Get rid of unused functions and macros now when
+Alchemy and RM9K are converted over to callbacks.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+(cherry picked from commit e8155629ff19e05722ba057d1521baec270d780e)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ drivers/tty/serial/8250/8250.c | 38 ++++++++++++--------------------------
+ 1 file changed, 12 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
+index cc398b1..662188d 100644
+--- a/drivers/tty/serial/8250/8250.c
++++ b/drivers/tty/serial/8250/8250.c
+@@ -285,28 +285,18 @@ static const struct serial8250_config uart_config[] = {
+ };
+
+ /* Uart divisor latch read */
+-static int default_dl_read(struct uart_8250_port *up)
++static int default_serial_dl_read(struct uart_8250_port *up)
+ {
+ return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8;
+ }
+
+ /* Uart divisor latch write */
+-static void default_dl_write(struct uart_8250_port *up, int value)
++static void default_serial_dl_write(struct uart_8250_port *up, int value)
+ {
+ serial_out(up, UART_DLL, value & 0xff);
+ serial_out(up, UART_DLM, value >> 8 & 0xff);
+ }
+
+-static int _serial_dl_read(struct uart_8250_port *up)
+-{
+- return default_dl_read(up);
+-}
+-
+-static void _serial_dl_write(struct uart_8250_port *up, int value)
+-{
+- default_dl_write(up, value);
+-}
+-
+ #ifdef CONFIG_MIPS_ALCHEMY
+
+ /* Au1x00 UART hardware has a weird register layout */
+@@ -403,57 +393,53 @@ static void rm9k_serial_dl_write(struct uart_8250_port *up, int value)
+
+ #endif
+
+-/* sane hardware needs no mapping */
+-#define map_8250_in_reg(up, offset) (offset)
+-#define map_8250_out_reg(up, offset) (offset)
+-
+ static unsigned int hub6_serial_in(struct uart_port *p, int offset)
+ {
+- offset = map_8250_in_reg(p, offset) << p->regshift;
++ offset = offset << p->regshift;
+ outb(p->hub6 - 1 + offset, p->iobase);
+ return inb(p->iobase + 1);
+ }
+
+ static void hub6_serial_out(struct uart_port *p, int offset, int value)
+ {
+- offset = map_8250_out_reg(p, offset) << p->regshift;
++ offset = offset << p->regshift;
+ outb(p->hub6 - 1 + offset, p->iobase);
+ outb(value, p->iobase + 1);
+ }
+
+ static unsigned int mem_serial_in(struct uart_port *p, int offset)
+ {
+- offset = map_8250_in_reg(p, offset) << p->regshift;
++ offset = offset << p->regshift;
+ return readb(p->membase + offset);
+ }
+
+ static void mem_serial_out(struct uart_port *p, int offset, int value)
+ {
+- offset = map_8250_out_reg(p, offset) << p->regshift;
++ offset = offset << p->regshift;
+ writeb(value, p->membase + offset);
+ }
+
+ static void mem32_serial_out(struct uart_port *p, int offset, int value)
+ {
+- offset = map_8250_out_reg(p, offset) << p->regshift;
++ offset = offset << p->regshift;
+ writel(value, p->membase + offset);
+ }
+
+ static unsigned int mem32_serial_in(struct uart_port *p, int offset)
+ {
+- offset = map_8250_in_reg(p, offset) << p->regshift;
++ offset = offset << p->regshift;
+ return readl(p->membase + offset);
+ }
+
+ static unsigned int io_serial_in(struct uart_port *p, int offset)
+ {
+- offset = map_8250_in_reg(p, offset) << p->regshift;
++ offset = offset << p->regshift;
+ return inb(p->iobase + offset);
+ }
+
+ static void io_serial_out(struct uart_port *p, int offset, int value)
+ {
+- offset = map_8250_out_reg(p, offset) << p->regshift;
++ offset = offset << p->regshift;
+ outb(value, p->iobase + offset);
+ }
+
+@@ -464,8 +450,8 @@ static void set_io_from_upio(struct uart_port *p)
+ struct uart_8250_port *up =
+ container_of(p, struct uart_8250_port, port);
+
+- up->dl_read = _serial_dl_read;
+- up->dl_write = _serial_dl_write;
++ up->dl_read = default_serial_dl_read;
++ up->dl_write = default_serial_dl_write;
+
+ switch (p->iotype) {
+ case UPIO_HUB6:
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/serial8250-em-add-dt-support.patch b/patches.kzm9d/serial8250-em-add-dt-support.patch
new file mode 100644
index 00000000000000..98b908efcf3542
--- /dev/null
+++ b/patches.kzm9d/serial8250-em-add-dt-support.patch
@@ -0,0 +1,47 @@
+From koba@kmckk.co.jp Wed Oct 3 04:27:39 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:03 +0900
+Subject: [PATCH 11/26] serial8250-em: Add DT support
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-12-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+Update the 8250_em driver to support DT.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+(cherry picked from commit 3e62c413fb0c75c8cfaf086d00a9ecc6b55009d6)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ drivers/tty/serial/8250/8250_em.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c
+index be6c289..3a0363e 100644
+--- a/drivers/tty/serial/8250/8250_em.c
++++ b/drivers/tty/serial/8250/8250_em.c
+@@ -163,9 +163,16 @@ static int __devexit serial8250_em_remove(struct platform_device *pdev)
+ return 0;
+ }
+
++static const struct of_device_id serial8250_em_dt_ids[] __devinitconst = {
++ { .compatible = "renesas,em-uart", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, serial8250_em_dt_ids);
++
+ static struct platform_driver serial8250_em_platform_driver = {
+ .driver = {
+ .name = "serial8250-em",
++ .of_match_table = serial8250_em_dt_ids,
+ .owner = THIS_MODULE,
+ },
+ .probe = serial8250_em_probe,
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/serial8250-em-clk_get-is_err-error-handling-fix.patch b/patches.kzm9d/serial8250-em-clk_get-is_err-error-handling-fix.patch
new file mode 100644
index 00000000000000..340ffc59ac1c7c
--- /dev/null
+++ b/patches.kzm9d/serial8250-em-clk_get-is_err-error-handling-fix.patch
@@ -0,0 +1,44 @@
+From koba@kmckk.co.jp Wed Oct 3 04:27:34 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:02 +0900
+Subject: [PATCH 10/26] serial8250-em: clk_get() IS_ERR() error handling fix
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-11-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+Update the 8250_em driver to correctly handle the case
+where no clock is associated with the device.
+
+The return value of clk_get() needs to be checked with
+IS_ERR() to avoid NULL pointer referencing.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+(cherry picked from commit 94e792ab66d696aad2e52c91bae4cfbeefe4c9f6)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ drivers/tty/serial/8250/8250_em.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c
+index ff42542..be6c289 100644
+--- a/drivers/tty/serial/8250/8250_em.c
++++ b/drivers/tty/serial/8250/8250_em.c
+@@ -110,8 +110,9 @@ static int __devinit serial8250_em_probe(struct platform_device *pdev)
+ }
+
+ priv->sclk = clk_get(&pdev->dev, "sclk");
+- if (!priv->sclk) {
++ if (IS_ERR(priv->sclk)) {
+ dev_err(&pdev->dev, "unable to get clock\n");
++ ret = PTR_ERR(priv->sclk);
+ goto err1;
+ }
+
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/serial8250-em-emma-mobile-uart-driver-v2.patch b/patches.kzm9d/serial8250-em-emma-mobile-uart-driver-v2.patch
new file mode 100644
index 00000000000000..117636e6e33301
--- /dev/null
+++ b/patches.kzm9d/serial8250-em-emma-mobile-uart-driver-v2.patch
@@ -0,0 +1,256 @@
+From koba@kmckk.co.jp Wed Oct 3 04:27:32 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:01 +0900
+Subject: [PATCH 09/26] serial8250-em: Emma Mobile UART driver V2
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-10-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+This is V2 of the Emma Mobile 8250 platform driver.
+
+The hardware itself has according to the data sheet
+up to 64 byte FIFOs but at this point we only make
+use of the 16550 compatible mode.
+
+To support this piece of hardware the common UART
+registers need to be remapped, and the access size
+differences need to be handled.
+
+The DLL and DLM registers can due to offset collision
+not be remapped easily, and because of that this
+driver makes use of ->dl_read() and ->dl_write()
+callbacks. This in turn requires a registration
+function that takes 8250-specific paramenters.
+
+Future potential enhancements include DT support,
+early platform driver console and fine grained PM.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+(cherry picked from commit 22886ee96895b7a9f9d06da4dc9420b61b4ef1f7)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ drivers/tty/serial/8250/8250_em.c | 178 +++++++++++++++++++++++++++++++++++++
+ drivers/tty/serial/8250/Kconfig | 8 ++
+ drivers/tty/serial/8250/Makefile | 1 +
+ 3 files changed, 187 insertions(+)
+ create mode 100644 drivers/tty/serial/8250/8250_em.c
+
+diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c
+new file mode 100644
+index 0000000..ff42542
+--- /dev/null
++++ b/drivers/tty/serial/8250/8250_em.c
+@@ -0,0 +1,178 @@
++/*
++ * Renesas Emma Mobile 8250 driver
++ *
++ * Copyright (C) 2012 Magnus Damm
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/serial_8250.h>
++#include <linux/serial_core.h>
++#include <linux/serial_reg.h>
++#include <linux/platform_device.h>
++#include <linux/clk.h>
++#include <linux/slab.h>
++
++#include "8250.h"
++
++#define UART_DLL_EM 9
++#define UART_DLM_EM 10
++
++struct serial8250_em_priv {
++ struct clk *sclk;
++ int line;
++};
++
++static void serial8250_em_serial_out(struct uart_port *p, int offset, int value)
++{
++ switch (offset) {
++ case UART_TX: /* TX @ 0x00 */
++ writeb(value, p->membase);
++ break;
++ case UART_FCR: /* FCR @ 0x0c (+1) */
++ case UART_LCR: /* LCR @ 0x10 (+1) */
++ case UART_MCR: /* MCR @ 0x14 (+1) */
++ case UART_SCR: /* SCR @ 0x20 (+1) */
++ writel(value, p->membase + ((offset + 1) << 2));
++ break;
++ case UART_IER: /* IER @ 0x04 */
++ value &= 0x0f; /* only 4 valid bits - not Xscale */
++ /* fall-through */
++ case UART_DLL_EM: /* DLL @ 0x24 (+9) */
++ case UART_DLM_EM: /* DLM @ 0x28 (+9) */
++ writel(value, p->membase + (offset << 2));
++ }
++}
++
++static unsigned int serial8250_em_serial_in(struct uart_port *p, int offset)
++{
++ switch (offset) {
++ case UART_RX: /* RX @ 0x00 */
++ return readb(p->membase);
++ case UART_MCR: /* MCR @ 0x14 (+1) */
++ case UART_LSR: /* LSR @ 0x18 (+1) */
++ case UART_MSR: /* MSR @ 0x1c (+1) */
++ case UART_SCR: /* SCR @ 0x20 (+1) */
++ return readl(p->membase + ((offset + 1) << 2));
++ case UART_IER: /* IER @ 0x04 */
++ case UART_IIR: /* IIR @ 0x08 */
++ case UART_DLL_EM: /* DLL @ 0x24 (+9) */
++ case UART_DLM_EM: /* DLM @ 0x28 (+9) */
++ return readl(p->membase + (offset << 2));
++ }
++ return 0;
++}
++
++static int serial8250_em_serial_dl_read(struct uart_8250_port *up)
++{
++ return serial_in(up, UART_DLL_EM) | serial_in(up, UART_DLM_EM) << 8;
++}
++
++static void serial8250_em_serial_dl_write(struct uart_8250_port *up, int value)
++{
++ serial_out(up, UART_DLL_EM, value & 0xff);
++ serial_out(up, UART_DLM_EM, value >> 8 & 0xff);
++}
++
++static int __devinit serial8250_em_probe(struct platform_device *pdev)
++{
++ struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++ struct serial8250_em_priv *priv;
++ struct uart_8250_port up;
++ int ret = -EINVAL;
++
++ if (!regs || !irq) {
++ dev_err(&pdev->dev, "missing registers or irq\n");
++ goto err0;
++ }
++
++ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
++ if (!priv) {
++ dev_err(&pdev->dev, "unable to allocate private data\n");
++ ret = -ENOMEM;
++ goto err0;
++ }
++
++ priv->sclk = clk_get(&pdev->dev, "sclk");
++ if (!priv->sclk) {
++ dev_err(&pdev->dev, "unable to get clock\n");
++ goto err1;
++ }
++
++ memset(&up, 0, sizeof(up));
++ up.port.mapbase = regs->start;
++ up.port.irq = irq->start;
++ up.port.type = PORT_UNKNOWN;
++ up.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_IOREMAP;
++ up.port.dev = &pdev->dev;
++ up.port.private_data = priv;
++
++ clk_enable(priv->sclk);
++ up.port.uartclk = clk_get_rate(priv->sclk);
++
++ up.port.iotype = UPIO_MEM32;
++ up.port.serial_in = serial8250_em_serial_in;
++ up.port.serial_out = serial8250_em_serial_out;
++ up.dl_read = serial8250_em_serial_dl_read;
++ up.dl_write = serial8250_em_serial_dl_write;
++
++ ret = serial8250_register_8250_port(&up);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "unable to register 8250 port\n");
++ goto err2;
++ }
++
++ priv->line = ret;
++ platform_set_drvdata(pdev, priv);
++ return 0;
++
++ err2:
++ clk_disable(priv->sclk);
++ clk_put(priv->sclk);
++ err1:
++ kfree(priv);
++ err0:
++ return ret;
++}
++
++static int __devexit serial8250_em_remove(struct platform_device *pdev)
++{
++ struct serial8250_em_priv *priv = platform_get_drvdata(pdev);
++
++ serial8250_unregister_port(priv->line);
++ clk_disable(priv->sclk);
++ clk_put(priv->sclk);
++ kfree(priv);
++ return 0;
++}
++
++static struct platform_driver serial8250_em_platform_driver = {
++ .driver = {
++ .name = "serial8250-em",
++ .owner = THIS_MODULE,
++ },
++ .probe = serial8250_em_probe,
++ .remove = __devexit_p(serial8250_em_remove),
++};
++
++module_platform_driver(serial8250_em_platform_driver);
++
++MODULE_AUTHOR("Magnus Damm");
++MODULE_DESCRIPTION("Renesas Emma Mobile 8250 Driver");
++MODULE_LICENSE("GPL v2");
+diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
+index 591f801..8bc7ecb 100644
+--- a/drivers/tty/serial/8250/Kconfig
++++ b/drivers/tty/serial/8250/Kconfig
+@@ -278,3 +278,11 @@ config SERIAL_8250_DW
+ help
+ Selecting this option will enable handling of the extra features
+ present in the Synopsys DesignWare APB UART.
++
++config SERIAL_8250_EM
++ tristate "Support for Emma Mobile intergrated serial port"
++ depends on SERIAL_8250 && ARM && HAVE_CLK
++ help
++ Selecting this option will add support for the integrated serial
++ port hardware found on the Emma Mobile line of processors.
++ If unsure, say N.
+diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
+index 867bba7..3f35eac 100644
+--- a/drivers/tty/serial/8250/Makefile
++++ b/drivers/tty/serial/8250/Makefile
+@@ -18,3 +18,4 @@ obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+ obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
+ obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
+ obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
++obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/serial8250-introduce-serial8250_register_8250_port.patch b/patches.kzm9d/serial8250-introduce-serial8250_register_8250_port.patch
new file mode 100644
index 00000000000000..100457132cc363
--- /dev/null
+++ b/patches.kzm9d/serial8250-introduce-serial8250_register_8250_port.patch
@@ -0,0 +1,176 @@
+From koba@kmckk.co.jp Wed Oct 3 04:27:28 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:23:00 +0900
+Subject: [PATCH 08/26] serial8250: Introduce serial8250_register_8250_port()
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-9-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+Introduce yet another 8250 registration function.
+This time it is serial8250_register_8250_port() and it
+allows us to register 8250 hardware instances using struct
+uart_8250_port. The new function makes it possible to
+register 8250 hardware that makes use of 8250 specific
+callbacks such as ->dl_read() and ->dl_write().
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+(cherry picked from commit f73fa05b90eb8c0dd3230c364cf1107f4f8f3848)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ drivers/tty/serial/8250/8250.c | 91 ++++++++++++++++++++++++++--------------
+ include/linux/serial_8250.h | 1 +
+ 2 files changed, 60 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
+index 662188d..47d061b 100644
+--- a/drivers/tty/serial/8250/8250.c
++++ b/drivers/tty/serial/8250/8250.c
+@@ -3112,7 +3112,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
+ }
+
+ /**
+- * serial8250_register_port - register a serial port
++ * serial8250_register_8250_port - register a serial port
+ * @port: serial port template
+ *
+ * Configure the serial port specified by the request. If the
+@@ -3124,52 +3124,56 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
+ *
+ * On success the port is ready to use and the line number is returned.
+ */
+-int serial8250_register_port(struct uart_port *port)
++int serial8250_register_8250_port(struct uart_8250_port *up)
+ {
+ struct uart_8250_port *uart;
+ int ret = -ENOSPC;
+
+- if (port->uartclk == 0)
++ if (up->port.uartclk == 0)
+ return -EINVAL;
+
+ mutex_lock(&serial_mutex);
+
+- uart = serial8250_find_match_or_unused(port);
++ uart = serial8250_find_match_or_unused(&up->port);
+ if (uart) {
+ uart_remove_one_port(&serial8250_reg, &uart->port);
+
+- uart->port.iobase = port->iobase;
+- uart->port.membase = port->membase;
+- uart->port.irq = port->irq;
+- uart->port.irqflags = port->irqflags;
+- uart->port.uartclk = port->uartclk;
+- uart->port.fifosize = port->fifosize;
+- uart->port.regshift = port->regshift;
+- uart->port.iotype = port->iotype;
+- uart->port.flags = port->flags | UPF_BOOT_AUTOCONF;
+- uart->port.mapbase = port->mapbase;
+- uart->port.private_data = port->private_data;
+- if (port->dev)
+- uart->port.dev = port->dev;
+-
+- if (port->flags & UPF_FIXED_TYPE)
+- serial8250_init_fixed_type_port(uart, port->type);
++ uart->port.iobase = up->port.iobase;
++ uart->port.membase = up->port.membase;
++ uart->port.irq = up->port.irq;
++ uart->port.irqflags = up->port.irqflags;
++ uart->port.uartclk = up->port.uartclk;
++ uart->port.fifosize = up->port.fifosize;
++ uart->port.regshift = up->port.regshift;
++ uart->port.iotype = up->port.iotype;
++ uart->port.flags = up->port.flags | UPF_BOOT_AUTOCONF;
++ uart->port.mapbase = up->port.mapbase;
++ uart->port.private_data = up->port.private_data;
++ if (up->port.dev)
++ uart->port.dev = up->port.dev;
++
++ if (up->port.flags & UPF_FIXED_TYPE)
++ serial8250_init_fixed_type_port(uart, up->port.type);
+
+ set_io_from_upio(&uart->port);
+ /* Possibly override default I/O functions. */
+- if (port->serial_in)
+- uart->port.serial_in = port->serial_in;
+- if (port->serial_out)
+- uart->port.serial_out = port->serial_out;
+- if (port->handle_irq)
+- uart->port.handle_irq = port->handle_irq;
++ if (up->port.serial_in)
++ uart->port.serial_in = up->port.serial_in;
++ if (up->port.serial_out)
++ uart->port.serial_out = up->port.serial_out;
++ if (up->port.handle_irq)
++ uart->port.handle_irq = up->port.handle_irq;
+ /* Possibly override set_termios call */
+- if (port->set_termios)
+- uart->port.set_termios = port->set_termios;
+- if (port->pm)
+- uart->port.pm = port->pm;
+- if (port->handle_break)
+- uart->port.handle_break = port->handle_break;
++ if (up->port.set_termios)
++ uart->port.set_termios = up->port.set_termios;
++ if (up->port.pm)
++ uart->port.pm = up->port.pm;
++ if (up->port.handle_break)
++ uart->port.handle_break = up->port.handle_break;
++ if (up->dl_read)
++ uart->dl_read = up->dl_read;
++ if (up->dl_write)
++ uart->dl_write = up->dl_write;
+
+ if (serial8250_isa_config != NULL)
+ serial8250_isa_config(0, &uart->port,
+@@ -3183,6 +3187,29 @@ int serial8250_register_port(struct uart_port *port)
+
+ return ret;
+ }
++EXPORT_SYMBOL(serial8250_register_8250_port);
++
++/**
++ * serial8250_register_port - register a serial port
++ * @port: serial port template
++ *
++ * Configure the serial port specified by the request. If the
++ * port exists and is in use, it is hung up and unregistered
++ * first.
++ *
++ * The port is then probed and if necessary the IRQ is autodetected
++ * If this fails an error is returned.
++ *
++ * On success the port is ready to use and the line number is returned.
++ */
++int serial8250_register_port(struct uart_port *port)
++{
++ struct uart_8250_port up;
++
++ memset(&up, 0, sizeof(up));
++ memcpy(&up.port, port, sizeof(*port));
++ return serial8250_register_8250_port(&up);
++}
+ EXPORT_SYMBOL(serial8250_register_port);
+
+ /**
+diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
+index a522fd9..10dbce5 100644
+--- a/include/linux/serial_8250.h
++++ b/include/linux/serial_8250.h
+@@ -69,6 +69,7 @@ enum {
+ struct uart_port;
+ struct uart_8250_port;
+
++int serial8250_register_8250_port(struct uart_8250_port *);
+ int serial8250_register_port(struct uart_port *);
+ void serial8250_unregister_port(int line);
+ void serial8250_suspend_port(int line);
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/serial8250-use-dl_read-dl_write-on-alchemy.patch b/patches.kzm9d/serial8250-use-dl_read-dl_write-on-alchemy.patch
new file mode 100644
index 00000000000000..0930be96415447
--- /dev/null
+++ b/patches.kzm9d/serial8250-use-dl_read-dl_write-on-alchemy.patch
@@ -0,0 +1,144 @@
+From koba@kmckk.co.jp Wed Oct 3 04:27:03 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:22:57 +0900
+Subject: [PATCH 05/26] serial8250: Use dl_read()/dl_write() on Alchemy
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-6-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+Convert the 8250 Alchemy support code to make
+use of the new dl_read()/dl_write() callbacks.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+(cherry picked from commit 6b4160313c239d61c3907b2aaaeeec156911c9d1)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ drivers/tty/serial/8250/8250.c | 67 ++++++++++++++++------------------------
+ 1 file changed, 26 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
+index 590ee85..2d62c89 100644
+--- a/drivers/tty/serial/8250/8250.c
++++ b/drivers/tty/serial/8250/8250.c
+@@ -297,24 +297,7 @@ static void default_dl_write(struct uart_8250_port *up, int value)
+ serial_out(up, UART_DLM, value >> 8 & 0xff);
+ }
+
+-#if defined(CONFIG_MIPS_ALCHEMY)
+-/* Au1x00 haven't got a standard divisor latch */
+-static int _serial_dl_read(struct uart_8250_port *up)
+-{
+- if (up->port.iotype == UPIO_AU)
+- return __raw_readl(up->port.membase + 0x28);
+- else
+- return default_dl_read(up);
+-}
+-
+-static void _serial_dl_write(struct uart_8250_port *up, int value)
+-{
+- if (up->port.iotype == UPIO_AU)
+- __raw_writel(value, up->port.membase + 0x28);
+- else
+- default_dl_write(up, value);
+-}
+-#elif defined(CONFIG_SERIAL_8250_RM9K)
++#if defined(CONFIG_SERIAL_8250_RM9K)
+ static int _serial_dl_read(struct uart_8250_port *up)
+ {
+ return (up->port.iotype == UPIO_RM9000) ?
+@@ -344,7 +327,7 @@ static void _serial_dl_write(struct uart_8250_port *up, int value)
+ }
+ #endif
+
+-#if defined(CONFIG_MIPS_ALCHEMY)
++#ifdef CONFIG_MIPS_ALCHEMY
+
+ /* Au1x00 UART hardware has a weird register layout */
+ static const u8 au_io_in_map[] = {
+@@ -365,22 +348,32 @@ static const u8 au_io_out_map[] = {
+ [UART_MCR] = 6,
+ };
+
+-/* sane hardware needs no mapping */
+-static inline int map_8250_in_reg(struct uart_port *p, int offset)
++static unsigned int au_serial_in(struct uart_port *p, int offset)
+ {
+- if (p->iotype != UPIO_AU)
+- return offset;
+- return au_io_in_map[offset];
++ offset = au_io_in_map[offset] << p->regshift;
++ return __raw_readl(p->membase + offset);
+ }
+
+-static inline int map_8250_out_reg(struct uart_port *p, int offset)
++static void au_serial_out(struct uart_port *p, int offset, int value)
+ {
+- if (p->iotype != UPIO_AU)
+- return offset;
+- return au_io_out_map[offset];
++ offset = au_io_out_map[offset] << p->regshift;
++ __raw_writel(value, p->membase + offset);
++}
++
++/* Au1x00 haven't got a standard divisor latch */
++static int au_serial_dl_read(struct uart_8250_port *up)
++{
++ return __raw_readl(up->port.membase + 0x28);
+ }
+
+-#elif defined(CONFIG_SERIAL_8250_RM9K)
++static void au_serial_dl_write(struct uart_8250_port *up, int value)
++{
++ __raw_writel(value, up->port.membase + 0x28);
++}
++
++#endif
++
++#if defined(CONFIG_SERIAL_8250_RM9K)
+
+ static const u8
+ regmap_in[8] = {
+@@ -464,18 +457,6 @@ static unsigned int mem32_serial_in(struct uart_port *p, int offset)
+ return readl(p->membase + offset);
+ }
+
+-static unsigned int au_serial_in(struct uart_port *p, int offset)
+-{
+- offset = map_8250_in_reg(p, offset) << p->regshift;
+- return __raw_readl(p->membase + offset);
+-}
+-
+-static void au_serial_out(struct uart_port *p, int offset, int value)
+-{
+- offset = map_8250_out_reg(p, offset) << p->regshift;
+- __raw_writel(value, p->membase + offset);
+-}
+-
+ static unsigned int io_serial_in(struct uart_port *p, int offset)
+ {
+ offset = map_8250_in_reg(p, offset) << p->regshift;
+@@ -515,10 +496,14 @@ static void set_io_from_upio(struct uart_port *p)
+ p->serial_out = mem32_serial_out;
+ break;
+
++#ifdef CONFIG_MIPS_ALCHEMY
+ case UPIO_AU:
+ p->serial_in = au_serial_in;
+ p->serial_out = au_serial_out;
++ up->dl_read = au_serial_dl_read;
++ up->dl_write = au_serial_dl_write;
+ break;
++#endif
+
+ default:
+ p->serial_in = io_serial_in;
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/serial8250-use-dl_read-dl_write-on-rm9k.patch b/patches.kzm9d/serial8250-use-dl_read-dl_write-on-rm9k.patch
new file mode 100644
index 00000000000000..267fe1acb7eed3
--- /dev/null
+++ b/patches.kzm9d/serial8250-use-dl_read-dl_write-on-rm9k.patch
@@ -0,0 +1,145 @@
+From koba@kmckk.co.jp Wed Oct 3 04:27:18 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:22:58 +0900
+Subject: [PATCH 06/26] serial8250: Use dl_read()/dl_write() on RM9K
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-7-git-send-email-koba@kmckk.co.jp>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+Convert the 8250 RM9K support code to make
+use of the new dl_read()/dl_write() callbacks.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+(cherry picked from commit 28bf4cf22dcd936f93dd6063696b1accdc1d5207)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ drivers/tty/serial/8250/8250.c | 62 +++++++++++++++++++---------------------
+ 1 file changed, 29 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
+index 2d62c89..cc398b1 100644
+--- a/drivers/tty/serial/8250/8250.c
++++ b/drivers/tty/serial/8250/8250.c
+@@ -297,25 +297,6 @@ static void default_dl_write(struct uart_8250_port *up, int value)
+ serial_out(up, UART_DLM, value >> 8 & 0xff);
+ }
+
+-#if defined(CONFIG_SERIAL_8250_RM9K)
+-static int _serial_dl_read(struct uart_8250_port *up)
+-{
+- return (up->port.iotype == UPIO_RM9000) ?
+- (((__raw_readl(up->port.membase + 0x10) << 8) |
+- (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
+- default_dl_read(up);
+-}
+-
+-static void _serial_dl_write(struct uart_8250_port *up, int value)
+-{
+- if (up->port.iotype == UPIO_RM9000) {
+- __raw_writel(value, up->port.membase + 0x08);
+- __raw_writel(value >> 8, up->port.membase + 0x10);
+- } else {
+- default_dl_write(up, value);
+- }
+-}
+-#else
+ static int _serial_dl_read(struct uart_8250_port *up)
+ {
+ return default_dl_read(up);
+@@ -325,7 +306,6 @@ static void _serial_dl_write(struct uart_8250_port *up, int value)
+ {
+ default_dl_write(up, value);
+ }
+-#endif
+
+ #ifdef CONFIG_MIPS_ALCHEMY
+
+@@ -373,7 +353,7 @@ static void au_serial_dl_write(struct uart_8250_port *up, int value)
+
+ #endif
+
+-#if defined(CONFIG_SERIAL_8250_RM9K)
++#ifdef CONFIG_SERIAL_8250_RM9K
+
+ static const u8
+ regmap_in[8] = {
+@@ -397,28 +377,36 @@ static const u8
+ [UART_SCR] = 0x2c
+ };
+
+-static inline int map_8250_in_reg(struct uart_port *p, int offset)
++static unsigned int rm9k_serial_in(struct uart_port *p, int offset)
+ {
+- if (p->iotype != UPIO_RM9000)
+- return offset;
+- return regmap_in[offset];
++ offset = regmap_in[offset] << p->regshift;
++ return readl(p->membase + offset);
+ }
+
+-static inline int map_8250_out_reg(struct uart_port *p, int offset)
++static void rm9k_serial_out(struct uart_port *p, int offset, int value)
+ {
+- if (p->iotype != UPIO_RM9000)
+- return offset;
+- return regmap_out[offset];
++ offset = regmap_out[offset] << p->regshift;
++ writel(value, p->membase + offset);
+ }
+
+-#else
++static int rm9k_serial_dl_read(struct uart_8250_port *up)
++{
++ return ((__raw_readl(up->port.membase + 0x10) << 8) |
++ (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff;
++}
++
++static void rm9k_serial_dl_write(struct uart_8250_port *up, int value)
++{
++ __raw_writel(value, up->port.membase + 0x08);
++ __raw_writel(value >> 8, up->port.membase + 0x10);
++}
++
++#endif
+
+ /* sane hardware needs no mapping */
+ #define map_8250_in_reg(up, offset) (offset)
+ #define map_8250_out_reg(up, offset) (offset)
+
+-#endif
+-
+ static unsigned int hub6_serial_in(struct uart_port *p, int offset)
+ {
+ offset = map_8250_in_reg(p, offset) << p->regshift;
+@@ -490,12 +478,20 @@ static void set_io_from_upio(struct uart_port *p)
+ p->serial_out = mem_serial_out;
+ break;
+
+- case UPIO_RM9000:
+ case UPIO_MEM32:
+ p->serial_in = mem32_serial_in;
+ p->serial_out = mem32_serial_out;
+ break;
+
++#ifdef CONFIG_SERIAL_8250_RM9K
++ case UPIO_RM9000:
++ p->serial_in = rm9k_serial_in;
++ p->serial_out = rm9k_serial_out;
++ up->dl_read = rm9k_serial_dl_read;
++ up->dl_write = rm9k_serial_dl_write;
++ break;
++#endif
++
+ #ifdef CONFIG_MIPS_ALCHEMY
+ case UPIO_AU:
+ p->serial_in = au_serial_in;
+--
+1.7.9.5
+
diff --git a/patches.kzm9d/tegra-serial8250-add-handle_break-uart_port-op.patch b/patches.kzm9d/tegra-serial8250-add-handle_break-uart_port-op.patch
new file mode 100644
index 00000000000000..d16ce543e38c8e
--- /dev/null
+++ b/patches.kzm9d/tegra-serial8250-add-handle_break-uart_port-op.patch
@@ -0,0 +1,330 @@
+From koba@kmckk.co.jp Wed Oct 3 04:24:29 2012
+From: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Date: Wed, 3 Oct 2012 20:22:53 +0900
+Subject: [PATCH 01/26] tegra, serial8250: add ->handle_break() uart_port op
+To: greg@kroah.com
+Cc: ltsi-dev@lists.linuxfoundation.org, horms@verge.net.au, damm@opensource.se, Dan Williams <dan.j.williams@intel.com>, Nhan H Mai <nhan.h.mai@intel.com>, Colin Cross <ccross@android.com>, Olof Johansson <olof@lixom.net>, Grant Likely <grant.likely@secretlab.ca>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+Message-ID: <1349263398-13152-2-git-send-email-koba@kmckk.co.jp>
+
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+The "KT" serial port has another use case for a "received break" quirk,
+so before adding another special case to the 8250 core take this
+opportunity to push such quirks out of the core and into a uart_port op.
+
+Stephen says:
+"If the callback function is to no longer live in 8250.c itself,
+ arch/arm/mach-tegra/devices.c isn't logically a good place to put it,
+ and that file will be going away once we get rid of all the board files
+ and move solely to device tree."
+
+...so since 8250_pci.c houses all the quirks for pci serial devices this
+quirk is similarly housed in of_serial.c. Once the open firmware
+conversion completes the infrastructure details
+(include/linux/of_serial.h, and the export) can all be removed to make
+this self contained to of_serial.c.
+
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Cc: Nhan H Mai <nhan.h.mai@intel.com>
+Cc: Colin Cross <ccross@android.com>
+Cc: Olof Johansson <olof@lixom.net>
+[stephen: kill CONFIG_SERIAL_TEGRA in favor just using CONFIG_ARCH_TEGRA]
+Cc: Grant Likely <grant.likely@secretlab.ca>
+Acked-by: Sudhakar Mamillapalli <sudhakar@fb.com>
+Reported-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Acked-by: Stephen Warren <swarren@wwwdotorg.org>
+Tested-by: Stephen Warren <swarren@wwwdotorg.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+(cherry picked from commit bf03f65b7967df5807ddef7b99f8a41d4c94fc70)
+
+Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
+---
+ arch/arm/mach-tegra/board-harmony.c | 2 ++
+ arch/arm/mach-tegra/board-paz00.c | 3 +++
+ arch/arm/mach-tegra/board-seaboard.c | 2 ++
+ arch/arm/mach-tegra/board-trimslice.c | 2 ++
+ drivers/tty/serial/8250/8250.c | 34 +++------------------------------
+ drivers/tty/serial/of_serial.c | 26 +++++++++++++++++++++++++
+ include/linux/of_serial.h | 17 +++++++++++++++++
+ include/linux/serial_8250.h | 1 +
+ include/linux/serial_core.h | 5 +++++
+ 9 files changed, 61 insertions(+), 31 deletions(-)
+ create mode 100644 include/linux/of_serial.h
+
+diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
+index c00aadb..222182e 100644
+--- a/arch/arm/mach-tegra/board-harmony.c
++++ b/arch/arm/mach-tegra/board-harmony.c
+@@ -19,6 +19,7 @@
+ #include <linux/init.h>
+ #include <linux/platform_device.h>
+ #include <linux/serial_8250.h>
++#include <linux/of_serial.h>
+ #include <linux/clk.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/pda_power.h>
+@@ -52,6 +53,7 @@ static struct plat_serial8250_port debug_uart_platform_data[] = {
+ .irq = INT_UARTD,
+ .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
+ .type = PORT_TEGRA,
++ .handle_break = tegra_serial_handle_break,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 216000000,
+diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
+index 330afdf..d0735c7 100644
+--- a/arch/arm/mach-tegra/board-paz00.c
++++ b/arch/arm/mach-tegra/board-paz00.c
+@@ -21,6 +21,7 @@
+ #include <linux/init.h>
+ #include <linux/platform_device.h>
+ #include <linux/serial_8250.h>
++#include <linux/of_serial.h>
+ #include <linux/clk.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/gpio_keys.h>
+@@ -55,6 +56,7 @@ static struct plat_serial8250_port debug_uart_platform_data[] = {
+ .irq = INT_UARTA,
+ .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
+ .type = PORT_TEGRA,
++ .handle_break = tegra_serial_handle_break,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 216000000,
+@@ -65,6 +67,7 @@ static struct plat_serial8250_port debug_uart_platform_data[] = {
+ .irq = INT_UARTC,
+ .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
+ .type = PORT_TEGRA,
++ .handle_break = tegra_serial_handle_break,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 216000000,
+diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c
+index d669847..5b687b8 100644
+--- a/arch/arm/mach-tegra/board-seaboard.c
++++ b/arch/arm/mach-tegra/board-seaboard.c
+@@ -18,6 +18,7 @@
+ #include <linux/init.h>
+ #include <linux/platform_device.h>
+ #include <linux/serial_8250.h>
++#include <linux/of_serial.h>
+ #include <linux/i2c.h>
+ #include <linux/delay.h>
+ #include <linux/input.h>
+@@ -47,6 +48,7 @@ static struct plat_serial8250_port debug_uart_platform_data[] = {
+ /* Memory and IRQ filled in before registration */
+ .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
+ .type = PORT_TEGRA,
++ .handle_break = tegra_serial_handle_break,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 216000000,
+diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c
+index cd52820a..f735858 100644
+--- a/arch/arm/mach-tegra/board-trimslice.c
++++ b/arch/arm/mach-tegra/board-trimslice.c
+@@ -22,6 +22,7 @@
+ #include <linux/init.h>
+ #include <linux/platform_device.h>
+ #include <linux/serial_8250.h>
++#include <linux/of_serial.h>
+ #include <linux/io.h>
+ #include <linux/i2c.h>
+ #include <linux/gpio.h>
+@@ -48,6 +49,7 @@ static struct plat_serial8250_port debug_uart_platform_data[] = {
+ .irq = INT_UARTA,
+ .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
+ .type = PORT_TEGRA,
++ .handle_break = tegra_serial_handle_break,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 216000000,
+diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
+index d537431..aed9363 100644
+--- a/drivers/tty/serial/8250/8250.c
++++ b/drivers/tty/serial/8250/8250.c
+@@ -1332,27 +1332,6 @@ static void serial8250_enable_ms(struct uart_port *port)
+ }
+
+ /*
+- * Clear the Tegra rx fifo after a break
+- *
+- * FIXME: This needs to become a port specific callback once we have a
+- * framework for this
+- */
+-static void clear_rx_fifo(struct uart_8250_port *up)
+-{
+- unsigned int status, tmout = 10000;
+- do {
+- status = serial_in(up, UART_LSR);
+- if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
+- status = serial_in(up, UART_RX);
+- else
+- break;
+- if (--tmout == 0)
+- break;
+- udelay(1);
+- } while (1);
+-}
+-
+-/*
+ * serial8250_rx_chars: processes according to the passed in LSR
+ * value, and returns the remaining LSR bits not handled
+ * by this Rx routine.
+@@ -1386,20 +1365,10 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
+ up->lsr_saved_flags = 0;
+
+ if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
+- /*
+- * For statistics only
+- */
+ if (lsr & UART_LSR_BI) {
+ lsr &= ~(UART_LSR_FE | UART_LSR_PE);
+ port->icount.brk++;
+ /*
+- * If tegra port then clear the rx fifo to
+- * accept another break/character.
+- */
+- if (port->type == PORT_TEGRA)
+- clear_rx_fifo(up);
+-
+- /*
+ * We do the SysRQ and SAK checking
+ * here because otherwise the break
+ * may get masked by ignore_status_mask
+@@ -3038,6 +3007,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
+ port.serial_in = p->serial_in;
+ port.serial_out = p->serial_out;
+ port.handle_irq = p->handle_irq;
++ port.handle_break = p->handle_break;
+ port.set_termios = p->set_termios;
+ port.pm = p->pm;
+ port.dev = &dev->dev;
+@@ -3210,6 +3180,8 @@ int serial8250_register_port(struct uart_port *port)
+ uart->port.set_termios = port->set_termios;
+ if (port->pm)
+ uart->port.pm = port->pm;
++ if (port->handle_break)
++ uart->port.handle_break = port->handle_break;
+
+ if (serial8250_isa_config != NULL)
+ serial8250_isa_config(0, &uart->port,
+diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
+index e8c9cee..5410c06 100644
+--- a/drivers/tty/serial/of_serial.c
++++ b/drivers/tty/serial/of_serial.c
+@@ -12,10 +12,13 @@
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
++#include <linux/delay.h>
+ #include <linux/serial_core.h>
+ #include <linux/serial_8250.h>
++#include <linux/serial_reg.h>
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
++#include <linux/of_serial.h>
+ #include <linux/of_platform.h>
+ #include <linux/nwpserial.h>
+
+@@ -24,6 +27,26 @@ struct of_serial_info {
+ int line;
+ };
+
++#ifdef CONFIG_ARCH_TEGRA
++void tegra_serial_handle_break(struct uart_port *p)
++{
++ unsigned int status, tmout = 10000;
++
++ do {
++ status = p->serial_in(p, UART_LSR);
++ if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
++ status = p->serial_in(p, UART_RX);
++ else
++ break;
++ if (--tmout == 0)
++ break;
++ udelay(1);
++ } while (1);
++}
++/* FIXME remove this export when tegra finishes conversion to open firmware */
++EXPORT_SYMBOL_GPL(tegra_serial_handle_break);
++#endif
++
+ /*
+ * Fill a struct uart_port for a given device node
+ */
+@@ -84,6 +107,9 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
+ | UPF_FIXED_PORT | UPF_FIXED_TYPE;
+ port->dev = &ofdev->dev;
+
++ if (type == PORT_TEGRA)
++ port->handle_break = tegra_serial_handle_break;
++
+ return 0;
+ }
+
+diff --git a/include/linux/of_serial.h b/include/linux/of_serial.h
+new file mode 100644
+index 0000000..4a73ed8
+--- /dev/null
++++ b/include/linux/of_serial.h
+@@ -0,0 +1,17 @@
++#ifndef __LINUX_OF_SERIAL_H
++#define __LINUX_OF_SERIAL_H
++
++/*
++ * FIXME remove this file when tegra finishes conversion to open firmware,
++ * expectation is that all quirks will then be self-contained in
++ * drivers/tty/serial/of_serial.c.
++ */
++#ifdef CONFIG_ARCH_TEGRA
++extern void tegra_serial_handle_break(struct uart_port *port);
++#else
++static inline void tegra_serial_handle_break(struct uart_port *port)
++{
++}
++#endif
++
++#endif /* __LINUX_OF_SERIAL */
+diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
+index 8f012f8..a522fd9 100644
+--- a/include/linux/serial_8250.h
++++ b/include/linux/serial_8250.h
+@@ -38,6 +38,7 @@ struct plat_serial8250_port {
+ int (*handle_irq)(struct uart_port *);
+ void (*pm)(struct uart_port *, unsigned int state,
+ unsigned old);
++ void (*handle_break)(struct uart_port *);
+ };
+
+ /*
+diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
+index 2db407a..65db992 100644
+--- a/include/linux/serial_core.h
++++ b/include/linux/serial_core.h
+@@ -310,6 +310,7 @@ struct uart_port {
+ int (*handle_irq)(struct uart_port *);
+ void (*pm)(struct uart_port *, unsigned int state,
+ unsigned int old);
++ void (*handle_break)(struct uart_port *);
+ unsigned int irq; /* irq number */
+ unsigned long irqflags; /* irq flags */
+ unsigned int uartclk; /* base uart clock */
+@@ -533,6 +534,10 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
+ static inline int uart_handle_break(struct uart_port *port)
+ {
+ struct uart_state *state = port->state;
++
++ if (port->handle_break)
++ port->handle_break(port);
++
+ #ifdef SUPPORT_SYSRQ
+ if (port->cons && port->cons->index == port->line) {
+ if (!port->sysrq) {
+--
+1.7.9.5
+
diff --git a/series b/series
index a9e1172660c65e..f09e0e9d2a0daa 100644
--- a/series
+++ b/series
@@ -637,3 +637,30 @@ patches.kzm9g/arm-shmobile-kzm9g-defconfig-enable-inotify_user.patch
patches.kzm9g/arm-shmobile-sh73a0-fixup-reloc_base-of-intca_irq_pins_desc.patch
+#############################################################################
+# kzm9d board support
+#
+patches.kzm9d/tegra-serial8250-add-handle_break-uart_port-op.patch
+patches.kzm9d/serial-8250_pci-clear-fifos-for-intel-me-serial-over-lan-device-on-bi.patch
+patches.kzm9d/serial-8250_pci-fix-suspend-resume-vs-init-exit-quirks.patch
+patches.kzm9d/serial8250-add-dl_read-dl_write-callbacks.patch
+patches.kzm9d/serial8250-use-dl_read-dl_write-on-alchemy.patch
+patches.kzm9d/serial8250-use-dl_read-dl_write-on-rm9k.patch
+patches.kzm9d/serial8250-clean-up-default-map-and-dl-code.patch
+patches.kzm9d/serial8250-introduce-serial8250_register_8250_port.patch
+patches.kzm9d/serial8250-em-emma-mobile-uart-driver-v2.patch
+patches.kzm9d/serial8250-em-clk_get-is_err-error-handling-fix.patch
+patches.kzm9d/serial8250-em-add-dt-support.patch
+patches.kzm9d/clockevents-make-clockevents_config-a-global-symbol.patch
+patches.kzm9d/clocksource-em_sti-emma-mobile-sti-driver.patch
+patches.kzm9d/clocksource-em_sti-add-dt-support.patch
+patches.kzm9d/gpio-emma-mobile-gpio-driver-v2.patch
+patches.kzm9d/mach-shmobile-emma-mobile-ev2-soc-base-support-v3.patch
+patches.kzm9d/mach-shmobile-kzm9d-board-support-v3.patch
+patches.kzm9d/mach-shmobile-emma-mobile-ev2-smp-support-v3.patch
+patches.kzm9d/mach-shmobile-emma-mobile-ev2-gpio-support-v3.patch
+patches.kzm9d/mach-shmobile-kzm9d-board-ethernet-support-v3.patch
+patches.kzm9d/arm-mach-shmobile-kzm9d-add-defconfig.patch
+patches.kzm9d/mach-shmobile-emma-mobile-ev2-dt-support-v3.patch
+patches.kzm9d/mach-shmobile-use-dt_machine-for-kzm9d-v3.patch
+patches.kzm9d/arm-mach-shmobile-fix-build-when-smp-is-enabled-and-emev2-is-not-enabled.patch