diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-07-09 14:56:32 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-07-09 14:56:32 -0700 |
commit | 28d7e9e4fe1c5d48a679f290b3a7d4adb3777f27 (patch) | |
tree | 70c2892046ffcf9471d5f87a87ed33881fd122d4 | |
parent | 0a2fbf5bd036fba62bf3613817116aae014f3461 (diff) | |
parent | 9c4b00913bff039abcd8852764fe0c9648d8cc8d (diff) | |
download | ltsi-kernel-28d7e9e4fe1c5d48a679f290b3a7d4adb3777f27.tar.gz |
Merge branch 'master' of git.linuxfoundation.org:ltsi-kernel
119 files changed, 18122 insertions, 319 deletions
diff --git a/KERNEL_VERSION b/KERNEL_VERSION index a0dc05846d8a46..f4605dc50cbe8c 100644 --- a/KERNEL_VERSION +++ b/KERNEL_VERSION @@ -1 +1 @@ -3.0.33 +3.0.36 diff --git a/patches.armadillo800eva/0141-v4l-Add-V4L2_PIX_FMT_NV24-and-V4L2_PIX_FMT_NV42-form.patch b/patches.armadillo800eva/0141-v4l-Add-V4L2_PIX_FMT_NV24-and-V4L2_PIX_FMT_NV42-form.patch index 847fe3beaa31ff..afb958ebecc8df 100644 --- a/patches.armadillo800eva/0141-v4l-Add-V4L2_PIX_FMT_NV24-and-V4L2_PIX_FMT_NV42-form.patch +++ b/patches.armadillo800eva/0141-v4l-Add-V4L2_PIX_FMT_NV24-and-V4L2_PIX_FMT_NV42-form.patch @@ -14,143 +14,14 @@ Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> Conflicts: Documentation/DocBook/media/v4l/pixfmt.xml + Documentation/DocBook/media/v4l/pixfmt-nv24.xml Signed-off-by: Simon Horman <horms@verge.net.au> + --- - Documentation/DocBook/media/v4l/pixfmt-nv24.xml | 121 +++++++++++++++++++++++ - include/linux/videodev2.h | 2 + - 2 files changed, 123 insertions(+) - create mode 100644 Documentation/DocBook/media/v4l/pixfmt-nv24.xml + include/linux/videodev2.h | 2 ++ + 1 file changed, 2 insertions(+) -diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv24.xml b/Documentation/DocBook/media/v4l/pixfmt-nv24.xml -new file mode 100644 -index 0000000..fb255f2 ---- /dev/null -+++ b/Documentation/DocBook/media/v4l/pixfmt-nv24.xml -@@ -0,0 +1,121 @@ -+ <refentry> -+ <refmeta> -+ <refentrytitle>V4L2_PIX_FMT_NV24 ('NV24'), V4L2_PIX_FMT_NV42 ('NV42')</refentrytitle> -+ &manvol; -+ </refmeta> -+ <refnamediv> -+ <refname id="V4L2-PIX-FMT-NV24"><constant>V4L2_PIX_FMT_NV24</constant></refname> -+ <refname id="V4L2-PIX-FMT-NV42"><constant>V4L2_PIX_FMT_NV42</constant></refname> -+ <refpurpose>Formats with full horizontal and vertical -+chroma resolutions, also known as YUV 4:4:4. One luminance and one -+chrominance plane with alternating chroma samples as opposed to -+<constant>V4L2_PIX_FMT_YVU420</constant></refpurpose> -+ </refnamediv> -+ <refsect1> -+ <title>Description</title> -+ -+ <para>These are two-plane versions of the YUV 4:4:4 format. The three -+ components are separated into two sub-images or planes. The Y plane is -+ first, with each Y sample stored in one byte per pixel. For -+ <constant>V4L2_PIX_FMT_NV24</constant>, a combined CbCr plane -+ immediately follows the Y plane in memory. The CbCr plane has the same -+ width and height, in pixels, as the Y plane (and the image). Each line -+ contains one CbCr pair per pixel, with each Cb and Cr sample stored in -+ one byte. <constant>V4L2_PIX_FMT_NV42</constant> is the same except that -+ the Cb and Cr samples are swapped, the CrCb plane starts with a Cr -+ sample.</para> -+ -+ <para>If the Y plane has pad bytes after each row, then the CbCr plane -+ has twice as many pad bytes after its rows.</para> -+ -+ <example> -+ <title><constant>V4L2_PIX_FMT_NV24</constant> 4 × 4 -+pixel image</title> -+ -+ <formalpara> -+ <title>Byte Order.</title> -+ <para>Each cell is one byte. -+ <informaltable frame="none"> -+ <tgroup cols="9" align="center"> -+ <colspec align="left" colwidth="2*" /> -+ <tbody valign="top"> -+ <row> -+ <entry>start + 0:</entry> -+ <entry>Y'<subscript>00</subscript></entry> -+ <entry>Y'<subscript>01</subscript></entry> -+ <entry>Y'<subscript>02</subscript></entry> -+ <entry>Y'<subscript>03</subscript></entry> -+ </row> -+ <row> -+ <entry>start + 4:</entry> -+ <entry>Y'<subscript>10</subscript></entry> -+ <entry>Y'<subscript>11</subscript></entry> -+ <entry>Y'<subscript>12</subscript></entry> -+ <entry>Y'<subscript>13</subscript></entry> -+ </row> -+ <row> -+ <entry>start + 8:</entry> -+ <entry>Y'<subscript>20</subscript></entry> -+ <entry>Y'<subscript>21</subscript></entry> -+ <entry>Y'<subscript>22</subscript></entry> -+ <entry>Y'<subscript>23</subscript></entry> -+ </row> -+ <row> -+ <entry>start + 12:</entry> -+ <entry>Y'<subscript>30</subscript></entry> -+ <entry>Y'<subscript>31</subscript></entry> -+ <entry>Y'<subscript>32</subscript></entry> -+ <entry>Y'<subscript>33</subscript></entry> -+ </row> -+ <row> -+ <entry>start + 16:</entry> -+ <entry>Cb<subscript>00</subscript></entry> -+ <entry>Cr<subscript>00</subscript></entry> -+ <entry>Cb<subscript>01</subscript></entry> -+ <entry>Cr<subscript>01</subscript></entry> -+ <entry>Cb<subscript>02</subscript></entry> -+ <entry>Cr<subscript>02</subscript></entry> -+ <entry>Cb<subscript>03</subscript></entry> -+ <entry>Cr<subscript>03</subscript></entry> -+ </row> -+ <row> -+ <entry>start + 24:</entry> -+ <entry>Cb<subscript>10</subscript></entry> -+ <entry>Cr<subscript>10</subscript></entry> -+ <entry>Cb<subscript>11</subscript></entry> -+ <entry>Cr<subscript>11</subscript></entry> -+ <entry>Cb<subscript>12</subscript></entry> -+ <entry>Cr<subscript>12</subscript></entry> -+ <entry>Cb<subscript>13</subscript></entry> -+ <entry>Cr<subscript>13</subscript></entry> -+ </row> -+ <row> -+ <entry>start + 32:</entry> -+ <entry>Cb<subscript>20</subscript></entry> -+ <entry>Cr<subscript>20</subscript></entry> -+ <entry>Cb<subscript>21</subscript></entry> -+ <entry>Cr<subscript>21</subscript></entry> -+ <entry>Cb<subscript>22</subscript></entry> -+ <entry>Cr<subscript>22</subscript></entry> -+ <entry>Cb<subscript>23</subscript></entry> -+ <entry>Cr<subscript>23</subscript></entry> -+ </row> -+ <row> -+ <entry>start + 40:</entry> -+ <entry>Cb<subscript>30</subscript></entry> -+ <entry>Cr<subscript>30</subscript></entry> -+ <entry>Cb<subscript>31</subscript></entry> -+ <entry>Cr<subscript>31</subscript></entry> -+ <entry>Cb<subscript>32</subscript></entry> -+ <entry>Cr<subscript>32</subscript></entry> -+ <entry>Cb<subscript>33</subscript></entry> -+ <entry>Cr<subscript>33</subscript></entry> -+ </row> -+ </tbody> -+ </tgroup> -+ </informaltable> -+ </para> -+ </formalpara> -+ </example> -+ </refsect1> -+ </refentry> -diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h -index eeeda13..bd0ab98 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -343,6 +343,8 @@ struct v4l2_pix_format { @@ -162,6 +33,3 @@ index eeeda13..bd0ab98 100644 /* two non contiguous planes - one Y, one Cr + Cb interleaved */ #define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */ --- -1.7.10 - diff --git a/patches.armadillo800eva/arm-mach-shmobile-sh7372-ap4evb-and-mackerel-timer-rework.patch b/patches.armadillo800eva/arm-mach-shmobile-sh7372-ap4evb-and-mackerel-timer-rework.patch new file mode 100644 index 00000000000000..9854a18225d548 --- /dev/null +++ b/patches.armadillo800eva/arm-mach-shmobile-sh7372-ap4evb-and-mackerel-timer-rework.patch @@ -0,0 +1,67 @@ +From horms@vergenet.net Tue May 29 17:45:19 2012 +From: Simon Horman <horms@verge.net.au> +Date: Wed, 30 May 2012 09:45:07 +0900 +Subject: [PATCH] ARM: mach-shmobile: sh7372, AP4EVB and Mackerel timer rework +To: ltsi-dev@lists.linuxfoundation.org +Cc: Greg KH <gregkh@linuxfoundation.org>, Magnus Damm <magnus.damm@gmail.com>, Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>, Simon Horman <horms@verge.net.au> +Message-ID: <1338338707-29333-2-git-send-email-horms@verge.net.au> + + +From: Magnus Damm <damm@opensource.se> + +Move the SoC specific timer code from AP4EVB and Mackerel +to sh7372 setup code. This makes is possible to share +the SoC specific timer code across boards and it also +removes the need for a board specific timer structure. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> +(cherry picked from commit 17254bffd6e4fda97d825acec153614f09bb33e7) + +Conflicts: + + arch/arm/mach-shmobile/board-ap4evb.c + arch/arm/mach-shmobile/board-mackerel.c + arch/arm/mach-shmobile/setup-sh7372.c + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/mach-shmobile/setup-sh7372.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c +index 8ddef91..42d9619 100644 +--- a/arch/arm/mach-shmobile/setup-sh7372.c ++++ b/arch/arm/mach-shmobile/setup-sh7372.c +@@ -32,8 +32,10 @@ + #include <linux/sh_timer.h> + #include <mach/hardware.h> + #include <mach/sh7372.h> ++#include <mach/common.h> + #include <asm/mach-types.h> + #include <asm/mach/arch.h> ++#include <asm/mach/time.h> + + /* SCIFA0 */ + static struct plat_sci_port scif0_platform_data = { +@@ -848,8 +850,17 @@ void __init sh7372_add_standard_devices(void) + ARRAY_SIZE(sh7372_late_devices)); + } + ++static void __init sh7372_earlytimer_init(void) ++{ ++ sh7372_clock_init(); ++ shmobile_earlytimer_init(); ++} ++ + void __init sh7372_add_early_devices(void) + { + early_platform_add_devices(sh7372_early_devices, + ARRAY_SIZE(sh7372_early_devices)); ++ ++ /* override timer setup with soc-specific code */ ++ shmobile_timer.init = sh7372_earlytimer_init; + } +-- +1.7.10.2.484.gcd07cc5 + diff --git a/patches.armadillo800eva/ltsi-bugfix-armadillo800eva-sh_eth-needs-net_ethernet-on-defconfig.patch b/patches.armadillo800eva/ltsi-bugfix-armadillo800eva-sh_eth-needs-net_ethernet-on-defconfig.patch new file mode 100644 index 00000000000000..6a1f951e05c927 --- /dev/null +++ b/patches.armadillo800eva/ltsi-bugfix-armadillo800eva-sh_eth-needs-net_ethernet-on-defconfig.patch @@ -0,0 +1,36 @@ +From kuninori.morimoto.gx@gmail.com Tue Jun 12 21:51:16 2012 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Tue, 12 Jun 2012 21:51:14 -0700 (PDT) +Subject: [PATCH 1/2] LTSI: bugfix: armadillo800eva: SH_ETH needs NET_ETHERNET on defconfig +To: Greg KH <gregkh@linuxfoundation.org>, ltsi-dev@lists.linuxfoundation.org +Cc: Simon <horms@verge.net.au>, Kuninori Morimoto <kuninori.morimoto.gx@gmail.com>, (KMC)tuji <kunihiko@kmckk.co.jp> +Message-ID: <87zk877r29.wl%kuninori.morimoto.gx@renesas.com> + + +On LTSI, sh_eth driver was backported from latest kernel. +But the ethernet driver dependency was modified between +latest kernel and 3.0.x kernel. +Then, LTSI kernel lost NET_ETHERNET which was required +from SH_ETH on defconfig. +This patch fix it up for LTSI. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +--- + arch/arm/configs/armadillo800eva_defconfig | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig +index 0d20749..f29893a 100644 +--- a/arch/arm/configs/armadillo800eva_defconfig ++++ b/arch/arm/configs/armadillo800eva_defconfig +@@ -68,6 +68,7 @@ CONFIG_NETDEVICES=y + # CONFIG_NET_VENDOR_MARVELL is not set + # CONFIG_NET_VENDOR_MICREL is not set + # CONFIG_NET_VENDOR_NATSEMI is not set ++CONFIG_NET_ETHERNET=y + CONFIG_SH_ETH=y + # CONFIG_NET_VENDOR_SEEQ is not set + # CONFIG_NET_VENDOR_STMICRO is not set +-- +1.7.5.4 + diff --git a/patches.kernel.org/arm-fix-rcu-stalls-on-smp-platforms.patch b/patches.kernel.org/arm-fix-rcu-stalls-on-smp-platforms.patch new file mode 100644 index 00000000000000..e2c6270437c688 --- /dev/null +++ b/patches.kernel.org/arm-fix-rcu-stalls-on-smp-platforms.patch @@ -0,0 +1,67 @@ +From 7deabca0acfe02b8e18f59a4c95676012f49a304 Mon Sep 17 00:00:00 2001 +From: Russell King <rmk+kernel@arm.linux.org.uk> +Date: Thu, 19 Jan 2012 15:20:58 +0000 +Subject: ARM: fix rcu stalls on SMP platforms + +From: Russell King <rmk+kernel@arm.linux.org.uk> + +commit 7deabca0acfe02b8e18f59a4c95676012f49a304 upstream. + +We can stall RCU processing on SMP platforms if a CPU sits in its idle +loop for a long time. This happens because we don't call irq_enter() +and irq_exit() around generic_smp_call_function_interrupt() and +friends. Add the necessary calls, and remove the one from within +ipi_timer(), so that they're all in a common place. + +Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> +Signed-off-by: UCHINO Satoshi <satoshi.uchino@toshiba.co.jp> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + arch/arm/kernel/smp.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/arch/arm/kernel/smp.c ++++ b/arch/arm/kernel/smp.c +@@ -445,9 +445,7 @@ static DEFINE_PER_CPU(struct clock_event + static void ipi_timer(void) + { + struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent); +- irq_enter(); + evt->event_handler(evt); +- irq_exit(); + } + + #ifdef CONFIG_LOCAL_TIMERS +@@ -568,7 +566,9 @@ asmlinkage void __exception_irq_entry do + + switch (ipinr) { + case IPI_TIMER: ++ irq_enter(); + ipi_timer(); ++ irq_exit(); + break; + + case IPI_RESCHEDULE: +@@ -576,15 +576,21 @@ asmlinkage void __exception_irq_entry do + break; + + case IPI_CALL_FUNC: ++ irq_enter(); + generic_smp_call_function_interrupt(); ++ irq_exit(); + break; + + case IPI_CALL_FUNC_SINGLE: ++ irq_enter(); + generic_smp_call_function_single_interrupt(); ++ irq_exit(); + break; + + case IPI_CPU_STOP: ++ irq_enter(); + ipi_cpu_stop(cpu); ++ irq_exit(); + break; + + default: diff --git a/patches.kzm9g/0001-tty-serial-allow-ports-to-override-the-irq-handler.patch b/patches.kzm9g/0001-tty-serial-allow-ports-to-override-the-irq-handler.patch new file mode 100644 index 00000000000000..3d7f126e8a3640 --- /dev/null +++ b/patches.kzm9g/0001-tty-serial-allow-ports-to-override-the-irq-handler.patch @@ -0,0 +1,36 @@ +From bc8d01eecbc317f8f39268b1e5e4fcb9ac1d89af Mon Sep 17 00:00:00 2001 +From: Jamie Iles <jamie@jamieiles.com> +Date: Mon, 15 Aug 2011 10:17:51 +0100 +Subject: tty: serial: allow ports to override the irq handler + +Some serial ports may have unusal requirements for interrupt handling +(e.g. the Synopsys DesignWare 8250-alike port and it's busy detect +interrupt). Add a .handle_irq callback that can be used for platforms +to override the interrupt behaviour in a similar fashion to the +.serial_out and .serial_in callbacks. + +Signed-off-by: Jamie Iles <jamie@jamieiles.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit a74036f51272975e9538e80cd1bb64dce164b208) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + include/linux/serial_core.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h +index a5c3114..b6fa317 100644 +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -300,6 +300,7 @@ struct uart_port { + void (*set_termios)(struct uart_port *, + struct ktermios *new, + struct ktermios *old); ++ int (*handle_irq)(struct uart_port *); + void (*pm)(struct uart_port *, unsigned int state, + unsigned int old); + unsigned int irq; /* irq number */ +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0002-serial-introduce-generic-port-in-out-helpers.patch b/patches.kzm9g/0002-serial-introduce-generic-port-in-out-helpers.patch new file mode 100644 index 00000000000000..377a496df1eb0e --- /dev/null +++ b/patches.kzm9g/0002-serial-introduce-generic-port-in-out-helpers.patch @@ -0,0 +1,53 @@ +From 790111bbb9291b79c960d33b406ccc7ab9833a76 Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Thu, 8 Mar 2012 19:12:12 -0500 +Subject: serial: introduce generic port in/out helpers + +Looking at the existing serial drivers (esp. the 8250 derived +variants) we see a common trend. They create a hardware specific +port struct, which in turn contains a generic serial_port struct. + +The other trend, is that they all create some sort of shortcut +to go through the hardware specific struct, to the serial_port +struct, which has the basic in/out operations within. Looking +for the serial_in and serial_out in several drivers shows this. + +Rather than let this continue, lets create a generic set of +similar helper wrappers that can be used on a struct port, so +we can eliminate bouncing out through hardware specific struct +pointers just to come back into struct port where possible. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 927353a75602dd97144352f53177e18093fdd198) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + include/linux/serial_core.h | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h +index b6fa317..1cb6309 100644 +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -376,6 +376,16 @@ struct uart_port { + void *private_data; /* generic platform data pointer */ + }; + ++static inline int serial_port_in(struct uart_port *up, int offset) ++{ ++ return up->serial_in(up, offset); ++} ++ ++static inline void serial_port_out(struct uart_port *up, int offset, int value) ++{ ++ up->serial_out(up, offset, value); ++} ++ + /* + * This is the state information which is persistent across opens. + */ +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0003-serial-8250-increase-PASS_LIMIT.patch b/patches.kzm9g/0003-serial-8250-increase-PASS_LIMIT.patch new file mode 100644 index 00000000000000..f2433d9055fa8a --- /dev/null +++ b/patches.kzm9g/0003-serial-8250-increase-PASS_LIMIT.patch @@ -0,0 +1,39 @@ +From 0028c21552eb37ad26e53e0d6d0a977d886b0abf Mon Sep 17 00:00:00 2001 +From: Jiri Slaby <jirislaby@gmail.com> +Date: Sun, 5 Jun 2011 22:51:49 +0200 +Subject: serial: 8250, increase PASS_LIMIT + +With virtual machines like qemu, it's pretty common to see "too much +work for irq4" messages nowadays. This happens when a bunch of output +is printed on the emulated serial console. This is caused by too low +PASS_LIMIT. When ISR loops more than the limit, it spits the message. + +I've been using a kernel with doubled the limit and I couldn't see no +problems. Maybe it's time to get rid of the message now? + +Signed-off-by: Jiri Slaby <jirislaby@gmail.com> +Cc: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit e7328ae1848966181a7ac47e8ae6cddbd2cf55f3) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c +index 762ce72..7f50999 100644 +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -81,7 +81,7 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */ + #define DEBUG_INTR(fmt...) do { } while (0) + #endif + +-#define PASS_LIMIT 256 ++#define PASS_LIMIT 512 + + #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) + +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0004-serial-Fix-wakeup-init-logic-to-speed-up-startup.patch b/patches.kzm9g/0004-serial-Fix-wakeup-init-logic-to-speed-up-startup.patch new file mode 100644 index 00000000000000..6a58103c6edb37 --- /dev/null +++ b/patches.kzm9g/0004-serial-Fix-wakeup-init-logic-to-speed-up-startup.patch @@ -0,0 +1,60 @@ +From da29566854e9ffb6770255fbd915184073d2d0b1 Mon Sep 17 00:00:00 2001 +From: Simon Glass <sjg@chromium.org> +Date: Thu, 19 Jan 2012 11:28:56 -0800 +Subject: serial: Fix wakeup init logic to speed up startup + +The synchronize_rcu() call resulting from making every serial driver +wake-up capable (commit b3b708fa) slows boot down on my Tegra2x system +(with CONFIG_PREEMPT disabled). + +But this is avoidable since it is the device_set_wakeup_enable() and then +subsequence disable which causes the delay. We might as well just make +the device wakeup capable but not actually enable it for wakeup until +needed. + +Effectively the current code does this: + + device_set_wakeup_capable(dev, 1); + device_set_wakeup_enable(dev, 1); + device_set_wakeup_enable(dev, 0); + +We can just drop the last two lines. + +Before this change my boot log says: +[ 0.227062] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled +[ 0.702928] serial8250.0: ttyS0 at MMIO 0x70006040 (irq = 69) is a Tegra + +after: +[ 0.227264] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled +[ 0.227983] serial8250.0: ttyS0 at MMIO 0x70006040 (irq = 69) is a Tegra + +for saving of 450ms. + +Suggested-by: Rafael J. Wysocki <rjw@sisk.pl> +Acked-by: Rafael J. Wysocki <rjw@sisk.pl> +Signed-off-by: Simon Glass <sjg@chromium.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 773598357c0baf03081cf87f2b444f97744faf1e) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/serial_core.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/tty/serial/serial_core.c ++++ b/drivers/tty/serial/serial_core.c +@@ -2391,11 +2391,11 @@ int uart_add_one_port(struct uart_driver + */ + tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev); + if (likely(!IS_ERR(tty_dev))) { +- device_init_wakeup(tty_dev, 1); +- device_set_wakeup_enable(tty_dev, 0); +- } else ++ device_set_wakeup_capable(tty_dev, 1); ++ } else { + printk(KERN_ERR "Cannot register tty device on line %d\n", + uport->line); ++ } + + /* + * Ensure UPF_DEAD is not set. diff --git a/patches.kzm9g/0005-tty-serial8250-allow-platforms-to-override-irq-handl.patch b/patches.kzm9g/0005-tty-serial8250-allow-platforms-to-override-irq-handl.patch new file mode 100644 index 00000000000000..a12baef1285a9a --- /dev/null +++ b/patches.kzm9g/0005-tty-serial8250-allow-platforms-to-override-irq-handl.patch @@ -0,0 +1,140 @@ +From 5d815ba3618efabed3571204df30a309d2471aee Mon Sep 17 00:00:00 2001 +From: Jamie Iles <jamie@jamieiles.com> +Date: Mon, 15 Aug 2011 10:17:52 +0100 +Subject: tty: serial8250: allow platforms to override irq handler + +Some ports (e.g. Synopsys DesignWare 8250) have special requirements for +handling the interrupts. Allow these platforms to specify their own +interrupt handler that will override the default. +serial8250_handle_irq() is provided so that platforms can extend the IRQ +handler rather than completely replacing it. + +Signed-off-by: Jamie Iles <jamie@jamieiles.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 583d28e92f667eb6cc81ea87daaa7e321c23fe14) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250.c | 39 +++++++++++++++++++++++++++++++++++---- + include/linux/serial_8250.h | 2 ++ + 2 files changed, 37 insertions(+), 4 deletions(-) + +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c +index 7f50999..97007e5 100644 +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -509,6 +509,8 @@ static void io_serial_out(struct uart_port *p, int offset, int value) + outb(value, p->iobase + offset); + } + ++static int serial8250_default_handle_irq(struct uart_port *port); ++ + static void set_io_from_upio(struct uart_port *p) + { + struct uart_8250_port *up = +@@ -557,6 +559,7 @@ static void set_io_from_upio(struct uart_port *p) + } + /* Remember loaded iotype */ + up->cur_iotype = p->iotype; ++ p->handle_irq = serial8250_default_handle_irq; + } + + static void +@@ -1621,6 +1624,28 @@ static void serial8250_handle_port(struct uart_8250_port *up) + spin_unlock_irqrestore(&up->port.lock, flags); + } + ++int serial8250_handle_irq(struct uart_port *port, unsigned int iir) ++{ ++ struct uart_8250_port *up = ++ container_of(port, struct uart_8250_port, port); ++ ++ if (!(iir & UART_IIR_NO_INT)) { ++ serial8250_handle_port(up); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static int serial8250_default_handle_irq(struct uart_port *port) ++{ ++ struct uart_8250_port *up = ++ container_of(port, struct uart_8250_port, port); ++ unsigned int iir = serial_in(up, UART_IIR); ++ ++ return serial8250_handle_irq(port, iir); ++} ++ + /* + * This is the serial driver's interrupt routine. + * +@@ -1648,13 +1673,12 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) + l = i->head; + do { + struct uart_8250_port *up; +- unsigned int iir; ++ struct uart_port *port; + + up = list_entry(l, struct uart_8250_port, list); ++ port = &up->port; + +- iir = serial_in(up, UART_IIR); +- if (!(iir & UART_IIR_NO_INT)) { +- serial8250_handle_port(up); ++ if (port->handle_irq(port)) { + + handled = 1; + +@@ -3050,6 +3074,10 @@ int __init early_serial_setup(struct uart_port *port) + p->serial_in = port->serial_in; + if (port->serial_out) + p->serial_out = port->serial_out; ++ if (port->handle_irq) ++ p->handle_irq = port->handle_irq; ++ else ++ p->handle_irq = serial8250_default_handle_irq; + + return 0; + } +@@ -3118,6 +3146,7 @@ static int __devinit serial8250_probe(struct platform_device *dev) + port.type = p->type; + port.serial_in = p->serial_in; + port.serial_out = p->serial_out; ++ port.handle_irq = p->handle_irq; + port.set_termios = p->set_termios; + port.pm = p->pm; + port.dev = &dev->dev; +@@ -3283,6 +3312,8 @@ int serial8250_register_port(struct uart_port *port) + 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; + /* Possibly override set_termios call */ + if (port->set_termios) + uart->port.set_termios = port->set_termios; +diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h +index 97f5b45..1f05bbe 100644 +--- a/include/linux/serial_8250.h ++++ b/include/linux/serial_8250.h +@@ -35,6 +35,7 @@ struct plat_serial8250_port { + void (*set_termios)(struct uart_port *, + struct ktermios *new, + struct ktermios *old); ++ int (*handle_irq)(struct uart_port *); + void (*pm)(struct uart_port *, unsigned int state, + unsigned old); + }; +@@ -80,6 +81,7 @@ extern void serial8250_do_set_termios(struct uart_port *port, + struct ktermios *termios, struct ktermios *old); + extern void serial8250_do_pm(struct uart_port *port, unsigned int state, + unsigned int oldstate); ++int serial8250_handle_irq(struct uart_port *port, unsigned int iir); + + extern void serial8250_set_isa_configurator(void (*v) + (int port, struct uart_port *up, +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0006-tty-serial8250-remove-UPIO_DWAPB-32.patch b/patches.kzm9g/0006-tty-serial8250-remove-UPIO_DWAPB-32.patch new file mode 100644 index 00000000000000..098799ff62900b --- /dev/null +++ b/patches.kzm9g/0006-tty-serial8250-remove-UPIO_DWAPB-32.patch @@ -0,0 +1,167 @@ +From ea7db772ed2f7cf3ce5d40ea3da4f4ead0505fb2 Mon Sep 17 00:00:00 2001 +From: Jamie Iles <jamie@jamieiles.com> +Date: Mon, 15 Aug 2011 10:17:55 +0100 +Subject: tty: serial8250: remove UPIO_DWAPB{,32} + +Now that platforms can override the port IRQ handler and the only user +of these UPIO modes has been converted over, kill off UPIO_DWAPB and +UPIO_DWAPB32. + +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Jamie Iles <jamie@jamieiles.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 4834d028978583dfe8e1fc19f1180ceb03d8dfb7) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250.c | 68 --------------------------------------- + drivers/tty/serial/serial_core.c | 4 -- + include/linux/serial_core.h | 4 -- + 3 files changed, 1 insertion(+), 75 deletions(-) + +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -461,42 +461,6 @@ static void tsi_serial_out(struct uart_p + writeb(value, p->membase + offset); + } + +-/* Save the LCR value so it can be re-written when a Busy Detect IRQ occurs. */ +-static inline void dwapb_save_out_value(struct uart_port *p, int offset, +- int value) +-{ +- struct uart_8250_port *up = +- container_of(p, struct uart_8250_port, port); +- +- if (offset == UART_LCR) +- up->lcr = value; +-} +- +-/* Read the IER to ensure any interrupt is cleared before returning from ISR. */ +-static inline void dwapb_check_clear_ier(struct uart_port *p, int offset) +-{ +- if (offset == UART_TX || offset == UART_IER) +- p->serial_in(p, UART_IER); +-} +- +-static void dwapb_serial_out(struct uart_port *p, int offset, int value) +-{ +- int save_offset = offset; +- offset = map_8250_out_reg(p, offset) << p->regshift; +- dwapb_save_out_value(p, save_offset, value); +- writeb(value, p->membase + offset); +- dwapb_check_clear_ier(p, save_offset); +-} +- +-static void dwapb32_serial_out(struct uart_port *p, int offset, int value) +-{ +- int save_offset = offset; +- offset = map_8250_out_reg(p, offset) << p->regshift; +- dwapb_save_out_value(p, save_offset, value); +- writel(value, p->membase + offset); +- dwapb_check_clear_ier(p, save_offset); +-} +- + static unsigned int io_serial_in(struct uart_port *p, int offset) + { + offset = map_8250_in_reg(p, offset) << p->regshift; +@@ -542,16 +506,6 @@ static void set_io_from_upio(struct uart + p->serial_out = tsi_serial_out; + break; + +- case UPIO_DWAPB: +- p->serial_in = mem_serial_in; +- p->serial_out = dwapb_serial_out; +- break; +- +- case UPIO_DWAPB32: +- p->serial_in = mem32_serial_in; +- p->serial_out = dwapb32_serial_out; +- break; +- + default: + p->serial_in = io_serial_in; + p->serial_out = io_serial_out; +@@ -570,8 +524,6 @@ serial_out_sync(struct uart_8250_port *u + case UPIO_MEM: + case UPIO_MEM32: + case UPIO_AU: +- case UPIO_DWAPB: +- case UPIO_DWAPB32: + p->serial_out(p, offset, value); + p->serial_in(p, UART_LCR); /* safe, no side-effects */ + break; +@@ -1679,23 +1631,7 @@ static irqreturn_t serial8250_interrupt( + port = &up->port; + + if (port->handle_irq(port)) { +- + handled = 1; +- +- end = NULL; +- } else if ((up->port.iotype == UPIO_DWAPB || +- up->port.iotype == UPIO_DWAPB32) && +- (iir & UART_IIR_BUSY) == UART_IIR_BUSY) { +- /* The DesignWare APB UART has an Busy Detect (0x07) +- * interrupt meaning an LCR write attempt occurred while the +- * UART was busy. The interrupt must be cleared by reading +- * the UART status register (USR) and the LCR re-written. */ +- unsigned int status; +- status = *(volatile u32 *)up->port.private_data; +- serial_out(up, UART_LCR, up->lcr); +- +- handled = 1; +- + end = NULL; + } else if (end == NULL) + end = l; +@@ -2594,8 +2530,6 @@ static int serial8250_request_std_resour + case UPIO_TSI: + case UPIO_MEM32: + case UPIO_MEM: +- case UPIO_DWAPB: +- case UPIO_DWAPB32: + if (!up->port.mapbase) + break; + +@@ -2632,8 +2566,6 @@ static void serial8250_release_std_resou + case UPIO_TSI: + case UPIO_MEM32: + case UPIO_MEM: +- case UPIO_DWAPB: +- case UPIO_DWAPB32: + if (!up->port.mapbase) + break; + +--- a/drivers/tty/serial/serial_core.c ++++ b/drivers/tty/serial/serial_core.c +@@ -2065,8 +2065,6 @@ uart_report_port(struct uart_driver *drv + case UPIO_MEM32: + case UPIO_AU: + case UPIO_TSI: +- case UPIO_DWAPB: +- case UPIO_DWAPB32: + snprintf(address, sizeof(address), + "MMIO 0x%llx", (unsigned long long)port->mapbase); + break; +@@ -2487,8 +2485,6 @@ int uart_match_port(struct uart_port *po + case UPIO_MEM32: + case UPIO_AU: + case UPIO_TSI: +- case UPIO_DWAPB: +- case UPIO_DWAPB32: + return (port1->mapbase == port2->mapbase); + } + return 0; +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -318,9 +318,7 @@ struct uart_port { + #define UPIO_MEM32 (3) + #define UPIO_AU (4) /* Au1x00 type IO */ + #define UPIO_TSI (5) /* Tsi108/109 type IO */ +-#define UPIO_DWAPB (6) /* DesignWare APB UART */ +-#define UPIO_RM9000 (7) /* RM9000 type IO */ +-#define UPIO_DWAPB32 (8) /* DesignWare APB UART (32 bit accesses) */ ++#define UPIO_RM9000 (6) /* RM9000 type IO */ + + unsigned int read_status_mask; /* driver specific */ + unsigned int ignore_status_mask; /* driver specific */ diff --git a/patches.kzm9g/0007-tty-8250-export-serial8250_handle_irq.patch b/patches.kzm9g/0007-tty-8250-export-serial8250_handle_irq.patch new file mode 100644 index 00000000000000..3d88d9e48044bb --- /dev/null +++ b/patches.kzm9g/0007-tty-8250-export-serial8250_handle_irq.patch @@ -0,0 +1,32 @@ +From e54750f312943c2135375552a80f417f969ec95f Mon Sep 17 00:00:00 2001 +From: Jamie Iles <jamie@jamieiles.com> +Date: Fri, 26 Aug 2011 19:04:49 +0100 +Subject: tty: 8250: export serial8250_handle_irq + +Allow modules to use the normal 8250 irq handler inside their own. + +Cc: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Jamie Iles <jamie@jamieiles.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit c7a1bdc5c951aae15021d13e3f5c0b2fe9d56112) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c +index 5d92b93..454fc92 100644 +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -1588,6 +1588,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) + + return 0; + } ++EXPORT_SYMBOL_GPL(serial8250_handle_irq); + + static int serial8250_default_handle_irq(struct uart_port *port) + { +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0008-serial-8250-Move-UPIO_TSI-to-powerpc.patch b/patches.kzm9g/0008-serial-8250-Move-UPIO_TSI-to-powerpc.patch new file mode 100644 index 00000000000000..c6b2a860b26229 --- /dev/null +++ b/patches.kzm9g/0008-serial-8250-Move-UPIO_TSI-to-powerpc.patch @@ -0,0 +1,129 @@ +From 173bc58b2e469e0f92a58de4b3644e171895300f Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann <arnd@arndb.de> +Date: Mon, 27 Jun 2011 11:45:16 +0000 +Subject: serial/8250: Move UPIO_TSI to powerpc + +This iotype is only used by the legacy_serial code in powerpc, so the +code should live there, rather than be compiled in for every 8250 +driver. + +Signed-off-by: Arnd Bergmann <arnd@arndb.de> +Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> +Cc: linuxppc-dev@lists.ozlabs.org +Cc: Greg Kroah-Hartman <gregkh@suse.de> +Cc: linux-serial@vger.kernel.org +Acked-by: David Daney <david.daney@cavium.com> +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +(cherry picked from commit 7df5659eefad9b6d457ccdee016bd78bd064cfc0) + +Conflicts: + + drivers/tty/serial/8250.c + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/powerpc/kernel/legacy_serial.c | 25 +++++++++++++++++++++++++ + drivers/tty/serial/8250.c | 23 ----------------------- + 2 files changed, 25 insertions(+), 23 deletions(-) + +diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c +index 2b97b80..c7b5afe 100644 +--- a/arch/powerpc/kernel/legacy_serial.c ++++ b/arch/powerpc/kernel/legacy_serial.c +@@ -6,6 +6,7 @@ + #include <linux/pci.h> + #include <linux/of_address.h> + #include <linux/of_device.h> ++#include <linux/serial_reg.h> + #include <asm/io.h> + #include <asm/mmu.h> + #include <asm/prom.h> +@@ -47,6 +48,24 @@ static struct __initdata of_device_id legacy_serial_parents[] = { + static unsigned int legacy_serial_count; + static int legacy_serial_console = -1; + ++static unsigned int tsi_serial_in(struct uart_port *p, int offset) ++{ ++ unsigned int tmp; ++ offset = offset << p->regshift; ++ if (offset == UART_IIR) { ++ tmp = readl(p->membase + (UART_IIR & ~3)); ++ return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */ ++ } else ++ return readb(p->membase + offset); ++} ++ ++static void tsi_serial_out(struct uart_port *p, int offset, int value) ++{ ++ offset = offset << p->regshift; ++ if (!((offset == UART_IER) && (value & UART_IER_UUE))) ++ writeb(value, p->membase + offset); ++} ++ + static int __init add_legacy_port(struct device_node *np, int want_index, + int iotype, phys_addr_t base, + phys_addr_t taddr, unsigned long irq, +@@ -102,6 +121,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index, + legacy_serial_ports[index].iobase = base; + else + legacy_serial_ports[index].mapbase = base; ++ + legacy_serial_ports[index].iotype = iotype; + legacy_serial_ports[index].uartclk = clock; + legacy_serial_ports[index].irq = irq; +@@ -112,6 +132,11 @@ static int __init add_legacy_port(struct device_node *np, int want_index, + legacy_serial_infos[index].speed = spd ? be32_to_cpup(spd) : 0; + legacy_serial_infos[index].irq_check_parent = irq_check_parent; + ++ if (iotype == UPIO_TSI) { ++ legacy_serial_ports[index].serial_in = tsi_serial_in; ++ legacy_serial_ports[index].serial_out = tsi_serial_out; ++ } ++ + printk(KERN_DEBUG "Found legacy serial port %d for %s\n", + index, np->full_name); + printk(KERN_DEBUG " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n", +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c +index 454fc92..a0e502b 100644 +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -443,24 +443,6 @@ static void au_serial_out(struct uart_port *p, int offset, int value) + __raw_writel(value, p->membase + offset); + } + +-static unsigned int tsi_serial_in(struct uart_port *p, int offset) +-{ +- unsigned int tmp; +- offset = map_8250_in_reg(p, offset) << p->regshift; +- if (offset == UART_IIR) { +- tmp = readl(p->membase + (UART_IIR & ~3)); +- return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */ +- } else +- return readb(p->membase + offset); +-} +- +-static void tsi_serial_out(struct uart_port *p, int offset, int value) +-{ +- offset = map_8250_out_reg(p, offset) << p->regshift; +- if (!((offset == UART_IER) && (value & UART_IER_UUE))) +- writeb(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; +@@ -501,11 +483,6 @@ static void set_io_from_upio(struct uart_port *p) + p->serial_out = au_serial_out; + break; + +- case UPIO_TSI: +- p->serial_in = tsi_serial_in; +- p->serial_out = tsi_serial_out; +- break; +- + default: + p->serial_in = io_serial_in; + p->serial_out = io_serial_out; +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0009-serial-Support-the-EFR-register-of-XR1715x-uarts.patch b/patches.kzm9g/0009-serial-Support-the-EFR-register-of-XR1715x-uarts.patch new file mode 100644 index 00000000000000..43c28f5c3a3329 --- /dev/null +++ b/patches.kzm9g/0009-serial-Support-the-EFR-register-of-XR1715x-uarts.patch @@ -0,0 +1,159 @@ +From 5df029e7baab27a7b6f848739659865a006820f9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?S=C3=B8ren=20Holm?= <sgh@sgh.dk> +Date: Fri, 2 Sep 2011 22:55:37 +0200 +Subject: serial: Support the EFR-register of XR1715x uarts. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The EFR (Enhenced-Features-Register) is located at a different offset +than the other devices supporting UART_CAP_EFR. This change add a special +setup quick to set UPF_EXAR_EFR on the port. UPF_EXAR_EFR is then used to +the port type to PORT_XR17D15X since it is for sure a XR17D15X uart. + +Signed-off-by: Søren Holm <sgh@sgh.dk> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 06315348b16178e4c006e7892ef8e5e65f49c66a) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250.c | 20 +++++++++++++++++++- + drivers/tty/serial/8250_pci.c | 33 +++++++++++++++++++++++++++++++++ + include/linux/serial_core.h | 4 +++- + include/linux/serial_reg.h | 1 + + 4 files changed, 56 insertions(+), 2 deletions(-) + +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c +index a0e502b..69802bd 100644 +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -309,6 +309,13 @@ static const struct serial8250_config uart_config[] = { + UART_FCR_T_TRIG_01, + .flags = UART_CAP_FIFO | UART_CAP_RTOIE, + }, ++ [PORT_XR17D15X] = { ++ .name = "XR17D15X", ++ .fifo_size = 64, ++ .tx_loadsz = 64, ++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, ++ .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR, ++ }, + }; + + #if defined(CONFIG_MIPS_ALCHEMY) +@@ -1052,6 +1059,14 @@ static void autoconfig_16550a(struct uart_8250_port *up) + serial_outp(up, UART_IER, iersave); + + /* ++ * Exar uarts have EFR in a weird location ++ */ ++ if (up->port.flags & UPF_EXAR_EFR) { ++ up->port.type = PORT_XR17D15X; ++ up->capabilities |= UART_CAP_AFE | UART_CAP_EFR; ++ } ++ ++ /* + * We distinguish between 16550A and U6 16550A by counting + * how many bytes are in the FIFO. + */ +@@ -2396,7 +2411,10 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + efr |= UART_EFR_CTS; + + serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); +- serial_outp(up, UART_EFR, efr); ++ if (up->port.flags & UPF_EXAR_EFR) ++ serial_outp(up, UART_XR_EFR, efr); ++ else ++ serial_outp(up, UART_EFR, efr); + } + + #ifdef CONFIG_ARCH_OMAP +diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c +index ff48fdb..a213f38 100644 +--- a/drivers/tty/serial/8250_pci.c ++++ b/drivers/tty/serial/8250_pci.c +@@ -1003,6 +1003,15 @@ static int pci_eg20t_init(struct pci_dev *dev) + #endif + } + ++static int ++pci_xr17c154_setup(struct serial_private *priv, ++ const struct pciserial_board *board, ++ struct uart_port *port, int idx) ++{ ++ port->flags |= UPF_EXAR_EFR; ++ return pci_default_setup(priv, board, port, idx); ++} ++ + /* This should be in linux/pci_ids.h */ + #define PCI_VENDOR_ID_SBSMODULARIO 0x124B + #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B +@@ -1407,6 +1416,30 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { + .setup = pci_timedia_setup, + }, + /* ++ * Exar cards ++ */ ++ { ++ .vendor = PCI_VENDOR_ID_EXAR, ++ .device = PCI_DEVICE_ID_EXAR_XR17C152, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .setup = pci_xr17c154_setup, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_EXAR, ++ .device = PCI_DEVICE_ID_EXAR_XR17C154, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .setup = pci_xr17c154_setup, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_EXAR, ++ .device = PCI_DEVICE_ID_EXAR_XR17C158, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .setup = pci_xr17c154_setup, ++ }, ++ /* + * Xircom cards + */ + { +diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h +index 4880024..d611ca0 100644 +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -46,7 +46,8 @@ + #define PORT_AR7 18 /* Texas Instruments AR7 internal UART */ + #define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */ + #define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */ +-#define PORT_MAX_8250 20 /* max port ID */ ++#define PORT_XR17D15X 21 /* Exar XR17D15x UART */ ++#define PORT_MAX_8250 21 /* max port ID */ + + /* + * ARM specific type numbers. These are not currently guaranteed +@@ -349,6 +350,7 @@ struct uart_port { + #define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16)) + #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) + #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) ++#define UPF_EXAR_EFR ((__force upf_t) (1 << 25)) + /* The exact UART type is known and should not be probed. */ + #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) + #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) +diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h +index c75bda3..8ce70d7 100644 +--- a/include/linux/serial_reg.h ++++ b/include/linux/serial_reg.h +@@ -152,6 +152,7 @@ + * LCR=0xBF (or DLAB=1 for 16C660) + */ + #define UART_EFR 2 /* I/O: Extended Features Register */ ++#define UART_XR_EFR 9 /* I/O: Extended Features Register (XR17D15x) */ + #define UART_EFR_CTS 0x80 /* CTS flow control */ + #define UART_EFR_RTS 0x40 /* RTS flow control */ + #define UART_EFR_SCD 0x20 /* Special character detect */ +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/001-ltsi-backport-arm-mach-shmobile-kzm9g-add-smsc-9221-support.patch b/patches.kzm9g/001-ltsi-backport-arm-mach-shmobile-kzm9g-add-smsc-9221-support.patch new file mode 100644 index 00000000000000..19dc86158db1ec --- /dev/null +++ b/patches.kzm9g/001-ltsi-backport-arm-mach-shmobile-kzm9g-add-smsc-9221-support.patch @@ -0,0 +1,96 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Tue Jun 26 04:09:54 2012 +From: Tetsuyuki Kobayashi <koba@kmckk.co.jp> +Date: Tue, 26 Jun 2012 20:09:49 +0900 +Subject: [LTSI-dev] [PATCH 1/4] LTSI: backport: ARM: mach-shmobile: kzm9g: add SMSC 9221 support +To: ltsi-dev@lists.linuxfoundation.org +Cc: kuninori.morimoto.gx@gmail.com +Message-ID: <4FE9987D.9080304@kmckk.co.jp> + + +This is backport of +commit c15c4257a7858c6670f54c667f804df86a9fff1c + +Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp> +--- + arch/arm/mach-shmobile/board-kzm9g.c | 38 ++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c +index e0fd6e2..35af2f8 100644 +--- a/arch/arm/mach-shmobile/board-kzm9g.c ++++ b/arch/arm/mach-shmobile/board-kzm9g.c +@@ -30,6 +30,7 @@ + #include <linux/mmc/sh_mobile_sdhi.h> + #include <linux/mfd/tmio.h> + #include <linux/platform_device.h> ++#include <linux/smsc911x.h> + #include <linux/videodev2.h> + #include <sound/sh_fsi.h> + #include <sound/simple_card.h> +@@ -62,6 +63,35 @@ + * # amixer set "LINEOUT Mixer DACL" on + */ + ++/* SMSC 9221 */ ++static struct resource smsc9221_resources[] = { ++ [0] = { ++ .start = 0x10000000, /* CS4 */ ++ .end = 0x100000ff, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = intcs_evt2irq(0x260), /* IRQ3 */ ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct smsc911x_platform_config smsc9221_platdata = { ++ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, ++ .phy_interface = PHY_INTERFACE_MODE_MII, ++ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, ++ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, ++}; ++ ++static struct platform_device smsc_device = { ++ .name = "smsc911x", ++ .dev = { ++ .platform_data = &smsc9221_platdata, ++ }, ++ .resource = smsc9221_resources, ++ .num_resources = ARRAY_SIZE(smsc9221_resources), ++}; ++ + /* LCDC */ + static struct fb_videomode kzm_lcdc_mode = { + .name = "WVGA Panel", +@@ -299,6 +329,7 @@ static struct i2c_board_info i2c3_devices[] = { + }; + + static struct platform_device *kzm_devices[] __initdata = { ++ &smsc_device, + &lcdc_device, + &mmc_device, + &sdhi0_device, +@@ -443,6 +474,13 @@ static void __init kzm_init(void) + gpio_request(GPIO_FN_FSIAISLD, NULL); + gpio_request(GPIO_FN_FSIAOSLD, NULL); + ++ /* CS4 for SMSC/USB */ ++ gpio_request(GPIO_FN_CS4_, NULL); /* CS4 */ ++ ++ /* SMSC */ ++ gpio_request(GPIO_PORT224, NULL); /* IRQ3 */ ++ gpio_direction_input(GPIO_PORT224); ++ + #ifdef CONFIG_CACHE_L2X0 + /* Early BRESP enable, Shared attribute override enable, 64K*8way */ + l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff); +-- +1.7.9.5 + + +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.kzm9g/0010-8250-ratelimit-LSR-safety-check-engaged-warning.patch b/patches.kzm9g/0010-8250-ratelimit-LSR-safety-check-engaged-warning.patch new file mode 100644 index 00000000000000..14fcdd5e5e0251 --- /dev/null +++ b/patches.kzm9g/0010-8250-ratelimit-LSR-safety-check-engaged-warning.patch @@ -0,0 +1,44 @@ +From 72ad6d3c5d84c98203676d587b25898690591ab7 Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Date: Mon, 26 Sep 2011 09:14:34 -0400 +Subject: 8250: ratelimit LSR safety check engaged warning. + +On my BIOSTAR TA890FXE the ttyS0 ends up spewing: + +[904682.485933] ttyS0: LSR safety check engaged! +[904692.505895] ttyS0: LSR safety check engaged! +[904702.525972] ttyS0: LSR safety check engaged! +[904712.545967] ttyS0: LSR safety check engaged! +[904722.566125] ttyS0: LSR safety check engaged! +.. +lets limit it so it won't be the only thing visible +in the ring buffer. + +CC: Alan Cox <alan@linux.intel.com> +Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 7808a4c4853fa0203085cf2217e01823d9f0c70c) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c +index 69802bd..eeadf1b 100644 +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -2034,8 +2034,8 @@ static int serial8250_startup(struct uart_port *port) + */ + if (!(up->port.flags & UPF_BUGGY_UART) && + (serial_inp(up, UART_LSR) == 0xff)) { +- printk(KERN_INFO "ttyS%d: LSR safety check engaged!\n", +- serial_index(&up->port)); ++ printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", ++ serial_index(&up->port)); + return -ENODEV; + } + +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0011-serial-8250-replace-hardcoded-0xbf-with-define.patch b/patches.kzm9g/0011-serial-8250-replace-hardcoded-0xbf-with-define.patch new file mode 100644 index 00000000000000..97c8003f6ac0d1 --- /dev/null +++ b/patches.kzm9g/0011-serial-8250-replace-hardcoded-0xbf-with-define.patch @@ -0,0 +1,33 @@ +From 698dcc00ab4b72502d3b69bf1167b7c3977f5e5a Mon Sep 17 00:00:00 2001 +From: Wolfram Sang <w.sang@pengutronix.de> +Date: Fri, 9 Dec 2011 18:07:13 +0100 +Subject: serial: 8250: replace hardcoded 0xbf with #define + +Makes it easier to find all occurences requesting CONF_MODE_B. + +Signed-off-by: Wolfram Sang <w.sang@pengutronix.de> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 7d73aaf1d45d9bd95638680361db4d019ebb75bb) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c +index eeadf1b..f8f2320 100644 +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -2000,7 +2000,7 @@ static int serial8250_startup(struct uart_port *port) + serial_outp(up, UART_IER, 0); + serial_outp(up, UART_LCR, 0); + serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ +- serial_outp(up, UART_LCR, 0xBF); ++ serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); + serial_outp(up, UART_EFR, UART_EFR_ECB); + serial_outp(up, UART_LCR, 0); + } +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0012-serial-move-struct-uart_8250_port-from-8250.c-to-825.patch b/patches.kzm9g/0012-serial-move-struct-uart_8250_port-from-8250.c-to-825.patch new file mode 100644 index 00000000000000..1c8f17df539bfc --- /dev/null +++ b/patches.kzm9g/0012-serial-move-struct-uart_8250_port-from-8250.c-to-825.patch @@ -0,0 +1,98 @@ +From 028e3de52cdfd054b54d0ff7c2b576aaf299a1df Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Sun, 4 Dec 2011 18:42:18 -0500 +Subject: serial: move struct uart_8250_port from 8250.c to 8250.h + +Since we want to promote sharing and move away from one single +uart driver with a bunch of platform specific bugfixes all +munged into one, relocate some header like material from +the C file to the header. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 850624c15da4651f4c6b821723419d8777659577) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250.c | 26 -------------------------- + drivers/tty/serial/8250.h | 26 ++++++++++++++++++++++++++ + 2 files changed, 26 insertions(+), 26 deletions(-) + +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c +index f8f2320..4a60d74 100644 +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -129,32 +129,6 @@ static unsigned long probe_rsa[PORT_RSA_MAX]; + static unsigned int probe_rsa_count; + #endif /* CONFIG_SERIAL_8250_RSA */ + +-struct uart_8250_port { +- struct uart_port port; +- struct timer_list timer; /* "no irq" timer */ +- struct list_head list; /* ports on this IRQ */ +- unsigned short capabilities; /* port capabilities */ +- unsigned short bugs; /* port bugs */ +- unsigned int tx_loadsz; /* transmit fifo load size */ +- unsigned char acr; +- unsigned char ier; +- unsigned char lcr; +- unsigned char mcr; +- unsigned char mcr_mask; /* mask of user bits */ +- unsigned char mcr_force; /* mask of forced bits */ +- unsigned char cur_iotype; /* Running I/O type */ +- +- /* +- * Some bits in registers are cleared on a read, so they must +- * be saved whenever the register is read but the bits will not +- * be immediately processed. +- */ +-#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS +- unsigned char lsr_saved_flags; +-#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA +- unsigned char msr_saved_flags; +-}; +- + struct irq_info { + struct hlist_node node; + int irq; +diff --git a/drivers/tty/serial/8250.h b/drivers/tty/serial/8250.h +index 6edf4a6..ae027be 100644 +--- a/drivers/tty/serial/8250.h ++++ b/drivers/tty/serial/8250.h +@@ -13,6 +13,32 @@ + + #include <linux/serial_8250.h> + ++struct uart_8250_port { ++ struct uart_port port; ++ struct timer_list timer; /* "no irq" timer */ ++ struct list_head list; /* ports on this IRQ */ ++ unsigned short capabilities; /* port capabilities */ ++ unsigned short bugs; /* port bugs */ ++ unsigned int tx_loadsz; /* transmit fifo load size */ ++ unsigned char acr; ++ unsigned char ier; ++ unsigned char lcr; ++ unsigned char mcr; ++ unsigned char mcr_mask; /* mask of user bits */ ++ unsigned char mcr_force; /* mask of forced bits */ ++ unsigned char cur_iotype; /* Running I/O type */ ++ ++ /* ++ * Some bits in registers are cleared on a read, so they must ++ * be saved whenever the register is read but the bits will not ++ * be immediately processed. ++ */ ++#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS ++ unsigned char lsr_saved_flags; ++#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA ++ unsigned char msr_saved_flags; ++}; ++ + struct old_serial_port { + unsigned int uart; + unsigned int baud_base; +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0013-serial-clean-up-parameter-passing-for-8250-Rx-IRQ-ha.patch b/patches.kzm9g/0013-serial-clean-up-parameter-passing-for-8250-Rx-IRQ-ha.patch new file mode 100644 index 00000000000000..918651f8c8b27b --- /dev/null +++ b/patches.kzm9g/0013-serial-clean-up-parameter-passing-for-8250-Rx-IRQ-ha.patch @@ -0,0 +1,79 @@ +From 955d6b2ede1041858602dacb15c624bf8aa325f8 Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Sun, 4 Dec 2011 18:42:19 -0500 +Subject: serial: clean up parameter passing for 8250 Rx IRQ handling + +The receive_chars() was taking a pointer to a passed in LSR value +in status and knocking off bits as it processed them. But since +receive_chars isn't returning a value, we can instead pass in +a normal non-pointer value for LSR, and simply return the +residual (unprocessed) LSR once it is done. + +The value in this cleanup, is that it clarifies the API of the +receive_chars prior to exporting it to other 8250-like drivers +for shared usage. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 0690f41fddd285c3473e4af2a42d15bce7ff3e68) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c +index 4a60d74..fbcd8a5 100644 +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -1375,11 +1375,16 @@ static void clear_rx_fifo(struct uart_8250_port *up) + } while (1); + } + +-static void +-receive_chars(struct uart_8250_port *up, unsigned int *status) ++/* ++ * receive_chars: processes according to the passed in LSR ++ * value, and returns the remaining LSR bits not handled ++ * by this Rx routine. ++ */ ++static unsigned char ++receive_chars(struct uart_8250_port *up, unsigned char lsr) + { + struct tty_struct *tty = up->port.state->port.tty; +- unsigned char ch, lsr = *status; ++ unsigned char ch; + int max_count = 256; + char flag; + +@@ -1455,7 +1460,7 @@ ignore_char: + spin_unlock(&up->port.lock); + tty_flip_buffer_push(tty); + spin_lock(&up->port.lock); +- *status = lsr; ++ return lsr; + } + + static void transmit_chars(struct uart_8250_port *up) +@@ -1524,7 +1529,7 @@ static unsigned int check_modem_status(struct uart_8250_port *up) + */ + static void serial8250_handle_port(struct uart_8250_port *up) + { +- unsigned int status; ++ unsigned char status; + unsigned long flags; + + spin_lock_irqsave(&up->port.lock, flags); +@@ -1534,7 +1539,7 @@ static void serial8250_handle_port(struct uart_8250_port *up) + DEBUG_INTR("status = %x...", status); + + if (status & (UART_LSR_DR | UART_LSR_BI)) +- receive_chars(up, &status); ++ status = receive_chars(up, status); + check_modem_status(up); + if (status & UART_LSR_THRE) + transmit_chars(up); +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0014-serial-export-the-key-functions-for-an-8250-IRQ-hand.patch b/patches.kzm9g/0014-serial-export-the-key-functions-for-an-8250-IRQ-hand.patch new file mode 100644 index 00000000000000..04b2ab12162ff9 --- /dev/null +++ b/patches.kzm9g/0014-serial-export-the-key-functions-for-an-8250-IRQ-hand.patch @@ -0,0 +1,161 @@ +From d55f600016446155f3d9a86467566353071c7205 Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Sun, 4 Dec 2011 18:42:20 -0500 +Subject: serial: export the key functions for an 8250 IRQ handler + +For drivers that need to construct their own IRQ handler, the +three components are seen in the current handle_port -- i.e. +Rx, Tx and modem_status. + +Make these exported symbols so that "almost" 8250 UARTs can +construct their own IRQ handler with these shared components, +while working around their own unique errata issues. + +The function names are given a serial8250 prefix, since they +are now entering the global namespace. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 3986fb2ba67bb30cac18b0cff48c88d69ad37681) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250.c | 29 +++++++++++++++-------------- + include/linux/serial_8250.h | 4 ++++ + 2 files changed, 19 insertions(+), 14 deletions(-) + +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c +index fbcd8a5..d759fcc 100644 +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -1300,8 +1300,6 @@ static void serial8250_stop_tx(struct uart_port *port) + } + } + +-static void transmit_chars(struct uart_8250_port *up); +- + static void serial8250_start_tx(struct uart_port *port) + { + struct uart_8250_port *up = +@@ -1318,7 +1316,7 @@ static void serial8250_start_tx(struct uart_port *port) + if ((up->port.type == PORT_RM9000) ? + (lsr & UART_LSR_THRE) : + (lsr & UART_LSR_TEMT)) +- transmit_chars(up); ++ serial8250_tx_chars(up); + } + } + +@@ -1376,12 +1374,12 @@ static void clear_rx_fifo(struct uart_8250_port *up) + } + + /* +- * receive_chars: processes according to the passed in LSR ++ * serial8250_rx_chars: processes according to the passed in LSR + * value, and returns the remaining LSR bits not handled + * by this Rx routine. + */ +-static unsigned char +-receive_chars(struct uart_8250_port *up, unsigned char lsr) ++unsigned char ++serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) + { + struct tty_struct *tty = up->port.state->port.tty; + unsigned char ch; +@@ -1462,8 +1460,9 @@ ignore_char: + spin_lock(&up->port.lock); + return lsr; + } ++EXPORT_SYMBOL_GPL(serial8250_rx_chars); + +-static void transmit_chars(struct uart_8250_port *up) ++void serial8250_tx_chars(struct uart_8250_port *up) + { + struct circ_buf *xmit = &up->port.state->xmit; + int count; +@@ -1500,8 +1499,9 @@ static void transmit_chars(struct uart_8250_port *up) + if (uart_circ_empty(xmit)) + __stop_tx(up); + } ++EXPORT_SYMBOL_GPL(serial8250_tx_chars); + +-static unsigned int check_modem_status(struct uart_8250_port *up) ++unsigned int serial8250_modem_status(struct uart_8250_port *up) + { + unsigned int status = serial_in(up, UART_MSR); + +@@ -1523,6 +1523,7 @@ static unsigned int check_modem_status(struct uart_8250_port *up) + + return status; + } ++EXPORT_SYMBOL_GPL(serial8250_modem_status); + + /* + * This handles the interrupt from one port. +@@ -1539,10 +1540,10 @@ static void serial8250_handle_port(struct uart_8250_port *up) + DEBUG_INTR("status = %x...", status); + + if (status & (UART_LSR_DR | UART_LSR_BI)) +- status = receive_chars(up, status); +- check_modem_status(up); ++ status = serial8250_rx_chars(up, status); ++ serial8250_modem_status(up); + if (status & UART_LSR_THRE) +- transmit_chars(up); ++ serial8250_tx_chars(up); + + spin_unlock_irqrestore(&up->port.lock, flags); + } +@@ -1780,7 +1781,7 @@ static void serial8250_backup_timeout(unsigned long data) + } + + if (!(iir & UART_IIR_NO_INT)) +- transmit_chars(up); ++ serial8250_tx_chars(up); + + if (is_real_interrupt(up->port.irq)) + serial_out(up, UART_IER, ier); +@@ -1814,7 +1815,7 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port) + unsigned int status; + unsigned int ret; + +- status = check_modem_status(up); ++ status = serial8250_modem_status(up); + + ret = 0; + if (status & UART_MSR_DCD) +@@ -2861,7 +2862,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) + * while processing with interrupts off. + */ + if (up->msr_saved_flags) +- check_modem_status(up); ++ serial8250_modem_status(up); + + if (locked) + spin_unlock(&up->port.lock); +diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h +index 1f05bbe..b44034e 100644 +--- a/include/linux/serial_8250.h ++++ b/include/linux/serial_8250.h +@@ -66,6 +66,7 @@ enum { + * dependent on the 8250 driver. + */ + struct uart_port; ++struct uart_8250_port; + + int serial8250_register_port(struct uart_port *); + void serial8250_unregister_port(int line); +@@ -82,6 +83,9 @@ extern void serial8250_do_set_termios(struct uart_port *port, + extern void serial8250_do_pm(struct uart_port *port, unsigned int state, + unsigned int oldstate); + int serial8250_handle_irq(struct uart_port *port, unsigned int iir); ++unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr); ++void serial8250_tx_chars(struct uart_8250_port *up); ++unsigned int serial8250_modem_status(struct uart_8250_port *up); + + extern void serial8250_set_isa_configurator(void (*v) + (int port, struct uart_port *up, +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0015-serial-make-8250-timeout-use-the-specified-IRQ-handl.patch b/patches.kzm9g/0015-serial-make-8250-timeout-use-the-specified-IRQ-handl.patch new file mode 100644 index 00000000000000..7205efee649dcb --- /dev/null +++ b/patches.kzm9g/0015-serial-make-8250-timeout-use-the-specified-IRQ-handl.patch @@ -0,0 +1,51 @@ +From 6f7a0cbda97ea6ac36b334a2639275f60f830390 Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Sun, 4 Dec 2011 18:42:21 -0500 +Subject: serial: make 8250 timeout use the specified IRQ handler + +The current 8250 timeout code duplicates the code path in +serial8250_default_handle_irq and then serial8250_handle_irq +i.e. reading iir, check for IIR_NO_INT, and then calling +serial8250_handle_port. + +So the immediate thought is to replace the duplicated code +with a call to serial8250_default_handle_irq. + +But this highlights a problem. We let 8250 driver variants +use their own IRQ handler via specifying their own custom +->handle_irq, but in the event of a timeout, we ignore their +handler and implicitly run serial8250_default_handle_irq instead. + +So, go through the struct to get ->handle_irq and call that, +which for most will still be serial8250_default_handle_irq. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit a0431476e95d18bb65349e7bcf98eb10b5ad00b9) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c +index d759fcc..a5c6c7d 100644 +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -1738,11 +1738,8 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up) + static void serial8250_timeout(unsigned long data) + { + struct uart_8250_port *up = (struct uart_8250_port *)data; +- unsigned int iir; + +- iir = serial_in(up, UART_IIR); +- if (!(iir & UART_IIR_NO_INT)) +- serial8250_handle_port(up); ++ up->port.handle_irq(&up->port); + mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port)); + } + +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0016-serial-manually-inline-serial8250_handle_port.patch b/patches.kzm9g/0016-serial-manually-inline-serial8250_handle_port.patch new file mode 100644 index 00000000000000..e14803ceb1e44e --- /dev/null +++ b/patches.kzm9g/0016-serial-manually-inline-serial8250_handle_port.patch @@ -0,0 +1,77 @@ +From f1e4b73758b9bead03589febddcb3dba5132ddf7 Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Sun, 4 Dec 2011 18:42:22 -0500 +Subject: serial: manually inline serial8250_handle_port + +Currently serial8250_handle_irq is a trivial wrapper around +serial8250_handle_port, which actually does all the work. + +Since there are no other callers of serial8250_handle_port, we +can just move it inline into serial8250_handle_irq. This also +makes it more clear what functionality any custom IRQ handlers +need to provide if not using serial8250_default_handle_irq. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 86b21199fc45e0052e181fefc07c747e9dc903b3) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250.c | 23 ++++++++--------------- + 1 file changed, 8 insertions(+), 15 deletions(-) + +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c +index a5c6c7d..047221d 100644 +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -1528,10 +1528,15 @@ EXPORT_SYMBOL_GPL(serial8250_modem_status); + /* + * This handles the interrupt from one port. + */ +-static void serial8250_handle_port(struct uart_8250_port *up) ++int serial8250_handle_irq(struct uart_port *port, unsigned int iir) + { + unsigned char status; + unsigned long flags; ++ struct uart_8250_port *up = ++ container_of(port, struct uart_8250_port, port); ++ ++ if (iir & UART_IIR_NO_INT) ++ return 0; + + spin_lock_irqsave(&up->port.lock, flags); + +@@ -1546,19 +1551,7 @@ static void serial8250_handle_port(struct uart_8250_port *up) + serial8250_tx_chars(up); + + spin_unlock_irqrestore(&up->port.lock, flags); +-} +- +-int serial8250_handle_irq(struct uart_port *port, unsigned int iir) +-{ +- struct uart_8250_port *up = +- container_of(port, struct uart_8250_port, port); +- +- if (!(iir & UART_IIR_NO_INT)) { +- serial8250_handle_port(up); +- return 1; +- } +- +- return 0; ++ return 1; + } + EXPORT_SYMBOL_GPL(serial8250_handle_irq); + +@@ -2825,7 +2818,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) + + local_irq_save(flags); + if (up->port.sysrq) { +- /* serial8250_handle_port() already took the lock */ ++ /* serial8250_handle_irq() already took the lock */ + locked = 0; + } else if (oops_in_progress) { + locked = spin_trylock(&up->port.lock); +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0017-serial-group-all-the-8250-related-code-together.patch b/patches.kzm9g/0017-serial-group-all-the-8250-related-code-together.patch new file mode 100644 index 00000000000000..d045b50b493364 --- /dev/null +++ b/patches.kzm9g/0017-serial-group-all-the-8250-related-code-together.patch @@ -0,0 +1,746 @@ +From 1ab1670cb4d8cba1870f9dc3fd7806262f72a904 Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Thu, 5 Jan 2012 18:21:43 -0500 +Subject: serial: group all the 8250 related code together + +The drivers/tty/serial dir is already getting rather busy. +Relocate the 8250 related drivers to their own subdir to +reduce the clutter. + +Note that sunsu.c is not included in this move -- it is +8250-like hardware, but it does not use any of the existing +infrastructure -- and does not depend on SERIAL_8250. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 9bef3d4197379a995fa80f81950bbbf8d32e9e8b) + +Conflicts: + + drivers/tty/serial/8250/Kconfig + drivers/tty/serial/8250/Makefile + drivers/tty/serial/8250/8250_dw.c + drivers/tty/serial/8250/8250_fsl.c + drivers/tty/serial/Kconfig + drivers/tty/serial/Makefile + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/{ => 8250}/8250.c | 0 + drivers/tty/serial/{ => 8250}/8250.h | 0 + drivers/tty/serial/{ => 8250}/8250_accent.c | 0 + drivers/tty/serial/{ => 8250}/8250_acorn.c | 0 + drivers/tty/serial/{ => 8250}/8250_boca.c | 0 + drivers/tty/serial/{ => 8250}/8250_early.c | 0 + drivers/tty/serial/{ => 8250}/8250_exar_st16c554.c | 0 + drivers/tty/serial/{ => 8250}/8250_fourport.c | 0 + drivers/tty/serial/{ => 8250}/8250_gsc.c | 0 + drivers/tty/serial/{ => 8250}/8250_hp300.c | 0 + drivers/tty/serial/{ => 8250}/8250_hub6.c | 0 + drivers/tty/serial/{ => 8250}/8250_mca.c | 0 + drivers/tty/serial/{ => 8250}/8250_pci.c | 0 + drivers/tty/serial/{ => 8250}/8250_pnp.c | 0 + drivers/tty/serial/8250/Kconfig | 268 ++++++++++++++++++++ + drivers/tty/serial/8250/Makefile | 18 ++ + drivers/tty/serial/{ => 8250}/m32r_sio.c | 0 + drivers/tty/serial/{ => 8250}/m32r_sio.h | 0 + drivers/tty/serial/{ => 8250}/m32r_sio_reg.h | 0 + drivers/tty/serial/{ => 8250}/serial_cs.c | 0 + drivers/tty/serial/Kconfig | 262 +------------------ + drivers/tty/serial/Makefile | 17 +- + 22 files changed, 290 insertions(+), 275 deletions(-) + rename drivers/tty/serial/{ => 8250}/8250.c (100%) + rename drivers/tty/serial/{ => 8250}/8250.h (100%) + rename drivers/tty/serial/{ => 8250}/8250_accent.c (100%) + rename drivers/tty/serial/{ => 8250}/8250_acorn.c (100%) + rename drivers/tty/serial/{ => 8250}/8250_boca.c (100%) + rename drivers/tty/serial/{ => 8250}/8250_early.c (100%) + rename drivers/tty/serial/{ => 8250}/8250_exar_st16c554.c (100%) + rename drivers/tty/serial/{ => 8250}/8250_fourport.c (100%) + rename drivers/tty/serial/{ => 8250}/8250_gsc.c (100%) + rename drivers/tty/serial/{ => 8250}/8250_hp300.c (100%) + rename drivers/tty/serial/{ => 8250}/8250_hub6.c (100%) + rename drivers/tty/serial/{ => 8250}/8250_mca.c (100%) + rename drivers/tty/serial/{ => 8250}/8250_pci.c (100%) + rename drivers/tty/serial/{ => 8250}/8250_pnp.c (100%) + create mode 100644 drivers/tty/serial/8250/Kconfig + create mode 100644 drivers/tty/serial/8250/Makefile + rename drivers/tty/serial/{ => 8250}/m32r_sio.c (100%) + rename drivers/tty/serial/{ => 8250}/m32r_sio.h (100%) + rename drivers/tty/serial/{ => 8250}/m32r_sio_reg.h (100%) + rename drivers/tty/serial/{ => 8250}/serial_cs.c (100%) + +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250/8250.c +similarity index 100% +rename from drivers/tty/serial/8250.c +rename to drivers/tty/serial/8250/8250.c +diff --git a/drivers/tty/serial/8250.h b/drivers/tty/serial/8250/8250.h +similarity index 100% +rename from drivers/tty/serial/8250.h +rename to drivers/tty/serial/8250/8250.h +diff --git a/drivers/tty/serial/8250_accent.c b/drivers/tty/serial/8250/8250_accent.c +similarity index 100% +rename from drivers/tty/serial/8250_accent.c +rename to drivers/tty/serial/8250/8250_accent.c +diff --git a/drivers/tty/serial/8250_acorn.c b/drivers/tty/serial/8250/8250_acorn.c +similarity index 100% +rename from drivers/tty/serial/8250_acorn.c +rename to drivers/tty/serial/8250/8250_acorn.c +diff --git a/drivers/tty/serial/8250_boca.c b/drivers/tty/serial/8250/8250_boca.c +similarity index 100% +rename from drivers/tty/serial/8250_boca.c +rename to drivers/tty/serial/8250/8250_boca.c +diff --git a/drivers/tty/serial/8250_early.c b/drivers/tty/serial/8250/8250_early.c +similarity index 100% +rename from drivers/tty/serial/8250_early.c +rename to drivers/tty/serial/8250/8250_early.c +diff --git a/drivers/tty/serial/8250_exar_st16c554.c b/drivers/tty/serial/8250/8250_exar_st16c554.c +similarity index 100% +rename from drivers/tty/serial/8250_exar_st16c554.c +rename to drivers/tty/serial/8250/8250_exar_st16c554.c +diff --git a/drivers/tty/serial/8250_fourport.c b/drivers/tty/serial/8250/8250_fourport.c +similarity index 100% +rename from drivers/tty/serial/8250_fourport.c +rename to drivers/tty/serial/8250/8250_fourport.c +diff --git a/drivers/tty/serial/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c +similarity index 100% +rename from drivers/tty/serial/8250_gsc.c +rename to drivers/tty/serial/8250/8250_gsc.c +diff --git a/drivers/tty/serial/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c +similarity index 100% +rename from drivers/tty/serial/8250_hp300.c +rename to drivers/tty/serial/8250/8250_hp300.c +diff --git a/drivers/tty/serial/8250_hub6.c b/drivers/tty/serial/8250/8250_hub6.c +similarity index 100% +rename from drivers/tty/serial/8250_hub6.c +rename to drivers/tty/serial/8250/8250_hub6.c +diff --git a/drivers/tty/serial/8250_mca.c b/drivers/tty/serial/8250/8250_mca.c +similarity index 100% +rename from drivers/tty/serial/8250_mca.c +rename to drivers/tty/serial/8250/8250_mca.c +diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +similarity index 100% +rename from drivers/tty/serial/8250_pci.c +rename to drivers/tty/serial/8250/8250_pci.c +diff --git a/drivers/tty/serial/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c +similarity index 100% +rename from drivers/tty/serial/8250_pnp.c +rename to drivers/tty/serial/8250/8250_pnp.c +diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig +new file mode 100644 +index 0000000..b1bb251 +--- /dev/null ++++ b/drivers/tty/serial/8250/Kconfig +@@ -0,0 +1,268 @@ ++# ++# The 8250/16550 serial drivers. You shouldn't be in this list unless ++# you somehow have an implicit or explicit dependency on SERIAL_8250. ++# ++ ++config SERIAL_8250 ++ tristate "8250/16550 and compatible serial support" ++ select SERIAL_CORE ++ ---help--- ++ This selects whether you want to include the driver for the standard ++ serial ports. The standard answer is Y. People who might say N ++ here are those that are setting up dedicated Ethernet WWW/FTP ++ servers, or users that have one of the various bus mice instead of a ++ serial mouse and don't intend to use their machine's standard serial ++ port for anything. (Note that the Cyclades and Stallion multi ++ serial port drivers do not need this driver built in for them to ++ work.) ++ ++ To compile this driver as a module, choose M here: the ++ module will be called 8250. ++ [WARNING: Do not compile this driver as a module if you are using ++ non-standard serial ports, since the configuration information will ++ be lost when the driver is unloaded. This limitation may be lifted ++ in the future.] ++ ++ BTW1: If you have a mouseman serial mouse which is not recognized by ++ the X window system, try running gpm first. ++ ++ BTW2: If you intend to use a software modem (also called Winmodem) ++ under Linux, forget it. These modems are crippled and require ++ proprietary drivers which are only available under Windows. ++ ++ Most people will say Y or M here, so that they can use serial mice, ++ modems and similar devices connecting to the standard serial ports. ++ ++config SERIAL_8250_CONSOLE ++ bool "Console on 8250/16550 and compatible serial port" ++ depends on SERIAL_8250=y ++ select SERIAL_CORE_CONSOLE ++ ---help--- ++ If you say Y here, it will be possible to use a serial port as the ++ system console (the system console is the device which receives all ++ kernel messages and warnings and which allows logins in single user ++ mode). This could be useful if some terminal or printer is connected ++ to that serial port. ++ ++ Even if you say Y here, the currently visible virtual console ++ (/dev/tty0) will still be used as the system console by default, but ++ you can alter that using a kernel command line option such as ++ "console=ttyS1". (Try "man bootparam" or see the documentation of ++ your boot loader (grub or lilo or loadlin) about how to pass options ++ to the kernel at boot time.) ++ ++ If you don't have a VGA card installed and you say Y here, the ++ kernel will automatically use the first serial line, /dev/ttyS0, as ++ system console. ++ ++ You can set that using a kernel command line option such as ++ "console=uart8250,io,0x3f8,9600n8" ++ "console=uart8250,mmio,0xff5e0000,115200n8". ++ and it will switch to normal serial console when the corresponding ++ port is ready. ++ "earlycon=uart8250,io,0x3f8,9600n8" ++ "earlycon=uart8250,mmio,0xff5e0000,115200n8". ++ it will not only setup early console. ++ ++ If unsure, say N. ++ ++config FIX_EARLYCON_MEM ++ bool ++ depends on X86 ++ default y ++ ++config SERIAL_8250_GSC ++ tristate ++ depends on SERIAL_8250 && GSC ++ default SERIAL_8250 ++ ++config SERIAL_8250_PCI ++ tristate "8250/16550 PCI device support" if EXPERT ++ depends on SERIAL_8250 && PCI ++ default SERIAL_8250 ++ help ++ This builds standard PCI serial support. You may be able to ++ disable this feature if you only need legacy serial support. ++ Saves about 9K. ++ ++config SERIAL_8250_PNP ++ tristate "8250/16550 PNP device support" if EXPERT ++ depends on SERIAL_8250 && PNP ++ default SERIAL_8250 ++ help ++ This builds standard PNP serial support. You may be able to ++ disable this feature if you only need legacy serial support. ++ ++config SERIAL_8250_HP300 ++ tristate ++ depends on SERIAL_8250 && HP300 ++ default SERIAL_8250 ++ ++config SERIAL_8250_CS ++ tristate "8250/16550 PCMCIA device support" ++ depends on PCMCIA && SERIAL_8250 ++ ---help--- ++ Say Y here to enable support for 16-bit PCMCIA serial devices, ++ including serial port cards, modems, and the modem functions of ++ multi-function Ethernet/modem cards. (PCMCIA- or PC-cards are ++ credit-card size devices often used with laptops.) ++ ++ To compile this driver as a module, choose M here: the ++ module will be called serial_cs. ++ ++ If unsure, say N. ++ ++config SERIAL_8250_NR_UARTS ++ int "Maximum number of 8250/16550 serial ports" ++ depends on SERIAL_8250 ++ default "4" ++ help ++ Set this to the number of serial ports you want the driver ++ to support. This includes any ports discovered via ACPI or ++ PCI enumeration and any ports that may be added at run-time ++ via hot-plug, or any ISA multi-port serial cards. ++ ++config SERIAL_8250_RUNTIME_UARTS ++ int "Number of 8250/16550 serial ports to register at runtime" ++ depends on SERIAL_8250 ++ range 0 SERIAL_8250_NR_UARTS ++ default "4" ++ help ++ Set this to the maximum number of serial ports you want ++ the kernel to register at boot time. This can be overridden ++ with the module parameter "nr_uarts", or boot-time parameter ++ 8250.nr_uarts ++ ++config SERIAL_8250_EXTENDED ++ bool "Extended 8250/16550 serial driver options" ++ depends on SERIAL_8250 ++ help ++ If you wish to use any non-standard features of the standard "dumb" ++ driver, say Y here. This includes HUB6 support, shared serial ++ interrupts, special multiport support, support for more than the ++ four COM 1/2/3/4 boards, etc. ++ ++ Note that the answer to this question won't directly affect the ++ kernel: saying N will just cause the configurator to skip all ++ the questions about serial driver options. If unsure, say N. ++ ++config SERIAL_8250_MANY_PORTS ++ bool "Support more than 4 legacy serial ports" ++ depends on SERIAL_8250_EXTENDED && !IA64 ++ help ++ Say Y here if you have dumb serial boards other than the four ++ standard COM 1/2/3/4 ports. This may happen if you have an AST ++ FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available ++ from <http://www.tldp.org/docs.html#howto>), or other custom ++ serial port hardware which acts similar to standard serial port ++ hardware. If you only use the standard COM 1/2/3/4 ports, you can ++ say N here to save some memory. You can also say Y if you have an ++ "intelligent" multiport card such as Cyclades, Digiboards, etc. ++ ++# ++# Multi-port serial cards ++# ++ ++config SERIAL_8250_FOURPORT ++ tristate "Support Fourport cards" ++ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS ++ help ++ Say Y here if you have an AST FourPort serial board. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called 8250_fourport. ++ ++config SERIAL_8250_ACCENT ++ tristate "Support Accent cards" ++ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS ++ help ++ Say Y here if you have an Accent Async serial board. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called 8250_accent. ++ ++config SERIAL_8250_BOCA ++ tristate "Support Boca cards" ++ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS ++ help ++ Say Y here if you have a Boca serial board. Please read the Boca ++ mini-HOWTO, available from <http://www.tldp.org/docs.html#howto> ++ ++ To compile this driver as a module, choose M here: the module ++ will be called 8250_boca. ++ ++config SERIAL_8250_EXAR_ST16C554 ++ tristate "Support Exar ST16C554/554D Quad UART" ++ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS ++ help ++ The Uplogix Envoy TU301 uses this Exar Quad UART. If you are ++ tinkering with your Envoy TU301, or have a machine with this UART, ++ say Y here. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called 8250_exar_st16c554. ++ ++config SERIAL_8250_HUB6 ++ tristate "Support Hub6 cards" ++ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS ++ help ++ Say Y here if you have a HUB6 serial board. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called 8250_hub6. ++ ++# ++# Misc. options/drivers. ++# ++ ++config SERIAL_8250_SHARE_IRQ ++ bool "Support for sharing serial interrupts" ++ depends on SERIAL_8250_EXTENDED ++ help ++ Some serial boards have hardware support which allows multiple dumb ++ serial ports on the same board to share a single IRQ. To enable ++ support for this in the serial driver, say Y here. ++ ++config SERIAL_8250_DETECT_IRQ ++ bool "Autodetect IRQ on standard ports (unsafe)" ++ depends on SERIAL_8250_EXTENDED ++ help ++ Say Y here if you want the kernel to try to guess which IRQ ++ to use for your serial port. ++ ++ This is considered unsafe; it is far better to configure the IRQ in ++ a boot script using the setserial command. ++ ++ If unsure, say N. ++ ++config SERIAL_8250_RSA ++ bool "Support RSA serial ports" ++ depends on SERIAL_8250_EXTENDED ++ help ++ ::: To be written ::: ++ ++config SERIAL_8250_MCA ++ tristate "Support 8250-type ports on MCA buses" ++ depends on SERIAL_8250 != n && MCA ++ help ++ Say Y here if you have a MCA serial ports. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called 8250_mca. ++ ++config SERIAL_8250_ACORN ++ tristate "Acorn expansion card serial port support" ++ depends on ARCH_ACORN && SERIAL_8250 ++ help ++ If you have an Atomwide Serial card or Serial Port card for an Acorn ++ system, say Y to this option. The driver can handle 1, 2, or 3 port ++ cards. If unsure, say N. ++ ++config SERIAL_8250_RM9K ++ bool "Support for MIPS RM9xxx integrated serial port" ++ depends on SERIAL_8250 != n && SERIAL_RM9000 ++ select SERIAL_8250_SHARE_IRQ ++ help ++ Selecting this option will add support for the integrated serial ++ port hardware found on MIPS RM9122 and similar processors. ++ If unsure, say N. +diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile +new file mode 100644 +index 0000000..c0d0c29 +--- /dev/null ++++ b/drivers/tty/serial/8250/Makefile +@@ -0,0 +1,18 @@ ++# ++# Makefile for the 8250 serial device drivers. ++# ++ ++obj-$(CONFIG_SERIAL_8250) += 8250.o ++obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o ++obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o ++obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o ++obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o ++obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o ++obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o ++obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o ++obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o ++obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o ++obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o ++obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o ++obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o ++obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o +diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/8250/m32r_sio.c +similarity index 100% +rename from drivers/tty/serial/m32r_sio.c +rename to drivers/tty/serial/8250/m32r_sio.c +diff --git a/drivers/tty/serial/m32r_sio.h b/drivers/tty/serial/8250/m32r_sio.h +similarity index 100% +rename from drivers/tty/serial/m32r_sio.h +rename to drivers/tty/serial/8250/m32r_sio.h +diff --git a/drivers/tty/serial/m32r_sio_reg.h b/drivers/tty/serial/8250/m32r_sio_reg.h +similarity index 100% +rename from drivers/tty/serial/m32r_sio_reg.h +rename to drivers/tty/serial/8250/m32r_sio_reg.h +diff --git a/drivers/tty/serial/serial_cs.c b/drivers/tty/serial/8250/serial_cs.c +similarity index 100% +rename from drivers/tty/serial/serial_cs.c +rename to drivers/tty/serial/8250/serial_cs.c +diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig +index 9789293..69349bf 100644 +--- a/drivers/tty/serial/Kconfig ++++ b/drivers/tty/serial/Kconfig +@@ -5,267 +5,7 @@ + menu "Serial drivers" + depends on HAS_IOMEM + +-# +-# The new 8250/16550 serial drivers +-config SERIAL_8250 +- tristate "8250/16550 and compatible serial support" +- select SERIAL_CORE +- ---help--- +- This selects whether you want to include the driver for the standard +- serial ports. The standard answer is Y. People who might say N +- here are those that are setting up dedicated Ethernet WWW/FTP +- servers, or users that have one of the various bus mice instead of a +- serial mouse and don't intend to use their machine's standard serial +- port for anything. (Note that the Cyclades and Stallion multi +- serial port drivers do not need this driver built in for them to +- work.) +- +- To compile this driver as a module, choose M here: the +- module will be called 8250. +- [WARNING: Do not compile this driver as a module if you are using +- non-standard serial ports, since the configuration information will +- be lost when the driver is unloaded. This limitation may be lifted +- in the future.] +- +- BTW1: If you have a mouseman serial mouse which is not recognized by +- the X window system, try running gpm first. +- +- BTW2: If you intend to use a software modem (also called Winmodem) +- under Linux, forget it. These modems are crippled and require +- proprietary drivers which are only available under Windows. +- +- Most people will say Y or M here, so that they can use serial mice, +- modems and similar devices connecting to the standard serial ports. +- +-config SERIAL_8250_CONSOLE +- bool "Console on 8250/16550 and compatible serial port" +- depends on SERIAL_8250=y +- select SERIAL_CORE_CONSOLE +- ---help--- +- If you say Y here, it will be possible to use a serial port as the +- system console (the system console is the device which receives all +- kernel messages and warnings and which allows logins in single user +- mode). This could be useful if some terminal or printer is connected +- to that serial port. +- +- Even if you say Y here, the currently visible virtual console +- (/dev/tty0) will still be used as the system console by default, but +- you can alter that using a kernel command line option such as +- "console=ttyS1". (Try "man bootparam" or see the documentation of +- your boot loader (grub or lilo or loadlin) about how to pass options +- to the kernel at boot time.) +- +- If you don't have a VGA card installed and you say Y here, the +- kernel will automatically use the first serial line, /dev/ttyS0, as +- system console. +- +- You can set that using a kernel command line option such as +- "console=uart8250,io,0x3f8,9600n8" +- "console=uart8250,mmio,0xff5e0000,115200n8". +- and it will switch to normal serial console when the corresponding +- port is ready. +- "earlycon=uart8250,io,0x3f8,9600n8" +- "earlycon=uart8250,mmio,0xff5e0000,115200n8". +- it will not only setup early console. +- +- If unsure, say N. +- +-config FIX_EARLYCON_MEM +- bool +- depends on X86 +- default y +- +-config SERIAL_8250_GSC +- tristate +- depends on SERIAL_8250 && GSC +- default SERIAL_8250 +- +-config SERIAL_8250_PCI +- tristate "8250/16550 PCI device support" if EXPERT +- depends on SERIAL_8250 && PCI +- default SERIAL_8250 +- help +- This builds standard PCI serial support. You may be able to +- disable this feature if you only need legacy serial support. +- Saves about 9K. +- +-config SERIAL_8250_PNP +- tristate "8250/16550 PNP device support" if EXPERT +- depends on SERIAL_8250 && PNP +- default SERIAL_8250 +- help +- This builds standard PNP serial support. You may be able to +- disable this feature if you only need legacy serial support. +- +-config SERIAL_8250_HP300 +- tristate +- depends on SERIAL_8250 && HP300 +- default SERIAL_8250 +- +-config SERIAL_8250_CS +- tristate "8250/16550 PCMCIA device support" +- depends on PCMCIA && SERIAL_8250 +- ---help--- +- Say Y here to enable support for 16-bit PCMCIA serial devices, +- including serial port cards, modems, and the modem functions of +- multi-function Ethernet/modem cards. (PCMCIA- or PC-cards are +- credit-card size devices often used with laptops.) +- +- To compile this driver as a module, choose M here: the +- module will be called serial_cs. +- +- If unsure, say N. +- +-config SERIAL_8250_NR_UARTS +- int "Maximum number of 8250/16550 serial ports" +- depends on SERIAL_8250 +- default "4" +- help +- Set this to the number of serial ports you want the driver +- to support. This includes any ports discovered via ACPI or +- PCI enumeration and any ports that may be added at run-time +- via hot-plug, or any ISA multi-port serial cards. +- +-config SERIAL_8250_RUNTIME_UARTS +- int "Number of 8250/16550 serial ports to register at runtime" +- depends on SERIAL_8250 +- range 0 SERIAL_8250_NR_UARTS +- default "4" +- help +- Set this to the maximum number of serial ports you want +- the kernel to register at boot time. This can be overridden +- with the module parameter "nr_uarts", or boot-time parameter +- 8250.nr_uarts +- +-config SERIAL_8250_EXTENDED +- bool "Extended 8250/16550 serial driver options" +- depends on SERIAL_8250 +- help +- If you wish to use any non-standard features of the standard "dumb" +- driver, say Y here. This includes HUB6 support, shared serial +- interrupts, special multiport support, support for more than the +- four COM 1/2/3/4 boards, etc. +- +- Note that the answer to this question won't directly affect the +- kernel: saying N will just cause the configurator to skip all +- the questions about serial driver options. If unsure, say N. +- +-config SERIAL_8250_MANY_PORTS +- bool "Support more than 4 legacy serial ports" +- depends on SERIAL_8250_EXTENDED && !IA64 +- help +- Say Y here if you have dumb serial boards other than the four +- standard COM 1/2/3/4 ports. This may happen if you have an AST +- FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available +- from <http://www.tldp.org/docs.html#howto>), or other custom +- serial port hardware which acts similar to standard serial port +- hardware. If you only use the standard COM 1/2/3/4 ports, you can +- say N here to save some memory. You can also say Y if you have an +- "intelligent" multiport card such as Cyclades, Digiboards, etc. +- +-# +-# Multi-port serial cards +-# +- +-config SERIAL_8250_FOURPORT +- tristate "Support Fourport cards" +- depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS +- help +- Say Y here if you have an AST FourPort serial board. +- +- To compile this driver as a module, choose M here: the module +- will be called 8250_fourport. +- +-config SERIAL_8250_ACCENT +- tristate "Support Accent cards" +- depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS +- help +- Say Y here if you have an Accent Async serial board. +- +- To compile this driver as a module, choose M here: the module +- will be called 8250_accent. +- +-config SERIAL_8250_BOCA +- tristate "Support Boca cards" +- depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS +- help +- Say Y here if you have a Boca serial board. Please read the Boca +- mini-HOWTO, available from <http://www.tldp.org/docs.html#howto> +- +- To compile this driver as a module, choose M here: the module +- will be called 8250_boca. +- +-config SERIAL_8250_EXAR_ST16C554 +- tristate "Support Exar ST16C554/554D Quad UART" +- depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS +- help +- The Uplogix Envoy TU301 uses this Exar Quad UART. If you are +- tinkering with your Envoy TU301, or have a machine with this UART, +- say Y here. +- +- To compile this driver as a module, choose M here: the module +- will be called 8250_exar_st16c554. +- +-config SERIAL_8250_HUB6 +- tristate "Support Hub6 cards" +- depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS +- help +- Say Y here if you have a HUB6 serial board. +- +- To compile this driver as a module, choose M here: the module +- will be called 8250_hub6. +- +-config SERIAL_8250_SHARE_IRQ +- bool "Support for sharing serial interrupts" +- depends on SERIAL_8250_EXTENDED +- help +- Some serial boards have hardware support which allows multiple dumb +- serial ports on the same board to share a single IRQ. To enable +- support for this in the serial driver, say Y here. +- +-config SERIAL_8250_DETECT_IRQ +- bool "Autodetect IRQ on standard ports (unsafe)" +- depends on SERIAL_8250_EXTENDED +- help +- Say Y here if you want the kernel to try to guess which IRQ +- to use for your serial port. +- +- This is considered unsafe; it is far better to configure the IRQ in +- a boot script using the setserial command. +- +- If unsure, say N. +- +-config SERIAL_8250_RSA +- bool "Support RSA serial ports" +- depends on SERIAL_8250_EXTENDED +- help +- ::: To be written ::: +- +-config SERIAL_8250_MCA +- tristate "Support 8250-type ports on MCA buses" +- depends on SERIAL_8250 != n && MCA +- help +- Say Y here if you have a MCA serial ports. +- +- To compile this driver as a module, choose M here: the module +- will be called 8250_mca. +- +-config SERIAL_8250_ACORN +- tristate "Acorn expansion card serial port support" +- depends on ARCH_ACORN && SERIAL_8250 +- help +- If you have an Atomwide Serial card or Serial Port card for an Acorn +- system, say Y to this option. The driver can handle 1, 2, or 3 port +- cards. If unsure, say N. +- +-config SERIAL_8250_RM9K +- bool "Support for MIPS RM9xxx integrated serial port" +- depends on SERIAL_8250 != n && SERIAL_RM9000 +- select SERIAL_8250_SHARE_IRQ +- help +- Selecting this option will add support for the integrated serial +- port hardware found on MIPS RM9122 and similar processors. +- If unsure, say N. ++source "drivers/tty/serial/8250/Kconfig" + + comment "Non-8250 serial port support" + +diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile +index cb2628f..b74267d 100644 +--- a/drivers/tty/serial/Makefile ++++ b/drivers/tty/serial/Makefile +@@ -14,20 +14,9 @@ obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o + obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o + obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o + +-obj-$(CONFIG_SERIAL_8250) += 8250.o +-obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o +-obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o +-obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o +-obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o +-obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o +-obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o +-obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o +-obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o +-obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o +-obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o +-obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o +-obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o +-obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o ++# Now bring in any enabled 8250/16450/16550 type drivers. ++obj-$(CONFIG_SERIAL_8250) += 8250/ ++ + obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o + obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o + obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0018-serial-Kill-off-NO_IRQ.patch b/patches.kzm9g/0018-serial-Kill-off-NO_IRQ.patch new file mode 100644 index 00000000000000..20a2b724db0863 --- /dev/null +++ b/patches.kzm9g/0018-serial-Kill-off-NO_IRQ.patch @@ -0,0 +1,361 @@ +From f2a0fc4b05410441cf28a4894bb7f1e1983a77bb Mon Sep 17 00:00:00 2001 +From: Alan Cox <alan@linux.intel.com> +Date: Thu, 26 Jan 2012 17:44:09 +0000 +Subject: serial: Kill off NO_IRQ + +We transform the offenders into a test of irq <= 0 which will be ok while +the ARM people get their platform sorted. Once that is done (or in a while +if they don't do it anyway) then we will change them all to !irq checks. + +For arch specific drivers that are already using NO_IRQ = 0 we just test +against zero so we don't need to re-review them later. + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit d4e33fac2408d37f7b52e80ca2a89f9fb482914f) + +Conflicts: + + drivers/tty/serial/m32r_sio.c + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/hvc/hvc_beat.c | 2 +- + drivers/tty/hvc/hvc_rtas.c | 2 +- + drivers/tty/hvc/hvc_udbg.c | 2 +- + drivers/tty/hvc/hvc_xen.c | 2 +- + drivers/tty/hvc/hvcs.c | 4 ++-- + drivers/tty/hvc/hvsi.c | 2 +- + drivers/tty/serial/21285.c | 4 ++-- + drivers/tty/serial/8250/8250.c | 21 +++++++-------------- + drivers/tty/serial/mpc52xx_uart.c | 4 ++-- + drivers/tty/serial/mux.c | 2 +- + drivers/tty/serial/pmac_zilog.c | 2 +- + drivers/tty/serial/sunzilog.c | 10 +++++----- + drivers/tty/serial/ucc_uart.c | 2 +- + drivers/tty/serial/vr41xx_siu.c | 4 ++-- + 14 files changed, 28 insertions(+), 35 deletions(-) + +diff --git a/drivers/tty/hvc/hvc_beat.c b/drivers/tty/hvc/hvc_beat.c +index 5fe4631..1560d23 100644 +--- a/drivers/tty/hvc/hvc_beat.c ++++ b/drivers/tty/hvc/hvc_beat.c +@@ -113,7 +113,7 @@ static int __init hvc_beat_init(void) + if (!firmware_has_feature(FW_FEATURE_BEAT)) + return -ENODEV; + +- hp = hvc_alloc(0, NO_IRQ, &hvc_beat_get_put_ops, 16); ++ hp = hvc_alloc(0, 0, &hvc_beat_get_put_ops, 16); + if (IS_ERR(hp)) + return PTR_ERR(hp); + hvc_beat_dev = hp; +diff --git a/drivers/tty/hvc/hvc_rtas.c b/drivers/tty/hvc/hvc_rtas.c +index 61c4a61..0069bb8 100644 +--- a/drivers/tty/hvc/hvc_rtas.c ++++ b/drivers/tty/hvc/hvc_rtas.c +@@ -94,7 +94,7 @@ static int __init hvc_rtas_init(void) + + /* Allocate an hvc_struct for the console device we instantiated + * earlier. Save off hp so that we can return it on exit */ +- hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops, 16); ++ hp = hvc_alloc(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops, 16); + if (IS_ERR(hp)) + return PTR_ERR(hp); + +diff --git a/drivers/tty/hvc/hvc_udbg.c b/drivers/tty/hvc/hvc_udbg.c +index b0957e6..4c9b13e 100644 +--- a/drivers/tty/hvc/hvc_udbg.c ++++ b/drivers/tty/hvc/hvc_udbg.c +@@ -69,7 +69,7 @@ static int __init hvc_udbg_init(void) + + BUG_ON(hvc_udbg_dev); + +- hp = hvc_alloc(0, NO_IRQ, &hvc_udbg_ops, 16); ++ hp = hvc_alloc(0, 0, &hvc_udbg_ops, 16); + if (IS_ERR(hp)) + return PTR_ERR(hp); + +diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c +index 52fdf60..a1b0a75 100644 +--- a/drivers/tty/hvc/hvc_xen.c ++++ b/drivers/tty/hvc/hvc_xen.c +@@ -176,7 +176,7 @@ static int __init xen_hvc_init(void) + xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); + } + if (xencons_irq < 0) +- xencons_irq = 0; /* NO_IRQ */ ++ xencons_irq = 0; + else + irq_set_noprobe(xencons_irq); + +diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c +index 4c8b665..cb0bf44 100644 +--- a/drivers/tty/hvc/hvcs.c ++++ b/drivers/tty/hvc/hvcs.c +@@ -1203,7 +1203,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) + { + struct hvcs_struct *hvcsd; + unsigned long flags; +- int irq = NO_IRQ; ++ int irq; + + /* + * Is someone trying to close the file associated with this device after +@@ -1264,7 +1264,7 @@ static void hvcs_hangup(struct tty_struct * tty) + struct hvcs_struct *hvcsd = tty->driver_data; + unsigned long flags; + int temp_open_count; +- int irq = NO_IRQ; ++ int irq; + + spin_lock_irqsave(&hvcsd->lock, flags); + /* Preserve this so that we know how many kref refs to put */ +diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c +index 8a8d637..8e1fbd3 100644 +--- a/drivers/tty/hvc/hvsi.c ++++ b/drivers/tty/hvc/hvsi.c +@@ -1298,7 +1298,7 @@ static int __init hvsi_console_init(void) + hp->state = HVSI_CLOSED; + hp->vtermno = *vtermno; + hp->virq = irq_create_mapping(NULL, irq[0]); +- if (hp->virq == NO_IRQ) { ++ if (hp->virq == 0) { + printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", + __func__, irq[0]); + continue; +diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c +index 1b37626..f899996 100644 +--- a/drivers/tty/serial/21285.c ++++ b/drivers/tty/serial/21285.c +@@ -331,7 +331,7 @@ static int serial21285_verify_port(struct uart_port *port, struct serial_struct + int ret = 0; + if (ser->type != PORT_UNKNOWN && ser->type != PORT_21285) + ret = -EINVAL; +- if (ser->irq != NO_IRQ) ++ if (ser->irq <= 0) + ret = -EINVAL; + if (ser->baud_base != port->uartclk / 16) + ret = -EINVAL; +@@ -360,7 +360,7 @@ static struct uart_ops serial21285_ops = { + static struct uart_port serial21285_port = { + .mapbase = 0x42000160, + .iotype = UPIO_MEM, +- .irq = NO_IRQ, ++ .irq = 0, + .fifosize = 16, + .ops = &serial21285_ops, + .flags = UPF_BOOT_AUTOCONF, +diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c +index 047221d..e7c1304 100644 +--- a/drivers/tty/serial/8250/8250.c ++++ b/drivers/tty/serial/8250/8250.c +@@ -86,13 +86,6 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */ + #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) + + +-/* +- * We default to IRQ0 for the "no irq" hack. Some +- * machine types want others as well - they're free +- * to redefine this in their header file. +- */ +-#define is_real_interrupt(irq) ((irq) != 0) +- + #ifdef CONFIG_SERIAL_8250_DETECT_IRQ + #define CONFIG_SERIAL_DETECT_IRQ 1 + #endif +@@ -1748,7 +1741,7 @@ static void serial8250_backup_timeout(unsigned long data) + * Must disable interrupts or else we risk racing with the interrupt + * based handler. + */ +- if (is_real_interrupt(up->port.irq)) { ++ if (up->port.irq) { + ier = serial_in(up, UART_IER); + serial_out(up, UART_IER, 0); + } +@@ -1773,7 +1766,7 @@ static void serial8250_backup_timeout(unsigned long data) + if (!(iir & UART_IIR_NO_INT)) + serial8250_tx_chars(up); + +- if (is_real_interrupt(up->port.irq)) ++ if (up->port.irq) + serial_out(up, UART_IER, ier); + + spin_unlock_irqrestore(&up->port.lock, flags); +@@ -2026,7 +2019,7 @@ static int serial8250_startup(struct uart_port *port) + serial_outp(up, UART_LCR, 0); + } + +- if (is_real_interrupt(up->port.irq)) { ++ if (up->port.irq) { + unsigned char iir1; + /* + * Test for UARTs that do not reassert THRE when the +@@ -2081,7 +2074,7 @@ static int serial8250_startup(struct uart_port *port) + * hardware interrupt, we use a timer-based system. The original + * driver used to do this with IRQ0. + */ +- if (!is_real_interrupt(up->port.irq)) { ++ if (!up->port.irq) { + up->timer.data = (unsigned long)up; + mod_timer(&up->timer, jiffies + uart_poll_timeout(port)); + } else { +@@ -2097,13 +2090,13 @@ static int serial8250_startup(struct uart_port *port) + + spin_lock_irqsave(&up->port.lock, flags); + if (up->port.flags & UPF_FOURPORT) { +- if (!is_real_interrupt(up->port.irq)) ++ if (!up->port.irq) + up->port.mctrl |= TIOCM_OUT1; + } else + /* + * Most PC uarts need OUT2 raised to enable interrupts. + */ +- if (is_real_interrupt(up->port.irq)) ++ if (up->port.irq) + up->port.mctrl |= TIOCM_OUT2; + + serial8250_set_mctrl(&up->port, up->port.mctrl); +@@ -2221,7 +2214,7 @@ static void serial8250_shutdown(struct uart_port *port) + + del_timer_sync(&up->timer); + up->timer.function = serial8250_timeout; +- if (is_real_interrupt(up->port.irq)) ++ if (up->port.irq) + serial_unlink_irq_chain(up); + } + +diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c +index a0bcd8a..0d0d859 100644 +--- a/drivers/tty/serial/mpc52xx_uart.c ++++ b/drivers/tty/serial/mpc52xx_uart.c +@@ -506,7 +506,7 @@ static int __init mpc512x_psc_fifoc_init(void) + + psc_fifoc_irq = irq_of_parse_and_map(np, 0); + of_node_put(np); +- if (psc_fifoc_irq == NO_IRQ) { ++ if (psc_fifoc_irq == 0) { + pr_err("%s: Can't get FIFOC irq\n", __func__); + iounmap(psc_fifoc); + return -ENODEV; +@@ -1353,7 +1353,7 @@ static int __devinit mpc52xx_uart_of_probe(struct platform_device *op) + } + + psc_ops->get_irq(port, op->dev.of_node); +- if (port->irq == NO_IRQ) { ++ if (port->irq == 0) { + dev_dbg(&op->dev, "Could not get irq\n"); + return -EINVAL; + } +diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c +index 9711e06..3605c79 100644 +--- a/drivers/tty/serial/mux.c ++++ b/drivers/tty/serial/mux.c +@@ -497,7 +497,7 @@ static int __init mux_probe(struct parisc_device *dev) + port->membase = ioremap_nocache(port->mapbase, MUX_LINE_OFFSET); + port->iotype = UPIO_MEM; + port->type = PORT_MUX; +- port->irq = NO_IRQ; ++ port->irq = 0; + port->uartclk = 0; + port->fifosize = MUX_FIFO_SIZE; + port->ops = &mux_pops; +diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c +index 5acd24a..22ef6b2 100644 +--- a/drivers/tty/serial/pmac_zilog.c ++++ b/drivers/tty/serial/pmac_zilog.c +@@ -1565,7 +1565,7 @@ no_dma: + * fixed up interrupt info, but we use the device-tree directly + * here due to early probing so we need the fixup too. + */ +- if (uap->port.irq == NO_IRQ && ++ if (uap->port.irq == 0 && + np->parent && np->parent->parent && + of_device_is_compatible(np->parent->parent, "gatwick")) { + /* IRQs on gatwick are offset by 64 */ +diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c +index 8e916e7..5a47d1b 100644 +--- a/drivers/tty/serial/sunzilog.c ++++ b/drivers/tty/serial/sunzilog.c +@@ -1397,7 +1397,7 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up) + #endif + } + +-static int zilog_irq = -1; ++static int zilog_irq; + + static int __devinit zs_probe(struct platform_device *op) + { +@@ -1425,7 +1425,7 @@ static int __devinit zs_probe(struct platform_device *op) + + rp = sunzilog_chip_regs[inst]; + +- if (zilog_irq == -1) ++ if (!zilog_irq) + zilog_irq = op->archdata.irqs[0]; + + up = &sunzilog_port_table[inst * 2]; +@@ -1580,7 +1580,7 @@ static int __init sunzilog_init(void) + if (err) + goto out_unregister_uart; + +- if (zilog_irq != -1) { ++ if (!zilog_irq) { + struct uart_sunzilog_port *up = sunzilog_irq_chain; + err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, + "zs", sunzilog_irq_chain); +@@ -1621,7 +1621,7 @@ static void __exit sunzilog_exit(void) + { + platform_driver_unregister(&zs_driver); + +- if (zilog_irq != -1) { ++ if (!zilog_irq) { + struct uart_sunzilog_port *up = sunzilog_irq_chain; + + /* Disable Interrupts */ +@@ -1637,7 +1637,7 @@ static void __exit sunzilog_exit(void) + } + + free_irq(zilog_irq, sunzilog_irq_chain); +- zilog_irq = -1; ++ zilog_irq = 0; + } + + if (sunzilog_reg.nr) { +diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c +index c327218..d5b8e7e 100644 +--- a/drivers/tty/serial/ucc_uart.c ++++ b/drivers/tty/serial/ucc_uart.c +@@ -1355,7 +1355,7 @@ static int ucc_uart_probe(struct platform_device *ofdev) + } + + qe_port->port.irq = irq_of_parse_and_map(np, 0); +- if (qe_port->port.irq == NO_IRQ) { ++ if (qe_port->port.irq == 0) { + dev_err(&ofdev->dev, "could not map IRQ for UCC%u\n", + qe_port->ucc_num + 1); + ret = -EINVAL; +diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c +index 3beb6ab..15be73d 100644 +--- a/drivers/tty/serial/vr41xx_siu.c ++++ b/drivers/tty/serial/vr41xx_siu.c +@@ -61,7 +61,7 @@ + static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = { + [0 ... SIU_PORTS_MAX-1] = { + .lock = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock), +- .irq = -1, ++ .irq = 0, + }, + }; + +@@ -171,7 +171,7 @@ static inline unsigned int siu_check_type(struct uart_port *port) + { + if (port->line == 0) + return PORT_VR41XX_SIU; +- if (port->line == 1 && port->irq != -1) ++ if (port->line == 1 && port->irq) + return PORT_VR41XX_DSIU; + + return PORT_UNKNOWN; +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0019-tty-fix-a-build-failure-on-sparc.patch b/patches.kzm9g/0019-tty-fix-a-build-failure-on-sparc.patch new file mode 100644 index 00000000000000..35a49625e5f4f7 --- /dev/null +++ b/patches.kzm9g/0019-tty-fix-a-build-failure-on-sparc.patch @@ -0,0 +1,42 @@ +From 571708bcbfb19bb1d4916d2bbc4c5cc23b4a701a Mon Sep 17 00:00:00 2001 +From: Cong Wang <xiyou.wangcong@gmail.com> +Date: Fri, 3 Feb 2012 13:22:10 +0800 +Subject: tty: fix a build failure on sparc + +On sparc, there is a build failure: + +drivers/tty/serial/8250/8250.c:48:21: error: suncore.h: No such file or directory +drivers/tty/serial/8250/8250.c:3275: error: implicit declaration of function 'sunserial_register_minors' +drivers/tty/serial/8250/8250.c:3305: error: implicit declaration of function 'sunserial_unregister_minors' + +this is due to commit 9bef3d4197379a995fa80f81950bbbf8d32e9e8b +(serial: group all the 8250 related code together) moved these files +into 8250/ subdirectory, but forgot to change the reference +to drivers/tty/serial/suncore.h. + +Cc: Paul Gortmaker <paul.gortmaker@windriver.com> +Signed-off-by: WANG Cong <xiyou.wangcong@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit e7c9bba7999a8e55efb96d4279c025ca587c5ecd) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250/8250.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c +index e7c1304..a154ba2 100644 +--- a/drivers/tty/serial/8250/8250.c ++++ b/drivers/tty/serial/8250/8250.c +@@ -45,7 +45,7 @@ + #include "8250.h" + + #ifdef CONFIG_SPARC +-#include "suncore.h" ++#include "../suncore.h" + #endif + + /* +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/002-lsti-backport-arm-mach-shmobile-kzm9g-add-external-usb-host-support.patch b/patches.kzm9g/002-lsti-backport-arm-mach-shmobile-kzm9g-add-external-usb-host-support.patch new file mode 100644 index 00000000000000..023be87566cfa1 --- /dev/null +++ b/patches.kzm9g/002-lsti-backport-arm-mach-shmobile-kzm9g-add-external-usb-host-support.patch @@ -0,0 +1,82 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Tue Jun 26 04:10:44 2012 +From: Tetsuyuki Kobayashi <koba@kmckk.co.jp> +Date: Tue, 26 Jun 2012 20:10:41 +0900 +Subject: [LTSI-dev] [PATCH 2/4] LSTI: backport: ARM: mach-shmobile: kzm9g: add external USB Host support +To: ltsi-dev@lists.linuxfoundation.org +Cc: kuninori.morimoto.gx@gmail.com +Message-ID: <4FE998B1.1050308@kmckk.co.jp> + + +This is backport of +commit dd818180f9303eed270513e8ccd4516bb3a577f5 + +Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp> +--- + arch/arm/mach-shmobile/board-kzm9g.c | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c +index 35af2f8..297cda9 100644 +--- a/arch/arm/mach-shmobile/board-kzm9g.c ++++ b/arch/arm/mach-shmobile/board-kzm9g.c +@@ -31,6 +31,7 @@ + #include <linux/mfd/tmio.h> + #include <linux/platform_device.h> + #include <linux/smsc911x.h> ++#include <linux/usb/r8a66597.h> + #include <linux/videodev2.h> + #include <sound/sh_fsi.h> + #include <sound/simple_card.h> +@@ -92,6 +93,35 @@ static struct platform_device smsc_device = { + .num_resources = ARRAY_SIZE(smsc9221_resources), + }; + ++/* USB external chip */ ++static struct r8a66597_platdata usb_host_data = { ++ .on_chip = 0, ++ .xtal = R8A66597_PLATDATA_XTAL_48MHZ, ++}; ++ ++static struct resource usb_resources[] = { ++ [0] = { ++ .start = 0x10010000, ++ .end = 0x1001ffff - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = intcs_evt2irq(0x220), /* IRQ1 */ ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device usb_host_device = { ++ .name = "r8a66597_hcd", ++ .dev = { ++ .platform_data = &usb_host_data, ++ .dma_mask = NULL, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++ .num_resources = ARRAY_SIZE(usb_resources), ++ .resource = usb_resources, ++}; ++ + /* LCDC */ + static struct fb_videomode kzm_lcdc_mode = { + .name = "WVGA Panel", +@@ -330,6 +360,7 @@ static struct i2c_board_info i2c3_devices[] = { + + static struct platform_device *kzm_devices[] __initdata = { + &smsc_device, ++ &usb_host_device, + &lcdc_device, + &mmc_device, + &sdhi0_device, +-- +1.7.9.5 + + +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.kzm9g/0020-tty-sparc-rename-drivers-tty-serial-suncore.h-includ.patch b/patches.kzm9g/0020-tty-sparc-rename-drivers-tty-serial-suncore.h-includ.patch new file mode 100644 index 00000000000000..073454477bb0df --- /dev/null +++ b/patches.kzm9g/0020-tty-sparc-rename-drivers-tty-serial-suncore.h-includ.patch @@ -0,0 +1,199 @@ +From 7242a5c3b6dae31b7d9fc687ece21d96aa27bead Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Thu, 9 Feb 2012 18:48:19 -0500 +Subject: tty: sparc: rename drivers/tty/serial/suncore.h -> + include/linux/sunserialcore.h + +There are multiple users of this file from different source +paths now, and rather than have ../ paths in include statements, +just move the file to the linux header dir. + +Suggested-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Acked-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 6816383a09b5be8d35f14f4c25dedb64498e4959) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + MAINTAINERS | 2 +- + drivers/tty/serial/8250/8250.c | 7 +++---- + drivers/tty/serial/suncore.c | 2 +- + drivers/tty/serial/suncore.h | 33 --------------------------------- + drivers/tty/serial/sunhv.c | 3 +-- + drivers/tty/serial/sunsab.c | 2 +- + drivers/tty/serial/sunsu.c | 3 +-- + drivers/tty/serial/sunzilog.c | 2 +- + include/linux/sunserialcore.h | 33 +++++++++++++++++++++++++++++++++ + 9 files changed, 42 insertions(+), 45 deletions(-) + rename drivers/tty/serial/suncore.h => include/linux/sunserialcore.h (98%) + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -5958,8 +5958,8 @@ L: sparclinux@vger.kernel.org + T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git + T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git + S: Maintained ++F: include/linux/sunserialcore.h + F: drivers/tty/serial/suncore.c +-F: drivers/tty/serial/suncore.h + F: drivers/tty/serial/sunhv.c + F: drivers/tty/serial/sunsab.c + F: drivers/tty/serial/sunsab.h +--- a/drivers/tty/serial/8250/8250.c ++++ b/drivers/tty/serial/8250/8250.c +@@ -38,16 +38,15 @@ + #include <linux/nmi.h> + #include <linux/mutex.h> + #include <linux/slab.h> ++#ifdef CONFIG_SPARC ++#include <linux/sunserialcore.h> ++#endif + + #include <asm/io.h> + #include <asm/irq.h> + + #include "8250.h" + +-#ifdef CONFIG_SPARC +-#include "../suncore.h" +-#endif +- + /* + * Configuration: + * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option +--- a/drivers/tty/serial/suncore.c ++++ b/drivers/tty/serial/suncore.c +@@ -17,11 +17,11 @@ + #include <linux/errno.h> + #include <linux/string.h> + #include <linux/serial_core.h> ++#include <linux/sunserialcore.h> + #include <linux/init.h> + + #include <asm/prom.h> + +-#include "suncore.h" + + static int sunserial_current_minor = 64; + +--- a/drivers/tty/serial/suncore.h ++++ /dev/null +@@ -1,33 +0,0 @@ +-/* suncore.h +- * +- * Generic SUN serial/kbd/ms layer. Based entirely +- * upon drivers/sbus/char/sunserial.h which is: +- * +- * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) +- * +- * Port to new UART layer is: +- * +- * Copyright (C) 2002 David S. Miller (davem@redhat.com) +- */ +- +-#ifndef _SERIAL_SUN_H +-#define _SERIAL_SUN_H +- +-/* Serial keyboard defines for L1-A processing... */ +-#define SUNKBD_RESET 0xff +-#define SUNKBD_L1 0x01 +-#define SUNKBD_UP 0x80 +-#define SUNKBD_A 0x4d +- +-extern unsigned int suncore_mouse_baud_cflag_next(unsigned int, int *); +-extern int suncore_mouse_baud_detection(unsigned char, int); +- +-extern int sunserial_register_minors(struct uart_driver *, int); +-extern void sunserial_unregister_minors(struct uart_driver *, int); +- +-extern int sunserial_console_match(struct console *, struct device_node *, +- struct uart_driver *, int, bool); +-extern void sunserial_console_termios(struct console *, +- struct device_node *); +- +-#endif /* !(_SERIAL_SUN_H) */ +--- a/drivers/tty/serial/sunhv.c ++++ b/drivers/tty/serial/sunhv.c +@@ -29,8 +29,7 @@ + #endif + + #include <linux/serial_core.h> +- +-#include "suncore.h" ++#include <linux/sunserialcore.h> + + #define CON_BREAK ((long)-1) + #define CON_HUP ((long)-2) +--- a/drivers/tty/serial/sunsab.c ++++ b/drivers/tty/serial/sunsab.c +@@ -43,8 +43,8 @@ + #endif + + #include <linux/serial_core.h> ++#include <linux/sunserialcore.h> + +-#include "suncore.h" + #include "sunsab.h" + + struct uart_sunsab_port { +--- a/drivers/tty/serial/sunsu.c ++++ b/drivers/tty/serial/sunsu.c +@@ -47,8 +47,7 @@ + #endif + + #include <linux/serial_core.h> +- +-#include "suncore.h" ++#include <linux/sunserialcore.h> + + /* We are on a NS PC87303 clocked with 24.0 MHz, which results + * in a UART clock of 1.8462 MHz. +--- a/drivers/tty/serial/sunzilog.c ++++ b/drivers/tty/serial/sunzilog.c +@@ -43,8 +43,8 @@ + #endif + + #include <linux/serial_core.h> ++#include <linux/sunserialcore.h> + +-#include "suncore.h" + #include "sunzilog.h" + + /* On 32-bit sparcs we need to delay after register accesses +--- /dev/null ++++ b/include/linux/sunserialcore.h +@@ -0,0 +1,33 @@ ++/* sunserialcore.h ++ * ++ * Generic SUN serial/kbd/ms layer. Based entirely ++ * upon drivers/sbus/char/sunserial.h which is: ++ * ++ * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) ++ * ++ * Port to new UART layer is: ++ * ++ * Copyright (C) 2002 David S. Miller (davem@redhat.com) ++ */ ++ ++#ifndef _SERIAL_SUN_H ++#define _SERIAL_SUN_H ++ ++/* Serial keyboard defines for L1-A processing... */ ++#define SUNKBD_RESET 0xff ++#define SUNKBD_L1 0x01 ++#define SUNKBD_UP 0x80 ++#define SUNKBD_A 0x4d ++ ++extern unsigned int suncore_mouse_baud_cflag_next(unsigned int, int *); ++extern int suncore_mouse_baud_detection(unsigned char, int); ++ ++extern int sunserial_register_minors(struct uart_driver *, int); ++extern void sunserial_unregister_minors(struct uart_driver *, int); ++ ++extern int sunserial_console_match(struct console *, struct device_node *, ++ struct uart_driver *, int, bool); ++extern void sunserial_console_termios(struct console *, ++ struct device_node *); ++ ++#endif /* !(_SERIAL_SUN_H) */ diff --git a/patches.kzm9g/0021-serial-delete-last-unused-traces-of-pausing-I-O-in-8.patch b/patches.kzm9g/0021-serial-delete-last-unused-traces-of-pausing-I-O-in-8.patch new file mode 100644 index 00000000000000..5356b24616bf68 --- /dev/null +++ b/patches.kzm9g/0021-serial-delete-last-unused-traces-of-pausing-I-O-in-8.patch @@ -0,0 +1,732 @@ +From 6312e447e5cfbc4a17af35d1c1bb0b12df671ad2 Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Thu, 8 Mar 2012 19:12:08 -0500 +Subject: serial: delete last unused traces of pausing I/O in 8250 + +This is the last traces of pausing I/O that we had back some +twenty years ago. Probably was only required for 8MHz ISA +cards running "on the edge" at 12MHz. Anyway it hasn't been +in use for years, so lets just bury it for good. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 0acf519f3f22450ae8f90cdb0f77b046fc731624) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250/8250.c | 308 +++++++++++++++++++--------------------- + 1 file changed, 150 insertions(+), 158 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c +index 9e2e282..fe75134 100644 +--- a/drivers/tty/serial/8250/8250.c ++++ b/drivers/tty/serial/8250/8250.c +@@ -486,26 +486,18 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value) + (up->port.serial_in(&(up)->port, (offset))) + #define serial_out(up, offset, value) \ + (up->port.serial_out(&(up)->port, (offset), (value))) +-/* +- * We used to support using pause I/O for certain machines. We +- * haven't supported this for a while, but just in case it's badly +- * needed for certain old 386 machines, I've left these #define's +- * in.... +- */ +-#define serial_inp(up, offset) serial_in(up, offset) +-#define serial_outp(up, offset, value) serial_out(up, offset, value) + + /* Uart divisor latch read */ + static inline int _serial_dl_read(struct uart_8250_port *up) + { +- return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8; ++ 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_outp(up, UART_DLL, value & 0xff); +- serial_outp(up, UART_DLM, value >> 8 & 0xff); ++ serial_out(up, UART_DLL, value & 0xff); ++ serial_out(up, UART_DLM, value >> 8 & 0xff); + } + + #if defined(CONFIG_MIPS_ALCHEMY) +@@ -575,10 +567,10 @@ static unsigned int serial_icr_read(struct uart_8250_port *up, int offset) + static void serial8250_clear_fifos(struct uart_8250_port *p) + { + if (p->capabilities & UART_CAP_FIFO) { +- serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO); +- serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO | ++ serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO); ++ serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); +- serial_outp(p, UART_FCR, 0); ++ serial_out(p, UART_FCR, 0); + } + } + +@@ -591,15 +583,15 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) + { + if (p->capabilities & UART_CAP_SLEEP) { + if (p->capabilities & UART_CAP_EFR) { +- serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B); +- serial_outp(p, UART_EFR, UART_EFR_ECB); +- serial_outp(p, UART_LCR, 0); ++ serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); ++ serial_out(p, UART_EFR, UART_EFR_ECB); ++ serial_out(p, UART_LCR, 0); + } +- serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); ++ serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); + if (p->capabilities & UART_CAP_EFR) { +- serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B); +- serial_outp(p, UART_EFR, 0); +- serial_outp(p, UART_LCR, 0); ++ serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); ++ serial_out(p, UART_EFR, 0); ++ serial_out(p, UART_LCR, 0); + } + } + } +@@ -614,12 +606,12 @@ static int __enable_rsa(struct uart_8250_port *up) + unsigned char mode; + int result; + +- mode = serial_inp(up, UART_RSA_MSR); ++ mode = serial_in(up, UART_RSA_MSR); + result = mode & UART_RSA_MSR_FIFO; + + if (!result) { +- serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO); +- mode = serial_inp(up, UART_RSA_MSR); ++ serial_out(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO); ++ mode = serial_in(up, UART_RSA_MSR); + result = mode & UART_RSA_MSR_FIFO; + } + +@@ -638,7 +630,7 @@ static void enable_rsa(struct uart_8250_port *up) + spin_unlock_irq(&up->port.lock); + } + if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) +- serial_outp(up, UART_RSA_FRR, 0); ++ serial_out(up, UART_RSA_FRR, 0); + } + } + +@@ -657,12 +649,12 @@ static void disable_rsa(struct uart_8250_port *up) + up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { + spin_lock_irq(&up->port.lock); + +- mode = serial_inp(up, UART_RSA_MSR); ++ mode = serial_in(up, UART_RSA_MSR); + result = !(mode & UART_RSA_MSR_FIFO); + + if (!result) { +- serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); +- mode = serial_inp(up, UART_RSA_MSR); ++ serial_out(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); ++ mode = serial_in(up, UART_RSA_MSR); + result = !(mode & UART_RSA_MSR_FIFO); + } + +@@ -683,28 +675,28 @@ static int size_fifo(struct uart_8250_port *up) + unsigned short old_dl; + int count; + +- old_lcr = serial_inp(up, UART_LCR); +- serial_outp(up, UART_LCR, 0); +- old_fcr = serial_inp(up, UART_FCR); +- old_mcr = serial_inp(up, UART_MCR); +- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | ++ old_lcr = serial_in(up, UART_LCR); ++ serial_out(up, UART_LCR, 0); ++ old_fcr = serial_in(up, UART_FCR); ++ old_mcr = serial_in(up, UART_MCR); ++ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); +- serial_outp(up, UART_MCR, UART_MCR_LOOP); +- serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A); ++ serial_out(up, UART_MCR, UART_MCR_LOOP); ++ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); + old_dl = serial_dl_read(up); + serial_dl_write(up, 0x0001); +- serial_outp(up, UART_LCR, 0x03); ++ serial_out(up, UART_LCR, 0x03); + for (count = 0; count < 256; count++) +- serial_outp(up, UART_TX, count); ++ serial_out(up, UART_TX, count); + mdelay(20);/* FIXME - schedule_timeout */ +- for (count = 0; (serial_inp(up, UART_LSR) & UART_LSR_DR) && ++ for (count = 0; (serial_in(up, UART_LSR) & UART_LSR_DR) && + (count < 256); count++) +- serial_inp(up, UART_RX); +- serial_outp(up, UART_FCR, old_fcr); +- serial_outp(up, UART_MCR, old_mcr); +- serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A); ++ serial_in(up, UART_RX); ++ serial_out(up, UART_FCR, old_fcr); ++ serial_out(up, UART_MCR, old_mcr); ++ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); + serial_dl_write(up, old_dl); +- serial_outp(up, UART_LCR, old_lcr); ++ serial_out(up, UART_LCR, old_lcr); + + return count; + } +@@ -719,20 +711,20 @@ static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) + unsigned char old_dll, old_dlm, old_lcr; + unsigned int id; + +- old_lcr = serial_inp(p, UART_LCR); +- serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_A); ++ old_lcr = serial_in(p, UART_LCR); ++ serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A); + +- old_dll = serial_inp(p, UART_DLL); +- old_dlm = serial_inp(p, UART_DLM); ++ old_dll = serial_in(p, UART_DLL); ++ old_dlm = serial_in(p, UART_DLM); + +- serial_outp(p, UART_DLL, 0); +- serial_outp(p, UART_DLM, 0); ++ serial_out(p, UART_DLL, 0); ++ serial_out(p, UART_DLM, 0); + +- id = serial_inp(p, UART_DLL) | serial_inp(p, UART_DLM) << 8; ++ id = serial_in(p, UART_DLL) | serial_in(p, UART_DLM) << 8; + +- serial_outp(p, UART_DLL, old_dll); +- serial_outp(p, UART_DLM, old_dlm); +- serial_outp(p, UART_LCR, old_lcr); ++ serial_out(p, UART_DLL, old_dll); ++ serial_out(p, UART_DLM, old_dlm); ++ serial_out(p, UART_LCR, old_lcr); + + return id; + } +@@ -842,11 +834,11 @@ static void autoconfig_8250(struct uart_8250_port *up) + up->port.type = PORT_8250; + + scratch = serial_in(up, UART_SCR); +- serial_outp(up, UART_SCR, 0xa5); ++ serial_out(up, UART_SCR, 0xa5); + status1 = serial_in(up, UART_SCR); +- serial_outp(up, UART_SCR, 0x5a); ++ serial_out(up, UART_SCR, 0x5a); + status2 = serial_in(up, UART_SCR); +- serial_outp(up, UART_SCR, scratch); ++ serial_out(up, UART_SCR, scratch); + + if (status1 == 0xa5 && status2 == 0x5a) + up->port.type = PORT_16450; +@@ -877,7 +869,7 @@ static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) + } else { + status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ + status |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ +- serial_outp(up, 0x04, status); ++ serial_out(up, 0x04, status); + } + return 1; + } +@@ -900,9 +892,9 @@ static void autoconfig_16550a(struct uart_8250_port *up) + * Check for presence of the EFR when DLAB is set. + * Only ST16C650V1 UARTs pass this test. + */ +- serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A); ++ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); + if (serial_in(up, UART_EFR) == 0) { +- serial_outp(up, UART_EFR, 0xA8); ++ serial_out(up, UART_EFR, 0xA8); + if (serial_in(up, UART_EFR) != 0) { + DEBUG_AUTOCONF("EFRv1 "); + up->port.type = PORT_16650; +@@ -910,7 +902,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) + } else { + DEBUG_AUTOCONF("Motorola 8xxx DUART "); + } +- serial_outp(up, UART_EFR, 0); ++ serial_out(up, UART_EFR, 0); + return; + } + +@@ -918,7 +910,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) + * Maybe it requires 0xbf to be written to the LCR. + * (other ST16C650V2 UARTs, TI16C752A, etc) + */ +- serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); ++ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) { + DEBUG_AUTOCONF("EFRv2 "); + autoconfig_has_efr(up); +@@ -932,23 +924,23 @@ static void autoconfig_16550a(struct uart_8250_port *up) + * switch back to bank 2, read it from EXCR1 again and check + * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 + */ +- serial_outp(up, UART_LCR, 0); ++ serial_out(up, UART_LCR, 0); + status1 = serial_in(up, UART_MCR); +- serial_outp(up, UART_LCR, 0xE0); ++ serial_out(up, UART_LCR, 0xE0); + status2 = serial_in(up, 0x02); /* EXCR1 */ + + if (!((status2 ^ status1) & UART_MCR_LOOP)) { +- serial_outp(up, UART_LCR, 0); +- serial_outp(up, UART_MCR, status1 ^ UART_MCR_LOOP); +- serial_outp(up, UART_LCR, 0xE0); ++ serial_out(up, UART_LCR, 0); ++ serial_out(up, UART_MCR, status1 ^ UART_MCR_LOOP); ++ serial_out(up, UART_LCR, 0xE0); + status2 = serial_in(up, 0x02); /* EXCR1 */ +- serial_outp(up, UART_LCR, 0); +- serial_outp(up, UART_MCR, status1); ++ serial_out(up, UART_LCR, 0); ++ serial_out(up, UART_MCR, status1); + + if ((status2 ^ status1) & UART_MCR_LOOP) { + unsigned short quot; + +- serial_outp(up, UART_LCR, 0xE0); ++ serial_out(up, UART_LCR, 0xE0); + + quot = serial_dl_read(up); + quot <<= 3; +@@ -956,7 +948,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) + if (ns16550a_goto_highspeed(up)) + serial_dl_write(up, quot); + +- serial_outp(up, UART_LCR, 0); ++ serial_out(up, UART_LCR, 0); + + up->port.uartclk = 921600*16; + up->port.type = PORT_NS16550A; +@@ -971,15 +963,15 @@ static void autoconfig_16550a(struct uart_8250_port *up) + * Try setting it with and without DLAB set. Cheap clones + * set bit 5 without DLAB set. + */ +- serial_outp(up, UART_LCR, 0); +- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); ++ serial_out(up, UART_LCR, 0); ++ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); + status1 = serial_in(up, UART_IIR) >> 5; +- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); +- serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A); +- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); ++ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); ++ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); ++ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); + status2 = serial_in(up, UART_IIR) >> 5; +- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); +- serial_outp(up, UART_LCR, 0); ++ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); ++ serial_out(up, UART_LCR, 0); + + DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2); + +@@ -998,13 +990,13 @@ static void autoconfig_16550a(struct uart_8250_port *up) + * already a 1 and maybe locked there before we even start start. + */ + iersave = serial_in(up, UART_IER); +- serial_outp(up, UART_IER, iersave & ~UART_IER_UUE); ++ serial_out(up, UART_IER, iersave & ~UART_IER_UUE); + if (!(serial_in(up, UART_IER) & UART_IER_UUE)) { + /* + * OK it's in a known zero state, try writing and reading + * without disturbing the current state of the other bits. + */ +- serial_outp(up, UART_IER, iersave | UART_IER_UUE); ++ serial_out(up, UART_IER, iersave | UART_IER_UUE); + if (serial_in(up, UART_IER) & UART_IER_UUE) { + /* + * It's an Xscale. +@@ -1022,7 +1014,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) + */ + DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); + } +- serial_outp(up, UART_IER, iersave); ++ serial_out(up, UART_IER, iersave); + + /* + * Exar uarts have EFR in a weird location +@@ -1084,8 +1076,8 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) + * Note: this is safe as long as MCR bit 4 is clear + * and the device is in "PC" mode. + */ +- scratch = serial_inp(up, UART_IER); +- serial_outp(up, UART_IER, 0); ++ scratch = serial_in(up, UART_IER); ++ serial_out(up, UART_IER, 0); + #ifdef __i386__ + outb(0xff, 0x080); + #endif +@@ -1093,13 +1085,13 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) + * Mask out IER[7:4] bits for test as some UARTs (e.g. TL + * 16C754B) allow only to modify them if an EFR bit is set. + */ +- scratch2 = serial_inp(up, UART_IER) & 0x0f; +- serial_outp(up, UART_IER, 0x0F); ++ scratch2 = serial_in(up, UART_IER) & 0x0f; ++ serial_out(up, UART_IER, 0x0F); + #ifdef __i386__ + outb(0, 0x080); + #endif +- scratch3 = serial_inp(up, UART_IER) & 0x0f; +- serial_outp(up, UART_IER, scratch); ++ scratch3 = serial_in(up, UART_IER) & 0x0f; ++ serial_out(up, UART_IER, scratch); + if (scratch2 != 0 || scratch3 != 0x0F) { + /* + * We failed; there's nothing here +@@ -1123,9 +1115,9 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) + * that conflicts with COM 1-4 --- we hope! + */ + if (!(up->port.flags & UPF_SKIP_TEST)) { +- serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A); +- status1 = serial_inp(up, UART_MSR) & 0xF0; +- serial_outp(up, UART_MCR, save_mcr); ++ serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A); ++ status1 = serial_in(up, UART_MSR) & 0xF0; ++ serial_out(up, UART_MCR, save_mcr); + if (status1 != 0x90) { + DEBUG_AUTOCONF("LOOP test failed (%02x) ", + status1); +@@ -1142,11 +1134,11 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) + * We also initialise the EFR (if any) to zero for later. The + * EFR occupies the same register location as the FCR and IIR. + */ +- serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); +- serial_outp(up, UART_EFR, 0); +- serial_outp(up, UART_LCR, 0); ++ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); ++ serial_out(up, UART_EFR, 0); ++ serial_out(up, UART_LCR, 0); + +- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); ++ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); + scratch = serial_in(up, UART_IIR) >> 6; + + DEBUG_AUTOCONF("iir=%d ", scratch); +@@ -1183,7 +1175,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) + } + #endif + +- serial_outp(up, UART_LCR, save_lcr); ++ serial_out(up, UART_LCR, save_lcr); + + if (up->capabilities != uart_config[up->port.type].flags) { + printk(KERN_WARNING +@@ -1204,15 +1196,15 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) + */ + #ifdef CONFIG_SERIAL_8250_RSA + if (up->port.type == PORT_RSA) +- serial_outp(up, UART_RSA_FRR, 0); ++ serial_out(up, UART_RSA_FRR, 0); + #endif +- serial_outp(up, UART_MCR, save_mcr); ++ serial_out(up, UART_MCR, save_mcr); + serial8250_clear_fifos(up); + serial_in(up, UART_RX); + if (up->capabilities & UART_CAP_UUE) +- serial_outp(up, UART_IER, UART_IER_UUE); ++ serial_out(up, UART_IER, UART_IER_UUE); + else +- serial_outp(up, UART_IER, 0); ++ serial_out(up, UART_IER, 0); + + out: + spin_unlock_irqrestore(&up->port.lock, flags); +@@ -1236,31 +1228,31 @@ static void autoconfig_irq(struct uart_8250_port *up) + + /* forget possible initially masked and pending IRQ */ + probe_irq_off(probe_irq_on()); +- save_mcr = serial_inp(up, UART_MCR); +- save_ier = serial_inp(up, UART_IER); +- serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); ++ save_mcr = serial_in(up, UART_MCR); ++ save_ier = serial_in(up, UART_IER); ++ serial_out(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); + + irqs = probe_irq_on(); +- serial_outp(up, UART_MCR, 0); ++ serial_out(up, UART_MCR, 0); + udelay(10); + if (up->port.flags & UPF_FOURPORT) { +- serial_outp(up, UART_MCR, ++ serial_out(up, UART_MCR, + UART_MCR_DTR | UART_MCR_RTS); + } else { +- serial_outp(up, UART_MCR, ++ serial_out(up, UART_MCR, + UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); + } +- serial_outp(up, UART_IER, 0x0f); /* enable all intrs */ +- (void)serial_inp(up, UART_LSR); +- (void)serial_inp(up, UART_RX); +- (void)serial_inp(up, UART_IIR); +- (void)serial_inp(up, UART_MSR); +- serial_outp(up, UART_TX, 0xFF); ++ serial_out(up, UART_IER, 0x0f); /* enable all intrs */ ++ (void)serial_in(up, UART_LSR); ++ (void)serial_in(up, UART_RX); ++ (void)serial_in(up, UART_IIR); ++ (void)serial_in(up, UART_MSR); ++ serial_out(up, UART_TX, 0xFF); + udelay(20); + irq = probe_irq_off(irqs); + +- serial_outp(up, UART_MCR, save_mcr); +- serial_outp(up, UART_IER, save_ier); ++ serial_out(up, UART_MCR, save_mcr); ++ serial_out(up, UART_IER, save_ier); + + if (up->port.flags & UPF_FOURPORT) + outb_p(save_ICP, ICP); +@@ -1380,7 +1372,7 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) + + do { + if (likely(lsr & UART_LSR_DR)) +- ch = serial_inp(up, UART_RX); ++ ch = serial_in(up, UART_RX); + else + /* + * Intel 82571 has a Serial Over Lan device that will +@@ -1445,7 +1437,7 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) + uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); + + ignore_char: +- lsr = serial_inp(up, UART_LSR); ++ lsr = serial_in(up, UART_LSR); + } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); + spin_unlock(&up->port.lock); + tty_flip_buffer_push(tty); +@@ -1460,7 +1452,7 @@ void serial8250_tx_chars(struct uart_8250_port *up) + int count; + + if (up->port.x_char) { +- serial_outp(up, UART_TX, up->port.x_char); ++ serial_out(up, UART_TX, up->port.x_char); + up->port.icount.tx++; + up->port.x_char = 0; + return; +@@ -1532,7 +1524,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) + + spin_lock_irqsave(&up->port.lock, flags); + +- status = serial_inp(up, UART_LSR); ++ status = serial_in(up, UART_LSR); + + DEBUG_INTR("status = %x...", status); + +@@ -1892,12 +1884,12 @@ static int serial8250_get_poll_char(struct uart_port *port) + { + struct uart_8250_port *up = + container_of(port, struct uart_8250_port, port); +- unsigned char lsr = serial_inp(up, UART_LSR); ++ unsigned char lsr = serial_in(up, UART_LSR); + + if (!(lsr & UART_LSR_DR)) + return NO_POLL_CHAR; + +- return serial_inp(up, UART_RX); ++ return serial_in(up, UART_RX); + } + + +@@ -1957,14 +1949,14 @@ static int serial8250_startup(struct uart_port *port) + if (up->port.type == PORT_16C950) { + /* Wake up and initialize UART */ + up->acr = 0; +- serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); +- serial_outp(up, UART_EFR, UART_EFR_ECB); +- serial_outp(up, UART_IER, 0); +- serial_outp(up, UART_LCR, 0); ++ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); ++ serial_out(up, UART_EFR, UART_EFR_ECB); ++ serial_out(up, UART_IER, 0); ++ serial_out(up, UART_LCR, 0); + serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ +- serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); +- serial_outp(up, UART_EFR, UART_EFR_ECB); +- serial_outp(up, UART_LCR, 0); ++ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); ++ serial_out(up, UART_EFR, UART_EFR_ECB); ++ serial_out(up, UART_LCR, 0); + } + + #ifdef CONFIG_SERIAL_8250_RSA +@@ -1984,10 +1976,10 @@ static int serial8250_startup(struct uart_port *port) + /* + * Clear the interrupt registers. + */ +- (void) serial_inp(up, UART_LSR); +- (void) serial_inp(up, UART_RX); +- (void) serial_inp(up, UART_IIR); +- (void) serial_inp(up, UART_MSR); ++ (void) serial_in(up, UART_LSR); ++ (void) serial_in(up, UART_RX); ++ (void) serial_in(up, UART_IIR); ++ (void) serial_in(up, UART_MSR); + + /* + * At this point, there's no way the LSR could still be 0xff; +@@ -1995,7 +1987,7 @@ static int serial8250_startup(struct uart_port *port) + * here. + */ + if (!(up->port.flags & UPF_BUGGY_UART) && +- (serial_inp(up, UART_LSR) == 0xff)) { ++ (serial_in(up, UART_LSR) == 0xff)) { + printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", + serial_index(&up->port)); + return -ENODEV; +@@ -2007,15 +1999,15 @@ static int serial8250_startup(struct uart_port *port) + if (up->port.type == PORT_16850) { + unsigned char fctr; + +- serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); ++ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + +- fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); +- serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX); +- serial_outp(up, UART_TRG, UART_TRG_96); +- serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_TX); +- serial_outp(up, UART_TRG, UART_TRG_96); ++ fctr = serial_in(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); ++ serial_out(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX); ++ serial_out(up, UART_TRG, UART_TRG_96); ++ serial_out(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_TX); ++ serial_out(up, UART_TRG, UART_TRG_96); + +- serial_outp(up, UART_LCR, 0); ++ serial_out(up, UART_LCR, 0); + } + + if (up->port.irq) { +@@ -2085,7 +2077,7 @@ static int serial8250_startup(struct uart_port *port) + /* + * Now, initialize the UART + */ +- serial_outp(up, UART_LCR, UART_LCR_WLEN8); ++ serial_out(up, UART_LCR, UART_LCR_WLEN8); + + spin_lock_irqsave(&up->port.lock, flags); + if (up->port.flags & UPF_FOURPORT) { +@@ -2118,10 +2110,10 @@ static int serial8250_startup(struct uart_port *port) + * Do a quick test to see if we receive an + * interrupt when we enable the TX irq. + */ +- serial_outp(up, UART_IER, UART_IER_THRI); ++ serial_out(up, UART_IER, UART_IER_THRI); + lsr = serial_in(up, UART_LSR); + iir = serial_in(up, UART_IIR); +- serial_outp(up, UART_IER, 0); ++ serial_out(up, UART_IER, 0); + + if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) { + if (!(up->bugs & UART_BUG_TXEN)) { +@@ -2141,10 +2133,10 @@ dont_test_tx_en: + * saved flags to avoid getting false values from polling + * routines or the previous session. + */ +- serial_inp(up, UART_LSR); +- serial_inp(up, UART_RX); +- serial_inp(up, UART_IIR); +- serial_inp(up, UART_MSR); ++ serial_in(up, UART_LSR); ++ serial_in(up, UART_RX); ++ serial_in(up, UART_IIR); ++ serial_in(up, UART_MSR); + up->lsr_saved_flags = 0; + up->msr_saved_flags = 0; + +@@ -2154,7 +2146,7 @@ dont_test_tx_en: + * anyway, so we don't enable them here. + */ + up->ier = UART_IER_RLSI | UART_IER_RDI; +- serial_outp(up, UART_IER, up->ier); ++ serial_out(up, UART_IER, up->ier); + + if (up->port.flags & UPF_FOURPORT) { + unsigned int icp; +@@ -2179,7 +2171,7 @@ static void serial8250_shutdown(struct uart_port *port) + * Disable interrupts from this port + */ + up->ier = 0; +- serial_outp(up, UART_IER, 0); ++ serial_out(up, UART_IER, 0); + + spin_lock_irqsave(&up->port.lock, flags); + if (up->port.flags & UPF_FOURPORT) { +@@ -2195,7 +2187,7 @@ static void serial8250_shutdown(struct uart_port *port) + /* + * Disable break condition and FIFOs + */ +- serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC); ++ serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); + serial8250_clear_fifos(up); + + #ifdef CONFIG_SERIAL_8250_RSA +@@ -2372,11 +2364,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + if (termios->c_cflag & CRTSCTS) + efr |= UART_EFR_CTS; + +- serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); ++ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + if (up->port.flags & UPF_EXAR_EFR) +- serial_outp(up, UART_XR_EFR, efr); ++ serial_out(up, UART_XR_EFR, efr); + else +- serial_outp(up, UART_EFR, efr); ++ serial_out(up, UART_EFR, efr); + } + + #ifdef CONFIG_ARCH_OMAP +@@ -2392,9 +2384,9 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + + if (up->capabilities & UART_NATSEMI) { + /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */ +- serial_outp(up, UART_LCR, 0xe0); ++ serial_out(up, UART_LCR, 0xe0); + } else { +- serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ ++ serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ + } + + serial_dl_write(up, quot); +@@ -2404,16 +2396,16 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + * is written without DLAB set, this mode will be disabled. + */ + if (up->port.type == PORT_16750) +- serial_outp(up, UART_FCR, fcr); ++ serial_out(up, UART_FCR, fcr); + +- serial_outp(up, UART_LCR, cval); /* reset DLAB */ ++ serial_out(up, UART_LCR, cval); /* reset DLAB */ + up->lcr = cval; /* Save LCR */ + if (up->port.type != PORT_16750) { + if (fcr & UART_FCR_ENABLE_FIFO) { + /* emulated UARTs (Lucent Venus 167x) need two steps */ +- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); ++ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); + } +- serial_outp(up, UART_FCR, fcr); /* set fcr */ ++ serial_out(up, UART_FCR, fcr); /* set fcr */ + } + serial8250_set_mctrl(&up->port, up->port.mctrl); + spin_unlock_irqrestore(&up->port.lock, flags); +@@ -2995,11 +2987,11 @@ void serial8250_resume_port(int line) + + if (up->capabilities & UART_NATSEMI) { + /* Ensure it's still in high speed mode */ +- serial_outp(up, UART_LCR, 0xE0); ++ serial_out(up, UART_LCR, 0xE0); + + ns16550a_goto_highspeed(up); + +- serial_outp(up, UART_LCR, 0); ++ serial_out(up, UART_LCR, 0); + up->port.uartclk = 921600*16; + } + uart_resume_port(&serial8250_reg, &up->port); +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0022-serial-make-8250-s-serial_in-shareable-to-other-driv.patch b/patches.kzm9g/0022-serial-make-8250-s-serial_in-shareable-to-other-driv.patch new file mode 100644 index 00000000000000..5492bd40e93e39 --- /dev/null +++ b/patches.kzm9g/0022-serial-make-8250-s-serial_in-shareable-to-other-driv.patch @@ -0,0 +1,73 @@ +From aa16319bc84ef2b1c48898c340accb81575be000 Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Thu, 8 Mar 2012 19:12:09 -0500 +Subject: serial: make 8250's serial_in shareable to other drivers. + +Currently 8250.c has serial_in and serial_out as shortcuts +to doing the port I/O. They are implemented as macros a +ways down in the file. This isn't by accident, but is +implicitly required, so cpp doesn't mangle other instances +of the common string "serial_in", as it exists as a field +in the port struct itself. + +The above mangling avoidance violates the principle of least +surprise, and it also prevents the shortcuts from being +relocated up to the top of file, or into 8250.h -- either +being a better location than the current one. + +Move them to 8250.h so other 8250-like drivers can also use +the shortcuts, and in the process, make the conflicting +names go away by using static inlines instead of macros. +The object file size remains unchanged with this modification. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 3f0ab32753b49ae7afc5b69e3f23152d92aa1f85) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250/8250.c | 5 ----- + drivers/tty/serial/8250/8250.h | 10 ++++++++++ + 2 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c +index fe75134..06e17d5 100644 +--- a/drivers/tty/serial/8250/8250.c ++++ b/drivers/tty/serial/8250/8250.c +@@ -482,11 +482,6 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value) + } + } + +-#define serial_in(up, offset) \ +- (up->port.serial_in(&(up)->port, (offset))) +-#define serial_out(up, offset, value) \ +- (up->port.serial_out(&(up)->port, (offset), (value))) +- + /* Uart divisor latch read */ + static inline int _serial_dl_read(struct uart_8250_port *up) + { +diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h +index ae027be..2868a1d 100644 +--- a/drivers/tty/serial/8250/8250.h ++++ b/drivers/tty/serial/8250/8250.h +@@ -86,6 +86,16 @@ struct serial8250_config { + #define SERIAL8250_SHARE_IRQS 0 + #endif + ++static inline int serial_in(struct uart_8250_port *up, int offset) ++{ ++ return up->port.serial_in(&up->port, offset); ++} ++ ++static inline void serial_out(struct uart_8250_port *up, int offset, int value) ++{ ++ up->port.serial_out(&up->port, offset, value); ++} ++ + #if defined(__alpha__) && !defined(CONFIG_PCI) + /* + * Digital did something really horribly wrong with the OUT1 and OUT2 +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0023-serial-delete-useless-void-casts-in-8250.c.patch b/patches.kzm9g/0023-serial-delete-useless-void-casts-in-8250.c.patch new file mode 100644 index 00000000000000..ee3eaff5a34de7 --- /dev/null +++ b/patches.kzm9g/0023-serial-delete-useless-void-casts-in-8250.c.patch @@ -0,0 +1,84 @@ +From e5d5cfab51ec956d809d5951e2ec3b7d7fe7819c Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Thu, 8 Mar 2012 19:12:10 -0500 +Subject: serial: delete useless void casts in 8250.c + +These might have worked some magic with an ancient gcc back in +1992, but "objdump --disassemble" on gcc 4.6 on x86-64 shows +identical output before and after this commit. Send the casts +and their hysterical rasins to the bitbucket. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 0d263a264c4b8376ccf33248f6fac873310e5e05) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250/8250.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c +index 06e17d5..5da9f99 100644 +--- a/drivers/tty/serial/8250/8250.c ++++ b/drivers/tty/serial/8250/8250.c +@@ -1218,7 +1218,7 @@ static void autoconfig_irq(struct uart_8250_port *up) + ICP = (up->port.iobase & 0xfe0) | 0x1f; + save_ICP = inb_p(ICP); + outb_p(0x80, ICP); +- (void) inb_p(ICP); ++ inb_p(ICP); + } + + /* forget possible initially masked and pending IRQ */ +@@ -1238,10 +1238,10 @@ static void autoconfig_irq(struct uart_8250_port *up) + UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); + } + serial_out(up, UART_IER, 0x0f); /* enable all intrs */ +- (void)serial_in(up, UART_LSR); +- (void)serial_in(up, UART_RX); +- (void)serial_in(up, UART_IIR); +- (void)serial_in(up, UART_MSR); ++ serial_in(up, UART_LSR); ++ serial_in(up, UART_RX); ++ serial_in(up, UART_IIR); ++ serial_in(up, UART_MSR); + serial_out(up, UART_TX, 0xFF); + udelay(20); + irq = probe_irq_off(irqs); +@@ -1971,10 +1971,10 @@ static int serial8250_startup(struct uart_port *port) + /* + * Clear the interrupt registers. + */ +- (void) serial_in(up, UART_LSR); +- (void) serial_in(up, UART_RX); +- (void) serial_in(up, UART_IIR); +- (void) serial_in(up, UART_MSR); ++ serial_in(up, UART_LSR); ++ serial_in(up, UART_RX); ++ serial_in(up, UART_IIR); ++ serial_in(up, UART_MSR); + + /* + * At this point, there's no way the LSR could still be 0xff; +@@ -2150,7 +2150,7 @@ dont_test_tx_en: + */ + icp = (up->port.iobase & 0xfe0) | 0x01f; + outb_p(0x80, icp); +- (void) inb_p(icp); ++ inb_p(icp); + } + + return 0; +@@ -2196,7 +2196,7 @@ static void serial8250_shutdown(struct uart_port *port) + * Read data port to reset things, and then unlink from + * the IRQ chain. + */ +- (void) serial_in(up, UART_RX); ++ serial_in(up, UART_RX); + + del_timer_sync(&up->timer); + up->timer.function = serial8250_timeout; +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0024-serial-reduce-number-of-indirections-in-8250-code.patch b/patches.kzm9g/0024-serial-reduce-number-of-indirections-in-8250-code.patch new file mode 100644 index 00000000000000..f729a5591f1fc3 --- /dev/null +++ b/patches.kzm9g/0024-serial-reduce-number-of-indirections-in-8250-code.patch @@ -0,0 +1,958 @@ +From 83c841cec4163679900da8fa7845ef51fd8d9486 Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Thu, 8 Mar 2012 19:12:11 -0500 +Subject: serial: reduce number of indirections in 8250 code + +The serial_8250_port struct contains within a serial_port struct +and many times one or the other, or both are in scope within +functions via a passed in arg, or via container_of. + +However there are a lot of cases where we have access directly +to the port pointer, but yet go through the parent 8250_port +structure instead to get it. These should just use the port +struct directly. + +Similarly there are cases where it makes sense (from a code +cleanliness point of view) to declare a local for the port +struct, so we aren't going through the parent 8250_port struct +repeatedly to get to it. + +We get a small reduction in text size, but it appears that +gcc was smart enough to internally be doing most of this +already, so the readability improvement is the larger gain. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit dfe42443ea1d30c98db59b7b1f914bc147d31336) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250/8250.c | 322 +++++++++++++++++++++------------------- + 1 file changed, 167 insertions(+), 155 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c +index 5da9f99..9ffb3cf 100644 +--- a/drivers/tty/serial/8250/8250.c ++++ b/drivers/tty/serial/8250/8250.c +@@ -1040,24 +1040,25 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) + { + unsigned char status1, scratch, scratch2, scratch3; + unsigned char save_lcr, save_mcr; ++ struct uart_port *port = &up->port; + unsigned long flags; + +- if (!up->port.iobase && !up->port.mapbase && !up->port.membase) ++ if (!port->iobase && !port->mapbase && !port->membase) + return; + + DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ", +- serial_index(&up->port), up->port.iobase, up->port.membase); ++ serial_index(port), port->iobase, port->membase); + + /* + * We really do need global IRQs disabled here - we're going to + * be frobbing the chips IRQ enable register to see if it exists. + */ +- spin_lock_irqsave(&up->port.lock, flags); ++ spin_lock_irqsave(&port->lock, flags); + + up->capabilities = 0; + up->bugs = 0; + +- if (!(up->port.flags & UPF_BUGGY_UART)) { ++ if (!(port->flags & UPF_BUGGY_UART)) { + /* + * Do a simple existence test first; if we fail this, + * there's no point trying anything else. +@@ -1109,7 +1110,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) + * manufacturer would be stupid enough to design a board + * that conflicts with COM 1-4 --- we hope! + */ +- if (!(up->port.flags & UPF_SKIP_TEST)) { ++ if (!(port->flags & UPF_SKIP_TEST)) { + serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A); + status1 = serial_in(up, UART_MSR) & 0xF0; + serial_out(up, UART_MCR, save_mcr); +@@ -1143,10 +1144,10 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) + autoconfig_8250(up); + break; + case 1: +- up->port.type = PORT_UNKNOWN; ++ port->type = PORT_UNKNOWN; + break; + case 2: +- up->port.type = PORT_16550; ++ port->type = PORT_16550; + break; + case 3: + autoconfig_16550a(up); +@@ -1157,13 +1158,12 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) + /* + * Only probe for RSA ports if we got the region. + */ +- if (up->port.type == PORT_16550A && probeflags & PROBE_RSA) { ++ if (port->type == PORT_16550A && probeflags & PROBE_RSA) { + int i; + + for (i = 0 ; i < probe_rsa_count; ++i) { +- if (probe_rsa[i] == up->port.iobase && +- __enable_rsa(up)) { +- up->port.type = PORT_RSA; ++ if (probe_rsa[i] == port->iobase && __enable_rsa(up)) { ++ port->type = PORT_RSA; + break; + } + } +@@ -1172,25 +1172,25 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) + + serial_out(up, UART_LCR, save_lcr); + +- if (up->capabilities != uart_config[up->port.type].flags) { ++ if (up->capabilities != uart_config[port->type].flags) { + printk(KERN_WARNING + "ttyS%d: detected caps %08x should be %08x\n", +- serial_index(&up->port), up->capabilities, +- uart_config[up->port.type].flags); ++ serial_index(port), up->capabilities, ++ uart_config[port->type].flags); + } + +- up->port.fifosize = uart_config[up->port.type].fifo_size; +- up->capabilities = uart_config[up->port.type].flags; +- up->tx_loadsz = uart_config[up->port.type].tx_loadsz; ++ port->fifosize = uart_config[up->port.type].fifo_size; ++ up->capabilities = uart_config[port->type].flags; ++ up->tx_loadsz = uart_config[port->type].tx_loadsz; + +- if (up->port.type == PORT_UNKNOWN) ++ if (port->type == PORT_UNKNOWN) + goto out; + + /* + * Reset the UART. + */ + #ifdef CONFIG_SERIAL_8250_RSA +- if (up->port.type == PORT_RSA) ++ if (port->type == PORT_RSA) + serial_out(up, UART_RSA_FRR, 0); + #endif + serial_out(up, UART_MCR, save_mcr); +@@ -1202,20 +1202,21 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) + serial_out(up, UART_IER, 0); + + out: +- spin_unlock_irqrestore(&up->port.lock, flags); +- DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name); ++ spin_unlock_irqrestore(&port->lock, flags); ++ DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name); + } + + static void autoconfig_irq(struct uart_8250_port *up) + { ++ struct uart_port *port = &up->port; + unsigned char save_mcr, save_ier; + unsigned char save_ICP = 0; + unsigned int ICP = 0; + unsigned long irqs; + int irq; + +- if (up->port.flags & UPF_FOURPORT) { +- ICP = (up->port.iobase & 0xfe0) | 0x1f; ++ if (port->flags & UPF_FOURPORT) { ++ ICP = (port->iobase & 0xfe0) | 0x1f; + save_ICP = inb_p(ICP); + outb_p(0x80, ICP); + inb_p(ICP); +@@ -1230,7 +1231,7 @@ static void autoconfig_irq(struct uart_8250_port *up) + irqs = probe_irq_on(); + serial_out(up, UART_MCR, 0); + udelay(10); +- if (up->port.flags & UPF_FOURPORT) { ++ if (port->flags & UPF_FOURPORT) { + serial_out(up, UART_MCR, + UART_MCR_DTR | UART_MCR_RTS); + } else { +@@ -1249,10 +1250,10 @@ static void autoconfig_irq(struct uart_8250_port *up) + serial_out(up, UART_MCR, save_mcr); + serial_out(up, UART_IER, save_ier); + +- if (up->port.flags & UPF_FOURPORT) ++ if (port->flags & UPF_FOURPORT) + outb_p(save_ICP, ICP); + +- up->port.irq = (irq > 0) ? irq : 0; ++ port->irq = (irq > 0) ? irq : 0; + } + + static inline void __stop_tx(struct uart_8250_port *p) +@@ -1273,7 +1274,7 @@ static void serial8250_stop_tx(struct uart_port *port) + /* + * We really want to stop the transmitter from sending. + */ +- if (up->port.type == PORT_16C950) { ++ if (port->type == PORT_16C950) { + up->acr |= UART_ACR_TXDIS; + serial_icr_write(up, UART_ACR, up->acr); + } +@@ -1292,7 +1293,7 @@ static void serial8250_start_tx(struct uart_port *port) + unsigned char lsr; + lsr = serial_in(up, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; +- if ((up->port.type == PORT_RM9000) ? ++ if ((port->type == PORT_RM9000) ? + (lsr & UART_LSR_THRE) : + (lsr & UART_LSR_TEMT)) + serial8250_tx_chars(up); +@@ -1302,7 +1303,7 @@ static void serial8250_start_tx(struct uart_port *port) + /* + * Re-enable the transmitter if we disabled it. + */ +- if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { ++ if (port->type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { + up->acr &= ~UART_ACR_TXDIS; + serial_icr_write(up, UART_ACR, up->acr); + } +@@ -1360,7 +1361,8 @@ static void clear_rx_fifo(struct uart_8250_port *up) + unsigned char + serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) + { +- struct tty_struct *tty = up->port.state->port.tty; ++ struct uart_port *port = &up->port; ++ struct tty_struct *tty = port->state->port.tty; + unsigned char ch; + int max_count = 256; + char flag; +@@ -1379,7 +1381,7 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) + ch = 0; + + flag = TTY_NORMAL; +- up->port.icount.rx++; ++ port->icount.rx++; + + lsr |= up->lsr_saved_flags; + up->lsr_saved_flags = 0; +@@ -1390,12 +1392,12 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) + */ + if (lsr & UART_LSR_BI) { + lsr &= ~(UART_LSR_FE | UART_LSR_PE); +- up->port.icount.brk++; ++ port->icount.brk++; + /* + * If tegra port then clear the rx fifo to + * accept another break/character. + */ +- if (up->port.type == PORT_TEGRA) ++ if (port->type == PORT_TEGRA) + clear_rx_fifo(up); + + /* +@@ -1404,19 +1406,19 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) + * may get masked by ignore_status_mask + * or read_status_mask. + */ +- if (uart_handle_break(&up->port)) ++ if (uart_handle_break(port)) + goto ignore_char; + } else if (lsr & UART_LSR_PE) +- up->port.icount.parity++; ++ port->icount.parity++; + else if (lsr & UART_LSR_FE) +- up->port.icount.frame++; ++ port->icount.frame++; + if (lsr & UART_LSR_OE) +- up->port.icount.overrun++; ++ port->icount.overrun++; + + /* + * Mask off conditions which should be ignored. + */ +- lsr &= up->port.read_status_mask; ++ lsr &= port->read_status_mask; + + if (lsr & UART_LSR_BI) { + DEBUG_INTR("handling break...."); +@@ -1426,34 +1428,35 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) + else if (lsr & UART_LSR_FE) + flag = TTY_FRAME; + } +- if (uart_handle_sysrq_char(&up->port, ch)) ++ if (uart_handle_sysrq_char(port, ch)) + goto ignore_char; + +- uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); ++ uart_insert_char(port, lsr, UART_LSR_OE, ch, flag); + + ignore_char: + lsr = serial_in(up, UART_LSR); + } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); +- spin_unlock(&up->port.lock); ++ spin_unlock(&port->lock); + tty_flip_buffer_push(tty); +- spin_lock(&up->port.lock); ++ spin_lock(&port->lock); + return lsr; + } + EXPORT_SYMBOL_GPL(serial8250_rx_chars); + + void serial8250_tx_chars(struct uart_8250_port *up) + { +- struct circ_buf *xmit = &up->port.state->xmit; ++ struct uart_port *port = &up->port; ++ struct circ_buf *xmit = &port->state->xmit; + int count; + +- if (up->port.x_char) { +- serial_out(up, UART_TX, up->port.x_char); +- up->port.icount.tx++; +- up->port.x_char = 0; ++ if (port->x_char) { ++ serial_out(up, UART_TX, port->x_char); ++ port->icount.tx++; ++ port->x_char = 0; + return; + } +- if (uart_tx_stopped(&up->port)) { +- serial8250_stop_tx(&up->port); ++ if (uart_tx_stopped(port)) { ++ serial8250_stop_tx(port); + return; + } + if (uart_circ_empty(xmit)) { +@@ -1465,13 +1468,13 @@ void serial8250_tx_chars(struct uart_8250_port *up) + do { + serial_out(up, UART_TX, xmit->buf[xmit->tail]); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); +- up->port.icount.tx++; ++ port->icount.tx++; + if (uart_circ_empty(xmit)) + break; + } while (--count > 0); + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) +- uart_write_wakeup(&up->port); ++ uart_write_wakeup(port); + + DEBUG_INTR("THRE..."); + +@@ -1482,22 +1485,23 @@ EXPORT_SYMBOL_GPL(serial8250_tx_chars); + + unsigned int serial8250_modem_status(struct uart_8250_port *up) + { ++ struct uart_port *port = &up->port; + unsigned int status = serial_in(up, UART_MSR); + + status |= up->msr_saved_flags; + up->msr_saved_flags = 0; + if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && +- up->port.state != NULL) { ++ port->state != NULL) { + if (status & UART_MSR_TERI) +- up->port.icount.rng++; ++ port->icount.rng++; + if (status & UART_MSR_DDSR) +- up->port.icount.dsr++; ++ port->icount.dsr++; + if (status & UART_MSR_DDCD) +- uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); ++ uart_handle_dcd_change(port, status & UART_MSR_DCD); + if (status & UART_MSR_DCTS) +- uart_handle_cts_change(&up->port, status & UART_MSR_CTS); ++ uart_handle_cts_change(port, status & UART_MSR_CTS); + +- wake_up_interruptible(&up->port.state->port.delta_msr_wait); ++ wake_up_interruptible(&port->state->port.delta_msr_wait); + } + + return status; +@@ -1517,7 +1521,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) + if (iir & UART_IIR_NO_INT) + return 0; + +- spin_lock_irqsave(&up->port.lock, flags); ++ spin_lock_irqsave(&port->lock, flags); + + status = serial_in(up, UART_LSR); + +@@ -1529,7 +1533,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) + if (status & UART_LSR_THRE) + serial8250_tx_chars(up); + +- spin_unlock_irqrestore(&up->port.lock, flags); ++ spin_unlock_irqrestore(&port->lock, flags); + return 1; + } + EXPORT_SYMBOL_GPL(serial8250_handle_irq); +@@ -1769,10 +1773,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) + unsigned long flags; + unsigned int lsr; + +- spin_lock_irqsave(&up->port.lock, flags); ++ spin_lock_irqsave(&port->lock, flags); + lsr = serial_in(up, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; +- spin_unlock_irqrestore(&up->port.lock, flags); ++ spin_unlock_irqrestore(&port->lock, flags); + + return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; + } +@@ -1826,13 +1830,13 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) + container_of(port, struct uart_8250_port, port); + unsigned long flags; + +- spin_lock_irqsave(&up->port.lock, flags); ++ spin_lock_irqsave(&port->lock, flags); + if (break_state == -1) + up->lcr |= UART_LCR_SBC; + else + up->lcr &= ~UART_LCR_SBC; + serial_out(up, UART_LCR, up->lcr); +- spin_unlock_irqrestore(&up->port.lock, flags); ++ spin_unlock_irqrestore(&port->lock, flags); + } + + /* +@@ -1933,15 +1937,15 @@ static int serial8250_startup(struct uart_port *port) + unsigned char lsr, iir; + int retval; + +- up->port.fifosize = uart_config[up->port.type].fifo_size; ++ port->fifosize = uart_config[up->port.type].fifo_size; + up->tx_loadsz = uart_config[up->port.type].tx_loadsz; + up->capabilities = uart_config[up->port.type].flags; + up->mcr = 0; + +- if (up->port.iotype != up->cur_iotype) ++ if (port->iotype != up->cur_iotype) + set_io_from_upio(port); + +- if (up->port.type == PORT_16C950) { ++ if (port->type == PORT_16C950) { + /* Wake up and initialize UART */ + up->acr = 0; + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); +@@ -1981,17 +1985,17 @@ static int serial8250_startup(struct uart_port *port) + * if it is, then bail out, because there's likely no UART + * here. + */ +- if (!(up->port.flags & UPF_BUGGY_UART) && ++ if (!(port->flags & UPF_BUGGY_UART) && + (serial_in(up, UART_LSR) == 0xff)) { + printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", +- serial_index(&up->port)); ++ serial_index(port)); + return -ENODEV; + } + + /* + * For a XR16C850, we need to set the trigger levels + */ +- if (up->port.type == PORT_16850) { ++ if (port->type == PORT_16850) { + unsigned char fctr; + + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); +@@ -2005,7 +2009,7 @@ static int serial8250_startup(struct uart_port *port) + serial_out(up, UART_LCR, 0); + } + +- if (up->port.irq) { ++ if (port->irq) { + unsigned char iir1; + /* + * Test for UARTs that do not reassert THRE when the +@@ -2015,9 +2019,9 @@ static int serial8250_startup(struct uart_port *port) + * the interrupt is enabled. Delays are necessary to + * allow register changes to become visible. + */ +- spin_lock_irqsave(&up->port.lock, flags); ++ spin_lock_irqsave(&port->lock, flags); + if (up->port.irqflags & IRQF_SHARED) +- disable_irq_nosync(up->port.irq); ++ disable_irq_nosync(port->irq); + + wait_for_xmitr(up, UART_LSR_THRE); + serial_out_sync(up, UART_IER, UART_IER_THRI); +@@ -2029,9 +2033,9 @@ static int serial8250_startup(struct uart_port *port) + iir = serial_in(up, UART_IIR); + serial_out(up, UART_IER, 0); + +- if (up->port.irqflags & IRQF_SHARED) +- enable_irq(up->port.irq); +- spin_unlock_irqrestore(&up->port.lock, flags); ++ if (port->irqflags & IRQF_SHARED) ++ enable_irq(port->irq); ++ spin_unlock_irqrestore(&port->lock, flags); + + /* + * If the interrupt is not reasserted, setup a timer to +@@ -2060,7 +2064,7 @@ static int serial8250_startup(struct uart_port *port) + * hardware interrupt, we use a timer-based system. The original + * driver used to do this with IRQ0. + */ +- if (!up->port.irq) { ++ if (!port->irq) { + up->timer.data = (unsigned long)up; + mod_timer(&up->timer, jiffies + uart_poll_timeout(port)); + } else { +@@ -2074,7 +2078,7 @@ static int serial8250_startup(struct uart_port *port) + */ + serial_out(up, UART_LCR, UART_LCR_WLEN8); + +- spin_lock_irqsave(&up->port.lock, flags); ++ spin_lock_irqsave(&port->lock, flags); + if (up->port.flags & UPF_FOURPORT) { + if (!up->port.irq) + up->port.mctrl |= TIOCM_OUT1; +@@ -2082,10 +2086,10 @@ static int serial8250_startup(struct uart_port *port) + /* + * Most PC uarts need OUT2 raised to enable interrupts. + */ +- if (up->port.irq) ++ if (port->irq) + up->port.mctrl |= TIOCM_OUT2; + +- serial8250_set_mctrl(&up->port, up->port.mctrl); ++ serial8250_set_mctrl(port, port->mctrl); + + /* Serial over Lan (SoL) hack: + Intel 8257x Gigabit ethernet chips have a +@@ -2121,7 +2125,7 @@ static int serial8250_startup(struct uart_port *port) + } + + dont_test_tx_en: +- spin_unlock_irqrestore(&up->port.lock, flags); ++ spin_unlock_irqrestore(&port->lock, flags); + + /* + * Clear the interrupt registers again for luck, and clear the +@@ -2143,12 +2147,12 @@ dont_test_tx_en: + up->ier = UART_IER_RLSI | UART_IER_RDI; + serial_out(up, UART_IER, up->ier); + +- if (up->port.flags & UPF_FOURPORT) { ++ if (port->flags & UPF_FOURPORT) { + unsigned int icp; + /* + * Enable interrupts on the AST Fourport board + */ +- icp = (up->port.iobase & 0xfe0) | 0x01f; ++ icp = (port->iobase & 0xfe0) | 0x01f; + outb_p(0x80, icp); + inb_p(icp); + } +@@ -2168,16 +2172,16 @@ static void serial8250_shutdown(struct uart_port *port) + up->ier = 0; + serial_out(up, UART_IER, 0); + +- spin_lock_irqsave(&up->port.lock, flags); +- if (up->port.flags & UPF_FOURPORT) { ++ spin_lock_irqsave(&port->lock, flags); ++ if (port->flags & UPF_FOURPORT) { + /* reset interrupts on the AST Fourport board */ +- inb((up->port.iobase & 0xfe0) | 0x1f); +- up->port.mctrl |= TIOCM_OUT1; ++ inb((port->iobase & 0xfe0) | 0x1f); ++ port->mctrl |= TIOCM_OUT1; + } else +- up->port.mctrl &= ~TIOCM_OUT2; ++ port->mctrl &= ~TIOCM_OUT2; + +- serial8250_set_mctrl(&up->port, up->port.mctrl); +- spin_unlock_irqrestore(&up->port.lock, flags); ++ serial8250_set_mctrl(port, port->mctrl); ++ spin_unlock_irqrestore(&port->lock, flags); + + /* + * Disable break condition and FIFOs +@@ -2200,7 +2204,7 @@ static void serial8250_shutdown(struct uart_port *port) + + del_timer_sync(&up->timer); + up->timer.function = serial8250_timeout; +- if (up->port.irq) ++ if (port->irq) + serial_unlink_irq_chain(up); + } + +@@ -2275,11 +2279,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0) + quot++; + +- if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) { ++ if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { + if (baud < 2400) + fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; + else +- fcr = uart_config[up->port.type].fcr; ++ fcr = uart_config[port->type].fcr; + } + + /* +@@ -2290,7 +2294,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + * have sufficient FIFO entries for the latency of the remote + * UART to respond. IOW, at least 32 bytes of FIFO. + */ +- if (up->capabilities & UART_CAP_AFE && up->port.fifosize >= 32) { ++ if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) { + up->mcr &= ~UART_MCR_AFE; + if (termios->c_cflag & CRTSCTS) + up->mcr |= UART_MCR_AFE; +@@ -2300,40 +2304,40 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + * Ok, we're now changing the port state. Do it with + * interrupts disabled. + */ +- spin_lock_irqsave(&up->port.lock, flags); ++ spin_lock_irqsave(&port->lock, flags); + + /* + * Update the per-port timeout. + */ + uart_update_timeout(port, termios->c_cflag, baud); + +- up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; ++ port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; + if (termios->c_iflag & INPCK) +- up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; ++ port->read_status_mask |= UART_LSR_FE | UART_LSR_PE; + if (termios->c_iflag & (BRKINT | PARMRK)) +- up->port.read_status_mask |= UART_LSR_BI; ++ port->read_status_mask |= UART_LSR_BI; + + /* + * Characteres to ignore + */ +- up->port.ignore_status_mask = 0; ++ port->ignore_status_mask = 0; + if (termios->c_iflag & IGNPAR) +- up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; ++ port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; + if (termios->c_iflag & IGNBRK) { +- up->port.ignore_status_mask |= UART_LSR_BI; ++ port->ignore_status_mask |= UART_LSR_BI; + /* + * If we're ignoring parity and break indicators, + * ignore overruns too (for real raw support). + */ + if (termios->c_iflag & IGNPAR) +- up->port.ignore_status_mask |= UART_LSR_OE; ++ port->ignore_status_mask |= UART_LSR_OE; + } + + /* + * ignore all characters if CREAD is not set + */ + if ((termios->c_cflag & CREAD) == 0) +- up->port.ignore_status_mask |= UART_LSR_DR; ++ port->ignore_status_mask |= UART_LSR_DR; + + /* + * CTS flow control flag and modem status interrupts +@@ -2360,7 +2364,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + efr |= UART_EFR_CTS; + + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); +- if (up->port.flags & UPF_EXAR_EFR) ++ if (port->flags & UPF_EXAR_EFR) + serial_out(up, UART_XR_EFR, efr); + else + serial_out(up, UART_EFR, efr); +@@ -2390,20 +2394,20 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR + * is written without DLAB set, this mode will be disabled. + */ +- if (up->port.type == PORT_16750) ++ if (port->type == PORT_16750) + serial_out(up, UART_FCR, fcr); + + serial_out(up, UART_LCR, cval); /* reset DLAB */ + up->lcr = cval; /* Save LCR */ +- if (up->port.type != PORT_16750) { ++ if (port->type != PORT_16750) { + if (fcr & UART_FCR_ENABLE_FIFO) { + /* emulated UARTs (Lucent Venus 167x) need two steps */ + serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); + } + serial_out(up, UART_FCR, fcr); /* set fcr */ + } +- serial8250_set_mctrl(&up->port, up->port.mctrl); +- spin_unlock_irqrestore(&up->port.lock, flags); ++ serial8250_set_mctrl(port, port->mctrl); ++ spin_unlock_irqrestore(&port->lock, flags); + /* Don't rewrite B0 */ + if (tty_termios_baud_rate(termios)) + tty_termios_encode_baud_rate(termios, baud, baud); +@@ -2468,26 +2472,26 @@ static unsigned int serial8250_port_size(struct uart_8250_port *pt) + static int serial8250_request_std_resource(struct uart_8250_port *up) + { + unsigned int size = serial8250_port_size(up); ++ struct uart_port *port = &up->port; + int ret = 0; + +- switch (up->port.iotype) { ++ switch (port->iotype) { + case UPIO_AU: + case UPIO_TSI: + case UPIO_MEM32: + case UPIO_MEM: +- if (!up->port.mapbase) ++ if (!port->mapbase) + break; + +- if (!request_mem_region(up->port.mapbase, size, "serial")) { ++ if (!request_mem_region(port->mapbase, size, "serial")) { + ret = -EBUSY; + break; + } + +- if (up->port.flags & UPF_IOREMAP) { +- up->port.membase = ioremap_nocache(up->port.mapbase, +- size); +- if (!up->port.membase) { +- release_mem_region(up->port.mapbase, size); ++ if (port->flags & UPF_IOREMAP) { ++ port->membase = ioremap_nocache(port->mapbase, size); ++ if (!port->membase) { ++ release_mem_region(port->mapbase, size); + ret = -ENOMEM; + } + } +@@ -2495,7 +2499,7 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) + + case UPIO_HUB6: + case UPIO_PORT: +- if (!request_region(up->port.iobase, size, "serial")) ++ if (!request_region(port->iobase, size, "serial")) + ret = -EBUSY; + break; + } +@@ -2505,26 +2509,27 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) + static void serial8250_release_std_resource(struct uart_8250_port *up) + { + unsigned int size = serial8250_port_size(up); ++ struct uart_port *port = &up->port; + +- switch (up->port.iotype) { ++ switch (port->iotype) { + case UPIO_AU: + case UPIO_TSI: + case UPIO_MEM32: + case UPIO_MEM: +- if (!up->port.mapbase) ++ if (!port->mapbase) + break; + +- if (up->port.flags & UPF_IOREMAP) { +- iounmap(up->port.membase); +- up->port.membase = NULL; ++ if (port->flags & UPF_IOREMAP) { ++ iounmap(port->membase); ++ port->membase = NULL; + } + +- release_mem_region(up->port.mapbase, size); ++ release_mem_region(port->mapbase, size); + break; + + case UPIO_HUB6: + case UPIO_PORT: +- release_region(up->port.iobase, size); ++ release_region(port->iobase, size); + break; + } + } +@@ -2533,12 +2538,13 @@ static int serial8250_request_rsa_resource(struct uart_8250_port *up) + { + unsigned long start = UART_RSA_BASE << up->port.regshift; + unsigned int size = 8 << up->port.regshift; ++ struct uart_port *port = &up->port; + int ret = -EINVAL; + +- switch (up->port.iotype) { ++ switch (port->iotype) { + case UPIO_HUB6: + case UPIO_PORT: +- start += up->port.iobase; ++ start += port->iobase; + if (request_region(start, size, "serial-rsa")) + ret = 0; + else +@@ -2553,11 +2559,12 @@ static void serial8250_release_rsa_resource(struct uart_8250_port *up) + { + unsigned long offset = UART_RSA_BASE << up->port.regshift; + unsigned int size = 8 << up->port.regshift; ++ struct uart_port *port = &up->port; + +- switch (up->port.iotype) { ++ switch (port->iotype) { + case UPIO_HUB6: + case UPIO_PORT: +- release_region(up->port.iobase + offset, size); ++ release_region(port->iobase + offset, size); + break; + } + } +@@ -2568,7 +2575,7 @@ static void serial8250_release_port(struct uart_port *port) + container_of(port, struct uart_8250_port, port); + + serial8250_release_std_resource(up); +- if (up->port.type == PORT_RSA) ++ if (port->type == PORT_RSA) + serial8250_release_rsa_resource(up); + } + +@@ -2579,7 +2586,7 @@ static int serial8250_request_port(struct uart_port *port) + int ret = 0; + + ret = serial8250_request_std_resource(up); +- if (ret == 0 && up->port.type == PORT_RSA) { ++ if (ret == 0 && port->type == PORT_RSA) { + ret = serial8250_request_rsa_resource(up); + if (ret < 0) + serial8250_release_std_resource(up); +@@ -2607,22 +2614,22 @@ static void serial8250_config_port(struct uart_port *port, int flags) + if (ret < 0) + probeflags &= ~PROBE_RSA; + +- if (up->port.iotype != up->cur_iotype) ++ if (port->iotype != up->cur_iotype) + set_io_from_upio(port); + + if (flags & UART_CONFIG_TYPE) + autoconfig(up, probeflags); + + /* if access method is AU, it is a 16550 with a quirk */ +- if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU) ++ if (port->type == PORT_16550A && port->iotype == UPIO_AU) + up->bugs |= UART_BUG_NOMSR; + +- if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) ++ if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) + autoconfig_irq(up); + +- if (up->port.type != PORT_RSA && probeflags & PROBE_RSA) ++ if (port->type != PORT_RSA && probeflags & PROBE_RSA) + serial8250_release_rsa_resource(up); +- if (up->port.type == PORT_UNKNOWN) ++ if (port->type == PORT_UNKNOWN) + serial8250_release_std_resource(up); + } + +@@ -2696,9 +2703,10 @@ static void __init serial8250_isa_init_ports(void) + + for (i = 0; i < nr_uarts; i++) { + struct uart_8250_port *up = &serial8250_ports[i]; ++ struct uart_port *port = &up->port; + +- up->port.line = i; +- spin_lock_init(&up->port.lock); ++ port->line = i; ++ spin_lock_init(&port->lock); + + init_timer(&up->timer); + up->timer.function = serial8250_timeout; +@@ -2709,7 +2717,7 @@ static void __init serial8250_isa_init_ports(void) + up->mcr_mask = ~ALPHA_KLUDGE_MCR; + up->mcr_force = ALPHA_KLUDGE_MCR; + +- up->port.ops = &serial8250_pops; ++ port->ops = &serial8250_pops; + } + + if (share_irqs) +@@ -2718,17 +2726,19 @@ static void __init serial8250_isa_init_ports(void) + for (i = 0, up = serial8250_ports; + i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; + i++, up++) { +- up->port.iobase = old_serial_port[i].port; +- up->port.irq = irq_canonicalize(old_serial_port[i].irq); +- up->port.irqflags = old_serial_port[i].irqflags; +- up->port.uartclk = old_serial_port[i].baud_base * 16; +- up->port.flags = old_serial_port[i].flags; +- up->port.hub6 = old_serial_port[i].hub6; +- up->port.membase = old_serial_port[i].iomem_base; +- up->port.iotype = old_serial_port[i].io_type; +- up->port.regshift = old_serial_port[i].iomem_reg_shift; +- set_io_from_upio(&up->port); +- up->port.irqflags |= irqflag; ++ struct uart_port *port = &up->port; ++ ++ port->iobase = old_serial_port[i].port; ++ port->irq = irq_canonicalize(old_serial_port[i].irq); ++ port->irqflags = old_serial_port[i].irqflags; ++ port->uartclk = old_serial_port[i].baud_base * 16; ++ port->flags = old_serial_port[i].flags; ++ port->hub6 = old_serial_port[i].hub6; ++ port->membase = old_serial_port[i].iomem_base; ++ port->iotype = old_serial_port[i].io_type; ++ port->regshift = old_serial_port[i].iomem_reg_shift; ++ set_io_from_upio(port); ++ port->irqflags |= irqflag; + if (serial8250_isa_config != NULL) + serial8250_isa_config(i, &up->port, &up->capabilities); + +@@ -2789,6 +2799,7 @@ static void + serial8250_console_write(struct console *co, const char *s, unsigned int count) + { + struct uart_8250_port *up = &serial8250_ports[co->index]; ++ struct uart_port *port = &up->port; + unsigned long flags; + unsigned int ier; + int locked = 1; +@@ -2796,13 +2807,13 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) + touch_nmi_watchdog(); + + local_irq_save(flags); +- if (up->port.sysrq) { ++ if (port->sysrq) { + /* serial8250_handle_irq() already took the lock */ + locked = 0; + } else if (oops_in_progress) { +- locked = spin_trylock(&up->port.lock); ++ locked = spin_trylock(&port->lock); + } else +- spin_lock(&up->port.lock); ++ spin_lock(&port->lock); + + /* + * First save the IER then disable the interrupts +@@ -2814,7 +2825,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) + else + serial_out(up, UART_IER, 0); + +- uart_console_write(&up->port, s, count, serial8250_console_putchar); ++ uart_console_write(port, s, count, serial8250_console_putchar); + + /* + * Finally, wait for transmitter to become empty +@@ -2834,7 +2845,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) + serial8250_modem_status(up); + + if (locked) +- spin_unlock(&up->port.lock); ++ spin_unlock(&port->lock); + local_irq_restore(flags); + } + +@@ -2979,6 +2990,7 @@ void serial8250_suspend_port(int line) + void serial8250_resume_port(int line) + { + struct uart_8250_port *up = &serial8250_ports[line]; ++ struct uart_port *port = &up->port; + + if (up->capabilities & UART_NATSEMI) { + /* Ensure it's still in high speed mode */ +@@ -2987,9 +2999,9 @@ void serial8250_resume_port(int line) + ns16550a_goto_highspeed(up); + + serial_out(up, UART_LCR, 0); +- up->port.uartclk = 921600*16; ++ port->uartclk = 921600*16; + } +- uart_resume_port(&serial8250_reg, &up->port); ++ uart_resume_port(&serial8250_reg, port); + } + + /* +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0025-serial-use-serial_port_in-out-vs-serial_in-out-in-82.patch b/patches.kzm9g/0025-serial-use-serial_port_in-out-vs-serial_in-out-in-82.patch new file mode 100644 index 00000000000000..249a4282220bec --- /dev/null +++ b/patches.kzm9g/0025-serial-use-serial_port_in-out-vs-serial_in-out-in-82.patch @@ -0,0 +1,455 @@ +From 291546c8ba381a8579bdcfc2a1dee3971c3ac9b9 Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Thu, 8 Mar 2012 19:12:13 -0500 +Subject: serial: use serial_port_in/out vs serial_in/out in 8250 + +The serial_in and serial_out helpers are expecting to operate +on an 8250_port struct. These in turn go after the contained +normal port struct which actually has the actual in/out accessors. + +But what is happening in some cases, is that a function is passed +in a port struct, and it runs container_of to get the 8250_port +struct, and then it uses serial_in/out helpers on that. But when +you do, it goes full circle, since it jumps back inside the 8250_port +to find the contained port struct (which we already knew!). + +So, if we are operating in a scope where we know the struct port, +then use the serial_port_in/out helpers and avoid the bouncing +around. If we don't have the struct port handy, and it isn't +worth making a local for it, then just leave things as-is which +uses the serial_in/out helpers that will resolve the 8250_port +onto the struct port. + +Mostly, gcc figures this out on its own -- so this doesn't bring to +the table any revolutionary runtime delta. However, it is somewhat +misleading to always hammer away on 8250 structs, when the actual +underlying property isn't at all 8250 specific -- and this change +makes that clear. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 4fd996a14660f56a6fd92ce7c8fb167d262c994f) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250/8250.c | 160 ++++++++++++++++++++-------------------- + 1 file changed, 80 insertions(+), 80 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c +index 9ffb3cf..cb45a29 100644 +--- a/drivers/tty/serial/8250/8250.c ++++ b/drivers/tty/serial/8250/8250.c +@@ -1287,7 +1287,7 @@ static void serial8250_start_tx(struct uart_port *port) + + if (!(up->ier & UART_IER_THRI)) { + up->ier |= UART_IER_THRI; +- serial_out(up, UART_IER, up->ier); ++ serial_port_out(port, UART_IER, up->ier); + + if (up->bugs & UART_BUG_TXEN) { + unsigned char lsr; +@@ -1316,7 +1316,7 @@ static void serial8250_stop_rx(struct uart_port *port) + + up->ier &= ~UART_IER_RLSI; + up->port.read_status_mask &= ~UART_LSR_DR; +- serial_out(up, UART_IER, up->ier); ++ serial_port_out(port, UART_IER, up->ier); + } + + static void serial8250_enable_ms(struct uart_port *port) +@@ -1329,7 +1329,7 @@ static void serial8250_enable_ms(struct uart_port *port) + return; + + up->ier |= UART_IER_MSI; +- serial_out(up, UART_IER, up->ier); ++ serial_port_out(port, UART_IER, up->ier); + } + + /* +@@ -1523,7 +1523,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) + + spin_lock_irqsave(&port->lock, flags); + +- status = serial_in(up, UART_LSR); ++ status = serial_port_in(port, UART_LSR); + + DEBUG_INTR("status = %x...", status); + +@@ -1540,9 +1540,7 @@ EXPORT_SYMBOL_GPL(serial8250_handle_irq); + + static int serial8250_default_handle_irq(struct uart_port *port) + { +- struct uart_8250_port *up = +- container_of(port, struct uart_8250_port, port); +- unsigned int iir = serial_in(up, UART_IIR); ++ unsigned int iir = serial_port_in(port, UART_IIR); + + return serial8250_handle_irq(port, iir); + } +@@ -1774,7 +1772,7 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) + unsigned int lsr; + + spin_lock_irqsave(&port->lock, flags); +- lsr = serial_in(up, UART_LSR); ++ lsr = serial_port_in(port, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + spin_unlock_irqrestore(&port->lock, flags); + +@@ -1821,7 +1819,7 @@ static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) + + mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr; + +- serial_out(up, UART_MCR, mcr); ++ serial_port_out(port, UART_MCR, mcr); + } + + static void serial8250_break_ctl(struct uart_port *port, int break_state) +@@ -1835,7 +1833,7 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) + up->lcr |= UART_LCR_SBC; + else + up->lcr &= ~UART_LCR_SBC; +- serial_out(up, UART_LCR, up->lcr); ++ serial_port_out(port, UART_LCR, up->lcr); + spin_unlock_irqrestore(&port->lock, flags); + } + +@@ -1881,14 +1879,12 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits) + + static int serial8250_get_poll_char(struct uart_port *port) + { +- struct uart_8250_port *up = +- container_of(port, struct uart_8250_port, port); +- unsigned char lsr = serial_in(up, UART_LSR); ++ unsigned char lsr = serial_port_in(port, UART_LSR); + + if (!(lsr & UART_LSR_DR)) + return NO_POLL_CHAR; + +- return serial_in(up, UART_RX); ++ return serial_port_in(port, UART_RX); + } + + +@@ -1902,21 +1898,21 @@ static void serial8250_put_poll_char(struct uart_port *port, + /* + * First save the IER then disable the interrupts + */ +- ier = serial_in(up, UART_IER); ++ ier = serial_port_in(port, UART_IER); + if (up->capabilities & UART_CAP_UUE) +- serial_out(up, UART_IER, UART_IER_UUE); ++ serial_port_out(port, UART_IER, UART_IER_UUE); + else +- serial_out(up, UART_IER, 0); ++ serial_port_out(port, UART_IER, 0); + + wait_for_xmitr(up, BOTH_EMPTY); + /* + * Send the character out. + * If a LF, also do CR... + */ +- serial_out(up, UART_TX, c); ++ serial_port_out(port, UART_TX, c); + if (c == 10) { + wait_for_xmitr(up, BOTH_EMPTY); +- serial_out(up, UART_TX, 13); ++ serial_port_out(port, UART_TX, 13); + } + + /* +@@ -1924,7 +1920,7 @@ static void serial8250_put_poll_char(struct uart_port *port, + * and restore the IER + */ + wait_for_xmitr(up, BOTH_EMPTY); +- serial_out(up, UART_IER, ier); ++ serial_port_out(port, UART_IER, ier); + } + + #endif /* CONFIG_CONSOLE_POLL */ +@@ -1948,14 +1944,14 @@ static int serial8250_startup(struct uart_port *port) + if (port->type == PORT_16C950) { + /* Wake up and initialize UART */ + up->acr = 0; +- serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); +- serial_out(up, UART_EFR, UART_EFR_ECB); +- serial_out(up, UART_IER, 0); +- serial_out(up, UART_LCR, 0); ++ serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); ++ serial_port_out(port, UART_EFR, UART_EFR_ECB); ++ serial_port_out(port, UART_IER, 0); ++ serial_port_out(port, UART_LCR, 0); + serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ +- serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); +- serial_out(up, UART_EFR, UART_EFR_ECB); +- serial_out(up, UART_LCR, 0); ++ serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); ++ serial_port_out(port, UART_EFR, UART_EFR_ECB); ++ serial_port_out(port, UART_LCR, 0); + } + + #ifdef CONFIG_SERIAL_8250_RSA +@@ -1975,10 +1971,10 @@ static int serial8250_startup(struct uart_port *port) + /* + * Clear the interrupt registers. + */ +- serial_in(up, UART_LSR); +- serial_in(up, UART_RX); +- serial_in(up, UART_IIR); +- serial_in(up, UART_MSR); ++ serial_port_in(port, UART_LSR); ++ serial_port_in(port, UART_RX); ++ serial_port_in(port, UART_IIR); ++ serial_port_in(port, UART_MSR); + + /* + * At this point, there's no way the LSR could still be 0xff; +@@ -1986,7 +1982,7 @@ static int serial8250_startup(struct uart_port *port) + * here. + */ + if (!(port->flags & UPF_BUGGY_UART) && +- (serial_in(up, UART_LSR) == 0xff)) { ++ (serial_port_in(port, UART_LSR) == 0xff)) { + printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", + serial_index(port)); + return -ENODEV; +@@ -2001,12 +1997,14 @@ static int serial8250_startup(struct uart_port *port) + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + + fctr = serial_in(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); +- serial_out(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX); +- serial_out(up, UART_TRG, UART_TRG_96); +- serial_out(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_TX); +- serial_out(up, UART_TRG, UART_TRG_96); ++ serial_port_out(port, UART_FCTR, ++ fctr | UART_FCTR_TRGD | UART_FCTR_RX); ++ serial_port_out(port, UART_TRG, UART_TRG_96); ++ serial_port_out(port, UART_FCTR, ++ fctr | UART_FCTR_TRGD | UART_FCTR_TX); ++ serial_port_out(port, UART_TRG, UART_TRG_96); + +- serial_out(up, UART_LCR, 0); ++ serial_port_out(port, UART_LCR, 0); + } + + if (port->irq) { +@@ -2026,12 +2024,12 @@ static int serial8250_startup(struct uart_port *port) + wait_for_xmitr(up, UART_LSR_THRE); + serial_out_sync(up, UART_IER, UART_IER_THRI); + udelay(1); /* allow THRE to set */ +- iir1 = serial_in(up, UART_IIR); +- serial_out(up, UART_IER, 0); ++ iir1 = serial_port_in(port, UART_IIR); ++ serial_port_out(port, UART_IER, 0); + serial_out_sync(up, UART_IER, UART_IER_THRI); + udelay(1); /* allow a working UART time to re-assert THRE */ +- iir = serial_in(up, UART_IIR); +- serial_out(up, UART_IER, 0); ++ iir = serial_port_in(port, UART_IIR); ++ serial_port_out(port, UART_IER, 0); + + if (port->irqflags & IRQF_SHARED) + enable_irq(port->irq); +@@ -2076,7 +2074,7 @@ static int serial8250_startup(struct uart_port *port) + /* + * Now, initialize the UART + */ +- serial_out(up, UART_LCR, UART_LCR_WLEN8); ++ serial_port_out(port, UART_LCR, UART_LCR_WLEN8); + + spin_lock_irqsave(&port->lock, flags); + if (up->port.flags & UPF_FOURPORT) { +@@ -2109,10 +2107,10 @@ static int serial8250_startup(struct uart_port *port) + * Do a quick test to see if we receive an + * interrupt when we enable the TX irq. + */ +- serial_out(up, UART_IER, UART_IER_THRI); +- lsr = serial_in(up, UART_LSR); +- iir = serial_in(up, UART_IIR); +- serial_out(up, UART_IER, 0); ++ serial_port_out(port, UART_IER, UART_IER_THRI); ++ lsr = serial_port_in(port, UART_LSR); ++ iir = serial_port_in(port, UART_IIR); ++ serial_port_out(port, UART_IER, 0); + + if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) { + if (!(up->bugs & UART_BUG_TXEN)) { +@@ -2132,10 +2130,10 @@ dont_test_tx_en: + * saved flags to avoid getting false values from polling + * routines or the previous session. + */ +- serial_in(up, UART_LSR); +- serial_in(up, UART_RX); +- serial_in(up, UART_IIR); +- serial_in(up, UART_MSR); ++ serial_port_in(port, UART_LSR); ++ serial_port_in(port, UART_RX); ++ serial_port_in(port, UART_IIR); ++ serial_port_in(port, UART_MSR); + up->lsr_saved_flags = 0; + up->msr_saved_flags = 0; + +@@ -2145,7 +2143,7 @@ dont_test_tx_en: + * anyway, so we don't enable them here. + */ + up->ier = UART_IER_RLSI | UART_IER_RDI; +- serial_out(up, UART_IER, up->ier); ++ serial_port_out(port, UART_IER, up->ier); + + if (port->flags & UPF_FOURPORT) { + unsigned int icp; +@@ -2170,7 +2168,7 @@ static void serial8250_shutdown(struct uart_port *port) + * Disable interrupts from this port + */ + up->ier = 0; +- serial_out(up, UART_IER, 0); ++ serial_port_out(port, UART_IER, 0); + + spin_lock_irqsave(&port->lock, flags); + if (port->flags & UPF_FOURPORT) { +@@ -2186,7 +2184,8 @@ static void serial8250_shutdown(struct uart_port *port) + /* + * Disable break condition and FIFOs + */ +- serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); ++ serial_port_out(port, UART_LCR, ++ serial_port_in(port, UART_LCR) & ~UART_LCR_SBC); + serial8250_clear_fifos(up); + + #ifdef CONFIG_SERIAL_8250_RSA +@@ -2200,7 +2199,7 @@ static void serial8250_shutdown(struct uart_port *port) + * Read data port to reset things, and then unlink from + * the IRQ chain. + */ +- serial_in(up, UART_RX); ++ serial_port_in(port, UART_RX); + + del_timer_sync(&up->timer); + up->timer.function = serial8250_timeout; +@@ -2351,7 +2350,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + if (up->capabilities & UART_CAP_RTOIE) + up->ier |= UART_IER_RTOIE; + +- serial_out(up, UART_IER, up->ier); ++ serial_port_out(port, UART_IER, up->ier); + + if (up->capabilities & UART_CAP_EFR) { + unsigned char efr = 0; +@@ -2363,11 +2362,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + if (termios->c_cflag & CRTSCTS) + efr |= UART_EFR_CTS; + +- serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); ++ serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); + if (port->flags & UPF_EXAR_EFR) +- serial_out(up, UART_XR_EFR, efr); ++ serial_port_out(port, UART_XR_EFR, efr); + else +- serial_out(up, UART_EFR, efr); ++ serial_port_out(port, UART_EFR, efr); + } + + #ifdef CONFIG_ARCH_OMAP +@@ -2375,18 +2374,20 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + if (cpu_is_omap1510() && is_omap_port(up)) { + if (baud == 115200) { + quot = 1; +- serial_out(up, UART_OMAP_OSC_12M_SEL, 1); ++ serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); + } else +- serial_out(up, UART_OMAP_OSC_12M_SEL, 0); ++ serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); + } + #endif + +- if (up->capabilities & UART_NATSEMI) { +- /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */ +- serial_out(up, UART_LCR, 0xe0); +- } else { +- serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ +- } ++ /* ++ * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, ++ * otherwise just set DLAB ++ */ ++ if (up->capabilities & UART_NATSEMI) ++ serial_port_out(port, UART_LCR, 0xe0); ++ else ++ serial_port_out(port, UART_LCR, cval | UART_LCR_DLAB); + + serial_dl_write(up, quot); + +@@ -2395,16 +2396,15 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + * is written without DLAB set, this mode will be disabled. + */ + if (port->type == PORT_16750) +- serial_out(up, UART_FCR, fcr); ++ serial_port_out(port, UART_FCR, fcr); + +- serial_out(up, UART_LCR, cval); /* reset DLAB */ ++ serial_port_out(port, UART_LCR, cval); /* reset DLAB */ + up->lcr = cval; /* Save LCR */ + if (port->type != PORT_16750) { +- if (fcr & UART_FCR_ENABLE_FIFO) { +- /* emulated UARTs (Lucent Venus 167x) need two steps */ +- serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); +- } +- serial_out(up, UART_FCR, fcr); /* set fcr */ ++ /* emulated UARTs (Lucent Venus 167x) need two steps */ ++ if (fcr & UART_FCR_ENABLE_FIFO) ++ serial_port_out(port, UART_FCR, UART_FCR_ENABLE_FIFO); ++ serial_port_out(port, UART_FCR, fcr); /* set fcr */ + } + serial8250_set_mctrl(port, port->mctrl); + spin_unlock_irqrestore(&port->lock, flags); +@@ -2786,7 +2786,7 @@ static void serial8250_console_putchar(struct uart_port *port, int ch) + container_of(port, struct uart_8250_port, port); + + wait_for_xmitr(up, UART_LSR_THRE); +- serial_out(up, UART_TX, ch); ++ serial_port_out(port, UART_TX, ch); + } + + /* +@@ -2818,12 +2818,12 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) + /* + * First save the IER then disable the interrupts + */ +- ier = serial_in(up, UART_IER); ++ ier = serial_port_in(port, UART_IER); + + if (up->capabilities & UART_CAP_UUE) +- serial_out(up, UART_IER, UART_IER_UUE); ++ serial_port_out(port, UART_IER, UART_IER_UUE); + else +- serial_out(up, UART_IER, 0); ++ serial_port_out(port, UART_IER, 0); + + uart_console_write(port, s, count, serial8250_console_putchar); + +@@ -2832,7 +2832,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) + * and restore the IER + */ + wait_for_xmitr(up, BOTH_EMPTY); +- serial_out(up, UART_IER, ier); ++ serial_port_out(port, UART_IER, ier); + + /* + * The receive handling will happen properly because the +@@ -2994,11 +2994,11 @@ void serial8250_resume_port(int line) + + if (up->capabilities & UART_NATSEMI) { + /* Ensure it's still in high speed mode */ +- serial_out(up, UART_LCR, 0xE0); ++ serial_port_out(port, UART_LCR, 0xE0); + + ns16550a_goto_highspeed(up); + +- serial_out(up, UART_LCR, 0); ++ serial_port_out(port, UART_LCR, 0); + port->uartclk = 921600*16; + } + uart_resume_port(&serial8250_reg, port); +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0026-serial-remove-back-and-forth-conversions-in-serial_o.patch b/patches.kzm9g/0026-serial-remove-back-and-forth-conversions-in-serial_o.patch new file mode 100644 index 00000000000000..efe8300234a695 --- /dev/null +++ b/patches.kzm9g/0026-serial-remove-back-and-forth-conversions-in-serial_o.patch @@ -0,0 +1,56 @@ +From 51a2897e38814dc21408888a8d3ddd364e7686e2 Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Thu, 8 Mar 2012 19:12:14 -0500 +Subject: serial: remove back and forth conversions in serial_out_sync + +The two callers to serial_out_sync() have a struct port right +there in scope, but then pass in a struct 8250_port which then +is locally resolved back to a struct port. + +Delete the needless back and forth and just pass in the struct +port directly. Rename the function to have "_port" in its +name, so the name <--> args relationship is consistent with the +other serial_in/out vs serial_port_in/out function classes. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Acked-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 55e4016dd055e262e4b078b81c80b55386ead0f4) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250/8250.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c +index cb45a29..56492d2 100644 +--- a/drivers/tty/serial/8250/8250.c ++++ b/drivers/tty/serial/8250/8250.c +@@ -467,9 +467,8 @@ static void set_io_from_upio(struct uart_port *p) + } + + static void +-serial_out_sync(struct uart_8250_port *up, int offset, int value) ++serial_port_out_sync(struct uart_port *p, int offset, int value) + { +- struct uart_port *p = &up->port; + switch (p->iotype) { + case UPIO_MEM: + case UPIO_MEM32: +@@ -2022,11 +2021,11 @@ static int serial8250_startup(struct uart_port *port) + disable_irq_nosync(port->irq); + + wait_for_xmitr(up, UART_LSR_THRE); +- serial_out_sync(up, UART_IER, UART_IER_THRI); ++ serial_port_out_sync(port, UART_IER, UART_IER_THRI); + udelay(1); /* allow THRE to set */ + iir1 = serial_port_in(port, UART_IIR); + serial_port_out(port, UART_IER, 0); +- serial_out_sync(up, UART_IER, UART_IER_THRI); ++ serial_port_out_sync(port, UART_IER, UART_IER_THRI); + udelay(1); /* allow a working UART time to re-assert THRE */ + iir = serial_port_in(port, UART_IIR); + serial_port_out(port, UART_IER, 0); +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0027-serial-8250_pci-add-a-force-background-timer-flag-an.patch b/patches.kzm9g/0027-serial-8250_pci-add-a-force-background-timer-flag-an.patch new file mode 100644 index 00000000000000..95b07cdfa19be1 --- /dev/null +++ b/patches.kzm9g/0027-serial-8250_pci-add-a-force-background-timer-flag-an.patch @@ -0,0 +1,118 @@ +From b503e9756dc79ffaf2b3160b79c1bf2aed842547 Mon Sep 17 00:00:00 2001 +From: Dan Williams <dan.j.williams@intel.com> +Date: Fri, 6 Apr 2012 11:49:50 -0700 +Subject: serial/8250_pci: add a "force background timer" flag and use it for + the "kt" serial port + +Workaround dropped notifications in the iir register. Register reads +coincident with new interrupt notifications sometimes result in this +device clearing the interrupt event without reporting it in the read +data. + +The serial core already has a heuristic for determining when a device +has an untrustworthy iir register. In this case when we apriori know +that the iir is faulty use a flag (UPF_BUG_THRE) to bypass the test and +force usage of the background timer. + +[stable: 3.3.x] +Acked-by: Alan Cox <alan@linux.intel.com> +Cc: stable <stable@vger.kernel.org> +Reported-by: Nhan H Mai <nhan.h.mai@intel.com> +Reported-by: Sudhakar Mamillapalli <sudhakar@fb.com> +Tested-by: Nhan H Mai <nhan.h.mai@intel.com> +Tested-by: Sudhakar Mamillapalli <sudhakar@fb.com> +Signed-off-by: Dan Williams <dan.j.williams@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit bc02d15a3452fdf9276e8fb89c5e504a88df888a) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250/8250.c | 8 +++++--- + drivers/tty/serial/8250/8250_pci.c | 17 ++++++++++++++++- + include/linux/serial_core.h | 1 + + 3 files changed, 22 insertions(+), 4 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c +index 56492d2..5c27f7e 100644 +--- a/drivers/tty/serial/8250/8250.c ++++ b/drivers/tty/serial/8250/8250.c +@@ -2035,10 +2035,12 @@ static int serial8250_startup(struct uart_port *port) + spin_unlock_irqrestore(&port->lock, flags); + + /* +- * If the interrupt is not reasserted, setup a timer to +- * kick the UART on a regular basis. ++ * If the interrupt is not reasserted, or we otherwise ++ * don't trust the iir, setup a timer to kick the UART ++ * on a regular basis. + */ +- if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) { ++ if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) || ++ up->port.flags & UPF_BUG_THRE) { + up->bugs |= UART_BUG_THRE; + pr_debug("ttyS%d - using backup timer\n", + serial_index(port)); +diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +index a213f38..107eff0 100644 +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -994,6 +994,14 @@ static int skip_tx_en_setup(struct serial_private *priv, + return pci_default_setup(priv, board, port, idx); + } + ++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; ++ return skip_tx_en_setup(priv, board, port, idx); ++} ++ + static int pci_eg20t_init(struct pci_dev *dev) + { + #if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE) +@@ -1012,7 +1020,6 @@ pci_xr17c154_setup(struct serial_private *priv, + return pci_default_setup(priv, board, port, idx); + } + +-/* This should be in linux/pci_ids.h */ + #define PCI_VENDOR_ID_SBSMODULARIO 0x124B + #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B + #define PCI_DEVICE_ID_OCTPRO 0x0001 +@@ -1038,6 +1045,7 @@ pci_xr17c154_setup(struct serial_private *priv, + #define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 + #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 + #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 ++#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d + + /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ + #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 +@@ -1122,6 +1130,13 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { + .subdevice = PCI_ANY_ID, + .setup = ce4100_serial_setup, + }, ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_PATSBURG_KT, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .setup = kt_serial_setup, ++ }, + /* + * ITE + */ +diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h +index d611ca0..724fde0 100644 +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -351,6 +351,7 @@ struct uart_port { + #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) + #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) + #define UPF_EXAR_EFR ((__force upf_t) (1 << 25)) ++#define UPF_BUG_THRE ((__force upf_t) (1 << 26)) + /* The exact UART type is known and should not be probed. */ + #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) + #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0028-8250.c-less-than-2400-baud-fix.patch b/patches.kzm9g/0028-8250.c-less-than-2400-baud-fix.patch new file mode 100644 index 00000000000000..44791ce2d1d895 --- /dev/null +++ b/patches.kzm9g/0028-8250.c-less-than-2400-baud-fix.patch @@ -0,0 +1,51 @@ +From 5fbfa3c9a23c95bb26065fb7a6ee3d6256d2a410 Mon Sep 17 00:00:00 2001 +From: Christian Melki <christian.melki@ericsson.se> +Date: Mon, 30 Apr 2012 11:21:26 +0200 +Subject: 8250.c: less than 2400 baud fix. + +We noticed that we were loosing data at speed less than 2400 baud. +It turned out our (TI16750 compatible) uart with 64 byte outgoing fifo +was truncated to 16 byte (bit 5 sets fifo len) when modifying the fcr +reg. +The input code still fills the buffer with 64 bytes if I remember +correctly and thus data is lost. +Our fix was to remove whiping of the fcr content and just add the +TRIGGER_1 which we want for latency. +I can't see why this would not work on less than 2400 always, for all +uarts ... +Otherwise one would have to make sure the filling of the fifo re-checks +the current state of available fifo size (urrk). + +Signed-off-by: Christian Melki <christian.melki@ericsson.se> +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit f9a9111b540fd67db5dab332f4b83d86c90e27b1) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250/8250.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c +index 5c27f7e..d537431 100644 +--- a/drivers/tty/serial/8250/8250.c ++++ b/drivers/tty/serial/8250/8250.c +@@ -2280,10 +2280,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + quot++; + + if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { +- if (baud < 2400) +- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; +- else +- fcr = uart_config[port->type].fcr; ++ fcr = uart_config[port->type].fcr; ++ if (baud < 2400) { ++ fcr &= ~UART_FCR_TRIGGER_MASK; ++ fcr |= UART_FCR_TRIGGER_1; ++ } + } + + /* +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0029-serial8250-Add-dl_read-dl_write-callbacks.patch b/patches.kzm9g/0029-serial8250-Add-dl_read-dl_write-callbacks.patch new file mode 100644 index 00000000000000..b1eb8440605ba8 --- /dev/null +++ b/patches.kzm9g/0029-serial8250-Add-dl_read-dl_write-callbacks.patch @@ -0,0 +1,203 @@ +From c7fbe0d5b21bad7ee177f745bfd423f0ed57243d Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 2 May 2012 21:46:51 +0900 +Subject: serial8250: Add dl_read()/dl_write() callbacks + +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) + +Conflicts: + drivers/tty/serial/8250/8250.h + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + 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 d537431..7a31149 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 2868a1d..bafe034 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 { +@@ -96,6 +100,16 @@ static inline void serial_out(struct uart_8250_port *up, int offset, int value) + up->port.serial_out(&up->port, offset, value); + } + ++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.10.1.362.g242cab3 + diff --git a/patches.kzm9g/003-ltsi-bugfix-sh73a0-add-lost-clk_enable_on_init-for-div6_zb1.patch b/patches.kzm9g/003-ltsi-bugfix-sh73a0-add-lost-clk_enable_on_init-for-div6_zb1.patch new file mode 100644 index 00000000000000..a2c38d49cd6794 --- /dev/null +++ b/patches.kzm9g/003-ltsi-bugfix-sh73a0-add-lost-clk_enable_on_init-for-div6_zb1.patch @@ -0,0 +1,52 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Tue Jun 26 04:11:21 2012 +From: Tetsuyuki Kobayashi <koba@kmckk.co.jp> +Date: Tue, 26 Jun 2012 20:11:18 +0900 +Subject: [LTSI-dev] [PATCH 3/4] LTSI: bugfix: sh73a0: add lost CLK_ENABLE_ON_INIT for DIV6_ZB1 +To: ltsi-dev@lists.linuxfoundation.org +Cc: kuninori.morimoto.gx@gmail.com +Message-ID: <4FE998D6.9050209@kmckk.co.jp> + + +On upstream kernel, on one branch, +CLK_ENABLE_ON_INIT was added to DIV6_ZB1 clock by +9bcc0a5d0de137b3a154dc951c5ff70dce815879 +(ARM: mach-shmobile: SH73A0 external Ethernet fix) + +On the other branch, below commit modified dev6_clks[] controlling method. +d4775356bb39eaa305844cc6cc4c267236535956 +(sh: clkfwk: clock-sh73a0: all div6_clks use SH_CLK_DIV6_EXT()) + +These 2 commit had conflict, and were solved when merge window +timing on upstream kernel. +But unfortunately, this solution seems had be lost on backporting. +This patch fixes it up for LTSI. + +Reported-by: Kunihiko Tsuji <kunihiko at kmckk.co.jp> +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com> +Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp> +--- + arch/arm/mach-shmobile/clock-sh73a0.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c +index 012b284..fcecbdc 100644 +--- a/arch/arm/mach-shmobile/clock-sh73a0.c ++++ b/arch/arm/mach-shmobile/clock-sh73a0.c +@@ -328,7 +328,7 @@ static struct clk div6_clks[DIV6_NR] = { + vck_parent, ARRAY_SIZE(vck_parent), 12, 3), + [DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0, + vck_parent, ARRAY_SIZE(vck_parent), 12, 3), +- [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, 0, ++ [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT, + pll_parent, ARRAY_SIZE(pll_parent), 7, 1), + [DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0, + pll_parent, ARRAY_SIZE(pll_parent), 7, 1), +-- +1.7.9.5 + + +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.kzm9g/0030-serial8250-Use-dl_read-dl_write-on-Alchemy.patch b/patches.kzm9g/0030-serial8250-Use-dl_read-dl_write-on-Alchemy.patch new file mode 100644 index 00000000000000..d543de7ec41cc8 --- /dev/null +++ b/patches.kzm9g/0030-serial8250-Use-dl_read-dl_write-on-Alchemy.patch @@ -0,0 +1,138 @@ +From c5c260031fff81671154c36017619be60bd9db4d Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 2 May 2012 21:47:00 +0900 +Subject: serial8250: Use dl_read()/dl_write() on Alchemy + +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: Simon Horman <horms@verge.net.au> +--- + 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 7a31149..ce7717c 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.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0031-serial8250-Use-dl_read-dl_write-on-RM9K.patch b/patches.kzm9g/0031-serial8250-Use-dl_read-dl_write-on-RM9K.patch new file mode 100644 index 00000000000000..11c12350a223cd --- /dev/null +++ b/patches.kzm9g/0031-serial8250-Use-dl_read-dl_write-on-RM9K.patch @@ -0,0 +1,139 @@ +From b2a0b1532958cbf0ef8e7078c78558b2e78bb524 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 2 May 2012 21:47:09 +0900 +Subject: serial8250: Use dl_read()/dl_write() on RM9K + +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: Simon Horman <horms@verge.net.au> +--- + 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 ce7717c..36ce1e2 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.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0032-serial8250-Clean-up-default-map-and-dl-code.patch b/patches.kzm9g/0032-serial8250-Clean-up-default-map-and-dl-code.patch new file mode 100644 index 00000000000000..5ebaebd7ba7583 --- /dev/null +++ b/patches.kzm9g/0032-serial8250-Clean-up-default-map-and-dl-code.patch @@ -0,0 +1,134 @@ +From 2c6855bab06ff3e78cdcafd00a9ab5b6fd4c3ef3 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 2 May 2012 21:47:18 +0900 +Subject: serial8250: Clean up default map and dl code + +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: Simon Horman <horms@verge.net.au> +--- + 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 36ce1e2..3445a27 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.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0033-serial8250-Introduce-serial8250_register_8250_port.patch b/patches.kzm9g/0033-serial8250-Introduce-serial8250_register_8250_port.patch new file mode 100644 index 00000000000000..f01d7ee280adfa --- /dev/null +++ b/patches.kzm9g/0033-serial8250-Introduce-serial8250_register_8250_port.patch @@ -0,0 +1,169 @@ +From 4d5e00ec9374ddf1ec0995e10380e2e044eb8154 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 2 May 2012 21:47:27 +0900 +Subject: serial8250: Introduce serial8250_register_8250_port() + +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) + +Conflicts: + drivers/tty/serial/8250/8250.c + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/tty/serial/8250/8250.c | 87 ++++++++++++++++++++++++++-------------- + include/linux/serial_8250.h | 1 + + 2 files changed, 58 insertions(+), 30 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c +index 3445a27..8de9a39 100644 +--- a/drivers/tty/serial/8250/8250.c ++++ b/drivers/tty/serial/8250/8250.c +@@ -3132,7 +3132,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 +@@ -3144,50 +3144,54 @@ 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 (up->port.set_termios) ++ uart->port.set_termios = up->port.set_termios; ++ if (up->port.pm) ++ uart->port.pm = up->port.pm; ++ 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, +@@ -3201,6 +3205,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 b44034e..d7f286e 100644 +--- a/include/linux/serial_8250.h ++++ b/include/linux/serial_8250.h +@@ -68,6 +68,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.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0034-serial8250-em-Emma-Mobile-UART-driver-V2.patch b/patches.kzm9g/0034-serial8250-em-Emma-Mobile-UART-driver-V2.patch new file mode 100644 index 00000000000000..d20eea6d874744 --- /dev/null +++ b/patches.kzm9g/0034-serial8250-em-Emma-Mobile-UART-driver-V2.patch @@ -0,0 +1,254 @@ +From 851dd6ac01a254a7c6e14a75c0cd0c8aec2d542b Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 3 May 2012 21:13:09 +0900 +Subject: serial8250-em: Emma Mobile UART driver V2 + +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) + +Conflicts: + drivers/tty/serial/8250/Kconfig + drivers/tty/serial/8250/Makefile + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + 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 b1bb251..7aa3b6c 100644 +--- a/drivers/tty/serial/8250/Kconfig ++++ b/drivers/tty/serial/8250/Kconfig +@@ -266,3 +266,11 @@ config SERIAL_8250_RM9K + Selecting this option will add support for the integrated serial + port hardware found on MIPS RM9122 and similar processors. + If unsure, say N. ++ ++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 c0d0c29..6a70704 100644 +--- a/drivers/tty/serial/8250/Makefile ++++ b/drivers/tty/serial/8250/Makefile +@@ -16,3 +16,4 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o + obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o + obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o + obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o ++obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0035-serial8250-em-clk_get-IS_ERR-error-handling-fix.patch b/patches.kzm9g/0035-serial8250-em-clk_get-IS_ERR-error-handling-fix.patch new file mode 100644 index 00000000000000..f0dbf2bf2bd6ed --- /dev/null +++ b/patches.kzm9g/0035-serial8250-em-clk_get-IS_ERR-error-handling-fix.patch @@ -0,0 +1,38 @@ +From 7ff1614653a079059c1d017d4d95376a616649ab Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 9 May 2012 15:49:57 +0900 +Subject: serial8250-em: clk_get() IS_ERR() error handling fix + +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: Simon Horman <horms@verge.net.au> +--- + 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.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0036-cpuidle-create-bootparam-cpuidle.off-1.patch b/patches.kzm9g/0036-cpuidle-create-bootparam-cpuidle.off-1.patch new file mode 100644 index 00000000000000..d0cef7b7014acd --- /dev/null +++ b/patches.kzm9g/0036-cpuidle-create-bootparam-cpuidle.off-1.patch @@ -0,0 +1,116 @@ +From 9c84f8943b8bb242d3eab46ab23bc6daeaa7a02f Mon Sep 17 00:00:00 2001 +From: Len Brown <len.brown@intel.com> +Date: Fri, 1 Apr 2011 18:13:10 -0400 +Subject: cpuidle: create bootparam "cpuidle.off=1" + +useful for disabling cpuidle to fall back +to architecture-default idle loop + +cpuidle drivers and governors will fail to register. +on x86 they'll say so: + +intel_idle: intel_idle yielding to (null) +ACPI: acpi_idle yielding to (null) + +Signed-off-by: Len Brown <len.brown@intel.com> +(cherry picked from commit 62027aea23fcd14478abdddd3b74a4e0f5fb2984) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + Documentation/kernel-parameters.txt | 3 +++ + drivers/cpuidle/cpuidle.c | 10 ++++++++++ + drivers/cpuidle/cpuidle.h | 1 + + drivers/cpuidle/driver.c | 3 +++ + drivers/cpuidle/governor.c | 3 +++ + 5 files changed, 20 insertions(+) + +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index 400b7be..79cef3c 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -546,6 +546,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + /proc/<pid>/coredump_filter. + See also Documentation/filesystems/proc.txt. + ++ cpuidle.off=1 [CPU_IDLE] ++ disable the cpuidle sub-system ++ + cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver + Format: + <first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>] +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index eed4c47..4487396 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -28,6 +28,12 @@ LIST_HEAD(cpuidle_detected_devices); + static void (*pm_idle_old)(void); + + static int enabled_devices; ++static int off __read_mostly; ++ ++int cpuidle_disabled(void) ++{ ++ return off; ++} + + #if defined(CONFIG_ARCH_HAS_CPU_IDLE_WAIT) + static void cpuidle_kick_cpus(void) +@@ -427,6 +433,9 @@ static int __init cpuidle_init(void) + { + int ret; + ++ if (cpuidle_disabled()) ++ return -ENODEV; ++ + pm_idle_old = pm_idle; + + ret = cpuidle_add_class_sysfs(&cpu_sysdev_class); +@@ -438,4 +447,5 @@ static int __init cpuidle_init(void) + return 0; + } + ++module_param(off, int, 0444); + core_initcall(cpuidle_init); +diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h +index 33e50d5..38c3fd8 100644 +--- a/drivers/cpuidle/cpuidle.h ++++ b/drivers/cpuidle/cpuidle.h +@@ -13,6 +13,7 @@ extern struct list_head cpuidle_governors; + extern struct list_head cpuidle_detected_devices; + extern struct mutex cpuidle_lock; + extern spinlock_t cpuidle_driver_lock; ++extern int cpuidle_disabled(void); + + /* idle loop */ + extern void cpuidle_install_idle_handler(void); +diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c +index fd1601e..3f7e3ce 100644 +--- a/drivers/cpuidle/driver.c ++++ b/drivers/cpuidle/driver.c +@@ -26,6 +26,9 @@ int cpuidle_register_driver(struct cpuidle_driver *drv) + if (!drv) + return -EINVAL; + ++ if (cpuidle_disabled()) ++ return -ENODEV; ++ + spin_lock(&cpuidle_driver_lock); + if (cpuidle_curr_driver) { + spin_unlock(&cpuidle_driver_lock); +diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c +index 724c164..ea2f8e7 100644 +--- a/drivers/cpuidle/governor.c ++++ b/drivers/cpuidle/governor.c +@@ -81,6 +81,9 @@ int cpuidle_register_governor(struct cpuidle_governor *gov) + if (!gov || !gov->select) + return -EINVAL; + ++ if (cpuidle_disabled()) ++ return -ENODEV; ++ + mutex_lock(&cpuidle_lock); + if (__cpuidle_find_governor(gov->name) == NULL) { + ret = 0; +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0037-cpuidle-replace-xen-access-to-x86-pm_idle-and-defaul.patch b/patches.kzm9g/0037-cpuidle-replace-xen-access-to-x86-pm_idle-and-defaul.patch new file mode 100644 index 00000000000000..3ae71b0e25c0c6 --- /dev/null +++ b/patches.kzm9g/0037-cpuidle-replace-xen-access-to-x86-pm_idle-and-defaul.patch @@ -0,0 +1,85 @@ +From 761a5d96c87fccab8a53f8c8c3240d8dcdb1bb19 Mon Sep 17 00:00:00 2001 +From: Len Brown <len.brown@intel.com> +Date: Fri, 1 Apr 2011 18:28:35 -0400 +Subject: cpuidle: replace xen access to x86 pm_idle and default_idle + +When a Xen Dom0 kernel boots on a hypervisor, it gets access +to the raw-hardware ACPI tables. While it parses the idle tables +for the hypervisor's beneift, it uses HLT for its own idle. + +Rather than have xen scribble on pm_idle and access default_idle, +have it simply disable_cpuidle() so acpi_idle will not load and +architecture default HLT will be used. + +cc: xen-devel@lists.xensource.com +Tested-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Acked-by: H. Peter Anvin <hpa@linux.intel.com> +Signed-off-by: Len Brown <len.brown@intel.com> +(cherry picked from commit d91ee5863b71e8c90eaf6035bff3078a85e2e7b5) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/x86/xen/setup.c | 3 ++- + drivers/cpuidle/cpuidle.c | 4 ++++ + include/linux/cpuidle.h | 2 ++ + 3 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c +index f8dcda4..e16a4ca 100644 +--- a/arch/x86/xen/setup.c ++++ b/arch/x86/xen/setup.c +@@ -9,6 +9,7 @@ + #include <linux/mm.h> + #include <linux/pm.h> + #include <linux/memblock.h> ++#include <linux/cpuidle.h> + + #include <asm/elf.h> + #include <asm/vdso.h> +@@ -459,7 +460,7 @@ void __init xen_arch_setup(void) + #ifdef CONFIG_X86_32 + boot_cpu_data.hlt_works_ok = 1; + #endif +- pm_idle = default_idle; ++ disable_cpuidle(); + boot_option_idle_override = IDLE_HALT; + + fiddle_vdso(); +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index 4487396..cd1c19c 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -34,6 +34,10 @@ int cpuidle_disabled(void) + { + return off; + } ++void disable_cpuidle(void) ++{ ++ off = 1; ++} + + #if defined(CONFIG_ARCH_HAS_CPU_IDLE_WAIT) + static void cpuidle_kick_cpus(void) +diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h +index 36719ea..b89f67d 100644 +--- a/include/linux/cpuidle.h ++++ b/include/linux/cpuidle.h +@@ -122,6 +122,7 @@ struct cpuidle_driver { + }; + + #ifdef CONFIG_CPU_IDLE ++extern void disable_cpuidle(void); + + extern int cpuidle_register_driver(struct cpuidle_driver *drv); + struct cpuidle_driver *cpuidle_get_driver(void); +@@ -135,6 +136,7 @@ extern int cpuidle_enable_device(struct cpuidle_device *dev); + extern void cpuidle_disable_device(struct cpuidle_device *dev); + + #else ++static inline void disable_cpuidle(void) { } + + static inline int cpuidle_register_driver(struct cpuidle_driver *drv) + {return -ENODEV; } +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0038-cpuidle-stop-depending-on-pm_idle.patch b/patches.kzm9g/0038-cpuidle-stop-depending-on-pm_idle.patch new file mode 100644 index 00000000000000..276df0975f753b --- /dev/null +++ b/patches.kzm9g/0038-cpuidle-stop-depending-on-pm_idle.patch @@ -0,0 +1,254 @@ +From be5500b643f8d3d104e64d9096a5c8d86afadd92 Mon Sep 17 00:00:00 2001 +From: Len Brown <len.brown@intel.com> +Date: Fri, 1 Apr 2011 19:34:59 -0400 +Subject: cpuidle: stop depending on pm_idle + +cpuidle users should call cpuidle_call_idle() directly +rather than via (pm_idle)() function pointer. + +Architecture may choose to continue using (pm_idle)(), +but cpuidle need not depend on it: + + my_arch_cpu_idle() + ... + if(cpuidle_call_idle()) + pm_idle(); + +cc: Kevin Hilman <khilman@deeprootsystems.com> +cc: Paul Mundt <lethal@linux-sh.org> +cc: x86@kernel.org +Acked-by: H. Peter Anvin <hpa@linux.intel.com> +Signed-off-by: Len Brown <len.brown@intel.com> +(cherry picked from commit a0bfa1373859e9d11dc92561a8667588803e42d8) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/kernel/process.c | 4 +++- + arch/sh/kernel/idle.c | 6 ++++-- + arch/x86/kernel/process_32.c | 4 +++- + arch/x86/kernel/process_64.c | 4 +++- + drivers/cpuidle/cpuidle.c | 38 ++++++++++++++++++-------------------- + include/linux/cpuidle.h | 2 ++ + 6 files changed, 33 insertions(+), 25 deletions(-) + +diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c +index 74ae833..5affc61 100644 +--- a/arch/arm/kernel/process.c ++++ b/arch/arm/kernel/process.c +@@ -30,6 +30,7 @@ + #include <linux/uaccess.h> + #include <linux/random.h> + #include <linux/hw_breakpoint.h> ++#include <linux/cpuidle.h> + + #include <asm/cacheflush.h> + #include <asm/leds.h> +@@ -199,7 +200,8 @@ void cpu_idle(void) + cpu_relax(); + } else { + stop_critical_timings(); +- pm_idle(); ++ if (cpuidle_call_idle()) ++ pm_idle(); + start_critical_timings(); + /* + * This will eventually be removed - pm_idle +diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c +index 425d604..9c7099e 100644 +--- a/arch/sh/kernel/idle.c ++++ b/arch/sh/kernel/idle.c +@@ -16,12 +16,13 @@ + #include <linux/thread_info.h> + #include <linux/irqflags.h> + #include <linux/smp.h> ++#include <linux/cpuidle.h> + #include <asm/pgalloc.h> + #include <asm/system.h> + #include <asm/atomic.h> + #include <asm/smp.h> + +-void (*pm_idle)(void) = NULL; ++static void (*pm_idle)(void); + + static int hlt_counter; + +@@ -100,7 +101,8 @@ void cpu_idle(void) + local_irq_disable(); + /* Don't trace irqs off for idle */ + stop_critical_timings(); +- pm_idle(); ++ if (cpuidle_call_idle()) ++ pm_idle(); + /* + * Sanity check to ensure that pm_idle() returns + * with IRQs enabled +diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c +index fcdb1b3..ca71e9a 100644 +--- a/arch/x86/kernel/process_32.c ++++ b/arch/x86/kernel/process_32.c +@@ -38,6 +38,7 @@ + #include <linux/uaccess.h> + #include <linux/io.h> + #include <linux/kdebug.h> ++#include <linux/cpuidle.h> + + #include <asm/pgtable.h> + #include <asm/system.h> +@@ -109,7 +110,8 @@ void cpu_idle(void) + local_irq_disable(); + /* Don't trace irqs off for idle */ + stop_critical_timings(); +- pm_idle(); ++ if (cpuidle_idle_call()) ++ pm_idle(); + start_critical_timings(); + } + tick_nohz_restart_sched_tick(); +diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c +index b01898d..ca8df6a 100644 +--- a/arch/x86/kernel/process_64.c ++++ b/arch/x86/kernel/process_64.c +@@ -37,6 +37,7 @@ + #include <linux/uaccess.h> + #include <linux/io.h> + #include <linux/ftrace.h> ++#include <linux/cpuidle.h> + + #include <asm/pgtable.h> + #include <asm/system.h> +@@ -136,7 +137,8 @@ void cpu_idle(void) + enter_idle(); + /* Don't trace irqs off for idle */ + stop_critical_timings(); +- pm_idle(); ++ if (cpuidle_idle_call()) ++ pm_idle(); + start_critical_timings(); + + /* In many cases the interrupt that ended idle +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index cd1c19c..0df0141 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -25,10 +25,10 @@ DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices); + + DEFINE_MUTEX(cpuidle_lock); + LIST_HEAD(cpuidle_detected_devices); +-static void (*pm_idle_old)(void); + + static int enabled_devices; + static int off __read_mostly; ++static int initialized __read_mostly; + + int cpuidle_disabled(void) + { +@@ -56,25 +56,23 @@ static int __cpuidle_register_device(struct cpuidle_device *dev); + * cpuidle_idle_call - the main idle loop + * + * NOTE: no locks or semaphores should be used here ++ * return non-zero on failure + */ +-static void cpuidle_idle_call(void) ++int cpuidle_idle_call(void) + { + struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); + struct cpuidle_state *target_state; + int next_state; + ++ if (off) ++ return -ENODEV; ++ ++ if (!initialized) ++ return -ENODEV; ++ + /* check if the device is ready */ +- if (!dev || !dev->enabled) { +- if (pm_idle_old) +- pm_idle_old(); +- else +-#if defined(CONFIG_ARCH_HAS_DEFAULT_IDLE) +- default_idle(); +-#else +- local_irq_enable(); +-#endif +- return; +- } ++ if (!dev || !dev->enabled) ++ return -EBUSY; + + #if 0 + /* shows regressions, re-enable for 2.6.29 */ +@@ -99,7 +97,7 @@ static void cpuidle_idle_call(void) + next_state = cpuidle_curr_governor->select(dev); + if (need_resched()) { + local_irq_enable(); +- return; ++ return 0; + } + + target_state = &dev->states[next_state]; +@@ -124,6 +122,8 @@ static void cpuidle_idle_call(void) + /* give the governor an opportunity to reflect on the outcome */ + if (cpuidle_curr_governor->reflect) + cpuidle_curr_governor->reflect(dev); ++ ++ return 0; + } + + /** +@@ -131,10 +131,10 @@ static void cpuidle_idle_call(void) + */ + void cpuidle_install_idle_handler(void) + { +- if (enabled_devices && (pm_idle != cpuidle_idle_call)) { ++ if (enabled_devices) { + /* Make sure all changes finished before we switch to new idle */ + smp_wmb(); +- pm_idle = cpuidle_idle_call; ++ initialized = 1; + } + } + +@@ -143,8 +143,8 @@ void cpuidle_install_idle_handler(void) + */ + void cpuidle_uninstall_idle_handler(void) + { +- if (enabled_devices && pm_idle_old && (pm_idle != pm_idle_old)) { +- pm_idle = pm_idle_old; ++ if (enabled_devices) { ++ initialized = 0; + cpuidle_kick_cpus(); + } + } +@@ -440,8 +440,6 @@ static int __init cpuidle_init(void) + if (cpuidle_disabled()) + return -ENODEV; + +- pm_idle_old = pm_idle; +- + ret = cpuidle_add_class_sysfs(&cpu_sysdev_class); + if (ret) + return ret; +diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h +index b89f67d..b51629e 100644 +--- a/include/linux/cpuidle.h ++++ b/include/linux/cpuidle.h +@@ -123,6 +123,7 @@ struct cpuidle_driver { + + #ifdef CONFIG_CPU_IDLE + extern void disable_cpuidle(void); ++extern int cpuidle_idle_call(void); + + extern int cpuidle_register_driver(struct cpuidle_driver *drv); + struct cpuidle_driver *cpuidle_get_driver(void); +@@ -137,6 +138,7 @@ extern void cpuidle_disable_device(struct cpuidle_device *dev); + + #else + static inline void disable_cpuidle(void) { } ++static inline int cpuidle_idle_call(void) { return -ENODEV; } + + static inline int cpuidle_register_driver(struct cpuidle_driver *drv) + {return -ENODEV; } +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0039-cpuidle-Consistent-spelling-of-cpuidle_idle_call.patch b/patches.kzm9g/0039-cpuidle-Consistent-spelling-of-cpuidle_idle_call.patch new file mode 100644 index 00000000000000..495c66f5cd66dc --- /dev/null +++ b/patches.kzm9g/0039-cpuidle-Consistent-spelling-of-cpuidle_idle_call.patch @@ -0,0 +1,53 @@ +From 8fb27384a7f934ae0f01e86b41a8cdc22bf57ca7 Mon Sep 17 00:00:00 2001 +From: David Brown <davidb@codeaurora.org> +Date: Thu, 4 Aug 2011 09:24:31 -0700 +Subject: cpuidle: Consistent spelling of cpuidle_idle_call() + +Commit a0bfa1373859e9d11dc92561a8667588803e42d8 mispells +cpuidle_idle_call() on ARM and SH code. Fix this to be consistent. + +Cc: Kevin Hilman <khilman@deeprootsystems.com> +Cc: Paul Mundt <lethal@linux-sh.org> +Cc: x86@kernel.org +Cc: Len Brown <len.brown@intel.com> +Signed-off-by: David Brown <davidb@codeaurora.org> +[ Also done by Mark Brown - th ebug has been around forever, and was + noticed in -next, but the idle tree never picked it up. Bad bad bad ] +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +(cherry picked from commit cbc158d6bfa1990f7869717bb5270867c66068d1) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/kernel/process.c | 2 +- + arch/sh/kernel/idle.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c +index 5affc61..c9d11ea 100644 +--- a/arch/arm/kernel/process.c ++++ b/arch/arm/kernel/process.c +@@ -200,7 +200,7 @@ void cpu_idle(void) + cpu_relax(); + } else { + stop_critical_timings(); +- if (cpuidle_call_idle()) ++ if (cpuidle_idle_call()) + pm_idle(); + start_critical_timings(); + /* +diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c +index 9c7099e..1db1968 100644 +--- a/arch/sh/kernel/idle.c ++++ b/arch/sh/kernel/idle.c +@@ -101,7 +101,7 @@ void cpu_idle(void) + local_irq_disable(); + /* Don't trace irqs off for idle */ + stop_critical_timings(); +- if (cpuidle_call_idle()) ++ if (cpuidle_idle_call()) + pm_idle(); + /* + * Sanity check to ensure that pm_idle() returns +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/004-ltsi-arm-mach_shmobile-kzm9g-update-defconfig.patch b/patches.kzm9g/004-ltsi-arm-mach_shmobile-kzm9g-update-defconfig.patch new file mode 100644 index 00000000000000..5e0b7267478066 --- /dev/null +++ b/patches.kzm9g/004-ltsi-arm-mach_shmobile-kzm9g-update-defconfig.patch @@ -0,0 +1,48 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Tue Jun 26 04:12:14 2012 +From: Tetsuyuki Kobayashi <koba@kmckk.co.jp> +Date: Tue, 26 Jun 2012 20:12:11 +0900 +Subject: [LTSI-dev] [PATCH 4/4] LTSI: ARM: mach_shmobile: kzm9g: update defconfig +To: ltsi-dev@lists.linuxfoundation.org, kuninori.morimoto.gx@gmail.com +Message-ID: <4FE9990B.7040207@kmckk.co.jp> + + +Add NET_ETHERNET and HID. + +Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp> +--- + arch/arm/configs/kzm9g_defconfig | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig +index 6fb27eb..b9b3722 100644 +--- a/arch/arm/configs/kzm9g_defconfig ++++ b/arch/arm/configs/kzm9g_defconfig +@@ -64,6 +64,9 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" + CONFIG_SCSI=y + CONFIG_BLK_DEV_SD=y + CONFIG_NETDEVICES=y ++CONFIG_MII=y ++CONFIG_PHYLIB=y ++CONFIG_NET_ETHERNET=y + CONFIG_SMSC911X=y + # CONFIG_WLAN is not set + CONFIG_INPUT_SPARSEKMAP=y +@@ -97,7 +100,9 @@ CONFIG_SND=y + # CONFIG_SND_USB is not set + CONFIG_SND_SOC=y + CONFIG_SND_SOC_SH4_FSI=y +-# CONFIG_HID_SUPPORT is not set ++CONFIG_HID_SUPPORT=y ++CONFIG_HID=y ++CONFIG_USB_HID=y + CONFIG_USB=y + CONFIG_USB_DEVICEFS=y + CONFIG_USB_R8A66597_HCD=y +-- +1.7.9.5 + +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.kzm9g/0040-sh-Fix-up-fallout-from-cpuidle-changes.patch b/patches.kzm9g/0040-sh-Fix-up-fallout-from-cpuidle-changes.patch new file mode 100644 index 00000000000000..e39f543f6d5345 --- /dev/null +++ b/patches.kzm9g/0040-sh-Fix-up-fallout-from-cpuidle-changes.patch @@ -0,0 +1,32 @@ +From ff5ca09e2aa7d364357133e228c8f47ceccaa8a0 Mon Sep 17 00:00:00 2001 +From: Paul Mundt <lethal@linux-sh.org> +Date: Mon, 8 Aug 2011 16:30:11 +0900 +Subject: sh: Fix up fallout from cpuidle changes. + +Fixes up the pm_idle redefinition that was introduced with the earlier +cpuidle changes. + +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit c66d3fcbf306af3c0c4b6f4e0d81467f89c67702) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/sh/kernel/idle.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c +index 1db1968..169767f 100644 +--- a/arch/sh/kernel/idle.c ++++ b/arch/sh/kernel/idle.c +@@ -22,7 +22,7 @@ + #include <asm/atomic.h> + #include <asm/smp.h> + +-static void (*pm_idle)(void); ++void (*pm_idle)(void); + + static int hlt_counter; + +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0041-cpuidle-Add-module.h-to-drivers-cpuidle-files-as-req.patch b/patches.kzm9g/0041-cpuidle-Add-module.h-to-drivers-cpuidle-files-as-req.patch new file mode 100644 index 00000000000000..4a4ecdd8a534a1 --- /dev/null +++ b/patches.kzm9g/0041-cpuidle-Add-module.h-to-drivers-cpuidle-files-as-req.patch @@ -0,0 +1,41 @@ +From e642a0935f0ebf4599766c1005b6995f79a0cfcd Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Mon, 29 Aug 2011 17:52:39 -0400 +Subject: cpuidle: Add module.h to drivers/cpuidle files as required. + +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +(cherry picked from commit 884b17e109d61e95ee4c652cf6873341bf1dca63) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/cpuidle/cpuidle.c | 1 + + drivers/cpuidle/governors/menu.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index 0df0141..becd6d9 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -17,6 +17,7 @@ + #include <linux/cpuidle.h> + #include <linux/ktime.h> + #include <linux/hrtimer.h> ++#include <linux/module.h> + #include <trace/events/power.h> + + #include "cpuidle.h" +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index 3600f19..0027524 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -19,6 +19,7 @@ + #include <linux/tick.h> + #include <linux/sched.h> + #include <linux/math64.h> ++#include <linux/module.h> + + #define BUCKETS 12 + #define INTERVALS 8 +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0042-cpuidle-Move-dev-last_residency-update-to-driver-ent.patch b/patches.kzm9g/0042-cpuidle-Move-dev-last_residency-update-to-driver-ent.patch new file mode 100644 index 00000000000000..fb997a6fcea315 --- /dev/null +++ b/patches.kzm9g/0042-cpuidle-Move-dev-last_residency-update-to-driver-ent.patch @@ -0,0 +1,868 @@ +From a2bea6713199f518d94d1bcc5acbe8b7523d4b7e Mon Sep 17 00:00:00 2001 +From: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> +Date: Fri, 28 Oct 2011 16:20:09 +0530 +Subject: cpuidle: Move dev->last_residency update to driver enter routine; + remove dev->last_state + +Cpuidle governor only suggests the state to enter using the +governor->select() interface, but allows the low level driver to +override the recommended state. The actual entered state +may be different because of software or hardware demotion. Software +demotion is done by the back-end cpuidle driver and can be accounted +correctly. Current cpuidle code uses last_state field to capture the +actual state entered and based on that updates the statistics for the +state entered. + +Ideally the driver enter routine should update the counters, +and it should return the state actually entered rather than the time +spent there. The generic cpuidle code should simply handle where +the counters live in the sysfs namespace, not updating the counters. + +Reference: +https://lkml.org/lkml/2011/3/25/52 + +Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> +Signed-off-by: Trinabh Gupta <g.trinabh@gmail.com> +Tested-by: Jean Pihet <j-pihet@ti.com> +Reviewed-by: Kevin Hilman <khilman@ti.com> +Acked-by: Arjan van de Ven <arjan@linux.intel.com> +Acked-by: Kevin Hilman <khilman@ti.com> +Signed-off-by: Len Brown <len.brown@intel.com> +(cherry picked from commit e978aa7d7d57d04eb5f88a7507c4fb98577def77) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/mach-at91/cpuidle.c | 10 +++-- + arch/arm/mach-davinci/cpuidle.c | 9 ++-- + arch/arm/mach-exynos4/cpuidle.c | 7 +-- + arch/arm/mach-kirkwood/cpuidle.c | 12 ++++-- + arch/arm/mach-omap2/cpuidle34xx.c | 67 +++++++++++++++++------------ + arch/sh/kernel/cpu/shmobile/cpuidle.c | 12 +++--- + drivers/acpi/processor_idle.c | 75 +++++++++++++++++++++------------ + drivers/cpuidle/cpuidle.c | 32 +++++++------- + drivers/cpuidle/governors/ladder.c | 13 ++++++ + drivers/cpuidle/governors/menu.c | 7 ++- + drivers/idle/intel_idle.c | 12 ++++-- + include/linux/cpuidle.h | 7 ++- + 12 files changed, 164 insertions(+), 99 deletions(-) + +diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c +index f474272..d76a600 100644 +--- a/arch/arm/mach-at91/cpuidle.c ++++ b/arch/arm/mach-at91/cpuidle.c +@@ -34,7 +34,7 @@ static struct cpuidle_driver at91_idle_driver = { + + /* Actual code that puts the SoC in different idle states */ + static int at91_enter_idle(struct cpuidle_device *dev, +- struct cpuidle_state *state) ++ int index) + { + struct timeval before, after; + int idle_time; +@@ -42,10 +42,10 @@ static int at91_enter_idle(struct cpuidle_device *dev, + + local_irq_disable(); + do_gettimeofday(&before); +- if (state == &dev->states[0]) ++ if (index == 0) + /* Wait for interrupt state */ + cpu_do_idle(); +- else if (state == &dev->states[1]) { ++ else if (index == 1) { + asm("b 1f; .align 5; 1:"); + asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ + saved_lpr = sdram_selfrefresh_enable(); +@@ -56,7 +56,9 @@ static int at91_enter_idle(struct cpuidle_device *dev, + local_irq_enable(); + idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + (after.tv_usec - before.tv_usec); +- return idle_time; ++ ++ dev->last_residency = idle_time; ++ return index; + } + + /* Initialize CPU idle by registering the idle states */ +diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c +index 85cc399..ab9a9e4 100644 +--- a/arch/arm/mach-davinci/cpuidle.c ++++ b/arch/arm/mach-davinci/cpuidle.c +@@ -79,9 +79,9 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = { + + /* Actual code that puts the SoC in different idle states */ + static int davinci_enter_idle(struct cpuidle_device *dev, +- struct cpuidle_state *state) ++ int index) + { +- struct davinci_ops *ops = cpuidle_get_statedata(state); ++ struct davinci_ops *ops = cpuidle_get_statedata(&dev->states[index]); + struct timeval before, after; + int idle_time; + +@@ -99,7 +99,10 @@ static int davinci_enter_idle(struct cpuidle_device *dev, + local_irq_enable(); + idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + (after.tv_usec - before.tv_usec); +- return idle_time; ++ ++ dev->last_residency = idle_time; ++ ++ return index; + } + + static int __init davinci_cpuidle_probe(struct platform_device *pdev) +diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos4/cpuidle.c +index bf7e96f..ea026e7 100644 +--- a/arch/arm/mach-exynos4/cpuidle.c ++++ b/arch/arm/mach-exynos4/cpuidle.c +@@ -16,7 +16,7 @@ + #include <asm/proc-fns.h> + + static int exynos4_enter_idle(struct cpuidle_device *dev, +- struct cpuidle_state *state); ++ int index); + + static struct cpuidle_state exynos4_cpuidle_set[] = { + [0] = { +@@ -37,7 +37,7 @@ static struct cpuidle_driver exynos4_idle_driver = { + }; + + static int exynos4_enter_idle(struct cpuidle_device *dev, +- struct cpuidle_state *state) ++ int index) + { + struct timeval before, after; + int idle_time; +@@ -52,7 +52,8 @@ static int exynos4_enter_idle(struct cpuidle_device *dev, + idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + (after.tv_usec - before.tv_usec); + +- return idle_time; ++ dev->last_residency = idle_time; ++ return index; + } + + static int __init exynos4_init_cpuidle(void) +diff --git a/arch/arm/mach-kirkwood/cpuidle.c b/arch/arm/mach-kirkwood/cpuidle.c +index 864e569..53d6049 100644 +--- a/arch/arm/mach-kirkwood/cpuidle.c ++++ b/arch/arm/mach-kirkwood/cpuidle.c +@@ -33,17 +33,17 @@ static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device); + + /* Actual code that puts the SoC in different idle states */ + static int kirkwood_enter_idle(struct cpuidle_device *dev, +- struct cpuidle_state *state) ++ int index) + { + struct timeval before, after; + int idle_time; + + local_irq_disable(); + do_gettimeofday(&before); +- if (state == &dev->states[0]) ++ if (index == 0) + /* Wait for interrupt state */ + cpu_do_idle(); +- else if (state == &dev->states[1]) { ++ else if (index == 1) { + /* + * Following write will put DDR in self refresh. + * Note that we have 256 cycles before DDR puts it +@@ -58,7 +58,11 @@ static int kirkwood_enter_idle(struct cpuidle_device *dev, + local_irq_enable(); + idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + (after.tv_usec - before.tv_usec); +- return idle_time; ++ ++ /* Update last residency */ ++ dev->last_residency = idle_time; ++ ++ return index; + } + + /* Initialize CPU idle by registering the idle states */ +diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c +index 4bf6e6e..58425c7 100644 +--- a/arch/arm/mach-omap2/cpuidle34xx.c ++++ b/arch/arm/mach-omap2/cpuidle34xx.c +@@ -88,17 +88,19 @@ static int _cpuidle_deny_idle(struct powerdomain *pwrdm, + /** + * omap3_enter_idle - Programs OMAP3 to enter the specified state + * @dev: cpuidle device +- * @state: The target state to be programmed ++ * @index: the index of state to be entered + * + * Called from the CPUidle framework to program the device to the + * specified target state selected by the governor. + */ + static int omap3_enter_idle(struct cpuidle_device *dev, +- struct cpuidle_state *state) ++ int index) + { +- struct omap3_idle_statedata *cx = cpuidle_get_statedata(state); ++ struct omap3_idle_statedata *cx = ++ cpuidle_get_statedata(&dev->states[index]); + struct timespec ts_preidle, ts_postidle, ts_idle; + u32 mpu_state = cx->mpu_state, core_state = cx->core_state; ++ int idle_time; + + /* Used to keep track of the total time in idle */ + getnstimeofday(&ts_preidle); +@@ -113,7 +115,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev, + goto return_sleep_time; + + /* Deny idle for C1 */ +- if (state == &dev->states[0]) { ++ if (index == 0) { + pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle); + pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); + } +@@ -122,7 +124,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev, + omap_sram_idle(); + + /* Re-allow idle for C1 */ +- if (state == &dev->states[0]) { ++ if (index == 0) { + pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); + pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle); + } +@@ -134,28 +136,35 @@ return_sleep_time: + local_irq_enable(); + local_fiq_enable(); + +- return ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * USEC_PER_SEC; ++ idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \ ++ USEC_PER_SEC; ++ ++ /* Update cpuidle counters */ ++ dev->last_residency = idle_time; ++ ++ return index; + } + + /** + * next_valid_state - Find next valid C-state + * @dev: cpuidle device +- * @state: Currently selected C-state ++ * @index: Index of currently selected c-state + * +- * If the current state is valid, it is returned back to the caller. +- * Else, this function searches for a lower c-state which is still +- * valid. ++ * If the state corresponding to index is valid, index is returned back ++ * to the caller. Else, this function searches for a lower c-state which is ++ * still valid (as defined in omap3_power_states[]) and returns its index. + * + * A state is valid if the 'valid' field is enabled and + * if it satisfies the enable_off_mode condition. + */ +-static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev, +- struct cpuidle_state *curr) ++static int next_valid_state(struct cpuidle_device *dev, ++ int index) + { +- struct cpuidle_state *next = NULL; ++ struct cpuidle_state *curr = &dev->states[index]; + struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr); + u32 mpu_deepest_state = PWRDM_POWER_RET; + u32 core_deepest_state = PWRDM_POWER_RET; ++ int next_index = -1; + + if (enable_off_mode) { + mpu_deepest_state = PWRDM_POWER_OFF; +@@ -172,20 +181,20 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev, + if ((cx->valid) && + (cx->mpu_state >= mpu_deepest_state) && + (cx->core_state >= core_deepest_state)) { +- return curr; ++ return index; + } else { + int idx = OMAP3_NUM_STATES - 1; + + /* Reach the current state starting at highest C-state */ + for (; idx >= 0; idx--) { + if (&dev->states[idx] == curr) { +- next = &dev->states[idx]; ++ next_index = idx; + break; + } + } + + /* Should never hit this condition */ +- WARN_ON(next == NULL); ++ WARN_ON(next_index == -1); + + /* + * Drop to next valid state. +@@ -197,37 +206,39 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev, + if ((cx->valid) && + (cx->mpu_state >= mpu_deepest_state) && + (cx->core_state >= core_deepest_state)) { +- next = &dev->states[idx]; ++ next_index = idx; + break; + } + } + /* + * C1 is always valid. +- * So, no need to check for 'next==NULL' outside this loop. ++ * So, no need to check for 'next_index == -1' outside ++ * this loop. + */ + } + +- return next; ++ return next_index; + } + + /** + * omap3_enter_idle_bm - Checks for any bus activity + * @dev: cpuidle device +- * @state: The target state to be programmed ++ * @index: array index of target state to be programmed + * + * This function checks for any pending activity and then programs + * the device to the specified or a safer state. + */ + static int omap3_enter_idle_bm(struct cpuidle_device *dev, +- struct cpuidle_state *state) ++ int index) + { +- struct cpuidle_state *new_state; ++ struct cpuidle_state *state = &dev->states[index]; ++ int new_state_idx; + u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state; + struct omap3_idle_statedata *cx; + int ret; + + if (!omap3_can_sleep()) { +- new_state = dev->safe_state; ++ new_state_idx = dev->safe_state_index; + goto select_state; + } + +@@ -237,7 +248,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, + */ + cam_state = pwrdm_read_pwrst(cam_pd); + if (cam_state == PWRDM_POWER_ON) { +- new_state = dev->safe_state; ++ new_state_idx = dev->safe_state_index; + goto select_state; + } + +@@ -264,11 +275,10 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, + if (per_next_state != per_saved_state) + pwrdm_set_next_pwrst(per_pd, per_next_state); + +- new_state = next_valid_state(dev, state); ++ new_state_idx = next_valid_state(dev, index); + + select_state: +- dev->last_state = new_state; +- ret = omap3_enter_idle(dev, new_state); ++ ret = omap3_enter_idle(dev, new_state_idx); + + /* Restore original PER state if it was modified */ + if (per_next_state != per_saved_state) +@@ -339,11 +349,12 @@ int __init omap3_idle_init(void) + + cpuidle_register_driver(&omap3_idle_driver); + dev = &per_cpu(omap3_idle_dev, smp_processor_id()); ++ dev->safe_state_index = -1; + + /* C1 . MPU WFI + Core active */ + cx = _fill_cstate(dev, 0, "MPU ON + CORE ON"); + (&dev->states[0])->enter = omap3_enter_idle; +- dev->safe_state = &dev->states[0]; ++ dev->safe_state_index = 0; + cx->valid = 1; /* C1 is always valid */ + cx->mpu_state = PWRDM_POWER_ON; + cx->core_state = PWRDM_POWER_ON; +diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c +index e4469e72..7be50d4c 100644 +--- a/arch/sh/kernel/cpu/shmobile/cpuidle.c ++++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c +@@ -25,11 +25,11 @@ static unsigned long cpuidle_mode[] = { + }; + + static int cpuidle_sleep_enter(struct cpuidle_device *dev, +- struct cpuidle_state *state) ++ int index) + { + unsigned long allowed_mode = arch_hwblk_sleep_mode(); + ktime_t before, after; +- int requested_state = state - &dev->states[0]; ++ int requested_state = index; + int allowed_state; + int k; + +@@ -46,11 +46,13 @@ static int cpuidle_sleep_enter(struct cpuidle_device *dev, + */ + k = min_t(int, allowed_state, requested_state); + +- dev->last_state = &dev->states[k]; + before = ktime_get(); + sh_mobile_call_standby(cpuidle_mode[k]); + after = ktime_get(); +- return ktime_to_ns(ktime_sub(after, before)) >> 10; ++ ++ dev->last_residency = (int)ktime_to_ns(ktime_sub(after, before)) >> 10; ++ ++ return k; + } + + static struct cpuidle_device cpuidle_dev; +@@ -84,7 +86,7 @@ void sh_mobile_setup_cpuidle(void) + state->flags |= CPUIDLE_FLAG_TIME_VALID; + state->enter = cpuidle_sleep_enter; + +- dev->safe_state = state; ++ dev->safe_state_index = i-1; + + if (sh_mobile_sleep_supported & SUSP_SH_SF) { + state = &dev->states[i++]; +diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c +index 2e69e09..6be70bf 100644 +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -741,22 +741,24 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) + /** + * acpi_idle_enter_c1 - enters an ACPI C1 state-type + * @dev: the target CPU +- * @state: the state data ++ * @index: index of target state + * + * This is equivalent to the HALT instruction. + */ + static int acpi_idle_enter_c1(struct cpuidle_device *dev, +- struct cpuidle_state *state) ++ int index) + { + ktime_t kt1, kt2; + s64 idle_time; + struct acpi_processor *pr; ++ struct cpuidle_state *state = &dev->states[index]; + struct acpi_processor_cx *cx = cpuidle_get_statedata(state); + + pr = __this_cpu_read(processors); ++ dev->last_residency = 0; + + if (unlikely(!pr)) +- return 0; ++ return -EINVAL; + + local_irq_disable(); + +@@ -764,7 +766,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, + if (acpi_idle_suspend) { + local_irq_enable(); + cpu_relax(); +- return 0; ++ return -EINVAL; + } + + lapic_timer_state_broadcast(pr, cx, 1); +@@ -773,37 +775,46 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, + kt2 = ktime_get_real(); + idle_time = ktime_to_us(ktime_sub(kt2, kt1)); + ++ /* Update device last_residency*/ ++ dev->last_residency = (int)idle_time; ++ + local_irq_enable(); + cx->usage++; + lapic_timer_state_broadcast(pr, cx, 0); + +- return idle_time; ++ return index; + } + + /** + * acpi_idle_enter_simple - enters an ACPI state without BM handling + * @dev: the target CPU +- * @state: the state data ++ * @index: the index of suggested state + */ + static int acpi_idle_enter_simple(struct cpuidle_device *dev, +- struct cpuidle_state *state) ++ int index) + { + struct acpi_processor *pr; ++ struct cpuidle_state *state = &dev->states[index]; + struct acpi_processor_cx *cx = cpuidle_get_statedata(state); + ktime_t kt1, kt2; + s64 idle_time_ns; + s64 idle_time; + + pr = __this_cpu_read(processors); ++ dev->last_residency = 0; + + if (unlikely(!pr)) +- return 0; +- +- if (acpi_idle_suspend) +- return(acpi_idle_enter_c1(dev, state)); ++ return -EINVAL; + + local_irq_disable(); + ++ if (acpi_idle_suspend) { ++ local_irq_enable(); ++ cpu_relax(); ++ return -EINVAL; ++ } ++ ++ + if (cx->entry_method != ACPI_CSTATE_FFH) { + current_thread_info()->status &= ~TS_POLLING; + /* +@@ -815,7 +826,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, + if (unlikely(need_resched())) { + current_thread_info()->status |= TS_POLLING; + local_irq_enable(); +- return 0; ++ return -EINVAL; + } + } + +@@ -837,6 +848,9 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, + idle_time = idle_time_ns; + do_div(idle_time, NSEC_PER_USEC); + ++ /* Update device last_residency*/ ++ dev->last_residency = (int)idle_time; ++ + /* Tell the scheduler how much we idled: */ + sched_clock_idle_wakeup_event(idle_time_ns); + +@@ -848,7 +862,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, + + lapic_timer_state_broadcast(pr, cx, 0); + cx->time += idle_time; +- return idle_time; ++ return index; + } + + static int c3_cpu_count; +@@ -857,14 +871,15 @@ static DEFINE_SPINLOCK(c3_lock); + /** + * acpi_idle_enter_bm - enters C3 with proper BM handling + * @dev: the target CPU +- * @state: the state data ++ * @index: the index of suggested state + * + * If BM is detected, the deepest non-C3 idle state is entered instead. + */ + static int acpi_idle_enter_bm(struct cpuidle_device *dev, +- struct cpuidle_state *state) ++ int index) + { + struct acpi_processor *pr; ++ struct cpuidle_state *state = &dev->states[index]; + struct acpi_processor_cx *cx = cpuidle_get_statedata(state); + ktime_t kt1, kt2; + s64 idle_time_ns; +@@ -872,22 +887,26 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, + + + pr = __this_cpu_read(processors); ++ dev->last_residency = 0; + + if (unlikely(!pr)) +- return 0; ++ return -EINVAL; + +- if (acpi_idle_suspend) +- return(acpi_idle_enter_c1(dev, state)); ++ ++ if (acpi_idle_suspend) { ++ cpu_relax(); ++ return -EINVAL; ++ } + + if (!cx->bm_sts_skip && acpi_idle_bm_check()) { +- if (dev->safe_state) { +- dev->last_state = dev->safe_state; +- return dev->safe_state->enter(dev, dev->safe_state); ++ if (dev->safe_state_index >= 0) { ++ return dev->states[dev->safe_state_index].enter(dev, ++ dev->safe_state_index); + } else { + local_irq_disable(); + acpi_safe_halt(); + local_irq_enable(); +- return 0; ++ return -EINVAL; + } + } + +@@ -904,7 +923,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, + if (unlikely(need_resched())) { + current_thread_info()->status |= TS_POLLING; + local_irq_enable(); +- return 0; ++ return -EINVAL; + } + } + +@@ -954,6 +973,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, + idle_time = idle_time_ns; + do_div(idle_time, NSEC_PER_USEC); + ++ /* Update device last_residency*/ ++ dev->last_residency = (int)idle_time; ++ + /* Tell the scheduler how much we idled: */ + sched_clock_idle_wakeup_event(idle_time_ns); + +@@ -965,7 +987,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, + + lapic_timer_state_broadcast(pr, cx, 0); + cx->time += idle_time; +- return idle_time; ++ return index; + } + + struct cpuidle_driver acpi_idle_driver = { +@@ -992,6 +1014,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) + } + + dev->cpu = pr->id; ++ dev->safe_state_index = -1; + for (i = 0; i < CPUIDLE_STATE_MAX; i++) { + dev->states[i].name[0] = '\0'; + dev->states[i].desc[0] = '\0'; +@@ -1027,13 +1050,13 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) + state->flags |= CPUIDLE_FLAG_TIME_VALID; + + state->enter = acpi_idle_enter_c1; +- dev->safe_state = state; ++ dev->safe_state_index = count; + break; + + case ACPI_STATE_C2: + state->flags |= CPUIDLE_FLAG_TIME_VALID; + state->enter = acpi_idle_enter_simple; +- dev->safe_state = state; ++ dev->safe_state_index = count; + break; + + case ACPI_STATE_C3: +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index becd6d9..c0f1a3a 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -63,7 +63,7 @@ int cpuidle_idle_call(void) + { + struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); + struct cpuidle_state *target_state; +- int next_state; ++ int next_state, entered_state; + + if (off) + return -ENODEV; +@@ -103,26 +103,27 @@ int cpuidle_idle_call(void) + + target_state = &dev->states[next_state]; + +- /* enter the state and update stats */ +- dev->last_state = target_state; +- + trace_power_start(POWER_CSTATE, next_state, dev->cpu); + trace_cpu_idle(next_state, dev->cpu); + +- dev->last_residency = target_state->enter(dev, target_state); ++ entered_state = target_state->enter(dev, next_state); + + trace_power_end(dev->cpu); + trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu); + +- if (dev->last_state) +- target_state = dev->last_state; +- +- target_state->time += (unsigned long long)dev->last_residency; +- target_state->usage++; ++ if (entered_state >= 0) { ++ /* Update cpuidle counters */ ++ /* This can be moved to within driver enter routine ++ * but that results in multiple copies of same code. ++ */ ++ dev->states[entered_state].time += ++ (unsigned long long)dev->last_residency; ++ dev->states[entered_state].usage++; ++ } + + /* give the governor an opportunity to reflect on the outcome */ + if (cpuidle_curr_governor->reflect) +- cpuidle_curr_governor->reflect(dev); ++ cpuidle_curr_governor->reflect(dev, entered_state); + + return 0; + } +@@ -173,11 +174,10 @@ void cpuidle_resume_and_unlock(void) + EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); + + #ifdef CONFIG_ARCH_HAS_CPU_RELAX +-static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st) ++static int poll_idle(struct cpuidle_device *dev, int index) + { + ktime_t t1, t2; + s64 diff; +- int ret; + + t1 = ktime_get(); + local_irq_enable(); +@@ -189,8 +189,9 @@ static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st) + if (diff > INT_MAX) + diff = INT_MAX; + +- ret = (int) diff; +- return ret; ++ dev->last_residency = (int) diff; ++ ++ return index; + } + + static void poll_idle_init(struct cpuidle_device *dev) +@@ -249,7 +250,6 @@ int cpuidle_enable_device(struct cpuidle_device *dev) + dev->states[i].time = 0; + } + dev->last_residency = 0; +- dev->last_state = NULL; + + smp_wmb(); + +diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c +index f62fde2..78b06d2 100644 +--- a/drivers/cpuidle/governors/ladder.c ++++ b/drivers/cpuidle/governors/ladder.c +@@ -153,11 +153,24 @@ static int ladder_enable_device(struct cpuidle_device *dev) + return 0; + } + ++/** ++ * ladder_reflect - update the correct last_state_idx ++ * @dev: the CPU ++ * @index: the index of actual state entered ++ */ ++static void ladder_reflect(struct cpuidle_device *dev, int index) ++{ ++ struct ladder_device *ldev = &__get_cpu_var(ladder_devices); ++ if (index > 0) ++ ldev->last_state_idx = index; ++} ++ + static struct cpuidle_governor ladder_governor = { + .name = "ladder", + .rating = 10, + .enable = ladder_enable_device, + .select = ladder_select_state, ++ .reflect = ladder_reflect, + .owner = THIS_MODULE, + }; + +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index 0027524..e27a2af 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -311,14 +311,17 @@ static int menu_select(struct cpuidle_device *dev) + /** + * menu_reflect - records that data structures need update + * @dev: the CPU ++ * @index: the index of actual entered state + * + * NOTE: it's important to be fast here because this operation will add to + * the overall exit latency. + */ +-static void menu_reflect(struct cpuidle_device *dev) ++static void menu_reflect(struct cpuidle_device *dev, int index) + { + struct menu_device *data = &__get_cpu_var(menu_devices); +- data->needs_update = 1; ++ data->last_state_idx = index; ++ if (index >= 0) ++ data->needs_update = 1; + } + + /** +diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c +index 026f9aa..8f056e1 100644 +--- a/drivers/idle/intel_idle.c ++++ b/drivers/idle/intel_idle.c +@@ -81,7 +81,7 @@ static unsigned int mwait_substates; + static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */ + + static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; +-static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); ++static int intel_idle(struct cpuidle_device *dev, int index); + + static struct cpuidle_state *cpuidle_state_table; + +@@ -209,12 +209,13 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { + /** + * intel_idle + * @dev: cpuidle_device +- * @state: cpuidle state ++ * @index: index of cpuidle state + * + */ +-static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state) ++static int intel_idle(struct cpuidle_device *dev, int index) + { + unsigned long ecx = 1; /* break on interrupt flag */ ++ struct cpuidle_state *state = &dev->states[index]; + unsigned long eax = (unsigned long)cpuidle_get_statedata(state); + unsigned int cstate; + ktime_t kt_before, kt_after; +@@ -256,7 +257,10 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state) + if (!(lapic_timer_reliable_states & (1 << (cstate)))) + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); + +- return usec_delta; ++ /* Update cpuidle counters */ ++ dev->last_residency = (int)usec_delta; ++ ++ return index; + } + + static void __setup_broadcast_timer(void *arg) +diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h +index b51629e..8da811b 100644 +--- a/include/linux/cpuidle.h ++++ b/include/linux/cpuidle.h +@@ -42,7 +42,7 @@ struct cpuidle_state { + unsigned long long time; /* in US */ + + int (*enter) (struct cpuidle_device *dev, +- struct cpuidle_state *state); ++ int index); + }; + + /* Idle State Flags */ +@@ -87,13 +87,12 @@ struct cpuidle_device { + int state_count; + struct cpuidle_state states[CPUIDLE_STATE_MAX]; + struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; +- struct cpuidle_state *last_state; + + struct list_head device_list; + struct kobject kobj; + struct completion kobj_unregister; + void *governor_data; +- struct cpuidle_state *safe_state; ++ int safe_state_index; + + int (*prepare) (struct cpuidle_device *dev); + }; +@@ -169,7 +168,7 @@ struct cpuidle_governor { + void (*disable) (struct cpuidle_device *dev); + + int (*select) (struct cpuidle_device *dev); +- void (*reflect) (struct cpuidle_device *dev); ++ void (*reflect) (struct cpuidle_device *dev, int index); + + struct module *owner; + }; +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0043-cpuidle-Remove-CPUIDLE_FLAG_IGNORE-and-dev-prepare.patch b/patches.kzm9g/0043-cpuidle-Remove-CPUIDLE_FLAG_IGNORE-and-dev-prepare.patch new file mode 100644 index 00000000000000..549d142a86ca94 --- /dev/null +++ b/patches.kzm9g/0043-cpuidle-Remove-CPUIDLE_FLAG_IGNORE-and-dev-prepare.patch @@ -0,0 +1,89 @@ +From bdf8107f9e58c5563946d7cb46e1bed307ce2653 Mon Sep 17 00:00:00 2001 +From: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> +Date: Fri, 28 Oct 2011 16:20:24 +0530 +Subject: cpuidle: Remove CPUIDLE_FLAG_IGNORE and dev->prepare() + +The cpuidle_device->prepare() mechanism causes updates to the +cpuidle_state[].flags, setting and clearing CPUIDLE_FLAG_IGNORE +to tell the governor not to chose a state on a per-cpu basis at +run-time. State demotion is now handled by the driver and it returns +the actual state entered. Hence, this mechanism is not required. +Also this removes per-cpu flags from cpuidle_state enabling +it to be made global. + +Reference: +https://lkml.org/lkml/2011/3/25/52 + +Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm> +Signed-off-by: Trinabh Gupta <g.trinabh@gmail.com> +Tested-by: Jean Pihet <j-pihet@ti.com> +Acked-by: Arjan van de Ven <arjan@linux.intel.com> +Reviewed-by: Kevin Hilman <khilman@ti.com> +Signed-off-by: Len Brown <len.brown@intel.com> +(cherry picked from commit b25edc42bfb9602f0503474b2c94701d5536ce60) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/cpuidle/cpuidle.c | 10 ---------- + drivers/cpuidle/governors/menu.c | 2 -- + include/linux/cpuidle.h | 3 --- + 3 files changed, 15 deletions(-) + +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index c0f1a3a..70350d2 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -84,16 +84,6 @@ int cpuidle_idle_call(void) + hrtimer_peek_ahead_timers(); + #endif + +- /* +- * Call the device's prepare function before calling the +- * governor's select function. ->prepare gives the device's +- * cpuidle driver a chance to update any dynamic information +- * of its cpuidle states for the current idle period, e.g. +- * state availability, latencies, residencies, etc. +- */ +- if (dev->prepare) +- dev->prepare(dev); +- + /* ask the governor for the next state */ + next_state = cpuidle_curr_governor->select(dev); + if (need_resched()) { +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index e27a2af..2072aeb 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -289,8 +289,6 @@ static int menu_select(struct cpuidle_device *dev) + for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++) { + struct cpuidle_state *s = &dev->states[i]; + +- if (s->flags & CPUIDLE_FLAG_IGNORE) +- continue; + if (s->target_residency > data->predicted_us) + continue; + if (s->exit_latency > latency_req) +diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h +index 8da811b..c6d85cf 100644 +--- a/include/linux/cpuidle.h ++++ b/include/linux/cpuidle.h +@@ -47,7 +47,6 @@ struct cpuidle_state { + + /* Idle State Flags */ + #define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */ +-#define CPUIDLE_FLAG_IGNORE (0x100) /* ignore during this idle period */ + + #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) + +@@ -93,8 +92,6 @@ struct cpuidle_device { + struct completion kobj_unregister; + void *governor_data; + int safe_state_index; +- +- int (*prepare) (struct cpuidle_device *dev); + }; + + DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices); +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0044-cpuidle-Split-cpuidle_state-structure-and-move-per-c.patch b/patches.kzm9g/0044-cpuidle-Split-cpuidle_state-structure-and-move-per-c.patch new file mode 100644 index 00000000000000..d41a55c17819b7 --- /dev/null +++ b/patches.kzm9g/0044-cpuidle-Split-cpuidle_state-structure-and-move-per-c.patch @@ -0,0 +1,531 @@ +From f3127a05382f54ff79a80cddcabc22ffdfb510e0 Mon Sep 17 00:00:00 2001 +From: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> +Date: Fri, 28 Oct 2011 16:20:33 +0530 +Subject: cpuidle: Split cpuidle_state structure and move per-cpu statistics + fields + +This is the first step towards global registration of cpuidle +states. The statistics used primarily by the governor are per-cpu +and have to be split from rest of the fields inside cpuidle_state, +which would be made global i.e. single copy. The driver_data field +is also per-cpu and moved. + +Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> +Signed-off-by: Trinabh Gupta <g.trinabh@gmail.com> +Tested-by: Jean Pihet <j-pihet@ti.com> +Reviewed-by: Kevin Hilman <khilman@ti.com> +Acked-by: Arjan van de Ven <arjan@linux.intel.com> +Acked-by: Kevin Hilman <khilman@ti.com> +Signed-off-by: Len Brown <len.brown@intel.com> +(cherry picked from commit 4202735e8ab6ecfb0381631a0d0b58fefe0bd4e2) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/mach-davinci/cpuidle.c | 5 ++-- + arch/arm/mach-omap2/cpuidle34xx.c | 13 ++++++----- + drivers/acpi/processor_idle.c | 25 ++++++++++---------- + drivers/cpuidle/cpuidle.c | 11 +++++---- + drivers/cpuidle/sysfs.c | 19 ++++++++++----- + drivers/idle/intel_idle.c | 46 +++++++++++++++++++++++++++---------- + include/linux/cpuidle.h | 25 ++++++++++++-------- + 7 files changed, 90 insertions(+), 54 deletions(-) + +diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c +index ab9a9e4..dda6d2f 100644 +--- a/arch/arm/mach-davinci/cpuidle.c ++++ b/arch/arm/mach-davinci/cpuidle.c +@@ -81,7 +81,8 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = { + static int davinci_enter_idle(struct cpuidle_device *dev, + int index) + { +- struct davinci_ops *ops = cpuidle_get_statedata(&dev->states[index]); ++ struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; ++ struct davinci_ops *ops = cpuidle_get_statedata(state_usage); + struct timeval before, after; + int idle_time; + +@@ -143,7 +144,7 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev) + strcpy(device->states[1].desc, "WFI and DDR Self Refresh"); + if (pdata->ddr2_pdown) + davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN; +- cpuidle_set_statedata(&device->states[1], &davinci_states[1]); ++ cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]); + + device->state_count = DAVINCI_CPUIDLE_MAX_STATES; + +diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c +index 58425c7..d3fce7b 100644 +--- a/arch/arm/mach-omap2/cpuidle34xx.c ++++ b/arch/arm/mach-omap2/cpuidle34xx.c +@@ -97,7 +97,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev, + int index) + { + struct omap3_idle_statedata *cx = +- cpuidle_get_statedata(&dev->states[index]); ++ cpuidle_get_statedata(&dev->states_usage[index]); + struct timespec ts_preidle, ts_postidle, ts_idle; + u32 mpu_state = cx->mpu_state, core_state = cx->core_state; + int idle_time; +@@ -160,8 +160,9 @@ return_sleep_time: + static int next_valid_state(struct cpuidle_device *dev, + int index) + { ++ struct cpuidle_state_usage *curr_usage = &dev->states_usage[index]; + struct cpuidle_state *curr = &dev->states[index]; +- struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr); ++ struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage); + u32 mpu_deepest_state = PWRDM_POWER_RET; + u32 core_deepest_state = PWRDM_POWER_RET; + int next_index = -1; +@@ -202,7 +203,7 @@ static int next_valid_state(struct cpuidle_device *dev, + */ + idx--; + for (; idx >= 0; idx--) { +- cx = cpuidle_get_statedata(&dev->states[idx]); ++ cx = cpuidle_get_statedata(&dev->states_usage[idx]); + if ((cx->valid) && + (cx->mpu_state >= mpu_deepest_state) && + (cx->core_state >= core_deepest_state)) { +@@ -231,7 +232,6 @@ static int next_valid_state(struct cpuidle_device *dev, + static int omap3_enter_idle_bm(struct cpuidle_device *dev, + int index) + { +- struct cpuidle_state *state = &dev->states[index]; + int new_state_idx; + u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state; + struct omap3_idle_statedata *cx; +@@ -264,7 +264,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, + * Prevent PER off if CORE is not in retention or off as this + * would disable PER wakeups completely. + */ +- cx = cpuidle_get_statedata(state); ++ cx = cpuidle_get_statedata(&dev->states_usage[index]); + core_next_state = cx->core_state; + per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); + if ((per_next_state == PWRDM_POWER_OFF) && +@@ -318,6 +318,7 @@ static inline struct omap3_idle_statedata *_fill_cstate( + { + struct omap3_idle_statedata *cx = &omap3_idle_data[idx]; + struct cpuidle_state *state = &dev->states[idx]; ++ struct cpuidle_state_usage *state_usage = &dev->states_usage[idx]; + + state->exit_latency = cpuidle_params_table[idx].exit_latency; + state->target_residency = cpuidle_params_table[idx].target_residency; +@@ -326,7 +327,7 @@ static inline struct omap3_idle_statedata *_fill_cstate( + cx->valid = cpuidle_params_table[idx].valid; + sprintf(state->name, "C%d", idx + 1); + strncpy(state->desc, descr, CPUIDLE_DESC_LEN); +- cpuidle_set_statedata(state, cx); ++ cpuidle_set_statedata(state_usage, cx); + + return cx; + } +diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c +index 6be70bf..c7b89f0 100644 +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -745,14 +745,13 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) + * + * This is equivalent to the HALT instruction. + */ +-static int acpi_idle_enter_c1(struct cpuidle_device *dev, +- int index) ++static int acpi_idle_enter_c1(struct cpuidle_device *dev, int index) + { + ktime_t kt1, kt2; + s64 idle_time; + struct acpi_processor *pr; +- struct cpuidle_state *state = &dev->states[index]; +- struct acpi_processor_cx *cx = cpuidle_get_statedata(state); ++ struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; ++ struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage); + + pr = __this_cpu_read(processors); + dev->last_residency = 0; +@@ -790,12 +789,11 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, + * @dev: the target CPU + * @index: the index of suggested state + */ +-static int acpi_idle_enter_simple(struct cpuidle_device *dev, +- int index) ++static int acpi_idle_enter_simple(struct cpuidle_device *dev, int index) + { + struct acpi_processor *pr; +- struct cpuidle_state *state = &dev->states[index]; +- struct acpi_processor_cx *cx = cpuidle_get_statedata(state); ++ struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; ++ struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage); + ktime_t kt1, kt2; + s64 idle_time_ns; + s64 idle_time; +@@ -875,12 +873,11 @@ static DEFINE_SPINLOCK(c3_lock); + * + * If BM is detected, the deepest non-C3 idle state is entered instead. + */ +-static int acpi_idle_enter_bm(struct cpuidle_device *dev, +- int index) ++static int acpi_idle_enter_bm(struct cpuidle_device *dev, int index) + { + struct acpi_processor *pr; +- struct cpuidle_state *state = &dev->states[index]; +- struct acpi_processor_cx *cx = cpuidle_get_statedata(state); ++ struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; ++ struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage); + ktime_t kt1, kt2; + s64 idle_time_ns; + s64 idle_time; +@@ -1004,6 +1001,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) + int i, count = CPUIDLE_DRIVER_STATE_START; + struct acpi_processor_cx *cx; + struct cpuidle_state *state; ++ struct cpuidle_state_usage *state_usage; + struct cpuidle_device *dev = &pr->power.dev; + + if (!pr->flags.power_setup_done) +@@ -1026,6 +1024,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) + for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { + cx = &pr->power.states[i]; + state = &dev->states[count]; ++ state_usage = &dev->states_usage[count]; + + if (!cx->valid) + continue; +@@ -1036,7 +1035,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) + !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) + continue; + #endif +- cpuidle_set_statedata(state, cx); ++ cpuidle_set_statedata(state_usage, cx); + + snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); + strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index 70350d2..219a757 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -106,9 +106,9 @@ int cpuidle_idle_call(void) + /* This can be moved to within driver enter routine + * but that results in multiple copies of same code. + */ +- dev->states[entered_state].time += ++ dev->states_usage[entered_state].time += + (unsigned long long)dev->last_residency; +- dev->states[entered_state].usage++; ++ dev->states_usage[entered_state].usage++; + } + + /* give the governor an opportunity to reflect on the outcome */ +@@ -187,8 +187,9 @@ static int poll_idle(struct cpuidle_device *dev, int index) + static void poll_idle_init(struct cpuidle_device *dev) + { + struct cpuidle_state *state = &dev->states[0]; ++ struct cpuidle_state_usage *state_usage = &dev->states_usage[0]; + +- cpuidle_set_statedata(state, NULL); ++ cpuidle_set_statedata(state_usage, NULL); + + snprintf(state->name, CPUIDLE_NAME_LEN, "POLL"); + snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); +@@ -236,8 +237,8 @@ int cpuidle_enable_device(struct cpuidle_device *dev) + goto fail_sysfs; + + for (i = 0; i < dev->state_count; i++) { +- dev->states[i].usage = 0; +- dev->states[i].time = 0; ++ dev->states_usage[i].usage = 0; ++ dev->states_usage[i].time = 0; + } + dev->last_residency = 0; + +diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c +index be7917ec..8a1ace1 100644 +--- a/drivers/cpuidle/sysfs.c ++++ b/drivers/cpuidle/sysfs.c +@@ -216,7 +216,8 @@ static struct kobj_type ktype_cpuidle = { + + struct cpuidle_state_attr { + struct attribute attr; +- ssize_t (*show)(struct cpuidle_state *, char *); ++ ssize_t (*show)(struct cpuidle_state *, \ ++ struct cpuidle_state_usage *, char *); + ssize_t (*store)(struct cpuidle_state *, const char *, size_t); + }; + +@@ -224,19 +225,22 @@ struct cpuidle_state_attr { + static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL) + + #define define_show_state_function(_name) \ +-static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \ ++static ssize_t show_state_##_name(struct cpuidle_state *state, \ ++ struct cpuidle_state_usage *state_usage, char *buf) \ + { \ + return sprintf(buf, "%u\n", state->_name);\ + } + + #define define_show_state_ull_function(_name) \ +-static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \ ++static ssize_t show_state_##_name(struct cpuidle_state *state, \ ++ struct cpuidle_state_usage *state_usage, char *buf) \ + { \ +- return sprintf(buf, "%llu\n", state->_name);\ ++ return sprintf(buf, "%llu\n", state_usage->_name);\ + } + + #define define_show_state_str_function(_name) \ +-static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \ ++static ssize_t show_state_##_name(struct cpuidle_state *state, \ ++ struct cpuidle_state_usage *state_usage, char *buf) \ + { \ + if (state->_name[0] == '\0')\ + return sprintf(buf, "<null>\n");\ +@@ -269,16 +273,18 @@ static struct attribute *cpuidle_state_default_attrs[] = { + + #define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj) + #define kobj_to_state(k) (kobj_to_state_obj(k)->state) ++#define kobj_to_state_usage(k) (kobj_to_state_obj(k)->state_usage) + #define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr) + static ssize_t cpuidle_state_show(struct kobject * kobj, + struct attribute * attr ,char * buf) + { + int ret = -EIO; + struct cpuidle_state *state = kobj_to_state(kobj); ++ struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj); + struct cpuidle_state_attr * cattr = attr_to_stateattr(attr); + + if (cattr->show) +- ret = cattr->show(state, buf); ++ ret = cattr->show(state, state_usage, buf); + + return ret; + } +@@ -323,6 +329,7 @@ int cpuidle_add_state_sysfs(struct cpuidle_device *device) + if (!kobj) + goto error_state; + kobj->state = &device->states[i]; ++ kobj->state_usage = &device->states_usage[i]; + init_completion(&kobj->kobj_unregister); + + ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle, &device->kobj, +diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c +index 8f056e1..b0c63e9 100644 +--- a/drivers/idle/intel_idle.c ++++ b/drivers/idle/intel_idle.c +@@ -109,7 +109,6 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C1 */ + .name = "C1-NHM", + .desc = "MWAIT 0x00", +- .driver_data = (void *) 0x00, + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 3, + .target_residency = 6, +@@ -117,7 +116,6 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C2 */ + .name = "C3-NHM", + .desc = "MWAIT 0x10", +- .driver_data = (void *) 0x10, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 20, + .target_residency = 80, +@@ -125,7 +123,6 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C3 */ + .name = "C6-NHM", + .desc = "MWAIT 0x20", +- .driver_data = (void *) 0x20, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 200, + .target_residency = 800, +@@ -137,7 +134,6 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C1 */ + .name = "C1-SNB", + .desc = "MWAIT 0x00", +- .driver_data = (void *) 0x00, + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 1, + .target_residency = 1, +@@ -145,7 +141,6 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C2 */ + .name = "C3-SNB", + .desc = "MWAIT 0x10", +- .driver_data = (void *) 0x10, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 80, + .target_residency = 211, +@@ -153,7 +148,6 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C3 */ + .name = "C6-SNB", + .desc = "MWAIT 0x20", +- .driver_data = (void *) 0x20, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 104, + .target_residency = 345, +@@ -161,7 +155,6 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C4 */ + .name = "C7-SNB", + .desc = "MWAIT 0x30", +- .driver_data = (void *) 0x30, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 109, + .target_residency = 345, +@@ -173,7 +166,6 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C1 */ + .name = "C1-ATM", + .desc = "MWAIT 0x00", +- .driver_data = (void *) 0x00, + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 1, + .target_residency = 4, +@@ -181,7 +173,6 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C2 */ + .name = "C2-ATM", + .desc = "MWAIT 0x10", +- .driver_data = (void *) 0x10, + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 20, + .target_residency = 80, +@@ -190,7 +181,6 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C4 */ + .name = "C4-ATM", + .desc = "MWAIT 0x30", +- .driver_data = (void *) 0x30, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 100, + .target_residency = 400, +@@ -199,13 +189,41 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C6 */ + .name = "C6-ATM", + .desc = "MWAIT 0x52", +- .driver_data = (void *) 0x52, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 140, + .target_residency = 560, + .enter = &intel_idle }, + }; + ++static int get_driver_data(int cstate) ++{ ++ int driver_data; ++ switch (cstate) { ++ ++ case 1: /* MWAIT C1 */ ++ driver_data = 0x00; ++ break; ++ case 2: /* MWAIT C2 */ ++ driver_data = 0x10; ++ break; ++ case 3: /* MWAIT C3 */ ++ driver_data = 0x20; ++ break; ++ case 4: /* MWAIT C4 */ ++ driver_data = 0x30; ++ break; ++ case 5: /* MWAIT C5 */ ++ driver_data = 0x40; ++ break; ++ case 6: /* MWAIT C6 */ ++ driver_data = 0x52; ++ break; ++ default: ++ driver_data = 0x00; ++ } ++ return driver_data; ++} ++ + /** + * intel_idle + * @dev: cpuidle_device +@@ -216,7 +234,8 @@ static int intel_idle(struct cpuidle_device *dev, int index) + { + unsigned long ecx = 1; /* break on interrupt flag */ + struct cpuidle_state *state = &dev->states[index]; +- unsigned long eax = (unsigned long)cpuidle_get_statedata(state); ++ struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; ++ unsigned long eax = (unsigned long)cpuidle_get_statedata(state_usage); + unsigned int cstate; + ktime_t kt_before, kt_after; + s64 usec_delta; +@@ -452,6 +471,9 @@ static int intel_idle_cpuidle_devices_init(void) + dev->states[dev->state_count] = /* structure copy */ + cpuidle_state_table[cstate]; + ++ dev->states_usage[dev->state_count].driver_data = ++ (void *)get_driver_data(cstate); ++ + dev->state_count += 1; + } + +diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h +index c6d85cf..0156540 100644 +--- a/include/linux/cpuidle.h ++++ b/include/linux/cpuidle.h +@@ -28,19 +28,22 @@ struct cpuidle_device; + * CPUIDLE DEVICE INTERFACE * + ****************************/ + ++struct cpuidle_state_usage { ++ void *driver_data; ++ ++ unsigned long long usage; ++ unsigned long long time; /* in US */ ++}; ++ + struct cpuidle_state { + char name[CPUIDLE_NAME_LEN]; + char desc[CPUIDLE_DESC_LEN]; +- void *driver_data; + + unsigned int flags; + unsigned int exit_latency; /* in US */ + unsigned int power_usage; /* in mW */ + unsigned int target_residency; /* in US */ + +- unsigned long long usage; +- unsigned long long time; /* in US */ +- + int (*enter) (struct cpuidle_device *dev, + int index); + }; +@@ -52,26 +55,27 @@ struct cpuidle_state { + + /** + * cpuidle_get_statedata - retrieves private driver state data +- * @state: the state ++ * @st_usage: the state usage statistics + */ +-static inline void * cpuidle_get_statedata(struct cpuidle_state *state) ++static inline void *cpuidle_get_statedata(struct cpuidle_state_usage *st_usage) + { +- return state->driver_data; ++ return st_usage->driver_data; + } + + /** + * cpuidle_set_statedata - stores private driver state data +- * @state: the state ++ * @st_usage: the state usage statistics + * @data: the private data + */ + static inline void +-cpuidle_set_statedata(struct cpuidle_state *state, void *data) ++cpuidle_set_statedata(struct cpuidle_state_usage *st_usage, void *data) + { +- state->driver_data = data; ++ st_usage->driver_data = data; + } + + struct cpuidle_state_kobj { + struct cpuidle_state *state; ++ struct cpuidle_state_usage *state_usage; + struct completion kobj_unregister; + struct kobject kobj; + }; +@@ -85,6 +89,7 @@ struct cpuidle_device { + int last_residency; + int state_count; + struct cpuidle_state states[CPUIDLE_STATE_MAX]; ++ struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX]; + struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; + + struct list_head device_list; +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0045-cpuidle-Single-Global-registration-of-idle-states.patch b/patches.kzm9g/0045-cpuidle-Single-Global-registration-of-idle-states.patch new file mode 100644 index 00000000000000..b6aa221bd0d115 --- /dev/null +++ b/patches.kzm9g/0045-cpuidle-Single-Global-registration-of-idle-states.patch @@ -0,0 +1,1520 @@ +From a50a3085d47712f6a11024570ffc8bf6b90fb126 Mon Sep 17 00:00:00 2001 +From: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> +Date: Fri, 28 Oct 2011 16:20:42 +0530 +Subject: cpuidle: Single/Global registration of idle states + +This patch makes the cpuidle_states structure global (single copy) +instead of per-cpu. The statistics needed on per-cpu basis +by the governor are kept per-cpu. This simplifies the cpuidle +subsystem as state registration is done by single cpu only. +Having single copy of cpuidle_states saves memory. Rare case +of asymmetric C-states can be handled within the cpuidle driver +and architectures such as POWER do not have asymmetric C-states. + +Having single/global registration of all the idle states, +dynamic C-state transitions on x86 are handled by +the boot cpu. Here, the boot cpu would disable all the devices, +re-populate the states and later enable all the devices, +irrespective of the cpu that would receive the notification first. + +Reference: +https://lkml.org/lkml/2011/4/25/83 + +Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> +Signed-off-by: Trinabh Gupta <g.trinabh@gmail.com> +Tested-by: Jean Pihet <j-pihet@ti.com> +Reviewed-by: Kevin Hilman <khilman@ti.com> +Acked-by: Arjan van de Ven <arjan@linux.intel.com> +Acked-by: Kevin Hilman <khilman@ti.com> +Signed-off-by: Len Brown <len.brown@intel.com> +(cherry picked from commit 46bcfad7a819bd17ac4e831b04405152d59784ab) + +Conflicts: + + drivers/idle/intel_idle.c + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/mach-at91/cpuidle.c | 31 +++--- + arch/arm/mach-davinci/cpuidle.c | 39 +++---- + arch/arm/mach-exynos4/cpuidle.c | 23 ++-- + arch/arm/mach-kirkwood/cpuidle.c | 30 +++--- + arch/arm/mach-omap2/cpuidle34xx.c | 73 ++++++++----- + arch/sh/kernel/cpu/shmobile/cpuidle.c | 18 ++-- + drivers/acpi/processor_driver.c | 20 +--- + drivers/acpi/processor_idle.c | 191 ++++++++++++++++++++++++++++----- + drivers/cpuidle/cpuidle.c | 45 +++----- + drivers/cpuidle/driver.c | 25 +++++ + drivers/cpuidle/governors/ladder.c | 28 +++-- + drivers/cpuidle/governors/menu.c | 20 ++-- + drivers/cpuidle/sysfs.c | 3 +- + drivers/idle/intel_idle.c | 80 ++++++++++---- + include/acpi/processor.h | 1 + + include/linux/cpuidle.h | 19 ++-- + 16 files changed, 439 insertions(+), 207 deletions(-) + +diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c +index d76a600..a851e6c 100644 +--- a/arch/arm/mach-at91/cpuidle.c ++++ b/arch/arm/mach-at91/cpuidle.c +@@ -34,6 +34,7 @@ static struct cpuidle_driver at91_idle_driver = { + + /* Actual code that puts the SoC in different idle states */ + static int at91_enter_idle(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, + int index) + { + struct timeval before, after; +@@ -65,27 +66,29 @@ static int at91_enter_idle(struct cpuidle_device *dev, + static int at91_init_cpuidle(void) + { + struct cpuidle_device *device; +- +- cpuidle_register_driver(&at91_idle_driver); ++ struct cpuidle_driver *driver = &at91_idle_driver; + + device = &per_cpu(at91_cpuidle_device, smp_processor_id()); + device->state_count = AT91_MAX_STATES; ++ driver->state_count = AT91_MAX_STATES; + + /* Wait for interrupt state */ +- device->states[0].enter = at91_enter_idle; +- device->states[0].exit_latency = 1; +- device->states[0].target_residency = 10000; +- device->states[0].flags = CPUIDLE_FLAG_TIME_VALID; +- strcpy(device->states[0].name, "WFI"); +- strcpy(device->states[0].desc, "Wait for interrupt"); ++ driver->states[0].enter = at91_enter_idle; ++ driver->states[0].exit_latency = 1; ++ driver->states[0].target_residency = 10000; ++ driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID; ++ strcpy(driver->states[0].name, "WFI"); ++ strcpy(driver->states[0].desc, "Wait for interrupt"); + + /* Wait for interrupt and RAM self refresh state */ +- device->states[1].enter = at91_enter_idle; +- device->states[1].exit_latency = 10; +- device->states[1].target_residency = 10000; +- device->states[1].flags = CPUIDLE_FLAG_TIME_VALID; +- strcpy(device->states[1].name, "RAM_SR"); +- strcpy(device->states[1].desc, "WFI and RAM Self Refresh"); ++ driver->states[1].enter = at91_enter_idle; ++ driver->states[1].exit_latency = 10; ++ driver->states[1].target_residency = 10000; ++ driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID; ++ strcpy(driver->states[1].name, "RAM_SR"); ++ strcpy(driver->states[1].desc, "WFI and RAM Self Refresh"); ++ ++ cpuidle_register_driver(&at91_idle_driver); + + if (cpuidle_register_device(device)) { + printk(KERN_ERR "at91_init_cpuidle: Failed registering\n"); +diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c +index dda6d2f..ed7fb95 100644 +--- a/arch/arm/mach-davinci/cpuidle.c ++++ b/arch/arm/mach-davinci/cpuidle.c +@@ -79,6 +79,7 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = { + + /* Actual code that puts the SoC in different idle states */ + static int davinci_enter_idle(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, + int index) + { + struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; +@@ -110,6 +111,7 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev) + { + int ret; + struct cpuidle_device *device; ++ struct cpuidle_driver *driver = &davinci_idle_driver; + struct davinci_cpuidle_config *pdata = pdev->dev.platform_data; + + device = &per_cpu(davinci_cpuidle_device, smp_processor_id()); +@@ -121,32 +123,33 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev) + + ddr2_reg_base = pdata->ddr2_ctlr_base; + +- ret = cpuidle_register_driver(&davinci_idle_driver); +- if (ret) { +- dev_err(&pdev->dev, "failed to register driver\n"); +- return ret; +- } +- + /* Wait for interrupt state */ +- device->states[0].enter = davinci_enter_idle; +- device->states[0].exit_latency = 1; +- device->states[0].target_residency = 10000; +- device->states[0].flags = CPUIDLE_FLAG_TIME_VALID; +- strcpy(device->states[0].name, "WFI"); +- strcpy(device->states[0].desc, "Wait for interrupt"); ++ driver->states[0].enter = davinci_enter_idle; ++ driver->states[0].exit_latency = 1; ++ driver->states[0].target_residency = 10000; ++ driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID; ++ strcpy(driver->states[0].name, "WFI"); ++ strcpy(driver->states[0].desc, "Wait for interrupt"); + + /* Wait for interrupt and DDR self refresh state */ +- device->states[1].enter = davinci_enter_idle; +- device->states[1].exit_latency = 10; +- device->states[1].target_residency = 10000; +- device->states[1].flags = CPUIDLE_FLAG_TIME_VALID; +- strcpy(device->states[1].name, "DDR SR"); +- strcpy(device->states[1].desc, "WFI and DDR Self Refresh"); ++ driver->states[1].enter = davinci_enter_idle; ++ driver->states[1].exit_latency = 10; ++ driver->states[1].target_residency = 10000; ++ driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID; ++ strcpy(driver->states[1].name, "DDR SR"); ++ strcpy(driver->states[1].desc, "WFI and DDR Self Refresh"); + if (pdata->ddr2_pdown) + davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN; + cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]); + + device->state_count = DAVINCI_CPUIDLE_MAX_STATES; ++ driver->state_count = DAVINCI_CPUIDLE_MAX_STATES; ++ ++ ret = cpuidle_register_driver(&davinci_idle_driver); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to register driver\n"); ++ return ret; ++ } + + ret = cpuidle_register_device(device); + if (ret) { +diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos4/cpuidle.c +index ea026e7..35f6502 100644 +--- a/arch/arm/mach-exynos4/cpuidle.c ++++ b/arch/arm/mach-exynos4/cpuidle.c +@@ -16,6 +16,7 @@ + #include <asm/proc-fns.h> + + static int exynos4_enter_idle(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, + int index); + + static struct cpuidle_state exynos4_cpuidle_set[] = { +@@ -37,6 +38,7 @@ static struct cpuidle_driver exynos4_idle_driver = { + }; + + static int exynos4_enter_idle(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, + int index) + { + struct timeval before, after; +@@ -60,22 +62,23 @@ static int __init exynos4_init_cpuidle(void) + { + int i, max_cpuidle_state, cpu_id; + struct cpuidle_device *device; +- ++ struct cpuidle_driver *drv = &exynos4_idle_driver; ++ ++ /* Setup cpuidle driver */ ++ drv->state_count = (sizeof(exynos4_cpuidle_set) / ++ sizeof(struct cpuidle_state)); ++ max_cpuidle_state = drv->state_count; ++ for (i = 0; i < max_cpuidle_state; i++) { ++ memcpy(&drv->states[i], &exynos4_cpuidle_set[i], ++ sizeof(struct cpuidle_state)); ++ } + cpuidle_register_driver(&exynos4_idle_driver); + + for_each_cpu(cpu_id, cpu_online_mask) { + device = &per_cpu(exynos4_cpuidle_device, cpu_id); + device->cpu = cpu_id; + +- device->state_count = (sizeof(exynos4_cpuidle_set) / +- sizeof(struct cpuidle_state)); +- +- max_cpuidle_state = device->state_count; +- +- for (i = 0; i < max_cpuidle_state; i++) { +- memcpy(&device->states[i], &exynos4_cpuidle_set[i], +- sizeof(struct cpuidle_state)); +- } ++ device->state_count = drv->state_count; + + if (cpuidle_register_device(device)) { + printk(KERN_ERR "CPUidle register device failed\n,"); +diff --git a/arch/arm/mach-kirkwood/cpuidle.c b/arch/arm/mach-kirkwood/cpuidle.c +index 53d6049..7088180 100644 +--- a/arch/arm/mach-kirkwood/cpuidle.c ++++ b/arch/arm/mach-kirkwood/cpuidle.c +@@ -33,6 +33,7 @@ static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device); + + /* Actual code that puts the SoC in different idle states */ + static int kirkwood_enter_idle(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, + int index) + { + struct timeval before, after; +@@ -69,28 +70,29 @@ static int kirkwood_enter_idle(struct cpuidle_device *dev, + static int kirkwood_init_cpuidle(void) + { + struct cpuidle_device *device; +- +- cpuidle_register_driver(&kirkwood_idle_driver); ++ struct cpuidle_driver *driver = &kirkwood_idle_driver; + + device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id()); + device->state_count = KIRKWOOD_MAX_STATES; ++ driver->state_count = KIRKWOOD_MAX_STATES; + + /* Wait for interrupt state */ +- device->states[0].enter = kirkwood_enter_idle; +- device->states[0].exit_latency = 1; +- device->states[0].target_residency = 10000; +- device->states[0].flags = CPUIDLE_FLAG_TIME_VALID; +- strcpy(device->states[0].name, "WFI"); +- strcpy(device->states[0].desc, "Wait for interrupt"); ++ driver->states[0].enter = kirkwood_enter_idle; ++ driver->states[0].exit_latency = 1; ++ driver->states[0].target_residency = 10000; ++ driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID; ++ strcpy(driver->states[0].name, "WFI"); ++ strcpy(driver->states[0].desc, "Wait for interrupt"); + + /* Wait for interrupt and DDR self refresh state */ +- device->states[1].enter = kirkwood_enter_idle; +- device->states[1].exit_latency = 10; +- device->states[1].target_residency = 10000; +- device->states[1].flags = CPUIDLE_FLAG_TIME_VALID; +- strcpy(device->states[1].name, "DDR SR"); +- strcpy(device->states[1].desc, "WFI and DDR Self Refresh"); ++ driver->states[1].enter = kirkwood_enter_idle; ++ driver->states[1].exit_latency = 10; ++ driver->states[1].target_residency = 10000; ++ driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID; ++ strcpy(driver->states[1].name, "DDR SR"); ++ strcpy(driver->states[1].desc, "WFI and DDR Self Refresh"); + ++ cpuidle_register_driver(&kirkwood_idle_driver); + if (cpuidle_register_device(device)) { + printk(KERN_ERR "kirkwood_init_cpuidle: Failed registering\n"); + return -EIO; +diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c +index d3fce7b..1fe35c2 100644 +--- a/arch/arm/mach-omap2/cpuidle34xx.c ++++ b/arch/arm/mach-omap2/cpuidle34xx.c +@@ -88,12 +88,14 @@ static int _cpuidle_deny_idle(struct powerdomain *pwrdm, + /** + * omap3_enter_idle - Programs OMAP3 to enter the specified state + * @dev: cpuidle device ++ * @drv: cpuidle driver + * @index: the index of state to be entered + * + * Called from the CPUidle framework to program the device to the + * specified target state selected by the governor. + */ + static int omap3_enter_idle(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, + int index) + { + struct omap3_idle_statedata *cx = +@@ -148,6 +150,7 @@ return_sleep_time: + /** + * next_valid_state - Find next valid C-state + * @dev: cpuidle device ++ * @drv: cpuidle driver + * @index: Index of currently selected c-state + * + * If the state corresponding to index is valid, index is returned back +@@ -158,10 +161,11 @@ return_sleep_time: + * if it satisfies the enable_off_mode condition. + */ + static int next_valid_state(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, + int index) + { + struct cpuidle_state_usage *curr_usage = &dev->states_usage[index]; +- struct cpuidle_state *curr = &dev->states[index]; ++ struct cpuidle_state *curr = &drv->states[index]; + struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage); + u32 mpu_deepest_state = PWRDM_POWER_RET; + u32 core_deepest_state = PWRDM_POWER_RET; +@@ -188,7 +192,7 @@ static int next_valid_state(struct cpuidle_device *dev, + + /* Reach the current state starting at highest C-state */ + for (; idx >= 0; idx--) { +- if (&dev->states[idx] == curr) { ++ if (&drv->states[idx] == curr) { + next_index = idx; + break; + } +@@ -224,12 +228,14 @@ static int next_valid_state(struct cpuidle_device *dev, + /** + * omap3_enter_idle_bm - Checks for any bus activity + * @dev: cpuidle device ++ * @drv: cpuidle driver + * @index: array index of target state to be programmed + * + * This function checks for any pending activity and then programs + * the device to the specified or a safer state. + */ + static int omap3_enter_idle_bm(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, + int index) + { + int new_state_idx; +@@ -238,7 +244,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, + int ret; + + if (!omap3_can_sleep()) { +- new_state_idx = dev->safe_state_index; ++ new_state_idx = drv->safe_state_index; + goto select_state; + } + +@@ -248,7 +254,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, + */ + cam_state = pwrdm_read_pwrst(cam_pd); + if (cam_state == PWRDM_POWER_ON) { +- new_state_idx = dev->safe_state_index; ++ new_state_idx = drv->safe_state_index; + goto select_state; + } + +@@ -275,10 +281,10 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, + if (per_next_state != per_saved_state) + pwrdm_set_next_pwrst(per_pd, per_next_state); + +- new_state_idx = next_valid_state(dev, index); ++ new_state_idx = next_valid_state(dev, drv, index); + + select_state: +- ret = omap3_enter_idle(dev, new_state_idx); ++ ret = omap3_enter_idle(dev, drv, new_state_idx); + + /* Restore original PER state if it was modified */ + if (per_next_state != per_saved_state) +@@ -311,22 +317,30 @@ struct cpuidle_driver omap3_idle_driver = { + .owner = THIS_MODULE, + }; + +-/* Helper to fill the C-state common data and register the driver_data */ +-static inline struct omap3_idle_statedata *_fill_cstate( +- struct cpuidle_device *dev, ++/* Helper to fill the C-state common data*/ ++static inline void _fill_cstate(struct cpuidle_driver *drv, + int idx, const char *descr) + { +- struct omap3_idle_statedata *cx = &omap3_idle_data[idx]; +- struct cpuidle_state *state = &dev->states[idx]; +- struct cpuidle_state_usage *state_usage = &dev->states_usage[idx]; ++ struct cpuidle_state *state = &drv->states[idx]; + + state->exit_latency = cpuidle_params_table[idx].exit_latency; + state->target_residency = cpuidle_params_table[idx].target_residency; + state->flags = CPUIDLE_FLAG_TIME_VALID; + state->enter = omap3_enter_idle_bm; +- cx->valid = cpuidle_params_table[idx].valid; + sprintf(state->name, "C%d", idx + 1); + strncpy(state->desc, descr, CPUIDLE_DESC_LEN); ++ ++} ++ ++/* Helper to register the driver_data */ ++static inline struct omap3_idle_statedata *_fill_cstate_usage( ++ struct cpuidle_device *dev, ++ int idx) ++{ ++ struct omap3_idle_statedata *cx = &omap3_idle_data[idx]; ++ struct cpuidle_state_usage *state_usage = &dev->states_usage[idx]; ++ ++ cx->valid = cpuidle_params_table[idx].valid; + cpuidle_set_statedata(state_usage, cx); + + return cx; +@@ -341,6 +355,7 @@ static inline struct omap3_idle_statedata *_fill_cstate( + int __init omap3_idle_init(void) + { + struct cpuidle_device *dev; ++ struct cpuidle_driver *drv = &omap3_idle_driver; + struct omap3_idle_statedata *cx; + + mpu_pd = pwrdm_lookup("mpu_pwrdm"); +@@ -348,45 +363,52 @@ int __init omap3_idle_init(void) + per_pd = pwrdm_lookup("per_pwrdm"); + cam_pd = pwrdm_lookup("cam_pwrdm"); + +- cpuidle_register_driver(&omap3_idle_driver); ++ ++ drv->safe_state_index = -1; + dev = &per_cpu(omap3_idle_dev, smp_processor_id()); +- dev->safe_state_index = -1; + + /* C1 . MPU WFI + Core active */ +- cx = _fill_cstate(dev, 0, "MPU ON + CORE ON"); +- (&dev->states[0])->enter = omap3_enter_idle; +- dev->safe_state_index = 0; ++ _fill_cstate(drv, 0, "MPU ON + CORE ON"); ++ (&drv->states[0])->enter = omap3_enter_idle; ++ drv->safe_state_index = 0; ++ cx = _fill_cstate_usage(dev, 0); + cx->valid = 1; /* C1 is always valid */ + cx->mpu_state = PWRDM_POWER_ON; + cx->core_state = PWRDM_POWER_ON; + + /* C2 . MPU WFI + Core inactive */ +- cx = _fill_cstate(dev, 1, "MPU ON + CORE ON"); ++ _fill_cstate(drv, 1, "MPU ON + CORE ON"); ++ cx = _fill_cstate_usage(dev, 1); + cx->mpu_state = PWRDM_POWER_ON; + cx->core_state = PWRDM_POWER_ON; + + /* C3 . MPU CSWR + Core inactive */ +- cx = _fill_cstate(dev, 2, "MPU RET + CORE ON"); ++ _fill_cstate(drv, 2, "MPU RET + CORE ON"); ++ cx = _fill_cstate_usage(dev, 2); + cx->mpu_state = PWRDM_POWER_RET; + cx->core_state = PWRDM_POWER_ON; + + /* C4 . MPU OFF + Core inactive */ +- cx = _fill_cstate(dev, 3, "MPU OFF + CORE ON"); ++ _fill_cstate(drv, 3, "MPU OFF + CORE ON"); ++ cx = _fill_cstate_usage(dev, 3); + cx->mpu_state = PWRDM_POWER_OFF; + cx->core_state = PWRDM_POWER_ON; + + /* C5 . MPU RET + Core RET */ +- cx = _fill_cstate(dev, 4, "MPU RET + CORE RET"); ++ _fill_cstate(drv, 4, "MPU RET + CORE RET"); ++ cx = _fill_cstate_usage(dev, 4); + cx->mpu_state = PWRDM_POWER_RET; + cx->core_state = PWRDM_POWER_RET; + + /* C6 . MPU OFF + Core RET */ +- cx = _fill_cstate(dev, 5, "MPU OFF + CORE RET"); ++ _fill_cstate(drv, 5, "MPU OFF + CORE RET"); ++ cx = _fill_cstate_usage(dev, 5); + cx->mpu_state = PWRDM_POWER_OFF; + cx->core_state = PWRDM_POWER_RET; + + /* C7 . MPU OFF + Core OFF */ +- cx = _fill_cstate(dev, 6, "MPU OFF + CORE OFF"); ++ _fill_cstate(drv, 6, "MPU OFF + CORE OFF"); ++ cx = _fill_cstate_usage(dev, 6); + /* + * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot + * enable OFF mode in a stable form for previous revisions. +@@ -400,6 +422,9 @@ int __init omap3_idle_init(void) + cx->mpu_state = PWRDM_POWER_OFF; + cx->core_state = PWRDM_POWER_OFF; + ++ drv->state_count = OMAP3_NUM_STATES; ++ cpuidle_register_driver(&omap3_idle_driver); ++ + dev->state_count = OMAP3_NUM_STATES; + if (cpuidle_register_device(dev)) { + printk(KERN_ERR "%s: CPUidle register device failed\n", +diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c +index 7be50d4c..ad1012a 100644 +--- a/arch/sh/kernel/cpu/shmobile/cpuidle.c ++++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c +@@ -25,6 +25,7 @@ static unsigned long cpuidle_mode[] = { + }; + + static int cpuidle_sleep_enter(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, + int index) + { + unsigned long allowed_mode = arch_hwblk_sleep_mode(); +@@ -64,19 +65,19 @@ static struct cpuidle_driver cpuidle_driver = { + void sh_mobile_setup_cpuidle(void) + { + struct cpuidle_device *dev = &cpuidle_dev; ++ struct cpuidle_driver *drv = &cpuidle_driver; + struct cpuidle_state *state; + int i; + +- cpuidle_register_driver(&cpuidle_driver); + + for (i = 0; i < CPUIDLE_STATE_MAX; i++) { +- dev->states[i].name[0] = '\0'; +- dev->states[i].desc[0] = '\0'; ++ drv->states[i].name[0] = '\0'; ++ drv->states[i].desc[0] = '\0'; + } + + i = CPUIDLE_DRIVER_STATE_START; + +- state = &dev->states[i++]; ++ state = &drv->states[i++]; + snprintf(state->name, CPUIDLE_NAME_LEN, "C1"); + strncpy(state->desc, "SuperH Sleep Mode", CPUIDLE_DESC_LEN); + state->exit_latency = 1; +@@ -86,10 +87,10 @@ void sh_mobile_setup_cpuidle(void) + state->flags |= CPUIDLE_FLAG_TIME_VALID; + state->enter = cpuidle_sleep_enter; + +- dev->safe_state_index = i-1; ++ drv->safe_state_index = i-1; + + if (sh_mobile_sleep_supported & SUSP_SH_SF) { +- state = &dev->states[i++]; ++ state = &drv->states[i++]; + snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); + strncpy(state->desc, "SuperH Sleep Mode [SF]", + CPUIDLE_DESC_LEN); +@@ -102,7 +103,7 @@ void sh_mobile_setup_cpuidle(void) + } + + if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) { +- state = &dev->states[i++]; ++ state = &drv->states[i++]; + snprintf(state->name, CPUIDLE_NAME_LEN, "C3"); + strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", + CPUIDLE_DESC_LEN); +@@ -114,7 +115,10 @@ void sh_mobile_setup_cpuidle(void) + state->enter = cpuidle_sleep_enter; + } + ++ drv->state_count = i; + dev->state_count = i; + ++ cpuidle_register_driver(&cpuidle_driver); ++ + cpuidle_register_device(dev); + } +diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c +index a4e0f1b..9d7bc9f 100644 +--- a/drivers/acpi/processor_driver.c ++++ b/drivers/acpi/processor_driver.c +@@ -426,7 +426,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, + + if (action == CPU_ONLINE && pr) { + acpi_processor_ppc_has_changed(pr, 0); +- acpi_processor_cst_has_changed(pr); ++ acpi_processor_hotplug(pr); + acpi_processor_reevaluate_tstate(pr, action); + acpi_processor_tstate_has_changed(pr); + } +@@ -503,8 +503,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) + acpi_processor_get_throttling_info(pr); + acpi_processor_get_limit_info(pr); + +- +- if (cpuidle_get_driver() == &acpi_idle_driver) ++ if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) + acpi_processor_power_init(pr, device); + + pr->cdev = thermal_cooling_device_register("Processor", device, +@@ -800,17 +799,9 @@ static int __init acpi_processor_init(void) + + memset(&errata, 0, sizeof(errata)); + +- if (!cpuidle_register_driver(&acpi_idle_driver)) { +- printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", +- acpi_idle_driver.name); +- } else { +- printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s\n", +- cpuidle_get_driver()->name); +- } +- + result = acpi_bus_register_driver(&acpi_processor_driver); + if (result < 0) +- goto out_cpuidle; ++ return result; + + acpi_processor_install_hotplug_notify(); + +@@ -821,11 +812,6 @@ static int __init acpi_processor_init(void) + acpi_processor_throttling_init(); + + return 0; +- +-out_cpuidle: +- cpuidle_unregister_driver(&acpi_idle_driver); +- +- return result; + } + + static void __exit acpi_processor_exit(void) +diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c +index c7b89f0..da70c26 100644 +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -741,11 +741,13 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) + /** + * acpi_idle_enter_c1 - enters an ACPI C1 state-type + * @dev: the target CPU ++ * @drv: cpuidle driver containing cpuidle state info + * @index: index of target state + * + * This is equivalent to the HALT instruction. + */ +-static int acpi_idle_enter_c1(struct cpuidle_device *dev, int index) ++static int acpi_idle_enter_c1(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index) + { + ktime_t kt1, kt2; + s64 idle_time; +@@ -787,9 +789,11 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, int index) + /** + * acpi_idle_enter_simple - enters an ACPI state without BM handling + * @dev: the target CPU ++ * @drv: cpuidle driver with cpuidle state information + * @index: the index of suggested state + */ +-static int acpi_idle_enter_simple(struct cpuidle_device *dev, int index) ++static int acpi_idle_enter_simple(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index) + { + struct acpi_processor *pr; + struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; +@@ -869,11 +873,13 @@ static DEFINE_SPINLOCK(c3_lock); + /** + * acpi_idle_enter_bm - enters C3 with proper BM handling + * @dev: the target CPU ++ * @drv: cpuidle driver containing state data + * @index: the index of suggested state + * + * If BM is detected, the deepest non-C3 idle state is entered instead. + */ +-static int acpi_idle_enter_bm(struct cpuidle_device *dev, int index) ++static int acpi_idle_enter_bm(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index) + { + struct acpi_processor *pr; + struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; +@@ -896,9 +902,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, int index) + } + + if (!cx->bm_sts_skip && acpi_idle_bm_check()) { +- if (dev->safe_state_index >= 0) { +- return dev->states[dev->safe_state_index].enter(dev, +- dev->safe_state_index); ++ if (drv->safe_state_index >= 0) { ++ return drv->states[drv->safe_state_index].enter(dev, ++ drv, drv->safe_state_index); + } else { + local_irq_disable(); + acpi_safe_halt(); +@@ -993,14 +999,15 @@ struct cpuidle_driver acpi_idle_driver = { + }; + + /** +- * acpi_processor_setup_cpuidle - prepares and configures CPUIDLE ++ * acpi_processor_setup_cpuidle_cx - prepares and configures CPUIDLE ++ * device i.e. per-cpu data ++ * + * @pr: the ACPI processor + */ +-static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) ++static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr) + { + int i, count = CPUIDLE_DRIVER_STATE_START; + struct acpi_processor_cx *cx; +- struct cpuidle_state *state; + struct cpuidle_state_usage *state_usage; + struct cpuidle_device *dev = &pr->power.dev; + +@@ -1012,18 +1019,12 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) + } + + dev->cpu = pr->id; +- dev->safe_state_index = -1; +- for (i = 0; i < CPUIDLE_STATE_MAX; i++) { +- dev->states[i].name[0] = '\0'; +- dev->states[i].desc[0] = '\0'; +- } + + if (max_cstate == 0) + max_cstate = 1; + + for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { + cx = &pr->power.states[i]; +- state = &dev->states[count]; + state_usage = &dev->states_usage[count]; + + if (!cx->valid) +@@ -1035,8 +1036,64 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) + !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) + continue; + #endif ++ + cpuidle_set_statedata(state_usage, cx); + ++ count++; ++ if (count == CPUIDLE_STATE_MAX) ++ break; ++ } ++ ++ dev->state_count = count; ++ ++ if (!count) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++/** ++ * acpi_processor_setup_cpuidle states- prepares and configures cpuidle ++ * global state data i.e. idle routines ++ * ++ * @pr: the ACPI processor ++ */ ++static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) ++{ ++ int i, count = CPUIDLE_DRIVER_STATE_START; ++ struct acpi_processor_cx *cx; ++ struct cpuidle_state *state; ++ struct cpuidle_driver *drv = &acpi_idle_driver; ++ ++ if (!pr->flags.power_setup_done) ++ return -EINVAL; ++ ++ if (pr->flags.power == 0) ++ return -EINVAL; ++ ++ drv->safe_state_index = -1; ++ for (i = 0; i < CPUIDLE_STATE_MAX; i++) { ++ drv->states[i].name[0] = '\0'; ++ drv->states[i].desc[0] = '\0'; ++ } ++ ++ if (max_cstate == 0) ++ max_cstate = 1; ++ ++ for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { ++ cx = &pr->power.states[i]; ++ ++ if (!cx->valid) ++ continue; ++ ++#ifdef CONFIG_HOTPLUG_CPU ++ if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && ++ !pr->flags.has_cst && ++ !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) ++ continue; ++#endif ++ ++ state = &drv->states[count]; + snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); + strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); + state->exit_latency = cx->latency; +@@ -1049,13 +1106,13 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) + state->flags |= CPUIDLE_FLAG_TIME_VALID; + + state->enter = acpi_idle_enter_c1; +- dev->safe_state_index = count; ++ drv->safe_state_index = count; + break; + + case ACPI_STATE_C2: + state->flags |= CPUIDLE_FLAG_TIME_VALID; + state->enter = acpi_idle_enter_simple; +- dev->safe_state_index = count; ++ drv->safe_state_index = count; + break; + + case ACPI_STATE_C3: +@@ -1071,7 +1128,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) + break; + } + +- dev->state_count = count; ++ drv->state_count = count; + + if (!count) + return -EINVAL; +@@ -1079,7 +1136,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) + return 0; + } + +-int acpi_processor_cst_has_changed(struct acpi_processor *pr) ++int acpi_processor_hotplug(struct acpi_processor *pr) + { + int ret = 0; + +@@ -1100,7 +1157,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) + cpuidle_disable_device(&pr->power.dev); + acpi_processor_get_power_info(pr); + if (pr->flags.power) { +- acpi_processor_setup_cpuidle(pr); ++ acpi_processor_setup_cpuidle_cx(pr); + ret = cpuidle_enable_device(&pr->power.dev); + } + cpuidle_resume_and_unlock(); +@@ -1108,10 +1165,72 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) + return ret; + } + ++int acpi_processor_cst_has_changed(struct acpi_processor *pr) ++{ ++ int cpu; ++ struct acpi_processor *_pr; ++ ++ if (disabled_by_idle_boot_param()) ++ return 0; ++ ++ if (!pr) ++ return -EINVAL; ++ ++ if (nocst) ++ return -ENODEV; ++ ++ if (!pr->flags.power_setup_done) ++ return -ENODEV; ++ ++ /* ++ * FIXME: Design the ACPI notification to make it once per ++ * system instead of once per-cpu. This condition is a hack ++ * to make the code that updates C-States be called once. ++ */ ++ ++ if (smp_processor_id() == 0 && ++ cpuidle_get_driver() == &acpi_idle_driver) { ++ ++ cpuidle_pause_and_lock(); ++ /* Protect against cpu-hotplug */ ++ get_online_cpus(); ++ ++ /* Disable all cpuidle devices */ ++ for_each_online_cpu(cpu) { ++ _pr = per_cpu(processors, cpu); ++ if (!_pr || !_pr->flags.power_setup_done) ++ continue; ++ cpuidle_disable_device(&_pr->power.dev); ++ } ++ ++ /* Populate Updated C-state information */ ++ acpi_processor_setup_cpuidle_states(pr); ++ ++ /* Enable all cpuidle devices */ ++ for_each_online_cpu(cpu) { ++ _pr = per_cpu(processors, cpu); ++ if (!_pr || !_pr->flags.power_setup_done) ++ continue; ++ acpi_processor_get_power_info(_pr); ++ if (_pr->flags.power) { ++ acpi_processor_setup_cpuidle_cx(_pr); ++ cpuidle_enable_device(&_pr->power.dev); ++ } ++ } ++ put_online_cpus(); ++ cpuidle_resume_and_unlock(); ++ } ++ ++ return 0; ++} ++ ++static int acpi_processor_registered; ++ + int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, + struct acpi_device *device) + { + acpi_status status = 0; ++ int retval; + static int first_run; + + if (disabled_by_idle_boot_param()) +@@ -1148,9 +1267,26 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, + * platforms that only support C1. + */ + if (pr->flags.power) { +- acpi_processor_setup_cpuidle(pr); +- if (cpuidle_register_device(&pr->power.dev)) +- return -EIO; ++ /* Register acpi_idle_driver if not already registered */ ++ if (!acpi_processor_registered) { ++ acpi_processor_setup_cpuidle_states(pr); ++ retval = cpuidle_register_driver(&acpi_idle_driver); ++ if (retval) ++ return retval; ++ printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", ++ acpi_idle_driver.name); ++ } ++ /* Register per-cpu cpuidle_device. Cpuidle driver ++ * must already be registered before registering device ++ */ ++ acpi_processor_setup_cpuidle_cx(pr); ++ retval = cpuidle_register_device(&pr->power.dev); ++ if (retval) { ++ if (acpi_processor_registered == 0) ++ cpuidle_unregister_driver(&acpi_idle_driver); ++ return retval; ++ } ++ acpi_processor_registered++; + } + return 0; + } +@@ -1161,8 +1297,13 @@ int acpi_processor_power_exit(struct acpi_processor *pr, + if (disabled_by_idle_boot_param()) + return 0; + +- cpuidle_unregister_device(&pr->power.dev); +- pr->flags.power_setup_done = 0; ++ if (pr->flags.power) { ++ cpuidle_unregister_device(&pr->power.dev); ++ acpi_processor_registered--; ++ if (acpi_processor_registered == 0) ++ cpuidle_unregister_driver(&acpi_idle_driver); ++ } + ++ pr->flags.power_setup_done = 0; + return 0; + } +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index 219a757..06ce268 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -62,6 +62,7 @@ static int __cpuidle_register_device(struct cpuidle_device *dev); + int cpuidle_idle_call(void) + { + struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); ++ struct cpuidle_driver *drv = cpuidle_get_driver(); + struct cpuidle_state *target_state; + int next_state, entered_state; + +@@ -85,18 +86,18 @@ int cpuidle_idle_call(void) + #endif + + /* ask the governor for the next state */ +- next_state = cpuidle_curr_governor->select(dev); ++ next_state = cpuidle_curr_governor->select(drv, dev); + if (need_resched()) { + local_irq_enable(); + return 0; + } + +- target_state = &dev->states[next_state]; ++ target_state = &drv->states[next_state]; + + trace_power_start(POWER_CSTATE, next_state, dev->cpu); + trace_cpu_idle(next_state, dev->cpu); + +- entered_state = target_state->enter(dev, next_state); ++ entered_state = target_state->enter(dev, drv, next_state); + + trace_power_end(dev->cpu); + trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu); +@@ -164,7 +165,8 @@ void cpuidle_resume_and_unlock(void) + EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); + + #ifdef CONFIG_ARCH_HAS_CPU_RELAX +-static int poll_idle(struct cpuidle_device *dev, int index) ++static int poll_idle(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index) + { + ktime_t t1, t2; + s64 diff; +@@ -184,12 +186,9 @@ static int poll_idle(struct cpuidle_device *dev, int index) + return index; + } + +-static void poll_idle_init(struct cpuidle_device *dev) ++static void poll_idle_init(struct cpuidle_driver *drv) + { +- struct cpuidle_state *state = &dev->states[0]; +- struct cpuidle_state_usage *state_usage = &dev->states_usage[0]; +- +- cpuidle_set_statedata(state_usage, NULL); ++ struct cpuidle_state *state = &drv->states[0]; + + snprintf(state->name, CPUIDLE_NAME_LEN, "POLL"); + snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); +@@ -200,7 +199,7 @@ static void poll_idle_init(struct cpuidle_device *dev) + state->enter = poll_idle; + } + #else +-static void poll_idle_init(struct cpuidle_device *dev) {} ++static void poll_idle_init(struct cpuidle_driver *drv) {} + #endif /* CONFIG_ARCH_HAS_CPU_RELAX */ + + /** +@@ -227,13 +226,13 @@ int cpuidle_enable_device(struct cpuidle_device *dev) + return ret; + } + +- poll_idle_init(dev); ++ poll_idle_init(cpuidle_get_driver()); + + if ((ret = cpuidle_add_state_sysfs(dev))) + return ret; + + if (cpuidle_curr_governor->enable && +- (ret = cpuidle_curr_governor->enable(dev))) ++ (ret = cpuidle_curr_governor->enable(cpuidle_get_driver(), dev))) + goto fail_sysfs; + + for (i = 0; i < dev->state_count; i++) { +@@ -274,7 +273,7 @@ void cpuidle_disable_device(struct cpuidle_device *dev) + dev->enabled = 0; + + if (cpuidle_curr_governor->disable) +- cpuidle_curr_governor->disable(dev); ++ cpuidle_curr_governor->disable(cpuidle_get_driver(), dev); + + cpuidle_remove_state_sysfs(dev); + enabled_devices--; +@@ -302,26 +301,6 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) + + init_completion(&dev->kobj_unregister); + +- /* +- * cpuidle driver should set the dev->power_specified bit +- * before registering the device if the driver provides +- * power_usage numbers. +- * +- * For those devices whose ->power_specified is not set, +- * we fill in power_usage with decreasing values as the +- * cpuidle code has an implicit assumption that state Cn +- * uses less power than C(n-1). +- * +- * With CONFIG_ARCH_HAS_CPU_RELAX, C0 is already assigned +- * an power value of -1. So we use -2, -3, etc, for other +- * c-states. +- */ +- if (!dev->power_specified) { +- int i; +- for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++) +- dev->states[i].power_usage = -1 - i; +- } +- + per_cpu(cpuidle_devices, dev->cpu) = dev; + list_add(&dev->device_list, &cpuidle_detected_devices); + if ((ret = cpuidle_add_sysfs(sys_dev))) { +diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c +index 3f7e3ce..284d7af 100644 +--- a/drivers/cpuidle/driver.c ++++ b/drivers/cpuidle/driver.c +@@ -17,6 +17,30 @@ + static struct cpuidle_driver *cpuidle_curr_driver; + DEFINE_SPINLOCK(cpuidle_driver_lock); + ++static void __cpuidle_register_driver(struct cpuidle_driver *drv) ++{ ++ int i; ++ /* ++ * cpuidle driver should set the drv->power_specified bit ++ * before registering if the driver provides ++ * power_usage numbers. ++ * ++ * If power_specified is not set, ++ * we fill in power_usage with decreasing values as the ++ * cpuidle code has an implicit assumption that state Cn ++ * uses less power than C(n-1). ++ * ++ * With CONFIG_ARCH_HAS_CPU_RELAX, C0 is already assigned ++ * an power value of -1. So we use -2, -3, etc, for other ++ * c-states. ++ */ ++ if (!drv->power_specified) { ++ for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) ++ drv->states[i].power_usage = -1 - i; ++ } ++} ++ ++ + /** + * cpuidle_register_driver - registers a driver + * @drv: the driver +@@ -34,6 +58,7 @@ int cpuidle_register_driver(struct cpuidle_driver *drv) + spin_unlock(&cpuidle_driver_lock); + return -EBUSY; + } ++ __cpuidle_register_driver(drv); + cpuidle_curr_driver = drv; + spin_unlock(&cpuidle_driver_lock); + +diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c +index 78b06d2..261e57a 100644 +--- a/drivers/cpuidle/governors/ladder.c ++++ b/drivers/cpuidle/governors/ladder.c +@@ -60,9 +60,11 @@ static inline void ladder_do_selection(struct ladder_device *ldev, + + /** + * ladder_select_state - selects the next state to enter ++ * @drv: cpuidle driver + * @dev: the CPU + */ +-static int ladder_select_state(struct cpuidle_device *dev) ++static int ladder_select_state(struct cpuidle_driver *drv, ++ struct cpuidle_device *dev) + { + struct ladder_device *ldev = &__get_cpu_var(ladder_devices); + struct ladder_device_state *last_state; +@@ -77,15 +79,17 @@ static int ladder_select_state(struct cpuidle_device *dev) + + last_state = &ldev->states[last_idx]; + +- if (dev->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID) +- last_residency = cpuidle_get_last_residency(dev) - dev->states[last_idx].exit_latency; ++ if (drv->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID) { ++ last_residency = cpuidle_get_last_residency(dev) - \ ++ drv->states[last_idx].exit_latency; ++ } + else + last_residency = last_state->threshold.promotion_time + 1; + + /* consider promotion */ +- if (last_idx < dev->state_count - 1 && ++ if (last_idx < drv->state_count - 1 && + last_residency > last_state->threshold.promotion_time && +- dev->states[last_idx + 1].exit_latency <= latency_req) { ++ drv->states[last_idx + 1].exit_latency <= latency_req) { + last_state->stats.promotion_count++; + last_state->stats.demotion_count = 0; + if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) { +@@ -96,11 +100,11 @@ static int ladder_select_state(struct cpuidle_device *dev) + + /* consider demotion */ + if (last_idx > CPUIDLE_DRIVER_STATE_START && +- dev->states[last_idx].exit_latency > latency_req) { ++ drv->states[last_idx].exit_latency > latency_req) { + int i; + + for (i = last_idx - 1; i > CPUIDLE_DRIVER_STATE_START; i--) { +- if (dev->states[i].exit_latency <= latency_req) ++ if (drv->states[i].exit_latency <= latency_req) + break; + } + ladder_do_selection(ldev, last_idx, i); +@@ -123,9 +127,11 @@ static int ladder_select_state(struct cpuidle_device *dev) + + /** + * ladder_enable_device - setup for the governor ++ * @drv: cpuidle driver + * @dev: the CPU + */ +-static int ladder_enable_device(struct cpuidle_device *dev) ++static int ladder_enable_device(struct cpuidle_driver *drv, ++ struct cpuidle_device *dev) + { + int i; + struct ladder_device *ldev = &per_cpu(ladder_devices, dev->cpu); +@@ -134,8 +140,8 @@ static int ladder_enable_device(struct cpuidle_device *dev) + + ldev->last_state_idx = CPUIDLE_DRIVER_STATE_START; + +- for (i = 0; i < dev->state_count; i++) { +- state = &dev->states[i]; ++ for (i = 0; i < drv->state_count; i++) { ++ state = &drv->states[i]; + lstate = &ldev->states[i]; + + lstate->stats.promotion_count = 0; +@@ -144,7 +150,7 @@ static int ladder_enable_device(struct cpuidle_device *dev) + lstate->threshold.promotion_count = PROMOTION_COUNT; + lstate->threshold.demotion_count = DEMOTION_COUNT; + +- if (i < dev->state_count - 1) ++ if (i < drv->state_count - 1) + lstate->threshold.promotion_time = state->exit_latency; + if (i > 0) + lstate->threshold.demotion_time = state->exit_latency; +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index 2072aeb..ad09526 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -183,7 +183,7 @@ static inline int performance_multiplier(void) + + static DEFINE_PER_CPU(struct menu_device, menu_devices); + +-static void menu_update(struct cpuidle_device *dev); ++static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev); + + /* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */ + static u64 div_round64(u64 dividend, u32 divisor) +@@ -229,9 +229,10 @@ static void detect_repeating_patterns(struct menu_device *data) + + /** + * menu_select - selects the next idle state to enter ++ * @drv: cpuidle driver containing state data + * @dev: the CPU + */ +-static int menu_select(struct cpuidle_device *dev) ++static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) + { + struct menu_device *data = &__get_cpu_var(menu_devices); + int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); +@@ -241,7 +242,7 @@ static int menu_select(struct cpuidle_device *dev) + struct timespec t; + + if (data->needs_update) { +- menu_update(dev); ++ menu_update(drv, dev); + data->needs_update = 0; + } + +@@ -286,8 +287,8 @@ static int menu_select(struct cpuidle_device *dev) + * Find the idle state with the lowest power while satisfying + * our constraints. + */ +- for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++) { +- struct cpuidle_state *s = &dev->states[i]; ++ for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) { ++ struct cpuidle_state *s = &drv->states[i]; + + if (s->target_residency > data->predicted_us) + continue; +@@ -324,14 +325,15 @@ static void menu_reflect(struct cpuidle_device *dev, int index) + + /** + * menu_update - attempts to guess what happened after entry ++ * @drv: cpuidle driver containing state data + * @dev: the CPU + */ +-static void menu_update(struct cpuidle_device *dev) ++static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) + { + struct menu_device *data = &__get_cpu_var(menu_devices); + int last_idx = data->last_state_idx; + unsigned int last_idle_us = cpuidle_get_last_residency(dev); +- struct cpuidle_state *target = &dev->states[last_idx]; ++ struct cpuidle_state *target = &drv->states[last_idx]; + unsigned int measured_us; + u64 new_factor; + +@@ -385,9 +387,11 @@ static void menu_update(struct cpuidle_device *dev) + + /** + * menu_enable_device - scans a CPU's states and does setup ++ * @drv: cpuidle driver + * @dev: the CPU + */ +-static int menu_enable_device(struct cpuidle_device *dev) ++static int menu_enable_device(struct cpuidle_driver *drv, ++ struct cpuidle_device *dev) + { + struct menu_device *data = &per_cpu(menu_devices, dev->cpu); + +diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c +index 8a1ace1..1e756e1 100644 +--- a/drivers/cpuidle/sysfs.c ++++ b/drivers/cpuidle/sysfs.c +@@ -322,13 +322,14 @@ int cpuidle_add_state_sysfs(struct cpuidle_device *device) + { + int i, ret = -ENOMEM; + struct cpuidle_state_kobj *kobj; ++ struct cpuidle_driver *drv = cpuidle_get_driver(); + + /* state statistics */ + for (i = 0; i < device->state_count; i++) { + kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL); + if (!kobj) + goto error_state; +- kobj->state = &device->states[i]; ++ kobj->state = &drv->states[i]; + kobj->state_usage = &device->states_usage[i]; + init_completion(&kobj->kobj_unregister); + +diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c +index b0c63e9..1f122c6 100644 +--- a/drivers/idle/intel_idle.c ++++ b/drivers/idle/intel_idle.c +@@ -81,7 +81,8 @@ static unsigned int mwait_substates; + static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */ + + static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; +-static int intel_idle(struct cpuidle_device *dev, int index); ++static int intel_idle(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index); + + static struct cpuidle_state *cpuidle_state_table; + +@@ -227,13 +228,15 @@ static int get_driver_data(int cstate) + /** + * intel_idle + * @dev: cpuidle_device ++ * @drv: cpuidle driver + * @index: index of cpuidle state + * + */ +-static int intel_idle(struct cpuidle_device *dev, int index) ++static int intel_idle(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index) + { + unsigned long ecx = 1; /* break on interrupt flag */ +- struct cpuidle_state *state = &dev->states[index]; ++ struct cpuidle_state *state = &drv->states[index]; + struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; + unsigned long eax = (unsigned long)cpuidle_get_statedata(state_usage); + unsigned int cstate; +@@ -421,6 +424,60 @@ static void intel_idle_cpuidle_devices_uninit(void) + return; + } + /* ++ * intel_idle_cpuidle_driver_init() ++ * allocate, initialize cpuidle_states ++ */ ++static int intel_idle_cpuidle_driver_init(void) ++{ ++ int cstate; ++ struct cpuidle_driver *drv = &intel_idle_driver; ++ ++ drv->state_count = 1; ++ ++ for (cstate = 1; cstate < MWAIT_MAX_NUM_CSTATES; ++cstate) { ++ int num_substates; ++ ++ if (cstate > max_cstate) { ++ printk(PREFIX "max_cstate %d reached\n", ++ max_cstate); ++ break; ++ } ++ ++ /* does the state exist in CPUID.MWAIT? */ ++ num_substates = (mwait_substates >> ((cstate) * 4)) ++ & MWAIT_SUBSTATE_MASK; ++ if (num_substates == 0) ++ continue; ++ /* is the state not enabled? */ ++ if (cpuidle_state_table[cstate].enter == NULL) { ++ /* does the driver not know about the state? */ ++ if (*cpuidle_state_table[cstate].name == '\0') ++ pr_debug(PREFIX "unaware of model 0x%x" ++ " MWAIT %d please" ++ " contact lenb@kernel.org", ++ boot_cpu_data.x86_model, cstate); ++ continue; ++ } ++ ++ if ((cstate > 2) && ++ !boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) ++ mark_tsc_unstable("TSC halts in idle" ++ " states deeper than C2"); ++ ++ drv->states[drv->state_count] = /* structure copy */ ++ cpuidle_state_table[cstate]; ++ ++ drv->state_count += 1; ++ } ++ ++ if (auto_demotion_disable_flags) ++ smp_call_function(auto_demotion_disable, NULL, 1); ++ ++ return 0; ++} ++ ++ ++/* + * intel_idle_cpuidle_devices_init() + * allocate, initialize, register cpuidle_devices + */ +@@ -454,23 +511,9 @@ static int intel_idle_cpuidle_devices_init(void) + continue; + /* is the state not enabled? */ + if (cpuidle_state_table[cstate].enter == NULL) { +- /* does the driver not know about the state? */ +- if (*cpuidle_state_table[cstate].name == '\0') +- pr_debug(PREFIX "unaware of model 0x%x" +- " MWAIT %d please" +- " contact lenb@kernel.org", +- boot_cpu_data.x86_model, cstate); + continue; + } + +- if ((cstate > 2) && +- !boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) +- mark_tsc_unstable("TSC halts in idle" +- " states deeper than C2"); +- +- dev->states[dev->state_count] = /* structure copy */ +- cpuidle_state_table[cstate]; +- + dev->states_usage[dev->state_count].driver_data = + (void *)get_driver_data(cstate); + +@@ -485,8 +528,6 @@ static int intel_idle_cpuidle_devices_init(void) + return -EIO; + } + } +- if (auto_demotion_disable_flags) +- on_each_cpu(auto_demotion_disable, NULL, 1); + + return 0; + } +@@ -504,6 +545,7 @@ static int __init intel_idle_init(void) + if (retval) + return retval; + ++ intel_idle_cpuidle_driver_init(); + retval = cpuidle_register_driver(&intel_idle_driver); + if (retval) { + printk(KERN_DEBUG PREFIX "intel_idle yielding to %s", +diff --git a/include/acpi/processor.h b/include/acpi/processor.h +index ba4928c..716e97b 100644 +--- a/include/acpi/processor.h ++++ b/include/acpi/processor.h +@@ -329,6 +329,7 @@ extern void acpi_processor_throttling_init(void); + int acpi_processor_power_init(struct acpi_processor *pr, + struct acpi_device *device); + int acpi_processor_cst_has_changed(struct acpi_processor *pr); ++int acpi_processor_hotplug(struct acpi_processor *pr); + int acpi_processor_power_exit(struct acpi_processor *pr, + struct acpi_device *device); + int acpi_processor_suspend(struct acpi_device * device, pm_message_t state); +diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h +index 0156540..c904188 100644 +--- a/include/linux/cpuidle.h ++++ b/include/linux/cpuidle.h +@@ -22,6 +22,7 @@ + #define CPUIDLE_DESC_LEN 32 + + struct cpuidle_device; ++struct cpuidle_driver; + + + /**************************** +@@ -45,6 +46,7 @@ struct cpuidle_state { + unsigned int target_residency; /* in US */ + + int (*enter) (struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, + int index); + }; + +@@ -83,12 +85,10 @@ struct cpuidle_state_kobj { + struct cpuidle_device { + unsigned int registered:1; + unsigned int enabled:1; +- unsigned int power_specified:1; + unsigned int cpu; + + int last_residency; + int state_count; +- struct cpuidle_state states[CPUIDLE_STATE_MAX]; + struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX]; + struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; + +@@ -96,7 +96,6 @@ struct cpuidle_device { + struct kobject kobj; + struct completion kobj_unregister; + void *governor_data; +- int safe_state_index; + }; + + DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices); +@@ -120,6 +119,11 @@ static inline int cpuidle_get_last_residency(struct cpuidle_device *dev) + struct cpuidle_driver { + char name[CPUIDLE_NAME_LEN]; + struct module *owner; ++ ++ unsigned int power_specified:1; ++ struct cpuidle_state states[CPUIDLE_STATE_MAX]; ++ int state_count; ++ int safe_state_index; + }; + + #ifdef CONFIG_CPU_IDLE +@@ -166,10 +170,13 @@ struct cpuidle_governor { + struct list_head governor_list; + unsigned int rating; + +- int (*enable) (struct cpuidle_device *dev); +- void (*disable) (struct cpuidle_device *dev); ++ int (*enable) (struct cpuidle_driver *drv, ++ struct cpuidle_device *dev); ++ void (*disable) (struct cpuidle_driver *drv, ++ struct cpuidle_device *dev); + +- int (*select) (struct cpuidle_device *dev); ++ int (*select) (struct cpuidle_driver *drv, ++ struct cpuidle_device *dev); + void (*reflect) (struct cpuidle_device *dev, int index); + + struct module *owner; +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0046-cpuidle-Add-common-time-keeping-and-irq-enabling.patch b/patches.kzm9g/0046-cpuidle-Add-common-time-keeping-and-irq-enabling.patch new file mode 100644 index 00000000000000..6e6e73f5646766 --- /dev/null +++ b/patches.kzm9g/0046-cpuidle-Add-common-time-keeping-and-irq-enabling.patch @@ -0,0 +1,285 @@ +From 578cf9ddd7dd3eee538113c2824ddfe3ca0b9857 Mon Sep 17 00:00:00 2001 +From: Robert Lee <rob.lee@linaro.org> +Date: Tue, 20 Mar 2012 15:22:42 -0500 +Subject: cpuidle: Add common time keeping and irq enabling + +Make necessary changes to implement time keeping and irq enabling +in the core cpuidle code. This will allow the removal of these +functionalities from various platform cpuidle implementations whose +timekeeping and irq enabling follows the form in this common code. + +Signed-off-by: Robert Lee <rob.lee@linaro.org> +Tested-by: Jean Pihet <j-pihet@ti.com> +Tested-by: Amit Daniel <amit.kachhap@linaro.org> +Tested-by: Robert Lee <rob.lee@linaro.org> +Reviewed-by: Kevin Hilman <khilman@ti.com> +Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org> +Reviewed-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> +Acked-by: Jean Pihet <j-pihet@ti.com> +Signed-off-by: Len Brown <len.brown@intel.com> +(cherry picked from commit e1689795a784a7c41ac4cf9032794986b095a133) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/include/asm/cpuidle.h | 29 ++++++++++++++++++ + arch/arm/kernel/Makefile | 2 +- + arch/arm/kernel/cpuidle.c | 21 +++++++++++++ + drivers/cpuidle/cpuidle.c | 66 +++++++++++++++++++++++++++++++++++----- + include/linux/cpuidle.h | 13 +++++++- + 5 files changed, 122 insertions(+), 9 deletions(-) + create mode 100644 arch/arm/include/asm/cpuidle.h + create mode 100644 arch/arm/kernel/cpuidle.c + +diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h +new file mode 100644 +index 0000000..2fca60a +--- /dev/null ++++ b/arch/arm/include/asm/cpuidle.h +@@ -0,0 +1,29 @@ ++#ifndef __ASM_ARM_CPUIDLE_H ++#define __ASM_ARM_CPUIDLE_H ++ ++#ifdef CONFIG_CPU_IDLE ++extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index); ++#else ++static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index) { return -ENODEV; } ++#endif ++ ++/* Common ARM WFI state */ ++#define ARM_CPUIDLE_WFI_STATE_PWR(p) {\ ++ .enter = arm_cpuidle_simple_enter,\ ++ .exit_latency = 1,\ ++ .target_residency = 1,\ ++ .power_usage = p,\ ++ .flags = CPUIDLE_FLAG_TIME_VALID,\ ++ .name = "WFI",\ ++ .desc = "ARM WFI",\ ++} ++ ++/* ++ * in case power_specified == 1, give a default WFI power value needed ++ * by some governors ++ */ ++#define ARM_CPUIDLE_WFI_STATE ARM_CPUIDLE_WFI_STATE_PWR(UINT_MAX) ++ ++#endif +diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile +index 816a481..086fe97 100644 +--- a/arch/arm/kernel/Makefile ++++ b/arch/arm/kernel/Makefile +@@ -21,7 +21,7 @@ obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o + + obj-$(CONFIG_LEDS) += leds.o + obj-$(CONFIG_OC_ETM) += etm.o +- ++obj-$(CONFIG_CPU_IDLE) += cpuidle.o + obj-$(CONFIG_ISA_DMA_API) += dma.o + obj-$(CONFIG_ARCH_ACORN) += ecard.o + obj-$(CONFIG_FIQ) += fiq.o fiqasm.o +diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c +new file mode 100644 +index 0000000..89545f6 +--- /dev/null ++++ b/arch/arm/kernel/cpuidle.c +@@ -0,0 +1,21 @@ ++/* ++ * Copyright 2012 Linaro Ltd. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include <linux/cpuidle.h> ++#include <asm/proc-fns.h> ++ ++int arm_cpuidle_simple_enter(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index) ++{ ++ cpu_do_idle(); ++ ++ return index; ++} +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index 06ce268..3d3bd98 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -53,6 +53,24 @@ static void cpuidle_kick_cpus(void) {} + + static int __cpuidle_register_device(struct cpuidle_device *dev); + ++static inline int cpuidle_enter(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index) ++{ ++ struct cpuidle_state *target_state = &drv->states[index]; ++ return target_state->enter(dev, drv, index); ++} ++ ++static inline int cpuidle_enter_tk(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index) ++{ ++ return cpuidle_wrap_enter(dev, drv, index, cpuidle_enter); ++} ++ ++typedef int (*cpuidle_enter_t)(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index); ++ ++static cpuidle_enter_t cpuidle_enter_ops; ++ + /** + * cpuidle_idle_call - the main idle loop + * +@@ -63,7 +81,6 @@ int cpuidle_idle_call(void) + { + struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); + struct cpuidle_driver *drv = cpuidle_get_driver(); +- struct cpuidle_state *target_state; + int next_state, entered_state; + + if (off) +@@ -92,12 +109,10 @@ int cpuidle_idle_call(void) + return 0; + } + +- target_state = &drv->states[next_state]; +- + trace_power_start(POWER_CSTATE, next_state, dev->cpu); + trace_cpu_idle(next_state, dev->cpu); + +- entered_state = target_state->enter(dev, drv, next_state); ++ entered_state = cpuidle_enter_ops(dev, drv, next_state); + + trace_power_end(dev->cpu); + trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu); +@@ -110,6 +125,8 @@ int cpuidle_idle_call(void) + dev->states_usage[entered_state].time += + (unsigned long long)dev->last_residency; + dev->states_usage[entered_state].usage++; ++ } else { ++ dev->last_residency = 0; + } + + /* give the governor an opportunity to reflect on the outcome */ +@@ -164,6 +181,37 @@ void cpuidle_resume_and_unlock(void) + + EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); + ++/** ++ * cpuidle_wrap_enter - performs timekeeping and irqen around enter function ++ * @dev: pointer to a valid cpuidle_device object ++ * @drv: pointer to a valid cpuidle_driver object ++ * @index: index of the target cpuidle state. ++ */ ++int cpuidle_wrap_enter(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index, ++ int (*enter)(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index)) ++{ ++ ktime_t time_start, time_end; ++ s64 diff; ++ ++ time_start = ktime_get(); ++ ++ index = enter(dev, drv, index); ++ ++ time_end = ktime_get(); ++ ++ local_irq_enable(); ++ ++ diff = ktime_to_us(ktime_sub(time_end, time_start)); ++ if (diff > INT_MAX) ++ diff = INT_MAX; ++ ++ dev->last_residency = (int) diff; ++ ++ return index; ++} ++ + #ifdef CONFIG_ARCH_HAS_CPU_RELAX + static int poll_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +@@ -212,10 +260,11 @@ static void poll_idle_init(struct cpuidle_driver *drv) {} + int cpuidle_enable_device(struct cpuidle_device *dev) + { + int ret, i; ++ struct cpuidle_driver *drv = cpuidle_get_driver(); + + if (dev->enabled) + return 0; +- if (!cpuidle_get_driver() || !cpuidle_curr_governor) ++ if (!drv || !cpuidle_curr_governor) + return -EIO; + if (!dev->state_count) + return -EINVAL; +@@ -226,13 +275,16 @@ int cpuidle_enable_device(struct cpuidle_device *dev) + return ret; + } + +- poll_idle_init(cpuidle_get_driver()); ++ cpuidle_enter_ops = drv->en_core_tk_irqen ? ++ cpuidle_enter_tk : cpuidle_enter; ++ ++ poll_idle_init(drv); + + if ((ret = cpuidle_add_state_sysfs(dev))) + return ret; + + if (cpuidle_curr_governor->enable && +- (ret = cpuidle_curr_governor->enable(cpuidle_get_driver(), dev))) ++ (ret = cpuidle_curr_governor->enable(drv, dev))) + goto fail_sysfs; + + for (i = 0; i < dev->state_count; i++) { +diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h +index c904188..fd11aa0 100644 +--- a/include/linux/cpuidle.h ++++ b/include/linux/cpuidle.h +@@ -16,6 +16,7 @@ + #include <linux/module.h> + #include <linux/kobject.h> + #include <linux/completion.h> ++#include <linux/hrtimer.h> + + #define CPUIDLE_STATE_MAX 8 + #define CPUIDLE_NAME_LEN 16 +@@ -121,6 +122,8 @@ struct cpuidle_driver { + struct module *owner; + + unsigned int power_specified:1; ++ /* set to 1 to use the core cpuidle time keeping (for all states). */ ++ unsigned int en_core_tk_irqen:1; + struct cpuidle_state states[CPUIDLE_STATE_MAX]; + int state_count; + int safe_state_index; +@@ -140,7 +143,10 @@ extern void cpuidle_pause_and_lock(void); + extern void cpuidle_resume_and_unlock(void); + extern int cpuidle_enable_device(struct cpuidle_device *dev); + extern void cpuidle_disable_device(struct cpuidle_device *dev); +- ++extern int cpuidle_wrap_enter(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index, ++ int (*enter)(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index)); + #else + static inline void disable_cpuidle(void) { } + static inline int cpuidle_idle_call(void) { return -ENODEV; } +@@ -158,6 +164,11 @@ static inline void cpuidle_resume_and_unlock(void) { } + static inline int cpuidle_enable_device(struct cpuidle_device *dev) + {return -ENODEV; } + static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } ++static inline int cpuidle_wrap_enter(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index, ++ int (*enter)(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index)) ++{ return -ENODEV; } + + #endif + +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0047-mm-add-vm_area_add_early.patch b/patches.kzm9g/0047-mm-add-vm_area_add_early.patch new file mode 100644 index 00000000000000..6e00e80e95e5ae --- /dev/null +++ b/patches.kzm9g/0047-mm-add-vm_area_add_early.patch @@ -0,0 +1,92 @@ +From faf323f0f552c0523cce81cf62b87a87b3eb0020 Mon Sep 17 00:00:00 2001 +From: Nicolas Pitre <nicolas.pitre@linaro.org> +Date: Thu, 25 Aug 2011 00:24:21 -0400 +Subject: mm: add vm_area_add_early() + +The existing vm_area_register_early() allows for early vmalloc space +allocation. However upcoming cleanups in the ARM architecture require +that some fixed locations in the vmalloc area be reserved also very early. + +The name "vm_area_register_early" would have been a good name for the +reservation part without the allocation. Since it is already in use with +different semantics, let's create vm_area_add_early() instead. + +Both vm_area_register_early() and vm_area_add_early() can be used together +meaning that the former is now implemented using the later where it is +ensured that no conflicting areas are added, but no attempt is made to +make the allocation scheme in vm_area_register_early() more sophisticated. +After all, you must know what you're doing when using those functions. + +Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org> +Acked-by: Andrew Morton <akpm@linux-foundation.org> +Cc: linux-mm@kvack.org +(cherry picked from commit be9b7335e70696bee731c152429b1737e42fe163) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + include/linux/vmalloc.h | 1 + + mm/vmalloc.c | 29 +++++++++++++++++++++++++++-- + 2 files changed, 28 insertions(+), 2 deletions(-) + +diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h +index 687fb11..4115d6a 100644 +--- a/include/linux/vmalloc.h ++++ b/include/linux/vmalloc.h +@@ -131,6 +131,7 @@ extern long vwrite(char *buf, char *addr, unsigned long count); + */ + extern rwlock_t vmlist_lock; + extern struct vm_struct *vmlist; ++extern __init void vm_area_add_early(struct vm_struct *vm); + extern __init void vm_area_register_early(struct vm_struct *vm, size_t align); + + #ifdef CONFIG_SMP +diff --git a/mm/vmalloc.c b/mm/vmalloc.c +index 43b44db..fb0d354 100644 +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -1132,6 +1132,32 @@ void *vm_map_ram(struct page **pages, unsigned int count, int node, pgprot_t pro + EXPORT_SYMBOL(vm_map_ram); + + /** ++ * vm_area_add_early - add vmap area early during boot ++ * @vm: vm_struct to add ++ * ++ * This function is used to add fixed kernel vm area to vmlist before ++ * vmalloc_init() is called. @vm->addr, @vm->size, and @vm->flags ++ * should contain proper values and the other fields should be zero. ++ * ++ * DO NOT USE THIS FUNCTION UNLESS YOU KNOW WHAT YOU'RE DOING. ++ */ ++void __init vm_area_add_early(struct vm_struct *vm) ++{ ++ struct vm_struct *tmp, **p; ++ ++ BUG_ON(vmap_initialized); ++ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next) { ++ if (tmp->addr >= vm->addr) { ++ BUG_ON(tmp->addr < vm->addr + vm->size); ++ break; ++ } else ++ BUG_ON(tmp->addr + tmp->size > vm->addr); ++ } ++ vm->next = *p; ++ *p = vm; ++} ++ ++/** + * vm_area_register_early - register vmap area early during boot + * @vm: vm_struct to register + * @align: requested alignment +@@ -1153,8 +1179,7 @@ void __init vm_area_register_early(struct vm_struct *vm, size_t align) + + vm->addr = (void *)addr; + +- vm->next = vmlist; +- vmlist = vm; ++ vm_area_add_early(vm); + } + + void __init vmalloc_init(void) +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0048-clockevents-Make-clockevents_config-a-global-symbol.patch b/patches.kzm9g/0048-clockevents-Make-clockevents_config-a-global-symbol.patch new file mode 100644 index 00000000000000..c276f9f29d3b24 --- /dev/null +++ b/patches.kzm9g/0048-clockevents-Make-clockevents_config-a-global-symbol.patch @@ -0,0 +1,46 @@ +From fff14be80697fd2ad8584769e60a24f97ba0a704 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 9 May 2012 23:39:34 +0900 +Subject: clockevents: Make clockevents_config() a global symbol + +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> +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + 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 d6733e2..91d1b67 100644 +--- a/include/linux/clockchips.h ++++ b/include/linux/clockchips.h +@@ -128,6 +128,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 e4c699d..1029cbc 100644 +--- a/kernel/time/clockevents.c ++++ b/kernel/time/clockevents.c +@@ -197,8 +197,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.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0049-clocksource-em_sti-Emma-Mobile-STI-driver-V2.patch b/patches.kzm9g/0049-clocksource-em_sti-Emma-Mobile-STI-driver-V2.patch new file mode 100644 index 00000000000000..826ec8002d1011 --- /dev/null +++ b/patches.kzm9g/0049-clocksource-em_sti-Emma-Mobile-STI-driver-V2.patch @@ -0,0 +1,484 @@ +From c97faaf620983062ebff15fd4db3f341a8e224b2 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 9 May 2012 23:39:42 +0900 +Subject: clocksource: em_sti: Emma Mobile STI driver V2 + +This is V2 of the Emma Mobile STI timer driver. + +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 periodic or oneshot modes. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms@verge.net.au> + +Conflicts: + drivers/clocksource/Makefile +--- + arch/arm/mach-shmobile/Kconfig | 6 + + drivers/clocksource/Makefile | 1 + + drivers/clocksource/em_sti.c | 418 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 425 insertions(+) + create mode 100644 drivers/clocksource/em_sti.c + +diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig +index 9020c1b..1e7656a 100644 +--- a/arch/arm/mach-shmobile/Kconfig ++++ b/arch/arm/mach-shmobile/Kconfig +@@ -147,6 +147,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 +diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile +index b995942..59eb37d 100644 +--- a/drivers/clocksource/Makefile ++++ b/drivers/clocksource/Makefile +@@ -6,5 +6,6 @@ obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o + 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_CLKSRC_I8253) += i8253.o + obj-$(CONFIG_CLKSRC_MMIO) += mmio.o +diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c +new file mode 100644 +index 0000000..e8fc46d +--- /dev/null ++++ b/drivers/clocksource/em_sti.c +@@ -0,0 +1,418 @@ ++/* ++ * 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; ++ unsigned long delta; ++ cycle_t next; ++ 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. ++ */ ++ 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); ++ spin_unlock_irqrestore(&p->lock, flags); ++ ++ return ticks; ++} ++ ++static void em_sti_update(struct em_sti_priv *p) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&p->lock, flags); ++ ++ /* update our cached counter */ ++ p->next += p->delta; ++ ++ /* mask compare A interrupt */ ++ em_sti_write(p, STI_INTENCLR, 1); ++ ++ /* update compare A value */ ++ em_sti_write(p, STI_COMPA_H, p->next >> 32); ++ em_sti_write(p, STI_COMPA_L, p->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); ++ ++ spin_unlock_irqrestore(&p->lock, flags); ++} ++ ++static irqreturn_t em_sti_interrupt(int irq, void *dev_id) ++{ ++ struct em_sti_priv *p = dev_id; ++ ++ /* Always regprogram timer compare A */ ++ if (p->ced.mode == CLOCK_EVT_MODE_PERIODIC) ++ em_sti_update(p); ++ ++ 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; ++ ++ 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; ++ 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; ++ ++ 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); ++ 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_PERIODIC: ++ case CLOCK_EVT_MODE_ONESHOT: ++ em_sti_stop(p, USER_CLOCKEVENT); ++ break; ++ default: ++ break; ++ } ++ ++ switch (mode) { ++ case CLOCK_EVT_MODE_PERIODIC: ++ dev_info(&p->pdev->dev, "used for periodic clock events\n"); ++ em_sti_start(p, USER_CLOCKEVENT); ++ clockevents_config(&p->ced, p->rate); ++ p->delta = (p->rate + HZ/2) / HZ; ++ p->next = em_sti_count(p); ++ em_sti_update(p); ++ break; ++ 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); ++ int safe; ++ ++ p->delta = delta; ++ p->next = em_sti_count(p); ++ em_sti_update(p); ++ ++ safe = em_sti_count(p) < (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_PERIODIC; ++ 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; ++ } ++ ++ 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"); +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0050-ARM-move-initialization-of-the-high_memory-variable-.patch b/patches.kzm9g/0050-ARM-move-initialization-of-the-high_memory-variable-.patch new file mode 100644 index 00000000000000..995ac0d9c826bd --- /dev/null +++ b/patches.kzm9g/0050-ARM-move-initialization-of-the-high_memory-variable-.patch @@ -0,0 +1,63 @@ +From 778219539dbd4ac7a63ab82fdba8b529e61f1aeb Mon Sep 17 00:00:00 2001 +From: Nicolas Pitre <nicolas.pitre@linaro.org> +Date: Sun, 18 Sep 2011 22:40:00 -0400 +Subject: ARM: move initialization of the high_memory variable earlier + +Some upcoming changes must know the VMALLOC_START value, which is based +on high_memory, before bootmem_init() is called. + +The best location to set it is in sanity_check_meminfo() where the needed +computation is already done, and in the non MMU case it is trivial to do +now that the meminfo array is already sorted at that point. + +Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org> +(cherry picked from commit 55a8173cfe1c6b489f8f5705282c762aed2e265e) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/mm/init.c | 2 -- + arch/arm/mm/mmu.c | 1 + + arch/arm/mm/nommu.c | 2 ++ + 3 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c +index db04a3e5..0530019 100644 +--- a/arch/arm/mm/init.c ++++ b/arch/arm/mm/init.c +@@ -391,8 +391,6 @@ void __init bootmem_init(void) + */ + arm_bootmem_free(min, max_low, max_high); + +- high_memory = __va(((phys_addr_t)max_low << PAGE_SHIFT) - 1) + 1; +- + /* + * This doesn't seem to be used by the Linux memory manager any + * more, but is used by ll_rw_block. If we can get rid of it, we +diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c +index 594d677..eefb8ed 100644 +--- a/arch/arm/mm/mmu.c ++++ b/arch/arm/mm/mmu.c +@@ -852,6 +852,7 @@ void __init sanity_check_meminfo(void) + } + #endif + meminfo.nr_banks = j; ++ high_memory = __va(lowmem_limit - 1) + 1; + memblock_set_current_limit(lowmem_limit); + } + +diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c +index 941a98c..9348730 100644 +--- a/arch/arm/mm/nommu.c ++++ b/arch/arm/mm/nommu.c +@@ -29,6 +29,8 @@ void __init arm_mm_memblock_reserve(void) + + void __init sanity_check_meminfo(void) + { ++ phys_addr_t end = bank_phys_end(&meminfo.bank[meminfo.nr_banks - 1]); ++ high_memory = __va(end - 1) + 1; + } + + /* +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0051-ARM-move-iotable-mappings-within-the-vmalloc-region.patch b/patches.kzm9g/0051-ARM-move-iotable-mappings-within-the-vmalloc-region.patch new file mode 100644 index 00000000000000..720421b0e5fa32 --- /dev/null +++ b/patches.kzm9g/0051-ARM-move-iotable-mappings-within-the-vmalloc-region.patch @@ -0,0 +1,207 @@ +From dbc2d5048de20169fff5e5c5032e89a4129cfc3b Mon Sep 17 00:00:00 2001 +From: Nicolas Pitre <nicolas.pitre@linaro.org> +Date: Thu, 25 Aug 2011 00:35:59 -0400 +Subject: ARM: move iotable mappings within the vmalloc region + +In order to remove the build time variation between different SOCs with +regards to VMALLOC_END, the iotable mappings are now allocated inside +the vmalloc region. This allows for VMALLOC_END to be identical across +all machines. + +The value for VMALLOC_END is now set to 0xff000000 which is right where +the consistent DMA area starts. + +To accommodate all static mappings on machines with possible highmem usage, +the default vmalloc area size is changed to 240 MB so that VMALLOC_START +is no higher than 0xf0000000 by default. + +Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org> +Tested-by: Stephen Warren <swarren@nvidia.com> +Tested-by: Kevin Hilman <khilman@ti.com> +Tested-by: Jamie Iles <jamie@jamieiles.com> +(cherry picked from commit 0536bdf33faff4d940ac094c77998cfac368cfff) + +Conflicts: + arch/arm/mm/mmu.c + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + Documentation/arm/memory.txt | 11 ++++----- + arch/arm/include/asm/pgtable.h | 8 +------ + arch/arm/mm/mmu.c | 49 ++++++++++++++++++++++++++++------------ + 3 files changed, 41 insertions(+), 27 deletions(-) + +diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt +index 771d48d..208a2d4 100644 +--- a/Documentation/arm/memory.txt ++++ b/Documentation/arm/memory.txt +@@ -51,15 +51,14 @@ ffc00000 ffefffff DMA memory mapping region. Memory returned + ff000000 ffbfffff Reserved for future expansion of DMA + mapping region. + +-VMALLOC_END feffffff Free for platform use, recommended. +- VMALLOC_END must be aligned to a 2MB +- boundary. +- + VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space. + Memory returned by vmalloc/ioremap will + be dynamically placed in this region. +- VMALLOC_START may be based upon the value +- of the high_memory variable. ++ Machine specific static mappings are also ++ located here through iotable_init(). ++ VMALLOC_START is based upon the value ++ of the high_memory variable, and VMALLOC_END ++ is equal to 0xff000000. + + PAGE_OFFSET high_memory-1 Kernel direct-mapped RAM region. + This maps the platforms RAM, and typically +diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h +index 5750704..950dee3 100644 +--- a/arch/arm/include/asm/pgtable.h ++++ b/arch/arm/include/asm/pgtable.h +@@ -21,7 +21,6 @@ + #else + + #include <asm/memory.h> +-#include <mach/vmalloc.h> + #include <asm/pgtable-hwdef.h> + + /* +@@ -31,15 +30,10 @@ + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) +- * +- * Note that platforms may override VMALLOC_START, but they must provide +- * VMALLOC_END. VMALLOC_END defines the (exclusive) limit of this space, +- * which may not overlap IO space. + */ +-#ifndef VMALLOC_START + #define VMALLOC_OFFSET (8*1024*1024) + #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +-#endif ++#define VMALLOC_END 0xff000000UL + + /* + * Hardware-wise, we have a two level page table structure, where the first +diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c +index eefb8ed..6a98c4a 100644 +--- a/arch/arm/mm/mmu.c ++++ b/arch/arm/mm/mmu.c +@@ -15,6 +15,7 @@ + #include <linux/nodemask.h> + #include <linux/memblock.h> + #include <linux/fs.h> ++#include <linux/vmalloc.h> + + #include <asm/cputype.h> + #include <asm/sections.h> +@@ -521,13 +522,18 @@ EXPORT_SYMBOL(phys_mem_access_prot); + + #define vectors_base() (vectors_high() ? 0xffff0000 : 0) + +-static void __init *early_alloc(unsigned long sz) ++static void __init *early_alloc_aligned(unsigned long sz, unsigned long align) + { +- void *ptr = __va(memblock_alloc(sz, sz)); ++ void *ptr = __va(memblock_alloc(sz, align)); + memset(ptr, 0, sz); + return ptr; + } + ++static void __init *early_alloc(unsigned long sz) ++{ ++ return early_alloc_aligned(sz, sz); ++} ++ + static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot) + { + if (pmd_none(*pmd)) { +@@ -677,9 +683,10 @@ static void __init create_mapping(struct map_desc *md) + } + + if ((md->type == MT_DEVICE || md->type == MT_ROM) && +- md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { ++ md->virtual >= PAGE_OFFSET && ++ (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) { + printk(KERN_WARNING "BUG: mapping for 0x%08llx" +- " at 0x%08lx overlaps vmalloc space\n", ++ " at 0x%08lx out of vmalloc space\n", + (long long)__pfn_to_phys((u64)md->pfn), md->virtual); + } + +@@ -721,18 +728,32 @@ static void __init create_mapping(struct map_desc *md) + */ + void __init iotable_init(struct map_desc *io_desc, int nr) + { +- int i; ++ struct map_desc *md; ++ struct vm_struct *vm; ++ ++ if (!nr) ++ return; + +- for (i = 0; i < nr; i++) +- create_mapping(io_desc + i); ++ vm = early_alloc_aligned(sizeof(*vm) * nr, __alignof__(*vm)); ++ ++ for (md = io_desc; nr; md++, nr--) { ++ create_mapping(md); ++ vm->addr = (void *)(md->virtual & PAGE_MASK); ++ vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); ++ vm->phys_addr = __pfn_to_phys(md->pfn); ++ vm->flags = VM_IOREMAP; ++ vm->caller = iotable_init; ++ vm_area_add_early(vm++); ++ } + } + +-static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_128M); ++static void * __initdata vmalloc_min = ++ (void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET); + + /* + * vmalloc=size forces the vmalloc area to be exactly 'size' + * bytes. This can be used to increase (or decrease) the vmalloc +- * area - the default is 128m. ++ * area - the default is 240m. + */ + static int __init early_vmalloc(char *arg) + { +@@ -883,10 +904,10 @@ static inline void prepare_page_table(void) + + /* + * Clear out all the kernel space mappings, except for the first +- * memory bank, up to the end of the vmalloc region. ++ * memory bank, up to the vmalloc region. + */ + for (addr = __phys_to_virt(end); +- addr < VMALLOC_END; addr += PGDIR_SIZE) ++ addr < VMALLOC_START; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + } + +@@ -911,8 +932,8 @@ void __init arm_mm_memblock_reserve(void) + } + + /* +- * Set up device the mappings. Since we clear out the page tables for all +- * mappings above VMALLOC_END, we will remove any debug device mappings. ++ * Set up the device mappings. Since we clear out the page tables for all ++ * mappings above VMALLOC_START, we will remove any debug device mappings. + * This means you have to be careful how you debug this function, or any + * called function. This means you can't use any function or debugging + * method which may touch any device, otherwise the kernel _will_ crash. +@@ -927,7 +948,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc) + */ + vectors_page = early_alloc(PAGE_SIZE); + +- for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) ++ for (addr = VMALLOC_START; addr; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + + /* +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0052-ARM-simplify-__iounmap-when-dealing-with-section-bas.patch b/patches.kzm9g/0052-ARM-simplify-__iounmap-when-dealing-with-section-bas.patch new file mode 100644 index 00000000000000..85b4c27b1b4d48 --- /dev/null +++ b/patches.kzm9g/0052-ARM-simplify-__iounmap-when-dealing-with-section-bas.patch @@ -0,0 +1,66 @@ +From 9c711a650671536e915cea3661fc7caa2a4ab487 Mon Sep 17 00:00:00 2001 +From: Nicolas Pitre <nicolas.pitre@linaro.org> +Date: Thu, 15 Sep 2011 22:12:19 -0400 +Subject: ARM: simplify __iounmap() when dealing with section based mapping + +Firstly, there is no need to have a double pointer here as we're only +walking the vmlist and not modifying it. + +Secondly, for the same reason, we don't need a write lock but only a +read lock here, since the lock only protects the coherency of the list +nothing else. + +Lastly, the reason for holding a lock is not what the comment says, so +let's remove that misleading piece of information. + +Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org> +(cherry picked from commit 6ee723a6570a897208b76ab3e9a495e9106b2f8c) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/mm/ioremap.c | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c +index ab50627..1ddcd8a 100644 +--- a/arch/arm/mm/ioremap.c ++++ b/arch/arm/mm/ioremap.c +@@ -293,26 +293,24 @@ void __iounmap(volatile void __iomem *io_addr) + { + void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr); + #ifndef CONFIG_SMP +- struct vm_struct **p, *tmp; ++ struct vm_struct *vm; + + /* + * If this is a section based mapping we need to handle it + * specially as the VM subsystem does not know how to handle +- * such a beast. We need the lock here b/c we need to clear +- * all the mappings before the area can be reclaimed +- * by someone else. ++ * such a beast. + */ +- write_lock(&vmlist_lock); +- for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) { +- if ((tmp->flags & VM_IOREMAP) && (tmp->addr == addr)) { +- if (tmp->flags & VM_ARM_SECTION_MAPPING) { +- unmap_area_sections((unsigned long)tmp->addr, +- tmp->size); ++ read_lock(&vmlist_lock); ++ for (vm = vmlist; vm; vm = vm->next) { ++ if ((vm->flags & VM_IOREMAP) && (vm->addr == addr)) { ++ if (vm->flags & VM_ARM_SECTION_MAPPING) { ++ unmap_area_sections((unsigned long)vm->addr, ++ vm->size); + } + break; + } + } +- write_unlock(&vmlist_lock); ++ read_unlock(&vmlist_lock); + #endif + + vunmap(addr); +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0053-ARM-add-generic-ioremap-optimization-by-reusing-stat.patch b/patches.kzm9g/0053-ARM-add-generic-ioremap-optimization-by-reusing-stat.patch new file mode 100644 index 00000000000000..1ecd497ee2d9bd --- /dev/null +++ b/patches.kzm9g/0053-ARM-add-generic-ioremap-optimization-by-reusing-stat.patch @@ -0,0 +1,177 @@ +From 5be0e66269ddfd8ca3dee6512e573b1f461a6faf Mon Sep 17 00:00:00 2001 +From: Nicolas Pitre <nicolas.pitre@linaro.org> +Date: Fri, 16 Sep 2011 01:14:23 -0400 +Subject: ARM: add generic ioremap optimization by reusing static mappings + +Now that we have all the static mappings from iotable_init() located +in the vmalloc area, it is trivial to optimize ioremap by reusing those +static mappings when the requested physical area fits in one of them, +and so in a generic way for all platforms. + +Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org> +Tested-by: Stephen Warren <swarren@nvidia.com> +Tested-by: Kevin Hilman <khilman@ti.com> +Tested-by: Jamie Iles <jamie@jamieiles.com> +(cherry picked from commit 576d2f2525612ecb5af029a76f21f22a3b82563d) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/mm/ioremap.c | 72 ++++++++++++++++++++++++++++++++----------------- + arch/arm/mm/mm.h | 14 ++++++++++ + arch/arm/mm/mmu.c | 3 ++- + 3 files changed, 64 insertions(+), 25 deletions(-) + +diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c +index 1ddcd8a..b5900f2 100644 +--- a/arch/arm/mm/ioremap.c ++++ b/arch/arm/mm/ioremap.c +@@ -36,12 +36,6 @@ + #include <asm/mach/map.h> + #include "mm.h" + +-/* +- * Used by ioremap() and iounmap() code to mark (super)section-mapped +- * I/O regions in vm_struct->flags field. +- */ +-#define VM_ARM_SECTION_MAPPING 0x80000000 +- + int ioremap_page(unsigned long virt, unsigned long phys, + const struct mem_type *mtype) + { +@@ -201,12 +195,6 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, + if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK)) + return NULL; + +- /* +- * Don't allow RAM to be mapped - this causes problems with ARMv6+ +- */ +- if (WARN_ON(pfn_valid(pfn))) +- return NULL; +- + type = get_mem_type(mtype); + if (!type) + return NULL; +@@ -216,6 +204,34 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, + */ + size = PAGE_ALIGN(offset + size); + ++ /* ++ * Try to reuse one of the static mapping whenever possible. ++ */ ++ read_lock(&vmlist_lock); ++ for (area = vmlist; area; area = area->next) { ++ if (!size || (sizeof(phys_addr_t) == 4 && pfn >= 0x100000)) ++ break; ++ if (!(area->flags & VM_ARM_STATIC_MAPPING)) ++ continue; ++ if ((area->flags & VM_ARM_MTYPE_MASK) != VM_ARM_MTYPE(mtype)) ++ continue; ++ if (__phys_to_pfn(area->phys_addr) > pfn || ++ __pfn_to_phys(pfn) + size-1 > area->phys_addr + area->size-1) ++ continue; ++ /* we can drop the lock here as we know *area is static */ ++ read_unlock(&vmlist_lock); ++ addr = (unsigned long)area->addr; ++ addr += __pfn_to_phys(pfn) - area->phys_addr; ++ return (void __iomem *) (offset + addr); ++ } ++ read_unlock(&vmlist_lock); ++ ++ /* ++ * Don't allow RAM to be mapped - this causes problems with ARMv6+ ++ */ ++ if (WARN_ON(pfn_valid(pfn))) ++ return NULL; ++ + area = get_vm_area_caller(size, VM_IOREMAP, caller); + if (!area) + return NULL; +@@ -292,26 +308,34 @@ EXPORT_SYMBOL(__arm_ioremap); + void __iounmap(volatile void __iomem *io_addr) + { + void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr); +-#ifndef CONFIG_SMP + struct vm_struct *vm; + +- /* +- * If this is a section based mapping we need to handle it +- * specially as the VM subsystem does not know how to handle +- * such a beast. +- */ + read_lock(&vmlist_lock); + for (vm = vmlist; vm; vm = vm->next) { +- if ((vm->flags & VM_IOREMAP) && (vm->addr == addr)) { +- if (vm->flags & VM_ARM_SECTION_MAPPING) { +- unmap_area_sections((unsigned long)vm->addr, +- vm->size); +- } ++ if (vm->addr > addr) + break; ++ if (!(vm->flags & VM_IOREMAP)) ++ continue; ++ /* If this is a static mapping we must leave it alone */ ++ if ((vm->flags & VM_ARM_STATIC_MAPPING) && ++ (vm->addr <= addr) && (vm->addr + vm->size > addr)) { ++ read_unlock(&vmlist_lock); ++ return; + } ++#ifndef CONFIG_SMP ++ /* ++ * If this is a section based mapping we need to handle it ++ * specially as the VM subsystem does not know how to handle ++ * such a beast. ++ */ ++ if ((vm->addr == addr) && ++ (vm->flags & VM_ARM_SECTION_MAPPING)) { ++ unmap_area_sections((unsigned long)vm->addr, vm->size); ++ break; ++ } ++#endif + } + read_unlock(&vmlist_lock); +-#endif + + vunmap(addr); + } +diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h +index 5b3d7d5..26f3a2c 100644 +--- a/arch/arm/mm/mm.h ++++ b/arch/arm/mm/mm.h +@@ -21,6 +21,20 @@ const struct mem_type *get_mem_type(unsigned int type); + + extern void __flush_dcache_page(struct address_space *mapping, struct page *page); + ++/* ++ * ARM specific vm_struct->flags bits. ++ */ ++ ++/* (super)section-mapped I/O regions used by ioremap()/iounmap() */ ++#define VM_ARM_SECTION_MAPPING 0x80000000 ++ ++/* permanent static mappings from iotable_init() */ ++#define VM_ARM_STATIC_MAPPING 0x40000000 ++ ++/* mapping type (attributes) for permanent static mappings */ ++#define VM_ARM_MTYPE(mt) ((mt) << 20) ++#define VM_ARM_MTYPE_MASK (0x1f << 20) ++ + #endif + + void __init bootmem_init(void); +diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c +index 6a98c4a..ce0e427 100644 +--- a/arch/arm/mm/mmu.c ++++ b/arch/arm/mm/mmu.c +@@ -741,7 +741,8 @@ void __init iotable_init(struct map_desc *io_desc, int nr) + vm->addr = (void *)(md->virtual & PAGE_MASK); + vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); + vm->phys_addr = __pfn_to_phys(md->pfn); +- vm->flags = VM_IOREMAP; ++ vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING; ++ vm->flags |= VM_ARM_MTYPE(md->type); + vm->caller = iotable_init; + vm_area_add_early(vm++); + } +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0054-ARM-mach-shmobile-Introduce-shmobile_setup_delay.patch b/patches.kzm9g/0054-ARM-mach-shmobile-Introduce-shmobile_setup_delay.patch new file mode 100644 index 00000000000000..df4fe7b07a5135 --- /dev/null +++ b/patches.kzm9g/0054-ARM-mach-shmobile-Introduce-shmobile_setup_delay.patch @@ -0,0 +1,72 @@ +From 4db83a8c2af822cc5ae76ea212c7a77b20a637b5 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 28 Mar 2012 19:22:30 +0900 +Subject: ARM: mach-shmobile: Introduce shmobile_setup_delay() + +Add the function shmobile_setup_delay() to let platforms +configure their maximum loops per jiffy delay. With this +jiffies calculation done the dependency on early timer +is removed. + +In the future this allows us to assign timers +using the regular driver model via the device tree. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> +(cherry picked from commit 0f2c9f20e4e339de30cfd5613dfa9505e7b9c58b) + +Conflicts: + arch/arm/mach-shmobile/include/mach/common.h + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/mach-shmobile/include/mach/common.h | 2 ++ + arch/arm/mach-shmobile/timer.c | 17 +++++++++++++++++ + 2 files changed, 19 insertions(+) + +diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h +index c77b3a1..bc3aa3e 100644 +--- a/arch/arm/mach-shmobile/include/mach/common.h ++++ b/arch/arm/mach-shmobile/include/mach/common.h +@@ -3,6 +3,8 @@ + + extern void shmobile_earlytimer_init(void); + extern struct sys_timer shmobile_timer; ++extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz, ++ unsigned int mult, unsigned int div); + extern void shmobile_setup_console(void); + extern void shmobile_secondary_vector(void); + struct clk; +diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c +index be1ad70..b323e3c 100644 +--- a/arch/arm/mach-shmobile/timer.c ++++ b/arch/arm/mach-shmobile/timer.c +@@ -19,8 +19,25 @@ + * + */ + #include <linux/platform_device.h> ++#include <linux/delay.h> + #include <asm/mach/time.h> + ++void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz, ++ unsigned int mult, unsigned int div) ++{ ++ /* calculate a worst-case loops-per-jiffy value ++ * based on maximum cpu core mhz setting and the ++ * __delay() implementation in arch/arm/lib/delay.S ++ * ++ * this will result in a longer delay than expected ++ * when the cpu core runs on lower frequencies. ++ */ ++ ++ unsigned int value = (1000000 * mult) / (HZ * div); ++ ++ lpj_fine = max_cpu_core_mhz * value; ++} ++ + static void __init shmobile_late_time_init(void) + { + /* +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0055-ARM-mach-shmobile-Allow-SoC-specific-CPU-kill-code.patch b/patches.kzm9g/0055-ARM-mach-shmobile-Allow-SoC-specific-CPU-kill-code.patch new file mode 100644 index 00000000000000..4c08f8fffb2b53 --- /dev/null +++ b/patches.kzm9g/0055-ARM-mach-shmobile-Allow-SoC-specific-CPU-kill-code.patch @@ -0,0 +1,67 @@ +From 05f453548b4b9fdf0ab8e36a15c9ef74b21f27e2 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 28 Dec 2011 16:47:16 +0900 +Subject: ARM: mach-shmobile: Allow SoC specific CPU kill code + +Add the function shmobile_platform_kill_cpu() to allow +SoC specific code to tie in their CPU shutdown code. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit 8b306796995609c281f6d32b3cbaa814551ad5ac) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/mach-shmobile/hotplug.c | 3 ++- + arch/arm/mach-shmobile/include/mach/common.h | 1 + + arch/arm/mach-shmobile/platsmp.c | 5 +++++ + 3 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/hotplug.c b/arch/arm/mach-shmobile/hotplug.c +index 238a0d9..aee3a10 100644 +--- a/arch/arm/mach-shmobile/hotplug.c ++++ b/arch/arm/mach-shmobile/hotplug.c +@@ -12,10 +12,11 @@ + #include <linux/kernel.h> + #include <linux/errno.h> + #include <linux/smp.h> ++#include <mach/common.h> + + int platform_cpu_kill(unsigned int cpu) + { +- return 1; ++ return shmobile_platform_cpu_kill(cpu); + } + + void platform_cpu_die(unsigned int cpu) +diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h +index bc3aa3e..8b88b80 100644 +--- a/arch/arm/mach-shmobile/include/mach/common.h ++++ b/arch/arm/mach-shmobile/include/mach/common.h +@@ -7,6 +7,7 @@ extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz, + unsigned int mult, unsigned int div); + extern void shmobile_setup_console(void); + extern void shmobile_secondary_vector(void); ++extern int shmobile_platform_cpu_kill(unsigned int cpu); + struct clk; + extern int shmobile_clk_init(void); + extern void shmobile_handle_irq_intc(struct pt_regs *); +diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c +index 2cc8930..1103ce5 100644 +--- a/arch/arm/mach-shmobile/platsmp.c ++++ b/arch/arm/mach-shmobile/platsmp.c +@@ -37,6 +37,11 @@ static void __init shmobile_smp_prepare_cpus(void) + sh73a0_smp_prepare_cpus(); + } + ++int shmobile_platform_cpu_kill(unsigned int cpu) ++{ ++ return 1; ++} ++ + void __cpuinit platform_secondary_init(unsigned int cpu) + { + trace_hardirqs_off(); +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0056-ARM-mach-shmobile-Use-preset_lpj-with-calibrate_dela.patch b/patches.kzm9g/0056-ARM-mach-shmobile-Use-preset_lpj-with-calibrate_dela.patch new file mode 100644 index 00000000000000..3b83af24fe5af5 --- /dev/null +++ b/patches.kzm9g/0056-ARM-mach-shmobile-Use-preset_lpj-with-calibrate_dela.patch @@ -0,0 +1,46 @@ +From 0d710173dcca9b9e7c5ec0ddf109e9bbaa6d4a79 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 10 May 2012 00:37:48 +0200 +Subject: ARM / mach-shmobile: Use preset_lpj with calibrate_delay() + +Update the mach-shmobile shared delay calibration code for late +timers. All existing in-tree non-DT socs are however using early +timers today and they are unaffected by this change. + +The patch modifies shmobile_setup_delay() from using lpj_fine +to preset_lpj. This change allows us to preset the worst case +loops-per-jiffy value to all CPU cores on the system. + +The old code which made use of lpj_fine did not affect the +secondary CPU cores which made it impossible to boot on SMP +without early timers. + +Needed for SMP SoCs using late timers like EMEV2 or any other +mach-shmobile SMP SoC that makes use of late timers via DT. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> +(cherry picked from commit 173bf69a7af142e0325fa514954f6eeb2d20cc1d) + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/mach-shmobile/timer.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c +index b323e3c..a169cea 100644 +--- a/arch/arm/mach-shmobile/timer.c ++++ b/arch/arm/mach-shmobile/timer.c +@@ -35,7 +35,8 @@ void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz, + + unsigned int value = (1000000 * mult) / (HZ * div); + +- lpj_fine = max_cpu_core_mhz * value; ++ if (!preset_lpj) ++ preset_lpj = max_cpu_core_mhz * value; + } + + static void __init shmobile_late_time_init(void) +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0057-ARM-Undelete-KZM9D-mach-type.patch b/patches.kzm9g/0057-ARM-Undelete-KZM9D-mach-type.patch new file mode 100644 index 00000000000000..5e93acec0931ad --- /dev/null +++ b/patches.kzm9g/0057-ARM-Undelete-KZM9D-mach-type.patch @@ -0,0 +1,32 @@ +From cc8618aa381c26c3aaeb40ac9617adeaac14dbfc Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Mon, 14 May 2012 19:54:51 +0900 +Subject: ARM: Undelete KZM9D mach-type + +Undelete the KZM9D mach-type to allow build of board +for EMEV2 SoC support. + +Signed-off-by: Magnus Damm <damm@opensource.se> + +N.B: Not present upstream + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/tools/mach-types | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types +index 2997e56..e2e0d3f 100644 +--- a/arch/arm/tools/mach-types ++++ b/arch/arm/tools/mach-types +@@ -462,6 +462,7 @@ msm7x27_surf MACH_MSM7X27_SURF MSM7X27_SURF 2705 + msm7x27_ffa MACH_MSM7X27_FFA MSM7X27_FFA 2706 + msm7x30_ffa MACH_MSM7X30_FFA MSM7X30_FFA 2707 + qsd8x50_surf MACH_QSD8X50_SURF QSD8X50_SURF 2708 ++kzm9d MACH_KZM9D KZM9D 3246 + mx53_evk MACH_MX53_EVK MX53_EVK 2716 + igep0030 MACH_IGEP0030 IGEP0030 2717 + sbc3530 MACH_SBC3530 SBC3530 2722 +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0058-gpio-Emma-Mobile-GPIO-driver.patch b/patches.kzm9g/0058-gpio-Emma-Mobile-GPIO-driver.patch new file mode 100644 index 00000000000000..fd825b1f193902 --- /dev/null +++ b/patches.kzm9g/0058-gpio-Emma-Mobile-GPIO-driver.patch @@ -0,0 +1,481 @@ +From 1ed76280e95d4cba220d465a58caec2ba5c20632 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Fri, 11 May 2012 18:41:03 +0900 +Subject: gpio: Emma Mobile GPIO driver + +This patch adds a GPIO driver for the Emma Mobile line +of SoCs. The 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. + +This version of the driver gets all configuration via +struct resource and platform data, but DT bindings are +currently in development and such support will be sent +as a individual feature patch in the near future. + +Signed-off-by: Magnus Damm <damm@opensource.se> + +N.B: This driver has been merged upsteram +as commit a07e103ef08c6907d695a06467d7ee950796fccf. +However, this code is an earlier version of +the driver that doesn't make use of infrastructure +that isn't present in Linux 3.0. + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + drivers/gpio/Kconfig | 6 + + drivers/gpio/Makefile | 1 + + drivers/gpio/gpio-em.c | 385 +++++++++++++++++++++++++++++++++ + include/linux/platform_data/gpio-em.h | 10 + + 4 files changed, 402 insertions(+) + create mode 100644 drivers/gpio/gpio-em.c + create mode 100644 include/linux/platform_data/gpio-em.h + +diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig +index 2967002..6450431 100644 +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -86,6 +86,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_EXYNOS4 + def_bool y + depends on CPU_EXYNOS4210 +diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile +index b605f8e..d5ae36e 100644 +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -32,6 +32,7 @@ obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o + obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o + obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o + obj-$(CONFIG_GPIO_CS5535) += cs5535-gpio.o ++obj-$(CONFIG_GPIO_EM) += gpio-em.o + obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o + obj-$(CONFIG_GPIO_IT8761E) += it8761e_gpio.o + obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o +diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c +new file mode 100644 +index 0000000..8873429 +--- /dev/null ++++ b/drivers/gpio/gpio-em.c +@@ -0,0 +1,385 @@ ++/* ++ * 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/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 gpio_chip gpio_chip; ++ struct irq_chip irq_chip; ++}; ++ ++#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 struct em_gio_priv *irq_to_priv(unsigned int irq) ++{ ++ struct irq_chip *chip = irq_get_chip(irq); ++ return container_of(chip, struct em_gio_priv, irq_chip); ++} ++ ++static void em_gio_irq_disable(struct irq_data *data) ++{ ++ struct em_gio_priv *p = irq_to_priv(data->irq); ++ int offset = data->irq - p->irq_base; ++ ++ em_gio_write(p, GIO_IDS, 1 << offset); ++} ++ ++static void em_gio_irq_enable(struct irq_data *data) ++{ ++ struct em_gio_priv *p = irq_to_priv(data->irq); ++ int offset = data->irq - p->irq_base; ++ ++ em_gio_write(p, GIO_IEN, 1 << offset); ++} ++ ++#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 *data, unsigned int type) ++{ ++ unsigned char value = em_gio_sense_table[type & IRQ_TYPE_SENSE_MASK]; ++ struct em_gio_priv *p = irq_to_priv(data->irq); ++ unsigned int reg, offset, shift; ++ unsigned long flags; ++ unsigned long tmp; ++ ++ if (!value) ++ return -EINVAL; ++ ++ offset = data->irq - p->irq_base; ++ ++ pr_debug("gio: sense irq = %d, irq = %d, mode = %d, sw base = %d\n", ++ offset, data->irq, value, p->irq_base); ++ ++ /* 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 &= ~(1 << 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, 1 << offset); ++ ++ /* enable the interrupt in IIA */ ++ tmp = em_gio_read(p, GIO_IIA); ++ tmp |= 1 << 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 tmp, status; ++ unsigned int offset; ++ ++ status = tmp = em_gio_read(p, GIO_MST); ++ if (!status) ++ return IRQ_NONE; ++ ++ while (status) { ++ offset = __ffs(status); ++ generic_handle_irq(p->irq_base + offset); ++ status &= ~(1 << offset); ++ } ++ ++ em_gio_write(p, GIO_IIR, tmp); ++ ++ return IRQ_HANDLED; ++} ++ ++static 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, 1 << 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) & (1 << 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, 1 << offset); ++ return 0; ++} ++ ++static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset) ++{ ++ return gpio_to_priv(chip)->irq_base + offset; ++} ++ ++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 k, ret; ++ ++ p = kzalloc(sizeof(*p), GFP_KERNEL); ++ if (!p) { ++ dev_err(&pdev->dev, "failed to allocate driver data\n"); ++ ret = -ENOMEM; ++ goto err0; ++ } ++ ++ gpio_chip = &p->gpio_chip; ++ irq_chip = &p->irq_chip; ++ 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; ++ } ++ ++ 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"); ++ ret = -ENXIO; ++ goto err3; ++ } ++ ++ pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n", ++ pdata->gpio_base, pdata->number_of_pins, p->irq_base); ++ ++ 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; ++ ++ for (k = p->irq_base; k < (p->irq_base + pdata->number_of_pins); k++) { ++ irq_set_chip_and_handler_name(k, irq_chip, handle_level_irq, ++ "level"); ++ set_irq_flags(k, IRQF_VALID); /* kill me now */ ++ } ++ ++ 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; ++ } ++ ++ 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; ++ ++ ret = gpiochip_add(gpio_chip); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to add GPIO cntroller\n"); ++ goto err6; ++ } ++ return 0; ++ ++err6: ++ free_irq(irq[1]->start, pdev); ++err5: ++ free_irq(irq[0]->start, pdev); ++err4: ++ irq_free_descs(p->irq_base, pdata->number_of_pins); ++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 gpio_em_config *pdata = pdev->dev.platform_data; ++ 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); ++ irq_free_descs(p->irq_base, pdata->number_of_pins); ++ 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"); +diff --git a/include/linux/platform_data/gpio-em.h b/include/linux/platform_data/gpio-em.h +new file mode 100644 +index 0000000..573edfb +--- /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__ */ +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0059-mach-shmobile-Emma-Mobile-EV2-SoC-base-support-V3.patch b/patches.kzm9g/0059-mach-shmobile-Emma-Mobile-EV2-SoC-base-support-V3.patch new file mode 100644 index 00000000000000..0706510e984c1a --- /dev/null +++ b/patches.kzm9g/0059-mach-shmobile-Emma-Mobile-EV2-SoC-base-support-V3.patch @@ -0,0 +1,493 @@ +From a60f89d7c6f7b301845e6943c6e2ec4c6d6197be Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 16 May 2012 15:44:58 +0900 +Subject: mach-shmobile: Emma Mobile EV2 SoC base support V3 + +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) + +Conflicts: + arch/arm/mach-shmobile/Kconfig + arch/arm/mach-shmobile/Makefile + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + 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 1e7656a..cabb9af 100644 +--- a/arch/arm/mach-shmobile/Kconfig ++++ b/arch/arm/mach-shmobile/Kconfig +@@ -33,6 +33,11 @@ config ARCH_R8A7740 + select SH_CLK_CPG + 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 36bd37d..624f721 100644 +--- a/arch/arm/mach-shmobile/Makefile ++++ b/arch/arm/mach-shmobile/Makefile +@@ -11,6 +11,7 @@ obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7377.o intc-sh7377.o + 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_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.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0060-mach-shmobile-KZM9D-board-support-V3.patch b/patches.kzm9g/0060-mach-shmobile-KZM9D-board-support-V3.patch new file mode 100644 index 00000000000000..ca4b244a9b6109 --- /dev/null +++ b/patches.kzm9g/0060-mach-shmobile-KZM9D-board-support-V3.patch @@ -0,0 +1,110 @@ +From e11d7a5d8be762494c2bf51a6585f61bdf8b290c Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 16 May 2012 15:45:16 +0900 +Subject: mach-shmobile: KZM9D board support V3 + +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/Makefile + arch/arm/mach-shmobile/clock-emev2.c + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + arch/arm/mach-shmobile/Kconfig | 4 ++++ + arch/arm/mach-shmobile/Makefile | 1 + + arch/arm/mach-shmobile/board-kzm9d.c | 36 ++++++++++++++++++++++++++++++++++ + arch/arm/mach-shmobile/clock-emev2.c | 2 ++ + 4 files changed, 43 insertions(+) + create mode 100644 arch/arm/mach-shmobile/board-kzm9d.c + +diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig +index cabb9af..d4dc4ee 100644 +--- a/arch/arm/mach-shmobile/Kconfig ++++ b/arch/arm/mach-shmobile/Kconfig +@@ -92,6 +92,10 @@ config MACH_KZM9G + select ARCH_REQUIRE_GPIOLIB + select SND_SOC_AK4642 if SND_SIMPLE_CARD + ++config MACH_KZM9D ++ bool "KZM9D board" ++ depends on ARCH_EMEV2 ++ + comment "SH-Mobile System Configuration" + + config CPU_HAS_INTEVT +diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile +index 624f721..bdd4383 100644 +--- a/arch/arm/mach-shmobile/Makefile ++++ b/arch/arm/mach-shmobile/Makefile +@@ -47,6 +47,7 @@ obj-$(CONFIG_MACH_AG5EVM) += board-ag5evm.o + obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o + obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o + obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o ++obj-$(CONFIG_MACH_KZM9D) += board-kzm9d.o + + # Framework support + obj-$(CONFIG_SMP) += $(smp-y) +diff --git a/arch/arm/mach-shmobile/board-kzm9d.c b/arch/arm/mach-shmobile/board-kzm9d.c +new file mode 100644 +index 0000000..e743f90 +--- /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/arch/arm/mach-shmobile/clock-emev2.c b/arch/arm/mach-shmobile/clock-emev2.c +index 73a1216..64d4a56 100644 +--- a/arch/arm/mach-shmobile/clock-emev2.c ++++ b/arch/arm/mach-shmobile/clock-emev2.c +@@ -84,6 +84,8 @@ static struct clk *main_clks[] = { + enum { SCLKDIV_USIAU0, SCLKDIV_USIBU2, SCLKDIV_USIBU1, SCLKDIV_USIBU3, + SCLKDIV_NR }; + ++#define IOMEM(x) ((void __force __iomem *)(x)) ++ + #define SCLKDIV(_reg, _shift) \ + { \ + .parent = &pll3_clk, \ +-- +1.7.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0061-mach-shmobile-Emma-Mobile-EV2-SMP-support-V3.patch b/patches.kzm9g/0061-mach-shmobile-Emma-Mobile-EV2-SMP-support-V3.patch new file mode 100644 index 00000000000000..12ddf536a6297b --- /dev/null +++ b/patches.kzm9g/0061-mach-shmobile-Emma-Mobile-EV2-SMP-support-V3.patch @@ -0,0 +1,329 @@ +From 0af702823eae60eceedd80cbd4bd0670285a2cca Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 16 May 2012 15:45:25 +0900 +Subject: mach-shmobile: Emma Mobile EV2 SMP support V3 + +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) + +Conflicts: + arch/arm/mach-shmobile/Makefile + arch/arm/mach-shmobile/platsmp.c + +Signed-off-by: Simon Horman <horms@verge.net.au> +--- + 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 bdd4383..a2c56d5 100644 +--- a/arch/arm/mach-shmobile/Makefile ++++ b/arch/arm/mach-shmobile/Makefile +@@ -18,6 +18,7 @@ smp-y := platsmp.o headsmp.o + smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o + smp-$(CONFIG_LOCAL_TIMERS) += localtimer.o + smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.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 64d4a56..9414383 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, +@@ -196,6 +202,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 1103ce5..9e98f9e 100644 +--- a/arch/arm/mach-shmobile/platsmp.c ++++ b/arch/arm/mach-shmobile/platsmp.c +@@ -20,14 +20,19 @@ + #include <asm/localtimer.h> + #include <asm/mach-types.h> + #include <mach/common.h> ++#include <mach/emev2.h> + + #define is_sh73a0() (machine_is_ag5evm() || machine_is_kzm9g()) ++#define is_emev2() machine_is_kzm9d() + + static unsigned int __init shmobile_smp_get_core_count(void) + { + if (is_sh73a0()) + return sh73a0_get_core_count(); + ++ if (is_emev2()) ++ return emev2_get_core_count(); ++ + return 1; + } + +@@ -35,10 +40,16 @@ static void __init shmobile_smp_prepare_cpus(void) + { + if (is_sh73a0()) + sh73a0_smp_prepare_cpus(); ++ ++ if (is_emev2()) ++ emev2_smp_prepare_cpus(); + } + + int shmobile_platform_cpu_kill(unsigned int cpu) + { ++ if (is_emev2()) ++ return emev2_platform_cpu_kill(cpu); ++ + return 1; + } + +@@ -48,6 +59,9 @@ void __cpuinit platform_secondary_init(unsigned int cpu) + + if (is_sh73a0()) + sh73a0_secondary_init(cpu); ++ ++ if (is_emev2()) ++ emev2_secondary_init(cpu); + } + + int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -55,6 +69,9 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) + if (is_sh73a0()) + return sh73a0_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.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0062-mach-shmobile-Emma-Mobile-EV2-GPIO-support-V3.patch b/patches.kzm9g/0062-mach-shmobile-Emma-Mobile-EV2-GPIO-support-V3.patch new file mode 100644 index 00000000000000..7604f5b5fbef4e --- /dev/null +++ b/patches.kzm9g/0062-mach-shmobile-Emma-Mobile-EV2-GPIO-support-V3.patch @@ -0,0 +1,280 @@ +From dbf1eecc80eac3500e8456e46d12601641756cd1 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 16 May 2012 15:45:34 +0900 +Subject: mach-shmobile: Emma Mobile EV2 GPIO support V3 + +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: Simon Horman <horms@verge.net.au> +--- + 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 d4dc4ee..4ce90f3 100644 +--- a/arch/arm/mach-shmobile/Kconfig ++++ b/arch/arm/mach-shmobile/Kconfig +@@ -37,6 +37,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.10.1.362.g242cab3 + diff --git a/patches.kzm9g/0063-mach-shmobile-KZM9D-board-Ethernet-support-V3.patch b/patches.kzm9g/0063-mach-shmobile-KZM9D-board-Ethernet-support-V3.patch new file mode 100644 index 00000000000000..78f4bbc6106e82 --- /dev/null +++ b/patches.kzm9g/0063-mach-shmobile-KZM9D-board-Ethernet-support-V3.patch @@ -0,0 +1,82 @@ +From adaf8f8c3a969904f01b38f842fb7416858ea4cc Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 16 May 2012 15:45:42 +0900 +Subject: mach-shmobile: KZM9D board Ethernet support V3 + +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: Simon Horman <horms@verge.net.au> +--- + arch/arm/mach-shmobile/board-kzm9d.c | 44 ++++++++++++++++++++++++++++++++++- + 1 file changed, 43 insertions(+), 1 deletion(-) + +--- 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 diff --git a/patches.kzm9g/0157-ARM-7123-1-smp-Add-an-IPI-handler-callable-from-C-co.patch b/patches.kzm9g/0157-ARM-7123-1-smp-Add-an-IPI-handler-callable-from-C-co.patch index 6f64a72920a5a6..327aac56649ce7 100644 --- a/patches.kzm9g/0157-ARM-7123-1-smp-Add-an-IPI-handler-callable-from-C-co.patch +++ b/patches.kzm9g/0157-ARM-7123-1-smp-Add-an-IPI-handler-callable-from-C-co.patch @@ -12,15 +12,13 @@ Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Simon Horman <horms@verge.net.au> --- - arch/arm/include/asm/smp.h | 5 +++++ - arch/arm/kernel/smp.c | 5 +++++ + arch/arm/include/asm/smp.h | 5 +++++ + arch/arm/kernel/smp.c | 5 +++++ 2 files changed, 10 insertions(+) -diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h -index 674ebcd..0a17b62 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h -@@ -33,6 +33,11 @@ extern void show_ipi_list(struct seq_file *, int); +@@ -33,6 +33,11 @@ extern void show_ipi_list(struct seq_fil asmlinkage void do_IPI(int ipinr, struct pt_regs *regs); /* @@ -32,11 +30,9 @@ index 674ebcd..0a17b62 100644 * Setup the set of possible CPUs (via set_cpu_possible) */ extern void smp_init_cpus(void); -diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c -index 4db266c..74ac4bb 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c -@@ -580,6 +580,11 @@ static void ipi_cpu_stop(unsigned int cpu) +@@ -578,6 +578,11 @@ static void ipi_cpu_stop(unsigned int cp */ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs) { @@ -48,6 +44,3 @@ index 4db266c..74ac4bb 100644 unsigned int cpu = smp_processor_id(); struct pt_regs *old_regs = set_irq_regs(regs); --- -1.7.10.2.565.gbd578b5 - diff --git a/patches.kzm9g/0158-ARM-7124-1-smp-Add-a-localtimer-handler-callable-fro.patch b/patches.kzm9g/0158-ARM-7124-1-smp-Add-a-localtimer-handler-callable-fro.patch index d260cb8b62f735..1309618162715f 100644 --- a/patches.kzm9g/0158-ARM-7124-1-smp-Add-a-localtimer-handler-callable-fro.patch +++ b/patches.kzm9g/0158-ARM-7124-1-smp-Add-a-localtimer-handler-callable-fro.patch @@ -13,12 +13,10 @@ Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Simon Horman <horms@verge.net.au> --- - arch/arm/include/asm/localtimer.h | 4 ++++ - arch/arm/kernel/smp.c | 5 +++++ + arch/arm/include/asm/localtimer.h | 4 ++++ + arch/arm/kernel/smp.c | 5 +++++ 2 files changed, 9 insertions(+) -diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h -index 080d74f..3306f28 100644 --- a/arch/arm/include/asm/localtimer.h +++ b/arch/arm/include/asm/localtimer.h @@ -22,6 +22,10 @@ void percpu_timer_setup(void); @@ -32,11 +30,9 @@ index 080d74f..3306f28 100644 #ifdef CONFIG_LOCAL_TIMERS -diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c -index 74ac4bb..53aaa59 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c -@@ -473,6 +473,11 @@ static void ipi_timer(void) +@@ -471,6 +471,11 @@ static void ipi_timer(void) #ifdef CONFIG_LOCAL_TIMERS asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) { @@ -48,6 +44,3 @@ index 74ac4bb..53aaa59 100644 struct pt_regs *old_regs = set_irq_regs(regs); int cpu = smp_processor_id(); --- -1.7.10.2.565.gbd578b5 - diff --git a/patches.kzm9g/0159-ARM-gic-consolidate-PPI-handling.patch b/patches.kzm9g/0159-ARM-gic-consolidate-PPI-handling.patch index 28b7f97e736e35..a1e1cfee7f439b 100644 --- a/patches.kzm9g/0159-ARM-gic-consolidate-PPI-handling.patch +++ b/patches.kzm9g/0159-ARM-gic-consolidate-PPI-handling.patch @@ -31,24 +31,22 @@ Conflicts: Signed-off-by: Simon Horman <horms@verge.net.au> --- - arch/arm/common/gic.c | 75 ++++++++++++++++++++++- - arch/arm/include/asm/entry-macro-multi.S | 7 --- - arch/arm/include/asm/hardirq.h | 3 - - arch/arm/include/asm/hardware/entry-macro-gic.S | 19 +----- - arch/arm/include/asm/localtimer.h | 11 ++-- - arch/arm/include/asm/smp.h | 5 -- - arch/arm/kernel/irq.c | 3 - - arch/arm/kernel/smp.c | 32 ++-------- - arch/arm/mach-exynos4/include/mach/entry-macro.S | 13 +--- - arch/arm/mach-msm/board-msm8x60.c | 11 ---- - arch/arm/mach-msm/include/mach/entry-macro-qgic.S | 73 +--------------------- - arch/arm/mach-omap2/include/mach/entry-macro.S | 14 +---- - arch/arm/mach-shmobile/entry-intc.S | 3 - - arch/arm/mach-shmobile/include/mach/entry-macro.S | 3 - + arch/arm/common/gic.c | 75 +++++++++++++++++++++- + arch/arm/include/asm/entry-macro-multi.S | 7 -- + arch/arm/include/asm/hardirq.h | 3 + arch/arm/include/asm/hardware/entry-macro-gic.S | 19 ----- + arch/arm/include/asm/localtimer.h | 11 +-- + arch/arm/include/asm/smp.h | 5 - + arch/arm/kernel/irq.c | 3 + arch/arm/kernel/smp.c | 32 +-------- + arch/arm/mach-exynos4/include/mach/entry-macro.S | 13 --- + arch/arm/mach-msm/board-msm8x60.c | 11 --- + arch/arm/mach-msm/include/mach/entry-macro-qgic.S | 73 --------------------- + arch/arm/mach-omap2/include/mach/entry-macro.S | 14 ---- + arch/arm/mach-shmobile/entry-intc.S | 3 + arch/arm/mach-shmobile/include/mach/entry-macro.S | 3 14 files changed, 88 insertions(+), 184 deletions(-) -diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c -index 8b5be72..95ad8d1 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -29,10 +29,14 @@ @@ -66,7 +64,7 @@ index 8b5be72..95ad8d1 100644 static DEFINE_SPINLOCK(irq_controller_lock); -@@ -256,6 +260,32 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) +@@ -256,6 +260,32 @@ void __init gic_cascade_irq(unsigned int irq_set_chained_handler(irq, gic_handle_cascade_irq); } @@ -99,7 +97,7 @@ index 8b5be72..95ad8d1 100644 static void __init gic_dist_init(struct gic_chip_data *gic, unsigned int irq_start) { -@@ -263,6 +293,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic, +@@ -263,6 +293,7 @@ static void __init gic_dist_init(struct u32 cpumask; void __iomem *base = gic->dist_base; u32 cpu = 0; @@ -107,7 +105,7 @@ index 8b5be72..95ad8d1 100644 #ifdef CONFIG_SMP cpu = cpu_logical_map(smp_processor_id()); -@@ -286,6 +317,33 @@ static void __init gic_dist_init(struct gic_chip_data *gic, +@@ -286,6 +317,33 @@ static void __init gic_dist_init(struct gic->gic_irqs = gic_irqs; /* @@ -141,7 +139,7 @@ index 8b5be72..95ad8d1 100644 * Set all global interrupts to be level triggered, active low. */ for (i = 32; i < gic_irqs; i += 16) -@@ -320,7 +378,22 @@ static void __init gic_dist_init(struct gic_chip_data *gic, +@@ -320,7 +378,22 @@ static void __init gic_dist_init(struct /* * Setup the Linux IRQ subsystem. */ @@ -165,8 +163,6 @@ index 8b5be72..95ad8d1 100644 irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq); irq_set_chip_data(i, gic); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); -diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S -index 2f1e209..88d6181 100644 --- a/arch/arm/include/asm/entry-macro-multi.S +++ b/arch/arm/include/asm/entry-macro-multi.S @@ -25,13 +25,6 @@ @@ -183,8 +179,6 @@ index 2f1e209..88d6181 100644 #endif 9997: .endm -diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h -index 89ad180..ddf07a9 100644 --- a/arch/arm/include/asm/hardirq.h +++ b/arch/arm/include/asm/hardirq.h @@ -9,9 +9,6 @@ @@ -197,8 +191,6 @@ index 89ad180..ddf07a9 100644 #ifdef CONFIG_SMP unsigned int ipi_irqs[NR_IPI]; #endif -diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S -index c115b82..74ebc80 100644 --- a/arch/arm/include/asm/hardware/entry-macro-gic.S +++ b/arch/arm/include/asm/hardware/entry-macro-gic.S @@ -22,15 +22,11 @@ @@ -242,8 +234,6 @@ index c115b82..74ebc80 100644 - streq \irqstat, [\base, #GIC_CPU_EOI] - cmp \tmp, #0 - .endm -diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h -index 3306f28..5c8acb4 100644 --- a/arch/arm/include/asm/localtimer.h +++ b/arch/arm/include/asm/localtimer.h @@ -10,6 +10,8 @@ @@ -272,11 +262,9 @@ index 3306f28..5c8acb4 100644 #ifdef CONFIG_LOCAL_TIMERS -diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h -index 0a17b62..1e5717a 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h -@@ -99,9 +99,4 @@ extern void platform_cpu_enable(unsigned int cpu); +@@ -99,9 +99,4 @@ extern void platform_cpu_enable(unsigned extern void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); @@ -286,11 +274,9 @@ index 0a17b62..1e5717a 100644 -extern void show_local_irqs(struct seq_file *, int); - #endif /* ifndef __ASM_ARM_SMP_H */ -diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c -index 3e34b1f..0ad5e98 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c -@@ -59,9 +59,6 @@ int arch_show_interrupts(struct seq_file *p, int prec) +@@ -59,9 +59,6 @@ int arch_show_interrupts(struct seq_file #ifdef CONFIG_SMP show_ipi_list(p, prec); #endif @@ -300,8 +286,6 @@ index 3e34b1f..0ad5e98 100644 seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); return 0; } -diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c -index 53aaa59..7db7120 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -450,10 +450,6 @@ u64 smp_irq_stat_cpu(unsigned int cpu) @@ -315,18 +299,18 @@ index 53aaa59..7db7120 100644 return sum; } -@@ -471,34 +467,16 @@ static void ipi_timer(void) +@@ -469,34 +465,16 @@ static void ipi_timer(void) } #ifdef CONFIG_LOCAL_TIMERS -asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) --{ ++irqreturn_t percpu_timer_handler(int irq, void *dev_id) + { - handle_local_timer(regs); -} - -void handle_local_timer(struct pt_regs *regs) -+irqreturn_t percpu_timer_handler(int irq, void *dev_id) - { +-{ - struct pt_regs *old_regs = set_irq_regs(regs); - int cpu = smp_processor_id(); + struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent); @@ -355,8 +339,6 @@ index 53aaa59..7db7120 100644 } #endif -diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S -index d8f38c2..9be072f 100644 --- a/arch/arm/mach-exynos4/include/mach/entry-macro.S +++ b/arch/arm/mach-exynos4/include/mach/entry-macro.S @@ -50,7 +50,7 @@ @@ -383,8 +365,6 @@ index d8f38c2..9be072f 100644 - streq \irqstat, [\base, #GIC_CPU_EOI] - cmp \tmp, #0 - .endm -diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c -index 1163b6f..d70a2f6 100644 --- a/arch/arm/mach-msm/board-msm8x60.c +++ b/arch/arm/mach-msm/board-msm8x60.c @@ -36,8 +36,6 @@ static void __init msm8x60_map_io(void) @@ -396,7 +376,7 @@ index 1163b6f..d70a2f6 100644 gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE, (void *)MSM_QGIC_CPU_BASE); -@@ -49,15 +47,6 @@ static void __init msm8x60_init_irq(void) +@@ -49,15 +47,6 @@ static void __init msm8x60_init_irq(void */ if (!machine_is_msm8x60_sim()) writel(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET); @@ -412,8 +392,6 @@ index 1163b6f..d70a2f6 100644 } static void __init msm8x60_init(void) -diff --git a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S -index 1246715..717076f 100644 --- a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S +++ b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S @@ -8,81 +8,10 @@ @@ -499,8 +477,6 @@ index 1246715..717076f 100644 - streq \irqstat, [\base, #GIC_CPU_EOI] - cmp \tmp, #0 - .endm -diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S -index a48690b..22d86ef 100644 --- a/arch/arm/mach-omap2/include/mach/entry-macro.S +++ b/arch/arm/mach-omap2/include/mach/entry-macro.S @@ -78,7 +78,7 @@ @@ -531,8 +507,6 @@ index a48690b..22d86ef 100644 #endif /* CONFIG_SMP */ #else /* MULTI_OMAP2 */ -diff --git a/arch/arm/mach-shmobile/entry-intc.S b/arch/arm/mach-shmobile/entry-intc.S -index cac0a7a..1a1c00c 100644 --- a/arch/arm/mach-shmobile/entry-intc.S +++ b/arch/arm/mach-shmobile/entry-intc.S @@ -51,7 +51,4 @@ @@ -543,8 +517,6 @@ index cac0a7a..1a1c00c 100644 - .endm - arch_irq_handler shmobile_handle_irq_intc -diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S -index d791f10..8d4a416 100644 --- a/arch/arm/mach-shmobile/include/mach/entry-macro.S +++ b/arch/arm/mach-shmobile/include/mach/entry-macro.S @@ -27,8 +27,5 @@ @@ -556,6 +528,3 @@ index d791f10..8d4a416 100644 - .macro arch_ret_to_user, tmp1, tmp2 .endm --- -1.7.10.2.565.gbd578b5 - diff --git a/patches.kzm9g/0164-ARM-gic-local-timers-use-the-request_percpu_irq-inte.patch b/patches.kzm9g/0164-ARM-gic-local-timers-use-the-request_percpu_irq-inte.patch index e01ad13c8e072e..8ac729d89bf87a 100644 --- a/patches.kzm9g/0164-ARM-gic-local-timers-use-the-request_percpu_irq-inte.patch +++ b/patches.kzm9g/0164-ARM-gic-local-timers-use-the-request_percpu_irq-inte.patch @@ -24,18 +24,16 @@ Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Simon Horman <horms@verge.net.au> --- - arch/arm/common/gic.c | 52 ---------------------------- - arch/arm/include/asm/hardware/gic.h | 1 - - arch/arm/include/asm/localtimer.h | 16 ++++----- - arch/arm/include/asm/smp_twd.h | 2 +- - arch/arm/kernel/smp.c | 16 +-------- - arch/arm/kernel/smp_twd.c | 47 +++++++++++++++++++++++-- - arch/arm/mach-exynos4/mct.c | 7 ++-- - arch/arm/mach-msm/timer.c | 69 +++++++++++++++++++++---------------- + arch/arm/common/gic.c | 52 --------------------------- + arch/arm/include/asm/hardware/gic.h | 1 + arch/arm/include/asm/localtimer.h | 16 +++----- + arch/arm/include/asm/smp_twd.h | 2 - + arch/arm/kernel/smp.c | 16 -------- + arch/arm/kernel/smp_twd.c | 47 +++++++++++++++++++++++- + arch/arm/mach-exynos4/mct.c | 7 ++- + arch/arm/mach-msm/timer.c | 69 ++++++++++++++++++++---------------- 8 files changed, 99 insertions(+), 111 deletions(-) -diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c -index 7a73799..5f7b4e2 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -35,7 +35,6 @@ @@ -46,7 +44,7 @@ index 7a73799..5f7b4e2 100644 static DEFINE_SPINLOCK(irq_controller_lock); -@@ -285,32 +284,6 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) +@@ -285,32 +284,6 @@ void __init gic_cascade_irq(unsigned int irq_set_chained_handler(irq, gic_handle_cascade_irq); } @@ -79,7 +77,7 @@ index 7a73799..5f7b4e2 100644 static void __init gic_dist_init(struct gic_chip_data *gic, unsigned int irq_start) { -@@ -353,16 +326,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic, +@@ -353,16 +326,6 @@ static void __init gic_dist_init(struct BUG(); ppi_base = gic->irq_offset + 32 - nrppis; @@ -96,7 +94,7 @@ index 7a73799..5f7b4e2 100644 } pr_info("Configuring GIC with %d sources (%d PPIs)\n", -@@ -405,17 +368,12 @@ static void __init gic_dist_init(struct gic_chip_data *gic, +@@ -405,17 +368,12 @@ static void __init gic_dist_init(struct */ for (i = 0; i < nrppis; i++) { int ppi = i + ppi_base; @@ -114,7 +112,7 @@ index 7a73799..5f7b4e2 100644 } for (i = irq_start + nrppis; i < irq_limit; i++) { -@@ -661,16 +619,6 @@ void __cpuinit gic_secondary_init(unsigned int gic_nr) +@@ -661,16 +619,6 @@ void __cpuinit gic_secondary_init(unsign gic_cpu_init(&gic_data[gic_nr]); } @@ -131,8 +129,6 @@ index 7a73799..5f7b4e2 100644 #ifdef CONFIG_SMP void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) { -diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h -index 615c336..a61f11e 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -41,7 +41,6 @@ void gic_secondary_init(unsigned int); @@ -143,8 +139,6 @@ index 615c336..a61f11e 100644 struct gic_chip_data { unsigned int irq_offset; -diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h -index 5c8acb4..f5e1cec 100644 --- a/arch/arm/include/asm/localtimer.h +++ b/arch/arm/include/asm/localtimer.h @@ -19,26 +19,20 @@ struct clock_event_device; @@ -177,7 +171,7 @@ index 5c8acb4..f5e1cec 100644 #endif -@@ -53,6 +47,10 @@ static inline int local_timer_setup(struct clock_event_device *evt) +@@ -53,6 +47,10 @@ static inline int local_timer_setup(stru { return -ENXIO; } @@ -188,8 +182,6 @@ index 5c8acb4..f5e1cec 100644 #endif #endif -diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h -index fed9981..ef9ffba9 100644 --- a/arch/arm/include/asm/smp_twd.h +++ b/arch/arm/include/asm/smp_twd.h @@ -22,7 +22,7 @@ struct clock_event_device; @@ -201,12 +193,10 @@ index fed9981..ef9ffba9 100644 +void twd_timer_stop(struct clock_event_device *); #endif -diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c -index 7db7120..083d36e 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c -@@ -466,20 +466,6 @@ static void ipi_timer(void) - irq_exit(); +@@ -464,20 +464,6 @@ static void ipi_timer(void) + evt->event_handler(evt); } -#ifdef CONFIG_LOCAL_TIMERS @@ -226,7 +216,7 @@ index 7db7120..083d36e 100644 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST static void smp_timer_broadcast(const struct cpumask *mask) { -@@ -530,7 +516,7 @@ static void percpu_timer_stop(void) +@@ -528,7 +514,7 @@ static void percpu_timer_stop(void) unsigned int cpu = smp_processor_id(); struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); @@ -235,8 +225,6 @@ index 7db7120..083d36e 100644 } #endif -diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c -index 01c1862..a8a6682 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -19,6 +19,7 @@ @@ -269,7 +257,7 @@ index 01c1862..a8a6682 100644 static void __cpuinit twd_calibrate_rate(void) { unsigned long count; -@@ -119,11 +128,43 @@ static void __cpuinit twd_calibrate_rate(void) +@@ -119,11 +128,43 @@ static void __cpuinit twd_calibrate_rate } } @@ -313,7 +301,7 @@ index 01c1862..a8a6682 100644 twd_calibrate_rate(); clk->name = "local_timer"; -@@ -137,8 +178,10 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) +@@ -137,8 +178,10 @@ void __cpuinit twd_timer_setup(struct cl clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk); clk->min_delta_ns = clockevent_delta2ns(0xf, clk); @@ -326,11 +314,9 @@ index 01c1862..a8a6682 100644 - gic_enable_ppi(clk->irq); + enable_percpu_irq(clk->irq, 0); } -diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c -index 1ae059b..85a1bb7 100644 --- a/arch/arm/mach-exynos4/mct.c +++ b/arch/arm/mach-exynos4/mct.c -@@ -380,9 +380,11 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt) +@@ -380,9 +380,11 @@ static void exynos4_mct_tick_init(struct if (cpu == 0) { mct_tick0_event_irq.dev_id = &mct_tick[cpu]; @@ -342,7 +328,7 @@ index 1ae059b..85a1bb7 100644 setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq); irq_set_affinity(IRQ_MCT_L1, cpumask_of(1)); } -@@ -394,9 +396,10 @@ void __cpuinit local_timer_setup(struct clock_event_device *evt) +@@ -394,9 +396,10 @@ void __cpuinit local_timer_setup(struct exynos4_mct_tick_init(evt); } @@ -355,8 +341,6 @@ index 1ae059b..85a1bb7 100644 } #endif /* CONFIG_LOCAL_TIMERS */ -diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c -index 63621f1..afeeca5 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -71,12 +71,16 @@ enum timer_location { @@ -373,7 +357,7 @@ index 63621f1..afeeca5 100644 + union { + struct clock_event_device *evt; + struct clock_event_device __percpu **percpu_evt; -+ }; ++ }; }; enum { @@ -464,7 +448,7 @@ index 63621f1..afeeca5 100644 struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER]; /* Use existing clock_event for cpu 0 */ -@@ -281,12 +291,13 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt) +@@ -281,12 +291,13 @@ int __cpuinit local_timer_setup(struct c writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); @@ -480,7 +464,7 @@ index 63621f1..afeeca5 100644 evt->name = "local_timer"; evt->features = CLOCK_EVT_FEAT_ONESHOT; evt->rating = clock->clockevent.rating; -@@ -298,17 +309,17 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt) +@@ -298,17 +309,17 @@ int __cpuinit local_timer_setup(struct c clockevent_delta2ns(0xf0000000 >> clock->shift, evt); evt->min_delta_ns = clockevent_delta2ns(4, evt); @@ -503,6 +487,3 @@ index 63621f1..afeeca5 100644 } #endif --- -1.7.10.2.565.gbd578b5 - diff --git a/patches.kzm9g/0180-arm-mach-shmobile-add-a-resource-name-for-shdma.patch b/patches.kzm9g/0180-arm-mach-shmobile-add-a-resource-name-for-shdma.patch index df953d69a43572..f4b2b450e5fbbb 100644 --- a/patches.kzm9g/0180-arm-mach-shmobile-add-a-resource-name-for-shdma.patch +++ b/patches.kzm9g/0180-arm-mach-shmobile-add-a-resource-name-for-shdma.patch @@ -9,15 +9,13 @@ Signed-off-by: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Simon Horman <horms@verge.net.au> --- - arch/arm/mach-shmobile/setup-sh7372.c | 6 +++--- - arch/arm/mach-shmobile/setup-sh73a0.c | 2 +- + arch/arm/mach-shmobile/setup-sh7372.c | 6 +++--- + arch/arm/mach-shmobile/setup-sh73a0.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) -diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c -index cd807ee..8ddef91 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c -@@ -503,7 +503,7 @@ static struct resource sh7372_dmae0_resources[] = { +@@ -505,7 +505,7 @@ static struct resource sh7372_dmae0_reso .flags = IORESOURCE_MEM, }, { @@ -26,7 +24,7 @@ index cd807ee..8ddef91 100644 .start = evt2irq(0x20c0), .end = evt2irq(0x20c0), .flags = IORESOURCE_IRQ, -@@ -531,7 +531,7 @@ static struct resource sh7372_dmae1_resources[] = { +@@ -533,7 +533,7 @@ static struct resource sh7372_dmae1_reso .flags = IORESOURCE_MEM, }, { @@ -35,7 +33,7 @@ index cd807ee..8ddef91 100644 .start = evt2irq(0x21c0), .end = evt2irq(0x21c0), .flags = IORESOURCE_IRQ, -@@ -559,7 +559,7 @@ static struct resource sh7372_dmae2_resources[] = { +@@ -561,7 +561,7 @@ static struct resource sh7372_dmae2_reso .flags = IORESOURCE_MEM, }, { @@ -44,11 +42,9 @@ index cd807ee..8ddef91 100644 .start = evt2irq(0x22c0), .end = evt2irq(0x22c0), .flags = IORESOURCE_IRQ, -diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c -index e46821c..20e71e5 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c -@@ -607,7 +607,7 @@ static struct resource sh73a0_dmae_resources[] = { +@@ -607,7 +607,7 @@ static struct resource sh73a0_dmae_resou .flags = IORESOURCE_MEM, }, { @@ -57,6 +53,3 @@ index e46821c..20e71e5 100644 .start = gic_spi(129), .end = gic_spi(129), .flags = IORESOURCE_IRQ, --- -1.7.10.2.565.gbd578b5 - diff --git a/patches.kzm9g/arm-shmobile-sh73a0-bugfix-sy-dmac-number.patch b/patches.kzm9g/arm-shmobile-sh73a0-bugfix-sy-dmac-number.patch new file mode 100644 index 00000000000000..771486ee8fb98a --- /dev/null +++ b/patches.kzm9g/arm-shmobile-sh73a0-bugfix-sy-dmac-number.patch @@ -0,0 +1,86 @@ +From horms@vergenet.net Thu Jun 21 17:52:36 2012 +From: Simon Horman <horms@verge.net.au> +Date: Fri, 22 Jun 2012 09:51:53 +0900 +Subject: [PATCH] ARM: shmobile: sh73a0: bugfix: SY-DMAC number +To: ltsi-dev@lists.linuxfoundation.org +Cc: Greg KH <gregkh@linuxfoundation.org> +Message-ID: <1340326313-1672-1-git-send-email-horms@verge.net.au> + + +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> + +681e1b3eeb3606e06a7c4984e8058df84296f8bb +(ARM: mach-shmobile: sh73a0 DMA Engine support for SY-DMAC) +adds SY-DMAC, but it is 218, not 318 + +This patch is based on v2.0 manual + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Acked-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> +(cherry picked from commit 32103c7ba7d274bcb3ace48bc3366e1df37ebb56) + +Conflicts: + arch/arm/mach-shmobile/clock-sh73a0.c + +Signed-off-by: Simon Horman <horms@verge.net.au> + +--- + +Greg, this is a bugfix for the sh73a0 and thus my work on the KZM9G +(not the D!) board. +--- + arch/arm/mach-shmobile/clock-sh73a0.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c +index 012b284..a7ae9c3 100644 +--- a/arch/arm/mach-shmobile/clock-sh73a0.c ++++ b/arch/arm/mach-shmobile/clock-sh73a0.c +@@ -474,9 +474,9 @@ static struct clk *late_main_clks[] = { + + enum { MSTP001, + MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100, +- MSTP219, ++ MSTP219, MSTP218, + MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, +- MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP318, ++ MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, + MSTP314, MSTP313, MSTP312, MSTP311, + MSTP303, MSTP302, MSTP301, MSTP300, + MSTP411, MSTP410, MSTP403, +@@ -496,6 +496,7 @@ static struct clk mstp_clks[MSTP_NR] = { + [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */ + [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ + [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */ ++ [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */ + [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ + [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ + [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ +@@ -508,7 +509,6 @@ static struct clk mstp_clks[MSTP_NR] = { + [MSTP328] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /*FSI*/ + [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */ + [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */ +- [MSTP318] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 18, 0), /* SY-DMAC */ + [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */ + [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */ + [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */ +@@ -552,6 +552,7 @@ static struct clk_lookup lookups[] = { + CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */ + CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ + CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */ ++ CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */ + CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ + CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */ + CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ +@@ -564,7 +565,6 @@ static struct clk_lookup lookups[] = { + CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */ + CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */ + CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */ +- CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP318]), /* SY-DMAC */ + CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ + CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ +-- +1.7.10.2.484.gcd07cc5 + diff --git a/patches.kzm9g/ltsi-arm-shmobile-kzm9g-support-real-time-clock.patch b/patches.kzm9g/ltsi-arm-shmobile-kzm9g-support-real-time-clock.patch new file mode 100644 index 00000000000000..fd8fbdfe6d2a50 --- /dev/null +++ b/patches.kzm9g/ltsi-arm-shmobile-kzm9g-support-real-time-clock.patch @@ -0,0 +1,53 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon Jun 18 04:06:00 2012 +From: Tetsuyuki Kobayashi <koba@kmckk.co.jp> +Date: Mon, 18 Jun 2012 20:06:02 +0900 +Subject: LTSI: ARM: shmobile: kzm9g: Support Real Time Clock +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FDF0B9A.6030404@kmckk.co.jp> + + +KZM-A9-GT board has RTC device r2025d at I2C channel 0 +with slave address 0x64. + +This patch enables reading and writing hardware real time clock on +KZM-A9-GT board. Interrupt is not yet supported. + +How to test this patch using user space command. + +Read RTC + # hwclock -r + +Copy system clock to RTC + # hwclock -w + +Shutdown and power off the board, and wait a while, then power on again. +Check RTC still keeps correct date. + +Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp> +--- + arch/arm/configs/kzm9g_defconfig | 1 + + arch/arm/mach-shmobile/board-kzm9g.c | 3 +++ + 2 files changed, 4 insertions(+) + +--- a/arch/arm/configs/kzm9g_defconfig ++++ b/arch/arm/configs/kzm9g_defconfig +@@ -108,6 +108,7 @@ CONFIG_MMC_SH_MMCIF=y + CONFIG_NEW_LEDS=y + CONFIG_LEDS_CLASS=y + CONFIG_RTC_CLASS=y ++CONFIG_RTC_DRV_RS5C372=y + CONFIG_DMADEVICES=y + CONFIG_SH_DMAE=y + CONFIG_ASYNC_TX_DMA=y +--- a/arch/arm/mach-shmobile/board-kzm9g.c ++++ b/arch/arm/mach-shmobile/board-kzm9g.c +@@ -278,6 +278,9 @@ static struct pcf857x_platform_data pcf8 + static struct i2c_board_info i2c0_devices[] = { + { + I2C_BOARD_INFO("ak4648", 0x12), ++ }, ++ { ++ I2C_BOARD_INFO("r2025sd", 0x32), + } + }; + diff --git a/patches.kzm9g/ltsi-bugfix-add-config_i2c-to-kzm9g_defconfig.patch b/patches.kzm9g/ltsi-bugfix-add-config_i2c-to-kzm9g_defconfig.patch new file mode 100644 index 00000000000000..35557987dff9ce --- /dev/null +++ b/patches.kzm9g/ltsi-bugfix-add-config_i2c-to-kzm9g_defconfig.patch @@ -0,0 +1,51 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon Jun 18 02:55:43 2012 +From: Tetsuyuki Kobayashi <koba@kmckk.co.jp> +Date: Mon, 18 Jun 2012 18:55:45 +0900 +Subject: LTSI: bugfix: add CONFIG_I2C to kzm9g_defconfig +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FDEFB21.1090608@kmckk.co.jp> + + + +Build fails for kzm9g because CONFIG_I2C=y is missing in kzm9g_defconfig. + +$ make kzm9g_defconfig +$ make + + ... + + CC arch/arm/mach-shmobile/board-kzm9g.o +arch/arm/mach-shmobile/board-kzm9g.c: In function 'as3711_enable_lcdc_backlight': +arch/arm/mach-shmobile/board-kzm9g.c:314:9: error: implicit declaration of function 'i2c_get_adapter' [-Werror=implicit-function-declaration] +arch/arm/mach-shmobile/board-kzm9g.c:314:26: warning: initialization makes pointer from integer without a cast [enabled by default] +arch/arm/mach-shmobile/board-kzm9g.c:349:3: error: implicit declaration of function 'i2c_transfer' [-Werror=implicit-function-declaration] +cc1: some warnings being treated as errors +make[1]: *** [arch/arm/mach-shmobile/board-kzm9g.o] Error 1 +make: *** [arch/arm/mach-shmobile] Error 2 + +This patch solves this problem. + +Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp> +--- + arch/arm/configs/kzm9g_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig +index e3ebc20..ff7b698 100644 +--- a/arch/arm/configs/kzm9g_defconfig ++++ b/arch/arm/configs/kzm9g_defconfig +@@ -78,6 +78,7 @@ CONFIG_SERIAL_SH_SCI=y + CONFIG_SERIAL_SH_SCI_NR_UARTS=9 + CONFIG_SERIAL_SH_SCI_CONSOLE=y + # CONFIG_HW_RANDOM is not set ++CONFIG_I2C=y + CONFIG_I2C_CHARDEV=y + CONFIG_I2C_SH_MOBILE=y + CONFIG_GPIO_PCF857X=y +-- +1.7.9.5 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.ltsi/ltsi-makefile-addition.patch b/patches.ltsi/ltsi-makefile-addition.patch index ddba84798093d5..50bc29074f5ad9 100644 --- a/patches.ltsi/ltsi-makefile-addition.patch +++ b/patches.ltsi/ltsi-makefile-addition.patch @@ -18,7 +18,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 0 - SUBLEVEL = 33 + SUBLEVEL = 36 -EXTRAVERSION = +EXTRAVERSION = -ltsi NAME = Sneaky Weasel diff --git a/patches.lttng/lttng-update-2.0.1-to-2.0.4.patch b/patches.lttng/lttng-update-2.0.1-to-2.0.4.patch new file mode 100644 index 00000000000000..7fb335cf0ce7c6 --- /dev/null +++ b/patches.lttng/lttng-update-2.0.1-to-2.0.4.patch @@ -0,0 +1,204 @@ +From compudj@mail.openrapids.net Tue Jun 26 23:52:58 2012 +From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> +Date: Wed, 27 Jun 2012 02:52:55 -0400 +Subject: [LTSI staging] LTTng staging update 2.0.1 to 2.0.4 +To: Greg KH <gregkh@linuxfoundation.org> +Cc: ltsi-dev@lists.linuxfoundation.org +Message-ID: <20120627065255.GA6293@Krystal> +Content-Disposition: inline + + +Update LTTng in LTSI staging from lttng-modules 2.0.1 to 2.0.4. +(available at: git://git.lttng.org/lttng-modules.git) + +Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> +--- + drivers/staging/lttng/README | 43 +++++++++- + drivers/staging/lttng/instrumentation/events/lttng-module/signal.h | 37 ++++++++ + drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh | 2 + drivers/staging/lttng/lttng-events.c | 2 + drivers/staging/lttng/lttng-tracer.h | 2 + drivers/staging/lttng/probes/lttng-events.h | 2 + drivers/staging/lttng/probes/lttng-probe-statedump.c | 1 + 7 files changed, 80 insertions(+), 9 deletions(-) + +--- a/drivers/staging/lttng/README ++++ b/drivers/staging/lttng/README +@@ -1,7 +1,7 @@ + LTTng 2.0 modules + + Mathieu Desnoyers +-February 8, 2012 ++April 6, 2012 + + LTTng 2.0 kernel modules build against a vanilla or distribution kernel, without + need for additional patches. Other features: +@@ -37,9 +37,44 @@ LTTng 0.x patchset, but the lttng-module + 0.x, so both tracers cannot be installed at the same time for a given + kernel version. + +-LTTng-modules depends on having kallsyms enabled in the kernel it is +-built against. Ideally, if you want to have system call tracing, the +-"Trace Syscalls" feature should be enabled too. ++ ++* Kernel config options required ++ ++CONFIG_MODULES: required ++ * Kernel modules support. ++CONFIG_KALLSYMS: required ++ * See wrapper/ files. This is necessary until the few required missing ++ symbols are exported to GPL modules from mainline. ++CONFIG_HIGH_RES_TIMERS: required ++ * Needed for LTTng 2.0 clock source. ++CONFIG_TRACEPOINTS: required ++ kernel tracepoint instrumentation ++ * Enabled as side-effect of any of the perf/ftrace/blktrace ++ instrumentation features. ++ ++ ++* Kernel config options supported (optional) ++ ++The following kernel configuration options will affect the features ++available from LTTng: ++ ++ ++CONFIG_HAVE_SYSCALL_TRACEPOINTS: ++ system call tracing ++ lttng enable-event -k --syscall ++ lttng enable-event -k -a ++CONFIG_PERF_EVENTS: ++ performance counters ++ lttng add-context -t perf:* ++CONFIG_EVENT_TRACING: ++ needed to allow block layer tracing ++CONFIG_KPROBES: ++ Dynamic probe. ++ lttng enable-event -k --probe ... ++CONFIG_KRETPROBES: ++ Dynamic function entry/return probe. ++ lttng enable-event -k --function ... ++ + + * Note about Perf PMU counters support + +--- a/drivers/staging/lttng/instrumentation/events/lttng-module/signal.h ++++ b/drivers/staging/lttng/instrumentation/events/lttng-module/signal.h +@@ -5,6 +5,7 @@ + #define _TRACE_SIGNAL_H + + #include <linux/tracepoint.h> ++#include <linux/version.h> + + #ifndef _TRACE_SIGNAL_DEF + #define _TRACE_SIGNAL_DEF +@@ -34,6 +35,7 @@ + * SEND_SIG_NOINFO means that si_code is SI_USER, and SEND_SIG_PRIV + * means that si_code is SI_KERNEL. + */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + TRACE_EVENT(signal_generate, + + TP_PROTO(int sig, struct siginfo *info, struct task_struct *task), +@@ -44,7 +46,7 @@ TRACE_EVENT(signal_generate, + __field( int, sig ) + __field( int, errno ) + __field( int, code ) +- __array( char, comm, TASK_COMM_LEN ) ++ __array_text( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + ), + +@@ -59,6 +61,39 @@ TRACE_EVENT(signal_generate, + __entry->sig, __entry->errno, __entry->code, + __entry->comm, __entry->pid) + ) ++#else ++TRACE_EVENT(signal_generate, ++ ++ TP_PROTO(int sig, struct siginfo *info, struct task_struct *task, ++ int group, int result), ++ ++ TP_ARGS(sig, info, task, group, result), ++ ++ TP_STRUCT__entry( ++ __field( int, sig ) ++ __field( int, errno ) ++ __field( int, code ) ++ __array_text( char, comm, TASK_COMM_LEN ) ++ __field( pid_t, pid ) ++ __field( int, group ) ++ __field( int, result ) ++ ), ++ ++ TP_fast_assign( ++ tp_assign(sig, sig) ++ TP_STORE_SIGINFO(info) ++ tp_memcpy(comm, task->comm, TASK_COMM_LEN) ++ tp_assign(pid, task->pid) ++ tp_assign(group, group) ++ tp_assign(result, result) ++ ), ++ ++ TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d grp=%d res=%d", ++ __entry->sig, __entry->errno, __entry->code, ++ __entry->comm, __entry->pid, __entry->group, ++ __entry->result) ++) ++#endif + + /** + * signal_deliver - called when a signal is delivered +--- a/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh ++++ b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh +@@ -59,7 +59,7 @@ if [ "$CLASS" = integers ]; then + + NRARGS=0 + +-echo \ ++echo -e \ + 'SC_DECLARE_EVENT_CLASS_NOARGS(syscalls_noargs,\n'\ + ' TP_STRUCT__entry(),\n'\ + ' TP_fast_assign(),\n'\ +--- a/drivers/staging/lttng/lttng-events.c ++++ b/drivers/staging/lttng/lttng-events.c +@@ -292,7 +292,7 @@ struct lttng_event *lttng_event_create(s + int ret; + + mutex_lock(&sessions_mutex); +- if (chan->free_event_id == -1UL) ++ if (chan->free_event_id == -1U) + goto full; + /* + * This is O(n^2) (for each event, the loop is called at event +--- a/drivers/staging/lttng/lttng-tracer.h ++++ b/drivers/staging/lttng/lttng-tracer.h +@@ -40,7 +40,7 @@ + + #define LTTNG_MODULES_MAJOR_VERSION 2 + #define LTTNG_MODULES_MINOR_VERSION 0 +-#define LTTNG_MODULES_PATCHLEVEL_VERSION 1 ++#define LTTNG_MODULES_PATCHLEVEL_VERSION 4 + + #define LTTNG_VERSION_NAME "Annedd'ale" + #define LTTNG_VERSION_DESCRIPTION \ +--- a/drivers/staging/lttng/probes/lttng-events.h ++++ b/drivers/staging/lttng/probes/lttng-events.h +@@ -18,7 +18,7 @@ + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +- ++#include <linux/uaccess.h> + #include <linux/debugfs.h> + #include "lttng.h" + #include "lttng-types.h" +--- a/drivers/staging/lttng/probes/lttng-probe-statedump.c ++++ b/drivers/staging/lttng/probes/lttng-probe-statedump.c +@@ -27,6 +27,7 @@ + #include <linux/ip.h> + #include <linux/netdevice.h> + #include <linux/inetdevice.h> ++#include <linux/sched.h> + #include "../lttng-events.h" + + /* diff --git a/patches.r8a66597-udc/001-usb-gadget-add-platform-module-alias-where-it-is-missing.patch b/patches.r8a66597-udc/001-usb-gadget-add-platform-module-alias-where-it-is-missing.patch new file mode 100644 index 00000000000000..390208c0854498 --- /dev/null +++ b/patches.r8a66597-udc/001-usb-gadget-add-platform-module-alias-where-it-is-missing.patch @@ -0,0 +1,52 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 23:23:26 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 29 May 2012 15:22:23 +0900 +Subject: [LTSI-dev] [PATCH 01/12] usb: gadget: add platform module alias where it is missing +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC46B1F.6040202@renesas.com> + + +>From 2db193dbaf8523e7ebfd9d16add47a85435b6b54 Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Wed, 29 Jun 2011 16:41:55 +0300 +Subject: usb: gadget: add platform module alias where it is missing + +Without it udev won't be able to load the driver once it notices the +device unbound. + +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Signed-off-by: Felipe Balbi <balbi@ti.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 86081d7be34e0f80dc5c46391ec927fc4f350462) + +Conflicts: + + drivers/usb/gadget/ci13xxx_msm.c + drivers/usb/gadget/mv_udc_core.c + drivers/usb/gadget/net2272.c + drivers/usb/gadget/s3c-hsudc.c + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/usb/gadget/r8a66597-udc.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c +index 6dcc1f6..600a2e7 100644 +--- a/drivers/usb/gadget/r8a66597-udc.c ++++ b/drivers/usb/gadget/r8a66597-udc.c +@@ -1679,6 +1679,7 @@ static struct platform_driver r8a66597_driver = { + .name = (char *) udc_name, + }, + }; ++MODULE_ALIAS("platform:r8a66597_udc"); + + static int __init r8a66597_udc_init(void) + { +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.r8a66597-udc/002-usb-update-email-address-in-r8a66597-udc-and-m66592-udc.patch b/patches.r8a66597-udc/002-usb-update-email-address-in-r8a66597-udc-and-m66592-udc.patch new file mode 100644 index 00000000000000..a6fea327f2f4e0 --- /dev/null +++ b/patches.r8a66597-udc/002-usb-update-email-address-in-r8a66597-udc-and-m66592-udc.patch @@ -0,0 +1,61 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 23:22:33 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 29 May 2012 15:22:28 +0900 +Subject: [LTSI-dev] [PATCH 02/12] usb: update email address in r8a66597-udc and m66592-udc +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC46B24.2010604@renesas.com> + + +>From d747c5ba902336200056de795e1187109178c59a Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Fri, 8 Jul 2011 14:51:21 +0900 +Subject: usb: update email address in r8a66597-udc and m66592-udc + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Felipe Balbi <balbi@ti.com> +(cherry picked from commit 5db05c09ac107ef957b7a052d7bba8190c93b460) + +Conflicts: + + drivers/usb/gadget/m66592-udc.c + drivers/usb/gadget/m66592-udc.h + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/usb/gadget/r8a66597-udc.c | 2 +- + drivers/usb/gadget/r8a66597-udc.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c +index 600a2e7..9fc3979 100644 +--- a/drivers/usb/gadget/r8a66597-udc.c ++++ b/drivers/usb/gadget/r8a66597-udc.c +@@ -3,7 +3,7 @@ + * + * Copyright (C) 2006-2009 Renesas Solutions Corp. + * +- * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> ++ * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> + * + * 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 +diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h +index 5fc22e0..503f766 100644 +--- a/drivers/usb/gadget/r8a66597-udc.h ++++ b/drivers/usb/gadget/r8a66597-udc.h +@@ -3,7 +3,7 @@ + * + * Copyright (C) 2007-2009 Renesas Solutions Corp. + * +- * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> ++ * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> + * + * 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 +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.r8a66597-udc/003-usb-gadget-r8a66597-udc-make-buswait-configurable-through-platform-data.patch b/patches.r8a66597-udc/003-usb-gadget-r8a66597-udc-make-buswait-configurable-through-platform-data.patch new file mode 100644 index 00000000000000..d5b936dece469b --- /dev/null +++ b/patches.r8a66597-udc/003-usb-gadget-r8a66597-udc-make-buswait-configurable-through-platform-data.patch @@ -0,0 +1,74 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 23:22:40 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 29 May 2012 15:22:35 +0900 +Subject: [LTSI-dev] [PATCH 03/12] usb: gadget: r8a66597-udc: Make BUSWAIT configurable through platform data +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC46B2B.7010109@renesas.com> + + +>From 0d5a5cc7d8b2da62c70d9ab7a9cdd626b889c745 Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Fri, 8 Jul 2011 14:51:27 +0900 +Subject: usb: gadget: r8a66597-udc: Make BUSWAIT configurable through platform data + +BUSWAIT is a 4-bit-wide value that controls the number of access waits +from the CPU to on-chip USB module. b'0000 inserts 0 wait (2 access +cycles) and b'1111 inserts 15 waits (17 access cycles, hardware +initial value), respectively. + +BUSWAIT value depends on peripheral clock frequency supplied to on-chip +of each CPU, hence should be configurable through platform data. + +Note that this patch assumes that b'0000 (0 wait, 2 access cycles) is +rerely used and considered as invalid. If valid 'buswait' data is not +provided by platform, initial b'1111 (15 waits, 17 access cycles) will +be applied as a safe default. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Felipe Balbi <balbi@ti.com> +(cherry picked from commit 5154e9f126c1d2ee8f5f93d9954f83d82b2d5e64) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/usb/gadget/r8a66597-udc.c | 6 +++++- + include/linux/usb/r8a66597.h | 3 +++ + 2 files changed, 8 insertions(+), 1 deletions(-) + +diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c +index 9fc3979..8a3a32a 100644 +--- a/drivers/usb/gadget/r8a66597-udc.c ++++ b/drivers/usb/gadget/r8a66597-udc.c +@@ -576,7 +576,11 @@ static void init_controller(struct r8a66597 *r8a66597) + u16 endian = r8a66597->pdata->endian ? BIGEND : 0; + + if (r8a66597->pdata->on_chip) { +- r8a66597_bset(r8a66597, 0x04, SYSCFG1); ++ if (r8a66597->pdata->buswait) ++ r8a66597_write(r8a66597, r8a66597->pdata->buswait, ++ SYSCFG1); ++ else ++ r8a66597_write(r8a66597, 0x0f, SYSCFG1); + r8a66597_bset(r8a66597, HSE, SYSCFG0); + + r8a66597_bclr(r8a66597, USBE, SYSCFG0); +diff --git a/include/linux/usb/r8a66597.h b/include/linux/usb/r8a66597.h +index 26d2167..6e1bfae 100644 +--- a/include/linux/usb/r8a66597.h ++++ b/include/linux/usb/r8a66597.h +@@ -31,6 +31,9 @@ struct r8a66597_platdata { + /* This callback can control port power instead of DVSTCTR register. */ + void (*port_power)(int port, int power); + ++ /* This parameter is for BUSWAIT */ ++ u16 buswait; ++ + /* set one = on chip controller, set zero = external controller */ + unsigned on_chip:1; + +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.r8a66597-udc/004-usb-gadget-r8a66597-udc-add-support-for-test_mode.patch b/patches.r8a66597-udc/004-usb-gadget-r8a66597-udc-add-support-for-test_mode.patch new file mode 100644 index 00000000000000..841a2cf6a729d9 --- /dev/null +++ b/patches.r8a66597-udc/004-usb-gadget-r8a66597-udc-add-support-for-test_mode.patch @@ -0,0 +1,85 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 23:23:26 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 29 May 2012 15:22:41 +0900 +Subject: [LTSI-dev] [PATCH 04/12] usb: gadget: r8a66597-udc: add support for TEST_MODE +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC46B31.90404@renesas.com> + + +>From b136f6dc4b62945390fa5fb8dcc2d876f894a11b Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Fri, 8 Jul 2011 14:51:14 +0900 +Subject: usb: gadget: r8a66597-udc: add support for TEST_MODE + +The USB high speed device must support the TEST_MODE, but the driver +didn't support it. When we sent the SET_FEATURE for TEST_MODE to +the driver, the request was successful, but the module didn't enter +the TEST_MODE. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Felipe Balbi <balbi@ti.com> +(cherry picked from commit 96fe53ef5498ba130b2f054f2de38e090ddaa55f) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/usb/gadget/r8a66597-udc.c | 23 ++++++++++++++++++++++- + 1 files changed, 22 insertions(+), 1 deletions(-) + +diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c +index 8a3a32a..eb1ad72 100644 +--- a/drivers/usb/gadget/r8a66597-udc.c ++++ b/drivers/usb/gadget/r8a66597-udc.c +@@ -622,6 +622,7 @@ static void disable_controller(struct r8a66597 *r8a66597) + { + if (r8a66597->pdata->on_chip) { + r8a66597_bset(r8a66597, SCKE, SYSCFG0); ++ r8a66597_bclr(r8a66597, UTST, TESTMODE); + + /* disable interrupts */ + r8a66597_write(r8a66597, 0, INTENB0); +@@ -639,6 +640,7 @@ static void disable_controller(struct r8a66597 *r8a66597) + r8a66597_bclr(r8a66597, SCKE, SYSCFG0); + + } else { ++ r8a66597_bclr(r8a66597, UTST, TESTMODE); + r8a66597_bclr(r8a66597, SCKE, SYSCFG0); + udelay(1); + r8a66597_bclr(r8a66597, PLLC, SYSCFG0); +@@ -1003,10 +1005,29 @@ static void clear_feature(struct r8a66597 *r8a66597, + + static void set_feature(struct r8a66597 *r8a66597, struct usb_ctrlrequest *ctrl) + { ++ u16 tmp; ++ int timeout = 3000; + + switch (ctrl->bRequestType & USB_RECIP_MASK) { + case USB_RECIP_DEVICE: +- control_end(r8a66597, 1); ++ switch (le16_to_cpu(ctrl->wValue)) { ++ case USB_DEVICE_TEST_MODE: ++ control_end(r8a66597, 1); ++ /* Wait for the completion of status stage */ ++ do { ++ tmp = r8a66597_read(r8a66597, INTSTS0) & CTSQ; ++ udelay(1); ++ } while (tmp != CS_IDST || timeout-- > 0); ++ ++ if (tmp == CS_IDST) ++ r8a66597_bset(r8a66597, ++ le16_to_cpu(ctrl->wIndex >> 8), ++ TESTMODE); ++ break; ++ default: ++ pipe_stall(r8a66597, 0); ++ break; ++ } + break; + case USB_RECIP_INTERFACE: + control_end(r8a66597, 1); +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.r8a66597-udc/005-usb-gadget-clean-up-fsf-boilerplate-text.patch b/patches.r8a66597-udc/005-usb-gadget-clean-up-fsf-boilerplate-text.patch new file mode 100644 index 00000000000000..91309889b3f079 --- /dev/null +++ b/patches.r8a66597-udc/005-usb-gadget-clean-up-fsf-boilerplate-text.patch @@ -0,0 +1,145 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 23:23:29 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 29 May 2012 15:22:51 +0900 +Subject: [LTSI-dev] [PATCH 05/12] usb gadget: clean up FSF boilerplate text +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC46B3B.4070502@renesas.com> + + +>From 4c3d87deff2bb6be573b7f9c1c6736e66fad712a Mon Sep 17 00:00:00 2001 +From: Klaus Schwarzkopf <schwarzkopf@sensortherm.de> +Date: Fri, 9 Sep 2011 16:10:44 +0200 +Subject: usb gadget: clean up FSF boilerplate text + +remove the following two paragraphs as they are not needed: + +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. + +Signed-off-by: Klaus Schwarzkopf <schwarzkopf@sensortherm.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 28c9fc68ebd32d473a8787d05c74e3f39c6c866b) + +Conflicts: + + drivers/usb/gadget/amd5536udc.c + drivers/usb/gadget/amd5536udc.h + drivers/usb/gadget/at91_udc.c + drivers/usb/gadget/at91_udc.h + drivers/usb/gadget/cdc2.c + drivers/usb/gadget/ci13xxx_msm.c + drivers/usb/gadget/composite.c + drivers/usb/gadget/config.c + drivers/usb/gadget/dbgp.c + drivers/usb/gadget/dummy_hcd.c + drivers/usb/gadget/epautoconf.c + drivers/usb/gadget/ether.c + drivers/usb/gadget/f_ecm.c + drivers/usb/gadget/f_eem.c + drivers/usb/gadget/f_fs.c + drivers/usb/gadget/f_hid.c + drivers/usb/gadget/f_loopback.c + drivers/usb/gadget/f_ncm.c + drivers/usb/gadget/f_obex.c + drivers/usb/gadget/f_phonet.c + drivers/usb/gadget/f_rndis.c + drivers/usb/gadget/f_sourcesink.c + drivers/usb/gadget/f_subset.c + drivers/usb/gadget/f_uvc.c + drivers/usb/gadget/f_uvc.h + drivers/usb/gadget/fusb300_udc.c + drivers/usb/gadget/fusb300_udc.h + drivers/usb/gadget/g_ffs.c + drivers/usb/gadget/hid.c + drivers/usb/gadget/imx_udc.h + drivers/usb/gadget/inode.c + drivers/usb/gadget/langwell_udc.c + drivers/usb/gadget/langwell_udc.h + drivers/usb/gadget/m66592-udc.c + drivers/usb/gadget/m66592-udc.h + drivers/usb/gadget/mass_storage.c + drivers/usb/gadget/multi.c + drivers/usb/gadget/ncm.c + drivers/usb/gadget/ndis.h + drivers/usb/gadget/net2280.c + drivers/usb/gadget/net2280.h + drivers/usb/gadget/omap_udc.c + drivers/usb/gadget/pch_udc.c + drivers/usb/gadget/printer.c + drivers/usb/gadget/pxa25x_udc.c + drivers/usb/gadget/pxa25x_udc.h + drivers/usb/gadget/pxa27x_udc.c + drivers/usb/gadget/pxa27x_udc.h + drivers/usb/gadget/s3c2410_udc.c + drivers/usb/gadget/s3c2410_udc.h + drivers/usb/gadget/storage_common.c + drivers/usb/gadget/u_ether.c + drivers/usb/gadget/u_ether.h + drivers/usb/gadget/uvc.h + drivers/usb/gadget/uvc_queue.c + drivers/usb/gadget/uvc_v4l2.c + drivers/usb/gadget/uvc_video.c + drivers/usb/gadget/webcam.c + drivers/usb/gadget/zero.c + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/usb/gadget/r8a66597-udc.c | 10 ---------- + drivers/usb/gadget/r8a66597-udc.h | 10 ---------- + 2 files changed, 0 insertions(+), 20 deletions(-) + +diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c +index eb1ad72..fe3313a 100644 +--- a/drivers/usb/gadget/r8a66597-udc.c ++++ b/drivers/usb/gadget/r8a66597-udc.c +@@ -8,16 +8,6 @@ + * 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/module.h> +diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h +index 503f766..a373c4e 100644 +--- a/drivers/usb/gadget/r8a66597-udc.h ++++ b/drivers/usb/gadget/r8a66597-udc.h +@@ -8,16 +8,6 @@ + * 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 +- * + */ + + #ifndef __R8A66597_H__ +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.r8a66597-udc/006-usb-irq-remove-irqf_disabled.patch b/patches.r8a66597-udc/006-usb-irq-remove-irqf_disabled.patch new file mode 100644 index 00000000000000..9fbc2940c64832 --- /dev/null +++ b/patches.r8a66597-udc/006-usb-irq-remove-irqf_disabled.patch @@ -0,0 +1,102 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 23:23:31 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 29 May 2012 15:22:59 +0900 +Subject: [LTSI-dev] [PATCH 06/12] USB: irq: Remove IRQF_DISABLED +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC46B43.3050307@renesas.com> + + +>From 1c1d88148ed0c54c58f7426b49c417c44bb68eeb Mon Sep 17 00:00:00 2001 +From: Yong Zhang <yong.zhang0@gmail.com> +Date: Wed, 7 Sep 2011 16:10:52 +0800 +Subject: USB: irq: Remove IRQF_DISABLED + +This flag is a NOOP and can be removed now. + +Signed-off-by: Yong Zhang <yong.zhang0@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit b5dd18d8747010e3f3eb1cc76a49f94291938559) + +Conflicts: + + drivers/usb/core/hcd-pci.c + drivers/usb/gadget/at91_udc.c + drivers/usb/gadget/fusb300_udc.c + drivers/usb/gadget/imx_udc.c + drivers/usb/gadget/m66592-udc.c + drivers/usb/gadget/mv_udc_core.c + drivers/usb/gadget/omap_udc.c + drivers/usb/gadget/pxa25x_udc.c + drivers/usb/gadget/r8a66597-udc.c + drivers/usb/gadget/s3c2410_udc.c + drivers/usb/host/ehci-ath79.c + drivers/usb/host/ehci-au1xxx.c + drivers/usb/host/ehci-fsl.c + drivers/usb/host/ehci-mxc.c + drivers/usb/host/ehci-octeon.c + drivers/usb/host/ehci-omap.c + drivers/usb/host/ehci-orion.c + drivers/usb/host/ehci-ps3.c + drivers/usb/host/ehci-s5p.c + drivers/usb/host/ehci-sh.c + drivers/usb/host/ehci-spear.c + drivers/usb/host/ehci-tegra.c + drivers/usb/host/ehci-vt8500.c + drivers/usb/host/fhci-hcd.c + drivers/usb/host/imx21-hcd.c + drivers/usb/host/isp116x-hcd.c + drivers/usb/host/isp1362-hcd.c + drivers/usb/host/isp1760-if.c + drivers/usb/host/ohci-ath79.c + drivers/usb/host/ohci-au1xxx.c + drivers/usb/host/ohci-da8xx.c + drivers/usb/host/ohci-ep93xx.c + drivers/usb/host/ohci-octeon.c + drivers/usb/host/ohci-omap.c + drivers/usb/host/ohci-omap3.c + drivers/usb/host/ohci-pnx4008.c + drivers/usb/host/ohci-pnx8550.c + drivers/usb/host/ohci-ppc-of.c + drivers/usb/host/ohci-ppc-soc.c + drivers/usb/host/ohci-ps3.c + drivers/usb/host/ohci-pxa27x.c + drivers/usb/host/ohci-s3c2410.c + drivers/usb/host/ohci-sa1111.c + drivers/usb/host/ohci-sh.c + drivers/usb/host/ohci-sm501.c + drivers/usb/host/ohci-spear.c + drivers/usb/host/ohci-ssb.c + drivers/usb/host/ohci-tmio.c + drivers/usb/host/r8a66597-hcd.c + drivers/usb/host/sl811-hcd.c + drivers/usb/host/xhci-pci.c + drivers/usb/musb/musbhsdma.c + drivers/usb/otg/isp1301_omap.c + drivers/usb/renesas_usbhs/mod.c + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/usb/gadget/r8a66597-udc.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c +index fe3313a..460b3bf 100644 +--- a/drivers/usb/gadget/r8a66597-udc.c ++++ b/drivers/usb/gadget/r8a66597-udc.c +@@ -1618,7 +1618,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) + + disable_controller(r8a66597); /* make sure controller is disabled */ + +- ret = request_irq(irq, r8a66597_irq, IRQF_DISABLED | IRQF_SHARED, ++ ret = request_irq(irq, r8a66597_irq, IRQF_SHARED, + udc_name, r8a66597); + if (ret < 0) { + printk(KERN_ERR "request_irq error (%d)\n", ret); +-- +1.7.1 + +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.r8a66597-udc/007-usb-gadget-r8a66597-udc-change-prototype-of-r8a66597_write_fifo.patch b/patches.r8a66597-udc/007-usb-gadget-r8a66597-udc-change-prototype-of-r8a66597_write_fifo.patch new file mode 100644 index 00000000000000..2bd54abcceb715 --- /dev/null +++ b/patches.r8a66597-udc/007-usb-gadget-r8a66597-udc-change-prototype-of-r8a66597_write_fifo.patch @@ -0,0 +1,70 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 23:23:10 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 29 May 2012 15:23:05 +0900 +Subject: [LTSI-dev] [PATCH 07/12] usb: gadget: r8a66597-udc: change prototype of r8a66597_write_fifo +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC46B49.5010102@renesas.com> + + +>From f29c87e4cdae1df5b2871e87c67799bc51766e2a Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Fri, 30 Sep 2011 20:07:08 +0900 +Subject: usb: gadget: r8a66597-udc: change prototype of r8a66597_write_fifo + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Felipe Balbi <balbi@ti.com> +(cherry picked from commit 0a85577627fc81936d3dbdfb349964024adcb01d) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/usb/gadget/r8a66597-udc.c | 4 ++-- + drivers/usb/gadget/r8a66597-udc.h | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c +index 460b3bf..3450038 100644 +--- a/drivers/usb/gadget/r8a66597-udc.c ++++ b/drivers/usb/gadget/r8a66597-udc.c +@@ -723,7 +723,7 @@ static void irq_ep0_write(struct r8a66597_ep *ep, struct r8a66597_request *req) + /* write fifo */ + if (req->req.buf) { + if (size > 0) +- r8a66597_write_fifo(r8a66597, ep->fifoaddr, buf, size); ++ r8a66597_write_fifo(r8a66597, ep, buf, size); + if ((size == 0) || ((size % ep->ep.maxpacket) != 0)) + r8a66597_bset(r8a66597, BVAL, ep->fifoctr); + } +@@ -770,7 +770,7 @@ static void irq_packet_write(struct r8a66597_ep *ep, + + /* write fifo */ + if (req->req.buf) { +- r8a66597_write_fifo(r8a66597, ep->fifoaddr, buf, size); ++ r8a66597_write_fifo(r8a66597, ep, buf, size); + if ((size == 0) + || ((size % ep->ep.maxpacket) != 0) + || ((bufsize != ep->ep.maxpacket) +diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h +index a373c4e..31047f8 100644 +--- a/drivers/usb/gadget/r8a66597-udc.h ++++ b/drivers/usb/gadget/r8a66597-udc.h +@@ -173,11 +173,11 @@ static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, + } + + static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, +- unsigned long offset, ++ struct r8a66597_ep *ep, + unsigned char *buf, + int len) + { +- void __iomem *fifoaddr = r8a66597->reg + offset; ++ void __iomem *fifoaddr = r8a66597->reg + ep->fifoaddr; + int adj = 0; + int i; + +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.r8a66597-udc/008-usb-r8a66597-hcd-add-function-for-external-controller.patch b/patches.r8a66597-udc/008-usb-r8a66597-hcd-add-function-for-external-controller.patch new file mode 100644 index 00000000000000..e5efd83f843824 --- /dev/null +++ b/patches.r8a66597-udc/008-usb-r8a66597-hcd-add-function-for-external-controller.patch @@ -0,0 +1,53 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 23:23:19 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 29 May 2012 15:23:15 +0900 +Subject: [LTSI-dev] [PATCH 08/12] usb: r8a66597-hcd: add function for external controller +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC46B53.2070602@renesas.com> + + +>From 8eb5b6c291ca376adaff5cd123cfc39e186b30ee Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Thu, 7 Jul 2011 09:57:10 +0900 +Subject: usb: r8a66597-hcd: add function for external controller + +R8A66597 has the pin of WR0 and WR1. So, if one write-pin of CPU +connects to the pins, we have to change the setting of FIFOSEL +register in the controller. If we don't change the setting, +the controller cannot send the data of odd length. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit f2e9039a43b01f01cab9dfaea2cad5f304fb3343) + +Conflicts: + + drivers/usb/host/r8a66597-hcd.c + drivers/usb/host/r8a66597.h + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + include/linux/usb/r8a66597.h | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +diff --git a/include/linux/usb/r8a66597.h b/include/linux/usb/r8a66597.h +index 6e1bfae..7cd89e7 100644 +--- a/include/linux/usb/r8a66597.h ++++ b/include/linux/usb/r8a66597.h +@@ -45,6 +45,9 @@ struct r8a66597_platdata { + + /* set one = big endian, set zero = little endian */ + unsigned endian:1; ++ ++ /* (external controller only) set one = WR0_N shorted to WR1_N */ ++ unsigned wr0_shorted_to_wr1:1; + }; + + /* Register definitions */ +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.r8a66597-udc/009-usb-gadget-r8a66597-udc-add-function-for-external-controller.patch b/patches.r8a66597-udc/009-usb-gadget-r8a66597-udc-add-function-for-external-controller.patch new file mode 100644 index 00000000000000..8683cb5ff5755a --- /dev/null +++ b/patches.r8a66597-udc/009-usb-gadget-r8a66597-udc-add-function-for-external-controller.patch @@ -0,0 +1,95 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 23:23:25 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 29 May 2012 15:23:22 +0900 +Subject: [LTSI-dev] [PATCH 09/12] usb: gadget: r8a66597-udc: add function for external controller +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC46B5A.8080304@renesas.com> + + +>From 0a5c27afa82c8b475eca91e74664dd90f4827faf Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Fri, 30 Sep 2011 20:07:21 +0900 +Subject: usb: gadget: r8a66597-udc: add function for external controller + +R8A66597 has the pin of WR0 and WR1. So, if one write-pin of CPU +connects to the pins, we have to change the setting of FIFOSEL +register in the controller. If we don't change the setting, +the controller cannot send the data of odd length. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Felipe Balbi <balbi@ti.com> +(cherry picked from commit 5c481a639068ac34bd1dcd183f37b7a65d0e3841) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/usb/gadget/r8a66597-udc.h | 34 +++++++++++++++++++--------------- + 1 files changed, 19 insertions(+), 15 deletions(-) + +diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h +index 31047f8..f9ac2d7 100644 +--- a/drivers/usb/gadget/r8a66597-udc.h ++++ b/drivers/usb/gadget/r8a66597-udc.h +@@ -172,6 +172,21 @@ static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, + iowrite16(val, r8a66597->reg + offset); + } + ++static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, ++ u16 val, u16 pat, unsigned long offset) ++{ ++ u16 tmp; ++ tmp = r8a66597_read(r8a66597, offset); ++ tmp = tmp & (~pat); ++ tmp = tmp | val; ++ r8a66597_write(r8a66597, tmp, offset); ++} ++ ++#define r8a66597_bclr(r8a66597, val, offset) \ ++ r8a66597_mdfy(r8a66597, 0, val, offset) ++#define r8a66597_bset(r8a66597, val, offset) \ ++ r8a66597_mdfy(r8a66597, val, 0, offset) ++ + static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, + struct r8a66597_ep *ep, + unsigned char *buf, +@@ -205,18 +220,12 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, + adj = 0x01; /* 16-bit wide */ + } + ++ if (r8a66597->pdata->wr0_shorted_to_wr1) ++ r8a66597_bclr(r8a66597, MBW_16, ep->fifosel); + for (i = 0; i < len; i++) + iowrite8(buf[i], fifoaddr + adj - (i & adj)); +-} +- +-static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, +- u16 val, u16 pat, unsigned long offset) +-{ +- u16 tmp; +- tmp = r8a66597_read(r8a66597, offset); +- tmp = tmp & (~pat); +- tmp = tmp | val; +- r8a66597_write(r8a66597, tmp, offset); ++ if (r8a66597->pdata->wr0_shorted_to_wr1) ++ r8a66597_bclr(r8a66597, MBW_16, ep->fifosel); + } + + static inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata) +@@ -241,11 +250,6 @@ static inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata) + return clock; + } + +-#define r8a66597_bclr(r8a66597, val, offset) \ +- r8a66597_mdfy(r8a66597, 0, val, offset) +-#define r8a66597_bset(r8a66597, val, offset) \ +- r8a66597_mdfy(r8a66597, val, 0, offset) +- + #define get_pipectr_addr(pipenum) (PIPE1CTR + (pipenum - 1) * 2) + + #define enable_irq_ready(r8a66597, pipenum) \ +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.r8a66597-udc/010-usb-gadget-r8a66597-udc-use-dev_-instead-of-printk.patch b/patches.r8a66597-udc/010-usb-gadget-r8a66597-udc-use-dev_-instead-of-printk.patch new file mode 100644 index 00000000000000..131ff5e91d05b9 --- /dev/null +++ b/patches.r8a66597-udc/010-usb-gadget-r8a66597-udc-use-dev_-instead-of-printk.patch @@ -0,0 +1,322 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 23:23:33 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 29 May 2012 15:23:28 +0900 +Subject: [LTSI-dev] [PATCH 10/12] usb: gadget: r8a66597-udc: use dev_*() instead of printk() +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC46B60.1090300@renesas.com> + + +>From 427c3968e29e2754b6ec7639ada0cc87b6dbecf9 Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Fri, 30 Sep 2011 20:07:30 +0900 +Subject: usb: gadget: r8a66597-udc: use dev_*() instead of printk() + +This patch also fix the balance of braces. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Felipe Balbi <balbi@ti.com> +(cherry picked from commit 12158f4280b4d42ef03b70a47d11b48dd8aad511) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/usb/gadget/r8a66597-udc.c | 99 ++++++++++++++++++++++--------------- + drivers/usb/gadget/r8a66597-udc.h | 1 + + 2 files changed, 60 insertions(+), 40 deletions(-) + +diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c +index 3450038..fd9ce15 100644 +--- a/drivers/usb/gadget/r8a66597-udc.c ++++ b/drivers/usb/gadget/r8a66597-udc.c +@@ -105,13 +105,15 @@ static inline u16 control_reg_get_pid(struct r8a66597 *r8a66597, u16 pipenum) + u16 pid = 0; + unsigned long offset; + +- if (pipenum == 0) ++ if (pipenum == 0) { + pid = r8a66597_read(r8a66597, DCPCTR) & PID; +- else if (pipenum < R8A66597_MAX_NUM_PIPE) { ++ } else if (pipenum < R8A66597_MAX_NUM_PIPE) { + offset = get_pipectr_addr(pipenum); + pid = r8a66597_read(r8a66597, offset) & PID; +- } else +- printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); ++ } else { ++ dev_err(r8a66597_to_dev(r8a66597), "unexpect pipe num (%d)\n", ++ pipenum); ++ } + + return pid; + } +@@ -121,13 +123,15 @@ static inline void control_reg_set_pid(struct r8a66597 *r8a66597, u16 pipenum, + { + unsigned long offset; + +- if (pipenum == 0) ++ if (pipenum == 0) { + r8a66597_mdfy(r8a66597, pid, PID, DCPCTR); +- else if (pipenum < R8A66597_MAX_NUM_PIPE) { ++ } else if (pipenum < R8A66597_MAX_NUM_PIPE) { + offset = get_pipectr_addr(pipenum); + r8a66597_mdfy(r8a66597, pid, PID, offset); +- } else +- printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); ++ } else { ++ dev_err(r8a66597_to_dev(r8a66597), "unexpect pipe num (%d)\n", ++ pipenum); ++ } + } + + static inline void pipe_start(struct r8a66597 *r8a66597, u16 pipenum) +@@ -150,13 +154,15 @@ static inline u16 control_reg_get(struct r8a66597 *r8a66597, u16 pipenum) + u16 ret = 0; + unsigned long offset; + +- if (pipenum == 0) ++ if (pipenum == 0) { + ret = r8a66597_read(r8a66597, DCPCTR); +- else if (pipenum < R8A66597_MAX_NUM_PIPE) { ++ } else if (pipenum < R8A66597_MAX_NUM_PIPE) { + offset = get_pipectr_addr(pipenum); + ret = r8a66597_read(r8a66597, offset); +- } else +- printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); ++ } else { ++ dev_err(r8a66597_to_dev(r8a66597), "unexpect pipe num (%d)\n", ++ pipenum); ++ } + + return ret; + } +@@ -167,13 +173,15 @@ static inline void control_reg_sqclr(struct r8a66597 *r8a66597, u16 pipenum) + + pipe_stop(r8a66597, pipenum); + +- if (pipenum == 0) ++ if (pipenum == 0) { + r8a66597_bset(r8a66597, SQCLR, DCPCTR); +- else if (pipenum < R8A66597_MAX_NUM_PIPE) { ++ } else if (pipenum < R8A66597_MAX_NUM_PIPE) { + offset = get_pipectr_addr(pipenum); + r8a66597_bset(r8a66597, SQCLR, offset); +- } else +- printk(KERN_ERR "unexpect pipe num(%d)\n", pipenum); ++ } else { ++ dev_err(r8a66597_to_dev(r8a66597), "unexpect pipe num (%d)\n", ++ pipenum); ++ } + } + + static inline int get_buffer_size(struct r8a66597 *r8a66597, u16 pipenum) +@@ -287,17 +295,18 @@ static void pipe_buffer_release(struct r8a66597 *r8a66597, + if (info->pipe == 0) + return; + +- if (is_bulk_pipe(info->pipe)) ++ if (is_bulk_pipe(info->pipe)) { + r8a66597->bulk--; +- else if (is_interrupt_pipe(info->pipe)) ++ } else if (is_interrupt_pipe(info->pipe)) { + r8a66597->interrupt--; +- else if (is_isoc_pipe(info->pipe)) { ++ } else if (is_isoc_pipe(info->pipe)) { + r8a66597->isochronous--; + if (info->type == R8A66597_BULK) + r8a66597->bulk--; +- } else +- printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n", +- info->pipe); ++ } else { ++ dev_err(r8a66597_to_dev(r8a66597), ++ "ep_release: unexpect pipenum (%d)\n", info->pipe); ++ } + } + + static void pipe_initialize(struct r8a66597_ep *ep) +@@ -371,7 +380,8 @@ static int alloc_pipe_config(struct r8a66597_ep *ep, + case USB_ENDPOINT_XFER_BULK: + if (r8a66597->bulk >= R8A66597_MAX_NUM_BULK) { + if (r8a66597->isochronous >= R8A66597_MAX_NUM_ISOC) { +- printk(KERN_ERR "bulk pipe is insufficient\n"); ++ dev_err(r8a66597_to_dev(r8a66597), ++ "bulk pipe is insufficient\n"); + return -ENODEV; + } else { + info.pipe = R8A66597_BASE_PIPENUM_ISOC +@@ -387,7 +397,8 @@ static int alloc_pipe_config(struct r8a66597_ep *ep, + break; + case USB_ENDPOINT_XFER_INT: + if (r8a66597->interrupt >= R8A66597_MAX_NUM_INT) { +- printk(KERN_ERR "interrupt pipe is insufficient\n"); ++ dev_err(r8a66597_to_dev(r8a66597), ++ "interrupt pipe is insufficient\n"); + return -ENODEV; + } + info.pipe = R8A66597_BASE_PIPENUM_INT + r8a66597->interrupt; +@@ -396,7 +407,8 @@ static int alloc_pipe_config(struct r8a66597_ep *ep, + break; + case USB_ENDPOINT_XFER_ISOC: + if (r8a66597->isochronous >= R8A66597_MAX_NUM_ISOC) { +- printk(KERN_ERR "isochronous pipe is insufficient\n"); ++ dev_err(r8a66597_to_dev(r8a66597), ++ "isochronous pipe is insufficient\n"); + return -ENODEV; + } + info.pipe = R8A66597_BASE_PIPENUM_ISOC + r8a66597->isochronous; +@@ -404,7 +416,7 @@ static int alloc_pipe_config(struct r8a66597_ep *ep, + counter = &r8a66597->isochronous; + break; + default: +- printk(KERN_ERR "unexpect xfer type\n"); ++ dev_err(r8a66597_to_dev(r8a66597), "unexpect xfer type\n"); + return -EINVAL; + } + ep->type = info.type; +@@ -419,7 +431,8 @@ static int alloc_pipe_config(struct r8a66597_ep *ep, + + ret = pipe_buffer_setting(r8a66597, &info); + if (ret < 0) { +- printk(KERN_ERR "pipe_buffer_setting fail\n"); ++ dev_err(r8a66597_to_dev(r8a66597), ++ "pipe_buffer_setting fail\n"); + return ret; + } + +@@ -554,7 +567,8 @@ static void start_ep0(struct r8a66597_ep *ep, struct r8a66597_request *req) + control_end(ep->r8a66597, 0); + break; + default: +- printk(KERN_ERR "start_ep0: unexpect ctsq(%x)\n", ctsq); ++ dev_err(r8a66597_to_dev(ep->r8a66597), ++ "start_ep0: unexpect ctsq(%x)\n", ctsq); + break; + } + } +@@ -708,7 +722,8 @@ static void irq_ep0_write(struct r8a66597_ep *ep, struct r8a66597_request *req) + do { + tmp = r8a66597_read(r8a66597, ep->fifoctr); + if (i++ > 100000) { +- printk(KERN_ERR "pipe0 is busy. maybe cpu i/o bus" ++ dev_err(r8a66597_to_dev(r8a66597), ++ "pipe0 is busy. maybe cpu i/o bus " + "conflict. please power off this controller."); + return; + } +@@ -759,7 +774,8 @@ static void irq_packet_write(struct r8a66597_ep *ep, + if (unlikely((tmp & FRDY) == 0)) { + pipe_stop(r8a66597, pipenum); + pipe_irq_disable(r8a66597, pipenum); +- printk(KERN_ERR "write fifo not ready. pipnum=%d\n", pipenum); ++ dev_err(r8a66597_to_dev(r8a66597), ++ "write fifo not ready. pipnum=%d\n", pipenum); + return; + } + +@@ -809,7 +825,7 @@ static void irq_packet_read(struct r8a66597_ep *ep, + req->req.status = -EPIPE; + pipe_stop(r8a66597, pipenum); + pipe_irq_disable(r8a66597, pipenum); +- printk(KERN_ERR "read fifo not ready"); ++ dev_err(r8a66597_to_dev(r8a66597), "read fifo not ready"); + return; + } + +@@ -1085,7 +1101,7 @@ static void r8a66597_update_usb_speed(struct r8a66597 *r8a66597) + break; + default: + r8a66597->gadget.speed = USB_SPEED_UNKNOWN; +- printk(KERN_ERR "USB speed unknown\n"); ++ dev_err(r8a66597_to_dev(r8a66597), "USB speed unknown\n"); + } + } + +@@ -1148,7 +1164,8 @@ __acquires(r8a66597->lock) + control_end(r8a66597, 0); + break; + default: +- printk(KERN_ERR "ctrl_stage: unexpect ctsq(%x)\n", ctsq); ++ dev_err(r8a66597_to_dev(r8a66597), ++ "ctrl_stage: unexpect ctsq(%x)\n", ctsq); + break; + } + } +@@ -1448,13 +1465,15 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + + retval = device_add(&r8a66597->gadget.dev); + if (retval) { +- printk(KERN_ERR "device_add error (%d)\n", retval); ++ dev_err(r8a66597_to_dev(r8a66597), "device_add error (%d)\n", ++ retval); + goto error; + } + + retval = bind(&r8a66597->gadget); + if (retval) { +- printk(KERN_ERR "bind to driver error (%d)\n", retval); ++ dev_err(r8a66597_to_dev(r8a66597), ++ "bind to driver error (%d)\n", retval); + device_del(&r8a66597->gadget.dev); + goto error; + } +@@ -1554,7 +1573,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENODEV; +- printk(KERN_ERR "platform_get_resource error.\n"); ++ dev_err(&pdev->dev, "platform_get_resource error.\n"); + goto clean_up; + } + +@@ -1564,14 +1583,14 @@ static int __init r8a66597_probe(struct platform_device *pdev) + + if (irq < 0) { + ret = -ENODEV; +- printk(KERN_ERR "platform_get_irq error.\n"); ++ dev_err(&pdev->dev, "platform_get_irq error.\n"); + goto clean_up; + } + + reg = ioremap(res->start, resource_size(res)); + if (reg == NULL) { + ret = -ENOMEM; +- printk(KERN_ERR "ioremap error.\n"); ++ dev_err(&pdev->dev, "ioremap error.\n"); + goto clean_up; + } + +@@ -1579,7 +1598,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) + r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); + if (r8a66597 == NULL) { + ret = -ENOMEM; +- printk(KERN_ERR "kzalloc error\n"); ++ dev_err(&pdev->dev, "kzalloc error\n"); + goto clean_up; + } + +@@ -1621,7 +1640,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) + ret = request_irq(irq, r8a66597_irq, IRQF_SHARED, + udc_name, r8a66597); + if (ret < 0) { +- printk(KERN_ERR "request_irq error (%d)\n", ret); ++ dev_err(&pdev->dev, "request_irq error (%d)\n", ret); + goto clean_up2; + } + +diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h +index f9ac2d7..832ee59 100644 +--- a/drivers/usb/gadget/r8a66597-udc.h ++++ b/drivers/usb/gadget/r8a66597-udc.h +@@ -114,6 +114,7 @@ struct r8a66597 { + #define gadget_to_r8a66597(_gadget) \ + container_of(_gadget, struct r8a66597, gadget) + #define r8a66597_to_gadget(r8a66597) (&r8a66597->gadget) ++#define r8a66597_to_dev(r8a66597) (r8a66597->gadget.dev.parent) + + static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset) + { +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.r8a66597-udc/011-usb-gadget-r8a66597-udc-add-support-for-sudmac.patch b/patches.r8a66597-udc/011-usb-gadget-r8a66597-udc-add-support-for-sudmac.patch new file mode 100644 index 00000000000000..fa0335d7b72893 --- /dev/null +++ b/patches.r8a66597-udc/011-usb-gadget-r8a66597-udc-add-support-for-sudmac.patch @@ -0,0 +1,677 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 23:23:37 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 29 May 2012 15:23:32 +0900 +Subject: [LTSI-dev] [PATCH 11/12] usb: gadget: r8a66597-udc: add support for SUDMAC +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC46B64.4080400@renesas.com> + + +>From 5011d0b167a9536dd46c10afb8afa96c60bb4193 Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Fri, 30 Sep 2011 20:07:38 +0900 +Subject: usb: gadget: r8a66597-udc: add support for SUDMAC + +SH7757 has a USB function with internal DMA controller (SUDMAC). +This patch supports the SUDMAC. The SUDMAC is incompatible with +general-purpose DMAC. So, it doesn't use dmaengine. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Felipe Balbi <balbi@ti.com> +(cherry picked from commit b8a56e17e18cca2402b390c10b8d7f3cd0f6265b) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/usb/gadget/r8a66597-udc.c | 364 +++++++++++++++++++++++++++++++++++-- + drivers/usb/gadget/r8a66597-udc.h | 26 +++- + include/linux/usb/r8a66597.h | 60 ++++++ + 3 files changed, 430 insertions(+), 20 deletions(-) + +diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c +index fd9ce15..7f37a2a 100644 +--- a/drivers/usb/gadget/r8a66597-udc.c ++++ b/drivers/usb/gadget/r8a66597-udc.c +@@ -18,13 +18,14 @@ + #include <linux/clk.h> + #include <linux/err.h> + #include <linux/slab.h> ++#include <linux/dma-mapping.h> + + #include <linux/usb/ch9.h> + #include <linux/usb/gadget.h> + + #include "r8a66597-udc.h" + +-#define DRIVER_VERSION "2009-08-18" ++#define DRIVER_VERSION "2011-09-26" + + static const char udc_name[] = "r8a66597_udc"; + static const char *r8a66597_ep_name[] = { +@@ -184,6 +185,54 @@ static inline void control_reg_sqclr(struct r8a66597 *r8a66597, u16 pipenum) + } + } + ++static void control_reg_sqset(struct r8a66597 *r8a66597, u16 pipenum) ++{ ++ unsigned long offset; ++ ++ pipe_stop(r8a66597, pipenum); ++ ++ if (pipenum == 0) { ++ r8a66597_bset(r8a66597, SQSET, DCPCTR); ++ } else if (pipenum < R8A66597_MAX_NUM_PIPE) { ++ offset = get_pipectr_addr(pipenum); ++ r8a66597_bset(r8a66597, SQSET, offset); ++ } else { ++ dev_err(r8a66597_to_dev(r8a66597), ++ "unexpect pipe num(%d)\n", pipenum); ++ } ++} ++ ++static u16 control_reg_sqmon(struct r8a66597 *r8a66597, u16 pipenum) ++{ ++ unsigned long offset; ++ ++ if (pipenum == 0) { ++ return r8a66597_read(r8a66597, DCPCTR) & SQMON; ++ } else if (pipenum < R8A66597_MAX_NUM_PIPE) { ++ offset = get_pipectr_addr(pipenum); ++ return r8a66597_read(r8a66597, offset) & SQMON; ++ } else { ++ dev_err(r8a66597_to_dev(r8a66597), ++ "unexpect pipe num(%d)\n", pipenum); ++ } ++ ++ return 0; ++} ++ ++static u16 save_usb_toggle(struct r8a66597 *r8a66597, u16 pipenum) ++{ ++ return control_reg_sqmon(r8a66597, pipenum); ++} ++ ++static void restore_usb_toggle(struct r8a66597 *r8a66597, u16 pipenum, ++ u16 toggle) ++{ ++ if (toggle) ++ control_reg_sqset(r8a66597, pipenum); ++ else ++ control_reg_sqclr(r8a66597, pipenum); ++} ++ + static inline int get_buffer_size(struct r8a66597 *r8a66597, u16 pipenum) + { + u16 tmp; +@@ -220,18 +269,51 @@ static inline unsigned short mbw_value(struct r8a66597 *r8a66597) + return MBW_16; + } + ++static void r8a66597_change_curpipe(struct r8a66597 *r8a66597, u16 pipenum, ++ u16 isel, u16 fifosel) ++{ ++ u16 tmp, mask, loop; ++ int i = 0; ++ ++ if (!pipenum) { ++ mask = ISEL | CURPIPE; ++ loop = isel; ++ } else { ++ mask = CURPIPE; ++ loop = pipenum; ++ } ++ r8a66597_mdfy(r8a66597, loop, mask, fifosel); ++ ++ do { ++ tmp = r8a66597_read(r8a66597, fifosel); ++ if (i++ > 1000000) { ++ dev_err(r8a66597_to_dev(r8a66597), ++ "r8a66597: register%x, loop %x " ++ "is timeout\n", fifosel, loop); ++ break; ++ } ++ ndelay(1); ++ } while ((tmp & mask) != loop); ++} ++ + static inline void pipe_change(struct r8a66597 *r8a66597, u16 pipenum) + { + struct r8a66597_ep *ep = r8a66597->pipenum2ep[pipenum]; + + if (ep->use_dma) +- return; ++ r8a66597_bclr(r8a66597, DREQE, ep->fifosel); + + r8a66597_mdfy(r8a66597, pipenum, CURPIPE, ep->fifosel); + + ndelay(450); + +- r8a66597_bset(r8a66597, mbw_value(r8a66597), ep->fifosel); ++ if (r8a66597_is_sudmac(r8a66597) && ep->use_dma) ++ r8a66597_bclr(r8a66597, mbw_value(r8a66597), ep->fifosel); ++ else ++ r8a66597_bset(r8a66597, mbw_value(r8a66597), ep->fifosel); ++ ++ if (ep->use_dma) ++ r8a66597_bset(r8a66597, DREQE, ep->fifosel); + } + + static int pipe_buffer_setting(struct r8a66597 *r8a66597, +@@ -336,9 +418,15 @@ static void r8a66597_ep_setting(struct r8a66597 *r8a66597, + ep->fifoaddr = CFIFO; + ep->fifosel = CFIFOSEL; + ep->fifoctr = CFIFOCTR; +- ep->fifotrn = 0; + + ep->pipectr = get_pipectr_addr(pipenum); ++ if (is_bulk_pipe(pipenum) || is_isoc_pipe(pipenum)) { ++ ep->pipetre = get_pipetre_addr(pipenum); ++ ep->pipetrn = get_pipetrn_addr(pipenum); ++ } else { ++ ep->pipetre = 0; ++ ep->pipetrn = 0; ++ } + ep->pipenum = pipenum; + ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); + r8a66597->pipenum2ep[pipenum] = ep; +@@ -498,6 +586,124 @@ static void start_ep0_write(struct r8a66597_ep *ep, + } + } + ++static void disable_fifosel(struct r8a66597 *r8a66597, u16 pipenum, ++ u16 fifosel) ++{ ++ u16 tmp; ++ ++ tmp = r8a66597_read(r8a66597, fifosel) & CURPIPE; ++ if (tmp == pipenum) ++ r8a66597_change_curpipe(r8a66597, 0, 0, fifosel); ++} ++ ++static void change_bfre_mode(struct r8a66597 *r8a66597, u16 pipenum, ++ int enable) ++{ ++ struct r8a66597_ep *ep = r8a66597->pipenum2ep[pipenum]; ++ u16 tmp, toggle; ++ ++ /* check current BFRE bit */ ++ r8a66597_write(r8a66597, pipenum, PIPESEL); ++ tmp = r8a66597_read(r8a66597, PIPECFG) & R8A66597_BFRE; ++ if ((enable && tmp) || (!enable && !tmp)) ++ return; ++ ++ /* change BFRE bit */ ++ pipe_stop(r8a66597, pipenum); ++ disable_fifosel(r8a66597, pipenum, CFIFOSEL); ++ disable_fifosel(r8a66597, pipenum, D0FIFOSEL); ++ disable_fifosel(r8a66597, pipenum, D1FIFOSEL); ++ ++ toggle = save_usb_toggle(r8a66597, pipenum); ++ ++ r8a66597_write(r8a66597, pipenum, PIPESEL); ++ if (enable) ++ r8a66597_bset(r8a66597, R8A66597_BFRE, PIPECFG); ++ else ++ r8a66597_bclr(r8a66597, R8A66597_BFRE, PIPECFG); ++ ++ /* initialize for internal BFRE flag */ ++ r8a66597_bset(r8a66597, ACLRM, ep->pipectr); ++ r8a66597_bclr(r8a66597, ACLRM, ep->pipectr); ++ ++ restore_usb_toggle(r8a66597, pipenum, toggle); ++} ++ ++static int sudmac_alloc_channel(struct r8a66597 *r8a66597, ++ struct r8a66597_ep *ep, ++ struct r8a66597_request *req) ++{ ++ struct r8a66597_dma *dma; ++ ++ if (!r8a66597_is_sudmac(r8a66597)) ++ return -ENODEV; ++ ++ /* Check transfer type */ ++ if (!is_bulk_pipe(ep->pipenum)) ++ return -EIO; ++ ++ if (r8a66597->dma.used) ++ return -EBUSY; ++ ++ /* set SUDMAC parameters */ ++ dma = &r8a66597->dma; ++ dma->used = 1; ++ if (ep->desc->bEndpointAddress & USB_DIR_IN) { ++ dma->dir = 1; ++ } else { ++ dma->dir = 0; ++ change_bfre_mode(r8a66597, ep->pipenum, 1); ++ } ++ ++ /* set r8a66597_ep paramters */ ++ ep->use_dma = 1; ++ ep->dma = dma; ++ ep->fifoaddr = D0FIFO; ++ ep->fifosel = D0FIFOSEL; ++ ep->fifoctr = D0FIFOCTR; ++ ++ /* dma mapping */ ++ req->req.dma = dma_map_single(r8a66597_to_dev(ep->r8a66597), ++ req->req.buf, req->req.length, ++ dma->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); ++ ++ return 0; ++} ++ ++static void sudmac_free_channel(struct r8a66597 *r8a66597, ++ struct r8a66597_ep *ep, ++ struct r8a66597_request *req) ++{ ++ if (!r8a66597_is_sudmac(r8a66597)) ++ return; ++ ++ dma_unmap_single(r8a66597_to_dev(ep->r8a66597), ++ req->req.dma, req->req.length, ++ ep->dma->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); ++ ++ r8a66597_bclr(r8a66597, DREQE, ep->fifosel); ++ r8a66597_change_curpipe(r8a66597, 0, 0, ep->fifosel); ++ ++ ep->dma->used = 0; ++ ep->use_dma = 0; ++ ep->fifoaddr = CFIFO; ++ ep->fifosel = CFIFOSEL; ++ ep->fifoctr = CFIFOCTR; ++} ++ ++static void sudmac_start(struct r8a66597 *r8a66597, struct r8a66597_ep *ep, ++ struct r8a66597_request *req) ++{ ++ BUG_ON(req->req.length == 0); ++ ++ r8a66597_sudmac_write(r8a66597, LBA_WAIT, CH0CFG); ++ r8a66597_sudmac_write(r8a66597, req->req.dma, CH0BA); ++ r8a66597_sudmac_write(r8a66597, req->req.length, CH0BBC); ++ r8a66597_sudmac_write(r8a66597, CH0ENDE, DINTCTRL); ++ ++ r8a66597_sudmac_write(r8a66597, DEN, CH0DEN); ++} ++ + static void start_packet_write(struct r8a66597_ep *ep, + struct r8a66597_request *req) + { +@@ -508,11 +714,29 @@ static void start_packet_write(struct r8a66597_ep *ep, + disable_irq_empty(r8a66597, ep->pipenum); + pipe_start(r8a66597, ep->pipenum); + +- tmp = r8a66597_read(r8a66597, ep->fifoctr); +- if (unlikely((tmp & FRDY) == 0)) +- pipe_irq_enable(r8a66597, ep->pipenum); +- else +- irq_packet_write(ep, req); ++ if (req->req.length == 0) { ++ transfer_complete(ep, req, 0); ++ } else { ++ r8a66597_write(r8a66597, ~(1 << ep->pipenum), BRDYSTS); ++ if (sudmac_alloc_channel(r8a66597, ep, req) < 0) { ++ /* PIO mode */ ++ pipe_change(r8a66597, ep->pipenum); ++ disable_irq_empty(r8a66597, ep->pipenum); ++ pipe_start(r8a66597, ep->pipenum); ++ tmp = r8a66597_read(r8a66597, ep->fifoctr); ++ if (unlikely((tmp & FRDY) == 0)) ++ pipe_irq_enable(r8a66597, ep->pipenum); ++ else ++ irq_packet_write(ep, req); ++ } else { ++ /* DMA mode */ ++ pipe_change(r8a66597, ep->pipenum); ++ disable_irq_nrdy(r8a66597, ep->pipenum); ++ pipe_start(r8a66597, ep->pipenum); ++ enable_irq_nrdy(r8a66597, ep->pipenum); ++ sudmac_start(r8a66597, ep, req); ++ } ++ } + } + + static void start_packet_read(struct r8a66597_ep *ep, +@@ -527,17 +751,26 @@ static void start_packet_read(struct r8a66597_ep *ep, + pipe_start(r8a66597, pipenum); + pipe_irq_enable(r8a66597, pipenum); + } else { +- if (ep->use_dma) { +- r8a66597_bset(r8a66597, TRCLR, ep->fifosel); +- pipe_change(r8a66597, pipenum); +- r8a66597_bset(r8a66597, TRENB, ep->fifosel); ++ pipe_stop(r8a66597, pipenum); ++ if (ep->pipetre) { ++ enable_irq_nrdy(r8a66597, pipenum); ++ r8a66597_write(r8a66597, TRCLR, ep->pipetre); + r8a66597_write(r8a66597, +- (req->req.length + ep->ep.maxpacket - 1) +- / ep->ep.maxpacket, +- ep->fifotrn); ++ DIV_ROUND_UP(req->req.length, ep->ep.maxpacket), ++ ep->pipetrn); ++ r8a66597_bset(r8a66597, TRENB, ep->pipetre); ++ } ++ ++ if (sudmac_alloc_channel(r8a66597, ep, req) < 0) { ++ /* PIO mode */ ++ change_bfre_mode(r8a66597, ep->pipenum, 0); ++ pipe_start(r8a66597, pipenum); /* trigger once */ ++ pipe_irq_enable(r8a66597, pipenum); ++ } else { ++ pipe_change(r8a66597, pipenum); ++ sudmac_start(r8a66597, ep, req); ++ pipe_start(r8a66597, pipenum); /* trigger once */ + } +- pipe_start(r8a66597, pipenum); /* trigger once */ +- pipe_irq_enable(r8a66597, pipenum); + } + } + +@@ -694,6 +927,9 @@ __acquires(r8a66597->lock) + if (!list_empty(&ep->queue)) + restart = 1; + ++ if (ep->use_dma) ++ sudmac_free_channel(ep->r8a66597, ep, req); ++ + spin_unlock(&ep->r8a66597->lock); + req->req.complete(&ep->ep, &req->req); + spin_lock(&ep->r8a66597->lock); +@@ -1170,6 +1406,65 @@ __acquires(r8a66597->lock) + } + } + ++static void sudmac_finish(struct r8a66597 *r8a66597, struct r8a66597_ep *ep) ++{ ++ u16 pipenum; ++ struct r8a66597_request *req; ++ u32 len; ++ int i = 0; ++ ++ pipenum = ep->pipenum; ++ pipe_change(r8a66597, pipenum); ++ ++ while (!(r8a66597_read(r8a66597, ep->fifoctr) & FRDY)) { ++ udelay(1); ++ if (unlikely(i++ >= 10000)) { /* timeout = 10 msec */ ++ dev_err(r8a66597_to_dev(r8a66597), ++ "%s: FRDY was not set (%d)\n", ++ __func__, pipenum); ++ return; ++ } ++ } ++ ++ r8a66597_bset(r8a66597, BCLR, ep->fifoctr); ++ req = get_request_from_ep(ep); ++ ++ /* prepare parameters */ ++ len = r8a66597_sudmac_read(r8a66597, CH0CBC); ++ req->req.actual += len; ++ ++ /* clear */ ++ r8a66597_sudmac_write(r8a66597, CH0STCLR, DSTSCLR); ++ ++ /* check transfer finish */ ++ if ((!req->req.zero && (req->req.actual == req->req.length)) ++ || (len % ep->ep.maxpacket)) { ++ if (ep->dma->dir) { ++ disable_irq_ready(r8a66597, pipenum); ++ enable_irq_empty(r8a66597, pipenum); ++ } else { ++ /* Clear the interrupt flag for next transfer */ ++ r8a66597_write(r8a66597, ~(1 << pipenum), BRDYSTS); ++ transfer_complete(ep, req, 0); ++ } ++ } ++} ++ ++static void r8a66597_sudmac_irq(struct r8a66597 *r8a66597) ++{ ++ u32 irqsts; ++ struct r8a66597_ep *ep; ++ u16 pipenum; ++ ++ irqsts = r8a66597_sudmac_read(r8a66597, DINTSTS); ++ if (irqsts & CH0ENDS) { ++ r8a66597_sudmac_write(r8a66597, CH0ENDC, DINTSTSCLR); ++ pipenum = (r8a66597_read(r8a66597, D0FIFOSEL) & CURPIPE); ++ ep = r8a66597->pipenum2ep[pipenum]; ++ sudmac_finish(r8a66597, ep); ++ } ++} ++ + static irqreturn_t r8a66597_irq(int irq, void *_r8a66597) + { + struct r8a66597 *r8a66597 = _r8a66597; +@@ -1180,6 +1475,9 @@ static irqreturn_t r8a66597_irq(int irq, void *_r8a66597) + u16 savepipe; + u16 mask0; + ++ if (r8a66597_is_sudmac(r8a66597)) ++ r8a66597_sudmac_irq(r8a66597); ++ + spin_lock(&r8a66597->lock); + + intsts0 = r8a66597_read(r8a66597, INTSTS0); +@@ -1541,6 +1839,8 @@ static int __exit r8a66597_remove(struct platform_device *pdev) + + del_timer_sync(&r8a66597->timer); + iounmap(r8a66597->reg); ++ if (r8a66597->pdata->sudmac) ++ iounmap(r8a66597->sudmac_reg); + free_irq(platform_get_irq(pdev, 0), r8a66597); + r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); + #ifdef CONFIG_HAVE_CLK +@@ -1557,6 +1857,26 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r) + { + } + ++static int __init r8a66597_sudmac_ioremap(struct r8a66597 *r8a66597, ++ struct platform_device *pdev) ++{ ++ struct resource *res; ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sudmac"); ++ if (!res) { ++ dev_err(&pdev->dev, "platform_get_resource error(sudmac).\n"); ++ return -ENODEV; ++ } ++ ++ r8a66597->sudmac_reg = ioremap(res->start, resource_size(res)); ++ if (r8a66597->sudmac_reg == NULL) { ++ dev_err(&pdev->dev, "ioremap error(sudmac).\n"); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ + static int __init r8a66597_probe(struct platform_device *pdev) + { + #ifdef CONFIG_HAVE_CLK +@@ -1634,6 +1954,11 @@ static int __init r8a66597_probe(struct platform_device *pdev) + clk_enable(r8a66597->clk); + } + #endif ++ if (r8a66597->pdata->sudmac) { ++ ret = r8a66597_sudmac_ioremap(r8a66597, pdev); ++ if (ret < 0) ++ goto clean_up2; ++ } + + disable_controller(r8a66597); /* make sure controller is disabled */ + +@@ -1666,7 +1991,6 @@ static int __init r8a66597_probe(struct platform_device *pdev) + r8a66597->ep[0].fifoaddr = CFIFO; + r8a66597->ep[0].fifosel = CFIFOSEL; + r8a66597->ep[0].fifoctr = CFIFOCTR; +- r8a66597->ep[0].fifotrn = 0; + r8a66597->ep[0].pipectr = get_pipectr_addr(0); + r8a66597->pipenum2ep[0] = &r8a66597->ep[0]; + r8a66597->epaddr2ep[0] = &r8a66597->ep[0]; +@@ -1695,6 +2019,8 @@ clean_up2: + #endif + clean_up: + if (r8a66597) { ++ if (r8a66597->sudmac_reg) ++ iounmap(r8a66597->sudmac_reg); + if (r8a66597->ep0_req) + r8a66597_free_request(&r8a66597->ep[0].ep, + r8a66597->ep0_req); +diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h +index 832ee59..8e3de61 100644 +--- a/drivers/usb/gadget/r8a66597-udc.h ++++ b/drivers/usb/gadget/r8a66597-udc.h +@@ -43,6 +43,7 @@ + ((pipenum >= R8A66597_BASE_PIPENUM_ISOC) && \ + (pipenum < (R8A66597_BASE_PIPENUM_ISOC + R8A66597_MAX_NUM_ISOC))) + ++#define r8a66597_is_sudmac(r8a66597) (r8a66597->pdata->sudmac) + struct r8a66597_pipe_info { + u16 pipe; + u16 epnum; +@@ -60,6 +61,7 @@ struct r8a66597_request { + struct r8a66597_ep { + struct usb_ep ep; + struct r8a66597 *r8a66597; ++ struct r8a66597_dma *dma; + + struct list_head queue; + unsigned busy:1; +@@ -75,13 +77,20 @@ struct r8a66597_ep { + unsigned char fifoaddr; + unsigned char fifosel; + unsigned char fifoctr; +- unsigned char fifotrn; + unsigned char pipectr; ++ unsigned char pipetre; ++ unsigned char pipetrn; ++}; ++ ++struct r8a66597_dma { ++ unsigned used:1; ++ unsigned dir:1; /* 1 = IN(write), 0 = OUT(read) */ + }; + + struct r8a66597 { + spinlock_t lock; + void __iomem *reg; ++ void __iomem *sudmac_reg; + + #ifdef CONFIG_HAVE_CLK + struct clk *clk; +@@ -94,6 +103,7 @@ struct r8a66597 { + struct r8a66597_ep ep[R8A66597_MAX_NUM_PIPE]; + struct r8a66597_ep *pipenum2ep[R8A66597_MAX_NUM_PIPE]; + struct r8a66597_ep *epaddr2ep[16]; ++ struct r8a66597_dma dma; + + struct timer_list timer; + struct usb_request *ep0_req; /* for internal request */ +@@ -251,7 +261,21 @@ static inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata) + return clock; + } + ++static inline u32 r8a66597_sudmac_read(struct r8a66597 *r8a66597, ++ unsigned long offset) ++{ ++ return ioread32(r8a66597->sudmac_reg + offset); ++} ++ ++static inline void r8a66597_sudmac_write(struct r8a66597 *r8a66597, u32 val, ++ unsigned long offset) ++{ ++ iowrite32(val, r8a66597->sudmac_reg + offset); ++} ++ + #define get_pipectr_addr(pipenum) (PIPE1CTR + (pipenum - 1) * 2) ++#define get_pipetre_addr(pipenum) (PIPE1TRE + (pipenum - 1) * 4) ++#define get_pipetrn_addr(pipenum) (PIPE1TRN + (pipenum - 1) * 4) + + #define enable_irq_ready(r8a66597, pipenum) \ + enable_pipe_irq(r8a66597, pipenum, BRDYENB) +diff --git a/include/linux/usb/r8a66597.h b/include/linux/usb/r8a66597.h +index 7cd89e7..1f5ef88 100644 +--- a/include/linux/usb/r8a66597.h ++++ b/include/linux/usb/r8a66597.h +@@ -48,6 +48,9 @@ struct r8a66597_platdata { + + /* (external controller only) set one = WR0_N shorted to WR1_N */ + unsigned wr0_shorted_to_wr1:1; ++ ++ /* set one = using SUDMAC */ ++ unsigned sudmac:1; + }; + + /* Register definitions */ +@@ -417,5 +420,62 @@ struct r8a66597_platdata { + #define USBSPD 0x00C0 + #define RTPORT 0x0001 + ++/* SUDMAC registers */ ++#define CH0CFG 0x00 ++#define CH1CFG 0x04 ++#define CH0BA 0x10 ++#define CH1BA 0x14 ++#define CH0BBC 0x18 ++#define CH1BBC 0x1C ++#define CH0CA 0x20 ++#define CH1CA 0x24 ++#define CH0CBC 0x28 ++#define CH1CBC 0x2C ++#define CH0DEN 0x30 ++#define CH1DEN 0x34 ++#define DSTSCLR 0x38 ++#define DBUFCTRL 0x3C ++#define DINTCTRL 0x40 ++#define DINTSTS 0x44 ++#define DINTSTSCLR 0x48 ++#define CH0SHCTRL 0x50 ++#define CH1SHCTRL 0x54 ++ ++/* SUDMAC Configuration Registers */ ++#define SENDBUFM 0x1000 /* b12: Transmit Buffer Mode */ ++#define RCVENDM 0x0100 /* b8: Receive Data Transfer End Mode */ ++#define LBA_WAIT 0x0030 /* b5-4: Local Bus Access Wait */ ++ ++/* DMA Enable Registers */ ++#define DEN 0x0001 /* b1: DMA Transfer Enable */ ++ ++/* DMA Status Clear Register */ ++#define CH1STCLR 0x0002 /* b2: Ch1 DMA Status Clear */ ++#define CH0STCLR 0x0001 /* b1: Ch0 DMA Status Clear */ ++ ++/* DMA Buffer Control Register */ ++#define CH1BUFW 0x0200 /* b9: Ch1 DMA Buffer Data Transfer Enable */ ++#define CH0BUFW 0x0100 /* b8: Ch0 DMA Buffer Data Transfer Enable */ ++#define CH1BUFS 0x0002 /* b2: Ch1 DMA Buffer Data Status */ ++#define CH0BUFS 0x0001 /* b1: Ch0 DMA Buffer Data Status */ ++ ++/* DMA Interrupt Control Register */ ++#define CH1ERRE 0x0200 /* b9: Ch1 SHwy Res Err Detect Int Enable */ ++#define CH0ERRE 0x0100 /* b8: Ch0 SHwy Res Err Detect Int Enable */ ++#define CH1ENDE 0x0002 /* b2: Ch1 DMA Transfer End Int Enable */ ++#define CH0ENDE 0x0001 /* b1: Ch0 DMA Transfer End Int Enable */ ++ ++/* DMA Interrupt Status Register */ ++#define CH1ERRS 0x0200 /* b9: Ch1 SHwy Res Err Detect Int Status */ ++#define CH0ERRS 0x0100 /* b8: Ch0 SHwy Res Err Detect Int Status */ ++#define CH1ENDS 0x0002 /* b2: Ch1 DMA Transfer End Int Status */ ++#define CH0ENDS 0x0001 /* b1: Ch0 DMA Transfer End Int Status */ ++ ++/* DMA Interrupt Status Clear Register */ ++#define CH1ERRC 0x0200 /* b9: Ch1 SHwy Res Err Detect Int Stat Clear */ ++#define CH0ERRC 0x0100 /* b8: Ch0 SHwy Res Err Detect Int Stat Clear */ ++#define CH1ENDC 0x0002 /* b2: Ch1 DMA Transfer End Int Stat Clear */ ++#define CH0ENDC 0x0001 /* b1: Ch0 DMA Transfer End Int Stat Clear */ ++ + #endif /* __LINUX_USB_R8A66597_H */ + +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.r8a66597-udc/012-usb-gadget-r8a66597-udc-fix-flush-fifo-handling.patch b/patches.r8a66597-udc/012-usb-gadget-r8a66597-udc-fix-flush-fifo-handling.patch new file mode 100644 index 00000000000000..39b779fdef8e58 --- /dev/null +++ b/patches.r8a66597-udc/012-usb-gadget-r8a66597-udc-fix-flush-fifo-handling.patch @@ -0,0 +1,46 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 23:23:40 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 29 May 2012 15:23:36 +0900 +Subject: [LTSI-dev] [PATCH 12/12] usb: gadget: r8a66597-udc: fix flush fifo handling +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC46B68.2050500@renesas.com> + + +>From 4014d3e59bb75141c49cf7161f385ff1bdaf2eed Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 31 Oct 2011 16:01:33 +0900 +Subject: usb: gadget: r8a66597-udc: fix flush fifo handling + +The "BCLR" in CFIFOCTR/DnFIFOCTR can flush the fifo of "CPU side" only. +To flush the fifo of "SIE side", we have to use the "ACLRM" in PIPEnCTR. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Felipe Balbi <balbi@ti.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +(cherry picked from commit 05bb7013038a2b609aef14ad4e07afe031daec49) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/usb/gadget/r8a66597-udc.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c +index 7f37a2a..fdd09de 100644 +--- a/drivers/usb/gadget/r8a66597-udc.c ++++ b/drivers/usb/gadget/r8a66597-udc.c +@@ -1718,6 +1718,8 @@ static void r8a66597_fifo_flush(struct usb_ep *_ep) + if (list_empty(&ep->queue) && !ep->busy) { + pipe_stop(ep->r8a66597, ep->pipenum); + r8a66597_bclr(ep->r8a66597, BCLR, ep->fifoctr); ++ r8a66597_write(ep->r8a66597, ACLRM, ep->pipectr); ++ r8a66597_write(ep->r8a66597, 0, ep->pipectr); + } + spin_unlock_irqrestore(&ep->r8a66597->lock, flags); + } +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.runtime_pm/0041-PM-Runtime-Add-macro-to-test-for-runtime-PM-events.patch b/patches.runtime_pm/0041-PM-Runtime-Add-macro-to-test-for-runtime-PM-events.patch index c9238f03735281..0019622e698ba4 100644 --- a/patches.runtime_pm/0041-PM-Runtime-Add-macro-to-test-for-runtime-PM-events.patch +++ b/patches.runtime_pm/0041-PM-Runtime-Add-macro-to-test-for-runtime-PM-events.patch @@ -55,7 +55,7 @@ Signed-off-by: Simon Horman <horms@verge.net.au> Mutual exclusion --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c -@@ -1112,7 +1112,7 @@ static int btusb_suspend(struct usb_inte +@@ -1126,7 +1126,7 @@ static int btusb_suspend(struct usb_inte return 0; spin_lock_irq(&data->txlock); @@ -138,7 +138,7 @@ Signed-off-by: Simon Horman <horms@verge.net.au> --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c -@@ -1319,7 +1319,7 @@ static int acm_suspend(struct usb_interf +@@ -1327,7 +1327,7 @@ static int acm_suspend(struct usb_interf struct acm *acm = usb_get_intfdata(intf); int cnt; @@ -279,7 +279,7 @@ Signed-off-by: Simon Horman <horms@verge.net.au> } --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c -@@ -1012,7 +1012,7 @@ static int sierra_suspend(struct usb_ser +@@ -1016,7 +1016,7 @@ static int sierra_suspend(struct usb_ser struct sierra_intf_private *intfdata; int b; diff --git a/patches.runtime_pm/0055-plist-Remove-the-need-to-supply-locks-to-plist-heads.patch b/patches.runtime_pm/0055-plist-Remove-the-need-to-supply-locks-to-plist-heads.patch index 72beeeec2b43f0..8ea194ba5e30de 100644 --- a/patches.runtime_pm/0055-plist-Remove-the-need-to-supply-locks-to-plist-heads.patch +++ b/patches.runtime_pm/0055-plist-Remove-the-need-to-supply-locks-to-plist-heads.patch @@ -203,7 +203,7 @@ Signed-off-by: Simon Horman <horms@verge.net.au> } --- a/kernel/sched.c +++ b/kernel/sched.c -@@ -7923,7 +7923,7 @@ static void init_rt_rq(struct rt_rq *rt_ +@@ -7920,7 +7920,7 @@ static void init_rt_rq(struct rt_rq *rt_ #ifdef CONFIG_SMP rt_rq->rt_nr_migratory = 0; rt_rq->overloaded = 0; @@ -212,7 +212,7 @@ Signed-off-by: Simon Horman <horms@verge.net.au> #endif rt_rq->rt_time = 0; -@@ -8128,7 +8128,7 @@ void __init sched_init(void) +@@ -8125,7 +8125,7 @@ void __init sched_init(void) #endif #ifdef CONFIG_RT_MUTEXES diff --git a/patches.runtime_pm/0113-freezer-unexport-refrigerator-and-update-try_to_free.patch b/patches.runtime_pm/0113-freezer-unexport-refrigerator-and-update-try_to_free.patch index 90922af3558db3..39966bc08edce8 100644 --- a/patches.runtime_pm/0113-freezer-unexport-refrigerator-and-update-try_to_free.patch +++ b/patches.runtime_pm/0113-freezer-unexport-refrigerator-and-update-try_to_free.patch @@ -54,11 +54,9 @@ Signed-off-by: Simon Horman <horms@verge.net.au> kernel/freezer.c | 10 +++++++--- 15 files changed, 37 insertions(+), 39 deletions(-) -diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt -index 587e082..3ab9fbd 100644 --- a/Documentation/power/freezing-of-tasks.txt +++ b/Documentation/power/freezing-of-tasks.txt -@@ -21,7 +21,7 @@ freeze_processes() (defined in kernel/power/process.c) is called. It executes +@@ -21,7 +21,7 @@ freeze_processes() (defined in kernel/po try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and either wakes them up, if they are kernel threads, or sends fake signals to them, if they are user space processes. A task that has TIF_FREEZE set, should react @@ -67,7 +65,7 @@ index 587e082..3ab9fbd 100644 kernel/freezer.c), which sets the task's PF_FROZEN flag, changes its state to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it. Then, we say that the task is 'frozen' and therefore the set of functions -@@ -29,10 +29,10 @@ handling this mechanism is referred to as 'the freezer' (these functions are +@@ -29,10 +29,10 @@ handling this mechanism is referred to a defined in kernel/power/process.c, kernel/freezer.c & include/linux/freezer.h). User space processes are generally frozen before kernel threads. @@ -82,7 +80,7 @@ index 587e082..3ab9fbd 100644 For user space processes try_to_freeze() is called automatically from the signal-handling code, but the freezable kernel threads need to call it -@@ -61,7 +61,7 @@ wait_event_freezable() and wait_event_freezable_timeout() macros. +@@ -61,7 +61,7 @@ wait_event_freezable() and wait_event_fr After the system memory state has been restored from a hibernation image and devices have been reinitialized, the function thaw_processes() is called in order to clear the PF_FROZEN flag for each frozen task. Then, the tasks that @@ -91,11 +89,9 @@ index 587e082..3ab9fbd 100644 III. Which kernel threads are freezable? -diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c -index 41c96b3..e880c79 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c -@@ -750,7 +750,7 @@ static int stir_transmit_thread(void *arg) +@@ -750,7 +750,7 @@ static int stir_transmit_thread(void *ar write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD); @@ -104,8 +100,6 @@ index 41c96b3..e880c79 100644 if (change_speed(stir, stir->speed)) break; -diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c -index 7ec1409..98ab240 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c @@ -340,7 +340,7 @@ again: @@ -117,8 +111,6 @@ index 7ec1409..98ab240 100644 } else { spin_unlock_irq(&worker->lock); if (!kthread_should_stop()) { -diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index 1ac8db5d..66f4b9e 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1479,9 +1479,7 @@ static int cleaner_kthread(void *arg) @@ -143,11 +135,9 @@ index 1ac8db5d..66f4b9e 100644 set_current_state(TASK_INTERRUPTIBLE); if (!kthread_should_stop() && !btrfs_transaction_blocked(root->fs_info)) -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index df121b2..8de0a54 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c -@@ -2820,8 +2820,7 @@ cont_thread: +@@ -2821,8 +2821,7 @@ cont_thread: } mutex_unlock(&eli->li_list_mtx); @@ -157,8 +147,6 @@ index df121b2..8de0a54 100644 cur = jiffies; if ((time_after_eq(cur, next_wakeup)) || -diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c -index 85c6292..b342c71 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -951,8 +951,8 @@ int gfs2_logd(void *data) @@ -172,8 +160,6 @@ index 85c6292..b342c71 100644 do { prepare_to_wait(&sdp->sd_logd_waitq, &wait, -diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c -index 42e8d23..2ccaaac 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -1431,8 +1431,8 @@ int gfs2_quotad(void *data) @@ -187,8 +173,6 @@ index 42e8d23..2ccaaac 100644 t = min(quotad_timeo, statfs_timeo); prepare_to_wait(&sdp->sd_quota_wait, &wait, TASK_INTERRUPTIBLE); -diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c -index 9f36384..b889c55 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c @@ -163,7 +163,7 @@ loop: @@ -200,8 +184,6 @@ index 9f36384..b889c55 100644 spin_lock(&journal->j_state_lock); } else { /* -diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c -index 40c5fb7..c7b7079 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -173,7 +173,7 @@ loop: @@ -213,8 +195,6 @@ index 40c5fb7..c7b7079 100644 write_lock(&journal->j_state_lock); } else { /* -diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c -index 583636f..c8c2d35 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -2348,7 +2348,7 @@ int jfsIOWait(void *arg) @@ -226,8 +206,6 @@ index 583636f..c8c2d35 100644 } else { set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irq(&log_redrive_lock); -diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c -index f6cc0c0..8a2f83b 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -2801,7 +2801,7 @@ int jfs_lazycommit(void *arg) @@ -248,11 +226,9 @@ index f6cc0c0..8a2f83b 100644 } else { set_current_state(TASK_INTERRUPTIBLE); TXN_UNLOCK(); -diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c -index bb24ab6..0e72ad6 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c -@@ -2470,7 +2470,7 @@ static int nilfs_segctor_thread(void *arg) +@@ -2470,7 +2470,7 @@ static int nilfs_segctor_thread(void *ar if (freezing(current)) { spin_unlock(&sci->sc_state_lock); @@ -261,8 +237,6 @@ index bb24ab6..0e72ad6 100644 spin_lock(&sci->sc_state_lock); } else { DEFINE_WAIT(wait); -diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c -index 5e68099..5930e87b 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1764,7 +1764,7 @@ xfsbufd( @@ -274,11 +248,9 @@ index 5e68099..5930e87b 100644 } else { clear_bit(XBT_FORCE_SLEEP, &target->bt_flags); } -diff --git a/include/linux/freezer.h b/include/linux/freezer.h -index aa56cf3..eb9c977 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h -@@ -47,18 +47,17 @@ static inline bool should_send_signal(struct task_struct *p) +@@ -47,18 +47,17 @@ static inline bool should_send_signal(st /* Takes and releases task alloc lock using task_lock() */ extern int thaw_process(struct task_struct *p); @@ -303,7 +275,7 @@ index aa56cf3..eb9c977 100644 } extern bool freeze_task(struct task_struct *p, bool sig_only); -@@ -171,12 +170,12 @@ static inline void set_freeze_flag(struct task_struct *p) {} +@@ -171,12 +170,12 @@ static inline void set_freeze_flag(struc static inline void clear_freeze_flag(struct task_struct *p) {} static inline int thaw_process(struct task_struct *p) { return 1; } @@ -318,8 +290,6 @@ index aa56cf3..eb9c977 100644 static inline void freezer_do_not_count(void) {} static inline void freezer_count(void) {} -diff --git a/kernel/freezer.c b/kernel/freezer.c -index 575f863..4d59904 100644 --- a/kernel/freezer.c +++ b/kernel/freezer.c @@ -23,10 +23,11 @@ static inline void frozen_process(void) @@ -364,6 +334,3 @@ index 575f863..4d59904 100644 static void fake_signal_wake_up(struct task_struct *p) { --- -1.7.10.1.362.g242cab3 - diff --git a/patches.sh7757lcr/001-spi-add-support-for-renesas-rspi.patch b/patches.sh7757lcr/001-spi-add-support-for-renesas-rspi.patch new file mode 100644 index 00000000000000..1bc26a6c4c5641 --- /dev/null +++ b/patches.sh7757lcr/001-spi-add-support-for-renesas-rspi.patch @@ -0,0 +1,595 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:46:52 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:46:46 +0900 +Subject: [LTSI-dev] [PATCH 01/21] spi: add support for Renesas RSPI +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC34986.1000802@renesas.com> + + +>From 3516d99256cdaef9cbcf5c69b5a538713c006be1 Mon Sep 17 00:00:00 2001 +From: Shimoda, Yoshihiro <yoshihiro.shimoda.uh@renesas.com> +Date: Wed, 7 Mar 2012 14:46:25 +0900 +Subject: spi: add support for Renesas RSPI + +The SH7757 has RSPI module. This patch supports it. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Grant Likely <grant.likely@secretlab.ca> +(cherry picked from commit 0b2182ddac4b8837bbba996d03b7b28f4346db0a) + +Conflicts: + + drivers/spi/Makefile + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/spi/Kconfig | 6 + + drivers/spi/Makefile | 1 + + drivers/spi/spi-rspi.c | 521 ++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 528 insertions(+), 0 deletions(-) + create mode 100644 drivers/spi/spi-rspi.c + +diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig +index de35c3a..bf331ab 100644 +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -310,6 +310,12 @@ config SPI_PXA2XX + config SPI_PXA2XX_PCI + def_bool SPI_PXA2XX && X86_32 && PCI + ++config SPI_RSPI ++ tristate "Renesas RSPI controller" ++ depends on SUPERH ++ help ++ SPI driver for Renesas RSPI blocks. ++ + config SPI_S3C24XX + tristate "Samsung S3C24XX series SPI" + depends on ARCH_S3C2410 && EXPERIMENTAL +diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile +index 0f8c69b..5997465 100644 +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -42,6 +42,7 @@ obj-$(CONFIG_SPI_FSL_LIB) += spi_fsl_lib.o + obj-$(CONFIG_SPI_FSL_ESPI) += spi_fsl_espi.o + obj-$(CONFIG_SPI_FSL_SPI) += spi_fsl_spi.o + obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o ++obj-$(CONFIG_SPI_RSPI) += spi-rspi.o + obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o + obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o + obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o +diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c +new file mode 100644 +index 0000000..354f170 +--- /dev/null ++++ b/drivers/spi/spi-rspi.c +@@ -0,0 +1,521 @@ ++/* ++ * SH RSPI driver ++ * ++ * Copyright (C) 2012 Renesas Solutions Corp. ++ * ++ * Based on spi-sh.c: ++ * Copyright (C) 2011 Renesas Solutions Corp. ++ * ++ * 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/module.h> ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/errno.h> ++#include <linux/list.h> ++#include <linux/workqueue.h> ++#include <linux/interrupt.h> ++#include <linux/platform_device.h> ++#include <linux/io.h> ++#include <linux/clk.h> ++#include <linux/spi/spi.h> ++ ++#define RSPI_SPCR 0x00 ++#define RSPI_SSLP 0x01 ++#define RSPI_SPPCR 0x02 ++#define RSPI_SPSR 0x03 ++#define RSPI_SPDR 0x04 ++#define RSPI_SPSCR 0x08 ++#define RSPI_SPSSR 0x09 ++#define RSPI_SPBR 0x0a ++#define RSPI_SPDCR 0x0b ++#define RSPI_SPCKD 0x0c ++#define RSPI_SSLND 0x0d ++#define RSPI_SPND 0x0e ++#define RSPI_SPCR2 0x0f ++#define RSPI_SPCMD0 0x10 ++#define RSPI_SPCMD1 0x12 ++#define RSPI_SPCMD2 0x14 ++#define RSPI_SPCMD3 0x16 ++#define RSPI_SPCMD4 0x18 ++#define RSPI_SPCMD5 0x1a ++#define RSPI_SPCMD6 0x1c ++#define RSPI_SPCMD7 0x1e ++ ++/* SPCR */ ++#define SPCR_SPRIE 0x80 ++#define SPCR_SPE 0x40 ++#define SPCR_SPTIE 0x20 ++#define SPCR_SPEIE 0x10 ++#define SPCR_MSTR 0x08 ++#define SPCR_MODFEN 0x04 ++#define SPCR_TXMD 0x02 ++#define SPCR_SPMS 0x01 ++ ++/* SSLP */ ++#define SSLP_SSL1P 0x02 ++#define SSLP_SSL0P 0x01 ++ ++/* SPPCR */ ++#define SPPCR_MOIFE 0x20 ++#define SPPCR_MOIFV 0x10 ++#define SPPCR_SPOM 0x04 ++#define SPPCR_SPLP2 0x02 ++#define SPPCR_SPLP 0x01 ++ ++/* SPSR */ ++#define SPSR_SPRF 0x80 ++#define SPSR_SPTEF 0x20 ++#define SPSR_PERF 0x08 ++#define SPSR_MODF 0x04 ++#define SPSR_IDLNF 0x02 ++#define SPSR_OVRF 0x01 ++ ++/* SPSCR */ ++#define SPSCR_SPSLN_MASK 0x07 ++ ++/* SPSSR */ ++#define SPSSR_SPECM_MASK 0x70 ++#define SPSSR_SPCP_MASK 0x07 ++ ++/* SPDCR */ ++#define SPDCR_SPLW 0x20 ++#define SPDCR_SPRDTD 0x10 ++#define SPDCR_SLSEL1 0x08 ++#define SPDCR_SLSEL0 0x04 ++#define SPDCR_SLSEL_MASK 0x0c ++#define SPDCR_SPFC1 0x02 ++#define SPDCR_SPFC0 0x01 ++ ++/* SPCKD */ ++#define SPCKD_SCKDL_MASK 0x07 ++ ++/* SSLND */ ++#define SSLND_SLNDL_MASK 0x07 ++ ++/* SPND */ ++#define SPND_SPNDL_MASK 0x07 ++ ++/* SPCR2 */ ++#define SPCR2_PTE 0x08 ++#define SPCR2_SPIE 0x04 ++#define SPCR2_SPOE 0x02 ++#define SPCR2_SPPE 0x01 ++ ++/* SPCMDn */ ++#define SPCMD_SCKDEN 0x8000 ++#define SPCMD_SLNDEN 0x4000 ++#define SPCMD_SPNDEN 0x2000 ++#define SPCMD_LSBF 0x1000 ++#define SPCMD_SPB_MASK 0x0f00 ++#define SPCMD_SPB_8_TO_16(bit) (((bit - 1) << 8) & SPCMD_SPB_MASK) ++#define SPCMD_SPB_20BIT 0x0000 ++#define SPCMD_SPB_24BIT 0x0100 ++#define SPCMD_SPB_32BIT 0x0200 ++#define SPCMD_SSLKP 0x0080 ++#define SPCMD_SSLA_MASK 0x0030 ++#define SPCMD_BRDV_MASK 0x000c ++#define SPCMD_CPOL 0x0002 ++#define SPCMD_CPHA 0x0001 ++ ++struct rspi_data { ++ void __iomem *addr; ++ u32 max_speed_hz; ++ struct spi_master *master; ++ struct list_head queue; ++ struct work_struct ws; ++ wait_queue_head_t wait; ++ spinlock_t lock; ++ struct clk *clk; ++ unsigned char spsr; ++}; ++ ++static void rspi_write8(struct rspi_data *rspi, u8 data, u16 offset) ++{ ++ iowrite8(data, rspi->addr + offset); ++} ++ ++static void rspi_write16(struct rspi_data *rspi, u16 data, u16 offset) ++{ ++ iowrite16(data, rspi->addr + offset); ++} ++ ++static u8 rspi_read8(struct rspi_data *rspi, u16 offset) ++{ ++ return ioread8(rspi->addr + offset); ++} ++ ++static u16 rspi_read16(struct rspi_data *rspi, u16 offset) ++{ ++ return ioread16(rspi->addr + offset); ++} ++ ++static unsigned char rspi_calc_spbr(struct rspi_data *rspi) ++{ ++ int tmp; ++ unsigned char spbr; ++ ++ tmp = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1; ++ spbr = clamp(tmp, 0, 255); ++ ++ return spbr; ++} ++ ++static void rspi_enable_irq(struct rspi_data *rspi, u8 enable) ++{ ++ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | enable, RSPI_SPCR); ++} ++ ++static void rspi_disable_irq(struct rspi_data *rspi, u8 disable) ++{ ++ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~disable, RSPI_SPCR); ++} ++ ++static int rspi_wait_for_interrupt(struct rspi_data *rspi, u8 wait_mask, ++ u8 enable_bit) ++{ ++ int ret; ++ ++ rspi->spsr = rspi_read8(rspi, RSPI_SPSR); ++ rspi_enable_irq(rspi, enable_bit); ++ ret = wait_event_timeout(rspi->wait, rspi->spsr & wait_mask, HZ); ++ if (ret == 0 && !(rspi->spsr & wait_mask)) ++ return -ETIMEDOUT; ++ ++ return 0; ++} ++ ++static void rspi_assert_ssl(struct rspi_data *rspi) ++{ ++ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR); ++} ++ ++static void rspi_negate_ssl(struct rspi_data *rspi) ++{ ++ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR); ++} ++ ++static int rspi_set_config_register(struct rspi_data *rspi, int access_size) ++{ ++ /* Sets output mode(CMOS) and MOSI signal(from previous transfer) */ ++ rspi_write8(rspi, 0x00, RSPI_SPPCR); ++ ++ /* Sets transfer bit rate */ ++ rspi_write8(rspi, rspi_calc_spbr(rspi), RSPI_SPBR); ++ ++ /* Sets number of frames to be used: 1 frame */ ++ rspi_write8(rspi, 0x00, RSPI_SPDCR); ++ ++ /* Sets RSPCK, SSL, next-access delay value */ ++ rspi_write8(rspi, 0x00, RSPI_SPCKD); ++ rspi_write8(rspi, 0x00, RSPI_SSLND); ++ rspi_write8(rspi, 0x00, RSPI_SPND); ++ ++ /* Sets parity, interrupt mask */ ++ rspi_write8(rspi, 0x00, RSPI_SPCR2); ++ ++ /* Sets SPCMD */ ++ rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP, ++ RSPI_SPCMD0); ++ ++ /* Sets RSPI mode */ ++ rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR); ++ ++ return 0; ++} ++ ++static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, ++ struct spi_transfer *t) ++{ ++ int remain = t->len; ++ u8 *data; ++ ++ data = (u8 *)t->tx_buf; ++ while (remain > 0) { ++ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, ++ RSPI_SPCR); ++ ++ if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { ++ dev_err(&rspi->master->dev, ++ "%s: tx empty timeout\n", __func__); ++ return -ETIMEDOUT; ++ } ++ ++ rspi_write16(rspi, *data, RSPI_SPDR); ++ data++; ++ remain--; ++ } ++ ++ /* Waiting for the last transmition */ ++ rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE); ++ ++ return 0; ++} ++ ++static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, ++ struct spi_transfer *t) ++{ ++ int remain = t->len; ++ u8 *data; ++ unsigned char spsr; ++ ++ spsr = rspi_read8(rspi, RSPI_SPSR); ++ if (spsr & SPSR_SPRF) ++ rspi_read16(rspi, RSPI_SPDR); /* dummy read */ ++ if (spsr & SPSR_OVRF) ++ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF, ++ RSPI_SPCR); ++ ++ data = (u8 *)t->rx_buf; ++ while (remain > 0) { ++ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, ++ RSPI_SPCR); ++ ++ if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { ++ dev_err(&rspi->master->dev, ++ "%s: tx empty timeout\n", __func__); ++ return -ETIMEDOUT; ++ } ++ /* dummy write for generate clock */ ++ rspi_write16(rspi, 0x00, RSPI_SPDR); ++ ++ if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { ++ dev_err(&rspi->master->dev, ++ "%s: receive timeout\n", __func__); ++ return -ETIMEDOUT; ++ } ++ /* SPDR allows 16 or 32-bit access only */ ++ *data = (u8)rspi_read16(rspi, RSPI_SPDR); ++ ++ data++; ++ remain--; ++ } ++ ++ return 0; ++} ++ ++static void rspi_work(struct work_struct *work) ++{ ++ struct rspi_data *rspi = container_of(work, struct rspi_data, ws); ++ struct spi_message *mesg; ++ struct spi_transfer *t; ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&rspi->lock, flags); ++ while (!list_empty(&rspi->queue)) { ++ mesg = list_entry(rspi->queue.next, struct spi_message, queue); ++ list_del_init(&mesg->queue); ++ spin_unlock_irqrestore(&rspi->lock, flags); ++ ++ rspi_assert_ssl(rspi); ++ ++ list_for_each_entry(t, &mesg->transfers, transfer_list) { ++ if (t->tx_buf) { ++ ret = rspi_send_pio(rspi, mesg, t); ++ if (ret < 0) ++ goto error; ++ } ++ if (t->rx_buf) { ++ ret = rspi_receive_pio(rspi, mesg, t); ++ if (ret < 0) ++ goto error; ++ } ++ mesg->actual_length += t->len; ++ } ++ rspi_negate_ssl(rspi); ++ ++ mesg->status = 0; ++ mesg->complete(mesg->context); ++ ++ spin_lock_irqsave(&rspi->lock, flags); ++ } ++ ++ return; ++ ++error: ++ mesg->status = ret; ++ mesg->complete(mesg->context); ++} ++ ++static int rspi_setup(struct spi_device *spi) ++{ ++ struct rspi_data *rspi = spi_master_get_devdata(spi->master); ++ ++ if (!spi->bits_per_word) ++ spi->bits_per_word = 8; ++ rspi->max_speed_hz = spi->max_speed_hz; ++ ++ rspi_set_config_register(rspi, 8); ++ ++ return 0; ++} ++ ++static int rspi_transfer(struct spi_device *spi, struct spi_message *mesg) ++{ ++ struct rspi_data *rspi = spi_master_get_devdata(spi->master); ++ unsigned long flags; ++ ++ mesg->actual_length = 0; ++ mesg->status = -EINPROGRESS; ++ ++ spin_lock_irqsave(&rspi->lock, flags); ++ list_add_tail(&mesg->queue, &rspi->queue); ++ schedule_work(&rspi->ws); ++ spin_unlock_irqrestore(&rspi->lock, flags); ++ ++ return 0; ++} ++ ++static void rspi_cleanup(struct spi_device *spi) ++{ ++} ++ ++static irqreturn_t rspi_irq(int irq, void *_sr) ++{ ++ struct rspi_data *rspi = (struct rspi_data *)_sr; ++ unsigned long spsr; ++ irqreturn_t ret = IRQ_NONE; ++ unsigned char disable_irq = 0; ++ ++ rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR); ++ if (spsr & SPSR_SPRF) ++ disable_irq |= SPCR_SPRIE; ++ if (spsr & SPSR_SPTEF) ++ disable_irq |= SPCR_SPTIE; ++ ++ if (disable_irq) { ++ ret = IRQ_HANDLED; ++ rspi_disable_irq(rspi, disable_irq); ++ wake_up(&rspi->wait); ++ } ++ ++ return ret; ++} ++ ++static int __devexit rspi_remove(struct platform_device *pdev) ++{ ++ struct rspi_data *rspi = dev_get_drvdata(&pdev->dev); ++ ++ spi_unregister_master(rspi->master); ++ free_irq(platform_get_irq(pdev, 0), rspi); ++ clk_put(rspi->clk); ++ iounmap(rspi->addr); ++ spi_master_put(rspi->master); ++ ++ return 0; ++} ++ ++static int __devinit rspi_probe(struct platform_device *pdev) ++{ ++ struct resource *res; ++ struct spi_master *master; ++ struct rspi_data *rspi; ++ int ret, irq; ++ char clk_name[16]; ++ ++ /* get base addr */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (unlikely(res == NULL)) { ++ dev_err(&pdev->dev, "invalid resource\n"); ++ return -EINVAL; ++ } ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(&pdev->dev, "platform_get_irq error\n"); ++ return -ENODEV; ++ } ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data)); ++ if (master == NULL) { ++ dev_err(&pdev->dev, "spi_alloc_master error.\n"); ++ return -ENOMEM; ++ } ++ ++ rspi = spi_master_get_devdata(master); ++ dev_set_drvdata(&pdev->dev, rspi); ++ ++ rspi->master = master; ++ rspi->addr = ioremap(res->start, resource_size(res)); ++ if (rspi->addr == NULL) { ++ dev_err(&pdev->dev, "ioremap error.\n"); ++ ret = -ENOMEM; ++ goto error1; ++ } ++ ++ snprintf(clk_name, sizeof(clk_name), "rspi%d", pdev->id); ++ rspi->clk = clk_get(&pdev->dev, clk_name); ++ if (IS_ERR(rspi->clk)) { ++ dev_err(&pdev->dev, "cannot get clock\n"); ++ ret = PTR_ERR(rspi->clk); ++ goto error2; ++ } ++ clk_enable(rspi->clk); ++ ++ INIT_LIST_HEAD(&rspi->queue); ++ spin_lock_init(&rspi->lock); ++ INIT_WORK(&rspi->ws, rspi_work); ++ init_waitqueue_head(&rspi->wait); ++ ++ master->num_chipselect = 2; ++ master->bus_num = pdev->id; ++ master->setup = rspi_setup; ++ master->transfer = rspi_transfer; ++ master->cleanup = rspi_cleanup; ++ ++ ret = request_irq(irq, rspi_irq, 0, dev_name(&pdev->dev), rspi); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "request_irq error\n"); ++ goto error3; ++ } ++ ++ ret = spi_register_master(master); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "spi_register_master error.\n"); ++ goto error4; ++ } ++ ++ dev_info(&pdev->dev, "probed\n"); ++ ++ return 0; ++ ++error4: ++ free_irq(irq, rspi); ++error3: ++ clk_put(rspi->clk); ++error2: ++ iounmap(rspi->addr); ++error1: ++ spi_master_put(master); ++ ++ return ret; ++} ++ ++static struct platform_driver rspi_driver = { ++ .probe = rspi_probe, ++ .remove = __devexit_p(rspi_remove), ++ .driver = { ++ .name = "rspi", ++ .owner = THIS_MODULE, ++ }, ++}; ++module_platform_driver(rspi_driver); ++ ++MODULE_DESCRIPTION("Renesas RSPI bus driver"); ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Yoshihiro Shimoda"); ++MODULE_ALIAS("platform:rspi"); +-- +1.7.1 + +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/002-spi-irq-remove-irqf_disabled.patch b/patches.sh7757lcr/002-spi-irq-remove-irqf_disabled.patch new file mode 100644 index 00000000000000..76087d06c9b63b --- /dev/null +++ b/patches.sh7757lcr/002-spi-irq-remove-irqf_disabled.patch @@ -0,0 +1,57 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:46:54 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:46:50 +0900 +Subject: [LTSI-dev] [PATCH 02/21] spi: irq: Remove IRQF_DISABLED +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC3498A.2000303@renesas.com> + + +>From 561d8e1807f2cc13d47f22c0caf210b123aea24d Mon Sep 17 00:00:00 2001 +From: Yong Zhang <yong.zhang0@gmail.com> +Date: Sat, 22 Oct 2011 17:56:55 +0800 +Subject: spi: irq: Remove IRQF_DISABLED + +Since commit [e58aa3d2: genirq: Run irq handlers with interrupts disabled], +We run all interrupt handlers with interrupts disabled +and we even check and yell when an interrupt handler +returns with interrupts enabled (see commit [b738a50a: +genirq: Warn when handler enables interrupts]). + +So now this flag is a NOOP and can be removed. + +Signed-off-by: Yong Zhang <yong.zhang0@gmail.com> +Signed-off-by: Grant Likely <grant.likely@secretlab.ca> +(cherry picked from commit 38ada214fad79ff5ebbed58932c5f0c9969d9c91) + +Conflicts: + + drivers/spi/spi-bfin5xx.c + drivers/spi/spi-ppc4xx.c + drivers/spi/spi-coldfire-qspi.c + drivers/spi/spi-sh-msiof.c + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/spi/spi_sh.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/drivers/spi/spi_sh.c b/drivers/spi/spi_sh.c +index 9eedd71..e0343d4 100644 +--- a/drivers/spi/spi_sh.c ++++ b/drivers/spi/spi_sh.c +@@ -484,7 +484,7 @@ static int __devinit spi_sh_probe(struct platform_device *pdev) + goto error2; + } + +- ret = request_irq(irq, spi_sh_irq, IRQF_DISABLED, "spi_sh", ss); ++ ret = request_irq(irq, spi_sh_irq, 0, "spi_sh", ss); + if (ret < 0) { + dev_err(&pdev->dev, "request_irq error\n"); + goto error3; +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/003-drivercore-add-helper-macro-for-platform_driver-boilerplate.patch b/patches.sh7757lcr/003-drivercore-add-helper-macro-for-platform_driver-boilerplate.patch new file mode 100644 index 00000000000000..760ab79cbaca7b --- /dev/null +++ b/patches.sh7757lcr/003-drivercore-add-helper-macro-for-platform_driver-boilerplate.patch @@ -0,0 +1,92 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:46:58 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:46:55 +0900 +Subject: [LTSI-dev] [PATCH 03/21] drivercore: Add helper macro for platform_driver boilerplate +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC3498F.9030400@renesas.com> + + +>From 0ac87d22b5e2f88fcaf9888496c8e7b1100ee87c Mon Sep 17 00:00:00 2001 +From: Grant Likely <grant.likely@secretlab.ca> +Date: Wed, 5 Oct 2011 11:29:49 -0600 +Subject: drivercore: Add helper macro for platform_driver boilerplate + +For simple modules that contain a single platform_driver without any +additional setup code then ends up being a block of duplicated +boilerplate. This patch adds a new macro, module_platform_driver(), +which replaces the module_init()/module_exit() registrations with +template functions. + +Signed-off-by: Grant Likely <grant.likely@secretlab.ca> +Acked-by: Greg Kroah-Hartman <gregkh@suse.de> +Reviewed-by: Magnus Damm <magnus.damm@gmail.com> +Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com> +Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> +(cherry picked from commit 940ab88962bc1aff3273a8356d64577a6e386736) + +Conflicts: + + drivers/spi/spi-altera.c + drivers/spi/spi-ath79.c + drivers/spi/spi-atmel.c + drivers/spi/spi-bfin-sport.c + drivers/spi/spi-coldfire-qspi.c + drivers/spi/spi-davinci.c + drivers/spi/spi-dw-mmio.c + drivers/spi/spi-ep93xx.c + drivers/spi/spi-fsl-espi.c + drivers/spi/spi-gpio.c + drivers/spi/spi-imx.c + drivers/spi/spi-mpc512x-psc.c + drivers/spi/spi-mpc52xx-psc.c + drivers/spi/spi-mpc52xx.c + drivers/spi/spi-nuc900.c + drivers/spi/spi-oc-tiny.c + drivers/spi/spi-ppc4xx.c + drivers/spi/spi-s3c24xx.c + drivers/spi/spi-sh-msiof.c + drivers/spi/spi-sh-sci.c + drivers/spi/spi-stmp.c + drivers/spi/spi-tegra.c + drivers/spi/spi-ti-ssp.c + drivers/spi/spi-xilinx.c + drivers/tty/serial/of_serial.c + include/linux/platform_device.h + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/spi/spi_sh.c | 13 +------------ + 1 files changed, 1 insertions(+), 12 deletions(-) + +diff --git a/drivers/spi/spi_sh.c b/drivers/spi/spi_sh.c +index e0343d4..70c8af9 100644 +--- a/drivers/spi/spi_sh.c ++++ b/drivers/spi/spi_sh.c +@@ -524,18 +524,7 @@ static struct platform_driver spi_sh_driver = { + .owner = THIS_MODULE, + }, + }; +- +-static int __init spi_sh_init(void) +-{ +- return platform_driver_register(&spi_sh_driver); +-} +-module_init(spi_sh_init); +- +-static void __exit spi_sh_exit(void) +-{ +- platform_driver_unregister(&spi_sh_driver); +-} +-module_exit(spi_sh_exit); ++module_platform_driver(spi_sh_driver); + + MODULE_DESCRIPTION("SH SPI bus driver"); + MODULE_LICENSE("GPL"); +-- +1.7.1 + +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/004-spi-spi-sh-add-ioresource_mem_type_mask-decoding-for-access-size.patch b/patches.sh7757lcr/004-spi-spi-sh-add-ioresource_mem_type_mask-decoding-for-access-size.patch new file mode 100644 index 00000000000000..694d166dffbd31 --- /dev/null +++ b/patches.sh7757lcr/004-spi-spi-sh-add-ioresource_mem_type_mask-decoding-for-access-size.patch @@ -0,0 +1,85 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:02 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:46:59 +0900 +Subject: [LTSI-dev] [PATCH 04/21] spi/spi-sh: add IORESOURCE_MEM_TYPE_MASK decoding for access size +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC34993.60503@renesas.com> + + +>From 766fd7edb8a1479627d7819b220469a2fe985491 Mon Sep 17 00:00:00 2001 +From: Shimoda, Yoshihiro <yoshihiro.shimoda.uh@renesas.com> +Date: Wed, 7 Mar 2012 14:45:37 +0900 +Subject: spi/spi-sh: add IORESOURCE_MEM_TYPE_MASK decoding for access size + +This SPI controller's access size is 32, or 8-bit. The previous driver +supported 32-bit only. So, this patch adds IORESOURCE_MEM_TYPE_MASK +decoding, an then, the driver can handle the SPI controller of 8-bit. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Grant Likely <grant.likely@secretlab.ca> +(cherry picked from commit 0eb8880fac7b0f32ebab33f99e758c6b308e3aa1) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + drivers/spi/spi_sh.c | 25 +++++++++++++++++++++++-- + 1 files changed, 23 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi_sh.c b/drivers/spi/spi_sh.c +index 70c8af9..79442c3 100644 +--- a/drivers/spi/spi_sh.c ++++ b/drivers/spi/spi_sh.c +@@ -92,17 +92,26 @@ struct spi_sh_data { + unsigned long cr1; + wait_queue_head_t wait; + spinlock_t lock; ++ int width; + }; + + static void spi_sh_write(struct spi_sh_data *ss, unsigned long data, + unsigned long offset) + { +- writel(data, ss->addr + offset); ++ if (ss->width == 8) ++ iowrite8(data, ss->addr + (offset >> 2)); ++ else if (ss->width == 32) ++ iowrite32(data, ss->addr + offset); + } + + static unsigned long spi_sh_read(struct spi_sh_data *ss, unsigned long offset) + { +- return readl(ss->addr + offset); ++ if (ss->width == 8) ++ return ioread8(ss->addr + (offset >> 2)); ++ else if (ss->width == 32) ++ return ioread32(ss->addr + offset); ++ else ++ return 0; + } + + static void spi_sh_set_bit(struct spi_sh_data *ss, unsigned long val, +@@ -464,6 +473,18 @@ static int __devinit spi_sh_probe(struct platform_device *pdev) + ss = spi_master_get_devdata(master); + dev_set_drvdata(&pdev->dev, ss); + ++ switch (res->flags & IORESOURCE_MEM_TYPE_MASK) { ++ case IORESOURCE_MEM_8BIT: ++ ss->width = 8; ++ break; ++ case IORESOURCE_MEM_32BIT: ++ ss->width = 32; ++ break; ++ default: ++ dev_err(&pdev->dev, "No support width\n"); ++ ret = -ENODEV; ++ goto error1; ++ } + ss->irq = irq; + ss->master = master; + ss->addr = ioremap(res->start, resource_size(res)); +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/005-sh-clock-sh7757-add-clkdev_ick_id-for-cleanup.patch b/patches.sh7757lcr/005-sh-clock-sh7757-add-clkdev_ick_id-for-cleanup.patch new file mode 100644 index 00000000000000..3e458e444f5498 --- /dev/null +++ b/patches.sh7757lcr/005-sh-clock-sh7757-add-clkdev_ick_id-for-cleanup.patch @@ -0,0 +1,82 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:07 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:03 +0900 +Subject: [LTSI-dev] [PATCH 05/21] sh: clock-sh7757: add CLKDEV_ICK_ID for cleanup +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC34997.7040605@renesas.com> + + +>From f996c223aca0fc81406daff93810f530d6543399 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Wed, 6 Jul 2011 01:18:27 +0000 +Subject: sh: clock-sh7757: add CLKDEV_ICK_ID for cleanup + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit 9b41757107a7fcabcf83bf2f04938dc8e596464c) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/kernel/cpu/sh4a/clock-sh7757.c | 35 +++++++------------------------ + 1 files changed, 8 insertions(+), 27 deletions(-) + +diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +index eedddad..86bf188 100644 +--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c ++++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +@@ -102,6 +102,7 @@ static struct clk mstp_clks[MSTP_NR] = { + }; + + #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } ++#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk } + + static struct clk_lookup lookups[] = { + /* main clocks */ +@@ -116,33 +117,13 @@ static struct clk_lookup lookups[] = { + /* MSTP32 clocks */ + CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP004]), + CLKDEV_CON_ID("riic", &mstp_clks[MSTP000]), +- { +- /* TMU0 */ +- .dev_id = "sh_tmu.0", +- .con_id = "tmu_fck", +- .clk = &mstp_clks[MSTP113], +- }, { +- /* TMU1 */ +- .dev_id = "sh_tmu.1", +- .con_id = "tmu_fck", +- .clk = &mstp_clks[MSTP114], +- }, +- { +- /* SCIF4 (But, ID is 2) */ +- .dev_id = "sh-sci.2", +- .con_id = "sci_fck", +- .clk = &mstp_clks[MSTP112], +- }, { +- /* SCIF3 */ +- .dev_id = "sh-sci.1", +- .con_id = "sci_fck", +- .clk = &mstp_clks[MSTP111], +- }, { +- /* SCIF2 */ +- .dev_id = "sh-sci.0", +- .con_id = "sci_fck", +- .clk = &mstp_clks[MSTP110], +- }, ++ ++ CLKDEV_ICK_ID("tmu_fck", "sh_tmu.0", &mstp_clks[MSTP113]), ++ CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[MSTP114]), ++ CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP112]), ++ CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP111]), ++ CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP110]), ++ + CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]), + CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]), + }; +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/006-sh-move-clkdev_xxx_id-macro-to-sh_clk.h.patch b/patches.sh7757lcr/006-sh-move-clkdev_xxx_id-macro-to-sh_clk.h.patch new file mode 100644 index 00000000000000..2bb3628d80d58a --- /dev/null +++ b/patches.sh7757lcr/006-sh-move-clkdev_xxx_id-macro-to-sh_clk.h.patch @@ -0,0 +1,54 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:12 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:07 +0900 +Subject: [LTSI-dev] [PATCH 06/21] sh: move CLKDEV_xxx_ID macro to sh_clk.h +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC3499B.9050300@renesas.com> + + +>From 540cdd813dd77275e44ec24701364e1895cd98bd Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Wed, 6 Jul 2011 02:54:11 +0000 +Subject: sh: move CLKDEV_xxx_ID macro to sh_clk.h + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit 1522043bf73ef0e9e61dc512a0f3cdbec1cbf89f) + +Conflicts: + + arch/sh/kernel/cpu/sh4a/clock-sh7343.c + arch/sh/kernel/cpu/sh4a/clock-sh7366.c + arch/sh/kernel/cpu/sh4a/clock-sh7722.c + arch/sh/kernel/cpu/sh4a/clock-sh7723.c + arch/sh/kernel/cpu/sh4a/clock-sh7724.c + arch/sh/kernel/cpu/sh4a/clock-sh7785.c + arch/sh/kernel/cpu/sh4a/clock-sh7786.c + arch/sh/kernel/cpu/sh4a/clock-shx3.c + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/kernel/cpu/sh4a/clock-sh7757.c | 3 --- + 1 files changed, 0 insertions(+), 3 deletions(-) + +diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +index 86bf188..3b097b0 100644 +--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c ++++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +@@ -101,9 +101,6 @@ static struct clk mstp_clks[MSTP_NR] = { + [MSTP220] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 20, 0), + }; + +-#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } +-#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk } +- + static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("extal", &extal_clk), +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/007-sh-fix-the-compile-error-in-setup-sh7757.c.patch b/patches.sh7757lcr/007-sh-fix-the-compile-error-in-setup-sh7757.c.patch new file mode 100644 index 00000000000000..ef2e2dd099ca21 --- /dev/null +++ b/patches.sh7757lcr/007-sh-fix-the-compile-error-in-setup-sh7757.c.patch @@ -0,0 +1,51 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:15 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:11 +0900 +Subject: [LTSI-dev] [PATCH 07/21] sh: fix the compile error in setup-sh7757.c +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC3499F.9020208@renesas.com> + + +>From 8912bc4c88e6690ff125f20a053961d71919c1be Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 23 Aug 2011 09:15:46 +0000 +Subject: sh: fix the compile error in setup-sh7757.c + +Fix the following build errors: + + CC arch/sh/kernel/cpu/sh4a/setup-sh7757.o +arch/sh/kernel/cpu/sh4a/setup-sh7757.c:681: error: implicit declaration of function ‘DMA_BIT_MASK’ +arch/sh/kernel/cpu/sh4a/setup-sh7757.c:681: error: initializer element is not constant +arch/sh/kernel/cpu/sh4a/setup-sh7757.c:681: error: (near initialization for ‘usb_ehci_device.dev.coherent_dma_mask’) +arch/sh/kernel/cpu/sh4a/setup-sh7757.c:705: error: initializer element is not constant +arch/sh/kernel/cpu/sh4a/setup-sh7757.c:705: error: (near initialization for ‘usb_ohci_device.dev.coherent_dma_mask’) +make[3]: *** [arch/sh/kernel/cpu/sh4a/setup-sh7757.o] Error 1 + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit 21d41f2b312231536cf981c960c83cc4493c0293) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +index e915dea..0555929 100644 +--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c ++++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +@@ -15,6 +15,7 @@ + #include <linux/serial_sci.h> + #include <linux/io.h> + #include <linux/mm.h> ++#include <linux/dma-mapping.h> + #include <linux/sh_timer.h> + #include <linux/sh_dma.h> + +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/008-sh-add-parameters-for-ehci-and-riic-in-clock-sh7757.c.patch b/patches.sh7757lcr/008-sh-add-parameters-for-ehci-and-riic-in-clock-sh7757.c.patch new file mode 100644 index 00000000000000..42a89bd59d7a58 --- /dev/null +++ b/patches.sh7757lcr/008-sh-add-parameters-for-ehci-and-riic-in-clock-sh7757.c.patch @@ -0,0 +1,57 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:19 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:15 +0900 +Subject: [LTSI-dev] [PATCH 08/21] sh: add parameters for EHCI and RIIC in clock-sh7757.c +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349A3.7010304@renesas.com> + + +>From 93827b13e428bfc4e2323ab8006e170bc530906e Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 26 Sep 2011 17:41:28 +0900 +Subject: sh: add parameters for EHCI and RIIC in clock-sh7757.c + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit 5261b0a290a87fa448fd1fd125baeab42603a318) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/kernel/cpu/sh4a/clock-sh7757.c | 10 +++++++++- + 1 files changed, 9 insertions(+), 1 deletions(-) + +diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +index 3b097b0..19222da 100644 +--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c ++++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +@@ -113,7 +113,14 @@ static struct clk_lookup lookups[] = { + + /* MSTP32 clocks */ + CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP004]), +- CLKDEV_CON_ID("riic", &mstp_clks[MSTP000]), ++ CLKDEV_CON_ID("riic0", &mstp_clks[MSTP000]), ++ CLKDEV_CON_ID("riic1", &mstp_clks[MSTP000]), ++ CLKDEV_CON_ID("riic2", &mstp_clks[MSTP000]), ++ CLKDEV_CON_ID("riic3", &mstp_clks[MSTP000]), ++ CLKDEV_CON_ID("riic4", &mstp_clks[MSTP000]), ++ CLKDEV_CON_ID("riic5", &mstp_clks[MSTP000]), ++ CLKDEV_CON_ID("riic6", &mstp_clks[MSTP000]), ++ CLKDEV_CON_ID("riic7", &mstp_clks[MSTP000]), + + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.0", &mstp_clks[MSTP113]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[MSTP114]), +@@ -121,6 +128,7 @@ static struct clk_lookup lookups[] = { + CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP111]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP110]), + ++ CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP103]), + CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]), + CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]), + }; +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/009-sh-add-a-resource-name-for-shdma.patch b/patches.sh7757lcr/009-sh-add-a-resource-name-for-shdma.patch new file mode 100644 index 00000000000000..4818a3ae21ecbf --- /dev/null +++ b/patches.sh7757lcr/009-sh-add-a-resource-name-for-shdma.patch @@ -0,0 +1,75 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:24 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:20 +0900 +Subject: [LTSI-dev] [PATCH 09/21] sh: add a resource name for shdma +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349A8.5020108@renesas.com> + + +>From 97de925e1dbf4faa708110d1441ea1d585d4a913 Mon Sep 17 00:00:00 2001 +From: Shimoda, Yoshihiro <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 10 Jan 2012 14:20:58 +0900 +Subject: sh: add a resource name for shdma + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit a4d5247310c993b6b30f1686be12ddacfc41142a) + +Conflicts: + arch/sh/kernel/cpu/sh4a/setup-sh7722.c + arch/sh/kernel/cpu/sh4a/setup-sh7724.c + arch/sh/kernel/cpu/sh4a/setup-sh7780.c + arch/sh/kernel/cpu/sh4a/setup-sh7785.c + arch/sh/kernel/cpu/sh4a/setup-sh7786.c + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 7 ++++--- + 1 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +index 0555929..a7b2da6 100644 +--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c ++++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +@@ -465,6 +465,7 @@ static struct resource sh7757_dmae0_resources[] = { + .flags = IORESOURCE_MEM, + }, + { ++ .name = "error_irq", + .start = 34, + .end = 34, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, +@@ -486,7 +487,7 @@ static struct resource sh7757_dmae1_resources[] = { + .flags = IORESOURCE_MEM, + }, + { +- /* DMA error */ ++ .name = "error_irq", + .start = 34, + .end = 34, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, +@@ -556,7 +557,7 @@ static struct resource sh7757_dmae2_resources[] = { + .flags = IORESOURCE_MEM, + }, + { +- /* DMA error */ ++ .name = "error_irq", + .start = 323, + .end = 323, + .flags = IORESOURCE_IRQ, +@@ -590,7 +591,7 @@ static struct resource sh7757_dmae3_resources[] = { + .flags = IORESOURCE_MEM, + }, + { +- /* DMA error */ ++ .name = "error_irq", + .start = 324, + .end = 324, + .flags = IORESOURCE_IRQ, +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/010-sh-modify-resource-for-spi0-in-setup-sh7757.patch b/patches.sh7757lcr/010-sh-modify-resource-for-spi0-in-setup-sh7757.patch new file mode 100644 index 00000000000000..42b4d3e8f0c0d5 --- /dev/null +++ b/patches.sh7757lcr/010-sh-modify-resource-for-spi0-in-setup-sh7757.patch @@ -0,0 +1,46 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:27 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:23 +0900 +Subject: [LTSI-dev] [PATCH 10/21] sh: modify resource for SPI0 in setup-sh7757 +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349AB.3020600@renesas.com> + + +>From 8b983d13cd434f9ecaaf59bb4407ab7f212134d5 Mon Sep 17 00:00:00 2001 +From: Shimoda, Yoshihiro <yoshihiro.shimoda.uh@renesas.com> +Date: Thu, 26 Jan 2012 17:44:05 +0900 +Subject: sh: modify resource for SPI0 in setup-sh7757 + +The new spi-sh driver decodes the IORESOURCE_MEM_TYPE_MASK. So, the +resource needs the IORESOURCE_MEM_32BIT. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit 11c582e32c664f67e2518b9f97e6c91918617274) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +index a7b2da6..226d809 100644 +--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c ++++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +@@ -133,7 +133,7 @@ static struct resource spi0_resources[] = { + [0] = { + .start = 0xfe002000, + .end = 0xfe0020ff, +- .flags = IORESOURCE_MEM, ++ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, + }, + [1] = { + .start = 86, +-- +1.7.1 + +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/011-sh-add-platform_device-for-spi1-in-setup-sh7757.patch b/patches.sh7757lcr/011-sh-add-platform_device-for-spi1-in-setup-sh7757.patch new file mode 100644 index 00000000000000..8d28d66a1bc180 --- /dev/null +++ b/patches.sh7757lcr/011-sh-add-platform_device-for-spi1-in-setup-sh7757.patch @@ -0,0 +1,68 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:32 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:28 +0900 +Subject: [LTSI-dev] [PATCH 11/21] sh: add platform_device for SPI1 in setup-sh7757 +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349B0.20603@renesas.com> + + +>From 207bfa238e5788eed6ec68738127ddb5f702f70d Mon Sep 17 00:00:00 2001 +From: Shimoda, Yoshihiro <yoshihiro.shimoda.uh@renesas.com> +Date: Thu, 26 Jan 2012 17:44:07 +0900 +Subject: sh: add platform_device for SPI1 in setup-sh7757 + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit a206c0087323337595de1284feb09a98c2a389d2) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 20 ++++++++++++++++++++ + 1 files changed, 20 insertions(+), 0 deletions(-) + +diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +index 226d809..2875e8b 100644 +--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c ++++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +@@ -661,6 +661,25 @@ static struct platform_device spi0_device = { + .resource = spi0_resources, + }; + ++static struct resource spi1_resources[] = { ++ { ++ .start = 0xffd8ee70, ++ .end = 0xffd8eeff, ++ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT, ++ }, ++ { ++ .start = 54, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device spi1_device = { ++ .name = "sh_spi", ++ .id = 1, ++ .num_resources = ARRAY_SIZE(spi1_resources), ++ .resource = spi1_resources, ++}; ++ + static struct resource usb_ehci_resources[] = { + [0] = { + .start = 0xfe4f1000, +@@ -720,6 +739,7 @@ static struct platform_device *sh7757_devices[] __initdata = { + &dma2_device, + &dma3_device, + &spi0_device, ++ &spi1_device, + &usb_ehci_device, + &usb_ohci_device, + }; +-- +1.7.1 + +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/012-sh-modify-clock-sh7757-for-renesas_usbhs.patch b/patches.sh7757lcr/012-sh-modify-clock-sh7757-for-renesas_usbhs.patch new file mode 100644 index 00000000000000..9aa2bacfae77f9 --- /dev/null +++ b/patches.sh7757lcr/012-sh-modify-clock-sh7757-for-renesas_usbhs.patch @@ -0,0 +1,48 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:36 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:32 +0900 +Subject: [LTSI-dev] [PATCH 12/21] sh: modify clock-sh7757 for renesas_usbhs +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349B4.1090603@renesas.com> + + +>From 2f2fc2bf63c60852a8ddd817a29df482bd18486f Mon Sep 17 00:00:00 2001 +From: Shimoda, Yoshihiro <yoshihiro.shimoda.uh@renesas.com> +Date: Thu, 5 Jan 2012 14:08:03 +0900 +Subject: sh: modify clock-sh7757 for renesas_usbhs + +The renesas_usbhs driver doesn't use the clk functions. So, even if we +adds "CLKDEV_DEV_ID("renesas_usbhs.0", ...)" only, we cannot use the USB +controller because clk_late_init() will disable the clock by "usb0". +So, the patch also removes the "CLKDEV_CON_ID("usb0", ...)". + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit 1760e371a9038329190f0fdd051776ae76aca083) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/kernel/cpu/sh4a/clock-sh7757.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +index 19222da..0fbff14 100644 +--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c ++++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +@@ -129,7 +129,7 @@ static struct clk_lookup lookups[] = { + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP110]), + + CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP103]), +- CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]), ++ CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP102]), + CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]), + }; + +-- +1.7.1 + +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/013-sh-add-parameter-for-rspi-in-clock-sh7757.patch b/patches.sh7757lcr/013-sh-add-parameter-for-rspi-in-clock-sh7757.patch new file mode 100644 index 00000000000000..02152f203d74de --- /dev/null +++ b/patches.sh7757lcr/013-sh-add-parameter-for-rspi-in-clock-sh7757.patch @@ -0,0 +1,58 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:40 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:36 +0900 +Subject: [LTSI-dev] [PATCH 13/21] sh: add parameter for RSPI in clock-sh7757 +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349B8.8010109@renesas.com> + + +>From dc2ff8b7383140efe6afe755620137ea6a156602 Mon Sep 17 00:00:00 2001 +From: Shimoda, Yoshihiro <yoshihiro.shimoda.uh@renesas.com> +Date: Wed, 7 Mar 2012 14:46:38 +0900 +Subject: sh: add parameter for RSPI in clock-sh7757 + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit fb4340656fda27bd38914ef382ee3235c23d8f58) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/kernel/cpu/sh4a/clock-sh7757.c | 4 +++- + 1 files changed, 3 insertions(+), 1 deletions(-) + +diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +index 0fbff14..0bd21c8 100644 +--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c ++++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +@@ -79,7 +79,7 @@ struct clk div4_clks[DIV4_NR] = { + #define MSTPCR1 0xffc80034 + #define MSTPCR2 0xffc10028 + +-enum { MSTP004, MSTP000, MSTP114, MSTP113, MSTP112, ++enum { MSTP004, MSTP000, MSTP127, MSTP114, MSTP113, MSTP112, + MSTP111, MSTP110, MSTP103, MSTP102, MSTP220, + MSTP_NR }; + +@@ -89,6 +89,7 @@ static struct clk mstp_clks[MSTP_NR] = { + [MSTP000] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 0, 0), + + /* MSTPCR1 */ ++ [MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 27, 0), + [MSTP114] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 14, 0), + [MSTP113] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 13, 0), + [MSTP112] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 12, 0), +@@ -131,6 +132,7 @@ static struct clk_lookup lookups[] = { + CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP103]), + CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP102]), + CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]), ++ CLKDEV_CON_ID("rspi2", &mstp_clks[MSTP127]), + }; + + int __init arch_clk_init(void) +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/014-sh-modify-the-asm-sh_eth.h-to-linux-sh_eth.h-in-sh7757lcr.patch b/patches.sh7757lcr/014-sh-modify-the-asm-sh_eth.h-to-linux-sh_eth.h-in-sh7757lcr.patch new file mode 100644 index 00000000000000..56504b9e5726df --- /dev/null +++ b/patches.sh7757lcr/014-sh-modify-the-asm-sh_eth.h-to-linux-sh_eth.h-in-sh7757lcr.patch @@ -0,0 +1,44 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:43 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:40 +0900 +Subject: [LTSI-dev] [PATCH 14/21] sh: modify the asm/sh_eth.h to linux/sh_eth.h in sh7757lcr +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349BC.6030503@renesas.com> + + +>From 457c07a09f4564cc6051e2ab982520a26b236d4e Mon Sep 17 00:00:00 2001 +From: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> +Date: Tue, 1 Nov 2011 14:54:38 +0900 +Subject: sh: modify the asm/sh_eth.h to linux/sh_eth.h in sh7757lcr + +Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit 389cc10cbdde1a9225eac51318fb30e2039135ad) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/boards/board-sh7757lcr.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c +index fa2a208..ec8c84c 100644 +--- a/arch/sh/boards/board-sh7757lcr.c ++++ b/arch/sh/boards/board-sh7757lcr.c +@@ -18,8 +18,8 @@ + #include <linux/mmc/host.h> + #include <linux/mmc/sh_mmcif.h> + #include <linux/mmc/sh_mobile_sdhi.h> ++#include <linux/sh_eth.h> + #include <cpu/sh7757.h> +-#include <asm/sh_eth.h> + #include <asm/heartbeat.h> + + static struct resource heartbeat_resource = { +-- +1.7.1 + +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/015-sh-add-platform_device-for-rspi-in-setup-sh7757.patch b/patches.sh7757lcr/015-sh-add-platform_device-for-rspi-in-setup-sh7757.patch new file mode 100644 index 00000000000000..04bc589c4a397e --- /dev/null +++ b/patches.sh7757lcr/015-sh-add-platform_device-for-rspi-in-setup-sh7757.patch @@ -0,0 +1,67 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:47 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:43 +0900 +Subject: [LTSI-dev] [PATCH 15/21] sh: add platform_device for RSPI in setup-sh7757 +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349BF.3080703@renesas.com> + + +>From 309c52cddb5ae308683d74591b6a00a25b2898fc Mon Sep 17 00:00:00 2001 +From: Shimoda, Yoshihiro <yoshihiro.shimoda.uh@renesas.com> +Date: Wed, 7 Mar 2012 14:46:41 +0900 +Subject: sh: add platform_device for RSPI in setup-sh7757 + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit 10a068f27ac2200c83f6d13f5e03f6e48cf06d10) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 20 ++++++++++++++++++++ + 1 files changed, 20 insertions(+), 0 deletions(-) + +diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +index 2875e8b..c8836cf 100644 +--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c ++++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +@@ -680,6 +680,25 @@ static struct platform_device spi1_device = { + .resource = spi1_resources, + }; + ++static struct resource rspi_resources[] = { ++ { ++ .start = 0xfe480000, ++ .end = 0xfe4800ff, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = 220, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device rspi_device = { ++ .name = "rspi", ++ .id = 2, ++ .num_resources = ARRAY_SIZE(rspi_resources), ++ .resource = rspi_resources, ++}; ++ + static struct resource usb_ehci_resources[] = { + [0] = { + .start = 0xfe4f1000, +@@ -740,6 +759,7 @@ static struct platform_device *sh7757_devices[] __initdata = { + &dma3_device, + &spi0_device, + &spi1_device, ++ &rspi_device, + &usb_ehci_device, + &usb_ohci_device, + }; +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/016-sh-fix-build-warning-in-board-sh7757lcr.patch b/patches.sh7757lcr/016-sh-fix-build-warning-in-board-sh7757lcr.patch new file mode 100644 index 00000000000000..babac18bdb6691 --- /dev/null +++ b/patches.sh7757lcr/016-sh-fix-build-warning-in-board-sh7757lcr.patch @@ -0,0 +1,82 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:50 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:46 +0900 +Subject: [LTSI-dev] [PATCH 16/21] sh: fix build warning in board-sh7757lcr +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349C2.9050303@renesas.com> + + +>From 2df9254111cd82738d8dc57a989f67a998c5540d Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Fri, 18 Nov 2011 16:32:34 +0900 +Subject: sh: fix build warning in board-sh7757lcr + +This patch fixed the following build warnings: + + CC arch/sh/boards/board-sh7757lcr.o +arch/sh/boards/board-sh7757lcr.c:77: warning: initialization from incompatible pointer type +arch/sh/boards/board-sh7757lcr.c:106: warning: initialization from incompatible pointer type +arch/sh/boards/board-sh7757lcr.c:151: warning: initialization from incompatible pointer type +arch/sh/boards/board-sh7757lcr.c:181: warning: initialization from incompatible pointer type +arch/sh/boards/board-sh7757lcr.c:213: warning: missing braces around initializer +arch/sh/boards/board-sh7757lcr.c:213: warning: (near initialization for ‘sh7757lcr_mmcif_dma.chan_priv_tx’) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit 19d7ca2998e095086869318dd2ad966952f5ac82) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/boards/board-sh7757lcr.c | 16 ++++++++++------ + 1 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c +index ec8c84c..895e337 100644 +--- a/arch/sh/boards/board-sh7757lcr.c ++++ b/arch/sh/boards/board-sh7757lcr.c +@@ -50,9 +50,9 @@ static struct platform_device heartbeat_device = { + #define GBECONT 0xffc10100 + #define GBECONT_RMII1 BIT(17) + #define GBECONT_RMII0 BIT(16) +-static void sh7757_eth_set_mdio_gate(unsigned long addr) ++static void sh7757_eth_set_mdio_gate(void *addr) + { +- if ((addr & 0x00000fff) < 0x0800) ++ if (((unsigned long)addr & 0x00000fff) < 0x0800) + writel(readl(GBECONT) | GBECONT_RMII0, GBECONT); + else + writel(readl(GBECONT) | GBECONT_RMII1, GBECONT); +@@ -116,9 +116,9 @@ static struct platform_device sh7757_eth1_device = { + }, + }; + +-static void sh7757_eth_giga_set_mdio_gate(unsigned long addr) ++static void sh7757_eth_giga_set_mdio_gate(void *addr) + { +- if ((addr & 0x00000fff) < 0x0800) { ++ if (((unsigned long)addr & 0x00000fff) < 0x0800) { + gpio_set_value(GPIO_PTT4, 1); + writel(readl(GBECONT) & ~GBECONT_RMII0, GBECONT); + } else { +@@ -210,8 +210,12 @@ static struct resource sh_mmcif_resources[] = { + }; + + static struct sh_mmcif_dma sh7757lcr_mmcif_dma = { +- .chan_priv_tx = SHDMA_SLAVE_MMCIF_TX, +- .chan_priv_rx = SHDMA_SLAVE_MMCIF_RX, ++ .chan_priv_tx = { ++ .slave_id = SHDMA_SLAVE_MMCIF_TX, ++ }, ++ .chan_priv_rx = { ++ .slave_id = SHDMA_SLAVE_MMCIF_RX, ++ } + }; + + static struct sh_mmcif_plat_data sh_mmcif_plat = { +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/017-sh-add-platform_device-for-renesas_usbhs-in-board-sh7757lcr.patch b/patches.sh7757lcr/017-sh-add-platform_device-for-renesas_usbhs-in-board-sh7757lcr.patch new file mode 100644 index 00000000000000..8de58457816a12 --- /dev/null +++ b/patches.sh7757lcr/017-sh-add-platform_device-for-renesas_usbhs-in-board-sh7757lcr.patch @@ -0,0 +1,93 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:54 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:49 +0900 +Subject: [LTSI-dev] [PATCH 17/21] sh: add platform_device for renesas_usbhs in board-sh7757lcr +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349C5.2080607@renesas.com> + + +>From 88b6a3d039fde3e966f002b64afe8c3e833f2902 Mon Sep 17 00:00:00 2001 +From: Shimoda, Yoshihiro <yoshihiro.shimoda.uh@renesas.com> +Date: Thu, 5 Jan 2012 14:08:12 +0900 +Subject: sh: add platform_device for renesas_usbhs in board-sh7757lcr + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit 7afb4e9a92e42e66124b7043405bbca82680aa96) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/boards/board-sh7757lcr.c | 39 ++++++++++++++++++++++++++++++++++++++ + 1 files changed, 39 insertions(+), 0 deletions(-) + +diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c +index 895e337..0838154 100644 +--- a/arch/sh/boards/board-sh7757lcr.c ++++ b/arch/sh/boards/board-sh7757lcr.c +@@ -19,6 +19,7 @@ + #include <linux/mmc/sh_mmcif.h> + #include <linux/mmc/sh_mobile_sdhi.h> + #include <linux/sh_eth.h> ++#include <linux/usb/renesas_usbhs.h> + #include <cpu/sh7757.h> + #include <asm/heartbeat.h> + +@@ -264,6 +265,43 @@ static struct platform_device sdhi_device = { + }, + }; + ++static int usbhs0_get_id(struct platform_device *pdev) ++{ ++ return USBHS_GADGET; ++} ++ ++static struct renesas_usbhs_platform_info usb0_data = { ++ .platform_callback = { ++ .get_id = usbhs0_get_id, ++ }, ++ .driver_param = { ++ .buswait_bwait = 5, ++ } ++}; ++ ++static struct resource usb0_resources[] = { ++ [0] = { ++ .start = 0xfe450000, ++ .end = 0xfe4501ff, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = 50, ++ .end = 50, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device usb0_device = { ++ .name = "renesas_usbhs", ++ .id = 0, ++ .dev = { ++ .platform_data = &usb0_data, ++ }, ++ .num_resources = ARRAY_SIZE(usb0_resources), ++ .resource = usb0_resources, ++}; ++ + static struct platform_device *sh7757lcr_devices[] __initdata = { + &heartbeat_device, + &sh7757_eth0_device, +@@ -272,6 +310,7 @@ static struct platform_device *sh7757lcr_devices[] __initdata = { + &sh7757_eth_giga1_device, + &sh_mmcif_device, + &sdhi_device, ++ &usb0_device, + }; + + static struct flash_platform_data spi_flash_data = { +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/018-sh-fix-the-sh_mmcif_plat_data-in-board-sh7757lcr.patch b/patches.sh7757lcr/018-sh-fix-the-sh_mmcif_plat_data-in-board-sh7757lcr.patch new file mode 100644 index 00000000000000..e03925afd9d764 --- /dev/null +++ b/patches.sh7757lcr/018-sh-fix-the-sh_mmcif_plat_data-in-board-sh7757lcr.patch @@ -0,0 +1,48 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:47:56 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:53 +0900 +Subject: [LTSI-dev] [PATCH 18/21] sh: fix the sh_mmcif_plat_data in board-sh7757lcr +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349C9.8000304@renesas.com> + + +>From 6238a9aa21a471e435ff0bc6106d477edfbe6865 Mon Sep 17 00:00:00 2001 +From: Shimoda, Yoshihiro <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 17 Jan 2012 17:49:38 +0900 +Subject: sh: fix the sh_mmcif_plat_data in board-sh7757lcr + +The board has an eMMC chip, so we cannot remove the chip. +In this case, we have to set the MMC_CAP_NONREMOVABLE to the caps +parameter. + +Reported-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit 78da107a7ed14fbc6ef77ff4c41d92b11edc9036) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/boards/board-sh7757lcr.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c +index 0838154..33dc5b6 100644 +--- a/arch/sh/boards/board-sh7757lcr.c ++++ b/arch/sh/boards/board-sh7757lcr.c +@@ -222,7 +222,8 @@ static struct sh_mmcif_dma sh7757lcr_mmcif_dma = { + static struct sh_mmcif_plat_data sh_mmcif_plat = { + .dma = &sh7757lcr_mmcif_dma, + .sup_pclk = 0x0f, +- .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, ++ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | ++ MMC_CAP_NONREMOVABLE, + .ocr = MMC_VDD_32_33 | MMC_VDD_33_34, + }; + +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/019-sh-modify-a-resource-of-sh_eth_giga1_resources-in-board-sh7757lcr.patch b/patches.sh7757lcr/019-sh-modify-a-resource-of-sh_eth_giga1_resources-in-board-sh7757lcr.patch new file mode 100644 index 00000000000000..536cd3bba908da --- /dev/null +++ b/patches.sh7757lcr/019-sh-modify-a-resource-of-sh_eth_giga1_resources-in-board-sh7757lcr.patch @@ -0,0 +1,48 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:48:00 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:47:56 +0900 +Subject: [LTSI-dev] [PATCH 19/21] sh: modify a resource of sh_eth_giga1_resources in board-sh7757lcr +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349CC.9000006@renesas.com> + + +>From c17794efb2da1484cf80a5421a55fd8e99951b60 Mon Sep 17 00:00:00 2001 +From: Shimoda, Yoshihiro <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 20 Feb 2012 17:26:50 +0900 +Subject: sh: modify a resource of sh_eth_giga1_resources in board-sh7757lcr + +The latest sh_eth driver needs a resource of TSU in the channel 1, +if the controller has TSU registers. So, this patch adds the resource. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit befe0756d5fa5841f02e2029bbcc77225b9a13bb) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/boards/board-sh7757lcr.c | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c +index 33dc5b6..14b0dae 100644 +--- a/arch/sh/boards/board-sh7757lcr.c ++++ b/arch/sh/boards/board-sh7757lcr.c +@@ -169,6 +169,11 @@ static struct resource sh_eth_giga1_resources[] = { + .end = 0xfee00fff, + .flags = IORESOURCE_MEM, + }, { ++ /* TSU */ ++ .start = 0xfee01800, ++ .end = 0xfee01fff, ++ .flags = IORESOURCE_MEM, ++ }, { + .start = 316, + .end = 316, + .flags = IORESOURCE_IRQ, +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/020-sh-kexec-register-crashk_res.patch b/patches.sh7757lcr/020-sh-kexec-register-crashk_res.patch new file mode 100644 index 00000000000000..60836e96bbf428 --- /dev/null +++ b/patches.sh7757lcr/020-sh-kexec-register-crashk_res.patch @@ -0,0 +1,63 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:48:04 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:48:00 +0900 +Subject: [LTSI-dev] [PATCH 20/21] sh: kexec: Register crashk_res +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349D0.4060007@renesas.com> + + +>From c6776324925d4d939667e9a7dd28079b35349e98 Mon Sep 17 00:00:00 2001 +From: Simon Horman <horms@verge.net.au> +Date: Fri, 2 Sep 2011 03:47:12 +0000 +Subject: sh: kexec: Register crashk_res + +Register crashk_res so that it can be used by kexec-tools +via /proc/iomem. + +The crash kernel resource needs to be requested the same as the +other kernel resources due to the fact that it's handled during +the common path for adding new memory ranges, so it's added in to +__add_active_range() with the others. This ensures that the crash +kernel is properly reserved regardless of which memory range it's +placed in. + +Signed-off-by: Simon Horman <horms@verge.net.au> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit 41309b7a22805f1650c600723d729af453d52719) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/kernel/setup.c | 9 ++++++--- + 1 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c +index 58bff45..1a0e946 100644 +--- a/arch/sh/kernel/setup.c ++++ b/arch/sh/kernel/setup.c +@@ -211,13 +211,16 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn, + } + + /* +- * We don't know which RAM region contains kernel data, +- * so we try it repeatedly and let the resource manager +- * test it. ++ * We don't know which RAM region contains kernel data or ++ * the reserved crashkernel region, so try it repeatedly ++ * and let the resource manager test it. + */ + request_resource(res, &code_resource); + request_resource(res, &data_resource); + request_resource(res, &bss_resource); ++#ifdef CONFIG_KEXEC ++ request_resource(res, &crashk_res); ++#endif + + /* + * Also make sure that there is a PMB mapping that covers this +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + diff --git a/patches.sh7757lcr/021-sh-kexec-add-physical_start.patch b/patches.sh7757lcr/021-sh-kexec-add-physical_start.patch new file mode 100644 index 00000000000000..b816516b597aed --- /dev/null +++ b/patches.sh7757lcr/021-sh-kexec-add-physical_start.patch @@ -0,0 +1,165 @@ +From ltsi-dev-bounces@lists.linuxfoundation.org Mon May 28 02:48:07 2012 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 28 May 2012 18:48:04 +0900 +Subject: [LTSI-dev] [PATCH 21/21] sh: kexec: Add PHYSICAL_START +To: ltsi-dev@lists.linuxfoundation.org +Message-ID: <4FC349D4.5090003@renesas.com> + + +>From e5e6ee27709b81739b5c22123e5b4c2f81303570 Mon Sep 17 00:00:00 2001 +From: Simon Horman <horms@verge.net.au> +Date: Thu, 15 Sep 2011 20:13:00 +0900 +Subject: sh: kexec: Add PHYSICAL_START + +Add PHYSICAL_START kernel configuration parameter to set the address at +which the kernel should be loaded. + +It has been observed on an sh7757lcr that simply modifying MEMORY_START +does not achieve this goal for 32bit sh. This is due to MEMORY_OFFSET in +arch/sh/kernel/vmlinux.lds.S bot being based on MEMORY_START on such +systems. + +Signed-off-by: Simon Horman <horms@verge.net.au> +Signed-off-by: Paul Mundt <lethal@linux-sh.org> +(cherry picked from commit e66ac3f26aef131f5ca60350d25fba95f43acd0d) + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +--- + arch/sh/Kconfig | 13 ++++++++++++- + arch/sh/boot/Makefile | 6 ++++-- + arch/sh/include/asm/page.h | 10 ++++++++++ + arch/sh/kernel/vmlinux.lds.S | 2 +- + arch/sh/mm/init.c | 8 ++++---- + 5 files changed, 31 insertions(+), 8 deletions(-) + +diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig +index bbdeb48..0d07d40 100644 +--- a/arch/sh/Kconfig ++++ b/arch/sh/Kconfig +@@ -648,7 +648,7 @@ config CRASH_DUMP + a specially reserved region and then later executed after + a crash by kdump/kexec. The crash dump kernel must be compiled + to a memory address not used by the main kernel using +- MEMORY_START. ++ PHYSICAL_START. + + For more details see Documentation/kdump/kdump.txt + +@@ -659,6 +659,17 @@ config KEXEC_JUMP + Jump between original kernel and kexeced kernel and invoke + code via KEXEC + ++config PHYSICAL_START ++ hex "Physical address where the kernel is loaded" if (EXPERT || CRASH_DUMP) ++ default MEMORY_START ++ ---help--- ++ This gives the physical address where the kernel is loaded ++ and is ordinarily the same as MEMORY_START. ++ ++ Different values are primarily used in the case of kexec on panic ++ where the fail safe kernel needs to run at a different address ++ than the panic-ed kernel. ++ + config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + depends on PROC_FS +diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile +index ba515d8..e4ea31a 100644 +--- a/arch/sh/boot/Makefile ++++ b/arch/sh/boot/Makefile +@@ -19,6 +19,7 @@ CONFIG_MEMORY_START ?= 0x0c000000 + CONFIG_BOOT_LINK_OFFSET ?= 0x00800000 + CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000 + CONFIG_ENTRY_OFFSET ?= 0x00001000 ++CONFIG_PHYSICAL_START ?= $(CONFIG_MEMORY_START) + + suffix-y := bin + suffix-$(CONFIG_KERNEL_GZIP) := gz +@@ -48,7 +49,7 @@ $(obj)/romimage/vmlinux: $(obj)/zImage FORCE + $(Q)$(MAKE) $(build)=$(obj)/romimage $@ + + KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \ +- $$[$(CONFIG_MEMORY_START) & 0x1fffffff]') ++ $$[$(CONFIG_PHYSICAL_START) & 0x1fffffff]') + + KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%08x" \ + $$[$(CONFIG_PAGE_OFFSET) + \ +@@ -114,4 +115,5 @@ $(obj)/uImage: $(obj)/uImage.$(suffix-y) + @echo ' Image $@ is ready' + + export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \ +- CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET KERNEL_MEMORY suffix-y ++ CONFIG_PHYSICAL_START CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET \ ++ KERNEL_MEMORY suffix-y +diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h +index abcc4dc..15d9703 100644 +--- a/arch/sh/include/asm/page.h ++++ b/arch/sh/include/asm/page.h +@@ -113,6 +113,16 @@ typedef struct page *pgtable_t; + #define __MEMORY_SIZE CONFIG_MEMORY_SIZE + + /* ++ * PHYSICAL_OFFSET is the offset in physical memory where the base ++ * of the kernel is loaded. ++ */ ++#ifdef CONFIG_PHYSICAL_START ++#define PHYSICAL_OFFSET (CONFIG_PHYSICAL_START - __MEMORY_START) ++#else ++#define PHYSICAL_OFFSET 0 ++#endif ++ ++/* + * PAGE_OFFSET is the virtual address of the start of kernel address + * space. + */ +diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S +index 731c10c..c98905f 100644 +--- a/arch/sh/kernel/vmlinux.lds.S ++++ b/arch/sh/kernel/vmlinux.lds.S +@@ -23,7 +23,7 @@ OUTPUT_ARCH(sh) + ENTRY(_start) + SECTIONS + { +- . = PAGE_OFFSET + MEMORY_OFFSET + CONFIG_ZERO_PAGE_OFFSET; ++ . = PAGE_OFFSET + MEMORY_OFFSET + PHYSICAL_OFFSET + CONFIG_ZERO_PAGE_OFFSET; + + _text = .; /* Text and read-only data */ + +diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c +index 58a93fb..c9dbace 100644 +--- a/arch/sh/mm/init.c ++++ b/arch/sh/mm/init.c +@@ -287,6 +287,8 @@ static void __init do_init_bootmem(void) + static void __init early_reserve_mem(void) + { + unsigned long start_pfn; ++ u32 zero_base = (u32)__MEMORY_START + (u32)PHYSICAL_OFFSET; ++ u32 start = zero_base + (u32)CONFIG_ZERO_PAGE_OFFSET; + + /* + * Partially used pages are not usable - thus +@@ -300,15 +302,13 @@ static void __init early_reserve_mem(void) + * this catches the (definitely buggy) case of us accidentally + * initializing the bootmem allocator with an invalid RAM area. + */ +- memblock_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET, +- (PFN_PHYS(start_pfn) + PAGE_SIZE - 1) - +- (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET)); ++ memblock_reserve(start, (PFN_PHYS(start_pfn) + PAGE_SIZE - 1) - start); + + /* + * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET. + */ + if (CONFIG_ZERO_PAGE_OFFSET != 0) +- memblock_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET); ++ memblock_reserve(zero_base, CONFIG_ZERO_PAGE_OFFSET); + + /* + * Handle additional early reservations +-- +1.7.1 +_______________________________________________ +LTSI-dev mailing list +LTSI-dev@lists.linuxfoundation.org +https://lists.linuxfoundation.org/mailman/listinfo/ltsi-dev + @@ -2,12 +2,22 @@ # LTSI patch queue series # -# +############################################################################# # LTSI project specific patches # - patches.ltsi/ltsi-makefile-addition.patch + +############################################################################# +# Patches that are upstream for the next -stable release, but are added here +# before a stable tree can be released. +# +# Also, any needed reverts that we don't want from the -stable releases should +# go here. +# +patches.kernel.org/arm-fix-rcu-stalls-on-smp-platforms.patch + + ############################################################################# # Android patches. # @@ -313,7 +323,8 @@ patches.armadillo800eva/0250-ARM-mach-shmobile-armadillo800eva-add-support-LCDC0 patches.armadillo800eva/0251-ARM-mach-shmobile-armadillo800eva-add-support-ST1232.patch patches.armadillo800eva/0252-ARM-mach-shmobile-armadillo800eva-add-support-gpio_k.patch patches.armadillo800eva/0253-ARM-mach-shmobile-armadillo800eva-add-support-sh_eth.patch - +patches.armadillo800eva/arm-mach-shmobile-sh7372-ap4evb-and-mackerel-timer-rework.patch +patches.armadillo800eva/ltsi-bugfix-armadillo800eva-sh_eth-needs-net_ethernet-on-defconfig.patch @@ -355,6 +366,7 @@ patches.lttng/0172-staging-lttng-Fix-recent-modifications-to-string_fro.patch patches.lttng/0173-staging-lttng-TODO-update-lttng-reported-to-work-fin.patch patches.lttng/0174-staging-lttng-Update-max-symbol-length-to-256.patch patches.lttng/lttng-update-to-v2.0.1.patch +patches.lttng/lttng-update-2.0.1-to-2.0.4.patch patches.runtime_pm/0001-Revert-PM-Runtime-Automatically-retry-failed-autosus.patch patches.runtime_pm/0002-PM-Domains-Rename-struct-dev_power_domain-to-struct-.patch @@ -792,3 +804,119 @@ patches.kzm9g/0202-ARM-mach-shmobile-kzm9g-add-PCF8757-gpio-key.patch patches.kzm9g/0203-ARM-mach-shmobile-kzm9g-defconfig-update.patch patches.kzm9g/0204-ARM-mach-shmobile-clock-sh73a0-add-FSI-clock.patch patches.kzm9g/0205-ARM-mach-shmobile-kzm9g-add-FSI-AK4648-support.patch + +patches.kzm9g/0001-tty-serial-allow-ports-to-override-the-irq-handler.patch +patches.kzm9g/0002-serial-introduce-generic-port-in-out-helpers.patch +patches.kzm9g/0003-serial-8250-increase-PASS_LIMIT.patch +patches.kzm9g/0004-serial-Fix-wakeup-init-logic-to-speed-up-startup.patch +patches.kzm9g/0005-tty-serial8250-allow-platforms-to-override-irq-handl.patch +patches.kzm9g/0006-tty-serial8250-remove-UPIO_DWAPB-32.patch +patches.kzm9g/0007-tty-8250-export-serial8250_handle_irq.patch +patches.kzm9g/0008-serial-8250-Move-UPIO_TSI-to-powerpc.patch +patches.kzm9g/0009-serial-Support-the-EFR-register-of-XR1715x-uarts.patch +patches.kzm9g/0010-8250-ratelimit-LSR-safety-check-engaged-warning.patch +patches.kzm9g/0011-serial-8250-replace-hardcoded-0xbf-with-define.patch +patches.kzm9g/0012-serial-move-struct-uart_8250_port-from-8250.c-to-825.patch +patches.kzm9g/0013-serial-clean-up-parameter-passing-for-8250-Rx-IRQ-ha.patch +patches.kzm9g/0014-serial-export-the-key-functions-for-an-8250-IRQ-hand.patch +patches.kzm9g/0015-serial-make-8250-timeout-use-the-specified-IRQ-handl.patch +patches.kzm9g/0016-serial-manually-inline-serial8250_handle_port.patch +patches.kzm9g/0017-serial-group-all-the-8250-related-code-together.patch +patches.kzm9g/0018-serial-Kill-off-NO_IRQ.patch +patches.kzm9g/0019-tty-fix-a-build-failure-on-sparc.patch +patches.kzm9g/0020-tty-sparc-rename-drivers-tty-serial-suncore.h-includ.patch +patches.kzm9g/0021-serial-delete-last-unused-traces-of-pausing-I-O-in-8.patch +patches.kzm9g/0022-serial-make-8250-s-serial_in-shareable-to-other-driv.patch +patches.kzm9g/0023-serial-delete-useless-void-casts-in-8250.c.patch +patches.kzm9g/0024-serial-reduce-number-of-indirections-in-8250-code.patch +patches.kzm9g/0025-serial-use-serial_port_in-out-vs-serial_in-out-in-82.patch +patches.kzm9g/0026-serial-remove-back-and-forth-conversions-in-serial_o.patch +patches.kzm9g/0027-serial-8250_pci-add-a-force-background-timer-flag-an.patch +patches.kzm9g/0028-8250.c-less-than-2400-baud-fix.patch +patches.kzm9g/0029-serial8250-Add-dl_read-dl_write-callbacks.patch +patches.kzm9g/0030-serial8250-Use-dl_read-dl_write-on-Alchemy.patch +patches.kzm9g/0031-serial8250-Use-dl_read-dl_write-on-RM9K.patch +patches.kzm9g/0032-serial8250-Clean-up-default-map-and-dl-code.patch +patches.kzm9g/0033-serial8250-Introduce-serial8250_register_8250_port.patch +patches.kzm9g/0034-serial8250-em-Emma-Mobile-UART-driver-V2.patch +patches.kzm9g/0035-serial8250-em-clk_get-IS_ERR-error-handling-fix.patch +patches.kzm9g/0036-cpuidle-create-bootparam-cpuidle.off-1.patch +patches.kzm9g/0037-cpuidle-replace-xen-access-to-x86-pm_idle-and-defaul.patch +patches.kzm9g/0038-cpuidle-stop-depending-on-pm_idle.patch +patches.kzm9g/0039-cpuidle-Consistent-spelling-of-cpuidle_idle_call.patch +patches.kzm9g/0040-sh-Fix-up-fallout-from-cpuidle-changes.patch +patches.kzm9g/0041-cpuidle-Add-module.h-to-drivers-cpuidle-files-as-req.patch +patches.kzm9g/0042-cpuidle-Move-dev-last_residency-update-to-driver-ent.patch +patches.kzm9g/0043-cpuidle-Remove-CPUIDLE_FLAG_IGNORE-and-dev-prepare.patch +patches.kzm9g/0044-cpuidle-Split-cpuidle_state-structure-and-move-per-c.patch +patches.kzm9g/0045-cpuidle-Single-Global-registration-of-idle-states.patch +patches.kzm9g/0046-cpuidle-Add-common-time-keeping-and-irq-enabling.patch +patches.kzm9g/0047-mm-add-vm_area_add_early.patch +patches.kzm9g/0048-clockevents-Make-clockevents_config-a-global-symbol.patch +patches.kzm9g/0049-clocksource-em_sti-Emma-Mobile-STI-driver-V2.patch +patches.kzm9g/0050-ARM-move-initialization-of-the-high_memory-variable-.patch +patches.kzm9g/0051-ARM-move-iotable-mappings-within-the-vmalloc-region.patch +patches.kzm9g/0052-ARM-simplify-__iounmap-when-dealing-with-section-bas.patch +patches.kzm9g/0053-ARM-add-generic-ioremap-optimization-by-reusing-stat.patch +patches.kzm9g/0054-ARM-mach-shmobile-Introduce-shmobile_setup_delay.patch +patches.kzm9g/0055-ARM-mach-shmobile-Allow-SoC-specific-CPU-kill-code.patch +patches.kzm9g/0056-ARM-mach-shmobile-Use-preset_lpj-with-calibrate_dela.patch +patches.kzm9g/0057-ARM-Undelete-KZM9D-mach-type.patch +patches.kzm9g/0058-gpio-Emma-Mobile-GPIO-driver.patch +patches.kzm9g/0059-mach-shmobile-Emma-Mobile-EV2-SoC-base-support-V3.patch +patches.kzm9g/0060-mach-shmobile-KZM9D-board-support-V3.patch +patches.kzm9g/0061-mach-shmobile-Emma-Mobile-EV2-SMP-support-V3.patch +patches.kzm9g/0062-mach-shmobile-Emma-Mobile-EV2-GPIO-support-V3.patch +patches.kzm9g/0063-mach-shmobile-KZM9D-board-Ethernet-support-V3.patch + +patches.kzm9g/ltsi-arm-shmobile-kzm9g-support-real-time-clock.patch +patches.kzm9g/ltsi-bugfix-add-config_i2c-to-kzm9g_defconfig.patch +patches.kzm9g/arm-shmobile-sh73a0-bugfix-sy-dmac-number.patch + +patches.kzm9g/001-ltsi-backport-arm-mach-shmobile-kzm9g-add-smsc-9221-support.patch +patches.kzm9g/002-lsti-backport-arm-mach-shmobile-kzm9g-add-external-usb-host-support.patch +patches.kzm9g/003-ltsi-bugfix-sh73a0-add-lost-clk_enable_on_init-for-div6_zb1.patch +patches.kzm9g/004-ltsi-arm-mach_shmobile-kzm9g-update-defconfig.patch + + +patches.sh7757lcr/001-spi-add-support-for-renesas-rspi.patch +patches.sh7757lcr/002-spi-irq-remove-irqf_disabled.patch +patches.sh7757lcr/003-drivercore-add-helper-macro-for-platform_driver-boilerplate.patch +patches.sh7757lcr/004-spi-spi-sh-add-ioresource_mem_type_mask-decoding-for-access-size.patch +patches.sh7757lcr/005-sh-clock-sh7757-add-clkdev_ick_id-for-cleanup.patch +patches.sh7757lcr/006-sh-move-clkdev_xxx_id-macro-to-sh_clk.h.patch +patches.sh7757lcr/007-sh-fix-the-compile-error-in-setup-sh7757.c.patch +patches.sh7757lcr/008-sh-add-parameters-for-ehci-and-riic-in-clock-sh7757.c.patch +patches.sh7757lcr/009-sh-add-a-resource-name-for-shdma.patch +patches.sh7757lcr/010-sh-modify-resource-for-spi0-in-setup-sh7757.patch +patches.sh7757lcr/011-sh-add-platform_device-for-spi1-in-setup-sh7757.patch +patches.sh7757lcr/012-sh-modify-clock-sh7757-for-renesas_usbhs.patch +patches.sh7757lcr/013-sh-add-parameter-for-rspi-in-clock-sh7757.patch +#patches.sh7757lcr/014-sh-modify-the-asm-sh_eth.h-to-linux-sh_eth.h-in-sh7757lcr.patch +patches.sh7757lcr/015-sh-add-platform_device-for-rspi-in-setup-sh7757.patch +patches.sh7757lcr/016-sh-fix-build-warning-in-board-sh7757lcr.patch +patches.sh7757lcr/017-sh-add-platform_device-for-renesas_usbhs-in-board-sh7757lcr.patch +patches.sh7757lcr/018-sh-fix-the-sh_mmcif_plat_data-in-board-sh7757lcr.patch +patches.sh7757lcr/019-sh-modify-a-resource-of-sh_eth_giga1_resources-in-board-sh7757lcr.patch +patches.sh7757lcr/020-sh-kexec-register-crashk_res.patch +patches.sh7757lcr/021-sh-kexec-add-physical_start.patch + + +patches.r8a66597-udc/001-usb-gadget-add-platform-module-alias-where-it-is-missing.patch +patches.r8a66597-udc/002-usb-update-email-address-in-r8a66597-udc-and-m66592-udc.patch +patches.r8a66597-udc/003-usb-gadget-r8a66597-udc-make-buswait-configurable-through-platform-data.patch +patches.r8a66597-udc/004-usb-gadget-r8a66597-udc-add-support-for-test_mode.patch +patches.r8a66597-udc/005-usb-gadget-clean-up-fsf-boilerplate-text.patch +patches.r8a66597-udc/006-usb-irq-remove-irqf_disabled.patch +patches.r8a66597-udc/007-usb-gadget-r8a66597-udc-change-prototype-of-r8a66597_write_fifo.patch +patches.r8a66597-udc/008-usb-r8a66597-hcd-add-function-for-external-controller.patch +patches.r8a66597-udc/009-usb-gadget-r8a66597-udc-add-function-for-external-controller.patch +patches.r8a66597-udc/010-usb-gadget-r8a66597-udc-use-dev_-instead-of-printk.patch +patches.r8a66597-udc/011-usb-gadget-r8a66597-udc-add-support-for-sudmac.patch +patches.r8a66597-udc/012-usb-gadget-r8a66597-udc-fix-flush-fifo-handling.patch + +# bugfixes due to LTSI-specific things that happened above. +# This is usually due to merge issues, or specific things like config file +# changes that are needed for the BSP being added. + + |